Файл: ai-bolit/ai-bolit.php
Строк: 2565
<?php
//define('LANG', 'EN');
define('LANG', 'RU');
define('PLRqvkb7X', 'PLRqvkb7X'); // Put any strong password to open the script from web
define('REPORT_MASK_PHPSIGN', 1);
define('REPORT_MASK_SPAMLINKS', 2);
define('REPORT_MASK_DOORWAYS', 4);
define('REPORT_MASK_SUSP', 8);
define('REPORT_MASK_CANDI', 16);
define('REPORT_MASK_WRIT', 32);
define('REPORT_MASK_FULL', REPORT_MASK_PHPSIGN | REPORT_MASK_SPAMLINKS | REPORT_MASK_DOORWAYS | REPORT_MASK_SUSP | REPORT_MASK_CANDI | REPORT_MASK_WRIT);
$defaults = array(
'path' => dirname(__FILE__),
'scan_all_files' => 1, // full scan (rather than just a .js, .php, .html, .htaccess)
'scan_delay' => 1, // delay in file scanning to reduce system load
'max_size_to_scan' => '1M',
'site_url' => '', // website url
'no_rw_dir' => 0,
'report_mask' => REPORT_MASK_FULL // full-featured report
);
define('DEBUG_MODE', 0);
define('DIR_SEPARATOR', '/');
if ((isset($_SERVER['OS']) && stripos('Win', $_SERVER['OS']) !== false)/* && stripos('CygWin', $_SERVER['OS']) === false)*/) {
define('DIR_SEPARATOR', '\');
}
if (LANG == 'RU') {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RUSSIAN INTERFACE
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
define('AI_STR_001', '<h3>AI-Болит v.%s — удаленькая искалка вредоносного ПО на хостинге.</h3><h5>Григорий Земсков, 2012-2013, <a target=_blank href="http://revisium.com/ai/">Страница проекта на revisium.com.</a> %s</h5>');
define('AI_STR_002', '<div class="update">Проверьте обновление на сайте <a href="http://revisium.com/ai/">http://revisium.com/ai/</a>. Возможно, ваша версия скрипта уже устарела.</div>');
define('AI_STR_003', 'ВНИМАНИЕ! Не оставляйте файл ai-bolit.php или файл отчета на сервере, и не давайте прямых ссылок с других сайтов на файл отчета или скрипта. Отчет содержит важную информацию о вашем сайте или сервере, сохраните его в надежном месте от посторонних глаз!');
define('AI_STR_004', 'Путь');
define('AI_STR_005', 'Дата создания');
define('AI_STR_006', 'Дата модификации');
define('AI_STR_007', 'Размер');
define('AI_STR_008', 'Конфигурация PHP');
define('AI_STR_009', "Вы установили слабый пароль на скрипт AI-BOLIT. Укажите пароль не менее 8 символов, содержащий латинские буквы в верхнем и нижнем регистре, а также цифры. Например, такой <b>%s</b>");
define('AI_STR_010', "Запустите скрипт с паролем, который установлен в переменной PASS (в начале файла). <br/>Например, так http://ваш_сайт_и_путь_до_скрипта/ai-bolit.php?p=<b>%s</b>");
define('AI_STR_011', 'Текущая директория не доступна для чтения скрипту. Пожалуйста, укажите права на доступ <b>rwxr-xr-x</b> или с помощью командной строки <b>chmod +r имя_директории</b>');
define('AI_STR_012', "<div class="rep">Известно %s шелл-сигнатур, а также %s других вредоносных фрагментов. Затрачено времени: <b>%s</b
>.<br/>Сканирование начато: %s. Сканирование завершено: %s</div> ");
define('AI_STR_013', '<div class="rep">Всего проверено %s директорий и %s файлов.</div>');
define('AI_STR_014', '<div class="rep" style="color: #0000A0">Внимание, скрипт выполнил быструю проверку сайта. Проверяются только наиболее критические файлы, но часть вредоносных скриптов может быть не обнаружена. Пожалуйста, запустите скрипт из командной строки для выполнения полного тестирования. Подробнее смотрите в <a href="http://revisium.com/ai/faq.php">FAQ вопрос №10</a>.</div>');
define('AI_STR_015', '<div class="sec">Критические замечания</div>');
define('AI_STR_016', 'Найдены сигнатуры шелл-скрипта. Подозрение на вредоносный скрипт:');
define('AI_STR_017', 'Шелл-скрипты не найдены.');
define('AI_STR_018', 'Найдены сигнатуры javascript вирусов:');
define('AI_STR_019', 'Найдены сигнатуры исполняемых файлов unix. Они могут быть вредоносными файлами:');
define('AI_STR_020', 'Найдены длинные зашифрованные последовательности в PHP или подключение внешних файлов. Подозрение на вредоносный скрипт:');
define('AI_STR_021', 'Подозрение на вредоносный скрипт:');
define('AI_STR_022', 'Список файловых ссылок (symlinks):');
define('AI_STR_023', 'Список скрытых файлов:');
define('AI_STR_024', 'Скорее всего этот файл лежит в каталоге с дорвеем:');
define('AI_STR_025', 'Не найдено директорий c дорвеями');
define('AI_STR_026', 'Предупреждения');
define('AI_STR_027', 'Опасный код в .htaccess (редирект на внешний сервер, подмена расширений или автовнедрение кода):');
define('AI_STR_028', 'В не .php файле содержится стартовая сигнатура PHP кода. Возможно, там вредоносный код:');
define('AI_STR_029', 'В этих файлах размещен код по продаже ссылок. Убедитесь, что размещали его вы:');
define('AI_STR_030', 'Непроверенные файлы - ошибка чтения');
define('AI_STR_031', 'В этих файлах размещены невидимые ссылки. Подозрение на ссылочный спам:');
define('AI_STR_032', 'Список невидимых ссылок:');
define('AI_STR_033', 'Отображены только первые ');
define('AI_STR_034', 'Найдены директории, в которых подозрительно много файлов .php или .html. Подозрение на дорвей:');
define('AI_STR_035', 'Скрипт использует код, который часто используются во вредоносных скриптах:');
define('AI_STR_036', 'Директории из файла .adirignore были пропущены при сканировании:');
define('AI_STR_037', 'Версии найденных CMS:');
define('AI_STR_038', 'Большие файлы (больше чем %s! Пропущено:');
define('AI_STR_039', 'Не найдено файлов больше чем %s');
define('AI_STR_040', 'Временные файлы или файлы(каталоги)-кандидаты на удаление по ряду причин:');
define('AI_STR_041', 'Потенциально небезопасно! Директории, доступные скрипту на запись:');
define('AI_STR_042', 'Не найдено директорий, доступных на запись скриптом');
define('AI_STR_043', 'Использовано памяти при сканировании: ');
define('AI_STR_044', '<div id="igid" style="display: none;"><div class="sec">Добавить в список игнорируемых</div><form name="ignore"><textarea name="list" style="width: 600px; height: 400px;"></textarea></form><div class="details">Скопируйте этот список и вставьте его в файл .aignore, чтобы исключить эти файлы из отчета.</div></div>');
define('AI_STR_045', '<div class="notice"><span class="vir">[!]</span> В скрипте отключено полное сканирование файлов, проверяются только .php, .html, .htaccess. Чтобы выполнить более тщательное сканирование, <br/>поменяйте значение настройки на <b>'scan_all_files' => 1</b> в самом верху скрипта. Скрипт в этом случае может работать очень долго. Рекомендуется отключить на хостинге лимит по времени выполнения, либо запускать скрипт из командной строки.</div>');
define('AI_STR_046', '[x] закрыть сообщение');
define('AI_STR_047', '<div class="offer" id="ofr"><span style="font-size: 15px;"><a href="http://www.revisium.com/ru/order/" target="_blank">Лечение сайта от вирусов. Защита от взлома. Гарантия.</a></span><br/><p>Быстро и качественно вылечим Ваш сайт от вирусов, удалим вредоносный код с сайта, поставим защиту от взлома. <a href="http://www.revisium.com/ru/order/">Пишите</a>.</p><a href="http://www.revisium.com/ru/order/" target="_blank">www.revisium.com →</a><p>Смотрите <a href="http://www.revisium.com/ru/quotes/" target=_blank>отзывы клиентов</a><p><p>Также приглашаем в <a href="http://vk.com/siteprotect" style="color: white" target="_blank">группу ВКонтакте: "Безопасность Веб-сайтов"</a>');
define('AI_STR_048', '<p>Если у вас есть эккаунт ВКонтакте, приглашаю в <a href="http://vk.com/siteprotect" target=_blank>группу "Безопасность Веб-сайтов"</a>: там я делюсь опытом защиты веб-сайтов и поиска вредоносных скриптов.</p>');
define('AI_STR_049', 'Отказ от гарантий: даже если скрипт не нашел вредоносных скриптов на сайте, автор не гарантирует их полное отсутствие, а также не несет ответственности за возможные последствия работы скрипта ai-bolit.php или неоправданные ожидания пользователей относительно функциональности и возможностей.');
define('AI_STR_050', 'Замечания и предложения по работе скрипта присылайте на <a href="mailto:audit@revisium.com">audit@revisium.com</a>.<p>Также буду чрезвычайно благодарен за любые упоминания скрипта ai-bolit на вашем сайте, в блоге, среди друзей, знакомых и клиентов. Ссылочку можно поставить на <a href="http://revisium.com/ai/">http://revisium.com/ai/</a>. <p>Если будут вопросы - пишите <a href="mailto:audit@revisium.com">audit@revisium.com</a>. Кстати, еще я собрал точную <a href="http://gzq.ru/">базу IP адресов</a> по городам России и Украины.');
define('AI_STR_051', 'Отчет по ');
define('AI_STR_052', 'Эвристический анализ обнаружил подозрительные файлы. Проверьте их на наличие вредоносного кода.');
} else {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ENGLISH INTERFACE
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
define('AI_STR_001', '<h3>AI-BOLIT v.%s — Enhanced Server-Side Detector of Viruses, Malicious and Hacker's Scripts.</h3><h5>Greg Zemskov, 2012-2013, <a target=_blank href="http://revisium.com/aibo/">AI-BOLIT web site.</a>. Non-commercial use only.</h5>');
define('AI_STR_002', '<div class="update">Check for updates on <a href="http://revisium.com/ai/">http://revisium.com/ai/</a>. Probably your version is out-of-date.</div>');
define('AI_STR_003', 'Caution! Do not leave either ai-bolit.php or report file on server and do not provide direct links to the report file. Report file contains sensitive information about your website which could be used by hackers. So keep it in safe place and don't leave on website!');
define('AI_STR_004', 'Path');
define('AI_STR_005', 'Created');
define('AI_STR_006', 'Modified');
define('AI_STR_007', 'Size');
define('AI_STR_008', 'PHP Info');
define('AI_STR_009', "Your password for AI-BOLIT is weak. Password must be more than 8 character length, contain both latin letters in upper and lower case, and digits. E.g. <b>%s</b>");
define('AI_STR_010', "Open AI-BOLIT with password specified in the beggining of file in PASS variable. <br/>E.g. http://you_website.com/ai-bolit.php?p=<b>%s</b>");
define('AI_STR_011', 'Current folder is not readable. Please change permission for <b>rwxr-xr-x</b> or using command line <b>chmod +r folder_name</b>');
define('AI_STR_012', "<div class="rep">%s malicious signatures known, %s virus signatures and other malicious code. Elapsed: <b>%s</b
>.<br/>Started: %s. Stopped: %s</div> ");
define('AI_STR_013', '<div class="rep">Scanned %s folders and %s files.</div>');
define('AI_STR_014', '<div class="rep" style="color: #0000A0">Attention! Script has performed quick scan. It scans only .html/.js/.php files in quick scan mode so some of malicious scripts might not be detected. Please launch script from a command line thru SSH to perform full scan.');
define('AI_STR_015', '<div class="sec">Critical</div>');
define('AI_STR_016', 'Shell script signatures detected. Might be a malicious or hacker's script:');
define('AI_STR_017', 'Shell scripts signatures not detected.');
define('AI_STR_018', 'Javascript virus signatures detected:');
define('AI_STR_019', 'Unix executables signatures detected. They might be a malicious binaries or rootkits:');
define('AI_STR_020', 'Suspicious encoded strings or external includes detected in PHP files. Might be a malicious or hacker's script:');
define('AI_STR_021', 'Might be a malicious or hacker's script:');
define('AI_STR_022', 'Symlinks:');
define('AI_STR_023', 'Hidden files:');
define('AI_STR_024', 'Files might be a part of doorway:');
define('AI_STR_025', 'Doorway folders not detected');
define('AI_STR_026', 'Warnings');
define('AI_STR_027', 'Malicious code in .htaccess (redirect to external server, extention handler replacement or malicious code auto-append):');
define('AI_STR_028', 'Non-PHP file has PHP signature. Check for malicious code:');
define('AI_STR_029', 'This script has black-SEO links or linkfarm. Check if it was installed by your:');
define('AI_STR_030', 'Reading error. Skipped.');
define('AI_STR_031', 'These files have invisible links, might be black-seo stuff:');
define('AI_STR_032', 'List of invisible links:');
define('AI_STR_033', 'Displayed first ');
define('AI_STR_034', 'Folders contained too many .php or .html files. Might be a doorway:');
define('AI_STR_035', 'Suspicious code detected. It's usually used in malicious scrips:');
define('AI_STR_036', 'The following list of files specified in .adirignore has been skipped:');
define('AI_STR_037', 'CMS found:');
define('AI_STR_038', 'Large files (greater than %s! Skipped:');
define('AI_STR_039', 'Files greater than %s not found');
define('AI_STR_040', 'Files recommended to be remove due to security reason:');
define('AI_STR_041', 'Potentially unsafe! Folders which are writable for scripts:');
define('AI_STR_042', 'Writable folders not found');
define('AI_STR_043', 'Memory used: ');
define('AI_STR_044', '<div id="igid" style="display: none;"><div class="sec">Add to ignore list</div><form name="ignore"><textarea name="list" style="width: 600px; height: 400px;"></textarea></form><div class="details">Copy and paste the following list into .aignore to eliminate these files from AI-BOLIT report.</div></div>');
define('AI_STR_045', '<div class="notice"><span class="vir">[!]</span> Ai-BOLIT is working in quick scan mode, only .php, .html, .htaccess files will be checked. Change the following setting 'scan_all_files' => 1 to perform full scanning.</b>. </div>');
define('AI_STR_046', '[x] close window');
define('AI_STR_047', '<div class="offer" id="ofr"><span style="font-size: 15px;"><a href="http://www.revisium.com/ru/order/" target="_blank">
We will protect your website against hackers and viruses with guarantee!</a></span><br/>
<p>We completely remove malicious software and scripts from your website, protect website against hackers, check servers for rootkits and suid-files, teach you how to keep your website secured. <a href="http://www.revisium.com/en/order/">Contact Us</a>');
define('AI_STR_048', '');
define('AI_STR_049', "Disclaimer: I'm not liable to you for any damages, including general, special, incidental or consequential damages arising out of the use or inability to use the script (including but not limited to loss of data or report being rendered inaccurate or failure of the script). There's no warranty for the program. Use at your own risk. ");
define('AI_STR_050', "I'm sincerely appreciate reports for any bugs you may found in the script. Please email me: <a href="mailto:audit@revisium.com">audit@revisium.com</a>.<p> Also I appriciate any reference to the script in your blog or forum posts. Thank you for the link to download page: <a href="http://revisium.com/aibo/">http://revisium.com/aibo/</a>");
define('AI_STR_051', 'Report for ');
define('AI_STR_052', 'Heuristic Analyzer has detected suspicious files. Check if they are malware.');
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This is signatures wrapped into base64.
$g_DBShe = unserialize(base64_decode("YTozNjE6e2k6MDtzOjQ3OiJAY2hyKCgkaFskZVskb11dPDw0KSsoJGhbJGVbKyskb11dKSk7fX1ldmFsKCRkKSI7aToxO3M6MzY6InBwY3xtaWRwfHdpbmRvd3MgY2V8bXRrfGoybWV8c3ltYmlhbiI7aToyO3M6NDA6ImFiYWNob3xhYml6ZGlyZWN0b3J5fGFib3V0fGFjb29ufGFsZXhhbmEiO2k6MztzOjU6IjZlc2FiIjtpOjQ7czo1OiJaZWQweCI7aTo1O3M6ODoiW2NvZGVyel0iO2k6NjtzOjg6ImRhcmttaW56IjtpOjc7czoxMzoiUmVhTF9QdU5pU2hFciI7aTo4O3M6MTE6IlsgUGhwcm94eSBdIjtpOjk7czo3OiJPb05fQm95IjtpOjEwO3M6MjA6Il9fVklFV1NUQVRFRU5DUllQVEVEIjtpOjExO3M6NjoiTTRsbDNyIjtpOjEyO3M6MjU6ImNyZWF0ZUZpbGVzRm9ySW5wdXRPdXRwdXQiO2k6MTM7czo4OiJQYXNoa2VsYSI7aToxNDtzOjY6IlNwYW1lciI7aToxNTtzOjc6IkZMb29kZVIiO2k6MTY7czoyMjoiXmNeYV5sXnBeZV5yXl9eZ15lXnJecCI7aToxNztzOjE0OiI9PSAiYmluZHNoZWxsIiI7aToxODtzOjE1OiJXZWJjb21tYW5kZXIgYXQiO2k6MTk7czoyNToiaXNzZXQoJF9QT1NUWydleGVjZ2F0ZSddKSI7aToyMDtzOjM3OiJmd3JpdGUoJGZwc2V0diwgZ2V0ZW52KCJIVFRQX0NPT0tJRSIpIjtpOjIxO3M6MjA6Ii1JL3Vzci9sb2NhbC9iYW5kbWluIjtpOjIyO3M6MjE6IiRPT08wMDAwMDA9dXJsZGVjb2RlKCI7aToyMztzOjc6IkRlZmFjZXIiO2k6MjQ7czo4OiJZRU5Jx0VSSSI7aToyNTtzOjY6ImQzbGV0ZSI7aToyNjtzOjIwOiJlY2hvICI8c2NyaXB0PmFsZXJ0KCI7aToyNztzOjc6IndlYnIwMHQiO2k6Mjg7czo0MzoiZnVuY3Rpb24gdXJsR2V0Q29udGVudHMoJHVybCwgJHRpbWVvdXQgPSA1KSI7aToyOTtzOjQ2OiJvdmVyZmxvdy15OnNjcm9sbDtcIj4iLiRsaW5rcy4kaHRtbF9tZlsnYm9keSddIjtpOjMwO3M6NjoiJGV2YTF0IjtpOjMxO3M6MTY6Ik1hZGUgYnkgRGVsb3JlYW4iO2k6MzI7czo3NToiaWYoZW1wdHkoJF9HRVRbJ3ppcCddKSBhbmQgZW1wdHkoJF9HRVRbJ2Rvd25sb2FkJ10pICYgZW1wdHkoJF9HRVRbJ2ltZyddKSl7IjtpOjMzO3M6NjU6InN0cl9yb3QxMygkYmFzZWFbKCRkaW1lbnNpb24qJGRpbWVuc2lvbi0xKSAtICgkaSokZGltZW5zaW9uKyRqKV0pIjtpOjM0O3M6NjA6IlIwbEdPRGxoRXdBUUFMTUFBQUFBQVAvLy81eWNBTTdPWS8vL25QLy96di9PblBmMzkvLy8vd0FBQUFBQSI7aTozNTtzOjQ1OiJwcmVnX21hdGNoKCchTUlEUHxXQVB8V2luZG93cy5DRXxQUEN8U2VyaWVzNjAiO2k6MzY7czo0NzoicHJlZ19tYXRjaCgnLyg/PD1SZXdyaXRlUnVsZSkuKig/PVxbTFwsUlw9MzAyXF0iO2k6Mzc7czozNzoiJHVybCA9ICR1cmxzW3JhbmQoMCwgY291bnQoJHVybHMpLTEpXSI7aTozODtzOjgwOiJ3cF9wb3N0cyBXSEVSRSBwb3N0X3R5cGUgPSAncG9zdCcgQU5EIHBvc3Rfc3RhdHVzID0gJ3B1Ymxpc2gnIE9SREVSIEJZIGBJRGAgREVTQyI7aTozOTtzOjY1OiJodHRwOi8vJy4kX1NFUlZFUlsnSFRUUF9IT1NUJ10udXJsZGVjb2RlKCRfU0VSVkVSWydSRVFVRVNUX1VSSSddKSI7aTo0MDtzOjM2OiJmd3JpdGUoJGYsZ2V0X2Rvd25sb2FkKCRfR0VUWyd1cmwnXSkiO2k6NDE7czoyNToiaW5pX3NldCgibWFnaWNfcXVvdGVzX2dwYyI7aTo0MjtzOjI1OiJpbmlfc2V0KCdtYWdpY19xdW90ZXNfZ3BjIjtpOjQzO3M6NzQ6IiRwYXJhbSB4ICRuLnN1YnN0ciAoJHBhcmFtLCBsZW5ndGgoJHBhcmFtKSAtIGxlbmd0aCgkY29kZSklbGVuZ3RoKCRwYXJhbSkpIjtpOjQ0O3M6NDc6IiR0aW1lX3N0YXJ0ZWQuJHNlY3VyZV9zZXNzaW9uX3VzZXIuc2Vzc2lvbl9pZCgpIjtpOjQ1O3M6NDg6IiR0aGlzLT5GLT5HZXRDb250cm9sbGVyKCRfU0VSVkVSWydSRVFVRVNUX1VSSSddKSI7aTo0NjtzOjIxOiJsdWNpZmZlckBsdWNpZmZlci5vcmciO2k6NDc7czoyNzoiYmFzZTY0X2RlY29kZSgkY29kZV9zY3JpcHQpIjtpOjQ4O3M6MjE6InVubGluaygkd3JpdGFibGVfZGlycyI7aTo0OTtzOjQxOiJmaWxlX2dldF9jb250ZW50cyh0cmltKCRmWyRfR0VUWydpZCddXSkpOyI7aTo1MDtzOjY6ImswZC5jYyI7aTo1MTtzOjEwOiJDeWJlc3RlcjkwIjtpOjUyO3M6NTU6ImlzX2NhbGxhYmxlKCdleGVjJykgYW5kICFpbl9hcnJheSgnZXhlYycsICRkaXNhYmxlZnVuY3MiO2k6NTM7czoxNDoiJEdMT0JBTFNbJ19fX18iO2k6NTQ7czoxODoidGltZSgpIC0gMTA1MjAwMjAwIjtpOjU1O3M6Mjc6Ii9ob21lL215ZGlyL2VnZ2Ryb3AvZmlsZXN5cyI7aTo1NjtzOjI5OiItLURDQ0RJUiBbbGluZGV4ICRVc2VyKCRpKSAyXSI7aTo1NztzOjEyOiJ1bmJpbmQgUkFXIC0iO2k6NTg7czoxMToicHV0Ym90ICRib3QiO2k6NTk7czoxMzoicHJpdm1zZyAkbmljayI7aTo2MDtzOjI2OiJwcm9jIGh0dHA6OkNvbm5lY3Qge3Rva2VufSI7aTo2MTtzOjQzOiJzZXQgZ29vZ2xlKGRhdGEpIFtodHRwOjpkYXRhICRnb29nbGUocGFnZSldIjtpOjYyO3M6MjI6ImJpbmQgam9pbiAtICogZ29wX2pvaW4iO2k6NjM7czoxMzoicHJpdm1zZyAkY2hhbiI7aTo2NDtzOjI0OiJyNGFUYy5kUG50RS9menRTRjFiSDNSSDAiO2k6NjU7czoxMDoiYmluZCBkY2MgLSI7aTo2NjtzOjM1OiJraWxsIC1DSExEIFwkYm90cGlkID4vZGV2L251bGwgMj4mMSI7aTo2NztzOjUwOiJyZWdzdWIgLWFsbCAtLSAsIFtzdHJpbmcgdG9sb3dlciAkb3duZXJdICIiIG93bmVycyI7aTo2ODtzOjMwOiJiaW5kIGZpbHQgLSAiXDAwMUFDVElPTiAqXDAwMSIiO2k6Njk7czoyNzoiYXl1IHByMSBwcjIgcHIzIHByNCBwcjUgcHI2IjtpOjcwO3M6MjA6InNldCBwcm90ZWN0LXRlbG5ldCAwIjtpOjcxO3M6MzM6Ii91c3IvbG9jYWwvYXBhY2hlL2Jpbi9odHRwZCAtRFNTTCI7aTo3MjtzOjc2OiIkdHN1MltyYW5kKDAsY291bnQoJHRzdTIpIC0gMSldLiR0c3UxW3JhbmQoMCxjb3VudCgkdHN1MSkgLSAxKV0uJHRzdTJbcmFuZCgwIjtpOjczO3M6NjoidWRwOi8vIjtpOjc0O3M6MTk6ImZvcGVuKCcvZXRjL3Bhc3N3ZCciO2k6NzU7czoxMToiZjBWTVJnRUJBUUEiO2k6NzY7czoyMzoiaXNfd3JpdGFibGUoIi92YXIvdG1wIikiO2k6Nzc7czozNToiMGQwYTBkMGE2NzZjNmY2MjYxNmMyMDI0NmQ3OTVmNzM2ZDciO2k6Nzg7czo5OiJldGFsZm5pemciO2k6Nzk7czozNzoiSkhacGMybDBZMjkxYm5RZ1BTQWtTRlJVVUY5RFQwOUxTVVZmViI7aTo4MDtzOjEzOiJlZG9jZWRfNDZlc2FiIjtpOjgxO3M6NToiZS8qLi8iO2k6ODI7czoyODoiQHNldGNvb2tpZSgiaGl0IiwgMSwgdGltZSgpKyI7aTo4MztzOjIzOiJldmFsKGZpbGVfZ2V0X2NvbnRlbnRzKCI7aTo4NDtzOjIwOiJwcmVnX3JlcGxhY2UoJy8uKi9lJyI7aTo4NTtzOjIwOiJwcmVnX3JlcGxhY2UoIi8uKi9lIiI7aTo4NjtzOjQ2OiJmaW5kX2RpcnMoJGdyYW5kcGFyZW50X2RpciwgJGxldmVsLCAxLCAkZGlycyk7IjtpOjg3O3M6Njk6IkBjb3B5KCRfRklMRVNbZmlsZU1hc3NdW3RtcF9uYW1lXSwkX1BPU1RbcGF0aF0uJF9GSUxFU1tmaWxlTWFzc11bbmFtZSI7aTo4ODtzOjc2OiJpbnQzMigoKCR6ID4+IDUgJiAweDA3ZmZmZmZmKSBeICR5IDw8IDIpICsgKCgkeSA+PiAzICYgMHgxZmZmZmZmZikgXiAkeiA8PCA0IjtpOjg5O3M6MTE6IlZPQlJBIEdBTkdPIjtpOjkwO3M6NTk6ImVjaG8geSA7IHNsZWVwIDEgOyB9IHwgeyB3aGlsZSByZWFkIDsgZG8gZWNobyB6JFJFUExZOyBkb25lIjtpOjkxO3M6OToiPHN0ZGxpYi5oIjtpOjkyO3M6NDU6ImFkZF9maWx0ZXIoJ3RoZV9jb250ZW50JywgJ19ibG9naW5mbycsIDEwMDAxKSI7aTo5MztzOjE3OiJpdHNva25vcHJvYmxlbWJybyI7aTo5NDtzOjE2OiJldmFsKGdldF9vcHRpb24oIjtpOjk1O3M6Mjg6ImlmIHNlbGYuaGFzaF90eXBlID09ICdwd2R1bXAiO2k6OTY7czo1OToiJGZyYW1ld29yay5wbHVnaW5zLmxvYWQoIiN7cnBjdHlwZS5kb3duY2FzZX1ycGMiLCBvcHRzKS5ydW4iO2k6OTc7czozNDoiL3Byb2Mvc3lzL2tlcm5lbC95YW1hL3B0cmFjZV9zY29wZSI7aTo5ODtzOjU3OiJzdWJwcm9jZXNzLlBvcGVuKCclc2dkYiAtcCAlZCAtYmF0Y2ggJXMnICUgKGdkYl9wcmVmaXgsIHAiO2k6OTk7czo1NzoiYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoZGVzY3JpcHRpb249aGVscCwgcHJvZz0ic2N0dW5uZWwiIjtpOjEwMDtzOjMyOiJydWxlX3JlcSA9IHJhd19pbnB1dCgiU291cmNlRmlyZSI7aToxMDE7czo1MDoib3Muc3lzdGVtKCdlY2hvIGFsaWFzIGxzPSIubHMuYmFzaCIgPj4gfi8uYmFzaHJjJykiO2k6MTAyO3M6NDI6ImNvbm5lY3Rpb24uc2VuZCgic2hlbGwgIitzdHIob3MuZ2V0Y3dkKCkpKyI7aToxMDM7czo2NzoicHJpbnQoIlshXSBIb3N0OiAiICsgaG9zdG5hbWUgKyAiIG1pZ2h0IGJlIGRvd24hXG5bIV0gUmVzcG9uc2UgQ29kZSI7aToxMDQ7czo2OToiZGVmIGRhZW1vbihzdGRpbj0nL2Rldi9udWxsJywgc3Rkb3V0PScvZGV2L251bGwnLCBzdGRlcnI9Jy9kZXYvbnVsbCcpIjtpOjEwNTtzOjgzOiJzdWJwcm9jZXNzLlBvcGVuKGNtZCwgc2hlbGwgPSBUcnVlLCBzdGRvdXQ9c3VicHJvY2Vzcy5QSVBFLCBzdGRlcnI9c3VicHJvY2Vzcy5TVERPVSI7aToxMDY7czo0NzoiaWYoaXNzZXQoJF9HRVRbJ2hvc3QnXSkmJmlzc2V0KCRfR0VUWyd0aW1lJ10pKXsiO2k6MTA3O3M6MTU6Ik5JR0dFUlMuTklHR0VSUyI7aToxMDg7czoyNToiSFRUUCBmbG9vZCBjb21wbGV0ZSBhZnRlciI7aToxMDk7czoyMToiODAgLWIgJDEgLWkgZXRoMCAtcyA4IjtpOjExMDtzOjEzOiJleHBsb2l0Y29va2llIjtpOjExMTtzOjI2OiJzeXN0ZW0oInBocCAtZiB4cGwgJGhvc3QiKSI7aToxMTI7czoxMToic2ggZ28gJDEuJHgiO2k6MTEzO3M6MTI6ImF6ODhwaXgwMHE5OCI7aToxMTQ7czozMDoidW5sZXNzKG9wZW4oUEZELCRnX3VwbG9hZF9kYikpIjtpOjExNTtzOjExOiJ3d3cudDBzLm9yZyI7aToxMTY7czozOToiJHZhbHVlID1+IHMvJSguLikvcGFjaygnYycsaGV4KCQxKSkvZWc7IjtpOjExNztzOjE0OiJUaGUgRGFyayBSYXZlciI7aToxMTg7czo2MToiUTNKbFpHbDBJRG9nVlc1a1pYSm5jbTkxYm1RZ1JHVjJhV3dnSm01aWMzQTdJQ0I4RFFvOFlTQm9jbVZtUCI7aToxMTk7czoyOToifWVsc2VpZigkX0dFVFsncGFnZSddPT0nZGRvcyciO2k6MTIwO3M6MTY6InskX1BPU1RbJ3Jvb3QnXX0iO2k6MTIxO3M6Mzk6IkkvZ2NaL3ZYMEExMEREUkRnN0V6ay9kKzMrOHF2cXFTMUswK0FYWSI7aToxMjI7czo0OToiJ2h0dHBkLmNvbmYnLCd2aG9zdHMuY29uZicsJ2NmZy5waHAnLCdjb25maWcucGhwJyI7aToxMjM7czo2NDoiRkozRmt1UEtGa1UvNTNXRUJtSWFpcGt0bkx3UVc4ejQ5ZGMxcmJiTHFzdzhlNjlsNnZKTSszLzEyNHhWbis3bCI7aToxMjQ7czoxMDI6Ilx1MDAzY1x1MDA2OVx1MDA2ZFx1MDA2N1x1MDAyMFx1MDA3M1x1MDA3Mlx1MDA2M1x1MDAzZFx1MDAyMlx1MDA2OFx1MDA3NFx1MDA3NFx1MDA3MFx1MDAzYVx1MDAyZlx1MDAyZiI7aToxMjU7czo1NToiNDYzODM5NjEwYzAwMGIwMDgwMDEwMGZmZmZmZmZmZmZmZjIxZjkwNDAxMDAwMDAxMDAyYzAwMCI7aToxMjY7czozNzoiWFZGTmF3SXhFTDBML29kaGhaSm9jRjJ2Mm9LSUJTbXRvbnRyWiI7aToxMjc7czozNjoiN1ZoM1dGUFp0ajhwa0VBU0VpUUlTRHNvQ2lnZFJrQ0RKQUlDIjtpOjEyODtzOjM2OiI5N1FFWFJBczk5Yzk4SGRqb2g5elppVFIxMkdhem9KVUlpTFUiO2k6MTI5O3M6MzA6ImZyZWFkKCRmcCwgZmlsZXNpemUoJGZpY2hlcm8pKSI7aToxMzA7czoyNDoiJGJhc2xpaz0kX1BPU1RbJ2Jhc2xpayddIjtpOjEzMTtzOjE4OiJwcm9jX29wZW4oJ0lIU3RlYW0iO2k6MTMyO3M6NTY6Ilx4MzFceGRiXHhmN1x4ZTNceDUzXHg0M1x4NTNceDZhXHgwMlx4ODlceGUxXHhiMFx4NjZceGNkIjtpOjEzMztzOjU4OiJBQUFBQUFBQU1BQXdBQkFBQUFlQVVBQURRQUFBRHNDUUFBQUFBQUFEUUFJQUFEQUNnQUZ3QVVBQUVBIjtpOjEzNDtzOjc6Im1pbHcwcm0iO2k6MTM1O3M6MzE6IiRpbmlbJ3VzZXJzJ10gPSBhcnJheSgncm9vdCcgPT4iO2k6MTM2O3M6NTg6IkhKM0hqdXRja29SZnBYZjlBMXpRTzJBd0RSclJleTl1R3ZUZWV6NzlxQWFvMWEwcmd1ZGtaa1I4UmEiO2k6MTM3O3M6NTA6ImN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9VUkwsICJodHRwOi8vJGhvc3Q6MjA4MiIpIjtpOjEzODtzOjE2OiJzeXN0ZW0oIndob2FtaSIpIjtpOjEzOTtzOjM5OiJ0YW9PSTh1eUxieklTTElOOUZzWGRLN2grL2RkMlluSVJVb3RCbE4iO2k6MTQwO3M6NzI6ImJNRml1YlJ3SXpxaUhoa1BrSWFwVFIzZFZENUFva3E4bVJGZE1ta1BVWGpXUlNjSi9XZlJmTHBQUGJHeThndGlVcGx1b2cwZCI7aToxNDE7czo3MToiNW9IblJuNmlkb3pOeGtVNmhoZGF1THlieTZMSXF4V1ZSUWRKblcxcUhIZU1SbDU5TTJTcXczRGtCVXpWOEtLbTFwclk5V1giO2k6MTQyO3M6NTg6IjNIanF4Y2xrWmZwV2IxU3d6d1RtcDFLWURBZXcrVEZ0NEgzajU5a3pXNmVkTVJuTFAzL3RZU0JQbWYiO2k6MTQzO3M6NjQ6IjwlPSAiXCIgJiBvU2NyaXB0TmV0LkNvbXB1dGVyTmFtZSAmICJcIiAmIG9TY3JpcHROZXQuVXNlck5hbWUgJT4iO2k6MTQ0O3M6MTA0OiJzcWxDb21tYW5kLlBhcmFtZXRlcnMuQWRkKCgoVGFibGVDZWxsKWRhdGFHcmlkSXRlbS5Db250cm9sc1swXSkuVGV4dCwgU3FsRGJUeXBlLkRlY2ltYWwpLlZhbHVlID0gZGVjaW1hbCI7aToxNDU7czo5MDoiUmVzcG9uc2UuV3JpdGUoIjxicj4oICkgPGEgaHJlZj0/dHlwZT0xJmZpbGU9IiAmIHNlcnZlci5VUkxlbmNvZGUoaXRlbS5wYXRoKSAmICJcPiIgJiBpdGVtIjtpOjE0NjtzOjExMToibmV3IEZpbGVTdHJlYW0oUGF0aC5Db21iaW5lKGZpbGVJbmZvLkRpcmVjdG9yeU5hbWUsIFBhdGguR2V0RmlsZU5hbWUoaHR0cFBvc3RlZEZpbGUuRmlsZU5hbWUpKSwgRmlsZU1vZGUuQ3JlYXRlIjtpOjE0NztzOjcxOiJSZXNwb25zZS5Xcml0ZShTZXJ2ZXIuSHRtbEVuY29kZSh0aGlzLkV4ZWN1dGVDb21tYW5kKHR4dENvbW1hbmQuVGV4dCkpKSI7aToxNDg7czo4MzoiPCU9UmVxdWVzdC5TZXJ2ZXJ2YXJpYWJsZXMoIlNDUklQVF9OQU1FIiklPj90eHRwYXRoPTwlPVJlcXVlc3QuUXVlcnlTdHJpbmcoInR4dHBhdGgiO2k6MTQ5O3M6NjA6Im91dHN0ciArPSBzdHJpbmcuRm9ybWF0KCI8YSBocmVmPSc/ZmRpcj17MH0nPnsxfS88L2E+Jm5ic3A7IiI7aToxNTA7czozNjoiaW5jbHVkZSgkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10pIjtpOjE1MTtzOjYxOiJRT2lLV0FnVjYxM0x2c3RLWStVQjk4SlpUUkdJaFlCZEh1SkNBd20rWHRoMTZBd1E4WDR0UE1jTVZaUXRlIjtpOjE1MjtzOjMzOiJyZS5maW5kYWxsKGRpcnQrJyguKiknLHByb2dubSlbMF0iO2k6MTUzO3M6NDA6ImZpbmQgLyAtbmFtZSAuc3NoID4gJGRpci9zc2hrZXlzL3NzaGtleXMiO2k6MTU0O3M6NjA6IkZTX2Noa19mdW5jX2xpYmM9KCAkKHJlYWRlbGYgLXMgJEZTX2xpYmMgfCBncmVwIF9jaGtAQCB8IGF3ayI7aToxNTU7czo0OToiTHk4M01UZzNPV1F5TVRKa1l6aGpZbVkwWkRSbVpEQTBOR0V6WkRFM1pqazNabUkyTiI7aToxNTY7czo5NToiJGZpbGUgPSAkX0ZJTEVTWyJmaWxlbmFtZSJdWyJuYW1lIl07IGVjaG8gIjxhIGhyZWY9XCIkZmlsZVwiPiRmaWxlPC9hPiI7fSBlbHNlIHtlY2hvKCJlbXB0eSIpO30iO2k6MTU3O3M6NDg6IkRKN1ZJVTdSSUNYcjZzRUVWMmNCdEhEU09lOW5WZHBFR2hFbXZSVlJOVVJmdzF3USI7aToxNTg7czo1MToiTHo4X0x5OHZEeDhlX3Y3LTd1N3Uzczd1enM3T3pxNnVucTdlcnE2dXZxNS1qbzZ1am41IjtpOjE1OTtzOjgzOiJpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQW9BQUFBSUNBWUFBQURBLW02MkFBQUFBWE5TUjBJQXJzNGM2UUFBQUFSblFVMUJBQUN4and2OFlRVSI7aToxNjA7czo3MToiUDJsQ1Axb3VXZzFXYzBFb0pGOURTMVJxSjNOSVFVOG5aRDVUVXo0bmMxbDRKeWsrWFExV0xrMWxPVTE2S0NJdlQwZzlUVWciO2k6MTYxO3M6Njk6IkQxMCsrM3FCbkhmeWgxaUk1dFp2NnZXaU8xaFZRdkRaNWNyS1YwTHR1eW8zcXczY0FnTXV6QjZMWEFSQlM3SWU5QlR4bSI7aToxNjI7czo3NDoiZTVXclBZTk01dURVQzJ3cnNaSHlSTFNEZzF5V1NtTXpQY3pXbUZGQUZxR1IwRVRjcmZhNU1TUWVDY0hCRWM1Y2twWlI2Q3JXdjEiO2k6MTYzO3M6NTE6InNlcnZlci48L3A+XHJcbjwvYm9keT48L2h0bWw+IjtleGl0O31pZihwcmVnX21hdGNoKCI7aToxNjQ7czo0MzoiT0RFMU5EVmpaR1F5WkdFeE5HWTVaalE0T1dGbE5XRXdNakZrT1dFek5qRSI7aToxNjU7czo3NzoiJEZjaG1vZCwkRmRhdGEsJE9wdGlvbnMsJEFjdGlvbiwkaGRkYWxsLCRoZGRmcmVlLCRoZGRwcm9jLCR1bmFtZSwkaWRkKTpzaGFyZWQiO2k6MTY2O3M6MTU6InBocCAiLiR3c29fcGF0aCI7aToxNjc7czo2MToiJHByb2Q9InN5Ii4icyIuInRlbSI7JGlkPSRwcm9kKCRfUkVRVUVTVFsncHJvZHVjdCddKTskeydpZCd9OyI7aToxNjg7czozOToiZXZhbChiYXNlNjRfZGVjb2RlKCdjR2h3YVc1bWJ5Z3BPdz09JykpIjtpOjE2OTtzOjg6InJvdW5kKDArIjtpOjE3MDtzOjMwOiJAYXNzZXJ0KCRfUkVRVUVTVFsnUEhQU0VTU0lEJ10iO2k6MTcxO3M6Njg6IlBPU1QgeyRwYXRofXskY29ubmVjdG9yfT9Db21tYW5kPUZpbGVVcGxvYWQmVHlwZT1GaWxlJkN1cnJlbnRGb2xkZXI9IjtpOjE3MjtzOjMwOiJmaW5kIC8gLXR5cGUgZiAtbmFtZSAuaHRwYXNzd2QiO2k6MTczO3M6MzE6ImZpbmQgLyAtdHlwZSBmIC1wZXJtIC0wMjAwMCAtbHMiO2k6MTc0O3M6MzE6ImZpbmQgLyAtdHlwZSBmIC1wZXJtIC0wNDAwMCAtbHMiO2k6MTc1O3M6ODc6IiJhZG1pbjEucGhwIiwgImFkbWluMS5odG1sIiwgImFkbWluMi5waHAiLCAiYWRtaW4yLmh0bWwiLCAieW9uZXRpbS5waHAiLCAieW9uZXRpbS5odG1sIiI7aToxNzY7czo5NzoiQHBhdGgxPSgnYWRtaW4vJywnYWRtaW5pc3RyYXRvci8nLCdtb2RlcmF0b3IvJywnd2ViYWRtaW4vJywnYWRtaW5hcmVhLycsJ2JiLWFkbWluLycsJ2FkbWluTG9naW4vJyI7aToxNzc7czozNjoiY2F0ICR7YmxrbG9nWzJdfSB8IGdyZXAgInJvb3Q6eDowOjAiIjtpOjE3ODtzOjQ2OiI/dXJsPScuJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS51bmxpbmsoUk9PVF9ESVIuIjtpOjE3OTtzOjQ2OiJsb25nIGludDp0KDAsMyk9cigwLDMpOy0yMTQ3NDgzNjQ4OzIxNDc0ODM2NDc7IjtpOjE4MDtzOjc1OiJjcmVhdGVfZnVuY3Rpb24oIiYkIi4iZnVuY3Rpb24iLCIkIi4iZnVuY3Rpb24gPSBjaHIob3JkKCQiLiJmdW5jdGlvbiktMyk7IikiO2k6MTgxO3M6MTY6ImV2YTFmWWxiYWtCY1ZTaXIiO2k6MTgyO3M6ODY6ImZ1bmN0aW9uIGdvb2dsZV9ib3QoKSB7JHNVc2VyQWdlbnQgPSBzdHJ0b2xvd2VyKCRfU0VSVkVSWydIVFRQX1VTRVJfQUdFTlQnXSk7aWYoIShzdHJwIjtpOjE4MztzOjExMzoiWm5WdVkzUnBiMjRnZUdOaktDUndMQ1I0UFRNeE5UTTJNREF3S1hzZ0pHWWdQU0JBWm1sc1pXMTBhVzFsS0NSd0tUc2dKR055YjI0Z1BTQjBhVzFsS0NrZ0xTQWtaanNnSkdRZ1BTQkFabWxzWlY5bloiO2k6MTg0O3M6NzQ6ImNvcHkoJF9GSUxFU1sndXBrayddWyd0bXBfbmFtZSddLCJray8iLmJhc2VuYW1lKCRfRklMRVNbJ3Vwa2snXVsnbmFtZSddKSk7IjtpOjE4NTtzOjY6ImxzIC1sYSI7aToxODY7czoxMDoiZGlyIC9PRyAvWCI7aToxODc7czo2NzoiZm9yICgkdmFsdWUpIHsgcy8mLyZhbXA7L2c7IHMvPC8mbHQ7L2c7IHMvPi8mZ3Q7L2c7IHMvIi8mcXVvdDsvZzsgfSI7aToxODg7czozNDoiaWYgKCgkcGVybXMgJiAweEMwMDApID09IDB4QzAwMCkgeyI7aToxODk7czo1OToiaWYgKGlzX2NhbGxhYmxlKCJleGVjIikgYW5kICFpbl9hcnJheSgiZXhlYyIsJGRpc2FibGVmdW5jKSkiO2k6MTkwO3M6NDI6IiRkYl9kID0gQG15c3FsX3NlbGVjdF9kYigkZGF0YWJhc2UsJGNvbjEpOyI7aToxOTE7czo1MToiU2VuZCB0aGlzIGZpbGU6IDxJTlBVVCBOQU1FPSJ1c2VyZmlsZSIgVFlQRT0iZmlsZSI+IjtpOjE5MjtzOjIyOiJmd3JpdGUgKCRmcCwgIiR5YXppIik7IjtpOjE5MztzOjUyOiJtYXAgeyByZWFkX3NoZWxsKCRfKSB9ICgkc2VsX3NoZWxsLT5jYW5fcmVhZCgwLjAxKSk7IjtpOjE5NDtzOjI3OiIyPiYxIDE+JjIiIDogIiAxPiYxIDI+JjEiKTsiO2k6MTk1O3M6NTk6Imdsb2JhbCAkbXlzcWxIYW5kbGUsICRkYm5hbWUsICR0YWJsZW5hbWUsICRvbGRfbmFtZSwgJG5hbWUsIjtpOjE5NjtzOjY5OiJfX2FsbF9fID0gWyJTTVRQU2VydmVyIiwiRGVidWdnaW5nU2VydmVyIiwiUHVyZVByb3h5IiwiTWFpbG1hblByb3h5Il0iO2k6MTk3O3M6Mjk6ImlmIChpc19maWxlKCIvdG1wLyRla2luY2kiKSl7IjtpOjE5ODtzOjM4OiJpZigkY21kICE9ICIiKSBwcmludCBTaGVsbF9FeGVjKCRjbWQpOyI7aToxOTk7czoyNjoiJGNtZCA9ICgkX1JFUVVFU1RbJ2NtZCddKTsiO2k6MjAwO3M6NTU6IiR1cGxvYWRmaWxlID0gJHJwYXRoLiIvIiAuICRfRklMRVNbJ3VzZXJmaWxlJ11bJ25hbWUnXTsiO2k6MjAxO3M6MzM6ImlmICgkZnVuY2FyZyA9fiAvXnBvcnRzY2FuICguKikvKSI7aToyMDI7czo0NjoiPCUgRm9yIEVhY2ggVmFycyBJbiBSZXF1ZXN0LlNlcnZlclZhcmlhYmxlcyAlPiI7aToyMDM7czo2NzoiZG9jdW1lbnQud3JpdGUodW5lc2NhcGUoJyUzQyU2OCU3NCU2RCU2QyUzRSUzQyU2MiU2RiU2NCU3OSUzRSUzQyU1MyI7aToyMDQ7czo0ODoiaWYoJyc9PSgkZGY9QGluaV9nZXQoJ2Rpc2FibGVfZnVuY3Rpb25zJykpKXtlY2hvIjtpOjIwNTtzOjM4OiIkZmlsZW5hbWUgPSAkYmFja3Vwc3RyaW5nLiIkZmlsZW5hbWUiOyI7aToyMDY7czo1OToiPCUjQH5eSHdBQUFBPT1AI0AmRG5rd0t4L39Sf1VOQCNAJm54OVBkOyhAI0AmdWdjQUFBPT1eI35AJT4iO2k6MjA3O3M6MjQ6IiRmdW5jdGlvbigkX1BPU1RbJ2NtZCddKSI7aToyMDg7czoyOToiZWNobyAiRklMRSBVUExPQURFRCBUTyAkZGV6IjsiO2k6MjA5O3M6Njg6ImlmICghQGlzX2xpbmsoJGZpbGUpICYmICgkciA9IHJlYWxwYXRoKCRmaWxlKSkgIT0gRkFMU0UpICRmaWxlID0gJHI7IjtpOjIxMDtzOjg3OiJVTklPTiBTRUxFQ1QgJzAnICwgJzw/IHN5c3RlbShcJF9HRVRbY3BjXSk7ZXhpdDsgPz4nICwwICwwICwwICwwIElOVE8gT1VURklMRSAnJG91dGZpbGUiO2k6MjExO3M6ODk6ImlmKG1vdmVfdXBsb2FkZWRfZmlsZSgkX0ZJTEVTWyJmaWMiXVsidG1wX25hbWUiXSxnb29kX2xpbmsoIi4vIi4kX0ZJTEVTWyJmaWMiXVsibmFtZSJdKSkpIjtpOjIxMjtzOjcyOiJjb25uZWN0KFNPQ0tFVCwgc29ja2FkZHJfaW4oJEFSR1ZbMV0sIGluZXRfYXRvbigkQVJHVlswXSkpKSBvciBkaWUgcHJpbnQiO2k6MjEzO3M6NTI6ImVsc2VpZihAaXNfd3JpdGFibGUoJEZOKSAmJiBAaXNfZmlsZSgkRk4pKSAkdG1wT3V0TUYiO2k6MjE0O3M6Njg6IndoaWxlICgkcm93ID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJlc3VsdCxNWVNRTF9BU1NPQykpIHByaW50X3IoJHJvdyk7IjtpOjIxNTtzOjE4OiIkZmUoIiRjbWQgIDI+JjEiKTsiO2k6MjE2O3M6Njk6InNlbmQoU09DSzUsICRtc2csIDAsIHNvY2thZGRyX2luKCRwb3J0YSwgJGlhZGRyKSkgYW5kICRwYWNvdGVze299Kys7OyI7aToyMTc7czo2OToifSBlbHNpZiAoJHNlcnZhcmcgPX4gL15cOiguKz8pXCEoLis/KVxAKC4rPykgUFJJVk1TRyAoLis/KSBcOiguKykvKSB7IjtpOjIxODtzOjM3OiJlbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCJzaGVsbF9leGVjIikpIjtpOjIxOTtzOjcxOiJzeXN0ZW0oIiRjbWQgMT4gL3RtcC9jbWR0ZW1wIDI+JjE7IGNhdCAvdG1wL2NtZHRlbXA7IHJtIC90bXAvY21kdGVtcCIpOyI7aToyMjA7czo1MjoiJF9GSUxFU1sncHJvYmUnXVsnc2l6ZSddLCAkX0ZJTEVTWydwcm9iZSddWyd0eXBlJ10pOyI7aToyMjE7czo4NzoiJHJhNDQgID0gcmFuZCgxLDk5OTk5KTskc2o5OCA9ICJzaC0kcmE0NCI7JG1sID0gIiRzZDk4IjskYTUgPSAkX1NFUlZFUlsnSFRUUF9SRUZFUkVSJ107IjtpOjIyMjtzOjQwOiJzZXRjb29raWUoICJteXNxbF93ZWJfYWRtaW5fdXNlcm5hbWUiICk7IjtpOjIyMztzOjY2OiJteXNxbF9xdWVyeSgiQ1JFQVRFIFRBQkxFIGB4cGxvaXRgIChgeHBsb2l0YCBMT05HQkxPQiBOT1QgTlVMTCkiKTsiO2k6MjI0O3M6NjY6InBhc3N0aHJ1KCAkYmluZGlyLiJteXNxbGR1bXAgLS11c2VyPSRVU0VSTkFNRSAtLXBhc3N3b3JkPSRQQVNTV09SRCI7aToyMjU7czo4NDoiPGEgaHJlZj0nJFBIUF9TRUxGP2FjdGlvbj12aWV3U2NoZW1hJmRibmFtZT0kZGJuYW1lJnRhYmxlbmFtZT0kdGFibGVuYW1lJz5TY2hlbWE8L2E+IjtpOjIyNjtzOjYwOiJpZihnZXRfbWFnaWNfcXVvdGVzX2dwYygpKSRzaGVsbE91dD1zdHJpcHNsYXNoZXMoJHNoZWxsT3V0KTsiO2k6MjI3O3M6MTk6InByaW50ICJTcGFtZWQnPjxicj4iO2k6MjI4O3M6NTE6IiRtZXNzYWdlID0gZXJlZ19yZXBsYWNlKCIlNUMlMjIiLCAiJTIyIiwgJG1lc3NhZ2UpOyI7aToyMjk7czo0NzoiaWYgKCFkZWZpbmVkJHBhcmFte2NtZH0peyRwYXJhbXtjbWR9PSJscyAtbGEifTsiO2k6MjMwO3M6MTU6Ii9ldGMvbmFtZWQuY29uZiI7aToyMzE7czoyMzoic2hlbGxfZXhlYygndW5hbWUgLWEnKTsiO2k6MjMyO3M6MTA6Ii9ldGMvaHR0cGQiO2k6MjMzO3M6MTE6Ii92YXIvY3BhbmVsIjtpOjIzNDtzOjExOiIvZXRjL3Bhc3N3ZCI7aToyMzU7czo5MToiaWYgKG1vdmVfdXBsb2FkZWRfZmlsZSgkX0ZJTEVTWydmaWxhJ11bJ3RtcF9uYW1lJ10sICRjdXJkaXIuIi8iLiRfRklMRVNbJ2ZpbGEnXVsnbmFtZSddKSkgeyI7aToyMzY7czo4MzoiaWYgKGVtcHR5KCRfUE9TVFsnd3NlciddKSkgeyR3c2VyID0gIndob2lzLnJpcGUubmV0Ijt9IGVsc2UgJHdzZXIgPSAkX1BPU1RbJ3dzZXInXTsiO2k6MjM3O3M6MzY6IjwlPWVudi5xdWVyeUhhc2h0YWJsZSgidXNlci5uYW1lIiklPiI7aToyMzg7czo2MToiUHlTeXN0ZW1TdGF0ZS5pbml0aWFsaXplKFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCksIG51bGwsIGFyZ3YpOyI7aToyMzk7czozNToiaWYoISR3aG9hbWkpJHdob2FtaT1leGVjKCJ3aG9hbWkiKTsiO2k6MjQwO3M6MzY6InNoZWxsX2V4ZWMoJF9QT1NUWydjbWQnXSAuICIgMj4mMSIpOyI7aToyNDE7czo1MzoiUG5WbGtXTTYzIUAjQCZkS3h+bk1EV01+RH8vRXNufnh/NkRAI0AmUH5+LD9uWSxXUHtQb2oiO2k6MjQyO3M6MjU6IiEkX1JFUVVFU1RbImM5OXNoX3N1cmwiXSkiO2k6MjQzO3M6NjA6IihlcmVnKCdeW1s6Ymxhbms6XV0qY2RbWzpibGFuazpdXSokJywgJF9SRVFVRVNUWydjb21tYW5kJ10pKSI7aToyNDQ7czoyMzoiJGxvZ2luPUBwb3NpeF9nZXR1aWQoKTsiO2k6MjQ1O3M6MTg6Ik5lIHVkYWxvcyB6YWdydXppdCI7aToyNDY7czozODoic3lzdGVtKCJ1bnNldCBISVNURklMRTsgdW5zZXQgU0FWRUhJU1QiO2k6MjQ3O3M6MzE6IjxIVE1MPjxIRUFEPjxUSVRMRT5jZ2ktc2hlbGwucHkiO2k6MjQ4O3M6MzY6ImV4ZWNsKCIvYmluL3NoIiwic2giLCItaSIsKGNoYXIqKTApOyI7aToyNDk7czoxNDoiZXhlYygicm0gLXIgLWYiO2k6MjUwO3M6MjY6Im5jZnRwcHV0IC11ICRmdHBfdXNlcl9uYW1lIjtpOjI1MTtzOjI5OiIkYVtoaXRzXScpOyBcclxuI2VuZHF1ZXJ5XHJcbiI7aToyNTI7czoyMzoieyR7cGFzc3RocnUoJGNtZCl9fTxicj4iO2k6MjUzO3M6NDI6IiRiYWNrZG9vci0+Y2NvcHkoJGNmaWNoaWVyLCRjZGVzdGluYXRpb24pOyI7aToyNTQ7czo1OToiJGl6aW5sZXIyPXN1YnN0cihiYXNlX2NvbnZlcnQoQGZpbGVwZXJtcygkZm5hbWUpLDEwLDgpLC00KTsiO2k6MjU1O3M6NTA6ImZvcig7JHBhZGRyPWFjY2VwdChDTElFTlQsIFNFUlZFUik7Y2xvc2UgQ0xJRU5UKSB7IjtpOjI1NjtzOjg6IkFzbW9kZXVzIjtpOjI1NztzOjM3OiJwYXNzdGhydShnZXRlbnYoIkhUVFBfQUNDRVBUX0xBTkdVQUdFIjtpOjI1ODtzOjM5OiIkX19fXz1AZ3ppbmZsYXRlKCRfX19fKSl7aWYoaXNzZXQoJF9QT1MiO2k6MjU5O3M6ODU6IiRzdWJqPXVybGRlY29kZSgkX0dFVFsnc3UnXSk7JGJvZHk9dXJsZGVjb2RlKCRfR0VUWydibyddKTskc2RzPXVybGRlY29kZSgkX0dFVFsnc2QnXSkiO2k6MjYwO3M6MzI6IiRrYT0nPD8vL0JSRSc7JGtha2E9JGthLidBQ0svLz8+IjtpOjI2MTtzOjQzOiJtdWlXcjRUbUxhUHdRb0pFU2dMb0FuUVN2OTNheHFoalJtT0FETW9GM1pMIjtpOjI2MjtzOjI0OiJldmFsKGd6aW5mbGF0ZShzdHJfcm90MTMiO2k6MjYzO3M6MzE6IkNhdXRhbSBmaXNpZXJlbGUgZGUgY29uZmlndXJhcmUiO2k6MjY0O3M6MTI6IkJSVVRFRk9SQ0lORyI7aToyNjU7czoxODoicHdkID4gR2VuZXJhc2kuZGlyIjtpOjI2NjtzOjU2OiJ4aCAtcyAiL3Vzci9sb2NhbC9hcGFjaGUvc2Jpbi9odHRwZCAtRFNTTCIgLi9odHRwZCAtbSAkMSI7aToyNjc7czo0ODoiJGE9KHN1YnN0cih1cmxlbmNvZGUocHJpbnRfcihhcnJheSgpLDEpKSw1LDEpLmMpIjtpOjI2ODtzOjc5OiI0WVRaaU56TXlNMlV3TWpBMVpHUXhOVGMwWkdGa01XWmlaVDBpWEhnMlppSTdKRzA1TnprMFlUWTBPV0V6WVdRelpEZzVPVEJsT1dKaVlqIjtpOjI2OTtzOjIxOiIhQCRfQ09PS0lFWyRzZXNzZHRfa10iO2k6MjcwO3M6NTg6IlNFTEVDVCAxIEZST00gbXlzcWwudXNlciBXSEVSRSBjb25jYXQoYHVzZXJgLCAnQCcsIGBob3N0YCkiO2k6MjcxO3M6OTM6IklpazdEUXBqYjI1dVpXTjBLRk5QUTB0RlZDd2dKSEJoWkdSeUtTQjhmQ0JrYVdVb0lrVnljbTl5T2lBa0lWeHVJaWs3RFFwdmNHVnVLRk5VUkVsT0xDQWlQaVpUVCI7aToyNzI7czo4OiJTaGVsbCBPayI7aToyNzM7czo0NDoiY29weSgkX0ZJTEVTW3hdW3RtcF9uYW1lXSwkX0ZJTEVTW3hdW25hbWVdKSkiO2k6Mjc0O3M6NDk6ImpWTnRUOXRBRFA0K2FmOGhReE50QlcwaGdRUUViS3RLWVBzeW9RNzJwWW1xYTJLYW8iO2k6Mjc1O3M6ODY6IjBpWkdsemNHeGhlVHB1YjI1bElqNDhZU0JvY21WbVBTSm9kSFJ3T2k4dmQzZDNMbXB2YjIxc1lYaDBZeTVqYjIwaVBrcHZiMjFzWVZoVVF5Qk9aWGR6IjtpOjI3NjtzOjU0OiIkTWVzc2FnZVN1YmplY3QgPSBiYXNlNjRfZGVjb2RlKCRfUE9TVFsibXNnc3ViamVjdCJdKTsiO2k6Mjc3O3M6MTc6InJlbmFtZSgid3NvLnBocCIsIjtpOjI3ODtzOjEwMzoiZEhVdTBkSldWc2dEZTJyZmU0Z1dCdGlMVmM1amtwbzFMVDhMcW1lWGVXelNYVjlGNElCVThpM0Jjb2VBclBvUG1uZ1IvQ1liNzUyZmNTOXBHQWpqRkZIMGpkSUt2ajRoTVpObnlWVSI7aToyNzk7czo4ODoiSVdsdUhqS3B4Ny9YR3FLY0gxR0hFMjA5THh5aU5LejVUS0NvekpYaXF1TnRPQXgzRHg0R0t6TlZuZlVTUi9zSDhDVEFsNXE3d29kYW9qTzN2K3ZDRGVHRSI7aToyODA7czoxMzU6IjQwVWVDS2RCOEVPcW1YQ0tlRzNxVTBZaUJqc0dXclVIbXdMR1Fnck5vdXlYRUo5TjR0alZ2clNRQUZEcURuVkhHOXZEWnlCRnZ3NGNUR0pvcS9QRkNVc3pJU3RDVFl6MlpiTGtUS3d2ZU1Wc05PQWZLTEkybkFva3prOUkzWmpsN3BBZUJqbiI7aToyODE7czo4ODoiJHJlZGlyZWN0VVJMPSdodHRwOi8vJy4kclNpdGUuJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ107aWYoaXNzZXQoJF9TRVJWRVJbJ0hUVFBfUkVGRVJFUiddKSI7aToyODI7czoxMToibXlzaGVsbGV4ZWMiO2k6MjgzO3M6OToicm9vdHNoZWxsIjtpOjI4NDtzOjk6ImFudGlzaGVsbCI7aToyODU7czo0MDoiJGZpbGVwYXRoPUByZWFscGF0aCgkX1BPU1RbJ2ZpbGVwYXRoJ10pOyI7aToyODY7czo0MjoiV29ya2VyX0dldFJlcGx5Q29kZSgkb3BEYXRhWydyZWN2QnVmZmVyJ10pIjtpOjI4NztzOjI3OiJkZWZhdWx0X2FjdGlvbiA9ICdGaWxlc01hbiciO2k6Mjg4O3M6MTI6InI1N3NoZWxsLnBocCI7aToyODk7czoyMToiRmFUYUxpc1RpQ3pfRnggRngyOVNoIjtpOjI5MDtzOjEzOiJ3NGNrMW5nIHNoZWxsIjtpOjI5MTtzOjIyOiJwcml2YXRlIFNoZWxsIGJ5IG00cmNvIjtpOjI5MjtzOjExOiJMb2N1czdTaGVsbCI7aToyOTM7czoxMToiU3Rvcm03U2hlbGwiO2k6Mjk0O3M6ODoiTjN0c2hlbGwiO2k6Mjk1O3M6MjA6IlNoZWxsIGJ5IE1hd2FyX0hpdGFtIjtpOjI5NjtzOjExOiJkZXZpbHpTaGVsbCI7aToyOTc7czoxNjoiV2ViIFNoZWxsIGJ5IG9SYiI7aToyOTg7czoxNzoiV2ViIFNoZWxsIGJ5IGJvZmYiO2k6Mjk5O3M6NzE6IkhCeWIzUnZLU0I4ZkNCa2FXVW9Ja1Z5Y205eU9pQWtJVnh1SWlrN0RRcGpiMjV1WldOMEtGTlBRMHRGVkN3Z0pIQmhaR1J5IjtpOjMwMDtzOjg3OiJXVEpUa0NvbDBYNEF1d0pTZkZodGZQNWRPZ241NjFpbCt3a3prcUNHOWRmVDl6cWMyNzR2ZUllU2Q0MUN4VUl2SEZuK3RXNzdvRTNvaHFTdjAxQlh6VDAiO2k6MzAxO3M6NTI6ImFIUjBjRG92TDJvdFpHVjJMbkoxTDJsdVpHVjRMbkJvY0Q5amNHNDlabkpoYldWelpXeHMiO2k6MzAyO3M6MTIwOiJUc05DaUFnSUNCemFXNHVjMmx1WDJaaGJXbHNlU0E5SUVGR1gwbE9SVlE3RFFvZ0lDQWdjMmx1TG5OcGJsOXdiM0owSUQwZ2FIUnZibk1vWVhSdmFTaGhjbWQyV3pKZEtTazdEUW9nSUNBZ2MybHVMbk5wYmw5aFoiO2k6MzAzO3M6MTI3OiJxaERUWklwTWNCMXhCb2szMzJCamNjZlBYcTBRc1pVL2c0ZWFwQnhUNWdpdDFyR2RLdHdmMXJ0OU9PaWNjL2hUbHBlRm1FalJSa1dHV1RKVGtDb2wwWDRBdXdKU2ZGaHRmUDVkT2duNTYxaWwrd2t6a3FDRzlkZlQ5enFjMjc0IjtpOjMwNDtzOjEyOiJQSFBTSEVMTC5QSFAiO2k6MzA1O3M6NDY6InJvdW5kKDArOTgzMC40Kzk4MzAuNCs5ODMwLjQrOTgzMC40Kzk4MzAuNCkpPT0iO2k6MzA2O3M6MTEwOiJ2enY2ZCtpT3Z0a2QzOFRsSHU4bVFhdlhkbkpDYnBRY3BYaE5iYkxtWk9xTW9wRFplTmFsYitWS2xlZGhDanBWQU1RU1FueFZJRUNRQWZMdTVLZ0xtd0I2ZWhRUUdOU0JZanBnOWc1R2RCaWhYbyI7aTozMDc7czo2NToiaWYgKGVyZWcoJ15bWzpibGFuazpdXSpjZFtbOmJsYW5rOl1dKyhbXjtdKykkJywgJGNvbW1hbmQsICRyZWdzKSkiO2k6MzA4O3M6NzY6IkxTMGdSSFZ0Y0ROa0lHSjVJRkJwY25Wc2FXNHVVRWhRSUZkbFluTm9NMnhzSUhZeExqQWdZekJrWldRZ1lua2djakJrY2pFZ09rdz0iO2k6MzA5O3M6MTQyOiI1amIyMGlLVzl5SUhOMGNtbHpkSElvSkhKbFptVnlaWElzSW1Gd2IzSjBJaWtnYjNJZ2MzUnlhWE4wY2lna2NtVm1aWEpsY2l3aWJtbG5iV0VpS1NCdmNpQnpkSEpwYzNSeUtDUnlaV1psY21WeUxDSjNaV0poYkhSaElpa2diM0lnYzNSeWFYTjBjaWdrIjtpOjMxMDtzOjIxOiJldmFsKGJhc2U2NF9kZWNvZGUoJF8iO2k6MzExO3M6NDg6Indzb0V4KCd0YXIgY2Z6diAnIC4gZXNjYXBlc2hlbGxhcmcoJF9QT1NUWydwMiddKSI7aTozMTI7czo4NjoiPG5vYnI+PGI+JGNkaXIkY2ZpbGU8L2I+ICgiLiRmaWxlWyJzaXplX3N0ciJdLiIpPC9ub2JyPjwvdGQ+PC90cj48Zm9ybSBuYW1lPWN1cnJfZmlsZT4iO2k6MzEzO3M6MTY6IkNvbnRlbnQtVHlwZTogJF8iO2k6MzE0O3M6MTQxOiI8L3RkPjx0ZCBpZD1mYT5bIDxhIHRpdGxlPVwiSG9tZTogJyIuaHRtbHNwZWNpYWxjaGFycyhzdHJfcmVwbGFjZSgiXCIsICRzZXAsIGdldGN3ZCgpKSkuIicuXCIgaWQ9ZmEgaHJlZj1cImphdmFzY3JpcHQ6Vmlld0RpcignIi5yYXd1cmxlbmNvZGUiO2k6MzE1O3M6MTA3OiJDUWJvR2w3Zit4Y0F5VXlzeGI1bUtTNmtBV3NuUkxkUytzS2dHb1pXZHN3TEZKWlY4dFZ6WHNxK21lU1BITXhUSTNuU1VCNGZKMnZSM3IzT252WHROQXFONnduL0R0VFRpK0N1MVVPSndOTCI7aTozMTY7czozOToiV1NPc2V0Y29va2llKG1kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pIjtpOjMxNztzOjc6IkZ4Yzk5c2giO2k6MzE4O3M6NjE6IkpIWnBjMmwwWTI5MWJuUWdQU0FrU0ZSVVVGOURUMDlMU1VWZlZrRlNVMXNpZG1semFYUnpJbDA3SUdsbUsiO2k6MzE5O3M6MTI2OiJYMU5GVTFOSlQwNWJKM1I0ZEdGMWRHaHBiaWRkSUQwZ2RISjFaVHNOQ2lBZ0lDQnBaaUFvSkY5UVQxTlVXeWR5YlNkZEtTQjdEUW9nSUNBZ0lDQnpaWFJqYjI5cmFXVW9KM1I0ZEdGMWRHaGZKeTRrY20xbmNtOTFjQ3dnYlciO2k6MzIwO3M6ODoiY2loc2hlbGwiO2k6MzIxO3M6Mzk6IkpAIVZyQComUkhSd35KTHcuR3x4bGhuTEp+PzEuYndPYnhiUHwhViI7aTozMjI7czoxMToiemVoaXJoYWNrZXIiO2k6MzIzO3M6MTYxOiIoJyInLCcmcXVvdDsnLCRmbikpLiciO2RvY3VtZW50Lmxpc3Quc3VibWl0KCk7XCc+Jy5odG1sc3BlY2lhbGNoYXJzKHN0cmxlbigkZm4pPmZvcm1hdD9zdWJzdHIoJGZuLDAsZm9ybWF0LTMpLicuLi4nOiRmbikuJzwvYT4nLnN0cl9yZXBlYXQoJyAnLGZvcm1hdC1zdHJsZW4oJGZuKSI7aTozMjQ7czoxNjA6InByaW50KChpc19yZWFkYWJsZSgkZikgJiYgaXNfd3JpdGVhYmxlKCRmKSk/Ijx0cj48dGQ+Ii53KDEpLmIoIlIiLncoMSkuZm9udCgncmVkJywnUlcnLDMpKS53KDEpOigoKGlzX3JlYWRhYmxlKCRmKSk/Ijx0cj48dGQ+Ii53KDEpLmIoIlIiKS53KDQpOiIiKS4oKGlzX3dyaXRhYmwiO2k6MzI1O3M6NzM6IlIwbEdPRGxoRkFBVUFLSUFBQUFBQVAvLy85M2QzY0RBd0lhR2hnUUVCUC8vL3dBQUFDSDVCQUVBQUFZQUxBQUFBQUFVQUJRQUEiO2k6MzI2O3M6OTA6IjwlPVJlcXVlc3QuU2VydmVyVmFyaWFibGVzKCJzY3JpcHRfbmFtZSIpJT4/Rm9sZGVyUGF0aD08JT1TZXJ2ZXIuVVJMUGF0aEVuY29kZShGb2xkZXIuRHJpdiI7aTozMjc7czoxMTM6Im05MWRDd2dKR1Z2ZFhRcE93MEtjMlZzWldOMEtDUnliM1YwSUQwZ0pISnBiaXdnZFc1a1pXWXNJQ1JsYjNWMElEMGdKSEpwYml3Z01USXdLVHNOQ21sbUlDZ2hKSEp2ZFhRZ0lDWW1JQ0FoSkdWdmRYIjtpOjMyODtzOjM4OiJSb290U2hlbGwhJyk7c2VsZi5sb2NhdGlvbi5ocmVmPSdodHRwOiI7aTozMjk7czoxMTU6IlRSVUZFUkZJc01TazdEUXBpYVc1a0tGTXNjMjlqYTJGa1pISmZhVzRvSkV4SlUxUkZUbDlRVDFKVUxFbE9RVVJFVWw5QlRsa3BLU0I4ZkNCa2FXVWdJa05oYm5RZ2IzQmxiaUJ3YjNKMFhHNGlPdzBLYkciO2k6MzMwO3M6NzY6ImEgaHJlZj0iPD9lY2hvICIkZmlzdGlrLnBocD9kaXppbj0kZGl6aW4vLi4vIj8+IiBzdHlsZT0idGV4dC1kZWNvcmF0aW9uOiBub24iO2k6MzMxO3M6NzoiTlREYWRkeSI7aTozMzI7czoxMjc6IkNCMmFUWnBJREV3TWpRdERRb2pMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUTBLSTNKbGNYVnAiO2k6MzMzO3M6NTU6Ikl5RXZkWE55TDJKcGJpOXdaWEpzRFFva1UwaEZURXc5SWk5aWFXNHZZbUZ6YUNBdGFTSTdEUXAiO2k6MzM0O3M6ODg6IkNSYnNrRUlTK3liS0F3YzYvT0IxalU4WTBZSU1WVWh4aGFPSXNIQUNCeUQwd01BTk9IcVk1WTQ4Z3VpQm5DaGt3UFlOVGt4ZEJSVlJaTEhGa29qWTk2SUkiO2k6MzM1O3M6MzE6InMoKS5nKCkucygpLnMoKS5nKCkucygpLnMoKS5nKCkiO2k6MzM2O3M6MTIyOiJudCkoZGlza190b3RhbF9zcGFjZShnZXRjd2QoKSkvKDEwMjQqMTAyNCkpIC4gIk1iICIgLiAiRnJlZSBzcGFjZSAiIC4gKGludCkoZGlza19mcmVlX3NwYWNlKGdldGN3ZCgpKS8oMTAyNCoxMDI0KSkgLiAiTWIgPCI7aTozMzc7czozNzoia2xhc3ZheXYuYXNwP3llbmlkb3N5YT08JT1ha3RpZmtsYXMlPiI7aTozMzg7czo0NDoiV1QrUHt+RVcwRXJQT3RuVUAjQCZebF5zUDFsZG55QCNAJm5zaytyMCxHVCsiO2k6MzM5O3M6MTE1OiJtcHR5KCRfUE9TVFsndXInXSkpICRtb2RlIHw9IDA0MDA7IGlmICghZW1wdHkoJF9QT1NUWyd1dyddKSkgJG1vZGUgfD0gMDIwMDsgaWYgKCFlbXB0eSgkX1BPU1RbJ3V4J10pKSAkbW9kZSB8PSAwMTAwIjtpOjM0MDtzOjEwNToiLzB0VlNHL1N1djBVci9oYVVZQWRuM2pNUXdiYm9jR2ZmQWVDMjlCTjl0bUJpSmRWMWxrK2pZRFU5MkM5NGpkdERpZit4T1lqRzZDTGh4MzFVbzl4OS9lQVdnc0JLNjBrSzJtTHdxenFkIjtpOjM0MTtzOjg2OiJjcmxmLid1bmxpbmsoJG5hbWUpOycuJGNybGYuJ3JlbmFtZSgifiIuJG5hbWUsICRuYW1lKTsnLiRjcmxmLid1bmxpbmsoImdycF9yZXBhaXIucGhwIiI7aTozNDI7czoxMDY6Ijl0WlNCMGJ5QnlOVGNnYzJobGJHd2dKaVlnTDJKcGJpOWlZWE5vSUMxcElpazdEUW9nSUNCbGJITmxEUW9nSUNCbWNISnBiblJtS0hOMFpHVnljaXdpVTI5eWNua2lLVHNOQ2lBZ0lHTnMiO2k6MzQzO3M6MTU6IkRYX0hlYWRlcl9kcmF3biI7aTozNDQ7czozMDoiW0F2NGJmQ1lDUyx4S1drJCtUa1VTLHhuR2RBeFtPIjtpOjM0NTtzOjExMToiQkRBUWtKQ1F3TERCZ05EUmd5SVJ3aE1qSXlNakl5TWpJeU1qSXlNakl5TWpJeU1qSXlNakl5TWpJeU1qSXlNakl5TWpJeU1qSXlNakl5TWpJeU1qSXlNakwvd0FBUkNBQVFBQkFEQVNJQUFoRUJBIjtpOjM0NjtzOjExOiJjdHNoZWxsLnBocCI7aTozNDc7czo0NzoiRXhlY3V0ZWQgY29tbWFuZDogPGI+PGZvbnQgY29sb3I9I2RjZGNkYz5bJGNtZF0iO2k6MzQ4O3M6MTM6IldTQ1JJUFQuU0hFTEwiO2k6MzQ5O3M6NzoiY2FzdXMxNSI7aTozNTA7czo3NjoiUjBsR09EbGhKZ0FXQUlBQUFBQUFBUC8vL3lINUJBVVVBQUVBTEFBQUFBQW1BQllBQUFJdmpJK3B5KzBQRjRpMGdWdnp1VnhYRG5vUSI7aTozNTE7czoxNzoiYWRtaW5Ac3B5Z3J1cC5vcmciO2k6MzUyO3M6MTQ6InRlbXBfcjU3X3RhYmxlIjtpOjM1MztzOjE3OiIkYzk5c2hfdXBkYXRlZnVybCI7aTozNTQ7czo4OiJyNTdzaGVsbCI7aTozNTU7czo4OiJjOTlzaGVsbCI7aTozNTY7czo5OiJCeSBQc3ljaDAiO2k6MzU3O3M6MTY6ImM5OWZ0cGJydXRlY2hlY2siO2k6MzU4O3M6MTAxOiI3VE1HQUhZNUthTTlvMzdXL0dRL2ZyRkpldGZxbFJHTzZGU1JUTW03SUxTbTM1bzV6NCt2MG1jZjRLYUhnS1M1WTE3ZXFxdkQybW1OOE56dGV5cGxOZDZXT3dyUVZLNDQ1Si95MCI7aTozNTk7czo4NDoiPHRleHRhcmVhIG5hbWU9XCJwaHBldlwiIHJvd3M9XCI1XCIgY29scz1cIjE1MFwiPiIuQCRfUE9TVFsncGhwZXYnXS4iPC90ZXh0YXJlYT48YnI+IjtpOjM2MDtzOjk0OiIkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDA0MCkgPygoJHBlcm1zICYgMHgwODAwKSA/ICdzJyA6ICd4JyApIDooKCRwZXJtcyAmIDB4MDgwMCkgPyAnUycgOiAnLScpIjt9"));
$g_FlexDBShe = unserialize(base64_decode("YToxNTY6e2k6MDtzOjQ3OiJzdHJfcm90MTNccypcKFxzKmd6aW5mbGF0ZVxzKlwoXHMqYmFzZTY0X2RlY29kZSI7aToxO3M6NTA6Imd6dW5jb21wcmVzc1xzKlwoXHMqc3RyX3JvdDEzXHMqXChccypiYXNlNjRfZGVjb2RlIjtpOjI7czo1MDoiZ3p1bmNvbXByZXNzXHMqXChccypiYXNlNjRfZGVjb2RlXHMqXChccypzdHJfcm90MTMiO2k6MztzOjYxOiJnemluZmxhdGVccypcKFxzKmJhc2U2NF9kZWNvZGVccypcKFxzKnN0cl9yb3QxM1xzKlwoXHMqc3RycmV2IjtpOjQ7czo2MToiZ3ppbmZsYXRlXHMqXChccypiYXNlNjRfZGVjb2RlXHMqXChccypzdHJyZXZccypcKFxzKnN0cl9yb3QxMyI7aTo1O3M6NDQ6Imd6aW5mbGF0ZVxzKlwoXHMqYmFzZTY0X2RlY29kZVxzKlwoXHMqc3RycmV2IjtpOjY7czo2ODoiZ3ppbmZsYXRlXHMqXChccypiYXNlNjRfZGVjb2RlXHMqXChccypiYXNlNjRfZGVjb2RlXHMqXChccypzdHJfcm90MTMiO2k6NztzOjU0OiJiYXNlNjRfZGVjb2RlXHMqXChccypnenVuY29tcHJlc3NccypcKFxzKmJhc2U2NF9kZWNvZGUiO2k6ODtzOjQ3OiJnemluZmxhdGVccypcKFxzKmJhc2U2NF9kZWNvZGVccypcKFxzKnN0cl9yb3QxMyI7aTo5O3M6NDc6Imd6aW5mbGF0ZVxzKlwoXHMqc3RyX3JvdDEzXHMqXChccypiYXNlNjRfZGVjb2RlIjtpOjEwO3M6MzM6Imd6dW5jb21wcmVzc1xzKlwoXHMqYmFzZTY0X2RlY29kZSI7aToxMTtzOjMwOiJnemluZmxhdGVccypcKFxzKmJhc2U2NF9kZWNvZGUiO2k6MTI7czoyNToiZXZhbFxzKlwoXHMqYmFzZTY0X2RlY29kZSI7aToxMztzOjE3OiJCcmF6aWxccytIYWNrVGVhbSI7aToxNDtzOjkwOiJcJHRsZFxzKj1ccyphcnJheVxzKlwoXHMqWyciXXswLDF9Y29tWyciXXswLDF9LFsnIl17MCwxfW9yZ1snIl17MCwxfSxbJyJdezAsMX1uZXRbJyJdezAsMX0iO2k6MTU7czozNzoic3RyX2lyZXBsYWNlXHMqXCgqXHMqWyciXXswLDF9PC9oZWFkPiI7aToxNjtzOjU1OiJkZWZpbmVccypcKCpccypbJyJdezAsMX1TQkNJRF9SRVFVRVNUX0ZJTEVbJyJdezAsMX1ccyosIjtpOjE3O3M6Mzk6InByZWdfcmVwbGFjZVxzKlwoKlxzKlsnIl17MCwxfS9cLlwrL2VzaSI7aToxODtzOjE3OiJNeXN0ZXJpb3VzXHMrV2lyZSI7aToxOTtzOjU1OiJcJGhlYWRlcnNccypcLj1ccypcJF9QT1NUXFtbJyJdezAsMX1lTWFpbEFkZFsnIl17MCwxfVxdIjtpOjIwO3M6Mzg6ImRlZmluZVxzKlwoXHMqWyciXXswLDF9REVGQ0FMTEJBQ0tNQUlMIjtpOjIxO3M6NDc6ImRlZmF1bHRfYWN0aW9uXHMqPVxzKlsnIl17MCwxfUZpbGVzTWFuWyciXXswLDF9IjtpOjIyO3M6Mzg6ImVjaG9ccytAZmlsZV9nZXRfY29udGVudHNccypcKFxzKlwkZ2V0IjtpOjIzO3M6MTU2OiJpZlxzKlwoXHMqc3RyaXBvc1xzKlwoXHMqXCRfU0VSVkVSXFtbJyJdezAsMX1IVFRQX1VTRVJfQUdFTlRbJyJdezAsMX1cXVxzKixccypbJyJdezAsMX1BbmRyb2lkWyciXXswLDF9XClccyohPT1mYWxzZVxzKiYmXHMqIVwkX0NPT0tJRVxbWyciXXswLDF9ZGxlX3VzZXJfaWQiO2k6MjQ7czo0NDoiaWZccypcKFxzKnByZWdfbWF0Y2hccypcKFxzKlsnIl17MCwxfSN5YW5kZXgiO2k6MjU7czo3MDoiaGVhZGVyXHMqXChbJyJdezAsMX1Mb2NhdGlvbjpccypbJyJdezAsMX1ccypcLlxzKlwkdG9ccypcLlxzKnVybGRlY29kZSI7aToyNjtzOjE1OiJEYzBSSGFbJyJdezAsMX0iO2k6Mjc7czoxNToiWyciXXswLDF9YUhSMGNEIjtpOjI4O3M6MzY6IiF0b3VjaFwoWyciXXswLDF9XC5cLi9cLlwuL2xhbmd1YWdlLyI7aToyOTtzOjMyOiJldmFsXChzdHJpcHNsYXNoZXNcKFxcXCRfUkVRVUVTVCI7aTozMDtzOjc4OiJkb2N1bWVudFwud3JpdGVccypcKFxzKlsnIl17MCwxfTxzY3JpcHRccytzcmM9WyciXXswLDF9aHR0cDovLzxcPz1cJGRvbWFpblw/Pi8iO2k6MzE7czo4NToiZXhpdFxzKlwoXHMqWyciXXswLDF9PHNjcmlwdD5ccypzZXRUaW1lb3V0XHMqXChccypcXFsnIl17MCwxfWRvY3VtZW50XC5sb2NhdGlvblwuaHJlZiI7aTozMjtzOjY3OiJzdHJwb3NccypcKCpccypcJF9TRVJWRVJcW1xzKlsnIl17MCwxfUhUVFBfVVNFUl9BR0VOVFsnIl17MCwxfVxzKlxdIjtpOjMzO3M6Mjg6ImZ1bmN0aW9uXHMrc3FsMl9zYWZlXHMqXChccyoiO2k6MzQ7czo0MToiXCRwb3N0UmVzdWx0XHMqPVxzKmN1cmxfZXhlY1xzKlwoKlxzKlwkY2giO2k6MzU7czo4NzoiJiZccypmdW5jdGlvbl9leGlzdHNccypcKCpccypbJyJdezAsMX1nZXRteHJyWyciXXswLDF9XClccypcKVxzKntccypAZ2V0bXhyclxzKlwoKlxzKlwkIjtpOjM2O3M6NTc6ImlzX193cml0YWJsZVxzKlwoKlxzKlwkcGF0aFxzKlwuXHMqdW5pcWlkXHMqXCgqXHMqbXRfcmFuZCI7aTozNztzOjI4OiJmaWxlX3B1dF9jb250ZW50elxzKlwoKlxzKlwkIjtpOjM4O3M6MzE6Ij1ccyphcnJheV9tYXBccypcKCpccypzdHJyZXZccyoiO2k6Mzk7czo5OiJcJF9fX1xzKj0iO2k6NDA7czo1NToiQCpnemluZmxhdGVccypcKFxzKkAqYmFzZTY0X2RlY29kZVxzKlwoXHMqQCpzdHJfcmVwbGFjZSI7aTo0MTtzOjg3OiJmb3BlblxzKlwoKlxzKiJodHRwOi8vIlxzKlwuXHMqXCRjaGVja19kb21haW5ccypcLlxzKiI6ODAiXHMqXC5ccypcJGNoZWNrX2RvY1xzKixccyoiciIiO2k6NDI7czo0MzoiQFwkX0NPT0tJRVxbWyciXXswLDF9c3RhdENvdW50ZXJbJyJdezAsMX1cXSI7aTo0MztzOjM1OiJpZlxzKlwoKlxzKkAqcHJlZ19tYXRjaFxzKlwoKlxzKnN0ciI7aTo0NDtzOjk0OiJhcnJheV9wb3BccypcKCpccypcJHdvcmtSZXBsYWNlXHMqLFxzKlwkXyhHRVR8UE9TVHxTRVJWRVJ8Q09PS0lFfFJFUVVFU1QpXHMqLFxzKlwkY291bnRLZXlzTmV3IjtpOjQ1O3M6NDk6Imd6dW5jb21wcmVzc1xzKlwoKlxzKnN1YnN0clxzKlwoKlxzKmJhc2U2NF9kZWNvZGUiO2k6NDY7czozMzoiQWRkVHlwZVxzK2FwcGxpY2F0aW9uL3gtaHR0cGQtcGhwIjtpOjQ3O3M6NjQ6IihHRVR8UE9TVHxTRVJWRVJ8Q09PS0lFfFJFUVVFU1QpXHMqXFtccypbJyJdezAsMX1fX19bJyJdezAsMX1ccyoiO2k6NDg7czoxMDoicGNudGxfZXhlYyI7aTo0OTtzOjMzOiJcKFxzKlsnIl17MCwxfUlOU0hFTExbJyJdezAsMX1ccyoiO2k6NTA7czo0NzoiXCRiXHMqXC5ccypcJHBccypcLlxzKlwkaFxzKlwuXHMqXCRrXHMqXC5ccypcJHYiO2k6NTE7czoxNDU6IlwkW2EtekEtWjAtOV9dKz9ccypcKFxzKlxkK1xzKlxeXHMqXGQrXHMqXClccypcLlxzKlwkW2EtekEtWjAtOV9dKz9ccypcKFxzKlxkK1xzKlxeXHMqXGQrXHMqXClccypcLlxzKlwkW2EtekEtWjAtOV9dKz9ccypcKFxzKlxkK1xzKlxeXHMqXGQrXHMqXCkiO2k6NTI7czoxMTQ6Ij1ccypwcmVnX3NwbGl0XHMqXChccypbJyJdezAsMX0vXFwsXChcXCBcK1wpXD8vWyciXXswLDF9LFxzKkAqaW5pX2dldFxzKlwoXHMqWyciXXswLDF9ZGlzYWJsZV9mdW5jdGlvbnNbJyJdezAsMX1cKSI7aTo1MztzOjEyNToiaWZccypcKCFmdW5jdGlvbl9leGlzdHNccypcKFxzKlsnIl17MCwxfXBvc2l4X2dldHB3dWlkWyciXXswLDF9XHMqXClccyomJlxzKiFpbl9hcnJheVxzKlwoXHMqWyciXXswLDF9cG9zaXhfZ2V0cHd1aWRbJyJdezAsMX0iO2k6NTQ7czo0Mzoic3RyZWFtX3NvY2tldF9jbGllbnRccypcKFxzKlsnIl17MCwxfXRjcDovLyI7aTo1NTtzOjE0MzoicHJlZ19yZXBsYWNlXHMqXChccypbJyJdezAsMX0vXF5cKHd3d1x8ZnRwXClcXFwuL2lbJyJdezAsMX1ccyosXHMqWyciXXswLDF9WyciXXswLDF9LFxzKkBcJF9TRVJWRVJccypcW1xzKlsnIl17MCwxfUhUVFBfSE9TVFsnIl17MCwxfVxzKlxdXHMqXCkiO2k6NTY7czoyNjE6ImlmXHMqXCgqXHMqaXNzZXRccypcKCpccypcJF8oR0VUfFBPU1R8U0VSVkVSfENPT0tJRXxSRVFVRVNUKVxzKlxbXHMqWyciXXswLDF9W2EtekEtWl8wLTldK1snIl17MCwxfVxzKlxdXHMqXCkqXHMqXClccyp7XHMqXCRbYS16QS1aXzAtOV0rXHMqPVxzKlwkXyhHRVR8UE9TVHxTRVJWRVJ8Q09PS0lFfFJFUVVFU1QpXHMqXFtccypbJyJdezAsMX1bYS16QS1aXzAtOV0rWyciXXswLDF9XHMqXF07XHMqZXZhbFxzKlwoKlxzKlwkW2EtekEtWl8wLTldK1xzKlwpKiI7aTo1NztzOjgxOiJldmFsXHMqXCgqXHMqc3RyaXBzbGFzaGVzXHMqXCgqXHMqYXJyYXlfcG9wXCgqXCRfKEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVCkiO2k6NTg7czo4MDoiKHN5c3RlbXxzaGVsbF9leGVjfHBhc3N0aHJ1fGVzY2FwZXNoZWxsY21kfHBvcGVufHByb2Nfb3BlbilcKCpbJyJdezAsMX1jZFxzKy90bXAiO2k6NTk7czoxNTQ6ImlmXHMrXChccypzdHJwb3NccypcKFxzKlwkdXJsXHMqLFxzKlsnIl17MCwxfWpzL21vb3Rvb2xzXC5qc1snIl17MCwxfVxzKlwpXHMqPT09XHMqZmFsc2VccysmJlxzK3N0cnBvc1xzKlwoXHMqXCR1cmxccyosXHMqWyciXXswLDF9anMvY2FwdGlvblwuanNbJyJdezAsMX0iO2k6NjA7czo2ODoiaWZccytcKCpccyptYWlsXHMqXChccypcJHJlY3BccyosXHMqXCRzdWJqXHMqLFxzKlwkc3R1bnRccyosXHMqXCRmcm0iO2k6NjE7czo0MzoiPFw/cGhwXHMrXCRfRlxzKj1ccypfX0ZJTEVfX1xzKjtccypcJF9YXHMqPSI7aTo2MjtzOjEwNDoiXCR4XGQrXHMqPVxzKlsnIl17MCwxfS4rP1snIl17MCwxfVxzKjtccypcJHhcZCtccyo9XHMqWyciXXswLDF9Lis/WyciXXswLDF9XHMqO1xzKlwkeFxkK1xzKj1ccypbJyJdezAsMX0iO2k6NjM7czoxMTU6IlwkYmVlY29kZVxzKj1AKmZpbGVfZ2V0X2NvbnRlbnRzXHMqWyciXXswLDF9XCgqXHMqXCR1cmxwdXJzXHMqWyciXXswLDF9XCkqXHMqO1xzKmVjaG9ccytbJyJdezAsMX1cJGJlZWNvZGVbJyJdezAsMX0iO2k6NjQ7czoxMDE6IlwkR0xPQkFMU1xbXHMqWyciXXswLDF9Lis/WyciXXswLDF9XHMqXF1cW1xzKlxkK1xzKlxdXChccypcJF9cZCtccyosXHMqX1xkK1xzKlwoXHMqXGQrXHMqXClccypcKVxzKlwpIjtpOjY1O3M6NzM6InByZWdfcmVwbGFjZVxzKlwoKlxzKlsnIl17MCwxfS9cLlwqXFsuKz9cXVw/L2VbJyJdezAsMX1ccyosXHMqc3RyX3JlcGxhY2UiO2k6NjY7czoxNDk6IlwkR0xPQkFMU1xbWyciXXswLDF9Lis/WyciXXswLDF9XF09QXJyYXlccypcKFxzKmJhc2U2NF9kZWNvZGVccypcKFxzKlsnIl17MCwxfS4rP1snIl17MCwxfVxzKlwpXHMqLFxzKmJhc2U2NF9kZWNvZGVccypcKFxzKlsnIl17MCwxfS4rP1snIl17MCwxfVxzKlwpIjtpOjY3O3M6MjAwOiJVTklPTlxzK1NFTEVDVFxzK1snIl17MCwxfTBbJyJdezAsMX1ccyosXHMqWyciXXswLDF9PFw/IHN5c3RlbVwoXFxcJF8oR0VUfFBPU1R8U0VSVkVSfENPT0tJRXxSRVFVRVNUKVxbY3BjXF1cKTtleGl0O1xzKlw/PlsnIl17MCwxfVxzKixccyowXHMqLDBccyosXHMqMFxzKixccyowXHMrSU5UT1xzK09VVEZJTEVccytbJyJdezAsMX1cJFsnIl17MCwxfSI7aTo2ODtzOjkzOiJpc3NldFwoKlwkX0AqKEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVClcW1snIl17MCwxfS4rP1snIl17MCwxfVxdXCkqXHMqb3JccypkaWVcKCouKj9cKSoiO2k6Njk7czo2NjoiaXNzZXRccypcKCpccypcJF9QT1NUXHMqXFtccypbJyJdezAsMX1leGVjZ2F0ZVsnIl17MCwxfVxzKlxdXHMqXCkqIjtpOjcwO3M6ODE6ImZ3cml0ZVxzKlwoKlxzKlwkZnBzZXR2XHMqLFxzKmdldGVudlxzKlwoXHMqWyciXXswLDF9SFRUUF9DT09LSUVbJyJdezAsMX1ccypcKVxzKiI7aTo3MTtzOjU3OiJPcHRpb25zXHMrRm9sbG93U3ltTGlua3NccytNdWx0aVZpZXdzXHMrSW5kZXhlc1xzK0V4ZWNDR0kiO2k6NzI7czozMToic3ltbGlua1xzKlwoKlxzKlsnIl17MCwxfS9ob21lLyI7aTo3MztzOjI3OiJcJE9PTy4rPz1ccyp1cmxkZWNvZGVccypcKCoiO2k6NzQ7czo3MDoiZnVuY3Rpb25ccyt1cmxHZXRDb250ZW50c1xzKlwoKlxzKlwkdXJsXHMqLFxzKlwkdGltZW91dFxzKj1ccypcZCtccypcKSI7aTo3NTtzOjQ5OiJzdHJyZXZcKCpccypbJyJdezAsMX1lZG9jZWRfNDZlc2FiWyciXXswLDF9XHMqXCkqIjtpOjc2O3M6NDI6InN0cnJldlwoKlxzKlsnIl17MCwxfXRyZXNzYVsnIl17MCwxfVxzKlwpKiI7aTo3NztzOjEzNjoid3BfcG9zdHNccytXSEVSRVxzK3Bvc3RfdHlwZVxzKj1ccypbJyJdezAsMX1wb3N0WyciXXswLDF9XHMrQU5EXHMrcG9zdF9zdGF0dXNccyo9XHMqWyciXXswLDF9cHVibGlzaFsnIl17MCwxfVxzK09SREVSXHMrQllccytgSURgXHMrREVTQyI7aTo3ODtzOjExMjoiZmlsZV9nZXRfY29udGVudHNccypcKCpccyp0cmltXHMqXChccypcJC4rP1xbXCRfKEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVClcW1snIl17MCwxfS4rP1snIl17MCwxfVxdXF1cKVwpOyI7aTo3OTtzOjIyNToiaXNfY2FsbGFibGVccypcKCpccypbJyJdezAsMX0oc3lzdGVtfHNoZWxsX2V4ZWN8cGFzc3RocnV8ZXNjYXBlc2hlbGxjbWR8cG9wZW58cHJvY19vcGVuKVsnIl17MCwxfVwpKlxzK2FuZFxzKyFpbl9hcnJheVxzKlwoKlxzKlsnIl17MCwxfShzeXN0ZW18c2hlbGxfZXhlY3xwYXNzdGhydXxlc2NhcGVzaGVsbGNtZHxwb3Blbnxwcm9jX29wZW4pWyciXXswLDF9XHMqLFxzKlwkZGlzYWJsZWZ1bmNzIjtpOjgwO3M6MjQ6IlwkR0xPQkFMU1xbWyciXXswLDF9X19fXyI7aTo4MTtzOjEyOiJybVxzKy1mXHMrLXIiO2k6ODI7czoxMjoicm1ccystclxzKy1mIjtpOjgzO3M6ODoicm1ccystZnIiO2k6ODQ7czo4OiJybVxzKy1yZiI7aTo4NTtzOjQzOiJmb3BlblxzKlwoKlxzKlsnIl17MCwxfS9ldGMvcGFzc3dkWyciXXswLDF9IjtpOjg2O3M6NTc6ImV2YWxccypcKCpccypzdHJpcHNsYXNoZXNccypcKCpccyphcnJheV9wb3BccypcKCpccypAKlwkXyI7aTo4NztzOjM5OiJldmFsXHMqXCgqXHMqc3RyaXBzbGFzaGVzXHMqXCgqXHMqQCpcJF8iO2k6ODg7czo1MjoiaXNfd3JpdGFibGVccypcKCpccypbJyJdezAsMX0vdmFyL3RtcFsnIl17MCwxfVxzKlwpKiI7aTo4OTtzOjc0OiJAKnNldGNvb2tpZVxzKlwoKlxzKlsnIl17MCwxfWhpdFsnIl17MCwxfSxccyoxXHMqLFxzKnRpbWVccypcKCpccypcKSpccypcKyI7aTo5MDtzOjM2OiJldmFsXHMqXCgqXHMqZmlsZV9nZXRfY29udGVudHNccypcKCoiO2k6OTE7czo0NjoicHJlZ19yZXBsYWNlXHMqXCgqXHMqWyciXXswLDF9L1wuXCovZVsnIl17MCwxfSI7aTo5MjtzOjk1OiJhZGRfZmlsdGVyXHMqXCgqXHMqWyciXXswLDF9dGhlX2NvbnRlbnRbJyJdezAsMX1ccyosXHMqWyciXXswLDF9X2Jsb2dpbmZvWyciXXswLDF9XHMqLFxzKi4rP1wpKiI7aTo5MztzOjI5OiJldmFsXHMqXCgqXHMqZ2V0X29wdGlvblxzKlwoKiI7aTo5NDtzOjgxOiJccyp7XHMqXCRfKEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVClccypcW1xzKlsnIl17MCwxfXJvb3RbJyJdezAsMX1ccypcXVxzKn0iO2k6OTU7czoxMzU6IlsnIl17MCwxfWh0dHBkXC5jb25mWyciXXswLDF9XHMqLFxzKlsnIl17MCwxfXZob3N0c1wuY29uZlsnIl17MCwxfVxzKixccypbJyJdezAsMX1jZmdcLnBocFsnIl17MCwxfVxzKixccypbJyJdezAsMX1jb25maWdcLnBocFsnIl17MCwxfSI7aTo5NjtzOjMzOiJwcm9jX29wZW5ccypcKFxzKlsnIl17MCwxfUlIU3RlYW0iO2k6OTc7czo4ODoiXCRpbmlccypcW1xzKlsnIl17MCwxfXVzZXJzWyciXXswLDF9XHMqXF1ccyo9XHMqYXJyYXlccypcKFxzKlsnIl17MCwxfXJvb3RbJyJdezAsMX1ccyo9PiI7aTo5ODtzOjg4OiJjdXJsX3NldG9wdFxzKlwoXHMqXCRjaFxzKixccypDVVJMT1BUX1VSTFxzKixccypbJyJdezAsMX1odHRwOi8vXCRob3N0OlxkK1snIl17MCwxfVxzKlwpIjtpOjk5O3M6NDU6InN5c3RlbVxzKlwoKlxzKlsnIl17MCwxfXdob2FtaVsnIl17MCwxfVxzKlwpKiI7aToxMDA7czo1MjoiZmluZFxzKy9ccystbmFtZVxzK1wuc3NoXHMrPlxzK1wkZGlyL3NzaGtleXMvc3Noa2V5cyI7aToxMDE7czoxMTA6IihzeXN0ZW18c2hlbGxfZXhlY3xwYXNzdGhydXxlc2NhcGVzaGVsbGNtZHxwb3Blbnxwcm9jX29wZW4pXHMqXCgqXHMqQCpcJF8oR0VUfFBPU1R8U0VSVkVSfENPT0tJRXxSRVFVRVNUKVxzKlxbIjtpOjEwMjtzOjM3OiJyZXF1aXJlX29uY2VccypcKCpccypbJyJdezAsMX1pbWFnZXMvIjtpOjEwMztzOjM3OiJpbmNsdWRlX29uY2VccypcKCpccypbJyJdezAsMX1pbWFnZXMvIjtpOjEwNDtzOjU4OiJyZXF1aXJlX29uY2VccypcKCpccypAKlwkXyhHRVR8UE9TVHxTRVJWRVJ8Q09PS0lFfFJFUVVFU1QpIjtpOjEwNTtzOjU4OiJpbmNsdWRlX29uY2VccypcKCpccypAKlwkXyhHRVR8UE9TVHxTRVJWRVJ8Q09PS0lFfFJFUVVFU1QpIjtpOjEwNjtzOjMyOiJyZXF1aXJlXHMqXCgqXHMqWyciXXswLDF9aW1hZ2VzLyI7aToxMDc7czozMjoiaW5jbHVkZVxzKlwoKlxzKlsnIl17MCwxfWltYWdlcy8iO2k6MTA4O3M6NTM6InJlcXVpcmVccypcKCpccypAKlwkXyhHRVR8UE9TVHxTRVJWRVJ8Q09PS0lFfFJFUVVFU1QpIjtpOjEwOTtzOjUzOiJpbmNsdWRlXHMqXCgqXHMqQCpcJF8oR0VUfFBPU1R8U0VSVkVSfENPT0tJRXxSRVFVRVNUKSI7aToxMTA7czo1OToiYmFzZTY0X2RlY29kZVxzKlwoKlxzKkAqXCRfKEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVCkiO2k6MTExO3M6NTI6ImFzc2VydFxzKlwoKlxzKkAqXCRfKEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVCkiO2k6MTEyO3M6NTA6ImV2YWxccypcKCpccypAKlwkXyhHRVR8UE9TVHxTRVJWRVJ8Q09PS0lFfFJFUVVFU1QpIjtpOjExMztzOjI1OiJwaHBccysiXHMqXC5ccypcJHdzb19wYXRoIjtpOjExNDtzOjg5OiJAKmFzc2VydFxzKlwoKlxzKlwkXyhHRVR8UE9TVHxTRVJWRVJ8Q09PS0lFfFJFUVVFU1QpXHMqXFtccypbJyJdezAsMX0uKz9bJyJdezAsMX1ccypcXVxzKiI7aToxMTU7czoxMDoiZXZhMS4rP1NpciI7aToxMTY7czo4OiJsc1xzKy1sYSI7aToxMTc7czoxMTM6ImlmXHMqXChccyppc19jYWxsYWJsZVxzKlwoKlxzKlsnIl17MCwxfShzeXN0ZW18c2hlbGxfZXhlY3xwYXNzdGhydXxlc2NhcGVzaGVsbGNtZHxwb3Blbnxwcm9jX29wZW4pWyciXXswLDF9XHMqXCkqIjtpOjExODtzOjkzOiJcJGNtZFxzKj1ccypcKFxzKkAqXCRfKEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVClccypcW1xzKlsnIl17MCwxfS4rP1snIl17MCwxfVxzKlxdXHMqXCkiO2k6MTE5O3M6NTE6ImRvY3VtZW50XC53cml0ZVxzKlwoXHMqdW5lc2NhcGVccypcKFxzKlsnIl17MCwxfSUzQyI7aToxMjA7czo5NjoiXCRmdW5jdGlvblxzKlwoKlxzKkAqXCRfKEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVClccypcW1xzKlsnIl17MCwxfWNtZFsnIl17MCwxfVxzKlxdXHMqXCkqIjtpOjEyMTtzOjIzOiJcJGZlXCgiXCRjbWRccysyPiYxIlwpOyI7aToxMjI7czoxMjA6ImlmXHMqXChccypmdW5jdGlvbl9leGlzdHNccypcKFxzKlsnIl17MCwxfShzeXN0ZW18c2hlbGxfZXhlY3xwYXNzdGhydXxlc2NhcGVzaGVsbGNtZHxwb3Blbnxwcm9jX29wZW4pWyciXXswLDF9XHMqXClccypcKSI7aToxMjM7czo4ODoic3lzdGVtXCgiXCRjbWRccysxPlxzKi90bXAvY21kdGVtcFxzKzI+JjE7XHMqY2F0XHMrL3RtcC9jbWR0ZW1wO1xzKnJtXHMrL3RtcC9jbWR0ZW1wIlwpOyI7aToxMjQ7czo2Mzoic2V0Y29va2llXCgqXHMqWyciXXswLDF9bXlzcWxfd2ViX2FkbWluX3VzZXJuYW1lWyciXXswLDF9XHMqXCkqIjtpOjEyNTtzOjUzOiJzaGVsbF9leGVjXHMqXCgqXHMqWyciXXswLDF9dW5hbWVccystYVsnIl17MCwxfVxzKlwpKiI7aToxMjY7czo5NDoic2hlbGxfZXhlY1xzKlwoKlxzKkAqXCRfUE9TVFxzKlxbXHMqWyciXXswLDF9Lis/WyciXXswLDF9XHMqXF1ccypcLlxzKiJccyoyXHMqPlxzKiYxXHMqIlxzKlwpKiI7aToxMjc7czo0MzoiIUAqXCRfUkVRVUVTVFxzKlxbXHMqImM5OXNoX3N1cmwiXHMqXF1ccypcKSI7aToxMjg7czozNzoiXCRsb2dpblxzKj1ccypAKnBvc2l4X2dldHVpZFwoKlxzKlwpKiI7aToxMjk7czozMDoiZXhlY1xzKlwoKlxzKlsnIl17MCwxfXJtXHMqLWZyIjtpOjEzMDtzOjMwOiJleGVjXHMqXCgqXHMqWyciXXswLDF9cm1ccyotcmYiO2k6MTMxO3M6MzQ6ImV4ZWNccypcKCpccypbJyJdezAsMX1ybVxzKi1yXHMqLWYiO2k6MTMyO3M6MzE6Im5jZnRwcHV0XHMqLXVccypcJGZ0cF91c2VyX25hbWUiO2k6MTMzO3M6MTAyOiJydW5jb21tYW5kXHMqXChccypbJyJdezAsMX1zaGVsbGhlbHBbJyJdezAsMX1ccyosXHMqWyciXXswLDF9KEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVClbJyJdezAsMX0iO2k6MTM0O3M6NTU6IntccypcJFxzKntccypwYXNzdGhydVxzKlwoKlxzKlwkY21kXHMqXClccyp9XHMqfVxzKjxicj4iO2k6MTM1O3M6NTM6InBhc3N0aHJ1XHMqXCgqXHMqZ2V0ZW52XHMqXCgqXHMqJ0hUVFBfQUNDRVBUX0xBTkdVQUdFIjtpOjEzNjtzOjUzOiJwYXNzdGhydVxzKlwoKlxzKmdldGVudlxzKlwoKlxzKiJIVFRQX0FDQ0VQVF9MQU5HVUFHRSI7aToxMzc7czo0MDoiZXZhbFxzKlwoKlxzKmd6aW5mbGF0ZVxzKlwoKlxzKnN0cl9yb3QxMyI7aToxMzg7czo4NzoiU0VMRUNUXHMrMVxzK0ZST01ccytteXNxbFwudXNlclxzK1dIRVJFXHMrY29uY2F0XChccypgdXNlcmBccyosXHMqJ0AnXHMqLFxzKmBob3N0YFxzKlwpIjtpOjEzOTtzOjk3OiJcJE1lc3NhZ2VTdWJqZWN0XHMqPVxzKmJhc2U2NF9kZWNvZGVccypcKFxzKlwkX1BPU1RccypcW1xzKlsnIl17MCwxfW1zZ3N1YmplY3RbJyJdezAsMX1ccypcXVxzKlwpIjtpOjE0MDtzOjQ0OiJyZW5hbWVccypcKFxzKlsnIl17MCwxfXdzb1wucGhwWyciXXswLDF9XHMqLCI7aToxNDE7czo2ODoiZmlsZXBhdGhccyo9XHMqQCpyZWFscGF0aFxzKlwoXHMqXCRfUE9TVFxzKlxbXHMqImZpbGVwYXRoIlxzKlxdXHMqXCkiO2k6MTQyO3M6Njg6ImZpbGVwYXRoXHMqPVxzKkAqcmVhbHBhdGhccypcKFxzKlwkX1BPU1RccypcW1xzKidmaWxlcGF0aCdccypcXVxzKlwpIjtpOjE0MztzOjE5OiJyb3VuZFxzKlwoXHMqMFxzKlwrIjtpOjE0NDtzOjQwOiJldmFsXHMqXCgqXHMqYmFzZTY0X2RlY29kZVxzKlwoKlxzKkAqXCRfIjtpOjE0NTtzOjg3OiJ3c29FeFxzKlwoXHMqJ1xzKnRhclxzKmNmenZccyonXHMqXC5ccyplc2NhcGVzaGVsbGFyZ1xzKlwoXHMqXCRfUE9TVFxbXHMqJ3AyJ1xzKlxdXHMqXCkiO2k6MTQ2O3M6MTk6IkNvbnRlbnQtVHlwZTpccypcJF8iO2k6MTQ3O3M6Njg6IldTT3NldGNvb2tpZVxzKlwoXHMqbWQ1XHMqXChccypAKlwkX1NFUlZFUlxbXHMqIkhUVFBfSE9TVCJccypcXVxzKlwpIjtpOjE0ODtzOjY4OiJXU09zZXRjb29raWVccypcKFxzKm1kNVxzKlwoXHMqQCpcJF9TRVJWRVJcW1xzKidIVFRQX0hPU1QnXHMqXF1ccypcKSI7aToxNDk7czoxNTA6IlwkaW5mbyBcLj0gXChcKFwkcGVybXNccyomXHMqMHgwMDQwXClccypcP1woXChcJHBlcm1zXHMqJlxzKjB4MDgwMFwpXHMqXD9ccyoncydccyo6XHMqJ3gnXHMqXClccyo6XChcKFwkcGVybXNccyomXHMqMHgwODAwXClccypcP1xzKidTJ1xzKjpccyonLSdccypcKSI7aToxNTA7czozMDoiZGVmYXVsdF9hY3Rpb25ccyo9XHMqJ0ZpbGVzTWFuIjtpOjE1MTtzOjMzOiJzeXN0ZW1ccytmaWxlXHMrZG9ccytub3RccytkZWxldGUiO2k6MTUyO3M6MTk6ImhhY2tlZFxzK2J5XHMrSG1laTciO2k6MTUzO3M6MTE6ImJ5XHMrR3JpbmF5IjtpOjE1NDtzOjIzOiJDYXB0YWluXHMrQ3J1bmNoXHMrVGVhbSI7aToxNTU7czo5NjoiXCRfKEdFVHxQT1NUfFNFUlZFUnxDT09LSUV8UkVRVUVTVClcW1xzKlsnIl17MCwxfXAyWyciXXswLDF9XHMqXF1ccyo9PVxzKlsnIl17MCwxfWNobW9kWyciXXswLDF9Ijt9"));
$g_ExceptFlex = unserialize(base64_decode("YTo1Mjp7aTowO3M6MTA6Im11c3QtcmV2YWwiO2k6MTtzOjk6InJldHJpZXZhbCI7aToyO3M6OToiZG91YmxldmFsIjtpOjM7czo2NjoicmVxdWlyZVxzKlwoKlxzKlwkX1NFUlZFUlxbXHMqWyciXXswLDF9RE9DVU1FTlRfUk9PVFsnIl17MCwxfVxzKlxdIjtpOjQ7czo3MToicmVxdWlyZV9vbmNlXHMqXCgqXHMqXCRfU0VSVkVSXFtccypbJyJdezAsMX1ET0NVTUVOVF9ST09UWyciXXswLDF9XHMqXF0iO2k6NTtzOjY2OiJpbmNsdWRlXHMqXCgqXHMqXCRfU0VSVkVSXFtccypbJyJdezAsMX1ET0NVTUVOVF9ST09UWyciXXswLDF9XHMqXF0iO2k6NjtzOjcxOiJpbmNsdWRlX29uY2VccypcKCpccypcJF9TRVJWRVJcW1xzKlsnIl17MCwxfURPQ1VNRU5UX1JPT1RbJyJdezAsMX1ccypcXSI7aTo3O3M6MTc6Ilwkc21hcnR5LT5fZXZhbFwoIjtpOjg7czozMDoicHJlcFxzK3JtXHMrLXJmXHMrJXtidWlsZHJvb3R9IjtpOjk7czoyMjoiVE9ETzpccytybVxzKy1yZlxzK3RoZSI7aToxMDtzOjI3OiJrcnNvcnRcKFwkd3BzbWlsaWVzdHJhbnNcKTsiO2k6MTE7czo2MzoiZG9jdW1lbnRcLndyaXRlXCh1bmVzY2FwZVwoIiUzQ3NjcmlwdCBzcmM9JyIgXCsgZ2FKc0hvc3QgXCsgImdvIjtpOjEyO3M6NjoiXC5leGVjIjtpOjEzO3M6ODoiZXhlY1woXCkiO2k6MTQ7czoyNDoiXCR4MSA9IFwkdGhpcy0+dyAtIFwkeDE7IjtpOjE1O3M6MzE6ImFzb3J0XChcJENhY2hlRGlyT2xkRmlsZXNBZ2VcKTsiO2k6MTY7czoxMzoiXCgncjU3c2hlbGwnLCI7aToxNztzOjI1OiJldmFsXCgibGlzdGVuZXIgPSAiXCtsaXN0IjtpOjE4O3M6ODoiZXZhbFwoXCkiO2k6MTk7czozMzoicHJlZ19yZXBsYWNlX2NhbGxiYWNrXCgnL1xce1woaW1hIjtpOjIwO3M6MjE6ImV2YWwgXChfY3RNZW51SW5pdFN0ciI7aToyMTtzOjI5OiJiYXNlNjRfZGVjb2RlXChcJGFjY291bnRLZXlcKSI7aToyMjtzOjM5OiJiYXNlNjRfZGVjb2RlXChcJGRhdGFcKVwpOyBcJGFwaS0+c2V0UmUiO2k6MjM7czo0ODoicmVxdWlyZVwoXCRfU0VSVkVSXFtcXCJET0NVTUVOVF9ST09UXFwiXF1cLlxcIi9iIjtpOjI0O3M6NjU6ImJhc2U2NF9kZWNvZGVcKFwkX1JFUVVFU1RcWydwYXJhbWV0ZXJzJ1xdXCk7IGlmXChDaGVja1NlcmlhbGl6ZWREIjtpOjI1O3M6NjM6InBjbnRsX2V4ZWMnID0+IEFycmF5XChBcnJheVwoMVwpLCBcJGFyUmVzdWx0XFsnU0VDVVJJTkdfRlVOQ1RJTyI7aToyNjtzOjM5OiJlY2hvICI8c2NyaXB0PmFsZXJ0XCgnIlwuQ1V0aWw6OkpTRXNjYXAiO2k6Mjc7czo2ODoiYmFzZTY0X2RlY29kZVwoXCRfUkVRVUVTVFxbJ3RpdGxlX2NoYW5nZXJfbGluaydcXVwpOyBpZiBcKHN0cmxlblwoXCQiO2k6Mjg7czo1MToiZXZhbFwoJ1wkaGV4ZHRpbWUgPSAiJyBcLiBcJGhleGR0aW1lIFwuICciOydcKTsgXCRmIjtpOjI5O3M6NTI6ImVjaG8gIjxzY3JpcHQ+YWxlcnRcKCdcJHJvdy0+dGl0bGUgLSAiXC5fTU9EVUxFX0lTX0UiO2k6MzA7czozNzoiZWNobyAiPHNjcmlwdD5hbGVydFwoJ1wkY2lkcyAiXC5fQ0FOTiI7aTozMTtzOjQxOiJpZlwoMVwpIHsgXCR2X2hvdXIgPSBcKFwkcF9oZWFkZXJcWydtdGltZSI7aTozMjtzOjcwOiJkb2N1bWVudFwud3JpdGVcKHVuZXNjYXBlXCgiJTNDc2NyaXB0JTIwc3JjPSUyMmh0dHAiIFwrIFwoXCgiaHR0cHM6IiA9IjtpOjMzO3M6MzI6ImVjaG8gIjxzY3JpcHQ+YWxlcnRcKCciXC5KVGV4dDo6IjtpOjM0O3M6MjU6IidmaWxlbmFtZSdcKSwgXCgncjU3c2hlbGwiO2k6MzU7czo0MzoiZWNobyAiPHNjcmlwdD5hbGVydFwoJyIgXC4gXCRlcnJNc2cgXC4gIidcKSI7aTozNjtzOjQyOiJlY2hvICI8c2NyaXB0PmFsZXJ0XChcXCJFcnJvciB3aGVuIGxvYWRpbmciO2k6Mzc7czo0MzoiZWNobyAiPHNjcmlwdD5hbGVydFwoJyJcLkpUZXh0OjpfXCgnVkFMSURfRSI7aTozODtzOjg6ImV2YWxcKFwpIjtpOjM5O3M6ODoiJ3N5c3RlbSciO2k6NDA7czo2OiInZXZhbCciO2k6NDE7czo2OiIiZXZhbCIiO2k6NDI7czo4OiJjb3B5XChcKSI7aTo0MztzOjc6Il9zeXN0ZW0iO2k6NDQ7czo5OiJzYXZlMmNvcHkiO2k6NDU7czoxMDoiZmlsZXN5c3RlbSI7aTo0NjtzOjg6InNlbmRtYWlsIjtpOjQ3O3M6ODoiY2FuQ2htb2QiO2k6NDg7czo5OiJkb3VibGV2YWwiO2k6NDk7czoxNjoib3BlcmF0aW5nIHN5c3RlbSI7aTo1MDtzOjEwOiJnbG9iYWxldmFsIjtpOjUxO3M6MjE6IndpdGggMC8wLzAgaWYgXCgxXCkgeyI7fQ=="));
$g_SusDB = unserialize(base64_decode("YToxMTY6e2k6MDtzOjc6IlNwYW1tZXIiO2k6MTtzOjQwOiJpbmlfZ2V0XHMqXCgqWyciXXswLDF9c2FmZV9tb2RlWyciXXswLDF9IjtpOjI7czoxNToiZXZhbFxzKlsnIlwoXCRdIjtpOjM7czoxNzoiYXNzZXJ0XHMqWyciXChcJF0iO2k6NDtzOjI4OiJzcnBhdGg6Ly9cLlwuL1wuXC4vXC5cLi9cLlwuIjtpOjU7czoxMjoicGhwaW5mb1xzKlwoIjtpOjY7czoxNjoiU0hPV1xzK0RBVEFCQVNFUyI7aTo3O3M6MTA6InBvcGVuXHMqXCgiO2k6ODtzOjk6ImV4ZWNccypcKCI7aTo5O3M6MTE6InN5c3RlbVxzKlwoIjtpOjEwO3M6MTM6InBhc3N0aHJ1XHMqXCgiO2k6MTE7czoxNDoicHJvY19vcGVuXHMqXCgiO2k6MTI7czoxNToic2hlbGxfZXhlY1xzKlwoIjtpOjEzO3M6MTY6ImluaV9yZXN0b3JlXHMqXCgiO2k6MTQ7czo3OiJkbFxzKlwoIjtpOjE1O3M6MTI6InN5bWxpbmtccypcKCI7aToxNjtzOjEwOiJjaGdycFxzKlwoIjtpOjE3O3M6MTI6ImluaV9zZXRccypcKCI7aToxODtzOjExOiJwdXRlbnZccypcKCI7aToxOTtzOjEzOiJnZXRteXVpZFxzKlwoIjtpOjIwO3M6MTQ6ImZzb2Nrb3BlblxzKlwoIjtpOjIxO3M6MTc6InBvc2l4X3NldHVpZFxzKlwoIjtpOjIyO3M6MTc6InBvc2l4X3NldHNpZFxzKlwoIjtpOjIzO3M6MTg6InBvc2l4X3NldHBnaWRccypcKCI7aToyNDtzOjE1OiJwb3NpeF9raWxsXHMqXCgiO2k6MjU7czoyNzoiYXBhY2hlX2NoaWxkX3Rlcm1pbmF0ZVxzKlwoIjtpOjI2O3M6MTA6ImNobW9kXHMqXCgiO2k6Mjc7czoxMDoiY2hkaXJccypcKCI7aToyODtzOjE1OiJwY250bF9leGVjXHMqXCgiO2k6Mjk7czoxMjoidmlydHVhbFxzKlwoIjtpOjMwO3M6MTU6InByb2NfY2xvc2VccypcKCI7aTozMTtzOjIwOiJwcm9jX2dldF9zdGF0dXNccypcKCI7aTozMjtzOjE5OiJwcm9jX3Rlcm1pbmF0ZVxzKlwoIjtpOjMzO3M6MTQ6InByb2NfbmljZVxzKlwoIjtpOjM0O3M6MTM6ImdldG15Z2lkXHMqXCgiO2k6MzU7czoxOToicHJvY19nZXRzdGF0dXNccypcKCI7aTozNjtzOjE1OiJwcm9jX2Nsb3NlXHMqXCgiO2k6Mzc7czoxOToiZXNjYXBlc2hlbGxjbWRccypcKCI7aTozODtzOjE5OiJlc2NhcGVzaGVsbGFyZ1xzKlwoIjtpOjM5O3M6MTY6InNob3dfc291cmNlXHMqXCgiO2k6NDA7czoxMToicGNsb3NlXHMqXCgiO2k6NDE7czoxMzoic2FmZV9kaXJccypcKCI7aTo0MjtzOjc6ImRsXHMqXCgiO2k6NDM7czoxNjoiaW5pX3Jlc3RvcmVccypcKCI7aTo0NDtzOjEwOiJjaG93blxzKlwoIjtpOjQ1O3M6MTA6ImNoZ3JwXHMqXCgiO2k6NDY7czoxNzoic2hvd25fc291cmNlXHMqXCgiO2k6NDc7czoxOToibXlzcWxfbGlzdF9kYnNccypcKCI7aTo0ODtzOjIxOiJnZXRfY3VycmVudF91c2VyXHMqXCgiO2k6NDk7czoxMjoiZ2V0bXlpZFxzKlwoIjtpOjUwO3M6OToibGVha1xzKlwoIjtpOjUxO3M6MTU6InBmc29ja29wZW5ccypcKCI7aTo1MjtzOjIxOiJnZXRfY3VycmVudF91c2VyXHMqXCgiO2k6NTM7czoxMToic3lzbG9nXHMqXCgiO2k6NTQ7czoxODoiXCRkZWZhdWx0X3VzZV9hamF4IjtpOjU1O3M6MjE6ImV2YWxccypcKCpccyp1bmVzY2FwZSI7aTo1NjtzOjMxOiJkb2N1bWVudFwud3JpdGVccypcKFxzKnVuZXNjYXBlIjtpOjU3O3M6OToiY29weVxzKlwoIjtpOjU4O3M6MjM6Im1vdmVfdXBsb2FkZWRfZmlsZVxzKlwoIjtpOjU5O3M6ODoiXC4zMzMzMzMiO2k6NjA7czo4OiJcLjY2NjY2NiI7aTo2MTtzOjIxOiJyb3VuZFxzKlwoKlxzKjBccypcKSoiO2k6NjI7czoxMTE6ImNvcHlccypcKCpccypcJF9GSUxFU1xzKlxbXHMqWyciXXswLDF9ZmlsZVsnIl17MCwxfVxzKlxdXFtccypbJyJdezAsMX10bXBfbmFtZVsnIl17MCwxfVxzKlxdXHMqLFxzKlwkdXBsb2FkZmlsZSI7aTo2MztzOjEyNjoibW92ZV91cGxvYWRlZF9maWxlc1xzKlwoKlxzKlwkX0ZJTEVTXHMqXFtccypbJyJdezAsMX1maWxlWyciXXswLDF9XHMqXF1cW1xzKlsnIl17MCwxfXRtcF9uYW1lWyciXXswLDF9XHMqXF1ccyosXHMqXCR1cGxvYWRmaWxlIjtpOjY0O3M6NTA6ImluaV9nZXRccypcKFxzKlsnIl17MCwxfWRpc2FibGVfZnVuY3Rpb25zWyciXXswLDF9IjtpOjY1O3M6MzY6IlVOSU9OXHMrU0VMRUNUXHMrWyciXXswLDF9MFsnIl17MCwxfSI7aTo2NjtzOjEwOiIyXHMqPlxzKiYxIjtpOjY3O3M6NTc6ImVjaG9ccypcKCpccypcJF9TRVJWRVJcW1snIl17MCwxfURPQ1VNRU5UX1JPT1RbJyJdezAsMX1cXSI7aTo2ODtzOjM3OiI9XHMqQXJyYXlccypcKCpccypiYXNlNjRfZGVjb2RlXHMqXCgqIjtpOjY5O3M6MTQ6ImtpbGxhbGxccystXGQrIjtpOjcwO3M6NzoiZXJpdXFlciI7aTo3MTtzOjEwOiJ0b3VjaFxzKlwoIjtpOjcyO3M6Nzoic3Noa2V5cyI7aTo3MztzOjg6IkBpbmNsdWRlIjtpOjc0O3M6ODoiQHJlcXVpcmUiO2k6NzU7czozODoiQGluaV9zZXRccypcKCpbJyJdezAsMX1hbGxvd191cmxfZm9wZW4iO2k6NzY7czoxODoiQGZpbGVfZ2V0X2NvbnRlbnRzIjtpOjc3O3M6MTc6ImZpbGVfcHV0X2NvbnRlbnRzIjtpOjc4O3M6NDY6ImFuZHJvaWRccypcfFxzKm1pZHBccypcfFxzKmoybWVccypcfFxzKnN5bWJpYW4iO2k6Nzk7czoyODoiQHNldGNvb2tpZVxzKlwoKlsnIl17MCwxfWhpdCI7aTo4MDtzOjEwOiJAZmlsZW93bmVyIjtpOjgxO3M6NjoiPGt1a3U+IjtpOjgyO3M6NToic3lwZXgiO2k6ODM7czo5OiJcJGJlZWNvZGUiO2k6ODQ7czo4OiJCYWNrZG9vciI7aTo4NTtzOjE0OiJwaHBfdW5hbWVccypcKCI7aTo4NjtzOjU1OiJtYWlsXHMqXCgqXHMqXCR0b1xzKixccypcJHN1YmpccyosXHMqXCRtc2dccyosXHMqXCRmcm9tIjtpOjg3O3M6Njc6Im1haWxccypcKCpccypcJHNlbmRccyosXHMqXCRzdWJqZWN0XHMqLFxzKlwkaGVhZGVyc1xzKixccypcJG1lc3NhZ2UiO2k6ODg7czo2NToibWFpbFxzKlwoKlxzKlwkdG9ccyosXHMqXCRzdWJqZWN0XHMqLFxzKlwkbWVzc2FnZVxzKixccypcJGhlYWRlcnMiO2k6ODk7czoxMjA6InN0cnBvc1xzKlwoKlxzKlwkbmFtZVxzKixccypbJyJdezAsMX1IVFRQX1snIl17MCwxfVxzKlwpKlxzKiE9PVxzKjBccyomJlxzKnN0cnBvc1xzKlwoKlxzKlwkbmFtZVxzKixccypbJyJdezAsMX1SRVFVRVNUXyI7aTo5MDtzOjU0OiJpc19mdW5jdGlvbl9lbmFibGVkXHMqXChccyoqWyciXXswLDF9aWdub3JlX3VzZXJfYWJvcnQiO2k6OTE7czozMDoiZWNob1xzKlwoKlxzKmZpbGVfZ2V0X2NvbnRlbnRzIjtpOjkyO3M6MjY6ImVjaG9ccypcKCpbJyJdezAsMX08c2NyaXB0IjtpOjkzO3M6MzE6InByaW50XHMqXCgqXHMqZmlsZV9nZXRfY29udGVudHMiO2k6OTQ7czoyNzoicHJpbnRccypcKCpbJyJdezAsMX08c2NyaXB0IjtpOjk1O3M6ODU6IjxtYXJxdWVlXHMrc3R5bGVccyo9XHMqWyciXXswLDF9cG9zaXRpb25ccyo6XHMqYWJzb2x1dGVccyo7XHMqd2lkdGhccyo6XHMqXGQrXHMqcHhccyoiO2k6OTY7czo0MjoiPVxzKlsnIl17MCwxfVwuXC4vXC5cLi9cLlwuL3dwLWNvbmZpZ1wucGhwIjtpOjk3O3M6NzoiZWdnZHJvcCI7aTo5ODtzOjk6InJ3eHJ3eHJ3eCI7aTo5OTtzOjE1OiJlcnJvcl9yZXBvcnRpbmciO2k6MTAwO3M6MTY6IkBjcmVhdGVfZnVuY3Rpb24iO2k6MTAxO3M6NDM6Intccypwb3NpdGlvblxzKjpccyphYnNvbHV0ZTtccypsZWZ0XHMqOlxzKi0iO2k6MTAyO3M6MTU6IjxzY3JpcHRccythc3luYyI7aToxMDM7czo2NjoiX1snIl17MCwxfVxzKlxdXHMqPVxzKkFycmF5XHMqXChccypiYXNlNjRfZGVjb2RlXHMqXCgqXHMqWyciXXswLDF9IjtpOjEwNDtzOjMzOiJBZGRUeXBlXHMrYXBwbGljYXRpb24veC1odHRwZC1jZ2kiO2k6MTA1O3M6NDQ6ImdldGVudlxzKlwoKlxzKlsnIl17MCwxfUhUVFBfQ09PS0lFWyciXXswLDF9IjtpOjEwNjtzOjQ2OiJpZ25vcmVfdXNlcl9hYm9ydFxzKlwoKlxzKlsnIl17MCwxfSoxWyciXXswLDF9IjtpOjEwNztzOjIxOiJcJF9SRVFVRVNUXHMqXFtccyolMjIiO2k6MTA4O3M6NTE6InVybFxzKlwoWyciXXswLDF9ZGF0YVxzKjpccyppbWFnZS9wbmc7XHMqYmFzZTY0XHMqLCI7aToxMDk7czo1MToidXJsXHMqXChbJyJdezAsMX1kYXRhXHMqOlxzKmltYWdlL2dpZjtccypiYXNlNjRccyosIjtpOjExMDtzOjMwOiI6XHMqdXJsXHMqXChccypbJyJdezAsMX08XD9waHAiO2k6MTExO3M6MTc6IjwvaHRtbD4uKz88c2NyaXB0IjtpOjExMjtzOjE3OiI8L2h0bWw+Lis/PGlmcmFtZSI7aToxMTM7czo3MDoiKHN5c3RlbXxzaGVsbF9leGVjfHBhc3N0aHJ1fGVzY2FwZXNoZWxsY21kfHBvcGVufHByb2Nfb3BlbilccypbJyJcKFwkXSI7aToxMTQ7czo5OiJtYWlsXHMqXCgiO2k6MTE1O3M6NDY6ImZpbGVfZ2V0X2NvbnRlbnRzXHMqXCgqXHMqWyciXXswLDF9cGhwOi8vaW5wdXQiO30="));
$g_SusDBPrio = unserialize(base64_decode("YToxMTU6e2k6MDtpOjA7aToxO2k6MDtpOjI7aTowO2k6MztpOjA7aTo0O2k6MTtpOjU7aToxO2k6NjtpOjA7aTo3O2k6MDtpOjg7aTowO2k6OTtpOjA7aToxMDtpOjA7aToxMTtpOjA7aToxMjtpOjA7aToxMztpOjA7aToxNDtpOjA7aToxNTtpOjA7aToxNjtpOjA7aToxNztpOjA7aToxODtpOjA7aToxOTtpOjA7aToyMDtpOjA7aToyMTtpOjA7aToyMjtpOjA7aToyMztpOjA7aToyNDtpOjA7aToyNTtpOjE7aToyNjtpOjE7aToyNztpOjA7aToyODtpOjA7aToyOTtpOjA7aTozMDtpOjA7aTozMTtpOjA7aTozMjtpOjA7aTozMztpOjA7aTozNDtpOjA7aTozNTtpOjA7aTozNjtpOjA7aTozNztpOjA7aTozODtpOjA7aTozOTtpOjA7aTo0MDtpOjA7aTo0MTtpOjA7aTo0MjtpOjA7aTo0MztpOjA7aTo0NDtpOjA7aTo0NTtpOjA7aTo0NjtpOjA7aTo0NztpOjA7aTo0ODtpOjA7aTo0OTtpOjA7aTo1MDtpOjA7aTo1MTtpOjA7aTo1MjtpOjA7aTo1MztpOjE7aTo1NDtpOjA7aTo1NTtpOjA7aTo1NjtpOjI7aTo1NztpOjE7aTo1ODtpOjA7aTo1OTtpOjA7aTo2MDtpOjA7aTo2MTtpOjI7aTo2MjtpOjI7aTo2MztpOjA7aTo2NDtpOjA7aTo2NTtpOjA7aTo2NjtpOjI7aTo2NztpOjE7aTo2ODtpOjA7aTo2OTtpOjA7aTo3MDtpOjE7aTo3MTtpOjA7aTo3MjtpOjE7aTo3MztpOjE7aTo3NDtpOjE7aTo3NTtpOjM7aTo3NjtpOjI7aTo3NztpOjA7aTo3ODtpOjI7aTo3OTtpOjA7aTo4MDtpOjA7aTo4MTtpOjI7aTo4MjtpOjA7aTo4MztpOjA7aTo4NDtpOjA7aTo4NTtpOjE7aTo4NjtpOjE7aTo4NztpOjE7aTo4ODtpOjE7aTo4OTtpOjA7aTo5MDtpOjI7aTo5MTtpOjI7aTo5MjtpOjI7aTo5MztpOjI7aTo5NDtpOjI7aTo5NTtpOjE7aTo5NjtpOjE7aTo5NztpOjM7aTo5ODtpOjM7aTo5OTtpOjE7aToxMDA7aTozO2k6MTAxO2k6MztpOjEwMjtpOjI7aToxMDM7aTowO2k6MTA0O2k6MztpOjEwNTtpOjE7aToxMDY7aToxO2k6MTA3O2k6MztpOjEwODtpOjM7aToxMDk7aTozO2k6MTEwO2k6MTtpOjExMTtpOjE7aToxMTI7aToxO2k6MTEzO2k6NDtpOjExNDtpOjE7fQ=="));
$g_AdwareSig = unserialize(base64_decode("YToxNDp7aTowO3M6MTk6Il9fbGlua2ZlZWRfcm9ib3RzX18iO2k6MTtzOjEzOiJMSU5LRkVFRF9VU0VSIjtpOjI7czoxODoiX19zYXBlX2RlbGltaXRlcl9fIjtpOjM7czoyOToiZGlzcGVuc2VyXC5hcnRpY2xlc1wuc2FwZVwucnUiO2k6NDtzOjExOiJMRU5LX2NsaWVudCI7aTo1O3M6MTE6IlNBUEVfY2xpZW50IjtpOjY7czoxNzoiZGJcLnRydXN0bGlua1wucnUiO2k6NztzOjE2OiJ0bF9saW5rc19kYl9maWxlIjtpOjg7czoxNToiVHJ1c3RsaW5rQ2xpZW50IjtpOjk7czoxMzoiLT5ccypTTENsaWVudCI7aToxMDtzOjE2NjoiaXNzZXRccypcKCpccypcJF9TRVJWRVJccypcW1xzKlsnIl17MCwxfUhUVFBfVVNFUl9BR0VOVFsnIl17MCwxfVxzKlxdXHMqXClccyomJlxzKlwoKlxzKlwkX1NFUlZFUlxzKlxbXHMqWyciXXswLDF9SFRUUF9VU0VSX0FHRU5UWyciXXswLDF9XF1ccyo9PVxzKlsnIl17MCwxfUxNUF9Sb2JvdCI7aToxMTtzOjQzOiJcJGxpbmtzLT5ccypyZXR1cm5fbGlua3NccypcKCpccypcJGxpYl9wYXRoIjtpOjEyO3M6NDQ6IlwkbGlua3NfY2xhc3Nccyo9XHMqbmV3XHMrR2V0X2xpbmtzXHMqXCgqXHMqIjtpOjEzO3M6NTI6IlsnIl17MCwxfVxzKixccypbJyJdezAsMX1cLlsnIl17MCwxfVxzKlwpKlxzKjtccypcPz4iO30="));
$g_JSVirSig = unserialize(base64_decode("YTo1OTp7aTowO3M6NDE6ImY9J2YnXCsncidcKydvJ1wrJ20nXCsnQ2gnXCsnYXJDJ1wrJ29kZSc7IjtpOjE7czoyMjoiXC5wcm90b3R5cGVcLmF9Y2F0Y2hcKCI7aToyO3M6Mzc6InRyeXtCb29sZWFuXChcKVwucHJvdG90eXBlXC5xfWNhdGNoXCgiO2k6MztzOjM0OiJpZlwoUmVmXC5pbmRleE9mXCgnXC5nb29nbGVcLidcKSE9IjtpOjQ7czo4NjoiaW5kZXhPZlx8aWZcfHJjXHxsZW5ndGhcfG1zblx8eWFob29cfHJlZmVycmVyXHxhbHRhdmlzdGFcfG9nb1x8YmlcfGhwXHx2YXJcfGFvbFx8cXVlcnkiO2k6NTtzOjU0OiJBcnJheVwucHJvdG90eXBlXC5zbGljZVwuY2FsbFwoYXJndW1lbnRzXClcLmpvaW5cKCIiXCkiO2k6NjtzOjgyOiJxPWRvY3VtZW50XC5jcmVhdGVFbGVtZW50XCgiZCJcKyJpIlwrInYiXCk7cVwuYXBwZW5kQ2hpbGRcKHFcKyIiXCk7fWNhdGNoXChxd1wpe2g9IjtpOjc7czo3OToiXCt6ejtzcz1cW1xdO2Y9J2ZyJ1wrJ29tJ1wrJ0NoJztmXCs9J2FyQyc7ZlwrPSdvZGUnO3c9dGhpcztlPXdcW2ZcWyJzdWJzdHIiXF1cKCI7aTo4O3M6MTE1OiJzNVwocTVcKXtyZXR1cm4gXCtcK3E1O31mdW5jdGlvbiB5Zlwoc2Ysd2VcKXtyZXR1cm4gc2ZcLnN1YnN0clwod2UsMVwpO31mdW5jdGlvbiB5MVwod2JcKXtpZlwod2I9PTE2OFwpd2I9MTAyNTtlbHNlIjtpOjk7czo2NDoiaWZcKG5hdmlnYXRvclwudXNlckFnZW50XC5tYXRjaFwoL1woYW5kcm9pZFx8bWlkcFx8ajJtZVx8c3ltYmlhbiI7aToxMDtzOjEwNjoiZG9jdW1lbnRcLndyaXRlXCgnPHNjcmlwdCBsYW5ndWFnZT0iSmF2YVNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9IidcK2RvbWFpblwrJyI+PC9zY3InXCsnaXB0PidcKSI7aToxMTtzOjMxOiJodHRwOi8vcGhzcFwucnUvXy9nb1wucGhwXD9zaWQ9IjtpOjEyO3M6MTc6IjwvaHRtbD5ccyo8c2NyaXB0IjtpOjEzO3M6MTc6IjwvaHRtbD5ccyo8aWZyYW1lIjtpOjE0O3M6NjY6Ij1uYXZpZ2F0b3JcW2FwcFZlcnNpb25fdmFyXF1cLmluZGV4T2ZcKCJNU0lFIlwpIT0tMVw/JzxpZnJhbWUgbmFtZSI7aToxNTtzOjc6IlxceDY1QXQiO2k6MTY7czo5OiJcXHg2MXJDb2QiO2k6MTc7czoyMjoiImZyIlwrIm9tQyJcKyJoYXJDb2RlIiI7aToxODtzOjExOiI9ImV2IlwrImFsIiI7aToxOTtzOjc4OiJcW1woXChlXClcPyJzIjoiIlwpXCsicCJcKyJsaXQiXF1cKCJhXCQiXFtcKFwoZVwpXD8ic3UiOiIiXClcKyJic3RyIlxdXCgxXClcKTsiO2k6MjA7czozOToiZj0nZnInXCsnb20nXCsnQ2gnO2ZcKz0nYXJDJztmXCs9J29kZSc7IjtpOjIxO3M6MjA6ImZcKz1cKGhcKVw/J29kZSc6IiI7IjtpOjIyO3M6NDE6ImY9J2YnXCsncidcKydvJ1wrJ20nXCsnQ2gnXCsnYXJDJ1wrJ29kZSc7IjtpOjIzO3M6NTA6ImY9J2Zyb21DaCc7ZlwrPSdhckMnO2ZcKz0ncWdvZGUnXFsic3Vic3RyIlxdXCgyXCk7IjtpOjI0O3M6MTY6InZhclxzK2Rpdl9jb2xvcnMiO2k6MjU7czo5OiJ2YXJccytfMHgiO2k6MjY7czoyMDoiQ29yZUxpYnJhcmllc0hhbmRsZXIiO2k6Mjc7czo3OiJwaW5nbm93IjtpOjI4O3M6ODoic2VyY2hib3QiO2k6Mjk7czoxMDoia20wYWU5Z3I2bSI7aTozMDtzOjY6ImMzMjg0ZCI7aTozMTtzOjIyOiJpZlxzKlwoXHMqXGQrXHMqXClccyp7IjtpOjMyO3M6ODoiXFx4NjhhckMiO2k6MzM7czo4OiJcXHg2ZENoYSI7aTozNDtzOjc6IlxceDZmZGUiO2k6MzU7czo3OiJcXHg2ZmRlIjtpOjM2O3M6ODoiXFx4NDNvZGUiO2k6Mzc7czo3OiJcXHg3Mm9tIjtpOjM4O3M6NzoiXFx4NDNoYSI7aTozOTtzOjc6IlxceDcyQ28iO2k6NDA7czo4OiJcXHg0M29kZSI7aTo0MTtzOjEwOiJcLmR5bmRuc1wuIjtpOjQyO3M6OToiXC5keW5kbnMtIjtpOjQzO3M6Nzk6In1ccyplbHNlXHMqe1xzKmRvY3VtZW50XC53cml0ZVxzKlwoXHMqWyciXXswLDF9XC5bJyJdezAsMX1cKVxzKn1ccyp9XHMqUlwoXHMqXCkiO2k6NDQ7czo0NToiZG9jdW1lbnRcLndyaXRlXCh1bmVzY2FwZVwoJyUzQ2RpdiUyMGlkJTNEJTIyIjtpOjQ1O3M6MTg6IlwuYml0Y29pbnBsdXNcLmNvbSI7aTo0NjtzOjQxOiJcLnNwbGl0XCgiJiYiXCk7aD0yO3M9IiI7aWZcKG1cKWZvclwoaT0wOyI7aTo0NztzOjQ4OiJkb2N1bWVudFwud3JpdGVccypcKFxzKnVuZXNjYXBlXHMqXChbJyJdezAsMX0lM2MiO2k6NDg7czo0MToiPGlmcmFtZVxzK3NyYz0iaHR0cDovL2RlbHV4ZXNjbGlja3NcLnByby8iO2k6NDk7czo0NToiM0Jmb3JcfGZyb21DaGFyQ29kZVx8MkMyN1x8M0RcfDJDODhcfHVuZXNjYXBlIjtpOjUwO3M6NTg6Ijtccypkb2N1bWVudFwud3JpdGVcKFsnIl17MCwxfTxpZnJhbWVccypzcmM9Imh0dHA6Ly95YVwucnUiO2k6NTE7czoxMTA6IndcLmRvY3VtZW50XC5ib2R5XC5hcHBlbmRDaGlsZFwoc2NyaXB0XCk7XHMqY2xlYXJJbnRlcnZhbFwoaVwpO1xzKn1ccyp9XHMqLFxzKlxkK1xzKlwpXHMqO1xzKn1ccypcKVwoXHMqd2luZG93IjtpOjUyO3M6MTEwOiJpZlwoIWdcKFwpJiZ3aW5kb3dcLm5hdmlnYXRvclwuY29va2llRW5hYmxlZFwpe2RvY3VtZW50XC5jb29raWU9IjE9MTtleHBpcmVzPSJcK2VcLnRvR01UU3RyaW5nXChcKVwrIjtwYXRoPS8iOyI7aTo1MztzOjcwOiJubl9wYXJhbV9wcmVsb2FkZXJfY29udGFpbmVyXHw1MDAxXHxoaWRkZW5cfGlubmVySFRNTFx8aW5qZWN0XHx2aXNpYmxlIjtpOjU0O3M6MzE6IjwhLS0gW2EtekEtWjAtOV9dKz9cfFx8c3RhdCAtLT4iO2k6NTU7czo4NToiJnBhcmFtZXRlcj1cJGtleXdvcmQmc2U9XCRzZSZ1cj0xJkhUVFBfUkVGRVJFUj0nXCtlbmNvZGVVUklDb21wb25lbnRcKGRvY3VtZW50XC5VUkxcKSI7aTo1NjtzOjQ4OiJ3aW5kb3dzXHxzZXJpZXNcfDYwXHxzeW1ib3NcfGNlXHxtb2JpbGVcfHN5bWJpYW4iO2k6NTc7czoyOToiXFsiZXZhbCJcXVwoc1wpO319fX08L3NjcmlwdD4iO2k6NTg7czo1OToia0M3MEZNYmx5SmtGV1pvZENLbDFXWU9kV1lVbG5RelJuYmwxV1pzVkVkbGRtTDA1V1p0VjNZdlJHSTkiO30="));
$g_UnsafeFilesArray = array('td*.php', 'a{1,}.php', 'zd*.php', '123.php', 'testd*.php', 'asd.php', 'info.php', 'CHANGELOG.php',
'COPYRIGHT.php', 'CREDITS.php', 'INSTALL.php', 'LICENSE.php', 'LICENSES.php', 'backup.+?.zip',
'backup.+?.tar.gz', 'backup.+?.tgz',
'phpinfo.php', 'changelog.txt', 'readme.txt', 'INSTALLATION.php', 'dump.php', 'changelog.log');
$g_UnsafeDirArray = array('install', 'backup', 'webalizer', 'awstats');
////////////////////////////////////////////////////////////////////////////
if (!isCli() && !isset($_SERVER['HTTP_USER_AGENT'])) {
print "#################################################n";
print "# Error: cannot run on php-cgi. Need php as cli #n";
print "# #n";
print "# See FAQ: http://revisium.com/ai/faq.php #n";
print "#################################################n";
exit;
}
define('AI_VERSION', '20130401');
define('INFO_M', base64_decode('PGZvbnQgY29sb3I9I0UwNjA2MD7QotC+0LvRjNC60L4g0LTQu9GPINC90LXQutC+0LzQvNC10YDRh9C10YHQutC+0LPQviDQuNGB0L/QvtC70YzQt9C+0LLQsNC90LjRjyE8L2ZvbnQ+PC9oNT4='));
////////////////////////////////////////////////////////////////////////////
$l_Res = '';
$g_Structure = array();
$g_Counter = 0;
$g_NotRead = array();
$g_FileInfo = array();
$g_Iframer = array();
$g_PHPCodeInside = array();
$g_CriticalJS = array();
$g_HeuristicDetected = array();
$g_UnixExec = array();
$g_SkippedFolders = array();
$g_UnsafeFilesFound = array();
$g_CMS = array();
$g_SymLinks = array();
$g_HiddenFiles = array();
$g_TotalFolder = 0;
$g_TotalFiles = 0;
$g_FoundTotalDirs = 0;
$g_FoundTotalFiles = 0;
if (!isCli()) {
$defaults['site_url'] = 'http://' . $_SERVER['HTTP_HOST'] . '/';
}
define('CRC32_LIMIT', pow(2, 31) - 1);
define('CRC32_DIFF', CRC32_LIMIT * 2 -2);
error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING);
set_time_limit(0);
ini_set('max_execution_time', '90000');
ini_set('memory_limit','256M');
if (!function_exists('stripos')) {
function stripos($par_Str, $par_Entry, $Offset = 0) {
return strpos(strtolower($par_Str), strtolower($par_Entry), $Offset);
}
}
/**
* Print file
*/
function printFile() {
$l_FileName = $_GET['fn'];
$l_CRC = isset($_GET['c']) ? (int)$_GET['c'] : 0;
$l_Content = implode('', file($l_FileName));
$l_FileCRC = realCRC($l_Content);
if ($l_FileCRC != $l_CRC) {
print 'Доступ запрещен.';
exit;
}
print '<pre>' . htmlspecialchars($l_Content) . '</pre>';
}
/**
*
*/
function realCRC($str_in, $full = false)
{
$in = crc32( $full ? normal($str_in) : $str_in );
return ($in > CRC32_LIMIT) ? ($in - CRC32_DIFF) : $in;
}
/**
* Determine php script is called from the command line interface
* @return bool
*/
function isCli()
{
return php_sapi_name() == 'cli';
}
/*
*
*/
function shanonEntropy($par_Str)
{
$dic = array();
$len = strlen($par_Str);
for ($i = 0; $i < $len; $i++) {
$dic[$par_Str[$i]]++;
}
$result = 0.0;
$frequency = 0.0;
foreach ($dic as $item)
{
$frequency = (float)$item / (float)$len;
$result -= $frequency * (log($frequency) / log(2));
}
return $result;
}
function generatePassword ($length = 9)
{
// start with a blank password
$password = "";
// define possible characters - any character in this string can be
// picked for use in the password, so if you want to put vowels back in
// or add special characters such as exclamation marks, this is where
// you should do it
$possible = "2346789bcdfghjkmnpqrtvwxyzBCDFGHJKLMNPQRTVWXYZ";
// we refer to the length of $possible a few times, so let's grab it now
$maxlength = strlen($possible);
// check for length overflow and truncate if necessary
if ($length > $maxlength) {
$length = $maxlength;
}
// set up a counter for how many characters are in the password so far
$i = 0;
// add random characters to $password until $length is reached
while ($i < $length) {
// pick a random character from the possible ones
$char = substr($possible, mt_rand(0, $maxlength-1), 1);
// have we already used this character in $password?
if (!strstr($password, $char)) {
// no, so it's OK to add it onto the end of whatever we've already got...
$password .= $char;
// ... and increase the counter by one
$i++;
}
}
// done!
return $password;
}
/**
* Print to console
* @param mixed $text
* @param bool $add_lb Add line break
* @return void
*/
function stdOut($text, $add_lb = true)
{
if (!isCli())
return;
if (is_bool($text))
{
$text = $text ? 'true' : 'false';
}
else if (is_null($text))
{
$text = 'null';
}
if (!is_scalar($text))
{
$text = print_r($text, true);
}
@fwrite(STDOUT, $text . ($add_lb ? "n" : ''));
}
/**
* Print progress
* @param int $num Current file
*/
function printProgress($num, &$par_File)
{
$total_files = $GLOBALS['g_FoundTotalFiles'];
$elapsed_time = microtime(true) - START_TIME;
$stat = '';
if ($elapsed_time >= 1)
{
$elapsed_seconds = round($elapsed_time, 0);
$fs = floor($num / $elapsed_seconds);
$left_files = $total_files - $num;
if ($fs > 0)
{
$left_time = ($left_files / $fs); //ceil($left_files / $fs);
$stat = '. [Avg: ' . round($fs,2) . ' files/s' . ($left_time > 0 ? ' Left: ' . seconds2Human($left_time) : '') . ']';
}
}
$l_FN = substr($par_File, -60);
$text = "Scanning file [$l_FN] $num of {$total_files}" . $stat;
$text = str_pad($text, 160, ' ', STR_PAD_RIGHT);
stdOut(str_repeat(chr(8), 160) . $text, false);
}
/**
* Seconds to human readable
* @param int $seconds
* @return string
*/
function seconds2Human($seconds)
{
$r = '';
$_seconds = floor($seconds);
$ms = $seconds - $_seconds;
$seconds = $_seconds;
if ($hours = floor($seconds / 3600))
{
$r .= $hours . (isCli() ? ' h ' : ' час ');
$seconds = $seconds % 3600;
}
if ($minutes = floor($seconds / 60))
{
$r .= $minutes . (isCli() ? ' m ' : ' мин ');
$seconds = $seconds % 60;
}
if ($minutes<3) $r .= ' ' . $seconds + ($ms > 0 ? round($ms, 5) : 0) . (isCli() ? ' s' : ' сек'); //' сек' - not good for shell
return $r;
}
if (isCli())
{
$cli_options = array(
'm:' => 'memory:',
's:' => 'size:',
'a' => 'all',
'd:' => 'delay:',
'r:' => 'report:',
'f' => 'fast',
'p:' => 'path:',
'h' => 'help'
);
$options = getopt(implode('', array_keys($cli_options)), array_values($cli_options));
if (isset($options['h']) OR isset($options['help']))
{
$memory_limit = ini_get('memory_limit');
echo <<<HELP
AI-Bolit - Script to search for shells and other malicious software.
Usage: php {$_SERVER['PHP_SELF']} [OPTIONS] [PATH]
Current default path is: {$defaults['path']}
Mandatory arguments to long options are mandatory for short options too.
-p, --path=PATH Directory path to scan, by default the file directory is used
Current path: {$defaults['path']}
-m, --memory=SIZE Maximum amount of memory a script may consume. Current value: $memory_limit
Can take shorthand byte values (1M, 1G...)
-s, --size=SIZE Scan files are smaller than SIZE. 0 - All files. Current value: {$defaults['max_size_to_scan']}
-a, --all Scan all files (by default scan. js,. php,. html,. htaccess)
-d, --delay=INT delay in milliseconds when scanning files to reduce load on the file system (Default: 1)
-r, --report=PATH Filename of report html, by default 'AI-BOLIT-REPORT-dd-mm-YYYY_hh-mm.html' is used, relative to scan path
Enter your email address if you wish to report has been sent to the email.
You can also specify multiple email separated by commas.
--help display this help and exit
HELP;
exit;
}
$l_FastCli = false;
if (
(isset($options['memory']) AND !empty($options['memory']) AND ($memory = $options['memory']))
OR (isset($options['m']) AND !empty($options['m']) AND ($memory = $options['m']))
)
{
$memory = getBytes($memory);
if ($memory > 0)
{
$defaults['memory_limit'] = $memory;
}
}
if (
(isset($options['size']) AND !empty($options['size']) AND ($size = $options['size']) !== false)
OR (isset($options['s']) AND !empty($options['s']) AND ($size = $options['s']) !== false)
)
{
$size = getBytes($size);
$defaults['max_size_to_scan'] = $size > 0 ? $size : 0;
}
if (isset($options['f']))
{
$l_FastCli = true;
}
if (
(isset($options['delay']) AND !empty($options['delay']) AND ($delay = $options['delay']) !== false)
OR (isset($options['d']) AND !empty($options['d']) AND ($delay = $options['d']) !== false)
)
{
$delay = (int) $delay;
if (!($delay < 0))
{
$defaults['scan_delay'] = $delay;
}
}
if (isset($options['all']) OR isset($options['a']))
{
$defaults['scan_all_files'] = 1;
}
if (
(isset($options['report']) AND ($report = $options['report']) !== false)
OR (isset($options['r']) AND ($report = $options['r']) !== false)
)
{
define('REPORT', $report);
}
defined('REPORT') OR define('REPORT', 'AI-BOLIT-REPORT-' . date('d-m-Y_H-i') . '-' . rand(1, 999999) . '.html');
$last_arg = max(1, sizeof($_SERVER['argv']) - 1);
if (isset($_SERVER['argv'][$last_arg]))
{
$path = $_SERVER['argv'][$last_arg];
if (
substr($path, 0, 1) != '-'
AND (substr($_SERVER['argv'][$last_arg - 1], 0, 1) != '-' OR array_key_exists(substr($_SERVER['argv'][$last_arg - 1], -1), $cli_options)))
{
$defaults['path'] = $path;
}
}
if (
(isset($options['path']) AND !empty($options['path']) AND ($path = $options['path']) !== false)
OR (isset($options['p']) AND !empty($options['p']) AND ($path = $options['p']) !== false)
)
{
$defaults['path'] = $path;
}
}
// Init
define('MAX_ALLOWED_PHP_HTML_IN_DIR', 100);
define('BASE64_LENGTH', 69);
define('MAX_PREVIEW_LEN', 80);
define('MAX_EXT_LINKS', 1001);
// Perform full scan when running from command line
if (isCli() || isset($_GET['full'])) {
$defaults['scan_all_files'] = 1;
}
if ($l_FastCli) {
$defaults['scan_all_files'] = 0;
}
define('SCAN_ALL_FILES', (bool) $defaults['scan_all_files']);
define('SCAN_DELAY', (int) $defaults['scan_delay']);
define('MAX_SIZE_TO_SCAN', getBytes($defaults['max_size_to_scan']));
if ($defaults['memory_limit'] AND ($defaults['memory_limit'] = getBytes($defaults['memory_limit'])) > 0)
ini_set('memory_limit', $defaults['memory_limit']);
define('START_TIME', microtime(true));
define('ROOT_PATH', realpath($defaults['path']));
if (!ROOT_PATH)
{
if (isCli()) {
die(stdOut("Directory '{$defaults['path']}' not found!"));
}
}
elseif(!is_readable(ROOT_PATH))
{
if (isCli()) {
die(stdOut("Cannot read directory '" . ROOT_PATH . "'!"));
}
}
define('CURRENT_DIR', getcwd());
chdir(ROOT_PATH);
// Проверяем отчет
if (isCli() AND REPORT !== '' AND !getEmails(REPORT))
{
$report = str_replace('\', '/', REPORT);
$abs = strpos($report, '/') === 0 ? DIR_SEPARATOR : '';
$report = array_values(array_filter(explode('/', $report)));
$report_file = array_pop($report);
$report_path = realpath($abs . implode(DIR_SEPARATOR, $report));
define('REPORT_FILE', $report_file);
define('REPORT_PATH', $report_path);
if (REPORT_FILE AND REPORT_PATH AND is_file(REPORT_PATH . DIR_SEPARATOR . REPORT_FILE))
{
@unlink(REPORT_PATH . DIR_SEPARATOR . REPORT_FILE);
}
}
if (function_exists('phpinfo')) {
ob_start();
phpinfo();
$l_PhpInfo = ob_get_contents();
ob_end_clean();
$l_PhpInfo = str_replace('border: 1px', '', $l_PhpInfo);
preg_match('|<body>(.*)</body>|smi', $l_PhpInfo, $l_PhpInfoBody);
}
$l_Result =<<<MAIN_PAGE
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<META NAME="ROBOTS" CONTENT="NOINDEX,NOFOLLOW">
<style type="text/css">
body {
font-family: Georgia;
color: #303030;
background: #FFFFF0;
font-size: 12px;
margin: 20px;
padding: 0;
}
h3 {
font-size: 27px;
margin: 0 0;
}
.sec {
font-size: 25px;
margin-bottom: 10px;
}
.warn {
color: #FF4C00;
margin: 0 0 20px 0;
}
.warn .it {
color: #FF4C00;
}
.warn2 {
color: #42ADFF;
margin: 0 0 20px 0;
}
.warn2 .it {
color: #42ADFF;
}
.ok {
color: #007F0E;
margin: 0 0 20px 0;
}
.vir {
color: #A00000;
margin: 0 0 20px 0;
}
.vir .it {
color: #A00000;
}
.disclaimer {
font-size: 11px;
font-family: Arial;
color: #505050;
margin: 10px 0 10px 0;
}
.thanx {
border: 1px solid #F0F0F0;
padding: 20px 20px 10px 20px;
font-size: 12px;
font-family: Arial;
background: #FBFFBA;
}
.footer {
margin: 40px 0 0 0;
}
.rep {
margin: 10px 0 20px 0;
font-size: 11px;
font-family: Arial;
}
.php_ok
{
color: #007F0E;
}
.php_bad
{
color: #A00000;
}
.notice
{
border: 1px solid cornflowerblue;
padding: 10px;
font-size: 12px;
font-family: Arial;
background: #E8F8F8;
}
.offer {
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
position: absolute;
width: 350px;
right: 100px;
top: 85px;
background: #E06060;
color: white;
font-size: 11px;
font-family: Arial;
padding: 20px 20px 10px 20px;
}
.offer2 {
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
position: absolute;
width: 350px;
right: 100px;
top: 100px;
background: #30A030;
color: white;
font-size: 11px;
font-family: Arial;
padding: 20px 20px 10px 20px;
}
.offer A, .offer2 A {
color: yellow;
}
.update {
color: red;
font-size: 12px;
font-family: Arial;
margin: 0 0 20px 0;
}
.tbg0 {
}
.tbg1 {
background: #F0F0F0;
}
.it {
font-size: 12px;
font-family: Arial;
}
.ctd {
font-size: 12px;
font-family: Arial;
color: #909090;
}
.flist {
margin: 10px 0 30px 0;
}
.tbgh {
background: #E0E0E0;
}
TH {
text-align: left;
font-size: 12px;
font-family: Arial;
color: #909090;
}
.details {
font-size: 9px;
font-family: Arial;
color: #303030;
}
.marker
{
color: #FF0000;
font-size: 16px;
font-weight: 700;
}
</style>
<script language="javascript">
function addToIgnore(par_Lnk, par_FN, par_CRC) {
var o = document.getElementById('igid');
var ta = document.forms.ignore.list;
ta.value = ta.value + par_FN + String.fromCharCode(09) + par_CRC + String.fromCharCode(10);
par_Lnk.innerHTML = 'Добавлено';
o.style.display = 'block';
}
</script>
</head>
<body>
<noindex>
MAIN_PAGE;
////////////////////////////////////////////////////////////////////////////
$l_Result .= sprintf(AI_STR_001, AI_VERSION, INFO_M);
$l_CreationTime = filemtime(__FILE__);
if (time() - $l_CreationTime > 86400 * 7) {
$l_Result .= AI_STR_002;
}
$l_Result .= '<div class="update" style="margin: 20px 0 20px 0; padding: 20px; width: 500px; border: 1px solid #400000"><b>' . AI_STR_003 . '</b></div>';
define('QCR_INDEX_FILENAME', 'fn');
define('QCR_INDEX_TYPE', 'type');
define('QCR_INDEX_WRITABLE', 'wr');
define('QCR_SVALUE_FILE', '1');
define('QCR_SVALUE_FOLDER', '0');
/**
* Extract emails from the string
* @param string $email
* @return array of strings with emails or false on error
*/
function getEmails($email)
{
$email = preg_split('#[,s;]#', $email, -1, PREG_SPLIT_NO_EMPTY);
$r = array();
for ($i = 0, $size = sizeof($email); $i < $size; $i++)
{
if (function_exists('filter_var')) {
if (filter_var($email[$i], FILTER_VALIDATE_EMAIL))
{
$r[] = $email[$i];
}
} else {
// for PHP4
if (strpos($email[$i], '@') !== false) {
$r[] = $email[$i];
}
}
}
return empty($r) ? false : $r;
}
/**
* Get bytes from shorthand byte values (1M, 1G...)
* @param int|string $val
* @return int
*/
function getBytes($val)
{
$val = trim($val);
$last = strtolower($val{strlen($val) - 1});
switch($last) {
case 't':
$val *= 1024;
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return intval($val);
}
/**
* Format bytes to human readable
* @param int $bites
* @return string
*/
function bytes2Human($bites)
{
if ($bites < 1024)
{
return $bites . ' b';
}
elseif (($kb = $bites / 1024) < 1024)
{
return number_format($kb, 2) . ' Kb';
}
elseif (($mb = $kb / 1024) < 1024)
{
return number_format($mb, 2) . ' Mb';
}
elseif (($gb = $mb / 1024) < 1024)
{
return number_format($gb, 2) . ' Gb';
}
else
{
return number_format($gb / 1024, 2) . 'Tb';
}
}
///////////////////////////////////////////////////////////////////////////
function needIgnore($par_FN, $par_CRC) {
global $g_IgnoreList;
for ($i = 0; $i < count($g_IgnoreList); $i++) {
if (strpos($par_FN, $g_IgnoreList[$i][0]) !== false) {
if ($par_CRC == $g_IgnoreList[$i][1]) {
return true;
}
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////
function printList($par_List, $par_Details = null, $par_NeedIgnore = false) {
global $g_Structure;
$l_Result = '';
$l_Result .= "<div class="flist"><table cellspacing=1 cellpadding=4 border=0>";
$l_Result .= "<tr class="tbgh" . ( $i % 2 ). "">";
$l_Result .= "<th>" . AI_STR_004 . "</th>";
$l_Result .= "<th>" . AI_STR_005 . "</th>";
$l_Result .= "<th>" . AI_STR_006 . "</th>";
$l_Result .= "<th width=90>" . AI_STR_007 . "</th>";
$l_Result .= "<th width=90>CRC32</th>";
$l_Result .= "</tr>";
for ($i = 0; $i < count($par_List); $i++) {
$l_Pos = $par_List[$i];
if ($par_NeedIgnore) {
if (needIgnore($g_Structure['n'][$par_List[$i]], $g_Structure['crc'][$l_Pos])) {
continue;
}
}
$l_Creat = $g_Structure['c'][$l_Pos] > 0 ? date("d/m/Y H:i:s", $g_Structure['c'][$l_Pos]) : '-';
$l_Modif = $g_Structure['m'][$l_Pos] > 0 ? date("d/m/Y H:i:s", $g_Structure['m'][$l_Pos]) : '-';
$l_Size = $g_Structure['s'][$l_Pos] > 0 ? bytes2Human($g_Structure['s'][$l_Pos]) : '-';
if ($par_Details != null) {
$l_WithMarket = preg_replace('|@AI_MARKER@|smi', '<span class="marker">|</span>', $par_Details[$i]);
$l_Body = '<div class="details">' . $l_WithMarket . '</div>';
} else {
$l_Body = '';
}
$l_Result .= '<tr class="tbg' . ( $i % 2 ). '">';
if (is_file($g_Structure['n'][$l_Pos])) {
$l_Result .= '<td><div class="it"><a class="it" target="_blank" href="'. $defaults['site_url'] . 'ai-bolit.php?fn=' .
$g_Structure['n'][$l_Pos] . '&ph=' . realCRC(PASS) . '&c=' . $g_Structure['crc'][$l_Pos] . '">' . $g_Structure['n'][$l_Pos] . '</a></div>' . $l_Body . '</td>';
} else {
$l_Result .= '<td><div class="it">' . $g_Structure['n'][$par_List[$i]] . '</div></td>';
}
$l_Result .= '<td><div class="ctd">' . $l_Creat . '</div></td>';
$l_Result .= '<td><div class="ctd">' . $l_Modif . '</div></td>';
$l_Result .= '<td><div class="ctd">' . $l_Size . '</div></td>';
$l_Result .= '<td><div class="ctd"><a href="#" onclick="addToIgnore(this, '' . $g_Structure['n'][$l_Pos] . '','' . $g_Structure['crc'][$l_Pos] . '');return false;">' . $g_Structure['crc'][$l_Pos] . '</a></div></td>';
$l_Result .= '</tr>';
}
$l_Result .= "</table></div>";
return $l_Result;
}
///////////////////////////////////////////////////////////////////////////
function extractValue(&$par_Str, $par_Name) {
if (preg_match('|<tr><td class="e">s*'.$par_Name.'s*</td><td class="v">(.+?)</td>|sm', $par_Str, $l_Result)) {
return str_replace('no value', '', strip_tags($l_Result[1]));
}
}
///////////////////////////////////////////////////////////////////////////
function QCR_ExtractInfo($par_Str) {
$l_PhpInfoSystem = extractValue($par_Str, 'System');
$l_PhpPHPAPI = extractValue($par_Str, 'Server API');
$l_AllowUrlFOpen = extractValue($par_Str, 'allow_url_fopen');
$l_AllowUrlInclude = extractValue($par_Str, 'allow_url_include');
$l_DisabledFunction = extractValue($par_Str, 'disable_functions');
$l_DisplayErrors = extractValue($par_Str, 'display_errors');
$l_ErrorReporting = extractValue($par_Str, 'error_reporting');
$l_ExposePHP = extractValue($par_Str, 'expose_php');
$l_LogErrors = extractValue($par_Str, 'log_errors');
$l_MQGPC = extractValue($par_Str, 'magic_quotes_gpc');
$l_MQRT = extractValue($par_Str, 'magic_quotes_runtime');
$l_OpenBaseDir = extractValue($par_Str, 'open_basedir');
$l_RegisterGlobals = extractValue($par_Str, 'register_globals');
$l_SafeMode = extractValue($par_Str, 'safe_mode');
$l_DisabledFunction = ($l_DisabledFunction == '' ? '-?-' : $l_DisabledFunction);
$l_OpenBaseDir = ($l_OpenBaseDir == '' ? '-?-' : $l_OpenBaseDir);
$l_Result = '<div class="sec">' . AI_STR_008 . ': ' . phpversion() . '</div>';
$l_Result .= 'System Version: <span class="php_ok">' . $l_PhpInfoSystem . '</span><br/>';
$l_Result .= 'PHP API: <span class="php_ok">' . $l_PhpPHPAPI. '</span><br/>';
$l_Result .= 'allow_url_fopen: <span class="php_' . ($l_AllowUrlFOpen == 'On' ? 'bad' : 'ok') . '">' . $l_AllowUrlFOpen. '</span><br/>';
$l_Result .= 'allow_url_include: <span class="php_' . ($l_AllowUrlInclude == 'On' ? 'bad' : 'ok') . '">' . $l_AllowUrlInclude. '</span><br/>';
$l_Result .= 'disable_functions: <span class="php_' . ($l_DisabledFunction == '-?-' ? 'bad' : 'ok') . '">' . $l_DisabledFunction. '</span><br/>';
$l_Result .= 'display_errors: <span class="php_' . ($l_DisplayErrors == 'On' ? 'ok' : 'bad') . '">' . $l_DisplayErrors. '</span><br/>';
$l_Result .= 'error_reporting: <span class="php_ok">' . $l_ErrorReporting. '</span><br/>';
$l_Result .= 'expose_php: <span class="php_' . ($l_ExposePHP == 'On' ? 'bad' : 'ok') . '">' . $l_ExposePHP. '</span><br/>';
$l_Result .= 'log_errors: <span class="php_' . ($l_LogErrors == 'On' ? 'ok' : 'bad') . '">' . $l_LogErrors . '</span><br/>';
$l_Result .= 'magic_quotes_gpc: <span class="php_' . ($l_MQGPC == 'On' ? 'ok' : 'bad') . '">' . $l_MQGPC. '</span><br/>';
$l_Result .= 'magic_quotes_runtime: <span class="php_' . ($l_MQRT == 'On' ? 'bad' : 'ok') . '">' . $l_MQRT. '</span><br/>';
$l_Result .= 'register_globals: <span class="php_' . ($l_RegisterGlobals == 'On' ? 'bad' : 'ok') . '">' . $l_RegisterGlobals . '</span><br/>';
$l_Result .= 'open_basedir: <span class="php_' . ($l_OpenBaseDir == '-?-' ? 'bad' : 'ok') . '">' . $l_OpenBaseDir . '</span><br/>';
if (phpversion() < '5.3.0') {
$l_Result .= 'safe_mode (PHP < 5.3.0): <span class="php_' . ($l_SafeMode == 'On' ? 'ok' : 'bad') . '">' . $l_SafeMode. '</span><br/>';
}
return $l_Result . '<p>';
}
///////////////////////////////////////////////////////////////////////////
function QCR_Debug($par_Str) {
if (!DEBUG_MODE) {
return;
}
$l_MemInfo = ' ';
if (function_exists('memory_get_usage')) {
$l_MemInfo .= ' curmem=' . bytes2Human(memory_get_usage());
}
if (function_exists('memory_get_peak_usage')) {
$l_MemInfo .= ' maxmem=' . bytes2Human(memory_get_peak_usage());
}
stdOut(date('H:i:s') . ': ' . $par_Str . $l_MemInfo);
}
///////////////////////////////////////////////////////////////////////////
function QCR_ScanDirectories($l_RootDir)
{
global $g_Structure, $g_Counter, $g_Doorway, $g_FoundTotalFiles, $g_FoundTotalDirs,
$defaults, $g_SkippedFolders, $g_UrlIgnoreList, $g_DirIgnoreList, $g_UnsafeFilesArray, $g_UnsafeDirArray,
$g_UnsafeFilesFound, $g_SymLinks, $g_HiddenFiles;
$l_DirCounter = 0;
$l_DoorwayFilesCounter = 0;
$l_SourceDirIndex = $g_Counter - 1;
QCR_Debug('Scan ' . $l_RootDir);
$l_QuotedSeparator = quotemeta(DIR_SEPARATOR);
$l_NeedCheckCandi = ($defaults['report_mask'] & REPORT_MASK_CANDI) == REPORT_MASK_CANDI;
if ($l_DIRH = @opendir($l_RootDir))
{
while (($l_FileName = readdir($l_DIRH)) !== false)
{
if ($l_FileName == '.' || $l_FileName == '..') continue;
if (is_link($l_FileName))
{
$g_SymLinks[] = $l_FileName;
continue;
}
$l_FileName = $l_RootDir . DIR_SEPARATOR . $l_FileName;
$l_Ext = substr($l_FileName, strrpos($l_FileName, '.') + 1);
$l_IsDir = is_dir($l_FileName);
// which files should be scanned
$l_NeedToScan = SCAN_ALL_FILES || (in_array($l_Ext, array(
'js', 'php', 'php3', 'phtml', 'shtml', 'khtml',
'php4', 'php5', 'tpl', 'inc', 'htaccess', 'html', 'htm'
)));
if (strpos(basename($l_FileName), '.') === 0) {
$g_HiddenFiles[] = $l_FileName;
}
if ($l_IsDir)
{
// if folder in ignore list
$l_Skip = false;
for ($dr = 0; $dr < count($g_DirIgnoreList); $dr++) {
if (($g_DirIgnoreList[$dr] != '') &&
preg_match('#' . $g_DirIgnoreList[$dr] . '#', $l_FileName, $l_Found)) {
$l_Skip = true;
}
}
// skip on ignore
if ($l_Skip) {
$g_SkippedFolders[] = $l_FileName;
continue;
}
$g_Structure['d'][$g_Counter] = $l_IsDir;
$g_Structure['n'][$g_Counter] = $l_FileName;
$l_DirCounter++;
if ($l_NeedCheckCandi) {
for ($j = 0; $j < count($g_UnsafeDirArray); $j++) {
if (preg_match('|' . $l_QuotedSeparator . $g_UnsafeDirArray[$j] . '$|i', $l_FileName, $l_Found)) {
$g_UnsafeFilesFound[] = $g_Counter;
break;
}
}
}
if ($l_DirCounter > MAX_ALLOWED_PHP_HTML_IN_DIR)
{
$g_Doorway[] = $l_SourceDirIndex;
$l_DirCounter = -655360;
}
$g_Counter++;
$g_FoundTotalDirs++;
QCR_ScanDirectories($l_FileName);
} else
{
if ($l_NeedToScan)
{
$g_FoundTotalFiles++;
if (in_array($l_Ext, array(
'php', 'php3',
'php4', 'php5', 'html', 'htm', 'phtml', 'shtml', 'khtml'
))
)
{
$l_DoorwayFilesCounter++;
if ($l_DoorwayFilesCounter > MAX_ALLOWED_PHP_HTML_IN_DIR)
{
$g_Doorway[] = $l_SourceDirIndex;
$l_DoorwayFilesCounter = -655360;
}
}
$l_Stat = stat($l_FileName);
$g_Structure['d'][$g_Counter] = $l_IsDir;
$g_Structure['n'][$g_Counter] = $l_FileName;
$g_Structure['s'][$g_Counter] = $l_Stat['size'];
$g_Structure['c'][$g_Counter] = $l_Stat['ctime'];
$g_Structure['m'][$g_Counter] = $l_Stat['mtime'];
if ($l_NeedCheckCandi) {
for ($j = 0; $j < count($g_UnsafeFilesArray); $j++) {
if (preg_match('|' . $l_QuotedSeparator . $g_UnsafeFilesArray[$j] . '|i', $l_FileName, $l_Found)) {
$g_UnsafeFilesFound[] = $g_Counter;
break;
}
}
}
$g_Counter++;
}
}
}
closedir($l_DIRH);
}
return $g_Structure;
}
///////////////////////////////////////////////////////////////////////////
function getFragment($par_Content, $par_Pos) {
$l_MaxChars = MAX_PREVIEW_LEN;
$l_MaxLen = strlen($par_Content);
$l_RightPos = min($par_Pos + $l_MaxChars, $l_MaxLen);
$l_MinPos = max(0, $par_Pos - $l_MaxChars);
$l_Res = substr($par_Content, $l_MinPos, $par_Pos - $l_MinPos) .
'@AI_MARKER@' .
substr($par_Content, $par_Pos, $l_RightPos - $par_Pos - 1);
return htmlspecialchars($l_Res);
}
///////////////////////////////////////////////////////////////////////////
function escapedHexToHex($escaped)
{ $GLOBALS['g_EncObfu']++; return chr(hexdec($escaped[1])); }
function escapedOctDec($escaped)
{ $GLOBALS['g_EncObfu']++; return chr(octdec($escaped[1])); }
function escapedDec($escaped)
{ $GLOBALS['g_EncObfu']++; return chr($escaped[1]); }
function UnwrapObfu($par_Content) {
$GLOBALS['g_EncObfu'] = 0;
$par_Content = preg_replace_callback('/\\x([a-fA-F0-9]{2})/i','escapedHexToHex', $par_Content);
$par_Content = preg_replace_callback('/\\([0-9]{3})/i','escapedOctDec', $par_Content);
$par_Content = preg_replace_callback('/\\d([0-9]{1,3})/i','escapedDec', $par_Content);
return $par_Content;
}
///////////////////////////////////////////////////////////////////////////
function QCR_SearchPHP($src)
{
if (preg_match("/(<?php[ws]{5,})/smi", $src, $l_Found, PREG_OFFSET_CAPTURE)) {
return $l_Found[0][1];
}
if (preg_match("/(<%[ws]{10,})/smi", $src, $l_Found, PREG_OFFSET_CAPTURE)) {
return $l_Found[0][1];
}
if (preg_match("/(<script[^>]*languages*=s*)('|"|)php('|"|)([^>]*>)/i", $src, $l_Found, PREG_OFFSET_CAPTURE)) {
return $l_Found[0][1];
}
return false;
}
///////////////////////////////////////////////////////////////////////////
function knowUrl($par_URL) {
global $g_UrlIgnoreList;
for ($jk = 0; $jk < count($g_UrlIgnoreList); $jk++) {
if ((stripos($par_URL, $g_UrlIgnoreList[$jk]) !== false)) {
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////
function QCR_GoScan($par_Offset)
{
global $g_IframerFragment, $g_Iframer, $g_SuspDir, $g_Redirect, $g_Doorway, $g_EmptyLink, $g_Structure, $g_Counter,
$g_WritableDirectories, $g_CriticalPHP, $g_HeuristicDetected, $g_TotalFolder, $g_TotalFiles, $g_WarningPHP, $g_AdwareList,
$g_CriticalPHP, $g_CriticalJS, $g_UrlIgnoreList, $g_CriticalJSFragment, $g_PHPCodeInside, $g_PHPCodeInsideFragment,
$g_NotRead, $g_WarningPHPFragment, $g_BigFiles, $g_RedirectPHPFragment, $g_EmptyLinkSrc, $g_CriticalPHPFragment,
$g_Base64Fragment, $g_UnixExec, $g_IframerFragment, $g_CMS, $defaults, $g_AdwareListFragment, $g_KnownList;
static $_files_and_ignored = 0;
QCR_Debug('QCR_GoScan ' . $par_Offset);
for ($i = $par_Offset; $i < $g_Counter; $i++)
{
$l_Filename = $g_Structure['n'][$i];
QCR_Debug('Check ' . $l_Filename);
if ($g_Structure['d'][$i])
{
// FOLDER
$g_TotalFolder++;
if (is_writable($l_Filename))
{
$g_WritableDirectories[] = $i;
}
}
else
{
// FILE
if (MAX_SIZE_TO_SCAN > 0 AND $g_Structure['s'][$i] > MAX_SIZE_TO_SCAN)
{
$g_BigFiles[] = $i;
}
else
{
$g_TotalFiles++;
$l_Content = @implode('', file($l_Filename));
if (($l_Content == '') && ($g_Structure['s'][$i] > 0)) {
$g_NotRead[] = $i;
}
$g_Structure['crc'][$i] = realCRC($l_Content);
// detect version CMS
if (strpos($l_Filename, DIR_SEPARATOR . 'engine' . DIR_SEPARATOR . 'data' . DIR_SEPARATOR . 'config.php') !== false) {
if (preg_match('|'version_id's*=>s*"(.+?)"|smi', $l_Content, $l_Ver)) {
$g_CMS[] = 'DLE v' . $l_Ver[1];
}
} else
if (strpos($l_Filename, DIR_SEPARATOR . 'wp-includes' . DIR_SEPARATOR . 'version.php') !== false) {
if (preg_match('|$wp_versions*=s*'(.+?)'|smi', $l_Content, $l_Ver)) {
$g_CMS[] = 'Wordpress v' . $l_Ver[1];
}
} else
if (strpos($l_Filename, 'install' . DIR_SEPARATOR . 'consts.php') !== false) {
if (preg_match('|STRING_VERSION',s*'(.+?)'|smi', $l_Content, $l_Ver)) {
$g_CMS[] = 'ShopScript Premium v' . $l_Ver[1];
}
} else
if (strpos($l_Filename, 'bitrix' . DIR_SEPARATOR . 'modules' . DIR_SEPARATOR . 'main' . DIR_SEPARATOR . 'classes' . DIR_SEPARATOR . 'general' . DIR_SEPARATOR . 'version.php') !== false) {
if (preg_match('|define("SM_VERSION","(.+?)")|smi', $l_Content, $l_Ver)) {
$g_CMS[] = 'Bitrix v' . $l_Ver[1];
}
}
$l_KnownCRC = $g_Structure['crc'][$i] + realCRC(basename($l_Filename));
if (in_array($l_KnownCRC, $g_KnownList)) {
printProgress(++$_files_and_ignored, $l_Filename);
continue;
}
$l_Unwrapped = UnwrapObfu($l_Content);
// ignore itself
if (strpos($l_Content, 'LJ2345234786783ddghdJHJKLKJFGF') !== false) {
continue;
}
// warnings
$l_Pos = '';
if (WarningPHP($l_Filename, $l_Unwrapped, $l_Pos))
{ $l_Prio = 1;
if (strpos($l_Filename, '.php') !== false) {
$l_Prio = 0;
}
$g_WarningPHP[$l_Prio][] = $i;
$g_WarningPHPFragment[$l_Prio][] = getFragment($l_Content, $l_Pos);
}
// adware
if (Adware($l_Filename, $l_Unwrapped, $l_Pos))
{
$g_AdwareList[] = $i;
$g_AdwareListFragment[] = getFragment($l_Content, $l_Pos);
}
// critical
if (CriticalPHP($l_Filename, $i, $l_Unwrapped, $l_Pos))
{
$g_CriticalPHP[] = $i;
$g_CriticalPHPFragment[] = getFragment($l_Content, $l_Pos);
}
if (ai_check_extra_obfus($l_Content)) {
$g_HeuristicDetected[] = $i;
}
// critical JS
$l_Pos = CriticalJS($l_Filename, $i, $l_Content);
if ($l_Pos !== false)
{
$g_CriticalJS[] = $i;
$g_CriticalJSFragment[] = getFragment($l_Content, $l_Pos);
}
if
(stripos($l_Filename, 'index.php') ||
stripos($l_Filename, 'index.htm') ||
SCAN_ALL_FILES
)
{
// check iframes
if (preg_match_all('|<iframe.+?src.+?>|smi', $l_Unwrapped, $l_Found, PREG_SET_ORDER))
{
for ($kk = 0; $kk < count($l_Found); $kk++) {
$l_Pos = stripos($l_Found[$kk][0], 'http://');
if (($l_Pos !== false) && (!knowUrl($l_Found[$kk][0]))) {
$g_Iframer[] = $i;
$g_IframerFragment[] = getFragment($l_Found[$kk][0], $l_Pos);
}
}
}
// check empty links
if (preg_match_all('|<a[^>]+href([^>]+?)>(.*?)</a>|smi', $l_Unwrapped, $l_Found, PREG_SET_ORDER))
{
for ($kk = 0; $kk < count($l_Found); $kk++) {
if ((stripos($l_Found[$kk][1], 'http://') !== false) &&
(trim(strip_tags($l_Found[$kk][2])) == '')) {
$l_NeedToAdd = true;
if ((stripos($l_Found[$kk][1], $default['site_url']) !== false)
|| knowUrl($l_Found[$kk][1])) {
$l_NeedToAdd = false;
}
if ($l_NeedToAdd && (count($g_EmptyLink) < MAX_EXT_LINKS)) {
$g_EmptyLink[] = $i;
$g_EmptyLinkSrc[$i][] = substr($l_Found[$kk][0], 0, MAX_PREVIEW_LEN);
}
}
}
}
}
// check for PHP code inside any type of file
if ((stripos($l_Filename, '.php') === false) &&
(stripos($l_Filename, '.phtml') === false))
{
$l_Pos = QCR_SearchPHP($l_Content);
if ($l_Pos !== false)
{
$g_PHPCodeInside[] = $i;
$g_PHPCodeInsideFragment[] = getFragment($l_Unwrapped, $l_Pos);
}
}
// articles
if (stripos($l_Filename, 'article_index'))
{
$g_AdwareSig[] = $i;
}
// unix executables
if (strpos($l_Content, chr(127) . 'ELF') !== false)
{
$g_UnixExec[] = $i;
}
// htaccess
if (stripos($l_Filename, '.htaccess'))
{
if (stripos($l_Content, 'index.php?name=$1') !== false ||
stripos($l_Content, 'index.php?m=1') !== false
)
{
$g_SuspDir[] = $i;
}
$l_Pos = stripos($l_Content, '^(%2d|-)[^=]+$');
if ($l_Pos !== false)
{
$g_Redirect[] = $i;
$g_RedirectPHPFragment[] = getFragment($l_Content, $l_Pos);
}
$l_Pos = stripos($l_Content, '%{HTTP_USER_AGENT}');
if ($l_Pos !== false)
{
$g_Redirect[] = $i;
$g_RedirectPHPFragment[] = getFragment($l_Content, $l_Pos);
}
if (
preg_match_all('|(RewriteConds+%{HTTP_HOST}/%1 !^[w.]*([^/]+)/\1$s+[NC])|smi', $l_Content, $l_Found, PREG_OFFSET_CAPTURE)
)
{
$g_Redirect[] = $i;
$g_RedirectPHPFragment[] = getFragment($l_Content, $l_Found[0][1]);
}
//
$l_HTAContent = preg_replace('|^s*#.+$|m', '', $l_Content);
if (
preg_match_all("|RewriteRules+.+?s+http://(.+?)/.+s+[.*R=d+.*]|smi", $l_HTAContent, $l_Found, PREG_SET_ORDER)
)
{
$l_Host = str_replace('www.', '', $_SERVER['HTTP_HOST']);
for ($j = 0; $j < sizeof($l_Found); $j++)
{
$l_Found[$j][1] = str_replace('www.', '', $l_Found[$j][1]);
if ($l_Found[$j][1] != $l_Host)
{
$g_Redirect[] = $i;
break;
}
}
}
unset($l_HTAContent);
$l_Pos = stripos($l_Content, 'auto_prepend_file');
if ($l_Pos !== false) {
$g_Redirect[] = $i;
$g_RedirectPHPFragment[] = getFragment($l_Content, $l_Pos);
}
$l_Pos = stripos($l_Content, 'auto_append_file');
if ($l_Pos !== false) {
$g_Redirect[] = $i;
$g_RedirectPHPFragment[] = getFragment($l_Content, $l_Pos);
}
if (preg_match("|RewriteRules+^(.*)$s+-s+[s*Fs*,s*Ls*]|smi", $l_Content, $l_Found)) {
$g_Redirect[] = $i;
}
}
}
unset($l_Unwrapped);
unset($l_Content);
printProgress(++$_files_and_ignored, $l_Filename);
} // end of if (file)
usleep(SCAN_DELAY * 1000);
} // end of for
}
///////////////////////////////////////////////////////////////////////////
function WarningPHP($l_FN, $l_Content, &$l_Pos)
{
global $g_SusDB;
$l_Res = false;
foreach ($g_SusDB as $l_Item) {
if (preg_match('#(' . $l_Item . ')#smi', $l_Content, $l_Found, PREG_OFFSET_CAPTURE)) {
if (!CheckException($l_Content, $l_Found)) {
$l_Pos = $l_Found[0][1];
//print "nSusDB $l_FN =" . $l_Item." l_Pos=" . $l_Pos . "n";
return true;
}
}
}
return $l_Res;
}
///////////////////////////////////////////////////////////////////////////
function Adware($l_FN, $l_Content, &$l_Pos)
{
global $g_AdwareSig;
$l_Res = false;
foreach ($g_AdwareSig as $l_Item) {
if (preg_match('#(' . $l_Item . ')#smi', $l_Content, $l_Found, PREG_OFFSET_CAPTURE)) {
if (!CheckException($l_Content, $l_Found)) {
$l_Pos = $l_Found[0][1];
//print "ng_AdwareSig $l_FN =" . $l_Item." l_Pos=" . $l_Pos . "n";
return true;
}
}
}
return $l_Res;
}
///////////////////////////////////////////////////////////////////////////
function CheckException(&$l_Content, &$l_Found) {
global $g_ExceptFlex, $g_FlexDBShe, $g_DBShe, $g_Base64, $g_Base64Fragment;
$l_FoundStrPlus = substr($l_Content, max($l_Found[0][1] - 10, 0), 70);
//print "Matched in " . $l_FN. "nn";
//print "==========> " . $l_Found[0][0]. "rn";
foreach ($g_ExceptFlex as $l_ExceptItem) {
//print "rn" . $l_FoundStrPlus . " vs " . $l_ExceptItem."rn";
if (preg_match('#(' . $l_ExceptItem . ')#smi', $l_FoundStrPlus, $l_Detected)) {
$l_Exception = true;
//print "rn" . "****** EXCEPTION *************" . "rn";
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////
function CriticalJS($l_FN, $l_Index, $l_Content)
{
global $g_JSVirSig;
$l_Res = false;
foreach ($g_JSVirSig as $l_Item) {
if (preg_match('#(' . $l_Item . ')#smi', $l_Content, $l_Found, PREG_OFFSET_CAPTURE)) {
if (!CheckException($l_Content, $l_Found)) {
$l_Pos = $l_Found[0][1];
//print "CriticalJS " . $l_FN . ' ' . $l_Item . ' l_Pos=' . $l_Pos . "n";
return $l_Pos;
}
}
}
return $l_Res;
}
///////////////////////////////////////////////////////////////////////////
function ai_check_extra_obfus($content) {
$res = false;
// 1
if (preg_match_all('|($[a-zA-Z0-9_]{3,}[[d+]]s*(s*$)|smiu', $content, $found, PREG_SET_ORDER)) {
$ref_calls = count($found);
}
// 2
if (preg_match_all('|$([a-zA-Z0-9_]{3,}?)s*[;=(]|smi', $content, $found, PREG_SET_ORDER)) {
$obf_var1 = 0;
$obf_var2 = 0;
$arr = array();
foreach ($found as $item) {
$arr[$item[1]] = 1;
}
$found = array_keys($arr);
foreach ($found as $item) {
if (preg_match('|([a-zA-Z]{2,}[0-9]+[a-zA-Z]+){1,}|', $item, $found_ob)) {
$obf_var1++;
}
if (!preg_match('|([aeiouy_])|i', $item, $found_ob) && (strlen($item) > 4)) {
$obf_var2++;
}
if (preg_match('|([0-9bcdfghjklmnpqrstvwxz]{6,})|i', $item, $found_ob) && (strlen($item) > 3)) {
$obf_var3++;
}
}
}
// 3
if (preg_match_all('|($GLOBALS['[a-z_0-9]+'][d+]()|smiu', $content, $found, PREG_SET_ORDER)) {
$ref_glob = count($found);
}
return ($ref_calls > 10)
||
($ref_glob > 10)
||
($obf_var1 + $obf_var2 + $obf_var3 >= 3);
}
///////////////////////////////////////////////////////////////////////////
function CriticalPHP($l_FN, $l_Index, $l_Content, &$l_Pos)
{
global $g_ExceptFlex, $g_FlexDBShe, $g_DBShe, $g_Base64, $g_Base64Fragment;
// LJ2345234786783ddghdJHJKLKJFGF
#var_dump($g_ExceptFlex);
foreach ($g_FlexDBShe as $l_Item) {
if (preg_match('#(' . $l_Item . ')#smi', $l_Content, $l_Found, PREG_OFFSET_CAPTURE)) {
//print "rnSIGNATURE: " . $l_Item . ''."nn";
//print "rnIN:" . $l_Found[0][0]. ']'."nn";
if (!CheckException($l_Content, $l_Found)) {
//print "rn****** VIR *************rn";
$l_Pos = $l_Found[0][1];
return true;
}
}
}
foreach ($g_DBShe as $l_Item) {
$l_Pos = stripos($l_Content, $l_Item);
if ($l_Pos !== false) {
return true;
}
}
if ((strpos($l_Content, 'GIF89') === 0) && (strpos($l_FN, '.php') !== false )) {
$l_Pos = 0;
return true;
}
if (preg_match('#((include|require|require_once|include_once)s*(*s*["']http://.+?["'])#smi', $l_Content, $l_Found)) {
$g_Base64[] = $l_Index;
$g_Base64Fragment[] = substr($l_Found[1], 0, MAX_PREVIEW_LEN);
}
// detect base64 suspicious
if (preg_match('|([A-Za-z0-9+/]{' . BASE64_LENGTH . ',})|smi', $l_Content, $l_Found, PREG_OFFSET_CAPTURE)) {
if (preg_match('#(eval|sort|array_map|create_function|base64_decode|gzip_decode|gzip_inflate|preg_replace_callback)s*(#smi',
$l_Content, $l_Found, PREG_OFFSET_CAPTURE)) {
if ((!CheckException($l_Content, $l_Found)) && (!in_array($l_Index, $g_Base64))) {
$g_Base64[] = $l_Index;
$g_Base64Fragment[] = getFragment($l_Content, $l_Found[1][1]);
}
}
}
if (preg_match('|evals*(.+?(.+?(s*implode|smi', $l_Content, $l_Found)) {
$g_Base64[] = $l_Index;
$g_Base64Fragment[] = getFragment($l_Content, $l_Pos);
}
// count number of base64_decode entries
$l_Count = substr_count($l_Content, 'base64_decode');
if ($l_Count > 10) {
$g_Base64[] = $l_Index;
$g_Base64Fragment[] = getFragment($l_Content, stripos($l_Content, 'base64_decode'));
}
return false;
}
///////////////////////////////////////////////////////////////////////////
if (!isCli()) {
header('Content-type: text/html; charset=utf-8');
}
if (!isCli()) {
$l_PassOK = false;
if (strlen(PASS) > 8) {
$l_PassOK = true;
}
if ($l_PassOK && preg_match('|[0-9]|', PASS, $l_Found) && preg_match('|[A-Z]|', PASS, $l_Found) && preg_match('|[a-z]|', PASS, $l_Found) ) {
$l_PassOK = true;
}
if (!$l_PassOK) {
print sprintf(AI_STR_009, generatePassword());
exit;
}
if (isset($_GET['fn']) && ($_GET['ph'] == crc32(PASS))) {
printFile();
exit;
}
if ($_GET['p'] != PASS) {
print sprintf(AI_STR_010, generatePassword());
exit;
}
}
if (!is_readable(ROOT_PATH)) {
print AI_STR_011;
exit;
}
if (isCli()) {
if (defined('REPORT_PATH') AND REPORT_PATH)
{
if (!is_writable(REPORT_PATH))
{
die("nCannot write report. Report dir " . REPORT_PATH . " is not writable.");
}
else if (!REPORT_FILE)
{
die("nCannot write report. Report filename is empty.");
}
else if (($file = REPORT_PATH . DIR_SEPARATOR . REPORT_FILE) AND is_file($file) AND !is_writable($file))
{
die("nCannot write report. Report file '$file' exists but is not writable.");
}
}
}
$g_IgnoreList = array();
$g_DirIgnoreList = array();
$g_UrlIgnoreList = array();
$g_KnownList = array();
$l_IgnoreFilename = '.aignore';
$l_DirIgnoreFilename = '.adirignore';
$l_UrlIgnoreFilename = '.aurlignore';
$l_KnownFilename = '.aknown';
if (file_exists($l_IgnoreFilename)) {
$l_IgnoreListRaw = file($l_IgnoreFilename);
for ($i = 0; $i < count($l_IgnoreListRaw); $i++)
{
$g_IgnoreList[] = explode("t", trim($l_IgnoreListRaw[$i]));
}
unset($l_IgnoreListRaw);
}
if (file_exists($l_DirIgnoreFilename)) {
$g_DirIgnoreList = file($l_DirIgnoreFilename);
for ($i = 0; $i < count($g_DirIgnoreList); $i++) {
$g_DirIgnoreList[$i] = trim($g_DirIgnoreList[$i]);
}
}
if (file_exists($l_UrlIgnoreFilename)) {
$g_UrlIgnoreList = file($l_UrlIgnoreFilename);
for ($i = 0; $i < count($g_UrlIgnoreList); $i++) {
$g_UrlIgnoreList[$i] = trim($g_UrlIgnoreList[$i]);
}
}
if ($l_DIRH = @opendir('.'))
{
while (($l_FileName = readdir($l_DIRH)) !== false)
{
if ($l_FileName == '.' || $l_FileName == '..') continue;
if (strpos($l_FileName, $l_KnownFilename) !== false) {
$g_KnownListTmp = file($l_FileName);
for ($i = 0; $i < count($g_KnownListTmp); $i++) {
$g_KnownListTmp[$i] = trim($g_KnownListTmp[$i]);
}
$g_KnownList = array_merge($g_KnownListTmp, $g_KnownList);
}
}
}
closedir($l_DIRH);
stdOut("Loaded " . count($g_KnownList) . ' known files');
stdOut("Start scanning '" . ROOT_PATH . "'.");
QCR_Debug();
QCR_ScanDirectories(ROOT_PATH);
$g_FoundTotalFiles = count($g_Structure['n']);
QCR_Debug();
stdOut("Founded $g_FoundTotalFiles files in $g_FoundTotalDirs directories.");
stdOut(str_repeat(' ', 160),false);
$g_FoundTotalFiles = count($g_Structure['n']);
QCR_GoScan(0);
QCR_Debug();
////////////////////////////////////////////////////////////////////////////
$l_Result .= "<div class="sec"><b>" . AI_STR_051 . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : realpath('.')) . "</b></div>";
$time_tacked = seconds2Human(microtime(true) - START_TIME);
$l_Result .= sprintf(AI_STR_012, count($g_DBShe) + count($g_FlexDBShe), (count($g_SusDB) + count($g_AdwareSig ) + count($g_JSVirSig)), $time_tacked, date('d-m-Y в H:i:s', floor(START_TIME)) , date('d-m-Y в H:i:s'));
$l_Result .= sprintf(AI_STR_013, $g_TotalFolder, $g_TotalFiles);
if (!$defaults['scan_all_files']) {
$l_Result .= AI_STR_014;
}
$l_Result .= AI_STR_015;
$l_ShowOffer = false;
stdOut("nBuilding reportn");
stdOut("Building list of shells " . count($g_CriticalPHP));
if (count($g_CriticalPHP) > 0) {
$l_Result .= '<div class="vir"><b>' . AI_STR_016 . '</b>';
$l_Result .= printList($g_CriticalPHP, $g_CriticalPHPFragment, true);
$l_Result .= '</div>';
$l_ShowOffer = true;
} else {
$l_Result .= '<div class="ok"><b>' . AI_STR_017. '</b></div>';
}
stdOut("Building list of js " . count($g_CriticalJS));
if (count($g_CriticalJS) > 0) {
$l_Result .= '<div class="vir"><b>' . AI_STR_018 . '</b>';
$l_Result .= printList($g_CriticalJS, $g_CriticalJSFragment, true);
$l_Result .= "</div>";
$l_ShowOffer = true;
}
stdOut("Building list of unix executables " . count($g_UnixExec));
if (count($g_UnixExec) > 0) {
$l_Result .= "<div class="vir"><b>". AI_STR_019 ."</b>";
$l_Result .= printList($g_UnixExec, '', true);
$l_Result .= "</div>";
$l_ShowOffer = true;
}
stdOut("Building list of base64s " . count($g_Base64));
if (count($g_Base64) > 0) {
$l_ShowOffer = true;
$l_Result .= "<div class="vir"><b>" . AI_STR_020 ."</b>";
$l_Result .= printList($g_Base64, $g_Base64Fragment, true);
$l_Result .= "</div>";
}
stdOut("Building list of iframes " . count($g_Iframer));
if (count($g_Iframer) > 0) {
$l_ShowOffer = true;
$l_Result .= "<div class="vir"><b>" . AI_STR_021 . "</b>";
$l_Result .= printList($g_Iframer, $g_IframerFragment, true);
$l_Result .= "</div>";
}
stdOut("Building list of heuristics " . count($g_HeuristicDetected));
if (count($g_HeuristicDetected) > 0) {
$l_Result .= '<div class="warn"><b>' . AI_STR_052 . '</b>';
$l_Result .= printList($g_HeuristicDetected, '', true);
$l_Result .= '</div>';
$l_ShowOffer = true;
}
stdOut("Building list of symlinks " . count($g_SymLinks));
if (count($g_SymLinks) > 0) {
$l_Result .= "<div class="warn"><b>" . AI_STR_022 . "</b><br>";
$l_Result .= implode("<br>", $g_SymLinks);
$l_Result .= "</div>";
}
stdOut("Building list of hidden files " . count($g_HiddenFiles));
if (count($g_HiddenFiles) > 0) {
$l_Result .= "<div class="warn"><b>" . AI_STR_023 . "</b><br>";
$l_Result .= implode("<br>", $g_HiddenFiles);
$l_Result .= "</div>";
}
stdOut("Building list of susp dirs " . count($g_SuspDir));
if (count($g_SuspDir) > 0) {
$l_Result .= "<div class="vir"><b>" . AI_STR_024 . "</b><br>";
$l_Result .= printList($g_SuspDir);
$l_Result .= "</div>";
} else {
$l_Result .= '<div class="ok"><b>' . AI_STR_025 . '</b></div>';
}
stdOut("Building list of redirects " . count($g_Redirect));
$l_Result .= "<div class="sec">" . AI_STR_026 . "</div>";
if (count($g_Redirect) > 0) {
$l_ShowOffer = true;
$l_Result .= "<div class="warn"><b>" . AI_STR_027 . "</b>";
$l_Result .= printList($g_Redirect, $g_RedirectPHPFragment, true);
$l_Result .= "</div>";
}
stdOut("Building list of php inj " . count($g_PHPCodeInside));
if ((count($g_PHPCodeInside) > 0) && (($defaults['report_mask'] & REPORT_MASK_PHPSIGN) == REPORT_MASK_PHPSIGN)) {
$l_ShowOffer = true;
$l_Result .= "<div class="warn"><b>" . AI_STR_028 . "</b>";
$l_Result .= printList($g_PHPCodeInside, $g_PHPCodeInsideFragment, true);
$l_Result .= "</div>";
}
stdOut("Building list of adware " . count($g_AdwareList));
if (count($g_AdwareList) > 0) {
$l_ShowOffer = true;
$l_Result .= "<div class="warn"><b>" . AI_STR_029 . "</b>";
$l_Result .= printList($g_AdwareList, $g_AdwareListFragment, true);
$l_Result .= "</div>";
}
stdOut("Building list of unread files " . count($g_NotRead));
if (count($g_NotRead) > 0) {
$l_ShowOffer = true;
$l_Result .= "<div class="warn"><b>" . AI_STR_030 . ":</b>";
$l_Result .= printList($g_NotRead);
$l_Result .= "</div>";
}
stdOut("Building list of empty links " . count($g_EmptyLink));
if ((count($g_EmptyLink) > 0) && (($defaults['report_mask'] & REPORT_MASK_SPAMLINKS) == REPORT_MASK_SPAMLINKS)) {
$l_ShowOffer = true;
$l_Result .= "<div class="warn"><b>" . AI_STR_031 . "</b>";
$l_Result .= printList($g_EmptyLink, '', true);
$l_Result .= AI_STR_032 . '<br/>';
if (count($g_EmptyLink) == MAX_EXT_LINKS) {
$l_Result .= '(' . AI_STR_033 . MAX_EXT_LINKS . ')<br/>';
}
for ($i = 0; $i < count($g_EmptyLink); $i++) {
$l_Idx = $g_EmptyLink[$i];
for ($j = 0; $j < count($g_EmptyLinkSrc[$l_Idx]); $j++) {
$l_Result .= '<span class="details">' . $g_Structure['n'][$g_EmptyLink[$i]] . ' → ' . htmlspecialchars($g_EmptyLinkSrc[$l_Idx][$j]) . '</span><br/>';
}
}
$l_Result .= "</div>";
}
stdOut("Building list of doorways " . count($g_Doorway));
if ((count($g_Doorway) > 0) && (($defaults['report_mask'] & REPORT_MASK_DOORWAYS) == REPORT_MASK_DOORWAYS)) {
$l_ShowOffer = true;
$l_Result .= "<div class="warn"><b>" . AI_STR_034 . "</b>";
$l_Result .= printList($g_Doorway);
$l_Result .= "</div>";
}
stdOut("Building list of php warnings " . (count($g_WarningPHP[0]) + count($g_WarningPHP[1])));
if (($defaults['report_mask'] & REPORT_MASK_SUSP) == REPORT_MASK_SUSP) {
if ((count($g_WarningPHP[0]) + count($g_WarningPHP[1])) > 0) {
$l_ShowOffer = true;
$l_Result .= "<div class="warn"><b>" . AI_STR_035 . "</b>";
for ($i = 0; $i < count($g_WarningPHP); $i++) {
if (count($g_WarningPHP[$i]) > 0) $l_Result .= printList($g_WarningPHP[$i], $g_WarningPHPFragment[$i], true);
}
$l_Result .= "</div>";
}
}
stdOut("Building list of skipped dirs " . count($g_SkippedFolders));
if (count($g_SkippedFolders) > 0) {
$l_Result .= "<div class="warn2"><b>" . AI_STR_036 . "</b><br/>";
$l_Result .= implode("<br>", $g_SkippedFolders);
$l_Result .= "</div>";
}
stdOut("Building list of writeable dirs " . count($g_WritableDirectories));
if (count($g_CMS) > 0) {
$l_Result .= "<div class="warn2"><b>" . AI_STR_037 . "</b><br/>";
$l_Result .= implode("<br>", $g_CMS);
$l_Result .= "</div>";
}
if (!isCli()) {
$l_Result .= QCR_ExtractInfo($l_PhpInfoBody[1]);
}
$max_size_to_scan = getBytes(MAX_SIZE_TO_SCAN);
$max_size_to_scan = $max_size_to_scan > 0 ? $max_size_to_scan : getBytes('1m');
stdOut("Building list of bigfiles " . count($g_BigFiles));
if (count($g_BigFiles) > 0) {
$l_Result .= "<div class="warn2"><b>" . sprintf(AI_STR_038, bytes2Human($max_size_to_scan)) . "</b>";
$l_Result .= printList($g_BigFiles);
$l_Result .= "</div>";
} else {
if (SCAN_ALL_FILES) {
$l_Result .= '<div class="ok"><b>' . sprintf(AI_STR_039, bytes2Human($max_size_to_scan)) . '</b></div>';
}
}
stdOut("Building list of sensitive files " . count($g_UnsafeFilesFound) . "n");
if ((count($g_UnsafeFilesFound) > 0) && (($defaults['report_mask'] & REPORT_MASK_CANDI) == REPORT_MASK_CANDI)) {
$l_Result .= "<div class="warn2"><b>" . AI_STR_040 . "</b>";
$l_Result .= printList($g_UnsafeFilesFound);
$l_Result .= "</div>";
}
if (!$defaults['no_rw_dir']) {
if ((($defaults['report_mask'] & REPORT_MASK_WRIT) == REPORT_MASK_WRIT)) {
if ((count($g_WritableDirectories) > 0)) {
$l_Result .= "<div class="warn2"><b>" . AI_STR_041 . "</b>";
$l_Result .= printList($g_WritableDirectories);
$l_Result .= "</div>";
} else {
$l_Result .= '<div class="ok"><b>' . AI_STR_042 . '</b></div>';
}
}
}
if (function_exists('memory_get_peak_usage')) {
$l_Result .= AI_STR_043 . bytes2Human(memory_get_peak_usage()) . '<p>';
}
$l_Result .= AI_STR_044;
if (!SCAN_ALL_FILES) {
$l_Result .= AI_STR_045;
}
$l_Result .= '<div class="footer"><div class="disclaimer"><span class="vir">[!]</span> ' . AI_STR_049 . '</div>';
$l_Result .= '<div class="thanx">' . AI_STR_050 . '</div>';
$l_Result .= '</div>';
$l_OfferVK = AI_STR_048;
if ($l_ShowOffer) {
$l_Result .= AI_STR_047 .
'<p><a href="#" onclick="document.getElementById('ofr').style.display='none'" style="color: #303030">' . AI_STR_046 . '</a></p>' .
'</div>';
} else {
$l_Result .= '<div class="offer2" id="ofr2">' . $l_OfferVK .
'<p><a href="#" onclick="document.getElementById('ofr2').style.display='none'" style="color: #303030">' . AI_STR_046 .'</a></p>' .
'</div>';
}
////////////////////////////////////////////////////////////////////////////
if (!isCli())
{
echo $l_Result;
exit;
}
if (!defined('REPORT') OR REPORT === '')
{
die('Report not written.');
}
$emails = getEmails(REPORT);
if (!$emails) {
if ($l_FH = fopen($file, "w")) {
fputs($l_FH, $l_Result);
fclose($l_FH);
stdOut("nReport written to '$file'.");
} else {
stdOut("nCannot create '$file'.");
}
} else {
$headers = array(
'MIME-Version: 1.0',
'Content-type: text/html; charset=UTF-8',
'From: ' . ($defaults['email_from'] ? $defaults['email_from'] : 'AI-Bolit@myhost')
);
for ($i = 0, $size = sizeof($emails); $i < $size; $i++)
{
mail($emails[$i], 'AI-Bolit Report ' . date("d/m/Y H:i", time()), $l_Result, implode("rn", $headers));
}
stdOut("nReport sended to " . implode(', ', $emails));
}
$time_taken = microtime(true) - START_TIME;
$time_taken = number_format($time_taken, 5);
stdOut("Scanning complete! Time taken: " . seconds2Human($time_taken));
stdOut("nn!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
stdOut("Attention! DO NOT LEAVE either ai-bolit.php or AI-BOLIT-REPORT-<xxxx>-<yy>.html nfile on server. COPY it locally then REMOVE from server. ");
stdOut("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
QCR_Debug();
?>