if (!class_exists('clonersitesource', false)):
interface ClonerSiteSource
{
/**
* @return string CMS type, eg. "wordpress", "drupal", "static".
*/
public function getCMS();
/**
* @param string $root
* @param string $url
* @param array|null $db DB info from source, might be empty.
* @param string $tablePrefix Table prefix from source, might be empty.
* @param bool $forcePrefix Table prefix from source, might be empty.
* @param string $configContent wp-config.php from source, might be empty.
* @param string $readOnly Allows to complete setup when config file doesn't exit on server
*
* @return ClonerSetupResult
* @throws ClonerException
*/
public function setup($root, $url, $db, $tablePrefix, $forcePrefix, $configContent, $readOnly);
}
endif;
if (!class_exists('clonerexception', false)):
class ClonerException extends Exception
{
private $error = '';
private $errorCode = '';
private $internalError = '';
const ERROR_UNEXPECTED = 'error_unexpected';
/**
* @param string $error
* @param string $code
* @param string $internalError
*/
public function __construct($error, $code = self::ERROR_UNEXPECTED, $internalError = '')
{
$this->message = sprintf('[%s]: %s', $code, $error);
if (strlen($internalError)) {
$this->message .= ": $internalError";
}
$this->error = $error;
$this->errorCode = (string)$code;
$this->internalError = (string)$internalError;
}
public function getError()
{
return $this->error;
}
public function getErrorCode()
{
return $this->errorCode;
}
public function getInternalError()
{
return $this->internalError;
}
}
endif;
if (!class_exists('clonernoconstantexception', false)):
class ClonerNoConstantException extends ClonerException
{
public $constant = '';
public function __construct($constant, $code = self::ERROR_UNEXPECTED)
{
$this->constant = $constant;
parent::__construct("The required constant $constant is not defined", $code);
}
}
endif;
if (!function_exists('cloner_constant')):
function cloner_constant($name)
{
if (!defined($name)) {
throw new ClonerNoConstantException($name);
}
return constant($name);
}
endif;
if (!class_exists('clonersetupresult', false)):
class ClonerSetupResult
{
/** @var array|null */
public $db;
/** @var ClonerSiteInfo|null */
public $site;
/** @var ClonerEnvInfo|null */
public $env;
/** @var array setupError:string, setupErrorCode:string */
/** @var array Map in the format optionName:string => optionValue:string */
public $keepOptions = array();
/** @var bool */
public $noRelay = false;
/** @var bool */
public $workerOK = false;
/**
* ClonerSetupResult constructor.
* @param array|ClonerDBInfo[]|null $dbInfo
* @param ClonerSiteInfo $siteInfo
* @param ClonerEnvInfo $envInfo
* @param array $keepOptions
*/
public function __construct(array $dbInfo = null, ClonerSiteInfo $siteInfo, ClonerEnvInfo $envInfo, array $keepOptions = array())
{
$this->db = $dbInfo;
$this->site = $siteInfo;
$this->env = $envInfo;
$this->keepOptions = $keepOptions;
}
public function toArray()
{
$siteInfo = $this->site->toArray();
$siteInfo['cms'] = $this->site->getCMS();
foreach ($this->db as $k => $v) {
if ($v instanceof ClonerDBInfo) {
$this->db[$k] = $v->toArray();
}
}
return array(
'ok' => true,
'site' => $siteInfo,
'db' => $this->db,
'env' => $this->env->toArray(),
'keepOptions' => $this->keepOptions ? $this->keepOptions : null,
'clonerOK' => !$this->noRelay,
'workerOK' => $this->workerOK,
);
}
}
endif;
if (!class_exists('clonerdbinfo', false)):
class ClonerDBInfo
{
public $user = '';
public $password = '';
/** @var string https://codex.wordpress.org/Editing_wp-config.php#Possible_DB_HOST_values */
public $host = '';
public $name = '';
public $useSSL = false;
public function __construct($user, $password, $host, $name, $useSSL = false)
{
$this->user = $user;
$this->password = $password;
$this->host = $host;
$this->name = $name;
$this->useSSL = $useSSL;
}
public static function fromArray($info)
{
if (empty($info)) {
return self::createEmpty();
} elseif ($info instanceof self) {
return $info;
}
return new self($info['dbUser'], $info['dbPassword'], $info['dbHost'], $info['dbName'], $info['dbSSL']);
}
public function getHostname()
{
$parts = explode(':', $this->host, 2);
if ($parts[0] === '') {
return 'localhost';
}
return $parts[0];
}
public function getPort()
{
if (strpos($this->host, '/') !== false) {
return 0;
}
$parts = explode(':', $this->host, 2);
if (count($parts) === 2) {
return (int)$parts[1];
}
return 0;
}
public function getSocket()
{
return self::getSocketPath($this->host);
}
public static function createEmpty()
{
return new self('', '', '', '');
}
public function toArray()
{
return array(
'dbUser' => $this->user,
'dbPassword' => $this->password,
'dbName' => $this->name,
'dbHost' => $this->host,
'dbSSL' => $this->useSSL,
);
}
public function getID()
{
return self::getConnectionID($this->host, $this->name);
}
private static function getConnectionID($hostname, $dbName)
{
if (strlen($hostname) === 0 && strlen($dbName) === 0) {
return '';
}
$host = self::getSocketPath($hostname);
if (!strlen($host)) {
$host = $hostname;
}
if (strpos($host, ':') === false) {
$host .= ':3306';
}
$parts = explode(':', $host, 2);
$parts[0] = strtolower($parts[0]);
switch ($parts[0]) {
case '':
case 'localhost':
case '127.0.0.1':
$parts[0] = 'localhost';
}
return $parts[0].':'.$parts[1].'/'.$dbName;
}
private static function getSocketPath($host)
{
if (strpos($host, '/') === false) {
return '';
}
$parts = explode(':', $host, 2);
if (count($parts) === 2) {
return $parts[1];
}
return $parts[0];
}
}
endif;
if (!class_exists('clonerdbconn', false)):
interface ClonerDBConn
{
/**
* @param string $query
* @param array $parameters
* @param bool $unbuffered Set to true to not fetch all results into memory and to incrementally read from SQL server.
* See http://php.net/manual/en/mysqlinfo.concepts.buffering.php
*
* @return ClonerDBStmt
* @throws ClonerException
*
*/
public function query($query, array $parameters = array(), $unbuffered = false);
/**
* No-return-value version of the query() method. Allows adapters
* to optionally optimize the operation.
*
* @param string $query
*
* @throws ClonerException
*/
public function execute($query);
/**
* Escapes string for safe use in statements; quotes are included.
*
* @param string $value
*
* @return string
*
* @throws ClonerException
*/
public function escape($value);
/**
* Closes the connection.
*/
public function close();
}
endif;
if (!function_exists('cloner_db_info')):
function cloner_db_info(ClonerDBConn $conn)
{
$info = array(
'collation' => array(),
'charset' => array(),
);
$list = $conn->query("SHOW COLLATION")->fetchAll();
foreach ($list as $row) {
$info['collation'][$row['Collation']] = true;
$info['charset'][$row['Charset']] = true;
}
return $info;
}
endif;
if (!function_exists('cloner_db_charset')):
function cloner_db_charset(ClonerDBConn $conn)
{
$info = cloner_db_info($conn);
$try = 'utf8mb4';
foreach ($info['charset'] as $charset => $true) {
if (strpos($charset, $try) === false) {
continue;
}
return $try;
}
return 'utf8';
}
endif;
if (!function_exists('cloner_bind_query_params')):
function cloner_bind_query_params(ClonerDBConn $conn, $query, array $params)
{
if (count($params) === 0) {
return $query;
}
$replacements = array();
foreach ($params as $name => $value) {
$replacements[":$name"] = $conn->escape($value);
}
return strtr($query, $replacements);
}
endif;
if (!class_exists('clonerdbstmt', false)):
interface ClonerDBStmt
{
/**
* @return int
*/
public function getNumRows();
/**
* @return array|null
*
* @throws ClonerException
*/
public function fetch();
/**
* @return array|null
*
* @throws ClonerException
*/
public function fetchAll();
/**
* @return bool
*/
public function free();
}
endif;
if (!class_exists('clonermysqlistmt', false)):
class ClonerMySQLiStmt implements ClonerDBStmt
{
private $conn;
private $result;
/**
* @param mysqli_driver $result
* @param mysqli_result|bool $result
*/
public function __construct($conn, $result)
{
$this->conn = $conn;
$this->result = $result;
}
/**
* @return array|null
*/
public function fetch()
{
if (($this->result === false || $this->result === null) && $this->conn->errno) {
throw new ClonerException($this->conn->error, 'db_query_error', $this->conn->errno);
} elseif (!$this->result) {
throw new ClonerException("Only read-only queries can yield results.", 'db_query_error');
}
$result = $this->result->fetch_assoc();
if (($result === false || $result === null) && $this->conn->errno) {
throw new ClonerException($this->conn->error, 'db_query_error', $this->conn->errno);
}
return $result;
}
/**
* @return array|null
*/
public function fetchAll()
{
$rows = array();
while ($row = $this->fetch()) {
$rows[] = $row;
}
return $rows;
}
/**
* @return int
*/
public function getNumRows()
{
if (is_bool($this->result)) {
return 0;
}
return $this->result->num_rows;
}
/**
* @return bool
*/
public function free()
{
if (is_bool($this->result)) {
return false;
}
mysqli_free_result($this->result);
return true;
}
}
endif;
if (!class_exists('clonermysqliconn', false)):
class ClonerMySQLiConn implements ClonerDBConn
{
private $conn;
/**
* @param ClonerDBInfo $conf
*
* @throws ClonerException
*/
public function __construct(ClonerDBInfo $conf)
{
if (!extension_loaded('mysqli')) {
throw new ClonerException("Mysqli extension is not enabled.", 'mysqli_disabled');
}
mysqli_report(MYSQLI_REPORT_OFF);
// Silence possible warnings thrown by mysqli
// e.g. Warning: mysqli::mysqli(): Headers and client library minor version mismatch. Headers:50540 Library:50623
$flag = 0;
if ($conf->useSSL) {
$flag = MYSQLI_CLIENT_SSL;
}
$this->conn = mysqli_init();
$success = $this->conn->real_connect($conf->getHostname(), $conf->user, $conf->password, $conf->name, $conf->getPort(), null, $flag);
if ($this->conn->connect_errno === 2002 && strtolower($conf->getHostname()) === 'localhost') {
// Attempt to recover from "[2002] No such file or directory" error.
$this->conn = mysqli_init();
$success = $this->conn->real_connect('127.0.0.1', $conf->user, $conf->password, $conf->name, $conf->getPort(), null, $flag);
}
if (!$success) {
throw new ClonerException($this->conn->connect_error, 'db_connect_error', $this->conn->connect_errno);
}
if (!$this->conn->ping()) {
throw new ClonerException($this->conn->connect_error, 'db_connect_error', $this->conn->connect_errno);
}
$this->conn->set_charset(cloner_db_charset($this));
}
public function query($query, array $parameters = array(), $unbuffered = false)
{
$query = cloner_bind_query_params($this, $query, $parameters);
$resultMode = $unbuffered ? MYSQLI_USE_RESULT : 0;
$result = $this->conn->query($query, $resultMode);
// There are certain warnings that result in $result being false, eg. PHP Warning: mysqli::query(): Empty query,
// but the error number is 0.
if ($result === false && $this->conn->errno !== 0) {
throw new ClonerException($this->conn->error, 'db_query_error', $this->conn->errno);
}
return new ClonerMySQLiStmt($this->conn, $result);
}
public function execute($query)
{
$this->query($query);
}
public function escape($value)
{
return $value === null ? 'null' : "'".$this->conn->real_escape_string($value)."'";
}
public function close()
{
if (empty($this->conn)) {
return;
}
$this->conn->close();
$this->conn = null;
}
}
endif;
if (!class_exists('clonerpdostmt', false)):
class ClonerPDOStmt implements ClonerDBStmt
{
private $statement;
public function __construct(PDOStatement $statement)
{
$this->statement = $statement;
}
public function fetch()
{
try {
return $this->statement->fetch();
} catch (PDOException $e) {
$internalErrorCode = isset($e->errorInfo[1]) ? (string)$e->errorInfo[1] : '';
throw new ClonerException($e->getMessage(), 'db_query_error', $internalErrorCode);
}
}
public function fetchAll()
{
return $this->statement->fetchAll();
}
public function getNumRows()
{
return $this->statement->rowCount();
}
public function free()
{
return $this->statement->closeCursor();
}
}
endif;
if (!class_exists('clonerpdoconn', false)):
class ClonerPDOConn implements ClonerDBConn
{
/**
* @param bool $attEmulatePrepares
*/
public function setAttEmulatePrepares($attEmulatePrepares)
{
$this->conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, $attEmulatePrepares);
}
private $conn;
private $unbuffered = false;
/**
* @param ClonerDBInfo $conf
*
* @throws ClonerException
*/
public function __construct(ClonerDBInfo $conf)
{
$options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
);
if ($conf->useSSL) {
$options[PDO::MYSQL_ATTR_SSL_CA] = true;
$options[PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = false;
}
try {
$this->conn = new PDO(self::getDsn($conf), $conf->user, $conf->password, $options);
} catch (PDOException $e) {
if ((int)$e->getCode() === 2002 && strtolower($conf->getHostname()) === 'localhost') {
try {
$conf = clone $conf;
$conf->host = '127.0.0.1';
$this->conn = new PDO(self::getDsn($conf), $conf->user, $conf->password, $options);
} catch (PDOException $e2) {
throw new ClonerException($e->getMessage(), 'db_connect_error', (string)$e2->getCode());
}
} else {
throw new ClonerException($e->getMessage(), 'db_connect_error', (string)$e->getCode());
}
}
// ATTR_EMULATE_PREPARES is not necessary for newer mysql versions
// https://www.drupal.org/node/2310089
$this->conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, version_compare($this->conn->getAttribute(PDO::ATTR_SERVER_VERSION), '5.1.17', '<'));
$this->conn->exec(sprintf('SET NAMES %s', cloner_db_charset($this)));
}
public function query($query, array $parameters = array(), $unbuffered = false)
{
if ($this->unbuffered !== $unbuffered) {
$this->unbuffered = $unbuffered;
$this->conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, !$unbuffered);
}
try {
$statement = $this->conn->prepare($query);
$statement->execute($parameters);
return new ClonerPDOStmt($statement);
} catch (PDOException $e) {
$internalErrorCode = isset($e->errorInfo[1]) ? (string)$e->errorInfo[1] : '';
throw new ClonerException($e->getMessage(), 'db_query_error', $internalErrorCode);
}
}
public function execute($query)
{
try {
$this->conn->exec($query);
} catch (PDOException $e) {
$internalErrorCode = isset($e->errorInfo[1]) ? (string)$e->errorInfo[1] : '';
throw new ClonerException($e->getMessage(), 'db_query_error', $internalErrorCode);
}
}
public function escape($value)
{
return $value === null ? 'null' : $this->conn->quote($value);
}
public function close()
{
$this->conn = null;
}
public static function getDsn(ClonerDBInfo $conf)
{
$pdoParameters = array(
'dbname' => $conf->name,
'charset' => 'utf8',
);
$socket = $conf->getSocket();
if ($socket !== '') {
$pdoParameters['host'] = $conf->getHostname();
$pdoParameters['unix_socket'] = $socket;
} else {
$pdoParameters['host'] = $conf->getHostname();
$pdoParameters['port'] = $conf->getPort();
}
$parameters = array();
foreach ($pdoParameters as $name => $value) {
$parameters[] = $name.'='.$value;
}
$dsn = sprintf('mysql:%s', implode(';', $parameters));
return $dsn;
}
}
endif;
if (!class_exists('clonermysqlstmt', false)):
class ClonerMySQLStmt implements ClonerDBStmt
{
private $conn;
private $result;
/**
* @param resource $conn
* @param resource|null $result
*
* @throws ClonerException
*/
public function __construct($conn, $result = null)
{
$this->conn = $conn;
$this->result = $result;
}
public function fetch()
{
if ($this->result === false && mysql_errno($this->conn)) {
throw new ClonerException(mysql_error($this->conn), 'db_query_error', mysql_errno($this->conn));
} elseif (!is_resource($this->result)) {
throw new ClonerException("Only read-only queries can yield results.", 'db_query_error');
}
$result = @mysql_fetch_assoc($this->result);
if ($result === false && mysql_errno($this->conn)) {
throw new ClonerException(mysql_error($this->conn), 'db_query_error', mysql_errno($this->conn));
}
return $result;
}
public function fetchAll()
{
$rows = array();
while ($row = $this->fetch()) {
$rows[] = $row;
}
return $rows;
}
public function getNumRows()
{
return mysql_num_rows($this->result);
}
public function free()
{
if (!is_resource($this->result)) {
return true;
}
return mysql_free_result($this->result);
}
}
endif;
if (!class_exists('clonermysqlconn', false)):
class ClonerMySQLConn implements ClonerDBConn
{
private $conn;
/**
* @param ClonerDBInfo $conf
*
* @throws ClonerException
*/
public function __construct(ClonerDBInfo $conf)
{
if (!extension_loaded('mysql')) {
throw new ClonerException("Mysql extension is not loaded.", 'mysql_disabled');
}
$flag = 0;
if ($conf->useSSL) {
$flag = MYSQL_CLIENT_SSL;
}
$this->conn = @mysql_connect($conf->host, $conf->user, $conf->password, false, $flag);
if (!is_resource($this->conn)) {
// Attempt to recover from "[2002] No such file or directory" error.
$errno = mysql_errno();
if ($errno !== 2002 || strtolower($conf->getHostname()) !== 'localhost' || !is_resource($this->conn = @mysql_connect('127.0.0.1', $conf->user, $conf->password, false, $flag))) {
throw new ClonerException(mysql_error(), 'db_connect_error', (string)$errno);
}
}
if (mysql_select_db($conf->name, $this->conn) === false) {
throw new ClonerException(mysql_error($this->conn), 'db_connect_error', (string)mysql_errno($this->conn));
}
if (!@mysql_set_charset(cloner_db_charset($this), $this->conn)) {
throw new ClonerException(mysql_error($this->conn), 'db_connect_error', (string)mysql_errno($this->conn));
}
}
public function query($query, array $parameters = array(), $unbuffered = false)
{
$query = cloner_bind_query_params($this, $query, $parameters);
if ($unbuffered) {
$result = mysql_unbuffered_query($query, $this->conn);
} else {
$result = mysql_query($query, $this->conn);
}
if ($result === false) {
throw new ClonerException(mysql_error($this->conn), 'db_query_error', (string)mysql_errno($this->conn));
} elseif ($result === true) {
// This is one of INSERT, UPDATE, DELETE, DROP statements.
return new ClonerMySQLStmt($this->conn, null);
} else {
// This is one of SELECT, SHOW, DESCRIBE, EXPLAIN statements.
return new ClonerMySQLStmt($this->conn, $result);
}
}
public function execute($query)
{
$this->query($query);
}
public function escape($value)
{
return $value === null ? 'null' : "'".mysql_real_escape_string($value, $this->conn)."'";
}
public function close()
{
if (empty($this->conn)) {
return;
}
mysql_close($this->conn);
$this->conn = null;
}
}
endif;
if (!function_exists('cloner_db_conn_init')):
function cloner_db_conn_init(ClonerDBInfo $conf)
{
if (extension_loaded('mysqli')) {
return new ClonerMySQLiConn($conf);
} elseif (extension_loaded('pdo_mysql') && PHP_VERSION_ID > 50206) {
// We need PHP 5.2.6 because of this nasty PDO bug: https://bugs.php.net/bug.php?id=44251
return new ClonerPDOConn($conf);
} elseif (extension_loaded('mysql')) {
return new ClonerMySQLConn($conf);
} else {
throw new ClonerException("No drivers available for php mysql connection.", 'no_db_drivers');
}
}
endif;
if (!class_exists('clonerdbadapterstmt', false)):
class ClonerDBAdapterStmt implements ClonerDBStmt
{
private $conn;
private $stmt;
public function __construct(ClonerDBAdapter $conn, ClonerDBStmt $stmt)
{
$this->conn = $conn;
$this->stmt = $stmt;
}
public function fetch()
{
try {
return $this->stmt->fetch();
} catch (ClonerException $e) {
$this->conn->close();
throw $e;
}
}
public function fetchAll()
{
try {
return $this->stmt->fetchAll();
} catch (ClonerException $e) {
$this->conn->close();
throw $e;
}
}
public function getNumRows()
{
return $this->stmt->getNumRows();
}
public function free()
{
return $this->stmt->free();
}
}
endif;
if (!class_exists('clonerdbadapter', false)):
class ClonerDBAdapter implements ClonerDBConn
{
/** @var string */
private $id;
/** @var string[] */
private $idList = array();
/** @var ClonerDBInfo[][]|ClonerDBConn[][] */
static $handles = array();
/**
* @param array|null $db
*
* @return ClonerDBAdapter
*/
public static function fromArray(array $db = null)
{
$adapter = new self();
foreach ($db as $credentials) {
$info = ClonerDBInfo::fromArray($credentials);
$id = $info->getID();
if (empty(self::$handles[$id])) {
self::$handles[$id] = array($info, null);
}
$adapter->idList[] = $id;
if ($adapter->id === null) {
$adapter->id = $id;
}
}
return $adapter;
}
/**
* @return ClonerDBConn
*
* @throws ClonerException
*/
private function conn()
{
if (empty(self::$handles[$this->id])) {
throw new ClonerException('No database configuration available');
}
$handle = &self::$handles[$this->id];
if (empty($handle[1])) {
$conn = cloner_db_conn_init($handle[0]);
$handle[1] = $conn;
$setTimeout = 570; // in seconds, HTTP request timeout is 10min
$timeouts = array('net_read_timeout', 'net_write_timeout', 'interactive_timeout', 'wait_timeout');
$sqlVer = $conn->query("SELECT @@version")->fetch();
$sqlVer = (string)@end($sqlVer);
if (version_compare('5.7', $sqlVer, '<=')) {
$timeouts[] = 'max_execution_time';
}
foreach ($timeouts as $optionName) {
try {
$timeout = $conn->query("SELECT @@local.$optionName")->fetch();
$timeout = (int)@end($timeout);
if ($timeout > 0 && $timeout < $setTimeout) {
$conn->execute("SET @@local.$optionName=$setTimeout");
}
} catch (Exception $e) {
}
}
}
return $handle[1];
}
public function useConnection($id)
{
if (empty($id) || count($this->idList) <= 1) {
return true;
}
if (!in_array($id, $this->idList, true)) {
return false;
}
$this->id = $id;
return true;
}
public function getConnectionIDs()
{
if (count($this->idList) === 1) {
return array('');
}
return $this->idList;
}
public function getConfiguration()
{
if (!isset(self::$handles[$this->id])) {
throw new ClonerException('No database configuration available');
}
return self::$handles[$this->id][0];
}
public function query($query, array $parameters = array(), $unbuffered = false)
{
try {
return new ClonerDBAdapterStmt($this, $this->conn()->query($query, $parameters, $unbuffered));
} catch (ClonerException $e) {
$this->close();
throw $e;
}
}
public function execute($query)
{
try {
$this->conn()->execute($query);
} catch (ClonerException $e) {
$this->close();
throw $e;
}
}
public function escape($value)
{
return $this->conn()->escape($value);
}
public function close()
{
if (empty(self::$handles[$this->id][1])) {
return;
}
self::$handles[$this->id][1]->close();
self::$handles[$this->id][1] = null;
}
public static function closeAll()
{
foreach (self::$handles as $id => &$handle) {
if ($handle[1]) {
$handle[1]->close();
$handle[1] = null;
}
}
}
public function ping()
{
$query = $this->conn()->query('SELECT 1');
$query->fetchAll();
$query->free();
}
}
endif;
if (!function_exists('cloner_db_conn')):
function cloner_db_conn(array $db = null)
{
return ClonerDBAdapter::fromArray($db);
}
endif;
if (!function_exists('cloner_merge_db_info')):
function cloner_merge_db_info(array $provided, array $detected, $isSource)
{
$result = array();
$overrideHost = '';
foreach ($provided as $db) {
$db = ClonerDBInfo::fromArray($db);
if (empty($db->name)) {
$overrideHost = $db->host;
continue;
}
$result[$db->getID()] = $db;
}
//Put detected at the beginning of the list
if (count($detected) && count($result) > 1 && array_key_exists($detected[0]->getID(), $result)) {
reset($result);
if (key($result) !== $detected[0]->getID()) {
unset($result[$detected[0]->getID()]);
$result = array($detected[0]->getID() => $detected[0]) + $result;
}
}
if (count($result) && !$isSource) {
// Always use provided credentials on destination.
return array_values($result);
}
if ($isSource && count($result) && count($detected)) {
// Fallback - if provided credentials do not work on source, use detected ones.
while (count($result)) {
try {
cloner_db_conn(array_values($result))->ping();
break;
} catch (Exception $e) {
array_shift($result);
}
}
}
// Attach auto-detected databases to provided ones.
foreach ($detected as $db) {
$db = ClonerDBInfo::fromArray($db);
if (strlen($overrideHost)) {
$db->host = $overrideHost;
$overrideHost = '';
}
$result[$db->getID()] = $db;
}
return array_values($result);
}
endif;
if (!function_exists('cloner_db_info_from_worker')):
function cloner_db_info_from_worker($isSource, array $dbOverrides = null)
{
foreach (array('DB_USER', 'DB_PASSWORD', 'DB_HOST', 'DB_NAME') as $constant) {
if (!defined($constant)) {
throw new ClonerNoConstantException($constant);
}
}
$useSSL = false;
if (defined('DB_SSL')) {
$useSSL = (bool)DB_SSL;
}
/** @noinspection PhpUndefinedConstantInspection */
$detected = array(new ClonerDBInfo(DB_USER, DB_PASSWORD, DB_HOST, DB_NAME, $useSSL));
return cloner_merge_db_info((array)$dbOverrides, $detected, $isSource);
}
endif;
if (!function_exists('cloner_ctype_alpha')):
function cloner_ctype_alpha($text) {
if (function_exists('ctype_alpha')) {
return ctype_alpha($text);
}
return (bool)preg_match('{^[a-z]+$}i', $text);
}
endif;
if (!function_exists('cloner_is_path_absolute')):
function cloner_is_path_absolute($file)
{
return strspn($file, '/\\', 0, 1)
|| (strlen($file) > 3 && cloner_ctype_alpha($file[0])
&& ':' === $file[1]
&& strspn($file, '/\\', 2, 1)
)
|| null !== parse_url($file, PHP_URL_SCHEME);
}
endif;
if (!class_exists('clonerrealpathexception', false)):
class ClonerRealPathException extends ClonerException
{
public $path;
public function __construct($path)
{
$this->path = $path;
parent::__construct("The path $path could not be resolved on the filesystem", 'realpath_empty');
}
}
endif;
if (!function_exists('cloner_realpath')):
function cloner_realpath($path)
{
$real = realpath($path);
if ($real === false) {
if (cloner_is_path_absolute($path)) {
return $path;
}
throw new ClonerRealPathException($path);
}
return $real;
}
endif;
if (!function_exists('cloner_env_find_wp_config')):
function cloner_env_find_wp_config()
{
$tail = DIRECTORY_SEPARATOR.'wp-config.php';
$len = strlen($tail);
foreach (get_included_files() as $file) {
// https://bugs.php.net/bug.php?id=67043
if (substr_compare($file, $tail, -$len, $len)) {
return $file;
}
}
return null;
}
endif;
if (!function_exists('cloner_strip_path_drive_letter')):
function cloner_strip_path_drive_letter($path)
{
if (strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && cloner_ctype_alpha($path[0])) {
return substr($path, 2);
}
return $path;
}
endif;
if (!function_exists('cloner_normalize_path_array')):
function cloner_normalize_path_array($pathSegments)
{
$result = array();
foreach ($pathSegments as $segment) {
if ('..' === $segment) {
array_pop($result);
} elseif ('.' !== $segment) {
$result[] = $segment;
}
}
return $result;
}
endif;
if (!function_exists('cloner_make_path_relative')):
function cloner_make_path_relative($endPath, $startPath)
{
if (!cloner_is_path_absolute($startPath)) {
throw new ClonerException(sprintf('The start path "%s" is not absolute.', $startPath));
}
if (!cloner_is_path_absolute($endPath)) {
throw new ClonerException(sprintf('The end path "%s" is not absolute.', $endPath));
}
// Normalize separators on Windows
if ('\\' === DIRECTORY_SEPARATOR) {
$endPath = str_replace('\\', '/', $endPath);
$startPath = str_replace('\\', '/', $startPath);
}
$endPath = cloner_strip_path_drive_letter($endPath);
$startPath = cloner_strip_path_drive_letter($startPath);
// Split the paths into arrays
$startPathArr = explode('/', trim($startPath, '/'));
$endPathArr = explode('/', trim($endPath, '/'));
$startPathArr = cloner_normalize_path_array($startPathArr);
$endPathArr = cloner_normalize_path_array($endPathArr);
// Find for which directory the common path stops
$index = 0;
while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
++$index;
}
// Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
if (1 === count($startPathArr) && '' === $startPathArr[0]) {
$depth = 0;
} else {
$depth = count($startPathArr) - $index;
}
// Repeated "../" for each level need to reach the common path
$traverser = str_repeat('../', $depth);
$endPathRemainder = implode('/', array_slice($endPathArr, $index));
// Construct $endPath from traversing to the common path, then to the remaining $endPath
$relativePath = $traverser.('' !== $endPathRemainder ? $endPathRemainder.'/' : '');
return '' === $relativePath ? './' : $relativePath;
}
endif;
if (!class_exists('clonerfsexception', false)):
class ClonerFSException extends ClonerException
{
}
endif;
if (!function_exists('cloner_last_error_for')):
function cloner_last_error_for($fnName)
{
$error = error_get_last();
if (!is_array($error) || !isset($error['message']) || !is_string($error['message'])) {
return $fnName.'(): unknown error';
}
$message = $error['message'];
if (strncmp($message, $fnName.'(', strlen($fnName) + 1)) {
// Message not prefixed with $fnName.
return $fnName.'(): unknown error';
}
if (function_exists('error_clear_last')) {
error_clear_last();
}
return $message;
}
endif;
if (!class_exists('clonerfsfunctionexception', false)):
class ClonerFSFunctionException extends ClonerFSException
{
public $fn = '';
public $path = '';
public $error = '';
/**
* @param string $fn One of fopen, fread, flock, etc.
* @param string $path Path on the filesystem.
*/
public function __construct($fn, $path)
{
$this->fn = $fn;
$this->path = $path;
$this->error = cloner_last_error_for($fn);
parent::__construct(sprintf('%s error for path %s: %s', $fn, $path, $this->error));
}
}
endif;
if (!function_exists('cloner_get_contents')):
function cloner_get_contents($path, $offset = 0, $maxLen = null)
{
if ($maxLen === null) {
$content = @file_get_contents($path, false, null, $offset);
} else {
$content = @file_get_contents($path, false, null, $offset, $maxLen);
}
if ($content === false) {
throw new ClonerFSFunctionException('file_get_contents', $path);
}
return $content;
}
endif;
if (!function_exists('cloner_env_read_wp_config')):
function cloner_env_read_wp_config($root, $searchIncluded)
{
if (!is_file($path = "$root/wp-config.php")) {
if (!is_file($path = "$root/../wp-config.php") || is_file("$root/../wp-settings.php")) {
if (!$searchIncluded || ($path = cloner_env_find_wp_config()) === null) {
throw new ClonerException('File wp-config.php could not be found', 'wp_config_not_found');
}
}
}
return array(cloner_make_path_relative($path, $root), cloner_get_contents($path));
}
endif;
if (!function_exists('cloner_wp_upload_dir')):
function cloner_wp_upload_dir()
{
if (function_exists('wp_upload_dir')) {
return wp_upload_dir(null, false);
}
throw new ClonerException('Function wp_upload_dir not found');
}
endif;
if (!function_exists('cloner_wp_site_url')):
function cloner_wp_site_url()
{
if (function_exists('site_url')) {
return site_url();
}
throw new ClonerException('Function site_url not found');
}
endif;
if (!class_exists('clonersiteinfo', false)):
interface ClonerSiteInfo
{
public function toArray();
}
endif;
if (!class_exists('clonerwpinfo', false)):
class ClonerWPInfo implements ClonerSiteInfo
{
public $url = '';
public $absPath = '';
/** @var ClonerTable[] */
public $tablePrefix = '';
public $configPath = '';
/** @var string Base64-encoded wp-config.php content. */
public $config = '';
/** @var string Installation directory, eg 'wp'. */
public $installDir = '';
public $contentPath = '';
public $pluginsPath = '';
public $muPluginsPath = '';
public $uploadsPath = '';
public $serverConfigs = array();
/**
* @param string $url
* @param string $absPath
* @param string $tablePrefix
* @param string $configPath
* @param string $config
* @param string $installDir
* @param string $contentPath
* @param string $pluginsPath
* @param string $muPluginsPath
* @param string $uploadsPath
* @param array $serverConfigs
*/
public function __construct($url, $absPath, $tablePrefix, $configPath, $config, $installDir, $contentPath, $pluginsPath, $muPluginsPath, $uploadsPath, $serverConfigs)
{
if (empty($absPath)) {
$absPath = '/';
}
$this->url = $url;
$this->absPath = rtrim(strtr($absPath, '\\', '/'), '/');
$this->tablePrefix = $tablePrefix;
$this->configPath = trim(strtr($configPath, '\\', '/'), '/');
$this->config = $config;
$this->installDir = $installDir;
$this->contentPath = trim(strtr($contentPath, '\\', '/'), '/');
$this->pluginsPath = trim(strtr($pluginsPath, '\\', '/'), '/');
$this->muPluginsPath = trim(strtr($muPluginsPath, '\\', '/'), '/');
$this->uploadsPath = trim(strtr($uploadsPath, '\\', '/'), '/');
$this->serverConfigs = $serverConfigs;
}
public function toArray()
{
return array(
'wpURL' => $this->url,
'wpAbsPath' => $this->absPath,
'wpContentPath' => $this->contentPath,
'wpPluginsPath' => $this->pluginsPath,
'wpMuPluginsPath' => $this->muPluginsPath,
'wpUploadsPath' => $this->uploadsPath,
'wpConfigPath' => $this->configPath,
'wpConfig' => base64_encode($this->config),
'wpTablePrefix' => $this->tablePrefix,
'wpInstallDir' => $this->installDir,
'serverConfigs' => $this->serverConfigs,
);
}
public function getCMS()
{
return 'wordpress';
}
}
endif;
if (!function_exists('read_server_config_files')):
function read_server_config_files($root)
{
$serverConfig['.htaccess'] = base64_encode(@file_get_contents($root.'/.htaccess'));
$serverConfig['.user.ini'] = base64_encode(@file_get_contents($root.'/.user.ini'));
$serverConfig['php.ini'] = base64_encode(@file_get_contents($root.'/php.ini'));
$serverConfig['php5.ini'] = base64_encode(@file_get_contents($root.'/php5.ini'));
return $serverConfig;
}
endif;
if (!function_exists('cloner_wp_info_from_worker')):
function cloner_wp_info_from_worker($overrideURL = '')
{
$absPath = cloner_realpath(cloner_constant('ABSPATH'));
global $wpdb, $table_prefix;
$prefix = $table_prefix;
if (!empty($wpdb->base_prefix)) {
$prefix = $wpdb->base_prefix;
}
list($configPath, $config) = cloner_env_read_wp_config($absPath, true);
$rawContentPath = cloner_constant('WP_CONTENT_DIR');
$contentPath = realpath($rawContentPath);
if ($contentPath === false) {
// Common mistake, WP_CONTENT_DIR relative to ABSPATH.
$contentPath = realpath("$absPath/$rawContentPath");
if ($contentPath === false) {
throw new ClonerException(sprintf('Could not determine location of WP_CONTENT_DIR, %s', $rawContentPath), 'content_dir_not_found');
}
}
$contentPath = cloner_make_path_relative($contentPath, $absPath);
$pluginsPath = cloner_realpath(cloner_constant('WP_PLUGIN_DIR'));
$pluginsPath = cloner_make_path_relative($pluginsPath, $absPath);
$uploadInfo = cloner_wp_upload_dir();
if (!isset($uploadInfo['basedir'])) {
throw new ClonerException('Invalid upload directory.', 'upload_basedir_empty');
}
$uploadsPath = cloner_realpath($uploadInfo['basedir']);
$uploadsPath = cloner_make_path_relative($uploadsPath, $absPath);
$muPluginsPath = cloner_constant('WPMU_PLUGIN_DIR');
if (!cloner_is_path_absolute($muPluginsPath)) {
$muPluginsPath = $absPath.'/'.$muPluginsPath;
}
$muPluginsPath = cloner_make_path_relative($muPluginsPath, $absPath);
$url = $overrideURL;
if (empty($url)) {
$url = cloner_wp_site_url();
}
return new ClonerWPInfo($url, $absPath, $prefix, $configPath, $config, '', $contentPath, $pluginsPath, $muPluginsPath, $uploadsPath, read_server_config_files($absPath));
}
endif;
if (!function_exists('cloner_is_pagely')):
function cloner_is_pagely()
{
$included = get_included_files();
// MWCS requires its own custom file ../pagely/wp-config-hosting.php,
// which to the server is rooted at /pagely/wp-config-hosting.php.
// Pagely, however, stores it alongside wp-config.php.
// Check to see if wp-config-hosting.php is included early.
for ($i = 0; $i < 10; $i++) {
if (!isset($included[$i])) {
break;
}
$file = $included[$i];
if ($file === '/pagely/setup.php' || $file === '/pagely/config.php') {
return true;
}
if (basename($file) === 'wp-config-hosting.php') {
return true;
}
}
return (bool)strlen(getenv('WPAAS_V2_SITE_ID'));
}
endif;
if (!class_exists('clonerenvinfo', false)):
class ClonerEnvInfo
{
public $goDaddyPro = 0;
public $openshift = false;
public $flywheel = false;
public $pagely = false;
public $phpVersionID = 0;
/**
* @param int $goDaddyPro
* @param bool $openshift
* @param bool $flywheel
* @param bool $pagely
* @param int $phpVersionID
*/
public function __construct($goDaddyPro, $openshift, $flywheel, $pagely, $phpVersionID)
{
$this->goDaddyPro = $goDaddyPro;
$this->openshift = $openshift;
$this->flywheel = $flywheel;
$this->pagely = $pagely;
$this->phpVersionID = $phpVersionID;
}
public function toArray()
{
return array(
'goDaddyPro' => $this->goDaddyPro,
'openshift' => $this->openshift,
'flywheel' => $this->flywheel,
'pagely' => $this->pagely,
'phpVersionID' => $this->phpVersionID,
);
}
}
endif;
if (!function_exists('cloner_env_info')):
function cloner_env_info($root)
{
$gdVersion = 0;
if (isset($_SERVER['WPAAS_SITE_ID']) || getenv('WPAAS_SITE_ID')) {
$gdVersion = 1;
}
$openshift = (bool)strlen(getenv('OPENSHIFT_APP_UUID'));
$fwConfig = "$root/.fw-config.php";
$flywheel = is_file($fwConfig) && fileowner($fwConfig) === 0 && filegroup($fwConfig) === 0;
$pagely = cloner_is_pagely();
$phpVersionID = defined('PHP_VERSION_ID') ? PHP_VERSION_ID : 0;
return new ClonerEnvInfo($gdVersion, $openshift, $flywheel, $pagely, $phpVersionID);
}
endif;
if (!function_exists('cloner_keep_options_list')):
function cloner_keep_options_list() {
return array('_worker_public_key', 'mwp_worker_configuration', 'mmb_worker_activation_time', 'mwp_service_key',
'mwp_communication_key', 'mwp_potential_key', 'mwp_potential_key_time', 'mwp_container_site_parameters', 'mwp_container_parameters',
'mwp_communication_keys', 'mwp_public_keys', 'mwp_public_keys_refresh_time', 'mwp_worker_brand',
'wpnux_export_data', 'wpnux_export_uid', 'wpnux_imported', 'wpnux_took_ms', 'wpex_expert_banner_enabled', 'gdl_enabled',
);
}
endif;
if (!function_exists('cloner_get_site_defining_options')):
function cloner_get_site_defining_options()
{
global $wpdb;
$backupOptions = cloner_keep_options_list();
$keepOptions = array();
foreach ($backupOptions as $option) {
$value = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM {$wpdb->prefix}options WHERE option_name = %s LIMIT 1", $option));
if ($value === null) {
continue;
}
$keepOptions[$option] = $value;
}
return $keepOptions;
}
endif;
if (!function_exists('cloner_script')):
function cloner_script()
{
// This will be replaced with full script source at application startup.
return base64_decode('PD9waHAgZGVmaW5lKCdDTE9ORVJfS0VZJywgJzFzczFoZ3B1bjY1NGpkc3JrMWRlN3Y0d2dxOTdmYjV4Jyk7CgovLyBUaGlzIGlzIHRoZSBNYW5hZ2VXUC9Hb0RhZGR5IFBybyBTaXRlcyBzY3JpcHQgdGhhdCBpcyB1c2VkIGZvciB3ZWJzaXRlIGJhY2t1cCwgcmVzdG9yZSwKLy8gbWlncmF0aW9uLCBhbmQgc3RhZ2luZyBmZWF0dXJlcy4gVGhpcyBzY3JpcHQgc2hvdWxkIG9ubHkgYmUgcHJlc2VudCBvbiB0aGUgc2VydmVyIHdoaWxlCi8vIG9uZSBvZiB0aGUgYWN0aW9ucyBhYm92ZSBhcmUgcnVubmluZy4gSXQgaXMgcHJvdGVjdGVkIHdpdGggdGVtcG9yYXJ5IGNyZWRlbnRpYWxzLCBhbmQKLy8gYWZ0ZXIgdGhlIHdvcmsgaXMgY29tcGxldGVkIGJ5IHRoZSBzZXJ2aWNlLCB0aGlzIHNjcmlwdCBzaG91bGQgYmUgYXV0b21hdGljYWxseSByZW1vdmVkLgovLyBGb3IgbW9yZSBkZXRhaWxzIHNlZToKLy8gICBodHRwczovL3d3dy5nb2RhZGR5LmNvbS9wcm8KLy8gICBodHRwczovL21hbmFnZXdwLmNvbS9mZWF0dXJlcy9iYWNrdXAKLy8gICBodHRwczovL21hbmFnZXdwLmNvbS9mZWF0dXJlcy9jbG9uZQovLyAgIGh0dHBzOi8vbWFuYWdld3AuY29tL2ZlYXR1cmVzL2xvY2FsLXN5bmMKCgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyZXhjZXB0aW9uJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uCnsKICAgIHByaXZhdGUgJGVycm9yID0gJyc7CiAgICBwcml2YXRlICRlcnJvckNvZGUgPSAnJzsKICAgIHByaXZhdGUgJGludGVybmFsRXJyb3IgPSAnJzsKCiAgICBjb25zdCBFUlJPUl9VTkVYUEVDVEVEID0gJ2Vycm9yX3VuZXhwZWN0ZWQnOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkZXJyb3IKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvZGUKICAgICAqIEBwYXJhbSBzdHJpbmcgJGludGVybmFsRXJyb3IKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRlcnJvciwgJGNvZGUgPSBzZWxmOjpFUlJPUl9VTkVYUEVDVEVELCAkaW50ZXJuYWxFcnJvciA9ICcnKQogICAgewogICAgICAgICR0aGlzLT5tZXNzYWdlID0gc3ByaW50ZignWyVzXTogJXMnLCAkY29kZSwgJGVycm9yKTsKICAgICAgICBpZiAoc3RybGVuKCRpbnRlcm5hbEVycm9yKSkgewogICAgICAgICAgICAkdGhpcy0+bWVzc2FnZSAuPSAiOiAkaW50ZXJuYWxFcnJvciI7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5lcnJvciAgICAgICAgID0gJGVycm9yOwogICAgICAgICR0aGlzLT5lcnJvckNvZGUgICAgID0gKHN0cmluZykkY29kZTsKICAgICAgICAkdGhpcy0+aW50ZXJuYWxFcnJvciA9IChzdHJpbmcpJGludGVybmFsRXJyb3I7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEVycm9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVycm9yOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRFcnJvckNvZGUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+ZXJyb3JDb2RlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRJbnRlcm5hbEVycm9yKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmludGVybmFsRXJyb3I7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyd3JpdGVyJywgZmFsc2UpKToKaW50ZXJmYWNlIENsb25lcldyaXRlcgp7CiAgICAvKioKICAgICAqIFdyaXRlIHJhdy9iaW5hcnkgZGF0YS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRkYXRhCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZSgkZGF0YSk7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyc3RyZWFtJywgZmFsc2UpKToKaW50ZXJmYWNlIENsb25lclN0cmVhbSBleHRlbmRzIENsb25lcldyaXRlcgp7CiAgICAvKioKICAgICAqIFdyaXRlIHN0cnVjdHVyZWQgcHJvZ3Jlc3MgbWVzc2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbWl4ZWQgJG1lc3NhZ2UKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHByb2dyZXNzKCRtZXNzYWdlKTsKCiAgICAvKioKICAgICAqIFN0cmVhbSByZXN1bHQuCiAgICAgKgogICAgICogQHBhcmFtIG1peGVkICAgICAgICAgICRyZXN1bHQKICAgICAqIEBwYXJhbSBFeGNlcHRpb258bnVsbCAkZQogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzdWx0KCRyZXN1bHQsIEV4Y2VwdGlvbiAkZSA9IG51bGwpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9iYXNlNjRfcm90YXRlJykpOgpmdW5jdGlvbiBjbG9uZXJfYmFzZTY0X3JvdGF0ZSgkZW5jb2RlZCkgewogICAgJGVuY29kZSAgPSAnXVtBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsve30nOwogICAgJHJldmVyc2UgPSBzdHJyZXYoJGVuY29kZSk7CiAgICByZXR1cm4gc3RydHIoJGVuY29kZWQsICRlbmNvZGUsICRyZXZlcnNlKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfbGFzdF9lcnJvcl9mb3InKSk6CmZ1bmN0aW9uIGNsb25lcl9sYXN0X2Vycm9yX2ZvcigkZm5OYW1lKQp7CiAgICAkZXJyb3IgPSBlcnJvcl9nZXRfbGFzdCgpOwogICAgaWYgKCFpc19hcnJheSgkZXJyb3IpIHx8ICFpc3NldCgkZXJyb3JbJ21lc3NhZ2UnXSkgfHwgIWlzX3N0cmluZygkZXJyb3JbJ21lc3NhZ2UnXSkpIHsKICAgICAgICByZXR1cm4gJGZuTmFtZS4nKCk6IHVua25vd24gZXJyb3InOwogICAgfQogICAgJG1lc3NhZ2UgPSAkZXJyb3JbJ21lc3NhZ2UnXTsKICAgIGlmIChzdHJuY21wKCRtZXNzYWdlLCAkZm5OYW1lLicoJywgc3RybGVuKCRmbk5hbWUpICsgMSkpIHsKICAgICAgICAvLyBNZXNzYWdlIG5vdCBwcmVmaXhlZCB3aXRoICRmbk5hbWUuCiAgICAgICAgcmV0dXJuICRmbk5hbWUuJygpOiB1bmtub3duIGVycm9yJzsKICAgIH0KICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2Vycm9yX2NsZWFyX2xhc3QnKSkgewogICAgICAgIGVycm9yX2NsZWFyX2xhc3QoKTsKICAgIH0KICAgIHJldHVybiAkbWVzc2FnZTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfanNvbl9lbmNvZGUnKSk6CmZ1bmN0aW9uIGNsb25lcl9qc29uX2VuY29kZSgkdmFsdWUpCnsKICAgICRkYXRhID0ganNvbl9lbmNvZGUoJHZhbHVlKTsKICAgIGlmICgkZGF0YSA9PT0gZmFsc2UpIHsKICAgICAgICAkanNvbkVyciA9IGNsb25lcl9sYXN0X2Vycm9yX2ZvcignanNvbl9lbmNvZGUnKTsKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdqc29uX2xhc3RfZXJyb3InKSkgewogICAgICAgICAgICAkanNvbkVyciA9IHNwcmludGYoJ2NvZGUgJWQnLCBqc29uX2xhc3RfZXJyb3IoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2pzb25fbGFzdF9lcnJvcl9tc2cnKSkgewogICAgICAgICAgICAkanNvbkVyciA9IGpzb25fbGFzdF9lcnJvcl9tc2coKTsKICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCdqc29uX2VuY29kZSAlcyBlcnJvcjogJXMnLCB2YXJfZXhwb3J0KCR2YWx1ZSwgdHJ1ZSksICRqc29uRXJyKSk7CiAgICB9CiAgICByZXR1cm4gJGRhdGE7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2V4Y2VwdGlvbl90b19yZXN1bHQnKSk6CmZ1bmN0aW9uIGNsb25lcl9leGNlcHRpb25fdG9fcmVzdWx0KEV4Y2VwdGlvbiAkZSkKewogICAgJGNvbnRleHQgPSBudWxsOwogICAgZm9yZWFjaCAoZ2V0X29iamVjdF92YXJzKCRlKSBhcyAka2V5ID0+ICR2YWwpIHsKICAgICAgICBpZiAoIWlzX3NjYWxhcigkdmFsKSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCRjb250ZXh0ID09PSBudWxsKSB7CiAgICAgICAgICAgICRjb250ZXh0ID0gYXJyYXkoKTsKICAgICAgICB9CiAgICAgICAgJGNvbnRleHRbJGtleV0gPSAoc3RyaW5nKSR2YWw7CiAgICB9CiAgICAkZXJyb3JDb2RlID0gJGludGVybmFsRXJyb3IgPSAnJzsKICAgIGlmICgkZSBpbnN0YW5jZW9mIENsb25lckV4Y2VwdGlvbikgewogICAgICAgICRlcnJvckNvZGUgICAgID0gJGUtPmdldEVycm9yQ29kZSgpOwogICAgICAgICRpbnRlcm5hbEVycm9yID0gJGUtPmdldEludGVybmFsRXJyb3IoKTsKICAgIH0KICAgIHJldHVybiBhcnJheSgKICAgICAgICAnZXJyb3InICAgICAgICAgPT4gJGVycm9yQ29kZSwKICAgICAgICAnbWVzc2FnZScgICAgICAgPT4gJGUtPmdldE1lc3NhZ2UoKSwKICAgICAgICAnaW50ZXJuYWxFcnJvcicgPT4gJGludGVybmFsRXJyb3IsCiAgICAgICAgJ2ZpbGUnICAgICAgICAgID0+ICRlLT5nZXRGaWxlKCksCiAgICAgICAgJ2xpbmUnICAgICAgICAgID0+ICRlLT5nZXRMaW5lKCksCiAgICAgICAgJ2NvbnRleHQnICAgICAgID0+ICRjb250ZXh0LAogICAgKTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJzdGFuZGFyZHN0cmVhbScsIGZhbHNlKSk6CmNsYXNzIENsb25lclN0YW5kYXJkU3RyZWFtIGltcGxlbWVudHMgQ2xvbmVyU3RyZWFtCnsKICAgIHByaXZhdGUgJHJlcXVlc3RJRCA9ICcnOwogICAgcHJpdmF0ZSAkc3RyZWFtSW5pdGlhdGVkOwogICAgcHJpdmF0ZSAkb2JGbHVzaDsKICAgIHByaXZhdGUgJGJ1ZmZlcmVkID0gMDsKICAgIHByaXZhdGUgJGJ1ZmZlckxpbWl0ID0gNDA5NjsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJlcXVlc3RJRAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHJlcXVlc3RJRCkKICAgIHsKICAgICAgICAkdGhpcy0+cmVxdWVzdElEID0gJHJlcXVlc3RJRDsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIGluaXQoKQogICAgewogICAgICAgIGlmICgkdGhpcy0+c3RyZWFtSW5pdGlhdGVkKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnN0cmVhbUluaXRpYXRlZCA9IHRydWU7CiAgICAgICAgQGluaV9zZXQoJ3psaWIub3V0cHV0X2NvbXByZXNzaW9uJywgMCk7CiAgICAgICAgQGluaV9zZXQoJ2ltcGxpY2l0X2ZsdXNoJywgMCk7CiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnYXBhY2hlX3NldGVudicpKSB7CiAgICAgICAgICAgIEBhcGFjaGVfc2V0ZW52KCduby1nemlwJywgMSk7CiAgICAgICAgfQogICAgICAgIGlmICghaGVhZGVyc19zZW50KCkpIHsKICAgICAgICAgICAgLy8gZGlzYWJsZSBuZ2lueCBmYXN0LWNnaS9wcm94eSBidWZmZXJpbmcKICAgICAgICAgICAgQGhlYWRlcignWC1BY2NlbC1CdWZmZXJpbmc6IG5vJyk7CiAgICAgICAgICAgIC8vIGRpc2FibGUgYXV0by1nemlwIGVuY29kaW5nIGFuZCBzdWNoCiAgICAgICAgICAgIEBoZWFkZXIoJ0NvbnRlbnQtRW5jb2Rpbmc6IG5vbmUnKTsKICAgICAgICB9CiAgICAgICAgLy8gY2xlYXIgYWxsIG91dHB1dCBidWZmZXJzIGV4Y2VwdCBvbmUKICAgICAgICAkYnVmZmVyQ291bnQgPSBjb3VudChvYl9saXN0X2hhbmRsZXJzKCkpOwogICAgICAgIHdoaWxlICgkYnVmZmVyQ291bnQgPiAxKSB7CiAgICAgICAgICAgIGlmICghQG9iX2VuZF9jbGVhbigpKSB7CiAgICAgICAgICAgICAgICAvLyBub24tcmVtb3ZhYmxlIGJ1ZmZlcgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLS0kYnVmZmVyQ291bnQ7CiAgICAgICAgfQogICAgICAgIGlmICgkYnVmZmVyQ291bnQgPT09IDApIHsKICAgICAgICAgICAgLy8gaW5pdGlhdGUgbmV3IGNsZWFuIGJ1ZmZlcgogICAgICAgICAgICAkdGhpcy0+b2JGbHVzaCA9IEBvYl9zdGFydCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIHJlc2V0IGV4aXN0aW5nIG5vbi1yZW1vdmFibGUgYnVmZmVyIGNvbnRlbnQKICAgICAgICAgICAgJHRoaXMtPm9iRmx1c2ggPSB0cnVlOwogICAgICAgICAgICBAb2JfY2xlYW4oKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBmbHVzaCgkZm9yY2UgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoKCR0aGlzLT5idWZmZXJlZCA8ICR0aGlzLT5idWZmZXJMaW1pdCkgJiYgISRmb3JjZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+b2JGbHVzaCkgewogICAgICAgICAgICBAb2JfZmx1c2goKTsKICAgICAgICB9CiAgICAgICAgQGZsdXNoKCk7CiAgICAgICAgJHRoaXMtPmJ1ZmZlcmVkID0gMDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gd3JpdGUoJGRhdGEpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXQoKTsKICAgICAgICAkbGluZSA9ICJcbiIuY2xvbmVyX2Jhc2U2NF9yb3RhdGUoJHRoaXMtPnJlcXVlc3RJRC4nLCcuYmFzZTY0X2VuY29kZSgkZGF0YSkpLiJcbiI7CiAgICAgICAgZWNobyAkbGluZTsKICAgICAgICAkdGhpcy0+YnVmZmVyZWQgKz0gc3RybGVuKCRsaW5lKTsKICAgICAgICAkdGhpcy0+Zmx1c2goKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcHJvZ3Jlc3MoJG1lc3NhZ2UpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXQoKTsKICAgICAgICAkbGluZSA9ICJcbiIuY2xvbmVyX2Jhc2U2NF9yb3RhdGUoJHRoaXMtPnJlcXVlc3RJRC4nOycuY2xvbmVyX2pzb25fZW5jb2RlKCRtZXNzYWdlKSkuIlxuIjsKICAgICAgICBlY2hvICRsaW5lOwogICAgICAgICR0aGlzLT5idWZmZXJlZCArPSBzdHJsZW4oJGxpbmUpOwogICAgICAgICR0aGlzLT5mbHVzaCh0cnVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVzdWx0KCRyZXN1bHQsIEV4Y2VwdGlvbiAkZSA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmluaXQoKTsKICAgICAgICAkdHlwZSAgID0gJy4nOwogICAgICAgICRlbmNvZGUgPSAkcmVzdWx0OwogICAgICAgIGlmICgkZSAhPT0gbnVsbCkgewogICAgICAgICAgICAkdHlwZSAgID0gJyEnOwogICAgICAgICAgICAkZW5jb2RlID0gY2xvbmVyX2V4Y2VwdGlvbl90b19yZXN1bHQoJGUpOwogICAgICAgIH0KICAgICAgICAkbGluZSA9ICJcbiIuY2xvbmVyX2Jhc2U2NF9yb3RhdGUoJHRoaXMtPnJlcXVlc3RJRC4kdHlwZS5jbG9uZXJfanNvbl9lbmNvZGUoJGVuY29kZSkpLiJcbiI7CiAgICAgICAgZWNobyAkbGluZTsKICAgICAgICAkdGhpcy0+YnVmZmVyZWQgKz0gc3RybGVuKCRsaW5lKTsKICAgICAgICAkdGhpcy0+Zmx1c2godHJ1ZSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3N0YW5kYXJkX3N0cmVhbScpKToKZnVuY3Rpb24gY2xvbmVyX3N0YW5kYXJkX3N0cmVhbSgkcmVxdWVzdElEKQp7CiAgICBzdGF0aWMgJHN0cmVhbXMgPSBhcnJheSgpOwogICAgaWYgKGlzc2V0KCRzdHJlYW1zWyRyZXF1ZXN0SURdKSkgewogICAgICAgIHJldHVybiAkc3RyZWFtc1skcmVxdWVzdElEXTsKICAgIH0KICAgICRzdHJlYW0gICAgICAgICAgICAgID0gbmV3IENsb25lclN0YW5kYXJkU3RyZWFtKCRyZXF1ZXN0SUQpOwogICAgJHN0cmVhbXNbJHJlcXVlc3RJRF0gPSAkc3RyZWFtOwogICAgcmV0dXJuICRzdHJlYW07Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3NlbmRfZXJyb3JfcmVzcG9uc2UnKSk6CmZ1bmN0aW9uIGNsb25lcl9zZW5kX2Vycm9yX3Jlc3BvbnNlKCRpZCwgRXhjZXB0aW9uICRlKSB7CiAgICBjbG9uZXJfc3RhbmRhcmRfc3RyZWFtKCRpZCktPnJlc3VsdChudWxsLCAkZSk7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyZXJyb3JoYW5kbGVyJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyRXJyb3JIYW5kbGVyCnsKICAgIHByaXZhdGUgJGxvZ0ZpbGU7CiAgICBwcml2YXRlICRyZXNlcnZlZE1lbW9yeTsKICAgIHByaXZhdGUgc3RhdGljICRsYXN0RXJyb3I7CiAgICBwcml2YXRlICRyZXF1ZXN0SUQ7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRsb2dGaWxlKSB7CiAgICAgICAgJHRoaXMtPmxvZ0ZpbGUgPSAkbG9nRmlsZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmVxdWVzdElEKCRyZXF1ZXN0SUQpIHsKICAgICAgICAkdGhpcy0+cmVxdWVzdElEID0gJHJlcXVlc3RJRDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVnaXN0ZXIoKSB7CiAgICAgICAgJHRoaXMtPnJlc2VydmVkTWVtb3J5ID0gc3RyX3JlcGVhdCgneCcsIDEwMjQwKTsKICAgICAgICByZWdpc3Rlcl9zaHV0ZG93bl9mdW5jdGlvbihhcnJheSgkdGhpcywgJ2hhbmRsZUZhdGFsRXJyb3InKSk7CiAgICAgICAgc2V0X2Vycm9yX2hhbmRsZXIoYXJyYXkoJHRoaXMsICdoYW5kbGVFcnJvcicpKTsKICAgICAgICBzZXRfZXhjZXB0aW9uX2hhbmRsZXIoYXJyYXkoJHRoaXMsICdoYW5kbGVFeGNlcHRpb24nKSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlZnJlc2goKSB7CiAgICAgICAgc2V0X2Vycm9yX2hhbmRsZXIoYXJyYXkoJHRoaXMsICdoYW5kbGVFcnJvcicpKTsKICAgICAgICBzZXRfZXhjZXB0aW9uX2hhbmRsZXIoYXJyYXkoJHRoaXMsICdoYW5kbGVFeGNlcHRpb24nKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbGFzdEVycm9yKCkgewogICAgICAgIHJldHVybiBzZWxmOjokbGFzdEVycm9yOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBoYW5kbGVFcnJvcigkdHlwZSwgJG1lc3NhZ2UsICRmaWxlLCAkbGluZSkgewogICAgICAgIHNlbGY6OiRsYXN0RXJyb3IgPSBjb21wYWN0KCdtZXNzYWdlJywgJ3R5cGUnLCAnZmlsZScsICdsaW5lJyk7CiAgICAgICAgaWYgKGVycm9yX3JlcG9ydGluZygpID09PSAwKSB7CiAgICAgICAgICAgIC8vIE11dGVkIGVycm9yLgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmICghc3RybGVuKCRtZXNzYWdlKSkgewogICAgICAgICAgICAkbWVzc2FnZSA9ICdlbXB0eSBlcnJvciBtZXNzYWdlJzsKICAgICAgICB9CiAgICAgICAgJGFyZ3MgPSBmdW5jX2dldF9hcmdzKCk7CiAgICAgICAgaWYgKGNvdW50KCRhcmdzKSA+PSA2ICYmICRhcmdzWzVdICE9PSBudWxsICYmICR0eXBlICYgRV9FUlJPUikgewogICAgICAgICAgICAvLyA2dGggYXJndW1lbnQgaXMgYmFja3RyYWNlLgogICAgICAgICAgICAvLyBFX0VSUk9SIGZhdGFsIGVycm9ycyBhcmUgdHJpZ2dlcmVkIG9uIEhIVk0gd2hlbgogICAgICAgICAgICAvLyBoaHZtLmVycm9yX2hhbmRsaW5nLmNhbGxfdXNlcl9oYW5kbGVyX29uX2ZhdGFscz0xCiAgICAgICAgICAgIC8vIHdoaWNoIGlzIHRoZSB3YXkgdG8gZ2V0IHRoZWlyIGJhY2t0cmFjZS4KICAgICAgICAgICAgJHRoaXMtPmhhbmRsZUZhdGFsRXJyb3IoY29tcGFjdCgndHlwZScsICdtZXNzYWdlJywgJ2ZpbGUnLCAnbGluZScpKTsKCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgbGlzdCgkZmlsZSwgJGxpbmUpID0gc2VsZjo6Z2V0RmlsZUxpbmUoJGZpbGUsICRsaW5lKTsKICAgICAgICAkdGhpcy0+bG9nKHNwcmludGYoIiVzOiAlcyBpbiAlcyBvbiBsaW5lICVkIiwgc2VsZjo6Y29kZVRvU3RyaW5nKCR0eXBlKSwgJG1lc3NhZ2UsICRmaWxlLCAkbGluZSkpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGdldEZpbGVMaW5lKCRmaWxlLCAkbGluZSkgewogICAgICAgIGlmIChfX0ZJTEVfXyAhPT0gJGZpbGUpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRmaWxlLCAkbGluZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ19fYnVuZGxlcl9zb3VyY2VtYXAnKSkgewogICAgICAgICAgICAkZ2xvYmFsT2Zmc2V0ID0gMDsKICAgICAgICAgICAgZm9yZWFjaCAoX19idW5kbGVyX3NvdXJjZW1hcCgpIGFzICRvZmZzZXRQYXRoKSB7CiAgICAgICAgICAgICAgICBsaXN0KCRvZmZzZXQsICRwYXRoKSA9ICRvZmZzZXRQYXRoOwogICAgICAgICAgICAgICAgaWYgKCRsaW5lIDw9ICRvZmZzZXQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXkoJHBhdGgsICRsaW5lIC0gJGdsb2JhbE9mZnNldCArIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGdsb2JhbE9mZnNldCA9ICRvZmZzZXQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFycmF5KCRmaWxlLCAkbGluZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gRXhjZXB0aW9ufEVycm9yICRlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBoYW5kbGVFeGNlcHRpb24oJGUpIHsKICAgICAgICBsaXN0KCRmaWxlLCAkbGluZSkgPSBzZWxmOjpnZXRGaWxlTGluZSgkZS0+Z2V0RmlsZSgpLCAkZS0+Z2V0TGluZSgpKTsKICAgICAgICAkdGhpcy0+bG9nKHNwcmludGYoJ1VuaGFuZGxlZCBleGNlcHRpb24gaW4gZmlsZSAlcyBsaW5lICVkOiAlcycsICRmaWxlLCAkbGluZSwgJGUtPmdldE1lc3NhZ2UoKSkpOwogICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIEVycm9yKSB7CiAgICAgICAgICAgICRlID0gbmV3IENsb25lckV4Y2VwdGlvbigkZS0+Z2V0TWVzc2FnZSgpLCAnZmF0YWxfZXJyb3InLCBzcHJpbnRmKCclcyBpbiBmaWxlICVzIG9uIGxpbmUgJWQnLCAkZS0+Z2V0TWVzc2FnZSgpLCAkZS0+Z2V0RmlsZSgpLCAkZS0+Z2V0TGluZSgpKSk7CiAgICAgICAgfQogICAgICAgIGNsb25lcl9zZW5kX2Vycm9yX3Jlc3BvbnNlKCR0aGlzLT5yZXF1ZXN0SUQsICRlKTsKICAgICAgICBleGl0OwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBoYW5kbGVGYXRhbEVycm9yKGFycmF5ICRlcnJvciA9IG51bGwpIHsKICAgICAgICAkdGhpcy0+cmVzZXJ2ZWRNZW1vcnkgPSBudWxsOwogICAgICAgIGlmICgkZXJyb3IgPT09IG51bGwpIHsKICAgICAgICAgICAgLy8gU2luY2UgZGVmYXVsdCBQSFAgaW1wbGVtZW50YXRpb24gZG9lc24ndCBjYWxsIGVycm9yIGhhbmRsZXJzIG9uIGZhdGFsIGVycm9ycywgdGhlIHNlbGY6OiRsYXN0RXJyb3IKICAgICAgICAgICAgLy8gdmFyaWFibGUgd29uJ3QgYmUgdXBkYXRlZC4gVGhhdCdzIHdoeSB0aGlzIGlzIHRoZSBvbmx5IHBsYWNlIHdoZXJlIHdlIGNhbGwgZXJyb3JfZ2V0X2xhc3QoKSBkaXJlY3RseS4KICAgICAgICAgICAgJGVycm9yID0gZXJyb3JfZ2V0X2xhc3QoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCEkZXJyb3IpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAoIWluX2FycmF5KCRlcnJvclsndHlwZSddLCBhcnJheShFX1BBUlNFLCBFX0VSUk9SLCBFX0NPUkVfRVJST1IsIEVfQ09NUElMRV9FUlJPUiwgRV9SRUNPVkVSQUJMRV9FUlJPUikpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgbGlzdCgkZmlsZSwgJGxpbmUpID0gc2VsZjo6Z2V0RmlsZUxpbmUoJGVycm9yWydmaWxlJ10sICRlcnJvclsnbGluZSddKTsKICAgICAgICAkbWVzc2FnZSA9IHNwcmludGYoIiVzOiAlcyBpbiAlcyBvbiBsaW5lICVkIiwgc2VsZjo6Y29kZVRvU3RyaW5nKCRlcnJvclsndHlwZSddKSwgJGVycm9yWydtZXNzYWdlJ10sICRmaWxlLCAkbGluZSk7CiAgICAgICAgJHRoaXMtPmxvZygkbWVzc2FnZSk7CiAgICAgICAgY2xvbmVyX3NlbmRfZXJyb3JfcmVzcG9uc2UoJHRoaXMtPnJlcXVlc3RJRCwgbmV3IENsb25lckV4Y2VwdGlvbigkbWVzc2FnZSwgJ2ZhdGFsX2Vycm9yJywgIiRmaWxlOiRsaW5lIikpOwogICAgICAgIGV4aXQ7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBsb2coJG1lc3NhZ2UpIHsKICAgICAgICBpZiAoKCRmcCA9IGZvcGVuKCR0aGlzLT5sb2dGaWxlLCAnYScpKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAoZmxvY2soJGZwLCBMT0NLX0VYKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgZmNsb3NlKCRmcCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKGZ3cml0ZSgkZnAsIHNwcmludGYoIlslc10gJXNcbiIsIGRhdGUoIlktbS1kIEg6aTpzIiksICRtZXNzYWdlKSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIGZjbG9zZSgkZnApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGZjbG9zZSgkZnApOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZ1bmN0aW9uIGNvZGVUb1N0cmluZygkY29kZSkgewogICAgICAgIHN3aXRjaCAoJGNvZGUpIHsKICAgICAgICAgICAgY2FzZSBFX0VSUk9SOgogICAgICAgICAgICAgICAgcmV0dXJuICdFX0VSUk9SJzsKICAgICAgICAgICAgY2FzZSBFX1dBUk5JTkc6CiAgICAgICAgICAgICAgICByZXR1cm4gJ0VfV0FSTklORyc7CiAgICAgICAgICAgIGNhc2UgRV9QQVJTRToKICAgICAgICAgICAgICAgIHJldHVybiAnRV9QQVJTRSc7CiAgICAgICAgICAgIGNhc2UgRV9OT1RJQ0U6CiAgICAgICAgICAgICAgICByZXR1cm4gJ0VfTk9USUNFJzsKICAgICAgICAgICAgY2FzZSBFX0NPUkVfRVJST1I6CiAgICAgICAgICAgICAgICByZXR1cm4gJ0VfQ09SRV9FUlJPUic7CiAgICAgICAgICAgIGNhc2UgRV9DT1JFX1dBUk5JTkc6CiAgICAgICAgICAgICAgICByZXR1cm4gJ0VfQ09SRV9XQVJOSU5HJzsKICAgICAgICAgICAgY2FzZSBFX0NPTVBJTEVfRVJST1I6CiAgICAgICAgICAgICAgICByZXR1cm4gJ0VfQ09NUElMRV9FUlJPUic7CiAgICAgICAgICAgIGNhc2UgRV9DT01QSUxFX1dBUk5JTkc6CiAgICAgICAgICAgICAgICByZXR1cm4gJ0VfQ09NUElMRV9XQVJOSU5HJzsKICAgICAgICAgICAgY2FzZSBFX1VTRVJfRVJST1I6CiAgICAgICAgICAgICAgICByZXR1cm4gJ0VfVVNFUl9FUlJPUic7CiAgICAgICAgICAgIGNhc2UgRV9VU0VSX1dBUk5JTkc6CiAgICAgICAgICAgICAgICByZXR1cm4gJ0VfVVNFUl9XQVJOSU5HJzsKICAgICAgICAgICAgY2FzZSBFX1VTRVJfTk9USUNFOgogICAgICAgICAgICAgICAgcmV0dXJuICdFX1VTRVJfTk9USUNFJzsKICAgICAgICAgICAgY2FzZSBFX1NUUklDVDoKICAgICAgICAgICAgICAgIHJldHVybiAnRV9TVFJJQ1QnOwogICAgICAgICAgICBjYXNlIEVfUkVDT1ZFUkFCTEVfRVJST1I6CiAgICAgICAgICAgICAgICByZXR1cm4gJ0VfUkVDT1ZFUkFCTEVfRVJST1InOwogICAgICAgICAgICBjYXNlIEVfREVQUkVDQVRFRDoKICAgICAgICAgICAgICAgIHJldHVybiAnRV9ERVBSRUNBVEVEJzsKICAgICAgICAgICAgY2FzZSBFX1VTRVJfREVQUkVDQVRFRDoKICAgICAgICAgICAgICAgIHJldHVybiAnRV9VU0VSX0RFUFJFQ0FURUQnOwogICAgICAgIH0KICAgICAgICBpZiAoZGVmaW5lZCgnUEhQX1ZFUlNJT05fSUQnKSAmJiBQSFBfVkVSU0lPTl9JRCA+PSA1MDMwMCkgewogICAgICAgICAgICBzd2l0Y2ggKCRjb2RlKSB7CiAgICAgICAgICAgICAgICBjYXNlIEVfREVQUkVDQVRFRDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ0VfREVQUkVDQVRFRCc7CiAgICAgICAgICAgICAgICBjYXNlIEVfVVNFUl9ERVBSRUNBVEVEOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAnRV9VU0VSX0RFUFJFQ0FURUQnOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAnRV9VTktOT1dOJzsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfcGFnZV9pbmRleCcpKToKZnVuY3Rpb24gY2xvbmVyX3BhZ2VfaW5kZXgoKSB7Cj8+PCFkb2N0eXBlIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIKICAgICAgICAgIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgdXNlci1zY2FsYWJsZT1ubywgaW5pdGlhbC1zY2FsZT0xLjAsIG1heGltdW0tc2NhbGU9MS4wLCBtaW5pbXVtLXNjYWxlPTEuMCI+CiAgICA8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRlbnQ9ImllPWVkZ2UiPgogICAgPHRpdGxlPlN5bmM8L3RpdGxlPgogICAgPHN0eWxlPgogICAgICAgIGJvZHkgewogICAgICAgICAgICBjb2xvcjogIzMzMzsKICAgICAgICAgICAgbWFyZ2luOiAwOwogICAgICAgICAgICBoZWlnaHQ6IDEwMHZoOwogICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMkM0NTRDOwogICAgICAgICAgICBmb250LWZhbWlseTogIk9wZW4gU2FucyIsICJIZWx2ZXRpY2EgTmV1ZSIsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWY7CiAgICAgICAgfQoKICAgICAgICAubG9nbyB7CiAgICAgICAgICAgIGhlaWdodDogMTUwcHg7CiAgICAgICAgICAgIGJhY2tncm91bmQ6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlkWFJtTFRnaVB6NEtQQ0V0TFNCSFpXNWxjbUYwWldRZ1lua2dTV052VFc5dmJpNXBieUF0TFQ0S1BDRkVUME5VV1ZCRklITjJaeUJRVlVKTVNVTWdJaTB2TDFjelF5OHZSRlJFSUZOV1J5QXhMakV2TDBWT0lpQWlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZSM0poY0docFkzTXZVMVpITHpFdU1TOUVWRVF2YzNabk1URXVaSFJrSWo0S1BITjJaeUIyWlhKemFXOXVQU0l4TGpFaUlIaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhkcFpIUm9QU0l6TWlJZ2FHVnBaMmgwUFNJek1pSWdkbWxsZDBKdmVEMGlNQ0F3SURNeUlETXlJajRLUEhCaGRHZ2dabWxzYkQwaUkyWm1aaUlnWkQwaVRURTJMakEyTXkwd0xqQXdOV010T0M0NE16WWdNQzB4TmlBM0xqRTJOQzB4TmlBeE5TNDVPVGtnTUNBNExqZ3pPU0EzTGpFMk5DQXhOaTR3TURFZ01UWWdNVFl1TURBeElEZ3VPRE01SURBZ01UWXROeTR4TmpNZ01UWXRNVFl1TURBeElEQXRPQzQ0TXpVdE55NHhOakV0TVRVdU9UazVMVEUyTFRFMUxqazVPWHBOTVRZdU1EWXpJRE13TGpVeU1XTXRPQzR3TWpNZ01DMHhOQzQxTWpjdE5pNDFNRFV0TVRRdU5USTNMVEUwTGpVeU9DQXdMVGd1TURJd0lEWXVOVEEwTFRFMExqVXlOU0F4TkM0MU1qY3RNVFF1TlRJMWN6RTBMalV5TlNBMkxqVXdOU0F4TkM0MU1qVWdNVFF1TlRJMVl6QWdPQzR3TWpNdE5pNDFNRE1nTVRRdU5USTRMVEUwTGpVeU5TQXhOQzQxTWpoNklqNDhMM0JoZEdnK0NqeHdZWFJvSUdacGJHdzlJaU5tWm1ZaUlHUTlJazB5Tmk0Mk5USWdOeTQ1TkROc0xUWXVNamc1SURZdU56UTFMVE11TVRJMUxUVXVORE15TFRRdU9EVTJJRFV1T0RjMkxUSXVOVEV6TFRNdU9EQTNMVFl1TWpReklEa3VNRGd6WXpFdU9EWXhJRFV1TURRNUlEWXVOekUzSURndU5qVXlJREV5TGpReE15QTRMalkxTWlBM0xqTXdOU0F3SURFekxqSXlOQzAxTGpreU1TQXhNeTR5TWpRdE1UTXVNakkzSURBdE1pNDVOVGN0TUM0NU56RXROUzQyT0RndE1pNDJNVEV0Tnk0NE9URjZJajQ4TDNCaGRHZytDand2YzNablBnbz0pIG5vLXJlcGVhdCBjZW50ZXIgY2VudGVyOwogICAgICAgICAgICBiYWNrZ3JvdW5kLXNpemU6IDEwMHB4IDEwMHB4OwogICAgICAgIH0KCiAgICAgICAgLmNvbnRlbnQgewogICAgICAgICAgICBsaW5lLWhlaWdodDogMS40OwogICAgICAgICAgICBiYWNrZ3JvdW5kOiAjZmZmOwogICAgICAgICAgICBib3JkZXItcmFkaXVzOiAxNXB4OwogICAgICAgICAgICBwYWRkaW5nOiAxNXB4OwogICAgICAgICAgICBtYXgtd2lkdGg6IDY1MHB4OwogICAgICAgICAgICBtYXJnaW46IDAgYXV0bzsKICAgICAgICB9CgogICAgICAgICNmZWVkYmFjayB7CiAgICAgICAgICAgIGZvbnQtZmFtaWx5OiBNb25hY28sIENvbnNvbGFzLCAiQW5kYWxlIE1vbm8iLCAiRGVqYVZ1IFNhbnMgTW9ubyIsIG1vbm9zcGFjZTsKICAgICAgICAgICAgd29yZC13cmFwOiBicmVhay13b3JkOwogICAgICAgICAgICBtYXgtaGVpZ2h0OiAyMDBweDsKICAgICAgICAgICAgY29sb3I6ICM2NjY7CiAgICAgICAgICAgIG92ZXJmbG93LXk6IGF1dG87CiAgICAgICAgfQogICAgPC9zdHlsZT4KPC9oZWFkPgo8Ym9keT4KCjxkaXYgY2xhc3M9ImxvZ28iPjwvZGl2PgoKPGRpdiBjbGFzcz0iY29udGVudCI+CiAgICA8cD4KICAgICAgICBUaGlzIHdpbmRvdyBjbG9zZXMgYXV0b21hdGljYWxseSB3aGVuIHRoZSBzeW5jaHJvbml6YXRpb24gZmluaXNoZXMuIFBsZWFzZSwgZG8gbm90IGNsb3NlIGl0LgogICAgPC9wPgogICAgPHA+CiAgICAgICAgRGVidWcgaW5mbzoKICAgIDwvcD4KICAgIDxkaXYgaWQ9ImZlZWRiYWNrIj48L2Rpdj4KPC9kaXY+Cgo8c2NyaXB0PgogICAgLyoqCiAgICAgKiBDcmVhdGVzIHJlc3BvbnNlIGZvciBYTUxIdHRwUmVxdWVzdC4gU2FmZSB0byBjYWxsIG9ubHkgZnJvbSBvbmVycm9yIGFuZCBvbmxvYWQsIHdoZW4gdGhlIHJlcXVlc3QgaXMgYWxyZWFkeSBmaW5pc2hlZC4KICAgICAqCiAgICAgKiBAcGFyYW0ge1hNTEh0dHBSZXF1ZXN0fSB4aHIKICAgICAqIEByZXR1cm4ge3tzdGF0dXM6IG51bWJlciwgcmVzcG9uc2U6IHN0cmluZ3xudWxsLCBoZWFkZXJzOiBzdHJpbmd8bnVsbH19CiAgICAgKi8KICAgIGZ1bmN0aW9uIGNyZWF0ZVhIUlJlc3VsdCh4aHIpIHsKICAgICAgICByZXR1cm4gewogICAgICAgICAgICBzdGF0dXM6IHhoci5zdGF0dXMsCiAgICAgICAgICAgIHJlc3BvbnNlOiB4aHIucmVzcG9uc2VUZXh0LAogICAgICAgICAgICBoZWFkZXJzOiB4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkKICAgICAgICB9OwogICAgfQoKICAgIGZ1bmN0aW9uIHJlcXVlc3QobWV0aG9kLCB1cmwsIGNhbGxiYWNrLCBwYXlsb2FkKSB7CiAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOwogICAgICAgIHhoci5vcGVuKG1ldGhvZCwgdXJsKTsKICAgICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgICAgICAgICAgY2FsbGJhY2soZSwgY3JlYXRlWEhSUmVzdWx0KHhocikpCiAgICAgICAgfTsKICAgICAgICB4aHIub25sb2FkID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciByZXN1bHQgPSBjcmVhdGVYSFJSZXN1bHQoeGhyKTsKICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgIT09IDIwMCkgewogICAgICAgICAgICAgICAgY2FsbGJhY2sobmV3IEVycm9yKCJOb24tMjAwIHJlc3BvbnNlIHN0YXR1cyBjb2RlIiksIHJlc3VsdCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVzdWx0KTsKICAgICAgICB9OwogICAgICAgIHhoci5zZW5kKHBheWxvYWQpOwogICAgICAgIHJldHVybiB4aHIuYWJvcnQ7CiAgICB9CgogICAgZnVuY3Rpb24gRGl2RmVlZGJhY2soY29udGFpbmVyKSB7CiAgICAgICAgdGhpcy5mZWVkYmFja0NvbnRhaW5lciA9IGNvbnRhaW5lcjsKICAgICAgICB0aGlzLmxhc3RGZWVkYmFjayA9ICcnOwogICAgICAgIHRoaXMubGFzdEZlZWRiYWNrTGVuID0gMDsKICAgICAgICB0aGlzLmxhc3RGZWVkYmFja0NvdW50ID0gMDsKICAgICAgICB0aGlzLm1heEZlZWRiYWNrTGVuID0gMTAgPDwgMTA7CiAgICB9CgogICAgRGl2RmVlZGJhY2sucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbih0ZXh0KSB7CiAgICAgICAgdmFyIHByZXBlbmQgPSAnJywgY3V0ID0gMDsKICAgICAgICB2YXIgcHJlZml4ID0gJ1snICsgbmV3IERhdGUoKS50b0pTT04oKSArICddICc7CiAgICAgICAgaWYgKHRoaXMubGFzdEZlZWRiYWNrID09PSAnJykgewogICAgICAgICAgICBwcmVwZW5kID0gcHJlZml4ICsgdGV4dDsKICAgICAgICB9IGVsc2UgaWYgKHRoaXMubGFzdEZlZWRiYWNrID09PSB0ZXh0KSB7CiAgICAgICAgICAgIHRoaXMubGFzdEZlZWRiYWNrQ291bnQrKzsKICAgICAgICAgICAgY3V0ID0gdGhpcy5sYXN0RmVlZGJhY2tMZW47CiAgICAgICAgICAgIHByZXBlbmQgPSBwcmVmaXggKyB0ZXh0ICsgQXJyYXkodGhpcy5sYXN0RmVlZGJhY2tDb3VudCArIDEpLmpvaW4oJyAuJykgKyAiXG4iOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRoaXMubGFzdEZlZWRiYWNrQ291bnQgPSAxOwogICAgICAgICAgICBwcmVwZW5kID0gcHJlZml4ICsgdGV4dCArICJcbiI7CiAgICAgICAgfQogICAgICAgIHRoaXMubGFzdEZlZWRiYWNrID0gdGV4dDsKICAgICAgICB0aGlzLmxhc3RGZWVkYmFja0xlbiA9IHByZXBlbmQubGVuZ3RoOwogICAgICAgIHRoaXMuZmVlZGJhY2tDb250YWluZXIuaW5uZXJUZXh0ID0gcHJlcGVuZCArIHRoaXMuZmVlZGJhY2tDb250YWluZXIuaW5uZXJUZXh0LnN1YnN0cihjdXQsIE1hdGgubWF4KHRoaXMubWF4RmVlZGJhY2tMZW4gLSBwcmVwZW5kLmxlbmd0aCAtIGN1dCwgMCkpOwogICAgfTsKCiAgICB2YXIgZmVlZGJhY2sgPSBuZXcgRGl2RmVlZGJhY2soZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZlZWRiYWNrJykpOwoKICAgIC8qKgogICAgICogQHBhcmFtIHtudW1iZXJ9IGlkCiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBhYm9ydCBDb25uZWN0aW9uIGNhbmNlbGF0aW9uIGZ1bmN0aW9uLgogICAgICovCiAgICBmdW5jdGlvbiBSZW1vdGVDb25uKGlkLCBhYm9ydCkgewogICAgICAgIHRoaXMuaWQgPSBpZDsKICAgICAgICB0aGlzLmNsb3NlID0gYWJvcnQ7CiAgICAgICAgdGhpcy5jcmVhdGVkQXQgPSBuZXcgRGF0ZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHtBcnJheTxUPn0gYQogICAgICoKICAgICAqIEByZXR1cm4ge0FycmF5PFQ+fQogICAgICovCiAgICBBcnJheS5wcm90b3R5cGUuZGlmZiA9IGZ1bmN0aW9uKGEpIHsKICAgICAgICByZXR1cm4gdGhpcy5maWx0ZXIoZnVuY3Rpb24oaSkgewogICAgICAgICAgICByZXR1cm4gYS5pbmRleE9mKGkpID09PSAtMTsKICAgICAgICB9KTsKICAgIH07CgogICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZmluZCNQb2x5ZmlsbAogICAgaWYgKCFBcnJheS5wcm90b3R5cGUuZmluZCkgewogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBcnJheS5wcm90b3R5cGUsICdmaW5kJywgewogICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24ocHJlZGljYXRlKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignInRoaXMiIGlzIG51bGwgb3Igbm90IGRlZmluZWQnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBvID0gT2JqZWN0KHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIGxlbiA9IG8ubGVuZ3RoID4+PiAwOwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdwcmVkaWNhdGUgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgdGhpc0FyZyA9IGFyZ3VtZW50c1sxXTsKICAgICAgICAgICAgICAgIHZhciBrID0gMDsKICAgICAgICAgICAgICAgIHdoaWxlIChrIDwgbGVuKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGtWYWx1ZSA9IG9ba107CiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWRpY2F0ZS5jYWxsKHRoaXNBcmcsIGtWYWx1ZSwgaywgbykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtWYWx1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaysrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLAogICAgICAgICAgICB3cml0YWJsZTogdHJ1ZQogICAgICAgIH0pOwogICAgfQoKICAgIHZhciBlcnJvckNvdW50ZXIgPSAwOwoKICAgIGZ1bmN0aW9uIGZpbmlzaCgpIHsKICAgICAgICB3aW5kb3cuY2xvc2UoKTsKICAgIH0KCiAgICBmdW5jdGlvbiBjbGVhbnVwKCkgewogICAgICAgIHJlcXVlc3QoIkdFVCIsIGxvY2F0aW9uLnBhdGhuYW1lICsgIj9xPWNsZWFudXAiLCBmaW5pc2gpOwogICAgfQoKICAgIGZ1bmN0aW9uIG1haW4oKSB7CiAgICAgICAgdmFyIGhhdmVDb25ucyA9IFtdOwogICAgICAgIHZhciBwb2xsID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB1cmwgPSBsb2NhdGlvbi5wYXRobmFtZSArICI/cT1zdGF0ZV9wb2xsIjsKICAgICAgICAgICAgcmVxdWVzdCgiR0VUIiwgdXJsLCBwb2xsUmVzdWx0KQogICAgICAgIH07CiAgICAgICAgdmFyIHBvbGxSZXN1bHQgPSBmdW5jdGlvbihlLCByZXN1bHQpIHsKICAgICAgICAgICAgaWYgKGUpIHsKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0LnN0YXR1cyA9PT0gNDA0KSB7CiAgICAgICAgICAgICAgICAgICAgZmVlZGJhY2suc2VuZCgiQ2xvc2luZyB0aGlzIHdpbmRvdyIpOwogICAgICAgICAgICAgICAgICAgIGZpbmlzaCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZlZWRiYWNrLnNlbmQoIkVycm9yIHBvbGxpbmcgZW5kcG9pbnQ6ICIgKyBKU09OLnN0cmluZ2lmeShlKSArICI7IHJlc3VsdDogIiArIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qKiBAdmFyIHt7b2s6IGJvb2xlYW4sIGVycm9yOiBzdHJpbmcsIHN0YXRlOiB7aG9zdDogc3RyaW5nLCBoYXZlQ29ubnM6IEFycmF5PHN0cmluZz4sIHdhbnRDb25uczogQXJyYXk8c3RyaW5nPiwgY2FjaGVkOiBib29sZWFuLCBhZ2U6IG51bWJlcn0gfX0gcG9sbERhdGEgKi8KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHZhciBwb2xsRGF0YSA9IEpTT04ucGFyc2UocmVzdWx0LnJlc3BvbnNlKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgZmVlZGJhY2suc2VuZCgiUG9sbCBlcnJvcjogIiArIEpTT04uc3RyaW5naWZ5KGUpKTsKICAgICAgICAgICAgICAgIHNldFRpbWVvdXQocG9sbCwgMjAwMCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFwb2xsRGF0YS5vaykgewogICAgICAgICAgICAgICAgaWYgKHBvbGxEYXRhLmVycm9yID09PSAnbm90X2ZvdW5kJykgewogICAgICAgICAgICAgICAgICAgIGZlZWRiYWNrLnNlbmQoIlRhc2sgbm90IGZvdW5kIik7CiAgICAgICAgICAgICAgICAgICAgY2xlYW51cCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocG9sbERhdGEuZXJyb3IgPT09ICdkb25lJykgewogICAgICAgICAgICAgICAgICAgIGZlZWRiYWNrLnNlbmQoIlRhc2sgY29tcGxldGVkIik7CiAgICAgICAgICAgICAgICAgICAgY2xlYW51cCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBlcnJvckNvdW50ZXIrKzsKICAgICAgICAgICAgICAgIHZhciBtZXNzYWdlID0gcG9sbERhdGEuZXJyb3I7CiAgICAgICAgICAgICAgICBpZiAocG9sbERhdGEubWVzc2FnZSkgewogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgKz0gJzogJyArIHBvbGxEYXRhLm1lc3NhZ2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmZWVkYmFjay5zZW5kKG1lc3NhZ2UpOwogICAgICAgICAgICAgICAgaWYgKGVycm9yQ291bnRlciA8IDMwKSB7CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChwb2xsLCAyMDAwKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZlZWRiYWNrLnNlbmQoIkFib3J0aW5nIGFmdGVyIHRvbyBtYW55IHJldHJpZXMiKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlcnJvckNvdW50ZXIgPSAwOwogICAgICAgICAgICB2YXIgc3RhdGUgPSBwb2xsRGF0YS5zdGF0ZTsKICAgICAgICAgICAgdmFyIGNyZWF0ZUNvbm5zID0gc3RhdGUud2FudENvbm5zLmRpZmYoc3RhdGUuaGF2ZUNvbm5zKTsKICAgICAgICAgICAgdmFyIGNsb3NlQ29ubnMgPSBzdGF0ZS5oYXZlQ29ubnMuZGlmZihzdGF0ZS53YW50Q29ubnMpOwogICAgICAgICAgICBjcmVhdGVDb25ucy5tYXAoZnVuY3Rpb24oY29ubklEKSB7CiAgICAgICAgICAgICAgICBmZWVkYmFjay5zZW5kKCJPcGVuaW5nIGNvbm5lY3Rpb24gIiArIGNvbm5JRCk7CiAgICAgICAgICAgICAgICBzcGF3bihzdGF0ZS5ob3N0LCBjb25uSUQpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgY2xvc2VDb25ucy5tYXAoZnVuY3Rpb24oY29ubklEKSB7CiAgICAgICAgICAgICAgICB2YXIgY29ubiA9IGhhdmVDb25ucy5maW5kKGZ1bmN0aW9uKGNvbm4pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29ubi5pZCA9PT0gY29ubklEOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBpZiAoIWNvbm4pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmZWVkYmFjay5zZW5kKCJDbG9zaW5nIGNvbm5lY3Rpb24gIiArIGNvbm5JRCk7CiAgICAgICAgICAgICAgICBjb25uLmNsb3NlKCk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzZXRUaW1lb3V0KHBvbGwsIDMwMDApOwogICAgICAgIH07CiAgICAgICAgdmFyIHNwYXduID0gZnVuY3Rpb24oaG9zdCwgaWQpIHsKICAgICAgICAgICAgdmFyIHVybCA9IGxvY2F0aW9uLnBhdGhuYW1lICsgIj9xPWNvbm5lY3QmaG9zdD0iICsgZW5jb2RlVVJJQ29tcG9uZW50KGhvc3QpICsgIiZjb25uX2lkPSIgKyBlbmNvZGVVUklDb21wb25lbnQoaWQpOwogICAgICAgICAgICB2YXIgYWJvcnQgPSByZXF1ZXN0KCJHRVQiLCB1cmwsIGNvbm5DbG9zZWQpOwogICAgICAgICAgICB2YXIgY29ubiA9IG5ldyBSZW1vdGVDb25uKGlkLCBhYm9ydCk7CiAgICAgICAgICAgIGhhdmVDb25ucy5wdXNoKGNvbm4pOwogICAgICAgIH07CiAgICAgICAgdmFyIGNvbm5DbG9zZWQgPSBmdW5jdGlvbihlLCByZXN1bHQpIHsKICAgICAgICAgICAgaWYgKGUpIHsKICAgICAgICAgICAgICAgIGZlZWRiYWNrLnNlbmQoIkVycm9yIHNwYXduaW5nIGNvbm5lY3Rpb246ICIgKyBKU09OLnN0cmluZ2lmeShlKSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIC8qKiBAdmFyIHt7b2s6IGJvb2xlYW4sIGVycm9yOiBzdHJpbmd9fSBjb25uRGF0YSAqLwogICAgICAgICAgICAgICAgdmFyIGNvbm5EYXRhID0gSlNPTi5wYXJzZShyZXN1bHQucmVzcG9uc2UpOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICBmZWVkYmFjay5zZW5kKCJJbnZhbGlkIHJlc3BvbnNlOiAiICsgSlNPTi5zdHJpbmdpZnkocmVzdWx0LnJlc3BvbnNlKSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvbm5EYXRhLmVycm9yKSB7CiAgICAgICAgICAgICAgICBmZWVkYmFjay5zZW5kKCJDb25uZWN0aW9uIGNsb3NlZDogIiArIEpTT04uc3RyaW5naWZ5KGNvbm5EYXRhLmVycm9yKSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZmVlZGJhY2suc2VuZCgiQ29ubmVjdGlvbiBjbG9zZWQiKQogICAgICAgIH07CiAgICAgICAgcG9sbCgpOwogICAgfQoKICAgIG1haW4oKTsKPC9zY3JpcHQ+Cgo8L2JvZHk+CjwvaHRtbD48P3BocAp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnVybGV4Y2VwdGlvbicsIGZhbHNlKSk6CmNsYXNzIENsb25lclVSTEV4Y2VwdGlvbiBleHRlbmRzIENsb25lckV4Y2VwdGlvbgp7CiAgICBwdWJsaWMgJHVybCA9ICcnOwogICAgcHVibGljICRlcnJvciA9ICcnOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRlcnJvcgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHVybCwgJGVycm9yKSB7CiAgICAgICAgJHRoaXMtPnVybCAgID0gJHVybDsKICAgICAgICAkdGhpcy0+ZXJyb3IgPSAkZXJyb3I7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdChzcHJpbnRmKCd1cmwgJXMgaXMgbm90IHZhbGlkOiAlcycsICR1cmwsICRlcnJvcikpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnVybCcsIGZhbHNlKSk6CmNsYXNzIENsb25lclVSTAp7CiAgICBwdWJsaWMgJHNlY3VyZSA9IGZhbHNlOwogICAgcHVibGljICRob3N0ID0gJyc7CiAgICBwdWJsaWMgJHBvcnQgPSAwOwogICAgcHVibGljICRzY2hlbWUgPSAnJzsKICAgIHB1YmxpYyAkcGF0aCA9ICcnOwogICAgcHVibGljICRxdWVyeSA9ICcnOwogICAgcHVibGljICRmcmFnbWVudCA9ICcnOwogICAgcHVibGljICR1c2VyID0gJyc7CiAgICBwdWJsaWMgJHBhc3MgPSAnJzsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b1N0cmluZygpCiAgICB7CiAgICAgICAgcmV0dXJuIHNwcmludGYoImh0dHAlczovLyVzJXMlcyIsICR0aGlzLT5zZWN1cmUgPyAncycgOiAnJywgJHRoaXMtPmhvc3QsICR0aGlzLT5wb3J0ID8gIjokdGhpcy0+cG9ydCIgOiAnJywgc3RybGVuKCR0aGlzLT5wYXRoKSA/ICR0aGlzLT5wYXRoIDogJy8nKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SFRUUEhvc3QoKQogICAgewogICAgICAgIGlmICghJHRoaXMtPnBvcnQpIHsKICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5ob3N0OwogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPnNlY3VyZSAmJiAkdGhpcy0+cG9ydCA9PT0gNDQzKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aG9zdDsKICAgICAgICB9CiAgICAgICAgaWYgKCEkdGhpcy0+c2VjdXJlICYmICR0aGlzLT5zY2hlbWUgPT09IDgwKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+aG9zdDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICIkdGhpcy0+aG9zdDokdGhpcy0+cG9ydCI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHN0cmluZyBJbiBob3N0OnBvcnQgZm9ybWF0LiBBcHBsaWVzIGRlZmF1bHQgcG9ydCBudW1iZXJzIHdoZXJlIG5vbmUgYXJlIHNldC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldEhvc3RQb3J0KCkKICAgIHsKICAgICAgICAkcG9ydCA9ICR0aGlzLT5wb3J0OwogICAgICAgIGlmICgkdGhpcy0+cG9ydCA9PT0gMCkgewogICAgICAgICAgICAkcG9ydCA9ICR0aGlzLT5zZWN1cmUgPyA0NDMgOiA4MDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICIkdGhpcy0+aG9zdDokcG9ydCI7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqCiAgICAgKiBAcmV0dXJuIENsb25lclVSTAogICAgICoKICAgICAqIEB0aHJvd3MgQ2xvbmVyVVJMRXhjZXB0aW9uIElmIHRoZSBVUkwgaXMgbm90IHZhbGlkLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21TdHJpbmcoJHVybCkKICAgIHsKICAgICAgICAkdSAgICAgPSBuZXcgQ2xvbmVyVVJMKCk7CiAgICAgICAgJHBhcnRzID0gcGFyc2VfdXJsKCR1cmwpOwogICAgICAgIGlmICgkcGFydHMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJVUkxFeGNlcHRpb24oJHVybCwgJ3VybF9pbnZhbGlkJyk7CiAgICAgICAgfQogICAgICAgIGlmICghYXJyYXlfa2V5X2V4aXN0cygnaG9zdCcsICRwYXJ0cykpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lclVSTEV4Y2VwdGlvbigkdXJsLCAnbWlzc2luZ19ob3N0Jyk7CiAgICAgICAgfQogICAgICAgICR1LT5ob3N0ID0gc3RydG9sb3dlcigkcGFydHNbJ2hvc3QnXSk7CiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ3NjaGVtZScsICRwYXJ0cykgJiYgc3RydG9sb3dlcigkcGFydHNbJ3NjaGVtZSddKSA9PT0gJ2h0dHBzJykgewogICAgICAgICAgICAkdS0+c2VjdXJlID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ3BvcnQnLCAkcGFydHMpKSB7CiAgICAgICAgICAgICR1LT5wb3J0ID0gJHBhcnRzWydwb3J0J107CiAgICAgICAgfQogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdwYXRoJywgJHBhcnRzKSAmJiBzdHJsZW4oJHBhcnRzWydwYXRoJ10pKSB7CiAgICAgICAgICAgICR1LT5wYXRoID0gJHBhcnRzWydwYXRoJ107CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHUtPnBhdGggPSAnLyc7CiAgICAgICAgfQogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdxdWVyeScsICRwYXJ0cykpIHsKICAgICAgICAgICAgJHUtPnF1ZXJ5ID0gJHBhcnRzWydxdWVyeSddOwogICAgICAgIH0KICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygnZnJhZ21lbnQnLCAkcGFydHMpKSB7CiAgICAgICAgICAgICR1LT5mcmFnbWVudCA9ICRwYXJ0c1snZnJhZ21lbnQnXTsKICAgICAgICB9CiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJ3VzZXInLCAkcGFydHMpKSB7CiAgICAgICAgICAgICR1LT51c2VyID0gJHBhcnRzWyd1c2VyJ107CiAgICAgICAgfQogICAgICAgIGlmIChhcnJheV9rZXlfZXhpc3RzKCdwYXNzJywgJHBhcnRzKSkgewogICAgICAgICAgICAkdS0+cGFzcyA9ICRwYXJ0c1sncGFzcyddOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHU7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVybm90cmFuc3BvcnRzdHJlYW1zZXhjZXB0aW9uJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyTm9UcmFuc3BvcnRTdHJlYW1zRXhjZXB0aW9uIGV4dGVuZHMgQ2xvbmVyRXhjZXB0aW9uCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkYXR0ZW1wdGVkLCBhcnJheSAkYXZhaWxhYmxlKSB7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdChzcHJpbnRmKAogICAgICAgICAgICAiY291bGQgbm90IGZpbmQgYXZhaWxhYmxlIHRyYW5zcG9ydCBzdHJlYW0gdG8gdXNlOyBhdHRlbXB0ZWQ6ICVzOyBhdmFpbGFibGU6ICVzIiwKICAgICAgICAgICAgaW1wbG9kZSgnLCcsICRhdHRlbXB0ZWQpLAogICAgICAgICAgICBpbXBsb2RlKCcsJywgJGF2YWlsYWJsZSkKICAgICAgICApLCAnbm9fdGxzJyk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyZnNleGNlcHRpb24nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJGU0V4Y2VwdGlvbiBleHRlbmRzIENsb25lckV4Y2VwdGlvbgp7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyZnNmdW5jdGlvbmV4Y2VwdGlvbicsIGZhbHNlKSk6CmNsYXNzIENsb25lckZTRnVuY3Rpb25FeGNlcHRpb24gZXh0ZW5kcyBDbG9uZXJGU0V4Y2VwdGlvbgp7CiAgICBwdWJsaWMgJGZuID0gJyc7CiAgICBwdWJsaWMgJHBhdGggPSAnJzsKICAgIHB1YmxpYyAkZXJyb3IgPSAnJzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZuICAgT25lIG9mIGZvcGVuLCBmcmVhZCwgZmxvY2ssIGV0Yy4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGggUGF0aCBvbiB0aGUgZmlsZXN5c3RlbS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRmbiwgJHBhdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPmZuICAgID0gJGZuOwogICAgICAgICR0aGlzLT5wYXRoICA9ICRwYXRoOwogICAgICAgICR0aGlzLT5lcnJvciA9IGNsb25lcl9sYXN0X2Vycm9yX2ZvcigkZm4pOwogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3Qoc3ByaW50ZignJXMgZXJyb3IgZm9yIHBhdGggJXM6ICVzJywgJGZuLCAkcGF0aCwgJHRoaXMtPmVycm9yKSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3Rsc190cmFuc3BvcnRfc2VsZl9zaWduZWQnKSk6CmZ1bmN0aW9uIGNsb25lcl90bHNfdHJhbnNwb3J0X3NlbGZfc2lnbmVkKCRwZWVyTmFtZSwgJGNlcnQpCnsKICAgIHN0YXRpYyAkdHJhbnNwb3J0LCAkY2VydFBhdGg7CgogICAgJGF2YWlsYWJsZSA9IHN0cmVhbV9nZXRfdHJhbnNwb3J0cygpOwogICAgJGF0dGVtcHRlZCA9IGFycmF5KCdzc2wnLCAndGxzJywgJ3Rsc3YxLjInLCAndGxzdjEuMScsICd0bHN2MS4wJyk7CiAgICBpZiAoISR0cmFuc3BvcnQpIHsKICAgICAgICBmb3JlYWNoICgkYXR0ZW1wdGVkIGFzICRhdHRlbXB0KSB7CiAgICAgICAgICAgICRpbmRleCA9IGFycmF5X3NlYXJjaCgkYXR0ZW1wdCwgJGF2YWlsYWJsZSk7CiAgICAgICAgICAgIGlmICgkaW5kZXggIT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkdHJhbnNwb3J0ID0gJGF2YWlsYWJsZVskaW5kZXhdOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBpZiAoISR0cmFuc3BvcnQpIHsKICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyTm9UcmFuc3BvcnRTdHJlYW1zRXhjZXB0aW9uKCRhdmFpbGFibGUsICRhdHRlbXB0ZWQpOwogICAgfQogICAgaWYgKCEkY2VydFBhdGgpIHsKICAgICAgICAkY2VydEhhc2ggPSBtZDUoJGNlcnQpOwogICAgICAgICR0ZW1wUGF0aCA9IHN5c19nZXRfdGVtcF9kaXIoKS4nL2Nsb25lci1jZXJ0LScuJGNlcnRIYXNoOwogICAgICAgIGlmICghZmlsZV9leGlzdHMoJHRlbXBQYXRoKSB8fCBAbWQ1X2ZpbGUoJHRlbXBQYXRoKSAhPT0gJGNlcnRIYXNoKSB7CiAgICAgICAgICAgIGlmICghZmlsZV9wdXRfY29udGVudHMoJHRlbXBQYXRoLCAkY2VydCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJGU0Z1bmN0aW9uRXhjZXB0aW9uKCdmaWxlX3B1dF9jb250ZW50cycsICR0ZW1wUGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJGNlcnRQYXRoID0gJHRlbXBQYXRoOwogICAgfQoKICAgIC8vIFRlbXBvcmFyaWx5IGRpc2FibGUgU1NMIHBlZXIgY2hlY2suCiAgICAkY3R4ID0gc3RyZWFtX2NvbnRleHRfY3JlYXRlKGFycmF5KCdzc2wnID0+IGFycmF5KAogICAgICAgICdhbGxvd19zZWxmX3NpZ25lZCcgPT4gdHJ1ZSwKICAgICAgICAnQ05fbWF0Y2gnICAgICAgICAgID0+ICRwZWVyTmFtZSwKICAgICAgICAndmVyaWZ5X3BlZXInICAgICAgID0+IHRydWUsCiAgICAgICAgJ1NOSV9lbmFibGVkJyAgICAgICA9PiB0cnVlLAogICAgICAgICdTTklfc2VydmVyX25hbWUnICAgPT4gJHBlZXJOYW1lLAogICAgICAgICdwZWVyX25hbWUnICAgICAgICAgPT4gJHBlZXJOYW1lLAogICAgICAgICdjYWZpbGUnICAgICAgICAgICAgPT4gJGNlcnRQYXRoLAogICAgKSkpOwogICAgcmV0dXJuIGFycmF5KCR0cmFuc3BvcnQsICRjdHgpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl90bHNfdHJhbnNwb3J0JykpOgpmdW5jdGlvbiBjbG9uZXJfdGxzX3RyYW5zcG9ydCgkcGVlck5hbWUgPSAnJykKewogICAgc3RhdGljICR0cmFuc3BvcnQ7CgogICAgJGF2YWlsYWJsZSA9IHN0cmVhbV9nZXRfdHJhbnNwb3J0cygpOwogICAgJGF0dGVtcHRlZCA9IGFycmF5KCdzc2wnLCAndGxzJywgJ3Rsc3YxLjInLCAndGxzdjEuMScsICd0bHN2MS4wJyk7CiAgICBmb3JlYWNoICgkYXR0ZW1wdGVkIGFzICRhdHRlbXB0KSB7CiAgICAgICAgJGluZGV4ID0gYXJyYXlfc2VhcmNoKCRhdHRlbXB0LCAkYXZhaWxhYmxlKTsKICAgICAgICBpZiAoJGluZGV4ICE9PSBmYWxzZSkgewogICAgICAgICAgICAkdHJhbnNwb3J0ID0gJGF2YWlsYWJsZVskaW5kZXhdOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBpZiAoJHRyYW5zcG9ydCA9PT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBDbG9uZXJOb1RyYW5zcG9ydFN0cmVhbXNFeGNlcHRpb24oJGF2YWlsYWJsZSwgJGF0dGVtcHRlZCk7CiAgICB9CgogICAgLy8gVGVtcG9yYXJpbHkgZGlzYWJsZSBTU0wgcGVlciBjaGVjay4KICAgICRjdHggPSBzdHJlYW1fY29udGV4dF9jcmVhdGUoYXJyYXkoJ3NzbCcgPT4gYXJyYXkoCiAgICAgICAgJ3ZlcmlmeV9wZWVyJyAgICAgICA9PiBmYWxzZSwKICAgICAgICAndmVyaWZ5X3BlZXJfbmFtZScgID0+IGZhbHNlLAogICAgICAgICdhbGxvd19zZWxmX3NpZ25lZCcgPT4gdHJ1ZSwKICAgICkpKTsKICAgIHJldHVybiBhcnJheSgkdHJhbnNwb3J0LCAkY3R4KTsKCiAgICAkY2FjaGVkQ2VydHNQYXRoID0gc3lzX2dldF90ZW1wX2RpcigpLicvbWFuYWdld3Atd29ya2VyLXYyLmNydCc7CiAgICAkdGxzT3B0aW9ucyAgICAgID0gYXJyYXkoCiAgICAgICAgJ3ZlcmlmeV9wZWVyJyAgICAgICA9PiB0cnVlLAogICAgICAgICd2ZXJpZnlfcGVlcl9uYW1lJyAgPT4gdHJ1ZSwKICAgICAgICAnYWxsb3dfc2VsZl9zaWduZWQnID0+IGZhbHNlLAogICAgICAgIC8vIEF0dGVtcHQgc3lzdGVtJ3MgQ0FGSUxFLgogICAgKTsKICAgIGlmIChpc19maWxlKCRjYWNoZWRDZXJ0c1BhdGgpKSB7CiAgICAgICAgJHRsc09wdGlvbnNbJ2NhZmlsZSddID0gJGNhY2hlZENlcnRzUGF0aDsKICAgIH0KICAgIGlmIChzdHJsZW4oJHBlZXJOYW1lKSkgewogICAgICAgIGlmIChQSFBfVkVSU0lPTl9JRCA+PSA1MDYwMCkgewogICAgICAgICAgICAkdGxzT3B0aW9uc1sncGVlcl9uYW1lJ10gPSAkcGVlck5hbWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHRsc09wdGlvbnNbJ0NOX21hdGNoJ10gPSAkcGVlck5hbWU7CiAgICAgICAgfQogICAgfQoKICAgICRjdHggPSBzdHJlYW1fY29udGV4dF9jcmVhdGUoYXJyYXkoJ3NzbCcgPT4gJHRsc09wdGlvbnMpKTsKCiAgICBpZiAoJHRyYW5zcG9ydCAhPT0gbnVsbCkgewogICAgICAgIHJldHVybiBhcnJheSgkdHJhbnNwb3J0LCAkY3R4KTsKICAgIH0KfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJuZXRleGNlcHRpb24nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJOZXRFeGNlcHRpb24gZXh0ZW5kcyBDbG9uZXJFeGNlcHRpb24Kewp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnNvY2tldGNsaWVudGV4Y2VwdGlvbicsIGZhbHNlKSk6CmNsYXNzIENsb25lclNvY2tldENsaWVudEV4Y2VwdGlvbiBleHRlbmRzIENsb25lck5ldEV4Y2VwdGlvbgp7CiAgICBwdWJsaWMgJGZuID0gJ3N0cmVhbV9zb2NrZXRfY2xpZW50JzsKICAgIHB1YmxpYyAkdHJhbnNwb3J0ID0gJyc7CiAgICBwdWJsaWMgJGhvc3QgPSAnJzsKICAgIHB1YmxpYyAkZXJyb3IgPSAnJzsKICAgIHB1YmxpYyAkZXJybm8gPSAwOwogICAgcHVibGljICRlcnJzdHIgPSAnJzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRyYW5zcG9ydAogICAgICogQHBhcmFtIHN0cmluZyAkaG9zdAogICAgICogQHBhcmFtIGludCAgICAkZXJybm8KICAgICAqIEBwYXJhbSBzdHJpbmcgJGVycnN0cgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHRyYW5zcG9ydCwgJGhvc3QsICRlcnJubywgJGVycnN0cikKICAgIHsKICAgICAgICAkdGhpcy0+aG9zdCAgID0gJGhvc3Q7CiAgICAgICAgJHRoaXMtPmVycm9yICA9IGNsb25lcl9sYXN0X2Vycm9yX2ZvcigkdGhpcy0+Zm4pOwogICAgICAgICR0aGlzLT5lcnJubyAgPSAkZXJybm87CiAgICAgICAgJHRoaXMtPmVycnN0ciA9ICRlcnJzdHI7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdChzcHJpbnRmKCclcyBlcnJvciBmb3IgaG9zdCAlczovLyVzOiAlczsgZXJybm86ICVkOyBlcnJzdHI6ICVzJywgJHRoaXMtPmZuLCAkdHJhbnNwb3J0LCAkaG9zdCwgJHRoaXMtPmVycm9yLCAkZXJybm8sICRlcnJzdHIpKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfdGxzX3RyYW5zcG9ydF9jb250ZXh0X2N1cmwnKSk6CmZ1bmN0aW9uIGNsb25lcl90bHNfdHJhbnNwb3J0X2NvbnRleHRfY3VybCgpCnsKICAgIC8vIFJlc3BlY3RpdmVseToKICAgIC8vIC0gRnJvbSBjdXJsLmhheHguc2U6CiAgICAvLyAgIC9DPVVTL1NUPUNhbGlmb3JuaWEvTD1TYW4gRnJhbmNpc2NvL089RmFzdGx5LCBJbmMuL0NOPWMuc25pLmZhc3RseS5uZXQKICAgIC8vICAgL0M9QkUvTz1HbG9iYWxTaWduIG52LXNhL0NOPUdsb2JhbFNpZ24gT3JnYW5pemF0aW9uIFZhbGlkYXRpb24gQ0EgLSBTSEEyNTYgLSBHMgogICAgLy8gLSBGcm9tIHRoZSBjYWNlcnQucGVtIGl0c2VsZjoKICAgIC8vICAgL0NOPUdsb2JhbFNpZ24gUm9vdCBDQQogICAgJGNlcnRzID0gPDw8Q1JUCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGT3pDQ0JDT2dBd0lCQWdJTU80cGdReW1nRVIrbTBrNk9NQTBHQ1NxR1NJYjNEUUVCQ3dVQU1HWXhDekFKCkJnTlZCQVlUQWtKRk1Sa3dGd1lEVlFRS0V4QkhiRzlpWVd4VGFXZHVJRzUyTFhOaE1Ud3dPZ1lEVlFRREV6TkgKYkc5aVlXeFRhV2R1SUU5eVoyRnVhWHBoZEdsdmJpQldZV3hwWkdGMGFXOXVJRU5CSUMwZ1UwaEJNalUySUMwZwpSekl3SGhjTk1UY3dNakEzTWpJME1UQTBXaGNOTVRrd01qQTRNakkwTVRBMFdqQnNNUXN3Q1FZRFZRUUdFd0pWClV6RVRNQkVHQTFVRUNCTUtRMkZzYVdadmNtNXBZVEVXTUJRR0ExVUVCeE1OVTJGdUlFWnlZVzVqYVhOamJ6RVYKTUJNR0ExVUVDaE1NUm1GemRHeDVMQ0JKYm1NdU1Sa3dGd1lEVlFRREV4QmpMbk51YVM1bVlYTjBiSGt1Ym1WMApNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXBiVWV2ZkZSRUFmdlVIMThvVzI3CkJWTGJrV0puYlo2OWRRQ0NjaGN1YVhKOEpxL0k2cGxnS3dXMnlXVUcveW5wN2RwKzBCd29XbnpiaVFIcVpUc1cKNlBxZjBsZTJ1RU5jOHNTeEx5SUxBVEcyQ3QvczM2WHhYTmZ1SDgzODh1T2ZpVnZ3b0VBb0RCRDFWRVhjSS80cgplaTJLR3dWeDhQR0xiNjBqaXRMRFBMWU9YVy9rTXUrV05nLytidGpKNGtoczMwVWVIaDEwVVVyWGp1Uk8zaWdhCjZoT2dLcHZia1gwM25mSEgvK3pjK3NEZkplckgwYm1Ud3ZaTHdXdXBSVzV4NjVoeDJPMnZvVVZiYjI3bm5icVoKelI1N0ZaQVRFSHl2cVFnaEhzSGpJOGJ3QkkxYXpEdUN6N3ZYSUlLeVlrWE5PMWVSclh6VDQ2VHg3bUh0YW5PTApid0lEQVFBQm80SUI0VENDQWQwd0RnWURWUjBQQVFIL0JBUURBZ1dnTUlHZ0JnZ3JCZ0VGQlFjQkFRU0JrekNCCmtEQk5CZ2dyQmdFRkJRY3dBb1pCYUhSMGNEb3ZMM05sWTNWeVpTNW5iRzlpWVd4emFXZHVMbU52YlM5allXTmwKY25RdlozTnZjbWRoYm1sNllYUnBiMjUyWVd4emFHRXlaekp5TVM1amNuUXdQd1lJS3dZQkJRVUhNQUdHTTJoMApkSEE2THk5dlkzTndNaTVuYkc5aVlXeHphV2R1TG1OdmJTOW5jMjl5WjJGdWFYcGhkR2x2Ym5aaGJITm9ZVEpuCk1qQldCZ05WSFNBRVR6Qk5NRUVHQ1NzR0FRUUJvRElCRkRBME1ESUdDQ3NHQVFVRkJ3SUJGaVpvZEhSd2N6b3YKTDNkM2R5NW5iRzlpWVd4emFXZHVMbU52YlM5eVpYQnZjMmwwYjNKNUx6QUlCZ1puZ1F3QkFnSXdDUVlEVlIwVApCQUl3QURCSkJnTlZIUjhFUWpCQU1ENmdQS0E2aGpob2RIUndPaTh2WTNKc0xtZHNiMkpoYkhOcFoyNHVZMjl0CkwyZHpMMmR6YjNKbllXNXBlbUYwYVc5dWRtRnNjMmhoTW1jeUxtTnliREFiQmdOVkhSRUVGREFTZ2hCakxuTnUKYVM1bVlYTjBiSGt1Ym1WME1CMEdBMVVkSlFRV01CUUdDQ3NHQVFVRkJ3TUJCZ2dyQmdFRkJRY0RBakFkQmdOVgpIUTRFRmdRVXRLaTA1TnVyNzJBRWFiL3VlYWdzUCtzbXJHQXdId1lEVlIwakJCZ3dGb0FVbHQ1aDhiMGNGaWxUCkhNRE1mVHVEQUVEbUdud3dEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSU80UWNuS3NXeU12ZmpaajRRTWcxYW8KMzFYdVk3alJpRzIvYStTMzlKWUVJUysxNkdYaVRSZktKTWs1ZE5LSzMwa1JVK3VQeEJhbDVIUy9pNDNaUm1ZMgowaVFHL3RNTG9Wb1RQVXp4YmdpSXZnRkl2ak5HNnZlZml6YStDODNBWTFWejhIT2NBQUUzQU03ZWZxWW8wWGRWCnhsdk9rZGlucUdEd0VSa1p5S1E0bUlEcUVlVTZ3UEhMVEtmK3dMbnFjWXh5ZUE0REs2Q2Q3djBOSE1CbTAyTDIKWk1mOGlXMU9aU3krdUtzd3FTSWVkbW15a28vdHVPNmdOQTdacy9wUzVyanM2VkgwT0U2VGxNSXh2SC93MGRqNwpuOEYvZTFtaGpwNzNDTVY3N01BSXl4bm5vck0vWjU4cmVXRi9WR2dPVTg5eTRPZFV1Z0hJWjRGN2ZEVGZwVFU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVhVENDQTFHZ0F3SUJBZ0lMQkFBQUFBQUJSRTd3UWtjd0RRWUpLb1pJaHZjTkFRRUxCUUF3VnpFTE1Ba0cKQTFVRUJoTUNRa1V4R1RBWEJnTlZCQW9URUVkc2IySmhiRk5wWjI0Z2JuWXRjMkV4RURBT0JnTlZCQXNUQjFKdgpiM1FnUTBFeEd6QVpCZ05WQkFNVEVrZHNiMkpoYkZOcFoyNGdVbTl2ZENCRFFUQWVGdzB4TkRBeU1qQXhNREF3Ck1EQmFGdzB5TkRBeU1qQXhNREF3TURCYU1HWXhDekFKQmdOVkJBWVRBa0pGTVJrd0Z3WURWUVFLRXhCSGJHOWkKWVd4VGFXZHVJRzUyTFhOaE1Ud3dPZ1lEVlFRREV6TkhiRzlpWVd4VGFXZHVJRTl5WjJGdWFYcGhkR2x2YmlCVwpZV3hwWkdGMGFXOXVJRU5CSUMwZ1UwaEJNalUySUMwZ1J6SXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRREhEbXcvSTVOL3pIQ2xuU0RERGxNL2ZzQk93cGhKeWtmVkkrOEROSVYweUtNQ0xrWmMKQzMzSmlKMVBpL0Q0bkd5TVZUWGJ2L0t6NnZ2alZ1ZEtSdGtUSXNvMjFadkJxT09XUTVQeURMem0rZWJvbWNoagpTSGgvVnpacEdoa2RXdEhVZmNLYzFIL2hnQkt1ZXVxSTZsZll5Z29LT2hKSm9tSVplZzBrOXpmcnRIT1Nld1VqCm14SzF6dXNwMzZRVUFya0JwZFNtbkVOa2lONzRmdjdqOVI3bC90eWpxT1JtTWRsTUpla1l1WWxaQ2E3cG5SeHQKTnc5S0hqVWdLT0t2MUNHTEFjUkZyVzRyWTZ1U2EyRUtUU0R0YzdwOHp2NFd0ZHVmZ1BEV2kyelpDSGxLVDNobAoycEs4dmpYNXM4VDVKNEJPLzVaUzVnSWc0UWR6NlYwcnZiTHhBZ01CQUFHamdnRWxNSUlCSVRBT0JnTlZIUThCCkFmOEVCQU1DQVFZd0VnWURWUjBUQVFIL0JBZ3dCZ0VCL3dJQkFEQWRCZ05WSFE0RUZnUVVsdDVoOGIwY0ZpbFQKSE1ETWZUdURBRURtR253d1J3WURWUjBnQkVBd1BqQThCZ1JWSFNBQU1EUXdNZ1lJS3dZQkJRVUhBZ0VXSm1oMApkSEJ6T2k4dmQzZDNMbWRzYjJKaGJITnBaMjR1WTI5dEwzSmxjRzl6YVhSdmNua3ZNRE1HQTFVZEh3UXNNQ293CktLQW1vQ1NHSW1oMGRIQTZMeTlqY213dVoyeHZZbUZzYzJsbmJpNXVaWFF2Y205dmRDNWpjbXd3UFFZSUt3WUIKQlFVSEFRRUVNVEF2TUMwR0NDc0dBUVVGQnpBQmhpRm9kSFJ3T2k4dmIyTnpjQzVuYkc5aVlXeHphV2R1TG1OdgpiUzl5YjI5MGNqRXdId1lEVlIwakJCZ3dGb0FVWUh0bUdrVU5sOHFKVUM5OUJNMDBxUC84L1Vzd0RRWUpLb1pJCmh2Y05BUUVMQlFBRGdnRUJBRVlxN2w2OXJnRmdOekVSaG5GMHRrWkp5QkFXL2k5aUl4ZXJINGY0Z3UzSzN3NHMKMzJSMWp1VVljcWVNT292SnJLVjNVUGZ2bnFUZ29JOFVWNk1xWCt4K2JSRG11bzJ3Q0lkMkRreXkyVkc3RVFMeQpYTjBjdmZOVmxnL1VCc0Q4NGlPS0pIRFR1L0I1R3FkaGNJT0tyd2JGSU5paFk5QnNyazh5MTY1OEdFVjFCU2wzCjMwSkFaR1NHdmlwMkNURnZIU1QwbWRDRi92SWhDUG5HOXZIUVdlM1dWandJS0FObnV2RDU4WkFXUjY1bjVyeUEKU09sQ2RqU1hWV2trRG9QV29DMjA5Zk41aWtrb2RCcEJvY0xUSklnMU1HQ1VGN1RoQkNJeFBUc3ZGd2F5dUoyRwpLMXBwNzRQMVM4U3F0Q3I0ZktHeGhaU005QXlIRFBTc1FQaFpTWmc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURkVENDQWwyZ0F3SUJBZ0lMQkFBQUFBQUJGVXRhdzVRd0RRWUpLb1pJaHZjTkFRRUZCUUF3VnpFTE1Ba0cKQTFVRUJoTUNRa1V4R1RBWEJnTlZCQW9URUVkc2IySmhiRk5wWjI0Z2JuWXRjMkV4RURBT0JnTlZCQXNUQjFKdgpiM1FnUTBFeEd6QVpCZ05WQkFNVEVrZHNiMkpoYkZOcFoyNGdVbTl2ZENCRFFUQWVGdzA1T0RBNU1ERXhNakF3Ck1EQmFGdzB5T0RBeE1qZ3hNakF3TURCYU1GY3hDekFKQmdOVkJBWVRBa0pGTVJrd0Z3WURWUVFLRXhCSGJHOWkKWVd4VGFXZHVJRzUyTFhOaE1SQXdEZ1lEVlFRTEV3ZFNiMjkwSUVOQk1Sc3dHUVlEVlFRREV4SkhiRzlpWVd4VAphV2R1SUZKdmIzUWdRMEV3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRGFEdWFaCmpjNmo0MCtLZnZ2eGk0TWxhK3BJSC9FcXNMbVZFUVM5OEdQUjRtZG16eHpkenh0SUsrNk5pWTZhcnltQVphdnAKeHkwU3k2c2NUSEFIb1QwS01NMFZqVS80M2RTTVVCVWM3MUR1eEM3My9PbFM4cEY5NEczVk5UQ09Ya056OGtIcAoxV3Jqc29rNlZqazRid1k4aUdsYktrM0ZwMVM0YkluTW0vazh5dVg5aWZVU1BKSjRsdGJjZEc2VFJHSFJqY2RHCnNuVU9odWdaaXRWdGJOVjRGcFdpNmNnS09PdnlKQk5QYzFTVEU0VTZHN3dlTkxXTEJZeTVkNHV4Mng4Z2thc0oKVTI2UXpuczNkTGx3UjVFaVVXTVdlYTZ4cmtFbUNNZ1pLOUZHcWtqV1pDclhnelQvTENyQmJCbERTZ2VGNTlOOAo5aUZvNytyeVVwOS9rNURQQWdNQkFBR2pRakJBTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFCkJUQURBUUgvTUIwR0ExVWREZ1FXQkJSZ2UyWWFSUTJYeW9sUUwzMEV6VFNvLy96OVN6QU5CZ2txaGtpRzl3MEIKQVFVRkFBT0NBUUVBMW5QbmZFOTIwSTIvN0xxaXZqVEZLREsxZlB4c25Dd3J2UW1lVTc5clhxb1JTTGJsQ0tPegp5ajFoVGROR0NiTSt3NkRqWTFVYjhycnZyVG5oUTdrNG8rWXZpaVk3NzZCUVZ2bkdDdjA0emNRTGNGR1VsNWdFCjM4TmZsTlVWeVJSQm5NUmRkV1FWRGY5Vk1PeUdqLzhON3l5NVkwYjJxdnpmdkduOUxoSklaSnJnbGZDbTd5bVAKQWJFVnRRd2RwZjVwTEdra2VCNnpweHh4WXU3S3lKZXNGMTJLd3ZoSGhtNHF4Rll4bGRCbmlZVXIrV3ltWFVhZApES3FDNUpsUjNYQzMyMVk5WWVScTRWelc5djQ5M2tITUI2NWpVcjlUVS9RcjZjZjl0dmVDWDRYU1FSamJnYk1FCkhNVWZwSUJ2RlNESjNneUlDaDNXWmxYaS9FakpLU1pwNEE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCkNSVDsKCiAgICAkY2VydHNQYXRoID0gc3lzX2dldF90ZW1wX2RpcigpLicvbWFuYWdld3AtY3VybC5jcnQnOwogICAgaWYgKEBmaWxlc2l6ZSgkY2VydHNQYXRoKSAhPT0gc3RybGVuKCRjZXJ0cykpIHsKICAgICAgICBpZiAoQGZpbGVfcHV0X2NvbnRlbnRzKCRjZXJ0c1BhdGgsICRjZXJ0cykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJGU0Z1bmN0aW9uRXhjZXB0aW9uKCdmaWxlX3B1dF9jb250ZW50cycsICRjZXJ0c1BhdGgpOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gc3RyZWFtX2NvbnRleHRfY3JlYXRlKGFycmF5KAogICAgICAgICdzc2wnID0+IGFycmF5KAogICAgICAgICAgICAndmVyaWZ5X3BlZXInICAgICAgID0+IHRydWUsCiAgICAgICAgICAgICd2ZXJpZnlfcGVlcl9uYW1lJyAgPT4gdHJ1ZSwKICAgICAgICAgICAgJ2FsbG93X3NlbGZfc2lnbmVkJyA9PiBmYWxzZSwKICAgICAgICAgICAgJ2NhZmlsZScgICAgICAgICAgICA9PiAkY2VydHNQYXRoLAogICAgICAgICksCiAgICApKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfdGxzX3RyYW5zcG9ydF9jb250ZXh0X2ZhbGxiYWNrJykpOgpmdW5jdGlvbiBjbG9uZXJfdGxzX3RyYW5zcG9ydF9jb250ZXh0X2ZhbGxiYWNrKCRwZWVyTmFtZSA9ICcnKQp7CiAgICAkY2VydHNQYXRoID0gc3lzX2dldF90ZW1wX2RpcigpLicvbWFuYWdld3Atd29ya2VyLXYyLmNydCc7CiAgICBpZiAoIWZpbGVfZXhpc3RzKCRjZXJ0c1BhdGgpKSB7CiAgICAgICAgJGNlcnRzID0gY2xvbmVyX2h0dHBfZG8oJ0dFVCcsIENsb25lclVSTDo6ZnJvbVN0cmluZygnaHR0cHM6Ly9jdXJsLmhheHguc2UvY2EvY2FjZXJ0LnBlbScpKTsKCiAgICAgICAgLy8gQXBwZW5kIG1hbmFnZXdwLnRlc3QgY2VydGlmaWNhdGU6CiAgICAgICAgLy8gICAvQz1SUy9TVD1TZXJiaWEvTD1CZWxncmFkZS9PPUdvRGFkZHkgTExDL09VPU1hbmFnZVdQL0NOPW1hbmFnZXdwLnRlc3QvZW1haWxBZGRyZXNzPWRldm9wc0BtYW5hZ2V3cC50ZXN0CiAgICAgICAgJGNlcnRzIC49IDw8PENSVAoKLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURyRENDQXBRQ0NRRDNyQ25PdTFjZGVUQU5CZ2txaGtpRzl3MEJBUVVGQURDQmx6RUxNQWtHQTFVRUJoTUMKVWxNeER6QU5CZ05WQkFnTUJsTmxjbUpwWVRFUk1BOEdBMVVFQnd3SVFtVnNaM0poWkdVeEZEQVNCZ05WQkFvTQpDMGR2UkdGa1pIa2dURXhETVJFd0R3WURWUVFMREFoTllXNWhaMlZYVURFV01CUUdBMVVFQXd3TmJXRnVZV2RsCmQzQXVkR1Z6ZERFak1DRUdDU3FHU0liM0RRRUpBUllVWkdWMmIzQnpRRzFoYm1GblpYZHdMblJsYzNRd0hoY04KTVRnd01UQTVNRGsxTmpJNFdoY05Namd3TVRBM01EazFOakk0V2pDQmx6RUxNQWtHQTFVRUJoTUNVbE14RHpBTgpCZ05WQkFnTUJsTmxjbUpwWVRFUk1BOEdBMVVFQnd3SVFtVnNaM0poWkdVeEZEQVNCZ05WQkFvTUMwZHZSR0ZrClpIa2dURXhETVJFd0R3WURWUVFMREFoTllXNWhaMlZYVURFV01CUUdBMVVFQXd3TmJXRnVZV2RsZDNBdWRHVnoKZERFak1DRUdDU3FHU0liM0RRRUpBUllVWkdWMmIzQnpRRzFoYm1GblpYZHdMblJsYzNRd2dnRWlNQTBHQ1NxRwpTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFEajhkV0VSWlhvRlYydXpRb2RnQXdqNXlDZlI2Zks2Z0FVCmhjODZUWUh5RklCQXFxNUdFc1VXNDhzdm1qS0FsZzJQeWRUdTUvVWxkMVE3M1ZZUjNlWDVkRHhSR3dJVndmbkkKVGRDc0Vtc2VDRmlkcjI0QkxaemR4TzNjYzBtL2lHR0xsY1FTRjQ3ZDRrRDlRY3U2Ritoemt2NHpUUlNINmFZKwprU0Q1aTFhSXphcFVpUU9yb0Q1c2ZRWlAxZmUxTjBDTHVxS3ZwVDVMRFBxbno2L1JhSXRxbXNKTDZzWmFTMDFkCndyQk5MdlUzTTRmbFp6a0lMSjd0OTdYYW1kd2pyOXF6eUVKWlRhU0tCUjdkaHk1a0hhOGpab0p6dm0yeW0wMmoKU3ZteVhJOW9nN3Y2M1BqUkNZUU9aZG5vaFI4L3kvYURYMW55dVJuU05PR0IrWTJkd1hyWEFnTUJBQUV3RFFZSgpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFBcURIQVVaWGdZY2kzaDlzVU53RGNUbkhQRVdtY1krb0MrdkJuWkJXaGhNClpBWVIxblJDZjcwR1pCSjNoTHplcE44Y0dDa0U2RVpRb0RTN3VUNTdGMS9BOG1EY0hiWWpPdTFDd0xTend5S1QKVTIwV1lMVGNncCt1bmVnQXFRVERHdzkyc0ZvaGo3VUZ4VTFuK2pPMXlnS0VOaVVwM0tWY2diamdGWnFBYnY0QgpnRUxDb1JHSlJCUEJqd0NyRFhNQ1M4cGZJUU5TVFdNQnlqMDNXNFpYRGs2U0RQV1VoVGNHeGxmdnBkYW1wTUk5CkZpM0NOTmtVM0FkS2o0dXVOeEU4eW1UcG9ERm1JMzVGWTRsbGVRRTcxVlpob0FIL3dnMHI4YVhNRXVPaEI2ajYKdDMvM3EwTmlRSDhCaUgrWlh4SFRQTGM3aFJmd09pdi93a0lVMlptcURrQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoKQ1JUOwogICAgICAgIGlmIChAZmlsZV9wdXRfY29udGVudHMoJGNlcnRzUGF0aCwgJGNlcnRzKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckZTRnVuY3Rpb25FeGNlcHRpb24oJ2ZpbGVfcHV0X2NvbnRlbnRzJywgJGNlcnRzUGF0aCk7CiAgICAgICAgfQogICAgfQoKICAgICR0bHNPcHRpb25zID0gYXJyYXkoCiAgICAgICAgJ3ZlcmlmeV9wZWVyJyAgICAgICA9PiB0cnVlLAogICAgICAgICd2ZXJpZnlfcGVlcl9uYW1lJyAgPT4gdHJ1ZSwKICAgICAgICAnYWxsb3dfc2VsZl9zaWduZWQnID0+IGZhbHNlLAogICAgICAgICdjYWZpbGUnICAgICAgICAgICAgPT4gJGNlcnRzUGF0aCwKICAgICk7CiAgICBpZiAoc3RybGVuKCRwZWVyTmFtZSkpIHsKICAgICAgICBpZiAoUEhQX1ZFUlNJT05fSUQgPj0gNTA2MDApIHsKICAgICAgICAgICAgJHRsc09wdGlvbnNbJ3BlZXJfbmFtZSddID0gJHBlZXJOYW1lOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICR0bHNPcHRpb25zWydDTl9tYXRjaCddID0gJHBlZXJOYW1lOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBzdHJlYW1fY29udGV4dF9jcmVhdGUoYXJyYXkoCiAgICAgICAgJ3NzbCcgPT4gJHRsc09wdGlvbnMsCiAgICApKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfdGNwX3NvY2tldF9kaWFsJykpOgpmdW5jdGlvbiBjbG9uZXJfdGNwX3NvY2tldF9kaWFsKCRob3N0LCAkdGltZW91dCA9IDEwLCAkc2VjdXJlID0gZmFsc2UsICRwZWVyTmFtZSA9ICcnLCAkY2VydCA9ICcnKQp7CiAgICAkdHJhbnNwb3J0ID0gJ3RjcCc7CiAgICAvLyBOdWxsIGlzIG5vdCBhbGxvd2VkIGluIHN0cmVhbV9zb2NrZXRfY2xpZW50LgogICAgJGN0eCA9IHN0cmVhbV9jb250ZXh0X2NyZWF0ZSgpOwogICAgaWYgKCRzZWN1cmUpIHsKICAgICAgICBpZiAoc3RybGVuKCRjZXJ0KSkgewogICAgICAgICAgICBsaXN0KCR0cmFuc3BvcnQsICRjdHgpID0gY2xvbmVyX3Rsc190cmFuc3BvcnRfc2VsZl9zaWduZWQoJHBlZXJOYW1lLCAkY2VydCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGlzdCgkdHJhbnNwb3J0LCAkY3R4KSA9IGNsb25lcl90bHNfdHJhbnNwb3J0KCRwZWVyTmFtZSk7CiAgICAgICAgfQogICAgfQogICAgJGZhbGxiYWNrID0gZmFsc2U7CiAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICRzb2NrID0gQHN0cmVhbV9zb2NrZXRfY2xpZW50KCR0cmFuc3BvcnQuJzovLycuJGhvc3QsICRlcnJubywgJGVycnN0ciwgJHRpbWVvdXQsIFNUUkVBTV9DTElFTlRfQ09OTkVDVCwgJGN0eCk7CiAgICAgICAgaWYgKCRzb2NrID09PSBmYWxzZSkgewogICAgICAgICAgICAkZSA9IG5ldyBDbG9uZXJTb2NrZXRDbGllbnRFeGNlcHRpb24oJHRyYW5zcG9ydCwgJGhvc3QsICRlcnJubywgJGVycnN0cik7CiAgICAgICAgICAgIC8vIFRlbXBvcmFyaWx5IGRpc2FibGUgU1NMIHBlZXIgY2hlY2suCiAgICAgICAgICAgIGlmIChmYWxzZSAmJiAkZXJybm8gPT09IDAgJiYgJHNlY3VyZSAmJiAhJGZhbGxiYWNrKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICRjdHggICAgICA9ICgkaG9zdCA9PT0gJ2N1cmwuaGF4eC5zZTo0NDMnKSA/IGNsb25lcl90bHNfdHJhbnNwb3J0X2NvbnRleHRfY3VybCgpIDogY2xvbmVyX3Rsc190cmFuc3BvcnRfY29udGV4dF9mYWxsYmFjaygkcGVlck5hbWUpOwogICAgICAgICAgICAgICAgICAgICRmYWxsYmFjayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUyKSB7CiAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdGYWxsYmFjayBUTFMgY29udGV4dCBlcnJvcjogJXMnLCAkZTItPmdldE1lc3NhZ2UoKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAkc29jazsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJuZXRzb2NrZXRleGNlcHRpb24nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJOZXRTb2NrZXRFeGNlcHRpb24gZXh0ZW5kcyBDbG9uZXJOZXRFeGNlcHRpb24KewogICAgcHVibGljICRmbiA9ICcnOwogICAgcHVibGljICRlcnJvciA9ICcnOwogICAgcHVibGljICR0aW1lb3V0ID0gZmFsc2U7CiAgICBwdWJsaWMgJGVvZiA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICRmbgogICAgICogQHBhcmFtIHJlc291cmNlICRzb2NrCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZm4sICRzb2NrKQogICAgewogICAgICAgICR0aGlzLT5mbiAgICA9ICRmbjsKICAgICAgICAkdGhpcy0+ZXJyb3IgPSBjbG9uZXJfbGFzdF9lcnJvcl9mb3IoJGZuKTsKICAgICAgICAkbWV0YSAgICAgICAgPSBAc3RyZWFtX2dldF9tZXRhX2RhdGEoJHNvY2spOwogICAgICAgIGlmICgkbWV0YSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgJHRoaXMtPnRpbWVvdXQgPSAkbWV0YVsndGltZWRfb3V0J107CiAgICAgICAgICAgICR0aGlzLT5lb2YgICAgID0gJG1ldGFbJ2VvZiddOwogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPnRpbWVvdXQpIHsKICAgICAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdChzcHJpbnRmKCclcyBzb2NrZXQgdGltZW91dDogJXMnLCAkZm4sICR0aGlzLT5lcnJvcikpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5lb2YpIHsKICAgICAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdChzcHJpbnRmKCclcyBzb2NrZXQgZW9mOiAlcycsICRmbiwgJHRoaXMtPmVycm9yKSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdChzcHJpbnRmKCclcyBzb2NrZXQgZXJyb3I6ICVzJywgJGZuLCAkdGhpcy0+ZXJyb3IpKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfaHR0cF9vcGVuX3JlcXVlc3QnKSk6CmZ1bmN0aW9uIGNsb25lcl9odHRwX29wZW5fcmVxdWVzdCgkbWV0aG9kLCBDbG9uZXJVUkwgJHVybCwgYXJyYXkgJGhlYWRlciA9IGFycmF5KCksICR0aW1lb3V0ID0gNjAsICRjZXJ0ID0gJycpCnsKICAgICRob3N0UG9ydCA9ICR1cmwtPmdldEhvc3RQb3J0KCk7CiAgICBpZiAoc3RybGVuKCR1cmwtPmZyYWdtZW50KSkgewogICAgICAgICRwb3J0ICAgICA9IGVtcHR5KCR1cmwtPnBvcnQpID8gKCR1cmwtPnNlY3VyZSA/IDQ0MyA6IDgwKSA6ICR1cmwtPnBvcnQ7CiAgICAgICAgJGhvc3RQb3J0ID0gIiR1cmwtPmZyYWdtZW50OiRwb3J0IjsKICAgIH0KICAgICRzb2NrICAgID0gY2xvbmVyX3RjcF9zb2NrZXRfZGlhbCgkaG9zdFBvcnQsICR0aW1lb3V0LCAkdXJsLT5zZWN1cmUsICR1cmwtPmhvc3QsICRjZXJ0KTsKICAgICRyZXF1ZXN0ID0gYXJyYXkoCiAgICAgICAgc3ByaW50ZigiJXMgJXMlcyBIVFRQLzEuMSIsICRtZXRob2QsICR1cmwtPnBhdGgsIHN0cmxlbigkdXJsLT5xdWVyeSkgPyAiPyR1cmwtPnF1ZXJ5IiA6ICcnKSwKICAgICk7CiAgICBpZiAoc3RybGVuKCR1cmwtPnVzZXIpKSB7CiAgICAgICAgJGhlYWRlclsnYXV0aG9yaXphdGlvbiddID0gc3ByaW50ZignQmFzaWMgJXMnLCBiYXNlNjRfZW5jb2RlKCIkdXJsLT51c2VyOiR1cmwtPnBhc3MiKSk7CiAgICB9CiAgICBmb3JlYWNoICgkaGVhZGVyIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgICAgJHJlcXVlc3RbXSA9IHNwcmludGYoJyVzOiAlcycsICRrZXksICR2YWx1ZSk7CiAgICB9CiAgICBhcnJheV9wdXNoKCRyZXF1ZXN0LCAnJywgJycpOyAvLyBPdXRwdXQgXHJcblxyXG4gYXQgdGhlIGVuZCBhZnRlciBpbXBsb2RlLgogICAgc3RyZWFtX3NldF90aW1lb3V0KCRzb2NrLCAkdGltZW91dCk7CiAgICBpZiAoQGZ3cml0ZSgkc29jaywgaW1wbG9kZSgiXHJcbiIsICRyZXF1ZXN0KSkgPT09IGZhbHNlKSB7CiAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZndyaXRlJywgJHNvY2spOwogICAgfQogICAgcmV0dXJuICRzb2NrOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmNsb25lcm5ldGZ1bmN0aW9uZXhjZXB0aW9uJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyQ2xvbmVyTmV0RnVuY3Rpb25FeGNlcHRpb24gZXh0ZW5kcyBDbG9uZXJOZXRFeGNlcHRpb24KewogICAgcHVibGljICRmbiA9ICcnOwogICAgcHVibGljICRob3N0ID0gJyc7CiAgICBwdWJsaWMgJGVycm9yID0gJyc7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgJGZuICAgIE9uZSBvZiBzdHJlYW1fc29ja2V0X2NsaWVudCwgZnJlYWQgKG9uIHNvY2tldCksIGV0Yy4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAkaG9zdCAgUmVtb3RlIGhvc3QgYWRkcmVzcy4KICAgICAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkZXJyb3IgRXJyb3IgbWVzc2FnZSwgd2lsbCBhdXRvbWF0aWNhbGx5IGZldGNoIGZyb20gZXJyb3JfZ2V0X2xhc3QoKSBpZiBudWxsLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGZuLCAkaG9zdCwgJGVycm9yID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+Zm4gICA9ICRmbjsKICAgICAgICAkdGhpcy0+aG9zdCA9ICRob3N0OwogICAgICAgIGlmICgkZXJyb3IgPT09IG51bGwpIHsKICAgICAgICAgICAgJGVycm9yID0gY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCRmbik7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5lcnJvciA9ICRlcnJvcjsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KHNwcmludGYoJyVzIGVycm9yIGZvciBob3N0ICVzOiAlcycsICRmbiwgJGhvc3QsICR0aGlzLT5lcnJvcikpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9jdHlwZV94ZGlnaXQnKSk6CmZ1bmN0aW9uIGNsb25lcl9jdHlwZV94ZGlnaXQoJHRleHQpIHsKICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX3hkaWdpdCcpKSB7CiAgICAgICAgcmV0dXJuIGN0eXBlX3hkaWdpdCgkdGV4dCk7CiAgICB9CiAgICByZXR1cm4gKGJvb2wpcHJlZ19tYXRjaCgne15bXGRhLWZdKyR9aScsICR0ZXh0KTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfY2h1bmtlZF9yZWFkJykpOgpmdW5jdGlvbiBjbG9uZXJfY2h1bmtlZF9yZWFkKCRzb2NrLCAkdGltZW91dCkKewogICAgc3RyZWFtX3NldF90aW1lb3V0KCRzb2NrLCAkdGltZW91dCk7CiAgICAkYm9keSA9ICcnOwogICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAkbGVuZ3RoID0gQGZnZXRzKCRzb2NrKTsKICAgICAgICBpZiAoJGxlbmd0aCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZmdldHMnLCAkc29jayk7CiAgICAgICAgfQogICAgICAgICRsZW5ndGggPSBydHJpbSgkbGVuZ3RoLCAiXHJcbiIpOwogICAgICAgIGlmICghY2xvbmVyX2N0eXBlX3hkaWdpdCgkbGVuZ3RoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoJ0RpZCBub3QgZ2V0IGhleCBjaHVuayBsZW5ndGg6ICVzJywgJGxlbmd0aCkpOwogICAgICAgIH0KICAgICAgICAkbGVuZ3RoID0gaGV4ZGVjKCRsZW5ndGgpOwogICAgICAgICRnb3QgICAgPSAwOwogICAgICAgIHdoaWxlICgkZ290IDwgJGxlbmd0aCkgewogICAgICAgICAgICAkY2h1bmsgPSBAZnJlYWQoJHNvY2ssICRsZW5ndGggLSAkZ290KTsKICAgICAgICAgICAgaWYgKCRjaHVuayA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJOZXRTb2NrZXRFeGNlcHRpb24oJ2ZyZWFkJywgJHNvY2spOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRnb3QgICs9IHN0cmxlbigkY2h1bmspOwogICAgICAgICAgICAkYm9keSAuPSAkY2h1bms7CiAgICAgICAgfQogICAgICAgIC8vIEV2ZXJ5IGNodW5rIChpbmNsdWRpbmcgZmluYWwpIGlzIGZvbGxvd2VkIHVwIGJ5IGFuIGFkZGl0aW9uYWwgXHJcbi4KICAgICAgICBpZiAoKCR0bXAgPSBAZmdldHMoJHNvY2ssIDMpKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZmdldHMnLCAkc29jayk7CiAgICAgICAgfQogICAgICAgIGlmICgkdG1wICE9PSAiXHJcbiIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignRGlkIG5vdCBnZXQgZXhwZWN0ZWQgQ1JMRicpOwogICAgICAgIH0KICAgICAgICBpZiAoJGxlbmd0aCA9PT0gMCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gJGJvZHk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2N0eXBlX2RpZ2l0JykpOgpmdW5jdGlvbiBjbG9uZXJfY3R5cGVfZGlnaXQoJHRleHQpIHsKICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2N0eXBlX2RpZ2l0JykpIHsKICAgICAgICByZXR1cm4gY3R5cGVfZGlnaXQoJHRleHQpOwogICAgfQogICAgcmV0dXJuIChib29sKXByZWdfbWF0Y2goJ3teXGQrJH0nLCAkdGV4dCk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2xpbWl0X3JlYWQnKSk6CmZ1bmN0aW9uIGNsb25lcl9saW1pdF9yZWFkKCRzb2NrLCAkbGltaXQsICR0aW1lb3V0KQp7CiAgICBzdHJlYW1fc2V0X3RpbWVvdXQoJHNvY2ssICR0aW1lb3V0KTsKICAgICRib2R5ID0gJyc7CiAgICB3aGlsZSAoc3RybGVuKCRib2R5KSA8ICRsaW1pdCkgewogICAgICAgICRjaHVuayA9IEBmcmVhZCgkc29jaywgJGxpbWl0IC0gc3RybGVuKCRib2R5KSk7CiAgICAgICAgaWYgKCRjaHVuayA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZnJlYWQnLCAkdGhpcy0+Ym9keSk7CiAgICAgICAgfQogICAgICAgICRib2R5IC49ICRjaHVuazsKICAgIH0KICAgIHJldHVybiAkYm9keTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJodHRwcmVzcG9uc2UnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJIVFRQUmVzcG9uc2UKewogICAgcHVibGljICRzdGF0dXNDb2RlID0gMDsKICAgIHB1YmxpYyAkc3RhdHVzID0gJyc7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZ1tdIEluIGtleSA9PiB2YWx1ZSBmb3JtYXQuCiAgICAgKi8KICAgIHB1YmxpYyAkaGVhZGVycyA9IGFycmF5KCk7CiAgICAvKioKICAgICAqIEB2YXIgcmVzb3VyY2UKICAgICAqLwogICAgcHVibGljICRib2R5OwoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbVBhcnRzKCRzdGF0dXNDb2RlLCAkc3RhdHVzLCBhcnJheSAkaGVhZGVycywgJGJvZHkpCiAgICB7CiAgICAgICAgJHNlbGYgICAgICAgICAgICAgPSBuZXcgc2VsZigpOwogICAgICAgICRzZWxmLT5zdGF0dXNDb2RlID0gJHN0YXR1c0NvZGU7CiAgICAgICAgJHNlbGYtPnN0YXR1cyAgICAgPSAkc3RhdHVzOwogICAgICAgICRzZWxmLT5oZWFkZXJzICAgID0gJGhlYWRlcnM7CiAgICAgICAgJHNlbGYtPmJvZHkgICAgICAgPSAkYm9keTsKICAgICAgICByZXR1cm4gJHNlbGY7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICR0aW1lb3V0CiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqCiAgICAgKiBAdGhyb3dzIENsb25lckV4Y2VwdGlvbgogICAgICogQHRocm93cyBDbG9uZXJOZXRFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHJlYWQoJHRpbWVvdXQpCiAgICB7CiAgICAgICAgaWYgKGlzc2V0KCR0aGlzLT5oZWFkZXJzWyd0cmFuc2Zlci1lbmNvZGluZyddKSAmJiBzdHJ0b2xvd2VyKCR0aGlzLT5oZWFkZXJzWyd0cmFuc2Zlci1lbmNvZGluZyddKSA9PT0gJ2NodW5rZWQnKSB7CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfY2h1bmtlZF9yZWFkKCR0aGlzLT5ib2R5LCAkdGltZW91dCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmhlYWRlcnNbJ2Nvbm5lY3Rpb24nXSkgJiYgc3RydG9sb3dlcigkdGhpcy0+aGVhZGVyc1snY29ubmVjdGlvbiddKSA9PT0gJ2Nsb3NlJykgewogICAgICAgICAgICAkZGF0YSA9IEBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0aGlzLT5ib2R5KTsKICAgICAgICAgICAgaWYgKCRkYXRhID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignc3RyZWFtX2dldF9jb250ZW50cycsICR0aGlzLT5ib2R5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJGRhdGE7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNzZXQoJHRoaXMtPmhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ10pIHx8IGNsb25lcl9jdHlwZV9kaWdpdCgkdGhpcy0+aGVhZGVyc1snY29udGVudC1sZW5ndGgnXSkpIHsKICAgICAgICAgICAgJGxlbmd0aCA9IChpbnQpJHRoaXMtPmhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ107CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfbGltaXRfcmVhZCgkdGhpcy0+Ym9keSwgJGxlbmd0aCwgJHRpbWVvdXQpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbigiZ290IHVucmVjb2duaXplZCBIVFRQIHJlc3BvbnNlIGZvcm1hdCIpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9odHRwX2dldF9yZXNwb25zZV9oZWFkZXJzJykpOgpmdW5jdGlvbiBjbG9uZXJfaHR0cF9nZXRfcmVzcG9uc2VfaGVhZGVycygkc29jaywgJHRpbWVvdXQgPSA2MCkKewogICAgJHJlcyAgICAgICA9IG5ldyBDbG9uZXJIVFRQUmVzcG9uc2UoKTsKICAgICRyZXMtPmJvZHkgPSAkc29jazsKICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgc3RyZWFtX3NldF90aW1lb3V0KCRzb2NrLCAkdGltZW91dCk7CiAgICAgICAgaWYgKCgkbGluZSA9IEBmZ2V0cygkc29jaykpID09PSBmYWxzZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyTmV0U29ja2V0RXhjZXB0aW9uKCdmZ2V0cycsICRzb2NrKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRsaW5lID09PSAiXG4iIHx8ICRsaW5lID09PSAiXHJcbiIpIHsKICAgICAgICAgICAgaWYgKCRyZXMtPnN0YXR1c0NvZGUgPT09IDApIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJOZXRFeGNlcHRpb24oJ25ld2xpbmUgZW5jb3VudGVyZWQgYmVmb3JlIEhUVFAgcmVzcG9uc2UnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKCRyZXMtPnN0YXR1c0NvZGUgPT09IDApIHsKICAgICAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7XkhUVFAvXGRcLlxkIChcZHszfSkgKC4qKSR9JywgJGxpbmUsICRtYXRjaGVzKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCdpbnZhbGlkIGZpcnN0IHJlc3BvbnNlIGxpbmU6ICVzJywgJGxpbmUpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmVzLT5zdGF0dXNDb2RlID0gKGludCkkbWF0Y2hlc1sxXTsKICAgICAgICAgICAgJHJlcy0+c3RhdHVzICAgICA9IHRyaW0oJG1hdGNoZXNbMl0pOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJHBhcnRzID0gZXhwbG9kZSgnOicsICRsaW5lLCAyKTs7CiAgICAgICAgaWYgKGNvdW50KCRwYXJ0cykgIT09IDIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCdpbnZhbGlkIGhlYWRlciBsaW5lOiAlcycsICRsaW5lKSk7CiAgICAgICAgfQogICAgICAgICRyZXMtPmhlYWRlcnNbc3RydG9sb3dlcih0cmltKCRwYXJ0c1swXSkpXSA9IHRyaW0oJHBhcnRzWzFdKTsKICAgIH0KICAgIHJldHVybiAkcmVzOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9odHRwX2RvJykpOgpmdW5jdGlvbiBjbG9uZXJfaHR0cF9kbygkbWV0aG9kLCAkdXJsLCAkY29udGVudFR5cGUgPSAnJywgJGJvZHkgPSAnJywgJHRpbWVvdXQgPSA2MCkKewogICAgJGRlYWRsaW5lID0gdGltZSgpICsgJHRpbWVvdXQ7CiAgICAkdXJsICAgICAgPSBDbG9uZXJVUkw6OmZyb21TdHJpbmcoJHVybCk7CiAgICAkaGVhZGVycyAgPSBhcnJheSgKICAgICAgICAnY29udGVudC10eXBlJyAgID0+ICRjb250ZW50VHlwZSwKICAgICAgICAnY29ubmVjdGlvbicgICAgID0+ICdjbG9zZScsCiAgICAgICAgJ2NvbnRlbnQtbGVuZ3RoJyA9PiAoc3RyaW5nKXN0cmxlbigkYm9keSksCiAgICAgICAgJ2hvc3QnICAgICAgICAgICA9PiAkdXJsLT5nZXRIVFRQSG9zdCgpLAogICAgKTsKICAgICRzb2NrICAgICA9IGNsb25lcl9odHRwX29wZW5fcmVxdWVzdCgkbWV0aG9kLCAkdXJsLCAkaGVhZGVycywgJHRpbWVvdXQpOwogICAgaWYgKHN0cmxlbigkYm9keSkpIHsKICAgICAgICBzdHJlYW1fc2V0X3RpbWVvdXQoJHNvY2ssIG1heCgxLCAkZGVhZGxpbmUgLSB0aW1lKCkpKTsKICAgICAgICAkbiA9IEBmd3JpdGUoJHNvY2ssICRib2R5KTsKICAgICAgICBpZiAoJG4gPT09IGZhbHNlKSB7CiAgICAgICAgICAgIEBmY2xvc2UoJHNvY2spOwogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyQ2xvbmVyTmV0RnVuY3Rpb25FeGNlcHRpb24oJ2Z3cml0ZScsICR1cmwpOwogICAgICAgIH0KICAgIH0KICAgIHRyeSB7CiAgICAgICAgJHJlc3BvbnNlID0gY2xvbmVyX2h0dHBfZ2V0X3Jlc3BvbnNlX2hlYWRlcnMoJHNvY2ssIG1heCgxLCAkZGVhZGxpbmUgLSB0aW1lKCkpKS0+cmVhZChtYXgoMSwgJGRlYWRsaW5lIC0gdGltZSgpKSk7CiAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICBAZmNsb3NlKCRzb2NrKTsKICAgICAgICB0aHJvdyAkZTsKICAgIH0KICAgIEBmY2xvc2UoJHNvY2spOwogICAgcmV0dXJuICRyZXNwb25zZTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJzeW5jc3RhdGUnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJTeW5jU3RhdGUKewogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZyBBZGRyZXNzIHRvIGNvbm5lY3QgdG8gaW4gaG9zdDpwb3J0IGZvcm1hdC4KICAgICAqLwogICAgcHVibGljICRob3N0ID0gJyc7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZ1tdIEVzdGFibGlzaGVkIGNvbm5lY3Rpb24gSURzLgogICAgICovCiAgICBwdWJsaWMgJGhhdmVDb25ucyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAdmFyIHN0cmluZ1tdIENvbm5lY3Rpb24gSURzIHRoYXQgd2UgbmVlZCB0byBjcmVhdGUuCiAgICAgKi8KICAgIHB1YmxpYyAkd2FudENvbm5zID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEB2YXIgaW50CiAgICAgKi8KICAgIHB1YmxpYyAkdGltZXN0YW1wOwoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbUFycmF5KGFycmF5ICRkYXRhKSB7CiAgICAgICAgJHN0YXRlICAgICAgICAgICAgPSBuZXcgc2VsZigpOwogICAgICAgICRzdGF0ZS0+aG9zdCAgICAgID0gaXNzZXQoJGRhdGFbJ2hvc3QnXSkgPyAkZGF0YVsnaG9zdCddIDogJyc7CiAgICAgICAgJHN0YXRlLT5oYXZlQ29ubnMgPSBpc3NldCgkZGF0YVsnaGF2ZUNvbm5zJ10pID8gJGRhdGFbJ2hhdmVDb25ucyddIDogYXJyYXkoKTsKICAgICAgICAkc3RhdGUtPndhbnRDb25ucyA9IGlzc2V0KCRkYXRhWyd3YW50Q29ubnMnXSkgPyAkZGF0YVsnd2FudENvbm5zJ10gOiBhcnJheSgpOwogICAgICAgICRzdGF0ZS0+dGltZXN0YW1wID0gdGltZSgpOwogICAgICAgIHJldHVybiAkc3RhdGU7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3N0YXRlX3BvbGwnKSk6CmZ1bmN0aW9uIGNsb25lcl9zdGF0ZV9wb2xsKCR1cmwpIHsKICAgICRqc29uID0gY2xvbmVyX2h0dHBfZG8oJ0dFVCcsICR1cmwpOwogICAgJGRhdGEgPSBqc29uX2RlY29kZSgkanNvbiwgdHJ1ZSk7CiAgICBpZiAoIWlzX2FycmF5KCRkYXRhKSkgewogICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIm5vbi1qc29uIGdldC1zdGF0ZSByZXNwb25zZTogJGpzb24iKTsKICAgIH0KICAgIGlmICghZW1wdHkoJGRhdGFbJ2Vycm9yJ10pKSB7CiAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignUG9sbCBlcnJvcicsICRkYXRhWydlcnJvciddKTsKICAgIH0KICAgIHJldHVybiBDbG9uZXJTeW5jU3RhdGU6OmZyb21BcnJheSgkZGF0YSk7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVybm9jb25zdGFudGV4Y2VwdGlvbicsIGZhbHNlKSk6CmNsYXNzIENsb25lck5vQ29uc3RhbnRFeGNlcHRpb24gZXh0ZW5kcyBDbG9uZXJFeGNlcHRpb24KewogICAgcHVibGljICRjb25zdGFudCA9ICcnOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkY29uc3RhbnQsICRjb2RlID0gc2VsZjo6RVJST1JfVU5FWFBFQ1RFRCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29uc3RhbnQgPSAkY29uc3RhbnQ7CiAgICAgICAgcGFyZW50OjpfX2NvbnN0cnVjdCgiVGhlIHJlcXVpcmVkIGNvbnN0YW50ICRjb25zdGFudCBpcyBub3QgZGVmaW5lZCIsICRjb2RlKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfY29uc3RhbnQnKSk6CmZ1bmN0aW9uIGNsb25lcl9jb25zdGFudCgkbmFtZSkKewogICAgaWYgKCFkZWZpbmVkKCRuYW1lKSkgewogICAgICAgIHRocm93IG5ldyBDbG9uZXJOb0NvbnN0YW50RXhjZXB0aW9uKCRuYW1lKTsKICAgIH0KICAgIHJldHVybiBjb25zdGFudCgkbmFtZSk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2Vycm9yX3Jlc3VsdCcpKToKZnVuY3Rpb24gY2xvbmVyX2Vycm9yX3Jlc3VsdCgkY29kZSwgJG1lc3NhZ2UpIHsKICAgIGlmICghc3RybGVuKCRjb2RlKSkgewogICAgICAgICRjb2RlID0gJ3VuZXhwZWN0ZWRfZXJyb3InOwogICAgfQogICAgcmV0dXJuIGpzb25fZW5jb2RlKGFycmF5KAogICAgICAgICdvaycgICAgICA9PiBmYWxzZSwKICAgICAgICAnZXJyb3InICAgPT4gJGNvZGUsCiAgICAgICAgJ21lc3NhZ2UnID0+ICRtZXNzYWdlLAogICAgKSk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX29rX3Jlc3VsdCcpKToKZnVuY3Rpb24gY2xvbmVyX29rX3Jlc3VsdChhcnJheSAkcHJvcHMgPSBhcnJheSgpKSB7CiAgICByZXR1cm4ganNvbl9lbmNvZGUoYXJyYXlfbWVyZ2UoYXJyYXkoJ29rJyA9PiB0cnVlKSwgJHByb3BzKSk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3BhZ2Vfc3RhdGVfcG9sbCcpKToKZnVuY3Rpb24gY2xvbmVyX3BhZ2Vfc3RhdGVfcG9sbCgpIHsKICAgIHRyeSB7CiAgICAgICAgJHN0YXRlID0gY2xvbmVyX3N0YXRlX3BvbGwoY2xvbmVyX2NvbnN0YW50KCdDTE9ORVJfU1RBVEUnKSk7CiAgICB9IGNhdGNoIChDbG9uZXJFeGNlcHRpb24gJGUpIHsKICAgICAgICB0cmlnZ2VyX2Vycm9yKCRlLT5nZXRNZXNzYWdlKCkpOwogICAgICAgIGV4aXQoY2xvbmVyX2Vycm9yX3Jlc3VsdCgkZS0+Z2V0RXJyb3JDb2RlKCksICRlLT5nZXRNZXNzYWdlKCkpKTsKICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgIHRyaWdnZXJfZXJyb3IoJGUtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgZXhpdChjbG9uZXJfZXJyb3JfcmVzdWx0KCcnLCAkZS0+Z2V0TWVzc2FnZSgpKSk7CiAgICB9CgogICAgZXhpdChjbG9uZXJfb2tfcmVzdWx0KGFycmF5KCdzdGF0ZScgPT4gJHN0YXRlKSkpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9yZXR1cm5fZmFsc2UnKSk6CmZ1bmN0aW9uIGNsb25lcl9yZXR1cm5fZmFsc2UoKQp7CiAgICByZXR1cm4gZmFsc2U7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyd2Vic29ja2V0JywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyV2ViU29ja2V0CnsKICAgIHByaXZhdGUgJGFkZHIgPSAiIjsKICAgIHByaXZhdGUgJHBhdGggPSAiIjsKICAgIHByaXZhdGUgJGNvbm5UaW1lb3V0ID0gMTA7CiAgICBwcml2YXRlICRyd1RpbWVvdXQgPSAzMDsKICAgIHByaXZhdGUgJGhvc3QgPSAiIjsKICAgIHByaXZhdGUgJGNlcnQgPSAiIjsKICAgIHByaXZhdGUgJG9yaWdpbiA9ICIiOwogICAgcHJpdmF0ZSAkcHJvdG8gPSAiIjsKICAgIHByaXZhdGUgJG1hc2sgPSB0cnVlOwogICAgLyoqIEB2YXIgcmVzb3VyY2V8bnVsbCAqLwogICAgcHJpdmF0ZSAkY29ubjsKICAgIHByaXZhdGUgJG1heFBheWxvYWQgPSAxMzQyMTc3Mjg7IC8vIDEyOCA8PCAyMAogICAgcHJpdmF0ZSAkd3NWZXJzaW9uID0gMTM7CgogICAgc3RhdGljICRvcENvbnRpbnVhdGlvbiA9IDB4MDsKICAgIHN0YXRpYyAkb3BUZXh0ID0gMHgxOwogICAgc3RhdGljICRvcEJpbmFyeSA9IDB4MjsKICAgIHN0YXRpYyAkb3BDbG9zZSA9IDB4ODsKICAgIHN0YXRpYyAkb3BQaW5nID0gMHg5OwogICAgc3RhdGljICRvcFBvbmcgPSAweEE7CgogICAgY29uc3QgR1VJRCA9ICcyNThFQUZBNS1FOTE0LTQ3REEtOTVDQS1DNUFCMERDODVCMTEnOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYWRkciwgJHBhdGggPSAiIiwgJGNvbm5UaW1lb3V0ID0gMTAsICRyd1RpbWVvdXQgPSAzMCwgJGhvc3QgPSAibG9jYWxob3N0IiwgJG9yaWdpbiA9ICJsb2NhbGhvc3QiLCAkY2VydCA9ICIiLCAkcHJvdG8gPSAiIiwgJG1hc2sgPSB0cnVlKQogICAgewogICAgICAgICR0aGlzLT5hZGRyICAgICAgICA9ICRhZGRyOwogICAgICAgICR0aGlzLT5wYXRoICAgICAgICA9ICRwYXRoOwogICAgICAgICR0aGlzLT5jb25uVGltZW91dCA9ICRjb25uVGltZW91dDsKICAgICAgICAkdGhpcy0+cndUaW1lb3V0ICAgPSAkcndUaW1lb3V0OwogICAgICAgICR0aGlzLT5ob3N0ICAgICAgICA9ICRob3N0OwogICAgICAgICR0aGlzLT5vcmlnaW4gICAgICA9ICRvcmlnaW47CiAgICAgICAgJHRoaXMtPmNlcnQgICAgICAgID0gJGNlcnQ7CiAgICAgICAgJHRoaXMtPnByb3RvICAgICAgID0gJHByb3RvOwogICAgICAgICR0aGlzLT5tYXNrICAgICAgICA9ICRtYXNrOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqIEB0aHJvd3MgQ2xvbmVyTmV0RXhjZXB0aW9uCiAgICAgKiBAdGhyb3dzIENsb25lclVSTEV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gY29ubmVjdCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jb25uICE9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJGtleSAgICAgICAgPSBiYXNlNjRfZW5jb2RlKG1kNSh1bmlxaWQoIiIsIHRydWUpLCB0cnVlKSk7CiAgICAgICAgJGV4cGVjdEtleSAgPSBiYXNlNjRfZW5jb2RlKHNoYTEoJGtleS5zZWxmOjpHVUlELCB0cnVlKSk7CiAgICAgICAgJHBhdGggICAgICAgPSAkdGhpcy0+cGF0aCA/ICR0aGlzLT5wYXRoIDogIi8iOwogICAgICAgICRoZWFkZXJzICAgID0gYXJyYXkoCiAgICAgICAgICAgICdIb3N0JyAgICAgICAgICAgICAgICAgICA9PiAkdGhpcy0+aG9zdCwKICAgICAgICAgICAgJ0Nvbm5lY3Rpb24nICAgICAgICAgICAgID0+ICd1cGdyYWRlJywKICAgICAgICAgICAgJ1VwZ3JhZGUnICAgICAgICAgICAgICAgID0+ICdXZWJTb2NrZXQnLAogICAgICAgICAgICAnT3JpZ2luJyAgICAgICAgICAgICAgICAgPT4gJHRoaXMtPm9yaWdpbiwKICAgICAgICAgICAgJ1NlYy1XZWJTb2NrZXQtS2V5JyAgICAgID0+ICRrZXksCiAgICAgICAgICAgICdTZWMtV2ViU29ja2V0LVZlcnNpb24nICA9PiAkdGhpcy0+d3NWZXJzaW9uLAogICAgICAgICAgICAnU2VjLVdlYlNvY2tldC1Qcm90b2NvbCcgPT4gJHRoaXMtPnByb3RvLAogICAgICAgICk7CiAgICAgICAgJHRoaXMtPmNvbm4gPSBjbG9uZXJfaHR0cF9vcGVuX3JlcXVlc3QoJ0dFVCcsIENsb25lclVSTDo6ZnJvbVN0cmluZygkdGhpcy0+YWRkci4kcGF0aCksICRoZWFkZXJzLCAkdGhpcy0+Y29ublRpbWVvdXQsICR0aGlzLT5jZXJ0KTsKICAgICAgICAkcmVzICAgICAgICA9IGNsb25lcl9odHRwX2dldF9yZXNwb25zZV9oZWFkZXJzKCR0aGlzLT5jb25uLCAxMCk7CiAgICAgICAgaWYgKCRyZXMtPmhlYWRlcnNbInNlYy13ZWJzb2NrZXQtYWNjZXB0Il0gIT09ICRleHBlY3RLZXkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCJHb3QgV1Mga2V5ICVzLCBleHBlY3RlZCAlcyIsICRyZXMtPmhlYWRlcnNbInNlYy13ZWJzb2NrZXQtYWNjZXB0Il0sICRleHBlY3RLZXkpLCAnaW52YWxpZF93c19rZXknLCAkcmVzLT5oZWFkZXJzWyJzZWMtd2Vic29ja2V0LWFjY2VwdCJdKTsKICAgICAgICB9CiAgICAgICAgaWYgKHN0cmxlbigkdGhpcy0+cHJvdG8pKSB7CiAgICAgICAgICAgICRwcm90b3MgPSBhcnJheV9tYXAoJ3RyaW0nLCBleHBsb2RlKCIsIiwgJHJlcy0+aGVhZGVyc1sic2VjLXdlYnNvY2tldC1wcm90b2NvbCJdKSk7CiAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJHRoaXMtPnByb3RvLCAkcHJvdG9zKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCJOZWVkIHByb3RvY29sICVzLCBnb3QgJXMiLCAkdGhpcy0+cHJvdG8sICRyZXMtPmhlYWRlcnNbInNlYy13ZWJzb2NrZXQtcHJvdG9jb2wiXSksICdpbnZhbGlkX3dzX2tleScsICRyZXMtPmhlYWRlcnNbInNlYy13ZWJzb2NrZXQtcHJvdG9jb2wiXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICAgICRjb2RlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyZWFzb24KICAgICAqCiAgICAgKiBAdGhyb3dzIENsb25lckV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZGlzY29ubmVjdCgkY29kZSwgJHJlYXNvbikKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmNvbm4gPT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+d3JpdGVGcmFtZSh0cnVlLCBzZWxmOjokb3BDbG9zZSwgcGFjaygibiIsICRjb2RlKS4kcmVhc29uKTsKICAgICAgICBpZiAoQGZjbG9zZSgkdGhpcy0+Y29ubikgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJDbG9uZXJOZXRGdW5jdGlvbkV4Y2VwdGlvbignZmNsb3NlJywgJHRoaXMtPmhvc3QpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+Y29ubiA9IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5IDFzdCBlbGVtZW50IGlzIG51bGwgaWYgcG9uZywgc3RyaW5nIG90aGVyd2lzZS4gU2Vjb25kIGlzIHRydWUgaWYgdGhlIGNvbm5lY3Rpb24gaXMgY2xvc2VkLgogICAgICoKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZWFkTWVzc2FnZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jb25uID09PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIlNvY2tldCBub3QgY29ubmVjdGVkIik7CiAgICAgICAgfQogICAgICAgICRtZXNzYWdlICAgPSBudWxsOwogICAgICAgICRmaW4gICAgICAgPSBmYWxzZTsKICAgICAgICAkbWVzc2FnZU9wID0gMHgwOwogICAgICAgIHdoaWxlICghJGZpbikgewogICAgICAgICAgICBsaXN0KCRmaW4sICRvcCwgJGZyYW1lKSA9ICR0aGlzLT5yZWFkRnJhbWUoKTsKICAgICAgICAgICAgc3dpdGNoICgkb3ApIHsKICAgICAgICAgICAgICAgIGNhc2Ugc2VsZjo6JG9wQ29udGludWF0aW9uOgogICAgICAgICAgICAgICAgICAgIGlmICghJG1lc3NhZ2VPcCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCJDb250aW51YXRpb24gZnJhbWUgc2VudCBiZWZvcmUgaW5pdGlhbCBmcmFtZSIsICd3c19wcm90b2NvbF9lcnJvcicpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRtZXNzYWdlKSArIHN0cmxlbigkZnJhbWUpID4gJHRoaXMtPm1heFBheWxvYWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCJSZWFkIGJ1ZmZlciBmdWxsLCBtZXNzYWdlIGxlbmd0aDogJWQiLCBzdHJsZW4oJG1lc3NhZ2UpICsgc3RybGVuKCRmcmFtZSkpLCAnd3NfcmVhZF9idWZmZXJfZnVsbCcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAuPSAkZnJhbWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHNlbGY6OiRvcENsb3NlOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkZnJhbWUsIHRydWUpOwogICAgICAgICAgICAgICAgY2FzZSBzZWxmOjokb3BCaW5hcnk6CiAgICAgICAgICAgICAgICBjYXNlIHNlbGY6OiRvcFRleHQ6CiAgICAgICAgICAgICAgICAgICAgJG1lc3NhZ2VPcCA9ICRvcDsKICAgICAgICAgICAgICAgICAgICAkbWVzc2FnZSAgID0gJGZyYW1lOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBzZWxmOjokb3BQb25nOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoIlJlYWQgZmFpbGVkLCBpbnZhbGlkIG9wOiAlZCIsICRvcCksICd3c19wcm90b2NvbF9lcnJvcicpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBhcnJheSgkbWVzc2FnZSwgZmFsc2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheSBUcmlwbGV0IG9mIGZpbjpib29sLCBvcDppbnQsIG1lc3NhZ2U6c3RyaW5nLgogICAgICoKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gcmVhZEZyYW1lKCkKICAgIHsKICAgICAgICBzdHJlYW1fc2V0X3RpbWVvdXQoJHRoaXMtPmNvbm4sICR0aGlzLT5yd1RpbWVvdXQpOwogICAgICAgIC8vICRiMSA9IHwgRklOIHxSU1YxIHxSU1YyIHxSU1YzIHwgT1AxIHwgT1AyIHwgT1AzIHwgT1A0IHwKICAgICAgICAvLyAgICAgICB8IDAvMSB8ICAwICB8ICAwICB8ICAwICB8ICBuMSB8ICBuMiB8ICBuMyB8ICBuNCB8CiAgICAgICAgaWYgKCgkYjEgPSBAZnJlYWQoJHRoaXMtPmNvbm4sIDEpKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZnJlYWQnLCAkdGhpcy0+Y29ubik7CiAgICAgICAgfQogICAgICAgICRtZXRhID0gc3RyZWFtX2dldF9tZXRhX2RhdGEoJHRoaXMtPmNvbm4pOwogICAgICAgIGlmICghZW1wdHkoJG1ldGFbInRpbWVkX291dCJdKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCJGaXJzdCBieXRlIHJlYWQgdGltZW91dCIsICd3c19yZWFkX3RpbWVvdXQnKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFlbXB0eSgkbWV0YVsiZW9mIl0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIkNvbm5lY3Rpb24gY2xvc2VkIiwgJ3dzX2Nsb3NlZCcpOwogICAgICAgIH0KICAgICAgICAkYjEgID0gb3JkKCRiMSk7CiAgICAgICAgJGZpbiA9IChib29sKSgkYjEgJiAweDgwIC8qMTAwMDAwMDAqLyk7CiAgICAgICAgaWYgKCgkYjEgJiAweDcwIC8qMDExMTAwMDAqLykgIT09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbigiUmVzZXJ2ZWQgYml0cyBwcmVzZW50IiwgJ3dzX3Byb3RvY29sX2Vycm9yJyk7CiAgICAgICAgfQogICAgICAgICRvcCA9ICRiMSAmIDB4RjsgLy8gMDAwMDExMTEKICAgICAgICAvLyAkYjIgPSB8TUFTSyB8IFBheWxvYWQgbGVuZ3RoICg3IGJpdHMpICAgICAgICAgICAgICAgICB8CiAgICAgICAgLy8gICAgICAgfCAwLzEgfCAgbjEgfCAgbjIgfCAgbjMgfCAgbjQgfCAgbjUgfCAgbjYgfCBuNyAgfAogICAgICAgIGlmICgoJGIyID0gQGZyZWFkKCR0aGlzLT5jb25uLCAxKSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJOZXRTb2NrZXRFeGNlcHRpb24oJ2ZyZWFkJywgJHRoaXMtPmNvbm4pOwogICAgICAgIH0KICAgICAgICAkYjIgICAgID0gb3JkKCRiMik7CiAgICAgICAgJG1hc2tlZCA9ICRiMiAmIDB4ODA7IC8vIDEwMDAwMDAwCiAgICAgICAgJGxlbiAgICA9ICRiMiAmIDB4N0Y7IC8vIDAxMTExMTExCiAgICAgICAgaWYgKCRsZW4gPT09IDEyNiAvKjAxMTExMTEwKi8pIHsKICAgICAgICAgICAgaWYgKCgkcGF5bG9hZExlbiA9IEBmcmVhZCgkdGhpcy0+Y29ubiwgMikpID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZnJlYWQnLCAkdGhpcy0+Y29ubik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHVucGFja2VkID0gdW5wYWNrKCJuIiwgJHBheWxvYWRMZW4pOwogICAgICAgICAgICAkbGVuICAgICAgPSBlbmQoJHVucGFja2VkKTsKICAgICAgICB9IGVsc2VpZiAoJGxlbiA9PT0gMTI3IC8qMDExMTExMTEqLykgewogICAgICAgICAgICBpZiAoKCRwYXlsb2FkTGVuID0gQGZyZWFkKCR0aGlzLT5jb25uLCA4KSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyTmV0U29ja2V0RXhjZXB0aW9uKCdmcmVhZCcsICR0aGlzLT5jb25uKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbGVuID0gJHRoaXMtPnVubWFyc2hhbFVJbnQ2NCgkcGF5bG9hZExlbik7CiAgICAgICAgfQogICAgICAgIGlmICgkbGVuID4gJHRoaXMtPm1heFBheWxvYWQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCJSZWFkIGJ1ZmZlciBmdWxsLCBmcmFtZSBsZW5ndGg6ICVkIiwgJGxlbiksICd3c19yZWFkX2J1ZmZlcl9mdWxsJyk7CiAgICAgICAgfQogICAgICAgICRtYXNrID0gIiI7CiAgICAgICAgaWYgKCRtYXNrZWQgJiYgKCgkbWFzayA9IEBmcmVhZCgkdGhpcy0+Y29ubiwgNCkpID09PSBmYWxzZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZnJlYWQnLCAkdGhpcy0+Y29ubik7CiAgICAgICAgfQogICAgICAgICRtZXNzYWdlID0gIiI7CiAgICAgICAgJHRvUmVhZCAgPSAkbGVuOwogICAgICAgIHdoaWxlICgkdG9SZWFkID4gMCkgewogICAgICAgICAgICAkY2h1bmsgPSBAZnJlYWQoJHRoaXMtPmNvbm4sICR0b1JlYWQpOwogICAgICAgICAgICBpZiAoJGNodW5rID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZnJlYWQnLCAkdGhpcy0+Y29ubik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRtYXNrICE9PSAiIikgewogICAgICAgICAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgc3RybGVuKCRjaHVuayk7ICRpKyspIHsKICAgICAgICAgICAgICAgICAgICAkY2h1bmtbJGldID0gJGNodW5rWyRpXSBeICRtYXNrWyRpICUgNF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJG1lc3NhZ2UgLj0gJGNodW5rOwogICAgICAgICAgICAkdG9SZWFkICAtPSBzdHJsZW4oJGNodW5rKTsKICAgICAgICB9CiAgICAgICAgJG1ldGEgPSBzdHJlYW1fZ2V0X21ldGFfZGF0YSgkdGhpcy0+Y29ubik7CiAgICAgICAgaWYgKCFlbXB0eSgkbWV0YVsidGltZWRfb3V0Il0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIkNodW5rIHJlYWQgdGltZW91dCIsICd3c19yZWFkX3RpbWVvdXQnKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFlbXB0eSgkbWV0YVsiZW9mIl0pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIkNvbm5lY3Rpb24gY2xvc2VkIiwgJ3dzX2Nsb3NlZCcpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYXJyYXkoJGZpbiwgJG9wLCAkbWVzc2FnZSk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBtYXJzaGFsVUludDY0KCR2YWx1ZSkKICAgIHsKICAgICAgICBpZiAoc3RybGVuKFBIUF9JTlRfTUFYKSA9PT0gMTkpIHsKICAgICAgICAgICAgJGhpZ2hlciA9ICgkdmFsdWUgJiAweGZmZmZmZmZmMDAwMDAwMDApID4+IDMyOwogICAgICAgICAgICAkbG93ZXIgID0gJHZhbHVlICYgMHgwMDAwMDAwMGZmZmZmZmZmOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRoaWdoZXIgPSAwOwogICAgICAgICAgICAkbG93ZXIgID0gJHZhbHVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGFjaygnTk4nLCAkaGlnaGVyLCAkbG93ZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGludCAkcGFja2VkCiAgICAgKgogICAgICogQHJldHVybiBpbnQKICAgICAqCiAgICAgKiBAdGhyb3dzIENsb25lckV4Y2VwdGlvbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIHVubWFyc2hhbFVJbnQ2NCgkcGFja2VkKQogICAgewogICAgICAgIGxpc3QoJGhpZ2hlciwgJGxvd2VyKSA9IGFycmF5X3ZhbHVlcyh1bnBhY2soJ04yJywgJHBhY2tlZCkpOwogICAgICAgIGlmICgkaGlnaGVyICE9PSAwICYmIHN0cmxlbihQSFBfSU5UX01BWCkgIT09IDE5KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIlBheWxvYWQgdG9vIGJpZyBmb3IgMzJiaXQgYXJjaGl0ZWN0dXJlIiwgJ25vXzY0Yml0X3N1cHBvcnQnKTsKICAgICAgICB9CiAgICAgICAgJHZhbHVlID0gJGhpZ2hlciA8PCAzMiB8ICRsb3dlcjsKICAgICAgICBpZiAoJHZhbHVlIDwgMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdub191aW50NjRfc3VwcG9ydCcpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkbWVzc2FnZQogICAgICoKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZU1lc3NhZ2UoJG1lc3NhZ2UsICRiaW5hcnkgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPmNvbm4gPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbigiU29ja2V0IG5vdCBjb25uZWN0ZWQiKTsKICAgICAgICB9CiAgICAgICAgJG9mZnNldCA9IDA7CiAgICAgICAgJGxlbiAgICA9IHN0cmxlbigkbWVzc2FnZSk7CiAgICAgICAgd2hpbGUgKCRvZmZzZXQgPCAkbGVuKSB7CiAgICAgICAgICAgICRmcmFtZSAgPSBzdWJzdHIoJG1lc3NhZ2UsICRvZmZzZXQsIG1pbigkbGVuIC0gJG9mZnNldCwgMSA8PCAyMCkpOwogICAgICAgICAgICAkb3AgICAgID0gJG9mZnNldCA9PT0gMCA/ICgkYmluYXJ5ID8gMHgyIDogMHgxKSA6IDB4MDsKICAgICAgICAgICAgJG9mZnNldCArPSBzdHJsZW4oJGZyYW1lKTsKICAgICAgICAgICAgJGZpbiAgICA9ICRvZmZzZXQgPj0gJGxlbjsKICAgICAgICAgICAgJHRoaXMtPndyaXRlRnJhbWUoJGZpbiwgJG9wLCAkZnJhbWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBib29sICAgJGZpbgogICAgICogQHBhcmFtIGludCAgICAkb3AKICAgICAqIEBwYXJhbSBzdHJpbmcgJGZyYW1lCiAgICAgKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiB3cml0ZUZyYW1lKCRmaW4sICRvcCwgJGZyYW1lKQogICAgewogICAgICAgICRtYXNrID0gJGxlbkxlbiA9ICIiOwogICAgICAgICRiMSAgID0gKCRmaW4gPyAweDgwIDogMHgwMCkgfCAkb3A7CiAgICAgICAgJGIyICAgPSAkdGhpcy0+bWFzayA/IDB4ODAgOiAweDAwOwogICAgICAgICRsZW4gID0gc3RybGVuKCRmcmFtZSk7CiAgICAgICAgaWYgKCRsZW4gPiA2NTUzNSkgewogICAgICAgICAgICAkYjIgICAgIHw9IDB4N2Y7CiAgICAgICAgICAgICRsZW5MZW4gPSAkdGhpcy0+bWFyc2hhbFVJbnQ2NCgkbGVuKTsKICAgICAgICB9IGVsc2VpZiAoJGxlbiA+PSAxMjYpIHsKICAgICAgICAgICAgJGIyICAgICB8PSAweDdlOwogICAgICAgICAgICAkbGVuTGVuID0gcGFjaygibiIsICRsZW4pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRiMiB8PSAkbGVuOwogICAgICAgIH0KICAgICAgICBpZiAoJHRoaXMtPm1hc2spIHsKICAgICAgICAgICAgJG1hc2sgPSBwYWNrKCJubiIsIG10X3JhbmQoMCwgMHhmZmZmKSwgbXRfcmFuZCgwLCAweGZmZmYpKTsKICAgICAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgc3RybGVuKCRmcmFtZSk7ICRpKyspIHsKICAgICAgICAgICAgICAgICRmcmFtZVskaV0gPSAkZnJhbWVbJGldIF4gJG1hc2tbJGkgJSA0XTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkc2VuZCA9IHBhY2soIkNDIiwgJGIxLCAkYjIpLiRsZW5MZW4uJG1hc2suJGZyYW1lOwogICAgICAgIHVuc2V0KCRmcmFtZSk7CiAgICAgICAgc3RyZWFtX3NldF90aW1lb3V0KCR0aGlzLT5jb25uLCAkdGhpcy0+cndUaW1lb3V0KTsKICAgICAgICBpZiAoKCR3cml0dGVuID0gQGZ3cml0ZSgkdGhpcy0+Y29ubiwgJHNlbmQpKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZndyaXRlJywgJHRoaXMtPmNvbm4pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gX19kZXN0cnVjdCgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jb25uID09PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGNvZGUgICA9IDEwMDA7CiAgICAgICAgICAgICRyZWFzb24gPSAnZGlzY29ubmVjdGVkIGJ5IGNsaWVudCc7CiAgICAgICAgICAgICRlcnJvciAgPSBlcnJvcl9nZXRfbGFzdCgpOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRlcnJvclsnbWVzc2FnZSddKSAmJiBpbl9hcnJheSgkZXJyb3JbJ3R5cGUnXSwgYXJyYXkoRV9QQVJTRSwgRV9FUlJPUiwgRV9DT1JFX0VSUk9SLCBFX0NPTVBJTEVfRVJST1IsIEVfUkVDT1ZFUkFCTEVfRVJST1IpKSkgewogICAgICAgICAgICAgICAgJGNvZGUgICA9IDEwMDE7CiAgICAgICAgICAgICAgICAkcmVhc29uID0gJGVycm9yWydtZXNzYWdlJ107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHRoaXMtPmRpc2Nvbm5lY3QoJGNvZGUsICRyZWFzb24pOwogICAgICAgIH0gY2F0Y2ggKENsb25lckV4Y2VwdGlvbiAkZSkgewogICAgICAgIH0KICAgIH0KfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJ3ZWJzb2NrZXRzdHJlYW0nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJXZWJTb2NrZXRTdHJlYW0gaW1wbGVtZW50cyBDbG9uZXJTdHJlYW0KewogICAgcHJpdmF0ZSAkd3M7CiAgICBwcml2YXRlICRyZXF1ZXN0SUQgPSAnJzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBDbG9uZXJXZWJTb2NrZXQgJHdzCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICRyZXF1ZXN0SUQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KENsb25lcldlYlNvY2tldCAkd3MsICRyZXF1ZXN0SUQpCiAgICB7CiAgICAgICAgJHRoaXMtPndzICAgICAgICA9ICR3czsKICAgICAgICAkdGhpcy0+cmVxdWVzdElEID0gJHJlcXVlc3RJRDsKICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiB3cml0ZSgkZGF0YSkKICAgIHsKICAgICAgICAkdGhpcy0+d3MtPndyaXRlTWVzc2FnZSgkdGhpcy0+cmVxdWVzdElELiRkYXRhLCB0cnVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBwcm9ncmVzcygkbWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+d3MtPndyaXRlTWVzc2FnZSgkdGhpcy0+cmVxdWVzdElELic7Jy5jbG9uZXJfanNvbl9lbmNvZGUoJG1lc3NhZ2UpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiByZXN1bHQoJHJlc3VsdCwgRXhjZXB0aW9uICRlID0gbnVsbCkKICAgIHsKICAgICAgICAkdHlwZSAgID0gJy4nOwogICAgICAgICRlbmNvZGUgPSAkcmVzdWx0OwogICAgICAgIGlmICgkZSAhPT0gbnVsbCkgewogICAgICAgICAgICAkdHlwZSAgID0gJyEnOwogICAgICAgICAgICAkZW5jb2RlID0gY2xvbmVyX2V4Y2VwdGlvbl90b19yZXN1bHQoJGUpOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+d3MtPndyaXRlTWVzc2FnZSgkdGhpcy0+cmVxdWVzdElELiR0eXBlLmNsb25lcl9qc29uX2VuY29kZSgkZW5jb2RlKSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl9waW5nJykpOgpmdW5jdGlvbiBjbG9uZXJfYWN0aW9uX3BpbmcoKQp7CiAgICByZXR1cm4gInBvbmciOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9lbmNvZGVfbm9uX3V0ZjgnKSk6CmZ1bmN0aW9uIGNsb25lcl9lbmNvZGVfbm9uX3V0ZjgoJHApIHsKICAgIHN0YXRpYyAkZmlyc3Q7CiAgICBpZiAoJGZpcnN0ID09PSBudWxsKSB7CiAgICAgICAgJHh4ICAgID0gMHhGMTsgLy8gaW52YWxpZDogc2l6ZSAxCiAgICAgICAgJGFzICAgID0gMHhGMDsgLy8gQVNDSUk6IHNpemUgMQogICAgICAgICRzMSAgICA9IDB4MDI7IC8vIGFjY2VwdCAwLCBzaXplIDIKICAgICAgICAkczIgICAgPSAweDEzOyAvLyBhY2NlcHQgMSwgc2l6ZSAzCiAgICAgICAgJHMzICAgID0gMHgwMzsgLy8gYWNjZXB0IDAsIHNpemUgMwogICAgICAgICRzNCAgICA9IDB4MjM7IC8vIGFjY2VwdCAyLCBzaXplIDMKICAgICAgICAkczUgICAgPSAweDM0OyAvLyBhY2NlcHQgMywgc2l6ZSA0CiAgICAgICAgJHM2ICAgID0gMHgwNDsgLy8gYWNjZXB0IDAsIHNpemUgNAogICAgICAgICRzNyAgICA9IDB4NDQ7IC8vIGFjY2VwdCA0LCBzaXplIDQKICAgICAgICAkZmlyc3QgPSBhcnJheSgKICAgICAgICAgICAgLy8gICAxICAgMiAgIDMgICA0ICAgNSAgIDYgICA3ICAgOCAgIDkgICBBICAgQiAgIEMgICBEICAgRSAgIEYKICAgICAgICAgICAgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAvLyAweDAwLTB4MEYKICAgICAgICAgICAgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAvLyAweDEwLTB4MUYKICAgICAgICAgICAgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAvLyAweDIwLTB4MkYKICAgICAgICAgICAgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAvLyAweDMwLTB4M0YKICAgICAgICAgICAgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAvLyAweDQwLTB4NEYKICAgICAgICAgICAgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAvLyAweDUwLTB4NUYKICAgICAgICAgICAgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAvLyAweDYwLTB4NkYKICAgICAgICAgICAgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAvLyAweDcwLTB4N0YKICAgICAgICAgICAgLy8gICAxICAgMiAgIDMgICA0ICAgNSAgIDYgICA3ICAgOCAgIDkgICBBICAgQiAgIEMgICBEICAgRSAgIEYKICAgICAgICAgICAgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAvLyAweDgwLTB4OEYKICAgICAgICAgICAgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAvLyAweDkwLTB4OUYKICAgICAgICAgICAgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAvLyAweEEwLTB4QUYKICAgICAgICAgICAgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAvLyAweEIwLTB4QkYKICAgICAgICAgICAgJHh4LCAkeHgsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAvLyAweEMwLTB4Q0YKICAgICAgICAgICAgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAvLyAweEQwLTB4REYKICAgICAgICAgICAgJHMyLCAkczMsICRzMywgJHMzLCAkczMsICRzMywgJHMzLCAkczMsICRzMywgJHMzLCAkczMsICRzMywgJHMzLCAkczQsICRzMywgJHMzLCAvLyAweEUwLTB4RUYKICAgICAgICAgICAgJHM1LCAkczYsICRzNiwgJHM2LCAkczcsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAvLyAweEYwLTB4RkYKICAgICAgICApOwogICAgfQogICAgc3RhdGljICR4eCA9IDB4RjE7CiAgICBzdGF0aWMgJGxvY2IgPSAweDgwOwogICAgc3RhdGljICRoaWNiID0gMHhCRjsKICAgIHN0YXRpYyAkYWNjZXB0UmFuZ2VzOwogICAgaWYgKCRhY2NlcHRSYW5nZXMgPT09IG51bGwpIHsKICAgICAgICAkYWNjZXB0UmFuZ2VzID0gYXJyYXkoCiAgICAgICAgICAgIDAgPT4gYXJyYXkoJGxvY2IsICRoaWNiKSwKICAgICAgICAgICAgMSA9PiBhcnJheSgweEEwLCAkaGljYiksCiAgICAgICAgICAgIDIgPT4gYXJyYXkoJGxvY2IsIDB4OUYpLAogICAgICAgICAgICAzID0+IGFycmF5KDB4OTAsICRoaWNiKSwKICAgICAgICAgICAgNCA9PiBhcnJheSgkbG9jYiwgMHg4RiksCiAgICAgICAgKTsKICAgIH0KICAgICRwZXJjZW50ID0gb3JkKCclJyk7CiAgICAkcGx1cyAgICA9IG9yZCgnKycpOwogICAgJGVuY29kZWQgPSBmYWxzZTsKICAgICRmaXhlZCAgID0gJyc7CiAgICAkbiAgICAgICA9IHN0cmxlbigkcCk7CiAgICAkaW52YWxpZCA9IGZhbHNlOwogICAgZm9yICgkaSA9IDA7ICRpIDwgJG47KSB7CiAgICAgICAgaWYgKCRpbnZhbGlkKSB7CiAgICAgICAgICAgIGlmICghJGVuY29kZWQpIHsKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0ICJ1cmxkZWNvZGUiIGNhbGwgdHJhbnNmb3JtcyB0aGUgc3RyaW5nIHRvIGl0cyBvcmlnaW5hbCBmb3JtLgogICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgZW5jb2RlIHByaW50YWJsZSBjaGFyYWN0ZXJzLCBvbmx5IGludmFsaWQgVVRGLTg7IGJ1dCB0aGVzZSBjaGFyYWN0ZXJzCiAgICAgICAgICAgICAgICAvLyB3aWxsIGFsd2F5cyBiZSBwcm9jZXNzZWQgYnkgVVJMLWRlY29kZXIuCiAgICAgICAgICAgICAgICAkZml4ZWQgPSBzdHJ0cigkZml4ZWQsIGFycmF5KCclJyA9PiAnJTI1JywgJysnID0+ICclMkInKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVuY29kZWQgPSB0cnVlOwogICAgICAgICAgICAkZml4ZWQgICAuPSB1cmxlbmNvZGUoJHBbJGldKTsKICAgICAgICAgICAgJGludmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgJGkrKzsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRwaSA9IG9yZCgkcFskaV0pOwogICAgICAgIGlmICgkcGkgPCAweDgwKSB7CiAgICAgICAgICAgIGlmICgkZW5jb2RlZCAmJiAkcGkgPT09ICRwZXJjZW50KSB7CiAgICAgICAgICAgICAgICAkZml4ZWQgLj0gJyUyNSc7CiAgICAgICAgICAgIH0gZWxzZWlmICgkZW5jb2RlZCAmJiAkcGkgPT09ICRwbHVzKSB7CiAgICAgICAgICAgICAgICAkZml4ZWQgLj0gJyUyQic7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkZml4ZWQgLj0gJHBbJGldOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRpKys7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAkeCA9ICRmaXJzdFskcGldOwogICAgICAgIGlmICgkeCA9PT0gJHh4KSB7CiAgICAgICAgICAgICRpbnZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRzaXplID0gJHggJiA3OwogICAgICAgIGlmICgkaSArICRzaXplID4gJG4pIHsKICAgICAgICAgICAgJGludmFsaWQgPSB0cnVlOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJGFjY2VwdCA9ICRhY2NlcHRSYW5nZXNbJHggPj4gNF07CiAgICAgICAgaWYgKCgoJGMgPSBvcmQoJHBbJGkgKyAxXSkpIDwgJGFjY2VwdFswXSkgfHwgKCRhY2NlcHRbMV0gPCAkYykpIHsKICAgICAgICAgICAgJGludmFsaWQgPSB0cnVlOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9IGVsc2VpZiAoJHNpemUgPT09IDIpIHsKICAgICAgICB9IGVsc2VpZiAoKCgkYyA9IG9yZCgkcFskaSArIDJdKSkgPCAkbG9jYikgfHwgKCRoaWNiIDwgJGMpKSB7CiAgICAgICAgICAgICRpbnZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfSBlbHNlaWYgKCRzaXplID09PSAzKSB7CiAgICAgICAgfSBlbHNlaWYgKCgoJGMgPSBvcmQoJHBbJGkgKyAzXSkpIDwgJGxvY2IpIHx8ICgkaGljYiA8ICRjKSkgewogICAgICAgICAgICAkaW52YWxpZCA9IHRydWU7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAkZml4ZWQgLj0gc3Vic3RyKCRwLCAkaSwgJHNpemUpOwogICAgICAgICRpICAgICArPSAkc2l6ZTsKICAgIH0KICAgIHJldHVybiAkZml4ZWQ7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyc3RhdHJlc3VsdCcsIGZhbHNlKSk6CmNsYXNzIENsb25lclN0YXRSZXN1bHQKewogICAgcHVibGljICRzdGF0cyA9IGFycmF5KCk7CgogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZEZpbGUoJHBhdGgsICRlbmNvZGVkLCAkbW9kVGltZSwgJHNpemUsICRwZXJtaXNzaW9ucykKICAgIHsKICAgICAgICAkdGhpcy0+c3RhdHNbXSA9IGFycmF5KCdwJyA9PiBiYXNlNjRfZW5jb2RlKCRwYXRoKSwgJ24nID0+ICRlbmNvZGVkLCAncycgPT4gJHNpemUsICdtJyA9PiAkbW9kVGltZSwgJ2knID0+ICRwZXJtaXNzaW9ucyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZERpcigkcGF0aCwgJGVuY29kZWQsICRtb2RUaW1lLCAkcGVybWlzc2lvbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YXRzW10gPSBhcnJheSgncCcgPT4gYmFzZTY0X2VuY29kZSgkcGF0aCksICduJyA9PiAkZW5jb2RlZCwgJ2QnID0+IDEsICdtJyA9PiAkbW9kVGltZSwgJ2knID0+ICRwZXJtaXNzaW9ucyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZExpbmsoJHBhdGgsICRlbmNvZGVkLCAkcmVmZXJlbmNlLCAkcGVybWlzc2lvbnMpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YXRzW10gPSBhcnJheSgncCcgPT4gYmFzZTY0X2VuY29kZSgkcGF0aCksICduJyA9PiAkZW5jb2RlZCwgJ2QnID0+IDIsICdrJyA9PiBiYXNlNjRfZW5jb2RlKCRyZWZlcmVuY2UpLCAnaScgPT4gJHBlcm1pc3Npb25zKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYXBwZW5kRXJyb3IoJHBhdGgsICRlbmNvZGVkLCAkc3RhdHVzLCAkZXJyb3IgPSAnJykKICAgIHsKICAgICAgICAkdGhpcy0+c3RhdHNbXSA9IGFycmF5KCdwJyA9PiBiYXNlNjRfZW5jb2RlKCRwYXRoKSwgJ24nID0+ICRlbmNvZGVkLCAnbycgPT4gJHN0YXR1cywgJ2UnID0+IGNsb25lcl9lbmNvZGVfbm9uX3V0ZjgoJGVycm9yKSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyc3RhdHVzJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyU3RhdHVzCnsKICAgIGNvbnN0IE9LID0gMDsKICAgIGNvbnN0IElOX1BST0dSRVNTID0gMTsKICAgIGNvbnN0IE5PX1BBUkVOVCA9IDI7CiAgICBjb25zdCBJU19ESVIgPSAzOwogICAgY29uc3QgSVNfRklMRSA9IDQ7CiAgICBjb25zdCBTS0lQUEVEID0gNTsKICAgIGNvbnN0IEVSUk9SID0gNjsKICAgIGNvbnN0IFJFTU9URV9FUlJPUiA9IDc7CiAgICBjb25zdCBOT1RfVVRGOCA9IDg7CiAgICBjb25zdCBOT19GSUxFID0gOTsKICAgIGNvbnN0IEhBU0hfTUlTU0lORyA9IDEwOwogICAgY29uc3QgVVNFUl9TS0lQUEVEID0gMTE7CiAgICBjb25zdCBJTlZJU0lCTEUgPSAxMjsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJpbmNsdWRlcnVsZXMnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJJbmNsdWRlUnVsZXMKewogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRjb21waWxlZEluY2x1ZGVMaXN0ID0gJyc7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGNvbXBpbGVkSW52aXNpYmxlTGlzdCA9ICcnOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRjb21waWxlZFVzZXJFeGNsdWRlTGlzdCA9ICcnOwogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRjb21waWxlZFN5c3RlbUV4Y2x1ZGVMaXN0ID0gJyc7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGNvbXBpbGVkRmlsZUV4Y2x1ZGVMaXN0ID0gJyc7CiAgICAvKiogQHZhciBzdHJpbmcgKi8KICAgIHByaXZhdGUgJGNvbXBpbGVkRGlyRXhjbHVkZUxpc3QgPSAnJzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJGFkZFBhdGhzICAgICAgICBQYXRocyB0byBpbmNsdWRlLgogICAgICogQHBhcmFtIHN0cmluZyAkaGlkZVBhdGhzICAgICAgIFBhdGhzIHRoYXQgc2hvdWxkIGJlIGludmlzaWJsZSB0byB0aGUgdXNlciAoZWcuIHRoZSBjbG9uZXIucGhwIHNjcmlwdCBpdHNlbGYpLgogICAgICogQHBhcmFtIHN0cmluZyAkc2tpcFBhdGhzICAgICAgIFNraXAgZmlsZXMvZGlycyBhdCBleGFjdCBwYXRoIChwcm92aWRlZCBieSB1c2VyKS4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHNraXBTeXN0ZW1QYXRocyBTa2lwIGZpbGVzL2RpcnMgd2l0aCB0aGlzIG5hbWUgaW4gYW55IHN1YmRpcmVjdG9yeS4KICAgICAqIEBwYXJhbSBzdHJpbmcgJHNraXBGaWxlcyAgICAgICBTa2lwIGZpbGVzIGF0IGV4YWN0IHBhdGguCiAgICAgKiBAcGFyYW0gc3RyaW5nICRza2lwRGlycyAgICAgICAgU2tpcCBkaXJzIGF0IGV4YWN0IHBhdGguCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkYWRkUGF0aHMsICRoaWRlUGF0aHMsICRza2lwUGF0aHMsICRza2lwU3lzdGVtUGF0aHMsICRza2lwRmlsZXMsICRza2lwRGlycykgewogICAgICAgICR0aGlzLT5jb21waWxlZEluY2x1ZGVMaXN0ID0gJ3snLiRhZGRQYXRocy4nfWknOwogICAgICAgIGlmICgkaGlkZVBhdGhzKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21waWxlZEludmlzaWJsZUxpc3QgPSAneycuJGhpZGVQYXRocy4nfWknOwogICAgICAgIH0KICAgICAgICBpZiAoJHNraXBTeXN0ZW1QYXRocykgewogICAgICAgICAgICAkdGhpcy0+Y29tcGlsZWRTeXN0ZW1FeGNsdWRlTGlzdCA9ICd7Jy4kc2tpcFN5c3RlbVBhdGhzLid9aSc7CiAgICAgICAgfQogICAgICAgIGlmICgkc2tpcFBhdGhzKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21waWxlZFVzZXJFeGNsdWRlTGlzdCA9ICd7Jy4kc2tpcFBhdGhzLid9aSc7CiAgICAgICAgfQogICAgICAgIGlmICgkc2tpcEZpbGVzKSB7CiAgICAgICAgICAgICR0aGlzLT5jb21waWxlZEZpbGVFeGNsdWRlTGlzdCA9ICd7Jy4kc2tpcEZpbGVzLid9aSc7CiAgICAgICAgfQogICAgICAgIGlmICgkc2tpcERpcnMpIHsKICAgICAgICAgICAgJHRoaXMtPmNvbXBpbGVkRGlyRXhjbHVkZUxpc3QgPSAneycuJHNraXBEaXJzLid9aSc7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBpbmNsdWRlUGF0aCgkcGF0aCwgJGlzRGlyKSB7CiAgICAgICAgaWYgKCRwYXRoID09PSAnLicpIHsKICAgICAgICAgICAgcmV0dXJuIENsb25lclN0YXR1czo6T0s7CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+Y29tcGlsZWRJbnZpc2libGVMaXN0ICYmIHByZWdfbWF0Y2goJHRoaXMtPmNvbXBpbGVkSW52aXNpYmxlTGlzdCwgJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiBDbG9uZXJTdGF0dXM6OklOVklTSUJMRTsKICAgICAgICB9CiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCR0aGlzLT5jb21waWxlZEluY2x1ZGVMaXN0LCAkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuIENsb25lclN0YXR1czo6U0tJUFBFRDsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5jb21waWxlZFN5c3RlbUV4Y2x1ZGVMaXN0ICYmIHByZWdfbWF0Y2goJHRoaXMtPmNvbXBpbGVkU3lzdGVtRXhjbHVkZUxpc3QsICRwYXRoLCAkbSkpIHsKICAgICAgICAgICAgcmV0dXJuIENsb25lclN0YXR1czo6U0tJUFBFRDsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5jb21waWxlZFVzZXJFeGNsdWRlTGlzdCAmJiBwcmVnX21hdGNoKCR0aGlzLT5jb21waWxlZFVzZXJFeGNsdWRlTGlzdCwgJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiBDbG9uZXJTdGF0dXM6OlVTRVJfU0tJUFBFRDsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5jb21waWxlZEZpbGVFeGNsdWRlTGlzdCAmJiAhJGlzRGlyICYmIHByZWdfbWF0Y2goJHRoaXMtPmNvbXBpbGVkRmlsZUV4Y2x1ZGVMaXN0LCAkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuIENsb25lclN0YXR1czo6U0tJUFBFRDsKICAgICAgICB9CiAgICAgICAgaWYgKCR0aGlzLT5jb21waWxlZERpckV4Y2x1ZGVMaXN0ICYmICRpc0RpciAmJiBwcmVnX21hdGNoKCR0aGlzLT5jb21waWxlZERpckV4Y2x1ZGVMaXN0LCAkcGF0aCkpIHsKICAgICAgICAgICAgcmV0dXJuIENsb25lclN0YXR1czo6U0tJUFBFRDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIENsb25lclN0YXR1czo6T0s7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyZnN2aXNpdG9yJywgZmFsc2UpKToKaW50ZXJmYWNlIENsb25lckZTVmlzaXRvcgp7CiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAkcGF0aCBQYXRoIHJlbGF0aXZlIHRvIHJvb3QuCiAgICAgKiBAcGFyYW0gQ2xvbmVyU3RhdEluZm8gJHN0YXQgU3RhdCByZXN1bHQgb2YgcGF0aC4KICAgICAqIEBwYXJhbSBFeGNlcHRpb258bnVsbCAkZSAgICBFcnJvciBkdXJpbmcgc3RhdCBvciByZWFkZGlyIG9mICRwYXRoLgogICAgICoKICAgICAqIEByZXR1cm4gYm9vbCBUcnVlIHRvIGNvbnRpbnVlIGl0ZXJhdGlvbiwgZmFsc2UgdG8gc3RvcCBhbmQgcmV0dXJuIHRoZSBmaWxlJ3MgcGF0aCBhcyBjdXJzb3IgdG8gcG90ZW50aWFsbHkgY29udGludWUgZnJvbS4KICAgICAqCiAgICAgKiBAdGhyb3dzIENsb25lclNraXBWaXNpdEV4Y2VwdGlvbiBJZiB0aGUgZGlyZWN0b3J5IHNob3VsZCBub3QgYmUgdHJhdmVyc2VkLiBObyByZWFsIGVmZmVjdCBpZiB2aXNpdGluZyBhIGZpbGUsIHNpbmNlIGl0cyBzaWJsaW5nIGNvbWVzIG5leHQuCiAgICAgKiBAdGhyb3dzIEV4Y2VwdGlvbiBUbyBhYm9ydCBleGVjdXRpb24gYW5kIHByb3BhZ2F0ZSB0aGUgZXhjZXB0aW9uLgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gdmlzaXQoJHBhdGgsIENsb25lclN0YXRJbmZvICRzdGF0LCBFeGNlcHRpb24gJGUgPSBudWxsKTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJza2lwdmlzaXRleGNlcHRpb24nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJTa2lwVmlzaXRFeGNlcHRpb24gZXh0ZW5kcyBDbG9uZXJFeGNlcHRpb24KewogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCkKICAgIHsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCJJbnRlcm5hbCBleGNlcHRpb24sIHNraXAgZmlsZSIpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9pbnRfbGVuJykpOgpmdW5jdGlvbiBjbG9uZXJfaW50X2xlbigkaW50KSB7CiAgICByZXR1cm4gKGludClmbG9vcihsb2cxMCgkaW50KSkgKyAxOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnN0YXR2aXNpdG9yJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyU3RhdFZpc2l0b3IgaW1wbGVtZW50cyBDbG9uZXJGU1Zpc2l0b3IKewogICAgLyoqIEB2YXIgQ2xvbmVyU3RhdFJlc3VsdCAqLwogICAgcHVibGljICRyZXN1bHQ7CiAgICBwcm90ZWN0ZWQgJG1heENvdW50ID0gMDsKICAgIHByb3RlY3RlZCAkbWF4UGF5bG9hZCA9IDA7CiAgICBwcm90ZWN0ZWQgJGRlYWRsaW5lID0gMDsKICAgIHByb3RlY3RlZCAkcGF5bG9hZCA9IDA7CiAgICBwcml2YXRlICRydWxlczsKICAgIHB1YmxpYyAkcHJlZml4ID0gJyc7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gQ2xvbmVyU3RhdFJlc3VsdCAgICRyZXN1bHQKICAgICAqIEBwYXJhbSBpbnQgICAgICAgICAgICAgICAgJG1heENvdW50CiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICAgICRtYXhQYXlsb2FkCiAgICAgKiBAcGFyYW0gaW50ICAgICAgICAgICAgICAgICR0aW1lb3V0CiAgICAgKiBAcGFyYW0gQ2xvbmVySW5jbHVkZVJ1bGVzICRydWxlcwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ2xvbmVyU3RhdFJlc3VsdCAkcmVzdWx0LCAkbWF4Q291bnQsICRtYXhQYXlsb2FkLCAkdGltZW91dCwgQ2xvbmVySW5jbHVkZVJ1bGVzICRydWxlcykgewogICAgICAgICR0aGlzLT5yZXN1bHQgICAgID0gJHJlc3VsdDsKICAgICAgICAkdGhpcy0+bWF4Q291bnQgICA9ICRtYXhDb3VudDsKICAgICAgICAkdGhpcy0+bWF4UGF5bG9hZCA9ICRtYXhQYXlsb2FkOwogICAgICAgICR0aGlzLT5kZWFkbGluZSAgID0gJHRpbWVvdXQgPyB0aW1lKCkgKyAkdGltZW91dCA6IDA7CiAgICAgICAgJHRoaXMtPnJ1bGVzICAgICAgPSAkcnVsZXM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHZpc2l0KCRwYXRoLCBDbG9uZXJTdGF0SW5mbyAkc3RhdCwgRXhjZXB0aW9uICRlID0gbnVsbCkgewogICAgICAgIGlmIChzdHJsZW4oJHBhdGgpID09PSAwKSB7CiAgICAgICAgICAgICRmdWxsUGF0aCA9ICR0aGlzLT5wcmVmaXg7CiAgICAgICAgICAgIGlmIChzdHJsZW4oJGZ1bGxQYXRoKSA9PT0gMCkgewogICAgICAgICAgICAgICAgJGZ1bGxQYXRoID0gJy4nOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlaWYgKHN0cmxlbigkdGhpcy0+cHJlZml4KSA+IDApIHsKICAgICAgICAgICAgJGZ1bGxQYXRoID0gJHRoaXMtPnByZWZpeC4iLyIuJHBhdGg7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGZ1bGxQYXRoID0gJHBhdGg7CiAgICAgICAgfQogICAgICAgICRlbmNvZGVkICAgICA9IGZhbHNlOwogICAgICAgICRlbmNvZGVkUGF0aCA9IGNsb25lcl9lbmNvZGVfbm9uX3V0ZjgoJGZ1bGxQYXRoKTsKICAgICAgICBpZiAoJGZ1bGxQYXRoICE9PSAkZW5jb2RlZFBhdGgpIHsKICAgICAgICAgICAgJGZ1bGxQYXRoID0gJGVuY29kZWRQYXRoOwogICAgICAgICAgICAkZW5jb2RlZCAgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGVtcHR5KCRlKSkgewogICAgICAgICAgICAkc3RhdHVzID0gJHRoaXMtPnJ1bGVzLT5pbmNsdWRlUGF0aCgkZnVsbFBhdGgsICRzdGF0LT5pc0RpcigpKTsKICAgICAgICB9IGVsc2VpZiAoJGUgaW5zdGFuY2VvZiBDbG9uZXJOb0ZpbGVFeGNlcHRpb24pIHsKICAgICAgICAgICAgJHN0YXR1cyA9IENsb25lclN0YXR1czo6Tk9fRklMRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkc3RhdHVzID0gQ2xvbmVyU3RhdHVzOjpFUlJPUjsKICAgICAgICB9CiAgICAgICAgaWYgKCRzdGF0dXMgPT09IENsb25lclN0YXR1czo6SU5WSVNJQkxFKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJTa2lwVmlzaXRFeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgICRsZW4gPSAwOwogICAgICAgIGlmICgkdGhpcy0+bWF4UGF5bG9hZCkgewogICAgICAgICAgICAkbGVuID0gJHRoaXMtPnBheWxvYWRMZW4oJHBhdGgsICRzdGF0dXMsICRzdGF0LCAkZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoY291bnQoJHRoaXMtPnJlc3VsdC0+c3RhdHMpKSB7CiAgICAgICAgICAgIGlmICgkdGhpcy0+ZGVhZGxpbmUgJiYgJHRoaXMtPmRlYWRsaW5lIDw9IHRpbWUoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdGhpcy0+bWF4Q291bnQgJiYgY291bnQoJHRoaXMtPnJlc3VsdC0+c3RhdHMpID49ICR0aGlzLT5tYXhDb3VudCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkdGhpcy0+bWF4UGF5bG9hZCAmJiAkdGhpcy0+cGF5bG9hZCArICRsZW4gPj0gJHRoaXMtPm1heFBheWxvYWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnBheWxvYWQgKz0gJGxlbjsKICAgICAgICBpZiAoJGUgIT09IG51bGwpIHsKICAgICAgICAgICAgJHRoaXMtPnJlc3VsdC0+YXBwZW5kRXJyb3IoJGZ1bGxQYXRoLCAkZW5jb2RlZCwgJHN0YXR1cywgJGUtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfSBlbHNlaWYgKCRzdGF0dXMpIHsKICAgICAgICAgICAgJHRoaXMtPnJlc3VsdC0+YXBwZW5kRXJyb3IoJGZ1bGxQYXRoLCAkZW5jb2RlZCwgJHN0YXR1cyk7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJTa2lwVmlzaXRFeGNlcHRpb24oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoJHN0YXQtPmlzRGlyKCkpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5yZXN1bHQtPmFwcGVuZERpcigkZnVsbFBhdGgsICRlbmNvZGVkLCAkc3RhdC0+Z2V0TVRpbWUoKSwgJHN0YXQtPmdldFBlcm1pc3Npb25zKCkpOwogICAgICAgICAgICB9IGVsc2VpZiAoJHN0YXQtPmlzTGluaygpKSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVzdWx0LT5hcHBlbmRMaW5rKCRmdWxsUGF0aCwgJGVuY29kZWQsICRzdGF0LT5saW5rLCAkc3RhdC0+Z2V0UGVybWlzc2lvbnMoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkdGhpcy0+cmVzdWx0LT5hcHBlbmRGaWxlKCRmdWxsUGF0aCwgJGVuY29kZWQsICRzdGF0LT5nZXRNVGltZSgpLCAkc3RhdC0+Z2V0U2l6ZSgpLCAkc3RhdC0+Z2V0UGVybWlzc2lvbnMoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gcGF5bG9hZExlbigkcGF0aCwgJHN0YXR1cywgQ2xvbmVyU3RhdEluZm8gJHN0YXQgPSBudWxsLCBFeGNlcHRpb24gJGUgPSBudWxsKSB7CiAgICAgICAgaWYgKCRzdGF0dXMpIHsKICAgICAgICAgICAgLy8geyJwYXRoIjoiIiwic3RhdHVzIjoxfQogICAgICAgICAgICByZXR1cm4gOCArIHN0cmxlbigkcGF0aCkgKyAxMzsKICAgICAgICB9CiAgICAgICAgaWYgKCRlICE9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIHsicGF0aDoiIiwic3RhdHVzIjoxLCJlcnJvciI6IiJ9CiAgICAgICAgICAgIHJldHVybiA4ICsgc3RybGVuKCRwYXRoKSArIDIyICsgc3RybGVuKCRlLT5nZXRNZXNzYWdlKCkpICsgMjsKICAgICAgICB9CiAgICAgICAgLy8geyJwYXRoIjoiIiwibXRpbWUiOjAsInNpemUiOjAsImRpciI6MH0sCiAgICAgICAgcmV0dXJuIDkgKyBzdHJsZW4oJHBhdGgpICsgMTAgKyBjbG9uZXJfaW50X2xlbigkc3RhdC0+Z2V0TVRpbWUoKSkgKyA4ICsgY2xvbmVyX2ludF9sZW4oJHN0YXQtPmdldFNpemUoKSkgKyA3ICsgMSArIDI7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyc3RhdGluZm8nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJTdGF0SW5mbwp7CiAgICAvLyBodHRwczovL3VuaXguc3VwZXJnbG9iYWxtZWdhY29ycC5jb20vTmV0Mi9uZXdzcmMvc3lzL3N0YXQuaC5odG1sCiAgICBjb25zdCBTX0lGTVQgPSAwMTcwMDAwOyAgIC8qIHR5cGUgb2YgZmlsZSAqLwogICAgY29uc3QgU19JRklGTyA9IDAwMTAwMDA7ICAvKiBuYW1lZCBwaXBlIChmaWZvKSAqLwogICAgY29uc3QgU19JRkNIUiA9IDAwMjAwMDA7ICAvKiBjaGFyYWN0ZXIgc3BlY2lhbCAqLwogICAgY29uc3QgU19JRkRJUiA9IDAwNDAwMDA7ICAvKiBkaXJlY3RvcnkgKi8KICAgIGNvbnN0IFNfSUZCTEsgPSAwMDYwMDAwOyAgLyogYmxvY2sgc3BlY2lhbCAqLwogICAgY29uc3QgU19JRlJFRyA9IDAxMDAwMDA7ICAvKiByZWd1bGFyICovCiAgICBjb25zdCBTX0lGTE5LID0gMDEyMDAwMDsgIC8qIHN5bWJvbGljIGxpbmsgKi8KICAgIGNvbnN0IFNfSUZTT0NLID0gMDE0MDAwMDsgLyogc29ja2V0ICovCgogICAgcHJpdmF0ZSAkc3RhdDsKICAgIHB1YmxpYyAkbGluayA9ICcnOwoKICAgIHByaXZhdGUgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJHN0YXQpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YXQgPSAkc3RhdDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYm9vbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaXNEaXIoKQogICAgewogICAgICAgIHJldHVybiAoJHRoaXMtPnN0YXRbJ21vZGUnXSAmIHNlbGY6OlNfSUZESVIpID09PSBzZWxmOjpTX0lGRElSOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBpc0xpbmsoKQogICAgewogICAgICAgIHJldHVybiAoJHRoaXMtPnN0YXRbJ21vZGUnXSAmIHNlbGY6OlNfSUZMTkspID09PSBzZWxmOjpTX0lGTE5LOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQZXJtaXNzaW9ucygpCiAgICB7CiAgICAgICAgcmV0dXJuICgkdGhpcy0+c3RhdFsnbW9kZSddICYgMDc3Nyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0U2l6ZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc0RpcigpID8gMCA6ICR0aGlzLT5zdGF0WydzaXplJ107CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGludAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0TVRpbWUoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RhdFsnbXRpbWUnXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkc3RhdCBSZXN1bHQgb2YgbHN0YXQoKSBvciBzdGF0KCkgZnVuY3Rpb24gY2FsbC4KICAgICAqCiAgICAgKiBAcmV0dXJuIENsb25lclN0YXRJbmZvCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbUFycmF5KGFycmF5ICRzdGF0KQogICAgewogICAgICAgIHJldHVybiBuZXcgc2VsZigkc3RhdCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtYWtlRW1wdHkoKQogICAgewogICAgICAgIHJldHVybiBuZXcgc2VsZihhcnJheSgnc2l6ZScgPT4gMCwgJ21vZGUnID0+IDAsICdtdGltZScgPT4gMCkpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmZzdW5leHBlY3RlZHNpemVyZXN1bHQnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJGU1VuZXhwZWN0ZWRTaXplUmVzdWx0IGV4dGVuZHMgQ2xvbmVyRlNFeGNlcHRpb24KewogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRwYXRoKQogICAgewogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3Qoc3ByaW50ZignRmlsZSBzaXplIG9mICVzIGlzIG92ZXIgMkdCIG9uIDMyYml0IHN5c3RlbS4nLCAkcGF0aCkpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcm5vZmlsZWV4Y2VwdGlvbicsIGZhbHNlKSk6CmNsYXNzIENsb25lck5vRmlsZUV4Y2VwdGlvbiBleHRlbmRzIENsb25lckZTRXhjZXB0aW9uCnsKICAgIHB1YmxpYyAkcGF0aCA9ICcnOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHBhdGgpCiAgICB7CiAgICAgICAgJHRoaXMtPnBhdGggPSAkcGF0aDsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KCJGaWxlICRwYXRoIGRvZXMgbm90IGV4aXN0Iik7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2ZzX3N0YXQnKSk6CmZ1bmN0aW9uIGNsb25lcl9mc19zdGF0KCRwYXRoKQp7CiAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdsc3RhdCcpKSB7CiAgICAgICAgJHN0YXQgPSBAbHN0YXQoJHBhdGgpOwogICAgICAgIGlmICgkc3RhdCkgewogICAgICAgICAgICAkaW5mbyA9IENsb25lclN0YXRJbmZvOjpmcm9tQXJyYXkoJHN0YXQpOwogICAgICAgICAgICBpZiAoJGluZm8tPmlzTGluaygpKSB7CiAgICAgICAgICAgICAgICAkbGluayA9IHJlYWRsaW5rKCRwYXRoKTsKICAgICAgICAgICAgICAgIGlmICghaXNfc3RyaW5nKCRsaW5rKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJGU0Z1bmN0aW9uRXhjZXB0aW9uKCdyZWFkbGluaycsICRwYXRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRpbmZvLT5saW5rID0gJGxpbms7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRpbmZvLT5nZXRTaXplKCkgPCAwKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRlNVbmV4cGVjdGVkU2l6ZVJlc3VsdCgkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICRpbmZvOwogICAgICAgIH0KICAgICAgICAkZXJyb3IgPSBlcnJvcl9nZXRfbGFzdCgpOwogICAgICAgIGlmICghZmlsZV9leGlzdHMoJHBhdGgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJOb0ZpbGVFeGNlcHRpb24oJHBhdGgpOwogICAgICAgIH0KICAgICAgICBpZiAoZW1wdHkoJGVycm9yWydtZXNzYWdlJ10pIHx8IHN0cm5jbXAoJGVycm9yWydtZXNzYWdlJ10sICdsc3RhdCgnLCAwKSAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyTm9GaWxlRXhjZXB0aW9uKCRwYXRoKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnc3RhdCcpKSB7CiAgICAgICAgJHN0YXQgPSBAc3RhdCgkcGF0aCk7CiAgICAgICAgaWYgKCRzdGF0KSB7CiAgICAgICAgICAgICRpbmZvID0gQ2xvbmVyU3RhdEluZm86OmZyb21BcnJheSgkc3RhdCk7OwogICAgICAgICAgICBpZiAoQGlzX2xpbmsoJHBhdGgpKSB7CiAgICAgICAgICAgICAgICAkbGluayA9ICRsaW5rID0gcmVhZGxpbmsoJHBhdGgpOwogICAgICAgICAgICAgICAgaWYgKCRsaW5rID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJGU0Z1bmN0aW9uRXhjZXB0aW9uKCdyZWFkbGluaycsICRwYXRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRpbmZvLT5saW5rID0gJGxpbms7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRpbmZvLT5nZXRTaXplKCkgPCAwKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRlNVbmV4cGVjdGVkU2l6ZVJlc3VsdCgkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICRpbmZvOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRlNGdW5jdGlvbkV4Y2VwdGlvbignc3RhdCcsICRwYXRoKTsKICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgbmV3IENsb25lckZTRnVuY3Rpb25FeGNlcHRpb24oJ2xzdGF0JywgJHBhdGgpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmZzZmlsZWluZm8nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJGU0ZpbGVJbmZvCnsKICAgIC8qKiBAdmFyIHN0cmluZyAqLwogICAgcHJpdmF0ZSAkcGF0aDsKICAgIC8qKiBAdmFyIENsb25lclN0YXRJbmZvICovCiAgICBwcml2YXRlICRzdGF0OwogICAgLyoqIEB2YXIgc3RyaW5nW118bnVsbCAqLwogICAgcHJpdmF0ZSAkY2hpbGRyZW47CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgJHJlbFBhdGgKICAgICAqIEBwYXJhbSBDbG9uZXJTdGF0SW5mbyAkc3RhdAogICAgICogQHBhcmFtIHN0cmluZ1tdfG51bGwgICRjaGlsZHJlbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHJlbFBhdGgsIENsb25lclN0YXRJbmZvICRzdGF0LCBhcnJheSAkY2hpbGRyZW4gPSBudWxsKQogICAgewogICAgICAgICR0aGlzLT5wYXRoICAgICA9ICRyZWxQYXRoOwogICAgICAgICR0aGlzLT5zdGF0ICAgICA9ICRzdGF0OwogICAgICAgICR0aGlzLT5jaGlsZHJlbiA9ICRjaGlsZHJlbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQYXRoKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENsb25lclN0YXRJbmZvCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTdGF0KCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nW118bnVsbCAkY2hpbGRyZW4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldENoaWxkcmVuKGFycmF5ICRjaGlsZHJlbiA9IG51bGwpCiAgICB7CiAgICAgICAgJHRoaXMtPmNoaWxkcmVuID0gJGNoaWxkcmVuOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBzdHJpbmdbXXxudWxsCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDaGlsZHJlbigpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5jaGlsZHJlbjsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfc2VlbXNfdXRmOCcpKToKZnVuY3Rpb24gY2xvbmVyX3NlZW1zX3V0ZjgoJHApIHsKICAgIHN0YXRpYyAkZmlyc3Q7CiAgICBpZiAoJGZpcnN0ID09PSBudWxsKSB7CiAgICAgICAgJHh4ICAgID0gMHhGMTsgLy8gaW52YWxpZDogc2l6ZSAxCiAgICAgICAgJGFzICAgID0gMHhGMDsgLy8gQVNDSUk6IHNpemUgMQogICAgICAgICRzMSAgICA9IDB4MDI7IC8vIGFjY2VwdCAwLCBzaXplIDIKICAgICAgICAkczIgICAgPSAweDEzOyAvLyBhY2NlcHQgMSwgc2l6ZSAzCiAgICAgICAgJHMzICAgID0gMHgwMzsgLy8gYWNjZXB0IDAsIHNpemUgMwogICAgICAgICRzNCAgICA9IDB4MjM7IC8vIGFjY2VwdCAyLCBzaXplIDMKICAgICAgICAkczUgICAgPSAweDM0OyAvLyBhY2NlcHQgMywgc2l6ZSA0CiAgICAgICAgJHM2ICAgID0gMHgwNDsgLy8gYWNjZXB0IDAsIHNpemUgNAogICAgICAgICRzNyAgICA9IDB4NDQ7IC8vIGFjY2VwdCA0LCBzaXplIDQKICAgICAgICAkZmlyc3QgPSBhcnJheSgKICAgICAgICAgICAgLy8gICAxICAgIDIgICAgMyAgICA0ICAgIDUgICAgNiAgICA3ICAgIDggICAgOSAgICBBICAgIEIgICAgQyAgICBEICAgIEUgICAgRgogICAgICAgICAgICAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsIC8vIDB4MDAtMHgwRgogICAgICAgICAgICAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsIC8vIDB4MTAtMHgxRgogICAgICAgICAgICAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsIC8vIDB4MjAtMHgyRgogICAgICAgICAgICAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsIC8vIDB4MzAtMHgzRgogICAgICAgICAgICAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsIC8vIDB4NDAtMHg0RgogICAgICAgICAgICAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsIC8vIDB4NTAtMHg1RgogICAgICAgICAgICAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsIC8vIDB4NjAtMHg2RgogICAgICAgICAgICAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsICRhcywgJGFzLCAkYXMsIC8vIDB4NzAtMHg3RgogICAgICAgICAgICAvLyAgIDEgICAgMiAgICAzICAgIDQgICAgNSAgICA2ICAgIDcgICAgOCAgICA5ICAgIEEgICAgQiAgICBDICAgIEQgICAgRSAgICBGCiAgICAgICAgICAgICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgLy8gMHg4MC0weDhGCiAgICAgICAgICAgICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgLy8gMHg5MC0weDlGCiAgICAgICAgICAgICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgLy8gMHhBMC0weEFGCiAgICAgICAgICAgICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgLy8gMHhCMC0weEJGCiAgICAgICAgICAgICR4eCwgJHh4LCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgLy8gMHhDMC0weENGCiAgICAgICAgICAgICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgJHMxLCAkczEsICRzMSwgLy8gMHhEMC0weERGCiAgICAgICAgICAgICRzMiwgJHMzLCAkczMsICRzMywgJHMzLCAkczMsICRzMywgJHMzLCAkczMsICRzMywgJHMzLCAkczMsICRzMywgJHM0LCAkczMsICRzMywgLy8gMHhFMC0weEVGCiAgICAgICAgICAgICRzNSwgJHM2LCAkczYsICRzNiwgJHM3LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgJHh4LCAkeHgsICR4eCwgLy8gMHhGMC0weEZGCiAgICAgICAgKTsKICAgIH0KICAgIHN0YXRpYyAkeHggPSAweEYxOwogICAgc3RhdGljICRsb2NiID0gMHg4MDsKICAgIHN0YXRpYyAkaGljYiA9IDB4QkY7CiAgICBzdGF0aWMgJGFjY2VwdFJhbmdlczsKICAgIGlmICgkYWNjZXB0UmFuZ2VzID09PSBudWxsKSB7CiAgICAgICAgJGFjY2VwdFJhbmdlcyA9IGFycmF5KAogICAgICAgICAgICAwID0+IGFycmF5KCRsb2NiLCAkaGljYiksCiAgICAgICAgICAgIDEgPT4gYXJyYXkoMHhBMCwgJGhpY2IpLAogICAgICAgICAgICAyID0+IGFycmF5KCRsb2NiLCAweDlGKSwKICAgICAgICAgICAgMyA9PiBhcnJheSgweDkwLCAkaGljYiksCiAgICAgICAgICAgIDQgPT4gYXJyYXkoJGxvY2IsIDB4OEYpLAogICAgICAgICk7CiAgICB9CiAgICAkbiA9IHN0cmxlbigkcCk7CiAgICBmb3IgKCRpID0gMDsgJGkgPCAkbjspIHsKICAgICAgICAkcGkgPSBvcmQoJHBbJGldKTsKICAgICAgICBpZiAoJHBpIDwgMHg4MCkgewogICAgICAgICAgICAkaSsrOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJHggPSAkZmlyc3RbJHBpXTsKICAgICAgICBpZiAoJHggPT09ICR4eCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIElsbGVnYWwgc3RhcnRlciBieXRlLgogICAgICAgIH0KICAgICAgICAkc2l6ZSA9ICR4ICYgNzsKICAgICAgICBpZiAoJGkgKyAkc2l6ZSA+ICRuKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gU2hvcnQgb3IgaW52YWxpZC4KICAgICAgICB9CiAgICAgICAgJGFjY2VwdCA9ICRhY2NlcHRSYW5nZXNbJHggPj4gNF07CiAgICAgICAgaWYgKCgoJGMgPSBvcmQoJHBbJGkgKyAxXSkpIDwgJGFjY2VwdFswXSkgfHwgKCRhY2NlcHRbMV0gPCAkYykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZWlmICgkc2l6ZSA9PT0gMikgewogICAgICAgIH0gZWxzZWlmICgoKCRjID0gb3JkKCRwWyRpICsgMl0pKSA8ICRsb2NiKSB8fCAoJGhpY2IgPCAkYykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZWlmICgkc2l6ZSA9PT0gMykgewogICAgICAgIH0gZWxzZWlmICgoKCRjID0gb3JkKCRwWyRpICsgM10pKSA8ICRsb2NiKSB8fCAoJGhpY2IgPCAkYykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAkaSArPSAkc2l6ZTsKICAgIH0KICAgIHJldHVybiB0cnVlOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9zb3J0X2VuY29kZWRfZmlsZXMnKSk6CmZ1bmN0aW9uIGNsb25lcl9zb3J0X2VuY29kZWRfZmlsZXMoJGYxLCAkZjIpCnsKICAgICRuYW1lMSA9ICRmMTsKICAgIGlmIChpc19hcnJheSgkZjEpKSB7CiAgICAgICAgJG5hbWUxID0gJGYxWzBdOwogICAgfQogICAgJG5hbWUyID0gJGYyOwogICAgaWYgKGlzX2FycmF5KCRmMikpIHsKICAgICAgICAkbmFtZTIgPSAkZjJbMF07CiAgICB9CiAgICByZXR1cm4gc3RyY21wKCRuYW1lMSwgJG5hbWUyKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZnNfbGlzdF9jaGlsZHJlbicpKToKZnVuY3Rpb24gY2xvbmVyX2ZzX2xpc3RfY2hpbGRyZW4oJHBhdGgsICRvZmZzZXQgPSAnJykKewogICAgJGZpbGVzID0gQHNjYW5kaXIoJHBhdGgpOwogICAgaWYgKCRmaWxlcyA9PT0gZmFsc2UpIHsKICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRlNGdW5jdGlvbkV4Y2VwdGlvbignc2NhbmRpcicsICRwYXRoKTsKICAgIH0KICAgICRoYXNFbmNvZGVkID0gZmFsc2U7CiAgICAkc3BsaWNlICAgICA9IDA7CiAgICBmb3IgKCRpID0gMDsgJGkgKyAkc3BsaWNlIDwgY291bnQoJGZpbGVzKTspIHsKICAgICAgICAkZmlsZSA9ICRmaWxlc1skaSArICRzcGxpY2VdOwogICAgICAgIGlmICgkZmlsZSA9PT0gJy4nIHx8ICRmaWxlID09PSAnLi4nKSB7CiAgICAgICAgICAgICRzcGxpY2UrKzsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRpc0VuY29kZWQgPSBmYWxzZTsKICAgICAgICBpZiAoIWNsb25lcl9zZWVtc191dGY4KCRmaWxlKSkgewogICAgICAgICAgICAkaXNFbmNvZGVkID0gdHJ1ZTsKICAgICAgICAgICAgJGZpbGUgICAgICA9IGNsb25lcl9lbmNvZGVfbm9uX3V0ZjgoJGZpbGUpOwogICAgICAgIH0KICAgICAgICBpZiAoc3RybGVuKCRvZmZzZXQpICYmIChzdHJjbXAoJGZpbGUsICRvZmZzZXQpIDwgMCkpIHsKICAgICAgICAgICAgJHNwbGljZSsrOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCRzcGxpY2UpIHsKICAgICAgICAgICAgYXJyYXlfc3BsaWNlKCRmaWxlcywgJGksICRzcGxpY2UpOwogICAgICAgICAgICAkc3BsaWNlID0gMDsKICAgICAgICB9CiAgICAgICAgaWYgKCRpc0VuY29kZWQpIHsKICAgICAgICAgICAgJGhhc0VuY29kZWQgPSB0cnVlOwogICAgICAgICAgICAkZmlsZXNbJGldICA9IGFycmF5KCRmaWxlKTsKICAgICAgICB9CiAgICAgICAgJGkrKzsKICAgIH0KICAgIGlmICgkc3BsaWNlKSB7CiAgICAgICAgYXJyYXlfc3BsaWNlKCRmaWxlcywgJGksICRzcGxpY2UpOwogICAgfQogICAgaWYgKFBIUF9WRVJTSU9OX0lEIDwgMCkgewogICAgICAgIC8vIEhhY2sgdG8gaW5jbHVkZSB1c29ydCBmdW5jdGlvbiBkdXJpbmcgYnVpbGQuCiAgICAgICAgY2xvbmVyX3NvcnRfZW5jb2RlZF9maWxlcygnJywgJycpOwogICAgfQogICAgdXNvcnQoJGZpbGVzLCAnY2xvbmVyX3NvcnRfZW5jb2RlZF9maWxlcycpOwogICAgaWYgKCRoYXNFbmNvZGVkKSB7CiAgICAgICAgZm9yZWFjaCAoJGZpbGVzIGFzICRpID0+ICRmaWxlKSB7CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkZmlsZSkpIHsKICAgICAgICAgICAgICAgICRmaWxlc1skaV0gPSB1cmxkZWNvZGUoJGZpbGVbMF0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuICRmaWxlczsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZnNfbWFrZV9zdGFjaycpKToKZnVuY3Rpb24gY2xvbmVyX2ZzX21ha2Vfc3RhY2soJHJvb3QsICRjdXJzb3IgPSAnJykKewogICAgLyoqIEB2YXIgQ2xvbmVyRlNGaWxlSW5mb1tdICRzdGFjayAqLwogICAgJHN0YWNrID0gYXJyYXkoKTsKICAgIC8vIFNwbGl0IGN1cnNvciB0byBwYXRocwogICAgJHBhdGhzID0gZXhwbG9kZSgnLycsIHByZWdfcmVwbGFjZSgne1tcXFxcL10rfScsICcvJywgdHJpbSgkY3Vyc29yLCAnXFwvJykpKTsKICAgIGlmICgkcGF0aHNbMF0gPT09ICcuJykgewogICAgICAgICRwYXRoc1swXSA9ICcnOwogICAgfQogICAgaWYgKCRwYXRoc1swXSAhPT0gJycpIHsKICAgICAgICBhcnJheV91bnNoaWZ0KCRwYXRocywgJycpOwogICAgfQogICAgZm9yICgkaSA9IDAsICRwYXRoQ291bnQgPSBjb3VudCgkcGF0aHMpOyAkaSA8ICRwYXRoQ291bnQ7ICRpKyspIHsKICAgICAgICAkY3VycmVudCA9ICRwYXRoc1skaV07CiAgICAgICAgLy8gJGN1cnJlbnRbJGkrMV0gaG9sZHMgcGF0aC10by1za2lwLXRvIGluIGN1cnJlbnQgZGlyZWN0b3J5LgogICAgICAgIC8vIEZpcnN0IHRpbWUgJGN1cnJlbnQgaXMgYW4gZW1wdHkgc3RyaW5nLgogICAgICAgICRwYXRoICAgICAgPSBpc3NldCgkcGF0aCkgPyAkcGF0aC4nLycuJGN1cnJlbnQgOiAkY3VycmVudDsKICAgICAgICAkbmV4dENoaWxkID0gaXNzZXQoJHBhdGhzWyRpICsgMV0pID8gJHBhdGhzWyRpICsgMV0gOiBudWxsOwogICAgICAgICRjaGlsZHJlbiAgPSBudWxsOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRzdGF0ID0gY2xvbmVyX2ZzX3N0YXQoJHJvb3QuJHBhdGgpOwogICAgICAgICAgICBpZiAoISRzdGF0LT5pc0RpcigpKSB7CiAgICAgICAgICAgICAgICBpZiAoY291bnQoJHN0YWNrKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheShuZXcgQ2xvbmVyRlNGaWxlSW5mbygkcGF0aCwgJHN0YXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAkc3RhY2s7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRuZXh0Q2hpbGQgIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICRjaGlsZHJlbiA9IGNsb25lcl9mc19saXN0X2NoaWxkcmVuKCRyb290LiRwYXRoLCAkbmV4dENoaWxkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNzZXQoJHN0YWNrWyRpIC0gMV0pKSB7CiAgICAgICAgICAgICAgICAkcGFyZW50ICAgPSAkc3RhY2tbJGkgLSAxXTsKICAgICAgICAgICAgICAgICRzaWJsaW5ncyA9ICRwYXJlbnQtPmdldENoaWxkcmVuKCk7CiAgICAgICAgICAgICAgICBpZiAoaXNzZXQoJHNpYmxpbmdzWzBdKSAmJiAkc2libGluZ3NbMF0gPT09ICRjdXJyZW50KSB7CiAgICAgICAgICAgICAgICAgICAgYXJyYXlfc2hpZnQoJHNpYmxpbmdzKTsKICAgICAgICAgICAgICAgICAgICAkcGFyZW50LT5zZXRDaGlsZHJlbigkc2libGluZ3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRzdGFja1tdID0gbmV3IENsb25lckZTRmlsZUluZm8obHRyaW0oJHBhdGgsICcvJyksICRzdGF0LCAkY2hpbGRyZW4pOwogICAgICAgIH0gY2F0Y2ggKENsb25lckZTRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmIChjb3VudCgkc3RhY2spID4gMCkgewogICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSByb290IGF0IGxlYXN0LgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuICRzdGFjazsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJpbnZhbGlkZmlsZW5hbWVleGNlcHRpb24nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJJbnZhbGlkRmlsZW5hbWVFeGNlcHRpb24gZXh0ZW5kcyBDbG9uZXJFeGNlcHRpb24KewogICAgcHVibGljICRyb290ID0gJyc7CiAgICBwdWJsaWMgJHBhcmVudCA9ICcnOwogICAgcHVibGljICRuYW1lID0gJyc7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRyb290LCAkcGFyZW50LCAkbmFtZSkKICAgIHsKICAgICAgICAkdGhpcy0+cm9vdCAgID0gJHJvb3Q7CiAgICAgICAgJHRoaXMtPnBhcmVudCA9ICRwYXJlbnQ7CiAgICAgICAgJHRoaXMtPm5hbWUgICA9ICRuYW1lOwogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3Qoc3ByaW50ZignUGF0aCAlcy8lcyBoYXMgaW52YWxpZCBmaWxlICIlcyInLCAkdGhpcy0+cm9vdCwgJHRoaXMtPnBhcmVudCwgJHRoaXMtPm5hbWUpKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZnNfd2FsaycpKToKZnVuY3Rpb24gY2xvbmVyX2ZzX3dhbGsoJHJvb3QsIENsb25lckZTVmlzaXRvciAkdmlzaXRvciwgJGN1cnNvciA9ICcnLCAkcGFyZW50c0ZpcnN0ID0gZmFsc2UpCnsKICAgIHRyeSB7CiAgICAgICAgJHN0YWNrID0gY2xvbmVyX2ZzX21ha2Vfc3RhY2soJHJvb3QsICRjdXJzb3IpOwogICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlKSB7CiAgICAgICAgJHZpc2l0b3ItPnZpc2l0KCRjdXJzb3IsIENsb25lclN0YXRJbmZvOjptYWtlRW1wdHkoKSwgJGUpOwogICAgICAgIHJldHVybiAnJzsKICAgIH0KICAgIC8qKiBAdmFyIENsb25lckZTRmlsZUluZm8gJGN1cnJlbnQgKi8KICAgICRjdXJyZW50ID0gYXJyYXlfcG9wKCRzdGFjayk7CiAgICBpZiAoISRjdXJyZW50LT5nZXRTdGF0KCktPmlzRGlyKCkpIHsKICAgICAgICAkdmlzaXRvci0+dmlzaXQoJGN1cnJlbnQtPmdldFBhdGgoKSwgJGN1cnJlbnQtPmdldFN0YXQoKSk7CiAgICAgICAgcmV0dXJuICcnOwogICAgfQogICAgLy8gRmxhZyB0aGF0IGlzIHNldCB0byB0cnVlIGV2ZXJ5IHRpbWUgd2UgdHJhdmVyc2UgZG93biBpbnRvIGEgbmV3IGRpcmVjdG9yeSwgYW5kIGZhbHNlIHdoZW4gZ29pbmcgdXAuCiAgICAvLyBJZiBsYXN0IG5vZGUgaW4gY3Vyc29yIGlzIGEgZGlyZWN0b3J5IHdpdGggdW4tc3RhdC1lZCBjaGlsZHJlbiwgdGhhdCBtZWFucyB0aGUgY3Vyc29yIGVuZGVkIHVwIG9uIGl0LAogICAgLy8gYW5kIHRoYXQgZGlyZWN0b3J5IHdhcyB0aGUgbGFzdCBvbmUgdG8gZ2V0IHZpc2l0ZWQuCiAgICAvLyBJZiBsYXN0IHBhcnQgb2YgY3Vyc29yIGlzIGEgZmlsZSwgJGN1cnJlbnQgd2lsbCBoYXZlIGl0cyBzaWJsaW5ncyBhcyBjaGlsZHJlbi4KICAgICRnb0Rvd24gPSB0cnVlOwogICAgaWYgKCRwYXJlbnRzRmlyc3QpIHsKICAgICAgICBpZiAoJGN1cnJlbnQtPmdldENoaWxkcmVuKCkgIT09IG51bGwpIHsKICAgICAgICAgICAgJGdvRG93biA9IG51bGw7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBpZiAoJGN1cnJlbnQtPmdldENoaWxkcmVuKCkgPT09IG51bGwpIHsKICAgICAgICAgICAgJGdvRG93biA9IGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICRlICAgICAgICA9IG51bGw7CiAgICAgICAgJGNoaWxkcmVuID0gJGN1cnJlbnQtPmdldENoaWxkcmVuKCk7CiAgICAgICAgaWYgKCRjaGlsZHJlbiA9PT0gbnVsbCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJGNoaWxkcmVuID0gY2xvbmVyX2ZzX2xpc3RfY2hpbGRyZW4oJHJvb3QuJy8nLiRjdXJyZW50LT5nZXRQYXRoKCkpOwogICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIC8vIENhcHR1cmUgJGUgZm9yIGNhbGwgYmVsb3cuCiAgICAgICAgICAgICAgICAkY2hpbGRyZW4gPSBhcnJheSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjdXJyZW50LT5zZXRDaGlsZHJlbigkY2hpbGRyZW4pOwogICAgICAgIH0KICAgICAgICBpZiAoJGdvRG93biA9PT0gJHBhcmVudHNGaXJzdCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYgKCEkdmlzaXRvci0+dmlzaXQoJGN1cnJlbnQtPmdldFBhdGgoKSwgJGN1cnJlbnQtPmdldFN0YXQoKSwgJGUpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRjdXJyZW50LT5nZXRQYXRoKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKENsb25lclNraXBWaXNpdEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgJGdvRG93biA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgkZ29Eb3duID09PSBmYWxzZSkgewogICAgICAgICAgICAkY3VycmVudCA9IGFycmF5X3BvcCgkc3RhY2spOwogICAgICAgICAgICBpZiAoJGN1cnJlbnQgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvcmVhY2ggKCRjdXJyZW50LT5nZXRDaGlsZHJlbigpIGFzICRpID0+ICRjaGlsZCkgewogICAgICAgICAgICAkY2hpbGRQYXRoID0gbHRyaW0oJGN1cnJlbnQtPmdldFBhdGgoKS4nLycuJGNoaWxkLCAnLycpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYgKHN0cnBvcygkY2hpbGQsICcvJykgIT09IGZhbHNlIHx8IHN0cnBvcygkY2hpbGQsICdcXCcpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICR2aXNpdG9yLT52aXNpdCgkY2hpbGRQYXRoLCAkY3VycmVudC0+Z2V0U3RhdCgpLCBuZXcgQ2xvbmVySW52YWxpZEZpbGVuYW1lRXhjZXB0aW9uKCRyb290LCAkY3VycmVudC0+Z2V0UGF0aCgpLCAkY2hpbGQpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRzdGF0ID0gY2xvbmVyX2ZzX3N0YXQoJHJvb3QuJy8nLiRjaGlsZFBhdGgpOwogICAgICAgICAgICAgICAgaWYgKCRzdGF0LT5pc0RpcigpKSB7CiAgICAgICAgICAgICAgICAgICAgJGN1cnJlbnQtPnNldENoaWxkcmVuKGFycmF5X3NsaWNlKCRjdXJyZW50LT5nZXRDaGlsZHJlbigpLCAkaSArIDEpKTsKICAgICAgICAgICAgICAgICAgICAkc3RhY2tbXSA9ICRjdXJyZW50OwogICAgICAgICAgICAgICAgICAgICRjdXJyZW50ID0gbmV3IENsb25lckZTRmlsZUluZm8oJGNoaWxkUGF0aCwgJHN0YXQpOwogICAgICAgICAgICAgICAgICAgICRnb0Rvd24gID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIGlmICghJHZpc2l0b3ItPnZpc2l0KCRjaGlsZFBhdGgsIENsb25lclN0YXRJbmZvOjptYWtlRW1wdHkoKSwgJGUpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRjaGlsZFBhdGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYgKCEkdmlzaXRvci0+dmlzaXQoJGNoaWxkUGF0aCwgJHN0YXQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRjaGlsZFBhdGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKENsb25lclNraXBWaXNpdEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgLy8gR28gdG8gbmV4dCBzaWJsaW5nLgogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJGdvRG93biA9IGZhbHNlOwogICAgfQogICAgcmV0dXJuICcnOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9hY3Rpb25fc3RhdCcpKToKZnVuY3Rpb24gY2xvbmVyX2FjdGlvbl9zdGF0KCRyb290LCAkY3Vyc29yLCAkbWF4Q291bnQsICRtYXhQYXlsb2FkLCAkdGltZW91dCwgJGFkZFBhdGhzLCAkaGlkZVBhdGhzLCAkc2tpcFBhdGhzLCAkc2tpcFN5c3RlbVBhdGhzLCAkc2tpcEZpbGVzLCAkc2tpcERpcnMsIGFycmF5ICR0cmF2ZXJzZSkKewogICAgJHJlc3VsdCA9IG5ldyBDbG9uZXJTdGF0UmVzdWx0KCk7CiAgICAkcnVsZXMgPSBuZXcgQ2xvbmVySW5jbHVkZVJ1bGVzKCRhZGRQYXRocywgJGhpZGVQYXRocywgJHNraXBQYXRocywgJHNraXBTeXN0ZW1QYXRocywgJHNraXBGaWxlcywgJHNraXBEaXJzKTsKICAgICR2aXNpdG9yID0gbmV3IENsb25lclN0YXRWaXNpdG9yKCRyZXN1bHQsICRtYXhDb3VudCwgJG1heFBheWxvYWQsICR0aW1lb3V0LCAkcnVsZXMpOwogICAgJG5ld0N1cnNvciA9ICcnOwogICAgZm9yZWFjaCAoJHRyYXZlcnNlIGFzICRwYXRoKSB7CiAgICAgICAgJHZpc2l0b3ItPnByZWZpeCA9ICRwYXRoOwogICAgICAgICRyb290UGF0aCAgICAgICAgPSBydHJpbSgiJHJvb3QvJHBhdGgiLCAnLycpOwogICAgICAgIGlmIChzdHJsZW4oJHJvb3RQYXRoKSA9PT0gMCkgewogICAgICAgICAgICAkcm9vdFBhdGggPSAnLyc7CiAgICAgICAgfQogICAgICAgICRuZXdDdXJzb3IgPSBjbG9uZXJfZnNfd2Fsaygkcm9vdFBhdGgsICR2aXNpdG9yLCAkY3Vyc29yLCB0cnVlKTsKICAgICAgICBpZiAoc3RybGVuKCRuZXdDdXJzb3IpICE9PSAwKSB7CiAgICAgICAgICAgIC8vIFdlIGhpdCBhIGRlYWRsaW5lLgogICAgICAgICAgICAkbmV3Q3Vyc29yID0gbHRyaW0oIiRwYXRoLyRuZXdDdXJzb3IiLCAnLycpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgJGN1cnNvciA9ICcnOwogICAgICAgIC8vIEN1cnNvciBpcyBlbXB0eSwgZ28gdG8gbmV4dCBwYXRoLCBvciByZXR1cm4uCiAgICB9CiAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgJ3N0YXRzJyAgPT4gJHJlc3VsdC0+c3RhdHMsCiAgICAgICAgJ2N1cnNvcicgPT4gY2xvbmVyX2VuY29kZV9ub25fdXRmOCgkbmV3Q3Vyc29yKSwKICAgICk7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyaGFzaHJlc3VsdCcsIGZhbHNlKSk6CmNsYXNzIENsb25lckhhc2hSZXN1bHQKewogICAgcHVibGljICRoYXNoZXMgPSBhcnJheSgpOwogICAgcHVibGljICR0ZW1wSGFzaGVzID0gJyc7CgogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZE9LKCRoYXNoKQogICAgewogICAgICAgICR0aGlzLT5oYXNoZXNbXSA9IGFycmF5KCdoJyA9PiAkaGFzaCk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZFRlbXBIYXNoZXMoJGhhc2hlcykKICAgIHsKICAgICAgICAkdGhpcy0+aGFzaGVzW10gICA9IGFycmF5KCd0JyA9PiB0cnVlKTsKICAgICAgICAkdGhpcy0+dGVtcEhhc2hlcyA9ICRoYXNoZXM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZEVycm9yKCRlcnJvcikKICAgIHsKICAgICAgICAkdGhpcy0+aGFzaGVzW10gPSBhcnJheSgnbycgPT4gQ2xvbmVyU3RhdHVzOjpFUlJPUiwgJ2UnID0+ICRlcnJvcik7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyZGVhZGxpbmUnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJEZWFkbGluZQp7CiAgICBwcml2YXRlICRkZWFkbGluZSA9IDA7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gJHRpbWVvdXQgaW50IFRpbWVvdXQgaW4gc2Vjb25kczsgMCB0byBuZXZlciB0aW1lIG91dDsgLTEgdG8gdGltZSBvdXQgaW1tZWRpYXRlbHkuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdGltZW91dCkgewogICAgICAgIGlmICgkdGltZW91dCA9PT0gMCB8fCAkdGltZW91dCA9PT0gLTEpIHsKICAgICAgICAgICAgJHRoaXMtPmRlYWRsaW5lID0gJHRpbWVvdXQ7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmRlYWRsaW5lID0gbWljcm90aW1lKHRydWUpICsgKGZsb2F0KSR0aW1lb3V0OwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBib29sIFRydWUgaWYgZGVhZGxpbmUgaXMgcmVhY2hlZC4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGRvbmUoKSB7CiAgICAgICAgaWYgKCR0aGlzLT5kZWFkbGluZSA9PT0gMCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSBlbHNlaWYgKCR0aGlzLT5kZWFkbGluZSA9PT0gLTEpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtaWNyb3RpbWUodHJ1ZSkgPiAkdGhpcy0+ZGVhZGxpbmU7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyZmlsZWluZm8nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJGaWxlSW5mbwp7CiAgICBwcml2YXRlICRmaWxlOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChhcnJheSAkZmlsZSkgewogICAgICAgICR0aGlzLT5maWxlID0gJGZpbGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gJG5hbWUKICAgICAqCiAgICAgKiBAcmV0dXJuIGludHxzdHJpbmd8YXJyYXkKICAgICAqCiAgICAgKiBAdGhyb3dzIENsb25lckV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19nZXQoJG5hbWUpIHsKICAgICAgICBzd2l0Y2ggKCRuYW1lKSB7CiAgICAgICAgICAgIGNhc2UgJ3BhdGgnOgogICAgICAgICAgICAgICAgaWYgKCFlbXB0eSgkdGhpcy0+ZmlsZVsnZW5jb2RlZCddKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmxkZWNvZGUoYmFzZTY0X2RlY29kZSgkdGhpcy0+ZmlsZVsncGF0aCddKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gYmFzZTY0X2RlY29kZSgkdGhpcy0+ZmlsZVsncGF0aCddKTsKICAgICAgICAgICAgY2FzZSAncGF0aDY0JzoKICAgICAgICAgICAgICAgIGlmICghZW1wdHkoJHRoaXMtPmZpbGVbJ2VuY29kZWQnXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXJsZGVjb2RlKCR0aGlzLT5maWxlWydwYXRoJ10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5maWxlWydwYXRoJ107CiAgICAgICAgICAgIGNhc2UgJ3NpemUnOgogICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzLT5maWxlWydzaXplJ107CiAgICAgICAgICAgIGNhc2UgJ2Rpcic6CiAgICAgICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZpbGVbJ3R5cGUnXSA9PT0gMTsKICAgICAgICAgICAgY2FzZSAnaXNMaW5rJzoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmlsZVsndHlwZSddID09PSAyOwogICAgICAgICAgICBjYXNlICdsaW5rJzoKICAgICAgICAgICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZmlsZVsnbGluazY0J10pID8gYmFzZTY0X2RlY29kZSgkdGhpcy0+ZmlsZVsnbGluazY0J10pIDogJyc7CiAgICAgICAgICAgIGNhc2UgJ210aW1lJzoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmlsZVsnbXRpbWUnXTsKICAgICAgICAgICAgY2FzZSAnb2Zmc2V0JzoKICAgICAgICAgICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZmlsZVsnb2Zmc2V0J10pID8gJHRoaXMtPmZpbGVbJ29mZnNldCddIDogMDsKICAgICAgICAgICAgY2FzZSAnaGFzaCc6CiAgICAgICAgICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmZpbGVbJ2hhc2gnXSkgPyAkdGhpcy0+ZmlsZVsnaGFzaCddIDogJyc7CiAgICAgICAgICAgIGNhc2UgJ2hhc2hlcyc6CiAgICAgICAgICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmZpbGVbJ2hhc2hlcyddKSA/ICR0aGlzLT5maWxlWydoYXNoZXMnXSA6ICcnOwogICAgICAgICAgICBjYXNlICdzdGF0dXMnOgogICAgICAgICAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5maWxlWydzdGF0dXMnXSkgPyAkdGhpcy0+ZmlsZVsnc3RhdHVzJ10gOiAwOwogICAgICAgICAgICBjYXNlICdlcnJvcic6CiAgICAgICAgICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmZpbGVbJ2Vycm9yJ10pID8gJHRoaXMtPmZpbGVbJ2Vycm9yJ10gOiAnJzsKICAgICAgICAgICAgY2FzZSAnZGF0YSc6CiAgICAgICAgICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmZpbGVbJ2RhdGE2NCddKSA/IGJhc2U2NF9kZWNvZGUoJHRoaXMtPmZpbGVbJ2RhdGE2NCddKSA6ICcnOwogICAgICAgICAgICBjYXNlICdkYXRhNjQnOgogICAgICAgICAgICAgICAgcmV0dXJuIGlzc2V0KCR0aGlzLT5maWxlWydkYXRhNjQnXSkgPyAkdGhpcy0+ZmlsZVsnZGF0YTY0J10gOiAnJzsKICAgICAgICAgICAgY2FzZSAnd3JpdHRlbic6CiAgICAgICAgICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmZpbGVbJ3dyaXR0ZW4nXSkgPyAkdGhpcy0+ZmlsZVsnd3JpdHRlbiddIDogMDsKICAgICAgICAgICAgY2FzZSAnZW9mJzoKICAgICAgICAgICAgICAgIHJldHVybiBpc3NldCgkdGhpcy0+ZmlsZVsnZW9mJ10pID8gJHRoaXMtPmZpbGVbJ2VvZiddIDogZmFsc2U7CiAgICAgICAgICAgIGNhc2UgJ3Byb2NlZHVyZSc6CiAgICAgICAgICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmZpbGVbJ3Byb2NlZHVyZSddKSA/ICR0aGlzLT5maWxlWydwcm9jZWR1cmUnXSA6IGZhbHNlOwogICAgICAgICAgICBjYXNlICdmdW5jdGlvbic6CiAgICAgICAgICAgICAgICByZXR1cm4gaXNzZXQoJHRoaXMtPmZpbGVbJ2Z1bmN0aW9uJ10pID8gJHRoaXMtPmZpbGVbJ2Z1bmN0aW9uJ10gOiBmYWxzZTsKICAgICAgICAgICAgY2FzZSAncmVzdWx0JzoKICAgICAgICAgICAgICAgIHJldHVybiAkdGhpcy0+ZmlsZTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIlVucmVjb2duaXplZCBmaWxlIHByb3BlcnR5OiAkbmFtZSIpOwogICAgICAgIH0KICAgIH0KfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJmdW5jdGlvbmV4Y2VwdGlvbicsIGZhbHNlKSk6CmNsYXNzIENsb25lckZ1bmN0aW9uRXhjZXB0aW9uIGV4dGVuZHMgQ2xvbmVyRXhjZXB0aW9uCnsKICAgIHByaXZhdGUgJGZuID0gJyc7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRmbk5hbWUsICRjb2RlID0gc2VsZjo6RVJST1JfVU5FWFBFQ1RFRCkKICAgIHsKICAgICAgICAkdGhpcy0+Zm4gPSAkZm5OYW1lOwogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoIkVycm9yIGNhbGxpbmcgJGZuTmFtZSIsICRjb2RlLCBjbG9uZXJfbGFzdF9lcnJvcl9mb3IoJGZuTmFtZSkpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9hY3Rpb25faGFzaCcpKToKZnVuY3Rpb24gY2xvbmVyX2FjdGlvbl9oYXNoKCRyb290LCBhcnJheSAkZmlsZXMsICR0ZW1wSGFzaGVzLCAkdGltZW91dCwgJG1heEhhc2hTaXplLCAkY2h1bmtTaXplLCAkaGFzaEJ1ZlNpemUpCnsKICAgICRoYXNoTGVuICA9IDMyOwogICAgJHJlc3VsdCAgID0gbmV3IENsb25lckhhc2hSZXN1bHQoKTsKICAgICRkZWFkbGluZSA9IG5ldyBDbG9uZXJEZWFkbGluZSgkdGltZW91dCk7CgogICAgZm9yZWFjaCAoJGZpbGVzIGFzICRmaWxlKSB7CiAgICAgICAgJGZpbGUgPSBuZXcgQ2xvbmVyRmlsZUluZm8oJGZpbGUpOwogICAgICAgIGlmICgkZmlsZS0+ZGlyKSB7CiAgICAgICAgICAgICRyZXN1bHQtPmFwcGVuZEVycm9yKCdjYW5ub3QgaGFzaCBkaXInKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmIChjb3VudCgkcmVzdWx0LT5oYXNoZXMpICE9PSAwICYmICRkZWFkbGluZS0+ZG9uZSgpKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICAkaGFzaGVzICAgICA9ICR0ZW1wSGFzaGVzOwogICAgICAgICR0ZW1wSGFzaGVzID0gJyc7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJGZpbGVQYXRoID0gIiRyb290LyRmaWxlLT5wYXRoIjsKICAgICAgICAgICAgJHN0YXQgICAgID0gY2xvbmVyX2ZzX3N0YXQoJGZpbGVQYXRoKTsKICAgICAgICAgICAgaWYgKCRzdGF0LT5nZXRTaXplKCkgIT09ICRmaWxlLT5zaXplKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoInNpemUgY2hhbmdlZCwgd2FzICVkLCBub3cgaXMgJWQiLCAkZmlsZS0+c2l6ZSwgJHN0YXQtPmdldFNpemUoKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRoYXNoID0gJ2Q0MWQ4Y2Q5OGYwMGIyMDRlOTgwMDk5OGVjZjg0MjdlJzsgLy8gbWQ1KCcnKQogICAgICAgICAgICBpZiAoJGZpbGUtPnNpemUgPT09IDApIHsKICAgICAgICAgICAgICAgIC8vIFplcm8tbGVuZ3RoIGZpbGUuCiAgICAgICAgICAgICAgICAkcmVzdWx0LT5hcHBlbmRPSygkaGFzaCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRmaWxlLT5zaXplIDw9ICRtYXhIYXNoU2l6ZSkgewogICAgICAgICAgICAgICAgLy8gU2luZ2xlLWNodW5rIGZpbGUuCiAgICAgICAgICAgICAgICAkaGFzaCA9IG1kNV9maWxlKCRmaWxlUGF0aCk7CiAgICAgICAgICAgICAgICBpZiAoJGhhc2ggPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kRXJyb3IoY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdtZDVfZmlsZScpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRyZXN1bHQtPmFwcGVuZE9LKCRoYXNoKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIENodW5rIGhhc2guCiAgICAgICAgICAgICRwYXJ0cyA9IChpbnQpY2VpbCgkc3RhdC0+Z2V0U2l6ZSgpIC8gJGNodW5rU2l6ZSk7CiAgICAgICAgICAgIGZvciAoJGkgPSBzdHJsZW4oJGhhc2hlcykgLyAkaGFzaExlbjsgJGkgPCAkcGFydHM7ICRpKyspIHsKICAgICAgICAgICAgICAgIGlmICgoJGZoID0gQGZvcGVuKCRmaWxlUGF0aCwgJ3JiJykpID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJGU0Z1bmN0aW9uRXhjZXB0aW9uKCdmb3BlbicsICRmaWxlUGF0aCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbGltaXQgPSAoJHBhcnRzID09PSAxKSA/ICRmaWxlLT5zaXplIDogbWluKCRjaHVua1NpemUsICRmaWxlLT5zaXplIC0gJGkgKiAkY2h1bmtTaXplKTsKICAgICAgICAgICAgICAgIGlmICgkaSAhPT0gMCAmJiAoQGZzZWVrKCRmaCwgJGkgKiAkY2h1bmtTaXplKSA9PT0gZmFsc2UpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckZTRnVuY3Rpb25FeGNlcHRpb24oJ2ZzZWVrJywgJGZpbGVQYXRoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoKCRjdHggPSBAaGFzaF9pbml0KCdtZDUnKSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckZ1bmN0aW9uRXhjZXB0aW9uKCdoYXNoX2luaXQnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHdoaWxlICgkbGltaXQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gTGltaXQgY2h1bmsgc2l6ZSB0byBlaXRoZXIgb3VyIHJlbWFpbmluZyBjaHVuayBvciBtYXggY2h1bmsgc2l6ZQogICAgICAgICAgICAgICAgICAgICRyZWFkICA9IG1pbigkbGltaXQsICRoYXNoQnVmU2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgJGxpbWl0IC09ICRyZWFkOwogICAgICAgICAgICAgICAgICAgIGlmICgoJGNodW5rID0gQGZyZWFkKCRmaCwgJHJlYWQpKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckZTRXhjZXB0aW9uKCdmcmVhZCcsICRmaWxlUGF0aCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChAaGFzaF91cGRhdGUoJGN0eCwgJGNodW5rKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckZ1bmN0aW9uRXhjZXB0aW9uKCdoYXNoX3VwZGF0ZScpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEBmY2xvc2UoJGZoKTsKICAgICAgICAgICAgICAgIGlmICgoJGhhc2ggPSBAaGFzaF9maW5hbCgkY3R4KSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckZ1bmN0aW9uRXhjZXB0aW9uKCdoYXNoX2ZpbmFsJyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRpICsgMSA9PT0gJHBhcnRzKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gTGFzdCAoYW5kIG1heWJlIG9ubHkpIHBhcnQuCiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkaGFzaGVzKSAhPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBFbmQgb2YgbXVsdGlwYXJ0IGhhc2guCiAgICAgICAgICAgICAgICAgICAgICAgICRoYXNoID0gbWQ1KCRoYXNoZXMuJGhhc2gpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBCcmVhayB3aWxsIGhhcHBlbiBoZXJlLgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkaGFzaGVzIC49ICRoYXNoOwogICAgICAgICAgICAgICAgICAgIC8vIE5lZWQgdG8gaGFzaCBtb3JlIHBhcnRzLgogICAgICAgICAgICAgICAgICAgIGlmICgkZGVhZGxpbmUtPmRvbmUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0LT5hcHBlbmRUZW1wSGFzaGVzKCRoYXNoZXMpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kT0soJGhhc2gpOwogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoaXNzZXQoJGZoKSAmJiBpc19yZXNvdXJjZSgkZmgpKSB7CiAgICAgICAgICAgICAgICBAZmNsb3NlKCRmaCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kRXJyb3IoJGUtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuICRyZXN1bHQ7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVydG91Y2hyZXN1bHQnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJUb3VjaFJlc3VsdAp7CiAgICBwdWJsaWMgJGZpbGVzID0gYXJyYXkoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gYXBwZW5kT0soKQogICAgewogICAgICAgIC8vIEZvcmNlIGRlZmF1bHQgc3RhdHVzIHNvIGl0IGRvZXNuJ3QganNvbl9lbmNvZGUgaW50byBhbiBhcnJheS4KICAgICAgICAkdGhpcy0+ZmlsZXNbXSA9IGFycmF5KCdzJyA9PiAwKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYXBwZW5kRXJyb3IoJGVycm9yKQogICAgewogICAgICAgICR0aGlzLT5maWxlc1tdID0gYXJyYXkoJ2UnID0+ICRlcnJvcik7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl90b3VjaCcpKToKZnVuY3Rpb24gY2xvbmVyX2FjdGlvbl90b3VjaCgkcm9vdCwgYXJyYXkgJGZpbGVzLCAkdGltZW91dCkKewogICAgJHJlc3VsdCAgID0gbmV3IENsb25lclRvdWNoUmVzdWx0KCk7CiAgICAkZGVhZGxpbmUgPSBuZXcgQ2xvbmVyRGVhZGxpbmUoJHRpbWVvdXQpOwogICAgZm9yZWFjaCAoJGZpbGVzIGFzICRpID0+ICRmaWxlKSB7CiAgICAgICAgaWYgKGNvdW50KCRyZXN1bHQtPmZpbGVzKSAhPT0gMCAmJiAkZGVhZGxpbmUtPmRvbmUoKSkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgJGZpbGUgICAgID0gbmV3IENsb25lckZpbGVJbmZvKCRmaWxlKTsKICAgICAgICAkZnVsbFBhdGggPSAiJHJvb3QvJGZpbGUtPnBhdGgiOwogICAgICAgIGlmIChAdG91Y2goJGZ1bGxQYXRoLCAkZmlsZS0+bXRpbWUpID09PSBmYWxzZSkgewogICAgICAgICAgICAkcmVzdWx0LT5hcHBlbmRFcnJvcihjbG9uZXJfbGFzdF9lcnJvcl9mb3IoJ3RvdWNoJykpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJHJlc3VsdC0+YXBwZW5kT0soKTsKICAgIH0KICAgIHJldHVybiAkcmVzdWx0Owp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnJlYWRyZXN1bHQnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJSZWFkUmVzdWx0CnsKICAgIHB1YmxpYyAkZmlsZXMgPSBhcnJheSgpOwogICAgcHVibGljICRsYXN0T2Zmc2V0ID0gMDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gYXBwZW5kRU9GKCRkYXRhKQogICAgewogICAgICAgICR0aGlzLT5maWxlc1tdID0gYXJyYXkoJ2InID0+IGJhc2U2NF9lbmNvZGUoJGRhdGEpLCAnZicgPT4gdHJ1ZSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZENodW5rKCRkYXRhKQogICAgewogICAgICAgICR0aGlzLT5maWxlc1tdID0gYXJyYXkoJ2InID0+IGJhc2U2NF9lbmNvZGUoJGRhdGEpKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYXBwZW5kRXJyb3IoJHN0YXR1cywgJGVycm9yKQogICAgewogICAgICAgICR0aGlzLT5maWxlc1tdID0gYXJyYXkoJ28nID0+ICRzdGF0dXMsICdlJyA9PiAkZXJyb3IpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9nZXRfZmlsZV9jaHVuaycpKToKZnVuY3Rpb24gY2xvbmVyX2dldF9maWxlX2NodW5rKCRwYXRoLCAkb2Zmc2V0LCAkbGltaXQpCnsKICAgICRmcCA9IEBmb3BlbigkcGF0aCwgJ3JiJyk7CiAgICBpZiAoJGZwID09PSBmYWxzZSkgewogICAgICAgIHJldHVybiBhcnJheSgnJywgZmFsc2UsIGNsb25lcl9sYXN0X2Vycm9yX2ZvcignZm9wZW4nKSk7CiAgICB9CiAgICBpZiAoJG9mZnNldCkgewogICAgICAgIGlmIChAZnNlZWsoJGZwLCAkb2Zmc2V0KSAhPT0gMCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXkoJycsIGZhbHNlLCBjbG9uZXJfbGFzdF9lcnJvcl9mb3IoJ2ZzZWVrJykpOwogICAgICAgIH0KICAgIH0KCiAgICAkY29udGVudCA9ICcnOwogICAgJG5lZWQgICAgPSAkbGltaXQ7CiAgICAkZW9mICAgICA9IGZhbHNlOwogICAgd2hpbGUgKCEkZW9mICYmICRuZWVkID4gMCkgewogICAgICAgICRjaHVuayA9IEBmcmVhZCgkZnAsICRuZWVkKTsKICAgICAgICBpZiAoJGNodW5rID09PSBmYWxzZSkgewogICAgICAgICAgICAkZXJyID0gY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdmcmVhZCcpOwogICAgICAgICAgICBAZmNsb3NlKCRmcCk7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgnJywgZmFsc2UsICRlcnIpOwogICAgICAgIH0KICAgICAgICAkY29udGVudCAuPSAkY2h1bms7CiAgICAgICAgJGVvZiAgICAgPSBAZmVvZigkZnApOwogICAgICAgICRuZWVkICAgIC09IHN0cmxlbigkY2h1bmspOwogICAgfQogICAgaWYgKCEkZW9mKSB7CiAgICAgICAgLy8gQnVmZmVyIGZ1bGw7IHBlZWsgMSBieXRlIHRvIHNlZSBpZiB3ZSByZWFjaGVkIGVvZi4KICAgICAgICBAZnJlYWQoJGZwLCAxKTsKICAgICAgICAkZW9mID0gQGZlb2YoJGZwKTsKICAgIH0KICAgIEBmY2xvc2UoJGZwKTsKCiAgICByZXR1cm4gYXJyYXkoJGNvbnRlbnQsICRlb2YsICcnKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfYWN0aW9uX3JlYWQnKSk6CmZ1bmN0aW9uIGNsb25lcl9hY3Rpb25fcmVhZCgkcm9vdCwgJGlkLCBhcnJheSAkZmlsZXMsICRsYXN0T2Zmc2V0LCAkbGltaXQpCnsKICAgICRyZXN1bHQgPSBuZXcgQ2xvbmVyUmVhZFJlc3VsdCgpOwogICAgJGN1cnNvciA9IDA7CiAgICBpZiAoJGxpbWl0IDw9IDApIHsKICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdMaW1pdCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvJyk7CiAgICB9CiAgICBmb3JlYWNoICgkZmlsZXMgYXMgJGZpbGUpIHsKICAgICAgICAkb2Zmc2V0ICAgICA9ICRsYXN0T2Zmc2V0OwogICAgICAgICRsYXN0T2Zmc2V0ID0gMDsKICAgICAgICAkZmlsZSAgICAgICA9IG5ldyBDbG9uZXJGaWxlSW5mbygkZmlsZSk7CiAgICAgICAgaWYgKCRjdXJzb3IgPj0gJGxpbWl0ICYmIGNvdW50KCRyZXN1bHQtPmZpbGVzKSAhPT0gMCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKCRmaWxlLT5kaXIgfHwgJGZpbGUtPmlzTGluaykgewogICAgICAgICAgICAkcmVzdWx0LT5hcHBlbmRFT0YoJycpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJGZ1bGxQYXRoID0gcnRyaW0oJHJvb3QsICcvJykuIi8kZmlsZS0+cGF0aCI7CiAgICAgICAgaWYgKHN0cm5jbXAoJGZpbGUtPnBhdGgsICdtd3BfZGIvJywgNykgPT09IDApIHsKICAgICAgICAgICAgJHRyeUZ1bGxQYXRoID0gc3lzX2dldF90ZW1wX2RpcigpLiIvbXdwX2RiJGlkLyIuc3Vic3RyKCRmaWxlLT5wYXRoLCA3KTsKICAgICAgICAgICAgaWYgKEBmaWxlc2l6ZSgkdHJ5RnVsbFBhdGgpID09PSAkZmlsZS0+c2l6ZSkgewogICAgICAgICAgICAgICAgJGZ1bGxQYXRoID0gJHRyeUZ1bGxQYXRoOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgoJHNpemUgPSBAZmlsZXNpemUoJGZ1bGxQYXRoKSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICRyZXN1bHQtPmFwcGVuZEVycm9yKENsb25lclN0YXR1czo6RVJST1IsIGNsb25lcl9sYXN0X2Vycm9yX2ZvcignZmlsZXNpemUnKSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJHNpemUgIT09ICRmaWxlLT5zaXplKSB7CiAgICAgICAgICAgICRyZXN1bHQtPmFwcGVuZEVycm9yKENsb25lclN0YXR1czo6RVJST1IsICJmaWxlIHNpemUgY2hhbmdlZCB0byAkc2l6ZSBieXRlcywgZXhwZWN0ZWQgJGZpbGUtPnNpemUgYnl0ZXMiKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRtYXhMZW4gPSBtaW4oJGxpbWl0IC0gJGN1cnNvciwgJGZpbGUtPnNpemUpOwogICAgICAgIGxpc3QoJGNvbnRlbnQsICRlb2YsICRlcnIpID0gY2xvbmVyX2dldF9maWxlX2NodW5rKCRmdWxsUGF0aCwgJG9mZnNldCwgJG1heExlbik7CiAgICAgICAgaWYgKHN0cmxlbigkZXJyKSkgewogICAgICAgICAgICAkcmVzdWx0LT5hcHBlbmRFcnJvcihDbG9uZXJTdGF0dXM6OkVSUk9SLCAkZXJyKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgkZW9mKSB7CiAgICAgICAgICAgIGlmIChzdHJsZW4oJGNvbnRlbnQpICsgJG9mZnNldCAhPT0gJGZpbGUtPnNpemUpIHsKICAgICAgICAgICAgICAgICRlcnJvciA9IHNwcmludGYoJ2V4cGVjdGVkIHRvIHJlYWQgJWQgYnl0ZXMgYXQgb2Zmc2V0ICVkLCBidXQgZ290IG9ubHkgJWQnLCAkZmlsZS0+c2l6ZSAtICRvZmZzZXQsICRvZmZzZXQsIHN0cmxlbigkY29udGVudCkpOwogICAgICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kRXJyb3IoQ2xvbmVyU3RhdHVzOjpFUlJPUiwgJGVycm9yKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXN1bHQtPmFwcGVuZEVPRigkY29udGVudCk7CiAgICAgICAgICAgICRjdXJzb3IgKz0gc3RybGVuKCRjb250ZW50KTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICgkZmlsZS0+c2l6ZSA8PSAkb2Zmc2V0ICsgc3RybGVuKCRjb250ZW50KSkgewogICAgICAgICAgICAkcmVzdWx0LT5hcHBlbmRFcnJvcihDbG9uZXJTdGF0dXM6OkVSUk9SLCBzcHJpbnRmKCdmaWxlIHNpemUgd2FzICVkIGJ5dGVzLCBidXQgJWQgYnl0ZXMgd2VyZSByZWFkJywgJGZpbGUtPnNpemUsICRvZmZzZXQgKyBzdHJsZW4oJGNvbnRlbnQpKSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAkcmVzdWx0LT5hcHBlbmRDaHVuaygkY29udGVudCk7CiAgICAgICAgJHJlc3VsdC0+bGFzdE9mZnNldCA9ICRvZmZzZXQgKyBzdHJsZW4oJGNvbnRlbnQpOwogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuICRyZXN1bHQ7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyd3JpdGVyZXN1bHQnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJXcml0ZVJlc3VsdAp7CiAgICBwdWJsaWMgJGZpbGVzID0gYXJyYXkoKTsKICAgIHB1YmxpYyAkbGFzdE9mZnNldCA9IDA7CgogICAgcHVibGljIGZ1bmN0aW9uIGFwcGVuZE9LKCR3cml0dGVuKQogICAgewogICAgICAgICR0aGlzLT5maWxlc1tdID0gYXJyYXkoJ3cnID0+ICR3cml0dGVuKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYXBwZW5kRXJyb3IoJHN0YXR1cywgJGVycm9yKQogICAgewogICAgICAgICR0aGlzLT5maWxlc1tdID0gYXJyYXkoJ28nID0+ICRzdGF0dXMsICdlJyA9PiAkZXJyb3IpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9jbGVhcl9zdGF0X2NhY2hlJykpOgpmdW5jdGlvbiBjbG9uZXJfY2xlYXJfc3RhdF9jYWNoZSgkcGF0aCA9IG51bGwpIHsKICAgIGlmIChQSFBfVkVSU0lPTl9JRCA8IDUwMzAwIHx8ICRwYXRoID09PSBudWxsKSB7CiAgICAgICAgY2xlYXJzdGF0Y2FjaGUoKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjbGVhcnN0YXRjYWNoZSh0cnVlLCAkcGF0aCk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX21ha2VfZGlyJykpOgpmdW5jdGlvbiBjbG9uZXJfbWFrZV9kaXIoJHJvb3QsICRwYXRoKSB7CiAgICAkZGlyID0gc3RydG9rKCRwYXRoLCAnLycpOwogICAgZG8gewogICAgICAgICRyb290IC49ICcvJy4kZGlyOwogICAgICAgIGlmICgkZGlyID09PSAnLi4nKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoaXNfZGlyKCRyb290KSkgewogICAgICAgICAgICBpZiAoIWlzX3dyaXRhYmxlKCRyb290KSkgewogICAgICAgICAgICAgICAgQGNobW9kKCRyb290LCAwNzc3KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJGRpck1hZGUgPSBAbWtkaXIoJHJvb3QsIDA3NzcsIHRydWUpOwogICAgICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBkaXIgd2FzIG5vdCBtYWRlIGJ5IGFub3RoZXIgcHJvY2VzcyBpbiBhIHJhY2UgY29uZGl0aW9uLgogICAgICAgIGlmICgkZGlyTWFkZSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgJGxhc3RFcnJvciA9IGNsb25lcl9sYXN0X2Vycm9yX2ZvcignbWtkaXInKTsKICAgICAgICAgICAgY2xvbmVyX2NsZWFyX3N0YXRfY2FjaGUoJHJvb3QpOwogICAgICAgICAgICBpZiAoIWlzX2Rpcigkcm9vdCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbGFzdEVycm9yOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSB3aGlsZSAoaXNfc3RyaW5nKCRkaXIgPSBzdHJ0b2soJy8nKSkpOwoKICAgIGlmICghaXNfd3JpdGFibGUoJHJvb3QpKSB7CiAgICAgICAgcmV0dXJuICJkaXJlY3RvcnkgJHJvb3QgaXMgbm90IHdyaXRhYmxlIjsKICAgIH0KCiAgICByZXR1cm4gJyc7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3JlbW92ZV9maWxlX29yX2RpcicpKToKZnVuY3Rpb24gY2xvbmVyX3JlbW92ZV9maWxlX29yX2RpcigkcGF0aCkKewogICAgJGF0dGVtcHQgICAgID0gMDsKICAgICRtYXhBdHRlbXB0cyA9IDM7CiAgICAkZXJyICAgICAgICAgPSAnJzsKICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgJGF0dGVtcHQrKzsKICAgICAgICBpZiAoJGF0dGVtcHQgPiAkbWF4QXR0ZW1wdHMpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgICRlcnIgPSAnJzsKICAgICAgICBpZiAoJGF0dGVtcHQgPiAxKSB7CiAgICAgICAgICAgIHVzbGVlcCgxMDAwMDAgKiBwb3coMiwgJGF0dGVtcHQpKTsKICAgICAgICAgICAgY2xvbmVyX2NsZWFyX3N0YXRfY2FjaGUoJHBhdGgpOwogICAgICAgIH0KICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRwYXRoKSkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKCFpc193cml0YWJsZSgkcGF0aCkpIHsKICAgICAgICAgICAgQGNobW9kKCRwYXRoLCAwNzc3KTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzX2RpcigkcGF0aCkpIHsKICAgICAgICAgICAgZm9yZWFjaCAoQHNjYW5kaXIoJHBhdGgpIGFzICRjaGlsZCkgewogICAgICAgICAgICAgICAgaWYgKCRjaGlsZCA9PT0gJy4nIHx8ICRjaGlsZCA9PT0gJy4uJykgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkZXJyID0gY2xvbmVyX3JlbW92ZV9maWxlX29yX2RpcigiJHBhdGgvJGNoaWxkIikpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRlcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKEBybWRpcigkcGF0aCkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkZXJyID0gY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdybWRpcicpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoQHVubGluaygkcGF0aCkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkZXJyID0gY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCd1bmxpbmsnKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuICRlcnI7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3dyaXRlX2ZpbGUnKSk6CmZ1bmN0aW9uIGNsb25lcl93cml0ZV9maWxlKCRwYXRoLCAkb2Zmc2V0LCAkY29udGVudCkgewogICAgJGF0dGVtcHQgPSAwOwogICAgJGxlbmd0aCAgPSBzdHJsZW4oJGNvbnRlbnQpOwogICAgJHRvdGFsICAgPSAkb2Zmc2V0ICsgJGxlbmd0aDsKICAgICRlcnIgICAgID0gJyc7CiAgICAkZnAgICAgICA9IG51bGw7CiAgICBkbyB7CiAgICAgICAgY2xvbmVyX2NsZWFyX3N0YXRfY2FjaGUoJHBhdGgpOwogICAgICAgIGlmICgkYXR0ZW1wdCA+IDApIHsKICAgICAgICAgICAgLy8gU2xlZXAgZm9yIDIwMG1zLCA0MDBtcywgODAwcywgMS42cyBldGMuCiAgICAgICAgICAgIHVzbGVlcCgxMDAwMDAgKiBwb3coMiwgJGF0dGVtcHQpKTsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcigiJGVyciAoZmlsZTogJHBhdGgsIGF0dGVtcHQ6ICRhdHRlbXB0LCBvZmZzZXQ6ICRvZmZzZXQsIGxlbmd0aDogJGxlbmd0aCkiKTsKICAgICAgICB9CiAgICAgICAgLy8gQ2hlY2sgZmlsZSBzaXplIGlmIGFwcGVuZGluZyBjb250ZW50LgogICAgICAgIGlmICgkb2Zmc2V0ICYmICgoJHNpemUgPSBmaWxlc2l6ZSgkcGF0aCkpIDwgJG9mZnNldCkpIHsKICAgICAgICAgICAgaWYgKCRzaXplID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJGVyciA9IGNsb25lcl9sYXN0X2Vycm9yX2ZvcignZmlsZXNpemUnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRlcnIgPSAiY29ycnVwdCBmaWxlOyB3cm90ZSAkb2Zmc2V0IGJ5dGVzLCBidXQgZmlsZSBpcyAkc2l6ZSBieXRlcyI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRlcnIgPSAnJzsKICAgICAgICBpZiAoaXNfcmVzb3VyY2UoJGZwKSkgewogICAgICAgICAgICBAZmNsb3NlKCRmcCk7CiAgICAgICAgfQogICAgICAgIGlmIChpc19kaXIoJHBhdGgpKSB7CiAgICAgICAgICAgIGlmIChzdHJsZW4oJGVyciA9IGNsb25lcl9yZW1vdmVfZmlsZV9vcl9kaXIoJHBhdGgpKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJGZwID0gQGZvcGVuKCRwYXRoLCAkb2Zmc2V0ID8gJ2NiJyA6ICd3YicpOwogICAgICAgIGlmICgkZnAgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICRlcnIgPSBjbG9uZXJfbGFzdF9lcnJvcl9mb3IoJ2ZvcGVuJyk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJG9mZnNldCkgewogICAgICAgICAgICBpZiAoQGZzZWVrKCRmcCwgJG9mZnNldCkgIT09IDApIHsKICAgICAgICAgICAgICAgICRlcnIgPSBjbG9uZXJfbGFzdF9lcnJvcl9mb3IoJ2ZzZWVrJyk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoQGZ3cml0ZSgkZnAsICRjb250ZW50KSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgJGVyciA9IGNsb25lcl9sYXN0X2Vycm9yX2ZvcignZndyaXRlJyk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoQGZjbG9zZSgkZnApID09PSBmYWxzZSkgewogICAgICAgICAgICAkZXJyID0gY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdmY2xvc2UnKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRmcCA9IG51bGw7CiAgICAgICAgLy8gVGhpcyBpcyBtYW5kYXRvcnkgYmVmb3JlIHN0YXQtaW5nIHRoZSBmaWxlLgogICAgICAgIGNsb25lcl9jbGVhcl9zdGF0X2NhY2hlKCRwYXRoKTsKICAgICAgICBpZiAoKCRzaXplID0gQGZpbGVzaXplKCRwYXRoKSkgIT09ICR0b3RhbCkgewogICAgICAgICAgICBpZiAoJHNpemUgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAkZXJyID0gY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdmaWxlc2l6ZScpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVyciA9ICJmaWxlIHNpemUgYWZ0ZXIgd3JpdGUgaXMgJHNpemU7IGV4cGVjdGVkICRvZmZzZXQrJGxlbmd0aD0kdG90YWwiOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9IHdoaWxlIChzdHJsZW4oJGVycikgJiYgKyskYXR0ZW1wdCA8IDMpOwoKICAgIHJldHVybiAkZXJyOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9hY3Rpb25fd3JpdGUnKSk6CmZ1bmN0aW9uIGNsb25lcl9hY3Rpb25fd3JpdGUoJHJvb3QsIGFycmF5ICRmaWxlcywgJGxhc3RPZmZzZXQpCnsKICAgICRyZXN1bHQgPSBuZXcgQ2xvbmVyV3JpdGVSZXN1bHQoKTsKICAgIGZvcmVhY2ggKCRmaWxlcyBhcyAkZmlsZSkgewogICAgICAgICRmaWxlICAgICAgID0gbmV3IENsb25lckZpbGVJbmZvKCRmaWxlKTsKICAgICAgICAkb2Zmc2V0ICAgICA9ICRsYXN0T2Zmc2V0OwogICAgICAgICRsYXN0T2Zmc2V0ID0gMDsKICAgICAgICBpZiAoJGZpbGUtPmRpcikgewogICAgICAgICAgICBpZiAoc3RybGVuKCRlcnJvciA9IGNsb25lcl9tYWtlX2Rpcigkcm9vdCwgJGZpbGUtPnBhdGgpKSkgewogICAgICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kRXJyb3IoQ2xvbmVyU3RhdHVzOjpFUlJPUiwgJGVycm9yKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRyZXN1bHQtPmFwcGVuZE9LKDApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKHN0cmxlbigkZXJyb3IgPSBjbG9uZXJfbWFrZV9kaXIoJHJvb3QsIGRpcm5hbWUoJGZpbGUtPnBhdGgpKSkpIHsKICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kRXJyb3IoQ2xvbmVyU3RhdHVzOjpFUlJPUiwgJGVycm9yKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRmaWxlUGF0aCA9ICIkcm9vdC8kZmlsZS0+cGF0aCI7CiAgICAgICAgaWYgKCRmaWxlLT5wcm9jZWR1cmUpIHsKICAgICAgICAgICAgJGZpbGVQYXRoID0gc3RyX3JlcGxhY2UoIm13cF9kYi8iLCAibXdwX2RiL213cF9wcm9jZWR1cmVfIiwgJGZpbGVQYXRoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCRmaWxlLT5mdW5jdGlvbikgewogICAgICAgICAgICAkZmlsZVBhdGggPSBzdHJfcmVwbGFjZSgibXdwX2RiLyIsICJtd3BfZGIvbXdwX2Z1bmN0aW9uXyIsICRmaWxlUGF0aCk7CiAgICAgICAgfQogICAgICAgIGlmICgkZmlsZS0+aXNMaW5rKSB7CiAgICAgICAgICAgIEB1bmxpbmsoJGZpbGVQYXRoKTsKICAgICAgICAgICAgaWYgKEBzeW1saW5rKCRmaWxlLT5saW5rLCAkZmlsZVBhdGgpID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kRXJyb3IoQ2xvbmVyU3RhdHVzOjpFUlJPUiwgY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdzeW1saW5rJykpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kT0soMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRkYXRhICA9ICRmaWxlLT5kYXRhOwogICAgICAgICRlcnJvciA9IGNsb25lcl93cml0ZV9maWxlKCRmaWxlUGF0aCwgJG9mZnNldCwgJGRhdGEpOwogICAgICAgIGlmIChzdHJsZW4oJGVycm9yKSkgewogICAgICAgICAgICAkcmVzdWx0LT5hcHBlbmRFcnJvcihDbG9uZXJTdGF0dXM6OkVSUk9SLCAkZXJyb3IpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJHJlc3VsdC0+YXBwZW5kT2soc3RybGVuKCRkYXRhKSk7CiAgICAgICAgaWYgKCEkZmlsZS0+ZW9mKSB7CiAgICAgICAgICAgICRsYXN0T2Zmc2V0ID0gJG9mZnNldCArIHN0cmxlbigkZGF0YSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJGZpbGUtPm10aW1lKSB7CiAgICAgICAgICAgIEB0b3VjaCgkZmlsZVBhdGgsICRmaWxlLT5tdGltZSk7CiAgICAgICAgfQogICAgfQogICAgJHJlc3VsdC0+bGFzdE9mZnNldCA9ICRsYXN0T2Zmc2V0OwogICAgcmV0dXJuICRyZXN1bHQ7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyYWN0aW9uJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyQWN0aW9uCnsKICAgIHB1YmxpYyAkaWQgPSAnJzsKICAgIHB1YmxpYyAkYWN0aW9uID0gJyc7CiAgICBwdWJsaWMgJHBhcmFtczsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEBwYXJhbSBtaXhlZCAgJHBhcmFtcwogICAgICoKICAgICAqIEBzZWUgY2xvbmVyX2V4ZWN1dGVfYWN0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgJHBhcmFtcykKICAgIHsKICAgICAgICAkdGhpcy0+aWQgICAgID0gbWQ1KHVuaXFpZCgnJywgdHJ1ZSkpOwogICAgICAgICR0aGlzLT5hY3Rpb24gPSAkbmFtZTsKICAgICAgICAkdGhpcy0+cGFyYW1zID0gJHBhcmFtczsKICAgIH0KfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJhY3Rpb25yZXN1bHRub3Rmb3VuZGV4Y2VwdGlvbicsIGZhbHNlKSk6CmNsYXNzIENsb25lckFjdGlvblJlc3VsdE5vdEZvdW5kRXhjZXB0aW9uIGV4dGVuZHMgQ2xvbmVyRXhjZXB0aW9uCnsKICAgIHB1YmxpYyAkYWN0aW9uID0gJyc7CiAgICBwdWJsaWMgJHVybCA9ICcnOwogICAgcHVibGljICRzdGF0dXNDb2RlID0gMDsKICAgIHB1YmxpYyAkc3RhdHVzID0gJyc7CiAgICBwdWJsaWMgJGhlYWRlcnMgPSBhcnJheSgpOwogICAgcHVibGljICRib2R5ID0gJyc7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICAgICRzdGF0dXNDb2RlCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdGF0dXMKICAgICAqIEBwYXJhbSBhcnJheSAgJGhlYWRlcnMKICAgICAqIEBwYXJhbSBzdHJpbmcgJGJvZHkKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRzdGF0dXNDb2RlLCAkc3RhdHVzLCBhcnJheSAkaGVhZGVycywgJGJvZHkpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YXR1c0NvZGUgPSAkc3RhdHVzQ29kZTsKICAgICAgICAkdGhpcy0+c3RhdHVzICAgICA9ICRzdGF0dXM7CiAgICAgICAgJHRoaXMtPmhlYWRlcnMgICAgPSAkaGVhZGVyczsKICAgICAgICAkdGhpcy0+Ym9keSAgICAgICA9ICRib2R5OwogICAgICAgICRleGNlcnB0ICAgICAgICAgID0gdHJpbShzdWJzdHIocHJlZ19yZXBsYWNlKCd7XHMrfScsICcgJywgc3RyaXBfdGFncygkYm9keSkpLCAwLCAxMDI0KSk7CiAgICAgICAgJG1lc3NhZ2UgICAgICAgICAgPSBzcHJpbnRmKCdyZXN1bHQgbm90IGZvdW5kLCBnb3Qgc3RhdHVzICIlZCAlcyI7IGV4Y2VycHQ6ICIlcyInLCAkc3RhdHVzQ29kZSwgJHN0YXR1cywgJGV4Y2VycHQpOwogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoJG1lc3NhZ2UsICdyZWFjdGlvbl9ub3RfZm91bmQnKTsKICAgIH0KfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJyZW1vdGVlcnJvcmV4Y2VwdGlvbicsIGZhbHNlKSk6CmNsYXNzIENsb25lclJlbW90ZUVycm9yRXhjZXB0aW9uIGV4dGVuZHMgQ2xvbmVyRXhjZXB0aW9uCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbWVzc2FnZSwgJGNvZGUsICRpbnRlcm5hbEVycm9yKQogICAgewogICAgICAgIGlmIChzdHJsZW4oJGludGVybmFsRXJyb3IpKSB7CiAgICAgICAgICAgICRpbnRlcm5hbEVycm9yID0gJzsgaW50ZXJuYWwgZXJyb3I6ICcuJGludGVybmFsRXJyb3I7CiAgICAgICAgfQogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3Qoc3ByaW50ZignZXJyb3IgY29kZSAlczogJXMlcycsICRjb2RlLCAkbWVzc2FnZSwgJGludGVybmFsRXJyb3IpLCAncmVtb3RlX2ZhdGFsX2Vycm9yJyk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyYWN0aW9uZXhjZXB0aW9uJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyQWN0aW9uRXhjZXB0aW9uIGV4dGVuZHMgQ2xvbmVyRXhjZXB0aW9uCnsKICAgIHB1YmxpYyAkYWN0aW9uID0gJyc7CiAgICBwdWJsaWMgJHRhcmdldCA9ICcnOwogICAgcHVibGljICRlcnJvcjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGFjdGlvbiwgJHRhcmdldCwgRXhjZXB0aW9uICRleGNlcHRpb24pCiAgICB7CiAgICAgICAgJHRoaXMtPmFjdGlvbiA9ICRhY3Rpb247CiAgICAgICAgJHRoaXMtPnRhcmdldCA9ICR0YXJnZXQ7CiAgICAgICAgJHRoaXMtPmVycm9yICA9ICRleGNlcHRpb24tPmdldE1lc3NhZ2UoKTsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KHNwcmludGYoJ2FjdGlvbiAlcy0+JXMgZmFpbGVkOiAlcycsICR0YXJnZXQsICRhY3Rpb24sICRleGNlcHRpb24tPmdldE1lc3NhZ2UoKSksICdhY3Rpb25fZXJyb3InKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfc2VuZF9hY3Rpb24nKSk6CmZ1bmN0aW9uIGNsb25lcl9zZW5kX2FjdGlvbihDbG9uZXJVUkwgJHVybCwgQ2xvbmVyQWN0aW9uICRhY3Rpb24pCnsKICAgIGlmIChpc3NldCgkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10pICYmIGlzX3N0cmluZygkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10pKSB7CiAgICAgICAgJHVhID0gJF9TRVJWRVJbJ0hUVFBfVVNFUl9BR0VOVCddOwogICAgfSBlbHNlIHsKICAgICAgICAkdWEgPSAnTW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTBfMTNfNikgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzY4LjAuMzQ0MC4xMDYgU2FmYXJpLzUzNy4zNic7CiAgICB9CiAgICAkcmV0cmllZCA9IGZhbHNlOwogICAgJHByZWZpeCAgPSBjbG9uZXJfYmFzZTY0X3JvdGF0ZSgkYWN0aW9uLT5pZCk7CiAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRwYXlsb2FkID0gY2xvbmVyX2Jhc2U2NF9yb3RhdGUoanNvbl9lbmNvZGUoJGFjdGlvbikpOwogICAgICAgICAgICAkcmVxICAgICA9IGNsb25lcl9odHRwX29wZW5fcmVxdWVzdCgnUE9TVCcsICR1cmwsIGFycmF5KAogICAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZScgICAgPT4gJ2FwcGxpY2F0aW9uL2pzb24nLAogICAgICAgICAgICAgICAgJ0NvbnRlbnQtTGVuZ3RoJyAgPT4gc3RybGVuKCRwYXlsb2FkKSwKICAgICAgICAgICAgICAgICdDb25uZWN0aW9uJyAgICAgID0+ICdjbG9zZScsCiAgICAgICAgICAgICAgICAnSG9zdCcgICAgICAgICAgICA9PiAkdXJsLT5nZXRIVFRQSG9zdCgpLAogICAgICAgICAgICAgICAgLy8gSW1pdGF0ZSBhIHN0YW5kYXJkIGJyb3dzZXIgcmVxdWVzdC4KICAgICAgICAgICAgICAgICdVc2VyLUFnZW50JyAgICAgID0+ICR1YSwKICAgICAgICAgICAgICAgICdSZWZlcmVyJyAgICAgICAgID0+ICR1cmwtPl9fdG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICdBY2NlcHQnICAgICAgICAgID0+ICd0ZXh0L2h0bWwsYXBwbGljYXRpb24veGh0bWwreG1sLGFwcGxpY2F0aW9uL3htbDtxPTAuOSxpbWFnZS93ZWJwLGltYWdlL2FwbmcsKi8qO3E9MC44JywKICAgICAgICAgICAgICAgICdBY2NlcHQtTGFuZ3VhZ2UnID0+ICdlbi1VUyxlbjtxPTAuOSxzcjtxPTAuOCxicztxPTAuNycsCiAgICAgICAgICAgICksIDEwKTsKICAgICAgICAgICAgc29ja2V0X3NldF90aW1lb3V0KCRyZXEsIDEwKTsKICAgICAgICAgICAgaWYgKEBmd3JpdGUoJHJlcSwgJHBheWxvYWQpID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lck5ldFNvY2tldEV4Y2VwdGlvbignZndyaXRlJywgJHJlcSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlcyAgICA9IGNsb25lcl9odHRwX2dldF9yZXNwb25zZV9oZWFkZXJzKCRyZXEsIDEyMCk7CiAgICAgICAgICAgICRyZXN1bHQgPSAkZXJyb3IgPSBudWxsOwogICAgICAgICAgICAkYm9keSAgID0gJHJlcy0+cmVhZCgxMjApOwogICAgICAgICAgICAkb2Zmc2V0ID0gMDsKICAgICAgICAgICAgd2hpbGUgKCRvZmZzZXQgPCBzdHJsZW4oJGJvZHkpKSB7CiAgICAgICAgICAgICAgICAkbGluZUVuZCA9IHN0cnBvcygkYm9keSwgIlxuIiwgJG9mZnNldCk7CiAgICAgICAgICAgICAgICBpZiAoJGxpbmVFbmQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgJGxpbmVFbmQgPSBzdHJsZW4oJGJvZHkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBDYXB0dXJlIFxuCiAgICAgICAgICAgICAgICAgICAgJGxpbmVFbmQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRsaW5lICAgPSBzdWJzdHIoJGJvZHksICRvZmZzZXQsICRsaW5lRW5kIC0gJG9mZnNldCk7CiAgICAgICAgICAgICAgICAkb2Zmc2V0ICs9ICRsaW5lRW5kOwogICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkbGluZSkgPCAoc3RybGVuKCRwcmVmaXgpICsgMSkpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzdHJuY21wKCRwcmVmaXgsICRsaW5lLCBzdHJsZW4oJHByZWZpeCkpICE9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkZGF0YSA9IGpzb25fZGVjb2RlKGNsb25lcl9iYXNlNjRfcm90YXRlKHN1YnN0cigkbGluZSwgc3RybGVuKCRwcmVmaXgpICsgMSkpLCB0cnVlKTsKICAgICAgICAgICAgICAgIHN3aXRjaCAoJGxpbmVbc3RybGVuKCRwcmVmaXgpXSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgJyEnOgogICAgICAgICAgICAgICAgICAgICAgICAkZXJyb3IgPSAkZGF0YTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnLic6CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXN1bHQgPSAkZGF0YTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBAZmNsb3NlKCRyZXMtPmJvZHkpOwogICAgICAgICAgICBpZiAoIWlzc2V0KCRyZXN1bHQpICYmICFpc3NldCgkZXJyb3IpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyQWN0aW9uUmVzdWx0Tm90Rm91bmRFeGNlcHRpb24oJHJlcy0+c3RhdHVzQ29kZSwgJHJlcy0+c3RhdHVzLCAkcmVzLT5oZWFkZXJzLCAkYm9keSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFNlZSBjbG9uZXJfc2VuZF9zdWNjZXNzX3Jlc3BvbnNlL2Nsb25lcl9zZW5kX2Vycm9yX3Jlc3BvbnNlIGZvciBleHBlY3RlZCBzdHJ1Y3R1cmUuCiAgICAgICAgICAgIGlmIChpc3NldCgkZXJyb3JbJ2Vycm9yJ10sICRlcnJvclsnZmlsZSddLCAkZXJyb3JbJ2xpbmUnXSkpIHsKICAgICAgICAgICAgICAgICRtZXNzYWdlID0gc3ByaW50ZignJXMgaW4gJXM6JWQnLCAkZXJyb3JbJ21lc3NhZ2UnXSwgJGVycm9yWydmaWxlJ10sICRlcnJvclsnbGluZSddKTsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJSZW1vdGVFcnJvckV4Y2VwdGlvbigkbWVzc2FnZSwgJGVycm9yWydlcnJvciddLCAkZXJyb3JbJ2ludGVybmFsRXJyb3InXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChDbG9uZXJFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCEkcmV0cmllZCkgewogICAgICAgICAgICAgICAgJHJldHJpZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjbG9uZXJfaHR0cF9kbygnR0VUJywgJHVybC0+X190b1N0cmluZygpLCAnJywgJycsIDIwKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZTIpIHsKICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKCdHRVQgcmVxdWVzdCBhZnRlciBmYWlsZWQgUE9TVCBhY3Rpb24gZmFpbGVkOiAnLiRlMi0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyQWN0aW9uRXhjZXB0aW9uKCRhY3Rpb24tPmFjdGlvbiwgJHVybC0+X190b1N0cmluZygpLCAkZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBSZXRyeSBpbml0aWFsIHJlcXVlc3QuCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyQWN0aW9uRXhjZXB0aW9uKCRhY3Rpb24tPmFjdGlvbiwgJHVybC0+X190b1N0cmluZygpLCAkZSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgLyoqIEBub2luc3BlY3Rpb24gUGhwVW5kZWZpbmVkVmFyaWFibGVJbnNwZWN0aW9uICovCiAgICByZXR1cm4gJHJlc3VsdDsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfYWN0aW9uX3B1c2gnKSk6CmZ1bmN0aW9uIGNsb25lcl9hY3Rpb25fcHVzaCgkcm9vdCwgJHJlbW90ZVJvb3QsICRpZCwgJHJlbW90ZUlELCBhcnJheSAkZmlsZXMsICR1cmwsICRsYXN0T2Zmc2V0LCAkbGltaXQpCnsKICAgICRyZXN1bHRzICAgID0gYXJyYXkoKTsKICAgICRwYXlsb2FkICAgID0gYXJyYXkoKTsKICAgICRzZW50ICAgICAgID0gYXJyYXkoKTsKICAgICRyZWFkUmVzdWx0ID0gY2xvbmVyX2FjdGlvbl9yZWFkKCRyb290LCAkaWQsICRmaWxlcywgJGxhc3RPZmZzZXQsICRsaW1pdCk7CiAgICBmb3JlYWNoICgkcmVhZFJlc3VsdC0+ZmlsZXMgYXMgJGkgPT4gJHJlYWRPcCkgewogICAgICAgIGlmICghZW1wdHkoJHJlYWRPcFsnbyddKSkgewogICAgICAgICAgICAkcmVzdWx0c1tdID0gJHJlYWRPcDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICR3cml0ZU9wICAgPSAkZmlsZXNbJGldICsgYXJyYXkoCiAgICAgICAgICAgICAgICAnZGF0YTY0JyA9PiAkcmVhZE9wWydiJ10sCiAgICAgICAgICAgICAgICAnZW9mJyAgICA9PiBlbXB0eSgkcmVhZE9wWydmJ10pID8gZmFsc2UgOiB0cnVlLAogICAgICAgICAgICApOwogICAgICAgICRwYXlsb2FkW10gPSAkd3JpdGVPcDsKICAgICAgICAkc2VudFtdICAgID0gJGk7CiAgICAgICAgJHJlc3VsdHNbXSA9IG51bGw7CiAgICB9CiAgICAkYWN0aW9uID0gbmV3IENsb25lckFjdGlvbignd3JpdGUnLCBhcnJheSgnZmlsZXMnID0+ICRwYXlsb2FkLCAnbGFzdE9mZnNldCcgPT4gJGxhc3RPZmZzZXQsICdyb290JyA9PiAkcmVtb3RlUm9vdCwgJ2lkJyA9PiAkcmVtb3RlSUQpKTsKICAgICRyZXN1bHQgPSBjbG9uZXJfc2VuZF9hY3Rpb24oQ2xvbmVyVVJMOjpmcm9tU3RyaW5nKCR1cmwpLCAkYWN0aW9uKTsKICAgIGZvcmVhY2ggKCRyZXN1bHRbJ2ZpbGVzJ10gYXMgJGkgPT4gJHdyaXRlT3BSZXN1bHQpIHsKICAgICAgICAkcmVzdWx0c1skc2VudFskaV1dID0gJHdyaXRlT3BSZXN1bHQ7CiAgICB9CiAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgJ2ZpbGVzJyAgICAgID0+ICRyZXN1bHRzLAogICAgICAgICdsYXN0T2Zmc2V0JyA9PiAkcmVzdWx0WydsYXN0T2Zmc2V0J10sCiAgICApOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9hY3Rpb25fcHVsbCcpKToKZnVuY3Rpb24gY2xvbmVyX2FjdGlvbl9wdWxsKCRyb290LCAkcmVtb3RlUm9vdCwgJHJlbW90ZUlELCBhcnJheSAkZmlsZXMsICR1cmwsICRsYXN0T2Zmc2V0LCAkbGltaXQpCnsKICAgICRyZXN1bHRzID0gYXJyYXkoKTsKICAgICRwYXlsb2FkID0gYXJyYXkoKTsKICAgICRzZW50ICAgID0gYXJyYXkoKTsKICAgICRhY3Rpb24gID0gbmV3IENsb25lckFjdGlvbigncmVhZCcsIGFycmF5KCdmaWxlcycgPT4gJGZpbGVzLCAnbGFzdE9mZnNldCcgPT4gJGxhc3RPZmZzZXQsICdsaW1pdCcgPT4gJGxpbWl0LCAncm9vdCcgPT4gJHJlbW90ZVJvb3QsICdpZCcgPT4gJHJlbW90ZUlEKSk7CiAgICAvKiogQHZhciBDbG9uZXJSZWFkUmVzdWx0ICRyZWFjdGlvbiAqLwogICAgJHJlYWN0aW9uID0gY2xvbmVyX3NlbmRfYWN0aW9uKENsb25lclVSTDo6ZnJvbVN0cmluZygkdXJsKSwgJGFjdGlvbik7CiAgICBmb3JlYWNoICgkcmVhY3Rpb25bJ2ZpbGVzJ10gYXMgJGkgPT4gJHJlYWRPcCkgewogICAgICAgIC8vIFNlZSBDbG9uZXJSZWFkUmVzdWx0IHN0cnVjdHVyZS4KICAgICAgICBpZiAoIWVtcHR5KCRyZWFkT3BbJ28nXSkpIHsKICAgICAgICAgICAgJHJlc3VsdHNbXSA9ICRyZWFkT3A7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAkd3JpdGVPcCAgID0gJGZpbGVzWyRpXSArIGFycmF5KAogICAgICAgICAgICAgICAgJ2RhdGE2NCcgPT4gJHJlYWRPcFsnYiddLAogICAgICAgICAgICAgICAgJ2VvZicgICAgPT4gZW1wdHkoJHJlYWRPcFsnZiddKSA/IGZhbHNlIDogdHJ1ZSwKICAgICAgICAgICAgKTsKICAgICAgICAkcGF5bG9hZFtdID0gJHdyaXRlT3A7CiAgICAgICAgJHNlbnRbXSAgICA9ICRpOwogICAgICAgICRyZXN1bHRzW10gPSBudWxsOwogICAgfQogICAgJHJlc3VsdCA9IGNsb25lcl9hY3Rpb25fd3JpdGUoJHJvb3QsICRwYXlsb2FkLCAkbGFzdE9mZnNldCk7CiAgICBmb3JlYWNoICgkcmVzdWx0LT5maWxlcyBhcyAkaSA9PiAkd3JpdGVPcFJlc3VsdCkgewogICAgICAgICRyZXN1bHRzWyRzZW50WyRpXV0gPSAkd3JpdGVPcFJlc3VsdDsKICAgIH0KICAgIHJldHVybiBhcnJheSgKICAgICAgICAnZmlsZXMnICAgICAgPT4gJHJlc3VsdHMsCiAgICAgICAgJ2xhc3RPZmZzZXQnID0+ICRyZXN1bHQtPmxhc3RPZmZzZXQsCiAgICApOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmRiY29ubicsIGZhbHNlKSk6CmludGVyZmFjZSBDbG9uZXJEQkNvbm4KewogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRxdWVyeQogICAgICogQHBhcmFtIGFycmF5ICAkcGFyYW1ldGVycwogICAgICogQHBhcmFtIGJvb2wgICAkdW5idWZmZXJlZCBTZXQgdG8gdHJ1ZSB0byBub3QgZmV0Y2ggYWxsIHJlc3VsdHMgaW50byBtZW1vcnkgYW5kIHRvIGluY3JlbWVudGFsbHkgcmVhZCBmcm9tIFNRTCBzZXJ2ZXIuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlZSBodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vbXlzcWxpbmZvLmNvbmNlcHRzLmJ1ZmZlcmluZy5waHAKICAgICAqCiAgICAgKiBAcmV0dXJuIENsb25lckRCU3RtdAogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBxdWVyeSgkcXVlcnksIGFycmF5ICRwYXJhbWV0ZXJzID0gYXJyYXkoKSwgJHVuYnVmZmVyZWQgPSBmYWxzZSk7CgogICAgLyoqCiAgICAgKiBOby1yZXR1cm4tdmFsdWUgdmVyc2lvbiBvZiB0aGUgcXVlcnkoKSBtZXRob2QuIEFsbG93cyBhZGFwdGVycwogICAgICogdG8gb3B0aW9uYWxseSBvcHRpbWl6ZSB0aGUgb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHF1ZXJ5CiAgICAgKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGV4ZWN1dGUoJHF1ZXJ5KTsKCiAgICAvKioKICAgICAqIEVzY2FwZXMgc3RyaW5nIGZvciBzYWZlIHVzZSBpbiBzdGF0ZW1lbnRzOyBxdW90ZXMgYXJlIGluY2x1ZGVkLgogICAgICoKICAgICAqIEBwYXJhbSBzdHJpbmcgJHZhbHVlCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcKICAgICAqCiAgICAgKiBAdGhyb3dzIENsb25lckV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZXNjYXBlKCR2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBDbG9zZXMgdGhlIGNvbm5lY3Rpb24uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbG9zZSgpOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmRiaW5mbycsIGZhbHNlKSk6CmNsYXNzIENsb25lckRCSW5mbwp7CiAgICBwdWJsaWMgJHVzZXIgPSAnJzsKICAgIHB1YmxpYyAkcGFzc3dvcmQgPSAnJzsKICAgIC8qKiBAdmFyIHN0cmluZyBodHRwczovL2NvZGV4LndvcmRwcmVzcy5vcmcvRWRpdGluZ193cC1jb25maWcucGhwI1Bvc3NpYmxlX0RCX0hPU1RfdmFsdWVzICovCiAgICBwdWJsaWMgJGhvc3QgPSAnJzsKICAgIHB1YmxpYyAkbmFtZSA9ICcnOwogICAgcHVibGljICR1c2VTU0wgPSBmYWxzZTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHVzZXIsICRwYXNzd29yZCwgJGhvc3QsICRuYW1lLCAkdXNlU1NMID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHRoaXMtPnVzZXIgICAgID0gJHVzZXI7CiAgICAgICAgJHRoaXMtPnBhc3N3b3JkID0gJHBhc3N3b3JkOwogICAgICAgICR0aGlzLT5ob3N0ICAgICA9ICRob3N0OwogICAgICAgICR0aGlzLT5uYW1lICAgICA9ICRuYW1lOwogICAgICAgICR0aGlzLT51c2VTU0wgICA9ICR1c2VTU0w7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmcm9tQXJyYXkoJGluZm8pCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCRpbmZvKSkgewogICAgICAgICAgICByZXR1cm4gc2VsZjo6Y3JlYXRlRW1wdHkoKTsKICAgICAgICB9IGVsc2VpZiAoJGluZm8gaW5zdGFuY2VvZiBzZWxmKSB7CiAgICAgICAgICAgIHJldHVybiAkaW5mbzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ldyBzZWxmKCRpbmZvWydkYlVzZXInXSwgJGluZm9bJ2RiUGFzc3dvcmQnXSwgJGluZm9bJ2RiSG9zdCddLCAkaW5mb1snZGJOYW1lJ10sICRpbmZvWydkYlNTTCddKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0SG9zdG5hbWUoKQogICAgewogICAgICAgICRwYXJ0cyA9IGV4cGxvZGUoJzonLCAkdGhpcy0+aG9zdCwgMik7CiAgICAgICAgaWYgKCRwYXJ0c1swXSA9PT0gJycpIHsKICAgICAgICAgICAgcmV0dXJuICdsb2NhbGhvc3QnOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHBhcnRzWzBdOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRQb3J0KCkKICAgIHsKICAgICAgICBpZiAoc3RycG9zKCR0aGlzLT5ob3N0LCAnLycpICE9PSBmYWxzZSkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgJHBhcnRzID0gZXhwbG9kZSgnOicsICR0aGlzLT5ob3N0LCAyKTsKICAgICAgICBpZiAoY291bnQoJHBhcnRzKSA9PT0gMikgewogICAgICAgICAgICByZXR1cm4gKGludCkkcGFydHNbMV07CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTb2NrZXQoKQogICAgewogICAgICAgIHJldHVybiBzZWxmOjpnZXRTb2NrZXRQYXRoKCR0aGlzLT5ob3N0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNyZWF0ZUVtcHR5KCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IHNlbGYoJycsICcnLCAnJywgJycpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB0b0FycmF5KCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICdkYlVzZXInICAgICA9PiAkdGhpcy0+dXNlciwKICAgICAgICAgICAgJ2RiUGFzc3dvcmQnID0+ICR0aGlzLT5wYXNzd29yZCwKICAgICAgICAgICAgJ2RiTmFtZScgICAgID0+ICR0aGlzLT5uYW1lLAogICAgICAgICAgICAnZGJIb3N0JyAgICAgPT4gJHRoaXMtPmhvc3QsCiAgICAgICAgICAgICdkYlNTTCcgICAgICA9PiAkdGhpcy0+dXNlU1NMLAogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldElEKCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZjo6Z2V0Q29ubmVjdGlvbklEKCR0aGlzLT5ob3N0LCAkdGhpcy0+bmFtZSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZnVuY3Rpb24gZ2V0Q29ubmVjdGlvbklEKCRob3N0bmFtZSwgJGRiTmFtZSkKICAgIHsKICAgICAgICBpZiAoc3RybGVuKCRob3N0bmFtZSkgPT09IDAgJiYgc3RybGVuKCRkYk5hbWUpID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CiAgICAgICAgJGhvc3QgPSBzZWxmOjpnZXRTb2NrZXRQYXRoKCRob3N0bmFtZSk7CiAgICAgICAgaWYgKCFzdHJsZW4oJGhvc3QpKSB7CiAgICAgICAgICAgICRob3N0ID0gJGhvc3RuYW1lOwogICAgICAgIH0KICAgICAgICBpZiAoc3RycG9zKCRob3N0LCAnOicpID09PSBmYWxzZSkgewogICAgICAgICAgICAkaG9zdCAuPSAnOjMzMDYnOwogICAgICAgIH0KICAgICAgICAkcGFydHMgICAgPSBleHBsb2RlKCc6JywgJGhvc3QsIDIpOwogICAgICAgICRwYXJ0c1swXSA9IHN0cnRvbG93ZXIoJHBhcnRzWzBdKTsKICAgICAgICBzd2l0Y2ggKCRwYXJ0c1swXSkgewogICAgICAgICAgICBjYXNlICcnOgogICAgICAgICAgICBjYXNlICdsb2NhbGhvc3QnOgogICAgICAgICAgICBjYXNlICcxMjcuMC4wLjEnOgogICAgICAgICAgICAgICAgJHBhcnRzWzBdID0gJ2xvY2FsaG9zdCc7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcGFydHNbMF0uJzonLiRwYXJ0c1sxXS4nLycuJGRiTmFtZTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmdW5jdGlvbiBnZXRTb2NrZXRQYXRoKCRob3N0KQogICAgewogICAgICAgIGlmIChzdHJwb3MoJGhvc3QsICcvJykgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CiAgICAgICAgJHBhcnRzID0gZXhwbG9kZSgnOicsICRob3N0LCAyKTsKICAgICAgICBpZiAoY291bnQoJHBhcnRzKSA9PT0gMikgewogICAgICAgICAgICByZXR1cm4gJHBhcnRzWzFdOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHBhcnRzWzBdOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9kYl9pbmZvJykpOgpmdW5jdGlvbiBjbG9uZXJfZGJfaW5mbyhDbG9uZXJEQkNvbm4gJGNvbm4pCnsKICAgICRpbmZvID0gYXJyYXkoCiAgICAgICAgJ2NvbGxhdGlvbicgPT4gYXJyYXkoKSwKICAgICAgICAnY2hhcnNldCcgICA9PiBhcnJheSgpLAogICAgKTsKICAgICRsaXN0ID0gJGNvbm4tPnF1ZXJ5KCJTSE9XIENPTExBVElPTiIpLT5mZXRjaEFsbCgpOwogICAgZm9yZWFjaCAoJGxpc3QgYXMgJHJvdykgewogICAgICAgICRpbmZvWydjb2xsYXRpb24nXVskcm93WydDb2xsYXRpb24nXV0gPSB0cnVlOwogICAgICAgICRpbmZvWydjaGFyc2V0J11bJHJvd1snQ2hhcnNldCddXSAgICAgPSB0cnVlOwogICAgfQogICAgcmV0dXJuICRpbmZvOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9kYl9jaGFyc2V0JykpOgpmdW5jdGlvbiBjbG9uZXJfZGJfY2hhcnNldChDbG9uZXJEQkNvbm4gJGNvbm4pCnsKICAgICRpbmZvID0gY2xvbmVyX2RiX2luZm8oJGNvbm4pOwogICAgJHRyeSAgPSAndXRmOG1iNCc7CiAgICBmb3JlYWNoICgkaW5mb1snY2hhcnNldCddIGFzICRjaGFyc2V0ID0+ICR0cnVlKSB7CiAgICAgICAgaWYgKHN0cnBvcygkY2hhcnNldCwgJHRyeSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRyeTsKICAgIH0KICAgIHJldHVybiAndXRmOCc7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2JpbmRfcXVlcnlfcGFyYW1zJykpOgpmdW5jdGlvbiBjbG9uZXJfYmluZF9xdWVyeV9wYXJhbXMoQ2xvbmVyREJDb25uICRjb25uLCAkcXVlcnksIGFycmF5ICRwYXJhbXMpCnsKICAgIGlmIChjb3VudCgkcGFyYW1zKSA9PT0gMCkgewogICAgICAgIHJldHVybiAkcXVlcnk7CiAgICB9CiAgICAkcmVwbGFjZW1lbnRzID0gYXJyYXkoKTsKICAgIGZvcmVhY2ggKCRwYXJhbXMgYXMgJG5hbWUgPT4gJHZhbHVlKSB7CiAgICAgICAgJHJlcGxhY2VtZW50c1siOiRuYW1lIl0gPSAkY29ubi0+ZXNjYXBlKCR2YWx1ZSk7CiAgICB9CiAgICByZXR1cm4gc3RydHIoJHF1ZXJ5LCAkcmVwbGFjZW1lbnRzKTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJkYnN0bXQnLCBmYWxzZSkpOgppbnRlcmZhY2UgQ2xvbmVyREJTdG10CnsKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE51bVJvd3MoKTsKCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICoKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBmZXRjaCgpOwoKICAgIC8qKgogICAgICogQHJldHVybiBhcnJheXxudWxsCiAgICAgKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZldGNoQWxsKCk7CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZyZWUoKTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJteXNxbGlzdG10JywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyTXlTUUxpU3RtdCBpbXBsZW1lbnRzIENsb25lckRCU3RtdAp7CiAgICBwcml2YXRlICRjb25uOwogICAgcHJpdmF0ZSAkcmVzdWx0OwoKICAgIC8qKgogICAgICogQHBhcmFtIG15c3FsaV9kcml2ZXIgICAgICAkcmVzdWx0CiAgICAgKiBAcGFyYW0gbXlzcWxpX3Jlc3VsdHxib29sICRyZXN1bHQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb25uLCAkcmVzdWx0KQogICAgewogICAgICAgICR0aGlzLT5jb25uICAgPSAkY29ubjsKICAgICAgICAkdGhpcy0+cmVzdWx0ID0gJHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gYXJyYXl8bnVsbAogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gZmV0Y2goKQogICAgewogICAgICAgIGlmICgoJHRoaXMtPnJlc3VsdCA9PT0gZmFsc2UgfHwgJHRoaXMtPnJlc3VsdCA9PT0gbnVsbCkgJiYgJHRoaXMtPmNvbm4tPmVycm5vKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oJHRoaXMtPmNvbm4tPmVycm9yLCAnZGJfcXVlcnlfZXJyb3InLCAkdGhpcy0+Y29ubi0+ZXJybm8pOwogICAgICAgIH0gZWxzZWlmICghJHRoaXMtPnJlc3VsdCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCJPbmx5IHJlYWQtb25seSBxdWVyaWVzIGNhbiB5aWVsZCByZXN1bHRzLiIsICdkYl9xdWVyeV9lcnJvcicpOwogICAgICAgIH0KICAgICAgICAkcmVzdWx0ID0gJHRoaXMtPnJlc3VsdC0+ZmV0Y2hfYXNzb2MoKTsKICAgICAgICBpZiAoKCRyZXN1bHQgPT09IGZhbHNlIHx8ICRyZXN1bHQgPT09IG51bGwpICYmICR0aGlzLT5jb25uLT5lcnJubykgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCR0aGlzLT5jb25uLT5lcnJvciwgJ2RiX3F1ZXJ5X2Vycm9yJywgJHRoaXMtPmNvbm4tPmVycm5vKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGFycmF5fG51bGwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZldGNoQWxsKCkKICAgIHsKICAgICAgICAkcm93cyA9IGFycmF5KCk7CiAgICAgICAgd2hpbGUgKCRyb3cgPSAkdGhpcy0+ZmV0Y2goKSkgewogICAgICAgICAgICAkcm93c1tdID0gJHJvdzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRyb3dzOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBpbnQKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldE51bVJvd3MoKQogICAgewogICAgICAgIGlmIChpc19ib29sKCR0aGlzLT5yZXN1bHQpKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHRoaXMtPnJlc3VsdC0+bnVtX3Jvd3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIGJvb2wKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZyZWUoKQogICAgewogICAgICAgIGlmIChpc19ib29sKCR0aGlzLT5yZXN1bHQpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgbXlzcWxpX2ZyZWVfcmVzdWx0KCR0aGlzLT5yZXN1bHQpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcm15c3FsaWNvbm4nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJNeVNRTGlDb25uIGltcGxlbWVudHMgQ2xvbmVyREJDb25uCnsKICAgIHByaXZhdGUgJGNvbm47CgogICAgLyoqCiAgICAgKiBAcGFyYW0gQ2xvbmVyREJJbmZvICRjb25mCiAgICAgKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KENsb25lckRCSW5mbyAkY29uZikKICAgIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ215c3FsaScpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIk15c3FsaSBleHRlbnNpb24gaXMgbm90IGVuYWJsZWQuIiwgJ215c3FsaV9kaXNhYmxlZCcpOwogICAgICAgIH0KCiAgICAgICAgbXlzcWxpX3JlcG9ydChNWVNRTElfUkVQT1JUX09GRik7CgogICAgICAgIC8vIFNpbGVuY2UgcG9zc2libGUgd2FybmluZ3MgdGhyb3duIGJ5IG15c3FsaQogICAgICAgIC8vIGUuZy4gV2FybmluZzogbXlzcWxpOjpteXNxbGkoKTogSGVhZGVycyBhbmQgY2xpZW50IGxpYnJhcnkgbWlub3IgdmVyc2lvbiBtaXNtYXRjaC4gSGVhZGVyczo1MDU0MCBMaWJyYXJ5OjUwNjIzCgogICAgICAgICRmbGFnID0gMDsKICAgICAgICBpZiAoJGNvbmYtPnVzZVNTTCkgewogICAgICAgICAgICAkZmxhZyA9IE1ZU1FMSV9DTElFTlRfU1NMOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPmNvbm4gPSBteXNxbGlfaW5pdCgpOwogICAgICAgICRzdWNjZXNzID0gJHRoaXMtPmNvbm4tPnJlYWxfY29ubmVjdCgkY29uZi0+Z2V0SG9zdG5hbWUoKSwgJGNvbmYtPnVzZXIsICRjb25mLT5wYXNzd29yZCwgJGNvbmYtPm5hbWUsICRjb25mLT5nZXRQb3J0KCksIG51bGwsICRmbGFnKTsKCiAgICAgICAgaWYgKCR0aGlzLT5jb25uLT5jb25uZWN0X2Vycm5vID09PSAyMDAyICYmIHN0cnRvbG93ZXIoJGNvbmYtPmdldEhvc3RuYW1lKCkpID09PSAnbG9jYWxob3N0JykgewogICAgICAgICAgICAvLyBBdHRlbXB0IHRvIHJlY292ZXIgZnJvbSAiWzIwMDJdIE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkiIGVycm9yLgogICAgICAgICAgICAkdGhpcy0+Y29ubiA9IG15c3FsaV9pbml0KCk7CiAgICAgICAgICAgICRzdWNjZXNzID0gJHRoaXMtPmNvbm4tPnJlYWxfY29ubmVjdCgnMTI3LjAuMC4xJywgJGNvbmYtPnVzZXIsICRjb25mLT5wYXNzd29yZCwgJGNvbmYtPm5hbWUsICRjb25mLT5nZXRQb3J0KCksIG51bGwsICRmbGFnKTsKICAgICAgICB9CiAgICAgICAgaWYgKCEkc3VjY2VzcykgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCR0aGlzLT5jb25uLT5jb25uZWN0X2Vycm9yLCAnZGJfY29ubmVjdF9lcnJvcicsICR0aGlzLT5jb25uLT5jb25uZWN0X2Vycm5vKTsKICAgICAgICB9CiAgICAgICAgaWYgKCEkdGhpcy0+Y29ubi0+cGluZygpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oJHRoaXMtPmNvbm4tPmNvbm5lY3RfZXJyb3IsICdkYl9jb25uZWN0X2Vycm9yJywgJHRoaXMtPmNvbm4tPmNvbm5lY3RfZXJybm8pOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+Y29ubi0+c2V0X2NoYXJzZXQoY2xvbmVyX2RiX2NoYXJzZXQoJHRoaXMpKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcXVlcnkoJHF1ZXJ5LCBhcnJheSAkcGFyYW1ldGVycyA9IGFycmF5KCksICR1bmJ1ZmZlcmVkID0gZmFsc2UpCiAgICB7CiAgICAgICAgJHF1ZXJ5ID0gY2xvbmVyX2JpbmRfcXVlcnlfcGFyYW1zKCR0aGlzLCAkcXVlcnksICRwYXJhbWV0ZXJzKTsKCiAgICAgICAgJHJlc3VsdE1vZGUgPSAkdW5idWZmZXJlZCA/IE1ZU1FMSV9VU0VfUkVTVUxUIDogMDsKICAgICAgICAkcmVzdWx0ICAgICA9ICR0aGlzLT5jb25uLT5xdWVyeSgkcXVlcnksICRyZXN1bHRNb2RlKTsKCiAgICAgICAgLy8gVGhlcmUgYXJlIGNlcnRhaW4gd2FybmluZ3MgdGhhdCByZXN1bHQgaW4gJHJlc3VsdCBiZWluZyBmYWxzZSwgZWcuIFBIUCBXYXJuaW5nOiAgbXlzcWxpOjpxdWVyeSgpOiBFbXB0eSBxdWVyeSwKICAgICAgICAvLyBidXQgdGhlIGVycm9yIG51bWJlciBpcyAwLgogICAgICAgIGlmICgkcmVzdWx0ID09PSBmYWxzZSAmJiAkdGhpcy0+Y29ubi0+ZXJybm8gIT09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbigkdGhpcy0+Y29ubi0+ZXJyb3IsICdkYl9xdWVyeV9lcnJvcicsICR0aGlzLT5jb25uLT5lcnJubyk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbmV3IENsb25lck15U1FMaVN0bXQoJHRoaXMtPmNvbm4sICRyZXN1bHQpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjdXRlKCRxdWVyeSkKICAgIHsKICAgICAgICAkdGhpcy0+cXVlcnkoJHF1ZXJ5KTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZXNjYXBlKCR2YWx1ZSkKICAgIHsKICAgICAgICByZXR1cm4gJHZhbHVlID09PSBudWxsID8gJ251bGwnIDogIiciLiR0aGlzLT5jb25uLT5yZWFsX2VzY2FwZV9zdHJpbmcoJHZhbHVlKS4iJyI7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNsb3NlKCkKICAgIHsKICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPmNvbm4pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmNvbm4tPmNsb3NlKCk7CiAgICAgICAgJHRoaXMtPmNvbm4gPSBudWxsOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnBkb3N0bXQnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJQRE9TdG10IGltcGxlbWVudHMgQ2xvbmVyREJTdG10CnsKICAgIHByaXZhdGUgJHN0YXRlbWVudDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUERPU3RhdGVtZW50ICRzdGF0ZW1lbnQpCiAgICB7CiAgICAgICAgJHRoaXMtPnN0YXRlbWVudCA9ICRzdGF0ZW1lbnQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGZldGNoKCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXRlbWVudC0+ZmV0Y2goKTsKICAgICAgICB9IGNhdGNoIChQRE9FeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJGludGVybmFsRXJyb3JDb2RlID0gaXNzZXQoJGUtPmVycm9ySW5mb1sxXSkgPyAoc3RyaW5nKSRlLT5lcnJvckluZm9bMV0gOiAnJzsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbigkZS0+Z2V0TWVzc2FnZSgpLCAnZGJfcXVlcnlfZXJyb3InLCAkaW50ZXJuYWxFcnJvckNvZGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZmV0Y2hBbGwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RhdGVtZW50LT5mZXRjaEFsbCgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXROdW1Sb3dzKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0YXRlbWVudC0+cm93Q291bnQoKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZnJlZSgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zdGF0ZW1lbnQtPmNsb3NlQ3Vyc29yKCk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVycGRvY29ubicsIGZhbHNlKSk6CmNsYXNzIENsb25lclBET0Nvbm4gaW1wbGVtZW50cyBDbG9uZXJEQkNvbm4KewogICAgLyoqCiAgICAgKiBAcGFyYW0gYm9vbCAkYXR0RW11bGF0ZVByZXBhcmVzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBzZXRBdHRFbXVsYXRlUHJlcGFyZXMoJGF0dEVtdWxhdGVQcmVwYXJlcykKICAgIHsKICAgICAgICAkdGhpcy0+Y29ubi0+c2V0QXR0cmlidXRlKFBETzo6QVRUUl9FTVVMQVRFX1BSRVBBUkVTLCAkYXR0RW11bGF0ZVByZXBhcmVzKTsKICAgIH0KCiAgICBwcml2YXRlICRjb25uOwogICAgcHJpdmF0ZSAkdW5idWZmZXJlZCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQHBhcmFtIENsb25lckRCSW5mbyAkY29uZgogICAgICoKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChDbG9uZXJEQkluZm8gJGNvbmYpCiAgICB7CiAgICAgICAgJG9wdGlvbnMgPSBhcnJheSgKICAgICAgICAgICAgUERPOjpBVFRSX0VSUk1PREUgICAgICAgICAgICA9PiBQRE86OkVSUk1PREVfRVhDRVBUSU9OLAogICAgICAgICAgICBQRE86OkFUVFJfREVGQVVMVF9GRVRDSF9NT0RFID0+IFBETzo6RkVUQ0hfQVNTT0MsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCRjb25mLT51c2VTU0wpIHsKICAgICAgICAgICAgJG9wdGlvbnNbUERPOjpNWVNRTF9BVFRSX1NTTF9DQV0gPSB0cnVlOwogICAgICAgICAgICAkb3B0aW9uc1tQRE86Ok1ZU1FMX0FUVFJfU1NMX1ZFUklGWV9TRVJWRVJfQ0VSVF0gPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICR0aGlzLT5jb25uID0gbmV3IFBETyhzZWxmOjpnZXREc24oJGNvbmYpLCAkY29uZi0+dXNlciwgJGNvbmYtPnBhc3N3b3JkLCAkb3B0aW9ucyk7CiAgICAgICAgfSBjYXRjaCAoUERPRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICgoaW50KSRlLT5nZXRDb2RlKCkgPT09IDIwMDIgJiYgc3RydG9sb3dlcigkY29uZi0+Z2V0SG9zdG5hbWUoKSkgPT09ICdsb2NhbGhvc3QnKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICRjb25mICAgICAgID0gY2xvbmUgJGNvbmY7CiAgICAgICAgICAgICAgICAgICAgJGNvbmYtPmhvc3QgPSAnMTI3LjAuMC4xJzsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+Y29ubiA9IG5ldyBQRE8oc2VsZjo6Z2V0RHNuKCRjb25mKSwgJGNvbmYtPnVzZXIsICRjb25mLT5wYXNzd29yZCwgJG9wdGlvbnMpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoUERPRXhjZXB0aW9uICRlMikgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oJGUtPmdldE1lc3NhZ2UoKSwgJ2RiX2Nvbm5lY3RfZXJyb3InLCAoc3RyaW5nKSRlMi0+Z2V0Q29kZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oJGUtPmdldE1lc3NhZ2UoKSwgJ2RiX2Nvbm5lY3RfZXJyb3InLCAoc3RyaW5nKSRlLT5nZXRDb2RlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIEFUVFJfRU1VTEFURV9QUkVQQVJFUyBpcyBub3QgbmVjZXNzYXJ5IGZvciBuZXdlciBteXNxbCB2ZXJzaW9ucwogICAgICAgIC8vIGh0dHBzOi8vd3d3LmRydXBhbC5vcmcvbm9kZS8yMzEwMDg5CiAgICAgICAgJHRoaXMtPmNvbm4tPnNldEF0dHJpYnV0ZShQRE86OkFUVFJfRU1VTEFURV9QUkVQQVJFUywgdmVyc2lvbl9jb21wYXJlKCR0aGlzLT5jb25uLT5nZXRBdHRyaWJ1dGUoUERPOjpBVFRSX1NFUlZFUl9WRVJTSU9OKSwgJzUuMS4xNycsICc8JykpOwogICAgICAgICR0aGlzLT5jb25uLT5leGVjKHNwcmludGYoJ1NFVCBOQU1FUyAlcycsIGNsb25lcl9kYl9jaGFyc2V0KCR0aGlzKSkpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBxdWVyeSgkcXVlcnksIGFycmF5ICRwYXJhbWV0ZXJzID0gYXJyYXkoKSwgJHVuYnVmZmVyZWQgPSBmYWxzZSkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnVuYnVmZmVyZWQgIT09ICR1bmJ1ZmZlcmVkKSB7CiAgICAgICAgICAgICR0aGlzLT51bmJ1ZmZlcmVkID0gJHVuYnVmZmVyZWQ7CiAgICAgICAgICAgICR0aGlzLT5jb25uLT5zZXRBdHRyaWJ1dGUoUERPOjpNWVNRTF9BVFRSX1VTRV9CVUZGRVJFRF9RVUVSWSwgISR1bmJ1ZmZlcmVkKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRzdGF0ZW1lbnQgPSAkdGhpcy0+Y29ubi0+cHJlcGFyZSgkcXVlcnkpOwogICAgICAgICAgICAkc3RhdGVtZW50LT5leGVjdXRlKCRwYXJhbWV0ZXJzKTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBDbG9uZXJQRE9TdG10KCRzdGF0ZW1lbnQpOwogICAgICAgIH0gY2F0Y2ggKFBET0V4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkaW50ZXJuYWxFcnJvckNvZGUgPSBpc3NldCgkZS0+ZXJyb3JJbmZvWzFdKSA/IChzdHJpbmcpJGUtPmVycm9ySW5mb1sxXSA6ICcnOwogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCRlLT5nZXRNZXNzYWdlKCksICdkYl9xdWVyeV9lcnJvcicsICRpbnRlcm5hbEVycm9yQ29kZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjdXRlKCRxdWVyeSkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAkdGhpcy0+Y29ubi0+ZXhlYygkcXVlcnkpOwogICAgICAgIH0gY2F0Y2ggKFBET0V4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkaW50ZXJuYWxFcnJvckNvZGUgPSBpc3NldCgkZS0+ZXJyb3JJbmZvWzFdKSA/IChzdHJpbmcpJGUtPmVycm9ySW5mb1sxXSA6ICcnOwogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCRlLT5nZXRNZXNzYWdlKCksICdkYl9xdWVyeV9lcnJvcicsICRpbnRlcm5hbEVycm9yQ29kZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBlc2NhcGUoJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiAkdmFsdWUgPT09IG51bGwgPyAnbnVsbCcgOiAkdGhpcy0+Y29ubi0+cXVvdGUoJHZhbHVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xvc2UoKQogICAgewogICAgICAgICR0aGlzLT5jb25uID0gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldERzbihDbG9uZXJEQkluZm8gJGNvbmYpCiAgICB7CiAgICAgICAgJHBkb1BhcmFtZXRlcnMgPSBhcnJheSgKICAgICAgICAgICAgJ2RibmFtZScgID0+ICRjb25mLT5uYW1lLAogICAgICAgICAgICAnY2hhcnNldCcgPT4gJ3V0ZjgnLAogICAgICAgICk7CiAgICAgICAgJHNvY2tldCAgICAgICAgPSAkY29uZi0+Z2V0U29ja2V0KCk7CiAgICAgICAgaWYgKCRzb2NrZXQgIT09ICcnKSB7CiAgICAgICAgICAgICRwZG9QYXJhbWV0ZXJzWydob3N0J10gICAgICAgID0gJGNvbmYtPmdldEhvc3RuYW1lKCk7CiAgICAgICAgICAgICRwZG9QYXJhbWV0ZXJzWyd1bml4X3NvY2tldCddID0gJHNvY2tldDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkcGRvUGFyYW1ldGVyc1snaG9zdCddID0gJGNvbmYtPmdldEhvc3RuYW1lKCk7CiAgICAgICAgICAgICRwZG9QYXJhbWV0ZXJzWydwb3J0J10gPSAkY29uZi0+Z2V0UG9ydCgpOwogICAgICAgIH0KICAgICAgICAkcGFyYW1ldGVycyA9IGFycmF5KCk7CiAgICAgICAgZm9yZWFjaCAoJHBkb1BhcmFtZXRlcnMgYXMgJG5hbWUgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgICRwYXJhbWV0ZXJzW10gPSAkbmFtZS4nPScuJHZhbHVlOwogICAgICAgIH0KICAgICAgICAkZHNuID0gc3ByaW50ZignbXlzcWw6JXMnLCBpbXBsb2RlKCc7JywgJHBhcmFtZXRlcnMpKTsKICAgICAgICByZXR1cm4gJGRzbjsKICAgIH0KfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJteXNxbHN0bXQnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJNeVNRTFN0bXQgaW1wbGVtZW50cyBDbG9uZXJEQlN0bXQKewogICAgcHJpdmF0ZSAkY29ubjsKICAgIHByaXZhdGUgJHJlc3VsdDsKCiAgICAvKioKICAgICAqIEBwYXJhbSByZXNvdXJjZSAgICAgICRjb25uCiAgICAgKiBAcGFyYW0gcmVzb3VyY2V8bnVsbCAkcmVzdWx0CiAgICAgKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRjb25uLCAkcmVzdWx0ID0gbnVsbCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29ubiAgID0gJGNvbm47CiAgICAgICAgJHRoaXMtPnJlc3VsdCA9ICRyZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGZldGNoKCkKICAgIHsKICAgICAgICBpZiAoJHRoaXMtPnJlc3VsdCA9PT0gZmFsc2UgJiYgbXlzcWxfZXJybm8oJHRoaXMtPmNvbm4pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24obXlzcWxfZXJyb3IoJHRoaXMtPmNvbm4pLCAnZGJfcXVlcnlfZXJyb3InLCBteXNxbF9lcnJubygkdGhpcy0+Y29ubikpOwogICAgICAgIH0gZWxzZWlmICghaXNfcmVzb3VyY2UoJHRoaXMtPnJlc3VsdCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbigiT25seSByZWFkLW9ubHkgcXVlcmllcyBjYW4geWllbGQgcmVzdWx0cy4iLCAnZGJfcXVlcnlfZXJyb3InKTsKICAgICAgICB9CiAgICAgICAgJHJlc3VsdCA9IEBteXNxbF9mZXRjaF9hc3NvYygkdGhpcy0+cmVzdWx0KTsKICAgICAgICBpZiAoJHJlc3VsdCA9PT0gZmFsc2UgJiYgbXlzcWxfZXJybm8oJHRoaXMtPmNvbm4pKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24obXlzcWxfZXJyb3IoJHRoaXMtPmNvbm4pLCAnZGJfcXVlcnlfZXJyb3InLCBteXNxbF9lcnJubygkdGhpcy0+Y29ubikpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZmV0Y2hBbGwoKQogICAgewogICAgICAgICRyb3dzID0gYXJyYXkoKTsKICAgICAgICB3aGlsZSAoJHJvdyA9ICR0aGlzLT5mZXRjaCgpKSB7CiAgICAgICAgICAgICRyb3dzW10gPSAkcm93OwogICAgICAgIH0KICAgICAgICByZXR1cm4gJHJvd3M7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldE51bVJvd3MoKQogICAgewogICAgICAgIHJldHVybiBteXNxbF9udW1fcm93cygkdGhpcy0+cmVzdWx0KTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZnJlZSgpCiAgICB7CiAgICAgICAgaWYgKCFpc19yZXNvdXJjZSgkdGhpcy0+cmVzdWx0KSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG15c3FsX2ZyZWVfcmVzdWx0KCR0aGlzLT5yZXN1bHQpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcm15c3FsY29ubicsIGZhbHNlKSk6CmNsYXNzIENsb25lck15U1FMQ29ubiBpbXBsZW1lbnRzIENsb25lckRCQ29ubgp7CiAgICBwcml2YXRlICRjb25uOwoKICAgIC8qKgogICAgICogQHBhcmFtIENsb25lckRCSW5mbyAkY29uZgogICAgICoKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChDbG9uZXJEQkluZm8gJGNvbmYpCiAgICB7CiAgICAgICAgaWYgKCFleHRlbnNpb25fbG9hZGVkKCdteXNxbCcpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIk15c3FsIGV4dGVuc2lvbiBpcyBub3QgbG9hZGVkLiIsICdteXNxbF9kaXNhYmxlZCcpOwogICAgICAgIH0KCiAgICAgICAgJGZsYWcgPSAwOwogICAgICAgIGlmICgkY29uZi0+dXNlU1NMKSB7CiAgICAgICAgICAgICRmbGFnID0gTVlTUUxfQ0xJRU5UX1NTTDsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5jb25uID0gQG15c3FsX2Nvbm5lY3QoJGNvbmYtPmhvc3QsICRjb25mLT51c2VyLCAkY29uZi0+cGFzc3dvcmQsIGZhbHNlLCAkZmxhZyk7CiAgICAgICAgaWYgKCFpc19yZXNvdXJjZSgkdGhpcy0+Y29ubikpIHsKICAgICAgICAgICAgLy8gQXR0ZW1wdCB0byByZWNvdmVyIGZyb20gIlsyMDAyXSBObyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IiBlcnJvci4KICAgICAgICAgICAgJGVycm5vID0gbXlzcWxfZXJybm8oKTsKICAgICAgICAgICAgaWYgKCRlcnJubyAhPT0gMjAwMiB8fCBzdHJ0b2xvd2VyKCRjb25mLT5nZXRIb3N0bmFtZSgpKSAhPT0gJ2xvY2FsaG9zdCcgfHwgIWlzX3Jlc291cmNlKCR0aGlzLT5jb25uID0gQG15c3FsX2Nvbm5lY3QoJzEyNy4wLjAuMScsICRjb25mLT51c2VyLCAkY29uZi0+cGFzc3dvcmQsIGZhbHNlLCAkZmxhZykpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKG15c3FsX2Vycm9yKCksICdkYl9jb25uZWN0X2Vycm9yJywgKHN0cmluZykkZXJybm8pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChteXNxbF9zZWxlY3RfZGIoJGNvbmYtPm5hbWUsICR0aGlzLT5jb25uKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihteXNxbF9lcnJvcigkdGhpcy0+Y29ubiksICdkYl9jb25uZWN0X2Vycm9yJywgKHN0cmluZylteXNxbF9lcnJubygkdGhpcy0+Y29ubikpOwogICAgICAgIH0KICAgICAgICBpZiAoIUBteXNxbF9zZXRfY2hhcnNldChjbG9uZXJfZGJfY2hhcnNldCgkdGhpcyksICR0aGlzLT5jb25uKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKG15c3FsX2Vycm9yKCR0aGlzLT5jb25uKSwgJ2RiX2Nvbm5lY3RfZXJyb3InLCAoc3RyaW5nKW15c3FsX2Vycm5vKCR0aGlzLT5jb25uKSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBxdWVyeSgkcXVlcnksIGFycmF5ICRwYXJhbWV0ZXJzID0gYXJyYXkoKSwgJHVuYnVmZmVyZWQgPSBmYWxzZSkKICAgIHsKICAgICAgICAkcXVlcnkgPSBjbG9uZXJfYmluZF9xdWVyeV9wYXJhbXMoJHRoaXMsICRxdWVyeSwgJHBhcmFtZXRlcnMpOwoKICAgICAgICBpZiAoJHVuYnVmZmVyZWQpIHsKICAgICAgICAgICAgJHJlc3VsdCA9IG15c3FsX3VuYnVmZmVyZWRfcXVlcnkoJHF1ZXJ5LCAkdGhpcy0+Y29ubik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHJlc3VsdCA9IG15c3FsX3F1ZXJ5KCRxdWVyeSwgJHRoaXMtPmNvbm4pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCRyZXN1bHQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24obXlzcWxfZXJyb3IoJHRoaXMtPmNvbm4pLCAnZGJfcXVlcnlfZXJyb3InLCAoc3RyaW5nKW15c3FsX2Vycm5vKCR0aGlzLT5jb25uKSk7CiAgICAgICAgfSBlbHNlaWYgKCRyZXN1bHQgPT09IHRydWUpIHsKICAgICAgICAgICAgLy8gVGhpcyBpcyBvbmUgb2YgSU5TRVJULCBVUERBVEUsIERFTEVURSwgRFJPUCBzdGF0ZW1lbnRzLgogICAgICAgICAgICByZXR1cm4gbmV3IENsb25lck15U1FMU3RtdCgkdGhpcy0+Y29ubiwgbnVsbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gVGhpcyBpcyBvbmUgb2YgU0VMRUNULCBTSE9XLCBERVNDUklCRSwgRVhQTEFJTiBzdGF0ZW1lbnRzLgogICAgICAgICAgICByZXR1cm4gbmV3IENsb25lck15U1FMU3RtdCgkdGhpcy0+Y29ubiwgJHJlc3VsdCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBleGVjdXRlKCRxdWVyeSkKICAgIHsKICAgICAgICAkdGhpcy0+cXVlcnkoJHF1ZXJ5KTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZXNjYXBlKCR2YWx1ZSkKICAgIHsKICAgICAgICByZXR1cm4gJHZhbHVlID09PSBudWxsID8gJ251bGwnIDogIiciLm15c3FsX3JlYWxfZXNjYXBlX3N0cmluZygkdmFsdWUsICR0aGlzLT5jb25uKS4iJyI7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGNsb3NlKCkKICAgIHsKICAgICAgICBpZiAoZW1wdHkoJHRoaXMtPmNvbm4pKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgbXlzcWxfY2xvc2UoJHRoaXMtPmNvbm4pOwogICAgICAgICR0aGlzLT5jb25uID0gbnVsbDsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZGJfY29ubl9pbml0JykpOgpmdW5jdGlvbiBjbG9uZXJfZGJfY29ubl9pbml0KENsb25lckRCSW5mbyAkY29uZikKewogICAgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ215c3FsaScpKSB7CiAgICAgICAgcmV0dXJuIG5ldyBDbG9uZXJNeVNRTGlDb25uKCRjb25mKTsKICAgIH0gZWxzZWlmIChleHRlbnNpb25fbG9hZGVkKCdwZG9fbXlzcWwnKSAmJiBQSFBfVkVSU0lPTl9JRCA+IDUwMjA2KSB7CiAgICAgICAgLy8gV2UgbmVlZCBQSFAgNS4yLjYgYmVjYXVzZSBvZiB0aGlzIG5hc3R5IFBETyBidWc6IGh0dHBzOi8vYnVncy5waHAubmV0L2J1Zy5waHA/aWQ9NDQyNTEKICAgICAgICByZXR1cm4gbmV3IENsb25lclBET0Nvbm4oJGNvbmYpOwogICAgfSBlbHNlaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ215c3FsJykpIHsKICAgICAgICByZXR1cm4gbmV3IENsb25lck15U1FMQ29ubigkY29uZik7CiAgICB9IGVsc2UgewogICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIk5vIGRyaXZlcnMgYXZhaWxhYmxlIGZvciBwaHAgbXlzcWwgY29ubmVjdGlvbi4iLCAnbm9fZGJfZHJpdmVycycpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmRiYWRhcHRlcnN0bXQnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJEQkFkYXB0ZXJTdG10IGltcGxlbWVudHMgQ2xvbmVyREJTdG10CnsKICAgIHByaXZhdGUgJGNvbm47CiAgICBwcml2YXRlICRzdG10OwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChDbG9uZXJEQkFkYXB0ZXIgJGNvbm4sIENsb25lckRCU3RtdCAkc3RtdCkKICAgIHsKICAgICAgICAkdGhpcy0+Y29ubiA9ICRjb25uOwogICAgICAgICR0aGlzLT5zdG10ID0gJHN0bXQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGZldGNoKCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnN0bXQtPmZldGNoKCk7CiAgICAgICAgfSBjYXRjaCAoQ2xvbmVyRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICR0aGlzLT5jb25uLT5jbG9zZSgpOwogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGZldGNoQWxsKCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnN0bXQtPmZldGNoQWxsKCk7CiAgICAgICAgfSBjYXRjaCAoQ2xvbmVyRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICR0aGlzLT5jb25uLT5jbG9zZSgpOwogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldE51bVJvd3MoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c3RtdC0+Z2V0TnVtUm93cygpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBmcmVlKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnN0bXQtPmZyZWUoKTsKICAgIH0KfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJkYmFkYXB0ZXInLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJEQkFkYXB0ZXIgaW1wbGVtZW50cyBDbG9uZXJEQkNvbm4KewogICAgLyoqIEB2YXIgc3RyaW5nICovCiAgICBwcml2YXRlICRpZDsKCiAgICAvKiogQHZhciBzdHJpbmdbXSAqLwogICAgcHJpdmF0ZSAkaWRMaXN0ID0gYXJyYXkoKTsKCiAgICAvKiogQHZhciBDbG9uZXJEQkluZm9bXVtdfENsb25lckRCQ29ubltdW10gKi8KICAgIHN0YXRpYyAkaGFuZGxlcyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJyYXl8bnVsbCAkZGIKICAgICAqCiAgICAgKiBAcmV0dXJuIENsb25lckRCQWRhcHRlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21BcnJheShhcnJheSAkZGIgPSBudWxsKQogICAgewogICAgICAgICRhZGFwdGVyID0gbmV3IHNlbGYoKTsKICAgICAgICBmb3JlYWNoICgkZGIgYXMgJGNyZWRlbnRpYWxzKSB7CiAgICAgICAgICAgICRpbmZvID0gQ2xvbmVyREJJbmZvOjpmcm9tQXJyYXkoJGNyZWRlbnRpYWxzKTsKICAgICAgICAgICAgJGlkICAgPSAkaW5mby0+Z2V0SUQoKTsKICAgICAgICAgICAgaWYgKGVtcHR5KHNlbGY6OiRoYW5kbGVzWyRpZF0pKSB7CiAgICAgICAgICAgICAgICBzZWxmOjokaGFuZGxlc1skaWRdID0gYXJyYXkoJGluZm8sIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRhZGFwdGVyLT5pZExpc3RbXSA9ICRpZDsKICAgICAgICAgICAgaWYgKCRhZGFwdGVyLT5pZCA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgJGFkYXB0ZXItPmlkID0gJGlkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAkYWRhcHRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gQ2xvbmVyREJDb25uCiAgICAgKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHJpdmF0ZSBmdW5jdGlvbiBjb25uKCkKICAgIHsKICAgICAgICBpZiAoZW1wdHkoc2VsZjo6JGhhbmRsZXNbJHRoaXMtPmlkXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignTm8gZGF0YWJhc2UgY29uZmlndXJhdGlvbiBhdmFpbGFibGUnKTsKICAgICAgICB9CiAgICAgICAgJGhhbmRsZSA9ICZzZWxmOjokaGFuZGxlc1skdGhpcy0+aWRdOwogICAgICAgIGlmIChlbXB0eSgkaGFuZGxlWzFdKSkgewogICAgICAgICAgICAkY29ubiAgICAgICA9IGNsb25lcl9kYl9jb25uX2luaXQoJGhhbmRsZVswXSk7CiAgICAgICAgICAgICRoYW5kbGVbMV0gID0gJGNvbm47CiAgICAgICAgICAgICRzZXRUaW1lb3V0ID0gNTcwOyAvLyBpbiBzZWNvbmRzLCBIVFRQIHJlcXVlc3QgdGltZW91dCBpcyAxMG1pbgogICAgICAgICAgICAkdGltZW91dHMgICA9IGFycmF5KCduZXRfcmVhZF90aW1lb3V0JywgJ25ldF93cml0ZV90aW1lb3V0JywgJ2ludGVyYWN0aXZlX3RpbWVvdXQnLCAnd2FpdF90aW1lb3V0Jyk7CiAgICAgICAgICAgICRzcWxWZXIgICAgID0gJGNvbm4tPnF1ZXJ5KCJTRUxFQ1QgQEB2ZXJzaW9uIiktPmZldGNoKCk7CiAgICAgICAgICAgICRzcWxWZXIgICAgID0gKHN0cmluZylAZW5kKCRzcWxWZXIpOwogICAgICAgICAgICBpZiAodmVyc2lvbl9jb21wYXJlKCc1LjcnLCAkc3FsVmVyLCAnPD0nKSkgewogICAgICAgICAgICAgICAgJHRpbWVvdXRzW10gPSAnbWF4X2V4ZWN1dGlvbl90aW1lJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JlYWNoICgkdGltZW91dHMgYXMgJG9wdGlvbk5hbWUpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgJHRpbWVvdXQgPSAkY29ubi0+cXVlcnkoIlNFTEVDVCBAQGxvY2FsLiRvcHRpb25OYW1lIiktPmZldGNoKCk7CiAgICAgICAgICAgICAgICAgICAgJHRpbWVvdXQgPSAoaW50KUBlbmQoJHRpbWVvdXQpOwogICAgICAgICAgICAgICAgICAgIGlmICgkdGltZW91dCA+IDAgJiYgJHRpbWVvdXQgPCAkc2V0VGltZW91dCkgewogICAgICAgICAgICAgICAgICAgICAgICAkY29ubi0+ZXhlY3V0ZSgiU0VUIEBAbG9jYWwuJG9wdGlvbk5hbWU9JHNldFRpbWVvdXQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJGhhbmRsZVsxXTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gdXNlQ29ubmVjdGlvbigkaWQpCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCRpZCkgfHwgY291bnQoJHRoaXMtPmlkTGlzdCkgPD0gMSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbl9hcnJheSgkaWQsICR0aGlzLT5pZExpc3QsIHRydWUpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmlkID0gJGlkOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb25uZWN0aW9uSURzKCkKICAgIHsKICAgICAgICBpZiAoY291bnQoJHRoaXMtPmlkTGlzdCkgPT09IDEpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCcnKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0aGlzLT5pZExpc3Q7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENvbmZpZ3VyYXRpb24oKQogICAgewogICAgICAgIGlmICghaXNzZXQoc2VsZjo6JGhhbmRsZXNbJHRoaXMtPmlkXSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignTm8gZGF0YWJhc2UgY29uZmlndXJhdGlvbiBhdmFpbGFibGUnKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGY6OiRoYW5kbGVzWyR0aGlzLT5pZF1bMF07CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHF1ZXJ5KCRxdWVyeSwgYXJyYXkgJHBhcmFtZXRlcnMgPSBhcnJheSgpLCAkdW5idWZmZXJlZCA9IGZhbHNlKQogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgQ2xvbmVyREJBZGFwdGVyU3RtdCgkdGhpcywgJHRoaXMtPmNvbm4oKS0+cXVlcnkoJHF1ZXJ5LCAkcGFyYW1ldGVycywgJHVuYnVmZmVyZWQpKTsKICAgICAgICB9IGNhdGNoIChDbG9uZXJFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHRoaXMtPmNsb3NlKCk7CiAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZXhlY3V0ZSgkcXVlcnkpCiAgICB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHRoaXMtPmNvbm4oKS0+ZXhlY3V0ZSgkcXVlcnkpOwogICAgICAgIH0gY2F0Y2ggKENsb25lckV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAkdGhpcy0+Y2xvc2UoKTsKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBlc2NhcGUoJHZhbHVlKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y29ubigpLT5lc2NhcGUoJHZhbHVlKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gY2xvc2UoKQogICAgewogICAgICAgIGlmIChlbXB0eShzZWxmOjokaGFuZGxlc1skdGhpcy0+aWRdWzFdKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHNlbGY6OiRoYW5kbGVzWyR0aGlzLT5pZF1bMV0tPmNsb3NlKCk7CiAgICAgICAgc2VsZjo6JGhhbmRsZXNbJHRoaXMtPmlkXVsxXSA9IG51bGw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjbG9zZUFsbCgpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoc2VsZjo6JGhhbmRsZXMgYXMgJGlkID0+ICYkaGFuZGxlKSB7CiAgICAgICAgICAgIGlmICgkaGFuZGxlWzFdKSB7CiAgICAgICAgICAgICAgICAkaGFuZGxlWzFdLT5jbG9zZSgpOwogICAgICAgICAgICAgICAgJGhhbmRsZVsxXSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHBpbmcoKQogICAgewogICAgICAgICRxdWVyeSA9ICR0aGlzLT5jb25uKCktPnF1ZXJ5KCdTRUxFQ1QgMScpOwogICAgICAgICRxdWVyeS0+ZmV0Y2hBbGwoKTsKICAgICAgICAkcXVlcnktPmZyZWUoKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZGJfY29ubicpKToKZnVuY3Rpb24gY2xvbmVyX2RiX2Nvbm4oYXJyYXkgJGRiID0gbnVsbCkKewogICAgcmV0dXJuIENsb25lckRCQWRhcHRlcjo6ZnJvbUFycmF5KCRkYik7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVydGFibGV0eXBlJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyVGFibGVUeXBlCnsKICAgIGNvbnN0IFJFR1VMQVIgPSAwOwogICAgY29uc3QgVklFVyA9IDE7CiAgICBjb25zdCBQUk9DRURVUkUgPSAyOwogICAgY29uc3QgRlVOQyA9IDM7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2xpc3Rfdmlld3MnKSk6CmZ1bmN0aW9uIGNsb25lcl9saXN0X3ZpZXdzKCRkYiwgYXJyYXkgJHRhYmxlTmFtZXMgPSBudWxsKQp7CiAgICAkY29ubiAgICAgID0gY2xvbmVyX2RiX2Nvbm4oJGRiKTsKICAgICRyZXN1bHQgICAgPSBhcnJheSgpOwogICAgZm9yZWFjaCAoJGNvbm4tPmdldENvbm5lY3Rpb25JRHMoKSBhcyAkY29ubmVjdGlvbklEKSB7CiAgICAgICAgJGNvbm4tPnVzZUNvbm5lY3Rpb24oJGNvbm5lY3Rpb25JRCk7CiAgICAgICAgJGZhaWxzID0gMDsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHZpZXdzID0gJGNvbm4tPnF1ZXJ5KCdTRUxFQ1QgYHRhYmxlX25hbWVgIEFTIGBuYW1lYCwgYGRlZmluZXJgIEFTIGBkZWZpbmVyYAogICAgICAgICAgICAgICAgICAgIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLlZJRVdTIFdIRVJFIHRhYmxlX3NjaGVtYSA9IDpkYl9uYW1lJywgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ2RiX25hbWUnICAgID0+ICRjb25uLT5nZXRDb25maWd1cmF0aW9uKCktPm5hbWUsCiAgICAgICAgICAgICAgICApKS0+ZmV0Y2hBbGwoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIENsb25lckV4Y2VwdGlvbiAmJiBzdHJsZW4oJGUtPmdldEludGVybmFsRXJyb3IoKSkgJiYgJGZhaWxzIDwgMykgewogICAgICAgICAgICAgICAgICAgICRmYWlscysrOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ25hbWUnICA9PiAkY29ubi0+Z2V0Q29uZmlndXJhdGlvbigpLT5nZXRJRCgpLAogICAgICAgICAgICAgICAgICAgICdlcnJvcicgPT4gJGUtPmdldE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkdmlld3MgYXMgJHZpZXcpIHsKICAgICAgICAgICAgJGRlZmluZXJTcGxpdGVkID0gZXhwbG9kZSgnQCcsICR2aWV3WydkZWZpbmVyJ10pOwogICAgICAgICAgICBpZiAoY291bnQoJGRlZmluZXJTcGxpdGVkKSA+IDAgJiYgJGNvbm4tPmdldENvbmZpZ3VyYXRpb24oKS0+dXNlciAhPT0gJGRlZmluZXJTcGxpdGVkWzBdKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnbmFtZScgICAgID0+ICR2aWV3WyduYW1lJ10sCiAgICAgICAgICAgICAgICAgICAgJ3R5cGUnICAgICA9PiBDbG9uZXJUYWJsZVR5cGU6OlZJRVcsCiAgICAgICAgICAgICAgICAgICAgJ3NvdXJjZScgICA9PiAkY29ubmVjdGlvbklELAogICAgICAgICAgICAgICAgICAgICdlcnJvcicgICAgPT4gInByb3ZpZGVkIGRhdGFiYXNlIHVzZXIgaXMgbm90IHZpZXcgZGVmaW5lciIsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFlbXB0eSgkdGFibGVOYW1lcykgJiYgIWluX2FycmF5KCR2aWV3WyduYW1lJ10sICR0YWJsZU5hbWVzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdFtdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAnbmFtZScgICAgID0+ICR2aWV3WyduYW1lJ10sCiAgICAgICAgICAgICAgICAndHlwZScgICAgID0+IENsb25lclRhYmxlVHlwZTo6VklFVywKICAgICAgICAgICAgICAgICdkYXRhU2l6ZScgPT4gMCwKICAgICAgICAgICAgICAgICdub0RhdGEnICAgPT4gdHJ1ZSwKICAgICAgICAgICAgICAgICdzb3VyY2UnICAgPT4gJGNvbm5lY3Rpb25JRCwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRjb25uLT5jbG9zZSgpOwogICAgfQoKICAgIHJldHVybiAkcmVzdWx0Owp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9pc19zY2hlbWFfb25seScpKToKZnVuY3Rpb24gY2xvbmVyX2lzX3NjaGVtYV9vbmx5KCR0YWJsZSkKewogICAgJHRhYmxlTGVuID0gc3RybGVuKCR0YWJsZSk7CiAgICAkaWdub3JlZCAgPSBhcnJheSgKICAgICAgICAnd3lzaWphX3VzZXJfaGlzdG9yeScsCiAgICAgICAgJ193c2RfcGx1Z2luX2FsZXJ0cycsCiAgICAgICAgJ193c2RfcGx1Z2luX2xpdmVfdHJhZmZpYycsCiAgICAgICAgJ2Fkcm90YXRlX3RyYWNrZXInLAogICAgICAgICdhaW93cHNfZXZlbnRzJywKICAgICAgICAnYWtfNDA0X2xvZycsCiAgICAgICAgJ2JhZF9iZWhhdmlvcicsCiAgICAgICAgJ2NuX3RyYWNrX3Bvc3QnLAogICAgICAgICduZ2lueGNoYW1wdXJ1JywKICAgICAgICAncG9wb3Zlcl9pcF9jYWNoZScsCiAgICAgICAgJ3JlZGlyZWN0aW9uXzQwNCcsCiAgICAgICAgJ3NweW5vdF9zeXN0ZW1zX2xvZycsCiAgICAgICAgJ3N0YXRpZnknLAogICAgICAgICdzdGF0aXN0aWNzX3VzZXJvbmxpbmUnLAogICAgICAgICd0Y2JfYXBpX2Vycm9yX2xvZycsCiAgICAgICAgJ3VzZXJvbmxpbmUnLAogICAgICAgICd3Yno0MDRfbG9ncycsCiAgICAgICAgJ3dmSGl0cycsCiAgICAgICAgJ3dmTGVlY2hlcnMnLAogICAgICAgICd3aG9faXNfb25saW5lJywKICAgICAgICAnc2ltcGxlX2hpc3RvcnknLAogICAgICAgICdzaW1wbGVfaGlzdG9yeV9jb250ZXh0cycsCiAgICAgICAgJ3dmSG9vdmVyJywKICAgICAgICAnZXRfYmxvb21fc3RhdHMnLAogICAgICAgICdpdHNlY19sb2cnLAogICAgICAgICdpdHNlY19sb2dzJywKICAgICAgICAnaXRzZWNfdGVtcCcsCiAgICAgICAgJ2NwZF9jb3VudGVyJywKICAgICAgICAnc2Vzc2lvbicsCiAgICAgICAgJ3dwYWFzX2FjdGl2aXR5X2xvZycsCiAgICAgICAgLy9waHBCQgogICAgICAgICdtb2RlcmF0b3JfY2FjaGUnLAogICAgICAgIC8vZHJ1cGFsCiAgICAgICAgJ3dhdGNoZG9nJywKICAgICAgICAnY2FjaGVfYm9vdHN0cmFwJywKICAgICAgICAnZHJ1cF9jYWNoZV9jb25maWcnLAogICAgICAgICdjYWNoZV9jb250YWluZXInLAogICAgICAgICdjYWNoZV9kYXRhJywKICAgICAgICAnY2FjaGVfZGVmYXVsdCcsCiAgICAgICAgJ2NhY2hlX2Rpc2NvdmVyeScsCiAgICAgICAgJ2NhY2hlX2R5bmFtaWNfcGFnZV9jYWNoZScsCiAgICAgICAgJ2NhY2hlX2VudGl0eScsCiAgICAgICAgJ2NhY2hlX21lbnUnLAogICAgICAgICdjYWNoZV9wYWdlJywKICAgICAgICAnY2FjaGVfcmVuZGVyJywKCiAgICAgICAgLy9tYWdlbnRvCiAgICAgICAgJ2xvZ192aXNpdG9yX2luZm8nLAoKICAgICAgICAvL3ZCdWxsZXRpbgogICAgICAgICdjYWNoZScsCiAgICAgICAgJ2NhY2hlZXZlbnQnCgogICAgKTsKICAgIGZvcmVhY2ggKCRpZ25vcmVkIGFzICRpZ25vcmUpIHsKICAgICAgICAkaWdub3JlTGVuID0gc3RybGVuKCRpZ25vcmUpOwogICAgICAgIGlmICgkaWdub3JlTGVuID4gJHRhYmxlTGVuKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAkc3VmZml4ID0gc3Vic3RyKCR0YWJsZSwgLSRpZ25vcmVMZW4pOwogICAgICAgIGlmIChzdHJuY2FzZWNtcCgkc3VmZml4LCAkaWdub3JlLCAkaWdub3JlTGVuKSA9PT0gMCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2xpc3RfdGFibGVzJykpOgpmdW5jdGlvbiBjbG9uZXJfbGlzdF90YWJsZXMoJGRiLCBhcnJheSAkdGFibGVOYW1lcyA9IG51bGwpCnsKICAgICRjb25uICAgICAgPSBjbG9uZXJfZGJfY29ubigkZGIpOwogICAgJHJlc3VsdCAgICA9IGFycmF5KCk7CiAgICAkc3VjY2VlZGVkID0gZmFsc2U7CgogICAgZm9yZWFjaCAoJGNvbm4tPmdldENvbm5lY3Rpb25JRHMoKSBhcyAkY29ubmVjdGlvbklEKSB7CiAgICAgICAgJGNvbm4tPnVzZUNvbm5lY3Rpb24oJGNvbm5lY3Rpb25JRCk7CiAgICAgICAgJGZhaWxzID0gMDsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHRhYmxlcyA9ICRjb25uLT5xdWVyeSgnU0VMRUNUIGB0YWJsZV9uYW1lYCBBUyBgbmFtZWAsIGBkYXRhX2xlbmd0aGAgQVMgYGRhdGFTaXplYAogICAgICAgICAgICAgICAgICAgIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLlRBQkxFUyBXSEVSRSB0YWJsZV9zY2hlbWEgPSA6ZGJfbmFtZSBBTkQgdGFibGVfdHlwZSA9IDp0YWJsZV90eXBlIEFORCBlbmdpbmUgSVMgTk9UIE5VTEwnLCBhcnJheSgKICAgICAgICAgICAgICAgICAgICAvLyBUaGUgTlVMTCBgZW5naW5lYCB0YWJsZXMgdXN1YWxseSBoYXZlIGB0YWJsZV9jb21tZW50YCA9PSAiVGFibGUgJ2ZvcnJlc3RsX3dyZHAxLndwX3dwZ216YV9jYXRlZ29yaWVzJyBkb2Vzbid0IGV4aXN0IGluIGVuZ2luZSIuCiAgICAgICAgICAgICAgICAgICAgJ2RiX25hbWUnICAgID0+ICRjb25uLT5nZXRDb25maWd1cmF0aW9uKCktPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgJ3RhYmxlX3R5cGUnID0+ICdCQVNFIFRBQkxFJywgLy8gYXMgb3Bwb3NlZCB0byBWSUVXCiAgICAgICAgICAgICAgICApKS0+ZmV0Y2hBbGwoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIENsb25lckV4Y2VwdGlvbiAmJiBzdHJsZW4oJGUtPmdldEludGVybmFsRXJyb3IoKSkgJiYgJGZhaWxzIDwgMykgewogICAgICAgICAgICAgICAgICAgICRmYWlscysrOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHJlc3VsdFtdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ25hbWUnICA9PiAkY29ubi0+Z2V0Q29uZmlndXJhdGlvbigpLT5nZXRJRCgpLAogICAgICAgICAgICAgICAgICAgICdlcnJvcicgPT4gJGUtPmdldE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBjb250aW51ZSAyOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkc3VjY2VlZGVkID0gdHJ1ZTsKICAgICAgICBmb3JlYWNoICgkdGFibGVzIGFzICR0YWJsZSkgewogICAgICAgICAgICBpZiAoIWVtcHR5KCR0YWJsZU5hbWVzKSAmJiAhaW5fYXJyYXkoJHRhYmxlWyduYW1lJ10sICR0YWJsZU5hbWVzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdFtdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAnbmFtZScgICAgID0+ICR0YWJsZVsnbmFtZSddLAogICAgICAgICAgICAgICAgJ3R5cGUnICAgICA9PiBDbG9uZXJUYWJsZVR5cGU6OlJFR1VMQVIsCiAgICAgICAgICAgICAgICAnZGF0YVNpemUnID0+IChpbnQpJHRhYmxlWydkYXRhU2l6ZSddLAogICAgICAgICAgICAgICAgJ25vRGF0YScgICA9PiBjbG9uZXJfaXNfc2NoZW1hX29ubHkoJHRhYmxlWyduYW1lJ10pLAogICAgICAgICAgICAgICAgJ3NvdXJjZScgICA9PiAkY29ubmVjdGlvbklELAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgJGNvbm4tPmNsb3NlKCk7CiAgICB9CgogICAgaWYgKCEkc3VjY2VlZGVkICYmIGlzc2V0KCRlKSkgewogICAgICAgIHRocm93ICRlOwogICAgfQogICAgcmV0dXJuICRyZXN1bHQ7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2xpc3Rfcm91dGluZXMnKSk6CmZ1bmN0aW9uIGNsb25lcl9saXN0X3JvdXRpbmVzKCRkYikKewogICAgJGNvbm4gICAgICA9IGNsb25lcl9kYl9jb25uKCRkYik7CiAgICAkcmVzdWx0ICAgID0gYXJyYXkoKTsKICAgIGZvcmVhY2ggKCRjb25uLT5nZXRDb25uZWN0aW9uSURzKCkgYXMgJGNvbm5lY3Rpb25JRCkgewogICAgICAgICRjb25uLT51c2VDb25uZWN0aW9uKCRjb25uZWN0aW9uSUQpOwogICAgICAgICRmYWlscyA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICRyb3V0aW5lcyA9ICRjb25uLT5xdWVyeSgnU0VMRUNUIGByb3V0aW5lX25hbWVgIEFTIGBuYW1lYCwgYHJvdXRpbmVfdHlwZWAgQVMgYHR5cGVgLCBgcm91dGluZV9kZWZpbml0aW9uYCBBUyBgZGVmaW5pdGlvbmAKICAgICAgICAgICAgICAgICAgICBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5ST1VUSU5FUyBXSEVSRSByb3V0aW5lX3NjaGVtYSA9IDpkYl9uYW1lJywgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgJ2RiX25hbWUnICAgID0+ICRjb25uLT5nZXRDb25maWd1cmF0aW9uKCktPm5hbWUsCiAgICAgICAgICAgICAgICApKS0+ZmV0Y2hBbGwoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgICAgIGlmICgkZSBpbnN0YW5jZW9mIENsb25lckV4Y2VwdGlvbiAmJiBzdHJsZW4oJGUtPmdldEludGVybmFsRXJyb3IoKSkgJiYgJGZhaWxzIDwgMykgewogICAgICAgICAgICAgICAgICAgICAgICAkZmFpbHMrKzsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRyZXN1bHRbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAnbmFtZScgID0+ICRjb25uLT5nZXRDb25maWd1cmF0aW9uKCktPmdldElEKCksCiAgICAgICAgICAgICAgICAgICAgICAgICdlcnJvcicgPT4gJGUtPmdldE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3JlYWNoICgkcm91dGluZXMgYXMgJHJvdXRpbmUpIHsKICAgICAgICAgICAgaWYgKGVtcHR5KCRyb3V0aW5lWydkZWZpbml0aW9uJ10pKSB7CiAgICAgICAgICAgICAgICAkcmVzdWx0W10gPSBhcnJheSgKICAgICAgICAgICAgICAgICAgICAnbmFtZScgICAgID0+ICRyb3V0aW5lWyduYW1lJ10sCiAgICAgICAgICAgICAgICAgICAgJ3R5cGUnICAgICA9PiAkdHlwZSwKICAgICAgICAgICAgICAgICAgICAnc291cmNlJyAgID0+ICRjb25uZWN0aW9uSUQsCiAgICAgICAgICAgICAgICAgICAgJ2Vycm9yJyAgICA9PiAicHJvdmlkZWQgZGF0YWJhc2UgdXNlciBpcyBub3Qgcm91dGluZSBkZWZpbmVyIiwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkdHlwZSA9IENsb25lclRhYmxlVHlwZTo6UFJPQ0VEVVJFOwogICAgICAgICAgICBpZiAoJHJvdXRpbmVbJ3R5cGUnXSA9PT0gIkZVTkNUSU9OIikgewogICAgICAgICAgICAgICAgJHR5cGUgPSBDbG9uZXJUYWJsZVR5cGU6OkZVTkM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHJlc3VsdFtdID0gYXJyYXkoCiAgICAgICAgICAgICAgICAnbmFtZScgICAgID0+ICRyb3V0aW5lWyduYW1lJ10sCiAgICAgICAgICAgICAgICAndHlwZScgICAgID0+ICR0eXBlLAogICAgICAgICAgICAgICAgJ2RhdGFTaXplJyA9PiAwLAogICAgICAgICAgICAgICAgJ25vRGF0YScgICA9PiB0cnVlLAogICAgICAgICAgICAgICAgJ3NvdXJjZScgICA9PiAkY29ubmVjdGlvbklELAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgJGNvbm4tPmNsb3NlKCk7CiAgICB9CgogICAgcmV0dXJuICRyZXN1bHQ7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl9saXN0X3RhYmxlcycpKToKZnVuY3Rpb24gY2xvbmVyX2FjdGlvbl9saXN0X3RhYmxlcygkZGIsIGFycmF5ICR0YWJsZU5hbWVzID0gbnVsbCkKewogICAgaWYgKCFjb3VudCgkZGIpIHx8IChjb3VudCgkZGIpID09PSAxICYmIGVtcHR5KCRkYlswXVsnZGJOYW1lJ10pKSkgewogICAgICAgIHJldHVybiBhcnJheSgpOwogICAgfQogICAgJHJlc3VsdCAgICA9IGFycmF5KCk7CgogICAgJHZpZXdzID0gY2xvbmVyX2xpc3Rfdmlld3MoJGRiLCAkdGFibGVOYW1lcyk7CiAgICAkcmVzdWx0ID0gYXJyYXlfbWVyZ2UoJHJlc3VsdCwgJHZpZXdzKTsKCiAgICAkdGFibGVzID0gY2xvbmVyX2xpc3RfdGFibGVzKCRkYiwgJHRhYmxlTmFtZXMpOwogICAgJHJlc3VsdCA9IGFycmF5X21lcmdlKCRyZXN1bHQsICR0YWJsZXMpOwoKICAgICRyb3V0aW5lcyA9IGNsb25lcl9saXN0X3JvdXRpbmVzKCRkYik7CiAgICAkcmVzdWx0ID0gYXJyYXlfbWVyZ2UoJHJlc3VsdCwgJHJvdXRpbmVzKTsKCiAgICByZXR1cm4gJHJlc3VsdDsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJ0YWJsZScsIGZhbHNlKSk6CmNsYXNzIENsb25lclRhYmxlCnsKICAgIHB1YmxpYyAkbmFtZSA9ICcnOwogICAgcHVibGljICR0eXBlID0gMDsKICAgIHB1YmxpYyAkc2l6ZSA9IDA7CiAgICBwdWJsaWMgJG5vRGF0YSA9IGZhbHNlOwogICAgcHVibGljICRzb3VyY2UgPSAnJzsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJG5hbWUKICAgICAqIEBwYXJhbSBpbnQgICAgJHR5cGUKICAgICAqIEBwYXJhbSBpbnQgICAgJHNpemUKICAgICAqIEBwYXJhbSBib29sICAgJG5vRGF0YQogICAgICogQHBhcmFtIHN0cmluZyAkc291cmNlCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkbmFtZSwgJHR5cGUsICRzaXplLCAkbm9EYXRhLCAkc291cmNlKQogICAgewogICAgICAgICR0aGlzLT5uYW1lICAgPSAkbmFtZTsKICAgICAgICAkdGhpcy0+dHlwZSAgID0gKGludCkkdHlwZTsKICAgICAgICAkdGhpcy0+c2l6ZSAgID0gKGludCkkc2l6ZTsKICAgICAgICAkdGhpcy0+bm9EYXRhID0gKGJvb2wpJG5vRGF0YTsKICAgICAgICAkdGhpcy0+c291cmNlID0gKHN0cmluZykkc291cmNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbUFycmF5KGFycmF5ICRkYXRhKQogICAgewogICAgICAgIHJldHVybiBuZXcgc2VsZigkZGF0YVsnbmFtZSddLCAkZGF0YVsndHlwZSddLCAkZGF0YVsnc2l6ZSddLCAkZGF0YVsnbm9EYXRhJ10sICRkYXRhWydzb3VyY2UnXSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl9oYXNoX3RhYmxlcycpKToKZnVuY3Rpb24gY2xvbmVyX2FjdGlvbl9oYXNoX3RhYmxlcygkZGIsIGFycmF5ICR0YWJsZXMsICR0aW1lb3V0KQp7CiAgICAkY29ubiAgICAgPSBjbG9uZXJfZGJfY29ubigkZGIpOwogICAgJGRlYWRsaW5lID0gbmV3IENsb25lckRlYWRsaW5lKCR0aW1lb3V0KTsKICAgICRyZXN1bHQgICA9IG5ldyBDbG9uZXJIYXNoUmVzdWx0KCk7CiAgICBmb3JlYWNoICgkdGFibGVzIGFzICR0YWJsZURhdGEpIHsKICAgICAgICAkdGFibGUgPSBDbG9uZXJUYWJsZTo6ZnJvbUFycmF5KCR0YWJsZURhdGEpOwogICAgICAgIGlmICghJGNvbm4tPnVzZUNvbm5lY3Rpb24oJHRhYmxlLT5zb3VyY2UpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oc3ByaW50ZignQ291bGQgbm90IHVzZSBjb25uZWN0aW9uICVzJywgJHRhYmxlLT5zb3VyY2UpKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgc3dpdGNoICgkdGFibGUtPnR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgQ2xvbmVyVGFibGVUeXBlOjpQUk9DRURVUkU6CiAgICAgICAgICAgICAgICAgICAgJHJvdyAgICAgICAgID0gJGNvbm4tPnF1ZXJ5KCJTSE9XIENSRUFURSBQUk9DRURVUkUgYHskdGFibGUtPm5hbWV9YCIpLT5mZXRjaCgpOwogICAgICAgICAgICAgICAgICAgICRjcmVhdGVQcm9jZWR1cmUgPSAkcm93WydDcmVhdGUgUHJvY2VkdXJlJ107CiAgICAgICAgICAgICAgICAgICAgaWYgKGVtcHR5KCRjcmVhdGVQcm9jZWR1cmUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oc3ByaW50ZignU0hPVyBDUkVBVEUgUFJPQ0VEVVJFIGRpZCBub3QgcmV0dXJuIGV4cGVjdGVkIHJlc3VsdCBmb3IgcHJvY2VkdXJlICVzJywgJHRhYmxlLT5uYW1lKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRyZXN1bHQtPmFwcGVuZE9LKG1kNSgkY3JlYXRlUHJvY2VkdXJlKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIENsb25lclRhYmxlVHlwZTo6RlVOQzoKICAgICAgICAgICAgICAgICAgICAkcm93ICAgICAgICAgPSAkY29ubi0+cXVlcnkoIlNIT1cgQ1JFQVRFIEZVTkNUSU9OIGB7JHRhYmxlLT5uYW1lfWAiKS0+ZmV0Y2goKTsKICAgICAgICAgICAgICAgICAgICAkY3JlYXRlRnVuY3Rpb24gPSAkcm93WydDcmVhdGUgRnVuY3Rpb24nXTsKICAgICAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJGNyZWF0ZUZ1bmN0aW9uKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoJ1NIT1cgQ1JFQVRFIEZVTkNUSU9OIGRpZCBub3QgcmV0dXJuIGV4cGVjdGVkIHJlc3VsdCBmb3IgZnVuY3Rpb24gJXMnLCAkdGFibGUtPm5hbWUpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kT0sobWQ1KCRjcmVhdGVGdW5jdGlvbikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBDbG9uZXJUYWJsZVR5cGU6OlZJRVc6CiAgICAgICAgICAgICAgICAgICAgJHJvdyAgICAgICAgID0gJGNvbm4tPnF1ZXJ5KCJTSE9XIENSRUFURSBWSUVXIGB7JHRhYmxlLT5uYW1lfWAiKS0+ZmV0Y2goKTsKICAgICAgICAgICAgICAgICAgICAkY3JlYXRlVmlldyA9ICRyb3dbJ0NyZWF0ZSBWaWV3J107CiAgICAgICAgICAgICAgICAgICAgaWYgKGVtcHR5KCRjcmVhdGVWaWV3KSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoJ1NIT1cgQ1JFQVRFIFZJRVcgZGlkIG5vdCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciB2aWV3ICVzJywgJHRhYmxlLT5uYW1lKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRyZXN1bHQtPmFwcGVuZE9LKG1kNSgkY3JlYXRlVmlldykpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBpZiAoJHRhYmxlLT5ub0RhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHJvdyAgICAgICAgID0gJGNvbm4tPnF1ZXJ5KCJTSE9XIENSRUFURSBUQUJMRSBgeyR0YWJsZS0+bmFtZX1gIiktPmZldGNoKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICRjcmVhdGVUYWJsZSA9ICRyb3dbJ0NyZWF0ZSBUYWJsZSddOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW1wdHkoJGNyZWF0ZVRhYmxlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCdTSE9XIENSRUFURSBUQUJMRSBkaWQgbm90IHJldHVybiBleHBlY3RlZCByZXN1bHQgZm9yIHRhYmxlICVzJywgJHRhYmxlLT5uYW1lKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kT0sobWQ1KCRjcmVhdGVUYWJsZSkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRyb3dzID0gJGNvbm4tPnF1ZXJ5KCJDSEVDS1NVTSBUQUJMRSBgeyR0YWJsZS0+bmFtZX1gIiktPmZldGNoQWxsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCgkcm93cykgIT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oc3ByaW50ZignRXhwZWN0ZWQgZXhhY3RseSBvbmUgQ0hFQ0tTVU0gVEFCTEUgcmVzdWx0LCBnb3QgJWQnLCBjb3VudCgkcm93cykpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkcmVzdWx0LT5hcHBlbmRPSyhtZDUoJHJvd3NbMF1bJ0NoZWNrc3VtJ10pKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgJHJlc3VsdC0+YXBwZW5kRXJyb3IoJGUtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmICgkZGVhZGxpbmUtPmRvbmUoKSkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gJHJlc3VsdC0+aGFzaGVzOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmRiY29sdW1uJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyREJDb2x1bW4KewogICAgcHVibGljICRuYW1lID0gJyc7CiAgICBwdWJsaWMgJHR5cGUgPSAnJzsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21BcnJheShhcnJheSAkZGF0YSkKICAgIHsKICAgICAgICAkY29sdW1uID0gbmV3IHNlbGY7CiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWyduYW1lJ10pKSB7CiAgICAgICAgICAgICRjb2x1bW4tPm5hbWUgPSAkZGF0YVsnbmFtZSddOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ3R5cGUnXSkpIHsKICAgICAgICAgICAgJGNvbHVtbi0+dHlwZSA9ICRkYXRhWyd0eXBlJ107CiAgICAgICAgfQogICAgICAgIHJldHVybiAkY29sdW1uOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmRidGFibGUnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJEQlRhYmxlCnsKICAgIHB1YmxpYyAkbmFtZSA9ICcnOwogICAgcHVibGljICR0eXBlID0gMDsKICAgIHB1YmxpYyAkc2l6ZSA9IDA7CiAgICBwdWJsaWMgJGRhdGFTaXplID0gMDsKICAgIHB1YmxpYyAkc3RvcmFnZSA9ICcnOwogICAgcHVibGljICRkb25lID0gZmFsc2U7CiAgICBwdWJsaWMgJGxpc3RlZCA9IGZhbHNlOwogICAgLyoqIEB2YXIgQ2xvbmVyREJDb2x1bW5bXSAqLwogICAgcHVibGljICRjb2x1bW5zID0gYXJyYXkoKTsKICAgIHB1YmxpYyAkcGF0aCA9ICcnOwogICAgcHVibGljICRub0RhdGEgPSBmYWxzZTsKICAgIHB1YmxpYyAkaGFzaCA9ICcnOwogICAgcHVibGljICRzb3VyY2UgPSAnJzsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21BcnJheShhcnJheSAkZGF0YSkKICAgIHsKICAgICAgICAkdGFibGUgPSBuZXcgc2VsZjsKICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ25hbWUnXSkpIHsKICAgICAgICAgICAgJHRhYmxlLT5uYW1lID0gJGRhdGFbJ25hbWUnXTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWyd0eXBlJ10pKSB7CiAgICAgICAgICAgICAgICAgICAgJHRhYmxlLT50eXBlID0gJGRhdGFbJ3R5cGUnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ3NpemUnXSkpIHsKICAgICAgICAgICAgJHRhYmxlLT5zaXplID0gJGRhdGFbJ3NpemUnXTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydkYXRhU2l6ZSddKSkgewogICAgICAgICAgICAkdGFibGUtPmRhdGFTaXplID0gJGRhdGFbJ2RhdGFTaXplJ107CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkZGF0YVsnc3RvcmFnZSddKSkgewogICAgICAgICAgICAkdGFibGUtPnN0b3JhZ2UgPSAkZGF0YVsnc3RvcmFnZSddOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ2RvbmUnXSkpIHsKICAgICAgICAgICAgJHRhYmxlLT5kb25lID0gJGRhdGFbJ2RvbmUnXTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydsaXN0ZWQnXSkpIHsKICAgICAgICAgICAgJHRhYmxlLT5saXN0ZWQgPSAkZGF0YVsnbGlzdGVkJ107CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkZGF0YVsnY29sdW1ucyddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkZGF0YVsnY29sdW1ucyddIGFzICRjb2x1bW4pIHsKICAgICAgICAgICAgICAgICR0YWJsZS0+Y29sdW1uc1tdID0gQ2xvbmVyREJDb2x1bW46OmZyb21BcnJheSgkY29sdW1uKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ3BhdGgnXSkpIHsKICAgICAgICAgICAgJHRhYmxlLT5wYXRoID0gJGRhdGFbJ3BhdGgnXTsKICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydub0RhdGEnXSkpIHsKICAgICAgICAgICAgJHRhYmxlLT5ub0RhdGEgPSAkZGF0YVsnbm9EYXRhJ107CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkZGF0YVsnc291cmNlJ10pKSB7CiAgICAgICAgICAgICR0YWJsZS0+c291cmNlID0gJGRhdGFbJ3NvdXJjZSddOwogICAgICAgIH0KICAgICAgICBpZiAoaXNzZXQoJGRhdGFbJ2hhc2gnXSkpIHsKICAgICAgICAgICAgJHRhYmxlLT5oYXNoID0gJGRhdGFbJ2hhc2gnXTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICR0YWJsZTsKICAgIH0KfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJkYmR1bXBzdGF0ZScsIGZhbHNlKSk6CmNsYXNzIENsb25lckRCRHVtcFN0YXRlCnsKICAgIHB1YmxpYyAkbGlzdGVkID0gZmFsc2U7CiAgICAvKiogQHZhciBDbG9uZXJEQlRhYmxlW10gKi8KICAgIHB1YmxpYyAkbGlzdCA9IGFycmF5KCk7CiAgICBwdWJsaWMgJGRvbmUgPSBmYWxzZTsKCiAgICBwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZyb21BcnJheSgkZGF0YSkKICAgIHsKICAgICAgICBpZiAoJGRhdGEgaW5zdGFuY2VvZiBzZWxmKSB7CiAgICAgICAgICAgIHJldHVybiAkZGF0YTsKICAgICAgICB9CiAgICAgICAgJHN0YXRlID0gbmV3IHNlbGY7CiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydsaXN0ZWQnXSkpIHsKICAgICAgICAgICAgJHN0YXRlLT5saXN0ZWQgPSAkZGF0YVsnbGlzdGVkJ107CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkZGF0YVsnbGlzdCddKSkgewogICAgICAgICAgICBmb3JlYWNoICgkZGF0YVsnbGlzdCddIGFzICRpdGVtKSB7CiAgICAgICAgICAgICAgICAkc3RhdGUtPmxpc3RbXSA9IENsb25lckRCVGFibGU6OmZyb21BcnJheSgkaXRlbSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGlzc2V0KCRkYXRhWydkb25lJ10pKSB7CiAgICAgICAgICAgICRzdGF0ZS0+ZG9uZSA9ICRkYXRhWydkb25lJ107CiAgICAgICAgfQogICAgICAgIHJldHVybiAkc3RhdGU7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3N0cmVhbScpKToKZnVuY3Rpb24gY2xvbmVyX3N0cmVhbSgkc3RyZWFtKQp7CiAgICBpZiAoISRzdHJlYW0pIHsKICAgICAgICAvLyBzdHJlYW0gZGlzYWJsZWQKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0gZWxzZWlmICgkc3RyZWFtIGluc3RhbmNlb2YgQ2xvbmVyU3RyZWFtKSB7CiAgICAgICAgLy8gc3RyZWFtIGltcGxlbWVudGF0aW9uIGFscmVhZHkgc2V0CiAgICAgICAgcmV0dXJuICRzdHJlYW07CiAgICB9IGVsc2UgewogICAgICAgIC8vIHJlc3BvbmRpbmcgdG8gSFRUUCByZXF1ZXN0CiAgICAgICAgZ2xvYmFsICRjbG9uZXJSZXF1ZXN0SUQ7CiAgICAgICAgcmV0dXJuIGNsb25lcl9zdGFuZGFyZF9zdHJlYW0oKHN0cmluZykkY2xvbmVyUmVxdWVzdElEKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZ2V0X3RhYmxlX2NvbHVtbnMnKSk6CmZ1bmN0aW9uIGNsb25lcl9nZXRfdGFibGVfY29sdW1ucyhDbG9uZXJEQkNvbm4gJGNvbm4sICR0YWJsZSkKewogICAgJGNvbHVtbkxpc3QgPSAkY29ubi0+cXVlcnkoIlNIT1cgQ09MVU1OUyBJTiBgJHRhYmxlYCIpLT5mZXRjaEFsbCgpOwoKICAgICRjb2x1bW5zID0gYXJyYXkoKTsKICAgIGZvcmVhY2ggKCRjb2x1bW5MaXN0IGFzICRjb2x1bW5EYXRhKSB7CiAgICAgICAgJGNvbHVtbiAgICAgICA9IG5ldyBDbG9uZXJEQkNvbHVtbigpOwogICAgICAgICRjb2x1bW4tPm5hbWUgPSAkY29sdW1uRGF0YVsnRmllbGQnXTsKICAgICAgICAkdHlwZSAgICAgICAgID0gc3RydG9sb3dlcigkY29sdW1uRGF0YVsnVHlwZSddKTsKICAgICAgICBpZiAoKCRvcGVuUGFyZW4gPSBzdHJwb3MoJHR5cGUsICcoJykpICE9PSBmYWxzZSkgewogICAgICAgICAgICAvLyBUcmFuc2Zvcm0gImludCgxMSkiIHRvICJpbnQiLCBldGMuCiAgICAgICAgICAgICR0eXBlID0gc3Vic3RyKCR0eXBlLCAwLCAkb3BlblBhcmVuKTsKICAgICAgICB9CiAgICAgICAgJGNvbHVtbi0+dHlwZSA9ICR0eXBlOwogICAgICAgICRjb2x1bW5zW10gICAgPSAkY29sdW1uOwoKICAgICAgICBpZiAoJGNvbm4gaW5zdGFuY2VvZiBDbG9uZXJQRE9Db25uICYmIHN0cnBvcygkY29sdW1uLT5uYW1lLCAnPycpICE9PSBmYWxzZSkgewogICAgICAgICAgICAkY29ubi0+c2V0QXR0RW11bGF0ZVByZXBhcmVzKGZhbHNlKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuICRjb2x1bW5zOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmZpbGVoYW5kbGUnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJGaWxlSGFuZGxlIGltcGxlbWVudHMgQ2xvbmVyV3JpdGVyCnsKICAgIHByaXZhdGUgJHBhdGg7CiAgICBwcml2YXRlICRmcDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJG1vZGUKICAgICAqIEB0aHJvd3MgQ2xvbmVyRlNFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRwYXRoLCAkbW9kZSkKICAgIHsKICAgICAgICAkdGhpcy0+cGF0aCA9ICRwYXRoOwogICAgICAgICR0aGlzLT5mcCAgID0gQGZvcGVuKCR0aGlzLT5wYXRoLCAkbW9kZSk7CiAgICAgICAgaWYgKCR0aGlzLT5mcCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckZTRnVuY3Rpb25FeGNlcHRpb24oJ2ZvcGVuJywgJHRoaXMtPnBhdGgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgQ2xvbmVyRlNFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHdyaXRlKCRkYXRhKQogICAgewogICAgICAgIGlmICgkdGhpcy0+ZnAgPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckZTRXhjZXB0aW9uKHNwcmludGYoJ0ZpbGUgJXMgYWxyZWFkeSBjbG9zZWQnLCAkdGhpcy0+cGF0aCkpOwogICAgICAgIH0KICAgICAgICBpZiAoQGZ3cml0ZSgkdGhpcy0+ZnAsICRkYXRhKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckZTRnVuY3Rpb25FeGNlcHRpb24oJ2Z3cml0ZScsICR0aGlzLT5wYXRoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIENsb25lckZTRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBjbG9zZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5mcCA9PT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmIChAZmNsb3NlKCR0aGlzLT5mcCkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJGU0Z1bmN0aW9uRXhjZXB0aW9uKCdmY2xvc2UnLCAkdGhpcy0+cGF0aCk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5mcCA9IG51bGw7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2R1bXBfcHJvY2VkdXJlJykpOgpmdW5jdGlvbiBjbG9uZXJfZHVtcF9wcm9jZWR1cmUoQ2xvbmVyREJDb25uICRjb25uLCAkcHJvY2VkdXJlTmFtZSwgQ2xvbmVyV3JpdGVyICRmcCkKewogICAgJHRpbWUgICAgICAgICAgPSBkYXRlKCdjJyk7CiAgICAkaGFsdENvbXBpbGVyICA9ICI8P3BocCBleGl0OyBfX2hhbHRfY29tcGlsZXIoKTsiOwogICAgJGR1bXBlciAgICAgICAgPSBnZXRfY2xhc3MoJGNvbm4pOwogICAgJHBocFZlcnNpb24gICAgPSBwaHB2ZXJzaW9uKCk7CiAgICAkcXVlcnkgICAgICAgICA9ICcnOwogICAgJGhlYWRlciAgICAgICAgPSA8PDxTUUwKLS0gJGhhbHRDb21waWxlciAvLyBQcm90ZWN0IHRoZSBmaWxlIGZyb20gYmVpbmcgdmlzaXRlZCB2aWEgd2ViCi0tIE9yaW9uIGJhY2t1cCBmb3JtYXQKLS0gR2VuZXJhdGVkIGF0OiAkdGltZSBieSAkZHVtcGVyOyBQSFAgdiRwaHBWZXJzaW9uCi8qITQwMTAxIFNFVCBAT0xEX0NIQVJBQ1RFUl9TRVRfQ0xJRU5UPUBAQ0hBUkFDVEVSX1NFVF9DTElFTlQgKi87Ci8qITQwMTAxIFNFVCBAT0xEX0NIQVJBQ1RFUl9TRVRfUkVTVUxUUz1AQENIQVJBQ1RFUl9TRVRfUkVTVUxUUyAqLzsKLyohNDAxMDEgU0VUIEBPTERfQ09MTEFUSU9OX0NPTk5FQ1RJT049QEBDT0xMQVRJT05fQ09OTkVDVElPTiAqLzsKLyohNDAxMDEgU0VUIE5BTUVTIHV0ZjggKi87Ci8qITQwMTAzIFNFVCBAT0xEX1RJTUVfWk9ORT1AQFRJTUVfWk9ORSAqLzsKLyohNDAxMDMgU0VUIFRJTUVfWk9ORT0nKzAwOjAwJyAqLzsKLyohNDAxMDEgU0VUIEBPTERfU1FMX01PREU9QEBTUUxfTU9ERSwgU1FMX01PREU9J05PX0FVVE9fVkFMVUVfT05fWkVSTycgKi87Ci8qITQwMTExIFNFVCBAT0xEX1NRTF9OT1RFUz1AQFNRTF9OT1RFUywgU1FMX05PVEVTPTAgKi87CgpTUUw7CiAgICAkcXVlcnkgLj0gJGhlYWRlcjsKCiAgICB0cnkgewogICAgICAgICRyb3cgPSAkY29ubi0+cXVlcnkoIlNIT1cgQ1JFQVRFIFBST0NFRFVSRSB7JHByb2NlZHVyZU5hbWV9IiktPmZldGNoKCk7CiAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICB0aHJvdyAkZTsKICAgIH0KCiAgICAkY3JlYXRlUHJvY2VkdXJlID0gJHJvd1siQ3JlYXRlIFByb2NlZHVyZSJdOwogICAgaWYgKGVtcHR5KCRjcmVhdGVQcm9jZWR1cmUpKSB7CiAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCdTSE9XIENSRUFURSBQUk9DRURVUkUgZGlkIG5vdCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciBwcm9jZWR1cmUgJXMnLCAkcHJvY2VkdXJlTmFtZSkpOwogICAgfQoKICAgICRkcm9wID0gIkRST1AgUFJPQ0VEVVJFIElGIEVYSVNUUyAiIC4gJHByb2NlZHVyZU5hbWUgLiAiO1xuIjsKICAgICRxdWVyeSAuPSAkZHJvcDsKCiAgICAkcXVlcnkgLj0gIkRFTElNSVRFUiA7O1xuIjsKICAgICRxdWVyeSAuPSAkY3JlYXRlUHJvY2VkdXJlLiI7O1xuIjsKICAgICRxdWVyeSAuPSAiREVMSU1JVEVSIDtcbiI7CgogICAgJGZvb3RlciA9IDw8PFNRTAoKLyohNDAxMDMgU0VUIFRJTUVfWk9ORT1AT0xEX1RJTUVfWk9ORSAqLzsKLyohNDAxMDEgU0VUIFNRTF9NT0RFPUBPTERfU1FMX01PREUgKi87Ci8qITQwMTAxIFNFVCBDSEFSQUNURVJfU0VUX0NMSUVOVD1AT0xEX0NIQVJBQ1RFUl9TRVRfQ0xJRU5UICovOwovKiE0MDEwMSBTRVQgQ0hBUkFDVEVSX1NFVF9SRVNVTFRTPUBPTERfQ0hBUkFDVEVSX1NFVF9SRVNVTFRTICovOwovKiE0MDEwMSBTRVQgQ09MTEFUSU9OX0NPTk5FQ1RJT049QE9MRF9DT0xMQVRJT05fQ09OTkVDVElPTiAqLzsKLyohNDAxMTEgU0VUIFNRTF9OT1RFUz1AT0xEX1NRTF9OT1RFUyAqLzsKClNRTDsKICAgICRxdWVyeSAuPSAkaGVhZGVyOwogICAgJGZwLT53cml0ZSgkcXVlcnkpOwoKICAgIHJldHVybiBzdHJsZW4oJHF1ZXJ5KTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZHVtcF9mdW5jdGlvbicpKToKZnVuY3Rpb24gY2xvbmVyX2R1bXBfZnVuY3Rpb24oQ2xvbmVyREJDb25uICRjb25uLCAkZnVuY3Rpb25OYW1lLCBDbG9uZXJXcml0ZXIgJGZwKQp7CiAgICAkdGltZSAgICAgICAgICA9IGRhdGUoJ2MnKTsKICAgICRoYWx0Q29tcGlsZXIgID0gIjw/cGhwIGV4aXQ7IF9faGFsdF9jb21waWxlcigpOyI7CiAgICAkZHVtcGVyICAgICAgICA9IGdldF9jbGFzcygkY29ubik7CiAgICAkcGhwVmVyc2lvbiAgICA9IHBocHZlcnNpb24oKTsKICAgICRxdWVyeSAgICAgICAgID0gJyc7CiAgICAkaGVhZGVyICAgICAgICA9IDw8PFNRTAotLSAkaGFsdENvbXBpbGVyIC8vIFByb3RlY3QgdGhlIGZpbGUgZnJvbSBiZWluZyB2aXNpdGVkIHZpYSB3ZWIKLS0gT3Jpb24gYmFja3VwIGZvcm1hdAotLSBHZW5lcmF0ZWQgYXQ6ICR0aW1lIGJ5ICRkdW1wZXI7IFBIUCB2JHBocFZlcnNpb24KLyohNDAxMDEgU0VUIEBPTERfQ0hBUkFDVEVSX1NFVF9DTElFTlQ9QEBDSEFSQUNURVJfU0VUX0NMSUVOVCAqLzsKLyohNDAxMDEgU0VUIEBPTERfQ0hBUkFDVEVSX1NFVF9SRVNVTFRTPUBAQ0hBUkFDVEVSX1NFVF9SRVNVTFRTICovOwovKiE0MDEwMSBTRVQgQE9MRF9DT0xMQVRJT05fQ09OTkVDVElPTj1AQENPTExBVElPTl9DT05ORUNUSU9OICovOwovKiE0MDEwMSBTRVQgTkFNRVMgdXRmOCAqLzsKLyohNDAxMDMgU0VUIEBPTERfVElNRV9aT05FPUBAVElNRV9aT05FICovOwovKiE0MDEwMyBTRVQgVElNRV9aT05FPScrMDA6MDAnICovOwoKU1FMOwogICAgJHF1ZXJ5IC49ICRoZWFkZXI7CgogICAgdHJ5IHsKICAgICAgICAkcm93ID0gJGNvbm4tPnF1ZXJ5KCJTSE9XIENSRUFURSBGVU5DVElPTiB7JGZ1bmN0aW9uTmFtZX0iKS0+ZmV0Y2goKTsKICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgIHRocm93ICRlOwogICAgfQoKICAgICRjcmVhdGVGdW5jdGlvbiA9ICRyb3dbIkNyZWF0ZSBGdW5jdGlvbiJdOwogICAgaWYgKGVtcHR5KCRjcmVhdGVGdW5jdGlvbikpIHsKICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoJ1NIT1cgQ1JFQVRFIEZVTkNUSU9OIGRpZCBub3QgcmV0dXJuIGV4cGVjdGVkIHJlc3VsdCBmb3IgZnVuY3Rpb24gJXMnLCAkZnVuY3Rpb25OYW1lKSk7CiAgICB9CgogICAgJGRyb3AgPSAiRFJPUCBGVU5DVElPTiBJRiBFWElTVFMgIiAuICRmdW5jdGlvbk5hbWUgLiAiO1xuIjsKICAgICRxdWVyeSAuPSAkZHJvcDsKCiAgICAkcXVlcnkgLj0gIkRFTElNSVRFUiA7O1xuIjsKICAgICRxdWVyeSAuPSAkY3JlYXRlRnVuY3Rpb24uIjs7XG4iOwogICAgJHF1ZXJ5IC49ICJERUxJTUlURVIgO1xuIjsKCiAgICAkZm9vdGVyID0gPDw8U1FMCgovKiE0MDEwMyBTRVQgVElNRV9aT05FPUBPTERfVElNRV9aT05FICovOwovKiE0MDEwMSBTRVQgQ0hBUkFDVEVSX1NFVF9DTElFTlQ9QE9MRF9DSEFSQUNURVJfU0VUX0NMSUVOVCAqLzsKLyohNDAxMDEgU0VUIENIQVJBQ1RFUl9TRVRfUkVTVUxUUz1AT0xEX0NIQVJBQ1RFUl9TRVRfUkVTVUxUUyAqLzsKLyohNDAxMDEgU0VUIENPTExBVElPTl9DT05ORUNUSU9OPUBPTERfQ09MTEFUSU9OX0NPTk5FQ1RJT04gKi87CgpTUUw7CiAgICAkcXVlcnkgLj0gJGZvb3RlcjsKICAgICRmcC0+d3JpdGUoJHF1ZXJ5KTsKCiAgICByZXR1cm4gc3RybGVuKCRxdWVyeSk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2R1bXBfdmlldycpKToKZnVuY3Rpb24gY2xvbmVyX2R1bXBfdmlldyhDbG9uZXJEQkNvbm4gJGNvbm4sICR2aWV3TmFtZSwgQ2xvbmVyV3JpdGVyICRmcCkKewogICAgJHJlc3VsdCAgICAgPSAkY29ubi0+cXVlcnkoIlNIT1cgQ1JFQVRFIFZJRVcgYCR2aWV3TmFtZWAiKS0+ZmV0Y2goKTsKICAgICRjcmVhdGVWaWV3ID0gJHJlc3VsdFsnQ3JlYXRlIFZpZXcnXTsKICAgIGlmIChlbXB0eSgkY3JlYXRlVmlldykpIHsKICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoJ1NIT1cgQ1JFQVRFIFZJRVcgZGlkIG5vdCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciB2aWV3ICVzJywgJHZpZXdOYW1lKSwgJ25vX2NyZWF0ZV90YWJsZScpOwogICAgfQoKICAgICR0aW1lICAgICAgICAgID0gZGF0ZSgnYycpOwogICAgJGhhbHRDb21waWxlciAgPSAiPD9waHAgZXhpdDsgX19oYWx0X2NvbXBpbGVyKCk7IjsKICAgICRkdW1wZXIgICAgICAgID0gZ2V0X2NsYXNzKCRjb25uKTsKICAgICRwaHBWZXJzaW9uICAgID0gcGhwdmVyc2lvbigpOwogICAgJHF1ZXJ5ICAgICAgICA9IDw8PFNRTAotLSAkaGFsdENvbXBpbGVyIC8vIFByb3RlY3QgdGhlIGZpbGUgZnJvbSBiZWluZyB2aXNpdGVkIHZpYSB3ZWIKLS0gT3Jpb24gYmFja3VwIGZvcm1hdAotLSBHZW5lcmF0ZWQgYXQ6ICR0aW1lIGJ5ICRkdW1wZXI7IFBIUCB2JHBocFZlcnNpb24KLS0gU2VsZWN0ZWQgdmlhOiAkZmV0Y2hBbGxRdWVyeQoKLyohNDAxMDEgU0VUIEBPTERfQ0hBUkFDVEVSX1NFVF9DTElFTlQ9QEBDSEFSQUNURVJfU0VUX0NMSUVOVCAqLzsKLyohNDAxMDEgU0VUIEBPTERfQ0hBUkFDVEVSX1NFVF9SRVNVTFRTPUBAQ0hBUkFDVEVSX1NFVF9SRVNVTFRTICovOwovKiE0MDEwMSBTRVQgQE9MRF9DT0xMQVRJT05fQ09OTkVDVElPTj1AQENPTExBVElPTl9DT05ORUNUSU9OICovOwovKiE0MDEwMSBTRVQgTkFNRVMgdXRmOCAqLzsKLyohNDAxMDMgU0VUIEBPTERfVElNRV9aT05FPUBAVElNRV9aT05FICovOwovKiE0MDEwMyBTRVQgVElNRV9aT05FPScrMDA6MDAnICovOwovKiE0MDAxNCBTRVQgQE9MRF9VTklRVUVfQ0hFQ0tTPUBAVU5JUVVFX0NIRUNLUywgVU5JUVVFX0NIRUNLUz0wICovOwovKiE0MDAxNCBTRVQgQE9MRF9GT1JFSUdOX0tFWV9DSEVDS1M9QEBGT1JFSUdOX0tFWV9DSEVDS1MsIEZPUkVJR05fS0VZX0NIRUNLUz0wICovOwovKiE0MDEwMSBTRVQgQE9MRF9TUUxfTU9ERT1AQFNRTF9NT0RFLCBTUUxfTU9ERT0nTk9fQVVUT19WQUxVRV9PTl9aRVJPJyAqLzsKLyohNDAxMTEgU0VUIEBPTERfU1FMX05PVEVTPUBAU1FMX05PVEVTLCBTUUxfTk9URVM9MCAqLzsKCkRST1AgVklFVyBJRiBFWElTVFMgYCR2aWV3TmFtZWA7CgovKiE0MDEwMSBTRVQgQHNhdmVkX2NzX2NsaWVudCAgICAgPSBAQGNoYXJhY3Rlcl9zZXRfY2xpZW50ICovOwovKiE0MDEwMSBTRVQgY2hhcmFjdGVyX3NldF9jbGllbnQgPSB1dGY4ICovOwoKJGNyZWF0ZVZpZXc7CgovKiE0MDEwMSBTRVQgY2hhcmFjdGVyX3NldF9jbGllbnQgPSBAc2F2ZWRfY3NfY2xpZW50ICovOwoKLyohNDAxMDMgU0VUIFRJTUVfWk9ORT1AT0xEX1RJTUVfWk9ORSAqLzsKLyohNDAxMDEgU0VUIFNRTF9NT0RFPUBPTERfU1FMX01PREUgKi87Ci8qITQwMDE0IFNFVCBGT1JFSUdOX0tFWV9DSEVDS1M9QE9MRF9GT1JFSUdOX0tFWV9DSEVDS1MgKi87Ci8qITQwMDE0IFNFVCBVTklRVUVfQ0hFQ0tTPUBPTERfVU5JUVVFX0NIRUNLUyAqLzsKLyohNDAxMDEgU0VUIENIQVJBQ1RFUl9TRVRfQ0xJRU5UPUBPTERfQ0hBUkFDVEVSX1NFVF9DTElFTlQgKi87Ci8qITQwMTAxIFNFVCBDSEFSQUNURVJfU0VUX1JFU1VMVFM9QE9MRF9DSEFSQUNURVJfU0VUX1JFU1VMVFMgKi87Ci8qITQwMTAxIFNFVCBDT0xMQVRJT05fQ09OTkVDVElPTj1AT0xEX0NPTExBVElPTl9DT05ORUNUSU9OICovOwovKiE0MDExMSBTRVQgU1FMX05PVEVTPUBPTERfU1FMX05PVEVTICovOwoKU1FMOwoKICAgICRmcC0+d3JpdGUoJHF1ZXJ5KTsKCiAgICByZXR1cm4gc3RybGVuKCRxdWVyeSk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2NyZWF0ZV9zZWxlY3RfcXVlcnknKSk6CmZ1bmN0aW9uIGNsb25lcl9jcmVhdGVfc2VsZWN0X3F1ZXJ5KCR0YWJsZU5hbWUsIGFycmF5ICRjb2x1bW5zKQp7CiAgICAkc2VsZWN0ID0gJ1NFTEVDVCAnOwogICAgZm9yZWFjaCAoJGNvbHVtbnMgYXMgJGkgPT4gJGNvbHVtbikgewogICAgICAgIGlmICgkaSA+IDApIHsKICAgICAgICAgICAgJHNlbGVjdCAuPSAnLCAnOwogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKCRjb2x1bW4tPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSAndGlueWJsb2InOgogICAgICAgICAgICBjYXNlICdtZWRpdW1ibG9iJzoKICAgICAgICAgICAgY2FzZSAnYmxvYic6CiAgICAgICAgICAgIGNhc2UgJ2xvbmdibG9iJzoKICAgICAgICAgICAgY2FzZSAnYmluYXJ5JzoKICAgICAgICAgICAgY2FzZSAndmFyYmluYXJ5JzoKICAgICAgICAgICAgICAgICRzZWxlY3QgLj0gIkhFWChgJGNvbHVtbi0+bmFtZWApIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgJHNlbGVjdCAuPSAiYCRjb2x1bW4tPm5hbWVgIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgICRzZWxlY3QgLj0gIiBGUk9NIGAkdGFibGVOYW1lYDsiOwoKICAgIHJldHVybiAkc2VsZWN0Owp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9jcmVhdGVfaW5zZXJ0X3F1ZXJ5JykpOgpmdW5jdGlvbiBjbG9uZXJfY3JlYXRlX2luc2VydF9xdWVyeShDbG9uZXJEQkNvbm4gJGNvbm4sICR0YWJsZU5hbWUsIGFycmF5ICRjb2x1bW5zLCBhcnJheSAkcm93KQp7CiAgICAkaW5zZXJ0ID0gIklOU0VSVCBJTlRPIGAkdGFibGVOYW1lYCBWQUxVRVMgKCI7CiAgICAkaSAgICAgID0gMDsKICAgIGZvcmVhY2ggKCRyb3cgYXMgJHZhbHVlKSB7CiAgICAgICAgJGNvbHVtbiA9ICRjb2x1bW5zWyRpXTsKICAgICAgICBpZiAoJGkgPiAwKSB7CiAgICAgICAgICAgICRpbnNlcnQgLj0gJywnOwogICAgICAgIH0KICAgICAgICAkaSsrOwogICAgICAgIGlmICgkdmFsdWUgPT09IG51bGwpIHsKICAgICAgICAgICAgJGluc2VydCAuPSAnbnVsbCc7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKCRjb2x1bW4tPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSAndGlueWludCc6CiAgICAgICAgICAgIGNhc2UgJ3NtYWxsaW50JzoKICAgICAgICAgICAgY2FzZSAnbWVkaXVtaW50JzoKICAgICAgICAgICAgY2FzZSAnaW50JzoKICAgICAgICAgICAgY2FzZSAnYmlnaW50JzoKICAgICAgICAgICAgY2FzZSAnZGVjaW1hbCc6CiAgICAgICAgICAgIGNhc2UgJ2Zsb2F0JzoKICAgICAgICAgICAgY2FzZSAnZG91YmxlJzoKICAgICAgICAgICAgICAgICRpbnNlcnQgLj0gJHZhbHVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ3RpbnlibG9iJzoKICAgICAgICAgICAgY2FzZSAnbWVkaXVtYmxvYic6CiAgICAgICAgICAgIGNhc2UgJ2Jsb2InOgogICAgICAgICAgICBjYXNlICdsb25nYmxvYic6CiAgICAgICAgICAgIGNhc2UgJ2JpbmFyeSc6CiAgICAgICAgICAgIGNhc2UgJ3ZhcmJpbmFyeSc6CiAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCR2YWx1ZSkgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAkaW5zZXJ0IC49ICInJyI7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICRpbnNlcnQgLj0gIjB4JHZhbHVlIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdiaXQnOgogICAgICAgICAgICAgICAgJGluc2VydCAuPSAkdmFsdWUgPyAiYicxJyIgOiAiYicwJyI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICRpbnNlcnQgLj0gJGNvbm4tPmVzY2FwZSgkdmFsdWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgJGluc2VydCAuPSAiKTtcbiI7CgogICAgcmV0dXJuICRpbnNlcnQ7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2R1bXBfdGFibGUnKSk6CmZ1bmN0aW9uIGNsb25lcl9kdW1wX3RhYmxlKENsb25lckRCQ29ubiAkY29ubiwgJHRhYmxlTmFtZSwgYXJyYXkgJGNvbHVtbnMsICRub0RhdGEsIENsb25lcldyaXRlciAkZnApCnsKICAgICR3cml0dGVuICAgICA9IDA7CiAgICAkcmVzdWx0ICAgICAgPSAkY29ubi0+cXVlcnkoIlNIT1cgQ1JFQVRFIFRBQkxFIGAkdGFibGVOYW1lYCIpLT5mZXRjaCgpOwogICAgJGNyZWF0ZVRhYmxlID0gJHJlc3VsdFsnQ3JlYXRlIFRhYmxlJ107CiAgICBpZiAoZW1wdHkoJGNyZWF0ZVRhYmxlKSkgewogICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oc3ByaW50ZignU0hPVyBDUkVBVEUgVEFCTEUgZGlkIG5vdCByZXR1cm4gZXhwZWN0ZWQgcmVzdWx0IGZvciB0YWJsZSAlcycsICR0YWJsZU5hbWUpLCAnbm9fY3JlYXRlX3RhYmxlJyk7CiAgICB9CgogICAgJHRpbWUgICAgICAgICAgPSBkYXRlKCdjJyk7CiAgICAkZmV0Y2hBbGxRdWVyeSA9IGNsb25lcl9jcmVhdGVfc2VsZWN0X3F1ZXJ5KCR0YWJsZU5hbWUsICRjb2x1bW5zKTsKICAgICRoYWx0Q29tcGlsZXIgID0gIjw/cGhwIGV4aXQ7IF9faGFsdF9jb21waWxlcigpOyI7CiAgICAkZHVtcGVyICAgICAgICA9IGdldF9jbGFzcygkY29ubik7CiAgICAkcGhwVmVyc2lvbiAgICA9IHBocHZlcnNpb24oKTsKICAgICRoZWFkZXIgICAgICAgID0gPDw8U1FMCi0tICRoYWx0Q29tcGlsZXIgLy8gUHJvdGVjdCB0aGUgZmlsZSBmcm9tIGJlaW5nIHZpc2l0ZWQgdmlhIHdlYgotLSBPcmlvbiBiYWNrdXAgZm9ybWF0Ci0tIEdlbmVyYXRlZCBhdDogJHRpbWUgYnkgJGR1bXBlcjsgUEhQIHYkcGhwVmVyc2lvbgotLSBTZWxlY3RlZCB2aWE6ICRmZXRjaEFsbFF1ZXJ5CgovKiE0MDEwMSBTRVQgQE9MRF9DSEFSQUNURVJfU0VUX0NMSUVOVD1AQENIQVJBQ1RFUl9TRVRfQ0xJRU5UICovOwovKiE0MDEwMSBTRVQgQE9MRF9DSEFSQUNURVJfU0VUX1JFU1VMVFM9QEBDSEFSQUNURVJfU0VUX1JFU1VMVFMgKi87Ci8qITQwMTAxIFNFVCBAT0xEX0NPTExBVElPTl9DT05ORUNUSU9OPUBAQ09MTEFUSU9OX0NPTk5FQ1RJT04gKi87Ci8qITQwMTAxIFNFVCBOQU1FUyB1dGY4ICovOwovKiE0MDEwMyBTRVQgQE9MRF9USU1FX1pPTkU9QEBUSU1FX1pPTkUgKi87Ci8qITQwMTAzIFNFVCBUSU1FX1pPTkU9JyswMDowMCcgKi87Ci8qITQwMDE0IFNFVCBAT0xEX1VOSVFVRV9DSEVDS1M9QEBVTklRVUVfQ0hFQ0tTLCBVTklRVUVfQ0hFQ0tTPTAgKi87Ci8qITQwMDE0IFNFVCBAT0xEX0ZPUkVJR05fS0VZX0NIRUNLUz1AQEZPUkVJR05fS0VZX0NIRUNLUywgRk9SRUlHTl9LRVlfQ0hFQ0tTPTAgKi87Ci8qITQwMTAxIFNFVCBAT0xEX1NRTF9NT0RFPUBAU1FMX01PREUsIFNRTF9NT0RFPSdOT19BVVRPX1ZBTFVFX09OX1pFUk8nICovOwovKiE0MDExMSBTRVQgQE9MRF9TUUxfTk9URVM9QEBTUUxfTk9URVMsIFNRTF9OT1RFUz0wICovOwoKRFJPUCBUQUJMRSBJRiBFWElTVFMgYCR0YWJsZU5hbWVgOwoKLyohNDAxMDEgU0VUIEBzYXZlZF9jc19jbGllbnQgICAgID0gQEBjaGFyYWN0ZXJfc2V0X2NsaWVudCAqLzsKLyohNDAxMDEgU0VUIGNoYXJhY3Rlcl9zZXRfY2xpZW50ID0gdXRmOCAqLzsKCiRjcmVhdGVUYWJsZTsKCi8qITQwMTAxIFNFVCBjaGFyYWN0ZXJfc2V0X2NsaWVudCA9IEBzYXZlZF9jc19jbGllbnQgKi87CgpTUUw7CiAgICBpZiAoISRub0RhdGEpIHsKICAgICAgICAkaGVhZGVyIC49IDw8PFNRTApMT0NLIFRBQkxFUyBgJHRhYmxlTmFtZWAgV1JJVEU7Ci8qITQwMDAwIEFMVEVSIFRBQkxFIGAkdGFibGVOYW1lYCBESVNBQkxFIEtFWVMgKi87CgpTUUw7CiAgICB9CiAgICAkZnAtPndyaXRlKCRoZWFkZXIpOwogICAgJHdyaXR0ZW4gKz0gc3RybGVuKCRoZWFkZXIpOwoKICAgIGlmICghJG5vRGF0YSkgewogICAgICAgICRmbHVzaFNpemUgPSA4IDw8IDIwOwogICAgICAgICRidWYgICAgICAgPSAnJzsKICAgICAgICAkZmV0Y2hBbGwgID0gJGNvbm4tPnF1ZXJ5KCRmZXRjaEFsbFF1ZXJ5LCBhcnJheSgpLCB0cnVlKTsKICAgICAgICB3aGlsZSAoJHJvdyA9ICRmZXRjaEFsbC0+ZmV0Y2goKSkgewogICAgICAgICAgICAkYnVmIC49IGNsb25lcl9jcmVhdGVfaW5zZXJ0X3F1ZXJ5KCRjb25uLCAkdGFibGVOYW1lLCAkY29sdW1ucywgJHJvdyk7CiAgICAgICAgICAgIGlmIChzdHJsZW4oJGJ1ZikgPCAkZmx1c2hTaXplKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZnAtPndyaXRlKCRidWYpOwogICAgICAgICAgICAkd3JpdHRlbiArPSBzdHJsZW4oJGJ1Zik7CiAgICAgICAgICAgICRidWYgICAgID0gJyc7CiAgICAgICAgfQogICAgICAgIGlmIChzdHJsZW4oJGJ1ZikpIHsKICAgICAgICAgICAgJGZwLT53cml0ZSgkYnVmKTsKICAgICAgICAgICAgJHdyaXR0ZW4gKz0gc3RybGVuKCRidWYpOwogICAgICAgICAgICB1bnNldCgkYnVmKTsKICAgICAgICB9CiAgICAgICAgJGZldGNoQWxsLT5mcmVlKCk7CiAgICB9CgogICAgJGZvb3RlciA9IDw8PFNRTAoKLyohNDAxMDMgU0VUIFRJTUVfWk9ORT1AT0xEX1RJTUVfWk9ORSAqLzsKLyohNDAxMDEgU0VUIFNRTF9NT0RFPUBPTERfU1FMX01PREUgKi87Ci8qITQwMDE0IFNFVCBGT1JFSUdOX0tFWV9DSEVDS1M9QE9MRF9GT1JFSUdOX0tFWV9DSEVDS1MgKi87Ci8qITQwMDE0IFNFVCBVTklRVUVfQ0hFQ0tTPUBPTERfVU5JUVVFX0NIRUNLUyAqLzsKLyohNDAxMDEgU0VUIENIQVJBQ1RFUl9TRVRfQ0xJRU5UPUBPTERfQ0hBUkFDVEVSX1NFVF9DTElFTlQgKi87Ci8qITQwMTAxIFNFVCBDSEFSQUNURVJfU0VUX1JFU1VMVFM9QE9MRF9DSEFSQUNURVJfU0VUX1JFU1VMVFMgKi87Ci8qITQwMTAxIFNFVCBDT0xMQVRJT05fQ09OTkVDVElPTj1AT0xEX0NPTExBVElPTl9DT05ORUNUSU9OICovOwovKiE0MDExMSBTRVQgU1FMX05PVEVTPUBPTERfU1FMX05PVEVTICovOwoKU1FMOwogICAgaWYgKCEkbm9EYXRhKSB7CiAgICAgICAgJGZvb3RlciA9IDw8PFNRTAoKLyohNDAwMDAgQUxURVIgVEFCTEUgYCR0YWJsZU5hbWVgIEVOQUJMRSBLRVlTICovOwpVTkxPQ0sgVEFCTEVTOwpTUUwKICAgICAgICAgICAgLiRmb290ZXI7CiAgICB9CiAgICAkZnAtPndyaXRlKCRmb290ZXIpOwogICAgJHdyaXR0ZW4gKz0gc3RybGVuKCRmb290ZXIpOwoKICAgIHJldHVybiAkd3JpdHRlbjsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfYWN0aW9uX2R1bXBfdGFibGVzJykpOgpmdW5jdGlvbiBjbG9uZXJfYWN0aW9uX2R1bXBfdGFibGVzKCRyb290LCAkaWQsICRkYiwgJHN0YXRlLCAkdGltZW91dCwgJHN0cmVhbSkKewogICAgc2V0X3RpbWVfbGltaXQobWF4KCR0aW1lb3V0ICogNSwgOTAwKSk7CiAgICAkY29ubiAgICAgPSBjbG9uZXJfZGJfY29ubigkZGIpOwogICAgJHN0YXRlICAgID0gQ2xvbmVyREJEdW1wU3RhdGU6OmZyb21BcnJheSgkc3RhdGUpOwogICAgJGRlYWRsaW5lID0gbmV3IENsb25lckRlYWRsaW5lKCR0aW1lb3V0KTsKICAgICRzdWZmaXggICA9ICcvbXdwX2RiJzsKICAgIGlmIChzdHJsZW4oJGVyciA9IGNsb25lcl9tYWtlX2Rpcigkcm9vdCwgJ213cF9kYicpKSB8fCBzdHJsZW4oJGVyciA9IGNsb25lcl93cml0ZV9maWxlKCIkcm9vdCRzdWZmaXgvaW5kZXgucGhwIiwgMCwgJycpKSkgewogICAgICAgICRyb290ICAgPSBzeXNfZ2V0X3RlbXBfZGlyKCk7CiAgICAgICAgJHN1ZmZpeCA9ICIvbXdwX2RiJGlkIjsKICAgICAgICBpZiAoc3RybGVuKGNsb25lcl9tYWtlX2Rpcigkcm9vdCwgIm13cF9kYiRpZCIpKSB8fCBzdHJsZW4oY2xvbmVyX3dyaXRlX2ZpbGUoIiRyb290JHN1ZmZpeC9pbmRleC5waHAiLCAwLCAnJykpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oJGVycik7CiAgICAgICAgfQogICAgfQogICAgJGNvdW50ICA9IDA7CiAgICAkc3RyZWFtID0gY2xvbmVyX3N0cmVhbSgkc3RyZWFtKTsKICAgIC8qKiBAdmFyIENsb25lclN0cmVhbXxudWxsICRzdHJlYW0gKi8KICAgIGZvcmVhY2ggKCRzdGF0ZS0+bGlzdCBhcyAkdGFibGUpIHsKICAgICAgICBpZiAoJGNvdW50ID4gMCAmJiAkZGVhZGxpbmUtPmRvbmUoKSkgewogICAgICAgICAgICBpZiAoJHN0cmVhbSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkc3RhdGU7CiAgICAgICAgfQogICAgICAgIGlmICgkdGFibGUtPmRvbmUpIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGlmICghJGNvbm4tPnVzZUNvbm5lY3Rpb24oJHRhYmxlLT5zb3VyY2UpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oc3ByaW50ZignQ29ubmVjdGlvbiAlcyBmb3IgdGFibGUgJXMgbm90IGZvdW5kJywgJHRhYmxlLT5zb3VyY2UsICR0YWJsZS0+bmFtZSkpOwogICAgICAgIH0KICAgICAgICBpZiAoISR0YWJsZS0+bGlzdGVkICYmICR0YWJsZS0+dHlwZSA9PT0gQ2xvbmVyVGFibGVUeXBlOjpSRUdVTEFSKSB7CiAgICAgICAgICAgICR0YWJsZS0+Y29sdW1ucyA9IGNsb25lcl9nZXRfdGFibGVfY29sdW1ucygkY29ubiwgJHRhYmxlLT5uYW1lKTsKICAgICAgICAgICAgJHRhYmxlLT5saXN0ZWQgID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgJHNvdXJjZSA9ICcnOwogICAgICAgIGlmIChzdHJsZW4oJHRhYmxlLT5zb3VyY2UpKSB7CiAgICAgICAgICAgICRzb3VyY2UgPSAnXycubWQ1KCR0YWJsZS0+c291cmNlKTsKICAgICAgICB9CiAgICAgICAgJHRhYmxlLT5wYXRoID0gIm13cF9kYi8kdGFibGUtPm5hbWV7JHNvdXJjZX0uc3FsLnBocCI7CiAgICAgICAgJGZwICAgICAgICAgID0gJHN0cmVhbTsKICAgICAgICBpZiAoISRmcCkgewogICAgICAgICAgICAkdGFibGVQYXRoID0gIiRyb290JHN1ZmZpeC97JHRhYmxlLT5uYW1lfXskc291cmNlfS5zcWwucGhwIjsKICAgICAgICAgICAgJGZwICAgICAgICA9IG5ldyBDbG9uZXJGaWxlSGFuZGxlKCR0YWJsZVBhdGgsICd3YicpOwogICAgICAgIH0KICAgICAgICAkZSA9IG51bGw7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgc3dpdGNoICgkdGFibGUtPnR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgQ2xvbmVyVGFibGVUeXBlOjpQUk9DRURVUkU6CiAgICAgICAgICAgICAgICAgICAgJHRhYmxlLT5zaXplID0gY2xvbmVyX2R1bXBfcHJvY2VkdXJlKCRjb25uLCAkdGFibGUtPm5hbWUsICRmcCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIENsb25lclRhYmxlVHlwZTo6RlVOQzoKICAgICAgICAgICAgICAgICAgICAkdGFibGUtPnNpemUgPSBjbG9uZXJfZHVtcF9mdW5jdGlvbigkY29ubiwgJHRhYmxlLT5uYW1lLCAkZnApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBDbG9uZXJUYWJsZVR5cGU6OlZJRVc6CiAgICAgICAgICAgICAgICAgICAgJHRhYmxlLT5zaXplID0gY2xvbmVyX2R1bXBfdmlldygkY29ubiwgJHRhYmxlLT5uYW1lLCAkZnApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAkdGFibGUtPnNpemUgPSBjbG9uZXJfZHVtcF90YWJsZSgkY29ubiwgJHRhYmxlLT5uYW1lLCAkdGFibGUtPmNvbHVtbnMsICR0YWJsZS0+bm9EYXRhLCAkZnApOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgIH0KICAgICAgICBpZiAoJGZwIGluc3RhbmNlb2YgQ2xvbmVyRmlsZUhhbmRsZSkgewogICAgICAgICAgICAkZnAtPmNsb3NlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChpc3NldCgkZSkgJiYgJHRhYmxlLT50eXBlID09PSBDbG9uZXJUYWJsZVR5cGU6OlJFR1VMQVIpIHsKICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgfQogICAgICAgICR0YWJsZS0+ZG9uZSA9IHRydWU7CiAgICAgICAgJHN0cmVhbSAmJiAkc3RyZWFtLT5wcm9ncmVzcygkdGFibGUpOwogICAgICAgICRjb3VudCsrOwogICAgfQogICAgJHN0YXRlLT5kb25lID0gdHJ1ZTsKICAgIGlmICgkc3RyZWFtKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICByZXR1cm4gJHN0YXRlOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9hY3Rpb25fZGVsZXRlX2ZpbGVzJykpOgpmdW5jdGlvbiBjbG9uZXJfYWN0aW9uX2RlbGV0ZV9maWxlcygkcm9vdCwgYXJyYXkgJGZpbGVzLCAkaWQsICRlcnJvckxvZ1NpemUgPSAwKQp7CiAgICAkb2sgICAgICAgPSB0cnVlOwogICAgJGVycnMgICAgID0gIkNvdWxkIG5vdCByZW1vdmUgdGhlIGZvbGxvd2luZyBmaWxlczoiOwogICAgJGVycm9yTG9nID0gJyc7CiAgICBpZiAoJGVycm9yTG9nU2l6ZSAhPT0gMCkgewogICAgICAgICRlcnJvckxvZyA9IEBmaWxlX2dldF9jb250ZW50cygnY2xvbmVyX2Vycm9yX2xvZycsIGZhbHNlLCBudWxsLCAwLCAkZXJyb3JMb2dTaXplKTsKICAgICAgICBpZiAoJGVycm9yTG9nID09PSBmYWxzZSkgewogICAgICAgICAgICAkZXJyb3JMb2cgPSBzcHJpbnRmKCd1bmFibGUgdG8gcmVhZCBlcnJvciBsb2c6ICVzJywgY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdmaWxlX2dldF9jb250ZW50cycpKTsKICAgICAgICB9CiAgICB9CiAgICBmb3JlYWNoICgkZmlsZXMgYXMgJGZpbGUpIHsKICAgICAgICAkZXJyID0gY2xvbmVyX3JlbW92ZV9maWxlX29yX2Rpcigkcm9vdC4nLycuJGZpbGUpOwogICAgICAgIGlmIChzdHJsZW4oJGVycikpIHsKICAgICAgICAgICAgJGVycnMgLj0gIiAkZmlsZSAoJGVycik7IjsKICAgICAgICAgICAgJG9rICAgPSBmYWxzZTsKICAgICAgICB9CiAgICB9CiAgICBpZiAoc3RybGVuKCRpZCkpIHsKICAgICAgICAkdGVtcCA9IHN5c19nZXRfdGVtcF9kaXIoKS4iL213cF9kYiRpZCI7CiAgICAgICAgJGVyciAgPSBjbG9uZXJfcmVtb3ZlX2ZpbGVfb3JfZGlyKCR0ZW1wKTsKICAgICAgICBpZiAoc3RybGVuKCRlcnIpKSB7CiAgICAgICAgICAgICRlcnJzIC49ICIgJHRlbXAgKCRlcnIpOyI7CiAgICAgICAgICAgICRvayAgID0gZmFsc2U7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFycmF5KAogICAgICAgICdvaycgICAgICAgPT4gJG9rLAogICAgICAgICdlcnJvcicgICAgPT4gJG9rID8gbnVsbCA6ICRlcnJzLAogICAgICAgICdlcnJvckxvZycgPT4gYmFzZTY0X2VuY29kZSgkZXJyb3JMb2cpLAogICAgKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfaXNfbXVsdGlzaXRlJykpOgpmdW5jdGlvbiBjbG9uZXJfaXNfbXVsdGlzaXRlKCkKewogICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnaXNfbXVsdGlzaXRlJykpIHsKICAgICAgICByZXR1cm4gaXNfbXVsdGlzaXRlKCk7CiAgICB9CiAgICBpZiAoZGVmaW5lZCgnTVVMVElTSVRFJykpIHsKICAgICAgICByZXR1cm4gTVVMVElTSVRFOwogICAgfQogICAgaWYgKGRlZmluZWQoJ1NVQkRPTUFJTl9JTlNUQUxMJykgfHwgZGVmaW5lZCgnVkhPU1QnKSB8fCBkZWZpbmVkKCdTVU5SSVNFJykpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfd3BfZmx1c2hfcmV3cml0ZV9ydWxlcycpKToKZnVuY3Rpb24gY2xvbmVyX3dwX2ZsdXNoX3Jld3JpdGVfcnVsZXMoKQp7CiAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdmbHVzaF9yZXdyaXRlX3J1bGVzJykpIHsKICAgICAgICBmbHVzaF9yZXdyaXRlX3J1bGVzKHRydWUpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oJ0Z1bmN0aW9uIGZsdXNoX3Jld3JpdGVfcnVsZXMgbm90IGZvdW5kJyk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl9mbHVzaF9yZXdyaXRlX3J1bGVzJykpOgpmdW5jdGlvbiBjbG9uZXJfYWN0aW9uX2ZsdXNoX3Jld3JpdGVfcnVsZXMoJGRiLCAkaWQsICRwcmVmaXgsICRhY3RpdmF0ZVdvcmtlciwgJHRpbWVvdXQsICRpc09yaWdpbmFsSHRhY2Nlc3MpCnsKICAgICRjb25uID0gY2xvbmVyX2RiX2Nvbm4oJGRiKTsKICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3czdGNfcGdjYWNoZV9mbHVzaCcpKSB7CiAgICAgICAgdzN0Y19wZ2NhY2hlX2ZsdXNoKCk7CiAgICB9CiAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCd3M3RjX2RiY2FjaGVfZmx1c2gnKSkgewogICAgICAgIHczdGNfZGJjYWNoZV9mbHVzaCgpOwogICAgfQogICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygndzN0Y19vYmplY3RjYWNoZV9mbHVzaCcpKSB7CiAgICAgICAgdzN0Y19vYmplY3RjYWNoZV9mbHVzaCgpOwogICAgfQogICAgLy9jaGVjayBpZiBNV1Agc2VydmVyCiAgICBpZiAoaXNzZXQoJF9TRVJWRVJbJ1dQQUFTX1NJVEVfSUQnXSkgfHwgZ2V0ZW52KCdXUEFBU19TSVRFX0lEJykpIHsKICAgICAgICAvLyBHb0RhZGR5IG1hbmFnZWQgd29yZHByZXNzIGhvc3RpbmcsIG1hbnVhbGx5IGZsdXNoIGNhY2hlLgogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2RvX2FjdGlvbicpKSB7CiAgICAgICAgICAgIGRvX2FjdGlvbignZmx1c2hfY2FjaGUnLCBhcnJheSgnYmFuJyA9PiAxLCAndXJscycgPT4gYXJyYXkoKSkpOwogICAgICAgIH0KICAgIH0KICAgIC8vY2hlY2sgaWYgTVdQVjIgc2VydmVyCiAgICBpZiAoaXNzZXQoJF9TRVJWRVJbJ1dQQUFTX1YyX1NJVEVfSUQnXSkgfHwgZ2V0ZW52KCdXUEFBU19WMl9TSVRFX0lEJykpIHsKICAgICAgICAvLyBHb0RhZGR5IG1hbmFnZWQgd29yZHByZXNzIGhvc3RpbmcsIG1hbnVhbGx5IGZsdXNoIGNhY2hlLgogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2RvX2FjdGlvbicpKSB7CiAgICAgICAgICAgIGRvX2FjdGlvbignZ2RsX3NwbGFzaF9wYWdlX3NldCcpOwogICAgICAgIH0KICAgIH0KICAgIGlmIChjbGFzc19leGlzdHMoJ0VTU0JEeW5hbWljQ2FjaGUnKSkgewogICAgICAgIGlmIChpc19jYWxsYWJsZShhcnJheSgnRVNTQkR5bmFtaWNDYWNoZScsICdmbHVzaCcpKSkgewogICAgICAgICAgICBFU1NCRHluYW1pY0NhY2hlOjpmbHVzaCgpOwogICAgICAgIH0KICAgIH0KICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3B1cmdlX2Vzc2JfY2FjaGVfc3RhdGljX2NhY2hlJykpIHsKICAgICAgICBwdXJnZV9lc3NiX2NhY2hlX3N0YXRpY19jYWNoZSgpOwogICAgfQogICAgaWYgKGNsb25lcl9pc19tdWx0aXNpdGUoKSkgewogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2FkZF9maWx0ZXInKSkgewogICAgICAgICAgICBhZGRfZmlsdGVyKCdtb2RfcmV3cml0ZV9ydWxlcycsIGFycmF5KF9fQ0xBU1NfXywgJ21zUmV3cml0ZVJ1bGVzJykpOwogICAgICAgIH0KICAgIH0KICAgICRvayA9IGZhbHNlOwogICAgaWYgKCEkaXNPcmlnaW5hbEh0YWNjZXNzKSB7CiAgICAgICAgY2xvbmVyX3dwX2ZsdXNoX3Jld3JpdGVfcnVsZXMoKTsKICAgICAgICBpZiAoJHRpbWVvdXQpIHsKICAgICAgICAgICAgJGRvbmUgPSB0aW1lKCk7CiAgICAgICAgICAgIHdoaWxlICgkdGltZW91dCkgewogICAgICAgICAgICAgICAgJHJvdyAgICAgICA9ICRjb25uLT5xdWVyeSgiU0VMRUNUIG9wdGlvbl92YWx1ZSBGUk9NIHskcHJlZml4fW9wdGlvbnMgV0hFUkUgb3B0aW9uX25hbWUgPSAnY2xvbmVfaGVhcnRiZWF0X3skaWR9JyIpLT5mZXRjaCgpOwogICAgICAgICAgICAgICAgJGhlYXJ0YmVhdCA9IGlzX2FycmF5KCRyb3cpID8gKGludCllbmQoJHJvdykgOiAwOwogICAgICAgICAgICAgICAgaWYgKCRoZWFydGJlYXQgLSAxID4gJGRvbmUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBXZSBoaXQgUEhQIGFmdGVyIHRoZSBjcmVhdGlvbiBvZiByZXdyaXRlIHJ1bGVzIC0gZXZlcnl0aGluZyBsb29rcyBvay4KICAgICAgICAgICAgICAgICAgICAkb2sgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJHRpbWVvdXQtLTsKICAgICAgICAgICAgICAgIHNsZWVwKDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRjb25uLT5xdWVyeSgiREVMRVRFIEZST00geyRwcmVmaXh9b3B0aW9ucyBXSEVSRSBvcHRpb25fbmFtZSA9ICdjbG9uZV9oZWFydGJlYXRfeyRpZH0nIik7CiAgICAgICAgICAgIGlmICghJG9rKSB7CiAgICAgICAgICAgICAgICAvL3Bvc3RvamkgbW9ndWNub3N0IGRhIG9icmlzZW1vIHBvZ3Jlc2FuIGh0YWNjZXNzCiAgICAgICAgICAgICAgICBmb3JlYWNoIChhcnJheShBQlNQQVRILicuaHRhY2Nlc3MnLCBBQlNQQVRILicuLi8uaHRhY2Nlc3MnKSBhcyAkcGF0aCkgewogICAgICAgICAgICAgICAgICAgIHVubGluaygkcGF0aCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gRnJvbSB3cC1hZG1pbi9hZG1pbi5waHAKICAgIGdsb2JhbCAkd3BfZGJfdmVyc2lvbjsKICAgICR1cGRhdGVEQiA9IGZhbHNlOwogICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnZ2V0X29wdGlvbicpKSB7CiAgICAgICAgaWYgKCRvayAmJiAoZ2V0X29wdGlvbignZGJfdmVyc2lvbicpICE9ICR3cF9kYl92ZXJzaW9uKSkgewogICAgICAgICAgICAkdXBkYXRlREIgPSB0cnVlOwogICAgICAgIH0KICAgIH0KICAgIGlmICgkdXBkYXRlREIpIHsKICAgICAgICBpZiAoIWZ1bmN0aW9uX2V4aXN0cygnd3BfdXBncmFkZScpKSB7CiAgICAgICAgICAgIC8qKiBAbm9pbnNwZWN0aW9uIFBocEluY2x1ZGVJbnNwZWN0aW9uICovCiAgICAgICAgICAgIHJlcXVpcmVfb25jZSBjbG9uZXJfY29uc3RhbnQoJ0FCU1BBVEgnKS4nd3AtYWRtaW4vaW5jbHVkZXMvdXBncmFkZS5waHAnOwogICAgICAgIH0KICAgICAgICBvYl9zdGFydCgpOwogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3dwX3VwZ3JhZGUnKSkgewogICAgICAgICAgICB3cF91cGdyYWRlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2RvX2FjdGlvbicpKSB7CiAgICAgICAgICAgIGRvX2FjdGlvbignYWZ0ZXJfZGJfdXBncmFkZScpOwogICAgICAgIH0KICAgICAgICBvYl9lbmRfY2xlYW4oKTsKICAgIH0KICAgIGlmICgkYWN0aXZhdGVXb3JrZXIpIHsKICAgICAgICAkcGx1Z2luc09wdGlvbiA9ICdhY3RpdmVfcGx1Z2lucyc7CiAgICAgICAgJG11bHRpc2l0ZSAgICAgPSBjbG9uZXJfaXNfbXVsdGlzaXRlKCk7CiAgICAgICAgaWYgKCRtdWx0aXNpdGUpIHsKICAgICAgICAgICAgJHBsdWdpbnNPcHRpb24gPSAnYWN0aXZlX3NpdGV3aWRlX3BsdWdpbnMnOwogICAgICAgIH0KICAgICAgICAkYWN0aXZlUGx1Z2luc1NlcmlhbGl6ZWQgPSAkY29ubi0+cXVlcnkoIlNFTEVDVCBvcHRpb25fdmFsdWUgRlJPTSB7JHByZWZpeH1vcHRpb25zIFdIRVJFIG9wdGlvbl9uYW1lID0gJ3skcGx1Z2luc09wdGlvbn0nIExJTUlUIDEiKS0+ZmV0Y2goKTsKICAgICAgICAkYWN0aXZlUGx1Z2luc1NlcmlhbGl6ZWQgPSAoc3RyaW5nKUBlbmQoJGFjdGl2ZVBsdWdpbnNTZXJpYWxpemVkKTsKICAgICAgICAkYWN0aXZlUGx1Z2lucyAgICAgICAgICAgPSBAdW5zZXJpYWxpemUoJGFjdGl2ZVBsdWdpbnNTZXJpYWxpemVkKTsKICAgICAgICAkd29ya2VyUGx1Z2luICAgICAgICAgICAgPSAnd29ya2VyL2luaXQucGhwJzsKICAgICAgICBpZiAoaXNfYXJyYXkoJGFjdGl2ZVBsdWdpbnMpICYmICRtdWx0aXNpdGUgJiYgIWFycmF5X2tleV9leGlzdHMoJHdvcmtlclBsdWdpbiwgJGFjdGl2ZVBsdWdpbnMpKSB7CiAgICAgICAgICAgICRhY3RpdmVQbHVnaW5zWyR3b3JrZXJQbHVnaW5dID0gdHJ1ZTsKICAgICAgICAgICAgJGNvbm4tPnF1ZXJ5KCJVUERBVEUgeyRwcmVmaXh9b3B0aW9ucyBTRVQgb3B0aW9uX3ZhbHVlID0gOnZhbCBXSEVSRSBvcHRpb25fbmFtZSA9ICd7JHBsdWdpbnNPcHRpb259JyBMSU1JVCAxIiwgYXJyYXkoCiAgICAgICAgICAgICAgICAndmFsJyA9PiBzZXJpYWxpemUoJGFjdGl2ZVBsdWdpbnMpLAogICAgICAgICAgICApKTsKICAgICAgICB9IGVsc2VpZiAoaXNfYXJyYXkoJGFjdGl2ZVBsdWdpbnMpICYmICEkbXVsdGlzaXRlICYmICFpbl9hcnJheSgkd29ya2VyUGx1Z2luLCAkYWN0aXZlUGx1Z2lucywgdHJ1ZSkpIHsKICAgICAgICAgICAgJGFjdGl2ZVBsdWdpbnNbXSA9ICR3b3JrZXJQbHVnaW47CiAgICAgICAgICAgICRjb25uLT5xdWVyeSgiVVBEQVRFIHskcHJlZml4fW9wdGlvbnMgU0VUIG9wdGlvbl92YWx1ZSA9IDp2YWwgV0hFUkUgb3B0aW9uX25hbWUgPSAneyRwbHVnaW5zT3B0aW9ufScgTElNSVQgMSIsIGFycmF5KAogICAgICAgICAgICAgICAgJ3ZhbCcgPT4gc2VyaWFsaXplKCRhY3RpdmVQbHVnaW5zKSwKICAgICAgICAgICAgKSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFycmF5KCdvaycgPT4gJG9rKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfYWN0aW9uX2hlYXJ0YmVhdCcpKToKZnVuY3Rpb24gY2xvbmVyX2FjdGlvbl9oZWFydGJlYXQoJGRiLCAkcHJlZml4LCAkaWQpCnsKICAgICRjb25uID0gY2xvbmVyX2RiX2Nvbm4oJGRiKTsKICAgICR0aW1lID0gdGltZSgpOwoKICAgICRjb25uLT5xdWVyeSgiSU5TRVJUIElOVE8geyRwcmVmaXh9b3B0aW9ucyBTRVQgb3B0aW9uX25hbWUgPSAnY2xvbmVfaGVhcnRiZWF0X3skaWR9Jywgb3B0aW9uX3ZhbHVlID0gOnZhbHVlIE9OIERVUExJQ0FURSBLRVkgVVBEQVRFIG9wdGlvbl92YWx1ZSA9IDp1cGRhdGVfdmFsdWUiLCBhcnJheSgKICAgICAgICAndmFsdWUnICAgICAgICA9PiAkdGltZSwKICAgICAgICAndXBkYXRlX3ZhbHVlJyA9PiAkdGltZSwgLy9jYW4gbm90IHVzZSBkdXBsaWNhdGUgYm91bmQgcGFyYW1ldGVycyBuYW1lCiAgICApKTsKCiAgICByZXR1cm4gYXJyYXkoJ29rJyA9PiB0cnVlKTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJpbXBvcnRkdW1wJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVySW1wb3J0RHVtcAp7CiAgICBwdWJsaWMgJHNpemUgPSAwOwogICAgcHVibGljICRwcm9jZXNzZWQgPSAwOwogICAgcHVibGljICRwYXRoID0gIiI7CiAgICBwdWJsaWMgJGVuY29kaW5nID0gIiI7CiAgICBwdWJsaWMgJHNvdXJjZSA9ICIiOwogICAgcHVibGljICR0eXBlID0gMDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHNpemUsICRwcm9jZXNzZWQsICRwYXRoLCAkZW5jb2RpbmcsICRzb3VyY2UsICR0eXBlKQogICAgewogICAgICAgICR0aGlzLT5zaXplICAgICAgPSAoaW50KSRzaXplOwogICAgICAgICR0aGlzLT5wcm9jZXNzZWQgPSAoaW50KSRwcm9jZXNzZWQ7CiAgICAgICAgJHRoaXMtPnBhdGggICAgICA9IChzdHJpbmcpJHBhdGg7CiAgICAgICAgJHRoaXMtPmVuY29kaW5nICA9IChzdHJpbmcpJGVuY29kaW5nOwogICAgICAgICR0aGlzLT5zb3VyY2UgICAgPSAoc3RyaW5nKSRzb3VyY2U7CiAgICAgICAgJHRoaXMtPnR5cGUgICAgICA9IChpbnQpJHR5cGU7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyZGJpbXBvcnRzdGF0ZScsIGZhbHNlKSk6CmNsYXNzIENsb25lckRCSW1wb3J0U3RhdGUKewogICAgLyoqIEB2YXIgc3RyaW5nIENvbGxlY3RzIHNraXBwZWQgc3RhdGVtZW50cyB1cCB0byBhIGNlcnRhaW4gYnVmZmVyIGxlbmd0aC4gKi8KICAgIHB1YmxpYyAkc2tpcCA9ICIiOwogICAgLyoqIEB2YXIgaW50IENvdW50cyBza2lwcGVkIHN0YXRlbWVudHMuICovCiAgICBwdWJsaWMgJHNraXBDb3VudCA9IDA7CiAgICAvKiogQHZhciBpbnQgS2VlcHMgc2tpcHBlZCBzdGF0ZW1lbnRzJyB0b3RhbCBzaXplLiAqLwogICAgcHVibGljICRza2lwU2l6ZSA9IDA7CiAgICAvKiogQHZhciBDbG9uZXJJbXBvcnREdW1wW10gRmlsZSBkdW1wcyB0aGF0IHNob3VsZCBiZSBpbXBvcnRlZC4gKi8KICAgIHB1YmxpYyAkZmlsZXMgPSBhcnJheSgpOwoKICAgIC8qKiBAdmFyIGludCBNYXhpbXVtIGJ1ZmZlciBzaXplIGZvciBza2lwcGVkIHN0YXRlbWVudHMuICovCiAgICBwcml2YXRlICRza2lwQnVmZmVyID0gMDsKCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkZGF0YSAgICAgICBTdGF0ZSBhcnJheTsgZW1wdHkgc3RhdGUgbWVhbnMgdGhlcmUncyBub3RoaW5nIHRvIHByb2Nlc3MuIEV2ZXJ5IGZpbGUgdGhhdCBzaG91bGQgYmUgaW1wb3J0ZWQKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBtdXN0IGNvbnRhaW4gdGhlIHByb3BzICRzdGF0ZVsnZmlsZXMnXVskaV1bJ3BhdGgnXSBhbmQgJHN0YXRlWydmaWxlcyddWyRpXVsnc2l6ZSddLgogICAgICogQHBhcmFtIGludCAgICRza2lwQnVmZmVyIE1heGltdW0gYnVmZmVyIHNpemUgZm9yIHNraXBwZWQgc3RhdGVtZW50IGxvZ2dpbmcuCiAgICAgKgogICAgICogQHJldHVybiBDbG9uZXJEQkltcG9ydFN0YXRlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZnJvbUFycmF5KGFycmF5ICRkYXRhLCAkc2tpcEJ1ZmZlciA9IDApCiAgICB7CiAgICAgICAgJHN0YXRlICAgICAgICAgICAgID0gbmV3IHNlbGY7CiAgICAgICAgJHN0YXRlLT5za2lwQnVmZmVyID0gJHNraXBCdWZmZXI7CiAgICAgICAgZm9yZWFjaCAoKGFycmF5KUAkZGF0YVsnZmlsZXMnXSBhcyAkaSA9PiAkZHVtcCkgewogICAgICAgICAgICBpZiAoJGR1bXBbJ3R5cGUnXSA9PT0gQ2xvbmVyVGFibGVUeXBlOjpQUk9DRURVUkUpIHsKICAgICAgICAgICAgICAgICRkdW1wWydwYXRoJ10gPSBzdHJfcmVwbGFjZSgibXdwX2RiLyIsICJtd3BfZGIvbXdwX3Byb2NlZHVyZV8iLCAkZHVtcFsncGF0aCddKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoJGR1bXBbJ3R5cGUnXSA9PT0gQ2xvbmVyVGFibGVUeXBlOjpGVU5DKSB7CiAgICAgICAgICAgICAgICAkZHVtcFsncGF0aCddID0gc3RyX3JlcGxhY2UoIm13cF9kYi8iLCAibXdwX2RiL213cF9mdW5jdGlvbl8iLCAkZHVtcFsncGF0aCddKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkc3RhdGUtPmZpbGVzWyRpXSA9IG5ldyBDbG9uZXJJbXBvcnREdW1wKCRkdW1wWydzaXplJ10sICRkdW1wWydwcm9jZXNzZWQnXSwgJGR1bXBbJ3BhdGgnXSwgJGR1bXBbJ2VuY29kaW5nJ10sIChzdHJpbmcpQCRkdW1wWydzb3VyY2UnXSwgJGR1bXBbJ3R5cGUnXSk7CiAgICAgICAgfQogICAgICAgICRzdGF0ZS0+c2tpcCAgICAgID0gKHN0cmluZylAJGRhdGFbJ3NraXAnXTsKICAgICAgICAkc3RhdGUtPnNraXBDb3VudCA9IChpbnQpQCRkYXRhWydza2lwQ291bnQnXTsKICAgICAgICAkc3RhdGUtPnNraXBTaXplICA9IChpbnQpQCRkYXRhWydza2lwU2l6ZSddOwogICAgICAgIHJldHVybiAkc3RhdGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIENsb25lckltcG9ydER1bXB8bnVsbCBUaGUgbmV4dCBkdW1wIGluIHRoZSBxdWV1ZSwgb3IgbnVsbCBpZiB0aGVyZSBhcmUgbm9uZSBsZWZ0LgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gbmV4dCgpCiAgICB7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZpbGVzIGFzICRmaWxlKSB7CiAgICAgICAgICAgIGlmICgkZmlsZS0+cHJvY2Vzc2VkIDwgJGZpbGUtPnNpemUpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFB1c2hlcyB0aGUgZmlyc3QgYXZhaWxhYmxlIGZpbGUgZHVtcCB0byB0aGUgZW5kIG9mIHRoZSBxdWV1ZS4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHB1c2hOZXh0VG9FbmQoKQogICAgewogICAgICAgICRjYXJyeSA9IG51bGw7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmZpbGVzIGFzICRpID0+ICRmaWxlKSB7CiAgICAgICAgICAgIGlmICgkZmlsZS0+c2l6ZSA9PT0gJGZpbGUtPnByb2Nlc3NlZCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGNhcnJ5ID0gJGZpbGU7CiAgICAgICAgICAgIHVuc2V0KCR0aGlzLT5maWxlc1skaV0pOwogICAgICAgICAgICAkdGhpcy0+ZmlsZXMgPSBhcnJheV92YWx1ZXMoJHRoaXMtPmZpbGVzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGNhcnJ5ID09PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICR0aGlzLT5maWxlc1tdID0gJGNhcnJ5OwogICAgfQoKICAgIC8qKgogICAgICogQWRkIGEgInNraXBwZWQgc3RhdGVtZW50IiB0byB0aGUgc3RhdGUgaWYgdGhlcmUncyBhbnkgcGxhY2UgbGVmdCBpbiBzdGF0ZSdzICJza2lwcGVkIHN0YXRlbWVudCIgYnVmZmVyLgogICAgICogQWxzbyB1cGRhdGVzIHN0YXRlJ3MgInNraXBwZWQgc3RhdGVtZW50IiBjb3VudCBhbmQgc2l6ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RyaW5nICRzdGF0ZW1lbnRzIFN0YXRlbWVudHMgdGhhdCB3ZXJlIHNraXBwZWQuCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBza2lwU3RhdGVtZW50KCRzdGF0ZW1lbnRzKQogICAgewogICAgICAgICRsZW5ndGggPSBzdHJsZW4oJHN0YXRlbWVudHMpOwogICAgICAgIGlmIChzdHJsZW4oJHRoaXMtPnNraXApICsgJGxlbmd0aCA8PSAkdGhpcy0+c2tpcEJ1ZmZlciAvIDIpIHsKICAgICAgICAgICAgLy8gT25seSB3cml0ZSBmdWxsIHN0YXRlbWVudHMgdG8gdGhlIGJ1ZmZlciBpZiBpdCB3b24ndCBleGNlZWQgaGFsZiB0aGUgYnVmZmVyLgogICAgICAgICAgICAkdGhpcy0+c2tpcCAuPSAkc3RhdGVtZW50czsKICAgICAgICB9IGVsc2VpZiAoJGxlbmd0aCArIDIwMCA8PSAkdGhpcy0+c2tpcEJ1ZmZlcikgewogICAgICAgICAgICAvLyBXZSBoYXZlIGVub3VnaCBzcGFjZSBpbiB0aGUgYnVmZmVyIHRvIGxvZyB0aGUgZXhjZXJwdCwgYnV0IGRvbid0IG92ZXJmbG93IHRoZSBidWZmZXIsIHNraXAgbG9nZ2luZwogICAgICAgICAgICAvLyB3aGVuIHdlIHJlYWNoIGl0cyBsaW1pdC4KICAgICAgICAgICAgJHRoaXMtPnNraXAgLj0gc3ByaW50ZignLyogcXVlcnkgdG9vIGJpZyAoJWQgYnl0ZXMpLCBleGNlcnB0OiAlcyAqLzsnLCAkbGVuZ3RoLCBzdWJzdHIoJHN0YXRlbWVudHMsIDAsIDEwMCkpOwogICAgICAgIH0KCiAgICAgICAgJHRoaXMtPnNraXBDb3VudCsrOwogICAgICAgICR0aGlzLT5za2lwU2l6ZSArPSAkbGVuZ3RoOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmltcG9ydGZpbHRlcicsIGZhbHNlKSk6CmludGVyZmFjZSBDbG9uZXJJbXBvcnRGaWx0ZXIKewogICAgLyoqCiAgICAgKiBAcGFyYW0gJHN0YXRlbWVudAogICAgICoKICAgICAqIEByZXR1cm4gc3RyaW5nCiAgICAgKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGZpbHRlcigkc3RhdGVtZW50KTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJwcmVmaXhmaWx0ZXInLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJQcmVmaXhGaWx0ZXIgaW1wbGVtZW50cyBDbG9uZXJJbXBvcnRGaWx0ZXIKewogICAgcHJpdmF0ZSAkb2xkUHJlZml4ID0gJyc7CiAgICBwcml2YXRlICRuZXdQcmVmaXggPSAnJzsKICAgIHByaXZhdGUgJHJlZ2V4ID0gJyc7CiAgICBwcml2YXRlICRyZXBsYWNlbWVudCA9ICcnOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkb2xkUHJlZml4CiAgICAgKiBAcGFyYW0gc3RyaW5nICRuZXdQcmVmaXgKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRvbGRQcmVmaXgsICRuZXdQcmVmaXgpCiAgICB7CiAgICAgICAgJHRoaXMtPm9sZFByZWZpeCA9ICRvbGRQcmVmaXg7CiAgICAgICAgJHRoaXMtPm5ld1ByZWZpeCA9ICRuZXdQcmVmaXg7CiAgICAgICAgLy8gQ3JlYXRlIGEgcmVnZXggdGhhdCBoYW5kbGVzIGFsbCB0aGVzZSBjYXNlczoKICAgICAgICAvLwogICAgICAgIC8vICAvKiE0MDAwMCBBTFRFUiBUQUJMRSBgd3BfLi4uYCBESVNBQkxFIEtFWVMgKi87CiAgICAgICAgLy8gIENSRUFURSBUQUJMRSBgd3BfLi4uYCAoCiAgICAgICAgLy8gCUxPQ0sgVEFCTEVTIGB3cF8uLi5gIFdSSVRFOwogICAgICAgIC8vIAlEUk9QIFRBQkxFIElGIEVYSVNUUyBgd3BfLi4uYDsKICAgICAgICAvLyAJQUxURVIgVEFCTEUgYHdwXy4uLmAKICAgICAgICAvLyAJICBBREQgQ09OU1RSQUlOVCBgc29tZV9jb25zdHJhaW50YCBGT1JFSUdOIEtFWSAoLi4uKSBSRUZFUkVOQ0VTIGB3cF8uLi5gCiAgICAgICAgLy8gCUlOU0VSVCBJTlRPIGB3cF8uLi5gIFZBTFVFUyAoLi4uKTsKICAgICAgICAvLwogICAgICAgIC8vIFdlIGFsc28gYWx3YXlzIGdvIGZyb20gdGhlIGxpbmUgc3RhcnQsIGFzIHdlIHJlYWxseSBkb24ndCB3YW50IGFueSBmYWxzZSBwb3NpdGl2ZXMuCiAgICAgICAgLy8gVGhlIHJlcGxhY2VtZW50IHBhdHRlcm4gaXM6CiAgICAgICAgLy8gICQxIGAke25ld1ByZWZpeH0kMmAKICAgICAgICAkdGhpcy0+cmVnZXggICAgICAgPSBzcHJpbnRmKCJ7KF4oPzpcXC9cXCohXFxkKyApPyg/OkxPQ0sgVEFCTEVTfERST1AgKD86VEFCTEV8VklFVykoPzogSUYgRVhJU1RTKT98QUxURVIgKD86VEFCTEV8VklFVyl8SU5TRVJUKD86IElHTk9SRSk/IElOVE98Q1JFQVRFICg/OlRBQkxFfFZJRVcpKD86IElGIE5PVCBFWElTVFMpP3wgICg/OkFERCApP0NPTlNUUkFJTlQpfCBGT1JFSUdOIEtFWSBcXChbXlxcKV17MCw2Nn1cXCkgUkVGRVJFTkNFUykgYCVzKFteYF0rKWB9bSIsICRvbGRQcmVmaXgpOwogICAgICAgICR0aGlzLT5yZXBsYWNlbWVudCA9IHNwcmludGYoJyQxIGAlcyQyYCcsICR0aGlzLT5uZXdQcmVmaXgpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBmaWx0ZXIoJHN0YXRlbWVudCkKICAgIHsKICAgICAgICAkcmV0dXJuID0gQHByZWdfcmVwbGFjZSgkdGhpcy0+cmVnZXgsICR0aGlzLT5yZXBsYWNlbWVudCwgJHN0YXRlbWVudCk7CiAgICAgICAgaWYgKCRyZXR1cm4gPT09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihwcmVnX2xhc3RfZXJyb3IoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkcmV0dXJuOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9pc19wYWdlbHknKSk6CmZ1bmN0aW9uIGNsb25lcl9pc19wYWdlbHkoKQp7CiAgICAkaW5jbHVkZWQgICAgPSBnZXRfaW5jbHVkZWRfZmlsZXMoKTsKICAgIC8vIE1XQ1MgcmVxdWlyZXMgaXRzIG93biBjdXN0b20gZmlsZSAuLi9wYWdlbHkvd3AtY29uZmlnLWhvc3RpbmcucGhwLAogICAgLy8gd2hpY2ggdG8gdGhlIHNlcnZlciBpcyByb290ZWQgYXQgL3BhZ2VseS93cC1jb25maWctaG9zdGluZy5waHAuCiAgICAvLyBQYWdlbHksIGhvd2V2ZXIsIHN0b3JlcyBpdCBhbG9uZ3NpZGUgd3AtY29uZmlnLnBocC4KICAgIC8vIENoZWNrIHRvIHNlZSBpZiB3cC1jb25maWctaG9zdGluZy5waHAgaXMgaW5jbHVkZWQgZWFybHkuCiAgICBmb3IgKCRpID0gMDsgJGkgPCAxMDsgJGkrKykgewogICAgICAgIGlmICghaXNzZXQoJGluY2x1ZGVkWyRpXSkpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgICRmaWxlID0gJGluY2x1ZGVkWyRpXTsKICAgICAgICBpZiAoJGZpbGUgPT09ICcvcGFnZWx5L3NldHVwLnBocCcgfHwgJGZpbGUgPT09ICcvcGFnZWx5L2NvbmZpZy5waHAnKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoYmFzZW5hbWUoJGZpbGUpID09PSAnd3AtY29uZmlnLWhvc3RpbmcucGhwJykgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gKGJvb2wpc3RybGVuKGdldGVudignV1BBQVNfVjJfU0lURV9JRCcpKTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJlbnZpbmZvJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyRW52SW5mbwp7CiAgICBwdWJsaWMgJGdvRGFkZHlQcm8gPSAwOwogICAgcHVibGljICRvcGVuc2hpZnQgPSBmYWxzZTsKICAgIHB1YmxpYyAkZmx5d2hlZWwgPSBmYWxzZTsKICAgIHB1YmxpYyAkcGFnZWx5ID0gZmFsc2U7CiAgICBwdWJsaWMgJHBocFZlcnNpb25JRCA9IDA7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gaW50ICAkZ29EYWRkeVBybwogICAgICogQHBhcmFtIGJvb2wgJG9wZW5zaGlmdAogICAgICogQHBhcmFtIGJvb2wgJGZseXdoZWVsCiAgICAgKiBAcGFyYW0gYm9vbCAkcGFnZWx5CiAgICAgKiBAcGFyYW0gaW50ICAkcGhwVmVyc2lvbklECiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZ29EYWRkeVBybywgJG9wZW5zaGlmdCwgJGZseXdoZWVsLCAkcGFnZWx5LCAkcGhwVmVyc2lvbklEKQogICAgewogICAgICAgICR0aGlzLT5nb0RhZGR5UHJvICAgPSAkZ29EYWRkeVBybzsKICAgICAgICAkdGhpcy0+b3BlbnNoaWZ0ICAgID0gJG9wZW5zaGlmdDsKICAgICAgICAkdGhpcy0+Zmx5d2hlZWwgICAgID0gJGZseXdoZWVsOwogICAgICAgICR0aGlzLT5wYWdlbHkgICAgICAgPSAkcGFnZWx5OwogICAgICAgICR0aGlzLT5waHBWZXJzaW9uSUQgPSAkcGhwVmVyc2lvbklEOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB0b0FycmF5KCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICdnb0RhZGR5UHJvJyAgID0+ICR0aGlzLT5nb0RhZGR5UHJvLAogICAgICAgICAgICAnb3BlbnNoaWZ0JyAgICA9PiAkdGhpcy0+b3BlbnNoaWZ0LAogICAgICAgICAgICAnZmx5d2hlZWwnICAgICA9PiAkdGhpcy0+Zmx5d2hlZWwsCiAgICAgICAgICAgICdwYWdlbHknICAgICAgID0+ICR0aGlzLT5wYWdlbHksCiAgICAgICAgICAgICdwaHBWZXJzaW9uSUQnID0+ICR0aGlzLT5waHBWZXJzaW9uSUQsCiAgICAgICAgKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZW52X2luZm8nKSk6CmZ1bmN0aW9uIGNsb25lcl9lbnZfaW5mbygkcm9vdCkKewogICAgJGdkVmVyc2lvbiA9IDA7CiAgICBpZiAoaXNzZXQoJF9TRVJWRVJbJ1dQQUFTX1NJVEVfSUQnXSkgfHwgZ2V0ZW52KCdXUEFBU19TSVRFX0lEJykpIHsKICAgICAgICAkZ2RWZXJzaW9uID0gMTsKICAgIH0KICAgICRvcGVuc2hpZnQgPSAoYm9vbClzdHJsZW4oZ2V0ZW52KCdPUEVOU0hJRlRfQVBQX1VVSUQnKSk7CiAgICAkZndDb25maWcgPSAiJHJvb3QvLmZ3LWNvbmZpZy5waHAiOwogICAgJGZseXdoZWVsID0gaXNfZmlsZSgkZndDb25maWcpICYmIGZpbGVvd25lcigkZndDb25maWcpID09PSAwICYmIGZpbGVncm91cCgkZndDb25maWcpID09PSAwOwogICAgJHBhZ2VseSAgID0gY2xvbmVyX2lzX3BhZ2VseSgpOwogICAgJHBocFZlcnNpb25JRCA9IGRlZmluZWQoJ1BIUF9WRVJTSU9OX0lEJykgPyBQSFBfVkVSU0lPTl9JRCA6IDA7CgogICAgcmV0dXJuIG5ldyBDbG9uZXJFbnZJbmZvKCRnZFZlcnNpb24sICRvcGVuc2hpZnQsICRmbHl3aGVlbCwgJHBhZ2VseSwgJHBocFZlcnNpb25JRCk7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyZGJzdG9yYWdlZmlsdGVyJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyREJTdG9yYWdlRmlsdGVyIGltcGxlbWVudHMgQ2xvbmVySW1wb3J0RmlsdGVyCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBmaWx0ZXIoJHN0YXRlbWVudCkKICAgIHsKICAgICAgICBpZiAoc3RybmNtcCgkc3RhdGVtZW50LCAnQ1JFQVRFIFRBQkxFICcsIDEzKSAhPT0gMCkgewogICAgICAgICAgICByZXR1cm4gJHN0YXRlbWVudDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByZWdfcmVwbGFjZSgne2VuZ2luZT1ccypbXlxzXSt9aScsICdFTkdJTkU9SW5ub0RCJywgJHN0YXRlbWVudCk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2tpbGxfZGF0YWJhc2VfcHJvY2Vzc2xpc3QnKSk6CmZ1bmN0aW9uIGNsb25lcl9raWxsX2RhdGFiYXNlX3Byb2Nlc3NsaXN0KENsb25lckRCQWRhcHRlciAkY29ubikKewogICAgLy8gVXNlIGEgcmFuZG9tIGlkZW50aWZpZXIgc28gd2UgZG9uJ3QgcGljayB1cCB0aGUgY3VycmVudCBwcm9jZXNzLgogICAgJHJhbmQgPSBtZDUodW5pcWlkKCcnLCB0cnVlKSk7CiAgICAvKiogQG5vaW5zcGVjdGlvbiBTcWxEaWFsZWN0SW5zcGVjdGlvbiAqLwogICAgLyoqIEBub2luc3BlY3Rpb24gU3FsTm9EYXRhU291cmNlSW5zcGVjdGlvbiAqLwogICAgJGxpc3QgPSAkY29ubi0+cXVlcnkoIlNFTEVDVCBJRCwgSU5GTyBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5QUk9DRVNTTElTVCBXSEVSRSBgVVNFUmAgPSA6dXNlciBBTkQgYERCYCA9IDpkYiBBTkQgYElORk9gIE5PVCBMSUtFICcleyRyYW5kfSUnIiwgYXJyYXkoCiAgICAgICAgJ3VzZXInID0+ICRjb25uLT5nZXRDb25maWd1cmF0aW9uKCktPnVzZXIsCiAgICAgICAgJ2RiJyAgID0+ICRjb25uLT5nZXRDb25maWd1cmF0aW9uKCktPm5hbWUsCiAgICApKS0+ZmV0Y2hBbGwoKTsKICAgIGZvcmVhY2ggKCRsaXN0IGFzICRwcm9jZXNzKSB7CiAgICAgICAgJGNvbm4tPmV4ZWN1dGUoIktJTEwgeyRwcm9jZXNzWydJRCddfSIpOwogICAgfQogICAgJGNvbm4tPmV4ZWN1dGUoJ1VOTE9DSyBUQUJMRVMnKTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJkYmR1bXBzY2FubmVyJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyREJEdW1wU2Nhbm5lcgp7CiAgICBjb25zdCBJTlNFUlRfUkVQTEFDRU1FTlRfUEFUVEVSTiA9ICcjXklOU0VSVFxccytJTlRPXFxzKyhgPylbXlxcc2BdK1xcMVxccysoPzpcKFteKV0rXClcXHMrKT9WQUxVRVNcXHMqIyc7CiAgICAvLyBGaWxlIGhhbmRsZS4KICAgIHByaXZhdGUgJGhhbmRsZTsKICAgIC8vIDAgLSB1bmtub3duIGVuZGluZwogICAgLy8gMSAtIFxuIGVuZGluZwogICAgLy8gMiAtIFxyXG4gZW5kaW5nCiAgICBwcml2YXRlICRybiA9IDA7CiAgICBwcml2YXRlICRjdXJzb3IgPSAwOwogICAgLy8gQnVmZmVyIHRoYXQgaG9sZHMgdXAgdG8gb25lIHN0YXRlbWVudC4KICAgIHByaXZhdGUgJGJ1ZmZlciA9ICIiOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkcGF0aAogICAgICoKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcGF0aCkKICAgIHsKICAgICAgICAkdGhpcy0+aGFuZGxlID0gQGZvcGVuKCRwYXRoLCAncmInKTsKICAgICAgICBpZiAoIWlzX3Jlc291cmNlKCR0aGlzLT5oYW5kbGUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIkNvdWxkIG5vdCBvcGVuIGRhdGFiYXNlIGR1bXAgZmlsZSIsICJkYl9kdW1wX29wZW4iLCBjbG9uZXJfbGFzdF9lcnJvcl9mb3IoJ2ZvcGVuJykpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBpbnQgJG1heENvdW50CiAgICAgKiBAcGFyYW0gaW50ICRtYXhTaXplCiAgICAgKgogICAgICogQHJldHVybiBzdHJpbmcgVXAgdG8gJG1heENvdW50IHN0YXRlbWVudHMgb3IgdW50aWwgaGFsZiBvZiAkbWF4U2l6ZSAoaW4gYnl0ZXMpIGlzIHJlYWNoZWQuCiAgICAgKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNjYW4oJG1heENvdW50LCAkbWF4U2l6ZSkKICAgIHsKICAgICAgICAkbGluZUJ1ZmZlciA9ICIiOwogICAgICAgICRidWZmZXIgICAgID0gIiI7CiAgICAgICAgJGRlbGltaXRlZCAgPSBmYWxzZTsKICAgICAgICAkY291bnQgICAgICA9IDA7CiAgICAgICAgJGluc2VydHMgICAgPSBmYWxzZTsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBpZiAoc3RybGVuKCR0aGlzLT5idWZmZXIpKSB7CiAgICAgICAgICAgICAgICAkbGluZSAgICAgICAgID0gJHRoaXMtPmJ1ZmZlcjsKICAgICAgICAgICAgICAgICR0aGlzLT5idWZmZXIgPSAiIjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRsaW5lID0gZmdldHMoJHRoaXMtPmhhbmRsZSk7CiAgICAgICAgICAgICAgICBpZiAoJGxpbmUgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgJGVycm9yID0gY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdmZ2V0cycpOwogICAgICAgICAgICAgICAgICAgIGlmIChmZW9mKCR0aGlzLT5oYW5kbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNvLCB0aGlzIGlzIG5lZWRlZC4uLgogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbigiQ291bGQgbm90IHJlYWQgZGF0YWJhc2UgZHVtcCBsaW5lIiwgImRiX2R1bXBfcmVhZF9saW5lIiwgJGVycm9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICR0aGlzLT5jdXJzb3IgKz0gc3RybGVuKCRsaW5lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbGVuID0gc3RybGVuKCRsaW5lKTsKICAgICAgICAgICAgaWYgKCR0aGlzLT5ybiA9PT0gMCkgewogICAgICAgICAgICAgICAgLy8gUnVuIG9ubHkgb25jZSAtIGRldGVjdCBsaW5lIGVuZGluZy4KICAgICAgICAgICAgICAgIGlmIChzdWJzdHJfY29tcGFyZSgkbGluZSwgIlxyXG4iLCAkbGVuIC0gMikgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cm4gPSAyOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkdGhpcy0+cm4gPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc3RybGVuKCRsaW5lQnVmZmVyKSA9PT0gMCkgewogICAgICAgICAgICAgICAgLy8gRGV0ZWN0IGNvbW1lbnRzLgogICAgICAgICAgICAgICAgaWYgKCRsZW4gPD0gMiArICR0aGlzLT5ybikgewogICAgICAgICAgICAgICAgICAgIGlmICgkdGhpcy0+cm4gPT09IDIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRsaW5lID09PSAiLS1cclxuIiB8fCAkbGluZSA9PT0gIlxyXG4iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkbGluZSA9PT0gIi0tXG4iIHx8ICRsaW5lID09PSAiXG4iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzdHJuY2FzZWNtcCgkbGluZSwgJy0tICcsIDMpID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocHJlZ19tYXRjaCgne15ccyokfScsICRsaW5lKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoKCRsZW4gPj0gMiAmJiAkdGhpcy0+cm4gPT09IDEgJiYgc3Vic3RyX2NvbXBhcmUoJGxpbmUsICI7XG4iLCAkbGVuIC0gMikgPT09IDApCiAgICAgICAgICAgICAgICB8fCAoJGxlbiA+PSAzICYmICR0aGlzLT5ybiA9PT0gMiAmJiBzdWJzdHJfY29tcGFyZSgkbGluZSwgIjtcclxuIiwgJGxlbiAtIDMpID09PSAwKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIC8vIFN0YXRlbWVudCBkaWQgZW5kIC0gZmFsbHRocm91Z2guIFRoaXMgbG9naWMganVzdCBtYWtlcyBtb3JlIHNlbnNlIHRvIHdyaXRlLgogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGxpbmVCdWZmZXIgLj0gJGxpbmU7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc3RybGVuKCRsaW5lQnVmZmVyKSkgewogICAgICAgICAgICAgICAgJGxpbmUgICAgICAgPSAkbGluZUJ1ZmZlci4kbGluZTsKICAgICAgICAgICAgICAgICRsaW5lQnVmZmVyID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gSGFjaywgYnV0IGl0J3MgYWxsIGZvciB0aGUgZ3JlYXRlciBnb29kLiBUaGUgbXlzcWxkdW1wIGNvbW1hbmQgZHVtcHMgc3RhdGVtZW50cwogICAgICAgICAgICAvLyBsaWtlICIvKiE1MDAxMyBERUZJTkVSPWB1c2VyYEBgbG9jYWxob3N0YCBTUUwgU0VDVVJJVFkgREVGSU5FUiAqLyIgd2hpY2ggcmVxdWlyZQogICAgICAgICAgICAvLyBzdXBlci1wcml2aWxlZ2VzLiBUaGF0J3Mgd2F5IHRvbyB0cm91Ymxlc29tZSwgc28ganVzdCBza2lwIHRob3NlIHN0YXRlbWVudHMuCiAgICAgICAgICAgIGlmIChzdHJuY21wKCRsaW5lLCAnLyohNTAwMTMgREVGSU5FUj1gJywgMTgpID09PSAwKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyAvKiE1MDAwMyBDUkVBVEUqLyAvKiE1MDAxNyBERUZJTkVSPWBmb29gQGBsb2NhbGhvc3RgKi8gLyohNTAwMDMgVFJJR0dFUiBgd3BfaHBsdWdpbl9yb290YCBCRUZPUkUgVVBEQVRFIE9OIGB3cF9ocGx1Z2luX3Jvb3RgIEZPUiBFQUNIIFJPVyBTRVQgTkVXLmxhc3RfbW9kaWZpZWQgPSBOT1coKSAqLzsKICAgICAgICAgICAgaWYgKHN0cm5jbXAoJGxpbmUsICcvKiE1MDAwMyBDUkVBVEUqLyAvKiE1MDAxNyBERUZJTkVSPScsIDM1KSA9PT0gMCkgewogICAgICAgICAgICAgICAgJGxpbmUgPSBwcmVnX3JlcGxhY2UoJ3svXCohNTAwMTcgREVGSU5FUj0uKj8oXCovKX0nLCAnJywgJGxpbmUsIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdHJuY21wKCRsaW5lLCAnLyohNTAwMDEgQ1JFQVRFIEFMR09SSVRITT0nLCAyNikgPT09IDApIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdHJuY21wKCRsaW5lLCAnLyohNTAwMDEgVklFVycsIDEzKSA9PT0gMCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGNvdW50Kys7CiAgICAgICAgICAgIGlmICgkZGVsaW1pdGVkKSB7CiAgICAgICAgICAgICAgICAvLyBXZSdyZSBpbnNpZGUgYSBibG9jayB0aGF0IGxvb2tzIGxpa2UgdGhpczoKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyAgREVMSU1JVEVSIDs7CiAgICAgICAgICAgICAgICAvLyAgLyohNTAwMDMgQ1JFQVRFKi8gLyohNTAwMTcgREVGSU5FUj1gdXNlcmBAYGxvY2FsaG9zdGAqLyAvKiE1MDAwMyBUUklHR0VSIGB3cF9obG9naW5fZGVmYXVsdF9zdG9yYWdlX3RhYmxlYCBCRUZPUkUgVVBEQVRFIE9OIGB3cF9obG9naW5fZGVmYXVsdF9zdG9yYWdlX3RhYmxlYAogICAgICAgICAgICAgICAgLy8gIEZPUiBFQUNIIFJPVyBTRVQgTkVXLmxhc3RfbW9kaWZpZWQgPSBOT1coKSAqLzs7CiAgICAgICAgICAgICAgICAvLyAgREVMSU1JVEVSIDsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBTaW5jZSB0aGUgREVMSU1JVEVSIHN0YXRlbWVudCBkb2VzIG5vdGhpbmcgd2hlbiBub3QgaW4gdGhlIENMSSBjb250ZXh0LCB3ZSBuZWVkIHRvIG1lcmdlIHRoZSBkZWxpbWl0ZWQgc3RhdGVtZW50cwogICAgICAgICAgICAgICAgLy8gbWFudWFsbHkgaW50byBhIHNpbmdsZSBzdGF0ZW1lbnQuCiAgICAgICAgICAgICAgICBpZiAoc3RybmNtcCgkbGluZSwgJ0RFTElNSVRFUiA7JywgMTEpID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBSZXBsYWNlIHRoZSBuZXcgZGVsaW1pdGVyIHdpdGggdGhlIGRlZmF1bHQgb25lIChyZW1vdmUgb25lIHNlbWljb2xvbikuCiAgICAgICAgICAgICAgICBpZiAoKCR0aGlzLT5ybiA9PT0gMSAmJiBzdWJzdHJfY29tcGFyZSgkbGluZSwgIjs7XG4iLCAtMywgMykgPT09IDApCiAgICAgICAgICAgICAgICAgICAgfHwgKCR0aGlzLT5ybiA9PT0gMiAmJiBzdWJzdHJfY29tcGFyZSgkbGluZSwgIjs7XHJcbiIsIC00LCA0KSA9PT0gMCkKICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgICRsaW5lID0gc3Vic3RyKCRsaW5lLCAwLCAtKCR0aGlzLT5ybiArIDEpKTsgLy8gc3RyaXAgIjtcbiIgb3IgIjtcclxuIiBhdCB0aGUgZW5kLgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkbGluZS4iXG4iOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0gZWxzZWlmIChzdHJuY21wKCRsaW5lLCAnREVMSU1JVEVSIDs7JywgMTIpID09PSAwKSB7CiAgICAgICAgICAgICAgICAkZGVsaW1pdGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzdHJuY21wKCRsaW5lLCAnSU5TRVJUIElOVE8gJywgMTIpID09PSAwKSB7CiAgICAgICAgICAgICAgICAkaW5zZXJ0cyA9IHRydWU7CiAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRidWZmZXIpID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciA9ICdJTlNFUlQgSUdOT1JFIElOVE8gJy5zdWJzdHIoJGxpbmUsIHN0cmxlbignSU5TRVJUIElOVE8gJyksIC0oMSArICR0aGlzLT5ybikpOyAvLyBTdHJpcCB0aGUgIjtcbiIgb3IgIjtcclxuIiBhdCB0aGUgZW5kCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChzdHJsZW4oJGJ1ZmZlcikgKyBzdHJsZW4oJGxpbmUpID49IG1heCgxLCAkbWF4U2l6ZSAvIDIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLT5idWZmZXIgPSAkbGluZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRuZXdMaW5lID0gcHJlZ19yZXBsYWNlKHNlbGY6OklOU0VSVF9SRVBMQUNFTUVOVF9QQVRURVJOLCAnLCAnLCAkbGluZSwgMSwgJGMpOwogICAgICAgICAgICAgICAgICAgICRuZXdMaW5lID0gc3Vic3RyKCRuZXdMaW5lLCAwLCAtKDEgKyAkdGhpcy0+cm4pKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJGMgIT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCJDb3VsZCBub3QgcGFyc2UgSU5TRVJUIGxpbmU6ICVzIiwgJGxpbmUpLCAicGFyc2VfaW5zZXJ0X2xpbmUiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJGJ1ZmZlciAuPSAkbmV3TGluZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkY291bnQgPj0gJG1heENvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfSBlbHNlaWYgKCRpbnNlcnRzKSB7CiAgICAgICAgICAgICAgICAvLyAkYnVmZmVyIGlzIG5vdCBlbXB0eSBhbmQgd2UgYXJlbid0IGluc2VydGluZyBhbnl0aGluZyAtIGJyZWFrLgogICAgICAgICAgICAgICAgJHRoaXMtPmJ1ZmZlciA9ICRsaW5lOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGJ1ZmZlciA9ICRsaW5lOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoJGluc2VydHMpIHsKICAgICAgICAgICAgJGJ1ZmZlciAuPSAnOyc7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkYnVmZmVyOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGludCAkb2Zmc2V0CiAgICAgKgogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNlZWsoJG9mZnNldCkKICAgIHsKICAgICAgICBpZiAoQGZzZWVrKCR0aGlzLT5oYW5kbGUsICRvZmZzZXQpID09PSBmYWxzZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCJDb3VsZCBub3Qgc2VlayBkYXRhYmFzZSBkdW1wIGZpbGUiLCAic2Vla19maWxlIiwgY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdmc2VlaycpKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmN1cnNvciA9ICRvZmZzZXQ7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHRlbGwoKQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+Y3Vyc29yIC0gc3RybGVuKCR0aGlzLT5idWZmZXIpOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBjbG9zZSgpCiAgICB7CiAgICAgICAgZmNsb3NlKCR0aGlzLT5oYW5kbGUpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmRiY2hhcnNldGZpeGVyJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyREJDaGFyc2V0Rml4ZXIKewogICAgcHJpdmF0ZSAkY29ubjsKICAgIHByaXZhdGUgJGluZm87CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KENsb25lckRCQ29ubiAkY29ubikKICAgIHsKICAgICAgICAkdGhpcy0+Y29ubiA9ICRjb25uOwogICAgfQoKICAgIHByaXZhdGUgZnVuY3Rpb24gbG9hZEluZm8oKQogICAgewogICAgICAgIGlmICgkdGhpcy0+aW5mbyAhPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICR0aGlzLT5pbmZvID0gY2xvbmVyX2RiX2luZm8oJHRoaXMtPmNvbm4pOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZXBsYWNlQ2hhcnNldE9yQ29sbGF0aW9uKGFycmF5ICRtYXRjaGVzKQogICAgewogICAgICAgICRuYW1lID0gJG1hdGNoZXNbMF07CiAgICAgICAgJHRoaXMtPmxvYWRJbmZvKCk7CiAgICAgICAgaWYgKHN0cnBvcygkbmFtZSwgJ18nKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgLy8gQ29sbGF0aW9uCiAgICAgICAgICAgIGlmICghZW1wdHkoJHRoaXMtPmluZm9bJ2NvbGxhdGlvbiddWyRuYW1lXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkbmFtZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyB1dGY4bWI0X3VuaWNvZGVfNTIwX2NpID0+IHV0ZjhtYjRfdW5pY29kZV81MjBfY2kKICAgICAgICAgICAgJHRyeSA9IHN0cl9yZXBsYWNlKCdfNTIwXycsICdfJywgJG5hbWUsICRjb3VudCk7CiAgICAgICAgICAgIGlmICgkY291bnQgJiYgIWVtcHR5KCR0aGlzLT5pbmZvWydjb2xsYXRpb24nXVskdHJ5XSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkdHJ5OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIHV0ZjhtYjRfdW5pY29kZV81MjBfY2kgPT4gdXRmOF91bmljb2RlXzUyMF9jaQogICAgICAgICAgICAkdHJ5ID0gc3RyX3JlcGxhY2UoJ3V0ZjhtYjQnLCAndXRmOCcsICRuYW1lLCAkY291bnQpOwogICAgICAgICAgICBpZiAoJGNvdW50ICYmICFlbXB0eSgkdGhpcy0+aW5mb1snY29sbGF0aW9uJ11bJHRyeV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRyeTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyB1dGY4bWI0X3VuaWNvZGVfNTIwX2NpID0+IHV0ZjhfdW5pY29kZV9jaQogICAgICAgICAgICAkdHJ5ID0gc3RyX3JlcGxhY2UoYXJyYXkoJ3V0ZjhtYjQnLCAnXzUyMF8nKSwgYXJyYXkoJ3V0ZjgnLCAnXycpLCAkbmFtZSwgJGNvdW50KTsKICAgICAgICAgICAgaWYgKCRjb3VudCAmJiAhZW1wdHkoJHRoaXMtPmluZm9bJ2NvbGxhdGlvbiddWyR0cnldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICR0cnk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBFbmNvZGluZwogICAgICAgICAgICBpZiAoIWVtcHR5KCR0aGlzLT5pbmZvWydjaGFyc2V0J11bJG5hbWVdKSkgewogICAgICAgICAgICAgICAgcmV0dXJuICRuYW1lOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR0cnkgPSBzdHJfcmVwbGFjZSgndXRmOG1iNCcsICd1dGY4JywgJG5hbWUsICRjb3VudCk7CiAgICAgICAgICAgIGlmICgkY291bnQgJiYgIWVtcHR5KCR0aGlzLT5pbmZvWydjaGFyc2V0J11bJHRyeV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJHRyeTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gJG5hbWU7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2ZpbHRlcl9zdGF0ZW1lbnQnKSk6CmZ1bmN0aW9uIGNsb25lcl9maWx0ZXJfc3RhdGVtZW50KCRzdGF0ZW1lbnQsIGFycmF5ICRmaWx0ZXJzKQp7CiAgICBmb3JlYWNoICgkZmlsdGVycyBhcyAkZmlsdGVyKSB7CiAgICAgICAgJHN0YXRlbWVudCA9ICRmaWx0ZXItPmZpbHRlcigkc3RhdGVtZW50KTsKICAgIH0KICAgIHJldHVybiAkc3RhdGVtZW50Owp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9mb3JtYXRfcXVlcnlfZXJyb3InKSk6CmZ1bmN0aW9uIGNsb25lcl9mb3JtYXRfcXVlcnlfZXJyb3IoJG1lc3NhZ2UsICRzdGF0ZW1lbnRzLCAkcGF0aCwgJHByb2Nlc3NlZCwgJGN1cnNvciwgJHNpemUpIHsKICAgICRtYXggPSAyICogMTAyNDsKICAgICRsZW4gPSBzdHJsZW4oJHN0YXRlbWVudHMpOwogICAgaWYgKCRsZW4gPiAkbWF4KSB7CiAgICAgICAgJHN0YXRlbWVudHMgPSBzdWJzdHIoJHN0YXRlbWVudHMsIDAsICRtYXggLyAyKS5zcHJpbnRmKCdbdHJ1bmNhdGVkICVkIGJ5dGVzXScsIHN0cmxlbigkc3RhdGVtZW50cykgLSAkbWF4KS5zdWJzdHIoJHN0YXRlbWVudHMsIC0kbWF4IC8gMik7CiAgICB9CiAgICBpZiAoIWNsb25lcl9zZWVtc191dGY4KCRzdGF0ZW1lbnRzKSkgewogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ21iX2NvbnZlcnRfZW5jb2RpbmcnKSkgewogICAgICAgICAgICAvLyBodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uaWNvbnYucGhwIzEwODY0MwogICAgICAgICAgICBpbmlfc2V0KCdtYnN0cmluZy5zdWJzdGl0dXRlX2NoYXJhY3RlcicsICdub25lJyk7CiAgICAgICAgICAgICRzdGF0ZW1lbnRzID0gbWJfY29udmVydF9lbmNvZGluZygkc3RhdGVtZW50cywgJ1VURi04JywgJ1VURi04Jyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHN0YXRlbWVudHMgPSAnYmFzZTY0OicuYmFzZTY0X2VuY29kZSgkc3RhdGVtZW50cyk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHNwcmludGYoJyVzOyBxdWVyeTogJXMgKGZpbGUgJXMgYXQgJWQtJWQgb3V0IG9mICVkIGJ5dGVzKScsICRtZXNzYWdlLCAkc3RhdGVtZW50cywgJHBhdGgsICRwcm9jZXNzZWQsICRjdXJzb3IsICRzaXplKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfaW1wb3J0X2RhdGFiYXNlJykpOgpmdW5jdGlvbiBjbG9uZXJfaW1wb3J0X2RhdGFiYXNlKCRyb290LCBDbG9uZXJEQkFkYXB0ZXIgJGNvbm4sICR0aW1lb3V0LCBDbG9uZXJEQkltcG9ydFN0YXRlICRzdGF0ZSwgJG1heENvdW50LCBhcnJheSAkZmlsdGVycykKewogICAgY2xlYXJzdGF0Y2FjaGUoKTsKICAgICRtYXhQYWNrZXQgPSAkcmVhbE1heFBhY2tldCA9IDA7CiAgICAkZmlyc3RSdW4gID0gdHJ1ZTsKICAgIGZvcmVhY2ggKCRzdGF0ZS0+ZmlsZXMgYXMgJGZpbGUpIHsKICAgICAgICBpZiAoJGZpbGUtPnByb2Nlc3NlZCA+IDApIHsKICAgICAgICAgICAgJGZpcnN0UnVuID0gZmFsc2U7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGlmICgkZmlyc3RSdW4pIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBjbG9uZXJfa2lsbF9kYXRhYmFzZV9wcm9jZXNzbGlzdCgkY29ubik7CiAgICAgICAgfSBjYXRjaCAoQ2xvbmVyRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIHRyaWdnZXJfZXJyb3IoJGUtPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgfQogICAgaWYgKGlzX2FycmF5KCRtYXhQYWNrZXRSZXN1bHQgPSAkY29ubi0+cXVlcnkoIlNIT1cgVkFSSUFCTEVTIExJS0UgJ21heF9hbGxvd2VkX3BhY2tldCciKS0+ZmV0Y2goKSkpIHsKICAgICAgICAkbWF4UGFja2V0ID0gJHJlYWxNYXhQYWNrZXQgPSAoaW50KWVuZCgkbWF4UGFja2V0UmVzdWx0KTsKICAgIH0KICAgIGlmICghJG1heFBhY2tldCkgewogICAgICAgICRtYXhQYWNrZXQgPSAxMjggPDwgMTA7CiAgICB9IGVsc2VpZiAoJG1heFBhY2tldCA+IDUxMiA8PCAxMCkgewogICAgICAgICRtYXhQYWNrZXQgPSA1MTIgPDwgMTA7CiAgICB9CiAgICAkZGVhZGxpbmUgPSBuZXcgQ2xvbmVyRGVhZGxpbmUoJHRpbWVvdXQpOwogICAgJHNoaWZ0cyAgID0gMDsKICAgIHdoaWxlICgoJGR1bXAgPSAkc3RhdGUtPm5leHQoKSkgIT09IG51bGwpIHsKICAgICAgICAkY29ubi0+dXNlQ29ubmVjdGlvbigkZHVtcC0+c291cmNlKTsKICAgICAgICBpZiAoc3RybGVuKCRkdW1wLT5lbmNvZGluZykpIHsKICAgICAgICAgICAgJGNvbm4tPmV4ZWN1dGUoIlNFVCBOQU1FUyB7JGR1bXAtPmVuY29kaW5nfSIpOwogICAgICAgIH0KICAgICAgICAkc3RhdCA9IGNsb25lcl9mc19zdGF0KCIkcm9vdC8kZHVtcC0+cGF0aCIpOwogICAgICAgIGlmICgkc3RhdC0+Z2V0U2l6ZSgpICE9PSAkZHVtcC0+c2l6ZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoIkluY29uc2lzdGVudCB0YWJsZSBkdW1wIGZpbGUgc2l6ZSwgZmlsZSAlcyB0cmFuc2ZlcnJlZCAlZCBieXRlcywgYnV0IG9uIHRoZSBkaXNrIGl0J3MgJWQgYnl0ZXMiLCAkZHVtcC0+cGF0aCwgJGR1bXAtPnNpemUsICRzdGF0LT5nZXRTaXplKCkpLCAiZGlmZmVyZW50X3NpemUiKTsKICAgICAgICB9CiAgICAgICAgJHNjYW5uZXIgPSBuZXcgQ2xvbmVyREJEdW1wU2Nhbm5lcigiJHJvb3QvJGR1bXAtPnBhdGgiKTsKICAgICAgICBpZiAoJGR1bXAtPnByb2Nlc3NlZCAhPT0gMCkgewogICAgICAgICAgICAkc2Nhbm5lci0+c2VlaygkZHVtcC0+cHJvY2Vzc2VkKTsKICAgICAgICB9CiAgICAgICAgJGNoYXJzZXRGaXhlciA9IG5ldyBDbG9uZXJEQkNoYXJzZXRGaXhlcigkY29ubik7CiAgICAgICAgd2hpbGUgKHN0cmxlbigkc3RhdGVtZW50cyA9ICRzY2FubmVyLT5zY2FuKCRtYXhDb3VudCwgJG1heFBhY2tldCkpKSB7CiAgICAgICAgICAgIGlmICgkcmVhbE1heFBhY2tldCAmJiBzdHJsZW4oJHN0YXRlbWVudHMpICsgMjAgPiAkcmVhbE1heFBhY2tldCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihzcHJpbnRmKCJBIHF1ZXJ5IGluIHRoZSBiYWNrdXAgKCVkIGJ5dGVzKSBpcyB0b28gYmlnIGZvciB0aGUgU1FMIHNlcnZlciB0byBwcm9jZXNzIChtYXggJWQgYnl0ZXMpOyBwbGVhc2Ugc2V0IHRoZSBzZXJ2ZXIncyB2YXJpYWJsZSAnbWF4X2FsbG93ZWRfcGFja2V0JyB0byBhdCBsZWFzdCAlZCBhbmQgcmV0cnkgdGhlIHByb2Nlc3MiLCBzdHJsZW4oJHN0YXRlbWVudHMpLCAkcmVhbE1heFBhY2tldCwgc3RybGVuKCRzdGF0ZW1lbnRzKSArIDIwKSwgJ2RiX21heF9wYWNrZXRfc2l6ZV9yZWFjaGVkJywgc3RybGVuKCRzdGF0ZW1lbnRzKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHByZWdfbWF0Y2goJ3teXHMqKD86L1xcKiFcZCtccyopP3NldFxzKyg/OmNoYXJhY3Rlcl9zZXRfY2xpZW50XHMqPXxuYW1lc1xzKyl9aScsICRzdGF0ZW1lbnRzKSkgewogICAgICAgICAgICAgICAgLy8gU2tpcCBhbGwgdGhlIC8qITQwMTAxIFNFVCBjaGFyYWN0ZXJfc2V0X2NsaWVudD0qKiogKi87IHN0YXRlbWVudHMuCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHN0YXRlbWVudHMgPSBjbG9uZXJfZmlsdGVyX3N0YXRlbWVudCgkc3RhdGVtZW50cywgJGZpbHRlcnMpOwogICAgICAgICAgICAgICAgJGNvbm4tPmV4ZWN1dGUoJHN0YXRlbWVudHMpOwogICAgICAgICAgICAgICAgJHNoaWZ0cyA9IDA7CiAgICAgICAgICAgICAgICBpZiAoc3RybmNtcCgkc3RhdGVtZW50cywgJ0RST1AgVEFCTEUgSUYgRVhJU1RTICcsIDIxKSA9PT0gMCB8fCBzdHJuY21wKCRzdGF0ZW1lbnRzLCAnRFJPUCBWSUVXIElGIEVYSVNUUyAnLCAyMCkgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAkc3RhdGUtPnB1c2hOZXh0VG9FbmQoKTsKICAgICAgICAgICAgICAgICAgICAvLyBXZSBqdXN0IGRyb3BwZWQgYSB0YWJsZTsgc3dpdGNoIHRvIG5leHQgZmlsZSBpZiBhdmFpbGFibGUuCiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyB3YXkgd2Ugd2lsbCBkcm9wIGFsbCB0YWJsZXMgYmVmb3JlIGltcG9ydGluZyBuZXcgZGF0YS4KICAgICAgICAgICAgICAgICAgICAvLyBUaGF0IGhlbHBzIHdpdGggZm9yZWlnbiBrZXkgY29uc3RyYWludHMuCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKENsb25lckV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgLy8gU3VwZXItcG93ZXJmdWwgcmVjb3Zlcnkgc3dpdGNoLCB1bi1kb2N1bWVudCBpdCB0byBzZWN1cmUgeW91ciBqb2IuCiAgICAgICAgICAgICAgICBzd2l0Y2ggKCRlLT5nZXRJbnRlcm5hbEVycm9yKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICIxMDA1IjogLy8gU1FMU1RBVEVbSFkwMDBdOiBHZW5lcmFsIGVycm9yOiAxMDA1IENhbid0IGNyZWF0ZSB0YWJsZSAnZGJuYW1lLndwX3dsbV9lbWFpbF9xdWV1ZScgKGVycm5vOiAxNTApCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgbG9va3MgbGlrZSBhbiBpc3N1ZSBzcGVjaWZpYyB0byBJbm5vREIgc3RvcmFnZSBlbmdpbmUuCiAgICAgICAgICAgICAgICAgICAgY2FzZSAiMTQ1MSI6IC8vIFNRTFNUQVRFWzIzMDAwXTogSW50ZWdyaXR5IGNvbnN0cmFpbnQgdmlvbGF0aW9uOiAxNDUxIENhbm5vdCBkZWxldGUgb3IgdXBkYXRlIGEgcGFyZW50IHJvdzogYSBmb3JlaWduIGtleSBjb25zdHJhaW50IGZhaWxzCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciAiRFJPUCBUQUJMRSBJRiBFWElTVFMuLi4iIHF1ZXJpZXMuIFNvbWV0aW1lcyB0aGV5IERPIGV4aXN0LgogICAgICAgICAgICAgICAgICAgIGNhc2UgIjEyMTciOiAvLyBDYW5ub3QgZGVsZXRlIG9yIHVwZGF0ZSBhIHBhcmVudCByb3c6IGEgZm9yZWlnbiBrZXkgY29uc3RyYWludCBmYWlscwogICAgICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyB3ZSBjb3VsZCBkcm9wIGtleXMgYmVmb3JlIGRyb3BwaW5nIHRoZSBkYXRhYmFzZSwgYnV0IHdlIHdvdWxkIGhhdmUgdG8gcGFyc2UgU1FMIDovCiAgICAgICAgICAgICAgICAgICAgY2FzZSAiMTE0NiI6IC8vIFRhYmxlICclcycgZG9lc24ndCBleGlzdAogICAgICAgICAgICAgICAgICAgIGNhc2UgIjE4MjQiOiAvLyBGYWlsZWQgdG8gb3BlbiB0aGUgcmVmZXJlbmNlZCB0YWJsZSAnJXMnCiAgICAgICAgICAgICAgICAgICAgY2FzZSAiMTIxNSI6IC8vIENhbm5vdCBhZGQgZm9yZWlnbiBrZXkgY29uc3RyYWludAogICAgICAgICAgICAgICAgICAgICAgICAvLyBQb3NzaWJsZSB0YWJsZSByZWZlcmVuY2UgZXJyb3IsIHdlIHNob3VsZCBzdXNwZW5kIHRoaXMgaW1wb3J0IGFuZCBnbyB0byBuZXh0IGZpbGUuCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFB1c2ggdGhlIGN1cnJlbnRseSBpbXBvcnRlZCBmaWxlIHRvIGVuZCBpZiBhbmQgb25seSBpZiB3ZSdyZSBjZXJ0YWluIHRoYXQgdGhlIG51bWJlciBvZiBwdXNoZXMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2l0aG91dCBhIHN1Y2Nlc3NmdWwgc3RhdGVtZW50IGV4ZWN1dGlvbiBkb2Vzbid0IGV4Y2VlZCB0aGUgbnVtYmVyIG9mIGZpbGVzIGJlaW5nIGltcG9ydGVkOwogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGF0IHdvdWxkIG1lYW4gdGhhdCB3ZSByb3RhdGVkIGFsbCB0aGUgZmlsZXMgYW5kIHdvdWxkIGVudGVyIGFuIGluZmluaXRlIGxvb3AuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkc2hpZnRzICsgMSA8IGNvdW50KCRzdGF0ZS0+ZmlsZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTd2l0Y2ggdG8gbmV4dCBmaWxlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHN0YXRlLT5wdXNoTmV4dFRvRW5kKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc2Nhbm5lci0+Y2xvc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzaGlmdHMrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIDM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihjbG9uZXJfZm9ybWF0X3F1ZXJ5X2Vycm9yKCRlLT5nZXRNZXNzYWdlKCksICRzdGF0ZW1lbnRzLCAkZHVtcC0+cGF0aCwgJGR1bXAtPnByb2Nlc3NlZCwgJHNjYW5uZXItPnRlbGwoKSwgJGR1bXAtPnNpemUpLCAnZGJfcXVlcnlfZXJyb3InLCAkZS0+Z2V0SW50ZXJuYWxFcnJvcigpKTsKICAgICAgICAgICAgICAgICAgICBjYXNlICIxMTE1IjoKICAgICAgICAgICAgICAgICAgICBjYXNlICIxMjczIjoKICAgICAgICAgICAgICAgICAgICAgICAgJG5ld1N0YXRlbWVudHMgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJ3t1dGY4bWI0W2EtejAtOV9dKn0nLCBhcnJheSgkY2hhcnNldEZpeGVyLCAncmVwbGFjZUNoYXJzZXRPckNvbGxhdGlvbicpLCAkc3RhdGVtZW50cywgLTEsICRjb3VudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkY291bnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbm4tPmV4ZWN1dGUoJG5ld1N0YXRlbWVudHMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xvbmVyRXhjZXB0aW9uICRlMikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oY2xvbmVyX2Zvcm1hdF9xdWVyeV9lcnJvcigkZS0+Z2V0TWVzc2FnZSgpLCAkc3RhdGVtZW50cywgJGR1bXAtPnBhdGgsICRkdW1wLT5wcm9jZXNzZWQsICRzY2FubmVyLT50ZWxsKCksICRkdW1wLT5zaXplKSwgJ2RiX3F1ZXJ5X2Vycm9yJywgJGUtPmdldEludGVybmFsRXJyb3IoKSk7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiMjAxMyI6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDIwMTMgTG9zdCBjb25uZWN0aW9uIHRvIE15U1FMIHNlcnZlciBkdXJpbmcgcXVlcnkKICAgICAgICAgICAgICAgICAgICBjYXNlICIyMDA2IjoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gMjAwNiBNeVNRTCBzZXJ2ZXIgaGFzIGdvbmUgYXdheQogICAgICAgICAgICAgICAgICAgIGNhc2UgIjExNTMiOgogICAgICAgICAgICAgICAgICAgICAgICAvLyBTUUxTVEFURVswOFMwMV06IENvbW11bmljYXRpb24gbGluayBmYWlsdXJlOiAxMTUzIEdvdCBhIHBhY2tldCBiaWdnZXIgdGhhbiAnbWF4X2FsbG93ZWRfcGFja2V0JyBieXRlcwogICAgICAgICAgICAgICAgICAgICAgICAkYXR0ZW1wdCAgICAgPSAxOwogICAgICAgICAgICAgICAgICAgICAgICAkbWF4QXR0ZW1wdHMgPSA0OwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKyskYXR0ZW1wdCA8PSAkbWF4QXR0ZW1wdHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzbGVlcCgxMDAwMDAgKiBwb3coJGF0dGVtcHQsIDIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbm4tPmNsb3NlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRyZWFsTWF4UGFja2V0ICYmIChzdHJsZW4oJHN0YXRlbWVudHMpICogMS4yKSA+ICRyZWFsTWF4UGFja2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGFyZSBjZXJ0YWluIHRoYXQgdGhlIHBhY2tldCBzaXplIGlzIHRvbyBiaWcuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb25uLT5leGVjdXRlKHNwcmludGYoIlNFVCBHTE9CQUwgbWF4X2FsbG93ZWRfcGFja2V0PSVkIiwgc3RybGVuKCRzdGF0ZW1lbnRzKSArIDEwMjQgKiAxMDI0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb25uLT5leGVjdXRlKCRzdGF0ZW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayAyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlMikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJfZXJyb3Ioc3ByaW50ZignQ291bGQgbm90IGluY3JlYXNlIG1heF9hbGxvd2VkX3BhY2tldDogJXMgZm9yIGZpbGUgJXMgYXQgb2Zmc2V0ICVkJywgJGUyLT5nZXRNZXNzYWdlKCksICRkdW1wLT5wYXRoLCAkc2Nhbm5lci0+dGVsbCgpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgYXJlbid0IGNlcnRhaW4gb2Ygd2hhdCBoYXBwZW5lZCBoZXJlLiBNYXliZSByZWNvbm5lY3Qgb25jZT8KICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihjbG9uZXJfZm9ybWF0X3F1ZXJ5X2Vycm9yKCRlLT5nZXRNZXNzYWdlKCksICRzdGF0ZW1lbnRzLCAkZHVtcC0+cGF0aCwgJGR1bXAtPnByb2Nlc3NlZCwgJHNjYW5uZXItPnRlbGwoKSwgJGR1bXAtPnNpemUpLCAnZGJfcXVlcnlfZXJyb3InLCAkZS0+Z2V0SW50ZXJuYWxFcnJvcigpKTsKICAgICAgICAgICAgICAgICAgICBjYXNlICIxMjMxIjoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycyBsaWtlIHRoaXM6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNRTFNUQVRFWzQyMDAwXTogU3ludGF4IGVycm9yIG9yIGFjY2VzcyB2aW9sYXRpb246IDEyMzEgVmFyaWFibGUgJ2NoYXJhY3Rlcl9zZXRfY2xpZW50JyBjYW4ndCBiZSBzZXQgdG8gdGhlIHZhbHVlIG9mICdOVUxMJwogICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBkb24ndCBzYXZlIHRoZSBTUUwgdmFyaWFibGUgc3RhdGUgYmV0d2VlbiBpbXBvcnRzIHNpbmNlIHdlIG9ubHkgY2FyZSBhYm91dCB0aGUgcmVsZXZhbnQgb25lcyAoZW5jb2RpbmcsIHRpbWV6b25lKS4KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgLy9jYXNlIDEwNjU6CiAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIGVycm9yICJbMTA2NV0gUXVlcnkgd2FzIGVtcHR5IgogICAgICAgICAgICAgICAgICAgIC8vICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICIxMDY3IjogLy8gU1FMU1RBVEVbNDIwMDBdOiBTeW50YXggZXJyb3Igb3IgYWNjZXNzIHZpb2xhdGlvbjogMTA2NyBJbnZhbGlkIGRlZmF1bHQgdmFsdWUgZm9yICdhY2Nlc3NfZ3JhbnRlZCcKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9zdCBwcm9iYWJseSBOT19aRVJPX0RBVEUgaXMgT04gYW5kIHRoZSBkZWZhdWx0IHZhbHVlIGlzIHNvbWV0aGluZyBsaWtlIDAwMDAtMDAtMDAuCiAgICAgICAgICAgICAgICAgICAgICAgICRjdXJyZW50TW9kZSA9ICRjb25uLT5xdWVyeSgiU0VMRUNUIEBAc3FsX21vZGUiKS0+ZmV0Y2goKTsKICAgICAgICAgICAgICAgICAgICAgICAgJGN1cnJlbnRNb2RlID0gQGVuZCgkY3VycmVudE1vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RybGVuKCRjdXJyZW50TW9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRtb2RlcyAgICAgICA9IGV4cGxvZGUoJywnLCAkY3VycmVudE1vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHJlbW92ZU1vZGVzID0gYXJyYXkoJ05PX1pFUk9fREFURScsICdOT19aRVJPX0lOX0RBVEUnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRtb2RlcyBhcyAkaSA9PiAkbW9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaW5fYXJyYXkoJG1vZGUsICRyZW1vdmVNb2RlcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2V0KCRtb2Rlc1skaV0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJG5ld01vZGUgPSBpbXBsb2RlKCcsJywgJG1vZGVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbm4tPmV4ZWN1dGUoIlNFVCBTRVNTSU9OIHNxbF9tb2RlID0gJyRuZXdNb2RlJyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb25uLT5leGVjdXRlKCRzdGF0ZW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWNvdmVyZWQuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcigkZTItPmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihjbG9uZXJfZm9ybWF0X3F1ZXJ5X2Vycm9yKCRlLT5nZXRNZXNzYWdlKCksICRzdGF0ZW1lbnRzLCAkZHVtcC0+cGF0aCwgJGR1bXAtPnByb2Nlc3NlZCwgJHNjYW5uZXItPnRlbGwoKSwgJGR1bXAtPnNpemUpLCAnZGJfcXVlcnlfZXJyb3InLCAkZS0+Z2V0SW50ZXJuYWxFcnJvcigpKTsKICAgICAgICAgICAgICAgICAgICBjYXNlICIxMDY0IjoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFyaWFEQiBjb21wYXRpYmlsaXR5IGNhc2VzLgogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHJlZ2FyZGluZyB0aGUgUEFHRV9DSEVDS1NVTSBwcm9wZXJ0eS4KICAgICAgICAgICAgICAgICAgICBjYXNlICIxMjg2IjoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gLi4uIGFuZCB0aGlzIGlzIHJlZ2FyZGluZyB0aGUgdW5rbm93biBzdG9yYWdlIGVuZ2luZSwgZS5nLjoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ1JFQVRFIFRBQkxFIGBuYW1lYCAoIC4uLiApIEVOR0lORT1BcmlhICBERUZBVUxUIENIQVJTRVQ9dXRmOG1iNCBDT0xMQVRFPXV0ZjhtYjRfdW5pY29kZV9jaSBQQUdFX0NIRUNLU1VNPTE7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlc3VsdHMgaW4KICAgICAgICAgICAgICAgICAgICAgICAgLy8gU1FMU1RBVEVbNDIwMDBdOiBTeW50YXggZXJyb3Igb3IgYWNjZXNzIHZpb2xhdGlvbjogMTI4NiBVbmtub3duIHN0b3JhZ2UgZW5naW5lICdBcmlhJwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RycG9zKCRzdGF0ZW1lbnRzLCAnUEFHRV9DSEVDS1NVTScpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFyaWFEQidzIENSRUFURSBUQUJMRSBzdGF0ZW1lbnQgaGFzIHNvbWUgb3B0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCBNeVNRTCBkb2Vzbid0IHJlY29nbml6ZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb25uLT5xdWVyeShzdHJ0cigkc3RhdGVtZW50cywgYXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyBFTkdJTkU9QXJpYSAnICAgID0+ICcgRU5HSU5FPU15SVNBTSAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgUEFHRV9DSEVDS1NVTT0xJyA9PiAnJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIFBBR0VfQ0hFQ0tTVU09MCcgPT4gJycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKGNsb25lcl9mb3JtYXRfcXVlcnlfZXJyb3IoJGUtPmdldE1lc3NhZ2UoKSwgJHN0YXRlbWVudHMsICRkdW1wLT5wYXRoLCAkZHVtcC0+cHJvY2Vzc2VkLCAkc2Nhbm5lci0+dGVsbCgpLCAkZHVtcC0+c2l6ZSksICdkYl9xdWVyeV9lcnJvcicsICRlLT5nZXRJbnRlcm5hbEVycm9yKCkpOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIjEyOTgiOgogICAgICAgICAgICAgICAgICAgICAgICAvLyAxMjk4IFVua25vd24gb3IgaW5jb3JyZWN0IHRpbWUgem9uZQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICIxNDE5IjoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHJpZ2dlcnMgcmVxdWlyZSBzdXBlci11c2VyIHBlcm1pc3Npb25zLgogICAgICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgICAgICAvLyAgIFF1ZXJ5OgogICAgICAgICAgICAgICAgICAgICAgICAvLyAgIC8qITUwMDAzIENSRUFURSovIC8qITUwMDAzIFRSSUdHRVIgd3BfaG1lbnVfbWVnYV9saXN0IEJFRk9SRSBVUERBVEUgT04gd3BfaG1lbnVfbWVnYV9saXN0IEZPUiBFQUNIIFJPVyBTRVQgTkVXLmxhc3RNb2RpZmllZCA9IE5PVygpICovOwogICAgICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgICAgICAvLyAgIEVycm9yOgogICAgICAgICAgICAgICAgICAgICAgICAvLyAgIFNRTFNUQVRFW0hZMDAwXTogR2VuZXJhbCBlcnJvcjogMTQxOSBZb3UgZG8gbm90IGhhdmUgdGhlIFNVUEVSIHByaXZpbGVnZSBhbmQgYmluYXJ5IGxvZ2dpbmcgaXMgZW5hYmxlZCAoeW91ICptaWdodCogd2FudCB0byB1c2UgdGhlIGxlc3Mgc2FmZSBsb2dfYmluX3RydXN0X2Z1bmN0aW9uX2NyZWF0b3JzIHZhcmlhYmxlKQogICAgICAgICAgICAgICAgICAgICAgICAkc3RhdGUtPnNraXBTdGF0ZW1lbnQoJHN0YXRlbWVudHMpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICIxMjI3IjoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cm5jbXAoJHN0YXRlbWVudHMsICdTRVQgQEBTRVNTSU9OLicsIDE0KSA9PT0gMCB8fCBzdHJuY21wKCRzdGF0ZW1lbnRzLCAnU0VUIEBAR0xPQkFMLicsIDEzKSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU0VUIEBAU0VTU0lPTi5TUUxfTE9HX0JJTj0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNFVCBAQEdMT0JBTC5HVElEX1BVUkdFRD0nJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBzdHJpbmdzIGxpa2UgREVGSU5FUj1gdXNlcmBAYGxvY2FsaG9zdGAsIGJlY2F1c2UgdGhleSBnZW5lcmF0ZSBlcnJvcnMgbGlrZSB0aGlzOgogICAgICAgICAgICAgICAgICAgICAgICAvLyAiWzEyMjddIEFjY2VzcyBkZW5pZWQ7IHlvdSBuZWVkIChhdCBsZWFzdCBvbmUgb2YpIHRoZSBTVVBFUiBwcml2aWxlZ2UocykgZm9yIHRoaXMgb3BlcmF0aW9uIgogICAgICAgICAgICAgICAgICAgICAgICAvLyBFeGFtcGxlIG9mIGEgcHJvYmxlbWF0aWMgcXVlcnk6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAvKiE1MDAwMyBDUkVBVEUqLyAvKiE1MDAxNyBERUZJTkVSPWB1c2VyYEBgbG9jYWxob3N0YCovIC8qITUwMDAzIFRSSUdHRVIgYHdwX2hsb2dpbl9kZWZhdWx0X3N0b3JhZ2VfdGFibGVgIEJFRk9SRSBVUERBVEUgT04gYHdwX2hsb2dpbl9kZWZhdWx0X3N0b3JhZ2VfdGFibGVgCiAgICAgICAgICAgICAgICAgICAgICAgICRuZXdTdGF0ZW1lbnRzID0gcHJlZ19yZXBsYWNlKCd7KC9cKiFcZCspIERFRklORVI9YFteYF0rYEBgW15gXStgKFwqLyApfScsICcnLCAkc3RhdGVtZW50cywgMSwgJGNvdW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY29ubi0+ZXhlY3V0ZSgkbmV3U3RhdGVtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChDbG9uZXJFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRkdW1wLT50eXBlID09PSBDbG9uZXJUYWJsZVR5cGU6OlBST0NFRFVSRSB8fCAkZHVtcC0+dHlwZSA9PT0gQ2xvbmVyVGFibGVUeXBlOjpGVU5DIHx8ICRkdW1wLT50eXBlID09PSBDbG9uZXJUYWJsZVR5cGU6OlZJRVcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRyeSBmb3IgcHJvY2VkdXJlLCBmdW5jdGlvbiBvciB2aWV3IHRvIHJlbW92ZSBzdHJpbmdzIGxpa2UgREVGSU5FUj1gdXNlcmBAYGxvY2FsaG9zdGAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIGl0IGZhaWxzIGp1c3QgY29udGludWUsIHdlIGRvbid0IHdhbnQgdG8gYnJlYWsgZHVlIHRvIHByb2JsZW0gd2l0aCBmdW5jdGlvbnMsIHByb2NlZHVyZXMgb3Igdmlld3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRuZXdTdGF0ZW1lbnRzID0gcHJlZ19yZXBsYWNlKCd7REVGSU5FUj1gW15gXStgQGBbXmBdK2B9JywgJycsICRzdGF0ZW1lbnRzLCAxLCAkY291bnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjb25uLT5leGVjdXRlKCRuZXdTdGF0ZW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChDbG9uZXJFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHN0YXRlLT5za2lwU3RhdGVtZW50KCRzdGF0ZW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oY2xvbmVyX2Zvcm1hdF9xdWVyeV9lcnJvcigkZS0+Z2V0TWVzc2FnZSgpLCAkc3RhdGVtZW50cywgJGR1bXAtPnBhdGgsICRkdW1wLT5wcm9jZXNzZWQsICRzY2FubmVyLT50ZWxsKCksICRkdW1wLT5zaXplKSwgJ2RiX3F1ZXJ5X2Vycm9yJywgJGUtPmdldEludGVybmFsRXJyb3IoKSk7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiMzE2NyI6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJwb3MoJHN0YXRlbWVudHMsICdAaXNfcm9ja3NkYl9zdXBwb3J0ZWQnKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJvY2tzREIgc3VwcG9ydCBoYW5kbGluZyBmb3IgdGhlIGZvbGxvd2luZyBjYXNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8qITUwMTEyIFNFTEVDVCBDT1VOVCgqKSBJTlRPIEBpc19yb2Nrc2RiX3N1cHBvcnRlZCBGUk9NIElORk9STUFUSU9OX1NDSEVNQS5TRVNTSU9OX1ZBUklBQkxFUyBXSEVSRSBWQVJJQUJMRV9OQU1FPSdyb2Nrc2RiX2J1bGtfbG9hZCcgKi87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAvKiE1MDExMiBTRVQgQHNhdmVfb2xkX3JvY2tzZGJfYnVsa19sb2FkID0gSUYgKEBpc19yb2Nrc2RiX3N1cHBvcnRlZCwgJ1NFVCBAb2xkX3JvY2tzZGJfYnVsa19sb2FkID0gQEByb2Nrc2RiX2J1bGtfbG9hZCcsICdTRVQgQGR1bW15X29sZF9yb2Nrc2RiX2J1bGtfbG9hZCA9IDAnKSAqLzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8qITUwMTEyIFBSRVBBUkUgcyBGUk9NIEBzYXZlX29sZF9yb2Nrc2RiX2J1bGtfbG9hZCAqLzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8qITUwMTEyIEVYRUNVVEUgcyAqLzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8qITUwMTEyIFNFVCBAZW5hYmxlX2J1bGtfbG9hZCA9IElGIChAaXNfcm9ja3NkYl9zdXBwb3J0ZWQsICdTRVQgU0VTU0lPTiByb2Nrc2RiX2J1bGtfbG9hZCA9IDEnLCAnU0VUIEBkdW1teV9yb2Nrc2RiX2J1bGtfbG9hZCA9IDAnKSAqLzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8qITUwMTEyIFBSRVBBUkUgcyBGUk9NIEBlbmFibGVfYnVsa19sb2FkICovOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gLyohNTAxMTIgRVhFQ1VURSBzICovOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gLyohNTAxMTIgREVBTExPQ0FURSBQUkVQQVJFIHMgKi87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAuLi4gdGFibGUgY3JlYXRpb24gYW5kIGluc2VydCBzdGF0ZW1lbnRzIC4uLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gLyohNTAxMTIgU0VUIEBkaXNhYmxlX2J1bGtfbG9hZCA9IElGIChAaXNfcm9ja3NkYl9zdXBwb3J0ZWQsICdTRVQgU0VTU0lPTiByb2Nrc2RiX2J1bGtfbG9hZCA9IEBvbGRfcm9ja3NkYl9idWxrX2xvYWQnLCAnU0VUIEBkdW1teV9yb2Nrc2RiX2J1bGtfbG9hZCA9IDAnKSAqLzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8qITUwMTEyIFBSRVBBUkUgcyBGUk9NIEBkaXNhYmxlX2J1bGtfbG9hZCAqLzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8qITUwMTEyIEVYRUNVVEUgcyAqLzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8qITUwMTEyIERFQUxMT0NBVEUgUFJFUEFSRSBzICovOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEVycm9yIG9uIHRoZSBmaXJzdCBzdGF0ZW1lbnQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICMzMTY3IC0gVGhlICdJTkZPUk1BVElPTl9TQ0hFTUEuU0VTU0lPTl9WQVJJQUJMRVMnIGZlYXR1cmUgaXMgZGlzYWJsZWQ7IHNlZSB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgJ3Nob3dfY29tcGF0aWJpbGl0eV81NicKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNvbm4tPmV4ZWN1dGUoJ1NFVCBAaXNfcm9ja3NkYl9zdXBwb3J0ZWQgPSAwJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChDbG9uZXJFeGNlcHRpb24gJGUyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbihjbG9uZXJfZm9ybWF0X3F1ZXJ5X2Vycm9yKCdDb3VsZCBub3QgcmVjb3ZlciBmcm9tIFJvY2tzREIgc3VwcG9ydCBwYXRjaDogJy4kZTItPmdldE1lc3NhZ2UoKSwgJHN0YXRlbWVudHMsICRkdW1wLT5wYXRoLCAkZHVtcC0+cHJvY2Vzc2VkLCAkc2Nhbm5lci0+dGVsbCgpLCAkZHVtcC0+c2l6ZSksICdkYl9xdWVyeV9lcnJvcicsICRlMi0+Z2V0SW50ZXJuYWxFcnJvcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oY2xvbmVyX2Zvcm1hdF9xdWVyeV9lcnJvcigkZS0+Z2V0TWVzc2FnZSgpLCAkc3RhdGVtZW50cywgJGR1bXAtPnBhdGgsICRkdW1wLT5wcm9jZXNzZWQsICRzY2FubmVyLT50ZWxsKCksICRkdW1wLT5zaXplKSwgJ2RiX3F1ZXJ5X2Vycm9yJywgJGUtPmdldEludGVybmFsRXJyb3IoKSk7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRkdW1wLT50eXBlICE9PSBDbG9uZXJUYWJsZVR5cGU6OlJFR1VMQVIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRzdGF0ZS0+c2tpcFN0YXRlbWVudCgkc3RhdGVtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKGNsb25lcl9mb3JtYXRfcXVlcnlfZXJyb3IoJGUtPmdldE1lc3NhZ2UoKSwgJHN0YXRlbWVudHMsICRkdW1wLT5wYXRoLCAkZHVtcC0+cHJvY2Vzc2VkLCAkc2Nhbm5lci0+dGVsbCgpLCAkZHVtcC0+c2l6ZSksICdkYl9xdWVyeV9lcnJvcicsICRlLT5nZXRJbnRlcm5hbEVycm9yKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRkdW1wLT5wcm9jZXNzZWQgPSAkc2Nhbm5lci0+dGVsbCgpOwogICAgICAgICAgICBpZiAoJGRlYWRsaW5lLT5kb25lKCkpIHsKICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBhbnkgbG9ja2VkIHRhYmxlcyB3ZSBtaWdodCBoYW5nIGZvcmV2ZXIgd2l0aCB0aGUgbmV4dCBxdWVyeSwgdW5sb2NrIHRoZW0uCiAgICAgICAgICAgICAgICAkY29ubi0+ZXhlY3V0ZSgiVU5MT0NLIFRBQkxFUyIpOwogICAgICAgICAgICAgICAgLy8gV2UncmUgY3V0dGluZyB0aGUgaW1wb3J0IGhlcmUgLSByZW1lbWJlciB0aGUgZW5jb2RpbmchISEKICAgICAgICAgICAgICAgICRjaGFyc2V0ICAgICAgICA9ICRjb25uLT5xdWVyeSgiU0hPVyBWQVJJQUJMRVMgTElLRSAnY2hhcmFjdGVyX3NldF9jbGllbnQnIiktPmZldGNoKCk7CiAgICAgICAgICAgICAgICAkZHVtcC0+ZW5jb2RpbmcgPSAoc3RyaW5nKWVuZCgkY2hhcnNldCk7CiAgICAgICAgICAgICAgICBicmVhayAyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRkdW1wLT5wcm9jZXNzZWQgPSAkc2Nhbm5lci0+dGVsbCgpOwogICAgICAgICRzY2FubmVyLT5jbG9zZSgpOwogICAgfQoKICAgIHJldHVybiAkc3RhdGU7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl9pbXBvcnRfZGF0YWJhc2UnKSk6CmZ1bmN0aW9uIGNsb25lcl9hY3Rpb25faW1wb3J0X2RhdGFiYXNlKCRyb290LCAkZGIsIGFycmF5ICRzdGF0ZSwgJG9sZFByZWZpeCwgJG5ld1ByZWZpeCwgJG1heENvdW50LCAkdGltZW91dCkKewogICAgJGNvbm4gICAgICAgID0gY2xvbmVyX2RiX2Nvbm4oJGRiKTsKICAgICRzdGF0ZSAgICAgICA9IENsb25lckRCSW1wb3J0U3RhdGU6OmZyb21BcnJheSgkc3RhdGUsIDEwIDw8IDEwKTsKICAgICRmaWx0ZXJzICAgICA9IGFycmF5KCk7CiAgICAkbG93ZXJQcmVmaXggPSBzdHJ0b2xvd2VyKCRuZXdQcmVmaXgpOwogICAgaWYgKCRvbGRQcmVmaXggIT09ICRuZXdQcmVmaXgpIHsKICAgICAgICAkZmlsdGVyc1tdID0gbmV3IENsb25lclByZWZpeEZpbHRlcigkb2xkUHJlZml4LCAkbmV3UHJlZml4KTsKICAgIH0gZWxzZWlmICgkbG93ZXJQcmVmaXggIT09ICRuZXdQcmVmaXgpIHsKICAgICAgICAvLyBQcmVmaXggY29udGFpbnMgdXBwZXJjYXNlIGNoYXJhY3RlcnMsIG1lYW5pbmcgdGhhdCBpZiB0aGUgb3JpZ2luIGlzIFdpbmRvd3MgdGhlIHRhYmxlcyBtYXkgYWN0dWFsbHkgaGF2ZQogICAgICAgIC8vIGxvd2VyY2FzZSBuYW1lcywgc2luY2Ugb24gV2luZG93cyBNeVNRTCBpbnRlcm5hbGx5IG5vcm1hbGl6ZXMgdGhlbSBhbGwgdG8gbG93ZXJjYXNlLgogICAgICAgIC8vIFRvIGJlIHNhZmUsIHRyYW5zZm9ybSBsb3dlcmNhc2UgdmVyc2lvbnMgb2YgdGFibGUgbmFtZXMgKGlmIGFueSBleGlzdCkgdG8gdXBwZXJjYXNlLgogICAgICAgICRmaWx0ZXJzW10gPSBuZXcgQ2xvbmVyUHJlZml4RmlsdGVyKCRsb3dlclByZWZpeCwgJG5ld1ByZWZpeCk7CiAgICB9CiAgICAkZW52ID0gY2xvbmVyX2Vudl9pbmZvKCRyb290KTsKICAgIGlmICgkZW52LT5nb0RhZGR5UHJvID09PSAxKSB7CiAgICAgICAgJGZpbHRlcnNbXSA9IG5ldyBDbG9uZXJEQlN0b3JhZ2VGaWx0ZXIoKTsKICAgIH0KICAgIHJldHVybiBjbG9uZXJfaW1wb3J0X2RhdGFiYXNlKCRyb290LCAkY29ubiwgJHRpbWVvdXQsICRzdGF0ZSwgJG1heENvdW50LCAkZmlsdGVycyk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2dldF91c2VyX2lkX2J5X3VzZXJuYW1lJykpOgpmdW5jdGlvbiBjbG9uZXJfZ2V0X3VzZXJfaWRfYnlfdXNlcm5hbWUoQ2xvbmVyREJDb25uICRjb25uLCAkcHJlZml4LCAkdXNlcm5hbWUpIHsKICAgICRxdWVyeSA9IDw8PFNRTApTRUxFQ1QgdS5JRAogIEZST00geyRwcmVmaXh9dXNlcnMgdQogIFdIRVJFCiAgICB1LnVzZXJfbG9naW4gPSA6dXNlcl9sb2dpbgogIE9SREVSIEJZIElEIEFTQwogIExJTUlUIDEKU1FMOwoKICAgICRleGlzdGluZ1VzZXIgPSAkY29ubi0+cXVlcnkoJHF1ZXJ5LCBhcnJheSgndXNlcl9sb2dpbicgPT4gJHVzZXJuYW1lKSktPmZldGNoKCk7CgogICAgaWYgKCRleGlzdGluZ1VzZXIpIHsKICAgICAgICByZXR1cm4gKGludCkkZXhpc3RpbmdVc2VyWydJRCddOwogICAgfQoKICAgIHJldHVybiBudWxsOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9zYW5pdGl6ZV91c2VyJykpOgpmdW5jdGlvbiBjbG9uZXJfc2FuaXRpemVfdXNlcigkdXNlcm5hbWUsICRzdHJpY3QgPSBmYWxzZSkgewogICAgJHVzZXJuYW1lID0gc3RyaXBfdGFncygkdXNlcm5hbWUpOwogICAgLy8gS2lsbCBvY3RldHMKICAgICR1c2VybmFtZSA9IHByZWdfcmVwbGFjZSgnfCUoW2EtZkEtRjAtOV1bYS1mQS1GMC05XSl8JywgJycsICR1c2VybmFtZSk7CiAgICAkdXNlcm5hbWUgPSBwcmVnX3JlcGxhY2UoJy8mLis/Oy8nLCAnJywgJHVzZXJuYW1lKTsgLy8gS2lsbCBlbnRpdGllcwoKICAgIC8vIElmIHN0cmljdCwgcmVkdWNlIHRvIEFTQ0lJIGZvciBtYXggcG9ydGFiaWxpdHkuCiAgICBpZiAoJHN0cmljdCkgewogICAgICAgICR1c2VybmFtZSA9IHByZWdfcmVwbGFjZSgnfFteYS16MC05IF8uXC1AXXxpJywgJycsICR1c2VybmFtZSk7CiAgICB9CgogICAgJHVzZXJuYW1lID0gdHJpbSgkdXNlcm5hbWUpOwogICAgLy8gQ29uc29saWRhdGUgY29udGlndW91cyB3aGl0ZXNwYWNlCiAgICAkdXNlcm5hbWUgPSBwcmVnX3JlcGxhY2UoJ3xccyt8JywgJyAnLCAkdXNlcm5hbWUpOwoKICAgIHJldHVybiAkdXNlcm5hbWU7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl9zZXRfYWRtaW4nKSk6CmZ1bmN0aW9uIGNsb25lcl9hY3Rpb25fc2V0X2FkbWluKCRkYiwgJHByZWZpeCwgJHVzZXJuYW1lLCAkcGFzc3dvcmQsICRlbWFpbCkKewogICAgJGNvbm4gICAgPSBjbG9uZXJfZGJfY29ubigkZGIpOwogICAgJGFkbWluSUQgPSBjbG9uZXJfZ2V0X3VzZXJfaWRfYnlfdXNlcm5hbWUoJGNvbm4sICRwcmVmaXgsICR1c2VybmFtZSk7CiAgICAkY29ubi0+cXVlcnkoIlVQREFURSB7JHByZWZpeH1vcHRpb25zIFNFVCBvcHRpb25fdmFsdWUgPSA6ZW1haWwgV0hFUkUgb3B0aW9uX25hbWUgPSAnYWRtaW5fZW1haWwnIiwgYXJyYXkoCiAgICAgICAgJ2VtYWlsJyA9PiAkZW1haWwsCiAgICApKTsKICAgIGlmICgkYWRtaW5JRCkgewogICAgICAgICRjb25uLT5xdWVyeSgiVVBEQVRFIHskcHJlZml4fXVzZXJzIFNFVCB1c2VyX3Bhc3MgPSA6cGFzc3dvcmQsIHVzZXJfZW1haWwgPSA6ZW1haWwgV0hFUkUgSUQgPSA6dXNlcl9pZCIsIGFycmF5KAogICAgICAgICAgICAndXNlcl9pZCcgID0+ICRhZG1pbklELAogICAgICAgICAgICAncGFzc3dvcmQnID0+ICRwYXNzd29yZCwKICAgICAgICAgICAgJ2VtYWlsJyAgICA9PiAkZW1haWwsCiAgICAgICAgKSk7CiAgICB9IGVsc2UgewogICAgICAgIC8qKiBAbm9pbnNwZWN0aW9uIFNxbERpYWxlY3RJbnNwZWN0aW9uICovCiAgICAgICAgJGNvbm4tPnF1ZXJ5KCJJTlNFUlQgSU5UTyB7JHByZWZpeH11c2VycyAodXNlcl9sb2dpbiwgdXNlcl9wYXNzLCB1c2VyX2VtYWlsLCB1c2VyX25pY2VuYW1lLCB1c2VyX3JlZ2lzdGVyZWQsIGRpc3BsYXlfbmFtZSkKVkFMVUVTICg6dXNlcm5hbWUsIDpwYXNzd29yZCwgOmVtYWlsLCA6c2x1ZywgOm5vdywgOmRpc3BsYXlfbmFtZSkiLCBhcnJheSgKICAgICAgICAgICAgJ3VzZXJuYW1lJyAgICAgPT4gJHVzZXJuYW1lLAogICAgICAgICAgICAncGFzc3dvcmQnICAgICA9PiAkcGFzc3dvcmQsCiAgICAgICAgICAgICdlbWFpbCcgICAgICAgID0+ICRlbWFpbCwKICAgICAgICAgICAgJ3NsdWcnICAgICAgICAgPT4gY2xvbmVyX3Nhbml0aXplX3VzZXIoJHVzZXJuYW1lKSwKICAgICAgICAgICAgJ25vdycgICAgICAgICAgPT4gZGF0ZSgnWS1tLWQgSDppOnMnKSwKICAgICAgICAgICAgJ2Rpc3BsYXlfbmFtZScgPT4gJHVzZXJuYW1lLAogICAgICAgICkpOwogICAgICAgICRuZXdJRCA9IGNsb25lcl9nZXRfdXNlcl9pZF9ieV91c2VybmFtZSgkY29ubiwgJHByZWZpeCwgJHVzZXJuYW1lKTsKICAgICAgICBpZiAoISRuZXdJRCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdBZG1pbiB1c2VyIGNvdWxkIG5vdCBiZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UuJywgJ2FkbWluX25vdF9zYXZlZCcpOwogICAgICAgIH0KICAgICAgICAkb3B0aW9ucyA9IGFycmF5KAogICAgICAgICAgICAkcHJlZml4LidjYXBhYmlsaXRpZXMnID0+IHNlcmlhbGl6ZShhcnJheSgnYWRtaW5pc3RyYXRvcicgPT4gdHJ1ZSkpLAogICAgICAgICAgICAncmljaF9lZGl0aW5nJyAgICAgICAgID0+ICd0cnVlJywKICAgICAgICAgICAgJ3Nob3dfYWRtaW5fYmFyX2Zyb250JyA9PiB0cnVlLAogICAgICAgICk7CiAgICAgICAgZm9yZWFjaCAoJG9wdGlvbnMgYXMgJG5hbWUgPT4gJHZhbHVlKSB7CiAgICAgICAgICAgIC8qKiBAbm9pbnNwZWN0aW9uIFNxbERpYWxlY3RJbnNwZWN0aW9uICovCiAgICAgICAgICAgICRjb25uLT5xdWVyeSgiSU5TRVJUIElOVE8geyRwcmVmaXh9dXNlcm1ldGEgU0VUIHVzZXJfaWQgPSA6dXNlcl9pZCwgbWV0YV9rZXkgPSA6bWV0YV9rZXksIG1ldGFfdmFsdWUgPSA6bWV0YV92YWx1ZSIsIGFycmF5KAogICAgICAgICAgICAgICAgJ3VzZXJfaWQnICAgID0+ICRuZXdJRCwKICAgICAgICAgICAgICAgICdtZXRhX2tleScgICA9PiAkbmFtZSwKICAgICAgICAgICAgICAgICdtZXRhX3ZhbHVlJyA9PiAkdmFsdWUsCiAgICAgICAgICAgICkpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBhcnJheSgpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl91cGRhdGVfdXNlcm1ldGFfcHJlZml4JykpOgpmdW5jdGlvbiBjbG9uZXJfdXBkYXRlX3VzZXJtZXRhX3ByZWZpeChDbG9uZXJEQkNvbm4gJGNvbm4sIGFycmF5ICRrZXlzLCAkb2xkUHJlZml4LCAkbmV3UHJlZml4LCAkbGltaXQpIHsKICAgICRvbGRQcmVmaXhMZW5ndGggPSBzdHJsZW4oJG9sZFByZWZpeCkgKyAxOwogICAgJG9sZEtleXMgICAgICAgICA9ICIneyRvbGRQcmVmaXh9Ii5pbXBsb2RlKCInLCAneyRvbGRQcmVmaXh9IiwgJGtleXMpLiInIjsKCiAgICAkc3FsID0gPDw8U1FMClVQREFURSBgeyRuZXdQcmVmaXh9dXNlcm1ldGFgCiAgU0VUIGBtZXRhX2tleWAgPSBDT05DQVQoeyRjb25uLT5lc2NhcGUoJG5ld1ByZWZpeCl9LCBTVUJTVFIoYG1ldGFfa2V5YCwgeyRvbGRQcmVmaXhMZW5ndGh9KSkKICBXSEVSRSBgbWV0YV9rZXlgIElOICh7JG9sZEtleXN9KQogIExJTUlUIHskbGltaXR9ClNRTDsKICAgIHJldHVybiAkY29ubi0+cXVlcnkoJHNxbCktPmdldE51bVJvd3MoKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdtaWdyYXRlX3dvcmRwcmVzc190YWJsZV9wcmVmaXgnKSk6CmZ1bmN0aW9uIG1pZ3JhdGVfd29yZHByZXNzX3RhYmxlX3ByZWZpeChDbG9uZXJEQkNvbm4gJGNvbm4sICR0aW1lb3V0LCBhcnJheSAkYXJncywgJHN0YXRlKQp7CiAgICAkZGVhZGxpbmUgPSB0aW1lKCkgKyAkdGltZW91dDsKICAgIGxpc3QoJG9sZFByZWZpeCwgJG5ld1ByZWZpeCkgPSAkYXJnczsKICAgICR1c2VyTWV0YUtleXMgPSBhcnJheSgKICAgICAgICAnY2FwYWJpbGl0aWVzJywKICAgICAgICAnZGFzaGJvYXJkX3F1aWNrX3ByZXNzX2xhc3RfcG9zdF9pZCcsCiAgICAgICAgJ3VzZXItc2V0dGluZ3MnLAogICAgICAgICd1c2VyLXNldHRpbmdzLXRpbWUnLAogICAgICAgICd1c2VyX2xldmVsJywKICAgICk7CgogICAgaWYgKGVtcHR5KCRzdGF0ZSkpIHsKICAgICAgICAkc3RhdGUgICAgICA9IGFycmF5KAogICAgICAgICAgICAndXBkYXRlX3JvbGVzJyAgICAgICAgICA9PiBmYWxzZSwKICAgICAgICAgICAgJ3VwZGF0ZV9yb2xlc19jb3VudCcgICAgPT4gMCwKICAgICAgICAgICAgJ2RlbGV0ZV91c2VybWV0YScgICAgICAgPT4gZmFsc2UsCiAgICAgICAgICAgICd1cGRhdGVfdXNlcm1ldGEnICAgICAgID0+IGZhbHNlLAogICAgICAgICAgICAndXBkYXRlX3VzZXJtZXRhX2NvdW50JyA9PiBmYWxzZSwKICAgICAgICApOwogICAgICAgICRjbGVhblF1ZXJ5ID0gPDw8U1FMCkRFTEVURSBGUk9NIGB7JG5ld1ByZWZpeH1vcHRpb25zYAogIFdIRVJFIG9wdGlvbl9uYW1lID0gJ3skbmV3UHJlZml4fXVzZXJfcm9sZXMnClNRTDsKICAgICAgICAkY29ubi0+cXVlcnkoJGNsZWFuUXVlcnkpOwoKICAgICAgICAkcm9sZVF1ZXJ5ICAgICAgICAgICAgICAgICAgID0gPDw8U1FMClVQREFURSBgeyRuZXdQcmVmaXh9b3B0aW9uc2AKICBTRVQgb3B0aW9uX25hbWUgPSAneyRuZXdQcmVmaXh9dXNlcl9yb2xlcycKICBXSEVSRSBvcHRpb25fbmFtZSA9ICd7JG9sZFByZWZpeH11c2VyX3JvbGVzJwpTUUw7CiAgICAgICAgJHN0YXRlWyd1cGRhdGVfcm9sZXNfY291bnQnXSA9ICRjb25uLT5xdWVyeSgkcm9sZVF1ZXJ5KS0+Z2V0TnVtUm93cygpOwogICAgICAgICRzdGF0ZVsndXBkYXRlX3JvbGVzJ10gICAgICAgPSB0cnVlOwoKICAgICAgICAvLyBGaXJzdCBtYWtlIHJvb20gZm9yIHRoZSB1cGRhdGVkIG1ldGEga2V5cy4gVGhpcyBzaG91bGQgYmUgYSBuby1vcCBmb3IgbW9zdAogICAgICAgIC8vIGluc3RhbGxhdGlvbnMgYW5kIGlzIGhlcmUgb25seSB0byBiZSBzYWZlLgogICAgICAgICRuZXdLZXlzICA9ICIneyRuZXdQcmVmaXh9Ii5pbXBsb2RlKCInLCAneyRuZXdQcmVmaXh9IiwgJHVzZXJNZXRhS2V5cykuIiciOwogICAgICAgICRjbGVhblNRTCA9IDw8PFNRTApERUxFVEUgRlJPTSBgeyRuZXdQcmVmaXh9dXNlcm1ldGFgCiAgV0hFUkUgYG1ldGFfa2V5YCBJTiAoeyRuZXdLZXlzfSkKU1FMOwogICAgICAgICRjb25uLT5xdWVyeSgkY2xlYW5TUUwpOwogICAgICAgICRzdGF0ZVsnZGVsZXRlX3VzZXJtZXRhJ10gPSB0cnVlOwogICAgfQogICAgJHVwZGF0ZUxpbWl0ID0gMTAwOwogICAgd2hpbGUgKCRjb3VudCA9IGNsb25lcl91cGRhdGVfdXNlcm1ldGFfcHJlZml4KCRjb25uLCAkdXNlck1ldGFLZXlzLCAkb2xkUHJlZml4LCAkbmV3UHJlZml4LCAkdXBkYXRlTGltaXQpKSB7CiAgICAgICAgaWYgKCFpc3NldCgkc3RhdGVbJ3VwZGF0ZV91c2VybWV0YSddKSkgewogICAgICAgICAgICAkc3RhdGVbJ3VwZGF0ZV91c2VybWV0YSddID0gMDsKICAgICAgICB9CiAgICAgICAgJHN0YXRlWyd1cGRhdGVfdXNlcm1ldGEnXSArPSAkY291bnQ7CiAgICAgICAgaWYgKCRjb3VudCA8ICR1cGRhdGVMaW1pdCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKHRpbWUoKSA+PSAkZGVhZGxpbmUpIHsKICAgICAgICAgICAgLy8gVGltZW91dC4KICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRzdGF0ZSwgZmFsc2UpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBhcnJheSgkc3RhdGUsIHRydWUpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9taWdyYXRlX3RhYmxlX3ByZWZpeCcpKToKZnVuY3Rpb24gY2xvbmVyX21pZ3JhdGVfdGFibGVfcHJlZml4KENsb25lckRCQ29ubiAkY29ubiwgJHRpbWVvdXQsIGFycmF5ICRhcmdzLCAkc3RhdGUsICRjbXMpCnsKICAgIHN3aXRjaCAoJGNtcyl7CiAgICAgICAgY2FzZSAnd29yZHByZXNzJzoKICAgICAgICAgICAgcmV0dXJuIG1pZ3JhdGVfd29yZHByZXNzX3RhYmxlX3ByZWZpeCgkY29ubiwgJHRpbWVvdXQsICRhcmdzLCAkc3RhdGUpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkc3RhdGUsIHRydWUpOwogICAgICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfdXBkYXRlX211bHRpc2l0ZV91cmwnKSk6CmZ1bmN0aW9uIGNsb25lcl91cGRhdGVfbXVsdGlzaXRlX3VybCgkb2xkUm9vdEhvc3QsICRvbGRSb290UGF0aCwgJG5ld1Jvb3RIb3N0LCAkbmV3Um9vdFBhdGgsICRob3N0LCAkcGF0aCkgewogICAgJHJlcGxhY2VkID0gZmFsc2U7CiAgICBpZiAoc3Vic3RyKCRob3N0LCAtc3RybGVuKCcuJy4kb2xkUm9vdEhvc3QpKSA9PT0gJy4nLiRvbGRSb290SG9zdCkgewogICAgICAgIC8vIEhvc3RzIHN0YXJ0cyBsaWtlIGRvbWFpbi5vbGQtdXJsLmNvbTsgbWlncmF0ZSBpdCB0byBkb21haW4ubmV3LXVybC5jb20KICAgICAgICAkaG9zdCAgICAgPSBzdWJzdHIoJGhvc3QsIDAsIHN0cmxlbigkaG9zdCkgLSBzdHJsZW4oJy4nLiRvbGRSb290SG9zdCkpLicuJy4kbmV3Um9vdEhvc3Q7CiAgICAgICAgJHJlcGxhY2VkID0gdHJ1ZTsKICAgIH0gZWxzZWlmICgkb2xkUm9vdEhvc3QgPT09ICRob3N0KSB7CiAgICAgICAgLy8gSG9zdCBpcyB0aGUgc2FtZSBhcyB0aGUgcm9vdCBob3N0OyB1c2UgdGhlIG5ldyBvbmUuCiAgICAgICAgJGhvc3QgICAgID0gJG5ld1Jvb3RIb3N0OwogICAgICAgICRyZXBsYWNlZCA9IHRydWU7CiAgICB9CiAgICBpZiAoc3RybGVuKCRvbGRSb290UGF0aCkgPiAxICYmIHN1YnN0cigkcGF0aCwgMCwgc3RybGVuKCRvbGRSb290UGF0aCkpID09PSAkb2xkUm9vdFBhdGgpIHsKICAgICAgICAvLyBQYXRoIHN0YXJ0cyBsaWtlIC9vbGQtcm9vdC9ibG9nLW5hbWUvLCBzdHJpcCB0aGUgb2xkLXJvb3QgcHJlZml4LgogICAgICAgICRwYXRoICAgICA9ICcvJy5sdHJpbShzdWJzdHIoJHBhdGgsIHN0cmxlbigkb2xkUm9vdFBhdGgpKSwgJy8nKTsKICAgICAgICAkcmVwbGFjZWQgPSB0cnVlOwogICAgfQogICAgJHBhdGggPSBydHJpbSgkbmV3Um9vdFBhdGgsICcvJykuJy8nLmx0cmltKCRwYXRoLCAnLycpOwogICAgcmV0dXJuIGFycmF5KCRob3N0LCAkcGF0aCwgJHJlcGxhY2VkKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfdXJsX3NsdWcnKSk6CmZ1bmN0aW9uIGNsb25lcl91cmxfc2x1ZygkdXJsKSB7CiAgICAkcGFydHMgPSBwYXJzZV91cmwoJHVybCk7CiAgICByZXR1cm4gc3RydG9sb3dlcihydHJpbShzcHJpbnRmKCclcyVzJXMnLCBwcmVnX3JlcGxhY2UoJy9ed3d3XC4vaScsICcnLCAkcGFydHNbJ2hvc3QnXSksIGlzc2V0KCRwYXJ0c1sncG9ydCddKSA/ICc6Jy4kcGFydHNbJ3BvcnQnXSA6ICcnLCBpc3NldCgkcGFydHNbJ3BhdGgnXSkgPyAkcGFydHNbJ3BhdGgnXSA6ICcnKSwgJy8nKSk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2VzY2FwZV9saWtlJykpOgpmdW5jdGlvbiBjbG9uZXJfZXNjYXBlX2xpa2UoJHZhbHVlKQp7CiAgICByZXR1cm4gc3RyX3JlcGxhY2UoYXJyYXkoJ1xcJywgJ18nLCAnJScpLCBhcnJheSgnXFxcXCcsICdcXycsICdcJScpLCAkdmFsdWUpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl91cGRhdGVfZmllbGRfcHJlZml4JykpOgpmdW5jdGlvbiBjbG9uZXJfdXBkYXRlX2ZpZWxkX3ByZWZpeChDbG9uZXJEQkNvbm4gJGNvbm4sICR0YWJsZSwgJGZpZWxkLCAkb2xkUHJlZml4LCAkbmV3UHJlZml4LCAkbGltaXQsICR3aGVyZSA9IG51bGwpIHsKICAgIGlmICgkd2hlcmUgIT09IG51bGwpIHsKICAgICAgICAkd2hlcmUgPSAnQU5EICcuJHdoZXJlOwogICAgfQogICAgJGVzY2FwZWRPbGRQcmVmaXggPSBjbG9uZXJfZXNjYXBlX2xpa2UoJG9sZFByZWZpeCk7CiAgICAvLyArMSBpcyBpbnRlbnRpb25hbC4KICAgIC8vIGh0dHBzOi8vZGV2Lm15c3FsLmNvbS9kb2MvcmVmbWFuLzUuMC9lbi9zdHJpbmctZnVuY3Rpb25zLmh0bWwjZnVuY3Rpb25fc3Vic3RyaW5nCiAgICAkb2xkUHJlZml4TGVuZ3RoID0gc3RybGVuKCRvbGRQcmVmaXgpICsgMTsKICAgICRzcWwgICAgICAgICAgICAgPSA8PDxTUUwKVVBEQVRFIGB7JHRhYmxlfWAKICBTRVQgYHskZmllbGR9YCA9IENPTkNBVCh7JGNvbm4tPmVzY2FwZSgkbmV3UHJlZml4KX0sIFNVQlNUUihgeyRmaWVsZH1gLCB7JG9sZFByZWZpeExlbmd0aH0pKQogIFdIRVJFIGB7JGZpZWxkfWAgTElLRSAneyRlc2NhcGVkT2xkUHJlZml4fSUnCiAgeyR3aGVyZX0KTElNSVQgeyRsaW1pdH0KU1FMOwogICAgLyoqIEB2YXIgVFlQRV9OQU1FICRjb25uICovCiAgICAkcmVzdWx0ID0gJGNvbm4tPnF1ZXJ5KCRzcWwpOwogICAgJGNvdW50ICA9ICRyZXN1bHQtPmdldE51bVJvd3MoKTsKICAgICRyZXN1bHQtPmZyZWUoKTsKICAgIHJldHVybiAkY291bnQ7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVydXJscmVwbGFjZXInLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJVUkxSZXBsYWNlcgp7CiAgICBwcml2YXRlICRmdWxsVVJMOwogICAgcHJpdmF0ZSAkc2hvcnRVUkw7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR1cmwpIHsKICAgICAgICAkdGhpcy0+ZnVsbFVSTCAgPSAkdXJsOwogICAgICAgICR0aGlzLT5zaG9ydFVSTCA9IHByZWdfcmVwbGFjZSgne15odHRwcz86fScsICcnLCAkdXJsKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBhcnJheSAkbWF0Y2hlcyBGaXJzdCBtYXRjaCBpcyBodHRwOiBvciBodHRwczosIHNlY29uZCBtYXRjaCBpcyB0cmFpbGluZyBzbGFzaC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHN0cmluZwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVwbGFjZShhcnJheSAkbWF0Y2hlcykgewogICAgICAgIGlmIChzdHJsZW4oJG1hdGNoZXNbMV0pKSB7CiAgICAgICAgICAgIC8vIFNjaGVtZSBpcyBwcmVzZW50LgogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmZ1bGxVUkwuJG1hdGNoZXNbMl07CiAgICAgICAgfQogICAgICAgIC8vIEVtcHR5IHNjaGVtZS4KICAgICAgICByZXR1cm4gJHRoaXMtPnNob3J0VVJMLiRtYXRjaGVzWzJdOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnNlcmlhbGl6ZWRyZWFkZXJleGNlcHRpb24nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJTZXJpYWxpemVkUmVhZGVyRXhjZXB0aW9uIGV4dGVuZHMgQ2xvbmVyRXhjZXB0aW9uCnsKICAgIHB1YmxpYyAkb2Zmc2V0OwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkb2Zmc2V0LCAkbWVzc2FnZSkKICAgIHsKICAgICAgICAkdGhpcy0+b2Zmc2V0ID0gJG9mZnNldDsKICAgICAgICBwYXJlbnQ6Ol9fY29uc3RydWN0KHNwcmludGYoImNsb25lcl9zZXJpYWxpemVkX3JlcGxhY2UgZXJyb3IgYXQgb2Zmc2V0ICVkOiAlcyIsICRvZmZzZXQsICRtZXNzYWdlKSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3NlcmlhbGl6ZWRfcmVwbGFjZV9pbnRlcm5hbCcpKToKZnVuY3Rpb24gY2xvbmVyX3NlcmlhbGl6ZWRfcmVwbGFjZV9pbnRlcm5hbChDbG9uZXJTZXJpYWxpemVkUmVhZGVyICRyLCAkc2VhcmNoLCAkY2FsbGJhY2ssICYkY291bnQpCnsKICAgICRzdGFydCA9ICRyLT5jdXJzb3I7CiAgICAkdHlwZSAgPSAkci0+cmVhZEJ5dGUoKTsKICAgIHN3aXRjaCAoJHR5cGUpIHsKICAgICAgICBjYXNlICdSJzoKICAgICAgICAgICAgLy8gUjoxOwogICAgICAgIGNhc2UgJ3InOgogICAgICAgICAgICAvLyByOjE7CiAgICAgICAgY2FzZSAnYic6CiAgICAgICAgICAgIC8vIGI6MDsKICAgICAgICAgICAgLy8gYjoxOwogICAgICAgICAgICAvKiogQG5vaW5zcGVjdGlvbiBQaHBNaXNzaW5nQnJlYWtTdGF0ZW1lbnRJbnNwZWN0aW9uICovCiAgICAgICAgY2FzZSAnaSc6CiAgICAgICAgICAgIC8vIGk6MDsKICAgICAgICAgICAgJHItPnJlYWRFeHBlY3QoJzonKTsKICAgICAgICAgICAgJHItPnJlYWRJbnQoKTsKICAgICAgICBjYXNlICdOJzoKICAgICAgICAgICAgLy8gTjsKICAgICAgICAgICAgJHItPnJlYWRFeHBlY3QoJzsnKTsKICAgICAgICAgICAgcmV0dXJuIHN1YnN0cigkci0+ZGF0YSwgJHN0YXJ0LCAkci0+Y3Vyc29yIC0gJHN0YXJ0KTsKICAgICAgICBjYXNlICdkJzoKICAgICAgICAgICAgLy8gZDoxOwogICAgICAgICAgICAvLyBkOjAuMTsKICAgICAgICAgICAgLy8gZDo5LjIyMzM3MjAzNjg1NDc3NkUrMTk7CiAgICAgICAgICAgIC8vIGQ6SU5GOwogICAgICAgICAgICAvLyBkOi1JTkY7CiAgICAgICAgICAgIC8vIGQ6TkFOOwogICAgICAgICAgICAkci0+cmVhZEV4cGVjdCgnOicpOwogICAgICAgICAgICAkci0+cmVhZEZsb2F0KCk7CiAgICAgICAgICAgICRyLT5yZWFkRXhwZWN0KCc7Jyk7CiAgICAgICAgICAgIHJldHVybiBzdWJzdHIoJHItPmRhdGEsICRzdGFydCwgJHItPmN1cnNvciAtICRzdGFydCk7CiAgICAgICAgY2FzZSAnQyc6CiAgICAgICAgICAgIC8vIEM6NToiVGVzdDIiOjY6e2Zvb2Jhcn0KICAgICAgICAgICAgJHItPnJlYWRFeHBlY3QoJzonKTsKICAgICAgICAgICAgJGNsYXNzTmFtZUxlbiA9ICRyLT5yZWFkSW50KCk7CiAgICAgICAgICAgICRyLT5yZWFkRXhwZWN0KCc6IicpOwogICAgICAgICAgICAkci0+cmVhZCgkY2xhc3NOYW1lTGVuKTsKICAgICAgICAgICAgJHItPnJlYWRFeHBlY3QoJyI6Jyk7CiAgICAgICAgICAgICRsZW4gPSAkci0+cmVhZEludCgpOwogICAgICAgICAgICAkci0+cmVhZEV4cGVjdCgnOnsnKTsKICAgICAgICAgICAgJHItPnJlYWQoJGxlbik7CiAgICAgICAgICAgICRyLT5yZWFkRXhwZWN0KCd9Jyk7CiAgICAgICAgICAgIHJldHVybiBzdWJzdHIoJHItPmRhdGEsICRzdGFydCwgJHItPmN1cnNvciAtICRzdGFydCk7CiAgICAgICAgLyoqIEBub2luc3BlY3Rpb24gUGhwTWlzc2luZ0JyZWFrU3RhdGVtZW50SW5zcGVjdGlvbiAqLwogICAgICAgIGNhc2UgJ08nOgogICAgICAgICAgICAvLyBPOjM6ImZvbyI6MTp7czo0OiJ0ZXN0IjtzOjM6ImZvbyI7fQogICAgICAgICAgICAkci0+cmVhZEV4cGVjdCgnOicpOwogICAgICAgICAgICAkY2xhc3NOYW1lTGVuID0gJHItPnJlYWRJbnQoKTsKICAgICAgICAgICAgJHItPnJlYWRFeHBlY3QoJzoiJyk7CiAgICAgICAgICAgICRyLT5yZWFkKCRjbGFzc05hbWVMZW4pOwogICAgICAgICAgICAkci0+cmVhZEV4cGVjdCgnIicpOwogICAgICAgIGNhc2UgJ2EnOgogICAgICAgICAgICAvLyBhOjE6e2k6MTtzOjM6ImZvbyI7fQogICAgICAgICAgICAkci0+cmVhZEV4cGVjdCgnOicpOwogICAgICAgICAgICAkZmllbGRzTGVuID0gJHItPnJlYWRJbnQoKTsKICAgICAgICAgICAgJHItPnJlYWRFeHBlY3QoJzp7Jyk7CiAgICAgICAgICAgICRzZXJpYWxpemVkID0gc3Vic3RyKCRyLT5kYXRhLCAkc3RhcnQsICRyLT5jdXJzb3IgLSAkc3RhcnQpOwogICAgICAgICAgICAkb2xkQ291bnQgICA9ICRjb3VudDsKICAgICAgICAgICAgZm9yICgkaSA9IDA7ICRpIDwgJGZpZWxkc0xlbjsgJGkrKykgewogICAgICAgICAgICAgICAgJHNlcmlhbGl6ZWQgLj0gY2xvbmVyX3NlcmlhbGl6ZWRfcmVwbGFjZV9pbnRlcm5hbCgkciwgJHNlYXJjaCwgbnVsbCwgJGNvdW50KTsKICAgICAgICAgICAgICAgICRzZXJpYWxpemVkIC49IGNsb25lcl9zZXJpYWxpemVkX3JlcGxhY2VfaW50ZXJuYWwoJHIsICRzZWFyY2gsICRjYWxsYmFjaywgJGNvdW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkci0+cmVhZEV4cGVjdCgnfScpOwogICAgICAgICAgICAkc2VyaWFsaXplZCAuPSAnfSc7CiAgICAgICAgICAgIGlmICgkb2xkQ291bnQgPT09ICRjb3VudCkgewogICAgICAgICAgICAgICAgLy8gTm8gcmVwbGFjZW1lbnRzIG1hZGUsIHJldHVybiBvcmlnaW5hbCBzdWJzdHJpbmcuCiAgICAgICAgICAgICAgICByZXR1cm4gc3Vic3RyKCRyLT5kYXRhLCAkc3RhcnQsICRyLT5jdXJzb3IgLSAkc3RhcnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkc2VyaWFsaXplZDsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyU2VyaWFsaXplZFJlYWRlckV4Y2VwdGlvbigkci0+Y3Vyc29yLCAidW5leHBlY3RlZCB0b2tlbjogJHR5cGUiKTsKICAgICAgICBjYXNlICdzJzoKICAgICAgICAgICAgLy8gczo0OiJ0ZXN0IjsKICAgICAgICAgICAgJHItPnJlYWRFeHBlY3QoJzonKTsKICAgICAgICAgICAgJGxlbiA9ICRyLT5yZWFkSW50KCk7CiAgICAgICAgICAgICRyLT5yZWFkRXhwZWN0KCc6IicpOwogICAgICAgICAgICAkdmFsdWUgPSAkci0+cmVhZCgkbGVuKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnUyc6CiAgICAgICAgICAgIC8vIFM6MzoiXDYxIGIiOwogICAgICAgICAgICAkci0+cmVhZEV4cGVjdCgnOicpOwogICAgICAgICAgICAkbGVuID0gJHItPnJlYWRJbnQoKTsKICAgICAgICAgICAgJHItPnJlYWRFeHBlY3QoJzoiJyk7CiAgICAgICAgICAgICR2YWx1ZSA9ICcnOwogICAgICAgICAgICB3aGlsZSAoc3RybGVuKCR2YWx1ZSkgPCAkbGVuKSB7CiAgICAgICAgICAgICAgICAkYnl0ZSA9ICRyLT5yZWFkQnl0ZSgpOwogICAgICAgICAgICAgICAgaWYgKCRieXRlID09PSAnXFwnKSB7CiAgICAgICAgICAgICAgICAgICAgJHZhbHVlIC49IGNocihpbnR2YWwoJHItPnJlYWQoMiksIDE2KSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkdmFsdWUgLj0gJGJ5dGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICAvLyBGYWxsdGhyb3VnaCAncycgYW5kICdTJyBoYW5kbGluZy4KICAgICRjb3VudFJlcGxhY2UgPSAwOwogICAgaWYgKCRjYWxsYmFjayAhPT0gbnVsbCkgewogICAgICAgICR2YWx1ZSA9IHByZWdfcmVwbGFjZV9jYWxsYmFjaygkc2VhcmNoLCAkY2FsbGJhY2ssICR2YWx1ZSwgLTEsICRjb3VudFJlcGxhY2UpOwogICAgICAgIGlmICgkdmFsdWUgPT09IG51bGwpIHsKICAgICAgICAgICAgJGVyciA9IGVycm9yX2dldF9sYXN0KCk7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJTZXJpYWxpemVkUmVhZGVyRXhjZXB0aW9uKCRyLT5jdXJzb3IsICRlcnJbJ21lc3NhZ2UnXSk7CiAgICAgICAgfQogICAgICAgICRjb3VudCArPSAkY291bnRSZXBsYWNlOwogICAgfQogICAgJHItPnJlYWRFeHBlY3QoJyI7Jyk7CiAgICBpZiAoJGNvdW50UmVwbGFjZSA9PT0gMCkgewogICAgICAgIHJldHVybiBzdWJzdHIoJHItPmRhdGEsICRzdGFydCwgJHItPmN1cnNvciAtICRzdGFydCk7CiAgICB9CiAgICByZXR1cm4gc3ByaW50ZignczolZDoiJXMiOycsIHN0cmxlbigkdmFsdWUpLCAkdmFsdWUpOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnNlcmlhbGl6ZWRyZWFkZXInLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJTZXJpYWxpemVkUmVhZGVyCnsKICAgIHB1YmxpYyAkY3Vyc29yID0gMDsKICAgIHB1YmxpYyAkZGF0YSA9ICcnOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkZGF0YSkKICAgIHsKICAgICAgICAkdGhpcy0+ZGF0YSA9ICRkYXRhOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZWFkKCRsZW4pCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jdXJzb3IgKyAkbGVuID4gc3RybGVuKCR0aGlzLT5kYXRhKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyU2VyaWFsaXplZFJlYWRlckV4Y2VwdGlvbigkdGhpcy0+Y3Vyc29yLCBzcHJpbnRmKCdleHBlY3RlZCB0byByZWFkICVkIGJ5dGVzLCBvbmx5ICVkIHJlbWFpbicsICRsZW4sIHN0cmxlbigkdGhpcy0+ZGF0YSkgLSAkdGhpcy0+Y3Vyc29yKSk7CiAgICAgICAgfQogICAgICAgICR2YWx1ZSAgICAgICAgPSBzdWJzdHIoJHRoaXMtPmRhdGEsICR0aGlzLT5jdXJzb3IsICRsZW4pOwogICAgICAgICR0aGlzLT5jdXJzb3IgKz0gJGxlbjsKICAgICAgICByZXR1cm4gJHZhbHVlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiByZWFkQnl0ZSgpCiAgICB7CiAgICAgICAgaWYgKCR0aGlzLT5jdXJzb3IgPj0gc3RybGVuKCR0aGlzLT5kYXRhKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyU2VyaWFsaXplZFJlYWRlckV4Y2VwdGlvbigkdGhpcy0+Y3Vyc29yLCAncmVhY2hlZCBlbmQgb2Ygc3RyZWFtJyk7CiAgICAgICAgfQogICAgICAgICRieXRlID0gJHRoaXMtPmRhdGFbJHRoaXMtPmN1cnNvcl07CiAgICAgICAgJHRoaXMtPmN1cnNvcisrOwogICAgICAgIHJldHVybiAkYnl0ZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVhZEludCgpCiAgICB7CiAgICAgICAgLy8gcHJlZ19tYXRjaCdzICRvZmZzZXQgb3B0aW9uIGlnbm9yZXMgXiwgc28gd2UgdXNlIGEgc3Vic3RyaW5nLgogICAgICAgIGlmICghcHJlZ19tYXRjaCgne14oWystXT9bMC05XSspfScsIHN1YnN0cigkdGhpcy0+ZGF0YSwgJHRoaXMtPmN1cnNvciksICRtYXRjaGVzKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyU2VyaWFsaXplZFJlYWRlckV4Y2VwdGlvbigkdGhpcy0+Y3Vyc29yLCAnZXhwZWN0ZWQgbnVtYmVyJyk7CiAgICAgICAgfQogICAgICAgICR0aGlzLT5jdXJzb3IgKz0gc3RybGVuKCRtYXRjaGVzWzBdKTsKICAgICAgICByZXR1cm4gaW50dmFsKCRtYXRjaGVzWzBdKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gcmVhZEZsb2F0KCkKICAgIHsKICAgICAgICAvLyBwcmVnX21hdGNoJ3MgJG9mZnNldCBvcHRpb24gaWdub3JlcyBeLCBzbyB3ZSB1c2UgYSBzdWJzdHJpbmcuCiAgICAgICAgaWYgKCFwcmVnX21hdGNoKCd7Xig/Ok5BTnwtP0lORnxbKy1dPyg/OlswLTldK1wuWzAtOV0qfFswLTldKlwuWzAtOV0rfFswLTldKykoPzpbZUVdWystXT9bMC05XSspPyl9Jywgc3Vic3RyKCR0aGlzLT5kYXRhLCAkdGhpcy0+Y3Vyc29yKSwgJG1hdGNoZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJTZXJpYWxpemVkUmVhZGVyRXhjZXB0aW9uKCR0aGlzLT5jdXJzb3IsICdleHBlY3RlZCBudW1iZXInKTsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPmN1cnNvciArPSBzdHJsZW4oJG1hdGNoZXNbMF0pOwogICAgICAgIHN3aXRjaCAoJG1hdGNoZXNbMF0pIHsKICAgICAgICAgICAgY2FzZSAnSU5GJzoKICAgICAgICAgICAgICAgIHJldHVybiBJTkY7CiAgICAgICAgICAgIGNhc2UgJy1JTkYnOgogICAgICAgICAgICAgICAgcmV0dXJuIC1JTkY7CiAgICAgICAgICAgIGNhc2UgJ05BTic7CiAgICAgICAgICAgICAgICByZXR1cm4gTkFOOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIGZsb2F0dmFsKCRtYXRjaGVzWzBdKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHJlYWRFeHBlY3QoJGV4cGVjdCkKICAgIHsKICAgICAgICAkZ290ID0gJHRoaXMtPnJlYWQoc3RybGVuKCRleHBlY3QpKTsKICAgICAgICBpZiAoJGdvdCAhPT0gJGV4cGVjdCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyU2VyaWFsaXplZFJlYWRlckV4Y2VwdGlvbigkdGhpcy0+Y3Vyc29yLCBzcHJpbnRmKCdleHBlY3RlZCAiJXMiLCBnb3QgIiVzIicsICRleHBlY3QsICRnb3QpKTsKICAgICAgICB9CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3NlcmlhbGl6ZWRfcmVwbGFjZScpKToKZnVuY3Rpb24gY2xvbmVyX3NlcmlhbGl6ZWRfcmVwbGFjZSgkc2VhcmNoLCAkZGF0YSwgJGNhbGxiYWNrLCAmJGNvdW50ID0gbnVsbCkKewogICAgaWYgKCRjb3VudCA9PT0gbnVsbCkgewogICAgICAgICRjb3VudCA9IDA7CiAgICB9CiAgICBpZiAoIWlzX3N0cmluZygkZGF0YSkgfHwgc3RybGVuKCRkYXRhKSA9PT0gMCkgewogICAgICAgIHJldHVybiAiIjsKICAgIH0KICAgIHJldHVybiBjbG9uZXJfc2VyaWFsaXplZF9yZXBsYWNlX2ludGVybmFsKG5ldyBDbG9uZXJTZXJpYWxpemVkUmVhZGVyKCRkYXRhKSwgJHNlYXJjaCwgJGNhbGxiYWNrLCAkY291bnQpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9tYXliZV9qc29uX2RlY29kZScpKToKZnVuY3Rpb24gY2xvbmVyX21heWJlX2pzb25fZGVjb2RlKCYkdmFsdWUpCnsKICAgIGlmICghaXNfc3RyaW5nKCR2YWx1ZSkpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgJHN0YXJ0c1dpdGggPSBzdWJzdHIoJHZhbHVlLCAwLCAxKTsKCiAgICBpZiAoaW5fYXJyYXkoJHN0YXJ0c1dpdGgsIGFycmF5KCdbJywgJ3snKSwgdHJ1ZSkpIHsKICAgICAgICAkbmV3VmFsdWUgPSBqc29uX2RlY29kZSgkdmFsdWUsIHRydWUpOwogICAgICAgIGlmICgkbmV3VmFsdWUgIT09IG51bGwgfHwgJHZhbHVlID09PSAnbnVsbCcpIHsKICAgICAgICAgICAgJHZhbHVlID0gJG5ld1ZhbHVlOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3N0cnVjdHVyZV93YWxrX3JlY3Vyc2l2ZScpKToKZnVuY3Rpb24gY2xvbmVyX3N0cnVjdHVyZV93YWxrX3JlY3Vyc2l2ZSgkZnVuY3Rpb24sICYkc3RydWN0dXJlLCAmJHdhbGtlZFJlZnMgPSBhcnJheSgpLCAkYXJncyA9IG51bGwpCnsKICAgICRhcmdzID0gZnVuY19nZXRfYXJncygpOwogICAgYXJyYXlfc2hpZnQoJGFyZ3MpOwogICAgYXJyYXlfc2hpZnQoJGFyZ3MpOwogICAgYXJyYXlfc2hpZnQoJGFyZ3MpOwoKICAgIHN3aXRjaCAoJHR5cGUgPSBnZXR0eXBlKCRzdHJ1Y3R1cmUpKSB7CiAgICAgICAgY2FzZSAnaW50ZWdlcic6CiAgICAgICAgY2FzZSAnYm9vbGVhbic6CiAgICAgICAgY2FzZSAnZmxvYXQnOgogICAgICAgIGNhc2UgJ2RvdWJsZSc6CiAgICAgICAgY2FzZSAnTlVMTCc6CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIGNhc2UgJ3N0cmluZyc6CiAgICAgICAgICAgIHJldHVybiBjYWxsX3VzZXJfZnVuY19hcnJheSgkZnVuY3Rpb24sIGFycmF5X21lcmdlKGFycmF5KCYkc3RydWN0dXJlKSwgJGFyZ3MpKTsKICAgICAgICAvKiogQG5vaW5zcGVjdGlvbiBQaHBNaXNzaW5nQnJlYWtTdGF0ZW1lbnRJbnNwZWN0aW9uICovCiAgICAgICAgY2FzZSAnb2JqZWN0JzoKICAgICAgICAgICAgaWYgKCRzdHJ1Y3R1cmUgaW5zdGFuY2VvZiBJdGVyYXRvcikgewogICAgICAgICAgICAgICAgLy8gUEhQIGVycm9yOiBpdGVyYXRvciBjYW5ub3QgYmUgdXNlZCB3aXRoIGZvcmVhY2ggYnkgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBIYW5kbGUgcmVjdXJzaW9uLgogICAgICAgICAgICAvLyBfX1BIUF9JbmNvbXBsZXRlX0NsYXNzIHdpbGwgcmV0dXJuIGZhbHNlIG9uIGlzX29iamVjdCgpIGNhbGwuIEx1Y2tpbHksIHdlIGNhbiBzdGlsbCBnZXQgaXRzIG9iamVjdCBoYXNoLgogICAgICAgICAgICAkb2JqZWN0SGFzaCA9IHNwbF9vYmplY3RfaGFzaCgkc3RydWN0dXJlKTsKICAgICAgICAgICAgaWYgKGlzc2V0KCR3YWxrZWRSZWZzWyRvYmplY3RIYXNoXSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR3YWxrZWRSZWZzWyRvYmplY3RIYXNoXSA9IHRydWU7CiAgICAgICAgLy8gRmFsbCB0aHJvdWdoLgogICAgICAgIGNhc2UgJ2FycmF5JzoKICAgICAgICAgICAgJHVwZGF0ZWQgPSAwOwogICAgICAgICAgICAvLyBPYmplY3QgYW5kIGFycmF5IGFyZSBieSBkZWZhdWx0IHRyYXZlcnNhYmxlLgogICAgICAgICAgICBmb3JlYWNoICgkc3RydWN0dXJlIGFzICYkdmFsdWUpIHsKICAgICAgICAgICAgICAgICR1cGRhdGVkICs9IGNhbGxfdXNlcl9mdW5jX2FycmF5KF9fRlVOQ1RJT05fXywgYXJyYXlfbWVyZ2UoYXJyYXkoJGZ1bmN0aW9uLCAmJHZhbHVlLCAmJHdhbGtlZFJlZnMpLCAkYXJncykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJHVwZGF0ZWQ7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignVW5zdXBwb3J0ZWQgc3RydWN0dXJlIHBhc3NlZDogJy4kdHlwZSwgJ3Vuc3VwcG9ydGVkX3R5cGUnKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfcHJlZ19yZXBsYWNlJykpOgpmdW5jdGlvbiBjbG9uZXJfcHJlZ19yZXBsYWNlKCYkdmFsdWUsICRzZWFyY2gsICRyZXBsYWNlKQp7CiAgICBpZiAoIWlzX3N0cmluZygkdmFsdWUpKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICAkdmFsdWUgPSBwcmVnX3JlcGxhY2VfY2FsbGJhY2soJHNlYXJjaCwgJHJlcGxhY2UsICR2YWx1ZSwgLTEsICRjb3VudCk7CiAgICByZXR1cm4gJGNvdW50Owp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl91cGRhdGVfc2VyaWFsaXplZF9maWVsZCcpKToKZnVuY3Rpb24gY2xvbmVyX3VwZGF0ZV9zZXJpYWxpemVkX2ZpZWxkKENsb25lckRCQ29ubiAkY29ubiwgJHRhYmxlLCAkaWRlbnRpZmllciwgJGZpZWxkLCAkc2VhcmNoLCAkcmVwbGFjZSwgJGRlYWRsaW5lID0gMCwgJGN1cnNvciA9IG51bGwsICR3aGVyZSA9IG51bGwpCnsKICAgICRyZWFsV2hlcmUgPSBudWxsOwogICAgaWYgKCRjdXJzb3IgIT09IG51bGwpIHsKICAgICAgICAkcmVhbFdoZXJlID0gc3ByaW50ZignV0hFUkUgYCVzYCA+ICVzJywgJGlkZW50aWZpZXIsICRjdXJzb3IpOwogICAgfQogICAgaWYgKCR3aGVyZSAhPT0gbnVsbCkgewogICAgICAgICRyZWFsV2hlcmUgPSBzdHJsZW4oJHJlYWxXaGVyZSkgPyAkcmVhbFdoZXJlLicgQU5EICcuJHdoZXJlIDogJ1dIRVJFICcuJHdoZXJlOwogICAgfQogICAgJHNxbCAgICA9IDw8PFNRTApTRUxFQ1QgYHskaWRlbnRpZmllcn1gIEFTIF9faWQsIGB7JGZpZWxkfWAgQVMgX19maWVsZAogIEZST00gYHskdGFibGV9YAogIHskcmVhbFdoZXJlfQpPUkRFUiBCWSBgeyRpZGVudGlmaWVyfWAgQVNDClNRTDsKICAgICRyZXN1bHQgPSAkY29ubi0+cXVlcnkoJHNxbCk7CiAgICAkY291bnQgID0gMDsKICAgIHdoaWxlICgkcm93ID0gJHJlc3VsdC0+ZmV0Y2goKSkgewogICAgICAgICRjdXJzb3IgPSAkcm93WydfX2lkJ107CiAgICAgICAgaWYgKCRkZWFkbGluZSAmJiB0aW1lKCkgPj0gJGRlYWRsaW5lKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheSgkY291bnQsICRjdXJzb3IsIGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgJGZpZWxkVmFsdWUgICA9ICRyb3dbJ19fZmllbGQnXTsKICAgICAgICAkaXNTZXJpYWxpemVkID0gZmFsc2U7CiAgICAgICAgaWYgKGluX2FycmF5KHN1YnN0cigkZmllbGRWYWx1ZSwgMCwgMiksIGFycmF5KCdTOicsICdzOicsICdhOicsICdPOicpLCB0cnVlKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJHVwZGF0ZWRWYWx1ZSA9IGNsb25lcl9zZXJpYWxpemVkX3JlcGxhY2UoJHNlYXJjaCwgJGZpZWxkVmFsdWUsICRyZXBsYWNlLCAkY291bnQpOwogICAgICAgICAgICAgICAgaWYgKCEkY291bnQpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRpc1NlcmlhbGl6ZWQgPSB0cnVlOwogICAgICAgICAgICB9IGNhdGNoIChDbG9uZXJTZXJpYWxpemVkUmVhZGVyRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJGlzSlNPTiA9IGZhbHNlOwogICAgICAgIGlmICghJGlzU2VyaWFsaXplZCAmJiBjbG9uZXJfbWF5YmVfanNvbl9kZWNvZGUoJGZpZWxkVmFsdWUpKSB7CiAgICAgICAgICAgICRyZWZzICAgID0gYXJyYXkoKTsKICAgICAgICAgICAgJHVwZGF0ZWQgPSBjbG9uZXJfc3RydWN0dXJlX3dhbGtfcmVjdXJzaXZlKCdjbG9uZXJfcHJlZ19yZXBsYWNlJywgJGZpZWxkVmFsdWUsICRyZWZzLCAkc2VhcmNoLCAkcmVwbGFjZSk7CiAgICAgICAgICAgIGlmICghJHVwZGF0ZWQpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR1cGRhdGVkVmFsdWUgPSBqc29uX2VuY29kZSgkZmllbGRWYWx1ZSk7CiAgICAgICAgICAgICRpc0pTT04gICAgICAgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoISRpc0pTT04gJiYgISRpc1NlcmlhbGl6ZWQpIHsKICAgICAgICAgICAgaWYgKCFjbG9uZXJfcHJlZ19yZXBsYWNlKCRmaWVsZFZhbHVlLCAkc2VhcmNoLCAkcmVwbGFjZSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgICR1cGRhdGVkVmFsdWUgPSAkZmllbGRWYWx1ZTsKICAgICAgICB9CiAgICAgICAgJHVwZGF0ZVNxbCAgICA9IHNwcmludGYoIlVQREFURSBgeyR0YWJsZX1gIFNFVCBgeyRmaWVsZH1gID0gJXMgV0hFUkUgYHskaWRlbnRpZmllcn1gID0gJXMiLCAkY29ubi0+ZXNjYXBlKCR1cGRhdGVkVmFsdWUpLCAkY29ubi0+ZXNjYXBlKCRyb3dbJ19faWQnXSkpOwogICAgICAgICR1cGRhdGVSZXN1bHQgPSAkY29ubi0+cXVlcnkoJHVwZGF0ZVNxbCk7CiAgICAgICAgJGNvdW50ICAgICAgICArPSAkdXBkYXRlUmVzdWx0LT5nZXROdW1Sb3dzKCk7CiAgICAgICAgJHVwZGF0ZVJlc3VsdC0+ZnJlZSgpOwogICAgfQogICAgJHJlc3VsdC0+ZnJlZSgpOwogICAgcmV0dXJuIGFycmF5KCRjb3VudCwgJGN1cnNvciwgdHJ1ZSk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWlncmF0ZV93b3JkcHJlc3Nfc2l0ZV91cmwnKSk6CmZ1bmN0aW9uIG1pZ3JhdGVfd29yZHByZXNzX3NpdGVfdXJsKENsb25lckRCQ29ubiAkY29ubiwgJHRpbWVvdXQsIGFycmF5ICRhcmdzLCAkc3RhdGUpCnsKICAgICRkZWFkbGluZSA9IHRpbWUoKSArICR0aW1lb3V0OwogICAgbGlzdCgkcHJlZml4LCAkb2xkVXJsLCAkbmV3VXJsKSA9ICRhcmdzOwogICAgaWYgKGVtcHR5KCRzdGF0ZSkpIHsKICAgICAgICAkc3RhdGUgICAgICAgPSBhcnJheSgKICAgICAgICAgICAgJ21pZ3JhdGlvbnMnID0+IGFycmF5KCksCiAgICAgICAgICAgICdtdWx0aXNpdGUnICA9PiBmYWxzZSwKICAgICAgICAgICAgJ2RvbmUnICAgICAgID0+IGFycmF5KCksCiAgICAgICAgICAgICdjb3VudCcgICAgICA9PiBhcnJheSgpLAogICAgICAgICAgICAnY3Vyc29yJyAgICAgPT4gYXJyYXkoKSwKICAgICAgICApOwogICAgICAgICRpc011bHRpc2l0ZSA9IChib29sKSRjb25uLT5xdWVyeSgiU0VMRUNUIHRhYmxlX25hbWUgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIFdIRVJFIHRhYmxlX3NjaGVtYSA9IDp0YWJsZV9zY2hlbWEgQU5EIHRhYmxlX25hbWUgPSA6dGFibGVfbmFtZSIsIGFycmF5KAogICAgICAgICAgICAndGFibGVfbmFtZScgICA9PiAkcHJlZml4LidibG9ncycsCiAgICAgICAgICAgICd0YWJsZV9zY2hlbWEnID0+ICRjb25uLT5nZXRDb25maWd1cmF0aW9uKCktPm5hbWUsCiAgICAgICAgKSktPmZldGNoKCk7CiAgICAgICAgJG1pZ3JhdGlvbnMgID0gYXJyYXkoYXJyYXkoMCwgJG9sZFVybCwgJG5ld1VybCkpOwogICAgICAgIGlmICgkaXNNdWx0aXNpdGUpIHsKICAgICAgICAgICAgJG9sZFJvb3RIb3N0ID0gcGFyc2VfdXJsKCRvbGRVcmwsIFBIUF9VUkxfSE9TVCk7CiAgICAgICAgICAgICRvbGRSb290UGF0aCA9IHJ0cmltKHBhcnNlX3VybCgkb2xkVXJsLCBQSFBfVVJMX1BBVEgpLCAnLycpLicvJzsKICAgICAgICAgICAgJG5ld1Jvb3RIb3N0ID0gcGFyc2VfdXJsKCRuZXdVcmwsIFBIUF9VUkxfSE9TVCk7CiAgICAgICAgICAgICRuZXdSb290UGF0aCA9IHJ0cmltKHBhcnNlX3VybCgkbmV3VXJsLCBQSFBfVVJMX1BBVEgpLCAnLycpLicvJzsKICAgICAgICAgICAgJGNvbm4tPnF1ZXJ5KCJVUERBVEUgeyRwcmVmaXh9c2l0ZSBTRVQgZG9tYWluID0gOmRvbWFpbiwgcGF0aCA9IDpwYXRoIE9SREVSIEJZIGlkIEFTQyBMSU1JVCAxIiwgYXJyYXkoCiAgICAgICAgICAgICAgICAnZG9tYWluJyA9PiAkbmV3Um9vdEhvc3QsCiAgICAgICAgICAgICAgICAncGF0aCcgICA9PiAkbmV3Um9vdFBhdGgsCiAgICAgICAgICAgICkpOwogICAgICAgICAgICAvLyBTa2lwIG1hc3RlciBzaXRlIGluIHRoZSBxdWVyeS4KICAgICAgICAgICAgJHF1ZXJ5ID0gJGNvbm4tPnF1ZXJ5KCJTRUxFQ1QgYmxvZ19pZCwgc2l0ZV9pZCwgZG9tYWluLCBwYXRoIEZST00geyRwcmVmaXh9YmxvZ3MgV0hFUkUgZGVsZXRlZD0wIik7CiAgICAgICAgICAgIHdoaWxlICgkcm93ID0gJHF1ZXJ5LT5mZXRjaCgpKSB7CiAgICAgICAgICAgICAgICAvLyBTY2hlbWUgaXMgbm90IGltcG9ydGFudCBoZXJlLCBzaW5jZSB3ZSBtaWdyYXRlIGJvdGggb2YgdGhlbS4KICAgICAgICAgICAgICAgICRvbGRCbG9nVVJMID0gJ2h0dHA6Ly8nLiRyb3dbJ2RvbWFpbiddLiRyb3dbJ3BhdGgnXTsKICAgICAgICAgICAgICAgIGxpc3QoJG5ld0hvc3QsICRuZXdQYXRoLCAkcmVwbGFjZWQpID0gY2xvbmVyX3VwZGF0ZV9tdWx0aXNpdGVfdXJsKCRvbGRSb290SG9zdCwgJG9sZFJvb3RQYXRoLCAkbmV3Um9vdEhvc3QsICRuZXdSb290UGF0aCwgJHJvd1snZG9tYWluJ10sICRyb3dbJ3BhdGgnXSk7CiAgICAgICAgICAgICAgICAkbmV3QmxvZ1VSTCA9ICdodHRwOi8vJy4kbmV3SG9zdC4kbmV3UGF0aDsKICAgICAgICAgICAgICAgIGlmICgkcmVwbGFjZWQgJiYgKCRyb3dbJ2Jsb2dfaWQnXSAhPT0gJHJvd1snc2l0ZV9pZCddKSkgewogICAgICAgICAgICAgICAgICAgICRtaWdyYXRpb25zW10gPSBhcnJheSgoaW50KSRyb3dbJ2Jsb2dfaWQnXSwgJG9sZEJsb2dVUkwsICRuZXdCbG9nVVJMKTsKICAgICAgICAgICAgICAgICAgICAvLyBBbHNvIG1pZ3JhdGUgcm9vdCBVUkxzIG9uIGV2ZXJ5IGNoaWxkIGJsb2cuCiAgICAgICAgICAgICAgICAgICAgJG1pZ3JhdGlvbnNbXSA9IGFycmF5KChpbnQpJHJvd1snYmxvZ19pZCddLCAkb2xkVXJsLCAkbmV3VXJsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghJHJlcGxhY2VkKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkY29ubi0+cXVlcnkoIlVQREFURSB7JHByZWZpeH1ibG9ncyBTRVQgZG9tYWluID0gOmRvbWFpbiwgcGF0aCA9IDpwYXRoIFdIRVJFIGJsb2dfaWQgPSA6YmxvZ19pZCIsIGFycmF5KAogICAgICAgICAgICAgICAgICAgICdkb21haW4nICA9PiBwYXJzZV91cmwoJG5ld0Jsb2dVUkwsIFBIUF9VUkxfSE9TVCksCiAgICAgICAgICAgICAgICAgICAgJ3BhdGgnICAgID0+IHBhcnNlX3VybCgkbmV3QmxvZ1VSTCwgUEhQX1VSTF9QQVRIKSwKICAgICAgICAgICAgICAgICAgICAnYmxvZ19pZCcgPT4gJHJvd1snYmxvZ19pZCddLAogICAgICAgICAgICAgICAgKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHN0YXRlWydtdWx0aXNpdGUnXSA9IHRydWU7CiAgICAgICAgfQogICAgICAgICRzdGF0ZVsnbWlncmF0aW9ucyddID0gJG1pZ3JhdGlvbnM7CiAgICB9CiAgICAkbWlncmF0ZUNvbHVtbnMgPSBhcnJheSgKICAgICAgICBhcnJheSgncG9zdG1ldGEnLCAnbWV0YV9pZCcsICdtZXRhX3ZhbHVlJyksCiAgICAgICAgYXJyYXkoJ29wdGlvbnMnLCAnb3B0aW9uX2lkJywgJ29wdGlvbl92YWx1ZScpLAogICAgICAgIGFycmF5KCdwb3N0cycsICdJRCcsICdwb3N0X2NvbnRlbnQnKSwKICAgICAgICBhcnJheSgnY29tbWVudHMnLCAnY29tbWVudF9JRCcsICdjb21tZW50X2NvbnRlbnQnKSwKICAgICk7CiAgICAkdXBkYXRlTGltaXQgICAgPSAxMDA7CiAgICBmb3JlYWNoICgkc3RhdGVbJ21pZ3JhdGlvbnMnXSBhcyAkbWlncmF0aW9uKSB7CiAgICAgICAgbGlzdCgkaWQsICRvbGRVcmwsICRuZXdVcmwpID0gJG1pZ3JhdGlvbjsKICAgICAgICAkc2l0ZVByZWZpeCAgICAgICA9ICRwcmVmaXg7CiAgICAgICAgJG9sZERvbWFpbkFuZFBhdGggPSBjbG9uZXJfdXJsX3NsdWcoJG9sZFVybCk7CiAgICAgICAgaWYgKCRpZCkgewogICAgICAgICAgICAkc2l0ZVByZWZpeCAuPSAieyRpZH1fIjsKICAgICAgICB9CiAgICAgICAgJG5ld1VSTFByZWZpeCA9IHJ0cmltKCRuZXdVcmwsICcvJykuJy8nOwogICAgICAgIGZvcmVhY2ggKGFycmF5KCdodHRwOi8vJy4kb2xkRG9tYWluQW5kUGF0aC4nLycsICdodHRwczovLycuJG9sZERvbWFpbkFuZFBhdGguJy8nLCAnaHR0cDovL3d3dy4nLiRvbGREb21haW5BbmRQYXRoLicvJywgJ2h0dHBzOi8vd3d3LicuJG9sZERvbWFpbkFuZFBhdGguJy8nKSBhcyAkb2xkVVJMUHJlZml4KSB7CiAgICAgICAgICAgIGlmICh0aW1lKCkgPj0gJGRlYWRsaW5lKSB7CiAgICAgICAgICAgICAgICAvLyBUaW1lb3V0LgogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRzdGF0ZSwgZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRrZXkgPSAkb2xkVVJMUHJlZml4LicjcG9zdHMuZ3VpZCc7CiAgICAgICAgICAgIGlmICghZW1wdHkoJHN0YXRlWydkb25lJ11bJGtleV0pKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBNaWdyYXRlIHBvc3RzIChHVUlEKQogICAgICAgICAgICAvLyBXb3JkUHJlc3MgaW5pdGlhbGx5IHVzZXMgb3B0aW9ucyB3aXRob3V0IHRoZSBsZWFkaW5nIHNsYXNoLCBidXQgYWx3YXlzIGhhcyB0aGVtIGluIEdVSUQgZmllbGRzLgogICAgICAgICAgICB3aGlsZSAoJGNvdW50ID0gY2xvbmVyX3VwZGF0ZV9maWVsZF9wcmVmaXgoJGNvbm4sICRzaXRlUHJlZml4Lidwb3N0cycsICdndWlkJywgJG9sZFVSTFByZWZpeCwgJG5ld1VSTFByZWZpeCwgJHVwZGF0ZUxpbWl0KSkgewogICAgICAgICAgICAgICAgaWYgKCFpc3NldCgkc3RhdGVbJ2NvdW50J11bJGtleV0pKSB7CiAgICAgICAgICAgICAgICAgICAgJHN0YXRlWydjb3VudCddWyRrZXldID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRzdGF0ZVsnY291bnQnXVska2V5XSArPSAkY291bnQ7CiAgICAgICAgICAgICAgICBpZiAoJGNvdW50IDwgJHVwZGF0ZUxpbWl0KSB7CiAgICAgICAgICAgICAgICAgICAgLy8gV2UgZGlkbid0IHJlYWNoIHRoZSB1cGRhdGUgY291bnQgbGltaXQsIG1lYW5pbmcgd2UncmUgZG9uZSB3aXRoIHRoaXMgbWlncmF0aW9uLgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHRpbWUoKSA+PSAkZGVhZGxpbmUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBUaW1lb3V0LgogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkc3RhdGUsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkc3RhdGVbJ2RvbmUnXVska2V5XSA9IHRydWU7CiAgICAgICAgfQogICAgICAgICRzZWFyY2ggICAgICAgICAgICAgICAgICAgPSAneyhodHRwcz86KT8vLyg/Ond3d1wuKT8nLnByZWdfcXVvdGUoJG9sZERvbWFpbkFuZFBhdGgpLicoLz8pfWknOwogICAgICAgICRyZXBsYWNlciAgICAgICAgICAgICAgICAgPSBuZXcgQ2xvbmVyVVJMUmVwbGFjZXIocnRyaW0oJG5ld1VybCwgJy8nKSk7CiAgICAgICAgJHJlcGxhY2UgICAgICAgICAgICAgICAgICA9IGFycmF5KCRyZXBsYWNlciwgJ3JlcGxhY2UnKTsKICAgICAgICAkbGlrZU9sZERvbWFpbkFuZFBhdGggICAgID0gJGNvbm4tPmVzY2FwZSgnJScuY2xvbmVyX2VzY2FwZV9saWtlKCRvbGREb21haW5BbmRQYXRoKS4nJScpOwogICAgICAgICRsaWtlT2xkRG9tYWluQW5kUGF0aEpTT04gPSAkY29ubi0+ZXNjYXBlKCclJy5jbG9uZXJfZXNjYXBlX2xpa2Uoc3Vic3RyKGpzb25fZW5jb2RlKCRvbGREb21haW5BbmRQYXRoKSwgMSwgLTEpKS4nJScpOwogICAgICAgIGZvcmVhY2ggKCRtaWdyYXRlQ29sdW1ucyBhcyAkbWlncmF0aW9uRGF0YSkgewogICAgICAgICAgICBpZiAodGltZSgpID49ICRkZWFkbGluZSkgewogICAgICAgICAgICAgICAgLy8gVGltZW91dC4KICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkc3RhdGUsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsaXN0KCR0YWJsZSwgJGlkZW50aWZpZXIsICRmaWVsZCkgPSAkbWlncmF0aW9uRGF0YTsKICAgICAgICAgICAgJGtleSA9ICRvbGRVcmwuJyMnLiR0YWJsZS4nLicuJGZpZWxkOwogICAgICAgICAgICBpZiAoIWVtcHR5KCRzdGF0ZVsnZG9uZSddWyRrZXldKSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHdoZXJlICA9IHNwcmludGYoJyhgJXNgIExJS0UgJXMgT1IgYCVzYCBMSUtFICVzKScsICRmaWVsZCwgJGxpa2VPbGREb21haW5BbmRQYXRoLCAkZmllbGQsICRsaWtlT2xkRG9tYWluQW5kUGF0aEpTT04pOwogICAgICAgICAgICAkY3Vyc29yID0gQCRzdGF0ZVsnY3Vyc29yJ11bJGtleV07CiAgICAgICAgICAgIGxpc3QoJGNvdW50LCAkY3Vyc29yLCAkZmluaXNoZWQpID0gY2xvbmVyX3VwZGF0ZV9zZXJpYWxpemVkX2ZpZWxkKCRjb25uLCAkc2l0ZVByZWZpeC4kdGFibGUsICRpZGVudGlmaWVyLCAkZmllbGQsICRzZWFyY2gsICRyZXBsYWNlLCAkZGVhZGxpbmUsICRjdXJzb3IsICR3aGVyZSk7CiAgICAgICAgICAgICRzdGF0ZVsnY3Vyc29yJ11bJGtleV0gPSAkY3Vyc29yOwogICAgICAgICAgICBpZiAoIWlzc2V0KCRzdGF0ZVsnY291bnQnXVska2V5XSkpIHsKICAgICAgICAgICAgICAgICRzdGF0ZVsnY291bnQnXVska2V5XSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHN0YXRlWydjb3VudCddWyRrZXldICs9ICRjb3VudDsKICAgICAgICAgICAgaWYgKCEkZmluaXNoZWQpIHsKICAgICAgICAgICAgICAgIC8vIFdlIGhpdCBkZWFkbGluZS4KICAgICAgICAgICAgICAgIHJldHVybiBhcnJheSgkc3RhdGUsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkc3RhdGVbJ2RvbmUnXVska2V5XSA9IHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFycmF5KCRzdGF0ZSwgdHJ1ZSk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnbWlncmF0ZV92YnVsbGV0aW5fc2l0ZV91cmwnKSk6CmZ1bmN0aW9uIG1pZ3JhdGVfdmJ1bGxldGluX3NpdGVfdXJsKENsb25lckRCQ29ubiAkY29ubiwgJHRpbWVvdXQsIGFycmF5ICRhcmdzLCAkc3RhdGUpCnsKICAgIGxpc3QoJHByZWZpeCkgPSAkYXJnczsKICAgICRjb25uLT5xdWVyeSgiVVBEQVRFIHskcHJlZml4fWRhdGFzdG9yZSBTRVQgZGF0YSA9IDpkYXRhIFdIRVJFIHRpdGxlID0gOm9wdGlvbnMgT1IgdGl0bGUgPSA6cHVibGljb3B0aW9ucyIgLCBhcnJheSgKICAgICAgICAnZGF0YScgICAgICAgICAgICA9PiAiIiwKICAgICAgICAnb3B0aW9ucycgICAgICAgICA9PiAib3B0aW9ucyIsCiAgICAgICAgJ3B1YmxpY29wdGlvbnMnICAgPT4gInB1YmxpY29wdGlvbnMiLAogICAgKSk7CiAgICByZXR1cm4gYXJyYXkoJHN0YXRlLCB0cnVlKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfbWlncmF0ZV9zaXRlX3VybCcpKToKZnVuY3Rpb24gY2xvbmVyX21pZ3JhdGVfc2l0ZV91cmwoQ2xvbmVyREJDb25uICRjb25uLCAkdGltZW91dCwgYXJyYXkgJGFyZ3MsICRzdGF0ZSwgJGNtcykKewogICAgc3dpdGNoICgkY21zKSB7CiAgICAgICAgY2FzZSAnd29yZHByZXNzJzoKICAgICAgICAgICAgcmV0dXJuIG1pZ3JhdGVfd29yZHByZXNzX3NpdGVfdXJsKCRjb25uLCAkdGltZW91dCwgJGFyZ3MsICRzdGF0ZSk7CiAgICAgICAgY2FzZSAndmJ1bGxldGluJzoKICAgICAgICAgICAgcmV0dXJuIG1pZ3JhdGVfdmJ1bGxldGluX3NpdGVfdXJsKCRjb25uLCAkdGltZW91dCwgJGFyZ3MsICRzdGF0ZSk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCRzdGF0ZSwgdHJ1ZSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl9taWdyYXRlX2RhdGFiYXNlJykpOgpmdW5jdGlvbiBjbG9uZXJfYWN0aW9uX21pZ3JhdGVfZGF0YWJhc2UoJGRiLCAkY21zLCAkdGltZW91dCwgYXJyYXkgJHN0YXRlKQp7CiAgICAkY29ubiA9IGNsb25lcl9kYl9jb25uKCRkYik7CiAgICBmb3JlYWNoICgkc3RhdGUgYXMgJGtleSA9PiAmJG1pZ3JhdGlvbikgewogICAgICAgIGlmICgkbWlncmF0aW9uWydkb25lJ10pIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAoJG1pZ3JhdGlvblsnZm4nXSkgewogICAgICAgICAgICBjYXNlICdjbG9uZXJfbWlncmF0ZV90YWJsZV9wcmVmaXgnOgogICAgICAgICAgICAgICAgbGlzdCgkbWlncmF0aW9uWydzdGF0ZSddLCAkbWlncmF0aW9uWydkb25lJ10pID0gY2xvbmVyX21pZ3JhdGVfdGFibGVfcHJlZml4KCRjb25uLCAkdGltZW91dCwgKGFycmF5KUAkbWlncmF0aW9uWydhcmdzJ10sIEAkbWlncmF0aW9uWydzdGF0ZSddLCAkY21zKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdjbG9uZXJfbWlncmF0ZV9zaXRlX3VybCc6CiAgICAgICAgICAgICAgICBsaXN0KCRtaWdyYXRpb25bJ3N0YXRlJ10sICRtaWdyYXRpb25bJ2RvbmUnXSkgPSBjbG9uZXJfbWlncmF0ZV9zaXRlX3VybCgkY29ubiwgJHRpbWVvdXQsIChhcnJheSlAJG1pZ3JhdGlvblsnYXJncyddLCBAJG1pZ3JhdGlvblsnc3RhdGUnXSwgJGNtcyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oc3ByaW50ZignVW5rbm93biBtaWdyYXRpb24gZnVuY3Rpb246ICVzJywgJG1pZ3JhdGlvblsnZm4nXSkpOwogICAgICAgIH0KICAgICAgICBpZiAoJG1pZ3JhdGlvblsnZG9uZSddKSB7CiAgICAgICAgICAgIC8vIFRpbWVvdXQgcmVhY2hlZCBvbiBhIG1pZ3JhdGlvbi4KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFycmF5KCdzdGF0ZScgPT4gJHN0YXRlKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfYWN0aW9uX2NsZWFudXAnKSk6CmZ1bmN0aW9uIGNsb25lcl9hY3Rpb25fY2xlYW51cCgkcm9vdCkKewogICAgJGVycnMgICAgID0gYXJyYXkoKTsKICAgICRlcnJvckxvZyA9IEBmaWxlX2dldF9jb250ZW50cygiJHJvb3QvY2xvbmVyX2Vycm9yX2xvZyIsIGZhbHNlLCBudWxsLCAwLCAxIDw8IDIwKTsKICAgIGlmICgkZXJyb3JMb2cgPT09IGZhbHNlKSB7CiAgICAgICAgJGVycm9yTG9nID0gImNvdWxkIG5vdCBmZXRjaCBjbG9uZXJfZXJyb3JfbG9nOiAiLmNsb25lcl9sYXN0X2Vycm9yX2ZvcignZmlsZV9nZXRfY29udGVudHMnKTsKICAgIH0KICAgICRkdW1wRGlyID0gJHJvb3QuJy9td3BfZGInOwogICAgJGR1bXBzICAgPSBpc19kaXIoJGR1bXBEaXIpID8gQHNjYW5kaXIoJGR1bXBEaXIpIDogYXJyYXkoKTsKICAgIGlmICghaXNfYXJyYXkoJGR1bXBzKSkgewogICAgICAgICRkdW1wcyAgPSBhcnJheSgpOwogICAgICAgICRlcnJzW10gPSBhcnJheSgnbXdwX2RiJywgY2xvbmVyX2xhc3RfZXJyb3JfZm9yKCdzY2FuZGlyJykpOwogICAgfSBlbHNlIHsKICAgICAgICAkZHVtcHMgPSBhcnJheV92YWx1ZXMoYXJyYXlfZmlsdGVyKCRkdW1wcywgJ2Nsb25lcl9pc19ub3RfZG90JykpOwogICAgICAgIGZvcmVhY2ggKCRkdW1wcyBhcyAkaSA9PiAkZHVtcCkgewogICAgICAgICAgICAkZHVtcHNbJGldID0gIm13cF9kYi8kZHVtcCI7CiAgICAgICAgfQogICAgICAgIC8vIFJlbW92ZSB0aGUgZGlyZWN0b3J5IGl0c2VsZi4KICAgICAgICAkZHVtcHNbXSA9ICdtd3BfZGInOwogICAgfQogICAgJGZpbGVzID0gYXJyYXlfbWVyZ2UoJGR1bXBzLCBhcnJheSgnY2xvbmVyX2Vycm9yX2xvZycsICdjbG9uZXIucGhwJykpOwogICAgZm9yZWFjaCAoJGZpbGVzIGFzICRmaWxlKSB7CiAgICAgICAgJGVyciA9IGNsb25lcl9yZW1vdmVfZmlsZV9vcl9kaXIoJHJvb3QuJy8nLiRmaWxlKTsKICAgICAgICBpZiAoc3RybGVuKCRlcnIpKSB7CiAgICAgICAgICAgICRlcnJzW10gPSBhcnJheSgkZmlsZSwgJGVycik7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFycmF5KAogICAgICAgICdvaycgICAgICAgPT4gZW1wdHkoJGVycnMpLAogICAgICAgICdlcnJvcnMnICAgPT4gJGVycnMsCiAgICAgICAgJ2Vycm9yTG9nJyA9PiAkZXJyb3JMb2csCiAgICApOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnNpdGVzb3VyY2UnLCBmYWxzZSkpOgppbnRlcmZhY2UgQ2xvbmVyU2l0ZVNvdXJjZQp7CiAgICAvKioKICAgICAqIEByZXR1cm4gc3RyaW5nIENNUyB0eXBlLCBlZy4gIndvcmRwcmVzcyIsICJkcnVwYWwiLCAic3RhdGljIi4KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIGdldENNUygpOwoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgJHJvb3QKICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICR1cmwKICAgICAqIEBwYXJhbSBhcnJheXxudWxsICRkYiAgICAgICAgICAgIERCIGluZm8gZnJvbSBzb3VyY2UsIG1pZ2h0IGJlIGVtcHR5LgogICAgICogQHBhcmFtIHN0cmluZyAgICAgJHRhYmxlUHJlZml4ICAgVGFibGUgcHJlZml4IGZyb20gc291cmNlLCBtaWdodCBiZSBlbXB0eS4KICAgICAqIEBwYXJhbSBib29sICAgICAgICRmb3JjZVByZWZpeCAgIFRhYmxlIHByZWZpeCBmcm9tIHNvdXJjZSwgbWlnaHQgYmUgZW1wdHkuCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAkY29uZmlnQ29udGVudCB3cC1jb25maWcucGhwIGZyb20gc291cmNlLCBtaWdodCBiZSBlbXB0eS4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICRyZWFkT25seSAgICAgIEFsbG93cyB0byBjb21wbGV0ZSBzZXR1cCB3aGVuIGNvbmZpZyBmaWxlIGRvZXNuJ3QgZXhpdCBvbiBzZXJ2ZXIKICAgICAqCiAgICAgKiBAcmV0dXJuIENsb25lclNldHVwUmVzdWx0CiAgICAgKiBAdGhyb3dzIENsb25lckV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0dXAoJHJvb3QsICR1cmwsICRkYiwgJHRhYmxlUHJlZml4LCAkZm9yY2VQcmVmaXgsICRjb25maWdDb250ZW50LCAkcmVhZE9ubHkpOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnNldHVwcmVzdWx0JywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyU2V0dXBSZXN1bHQKewogICAgLyoqIEB2YXIgYXJyYXl8bnVsbCAqLwogICAgcHVibGljICRkYjsKICAgIC8qKiBAdmFyIENsb25lclNpdGVJbmZvfG51bGwgKi8KICAgIHB1YmxpYyAkc2l0ZTsKICAgIC8qKiBAdmFyIENsb25lckVudkluZm98bnVsbCAqLwogICAgcHVibGljICRlbnY7CiAgICAvKiogQHZhciBhcnJheSBzZXR1cEVycm9yOnN0cmluZywgc2V0dXBFcnJvckNvZGU6c3RyaW5nICovCiAgICAvKiogQHZhciBhcnJheSBNYXAgaW4gdGhlIGZvcm1hdCBvcHRpb25OYW1lOnN0cmluZyA9PiBvcHRpb25WYWx1ZTpzdHJpbmcgKi8KICAgIHB1YmxpYyAka2VlcE9wdGlvbnMgPSBhcnJheSgpOwogICAgLyoqIEB2YXIgYm9vbCAqLwogICAgcHVibGljICRub1JlbGF5ID0gZmFsc2U7CiAgICAvKiogQHZhciBib29sICovCiAgICBwdWJsaWMgJHdvcmtlck9LID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBDbG9uZXJTZXR1cFJlc3VsdCBjb25zdHJ1Y3Rvci4KICAgICAqIEBwYXJhbSBhcnJheXxDbG9uZXJEQkluZm9bXXxudWxsICRkYkluZm8KICAgICAqIEBwYXJhbSBDbG9uZXJTaXRlSW5mbyAgICAgICAgICAgICRzaXRlSW5mbwogICAgICogQHBhcmFtIENsb25lckVudkluZm8gICAgICAgICAgICAgJGVudkluZm8KICAgICAqIEBwYXJhbSBhcnJheSAgICAgICAgICAgICAgICAgICAgICRrZWVwT3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGRiSW5mbyA9IG51bGwsIENsb25lclNpdGVJbmZvICRzaXRlSW5mbywgQ2xvbmVyRW52SW5mbyAkZW52SW5mbywgYXJyYXkgJGtlZXBPcHRpb25zID0gYXJyYXkoKSkKICAgIHsKICAgICAgICAkdGhpcy0+ZGIgICAgICAgICAgPSAkZGJJbmZvOwogICAgICAgICR0aGlzLT5zaXRlICAgICAgICA9ICRzaXRlSW5mbzsKICAgICAgICAkdGhpcy0+ZW52ICAgICAgICAgPSAkZW52SW5mbzsKICAgICAgICAkdGhpcy0+a2VlcE9wdGlvbnMgPSAka2VlcE9wdGlvbnM7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHRvQXJyYXkoKQogICAgewogICAgICAgICRzaXRlSW5mbyAgICAgICAgPSAkdGhpcy0+c2l0ZS0+dG9BcnJheSgpOwogICAgICAgICRzaXRlSW5mb1snY21zJ10gPSAkdGhpcy0+c2l0ZS0+Z2V0Q01TKCk7CiAgICAgICAgZm9yZWFjaCAoJHRoaXMtPmRiIGFzICRrID0+ICR2KSB7CiAgICAgICAgICAgIGlmICgkdiBpbnN0YW5jZW9mIENsb25lckRCSW5mbykgewogICAgICAgICAgICAgICAgJHRoaXMtPmRiWyRrXSA9ICR2LT50b0FycmF5KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAnb2snICAgICAgICAgID0+IHRydWUsCiAgICAgICAgICAgICdzaXRlJyAgICAgICAgPT4gJHNpdGVJbmZvLAogICAgICAgICAgICAnZGInICAgICAgICAgID0+ICR0aGlzLT5kYiwKICAgICAgICAgICAgJ2VudicgICAgICAgICA9PiAkdGhpcy0+ZW52LT50b0FycmF5KCksCiAgICAgICAgICAgICdrZWVwT3B0aW9ucycgPT4gJHRoaXMtPmtlZXBPcHRpb25zID8gJHRoaXMtPmtlZXBPcHRpb25zIDogbnVsbCwKICAgICAgICAgICAgJ2Nsb25lck9LJyAgICA9PiAhJHRoaXMtPm5vUmVsYXksCiAgICAgICAgICAgICd3b3JrZXJPSycgICAgPT4gJHRoaXMtPndvcmtlck9LLAogICAgICAgICk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX21lcmdlX2RiX2luZm8nKSk6CmZ1bmN0aW9uIGNsb25lcl9tZXJnZV9kYl9pbmZvKGFycmF5ICRwcm92aWRlZCwgYXJyYXkgJGRldGVjdGVkLCAkaXNTb3VyY2UpCnsKICAgICRyZXN1bHQgICAgICAgPSBhcnJheSgpOwogICAgJG92ZXJyaWRlSG9zdCA9ICcnOwogICAgZm9yZWFjaCAoJHByb3ZpZGVkIGFzICRkYikgewogICAgICAgICRkYiA9IENsb25lckRCSW5mbzo6ZnJvbUFycmF5KCRkYik7CiAgICAgICAgaWYgKGVtcHR5KCRkYi0+bmFtZSkpIHsKICAgICAgICAgICAgJG92ZXJyaWRlSG9zdCA9ICRkYi0+aG9zdDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRyZXN1bHRbJGRiLT5nZXRJRCgpXSA9ICRkYjsKICAgIH0KCiAgICAvL1B1dCBkZXRlY3RlZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0CiAgICBpZiAoY291bnQoJGRldGVjdGVkKSAmJiBjb3VudCgkcmVzdWx0KSA+IDEgJiYgYXJyYXlfa2V5X2V4aXN0cygkZGV0ZWN0ZWRbMF0tPmdldElEKCksICRyZXN1bHQpKSB7CiAgICAgICAgcmVzZXQoJHJlc3VsdCk7CiAgICAgICAgaWYgKGtleSgkcmVzdWx0KSAhPT0gJGRldGVjdGVkWzBdLT5nZXRJRCgpKSB7CiAgICAgICAgICAgIHVuc2V0KCRyZXN1bHRbJGRldGVjdGVkWzBdLT5nZXRJRCgpXSk7CiAgICAgICAgICAgICRyZXN1bHQgPSBhcnJheSgkZGV0ZWN0ZWRbMF0tPmdldElEKCkgPT4gJGRldGVjdGVkWzBdKSArICRyZXN1bHQ7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjb3VudCgkcmVzdWx0KSAmJiAhJGlzU291cmNlKSB7CiAgICAgICAgLy8gQWx3YXlzIHVzZSBwcm92aWRlZCBjcmVkZW50aWFscyBvbiBkZXN0aW5hdGlvbi4KICAgICAgICByZXR1cm4gYXJyYXlfdmFsdWVzKCRyZXN1bHQpOwogICAgfQogICAgaWYgKCRpc1NvdXJjZSAmJiBjb3VudCgkcmVzdWx0KSAmJiBjb3VudCgkZGV0ZWN0ZWQpKSB7CiAgICAgICAgLy8gRmFsbGJhY2sgLSBpZiBwcm92aWRlZCBjcmVkZW50aWFscyBkbyBub3Qgd29yayBvbiBzb3VyY2UsIHVzZSBkZXRlY3RlZCBvbmVzLgogICAgICAgIHdoaWxlIChjb3VudCgkcmVzdWx0KSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgY2xvbmVyX2RiX2Nvbm4oYXJyYXlfdmFsdWVzKCRyZXN1bHQpKS0+cGluZygpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgYXJyYXlfc2hpZnQoJHJlc3VsdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBBdHRhY2ggYXV0by1kZXRlY3RlZCBkYXRhYmFzZXMgdG8gcHJvdmlkZWQgb25lcy4KICAgIGZvcmVhY2ggKCRkZXRlY3RlZCBhcyAkZGIpIHsKICAgICAgICAkZGIgPSBDbG9uZXJEQkluZm86OmZyb21BcnJheSgkZGIpOwogICAgICAgIGlmIChzdHJsZW4oJG92ZXJyaWRlSG9zdCkpIHsKICAgICAgICAgICAgJGRiLT5ob3N0ICAgICA9ICRvdmVycmlkZUhvc3Q7CiAgICAgICAgICAgICRvdmVycmlkZUhvc3QgPSAnJzsKICAgICAgICB9CiAgICAgICAgJHJlc3VsdFskZGItPmdldElEKCldID0gJGRiOwogICAgfQogICAgcmV0dXJuIGFycmF5X3ZhbHVlcygkcmVzdWx0KTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZGJfaW5mb19mcm9tX3dvcmtlcicpKToKZnVuY3Rpb24gY2xvbmVyX2RiX2luZm9fZnJvbV93b3JrZXIoJGlzU291cmNlLCBhcnJheSAkZGJPdmVycmlkZXMgPSBudWxsKQp7CiAgICBmb3JlYWNoIChhcnJheSgnREJfVVNFUicsICdEQl9QQVNTV09SRCcsICdEQl9IT1NUJywgJ0RCX05BTUUnKSBhcyAkY29uc3RhbnQpIHsKICAgICAgICBpZiAoIWRlZmluZWQoJGNvbnN0YW50KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyTm9Db25zdGFudEV4Y2VwdGlvbigkY29uc3RhbnQpOwogICAgICAgIH0KICAgIH0KCiAgICAkdXNlU1NMID0gZmFsc2U7CiAgICBpZiAoZGVmaW5lZCgnREJfU1NMJykpIHsKICAgICAgICAkdXNlU1NMID0gKGJvb2wpREJfU1NMOwogICAgfQoKICAgIC8qKiBAbm9pbnNwZWN0aW9uIFBocFVuZGVmaW5lZENvbnN0YW50SW5zcGVjdGlvbiAqLwogICAgJGRldGVjdGVkID0gYXJyYXkobmV3IENsb25lckRCSW5mbyhEQl9VU0VSLCBEQl9QQVNTV09SRCwgREJfSE9TVCwgREJfTkFNRSwgJHVzZVNTTCkpOwogICAgcmV0dXJuIGNsb25lcl9tZXJnZV9kYl9pbmZvKChhcnJheSkkZGJPdmVycmlkZXMsICRkZXRlY3RlZCwgJGlzU291cmNlKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfY3R5cGVfYWxwaGEnKSk6CmZ1bmN0aW9uIGNsb25lcl9jdHlwZV9hbHBoYSgkdGV4dCkgewogICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnY3R5cGVfYWxwaGEnKSkgewogICAgICAgIHJldHVybiBjdHlwZV9hbHBoYSgkdGV4dCk7CiAgICB9CiAgICByZXR1cm4gKGJvb2wpcHJlZ19tYXRjaCgne15bYS16XSskfWknLCAkdGV4dCk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2lzX3BhdGhfYWJzb2x1dGUnKSk6CmZ1bmN0aW9uIGNsb25lcl9pc19wYXRoX2Fic29sdXRlKCRmaWxlKQp7CiAgICByZXR1cm4gc3Ryc3BuKCRmaWxlLCAnL1xcJywgMCwgMSkKICAgICAgICB8fCAoc3RybGVuKCRmaWxlKSA+IDMgJiYgY2xvbmVyX2N0eXBlX2FscGhhKCRmaWxlWzBdKQogICAgICAgICAgICAmJiAnOicgPT09ICRmaWxlWzFdCiAgICAgICAgICAgICYmIHN0cnNwbigkZmlsZSwgJy9cXCcsIDIsIDEpCiAgICAgICAgKQogICAgICAgIHx8IG51bGwgIT09IHBhcnNlX3VybCgkZmlsZSwgUEhQX1VSTF9TQ0hFTUUpOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnJlYWxwYXRoZXhjZXB0aW9uJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyUmVhbFBhdGhFeGNlcHRpb24gZXh0ZW5kcyBDbG9uZXJFeGNlcHRpb24KewogICAgcHVibGljICRwYXRoOwoKICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkcGF0aCkKICAgIHsKICAgICAgICAkdGhpcy0+cGF0aCA9ICRwYXRoOwogICAgICAgIHBhcmVudDo6X19jb25zdHJ1Y3QoIlRoZSBwYXRoICRwYXRoIGNvdWxkIG5vdCBiZSByZXNvbHZlZCBvbiB0aGUgZmlsZXN5c3RlbSIsICdyZWFscGF0aF9lbXB0eScpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9yZWFscGF0aCcpKToKZnVuY3Rpb24gY2xvbmVyX3JlYWxwYXRoKCRwYXRoKQp7CiAgICAkcmVhbCA9IHJlYWxwYXRoKCRwYXRoKTsKICAgIGlmICgkcmVhbCA9PT0gZmFsc2UpIHsKICAgICAgICBpZiAoY2xvbmVyX2lzX3BhdGhfYWJzb2x1dGUoJHBhdGgpKSB7CiAgICAgICAgICAgIHJldHVybiAkcGF0aDsKICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IENsb25lclJlYWxQYXRoRXhjZXB0aW9uKCRwYXRoKTsKICAgIH0KICAgIHJldHVybiAkcmVhbDsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZW52X2ZpbmRfd3BfY29uZmlnJykpOgpmdW5jdGlvbiBjbG9uZXJfZW52X2ZpbmRfd3BfY29uZmlnKCkKewogICAgJHRhaWwgPSBESVJFQ1RPUllfU0VQQVJBVE9SLid3cC1jb25maWcucGhwJzsKICAgICRsZW4gID0gc3RybGVuKCR0YWlsKTsKICAgIGZvcmVhY2ggKGdldF9pbmNsdWRlZF9maWxlcygpIGFzICRmaWxlKSB7CiAgICAgICAgLy8gaHR0cHM6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD02NzA0MwogICAgICAgIGlmIChzdWJzdHJfY29tcGFyZSgkZmlsZSwgJHRhaWwsIC0kbGVuLCAkbGVuKSkgewogICAgICAgICAgICByZXR1cm4gJGZpbGU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIG51bGw7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3N0cmlwX3BhdGhfZHJpdmVfbGV0dGVyJykpOgpmdW5jdGlvbiBjbG9uZXJfc3RyaXBfcGF0aF9kcml2ZV9sZXR0ZXIoJHBhdGgpCnsKICAgIGlmIChzdHJsZW4oJHBhdGgpID4gMiAmJiAnOicgPT09ICRwYXRoWzFdICYmICcvJyA9PT0gJHBhdGhbMl0gJiYgY2xvbmVyX2N0eXBlX2FscGhhKCRwYXRoWzBdKSkgewogICAgICAgIHJldHVybiBzdWJzdHIoJHBhdGgsIDIpOwogICAgfQogICAgcmV0dXJuICRwYXRoOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9ub3JtYWxpemVfcGF0aF9hcnJheScpKToKZnVuY3Rpb24gY2xvbmVyX25vcm1hbGl6ZV9wYXRoX2FycmF5KCRwYXRoU2VnbWVudHMpCnsKICAgICRyZXN1bHQgPSBhcnJheSgpOwogICAgZm9yZWFjaCAoJHBhdGhTZWdtZW50cyBhcyAkc2VnbWVudCkgewogICAgICAgIGlmICgnLi4nID09PSAkc2VnbWVudCkgewogICAgICAgICAgICBhcnJheV9wb3AoJHJlc3VsdCk7CiAgICAgICAgfSBlbHNlaWYgKCcuJyAhPT0gJHNlZ21lbnQpIHsKICAgICAgICAgICAgJHJlc3VsdFtdID0gJHNlZ21lbnQ7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuICRyZXN1bHQ7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX21ha2VfcGF0aF9yZWxhdGl2ZScpKToKZnVuY3Rpb24gY2xvbmVyX21ha2VfcGF0aF9yZWxhdGl2ZSgkZW5kUGF0aCwgJHN0YXJ0UGF0aCkKewogICAgaWYgKCFjbG9uZXJfaXNfcGF0aF9hYnNvbHV0ZSgkc3RhcnRQYXRoKSkgewogICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oc3ByaW50ZignVGhlIHN0YXJ0IHBhdGggIiVzIiBpcyBub3QgYWJzb2x1dGUuJywgJHN0YXJ0UGF0aCkpOwogICAgfQogICAgaWYgKCFjbG9uZXJfaXNfcGF0aF9hYnNvbHV0ZSgkZW5kUGF0aCkpIHsKICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoJ1RoZSBlbmQgcGF0aCAiJXMiIGlzIG5vdCBhYnNvbHV0ZS4nLCAkZW5kUGF0aCkpOwogICAgfQoKICAgIC8vIE5vcm1hbGl6ZSBzZXBhcmF0b3JzIG9uIFdpbmRvd3MKICAgIGlmICgnXFwnID09PSBESVJFQ1RPUllfU0VQQVJBVE9SKSB7CiAgICAgICAgJGVuZFBhdGggICA9IHN0cl9yZXBsYWNlKCdcXCcsICcvJywgJGVuZFBhdGgpOwogICAgICAgICRzdGFydFBhdGggPSBzdHJfcmVwbGFjZSgnXFwnLCAnLycsICRzdGFydFBhdGgpOwogICAgfQogICAgJGVuZFBhdGggICA9IGNsb25lcl9zdHJpcF9wYXRoX2RyaXZlX2xldHRlcigkZW5kUGF0aCk7CiAgICAkc3RhcnRQYXRoID0gY2xvbmVyX3N0cmlwX3BhdGhfZHJpdmVfbGV0dGVyKCRzdGFydFBhdGgpOwogICAgLy8gU3BsaXQgdGhlIHBhdGhzIGludG8gYXJyYXlzCiAgICAkc3RhcnRQYXRoQXJyID0gZXhwbG9kZSgnLycsIHRyaW0oJHN0YXJ0UGF0aCwgJy8nKSk7CiAgICAkZW5kUGF0aEFyciAgID0gZXhwbG9kZSgnLycsIHRyaW0oJGVuZFBhdGgsICcvJykpOwogICAgJHN0YXJ0UGF0aEFyciA9IGNsb25lcl9ub3JtYWxpemVfcGF0aF9hcnJheSgkc3RhcnRQYXRoQXJyKTsKICAgICRlbmRQYXRoQXJyICAgPSBjbG9uZXJfbm9ybWFsaXplX3BhdGhfYXJyYXkoJGVuZFBhdGhBcnIpOwogICAgLy8gRmluZCBmb3Igd2hpY2ggZGlyZWN0b3J5IHRoZSBjb21tb24gcGF0aCBzdG9wcwogICAgJGluZGV4ID0gMDsKICAgIHdoaWxlIChpc3NldCgkc3RhcnRQYXRoQXJyWyRpbmRleF0pICYmIGlzc2V0KCRlbmRQYXRoQXJyWyRpbmRleF0pICYmICRzdGFydFBhdGhBcnJbJGluZGV4XSA9PT0gJGVuZFBhdGhBcnJbJGluZGV4XSkgewogICAgICAgICsrJGluZGV4OwogICAgfQogICAgLy8gRGV0ZXJtaW5lIGhvdyBkZWVwIHRoZSBzdGFydCBwYXRoIGlzIHJlbGF0aXZlIHRvIHRoZSBjb21tb24gcGF0aCAoaWUsICJ3ZWIvYnVuZGxlcyIgPSAyIGxldmVscykKICAgIGlmICgxID09PSBjb3VudCgkc3RhcnRQYXRoQXJyKSAmJiAnJyA9PT0gJHN0YXJ0UGF0aEFyclswXSkgewogICAgICAgICRkZXB0aCA9IDA7CiAgICB9IGVsc2UgewogICAgICAgICRkZXB0aCA9IGNvdW50KCRzdGFydFBhdGhBcnIpIC0gJGluZGV4OwogICAgfQogICAgLy8gUmVwZWF0ZWQgIi4uLyIgZm9yIGVhY2ggbGV2ZWwgbmVlZCB0byByZWFjaCB0aGUgY29tbW9uIHBhdGgKICAgICR0cmF2ZXJzZXIgICAgICAgID0gc3RyX3JlcGVhdCgnLi4vJywgJGRlcHRoKTsKICAgICRlbmRQYXRoUmVtYWluZGVyID0gaW1wbG9kZSgnLycsIGFycmF5X3NsaWNlKCRlbmRQYXRoQXJyLCAkaW5kZXgpKTsKICAgIC8vIENvbnN0cnVjdCAkZW5kUGF0aCBmcm9tIHRyYXZlcnNpbmcgdG8gdGhlIGNvbW1vbiBwYXRoLCB0aGVuIHRvIHRoZSByZW1haW5pbmcgJGVuZFBhdGgKICAgICRyZWxhdGl2ZVBhdGggPSAkdHJhdmVyc2VyLignJyAhPT0gJGVuZFBhdGhSZW1haW5kZXIgPyAkZW5kUGF0aFJlbWFpbmRlci4nLycgOiAnJyk7CiAgICByZXR1cm4gJycgPT09ICRyZWxhdGl2ZVBhdGggPyAnLi8nIDogJHJlbGF0aXZlUGF0aDsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZ2V0X2NvbnRlbnRzJykpOgpmdW5jdGlvbiBjbG9uZXJfZ2V0X2NvbnRlbnRzKCRwYXRoLCAkb2Zmc2V0ID0gMCwgJG1heExlbiA9IG51bGwpCnsKICAgIGlmICgkbWF4TGVuID09PSBudWxsKSB7CiAgICAgICAgJGNvbnRlbnQgPSBAZmlsZV9nZXRfY29udGVudHMoJHBhdGgsIGZhbHNlLCBudWxsLCAkb2Zmc2V0KTsKICAgIH0gZWxzZSB7CiAgICAgICAgJGNvbnRlbnQgPSBAZmlsZV9nZXRfY29udGVudHMoJHBhdGgsIGZhbHNlLCBudWxsLCAkb2Zmc2V0LCAkbWF4TGVuKTsKICAgIH0KICAgIGlmICgkY29udGVudCA9PT0gZmFsc2UpIHsKICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRlNGdW5jdGlvbkV4Y2VwdGlvbignZmlsZV9nZXRfY29udGVudHMnLCAkcGF0aCk7CiAgICB9CiAgICByZXR1cm4gJGNvbnRlbnQ7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2Vudl9yZWFkX3dwX2NvbmZpZycpKToKZnVuY3Rpb24gY2xvbmVyX2Vudl9yZWFkX3dwX2NvbmZpZygkcm9vdCwgJHNlYXJjaEluY2x1ZGVkKQp7CiAgICBpZiAoIWlzX2ZpbGUoJHBhdGggPSAiJHJvb3Qvd3AtY29uZmlnLnBocCIpKSB7CiAgICAgICAgaWYgKCFpc19maWxlKCRwYXRoID0gIiRyb290Ly4uL3dwLWNvbmZpZy5waHAiKSB8fCBpc19maWxlKCIkcm9vdC8uLi93cC1zZXR0aW5ncy5waHAiKSkgewogICAgICAgICAgICBpZiAoISRzZWFyY2hJbmNsdWRlZCB8fCAoJHBhdGggPSBjbG9uZXJfZW52X2ZpbmRfd3BfY29uZmlnKCkpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdGaWxlIHdwLWNvbmZpZy5waHAgY291bGQgbm90IGJlIGZvdW5kJywgJ3dwX2NvbmZpZ19ub3RfZm91bmQnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBhcnJheShjbG9uZXJfbWFrZV9wYXRoX3JlbGF0aXZlKCRwYXRoLCAkcm9vdCksIGNsb25lcl9nZXRfY29udGVudHMoJHBhdGgpKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfd3BfdXBsb2FkX2RpcicpKToKZnVuY3Rpb24gY2xvbmVyX3dwX3VwbG9hZF9kaXIoKQp7CiAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCd3cF91cGxvYWRfZGlyJykpIHsKICAgICAgICByZXR1cm4gd3BfdXBsb2FkX2RpcihudWxsLCBmYWxzZSk7CiAgICB9CiAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdGdW5jdGlvbiB3cF91cGxvYWRfZGlyIG5vdCBmb3VuZCcpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl93cF9zaXRlX3VybCcpKToKZnVuY3Rpb24gY2xvbmVyX3dwX3NpdGVfdXJsKCkKewogICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnc2l0ZV91cmwnKSkgewogICAgICAgIHJldHVybiBzaXRlX3VybCgpOwogICAgfQogICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignRnVuY3Rpb24gc2l0ZV91cmwgbm90IGZvdW5kJyk7Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVyc2l0ZWluZm8nLCBmYWxzZSkpOgppbnRlcmZhY2UgQ2xvbmVyU2l0ZUluZm8KewogICAgcHVibGljIGZ1bmN0aW9uIHRvQXJyYXkoKTsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJ3cGluZm8nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJXUEluZm8gaW1wbGVtZW50cyBDbG9uZXJTaXRlSW5mbwp7CiAgICBwdWJsaWMgJHVybCA9ICcnOwogICAgcHVibGljICRhYnNQYXRoID0gJyc7CiAgICAvKiogQHZhciBDbG9uZXJUYWJsZVtdICovCiAgICBwdWJsaWMgJHRhYmxlUHJlZml4ID0gJyc7CiAgICBwdWJsaWMgJGNvbmZpZ1BhdGggPSAnJzsKICAgIC8qKiBAdmFyIHN0cmluZyBCYXNlNjQtZW5jb2RlZCB3cC1jb25maWcucGhwIGNvbnRlbnQuICovCiAgICBwdWJsaWMgJGNvbmZpZyA9ICcnOwogICAgLyoqIEB2YXIgc3RyaW5nIEluc3RhbGxhdGlvbiBkaXJlY3RvcnksIGVnICd3cCcuICovCiAgICBwdWJsaWMgJGluc3RhbGxEaXIgPSAnJzsKICAgIHB1YmxpYyAkY29udGVudFBhdGggPSAnJzsKICAgIHB1YmxpYyAkcGx1Z2luc1BhdGggPSAnJzsKICAgIHB1YmxpYyAkbXVQbHVnaW5zUGF0aCA9ICcnOwogICAgcHVibGljICR1cGxvYWRzUGF0aCA9ICcnOwogICAgcHVibGljICRzZXJ2ZXJDb25maWdzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybAogICAgICogQHBhcmFtIHN0cmluZyAkYWJzUGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkdGFibGVQcmVmaXgKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbmZpZ1BhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbmZpZwogICAgICogQHBhcmFtIHN0cmluZyAkaW5zdGFsbERpcgogICAgICogQHBhcmFtIHN0cmluZyAkY29udGVudFBhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJHBsdWdpbnNQYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICRtdVBsdWdpbnNQYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cGxvYWRzUGF0aAogICAgICogQHBhcmFtIGFycmF5ICAkc2VydmVyQ29uZmlncwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHVybCwgJGFic1BhdGgsICR0YWJsZVByZWZpeCwgJGNvbmZpZ1BhdGgsICRjb25maWcsICRpbnN0YWxsRGlyLCAkY29udGVudFBhdGgsICRwbHVnaW5zUGF0aCwgJG11UGx1Z2luc1BhdGgsICR1cGxvYWRzUGF0aCwgJHNlcnZlckNvbmZpZ3MpCiAgICB7CiAgICAgICAgaWYgKGVtcHR5KCRhYnNQYXRoKSkgewogICAgICAgICAgICAkYWJzUGF0aCA9ICcvJzsKICAgICAgICB9CiAgICAgICAgJHRoaXMtPnVybCAgICAgICAgICAgPSAkdXJsOwogICAgICAgICR0aGlzLT5hYnNQYXRoICAgICAgID0gcnRyaW0oc3RydHIoJGFic1BhdGgsICdcXCcsICcvJyksICcvJyk7CiAgICAgICAgJHRoaXMtPnRhYmxlUHJlZml4ICAgPSAkdGFibGVQcmVmaXg7CiAgICAgICAgJHRoaXMtPmNvbmZpZ1BhdGggICAgPSB0cmltKHN0cnRyKCRjb25maWdQYXRoLCAnXFwnLCAnLycpLCAnLycpOwogICAgICAgICR0aGlzLT5jb25maWcgICAgICAgID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+aW5zdGFsbERpciAgICA9ICRpbnN0YWxsRGlyOwogICAgICAgICR0aGlzLT5jb250ZW50UGF0aCAgID0gdHJpbShzdHJ0cigkY29udGVudFBhdGgsICdcXCcsICcvJyksICcvJyk7CiAgICAgICAgJHRoaXMtPnBsdWdpbnNQYXRoICAgPSB0cmltKHN0cnRyKCRwbHVnaW5zUGF0aCwgJ1xcJywgJy8nKSwgJy8nKTsKICAgICAgICAkdGhpcy0+bXVQbHVnaW5zUGF0aCA9IHRyaW0oc3RydHIoJG11UGx1Z2luc1BhdGgsICdcXCcsICcvJyksICcvJyk7CiAgICAgICAgJHRoaXMtPnVwbG9hZHNQYXRoICAgPSB0cmltKHN0cnRyKCR1cGxvYWRzUGF0aCwgJ1xcJywgJy8nKSwgJy8nKTsKICAgICAgICAkdGhpcy0+c2VydmVyQ29uZmlncyA9ICRzZXJ2ZXJDb25maWdzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB0b0FycmF5KCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICd3cFVSTCcgICAgICAgICAgID0+ICR0aGlzLT51cmwsCiAgICAgICAgICAgICd3cEFic1BhdGgnICAgICAgID0+ICR0aGlzLT5hYnNQYXRoLAogICAgICAgICAgICAnd3BDb250ZW50UGF0aCcgICA9PiAkdGhpcy0+Y29udGVudFBhdGgsCiAgICAgICAgICAgICd3cFBsdWdpbnNQYXRoJyAgID0+ICR0aGlzLT5wbHVnaW5zUGF0aCwKICAgICAgICAgICAgJ3dwTXVQbHVnaW5zUGF0aCcgPT4gJHRoaXMtPm11UGx1Z2luc1BhdGgsCiAgICAgICAgICAgICd3cFVwbG9hZHNQYXRoJyAgID0+ICR0aGlzLT51cGxvYWRzUGF0aCwKICAgICAgICAgICAgJ3dwQ29uZmlnUGF0aCcgICAgPT4gJHRoaXMtPmNvbmZpZ1BhdGgsCiAgICAgICAgICAgICd3cENvbmZpZycgICAgICAgID0+IGJhc2U2NF9lbmNvZGUoJHRoaXMtPmNvbmZpZyksCiAgICAgICAgICAgICd3cFRhYmxlUHJlZml4JyAgID0+ICR0aGlzLT50YWJsZVByZWZpeCwKICAgICAgICAgICAgJ3dwSW5zdGFsbERpcicgICAgPT4gJHRoaXMtPmluc3RhbGxEaXIsCiAgICAgICAgICAgICdzZXJ2ZXJDb25maWdzJyAgID0+ICR0aGlzLT5zZXJ2ZXJDb25maWdzLAogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENNUygpCiAgICB7CiAgICAgICAgcmV0dXJuICd3b3JkcHJlc3MnOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3JlYWRfc2VydmVyX2NvbmZpZ19maWxlcycpKToKZnVuY3Rpb24gcmVhZF9zZXJ2ZXJfY29uZmlnX2ZpbGVzKCRyb290KQp7CiAgICAkc2VydmVyQ29uZmlnWycuaHRhY2Nlc3MnXSA9IGJhc2U2NF9lbmNvZGUoQGZpbGVfZ2V0X2NvbnRlbnRzKCRyb290LicvLmh0YWNjZXNzJykpOwogICAgJHNlcnZlckNvbmZpZ1snLnVzZXIuaW5pJ10gPSBiYXNlNjRfZW5jb2RlKEBmaWxlX2dldF9jb250ZW50cygkcm9vdC4nLy51c2VyLmluaScpKTsKICAgICRzZXJ2ZXJDb25maWdbJ3BocC5pbmknXSAgID0gYmFzZTY0X2VuY29kZShAZmlsZV9nZXRfY29udGVudHMoJHJvb3QuJy9waHAuaW5pJykpOwogICAgJHNlcnZlckNvbmZpZ1sncGhwNS5pbmknXSAgPSBiYXNlNjRfZW5jb2RlKEBmaWxlX2dldF9jb250ZW50cygkcm9vdC4nL3BocDUuaW5pJykpOwogICAgcmV0dXJuICRzZXJ2ZXJDb25maWc7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3dwX2luZm9fZnJvbV93b3JrZXInKSk6CmZ1bmN0aW9uIGNsb25lcl93cF9pbmZvX2Zyb21fd29ya2VyKCRvdmVycmlkZVVSTCA9ICcnKQp7CiAgICAkYWJzUGF0aCA9IGNsb25lcl9yZWFscGF0aChjbG9uZXJfY29uc3RhbnQoJ0FCU1BBVEgnKSk7CgogICAgZ2xvYmFsICR3cGRiLCAkdGFibGVfcHJlZml4OwoKICAgICRwcmVmaXggPSAkdGFibGVfcHJlZml4OwogICAgaWYgKCFlbXB0eSgkd3BkYi0+YmFzZV9wcmVmaXgpKSB7CiAgICAgICAgJHByZWZpeCA9ICR3cGRiLT5iYXNlX3ByZWZpeDsKICAgIH0KCiAgICBsaXN0KCRjb25maWdQYXRoLCAkY29uZmlnKSA9IGNsb25lcl9lbnZfcmVhZF93cF9jb25maWcoJGFic1BhdGgsIHRydWUpOwoKICAgICRyYXdDb250ZW50UGF0aCA9IGNsb25lcl9jb25zdGFudCgnV1BfQ09OVEVOVF9ESVInKTsKICAgICRjb250ZW50UGF0aCAgICA9IHJlYWxwYXRoKCRyYXdDb250ZW50UGF0aCk7CiAgICBpZiAoJGNvbnRlbnRQYXRoID09PSBmYWxzZSkgewogICAgICAgIC8vIENvbW1vbiBtaXN0YWtlLCBXUF9DT05URU5UX0RJUiByZWxhdGl2ZSB0byBBQlNQQVRILgogICAgICAgICRjb250ZW50UGF0aCA9IHJlYWxwYXRoKCIkYWJzUGF0aC8kcmF3Q29udGVudFBhdGgiKTsKICAgICAgICBpZiAoJGNvbnRlbnRQYXRoID09PSBmYWxzZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKHNwcmludGYoJ0NvdWxkIG5vdCBkZXRlcm1pbmUgbG9jYXRpb24gb2YgV1BfQ09OVEVOVF9ESVIsICVzJywgJHJhd0NvbnRlbnRQYXRoKSwgJ2NvbnRlbnRfZGlyX25vdF9mb3VuZCcpOwogICAgICAgIH0KICAgIH0KICAgICRjb250ZW50UGF0aCA9IGNsb25lcl9tYWtlX3BhdGhfcmVsYXRpdmUoJGNvbnRlbnRQYXRoLCAkYWJzUGF0aCk7CiAgICAkcGx1Z2luc1BhdGggPSBjbG9uZXJfcmVhbHBhdGgoY2xvbmVyX2NvbnN0YW50KCdXUF9QTFVHSU5fRElSJykpOwogICAgJHBsdWdpbnNQYXRoID0gY2xvbmVyX21ha2VfcGF0aF9yZWxhdGl2ZSgkcGx1Z2luc1BhdGgsICRhYnNQYXRoKTsKCiAgICAkdXBsb2FkSW5mbyA9IGNsb25lcl93cF91cGxvYWRfZGlyKCk7CiAgICBpZiAoIWlzc2V0KCR1cGxvYWRJbmZvWydiYXNlZGlyJ10pKSB7CiAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignSW52YWxpZCB1cGxvYWQgZGlyZWN0b3J5LicsICd1cGxvYWRfYmFzZWRpcl9lbXB0eScpOwogICAgfQoKICAgICR1cGxvYWRzUGF0aCAgID0gY2xvbmVyX3JlYWxwYXRoKCR1cGxvYWRJbmZvWydiYXNlZGlyJ10pOwogICAgJHVwbG9hZHNQYXRoICAgPSBjbG9uZXJfbWFrZV9wYXRoX3JlbGF0aXZlKCR1cGxvYWRzUGF0aCwgJGFic1BhdGgpOwogICAgJG11UGx1Z2luc1BhdGggPSBjbG9uZXJfY29uc3RhbnQoJ1dQTVVfUExVR0lOX0RJUicpOwogICAgaWYgKCFjbG9uZXJfaXNfcGF0aF9hYnNvbHV0ZSgkbXVQbHVnaW5zUGF0aCkpIHsKICAgICAgICAkbXVQbHVnaW5zUGF0aCA9ICRhYnNQYXRoLicvJy4kbXVQbHVnaW5zUGF0aDsKICAgIH0KICAgICRtdVBsdWdpbnNQYXRoID0gY2xvbmVyX21ha2VfcGF0aF9yZWxhdGl2ZSgkbXVQbHVnaW5zUGF0aCwgJGFic1BhdGgpOwoKICAgICR1cmwgPSAkb3ZlcnJpZGVVUkw7CiAgICBpZiAoZW1wdHkoJHVybCkpIHsKICAgICAgICAkdXJsID0gY2xvbmVyX3dwX3NpdGVfdXJsKCk7CiAgICB9CiAgICByZXR1cm4gbmV3IENsb25lcldQSW5mbygkdXJsLCAkYWJzUGF0aCwgJHByZWZpeCwgJGNvbmZpZ1BhdGgsICRjb25maWcsICcnLCAkY29udGVudFBhdGgsICRwbHVnaW5zUGF0aCwgJG11UGx1Z2luc1BhdGgsICR1cGxvYWRzUGF0aCwgcmVhZF9zZXJ2ZXJfY29uZmlnX2ZpbGVzKCRhYnNQYXRoKSk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2tlZXBfb3B0aW9uc19saXN0JykpOgpmdW5jdGlvbiBjbG9uZXJfa2VlcF9vcHRpb25zX2xpc3QoKSB7CiAgICByZXR1cm4gYXJyYXkoJ193b3JrZXJfcHVibGljX2tleScsICdtd3Bfd29ya2VyX2NvbmZpZ3VyYXRpb24nLCAnbW1iX3dvcmtlcl9hY3RpdmF0aW9uX3RpbWUnLCAnbXdwX3NlcnZpY2Vfa2V5JywKICAgICAgICAgICAgICAgICAnbXdwX2NvbW11bmljYXRpb25fa2V5JywgJ213cF9wb3RlbnRpYWxfa2V5JywgJ213cF9wb3RlbnRpYWxfa2V5X3RpbWUnLCAnbXdwX2NvbnRhaW5lcl9zaXRlX3BhcmFtZXRlcnMnLCAnbXdwX2NvbnRhaW5lcl9wYXJhbWV0ZXJzJywKICAgICAgICAgICAgICAgICAnbXdwX2NvbW11bmljYXRpb25fa2V5cycsICdtd3BfcHVibGljX2tleXMnLCAnbXdwX3B1YmxpY19rZXlzX3JlZnJlc2hfdGltZScsICdtd3Bfd29ya2VyX2JyYW5kJywKICAgICAgICAgICAgICAgICAnd3BudXhfZXhwb3J0X2RhdGEnLCAnd3BudXhfZXhwb3J0X3VpZCcsICd3cG51eF9pbXBvcnRlZCcsICd3cG51eF90b29rX21zJywgJ3dwZXhfZXhwZXJ0X2Jhbm5lcl9lbmFibGVkJywgJ2dkbF9lbmFibGVkJywKICAgICk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2dldF9zaXRlX2RlZmluaW5nX29wdGlvbnMnKSk6CmZ1bmN0aW9uIGNsb25lcl9nZXRfc2l0ZV9kZWZpbmluZ19vcHRpb25zKCkKewogICAgZ2xvYmFsICR3cGRiOwogICAgJGJhY2t1cE9wdGlvbnMgPSBjbG9uZXJfa2VlcF9vcHRpb25zX2xpc3QoKTsKICAgICRrZWVwT3B0aW9ucyAgID0gYXJyYXkoKTsKICAgIGZvcmVhY2ggKCRiYWNrdXBPcHRpb25zIGFzICRvcHRpb24pIHsKICAgICAgICAkdmFsdWUgPSAkd3BkYi0+Z2V0X3Zhcigkd3BkYi0+cHJlcGFyZSgiU0VMRUNUIG9wdGlvbl92YWx1ZSBGUk9NIHskd3BkYi0+cHJlZml4fW9wdGlvbnMgV0hFUkUgb3B0aW9uX25hbWUgPSAlcyBMSU1JVCAxIiwgJG9wdGlvbikpOwogICAgICAgIGlmICgkdmFsdWUgPT09IG51bGwpIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRrZWVwT3B0aW9uc1skb3B0aW9uXSA9ICR2YWx1ZTsKICAgIH0KICAgIHJldHVybiAka2VlcE9wdGlvbnM7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3NjcmlwdCcpKToKZnVuY3Rpb24gY2xvbmVyX3NjcmlwdCgpCnsKICAgIC8vIFRoaXMgd2lsbCBiZSByZXBsYWNlZCB3aXRoIGZ1bGwgc2NyaXB0IHNvdXJjZSBhdCBhcHBsaWNhdGlvbiBzdGFydHVwLgogICAgcmV0dXJuIGJhc2U2NF9kZWNvZGUoJ19fQ0xPTkVSX1NDUklQVF9fJyk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3dwX2ZpbGVzeXN0ZW0nKSk6CmZ1bmN0aW9uIGNsb25lcl93cF9maWxlc3lzdGVtKCkKewogICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnV1BfRmlsZXN5c3RlbScpKSB7CiAgICAgICAgV1BfRmlsZXN5c3RlbSgpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oJ0Z1bmN0aW9uIFdQX0ZpbGVzeXN0ZW0gbm90IGZvdW5kJyk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2NyZWF0ZV9maWxlJykpOgpmdW5jdGlvbiBjbG9uZXJfY3JlYXRlX2ZpbGUoJHBhdGgsICRjb250ZW50cywgJG1vZGUgPSBudWxsKQp7CiAgICBpZiAoQGZpbGVfcHV0X2NvbnRlbnRzKCRwYXRoLCAkY29udGVudHMpICE9PSBmYWxzZSkgewogICAgICAgIGlmICgkbW9kZSAhPT0gbnVsbCkgewogICAgICAgICAgICBAY2htb2QoJHBhdGgsICRtb2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAkZXJyb3IgPSBjbG9uZXJfbGFzdF9lcnJvcl9mb3IoJ2ZpbGVfcHV0X2NvbnRlbnRzJyk7CiAgICBpZiAoQGNobW9kKCRwYXRoLCAwNjY2KSAhPT0gZmFsc2UgJiYgQGZpbGVfcHV0X2NvbnRlbnRzKCRwYXRoLCAkY29udGVudHMpICE9PSBmYWxzZSkgewogICAgICAgIGlmICgkbW9kZSAhPT0gbnVsbCkgewogICAgICAgICAgICBAY2htb2QoJHBhdGgsICRtb2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBpZiAoZGVmaW5lZCgnQUJTUEFUSCcpICYmIGlzX2ZpbGUoQUJTUEFUSC4nd3AtYWRtaW4vaW5jbHVkZXMvZmlsZS5waHAnKSkgewogICAgICAgIHJlcXVpcmVfb25jZSBBQlNQQVRILid3cC1hZG1pbi9pbmNsdWRlcy9maWxlLnBocCc7CiAgICAgICAgY2xvbmVyX3dwX2ZpbGVzeXN0ZW0oKTsKICAgICAgICAvKiogQHZhciBXUF9GaWxlc3lzdGVtICR3cF9maWxlc3lzdGVtICovCiAgICAgICAgZ2xvYmFsICR3cF9maWxlc3lzdGVtOwogICAgICAgIGlmICghJHdwX2ZpbGVzeXN0ZW0pIHsKICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJ2NvdWxkIG5vdCBsb2FkIFdQX0ZpbGVzeXN0ZW07IFBIUCB3cml0ZSBlcnJvcjogJXMnLCAkZXJyb3IpOwogICAgICAgIH0KICAgICAgICBpZiAoISR3cF9maWxlc3lzdGVtLT5jb25uZWN0KCkpIHsKICAgICAgICAgICAgJGVycm9yQ29kZSAgICA9ICd1bmtub3duJzsKICAgICAgICAgICAgJGVycm9yTWVzc2FnZSA9ICdjb25uZWN0IHJldHVybmVkIGZhbHNlJzsKICAgICAgICAgICAgZm9yZWFjaCAoJHdwX2ZpbGVzeXN0ZW0tPmVycm9ycyBhcyAkY29kZSA9PiAkbWVzc2FnZXMpIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKCRtZXNzYWdlcyBhcyAkbWVzc2FnZSkgewogICAgICAgICAgICAgICAgICAgICRlcnJvckNvZGUgICAgPSAkY29kZTsKICAgICAgICAgICAgICAgICAgICAkZXJyb3JNZXNzYWdlID0gJG1lc3NhZ2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoJ1dQX0ZpbGVzeXN0ZW0gZXJyb3IgWyVzXTogJXM7IFBIUCB3cml0ZSBlcnJvcjogJXMnLCAkZXJyb3JDb2RlLCAkZXJyb3JNZXNzYWdlLCAkZXJyb3IpOwogICAgICAgIH0KICAgICAgICAkb2sgPSAkd3BfZmlsZXN5c3RlbS0+cHV0X2NvbnRlbnRzKEFCU1BBVEguJ2Nsb25lci5waHAnLCAkY29udGVudHMpOwogICAgICAgIGlmICghJG9rKSB7CiAgICAgICAgICAgICR2YXJzID0gZ2V0X29iamVjdF92YXJzKCR3cF9maWxlc3lzdGVtKTsKICAgICAgICAgICAgaWYgKCFlbXB0eSgkdmFyc1snZXJyb3JzJ10pICYmICR2YXJzWydlcnJvcnMnXSBpbnN0YW5jZW9mIFdQX0Vycm9yKSB7CiAgICAgICAgICAgICAgICAkd3BFcnJvciA9IGltcGxvZGUoJzsgJywgJHZhcnNbJ2Vycm9ycyddLT5nZXRfZXJyb3JfbWVzc2FnZXMoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkd3BFcnJvciAgID0gJ3Vua25vd24gZXJyb3InOwogICAgICAgICAgICAgICAgJGxhc3RFcnJvciA9IGVycm9yX2dldF9sYXN0KCk7CiAgICAgICAgICAgICAgICBpZiAoIWVtcHR5KCRsYXN0RXJyb3JbJ21lc3NhZ2UnXSkpIHsKICAgICAgICAgICAgICAgICAgICAkd3BFcnJvciA9ICRsYXN0RXJyb3JbJ21lc3NhZ2UnXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc3ByaW50ZignY291bGQgbm90IHdyaXRlIHZpYSAlczogJXM7IFBIUCB3cml0ZSBlcnJvcjogJXMnLCBnZXRfY2xhc3MoJHdwX2ZpbGVzeXN0ZW0pLCAkd3BFcnJvciwgJGVycm9yKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICByZXR1cm4gJGVycm9yOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnBhcnNlZHdwY29uZmlnaW5mbycsIGZhbHNlKSk6CmNsYXNzIENsb25lclBhcnNlZFdQQ29uZmlnSW5mbwp7CiAgICBwdWJsaWMgJGRiVXNlciA9ICcnOwogICAgcHVibGljICRkYlBhc3N3b3JkID0gJyc7CiAgICBwdWJsaWMgJGRiSG9zdCA9ICcnOwogICAgcHVibGljICRkYk5hbWUgPSAnJzsKICAgIHB1YmxpYyAkd3BUYWJsZVByZWZpeCA9ICcnOwogICAgcHVibGljICRkYlNTTCA9IGZhbHNlOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9nZXRfd3BfY29uZmlnX3RhYmxlX3ByZWZpeCcpKToKZnVuY3Rpb24gY2xvbmVyX2dldF93cF9jb25maWdfdGFibGVfcHJlZml4KGFycmF5ICR0b2tlbnMpCnsKICAgICRwaGFzZSA9IDA7CiAgICBmb3JlYWNoICgkdG9rZW5zIGFzICR0b2tlbikgewogICAgICAgIGlmIChpc19hcnJheSgkdG9rZW4pICYmICgkdG9rZW5bMF0gPT09IFRfV0hJVEVTUEFDRSB8fCAkdG9rZW5bMF0gPT09IFRfQ09NTUVOVCB8fCAkdG9rZW5bMF0gPT09IFRfRE9DX0NPTU1FTlQpKSB7CiAgICAgICAgICAgIC8vIFNraXAgd2hpdGVzcGFjZSBhbmQgY29tbWVudCB0b2tlbnMuCiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoJHBoYXNlID09PSAwKSB7CiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdG9rZW4pICYmICR0b2tlblswXSA9PT0gVF9WQVJJQUJMRSAmJiBzdHJ0b2xvd2VyKCR0b2tlblsxXSkgPT09ICckdGFibGVfcHJlZml4JykgewogICAgICAgICAgICAgICAgJHBoYXNlID0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZWlmICgkcGhhc2UgPT09IDEgJiYgJHRva2VuID09PSAnPScpIHsKICAgICAgICAgICAgJHBoYXNlID0gMjsKICAgICAgICB9IGVsc2VpZiAoJHBoYXNlID09PSAyICYmIGlzX2FycmF5KCR0b2tlbikgJiYgJHRva2VuWzBdID09PSBUX0NPTlNUQU5UX0VOQ0FQU0VEX1NUUklORykgewogICAgICAgICAgICByZXR1cm4gZXZhbChzcHJpbnRmKCdyZXR1cm4gJXM7JywgJHRva2VuWzFdKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHBoYXNlID0gMDsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gbnVsbDsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZ2V0X2NvbnN0YW50c19mcm9tX3Rva2VucycpKToKZnVuY3Rpb24gY2xvbmVyX2dldF9jb25zdGFudHNfZnJvbV90b2tlbnMoYXJyYXkgJHRva2VucywgYXJyYXkgJHNlYXJjaGVkQ29uc3RhbnRzKQp7CiAgICAkZGVmaW5pdGlvbnMgICAgPSBhcnJheSgpOwogICAgJHBoYXNlICAgICAgICAgID0gMDsKICAgICRsYXN0RGVmaW5pdGlvbiA9ICcnOwogICAgJGxhc3RWYWx1ZSAgICAgID0gJyc7CiAgICAkaW5kZW50ICAgICAgICAgPSAwOwogICAgZm9yZWFjaCAoJHRva2VucyBhcyAkdG9rZW4pIHsKICAgICAgICBpZiAoaXNfYXJyYXkoJHRva2VuKSAmJiAoJHRva2VuWzBdID09PSBUX1dISVRFU1BBQ0UgfHwgJHRva2VuWzBdID09PSBUX0NPTU1FTlQgfHwgJHRva2VuWzBdID09PSBUX0RPQ19DT01NRU5UKSkgewogICAgICAgICAgICAvLyBTa2lwIHdoaXRlc3BhY2UgYW5kIGNvbW1lbnQgdG9rZW5zLgogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCRwaGFzZSA9PT0gMCkgewogICAgICAgICAgICAvLyBMb29rIGZvciBhICdkZWZpbmUnIGZ1bmN0aW9uIGNhbGwuCiAgICAgICAgICAgIGlmIChpc19hcnJheSgkdG9rZW4pICYmICR0b2tlblswXSA9PT0gVF9TVFJJTkcgJiYgc3RydG9sb3dlcigkdG9rZW5bMV0pID09PSAnZGVmaW5lJykgewogICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhICdkZWZpbmUnIGNhbGwsIG1vdmUgdG8gbmV4dCBwaGFzZS4KICAgICAgICAgICAgICAgICRwaGFzZSA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2VpZiAoJHBoYXNlID09PSAxICYmICR0b2tlbiA9PT0gJygnKSB7CiAgICAgICAgICAgIC8vIE9wZW4gcGFyZW50aGVzZXMgZm91bmQsIG1vdmUgdG8gbmV4dCBwaGFzZS4KICAgICAgICAgICAgJHBoYXNlID0gMjsKICAgICAgICB9IGVsc2VpZiAoJHBoYXNlID09PSAyICYmIGlzX2FycmF5KCR0b2tlbikgJiYgJHRva2VuWzBdID09PSBUX0NPTlNUQU5UX0VOQ0FQU0VEX1NUUklORykgewogICAgICAgICAgICAvLyBDb25zdGFudCBzdHJpbmcgZm91bmQsIHNhdmUgaXQgZm9yIGxhdGVyCiAgICAgICAgICAgICRsYXN0RGVmaW5pdGlvbiA9IHRyaW0oJHRva2VuWzFdLCAnIlwnJyk7CiAgICAgICAgICAgIC8vaWYgd2UgYXJlIG5vdCBzZWFyY2hpZyBmb3IgdGhhdCBjb25zdGFudCB3ZSBza2lwIGl0LgogICAgICAgICAgICBpZiAoIWluX2FycmF5KCRsYXN0RGVmaW5pdGlvbiwgJHNlYXJjaGVkQ29uc3RhbnRzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgJHBoYXNlICAgICAgICAgID0gMDsKICAgICAgICAgICAgICAgICRsYXN0RGVmaW5pdGlvbiA9ICcnOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJHBoYXNlID0gMzsKICAgICAgICB9IGVsc2VpZiAoJHBoYXNlID09PSAzICYmICR0b2tlbiA9PT0gJywnKSB7CiAgICAgICAgICAgIC8vIENvbW1hIGZvdW5kLgogICAgICAgICAgICAkcGhhc2UgPSA0OwogICAgICAgIH0gZWxzZWlmICgkcGhhc2UgPT09IDQpIHsKICAgICAgICAgICAgaWYgKCR0b2tlbiA9PT0gJygnKSB7CiAgICAgICAgICAgICAgICAkaW5kZW50Kys7CiAgICAgICAgICAgIH0gZWxzZWlmICgkdG9rZW4gPT09ICcpJykgewogICAgICAgICAgICAgICAgaWYgKCRpbmRlbnQgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAkZGVmaW5pdGlvbnNbJGxhc3REZWZpbml0aW9uXSA9IGV2YWwoc3ByaW50ZigncmV0dXJuICVzOycsICRsYXN0VmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICAkcGhhc2UgICAgICAgICAgICAgICAgICAgICAgICA9IDA7CiAgICAgICAgICAgICAgICAgICAgJGxhc3RWYWx1ZSAgICAgICAgICAgICAgICAgICAgPSAnJzsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJGluZGVudC0tOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRsYXN0VmFsdWUgLj0gaXNfYXJyYXkoJHRva2VuKSA/ICR0b2tlblsxXSA6ICR0b2tlbjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBVbnN1cHBvcnRlZCB0b2tlbiBmb3VuZCwgcmVzZXQgdGhlIHBhcnNlciBwaGFzZS4KICAgICAgICAgICAgJHBoYXNlICAgICA9IDA7CiAgICAgICAgICAgICRsYXN0VmFsdWUgPSAnJzsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gJGRlZmluaXRpb25zOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9lbnZfcGFyc2Vfd3BfY29uZmlnJykpOgpmdW5jdGlvbiBjbG9uZXJfZW52X3BhcnNlX3dwX2NvbmZpZygkY29uZmlnKQp7CiAgICAkdG9rZW5zICAgICAgPSB0b2tlbl9nZXRfYWxsKCRjb25maWcpOwogICAgJGRiQ29uc3RhbnRzID0gYXJyYXkoJ0RCX1VTRVInLCAnREJfUEFTU1dPUkQnLCAnREJfSE9TVCcsICdEQl9OQU1FJywgJ0RCX1NTTCcpOwogICAgJGNvbnN0YW50cyAgID0gY2xvbmVyX2dldF9jb25zdGFudHNfZnJvbV90b2tlbnMoJHRva2VucywgJGRiQ29uc3RhbnRzKTsKICAgIGZvcmVhY2ggKCRkYkNvbnN0YW50cyBhcyAkY29uc3RhbnQpIHsKICAgICAgICBpZiAoIWlzc2V0KCRjb25zdGFudHNbJGNvbnN0YW50XSkgJiYgJGNvbnN0YW50ICE9PSAnREJfU1NMJykgewogICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCJDb25zdGFudCAkY29uc3RhbnQgbm90IGZvdW5kIGluc2lkZSB3cC1jb25maWcucGhwIik7CiAgICAgICAgfQogICAgfQogICAgJGluZm8gICAgICAgICAgICAgPSBuZXcgQ2xvbmVyUGFyc2VkV1BDb25maWdJbmZvKCk7CiAgICAkaW5mby0+ZGJVc2VyICAgICA9ICRjb25zdGFudHNbJ0RCX1VTRVInXTsKICAgICRpbmZvLT5kYlBhc3N3b3JkID0gJGNvbnN0YW50c1snREJfUEFTU1dPUkQnXTsKICAgICRpbmZvLT5kYkhvc3QgICAgID0gJGNvbnN0YW50c1snREJfSE9TVCddOwogICAgJGluZm8tPmRiTmFtZSAgICAgPSAkY29uc3RhbnRzWydEQl9OQU1FJ107CiAgICAkdGFibGVQcmVmaXggICAgICA9IGNsb25lcl9nZXRfd3BfY29uZmlnX3RhYmxlX3ByZWZpeCgkdG9rZW5zKTsKICAgICRpbmZvLT5kYlNTTCAgICAgID0gaXNzZXQoJGNvbnN0YW50c1snREJfU1NMJ10pID8gKGJvb2wpJGNvbnN0YW50c1snREJfU1NMJ10gOiBmYWxzZTsKICAgIGlmICgkdGFibGVQcmVmaXggPT09IG51bGwpIHsKICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdWYXJpYWJsZSAkdGFibGVfcHJlZml4IGNvdWxkIG5vdCBiZSBwYXJzZWQgZnJvbSB3cC1jb25maWcucGhwJyk7CiAgICB9CiAgICAkaW5mby0+d3BUYWJsZVByZWZpeCA9ICR0YWJsZVByZWZpeDsKICAgIHJldHVybiAkaW5mbzsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfZ2V0X3N0YXRpY19zaXRlX2RlZmluaW5nX29wdGlvbnMnKSk6CmZ1bmN0aW9uIGNsb25lcl9nZXRfc3RhdGljX3NpdGVfZGVmaW5pbmdfb3B0aW9ucyhDbG9uZXJEQkFkYXB0ZXIgJGNvbm4sICRwcmVmaXgpCnsKICAgICRiYWNrdXBPcHRpb25zID0gY2xvbmVyX2tlZXBfb3B0aW9uc19saXN0KCk7CiAgICAka2VlcE9wdGlvbnMgICA9IGFycmF5KCk7CiAgICBmb3JlYWNoICgkYmFja3VwT3B0aW9ucyBhcyAkb3B0aW9uKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgJHN0bXQgID0gJGNvbm4tPnF1ZXJ5KCJTRUxFQ1Qgb3B0aW9uX3ZhbHVlIEZST00geyRwcmVmaXh9b3B0aW9ucyBXSEVSRSBvcHRpb25fbmFtZSA9IDpvcHRpb24gTElNSVQgMSIsIGFycmF5KAogICAgICAgICAgICAgICAgJ29wdGlvbicgPT4gJG9wdGlvbiwKICAgICAgICAgICAgKSk7CiAgICAgICAgICAgICR2YWx1ZSA9ICRzdG10LT5mZXRjaCgpOwogICAgICAgICAgICAkc3RtdC0+ZnJlZSgpOwogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICB0cmlnZ2VyX2Vycm9yKHNwcmludGYoJ0NvdWxkIG5vdCBzZWxlY3Qgb3B0aW9uICVzIGZyb20gJXM6ICVzJywgJG9wdGlvbiwgJHByZWZpeC4nb3B0aW9ucycsICRlLT5nZXRNZXNzYWdlKCkpKTsKICAgICAgICAgICAgcmV0dXJuIGFycmF5KCk7CiAgICAgICAgfQogICAgICAgIGlmICgkdmFsdWUgPT09IG51bGwpIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgICRrZWVwT3B0aW9uc1skb3B0aW9uXSA9IGVuZCgkdmFsdWUpOwogICAgfQogICAgcmV0dXJuICRrZWVwT3B0aW9uczsKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJ3b3JkcHJlc3NzaXRlc291cmNlJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyV29yZFByZXNzU2l0ZVNvdXJjZSBpbXBsZW1lbnRzIENsb25lclNpdGVTb3VyY2UKewogICAgcHJpdmF0ZSAkZGVmYXVsdENvbnRlbnQgPSAnd3AtY29udGVudCc7CiAgICBwcml2YXRlICRkZWZhdWx0UGx1Z2lucyA9ICd3cC1jb250ZW50L3BsdWdpbnMnOwogICAgcHJpdmF0ZSAkZGVmYXVsdE11UGx1Z2lucyA9ICd3cC1jb250ZW50L211LXBsdWdpbnMnOwogICAgcHJpdmF0ZSAkZGVmYXVsdFVwbG9hZHMgPSAnd3AtY29udGVudC91cGxvYWRzJzsKCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q01TKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3dvcmRwcmVzcyc7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAkcm9vdAogICAgICogQHBhcmFtIHN0cmluZyAgICAgJHVybAogICAgICogQHBhcmFtIGFycmF5fG51bGwgJGRiICAgICAgICAgICAgREIgaW5mbyBmcm9tIHNvdXJjZSwgbWlnaHQgYmUgZW1wdHkuCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAkdGFibGVQcmVmaXggICBUYWJsZSBwcmVmaXggZnJvbSBzb3VyY2UsIG1pZ2h0IGJlIGVtcHR5LgogICAgICogQHBhcmFtIHN0cmluZyAgICAgJGNvbmZpZ0NvbnRlbnQgd3AtY29uZmlnLnBocCBmcm9tIHNvdXJjZSwgbWlnaHQgYmUgZW1wdHkuCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAkcmVhZE9ubHkgICAgICBBbGxvd3MgdG8gY29tcGxldGUgc2V0dXAgd2hlbiBjb25maWcgZmlsZSBkb2Vzbid0IGV4aXQgb24gc2VydmVyCiAgICAgKgogICAgICogQHJldHVybiBDbG9uZXJTZXR1cFJlc3VsdAogICAgICogQHRocm93cyBDbG9uZXJFeGNlcHRpb24KICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNldHVwKCRyb290LCAkdXJsLCAkZGIsICR0YWJsZVByZWZpeCwgJGZvcmNlUHJlZml4LCAkY29uZmlnQ29udGVudCwgJHJlYWRPbmx5KQogICAgewogICAgICAgIGdsb2JhbCAkd3BkYjsKICAgICAgICBpZiAoIWVtcHR5KCR3cGRiKSkgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnNldHVwV29ya2VyKCR1cmwsICEkcmVhZE9ubHksICRkYik7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkdGhpcy0+c2V0dXBTdGF0aWMoJHJvb3QsICR1cmwsICRkYiwgJHRhYmxlUHJlZml4LCAkZm9yY2VQcmVmaXgsICRjb25maWdDb250ZW50LCAkcmVhZE9ubHkpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAgICAgJHVybE92ZXJyaWRlCiAgICAgKiBAcGFyYW0gYm9vbCAgICAgICAkaXNTb3VyY2UKICAgICAqIEBwYXJhbSBhcnJheXxudWxsICRkYk92ZXJyaWRlcwogICAgICoKICAgICAqIEByZXR1cm4gQ2xvbmVyU2V0dXBSZXN1bHQKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2V0dXBXb3JrZXIoJHVybE92ZXJyaWRlLCAkaXNTb3VyY2UsIGFycmF5ICRkYk92ZXJyaWRlcyA9IG51bGwpCiAgICB7CiAgICAgICAgJGFic1BhdGggICAgICAgICAgPSBjbG9uZXJfY29uc3RhbnQoJ0FCU1BBVEgnKTsKICAgICAgICAkcmVzdWx0ICAgICAgICAgICA9IG5ldyBDbG9uZXJTZXR1cFJlc3VsdChjbG9uZXJfZGJfaW5mb19mcm9tX3dvcmtlcigkaXNTb3VyY2UsICRkYk92ZXJyaWRlcyksIGNsb25lcl93cF9pbmZvX2Zyb21fd29ya2VyKCR1cmxPdmVycmlkZSksIGNsb25lcl9lbnZfaW5mbygkYWJzUGF0aCksIGNsb25lcl9nZXRfc2l0ZV9kZWZpbmluZ19vcHRpb25zKCkpOwogICAgICAgICRhcHBlbmQgICAgICAgICAgID0gc3ByaW50ZigiXG5mdW5jdGlvbiBfX2Nsb25lcl9nZXRfc3RhdGUoKSB7XG4gICAgcmV0dXJuICVzO1xufVxuIiwgdmFyX2V4cG9ydCgkcmVzdWx0LT50b0FycmF5KCksIHRydWUpKTsKICAgICAgICAkY2xvbmVyU2NyaXB0ICAgICA9IGNsb25lcl9zY3JpcHQoKTsKICAgICAgICAkcmVzdWx0LT53b3JrZXJPSyA9IHRydWU7CiAgICAgICAgaWYgKHN0cmxlbigkY2xvbmVyU2NyaXB0KSkgewogICAgICAgICAgICBpZiAoJGVycm9yID0gY2xvbmVyX2NyZWF0ZV9maWxlKCIkYWJzUGF0aC9jbG9uZXIucGhwIiwgJGNsb25lclNjcmlwdC4kYXBwZW5kLCAwNDQ0KSkgewogICAgICAgICAgICAgICAgJHJlc3VsdC0+bm9SZWxheSA9IHRydWU7CiAgICAgICAgICAgICAgICByZXR1cm4gJHJlc3VsdDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRyZXN1bHQtPm5vUmVsYXkgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBjbG9uZXJfY3JlYXRlX2ZpbGUoIiRhYnNQYXRoL2Nsb25lcl9lcnJvcl9sb2ciLCAnJywgMDY2Nik7CiAgICAgICAgcmV0dXJuICRyZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAkcm9vdAogICAgICogQHBhcmFtIHN0cmluZyAgICAgJHVybAogICAgICogQHBhcmFtIGFycmF5fG51bGwgJGRiICAgICAgICAgICAgREIgaW5mbyBmcm9tIHNvdXJjZSwgbWlnaHQgYmUgZW1wdHkuCiAgICAgKiBAcGFyYW0gc3RyaW5nICAgICAkdGFibGVQcmVmaXggICBUYWJsZSBwcmVmaXggZnJvbSBzb3VyY2UsIG1pZ2h0IGJlIGVtcHR5LgogICAgICogQHBhcmFtIGJvb2wgICAgICAgJGZvcmNlUHJlZml4ICAgVGFibGUgcHJlZml4IGZyb20gc291cmNlLCBtaWdodCBiZSBlbXB0eS4KICAgICAqIEBwYXJhbSBzdHJpbmcgICAgICRjb25maWdDb250ZW50IHdwLWNvbmZpZy5waHAgZnJvbSBzb3VyY2UsIG1pZ2h0IGJlIGVtcHR5LgogICAgICogQHBhcmFtIHN0cmluZyAgICAgJHJlYWRPbmx5ICAgICAgQWxsb3dzIHRvIGNvbXBsZXRlIHNldHVwIHdoZW4gY29uZmlnIGZpbGUgZG9lc24ndCBleGl0IG9uIHNlcnZlcgogICAgICoKICAgICAqIEByZXR1cm4gQ2xvbmVyU2V0dXBSZXN1bHQKICAgICAqIEB0aHJvd3MgQ2xvbmVyRXhjZXB0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgZnVuY3Rpb24gc2V0dXBTdGF0aWMoJHJvb3QsICR1cmwsICRkYiwgJHRhYmxlUHJlZml4LCAkZm9yY2VQcmVmaXgsICRjb25maWdDb250ZW50LCAkcmVhZE9ubHkpCiAgICB7CiAgICAgICAgJHdwQ29uZmlnUGF0aCA9ICd3cC1jb25maWcucGhwJzsKICAgICAgICAkY2hlY2tQcmVmaXggID0gJHRhYmxlUHJlZml4OwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChlbXB0eSgkY29uZmlnQ29udGVudCkpIHsKICAgICAgICAgICAgICAgIGxpc3QoJHdwQ29uZmlnUGF0aCwgJGNvbmZpZ0NvbnRlbnQpID0gY2xvbmVyX2Vudl9yZWFkX3dwX2NvbmZpZygkcm9vdCwgZmFsc2UpOwogICAgICAgICAgICAgICAgaWYgKCFpc19kaXIoJHJvb3QuJy93cC1hZG1pbicpIHx8ICFpc19kaXIoJHJvb3QuJy93cC1pbmNsdWRlcycpCiAgICAgICAgICAgICAgICAgICAgfHwgIWlzX2ZpbGUoJHJvb3QuJy93cC1sb2FkLnBocCcpIHx8ICFpc19maWxlKCRyb290Licvd3Atc2V0dGluZ3MucGhwJykpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdObyBXb3JkUHJlc3MgY29yZSBmaWxlcyBmb3VuZCcsICdub193b3JkcHJlc3NfY29yZScpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICghJHJlYWRPbmx5KSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoZGVmaW5lZCgnREJfTkFNRScpICYmIGRlZmluZWQoJ0RCX1VTRVInKSAmJiBkZWZpbmVkKCdEQl9QQVNTV09SRCcpICYmIGRlZmluZWQoJ0RCX0hPU1QnKSAmJiBpc19maWxlKCIvcGFnZWx5L3dwLWNvbmZpZy1ob3N0aW5nLnBocCIpKSB7CiAgICAgICAgICAgICAgICAkd3BDb25maWdJbmZvICAgICAgICAgICAgICAgID0gbmV3IENsb25lclBhcnNlZFdQQ29uZmlnSW5mbygpOwogICAgICAgICAgICAgICAgJHdwQ29uZmlnSW5mby0+ZGJVc2VyICAgICAgICA9IERCX1VTRVI7CiAgICAgICAgICAgICAgICAkd3BDb25maWdJbmZvLT5kYlBhc3N3b3JkICAgID0gREJfUEFTU1dPUkQ7CiAgICAgICAgICAgICAgICAkd3BDb25maWdJbmZvLT5kYkhvc3QgICAgICAgID0gREJfSE9TVDsKICAgICAgICAgICAgICAgICR3cENvbmZpZ0luZm8tPmRiTmFtZSAgICAgICAgPSBEQl9OQU1FOwogICAgICAgICAgICAgICAgJHdwQ29uZmlnSW5mby0+ZGJTU0wgICAgICAgICA9IGRlZmluZWQoJ0RCX1NTTCcpICYmIChib29sKURCX1NTTDsKICAgICAgICAgICAgICAgICR3cENvbmZpZ0luZm8tPndwVGFibGVQcmVmaXggPSBjbG9uZXJfZ2V0X3dwX2NvbmZpZ190YWJsZV9wcmVmaXgodG9rZW5fZ2V0X2FsbChmaWxlX2dldF9jb250ZW50cygiL3BhZ2VseS93cC1jb25maWctaG9zdGluZy5waHAiKSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKHN0cmxlbigkY29uZmlnQ29udGVudCkgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyBGaW5kIHRoaXMgd2Vic2l0ZSdzIHdwLWNvbmZpZy5waHAuCiAgICAgICAgICAgICAgICAgICAgbGlzdCgkd3BDb25maWdQYXRoLCAkY29uZmlnQ29udGVudCkgPSBjbG9uZXJfZW52X3JlYWRfd3BfY29uZmlnKCRyb290LCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkd3BDb25maWdJbmZvID0gY2xvbmVyX2Vudl9wYXJzZV93cF9jb25maWcoJGNvbmZpZ0NvbnRlbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRkZXRlY3RlZCAgICAgPSBhcnJheShuZXcgQ2xvbmVyREJJbmZvKCR3cENvbmZpZ0luZm8tPmRiVXNlciwgJHdwQ29uZmlnSW5mby0+ZGJQYXNzd29yZCwgJHdwQ29uZmlnSW5mby0+ZGJIb3N0LCAkd3BDb25maWdJbmZvLT5kYk5hbWUsICR3cENvbmZpZ0luZm8tPmRiU1NMKSk7CiAgICAgICAgICAgICRkYiAgICAgICAgICAgPSBjbG9uZXJfbWVyZ2VfZGJfaW5mbygoYXJyYXkpJGRiLCAkZGV0ZWN0ZWQsICEkcmVhZE9ubHkpOwogICAgICAgICAgICAkY2hlY2tQcmVmaXggID0gJHdwQ29uZmlnSW5mby0+d3BUYWJsZVByZWZpeDsKICAgICAgICAgICAgaWYgKCEkZm9yY2VQcmVmaXgpIHsKICAgICAgICAgICAgICAgICR0YWJsZVByZWZpeCA9ICR3cENvbmZpZ0luZm8tPndwVGFibGVQcmVmaXg7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCEkcmVhZE9ubHkpIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIFZlcmlmeSBjb25uZWN0aW9uIGluZm8uCiAgICAgICAgJGNvbm4gPSBjbG9uZXJfZGJfY29ubigkZGIpOwogICAgICAgICRjb25uLT5waW5nKCk7CiAgICAgICAgJGNsb25lcldwSW5mbyA9IG5ldyBDbG9uZXJXUEluZm8oJHVybCwgJHJvb3QsICR0YWJsZVByZWZpeCwgJHdwQ29uZmlnUGF0aCwgJGNvbmZpZ0NvbnRlbnQsCiAgICAgICAgICAgICcnLCAnd3AtY29udGVudCcsICd3cC1jb250ZW50L3BsdWdpbnMnLCAnd3AtY29udGVudC9tdS1wbHVnaW5zJywgJ3dwLWNvbnRlbnQvdXBsb2FkcycsIHJlYWRfc2VydmVyX2NvbmZpZ19maWxlcygkcm9vdCkpOwogICAgICAgIHJldHVybiBuZXcgQ2xvbmVyU2V0dXBSZXN1bHQoJGRiLCAkY2xvbmVyV3BJbmZvLCBjbG9uZXJfZW52X2luZm8oJHJvb3QpLCBjbG9uZXJfZ2V0X3N0YXRpY19zaXRlX2RlZmluaW5nX29wdGlvbnMoJGNvbm4sICRjaGVja1ByZWZpeCkpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmRydXBhbGluZm8nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJEcnVwYWxJbmZvIGltcGxlbWVudHMgQ2xvbmVyU2l0ZUluZm8KewogICAgcHJpdmF0ZSAkdXJsID0gJyc7CiAgICBwcml2YXRlICRyb290ID0gJyc7CiAgICBwcml2YXRlICRjb25maWdQYXRoID0gJyc7CiAgICBwcml2YXRlICR0YWJsZVByZWZpeCA9ICcnOwogICAgcHJpdmF0ZSAkY29uZmlnID0gJyc7CiAgICBwcml2YXRlICRzZXJ2ZXJDb25maWdzID0gYXJyYXkoKTsKCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybAogICAgICogQHBhcmFtIHN0cmluZyAkcm9vdAogICAgICogQHBhcmFtIHN0cmluZyAkY29uZmlnUGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkdGFibGVQcmVmaXgKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbmZpZwogICAgICogQHBhcmFtIGFycmF5ICAkc2VydmVyQ29uZmlncwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHVybCwgJHJvb3QsICRjb25maWdQYXRoLCAkdGFibGVQcmVmaXgsICRjb25maWcsICRzZXJ2ZXJDb25maWdzKQogICAgewogICAgICAgICR0aGlzLT51cmwgICAgICAgICAgID0gJHVybDsKICAgICAgICAkdGhpcy0+cm9vdCAgICAgICAgICA9ICRyb290OwogICAgICAgICR0aGlzLT5jb25maWdQYXRoICAgID0gJGNvbmZpZ1BhdGg7CiAgICAgICAgJHRoaXMtPnRhYmxlUHJlZml4ICAgPSAkdGFibGVQcmVmaXg7CiAgICAgICAgJHRoaXMtPmNvbmZpZyAgICAgICAgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5zZXJ2ZXJDb25maWdzID0gJHNlcnZlckNvbmZpZ3M7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHRvQXJyYXkoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJ3VybCcgICAgICAgICAgID0+ICR0aGlzLT51cmwsCiAgICAgICAgICAgICdyb290JyAgICAgICAgICA9PiAkdGhpcy0+cm9vdCwKICAgICAgICAgICAgJ2NvbmZpZ1BhdGgnICAgID0+ICR0aGlzLT5jb25maWdQYXRoLAogICAgICAgICAgICAndGFibGVQcmVmaXgnICAgPT4gJHRoaXMtPnRhYmxlUHJlZml4LAogICAgICAgICAgICAnZHJ1cGFsQ29uZmlnJyAgPT4gYmFzZTY0X2VuY29kZSgkdGhpcy0+Y29uZmlnKSwKICAgICAgICAgICAgJ3NlcnZlckNvbmZpZ3MnID0+ICR0aGlzLT5zZXJ2ZXJDb25maWdzLAogICAgICAgICk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENNUygpCiAgICB7CiAgICAgICAgcmV0dXJuICdkcnVwYWwnOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmRydXBhbHNpdGVzb3VyY2UnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJEcnVwYWxTaXRlU291cmNlIGltcGxlbWVudHMgQ2xvbmVyU2l0ZVNvdXJjZQp7CiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q01TKCkKICAgIHsKICAgICAgICByZXR1cm4gJ2RydXBhbCc7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldHVwKCRyb290LCAkdXJsLCAkZGIsICR0YWJsZVByZWZpeCwgJGZvcmNlUHJlZml4LCAkY29uZmlnQ29udGVudCwgJHJlYWRPbmx5KQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2V0dXBEcnVwYWwoJHJvb3QsICR1cmwsICRkYiwgJHRhYmxlUHJlZml4LCAkY29uZmlnQ29udGVudCwgJHJlYWRPbmx5KTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldHVwRHJ1cGFsKCRyb290LCAkdXJsLCAkZGIsICR0YWJsZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsICRyZWFkT25seSkKICAgIHsKICAgICAgICAkY29uZmlnUGF0aCA9ICJzaXRlcy9kZWZhdWx0L3NldHRpbmdzLnBocCI7CiAgICAgICAgJHBhdGggICAgICAgPSAiJHJvb3Qvc2l0ZXMvZGVmYXVsdC9zZXR0aW5ncy5waHAiOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChlbXB0eSgkY29uZmlnQ29udGVudCkpIHsKICAgICAgICAgICAgICAgICRjb25maWdDb250ZW50ID0gY2xvbmVyX2dldF9jb250ZW50cygkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCEkcmVhZE9ubHkpIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRkYXRhYmFzZXMgPSBhcnJheSgpOwogICAgICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRwYXRoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignTm8gZHJ1cGFsIGRlZmF1bHQgY29uZmlndXJhdGlvbiBmb3VuZCcsICdub19kcnVwYWxfY29uZmlnJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVxdWlyZV9vbmNlICRwYXRoOwogICAgICAgICAgICAkZGJJbmZvICAgICAgPSAkZGF0YWJhc2VzWydkZWZhdWx0J11bJ2RlZmF1bHQnXTsKICAgICAgICAgICAgJHRhYmxlUHJlZml4ID0gJGRiSW5mb1sncHJlZml4J107CiAgICAgICAgICAgICRkZXRlY3RlZCAgICA9IGFycmF5KG5ldyBDbG9uZXJEQkluZm8oJGRiSW5mb1sndXNlcm5hbWUnXSwgJGRiSW5mb1sncGFzc3dvcmQnXSwgJGRiSW5mb1snaG9zdCddLCAkZGJJbmZvWydkYXRhYmFzZSddKSk7CiAgICAgICAgICAgICRkYiAgICAgICAgICA9IGNsb25lcl9tZXJnZV9kYl9pbmZvKChhcnJheSkkZGIsICRkZXRlY3RlZCwgISRyZWFkT25seSk7CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICghJHJlYWRPbmx5KSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjbG9uZXJfZGJfY29ubigkZGIpLT5waW5nKCk7CiAgICAgICAgJGRydXBhbEluZm8gPSBuZXcgQ2xvbmVyRHJ1cGFsSW5mbygkdXJsLCAkcm9vdCwgJGNvbmZpZ1BhdGgsICR0YWJsZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsIHJlYWRfc2VydmVyX2NvbmZpZ19maWxlcygkcm9vdCkpOwogICAgICAgIHJldHVybiBuZXcgQ2xvbmVyU2V0dXBSZXN1bHQoJGRiLCAkZHJ1cGFsSW5mbywgY2xvbmVyX2Vudl9pbmZvKCRyb290KSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2pjb25maWcnKSk6CmZ1bmN0aW9uIGNsb25lcl9qY29uZmlnKCkKewogICAgaWYgKGNsYXNzX2V4aXN0cygnSkNvbmZpZycpKSB7CiAgICAgICAgcmV0dXJuIG5ldyBKQ29uZmlnKCk7CiAgICB9CiAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdDbGFzcyBKQ29uZmlnIG5vdCBmb3VuZCcpOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmpvb21sYWluZm8nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJKb29tbGFJbmZvIGltcGxlbWVudHMgQ2xvbmVyU2l0ZUluZm8KewogICAgcHJpdmF0ZSAkdXJsID0gJyc7CiAgICBwcml2YXRlICRyb290ID0gJyc7CiAgICBwcml2YXRlICRjb25maWdQYXRoID0gJyc7CiAgICBwcml2YXRlICR0YWJsZVByZWZpeCA9ICcnOwogICAgcHJpdmF0ZSAkY29uZmlnID0gJyc7CiAgICBwcml2YXRlICRzZXJ2ZXJDb25maWdzID0gYXJyYXkoKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gdG9BcnJheSgpCiAgICB7CiAgICAgICAgcmV0dXJuIGFycmF5KAogICAgICAgICAgICAndXJsJyAgICAgICAgICAgPT4gJHRoaXMtPnVybCwKICAgICAgICAgICAgJ3Jvb3QnICAgICAgICAgID0+ICR0aGlzLT5yb290LAogICAgICAgICAgICAnY29uZmlnUGF0aCcgICAgPT4gJHRoaXMtPmNvbmZpZ1BhdGgsCiAgICAgICAgICAgICd0YWJsZVByZWZpeCcgICA9PiAkdGhpcy0+dGFibGVQcmVmaXgsCiAgICAgICAgICAgICdqb29tbGFDb25maWcnICA9PiBiYXNlNjRfZW5jb2RlKCR0aGlzLT5jb25maWcpLAogICAgICAgICAgICAnc2VydmVyQ29uZmlncycgPT4gJHRoaXMtPnNlcnZlckNvbmZpZ3MsCiAgICAgICAgKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdHJpbmcgJHVybAogICAgICogQHBhcmFtIHN0cmluZyAkcm9vdAogICAgICogQHBhcmFtIHN0cmluZyAkY29uZmlnUGF0aAogICAgICogQHBhcmFtIHN0cmluZyAkdGFibGVQcmVmaXgKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbmZpZwogICAgICogQHBhcmFtIGFycmF5ICAkc2VydmVyQ29uZmlncwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHVybCwgJHJvb3QsICRjb25maWdQYXRoLCAkdGFibGVQcmVmaXgsICRjb25maWcsICRzZXJ2ZXJDb25maWdzKQogICAgewogICAgICAgICR0aGlzLT51cmwgICAgICAgICAgID0gJHVybDsKICAgICAgICAkdGhpcy0+cm9vdCAgICAgICAgICA9ICRyb290OwogICAgICAgICR0aGlzLT5jb25maWdQYXRoICAgID0gJGNvbmZpZ1BhdGg7CiAgICAgICAgJHRoaXMtPnRhYmxlUHJlZml4ICAgPSAkdGFibGVQcmVmaXg7CiAgICAgICAgJHRoaXMtPmNvbmZpZyAgICAgICAgPSAkY29uZmlnOwogICAgICAgICR0aGlzLT5zZXJ2ZXJDb25maWdzID0gJHNlcnZlckNvbmZpZ3M7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldENNUygpCiAgICB7CiAgICAgICAgcmV0dXJuICdqb29tbGEnOwogICAgfQoKfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJqb29tbGFzaXRlc291cmNlJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVySm9vbWxhU2l0ZVNvdXJjZSBpbXBsZW1lbnRzIENsb25lclNpdGVTb3VyY2UKewogICAgcHVibGljIGZ1bmN0aW9uIGdldENNUygpCiAgICB7CiAgICAgICAgcmV0dXJuICdqb29tbGEnOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXR1cCgkcm9vdCwgJHVybCwgJGRiLCAkdGFibGVQcmVmaXgsICRmb3JjZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsICRyZWFkT25seSkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnNldHVwSm9vbWxhKCRyb290LCAkdXJsLCAkZGIsICR0YWJsZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsICRyZWFkT25seSk7CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jdGlvbiBzZXR1cEpvb21sYSgkcm9vdCwgJHVybCwgJGRiLCAkdGFibGVQcmVmaXgsICRjb25maWdDb250ZW50LCAkcmVhZE9ubHkpCiAgICB7CiAgICAgICAgJGNvbmZpZ1BhdGggPSAnY29uZmlndXJhdGlvbi5waHAnOwogICAgICAgICRwYXRoICAgICAgID0gJHJvb3QuIi9jb25maWd1cmF0aW9uLnBocCI7CiAgICAgICAgaWYgKGVtcHR5KCRjb25maWdDb250ZW50KSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgJGNvbmZpZ0NvbnRlbnQgPSBjbG9uZXJfZ2V0X2NvbnRlbnRzKCRwYXRoKTsKICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICBpZiAoISRyZWFkT25seSkgewogICAgICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJHBhdGgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdObyBqb29tbGEgY29uZmlndXJhdGlvbiBmb3VuZCcsICdub19qb29tbGFfY29uZmlnJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVxdWlyZV9vbmNlICRwYXRoOwogICAgICAgICAgICAkc2l0ZUluZm8gICAgPSBjbG9uZXJfamNvbmZpZygpOwogICAgICAgICAgICAkdGFibGVQcmVmaXggPSAkc2l0ZUluZm8tPmRicHJlZml4OwogICAgICAgICAgICAkZGV0ZWN0ZWQgICAgPSBhcnJheShuZXcgQ2xvbmVyREJJbmZvKCRzaXRlSW5mby0+dXNlciwgJHNpdGVJbmZvLT5wYXNzd29yZCwgJHNpdGVJbmZvLT5ob3N0LCAkc2l0ZUluZm8tPmRiKSk7CiAgICAgICAgICAgICRkYiAgICAgICAgICA9IGNsb25lcl9tZXJnZV9kYl9pbmZvKChhcnJheSkkZGIsICRkZXRlY3RlZCwgISRyZWFkT25seSk7CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICghJHJlYWRPbmx5KSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjbG9uZXJfZGJfY29ubigkZGIpLT5waW5nKCk7CiAgICAgICAgJGRydXBhbEluZm8gPSBuZXcgQ2xvbmVySm9vbWxhSW5mbygkdXJsLCAkcm9vdCwgJGNvbmZpZ1BhdGgsICR0YWJsZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsIHJlYWRfc2VydmVyX2NvbmZpZ19maWxlcygkcm9vdCkpOwogICAgICAgIHJldHVybiBuZXcgQ2xvbmVyU2V0dXBSZXN1bHQoJGRiLCAkZHJ1cGFsSW5mbywgY2xvbmVyX2Vudl9pbmZvKCRyb290KSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVybWFnZW50b2luZm8nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJNYWdlbnRvSW5mbyBpbXBsZW1lbnRzIENsb25lclNpdGVJbmZvCnsKICAgIHByaXZhdGUgJHVybCA9ICcnOwogICAgcHJpdmF0ZSAkcm9vdCA9ICcnOwogICAgcHJpdmF0ZSAkY29uZmlnUGF0aCA9ICcnOwogICAgcHJpdmF0ZSAkdGFibGVQcmVmaXggPSAnJzsKICAgIHByaXZhdGUgJGNvbmZpZyA9ICcnOwogICAgcHJpdmF0ZSAkc2VydmVyQ29uZmlncyA9IGFycmF5KCk7CgogICAgcHVibGljIGZ1bmN0aW9uIHRvQXJyYXkoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJ3VybCcgICAgICAgICAgID0+ICR0aGlzLT51cmwsCiAgICAgICAgICAgICdyb290JyAgICAgICAgICA9PiAkdGhpcy0+cm9vdCwKICAgICAgICAgICAgJ2NvbmZpZ1BhdGgnICAgID0+ICR0aGlzLT5jb25maWdQYXRoLAogICAgICAgICAgICAndGFibGVQcmVmaXgnICAgPT4gJHRoaXMtPnRhYmxlUHJlZml4LAogICAgICAgICAgICAnbWFnZW50b0NvbmZpZycgPT4gYmFzZTY0X2VuY29kZSgkdGhpcy0+Y29uZmlnKSwKICAgICAgICAgICAgJ3NlcnZlckNvbmZpZ3MnID0+ICR0aGlzLT5zZXJ2ZXJDb25maWdzLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJvb3QKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbmZpZ1BhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRhYmxlUHJlZml4CiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb25maWcKICAgICAqIEBwYXJhbSBhcnJheSAgJHNlcnZlckNvbmZpZ3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR1cmwsICRyb290LCAkY29uZmlnUGF0aCwgJHRhYmxlUHJlZml4LCAkY29uZmlnLCAkc2VydmVyQ29uZmlncykKICAgIHsKICAgICAgICAkdGhpcy0+dXJsICAgICAgICAgICA9ICR1cmw7CiAgICAgICAgJHRoaXMtPnJvb3QgICAgICAgICAgPSAkcm9vdDsKICAgICAgICAkdGhpcy0+Y29uZmlnUGF0aCAgICA9ICRjb25maWdQYXRoOwogICAgICAgICR0aGlzLT50YWJsZVByZWZpeCAgID0gJHRhYmxlUHJlZml4OwogICAgICAgICR0aGlzLT5jb25maWcgICAgICAgID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+c2VydmVyQ29uZmlncyA9ICRzZXJ2ZXJDb25maWdzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDTVMoKQogICAgewogICAgICAgIHJldHVybiAnbWFnZW50byc7CiAgICB9Cgp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcm1hZ2VudG9zaXRlc291cmNlJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyTWFnZW50b1NpdGVTb3VyY2UgaW1wbGVtZW50cyBDbG9uZXJTaXRlU291cmNlCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDTVMoKQogICAgewogICAgICAgIHJldHVybiAnbWFnZW50byc7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldHVwKCRyb290LCAkdXJsLCAkZGIsICR0YWJsZVByZWZpeCwgJGZvcmNlUHJlZml4LCAkY29uZmlnQ29udGVudCwgJHJlYWRPbmx5KQogICAgewogICAgICAgICRjb25maWdQYXRoID0gJy9hcHAvZXRjL2Vudi5waHAnOwogICAgICAgICRwYXRoICAgICAgID0gJHJvb3QuIi9hcHAvZXRjL2Vudi5waHAiOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChlbXB0eSgkY29uZmlnQ29udGVudCkpIHsKICAgICAgICAgICAgICAgICRjb25maWdDb250ZW50ID0gY2xvbmVyX2dldF9jb250ZW50cygkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCEkcmVhZE9ubHkpIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICghZmlsZV9leGlzdHMoJHBhdGgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdObyBtYWdlbnRvIGNvbmZpZ3VyYXRpb24gZm91bmQnLCAnbm9fbWFnZW50b19jb25maWcnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbWFnZW50b0luZm8gICA9IHJlcXVpcmVfb25jZSAkcGF0aDsKICAgICAgICAgICAgJGRiSW5mb3JtYXRpb24gPSAkbWFnZW50b0luZm9bJ2RiJ107CiAgICAgICAgICAgICR0YWJsZVByZWZpeCAgID0gJGRiSW5mb3JtYXRpb25bJ3RhYmxlX3ByZWZpeCddOwogICAgICAgICAgICAkZGJDb25uZWN0aW9uICA9ICRkYkluZm9ybWF0aW9uWydjb25uZWN0aW9uJ11bJ2RlZmF1bHQnXTsKICAgICAgICAgICAgJGRldGVjdGVkICAgICAgPSBhcnJheShuZXcgQ2xvbmVyREJJbmZvKCRkYkNvbm5lY3Rpb25bJ3VzZXJuYW1lJ10sICRkYkNvbm5lY3Rpb25bJ3Bhc3N3b3JkJ10sICRkYkNvbm5lY3Rpb25bJ2hvc3QnXSwgJGRiQ29ubmVjdGlvblsnZGJuYW1lJ10pKTsKICAgICAgICAgICAgJGRiICAgICAgICAgICAgPSBjbG9uZXJfbWVyZ2VfZGJfaW5mbygoYXJyYXkpJGRiLCAkZGV0ZWN0ZWQsICEkcmVhZE9ubHkpOwogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoISRyZWFkT25seSkgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2xvbmVyX2RiX2Nvbm4oJGRiKS0+cGluZygpOwogICAgICAgICRtYWdlbnRvSW5mbyA9IG5ldyBDbG9uZXJNYWdlbnRvSW5mbygkdXJsLCAkcm9vdCwgJGNvbmZpZ1BhdGgsICR0YWJsZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsIHJlYWRfc2VydmVyX2NvbmZpZ19maWxlcygkcm9vdCkpOwogICAgICAgIHJldHVybiBuZXcgQ2xvbmVyU2V0dXBSZXN1bHQoJGRiLCAkbWFnZW50b0luZm8sIGNsb25lcl9lbnZfaW5mbygkcm9vdCkpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcm1hZ2VudG9vbmVpbmZvJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyTWFnZW50b09uZUluZm8gaW1wbGVtZW50cyBDbG9uZXJTaXRlSW5mbwp7CiAgICBwcml2YXRlICR1cmwgPSAnJzsKICAgIHByaXZhdGUgJHJvb3QgPSAnJzsKICAgIHByaXZhdGUgJGNvbmZpZ1BhdGggPSAnJzsKICAgIHByaXZhdGUgJHRhYmxlUHJlZml4ID0gJyc7CiAgICBwcml2YXRlICRjb25maWcgPSAnJzsKICAgIHByaXZhdGUgJHNlcnZlckNvbmZpZ3MgPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiB0b0FycmF5KCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICd1cmwnICAgICAgICAgICA9PiAkdGhpcy0+dXJsLAogICAgICAgICAgICAncm9vdCcgICAgICAgICAgPT4gJHRoaXMtPnJvb3QsCiAgICAgICAgICAgICdjb25maWdQYXRoJyAgICA9PiAkdGhpcy0+Y29uZmlnUGF0aCwKICAgICAgICAgICAgJ3RhYmxlUHJlZml4JyAgID0+ICR0aGlzLT50YWJsZVByZWZpeCwKICAgICAgICAgICAgJ21hZ2VudG9Db25maWcnID0+IGJhc2U2NF9lbmNvZGUoJHRoaXMtPmNvbmZpZyksCiAgICAgICAgICAgICdzZXJ2ZXJDb25maWdzJyA9PiAkdGhpcy0+c2VydmVyQ29uZmlncywKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyb290CiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb25maWdQYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YWJsZVByZWZpeAogICAgICogQHBhcmFtIHN0cmluZyAkY29uZmlnCiAgICAgKiBAcGFyYW0gYXJyYXkgICRzZXJ2ZXJDb25maWdzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdXJsLCAkcm9vdCwgJGNvbmZpZ1BhdGgsICR0YWJsZVByZWZpeCwgJGNvbmZpZywgJHNlcnZlckNvbmZpZ3MpCiAgICB7CiAgICAgICAgJHRoaXMtPnVybCAgICAgICAgICAgPSAkdXJsOwogICAgICAgICR0aGlzLT5yb290ICAgICAgICAgID0gJHJvb3Q7CiAgICAgICAgJHRoaXMtPmNvbmZpZ1BhdGggICAgPSAkY29uZmlnUGF0aDsKICAgICAgICAkdGhpcy0+dGFibGVQcmVmaXggICA9ICR0YWJsZVByZWZpeDsKICAgICAgICAkdGhpcy0+Y29uZmlnICAgICAgICA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPnNlcnZlckNvbmZpZ3MgPSAkc2VydmVyQ29uZmlnczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q01TKCkKICAgIHsKICAgICAgICByZXR1cm4gJ21hZ2VudG9fb25lJzsKICAgIH0KCn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVybWFnZW50b29uZXNpdGVzb3VyY2UnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJNYWdlbnRvT25lU2l0ZVNvdXJjZSBleHRlbmRzIENsb25lck1hZ2VudG9TaXRlU291cmNlCnsKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDTVMoKQogICAgewogICAgICAgIHJldHVybiAnbWFnZW50b19vbmUnOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXR1cCgkcm9vdCwgJHVybCwgJGRiLCAkdGFibGVQcmVmaXgsICRmb3JjZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsICRyZWFkT25seSkKICAgIHsKICAgICAgICAkY29uZmlnUGF0aCA9ICdhcHAvZXRjL2xvY2FsLnhtbCc7CiAgICAgICAgJGxvY2FsUGF0aCAgPSAkcm9vdC4iL2FwcC9ldGMvbG9jYWwueG1sIjsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKGVtcHR5KCRjb25maWdDb250ZW50KSkgewogICAgICAgICAgICAgICAgJGNvbmZpZ0NvbnRlbnQgPSBjbG9uZXJfZ2V0X2NvbnRlbnRzKCRsb2NhbFBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICghJHJlYWRPbmx5KSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRsb2NhbFBhdGgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdDb3VsZCBub3QgbG9hZCBtYWdlbnRvIGNvbmZpZ3VyYXRpb24nLCAnbm9fbWFnZW50b19jb25maWcnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWV4dGVuc2lvbl9sb2FkZWQoJ3NpbXBsZXhtbCcpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdDb3VsZCBub3QgbG9hZCBtYWdlbnRvLCBubyBzaW1wbGV4bWwgZXh0ZW5zaW9uJywgJ21hZ2VudG9fbm9fc2ltcGxleG1sJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJG1hZ2VudG9Mb2NhbFhtbCAgICAgICA9IHNpbXBsZXhtbF9sb2FkX2ZpbGUoJGxvY2FsUGF0aCwgIlNpbXBsZVhNTEVsZW1lbnQiLCBMSUJYTUxfTk9DREFUQSk7CiAgICAgICAgICAgICRtYWdlbnRvTG9jYWxKc29uICAgICAgPSBqc29uX2VuY29kZSgkbWFnZW50b0xvY2FsWG1sKTsKICAgICAgICAgICAgJG1hZ2VudG9Mb2NhbCAgICAgICAgICA9IGpzb25fZGVjb2RlKCRtYWdlbnRvTG9jYWxKc29uLCB0cnVlKTsKICAgICAgICAgICAgJG1hZ2VudG9Mb2NhbFJlc291cmNlcyA9ICRtYWdlbnRvTG9jYWxbJ2dsb2JhbCddWydyZXNvdXJjZXMnXTsKICAgICAgICAgICAgJGRiSW5mbyAgICAgICAgICAgICAgICA9ICRtYWdlbnRvTG9jYWxSZXNvdXJjZXNbJ2RlZmF1bHRfc2V0dXAnXVsnY29ubmVjdGlvbiddOwogICAgICAgICAgICAkdGFibGVQcmVmaXggICAgICAgICAgID0gJG1hZ2VudG9Mb2NhbFJlc291cmNlc1snZGInXVsndGFibGVfcHJlZml4J107CiAgICAgICAgICAgIC8vaGFuZGxlIGNhc2Ugd2hlbiB0YWJsZSBwcmVmaXggaXMgZW1wdHksIGF2b2lkIHRvIGJlIGFycmF5CiAgICAgICAgICAgIGlmIChlbXB0eSgkdGFibGVQcmVmaXgpKSB7CiAgICAgICAgICAgIAkkdGFibGVQcmVmaXggPSAnJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZGV0ZWN0ZWQgICAgICAgICAgICAgID0gYXJyYXkobmV3IENsb25lckRCSW5mbygkZGJJbmZvWyd1c2VybmFtZSddLCAkZGJJbmZvWydwYXNzd29yZCddLCAkZGJJbmZvWydob3N0J10sICRkYkluZm9bJ2RibmFtZSddKSk7CiAgICAgICAgICAgICRkYiAgICAgICAgICAgICAgICAgICAgPSBjbG9uZXJfbWVyZ2VfZGJfaW5mbygoYXJyYXkpJGRiLCAkZGV0ZWN0ZWQsICEkcmVhZE9ubHkpOwogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoISRyZWFkT25seSkgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2xvbmVyX2RiX2Nvbm4oJGRiKS0+cGluZygpOwogICAgICAgICRtYWdlbnRvSW5mbyA9IG5ldyBDbG9uZXJNYWdlbnRvT25lSW5mbygkdXJsLCAkcm9vdCwgJGNvbmZpZ1BhdGgsICR0YWJsZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsIHJlYWRfc2VydmVyX2NvbmZpZ19maWxlcygkcm9vdCkpOwogICAgICAgIHJldHVybiBuZXcgQ2xvbmVyU2V0dXBSZXN1bHQoJGRiLCAkbWFnZW50b0luZm8sIGNsb25lcl9lbnZfaW5mbygkcm9vdCkpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnBocGJiaW5mbycsIGZhbHNlKSk6CmNsYXNzIENsb25lclBocEJCSW5mbyBpbXBsZW1lbnRzIENsb25lclNpdGVJbmZvCnsKICAgIHByaXZhdGUgJHVybCA9ICcnOwogICAgcHJpdmF0ZSAkcm9vdCA9ICcnOwogICAgcHJpdmF0ZSAkY29uZmlnUGF0aCA9ICcnOwogICAgcHJpdmF0ZSAkdGFibGVQcmVmaXggPSAnJzsKICAgIHByaXZhdGUgJGNvbmZpZyA9ICcnOwogICAgcHJpdmF0ZSAkc2VydmVyQ29uZmlncyA9IGFycmF5KCk7CgogICAgcHVibGljIGZ1bmN0aW9uIHRvQXJyYXkoKQogICAgewogICAgICAgIHJldHVybiBhcnJheSgKICAgICAgICAgICAgJ3VybCcgICAgICAgICAgID0+ICR0aGlzLT51cmwsCiAgICAgICAgICAgICdyb290JyAgICAgICAgICA9PiAkdGhpcy0+cm9vdCwKICAgICAgICAgICAgJ2NvbmZpZ1BhdGgnICAgID0+ICR0aGlzLT5jb25maWdQYXRoLAogICAgICAgICAgICAndGFibGVQcmVmaXgnICAgPT4gJHRoaXMtPnRhYmxlUHJlZml4LAogICAgICAgICAgICAncGhwQkJDb25maWcnICAgPT4gYmFzZTY0X2VuY29kZSgkdGhpcy0+Y29uZmlnKSwKICAgICAgICAgICAgJ3NlcnZlckNvbmZpZ3MnID0+ICR0aGlzLT5zZXJ2ZXJDb25maWdzLAogICAgICAgICk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJvb3QKICAgICAqIEBwYXJhbSBzdHJpbmcgJGNvbmZpZ1BhdGgKICAgICAqIEBwYXJhbSBzdHJpbmcgJHRhYmxlUHJlZml4CiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb25maWcKICAgICAqIEBwYXJhbSBhcnJheSAgJHNlcnZlckNvbmZpZ3MKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR1cmwsICRyb290LCAkY29uZmlnUGF0aCwgJHRhYmxlUHJlZml4LCAkY29uZmlnLCAkc2VydmVyQ29uZmlncykKICAgIHsKICAgICAgICAkdGhpcy0+dXJsICAgICAgICAgICA9ICR1cmw7CiAgICAgICAgJHRoaXMtPnJvb3QgICAgICAgICAgPSAkcm9vdDsKICAgICAgICAkdGhpcy0+Y29uZmlnUGF0aCAgICA9ICRjb25maWdQYXRoOwogICAgICAgICR0aGlzLT50YWJsZVByZWZpeCAgID0gJHRhYmxlUHJlZml4OwogICAgICAgICR0aGlzLT5jb25maWcgICAgICAgID0gJGNvbmZpZzsKICAgICAgICAkdGhpcy0+c2VydmVyQ29uZmlncyA9ICRzZXJ2ZXJDb25maWdzOwoKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q01TKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3BocEJCJzsKICAgIH0KCn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVycGhwYmJzaXRlc291cmNlJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyUGhwQkJTaXRlU291cmNlIGltcGxlbWVudHMgQ2xvbmVyU2l0ZVNvdXJjZQp7CiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q01TKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3BocEJCJzsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0dXAoJHJvb3QsICR1cmwsICRkYiwgJHRhYmxlUHJlZml4LCAkZm9yY2VQcmVmaXgsICRjb25maWdDb250ZW50LCAkcmVhZE9ubHkpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5zZXR1cEJCUHJlc3MoJHJvb3QsICR1cmwsICRkYiwgJHRhYmxlUHJlZml4LCAkY29uZmlnQ29udGVudCwgJHJlYWRPbmx5KTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldHVwQkJQcmVzcygkcm9vdCwgJHVybCwgJGRiLCAkdGFibGVQcmVmaXgsICRjb25maWdDb250ZW50LCAkcmVhZE9ubHkpCiAgICB7CiAgICAgICAgJHBhdGggICAgICAgPSAkcm9vdC4nL2NvbmZpZy5waHAnOwogICAgICAgICRjb25maWdQYXRoID0gJ2NvbmZpZy5waHAnOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChlbXB0eSgkY29uZmlnQ29udGVudCkpIHsKICAgICAgICAgICAgICAgICRjb25maWdDb250ZW50ID0gY2xvbmVyX2dldF9jb250ZW50cygkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCEkcmVhZE9ubHkpIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRkYnVzZXIgICAgICAgPSAiIjsKICAgICAgICAgICAgJGRicGFzc3dkICAgICA9ICIiOwogICAgICAgICAgICAkZGJob3N0ICAgICAgID0gIiI7CiAgICAgICAgICAgICRkYm5hbWUgICAgICAgPSAiIjsKICAgICAgICAgICAgJHRhYmxlX3ByZWZpeCA9ICIiOwogICAgICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRwYXRoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignTm8gcGhwYmIgY29uZmlndXJhdGlvbiBmb3VuZCcsICdub19waHBiYl9jb25maWcnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWlzX2RpcihkaXJuYW1lKCRwYXRoKS4nL3BocGJiJykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oJ05vIHBocGJiIGRpcmVjdG9yeSBmb3VuZCcsICdub19waHBiYl9kaXInKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXF1aXJlX29uY2UgJHBhdGg7CiAgICAgICAgICAgICR0YWJsZVByZWZpeCA9ICR0YWJsZV9wcmVmaXg7CiAgICAgICAgICAgICRkZXRlY3RlZCAgICA9IGFycmF5KG5ldyBDbG9uZXJEQkluZm8oJGRidXNlciwgJGRicGFzc3dkLCAkZGJob3N0LCAkZGJuYW1lKSk7CiAgICAgICAgICAgICRkYiAgICAgICAgICA9IGNsb25lcl9tZXJnZV9kYl9pbmZvKChhcnJheSkkZGIsICRkZXRlY3RlZCwgISRyZWFkT25seSk7CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgIGlmICghJHJlYWRPbmx5KSB7CiAgICAgICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkc2l0ZUluZm8gPSBuZXcgQ2xvbmVyUGhwQkJJbmZvKCR1cmwsICRyb290LCAkY29uZmlnUGF0aCwgJHRhYmxlUHJlZml4LCAkY29uZmlnQ29udGVudCwgcmVhZF9zZXJ2ZXJfY29uZmlnX2ZpbGVzKCRyb290KSk7CiAgICAgICAgcmV0dXJuIG5ldyBDbG9uZXJTZXR1cFJlc3VsdCgkZGIsICRzaXRlSW5mbywgY2xvbmVyX2Vudl9pbmZvKCRyb290KSk7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWNsYXNzX2V4aXN0cygnY2xvbmVydmJ1bGxldGluaW5mbycsIGZhbHNlKSk6CmNsYXNzIENsb25lclZCdWxsZXRpbkluZm8gaW1wbGVtZW50cyBDbG9uZXJTaXRlSW5mbwp7CiAgICBwcml2YXRlICR1cmwgPSAnJzsKICAgIHByaXZhdGUgJHJvb3QgPSAnJzsKICAgIHByaXZhdGUgJGNvbmZpZ1BhdGggPSAnJzsKICAgIHByaXZhdGUgJHRhYmxlUHJlZml4ID0gJyc7CiAgICBwcml2YXRlICRjb25maWcgPSAnJzsKICAgIHByaXZhdGUgJHNlcnZlckNvbmZpZ3MgPSBhcnJheSgpOwoKICAgIHB1YmxpYyBmdW5jdGlvbiB0b0FycmF5KCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICd1cmwnICAgICAgICAgICAgID0+ICR0aGlzLT51cmwsCiAgICAgICAgICAgICdyb290JyAgICAgICAgICAgID0+ICR0aGlzLT5yb290LAogICAgICAgICAgICAnY29uZmlnUGF0aCcgICAgICA9PiAkdGhpcy0+Y29uZmlnUGF0aCwKICAgICAgICAgICAgJ3RhYmxlUHJlZml4JyAgICAgPT4gJHRoaXMtPnRhYmxlUHJlZml4LAogICAgICAgICAgICAndkJ1bGxldGluQ29uZmlnJyA9PiBiYXNlNjRfZW5jb2RlKCR0aGlzLT5jb25maWcpLAogICAgICAgICAgICAnc2VydmVyQ29uZmlncycgICA9PiAkdGhpcy0+c2VydmVyQ29uZmlncywKICAgICAgICApOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHN0cmluZyAkdXJsCiAgICAgKiBAcGFyYW0gc3RyaW5nICRyb290CiAgICAgKiBAcGFyYW0gc3RyaW5nICRjb25maWdQYXRoCiAgICAgKiBAcGFyYW0gc3RyaW5nICR0YWJsZVByZWZpeAogICAgICogQHBhcmFtIHN0cmluZyAkY29uZmlnCiAgICAgKiBAcGFyYW0gYXJyYXkgICRzZXJ2ZXJDb25maWdzCiAgICAgKi8KICAgIHB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgkdXJsLCAkcm9vdCwgJGNvbmZpZ1BhdGgsICR0YWJsZVByZWZpeCwgJGNvbmZpZywgJHNlcnZlckNvbmZpZ3MpCiAgICB7CiAgICAgICAgJHRoaXMtPnVybCAgICAgICAgICAgPSAkdXJsOwogICAgICAgICR0aGlzLT5yb290ICAgICAgICAgID0gJHJvb3Q7CiAgICAgICAgJHRoaXMtPmNvbmZpZ1BhdGggICAgPSAkY29uZmlnUGF0aDsKICAgICAgICAkdGhpcy0+dGFibGVQcmVmaXggICA9ICR0YWJsZVByZWZpeDsKICAgICAgICAkdGhpcy0+Y29uZmlnICAgICAgICA9ICRjb25maWc7CiAgICAgICAgJHRoaXMtPnNlcnZlckNvbmZpZ3MgPSAkc2VydmVyQ29uZmlnczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q01TKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3ZidWxsZXRpbic7CiAgICB9Cgp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnZidWxsZXRpbnNpdGVzb3VyY2UnLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJWQnVsbGV0aW5TaXRlU291cmNlIGltcGxlbWVudHMgQ2xvbmVyU2l0ZVNvdXJjZQp7CiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q01TKCkKICAgIHsKICAgICAgICByZXR1cm4gJ3ZidWxsZXRpbic7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldHVwKCRyb290LCAkdXJsLCAkZGIsICR0YWJsZVByZWZpeCwgJGZvcmNlUHJlZml4LCAkY29uZmlnQ29udGVudCwgJHJlYWRPbmx5KQogICAgewogICAgICAgIHJldHVybiAkdGhpcy0+c2V0dXBWQnVsbGV0aW4oJHJvb3QsICR1cmwsICRkYiwgJHRhYmxlUHJlZml4LCAkY29uZmlnQ29udGVudCwgJHJlYWRPbmx5KTsKICAgIH0KCiAgICBwcml2YXRlIGZ1bmN0aW9uIHNldHVwVkJ1bGxldGluKCRyb290LCAkdXJsLCAkZGIsICR0YWJsZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsICRyZWFkT25seSkKICAgIHsKICAgICAgICAkY29uZmlnUGF0aCA9ICdjb3JlL2luY2x1ZGVzL2NvbmZpZy5waHAnOwogICAgICAgICRwYXRoICAgICAgID0gJHJvb3QuJy8nLiRjb25maWdQYXRoOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChlbXB0eSgkY29uZmlnQ29udGVudCkpIHsKICAgICAgICAgICAgICAgICRjb25maWdDb250ZW50ID0gY2xvbmVyX2dldF9jb250ZW50cygkcGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgaWYgKCEkcmVhZE9ubHkpIHsKICAgICAgICAgICAgICAgIHRocm93ICRlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgICRjb25maWcgPSBhcnJheSgpOwogICAgICAgICAgICBpZiAoIWZpbGVfZXhpc3RzKCRwYXRoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignTm8gdmJ1bGxldGluIGNvbmZpZ3VyYXRpb24gZm91bmQnLCAnbm9fdmJ1bGxldGluX2NvbmZpZycpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlcXVpcmVfb25jZSAkcGF0aDsKICAgICAgICAgICAgJHRhYmxlUHJlZml4ID0gJGNvbmZpZ1snRGF0YWJhc2UnXVsndGFibGVwcmVmaXgnXTsKICAgICAgICAgICAgJGNvbm5JbmZvICAgID0gJGNvbmZpZ1snTWFzdGVyU2VydmVyJ107CiAgICAgICAgICAgICRwcm92aWRlZCAgICA9IGFycmF5KG5ldyBDbG9uZXJEQkluZm8oJGNvbm5JbmZvWyd1c2VybmFtZSddLCAkY29ubkluZm9bJ3Bhc3N3b3JkJ10sICRjb25uSW5mb1snc2VydmVybmFtZSddLCAkY29uZmlnWydEYXRhYmFzZSddWydkYm5hbWUnXSkpOwogICAgICAgICAgICAkZGIgICAgICAgICAgPSBjbG9uZXJfbWVyZ2VfZGJfaW5mbygoYXJyYXkpJGRiLCAkcHJvdmlkZWQsICEkcmVhZE9ubHkpOwogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICBpZiAoISRyZWFkT25seSkgewogICAgICAgICAgICAgICAgdGhyb3cgJGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2xvbmVyX2RiX2Nvbm4oJGRiKS0+cGluZygpOwogICAgICAgICR2QnVsbGV0aW5JbmZvID0gbmV3IENsb25lclZCdWxsZXRpbkluZm8oJHVybCwgJHJvb3QsICRjb25maWdQYXRoLCAkdGFibGVQcmVmaXgsICRjb25maWdDb250ZW50LCByZWFkX3NlcnZlcl9jb25maWdfZmlsZXMoJHJvb3QpKTsKICAgICAgICByZXR1cm4gbmV3IENsb25lclNldHVwUmVzdWx0KCRkYiwgJHZCdWxsZXRpbkluZm8sIGNsb25lcl9lbnZfaW5mbygkcm9vdCkpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcnN0YXRpY2luZm8nLCBmYWxzZSkpOgpjbGFzcyBDbG9uZXJTdGF0aWNJbmZvIGltcGxlbWVudHMgQ2xvbmVyU2l0ZUluZm8KewogICAgcHJpdmF0ZSAkdXJsID0gJyc7CiAgICBwcml2YXRlICRyb290ID0gJyc7CiAgICBwcml2YXRlICRoYXNEQiA9IGZhbHNlOwogICAgcHJpdmF0ZSAkZGJFcnJvcnMgPSBhcnJheSgpOwogICAgcHJpdmF0ZSAkc2VydmVyQ29uZmlncyA9IGFycmF5KCk7CgogICAgLyoqCiAgICAgKiBAcGFyYW0gc3RyaW5nICR1cmwKICAgICAqIEBwYXJhbSBzdHJpbmcgJHJvb3QKICAgICAqIEBwYXJhbSBib29sICAgJGhhc0RCCiAgICAgKiBAcGFyYW0gYXJyYXkgICRkYkVycm9ycwogICAgICogQHBhcmFtIGFycmF5ICAkc2VydmVyQ29uZmlncwogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHVybCwgJHJvb3QsICRoYXNEQiwgYXJyYXkgJGRiRXJyb3JzLCAkc2VydmVyQ29uZmlncykKICAgIHsKICAgICAgICAkdGhpcy0+dXJsICAgICAgICAgICA9ICR1cmw7CiAgICAgICAgJHRoaXMtPnJvb3QgICAgICAgICAgPSAkcm9vdDsKICAgICAgICAkdGhpcy0+aGFzREIgICAgICAgICA9ICRoYXNEQjsKICAgICAgICAkdGhpcy0+ZGJFcnJvcnMgICAgICA9ICRkYkVycm9yczsKICAgICAgICAkdGhpcy0+c2VydmVyQ29uZmlncyA9ICRzZXJ2ZXJDb25maWdzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiB0b0FycmF5KCkKICAgIHsKICAgICAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgICAgICd1cmwnICAgICAgICAgICA9PiAkdGhpcy0+dXJsLAogICAgICAgICAgICAncm9vdCcgICAgICAgICAgPT4gJHRoaXMtPnJvb3QsCiAgICAgICAgICAgICdoYXNEQicgICAgICAgICA9PiAkdGhpcy0+aGFzREIsCiAgICAgICAgICAgICdkYkVycm9ycycgICAgICA9PiAkdGhpcy0+ZGJFcnJvcnMsCiAgICAgICAgICAgICdzZXJ2ZXJDb25maWdzJyA9PiAkdGhpcy0+c2VydmVyQ29uZmlncywKICAgICAgICApOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDTVMoKQogICAgewogICAgICAgIHJldHVybiAnc3RhdGljJzsKICAgIH0KfQplbmRpZjsKCmlmICghY2xhc3NfZXhpc3RzKCdjbG9uZXJzdGF0aWNzaXRlc291cmNlJywgZmFsc2UpKToKY2xhc3MgQ2xvbmVyU3RhdGljU2l0ZVNvdXJjZSBpbXBsZW1lbnRzIENsb25lclNpdGVTb3VyY2UKewogICAgcHVibGljIGZ1bmN0aW9uIGdldENNUygpCiAgICB7CiAgICAgICAgcmV0dXJuICdzdGF0aWMnOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBzZXR1cCgkcm9vdCwgJHVybCwgJGRiLCAkdGFibGVQcmVmaXgsICRmb3JjZVByZWZpeCwgJGNvbmZpZ0NvbnRlbnQsICRyZWFkT25seSkKICAgIHsKICAgICAgICAkZGJJbmZvICAgPSBhcnJheSgpOwogICAgICAgICRoYXNEQiAgICA9IGZhbHNlOwogICAgICAgICRkYkVycm9ycyA9IGFycmF5KCk7CiAgICAgICAgaWYgKCFlbXB0eSgkZGJbMF1bJ2RiTmFtZSddKSkgewogICAgICAgICAgICAkaGFzREIgPSB0cnVlOwogICAgICAgICAgICAkY29ubiAgPSBjbG9uZXJfZGJfY29ubigkZGIpOwogICAgICAgICAgICBmb3JlYWNoICgkY29ubi0+Z2V0Q29ubmVjdGlvbklEcygpIGFzICRjb25uSUQpIHsKICAgICAgICAgICAgICAgICRjb25uLT51c2VDb25uZWN0aW9uKCRjb25uSUQpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAkY29ubi0+cGluZygpOwogICAgICAgICAgICAgICAgICAgICRkYkluZm9bXSA9ICRjb25uLT5nZXRDb25maWd1cmF0aW9uKCktPnRvQXJyYXkoKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsb25lckV4Y2VwdGlvbiAkZSkgewogICAgICAgICAgICAgICAgICAgICRjb25mICAgICAgID0gJGNvbm4tPmdldENvbmZpZ3VyYXRpb24oKTsKICAgICAgICAgICAgICAgICAgICAkZGJFcnJvcnNbXSA9IGFycmF5KAogICAgICAgICAgICAgICAgICAgICAgICAnc291cmNlJyA9PiAkY29uZi0+Z2V0SUQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgJ2NvZGUnICAgPT4gJGUtPmdldEVycm9yQ29kZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAnZXJyb3InICA9PiAkZS0+Z2V0TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICRjb25uLT5jbG9zZSgpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uICRlKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ldyBDbG9uZXJTZXR1cFJlc3VsdCgkZGJJbmZvLCBuZXcgQ2xvbmVyU3RhdGljSW5mbygkdXJsLCAkcm9vdCwgJGhhc0RCLCAkZGJFcnJvcnMsIHJlYWRfc2VydmVyX2NvbmZpZ19maWxlcygkcm9vdCkpLCBjbG9uZXJfZW52X2luZm8oJHJvb3QpKTsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfc291cmNlcycpKToKZnVuY3Rpb24gY2xvbmVyX3NvdXJjZXMoKQp7CiAgICByZXR1cm4gYXJyYXkoCiAgICAgICAgbmV3IENsb25lcldvcmRQcmVzc1NpdGVTb3VyY2UoKSwKICAgICAgICBuZXcgQ2xvbmVyRHJ1cGFsU2l0ZVNvdXJjZSgpLAogICAgICAgIG5ldyBDbG9uZXJKb29tbGFTaXRlU291cmNlKCksCiAgICAgICAgbmV3IENsb25lck1hZ2VudG9TaXRlU291cmNlKCksCiAgICAgICAgbmV3IENsb25lck1hZ2VudG9PbmVTaXRlU291cmNlKCksCiAgICAgICAgbmV3IENsb25lclBocEJCU2l0ZVNvdXJjZSgpLAogICAgICAgIG5ldyBDbG9uZXJWQnVsbGV0aW5TaXRlU291cmNlKCksCiAgICAgICAgbmV3IENsb25lclN0YXRpY1NpdGVTb3VyY2UoKSwKICAgICk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3NldHVwJykpOgpmdW5jdGlvbiBjbG9uZXJfc2V0dXAoJHJvb3QsICR1cmwsICRmb3JjZUNNUywgJHRhYmxlUHJlZml4ID0gJycsICRmb3JjZVByZWZpeCA9IGZhbHNlLCAkZGIgPSBudWxsLCAkY29uZmlnQ29udGVudCA9ICcnLCAkcmVhZE9ubHkgPSBmYWxzZSkKewogICAgJGUgPSBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdObyBzb3VyY2VzIGF2YWlsYWJsZSB0byBzZXR1cCcsICdub19zb3VyY2VzJyk7CiAgICBmb3JlYWNoIChjbG9uZXJfc291cmNlcygpIGFzICRzb3VyY2UpIHsKICAgICAgICBpZiAoc3RybGVuKCRmb3JjZUNNUykgJiYgJGZvcmNlQ01TICE9PSAkc291cmNlLT5nZXRDTVMoKSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuICRzb3VyY2UtPnNldHVwKCRyb290LCAkdXJsLCAkZGIsICR0YWJsZVByZWZpeCwgJGZvcmNlUHJlZml4LCAkY29uZmlnQ29udGVudCwgJHJlYWRPbmx5KTsKICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICAgICAgdHJpZ2dlcl9lcnJvcihzcHJpbnRmKCdDb3VsZCBub3Qgc2V0dXAgJXM6ICVzJywgJHNvdXJjZS0+Z2V0Q01TKCksICRlLT5nZXRNZXNzYWdlKCkpKTsKICAgICAgICB9CiAgICB9CiAgICB0aHJvdyAkZTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfYWN0aW9uX2dldF9lbnYnKSk6CmZ1bmN0aW9uIGNsb25lcl9hY3Rpb25fZ2V0X2VudigkdXJsLCAkZm9yY2VDTVMsICR0YWJsZVByZWZpeCwgJGZvcmNlUHJlZml4LCAkZGIsICRjb25maWdDb250ZW50LCAkcmVhZE9ubHkpCnsKICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ19fY2xvbmVyX2dldF9zdGF0ZScpKSB7CiAgICAgICAgLy8gVGhpcyBtYXkgYmUgaW5qZWN0ZWQganVzdCBiZWZvcmUgc2NyaXB0IHdyaXRlIGR1cmluZyBzZXR1cCB3aGlsZSBpbiBXb3JrZXIgcGx1Z2luIGNvbnRleHQsIGVnLiBpZiB3aGVuIHVzaW5nCiAgICAgICAgLy8gbG9jYWwtc3luYyBvciByZWd1bGFyIFdvcmtlciBzZXR1cC4gVGhpcyBpcyBkb25lIGJlY2F1c2Ugd2UgaGF2ZSByZWxpYWJsZSBpbmZvIHdoaWxlIGluIFdvcmtlciBwbHVnaW4gY29udGV4dAogICAgICAgIC8vIChlZy4gZGF0YWJhc2UgY3JlZGVudGlhbHMpLCBzbyB3ZSBkb24ndCBwYXJzZSBjb25maWd1cmF0aW9uIHN0YXRpY2FsbHkuCiAgICAgICAgcmV0dXJuIF9fY2xvbmVyX2dldF9zdGF0ZSgpOwogICAgfQogICAgJHJvb3QgICAgICAgICAgPSBkaXJuYW1lKF9fRklMRV9fKTsKICAgICRjb25maWdDb250ZW50ID0gYmFzZTY0X2RlY29kZSgkY29uZmlnQ29udGVudCk7CiAgICByZXR1cm4gY2xvbmVyX3NldHVwKCRyb290LCAkdXJsLCAkZm9yY2VDTVMsICR0YWJsZVByZWZpeCwgJGZvcmNlUHJlZml4LCAkZGIsICRjb25maWdDb250ZW50LCAkcmVhZE9ubHkpLT50b0FycmF5KCk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl9nZXRfc2l0ZV91cmwnKSk6CmZ1bmN0aW9uIGNsb25lcl9hY3Rpb25fZ2V0X3NpdGVfdXJsKCRkYiwgJHByZWZpeCkKewogICAgJGNvbm4gPSBjbG9uZXJfZGJfY29ubigkZGIpOwogICAgJHJvdyAgPSAkY29ubi0+cXVlcnkoIlNFTEVDVCBvcHRpb25fdmFsdWUgRlJPTSB7JHByZWZpeH1vcHRpb25zIFdIRVJFIG9wdGlvbl9uYW1lPSdzaXRldXJsJyIpLT5mZXRjaCgpOwogICAgaWYgKCEkcm93KSB7CiAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignT3B0aW9uICJzaXRldXJsIiBub3QgZm91bmQnLCAnbm9fc2l0ZXVybCcpOwogICAgfQogICAgcmV0dXJuIChzdHJpbmcpZW5kKCRyb3cpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9zZXRfd29yZHByZXNzX29wdGlvbnMnKSk6CmZ1bmN0aW9uIGNsb25lcl9zZXRfd29yZHByZXNzX29wdGlvbnMoJGRiLCAkcHJlZml4LCBhcnJheSAkb3B0aW9ucykKewogICAgJGNvbm4gPSBjbG9uZXJfZGJfY29ubigkZGIpOwogICAgZm9yZWFjaCAoJG9wdGlvbnMgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICBpZiAoJHZhbHVlID09PSBudWxsKSB7CiAgICAgICAgICAgICRjb25uLT5xdWVyeSgiREVMRVRFIEZST00geyRwcmVmaXh9b3B0aW9ucyBXSEVSRSBvcHRpb25fbmFtZSA9IDpvcHRpb25fbmFtZSIsIGFycmF5KAogICAgICAgICAgICAgICAgJ29wdGlvbl9uYW1lJyA9PiAka2V5LAogICAgICAgICAgICApKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkY29ubi0+cXVlcnkoIklOU0VSVCBJTlRPIHskcHJlZml4fW9wdGlvbnMgU0VUIG9wdGlvbl9uYW1lID0gOm9wdGlvbl9uYW1lLCBvcHRpb25fdmFsdWUgPSA6b3B0aW9uX3ZhbHVlIE9OIERVUExJQ0FURSBLRVkgVVBEQVRFIG9wdGlvbl92YWx1ZSA9IDp1cGRhdGVfb3B0aW9uX3ZhbHVlIiwgYXJyYXkoCiAgICAgICAgICAgICAgICAnb3B0aW9uX25hbWUnICAgICAgICAgPT4gJGtleSwKICAgICAgICAgICAgICAgICdvcHRpb25fdmFsdWUnICAgICAgICA9PiAkdmFsdWUsCiAgICAgICAgICAgICAgICAndXBkYXRlX29wdGlvbl92YWx1ZScgPT4gJHZhbHVlLCAvL2NhbiBub3QgdXNlIGR1cGxpY2F0ZSBib3VuZCBwYXJhbWV0ZXJzIG5hbWUKICAgICAgICAgICAgKSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFycmF5KCk7Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnc2V0X21hZ2VudG9fY29uZmlnJykpOgpmdW5jdGlvbiBzZXRfbWFnZW50b19jb25maWcoJGRiLCAkcHJlZml4LCBhcnJheSAkb3B0aW9ucykKewogICAgJGNvbm4gPSBjbG9uZXJfZGJfY29ubigkZGIpOwogICAgZm9yZWFjaCAoJG9wdGlvbnMgYXMgJGtleSA9PiAkdmFsdWUpIHsKICAgICAgICAkY29ubi0+cXVlcnkoIlVQREFURSB7JHByZWZpeH1jb3JlX2NvbmZpZ19kYXRhIFNFVCB2YWx1ZSA9IDpjb25maWdfdmFsdWUgV0hFUkUgcGF0aCA9IDpjb25maWdfcGF0aCIsIGFycmF5KAogICAgICAgICAgICAnY29uZmlnX3BhdGgnICA9PiAka2V5LAogICAgICAgICAgICAnY29uZmlnX3ZhbHVlJyA9PiAkdmFsdWUsCiAgICAgICAgKSk7CiAgICB9CiAgICByZXR1cm4gYXJyYXkoKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdzZXRfcGhwYmJfY29uZmlnJykpOgpmdW5jdGlvbiBzZXRfcGhwQkJfY29uZmlnKCRkYiwgJHByZWZpeCwgYXJyYXkgJG9wdGlvbnMpCnsKICAgICRjb25uID0gY2xvbmVyX2RiX2Nvbm4oJGRiKTsKICAgIGZvcmVhY2ggKCRvcHRpb25zIGFzICRrZXkgPT4gJHZhbHVlKSB7CiAgICAgICAgJGNvbm4tPnF1ZXJ5KCJVUERBVEUgeyRwcmVmaXh9Y29uZmlnIFNFVCBjb25maWdfdmFsdWUgPSA6Y29uZmlnX3ZhbHVlIFdIRVJFIGNvbmZpZ19uYW1lID0gOmNvbmZpZ19uYW1lIiwgYXJyYXkoCiAgICAgICAgICAgICdjb25maWdfbmFtZScgID0+ICRrZXksCiAgICAgICAgICAgICdjb25maWdfdmFsdWUnID0+ICR2YWx1ZSwKICAgICAgICApKTsKICAgIH0KICAgIHJldHVybiBhcnJheSgpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ3NldF92YnVsbGV0aW5fY29uZmlnJykpOgpmdW5jdGlvbiBzZXRfdkJ1bGxldGluX2NvbmZpZygkZGIsICRwcmVmaXgsIGFycmF5ICRvcHRpb25zKQp7CiAgICAkY29ubiA9IGNsb25lcl9kYl9jb25uKCRkYik7CiAgICBmb3JlYWNoICgkb3B0aW9ucyBhcyAka2V5ID0+ICR2YWx1ZSkgewogICAgICAgICRjb25uLT5xdWVyeSgiVVBEQVRFIHskcHJlZml4fXNldHRpbmcgU0VUIHZhbHVlID0gOmNvbmZpZ192YWx1ZSBXSEVSRSB2YXJuYW1lID0gOmNvbmZpZ19uYW1lIiwgYXJyYXkoCiAgICAgICAgICAgICdjb25maWdfbmFtZScgID0+ICRrZXksCiAgICAgICAgICAgICdjb25maWdfdmFsdWUnID0+ICR2YWx1ZSwKICAgICAgICApKTsKICAgIH0KICAgIHJldHVybiBhcnJheSgpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9hY3Rpb25fc2V0X2NvbmZpZ19vcHRpb25zJykpOgpmdW5jdGlvbiBjbG9uZXJfYWN0aW9uX3NldF9jb25maWdfb3B0aW9ucygkZGIsICRwcmVmaXgsIGFycmF5ICRvcHRpb25zLCAkY21zKQp7CiAgICBzd2l0Y2ggKCRjbXMpIHsKICAgICAgICBjYXNlICd3b3JkcHJlc3MnOgogICAgICAgICAgICByZXR1cm4gY2xvbmVyX3NldF93b3JkcHJlc3Nfb3B0aW9ucygkZGIsICRwcmVmaXgsICRvcHRpb25zKTsKICAgICAgICBjYXNlICdtYWdlbnRvJzoKICAgICAgICBjYXNlICdtYWdlbnRvX29uZSc6CiAgICAgICAgICAgIHJldHVybiBzZXRfbWFnZW50b19jb25maWcoJGRiLCAkcHJlZml4LCAkb3B0aW9ucyk7CiAgICAgICAgY2FzZSAncGhwQkInOgogICAgICAgICAgICByZXR1cm4gc2V0X3BocEJCX2NvbmZpZygkZGIsICRwcmVmaXgsICRvcHRpb25zKTsKICAgICAgICBjYXNlICd2YnVsbGV0aW4nOgogICAgICAgICAgICByZXR1cm4gc2V0X3ZidWxsZXRpbl9jb25maWcoJGRiLCAkcHJlZml4LCAkb3B0aW9ucyk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbigiQ291bGRuJ3QgY2hhbmdlIGNvbmZpZyBvcHRpb24uIFVuZGVmaW5lZCBjbXMuIik7CiAgICB9Cn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX2FjdGlvbl93cml0ZV9odGFjY2VzcycpKToKZnVuY3Rpb24gY2xvbmVyX2FjdGlvbl93cml0ZV9odGFjY2VzcygkZmlsZU5hbWUsICRyb290LCAkY29udGVudCwgJHBlcmZvcm1DbGVhbnVwKQp7CiAgICAkZXJyb3IgPSBjbG9uZXJfd3JpdGVfZmlsZSgkcm9vdC4iLyIuJGZpbGVOYW1lLCAwLCBiYXNlNjRfZGVjb2RlKCRjb250ZW50KSk7CiAgICBpZiAoIWVtcHR5KCRlcnJvcikpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoJHBlcmZvcm1DbGVhbnVwKSB7CiAgICAgICAgZm9yZWFjaCAoYXJyYXkoJHJvb3QuJy9jbG9uZXIucGhwJywgJHJvb3QuJy9jbG9uZXJfZXJyb3JfbG9nJykgYXMgJHBhdGgpIHsKICAgICAgICAgICAgdW5saW5rKCRwYXRoKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfYWN0aW9uX3dyaXRlX3NlcnZlcl9jb25maWd1cmF0aW9uJykpOgpmdW5jdGlvbiBjbG9uZXJfYWN0aW9uX3dyaXRlX3NlcnZlcl9jb25maWd1cmF0aW9uKCRyb290LCAkY29uZmlndXJhdGlvbiwgJHBlcmZvcm1DbGVhbnVwLCAkc3VmZml4LCAkY2xlYW51cEh0YWNjZXNzKQp7CiAgICBpZiAoJGNsZWFudXBIdGFjY2VzcykgewogICAgICAgIHVubGluayhzdHJsZW4oJHJvb3QpID8gcnRyaW0oJHJvb3QsICcvJykuJy8uaHRhY2Nlc3MnIDogJy5odGFjY2VzcycpOwogICAgfQogICAgJHJlc3VsdCA9IGFycmF5KCk7CiAgICBmb3JlYWNoICgkY29uZmlndXJhdGlvbiBhcyAkZmlsZU5hbWUgPT4gJGNvbnRlbnQpIHsKICAgICAgICBpZiAoIWJhc2U2NF9kZWNvZGUoJGNvbnRlbnQpKSB7CiAgICAgICAgICAgICRyZXN1bHRbXSA9IGFycmF5KCdwYXRoJyA9PiAkZmlsZU5hbWUsICdlcnJvcicgPT4gIk1pc3NpbmcgY29udGVudCIsICdzdGF0dXMnID0+IENsb25lclN0YXR1czo6Tk9fRklMRSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAkZXJyb3IgPSBjbG9uZXJfd3JpdGVfZmlsZSgkcm9vdC4iLyIuJGZpbGVOYW1lLiRzdWZmaXgsIDAsIGJhc2U2NF9kZWNvZGUoJGNvbnRlbnQpKTsKICAgICAgICBpZiAoIWVtcHR5KCRlcnJvcikpIHsKICAgICAgICAgICAgJHJlc3VsdFtdID0gYXJyYXkoJ3BhdGgnID0+ICRmaWxlTmFtZSwgJ2Vycm9yJyA9PiAkZXJyb3IsICdzdGF0dXMnID0+IENsb25lclN0YXR1czo6RVJST1IpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgJHJlc3VsdFtdID0gYXJyYXkoJ3BhdGgnID0+ICRmaWxlTmFtZSwgJ2Vycm9yJyA9PiAkZXJyb3IsICdzdGF0dXMnID0+IENsb25lclN0YXR1czo6T0spOwogICAgfQogICAgaWYgKCRwZXJmb3JtQ2xlYW51cCkgewogICAgICAgIGZvcmVhY2ggKGFycmF5KCRyb290LicvY2xvbmVyLnBocCcsICRyb290LicvY2xvbmVyX2Vycm9yX2xvZycpIGFzICRwYXRoKSB7CiAgICAgICAgICAgIHVubGluaygkcGF0aCk7CiAgICAgICAgfQogICAgICAgIGlmIChpc19kaXIoJHJvb3QuIi9td3BfZGIvIikpIHsKICAgICAgICAgICAgJGZpbGVzID0gZ2xvYigkcm9vdC4iL213cF9kYi8iLicqJywgR0xPQl9NQVJLKTsKICAgICAgICAgICAgZm9yZWFjaCAoJGZpbGVzIGFzICRmaWxlKSB7CiAgICAgICAgICAgICAgICB1bmxpbmsoJGZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJtZGlyKCRyb290LiIvbXdwX2RiLyIpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBhcnJheSgnZmlsZXMnID0+ICRyZXN1bHQpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9leGVjdXRlX2FjdGlvbicpKToKZnVuY3Rpb24gY2xvbmVyX2V4ZWN1dGVfYWN0aW9uKCRhY3Rpb24sIGFycmF5ICRwYXJhbXMsICRpZCkgewogICAgc3dpdGNoICgkYWN0aW9uID0gKHN0cmluZykkYWN0aW9uKSB7CiAgICAgICAgY2FzZSAncGluZyc6CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfYWN0aW9uX3BpbmcoKTsKICAgICAgICBjYXNlICdzdGF0JzoKICAgICAgICAgICAgcmV0dXJuIGNsb25lcl9hY3Rpb25fc3RhdCgkcGFyYW1zWydyb290J10sICRwYXJhbXNbJ2N1cnNvciddLCAkcGFyYW1zWydtYXhDb3VudCddLCAkcGFyYW1zWydtYXhQYXlsb2FkJ10sICRwYXJhbXNbJ3RpbWVvdXQnXSwgJHBhcmFtc1snYWRkUGF0aHMnXSwgJHBhcmFtc1snaGlkZVBhdGhzJ10sICRwYXJhbXNbJ3NraXBQYXRocyddLCAkcGFyYW1zWydza2lwU3lzdGVtUGF0aHMnXSwgJHBhcmFtc1snc2tpcEZpbGVzJ10sICRwYXJhbXNbJ3NraXBEaXJzJ10sICRwYXJhbXNbJ3RyYXZlcnNlJ10pOwogICAgICAgIGNhc2UgJ2hhc2gnOgogICAgICAgICAgICByZXR1cm4gY2xvbmVyX2FjdGlvbl9oYXNoKCRwYXJhbXNbJ3Jvb3QnXSwgJHBhcmFtc1snZmlsZXMnXSwgJHBhcmFtc1sndGVtcEhhc2hlcyddLCAkcGFyYW1zWyd0aW1lb3V0J10sICRwYXJhbXNbJ21heEhhc2hTaXplJ10sICRwYXJhbXNbJ2NodW5rU2l6ZSddLCAkcGFyYW1zWydoYXNoQnVmU2l6ZSddKTsKICAgICAgICBjYXNlICd0b3VjaCc6CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfYWN0aW9uX3RvdWNoKCRwYXJhbXNbJ3Jvb3QnXSwgJHBhcmFtc1snZmlsZXMnXSwgJHBhcmFtc1sndGltZW91dCddKTsKICAgICAgICBjYXNlICdyZWFkJzoKICAgICAgICAgICAgcmV0dXJuIGNsb25lcl9hY3Rpb25fcmVhZCgkcGFyYW1zWydyb290J10sICRwYXJhbXNbJ2lkJ10sICRwYXJhbXNbJ2ZpbGVzJ10sICRwYXJhbXNbJ2xhc3RPZmZzZXQnXSwgJHBhcmFtc1snbGltaXQnXSk7CiAgICAgICAgY2FzZSAnd3JpdGUnOgogICAgICAgICAgICByZXR1cm4gY2xvbmVyX2FjdGlvbl93cml0ZSgkcGFyYW1zWydyb290J10sICRwYXJhbXNbJ2ZpbGVzJ10sICRwYXJhbXNbJ2xhc3RPZmZzZXQnXSk7CiAgICAgICAgY2FzZSAncHVzaCc6CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfYWN0aW9uX3B1c2goJHBhcmFtc1sncm9vdCddLCAkcGFyYW1zWydyZW1vdGVSb290J10sICRwYXJhbXNbJ2lkJ10sICRwYXJhbXNbJ3JlbW90ZUlEJ10sICRwYXJhbXNbJ2ZpbGVzJ10sICRwYXJhbXNbJ3VybCddLCAkcGFyYW1zWydsYXN0T2Zmc2V0J10sICRwYXJhbXNbJ2xpbWl0J10pOwogICAgICAgIGNhc2UgJ3B1bGwnOgogICAgICAgICAgICByZXR1cm4gY2xvbmVyX2FjdGlvbl9wdWxsKCRwYXJhbXNbJ3Jvb3QnXSwgJHBhcmFtc1sncmVtb3RlUm9vdCddLCAkcGFyYW1zWydyZW1vdGVJRCddLCAkcGFyYW1zWydmaWxlcyddLCAkcGFyYW1zWyd1cmwnXSwgJHBhcmFtc1snbGFzdE9mZnNldCddLCAkcGFyYW1zWydsaW1pdCddKTsKICAgICAgICBjYXNlICdsaXN0X3RhYmxlcyc6CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfYWN0aW9uX2xpc3RfdGFibGVzKCRwYXJhbXNbJ2RiJ10sICRwYXJhbXNbJ3RhYmxlTmFtZXMnXSk7CiAgICAgICAgY2FzZSAnaGFzaF90YWJsZXMnOgogICAgICAgICAgICByZXR1cm4gY2xvbmVyX2FjdGlvbl9oYXNoX3RhYmxlcygkcGFyYW1zWydkYiddLCAkcGFyYW1zWyd0YWJsZXMnXSwgJHBhcmFtc1sndGltZW91dCddKTsKICAgICAgICBjYXNlICdkdW1wX3RhYmxlcyc6CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfYWN0aW9uX2R1bXBfdGFibGVzKCRwYXJhbXNbJ3Jvb3QnXSwgJHBhcmFtc1snaWQnXSwgJHBhcmFtc1snZGInXSwgJHBhcmFtc1snc3RhdGUnXSwgJHBhcmFtc1sndGltZW91dCddLCAkcGFyYW1zWydzdHJlYW0nXSk7CiAgICAgICAgY2FzZSAnZGVsZXRlX2ZpbGVzJzoKICAgICAgICAgICAgcmV0dXJuIGNsb25lcl9hY3Rpb25fZGVsZXRlX2ZpbGVzKCRwYXJhbXNbJ3Jvb3QnXSwgJHBhcmFtc1snZmlsZXMnXSwgJHBhcmFtc1snaWQnXSwgJHBhcmFtc1snZXJyb3JMb2dTaXplJ10pOwogICAgICAgIGNhc2UgJ2ZsdXNoX3Jld3JpdGVfcnVsZXMnOgogICAgICAgICAgICByZXR1cm4gY2xvbmVyX2FjdGlvbl9mbHVzaF9yZXdyaXRlX3J1bGVzKCRwYXJhbXNbJ2RiJ10sICRwYXJhbXNbJ2lkJ10sICRwYXJhbXNbJ3ByZWZpeCddLCAkcGFyYW1zWydhY3RpdmF0ZVdvcmtlciddLCAkcGFyYW1zWyd0aW1lb3V0J10sICRwYXJhbXNbJ2lzT3JpZ2luYWwnXSk7CiAgICAgICAgY2FzZSAnaGVhcnRiZWF0JzoKICAgICAgICAgICAgcmV0dXJuIGNsb25lcl9hY3Rpb25faGVhcnRiZWF0KCRwYXJhbXNbJ2RiJ10sICRwYXJhbXNbJ3ByZWZpeCddLCAkcGFyYW1zWydpZCddKTsKICAgICAgICBjYXNlICdpbXBvcnRfZGF0YWJhc2UnOgogICAgICAgICAgICByZXR1cm4gY2xvbmVyX2FjdGlvbl9pbXBvcnRfZGF0YWJhc2UoJHBhcmFtc1sncm9vdCddLCAkcGFyYW1zWydkYiddLCAkcGFyYW1zWydzdGF0ZSddLCAkcGFyYW1zWydvbGRQcmVmaXgnXSwgJHBhcmFtc1snbmV3UHJlZml4J10sICRwYXJhbXNbJ21heENvdW50J10sICRwYXJhbXNbJ3RpbWVvdXQnXSk7CiAgICAgICAgY2FzZSAnc2V0X2FkbWluJzoKICAgICAgICAgICAgcmV0dXJuIGNsb25lcl9hY3Rpb25fc2V0X2FkbWluKCRwYXJhbXNbJ2RiJ10sICRwYXJhbXNbJ3ByZWZpeCddLCAkcGFyYW1zWyd1c2VybmFtZSddLCAkcGFyYW1zWydwYXNzd29yZCddLCAkcGFyYW1zWydlbWFpbCddKTsKICAgICAgICBjYXNlICdtaWdyYXRlX2RhdGFiYXNlJzoKICAgICAgICAgICAgcmV0dXJuIGNsb25lcl9hY3Rpb25fbWlncmF0ZV9kYXRhYmFzZSgkcGFyYW1zWydkYiddLCAkcGFyYW1zWydjbXMnXSwgJHBhcmFtc1sndGltZW91dCddLCAkcGFyYW1zWydzdGF0ZSddKTsKICAgICAgICBjYXNlICdjb25uZWN0X2JhY2snOgogICAgICAgICAgICByZXR1cm4gY2xvbmVyX2FjdGlvbl9jb25uZWN0X2JhY2soJHBhcmFtc1snYWRkciddLCAkcGFyYW1zWydwYXRoJ10sICRwYXJhbXNbJ29yaWdpbiddLCAkcGFyYW1zWydjb25uVGltZW91dCddLCAkcGFyYW1zWydyd1RpbWVvdXQnXSwgJHBhcmFtc1snY2VydCddKTsKICAgICAgICBjYXNlICdjbGVhbnVwJzoKICAgICAgICAgICAgcmV0dXJuIGNsb25lcl9hY3Rpb25fY2xlYW51cCgkcGFyYW1zWydyb290J10pOwogICAgICAgIGNhc2UgJ2dldF9lbnYnOgogICAgICAgICAgICByZXR1cm4gY2xvbmVyX2FjdGlvbl9nZXRfZW52KCRwYXJhbXNbJ3VybCddLCAkcGFyYW1zWydmb3JjZUNNUyddLCAkcGFyYW1zWyd0YWJsZVByZWZpeCddLCAkcGFyYW1zWydmb3JjZVByZWZpeCddLCAkcGFyYW1zWydkYiddLCAkcGFyYW1zWydjb25maWdDb250ZW50J10sICRwYXJhbXNbJ3JlYWRPbmx5J10pOwogICAgICAgIGNhc2UgJ2dldF9zaXRlX3VybCc6CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfYWN0aW9uX2dldF9zaXRlX3VybCgkcGFyYW1zWydkYiddLCAkcGFyYW1zWydwcmVmaXgnXSk7CiAgICAgICAgY2FzZSAnc2V0X2NvbmZpZ19vcHRpb25zJzoKICAgICAgICAgICAgcmV0dXJuIGNsb25lcl9hY3Rpb25fc2V0X2NvbmZpZ19vcHRpb25zKCRwYXJhbXNbJ2RiJ10sICRwYXJhbXNbJ3ByZWZpeCddLCAkcGFyYW1zWydvcHRpb25zJ10sICRwYXJhbXNbJ2NtcyddKTsKICAgICAgICBjYXNlICd3cml0ZV9odGFjY2Vzcyc6CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfYWN0aW9uX3dyaXRlX2h0YWNjZXNzKCRwYXJhbXNbJ2ZpbGVOYW1lJ10sICRwYXJhbXNbJ3Jvb3QnXSwgJHBhcmFtc1snY29udGVudCddLCAkcGFyYW1zWydwZXJmb3JtQ2xlYW51cCddKTsKICAgICAgICBjYXNlICd3cml0ZV9zZXJ2ZXJfY29uZmlndXJhdGlvbic6CiAgICAgICAgICAgIHJldHVybiBjbG9uZXJfYWN0aW9uX3dyaXRlX3NlcnZlcl9jb25maWd1cmF0aW9uKCRwYXJhbXNbJ3Jvb3QnXSwgJHBhcmFtc1snY29uZmlndXJhdGlvbiddLCAkcGFyYW1zWydwZXJmb3JtQ2xlYW51cCddLCAkcGFyYW1zWydzdWZmaXgnXSwgJHBhcmFtc1snY2xlYW51cEh0YWNjZXNzJ10pOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oIkFjdGlvbiBcIiRhY3Rpb25cIiBub3QgZm91bmQiLCAnYWN0aW9uX25vdF9mb3VuZCcpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9ydW5fd3NfdHJhbnNhY3Rpb24nKSk6CmZ1bmN0aW9uIGNsb25lcl9ydW5fd3NfdHJhbnNhY3Rpb24oQ2xvbmVyV2ViU29ja2V0ICR3cykKewogICAgbGlzdCgkbWVzc2FnZSwgJGVvZikgPSAkd3MtPnJlYWRNZXNzYWdlKCk7CiAgICBpZiAoJGVvZikgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgICRkYXRhID0ganNvbl9kZWNvZGUoJG1lc3NhZ2UsIHRydWUpOwogICAgaWYgKCRkYXRhID09PSBudWxsIHx8ICRkYXRhID09PSBmYWxzZSkgewogICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oc3ByaW50ZigiSW52YWxpZCBKU09OIHBheWxvYWQ6ICVzIiwgYmFzZTY0X2VuY29kZSgkbWVzc2FnZSkpLCAnd3NfaW52YWxpZF9qc29uJyk7CiAgICB9CiAgICB1bnNldCgkbWVzc2FnZSk7CiAgICAkcmVzdWx0ID0gJGUgPSBudWxsOwogICAgJGlkICAgICA9ICRkYXRhWydpZCddOwogICAgJHN0cmVhbSA9IG5ldyBDbG9uZXJXZWJTb2NrZXRTdHJlYW0oJHdzLCAkaWQpOwogICAgdHJ5IHsKICAgICAgICAkcGFyYW1zID0gKGFycmF5KUAkZGF0YVsncGFyYW1zJ107CiAgICAgICAgaWYgKCFlbXB0eSgkcGFyYW1zWydzdHJlYW0nXSkpIHsKICAgICAgICAgICAgJHBhcmFtc1snc3RyZWFtJ10gPSAkc3RyZWFtOwogICAgICAgIH0KICAgICAgICAkcmVzdWx0ID0gY2xvbmVyX2V4ZWN1dGVfYWN0aW9uKCRkYXRhWydhY3Rpb24nXSwgJHBhcmFtcywgJGlkKTsKICAgIH0gY2F0Y2ggKENsb25lckV4Y2VwdGlvbiAkZSkgewogICAgICAgIGlmICgkZS0+Z2V0SW50ZXJuYWxFcnJvcigpID09PSAiMjAwNiIgfHwgJGUtPmdldEludGVybmFsRXJyb3IoKSA9PT0gIjIwMTMiKSB7CiAgICAgICAgICAgIC8vIE15U1FMIHNlcnZlciBoYXMgZ29uZSBhd2F5OyB1c2UgaGFja3kgbmV3IHdheSB0byBjbGVhciBjYWNoZS4KICAgICAgICAgICAgQ2xvbmVyREJBZGFwdGVyOjpjbG9zZUFsbCgpOwogICAgICAgIH0KICAgIH0KICAgICRzdHJlYW0tPnJlc3VsdCgkcmVzdWx0LCAkZSk7CiAgICByZXR1cm4gdHJ1ZTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfYWN0aW9uX2Nvbm5lY3RfYmFjaycpKToKZnVuY3Rpb24gY2xvbmVyX2FjdGlvbl9jb25uZWN0X2JhY2soJGFkZHIsICRwYXRoLCAkb3JpZ2luLCAkY29ublRpbWVvdXQsICRyd1RpbWVvdXQsICRjZXJ0KQp7CiAgICBzZXRfdGltZV9saW1pdCgxMiAqIDM2MDApOwogICAgLyoqIEBub2luc3BlY3Rpb24gUGhwRXhwcmVzc2lvblJlc3VsdFVudXNlZEluc3BlY3Rpb24gKi8KICAgIC8vIEluY2x1ZGUgdGhlIGZ1bmN0aW9uIGluIGJ1bmRsZXIuCiAgICBjbG9uZXJfcmV0dXJuX2ZhbHNlKCk7CiAgICBzZXRfZXJyb3JfaGFuZGxlcignY2xvbmVyX3JldHVybl9mYWxzZScpOwogICAgJHdzID0gbmV3IENsb25lcldlYlNvY2tldCgkYWRkciwgJHBhdGgsICRjb25uVGltZW91dCwgJHJ3VGltZW91dCwgJ2xvY2FsaG9zdCcsICRvcmlnaW4sICRjZXJ0KTsKICAgICR3cy0+Y29ubmVjdCgpOwogICAgdHJ5IHsKICAgICAgICB3aGlsZSAoY2xvbmVyX3J1bl93c190cmFuc2FjdGlvbigkd3MpKSB7CiAgICAgICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ2djX2NvbGxlY3RfY3ljbGVzJykpIHsKICAgICAgICAgICAgICAgIGdjX2NvbGxlY3RfY3ljbGVzKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGNhdGNoIChDbG9uZXJFeGNlcHRpb24gJGUpIHsKICAgICAgICBpZiAoJGUtPmdldEVycm9yQ29kZSgpICE9PSAnd3NfY2xvc2VkJykgewogICAgICAgICAgICB0aHJvdyAkZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gYXJyYXkoKTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfcGFnZV9jb25uZWN0JykpOgpmdW5jdGlvbiBjbG9uZXJfcGFnZV9jb25uZWN0KCRob3N0LCAkY29ubklEKSB7CiAgICB0cnkgewogICAgICAgIGNsb25lcl9hY3Rpb25fY29ubmVjdF9iYWNrKCRob3N0LCAnL2FwaS93cycsICRjb25uSUQsIDUsIDEyMCwgJycpOwogICAgfSBjYXRjaCAoQ2xvbmVyRXhjZXB0aW9uICRlKSB7CiAgICAgICAgdHJpZ2dlcl9lcnJvcigkZS0+Z2V0TWVzc2FnZSgpKTsKICAgICAgICBleGl0KGNsb25lcl9lcnJvcl9yZXN1bHQoJGUtPmdldEVycm9yQ29kZSgpLCAkZS0+Z2V0TWVzc2FnZSgpKSk7CiAgICB9IGNhdGNoIChFeGNlcHRpb24gJGUpIHsKICAgICAgICB0cmlnZ2VyX2Vycm9yKCRlLT5nZXRNZXNzYWdlKCkpOwogICAgICAgIGV4aXQoY2xvbmVyX2Vycm9yX3Jlc3VsdCgnJywgJGUtPmdldE1lc3NhZ2UoKSkpOwogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9wYWdlXzQwNCcpKToKZnVuY3Rpb24gY2xvbmVyX3BhZ2VfNDA0KCkgewo/PjwhZG9jdHlwZSBodG1sPgo8aHRtbCBsYW5nPSJlbiI+CjxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0iVVRGLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiCiAgICAgICAgICBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIHVzZXItc2NhbGFibGU9bm8sIGluaXRpYWwtc2NhbGU9MS4wLCBtYXhpbXVtLXNjYWxlPTEuMCwgbWluaW11bS1zY2FsZT0xLjAiPgogICAgPG1ldGEgaHR0cC1lcXVpdj0iWC1VQS1Db21wYXRpYmxlIiBjb250ZW50PSJpZT1lZGdlIj4KICAgIDx0aXRsZT40MDQgUGFnZSBOb3QgRm91bmQ8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo0MDQgcGFnZSBub3QgZm91bmQuCjwvYm9keT4KPC9odG1sPjw/cGhwCn0KZW5kaWY7CgppZiAoIWZ1bmN0aW9uX2V4aXN0cygnY2xvbmVyX3N5bmNfbWFpbicpKToKZnVuY3Rpb24gY2xvbmVyX3N5bmNfbWFpbigpIHsKICAgICRyb290ID0gZGlybmFtZShfX0ZJTEVfXyk7CiAgICAkdXJpICA9ICcnOwogICAgaWYgKGlzc2V0KCRfR0VUWydxJ10pICYmIGlzX3N0cmluZygkX0dFVFsncSddKSAmJiBzdHJsZW4oJF9HRVRbJ3EnXSkpIHsKICAgICAgICAkdXJpID0gJF9HRVRbJ3EnXTsKICAgIH0KICAgIHN3aXRjaCAoJHVyaSkgewogICAgICAgIGNhc2UgJyc6CiAgICAgICAgICAgIGNsb25lcl9wYWdlX2luZGV4KCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBjYXNlICdzdGF0ZV9wb2xsJzoKICAgICAgICAgICAgY2xvbmVyX3BhZ2Vfc3RhdGVfcG9sbCgpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgY2FzZSAnY29ubmVjdCc6CiAgICAgICAgICAgIGNsb25lcl9wYWdlX2Nvbm5lY3QoKHN0cmluZylAJF9HRVRbJ2hvc3QnXSwgKHN0cmluZylAJF9HRVRbJ2Nvbm5faWQnXSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBjYXNlICdjbGVhbnVwJzoKICAgICAgICAgICAgZWNobyBqc29uX2VuY29kZShjbG9uZXJfYWN0aW9uX2RlbGV0ZV9maWxlcygkcm9vdCwgYXJyYXkoJ2Nsb25lci5waHAnKSkpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgY2xvbmVyX3BhZ2VfNDA0KCk7CiAgICAgICAgICAgIHJldHVybjsKICAgIH0KfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfd3BfYWRtaW5fdXJsJykpOgpmdW5jdGlvbiBjbG9uZXJfd3BfYWRtaW5fdXJsKCRwYXRoID0gJycsICRzY2hlbWUgPSAnYWRtaW4nKQp7CiAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdhZG1pbl91cmwnKSkgewogICAgICAgIHJldHVybiBhZG1pbl91cmwoJHBhdGgsICRzY2hlbWUpOwogICAgfQogICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignRnVuY3Rpb24gYWRtaW5fdXJsIG5vdCBmb3VuZCcpOwp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl93cF9mb3JjZV9zc2xfYWRtaW4nKSk6CmZ1bmN0aW9uIGNsb25lcl93cF9mb3JjZV9zc2xfYWRtaW4oKQp7CiAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdmb3JjZV9zc2xfYWRtaW4nKSkgewogICAgICAgIHJldHVybiBmb3JjZV9zc2xfYWRtaW4oKTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKfQplbmRpZjsKCmlmICghZnVuY3Rpb25fZXhpc3RzKCdjbG9uZXJfd3BfZ2V0X3VzZXJzJykpOgpmdW5jdGlvbiBjbG9uZXJfd3BfZ2V0X3VzZXJzKCRhcmdzKQp7CiAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdnZXRfdXNlcnMnKSkgewogICAgICAgIHJldHVybiBnZXRfdXNlcnMoJGFyZ3MpOwogICAgfQogICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignRnVuY3Rpb24gZ2V0X3VzZXJzIG5vdCBmb3VuZCcpOwp9CmVuZGlmOwoKaWYgKCFjbGFzc19leGlzdHMoJ2Nsb25lcmxvYWRlcicsIGZhbHNlKSk6CmNsYXNzIENsb25lckxvYWRlcgp7CiAgICBwcml2YXRlICRob29rZWRBZG1pbiA9IGZhbHNlOwoKICAgIHByaXZhdGUgJGhvb2tlZEFkbWluV3BkYiA9IGZhbHNlOwoKICAgIHByaXZhdGUgJGVycm9ySGFuZGxlcjsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoQ2xvbmVyRXJyb3JIYW5kbGVyICRlcnJvckhhbmRsZXIpIHsKICAgICAgICAkdGhpcy0+ZXJyb3JIYW5kbGVyID0gJGVycm9ySGFuZGxlcjsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gaG9vaygpIHsKICAgICAgICBnbG9iYWwgJHdwX2ZpbHRlcjsKICAgICAgICAkd3BfZmlsdGVyWydhbGwnXVstOTk5OTk5XVswXSAgICAgICAgICAgICAgICAgID0gYXJyYXkoJ2Z1bmN0aW9uJyA9PiBhcnJheSgkdGhpcywgJ2hvb2tUaWNrJyksICdhY2NlcHRlZF9hcmdzJyA9PiAwKTsKICAgICAgICAkd3BfZmlsdGVyWydzZXRfYXV0aF9jb29raWUnXVstOTk5OTk5XVswXSAgICAgID0gYXJyYXkoJ2Z1bmN0aW9uJyA9PiBhcnJheSgkdGhpcywgJ3NldEF1dGhDb29raWUnKSwgJ2FjY2VwdGVkX2FyZ3MnID0+IDUpOwogICAgICAgICR3cF9maWx0ZXJbJ3NldF9sb2dnZWRfaW5fY29va2llJ11bLTk5OTk5OV1bMF0gPSBhcnJheSgnZnVuY3Rpb24nID0+IGFycmF5KCR0aGlzLCAnc2V0QXV0aENvb2tpZScpLCAnYWNjZXB0ZWRfYXJncycgPT4gNSk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldEF1dGhDb29raWUoJGNvb2tpZSwgJGV4cGlyZSwgJGV4cGlyYXRpb24sICR1c2VySWQsICRzY2hlbWUpIHsKICAgICAgICBzd2l0Y2ggKCRzY2hlbWUpIHsKICAgICAgICAgICAgY2FzZSAnYXV0aCc6CiAgICAgICAgICAgICAgICBpZiAoIWRlZmluZWQoJ0FVVEhfQ09PS0lFJykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkX0NPT0tJRVtBVVRIX0NPT0tJRV0gPSAkY29va2llOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgJ3NlY3VyZV9hdXRoJzoKICAgICAgICAgICAgICAgIGlmICghZGVmaW5lZCgnU0VDVVJFX0FVVEhfQ09PS0lFJykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkX0NPT0tJRVtTRUNVUkVfQVVUSF9DT09LSUVdID0gJGNvb2tpZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdsb2dnZWRfaW4nOgogICAgICAgICAgICAgICAgaWYgKCFkZWZpbmVkKCdMT0dHRURfSU5fQ09PS0lFJykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkX0NPT0tJRVtMT0dHRURfSU5fQ09PS0lFXSA9ICRjb29raWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIENsb25lckV4Y2VwdGlvbgogICAgICovCiAgICBwdWJsaWMgZnVuY3Rpb24gaG9va1RpY2soKSB7CiAgICAgICAgZ2xvYmFsICR3cGRiLCAkcGFnZW5vdzsKICAgICAgICAkdGhpcy0+ZXJyb3JIYW5kbGVyLT5yZWZyZXNoKCk7CiAgICAgICAgaWYgKCR0aGlzLT5ob29rZWRBZG1pbiB8fCAhZnVuY3Rpb25fZXhpc3RzKCdhZG1pbl91cmwnKSkgewogICAgICAgICAgICBpZiAoJHdwZGIpIHsKICAgICAgICAgICAgICAgICR0aGlzLT5hZG1pbkhvb2tXcGRiKCR3cGRiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+aG9va2VkQWRtaW4gPSB0cnVlOwoKICAgICAgICBAaW5pX3NldCgnbWVtb3J5X2xpbWl0JywgJzEwMjRNJyk7CiAgICAgICAgZGVmaW5lKCdET0lOR19BSkFYJywgdHJ1ZSk7CiAgICAgICAgJHBhZ2Vub3cgICAgICAgICAgICAgICAgICAgPSAnb3B0aW9ucy1nZW5lcmFsLnBocCc7CiAgICAgICAgJF9TRVJWRVJbJ1BIUF9TRUxGJ10gICAgICAgPSBwYXJzZV91cmwoY2xvbmVyX3dwX2FkbWluX3VybCgnb3B0aW9ucy1nZW5lcmFsLnBocCcpLCBQSFBfVVJMX1BBVEgpOwogICAgICAgICRfQ09PS0lFWydyZWRpcmVjdF9jb3VudCddID0gMTA7IC8vIGhhY2sgZm9yIHRoZSBXb3JkUHJlc3MgSFRUUFMgcGx1Z2luLCBzbyBpdCBkb2Vzbid0IHJlZGlyZWN0IHVzCiAgICAgICAgaWYgKGNsb25lcl93cF9mb3JjZV9zc2xfYWRtaW4oKSkgewogICAgICAgICAgICAkX1NFUlZFUlsnSFRUUFMnXSAgICAgICA9ICdvbic7CiAgICAgICAgICAgICRfU0VSVkVSWydTRVJWRVJfUE9SVCddID0gJzQ0Myc7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHdwZGIgJHdwZGIKICAgICAqCiAgICAgKiBAdGhyb3dzIENsb25lckV4Y2VwdGlvbgogICAgICovCiAgICBwcml2YXRlIGZ1bmN0aW9uIGFkbWluSG9va1dwZGIoJHdwZGIpIHsKICAgICAgICBpZiAoJHRoaXMtPmhvb2tlZEFkbWluV3BkYiB8fCAhZnVuY3Rpb25fZXhpc3RzKCd3cF9zZXRfY3VycmVudF91c2VyJykpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAkdGhpcy0+aG9va2VkQWRtaW5XcGRiID0gdHJ1ZTsKICAgICAgICAkdXNlcnMgICAgICAgICAgICAgICAgID0gY2xvbmVyX3dwX2dldF91c2VycyhhcnJheSgncm9sZScgPT4gJ2FkbWluaXN0cmF0b3InLCAnbnVtYmVyJyA9PiAxLCAnb3JkZXJieScgPT4gJ0lEJykpOwogICAgICAgICR1c2VyICAgICAgICAgICAgICAgICAgPSByZXNldCgkdXNlcnMpOwogICAgICAgIGlmICghJHVzZXIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENsb25lckV4Y2VwdGlvbignQ291bGQgbm90IGZpbmQgYW4gYWRtaW5pc3RyYXRvciB1c2VyIHRvIHVzZS4nLCAnbm9fYWRtaW5fdXNlcicpOwogICAgICAgIH0KICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCd3cF9zZXRfY3VycmVudF91c2VyJykpIHsKICAgICAgICAgICAgd3Bfc2V0X2N1cnJlbnRfdXNlcigkdXNlcik7CiAgICAgICAgfQogICAgICAgIGlmIChmdW5jdGlvbl9leGlzdHMoJ3dwX3NldF9hdXRoX2Nvb2tpZScpKSB7CiAgICAgICAgICAgIHdwX3NldF9hdXRoX2Nvb2tpZSgkdXNlci0+SUQpOwogICAgICAgIH0KICAgICAgICAkbG9naW5UaW1lID0gZGF0ZSgnWS1tLWQgSDppOnMnKTsKICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCdjdXJyZW50X3RpbWUnKSkgewogICAgICAgICAgICAkbG9naW5UaW1lID0gY3VycmVudF90aW1lKCdteXNxbCcpOwogICAgICAgIH0KICAgICAgICBpZiAoZnVuY3Rpb25fZXhpc3RzKCd1cGRhdGVfdXNlcl9tZXRhJykpIHsKICAgICAgICAgICAgdXBkYXRlX3VzZXJfbWV0YSgkdXNlci0+SUQsICdsYXN0X2xvZ2luX3RpbWUnLCAkbG9naW5UaW1lKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZ1bmN0aW9uX2V4aXN0cygnZG9fYWN0aW9uJykpIHsKICAgICAgICAgICAgZG9fYWN0aW9uKCd3cF9sb2dpbicsICR1c2VyLT51c2VyX2xvZ2luLCAkdXNlcik7CiAgICAgICAgfQogICAgfQp9CmVuZGlmOwoKaWYgKCFmdW5jdGlvbl9leGlzdHMoJ2Nsb25lcl9zZW5kX3N1Y2Nlc3NfcmVzcG9uc2UnKSk6CmZ1bmN0aW9uIGNsb25lcl9zZW5kX3N1Y2Nlc3NfcmVzcG9uc2UoJGlkLCAkZGF0YSkgewogICAgY2xvbmVyX3N0YW5kYXJkX3N0cmVhbSgkaWQpLT5yZXN1bHQoJGRhdGEpOwp9CmVuZGlmOwoKJGNsb25lclJvb3QgICA9IGRpcm5hbWUoX19GSUxFX18pOwokZXJyb3JIYW5kbGVyID0gbmV3IENsb25lckVycm9ySGFuZGxlcigkY2xvbmVyUm9vdC4nL2Nsb25lcl9lcnJvcl9sb2cnKTsKJGVycm9ySGFuZGxlci0+cmVnaXN0ZXIoKTsKaWYgKHN0cmxlbihzZXNzaW9uX2lkKCkpKSB7CiAgICBzZXNzaW9uX3dyaXRlX2Nsb3NlKCk7Cn0KCmVycm9yX3JlcG9ydGluZyhFX0FMTCk7CmluaV9zZXQoJ2Rpc3BsYXlfZXJyb3JzJywgMCk7CmluaV9zZXQoJ2xvZ19lcnJvcnMnLCAwKTsKZGF0ZV9kZWZhdWx0X3RpbWV6b25lX3NldCgnVVRDJyk7CmluaV9zZXQoJ21lbW9yeV9saW1pdCcsICcxMDI0TScpOwpzZXRfdGltZV9saW1pdCgxODAwKTsKCiRvYkxldmVsID0gb2JfZ2V0X2xldmVsKCk7CndoaWxlICgkb2JMZXZlbCkgewogICAgaWYgKCFAb2JfZW5kX2NsZWFuKCkpIHsKICAgICAgICBicmVhazsKICAgIH0KICAgICRvYkxldmVsLS07Cn0KCmlmIChkZWZpbmVkKCdDTE9ORVJfU1RBVEUnKSkgewogICAgY2xvbmVyX3N5bmNfbWFpbigpOwogICAgcmV0dXJuOwp9CgpnbG9iYWwgJEhUVFBfUkFXX1BPU1RfREFUQTsKJHJlcXVlc3RCb2R5ID0gJEhUVFBfUkFXX1BPU1RfREFUQTsKaWYgKCRyZXF1ZXN0Qm9keSA9PT0gbnVsbCB8fCBzdHJsZW4oJHJlcXVlc3RCb2R5KSA9PT0gMCkgewogICAgJHJlcXVlc3RCb2R5ID0gZmlsZV9nZXRfY29udGVudHMoJ3BocDovL2lucHV0Jyk7Cn0KaWYgKHN0cmxlbigkcmVxdWVzdEJvZHkpID09PSAwICYmIGRlZmluZWQoJ1NURElOJykpIHsKICAgICRyZXF1ZXN0Qm9keSA9IHN0cmVhbV9nZXRfY29udGVudHMoU1RESU4pOwp9CmlmIChkZWZpbmVkKCdDTE9ORVJfS0VZJykgJiYgc3RybGVuKENMT05FUl9LRVkpKSB7CiAgICBpZiAoIWlzc2V0KCRfR0VUWydrZXknXSkgfHwgJF9HRVRbJ2tleSddICE9PSBDTE9ORVJfS0VZKSB7CiAgICAgICAgJHJlcXVlc3QgPSBqc29uX2RlY29kZSgkcmVxdWVzdEJvZHksIHRydWUpOwogICAgICAgICRtZXNzYWdlID0gIktleSBtaXNtYXRjaGVzLiI7CiAgICAgICAgaWYgKGlzc2V0KCRyZXF1ZXN0WydpZCddKSAmJiBpc19zdHJpbmcoJHJlcXVlc3RbJ2lkJ10pKSB7CiAgICAgICAgICAgIGNsb25lcl9zZW5kX2Vycm9yX3Jlc3BvbnNlKCRyZXF1ZXN0WydpZCddLCBuZXcgQ2xvbmVyRXhjZXB0aW9uKCRtZXNzYWdlLCAna2V5X21pc21hdGNoJykpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGVjaG8gJG1lc3NhZ2U7CiAgICAgICAgcmV0dXJuOwogICAgfQp9CgppZiAoc3RybGVuKCRyZXF1ZXN0Qm9keSkgIT09IDAgJiYgc3RybmNtcCgkcmVxdWVzdEJvZHksICd7JywgMSkgIT09IDApIHsKICAgICRyZXF1ZXN0Qm9keSA9IGNsb25lcl9iYXNlNjRfcm90YXRlKCRyZXF1ZXN0Qm9keSk7Cn0KJHJlcXVlc3QgPSBqc29uX2RlY29kZSgkcmVxdWVzdEJvZHksIHRydWUpOwpnbG9iYWwgJGNsb25lclJlcXVlc3RJRDsKaWYgKCFlbXB0eSgkcmVxdWVzdFsnaWQnXSkgJiYgaXNfc3RyaW5nKCRyZXF1ZXN0WydpZCddKSkgewogICAgJGNsb25lclJlcXVlc3RJRCA9ICRyZXF1ZXN0WydpZCddOwp9CmlmIChlbXB0eSgkcmVxdWVzdFsnYWN0aW9uJ10pIHx8ICFpc19zdHJpbmcoJHJlcXVlc3RbJ2FjdGlvbiddKSkgewogICAgY2xvbmVyX3NlbmRfZXJyb3JfcmVzcG9uc2UoJGNsb25lclJlcXVlc3RJRCwgbmV3IENsb25lckV4Y2VwdGlvbigiQWN0aW9uIG5hbWUgbm90IHByb3ZpZGVkIiwgJ25vX2FjdGlvbicpKTsKICAgIHJldHVybjsKfQokZXJyb3JIYW5kbGVyLT5zZXRSZXF1ZXN0SUQoJGNsb25lclJlcXVlc3RJRCk7CgppZiAoJHJlcXVlc3RbJ2FjdGlvbiddID09PSAnZmx1c2hfcmV3cml0ZV9ydWxlcycpIHsKICAgIC8vIEl0J3MgaW1wb3J0YW50IHRvIGJvb3RzdHJhcCBXb3JkUHJlc3Mgd2hpbGUgaW4gdGhlIGdsb2JhbCBzY29wZSEKICAgIGlmKCFkZWZpbmVkKCdXUF9ERUJVRycpKSB7CiAgICAgICAgZGVmaW5lKCdXUF9ERUJVRycsIGZhbHNlKTsKICAgIH0KICAgIGlmKCFkZWZpbmVkKCdNV1BfU0tJUF9CT09UU1RSQVAnKSkgewogICAgICAgIGRlZmluZSgnTVdQX1NLSVBfQk9PVFNUUkFQJywgdHJ1ZSk7CiAgICB9CiAgICBpZighZGVmaW5lZCgnQVVUT01BVElDX1VQREFURVJfRElTQUJMRUQnKSkgewogICAgICAgIGRlZmluZSgnQVVUT01BVElDX1VQREFURVJfRElTQUJMRUQnLCB0cnVlKTsKICAgIH0KICAgIGlmKCFkZWZpbmVkKCdXUF9NRU1PUllfTElNSVQnKSkgewogICAgICAgIGRlZmluZSgnV1BfTUVNT1JZX0xJTUlUJywgJzI1Nk0nKTsKICAgIH0KICAgIGlmKCFkZWZpbmVkKCdXUF9NQVhfTUVNT1JZX0xJTUlUJykpIHsKICAgICAgICBkZWZpbmUoJ1dQX01BWF9NRU1PUllfTElNSVQnLCAnMjU2TScpOwogICAgfQogICAgaWYoIWRlZmluZWQoJ0RJU0FCTEVfV1BfQ1JPTicpKSB7CiAgICAgICAgZGVmaW5lKCdESVNBQkxFX1dQX0NST04nLCB0cnVlKTsKICAgIH0KCiAgICAkbG9hZGVyID0gbmV3IENsb25lckxvYWRlcigkZXJyb3JIYW5kbGVyKTsKICAgICRsb2FkZXItPmhvb2soKTsKICAgIC8vIC93cC1hZG1pbi9hZG1pbi5waHAgZmlsZSBjdXRzIHVzIG9mZiBhbmQgcmVkaXJlY3RzIHVzIHRvIC93cC1hZG1pbi91cGdyYWRlLnBocAogICAgLy8gaWYgYSBkYXRhYmFzZSB1cGRhdGUgaGFzIHRvIGJlIHBlcmZvcm1lZCBBTkQgJF9QT1NUIGlzIGVtcHR5LiBBdm9pZCB0aGF0LgogICAgaWYgKGlzX2FycmF5KCRfUE9TVCkpIHsKICAgICAgICAvLyBBdm9pZCBFX0NPTVBJTEVfRVJST1I6IENhbm5vdCByZS1hc3NpZ24gYXV0by1nbG9iYWwgdmFyaWFibGUgX1BPU1QKICAgICAgICAkX1BPU1RbJ2ZvbyddID0gJ2Jhcic7CiAgICB9IGVsc2UgewogICAgICAgICRfUE9TVCA9IGFycmF5KCdmb28nID0+ICdiYXInKTsKICAgIH0KCiAgICAkYWRtaW5TY3JpcHQgPSAkY2xvbmVyUm9vdC4nL3dwLWFkbWluL2FkbWluLnBocCc7CiAgICBpZiAoIWlzX2ZpbGUoJGFkbWluU2NyaXB0KSkgewogICAgICAgIC8qKiBAbm9pbnNwZWN0aW9uIFBocFVuaGFuZGxlZEV4Y2VwdGlvbkluc3BlY3Rpb24gKi8KICAgICAgICB0aHJvdyBuZXcgQ2xvbmVyRXhjZXB0aW9uKCdDb3VsZCBub3QgZmluZCB0aGUgL3dwLWFkbWluL2FkbWluLnBocCBmaWxlIHJlcXVpcmVkIHRvIGJvb3RzdHJhcCBXb3JkUHJlc3MuJywgJ3dwX2FkbWluX25vdF9mb3VuZCcpOwogICAgfQogICAgLyoqIEBub2luc3BlY3Rpb24gUGhwSW5jbHVkZUluc3BlY3Rpb24gKi8KICAgIHJlcXVpcmUgJGFkbWluU2NyaXB0OwoKICAgIGlmICghZGVmaW5lZCgnQUJTUEFUSCcpIHx8ICFkZWZpbmVkKCdXUElOQycpKSB7CiAgICAgICAgLyoqIEBub2luc3BlY3Rpb24gUGhwVW5oYW5kbGVkRXhjZXB0aW9uSW5zcGVjdGlvbiAqLwogICAgICAgIHRocm93IG5ldyBDbG9uZXJFeGNlcHRpb24oJ0FCU1BBVEggYW5kIFdQSU5DIG11c3QgYmUgZGVmaW5lZCBhZnRlciBpbml0aWFsaXphdGlvbiBvZiBhZG1pbiBjb250ZXh0LicpOwogICAgfQoKICAgICRhYnNQYXRoICAgPSBjbG9uZXJfY29uc3RhbnQoJ0FCU1BBVEgnKTsKICAgICR3cEluYyAgICAgPSBjbG9uZXJfY29uc3RhbnQoJ1dQSU5DJyk7CiAgICAkcGx1Z2dhYmxlID0gJGFic1BhdGguJHdwSW5jLicvcGx1Z2dhYmxlLnBocCc7CiAgICBpZiAoaXNfZmlsZSgkcGx1Z2dhYmxlKSkgewogICAgICAgIC8qKiBAbm9pbnNwZWN0aW9uIFBocEluY2x1ZGVJbnNwZWN0aW9uICovCiAgICAgICAgcmVxdWlyZV9vbmNlICRwbHVnZ2FibGU7CiAgICB9Cn0KCi8vIERvbid0IGFsbG93IGVycm9yIGhhbmRsaW5nLCBzaW5jZSB3ZSdyZSByZWx5aW5nIG9uIGVycm9yX2dldF9sYXN0KCkuCi8vIFRoaXMgaXMgYSBidWlsdC1pbiBXUCBmdW5jdGlvbi4KaWYgKCFmdW5jdGlvbl9leGlzdHMoJ19fcmV0dXJuX2ZhbHNlJykpIHsKICAgIGZ1bmN0aW9uIF9fcmV0dXJuX2ZhbHNlKCkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0Kc2V0X2Vycm9yX2hhbmRsZXIoJ19fcmV0dXJuX2ZhbHNlJyk7CiRyZXN1bHQgPSBjbG9uZXJfZXhlY3V0ZV9hY3Rpb24oJHJlcXVlc3RbJ2FjdGlvbiddLCAoYXJyYXkpQCRyZXF1ZXN0WydwYXJhbXMnXSwgJGNsb25lclJlcXVlc3RJRCk7CmNsb25lcl9zZW5kX3N1Y2Nlc3NfcmVzcG9uc2UoJGNsb25lclJlcXVlc3RJRCwgJHJlc3VsdCk7');
}
endif;
if (!function_exists('cloner_wp_filesystem')):
function cloner_wp_filesystem()
{
if (function_exists('WP_Filesystem')) {
WP_Filesystem();
return;
}
throw new ClonerException('Function WP_Filesystem not found');
}
endif;
if (!function_exists('cloner_create_file')):
function cloner_create_file($path, $contents, $mode = null)
{
if (@file_put_contents($path, $contents) !== false) {
if ($mode !== null) {
@chmod($path, $mode);
}
return null;
}
$error = cloner_last_error_for('file_put_contents');
if (@chmod($path, 0666) !== false && @file_put_contents($path, $contents) !== false) {
if ($mode !== null) {
@chmod($path, $mode);
}
return null;
}
if (defined('ABSPATH') && is_file(ABSPATH.'wp-admin/includes/file.php')) {
require_once ABSPATH.'wp-admin/includes/file.php';
cloner_wp_filesystem();
/** @var WP_Filesystem $wp_filesystem */
global $wp_filesystem;
if (!$wp_filesystem) {
return sprintf('could not load WP_Filesystem; PHP write error: %s', $error);
}
if (!$wp_filesystem->connect()) {
$errorCode = 'unknown';
$errorMessage = 'connect returned false';
foreach ($wp_filesystem->errors as $code => $messages) {
foreach ($messages as $message) {
$errorCode = $code;
$errorMessage = $message;
}
}
return sprintf('WP_Filesystem error [%s]: %s; PHP write error: %s', $errorCode, $errorMessage, $error);
}
$ok = $wp_filesystem->put_contents(ABSPATH.'cloner.php', $contents);
if (!$ok) {
$vars = get_object_vars($wp_filesystem);
if (!empty($vars['errors']) && $vars['errors'] instanceof WP_Error) {
$wpError = implode('; ', $vars['errors']->get_error_messages());
} else {
$wpError = 'unknown error';
$lastError = error_get_last();
if (!empty($lastError['message'])) {
$wpError = $lastError['message'];
}
}
return sprintf('could not write via %s: %s; PHP write error: %s', get_class($wp_filesystem), $wpError, $error);
}
return null;
}
return $error;
}
endif;
if (!class_exists('clonerparsedwpconfiginfo', false)):
class ClonerParsedWPConfigInfo
{
public $dbUser = '';
public $dbPassword = '';
public $dbHost = '';
public $dbName = '';
public $wpTablePrefix = '';
public $dbSSL = false;
}
endif;
if (!function_exists('cloner_get_wp_config_table_prefix')):
function cloner_get_wp_config_table_prefix(array $tokens)
{
$phase = 0;
foreach ($tokens as $token) {
if (is_array($token) && ($token[0] === T_WHITESPACE || $token[0] === T_COMMENT || $token[0] === T_DOC_COMMENT)) {
// Skip whitespace and comment tokens.
continue;
}
if ($phase === 0) {
if (is_array($token) && $token[0] === T_VARIABLE && strtolower($token[1]) === '$table_prefix') {
$phase = 1;
}
} elseif ($phase === 1 && $token === '=') {
$phase = 2;
} elseif ($phase === 2 && is_array($token) && $token[0] === T_CONSTANT_ENCAPSED_STRING) {
return eval(sprintf('return %s;', $token[1]));
} else {
$phase = 0;
}
}
return null;
}
endif;
if (!function_exists('cloner_get_constants_from_tokens')):
function cloner_get_constants_from_tokens(array $tokens, array $searchedConstants)
{
$definitions = array();
$phase = 0;
$lastDefinition = '';
$lastValue = '';
$indent = 0;
foreach ($tokens as $token) {
if (is_array($token) && ($token[0] === T_WHITESPACE || $token[0] === T_COMMENT || $token[0] === T_DOC_COMMENT)) {
// Skip whitespace and comment tokens.
continue;
}
if ($phase === 0) {
// Look for a 'define' function call.
if (is_array($token) && $token[0] === T_STRING && strtolower($token[1]) === 'define') {
// This is a 'define' call, move to next phase.
$phase = 1;
}
} elseif ($phase === 1 && $token === '(') {
// Open parentheses found, move to next phase.
$phase = 2;
} elseif ($phase === 2 && is_array($token) && $token[0] === T_CONSTANT_ENCAPSED_STRING) {
// Constant string found, save it for later
$lastDefinition = trim($token[1], '"\'');
//if we are not searchig for that constant we skip it.
if (!in_array($lastDefinition, $searchedConstants, true)) {
$phase = 0;
$lastDefinition = '';
continue;
}
$phase = 3;
} elseif ($phase === 3 && $token === ',') {
// Comma found.
$phase = 4;
} elseif ($phase === 4) {
if ($token === '(') {
$indent++;
} elseif ($token === ')') {
if ($indent === 0) {
$definitions[$lastDefinition] = eval(sprintf('return %s;', $lastValue));
$phase = 0;
$lastValue = '';
continue;
} else {
$indent--;
}
}
$lastValue .= is_array($token) ? $token[1] : $token;
} else {
// Unsupported token found, reset the parser phase.
$phase = 0;
$lastValue = '';
}
}
return $definitions;
}
endif;
if (!function_exists('cloner_env_parse_wp_config')):
function cloner_env_parse_wp_config($config)
{
$tokens = token_get_all($config);
$dbConstants = array('DB_USER', 'DB_PASSWORD', 'DB_HOST', 'DB_NAME', 'DB_SSL');
$constants = cloner_get_constants_from_tokens($tokens, $dbConstants);
foreach ($dbConstants as $constant) {
if (!isset($constants[$constant]) && $constant !== 'DB_SSL') {
throw new ClonerException("Constant $constant not found inside wp-config.php");
}
}
$info = new ClonerParsedWPConfigInfo();
$info->dbUser = $constants['DB_USER'];
$info->dbPassword = $constants['DB_PASSWORD'];
$info->dbHost = $constants['DB_HOST'];
$info->dbName = $constants['DB_NAME'];
$tablePrefix = cloner_get_wp_config_table_prefix($tokens);
$info->dbSSL = isset($constants['DB_SSL']) ? (bool)$constants['DB_SSL'] : false;
if ($tablePrefix === null) {
throw new ClonerException('Variable $table_prefix could not be parsed from wp-config.php');
}
$info->wpTablePrefix = $tablePrefix;
return $info;
}
endif;
if (!function_exists('cloner_get_static_site_defining_options')):
function cloner_get_static_site_defining_options(ClonerDBAdapter $conn, $prefix)
{
$backupOptions = cloner_keep_options_list();
$keepOptions = array();
foreach ($backupOptions as $option) {
try {
$stmt = $conn->query("SELECT option_value FROM {$prefix}options WHERE option_name = :option LIMIT 1", array(
'option' => $option,
));
$value = $stmt->fetch();
$stmt->free();
} catch (Exception $e) {
trigger_error(sprintf('Could not select option %s from %s: %s', $option, $prefix.'options', $e->getMessage()));
return array();
}
if ($value === null) {
continue;
}
$keepOptions[$option] = end($value);
}
return $keepOptions;
}
endif;
if (!class_exists('clonerwordpresssitesource', false)):
class ClonerWordPressSiteSource implements ClonerSiteSource
{
private $defaultContent = 'wp-content';
private $defaultPlugins = 'wp-content/plugins';
private $defaultMuPlugins = 'wp-content/mu-plugins';
private $defaultUploads = 'wp-content/uploads';
public function getCMS()
{
return 'wordpress';
}
/**
* @param string $root
* @param string $url
* @param array|null $db DB info from source, might be empty.
* @param string $tablePrefix Table prefix from source, might be empty.
* @param string $configContent wp-config.php from source, might be empty.
* @param string $readOnly Allows to complete setup when config file doesn't exit on server
*
* @return ClonerSetupResult
* @throws ClonerException
*/
public function setup($root, $url, $db, $tablePrefix, $forcePrefix, $configContent, $readOnly)
{
global $wpdb;
if (!empty($wpdb)) {
return $this->setupWorker($url, !$readOnly, $db);
}
return $this->setupStatic($root, $url, $db, $tablePrefix, $forcePrefix, $configContent, $readOnly);
}
/**
* @param string $urlOverride
* @param bool $isSource
* @param array|null $dbOverrides
*
* @return ClonerSetupResult
* @throws ClonerException
*/
private function setupWorker($urlOverride, $isSource, array $dbOverrides = null)
{
$absPath = cloner_constant('ABSPATH');
$result = new ClonerSetupResult(cloner_db_info_from_worker($isSource, $dbOverrides), cloner_wp_info_from_worker($urlOverride), cloner_env_info($absPath), cloner_get_site_defining_options());
$append = sprintf("\nfunction __cloner_get_state() {\n return %s;\n}\n", var_export($result->toArray(), true));
$clonerScript = cloner_script();
$result->workerOK = true;
if (strlen($clonerScript)) {
if ($error = cloner_create_file("$absPath/cloner.php", $clonerScript.$append, 0444)) {
$result->noRelay = true;
return $result;
}
} else {
$result->noRelay = true;
}
cloner_create_file("$absPath/cloner_error_log", '', 0666);
return $result;
}
/**
* @param string $root
* @param string $url
* @param array|null $db DB info from source, might be empty.
* @param string $tablePrefix Table prefix from source, might be empty.
* @param bool $forcePrefix Table prefix from source, might be empty.
* @param string $configContent wp-config.php from source, might be empty.
* @param string $readOnly Allows to complete setup when config file doesn't exit on server
*
* @return ClonerSetupResult
* @throws ClonerException
*/
private function setupStatic($root, $url, $db, $tablePrefix, $forcePrefix, $configContent, $readOnly)
{
$wpConfigPath = 'wp-config.php';
$checkPrefix = $tablePrefix;
try {
if (empty($configContent)) {
list($wpConfigPath, $configContent) = cloner_env_read_wp_config($root, false);
if (!is_dir($root.'/wp-admin') || !is_dir($root.'/wp-includes')
|| !is_file($root.'/wp-load.php') || !is_file($root.'/wp-settings.php')) {
throw new ClonerException('No WordPress core files found', 'no_wordpress_core');
}
}
} catch (Exception $e) {
if (!$readOnly) {
throw $e;
}
}
try {
if (defined('DB_NAME') && defined('DB_USER') && defined('DB_PASSWORD') && defined('DB_HOST') && is_file("/pagely/wp-config-hosting.php")) {
$wpConfigInfo = new ClonerParsedWPConfigInfo();
$wpConfigInfo->dbUser = DB_USER;
$wpConfigInfo->dbPassword = DB_PASSWORD;
$wpConfigInfo->dbHost = DB_HOST;
$wpConfigInfo->dbName = DB_NAME;
$wpConfigInfo->dbSSL = defined('DB_SSL') && (bool)DB_SSL;
$wpConfigInfo->wpTablePrefix = cloner_get_wp_config_table_prefix(token_get_all(file_get_contents("/pagely/wp-config-hosting.php")));
} else {
if (strlen($configContent) === 0) {
// Find this website's wp-config.php.
list($wpConfigPath, $configContent) = cloner_env_read_wp_config($root, false);
}
$wpConfigInfo = cloner_env_parse_wp_config($configContent);
}
$detected = array(new ClonerDBInfo($wpConfigInfo->dbUser, $wpConfigInfo->dbPassword, $wpConfigInfo->dbHost, $wpConfigInfo->dbName, $wpConfigInfo->dbSSL));
$db = cloner_merge_db_info((array)$db, $detected, !$readOnly);
$checkPrefix = $wpConfigInfo->wpTablePrefix;
if (!$forcePrefix) {
$tablePrefix = $wpConfigInfo->wpTablePrefix;
}
} catch (Exception $e) {
if (!$readOnly) {
throw $e;
}
}
// Verify connection info.
$conn = cloner_db_conn($db);
$conn->ping();
$clonerWpInfo = new ClonerWPInfo($url, $root, $tablePrefix, $wpConfigPath, $configContent,
'', 'wp-content', 'wp-content/plugins', 'wp-content/mu-plugins', 'wp-content/uploads', read_server_config_files($root));
return new ClonerSetupResult($db, $clonerWpInfo, cloner_env_info($root), cloner_get_static_site_defining_options($conn, $checkPrefix));
}
}
endif;
$source = new ClonerWordPressSiteSource();
$args = json_decode(base64_decode('bnVsbA=='), true);
if (!is_array($args)) {
$args = array();
}
if (empty($args['root'])) {
$args['root'] = rtrim(ABSPATH, '\\/');
}
if (empty($args['url'])) {
$args['url'] = site_url();
}
if (empty($args['db'])) {
$args['db'] = null;
}
if (empty($args['tablePrefix'])) {
global $table_prefix;
$args['tablePrefix'] = $table_prefix;
}
if (empty($args['configContent'])) {
$args['configContent'] = '';
}
if (!isset($args['readOnly'])) {
$args['readOnly'] = false;
}
$result = $source->setup($args['root'], $args['url'], $args['db'], $args['tablePrefix'], false, $args['configContent'], $args['readOnly']);
return array('ok' => true) + $result->toArray();