22337 lines
1.9 MiB
22337 lines
1.9 MiB
/******/ (() => { // webpackBootstrap
|
||
/******/ var __webpack_modules__ = ({
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/internal.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/internal.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports._exposeCertSettings = exports._exposeProxySettings = exports._normalizeSeparators = exports._isRooted = exports._getDirectoryName = exports._ensureRooted = exports._loadData = exports._ensurePatternRooted = exports._getFindInfoFromPattern = exports._cloneMatchOptions = exports._legacyFindFiles_convertPatternToRegExp = exports._which = exports._checkPath = exports._exist = exports._debug = exports._error = exports._warning = exports._command = exports._getVariableKey = exports._getVariable = exports._loc = exports._setResourcePath = exports._setErrStream = exports._setStdStream = exports._writeLine = exports._endsWith = exports._startsWith = exports._vault = exports._knownVariableMap = void 0;
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js");
|
||
var util = __webpack_require__(/*! util */ "util");
|
||
var tcm = __webpack_require__(/*! ./taskcommand */ "./node_modules/azure-pipelines-task-lib/taskcommand.js");
|
||
var vm = __webpack_require__(/*! ./vault */ "./node_modules/azure-pipelines-task-lib/vault.js");
|
||
var semver = __webpack_require__(/*! semver */ "./node_modules/semver/semver.js");
|
||
var crypto = __webpack_require__(/*! crypto */ "crypto");
|
||
/**
|
||
* Hash table of known variable info. The formatted env var name is the lookup key.
|
||
*
|
||
* The purpose of this hash table is to keep track of known variables. The hash table
|
||
* needs to be maintained for multiple reasons:
|
||
* 1) to distinguish between env vars and job vars
|
||
* 2) to distinguish between secret vars and public
|
||
* 3) to know the real variable name and not just the formatted env var name.
|
||
*/
|
||
exports._knownVariableMap = {};
|
||
//-----------------------------------------------------
|
||
// Validation Checks
|
||
//-----------------------------------------------------
|
||
// async await needs generators in node 4.x+
|
||
if (semver.lt(process.versions.node, '4.2.0')) {
|
||
_warning('Tasks require a new agent. Upgrade your agent or node to 4.2.0 or later');
|
||
}
|
||
//-----------------------------------------------------
|
||
// String convenience
|
||
//-----------------------------------------------------
|
||
function _startsWith(str, start) {
|
||
return str.slice(0, start.length) == start;
|
||
}
|
||
exports._startsWith = _startsWith;
|
||
function _endsWith(str, end) {
|
||
return str.slice(-end.length) == end;
|
||
}
|
||
exports._endsWith = _endsWith;
|
||
//-----------------------------------------------------
|
||
// General Helpers
|
||
//-----------------------------------------------------
|
||
var _outStream = process.stdout;
|
||
var _errStream = process.stderr;
|
||
function _writeLine(str) {
|
||
_outStream.write(str + os.EOL);
|
||
}
|
||
exports._writeLine = _writeLine;
|
||
function _setStdStream(stdStream) {
|
||
_outStream = stdStream;
|
||
}
|
||
exports._setStdStream = _setStdStream;
|
||
function _setErrStream(errStream) {
|
||
_errStream = errStream;
|
||
}
|
||
exports._setErrStream = _setErrStream;
|
||
//-----------------------------------------------------
|
||
// Loc Helpers
|
||
//-----------------------------------------------------
|
||
var _locStringCache = {};
|
||
var _resourceFiles = {};
|
||
var _libResourceFileLoaded = false;
|
||
var _resourceCulture = 'en-US';
|
||
function _loadResJson(resjsonFile) {
|
||
var resJson;
|
||
if (_exist(resjsonFile)) {
|
||
var resjsonContent = fs.readFileSync(resjsonFile, 'utf8').toString();
|
||
// remove BOM
|
||
if (resjsonContent.indexOf('\uFEFF') == 0) {
|
||
resjsonContent = resjsonContent.slice(1);
|
||
}
|
||
try {
|
||
resJson = JSON.parse(resjsonContent);
|
||
}
|
||
catch (err) {
|
||
_debug('unable to parse resjson with err: ' + err.message);
|
||
}
|
||
}
|
||
else {
|
||
_debug('.resjson file not found: ' + resjsonFile);
|
||
}
|
||
return resJson;
|
||
}
|
||
function _loadLocStrings(resourceFile, culture) {
|
||
var locStrings = {};
|
||
if (_exist(resourceFile)) {
|
||
var resourceJson = _loadResJson(resourceFile);
|
||
if (resourceJson && resourceJson.hasOwnProperty('messages')) {
|
||
var locResourceJson;
|
||
// load up resource resjson for different culture
|
||
var localizedResourceFile = path.join(path.dirname(resourceFile), 'Strings', 'resources.resjson');
|
||
var upperCulture = culture.toUpperCase();
|
||
var cultures = [];
|
||
try {
|
||
cultures = fs.readdirSync(localizedResourceFile);
|
||
}
|
||
catch (ex) { }
|
||
for (var i = 0; i < cultures.length; i++) {
|
||
if (cultures[i].toUpperCase() == upperCulture) {
|
||
localizedResourceFile = path.join(localizedResourceFile, cultures[i], 'resources.resjson');
|
||
if (_exist(localizedResourceFile)) {
|
||
locResourceJson = _loadResJson(localizedResourceFile);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
for (var key in resourceJson.messages) {
|
||
if (locResourceJson && locResourceJson.hasOwnProperty('loc.messages.' + key)) {
|
||
locStrings[key] = locResourceJson['loc.messages.' + key];
|
||
}
|
||
else {
|
||
locStrings[key] = resourceJson.messages[key];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
_warning('LIB_ResourceFile does not exist');
|
||
}
|
||
return locStrings;
|
||
}
|
||
/**
|
||
* Sets the location of the resources json. This is typically the task.json file.
|
||
* Call once at the beginning of the script before any calls to loc.
|
||
* @param path Full path to the json.
|
||
* @param ignoreWarnings Won't throw warnings if path already set.
|
||
* @returns void
|
||
*/
|
||
function _setResourcePath(path, ignoreWarnings) {
|
||
if (ignoreWarnings === void 0) { ignoreWarnings = false; }
|
||
if (process.env['TASKLIB_INPROC_UNITS']) {
|
||
_resourceFiles = {};
|
||
_libResourceFileLoaded = false;
|
||
_locStringCache = {};
|
||
_resourceCulture = 'en-US';
|
||
}
|
||
if (!_resourceFiles[path]) {
|
||
_checkPath(path, 'resource file path');
|
||
_resourceFiles[path] = path;
|
||
_debug('adding resource file: ' + path);
|
||
_resourceCulture = _getVariable('system.culture') || _resourceCulture;
|
||
var locStrs = _loadLocStrings(path, _resourceCulture);
|
||
for (var key in locStrs) {
|
||
//cache loc string
|
||
_locStringCache[key] = locStrs[key];
|
||
}
|
||
}
|
||
else {
|
||
if (ignoreWarnings) {
|
||
_debug(_loc('LIB_ResourceFileAlreadySet', path));
|
||
}
|
||
else {
|
||
_warning(_loc('LIB_ResourceFileAlreadySet', path));
|
||
}
|
||
}
|
||
}
|
||
exports._setResourcePath = _setResourcePath;
|
||
/**
|
||
* Gets the localized string from the json resource file. Optionally formats with additional params.
|
||
*
|
||
* @param key key of the resources string in the resource file
|
||
* @param param additional params for formatting the string
|
||
* @returns string
|
||
*/
|
||
function _loc(key) {
|
||
var param = [];
|
||
for (var _i = 1; _i < arguments.length; _i++) {
|
||
param[_i - 1] = arguments[_i];
|
||
}
|
||
if (!_libResourceFileLoaded) {
|
||
// merge loc strings from azure-pipelines-task-lib.
|
||
var libResourceFile = path.join(__dirname, 'lib.json');
|
||
var libLocStrs = _loadLocStrings(libResourceFile, _resourceCulture);
|
||
for (var libKey in libLocStrs) {
|
||
//cache azure-pipelines-task-lib loc string
|
||
_locStringCache[libKey] = libLocStrs[libKey];
|
||
}
|
||
_libResourceFileLoaded = true;
|
||
}
|
||
var locString;
|
||
;
|
||
if (_locStringCache.hasOwnProperty(key)) {
|
||
locString = _locStringCache[key];
|
||
}
|
||
else {
|
||
if (Object.keys(_resourceFiles).length <= 0) {
|
||
_warning(_loc('LIB_ResourceFileNotSet', key));
|
||
}
|
||
else {
|
||
_warning(_loc('LIB_LocStringNotFound', key));
|
||
}
|
||
locString = key;
|
||
}
|
||
if (param.length > 0) {
|
||
return util.format.apply(this, [locString].concat(param));
|
||
}
|
||
else {
|
||
return locString;
|
||
}
|
||
}
|
||
exports._loc = _loc;
|
||
//-----------------------------------------------------
|
||
// Input Helpers
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Gets a variable value that is defined on the build/release definition or set at runtime.
|
||
*
|
||
* @param name name of the variable to get
|
||
* @returns string
|
||
*/
|
||
function _getVariable(name) {
|
||
var varval;
|
||
// get the metadata
|
||
var info;
|
||
var key = _getVariableKey(name);
|
||
if (exports._knownVariableMap.hasOwnProperty(key)) {
|
||
info = exports._knownVariableMap[key];
|
||
}
|
||
if (info && info.secret) {
|
||
// get the secret value
|
||
varval = exports._vault.retrieveSecret('SECRET_' + key);
|
||
}
|
||
else {
|
||
// get the public value
|
||
varval = process.env[key];
|
||
// fallback for pre 2.104.1 agent
|
||
if (!varval && name.toUpperCase() == 'AGENT.JOBSTATUS') {
|
||
varval = process.env['agent.jobstatus'];
|
||
}
|
||
}
|
||
_debug(name + '=' + varval);
|
||
return varval;
|
||
}
|
||
exports._getVariable = _getVariable;
|
||
function _getVariableKey(name) {
|
||
if (!name) {
|
||
throw new Error(_loc('LIB_ParameterIsRequired', 'name'));
|
||
}
|
||
return name.replace(/\./g, '_').replace(/ /g, '_').toUpperCase();
|
||
}
|
||
exports._getVariableKey = _getVariableKey;
|
||
//-----------------------------------------------------
|
||
// Cmd Helpers
|
||
//-----------------------------------------------------
|
||
function _command(command, properties, message) {
|
||
var taskCmd = new tcm.TaskCommand(command, properties, message);
|
||
_writeLine(taskCmd.toString());
|
||
}
|
||
exports._command = _command;
|
||
function _warning(message) {
|
||
_command('task.issue', { 'type': 'warning' }, message);
|
||
}
|
||
exports._warning = _warning;
|
||
function _error(message) {
|
||
_command('task.issue', { 'type': 'error' }, message);
|
||
}
|
||
exports._error = _error;
|
||
function _debug(message) {
|
||
_command('task.debug', null, message);
|
||
}
|
||
exports._debug = _debug;
|
||
// //-----------------------------------------------------
|
||
// // Disk Functions
|
||
// //-----------------------------------------------------
|
||
/**
|
||
* Returns whether a path exists.
|
||
*
|
||
* @param path path to check
|
||
* @returns boolean
|
||
*/
|
||
function _exist(path) {
|
||
var exist = false;
|
||
try {
|
||
exist = !!(path && fs.statSync(path) != null);
|
||
}
|
||
catch (err) {
|
||
if (err && err.code === 'ENOENT') {
|
||
exist = false;
|
||
}
|
||
else {
|
||
throw err;
|
||
}
|
||
}
|
||
return exist;
|
||
}
|
||
exports._exist = _exist;
|
||
/**
|
||
* Checks whether a path exists.
|
||
* If the path does not exist, it will throw.
|
||
*
|
||
* @param p path to check
|
||
* @param name name only used in error message to identify the path
|
||
* @returns void
|
||
*/
|
||
function _checkPath(p, name) {
|
||
_debug('check path : ' + p);
|
||
if (!_exist(p)) {
|
||
throw new Error(_loc('LIB_PathNotFound', name, p));
|
||
}
|
||
}
|
||
exports._checkPath = _checkPath;
|
||
/**
|
||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||
* If you check and the tool does not exist, it will throw.
|
||
*
|
||
* @param tool name of the tool
|
||
* @param check whether to check if tool exists
|
||
* @returns string
|
||
*/
|
||
function _which(tool, check) {
|
||
if (!tool) {
|
||
throw new Error('parameter \'tool\' is required');
|
||
}
|
||
// recursive when check=true
|
||
if (check) {
|
||
var result = _which(tool, false);
|
||
if (result) {
|
||
return result;
|
||
}
|
||
else {
|
||
if (process.platform == 'win32') {
|
||
throw new Error(_loc('LIB_WhichNotFound_Win', tool));
|
||
}
|
||
else {
|
||
throw new Error(_loc('LIB_WhichNotFound_Linux', tool));
|
||
}
|
||
}
|
||
}
|
||
_debug("which '" + tool + "'");
|
||
try {
|
||
// build the list of extensions to try
|
||
var extensions = [];
|
||
if (process.platform == 'win32' && process.env['PATHEXT']) {
|
||
for (var _i = 0, _a = process.env['PATHEXT'].split(path.delimiter); _i < _a.length; _i++) {
|
||
var extension = _a[_i];
|
||
if (extension) {
|
||
extensions.push(extension);
|
||
}
|
||
}
|
||
}
|
||
// if it's rooted, return it if exists. otherwise return empty.
|
||
if (_isRooted(tool)) {
|
||
var filePath = _tryGetExecutablePath(tool, extensions);
|
||
if (filePath) {
|
||
_debug("found: '" + filePath + "'");
|
||
return filePath;
|
||
}
|
||
_debug('not found');
|
||
return '';
|
||
}
|
||
// if any path separators, return empty
|
||
if (tool.indexOf('/') >= 0 || (process.platform == 'win32' && tool.indexOf('\\') >= 0)) {
|
||
_debug('not found');
|
||
return '';
|
||
}
|
||
// build the list of directories
|
||
//
|
||
// Note, technically "where" checks the current directory on Windows. From a task lib perspective,
|
||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
||
// case of a shell, and the which() function exposed by the task lib should strive for consistency
|
||
// across platforms.
|
||
var directories = [];
|
||
if (process.env['PATH']) {
|
||
for (var _b = 0, _c = process.env['PATH'].split(path.delimiter); _b < _c.length; _b++) {
|
||
var p = _c[_b];
|
||
if (p) {
|
||
directories.push(p);
|
||
}
|
||
}
|
||
}
|
||
// return the first match
|
||
for (var _d = 0, directories_1 = directories; _d < directories_1.length; _d++) {
|
||
var directory = directories_1[_d];
|
||
var filePath = _tryGetExecutablePath(directory + path.sep + tool, extensions);
|
||
if (filePath) {
|
||
_debug("found: '" + filePath + "'");
|
||
return filePath;
|
||
}
|
||
}
|
||
_debug('not found');
|
||
return '';
|
||
}
|
||
catch (err) {
|
||
throw new Error(_loc('LIB_OperationFailed', 'which', err.message));
|
||
}
|
||
}
|
||
exports._which = _which;
|
||
/**
|
||
* Best effort attempt to determine whether a file exists and is executable.
|
||
* @param filePath file path to check
|
||
* @param extensions additional file extensions to try
|
||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||
*/
|
||
function _tryGetExecutablePath(filePath, extensions) {
|
||
try {
|
||
// test file exists
|
||
var stats = fs.statSync(filePath);
|
||
if (stats.isFile()) {
|
||
if (process.platform == 'win32') {
|
||
// on Windows, test for valid extension
|
||
var isExecutable = false;
|
||
var fileName = path.basename(filePath);
|
||
var dotIndex = fileName.lastIndexOf('.');
|
||
if (dotIndex >= 0) {
|
||
var upperExt_1 = fileName.substr(dotIndex).toUpperCase();
|
||
if (extensions.some(function (validExt) { return validExt.toUpperCase() == upperExt_1; })) {
|
||
return filePath;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if (isUnixExecutable(stats)) {
|
||
return filePath;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (err) {
|
||
if (err.code != 'ENOENT') {
|
||
_debug("Unexpected error attempting to determine if executable file exists '" + filePath + "': " + err);
|
||
}
|
||
}
|
||
// try each extension
|
||
var originalFilePath = filePath;
|
||
for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
|
||
var extension = extensions_1[_i];
|
||
var found = false;
|
||
var filePath_1 = originalFilePath + extension;
|
||
try {
|
||
var stats = fs.statSync(filePath_1);
|
||
if (stats.isFile()) {
|
||
if (process.platform == 'win32') {
|
||
// preserve the case of the actual file (since an extension was appended)
|
||
try {
|
||
var directory = path.dirname(filePath_1);
|
||
var upperName = path.basename(filePath_1).toUpperCase();
|
||
for (var _a = 0, _b = fs.readdirSync(directory); _a < _b.length; _a++) {
|
||
var actualName = _b[_a];
|
||
if (upperName == actualName.toUpperCase()) {
|
||
filePath_1 = path.join(directory, actualName);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
catch (err) {
|
||
_debug("Unexpected error attempting to determine the actual case of the file '" + filePath_1 + "': " + err);
|
||
}
|
||
return filePath_1;
|
||
}
|
||
else {
|
||
if (isUnixExecutable(stats)) {
|
||
return filePath_1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (err) {
|
||
if (err.code != 'ENOENT') {
|
||
_debug("Unexpected error attempting to determine if executable file exists '" + filePath_1 + "': " + err);
|
||
}
|
||
}
|
||
}
|
||
return '';
|
||
}
|
||
// on Mac/Linux, test the execute bit
|
||
// R W X R W X R W X
|
||
// 256 128 64 32 16 8 4 2 1
|
||
function isUnixExecutable(stats) {
|
||
return (stats.mode & 1) > 0 || ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || ((stats.mode & 64) > 0 && stats.uid === process.getuid());
|
||
}
|
||
function _legacyFindFiles_convertPatternToRegExp(pattern) {
|
||
pattern = (process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern) // normalize separator on Windows
|
||
.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') // regex escape - from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
|
||
.replace(/\\\/\\\*\\\*\\\//g, '((\/.+/)|(\/))') // replace directory globstar, e.g. /hello/**/world
|
||
.replace(/\\\*\\\*/g, '.*') // replace remaining globstars with a wildcard that can span directory separators, e.g. /hello/**dll
|
||
.replace(/\\\*/g, '[^\/]*') // replace asterisks with a wildcard that cannot span directory separators, e.g. /hello/*.dll
|
||
.replace(/\\\?/g, '[^\/]'); // replace single character wildcards, e.g. /hello/log?.dll
|
||
pattern = "^" + pattern + "$";
|
||
var flags = process.platform == 'win32' ? 'i' : '';
|
||
return new RegExp(pattern, flags);
|
||
}
|
||
exports._legacyFindFiles_convertPatternToRegExp = _legacyFindFiles_convertPatternToRegExp;
|
||
function _cloneMatchOptions(matchOptions) {
|
||
return {
|
||
debug: matchOptions.debug,
|
||
nobrace: matchOptions.nobrace,
|
||
noglobstar: matchOptions.noglobstar,
|
||
dot: matchOptions.dot,
|
||
noext: matchOptions.noext,
|
||
nocase: matchOptions.nocase,
|
||
nonull: matchOptions.nonull,
|
||
matchBase: matchOptions.matchBase,
|
||
nocomment: matchOptions.nocomment,
|
||
nonegate: matchOptions.nonegate,
|
||
flipNegate: matchOptions.flipNegate
|
||
};
|
||
}
|
||
exports._cloneMatchOptions = _cloneMatchOptions;
|
||
function _getFindInfoFromPattern(defaultRoot, pattern, matchOptions) {
|
||
// parameter validation
|
||
if (!defaultRoot) {
|
||
throw new Error('getFindRootFromPattern() parameter defaultRoot cannot be empty');
|
||
}
|
||
if (!pattern) {
|
||
throw new Error('getFindRootFromPattern() parameter pattern cannot be empty');
|
||
}
|
||
if (!matchOptions.nobrace) {
|
||
throw new Error('getFindRootFromPattern() expected matchOptions.nobrace to be true');
|
||
}
|
||
// for the sake of determining the findPath, pretend nocase=false
|
||
matchOptions = _cloneMatchOptions(matchOptions);
|
||
matchOptions.nocase = false;
|
||
// check if basename only and matchBase=true
|
||
if (matchOptions.matchBase &&
|
||
!_isRooted(pattern) &&
|
||
(process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern).indexOf('/') < 0) {
|
||
return {
|
||
adjustedPattern: pattern,
|
||
findPath: defaultRoot,
|
||
statOnly: false,
|
||
};
|
||
}
|
||
// the technique applied by this function is to use the information on the Minimatch object determine
|
||
// the findPath. Minimatch breaks the pattern into path segments, and exposes information about which
|
||
// segments are literal vs patterns.
|
||
//
|
||
// note, the technique currently imposes a limitation for drive-relative paths with a glob in the
|
||
// first segment, e.g. C:hello*/world. it's feasible to overcome this limitation, but is left unsolved
|
||
// for now.
|
||
var minimatchObj = new minimatch.Minimatch(pattern, matchOptions);
|
||
// the "set" property is an array of arrays of parsed path segment info. the outer array should only
|
||
// contain one item, otherwise something went wrong. brace expansion can result in multiple arrays,
|
||
// but that should be turned off by the time this function is reached.
|
||
if (minimatchObj.set.length != 1) {
|
||
throw new Error('getFindRootFromPattern() expected Minimatch(...).set.length to be 1. Actual: ' + minimatchObj.set.length);
|
||
}
|
||
var literalSegments = [];
|
||
for (var _i = 0, _a = minimatchObj.set[0]; _i < _a.length; _i++) {
|
||
var parsedSegment = _a[_i];
|
||
if (typeof parsedSegment == 'string') {
|
||
// the item is a string when the original input for the path segment does not contain any
|
||
// unescaped glob characters.
|
||
//
|
||
// note, the string here is already unescaped (i.e. glob escaping removed), so it is ready
|
||
// to pass to find() as-is. for example, an input string 'hello\\*world' => 'hello*world'.
|
||
literalSegments.push(parsedSegment);
|
||
continue;
|
||
}
|
||
break;
|
||
}
|
||
// join the literal segments back together. Minimatch converts '\' to '/' on Windows, then squashes
|
||
// consequetive slashes, and finally splits on slash. this means that UNC format is lost, but can
|
||
// be detected from the original pattern.
|
||
var joinedSegments = literalSegments.join('/');
|
||
if (joinedSegments && process.platform == 'win32' && _startsWith(pattern.replace(/\\/g, '/'), '//')) {
|
||
joinedSegments = '/' + joinedSegments; // restore UNC format
|
||
}
|
||
// determine the find path
|
||
var findPath;
|
||
if (_isRooted(pattern)) { // the pattern was rooted
|
||
findPath = joinedSegments;
|
||
}
|
||
else if (joinedSegments) { // the pattern was not rooted, and literal segments were found
|
||
findPath = _ensureRooted(defaultRoot, joinedSegments);
|
||
}
|
||
else { // the pattern was not rooted, and no literal segments were found
|
||
findPath = defaultRoot;
|
||
}
|
||
// clean up the path
|
||
if (findPath) {
|
||
findPath = _getDirectoryName(_ensureRooted(findPath, '_')); // hack to remove unnecessary trailing slash
|
||
findPath = _normalizeSeparators(findPath); // normalize slashes
|
||
}
|
||
return {
|
||
adjustedPattern: _ensurePatternRooted(defaultRoot, pattern),
|
||
findPath: findPath,
|
||
statOnly: literalSegments.length == minimatchObj.set[0].length,
|
||
};
|
||
}
|
||
exports._getFindInfoFromPattern = _getFindInfoFromPattern;
|
||
function _ensurePatternRooted(root, p) {
|
||
if (!root) {
|
||
throw new Error('ensurePatternRooted() parameter "root" cannot be empty');
|
||
}
|
||
if (!p) {
|
||
throw new Error('ensurePatternRooted() parameter "p" cannot be empty');
|
||
}
|
||
if (_isRooted(p)) {
|
||
return p;
|
||
}
|
||
// normalize root
|
||
root = _normalizeSeparators(root);
|
||
// escape special glob characters
|
||
root = (process.platform == 'win32' ? root : root.replace(/\\/g, '\\\\')) // escape '\' on OSX/Linux
|
||
.replace(/(\[)(?=[^\/]+\])/g, '[[]') // escape '[' when ']' follows within the path segment
|
||
.replace(/\?/g, '[?]') // escape '?'
|
||
.replace(/\*/g, '[*]') // escape '*'
|
||
.replace(/\+\(/g, '[+](') // escape '+('
|
||
.replace(/@\(/g, '[@](') // escape '@('
|
||
.replace(/!\(/g, '[!]('); // escape '!('
|
||
return _ensureRooted(root, p);
|
||
}
|
||
exports._ensurePatternRooted = _ensurePatternRooted;
|
||
//-------------------------------------------------------------------
|
||
// Populate the vault with sensitive data. Inputs and Endpoints
|
||
//-------------------------------------------------------------------
|
||
function _loadData() {
|
||
// in agent, prefer TempDirectory then workFolder.
|
||
// In interactive dev mode, it won't be
|
||
var keyPath = _getVariable("agent.TempDirectory") || _getVariable("agent.workFolder") || process.cwd();
|
||
exports._vault = new vm.Vault(keyPath);
|
||
exports._knownVariableMap = {};
|
||
_debug('loading inputs and endpoints');
|
||
var loaded = 0;
|
||
for (var envvar in process.env) {
|
||
if (_startsWith(envvar, 'INPUT_') ||
|
||
_startsWith(envvar, 'ENDPOINT_AUTH_') ||
|
||
_startsWith(envvar, 'SECUREFILE_TICKET_') ||
|
||
_startsWith(envvar, 'SECRET_') ||
|
||
_startsWith(envvar, 'VSTS_TASKVARIABLE_')) {
|
||
// Record the secret variable metadata. This is required by getVariable to know whether
|
||
// to retrieve the value from the vault. In a 2.104.1 agent or higher, this metadata will
|
||
// be overwritten when the VSTS_SECRET_VARIABLES env var is processed below.
|
||
if (_startsWith(envvar, 'SECRET_')) {
|
||
var variableName = envvar.substring('SECRET_'.length);
|
||
if (variableName) {
|
||
// This is technically not the variable name (has underscores instead of dots),
|
||
// but it's good enough to make getVariable work in a pre-2.104.1 agent where
|
||
// the VSTS_SECRET_VARIABLES env var is not defined.
|
||
exports._knownVariableMap[_getVariableKey(variableName)] = { name: variableName, secret: true };
|
||
}
|
||
}
|
||
// store the secret
|
||
var value = process.env[envvar];
|
||
if (value) {
|
||
++loaded;
|
||
_debug('loading ' + envvar);
|
||
exports._vault.storeSecret(envvar, value);
|
||
delete process.env[envvar];
|
||
}
|
||
}
|
||
}
|
||
_debug('loaded ' + loaded);
|
||
// store public variable metadata
|
||
var names;
|
||
try {
|
||
names = JSON.parse(process.env['VSTS_PUBLIC_VARIABLES'] || '[]');
|
||
}
|
||
catch (err) {
|
||
throw new Error('Failed to parse VSTS_PUBLIC_VARIABLES as JSON. ' + err); // may occur during interactive testing
|
||
}
|
||
names.forEach(function (name) {
|
||
exports._knownVariableMap[_getVariableKey(name)] = { name: name, secret: false };
|
||
});
|
||
delete process.env['VSTS_PUBLIC_VARIABLES'];
|
||
// store secret variable metadata
|
||
try {
|
||
names = JSON.parse(process.env['VSTS_SECRET_VARIABLES'] || '[]');
|
||
}
|
||
catch (err) {
|
||
throw new Error('Failed to parse VSTS_SECRET_VARIABLES as JSON. ' + err); // may occur during interactive testing
|
||
}
|
||
names.forEach(function (name) {
|
||
exports._knownVariableMap[_getVariableKey(name)] = { name: name, secret: true };
|
||
});
|
||
delete process.env['VSTS_SECRET_VARIABLES'];
|
||
// avoid loading twice (overwrites .taskkey)
|
||
global['_vsts_task_lib_loaded'] = true;
|
||
}
|
||
exports._loadData = _loadData;
|
||
//--------------------------------------------------------------------------------
|
||
// Internal path helpers.
|
||
//--------------------------------------------------------------------------------
|
||
function _ensureRooted(root, p) {
|
||
if (!root) {
|
||
throw new Error('ensureRooted() parameter "root" cannot be empty');
|
||
}
|
||
if (!p) {
|
||
throw new Error('ensureRooted() parameter "p" cannot be empty');
|
||
}
|
||
if (_isRooted(p)) {
|
||
return p;
|
||
}
|
||
if (process.platform == 'win32' && root.match(/^[A-Z]:$/i)) { // e.g. C:
|
||
return root + p;
|
||
}
|
||
// ensure root ends with a separator
|
||
if (_endsWith(root, '/') || (process.platform == 'win32' && _endsWith(root, '\\'))) {
|
||
// root already ends with a separator
|
||
}
|
||
else {
|
||
root += path.sep; // append separator
|
||
}
|
||
return root + p;
|
||
}
|
||
exports._ensureRooted = _ensureRooted;
|
||
/**
|
||
* Determines the parent path and trims trailing slashes (when safe). Path separators are normalized
|
||
* in the result. This function works similar to the .NET System.IO.Path.GetDirectoryName() method.
|
||
* For example, C:\hello\world\ returns C:\hello\world (trailing slash removed). Returns empty when
|
||
* no higher directory can be determined.
|
||
*/
|
||
function _getDirectoryName(p) {
|
||
// short-circuit if empty
|
||
if (!p) {
|
||
return '';
|
||
}
|
||
// normalize separators
|
||
p = _normalizeSeparators(p);
|
||
// on Windows, the goal of this function is to match the behavior of
|
||
// [System.IO.Path]::GetDirectoryName(), e.g.
|
||
// C:/ =>
|
||
// C:/hello => C:\
|
||
// C:/hello/ => C:\hello
|
||
// C:/hello/world => C:\hello
|
||
// C:/hello/world/ => C:\hello\world
|
||
// C: =>
|
||
// C:hello => C:
|
||
// C:hello/ => C:hello
|
||
// / =>
|
||
// /hello => \
|
||
// /hello/ => \hello
|
||
// //hello =>
|
||
// //hello/ =>
|
||
// //hello/world =>
|
||
// //hello/world/ => \\hello\world
|
||
//
|
||
// unfortunately, path.dirname() can't simply be used. for example, on Windows
|
||
// it yields different results from Path.GetDirectoryName:
|
||
// C:/ => C:/
|
||
// C:/hello => C:/
|
||
// C:/hello/ => C:/
|
||
// C:/hello/world => C:/hello
|
||
// C:/hello/world/ => C:/hello
|
||
// C: => C:
|
||
// C:hello => C:
|
||
// C:hello/ => C:
|
||
// / => /
|
||
// /hello => /
|
||
// /hello/ => /
|
||
// //hello => /
|
||
// //hello/ => /
|
||
// //hello/world => //hello/world
|
||
// //hello/world/ => //hello/world/
|
||
// //hello/world/again => //hello/world/
|
||
// //hello/world/again/ => //hello/world/
|
||
// //hello/world/again/again => //hello/world/again
|
||
// //hello/world/again/again/ => //hello/world/again
|
||
if (process.platform == 'win32') {
|
||
if (/^[A-Z]:\\?[^\\]+$/i.test(p)) { // e.g. C:\hello or C:hello
|
||
return p.charAt(2) == '\\' ? p.substring(0, 3) : p.substring(0, 2);
|
||
}
|
||
else if (/^[A-Z]:\\?$/i.test(p)) { // e.g. C:\ or C:
|
||
return '';
|
||
}
|
||
var lastSlashIndex = p.lastIndexOf('\\');
|
||
if (lastSlashIndex < 0) { // file name only
|
||
return '';
|
||
}
|
||
else if (p == '\\') { // relative root
|
||
return '';
|
||
}
|
||
else if (lastSlashIndex == 0) { // e.g. \\hello
|
||
return '\\';
|
||
}
|
||
else if (/^\\\\[^\\]+(\\[^\\]*)?$/.test(p)) { // UNC root, e.g. \\hello or \\hello\ or \\hello\world
|
||
return '';
|
||
}
|
||
return p.substring(0, lastSlashIndex); // e.g. hello\world => hello or hello\world\ => hello\world
|
||
// note, this means trailing slashes for non-root directories
|
||
// (i.e. not C:\, \, or \\unc\) will simply be removed.
|
||
}
|
||
// OSX/Linux
|
||
if (p.indexOf('/') < 0) { // file name only
|
||
return '';
|
||
}
|
||
else if (p == '/') {
|
||
return '';
|
||
}
|
||
else if (_endsWith(p, '/')) {
|
||
return p.substring(0, p.length - 1);
|
||
}
|
||
return path.dirname(p);
|
||
}
|
||
exports._getDirectoryName = _getDirectoryName;
|
||
/**
|
||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||
*/
|
||
function _isRooted(p) {
|
||
p = _normalizeSeparators(p);
|
||
if (!p) {
|
||
throw new Error('isRooted() parameter "p" cannot be empty');
|
||
}
|
||
if (process.platform == 'win32') {
|
||
return _startsWith(p, '\\') || // e.g. \ or \hello or \\hello
|
||
/^[A-Z]:/i.test(p); // e.g. C: or C:\hello
|
||
}
|
||
return _startsWith(p, '/'); // e.g. /hello
|
||
}
|
||
exports._isRooted = _isRooted;
|
||
function _normalizeSeparators(p) {
|
||
p = p || '';
|
||
if (process.platform == 'win32') {
|
||
// convert slashes on Windows
|
||
p = p.replace(/\//g, '\\');
|
||
// remove redundant slashes
|
||
var isUnc = /^\\\\+[^\\]/.test(p); // e.g. \\hello
|
||
return (isUnc ? '\\' : '') + p.replace(/\\\\+/g, '\\'); // preserve leading // for UNC
|
||
}
|
||
// remove redundant slashes
|
||
return p.replace(/\/\/+/g, '/');
|
||
}
|
||
exports._normalizeSeparators = _normalizeSeparators;
|
||
//-----------------------------------------------------
|
||
// Expose proxy information to vsts-node-api
|
||
//-----------------------------------------------------
|
||
function _exposeProxySettings() {
|
||
var proxyUrl = _getVariable('Agent.ProxyUrl');
|
||
if (proxyUrl && proxyUrl.length > 0) {
|
||
var proxyUsername = _getVariable('Agent.ProxyUsername');
|
||
var proxyPassword = _getVariable('Agent.ProxyPassword');
|
||
var proxyBypassHostsJson = _getVariable('Agent.ProxyBypassList');
|
||
global['_vsts_task_lib_proxy_url'] = proxyUrl;
|
||
global['_vsts_task_lib_proxy_username'] = proxyUsername;
|
||
global['_vsts_task_lib_proxy_bypass'] = proxyBypassHostsJson;
|
||
global['_vsts_task_lib_proxy_password'] = _exposeTaskLibSecret('proxy', proxyPassword || '');
|
||
_debug('expose agent proxy configuration.');
|
||
global['_vsts_task_lib_proxy'] = true;
|
||
}
|
||
}
|
||
exports._exposeProxySettings = _exposeProxySettings;
|
||
//-----------------------------------------------------
|
||
// Expose certificate information to vsts-node-api
|
||
//-----------------------------------------------------
|
||
function _exposeCertSettings() {
|
||
var ca = _getVariable('Agent.CAInfo');
|
||
if (ca) {
|
||
global['_vsts_task_lib_cert_ca'] = ca;
|
||
}
|
||
var clientCert = _getVariable('Agent.ClientCert');
|
||
if (clientCert) {
|
||
var clientCertKey = _getVariable('Agent.ClientCertKey');
|
||
var clientCertArchive = _getVariable('Agent.ClientCertArchive');
|
||
var clientCertPassword = _getVariable('Agent.ClientCertPassword');
|
||
global['_vsts_task_lib_cert_clientcert'] = clientCert;
|
||
global['_vsts_task_lib_cert_key'] = clientCertKey;
|
||
global['_vsts_task_lib_cert_archive'] = clientCertArchive;
|
||
global['_vsts_task_lib_cert_passphrase'] = _exposeTaskLibSecret('cert', clientCertPassword || '');
|
||
}
|
||
if (ca || clientCert) {
|
||
_debug('expose agent certificate configuration.');
|
||
global['_vsts_task_lib_cert'] = true;
|
||
}
|
||
var skipCertValidation = _getVariable('Agent.SkipCertValidation') || 'false';
|
||
if (skipCertValidation) {
|
||
global['_vsts_task_lib_skip_cert_validation'] = skipCertValidation.toUpperCase() === 'TRUE';
|
||
}
|
||
}
|
||
exports._exposeCertSettings = _exposeCertSettings;
|
||
// We store the encryption key on disk and hold the encrypted content and key file in memory
|
||
// return base64encoded<keyFilePath>:base64encoded<encryptedContent>
|
||
// downstream vsts-node-api will retrieve the secret later
|
||
function _exposeTaskLibSecret(keyFile, secret) {
|
||
if (secret) {
|
||
var encryptKey = crypto.randomBytes(256);
|
||
var cipher = crypto.createCipher("aes-256-ctr", encryptKey);
|
||
var encryptedContent = cipher.update(secret, "utf8", "hex");
|
||
encryptedContent += cipher.final("hex");
|
||
var storageFile = path.join(_getVariable('Agent.TempDirectory') || _getVariable("agent.workFolder") || process.cwd(), keyFile);
|
||
fs.writeFileSync(storageFile, encryptKey.toString('base64'), { encoding: 'utf8' });
|
||
return new Buffer(storageFile).toString('base64') + ':' + new Buffer(encryptedContent).toString('base64');
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/bytesToUuid.js":
|
||
/*!************************************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/bytesToUuid.js ***!
|
||
\************************************************************************************/
|
||
/***/ ((module) => {
|
||
|
||
/**
|
||
* Convert array of 16 byte values to UUID string format of the form:
|
||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||
*/
|
||
var byteToHex = [];
|
||
for (var i = 0; i < 256; ++i) {
|
||
byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
||
}
|
||
|
||
function bytesToUuid(buf, offset) {
|
||
var i = offset || 0;
|
||
var bth = byteToHex;
|
||
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
|
||
return ([
|
||
bth[buf[i++]], bth[buf[i++]],
|
||
bth[buf[i++]], bth[buf[i++]], '-',
|
||
bth[buf[i++]], bth[buf[i++]], '-',
|
||
bth[buf[i++]], bth[buf[i++]], '-',
|
||
bth[buf[i++]], bth[buf[i++]], '-',
|
||
bth[buf[i++]], bth[buf[i++]],
|
||
bth[buf[i++]], bth[buf[i++]],
|
||
bth[buf[i++]], bth[buf[i++]]
|
||
]).join('');
|
||
}
|
||
|
||
module.exports = bytesToUuid;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/rng.js":
|
||
/*!****************************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/rng.js ***!
|
||
\****************************************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
// Unique ID creation requires a high quality random # generator. In node.js
|
||
// this is pretty straight-forward - we use the crypto API.
|
||
|
||
var crypto = __webpack_require__(/*! crypto */ "crypto");
|
||
|
||
module.exports = function nodeRNG() {
|
||
return crypto.randomBytes(16);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/node_modules/uuid/v4.js":
|
||
/*!***********************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/node_modules/uuid/v4.js ***!
|
||
\***********************************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var rng = __webpack_require__(/*! ./lib/rng */ "./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/rng.js");
|
||
var bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ "./node_modules/azure-pipelines-task-lib/node_modules/uuid/lib/bytesToUuid.js");
|
||
|
||
function v4(options, buf, offset) {
|
||
var i = buf && offset || 0;
|
||
|
||
if (typeof(options) == 'string') {
|
||
buf = options === 'binary' ? new Array(16) : null;
|
||
options = null;
|
||
}
|
||
options = options || {};
|
||
|
||
var rnds = options.random || (options.rng || rng)();
|
||
|
||
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
||
rnds[6] = (rnds[6] & 0x0f) | 0x40;
|
||
rnds[8] = (rnds[8] & 0x3f) | 0x80;
|
||
|
||
// Copy bytes to buffer, if provided
|
||
if (buf) {
|
||
for (var ii = 0; ii < 16; ++ii) {
|
||
buf[i + ii] = rnds[ii];
|
||
}
|
||
}
|
||
|
||
return buf || bytesToUuid(rnds);
|
||
}
|
||
|
||
module.exports = v4;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/task.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/task.js ***!
|
||
\*******************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.updateReleaseName = exports.addBuildTag = exports.updateBuildNumber = exports.uploadBuildLog = exports.associateArtifact = exports.uploadArtifact = exports.logIssue = exports.logDetail = exports.setProgress = exports.setEndpoint = exports.addAttachment = exports.uploadSummary = exports.prependPath = exports.uploadFile = exports.CodeCoverageEnabler = exports.CodeCoveragePublisher = exports.TestPublisher = exports.getHttpCertConfiguration = exports.getHttpProxyConfiguration = exports.findMatch = exports.filter = exports.match = exports.tool = exports.execSync = exports.exec = exports.rmRF = exports.legacyFindFiles = exports.find = exports.mv = exports.cp = exports.ls = exports.which = exports.resolve = exports.mkdirP = exports.popd = exports.pushd = exports.cd = exports.checkPath = exports.cwd = exports.getPlatform = exports.osType = exports.writeFile = exports.exist = exports.stats = exports.debug = exports.error = exports.warning = exports.command = exports.setTaskVariable = exports.getTaskVariable = exports.getSecureFileTicket = exports.getSecureFileName = exports.getEndpointAuthorization = exports.getEndpointAuthorizationParameter = exports.getEndpointAuthorizationScheme = exports.getEndpointDataParameter = exports.getEndpointUrl = exports.getPathInput = exports.filePathSupplied = exports.getDelimitedInput = exports.getBoolInput = exports.getInput = exports.setSecret = exports.setVariable = exports.getVariables = exports.assertAgent = exports.getVariable = exports.loc = exports.setResourcePath = exports.setResult = exports.setErrStream = exports.setStdStream = exports.Platform = exports.FieldType = exports.ArtifactType = exports.IssueType = exports.TaskState = exports.TaskResult = void 0;
|
||
var shell = __webpack_require__(/*! shelljs */ "./node_modules/shelljs/shell.js");
|
||
var childProcess = __webpack_require__(/*! child_process */ "child_process");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js");
|
||
var im = __webpack_require__(/*! ./internal */ "./node_modules/azure-pipelines-task-lib/internal.js");
|
||
var tcm = __webpack_require__(/*! ./taskcommand */ "./node_modules/azure-pipelines-task-lib/taskcommand.js");
|
||
var trm = __webpack_require__(/*! ./toolrunner */ "./node_modules/azure-pipelines-task-lib/toolrunner.js");
|
||
var semver = __webpack_require__(/*! semver */ "./node_modules/semver/semver.js");
|
||
var TaskResult;
|
||
(function (TaskResult) {
|
||
TaskResult[TaskResult["Succeeded"] = 0] = "Succeeded";
|
||
TaskResult[TaskResult["SucceededWithIssues"] = 1] = "SucceededWithIssues";
|
||
TaskResult[TaskResult["Failed"] = 2] = "Failed";
|
||
TaskResult[TaskResult["Cancelled"] = 3] = "Cancelled";
|
||
TaskResult[TaskResult["Skipped"] = 4] = "Skipped";
|
||
})(TaskResult = exports.TaskResult || (exports.TaskResult = {}));
|
||
var TaskState;
|
||
(function (TaskState) {
|
||
TaskState[TaskState["Unknown"] = 0] = "Unknown";
|
||
TaskState[TaskState["Initialized"] = 1] = "Initialized";
|
||
TaskState[TaskState["InProgress"] = 2] = "InProgress";
|
||
TaskState[TaskState["Completed"] = 3] = "Completed";
|
||
})(TaskState = exports.TaskState || (exports.TaskState = {}));
|
||
var IssueType;
|
||
(function (IssueType) {
|
||
IssueType[IssueType["Error"] = 0] = "Error";
|
||
IssueType[IssueType["Warning"] = 1] = "Warning";
|
||
})(IssueType = exports.IssueType || (exports.IssueType = {}));
|
||
var ArtifactType;
|
||
(function (ArtifactType) {
|
||
ArtifactType[ArtifactType["Container"] = 0] = "Container";
|
||
ArtifactType[ArtifactType["FilePath"] = 1] = "FilePath";
|
||
ArtifactType[ArtifactType["VersionControl"] = 2] = "VersionControl";
|
||
ArtifactType[ArtifactType["GitRef"] = 3] = "GitRef";
|
||
ArtifactType[ArtifactType["TfvcLabel"] = 4] = "TfvcLabel";
|
||
})(ArtifactType = exports.ArtifactType || (exports.ArtifactType = {}));
|
||
var FieldType;
|
||
(function (FieldType) {
|
||
FieldType[FieldType["AuthParameter"] = 0] = "AuthParameter";
|
||
FieldType[FieldType["DataParameter"] = 1] = "DataParameter";
|
||
FieldType[FieldType["Url"] = 2] = "Url";
|
||
})(FieldType = exports.FieldType || (exports.FieldType = {}));
|
||
/** Platforms supported by our build agent */
|
||
var Platform;
|
||
(function (Platform) {
|
||
Platform[Platform["Windows"] = 0] = "Windows";
|
||
Platform[Platform["MacOS"] = 1] = "MacOS";
|
||
Platform[Platform["Linux"] = 2] = "Linux";
|
||
})(Platform = exports.Platform || (exports.Platform = {}));
|
||
//-----------------------------------------------------
|
||
// General Helpers
|
||
//-----------------------------------------------------
|
||
exports.setStdStream = im._setStdStream;
|
||
exports.setErrStream = im._setErrStream;
|
||
//-----------------------------------------------------
|
||
// Results
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Sets the result of the task.
|
||
* Execution will continue.
|
||
* If not set, task will be Succeeded.
|
||
* If multiple calls are made to setResult the most pessimistic call wins (Failed) regardless of the order of calls.
|
||
*
|
||
* @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
|
||
* @param message A message which will be logged as an error issue if the result is Failed.
|
||
* @param done Optional. Instructs the agent the task is done. This is helpful when child processes
|
||
* may still be running and prevent node from fully exiting. This argument is supported
|
||
* from agent version 2.142.0 or higher (otherwise will no-op).
|
||
* @returns void
|
||
*/
|
||
function setResult(result, message, done) {
|
||
exports.debug('task result: ' + TaskResult[result]);
|
||
// add an error issue
|
||
if (result == TaskResult.Failed && message) {
|
||
exports.error(message);
|
||
}
|
||
else if (result == TaskResult.SucceededWithIssues && message) {
|
||
exports.warning(message);
|
||
}
|
||
// task.complete
|
||
var properties = { 'result': TaskResult[result] };
|
||
if (done) {
|
||
properties['done'] = 'true';
|
||
}
|
||
exports.command('task.complete', properties, message);
|
||
}
|
||
exports.setResult = setResult;
|
||
//
|
||
// Catching all exceptions
|
||
//
|
||
process.on('uncaughtException', function (err) {
|
||
setResult(TaskResult.Failed, exports.loc('LIB_UnhandledEx', err.message));
|
||
});
|
||
//-----------------------------------------------------
|
||
// Loc Helpers
|
||
//-----------------------------------------------------
|
||
exports.setResourcePath = im._setResourcePath;
|
||
exports.loc = im._loc;
|
||
//-----------------------------------------------------
|
||
// Input Helpers
|
||
//-----------------------------------------------------
|
||
exports.getVariable = im._getVariable;
|
||
/**
|
||
* Asserts the agent version is at least the specified minimum.
|
||
*
|
||
* @param minimum minimum version version - must be 2.104.1 or higher
|
||
*/
|
||
function assertAgent(minimum) {
|
||
if (semver.lt(minimum, '2.104.1')) {
|
||
throw new Error('assertAgent() requires the parameter to be 2.104.1 or higher');
|
||
}
|
||
var agent = exports.getVariable('Agent.Version');
|
||
if (agent && semver.lt(agent, minimum)) {
|
||
throw new Error("Agent version " + minimum + " or higher is required");
|
||
}
|
||
}
|
||
exports.assertAgent = assertAgent;
|
||
/**
|
||
* Gets a snapshot of the current state of all job variables available to the task.
|
||
* Requires a 2.104.1 agent or higher for full functionality.
|
||
*
|
||
* Limitations on an agent prior to 2.104.1:
|
||
* 1) The return value does not include all public variables. Only public variables
|
||
* that have been added using setVariable are returned.
|
||
* 2) The name returned for each secret variable is the formatted environment variable
|
||
* name, not the actual variable name (unless it was set explicitly at runtime using
|
||
* setVariable).
|
||
*
|
||
* @returns VariableInfo[]
|
||
*/
|
||
function getVariables() {
|
||
return Object.keys(im._knownVariableMap)
|
||
.map(function (key) {
|
||
var info = im._knownVariableMap[key];
|
||
return { name: info.name, value: exports.getVariable(info.name), secret: info.secret };
|
||
});
|
||
}
|
||
exports.getVariables = getVariables;
|
||
/**
|
||
* Sets a variable which will be available to subsequent tasks as well.
|
||
*
|
||
* @param name name of the variable to set
|
||
* @param val value to set
|
||
* @param secret whether variable is secret. Multi-line secrets are not allowed. Optional, defaults to false
|
||
* @param isOutput whether variable is an output variable. Optional, defaults to false
|
||
* @returns void
|
||
*/
|
||
function setVariable(name, val, secret, isOutput) {
|
||
if (secret === void 0) { secret = false; }
|
||
if (isOutput === void 0) { isOutput = false; }
|
||
// once a secret always a secret
|
||
var key = im._getVariableKey(name);
|
||
if (im._knownVariableMap.hasOwnProperty(key)) {
|
||
secret = secret || im._knownVariableMap[key].secret;
|
||
}
|
||
// store the value
|
||
var varValue = val || '';
|
||
exports.debug('set ' + name + '=' + (secret && varValue ? '********' : varValue));
|
||
if (secret) {
|
||
if (varValue && varValue.match(/\r|\n/) && ("" + process.env['SYSTEM_UNSAFEALLOWMULTILINESECRET']).toUpperCase() != 'TRUE') {
|
||
throw new Error(exports.loc('LIB_MultilineSecret'));
|
||
}
|
||
im._vault.storeSecret('SECRET_' + key, varValue);
|
||
delete process.env[key];
|
||
}
|
||
else {
|
||
process.env[key] = varValue;
|
||
}
|
||
// store the metadata
|
||
im._knownVariableMap[key] = { name: name, secret: secret };
|
||
// write the setvariable command
|
||
exports.command('task.setvariable', { 'variable': name || '', isOutput: (isOutput || false).toString(), 'issecret': (secret || false).toString() }, varValue);
|
||
}
|
||
exports.setVariable = setVariable;
|
||
/**
|
||
* Registers a value with the logger, so the value will be masked from the logs. Multi-line secrets are not allowed.
|
||
*
|
||
* @param val value to register
|
||
*/
|
||
function setSecret(val) {
|
||
if (val) {
|
||
if (val.match(/\r|\n/) && ("" + process.env['SYSTEM_UNSAFEALLOWMULTILINESECRET']).toUpperCase() !== 'TRUE') {
|
||
throw new Error(exports.loc('LIB_MultilineSecret'));
|
||
}
|
||
exports.command('task.setsecret', {}, val);
|
||
}
|
||
}
|
||
exports.setSecret = setSecret;
|
||
/**
|
||
* Gets the value of an input.
|
||
* If required is true and the value is not set, it will throw.
|
||
*
|
||
* @param name name of the input to get
|
||
* @param required whether input is required. optional, defaults to false
|
||
* @returns string
|
||
*/
|
||
function getInput(name, required) {
|
||
var inval = im._vault.retrieveSecret('INPUT_' + im._getVariableKey(name));
|
||
if (required && !inval) {
|
||
throw new Error(exports.loc('LIB_InputRequired', name));
|
||
}
|
||
exports.debug(name + '=' + inval);
|
||
return inval;
|
||
}
|
||
exports.getInput = getInput;
|
||
/**
|
||
* Gets the value of an input and converts to a bool. Convenience.
|
||
* If required is true and the value is not set, it will throw.
|
||
* If required is false and the value is not set, returns false.
|
||
*
|
||
* @param name name of the bool input to get
|
||
* @param required whether input is required. optional, defaults to false
|
||
* @returns boolean
|
||
*/
|
||
function getBoolInput(name, required) {
|
||
return (getInput(name, required) || '').toUpperCase() == "TRUE";
|
||
}
|
||
exports.getBoolInput = getBoolInput;
|
||
/**
|
||
* Gets the value of an input and splits the value using a delimiter (space, comma, etc).
|
||
* Empty values are removed. This function is useful for splitting an input containing a simple
|
||
* list of items - such as build targets.
|
||
* IMPORTANT: Do not use this function for splitting additional args! Instead use argString(), which
|
||
* follows normal argument splitting rules and handles values encapsulated by quotes.
|
||
* If required is true and the value is not set, it will throw.
|
||
*
|
||
* @param name name of the input to get
|
||
* @param delim delimiter to split on
|
||
* @param required whether input is required. optional, defaults to false
|
||
* @returns string[]
|
||
*/
|
||
function getDelimitedInput(name, delim, required) {
|
||
var inputVal = getInput(name, required);
|
||
if (!inputVal) {
|
||
return [];
|
||
}
|
||
var result = [];
|
||
inputVal.split(delim).forEach(function (x) {
|
||
if (x) {
|
||
result.push(x);
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
exports.getDelimitedInput = getDelimitedInput;
|
||
/**
|
||
* Checks whether a path inputs value was supplied by the user
|
||
* File paths are relative with a picker, so an empty path is the root of the repo.
|
||
* Useful if you need to condition work (like append an arg) if a value was supplied
|
||
*
|
||
* @param name name of the path input to check
|
||
* @returns boolean
|
||
*/
|
||
function filePathSupplied(name) {
|
||
// normalize paths
|
||
var pathValue = this.resolve(this.getPathInput(name) || '');
|
||
var repoRoot = this.resolve(exports.getVariable('build.sourcesDirectory') || exports.getVariable('system.defaultWorkingDirectory') || '');
|
||
var supplied = pathValue !== repoRoot;
|
||
exports.debug(name + 'path supplied :' + supplied);
|
||
return supplied;
|
||
}
|
||
exports.filePathSupplied = filePathSupplied;
|
||
/**
|
||
* Gets the value of a path input
|
||
* It will be quoted for you if it isn't already and contains spaces
|
||
* If required is true and the value is not set, it will throw.
|
||
* If check is true and the path does not exist, it will throw.
|
||
*
|
||
* @param name name of the input to get
|
||
* @param required whether input is required. optional, defaults to false
|
||
* @param check whether path is checked. optional, defaults to false
|
||
* @returns string
|
||
*/
|
||
function getPathInput(name, required, check) {
|
||
var inval = getInput(name, required);
|
||
if (inval) {
|
||
if (check) {
|
||
exports.checkPath(inval, name);
|
||
}
|
||
}
|
||
return inval;
|
||
}
|
||
exports.getPathInput = getPathInput;
|
||
//-----------------------------------------------------
|
||
// Endpoint Helpers
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Gets the url for a service endpoint
|
||
* If the url was not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param optional whether the url is optional
|
||
* @returns string
|
||
*/
|
||
function getEndpointUrl(id, optional) {
|
||
var urlval = process.env['ENDPOINT_URL_' + id];
|
||
if (!optional && !urlval) {
|
||
throw new Error(exports.loc('LIB_EndpointNotExist', id));
|
||
}
|
||
exports.debug(id + '=' + urlval);
|
||
return urlval;
|
||
}
|
||
exports.getEndpointUrl = getEndpointUrl;
|
||
/*
|
||
* Gets the endpoint data parameter value with specified key for a service endpoint
|
||
* If the endpoint data parameter was not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param key of the parameter
|
||
* @param optional whether the endpoint data is optional
|
||
* @returns {string} value of the endpoint data parameter
|
||
*/
|
||
function getEndpointDataParameter(id, key, optional) {
|
||
var dataParamVal = process.env['ENDPOINT_DATA_' + id + '_' + key.toUpperCase()];
|
||
if (!optional && !dataParamVal) {
|
||
throw new Error(exports.loc('LIB_EndpointDataNotExist', id, key));
|
||
}
|
||
exports.debug(id + ' data ' + key + ' = ' + dataParamVal);
|
||
return dataParamVal;
|
||
}
|
||
exports.getEndpointDataParameter = getEndpointDataParameter;
|
||
/**
|
||
* Gets the endpoint authorization scheme for a service endpoint
|
||
* If the endpoint authorization scheme is not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param optional whether the endpoint authorization scheme is optional
|
||
* @returns {string} value of the endpoint authorization scheme
|
||
*/
|
||
function getEndpointAuthorizationScheme(id, optional) {
|
||
var authScheme = im._vault.retrieveSecret('ENDPOINT_AUTH_SCHEME_' + id);
|
||
if (!optional && !authScheme) {
|
||
throw new Error(exports.loc('LIB_EndpointAuthNotExist', id));
|
||
}
|
||
exports.debug(id + ' auth scheme = ' + authScheme);
|
||
return authScheme;
|
||
}
|
||
exports.getEndpointAuthorizationScheme = getEndpointAuthorizationScheme;
|
||
/**
|
||
* Gets the endpoint authorization parameter value for a service endpoint with specified key
|
||
* If the endpoint authorization parameter is not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param key key to find the endpoint authorization parameter
|
||
* @param optional optional whether the endpoint authorization scheme is optional
|
||
* @returns {string} value of the endpoint authorization parameter value
|
||
*/
|
||
function getEndpointAuthorizationParameter(id, key, optional) {
|
||
var authParam = im._vault.retrieveSecret('ENDPOINT_AUTH_PARAMETER_' + id + '_' + key.toUpperCase());
|
||
if (!optional && !authParam) {
|
||
throw new Error(exports.loc('LIB_EndpointAuthNotExist', id));
|
||
}
|
||
exports.debug(id + ' auth param ' + key + ' = ' + authParam);
|
||
return authParam;
|
||
}
|
||
exports.getEndpointAuthorizationParameter = getEndpointAuthorizationParameter;
|
||
/**
|
||
* Gets the authorization details for a service endpoint
|
||
* If the authorization was not set and is not optional, it will throw.
|
||
*
|
||
* @param id name of the service endpoint
|
||
* @param optional whether the url is optional
|
||
* @returns string
|
||
*/
|
||
function getEndpointAuthorization(id, optional) {
|
||
var aval = im._vault.retrieveSecret('ENDPOINT_AUTH_' + id);
|
||
if (!optional && !aval) {
|
||
setResult(TaskResult.Failed, exports.loc('LIB_EndpointAuthNotExist', id));
|
||
}
|
||
exports.debug(id + ' exists ' + (aval !== null));
|
||
var auth;
|
||
try {
|
||
if (aval) {
|
||
auth = JSON.parse(aval);
|
||
}
|
||
}
|
||
catch (err) {
|
||
throw new Error(exports.loc('LIB_InvalidEndpointAuth', aval));
|
||
}
|
||
return auth;
|
||
}
|
||
exports.getEndpointAuthorization = getEndpointAuthorization;
|
||
//-----------------------------------------------------
|
||
// SecureFile Helpers
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Gets the name for a secure file
|
||
*
|
||
* @param id secure file id
|
||
* @returns string
|
||
*/
|
||
function getSecureFileName(id) {
|
||
var name = process.env['SECUREFILE_NAME_' + id];
|
||
exports.debug('secure file name for id ' + id + ' = ' + name);
|
||
return name;
|
||
}
|
||
exports.getSecureFileName = getSecureFileName;
|
||
/**
|
||
* Gets the secure file ticket that can be used to download the secure file contents
|
||
*
|
||
* @param id name of the secure file
|
||
* @returns {string} secure file ticket
|
||
*/
|
||
function getSecureFileTicket(id) {
|
||
var ticket = im._vault.retrieveSecret('SECUREFILE_TICKET_' + id);
|
||
exports.debug('secure file ticket for id ' + id + ' = ' + ticket);
|
||
return ticket;
|
||
}
|
||
exports.getSecureFileTicket = getSecureFileTicket;
|
||
//-----------------------------------------------------
|
||
// Task Variable Helpers
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Gets a variable value that is set by previous step from the same wrapper task.
|
||
* Requires a 2.115.0 agent or higher.
|
||
*
|
||
* @param name name of the variable to get
|
||
* @returns string
|
||
*/
|
||
function getTaskVariable(name) {
|
||
assertAgent('2.115.0');
|
||
var inval = im._vault.retrieveSecret('VSTS_TASKVARIABLE_' + im._getVariableKey(name));
|
||
if (inval) {
|
||
inval = inval.trim();
|
||
}
|
||
exports.debug('task variable: ' + name + '=' + inval);
|
||
return inval;
|
||
}
|
||
exports.getTaskVariable = getTaskVariable;
|
||
/**
|
||
* Sets a task variable which will only be available to subsequent steps belong to the same wrapper task.
|
||
* Requires a 2.115.0 agent or higher.
|
||
*
|
||
* @param name name of the variable to set
|
||
* @param val value to set
|
||
* @param secret whether variable is secret. optional, defaults to false
|
||
* @returns void
|
||
*/
|
||
function setTaskVariable(name, val, secret) {
|
||
if (secret === void 0) { secret = false; }
|
||
assertAgent('2.115.0');
|
||
var key = im._getVariableKey(name);
|
||
// store the value
|
||
var varValue = val || '';
|
||
exports.debug('set task variable: ' + name + '=' + (secret && varValue ? '********' : varValue));
|
||
im._vault.storeSecret('VSTS_TASKVARIABLE_' + key, varValue);
|
||
delete process.env[key];
|
||
// write the command
|
||
exports.command('task.settaskvariable', { 'variable': name || '', 'issecret': (secret || false).toString() }, varValue);
|
||
}
|
||
exports.setTaskVariable = setTaskVariable;
|
||
//-----------------------------------------------------
|
||
// Cmd Helpers
|
||
//-----------------------------------------------------
|
||
exports.command = im._command;
|
||
exports.warning = im._warning;
|
||
exports.error = im._error;
|
||
exports.debug = im._debug;
|
||
//-----------------------------------------------------
|
||
// Disk Functions
|
||
//-----------------------------------------------------
|
||
function _checkShell(cmd, continueOnError) {
|
||
var se = shell.error();
|
||
if (se) {
|
||
exports.debug(cmd + ' failed');
|
||
var errMsg = exports.loc('LIB_OperationFailed', cmd, se);
|
||
exports.debug(errMsg);
|
||
if (!continueOnError) {
|
||
throw new Error(errMsg);
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Get's stat on a path.
|
||
* Useful for checking whether a file or directory. Also getting created, modified and accessed time.
|
||
* see [fs.stat](https://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||
*
|
||
* @param path path to check
|
||
* @returns fsStat
|
||
*/
|
||
function stats(path) {
|
||
return fs.statSync(path);
|
||
}
|
||
exports.stats = stats;
|
||
exports.exist = im._exist;
|
||
function writeFile(file, data, options) {
|
||
if (typeof (options) === 'string') {
|
||
fs.writeFileSync(file, data, { encoding: options });
|
||
}
|
||
else {
|
||
fs.writeFileSync(file, data, options);
|
||
}
|
||
}
|
||
exports.writeFile = writeFile;
|
||
/**
|
||
* @deprecated Use `getPlatform`
|
||
* Useful for determining the host operating system.
|
||
* see [os.type](https://nodejs.org/api/os.html#os_os_type)
|
||
*
|
||
* @return the name of the operating system
|
||
*/
|
||
function osType() {
|
||
return os.type();
|
||
}
|
||
exports.osType = osType;
|
||
/**
|
||
* Determine the operating system the build agent is running on.
|
||
* @returns {Platform}
|
||
* @throws {Error} Platform is not supported by our agent
|
||
*/
|
||
function getPlatform() {
|
||
switch (process.platform) {
|
||
case 'win32': return Platform.Windows;
|
||
case 'darwin': return Platform.MacOS;
|
||
case 'linux': return Platform.Linux;
|
||
default: throw Error(exports.loc('LIB_PlatformNotSupported', process.platform));
|
||
}
|
||
}
|
||
exports.getPlatform = getPlatform;
|
||
/**
|
||
* Returns the process's current working directory.
|
||
* see [process.cwd](https://nodejs.org/api/process.html#process_process_cwd)
|
||
*
|
||
* @return the path to the current working directory of the process
|
||
*/
|
||
function cwd() {
|
||
return process.cwd();
|
||
}
|
||
exports.cwd = cwd;
|
||
exports.checkPath = im._checkPath;
|
||
/**
|
||
* Change working directory.
|
||
*
|
||
* @param path new working directory path
|
||
* @returns void
|
||
*/
|
||
function cd(path) {
|
||
if (path) {
|
||
shell.cd(path);
|
||
_checkShell('cd');
|
||
}
|
||
}
|
||
exports.cd = cd;
|
||
/**
|
||
* Change working directory and push it on the stack
|
||
*
|
||
* @param path new working directory path
|
||
* @returns void
|
||
*/
|
||
function pushd(path) {
|
||
shell.pushd(path);
|
||
_checkShell('pushd');
|
||
}
|
||
exports.pushd = pushd;
|
||
/**
|
||
* Change working directory back to previously pushed directory
|
||
*
|
||
* @returns void
|
||
*/
|
||
function popd() {
|
||
shell.popd();
|
||
_checkShell('popd');
|
||
}
|
||
exports.popd = popd;
|
||
/**
|
||
* Make a directory. Creates the full path with folders in between
|
||
* Will throw if it fails
|
||
*
|
||
* @param p path to create
|
||
* @returns void
|
||
*/
|
||
function mkdirP(p) {
|
||
if (!p) {
|
||
throw new Error(exports.loc('LIB_ParameterIsRequired', 'p'));
|
||
}
|
||
// build a stack of directories to create
|
||
var stack = [];
|
||
var testDir = p;
|
||
while (true) {
|
||
// validate the loop is not out of control
|
||
if (stack.length >= (process.env['TASKLIB_TEST_MKDIRP_FAILSAFE'] || 1000)) {
|
||
// let the framework throw
|
||
exports.debug('loop is out of control');
|
||
fs.mkdirSync(p);
|
||
return;
|
||
}
|
||
exports.debug("testing directory '" + testDir + "'");
|
||
var stats_1 = void 0;
|
||
try {
|
||
stats_1 = fs.statSync(testDir);
|
||
}
|
||
catch (err) {
|
||
if (err.code == 'ENOENT') {
|
||
// validate the directory is not the drive root
|
||
var parentDir = path.dirname(testDir);
|
||
if (testDir == parentDir) {
|
||
throw new Error(exports.loc('LIB_MkdirFailedInvalidDriveRoot', p, testDir)); // Unable to create directory '{p}'. Root directory does not exist: '{testDir}'
|
||
}
|
||
// push the dir and test the parent
|
||
stack.push(testDir);
|
||
testDir = parentDir;
|
||
continue;
|
||
}
|
||
else if (err.code == 'UNKNOWN') {
|
||
throw new Error(exports.loc('LIB_MkdirFailedInvalidShare', p, testDir)); // Unable to create directory '{p}'. Unable to verify the directory exists: '{testDir}'. If directory is a file share, please verify the share name is correct, the share is online, and the current process has permission to access the share.
|
||
}
|
||
else {
|
||
throw err;
|
||
}
|
||
}
|
||
if (!stats_1.isDirectory()) {
|
||
throw new Error(exports.loc('LIB_MkdirFailedFileExists', p, testDir)); // Unable to create directory '{p}'. Conflicting file exists: '{testDir}'
|
||
}
|
||
// testDir exists
|
||
break;
|
||
}
|
||
// create each directory
|
||
while (stack.length) {
|
||
var dir = stack.pop(); // non-null because `stack.length` was truthy
|
||
exports.debug("mkdir '" + dir + "'");
|
||
try {
|
||
fs.mkdirSync(dir);
|
||
}
|
||
catch (err) {
|
||
throw new Error(exports.loc('LIB_MkdirFailed', p, err.message)); // Unable to create directory '{p}'. {err.message}
|
||
}
|
||
}
|
||
}
|
||
exports.mkdirP = mkdirP;
|
||
/**
|
||
* Resolves a sequence of paths or path segments into an absolute path.
|
||
* Calls node.js path.resolve()
|
||
* Allows L0 testing with consistent path formats on Mac/Linux and Windows in the mock implementation
|
||
* @param pathSegments
|
||
* @returns {string}
|
||
*/
|
||
function resolve() {
|
||
var pathSegments = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
pathSegments[_i] = arguments[_i];
|
||
}
|
||
var absolutePath = path.resolve.apply(this, pathSegments);
|
||
exports.debug('Absolute path for pathSegments: ' + pathSegments + ' = ' + absolutePath);
|
||
return absolutePath;
|
||
}
|
||
exports.resolve = resolve;
|
||
exports.which = im._which;
|
||
/**
|
||
* Returns array of files in the given path, or in current directory if no path provided. See shelljs.ls
|
||
* @param {string} options Available options: -R (recursive), -A (all files, include files beginning with ., except for . and ..)
|
||
* @param {string[]} paths Paths to search.
|
||
* @return {string[]} An array of files in the given path(s).
|
||
*/
|
||
function ls(options, paths) {
|
||
if (options) {
|
||
return shell.ls(options, paths);
|
||
}
|
||
else {
|
||
return shell.ls(paths);
|
||
}
|
||
}
|
||
exports.ls = ls;
|
||
/**
|
||
* Copies a file or folder.
|
||
*
|
||
* @param source source path
|
||
* @param dest destination path
|
||
* @param options string -r, -f or -rf for recursive and force
|
||
* @param continueOnError optional. whether to continue on error
|
||
* @param retryCount optional. Retry count to copy the file. It might help to resolve intermittent issues e.g. with UNC target paths on a remote host.
|
||
*/
|
||
function cp(source, dest, options, continueOnError, retryCount) {
|
||
if (retryCount === void 0) { retryCount = 0; }
|
||
while (retryCount >= 0) {
|
||
try {
|
||
if (options) {
|
||
shell.cp(options, source, dest);
|
||
}
|
||
else {
|
||
shell.cp(source, dest);
|
||
}
|
||
_checkShell('cp', false);
|
||
break;
|
||
}
|
||
catch (e) {
|
||
if (retryCount <= 0) {
|
||
if (continueOnError) {
|
||
exports.warning(e);
|
||
break;
|
||
}
|
||
else {
|
||
throw e;
|
||
}
|
||
}
|
||
else {
|
||
console.log(exports.loc('LIB_CopyFileFailed', retryCount));
|
||
retryCount--;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
exports.cp = cp;
|
||
/**
|
||
* Moves a path.
|
||
*
|
||
* @param source source path
|
||
* @param dest destination path
|
||
* @param options string -f or -n for force and no clobber
|
||
* @param continueOnError optional. whether to continue on error
|
||
*/
|
||
function mv(source, dest, options, continueOnError) {
|
||
if (options) {
|
||
shell.mv(options, source, dest);
|
||
}
|
||
else {
|
||
shell.mv(source, dest);
|
||
}
|
||
_checkShell('mv', continueOnError);
|
||
}
|
||
exports.mv = mv;
|
||
/**
|
||
* Recursively finds all paths a given path. Returns an array of paths.
|
||
*
|
||
* @param findPath path to search
|
||
* @param options optional. defaults to { followSymbolicLinks: true }. following soft links is generally appropriate unless deleting files.
|
||
* @returns string[]
|
||
*/
|
||
function find(findPath, options) {
|
||
if (!findPath) {
|
||
exports.debug('no path specified');
|
||
return [];
|
||
}
|
||
// normalize the path, otherwise the first result is inconsistently formatted from the rest of the results
|
||
// because path.join() performs normalization.
|
||
findPath = path.normalize(findPath);
|
||
// debug trace the parameters
|
||
exports.debug("findPath: '" + findPath + "'");
|
||
options = options || _getDefaultFindOptions();
|
||
_debugFindOptions(options);
|
||
// return empty if not exists
|
||
try {
|
||
fs.lstatSync(findPath);
|
||
}
|
||
catch (err) {
|
||
if (err.code == 'ENOENT') {
|
||
exports.debug('0 results');
|
||
return [];
|
||
}
|
||
throw err;
|
||
}
|
||
try {
|
||
var result = [];
|
||
// push the first item
|
||
var stack = [new _FindItem(findPath, 1)];
|
||
var traversalChain = []; // used to detect cycles
|
||
var _loop_1 = function () {
|
||
// pop the next item and push to the result array
|
||
var item = stack.pop(); // non-null because `stack.length` was truthy
|
||
result.push(item.path);
|
||
// stat the item. the stat info is used further below to determine whether to traverse deeper
|
||
//
|
||
// stat returns info about the target of a symlink (or symlink chain),
|
||
// lstat returns info about a symlink itself
|
||
var stats_2 = void 0;
|
||
if (options.followSymbolicLinks) {
|
||
try {
|
||
// use stat (following all symlinks)
|
||
stats_2 = fs.statSync(item.path);
|
||
}
|
||
catch (err) {
|
||
if (err.code == 'ENOENT' && options.allowBrokenSymbolicLinks) {
|
||
// fallback to lstat (broken symlinks allowed)
|
||
stats_2 = fs.lstatSync(item.path);
|
||
exports.debug(" " + item.path + " (broken symlink)");
|
||
}
|
||
else {
|
||
throw err;
|
||
}
|
||
}
|
||
}
|
||
else if (options.followSpecifiedSymbolicLink && result.length == 1) {
|
||
try {
|
||
// use stat (following symlinks for the specified path and this is the specified path)
|
||
stats_2 = fs.statSync(item.path);
|
||
}
|
||
catch (err) {
|
||
if (err.code == 'ENOENT' && options.allowBrokenSymbolicLinks) {
|
||
// fallback to lstat (broken symlinks allowed)
|
||
stats_2 = fs.lstatSync(item.path);
|
||
exports.debug(" " + item.path + " (broken symlink)");
|
||
}
|
||
else {
|
||
throw err;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
// use lstat (not following symlinks)
|
||
stats_2 = fs.lstatSync(item.path);
|
||
}
|
||
// note, isDirectory() returns false for the lstat of a symlink
|
||
if (stats_2.isDirectory()) {
|
||
exports.debug(" " + item.path + " (directory)");
|
||
if (options.followSymbolicLinks) {
|
||
// get the realpath
|
||
var realPath_1 = fs.realpathSync(item.path);
|
||
// fixup the traversal chain to match the item level
|
||
while (traversalChain.length >= item.level) {
|
||
traversalChain.pop();
|
||
}
|
||
// test for a cycle
|
||
if (traversalChain.some(function (x) { return x == realPath_1; })) {
|
||
exports.debug(' cycle detected');
|
||
return "continue";
|
||
}
|
||
// update the traversal chain
|
||
traversalChain.push(realPath_1);
|
||
}
|
||
// push the child items in reverse onto the stack
|
||
var childLevel_1 = item.level + 1;
|
||
var childItems = fs.readdirSync(item.path)
|
||
.map(function (childName) { return new _FindItem(path.join(item.path, childName), childLevel_1); });
|
||
for (var i = childItems.length - 1; i >= 0; i--) {
|
||
stack.push(childItems[i]);
|
||
}
|
||
}
|
||
else {
|
||
exports.debug(" " + item.path + " (file)");
|
||
}
|
||
};
|
||
while (stack.length) {
|
||
_loop_1();
|
||
}
|
||
exports.debug(result.length + " results");
|
||
return result;
|
||
}
|
||
catch (err) {
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'find', err.message));
|
||
}
|
||
}
|
||
exports.find = find;
|
||
var _FindItem = /** @class */ (function () {
|
||
function _FindItem(path, level) {
|
||
this.path = path;
|
||
this.level = level;
|
||
}
|
||
return _FindItem;
|
||
}());
|
||
function _debugFindOptions(options) {
|
||
exports.debug("findOptions.allowBrokenSymbolicLinks: '" + options.allowBrokenSymbolicLinks + "'");
|
||
exports.debug("findOptions.followSpecifiedSymbolicLink: '" + options.followSpecifiedSymbolicLink + "'");
|
||
exports.debug("findOptions.followSymbolicLinks: '" + options.followSymbolicLinks + "'");
|
||
}
|
||
function _getDefaultFindOptions() {
|
||
return {
|
||
allowBrokenSymbolicLinks: false,
|
||
followSpecifiedSymbolicLink: true,
|
||
followSymbolicLinks: true
|
||
};
|
||
}
|
||
/**
|
||
* Prefer tl.find() and tl.match() instead. This function is for backward compatibility
|
||
* when porting tasks to Node from the PowerShell or PowerShell3 execution handler.
|
||
*
|
||
* @param rootDirectory path to root unrooted patterns with
|
||
* @param pattern include and exclude patterns
|
||
* @param includeFiles whether to include files in the result. defaults to true when includeFiles and includeDirectories are both false
|
||
* @param includeDirectories whether to include directories in the result
|
||
* @returns string[]
|
||
*/
|
||
function legacyFindFiles(rootDirectory, pattern, includeFiles, includeDirectories) {
|
||
if (!pattern) {
|
||
throw new Error('pattern parameter cannot be empty');
|
||
}
|
||
exports.debug("legacyFindFiles rootDirectory: '" + rootDirectory + "'");
|
||
exports.debug("pattern: '" + pattern + "'");
|
||
exports.debug("includeFiles: '" + includeFiles + "'");
|
||
exports.debug("includeDirectories: '" + includeDirectories + "'");
|
||
if (!includeFiles && !includeDirectories) {
|
||
includeFiles = true;
|
||
}
|
||
// organize the patterns into include patterns and exclude patterns
|
||
var includePatterns = [];
|
||
var excludePatterns = [];
|
||
pattern = pattern.replace(/;;/g, '\0');
|
||
for (var _i = 0, _a = pattern.split(';'); _i < _a.length; _i++) {
|
||
var pat = _a[_i];
|
||
if (!pat) {
|
||
continue;
|
||
}
|
||
pat = pat.replace(/\0/g, ';');
|
||
// determine whether include pattern and remove any include/exclude prefix.
|
||
// include patterns start with +: or anything other than -:
|
||
// exclude patterns start with -:
|
||
var isIncludePattern = void 0;
|
||
if (im._startsWith(pat, '+:')) {
|
||
pat = pat.substring(2);
|
||
isIncludePattern = true;
|
||
}
|
||
else if (im._startsWith(pat, '-:')) {
|
||
pat = pat.substring(2);
|
||
isIncludePattern = false;
|
||
}
|
||
else {
|
||
isIncludePattern = true;
|
||
}
|
||
// validate pattern does not end with a slash
|
||
if (im._endsWith(pat, '/') || (process.platform == 'win32' && im._endsWith(pat, '\\'))) {
|
||
throw new Error(exports.loc('LIB_InvalidPattern', pat));
|
||
}
|
||
// root the pattern
|
||
if (rootDirectory && !path.isAbsolute(pat)) {
|
||
pat = path.join(rootDirectory, pat);
|
||
// remove trailing slash sometimes added by path.join() on Windows, e.g.
|
||
// path.join('\\\\hello', 'world') => '\\\\hello\\world\\'
|
||
// path.join('//hello', 'world') => '\\\\hello\\world\\'
|
||
if (im._endsWith(pat, '\\')) {
|
||
pat = pat.substring(0, pat.length - 1);
|
||
}
|
||
}
|
||
if (isIncludePattern) {
|
||
includePatterns.push(pat);
|
||
}
|
||
else {
|
||
excludePatterns.push(im._legacyFindFiles_convertPatternToRegExp(pat));
|
||
}
|
||
}
|
||
// find and apply patterns
|
||
var count = 0;
|
||
var result = _legacyFindFiles_getMatchingItems(includePatterns, excludePatterns, !!includeFiles, !!includeDirectories);
|
||
exports.debug('all matches:');
|
||
for (var _b = 0, result_1 = result; _b < result_1.length; _b++) {
|
||
var resultItem = result_1[_b];
|
||
exports.debug(' ' + resultItem);
|
||
}
|
||
exports.debug('total matched: ' + result.length);
|
||
return result;
|
||
}
|
||
exports.legacyFindFiles = legacyFindFiles;
|
||
function _legacyFindFiles_getMatchingItems(includePatterns, excludePatterns, includeFiles, includeDirectories) {
|
||
exports.debug('getMatchingItems()');
|
||
for (var _i = 0, includePatterns_1 = includePatterns; _i < includePatterns_1.length; _i++) {
|
||
var pattern = includePatterns_1[_i];
|
||
exports.debug("includePattern: '" + pattern + "'");
|
||
}
|
||
for (var _a = 0, excludePatterns_1 = excludePatterns; _a < excludePatterns_1.length; _a++) {
|
||
var pattern = excludePatterns_1[_a];
|
||
exports.debug("excludePattern: " + pattern);
|
||
}
|
||
exports.debug('includeFiles: ' + includeFiles);
|
||
exports.debug('includeDirectories: ' + includeDirectories);
|
||
var allFiles = {};
|
||
var _loop_2 = function (pattern) {
|
||
// determine the directory to search
|
||
//
|
||
// note, getDirectoryName removes redundant path separators
|
||
var findPath = void 0;
|
||
var starIndex = pattern.indexOf('*');
|
||
var questionIndex = pattern.indexOf('?');
|
||
if (starIndex < 0 && questionIndex < 0) {
|
||
// if no wildcards are found, use the directory name portion of the path.
|
||
// if there is no directory name (file name only in pattern or drive root),
|
||
// this will return empty string.
|
||
findPath = im._getDirectoryName(pattern);
|
||
}
|
||
else {
|
||
// extract the directory prior to the first wildcard
|
||
var index = Math.min(starIndex >= 0 ? starIndex : questionIndex, questionIndex >= 0 ? questionIndex : starIndex);
|
||
findPath = im._getDirectoryName(pattern.substring(0, index));
|
||
}
|
||
// note, due to this short-circuit and the above usage of getDirectoryName, this
|
||
// function has the same limitations regarding drive roots as the powershell
|
||
// implementation.
|
||
//
|
||
// also note, since getDirectoryName eliminates slash redundancies, some additional
|
||
// work may be required if removal of this limitation is attempted.
|
||
if (!findPath) {
|
||
return "continue";
|
||
}
|
||
var patternRegex = im._legacyFindFiles_convertPatternToRegExp(pattern);
|
||
// find files/directories
|
||
var items = find(findPath, { followSymbolicLinks: true })
|
||
.filter(function (item) {
|
||
if (includeFiles && includeDirectories) {
|
||
return true;
|
||
}
|
||
var isDir = fs.statSync(item).isDirectory();
|
||
return (includeFiles && !isDir) || (includeDirectories && isDir);
|
||
})
|
||
.forEach(function (item) {
|
||
var normalizedPath = process.platform == 'win32' ? item.replace(/\\/g, '/') : item; // normalize separators
|
||
// **/times/** will not match C:/fun/times because there isn't a trailing slash
|
||
// so try both if including directories
|
||
var alternatePath = normalizedPath + "/"; // potential bug: it looks like this will result in a false
|
||
// positive if the item is a regular file and not a directory
|
||
var isMatch = false;
|
||
if (patternRegex.test(normalizedPath) || (includeDirectories && patternRegex.test(alternatePath))) {
|
||
isMatch = true;
|
||
// test whether the path should be excluded
|
||
for (var _i = 0, excludePatterns_2 = excludePatterns; _i < excludePatterns_2.length; _i++) {
|
||
var regex = excludePatterns_2[_i];
|
||
if (regex.test(normalizedPath) || (includeDirectories && regex.test(alternatePath))) {
|
||
isMatch = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (isMatch) {
|
||
allFiles[item] = item;
|
||
}
|
||
});
|
||
};
|
||
for (var _b = 0, includePatterns_2 = includePatterns; _b < includePatterns_2.length; _b++) {
|
||
var pattern = includePatterns_2[_b];
|
||
_loop_2(pattern);
|
||
}
|
||
return Object.keys(allFiles).sort();
|
||
}
|
||
/**
|
||
* Remove a path recursively with force
|
||
*
|
||
* @param inputPath path to remove
|
||
* @throws when the file or directory exists but could not be deleted.
|
||
*/
|
||
function rmRF(inputPath) {
|
||
exports.debug('rm -rf ' + inputPath);
|
||
if (getPlatform() == Platform.Windows) {
|
||
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
|
||
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
|
||
try {
|
||
if (fs.statSync(inputPath).isDirectory()) {
|
||
exports.debug('removing directory ' + inputPath);
|
||
childProcess.execSync("rd /s /q \"" + inputPath + "\"");
|
||
}
|
||
else {
|
||
exports.debug('removing file ' + inputPath);
|
||
childProcess.execSync("del /f /a \"" + inputPath + "\"");
|
||
}
|
||
}
|
||
catch (err) {
|
||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||
// other errors are valid
|
||
if (err.code != 'ENOENT') {
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
|
||
}
|
||
}
|
||
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
|
||
try {
|
||
fs.unlinkSync(inputPath);
|
||
}
|
||
catch (err) {
|
||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||
// other errors are valid
|
||
if (err.code != 'ENOENT') {
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
// get the lstats in order to workaround a bug in shelljs@0.3.0 where symlinks
|
||
// with missing targets are not handled correctly by "rm('-rf', path)"
|
||
var lstats = void 0;
|
||
try {
|
||
lstats = fs.lstatSync(inputPath);
|
||
}
|
||
catch (err) {
|
||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||
// other errors are valid
|
||
if (err.code == 'ENOENT') {
|
||
return;
|
||
}
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
|
||
}
|
||
if (lstats.isDirectory()) {
|
||
exports.debug('removing directory');
|
||
shell.rm('-rf', inputPath);
|
||
var errMsg = shell.error();
|
||
if (errMsg) {
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', errMsg));
|
||
}
|
||
return;
|
||
}
|
||
exports.debug('removing file');
|
||
try {
|
||
fs.unlinkSync(inputPath);
|
||
}
|
||
catch (err) {
|
||
throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
|
||
}
|
||
}
|
||
}
|
||
exports.rmRF = rmRF;
|
||
/**
|
||
* Exec a tool. Convenience wrapper over ToolRunner to exec with args in one call.
|
||
* Output will be streamed to the live console.
|
||
* Returns promise with return code
|
||
*
|
||
* @param tool path to tool to exec
|
||
* @param args an arg string or array of args
|
||
* @param options optional exec options. See IExecOptions
|
||
* @returns number
|
||
*/
|
||
function exec(tool, args, options) {
|
||
var tr = this.tool(tool);
|
||
tr.on('debug', function (data) {
|
||
exports.debug(data);
|
||
});
|
||
if (args) {
|
||
if (args instanceof Array) {
|
||
tr.arg(args);
|
||
}
|
||
else if (typeof (args) === 'string') {
|
||
tr.line(args);
|
||
}
|
||
}
|
||
return tr.exec(options);
|
||
}
|
||
exports.exec = exec;
|
||
/**
|
||
* Exec a tool synchronously. Convenience wrapper over ToolRunner to execSync with args in one call.
|
||
* Output will be *not* be streamed to the live console. It will be returned after execution is complete.
|
||
* Appropriate for short running tools
|
||
* Returns IExecResult with output and return code
|
||
*
|
||
* @param tool path to tool to exec
|
||
* @param args an arg string or array of args
|
||
* @param options optional exec options. See IExecSyncOptions
|
||
* @returns IExecSyncResult
|
||
*/
|
||
function execSync(tool, args, options) {
|
||
var tr = this.tool(tool);
|
||
tr.on('debug', function (data) {
|
||
exports.debug(data);
|
||
});
|
||
if (args) {
|
||
if (args instanceof Array) {
|
||
tr.arg(args);
|
||
}
|
||
else if (typeof (args) === 'string') {
|
||
tr.line(args);
|
||
}
|
||
}
|
||
return tr.execSync(options);
|
||
}
|
||
exports.execSync = execSync;
|
||
/**
|
||
* Convenience factory to create a ToolRunner.
|
||
*
|
||
* @param tool path to tool to exec
|
||
* @returns ToolRunner
|
||
*/
|
||
function tool(tool) {
|
||
var tr = new trm.ToolRunner(tool);
|
||
tr.on('debug', function (message) {
|
||
exports.debug(message);
|
||
});
|
||
return tr;
|
||
}
|
||
exports.tool = tool;
|
||
/**
|
||
* Applies glob patterns to a list of paths. Supports interleaved exclude patterns.
|
||
*
|
||
* @param list array of paths
|
||
* @param patterns patterns to apply. supports interleaved exclude patterns.
|
||
* @param patternRoot optional. default root to apply to unrooted patterns. not applied to basename-only patterns when matchBase:true.
|
||
* @param options optional. defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }.
|
||
*/
|
||
function match(list, patterns, patternRoot, options) {
|
||
// trace parameters
|
||
exports.debug("patternRoot: '" + patternRoot + "'");
|
||
options = options || _getDefaultMatchOptions(); // default match options
|
||
_debugMatchOptions(options);
|
||
// convert pattern to an array
|
||
if (typeof patterns == 'string') {
|
||
patterns = [patterns];
|
||
}
|
||
// hashtable to keep track of matches
|
||
var map = {};
|
||
var originalOptions = options;
|
||
for (var _i = 0, patterns_1 = patterns; _i < patterns_1.length; _i++) {
|
||
var pattern = patterns_1[_i];
|
||
exports.debug("pattern: '" + pattern + "'");
|
||
// trim and skip empty
|
||
pattern = (pattern || '').trim();
|
||
if (!pattern) {
|
||
exports.debug('skipping empty pattern');
|
||
continue;
|
||
}
|
||
// clone match options
|
||
var options_1 = im._cloneMatchOptions(originalOptions);
|
||
// skip comments
|
||
if (!options_1.nocomment && im._startsWith(pattern, '#')) {
|
||
exports.debug('skipping comment');
|
||
continue;
|
||
}
|
||
// set nocomment - brace expansion could result in a leading '#'
|
||
options_1.nocomment = true;
|
||
// determine whether pattern is include or exclude
|
||
var negateCount = 0;
|
||
if (!options_1.nonegate) {
|
||
while (pattern.charAt(negateCount) == '!') {
|
||
negateCount++;
|
||
}
|
||
pattern = pattern.substring(negateCount); // trim leading '!'
|
||
if (negateCount) {
|
||
exports.debug("trimmed leading '!'. pattern: '" + pattern + "'");
|
||
}
|
||
}
|
||
var isIncludePattern = negateCount == 0 ||
|
||
(negateCount % 2 == 0 && !options_1.flipNegate) ||
|
||
(negateCount % 2 == 1 && options_1.flipNegate);
|
||
// set nonegate - brace expansion could result in a leading '!'
|
||
options_1.nonegate = true;
|
||
options_1.flipNegate = false;
|
||
// expand braces - required to accurately root patterns
|
||
var expanded = void 0;
|
||
var preExpanded = pattern;
|
||
if (options_1.nobrace) {
|
||
expanded = [pattern];
|
||
}
|
||
else {
|
||
// convert slashes on Windows before calling braceExpand(). unfortunately this means braces cannot
|
||
// be escaped on Windows, this limitation is consistent with current limitations of minimatch (3.0.3).
|
||
exports.debug('expanding braces');
|
||
var convertedPattern = process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern;
|
||
expanded = minimatch.braceExpand(convertedPattern);
|
||
}
|
||
// set nobrace
|
||
options_1.nobrace = true;
|
||
for (var _a = 0, expanded_1 = expanded; _a < expanded_1.length; _a++) {
|
||
var pattern_1 = expanded_1[_a];
|
||
if (expanded.length != 1 || pattern_1 != preExpanded) {
|
||
exports.debug("pattern: '" + pattern_1 + "'");
|
||
}
|
||
// trim and skip empty
|
||
pattern_1 = (pattern_1 || '').trim();
|
||
if (!pattern_1) {
|
||
exports.debug('skipping empty pattern');
|
||
continue;
|
||
}
|
||
// root the pattern when all of the following conditions are true:
|
||
if (patternRoot && // patternRoot supplied
|
||
!im._isRooted(pattern_1) && // AND pattern not rooted
|
||
// AND matchBase:false or not basename only
|
||
(!options_1.matchBase || (process.platform == 'win32' ? pattern_1.replace(/\\/g, '/') : pattern_1).indexOf('/') >= 0)) {
|
||
pattern_1 = im._ensureRooted(patternRoot, pattern_1);
|
||
exports.debug("rooted pattern: '" + pattern_1 + "'");
|
||
}
|
||
if (isIncludePattern) {
|
||
// apply the pattern
|
||
exports.debug('applying include pattern against original list');
|
||
var matchResults = minimatch.match(list, pattern_1, options_1);
|
||
exports.debug(matchResults.length + ' matches');
|
||
// union the results
|
||
for (var _b = 0, matchResults_1 = matchResults; _b < matchResults_1.length; _b++) {
|
||
var matchResult = matchResults_1[_b];
|
||
map[matchResult] = true;
|
||
}
|
||
}
|
||
else {
|
||
// apply the pattern
|
||
exports.debug('applying exclude pattern against original list');
|
||
var matchResults = minimatch.match(list, pattern_1, options_1);
|
||
exports.debug(matchResults.length + ' matches');
|
||
// substract the results
|
||
for (var _c = 0, matchResults_2 = matchResults; _c < matchResults_2.length; _c++) {
|
||
var matchResult = matchResults_2[_c];
|
||
delete map[matchResult];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// return a filtered version of the original list (preserves order and prevents duplication)
|
||
var result = list.filter(function (item) { return map.hasOwnProperty(item); });
|
||
exports.debug(result.length + ' final results');
|
||
return result;
|
||
}
|
||
exports.match = match;
|
||
/**
|
||
* Filter to apply glob patterns
|
||
*
|
||
* @param pattern pattern to apply
|
||
* @param options optional. defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }.
|
||
*/
|
||
function filter(pattern, options) {
|
||
options = options || _getDefaultMatchOptions();
|
||
return minimatch.filter(pattern, options);
|
||
}
|
||
exports.filter = filter;
|
||
function _debugMatchOptions(options) {
|
||
exports.debug("matchOptions.debug: '" + options.debug + "'");
|
||
exports.debug("matchOptions.nobrace: '" + options.nobrace + "'");
|
||
exports.debug("matchOptions.noglobstar: '" + options.noglobstar + "'");
|
||
exports.debug("matchOptions.dot: '" + options.dot + "'");
|
||
exports.debug("matchOptions.noext: '" + options.noext + "'");
|
||
exports.debug("matchOptions.nocase: '" + options.nocase + "'");
|
||
exports.debug("matchOptions.nonull: '" + options.nonull + "'");
|
||
exports.debug("matchOptions.matchBase: '" + options.matchBase + "'");
|
||
exports.debug("matchOptions.nocomment: '" + options.nocomment + "'");
|
||
exports.debug("matchOptions.nonegate: '" + options.nonegate + "'");
|
||
exports.debug("matchOptions.flipNegate: '" + options.flipNegate + "'");
|
||
}
|
||
function _getDefaultMatchOptions() {
|
||
return {
|
||
debug: false,
|
||
nobrace: true,
|
||
noglobstar: false,
|
||
dot: true,
|
||
noext: false,
|
||
nocase: process.platform == 'win32',
|
||
nonull: false,
|
||
matchBase: false,
|
||
nocomment: false,
|
||
nonegate: false,
|
||
flipNegate: false
|
||
};
|
||
}
|
||
/**
|
||
* Determines the find root from a list of patterns. Performs the find and then applies the glob patterns.
|
||
* Supports interleaved exclude patterns. Unrooted patterns are rooted using defaultRoot, unless
|
||
* matchOptions.matchBase is specified and the pattern is a basename only. For matchBase cases, the
|
||
* defaultRoot is used as the find root.
|
||
*
|
||
* @param defaultRoot default path to root unrooted patterns. falls back to System.DefaultWorkingDirectory or process.cwd().
|
||
* @param patterns pattern or array of patterns to apply
|
||
* @param findOptions defaults to { followSymbolicLinks: true }. following soft links is generally appropriate unless deleting files.
|
||
* @param matchOptions defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }
|
||
*/
|
||
function findMatch(defaultRoot, patterns, findOptions, matchOptions) {
|
||
// apply defaults for parameters and trace
|
||
defaultRoot = defaultRoot || this.getVariable('system.defaultWorkingDirectory') || process.cwd();
|
||
exports.debug("defaultRoot: '" + defaultRoot + "'");
|
||
patterns = patterns || [];
|
||
patterns = typeof patterns == 'string' ? [patterns] : patterns;
|
||
findOptions = findOptions || _getDefaultFindOptions();
|
||
_debugFindOptions(findOptions);
|
||
matchOptions = matchOptions || _getDefaultMatchOptions();
|
||
_debugMatchOptions(matchOptions);
|
||
// normalize slashes for root dir
|
||
defaultRoot = im._normalizeSeparators(defaultRoot);
|
||
var results = {};
|
||
var originalMatchOptions = matchOptions;
|
||
for (var _i = 0, _a = (patterns || []); _i < _a.length; _i++) {
|
||
var pattern = _a[_i];
|
||
exports.debug("pattern: '" + pattern + "'");
|
||
// trim and skip empty
|
||
pattern = (pattern || '').trim();
|
||
if (!pattern) {
|
||
exports.debug('skipping empty pattern');
|
||
continue;
|
||
}
|
||
// clone match options
|
||
var matchOptions_1 = im._cloneMatchOptions(originalMatchOptions);
|
||
// skip comments
|
||
if (!matchOptions_1.nocomment && im._startsWith(pattern, '#')) {
|
||
exports.debug('skipping comment');
|
||
continue;
|
||
}
|
||
// set nocomment - brace expansion could result in a leading '#'
|
||
matchOptions_1.nocomment = true;
|
||
// determine whether pattern is include or exclude
|
||
var negateCount = 0;
|
||
if (!matchOptions_1.nonegate) {
|
||
while (pattern.charAt(negateCount) == '!') {
|
||
negateCount++;
|
||
}
|
||
pattern = pattern.substring(negateCount); // trim leading '!'
|
||
if (negateCount) {
|
||
exports.debug("trimmed leading '!'. pattern: '" + pattern + "'");
|
||
}
|
||
}
|
||
var isIncludePattern = negateCount == 0 ||
|
||
(negateCount % 2 == 0 && !matchOptions_1.flipNegate) ||
|
||
(negateCount % 2 == 1 && matchOptions_1.flipNegate);
|
||
// set nonegate - brace expansion could result in a leading '!'
|
||
matchOptions_1.nonegate = true;
|
||
matchOptions_1.flipNegate = false;
|
||
// expand braces - required to accurately interpret findPath
|
||
var expanded = void 0;
|
||
var preExpanded = pattern;
|
||
if (matchOptions_1.nobrace) {
|
||
expanded = [pattern];
|
||
}
|
||
else {
|
||
// convert slashes on Windows before calling braceExpand(). unfortunately this means braces cannot
|
||
// be escaped on Windows, this limitation is consistent with current limitations of minimatch (3.0.3).
|
||
exports.debug('expanding braces');
|
||
var convertedPattern = process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern;
|
||
expanded = minimatch.braceExpand(convertedPattern);
|
||
}
|
||
// set nobrace
|
||
matchOptions_1.nobrace = true;
|
||
for (var _b = 0, expanded_2 = expanded; _b < expanded_2.length; _b++) {
|
||
var pattern_2 = expanded_2[_b];
|
||
if (expanded.length != 1 || pattern_2 != preExpanded) {
|
||
exports.debug("pattern: '" + pattern_2 + "'");
|
||
}
|
||
// trim and skip empty
|
||
pattern_2 = (pattern_2 || '').trim();
|
||
if (!pattern_2) {
|
||
exports.debug('skipping empty pattern');
|
||
continue;
|
||
}
|
||
if (isIncludePattern) {
|
||
// determine the findPath
|
||
var findInfo = im._getFindInfoFromPattern(defaultRoot, pattern_2, matchOptions_1);
|
||
var findPath = findInfo.findPath;
|
||
exports.debug("findPath: '" + findPath + "'");
|
||
if (!findPath) {
|
||
exports.debug('skipping empty path');
|
||
continue;
|
||
}
|
||
// perform the find
|
||
exports.debug("statOnly: '" + findInfo.statOnly + "'");
|
||
var findResults = [];
|
||
if (findInfo.statOnly) {
|
||
// simply stat the path - all path segments were used to build the path
|
||
try {
|
||
fs.statSync(findPath);
|
||
findResults.push(findPath);
|
||
}
|
||
catch (err) {
|
||
if (err.code != 'ENOENT') {
|
||
throw err;
|
||
}
|
||
exports.debug('ENOENT');
|
||
}
|
||
}
|
||
else {
|
||
findResults = find(findPath, findOptions);
|
||
}
|
||
exports.debug("found " + findResults.length + " paths");
|
||
// apply the pattern
|
||
exports.debug('applying include pattern');
|
||
if (findInfo.adjustedPattern != pattern_2) {
|
||
exports.debug("adjustedPattern: '" + findInfo.adjustedPattern + "'");
|
||
pattern_2 = findInfo.adjustedPattern;
|
||
}
|
||
var matchResults = minimatch.match(findResults, pattern_2, matchOptions_1);
|
||
exports.debug(matchResults.length + ' matches');
|
||
// union the results
|
||
for (var _c = 0, matchResults_3 = matchResults; _c < matchResults_3.length; _c++) {
|
||
var matchResult = matchResults_3[_c];
|
||
var key = process.platform == 'win32' ? matchResult.toUpperCase() : matchResult;
|
||
results[key] = matchResult;
|
||
}
|
||
}
|
||
else {
|
||
// check if basename only and matchBase=true
|
||
if (matchOptions_1.matchBase &&
|
||
!im._isRooted(pattern_2) &&
|
||
(process.platform == 'win32' ? pattern_2.replace(/\\/g, '/') : pattern_2).indexOf('/') < 0) {
|
||
// do not root the pattern
|
||
exports.debug('matchBase and basename only');
|
||
}
|
||
else {
|
||
// root the exclude pattern
|
||
pattern_2 = im._ensurePatternRooted(defaultRoot, pattern_2);
|
||
exports.debug("after ensurePatternRooted, pattern: '" + pattern_2 + "'");
|
||
}
|
||
// apply the pattern
|
||
exports.debug('applying exclude pattern');
|
||
var matchResults = minimatch.match(Object.keys(results).map(function (key) { return results[key]; }), pattern_2, matchOptions_1);
|
||
exports.debug(matchResults.length + ' matches');
|
||
// substract the results
|
||
for (var _d = 0, matchResults_4 = matchResults; _d < matchResults_4.length; _d++) {
|
||
var matchResult = matchResults_4[_d];
|
||
var key = process.platform == 'win32' ? matchResult.toUpperCase() : matchResult;
|
||
delete results[key];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
var finalResult = Object.keys(results)
|
||
.map(function (key) { return results[key]; })
|
||
.sort();
|
||
exports.debug(finalResult.length + ' final results');
|
||
return finalResult;
|
||
}
|
||
exports.findMatch = findMatch;
|
||
/**
|
||
* Gets http proxy configuration used by Build/Release agent
|
||
*
|
||
* @return ProxyConfiguration
|
||
*/
|
||
function getHttpProxyConfiguration(requestUrl) {
|
||
var proxyUrl = exports.getVariable('Agent.ProxyUrl');
|
||
if (proxyUrl && proxyUrl.length > 0) {
|
||
var proxyUsername = exports.getVariable('Agent.ProxyUsername');
|
||
var proxyPassword = exports.getVariable('Agent.ProxyPassword');
|
||
var proxyBypassHosts = JSON.parse(exports.getVariable('Agent.ProxyBypassList') || '[]');
|
||
var bypass_1 = false;
|
||
if (requestUrl) {
|
||
proxyBypassHosts.forEach(function (bypassHost) {
|
||
if (new RegExp(bypassHost, 'i').test(requestUrl)) {
|
||
bypass_1 = true;
|
||
}
|
||
});
|
||
}
|
||
if (bypass_1) {
|
||
return null;
|
||
}
|
||
else {
|
||
return {
|
||
proxyUrl: proxyUrl,
|
||
proxyUsername: proxyUsername,
|
||
proxyPassword: proxyPassword,
|
||
proxyBypassHosts: proxyBypassHosts
|
||
};
|
||
}
|
||
}
|
||
else {
|
||
return null;
|
||
}
|
||
}
|
||
exports.getHttpProxyConfiguration = getHttpProxyConfiguration;
|
||
/**
|
||
* Gets http certificate configuration used by Build/Release agent
|
||
*
|
||
* @return CertConfiguration
|
||
*/
|
||
function getHttpCertConfiguration() {
|
||
var ca = exports.getVariable('Agent.CAInfo');
|
||
var clientCert = exports.getVariable('Agent.ClientCert');
|
||
if (ca || clientCert) {
|
||
var certConfig = {};
|
||
certConfig.caFile = ca;
|
||
certConfig.certFile = clientCert;
|
||
if (clientCert) {
|
||
var clientCertKey = exports.getVariable('Agent.ClientCertKey');
|
||
var clientCertArchive = exports.getVariable('Agent.ClientCertArchive');
|
||
var clientCertPassword = exports.getVariable('Agent.ClientCertPassword');
|
||
certConfig.keyFile = clientCertKey;
|
||
certConfig.certArchiveFile = clientCertArchive;
|
||
certConfig.passphrase = clientCertPassword;
|
||
}
|
||
return certConfig;
|
||
}
|
||
else {
|
||
return null;
|
||
}
|
||
}
|
||
exports.getHttpCertConfiguration = getHttpCertConfiguration;
|
||
//-----------------------------------------------------
|
||
// Test Publisher
|
||
//-----------------------------------------------------
|
||
var TestPublisher = /** @class */ (function () {
|
||
function TestPublisher(testRunner) {
|
||
this.testRunner = testRunner;
|
||
}
|
||
TestPublisher.prototype.publish = function (resultFiles, mergeResults, platform, config, runTitle, publishRunAttachments, testRunSystem) {
|
||
// Could have used an initializer, but wanted to avoid reordering parameters when converting to strict null checks
|
||
// (A parameter cannot both be optional and have an initializer)
|
||
testRunSystem = testRunSystem || "VSTSTask";
|
||
var properties = {};
|
||
properties['type'] = this.testRunner;
|
||
if (mergeResults) {
|
||
properties['mergeResults'] = mergeResults;
|
||
}
|
||
if (platform) {
|
||
properties['platform'] = platform;
|
||
}
|
||
if (config) {
|
||
properties['config'] = config;
|
||
}
|
||
if (runTitle) {
|
||
properties['runTitle'] = runTitle;
|
||
}
|
||
if (publishRunAttachments) {
|
||
properties['publishRunAttachments'] = publishRunAttachments;
|
||
}
|
||
if (resultFiles) {
|
||
properties['resultFiles'] = Array.isArray(resultFiles) ? resultFiles.join() : resultFiles;
|
||
}
|
||
properties['testRunSystem'] = testRunSystem;
|
||
exports.command('results.publish', properties, '');
|
||
};
|
||
return TestPublisher;
|
||
}());
|
||
exports.TestPublisher = TestPublisher;
|
||
//-----------------------------------------------------
|
||
// Code coverage Publisher
|
||
//-----------------------------------------------------
|
||
var CodeCoveragePublisher = /** @class */ (function () {
|
||
function CodeCoveragePublisher() {
|
||
}
|
||
CodeCoveragePublisher.prototype.publish = function (codeCoverageTool, summaryFileLocation, reportDirectory, additionalCodeCoverageFiles) {
|
||
var properties = {};
|
||
if (codeCoverageTool) {
|
||
properties['codecoveragetool'] = codeCoverageTool;
|
||
}
|
||
if (summaryFileLocation) {
|
||
properties['summaryfile'] = summaryFileLocation;
|
||
}
|
||
if (reportDirectory) {
|
||
properties['reportdirectory'] = reportDirectory;
|
||
}
|
||
if (additionalCodeCoverageFiles) {
|
||
properties['additionalcodecoveragefiles'] = Array.isArray(additionalCodeCoverageFiles) ? additionalCodeCoverageFiles.join() : additionalCodeCoverageFiles;
|
||
}
|
||
exports.command('codecoverage.publish', properties, "");
|
||
};
|
||
return CodeCoveragePublisher;
|
||
}());
|
||
exports.CodeCoveragePublisher = CodeCoveragePublisher;
|
||
//-----------------------------------------------------
|
||
// Code coverage Publisher
|
||
//-----------------------------------------------------
|
||
var CodeCoverageEnabler = /** @class */ (function () {
|
||
function CodeCoverageEnabler(buildTool, ccTool) {
|
||
this.buildTool = buildTool;
|
||
this.ccTool = ccTool;
|
||
}
|
||
CodeCoverageEnabler.prototype.enableCodeCoverage = function (buildProps) {
|
||
buildProps['buildtool'] = this.buildTool;
|
||
buildProps['codecoveragetool'] = this.ccTool;
|
||
exports.command('codecoverage.enable', buildProps, "");
|
||
};
|
||
return CodeCoverageEnabler;
|
||
}());
|
||
exports.CodeCoverageEnabler = CodeCoverageEnabler;
|
||
//-----------------------------------------------------
|
||
// Task Logging Commands
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Upload user interested file as additional log information
|
||
* to the current timeline record.
|
||
*
|
||
* The file shall be available for download along with task logs.
|
||
*
|
||
* @param path Path to the file that should be uploaded.
|
||
* @returns void
|
||
*/
|
||
function uploadFile(path) {
|
||
exports.command("task.uploadfile", null, path);
|
||
}
|
||
exports.uploadFile = uploadFile;
|
||
/**
|
||
* Instruction for the agent to update the PATH environment variable.
|
||
* The specified directory is prepended to the PATH.
|
||
* The updated environment variable will be reflected in subsequent tasks.
|
||
*
|
||
* @param path Local directory path.
|
||
* @returns void
|
||
*/
|
||
function prependPath(path) {
|
||
assertAgent("2.115.0");
|
||
exports.command("task.prependpath", null, path);
|
||
}
|
||
exports.prependPath = prependPath;
|
||
/**
|
||
* Upload and attach summary markdown to current timeline record.
|
||
* This summary shall be added to the build/release summary and
|
||
* not available for download with logs.
|
||
*
|
||
* @param path Local directory path.
|
||
* @returns void
|
||
*/
|
||
function uploadSummary(path) {
|
||
exports.command("task.uploadsummary", null, path);
|
||
}
|
||
exports.uploadSummary = uploadSummary;
|
||
/**
|
||
* Upload and attach attachment to current timeline record.
|
||
* These files are not available for download with logs.
|
||
* These can only be referred to by extensions using the type or name values.
|
||
*
|
||
* @param type Attachment type.
|
||
* @param name Attachment name.
|
||
* @param path Attachment path.
|
||
* @returns void
|
||
*/
|
||
function addAttachment(type, name, path) {
|
||
exports.command("task.addattachment", { "type": type, "name": name }, path);
|
||
}
|
||
exports.addAttachment = addAttachment;
|
||
/**
|
||
* Set an endpoint field with given value.
|
||
* Value updated will be retained in the endpoint for
|
||
* the subsequent tasks that execute within the same job.
|
||
*
|
||
* @param id Endpoint id.
|
||
* @param field FieldType enum of AuthParameter, DataParameter or Url.
|
||
* @param key Key.
|
||
* @param value Value for key or url.
|
||
* @returns void
|
||
*/
|
||
function setEndpoint(id, field, key, value) {
|
||
exports.command("task.setendpoint", { "id": id, "field": FieldType[field].toLowerCase(), "key": key }, value);
|
||
}
|
||
exports.setEndpoint = setEndpoint;
|
||
/**
|
||
* Set progress and current operation for current task.
|
||
*
|
||
* @param percent Percentage of completion.
|
||
* @param currentOperation Current pperation.
|
||
* @returns void
|
||
*/
|
||
function setProgress(percent, currentOperation) {
|
||
exports.command("task.setprogress", { "value": "" + percent }, currentOperation);
|
||
}
|
||
exports.setProgress = setProgress;
|
||
/**
|
||
* Indicates whether to write the logging command directly to the host or to the output pipeline.
|
||
*
|
||
* @param id Timeline record Guid.
|
||
* @param parentId Parent timeline record Guid.
|
||
* @param recordType Record type.
|
||
* @param recordName Record name.
|
||
* @param order Order of timeline record.
|
||
* @param startTime Start time.
|
||
* @param finishTime End time.
|
||
* @param progress Percentage of completion.
|
||
* @param state TaskState enum of Unknown, Initialized, InProgress or Completed.
|
||
* @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
|
||
* @param message current operation
|
||
* @returns void
|
||
*/
|
||
function logDetail(id, message, parentId, recordType, recordName, order, startTime, finishTime, progress, state, result) {
|
||
var properties = {
|
||
"id": id,
|
||
"parentid": parentId,
|
||
"type": recordType,
|
||
"name": recordName,
|
||
"order": order ? order.toString() : undefined,
|
||
"starttime": startTime,
|
||
"finishtime": finishTime,
|
||
"progress": progress ? progress.toString() : undefined,
|
||
"state": state ? TaskState[state] : undefined,
|
||
"result": result ? TaskResult[result] : undefined
|
||
};
|
||
exports.command("task.logdetail", properties, message);
|
||
}
|
||
exports.logDetail = logDetail;
|
||
/**
|
||
* Log error or warning issue to timeline record of current task.
|
||
*
|
||
* @param type IssueType enum of Error or Warning.
|
||
* @param sourcePath Source file location.
|
||
* @param lineNumber Line number.
|
||
* @param columnNumber Column number.
|
||
* @param code Error or warning code.
|
||
* @param message Error or warning message.
|
||
* @returns void
|
||
*/
|
||
function logIssue(type, message, sourcePath, lineNumber, columnNumber, errorCode) {
|
||
var properties = {
|
||
"type": IssueType[type].toLowerCase(),
|
||
"code": errorCode,
|
||
"sourcepath": sourcePath,
|
||
"linenumber": lineNumber ? lineNumber.toString() : undefined,
|
||
"columnnumber": columnNumber ? columnNumber.toString() : undefined,
|
||
};
|
||
exports.command("task.logissue", properties, message);
|
||
}
|
||
exports.logIssue = logIssue;
|
||
//-----------------------------------------------------
|
||
// Artifact Logging Commands
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Upload user interested file as additional log information
|
||
* to the current timeline record.
|
||
*
|
||
* The file shall be available for download along with task logs.
|
||
*
|
||
* @param containerFolder Folder that the file will upload to, folder will be created if needed.
|
||
* @param path Path to the file that should be uploaded.
|
||
* @param name Artifact name.
|
||
* @returns void
|
||
*/
|
||
function uploadArtifact(containerFolder, path, name) {
|
||
exports.command("artifact.upload", { "containerfolder": containerFolder, "artifactname": name }, path);
|
||
}
|
||
exports.uploadArtifact = uploadArtifact;
|
||
/**
|
||
* Create an artifact link, artifact location is required to be
|
||
* a file container path, VC path or UNC share path.
|
||
*
|
||
* The file shall be available for download along with task logs.
|
||
*
|
||
* @param name Artifact name.
|
||
* @param path Path to the file that should be associated.
|
||
* @param artifactType ArtifactType enum of Container, FilePath, VersionControl, GitRef or TfvcLabel.
|
||
* @returns void
|
||
*/
|
||
function associateArtifact(name, path, artifactType) {
|
||
exports.command("artifact.associate", { "type": ArtifactType[artifactType].toLowerCase(), "artifactname": name }, path);
|
||
}
|
||
exports.associateArtifact = associateArtifact;
|
||
//-----------------------------------------------------
|
||
// Build Logging Commands
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Upload user interested log to build’s container “logs\tool” folder.
|
||
*
|
||
* @param path Path to the file that should be uploaded.
|
||
* @returns void
|
||
*/
|
||
function uploadBuildLog(path) {
|
||
exports.command("build.uploadlog", null, path);
|
||
}
|
||
exports.uploadBuildLog = uploadBuildLog;
|
||
/**
|
||
* Update build number for current build.
|
||
*
|
||
* @param value Value to be assigned as the build number.
|
||
* @returns void
|
||
*/
|
||
function updateBuildNumber(value) {
|
||
exports.command("build.updatebuildnumber", null, value);
|
||
}
|
||
exports.updateBuildNumber = updateBuildNumber;
|
||
/**
|
||
* Add a tag for current build.
|
||
*
|
||
* @param value Tag value.
|
||
* @returns void
|
||
*/
|
||
function addBuildTag(value) {
|
||
exports.command("build.addbuildtag", null, value);
|
||
}
|
||
exports.addBuildTag = addBuildTag;
|
||
//-----------------------------------------------------
|
||
// Release Logging Commands
|
||
//-----------------------------------------------------
|
||
/**
|
||
* Update release name for current release.
|
||
*
|
||
* @param value Value to be assigned as the release name.
|
||
* @returns void
|
||
*/
|
||
function updateReleaseName(name) {
|
||
assertAgent("2.132");
|
||
exports.command("release.updatereleasename", null, name);
|
||
}
|
||
exports.updateReleaseName = updateReleaseName;
|
||
//-----------------------------------------------------
|
||
// Tools
|
||
//-----------------------------------------------------
|
||
exports.TaskCommand = tcm.TaskCommand;
|
||
exports.commandFromString = tcm.commandFromString;
|
||
exports.ToolRunner = trm.ToolRunner;
|
||
//-----------------------------------------------------
|
||
// Validation Checks
|
||
//-----------------------------------------------------
|
||
// async await needs generators in node 4.x+
|
||
if (semver.lt(process.versions.node, '4.2.0')) {
|
||
exports.warning('Tasks require a new agent. Upgrade your agent or node to 4.2.0 or later');
|
||
}
|
||
//-------------------------------------------------------------------
|
||
// Populate the vault with sensitive data. Inputs and Endpoints
|
||
//-------------------------------------------------------------------
|
||
// avoid loading twice (overwrites .taskkey)
|
||
if (!global['_vsts_task_lib_loaded']) {
|
||
im._loadData();
|
||
im._exposeProxySettings();
|
||
im._exposeCertSettings();
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/taskcommand.js":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/taskcommand.js ***!
|
||
\**************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.commandFromString = exports.TaskCommand = void 0;
|
||
//
|
||
// Command Format:
|
||
// ##vso[artifact.command key=value;key=value]user message
|
||
//
|
||
// Examples:
|
||
// ##vso[task.progress value=58]
|
||
// ##vso[task.issue type=warning;]This is the user warning message
|
||
//
|
||
var CMD_PREFIX = '##vso[';
|
||
var TaskCommand = /** @class */ (function () {
|
||
function TaskCommand(command, properties, message) {
|
||
if (!command) {
|
||
command = 'missing.command';
|
||
}
|
||
this.command = command;
|
||
this.properties = properties;
|
||
this.message = message;
|
||
}
|
||
TaskCommand.prototype.toString = function () {
|
||
var cmdStr = CMD_PREFIX + this.command;
|
||
if (this.properties && Object.keys(this.properties).length > 0) {
|
||
cmdStr += ' ';
|
||
for (var key in this.properties) {
|
||
if (this.properties.hasOwnProperty(key)) {
|
||
var val = this.properties[key];
|
||
if (val) {
|
||
// safely append the val - avoid blowing up when attempting to
|
||
// call .replace() if message is not a string for some reason
|
||
cmdStr += key + '=' + escape('' + (val || '')) + ';';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
cmdStr += ']';
|
||
// safely append the message - avoid blowing up when attempting to
|
||
// call .replace() if message is not a string for some reason
|
||
var message = '' + (this.message || '');
|
||
cmdStr += escapedata(message);
|
||
return cmdStr;
|
||
};
|
||
return TaskCommand;
|
||
}());
|
||
exports.TaskCommand = TaskCommand;
|
||
function commandFromString(commandLine) {
|
||
var preLen = CMD_PREFIX.length;
|
||
var lbPos = commandLine.indexOf('[');
|
||
var rbPos = commandLine.indexOf(']');
|
||
if (lbPos == -1 || rbPos == -1 || rbPos - lbPos < 3) {
|
||
throw new Error('Invalid command brackets');
|
||
}
|
||
var cmdInfo = commandLine.substring(lbPos + 1, rbPos);
|
||
var spaceIdx = cmdInfo.indexOf(' ');
|
||
var command = cmdInfo;
|
||
var properties = {};
|
||
if (spaceIdx > 0) {
|
||
command = cmdInfo.trim().substring(0, spaceIdx);
|
||
var propSection = cmdInfo.trim().substring(spaceIdx + 1);
|
||
var propLines = propSection.split(';');
|
||
propLines.forEach(function (propLine) {
|
||
propLine = propLine.trim();
|
||
if (propLine.length > 0) {
|
||
var eqIndex = propLine.indexOf('=');
|
||
if (eqIndex == -1) {
|
||
throw new Error('Invalid property: ' + propLine);
|
||
}
|
||
var key = propLine.substring(0, eqIndex);
|
||
var val = propLine.substring(eqIndex + 1);
|
||
properties[key] = unescape(val);
|
||
}
|
||
});
|
||
}
|
||
var msg = unescapedata(commandLine.substring(rbPos + 1));
|
||
var cmd = new TaskCommand(command, properties, msg);
|
||
return cmd;
|
||
}
|
||
exports.commandFromString = commandFromString;
|
||
function escapedata(s) {
|
||
return s.replace(/%/g, '%AZP25')
|
||
.replace(/\r/g, '%0D')
|
||
.replace(/\n/g, '%0A');
|
||
}
|
||
function unescapedata(s) {
|
||
return s.replace(/%0D/g, '\r')
|
||
.replace(/%0A/g, '\n')
|
||
.replace(/%AZP25/g, '%');
|
||
}
|
||
function escape(s) {
|
||
return s.replace(/%/g, '%AZP25')
|
||
.replace(/\r/g, '%0D')
|
||
.replace(/\n/g, '%0A')
|
||
.replace(/]/g, '%5D')
|
||
.replace(/;/g, '%3B');
|
||
}
|
||
function unescape(s) {
|
||
return s.replace(/%0D/g, '\r')
|
||
.replace(/%0A/g, '\n')
|
||
.replace(/%5D/g, ']')
|
||
.replace(/%3B/g, ';')
|
||
.replace(/%AZP25/g, '%');
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/toolrunner.js":
|
||
/*!*************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/toolrunner.js ***!
|
||
\*************************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __extends = (this && this.__extends) || (function () {
|
||
var extendStatics = function (d, b) {
|
||
extendStatics = Object.setPrototypeOf ||
|
||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||
return extendStatics(d, b);
|
||
};
|
||
return function (d, b) {
|
||
extendStatics(d, b);
|
||
function __() { this.constructor = d; }
|
||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||
};
|
||
})();
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.ToolRunner = void 0;
|
||
var Q = __webpack_require__(/*! q */ "./node_modules/q/q.js");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var events = __webpack_require__(/*! events */ "events");
|
||
var child = __webpack_require__(/*! child_process */ "child_process");
|
||
var im = __webpack_require__(/*! ./internal */ "./node_modules/azure-pipelines-task-lib/internal.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var ToolRunner = /** @class */ (function (_super) {
|
||
__extends(ToolRunner, _super);
|
||
function ToolRunner(toolPath) {
|
||
var _this = _super.call(this) || this;
|
||
_this.cmdSpecialChars = [' ', '\t', '&', '(', ')', '[', ']', '{', '}', '^', '=', ';', '!', '\'', '+', ',', '`', '~', '|', '<', '>', '"'];
|
||
if (!toolPath) {
|
||
throw new Error('Parameter \'toolPath\' cannot be null or empty.');
|
||
}
|
||
_this.toolPath = im._which(toolPath, true);
|
||
_this.args = [];
|
||
_this._debug('toolRunner toolPath: ' + toolPath);
|
||
return _this;
|
||
}
|
||
ToolRunner.prototype._debug = function (message) {
|
||
this.emit('debug', message);
|
||
};
|
||
ToolRunner.prototype._argStringToArray = function (argString) {
|
||
var args = [];
|
||
var inQuotes = false;
|
||
var escaped = false;
|
||
var lastCharWasSpace = true;
|
||
var arg = '';
|
||
var append = function (c) {
|
||
// we only escape double quotes.
|
||
if (escaped) {
|
||
if (c !== '"') {
|
||
arg += '\\';
|
||
}
|
||
else {
|
||
arg.slice(0, -1);
|
||
}
|
||
}
|
||
arg += c;
|
||
escaped = false;
|
||
};
|
||
for (var i = 0; i < argString.length; i++) {
|
||
var c = argString.charAt(i);
|
||
if (c === ' ' && !inQuotes) {
|
||
if (!lastCharWasSpace) {
|
||
args.push(arg);
|
||
arg = '';
|
||
}
|
||
lastCharWasSpace = true;
|
||
continue;
|
||
}
|
||
else {
|
||
lastCharWasSpace = false;
|
||
}
|
||
if (c === '"') {
|
||
if (!escaped) {
|
||
inQuotes = !inQuotes;
|
||
}
|
||
else {
|
||
append(c);
|
||
}
|
||
continue;
|
||
}
|
||
if (c === "\\" && escaped) {
|
||
append(c);
|
||
continue;
|
||
}
|
||
if (c === "\\" && inQuotes) {
|
||
escaped = true;
|
||
continue;
|
||
}
|
||
append(c);
|
||
lastCharWasSpace = false;
|
||
}
|
||
if (!lastCharWasSpace) {
|
||
args.push(arg.trim());
|
||
}
|
||
return args;
|
||
};
|
||
ToolRunner.prototype._getCommandString = function (options, noPrefix) {
|
||
var _this = this;
|
||
var toolPath = this._getSpawnFileName();
|
||
var args = this._getSpawnArgs(options);
|
||
var cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
|
||
var commandParts = [];
|
||
if (process.platform == 'win32') {
|
||
// Windows + cmd file
|
||
if (this._isCmdFile()) {
|
||
commandParts.push(toolPath);
|
||
commandParts = commandParts.concat(args);
|
||
}
|
||
// Windows + verbatim
|
||
else if (options.windowsVerbatimArguments) {
|
||
commandParts.push("\"" + toolPath + "\"");
|
||
commandParts = commandParts.concat(args);
|
||
}
|
||
else if (options.shell) {
|
||
commandParts.push(this._windowsQuoteCmdArg(toolPath));
|
||
commandParts = commandParts.concat(args);
|
||
}
|
||
// Windows (regular)
|
||
else {
|
||
commandParts.push(this._windowsQuoteCmdArg(toolPath));
|
||
commandParts = commandParts.concat(args.map(function (arg) { return _this._windowsQuoteCmdArg(arg); }));
|
||
}
|
||
}
|
||
else {
|
||
// OSX/Linux - this can likely be improved with some form of quoting.
|
||
// creating processes on Unix is fundamentally different than Windows.
|
||
// on Unix, execvp() takes an arg array.
|
||
commandParts.push(toolPath);
|
||
commandParts = commandParts.concat(args);
|
||
}
|
||
cmd += commandParts.join(' ');
|
||
// append second tool
|
||
if (this.pipeOutputToTool) {
|
||
cmd += ' | ' + this.pipeOutputToTool._getCommandString(options, /*noPrefix:*/ true);
|
||
}
|
||
return cmd;
|
||
};
|
||
ToolRunner.prototype._processLineBuffer = function (data, strBuffer, onLine) {
|
||
try {
|
||
var s = strBuffer + data.toString();
|
||
var n = s.indexOf(os.EOL);
|
||
while (n > -1) {
|
||
var line = s.substring(0, n);
|
||
onLine(line);
|
||
// the rest of the string ...
|
||
s = s.substring(n + os.EOL.length);
|
||
n = s.indexOf(os.EOL);
|
||
}
|
||
strBuffer = s;
|
||
}
|
||
catch (err) {
|
||
// streaming lines to console is best effort. Don't fail a build.
|
||
this._debug('error processing line');
|
||
}
|
||
};
|
||
/**
|
||
* Wraps an arg string with specified char if it's not already wrapped
|
||
* @returns {string} Arg wrapped with specified char
|
||
* @param {string} arg Input argument string
|
||
* @param {string} wrapChar A char input string should be wrapped with
|
||
*/
|
||
ToolRunner.prototype._wrapArg = function (arg, wrapChar) {
|
||
if (!this._isWrapped(arg, wrapChar)) {
|
||
return "" + wrapChar + arg + wrapChar;
|
||
}
|
||
return arg;
|
||
};
|
||
/**
|
||
* Unwraps an arg string wrapped with specified char
|
||
* @param arg Arg wrapped with specified char
|
||
* @param wrapChar A char to be removed
|
||
*/
|
||
ToolRunner.prototype._unwrapArg = function (arg, wrapChar) {
|
||
if (this._isWrapped(arg, wrapChar)) {
|
||
var pattern = new RegExp("(^\\\\?" + wrapChar + ")|(\\\\?" + wrapChar + "$)", 'g');
|
||
return arg.trim().replace(pattern, '');
|
||
}
|
||
return arg;
|
||
};
|
||
/**
|
||
* Determine if arg string is wrapped with specified char
|
||
* @param arg Input arg string
|
||
*/
|
||
ToolRunner.prototype._isWrapped = function (arg, wrapChar) {
|
||
var pattern = new RegExp("^\\\\?" + wrapChar + ".+\\\\?" + wrapChar + "$");
|
||
return pattern.test(arg.trim());
|
||
};
|
||
ToolRunner.prototype._getSpawnFileName = function (options) {
|
||
if (process.platform == 'win32') {
|
||
if (this._isCmdFile()) {
|
||
return process.env['COMSPEC'] || 'cmd.exe';
|
||
}
|
||
}
|
||
if (options && options.shell) {
|
||
return this._wrapArg(this.toolPath, '"');
|
||
}
|
||
return this.toolPath;
|
||
};
|
||
ToolRunner.prototype._getSpawnArgs = function (options) {
|
||
var _this = this;
|
||
if (process.platform == 'win32') {
|
||
if (this._isCmdFile()) {
|
||
var argline = "/D /S /C \"" + this._windowsQuoteCmdArg(this.toolPath);
|
||
for (var i = 0; i < this.args.length; i++) {
|
||
argline += ' ';
|
||
argline += options.windowsVerbatimArguments ? this.args[i] : this._windowsQuoteCmdArg(this.args[i]);
|
||
}
|
||
argline += '"';
|
||
return [argline];
|
||
}
|
||
if (options.windowsVerbatimArguments) {
|
||
// note, in Node 6.x options.argv0 can be used instead of overriding args.slice and args.unshift.
|
||
// for more details, refer to https://github.com/nodejs/node/blob/v6.x/lib/child_process.js
|
||
var args_1 = this.args.slice(0); // copy the array
|
||
// override slice to prevent Node from creating a copy of the arg array.
|
||
// we need Node to use the "unshift" override below.
|
||
args_1.slice = function () {
|
||
if (arguments.length != 1 || arguments[0] != 0) {
|
||
throw new Error('Unexpected arguments passed to args.slice when windowsVerbatimArguments flag is set.');
|
||
}
|
||
return args_1;
|
||
};
|
||
// override unshift
|
||
//
|
||
// when using the windowsVerbatimArguments option, Node does not quote the tool path when building
|
||
// the cmdline parameter for the win32 function CreateProcess(). an unquoted space in the tool path
|
||
// causes problems for tools when attempting to parse their own command line args. tools typically
|
||
// assume their arguments begin after arg 0.
|
||
//
|
||
// by hijacking unshift, we can quote the tool path when it pushed onto the args array. Node builds
|
||
// the cmdline parameter from the args array.
|
||
//
|
||
// note, we can't simply pass a quoted tool path to Node for multiple reasons:
|
||
// 1) Node verifies the file exists (calls win32 function GetFileAttributesW) and the check returns
|
||
// false if the path is quoted.
|
||
// 2) Node passes the tool path as the application parameter to CreateProcess, which expects the
|
||
// path to be unquoted.
|
||
//
|
||
// also note, in addition to the tool path being embedded within the cmdline parameter, Node also
|
||
// passes the tool path to CreateProcess via the application parameter (optional parameter). when
|
||
// present, Windows uses the application parameter to determine which file to run, instead of
|
||
// interpreting the file from the cmdline parameter.
|
||
args_1.unshift = function () {
|
||
if (arguments.length != 1) {
|
||
throw new Error('Unexpected arguments passed to args.unshift when windowsVerbatimArguments flag is set.');
|
||
}
|
||
return Array.prototype.unshift.call(args_1, "\"" + arguments[0] + "\""); // quote the file name
|
||
};
|
||
return args_1;
|
||
}
|
||
else if (options.shell) {
|
||
var args = [];
|
||
for (var _i = 0, _a = this.args; _i < _a.length; _i++) {
|
||
var arg = _a[_i];
|
||
if (this._needQuotesForCmd(arg, '%')) {
|
||
args.push(this._wrapArg(arg, '"'));
|
||
}
|
||
else {
|
||
args.push(arg);
|
||
}
|
||
}
|
||
return args;
|
||
}
|
||
}
|
||
else if (options.shell) {
|
||
return this.args.map(function (arg) {
|
||
if (_this._isWrapped(arg, "'")) {
|
||
return arg;
|
||
}
|
||
// remove wrapping double quotes to avoid escaping
|
||
arg = _this._unwrapArg(arg, '"');
|
||
arg = _this._escapeChar(arg, '"');
|
||
return _this._wrapArg(arg, '"');
|
||
});
|
||
}
|
||
return this.args;
|
||
};
|
||
/**
|
||
* Escape specified character.
|
||
* @param arg String to escape char in
|
||
* @param charToEscape Char should be escaped
|
||
*/
|
||
ToolRunner.prototype._escapeChar = function (arg, charToEscape) {
|
||
var escChar = "\\";
|
||
var output = '';
|
||
var charIsEscaped = false;
|
||
for (var _i = 0, arg_1 = arg; _i < arg_1.length; _i++) {
|
||
var char = arg_1[_i];
|
||
if (char === charToEscape && !charIsEscaped) {
|
||
output += escChar + char;
|
||
}
|
||
else {
|
||
output += char;
|
||
}
|
||
charIsEscaped = char === escChar && !charIsEscaped;
|
||
}
|
||
return output;
|
||
};
|
||
ToolRunner.prototype._isCmdFile = function () {
|
||
var upperToolPath = this.toolPath.toUpperCase();
|
||
return im._endsWith(upperToolPath, '.CMD') || im._endsWith(upperToolPath, '.BAT');
|
||
};
|
||
/**
|
||
* Determine whether the cmd arg needs to be quoted. Returns true if arg contains any of special chars array.
|
||
* @param arg The cmd command arg.
|
||
* @param additionalChars Additional chars which should be also checked.
|
||
*/
|
||
ToolRunner.prototype._needQuotesForCmd = function (arg, additionalChars) {
|
||
var specialChars = this.cmdSpecialChars;
|
||
if (additionalChars) {
|
||
specialChars = this.cmdSpecialChars.concat(additionalChars);
|
||
}
|
||
var _loop_1 = function (char) {
|
||
if (specialChars.some(function (x) { return x === char; })) {
|
||
return { value: true };
|
||
}
|
||
};
|
||
for (var _i = 0, arg_2 = arg; _i < arg_2.length; _i++) {
|
||
var char = arg_2[_i];
|
||
var state_1 = _loop_1(char);
|
||
if (typeof state_1 === "object")
|
||
return state_1.value;
|
||
}
|
||
return false;
|
||
};
|
||
ToolRunner.prototype._windowsQuoteCmdArg = function (arg) {
|
||
// for .exe, apply the normal quoting rules that libuv applies
|
||
if (!this._isCmdFile()) {
|
||
return this._uv_quote_cmd_arg(arg);
|
||
}
|
||
// otherwise apply quoting rules specific to the cmd.exe command line parser.
|
||
// the libuv rules are generic and are not designed specifically for cmd.exe
|
||
// command line parser.
|
||
//
|
||
// for a detailed description of the cmd.exe command line parser, refer to
|
||
// http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
|
||
// need quotes for empty arg
|
||
if (!arg) {
|
||
return '""';
|
||
}
|
||
// determine whether the arg needs to be quoted
|
||
var needsQuotes = this._needQuotesForCmd(arg);
|
||
// short-circuit if quotes not needed
|
||
if (!needsQuotes) {
|
||
return arg;
|
||
}
|
||
// the following quoting rules are very similar to the rules that by libuv applies.
|
||
//
|
||
// 1) wrap the string in quotes
|
||
//
|
||
// 2) double-up quotes - i.e. " => ""
|
||
//
|
||
// this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
|
||
// doesn't work well with a cmd.exe command line.
|
||
//
|
||
// note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
|
||
// for example, the command line:
|
||
// foo.exe "myarg:""my val"""
|
||
// is parsed by a .NET console app into an arg array:
|
||
// [ "myarg:\"my val\"" ]
|
||
// which is the same end result when applying libuv quoting rules. although the actual
|
||
// command line from libuv quoting rules would look like:
|
||
// foo.exe "myarg:\"my val\""
|
||
//
|
||
// 3) double-up slashes that preceed a quote,
|
||
// e.g. hello \world => "hello \world"
|
||
// hello\"world => "hello\\""world"
|
||
// hello\\"world => "hello\\\\""world"
|
||
// hello world\ => "hello world\\"
|
||
//
|
||
// technically this is not required for a cmd.exe command line, or the batch argument parser.
|
||
// the reasons for including this as a .cmd quoting rule are:
|
||
//
|
||
// a) this is optimized for the scenario where the argument is passed from the .cmd file to an
|
||
// external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
|
||
//
|
||
// b) it's what we've been doing previously (by deferring to node default behavior) and we
|
||
// haven't heard any complaints about that aspect.
|
||
//
|
||
// note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
|
||
// escaped when used on the command line directly - even though within a .cmd file % can be escaped
|
||
// by using %%.
|
||
//
|
||
// the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
|
||
// the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
|
||
//
|
||
// one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
|
||
// often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
|
||
// variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
|
||
// to an external program.
|
||
//
|
||
// an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
|
||
// % can be escaped within a .cmd file.
|
||
var reverse = '"';
|
||
var quote_hit = true;
|
||
for (var i = arg.length; i > 0; i--) { // walk the string in reverse
|
||
reverse += arg[i - 1];
|
||
if (quote_hit && arg[i - 1] == '\\') {
|
||
reverse += '\\'; // double the slash
|
||
}
|
||
else if (arg[i - 1] == '"') {
|
||
quote_hit = true;
|
||
reverse += '"'; // double the quote
|
||
}
|
||
else {
|
||
quote_hit = false;
|
||
}
|
||
}
|
||
reverse += '"';
|
||
return reverse.split('').reverse().join('');
|
||
};
|
||
ToolRunner.prototype._uv_quote_cmd_arg = function (arg) {
|
||
// Tool runner wraps child_process.spawn() and needs to apply the same quoting as
|
||
// Node in certain cases where the undocumented spawn option windowsVerbatimArguments
|
||
// is used.
|
||
//
|
||
// Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
|
||
// see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
|
||
// pasting copyright notice from Node within this function:
|
||
//
|
||
// Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
// of this software and associated documentation files (the "Software"), to
|
||
// deal in the Software without restriction, including without limitation the
|
||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||
// sell copies of the Software, and to permit persons to whom the Software is
|
||
// furnished to do so, subject to the following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included in
|
||
// all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||
// IN THE SOFTWARE.
|
||
if (!arg) {
|
||
// Need double quotation for empty argument
|
||
return '""';
|
||
}
|
||
if (arg.indexOf(' ') < 0 && arg.indexOf('\t') < 0 && arg.indexOf('"') < 0) {
|
||
// No quotation needed
|
||
return arg;
|
||
}
|
||
if (arg.indexOf('"') < 0 && arg.indexOf('\\') < 0) {
|
||
// No embedded double quotes or backslashes, so I can just wrap
|
||
// quote marks around the whole thing.
|
||
return "\"" + arg + "\"";
|
||
}
|
||
// Expected input/output:
|
||
// input : hello"world
|
||
// output: "hello\"world"
|
||
// input : hello""world
|
||
// output: "hello\"\"world"
|
||
// input : hello\world
|
||
// output: hello\world
|
||
// input : hello\\world
|
||
// output: hello\\world
|
||
// input : hello\"world
|
||
// output: "hello\\\"world"
|
||
// input : hello\\"world
|
||
// output: "hello\\\\\"world"
|
||
// input : hello world\
|
||
// output: "hello world\\" - note the comment in libuv actually reads "hello world\"
|
||
// but it appears the comment is wrong, it should be "hello world\\"
|
||
var reverse = '"';
|
||
var quote_hit = true;
|
||
for (var i = arg.length; i > 0; i--) { // walk the string in reverse
|
||
reverse += arg[i - 1];
|
||
if (quote_hit && arg[i - 1] == '\\') {
|
||
reverse += '\\';
|
||
}
|
||
else if (arg[i - 1] == '"') {
|
||
quote_hit = true;
|
||
reverse += '\\';
|
||
}
|
||
else {
|
||
quote_hit = false;
|
||
}
|
||
}
|
||
reverse += '"';
|
||
return reverse.split('').reverse().join('');
|
||
};
|
||
ToolRunner.prototype._cloneExecOptions = function (options) {
|
||
options = options || {};
|
||
var result = {
|
||
cwd: options.cwd || process.cwd(),
|
||
env: options.env || process.env,
|
||
silent: options.silent || false,
|
||
failOnStdErr: options.failOnStdErr || false,
|
||
ignoreReturnCode: options.ignoreReturnCode || false,
|
||
windowsVerbatimArguments: options.windowsVerbatimArguments || false,
|
||
shell: options.shell || false
|
||
};
|
||
result.outStream = options.outStream || process.stdout;
|
||
result.errStream = options.errStream || process.stderr;
|
||
return result;
|
||
};
|
||
ToolRunner.prototype._getSpawnOptions = function (options) {
|
||
options = options || {};
|
||
var result = {};
|
||
result.cwd = options.cwd;
|
||
result.env = options.env;
|
||
result.shell = options.shell;
|
||
result['windowsVerbatimArguments'] = options.windowsVerbatimArguments || this._isCmdFile();
|
||
return result;
|
||
};
|
||
ToolRunner.prototype._getSpawnSyncOptions = function (options) {
|
||
var result = {};
|
||
result.cwd = options.cwd;
|
||
result.env = options.env;
|
||
result.shell = options.shell;
|
||
result['windowsVerbatimArguments'] = options.windowsVerbatimArguments || this._isCmdFile();
|
||
return result;
|
||
};
|
||
ToolRunner.prototype.execWithPiping = function (pipeOutputToTool, options) {
|
||
var _this = this;
|
||
var _a, _b, _c, _d;
|
||
var defer = Q.defer();
|
||
this._debug('exec tool: ' + this.toolPath);
|
||
this._debug('arguments:');
|
||
this.args.forEach(function (arg) {
|
||
_this._debug(' ' + arg);
|
||
});
|
||
var success = true;
|
||
var optionsNonNull = this._cloneExecOptions(options);
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
||
}
|
||
var cp;
|
||
var toolPath = pipeOutputToTool.toolPath;
|
||
var toolPathFirst;
|
||
var successFirst = true;
|
||
var returnCodeFirst;
|
||
var fileStream;
|
||
var waitingEvents = 0; // number of process or stream events we are waiting on to complete
|
||
var returnCode = 0;
|
||
var error;
|
||
toolPathFirst = this.toolPath;
|
||
// Following node documentation example from this link on how to pipe output of one process to another
|
||
// https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options
|
||
//start the child process for both tools
|
||
waitingEvents++;
|
||
var cpFirst = child.spawn(this._getSpawnFileName(optionsNonNull), this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(optionsNonNull));
|
||
waitingEvents++;
|
||
cp = child.spawn(pipeOutputToTool._getSpawnFileName(optionsNonNull), pipeOutputToTool._getSpawnArgs(optionsNonNull), pipeOutputToTool._getSpawnOptions(optionsNonNull));
|
||
fileStream = this.pipeOutputToFile ? fs.createWriteStream(this.pipeOutputToFile) : null;
|
||
if (fileStream) {
|
||
waitingEvents++;
|
||
fileStream.on('finish', function () {
|
||
waitingEvents--; //file write is complete
|
||
fileStream = null;
|
||
if (waitingEvents == 0) {
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(returnCode);
|
||
}
|
||
}
|
||
});
|
||
fileStream.on('error', function (err) {
|
||
waitingEvents--; //there were errors writing to the file, write is done
|
||
_this._debug("Failed to pipe output of " + toolPathFirst + " to file " + _this.pipeOutputToFile + ". Error = " + err);
|
||
fileStream = null;
|
||
if (waitingEvents == 0) {
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(returnCode);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
//pipe stdout of first tool to stdin of second tool
|
||
(_a = cpFirst.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) {
|
||
var _a;
|
||
try {
|
||
if (fileStream) {
|
||
fileStream.write(data);
|
||
}
|
||
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.write(data);
|
||
}
|
||
catch (err) {
|
||
_this._debug('Failed to pipe output of ' + toolPathFirst + ' to ' + toolPath);
|
||
_this._debug(toolPath + ' might have exited due to errors prematurely. Verify the arguments passed are valid.');
|
||
}
|
||
});
|
||
(_b = cpFirst.stderr) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
||
if (fileStream) {
|
||
fileStream.write(data);
|
||
}
|
||
successFirst = !optionsNonNull.failOnStdErr;
|
||
if (!optionsNonNull.silent) {
|
||
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
||
s.write(data);
|
||
}
|
||
});
|
||
cpFirst.on('error', function (err) {
|
||
var _a;
|
||
waitingEvents--; //first process is complete with errors
|
||
if (fileStream) {
|
||
fileStream.end();
|
||
}
|
||
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.end();
|
||
error = new Error(toolPathFirst + ' failed. ' + err.message);
|
||
if (waitingEvents == 0) {
|
||
defer.reject(error);
|
||
}
|
||
});
|
||
cpFirst.on('close', function (code, signal) {
|
||
var _a;
|
||
waitingEvents--; //first process is complete
|
||
if (code != 0 && !optionsNonNull.ignoreReturnCode) {
|
||
successFirst = false;
|
||
returnCodeFirst = code;
|
||
returnCode = returnCodeFirst;
|
||
}
|
||
_this._debug('success of first tool:' + successFirst);
|
||
if (fileStream) {
|
||
fileStream.end();
|
||
}
|
||
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.end();
|
||
if (waitingEvents == 0) {
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(returnCode);
|
||
}
|
||
}
|
||
});
|
||
var stdbuffer = '';
|
||
(_c = cp.stdout) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
||
_this.emit('stdout', data);
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(data);
|
||
}
|
||
_this._processLineBuffer(data, stdbuffer, function (line) {
|
||
_this.emit('stdline', line);
|
||
});
|
||
});
|
||
var errbuffer = '';
|
||
(_d = cp.stderr) === null || _d === void 0 ? void 0 : _d.on('data', function (data) {
|
||
_this.emit('stderr', data);
|
||
success = !optionsNonNull.failOnStdErr;
|
||
if (!optionsNonNull.silent) {
|
||
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
||
s.write(data);
|
||
}
|
||
_this._processLineBuffer(data, errbuffer, function (line) {
|
||
_this.emit('errline', line);
|
||
});
|
||
});
|
||
cp.on('error', function (err) {
|
||
waitingEvents--; //process is done with errors
|
||
error = new Error(toolPath + ' failed. ' + err.message);
|
||
if (waitingEvents == 0) {
|
||
defer.reject(error);
|
||
}
|
||
});
|
||
cp.on('close', function (code, signal) {
|
||
waitingEvents--; //process is complete
|
||
_this._debug('rc:' + code);
|
||
returnCode = code;
|
||
if (stdbuffer.length > 0) {
|
||
_this.emit('stdline', stdbuffer);
|
||
}
|
||
if (errbuffer.length > 0) {
|
||
_this.emit('errline', errbuffer);
|
||
}
|
||
if (code != 0 && !optionsNonNull.ignoreReturnCode) {
|
||
success = false;
|
||
}
|
||
_this._debug('success:' + success);
|
||
if (!successFirst) { //in the case output is piped to another tool, check exit code of both tools
|
||
error = new Error(toolPathFirst + ' failed with return code: ' + returnCodeFirst);
|
||
}
|
||
else if (!success) {
|
||
error = new Error(toolPath + ' failed with return code: ' + code);
|
||
}
|
||
if (waitingEvents == 0) {
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(returnCode);
|
||
}
|
||
}
|
||
});
|
||
return defer.promise;
|
||
};
|
||
/**
|
||
* Add argument
|
||
* Append an argument or an array of arguments
|
||
* returns ToolRunner for chaining
|
||
*
|
||
* @param val string cmdline or array of strings
|
||
* @returns ToolRunner
|
||
*/
|
||
ToolRunner.prototype.arg = function (val) {
|
||
if (!val) {
|
||
return this;
|
||
}
|
||
if (val instanceof Array) {
|
||
this._debug(this.toolPath + ' arg: ' + JSON.stringify(val));
|
||
this.args = this.args.concat(val);
|
||
}
|
||
else if (typeof (val) === 'string') {
|
||
this._debug(this.toolPath + ' arg: ' + val);
|
||
this.args = this.args.concat(val.trim());
|
||
}
|
||
return this;
|
||
};
|
||
/**
|
||
* Parses an argument line into one or more arguments
|
||
* e.g. .line('"arg one" two -z') is equivalent to .arg(['arg one', 'two', '-z'])
|
||
* returns ToolRunner for chaining
|
||
*
|
||
* @param val string argument line
|
||
* @returns ToolRunner
|
||
*/
|
||
ToolRunner.prototype.line = function (val) {
|
||
if (!val) {
|
||
return this;
|
||
}
|
||
this._debug(this.toolPath + ' arg: ' + val);
|
||
this.args = this.args.concat(this._argStringToArray(val));
|
||
return this;
|
||
};
|
||
/**
|
||
* Add argument(s) if a condition is met
|
||
* Wraps arg(). See arg for details
|
||
* returns ToolRunner for chaining
|
||
*
|
||
* @param condition boolean condition
|
||
* @param val string cmdline or array of strings
|
||
* @returns ToolRunner
|
||
*/
|
||
ToolRunner.prototype.argIf = function (condition, val) {
|
||
if (condition) {
|
||
this.arg(val);
|
||
}
|
||
return this;
|
||
};
|
||
/**
|
||
* Pipe output of exec() to another tool
|
||
* @param tool
|
||
* @param file optional filename to additionally stream the output to.
|
||
* @returns {ToolRunner}
|
||
*/
|
||
ToolRunner.prototype.pipeExecOutputToTool = function (tool, file) {
|
||
this.pipeOutputToTool = tool;
|
||
this.pipeOutputToFile = file;
|
||
return this;
|
||
};
|
||
/**
|
||
* Exec a tool.
|
||
* Output will be streamed to the live console.
|
||
* Returns promise with return code
|
||
*
|
||
* @param tool path to tool to exec
|
||
* @param options optional exec options. See IExecOptions
|
||
* @returns number
|
||
*/
|
||
ToolRunner.prototype.exec = function (options) {
|
||
var _this = this;
|
||
var _a, _b, _c;
|
||
if (this.pipeOutputToTool) {
|
||
return this.execWithPiping(this.pipeOutputToTool, options);
|
||
}
|
||
var defer = Q.defer();
|
||
this._debug('exec tool: ' + this.toolPath);
|
||
this._debug('arguments:');
|
||
this.args.forEach(function (arg) {
|
||
_this._debug(' ' + arg);
|
||
});
|
||
var optionsNonNull = this._cloneExecOptions(options);
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
||
}
|
||
var state = new ExecState(optionsNonNull, this.toolPath);
|
||
state.on('debug', function (message) {
|
||
_this._debug(message);
|
||
});
|
||
var cp = child.spawn(this._getSpawnFileName(options), this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(options));
|
||
this.childProcess = cp;
|
||
// it is possible for the child process to end its last line without a new line.
|
||
// because stdout is buffered, this causes the last line to not get sent to the parent
|
||
// stream. Adding this event forces a flush before the child streams are closed.
|
||
(_a = cp.stdout) === null || _a === void 0 ? void 0 : _a.on('finish', function () {
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(os.EOL);
|
||
}
|
||
});
|
||
var stdbuffer = '';
|
||
(_b = cp.stdout) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
||
_this.emit('stdout', data);
|
||
if (!optionsNonNull.silent) {
|
||
optionsNonNull.outStream.write(data);
|
||
}
|
||
_this._processLineBuffer(data, stdbuffer, function (line) {
|
||
_this.emit('stdline', line);
|
||
});
|
||
});
|
||
var errbuffer = '';
|
||
(_c = cp.stderr) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
||
state.processStderr = true;
|
||
_this.emit('stderr', data);
|
||
if (!optionsNonNull.silent) {
|
||
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
||
s.write(data);
|
||
}
|
||
_this._processLineBuffer(data, errbuffer, function (line) {
|
||
_this.emit('errline', line);
|
||
});
|
||
});
|
||
cp.on('error', function (err) {
|
||
state.processError = err.message;
|
||
state.processExited = true;
|
||
state.processClosed = true;
|
||
state.CheckComplete();
|
||
});
|
||
cp.on('exit', function (code, signal) {
|
||
state.processExitCode = code;
|
||
state.processExited = true;
|
||
_this._debug("Exit code " + code + " received from tool '" + _this.toolPath + "'");
|
||
state.CheckComplete();
|
||
});
|
||
cp.on('close', function (code, signal) {
|
||
state.processExitCode = code;
|
||
state.processExited = true;
|
||
state.processClosed = true;
|
||
_this._debug("STDIO streams have closed for tool '" + _this.toolPath + "'");
|
||
state.CheckComplete();
|
||
});
|
||
state.on('done', function (error, exitCode) {
|
||
if (stdbuffer.length > 0) {
|
||
_this.emit('stdline', stdbuffer);
|
||
}
|
||
if (errbuffer.length > 0) {
|
||
_this.emit('errline', errbuffer);
|
||
}
|
||
cp.removeAllListeners();
|
||
if (error) {
|
||
defer.reject(error);
|
||
}
|
||
else {
|
||
defer.resolve(exitCode);
|
||
}
|
||
});
|
||
return defer.promise;
|
||
};
|
||
/**
|
||
* Exec a tool synchronously.
|
||
* Output will be *not* be streamed to the live console. It will be returned after execution is complete.
|
||
* Appropriate for short running tools
|
||
* Returns IExecSyncResult with output and return code
|
||
*
|
||
* @param tool path to tool to exec
|
||
* @param options optional exec options. See IExecSyncOptions
|
||
* @returns IExecSyncResult
|
||
*/
|
||
ToolRunner.prototype.execSync = function (options) {
|
||
var _this = this;
|
||
this._debug('exec tool: ' + this.toolPath);
|
||
this._debug('arguments:');
|
||
this.args.forEach(function (arg) {
|
||
_this._debug(' ' + arg);
|
||
});
|
||
var success = true;
|
||
options = this._cloneExecOptions(options);
|
||
if (!options.silent) {
|
||
options.outStream.write(this._getCommandString(options) + os.EOL);
|
||
}
|
||
var r = child.spawnSync(this._getSpawnFileName(options), this._getSpawnArgs(options), this._getSpawnSyncOptions(options));
|
||
if (!options.silent && r.stdout && r.stdout.length > 0) {
|
||
options.outStream.write(r.stdout);
|
||
}
|
||
if (!options.silent && r.stderr && r.stderr.length > 0) {
|
||
options.errStream.write(r.stderr);
|
||
}
|
||
var res = { code: r.status, error: r.error };
|
||
res.stdout = (r.stdout) ? r.stdout.toString() : '';
|
||
res.stderr = (r.stderr) ? r.stderr.toString() : '';
|
||
return res;
|
||
};
|
||
/**
|
||
* Used to close child process by sending SIGNINT signal.
|
||
* It allows executed script to have some additional logic on SIGINT, before exiting.
|
||
*/
|
||
ToolRunner.prototype.killChildProcess = function () {
|
||
if (this.childProcess) {
|
||
this.childProcess.kill();
|
||
}
|
||
};
|
||
return ToolRunner;
|
||
}(events.EventEmitter));
|
||
exports.ToolRunner = ToolRunner;
|
||
var ExecState = /** @class */ (function (_super) {
|
||
__extends(ExecState, _super);
|
||
function ExecState(options, toolPath) {
|
||
var _this = _super.call(this) || this;
|
||
_this.delay = 10000; // 10 seconds
|
||
_this.timeout = null;
|
||
if (!toolPath) {
|
||
throw new Error('toolPath must not be empty');
|
||
}
|
||
_this.options = options;
|
||
_this.toolPath = toolPath;
|
||
var delay = process.env['TASKLIB_TEST_TOOLRUNNER_EXITDELAY'];
|
||
if (delay) {
|
||
_this.delay = parseInt(delay);
|
||
}
|
||
return _this;
|
||
}
|
||
ExecState.prototype.CheckComplete = function () {
|
||
if (this.done) {
|
||
return;
|
||
}
|
||
if (this.processClosed) {
|
||
this._setResult();
|
||
}
|
||
else if (this.processExited) {
|
||
this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this);
|
||
}
|
||
};
|
||
ExecState.prototype._debug = function (message) {
|
||
this.emit('debug', message);
|
||
};
|
||
ExecState.prototype._setResult = function () {
|
||
// determine whether there is an error
|
||
var error;
|
||
if (this.processExited) {
|
||
if (this.processError) {
|
||
error = new Error(im._loc('LIB_ProcessError', this.toolPath, this.processError));
|
||
}
|
||
else if (this.processExitCode != 0 && !this.options.ignoreReturnCode) {
|
||
error = new Error(im._loc('LIB_ProcessExitCode', this.toolPath, this.processExitCode));
|
||
}
|
||
else if (this.processStderr && this.options.failOnStdErr) {
|
||
error = new Error(im._loc('LIB_ProcessStderr', this.toolPath));
|
||
}
|
||
}
|
||
// clear the timeout
|
||
if (this.timeout) {
|
||
clearTimeout(this.timeout);
|
||
this.timeout = null;
|
||
}
|
||
this.done = true;
|
||
this.emit('done', error, this.processExitCode);
|
||
};
|
||
ExecState.HandleTimeout = function (state) {
|
||
if (state.done) {
|
||
return;
|
||
}
|
||
if (!state.processClosed && state.processExited) {
|
||
console.log(im._loc('LIB_StdioNotClosed', state.delay / 1000, state.toolPath));
|
||
state._debug(im._loc('LIB_StdioNotClosed', state.delay / 1000, state.toolPath));
|
||
}
|
||
state._setResult();
|
||
};
|
||
return ExecState;
|
||
}(events.EventEmitter));
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib/vault.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/vault.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Vault = void 0;
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var crypto = __webpack_require__(/*! crypto */ "crypto");
|
||
var uuidV4 = __webpack_require__(/*! uuid/v4 */ "./node_modules/azure-pipelines-task-lib/node_modules/uuid/v4.js");
|
||
var algorithm = "aes-256-ctr";
|
||
var encryptEncoding = 'hex';
|
||
var unencryptedEncoding = 'utf8';
|
||
//
|
||
// Store sensitive data in proc.
|
||
// Main goal: Protects tasks which would dump envvars from leaking secrets inadvertently
|
||
// the task lib clears after storing.
|
||
// Also protects against a dump of a process getting the secrets
|
||
// The secret is generated and stored externally for the lifetime of the task.
|
||
//
|
||
var Vault = /** @class */ (function () {
|
||
function Vault(keyPath) {
|
||
this._keyFile = path.join(keyPath, '.taskkey');
|
||
this._store = {};
|
||
this.genKey();
|
||
}
|
||
Vault.prototype.initialize = function () {
|
||
};
|
||
Vault.prototype.storeSecret = function (name, data) {
|
||
if (!name || name.length == 0) {
|
||
return false;
|
||
}
|
||
name = name.toLowerCase();
|
||
if (!data || data.length == 0) {
|
||
if (this._store.hasOwnProperty(name)) {
|
||
delete this._store[name];
|
||
}
|
||
return false;
|
||
}
|
||
var key = this.getKey();
|
||
var iv = crypto.randomBytes(16);
|
||
var cipher = crypto.createCipheriv(algorithm, key, iv);
|
||
var crypted = cipher.update(data, unencryptedEncoding, encryptEncoding);
|
||
var cryptedFinal = cipher.final(encryptEncoding);
|
||
this._store[name] = iv.toString(encryptEncoding) + crypted + cryptedFinal;
|
||
return true;
|
||
};
|
||
Vault.prototype.retrieveSecret = function (name) {
|
||
var secret;
|
||
name = (name || '').toLowerCase();
|
||
if (this._store.hasOwnProperty(name)) {
|
||
var key = this.getKey();
|
||
var data = this._store[name];
|
||
var ivDataBuffer = Buffer.from(data, encryptEncoding);
|
||
var iv = ivDataBuffer.slice(0, 16);
|
||
var encryptedText = ivDataBuffer.slice(16);
|
||
var decipher = crypto.createDecipheriv(algorithm, key, iv);
|
||
var dec = decipher.update(encryptedText, encryptEncoding, unencryptedEncoding);
|
||
var decFinal = decipher.final(unencryptedEncoding);
|
||
secret = dec + decFinal;
|
||
}
|
||
return secret;
|
||
};
|
||
Vault.prototype.getKey = function () {
|
||
var key = fs.readFileSync(this._keyFile).toString('utf8');
|
||
// Key needs to be hashed to correct length to match algorithm (aes-256-ctr)
|
||
return crypto.createHash('sha256').update(key).digest();
|
||
};
|
||
Vault.prototype.genKey = function () {
|
||
fs.writeFileSync(this._keyFile, uuidV4(), { encoding: 'utf8' });
|
||
};
|
||
return Vault;
|
||
}());
|
||
exports.Vault = Vault;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-task-lib sync recursive":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-task-lib/ sync ***!
|
||
\*****************************************************/
|
||
/***/ ((module) => {
|
||
|
||
function webpackEmptyContext(req) {
|
||
var e = new Error("Cannot find module '" + req + "'");
|
||
e.code = 'MODULE_NOT_FOUND';
|
||
throw e;
|
||
}
|
||
webpackEmptyContext.keys = () => ([]);
|
||
webpackEmptyContext.resolve = webpackEmptyContext;
|
||
webpackEmptyContext.id = "./node_modules/azure-pipelines-task-lib sync recursive";
|
||
module.exports = webpackEmptyContext;
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/bytesToUuid.js":
|
||
/*!************************************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/bytesToUuid.js ***!
|
||
\************************************************************************************/
|
||
/***/ ((module) => {
|
||
|
||
/**
|
||
* Convert array of 16 byte values to UUID string format of the form:
|
||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||
*/
|
||
var byteToHex = [];
|
||
for (var i = 0; i < 256; ++i) {
|
||
byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
||
}
|
||
|
||
function bytesToUuid(buf, offset) {
|
||
var i = offset || 0;
|
||
var bth = byteToHex;
|
||
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
|
||
return ([
|
||
bth[buf[i++]], bth[buf[i++]],
|
||
bth[buf[i++]], bth[buf[i++]], '-',
|
||
bth[buf[i++]], bth[buf[i++]], '-',
|
||
bth[buf[i++]], bth[buf[i++]], '-',
|
||
bth[buf[i++]], bth[buf[i++]], '-',
|
||
bth[buf[i++]], bth[buf[i++]],
|
||
bth[buf[i++]], bth[buf[i++]],
|
||
bth[buf[i++]], bth[buf[i++]]
|
||
]).join('');
|
||
}
|
||
|
||
module.exports = bytesToUuid;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/rng.js":
|
||
/*!****************************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/rng.js ***!
|
||
\****************************************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
// Unique ID creation requires a high quality random # generator. In node.js
|
||
// this is pretty straight-forward - we use the crypto API.
|
||
|
||
var crypto = __webpack_require__(/*! crypto */ "crypto");
|
||
|
||
module.exports = function nodeRNG() {
|
||
return crypto.randomBytes(16);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-tool-lib/node_modules/uuid/v4.js":
|
||
/*!***********************************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/node_modules/uuid/v4.js ***!
|
||
\***********************************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var rng = __webpack_require__(/*! ./lib/rng */ "./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/rng.js");
|
||
var bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ "./node_modules/azure-pipelines-tool-lib/node_modules/uuid/lib/bytesToUuid.js");
|
||
|
||
function v4(options, buf, offset) {
|
||
var i = buf && offset || 0;
|
||
|
||
if (typeof(options) == 'string') {
|
||
buf = options === 'binary' ? new Array(16) : null;
|
||
options = null;
|
||
}
|
||
options = options || {};
|
||
|
||
var rnds = options.random || (options.rng || rng)();
|
||
|
||
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
||
rnds[6] = (rnds[6] & 0x0f) | 0x40;
|
||
rnds[8] = (rnds[8] & 0x3f) | 0x80;
|
||
|
||
// Copy bytes to buffer, if provided
|
||
if (buf) {
|
||
for (var ii = 0; ii < 16; ++ii) {
|
||
buf[i + ii] = rnds[ii];
|
||
}
|
||
}
|
||
|
||
return buf || bytesToUuid(rnds);
|
||
}
|
||
|
||
module.exports = v4;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-tool-lib/tool.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/tool.js ***!
|
||
\*******************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.scrape = exports.extractZip = exports.extractTar = exports.extract7z = exports.cacheFile = exports.cacheDir = exports.downloadTool = exports.findLocalToolVersions = exports.findLocalTool = exports.evaluateVersions = exports.cleanVersion = exports.isExplicitVersion = exports.prependPath = exports.debug = void 0;
|
||
const httpm = __webpack_require__(/*! typed-rest-client/HttpClient */ "./node_modules/typed-rest-client/HttpClient.js");
|
||
const path = __webpack_require__(/*! path */ "path");
|
||
const os = __webpack_require__(/*! os */ "os");
|
||
const process = __webpack_require__(/*! process */ "process");
|
||
const fs = __webpack_require__(/*! fs */ "fs");
|
||
const semver = __webpack_require__(/*! semver */ "./node_modules/semver/semver.js");
|
||
const tl = __webpack_require__(/*! azure-pipelines-task-lib/task */ "./node_modules/azure-pipelines-task-lib/task.js");
|
||
const cmp = __webpack_require__(/*! semver-compare */ "./node_modules/semver-compare/index.js");
|
||
const uuidV4 = __webpack_require__(/*! uuid/v4 */ "./node_modules/azure-pipelines-tool-lib/node_modules/uuid/v4.js");
|
||
let pkg = { version: "1.2.3" };
|
||
let userAgent = 'vsts-task-installer/' + pkg.version;
|
||
let requestOptions = {
|
||
// ignoreSslError: true,
|
||
proxy: tl.getHttpProxyConfiguration(),
|
||
cert: tl.getHttpCertConfiguration(),
|
||
allowRedirects: true,
|
||
allowRetries: true,
|
||
maxRetries: 2
|
||
};
|
||
tl.setResourcePath(path.join(__dirname, 'lib.json'));
|
||
function debug(message) {
|
||
tl.debug(message);
|
||
}
|
||
exports.debug = debug;
|
||
function prependPath(toolPath) {
|
||
tl.assertAgent('2.115.0');
|
||
if (!toolPath) {
|
||
throw new Error('Parameter toolPath must not be null or empty');
|
||
}
|
||
else if (!tl.exist(toolPath) || !tl.stats(toolPath).isDirectory()) {
|
||
throw new Error('Directory does not exist: ' + toolPath);
|
||
}
|
||
// todo: add a test for path
|
||
console.log(tl.loc('TOOL_LIB_PrependPath', toolPath));
|
||
let newPath = toolPath + path.delimiter + process.env['PATH'];
|
||
tl.debug('new Path: ' + newPath);
|
||
process.env['PATH'] = newPath;
|
||
// instruct the agent to set this path on future tasks
|
||
console.log('##vso[task.prependpath]' + toolPath);
|
||
}
|
||
exports.prependPath = prependPath;
|
||
function delay(ms) {
|
||
return new Promise(resolve => setTimeout(resolve, ms));
|
||
}
|
||
//-----------------------------
|
||
// Version Functions
|
||
//-----------------------------
|
||
/**
|
||
* Checks if a version spec is an explicit version (e.g. 1.0.1 or v1.0.1)
|
||
* As opposed to a version spec like 1.x
|
||
*
|
||
* @param versionSpec
|
||
*/
|
||
function isExplicitVersion(versionSpec) {
|
||
let c = semver.clean(versionSpec);
|
||
tl.debug('isExplicit: ' + c);
|
||
let valid = semver.valid(c) != null;
|
||
tl.debug('explicit? ' + valid);
|
||
return valid;
|
||
}
|
||
exports.isExplicitVersion = isExplicitVersion;
|
||
/**
|
||
* Returns cleaned (removed leading/trailing whitespace, remove '=v' prefix)
|
||
* and parsed version, or null if version is invalid.
|
||
*/
|
||
function cleanVersion(version) {
|
||
tl.debug('cleaning: ' + version);
|
||
return semver.clean(version);
|
||
}
|
||
exports.cleanVersion = cleanVersion;
|
||
/**
|
||
* evaluates a list of versions and returns the latest version matching the version spec
|
||
*
|
||
* @param versions an array of versions to evaluate
|
||
* @param versionSpec a version spec (e.g. 1.x)
|
||
*/
|
||
function evaluateVersions(versions, versionSpec) {
|
||
let version;
|
||
tl.debug('evaluating ' + versions.length + ' versions');
|
||
versions = versions.sort(cmp);
|
||
for (let i = versions.length - 1; i >= 0; i--) {
|
||
let potential = versions[i];
|
||
let satisfied = semver.satisfies(potential, versionSpec);
|
||
if (satisfied) {
|
||
version = potential;
|
||
break;
|
||
}
|
||
}
|
||
if (version) {
|
||
tl.debug('matched: ' + version);
|
||
}
|
||
else {
|
||
tl.debug('match not found');
|
||
}
|
||
return version;
|
||
}
|
||
exports.evaluateVersions = evaluateVersions;
|
||
//-----------------------------
|
||
// Local Tool Cache Functions
|
||
//-----------------------------
|
||
/**
|
||
* finds the path to a tool in the local installed tool cache
|
||
*
|
||
* @param toolName name of the tool
|
||
* @param versionSpec version of the tool
|
||
* @param arch optional arch. defaults to arch of computer
|
||
*/
|
||
function findLocalTool(toolName, versionSpec, arch) {
|
||
if (!toolName) {
|
||
throw new Error('toolName parameter is required');
|
||
}
|
||
if (!versionSpec) {
|
||
throw new Error('versionSpec parameter is required');
|
||
}
|
||
arch = arch || os.arch();
|
||
// attempt to resolve an explicit version
|
||
if (!isExplicitVersion(versionSpec)) {
|
||
let localVersions = findLocalToolVersions(toolName, arch);
|
||
let match = evaluateVersions(localVersions, versionSpec);
|
||
versionSpec = match;
|
||
}
|
||
// check for the explicit version in the cache
|
||
let toolPath;
|
||
if (versionSpec) {
|
||
versionSpec = semver.clean(versionSpec);
|
||
let cacheRoot = _getCacheRoot();
|
||
let cachePath = path.join(cacheRoot, toolName, versionSpec, arch);
|
||
tl.debug('checking cache: ' + cachePath);
|
||
if (tl.exist(cachePath) && tl.exist(`${cachePath}.complete`)) {
|
||
console.log(tl.loc('TOOL_LIB_FoundInCache', toolName, versionSpec, arch));
|
||
toolPath = cachePath;
|
||
}
|
||
else {
|
||
tl.debug('not found');
|
||
}
|
||
}
|
||
return toolPath;
|
||
}
|
||
exports.findLocalTool = findLocalTool;
|
||
/**
|
||
* Retrieves the versions of a tool that is intalled in the local tool cache
|
||
*
|
||
* @param toolName name of the tool
|
||
* @param arch optional arch. defaults to arch of computer
|
||
*/
|
||
function findLocalToolVersions(toolName, arch) {
|
||
let versions = [];
|
||
arch = arch || os.arch();
|
||
let toolPath = path.join(_getCacheRoot(), toolName);
|
||
if (tl.exist(toolPath)) {
|
||
let children = tl.ls('', [toolPath]);
|
||
children.forEach((child) => {
|
||
if (isExplicitVersion(child)) {
|
||
let fullPath = path.join(toolPath, child, arch);
|
||
if (tl.exist(fullPath) && tl.exist(`${fullPath}.complete`)) {
|
||
versions.push(child);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
return versions;
|
||
}
|
||
exports.findLocalToolVersions = findLocalToolVersions;
|
||
//---------------------
|
||
// Download Functions
|
||
//---------------------
|
||
//
|
||
// TODO: keep extension intact
|
||
//
|
||
/**
|
||
* Download a tool from an url and stream it into a file
|
||
*
|
||
* @param url url of tool to download
|
||
* @param fileName optional fileName. Should typically not use (will be a guid for reliability). Can pass fileName with an absolute path.
|
||
* @param handlers optional handlers array. Auth handlers to pass to the HttpClient for the tool download.
|
||
*/
|
||
function downloadTool(url, fileName, handlers) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
handlers = handlers || null;
|
||
let http = new httpm.HttpClient(userAgent, handlers, requestOptions);
|
||
tl.debug(fileName);
|
||
fileName = fileName || uuidV4();
|
||
// check if it's an absolute path already
|
||
var destPath;
|
||
if (path.isAbsolute(fileName)) {
|
||
destPath = fileName;
|
||
}
|
||
else {
|
||
destPath = path.join(_getAgentTemp(), fileName);
|
||
}
|
||
// make sure that the folder exists
|
||
tl.mkdirP(path.dirname(destPath));
|
||
console.log(tl.loc('TOOL_LIB_Downloading', url));
|
||
tl.debug('destination ' + destPath);
|
||
if (fs.existsSync(destPath)) {
|
||
throw new Error("Destination file path already exists");
|
||
}
|
||
tl.debug('downloading');
|
||
let response = yield http.get(url);
|
||
if (response.message.statusCode != 200) {
|
||
let err = new Error('Unexpected HTTP response: ' + response.message.statusCode);
|
||
err['httpStatusCode'] = response.message.statusCode;
|
||
tl.debug(`Failed to download "${fileName}" from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
|
||
throw err;
|
||
}
|
||
tl.debug('creating stream');
|
||
let file = fs.createWriteStream(destPath);
|
||
file.on('open', (fd) => __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
let stream = response.message.pipe(file);
|
||
stream.on('close', () => {
|
||
tl.debug('download complete');
|
||
resolve(destPath);
|
||
});
|
||
}
|
||
catch (err) {
|
||
reject(err);
|
||
}
|
||
}));
|
||
file.on('error', (err) => {
|
||
file.end();
|
||
reject(err);
|
||
});
|
||
}
|
||
catch (error) {
|
||
reject(error);
|
||
}
|
||
}));
|
||
});
|
||
}
|
||
exports.downloadTool = downloadTool;
|
||
//---------------------
|
||
// Install Functions
|
||
//---------------------
|
||
function _createToolPath(tool, version, arch) {
|
||
// todo: add test for clean
|
||
let folderPath = path.join(_getCacheRoot(), tool, semver.clean(version), arch);
|
||
tl.debug('destination ' + folderPath);
|
||
let markerPath = `${folderPath}.complete`;
|
||
tl.rmRF(folderPath);
|
||
tl.rmRF(markerPath);
|
||
tl.mkdirP(folderPath);
|
||
return folderPath;
|
||
}
|
||
function _completeToolPath(tool, version, arch) {
|
||
let folderPath = path.join(_getCacheRoot(), tool, semver.clean(version), arch);
|
||
let markerPath = `${folderPath}.complete`;
|
||
tl.writeFile(markerPath, '');
|
||
tl.debug('finished caching tool');
|
||
}
|
||
/**
|
||
* Caches a directory and installs it into the tool cacheDir
|
||
*
|
||
* @param sourceDir the directory to cache into tools
|
||
* @param tool tool name
|
||
* @param version version of the tool. semver format
|
||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||
*/
|
||
function cacheDir(sourceDir, tool, version, arch) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
version = semver.clean(version);
|
||
arch = arch || os.arch();
|
||
console.log(tl.loc('TOOL_LIB_CachingTool', tool, version, arch));
|
||
tl.debug('source dir: ' + sourceDir);
|
||
if (!tl.stats(sourceDir).isDirectory()) {
|
||
throw new Error('sourceDir is not a directory');
|
||
}
|
||
// create the tool dir
|
||
let destPath = _createToolPath(tool, version, arch);
|
||
// copy each child item. do not move. move can fail on Windows
|
||
// due to anti-virus software having an open handle on a file.
|
||
for (let itemName of fs.readdirSync(sourceDir)) {
|
||
let s = path.join(sourceDir, itemName);
|
||
tl.cp(s, destPath + '/', '-r');
|
||
}
|
||
// write .complete
|
||
_completeToolPath(tool, version, arch);
|
||
return destPath;
|
||
});
|
||
}
|
||
exports.cacheDir = cacheDir;
|
||
/**
|
||
* Caches a downloaded file (GUID) and installs it
|
||
* into the tool cache with a given targetName
|
||
*
|
||
* @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid.
|
||
* @param targetFile the name of the file name in the tools directory
|
||
* @param tool tool name
|
||
* @param version version of the tool. semver format
|
||
* @param arch architecture of the tool. Optional. Defaults to machine architecture
|
||
*/
|
||
function cacheFile(sourceFile, targetFile, tool, version, arch) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
version = semver.clean(version);
|
||
arch = arch || os.arch();
|
||
console.log(tl.loc('TOOL_LIB_CachingTool', tool, version, arch));
|
||
tl.debug('source file:' + sourceFile);
|
||
if (!tl.stats(sourceFile).isFile()) {
|
||
throw new Error('sourceFile is not a file');
|
||
}
|
||
// create the tool dir
|
||
let destFolder = _createToolPath(tool, version, arch);
|
||
// copy instead of move. move can fail on Windows due to
|
||
// anti-virus software having an open handle on a file.
|
||
let destPath = path.join(destFolder, targetFile);
|
||
tl.debug('destination file' + destPath);
|
||
tl.cp(sourceFile, destPath);
|
||
// write .complete
|
||
_completeToolPath(tool, version, arch);
|
||
return destFolder;
|
||
});
|
||
}
|
||
exports.cacheFile = cacheFile;
|
||
//---------------------
|
||
// Extract Functions
|
||
//---------------------
|
||
/**
|
||
* Extract a .7z file
|
||
*
|
||
* @param file path to the .7z file
|
||
* @param dest destination directory. Optional.
|
||
* @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this
|
||
* problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will
|
||
* gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is
|
||
* bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line
|
||
* interface, it is smaller than the full command line interface, and it does support long paths. At the
|
||
* time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website.
|
||
* Be sure to check the current license agreement. If 7zr.exe is bundled with your task, then the path
|
||
* to 7zr.exe can be pass to this function.
|
||
* @returns path to the destination directory
|
||
*/
|
||
function extract7z(file, dest, _7zPath) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
if (process.platform != 'win32') {
|
||
throw new Error('extract7z() not supported on current OS');
|
||
}
|
||
if (!file) {
|
||
throw new Error("parameter 'file' is required");
|
||
}
|
||
console.log(tl.loc('TOOL_LIB_ExtractingArchive'));
|
||
dest = _createExtractFolder(dest);
|
||
let originalCwd = process.cwd();
|
||
try {
|
||
process.chdir(dest);
|
||
if (_7zPath) {
|
||
// extract
|
||
let _7z = tl.tool(_7zPath)
|
||
.arg('x') // eXtract files with full paths
|
||
.arg('-bb1') // -bb[0-3] : set output log level
|
||
.arg('-bd') // disable progress indicator
|
||
.arg('-sccUTF-8') // set charset for for console input/output
|
||
.arg(file);
|
||
yield _7z.exec();
|
||
}
|
||
else {
|
||
// extract
|
||
let escapedScript = path.join(__dirname, 'Invoke-7zdec.ps1').replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
|
||
let escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||
let escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||
let command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`;
|
||
let powershellPath = tl.which('powershell', true);
|
||
let powershell = tl.tool(powershellPath)
|
||
.line('-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command')
|
||
.arg(command);
|
||
powershell.on('stdout', (buffer) => {
|
||
process.stdout.write(buffer);
|
||
});
|
||
powershell.on('stderr', (buffer) => {
|
||
process.stderr.write(buffer);
|
||
});
|
||
yield powershell.exec({ silent: true });
|
||
}
|
||
}
|
||
finally {
|
||
process.chdir(originalCwd);
|
||
}
|
||
return dest;
|
||
});
|
||
}
|
||
exports.extract7z = extract7z;
|
||
/**
|
||
* installs a tool from a tar by extracting the tar and installing it into the tool cache
|
||
*
|
||
* @param file file path of the tar
|
||
* @param tool name of tool in the tool cache
|
||
* @param version version of the tool
|
||
* @param arch arch of the tool. optional. defaults to the arch of the machine
|
||
* @param options IExtractOptions
|
||
* @param destination destination directory. optional.
|
||
*/
|
||
function extractTar(file, destination) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
// mkdir -p node/4.7.0/x64
|
||
// tar xzC ./node/4.7.0/x64 -f node-v4.7.0-darwin-x64.tar.gz --strip-components 1
|
||
console.log(tl.loc('TOOL_LIB_ExtractingArchive'));
|
||
let dest = _createExtractFolder(destination);
|
||
let tr = tl.tool('tar');
|
||
tr.arg(['xC', dest, '-f', file]);
|
||
yield tr.exec();
|
||
return dest;
|
||
});
|
||
}
|
||
exports.extractTar = extractTar;
|
||
function extractZip(file, destination) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
if (!file) {
|
||
throw new Error("parameter 'file' is required");
|
||
}
|
||
console.log(tl.loc('TOOL_LIB_ExtractingArchive'));
|
||
let dest = _createExtractFolder(destination);
|
||
if (process.platform == 'win32') {
|
||
// build the powershell command
|
||
let escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
|
||
let escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
|
||
let command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`;
|
||
// change the console output code page to UTF-8.
|
||
// TODO: FIX WHICH: let chcpPath = tl.which('chcp.com', true);
|
||
let chcpPath = path.join(process.env.windir, "system32", "chcp.com");
|
||
yield tl.exec(chcpPath, '65001');
|
||
// run powershell
|
||
let powershell = tl.tool('powershell')
|
||
.line('-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command')
|
||
.arg(command);
|
||
yield powershell.exec();
|
||
}
|
||
else {
|
||
let unzip = tl.tool('unzip')
|
||
.arg(file);
|
||
yield unzip.exec({ cwd: dest });
|
||
}
|
||
return dest;
|
||
});
|
||
}
|
||
exports.extractZip = extractZip;
|
||
function _createExtractFolder(dest) {
|
||
if (!dest) {
|
||
// create a temp dir
|
||
dest = path.join(_getAgentTemp(), uuidV4());
|
||
}
|
||
tl.mkdirP(dest);
|
||
return dest;
|
||
}
|
||
//---------------------
|
||
// Query Functions
|
||
//---------------------
|
||
// default input will be >= LTS version. drop label different than value.
|
||
// v4 (LTS) would have a value of 4.x
|
||
// option to always download? (not cache), TTL?
|
||
/**
|
||
* Scrape a web page for versions by regex
|
||
*
|
||
* @param url url to scrape
|
||
* @param regex regex to use for version matches
|
||
* @param handlers optional handlers array. Auth handlers to pass to the HttpClient for the tool download.
|
||
*/
|
||
function scrape(url, regex, handlers) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
handlers = handlers || null;
|
||
let http = new httpm.HttpClient(userAgent, handlers, requestOptions);
|
||
let output = yield (yield http.get(url)).readBody();
|
||
let matches = output.match(regex);
|
||
let seen = {};
|
||
let versions = [];
|
||
for (let i = 0; i < matches.length; i++) {
|
||
let ver = semver.clean(matches[i]);
|
||
if (!seen.hasOwnProperty(ver)) {
|
||
seen[ver] = true;
|
||
versions.push(ver);
|
||
}
|
||
}
|
||
return versions;
|
||
});
|
||
}
|
||
exports.scrape = scrape;
|
||
function _getCacheRoot() {
|
||
tl.assertAgent('2.115.0');
|
||
let cacheRoot = tl.getVariable('Agent.ToolsDirectory');
|
||
if (!cacheRoot) {
|
||
throw new Error('Agent.ToolsDirectory is not set');
|
||
}
|
||
return cacheRoot;
|
||
}
|
||
function _getAgentTemp() {
|
||
tl.assertAgent('2.115.0');
|
||
let tempDirectory = tl.getVariable('Agent.TempDirectory');
|
||
if (!tempDirectory) {
|
||
throw new Error('Agent.TempDirectory is not set');
|
||
}
|
||
return tempDirectory;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/azure-pipelines-tool-lib sync recursive":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/azure-pipelines-tool-lib/ sync ***!
|
||
\*****************************************************/
|
||
/***/ ((module) => {
|
||
|
||
function webpackEmptyContext(req) {
|
||
var e = new Error("Cannot find module '" + req + "'");
|
||
e.code = 'MODULE_NOT_FOUND';
|
||
throw e;
|
||
}
|
||
webpackEmptyContext.keys = () => ([]);
|
||
webpackEmptyContext.resolve = webpackEmptyContext;
|
||
webpackEmptyContext.id = "./node_modules/azure-pipelines-tool-lib sync recursive";
|
||
module.exports = webpackEmptyContext;
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/balanced-match/index.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/balanced-match/index.js ***!
|
||
\**********************************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
|
||
module.exports = balanced;
|
||
function balanced(a, b, str) {
|
||
if (a instanceof RegExp) a = maybeMatch(a, str);
|
||
if (b instanceof RegExp) b = maybeMatch(b, str);
|
||
|
||
var r = range(a, b, str);
|
||
|
||
return r && {
|
||
start: r[0],
|
||
end: r[1],
|
||
pre: str.slice(0, r[0]),
|
||
body: str.slice(r[0] + a.length, r[1]),
|
||
post: str.slice(r[1] + b.length)
|
||
};
|
||
}
|
||
|
||
function maybeMatch(reg, str) {
|
||
var m = str.match(reg);
|
||
return m ? m[0] : null;
|
||
}
|
||
|
||
balanced.range = range;
|
||
function range(a, b, str) {
|
||
var begs, beg, left, right, result;
|
||
var ai = str.indexOf(a);
|
||
var bi = str.indexOf(b, ai + 1);
|
||
var i = ai;
|
||
|
||
if (ai >= 0 && bi > 0) {
|
||
begs = [];
|
||
left = str.length;
|
||
|
||
while (i >= 0 && !result) {
|
||
if (i == ai) {
|
||
begs.push(i);
|
||
ai = str.indexOf(a, i + 1);
|
||
} else if (begs.length == 1) {
|
||
result = [ begs.pop(), bi ];
|
||
} else {
|
||
beg = begs.pop();
|
||
if (beg < left) {
|
||
left = beg;
|
||
right = bi;
|
||
}
|
||
|
||
bi = str.indexOf(b, i + 1);
|
||
}
|
||
|
||
i = ai < bi && ai >= 0 ? ai : bi;
|
||
}
|
||
|
||
if (begs.length) {
|
||
result = [ left, right ];
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/brace-expansion/index.js":
|
||
/*!***********************************************!*\
|
||
!*** ./node_modules/brace-expansion/index.js ***!
|
||
\***********************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var concatMap = __webpack_require__(/*! concat-map */ "./node_modules/concat-map/index.js");
|
||
var balanced = __webpack_require__(/*! balanced-match */ "./node_modules/balanced-match/index.js");
|
||
|
||
module.exports = expandTop;
|
||
|
||
var escSlash = '\0SLASH'+Math.random()+'\0';
|
||
var escOpen = '\0OPEN'+Math.random()+'\0';
|
||
var escClose = '\0CLOSE'+Math.random()+'\0';
|
||
var escComma = '\0COMMA'+Math.random()+'\0';
|
||
var escPeriod = '\0PERIOD'+Math.random()+'\0';
|
||
|
||
function numeric(str) {
|
||
return parseInt(str, 10) == str
|
||
? parseInt(str, 10)
|
||
: str.charCodeAt(0);
|
||
}
|
||
|
||
function escapeBraces(str) {
|
||
return str.split('\\\\').join(escSlash)
|
||
.split('\\{').join(escOpen)
|
||
.split('\\}').join(escClose)
|
||
.split('\\,').join(escComma)
|
||
.split('\\.').join(escPeriod);
|
||
}
|
||
|
||
function unescapeBraces(str) {
|
||
return str.split(escSlash).join('\\')
|
||
.split(escOpen).join('{')
|
||
.split(escClose).join('}')
|
||
.split(escComma).join(',')
|
||
.split(escPeriod).join('.');
|
||
}
|
||
|
||
|
||
// Basically just str.split(","), but handling cases
|
||
// where we have nested braced sections, which should be
|
||
// treated as individual members, like {a,{b,c},d}
|
||
function parseCommaParts(str) {
|
||
if (!str)
|
||
return [''];
|
||
|
||
var parts = [];
|
||
var m = balanced('{', '}', str);
|
||
|
||
if (!m)
|
||
return str.split(',');
|
||
|
||
var pre = m.pre;
|
||
var body = m.body;
|
||
var post = m.post;
|
||
var p = pre.split(',');
|
||
|
||
p[p.length-1] += '{' + body + '}';
|
||
var postParts = parseCommaParts(post);
|
||
if (post.length) {
|
||
p[p.length-1] += postParts.shift();
|
||
p.push.apply(p, postParts);
|
||
}
|
||
|
||
parts.push.apply(parts, p);
|
||
|
||
return parts;
|
||
}
|
||
|
||
function expandTop(str) {
|
||
if (!str)
|
||
return [];
|
||
|
||
// I don't know why Bash 4.3 does this, but it does.
|
||
// Anything starting with {} will have the first two bytes preserved
|
||
// but *only* at the top level, so {},a}b will not expand to anything,
|
||
// but a{},b}c will be expanded to [a}c,abc].
|
||
// One could argue that this is a bug in Bash, but since the goal of
|
||
// this module is to match Bash's rules, we escape a leading {}
|
||
if (str.substr(0, 2) === '{}') {
|
||
str = '\\{\\}' + str.substr(2);
|
||
}
|
||
|
||
return expand(escapeBraces(str), true).map(unescapeBraces);
|
||
}
|
||
|
||
function identity(e) {
|
||
return e;
|
||
}
|
||
|
||
function embrace(str) {
|
||
return '{' + str + '}';
|
||
}
|
||
function isPadded(el) {
|
||
return /^-?0\d/.test(el);
|
||
}
|
||
|
||
function lte(i, y) {
|
||
return i <= y;
|
||
}
|
||
function gte(i, y) {
|
||
return i >= y;
|
||
}
|
||
|
||
function expand(str, isTop) {
|
||
var expansions = [];
|
||
|
||
var m = balanced('{', '}', str);
|
||
if (!m || /\$$/.test(m.pre)) return [str];
|
||
|
||
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
||
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
||
var isSequence = isNumericSequence || isAlphaSequence;
|
||
var isOptions = m.body.indexOf(',') >= 0;
|
||
if (!isSequence && !isOptions) {
|
||
// {a},b}
|
||
if (m.post.match(/,.*\}/)) {
|
||
str = m.pre + '{' + m.body + escClose + m.post;
|
||
return expand(str);
|
||
}
|
||
return [str];
|
||
}
|
||
|
||
var n;
|
||
if (isSequence) {
|
||
n = m.body.split(/\.\./);
|
||
} else {
|
||
n = parseCommaParts(m.body);
|
||
if (n.length === 1) {
|
||
// x{{a,b}}y ==> x{a}y x{b}y
|
||
n = expand(n[0], false).map(embrace);
|
||
if (n.length === 1) {
|
||
var post = m.post.length
|
||
? expand(m.post, false)
|
||
: [''];
|
||
return post.map(function(p) {
|
||
return m.pre + n[0] + p;
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
// at this point, n is the parts, and we know it's not a comma set
|
||
// with a single entry.
|
||
|
||
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
||
var pre = m.pre;
|
||
var post = m.post.length
|
||
? expand(m.post, false)
|
||
: [''];
|
||
|
||
var N;
|
||
|
||
if (isSequence) {
|
||
var x = numeric(n[0]);
|
||
var y = numeric(n[1]);
|
||
var width = Math.max(n[0].length, n[1].length)
|
||
var incr = n.length == 3
|
||
? Math.abs(numeric(n[2]))
|
||
: 1;
|
||
var test = lte;
|
||
var reverse = y < x;
|
||
if (reverse) {
|
||
incr *= -1;
|
||
test = gte;
|
||
}
|
||
var pad = n.some(isPadded);
|
||
|
||
N = [];
|
||
|
||
for (var i = x; test(i, y); i += incr) {
|
||
var c;
|
||
if (isAlphaSequence) {
|
||
c = String.fromCharCode(i);
|
||
if (c === '\\')
|
||
c = '';
|
||
} else {
|
||
c = String(i);
|
||
if (pad) {
|
||
var need = width - c.length;
|
||
if (need > 0) {
|
||
var z = new Array(need + 1).join('0');
|
||
if (i < 0)
|
||
c = '-' + z + c.slice(1);
|
||
else
|
||
c = z + c;
|
||
}
|
||
}
|
||
}
|
||
N.push(c);
|
||
}
|
||
} else {
|
||
N = concatMap(n, function(el) { return expand(el, false) });
|
||
}
|
||
|
||
for (var j = 0; j < N.length; j++) {
|
||
for (var k = 0; k < post.length; k++) {
|
||
var expansion = pre + N[j] + post[k];
|
||
if (!isTop || isSequence || expansion)
|
||
expansions.push(expansion);
|
||
}
|
||
}
|
||
|
||
return expansions;
|
||
}
|
||
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/concat-map/index.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/concat-map/index.js ***!
|
||
\******************************************/
|
||
/***/ ((module) => {
|
||
|
||
module.exports = function (xs, fn) {
|
||
var res = [];
|
||
for (var i = 0; i < xs.length; i++) {
|
||
var x = fn(xs[i], i);
|
||
if (isArray(x)) res.push.apply(res, x);
|
||
else res.push(x);
|
||
}
|
||
return res;
|
||
};
|
||
|
||
var isArray = Array.isArray || function (xs) {
|
||
return Object.prototype.toString.call(xs) === '[object Array]';
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/fs.realpath/index.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/fs.realpath/index.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
module.exports = realpath
|
||
realpath.realpath = realpath
|
||
realpath.sync = realpathSync
|
||
realpath.realpathSync = realpathSync
|
||
realpath.monkeypatch = monkeypatch
|
||
realpath.unmonkeypatch = unmonkeypatch
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs")
|
||
var origRealpath = fs.realpath
|
||
var origRealpathSync = fs.realpathSync
|
||
|
||
var version = process.version
|
||
var ok = /^v[0-5]\./.test(version)
|
||
var old = __webpack_require__(/*! ./old.js */ "./node_modules/fs.realpath/old.js")
|
||
|
||
function newError (er) {
|
||
return er && er.syscall === 'realpath' && (
|
||
er.code === 'ELOOP' ||
|
||
er.code === 'ENOMEM' ||
|
||
er.code === 'ENAMETOOLONG'
|
||
)
|
||
}
|
||
|
||
function realpath (p, cache, cb) {
|
||
if (ok) {
|
||
return origRealpath(p, cache, cb)
|
||
}
|
||
|
||
if (typeof cache === 'function') {
|
||
cb = cache
|
||
cache = null
|
||
}
|
||
origRealpath(p, cache, function (er, result) {
|
||
if (newError(er)) {
|
||
old.realpath(p, cache, cb)
|
||
} else {
|
||
cb(er, result)
|
||
}
|
||
})
|
||
}
|
||
|
||
function realpathSync (p, cache) {
|
||
if (ok) {
|
||
return origRealpathSync(p, cache)
|
||
}
|
||
|
||
try {
|
||
return origRealpathSync(p, cache)
|
||
} catch (er) {
|
||
if (newError(er)) {
|
||
return old.realpathSync(p, cache)
|
||
} else {
|
||
throw er
|
||
}
|
||
}
|
||
}
|
||
|
||
function monkeypatch () {
|
||
fs.realpath = realpath
|
||
fs.realpathSync = realpathSync
|
||
}
|
||
|
||
function unmonkeypatch () {
|
||
fs.realpath = origRealpath
|
||
fs.realpathSync = origRealpathSync
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/fs.realpath/old.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/fs.realpath/old.js ***!
|
||
\*****************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
var pathModule = __webpack_require__(/*! path */ "path");
|
||
var isWindows = process.platform === 'win32';
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
// JavaScript implementation of realpath, ported from node pre-v6
|
||
|
||
var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
|
||
|
||
function rethrow() {
|
||
// Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
|
||
// is fairly slow to generate.
|
||
var callback;
|
||
if (DEBUG) {
|
||
var backtrace = new Error;
|
||
callback = debugCallback;
|
||
} else
|
||
callback = missingCallback;
|
||
|
||
return callback;
|
||
|
||
function debugCallback(err) {
|
||
if (err) {
|
||
backtrace.message = err.message;
|
||
err = backtrace;
|
||
missingCallback(err);
|
||
}
|
||
}
|
||
|
||
function missingCallback(err) {
|
||
if (err) {
|
||
if (process.throwDeprecation)
|
||
throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs
|
||
else if (!process.noDeprecation) {
|
||
var msg = 'fs: missing callback ' + (err.stack || err.message);
|
||
if (process.traceDeprecation)
|
||
console.trace(msg);
|
||
else
|
||
console.error(msg);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function maybeCallback(cb) {
|
||
return typeof cb === 'function' ? cb : rethrow();
|
||
}
|
||
|
||
var normalize = pathModule.normalize;
|
||
|
||
// Regexp that finds the next partion of a (partial) path
|
||
// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
|
||
if (isWindows) {
|
||
var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
|
||
} else {
|
||
var nextPartRe = /(.*?)(?:[\/]+|$)/g;
|
||
}
|
||
|
||
// Regex to find the device root, including trailing slash. E.g. 'c:\\'.
|
||
if (isWindows) {
|
||
var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
|
||
} else {
|
||
var splitRootRe = /^[\/]*/;
|
||
}
|
||
|
||
exports.realpathSync = function realpathSync(p, cache) {
|
||
// make p is absolute
|
||
p = pathModule.resolve(p);
|
||
|
||
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
|
||
return cache[p];
|
||
}
|
||
|
||
var original = p,
|
||
seenLinks = {},
|
||
knownHard = {};
|
||
|
||
// current character position in p
|
||
var pos;
|
||
// the partial path so far, including a trailing slash if any
|
||
var current;
|
||
// the partial path without a trailing slash (except when pointing at a root)
|
||
var base;
|
||
// the partial path scanned in the previous round, with slash
|
||
var previous;
|
||
|
||
start();
|
||
|
||
function start() {
|
||
// Skip over roots
|
||
var m = splitRootRe.exec(p);
|
||
pos = m[0].length;
|
||
current = m[0];
|
||
base = m[0];
|
||
previous = '';
|
||
|
||
// On windows, check that the root exists. On unix there is no need.
|
||
if (isWindows && !knownHard[base]) {
|
||
fs.lstatSync(base);
|
||
knownHard[base] = true;
|
||
}
|
||
}
|
||
|
||
// walk down the path, swapping out linked pathparts for their real
|
||
// values
|
||
// NB: p.length changes.
|
||
while (pos < p.length) {
|
||
// find the next part
|
||
nextPartRe.lastIndex = pos;
|
||
var result = nextPartRe.exec(p);
|
||
previous = current;
|
||
current += result[0];
|
||
base = previous + result[1];
|
||
pos = nextPartRe.lastIndex;
|
||
|
||
// continue if not a symlink
|
||
if (knownHard[base] || (cache && cache[base] === base)) {
|
||
continue;
|
||
}
|
||
|
||
var resolvedLink;
|
||
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
|
||
// some known symbolic link. no need to stat again.
|
||
resolvedLink = cache[base];
|
||
} else {
|
||
var stat = fs.lstatSync(base);
|
||
if (!stat.isSymbolicLink()) {
|
||
knownHard[base] = true;
|
||
if (cache) cache[base] = base;
|
||
continue;
|
||
}
|
||
|
||
// read the link if it wasn't read before
|
||
// dev/ino always return 0 on windows, so skip the check.
|
||
var linkTarget = null;
|
||
if (!isWindows) {
|
||
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
|
||
if (seenLinks.hasOwnProperty(id)) {
|
||
linkTarget = seenLinks[id];
|
||
}
|
||
}
|
||
if (linkTarget === null) {
|
||
fs.statSync(base);
|
||
linkTarget = fs.readlinkSync(base);
|
||
}
|
||
resolvedLink = pathModule.resolve(previous, linkTarget);
|
||
// track this, if given a cache.
|
||
if (cache) cache[base] = resolvedLink;
|
||
if (!isWindows) seenLinks[id] = linkTarget;
|
||
}
|
||
|
||
// resolve the link, then start over
|
||
p = pathModule.resolve(resolvedLink, p.slice(pos));
|
||
start();
|
||
}
|
||
|
||
if (cache) cache[original] = p;
|
||
|
||
return p;
|
||
};
|
||
|
||
|
||
exports.realpath = function realpath(p, cache, cb) {
|
||
if (typeof cb !== 'function') {
|
||
cb = maybeCallback(cache);
|
||
cache = null;
|
||
}
|
||
|
||
// make p is absolute
|
||
p = pathModule.resolve(p);
|
||
|
||
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
|
||
return process.nextTick(cb.bind(null, null, cache[p]));
|
||
}
|
||
|
||
var original = p,
|
||
seenLinks = {},
|
||
knownHard = {};
|
||
|
||
// current character position in p
|
||
var pos;
|
||
// the partial path so far, including a trailing slash if any
|
||
var current;
|
||
// the partial path without a trailing slash (except when pointing at a root)
|
||
var base;
|
||
// the partial path scanned in the previous round, with slash
|
||
var previous;
|
||
|
||
start();
|
||
|
||
function start() {
|
||
// Skip over roots
|
||
var m = splitRootRe.exec(p);
|
||
pos = m[0].length;
|
||
current = m[0];
|
||
base = m[0];
|
||
previous = '';
|
||
|
||
// On windows, check that the root exists. On unix there is no need.
|
||
if (isWindows && !knownHard[base]) {
|
||
fs.lstat(base, function(err) {
|
||
if (err) return cb(err);
|
||
knownHard[base] = true;
|
||
LOOP();
|
||
});
|
||
} else {
|
||
process.nextTick(LOOP);
|
||
}
|
||
}
|
||
|
||
// walk down the path, swapping out linked pathparts for their real
|
||
// values
|
||
function LOOP() {
|
||
// stop if scanned past end of path
|
||
if (pos >= p.length) {
|
||
if (cache) cache[original] = p;
|
||
return cb(null, p);
|
||
}
|
||
|
||
// find the next part
|
||
nextPartRe.lastIndex = pos;
|
||
var result = nextPartRe.exec(p);
|
||
previous = current;
|
||
current += result[0];
|
||
base = previous + result[1];
|
||
pos = nextPartRe.lastIndex;
|
||
|
||
// continue if not a symlink
|
||
if (knownHard[base] || (cache && cache[base] === base)) {
|
||
return process.nextTick(LOOP);
|
||
}
|
||
|
||
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
|
||
// known symbolic link. no need to stat again.
|
||
return gotResolvedLink(cache[base]);
|
||
}
|
||
|
||
return fs.lstat(base, gotStat);
|
||
}
|
||
|
||
function gotStat(err, stat) {
|
||
if (err) return cb(err);
|
||
|
||
// if not a symlink, skip to the next path part
|
||
if (!stat.isSymbolicLink()) {
|
||
knownHard[base] = true;
|
||
if (cache) cache[base] = base;
|
||
return process.nextTick(LOOP);
|
||
}
|
||
|
||
// stat & read the link if not read before
|
||
// call gotTarget as soon as the link target is known
|
||
// dev/ino always return 0 on windows, so skip the check.
|
||
if (!isWindows) {
|
||
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
|
||
if (seenLinks.hasOwnProperty(id)) {
|
||
return gotTarget(null, seenLinks[id], base);
|
||
}
|
||
}
|
||
fs.stat(base, function(err) {
|
||
if (err) return cb(err);
|
||
|
||
fs.readlink(base, function(err, target) {
|
||
if (!isWindows) seenLinks[id] = target;
|
||
gotTarget(err, target);
|
||
});
|
||
});
|
||
}
|
||
|
||
function gotTarget(err, target, base) {
|
||
if (err) return cb(err);
|
||
|
||
var resolvedLink = pathModule.resolve(previous, target);
|
||
if (cache) cache[base] = resolvedLink;
|
||
gotResolvedLink(resolvedLink);
|
||
}
|
||
|
||
function gotResolvedLink(resolvedLink) {
|
||
// resolve the link, then start over
|
||
p = pathModule.resolve(resolvedLink, p.slice(pos));
|
||
start();
|
||
}
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/glob/common.js":
|
||
/*!*************************************!*\
|
||
!*** ./node_modules/glob/common.js ***!
|
||
\*************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
exports.alphasort = alphasort
|
||
exports.alphasorti = alphasorti
|
||
exports.setopts = setopts
|
||
exports.ownProp = ownProp
|
||
exports.makeAbs = makeAbs
|
||
exports.finish = finish
|
||
exports.mark = mark
|
||
exports.isIgnored = isIgnored
|
||
exports.childrenIgnored = childrenIgnored
|
||
|
||
function ownProp (obj, field) {
|
||
return Object.prototype.hasOwnProperty.call(obj, field)
|
||
}
|
||
|
||
var path = __webpack_require__(/*! path */ "path")
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js")
|
||
var isAbsolute = __webpack_require__(/*! path-is-absolute */ "./node_modules/path-is-absolute/index.js")
|
||
var Minimatch = minimatch.Minimatch
|
||
|
||
function alphasorti (a, b) {
|
||
return a.toLowerCase().localeCompare(b.toLowerCase())
|
||
}
|
||
|
||
function alphasort (a, b) {
|
||
return a.localeCompare(b)
|
||
}
|
||
|
||
function setupIgnores (self, options) {
|
||
self.ignore = options.ignore || []
|
||
|
||
if (!Array.isArray(self.ignore))
|
||
self.ignore = [self.ignore]
|
||
|
||
if (self.ignore.length) {
|
||
self.ignore = self.ignore.map(ignoreMap)
|
||
}
|
||
}
|
||
|
||
// ignore patterns are always in dot:true mode.
|
||
function ignoreMap (pattern) {
|
||
var gmatcher = null
|
||
if (pattern.slice(-3) === '/**') {
|
||
var gpattern = pattern.replace(/(\/\*\*)+$/, '')
|
||
gmatcher = new Minimatch(gpattern, { dot: true })
|
||
}
|
||
|
||
return {
|
||
matcher: new Minimatch(pattern, { dot: true }),
|
||
gmatcher: gmatcher
|
||
}
|
||
}
|
||
|
||
function setopts (self, pattern, options) {
|
||
if (!options)
|
||
options = {}
|
||
|
||
// base-matching: just use globstar for that.
|
||
if (options.matchBase && -1 === pattern.indexOf("/")) {
|
||
if (options.noglobstar) {
|
||
throw new Error("base matching requires globstar")
|
||
}
|
||
pattern = "**/" + pattern
|
||
}
|
||
|
||
self.silent = !!options.silent
|
||
self.pattern = pattern
|
||
self.strict = options.strict !== false
|
||
self.realpath = !!options.realpath
|
||
self.realpathCache = options.realpathCache || Object.create(null)
|
||
self.follow = !!options.follow
|
||
self.dot = !!options.dot
|
||
self.mark = !!options.mark
|
||
self.nodir = !!options.nodir
|
||
if (self.nodir)
|
||
self.mark = true
|
||
self.sync = !!options.sync
|
||
self.nounique = !!options.nounique
|
||
self.nonull = !!options.nonull
|
||
self.nosort = !!options.nosort
|
||
self.nocase = !!options.nocase
|
||
self.stat = !!options.stat
|
||
self.noprocess = !!options.noprocess
|
||
self.absolute = !!options.absolute
|
||
|
||
self.maxLength = options.maxLength || Infinity
|
||
self.cache = options.cache || Object.create(null)
|
||
self.statCache = options.statCache || Object.create(null)
|
||
self.symlinks = options.symlinks || Object.create(null)
|
||
|
||
setupIgnores(self, options)
|
||
|
||
self.changedCwd = false
|
||
var cwd = process.cwd()
|
||
if (!ownProp(options, "cwd"))
|
||
self.cwd = cwd
|
||
else {
|
||
self.cwd = path.resolve(options.cwd)
|
||
self.changedCwd = self.cwd !== cwd
|
||
}
|
||
|
||
self.root = options.root || path.resolve(self.cwd, "/")
|
||
self.root = path.resolve(self.root)
|
||
if (process.platform === "win32")
|
||
self.root = self.root.replace(/\\/g, "/")
|
||
|
||
// TODO: is an absolute `cwd` supposed to be resolved against `root`?
|
||
// e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test')
|
||
self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd)
|
||
if (process.platform === "win32")
|
||
self.cwdAbs = self.cwdAbs.replace(/\\/g, "/")
|
||
self.nomount = !!options.nomount
|
||
|
||
// disable comments and negation in Minimatch.
|
||
// Note that they are not supported in Glob itself anyway.
|
||
options.nonegate = true
|
||
options.nocomment = true
|
||
|
||
self.minimatch = new Minimatch(pattern, options)
|
||
self.options = self.minimatch.options
|
||
}
|
||
|
||
function finish (self) {
|
||
var nou = self.nounique
|
||
var all = nou ? [] : Object.create(null)
|
||
|
||
for (var i = 0, l = self.matches.length; i < l; i ++) {
|
||
var matches = self.matches[i]
|
||
if (!matches || Object.keys(matches).length === 0) {
|
||
if (self.nonull) {
|
||
// do like the shell, and spit out the literal glob
|
||
var literal = self.minimatch.globSet[i]
|
||
if (nou)
|
||
all.push(literal)
|
||
else
|
||
all[literal] = true
|
||
}
|
||
} else {
|
||
// had matches
|
||
var m = Object.keys(matches)
|
||
if (nou)
|
||
all.push.apply(all, m)
|
||
else
|
||
m.forEach(function (m) {
|
||
all[m] = true
|
||
})
|
||
}
|
||
}
|
||
|
||
if (!nou)
|
||
all = Object.keys(all)
|
||
|
||
if (!self.nosort)
|
||
all = all.sort(self.nocase ? alphasorti : alphasort)
|
||
|
||
// at *some* point we statted all of these
|
||
if (self.mark) {
|
||
for (var i = 0; i < all.length; i++) {
|
||
all[i] = self._mark(all[i])
|
||
}
|
||
if (self.nodir) {
|
||
all = all.filter(function (e) {
|
||
var notDir = !(/\/$/.test(e))
|
||
var c = self.cache[e] || self.cache[makeAbs(self, e)]
|
||
if (notDir && c)
|
||
notDir = c !== 'DIR' && !Array.isArray(c)
|
||
return notDir
|
||
})
|
||
}
|
||
}
|
||
|
||
if (self.ignore.length)
|
||
all = all.filter(function(m) {
|
||
return !isIgnored(self, m)
|
||
})
|
||
|
||
self.found = all
|
||
}
|
||
|
||
function mark (self, p) {
|
||
var abs = makeAbs(self, p)
|
||
var c = self.cache[abs]
|
||
var m = p
|
||
if (c) {
|
||
var isDir = c === 'DIR' || Array.isArray(c)
|
||
var slash = p.slice(-1) === '/'
|
||
|
||
if (isDir && !slash)
|
||
m += '/'
|
||
else if (!isDir && slash)
|
||
m = m.slice(0, -1)
|
||
|
||
if (m !== p) {
|
||
var mabs = makeAbs(self, m)
|
||
self.statCache[mabs] = self.statCache[abs]
|
||
self.cache[mabs] = self.cache[abs]
|
||
}
|
||
}
|
||
|
||
return m
|
||
}
|
||
|
||
// lotta situps...
|
||
function makeAbs (self, f) {
|
||
var abs = f
|
||
if (f.charAt(0) === '/') {
|
||
abs = path.join(self.root, f)
|
||
} else if (isAbsolute(f) || f === '') {
|
||
abs = f
|
||
} else if (self.changedCwd) {
|
||
abs = path.resolve(self.cwd, f)
|
||
} else {
|
||
abs = path.resolve(f)
|
||
}
|
||
|
||
if (process.platform === 'win32')
|
||
abs = abs.replace(/\\/g, '/')
|
||
|
||
return abs
|
||
}
|
||
|
||
|
||
// Return true, if pattern ends with globstar '**', for the accompanying parent directory.
|
||
// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents
|
||
function isIgnored (self, path) {
|
||
if (!self.ignore.length)
|
||
return false
|
||
|
||
return self.ignore.some(function(item) {
|
||
return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path))
|
||
})
|
||
}
|
||
|
||
function childrenIgnored (self, path) {
|
||
if (!self.ignore.length)
|
||
return false
|
||
|
||
return self.ignore.some(function(item) {
|
||
return !!(item.gmatcher && item.gmatcher.match(path))
|
||
})
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/glob/glob.js":
|
||
/*!***********************************!*\
|
||
!*** ./node_modules/glob/glob.js ***!
|
||
\***********************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
// Approach:
|
||
//
|
||
// 1. Get the minimatch set
|
||
// 2. For each pattern in the set, PROCESS(pattern, false)
|
||
// 3. Store matches per-set, then uniq them
|
||
//
|
||
// PROCESS(pattern, inGlobStar)
|
||
// Get the first [n] items from pattern that are all strings
|
||
// Join these together. This is PREFIX.
|
||
// If there is no more remaining, then stat(PREFIX) and
|
||
// add to matches if it succeeds. END.
|
||
//
|
||
// If inGlobStar and PREFIX is symlink and points to dir
|
||
// set ENTRIES = []
|
||
// else readdir(PREFIX) as ENTRIES
|
||
// If fail, END
|
||
//
|
||
// with ENTRIES
|
||
// If pattern[n] is GLOBSTAR
|
||
// // handle the case where the globstar match is empty
|
||
// // by pruning it out, and testing the resulting pattern
|
||
// PROCESS(pattern[0..n] + pattern[n+1 .. $], false)
|
||
// // handle other cases.
|
||
// for ENTRY in ENTRIES (not dotfiles)
|
||
// // attach globstar + tail onto the entry
|
||
// // Mark that this entry is a globstar match
|
||
// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true)
|
||
//
|
||
// else // not globstar
|
||
// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
|
||
// Test ENTRY against pattern[n]
|
||
// If fails, continue
|
||
// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
|
||
//
|
||
// Caveat:
|
||
// Cache all stats and readdirs results to minimize syscall. Since all
|
||
// we ever care about is existence and directory-ness, we can just keep
|
||
// `true` for files, and [children,...] for directories, or `false` for
|
||
// things that don't exist.
|
||
|
||
module.exports = glob
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs")
|
||
var rp = __webpack_require__(/*! fs.realpath */ "./node_modules/fs.realpath/index.js")
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js")
|
||
var Minimatch = minimatch.Minimatch
|
||
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits.js")
|
||
var EE = __webpack_require__(/*! events */ "events").EventEmitter
|
||
var path = __webpack_require__(/*! path */ "path")
|
||
var assert = __webpack_require__(/*! assert */ "assert")
|
||
var isAbsolute = __webpack_require__(/*! path-is-absolute */ "./node_modules/path-is-absolute/index.js")
|
||
var globSync = __webpack_require__(/*! ./sync.js */ "./node_modules/glob/sync.js")
|
||
var common = __webpack_require__(/*! ./common.js */ "./node_modules/glob/common.js")
|
||
var alphasort = common.alphasort
|
||
var alphasorti = common.alphasorti
|
||
var setopts = common.setopts
|
||
var ownProp = common.ownProp
|
||
var inflight = __webpack_require__(/*! inflight */ "./node_modules/inflight/inflight.js")
|
||
var util = __webpack_require__(/*! util */ "util")
|
||
var childrenIgnored = common.childrenIgnored
|
||
var isIgnored = common.isIgnored
|
||
|
||
var once = __webpack_require__(/*! once */ "./node_modules/once/once.js")
|
||
|
||
function glob (pattern, options, cb) {
|
||
if (typeof options === 'function') cb = options, options = {}
|
||
if (!options) options = {}
|
||
|
||
if (options.sync) {
|
||
if (cb)
|
||
throw new TypeError('callback provided to sync glob')
|
||
return globSync(pattern, options)
|
||
}
|
||
|
||
return new Glob(pattern, options, cb)
|
||
}
|
||
|
||
glob.sync = globSync
|
||
var GlobSync = glob.GlobSync = globSync.GlobSync
|
||
|
||
// old api surface
|
||
glob.glob = glob
|
||
|
||
function extend (origin, add) {
|
||
if (add === null || typeof add !== 'object') {
|
||
return origin
|
||
}
|
||
|
||
var keys = Object.keys(add)
|
||
var i = keys.length
|
||
while (i--) {
|
||
origin[keys[i]] = add[keys[i]]
|
||
}
|
||
return origin
|
||
}
|
||
|
||
glob.hasMagic = function (pattern, options_) {
|
||
var options = extend({}, options_)
|
||
options.noprocess = true
|
||
|
||
var g = new Glob(pattern, options)
|
||
var set = g.minimatch.set
|
||
|
||
if (!pattern)
|
||
return false
|
||
|
||
if (set.length > 1)
|
||
return true
|
||
|
||
for (var j = 0; j < set[0].length; j++) {
|
||
if (typeof set[0][j] !== 'string')
|
||
return true
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
glob.Glob = Glob
|
||
inherits(Glob, EE)
|
||
function Glob (pattern, options, cb) {
|
||
if (typeof options === 'function') {
|
||
cb = options
|
||
options = null
|
||
}
|
||
|
||
if (options && options.sync) {
|
||
if (cb)
|
||
throw new TypeError('callback provided to sync glob')
|
||
return new GlobSync(pattern, options)
|
||
}
|
||
|
||
if (!(this instanceof Glob))
|
||
return new Glob(pattern, options, cb)
|
||
|
||
setopts(this, pattern, options)
|
||
this._didRealPath = false
|
||
|
||
// process each pattern in the minimatch set
|
||
var n = this.minimatch.set.length
|
||
|
||
// The matches are stored as {<filename>: true,...} so that
|
||
// duplicates are automagically pruned.
|
||
// Later, we do an Object.keys() on these.
|
||
// Keep them as a list so we can fill in when nonull is set.
|
||
this.matches = new Array(n)
|
||
|
||
if (typeof cb === 'function') {
|
||
cb = once(cb)
|
||
this.on('error', cb)
|
||
this.on('end', function (matches) {
|
||
cb(null, matches)
|
||
})
|
||
}
|
||
|
||
var self = this
|
||
this._processing = 0
|
||
|
||
this._emitQueue = []
|
||
this._processQueue = []
|
||
this.paused = false
|
||
|
||
if (this.noprocess)
|
||
return this
|
||
|
||
if (n === 0)
|
||
return done()
|
||
|
||
var sync = true
|
||
for (var i = 0; i < n; i ++) {
|
||
this._process(this.minimatch.set[i], i, false, done)
|
||
}
|
||
sync = false
|
||
|
||
function done () {
|
||
--self._processing
|
||
if (self._processing <= 0) {
|
||
if (sync) {
|
||
process.nextTick(function () {
|
||
self._finish()
|
||
})
|
||
} else {
|
||
self._finish()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Glob.prototype._finish = function () {
|
||
assert(this instanceof Glob)
|
||
if (this.aborted)
|
||
return
|
||
|
||
if (this.realpath && !this._didRealpath)
|
||
return this._realpath()
|
||
|
||
common.finish(this)
|
||
this.emit('end', this.found)
|
||
}
|
||
|
||
Glob.prototype._realpath = function () {
|
||
if (this._didRealpath)
|
||
return
|
||
|
||
this._didRealpath = true
|
||
|
||
var n = this.matches.length
|
||
if (n === 0)
|
||
return this._finish()
|
||
|
||
var self = this
|
||
for (var i = 0; i < this.matches.length; i++)
|
||
this._realpathSet(i, next)
|
||
|
||
function next () {
|
||
if (--n === 0)
|
||
self._finish()
|
||
}
|
||
}
|
||
|
||
Glob.prototype._realpathSet = function (index, cb) {
|
||
var matchset = this.matches[index]
|
||
if (!matchset)
|
||
return cb()
|
||
|
||
var found = Object.keys(matchset)
|
||
var self = this
|
||
var n = found.length
|
||
|
||
if (n === 0)
|
||
return cb()
|
||
|
||
var set = this.matches[index] = Object.create(null)
|
||
found.forEach(function (p, i) {
|
||
// If there's a problem with the stat, then it means that
|
||
// one or more of the links in the realpath couldn't be
|
||
// resolved. just return the abs value in that case.
|
||
p = self._makeAbs(p)
|
||
rp.realpath(p, self.realpathCache, function (er, real) {
|
||
if (!er)
|
||
set[real] = true
|
||
else if (er.syscall === 'stat')
|
||
set[p] = true
|
||
else
|
||
self.emit('error', er) // srsly wtf right here
|
||
|
||
if (--n === 0) {
|
||
self.matches[index] = set
|
||
cb()
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
Glob.prototype._mark = function (p) {
|
||
return common.mark(this, p)
|
||
}
|
||
|
||
Glob.prototype._makeAbs = function (f) {
|
||
return common.makeAbs(this, f)
|
||
}
|
||
|
||
Glob.prototype.abort = function () {
|
||
this.aborted = true
|
||
this.emit('abort')
|
||
}
|
||
|
||
Glob.prototype.pause = function () {
|
||
if (!this.paused) {
|
||
this.paused = true
|
||
this.emit('pause')
|
||
}
|
||
}
|
||
|
||
Glob.prototype.resume = function () {
|
||
if (this.paused) {
|
||
this.emit('resume')
|
||
this.paused = false
|
||
if (this._emitQueue.length) {
|
||
var eq = this._emitQueue.slice(0)
|
||
this._emitQueue.length = 0
|
||
for (var i = 0; i < eq.length; i ++) {
|
||
var e = eq[i]
|
||
this._emitMatch(e[0], e[1])
|
||
}
|
||
}
|
||
if (this._processQueue.length) {
|
||
var pq = this._processQueue.slice(0)
|
||
this._processQueue.length = 0
|
||
for (var i = 0; i < pq.length; i ++) {
|
||
var p = pq[i]
|
||
this._processing--
|
||
this._process(p[0], p[1], p[2], p[3])
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Glob.prototype._process = function (pattern, index, inGlobStar, cb) {
|
||
assert(this instanceof Glob)
|
||
assert(typeof cb === 'function')
|
||
|
||
if (this.aborted)
|
||
return
|
||
|
||
this._processing++
|
||
if (this.paused) {
|
||
this._processQueue.push([pattern, index, inGlobStar, cb])
|
||
return
|
||
}
|
||
|
||
//console.error('PROCESS %d', this._processing, pattern)
|
||
|
||
// Get the first [n] parts of pattern that are all strings.
|
||
var n = 0
|
||
while (typeof pattern[n] === 'string') {
|
||
n ++
|
||
}
|
||
// now n is the index of the first one that is *not* a string.
|
||
|
||
// see if there's anything else
|
||
var prefix
|
||
switch (n) {
|
||
// if not, then this is rather simple
|
||
case pattern.length:
|
||
this._processSimple(pattern.join('/'), index, cb)
|
||
return
|
||
|
||
case 0:
|
||
// pattern *starts* with some non-trivial item.
|
||
// going to readdir(cwd), but not include the prefix in matches.
|
||
prefix = null
|
||
break
|
||
|
||
default:
|
||
// pattern has some string bits in the front.
|
||
// whatever it starts with, whether that's 'absolute' like /foo/bar,
|
||
// or 'relative' like '../baz'
|
||
prefix = pattern.slice(0, n).join('/')
|
||
break
|
||
}
|
||
|
||
var remain = pattern.slice(n)
|
||
|
||
// get the list of entries.
|
||
var read
|
||
if (prefix === null)
|
||
read = '.'
|
||
else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) {
|
||
if (!prefix || !isAbsolute(prefix))
|
||
prefix = '/' + prefix
|
||
read = prefix
|
||
} else
|
||
read = prefix
|
||
|
||
var abs = this._makeAbs(read)
|
||
|
||
//if ignored, skip _processing
|
||
if (childrenIgnored(this, read))
|
||
return cb()
|
||
|
||
var isGlobStar = remain[0] === minimatch.GLOBSTAR
|
||
if (isGlobStar)
|
||
this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb)
|
||
else
|
||
this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb)
|
||
}
|
||
|
||
Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) {
|
||
var self = this
|
||
this._readdir(abs, inGlobStar, function (er, entries) {
|
||
return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
|
||
})
|
||
}
|
||
|
||
Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
|
||
|
||
// if the abs isn't a dir, then nothing can match!
|
||
if (!entries)
|
||
return cb()
|
||
|
||
// It will only match dot entries if it starts with a dot, or if
|
||
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
|
||
var pn = remain[0]
|
||
var negate = !!this.minimatch.negate
|
||
var rawGlob = pn._glob
|
||
var dotOk = this.dot || rawGlob.charAt(0) === '.'
|
||
|
||
var matchedEntries = []
|
||
for (var i = 0; i < entries.length; i++) {
|
||
var e = entries[i]
|
||
if (e.charAt(0) !== '.' || dotOk) {
|
||
var m
|
||
if (negate && !prefix) {
|
||
m = !e.match(pn)
|
||
} else {
|
||
m = e.match(pn)
|
||
}
|
||
if (m)
|
||
matchedEntries.push(e)
|
||
}
|
||
}
|
||
|
||
//console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries)
|
||
|
||
var len = matchedEntries.length
|
||
// If there are no matched entries, then nothing matches.
|
||
if (len === 0)
|
||
return cb()
|
||
|
||
// if this is the last remaining pattern bit, then no need for
|
||
// an additional stat *unless* the user has specified mark or
|
||
// stat explicitly. We know they exist, since readdir returned
|
||
// them.
|
||
|
||
if (remain.length === 1 && !this.mark && !this.stat) {
|
||
if (!this.matches[index])
|
||
this.matches[index] = Object.create(null)
|
||
|
||
for (var i = 0; i < len; i ++) {
|
||
var e = matchedEntries[i]
|
||
if (prefix) {
|
||
if (prefix !== '/')
|
||
e = prefix + '/' + e
|
||
else
|
||
e = prefix + e
|
||
}
|
||
|
||
if (e.charAt(0) === '/' && !this.nomount) {
|
||
e = path.join(this.root, e)
|
||
}
|
||
this._emitMatch(index, e)
|
||
}
|
||
// This was the last one, and no stats were needed
|
||
return cb()
|
||
}
|
||
|
||
// now test all matched entries as stand-ins for that part
|
||
// of the pattern.
|
||
remain.shift()
|
||
for (var i = 0; i < len; i ++) {
|
||
var e = matchedEntries[i]
|
||
var newPattern
|
||
if (prefix) {
|
||
if (prefix !== '/')
|
||
e = prefix + '/' + e
|
||
else
|
||
e = prefix + e
|
||
}
|
||
this._process([e].concat(remain), index, inGlobStar, cb)
|
||
}
|
||
cb()
|
||
}
|
||
|
||
Glob.prototype._emitMatch = function (index, e) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
if (isIgnored(this, e))
|
||
return
|
||
|
||
if (this.paused) {
|
||
this._emitQueue.push([index, e])
|
||
return
|
||
}
|
||
|
||
var abs = isAbsolute(e) ? e : this._makeAbs(e)
|
||
|
||
if (this.mark)
|
||
e = this._mark(e)
|
||
|
||
if (this.absolute)
|
||
e = abs
|
||
|
||
if (this.matches[index][e])
|
||
return
|
||
|
||
if (this.nodir) {
|
||
var c = this.cache[abs]
|
||
if (c === 'DIR' || Array.isArray(c))
|
||
return
|
||
}
|
||
|
||
this.matches[index][e] = true
|
||
|
||
var st = this.statCache[abs]
|
||
if (st)
|
||
this.emit('stat', e, st)
|
||
|
||
this.emit('match', e)
|
||
}
|
||
|
||
Glob.prototype._readdirInGlobStar = function (abs, cb) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
// follow all symlinked directories forever
|
||
// just proceed as if this is a non-globstar situation
|
||
if (this.follow)
|
||
return this._readdir(abs, false, cb)
|
||
|
||
var lstatkey = 'lstat\0' + abs
|
||
var self = this
|
||
var lstatcb = inflight(lstatkey, lstatcb_)
|
||
|
||
if (lstatcb)
|
||
fs.lstat(abs, lstatcb)
|
||
|
||
function lstatcb_ (er, lstat) {
|
||
if (er && er.code === 'ENOENT')
|
||
return cb()
|
||
|
||
var isSym = lstat && lstat.isSymbolicLink()
|
||
self.symlinks[abs] = isSym
|
||
|
||
// If it's not a symlink or a dir, then it's definitely a regular file.
|
||
// don't bother doing a readdir in that case.
|
||
if (!isSym && lstat && !lstat.isDirectory()) {
|
||
self.cache[abs] = 'FILE'
|
||
cb()
|
||
} else
|
||
self._readdir(abs, false, cb)
|
||
}
|
||
}
|
||
|
||
Glob.prototype._readdir = function (abs, inGlobStar, cb) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb)
|
||
if (!cb)
|
||
return
|
||
|
||
//console.error('RD %j %j', +inGlobStar, abs)
|
||
if (inGlobStar && !ownProp(this.symlinks, abs))
|
||
return this._readdirInGlobStar(abs, cb)
|
||
|
||
if (ownProp(this.cache, abs)) {
|
||
var c = this.cache[abs]
|
||
if (!c || c === 'FILE')
|
||
return cb()
|
||
|
||
if (Array.isArray(c))
|
||
return cb(null, c)
|
||
}
|
||
|
||
var self = this
|
||
fs.readdir(abs, readdirCb(this, abs, cb))
|
||
}
|
||
|
||
function readdirCb (self, abs, cb) {
|
||
return function (er, entries) {
|
||
if (er)
|
||
self._readdirError(abs, er, cb)
|
||
else
|
||
self._readdirEntries(abs, entries, cb)
|
||
}
|
||
}
|
||
|
||
Glob.prototype._readdirEntries = function (abs, entries, cb) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
// if we haven't asked to stat everything, then just
|
||
// assume that everything in there exists, so we can avoid
|
||
// having to stat it a second time.
|
||
if (!this.mark && !this.stat) {
|
||
for (var i = 0; i < entries.length; i ++) {
|
||
var e = entries[i]
|
||
if (abs === '/')
|
||
e = abs + e
|
||
else
|
||
e = abs + '/' + e
|
||
this.cache[e] = true
|
||
}
|
||
}
|
||
|
||
this.cache[abs] = entries
|
||
return cb(null, entries)
|
||
}
|
||
|
||
Glob.prototype._readdirError = function (f, er, cb) {
|
||
if (this.aborted)
|
||
return
|
||
|
||
// handle errors, and cache the information
|
||
switch (er.code) {
|
||
case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
|
||
case 'ENOTDIR': // totally normal. means it *does* exist.
|
||
var abs = this._makeAbs(f)
|
||
this.cache[abs] = 'FILE'
|
||
if (abs === this.cwdAbs) {
|
||
var error = new Error(er.code + ' invalid cwd ' + this.cwd)
|
||
error.path = this.cwd
|
||
error.code = er.code
|
||
this.emit('error', error)
|
||
this.abort()
|
||
}
|
||
break
|
||
|
||
case 'ENOENT': // not terribly unusual
|
||
case 'ELOOP':
|
||
case 'ENAMETOOLONG':
|
||
case 'UNKNOWN':
|
||
this.cache[this._makeAbs(f)] = false
|
||
break
|
||
|
||
default: // some unusual error. Treat as failure.
|
||
this.cache[this._makeAbs(f)] = false
|
||
if (this.strict) {
|
||
this.emit('error', er)
|
||
// If the error is handled, then we abort
|
||
// if not, we threw out of here
|
||
this.abort()
|
||
}
|
||
if (!this.silent)
|
||
console.error('glob error', er)
|
||
break
|
||
}
|
||
|
||
return cb()
|
||
}
|
||
|
||
Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) {
|
||
var self = this
|
||
this._readdir(abs, inGlobStar, function (er, entries) {
|
||
self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
|
||
})
|
||
}
|
||
|
||
|
||
Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
|
||
//console.error('pgs2', prefix, remain[0], entries)
|
||
|
||
// no entries means not a dir, so it can never have matches
|
||
// foo.txt/** doesn't match foo.txt
|
||
if (!entries)
|
||
return cb()
|
||
|
||
// test without the globstar, and with every child both below
|
||
// and replacing the globstar.
|
||
var remainWithoutGlobStar = remain.slice(1)
|
||
var gspref = prefix ? [ prefix ] : []
|
||
var noGlobStar = gspref.concat(remainWithoutGlobStar)
|
||
|
||
// the noGlobStar pattern exits the inGlobStar state
|
||
this._process(noGlobStar, index, false, cb)
|
||
|
||
var isSym = this.symlinks[abs]
|
||
var len = entries.length
|
||
|
||
// If it's a symlink, and we're in a globstar, then stop
|
||
if (isSym && inGlobStar)
|
||
return cb()
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
var e = entries[i]
|
||
if (e.charAt(0) === '.' && !this.dot)
|
||
continue
|
||
|
||
// these two cases enter the inGlobStar state
|
||
var instead = gspref.concat(entries[i], remainWithoutGlobStar)
|
||
this._process(instead, index, true, cb)
|
||
|
||
var below = gspref.concat(entries[i], remain)
|
||
this._process(below, index, true, cb)
|
||
}
|
||
|
||
cb()
|
||
}
|
||
|
||
Glob.prototype._processSimple = function (prefix, index, cb) {
|
||
// XXX review this. Shouldn't it be doing the mounting etc
|
||
// before doing stat? kinda weird?
|
||
var self = this
|
||
this._stat(prefix, function (er, exists) {
|
||
self._processSimple2(prefix, index, er, exists, cb)
|
||
})
|
||
}
|
||
Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) {
|
||
|
||
//console.error('ps2', prefix, exists)
|
||
|
||
if (!this.matches[index])
|
||
this.matches[index] = Object.create(null)
|
||
|
||
// If it doesn't exist, then just mark the lack of results
|
||
if (!exists)
|
||
return cb()
|
||
|
||
if (prefix && isAbsolute(prefix) && !this.nomount) {
|
||
var trail = /[\/\\]$/.test(prefix)
|
||
if (prefix.charAt(0) === '/') {
|
||
prefix = path.join(this.root, prefix)
|
||
} else {
|
||
prefix = path.resolve(this.root, prefix)
|
||
if (trail)
|
||
prefix += '/'
|
||
}
|
||
}
|
||
|
||
if (process.platform === 'win32')
|
||
prefix = prefix.replace(/\\/g, '/')
|
||
|
||
// Mark this as a match
|
||
this._emitMatch(index, prefix)
|
||
cb()
|
||
}
|
||
|
||
// Returns either 'DIR', 'FILE', or false
|
||
Glob.prototype._stat = function (f, cb) {
|
||
var abs = this._makeAbs(f)
|
||
var needDir = f.slice(-1) === '/'
|
||
|
||
if (f.length > this.maxLength)
|
||
return cb()
|
||
|
||
if (!this.stat && ownProp(this.cache, abs)) {
|
||
var c = this.cache[abs]
|
||
|
||
if (Array.isArray(c))
|
||
c = 'DIR'
|
||
|
||
// It exists, but maybe not how we need it
|
||
if (!needDir || c === 'DIR')
|
||
return cb(null, c)
|
||
|
||
if (needDir && c === 'FILE')
|
||
return cb()
|
||
|
||
// otherwise we have to stat, because maybe c=true
|
||
// if we know it exists, but not what it is.
|
||
}
|
||
|
||
var exists
|
||
var stat = this.statCache[abs]
|
||
if (stat !== undefined) {
|
||
if (stat === false)
|
||
return cb(null, stat)
|
||
else {
|
||
var type = stat.isDirectory() ? 'DIR' : 'FILE'
|
||
if (needDir && type === 'FILE')
|
||
return cb()
|
||
else
|
||
return cb(null, type, stat)
|
||
}
|
||
}
|
||
|
||
var self = this
|
||
var statcb = inflight('stat\0' + abs, lstatcb_)
|
||
if (statcb)
|
||
fs.lstat(abs, statcb)
|
||
|
||
function lstatcb_ (er, lstat) {
|
||
if (lstat && lstat.isSymbolicLink()) {
|
||
// If it's a symlink, then treat it as the target, unless
|
||
// the target does not exist, then treat it as a file.
|
||
return fs.stat(abs, function (er, stat) {
|
||
if (er)
|
||
self._stat2(f, abs, null, lstat, cb)
|
||
else
|
||
self._stat2(f, abs, er, stat, cb)
|
||
})
|
||
} else {
|
||
self._stat2(f, abs, er, lstat, cb)
|
||
}
|
||
}
|
||
}
|
||
|
||
Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
|
||
if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
|
||
this.statCache[abs] = false
|
||
return cb()
|
||
}
|
||
|
||
var needDir = f.slice(-1) === '/'
|
||
this.statCache[abs] = stat
|
||
|
||
if (abs.slice(-1) === '/' && stat && !stat.isDirectory())
|
||
return cb(null, false, stat)
|
||
|
||
var c = true
|
||
if (stat)
|
||
c = stat.isDirectory() ? 'DIR' : 'FILE'
|
||
this.cache[abs] = this.cache[abs] || c
|
||
|
||
if (needDir && c === 'FILE')
|
||
return cb()
|
||
|
||
return cb(null, c, stat)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/glob/sync.js":
|
||
/*!***********************************!*\
|
||
!*** ./node_modules/glob/sync.js ***!
|
||
\***********************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
module.exports = globSync
|
||
globSync.GlobSync = GlobSync
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs")
|
||
var rp = __webpack_require__(/*! fs.realpath */ "./node_modules/fs.realpath/index.js")
|
||
var minimatch = __webpack_require__(/*! minimatch */ "./node_modules/minimatch/minimatch.js")
|
||
var Minimatch = minimatch.Minimatch
|
||
var Glob = __webpack_require__(/*! ./glob.js */ "./node_modules/glob/glob.js").Glob
|
||
var util = __webpack_require__(/*! util */ "util")
|
||
var path = __webpack_require__(/*! path */ "path")
|
||
var assert = __webpack_require__(/*! assert */ "assert")
|
||
var isAbsolute = __webpack_require__(/*! path-is-absolute */ "./node_modules/path-is-absolute/index.js")
|
||
var common = __webpack_require__(/*! ./common.js */ "./node_modules/glob/common.js")
|
||
var alphasort = common.alphasort
|
||
var alphasorti = common.alphasorti
|
||
var setopts = common.setopts
|
||
var ownProp = common.ownProp
|
||
var childrenIgnored = common.childrenIgnored
|
||
var isIgnored = common.isIgnored
|
||
|
||
function globSync (pattern, options) {
|
||
if (typeof options === 'function' || arguments.length === 3)
|
||
throw new TypeError('callback provided to sync glob\n'+
|
||
'See: https://github.com/isaacs/node-glob/issues/167')
|
||
|
||
return new GlobSync(pattern, options).found
|
||
}
|
||
|
||
function GlobSync (pattern, options) {
|
||
if (!pattern)
|
||
throw new Error('must provide pattern')
|
||
|
||
if (typeof options === 'function' || arguments.length === 3)
|
||
throw new TypeError('callback provided to sync glob\n'+
|
||
'See: https://github.com/isaacs/node-glob/issues/167')
|
||
|
||
if (!(this instanceof GlobSync))
|
||
return new GlobSync(pattern, options)
|
||
|
||
setopts(this, pattern, options)
|
||
|
||
if (this.noprocess)
|
||
return this
|
||
|
||
var n = this.minimatch.set.length
|
||
this.matches = new Array(n)
|
||
for (var i = 0; i < n; i ++) {
|
||
this._process(this.minimatch.set[i], i, false)
|
||
}
|
||
this._finish()
|
||
}
|
||
|
||
GlobSync.prototype._finish = function () {
|
||
assert(this instanceof GlobSync)
|
||
if (this.realpath) {
|
||
var self = this
|
||
this.matches.forEach(function (matchset, index) {
|
||
var set = self.matches[index] = Object.create(null)
|
||
for (var p in matchset) {
|
||
try {
|
||
p = self._makeAbs(p)
|
||
var real = rp.realpathSync(p, self.realpathCache)
|
||
set[real] = true
|
||
} catch (er) {
|
||
if (er.syscall === 'stat')
|
||
set[self._makeAbs(p)] = true
|
||
else
|
||
throw er
|
||
}
|
||
}
|
||
})
|
||
}
|
||
common.finish(this)
|
||
}
|
||
|
||
|
||
GlobSync.prototype._process = function (pattern, index, inGlobStar) {
|
||
assert(this instanceof GlobSync)
|
||
|
||
// Get the first [n] parts of pattern that are all strings.
|
||
var n = 0
|
||
while (typeof pattern[n] === 'string') {
|
||
n ++
|
||
}
|
||
// now n is the index of the first one that is *not* a string.
|
||
|
||
// See if there's anything else
|
||
var prefix
|
||
switch (n) {
|
||
// if not, then this is rather simple
|
||
case pattern.length:
|
||
this._processSimple(pattern.join('/'), index)
|
||
return
|
||
|
||
case 0:
|
||
// pattern *starts* with some non-trivial item.
|
||
// going to readdir(cwd), but not include the prefix in matches.
|
||
prefix = null
|
||
break
|
||
|
||
default:
|
||
// pattern has some string bits in the front.
|
||
// whatever it starts with, whether that's 'absolute' like /foo/bar,
|
||
// or 'relative' like '../baz'
|
||
prefix = pattern.slice(0, n).join('/')
|
||
break
|
||
}
|
||
|
||
var remain = pattern.slice(n)
|
||
|
||
// get the list of entries.
|
||
var read
|
||
if (prefix === null)
|
||
read = '.'
|
||
else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) {
|
||
if (!prefix || !isAbsolute(prefix))
|
||
prefix = '/' + prefix
|
||
read = prefix
|
||
} else
|
||
read = prefix
|
||
|
||
var abs = this._makeAbs(read)
|
||
|
||
//if ignored, skip processing
|
||
if (childrenIgnored(this, read))
|
||
return
|
||
|
||
var isGlobStar = remain[0] === minimatch.GLOBSTAR
|
||
if (isGlobStar)
|
||
this._processGlobStar(prefix, read, abs, remain, index, inGlobStar)
|
||
else
|
||
this._processReaddir(prefix, read, abs, remain, index, inGlobStar)
|
||
}
|
||
|
||
|
||
GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) {
|
||
var entries = this._readdir(abs, inGlobStar)
|
||
|
||
// if the abs isn't a dir, then nothing can match!
|
||
if (!entries)
|
||
return
|
||
|
||
// It will only match dot entries if it starts with a dot, or if
|
||
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
|
||
var pn = remain[0]
|
||
var negate = !!this.minimatch.negate
|
||
var rawGlob = pn._glob
|
||
var dotOk = this.dot || rawGlob.charAt(0) === '.'
|
||
|
||
var matchedEntries = []
|
||
for (var i = 0; i < entries.length; i++) {
|
||
var e = entries[i]
|
||
if (e.charAt(0) !== '.' || dotOk) {
|
||
var m
|
||
if (negate && !prefix) {
|
||
m = !e.match(pn)
|
||
} else {
|
||
m = e.match(pn)
|
||
}
|
||
if (m)
|
||
matchedEntries.push(e)
|
||
}
|
||
}
|
||
|
||
var len = matchedEntries.length
|
||
// If there are no matched entries, then nothing matches.
|
||
if (len === 0)
|
||
return
|
||
|
||
// if this is the last remaining pattern bit, then no need for
|
||
// an additional stat *unless* the user has specified mark or
|
||
// stat explicitly. We know they exist, since readdir returned
|
||
// them.
|
||
|
||
if (remain.length === 1 && !this.mark && !this.stat) {
|
||
if (!this.matches[index])
|
||
this.matches[index] = Object.create(null)
|
||
|
||
for (var i = 0; i < len; i ++) {
|
||
var e = matchedEntries[i]
|
||
if (prefix) {
|
||
if (prefix.slice(-1) !== '/')
|
||
e = prefix + '/' + e
|
||
else
|
||
e = prefix + e
|
||
}
|
||
|
||
if (e.charAt(0) === '/' && !this.nomount) {
|
||
e = path.join(this.root, e)
|
||
}
|
||
this._emitMatch(index, e)
|
||
}
|
||
// This was the last one, and no stats were needed
|
||
return
|
||
}
|
||
|
||
// now test all matched entries as stand-ins for that part
|
||
// of the pattern.
|
||
remain.shift()
|
||
for (var i = 0; i < len; i ++) {
|
||
var e = matchedEntries[i]
|
||
var newPattern
|
||
if (prefix)
|
||
newPattern = [prefix, e]
|
||
else
|
||
newPattern = [e]
|
||
this._process(newPattern.concat(remain), index, inGlobStar)
|
||
}
|
||
}
|
||
|
||
|
||
GlobSync.prototype._emitMatch = function (index, e) {
|
||
if (isIgnored(this, e))
|
||
return
|
||
|
||
var abs = this._makeAbs(e)
|
||
|
||
if (this.mark)
|
||
e = this._mark(e)
|
||
|
||
if (this.absolute) {
|
||
e = abs
|
||
}
|
||
|
||
if (this.matches[index][e])
|
||
return
|
||
|
||
if (this.nodir) {
|
||
var c = this.cache[abs]
|
||
if (c === 'DIR' || Array.isArray(c))
|
||
return
|
||
}
|
||
|
||
this.matches[index][e] = true
|
||
|
||
if (this.stat)
|
||
this._stat(e)
|
||
}
|
||
|
||
|
||
GlobSync.prototype._readdirInGlobStar = function (abs) {
|
||
// follow all symlinked directories forever
|
||
// just proceed as if this is a non-globstar situation
|
||
if (this.follow)
|
||
return this._readdir(abs, false)
|
||
|
||
var entries
|
||
var lstat
|
||
var stat
|
||
try {
|
||
lstat = fs.lstatSync(abs)
|
||
} catch (er) {
|
||
if (er.code === 'ENOENT') {
|
||
// lstat failed, doesn't exist
|
||
return null
|
||
}
|
||
}
|
||
|
||
var isSym = lstat && lstat.isSymbolicLink()
|
||
this.symlinks[abs] = isSym
|
||
|
||
// If it's not a symlink or a dir, then it's definitely a regular file.
|
||
// don't bother doing a readdir in that case.
|
||
if (!isSym && lstat && !lstat.isDirectory())
|
||
this.cache[abs] = 'FILE'
|
||
else
|
||
entries = this._readdir(abs, false)
|
||
|
||
return entries
|
||
}
|
||
|
||
GlobSync.prototype._readdir = function (abs, inGlobStar) {
|
||
var entries
|
||
|
||
if (inGlobStar && !ownProp(this.symlinks, abs))
|
||
return this._readdirInGlobStar(abs)
|
||
|
||
if (ownProp(this.cache, abs)) {
|
||
var c = this.cache[abs]
|
||
if (!c || c === 'FILE')
|
||
return null
|
||
|
||
if (Array.isArray(c))
|
||
return c
|
||
}
|
||
|
||
try {
|
||
return this._readdirEntries(abs, fs.readdirSync(abs))
|
||
} catch (er) {
|
||
this._readdirError(abs, er)
|
||
return null
|
||
}
|
||
}
|
||
|
||
GlobSync.prototype._readdirEntries = function (abs, entries) {
|
||
// if we haven't asked to stat everything, then just
|
||
// assume that everything in there exists, so we can avoid
|
||
// having to stat it a second time.
|
||
if (!this.mark && !this.stat) {
|
||
for (var i = 0; i < entries.length; i ++) {
|
||
var e = entries[i]
|
||
if (abs === '/')
|
||
e = abs + e
|
||
else
|
||
e = abs + '/' + e
|
||
this.cache[e] = true
|
||
}
|
||
}
|
||
|
||
this.cache[abs] = entries
|
||
|
||
// mark and cache dir-ness
|
||
return entries
|
||
}
|
||
|
||
GlobSync.prototype._readdirError = function (f, er) {
|
||
// handle errors, and cache the information
|
||
switch (er.code) {
|
||
case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
|
||
case 'ENOTDIR': // totally normal. means it *does* exist.
|
||
var abs = this._makeAbs(f)
|
||
this.cache[abs] = 'FILE'
|
||
if (abs === this.cwdAbs) {
|
||
var error = new Error(er.code + ' invalid cwd ' + this.cwd)
|
||
error.path = this.cwd
|
||
error.code = er.code
|
||
throw error
|
||
}
|
||
break
|
||
|
||
case 'ENOENT': // not terribly unusual
|
||
case 'ELOOP':
|
||
case 'ENAMETOOLONG':
|
||
case 'UNKNOWN':
|
||
this.cache[this._makeAbs(f)] = false
|
||
break
|
||
|
||
default: // some unusual error. Treat as failure.
|
||
this.cache[this._makeAbs(f)] = false
|
||
if (this.strict)
|
||
throw er
|
||
if (!this.silent)
|
||
console.error('glob error', er)
|
||
break
|
||
}
|
||
}
|
||
|
||
GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) {
|
||
|
||
var entries = this._readdir(abs, inGlobStar)
|
||
|
||
// no entries means not a dir, so it can never have matches
|
||
// foo.txt/** doesn't match foo.txt
|
||
if (!entries)
|
||
return
|
||
|
||
// test without the globstar, and with every child both below
|
||
// and replacing the globstar.
|
||
var remainWithoutGlobStar = remain.slice(1)
|
||
var gspref = prefix ? [ prefix ] : []
|
||
var noGlobStar = gspref.concat(remainWithoutGlobStar)
|
||
|
||
// the noGlobStar pattern exits the inGlobStar state
|
||
this._process(noGlobStar, index, false)
|
||
|
||
var len = entries.length
|
||
var isSym = this.symlinks[abs]
|
||
|
||
// If it's a symlink, and we're in a globstar, then stop
|
||
if (isSym && inGlobStar)
|
||
return
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
var e = entries[i]
|
||
if (e.charAt(0) === '.' && !this.dot)
|
||
continue
|
||
|
||
// these two cases enter the inGlobStar state
|
||
var instead = gspref.concat(entries[i], remainWithoutGlobStar)
|
||
this._process(instead, index, true)
|
||
|
||
var below = gspref.concat(entries[i], remain)
|
||
this._process(below, index, true)
|
||
}
|
||
}
|
||
|
||
GlobSync.prototype._processSimple = function (prefix, index) {
|
||
// XXX review this. Shouldn't it be doing the mounting etc
|
||
// before doing stat? kinda weird?
|
||
var exists = this._stat(prefix)
|
||
|
||
if (!this.matches[index])
|
||
this.matches[index] = Object.create(null)
|
||
|
||
// If it doesn't exist, then just mark the lack of results
|
||
if (!exists)
|
||
return
|
||
|
||
if (prefix && isAbsolute(prefix) && !this.nomount) {
|
||
var trail = /[\/\\]$/.test(prefix)
|
||
if (prefix.charAt(0) === '/') {
|
||
prefix = path.join(this.root, prefix)
|
||
} else {
|
||
prefix = path.resolve(this.root, prefix)
|
||
if (trail)
|
||
prefix += '/'
|
||
}
|
||
}
|
||
|
||
if (process.platform === 'win32')
|
||
prefix = prefix.replace(/\\/g, '/')
|
||
|
||
// Mark this as a match
|
||
this._emitMatch(index, prefix)
|
||
}
|
||
|
||
// Returns either 'DIR', 'FILE', or false
|
||
GlobSync.prototype._stat = function (f) {
|
||
var abs = this._makeAbs(f)
|
||
var needDir = f.slice(-1) === '/'
|
||
|
||
if (f.length > this.maxLength)
|
||
return false
|
||
|
||
if (!this.stat && ownProp(this.cache, abs)) {
|
||
var c = this.cache[abs]
|
||
|
||
if (Array.isArray(c))
|
||
c = 'DIR'
|
||
|
||
// It exists, but maybe not how we need it
|
||
if (!needDir || c === 'DIR')
|
||
return c
|
||
|
||
if (needDir && c === 'FILE')
|
||
return false
|
||
|
||
// otherwise we have to stat, because maybe c=true
|
||
// if we know it exists, but not what it is.
|
||
}
|
||
|
||
var exists
|
||
var stat = this.statCache[abs]
|
||
if (!stat) {
|
||
var lstat
|
||
try {
|
||
lstat = fs.lstatSync(abs)
|
||
} catch (er) {
|
||
if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
|
||
this.statCache[abs] = false
|
||
return false
|
||
}
|
||
}
|
||
|
||
if (lstat && lstat.isSymbolicLink()) {
|
||
try {
|
||
stat = fs.statSync(abs)
|
||
} catch (er) {
|
||
stat = lstat
|
||
}
|
||
} else {
|
||
stat = lstat
|
||
}
|
||
}
|
||
|
||
this.statCache[abs] = stat
|
||
|
||
var c = true
|
||
if (stat)
|
||
c = stat.isDirectory() ? 'DIR' : 'FILE'
|
||
|
||
this.cache[abs] = this.cache[abs] || c
|
||
|
||
if (needDir && c === 'FILE')
|
||
return false
|
||
|
||
return c
|
||
}
|
||
|
||
GlobSync.prototype._mark = function (p) {
|
||
return common.mark(this, p)
|
||
}
|
||
|
||
GlobSync.prototype._makeAbs = function (f) {
|
||
return common.makeAbs(this, f)
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inflight/inflight.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/inflight/inflight.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var wrappy = __webpack_require__(/*! wrappy */ "./node_modules/wrappy/wrappy.js")
|
||
var reqs = Object.create(null)
|
||
var once = __webpack_require__(/*! once */ "./node_modules/once/once.js")
|
||
|
||
module.exports = wrappy(inflight)
|
||
|
||
function inflight (key, cb) {
|
||
if (reqs[key]) {
|
||
reqs[key].push(cb)
|
||
return null
|
||
} else {
|
||
reqs[key] = [cb]
|
||
return makeres(key)
|
||
}
|
||
}
|
||
|
||
function makeres (key) {
|
||
return once(function RES () {
|
||
var cbs = reqs[key]
|
||
var len = cbs.length
|
||
var args = slice(arguments)
|
||
|
||
// XXX It's somewhat ambiguous whether a new callback added in this
|
||
// pass should be queued for later execution if something in the
|
||
// list of callbacks throws, or if it should just be discarded.
|
||
// However, it's such an edge case that it hardly matters, and either
|
||
// choice is likely as surprising as the other.
|
||
// As it happens, we do go ahead and schedule it for later execution.
|
||
try {
|
||
for (var i = 0; i < len; i++) {
|
||
cbs[i].apply(null, args)
|
||
}
|
||
} finally {
|
||
if (cbs.length > len) {
|
||
// added more in the interim.
|
||
// de-zalgo, just in case, but don't call again.
|
||
cbs.splice(0, len)
|
||
process.nextTick(function () {
|
||
RES.apply(null, args)
|
||
})
|
||
} else {
|
||
delete reqs[key]
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
function slice (args) {
|
||
var length = args.length
|
||
var array = []
|
||
|
||
for (var i = 0; i < length; i++) array[i] = args[i]
|
||
return array
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inherits/inherits.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/inherits/inherits.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
try {
|
||
var util = __webpack_require__(/*! util */ "util");
|
||
/* istanbul ignore next */
|
||
if (typeof util.inherits !== 'function') throw '';
|
||
module.exports = util.inherits;
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
module.exports = __webpack_require__(/*! ./inherits_browser.js */ "./node_modules/inherits/inherits_browser.js");
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inherits/inherits_browser.js":
|
||
/*!***************************************************!*\
|
||
!*** ./node_modules/inherits/inherits_browser.js ***!
|
||
\***************************************************/
|
||
/***/ ((module) => {
|
||
|
||
if (typeof Object.create === 'function') {
|
||
// implementation from standard node.js 'util' module
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
if (superCtor) {
|
||
ctor.super_ = superCtor
|
||
ctor.prototype = Object.create(superCtor.prototype, {
|
||
constructor: {
|
||
value: ctor,
|
||
enumerable: false,
|
||
writable: true,
|
||
configurable: true
|
||
}
|
||
})
|
||
}
|
||
};
|
||
} else {
|
||
// old school shim for old browsers
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
if (superCtor) {
|
||
ctor.super_ = superCtor
|
||
var TempCtor = function () {}
|
||
TempCtor.prototype = superCtor.prototype
|
||
ctor.prototype = new TempCtor()
|
||
ctor.prototype.constructor = ctor
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/decorator_utils.js":
|
||
/*!******************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/decorator_utils.js ***!
|
||
\******************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.tagProperty = exports.tagParameter = exports.decorate = void 0;
|
||
var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
function tagParameter(annotationTarget, propertyName, parameterIndex, metadata) {
|
||
var metadataKey = METADATA_KEY.TAGGED;
|
||
_tagParameterOrProperty(metadataKey, annotationTarget, propertyName, metadata, parameterIndex);
|
||
}
|
||
exports.tagParameter = tagParameter;
|
||
function tagProperty(annotationTarget, propertyName, metadata) {
|
||
var metadataKey = METADATA_KEY.TAGGED_PROP;
|
||
_tagParameterOrProperty(metadataKey, annotationTarget.constructor, propertyName, metadata);
|
||
}
|
||
exports.tagProperty = tagProperty;
|
||
function _tagParameterOrProperty(metadataKey, annotationTarget, propertyName, metadata, parameterIndex) {
|
||
var paramsOrPropertiesMetadata = {};
|
||
var isParameterDecorator = (typeof parameterIndex === "number");
|
||
var key = (parameterIndex !== undefined && isParameterDecorator) ? parameterIndex.toString() : propertyName;
|
||
if (isParameterDecorator && propertyName !== undefined) {
|
||
throw new Error(ERROR_MSGS.INVALID_DECORATOR_OPERATION);
|
||
}
|
||
if (Reflect.hasOwnMetadata(metadataKey, annotationTarget)) {
|
||
paramsOrPropertiesMetadata = Reflect.getMetadata(metadataKey, annotationTarget);
|
||
}
|
||
var paramOrPropertyMetadata = paramsOrPropertiesMetadata[key];
|
||
if (!Array.isArray(paramOrPropertyMetadata)) {
|
||
paramOrPropertyMetadata = [];
|
||
}
|
||
else {
|
||
for (var _i = 0, paramOrPropertyMetadata_1 = paramOrPropertyMetadata; _i < paramOrPropertyMetadata_1.length; _i++) {
|
||
var m = paramOrPropertyMetadata_1[_i];
|
||
if (m.key === metadata.key) {
|
||
throw new Error(ERROR_MSGS.DUPLICATED_METADATA + " " + m.key.toString());
|
||
}
|
||
}
|
||
}
|
||
paramOrPropertyMetadata.push(metadata);
|
||
paramsOrPropertiesMetadata[key] = paramOrPropertyMetadata;
|
||
Reflect.defineMetadata(metadataKey, paramsOrPropertiesMetadata, annotationTarget);
|
||
}
|
||
function _decorate(decorators, target) {
|
||
Reflect.decorate(decorators, target);
|
||
}
|
||
function _param(paramIndex, decorator) {
|
||
return function (target, key) { decorator(target, key, paramIndex); };
|
||
}
|
||
function decorate(decorator, target, parameterIndex) {
|
||
if (typeof parameterIndex === "number") {
|
||
_decorate([_param(parameterIndex, decorator)], target);
|
||
}
|
||
else if (typeof parameterIndex === "string") {
|
||
Reflect.decorate([decorator], target, parameterIndex);
|
||
}
|
||
else {
|
||
_decorate([decorator], target);
|
||
}
|
||
}
|
||
exports.decorate = decorate;
|
||
//# sourceMappingURL=decorator_utils.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/inject.js":
|
||
/*!*********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/inject.js ***!
|
||
\*********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.inject = exports.LazyServiceIdentifer = void 0;
|
||
var error_msgs_1 = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js");
|
||
var LazyServiceIdentifer = (function () {
|
||
function LazyServiceIdentifer(cb) {
|
||
this._cb = cb;
|
||
}
|
||
LazyServiceIdentifer.prototype.unwrap = function () {
|
||
return this._cb();
|
||
};
|
||
return LazyServiceIdentifer;
|
||
}());
|
||
exports.LazyServiceIdentifer = LazyServiceIdentifer;
|
||
function inject(serviceIdentifier) {
|
||
return function (target, targetKey, index) {
|
||
if (serviceIdentifier === undefined) {
|
||
throw new Error(error_msgs_1.UNDEFINED_INJECT_ANNOTATION(target.name));
|
||
}
|
||
var metadata = new metadata_1.Metadata(METADATA_KEY.INJECT_TAG, serviceIdentifier);
|
||
if (typeof index === "number") {
|
||
decorator_utils_1.tagParameter(target, targetKey, index, metadata);
|
||
}
|
||
else {
|
||
decorator_utils_1.tagProperty(target, targetKey, metadata);
|
||
}
|
||
};
|
||
}
|
||
exports.inject = inject;
|
||
//# sourceMappingURL=inject.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/injectable.js":
|
||
/*!*************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/injectable.js ***!
|
||
\*************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.injectable = void 0;
|
||
var ERRORS_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
function injectable() {
|
||
return function (target) {
|
||
if (Reflect.hasOwnMetadata(METADATA_KEY.PARAM_TYPES, target)) {
|
||
throw new Error(ERRORS_MSGS.DUPLICATED_INJECTABLE_DECORATOR);
|
||
}
|
||
var types = Reflect.getMetadata(METADATA_KEY.DESIGN_PARAM_TYPES, target) || [];
|
||
Reflect.defineMetadata(METADATA_KEY.PARAM_TYPES, types, target);
|
||
return target;
|
||
};
|
||
}
|
||
exports.injectable = injectable;
|
||
//# sourceMappingURL=injectable.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/multi_inject.js":
|
||
/*!***************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/multi_inject.js ***!
|
||
\***************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.multiInject = void 0;
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js");
|
||
function multiInject(serviceIdentifier) {
|
||
return function (target, targetKey, index) {
|
||
var metadata = new metadata_1.Metadata(METADATA_KEY.MULTI_INJECT_TAG, serviceIdentifier);
|
||
if (typeof index === "number") {
|
||
decorator_utils_1.tagParameter(target, targetKey, index, metadata);
|
||
}
|
||
else {
|
||
decorator_utils_1.tagProperty(target, targetKey, metadata);
|
||
}
|
||
};
|
||
}
|
||
exports.multiInject = multiInject;
|
||
//# sourceMappingURL=multi_inject.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/named.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/named.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.named = void 0;
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js");
|
||
function named(name) {
|
||
return function (target, targetKey, index) {
|
||
var metadata = new metadata_1.Metadata(METADATA_KEY.NAMED_TAG, name);
|
||
if (typeof index === "number") {
|
||
decorator_utils_1.tagParameter(target, targetKey, index, metadata);
|
||
}
|
||
else {
|
||
decorator_utils_1.tagProperty(target, targetKey, metadata);
|
||
}
|
||
};
|
||
}
|
||
exports.named = named;
|
||
//# sourceMappingURL=named.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/optional.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/optional.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.optional = void 0;
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js");
|
||
function optional() {
|
||
return function (target, targetKey, index) {
|
||
var metadata = new metadata_1.Metadata(METADATA_KEY.OPTIONAL_TAG, true);
|
||
if (typeof index === "number") {
|
||
decorator_utils_1.tagParameter(target, targetKey, index, metadata);
|
||
}
|
||
else {
|
||
decorator_utils_1.tagProperty(target, targetKey, metadata);
|
||
}
|
||
};
|
||
}
|
||
exports.optional = optional;
|
||
//# sourceMappingURL=optional.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/post_construct.js":
|
||
/*!*****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/post_construct.js ***!
|
||
\*****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.postConstruct = void 0;
|
||
var ERRORS_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
function postConstruct() {
|
||
return function (target, propertyKey, descriptor) {
|
||
var metadata = new metadata_1.Metadata(METADATA_KEY.POST_CONSTRUCT, propertyKey);
|
||
if (Reflect.hasOwnMetadata(METADATA_KEY.POST_CONSTRUCT, target.constructor)) {
|
||
throw new Error(ERRORS_MSGS.MULTIPLE_POST_CONSTRUCT_METHODS);
|
||
}
|
||
Reflect.defineMetadata(METADATA_KEY.POST_CONSTRUCT, metadata, target.constructor);
|
||
};
|
||
}
|
||
exports.postConstruct = postConstruct;
|
||
//# sourceMappingURL=post_construct.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/tagged.js":
|
||
/*!*********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/tagged.js ***!
|
||
\*********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.tagged = void 0;
|
||
var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js");
|
||
function tagged(metadataKey, metadataValue) {
|
||
return function (target, targetKey, index) {
|
||
var metadata = new metadata_1.Metadata(metadataKey, metadataValue);
|
||
if (typeof index === "number") {
|
||
decorator_utils_1.tagParameter(target, targetKey, index, metadata);
|
||
}
|
||
else {
|
||
decorator_utils_1.tagProperty(target, targetKey, metadata);
|
||
}
|
||
};
|
||
}
|
||
exports.tagged = tagged;
|
||
//# sourceMappingURL=tagged.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/target_name.js":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/target_name.js ***!
|
||
\**************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.targetName = void 0;
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js");
|
||
function targetName(name) {
|
||
return function (target, targetKey, index) {
|
||
var metadata = new metadata_1.Metadata(METADATA_KEY.NAME_TAG, name);
|
||
decorator_utils_1.tagParameter(target, targetKey, index, metadata);
|
||
};
|
||
}
|
||
exports.targetName = targetName;
|
||
//# sourceMappingURL=target_name.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/annotation/unmanaged.js":
|
||
/*!************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/annotation/unmanaged.js ***!
|
||
\************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.unmanaged = void 0;
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var decorator_utils_1 = __webpack_require__(/*! ./decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js");
|
||
function unmanaged() {
|
||
return function (target, targetKey, index) {
|
||
var metadata = new metadata_1.Metadata(METADATA_KEY.UNMANAGED_TAG, true);
|
||
decorator_utils_1.tagParameter(target, targetKey, index, metadata);
|
||
};
|
||
}
|
||
exports.unmanaged = unmanaged;
|
||
//# sourceMappingURL=unmanaged.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/bindings/binding.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/bindings/binding.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Binding = void 0;
|
||
var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js");
|
||
var Binding = (function () {
|
||
function Binding(serviceIdentifier, scope) {
|
||
this.id = id_1.id();
|
||
this.activated = false;
|
||
this.serviceIdentifier = serviceIdentifier;
|
||
this.scope = scope;
|
||
this.type = literal_types_1.BindingTypeEnum.Invalid;
|
||
this.constraint = function (request) { return true; };
|
||
this.implementationType = null;
|
||
this.cache = null;
|
||
this.factory = null;
|
||
this.provider = null;
|
||
this.onActivation = null;
|
||
this.dynamicValue = null;
|
||
}
|
||
Binding.prototype.clone = function () {
|
||
var clone = new Binding(this.serviceIdentifier, this.scope);
|
||
clone.activated = (clone.scope === literal_types_1.BindingScopeEnum.Singleton) ? this.activated : false;
|
||
clone.implementationType = this.implementationType;
|
||
clone.dynamicValue = this.dynamicValue;
|
||
clone.scope = this.scope;
|
||
clone.type = this.type;
|
||
clone.factory = this.factory;
|
||
clone.provider = this.provider;
|
||
clone.constraint = this.constraint;
|
||
clone.onActivation = this.onActivation;
|
||
clone.cache = this.cache;
|
||
return clone;
|
||
};
|
||
return Binding;
|
||
}());
|
||
exports.Binding = Binding;
|
||
//# sourceMappingURL=binding.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/bindings/binding_count.js":
|
||
/*!**************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/bindings/binding_count.js ***!
|
||
\**************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingCount = void 0;
|
||
var BindingCount = {
|
||
MultipleBindingsAvailable: 2,
|
||
NoBindingsAvailable: 0,
|
||
OnlyOneBindingAvailable: 1
|
||
};
|
||
exports.BindingCount = BindingCount;
|
||
//# sourceMappingURL=binding_count.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/constants/error_msgs.js":
|
||
/*!************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/constants/error_msgs.js ***!
|
||
\************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.STACK_OVERFLOW = exports.CIRCULAR_DEPENDENCY_IN_FACTORY = exports.POST_CONSTRUCT_ERROR = exports.MULTIPLE_POST_CONSTRUCT_METHODS = exports.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK = exports.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE = exports.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE = exports.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT = exports.ARGUMENTS_LENGTH_MISMATCH = exports.INVALID_DECORATOR_OPERATION = exports.INVALID_TO_SELF_VALUE = exports.INVALID_FUNCTION_BINDING = exports.INVALID_MIDDLEWARE_RETURN = exports.NO_MORE_SNAPSHOTS_AVAILABLE = exports.INVALID_BINDING_TYPE = exports.NOT_IMPLEMENTED = exports.CIRCULAR_DEPENDENCY = exports.UNDEFINED_INJECT_ANNOTATION = exports.MISSING_INJECT_ANNOTATION = exports.MISSING_INJECTABLE_ANNOTATION = exports.NOT_REGISTERED = exports.CANNOT_UNBIND = exports.AMBIGUOUS_MATCH = exports.KEY_NOT_FOUND = exports.NULL_ARGUMENT = exports.DUPLICATED_METADATA = exports.DUPLICATED_INJECTABLE_DECORATOR = void 0;
|
||
exports.DUPLICATED_INJECTABLE_DECORATOR = "Cannot apply @injectable decorator multiple times.";
|
||
exports.DUPLICATED_METADATA = "Metadata key was used more than once in a parameter:";
|
||
exports.NULL_ARGUMENT = "NULL argument";
|
||
exports.KEY_NOT_FOUND = "Key Not Found";
|
||
exports.AMBIGUOUS_MATCH = "Ambiguous match found for serviceIdentifier:";
|
||
exports.CANNOT_UNBIND = "Could not unbind serviceIdentifier:";
|
||
exports.NOT_REGISTERED = "No matching bindings found for serviceIdentifier:";
|
||
exports.MISSING_INJECTABLE_ANNOTATION = "Missing required @injectable annotation in:";
|
||
exports.MISSING_INJECT_ANNOTATION = "Missing required @inject or @multiInject annotation in:";
|
||
var UNDEFINED_INJECT_ANNOTATION = function (name) {
|
||
return "@inject called with undefined this could mean that the class " + name + " has " +
|
||
"a circular dependency problem. You can use a LazyServiceIdentifer to " +
|
||
"overcome this limitation.";
|
||
};
|
||
exports.UNDEFINED_INJECT_ANNOTATION = UNDEFINED_INJECT_ANNOTATION;
|
||
exports.CIRCULAR_DEPENDENCY = "Circular dependency found:";
|
||
exports.NOT_IMPLEMENTED = "Sorry, this feature is not fully implemented yet.";
|
||
exports.INVALID_BINDING_TYPE = "Invalid binding type:";
|
||
exports.NO_MORE_SNAPSHOTS_AVAILABLE = "No snapshot available to restore.";
|
||
exports.INVALID_MIDDLEWARE_RETURN = "Invalid return type in middleware. Middleware must return!";
|
||
exports.INVALID_FUNCTION_BINDING = "Value provided to function binding must be a function!";
|
||
exports.INVALID_TO_SELF_VALUE = "The toSelf function can only be applied when a constructor is " +
|
||
"used as service identifier";
|
||
exports.INVALID_DECORATOR_OPERATION = "The @inject @multiInject @tagged and @named decorators " +
|
||
"must be applied to the parameters of a class constructor or a class property.";
|
||
var ARGUMENTS_LENGTH_MISMATCH = function () {
|
||
var values = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
values[_i] = arguments[_i];
|
||
}
|
||
return "The number of constructor arguments in the derived class " +
|
||
(values[0] + " must be >= than the number of constructor arguments of its base class.");
|
||
};
|
||
exports.ARGUMENTS_LENGTH_MISMATCH = ARGUMENTS_LENGTH_MISMATCH;
|
||
exports.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT = "Invalid Container constructor argument. Container options " +
|
||
"must be an object.";
|
||
exports.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE = "Invalid Container option. Default scope must " +
|
||
"be a string ('singleton' or 'transient').";
|
||
exports.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE = "Invalid Container option. Auto bind injectable must " +
|
||
"be a boolean";
|
||
exports.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK = "Invalid Container option. Skip base check must " +
|
||
"be a boolean";
|
||
exports.MULTIPLE_POST_CONSTRUCT_METHODS = "Cannot apply @postConstruct decorator multiple times in the same class";
|
||
var POST_CONSTRUCT_ERROR = function () {
|
||
var values = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
values[_i] = arguments[_i];
|
||
}
|
||
return "@postConstruct error in class " + values[0] + ": " + values[1];
|
||
};
|
||
exports.POST_CONSTRUCT_ERROR = POST_CONSTRUCT_ERROR;
|
||
var CIRCULAR_DEPENDENCY_IN_FACTORY = function () {
|
||
var values = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
values[_i] = arguments[_i];
|
||
}
|
||
return "It looks like there is a circular dependency " +
|
||
("in one of the '" + values[0] + "' bindings. Please investigate bindings with") +
|
||
("service identifier '" + values[1] + "'.");
|
||
};
|
||
exports.CIRCULAR_DEPENDENCY_IN_FACTORY = CIRCULAR_DEPENDENCY_IN_FACTORY;
|
||
exports.STACK_OVERFLOW = "Maximum call stack size exceeded";
|
||
//# sourceMappingURL=error_msgs.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/constants/literal_types.js":
|
||
/*!***************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/constants/literal_types.js ***!
|
||
\***************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.TargetTypeEnum = exports.BindingTypeEnum = exports.BindingScopeEnum = void 0;
|
||
var BindingScopeEnum = {
|
||
Request: "Request",
|
||
Singleton: "Singleton",
|
||
Transient: "Transient"
|
||
};
|
||
exports.BindingScopeEnum = BindingScopeEnum;
|
||
var BindingTypeEnum = {
|
||
ConstantValue: "ConstantValue",
|
||
Constructor: "Constructor",
|
||
DynamicValue: "DynamicValue",
|
||
Factory: "Factory",
|
||
Function: "Function",
|
||
Instance: "Instance",
|
||
Invalid: "Invalid",
|
||
Provider: "Provider"
|
||
};
|
||
exports.BindingTypeEnum = BindingTypeEnum;
|
||
var TargetTypeEnum = {
|
||
ClassProperty: "ClassProperty",
|
||
ConstructorArgument: "ConstructorArgument",
|
||
Variable: "Variable"
|
||
};
|
||
exports.TargetTypeEnum = TargetTypeEnum;
|
||
//# sourceMappingURL=literal_types.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/constants/metadata_keys.js":
|
||
/*!***************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/constants/metadata_keys.js ***!
|
||
\***************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.NON_CUSTOM_TAG_KEYS = exports.POST_CONSTRUCT = exports.DESIGN_PARAM_TYPES = exports.PARAM_TYPES = exports.TAGGED_PROP = exports.TAGGED = exports.MULTI_INJECT_TAG = exports.INJECT_TAG = exports.OPTIONAL_TAG = exports.UNMANAGED_TAG = exports.NAME_TAG = exports.NAMED_TAG = void 0;
|
||
exports.NAMED_TAG = "named";
|
||
exports.NAME_TAG = "name";
|
||
exports.UNMANAGED_TAG = "unmanaged";
|
||
exports.OPTIONAL_TAG = "optional";
|
||
exports.INJECT_TAG = "inject";
|
||
exports.MULTI_INJECT_TAG = "multi_inject";
|
||
exports.TAGGED = "inversify:tagged";
|
||
exports.TAGGED_PROP = "inversify:tagged_props";
|
||
exports.PARAM_TYPES = "inversify:paramtypes";
|
||
exports.DESIGN_PARAM_TYPES = "design:paramtypes";
|
||
exports.POST_CONSTRUCT = "post_construct";
|
||
function getNonCustomTagKeys() {
|
||
return [
|
||
exports.INJECT_TAG,
|
||
exports.MULTI_INJECT_TAG,
|
||
exports.NAME_TAG,
|
||
exports.UNMANAGED_TAG,
|
||
exports.NAMED_TAG,
|
||
exports.OPTIONAL_TAG,
|
||
];
|
||
}
|
||
exports.NON_CUSTOM_TAG_KEYS = getNonCustomTagKeys();
|
||
//# sourceMappingURL=metadata_keys.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/container/container.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/container/container.js ***!
|
||
\***********************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||
function step(op) {
|
||
if (f) throw new TypeError("Generator is already executing.");
|
||
while (_) try {
|
||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||
switch (op[0]) {
|
||
case 0: case 1: t = op; break;
|
||
case 4: _.label++; return { value: op[1], done: false };
|
||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||
default:
|
||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||
if (t[2]) _.ops.pop();
|
||
_.trys.pop(); continue;
|
||
}
|
||
op = body.call(thisArg, _);
|
||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||
}
|
||
};
|
||
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||
to[j] = from[i];
|
||
return to;
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Container = void 0;
|
||
var binding_1 = __webpack_require__(/*! ../bindings/binding */ "./node_modules/inversify/lib/bindings/binding.js");
|
||
var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var metadata_reader_1 = __webpack_require__(/*! ../planning/metadata_reader */ "./node_modules/inversify/lib/planning/metadata_reader.js");
|
||
var planner_1 = __webpack_require__(/*! ../planning/planner */ "./node_modules/inversify/lib/planning/planner.js");
|
||
var resolver_1 = __webpack_require__(/*! ../resolution/resolver */ "./node_modules/inversify/lib/resolution/resolver.js");
|
||
var binding_to_syntax_1 = __webpack_require__(/*! ../syntax/binding_to_syntax */ "./node_modules/inversify/lib/syntax/binding_to_syntax.js");
|
||
var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js");
|
||
var serialization_1 = __webpack_require__(/*! ../utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js");
|
||
var container_snapshot_1 = __webpack_require__(/*! ./container_snapshot */ "./node_modules/inversify/lib/container/container_snapshot.js");
|
||
var lookup_1 = __webpack_require__(/*! ./lookup */ "./node_modules/inversify/lib/container/lookup.js");
|
||
var Container = (function () {
|
||
function Container(containerOptions) {
|
||
this._appliedMiddleware = [];
|
||
var options = containerOptions || {};
|
||
if (typeof options !== "object") {
|
||
throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT);
|
||
}
|
||
if (options.defaultScope === undefined) {
|
||
options.defaultScope = literal_types_1.BindingScopeEnum.Transient;
|
||
}
|
||
else if (options.defaultScope !== literal_types_1.BindingScopeEnum.Singleton &&
|
||
options.defaultScope !== literal_types_1.BindingScopeEnum.Transient &&
|
||
options.defaultScope !== literal_types_1.BindingScopeEnum.Request) {
|
||
throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE);
|
||
}
|
||
if (options.autoBindInjectable === undefined) {
|
||
options.autoBindInjectable = false;
|
||
}
|
||
else if (typeof options.autoBindInjectable !== "boolean") {
|
||
throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE);
|
||
}
|
||
if (options.skipBaseClassChecks === undefined) {
|
||
options.skipBaseClassChecks = false;
|
||
}
|
||
else if (typeof options.skipBaseClassChecks !== "boolean") {
|
||
throw new Error("" + ERROR_MSGS.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK);
|
||
}
|
||
this.options = {
|
||
autoBindInjectable: options.autoBindInjectable,
|
||
defaultScope: options.defaultScope,
|
||
skipBaseClassChecks: options.skipBaseClassChecks
|
||
};
|
||
this.id = id_1.id();
|
||
this._bindingDictionary = new lookup_1.Lookup();
|
||
this._snapshots = [];
|
||
this._middleware = null;
|
||
this.parent = null;
|
||
this._metadataReader = new metadata_reader_1.MetadataReader();
|
||
}
|
||
Container.merge = function (container1, container2) {
|
||
var container3 = [];
|
||
for (var _i = 2; _i < arguments.length; _i++) {
|
||
container3[_i - 2] = arguments[_i];
|
||
}
|
||
var container = new Container();
|
||
var targetContainers = __spreadArray([container1, container2], container3).map(function (targetContainer) { return planner_1.getBindingDictionary(targetContainer); });
|
||
var bindingDictionary = planner_1.getBindingDictionary(container);
|
||
function copyDictionary(origin, destination) {
|
||
origin.traverse(function (key, value) {
|
||
value.forEach(function (binding) {
|
||
destination.add(binding.serviceIdentifier, binding.clone());
|
||
});
|
||
});
|
||
}
|
||
targetContainers.forEach(function (targetBindingDictionary) {
|
||
copyDictionary(targetBindingDictionary, bindingDictionary);
|
||
});
|
||
return container;
|
||
};
|
||
Container.prototype.load = function () {
|
||
var modules = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
modules[_i] = arguments[_i];
|
||
}
|
||
var getHelpers = this._getContainerModuleHelpersFactory();
|
||
for (var _a = 0, modules_1 = modules; _a < modules_1.length; _a++) {
|
||
var currentModule = modules_1[_a];
|
||
var containerModuleHelpers = getHelpers(currentModule.id);
|
||
currentModule.registry(containerModuleHelpers.bindFunction, containerModuleHelpers.unbindFunction, containerModuleHelpers.isboundFunction, containerModuleHelpers.rebindFunction);
|
||
}
|
||
};
|
||
Container.prototype.loadAsync = function () {
|
||
var modules = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
modules[_i] = arguments[_i];
|
||
}
|
||
return __awaiter(this, void 0, void 0, function () {
|
||
var getHelpers, _a, modules_2, currentModule, containerModuleHelpers;
|
||
return __generator(this, function (_b) {
|
||
switch (_b.label) {
|
||
case 0:
|
||
getHelpers = this._getContainerModuleHelpersFactory();
|
||
_a = 0, modules_2 = modules;
|
||
_b.label = 1;
|
||
case 1:
|
||
if (!(_a < modules_2.length)) return [3, 4];
|
||
currentModule = modules_2[_a];
|
||
containerModuleHelpers = getHelpers(currentModule.id);
|
||
return [4, currentModule.registry(containerModuleHelpers.bindFunction, containerModuleHelpers.unbindFunction, containerModuleHelpers.isboundFunction, containerModuleHelpers.rebindFunction)];
|
||
case 2:
|
||
_b.sent();
|
||
_b.label = 3;
|
||
case 3:
|
||
_a++;
|
||
return [3, 1];
|
||
case 4: return [2];
|
||
}
|
||
});
|
||
});
|
||
};
|
||
Container.prototype.unload = function () {
|
||
var _this = this;
|
||
var modules = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
modules[_i] = arguments[_i];
|
||
}
|
||
var conditionFactory = function (expected) { return function (item) {
|
||
return item.moduleId === expected;
|
||
}; };
|
||
modules.forEach(function (module) {
|
||
var condition = conditionFactory(module.id);
|
||
_this._bindingDictionary.removeByCondition(condition);
|
||
});
|
||
};
|
||
Container.prototype.bind = function (serviceIdentifier) {
|
||
var scope = this.options.defaultScope || literal_types_1.BindingScopeEnum.Transient;
|
||
var binding = new binding_1.Binding(serviceIdentifier, scope);
|
||
this._bindingDictionary.add(serviceIdentifier, binding);
|
||
return new binding_to_syntax_1.BindingToSyntax(binding);
|
||
};
|
||
Container.prototype.rebind = function (serviceIdentifier) {
|
||
this.unbind(serviceIdentifier);
|
||
return this.bind(serviceIdentifier);
|
||
};
|
||
Container.prototype.unbind = function (serviceIdentifier) {
|
||
try {
|
||
this._bindingDictionary.remove(serviceIdentifier);
|
||
}
|
||
catch (e) {
|
||
throw new Error(ERROR_MSGS.CANNOT_UNBIND + " " + serialization_1.getServiceIdentifierAsString(serviceIdentifier));
|
||
}
|
||
};
|
||
Container.prototype.unbindAll = function () {
|
||
this._bindingDictionary = new lookup_1.Lookup();
|
||
};
|
||
Container.prototype.isBound = function (serviceIdentifier) {
|
||
var bound = this._bindingDictionary.hasKey(serviceIdentifier);
|
||
if (!bound && this.parent) {
|
||
bound = this.parent.isBound(serviceIdentifier);
|
||
}
|
||
return bound;
|
||
};
|
||
Container.prototype.isBoundNamed = function (serviceIdentifier, named) {
|
||
return this.isBoundTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
|
||
};
|
||
Container.prototype.isBoundTagged = function (serviceIdentifier, key, value) {
|
||
var bound = false;
|
||
if (this._bindingDictionary.hasKey(serviceIdentifier)) {
|
||
var bindings = this._bindingDictionary.get(serviceIdentifier);
|
||
var request_1 = planner_1.createMockRequest(this, serviceIdentifier, key, value);
|
||
bound = bindings.some(function (b) { return b.constraint(request_1); });
|
||
}
|
||
if (!bound && this.parent) {
|
||
bound = this.parent.isBoundTagged(serviceIdentifier, key, value);
|
||
}
|
||
return bound;
|
||
};
|
||
Container.prototype.snapshot = function () {
|
||
this._snapshots.push(container_snapshot_1.ContainerSnapshot.of(this._bindingDictionary.clone(), this._middleware));
|
||
};
|
||
Container.prototype.restore = function () {
|
||
var snapshot = this._snapshots.pop();
|
||
if (snapshot === undefined) {
|
||
throw new Error(ERROR_MSGS.NO_MORE_SNAPSHOTS_AVAILABLE);
|
||
}
|
||
this._bindingDictionary = snapshot.bindings;
|
||
this._middleware = snapshot.middleware;
|
||
};
|
||
Container.prototype.createChild = function (containerOptions) {
|
||
var child = new Container(containerOptions || this.options);
|
||
child.parent = this;
|
||
return child;
|
||
};
|
||
Container.prototype.applyMiddleware = function () {
|
||
var middlewares = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
middlewares[_i] = arguments[_i];
|
||
}
|
||
this._appliedMiddleware = this._appliedMiddleware.concat(middlewares);
|
||
var initial = (this._middleware) ? this._middleware : this._planAndResolve();
|
||
this._middleware = middlewares.reduce(function (prev, curr) { return curr(prev); }, initial);
|
||
};
|
||
Container.prototype.applyCustomMetadataReader = function (metadataReader) {
|
||
this._metadataReader = metadataReader;
|
||
};
|
||
Container.prototype.get = function (serviceIdentifier) {
|
||
return this._get(false, false, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier);
|
||
};
|
||
Container.prototype.getTagged = function (serviceIdentifier, key, value) {
|
||
return this._get(false, false, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier, key, value);
|
||
};
|
||
Container.prototype.getNamed = function (serviceIdentifier, named) {
|
||
return this.getTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
|
||
};
|
||
Container.prototype.getAll = function (serviceIdentifier) {
|
||
return this._get(true, true, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier);
|
||
};
|
||
Container.prototype.getAllTagged = function (serviceIdentifier, key, value) {
|
||
return this._get(false, true, literal_types_1.TargetTypeEnum.Variable, serviceIdentifier, key, value);
|
||
};
|
||
Container.prototype.getAllNamed = function (serviceIdentifier, named) {
|
||
return this.getAllTagged(serviceIdentifier, METADATA_KEY.NAMED_TAG, named);
|
||
};
|
||
Container.prototype.resolve = function (constructorFunction) {
|
||
var tempContainer = this.createChild();
|
||
tempContainer.bind(constructorFunction).toSelf();
|
||
this._appliedMiddleware.forEach(function (m) {
|
||
tempContainer.applyMiddleware(m);
|
||
});
|
||
return tempContainer.get(constructorFunction);
|
||
};
|
||
Container.prototype._getContainerModuleHelpersFactory = function () {
|
||
var _this = this;
|
||
var setModuleId = function (bindingToSyntax, moduleId) {
|
||
bindingToSyntax._binding.moduleId = moduleId;
|
||
};
|
||
var getBindFunction = function (moduleId) {
|
||
return function (serviceIdentifier) {
|
||
var _bind = _this.bind.bind(_this);
|
||
var bindingToSyntax = _bind(serviceIdentifier);
|
||
setModuleId(bindingToSyntax, moduleId);
|
||
return bindingToSyntax;
|
||
};
|
||
};
|
||
var getUnbindFunction = function (moduleId) {
|
||
return function (serviceIdentifier) {
|
||
var _unbind = _this.unbind.bind(_this);
|
||
_unbind(serviceIdentifier);
|
||
};
|
||
};
|
||
var getIsboundFunction = function (moduleId) {
|
||
return function (serviceIdentifier) {
|
||
var _isBound = _this.isBound.bind(_this);
|
||
return _isBound(serviceIdentifier);
|
||
};
|
||
};
|
||
var getRebindFunction = function (moduleId) {
|
||
return function (serviceIdentifier) {
|
||
var _rebind = _this.rebind.bind(_this);
|
||
var bindingToSyntax = _rebind(serviceIdentifier);
|
||
setModuleId(bindingToSyntax, moduleId);
|
||
return bindingToSyntax;
|
||
};
|
||
};
|
||
return function (mId) { return ({
|
||
bindFunction: getBindFunction(mId),
|
||
isboundFunction: getIsboundFunction(mId),
|
||
rebindFunction: getRebindFunction(mId),
|
||
unbindFunction: getUnbindFunction(mId)
|
||
}); };
|
||
};
|
||
Container.prototype._get = function (avoidConstraints, isMultiInject, targetType, serviceIdentifier, key, value) {
|
||
var result = null;
|
||
var defaultArgs = {
|
||
avoidConstraints: avoidConstraints,
|
||
contextInterceptor: function (context) { return context; },
|
||
isMultiInject: isMultiInject,
|
||
key: key,
|
||
serviceIdentifier: serviceIdentifier,
|
||
targetType: targetType,
|
||
value: value
|
||
};
|
||
if (this._middleware) {
|
||
result = this._middleware(defaultArgs);
|
||
if (result === undefined || result === null) {
|
||
throw new Error(ERROR_MSGS.INVALID_MIDDLEWARE_RETURN);
|
||
}
|
||
}
|
||
else {
|
||
result = this._planAndResolve()(defaultArgs);
|
||
}
|
||
return result;
|
||
};
|
||
Container.prototype._planAndResolve = function () {
|
||
var _this = this;
|
||
return function (args) {
|
||
var context = planner_1.plan(_this._metadataReader, _this, args.isMultiInject, args.targetType, args.serviceIdentifier, args.key, args.value, args.avoidConstraints);
|
||
context = args.contextInterceptor(context);
|
||
var result = resolver_1.resolve(context);
|
||
return result;
|
||
};
|
||
};
|
||
return Container;
|
||
}());
|
||
exports.Container = Container;
|
||
//# sourceMappingURL=container.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/container/container_module.js":
|
||
/*!******************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/container/container_module.js ***!
|
||
\******************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.AsyncContainerModule = exports.ContainerModule = void 0;
|
||
var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js");
|
||
var ContainerModule = (function () {
|
||
function ContainerModule(registry) {
|
||
this.id = id_1.id();
|
||
this.registry = registry;
|
||
}
|
||
return ContainerModule;
|
||
}());
|
||
exports.ContainerModule = ContainerModule;
|
||
var AsyncContainerModule = (function () {
|
||
function AsyncContainerModule(registry) {
|
||
this.id = id_1.id();
|
||
this.registry = registry;
|
||
}
|
||
return AsyncContainerModule;
|
||
}());
|
||
exports.AsyncContainerModule = AsyncContainerModule;
|
||
//# sourceMappingURL=container_module.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/container/container_snapshot.js":
|
||
/*!********************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/container/container_snapshot.js ***!
|
||
\********************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.ContainerSnapshot = void 0;
|
||
var ContainerSnapshot = (function () {
|
||
function ContainerSnapshot() {
|
||
}
|
||
ContainerSnapshot.of = function (bindings, middleware) {
|
||
var snapshot = new ContainerSnapshot();
|
||
snapshot.bindings = bindings;
|
||
snapshot.middleware = middleware;
|
||
return snapshot;
|
||
};
|
||
return ContainerSnapshot;
|
||
}());
|
||
exports.ContainerSnapshot = ContainerSnapshot;
|
||
//# sourceMappingURL=container_snapshot.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/container/lookup.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/container/lookup.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Lookup = void 0;
|
||
var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var Lookup = (function () {
|
||
function Lookup() {
|
||
this._map = new Map();
|
||
}
|
||
Lookup.prototype.getMap = function () {
|
||
return this._map;
|
||
};
|
||
Lookup.prototype.add = function (serviceIdentifier, value) {
|
||
if (serviceIdentifier === null || serviceIdentifier === undefined) {
|
||
throw new Error(ERROR_MSGS.NULL_ARGUMENT);
|
||
}
|
||
if (value === null || value === undefined) {
|
||
throw new Error(ERROR_MSGS.NULL_ARGUMENT);
|
||
}
|
||
var entry = this._map.get(serviceIdentifier);
|
||
if (entry !== undefined) {
|
||
entry.push(value);
|
||
this._map.set(serviceIdentifier, entry);
|
||
}
|
||
else {
|
||
this._map.set(serviceIdentifier, [value]);
|
||
}
|
||
};
|
||
Lookup.prototype.get = function (serviceIdentifier) {
|
||
if (serviceIdentifier === null || serviceIdentifier === undefined) {
|
||
throw new Error(ERROR_MSGS.NULL_ARGUMENT);
|
||
}
|
||
var entry = this._map.get(serviceIdentifier);
|
||
if (entry !== undefined) {
|
||
return entry;
|
||
}
|
||
else {
|
||
throw new Error(ERROR_MSGS.KEY_NOT_FOUND);
|
||
}
|
||
};
|
||
Lookup.prototype.remove = function (serviceIdentifier) {
|
||
if (serviceIdentifier === null || serviceIdentifier === undefined) {
|
||
throw new Error(ERROR_MSGS.NULL_ARGUMENT);
|
||
}
|
||
if (!this._map.delete(serviceIdentifier)) {
|
||
throw new Error(ERROR_MSGS.KEY_NOT_FOUND);
|
||
}
|
||
};
|
||
Lookup.prototype.removeByCondition = function (condition) {
|
||
var _this = this;
|
||
this._map.forEach(function (entries, key) {
|
||
var updatedEntries = entries.filter(function (entry) { return !condition(entry); });
|
||
if (updatedEntries.length > 0) {
|
||
_this._map.set(key, updatedEntries);
|
||
}
|
||
else {
|
||
_this._map.delete(key);
|
||
}
|
||
});
|
||
};
|
||
Lookup.prototype.hasKey = function (serviceIdentifier) {
|
||
if (serviceIdentifier === null || serviceIdentifier === undefined) {
|
||
throw new Error(ERROR_MSGS.NULL_ARGUMENT);
|
||
}
|
||
return this._map.has(serviceIdentifier);
|
||
};
|
||
Lookup.prototype.clone = function () {
|
||
var copy = new Lookup();
|
||
this._map.forEach(function (value, key) {
|
||
value.forEach(function (b) { return copy.add(key, b.clone()); });
|
||
});
|
||
return copy;
|
||
};
|
||
Lookup.prototype.traverse = function (func) {
|
||
this._map.forEach(function (value, key) {
|
||
func(key, value);
|
||
});
|
||
};
|
||
return Lookup;
|
||
}());
|
||
exports.Lookup = Lookup;
|
||
//# sourceMappingURL=lookup.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/inversify.js":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/inversify/lib/inversify.js ***!
|
||
\*************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.multiBindToService = exports.getServiceIdentifierAsString = exports.typeConstraint = exports.namedConstraint = exports.taggedConstraint = exports.traverseAncerstors = exports.decorate = exports.id = exports.MetadataReader = exports.postConstruct = exports.targetName = exports.multiInject = exports.unmanaged = exports.optional = exports.LazyServiceIdentifer = exports.inject = exports.named = exports.tagged = exports.injectable = exports.ContainerModule = exports.AsyncContainerModule = exports.TargetTypeEnum = exports.BindingTypeEnum = exports.BindingScopeEnum = exports.Container = exports.METADATA_KEY = void 0;
|
||
var keys = __webpack_require__(/*! ./constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
exports.METADATA_KEY = keys;
|
||
var container_1 = __webpack_require__(/*! ./container/container */ "./node_modules/inversify/lib/container/container.js");
|
||
Object.defineProperty(exports, "Container", ({ enumerable: true, get: function () { return container_1.Container; } }));
|
||
var literal_types_1 = __webpack_require__(/*! ./constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
Object.defineProperty(exports, "BindingScopeEnum", ({ enumerable: true, get: function () { return literal_types_1.BindingScopeEnum; } }));
|
||
Object.defineProperty(exports, "BindingTypeEnum", ({ enumerable: true, get: function () { return literal_types_1.BindingTypeEnum; } }));
|
||
Object.defineProperty(exports, "TargetTypeEnum", ({ enumerable: true, get: function () { return literal_types_1.TargetTypeEnum; } }));
|
||
var container_module_1 = __webpack_require__(/*! ./container/container_module */ "./node_modules/inversify/lib/container/container_module.js");
|
||
Object.defineProperty(exports, "AsyncContainerModule", ({ enumerable: true, get: function () { return container_module_1.AsyncContainerModule; } }));
|
||
Object.defineProperty(exports, "ContainerModule", ({ enumerable: true, get: function () { return container_module_1.ContainerModule; } }));
|
||
var injectable_1 = __webpack_require__(/*! ./annotation/injectable */ "./node_modules/inversify/lib/annotation/injectable.js");
|
||
Object.defineProperty(exports, "injectable", ({ enumerable: true, get: function () { return injectable_1.injectable; } }));
|
||
var tagged_1 = __webpack_require__(/*! ./annotation/tagged */ "./node_modules/inversify/lib/annotation/tagged.js");
|
||
Object.defineProperty(exports, "tagged", ({ enumerable: true, get: function () { return tagged_1.tagged; } }));
|
||
var named_1 = __webpack_require__(/*! ./annotation/named */ "./node_modules/inversify/lib/annotation/named.js");
|
||
Object.defineProperty(exports, "named", ({ enumerable: true, get: function () { return named_1.named; } }));
|
||
var inject_1 = __webpack_require__(/*! ./annotation/inject */ "./node_modules/inversify/lib/annotation/inject.js");
|
||
Object.defineProperty(exports, "inject", ({ enumerable: true, get: function () { return inject_1.inject; } }));
|
||
Object.defineProperty(exports, "LazyServiceIdentifer", ({ enumerable: true, get: function () { return inject_1.LazyServiceIdentifer; } }));
|
||
var optional_1 = __webpack_require__(/*! ./annotation/optional */ "./node_modules/inversify/lib/annotation/optional.js");
|
||
Object.defineProperty(exports, "optional", ({ enumerable: true, get: function () { return optional_1.optional; } }));
|
||
var unmanaged_1 = __webpack_require__(/*! ./annotation/unmanaged */ "./node_modules/inversify/lib/annotation/unmanaged.js");
|
||
Object.defineProperty(exports, "unmanaged", ({ enumerable: true, get: function () { return unmanaged_1.unmanaged; } }));
|
||
var multi_inject_1 = __webpack_require__(/*! ./annotation/multi_inject */ "./node_modules/inversify/lib/annotation/multi_inject.js");
|
||
Object.defineProperty(exports, "multiInject", ({ enumerable: true, get: function () { return multi_inject_1.multiInject; } }));
|
||
var target_name_1 = __webpack_require__(/*! ./annotation/target_name */ "./node_modules/inversify/lib/annotation/target_name.js");
|
||
Object.defineProperty(exports, "targetName", ({ enumerable: true, get: function () { return target_name_1.targetName; } }));
|
||
var post_construct_1 = __webpack_require__(/*! ./annotation/post_construct */ "./node_modules/inversify/lib/annotation/post_construct.js");
|
||
Object.defineProperty(exports, "postConstruct", ({ enumerable: true, get: function () { return post_construct_1.postConstruct; } }));
|
||
var metadata_reader_1 = __webpack_require__(/*! ./planning/metadata_reader */ "./node_modules/inversify/lib/planning/metadata_reader.js");
|
||
Object.defineProperty(exports, "MetadataReader", ({ enumerable: true, get: function () { return metadata_reader_1.MetadataReader; } }));
|
||
var id_1 = __webpack_require__(/*! ./utils/id */ "./node_modules/inversify/lib/utils/id.js");
|
||
Object.defineProperty(exports, "id", ({ enumerable: true, get: function () { return id_1.id; } }));
|
||
var decorator_utils_1 = __webpack_require__(/*! ./annotation/decorator_utils */ "./node_modules/inversify/lib/annotation/decorator_utils.js");
|
||
Object.defineProperty(exports, "decorate", ({ enumerable: true, get: function () { return decorator_utils_1.decorate; } }));
|
||
var constraint_helpers_1 = __webpack_require__(/*! ./syntax/constraint_helpers */ "./node_modules/inversify/lib/syntax/constraint_helpers.js");
|
||
Object.defineProperty(exports, "traverseAncerstors", ({ enumerable: true, get: function () { return constraint_helpers_1.traverseAncerstors; } }));
|
||
Object.defineProperty(exports, "taggedConstraint", ({ enumerable: true, get: function () { return constraint_helpers_1.taggedConstraint; } }));
|
||
Object.defineProperty(exports, "namedConstraint", ({ enumerable: true, get: function () { return constraint_helpers_1.namedConstraint; } }));
|
||
Object.defineProperty(exports, "typeConstraint", ({ enumerable: true, get: function () { return constraint_helpers_1.typeConstraint; } }));
|
||
var serialization_1 = __webpack_require__(/*! ./utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js");
|
||
Object.defineProperty(exports, "getServiceIdentifierAsString", ({ enumerable: true, get: function () { return serialization_1.getServiceIdentifierAsString; } }));
|
||
var binding_utils_1 = __webpack_require__(/*! ./utils/binding_utils */ "./node_modules/inversify/lib/utils/binding_utils.js");
|
||
Object.defineProperty(exports, "multiBindToService", ({ enumerable: true, get: function () { return binding_utils_1.multiBindToService; } }));
|
||
//# sourceMappingURL=inversify.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/context.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/context.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Context = void 0;
|
||
var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js");
|
||
var Context = (function () {
|
||
function Context(container) {
|
||
this.id = id_1.id();
|
||
this.container = container;
|
||
}
|
||
Context.prototype.addPlan = function (plan) {
|
||
this.plan = plan;
|
||
};
|
||
Context.prototype.setCurrentRequest = function (currentRequest) {
|
||
this.currentRequest = currentRequest;
|
||
};
|
||
return Context;
|
||
}());
|
||
exports.Context = Context;
|
||
//# sourceMappingURL=context.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/metadata.js":
|
||
/*!*********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/metadata.js ***!
|
||
\*********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Metadata = void 0;
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var Metadata = (function () {
|
||
function Metadata(key, value) {
|
||
this.key = key;
|
||
this.value = value;
|
||
}
|
||
Metadata.prototype.toString = function () {
|
||
if (this.key === METADATA_KEY.NAMED_TAG) {
|
||
return "named: " + this.value.toString() + " ";
|
||
}
|
||
else {
|
||
return "tagged: { key:" + this.key.toString() + ", value: " + this.value + " }";
|
||
}
|
||
};
|
||
return Metadata;
|
||
}());
|
||
exports.Metadata = Metadata;
|
||
//# sourceMappingURL=metadata.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/metadata_reader.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/metadata_reader.js ***!
|
||
\****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.MetadataReader = void 0;
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var MetadataReader = (function () {
|
||
function MetadataReader() {
|
||
}
|
||
MetadataReader.prototype.getConstructorMetadata = function (constructorFunc) {
|
||
var compilerGeneratedMetadata = Reflect.getMetadata(METADATA_KEY.PARAM_TYPES, constructorFunc);
|
||
var userGeneratedMetadata = Reflect.getMetadata(METADATA_KEY.TAGGED, constructorFunc);
|
||
return {
|
||
compilerGeneratedMetadata: compilerGeneratedMetadata,
|
||
userGeneratedMetadata: userGeneratedMetadata || {}
|
||
};
|
||
};
|
||
MetadataReader.prototype.getPropertiesMetadata = function (constructorFunc) {
|
||
var userGeneratedMetadata = Reflect.getMetadata(METADATA_KEY.TAGGED_PROP, constructorFunc) || [];
|
||
return userGeneratedMetadata;
|
||
};
|
||
return MetadataReader;
|
||
}());
|
||
exports.MetadataReader = MetadataReader;
|
||
//# sourceMappingURL=metadata_reader.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/plan.js":
|
||
/*!*****************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/plan.js ***!
|
||
\*****************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Plan = void 0;
|
||
var Plan = (function () {
|
||
function Plan(parentContext, rootRequest) {
|
||
this.parentContext = parentContext;
|
||
this.rootRequest = rootRequest;
|
||
}
|
||
return Plan;
|
||
}());
|
||
exports.Plan = Plan;
|
||
//# sourceMappingURL=plan.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/planner.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/planner.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.getBindingDictionary = exports.createMockRequest = exports.plan = void 0;
|
||
var binding_count_1 = __webpack_require__(/*! ../bindings/binding_count */ "./node_modules/inversify/lib/bindings/binding_count.js");
|
||
var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var exceptions_1 = __webpack_require__(/*! ../utils/exceptions */ "./node_modules/inversify/lib/utils/exceptions.js");
|
||
var serialization_1 = __webpack_require__(/*! ../utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js");
|
||
var context_1 = __webpack_require__(/*! ./context */ "./node_modules/inversify/lib/planning/context.js");
|
||
var metadata_1 = __webpack_require__(/*! ./metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var plan_1 = __webpack_require__(/*! ./plan */ "./node_modules/inversify/lib/planning/plan.js");
|
||
var reflection_utils_1 = __webpack_require__(/*! ./reflection_utils */ "./node_modules/inversify/lib/planning/reflection_utils.js");
|
||
var request_1 = __webpack_require__(/*! ./request */ "./node_modules/inversify/lib/planning/request.js");
|
||
var target_1 = __webpack_require__(/*! ./target */ "./node_modules/inversify/lib/planning/target.js");
|
||
function getBindingDictionary(cntnr) {
|
||
return cntnr._bindingDictionary;
|
||
}
|
||
exports.getBindingDictionary = getBindingDictionary;
|
||
function _createTarget(isMultiInject, targetType, serviceIdentifier, name, key, value) {
|
||
var metadataKey = isMultiInject ? METADATA_KEY.MULTI_INJECT_TAG : METADATA_KEY.INJECT_TAG;
|
||
var injectMetadata = new metadata_1.Metadata(metadataKey, serviceIdentifier);
|
||
var target = new target_1.Target(targetType, name, serviceIdentifier, injectMetadata);
|
||
if (key !== undefined) {
|
||
var tagMetadata = new metadata_1.Metadata(key, value);
|
||
target.metadata.push(tagMetadata);
|
||
}
|
||
return target;
|
||
}
|
||
function _getActiveBindings(metadataReader, avoidConstraints, context, parentRequest, target) {
|
||
var bindings = getBindings(context.container, target.serviceIdentifier);
|
||
var activeBindings = [];
|
||
if (bindings.length === binding_count_1.BindingCount.NoBindingsAvailable &&
|
||
context.container.options.autoBindInjectable &&
|
||
typeof target.serviceIdentifier === "function" &&
|
||
metadataReader.getConstructorMetadata(target.serviceIdentifier).compilerGeneratedMetadata) {
|
||
context.container.bind(target.serviceIdentifier).toSelf();
|
||
bindings = getBindings(context.container, target.serviceIdentifier);
|
||
}
|
||
if (!avoidConstraints) {
|
||
activeBindings = bindings.filter(function (binding) {
|
||
var request = new request_1.Request(binding.serviceIdentifier, context, parentRequest, binding, target);
|
||
return binding.constraint(request);
|
||
});
|
||
}
|
||
else {
|
||
activeBindings = bindings;
|
||
}
|
||
_validateActiveBindingCount(target.serviceIdentifier, activeBindings, target, context.container);
|
||
return activeBindings;
|
||
}
|
||
function _validateActiveBindingCount(serviceIdentifier, bindings, target, container) {
|
||
switch (bindings.length) {
|
||
case binding_count_1.BindingCount.NoBindingsAvailable:
|
||
if (target.isOptional()) {
|
||
return bindings;
|
||
}
|
||
else {
|
||
var serviceIdentifierString = serialization_1.getServiceIdentifierAsString(serviceIdentifier);
|
||
var msg = ERROR_MSGS.NOT_REGISTERED;
|
||
msg += serialization_1.listMetadataForTarget(serviceIdentifierString, target);
|
||
msg += serialization_1.listRegisteredBindingsForServiceIdentifier(container, serviceIdentifierString, getBindings);
|
||
throw new Error(msg);
|
||
}
|
||
case binding_count_1.BindingCount.OnlyOneBindingAvailable:
|
||
if (!target.isArray()) {
|
||
return bindings;
|
||
}
|
||
case binding_count_1.BindingCount.MultipleBindingsAvailable:
|
||
default:
|
||
if (!target.isArray()) {
|
||
var serviceIdentifierString = serialization_1.getServiceIdentifierAsString(serviceIdentifier);
|
||
var msg = ERROR_MSGS.AMBIGUOUS_MATCH + " " + serviceIdentifierString;
|
||
msg += serialization_1.listRegisteredBindingsForServiceIdentifier(container, serviceIdentifierString, getBindings);
|
||
throw new Error(msg);
|
||
}
|
||
else {
|
||
return bindings;
|
||
}
|
||
}
|
||
}
|
||
function _createSubRequests(metadataReader, avoidConstraints, serviceIdentifier, context, parentRequest, target) {
|
||
var activeBindings;
|
||
var childRequest;
|
||
if (parentRequest === null) {
|
||
activeBindings = _getActiveBindings(metadataReader, avoidConstraints, context, null, target);
|
||
childRequest = new request_1.Request(serviceIdentifier, context, null, activeBindings, target);
|
||
var thePlan = new plan_1.Plan(context, childRequest);
|
||
context.addPlan(thePlan);
|
||
}
|
||
else {
|
||
activeBindings = _getActiveBindings(metadataReader, avoidConstraints, context, parentRequest, target);
|
||
childRequest = parentRequest.addChildRequest(target.serviceIdentifier, activeBindings, target);
|
||
}
|
||
activeBindings.forEach(function (binding) {
|
||
var subChildRequest = null;
|
||
if (target.isArray()) {
|
||
subChildRequest = childRequest.addChildRequest(binding.serviceIdentifier, binding, target);
|
||
}
|
||
else {
|
||
if (binding.cache) {
|
||
return;
|
||
}
|
||
subChildRequest = childRequest;
|
||
}
|
||
if (binding.type === literal_types_1.BindingTypeEnum.Instance && binding.implementationType !== null) {
|
||
var dependencies = reflection_utils_1.getDependencies(metadataReader, binding.implementationType);
|
||
if (!context.container.options.skipBaseClassChecks) {
|
||
var baseClassDependencyCount = reflection_utils_1.getBaseClassDependencyCount(metadataReader, binding.implementationType);
|
||
if (dependencies.length < baseClassDependencyCount) {
|
||
var error = ERROR_MSGS.ARGUMENTS_LENGTH_MISMATCH(reflection_utils_1.getFunctionName(binding.implementationType));
|
||
throw new Error(error);
|
||
}
|
||
}
|
||
dependencies.forEach(function (dependency) {
|
||
_createSubRequests(metadataReader, false, dependency.serviceIdentifier, context, subChildRequest, dependency);
|
||
});
|
||
}
|
||
});
|
||
}
|
||
function getBindings(container, serviceIdentifier) {
|
||
var bindings = [];
|
||
var bindingDictionary = getBindingDictionary(container);
|
||
if (bindingDictionary.hasKey(serviceIdentifier)) {
|
||
bindings = bindingDictionary.get(serviceIdentifier);
|
||
}
|
||
else if (container.parent !== null) {
|
||
bindings = getBindings(container.parent, serviceIdentifier);
|
||
}
|
||
return bindings;
|
||
}
|
||
function plan(metadataReader, container, isMultiInject, targetType, serviceIdentifier, key, value, avoidConstraints) {
|
||
if (avoidConstraints === void 0) { avoidConstraints = false; }
|
||
var context = new context_1.Context(container);
|
||
var target = _createTarget(isMultiInject, targetType, serviceIdentifier, "", key, value);
|
||
try {
|
||
_createSubRequests(metadataReader, avoidConstraints, serviceIdentifier, context, null, target);
|
||
return context;
|
||
}
|
||
catch (error) {
|
||
if (exceptions_1.isStackOverflowExeption(error)) {
|
||
if (context.plan) {
|
||
serialization_1.circularDependencyToException(context.plan.rootRequest);
|
||
}
|
||
}
|
||
throw error;
|
||
}
|
||
}
|
||
exports.plan = plan;
|
||
function createMockRequest(container, serviceIdentifier, key, value) {
|
||
var target = new target_1.Target(literal_types_1.TargetTypeEnum.Variable, "", serviceIdentifier, new metadata_1.Metadata(key, value));
|
||
var context = new context_1.Context(container);
|
||
var request = new request_1.Request(serviceIdentifier, context, null, [], target);
|
||
return request;
|
||
}
|
||
exports.createMockRequest = createMockRequest;
|
||
//# sourceMappingURL=planner.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/queryable_string.js":
|
||
/*!*****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/queryable_string.js ***!
|
||
\*****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.QueryableString = void 0;
|
||
var QueryableString = (function () {
|
||
function QueryableString(str) {
|
||
this.str = str;
|
||
}
|
||
QueryableString.prototype.startsWith = function (searchString) {
|
||
return this.str.indexOf(searchString) === 0;
|
||
};
|
||
QueryableString.prototype.endsWith = function (searchString) {
|
||
var reverseString = "";
|
||
var reverseSearchString = searchString.split("").reverse().join("");
|
||
reverseString = this.str.split("").reverse().join("");
|
||
return this.startsWith.call({ str: reverseString }, reverseSearchString);
|
||
};
|
||
QueryableString.prototype.contains = function (searchString) {
|
||
return (this.str.indexOf(searchString) !== -1);
|
||
};
|
||
QueryableString.prototype.equals = function (compareString) {
|
||
return this.str === compareString;
|
||
};
|
||
QueryableString.prototype.value = function () {
|
||
return this.str;
|
||
};
|
||
return QueryableString;
|
||
}());
|
||
exports.QueryableString = QueryableString;
|
||
//# sourceMappingURL=queryable_string.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/reflection_utils.js":
|
||
/*!*****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/reflection_utils.js ***!
|
||
\*****************************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||
to[j] = from[i];
|
||
return to;
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.getFunctionName = exports.getBaseClassDependencyCount = exports.getDependencies = void 0;
|
||
var inject_1 = __webpack_require__(/*! ../annotation/inject */ "./node_modules/inversify/lib/annotation/inject.js");
|
||
var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var serialization_1 = __webpack_require__(/*! ../utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js");
|
||
Object.defineProperty(exports, "getFunctionName", ({ enumerable: true, get: function () { return serialization_1.getFunctionName; } }));
|
||
var target_1 = __webpack_require__(/*! ./target */ "./node_modules/inversify/lib/planning/target.js");
|
||
function getDependencies(metadataReader, func) {
|
||
var constructorName = serialization_1.getFunctionName(func);
|
||
var targets = getTargets(metadataReader, constructorName, func, false);
|
||
return targets;
|
||
}
|
||
exports.getDependencies = getDependencies;
|
||
function getTargets(metadataReader, constructorName, func, isBaseClass) {
|
||
var metadata = metadataReader.getConstructorMetadata(func);
|
||
var serviceIdentifiers = metadata.compilerGeneratedMetadata;
|
||
if (serviceIdentifiers === undefined) {
|
||
var msg = ERROR_MSGS.MISSING_INJECTABLE_ANNOTATION + " " + constructorName + ".";
|
||
throw new Error(msg);
|
||
}
|
||
var constructorArgsMetadata = metadata.userGeneratedMetadata;
|
||
var keys = Object.keys(constructorArgsMetadata);
|
||
var hasUserDeclaredUnknownInjections = (func.length === 0 && keys.length > 0);
|
||
var hasOptionalParameters = keys.length > func.length;
|
||
var iterations = (hasUserDeclaredUnknownInjections || hasOptionalParameters) ? keys.length : func.length;
|
||
var constructorTargets = getConstructorArgsAsTargets(isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata, iterations);
|
||
var propertyTargets = getClassPropsAsTargets(metadataReader, func);
|
||
var targets = __spreadArray(__spreadArray([], constructorTargets), propertyTargets);
|
||
return targets;
|
||
}
|
||
function getConstructorArgsAsTarget(index, isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata) {
|
||
var targetMetadata = constructorArgsMetadata[index.toString()] || [];
|
||
var metadata = formatTargetMetadata(targetMetadata);
|
||
var isManaged = metadata.unmanaged !== true;
|
||
var serviceIdentifier = serviceIdentifiers[index];
|
||
var injectIdentifier = (metadata.inject || metadata.multiInject);
|
||
serviceIdentifier = (injectIdentifier) ? (injectIdentifier) : serviceIdentifier;
|
||
if (serviceIdentifier instanceof inject_1.LazyServiceIdentifer) {
|
||
serviceIdentifier = serviceIdentifier.unwrap();
|
||
}
|
||
if (isManaged) {
|
||
var isObject = serviceIdentifier === Object;
|
||
var isFunction = serviceIdentifier === Function;
|
||
var isUndefined = serviceIdentifier === undefined;
|
||
var isUnknownType = (isObject || isFunction || isUndefined);
|
||
if (!isBaseClass && isUnknownType) {
|
||
var msg = ERROR_MSGS.MISSING_INJECT_ANNOTATION + " argument " + index + " in class " + constructorName + ".";
|
||
throw new Error(msg);
|
||
}
|
||
var target = new target_1.Target(literal_types_1.TargetTypeEnum.ConstructorArgument, metadata.targetName, serviceIdentifier);
|
||
target.metadata = targetMetadata;
|
||
return target;
|
||
}
|
||
return null;
|
||
}
|
||
function getConstructorArgsAsTargets(isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata, iterations) {
|
||
var targets = [];
|
||
for (var i = 0; i < iterations; i++) {
|
||
var index = i;
|
||
var target = getConstructorArgsAsTarget(index, isBaseClass, constructorName, serviceIdentifiers, constructorArgsMetadata);
|
||
if (target !== null) {
|
||
targets.push(target);
|
||
}
|
||
}
|
||
return targets;
|
||
}
|
||
function getClassPropsAsTargets(metadataReader, constructorFunc) {
|
||
var classPropsMetadata = metadataReader.getPropertiesMetadata(constructorFunc);
|
||
var targets = [];
|
||
var keys = Object.keys(classPropsMetadata);
|
||
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
|
||
var key = keys_1[_i];
|
||
var targetMetadata = classPropsMetadata[key];
|
||
var metadata = formatTargetMetadata(classPropsMetadata[key]);
|
||
var targetName = metadata.targetName || key;
|
||
var serviceIdentifier = (metadata.inject || metadata.multiInject);
|
||
var target = new target_1.Target(literal_types_1.TargetTypeEnum.ClassProperty, targetName, serviceIdentifier);
|
||
target.metadata = targetMetadata;
|
||
targets.push(target);
|
||
}
|
||
var baseConstructor = Object.getPrototypeOf(constructorFunc.prototype).constructor;
|
||
if (baseConstructor !== Object) {
|
||
var baseTargets = getClassPropsAsTargets(metadataReader, baseConstructor);
|
||
targets = __spreadArray(__spreadArray([], targets), baseTargets);
|
||
}
|
||
return targets;
|
||
}
|
||
function getBaseClassDependencyCount(metadataReader, func) {
|
||
var baseConstructor = Object.getPrototypeOf(func.prototype).constructor;
|
||
if (baseConstructor !== Object) {
|
||
var baseConstructorName = serialization_1.getFunctionName(baseConstructor);
|
||
var targets = getTargets(metadataReader, baseConstructorName, baseConstructor, true);
|
||
var metadata = targets.map(function (t) {
|
||
return t.metadata.filter(function (m) {
|
||
return m.key === METADATA_KEY.UNMANAGED_TAG;
|
||
});
|
||
});
|
||
var unmanagedCount = [].concat.apply([], metadata).length;
|
||
var dependencyCount = targets.length - unmanagedCount;
|
||
if (dependencyCount > 0) {
|
||
return dependencyCount;
|
||
}
|
||
else {
|
||
return getBaseClassDependencyCount(metadataReader, baseConstructor);
|
||
}
|
||
}
|
||
else {
|
||
return 0;
|
||
}
|
||
}
|
||
exports.getBaseClassDependencyCount = getBaseClassDependencyCount;
|
||
function formatTargetMetadata(targetMetadata) {
|
||
var targetMetadataMap = {};
|
||
targetMetadata.forEach(function (m) {
|
||
targetMetadataMap[m.key.toString()] = m.value;
|
||
});
|
||
return {
|
||
inject: targetMetadataMap[METADATA_KEY.INJECT_TAG],
|
||
multiInject: targetMetadataMap[METADATA_KEY.MULTI_INJECT_TAG],
|
||
targetName: targetMetadataMap[METADATA_KEY.NAME_TAG],
|
||
unmanaged: targetMetadataMap[METADATA_KEY.UNMANAGED_TAG]
|
||
};
|
||
}
|
||
//# sourceMappingURL=reflection_utils.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/request.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/request.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Request = void 0;
|
||
var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js");
|
||
var Request = (function () {
|
||
function Request(serviceIdentifier, parentContext, parentRequest, bindings, target) {
|
||
this.id = id_1.id();
|
||
this.serviceIdentifier = serviceIdentifier;
|
||
this.parentContext = parentContext;
|
||
this.parentRequest = parentRequest;
|
||
this.target = target;
|
||
this.childRequests = [];
|
||
this.bindings = (Array.isArray(bindings) ? bindings : [bindings]);
|
||
this.requestScope = parentRequest === null
|
||
? new Map()
|
||
: null;
|
||
}
|
||
Request.prototype.addChildRequest = function (serviceIdentifier, bindings, target) {
|
||
var child = new Request(serviceIdentifier, this.parentContext, this, bindings, target);
|
||
this.childRequests.push(child);
|
||
return child;
|
||
};
|
||
return Request;
|
||
}());
|
||
exports.Request = Request;
|
||
//# sourceMappingURL=request.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/planning/target.js":
|
||
/*!*******************************************************!*\
|
||
!*** ./node_modules/inversify/lib/planning/target.js ***!
|
||
\*******************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Target = void 0;
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var id_1 = __webpack_require__(/*! ../utils/id */ "./node_modules/inversify/lib/utils/id.js");
|
||
var metadata_1 = __webpack_require__(/*! ./metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var queryable_string_1 = __webpack_require__(/*! ./queryable_string */ "./node_modules/inversify/lib/planning/queryable_string.js");
|
||
var Target = (function () {
|
||
function Target(type, name, serviceIdentifier, namedOrTagged) {
|
||
this.id = id_1.id();
|
||
this.type = type;
|
||
this.serviceIdentifier = serviceIdentifier;
|
||
this.name = new queryable_string_1.QueryableString(name || "");
|
||
this.metadata = new Array();
|
||
var metadataItem = null;
|
||
if (typeof namedOrTagged === "string") {
|
||
metadataItem = new metadata_1.Metadata(METADATA_KEY.NAMED_TAG, namedOrTagged);
|
||
}
|
||
else if (namedOrTagged instanceof metadata_1.Metadata) {
|
||
metadataItem = namedOrTagged;
|
||
}
|
||
if (metadataItem !== null) {
|
||
this.metadata.push(metadataItem);
|
||
}
|
||
}
|
||
Target.prototype.hasTag = function (key) {
|
||
for (var _i = 0, _a = this.metadata; _i < _a.length; _i++) {
|
||
var m = _a[_i];
|
||
if (m.key === key) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
Target.prototype.isArray = function () {
|
||
return this.hasTag(METADATA_KEY.MULTI_INJECT_TAG);
|
||
};
|
||
Target.prototype.matchesArray = function (name) {
|
||
return this.matchesTag(METADATA_KEY.MULTI_INJECT_TAG)(name);
|
||
};
|
||
Target.prototype.isNamed = function () {
|
||
return this.hasTag(METADATA_KEY.NAMED_TAG);
|
||
};
|
||
Target.prototype.isTagged = function () {
|
||
return this.metadata.some(function (metadata) { return METADATA_KEY.NON_CUSTOM_TAG_KEYS.every(function (key) { return metadata.key !== key; }); });
|
||
};
|
||
Target.prototype.isOptional = function () {
|
||
return this.matchesTag(METADATA_KEY.OPTIONAL_TAG)(true);
|
||
};
|
||
Target.prototype.getNamedTag = function () {
|
||
if (this.isNamed()) {
|
||
return this.metadata.filter(function (m) { return m.key === METADATA_KEY.NAMED_TAG; })[0];
|
||
}
|
||
return null;
|
||
};
|
||
Target.prototype.getCustomTags = function () {
|
||
if (this.isTagged()) {
|
||
return this.metadata.filter(function (metadata) { return METADATA_KEY.NON_CUSTOM_TAG_KEYS.every(function (key) { return metadata.key !== key; }); });
|
||
}
|
||
else {
|
||
return null;
|
||
}
|
||
};
|
||
Target.prototype.matchesNamedTag = function (name) {
|
||
return this.matchesTag(METADATA_KEY.NAMED_TAG)(name);
|
||
};
|
||
Target.prototype.matchesTag = function (key) {
|
||
var _this = this;
|
||
return function (value) {
|
||
for (var _i = 0, _a = _this.metadata; _i < _a.length; _i++) {
|
||
var m = _a[_i];
|
||
if (m.key === key && m.value === value) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
};
|
||
return Target;
|
||
}());
|
||
exports.Target = Target;
|
||
//# sourceMappingURL=target.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/resolution/instantiation.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/resolution/instantiation.js ***!
|
||
\****************************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||
to[j] = from[i];
|
||
return to;
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.resolveInstance = void 0;
|
||
var error_msgs_1 = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
function _injectProperties(instance, childRequests, resolveRequest) {
|
||
var propertyInjectionsRequests = childRequests.filter(function (childRequest) {
|
||
return (childRequest.target !== null &&
|
||
childRequest.target.type === literal_types_1.TargetTypeEnum.ClassProperty);
|
||
});
|
||
var propertyInjections = propertyInjectionsRequests.map(resolveRequest);
|
||
propertyInjectionsRequests.forEach(function (r, index) {
|
||
var propertyName = "";
|
||
propertyName = r.target.name.value();
|
||
var injection = propertyInjections[index];
|
||
instance[propertyName] = injection;
|
||
});
|
||
return instance;
|
||
}
|
||
function _createInstance(Func, injections) {
|
||
return new (Func.bind.apply(Func, __spreadArray([void 0], injections)))();
|
||
}
|
||
function _postConstruct(constr, result) {
|
||
if (Reflect.hasMetadata(METADATA_KEY.POST_CONSTRUCT, constr)) {
|
||
var data = Reflect.getMetadata(METADATA_KEY.POST_CONSTRUCT, constr);
|
||
try {
|
||
result[data.value]();
|
||
}
|
||
catch (e) {
|
||
throw new Error(error_msgs_1.POST_CONSTRUCT_ERROR(constr.name, e.message));
|
||
}
|
||
}
|
||
}
|
||
function resolveInstance(constr, childRequests, resolveRequest) {
|
||
var result = null;
|
||
if (childRequests.length > 0) {
|
||
var constructorInjectionsRequests = childRequests.filter(function (childRequest) {
|
||
return (childRequest.target !== null && childRequest.target.type === literal_types_1.TargetTypeEnum.ConstructorArgument);
|
||
});
|
||
var constructorInjections = constructorInjectionsRequests.map(resolveRequest);
|
||
result = _createInstance(constr, constructorInjections);
|
||
result = _injectProperties(result, childRequests, resolveRequest);
|
||
}
|
||
else {
|
||
result = new constr();
|
||
}
|
||
_postConstruct(constr, result);
|
||
return result;
|
||
}
|
||
exports.resolveInstance = resolveInstance;
|
||
//# sourceMappingURL=instantiation.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/resolution/resolver.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/resolution/resolver.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.resolve = void 0;
|
||
var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
var exceptions_1 = __webpack_require__(/*! ../utils/exceptions */ "./node_modules/inversify/lib/utils/exceptions.js");
|
||
var serialization_1 = __webpack_require__(/*! ../utils/serialization */ "./node_modules/inversify/lib/utils/serialization.js");
|
||
var instantiation_1 = __webpack_require__(/*! ./instantiation */ "./node_modules/inversify/lib/resolution/instantiation.js");
|
||
var invokeFactory = function (factoryType, serviceIdentifier, fn) {
|
||
try {
|
||
return fn();
|
||
}
|
||
catch (error) {
|
||
if (exceptions_1.isStackOverflowExeption(error)) {
|
||
throw new Error(ERROR_MSGS.CIRCULAR_DEPENDENCY_IN_FACTORY(factoryType, serviceIdentifier.toString()));
|
||
}
|
||
else {
|
||
throw error;
|
||
}
|
||
}
|
||
};
|
||
var _resolveRequest = function (requestScope) {
|
||
return function (request) {
|
||
request.parentContext.setCurrentRequest(request);
|
||
var bindings = request.bindings;
|
||
var childRequests = request.childRequests;
|
||
var targetIsAnArray = request.target && request.target.isArray();
|
||
var targetParentIsNotAnArray = !request.parentRequest ||
|
||
!request.parentRequest.target ||
|
||
!request.target ||
|
||
!request.parentRequest.target.matchesArray(request.target.serviceIdentifier);
|
||
if (targetIsAnArray && targetParentIsNotAnArray) {
|
||
return childRequests.map(function (childRequest) {
|
||
var _f = _resolveRequest(requestScope);
|
||
return _f(childRequest);
|
||
});
|
||
}
|
||
else {
|
||
var result = null;
|
||
if (request.target.isOptional() && bindings.length === 0) {
|
||
return undefined;
|
||
}
|
||
var binding_1 = bindings[0];
|
||
var isSingleton = binding_1.scope === literal_types_1.BindingScopeEnum.Singleton;
|
||
var isRequestSingleton = binding_1.scope === literal_types_1.BindingScopeEnum.Request;
|
||
if (isSingleton && binding_1.activated) {
|
||
return binding_1.cache;
|
||
}
|
||
if (isRequestSingleton &&
|
||
requestScope !== null &&
|
||
requestScope.has(binding_1.id)) {
|
||
return requestScope.get(binding_1.id);
|
||
}
|
||
if (binding_1.type === literal_types_1.BindingTypeEnum.ConstantValue) {
|
||
result = binding_1.cache;
|
||
binding_1.activated = true;
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Function) {
|
||
result = binding_1.cache;
|
||
binding_1.activated = true;
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Constructor) {
|
||
result = binding_1.implementationType;
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.DynamicValue && binding_1.dynamicValue !== null) {
|
||
result = invokeFactory("toDynamicValue", binding_1.serviceIdentifier, function () { return binding_1.dynamicValue(request.parentContext); });
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Factory && binding_1.factory !== null) {
|
||
result = invokeFactory("toFactory", binding_1.serviceIdentifier, function () { return binding_1.factory(request.parentContext); });
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Provider && binding_1.provider !== null) {
|
||
result = invokeFactory("toProvider", binding_1.serviceIdentifier, function () { return binding_1.provider(request.parentContext); });
|
||
}
|
||
else if (binding_1.type === literal_types_1.BindingTypeEnum.Instance && binding_1.implementationType !== null) {
|
||
result = instantiation_1.resolveInstance(binding_1.implementationType, childRequests, _resolveRequest(requestScope));
|
||
}
|
||
else {
|
||
var serviceIdentifier = serialization_1.getServiceIdentifierAsString(request.serviceIdentifier);
|
||
throw new Error(ERROR_MSGS.INVALID_BINDING_TYPE + " " + serviceIdentifier);
|
||
}
|
||
if (typeof binding_1.onActivation === "function") {
|
||
result = binding_1.onActivation(request.parentContext, result);
|
||
}
|
||
if (isSingleton) {
|
||
binding_1.cache = result;
|
||
binding_1.activated = true;
|
||
}
|
||
if (isRequestSingleton &&
|
||
requestScope !== null &&
|
||
!requestScope.has(binding_1.id)) {
|
||
requestScope.set(binding_1.id, result);
|
||
}
|
||
return result;
|
||
}
|
||
};
|
||
};
|
||
function resolve(context) {
|
||
var _f = _resolveRequest(context.plan.rootRequest.requestScope);
|
||
return _f(context.plan.rootRequest);
|
||
}
|
||
exports.resolve = resolve;
|
||
//# sourceMappingURL=resolver.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_in_syntax.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_in_syntax.js ***!
|
||
\****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingInSyntax = void 0;
|
||
var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
var binding_when_on_syntax_1 = __webpack_require__(/*! ./binding_when_on_syntax */ "./node_modules/inversify/lib/syntax/binding_when_on_syntax.js");
|
||
var BindingInSyntax = (function () {
|
||
function BindingInSyntax(binding) {
|
||
this._binding = binding;
|
||
}
|
||
BindingInSyntax.prototype.inRequestScope = function () {
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Request;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingInSyntax.prototype.inSingletonScope = function () {
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingInSyntax.prototype.inTransientScope = function () {
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Transient;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
return BindingInSyntax;
|
||
}());
|
||
exports.BindingInSyntax = BindingInSyntax;
|
||
//# sourceMappingURL=binding_in_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_in_when_on_syntax.js":
|
||
/*!************************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_in_when_on_syntax.js ***!
|
||
\************************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingInWhenOnSyntax = void 0;
|
||
var binding_in_syntax_1 = __webpack_require__(/*! ./binding_in_syntax */ "./node_modules/inversify/lib/syntax/binding_in_syntax.js");
|
||
var binding_on_syntax_1 = __webpack_require__(/*! ./binding_on_syntax */ "./node_modules/inversify/lib/syntax/binding_on_syntax.js");
|
||
var binding_when_syntax_1 = __webpack_require__(/*! ./binding_when_syntax */ "./node_modules/inversify/lib/syntax/binding_when_syntax.js");
|
||
var BindingInWhenOnSyntax = (function () {
|
||
function BindingInWhenOnSyntax(binding) {
|
||
this._binding = binding;
|
||
this._bindingWhenSyntax = new binding_when_syntax_1.BindingWhenSyntax(this._binding);
|
||
this._bindingOnSyntax = new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
this._bindingInSyntax = new binding_in_syntax_1.BindingInSyntax(binding);
|
||
}
|
||
BindingInWhenOnSyntax.prototype.inRequestScope = function () {
|
||
return this._bindingInSyntax.inRequestScope();
|
||
};
|
||
BindingInWhenOnSyntax.prototype.inSingletonScope = function () {
|
||
return this._bindingInSyntax.inSingletonScope();
|
||
};
|
||
BindingInWhenOnSyntax.prototype.inTransientScope = function () {
|
||
return this._bindingInSyntax.inTransientScope();
|
||
};
|
||
BindingInWhenOnSyntax.prototype.when = function (constraint) {
|
||
return this._bindingWhenSyntax.when(constraint);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenTargetNamed = function (name) {
|
||
return this._bindingWhenSyntax.whenTargetNamed(name);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenTargetIsDefault = function () {
|
||
return this._bindingWhenSyntax.whenTargetIsDefault();
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenTargetTagged = function (tag, value) {
|
||
return this._bindingWhenSyntax.whenTargetTagged(tag, value);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenInjectedInto = function (parent) {
|
||
return this._bindingWhenSyntax.whenInjectedInto(parent);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenParentNamed = function (name) {
|
||
return this._bindingWhenSyntax.whenParentNamed(name);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenParentTagged = function (tag, value) {
|
||
return this._bindingWhenSyntax.whenParentTagged(tag, value);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenAnyAncestorIs = function (ancestor) {
|
||
return this._bindingWhenSyntax.whenAnyAncestorIs(ancestor);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenNoAncestorIs = function (ancestor) {
|
||
return this._bindingWhenSyntax.whenNoAncestorIs(ancestor);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenAnyAncestorNamed = function (name) {
|
||
return this._bindingWhenSyntax.whenAnyAncestorNamed(name);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenAnyAncestorTagged = function (tag, value) {
|
||
return this._bindingWhenSyntax.whenAnyAncestorTagged(tag, value);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenNoAncestorNamed = function (name) {
|
||
return this._bindingWhenSyntax.whenNoAncestorNamed(name);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenNoAncestorTagged = function (tag, value) {
|
||
return this._bindingWhenSyntax.whenNoAncestorTagged(tag, value);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenAnyAncestorMatches = function (constraint) {
|
||
return this._bindingWhenSyntax.whenAnyAncestorMatches(constraint);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.whenNoAncestorMatches = function (constraint) {
|
||
return this._bindingWhenSyntax.whenNoAncestorMatches(constraint);
|
||
};
|
||
BindingInWhenOnSyntax.prototype.onActivation = function (handler) {
|
||
return this._bindingOnSyntax.onActivation(handler);
|
||
};
|
||
return BindingInWhenOnSyntax;
|
||
}());
|
||
exports.BindingInWhenOnSyntax = BindingInWhenOnSyntax;
|
||
//# sourceMappingURL=binding_in_when_on_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_on_syntax.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_on_syntax.js ***!
|
||
\****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingOnSyntax = void 0;
|
||
var binding_when_syntax_1 = __webpack_require__(/*! ./binding_when_syntax */ "./node_modules/inversify/lib/syntax/binding_when_syntax.js");
|
||
var BindingOnSyntax = (function () {
|
||
function BindingOnSyntax(binding) {
|
||
this._binding = binding;
|
||
}
|
||
BindingOnSyntax.prototype.onActivation = function (handler) {
|
||
this._binding.onActivation = handler;
|
||
return new binding_when_syntax_1.BindingWhenSyntax(this._binding);
|
||
};
|
||
return BindingOnSyntax;
|
||
}());
|
||
exports.BindingOnSyntax = BindingOnSyntax;
|
||
//# sourceMappingURL=binding_on_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_to_syntax.js":
|
||
/*!****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_to_syntax.js ***!
|
||
\****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingToSyntax = void 0;
|
||
var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
var literal_types_1 = __webpack_require__(/*! ../constants/literal_types */ "./node_modules/inversify/lib/constants/literal_types.js");
|
||
var binding_in_when_on_syntax_1 = __webpack_require__(/*! ./binding_in_when_on_syntax */ "./node_modules/inversify/lib/syntax/binding_in_when_on_syntax.js");
|
||
var binding_when_on_syntax_1 = __webpack_require__(/*! ./binding_when_on_syntax */ "./node_modules/inversify/lib/syntax/binding_when_on_syntax.js");
|
||
var BindingToSyntax = (function () {
|
||
function BindingToSyntax(binding) {
|
||
this._binding = binding;
|
||
}
|
||
BindingToSyntax.prototype.to = function (constructor) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Instance;
|
||
this._binding.implementationType = constructor;
|
||
return new binding_in_when_on_syntax_1.BindingInWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toSelf = function () {
|
||
if (typeof this._binding.serviceIdentifier !== "function") {
|
||
throw new Error("" + ERROR_MSGS.INVALID_TO_SELF_VALUE);
|
||
}
|
||
var self = this._binding.serviceIdentifier;
|
||
return this.to(self);
|
||
};
|
||
BindingToSyntax.prototype.toConstantValue = function (value) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.ConstantValue;
|
||
this._binding.cache = value;
|
||
this._binding.dynamicValue = null;
|
||
this._binding.implementationType = null;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toDynamicValue = function (func) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.DynamicValue;
|
||
this._binding.cache = null;
|
||
this._binding.dynamicValue = func;
|
||
this._binding.implementationType = null;
|
||
return new binding_in_when_on_syntax_1.BindingInWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toConstructor = function (constructor) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Constructor;
|
||
this._binding.implementationType = constructor;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toFactory = function (factory) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Factory;
|
||
this._binding.factory = factory;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toFunction = function (func) {
|
||
if (typeof func !== "function") {
|
||
throw new Error(ERROR_MSGS.INVALID_FUNCTION_BINDING);
|
||
}
|
||
var bindingWhenOnSyntax = this.toConstantValue(func);
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Function;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
return bindingWhenOnSyntax;
|
||
};
|
||
BindingToSyntax.prototype.toAutoFactory = function (serviceIdentifier) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Factory;
|
||
this._binding.factory = function (context) {
|
||
var autofactory = function () { return context.container.get(serviceIdentifier); };
|
||
return autofactory;
|
||
};
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toProvider = function (provider) {
|
||
this._binding.type = literal_types_1.BindingTypeEnum.Provider;
|
||
this._binding.provider = provider;
|
||
this._binding.scope = literal_types_1.BindingScopeEnum.Singleton;
|
||
return new binding_when_on_syntax_1.BindingWhenOnSyntax(this._binding);
|
||
};
|
||
BindingToSyntax.prototype.toService = function (service) {
|
||
this.toDynamicValue(function (context) { return context.container.get(service); });
|
||
};
|
||
return BindingToSyntax;
|
||
}());
|
||
exports.BindingToSyntax = BindingToSyntax;
|
||
//# sourceMappingURL=binding_to_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_when_on_syntax.js":
|
||
/*!*********************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_when_on_syntax.js ***!
|
||
\*********************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingWhenOnSyntax = void 0;
|
||
var binding_on_syntax_1 = __webpack_require__(/*! ./binding_on_syntax */ "./node_modules/inversify/lib/syntax/binding_on_syntax.js");
|
||
var binding_when_syntax_1 = __webpack_require__(/*! ./binding_when_syntax */ "./node_modules/inversify/lib/syntax/binding_when_syntax.js");
|
||
var BindingWhenOnSyntax = (function () {
|
||
function BindingWhenOnSyntax(binding) {
|
||
this._binding = binding;
|
||
this._bindingWhenSyntax = new binding_when_syntax_1.BindingWhenSyntax(this._binding);
|
||
this._bindingOnSyntax = new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
}
|
||
BindingWhenOnSyntax.prototype.when = function (constraint) {
|
||
return this._bindingWhenSyntax.when(constraint);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenTargetNamed = function (name) {
|
||
return this._bindingWhenSyntax.whenTargetNamed(name);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenTargetIsDefault = function () {
|
||
return this._bindingWhenSyntax.whenTargetIsDefault();
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenTargetTagged = function (tag, value) {
|
||
return this._bindingWhenSyntax.whenTargetTagged(tag, value);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenInjectedInto = function (parent) {
|
||
return this._bindingWhenSyntax.whenInjectedInto(parent);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenParentNamed = function (name) {
|
||
return this._bindingWhenSyntax.whenParentNamed(name);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenParentTagged = function (tag, value) {
|
||
return this._bindingWhenSyntax.whenParentTagged(tag, value);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenAnyAncestorIs = function (ancestor) {
|
||
return this._bindingWhenSyntax.whenAnyAncestorIs(ancestor);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenNoAncestorIs = function (ancestor) {
|
||
return this._bindingWhenSyntax.whenNoAncestorIs(ancestor);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenAnyAncestorNamed = function (name) {
|
||
return this._bindingWhenSyntax.whenAnyAncestorNamed(name);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenAnyAncestorTagged = function (tag, value) {
|
||
return this._bindingWhenSyntax.whenAnyAncestorTagged(tag, value);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenNoAncestorNamed = function (name) {
|
||
return this._bindingWhenSyntax.whenNoAncestorNamed(name);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenNoAncestorTagged = function (tag, value) {
|
||
return this._bindingWhenSyntax.whenNoAncestorTagged(tag, value);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenAnyAncestorMatches = function (constraint) {
|
||
return this._bindingWhenSyntax.whenAnyAncestorMatches(constraint);
|
||
};
|
||
BindingWhenOnSyntax.prototype.whenNoAncestorMatches = function (constraint) {
|
||
return this._bindingWhenSyntax.whenNoAncestorMatches(constraint);
|
||
};
|
||
BindingWhenOnSyntax.prototype.onActivation = function (handler) {
|
||
return this._bindingOnSyntax.onActivation(handler);
|
||
};
|
||
return BindingWhenOnSyntax;
|
||
}());
|
||
exports.BindingWhenOnSyntax = BindingWhenOnSyntax;
|
||
//# sourceMappingURL=binding_when_on_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/binding_when_syntax.js":
|
||
/*!******************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/binding_when_syntax.js ***!
|
||
\******************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BindingWhenSyntax = void 0;
|
||
var binding_on_syntax_1 = __webpack_require__(/*! ./binding_on_syntax */ "./node_modules/inversify/lib/syntax/binding_on_syntax.js");
|
||
var constraint_helpers_1 = __webpack_require__(/*! ./constraint_helpers */ "./node_modules/inversify/lib/syntax/constraint_helpers.js");
|
||
var BindingWhenSyntax = (function () {
|
||
function BindingWhenSyntax(binding) {
|
||
this._binding = binding;
|
||
}
|
||
BindingWhenSyntax.prototype.when = function (constraint) {
|
||
this._binding.constraint = constraint;
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenTargetNamed = function (name) {
|
||
this._binding.constraint = constraint_helpers_1.namedConstraint(name);
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenTargetIsDefault = function () {
|
||
this._binding.constraint = function (request) {
|
||
var targetIsDefault = (request.target !== null) &&
|
||
(!request.target.isNamed()) &&
|
||
(!request.target.isTagged());
|
||
return targetIsDefault;
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenTargetTagged = function (tag, value) {
|
||
this._binding.constraint = constraint_helpers_1.taggedConstraint(tag)(value);
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenInjectedInto = function (parent) {
|
||
this._binding.constraint = function (request) {
|
||
return constraint_helpers_1.typeConstraint(parent)(request.parentRequest);
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenParentNamed = function (name) {
|
||
this._binding.constraint = function (request) {
|
||
return constraint_helpers_1.namedConstraint(name)(request.parentRequest);
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenParentTagged = function (tag, value) {
|
||
this._binding.constraint = function (request) {
|
||
return constraint_helpers_1.taggedConstraint(tag)(value)(request.parentRequest);
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenAnyAncestorIs = function (ancestor) {
|
||
this._binding.constraint = function (request) {
|
||
return constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.typeConstraint(ancestor));
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenNoAncestorIs = function (ancestor) {
|
||
this._binding.constraint = function (request) {
|
||
return !constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.typeConstraint(ancestor));
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenAnyAncestorNamed = function (name) {
|
||
this._binding.constraint = function (request) {
|
||
return constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.namedConstraint(name));
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenNoAncestorNamed = function (name) {
|
||
this._binding.constraint = function (request) {
|
||
return !constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.namedConstraint(name));
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenAnyAncestorTagged = function (tag, value) {
|
||
this._binding.constraint = function (request) {
|
||
return constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.taggedConstraint(tag)(value));
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenNoAncestorTagged = function (tag, value) {
|
||
this._binding.constraint = function (request) {
|
||
return !constraint_helpers_1.traverseAncerstors(request, constraint_helpers_1.taggedConstraint(tag)(value));
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenAnyAncestorMatches = function (constraint) {
|
||
this._binding.constraint = function (request) {
|
||
return constraint_helpers_1.traverseAncerstors(request, constraint);
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
BindingWhenSyntax.prototype.whenNoAncestorMatches = function (constraint) {
|
||
this._binding.constraint = function (request) {
|
||
return !constraint_helpers_1.traverseAncerstors(request, constraint);
|
||
};
|
||
return new binding_on_syntax_1.BindingOnSyntax(this._binding);
|
||
};
|
||
return BindingWhenSyntax;
|
||
}());
|
||
exports.BindingWhenSyntax = BindingWhenSyntax;
|
||
//# sourceMappingURL=binding_when_syntax.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/syntax/constraint_helpers.js":
|
||
/*!*****************************************************************!*\
|
||
!*** ./node_modules/inversify/lib/syntax/constraint_helpers.js ***!
|
||
\*****************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.typeConstraint = exports.namedConstraint = exports.taggedConstraint = exports.traverseAncerstors = void 0;
|
||
var METADATA_KEY = __webpack_require__(/*! ../constants/metadata_keys */ "./node_modules/inversify/lib/constants/metadata_keys.js");
|
||
var metadata_1 = __webpack_require__(/*! ../planning/metadata */ "./node_modules/inversify/lib/planning/metadata.js");
|
||
var traverseAncerstors = function (request, constraint) {
|
||
var parent = request.parentRequest;
|
||
if (parent !== null) {
|
||
return constraint(parent) ? true : traverseAncerstors(parent, constraint);
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
};
|
||
exports.traverseAncerstors = traverseAncerstors;
|
||
var taggedConstraint = function (key) { return function (value) {
|
||
var constraint = function (request) {
|
||
return request !== null && request.target !== null && request.target.matchesTag(key)(value);
|
||
};
|
||
constraint.metaData = new metadata_1.Metadata(key, value);
|
||
return constraint;
|
||
}; };
|
||
exports.taggedConstraint = taggedConstraint;
|
||
var namedConstraint = taggedConstraint(METADATA_KEY.NAMED_TAG);
|
||
exports.namedConstraint = namedConstraint;
|
||
var typeConstraint = function (type) { return function (request) {
|
||
var binding = null;
|
||
if (request !== null) {
|
||
binding = request.bindings[0];
|
||
if (typeof type === "string") {
|
||
var serviceIdentifier = binding.serviceIdentifier;
|
||
return serviceIdentifier === type;
|
||
}
|
||
else {
|
||
var constructor = request.bindings[0].implementationType;
|
||
return type === constructor;
|
||
}
|
||
}
|
||
return false;
|
||
}; };
|
||
exports.typeConstraint = typeConstraint;
|
||
//# sourceMappingURL=constraint_helpers.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/utils/binding_utils.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/utils/binding_utils.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.multiBindToService = void 0;
|
||
var multiBindToService = function (container) {
|
||
return function (service) {
|
||
return function () {
|
||
var types = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
types[_i] = arguments[_i];
|
||
}
|
||
return types.forEach(function (t) { return container.bind(t).toService(service); });
|
||
};
|
||
};
|
||
};
|
||
exports.multiBindToService = multiBindToService;
|
||
//# sourceMappingURL=binding_utils.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/utils/exceptions.js":
|
||
/*!********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/utils/exceptions.js ***!
|
||
\********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.isStackOverflowExeption = void 0;
|
||
var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
function isStackOverflowExeption(error) {
|
||
return (error instanceof RangeError ||
|
||
error.message === ERROR_MSGS.STACK_OVERFLOW);
|
||
}
|
||
exports.isStackOverflowExeption = isStackOverflowExeption;
|
||
//# sourceMappingURL=exceptions.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/utils/id.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/inversify/lib/utils/id.js ***!
|
||
\************************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.id = void 0;
|
||
var idCounter = 0;
|
||
function id() {
|
||
return idCounter++;
|
||
}
|
||
exports.id = id;
|
||
//# sourceMappingURL=id.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/inversify/lib/utils/serialization.js":
|
||
/*!***********************************************************!*\
|
||
!*** ./node_modules/inversify/lib/utils/serialization.js ***!
|
||
\***********************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.circularDependencyToException = exports.listMetadataForTarget = exports.listRegisteredBindingsForServiceIdentifier = exports.getServiceIdentifierAsString = exports.getFunctionName = void 0;
|
||
var ERROR_MSGS = __webpack_require__(/*! ../constants/error_msgs */ "./node_modules/inversify/lib/constants/error_msgs.js");
|
||
function getServiceIdentifierAsString(serviceIdentifier) {
|
||
if (typeof serviceIdentifier === "function") {
|
||
var _serviceIdentifier = serviceIdentifier;
|
||
return _serviceIdentifier.name;
|
||
}
|
||
else if (typeof serviceIdentifier === "symbol") {
|
||
return serviceIdentifier.toString();
|
||
}
|
||
else {
|
||
var _serviceIdentifier = serviceIdentifier;
|
||
return _serviceIdentifier;
|
||
}
|
||
}
|
||
exports.getServiceIdentifierAsString = getServiceIdentifierAsString;
|
||
function listRegisteredBindingsForServiceIdentifier(container, serviceIdentifier, getBindings) {
|
||
var registeredBindingsList = "";
|
||
var registeredBindings = getBindings(container, serviceIdentifier);
|
||
if (registeredBindings.length !== 0) {
|
||
registeredBindingsList = "\nRegistered bindings:";
|
||
registeredBindings.forEach(function (binding) {
|
||
var name = "Object";
|
||
if (binding.implementationType !== null) {
|
||
name = getFunctionName(binding.implementationType);
|
||
}
|
||
registeredBindingsList = registeredBindingsList + "\n " + name;
|
||
if (binding.constraint.metaData) {
|
||
registeredBindingsList = registeredBindingsList + " - " + binding.constraint.metaData;
|
||
}
|
||
});
|
||
}
|
||
return registeredBindingsList;
|
||
}
|
||
exports.listRegisteredBindingsForServiceIdentifier = listRegisteredBindingsForServiceIdentifier;
|
||
function alreadyDependencyChain(request, serviceIdentifier) {
|
||
if (request.parentRequest === null) {
|
||
return false;
|
||
}
|
||
else if (request.parentRequest.serviceIdentifier === serviceIdentifier) {
|
||
return true;
|
||
}
|
||
else {
|
||
return alreadyDependencyChain(request.parentRequest, serviceIdentifier);
|
||
}
|
||
}
|
||
function dependencyChainToString(request) {
|
||
function _createStringArr(req, result) {
|
||
if (result === void 0) { result = []; }
|
||
var serviceIdentifier = getServiceIdentifierAsString(req.serviceIdentifier);
|
||
result.push(serviceIdentifier);
|
||
if (req.parentRequest !== null) {
|
||
return _createStringArr(req.parentRequest, result);
|
||
}
|
||
return result;
|
||
}
|
||
var stringArr = _createStringArr(request);
|
||
return stringArr.reverse().join(" --> ");
|
||
}
|
||
function circularDependencyToException(request) {
|
||
request.childRequests.forEach(function (childRequest) {
|
||
if (alreadyDependencyChain(childRequest, childRequest.serviceIdentifier)) {
|
||
var services = dependencyChainToString(childRequest);
|
||
throw new Error(ERROR_MSGS.CIRCULAR_DEPENDENCY + " " + services);
|
||
}
|
||
else {
|
||
circularDependencyToException(childRequest);
|
||
}
|
||
});
|
||
}
|
||
exports.circularDependencyToException = circularDependencyToException;
|
||
function listMetadataForTarget(serviceIdentifierString, target) {
|
||
if (target.isTagged() || target.isNamed()) {
|
||
var m_1 = "";
|
||
var namedTag = target.getNamedTag();
|
||
var otherTags = target.getCustomTags();
|
||
if (namedTag !== null) {
|
||
m_1 += namedTag.toString() + "\n";
|
||
}
|
||
if (otherTags !== null) {
|
||
otherTags.forEach(function (tag) {
|
||
m_1 += tag.toString() + "\n";
|
||
});
|
||
}
|
||
return " " + serviceIdentifierString + "\n " + serviceIdentifierString + " - " + m_1;
|
||
}
|
||
else {
|
||
return " " + serviceIdentifierString;
|
||
}
|
||
}
|
||
exports.listMetadataForTarget = listMetadataForTarget;
|
||
function getFunctionName(v) {
|
||
if (v.name) {
|
||
return v.name;
|
||
}
|
||
else {
|
||
var name_1 = v.toString();
|
||
var match = name_1.match(/^function\s*([^\s(]+)/);
|
||
return match ? match[1] : "Anonymous function: " + name_1;
|
||
}
|
||
}
|
||
exports.getFunctionName = getFunctionName;
|
||
//# sourceMappingURL=serialization.js.map
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/minimatch/minimatch.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/minimatch/minimatch.js ***!
|
||
\*********************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
module.exports = minimatch
|
||
minimatch.Minimatch = Minimatch
|
||
|
||
var path = { sep: '/' }
|
||
try {
|
||
path = __webpack_require__(/*! path */ "path")
|
||
} catch (er) {}
|
||
|
||
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
|
||
var expand = __webpack_require__(/*! brace-expansion */ "./node_modules/brace-expansion/index.js")
|
||
|
||
var plTypes = {
|
||
'!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
|
||
'?': { open: '(?:', close: ')?' },
|
||
'+': { open: '(?:', close: ')+' },
|
||
'*': { open: '(?:', close: ')*' },
|
||
'@': { open: '(?:', close: ')' }
|
||
}
|
||
|
||
// any single thing other than /
|
||
// don't need to escape / when using new RegExp()
|
||
var qmark = '[^/]'
|
||
|
||
// * => any number of characters
|
||
var star = qmark + '*?'
|
||
|
||
// ** when dots are allowed. Anything goes, except .. and .
|
||
// not (^ or / followed by one or two dots followed by $ or /),
|
||
// followed by anything, any number of times.
|
||
var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
|
||
|
||
// not a ^ or / followed by a dot,
|
||
// followed by anything, any number of times.
|
||
var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
|
||
|
||
// characters that need to be escaped in RegExp.
|
||
var reSpecials = charSet('().*{}+?[]^$\\!')
|
||
|
||
// "abc" -> { a:true, b:true, c:true }
|
||
function charSet (s) {
|
||
return s.split('').reduce(function (set, c) {
|
||
set[c] = true
|
||
return set
|
||
}, {})
|
||
}
|
||
|
||
// normalizes slashes.
|
||
var slashSplit = /\/+/
|
||
|
||
minimatch.filter = filter
|
||
function filter (pattern, options) {
|
||
options = options || {}
|
||
return function (p, i, list) {
|
||
return minimatch(p, pattern, options)
|
||
}
|
||
}
|
||
|
||
function ext (a, b) {
|
||
a = a || {}
|
||
b = b || {}
|
||
var t = {}
|
||
Object.keys(b).forEach(function (k) {
|
||
t[k] = b[k]
|
||
})
|
||
Object.keys(a).forEach(function (k) {
|
||
t[k] = a[k]
|
||
})
|
||
return t
|
||
}
|
||
|
||
minimatch.defaults = function (def) {
|
||
if (!def || !Object.keys(def).length) return minimatch
|
||
|
||
var orig = minimatch
|
||
|
||
var m = function minimatch (p, pattern, options) {
|
||
return orig.minimatch(p, pattern, ext(def, options))
|
||
}
|
||
|
||
m.Minimatch = function Minimatch (pattern, options) {
|
||
return new orig.Minimatch(pattern, ext(def, options))
|
||
}
|
||
|
||
return m
|
||
}
|
||
|
||
Minimatch.defaults = function (def) {
|
||
if (!def || !Object.keys(def).length) return Minimatch
|
||
return minimatch.defaults(def).Minimatch
|
||
}
|
||
|
||
function minimatch (p, pattern, options) {
|
||
if (typeof pattern !== 'string') {
|
||
throw new TypeError('glob pattern string required')
|
||
}
|
||
|
||
if (!options) options = {}
|
||
|
||
// shortcut: comments match nothing.
|
||
if (!options.nocomment && pattern.charAt(0) === '#') {
|
||
return false
|
||
}
|
||
|
||
// "" only matches ""
|
||
if (pattern.trim() === '') return p === ''
|
||
|
||
return new Minimatch(pattern, options).match(p)
|
||
}
|
||
|
||
function Minimatch (pattern, options) {
|
||
if (!(this instanceof Minimatch)) {
|
||
return new Minimatch(pattern, options)
|
||
}
|
||
|
||
if (typeof pattern !== 'string') {
|
||
throw new TypeError('glob pattern string required')
|
||
}
|
||
|
||
if (!options) options = {}
|
||
pattern = pattern.trim()
|
||
|
||
// windows support: need to use /, not \
|
||
if (path.sep !== '/') {
|
||
pattern = pattern.split(path.sep).join('/')
|
||
}
|
||
|
||
this.options = options
|
||
this.set = []
|
||
this.pattern = pattern
|
||
this.regexp = null
|
||
this.negate = false
|
||
this.comment = false
|
||
this.empty = false
|
||
|
||
// make the set of regexps etc.
|
||
this.make()
|
||
}
|
||
|
||
Minimatch.prototype.debug = function () {}
|
||
|
||
Minimatch.prototype.make = make
|
||
function make () {
|
||
// don't do it more than once.
|
||
if (this._made) return
|
||
|
||
var pattern = this.pattern
|
||
var options = this.options
|
||
|
||
// empty patterns and comments match nothing.
|
||
if (!options.nocomment && pattern.charAt(0) === '#') {
|
||
this.comment = true
|
||
return
|
||
}
|
||
if (!pattern) {
|
||
this.empty = true
|
||
return
|
||
}
|
||
|
||
// step 1: figure out negation, etc.
|
||
this.parseNegate()
|
||
|
||
// step 2: expand braces
|
||
var set = this.globSet = this.braceExpand()
|
||
|
||
if (options.debug) this.debug = console.error
|
||
|
||
this.debug(this.pattern, set)
|
||
|
||
// step 3: now we have a set, so turn each one into a series of path-portion
|
||
// matching patterns.
|
||
// These will be regexps, except in the case of "**", which is
|
||
// set to the GLOBSTAR object for globstar behavior,
|
||
// and will not contain any / characters
|
||
set = this.globParts = set.map(function (s) {
|
||
return s.split(slashSplit)
|
||
})
|
||
|
||
this.debug(this.pattern, set)
|
||
|
||
// glob --> regexps
|
||
set = set.map(function (s, si, set) {
|
||
return s.map(this.parse, this)
|
||
}, this)
|
||
|
||
this.debug(this.pattern, set)
|
||
|
||
// filter out everything that didn't compile properly.
|
||
set = set.filter(function (s) {
|
||
return s.indexOf(false) === -1
|
||
})
|
||
|
||
this.debug(this.pattern, set)
|
||
|
||
this.set = set
|
||
}
|
||
|
||
Minimatch.prototype.parseNegate = parseNegate
|
||
function parseNegate () {
|
||
var pattern = this.pattern
|
||
var negate = false
|
||
var options = this.options
|
||
var negateOffset = 0
|
||
|
||
if (options.nonegate) return
|
||
|
||
for (var i = 0, l = pattern.length
|
||
; i < l && pattern.charAt(i) === '!'
|
||
; i++) {
|
||
negate = !negate
|
||
negateOffset++
|
||
}
|
||
|
||
if (negateOffset) this.pattern = pattern.substr(negateOffset)
|
||
this.negate = negate
|
||
}
|
||
|
||
// Brace expansion:
|
||
// a{b,c}d -> abd acd
|
||
// a{b,}c -> abc ac
|
||
// a{0..3}d -> a0d a1d a2d a3d
|
||
// a{b,c{d,e}f}g -> abg acdfg acefg
|
||
// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
|
||
//
|
||
// Invalid sets are not expanded.
|
||
// a{2..}b -> a{2..}b
|
||
// a{b}c -> a{b}c
|
||
minimatch.braceExpand = function (pattern, options) {
|
||
return braceExpand(pattern, options)
|
||
}
|
||
|
||
Minimatch.prototype.braceExpand = braceExpand
|
||
|
||
function braceExpand (pattern, options) {
|
||
if (!options) {
|
||
if (this instanceof Minimatch) {
|
||
options = this.options
|
||
} else {
|
||
options = {}
|
||
}
|
||
}
|
||
|
||
pattern = typeof pattern === 'undefined'
|
||
? this.pattern : pattern
|
||
|
||
if (typeof pattern === 'undefined') {
|
||
throw new TypeError('undefined pattern')
|
||
}
|
||
|
||
if (options.nobrace ||
|
||
!pattern.match(/\{.*\}/)) {
|
||
// shortcut. no need to expand.
|
||
return [pattern]
|
||
}
|
||
|
||
return expand(pattern)
|
||
}
|
||
|
||
// parse a component of the expanded set.
|
||
// At this point, no pattern may contain "/" in it
|
||
// so we're going to return a 2d array, where each entry is the full
|
||
// pattern, split on '/', and then turned into a regular expression.
|
||
// A regexp is made at the end which joins each array with an
|
||
// escaped /, and another full one which joins each regexp with |.
|
||
//
|
||
// Following the lead of Bash 4.1, note that "**" only has special meaning
|
||
// when it is the *only* thing in a path portion. Otherwise, any series
|
||
// of * is equivalent to a single *. Globstar behavior is enabled by
|
||
// default, and can be disabled by setting options.noglobstar.
|
||
Minimatch.prototype.parse = parse
|
||
var SUBPARSE = {}
|
||
function parse (pattern, isSub) {
|
||
if (pattern.length > 1024 * 64) {
|
||
throw new TypeError('pattern is too long')
|
||
}
|
||
|
||
var options = this.options
|
||
|
||
// shortcuts
|
||
if (!options.noglobstar && pattern === '**') return GLOBSTAR
|
||
if (pattern === '') return ''
|
||
|
||
var re = ''
|
||
var hasMagic = !!options.nocase
|
||
var escaping = false
|
||
// ? => one single character
|
||
var patternListStack = []
|
||
var negativeLists = []
|
||
var stateChar
|
||
var inClass = false
|
||
var reClassStart = -1
|
||
var classStart = -1
|
||
// . and .. never match anything that doesn't start with .,
|
||
// even when options.dot is set.
|
||
var patternStart = pattern.charAt(0) === '.' ? '' // anything
|
||
// not (start or / followed by . or .. followed by / or end)
|
||
: options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
|
||
: '(?!\\.)'
|
||
var self = this
|
||
|
||
function clearStateChar () {
|
||
if (stateChar) {
|
||
// we had some state-tracking character
|
||
// that wasn't consumed by this pass.
|
||
switch (stateChar) {
|
||
case '*':
|
||
re += star
|
||
hasMagic = true
|
||
break
|
||
case '?':
|
||
re += qmark
|
||
hasMagic = true
|
||
break
|
||
default:
|
||
re += '\\' + stateChar
|
||
break
|
||
}
|
||
self.debug('clearStateChar %j %j', stateChar, re)
|
||
stateChar = false
|
||
}
|
||
}
|
||
|
||
for (var i = 0, len = pattern.length, c
|
||
; (i < len) && (c = pattern.charAt(i))
|
||
; i++) {
|
||
this.debug('%s\t%s %s %j', pattern, i, re, c)
|
||
|
||
// skip over any that are escaped.
|
||
if (escaping && reSpecials[c]) {
|
||
re += '\\' + c
|
||
escaping = false
|
||
continue
|
||
}
|
||
|
||
switch (c) {
|
||
case '/':
|
||
// completely not allowed, even escaped.
|
||
// Should already be path-split by now.
|
||
return false
|
||
|
||
case '\\':
|
||
clearStateChar()
|
||
escaping = true
|
||
continue
|
||
|
||
// the various stateChar values
|
||
// for the "extglob" stuff.
|
||
case '?':
|
||
case '*':
|
||
case '+':
|
||
case '@':
|
||
case '!':
|
||
this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
|
||
|
||
// all of those are literals inside a class, except that
|
||
// the glob [!a] means [^a] in regexp
|
||
if (inClass) {
|
||
this.debug(' in class')
|
||
if (c === '!' && i === classStart + 1) c = '^'
|
||
re += c
|
||
continue
|
||
}
|
||
|
||
// if we already have a stateChar, then it means
|
||
// that there was something like ** or +? in there.
|
||
// Handle the stateChar, then proceed with this one.
|
||
self.debug('call clearStateChar %j', stateChar)
|
||
clearStateChar()
|
||
stateChar = c
|
||
// if extglob is disabled, then +(asdf|foo) isn't a thing.
|
||
// just clear the statechar *now*, rather than even diving into
|
||
// the patternList stuff.
|
||
if (options.noext) clearStateChar()
|
||
continue
|
||
|
||
case '(':
|
||
if (inClass) {
|
||
re += '('
|
||
continue
|
||
}
|
||
|
||
if (!stateChar) {
|
||
re += '\\('
|
||
continue
|
||
}
|
||
|
||
patternListStack.push({
|
||
type: stateChar,
|
||
start: i - 1,
|
||
reStart: re.length,
|
||
open: plTypes[stateChar].open,
|
||
close: plTypes[stateChar].close
|
||
})
|
||
// negation is (?:(?!js)[^/]*)
|
||
re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
|
||
this.debug('plType %j %j', stateChar, re)
|
||
stateChar = false
|
||
continue
|
||
|
||
case ')':
|
||
if (inClass || !patternListStack.length) {
|
||
re += '\\)'
|
||
continue
|
||
}
|
||
|
||
clearStateChar()
|
||
hasMagic = true
|
||
var pl = patternListStack.pop()
|
||
// negation is (?:(?!js)[^/]*)
|
||
// The others are (?:<pattern>)<type>
|
||
re += pl.close
|
||
if (pl.type === '!') {
|
||
negativeLists.push(pl)
|
||
}
|
||
pl.reEnd = re.length
|
||
continue
|
||
|
||
case '|':
|
||
if (inClass || !patternListStack.length || escaping) {
|
||
re += '\\|'
|
||
escaping = false
|
||
continue
|
||
}
|
||
|
||
clearStateChar()
|
||
re += '|'
|
||
continue
|
||
|
||
// these are mostly the same in regexp and glob
|
||
case '[':
|
||
// swallow any state-tracking char before the [
|
||
clearStateChar()
|
||
|
||
if (inClass) {
|
||
re += '\\' + c
|
||
continue
|
||
}
|
||
|
||
inClass = true
|
||
classStart = i
|
||
reClassStart = re.length
|
||
re += c
|
||
continue
|
||
|
||
case ']':
|
||
// a right bracket shall lose its special
|
||
// meaning and represent itself in
|
||
// a bracket expression if it occurs
|
||
// first in the list. -- POSIX.2 2.8.3.2
|
||
if (i === classStart + 1 || !inClass) {
|
||
re += '\\' + c
|
||
escaping = false
|
||
continue
|
||
}
|
||
|
||
// handle the case where we left a class open.
|
||
// "[z-a]" is valid, equivalent to "\[z-a\]"
|
||
if (inClass) {
|
||
// split where the last [ was, make sure we don't have
|
||
// an invalid re. if so, re-walk the contents of the
|
||
// would-be class to re-translate any characters that
|
||
// were passed through as-is
|
||
// TODO: It would probably be faster to determine this
|
||
// without a try/catch and a new RegExp, but it's tricky
|
||
// to do safely. For now, this is safe and works.
|
||
var cs = pattern.substring(classStart + 1, i)
|
||
try {
|
||
RegExp('[' + cs + ']')
|
||
} catch (er) {
|
||
// not a valid class!
|
||
var sp = this.parse(cs, SUBPARSE)
|
||
re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
|
||
hasMagic = hasMagic || sp[1]
|
||
inClass = false
|
||
continue
|
||
}
|
||
}
|
||
|
||
// finish up the class.
|
||
hasMagic = true
|
||
inClass = false
|
||
re += c
|
||
continue
|
||
|
||
default:
|
||
// swallow any state char that wasn't consumed
|
||
clearStateChar()
|
||
|
||
if (escaping) {
|
||
// no need
|
||
escaping = false
|
||
} else if (reSpecials[c]
|
||
&& !(c === '^' && inClass)) {
|
||
re += '\\'
|
||
}
|
||
|
||
re += c
|
||
|
||
} // switch
|
||
} // for
|
||
|
||
// handle the case where we left a class open.
|
||
// "[abc" is valid, equivalent to "\[abc"
|
||
if (inClass) {
|
||
// split where the last [ was, and escape it
|
||
// this is a huge pita. We now have to re-walk
|
||
// the contents of the would-be class to re-translate
|
||
// any characters that were passed through as-is
|
||
cs = pattern.substr(classStart + 1)
|
||
sp = this.parse(cs, SUBPARSE)
|
||
re = re.substr(0, reClassStart) + '\\[' + sp[0]
|
||
hasMagic = hasMagic || sp[1]
|
||
}
|
||
|
||
// handle the case where we had a +( thing at the *end*
|
||
// of the pattern.
|
||
// each pattern list stack adds 3 chars, and we need to go through
|
||
// and escape any | chars that were passed through as-is for the regexp.
|
||
// Go through and escape them, taking care not to double-escape any
|
||
// | chars that were already escaped.
|
||
for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
|
||
var tail = re.slice(pl.reStart + pl.open.length)
|
||
this.debug('setting tail', re, pl)
|
||
// maybe some even number of \, then maybe 1 \, followed by a |
|
||
tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) {
|
||
if (!$2) {
|
||
// the | isn't already escaped, so escape it.
|
||
$2 = '\\'
|
||
}
|
||
|
||
// need to escape all those slashes *again*, without escaping the
|
||
// one that we need for escaping the | character. As it works out,
|
||
// escaping an even number of slashes can be done by simply repeating
|
||
// it exactly after itself. That's why this trick works.
|
||
//
|
||
// I am sorry that you have to see this.
|
||
return $1 + $1 + $2 + '|'
|
||
})
|
||
|
||
this.debug('tail=%j\n %s', tail, tail, pl, re)
|
||
var t = pl.type === '*' ? star
|
||
: pl.type === '?' ? qmark
|
||
: '\\' + pl.type
|
||
|
||
hasMagic = true
|
||
re = re.slice(0, pl.reStart) + t + '\\(' + tail
|
||
}
|
||
|
||
// handle trailing things that only matter at the very end.
|
||
clearStateChar()
|
||
if (escaping) {
|
||
// trailing \\
|
||
re += '\\\\'
|
||
}
|
||
|
||
// only need to apply the nodot start if the re starts with
|
||
// something that could conceivably capture a dot
|
||
var addPatternStart = false
|
||
switch (re.charAt(0)) {
|
||
case '.':
|
||
case '[':
|
||
case '(': addPatternStart = true
|
||
}
|
||
|
||
// Hack to work around lack of negative lookbehind in JS
|
||
// A pattern like: *.!(x).!(y|z) needs to ensure that a name
|
||
// like 'a.xyz.yz' doesn't match. So, the first negative
|
||
// lookahead, has to look ALL the way ahead, to the end of
|
||
// the pattern.
|
||
for (var n = negativeLists.length - 1; n > -1; n--) {
|
||
var nl = negativeLists[n]
|
||
|
||
var nlBefore = re.slice(0, nl.reStart)
|
||
var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)
|
||
var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)
|
||
var nlAfter = re.slice(nl.reEnd)
|
||
|
||
nlLast += nlAfter
|
||
|
||
// Handle nested stuff like *(*.js|!(*.json)), where open parens
|
||
// mean that we should *not* include the ) in the bit that is considered
|
||
// "after" the negated section.
|
||
var openParensBefore = nlBefore.split('(').length - 1
|
||
var cleanAfter = nlAfter
|
||
for (i = 0; i < openParensBefore; i++) {
|
||
cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')
|
||
}
|
||
nlAfter = cleanAfter
|
||
|
||
var dollar = ''
|
||
if (nlAfter === '' && isSub !== SUBPARSE) {
|
||
dollar = '$'
|
||
}
|
||
var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
|
||
re = newRe
|
||
}
|
||
|
||
// if the re is not "" at this point, then we need to make sure
|
||
// it doesn't match against an empty path part.
|
||
// Otherwise a/* will match a/, which it should not.
|
||
if (re !== '' && hasMagic) {
|
||
re = '(?=.)' + re
|
||
}
|
||
|
||
if (addPatternStart) {
|
||
re = patternStart + re
|
||
}
|
||
|
||
// parsing just a piece of a larger pattern.
|
||
if (isSub === SUBPARSE) {
|
||
return [re, hasMagic]
|
||
}
|
||
|
||
// skip the regexp for non-magical patterns
|
||
// unescape anything in it, though, so that it'll be
|
||
// an exact match against a file etc.
|
||
if (!hasMagic) {
|
||
return globUnescape(pattern)
|
||
}
|
||
|
||
var flags = options.nocase ? 'i' : ''
|
||
try {
|
||
var regExp = new RegExp('^' + re + '$', flags)
|
||
} catch (er) {
|
||
// If it was an invalid regular expression, then it can't match
|
||
// anything. This trick looks for a character after the end of
|
||
// the string, which is of course impossible, except in multi-line
|
||
// mode, but it's not a /m regex.
|
||
return new RegExp('$.')
|
||
}
|
||
|
||
regExp._glob = pattern
|
||
regExp._src = re
|
||
|
||
return regExp
|
||
}
|
||
|
||
minimatch.makeRe = function (pattern, options) {
|
||
return new Minimatch(pattern, options || {}).makeRe()
|
||
}
|
||
|
||
Minimatch.prototype.makeRe = makeRe
|
||
function makeRe () {
|
||
if (this.regexp || this.regexp === false) return this.regexp
|
||
|
||
// at this point, this.set is a 2d array of partial
|
||
// pattern strings, or "**".
|
||
//
|
||
// It's better to use .match(). This function shouldn't
|
||
// be used, really, but it's pretty convenient sometimes,
|
||
// when you just want to work with a regex.
|
||
var set = this.set
|
||
|
||
if (!set.length) {
|
||
this.regexp = false
|
||
return this.regexp
|
||
}
|
||
var options = this.options
|
||
|
||
var twoStar = options.noglobstar ? star
|
||
: options.dot ? twoStarDot
|
||
: twoStarNoDot
|
||
var flags = options.nocase ? 'i' : ''
|
||
|
||
var re = set.map(function (pattern) {
|
||
return pattern.map(function (p) {
|
||
return (p === GLOBSTAR) ? twoStar
|
||
: (typeof p === 'string') ? regExpEscape(p)
|
||
: p._src
|
||
}).join('\\\/')
|
||
}).join('|')
|
||
|
||
// must match entire pattern
|
||
// ending in a * or ** will make it less strict.
|
||
re = '^(?:' + re + ')$'
|
||
|
||
// can match anything, as long as it's not this.
|
||
if (this.negate) re = '^(?!' + re + ').*$'
|
||
|
||
try {
|
||
this.regexp = new RegExp(re, flags)
|
||
} catch (ex) {
|
||
this.regexp = false
|
||
}
|
||
return this.regexp
|
||
}
|
||
|
||
minimatch.match = function (list, pattern, options) {
|
||
options = options || {}
|
||
var mm = new Minimatch(pattern, options)
|
||
list = list.filter(function (f) {
|
||
return mm.match(f)
|
||
})
|
||
if (mm.options.nonull && !list.length) {
|
||
list.push(pattern)
|
||
}
|
||
return list
|
||
}
|
||
|
||
Minimatch.prototype.match = match
|
||
function match (f, partial) {
|
||
this.debug('match', f, this.pattern)
|
||
// short-circuit in the case of busted things.
|
||
// comments, etc.
|
||
if (this.comment) return false
|
||
if (this.empty) return f === ''
|
||
|
||
if (f === '/' && partial) return true
|
||
|
||
var options = this.options
|
||
|
||
// windows: need to use /, not \
|
||
if (path.sep !== '/') {
|
||
f = f.split(path.sep).join('/')
|
||
}
|
||
|
||
// treat the test path as a set of pathparts.
|
||
f = f.split(slashSplit)
|
||
this.debug(this.pattern, 'split', f)
|
||
|
||
// just ONE of the pattern sets in this.set needs to match
|
||
// in order for it to be valid. If negating, then just one
|
||
// match means that we have failed.
|
||
// Either way, return on the first hit.
|
||
|
||
var set = this.set
|
||
this.debug(this.pattern, 'set', set)
|
||
|
||
// Find the basename of the path by looking for the last non-empty segment
|
||
var filename
|
||
var i
|
||
for (i = f.length - 1; i >= 0; i--) {
|
||
filename = f[i]
|
||
if (filename) break
|
||
}
|
||
|
||
for (i = 0; i < set.length; i++) {
|
||
var pattern = set[i]
|
||
var file = f
|
||
if (options.matchBase && pattern.length === 1) {
|
||
file = [filename]
|
||
}
|
||
var hit = this.matchOne(file, pattern, partial)
|
||
if (hit) {
|
||
if (options.flipNegate) return true
|
||
return !this.negate
|
||
}
|
||
}
|
||
|
||
// didn't get any hits. this is success if it's a negative
|
||
// pattern, failure otherwise.
|
||
if (options.flipNegate) return false
|
||
return this.negate
|
||
}
|
||
|
||
// set partial to true to test if, for example,
|
||
// "/a/b" matches the start of "/*/b/*/d"
|
||
// Partial means, if you run out of file before you run
|
||
// out of pattern, then that's fine, as long as all
|
||
// the parts match.
|
||
Minimatch.prototype.matchOne = function (file, pattern, partial) {
|
||
var options = this.options
|
||
|
||
this.debug('matchOne',
|
||
{ 'this': this, file: file, pattern: pattern })
|
||
|
||
this.debug('matchOne', file.length, pattern.length)
|
||
|
||
for (var fi = 0,
|
||
pi = 0,
|
||
fl = file.length,
|
||
pl = pattern.length
|
||
; (fi < fl) && (pi < pl)
|
||
; fi++, pi++) {
|
||
this.debug('matchOne loop')
|
||
var p = pattern[pi]
|
||
var f = file[fi]
|
||
|
||
this.debug(pattern, p, f)
|
||
|
||
// should be impossible.
|
||
// some invalid regexp stuff in the set.
|
||
if (p === false) return false
|
||
|
||
if (p === GLOBSTAR) {
|
||
this.debug('GLOBSTAR', [pattern, p, f])
|
||
|
||
// "**"
|
||
// a/**/b/**/c would match the following:
|
||
// a/b/x/y/z/c
|
||
// a/x/y/z/b/c
|
||
// a/b/x/b/x/c
|
||
// a/b/c
|
||
// To do this, take the rest of the pattern after
|
||
// the **, and see if it would match the file remainder.
|
||
// If so, return success.
|
||
// If not, the ** "swallows" a segment, and try again.
|
||
// This is recursively awful.
|
||
//
|
||
// a/**/b/**/c matching a/b/x/y/z/c
|
||
// - a matches a
|
||
// - doublestar
|
||
// - matchOne(b/x/y/z/c, b/**/c)
|
||
// - b matches b
|
||
// - doublestar
|
||
// - matchOne(x/y/z/c, c) -> no
|
||
// - matchOne(y/z/c, c) -> no
|
||
// - matchOne(z/c, c) -> no
|
||
// - matchOne(c, c) yes, hit
|
||
var fr = fi
|
||
var pr = pi + 1
|
||
if (pr === pl) {
|
||
this.debug('** at the end')
|
||
// a ** at the end will just swallow the rest.
|
||
// We have found a match.
|
||
// however, it will not swallow /.x, unless
|
||
// options.dot is set.
|
||
// . and .. are *never* matched by **, for explosively
|
||
// exponential reasons.
|
||
for (; fi < fl; fi++) {
|
||
if (file[fi] === '.' || file[fi] === '..' ||
|
||
(!options.dot && file[fi].charAt(0) === '.')) return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
// ok, let's see if we can swallow whatever we can.
|
||
while (fr < fl) {
|
||
var swallowee = file[fr]
|
||
|
||
this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
|
||
|
||
// XXX remove this slice. Just pass the start index.
|
||
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
|
||
this.debug('globstar found match!', fr, fl, swallowee)
|
||
// found a match.
|
||
return true
|
||
} else {
|
||
// can't swallow "." or ".." ever.
|
||
// can only swallow ".foo" when explicitly asked.
|
||
if (swallowee === '.' || swallowee === '..' ||
|
||
(!options.dot && swallowee.charAt(0) === '.')) {
|
||
this.debug('dot detected!', file, fr, pattern, pr)
|
||
break
|
||
}
|
||
|
||
// ** swallows a segment, and continue.
|
||
this.debug('globstar swallow a segment, and continue')
|
||
fr++
|
||
}
|
||
}
|
||
|
||
// no match was found.
|
||
// However, in partial mode, we can't say this is necessarily over.
|
||
// If there's more *pattern* left, then
|
||
if (partial) {
|
||
// ran out of file
|
||
this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
|
||
if (fr === fl) return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
// something other than **
|
||
// non-magic patterns just have to match exactly
|
||
// patterns with magic have been turned into regexps.
|
||
var hit
|
||
if (typeof p === 'string') {
|
||
if (options.nocase) {
|
||
hit = f.toLowerCase() === p.toLowerCase()
|
||
} else {
|
||
hit = f === p
|
||
}
|
||
this.debug('string match', p, f, hit)
|
||
} else {
|
||
hit = f.match(p)
|
||
this.debug('pattern match', p, f, hit)
|
||
}
|
||
|
||
if (!hit) return false
|
||
}
|
||
|
||
// Note: ending in / means that we'll get a final ""
|
||
// at the end of the pattern. This can only match a
|
||
// corresponding "" at the end of the file.
|
||
// If the file ends in /, then it can only match a
|
||
// a pattern that ends in /, unless the pattern just
|
||
// doesn't have any more for it. But, a/b/ should *not*
|
||
// match "a/b/*", even though "" matches against the
|
||
// [^/]*? pattern, except in partial mode, where it might
|
||
// simply not be reached yet.
|
||
// However, a/b/ should still satisfy a/*
|
||
|
||
// now either we fell off the end of the pattern, or we're done.
|
||
if (fi === fl && pi === pl) {
|
||
// ran out of pattern and filename at the same time.
|
||
// an exact hit!
|
||
return true
|
||
} else if (fi === fl) {
|
||
// ran out of file, but still had pattern left.
|
||
// this is ok if we're doing the match as part of
|
||
// a glob fs traversal.
|
||
return partial
|
||
} else if (pi === pl) {
|
||
// ran out of pattern, still have file left.
|
||
// this is only acceptable if we're on the very last
|
||
// empty segment of a file with a trailing slash.
|
||
// a/* should match a/b/
|
||
var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')
|
||
return emptyFileEnd
|
||
}
|
||
|
||
// should be unreachable.
|
||
throw new Error('wtf?')
|
||
}
|
||
|
||
// replace stuff like \* with *
|
||
function globUnescape (s) {
|
||
return s.replace(/\\(.)/g, '$1')
|
||
}
|
||
|
||
function regExpEscape (s) {
|
||
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/once/once.js":
|
||
/*!***********************************!*\
|
||
!*** ./node_modules/once/once.js ***!
|
||
\***********************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var wrappy = __webpack_require__(/*! wrappy */ "./node_modules/wrappy/wrappy.js")
|
||
module.exports = wrappy(once)
|
||
module.exports.strict = wrappy(onceStrict)
|
||
|
||
once.proto = once(function () {
|
||
Object.defineProperty(Function.prototype, 'once', {
|
||
value: function () {
|
||
return once(this)
|
||
},
|
||
configurable: true
|
||
})
|
||
|
||
Object.defineProperty(Function.prototype, 'onceStrict', {
|
||
value: function () {
|
||
return onceStrict(this)
|
||
},
|
||
configurable: true
|
||
})
|
||
})
|
||
|
||
function once (fn) {
|
||
var f = function () {
|
||
if (f.called) return f.value
|
||
f.called = true
|
||
return f.value = fn.apply(this, arguments)
|
||
}
|
||
f.called = false
|
||
return f
|
||
}
|
||
|
||
function onceStrict (fn) {
|
||
var f = function () {
|
||
if (f.called)
|
||
throw new Error(f.onceError)
|
||
f.called = true
|
||
return f.value = fn.apply(this, arguments)
|
||
}
|
||
var name = fn.name || 'Function wrapped with `once`'
|
||
f.onceError = name + " shouldn't be called more than once"
|
||
f.called = false
|
||
return f
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/path-is-absolute/index.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/path-is-absolute/index.js ***!
|
||
\************************************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
|
||
|
||
function posix(path) {
|
||
return path.charAt(0) === '/';
|
||
}
|
||
|
||
function win32(path) {
|
||
// https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56
|
||
var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
|
||
var result = splitDeviceRe.exec(path);
|
||
var device = result[1] || '';
|
||
var isUnc = Boolean(device && device.charAt(1) !== ':');
|
||
|
||
// UNC paths are always absolute
|
||
return Boolean(result[2] || isUnc);
|
||
}
|
||
|
||
module.exports = process.platform === 'win32' ? win32 : posix;
|
||
module.exports.posix = posix;
|
||
module.exports.win32 = win32;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/q/q.js":
|
||
/*!*****************************!*\
|
||
!*** ./node_modules/q/q.js ***!
|
||
\*****************************/
|
||
/***/ ((module) => {
|
||
|
||
// vim:ts=4:sts=4:sw=4:
|
||
/*!
|
||
*
|
||
* Copyright 2009-2017 Kris Kowal under the terms of the MIT
|
||
* license found at https://github.com/kriskowal/q/blob/v1/LICENSE
|
||
*
|
||
* With parts by Tyler Close
|
||
* Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
|
||
* at http://www.opensource.org/licenses/mit-license.html
|
||
* Forked at ref_send.js version: 2009-05-11
|
||
*
|
||
* With parts by Mark Miller
|
||
* Copyright (C) 2011 Google Inc.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
*
|
||
*/
|
||
|
||
(function (definition) {
|
||
"use strict";
|
||
|
||
// This file will function properly as a <script> tag, or a module
|
||
// using CommonJS and NodeJS or RequireJS module formats. In
|
||
// Common/Node/RequireJS, the module exports the Q API and when
|
||
// executed as a simple <script>, it creates a Q global instead.
|
||
|
||
// Montage Require
|
||
if (typeof bootstrap === "function") {
|
||
bootstrap("promise", definition);
|
||
|
||
// CommonJS
|
||
} else if (true) {
|
||
module.exports = definition();
|
||
|
||
// RequireJS
|
||
} else { var previousQ, global; }
|
||
|
||
})(function () {
|
||
"use strict";
|
||
|
||
var hasStacks = false;
|
||
try {
|
||
throw new Error();
|
||
} catch (e) {
|
||
hasStacks = !!e.stack;
|
||
}
|
||
|
||
// All code after this point will be filtered from stack traces reported
|
||
// by Q.
|
||
var qStartingLine = captureLine();
|
||
var qFileName;
|
||
|
||
// shims
|
||
|
||
// used for fallback in "allResolved"
|
||
var noop = function () {};
|
||
|
||
// Use the fastest possible means to execute a task in a future turn
|
||
// of the event loop.
|
||
var nextTick =(function () {
|
||
// linked list of tasks (single, with head node)
|
||
var head = {task: void 0, next: null};
|
||
var tail = head;
|
||
var flushing = false;
|
||
var requestTick = void 0;
|
||
var isNodeJS = false;
|
||
// queue for late tasks, used by unhandled rejection tracking
|
||
var laterQueue = [];
|
||
|
||
function flush() {
|
||
/* jshint loopfunc: true */
|
||
var task, domain;
|
||
|
||
while (head.next) {
|
||
head = head.next;
|
||
task = head.task;
|
||
head.task = void 0;
|
||
domain = head.domain;
|
||
|
||
if (domain) {
|
||
head.domain = void 0;
|
||
domain.enter();
|
||
}
|
||
runSingle(task, domain);
|
||
|
||
}
|
||
while (laterQueue.length) {
|
||
task = laterQueue.pop();
|
||
runSingle(task);
|
||
}
|
||
flushing = false;
|
||
}
|
||
// runs a single function in the async queue
|
||
function runSingle(task, domain) {
|
||
try {
|
||
task();
|
||
|
||
} catch (e) {
|
||
if (isNodeJS) {
|
||
// In node, uncaught exceptions are considered fatal errors.
|
||
// Re-throw them synchronously to interrupt flushing!
|
||
|
||
// Ensure continuation if the uncaught exception is suppressed
|
||
// listening "uncaughtException" events (as domains does).
|
||
// Continue in next event to avoid tick recursion.
|
||
if (domain) {
|
||
domain.exit();
|
||
}
|
||
setTimeout(flush, 0);
|
||
if (domain) {
|
||
domain.enter();
|
||
}
|
||
|
||
throw e;
|
||
|
||
} else {
|
||
// In browsers, uncaught exceptions are not fatal.
|
||
// Re-throw them asynchronously to avoid slow-downs.
|
||
setTimeout(function () {
|
||
throw e;
|
||
}, 0);
|
||
}
|
||
}
|
||
|
||
if (domain) {
|
||
domain.exit();
|
||
}
|
||
}
|
||
|
||
nextTick = function (task) {
|
||
tail = tail.next = {
|
||
task: task,
|
||
domain: isNodeJS && process.domain,
|
||
next: null
|
||
};
|
||
|
||
if (!flushing) {
|
||
flushing = true;
|
||
requestTick();
|
||
}
|
||
};
|
||
|
||
if (typeof process === "object" &&
|
||
process.toString() === "[object process]" && process.nextTick) {
|
||
// Ensure Q is in a real Node environment, with a `process.nextTick`.
|
||
// To see through fake Node environments:
|
||
// * Mocha test runner - exposes a `process` global without a `nextTick`
|
||
// * Browserify - exposes a `process.nexTick` function that uses
|
||
// `setTimeout`. In this case `setImmediate` is preferred because
|
||
// it is faster. Browserify's `process.toString()` yields
|
||
// "[object Object]", while in a real Node environment
|
||
// `process.toString()` yields "[object process]".
|
||
isNodeJS = true;
|
||
|
||
requestTick = function () {
|
||
process.nextTick(flush);
|
||
};
|
||
|
||
} else if (typeof setImmediate === "function") {
|
||
// In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
|
||
if (typeof window !== "undefined") {
|
||
requestTick = setImmediate.bind(window, flush);
|
||
} else {
|
||
requestTick = function () {
|
||
setImmediate(flush);
|
||
};
|
||
}
|
||
|
||
} else if (typeof MessageChannel !== "undefined") {
|
||
// modern browsers
|
||
// http://www.nonblocking.io/2011/06/windownexttick.html
|
||
var channel = new MessageChannel();
|
||
// At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
|
||
// working message ports the first time a page loads.
|
||
channel.port1.onmessage = function () {
|
||
requestTick = requestPortTick;
|
||
channel.port1.onmessage = flush;
|
||
flush();
|
||
};
|
||
var requestPortTick = function () {
|
||
// Opera requires us to provide a message payload, regardless of
|
||
// whether we use it.
|
||
channel.port2.postMessage(0);
|
||
};
|
||
requestTick = function () {
|
||
setTimeout(flush, 0);
|
||
requestPortTick();
|
||
};
|
||
|
||
} else {
|
||
// old browsers
|
||
requestTick = function () {
|
||
setTimeout(flush, 0);
|
||
};
|
||
}
|
||
// runs a task after all other tasks have been run
|
||
// this is useful for unhandled rejection tracking that needs to happen
|
||
// after all `then`d tasks have been run.
|
||
nextTick.runAfter = function (task) {
|
||
laterQueue.push(task);
|
||
if (!flushing) {
|
||
flushing = true;
|
||
requestTick();
|
||
}
|
||
};
|
||
return nextTick;
|
||
})();
|
||
|
||
// Attempt to make generics safe in the face of downstream
|
||
// modifications.
|
||
// There is no situation where this is necessary.
|
||
// If you need a security guarantee, these primordials need to be
|
||
// deeply frozen anyway, and if you don’t need a security guarantee,
|
||
// this is just plain paranoid.
|
||
// However, this **might** have the nice side-effect of reducing the size of
|
||
// the minified code by reducing x.call() to merely x()
|
||
// See Mark Miller’s explanation of what this does.
|
||
// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
|
||
var call = Function.call;
|
||
function uncurryThis(f) {
|
||
return function () {
|
||
return call.apply(f, arguments);
|
||
};
|
||
}
|
||
// This is equivalent, but slower:
|
||
// uncurryThis = Function_bind.bind(Function_bind.call);
|
||
// http://jsperf.com/uncurrythis
|
||
|
||
var array_slice = uncurryThis(Array.prototype.slice);
|
||
|
||
var array_reduce = uncurryThis(
|
||
Array.prototype.reduce || function (callback, basis) {
|
||
var index = 0,
|
||
length = this.length;
|
||
// concerning the initial value, if one is not provided
|
||
if (arguments.length === 1) {
|
||
// seek to the first value in the array, accounting
|
||
// for the possibility that is is a sparse array
|
||
do {
|
||
if (index in this) {
|
||
basis = this[index++];
|
||
break;
|
||
}
|
||
if (++index >= length) {
|
||
throw new TypeError();
|
||
}
|
||
} while (1);
|
||
}
|
||
// reduce
|
||
for (; index < length; index++) {
|
||
// account for the possibility that the array is sparse
|
||
if (index in this) {
|
||
basis = callback(basis, this[index], index);
|
||
}
|
||
}
|
||
return basis;
|
||
}
|
||
);
|
||
|
||
var array_indexOf = uncurryThis(
|
||
Array.prototype.indexOf || function (value) {
|
||
// not a very good shim, but good enough for our one use of it
|
||
for (var i = 0; i < this.length; i++) {
|
||
if (this[i] === value) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
);
|
||
|
||
var array_map = uncurryThis(
|
||
Array.prototype.map || function (callback, thisp) {
|
||
var self = this;
|
||
var collect = [];
|
||
array_reduce(self, function (undefined, value, index) {
|
||
collect.push(callback.call(thisp, value, index, self));
|
||
}, void 0);
|
||
return collect;
|
||
}
|
||
);
|
||
|
||
var object_create = Object.create || function (prototype) {
|
||
function Type() { }
|
||
Type.prototype = prototype;
|
||
return new Type();
|
||
};
|
||
|
||
var object_defineProperty = Object.defineProperty || function (obj, prop, descriptor) {
|
||
obj[prop] = descriptor.value;
|
||
return obj;
|
||
};
|
||
|
||
var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
|
||
|
||
var object_keys = Object.keys || function (object) {
|
||
var keys = [];
|
||
for (var key in object) {
|
||
if (object_hasOwnProperty(object, key)) {
|
||
keys.push(key);
|
||
}
|
||
}
|
||
return keys;
|
||
};
|
||
|
||
var object_toString = uncurryThis(Object.prototype.toString);
|
||
|
||
function isObject(value) {
|
||
return value === Object(value);
|
||
}
|
||
|
||
// generator related shims
|
||
|
||
// FIXME: Remove this function once ES6 generators are in SpiderMonkey.
|
||
function isStopIteration(exception) {
|
||
return (
|
||
object_toString(exception) === "[object StopIteration]" ||
|
||
exception instanceof QReturnValue
|
||
);
|
||
}
|
||
|
||
// FIXME: Remove this helper and Q.return once ES6 generators are in
|
||
// SpiderMonkey.
|
||
var QReturnValue;
|
||
if (typeof ReturnValue !== "undefined") {
|
||
QReturnValue = ReturnValue;
|
||
} else {
|
||
QReturnValue = function (value) {
|
||
this.value = value;
|
||
};
|
||
}
|
||
|
||
// long stack traces
|
||
|
||
var STACK_JUMP_SEPARATOR = "From previous event:";
|
||
|
||
function makeStackTraceLong(error, promise) {
|
||
// If possible, transform the error stack trace by removing Node and Q
|
||
// cruft, then concatenating with the stack trace of `promise`. See #57.
|
||
if (hasStacks &&
|
||
promise.stack &&
|
||
typeof error === "object" &&
|
||
error !== null &&
|
||
error.stack
|
||
) {
|
||
var stacks = [];
|
||
for (var p = promise; !!p; p = p.source) {
|
||
if (p.stack && (!error.__minimumStackCounter__ || error.__minimumStackCounter__ > p.stackCounter)) {
|
||
object_defineProperty(error, "__minimumStackCounter__", {value: p.stackCounter, configurable: true});
|
||
stacks.unshift(p.stack);
|
||
}
|
||
}
|
||
stacks.unshift(error.stack);
|
||
|
||
var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
|
||
var stack = filterStackString(concatedStacks);
|
||
object_defineProperty(error, "stack", {value: stack, configurable: true});
|
||
}
|
||
}
|
||
|
||
function filterStackString(stackString) {
|
||
var lines = stackString.split("\n");
|
||
var desiredLines = [];
|
||
for (var i = 0; i < lines.length; ++i) {
|
||
var line = lines[i];
|
||
|
||
if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
|
||
desiredLines.push(line);
|
||
}
|
||
}
|
||
return desiredLines.join("\n");
|
||
}
|
||
|
||
function isNodeFrame(stackLine) {
|
||
return stackLine.indexOf("(module.js:") !== -1 ||
|
||
stackLine.indexOf("(node.js:") !== -1;
|
||
}
|
||
|
||
function getFileNameAndLineNumber(stackLine) {
|
||
// Named functions: "at functionName (filename:lineNumber:columnNumber)"
|
||
// In IE10 function name can have spaces ("Anonymous function") O_o
|
||
var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
|
||
if (attempt1) {
|
||
return [attempt1[1], Number(attempt1[2])];
|
||
}
|
||
|
||
// Anonymous functions: "at filename:lineNumber:columnNumber"
|
||
var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
|
||
if (attempt2) {
|
||
return [attempt2[1], Number(attempt2[2])];
|
||
}
|
||
|
||
// Firefox style: "function@filename:lineNumber or @filename:lineNumber"
|
||
var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
|
||
if (attempt3) {
|
||
return [attempt3[1], Number(attempt3[2])];
|
||
}
|
||
}
|
||
|
||
function isInternalFrame(stackLine) {
|
||
var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
|
||
|
||
if (!fileNameAndLineNumber) {
|
||
return false;
|
||
}
|
||
|
||
var fileName = fileNameAndLineNumber[0];
|
||
var lineNumber = fileNameAndLineNumber[1];
|
||
|
||
return fileName === qFileName &&
|
||
lineNumber >= qStartingLine &&
|
||
lineNumber <= qEndingLine;
|
||
}
|
||
|
||
// discover own file name and line number range for filtering stack
|
||
// traces
|
||
function captureLine() {
|
||
if (!hasStacks) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
throw new Error();
|
||
} catch (e) {
|
||
var lines = e.stack.split("\n");
|
||
var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
|
||
var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
|
||
if (!fileNameAndLineNumber) {
|
||
return;
|
||
}
|
||
|
||
qFileName = fileNameAndLineNumber[0];
|
||
return fileNameAndLineNumber[1];
|
||
}
|
||
}
|
||
|
||
function deprecate(callback, name, alternative) {
|
||
return function () {
|
||
if (typeof console !== "undefined" &&
|
||
typeof console.warn === "function") {
|
||
console.warn(name + " is deprecated, use " + alternative +
|
||
" instead.", new Error("").stack);
|
||
}
|
||
return callback.apply(callback, arguments);
|
||
};
|
||
}
|
||
|
||
// end of shims
|
||
// beginning of real work
|
||
|
||
/**
|
||
* Constructs a promise for an immediate reference, passes promises through, or
|
||
* coerces promises from different systems.
|
||
* @param value immediate reference or promise
|
||
*/
|
||
function Q(value) {
|
||
// If the object is already a Promise, return it directly. This enables
|
||
// the resolve function to both be used to created references from objects,
|
||
// but to tolerably coerce non-promises to promises.
|
||
if (value instanceof Promise) {
|
||
return value;
|
||
}
|
||
|
||
// assimilate thenables
|
||
if (isPromiseAlike(value)) {
|
||
return coerce(value);
|
||
} else {
|
||
return fulfill(value);
|
||
}
|
||
}
|
||
Q.resolve = Q;
|
||
|
||
/**
|
||
* Performs a task in a future turn of the event loop.
|
||
* @param {Function} task
|
||
*/
|
||
Q.nextTick = nextTick;
|
||
|
||
/**
|
||
* Controls whether or not long stack traces will be on
|
||
*/
|
||
Q.longStackSupport = false;
|
||
|
||
/**
|
||
* The counter is used to determine the stopping point for building
|
||
* long stack traces. In makeStackTraceLong we walk backwards through
|
||
* the linked list of promises, only stacks which were created before
|
||
* the rejection are concatenated.
|
||
*/
|
||
var longStackCounter = 1;
|
||
|
||
// enable long stacks if Q_DEBUG is set
|
||
if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
|
||
Q.longStackSupport = true;
|
||
}
|
||
|
||
/**
|
||
* Constructs a {promise, resolve, reject} object.
|
||
*
|
||
* `resolve` is a callback to invoke with a more resolved value for the
|
||
* promise. To fulfill the promise, invoke `resolve` with any value that is
|
||
* not a thenable. To reject the promise, invoke `resolve` with a rejected
|
||
* thenable, or invoke `reject` with the reason directly. To resolve the
|
||
* promise to another thenable, thus putting it in the same state, invoke
|
||
* `resolve` with that other thenable.
|
||
*/
|
||
Q.defer = defer;
|
||
function defer() {
|
||
// if "messages" is an "Array", that indicates that the promise has not yet
|
||
// been resolved. If it is "undefined", it has been resolved. Each
|
||
// element of the messages array is itself an array of complete arguments to
|
||
// forward to the resolved promise. We coerce the resolution value to a
|
||
// promise using the `resolve` function because it handles both fully
|
||
// non-thenable values and other thenables gracefully.
|
||
var messages = [], progressListeners = [], resolvedPromise;
|
||
|
||
var deferred = object_create(defer.prototype);
|
||
var promise = object_create(Promise.prototype);
|
||
|
||
promise.promiseDispatch = function (resolve, op, operands) {
|
||
var args = array_slice(arguments);
|
||
if (messages) {
|
||
messages.push(args);
|
||
if (op === "when" && operands[1]) { // progress operand
|
||
progressListeners.push(operands[1]);
|
||
}
|
||
} else {
|
||
Q.nextTick(function () {
|
||
resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
|
||
});
|
||
}
|
||
};
|
||
|
||
// XXX deprecated
|
||
promise.valueOf = function () {
|
||
if (messages) {
|
||
return promise;
|
||
}
|
||
var nearerValue = nearer(resolvedPromise);
|
||
if (isPromise(nearerValue)) {
|
||
resolvedPromise = nearerValue; // shorten chain
|
||
}
|
||
return nearerValue;
|
||
};
|
||
|
||
promise.inspect = function () {
|
||
if (!resolvedPromise) {
|
||
return { state: "pending" };
|
||
}
|
||
return resolvedPromise.inspect();
|
||
};
|
||
|
||
if (Q.longStackSupport && hasStacks) {
|
||
try {
|
||
throw new Error();
|
||
} catch (e) {
|
||
// NOTE: don't try to use `Error.captureStackTrace` or transfer the
|
||
// accessor around; that causes memory leaks as per GH-111. Just
|
||
// reify the stack trace as a string ASAP.
|
||
//
|
||
// At the same time, cut off the first line; it's always just
|
||
// "[object Promise]\n", as per the `toString`.
|
||
promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
|
||
promise.stackCounter = longStackCounter++;
|
||
}
|
||
}
|
||
|
||
// NOTE: we do the checks for `resolvedPromise` in each method, instead of
|
||
// consolidating them into `become`, since otherwise we'd create new
|
||
// promises with the lines `become(whatever(value))`. See e.g. GH-252.
|
||
|
||
function become(newPromise) {
|
||
resolvedPromise = newPromise;
|
||
|
||
if (Q.longStackSupport && hasStacks) {
|
||
// Only hold a reference to the new promise if long stacks
|
||
// are enabled to reduce memory usage
|
||
promise.source = newPromise;
|
||
}
|
||
|
||
array_reduce(messages, function (undefined, message) {
|
||
Q.nextTick(function () {
|
||
newPromise.promiseDispatch.apply(newPromise, message);
|
||
});
|
||
}, void 0);
|
||
|
||
messages = void 0;
|
||
progressListeners = void 0;
|
||
}
|
||
|
||
deferred.promise = promise;
|
||
deferred.resolve = function (value) {
|
||
if (resolvedPromise) {
|
||
return;
|
||
}
|
||
|
||
become(Q(value));
|
||
};
|
||
|
||
deferred.fulfill = function (value) {
|
||
if (resolvedPromise) {
|
||
return;
|
||
}
|
||
|
||
become(fulfill(value));
|
||
};
|
||
deferred.reject = function (reason) {
|
||
if (resolvedPromise) {
|
||
return;
|
||
}
|
||
|
||
become(reject(reason));
|
||
};
|
||
deferred.notify = function (progress) {
|
||
if (resolvedPromise) {
|
||
return;
|
||
}
|
||
|
||
array_reduce(progressListeners, function (undefined, progressListener) {
|
||
Q.nextTick(function () {
|
||
progressListener(progress);
|
||
});
|
||
}, void 0);
|
||
};
|
||
|
||
return deferred;
|
||
}
|
||
|
||
/**
|
||
* Creates a Node-style callback that will resolve or reject the deferred
|
||
* promise.
|
||
* @returns a nodeback
|
||
*/
|
||
defer.prototype.makeNodeResolver = function () {
|
||
var self = this;
|
||
return function (error, value) {
|
||
if (error) {
|
||
self.reject(error);
|
||
} else if (arguments.length > 2) {
|
||
self.resolve(array_slice(arguments, 1));
|
||
} else {
|
||
self.resolve(value);
|
||
}
|
||
};
|
||
};
|
||
|
||
/**
|
||
* @param resolver {Function} a function that returns nothing and accepts
|
||
* the resolve, reject, and notify functions for a deferred.
|
||
* @returns a promise that may be resolved with the given resolve and reject
|
||
* functions, or rejected by a thrown exception in resolver
|
||
*/
|
||
Q.Promise = promise; // ES6
|
||
Q.promise = promise;
|
||
function promise(resolver) {
|
||
if (typeof resolver !== "function") {
|
||
throw new TypeError("resolver must be a function.");
|
||
}
|
||
var deferred = defer();
|
||
try {
|
||
resolver(deferred.resolve, deferred.reject, deferred.notify);
|
||
} catch (reason) {
|
||
deferred.reject(reason);
|
||
}
|
||
return deferred.promise;
|
||
}
|
||
|
||
promise.race = race; // ES6
|
||
promise.all = all; // ES6
|
||
promise.reject = reject; // ES6
|
||
promise.resolve = Q; // ES6
|
||
|
||
// XXX experimental. This method is a way to denote that a local value is
|
||
// serializable and should be immediately dispatched to a remote upon request,
|
||
// instead of passing a reference.
|
||
Q.passByCopy = function (object) {
|
||
//freeze(object);
|
||
//passByCopies.set(object, true);
|
||
return object;
|
||
};
|
||
|
||
Promise.prototype.passByCopy = function () {
|
||
//freeze(object);
|
||
//passByCopies.set(object, true);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* If two promises eventually fulfill to the same value, promises that value,
|
||
* but otherwise rejects.
|
||
* @param x {Any*}
|
||
* @param y {Any*}
|
||
* @returns {Any*} a promise for x and y if they are the same, but a rejection
|
||
* otherwise.
|
||
*
|
||
*/
|
||
Q.join = function (x, y) {
|
||
return Q(x).join(y);
|
||
};
|
||
|
||
Promise.prototype.join = function (that) {
|
||
return Q([this, that]).spread(function (x, y) {
|
||
if (x === y) {
|
||
// TODO: "===" should be Object.is or equiv
|
||
return x;
|
||
} else {
|
||
throw new Error("Q can't join: not the same: " + x + " " + y);
|
||
}
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Returns a promise for the first of an array of promises to become settled.
|
||
* @param answers {Array[Any*]} promises to race
|
||
* @returns {Any*} the first promise to be settled
|
||
*/
|
||
Q.race = race;
|
||
function race(answerPs) {
|
||
return promise(function (resolve, reject) {
|
||
// Switch to this once we can assume at least ES5
|
||
// answerPs.forEach(function (answerP) {
|
||
// Q(answerP).then(resolve, reject);
|
||
// });
|
||
// Use this in the meantime
|
||
for (var i = 0, len = answerPs.length; i < len; i++) {
|
||
Q(answerPs[i]).then(resolve, reject);
|
||
}
|
||
});
|
||
}
|
||
|
||
Promise.prototype.race = function () {
|
||
return this.then(Q.race);
|
||
};
|
||
|
||
/**
|
||
* Constructs a Promise with a promise descriptor object and optional fallback
|
||
* function. The descriptor contains methods like when(rejected), get(name),
|
||
* set(name, value), post(name, args), and delete(name), which all
|
||
* return either a value, a promise for a value, or a rejection. The fallback
|
||
* accepts the operation name, a resolver, and any further arguments that would
|
||
* have been forwarded to the appropriate method above had a method been
|
||
* provided with the proper name. The API makes no guarantees about the nature
|
||
* of the returned object, apart from that it is usable whereever promises are
|
||
* bought and sold.
|
||
*/
|
||
Q.makePromise = Promise;
|
||
function Promise(descriptor, fallback, inspect) {
|
||
if (fallback === void 0) {
|
||
fallback = function (op) {
|
||
return reject(new Error(
|
||
"Promise does not support operation: " + op
|
||
));
|
||
};
|
||
}
|
||
if (inspect === void 0) {
|
||
inspect = function () {
|
||
return {state: "unknown"};
|
||
};
|
||
}
|
||
|
||
var promise = object_create(Promise.prototype);
|
||
|
||
promise.promiseDispatch = function (resolve, op, args) {
|
||
var result;
|
||
try {
|
||
if (descriptor[op]) {
|
||
result = descriptor[op].apply(promise, args);
|
||
} else {
|
||
result = fallback.call(promise, op, args);
|
||
}
|
||
} catch (exception) {
|
||
result = reject(exception);
|
||
}
|
||
if (resolve) {
|
||
resolve(result);
|
||
}
|
||
};
|
||
|
||
promise.inspect = inspect;
|
||
|
||
// XXX deprecated `valueOf` and `exception` support
|
||
if (inspect) {
|
||
var inspected = inspect();
|
||
if (inspected.state === "rejected") {
|
||
promise.exception = inspected.reason;
|
||
}
|
||
|
||
promise.valueOf = function () {
|
||
var inspected = inspect();
|
||
if (inspected.state === "pending" ||
|
||
inspected.state === "rejected") {
|
||
return promise;
|
||
}
|
||
return inspected.value;
|
||
};
|
||
}
|
||
|
||
return promise;
|
||
}
|
||
|
||
Promise.prototype.toString = function () {
|
||
return "[object Promise]";
|
||
};
|
||
|
||
Promise.prototype.then = function (fulfilled, rejected, progressed) {
|
||
var self = this;
|
||
var deferred = defer();
|
||
var done = false; // ensure the untrusted promise makes at most a
|
||
// single call to one of the callbacks
|
||
|
||
function _fulfilled(value) {
|
||
try {
|
||
return typeof fulfilled === "function" ? fulfilled(value) : value;
|
||
} catch (exception) {
|
||
return reject(exception);
|
||
}
|
||
}
|
||
|
||
function _rejected(exception) {
|
||
if (typeof rejected === "function") {
|
||
makeStackTraceLong(exception, self);
|
||
try {
|
||
return rejected(exception);
|
||
} catch (newException) {
|
||
return reject(newException);
|
||
}
|
||
}
|
||
return reject(exception);
|
||
}
|
||
|
||
function _progressed(value) {
|
||
return typeof progressed === "function" ? progressed(value) : value;
|
||
}
|
||
|
||
Q.nextTick(function () {
|
||
self.promiseDispatch(function (value) {
|
||
if (done) {
|
||
return;
|
||
}
|
||
done = true;
|
||
|
||
deferred.resolve(_fulfilled(value));
|
||
}, "when", [function (exception) {
|
||
if (done) {
|
||
return;
|
||
}
|
||
done = true;
|
||
|
||
deferred.resolve(_rejected(exception));
|
||
}]);
|
||
});
|
||
|
||
// Progress propagator need to be attached in the current tick.
|
||
self.promiseDispatch(void 0, "when", [void 0, function (value) {
|
||
var newValue;
|
||
var threw = false;
|
||
try {
|
||
newValue = _progressed(value);
|
||
} catch (e) {
|
||
threw = true;
|
||
if (Q.onerror) {
|
||
Q.onerror(e);
|
||
} else {
|
||
throw e;
|
||
}
|
||
}
|
||
|
||
if (!threw) {
|
||
deferred.notify(newValue);
|
||
}
|
||
}]);
|
||
|
||
return deferred.promise;
|
||
};
|
||
|
||
Q.tap = function (promise, callback) {
|
||
return Q(promise).tap(callback);
|
||
};
|
||
|
||
/**
|
||
* Works almost like "finally", but not called for rejections.
|
||
* Original resolution value is passed through callback unaffected.
|
||
* Callback may return a promise that will be awaited for.
|
||
* @param {Function} callback
|
||
* @returns {Q.Promise}
|
||
* @example
|
||
* doSomething()
|
||
* .then(...)
|
||
* .tap(console.log)
|
||
* .then(...);
|
||
*/
|
||
Promise.prototype.tap = function (callback) {
|
||
callback = Q(callback);
|
||
|
||
return this.then(function (value) {
|
||
return callback.fcall(value).thenResolve(value);
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Registers an observer on a promise.
|
||
*
|
||
* Guarantees:
|
||
*
|
||
* 1. that fulfilled and rejected will be called only once.
|
||
* 2. that either the fulfilled callback or the rejected callback will be
|
||
* called, but not both.
|
||
* 3. that fulfilled and rejected will not be called in this turn.
|
||
*
|
||
* @param value promise or immediate reference to observe
|
||
* @param fulfilled function to be called with the fulfilled value
|
||
* @param rejected function to be called with the rejection exception
|
||
* @param progressed function to be called on any progress notifications
|
||
* @return promise for the return value from the invoked callback
|
||
*/
|
||
Q.when = when;
|
||
function when(value, fulfilled, rejected, progressed) {
|
||
return Q(value).then(fulfilled, rejected, progressed);
|
||
}
|
||
|
||
Promise.prototype.thenResolve = function (value) {
|
||
return this.then(function () { return value; });
|
||
};
|
||
|
||
Q.thenResolve = function (promise, value) {
|
||
return Q(promise).thenResolve(value);
|
||
};
|
||
|
||
Promise.prototype.thenReject = function (reason) {
|
||
return this.then(function () { throw reason; });
|
||
};
|
||
|
||
Q.thenReject = function (promise, reason) {
|
||
return Q(promise).thenReject(reason);
|
||
};
|
||
|
||
/**
|
||
* If an object is not a promise, it is as "near" as possible.
|
||
* If a promise is rejected, it is as "near" as possible too.
|
||
* If it’s a fulfilled promise, the fulfillment value is nearer.
|
||
* If it’s a deferred promise and the deferred has been resolved, the
|
||
* resolution is "nearer".
|
||
* @param object
|
||
* @returns most resolved (nearest) form of the object
|
||
*/
|
||
|
||
// XXX should we re-do this?
|
||
Q.nearer = nearer;
|
||
function nearer(value) {
|
||
if (isPromise(value)) {
|
||
var inspected = value.inspect();
|
||
if (inspected.state === "fulfilled") {
|
||
return inspected.value;
|
||
}
|
||
}
|
||
return value;
|
||
}
|
||
|
||
/**
|
||
* @returns whether the given object is a promise.
|
||
* Otherwise it is a fulfilled value.
|
||
*/
|
||
Q.isPromise = isPromise;
|
||
function isPromise(object) {
|
||
return object instanceof Promise;
|
||
}
|
||
|
||
Q.isPromiseAlike = isPromiseAlike;
|
||
function isPromiseAlike(object) {
|
||
return isObject(object) && typeof object.then === "function";
|
||
}
|
||
|
||
/**
|
||
* @returns whether the given object is a pending promise, meaning not
|
||
* fulfilled or rejected.
|
||
*/
|
||
Q.isPending = isPending;
|
||
function isPending(object) {
|
||
return isPromise(object) && object.inspect().state === "pending";
|
||
}
|
||
|
||
Promise.prototype.isPending = function () {
|
||
return this.inspect().state === "pending";
|
||
};
|
||
|
||
/**
|
||
* @returns whether the given object is a value or fulfilled
|
||
* promise.
|
||
*/
|
||
Q.isFulfilled = isFulfilled;
|
||
function isFulfilled(object) {
|
||
return !isPromise(object) || object.inspect().state === "fulfilled";
|
||
}
|
||
|
||
Promise.prototype.isFulfilled = function () {
|
||
return this.inspect().state === "fulfilled";
|
||
};
|
||
|
||
/**
|
||
* @returns whether the given object is a rejected promise.
|
||
*/
|
||
Q.isRejected = isRejected;
|
||
function isRejected(object) {
|
||
return isPromise(object) && object.inspect().state === "rejected";
|
||
}
|
||
|
||
Promise.prototype.isRejected = function () {
|
||
return this.inspect().state === "rejected";
|
||
};
|
||
|
||
//// BEGIN UNHANDLED REJECTION TRACKING
|
||
|
||
// This promise library consumes exceptions thrown in handlers so they can be
|
||
// handled by a subsequent promise. The exceptions get added to this array when
|
||
// they are created, and removed when they are handled. Note that in ES6 or
|
||
// shimmed environments, this would naturally be a `Set`.
|
||
var unhandledReasons = [];
|
||
var unhandledRejections = [];
|
||
var reportedUnhandledRejections = [];
|
||
var trackUnhandledRejections = true;
|
||
|
||
function resetUnhandledRejections() {
|
||
unhandledReasons.length = 0;
|
||
unhandledRejections.length = 0;
|
||
|
||
if (!trackUnhandledRejections) {
|
||
trackUnhandledRejections = true;
|
||
}
|
||
}
|
||
|
||
function trackRejection(promise, reason) {
|
||
if (!trackUnhandledRejections) {
|
||
return;
|
||
}
|
||
if (typeof process === "object" && typeof process.emit === "function") {
|
||
Q.nextTick.runAfter(function () {
|
||
if (array_indexOf(unhandledRejections, promise) !== -1) {
|
||
process.emit("unhandledRejection", reason, promise);
|
||
reportedUnhandledRejections.push(promise);
|
||
}
|
||
});
|
||
}
|
||
|
||
unhandledRejections.push(promise);
|
||
if (reason && typeof reason.stack !== "undefined") {
|
||
unhandledReasons.push(reason.stack);
|
||
} else {
|
||
unhandledReasons.push("(no stack) " + reason);
|
||
}
|
||
}
|
||
|
||
function untrackRejection(promise) {
|
||
if (!trackUnhandledRejections) {
|
||
return;
|
||
}
|
||
|
||
var at = array_indexOf(unhandledRejections, promise);
|
||
if (at !== -1) {
|
||
if (typeof process === "object" && typeof process.emit === "function") {
|
||
Q.nextTick.runAfter(function () {
|
||
var atReport = array_indexOf(reportedUnhandledRejections, promise);
|
||
if (atReport !== -1) {
|
||
process.emit("rejectionHandled", unhandledReasons[at], promise);
|
||
reportedUnhandledRejections.splice(atReport, 1);
|
||
}
|
||
});
|
||
}
|
||
unhandledRejections.splice(at, 1);
|
||
unhandledReasons.splice(at, 1);
|
||
}
|
||
}
|
||
|
||
Q.resetUnhandledRejections = resetUnhandledRejections;
|
||
|
||
Q.getUnhandledReasons = function () {
|
||
// Make a copy so that consumers can't interfere with our internal state.
|
||
return unhandledReasons.slice();
|
||
};
|
||
|
||
Q.stopUnhandledRejectionTracking = function () {
|
||
resetUnhandledRejections();
|
||
trackUnhandledRejections = false;
|
||
};
|
||
|
||
resetUnhandledRejections();
|
||
|
||
//// END UNHANDLED REJECTION TRACKING
|
||
|
||
/**
|
||
* Constructs a rejected promise.
|
||
* @param reason value describing the failure
|
||
*/
|
||
Q.reject = reject;
|
||
function reject(reason) {
|
||
var rejection = Promise({
|
||
"when": function (rejected) {
|
||
// note that the error has been handled
|
||
if (rejected) {
|
||
untrackRejection(this);
|
||
}
|
||
return rejected ? rejected(reason) : this;
|
||
}
|
||
}, function fallback() {
|
||
return this;
|
||
}, function inspect() {
|
||
return { state: "rejected", reason: reason };
|
||
});
|
||
|
||
// Note that the reason has not been handled.
|
||
trackRejection(rejection, reason);
|
||
|
||
return rejection;
|
||
}
|
||
|
||
/**
|
||
* Constructs a fulfilled promise for an immediate reference.
|
||
* @param value immediate reference
|
||
*/
|
||
Q.fulfill = fulfill;
|
||
function fulfill(value) {
|
||
return Promise({
|
||
"when": function () {
|
||
return value;
|
||
},
|
||
"get": function (name) {
|
||
return value[name];
|
||
},
|
||
"set": function (name, rhs) {
|
||
value[name] = rhs;
|
||
},
|
||
"delete": function (name) {
|
||
delete value[name];
|
||
},
|
||
"post": function (name, args) {
|
||
// Mark Miller proposes that post with no name should apply a
|
||
// promised function.
|
||
if (name === null || name === void 0) {
|
||
return value.apply(void 0, args);
|
||
} else {
|
||
return value[name].apply(value, args);
|
||
}
|
||
},
|
||
"apply": function (thisp, args) {
|
||
return value.apply(thisp, args);
|
||
},
|
||
"keys": function () {
|
||
return object_keys(value);
|
||
}
|
||
}, void 0, function inspect() {
|
||
return { state: "fulfilled", value: value };
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Converts thenables to Q promises.
|
||
* @param promise thenable promise
|
||
* @returns a Q promise
|
||
*/
|
||
function coerce(promise) {
|
||
var deferred = defer();
|
||
Q.nextTick(function () {
|
||
try {
|
||
promise.then(deferred.resolve, deferred.reject, deferred.notify);
|
||
} catch (exception) {
|
||
deferred.reject(exception);
|
||
}
|
||
});
|
||
return deferred.promise;
|
||
}
|
||
|
||
/**
|
||
* Annotates an object such that it will never be
|
||
* transferred away from this process over any promise
|
||
* communication channel.
|
||
* @param object
|
||
* @returns promise a wrapping of that object that
|
||
* additionally responds to the "isDef" message
|
||
* without a rejection.
|
||
*/
|
||
Q.master = master;
|
||
function master(object) {
|
||
return Promise({
|
||
"isDef": function () {}
|
||
}, function fallback(op, args) {
|
||
return dispatch(object, op, args);
|
||
}, function () {
|
||
return Q(object).inspect();
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Spreads the values of a promised array of arguments into the
|
||
* fulfillment callback.
|
||
* @param fulfilled callback that receives variadic arguments from the
|
||
* promised array
|
||
* @param rejected callback that receives the exception if the promise
|
||
* is rejected.
|
||
* @returns a promise for the return value or thrown exception of
|
||
* either callback.
|
||
*/
|
||
Q.spread = spread;
|
||
function spread(value, fulfilled, rejected) {
|
||
return Q(value).spread(fulfilled, rejected);
|
||
}
|
||
|
||
Promise.prototype.spread = function (fulfilled, rejected) {
|
||
return this.all().then(function (array) {
|
||
return fulfilled.apply(void 0, array);
|
||
}, rejected);
|
||
};
|
||
|
||
/**
|
||
* The async function is a decorator for generator functions, turning
|
||
* them into asynchronous generators. Although generators are only part
|
||
* of the newest ECMAScript 6 drafts, this code does not cause syntax
|
||
* errors in older engines. This code should continue to work and will
|
||
* in fact improve over time as the language improves.
|
||
*
|
||
* ES6 generators are currently part of V8 version 3.19 with the
|
||
* --harmony-generators runtime flag enabled. SpiderMonkey has had them
|
||
* for longer, but under an older Python-inspired form. This function
|
||
* works on both kinds of generators.
|
||
*
|
||
* Decorates a generator function such that:
|
||
* - it may yield promises
|
||
* - execution will continue when that promise is fulfilled
|
||
* - the value of the yield expression will be the fulfilled value
|
||
* - it returns a promise for the return value (when the generator
|
||
* stops iterating)
|
||
* - the decorated function returns a promise for the return value
|
||
* of the generator or the first rejected promise among those
|
||
* yielded.
|
||
* - if an error is thrown in the generator, it propagates through
|
||
* every following yield until it is caught, or until it escapes
|
||
* the generator function altogether, and is translated into a
|
||
* rejection for the promise returned by the decorated generator.
|
||
*/
|
||
Q.async = async;
|
||
function async(makeGenerator) {
|
||
return function () {
|
||
// when verb is "send", arg is a value
|
||
// when verb is "throw", arg is an exception
|
||
function continuer(verb, arg) {
|
||
var result;
|
||
|
||
// Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
|
||
// engine that has a deployed base of browsers that support generators.
|
||
// However, SM's generators use the Python-inspired semantics of
|
||
// outdated ES6 drafts. We would like to support ES6, but we'd also
|
||
// like to make it possible to use generators in deployed browsers, so
|
||
// we also support Python-style generators. At some point we can remove
|
||
// this block.
|
||
|
||
if (typeof StopIteration === "undefined") {
|
||
// ES6 Generators
|
||
try {
|
||
result = generator[verb](arg);
|
||
} catch (exception) {
|
||
return reject(exception);
|
||
}
|
||
if (result.done) {
|
||
return Q(result.value);
|
||
} else {
|
||
return when(result.value, callback, errback);
|
||
}
|
||
} else {
|
||
// SpiderMonkey Generators
|
||
// FIXME: Remove this case when SM does ES6 generators.
|
||
try {
|
||
result = generator[verb](arg);
|
||
} catch (exception) {
|
||
if (isStopIteration(exception)) {
|
||
return Q(exception.value);
|
||
} else {
|
||
return reject(exception);
|
||
}
|
||
}
|
||
return when(result, callback, errback);
|
||
}
|
||
}
|
||
var generator = makeGenerator.apply(this, arguments);
|
||
var callback = continuer.bind(continuer, "next");
|
||
var errback = continuer.bind(continuer, "throw");
|
||
return callback();
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The spawn function is a small wrapper around async that immediately
|
||
* calls the generator and also ends the promise chain, so that any
|
||
* unhandled errors are thrown instead of forwarded to the error
|
||
* handler. This is useful because it's extremely common to run
|
||
* generators at the top-level to work with libraries.
|
||
*/
|
||
Q.spawn = spawn;
|
||
function spawn(makeGenerator) {
|
||
Q.done(Q.async(makeGenerator)());
|
||
}
|
||
|
||
// FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
|
||
/**
|
||
* Throws a ReturnValue exception to stop an asynchronous generator.
|
||
*
|
||
* This interface is a stop-gap measure to support generator return
|
||
* values in older Firefox/SpiderMonkey. In browsers that support ES6
|
||
* generators like Chromium 29, just use "return" in your generator
|
||
* functions.
|
||
*
|
||
* @param value the return value for the surrounding generator
|
||
* @throws ReturnValue exception with the value.
|
||
* @example
|
||
* // ES6 style
|
||
* Q.async(function* () {
|
||
* var foo = yield getFooPromise();
|
||
* var bar = yield getBarPromise();
|
||
* return foo + bar;
|
||
* })
|
||
* // Older SpiderMonkey style
|
||
* Q.async(function () {
|
||
* var foo = yield getFooPromise();
|
||
* var bar = yield getBarPromise();
|
||
* Q.return(foo + bar);
|
||
* })
|
||
*/
|
||
Q["return"] = _return;
|
||
function _return(value) {
|
||
throw new QReturnValue(value);
|
||
}
|
||
|
||
/**
|
||
* The promised function decorator ensures that any promise arguments
|
||
* are settled and passed as values (`this` is also settled and passed
|
||
* as a value). It will also ensure that the result of a function is
|
||
* always a promise.
|
||
*
|
||
* @example
|
||
* var add = Q.promised(function (a, b) {
|
||
* return a + b;
|
||
* });
|
||
* add(Q(a), Q(B));
|
||
*
|
||
* @param {function} callback The function to decorate
|
||
* @returns {function} a function that has been decorated.
|
||
*/
|
||
Q.promised = promised;
|
||
function promised(callback) {
|
||
return function () {
|
||
return spread([this, all(arguments)], function (self, args) {
|
||
return callback.apply(self, args);
|
||
});
|
||
};
|
||
}
|
||
|
||
/**
|
||
* sends a message to a value in a future turn
|
||
* @param object* the recipient
|
||
* @param op the name of the message operation, e.g., "when",
|
||
* @param args further arguments to be forwarded to the operation
|
||
* @returns result {Promise} a promise for the result of the operation
|
||
*/
|
||
Q.dispatch = dispatch;
|
||
function dispatch(object, op, args) {
|
||
return Q(object).dispatch(op, args);
|
||
}
|
||
|
||
Promise.prototype.dispatch = function (op, args) {
|
||
var self = this;
|
||
var deferred = defer();
|
||
Q.nextTick(function () {
|
||
self.promiseDispatch(deferred.resolve, op, args);
|
||
});
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Gets the value of a property in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @param name name of property to get
|
||
* @return promise for the property value
|
||
*/
|
||
Q.get = function (object, key) {
|
||
return Q(object).dispatch("get", [key]);
|
||
};
|
||
|
||
Promise.prototype.get = function (key) {
|
||
return this.dispatch("get", [key]);
|
||
};
|
||
|
||
/**
|
||
* Sets the value of a property in a future turn.
|
||
* @param object promise or immediate reference for object object
|
||
* @param name name of property to set
|
||
* @param value new value of property
|
||
* @return promise for the return value
|
||
*/
|
||
Q.set = function (object, key, value) {
|
||
return Q(object).dispatch("set", [key, value]);
|
||
};
|
||
|
||
Promise.prototype.set = function (key, value) {
|
||
return this.dispatch("set", [key, value]);
|
||
};
|
||
|
||
/**
|
||
* Deletes a property in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @param name name of property to delete
|
||
* @return promise for the return value
|
||
*/
|
||
Q.del = // XXX legacy
|
||
Q["delete"] = function (object, key) {
|
||
return Q(object).dispatch("delete", [key]);
|
||
};
|
||
|
||
Promise.prototype.del = // XXX legacy
|
||
Promise.prototype["delete"] = function (key) {
|
||
return this.dispatch("delete", [key]);
|
||
};
|
||
|
||
/**
|
||
* Invokes a method in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @param name name of method to invoke
|
||
* @param value a value to post, typically an array of
|
||
* invocation arguments for promises that
|
||
* are ultimately backed with `resolve` values,
|
||
* as opposed to those backed with URLs
|
||
* wherein the posted value can be any
|
||
* JSON serializable object.
|
||
* @return promise for the return value
|
||
*/
|
||
// bound locally because it is used by other methods
|
||
Q.mapply = // XXX As proposed by "Redsandro"
|
||
Q.post = function (object, name, args) {
|
||
return Q(object).dispatch("post", [name, args]);
|
||
};
|
||
|
||
Promise.prototype.mapply = // XXX As proposed by "Redsandro"
|
||
Promise.prototype.post = function (name, args) {
|
||
return this.dispatch("post", [name, args]);
|
||
};
|
||
|
||
/**
|
||
* Invokes a method in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @param name name of method to invoke
|
||
* @param ...args array of invocation arguments
|
||
* @return promise for the return value
|
||
*/
|
||
Q.send = // XXX Mark Miller's proposed parlance
|
||
Q.mcall = // XXX As proposed by "Redsandro"
|
||
Q.invoke = function (object, name /*...args*/) {
|
||
return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
|
||
};
|
||
|
||
Promise.prototype.send = // XXX Mark Miller's proposed parlance
|
||
Promise.prototype.mcall = // XXX As proposed by "Redsandro"
|
||
Promise.prototype.invoke = function (name /*...args*/) {
|
||
return this.dispatch("post", [name, array_slice(arguments, 1)]);
|
||
};
|
||
|
||
/**
|
||
* Applies the promised function in a future turn.
|
||
* @param object promise or immediate reference for target function
|
||
* @param args array of application arguments
|
||
*/
|
||
Q.fapply = function (object, args) {
|
||
return Q(object).dispatch("apply", [void 0, args]);
|
||
};
|
||
|
||
Promise.prototype.fapply = function (args) {
|
||
return this.dispatch("apply", [void 0, args]);
|
||
};
|
||
|
||
/**
|
||
* Calls the promised function in a future turn.
|
||
* @param object promise or immediate reference for target function
|
||
* @param ...args array of application arguments
|
||
*/
|
||
Q["try"] =
|
||
Q.fcall = function (object /* ...args*/) {
|
||
return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
|
||
};
|
||
|
||
Promise.prototype.fcall = function (/*...args*/) {
|
||
return this.dispatch("apply", [void 0, array_slice(arguments)]);
|
||
};
|
||
|
||
/**
|
||
* Binds the promised function, transforming return values into a fulfilled
|
||
* promise and thrown errors into a rejected one.
|
||
* @param object promise or immediate reference for target function
|
||
* @param ...args array of application arguments
|
||
*/
|
||
Q.fbind = function (object /*...args*/) {
|
||
var promise = Q(object);
|
||
var args = array_slice(arguments, 1);
|
||
return function fbound() {
|
||
return promise.dispatch("apply", [
|
||
this,
|
||
args.concat(array_slice(arguments))
|
||
]);
|
||
};
|
||
};
|
||
Promise.prototype.fbind = function (/*...args*/) {
|
||
var promise = this;
|
||
var args = array_slice(arguments);
|
||
return function fbound() {
|
||
return promise.dispatch("apply", [
|
||
this,
|
||
args.concat(array_slice(arguments))
|
||
]);
|
||
};
|
||
};
|
||
|
||
/**
|
||
* Requests the names of the owned properties of a promised
|
||
* object in a future turn.
|
||
* @param object promise or immediate reference for target object
|
||
* @return promise for the keys of the eventually settled object
|
||
*/
|
||
Q.keys = function (object) {
|
||
return Q(object).dispatch("keys", []);
|
||
};
|
||
|
||
Promise.prototype.keys = function () {
|
||
return this.dispatch("keys", []);
|
||
};
|
||
|
||
/**
|
||
* Turns an array of promises into a promise for an array. If any of
|
||
* the promises gets rejected, the whole array is rejected immediately.
|
||
* @param {Array*} an array (or promise for an array) of values (or
|
||
* promises for values)
|
||
* @returns a promise for an array of the corresponding values
|
||
*/
|
||
// By Mark Miller
|
||
// http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
|
||
Q.all = all;
|
||
function all(promises) {
|
||
return when(promises, function (promises) {
|
||
var pendingCount = 0;
|
||
var deferred = defer();
|
||
array_reduce(promises, function (undefined, promise, index) {
|
||
var snapshot;
|
||
if (
|
||
isPromise(promise) &&
|
||
(snapshot = promise.inspect()).state === "fulfilled"
|
||
) {
|
||
promises[index] = snapshot.value;
|
||
} else {
|
||
++pendingCount;
|
||
when(
|
||
promise,
|
||
function (value) {
|
||
promises[index] = value;
|
||
if (--pendingCount === 0) {
|
||
deferred.resolve(promises);
|
||
}
|
||
},
|
||
deferred.reject,
|
||
function (progress) {
|
||
deferred.notify({ index: index, value: progress });
|
||
}
|
||
);
|
||
}
|
||
}, void 0);
|
||
if (pendingCount === 0) {
|
||
deferred.resolve(promises);
|
||
}
|
||
return deferred.promise;
|
||
});
|
||
}
|
||
|
||
Promise.prototype.all = function () {
|
||
return all(this);
|
||
};
|
||
|
||
/**
|
||
* Returns the first resolved promise of an array. Prior rejected promises are
|
||
* ignored. Rejects only if all promises are rejected.
|
||
* @param {Array*} an array containing values or promises for values
|
||
* @returns a promise fulfilled with the value of the first resolved promise,
|
||
* or a rejected promise if all promises are rejected.
|
||
*/
|
||
Q.any = any;
|
||
|
||
function any(promises) {
|
||
if (promises.length === 0) {
|
||
return Q.resolve();
|
||
}
|
||
|
||
var deferred = Q.defer();
|
||
var pendingCount = 0;
|
||
array_reduce(promises, function (prev, current, index) {
|
||
var promise = promises[index];
|
||
|
||
pendingCount++;
|
||
|
||
when(promise, onFulfilled, onRejected, onProgress);
|
||
function onFulfilled(result) {
|
||
deferred.resolve(result);
|
||
}
|
||
function onRejected(err) {
|
||
pendingCount--;
|
||
if (pendingCount === 0) {
|
||
var rejection = err || new Error("" + err);
|
||
|
||
rejection.message = ("Q can't get fulfillment value from any promise, all " +
|
||
"promises were rejected. Last error message: " + rejection.message);
|
||
|
||
deferred.reject(rejection);
|
||
}
|
||
}
|
||
function onProgress(progress) {
|
||
deferred.notify({
|
||
index: index,
|
||
value: progress
|
||
});
|
||
}
|
||
}, undefined);
|
||
|
||
return deferred.promise;
|
||
}
|
||
|
||
Promise.prototype.any = function () {
|
||
return any(this);
|
||
};
|
||
|
||
/**
|
||
* Waits for all promises to be settled, either fulfilled or
|
||
* rejected. This is distinct from `all` since that would stop
|
||
* waiting at the first rejection. The promise returned by
|
||
* `allResolved` will never be rejected.
|
||
* @param promises a promise for an array (or an array) of promises
|
||
* (or values)
|
||
* @return a promise for an array of promises
|
||
*/
|
||
Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
|
||
function allResolved(promises) {
|
||
return when(promises, function (promises) {
|
||
promises = array_map(promises, Q);
|
||
return when(all(array_map(promises, function (promise) {
|
||
return when(promise, noop, noop);
|
||
})), function () {
|
||
return promises;
|
||
});
|
||
});
|
||
}
|
||
|
||
Promise.prototype.allResolved = function () {
|
||
return allResolved(this);
|
||
};
|
||
|
||
/**
|
||
* @see Promise#allSettled
|
||
*/
|
||
Q.allSettled = allSettled;
|
||
function allSettled(promises) {
|
||
return Q(promises).allSettled();
|
||
}
|
||
|
||
/**
|
||
* Turns an array of promises into a promise for an array of their states (as
|
||
* returned by `inspect`) when they have all settled.
|
||
* @param {Array[Any*]} values an array (or promise for an array) of values (or
|
||
* promises for values)
|
||
* @returns {Array[State]} an array of states for the respective values.
|
||
*/
|
||
Promise.prototype.allSettled = function () {
|
||
return this.then(function (promises) {
|
||
return all(array_map(promises, function (promise) {
|
||
promise = Q(promise);
|
||
function regardless() {
|
||
return promise.inspect();
|
||
}
|
||
return promise.then(regardless, regardless);
|
||
}));
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Captures the failure of a promise, giving an oportunity to recover
|
||
* with a callback. If the given promise is fulfilled, the returned
|
||
* promise is fulfilled.
|
||
* @param {Any*} promise for something
|
||
* @param {Function} callback to fulfill the returned promise if the
|
||
* given promise is rejected
|
||
* @returns a promise for the return value of the callback
|
||
*/
|
||
Q.fail = // XXX legacy
|
||
Q["catch"] = function (object, rejected) {
|
||
return Q(object).then(void 0, rejected);
|
||
};
|
||
|
||
Promise.prototype.fail = // XXX legacy
|
||
Promise.prototype["catch"] = function (rejected) {
|
||
return this.then(void 0, rejected);
|
||
};
|
||
|
||
/**
|
||
* Attaches a listener that can respond to progress notifications from a
|
||
* promise's originating deferred. This listener receives the exact arguments
|
||
* passed to ``deferred.notify``.
|
||
* @param {Any*} promise for something
|
||
* @param {Function} callback to receive any progress notifications
|
||
* @returns the given promise, unchanged
|
||
*/
|
||
Q.progress = progress;
|
||
function progress(object, progressed) {
|
||
return Q(object).then(void 0, void 0, progressed);
|
||
}
|
||
|
||
Promise.prototype.progress = function (progressed) {
|
||
return this.then(void 0, void 0, progressed);
|
||
};
|
||
|
||
/**
|
||
* Provides an opportunity to observe the settling of a promise,
|
||
* regardless of whether the promise is fulfilled or rejected. Forwards
|
||
* the resolution to the returned promise when the callback is done.
|
||
* The callback can return a promise to defer completion.
|
||
* @param {Any*} promise
|
||
* @param {Function} callback to observe the resolution of the given
|
||
* promise, takes no arguments.
|
||
* @returns a promise for the resolution of the given promise when
|
||
* ``fin`` is done.
|
||
*/
|
||
Q.fin = // XXX legacy
|
||
Q["finally"] = function (object, callback) {
|
||
return Q(object)["finally"](callback);
|
||
};
|
||
|
||
Promise.prototype.fin = // XXX legacy
|
||
Promise.prototype["finally"] = function (callback) {
|
||
if (!callback || typeof callback.apply !== "function") {
|
||
throw new Error("Q can't apply finally callback");
|
||
}
|
||
callback = Q(callback);
|
||
return this.then(function (value) {
|
||
return callback.fcall().then(function () {
|
||
return value;
|
||
});
|
||
}, function (reason) {
|
||
// TODO attempt to recycle the rejection with "this".
|
||
return callback.fcall().then(function () {
|
||
throw reason;
|
||
});
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Terminates a chain of promises, forcing rejections to be
|
||
* thrown as exceptions.
|
||
* @param {Any*} promise at the end of a chain of promises
|
||
* @returns nothing
|
||
*/
|
||
Q.done = function (object, fulfilled, rejected, progress) {
|
||
return Q(object).done(fulfilled, rejected, progress);
|
||
};
|
||
|
||
Promise.prototype.done = function (fulfilled, rejected, progress) {
|
||
var onUnhandledError = function (error) {
|
||
// forward to a future turn so that ``when``
|
||
// does not catch it and turn it into a rejection.
|
||
Q.nextTick(function () {
|
||
makeStackTraceLong(error, promise);
|
||
if (Q.onerror) {
|
||
Q.onerror(error);
|
||
} else {
|
||
throw error;
|
||
}
|
||
});
|
||
};
|
||
|
||
// Avoid unnecessary `nextTick`ing via an unnecessary `when`.
|
||
var promise = fulfilled || rejected || progress ?
|
||
this.then(fulfilled, rejected, progress) :
|
||
this;
|
||
|
||
if (typeof process === "object" && process && process.domain) {
|
||
onUnhandledError = process.domain.bind(onUnhandledError);
|
||
}
|
||
|
||
promise.then(void 0, onUnhandledError);
|
||
};
|
||
|
||
/**
|
||
* Causes a promise to be rejected if it does not get fulfilled before
|
||
* some milliseconds time out.
|
||
* @param {Any*} promise
|
||
* @param {Number} milliseconds timeout
|
||
* @param {Any*} custom error message or Error object (optional)
|
||
* @returns a promise for the resolution of the given promise if it is
|
||
* fulfilled before the timeout, otherwise rejected.
|
||
*/
|
||
Q.timeout = function (object, ms, error) {
|
||
return Q(object).timeout(ms, error);
|
||
};
|
||
|
||
Promise.prototype.timeout = function (ms, error) {
|
||
var deferred = defer();
|
||
var timeoutId = setTimeout(function () {
|
||
if (!error || "string" === typeof error) {
|
||
error = new Error(error || "Timed out after " + ms + " ms");
|
||
error.code = "ETIMEDOUT";
|
||
}
|
||
deferred.reject(error);
|
||
}, ms);
|
||
|
||
this.then(function (value) {
|
||
clearTimeout(timeoutId);
|
||
deferred.resolve(value);
|
||
}, function (exception) {
|
||
clearTimeout(timeoutId);
|
||
deferred.reject(exception);
|
||
}, deferred.notify);
|
||
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Returns a promise for the given value (or promised value), some
|
||
* milliseconds after it resolved. Passes rejections immediately.
|
||
* @param {Any*} promise
|
||
* @param {Number} milliseconds
|
||
* @returns a promise for the resolution of the given promise after milliseconds
|
||
* time has elapsed since the resolution of the given promise.
|
||
* If the given promise rejects, that is passed immediately.
|
||
*/
|
||
Q.delay = function (object, timeout) {
|
||
if (timeout === void 0) {
|
||
timeout = object;
|
||
object = void 0;
|
||
}
|
||
return Q(object).delay(timeout);
|
||
};
|
||
|
||
Promise.prototype.delay = function (timeout) {
|
||
return this.then(function (value) {
|
||
var deferred = defer();
|
||
setTimeout(function () {
|
||
deferred.resolve(value);
|
||
}, timeout);
|
||
return deferred.promise;
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Passes a continuation to a Node function, which is called with the given
|
||
* arguments provided as an array, and returns a promise.
|
||
*
|
||
* Q.nfapply(FS.readFile, [__filename])
|
||
* .then(function (content) {
|
||
* })
|
||
*
|
||
*/
|
||
Q.nfapply = function (callback, args) {
|
||
return Q(callback).nfapply(args);
|
||
};
|
||
|
||
Promise.prototype.nfapply = function (args) {
|
||
var deferred = defer();
|
||
var nodeArgs = array_slice(args);
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
this.fapply(nodeArgs).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Passes a continuation to a Node function, which is called with the given
|
||
* arguments provided individually, and returns a promise.
|
||
* @example
|
||
* Q.nfcall(FS.readFile, __filename)
|
||
* .then(function (content) {
|
||
* })
|
||
*
|
||
*/
|
||
Q.nfcall = function (callback /*...args*/) {
|
||
var args = array_slice(arguments, 1);
|
||
return Q(callback).nfapply(args);
|
||
};
|
||
|
||
Promise.prototype.nfcall = function (/*...args*/) {
|
||
var nodeArgs = array_slice(arguments);
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
this.fapply(nodeArgs).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Wraps a NodeJS continuation passing function and returns an equivalent
|
||
* version that returns a promise.
|
||
* @example
|
||
* Q.nfbind(FS.readFile, __filename)("utf-8")
|
||
* .then(console.log)
|
||
* .done()
|
||
*/
|
||
Q.nfbind =
|
||
Q.denodeify = function (callback /*...args*/) {
|
||
if (callback === undefined) {
|
||
throw new Error("Q can't wrap an undefined function");
|
||
}
|
||
var baseArgs = array_slice(arguments, 1);
|
||
return function () {
|
||
var nodeArgs = baseArgs.concat(array_slice(arguments));
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
Q(callback).fapply(nodeArgs).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
};
|
||
|
||
Promise.prototype.nfbind =
|
||
Promise.prototype.denodeify = function (/*...args*/) {
|
||
var args = array_slice(arguments);
|
||
args.unshift(this);
|
||
return Q.denodeify.apply(void 0, args);
|
||
};
|
||
|
||
Q.nbind = function (callback, thisp /*...args*/) {
|
||
var baseArgs = array_slice(arguments, 2);
|
||
return function () {
|
||
var nodeArgs = baseArgs.concat(array_slice(arguments));
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
function bound() {
|
||
return callback.apply(thisp, arguments);
|
||
}
|
||
Q(bound).fapply(nodeArgs).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
};
|
||
|
||
Promise.prototype.nbind = function (/*thisp, ...args*/) {
|
||
var args = array_slice(arguments, 0);
|
||
args.unshift(this);
|
||
return Q.nbind.apply(void 0, args);
|
||
};
|
||
|
||
/**
|
||
* Calls a method of a Node-style object that accepts a Node-style
|
||
* callback with a given array of arguments, plus a provided callback.
|
||
* @param object an object that has the named method
|
||
* @param {String} name name of the method of object
|
||
* @param {Array} args arguments to pass to the method; the callback
|
||
* will be provided by Q and appended to these arguments.
|
||
* @returns a promise for the value or error
|
||
*/
|
||
Q.nmapply = // XXX As proposed by "Redsandro"
|
||
Q.npost = function (object, name, args) {
|
||
return Q(object).npost(name, args);
|
||
};
|
||
|
||
Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
|
||
Promise.prototype.npost = function (name, args) {
|
||
var nodeArgs = array_slice(args || []);
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* Calls a method of a Node-style object that accepts a Node-style
|
||
* callback, forwarding the given variadic arguments, plus a provided
|
||
* callback argument.
|
||
* @param object an object that has the named method
|
||
* @param {String} name name of the method of object
|
||
* @param ...args arguments to pass to the method; the callback will
|
||
* be provided by Q and appended to these arguments.
|
||
* @returns a promise for the value or error
|
||
*/
|
||
Q.nsend = // XXX Based on Mark Miller's proposed "send"
|
||
Q.nmcall = // XXX Based on "Redsandro's" proposal
|
||
Q.ninvoke = function (object, name /*...args*/) {
|
||
var nodeArgs = array_slice(arguments, 2);
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
|
||
Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
|
||
Promise.prototype.ninvoke = function (name /*...args*/) {
|
||
var nodeArgs = array_slice(arguments, 1);
|
||
var deferred = defer();
|
||
nodeArgs.push(deferred.makeNodeResolver());
|
||
this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
|
||
return deferred.promise;
|
||
};
|
||
|
||
/**
|
||
* If a function would like to support both Node continuation-passing-style and
|
||
* promise-returning-style, it can end its internal promise chain with
|
||
* `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user
|
||
* elects to use a nodeback, the result will be sent there. If they do not
|
||
* pass a nodeback, they will receive the result promise.
|
||
* @param object a result (or a promise for a result)
|
||
* @param {Function} nodeback a Node.js-style callback
|
||
* @returns either the promise or nothing
|
||
*/
|
||
Q.nodeify = nodeify;
|
||
function nodeify(object, nodeback) {
|
||
return Q(object).nodeify(nodeback);
|
||
}
|
||
|
||
Promise.prototype.nodeify = function (nodeback) {
|
||
if (nodeback) {
|
||
this.then(function (value) {
|
||
Q.nextTick(function () {
|
||
nodeback(null, value);
|
||
});
|
||
}, function (error) {
|
||
Q.nextTick(function () {
|
||
nodeback(error);
|
||
});
|
||
});
|
||
} else {
|
||
return this;
|
||
}
|
||
};
|
||
|
||
Q.noConflict = function() {
|
||
throw new Error("Q.noConflict only works when Q is used as a global");
|
||
};
|
||
|
||
// All code before this point will be filtered from stack traces.
|
||
var qEndingLine = captureLine();
|
||
|
||
return Q;
|
||
|
||
});
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/qs/lib/formats.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/qs/lib/formats.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
|
||
var replace = String.prototype.replace;
|
||
var percentTwenties = /%20/g;
|
||
|
||
var util = __webpack_require__(/*! ./utils */ "./node_modules/qs/lib/utils.js");
|
||
|
||
var Format = {
|
||
RFC1738: 'RFC1738',
|
||
RFC3986: 'RFC3986'
|
||
};
|
||
|
||
module.exports = util.assign(
|
||
{
|
||
'default': Format.RFC3986,
|
||
formatters: {
|
||
RFC1738: function (value) {
|
||
return replace.call(value, percentTwenties, '+');
|
||
},
|
||
RFC3986: function (value) {
|
||
return String(value);
|
||
}
|
||
}
|
||
},
|
||
Format
|
||
);
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/qs/lib/index.js":
|
||
/*!**************************************!*\
|
||
!*** ./node_modules/qs/lib/index.js ***!
|
||
\**************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
|
||
var stringify = __webpack_require__(/*! ./stringify */ "./node_modules/qs/lib/stringify.js");
|
||
var parse = __webpack_require__(/*! ./parse */ "./node_modules/qs/lib/parse.js");
|
||
var formats = __webpack_require__(/*! ./formats */ "./node_modules/qs/lib/formats.js");
|
||
|
||
module.exports = {
|
||
formats: formats,
|
||
parse: parse,
|
||
stringify: stringify
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/qs/lib/parse.js":
|
||
/*!**************************************!*\
|
||
!*** ./node_modules/qs/lib/parse.js ***!
|
||
\**************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ./utils */ "./node_modules/qs/lib/utils.js");
|
||
|
||
var has = Object.prototype.hasOwnProperty;
|
||
var isArray = Array.isArray;
|
||
|
||
var defaults = {
|
||
allowDots: false,
|
||
allowPrototypes: false,
|
||
arrayLimit: 20,
|
||
charset: 'utf-8',
|
||
charsetSentinel: false,
|
||
comma: false,
|
||
decoder: utils.decode,
|
||
delimiter: '&',
|
||
depth: 5,
|
||
ignoreQueryPrefix: false,
|
||
interpretNumericEntities: false,
|
||
parameterLimit: 1000,
|
||
parseArrays: true,
|
||
plainObjects: false,
|
||
strictNullHandling: false
|
||
};
|
||
|
||
var interpretNumericEntities = function (str) {
|
||
return str.replace(/&#(\d+);/g, function ($0, numberStr) {
|
||
return String.fromCharCode(parseInt(numberStr, 10));
|
||
});
|
||
};
|
||
|
||
var parseArrayValue = function (val, options) {
|
||
if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
|
||
return val.split(',');
|
||
}
|
||
|
||
return val;
|
||
};
|
||
|
||
var maybeMap = function maybeMap(val, fn) {
|
||
if (isArray(val)) {
|
||
var mapped = [];
|
||
for (var i = 0; i < val.length; i += 1) {
|
||
mapped.push(fn(val[i]));
|
||
}
|
||
return mapped;
|
||
}
|
||
return fn(val);
|
||
};
|
||
|
||
// This is what browsers will submit when the ✓ character occurs in an
|
||
// application/x-www-form-urlencoded body and the encoding of the page containing
|
||
// the form is iso-8859-1, or when the submitted form has an accept-charset
|
||
// attribute of iso-8859-1. Presumably also with other charsets that do not contain
|
||
// the ✓ character, such as us-ascii.
|
||
var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓')
|
||
|
||
// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.
|
||
var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
|
||
|
||
var parseValues = function parseQueryStringValues(str, options) {
|
||
var obj = {};
|
||
var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
|
||
var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
|
||
var parts = cleanStr.split(options.delimiter, limit);
|
||
var skipIndex = -1; // Keep track of where the utf8 sentinel was found
|
||
var i;
|
||
|
||
var charset = options.charset;
|
||
if (options.charsetSentinel) {
|
||
for (i = 0; i < parts.length; ++i) {
|
||
if (parts[i].indexOf('utf8=') === 0) {
|
||
if (parts[i] === charsetSentinel) {
|
||
charset = 'utf-8';
|
||
} else if (parts[i] === isoSentinel) {
|
||
charset = 'iso-8859-1';
|
||
}
|
||
skipIndex = i;
|
||
i = parts.length; // The eslint settings do not allow break;
|
||
}
|
||
}
|
||
}
|
||
|
||
for (i = 0; i < parts.length; ++i) {
|
||
if (i === skipIndex) {
|
||
continue;
|
||
}
|
||
var part = parts[i];
|
||
|
||
var bracketEqualsPos = part.indexOf(']=');
|
||
var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;
|
||
|
||
var key, val;
|
||
if (pos === -1) {
|
||
key = options.decoder(part, defaults.decoder, charset, 'key');
|
||
val = options.strictNullHandling ? null : '';
|
||
} else {
|
||
key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
|
||
val = maybeMap(
|
||
parseArrayValue(part.slice(pos + 1), options),
|
||
function (encodedVal) {
|
||
return options.decoder(encodedVal, defaults.decoder, charset, 'value');
|
||
}
|
||
);
|
||
}
|
||
|
||
if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
|
||
val = interpretNumericEntities(val);
|
||
}
|
||
|
||
if (part.indexOf('[]=') > -1) {
|
||
val = isArray(val) ? [val] : val;
|
||
}
|
||
|
||
if (has.call(obj, key)) {
|
||
obj[key] = utils.combine(obj[key], val);
|
||
} else {
|
||
obj[key] = val;
|
||
}
|
||
}
|
||
|
||
return obj;
|
||
};
|
||
|
||
var parseObject = function (chain, val, options, valuesParsed) {
|
||
var leaf = valuesParsed ? val : parseArrayValue(val, options);
|
||
|
||
for (var i = chain.length - 1; i >= 0; --i) {
|
||
var obj;
|
||
var root = chain[i];
|
||
|
||
if (root === '[]' && options.parseArrays) {
|
||
obj = [].concat(leaf);
|
||
} else {
|
||
obj = options.plainObjects ? Object.create(null) : {};
|
||
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
|
||
var index = parseInt(cleanRoot, 10);
|
||
if (!options.parseArrays && cleanRoot === '') {
|
||
obj = { 0: leaf };
|
||
} else if (
|
||
!isNaN(index)
|
||
&& root !== cleanRoot
|
||
&& String(index) === cleanRoot
|
||
&& index >= 0
|
||
&& (options.parseArrays && index <= options.arrayLimit)
|
||
) {
|
||
obj = [];
|
||
obj[index] = leaf;
|
||
} else {
|
||
obj[cleanRoot] = leaf;
|
||
}
|
||
}
|
||
|
||
leaf = obj; // eslint-disable-line no-param-reassign
|
||
}
|
||
|
||
return leaf;
|
||
};
|
||
|
||
var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {
|
||
if (!givenKey) {
|
||
return;
|
||
}
|
||
|
||
// Transform dot notation to bracket notation
|
||
var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey;
|
||
|
||
// The regex chunks
|
||
|
||
var brackets = /(\[[^[\]]*])/;
|
||
var child = /(\[[^[\]]*])/g;
|
||
|
||
// Get the parent
|
||
|
||
var segment = options.depth > 0 && brackets.exec(key);
|
||
var parent = segment ? key.slice(0, segment.index) : key;
|
||
|
||
// Stash the parent if it exists
|
||
|
||
var keys = [];
|
||
if (parent) {
|
||
// If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
|
||
if (!options.plainObjects && has.call(Object.prototype, parent)) {
|
||
if (!options.allowPrototypes) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
keys.push(parent);
|
||
}
|
||
|
||
// Loop through children appending to the array until we hit depth
|
||
|
||
var i = 0;
|
||
while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {
|
||
i += 1;
|
||
if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
|
||
if (!options.allowPrototypes) {
|
||
return;
|
||
}
|
||
}
|
||
keys.push(segment[1]);
|
||
}
|
||
|
||
// If there's a remainder, just add whatever is left
|
||
|
||
if (segment) {
|
||
keys.push('[' + key.slice(segment.index) + ']');
|
||
}
|
||
|
||
return parseObject(keys, val, options, valuesParsed);
|
||
};
|
||
|
||
var normalizeParseOptions = function normalizeParseOptions(opts) {
|
||
if (!opts) {
|
||
return defaults;
|
||
}
|
||
|
||
if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') {
|
||
throw new TypeError('Decoder has to be a function.');
|
||
}
|
||
|
||
if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
|
||
throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
|
||
}
|
||
var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
|
||
|
||
return {
|
||
allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
|
||
allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
|
||
arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
|
||
charset: charset,
|
||
charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
||
comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
|
||
decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
|
||
delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
|
||
// eslint-disable-next-line no-implicit-coercion, no-extra-parens
|
||
depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,
|
||
ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
|
||
interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
|
||
parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
|
||
parseArrays: opts.parseArrays !== false,
|
||
plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
|
||
strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
|
||
};
|
||
};
|
||
|
||
module.exports = function (str, opts) {
|
||
var options = normalizeParseOptions(opts);
|
||
|
||
if (str === '' || str === null || typeof str === 'undefined') {
|
||
return options.plainObjects ? Object.create(null) : {};
|
||
}
|
||
|
||
var tempObj = typeof str === 'string' ? parseValues(str, options) : str;
|
||
var obj = options.plainObjects ? Object.create(null) : {};
|
||
|
||
// Iterate over the keys and setup the new object
|
||
|
||
var keys = Object.keys(tempObj);
|
||
for (var i = 0; i < keys.length; ++i) {
|
||
var key = keys[i];
|
||
var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string');
|
||
obj = utils.merge(obj, newObj, options);
|
||
}
|
||
|
||
return utils.compact(obj);
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/qs/lib/stringify.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/qs/lib/stringify.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
|
||
var utils = __webpack_require__(/*! ./utils */ "./node_modules/qs/lib/utils.js");
|
||
var formats = __webpack_require__(/*! ./formats */ "./node_modules/qs/lib/formats.js");
|
||
var has = Object.prototype.hasOwnProperty;
|
||
|
||
var arrayPrefixGenerators = {
|
||
brackets: function brackets(prefix) {
|
||
return prefix + '[]';
|
||
},
|
||
comma: 'comma',
|
||
indices: function indices(prefix, key) {
|
||
return prefix + '[' + key + ']';
|
||
},
|
||
repeat: function repeat(prefix) {
|
||
return prefix;
|
||
}
|
||
};
|
||
|
||
var isArray = Array.isArray;
|
||
var push = Array.prototype.push;
|
||
var pushToArray = function (arr, valueOrArray) {
|
||
push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
|
||
};
|
||
|
||
var toISO = Date.prototype.toISOString;
|
||
|
||
var defaultFormat = formats['default'];
|
||
var defaults = {
|
||
addQueryPrefix: false,
|
||
allowDots: false,
|
||
charset: 'utf-8',
|
||
charsetSentinel: false,
|
||
delimiter: '&',
|
||
encode: true,
|
||
encoder: utils.encode,
|
||
encodeValuesOnly: false,
|
||
format: defaultFormat,
|
||
formatter: formats.formatters[defaultFormat],
|
||
// deprecated
|
||
indices: false,
|
||
serializeDate: function serializeDate(date) {
|
||
return toISO.call(date);
|
||
},
|
||
skipNulls: false,
|
||
strictNullHandling: false
|
||
};
|
||
|
||
var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
|
||
return typeof v === 'string'
|
||
|| typeof v === 'number'
|
||
|| typeof v === 'boolean'
|
||
|| typeof v === 'symbol'
|
||
|| typeof v === 'bigint';
|
||
};
|
||
|
||
var stringify = function stringify(
|
||
object,
|
||
prefix,
|
||
generateArrayPrefix,
|
||
strictNullHandling,
|
||
skipNulls,
|
||
encoder,
|
||
filter,
|
||
sort,
|
||
allowDots,
|
||
serializeDate,
|
||
formatter,
|
||
encodeValuesOnly,
|
||
charset
|
||
) {
|
||
var obj = object;
|
||
if (typeof filter === 'function') {
|
||
obj = filter(prefix, obj);
|
||
} else if (obj instanceof Date) {
|
||
obj = serializeDate(obj);
|
||
} else if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
||
obj = obj.join(',');
|
||
}
|
||
|
||
if (obj === null) {
|
||
if (strictNullHandling) {
|
||
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key') : prefix;
|
||
}
|
||
|
||
obj = '';
|
||
}
|
||
|
||
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
|
||
if (encoder) {
|
||
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key');
|
||
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value'))];
|
||
}
|
||
return [formatter(prefix) + '=' + formatter(String(obj))];
|
||
}
|
||
|
||
var values = [];
|
||
|
||
if (typeof obj === 'undefined') {
|
||
return values;
|
||
}
|
||
|
||
var objKeys;
|
||
if (isArray(filter)) {
|
||
objKeys = filter;
|
||
} else {
|
||
var keys = Object.keys(obj);
|
||
objKeys = sort ? keys.sort(sort) : keys;
|
||
}
|
||
|
||
for (var i = 0; i < objKeys.length; ++i) {
|
||
var key = objKeys[i];
|
||
|
||
if (skipNulls && obj[key] === null) {
|
||
continue;
|
||
}
|
||
|
||
if (isArray(obj)) {
|
||
pushToArray(values, stringify(
|
||
obj[key],
|
||
typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix,
|
||
generateArrayPrefix,
|
||
strictNullHandling,
|
||
skipNulls,
|
||
encoder,
|
||
filter,
|
||
sort,
|
||
allowDots,
|
||
serializeDate,
|
||
formatter,
|
||
encodeValuesOnly,
|
||
charset
|
||
));
|
||
} else {
|
||
pushToArray(values, stringify(
|
||
obj[key],
|
||
prefix + (allowDots ? '.' + key : '[' + key + ']'),
|
||
generateArrayPrefix,
|
||
strictNullHandling,
|
||
skipNulls,
|
||
encoder,
|
||
filter,
|
||
sort,
|
||
allowDots,
|
||
serializeDate,
|
||
formatter,
|
||
encodeValuesOnly,
|
||
charset
|
||
));
|
||
}
|
||
}
|
||
|
||
return values;
|
||
};
|
||
|
||
var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
|
||
if (!opts) {
|
||
return defaults;
|
||
}
|
||
|
||
if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
|
||
throw new TypeError('Encoder has to be a function.');
|
||
}
|
||
|
||
var charset = opts.charset || defaults.charset;
|
||
if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
|
||
throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
|
||
}
|
||
|
||
var format = formats['default'];
|
||
if (typeof opts.format !== 'undefined') {
|
||
if (!has.call(formats.formatters, opts.format)) {
|
||
throw new TypeError('Unknown format option provided.');
|
||
}
|
||
format = opts.format;
|
||
}
|
||
var formatter = formats.formatters[format];
|
||
|
||
var filter = defaults.filter;
|
||
if (typeof opts.filter === 'function' || isArray(opts.filter)) {
|
||
filter = opts.filter;
|
||
}
|
||
|
||
return {
|
||
addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
|
||
allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
|
||
charset: charset,
|
||
charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
||
delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
|
||
encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
|
||
encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
|
||
encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
|
||
filter: filter,
|
||
formatter: formatter,
|
||
serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
|
||
skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
|
||
sort: typeof opts.sort === 'function' ? opts.sort : null,
|
||
strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
|
||
};
|
||
};
|
||
|
||
module.exports = function (object, opts) {
|
||
var obj = object;
|
||
var options = normalizeStringifyOptions(opts);
|
||
|
||
var objKeys;
|
||
var filter;
|
||
|
||
if (typeof options.filter === 'function') {
|
||
filter = options.filter;
|
||
obj = filter('', obj);
|
||
} else if (isArray(options.filter)) {
|
||
filter = options.filter;
|
||
objKeys = filter;
|
||
}
|
||
|
||
var keys = [];
|
||
|
||
if (typeof obj !== 'object' || obj === null) {
|
||
return '';
|
||
}
|
||
|
||
var arrayFormat;
|
||
if (opts && opts.arrayFormat in arrayPrefixGenerators) {
|
||
arrayFormat = opts.arrayFormat;
|
||
} else if (opts && 'indices' in opts) {
|
||
arrayFormat = opts.indices ? 'indices' : 'repeat';
|
||
} else {
|
||
arrayFormat = 'indices';
|
||
}
|
||
|
||
var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
|
||
|
||
if (!objKeys) {
|
||
objKeys = Object.keys(obj);
|
||
}
|
||
|
||
if (options.sort) {
|
||
objKeys.sort(options.sort);
|
||
}
|
||
|
||
for (var i = 0; i < objKeys.length; ++i) {
|
||
var key = objKeys[i];
|
||
|
||
if (options.skipNulls && obj[key] === null) {
|
||
continue;
|
||
}
|
||
pushToArray(keys, stringify(
|
||
obj[key],
|
||
key,
|
||
generateArrayPrefix,
|
||
options.strictNullHandling,
|
||
options.skipNulls,
|
||
options.encode ? options.encoder : null,
|
||
options.filter,
|
||
options.sort,
|
||
options.allowDots,
|
||
options.serializeDate,
|
||
options.formatter,
|
||
options.encodeValuesOnly,
|
||
options.charset
|
||
));
|
||
}
|
||
|
||
var joined = keys.join(options.delimiter);
|
||
var prefix = options.addQueryPrefix === true ? '?' : '';
|
||
|
||
if (options.charsetSentinel) {
|
||
if (options.charset === 'iso-8859-1') {
|
||
// encodeURIComponent('✓'), the "numeric entity" representation of a checkmark
|
||
prefix += 'utf8=%26%2310003%3B&';
|
||
} else {
|
||
// encodeURIComponent('✓')
|
||
prefix += 'utf8=%E2%9C%93&';
|
||
}
|
||
}
|
||
|
||
return joined.length > 0 ? prefix + joined : '';
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/qs/lib/utils.js":
|
||
/*!**************************************!*\
|
||
!*** ./node_modules/qs/lib/utils.js ***!
|
||
\**************************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
|
||
|
||
var has = Object.prototype.hasOwnProperty;
|
||
var isArray = Array.isArray;
|
||
|
||
var hexTable = (function () {
|
||
var array = [];
|
||
for (var i = 0; i < 256; ++i) {
|
||
array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
|
||
}
|
||
|
||
return array;
|
||
}());
|
||
|
||
var compactQueue = function compactQueue(queue) {
|
||
while (queue.length > 1) {
|
||
var item = queue.pop();
|
||
var obj = item.obj[item.prop];
|
||
|
||
if (isArray(obj)) {
|
||
var compacted = [];
|
||
|
||
for (var j = 0; j < obj.length; ++j) {
|
||
if (typeof obj[j] !== 'undefined') {
|
||
compacted.push(obj[j]);
|
||
}
|
||
}
|
||
|
||
item.obj[item.prop] = compacted;
|
||
}
|
||
}
|
||
};
|
||
|
||
var arrayToObject = function arrayToObject(source, options) {
|
||
var obj = options && options.plainObjects ? Object.create(null) : {};
|
||
for (var i = 0; i < source.length; ++i) {
|
||
if (typeof source[i] !== 'undefined') {
|
||
obj[i] = source[i];
|
||
}
|
||
}
|
||
|
||
return obj;
|
||
};
|
||
|
||
var merge = function merge(target, source, options) {
|
||
/* eslint no-param-reassign: 0 */
|
||
if (!source) {
|
||
return target;
|
||
}
|
||
|
||
if (typeof source !== 'object') {
|
||
if (isArray(target)) {
|
||
target.push(source);
|
||
} else if (target && typeof target === 'object') {
|
||
if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
|
||
target[source] = true;
|
||
}
|
||
} else {
|
||
return [target, source];
|
||
}
|
||
|
||
return target;
|
||
}
|
||
|
||
if (!target || typeof target !== 'object') {
|
||
return [target].concat(source);
|
||
}
|
||
|
||
var mergeTarget = target;
|
||
if (isArray(target) && !isArray(source)) {
|
||
mergeTarget = arrayToObject(target, options);
|
||
}
|
||
|
||
if (isArray(target) && isArray(source)) {
|
||
source.forEach(function (item, i) {
|
||
if (has.call(target, i)) {
|
||
var targetItem = target[i];
|
||
if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
|
||
target[i] = merge(targetItem, item, options);
|
||
} else {
|
||
target.push(item);
|
||
}
|
||
} else {
|
||
target[i] = item;
|
||
}
|
||
});
|
||
return target;
|
||
}
|
||
|
||
return Object.keys(source).reduce(function (acc, key) {
|
||
var value = source[key];
|
||
|
||
if (has.call(acc, key)) {
|
||
acc[key] = merge(acc[key], value, options);
|
||
} else {
|
||
acc[key] = value;
|
||
}
|
||
return acc;
|
||
}, mergeTarget);
|
||
};
|
||
|
||
var assign = function assignSingleSource(target, source) {
|
||
return Object.keys(source).reduce(function (acc, key) {
|
||
acc[key] = source[key];
|
||
return acc;
|
||
}, target);
|
||
};
|
||
|
||
var decode = function (str, decoder, charset) {
|
||
var strWithoutPlus = str.replace(/\+/g, ' ');
|
||
if (charset === 'iso-8859-1') {
|
||
// unescape never throws, no try...catch needed:
|
||
return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
|
||
}
|
||
// utf-8
|
||
try {
|
||
return decodeURIComponent(strWithoutPlus);
|
||
} catch (e) {
|
||
return strWithoutPlus;
|
||
}
|
||
};
|
||
|
||
var encode = function encode(str, defaultEncoder, charset) {
|
||
// This code was originally written by Brian White (mscdex) for the io.js core querystring library.
|
||
// It has been adapted here for stricter adherence to RFC 3986
|
||
if (str.length === 0) {
|
||
return str;
|
||
}
|
||
|
||
var string = str;
|
||
if (typeof str === 'symbol') {
|
||
string = Symbol.prototype.toString.call(str);
|
||
} else if (typeof str !== 'string') {
|
||
string = String(str);
|
||
}
|
||
|
||
if (charset === 'iso-8859-1') {
|
||
return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
|
||
return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
|
||
});
|
||
}
|
||
|
||
var out = '';
|
||
for (var i = 0; i < string.length; ++i) {
|
||
var c = string.charCodeAt(i);
|
||
|
||
if (
|
||
c === 0x2D // -
|
||
|| c === 0x2E // .
|
||
|| c === 0x5F // _
|
||
|| c === 0x7E // ~
|
||
|| (c >= 0x30 && c <= 0x39) // 0-9
|
||
|| (c >= 0x41 && c <= 0x5A) // a-z
|
||
|| (c >= 0x61 && c <= 0x7A) // A-Z
|
||
) {
|
||
out += string.charAt(i);
|
||
continue;
|
||
}
|
||
|
||
if (c < 0x80) {
|
||
out = out + hexTable[c];
|
||
continue;
|
||
}
|
||
|
||
if (c < 0x800) {
|
||
out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
|
||
continue;
|
||
}
|
||
|
||
if (c < 0xD800 || c >= 0xE000) {
|
||
out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
|
||
continue;
|
||
}
|
||
|
||
i += 1;
|
||
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
|
||
out += hexTable[0xF0 | (c >> 18)]
|
||
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
|
||
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
|
||
+ hexTable[0x80 | (c & 0x3F)];
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
var compact = function compact(value) {
|
||
var queue = [{ obj: { o: value }, prop: 'o' }];
|
||
var refs = [];
|
||
|
||
for (var i = 0; i < queue.length; ++i) {
|
||
var item = queue[i];
|
||
var obj = item.obj[item.prop];
|
||
|
||
var keys = Object.keys(obj);
|
||
for (var j = 0; j < keys.length; ++j) {
|
||
var key = keys[j];
|
||
var val = obj[key];
|
||
if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
|
||
queue.push({ obj: obj, prop: key });
|
||
refs.push(val);
|
||
}
|
||
}
|
||
}
|
||
|
||
compactQueue(queue);
|
||
|
||
return value;
|
||
};
|
||
|
||
var isRegExp = function isRegExp(obj) {
|
||
return Object.prototype.toString.call(obj) === '[object RegExp]';
|
||
};
|
||
|
||
var isBuffer = function isBuffer(obj) {
|
||
if (!obj || typeof obj !== 'object') {
|
||
return false;
|
||
}
|
||
|
||
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
|
||
};
|
||
|
||
var combine = function combine(a, b) {
|
||
return [].concat(a, b);
|
||
};
|
||
|
||
module.exports = {
|
||
arrayToObject: arrayToObject,
|
||
assign: assign,
|
||
combine: combine,
|
||
compact: compact,
|
||
decode: decode,
|
||
encode: encode,
|
||
isBuffer: isBuffer,
|
||
isRegExp: isRegExp,
|
||
merge: merge
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/reflect-metadata/Reflect.js":
|
||
/*!**************************************************!*\
|
||
!*** ./node_modules/reflect-metadata/Reflect.js ***!
|
||
\**************************************************/
|
||
/***/ (() => {
|
||
|
||
/*! *****************************************************************************
|
||
Copyright (C) Microsoft. All rights reserved.
|
||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||
this file except in compliance with the License. You may obtain a copy of the
|
||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||
|
||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||
|
||
See the Apache Version 2.0 License for specific language governing permissions
|
||
and limitations under the License.
|
||
***************************************************************************** */
|
||
var Reflect;
|
||
(function (Reflect) {
|
||
// Metadata Proposal
|
||
// https://rbuckton.github.io/reflect-metadata/
|
||
(function (factory) {
|
||
var root = typeof global === "object" ? global :
|
||
typeof self === "object" ? self :
|
||
typeof this === "object" ? this :
|
||
Function("return this;")();
|
||
var exporter = makeExporter(Reflect);
|
||
if (typeof root.Reflect === "undefined") {
|
||
root.Reflect = Reflect;
|
||
}
|
||
else {
|
||
exporter = makeExporter(root.Reflect, exporter);
|
||
}
|
||
factory(exporter);
|
||
function makeExporter(target, previous) {
|
||
return function (key, value) {
|
||
if (typeof target[key] !== "function") {
|
||
Object.defineProperty(target, key, { configurable: true, writable: true, value: value });
|
||
}
|
||
if (previous)
|
||
previous(key, value);
|
||
};
|
||
}
|
||
})(function (exporter) {
|
||
var hasOwn = Object.prototype.hasOwnProperty;
|
||
// feature test for Symbol support
|
||
var supportsSymbol = typeof Symbol === "function";
|
||
var toPrimitiveSymbol = supportsSymbol && typeof Symbol.toPrimitive !== "undefined" ? Symbol.toPrimitive : "@@toPrimitive";
|
||
var iteratorSymbol = supportsSymbol && typeof Symbol.iterator !== "undefined" ? Symbol.iterator : "@@iterator";
|
||
var supportsCreate = typeof Object.create === "function"; // feature test for Object.create support
|
||
var supportsProto = { __proto__: [] } instanceof Array; // feature test for __proto__ support
|
||
var downLevel = !supportsCreate && !supportsProto;
|
||
var HashMap = {
|
||
// create an object in dictionary mode (a.k.a. "slow" mode in v8)
|
||
create: supportsCreate
|
||
? function () { return MakeDictionary(Object.create(null)); }
|
||
: supportsProto
|
||
? function () { return MakeDictionary({ __proto__: null }); }
|
||
: function () { return MakeDictionary({}); },
|
||
has: downLevel
|
||
? function (map, key) { return hasOwn.call(map, key); }
|
||
: function (map, key) { return key in map; },
|
||
get: downLevel
|
||
? function (map, key) { return hasOwn.call(map, key) ? map[key] : undefined; }
|
||
: function (map, key) { return map[key]; },
|
||
};
|
||
// Load global or shim versions of Map, Set, and WeakMap
|
||
var functionPrototype = Object.getPrototypeOf(Function);
|
||
var usePolyfill = typeof process === "object" && process.env && process.env["REFLECT_METADATA_USE_MAP_POLYFILL"] === "true";
|
||
var _Map = !usePolyfill && typeof Map === "function" && typeof Map.prototype.entries === "function" ? Map : CreateMapPolyfill();
|
||
var _Set = !usePolyfill && typeof Set === "function" && typeof Set.prototype.entries === "function" ? Set : CreateSetPolyfill();
|
||
var _WeakMap = !usePolyfill && typeof WeakMap === "function" ? WeakMap : CreateWeakMapPolyfill();
|
||
// [[Metadata]] internal slot
|
||
// https://rbuckton.github.io/reflect-metadata/#ordinary-object-internal-methods-and-internal-slots
|
||
var Metadata = new _WeakMap();
|
||
/**
|
||
* Applies a set of decorators to a property of a target object.
|
||
* @param decorators An array of decorators.
|
||
* @param target The target object.
|
||
* @param propertyKey (Optional) The property key to decorate.
|
||
* @param attributes (Optional) The property descriptor for the target key.
|
||
* @remarks Decorators are applied in reverse order.
|
||
* @example
|
||
*
|
||
* class Example {
|
||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||
* // static staticProperty;
|
||
* // property;
|
||
*
|
||
* constructor(p) { }
|
||
* static staticMethod(p) { }
|
||
* method(p) { }
|
||
* }
|
||
*
|
||
* // constructor
|
||
* Example = Reflect.decorate(decoratorsArray, Example);
|
||
*
|
||
* // property (on constructor)
|
||
* Reflect.decorate(decoratorsArray, Example, "staticProperty");
|
||
*
|
||
* // property (on prototype)
|
||
* Reflect.decorate(decoratorsArray, Example.prototype, "property");
|
||
*
|
||
* // method (on constructor)
|
||
* Object.defineProperty(Example, "staticMethod",
|
||
* Reflect.decorate(decoratorsArray, Example, "staticMethod",
|
||
* Object.getOwnPropertyDescriptor(Example, "staticMethod")));
|
||
*
|
||
* // method (on prototype)
|
||
* Object.defineProperty(Example.prototype, "method",
|
||
* Reflect.decorate(decoratorsArray, Example.prototype, "method",
|
||
* Object.getOwnPropertyDescriptor(Example.prototype, "method")));
|
||
*
|
||
*/
|
||
function decorate(decorators, target, propertyKey, attributes) {
|
||
if (!IsUndefined(propertyKey)) {
|
||
if (!IsArray(decorators))
|
||
throw new TypeError();
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsObject(attributes) && !IsUndefined(attributes) && !IsNull(attributes))
|
||
throw new TypeError();
|
||
if (IsNull(attributes))
|
||
attributes = undefined;
|
||
propertyKey = ToPropertyKey(propertyKey);
|
||
return DecorateProperty(decorators, target, propertyKey, attributes);
|
||
}
|
||
else {
|
||
if (!IsArray(decorators))
|
||
throw new TypeError();
|
||
if (!IsConstructor(target))
|
||
throw new TypeError();
|
||
return DecorateConstructor(decorators, target);
|
||
}
|
||
}
|
||
exporter("decorate", decorate);
|
||
// 4.1.2 Reflect.metadata(metadataKey, metadataValue)
|
||
// https://rbuckton.github.io/reflect-metadata/#reflect.metadata
|
||
/**
|
||
* A default metadata decorator factory that can be used on a class, class member, or parameter.
|
||
* @param metadataKey The key for the metadata entry.
|
||
* @param metadataValue The value for the metadata entry.
|
||
* @returns A decorator function.
|
||
* @remarks
|
||
* If `metadataKey` is already defined for the target and target key, the
|
||
* metadataValue for that key will be overwritten.
|
||
* @example
|
||
*
|
||
* // constructor
|
||
* @Reflect.metadata(key, value)
|
||
* class Example {
|
||
* }
|
||
*
|
||
* // property (on constructor, TypeScript only)
|
||
* class Example {
|
||
* @Reflect.metadata(key, value)
|
||
* static staticProperty;
|
||
* }
|
||
*
|
||
* // property (on prototype, TypeScript only)
|
||
* class Example {
|
||
* @Reflect.metadata(key, value)
|
||
* property;
|
||
* }
|
||
*
|
||
* // method (on constructor)
|
||
* class Example {
|
||
* @Reflect.metadata(key, value)
|
||
* static staticMethod() { }
|
||
* }
|
||
*
|
||
* // method (on prototype)
|
||
* class Example {
|
||
* @Reflect.metadata(key, value)
|
||
* method() { }
|
||
* }
|
||
*
|
||
*/
|
||
function metadata(metadataKey, metadataValue) {
|
||
function decorator(target, propertyKey) {
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsUndefined(propertyKey) && !IsPropertyKey(propertyKey))
|
||
throw new TypeError();
|
||
OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey);
|
||
}
|
||
return decorator;
|
||
}
|
||
exporter("metadata", metadata);
|
||
/**
|
||
* Define a unique metadata entry on the target.
|
||
* @param metadataKey A key used to store and retrieve metadata.
|
||
* @param metadataValue A value that contains attached metadata.
|
||
* @param target The target object on which to define metadata.
|
||
* @param propertyKey (Optional) The property key for the target.
|
||
* @example
|
||
*
|
||
* class Example {
|
||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||
* // static staticProperty;
|
||
* // property;
|
||
*
|
||
* constructor(p) { }
|
||
* static staticMethod(p) { }
|
||
* method(p) { }
|
||
* }
|
||
*
|
||
* // constructor
|
||
* Reflect.defineMetadata("custom:annotation", options, Example);
|
||
*
|
||
* // property (on constructor)
|
||
* Reflect.defineMetadata("custom:annotation", options, Example, "staticProperty");
|
||
*
|
||
* // property (on prototype)
|
||
* Reflect.defineMetadata("custom:annotation", options, Example.prototype, "property");
|
||
*
|
||
* // method (on constructor)
|
||
* Reflect.defineMetadata("custom:annotation", options, Example, "staticMethod");
|
||
*
|
||
* // method (on prototype)
|
||
* Reflect.defineMetadata("custom:annotation", options, Example.prototype, "method");
|
||
*
|
||
* // decorator factory as metadata-producing annotation.
|
||
* function MyAnnotation(options): Decorator {
|
||
* return (target, key?) => Reflect.defineMetadata("custom:annotation", options, target, key);
|
||
* }
|
||
*
|
||
*/
|
||
function defineMetadata(metadataKey, metadataValue, target, propertyKey) {
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsUndefined(propertyKey))
|
||
propertyKey = ToPropertyKey(propertyKey);
|
||
return OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey);
|
||
}
|
||
exporter("defineMetadata", defineMetadata);
|
||
/**
|
||
* Gets a value indicating whether the target object or its prototype chain has the provided metadata key defined.
|
||
* @param metadataKey A key used to store and retrieve metadata.
|
||
* @param target The target object on which the metadata is defined.
|
||
* @param propertyKey (Optional) The property key for the target.
|
||
* @returns `true` if the metadata key was defined on the target object or its prototype chain; otherwise, `false`.
|
||
* @example
|
||
*
|
||
* class Example {
|
||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||
* // static staticProperty;
|
||
* // property;
|
||
*
|
||
* constructor(p) { }
|
||
* static staticMethod(p) { }
|
||
* method(p) { }
|
||
* }
|
||
*
|
||
* // constructor
|
||
* result = Reflect.hasMetadata("custom:annotation", Example);
|
||
*
|
||
* // property (on constructor)
|
||
* result = Reflect.hasMetadata("custom:annotation", Example, "staticProperty");
|
||
*
|
||
* // property (on prototype)
|
||
* result = Reflect.hasMetadata("custom:annotation", Example.prototype, "property");
|
||
*
|
||
* // method (on constructor)
|
||
* result = Reflect.hasMetadata("custom:annotation", Example, "staticMethod");
|
||
*
|
||
* // method (on prototype)
|
||
* result = Reflect.hasMetadata("custom:annotation", Example.prototype, "method");
|
||
*
|
||
*/
|
||
function hasMetadata(metadataKey, target, propertyKey) {
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsUndefined(propertyKey))
|
||
propertyKey = ToPropertyKey(propertyKey);
|
||
return OrdinaryHasMetadata(metadataKey, target, propertyKey);
|
||
}
|
||
exporter("hasMetadata", hasMetadata);
|
||
/**
|
||
* Gets a value indicating whether the target object has the provided metadata key defined.
|
||
* @param metadataKey A key used to store and retrieve metadata.
|
||
* @param target The target object on which the metadata is defined.
|
||
* @param propertyKey (Optional) The property key for the target.
|
||
* @returns `true` if the metadata key was defined on the target object; otherwise, `false`.
|
||
* @example
|
||
*
|
||
* class Example {
|
||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||
* // static staticProperty;
|
||
* // property;
|
||
*
|
||
* constructor(p) { }
|
||
* static staticMethod(p) { }
|
||
* method(p) { }
|
||
* }
|
||
*
|
||
* // constructor
|
||
* result = Reflect.hasOwnMetadata("custom:annotation", Example);
|
||
*
|
||
* // property (on constructor)
|
||
* result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticProperty");
|
||
*
|
||
* // property (on prototype)
|
||
* result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "property");
|
||
*
|
||
* // method (on constructor)
|
||
* result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticMethod");
|
||
*
|
||
* // method (on prototype)
|
||
* result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "method");
|
||
*
|
||
*/
|
||
function hasOwnMetadata(metadataKey, target, propertyKey) {
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsUndefined(propertyKey))
|
||
propertyKey = ToPropertyKey(propertyKey);
|
||
return OrdinaryHasOwnMetadata(metadataKey, target, propertyKey);
|
||
}
|
||
exporter("hasOwnMetadata", hasOwnMetadata);
|
||
/**
|
||
* Gets the metadata value for the provided metadata key on the target object or its prototype chain.
|
||
* @param metadataKey A key used to store and retrieve metadata.
|
||
* @param target The target object on which the metadata is defined.
|
||
* @param propertyKey (Optional) The property key for the target.
|
||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||
* @example
|
||
*
|
||
* class Example {
|
||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||
* // static staticProperty;
|
||
* // property;
|
||
*
|
||
* constructor(p) { }
|
||
* static staticMethod(p) { }
|
||
* method(p) { }
|
||
* }
|
||
*
|
||
* // constructor
|
||
* result = Reflect.getMetadata("custom:annotation", Example);
|
||
*
|
||
* // property (on constructor)
|
||
* result = Reflect.getMetadata("custom:annotation", Example, "staticProperty");
|
||
*
|
||
* // property (on prototype)
|
||
* result = Reflect.getMetadata("custom:annotation", Example.prototype, "property");
|
||
*
|
||
* // method (on constructor)
|
||
* result = Reflect.getMetadata("custom:annotation", Example, "staticMethod");
|
||
*
|
||
* // method (on prototype)
|
||
* result = Reflect.getMetadata("custom:annotation", Example.prototype, "method");
|
||
*
|
||
*/
|
||
function getMetadata(metadataKey, target, propertyKey) {
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsUndefined(propertyKey))
|
||
propertyKey = ToPropertyKey(propertyKey);
|
||
return OrdinaryGetMetadata(metadataKey, target, propertyKey);
|
||
}
|
||
exporter("getMetadata", getMetadata);
|
||
/**
|
||
* Gets the metadata value for the provided metadata key on the target object.
|
||
* @param metadataKey A key used to store and retrieve metadata.
|
||
* @param target The target object on which the metadata is defined.
|
||
* @param propertyKey (Optional) The property key for the target.
|
||
* @returns The metadata value for the metadata key if found; otherwise, `undefined`.
|
||
* @example
|
||
*
|
||
* class Example {
|
||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||
* // static staticProperty;
|
||
* // property;
|
||
*
|
||
* constructor(p) { }
|
||
* static staticMethod(p) { }
|
||
* method(p) { }
|
||
* }
|
||
*
|
||
* // constructor
|
||
* result = Reflect.getOwnMetadata("custom:annotation", Example);
|
||
*
|
||
* // property (on constructor)
|
||
* result = Reflect.getOwnMetadata("custom:annotation", Example, "staticProperty");
|
||
*
|
||
* // property (on prototype)
|
||
* result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "property");
|
||
*
|
||
* // method (on constructor)
|
||
* result = Reflect.getOwnMetadata("custom:annotation", Example, "staticMethod");
|
||
*
|
||
* // method (on prototype)
|
||
* result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "method");
|
||
*
|
||
*/
|
||
function getOwnMetadata(metadataKey, target, propertyKey) {
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsUndefined(propertyKey))
|
||
propertyKey = ToPropertyKey(propertyKey);
|
||
return OrdinaryGetOwnMetadata(metadataKey, target, propertyKey);
|
||
}
|
||
exporter("getOwnMetadata", getOwnMetadata);
|
||
/**
|
||
* Gets the metadata keys defined on the target object or its prototype chain.
|
||
* @param target The target object on which the metadata is defined.
|
||
* @param propertyKey (Optional) The property key for the target.
|
||
* @returns An array of unique metadata keys.
|
||
* @example
|
||
*
|
||
* class Example {
|
||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||
* // static staticProperty;
|
||
* // property;
|
||
*
|
||
* constructor(p) { }
|
||
* static staticMethod(p) { }
|
||
* method(p) { }
|
||
* }
|
||
*
|
||
* // constructor
|
||
* result = Reflect.getMetadataKeys(Example);
|
||
*
|
||
* // property (on constructor)
|
||
* result = Reflect.getMetadataKeys(Example, "staticProperty");
|
||
*
|
||
* // property (on prototype)
|
||
* result = Reflect.getMetadataKeys(Example.prototype, "property");
|
||
*
|
||
* // method (on constructor)
|
||
* result = Reflect.getMetadataKeys(Example, "staticMethod");
|
||
*
|
||
* // method (on prototype)
|
||
* result = Reflect.getMetadataKeys(Example.prototype, "method");
|
||
*
|
||
*/
|
||
function getMetadataKeys(target, propertyKey) {
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsUndefined(propertyKey))
|
||
propertyKey = ToPropertyKey(propertyKey);
|
||
return OrdinaryMetadataKeys(target, propertyKey);
|
||
}
|
||
exporter("getMetadataKeys", getMetadataKeys);
|
||
/**
|
||
* Gets the unique metadata keys defined on the target object.
|
||
* @param target The target object on which the metadata is defined.
|
||
* @param propertyKey (Optional) The property key for the target.
|
||
* @returns An array of unique metadata keys.
|
||
* @example
|
||
*
|
||
* class Example {
|
||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||
* // static staticProperty;
|
||
* // property;
|
||
*
|
||
* constructor(p) { }
|
||
* static staticMethod(p) { }
|
||
* method(p) { }
|
||
* }
|
||
*
|
||
* // constructor
|
||
* result = Reflect.getOwnMetadataKeys(Example);
|
||
*
|
||
* // property (on constructor)
|
||
* result = Reflect.getOwnMetadataKeys(Example, "staticProperty");
|
||
*
|
||
* // property (on prototype)
|
||
* result = Reflect.getOwnMetadataKeys(Example.prototype, "property");
|
||
*
|
||
* // method (on constructor)
|
||
* result = Reflect.getOwnMetadataKeys(Example, "staticMethod");
|
||
*
|
||
* // method (on prototype)
|
||
* result = Reflect.getOwnMetadataKeys(Example.prototype, "method");
|
||
*
|
||
*/
|
||
function getOwnMetadataKeys(target, propertyKey) {
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsUndefined(propertyKey))
|
||
propertyKey = ToPropertyKey(propertyKey);
|
||
return OrdinaryOwnMetadataKeys(target, propertyKey);
|
||
}
|
||
exporter("getOwnMetadataKeys", getOwnMetadataKeys);
|
||
/**
|
||
* Deletes the metadata entry from the target object with the provided key.
|
||
* @param metadataKey A key used to store and retrieve metadata.
|
||
* @param target The target object on which the metadata is defined.
|
||
* @param propertyKey (Optional) The property key for the target.
|
||
* @returns `true` if the metadata entry was found and deleted; otherwise, false.
|
||
* @example
|
||
*
|
||
* class Example {
|
||
* // property declarations are not part of ES6, though they are valid in TypeScript:
|
||
* // static staticProperty;
|
||
* // property;
|
||
*
|
||
* constructor(p) { }
|
||
* static staticMethod(p) { }
|
||
* method(p) { }
|
||
* }
|
||
*
|
||
* // constructor
|
||
* result = Reflect.deleteMetadata("custom:annotation", Example);
|
||
*
|
||
* // property (on constructor)
|
||
* result = Reflect.deleteMetadata("custom:annotation", Example, "staticProperty");
|
||
*
|
||
* // property (on prototype)
|
||
* result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "property");
|
||
*
|
||
* // method (on constructor)
|
||
* result = Reflect.deleteMetadata("custom:annotation", Example, "staticMethod");
|
||
*
|
||
* // method (on prototype)
|
||
* result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "method");
|
||
*
|
||
*/
|
||
function deleteMetadata(metadataKey, target, propertyKey) {
|
||
if (!IsObject(target))
|
||
throw new TypeError();
|
||
if (!IsUndefined(propertyKey))
|
||
propertyKey = ToPropertyKey(propertyKey);
|
||
var metadataMap = GetOrCreateMetadataMap(target, propertyKey, /*Create*/ false);
|
||
if (IsUndefined(metadataMap))
|
||
return false;
|
||
if (!metadataMap.delete(metadataKey))
|
||
return false;
|
||
if (metadataMap.size > 0)
|
||
return true;
|
||
var targetMetadata = Metadata.get(target);
|
||
targetMetadata.delete(propertyKey);
|
||
if (targetMetadata.size > 0)
|
||
return true;
|
||
Metadata.delete(target);
|
||
return true;
|
||
}
|
||
exporter("deleteMetadata", deleteMetadata);
|
||
function DecorateConstructor(decorators, target) {
|
||
for (var i = decorators.length - 1; i >= 0; --i) {
|
||
var decorator = decorators[i];
|
||
var decorated = decorator(target);
|
||
if (!IsUndefined(decorated) && !IsNull(decorated)) {
|
||
if (!IsConstructor(decorated))
|
||
throw new TypeError();
|
||
target = decorated;
|
||
}
|
||
}
|
||
return target;
|
||
}
|
||
function DecorateProperty(decorators, target, propertyKey, descriptor) {
|
||
for (var i = decorators.length - 1; i >= 0; --i) {
|
||
var decorator = decorators[i];
|
||
var decorated = decorator(target, propertyKey, descriptor);
|
||
if (!IsUndefined(decorated) && !IsNull(decorated)) {
|
||
if (!IsObject(decorated))
|
||
throw new TypeError();
|
||
descriptor = decorated;
|
||
}
|
||
}
|
||
return descriptor;
|
||
}
|
||
function GetOrCreateMetadataMap(O, P, Create) {
|
||
var targetMetadata = Metadata.get(O);
|
||
if (IsUndefined(targetMetadata)) {
|
||
if (!Create)
|
||
return undefined;
|
||
targetMetadata = new _Map();
|
||
Metadata.set(O, targetMetadata);
|
||
}
|
||
var metadataMap = targetMetadata.get(P);
|
||
if (IsUndefined(metadataMap)) {
|
||
if (!Create)
|
||
return undefined;
|
||
metadataMap = new _Map();
|
||
targetMetadata.set(P, metadataMap);
|
||
}
|
||
return metadataMap;
|
||
}
|
||
// 3.1.1.1 OrdinaryHasMetadata(MetadataKey, O, P)
|
||
// https://rbuckton.github.io/reflect-metadata/#ordinaryhasmetadata
|
||
function OrdinaryHasMetadata(MetadataKey, O, P) {
|
||
var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P);
|
||
if (hasOwn)
|
||
return true;
|
||
var parent = OrdinaryGetPrototypeOf(O);
|
||
if (!IsNull(parent))
|
||
return OrdinaryHasMetadata(MetadataKey, parent, P);
|
||
return false;
|
||
}
|
||
// 3.1.2.1 OrdinaryHasOwnMetadata(MetadataKey, O, P)
|
||
// https://rbuckton.github.io/reflect-metadata/#ordinaryhasownmetadata
|
||
function OrdinaryHasOwnMetadata(MetadataKey, O, P) {
|
||
var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false);
|
||
if (IsUndefined(metadataMap))
|
||
return false;
|
||
return ToBoolean(metadataMap.has(MetadataKey));
|
||
}
|
||
// 3.1.3.1 OrdinaryGetMetadata(MetadataKey, O, P)
|
||
// https://rbuckton.github.io/reflect-metadata/#ordinarygetmetadata
|
||
function OrdinaryGetMetadata(MetadataKey, O, P) {
|
||
var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P);
|
||
if (hasOwn)
|
||
return OrdinaryGetOwnMetadata(MetadataKey, O, P);
|
||
var parent = OrdinaryGetPrototypeOf(O);
|
||
if (!IsNull(parent))
|
||
return OrdinaryGetMetadata(MetadataKey, parent, P);
|
||
return undefined;
|
||
}
|
||
// 3.1.4.1 OrdinaryGetOwnMetadata(MetadataKey, O, P)
|
||
// https://rbuckton.github.io/reflect-metadata/#ordinarygetownmetadata
|
||
function OrdinaryGetOwnMetadata(MetadataKey, O, P) {
|
||
var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false);
|
||
if (IsUndefined(metadataMap))
|
||
return undefined;
|
||
return metadataMap.get(MetadataKey);
|
||
}
|
||
// 3.1.5.1 OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P)
|
||
// https://rbuckton.github.io/reflect-metadata/#ordinarydefineownmetadata
|
||
function OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P) {
|
||
var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ true);
|
||
metadataMap.set(MetadataKey, MetadataValue);
|
||
}
|
||
// 3.1.6.1 OrdinaryMetadataKeys(O, P)
|
||
// https://rbuckton.github.io/reflect-metadata/#ordinarymetadatakeys
|
||
function OrdinaryMetadataKeys(O, P) {
|
||
var ownKeys = OrdinaryOwnMetadataKeys(O, P);
|
||
var parent = OrdinaryGetPrototypeOf(O);
|
||
if (parent === null)
|
||
return ownKeys;
|
||
var parentKeys = OrdinaryMetadataKeys(parent, P);
|
||
if (parentKeys.length <= 0)
|
||
return ownKeys;
|
||
if (ownKeys.length <= 0)
|
||
return parentKeys;
|
||
var set = new _Set();
|
||
var keys = [];
|
||
for (var _i = 0, ownKeys_1 = ownKeys; _i < ownKeys_1.length; _i++) {
|
||
var key = ownKeys_1[_i];
|
||
var hasKey = set.has(key);
|
||
if (!hasKey) {
|
||
set.add(key);
|
||
keys.push(key);
|
||
}
|
||
}
|
||
for (var _a = 0, parentKeys_1 = parentKeys; _a < parentKeys_1.length; _a++) {
|
||
var key = parentKeys_1[_a];
|
||
var hasKey = set.has(key);
|
||
if (!hasKey) {
|
||
set.add(key);
|
||
keys.push(key);
|
||
}
|
||
}
|
||
return keys;
|
||
}
|
||
// 3.1.7.1 OrdinaryOwnMetadataKeys(O, P)
|
||
// https://rbuckton.github.io/reflect-metadata/#ordinaryownmetadatakeys
|
||
function OrdinaryOwnMetadataKeys(O, P) {
|
||
var keys = [];
|
||
var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false);
|
||
if (IsUndefined(metadataMap))
|
||
return keys;
|
||
var keysObj = metadataMap.keys();
|
||
var iterator = GetIterator(keysObj);
|
||
var k = 0;
|
||
while (true) {
|
||
var next = IteratorStep(iterator);
|
||
if (!next) {
|
||
keys.length = k;
|
||
return keys;
|
||
}
|
||
var nextValue = IteratorValue(next);
|
||
try {
|
||
keys[k] = nextValue;
|
||
}
|
||
catch (e) {
|
||
try {
|
||
IteratorClose(iterator);
|
||
}
|
||
finally {
|
||
throw e;
|
||
}
|
||
}
|
||
k++;
|
||
}
|
||
}
|
||
// 6 ECMAScript Data Typ0es and Values
|
||
// https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values
|
||
function Type(x) {
|
||
if (x === null)
|
||
return 1 /* Null */;
|
||
switch (typeof x) {
|
||
case "undefined": return 0 /* Undefined */;
|
||
case "boolean": return 2 /* Boolean */;
|
||
case "string": return 3 /* String */;
|
||
case "symbol": return 4 /* Symbol */;
|
||
case "number": return 5 /* Number */;
|
||
case "object": return x === null ? 1 /* Null */ : 6 /* Object */;
|
||
default: return 6 /* Object */;
|
||
}
|
||
}
|
||
// 6.1.1 The Undefined Type
|
||
// https://tc39.github.io/ecma262/#sec-ecmascript-language-types-undefined-type
|
||
function IsUndefined(x) {
|
||
return x === undefined;
|
||
}
|
||
// 6.1.2 The Null Type
|
||
// https://tc39.github.io/ecma262/#sec-ecmascript-language-types-null-type
|
||
function IsNull(x) {
|
||
return x === null;
|
||
}
|
||
// 6.1.5 The Symbol Type
|
||
// https://tc39.github.io/ecma262/#sec-ecmascript-language-types-symbol-type
|
||
function IsSymbol(x) {
|
||
return typeof x === "symbol";
|
||
}
|
||
// 6.1.7 The Object Type
|
||
// https://tc39.github.io/ecma262/#sec-object-type
|
||
function IsObject(x) {
|
||
return typeof x === "object" ? x !== null : typeof x === "function";
|
||
}
|
||
// 7.1 Type Conversion
|
||
// https://tc39.github.io/ecma262/#sec-type-conversion
|
||
// 7.1.1 ToPrimitive(input [, PreferredType])
|
||
// https://tc39.github.io/ecma262/#sec-toprimitive
|
||
function ToPrimitive(input, PreferredType) {
|
||
switch (Type(input)) {
|
||
case 0 /* Undefined */: return input;
|
||
case 1 /* Null */: return input;
|
||
case 2 /* Boolean */: return input;
|
||
case 3 /* String */: return input;
|
||
case 4 /* Symbol */: return input;
|
||
case 5 /* Number */: return input;
|
||
}
|
||
var hint = PreferredType === 3 /* String */ ? "string" : PreferredType === 5 /* Number */ ? "number" : "default";
|
||
var exoticToPrim = GetMethod(input, toPrimitiveSymbol);
|
||
if (exoticToPrim !== undefined) {
|
||
var result = exoticToPrim.call(input, hint);
|
||
if (IsObject(result))
|
||
throw new TypeError();
|
||
return result;
|
||
}
|
||
return OrdinaryToPrimitive(input, hint === "default" ? "number" : hint);
|
||
}
|
||
// 7.1.1.1 OrdinaryToPrimitive(O, hint)
|
||
// https://tc39.github.io/ecma262/#sec-ordinarytoprimitive
|
||
function OrdinaryToPrimitive(O, hint) {
|
||
if (hint === "string") {
|
||
var toString_1 = O.toString;
|
||
if (IsCallable(toString_1)) {
|
||
var result = toString_1.call(O);
|
||
if (!IsObject(result))
|
||
return result;
|
||
}
|
||
var valueOf = O.valueOf;
|
||
if (IsCallable(valueOf)) {
|
||
var result = valueOf.call(O);
|
||
if (!IsObject(result))
|
||
return result;
|
||
}
|
||
}
|
||
else {
|
||
var valueOf = O.valueOf;
|
||
if (IsCallable(valueOf)) {
|
||
var result = valueOf.call(O);
|
||
if (!IsObject(result))
|
||
return result;
|
||
}
|
||
var toString_2 = O.toString;
|
||
if (IsCallable(toString_2)) {
|
||
var result = toString_2.call(O);
|
||
if (!IsObject(result))
|
||
return result;
|
||
}
|
||
}
|
||
throw new TypeError();
|
||
}
|
||
// 7.1.2 ToBoolean(argument)
|
||
// https://tc39.github.io/ecma262/2016/#sec-toboolean
|
||
function ToBoolean(argument) {
|
||
return !!argument;
|
||
}
|
||
// 7.1.12 ToString(argument)
|
||
// https://tc39.github.io/ecma262/#sec-tostring
|
||
function ToString(argument) {
|
||
return "" + argument;
|
||
}
|
||
// 7.1.14 ToPropertyKey(argument)
|
||
// https://tc39.github.io/ecma262/#sec-topropertykey
|
||
function ToPropertyKey(argument) {
|
||
var key = ToPrimitive(argument, 3 /* String */);
|
||
if (IsSymbol(key))
|
||
return key;
|
||
return ToString(key);
|
||
}
|
||
// 7.2 Testing and Comparison Operations
|
||
// https://tc39.github.io/ecma262/#sec-testing-and-comparison-operations
|
||
// 7.2.2 IsArray(argument)
|
||
// https://tc39.github.io/ecma262/#sec-isarray
|
||
function IsArray(argument) {
|
||
return Array.isArray
|
||
? Array.isArray(argument)
|
||
: argument instanceof Object
|
||
? argument instanceof Array
|
||
: Object.prototype.toString.call(argument) === "[object Array]";
|
||
}
|
||
// 7.2.3 IsCallable(argument)
|
||
// https://tc39.github.io/ecma262/#sec-iscallable
|
||
function IsCallable(argument) {
|
||
// NOTE: This is an approximation as we cannot check for [[Call]] internal method.
|
||
return typeof argument === "function";
|
||
}
|
||
// 7.2.4 IsConstructor(argument)
|
||
// https://tc39.github.io/ecma262/#sec-isconstructor
|
||
function IsConstructor(argument) {
|
||
// NOTE: This is an approximation as we cannot check for [[Construct]] internal method.
|
||
return typeof argument === "function";
|
||
}
|
||
// 7.2.7 IsPropertyKey(argument)
|
||
// https://tc39.github.io/ecma262/#sec-ispropertykey
|
||
function IsPropertyKey(argument) {
|
||
switch (Type(argument)) {
|
||
case 3 /* String */: return true;
|
||
case 4 /* Symbol */: return true;
|
||
default: return false;
|
||
}
|
||
}
|
||
// 7.3 Operations on Objects
|
||
// https://tc39.github.io/ecma262/#sec-operations-on-objects
|
||
// 7.3.9 GetMethod(V, P)
|
||
// https://tc39.github.io/ecma262/#sec-getmethod
|
||
function GetMethod(V, P) {
|
||
var func = V[P];
|
||
if (func === undefined || func === null)
|
||
return undefined;
|
||
if (!IsCallable(func))
|
||
throw new TypeError();
|
||
return func;
|
||
}
|
||
// 7.4 Operations on Iterator Objects
|
||
// https://tc39.github.io/ecma262/#sec-operations-on-iterator-objects
|
||
function GetIterator(obj) {
|
||
var method = GetMethod(obj, iteratorSymbol);
|
||
if (!IsCallable(method))
|
||
throw new TypeError(); // from Call
|
||
var iterator = method.call(obj);
|
||
if (!IsObject(iterator))
|
||
throw new TypeError();
|
||
return iterator;
|
||
}
|
||
// 7.4.4 IteratorValue(iterResult)
|
||
// https://tc39.github.io/ecma262/2016/#sec-iteratorvalue
|
||
function IteratorValue(iterResult) {
|
||
return iterResult.value;
|
||
}
|
||
// 7.4.5 IteratorStep(iterator)
|
||
// https://tc39.github.io/ecma262/#sec-iteratorstep
|
||
function IteratorStep(iterator) {
|
||
var result = iterator.next();
|
||
return result.done ? false : result;
|
||
}
|
||
// 7.4.6 IteratorClose(iterator, completion)
|
||
// https://tc39.github.io/ecma262/#sec-iteratorclose
|
||
function IteratorClose(iterator) {
|
||
var f = iterator["return"];
|
||
if (f)
|
||
f.call(iterator);
|
||
}
|
||
// 9.1 Ordinary Object Internal Methods and Internal Slots
|
||
// https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots
|
||
// 9.1.1.1 OrdinaryGetPrototypeOf(O)
|
||
// https://tc39.github.io/ecma262/#sec-ordinarygetprototypeof
|
||
function OrdinaryGetPrototypeOf(O) {
|
||
var proto = Object.getPrototypeOf(O);
|
||
if (typeof O !== "function" || O === functionPrototype)
|
||
return proto;
|
||
// TypeScript doesn't set __proto__ in ES5, as it's non-standard.
|
||
// Try to determine the superclass constructor. Compatible implementations
|
||
// must either set __proto__ on a subclass constructor to the superclass constructor,
|
||
// or ensure each class has a valid `constructor` property on its prototype that
|
||
// points back to the constructor.
|
||
// If this is not the same as Function.[[Prototype]], then this is definately inherited.
|
||
// This is the case when in ES6 or when using __proto__ in a compatible browser.
|
||
if (proto !== functionPrototype)
|
||
return proto;
|
||
// If the super prototype is Object.prototype, null, or undefined, then we cannot determine the heritage.
|
||
var prototype = O.prototype;
|
||
var prototypeProto = prototype && Object.getPrototypeOf(prototype);
|
||
if (prototypeProto == null || prototypeProto === Object.prototype)
|
||
return proto;
|
||
// If the constructor was not a function, then we cannot determine the heritage.
|
||
var constructor = prototypeProto.constructor;
|
||
if (typeof constructor !== "function")
|
||
return proto;
|
||
// If we have some kind of self-reference, then we cannot determine the heritage.
|
||
if (constructor === O)
|
||
return proto;
|
||
// we have a pretty good guess at the heritage.
|
||
return constructor;
|
||
}
|
||
// naive Map shim
|
||
function CreateMapPolyfill() {
|
||
var cacheSentinel = {};
|
||
var arraySentinel = [];
|
||
var MapIterator = /** @class */ (function () {
|
||
function MapIterator(keys, values, selector) {
|
||
this._index = 0;
|
||
this._keys = keys;
|
||
this._values = values;
|
||
this._selector = selector;
|
||
}
|
||
MapIterator.prototype["@@iterator"] = function () { return this; };
|
||
MapIterator.prototype[iteratorSymbol] = function () { return this; };
|
||
MapIterator.prototype.next = function () {
|
||
var index = this._index;
|
||
if (index >= 0 && index < this._keys.length) {
|
||
var result = this._selector(this._keys[index], this._values[index]);
|
||
if (index + 1 >= this._keys.length) {
|
||
this._index = -1;
|
||
this._keys = arraySentinel;
|
||
this._values = arraySentinel;
|
||
}
|
||
else {
|
||
this._index++;
|
||
}
|
||
return { value: result, done: false };
|
||
}
|
||
return { value: undefined, done: true };
|
||
};
|
||
MapIterator.prototype.throw = function (error) {
|
||
if (this._index >= 0) {
|
||
this._index = -1;
|
||
this._keys = arraySentinel;
|
||
this._values = arraySentinel;
|
||
}
|
||
throw error;
|
||
};
|
||
MapIterator.prototype.return = function (value) {
|
||
if (this._index >= 0) {
|
||
this._index = -1;
|
||
this._keys = arraySentinel;
|
||
this._values = arraySentinel;
|
||
}
|
||
return { value: value, done: true };
|
||
};
|
||
return MapIterator;
|
||
}());
|
||
return /** @class */ (function () {
|
||
function Map() {
|
||
this._keys = [];
|
||
this._values = [];
|
||
this._cacheKey = cacheSentinel;
|
||
this._cacheIndex = -2;
|
||
}
|
||
Object.defineProperty(Map.prototype, "size", {
|
||
get: function () { return this._keys.length; },
|
||
enumerable: true,
|
||
configurable: true
|
||
});
|
||
Map.prototype.has = function (key) { return this._find(key, /*insert*/ false) >= 0; };
|
||
Map.prototype.get = function (key) {
|
||
var index = this._find(key, /*insert*/ false);
|
||
return index >= 0 ? this._values[index] : undefined;
|
||
};
|
||
Map.prototype.set = function (key, value) {
|
||
var index = this._find(key, /*insert*/ true);
|
||
this._values[index] = value;
|
||
return this;
|
||
};
|
||
Map.prototype.delete = function (key) {
|
||
var index = this._find(key, /*insert*/ false);
|
||
if (index >= 0) {
|
||
var size = this._keys.length;
|
||
for (var i = index + 1; i < size; i++) {
|
||
this._keys[i - 1] = this._keys[i];
|
||
this._values[i - 1] = this._values[i];
|
||
}
|
||
this._keys.length--;
|
||
this._values.length--;
|
||
if (key === this._cacheKey) {
|
||
this._cacheKey = cacheSentinel;
|
||
this._cacheIndex = -2;
|
||
}
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
Map.prototype.clear = function () {
|
||
this._keys.length = 0;
|
||
this._values.length = 0;
|
||
this._cacheKey = cacheSentinel;
|
||
this._cacheIndex = -2;
|
||
};
|
||
Map.prototype.keys = function () { return new MapIterator(this._keys, this._values, getKey); };
|
||
Map.prototype.values = function () { return new MapIterator(this._keys, this._values, getValue); };
|
||
Map.prototype.entries = function () { return new MapIterator(this._keys, this._values, getEntry); };
|
||
Map.prototype["@@iterator"] = function () { return this.entries(); };
|
||
Map.prototype[iteratorSymbol] = function () { return this.entries(); };
|
||
Map.prototype._find = function (key, insert) {
|
||
if (this._cacheKey !== key) {
|
||
this._cacheIndex = this._keys.indexOf(this._cacheKey = key);
|
||
}
|
||
if (this._cacheIndex < 0 && insert) {
|
||
this._cacheIndex = this._keys.length;
|
||
this._keys.push(key);
|
||
this._values.push(undefined);
|
||
}
|
||
return this._cacheIndex;
|
||
};
|
||
return Map;
|
||
}());
|
||
function getKey(key, _) {
|
||
return key;
|
||
}
|
||
function getValue(_, value) {
|
||
return value;
|
||
}
|
||
function getEntry(key, value) {
|
||
return [key, value];
|
||
}
|
||
}
|
||
// naive Set shim
|
||
function CreateSetPolyfill() {
|
||
return /** @class */ (function () {
|
||
function Set() {
|
||
this._map = new _Map();
|
||
}
|
||
Object.defineProperty(Set.prototype, "size", {
|
||
get: function () { return this._map.size; },
|
||
enumerable: true,
|
||
configurable: true
|
||
});
|
||
Set.prototype.has = function (value) { return this._map.has(value); };
|
||
Set.prototype.add = function (value) { return this._map.set(value, value), this; };
|
||
Set.prototype.delete = function (value) { return this._map.delete(value); };
|
||
Set.prototype.clear = function () { this._map.clear(); };
|
||
Set.prototype.keys = function () { return this._map.keys(); };
|
||
Set.prototype.values = function () { return this._map.values(); };
|
||
Set.prototype.entries = function () { return this._map.entries(); };
|
||
Set.prototype["@@iterator"] = function () { return this.keys(); };
|
||
Set.prototype[iteratorSymbol] = function () { return this.keys(); };
|
||
return Set;
|
||
}());
|
||
}
|
||
// naive WeakMap shim
|
||
function CreateWeakMapPolyfill() {
|
||
var UUID_SIZE = 16;
|
||
var keys = HashMap.create();
|
||
var rootKey = CreateUniqueKey();
|
||
return /** @class */ (function () {
|
||
function WeakMap() {
|
||
this._key = CreateUniqueKey();
|
||
}
|
||
WeakMap.prototype.has = function (target) {
|
||
var table = GetOrCreateWeakMapTable(target, /*create*/ false);
|
||
return table !== undefined ? HashMap.has(table, this._key) : false;
|
||
};
|
||
WeakMap.prototype.get = function (target) {
|
||
var table = GetOrCreateWeakMapTable(target, /*create*/ false);
|
||
return table !== undefined ? HashMap.get(table, this._key) : undefined;
|
||
};
|
||
WeakMap.prototype.set = function (target, value) {
|
||
var table = GetOrCreateWeakMapTable(target, /*create*/ true);
|
||
table[this._key] = value;
|
||
return this;
|
||
};
|
||
WeakMap.prototype.delete = function (target) {
|
||
var table = GetOrCreateWeakMapTable(target, /*create*/ false);
|
||
return table !== undefined ? delete table[this._key] : false;
|
||
};
|
||
WeakMap.prototype.clear = function () {
|
||
// NOTE: not a real clear, just makes the previous data unreachable
|
||
this._key = CreateUniqueKey();
|
||
};
|
||
return WeakMap;
|
||
}());
|
||
function CreateUniqueKey() {
|
||
var key;
|
||
do
|
||
key = "@@WeakMap@@" + CreateUUID();
|
||
while (HashMap.has(keys, key));
|
||
keys[key] = true;
|
||
return key;
|
||
}
|
||
function GetOrCreateWeakMapTable(target, create) {
|
||
if (!hasOwn.call(target, rootKey)) {
|
||
if (!create)
|
||
return undefined;
|
||
Object.defineProperty(target, rootKey, { value: HashMap.create() });
|
||
}
|
||
return target[rootKey];
|
||
}
|
||
function FillRandomBytes(buffer, size) {
|
||
for (var i = 0; i < size; ++i)
|
||
buffer[i] = Math.random() * 0xff | 0;
|
||
return buffer;
|
||
}
|
||
function GenRandomBytes(size) {
|
||
if (typeof Uint8Array === "function") {
|
||
if (typeof crypto !== "undefined")
|
||
return crypto.getRandomValues(new Uint8Array(size));
|
||
if (typeof msCrypto !== "undefined")
|
||
return msCrypto.getRandomValues(new Uint8Array(size));
|
||
return FillRandomBytes(new Uint8Array(size), size);
|
||
}
|
||
return FillRandomBytes(new Array(size), size);
|
||
}
|
||
function CreateUUID() {
|
||
var data = GenRandomBytes(UUID_SIZE);
|
||
// mark as random - RFC 4122 § 4.4
|
||
data[6] = data[6] & 0x4f | 0x40;
|
||
data[8] = data[8] & 0xbf | 0x80;
|
||
var result = "";
|
||
for (var offset = 0; offset < UUID_SIZE; ++offset) {
|
||
var byte = data[offset];
|
||
if (offset === 4 || offset === 6 || offset === 8)
|
||
result += "-";
|
||
if (byte < 16)
|
||
result += "0";
|
||
result += byte.toString(16).toLowerCase();
|
||
}
|
||
return result;
|
||
}
|
||
}
|
||
// uses a heuristic used by v8 and chakra to force an object into dictionary mode.
|
||
function MakeDictionary(obj) {
|
||
obj.__ = undefined;
|
||
delete obj.__;
|
||
return obj;
|
||
}
|
||
});
|
||
})(Reflect || (Reflect = {}));
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/semver-compare/index.js":
|
||
/*!**********************************************!*\
|
||
!*** ./node_modules/semver-compare/index.js ***!
|
||
\**********************************************/
|
||
/***/ ((module) => {
|
||
|
||
module.exports = function cmp (a, b) {
|
||
var pa = a.split('.');
|
||
var pb = b.split('.');
|
||
for (var i = 0; i < 3; i++) {
|
||
var na = Number(pa[i]);
|
||
var nb = Number(pb[i]);
|
||
if (na > nb) return 1;
|
||
if (nb > na) return -1;
|
||
if (!isNaN(na) && isNaN(nb)) return 1;
|
||
if (isNaN(na) && !isNaN(nb)) return -1;
|
||
}
|
||
return 0;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/semver/semver.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/semver/semver.js ***!
|
||
\***************************************/
|
||
/***/ ((module, exports) => {
|
||
|
||
exports = module.exports = SemVer
|
||
|
||
var debug
|
||
/* istanbul ignore next */
|
||
if (typeof process === 'object' &&
|
||
process.env &&
|
||
process.env.NODE_DEBUG &&
|
||
/\bsemver\b/i.test(process.env.NODE_DEBUG)) {
|
||
debug = function () {
|
||
var args = Array.prototype.slice.call(arguments, 0)
|
||
args.unshift('SEMVER')
|
||
console.log.apply(console, args)
|
||
}
|
||
} else {
|
||
debug = function () {}
|
||
}
|
||
|
||
// Note: this is the semver.org version of the spec that it implements
|
||
// Not necessarily the package version of this code.
|
||
exports.SEMVER_SPEC_VERSION = '2.0.0'
|
||
|
||
var MAX_LENGTH = 256
|
||
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
|
||
/* istanbul ignore next */ 9007199254740991
|
||
|
||
// Max safe segment length for coercion.
|
||
var MAX_SAFE_COMPONENT_LENGTH = 16
|
||
|
||
// The actual regexps go on exports.re
|
||
var re = exports.re = []
|
||
var src = exports.src = []
|
||
var R = 0
|
||
|
||
// The following Regular Expressions can be used for tokenizing,
|
||
// validating, and parsing SemVer version strings.
|
||
|
||
// ## Numeric Identifier
|
||
// A single `0`, or a non-zero digit followed by zero or more digits.
|
||
|
||
var NUMERICIDENTIFIER = R++
|
||
src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'
|
||
var NUMERICIDENTIFIERLOOSE = R++
|
||
src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'
|
||
|
||
// ## Non-numeric Identifier
|
||
// Zero or more digits, followed by a letter or hyphen, and then zero or
|
||
// more letters, digits, or hyphens.
|
||
|
||
var NONNUMERICIDENTIFIER = R++
|
||
src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'
|
||
|
||
// ## Main Version
|
||
// Three dot-separated numeric identifiers.
|
||
|
||
var MAINVERSION = R++
|
||
src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' +
|
||
'(' + src[NUMERICIDENTIFIER] + ')\\.' +
|
||
'(' + src[NUMERICIDENTIFIER] + ')'
|
||
|
||
var MAINVERSIONLOOSE = R++
|
||
src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
|
||
'(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
|
||
'(' + src[NUMERICIDENTIFIERLOOSE] + ')'
|
||
|
||
// ## Pre-release Version Identifier
|
||
// A numeric identifier, or a non-numeric identifier.
|
||
|
||
var PRERELEASEIDENTIFIER = R++
|
||
src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] +
|
||
'|' + src[NONNUMERICIDENTIFIER] + ')'
|
||
|
||
var PRERELEASEIDENTIFIERLOOSE = R++
|
||
src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] +
|
||
'|' + src[NONNUMERICIDENTIFIER] + ')'
|
||
|
||
// ## Pre-release Version
|
||
// Hyphen, followed by one or more dot-separated pre-release version
|
||
// identifiers.
|
||
|
||
var PRERELEASE = R++
|
||
src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] +
|
||
'(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'
|
||
|
||
var PRERELEASELOOSE = R++
|
||
src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] +
|
||
'(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'
|
||
|
||
// ## Build Metadata Identifier
|
||
// Any combination of digits, letters, or hyphens.
|
||
|
||
var BUILDIDENTIFIER = R++
|
||
src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'
|
||
|
||
// ## Build Metadata
|
||
// Plus sign, followed by one or more period-separated build metadata
|
||
// identifiers.
|
||
|
||
var BUILD = R++
|
||
src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
|
||
'(?:\\.' + src[BUILDIDENTIFIER] + ')*))'
|
||
|
||
// ## Full Version String
|
||
// A main version, followed optionally by a pre-release version and
|
||
// build metadata.
|
||
|
||
// Note that the only major, minor, patch, and pre-release sections of
|
||
// the version string are capturing groups. The build metadata is not a
|
||
// capturing group, because it should not ever be used in version
|
||
// comparison.
|
||
|
||
var FULL = R++
|
||
var FULLPLAIN = 'v?' + src[MAINVERSION] +
|
||
src[PRERELEASE] + '?' +
|
||
src[BUILD] + '?'
|
||
|
||
src[FULL] = '^' + FULLPLAIN + '$'
|
||
|
||
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
|
||
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
|
||
// common in the npm registry.
|
||
var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] +
|
||
src[PRERELEASELOOSE] + '?' +
|
||
src[BUILD] + '?'
|
||
|
||
var LOOSE = R++
|
||
src[LOOSE] = '^' + LOOSEPLAIN + '$'
|
||
|
||
var GTLT = R++
|
||
src[GTLT] = '((?:<|>)?=?)'
|
||
|
||
// Something like "2.*" or "1.2.x".
|
||
// Note that "x.x" is a valid xRange identifer, meaning "any version"
|
||
// Only the first item is strictly required.
|
||
var XRANGEIDENTIFIERLOOSE = R++
|
||
src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'
|
||
var XRANGEIDENTIFIER = R++
|
||
src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'
|
||
|
||
var XRANGEPLAIN = R++
|
||
src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' +
|
||
'(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
|
||
'(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
|
||
'(?:' + src[PRERELEASE] + ')?' +
|
||
src[BUILD] + '?' +
|
||
')?)?'
|
||
|
||
var XRANGEPLAINLOOSE = R++
|
||
src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
|
||
'(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
|
||
'(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
|
||
'(?:' + src[PRERELEASELOOSE] + ')?' +
|
||
src[BUILD] + '?' +
|
||
')?)?'
|
||
|
||
var XRANGE = R++
|
||
src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'
|
||
var XRANGELOOSE = R++
|
||
src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'
|
||
|
||
// Coercion.
|
||
// Extract anything that could conceivably be a part of a valid semver
|
||
var COERCE = R++
|
||
src[COERCE] = '(?:^|[^\\d])' +
|
||
'(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' +
|
||
'(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
|
||
'(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
|
||
'(?:$|[^\\d])'
|
||
|
||
// Tilde ranges.
|
||
// Meaning is "reasonably at or greater than"
|
||
var LONETILDE = R++
|
||
src[LONETILDE] = '(?:~>?)'
|
||
|
||
var TILDETRIM = R++
|
||
src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'
|
||
re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g')
|
||
var tildeTrimReplace = '$1~'
|
||
|
||
var TILDE = R++
|
||
src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'
|
||
var TILDELOOSE = R++
|
||
src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'
|
||
|
||
// Caret ranges.
|
||
// Meaning is "at least and backwards compatible with"
|
||
var LONECARET = R++
|
||
src[LONECARET] = '(?:\\^)'
|
||
|
||
var CARETTRIM = R++
|
||
src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'
|
||
re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g')
|
||
var caretTrimReplace = '$1^'
|
||
|
||
var CARET = R++
|
||
src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'
|
||
var CARETLOOSE = R++
|
||
src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'
|
||
|
||
// A simple gt/lt/eq thing, or just "" to indicate "any version"
|
||
var COMPARATORLOOSE = R++
|
||
src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'
|
||
var COMPARATOR = R++
|
||
src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'
|
||
|
||
// An expression to strip any whitespace between the gtlt and the thing
|
||
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
|
||
var COMPARATORTRIM = R++
|
||
src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] +
|
||
'\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'
|
||
|
||
// this one has to use the /g flag
|
||
re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g')
|
||
var comparatorTrimReplace = '$1$2$3'
|
||
|
||
// Something like `1.2.3 - 1.2.4`
|
||
// Note that these all use the loose form, because they'll be
|
||
// checked against either the strict or loose comparator form
|
||
// later.
|
||
var HYPHENRANGE = R++
|
||
src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' +
|
||
'\\s+-\\s+' +
|
||
'(' + src[XRANGEPLAIN] + ')' +
|
||
'\\s*$'
|
||
|
||
var HYPHENRANGELOOSE = R++
|
||
src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' +
|
||
'\\s+-\\s+' +
|
||
'(' + src[XRANGEPLAINLOOSE] + ')' +
|
||
'\\s*$'
|
||
|
||
// Star ranges basically just allow anything at all.
|
||
var STAR = R++
|
||
src[STAR] = '(<|>)?=?\\s*\\*'
|
||
|
||
// Compile to actual regexp objects.
|
||
// All are flag-free, unless they were created above with a flag.
|
||
for (var i = 0; i < R; i++) {
|
||
debug(i, src[i])
|
||
if (!re[i]) {
|
||
re[i] = new RegExp(src[i])
|
||
}
|
||
}
|
||
|
||
exports.parse = parse
|
||
function parse (version, options) {
|
||
if (!options || typeof options !== 'object') {
|
||
options = {
|
||
loose: !!options,
|
||
includePrerelease: false
|
||
}
|
||
}
|
||
|
||
if (version instanceof SemVer) {
|
||
return version
|
||
}
|
||
|
||
if (typeof version !== 'string') {
|
||
return null
|
||
}
|
||
|
||
if (version.length > MAX_LENGTH) {
|
||
return null
|
||
}
|
||
|
||
var r = options.loose ? re[LOOSE] : re[FULL]
|
||
if (!r.test(version)) {
|
||
return null
|
||
}
|
||
|
||
try {
|
||
return new SemVer(version, options)
|
||
} catch (er) {
|
||
return null
|
||
}
|
||
}
|
||
|
||
exports.valid = valid
|
||
function valid (version, options) {
|
||
var v = parse(version, options)
|
||
return v ? v.version : null
|
||
}
|
||
|
||
exports.clean = clean
|
||
function clean (version, options) {
|
||
var s = parse(version.trim().replace(/^[=v]+/, ''), options)
|
||
return s ? s.version : null
|
||
}
|
||
|
||
exports.SemVer = SemVer
|
||
|
||
function SemVer (version, options) {
|
||
if (!options || typeof options !== 'object') {
|
||
options = {
|
||
loose: !!options,
|
||
includePrerelease: false
|
||
}
|
||
}
|
||
if (version instanceof SemVer) {
|
||
if (version.loose === options.loose) {
|
||
return version
|
||
} else {
|
||
version = version.version
|
||
}
|
||
} else if (typeof version !== 'string') {
|
||
throw new TypeError('Invalid Version: ' + version)
|
||
}
|
||
|
||
if (version.length > MAX_LENGTH) {
|
||
throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters')
|
||
}
|
||
|
||
if (!(this instanceof SemVer)) {
|
||
return new SemVer(version, options)
|
||
}
|
||
|
||
debug('SemVer', version, options)
|
||
this.options = options
|
||
this.loose = !!options.loose
|
||
|
||
var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL])
|
||
|
||
if (!m) {
|
||
throw new TypeError('Invalid Version: ' + version)
|
||
}
|
||
|
||
this.raw = version
|
||
|
||
// these are actually numbers
|
||
this.major = +m[1]
|
||
this.minor = +m[2]
|
||
this.patch = +m[3]
|
||
|
||
if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
|
||
throw new TypeError('Invalid major version')
|
||
}
|
||
|
||
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
|
||
throw new TypeError('Invalid minor version')
|
||
}
|
||
|
||
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
|
||
throw new TypeError('Invalid patch version')
|
||
}
|
||
|
||
// numberify any prerelease numeric ids
|
||
if (!m[4]) {
|
||
this.prerelease = []
|
||
} else {
|
||
this.prerelease = m[4].split('.').map(function (id) {
|
||
if (/^[0-9]+$/.test(id)) {
|
||
var num = +id
|
||
if (num >= 0 && num < MAX_SAFE_INTEGER) {
|
||
return num
|
||
}
|
||
}
|
||
return id
|
||
})
|
||
}
|
||
|
||
this.build = m[5] ? m[5].split('.') : []
|
||
this.format()
|
||
}
|
||
|
||
SemVer.prototype.format = function () {
|
||
this.version = this.major + '.' + this.minor + '.' + this.patch
|
||
if (this.prerelease.length) {
|
||
this.version += '-' + this.prerelease.join('.')
|
||
}
|
||
return this.version
|
||
}
|
||
|
||
SemVer.prototype.toString = function () {
|
||
return this.version
|
||
}
|
||
|
||
SemVer.prototype.compare = function (other) {
|
||
debug('SemVer.compare', this.version, this.options, other)
|
||
if (!(other instanceof SemVer)) {
|
||
other = new SemVer(other, this.options)
|
||
}
|
||
|
||
return this.compareMain(other) || this.comparePre(other)
|
||
}
|
||
|
||
SemVer.prototype.compareMain = function (other) {
|
||
if (!(other instanceof SemVer)) {
|
||
other = new SemVer(other, this.options)
|
||
}
|
||
|
||
return compareIdentifiers(this.major, other.major) ||
|
||
compareIdentifiers(this.minor, other.minor) ||
|
||
compareIdentifiers(this.patch, other.patch)
|
||
}
|
||
|
||
SemVer.prototype.comparePre = function (other) {
|
||
if (!(other instanceof SemVer)) {
|
||
other = new SemVer(other, this.options)
|
||
}
|
||
|
||
// NOT having a prerelease is > having one
|
||
if (this.prerelease.length && !other.prerelease.length) {
|
||
return -1
|
||
} else if (!this.prerelease.length && other.prerelease.length) {
|
||
return 1
|
||
} else if (!this.prerelease.length && !other.prerelease.length) {
|
||
return 0
|
||
}
|
||
|
||
var i = 0
|
||
do {
|
||
var a = this.prerelease[i]
|
||
var b = other.prerelease[i]
|
||
debug('prerelease compare', i, a, b)
|
||
if (a === undefined && b === undefined) {
|
||
return 0
|
||
} else if (b === undefined) {
|
||
return 1
|
||
} else if (a === undefined) {
|
||
return -1
|
||
} else if (a === b) {
|
||
continue
|
||
} else {
|
||
return compareIdentifiers(a, b)
|
||
}
|
||
} while (++i)
|
||
}
|
||
|
||
// preminor will bump the version up to the next minor release, and immediately
|
||
// down to pre-release. premajor and prepatch work the same way.
|
||
SemVer.prototype.inc = function (release, identifier) {
|
||
switch (release) {
|
||
case 'premajor':
|
||
this.prerelease.length = 0
|
||
this.patch = 0
|
||
this.minor = 0
|
||
this.major++
|
||
this.inc('pre', identifier)
|
||
break
|
||
case 'preminor':
|
||
this.prerelease.length = 0
|
||
this.patch = 0
|
||
this.minor++
|
||
this.inc('pre', identifier)
|
||
break
|
||
case 'prepatch':
|
||
// If this is already a prerelease, it will bump to the next version
|
||
// drop any prereleases that might already exist, since they are not
|
||
// relevant at this point.
|
||
this.prerelease.length = 0
|
||
this.inc('patch', identifier)
|
||
this.inc('pre', identifier)
|
||
break
|
||
// If the input is a non-prerelease version, this acts the same as
|
||
// prepatch.
|
||
case 'prerelease':
|
||
if (this.prerelease.length === 0) {
|
||
this.inc('patch', identifier)
|
||
}
|
||
this.inc('pre', identifier)
|
||
break
|
||
|
||
case 'major':
|
||
// If this is a pre-major version, bump up to the same major version.
|
||
// Otherwise increment major.
|
||
// 1.0.0-5 bumps to 1.0.0
|
||
// 1.1.0 bumps to 2.0.0
|
||
if (this.minor !== 0 ||
|
||
this.patch !== 0 ||
|
||
this.prerelease.length === 0) {
|
||
this.major++
|
||
}
|
||
this.minor = 0
|
||
this.patch = 0
|
||
this.prerelease = []
|
||
break
|
||
case 'minor':
|
||
// If this is a pre-minor version, bump up to the same minor version.
|
||
// Otherwise increment minor.
|
||
// 1.2.0-5 bumps to 1.2.0
|
||
// 1.2.1 bumps to 1.3.0
|
||
if (this.patch !== 0 || this.prerelease.length === 0) {
|
||
this.minor++
|
||
}
|
||
this.patch = 0
|
||
this.prerelease = []
|
||
break
|
||
case 'patch':
|
||
// If this is not a pre-release version, it will increment the patch.
|
||
// If it is a pre-release it will bump up to the same patch version.
|
||
// 1.2.0-5 patches to 1.2.0
|
||
// 1.2.0 patches to 1.2.1
|
||
if (this.prerelease.length === 0) {
|
||
this.patch++
|
||
}
|
||
this.prerelease = []
|
||
break
|
||
// This probably shouldn't be used publicly.
|
||
// 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
|
||
case 'pre':
|
||
if (this.prerelease.length === 0) {
|
||
this.prerelease = [0]
|
||
} else {
|
||
var i = this.prerelease.length
|
||
while (--i >= 0) {
|
||
if (typeof this.prerelease[i] === 'number') {
|
||
this.prerelease[i]++
|
||
i = -2
|
||
}
|
||
}
|
||
if (i === -1) {
|
||
// didn't increment anything
|
||
this.prerelease.push(0)
|
||
}
|
||
}
|
||
if (identifier) {
|
||
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
|
||
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
|
||
if (this.prerelease[0] === identifier) {
|
||
if (isNaN(this.prerelease[1])) {
|
||
this.prerelease = [identifier, 0]
|
||
}
|
||
} else {
|
||
this.prerelease = [identifier, 0]
|
||
}
|
||
}
|
||
break
|
||
|
||
default:
|
||
throw new Error('invalid increment argument: ' + release)
|
||
}
|
||
this.format()
|
||
this.raw = this.version
|
||
return this
|
||
}
|
||
|
||
exports.inc = inc
|
||
function inc (version, release, loose, identifier) {
|
||
if (typeof (loose) === 'string') {
|
||
identifier = loose
|
||
loose = undefined
|
||
}
|
||
|
||
try {
|
||
return new SemVer(version, loose).inc(release, identifier).version
|
||
} catch (er) {
|
||
return null
|
||
}
|
||
}
|
||
|
||
exports.diff = diff
|
||
function diff (version1, version2) {
|
||
if (eq(version1, version2)) {
|
||
return null
|
||
} else {
|
||
var v1 = parse(version1)
|
||
var v2 = parse(version2)
|
||
var prefix = ''
|
||
if (v1.prerelease.length || v2.prerelease.length) {
|
||
prefix = 'pre'
|
||
var defaultResult = 'prerelease'
|
||
}
|
||
for (var key in v1) {
|
||
if (key === 'major' || key === 'minor' || key === 'patch') {
|
||
if (v1[key] !== v2[key]) {
|
||
return prefix + key
|
||
}
|
||
}
|
||
}
|
||
return defaultResult // may be undefined
|
||
}
|
||
}
|
||
|
||
exports.compareIdentifiers = compareIdentifiers
|
||
|
||
var numeric = /^[0-9]+$/
|
||
function compareIdentifiers (a, b) {
|
||
var anum = numeric.test(a)
|
||
var bnum = numeric.test(b)
|
||
|
||
if (anum && bnum) {
|
||
a = +a
|
||
b = +b
|
||
}
|
||
|
||
return a === b ? 0
|
||
: (anum && !bnum) ? -1
|
||
: (bnum && !anum) ? 1
|
||
: a < b ? -1
|
||
: 1
|
||
}
|
||
|
||
exports.rcompareIdentifiers = rcompareIdentifiers
|
||
function rcompareIdentifiers (a, b) {
|
||
return compareIdentifiers(b, a)
|
||
}
|
||
|
||
exports.major = major
|
||
function major (a, loose) {
|
||
return new SemVer(a, loose).major
|
||
}
|
||
|
||
exports.minor = minor
|
||
function minor (a, loose) {
|
||
return new SemVer(a, loose).minor
|
||
}
|
||
|
||
exports.patch = patch
|
||
function patch (a, loose) {
|
||
return new SemVer(a, loose).patch
|
||
}
|
||
|
||
exports.compare = compare
|
||
function compare (a, b, loose) {
|
||
return new SemVer(a, loose).compare(new SemVer(b, loose))
|
||
}
|
||
|
||
exports.compareLoose = compareLoose
|
||
function compareLoose (a, b) {
|
||
return compare(a, b, true)
|
||
}
|
||
|
||
exports.rcompare = rcompare
|
||
function rcompare (a, b, loose) {
|
||
return compare(b, a, loose)
|
||
}
|
||
|
||
exports.sort = sort
|
||
function sort (list, loose) {
|
||
return list.sort(function (a, b) {
|
||
return exports.compare(a, b, loose)
|
||
})
|
||
}
|
||
|
||
exports.rsort = rsort
|
||
function rsort (list, loose) {
|
||
return list.sort(function (a, b) {
|
||
return exports.rcompare(a, b, loose)
|
||
})
|
||
}
|
||
|
||
exports.gt = gt
|
||
function gt (a, b, loose) {
|
||
return compare(a, b, loose) > 0
|
||
}
|
||
|
||
exports.lt = lt
|
||
function lt (a, b, loose) {
|
||
return compare(a, b, loose) < 0
|
||
}
|
||
|
||
exports.eq = eq
|
||
function eq (a, b, loose) {
|
||
return compare(a, b, loose) === 0
|
||
}
|
||
|
||
exports.neq = neq
|
||
function neq (a, b, loose) {
|
||
return compare(a, b, loose) !== 0
|
||
}
|
||
|
||
exports.gte = gte
|
||
function gte (a, b, loose) {
|
||
return compare(a, b, loose) >= 0
|
||
}
|
||
|
||
exports.lte = lte
|
||
function lte (a, b, loose) {
|
||
return compare(a, b, loose) <= 0
|
||
}
|
||
|
||
exports.cmp = cmp
|
||
function cmp (a, op, b, loose) {
|
||
switch (op) {
|
||
case '===':
|
||
if (typeof a === 'object')
|
||
a = a.version
|
||
if (typeof b === 'object')
|
||
b = b.version
|
||
return a === b
|
||
|
||
case '!==':
|
||
if (typeof a === 'object')
|
||
a = a.version
|
||
if (typeof b === 'object')
|
||
b = b.version
|
||
return a !== b
|
||
|
||
case '':
|
||
case '=':
|
||
case '==':
|
||
return eq(a, b, loose)
|
||
|
||
case '!=':
|
||
return neq(a, b, loose)
|
||
|
||
case '>':
|
||
return gt(a, b, loose)
|
||
|
||
case '>=':
|
||
return gte(a, b, loose)
|
||
|
||
case '<':
|
||
return lt(a, b, loose)
|
||
|
||
case '<=':
|
||
return lte(a, b, loose)
|
||
|
||
default:
|
||
throw new TypeError('Invalid operator: ' + op)
|
||
}
|
||
}
|
||
|
||
exports.Comparator = Comparator
|
||
function Comparator (comp, options) {
|
||
if (!options || typeof options !== 'object') {
|
||
options = {
|
||
loose: !!options,
|
||
includePrerelease: false
|
||
}
|
||
}
|
||
|
||
if (comp instanceof Comparator) {
|
||
if (comp.loose === !!options.loose) {
|
||
return comp
|
||
} else {
|
||
comp = comp.value
|
||
}
|
||
}
|
||
|
||
if (!(this instanceof Comparator)) {
|
||
return new Comparator(comp, options)
|
||
}
|
||
|
||
debug('comparator', comp, options)
|
||
this.options = options
|
||
this.loose = !!options.loose
|
||
this.parse(comp)
|
||
|
||
if (this.semver === ANY) {
|
||
this.value = ''
|
||
} else {
|
||
this.value = this.operator + this.semver.version
|
||
}
|
||
|
||
debug('comp', this)
|
||
}
|
||
|
||
var ANY = {}
|
||
Comparator.prototype.parse = function (comp) {
|
||
var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]
|
||
var m = comp.match(r)
|
||
|
||
if (!m) {
|
||
throw new TypeError('Invalid comparator: ' + comp)
|
||
}
|
||
|
||
this.operator = m[1]
|
||
if (this.operator === '=') {
|
||
this.operator = ''
|
||
}
|
||
|
||
// if it literally is just '>' or '' then allow anything.
|
||
if (!m[2]) {
|
||
this.semver = ANY
|
||
} else {
|
||
this.semver = new SemVer(m[2], this.options.loose)
|
||
}
|
||
}
|
||
|
||
Comparator.prototype.toString = function () {
|
||
return this.value
|
||
}
|
||
|
||
Comparator.prototype.test = function (version) {
|
||
debug('Comparator.test', version, this.options.loose)
|
||
|
||
if (this.semver === ANY) {
|
||
return true
|
||
}
|
||
|
||
if (typeof version === 'string') {
|
||
version = new SemVer(version, this.options)
|
||
}
|
||
|
||
return cmp(version, this.operator, this.semver, this.options)
|
||
}
|
||
|
||
Comparator.prototype.intersects = function (comp, options) {
|
||
if (!(comp instanceof Comparator)) {
|
||
throw new TypeError('a Comparator is required')
|
||
}
|
||
|
||
if (!options || typeof options !== 'object') {
|
||
options = {
|
||
loose: !!options,
|
||
includePrerelease: false
|
||
}
|
||
}
|
||
|
||
var rangeTmp
|
||
|
||
if (this.operator === '') {
|
||
rangeTmp = new Range(comp.value, options)
|
||
return satisfies(this.value, rangeTmp, options)
|
||
} else if (comp.operator === '') {
|
||
rangeTmp = new Range(this.value, options)
|
||
return satisfies(comp.semver, rangeTmp, options)
|
||
}
|
||
|
||
var sameDirectionIncreasing =
|
||
(this.operator === '>=' || this.operator === '>') &&
|
||
(comp.operator === '>=' || comp.operator === '>')
|
||
var sameDirectionDecreasing =
|
||
(this.operator === '<=' || this.operator === '<') &&
|
||
(comp.operator === '<=' || comp.operator === '<')
|
||
var sameSemVer = this.semver.version === comp.semver.version
|
||
var differentDirectionsInclusive =
|
||
(this.operator === '>=' || this.operator === '<=') &&
|
||
(comp.operator === '>=' || comp.operator === '<=')
|
||
var oppositeDirectionsLessThan =
|
||
cmp(this.semver, '<', comp.semver, options) &&
|
||
((this.operator === '>=' || this.operator === '>') &&
|
||
(comp.operator === '<=' || comp.operator === '<'))
|
||
var oppositeDirectionsGreaterThan =
|
||
cmp(this.semver, '>', comp.semver, options) &&
|
||
((this.operator === '<=' || this.operator === '<') &&
|
||
(comp.operator === '>=' || comp.operator === '>'))
|
||
|
||
return sameDirectionIncreasing || sameDirectionDecreasing ||
|
||
(sameSemVer && differentDirectionsInclusive) ||
|
||
oppositeDirectionsLessThan || oppositeDirectionsGreaterThan
|
||
}
|
||
|
||
exports.Range = Range
|
||
function Range (range, options) {
|
||
if (!options || typeof options !== 'object') {
|
||
options = {
|
||
loose: !!options,
|
||
includePrerelease: false
|
||
}
|
||
}
|
||
|
||
if (range instanceof Range) {
|
||
if (range.loose === !!options.loose &&
|
||
range.includePrerelease === !!options.includePrerelease) {
|
||
return range
|
||
} else {
|
||
return new Range(range.raw, options)
|
||
}
|
||
}
|
||
|
||
if (range instanceof Comparator) {
|
||
return new Range(range.value, options)
|
||
}
|
||
|
||
if (!(this instanceof Range)) {
|
||
return new Range(range, options)
|
||
}
|
||
|
||
this.options = options
|
||
this.loose = !!options.loose
|
||
this.includePrerelease = !!options.includePrerelease
|
||
|
||
// First, split based on boolean or ||
|
||
this.raw = range
|
||
this.set = range.split(/\s*\|\|\s*/).map(function (range) {
|
||
return this.parseRange(range.trim())
|
||
}, this).filter(function (c) {
|
||
// throw out any that are not relevant for whatever reason
|
||
return c.length
|
||
})
|
||
|
||
if (!this.set.length) {
|
||
throw new TypeError('Invalid SemVer Range: ' + range)
|
||
}
|
||
|
||
this.format()
|
||
}
|
||
|
||
Range.prototype.format = function () {
|
||
this.range = this.set.map(function (comps) {
|
||
return comps.join(' ').trim()
|
||
}).join('||').trim()
|
||
return this.range
|
||
}
|
||
|
||
Range.prototype.toString = function () {
|
||
return this.range
|
||
}
|
||
|
||
Range.prototype.parseRange = function (range) {
|
||
var loose = this.options.loose
|
||
range = range.trim()
|
||
// `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
|
||
var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]
|
||
range = range.replace(hr, hyphenReplace)
|
||
debug('hyphen replace', range)
|
||
// `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
|
||
range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace)
|
||
debug('comparator trim', range, re[COMPARATORTRIM])
|
||
|
||
// `~ 1.2.3` => `~1.2.3`
|
||
range = range.replace(re[TILDETRIM], tildeTrimReplace)
|
||
|
||
// `^ 1.2.3` => `^1.2.3`
|
||
range = range.replace(re[CARETTRIM], caretTrimReplace)
|
||
|
||
// normalize spaces
|
||
range = range.split(/\s+/).join(' ')
|
||
|
||
// At this point, the range is completely trimmed and
|
||
// ready to be split into comparators.
|
||
|
||
var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]
|
||
var set = range.split(' ').map(function (comp) {
|
||
return parseComparator(comp, this.options)
|
||
}, this).join(' ').split(/\s+/)
|
||
if (this.options.loose) {
|
||
// in loose mode, throw out any that are not valid comparators
|
||
set = set.filter(function (comp) {
|
||
return !!comp.match(compRe)
|
||
})
|
||
}
|
||
set = set.map(function (comp) {
|
||
return new Comparator(comp, this.options)
|
||
}, this)
|
||
|
||
return set
|
||
}
|
||
|
||
Range.prototype.intersects = function (range, options) {
|
||
if (!(range instanceof Range)) {
|
||
throw new TypeError('a Range is required')
|
||
}
|
||
|
||
return this.set.some(function (thisComparators) {
|
||
return thisComparators.every(function (thisComparator) {
|
||
return range.set.some(function (rangeComparators) {
|
||
return rangeComparators.every(function (rangeComparator) {
|
||
return thisComparator.intersects(rangeComparator, options)
|
||
})
|
||
})
|
||
})
|
||
})
|
||
}
|
||
|
||
// Mostly just for testing and legacy API reasons
|
||
exports.toComparators = toComparators
|
||
function toComparators (range, options) {
|
||
return new Range(range, options).set.map(function (comp) {
|
||
return comp.map(function (c) {
|
||
return c.value
|
||
}).join(' ').trim().split(' ')
|
||
})
|
||
}
|
||
|
||
// comprised of xranges, tildes, stars, and gtlt's at this point.
|
||
// already replaced the hyphen ranges
|
||
// turn into a set of JUST comparators.
|
||
function parseComparator (comp, options) {
|
||
debug('comp', comp, options)
|
||
comp = replaceCarets(comp, options)
|
||
debug('caret', comp)
|
||
comp = replaceTildes(comp, options)
|
||
debug('tildes', comp)
|
||
comp = replaceXRanges(comp, options)
|
||
debug('xrange', comp)
|
||
comp = replaceStars(comp, options)
|
||
debug('stars', comp)
|
||
return comp
|
||
}
|
||
|
||
function isX (id) {
|
||
return !id || id.toLowerCase() === 'x' || id === '*'
|
||
}
|
||
|
||
// ~, ~> --> * (any, kinda silly)
|
||
// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
|
||
// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
|
||
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
|
||
// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
|
||
// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
|
||
function replaceTildes (comp, options) {
|
||
return comp.trim().split(/\s+/).map(function (comp) {
|
||
return replaceTilde(comp, options)
|
||
}).join(' ')
|
||
}
|
||
|
||
function replaceTilde (comp, options) {
|
||
var r = options.loose ? re[TILDELOOSE] : re[TILDE]
|
||
return comp.replace(r, function (_, M, m, p, pr) {
|
||
debug('tilde', comp, _, M, m, p, pr)
|
||
var ret
|
||
|
||
if (isX(M)) {
|
||
ret = ''
|
||
} else if (isX(m)) {
|
||
ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'
|
||
} else if (isX(p)) {
|
||
// ~1.2 == >=1.2.0 <1.3.0
|
||
ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'
|
||
} else if (pr) {
|
||
debug('replaceTilde pr', pr)
|
||
ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
|
||
' <' + M + '.' + (+m + 1) + '.0'
|
||
} else {
|
||
// ~1.2.3 == >=1.2.3 <1.3.0
|
||
ret = '>=' + M + '.' + m + '.' + p +
|
||
' <' + M + '.' + (+m + 1) + '.0'
|
||
}
|
||
|
||
debug('tilde return', ret)
|
||
return ret
|
||
})
|
||
}
|
||
|
||
// ^ --> * (any, kinda silly)
|
||
// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
|
||
// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
|
||
// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
|
||
// ^1.2.3 --> >=1.2.3 <2.0.0
|
||
// ^1.2.0 --> >=1.2.0 <2.0.0
|
||
function replaceCarets (comp, options) {
|
||
return comp.trim().split(/\s+/).map(function (comp) {
|
||
return replaceCaret(comp, options)
|
||
}).join(' ')
|
||
}
|
||
|
||
function replaceCaret (comp, options) {
|
||
debug('caret', comp, options)
|
||
var r = options.loose ? re[CARETLOOSE] : re[CARET]
|
||
return comp.replace(r, function (_, M, m, p, pr) {
|
||
debug('caret', comp, _, M, m, p, pr)
|
||
var ret
|
||
|
||
if (isX(M)) {
|
||
ret = ''
|
||
} else if (isX(m)) {
|
||
ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'
|
||
} else if (isX(p)) {
|
||
if (M === '0') {
|
||
ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'
|
||
} else {
|
||
ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'
|
||
}
|
||
} else if (pr) {
|
||
debug('replaceCaret pr', pr)
|
||
if (M === '0') {
|
||
if (m === '0') {
|
||
ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
|
||
' <' + M + '.' + m + '.' + (+p + 1)
|
||
} else {
|
||
ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
|
||
' <' + M + '.' + (+m + 1) + '.0'
|
||
}
|
||
} else {
|
||
ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
|
||
' <' + (+M + 1) + '.0.0'
|
||
}
|
||
} else {
|
||
debug('no pr')
|
||
if (M === '0') {
|
||
if (m === '0') {
|
||
ret = '>=' + M + '.' + m + '.' + p +
|
||
' <' + M + '.' + m + '.' + (+p + 1)
|
||
} else {
|
||
ret = '>=' + M + '.' + m + '.' + p +
|
||
' <' + M + '.' + (+m + 1) + '.0'
|
||
}
|
||
} else {
|
||
ret = '>=' + M + '.' + m + '.' + p +
|
||
' <' + (+M + 1) + '.0.0'
|
||
}
|
||
}
|
||
|
||
debug('caret return', ret)
|
||
return ret
|
||
})
|
||
}
|
||
|
||
function replaceXRanges (comp, options) {
|
||
debug('replaceXRanges', comp, options)
|
||
return comp.split(/\s+/).map(function (comp) {
|
||
return replaceXRange(comp, options)
|
||
}).join(' ')
|
||
}
|
||
|
||
function replaceXRange (comp, options) {
|
||
comp = comp.trim()
|
||
var r = options.loose ? re[XRANGELOOSE] : re[XRANGE]
|
||
return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
|
||
debug('xRange', comp, ret, gtlt, M, m, p, pr)
|
||
var xM = isX(M)
|
||
var xm = xM || isX(m)
|
||
var xp = xm || isX(p)
|
||
var anyX = xp
|
||
|
||
if (gtlt === '=' && anyX) {
|
||
gtlt = ''
|
||
}
|
||
|
||
if (xM) {
|
||
if (gtlt === '>' || gtlt === '<') {
|
||
// nothing is allowed
|
||
ret = '<0.0.0'
|
||
} else {
|
||
// nothing is forbidden
|
||
ret = '*'
|
||
}
|
||
} else if (gtlt && anyX) {
|
||
// we know patch is an x, because we have any x at all.
|
||
// replace X with 0
|
||
if (xm) {
|
||
m = 0
|
||
}
|
||
p = 0
|
||
|
||
if (gtlt === '>') {
|
||
// >1 => >=2.0.0
|
||
// >1.2 => >=1.3.0
|
||
// >1.2.3 => >= 1.2.4
|
||
gtlt = '>='
|
||
if (xm) {
|
||
M = +M + 1
|
||
m = 0
|
||
p = 0
|
||
} else {
|
||
m = +m + 1
|
||
p = 0
|
||
}
|
||
} else if (gtlt === '<=') {
|
||
// <=0.7.x is actually <0.8.0, since any 0.7.x should
|
||
// pass. Similarly, <=7.x is actually <8.0.0, etc.
|
||
gtlt = '<'
|
||
if (xm) {
|
||
M = +M + 1
|
||
} else {
|
||
m = +m + 1
|
||
}
|
||
}
|
||
|
||
ret = gtlt + M + '.' + m + '.' + p
|
||
} else if (xm) {
|
||
ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'
|
||
} else if (xp) {
|
||
ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'
|
||
}
|
||
|
||
debug('xRange return', ret)
|
||
|
||
return ret
|
||
})
|
||
}
|
||
|
||
// Because * is AND-ed with everything else in the comparator,
|
||
// and '' means "any version", just remove the *s entirely.
|
||
function replaceStars (comp, options) {
|
||
debug('replaceStars', comp, options)
|
||
// Looseness is ignored here. star is always as loose as it gets!
|
||
return comp.trim().replace(re[STAR], '')
|
||
}
|
||
|
||
// This function is passed to string.replace(re[HYPHENRANGE])
|
||
// M, m, patch, prerelease, build
|
||
// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
|
||
// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
|
||
// 1.2 - 3.4 => >=1.2.0 <3.5.0
|
||
function hyphenReplace ($0,
|
||
from, fM, fm, fp, fpr, fb,
|
||
to, tM, tm, tp, tpr, tb) {
|
||
if (isX(fM)) {
|
||
from = ''
|
||
} else if (isX(fm)) {
|
||
from = '>=' + fM + '.0.0'
|
||
} else if (isX(fp)) {
|
||
from = '>=' + fM + '.' + fm + '.0'
|
||
} else {
|
||
from = '>=' + from
|
||
}
|
||
|
||
if (isX(tM)) {
|
||
to = ''
|
||
} else if (isX(tm)) {
|
||
to = '<' + (+tM + 1) + '.0.0'
|
||
} else if (isX(tp)) {
|
||
to = '<' + tM + '.' + (+tm + 1) + '.0'
|
||
} else if (tpr) {
|
||
to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr
|
||
} else {
|
||
to = '<=' + to
|
||
}
|
||
|
||
return (from + ' ' + to).trim()
|
||
}
|
||
|
||
// if ANY of the sets match ALL of its comparators, then pass
|
||
Range.prototype.test = function (version) {
|
||
if (!version) {
|
||
return false
|
||
}
|
||
|
||
if (typeof version === 'string') {
|
||
version = new SemVer(version, this.options)
|
||
}
|
||
|
||
for (var i = 0; i < this.set.length; i++) {
|
||
if (testSet(this.set[i], version, this.options)) {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
function testSet (set, version, options) {
|
||
for (var i = 0; i < set.length; i++) {
|
||
if (!set[i].test(version)) {
|
||
return false
|
||
}
|
||
}
|
||
|
||
if (version.prerelease.length && !options.includePrerelease) {
|
||
// Find the set of versions that are allowed to have prereleases
|
||
// For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
|
||
// That should allow `1.2.3-pr.2` to pass.
|
||
// However, `1.2.4-alpha.notready` should NOT be allowed,
|
||
// even though it's within the range set by the comparators.
|
||
for (i = 0; i < set.length; i++) {
|
||
debug(set[i].semver)
|
||
if (set[i].semver === ANY) {
|
||
continue
|
||
}
|
||
|
||
if (set[i].semver.prerelease.length > 0) {
|
||
var allowed = set[i].semver
|
||
if (allowed.major === version.major &&
|
||
allowed.minor === version.minor &&
|
||
allowed.patch === version.patch) {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
|
||
// Version has a -pre, but it's not one of the ones we like.
|
||
return false
|
||
}
|
||
|
||
return true
|
||
}
|
||
|
||
exports.satisfies = satisfies
|
||
function satisfies (version, range, options) {
|
||
try {
|
||
range = new Range(range, options)
|
||
} catch (er) {
|
||
return false
|
||
}
|
||
return range.test(version)
|
||
}
|
||
|
||
exports.maxSatisfying = maxSatisfying
|
||
function maxSatisfying (versions, range, options) {
|
||
var max = null
|
||
var maxSV = null
|
||
try {
|
||
var rangeObj = new Range(range, options)
|
||
} catch (er) {
|
||
return null
|
||
}
|
||
versions.forEach(function (v) {
|
||
if (rangeObj.test(v)) {
|
||
// satisfies(v, range, options)
|
||
if (!max || maxSV.compare(v) === -1) {
|
||
// compare(max, v, true)
|
||
max = v
|
||
maxSV = new SemVer(max, options)
|
||
}
|
||
}
|
||
})
|
||
return max
|
||
}
|
||
|
||
exports.minSatisfying = minSatisfying
|
||
function minSatisfying (versions, range, options) {
|
||
var min = null
|
||
var minSV = null
|
||
try {
|
||
var rangeObj = new Range(range, options)
|
||
} catch (er) {
|
||
return null
|
||
}
|
||
versions.forEach(function (v) {
|
||
if (rangeObj.test(v)) {
|
||
// satisfies(v, range, options)
|
||
if (!min || minSV.compare(v) === 1) {
|
||
// compare(min, v, true)
|
||
min = v
|
||
minSV = new SemVer(min, options)
|
||
}
|
||
}
|
||
})
|
||
return min
|
||
}
|
||
|
||
exports.minVersion = minVersion
|
||
function minVersion (range, loose) {
|
||
range = new Range(range, loose)
|
||
|
||
var minver = new SemVer('0.0.0')
|
||
if (range.test(minver)) {
|
||
return minver
|
||
}
|
||
|
||
minver = new SemVer('0.0.0-0')
|
||
if (range.test(minver)) {
|
||
return minver
|
||
}
|
||
|
||
minver = null
|
||
for (var i = 0; i < range.set.length; ++i) {
|
||
var comparators = range.set[i]
|
||
|
||
comparators.forEach(function (comparator) {
|
||
// Clone to avoid manipulating the comparator's semver object.
|
||
var compver = new SemVer(comparator.semver.version)
|
||
switch (comparator.operator) {
|
||
case '>':
|
||
if (compver.prerelease.length === 0) {
|
||
compver.patch++
|
||
} else {
|
||
compver.prerelease.push(0)
|
||
}
|
||
compver.raw = compver.format()
|
||
/* fallthrough */
|
||
case '':
|
||
case '>=':
|
||
if (!minver || gt(minver, compver)) {
|
||
minver = compver
|
||
}
|
||
break
|
||
case '<':
|
||
case '<=':
|
||
/* Ignore maximum versions */
|
||
break
|
||
/* istanbul ignore next */
|
||
default:
|
||
throw new Error('Unexpected operation: ' + comparator.operator)
|
||
}
|
||
})
|
||
}
|
||
|
||
if (minver && range.test(minver)) {
|
||
return minver
|
||
}
|
||
|
||
return null
|
||
}
|
||
|
||
exports.validRange = validRange
|
||
function validRange (range, options) {
|
||
try {
|
||
// Return '*' instead of '' so that truthiness works.
|
||
// This will throw if it's invalid anyway
|
||
return new Range(range, options).range || '*'
|
||
} catch (er) {
|
||
return null
|
||
}
|
||
}
|
||
|
||
// Determine if version is less than all the versions possible in the range
|
||
exports.ltr = ltr
|
||
function ltr (version, range, options) {
|
||
return outside(version, range, '<', options)
|
||
}
|
||
|
||
// Determine if version is greater than all the versions possible in the range.
|
||
exports.gtr = gtr
|
||
function gtr (version, range, options) {
|
||
return outside(version, range, '>', options)
|
||
}
|
||
|
||
exports.outside = outside
|
||
function outside (version, range, hilo, options) {
|
||
version = new SemVer(version, options)
|
||
range = new Range(range, options)
|
||
|
||
var gtfn, ltefn, ltfn, comp, ecomp
|
||
switch (hilo) {
|
||
case '>':
|
||
gtfn = gt
|
||
ltefn = lte
|
||
ltfn = lt
|
||
comp = '>'
|
||
ecomp = '>='
|
||
break
|
||
case '<':
|
||
gtfn = lt
|
||
ltefn = gte
|
||
ltfn = gt
|
||
comp = '<'
|
||
ecomp = '<='
|
||
break
|
||
default:
|
||
throw new TypeError('Must provide a hilo val of "<" or ">"')
|
||
}
|
||
|
||
// If it satisifes the range it is not outside
|
||
if (satisfies(version, range, options)) {
|
||
return false
|
||
}
|
||
|
||
// From now on, variable terms are as if we're in "gtr" mode.
|
||
// but note that everything is flipped for the "ltr" function.
|
||
|
||
for (var i = 0; i < range.set.length; ++i) {
|
||
var comparators = range.set[i]
|
||
|
||
var high = null
|
||
var low = null
|
||
|
||
comparators.forEach(function (comparator) {
|
||
if (comparator.semver === ANY) {
|
||
comparator = new Comparator('>=0.0.0')
|
||
}
|
||
high = high || comparator
|
||
low = low || comparator
|
||
if (gtfn(comparator.semver, high.semver, options)) {
|
||
high = comparator
|
||
} else if (ltfn(comparator.semver, low.semver, options)) {
|
||
low = comparator
|
||
}
|
||
})
|
||
|
||
// If the edge version comparator has a operator then our version
|
||
// isn't outside it
|
||
if (high.operator === comp || high.operator === ecomp) {
|
||
return false
|
||
}
|
||
|
||
// If the lowest version comparator has an operator and our version
|
||
// is less than it then it isn't higher than the range
|
||
if ((!low.operator || low.operator === comp) &&
|
||
ltefn(version, low.semver)) {
|
||
return false
|
||
} else if (low.operator === ecomp && ltfn(version, low.semver)) {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
exports.prerelease = prerelease
|
||
function prerelease (version, options) {
|
||
var parsed = parse(version, options)
|
||
return (parsed && parsed.prerelease.length) ? parsed.prerelease : null
|
||
}
|
||
|
||
exports.intersects = intersects
|
||
function intersects (r1, r2, options) {
|
||
r1 = new Range(r1, options)
|
||
r2 = new Range(r2, options)
|
||
return r1.intersects(r2)
|
||
}
|
||
|
||
exports.coerce = coerce
|
||
function coerce (version) {
|
||
if (version instanceof SemVer) {
|
||
return version
|
||
}
|
||
|
||
if (typeof version !== 'string') {
|
||
return null
|
||
}
|
||
|
||
var match = version.match(re[COERCE])
|
||
|
||
if (match == null) {
|
||
return null
|
||
}
|
||
|
||
return parse(match[1] +
|
||
'.' + (match[2] || '0') +
|
||
'.' + (match[3] || '0'))
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/commands.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/commands.js ***!
|
||
\******************************************/
|
||
/***/ ((module) => {
|
||
|
||
module.exports = [
|
||
'cat',
|
||
'cd',
|
||
'chmod',
|
||
'cp',
|
||
'dirs',
|
||
'echo',
|
||
'exec',
|
||
'find',
|
||
'grep',
|
||
'head',
|
||
'ln',
|
||
'ls',
|
||
'mkdir',
|
||
'mv',
|
||
'pwd',
|
||
'rm',
|
||
'sed',
|
||
'set',
|
||
'sort',
|
||
'tail',
|
||
'tempdir',
|
||
'test',
|
||
'to',
|
||
'toEnd',
|
||
'touch',
|
||
'uniq',
|
||
'which',
|
||
];
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/shell.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/shelljs/shell.js ***!
|
||
\***************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
//
|
||
// ShellJS
|
||
// Unix shell commands on top of Node's API
|
||
//
|
||
// Copyright (c) 2012 Artur Adib
|
||
// http://github.com/shelljs/shelljs
|
||
//
|
||
|
||
var common = __webpack_require__(/*! ./src/common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
//@
|
||
//@ All commands run synchronously, unless otherwise stated.
|
||
//@ All commands accept standard bash globbing characters (`*`, `?`, etc.),
|
||
//@ compatible with the [node `glob` module](https://github.com/isaacs/node-glob).
|
||
//@
|
||
//@ For less-commonly used commands and features, please check out our [wiki
|
||
//@ page](https://github.com/shelljs/shelljs/wiki).
|
||
//@
|
||
|
||
// Include the docs for all the default commands
|
||
//@commands
|
||
|
||
// Load all default commands
|
||
__webpack_require__(/*! ./commands */ "./node_modules/shelljs/commands.js").forEach(function (command) {
|
||
__webpack_require__("./node_modules/shelljs/src sync recursive ^\\.\\/.*$")("./" + command);
|
||
});
|
||
|
||
//@
|
||
//@ ### exit(code)
|
||
//@
|
||
//@ Exits the current process with the given exit `code`.
|
||
exports.exit = process.exit;
|
||
|
||
//@include ./src/error
|
||
exports.error = __webpack_require__(/*! ./src/error */ "./node_modules/shelljs/src/error.js");
|
||
|
||
//@include ./src/common
|
||
exports.ShellString = common.ShellString;
|
||
|
||
//@
|
||
//@ ### env['VAR_NAME']
|
||
//@
|
||
//@ Object containing environment variables (both getter and setter). Shortcut
|
||
//@ to `process.env`.
|
||
exports.env = process.env;
|
||
|
||
//@
|
||
//@ ### Pipes
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ grep('foo', 'file1.txt', 'file2.txt').sed(/o/g, 'a').to('output.txt');
|
||
//@ echo('files with o\'s in the name:\n' + ls().grep('o'));
|
||
//@ cat('test.js').exec('node'); // pipe to exec() call
|
||
//@ ```
|
||
//@
|
||
//@ Commands can send their output to another command in a pipe-like fashion.
|
||
//@ `sed`, `grep`, `cat`, `exec`, `to`, and `toEnd` can appear on the right-hand
|
||
//@ side of a pipe. Pipes can be chained.
|
||
|
||
//@
|
||
//@ ## Configuration
|
||
//@
|
||
|
||
exports.config = common.config;
|
||
|
||
//@
|
||
//@ ### config.silent
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var sh = require('shelljs');
|
||
//@ var silentState = sh.config.silent; // save old silent state
|
||
//@ sh.config.silent = true;
|
||
//@ /* ... */
|
||
//@ sh.config.silent = silentState; // restore old silent state
|
||
//@ ```
|
||
//@
|
||
//@ Suppresses all command output if `true`, except for `echo()` calls.
|
||
//@ Default is `false`.
|
||
|
||
//@
|
||
//@ ### config.fatal
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ require('shelljs/global');
|
||
//@ config.fatal = true; // or set('-e');
|
||
//@ cp('this_file_does_not_exist', '/dev/null'); // throws Error here
|
||
//@ /* more commands... */
|
||
//@ ```
|
||
//@
|
||
//@ If `true`, the script will throw a Javascript error when any shell.js
|
||
//@ command encounters an error. Default is `false`. This is analogous to
|
||
//@ Bash's `set -e`.
|
||
|
||
//@
|
||
//@ ### config.verbose
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ config.verbose = true; // or set('-v');
|
||
//@ cd('dir/');
|
||
//@ rm('-rf', 'foo.txt', 'bar.txt');
|
||
//@ exec('echo hello');
|
||
//@ ```
|
||
//@
|
||
//@ Will print each command as follows:
|
||
//@
|
||
//@ ```
|
||
//@ cd dir/
|
||
//@ rm -rf foo.txt bar.txt
|
||
//@ exec echo hello
|
||
//@ ```
|
||
|
||
//@
|
||
//@ ### config.globOptions
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ config.globOptions = {nodir: true};
|
||
//@ ```
|
||
//@
|
||
//@ Use this value for calls to `glob.sync()` instead of the default options.
|
||
|
||
//@
|
||
//@ ### config.reset()
|
||
//@
|
||
//@ Example:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var shell = require('shelljs');
|
||
//@ // Make changes to shell.config, and do stuff...
|
||
//@ /* ... */
|
||
//@ shell.config.reset(); // reset to original state
|
||
//@ // Do more stuff, but with original settings
|
||
//@ /* ... */
|
||
//@ ```
|
||
//@
|
||
//@ Reset `shell.config` to the defaults:
|
||
//@
|
||
//@ ```javascript
|
||
//@ {
|
||
//@ fatal: false,
|
||
//@ globOptions: {},
|
||
//@ maxdepth: 255,
|
||
//@ noglob: false,
|
||
//@ silent: false,
|
||
//@ verbose: false,
|
||
//@ }
|
||
//@ ```
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/cat.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/shelljs/src/cat.js ***!
|
||
\*****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('cat', _cat, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'n': 'number',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### cat([options,] file [, file ...])
|
||
//@ ### cat([options,] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n`: number all output lines
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var str = cat('file*.txt');
|
||
//@ var str = cat('file1', 'file2');
|
||
//@ var str = cat(['file1', 'file2']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Returns a string containing the given file, or a concatenated string
|
||
//@ containing the files if more than one file is given (a new line character is
|
||
//@ introduced between each file).
|
||
function _cat(options, files) {
|
||
var cat = common.readFromPipe();
|
||
|
||
if (!files && !cat) common.error('no paths given');
|
||
|
||
files = [].slice.call(arguments, 1);
|
||
|
||
files.forEach(function (file) {
|
||
if (!fs.existsSync(file)) {
|
||
common.error('no such file or directory: ' + file);
|
||
} else if (common.statFollowLinks(file).isDirectory()) {
|
||
common.error(file + ': Is a directory');
|
||
}
|
||
|
||
cat += fs.readFileSync(file, 'utf8');
|
||
});
|
||
|
||
if (options.number) {
|
||
cat = addNumbers(cat);
|
||
}
|
||
|
||
return cat;
|
||
}
|
||
module.exports = _cat;
|
||
|
||
function addNumbers(cat) {
|
||
var lines = cat.split('\n');
|
||
var lastLine = lines.pop();
|
||
|
||
lines = lines.map(function (line, i) {
|
||
return numberedLine(i + 1, line);
|
||
});
|
||
|
||
if (lastLine.length) {
|
||
lastLine = numberedLine(lines.length + 1, lastLine);
|
||
}
|
||
lines.push(lastLine);
|
||
|
||
return lines.join('\n');
|
||
}
|
||
|
||
function numberedLine(n, line) {
|
||
// GNU cat use six pad start number + tab. See http://lingrok.org/xref/coreutils/src/cat.c#57
|
||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
|
||
var number = (' ' + n).slice(-6) + '\t';
|
||
return number + line;
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/cd.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/cd.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('cd', _cd, {});
|
||
|
||
//@
|
||
//@ ### cd([dir])
|
||
//@
|
||
//@ Changes to directory `dir` for the duration of the script. Changes to home
|
||
//@ directory if no argument is supplied.
|
||
function _cd(options, dir) {
|
||
if (!dir) dir = os.homedir();
|
||
|
||
if (dir === '-') {
|
||
if (!process.env.OLDPWD) {
|
||
common.error('could not find previous directory');
|
||
} else {
|
||
dir = process.env.OLDPWD;
|
||
}
|
||
}
|
||
|
||
try {
|
||
var curDir = process.cwd();
|
||
process.chdir(dir);
|
||
process.env.OLDPWD = curDir;
|
||
} catch (e) {
|
||
// something went wrong, let's figure out the error
|
||
var err;
|
||
try {
|
||
common.statFollowLinks(dir); // if this succeeds, it must be some sort of file
|
||
err = 'not a directory: ' + dir;
|
||
} catch (e2) {
|
||
err = 'no such file or directory: ' + dir;
|
||
}
|
||
if (err) common.error(err);
|
||
}
|
||
return '';
|
||
}
|
||
module.exports = _cd;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/chmod.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/chmod.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
var PERMS = (function (base) {
|
||
return {
|
||
OTHER_EXEC: base.EXEC,
|
||
OTHER_WRITE: base.WRITE,
|
||
OTHER_READ: base.READ,
|
||
|
||
GROUP_EXEC: base.EXEC << 3,
|
||
GROUP_WRITE: base.WRITE << 3,
|
||
GROUP_READ: base.READ << 3,
|
||
|
||
OWNER_EXEC: base.EXEC << 6,
|
||
OWNER_WRITE: base.WRITE << 6,
|
||
OWNER_READ: base.READ << 6,
|
||
|
||
// Literal octal numbers are apparently not allowed in "strict" javascript.
|
||
STICKY: parseInt('01000', 8),
|
||
SETGID: parseInt('02000', 8),
|
||
SETUID: parseInt('04000', 8),
|
||
|
||
TYPE_MASK: parseInt('0770000', 8),
|
||
};
|
||
}({
|
||
EXEC: 1,
|
||
WRITE: 2,
|
||
READ: 4,
|
||
}));
|
||
|
||
common.register('chmod', _chmod, {
|
||
});
|
||
|
||
//@
|
||
//@ ### chmod([options,] octal_mode || octal_string, file)
|
||
//@ ### chmod([options,] symbolic_mode, file)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-v`: output a diagnostic for every file processed//@
|
||
//@ + `-c`: like verbose, but report only when a change is made//@
|
||
//@ + `-R`: change files and directories recursively//@
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ chmod(755, '/Users/brandon');
|
||
//@ chmod('755', '/Users/brandon'); // same as above
|
||
//@ chmod('u+x', '/Users/brandon');
|
||
//@ chmod('-R', 'a-w', '/Users/brandon');
|
||
//@ ```
|
||
//@
|
||
//@ Alters the permissions of a file or directory by either specifying the
|
||
//@ absolute permissions in octal form or expressing the changes in symbols.
|
||
//@ This command tries to mimic the POSIX behavior as much as possible.
|
||
//@ Notable exceptions:
|
||
//@
|
||
//@ + In symbolic modes, `a-r` and `-r` are identical. No consideration is
|
||
//@ given to the `umask`.
|
||
//@ + There is no "quiet" option, since default behavior is to run silent.
|
||
function _chmod(options, mode, filePattern) {
|
||
if (!filePattern) {
|
||
if (options.length > 0 && options.charAt(0) === '-') {
|
||
// Special case where the specified file permissions started with - to subtract perms, which
|
||
// get picked up by the option parser as command flags.
|
||
// If we are down by one argument and options starts with -, shift everything over.
|
||
[].unshift.call(arguments, '');
|
||
} else {
|
||
common.error('You must specify a file.');
|
||
}
|
||
}
|
||
|
||
options = common.parseOptions(options, {
|
||
'R': 'recursive',
|
||
'c': 'changes',
|
||
'v': 'verbose',
|
||
});
|
||
|
||
filePattern = [].slice.call(arguments, 2);
|
||
|
||
var files;
|
||
|
||
// TODO: replace this with a call to common.expand()
|
||
if (options.recursive) {
|
||
files = [];
|
||
filePattern.forEach(function addFile(expandedFile) {
|
||
var stat = common.statNoFollowLinks(expandedFile);
|
||
|
||
if (!stat.isSymbolicLink()) {
|
||
files.push(expandedFile);
|
||
|
||
if (stat.isDirectory()) { // intentionally does not follow symlinks.
|
||
fs.readdirSync(expandedFile).forEach(function (child) {
|
||
addFile(expandedFile + '/' + child);
|
||
});
|
||
}
|
||
}
|
||
});
|
||
} else {
|
||
files = filePattern;
|
||
}
|
||
|
||
files.forEach(function innerChmod(file) {
|
||
file = path.resolve(file);
|
||
if (!fs.existsSync(file)) {
|
||
common.error('File not found: ' + file);
|
||
}
|
||
|
||
// When recursing, don't follow symlinks.
|
||
if (options.recursive && common.statNoFollowLinks(file).isSymbolicLink()) {
|
||
return;
|
||
}
|
||
|
||
var stat = common.statFollowLinks(file);
|
||
var isDir = stat.isDirectory();
|
||
var perms = stat.mode;
|
||
var type = perms & PERMS.TYPE_MASK;
|
||
|
||
var newPerms = perms;
|
||
|
||
if (isNaN(parseInt(mode, 8))) {
|
||
// parse options
|
||
mode.split(',').forEach(function (symbolicMode) {
|
||
var pattern = /([ugoa]*)([=\+-])([rwxXst]*)/i;
|
||
var matches = pattern.exec(symbolicMode);
|
||
|
||
if (matches) {
|
||
var applyTo = matches[1];
|
||
var operator = matches[2];
|
||
var change = matches[3];
|
||
|
||
var changeOwner = applyTo.indexOf('u') !== -1 || applyTo === 'a' || applyTo === '';
|
||
var changeGroup = applyTo.indexOf('g') !== -1 || applyTo === 'a' || applyTo === '';
|
||
var changeOther = applyTo.indexOf('o') !== -1 || applyTo === 'a' || applyTo === '';
|
||
|
||
var changeRead = change.indexOf('r') !== -1;
|
||
var changeWrite = change.indexOf('w') !== -1;
|
||
var changeExec = change.indexOf('x') !== -1;
|
||
var changeExecDir = change.indexOf('X') !== -1;
|
||
var changeSticky = change.indexOf('t') !== -1;
|
||
var changeSetuid = change.indexOf('s') !== -1;
|
||
|
||
if (changeExecDir && isDir) {
|
||
changeExec = true;
|
||
}
|
||
|
||
var mask = 0;
|
||
if (changeOwner) {
|
||
mask |= (changeRead ? PERMS.OWNER_READ : 0) + (changeWrite ? PERMS.OWNER_WRITE : 0) + (changeExec ? PERMS.OWNER_EXEC : 0) + (changeSetuid ? PERMS.SETUID : 0);
|
||
}
|
||
if (changeGroup) {
|
||
mask |= (changeRead ? PERMS.GROUP_READ : 0) + (changeWrite ? PERMS.GROUP_WRITE : 0) + (changeExec ? PERMS.GROUP_EXEC : 0) + (changeSetuid ? PERMS.SETGID : 0);
|
||
}
|
||
if (changeOther) {
|
||
mask |= (changeRead ? PERMS.OTHER_READ : 0) + (changeWrite ? PERMS.OTHER_WRITE : 0) + (changeExec ? PERMS.OTHER_EXEC : 0);
|
||
}
|
||
|
||
// Sticky bit is special - it's not tied to user, group or other.
|
||
if (changeSticky) {
|
||
mask |= PERMS.STICKY;
|
||
}
|
||
|
||
switch (operator) {
|
||
case '+':
|
||
newPerms |= mask;
|
||
break;
|
||
|
||
case '-':
|
||
newPerms &= ~mask;
|
||
break;
|
||
|
||
case '=':
|
||
newPerms = type + mask;
|
||
|
||
// According to POSIX, when using = to explicitly set the
|
||
// permissions, setuid and setgid can never be cleared.
|
||
if (common.statFollowLinks(file).isDirectory()) {
|
||
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
|
||
}
|
||
break;
|
||
default:
|
||
common.error('Could not recognize operator: `' + operator + '`');
|
||
}
|
||
|
||
if (options.verbose) {
|
||
console.log(file + ' -> ' + newPerms.toString(8));
|
||
}
|
||
|
||
if (perms !== newPerms) {
|
||
if (!options.verbose && options.changes) {
|
||
console.log(file + ' -> ' + newPerms.toString(8));
|
||
}
|
||
fs.chmodSync(file, newPerms);
|
||
perms = newPerms; // for the next round of changes!
|
||
}
|
||
} else {
|
||
common.error('Invalid symbolic mode change: ' + symbolicMode);
|
||
}
|
||
});
|
||
} else {
|
||
// they gave us a full number
|
||
newPerms = type + parseInt(mode, 8);
|
||
|
||
// POSIX rules are that setuid and setgid can only be added using numeric
|
||
// form, but not cleared.
|
||
if (common.statFollowLinks(file).isDirectory()) {
|
||
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
|
||
}
|
||
|
||
fs.chmodSync(file, newPerms);
|
||
}
|
||
});
|
||
return '';
|
||
}
|
||
module.exports = _chmod;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/common.js":
|
||
/*!********************************************!*\
|
||
!*** ./node_modules/shelljs/src/common.js ***!
|
||
\********************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
// Ignore warning about 'new String()'
|
||
/* eslint no-new-wrappers: 0 */
|
||
|
||
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var glob = __webpack_require__(/*! glob */ "./node_modules/glob/glob.js");
|
||
var shell = __webpack_require__(/*! .. */ "./node_modules/shelljs/shell.js");
|
||
|
||
var shellMethods = Object.create(shell);
|
||
|
||
exports.extend = Object.assign;
|
||
|
||
// Check if we're running under electron
|
||
var isElectron = Boolean(process.versions.electron);
|
||
|
||
// Module globals (assume no execPath by default)
|
||
var DEFAULT_CONFIG = {
|
||
fatal: false,
|
||
globOptions: {},
|
||
maxdepth: 255,
|
||
noglob: false,
|
||
silent: false,
|
||
verbose: false,
|
||
execPath: null,
|
||
bufLength: 64 * 1024, // 64KB
|
||
};
|
||
|
||
var config = {
|
||
reset: function () {
|
||
Object.assign(this, DEFAULT_CONFIG);
|
||
if (!isElectron) {
|
||
this.execPath = process.execPath;
|
||
}
|
||
},
|
||
resetForTesting: function () {
|
||
this.reset();
|
||
this.silent = true;
|
||
},
|
||
};
|
||
|
||
config.reset();
|
||
exports.config = config;
|
||
|
||
// Note: commands should generally consider these as read-only values.
|
||
var state = {
|
||
error: null,
|
||
errorCode: 0,
|
||
currentCmd: 'shell.js',
|
||
};
|
||
exports.state = state;
|
||
|
||
delete process.env.OLDPWD; // initially, there's no previous directory
|
||
|
||
// Reliably test if something is any sort of javascript object
|
||
function isObject(a) {
|
||
return typeof a === 'object' && a !== null;
|
||
}
|
||
exports.isObject = isObject;
|
||
|
||
function log() {
|
||
/* istanbul ignore next */
|
||
if (!config.silent) {
|
||
console.error.apply(console, arguments);
|
||
}
|
||
}
|
||
exports.log = log;
|
||
|
||
// Converts strings to be equivalent across all platforms. Primarily responsible
|
||
// for making sure we use '/' instead of '\' as path separators, but this may be
|
||
// expanded in the future if necessary
|
||
function convertErrorOutput(msg) {
|
||
if (typeof msg !== 'string') {
|
||
throw new TypeError('input must be a string');
|
||
}
|
||
return msg.replace(/\\/g, '/');
|
||
}
|
||
exports.convertErrorOutput = convertErrorOutput;
|
||
|
||
// Shows error message. Throws if config.fatal is true
|
||
function error(msg, _code, options) {
|
||
// Validate input
|
||
if (typeof msg !== 'string') throw new Error('msg must be a string');
|
||
|
||
var DEFAULT_OPTIONS = {
|
||
continue: false,
|
||
code: 1,
|
||
prefix: state.currentCmd + ': ',
|
||
silent: false,
|
||
};
|
||
|
||
if (typeof _code === 'number' && isObject(options)) {
|
||
options.code = _code;
|
||
} else if (isObject(_code)) { // no 'code'
|
||
options = _code;
|
||
} else if (typeof _code === 'number') { // no 'options'
|
||
options = { code: _code };
|
||
} else if (typeof _code !== 'number') { // only 'msg'
|
||
options = {};
|
||
}
|
||
options = Object.assign({}, DEFAULT_OPTIONS, options);
|
||
|
||
if (!state.errorCode) state.errorCode = options.code;
|
||
|
||
var logEntry = convertErrorOutput(options.prefix + msg);
|
||
state.error = state.error ? state.error + '\n' : '';
|
||
state.error += logEntry;
|
||
|
||
// Throw an error, or log the entry
|
||
if (config.fatal) throw new Error(logEntry);
|
||
if (msg.length > 0 && !options.silent) log(logEntry);
|
||
|
||
if (!options.continue) {
|
||
throw {
|
||
msg: 'earlyExit',
|
||
retValue: (new ShellString('', state.error, state.errorCode)),
|
||
};
|
||
}
|
||
}
|
||
exports.error = error;
|
||
|
||
//@
|
||
//@ ### ShellString(str)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var foo = ShellString('hello world');
|
||
//@ ```
|
||
//@
|
||
//@ Turns a regular string into a string-like object similar to what each
|
||
//@ command returns. This has special methods, like `.to()` and `.toEnd()`.
|
||
function ShellString(stdout, stderr, code) {
|
||
var that;
|
||
if (stdout instanceof Array) {
|
||
that = stdout;
|
||
that.stdout = stdout.join('\n');
|
||
if (stdout.length > 0) that.stdout += '\n';
|
||
} else {
|
||
that = new String(stdout);
|
||
that.stdout = stdout;
|
||
}
|
||
that.stderr = stderr;
|
||
that.code = code;
|
||
// A list of all commands that can appear on the right-hand side of a pipe
|
||
// (populated by calls to common.wrap())
|
||
pipeMethods.forEach(function (cmd) {
|
||
that[cmd] = shellMethods[cmd].bind(that);
|
||
});
|
||
return that;
|
||
}
|
||
|
||
exports.ShellString = ShellString;
|
||
|
||
// Returns {'alice': true, 'bob': false} when passed a string and dictionary as follows:
|
||
// parseOptions('-a', {'a':'alice', 'b':'bob'});
|
||
// Returns {'reference': 'string-value', 'bob': false} when passed two dictionaries of the form:
|
||
// parseOptions({'-r': 'string-value'}, {'r':'reference', 'b':'bob'});
|
||
// Throws an error when passed a string that does not start with '-':
|
||
// parseOptions('a', {'a':'alice'}); // throws
|
||
function parseOptions(opt, map, errorOptions) {
|
||
// Validate input
|
||
if (typeof opt !== 'string' && !isObject(opt)) {
|
||
throw new Error('options must be strings or key-value pairs');
|
||
} else if (!isObject(map)) {
|
||
throw new Error('parseOptions() internal error: map must be an object');
|
||
} else if (errorOptions && !isObject(errorOptions)) {
|
||
throw new Error('parseOptions() internal error: errorOptions must be object');
|
||
}
|
||
|
||
if (opt === '--') {
|
||
// This means there are no options.
|
||
return {};
|
||
}
|
||
|
||
// All options are false by default
|
||
var options = {};
|
||
Object.keys(map).forEach(function (letter) {
|
||
var optName = map[letter];
|
||
if (optName[0] !== '!') {
|
||
options[optName] = false;
|
||
}
|
||
});
|
||
|
||
if (opt === '') return options; // defaults
|
||
|
||
if (typeof opt === 'string') {
|
||
if (opt[0] !== '-') {
|
||
throw new Error("Options string must start with a '-'");
|
||
}
|
||
|
||
// e.g. chars = ['R', 'f']
|
||
var chars = opt.slice(1).split('');
|
||
|
||
chars.forEach(function (c) {
|
||
if (c in map) {
|
||
var optionName = map[c];
|
||
if (optionName[0] === '!') {
|
||
options[optionName.slice(1)] = false;
|
||
} else {
|
||
options[optionName] = true;
|
||
}
|
||
} else {
|
||
error('option not recognized: ' + c, errorOptions || {});
|
||
}
|
||
});
|
||
} else { // opt is an Object
|
||
Object.keys(opt).forEach(function (key) {
|
||
// key is a string of the form '-r', '-d', etc.
|
||
var c = key[1];
|
||
if (c in map) {
|
||
var optionName = map[c];
|
||
options[optionName] = opt[key]; // assign the given value
|
||
} else {
|
||
error('option not recognized: ' + c, errorOptions || {});
|
||
}
|
||
});
|
||
}
|
||
return options;
|
||
}
|
||
exports.parseOptions = parseOptions;
|
||
|
||
// Expands wildcards with matching (ie. existing) file names.
|
||
// For example:
|
||
// expand(['file*.js']) = ['file1.js', 'file2.js', ...]
|
||
// (if the files 'file1.js', 'file2.js', etc, exist in the current dir)
|
||
function expand(list) {
|
||
if (!Array.isArray(list)) {
|
||
throw new TypeError('must be an array');
|
||
}
|
||
var expanded = [];
|
||
list.forEach(function (listEl) {
|
||
// Don't expand non-strings
|
||
if (typeof listEl !== 'string') {
|
||
expanded.push(listEl);
|
||
} else {
|
||
var ret;
|
||
try {
|
||
ret = glob.sync(listEl, config.globOptions);
|
||
// if nothing matched, interpret the string literally
|
||
ret = ret.length > 0 ? ret : [listEl];
|
||
} catch (e) {
|
||
// if glob fails, interpret the string literally
|
||
ret = [listEl];
|
||
}
|
||
expanded = expanded.concat(ret);
|
||
}
|
||
});
|
||
return expanded;
|
||
}
|
||
exports.expand = expand;
|
||
|
||
// Normalizes Buffer creation, using Buffer.alloc if possible.
|
||
// Also provides a good default buffer length for most use cases.
|
||
var buffer = typeof Buffer.alloc === 'function' ?
|
||
function (len) {
|
||
return Buffer.alloc(len || config.bufLength);
|
||
} :
|
||
function (len) {
|
||
return new Buffer(len || config.bufLength);
|
||
};
|
||
exports.buffer = buffer;
|
||
|
||
// Normalizes _unlinkSync() across platforms to match Unix behavior, i.e.
|
||
// file can be unlinked even if it's read-only, see https://github.com/joyent/node/issues/3006
|
||
function unlinkSync(file) {
|
||
try {
|
||
fs.unlinkSync(file);
|
||
} catch (e) {
|
||
// Try to override file permission
|
||
/* istanbul ignore next */
|
||
if (e.code === 'EPERM') {
|
||
fs.chmodSync(file, '0666');
|
||
fs.unlinkSync(file);
|
||
} else {
|
||
throw e;
|
||
}
|
||
}
|
||
}
|
||
exports.unlinkSync = unlinkSync;
|
||
|
||
// wrappers around common.statFollowLinks and common.statNoFollowLinks that clarify intent
|
||
// and improve readability
|
||
function statFollowLinks() {
|
||
return fs.statSync.apply(fs, arguments);
|
||
}
|
||
exports.statFollowLinks = statFollowLinks;
|
||
|
||
function statNoFollowLinks() {
|
||
return fs.lstatSync.apply(fs, arguments);
|
||
}
|
||
exports.statNoFollowLinks = statNoFollowLinks;
|
||
|
||
// e.g. 'shelljs_a5f185d0443ca...'
|
||
function randomFileName() {
|
||
function randomHash(count) {
|
||
if (count === 1) {
|
||
return parseInt(16 * Math.random(), 10).toString(16);
|
||
}
|
||
var hash = '';
|
||
for (var i = 0; i < count; i++) {
|
||
hash += randomHash(1);
|
||
}
|
||
return hash;
|
||
}
|
||
|
||
return 'shelljs_' + randomHash(20);
|
||
}
|
||
exports.randomFileName = randomFileName;
|
||
|
||
// Common wrapper for all Unix-like commands that performs glob expansion,
|
||
// command-logging, and other nice things
|
||
function wrap(cmd, fn, options) {
|
||
options = options || {};
|
||
return function () {
|
||
var retValue = null;
|
||
|
||
state.currentCmd = cmd;
|
||
state.error = null;
|
||
state.errorCode = 0;
|
||
|
||
try {
|
||
var args = [].slice.call(arguments, 0);
|
||
|
||
// Log the command to stderr, if appropriate
|
||
if (config.verbose) {
|
||
console.error.apply(console, [cmd].concat(args));
|
||
}
|
||
|
||
// If this is coming from a pipe, let's set the pipedValue (otherwise, set
|
||
// it to the empty string)
|
||
state.pipedValue = (this && typeof this.stdout === 'string') ? this.stdout : '';
|
||
|
||
if (options.unix === false) { // this branch is for exec()
|
||
retValue = fn.apply(this, args);
|
||
} else { // and this branch is for everything else
|
||
if (isObject(args[0]) && args[0].constructor.name === 'Object') {
|
||
// a no-op, allowing the syntax `touch({'-r': file}, ...)`
|
||
} else if (args.length === 0 || typeof args[0] !== 'string' || args[0].length <= 1 || args[0][0] !== '-') {
|
||
args.unshift(''); // only add dummy option if '-option' not already present
|
||
}
|
||
|
||
// flatten out arrays that are arguments, to make the syntax:
|
||
// `cp([file1, file2, file3], dest);`
|
||
// equivalent to:
|
||
// `cp(file1, file2, file3, dest);`
|
||
args = args.reduce(function (accum, cur) {
|
||
if (Array.isArray(cur)) {
|
||
return accum.concat(cur);
|
||
}
|
||
accum.push(cur);
|
||
return accum;
|
||
}, []);
|
||
|
||
// Convert ShellStrings (basically just String objects) to regular strings
|
||
args = args.map(function (arg) {
|
||
if (isObject(arg) && arg.constructor.name === 'String') {
|
||
return arg.toString();
|
||
}
|
||
return arg;
|
||
});
|
||
|
||
// Expand the '~' if appropriate
|
||
var homeDir = os.homedir();
|
||
args = args.map(function (arg) {
|
||
if (typeof arg === 'string' && arg.slice(0, 2) === '~/' || arg === '~') {
|
||
return arg.replace(/^~/, homeDir);
|
||
}
|
||
return arg;
|
||
});
|
||
|
||
// Perform glob-expansion on all arguments after globStart, but preserve
|
||
// the arguments before it (like regexes for sed and grep)
|
||
if (!config.noglob && options.allowGlobbing === true) {
|
||
args = args.slice(0, options.globStart).concat(expand(args.slice(options.globStart)));
|
||
}
|
||
|
||
try {
|
||
// parse options if options are provided
|
||
if (isObject(options.cmdOptions)) {
|
||
args[0] = parseOptions(args[0], options.cmdOptions);
|
||
}
|
||
|
||
retValue = fn.apply(this, args);
|
||
} catch (e) {
|
||
/* istanbul ignore else */
|
||
if (e.msg === 'earlyExit') {
|
||
retValue = e.retValue;
|
||
} else {
|
||
throw e; // this is probably a bug that should be thrown up the call stack
|
||
}
|
||
}
|
||
}
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
if (!state.error) {
|
||
// If state.error hasn't been set it's an error thrown by Node, not us - probably a bug...
|
||
e.name = 'ShellJSInternalError';
|
||
throw e;
|
||
}
|
||
if (config.fatal) throw e;
|
||
}
|
||
|
||
if (options.wrapOutput &&
|
||
(typeof retValue === 'string' || Array.isArray(retValue))) {
|
||
retValue = new ShellString(retValue, state.error, state.errorCode);
|
||
}
|
||
|
||
state.currentCmd = 'shell.js';
|
||
return retValue;
|
||
};
|
||
} // wrap
|
||
exports.wrap = wrap;
|
||
|
||
// This returns all the input that is piped into the current command (or the
|
||
// empty string, if this isn't on the right-hand side of a pipe
|
||
function _readFromPipe() {
|
||
return state.pipedValue;
|
||
}
|
||
exports.readFromPipe = _readFromPipe;
|
||
|
||
var DEFAULT_WRAP_OPTIONS = {
|
||
allowGlobbing: true,
|
||
canReceivePipe: false,
|
||
cmdOptions: null,
|
||
globStart: 1,
|
||
pipeOnly: false,
|
||
wrapOutput: true,
|
||
unix: true,
|
||
};
|
||
|
||
// This is populated during plugin registration
|
||
var pipeMethods = [];
|
||
|
||
// Register a new ShellJS command
|
||
function _register(name, implementation, wrapOptions) {
|
||
wrapOptions = wrapOptions || {};
|
||
|
||
// Validate options
|
||
Object.keys(wrapOptions).forEach(function (option) {
|
||
if (!DEFAULT_WRAP_OPTIONS.hasOwnProperty(option)) {
|
||
throw new Error("Unknown option '" + option + "'");
|
||
}
|
||
if (typeof wrapOptions[option] !== typeof DEFAULT_WRAP_OPTIONS[option]) {
|
||
throw new TypeError("Unsupported type '" + typeof wrapOptions[option] +
|
||
"' for option '" + option + "'");
|
||
}
|
||
});
|
||
|
||
// If an option isn't specified, use the default
|
||
wrapOptions = Object.assign({}, DEFAULT_WRAP_OPTIONS, wrapOptions);
|
||
|
||
if (shell.hasOwnProperty(name)) {
|
||
throw new Error('Command `' + name + '` already exists');
|
||
}
|
||
|
||
if (wrapOptions.pipeOnly) {
|
||
wrapOptions.canReceivePipe = true;
|
||
shellMethods[name] = wrap(name, implementation, wrapOptions);
|
||
} else {
|
||
shell[name] = wrap(name, implementation, wrapOptions);
|
||
}
|
||
|
||
if (wrapOptions.canReceivePipe) {
|
||
pipeMethods.push(name);
|
||
}
|
||
}
|
||
exports.register = _register;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/cp.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/cp.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('cp', _cp, {
|
||
cmdOptions: {
|
||
'f': '!no_force',
|
||
'n': 'no_force',
|
||
'u': 'update',
|
||
'R': 'recursive',
|
||
'r': 'recursive',
|
||
'L': 'followsymlink',
|
||
'P': 'noFollowsymlink',
|
||
},
|
||
wrapOutput: false,
|
||
});
|
||
|
||
// Buffered file copy, synchronous
|
||
// (Using readFileSync() + writeFileSync() could easily cause a memory overflow
|
||
// with large files)
|
||
function copyFileSync(srcFile, destFile, options) {
|
||
if (!fs.existsSync(srcFile)) {
|
||
common.error('copyFileSync: no such file or directory: ' + srcFile);
|
||
}
|
||
|
||
var isWindows = process.platform === 'win32';
|
||
|
||
// Check the mtimes of the files if the '-u' flag is provided
|
||
try {
|
||
if (options.update && common.statFollowLinks(srcFile).mtime < fs.statSync(destFile).mtime) {
|
||
return;
|
||
}
|
||
} catch (e) {
|
||
// If we're here, destFile probably doesn't exist, so just do a normal copy
|
||
}
|
||
|
||
if (common.statNoFollowLinks(srcFile).isSymbolicLink() && !options.followsymlink) {
|
||
try {
|
||
common.statNoFollowLinks(destFile);
|
||
common.unlinkSync(destFile); // re-link it
|
||
} catch (e) {
|
||
// it doesn't exist, so no work needs to be done
|
||
}
|
||
|
||
var symlinkFull = fs.readlinkSync(srcFile);
|
||
fs.symlinkSync(symlinkFull, destFile, isWindows ? 'junction' : null);
|
||
} else {
|
||
var buf = common.buffer();
|
||
var bufLength = buf.length;
|
||
var bytesRead = bufLength;
|
||
var pos = 0;
|
||
var fdr = null;
|
||
var fdw = null;
|
||
|
||
try {
|
||
fdr = fs.openSync(srcFile, 'r');
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('copyFileSync: could not read src file (' + srcFile + ')');
|
||
}
|
||
|
||
try {
|
||
fdw = fs.openSync(destFile, 'w');
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('copyFileSync: could not write to dest file (code=' + e.code + '):' + destFile);
|
||
}
|
||
|
||
while (bytesRead === bufLength) {
|
||
bytesRead = fs.readSync(fdr, buf, 0, bufLength, pos);
|
||
fs.writeSync(fdw, buf, 0, bytesRead);
|
||
pos += bytesRead;
|
||
}
|
||
|
||
fs.closeSync(fdr);
|
||
fs.closeSync(fdw);
|
||
|
||
fs.chmodSync(destFile, common.statFollowLinks(srcFile).mode);
|
||
}
|
||
}
|
||
|
||
// Recursively copies 'sourceDir' into 'destDir'
|
||
// Adapted from https://github.com/ryanmcgrath/wrench-js
|
||
//
|
||
// Copyright (c) 2010 Ryan McGrath
|
||
// Copyright (c) 2012 Artur Adib
|
||
//
|
||
// Licensed under the MIT License
|
||
// http://www.opensource.org/licenses/mit-license.php
|
||
function cpdirSyncRecursive(sourceDir, destDir, currentDepth, opts) {
|
||
if (!opts) opts = {};
|
||
|
||
// Ensure there is not a run away recursive copy
|
||
if (currentDepth >= common.config.maxdepth) return;
|
||
currentDepth++;
|
||
|
||
var isWindows = process.platform === 'win32';
|
||
|
||
// Create the directory where all our junk is moving to; read the mode of the
|
||
// source directory and mirror it
|
||
try {
|
||
fs.mkdirSync(destDir);
|
||
} catch (e) {
|
||
// if the directory already exists, that's okay
|
||
if (e.code !== 'EEXIST') throw e;
|
||
}
|
||
|
||
var files = fs.readdirSync(sourceDir);
|
||
|
||
for (var i = 0; i < files.length; i++) {
|
||
var srcFile = sourceDir + '/' + files[i];
|
||
var destFile = destDir + '/' + files[i];
|
||
var srcFileStat = common.statNoFollowLinks(srcFile);
|
||
|
||
var symlinkFull;
|
||
if (opts.followsymlink) {
|
||
if (cpcheckcycle(sourceDir, srcFile)) {
|
||
// Cycle link found.
|
||
console.error('Cycle link found.');
|
||
symlinkFull = fs.readlinkSync(srcFile);
|
||
fs.symlinkSync(symlinkFull, destFile, isWindows ? 'junction' : null);
|
||
continue;
|
||
}
|
||
}
|
||
if (srcFileStat.isDirectory()) {
|
||
/* recursion this thing right on back. */
|
||
cpdirSyncRecursive(srcFile, destFile, currentDepth, opts);
|
||
} else if (srcFileStat.isSymbolicLink() && !opts.followsymlink) {
|
||
symlinkFull = fs.readlinkSync(srcFile);
|
||
try {
|
||
common.statNoFollowLinks(destFile);
|
||
common.unlinkSync(destFile); // re-link it
|
||
} catch (e) {
|
||
// it doesn't exist, so no work needs to be done
|
||
}
|
||
fs.symlinkSync(symlinkFull, destFile, isWindows ? 'junction' : null);
|
||
} else if (srcFileStat.isSymbolicLink() && opts.followsymlink) {
|
||
srcFileStat = common.statFollowLinks(srcFile);
|
||
if (srcFileStat.isDirectory()) {
|
||
cpdirSyncRecursive(srcFile, destFile, currentDepth, opts);
|
||
} else {
|
||
copyFileSync(srcFile, destFile, opts);
|
||
}
|
||
} else {
|
||
/* At this point, we've hit a file actually worth copying... so copy it on over. */
|
||
if (fs.existsSync(destFile) && opts.no_force) {
|
||
common.log('skipping existing file: ' + files[i]);
|
||
} else {
|
||
copyFileSync(srcFile, destFile, opts);
|
||
}
|
||
}
|
||
} // for files
|
||
|
||
// finally change the mode for the newly created directory (otherwise, we
|
||
// couldn't add files to a read-only directory).
|
||
var checkDir = common.statFollowLinks(sourceDir);
|
||
fs.chmodSync(destDir, checkDir.mode);
|
||
} // cpdirSyncRecursive
|
||
|
||
// Checks if cureent file was created recently
|
||
function checkRecentCreated(sources, index) {
|
||
var lookedSource = sources[index];
|
||
return sources.slice(0, index).some(function (src) {
|
||
return path.basename(src) === path.basename(lookedSource);
|
||
});
|
||
}
|
||
|
||
function cpcheckcycle(sourceDir, srcFile) {
|
||
var srcFileStat = common.statNoFollowLinks(srcFile);
|
||
if (srcFileStat.isSymbolicLink()) {
|
||
// Do cycle check. For example:
|
||
// $ mkdir -p 1/2/3/4
|
||
// $ cd 1/2/3/4
|
||
// $ ln -s ../../3 link
|
||
// $ cd ../../../..
|
||
// $ cp -RL 1 copy
|
||
var cyclecheck = common.statFollowLinks(srcFile);
|
||
if (cyclecheck.isDirectory()) {
|
||
var sourcerealpath = fs.realpathSync(sourceDir);
|
||
var symlinkrealpath = fs.realpathSync(srcFile);
|
||
var re = new RegExp(symlinkrealpath);
|
||
if (re.test(sourcerealpath)) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
//@
|
||
//@ ### cp([options,] source [, source ...], dest)
|
||
//@ ### cp([options,] source_array, dest)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-f`: force (default behavior)
|
||
//@ + `-n`: no-clobber
|
||
//@ + `-u`: only copy if `source` is newer than `dest`
|
||
//@ + `-r`, `-R`: recursive
|
||
//@ + `-L`: follow symlinks
|
||
//@ + `-P`: don't follow symlinks
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ cp('file1', 'dir1');
|
||
//@ cp('-R', 'path/to/dir/', '~/newCopy/');
|
||
//@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
|
||
//@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Copies files.
|
||
function _cp(options, sources, dest) {
|
||
// If we're missing -R, it actually implies -L (unless -P is explicit)
|
||
if (options.followsymlink) {
|
||
options.noFollowsymlink = false;
|
||
}
|
||
if (!options.recursive && !options.noFollowsymlink) {
|
||
options.followsymlink = true;
|
||
}
|
||
|
||
// Get sources, dest
|
||
if (arguments.length < 3) {
|
||
common.error('missing <source> and/or <dest>');
|
||
} else {
|
||
sources = [].slice.call(arguments, 1, arguments.length - 1);
|
||
dest = arguments[arguments.length - 1];
|
||
}
|
||
|
||
var destExists = fs.existsSync(dest);
|
||
var destStat = destExists && common.statFollowLinks(dest);
|
||
|
||
// Dest is not existing dir, but multiple sources given
|
||
if ((!destExists || !destStat.isDirectory()) && sources.length > 1) {
|
||
common.error('dest is not a directory (too many sources)');
|
||
}
|
||
|
||
// Dest is an existing file, but -n is given
|
||
if (destExists && destStat.isFile() && options.no_force) {
|
||
return new common.ShellString('', '', 0);
|
||
}
|
||
|
||
sources.forEach(function (src, srcIndex) {
|
||
if (!fs.existsSync(src)) {
|
||
if (src === '') src = "''"; // if src was empty string, display empty string
|
||
common.error('no such file or directory: ' + src, { continue: true });
|
||
return; // skip file
|
||
}
|
||
var srcStat = common.statFollowLinks(src);
|
||
if (!options.noFollowsymlink && srcStat.isDirectory()) {
|
||
if (!options.recursive) {
|
||
// Non-Recursive
|
||
common.error("omitting directory '" + src + "'", { continue: true });
|
||
} else {
|
||
// Recursive
|
||
// 'cp /a/source dest' should create 'source' in 'dest'
|
||
var newDest = (destStat && destStat.isDirectory()) ?
|
||
path.join(dest, path.basename(src)) :
|
||
dest;
|
||
|
||
try {
|
||
common.statFollowLinks(path.dirname(dest));
|
||
cpdirSyncRecursive(src, newDest, 0, { no_force: options.no_force, followsymlink: options.followsymlink });
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error("cannot create directory '" + dest + "': No such file or directory");
|
||
}
|
||
}
|
||
} else {
|
||
// If here, src is a file
|
||
|
||
// When copying to '/path/dir':
|
||
// thisDest = '/path/dir/file1'
|
||
var thisDest = dest;
|
||
if (destStat && destStat.isDirectory()) {
|
||
thisDest = path.normalize(dest + '/' + path.basename(src));
|
||
}
|
||
|
||
var thisDestExists = fs.existsSync(thisDest);
|
||
if (thisDestExists && checkRecentCreated(sources, srcIndex)) {
|
||
// cannot overwrite file created recently in current execution, but we want to continue copying other files
|
||
if (!options.no_force) {
|
||
common.error("will not overwrite just-created '" + thisDest + "' with '" + src + "'", { continue: true });
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (thisDestExists && options.no_force) {
|
||
return; // skip file
|
||
}
|
||
|
||
if (path.relative(src, thisDest) === '') {
|
||
// a file cannot be copied to itself, but we want to continue copying other files
|
||
common.error("'" + thisDest + "' and '" + src + "' are the same file", { continue: true });
|
||
return;
|
||
}
|
||
|
||
copyFileSync(src, thisDest, options);
|
||
}
|
||
}); // forEach(src)
|
||
|
||
return new common.ShellString('', common.state.error, common.state.errorCode);
|
||
}
|
||
module.exports = _cp;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/dirs.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/dirs.js ***!
|
||
\******************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var _cd = __webpack_require__(/*! ./cd */ "./node_modules/shelljs/src/cd.js");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('dirs', _dirs, {
|
||
wrapOutput: false,
|
||
});
|
||
common.register('pushd', _pushd, {
|
||
wrapOutput: false,
|
||
});
|
||
common.register('popd', _popd, {
|
||
wrapOutput: false,
|
||
});
|
||
|
||
// Pushd/popd/dirs internals
|
||
var _dirStack = [];
|
||
|
||
function _isStackIndex(index) {
|
||
return (/^[\-+]\d+$/).test(index);
|
||
}
|
||
|
||
function _parseStackIndex(index) {
|
||
if (_isStackIndex(index)) {
|
||
if (Math.abs(index) < _dirStack.length + 1) { // +1 for pwd
|
||
return (/^-/).test(index) ? Number(index) - 1 : Number(index);
|
||
}
|
||
common.error(index + ': directory stack index out of range');
|
||
} else {
|
||
common.error(index + ': invalid number');
|
||
}
|
||
}
|
||
|
||
function _actualDirStack() {
|
||
return [process.cwd()].concat(_dirStack);
|
||
}
|
||
|
||
//@
|
||
//@ ### pushd([options,] [dir | '-N' | '+N'])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated.
|
||
//@ + `-q`: Supresses output to the console.
|
||
//@
|
||
//@ Arguments:
|
||
//@
|
||
//@ + `dir`: Sets the current working directory to the top of the stack, then executes the equivalent of `cd dir`.
|
||
//@ + `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
|
||
//@ + `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ // process.cwd() === '/usr'
|
||
//@ pushd('/etc'); // Returns /etc /usr
|
||
//@ pushd('+1'); // Returns /usr /etc
|
||
//@ ```
|
||
//@
|
||
//@ Save the current directory on the top of the directory stack and then `cd` to `dir`. With no arguments, `pushd` exchanges the top two directories. Returns an array of paths in the stack.
|
||
function _pushd(options, dir) {
|
||
if (_isStackIndex(options)) {
|
||
dir = options;
|
||
options = '';
|
||
}
|
||
|
||
options = common.parseOptions(options, {
|
||
'n': 'no-cd',
|
||
'q': 'quiet',
|
||
});
|
||
|
||
var dirs = _actualDirStack();
|
||
|
||
if (dir === '+0') {
|
||
return dirs; // +0 is a noop
|
||
} else if (!dir) {
|
||
if (dirs.length > 1) {
|
||
dirs = dirs.splice(1, 1).concat(dirs);
|
||
} else {
|
||
return common.error('no other directory');
|
||
}
|
||
} else if (_isStackIndex(dir)) {
|
||
var n = _parseStackIndex(dir);
|
||
dirs = dirs.slice(n).concat(dirs.slice(0, n));
|
||
} else {
|
||
if (options['no-cd']) {
|
||
dirs.splice(1, 0, dir);
|
||
} else {
|
||
dirs.unshift(dir);
|
||
}
|
||
}
|
||
|
||
if (options['no-cd']) {
|
||
dirs = dirs.slice(1);
|
||
} else {
|
||
dir = path.resolve(dirs.shift());
|
||
_cd('', dir);
|
||
}
|
||
|
||
_dirStack = dirs;
|
||
return _dirs(options.quiet ? '-q' : '');
|
||
}
|
||
exports.pushd = _pushd;
|
||
|
||
//@
|
||
//@
|
||
//@ ### popd([options,] ['-N' | '+N'])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n`: Suppress the normal directory change when removing directories from the stack, so that only the stack is manipulated.
|
||
//@ + `-q`: Supresses output to the console.
|
||
//@
|
||
//@ Arguments:
|
||
//@
|
||
//@ + `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero.
|
||
//@ + `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero.
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ echo(process.cwd()); // '/usr'
|
||
//@ pushd('/etc'); // '/etc /usr'
|
||
//@ echo(process.cwd()); // '/etc'
|
||
//@ popd(); // '/usr'
|
||
//@ echo(process.cwd()); // '/usr'
|
||
//@ ```
|
||
//@
|
||
//@ When no arguments are given, `popd` removes the top directory from the stack and performs a `cd` to the new top directory. The elements are numbered from 0, starting at the first directory listed with dirs (i.e., `popd` is equivalent to `popd +0`). Returns an array of paths in the stack.
|
||
function _popd(options, index) {
|
||
if (_isStackIndex(options)) {
|
||
index = options;
|
||
options = '';
|
||
}
|
||
|
||
options = common.parseOptions(options, {
|
||
'n': 'no-cd',
|
||
'q': 'quiet',
|
||
});
|
||
|
||
if (!_dirStack.length) {
|
||
return common.error('directory stack empty');
|
||
}
|
||
|
||
index = _parseStackIndex(index || '+0');
|
||
|
||
if (options['no-cd'] || index > 0 || _dirStack.length + index === 0) {
|
||
index = index > 0 ? index - 1 : index;
|
||
_dirStack.splice(index, 1);
|
||
} else {
|
||
var dir = path.resolve(_dirStack.shift());
|
||
_cd('', dir);
|
||
}
|
||
|
||
return _dirs(options.quiet ? '-q' : '');
|
||
}
|
||
exports.popd = _popd;
|
||
|
||
//@
|
||
//@
|
||
//@ ### dirs([options | '+N' | '-N'])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-c`: Clears the directory stack by deleting all of the elements.
|
||
//@ + `-q`: Supresses output to the console.
|
||
//@
|
||
//@ Arguments:
|
||
//@
|
||
//@ + `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.
|
||
//@ + `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero.
|
||
//@
|
||
//@ Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if `+N` or `-N` was specified.
|
||
//@
|
||
//@ See also: `pushd`, `popd`
|
||
function _dirs(options, index) {
|
||
if (_isStackIndex(options)) {
|
||
index = options;
|
||
options = '';
|
||
}
|
||
|
||
options = common.parseOptions(options, {
|
||
'c': 'clear',
|
||
'q': 'quiet',
|
||
});
|
||
|
||
if (options.clear) {
|
||
_dirStack = [];
|
||
return _dirStack;
|
||
}
|
||
|
||
var stack = _actualDirStack();
|
||
|
||
if (index) {
|
||
index = _parseStackIndex(index);
|
||
|
||
if (index < 0) {
|
||
index = stack.length + index;
|
||
}
|
||
|
||
if (!options.quiet) {
|
||
common.log(stack[index]);
|
||
}
|
||
return stack[index];
|
||
}
|
||
|
||
if (!options.quiet) {
|
||
common.log(stack.join(' '));
|
||
}
|
||
|
||
return stack;
|
||
}
|
||
exports.dirs = _dirs;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/echo.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/echo.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var format = __webpack_require__(/*! util */ "util").format;
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('echo', _echo, {
|
||
allowGlobbing: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### echo([options,] string [, string ...])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-e`: interpret backslash escapes (default)
|
||
//@ + `-n`: remove trailing newline from output
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ echo('hello world');
|
||
//@ var str = echo('hello world');
|
||
//@ echo('-n', 'no newline at end');
|
||
//@ ```
|
||
//@
|
||
//@ Prints `string` to stdout, and returns string with additional utility methods
|
||
//@ like `.to()`.
|
||
function _echo(opts) {
|
||
// allow strings starting with '-', see issue #20
|
||
var messages = [].slice.call(arguments, opts ? 0 : 1);
|
||
var options = {};
|
||
|
||
// If the first argument starts with '-', parse it as options string.
|
||
// If parseOptions throws, it wasn't an options string.
|
||
try {
|
||
options = common.parseOptions(messages[0], {
|
||
'e': 'escapes',
|
||
'n': 'no_newline',
|
||
}, {
|
||
silent: true,
|
||
});
|
||
|
||
// Allow null to be echoed
|
||
if (messages[0]) {
|
||
messages.shift();
|
||
}
|
||
} catch (_) {
|
||
// Clear out error if an error occurred
|
||
common.state.error = null;
|
||
}
|
||
|
||
var output = format.apply(null, messages);
|
||
|
||
// Add newline if -n is not passed.
|
||
if (!options.no_newline) {
|
||
output += '\n';
|
||
}
|
||
|
||
process.stdout.write(output);
|
||
|
||
return output;
|
||
}
|
||
|
||
module.exports = _echo;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/error.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/error.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
//@
|
||
//@ ### error()
|
||
//@
|
||
//@ Tests if error occurred in the last command. Returns a truthy value if an
|
||
//@ error returned, or a falsy value otherwise.
|
||
//@
|
||
//@ **Note**: do not rely on the
|
||
//@ return value to be an error message. If you need the last error message, use
|
||
//@ the `.stderr` attribute from the last command's return value instead.
|
||
function error() {
|
||
return common.state.error;
|
||
}
|
||
module.exports = error;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/exec-child.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/shelljs/src/exec-child.js ***!
|
||
\************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
/* module decorator */ module = __webpack_require__.nmd(module);
|
||
if (__webpack_require__.c[__webpack_require__.s] !== module) {
|
||
throw new Error('This file should not be required');
|
||
}
|
||
|
||
var childProcess = __webpack_require__(/*! child_process */ "child_process");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
var paramFilePath = process.argv[2];
|
||
|
||
var serializedParams = fs.readFileSync(paramFilePath, 'utf8');
|
||
var params = JSON.parse(serializedParams);
|
||
|
||
var cmd = params.command;
|
||
var execOptions = params.execOptions;
|
||
var pipe = params.pipe;
|
||
var stdoutFile = params.stdoutFile;
|
||
var stderrFile = params.stderrFile;
|
||
|
||
var c = childProcess.exec(cmd, execOptions, function (err) {
|
||
if (!err) {
|
||
process.exitCode = 0;
|
||
} else if (err.code === undefined) {
|
||
process.exitCode = 1;
|
||
} else {
|
||
process.exitCode = err.code;
|
||
}
|
||
});
|
||
|
||
var stdoutStream = fs.createWriteStream(stdoutFile);
|
||
var stderrStream = fs.createWriteStream(stderrFile);
|
||
|
||
c.stdout.pipe(stdoutStream);
|
||
c.stderr.pipe(stderrStream);
|
||
c.stdout.pipe(process.stdout);
|
||
c.stderr.pipe(process.stderr);
|
||
|
||
if (pipe) {
|
||
c.stdin.end(pipe);
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/exec.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/exec.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var _tempDir = __webpack_require__(/*! ./tempdir */ "./node_modules/shelljs/src/tempdir.js").tempDir;
|
||
var _pwd = __webpack_require__(/*! ./pwd */ "./node_modules/shelljs/src/pwd.js");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var child = __webpack_require__(/*! child_process */ "child_process");
|
||
|
||
var DEFAULT_MAXBUFFER_SIZE = 20 * 1024 * 1024;
|
||
var DEFAULT_ERROR_CODE = 1;
|
||
|
||
common.register('exec', _exec, {
|
||
unix: false,
|
||
canReceivePipe: true,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
// We use this function to run `exec` synchronously while also providing realtime
|
||
// output.
|
||
function execSync(cmd, opts, pipe) {
|
||
if (!common.config.execPath) {
|
||
common.error('Unable to find a path to the node binary. Please manually set config.execPath');
|
||
}
|
||
|
||
var tempDir = _tempDir();
|
||
var paramsFile = path.resolve(tempDir + '/' + common.randomFileName());
|
||
var stderrFile = path.resolve(tempDir + '/' + common.randomFileName());
|
||
var stdoutFile = path.resolve(tempDir + '/' + common.randomFileName());
|
||
|
||
opts = common.extend({
|
||
silent: common.config.silent,
|
||
cwd: _pwd().toString(),
|
||
env: process.env,
|
||
maxBuffer: DEFAULT_MAXBUFFER_SIZE,
|
||
encoding: 'utf8',
|
||
}, opts);
|
||
|
||
if (fs.existsSync(paramsFile)) common.unlinkSync(paramsFile);
|
||
if (fs.existsSync(stderrFile)) common.unlinkSync(stderrFile);
|
||
if (fs.existsSync(stdoutFile)) common.unlinkSync(stdoutFile);
|
||
|
||
opts.cwd = path.resolve(opts.cwd);
|
||
|
||
var paramsToSerialize = {
|
||
command: cmd,
|
||
execOptions: opts,
|
||
pipe: pipe,
|
||
stdoutFile: stdoutFile,
|
||
stderrFile: stderrFile,
|
||
};
|
||
|
||
fs.writeFileSync(paramsFile, JSON.stringify(paramsToSerialize), 'utf8');
|
||
|
||
var execArgs = [
|
||
path.join(__dirname, 'exec-child.js'),
|
||
paramsFile,
|
||
];
|
||
|
||
/* istanbul ignore else */
|
||
if (opts.silent) {
|
||
opts.stdio = 'ignore';
|
||
} else {
|
||
opts.stdio = [0, 1, 2];
|
||
}
|
||
|
||
var code = 0;
|
||
|
||
// Welcome to the future
|
||
try {
|
||
// Bad things if we pass in a `shell` option to child_process.execFileSync,
|
||
// so we need to explicitly remove it here.
|
||
delete opts.shell;
|
||
|
||
child.execFileSync(common.config.execPath, execArgs, opts);
|
||
} catch (e) {
|
||
// Commands with non-zero exit code raise an exception.
|
||
code = e.status || DEFAULT_ERROR_CODE;
|
||
}
|
||
|
||
// fs.readFileSync uses buffer encoding by default, so call
|
||
// it without the encoding option if the encoding is 'buffer'.
|
||
// Also, if the exec timeout is too short for node to start up,
|
||
// the files will not be created, so these calls will throw.
|
||
var stdout = '';
|
||
var stderr = '';
|
||
if (opts.encoding === 'buffer') {
|
||
stdout = fs.readFileSync(stdoutFile);
|
||
stderr = fs.readFileSync(stderrFile);
|
||
} else {
|
||
stdout = fs.readFileSync(stdoutFile, opts.encoding);
|
||
stderr = fs.readFileSync(stderrFile, opts.encoding);
|
||
}
|
||
|
||
// No biggie if we can't erase the files now -- they're in a temp dir anyway
|
||
try { common.unlinkSync(paramsFile); } catch (e) {}
|
||
try { common.unlinkSync(stderrFile); } catch (e) {}
|
||
try { common.unlinkSync(stdoutFile); } catch (e) {}
|
||
|
||
if (code !== 0) {
|
||
// Note: `silent` should be unconditionally true to avoid double-printing
|
||
// the command's stderr, and to avoid printing any stderr when the user has
|
||
// set `shell.config.silent`.
|
||
common.error(stderr, code, { continue: true, silent: true });
|
||
}
|
||
var obj = common.ShellString(stdout, stderr, code);
|
||
return obj;
|
||
} // execSync()
|
||
|
||
// Wrapper around exec() to enable echoing output to console in real time
|
||
function execAsync(cmd, opts, pipe, callback) {
|
||
opts = common.extend({
|
||
silent: common.config.silent,
|
||
cwd: _pwd().toString(),
|
||
env: process.env,
|
||
maxBuffer: DEFAULT_MAXBUFFER_SIZE,
|
||
encoding: 'utf8',
|
||
}, opts);
|
||
|
||
var c = child.exec(cmd, opts, function (err, stdout, stderr) {
|
||
if (callback) {
|
||
if (!err) {
|
||
callback(0, stdout, stderr);
|
||
} else if (err.code === undefined) {
|
||
// See issue #536
|
||
/* istanbul ignore next */
|
||
callback(1, stdout, stderr);
|
||
} else {
|
||
callback(err.code, stdout, stderr);
|
||
}
|
||
}
|
||
});
|
||
|
||
if (pipe) c.stdin.end(pipe);
|
||
|
||
if (!opts.silent) {
|
||
c.stdout.pipe(process.stdout);
|
||
c.stderr.pipe(process.stderr);
|
||
}
|
||
|
||
return c;
|
||
}
|
||
|
||
//@
|
||
//@ ### exec(command [, options] [, callback])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `async`: Asynchronous execution. If a callback is provided, it will be set to
|
||
//@ `true`, regardless of the passed value (default: `false`).
|
||
//@ + `silent`: Do not echo program output to console (default: `false`).
|
||
//@ + `encoding`: Character encoding to use. Affects the values returned to stdout and stderr, and
|
||
//@ what is written to stdout and stderr when not in silent mode (default: `'utf8'`).
|
||
//@ + and any option available to Node.js's
|
||
//@ [`child_process.exec()`](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var version = exec('node --version', {silent:true}).stdout;
|
||
//@
|
||
//@ var child = exec('some_long_running_process', {async:true});
|
||
//@ child.stdout.on('data', function(data) {
|
||
//@ /* ... do something with data ... */
|
||
//@ });
|
||
//@
|
||
//@ exec('some_long_running_process', function(code, stdout, stderr) {
|
||
//@ console.log('Exit code:', code);
|
||
//@ console.log('Program output:', stdout);
|
||
//@ console.log('Program stderr:', stderr);
|
||
//@ });
|
||
//@ ```
|
||
//@
|
||
//@ Executes the given `command` _synchronously_, unless otherwise specified. When in synchronous
|
||
//@ mode, this returns a `ShellString` (compatible with ShellJS v0.6.x, which returns an object
|
||
//@ of the form `{ code:..., stdout:... , stderr:... }`). Otherwise, this returns the child process
|
||
//@ object, and the `callback` receives the arguments `(code, stdout, stderr)`.
|
||
//@
|
||
//@ Not seeing the behavior you want? `exec()` runs everything through `sh`
|
||
//@ by default (or `cmd.exe` on Windows), which differs from `bash`. If you
|
||
//@ need bash-specific behavior, try out the `{shell: 'path/to/bash'}` option.
|
||
function _exec(command, options, callback) {
|
||
options = options || {};
|
||
if (!command) common.error('must specify command');
|
||
|
||
var pipe = common.readFromPipe();
|
||
|
||
// Callback is defined instead of options.
|
||
if (typeof options === 'function') {
|
||
callback = options;
|
||
options = { async: true };
|
||
}
|
||
|
||
// Callback is defined with options.
|
||
if (typeof options === 'object' && typeof callback === 'function') {
|
||
options.async = true;
|
||
}
|
||
|
||
options = common.extend({
|
||
silent: common.config.silent,
|
||
async: false,
|
||
}, options);
|
||
|
||
if (options.async) {
|
||
return execAsync(command, options, pipe, callback);
|
||
} else {
|
||
return execSync(command, options, pipe);
|
||
}
|
||
}
|
||
module.exports = _exec;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/find.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/find.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var _ls = __webpack_require__(/*! ./ls */ "./node_modules/shelljs/src/ls.js");
|
||
|
||
common.register('find', _find, {});
|
||
|
||
//@
|
||
//@ ### find(path [, path ...])
|
||
//@ ### find(path_array)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ find('src', 'lib');
|
||
//@ find(['src', 'lib']); // same as above
|
||
//@ find('.').filter(function(file) { return file.match(/\.js$/); });
|
||
//@ ```
|
||
//@
|
||
//@ Returns array of all files (however deep) in the given paths.
|
||
//@
|
||
//@ The main difference from `ls('-R', path)` is that the resulting file names
|
||
//@ include the base directories (e.g., `lib/resources/file1` instead of just `file1`).
|
||
function _find(options, paths) {
|
||
if (!paths) {
|
||
common.error('no path specified');
|
||
} else if (typeof paths === 'string') {
|
||
paths = [].slice.call(arguments, 1);
|
||
}
|
||
|
||
var list = [];
|
||
|
||
function pushFile(file) {
|
||
if (process.platform === 'win32') {
|
||
file = file.replace(/\\/g, '/');
|
||
}
|
||
list.push(file);
|
||
}
|
||
|
||
// why not simply do `ls('-R', paths)`? because the output wouldn't give the base dirs
|
||
// to get the base dir in the output, we need instead `ls('-R', 'dir/*')` for every directory
|
||
|
||
paths.forEach(function (file) {
|
||
var stat;
|
||
try {
|
||
stat = common.statFollowLinks(file);
|
||
} catch (e) {
|
||
common.error('no such file or directory: ' + file);
|
||
}
|
||
|
||
pushFile(file);
|
||
|
||
if (stat.isDirectory()) {
|
||
_ls({ recursive: true, all: true }, file).forEach(function (subfile) {
|
||
pushFile(path.join(file, subfile));
|
||
});
|
||
}
|
||
});
|
||
|
||
return list;
|
||
}
|
||
module.exports = _find;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/grep.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/grep.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('grep', _grep, {
|
||
globStart: 2, // don't glob-expand the regex
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'v': 'inverse',
|
||
'l': 'nameOnly',
|
||
'i': 'ignoreCase',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### grep([options,] regex_filter, file [, file ...])
|
||
//@ ### grep([options,] regex_filter, file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-v`: Invert `regex_filter` (only print non-matching lines).
|
||
//@ + `-l`: Print only filenames of matching files.
|
||
//@ + `-i`: Ignore case.
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ grep('-v', 'GLOBAL_VARIABLE', '*.js');
|
||
//@ grep('GLOBAL_VARIABLE', '*.js');
|
||
//@ ```
|
||
//@
|
||
//@ Reads input string from given files and returns a string containing all lines of the
|
||
//@ file that match the given `regex_filter`.
|
||
function _grep(options, regex, files) {
|
||
// Check if this is coming from a pipe
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!files && !pipe) common.error('no paths given', 2);
|
||
|
||
files = [].slice.call(arguments, 2);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var grep = [];
|
||
if (options.ignoreCase) {
|
||
regex = new RegExp(regex, 'i');
|
||
}
|
||
files.forEach(function (file) {
|
||
if (!fs.existsSync(file) && file !== '-') {
|
||
common.error('no such file or directory: ' + file, 2, { continue: true });
|
||
return;
|
||
}
|
||
|
||
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
|
||
if (options.nameOnly) {
|
||
if (contents.match(regex)) {
|
||
grep.push(file);
|
||
}
|
||
} else {
|
||
var lines = contents.split('\n');
|
||
lines.forEach(function (line) {
|
||
var matched = line.match(regex);
|
||
if ((options.inverse && !matched) || (!options.inverse && matched)) {
|
||
grep.push(line);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
return grep.join('\n') + '\n';
|
||
}
|
||
module.exports = _grep;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/head.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/head.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('head', _head, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'n': 'numLines',
|
||
},
|
||
});
|
||
|
||
// Reads |numLines| lines or the entire file, whichever is less.
|
||
function readSomeLines(file, numLines) {
|
||
var buf = common.buffer();
|
||
var bufLength = buf.length;
|
||
var bytesRead = bufLength;
|
||
var pos = 0;
|
||
|
||
var fdr = fs.openSync(file, 'r');
|
||
var numLinesRead = 0;
|
||
var ret = '';
|
||
while (bytesRead === bufLength && numLinesRead < numLines) {
|
||
bytesRead = fs.readSync(fdr, buf, 0, bufLength, pos);
|
||
var bufStr = buf.toString('utf8', 0, bytesRead);
|
||
numLinesRead += bufStr.split('\n').length - 1;
|
||
ret += bufStr;
|
||
pos += bytesRead;
|
||
}
|
||
|
||
fs.closeSync(fdr);
|
||
return ret;
|
||
}
|
||
|
||
//@
|
||
//@ ### head([{'-n': \<num\>},] file [, file ...])
|
||
//@ ### head([{'-n': \<num\>},] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n <num>`: Show the first `<num>` lines of the files
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var str = head({'-n': 1}, 'file*.txt');
|
||
//@ var str = head('file1', 'file2');
|
||
//@ var str = head(['file1', 'file2']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Read the start of a file.
|
||
function _head(options, files) {
|
||
var head = [];
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!files && !pipe) common.error('no paths given');
|
||
|
||
var idx = 1;
|
||
if (options.numLines === true) {
|
||
idx = 2;
|
||
options.numLines = Number(arguments[1]);
|
||
} else if (options.numLines === false) {
|
||
options.numLines = 10;
|
||
}
|
||
files = [].slice.call(arguments, idx);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var shouldAppendNewline = false;
|
||
files.forEach(function (file) {
|
||
if (file !== '-') {
|
||
if (!fs.existsSync(file)) {
|
||
common.error('no such file or directory: ' + file, { continue: true });
|
||
return;
|
||
} else if (common.statFollowLinks(file).isDirectory()) {
|
||
common.error("error reading '" + file + "': Is a directory", {
|
||
continue: true,
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
|
||
var contents;
|
||
if (file === '-') {
|
||
contents = pipe;
|
||
} else if (options.numLines < 0) {
|
||
contents = fs.readFileSync(file, 'utf8');
|
||
} else {
|
||
contents = readSomeLines(file, options.numLines);
|
||
}
|
||
|
||
var lines = contents.split('\n');
|
||
var hasTrailingNewline = (lines[lines.length - 1] === '');
|
||
if (hasTrailingNewline) {
|
||
lines.pop();
|
||
}
|
||
shouldAppendNewline = (hasTrailingNewline || options.numLines < lines.length);
|
||
|
||
head = head.concat(lines.slice(0, options.numLines));
|
||
});
|
||
|
||
if (shouldAppendNewline) {
|
||
head.push(''); // to add a trailing newline once we join
|
||
}
|
||
return head.join('\n');
|
||
}
|
||
module.exports = _head;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/ln.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/ln.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('ln', _ln, {
|
||
cmdOptions: {
|
||
's': 'symlink',
|
||
'f': 'force',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### ln([options,] source, dest)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-s`: symlink
|
||
//@ + `-f`: force
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ ln('file', 'newlink');
|
||
//@ ln('-sf', 'file', 'existing');
|
||
//@ ```
|
||
//@
|
||
//@ Links `source` to `dest`. Use `-f` to force the link, should `dest` already exist.
|
||
function _ln(options, source, dest) {
|
||
if (!source || !dest) {
|
||
common.error('Missing <source> and/or <dest>');
|
||
}
|
||
|
||
source = String(source);
|
||
var sourcePath = path.normalize(source).replace(RegExp(path.sep + '$'), '');
|
||
var isAbsolute = (path.resolve(source) === sourcePath);
|
||
dest = path.resolve(process.cwd(), String(dest));
|
||
|
||
if (fs.existsSync(dest)) {
|
||
if (!options.force) {
|
||
common.error('Destination file exists', { continue: true });
|
||
}
|
||
|
||
fs.unlinkSync(dest);
|
||
}
|
||
|
||
if (options.symlink) {
|
||
var isWindows = process.platform === 'win32';
|
||
var linkType = isWindows ? 'file' : null;
|
||
var resolvedSourcePath = isAbsolute ? sourcePath : path.resolve(process.cwd(), path.dirname(dest), source);
|
||
if (!fs.existsSync(resolvedSourcePath)) {
|
||
common.error('Source file does not exist', { continue: true });
|
||
} else if (isWindows && common.statFollowLinks(resolvedSourcePath).isDirectory()) {
|
||
linkType = 'junction';
|
||
}
|
||
|
||
try {
|
||
fs.symlinkSync(linkType === 'junction' ? resolvedSourcePath : source, dest, linkType);
|
||
} catch (err) {
|
||
common.error(err.message);
|
||
}
|
||
} else {
|
||
if (!fs.existsSync(source)) {
|
||
common.error('Source file does not exist', { continue: true });
|
||
}
|
||
try {
|
||
fs.linkSync(source, dest);
|
||
} catch (err) {
|
||
common.error(err.message);
|
||
}
|
||
}
|
||
return '';
|
||
}
|
||
module.exports = _ln;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/ls.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/ls.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var glob = __webpack_require__(/*! glob */ "./node_modules/glob/glob.js");
|
||
|
||
var globPatternRecursive = path.sep + '**';
|
||
|
||
common.register('ls', _ls, {
|
||
cmdOptions: {
|
||
'R': 'recursive',
|
||
'A': 'all',
|
||
'L': 'link',
|
||
'a': 'all_deprecated',
|
||
'd': 'directory',
|
||
'l': 'long',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### ls([options,] [path, ...])
|
||
//@ ### ls([options,] path_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-R`: recursive
|
||
//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`)
|
||
//@ + `-L`: follow symlinks
|
||
//@ + `-d`: list directories themselves, not their contents
|
||
//@ + `-l`: list objects representing each file, each with fields containing `ls
|
||
//@ -l` output fields. See
|
||
//@ [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||
//@ for more info
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ ls('projs/*.js');
|
||
//@ ls('-R', '/users/me', '/tmp');
|
||
//@ ls('-R', ['/users/me', '/tmp']); // same as above
|
||
//@ ls('-l', 'file.txt'); // { name: 'file.txt', mode: 33188, nlink: 1, ...}
|
||
//@ ```
|
||
//@
|
||
//@ Returns array of files in the given `path`, or files in
|
||
//@ the current directory if no `path` is provided.
|
||
function _ls(options, paths) {
|
||
if (options.all_deprecated) {
|
||
// We won't support the -a option as it's hard to image why it's useful
|
||
// (it includes '.' and '..' in addition to '.*' files)
|
||
// For backwards compatibility we'll dump a deprecated message and proceed as before
|
||
common.log('ls: Option -a is deprecated. Use -A instead');
|
||
options.all = true;
|
||
}
|
||
|
||
if (!paths) {
|
||
paths = ['.'];
|
||
} else {
|
||
paths = [].slice.call(arguments, 1);
|
||
}
|
||
|
||
var list = [];
|
||
|
||
function pushFile(abs, relName, stat) {
|
||
if (process.platform === 'win32') {
|
||
relName = relName.replace(/\\/g, '/');
|
||
}
|
||
if (options.long) {
|
||
stat = stat || (options.link ? common.statFollowLinks(abs) : common.statNoFollowLinks(abs));
|
||
list.push(addLsAttributes(relName, stat));
|
||
} else {
|
||
// list.push(path.relative(rel || '.', file));
|
||
list.push(relName);
|
||
}
|
||
}
|
||
|
||
paths.forEach(function (p) {
|
||
var stat;
|
||
|
||
try {
|
||
stat = options.link ? common.statFollowLinks(p) : common.statNoFollowLinks(p);
|
||
// follow links to directories by default
|
||
if (stat.isSymbolicLink()) {
|
||
/* istanbul ignore next */
|
||
// workaround for https://github.com/shelljs/shelljs/issues/795
|
||
// codecov seems to have a bug that miscalculate this block as uncovered.
|
||
// but according to nyc report this block does get covered.
|
||
try {
|
||
var _stat = common.statFollowLinks(p);
|
||
if (_stat.isDirectory()) {
|
||
stat = _stat;
|
||
}
|
||
} catch (_) {} // bad symlink, treat it like a file
|
||
}
|
||
} catch (e) {
|
||
common.error('no such file or directory: ' + p, 2, { continue: true });
|
||
return;
|
||
}
|
||
|
||
// If the stat succeeded
|
||
if (stat.isDirectory() && !options.directory) {
|
||
if (options.recursive) {
|
||
// use glob, because it's simple
|
||
glob.sync(p + globPatternRecursive, { dot: options.all, follow: options.link })
|
||
.forEach(function (item) {
|
||
// Glob pattern returns the directory itself and needs to be filtered out.
|
||
if (path.relative(p, item)) {
|
||
pushFile(item, path.relative(p, item));
|
||
}
|
||
});
|
||
} else if (options.all) {
|
||
// use fs.readdirSync, because it's fast
|
||
fs.readdirSync(p).forEach(function (item) {
|
||
pushFile(path.join(p, item), item);
|
||
});
|
||
} else {
|
||
// use fs.readdirSync and then filter out secret files
|
||
fs.readdirSync(p).forEach(function (item) {
|
||
if (item[0] !== '.') {
|
||
pushFile(path.join(p, item), item);
|
||
}
|
||
});
|
||
}
|
||
} else {
|
||
pushFile(p, p, stat);
|
||
}
|
||
});
|
||
|
||
// Add methods, to make this more compatible with ShellStrings
|
||
return list;
|
||
}
|
||
|
||
function addLsAttributes(pathName, stats) {
|
||
// Note: this object will contain more information than .toString() returns
|
||
stats.name = pathName;
|
||
stats.toString = function () {
|
||
// Return a string resembling unix's `ls -l` format
|
||
return [this.mode, this.nlink, this.uid, this.gid, this.size, this.mtime, this.name].join(' ');
|
||
};
|
||
return stats;
|
||
}
|
||
|
||
module.exports = _ls;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/mkdir.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/mkdir.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('mkdir', _mkdir, {
|
||
cmdOptions: {
|
||
'p': 'fullpath',
|
||
},
|
||
});
|
||
|
||
// Recursively creates `dir`
|
||
function mkdirSyncRecursive(dir) {
|
||
var baseDir = path.dirname(dir);
|
||
|
||
// Prevents some potential problems arising from malformed UNCs or
|
||
// insufficient permissions.
|
||
/* istanbul ignore next */
|
||
if (baseDir === dir) {
|
||
common.error('dirname() failed: [' + dir + ']');
|
||
}
|
||
|
||
// Base dir exists, no recursion necessary
|
||
if (fs.existsSync(baseDir)) {
|
||
fs.mkdirSync(dir, parseInt('0777', 8));
|
||
return;
|
||
}
|
||
|
||
// Base dir does not exist, go recursive
|
||
mkdirSyncRecursive(baseDir);
|
||
|
||
// Base dir created, can create dir
|
||
fs.mkdirSync(dir, parseInt('0777', 8));
|
||
}
|
||
|
||
//@
|
||
//@ ### mkdir([options,] dir [, dir ...])
|
||
//@ ### mkdir([options,] dir_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-p`: full path (and create intermediate directories, if necessary)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');
|
||
//@ mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Creates directories.
|
||
function _mkdir(options, dirs) {
|
||
if (!dirs) common.error('no paths given');
|
||
|
||
if (typeof dirs === 'string') {
|
||
dirs = [].slice.call(arguments, 1);
|
||
}
|
||
// if it's array leave it as it is
|
||
|
||
dirs.forEach(function (dir) {
|
||
try {
|
||
var stat = common.statNoFollowLinks(dir);
|
||
if (!options.fullpath) {
|
||
common.error('path already exists: ' + dir, { continue: true });
|
||
} else if (stat.isFile()) {
|
||
common.error('cannot create directory ' + dir + ': File exists', { continue: true });
|
||
}
|
||
return; // skip dir
|
||
} catch (e) {
|
||
// do nothing
|
||
}
|
||
|
||
// Base dir does not exist, and no -p option given
|
||
var baseDir = path.dirname(dir);
|
||
if (!fs.existsSync(baseDir) && !options.fullpath) {
|
||
common.error('no such file or directory: ' + baseDir, { continue: true });
|
||
return; // skip dir
|
||
}
|
||
|
||
try {
|
||
if (options.fullpath) {
|
||
mkdirSyncRecursive(path.resolve(dir));
|
||
} else {
|
||
fs.mkdirSync(dir, parseInt('0777', 8));
|
||
}
|
||
} catch (e) {
|
||
var reason;
|
||
if (e.code === 'EACCES') {
|
||
reason = 'Permission denied';
|
||
} else if (e.code === 'ENOTDIR' || e.code === 'ENOENT') {
|
||
reason = 'Not a directory';
|
||
} else {
|
||
/* istanbul ignore next */
|
||
throw e;
|
||
}
|
||
common.error('cannot create directory ' + dir + ': ' + reason, { continue: true });
|
||
}
|
||
});
|
||
return '';
|
||
} // mkdir
|
||
module.exports = _mkdir;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/mv.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/mv.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var cp = __webpack_require__(/*! ./cp */ "./node_modules/shelljs/src/cp.js");
|
||
var rm = __webpack_require__(/*! ./rm */ "./node_modules/shelljs/src/rm.js");
|
||
|
||
common.register('mv', _mv, {
|
||
cmdOptions: {
|
||
'f': '!no_force',
|
||
'n': 'no_force',
|
||
},
|
||
});
|
||
|
||
// Checks if cureent file was created recently
|
||
function checkRecentCreated(sources, index) {
|
||
var lookedSource = sources[index];
|
||
return sources.slice(0, index).some(function (src) {
|
||
return path.basename(src) === path.basename(lookedSource);
|
||
});
|
||
}
|
||
|
||
//@
|
||
//@ ### mv([options ,] source [, source ...], dest')
|
||
//@ ### mv([options ,] source_array, dest')
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-f`: force (default behavior)
|
||
//@ + `-n`: no-clobber
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ mv('-n', 'file', 'dir/');
|
||
//@ mv('file1', 'file2', 'dir/');
|
||
//@ mv(['file1', 'file2'], 'dir/'); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Moves `source` file(s) to `dest`.
|
||
function _mv(options, sources, dest) {
|
||
// Get sources, dest
|
||
if (arguments.length < 3) {
|
||
common.error('missing <source> and/or <dest>');
|
||
} else if (arguments.length > 3) {
|
||
sources = [].slice.call(arguments, 1, arguments.length - 1);
|
||
dest = arguments[arguments.length - 1];
|
||
} else if (typeof sources === 'string') {
|
||
sources = [sources];
|
||
} else {
|
||
// TODO(nate): figure out if we actually need this line
|
||
common.error('invalid arguments');
|
||
}
|
||
|
||
var exists = fs.existsSync(dest);
|
||
var stats = exists && common.statFollowLinks(dest);
|
||
|
||
// Dest is not existing dir, but multiple sources given
|
||
if ((!exists || !stats.isDirectory()) && sources.length > 1) {
|
||
common.error('dest is not a directory (too many sources)');
|
||
}
|
||
|
||
// Dest is an existing file, but no -f given
|
||
if (exists && stats.isFile() && options.no_force) {
|
||
common.error('dest file already exists: ' + dest);
|
||
}
|
||
|
||
sources.forEach(function (src, srcIndex) {
|
||
if (!fs.existsSync(src)) {
|
||
common.error('no such file or directory: ' + src, { continue: true });
|
||
return; // skip file
|
||
}
|
||
|
||
// If here, src exists
|
||
|
||
// When copying to '/path/dir':
|
||
// thisDest = '/path/dir/file1'
|
||
var thisDest = dest;
|
||
if (fs.existsSync(dest) && common.statFollowLinks(dest).isDirectory()) {
|
||
thisDest = path.normalize(dest + '/' + path.basename(src));
|
||
}
|
||
|
||
var thisDestExists = fs.existsSync(thisDest);
|
||
|
||
if (thisDestExists && checkRecentCreated(sources, srcIndex)) {
|
||
// cannot overwrite file created recently in current execution, but we want to continue copying other files
|
||
if (!options.no_force) {
|
||
common.error("will not overwrite just-created '" + thisDest + "' with '" + src + "'", { continue: true });
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (fs.existsSync(thisDest) && options.no_force) {
|
||
common.error('dest file already exists: ' + thisDest, { continue: true });
|
||
return; // skip file
|
||
}
|
||
|
||
if (path.resolve(src) === path.dirname(path.resolve(thisDest))) {
|
||
common.error('cannot move to self: ' + src, { continue: true });
|
||
return; // skip file
|
||
}
|
||
|
||
try {
|
||
fs.renameSync(src, thisDest);
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
if (e.code === 'EXDEV') {
|
||
// If we're trying to `mv` to an external partition, we'll actually need
|
||
// to perform a copy and then clean up the original file. If either the
|
||
// copy or the rm fails with an exception, we should allow this
|
||
// exception to pass up to the top level.
|
||
cp('-r', src, thisDest);
|
||
rm('-rf', src);
|
||
}
|
||
}
|
||
}); // forEach(src)
|
||
return '';
|
||
} // mv
|
||
module.exports = _mv;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/popd.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/popd.js ***!
|
||
\******************************************/
|
||
/***/ (() => {
|
||
|
||
// see dirs.js
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/pushd.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/pushd.js ***!
|
||
\*******************************************/
|
||
/***/ (() => {
|
||
|
||
// see dirs.js
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/pwd.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/shelljs/src/pwd.js ***!
|
||
\*****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('pwd', _pwd, {
|
||
allowGlobbing: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### pwd()
|
||
//@
|
||
//@ Returns the current directory.
|
||
function _pwd() {
|
||
var pwd = path.resolve(process.cwd());
|
||
return pwd;
|
||
}
|
||
module.exports = _pwd;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/rm.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/rm.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('rm', _rm, {
|
||
cmdOptions: {
|
||
'f': 'force',
|
||
'r': 'recursive',
|
||
'R': 'recursive',
|
||
},
|
||
});
|
||
|
||
// Recursively removes 'dir'
|
||
// Adapted from https://github.com/ryanmcgrath/wrench-js
|
||
//
|
||
// Copyright (c) 2010 Ryan McGrath
|
||
// Copyright (c) 2012 Artur Adib
|
||
//
|
||
// Licensed under the MIT License
|
||
// http://www.opensource.org/licenses/mit-license.php
|
||
function rmdirSyncRecursive(dir, force, fromSymlink) {
|
||
var files;
|
||
|
||
files = fs.readdirSync(dir);
|
||
|
||
// Loop through and delete everything in the sub-tree after checking it
|
||
for (var i = 0; i < files.length; i++) {
|
||
var file = dir + '/' + files[i];
|
||
var currFile = common.statNoFollowLinks(file);
|
||
|
||
if (currFile.isDirectory()) { // Recursive function back to the beginning
|
||
rmdirSyncRecursive(file, force);
|
||
} else { // Assume it's a file - perhaps a try/catch belongs here?
|
||
if (force || isWriteable(file)) {
|
||
try {
|
||
common.unlinkSync(file);
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('could not remove file (code ' + e.code + '): ' + file, {
|
||
continue: true,
|
||
});
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// if was directory was referenced through a symbolic link,
|
||
// the contents should be removed, but not the directory itself
|
||
if (fromSymlink) return;
|
||
|
||
// Now that we know everything in the sub-tree has been deleted, we can delete the main directory.
|
||
// Huzzah for the shopkeep.
|
||
|
||
var result;
|
||
try {
|
||
// Retry on windows, sometimes it takes a little time before all the files in the directory are gone
|
||
var start = Date.now();
|
||
|
||
// TODO: replace this with a finite loop
|
||
for (;;) {
|
||
try {
|
||
result = fs.rmdirSync(dir);
|
||
if (fs.existsSync(dir)) throw { code: 'EAGAIN' };
|
||
break;
|
||
} catch (er) {
|
||
/* istanbul ignore next */
|
||
// In addition to error codes, also check if the directory still exists and loop again if true
|
||
if (process.platform === 'win32' && (er.code === 'ENOTEMPTY' || er.code === 'EBUSY' || er.code === 'EPERM' || er.code === 'EAGAIN')) {
|
||
if (Date.now() - start > 1000) throw er;
|
||
} else if (er.code === 'ENOENT') {
|
||
// Directory did not exist, deletion was successful
|
||
break;
|
||
} else {
|
||
throw er;
|
||
}
|
||
}
|
||
}
|
||
} catch (e) {
|
||
common.error('could not remove directory (code ' + e.code + '): ' + dir, { continue: true });
|
||
}
|
||
|
||
return result;
|
||
} // rmdirSyncRecursive
|
||
|
||
// Hack to determine if file has write permissions for current user
|
||
// Avoids having to check user, group, etc, but it's probably slow
|
||
function isWriteable(file) {
|
||
var writePermission = true;
|
||
try {
|
||
var __fd = fs.openSync(file, 'a');
|
||
fs.closeSync(__fd);
|
||
} catch (e) {
|
||
writePermission = false;
|
||
}
|
||
|
||
return writePermission;
|
||
}
|
||
|
||
function handleFile(file, options) {
|
||
if (options.force || isWriteable(file)) {
|
||
// -f was passed, or file is writable, so it can be removed
|
||
common.unlinkSync(file);
|
||
} else {
|
||
common.error('permission denied: ' + file, { continue: true });
|
||
}
|
||
}
|
||
|
||
function handleDirectory(file, options) {
|
||
if (options.recursive) {
|
||
// -r was passed, so directory can be removed
|
||
rmdirSyncRecursive(file, options.force);
|
||
} else {
|
||
common.error('path is a directory', { continue: true });
|
||
}
|
||
}
|
||
|
||
function handleSymbolicLink(file, options) {
|
||
var stats;
|
||
try {
|
||
stats = common.statFollowLinks(file);
|
||
} catch (e) {
|
||
// symlink is broken, so remove the symlink itself
|
||
common.unlinkSync(file);
|
||
return;
|
||
}
|
||
|
||
if (stats.isFile()) {
|
||
common.unlinkSync(file);
|
||
} else if (stats.isDirectory()) {
|
||
if (file[file.length - 1] === '/') {
|
||
// trailing separator, so remove the contents, not the link
|
||
if (options.recursive) {
|
||
// -r was passed, so directory can be removed
|
||
var fromSymlink = true;
|
||
rmdirSyncRecursive(file, options.force, fromSymlink);
|
||
} else {
|
||
common.error('path is a directory', { continue: true });
|
||
}
|
||
} else {
|
||
// no trailing separator, so remove the link
|
||
common.unlinkSync(file);
|
||
}
|
||
}
|
||
}
|
||
|
||
function handleFIFO(file) {
|
||
common.unlinkSync(file);
|
||
}
|
||
|
||
//@
|
||
//@ ### rm([options,] file [, file ...])
|
||
//@ ### rm([options,] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-f`: force
|
||
//@ + `-r, -R`: recursive
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ rm('-rf', '/tmp/*');
|
||
//@ rm('some_file.txt', 'another_file.txt');
|
||
//@ rm(['some_file.txt', 'another_file.txt']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Removes files.
|
||
function _rm(options, files) {
|
||
if (!files) common.error('no paths given');
|
||
|
||
// Convert to array
|
||
files = [].slice.call(arguments, 1);
|
||
|
||
files.forEach(function (file) {
|
||
var lstats;
|
||
try {
|
||
var filepath = (file[file.length - 1] === '/')
|
||
? file.slice(0, -1) // remove the '/' so lstatSync can detect symlinks
|
||
: file;
|
||
lstats = common.statNoFollowLinks(filepath); // test for existence
|
||
} catch (e) {
|
||
// Path does not exist, no force flag given
|
||
if (!options.force) {
|
||
common.error('no such file or directory: ' + file, { continue: true });
|
||
}
|
||
return; // skip file
|
||
}
|
||
|
||
// If here, path exists
|
||
if (lstats.isFile()) {
|
||
handleFile(file, options);
|
||
} else if (lstats.isDirectory()) {
|
||
handleDirectory(file, options);
|
||
} else if (lstats.isSymbolicLink()) {
|
||
handleSymbolicLink(file, options);
|
||
} else if (lstats.isFIFO()) {
|
||
handleFIFO(file);
|
||
}
|
||
}); // forEach(file)
|
||
return '';
|
||
} // rm
|
||
module.exports = _rm;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/sed.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/shelljs/src/sed.js ***!
|
||
\*****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('sed', _sed, {
|
||
globStart: 3, // don't glob-expand regexes
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'i': 'inplace',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### sed([options,] search_regex, replacement, file [, file ...])
|
||
//@ ### sed([options,] search_regex, replacement, file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-i`: Replace contents of `file` in-place. _Note that no backups will be created!_
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
|
||
//@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
|
||
//@ ```
|
||
//@
|
||
//@ Reads an input string from `file`s, and performs a JavaScript `replace()` on the input
|
||
//@ using the given `search_regex` and `replacement` string or function. Returns the new string after replacement.
|
||
//@
|
||
//@ Note:
|
||
//@
|
||
//@ Like unix `sed`, ShellJS `sed` supports capture groups. Capture groups are specified
|
||
//@ using the `$n` syntax:
|
||
//@
|
||
//@ ```javascript
|
||
//@ sed(/(\w+)\s(\w+)/, '$2, $1', 'file.txt');
|
||
//@ ```
|
||
function _sed(options, regex, replacement, files) {
|
||
// Check if this is coming from a pipe
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (typeof replacement !== 'string' && typeof replacement !== 'function') {
|
||
if (typeof replacement === 'number') {
|
||
replacement = replacement.toString(); // fallback
|
||
} else {
|
||
common.error('invalid replacement string');
|
||
}
|
||
}
|
||
|
||
// Convert all search strings to RegExp
|
||
if (typeof regex === 'string') {
|
||
regex = RegExp(regex);
|
||
}
|
||
|
||
if (!files && !pipe) {
|
||
common.error('no files given');
|
||
}
|
||
|
||
files = [].slice.call(arguments, 3);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var sed = [];
|
||
files.forEach(function (file) {
|
||
if (!fs.existsSync(file) && file !== '-') {
|
||
common.error('no such file or directory: ' + file, 2, { continue: true });
|
||
return;
|
||
}
|
||
|
||
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
|
||
var lines = contents.split('\n');
|
||
var result = lines.map(function (line) {
|
||
return line.replace(regex, replacement);
|
||
}).join('\n');
|
||
|
||
sed.push(result);
|
||
|
||
if (options.inplace) {
|
||
fs.writeFileSync(file, result, 'utf8');
|
||
}
|
||
});
|
||
|
||
return sed.join('\n');
|
||
}
|
||
module.exports = _sed;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/set.js":
|
||
/*!*****************************************!*\
|
||
!*** ./node_modules/shelljs/src/set.js ***!
|
||
\*****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
|
||
common.register('set', _set, {
|
||
allowGlobbing: false,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### set(options)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `+/-e`: exit upon error (`config.fatal`)
|
||
//@ + `+/-v`: verbose: show all commands (`config.verbose`)
|
||
//@ + `+/-f`: disable filename expansion (globbing)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ set('-e'); // exit upon first error
|
||
//@ set('+e'); // this undoes a "set('-e')"
|
||
//@ ```
|
||
//@
|
||
//@ Sets global configuration variables.
|
||
function _set(options) {
|
||
if (!options) {
|
||
var args = [].slice.call(arguments, 0);
|
||
if (args.length < 2) common.error('must provide an argument');
|
||
options = args[1];
|
||
}
|
||
var negate = (options[0] === '+');
|
||
if (negate) {
|
||
options = '-' + options.slice(1); // parseOptions needs a '-' prefix
|
||
}
|
||
options = common.parseOptions(options, {
|
||
'e': 'fatal',
|
||
'v': 'verbose',
|
||
'f': 'noglob',
|
||
});
|
||
|
||
if (negate) {
|
||
Object.keys(options).forEach(function (key) {
|
||
options[key] = !options[key];
|
||
});
|
||
}
|
||
|
||
Object.keys(options).forEach(function (key) {
|
||
// Only change the global config if `negate` is false and the option is true
|
||
// or if `negate` is true and the option is false (aka negate !== option)
|
||
if (negate !== options[key]) {
|
||
common.config[key] = options[key];
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
module.exports = _set;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/sort.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/sort.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('sort', _sort, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'r': 'reverse',
|
||
'n': 'numerical',
|
||
},
|
||
});
|
||
|
||
// parse out the number prefix of a line
|
||
function parseNumber(str) {
|
||
var match = str.match(/^\s*(\d*)\s*(.*)$/);
|
||
return { num: Number(match[1]), value: match[2] };
|
||
}
|
||
|
||
// compare two strings case-insensitively, but examine case for strings that are
|
||
// case-insensitive equivalent
|
||
function unixCmp(a, b) {
|
||
var aLower = a.toLowerCase();
|
||
var bLower = b.toLowerCase();
|
||
return (aLower === bLower ?
|
||
-1 * a.localeCompare(b) : // unix sort treats case opposite how javascript does
|
||
aLower.localeCompare(bLower));
|
||
}
|
||
|
||
// compare two strings in the fashion that unix sort's -n option works
|
||
function numericalCmp(a, b) {
|
||
var objA = parseNumber(a);
|
||
var objB = parseNumber(b);
|
||
if (objA.hasOwnProperty('num') && objB.hasOwnProperty('num')) {
|
||
return ((objA.num !== objB.num) ?
|
||
(objA.num - objB.num) :
|
||
unixCmp(objA.value, objB.value));
|
||
} else {
|
||
return unixCmp(objA.value, objB.value);
|
||
}
|
||
}
|
||
|
||
//@
|
||
//@ ### sort([options,] file [, file ...])
|
||
//@ ### sort([options,] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-r`: Reverse the results
|
||
//@ + `-n`: Compare according to numerical value
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ sort('foo.txt', 'bar.txt');
|
||
//@ sort('-r', 'foo.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Return the contents of the `file`s, sorted line-by-line. Sorting multiple
|
||
//@ files mixes their content (just as unix `sort` does).
|
||
function _sort(options, files) {
|
||
// Check if this is coming from a pipe
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!files && !pipe) common.error('no files given');
|
||
|
||
files = [].slice.call(arguments, 1);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var lines = files.reduce(function (accum, file) {
|
||
if (file !== '-') {
|
||
if (!fs.existsSync(file)) {
|
||
common.error('no such file or directory: ' + file, { continue: true });
|
||
return accum;
|
||
} else if (common.statFollowLinks(file).isDirectory()) {
|
||
common.error('read failed: ' + file + ': Is a directory', {
|
||
continue: true,
|
||
});
|
||
return accum;
|
||
}
|
||
}
|
||
|
||
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
|
||
return accum.concat(contents.trimRight().split('\n'));
|
||
}, []);
|
||
|
||
var sorted = lines.sort(options.numerical ? numericalCmp : unixCmp);
|
||
|
||
if (options.reverse) {
|
||
sorted = sorted.reverse();
|
||
}
|
||
|
||
return sorted.join('\n') + '\n';
|
||
}
|
||
|
||
module.exports = _sort;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/tail.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/tail.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('tail', _tail, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'n': 'numLines',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### tail([{'-n': \<num\>},] file [, file ...])
|
||
//@ ### tail([{'-n': \<num\>},] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-n <num>`: Show the last `<num>` lines of `file`s
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var str = tail({'-n': 1}, 'file*.txt');
|
||
//@ var str = tail('file1', 'file2');
|
||
//@ var str = tail(['file1', 'file2']); // same as above
|
||
//@ ```
|
||
//@
|
||
//@ Read the end of a `file`.
|
||
function _tail(options, files) {
|
||
var tail = [];
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!files && !pipe) common.error('no paths given');
|
||
|
||
var idx = 1;
|
||
if (options.numLines === true) {
|
||
idx = 2;
|
||
options.numLines = Number(arguments[1]);
|
||
} else if (options.numLines === false) {
|
||
options.numLines = 10;
|
||
}
|
||
options.numLines = -1 * Math.abs(options.numLines);
|
||
files = [].slice.call(arguments, idx);
|
||
|
||
if (pipe) {
|
||
files.unshift('-');
|
||
}
|
||
|
||
var shouldAppendNewline = false;
|
||
files.forEach(function (file) {
|
||
if (file !== '-') {
|
||
if (!fs.existsSync(file)) {
|
||
common.error('no such file or directory: ' + file, { continue: true });
|
||
return;
|
||
} else if (common.statFollowLinks(file).isDirectory()) {
|
||
common.error("error reading '" + file + "': Is a directory", {
|
||
continue: true,
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
|
||
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
|
||
|
||
var lines = contents.split('\n');
|
||
if (lines[lines.length - 1] === '') {
|
||
lines.pop();
|
||
shouldAppendNewline = true;
|
||
} else {
|
||
shouldAppendNewline = false;
|
||
}
|
||
|
||
tail = tail.concat(lines.slice(options.numLines));
|
||
});
|
||
|
||
if (shouldAppendNewline) {
|
||
tail.push(''); // to add a trailing newline once we join
|
||
}
|
||
return tail.join('\n');
|
||
}
|
||
module.exports = _tail;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/tempdir.js":
|
||
/*!*********************************************!*\
|
||
!*** ./node_modules/shelljs/src/tempdir.js ***!
|
||
\*********************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var os = __webpack_require__(/*! os */ "os");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('tempdir', _tempDir, {
|
||
allowGlobbing: false,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
// Returns false if 'dir' is not a writeable directory, 'dir' otherwise
|
||
function writeableDir(dir) {
|
||
if (!dir || !fs.existsSync(dir)) return false;
|
||
|
||
if (!common.statFollowLinks(dir).isDirectory()) return false;
|
||
|
||
var testFile = dir + '/' + common.randomFileName();
|
||
try {
|
||
fs.writeFileSync(testFile, ' ');
|
||
common.unlinkSync(testFile);
|
||
return dir;
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Variable to cache the tempdir value for successive lookups.
|
||
var cachedTempDir;
|
||
|
||
//@
|
||
//@ ### tempdir()
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var tmp = tempdir(); // "/tmp" for most *nix platforms
|
||
//@ ```
|
||
//@
|
||
//@ Searches and returns string containing a writeable, platform-dependent temporary directory.
|
||
//@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
|
||
function _tempDir() {
|
||
if (cachedTempDir) return cachedTempDir;
|
||
|
||
cachedTempDir = writeableDir(os.tmpdir()) ||
|
||
writeableDir(process.env.TMPDIR) ||
|
||
writeableDir(process.env.TEMP) ||
|
||
writeableDir(process.env.TMP) ||
|
||
writeableDir(process.env.Wimp$ScrapDir) || // RiscOS
|
||
writeableDir('C:\\TEMP') || // Windows
|
||
writeableDir('C:\\TMP') || // Windows
|
||
writeableDir('\\TEMP') || // Windows
|
||
writeableDir('\\TMP') || // Windows
|
||
writeableDir('/tmp') ||
|
||
writeableDir('/var/tmp') ||
|
||
writeableDir('/usr/tmp') ||
|
||
writeableDir('.'); // last resort
|
||
|
||
return cachedTempDir;
|
||
}
|
||
|
||
// Indicates if the tempdir value is currently cached. This is exposed for tests
|
||
// only. The return value should only be tested for truthiness.
|
||
function isCached() {
|
||
return cachedTempDir;
|
||
}
|
||
|
||
// Clears the cached tempDir value, if one is cached. This is exposed for tests
|
||
// only.
|
||
function clearCache() {
|
||
cachedTempDir = undefined;
|
||
}
|
||
|
||
module.exports.tempDir = _tempDir;
|
||
module.exports.isCached = isCached;
|
||
module.exports.clearCache = clearCache;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/test.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/test.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('test', _test, {
|
||
cmdOptions: {
|
||
'b': 'block',
|
||
'c': 'character',
|
||
'd': 'directory',
|
||
'e': 'exists',
|
||
'f': 'file',
|
||
'L': 'link',
|
||
'p': 'pipe',
|
||
'S': 'socket',
|
||
},
|
||
wrapOutput: false,
|
||
allowGlobbing: false,
|
||
});
|
||
|
||
|
||
//@
|
||
//@ ### test(expression)
|
||
//@
|
||
//@ Available expression primaries:
|
||
//@
|
||
//@ + `'-b', 'path'`: true if path is a block device
|
||
//@ + `'-c', 'path'`: true if path is a character device
|
||
//@ + `'-d', 'path'`: true if path is a directory
|
||
//@ + `'-e', 'path'`: true if path exists
|
||
//@ + `'-f', 'path'`: true if path is a regular file
|
||
//@ + `'-L', 'path'`: true if path is a symbolic link
|
||
//@ + `'-p', 'path'`: true if path is a pipe (FIFO)
|
||
//@ + `'-S', 'path'`: true if path is a socket
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ if (test('-d', path)) { /* do something with dir */ };
|
||
//@ if (!test('-f', path)) continue; // skip if it's a regular file
|
||
//@ ```
|
||
//@
|
||
//@ Evaluates `expression` using the available primaries and returns corresponding value.
|
||
function _test(options, path) {
|
||
if (!path) common.error('no path given');
|
||
|
||
var canInterpret = false;
|
||
Object.keys(options).forEach(function (key) {
|
||
if (options[key] === true) {
|
||
canInterpret = true;
|
||
}
|
||
});
|
||
|
||
if (!canInterpret) common.error('could not interpret expression');
|
||
|
||
if (options.link) {
|
||
try {
|
||
return common.statNoFollowLinks(path).isSymbolicLink();
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (!fs.existsSync(path)) return false;
|
||
|
||
if (options.exists) return true;
|
||
|
||
var stats = common.statFollowLinks(path);
|
||
|
||
if (options.block) return stats.isBlockDevice();
|
||
|
||
if (options.character) return stats.isCharacterDevice();
|
||
|
||
if (options.directory) return stats.isDirectory();
|
||
|
||
if (options.file) return stats.isFile();
|
||
|
||
/* istanbul ignore next */
|
||
if (options.pipe) return stats.isFIFO();
|
||
|
||
/* istanbul ignore next */
|
||
if (options.socket) return stats.isSocket();
|
||
|
||
/* istanbul ignore next */
|
||
return false; // fallback
|
||
} // test
|
||
module.exports = _test;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/to.js":
|
||
/*!****************************************!*\
|
||
!*** ./node_modules/shelljs/src/to.js ***!
|
||
\****************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('to', _to, {
|
||
pipeOnly: true,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### ShellString.prototype.to(file)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ cat('input.txt').to('output.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Analogous to the redirection operator `>` in Unix, but works with
|
||
//@ `ShellStrings` (such as those returned by `cat`, `grep`, etc.). _Like Unix
|
||
//@ redirections, `to()` will overwrite any existing file!_
|
||
function _to(options, file) {
|
||
if (!file) common.error('wrong arguments');
|
||
|
||
if (!fs.existsSync(path.dirname(file))) {
|
||
common.error('no such file or directory: ' + path.dirname(file));
|
||
}
|
||
|
||
try {
|
||
fs.writeFileSync(file, this.stdout || this.toString(), 'utf8');
|
||
return this;
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('could not write to file (code ' + e.code + '): ' + file, { continue: true });
|
||
}
|
||
}
|
||
module.exports = _to;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/toEnd.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/toEnd.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('toEnd', _toEnd, {
|
||
pipeOnly: true,
|
||
wrapOutput: false,
|
||
});
|
||
|
||
//@
|
||
//@ ### ShellString.prototype.toEnd(file)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ cat('input.txt').toEnd('output.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Analogous to the redirect-and-append operator `>>` in Unix, but works with
|
||
//@ `ShellStrings` (such as those returned by `cat`, `grep`, etc.).
|
||
function _toEnd(options, file) {
|
||
if (!file) common.error('wrong arguments');
|
||
|
||
if (!fs.existsSync(path.dirname(file))) {
|
||
common.error('no such file or directory: ' + path.dirname(file));
|
||
}
|
||
|
||
try {
|
||
fs.appendFileSync(file, this.stdout || this.toString(), 'utf8');
|
||
return this;
|
||
} catch (e) {
|
||
/* istanbul ignore next */
|
||
common.error('could not append to file (code ' + e.code + '): ' + file, { continue: true });
|
||
}
|
||
}
|
||
module.exports = _toEnd;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/touch.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/touch.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
common.register('touch', _touch, {
|
||
cmdOptions: {
|
||
'a': 'atime_only',
|
||
'c': 'no_create',
|
||
'd': 'date',
|
||
'm': 'mtime_only',
|
||
'r': 'reference',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### touch([options,] file [, file ...])
|
||
//@ ### touch([options,] file_array)
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-a`: Change only the access time
|
||
//@ + `-c`: Do not create any files
|
||
//@ + `-m`: Change only the modification time
|
||
//@ + `-d DATE`: Parse `DATE` and use it instead of current time
|
||
//@ + `-r FILE`: Use `FILE`'s times instead of current time
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ touch('source.js');
|
||
//@ touch('-c', '/path/to/some/dir/source.js');
|
||
//@ touch({ '-r': FILE }, '/path/to/some/dir/source.js');
|
||
//@ ```
|
||
//@
|
||
//@ Update the access and modification times of each `FILE` to the current time.
|
||
//@ A `FILE` argument that does not exist is created empty, unless `-c` is supplied.
|
||
//@ This is a partial implementation of [`touch(1)`](http://linux.die.net/man/1/touch).
|
||
function _touch(opts, files) {
|
||
if (!files) {
|
||
common.error('no files given');
|
||
} else if (typeof files === 'string') {
|
||
files = [].slice.call(arguments, 1);
|
||
} else {
|
||
common.error('file arg should be a string file path or an Array of string file paths');
|
||
}
|
||
|
||
files.forEach(function (f) {
|
||
touchFile(opts, f);
|
||
});
|
||
return '';
|
||
}
|
||
|
||
function touchFile(opts, file) {
|
||
var stat = tryStatFile(file);
|
||
|
||
if (stat && stat.isDirectory()) {
|
||
// don't error just exit
|
||
return;
|
||
}
|
||
|
||
// if the file doesn't already exist and the user has specified --no-create then
|
||
// this script is finished
|
||
if (!stat && opts.no_create) {
|
||
return;
|
||
}
|
||
|
||
// open the file and then close it. this will create it if it doesn't exist but will
|
||
// not truncate the file
|
||
fs.closeSync(fs.openSync(file, 'a'));
|
||
|
||
//
|
||
// Set timestamps
|
||
//
|
||
|
||
// setup some defaults
|
||
var now = new Date();
|
||
var mtime = opts.date || now;
|
||
var atime = opts.date || now;
|
||
|
||
// use reference file
|
||
if (opts.reference) {
|
||
var refStat = tryStatFile(opts.reference);
|
||
if (!refStat) {
|
||
common.error('failed to get attributess of ' + opts.reference);
|
||
}
|
||
mtime = refStat.mtime;
|
||
atime = refStat.atime;
|
||
} else if (opts.date) {
|
||
mtime = opts.date;
|
||
atime = opts.date;
|
||
}
|
||
|
||
if (opts.atime_only && opts.mtime_only) {
|
||
// keep the new values of mtime and atime like GNU
|
||
} else if (opts.atime_only) {
|
||
mtime = stat.mtime;
|
||
} else if (opts.mtime_only) {
|
||
atime = stat.atime;
|
||
}
|
||
|
||
fs.utimesSync(file, atime, mtime);
|
||
}
|
||
|
||
module.exports = _touch;
|
||
|
||
function tryStatFile(filePath) {
|
||
try {
|
||
return common.statFollowLinks(filePath);
|
||
} catch (e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/uniq.js":
|
||
/*!******************************************!*\
|
||
!*** ./node_modules/shelljs/src/uniq.js ***!
|
||
\******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
|
||
// add c spaces to the left of str
|
||
function lpad(c, str) {
|
||
var res = '' + str;
|
||
if (res.length < c) {
|
||
res = Array((c - res.length) + 1).join(' ') + res;
|
||
}
|
||
return res;
|
||
}
|
||
|
||
common.register('uniq', _uniq, {
|
||
canReceivePipe: true,
|
||
cmdOptions: {
|
||
'i': 'ignoreCase',
|
||
'c': 'count',
|
||
'd': 'duplicates',
|
||
},
|
||
});
|
||
|
||
//@
|
||
//@ ### uniq([options,] [input, [output]])
|
||
//@
|
||
//@ Available options:
|
||
//@
|
||
//@ + `-i`: Ignore case while comparing
|
||
//@ + `-c`: Prefix lines by the number of occurrences
|
||
//@ + `-d`: Only print duplicate lines, one for each group of identical lines
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ uniq('foo.txt');
|
||
//@ uniq('-i', 'foo.txt');
|
||
//@ uniq('-cd', 'foo.txt', 'bar.txt');
|
||
//@ ```
|
||
//@
|
||
//@ Filter adjacent matching lines from `input`.
|
||
function _uniq(options, input, output) {
|
||
// Check if this is coming from a pipe
|
||
var pipe = common.readFromPipe();
|
||
|
||
if (!pipe) {
|
||
if (!input) common.error('no input given');
|
||
|
||
if (!fs.existsSync(input)) {
|
||
common.error(input + ': No such file or directory');
|
||
} else if (common.statFollowLinks(input).isDirectory()) {
|
||
common.error("error reading '" + input + "'");
|
||
}
|
||
}
|
||
if (output && fs.existsSync(output) && common.statFollowLinks(output).isDirectory()) {
|
||
common.error(output + ': Is a directory');
|
||
}
|
||
|
||
var lines = (input ? fs.readFileSync(input, 'utf8') : pipe).
|
||
trimRight().
|
||
split('\n');
|
||
|
||
var compare = function (a, b) {
|
||
return options.ignoreCase ?
|
||
a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase()) :
|
||
a.localeCompare(b);
|
||
};
|
||
var uniqed = lines.reduceRight(function (res, e) {
|
||
// Perform uniq -c on the input
|
||
if (res.length === 0) {
|
||
return [{ count: 1, ln: e }];
|
||
} else if (compare(res[0].ln, e) === 0) {
|
||
return [{ count: res[0].count + 1, ln: e }].concat(res.slice(1));
|
||
} else {
|
||
return [{ count: 1, ln: e }].concat(res);
|
||
}
|
||
}, []).filter(function (obj) {
|
||
// Do we want only duplicated objects?
|
||
return options.duplicates ? obj.count > 1 : true;
|
||
}).map(function (obj) {
|
||
// Are we tracking the counts of each line?
|
||
return (options.count ? (lpad(7, obj.count) + ' ') : '') + obj.ln;
|
||
}).join('\n') + '\n';
|
||
|
||
if (output) {
|
||
(new common.ShellString(uniqed)).to(output);
|
||
// if uniq writes to output, nothing is passed to the next command in the pipeline (if any)
|
||
return '';
|
||
} else {
|
||
return uniqed;
|
||
}
|
||
}
|
||
|
||
module.exports = _uniq;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src/which.js":
|
||
/*!*******************************************!*\
|
||
!*** ./node_modules/shelljs/src/which.js ***!
|
||
\*******************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var common = __webpack_require__(/*! ./common */ "./node_modules/shelljs/src/common.js");
|
||
var fs = __webpack_require__(/*! fs */ "fs");
|
||
var path = __webpack_require__(/*! path */ "path");
|
||
|
||
common.register('which', _which, {
|
||
allowGlobbing: false,
|
||
cmdOptions: {
|
||
'a': 'all',
|
||
},
|
||
});
|
||
|
||
// XP's system default value for `PATHEXT` system variable, just in case it's not
|
||
// set on Windows.
|
||
var XP_DEFAULT_PATHEXT = '.com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh';
|
||
|
||
// For earlier versions of NodeJS that doesn't have a list of constants (< v6)
|
||
var FILE_EXECUTABLE_MODE = 1;
|
||
|
||
function isWindowsPlatform() {
|
||
return process.platform === 'win32';
|
||
}
|
||
|
||
// Cross-platform method for splitting environment `PATH` variables
|
||
function splitPath(p) {
|
||
return p ? p.split(path.delimiter) : [];
|
||
}
|
||
|
||
// Tests are running all cases for this func but it stays uncovered by codecov due to unknown reason
|
||
/* istanbul ignore next */
|
||
function isExecutable(pathName) {
|
||
try {
|
||
// TODO(node-support): replace with fs.constants.X_OK once remove support for node < v6
|
||
fs.accessSync(pathName, FILE_EXECUTABLE_MODE);
|
||
} catch (err) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
function checkPath(pathName) {
|
||
return fs.existsSync(pathName) && !common.statFollowLinks(pathName).isDirectory()
|
||
&& (isWindowsPlatform() || isExecutable(pathName));
|
||
}
|
||
|
||
//@
|
||
//@ ### which(command)
|
||
//@
|
||
//@ Examples:
|
||
//@
|
||
//@ ```javascript
|
||
//@ var nodeExec = which('node');
|
||
//@ ```
|
||
//@
|
||
//@ Searches for `command` in the system's `PATH`. On Windows, this uses the
|
||
//@ `PATHEXT` variable to append the extension if it's not already executable.
|
||
//@ Returns string containing the absolute path to `command`.
|
||
function _which(options, cmd) {
|
||
if (!cmd) common.error('must specify command');
|
||
|
||
var isWindows = isWindowsPlatform();
|
||
var pathArray = splitPath(process.env.PATH);
|
||
|
||
var queryMatches = [];
|
||
|
||
// No relative/absolute paths provided?
|
||
if (cmd.indexOf('/') === -1) {
|
||
// Assume that there are no extensions to append to queries (this is the
|
||
// case for unix)
|
||
var pathExtArray = [''];
|
||
if (isWindows) {
|
||
// In case the PATHEXT variable is somehow not set (e.g.
|
||
// child_process.spawn with an empty environment), use the XP default.
|
||
var pathExtEnv = process.env.PATHEXT || XP_DEFAULT_PATHEXT;
|
||
pathExtArray = splitPath(pathExtEnv.toUpperCase());
|
||
}
|
||
|
||
// Search for command in PATH
|
||
for (var k = 0; k < pathArray.length; k++) {
|
||
// already found it
|
||
if (queryMatches.length > 0 && !options.all) break;
|
||
|
||
var attempt = path.resolve(pathArray[k], cmd);
|
||
|
||
if (isWindows) {
|
||
attempt = attempt.toUpperCase();
|
||
}
|
||
|
||
var match = attempt.match(/\.[^<>:"/\|?*.]+$/);
|
||
if (match && pathExtArray.indexOf(match[0]) >= 0) { // this is Windows-only
|
||
// The user typed a query with the file extension, like
|
||
// `which('node.exe')`
|
||
if (checkPath(attempt)) {
|
||
queryMatches.push(attempt);
|
||
break;
|
||
}
|
||
} else { // All-platforms
|
||
// Cycle through the PATHEXT array, and check each extension
|
||
// Note: the array is always [''] on Unix
|
||
for (var i = 0; i < pathExtArray.length; i++) {
|
||
var ext = pathExtArray[i];
|
||
var newAttempt = attempt + ext;
|
||
if (checkPath(newAttempt)) {
|
||
queryMatches.push(newAttempt);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else if (checkPath(cmd)) { // a valid absolute or relative path
|
||
queryMatches.push(path.resolve(cmd));
|
||
}
|
||
|
||
if (queryMatches.length > 0) {
|
||
return options.all ? queryMatches : queryMatches[0];
|
||
}
|
||
return options.all ? [] : null;
|
||
}
|
||
module.exports = _which;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/shelljs/src sync recursive ^\\.\\/.*$":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/shelljs/src/ sync ^\.\/.*$ ***!
|
||
\*************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
var map = {
|
||
"./cat": "./node_modules/shelljs/src/cat.js",
|
||
"./cat.js": "./node_modules/shelljs/src/cat.js",
|
||
"./cd": "./node_modules/shelljs/src/cd.js",
|
||
"./cd.js": "./node_modules/shelljs/src/cd.js",
|
||
"./chmod": "./node_modules/shelljs/src/chmod.js",
|
||
"./chmod.js": "./node_modules/shelljs/src/chmod.js",
|
||
"./common": "./node_modules/shelljs/src/common.js",
|
||
"./common.js": "./node_modules/shelljs/src/common.js",
|
||
"./cp": "./node_modules/shelljs/src/cp.js",
|
||
"./cp.js": "./node_modules/shelljs/src/cp.js",
|
||
"./dirs": "./node_modules/shelljs/src/dirs.js",
|
||
"./dirs.js": "./node_modules/shelljs/src/dirs.js",
|
||
"./echo": "./node_modules/shelljs/src/echo.js",
|
||
"./echo.js": "./node_modules/shelljs/src/echo.js",
|
||
"./error": "./node_modules/shelljs/src/error.js",
|
||
"./error.js": "./node_modules/shelljs/src/error.js",
|
||
"./exec": "./node_modules/shelljs/src/exec.js",
|
||
"./exec-child": "./node_modules/shelljs/src/exec-child.js",
|
||
"./exec-child.js": "./node_modules/shelljs/src/exec-child.js",
|
||
"./exec.js": "./node_modules/shelljs/src/exec.js",
|
||
"./find": "./node_modules/shelljs/src/find.js",
|
||
"./find.js": "./node_modules/shelljs/src/find.js",
|
||
"./grep": "./node_modules/shelljs/src/grep.js",
|
||
"./grep.js": "./node_modules/shelljs/src/grep.js",
|
||
"./head": "./node_modules/shelljs/src/head.js",
|
||
"./head.js": "./node_modules/shelljs/src/head.js",
|
||
"./ln": "./node_modules/shelljs/src/ln.js",
|
||
"./ln.js": "./node_modules/shelljs/src/ln.js",
|
||
"./ls": "./node_modules/shelljs/src/ls.js",
|
||
"./ls.js": "./node_modules/shelljs/src/ls.js",
|
||
"./mkdir": "./node_modules/shelljs/src/mkdir.js",
|
||
"./mkdir.js": "./node_modules/shelljs/src/mkdir.js",
|
||
"./mv": "./node_modules/shelljs/src/mv.js",
|
||
"./mv.js": "./node_modules/shelljs/src/mv.js",
|
||
"./popd": "./node_modules/shelljs/src/popd.js",
|
||
"./popd.js": "./node_modules/shelljs/src/popd.js",
|
||
"./pushd": "./node_modules/shelljs/src/pushd.js",
|
||
"./pushd.js": "./node_modules/shelljs/src/pushd.js",
|
||
"./pwd": "./node_modules/shelljs/src/pwd.js",
|
||
"./pwd.js": "./node_modules/shelljs/src/pwd.js",
|
||
"./rm": "./node_modules/shelljs/src/rm.js",
|
||
"./rm.js": "./node_modules/shelljs/src/rm.js",
|
||
"./sed": "./node_modules/shelljs/src/sed.js",
|
||
"./sed.js": "./node_modules/shelljs/src/sed.js",
|
||
"./set": "./node_modules/shelljs/src/set.js",
|
||
"./set.js": "./node_modules/shelljs/src/set.js",
|
||
"./sort": "./node_modules/shelljs/src/sort.js",
|
||
"./sort.js": "./node_modules/shelljs/src/sort.js",
|
||
"./tail": "./node_modules/shelljs/src/tail.js",
|
||
"./tail.js": "./node_modules/shelljs/src/tail.js",
|
||
"./tempdir": "./node_modules/shelljs/src/tempdir.js",
|
||
"./tempdir.js": "./node_modules/shelljs/src/tempdir.js",
|
||
"./test": "./node_modules/shelljs/src/test.js",
|
||
"./test.js": "./node_modules/shelljs/src/test.js",
|
||
"./to": "./node_modules/shelljs/src/to.js",
|
||
"./to.js": "./node_modules/shelljs/src/to.js",
|
||
"./toEnd": "./node_modules/shelljs/src/toEnd.js",
|
||
"./toEnd.js": "./node_modules/shelljs/src/toEnd.js",
|
||
"./touch": "./node_modules/shelljs/src/touch.js",
|
||
"./touch.js": "./node_modules/shelljs/src/touch.js",
|
||
"./uniq": "./node_modules/shelljs/src/uniq.js",
|
||
"./uniq.js": "./node_modules/shelljs/src/uniq.js",
|
||
"./which": "./node_modules/shelljs/src/which.js",
|
||
"./which.js": "./node_modules/shelljs/src/which.js"
|
||
};
|
||
|
||
|
||
function webpackContext(req) {
|
||
var id = webpackContextResolve(req);
|
||
return __webpack_require__(id);
|
||
}
|
||
function webpackContextResolve(req) {
|
||
if(!__webpack_require__.o(map, req)) {
|
||
var e = new Error("Cannot find module '" + req + "'");
|
||
e.code = 'MODULE_NOT_FOUND';
|
||
throw e;
|
||
}
|
||
return map[req];
|
||
}
|
||
webpackContext.keys = function webpackContextKeys() {
|
||
return Object.keys(map);
|
||
};
|
||
webpackContext.resolve = webpackContextResolve;
|
||
module.exports = webpackContext;
|
||
webpackContext.id = "./node_modules/shelljs/src sync recursive ^\\.\\/.*$";
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/agent/azure/build-agent.ts":
|
||
/*!****************************************!*\
|
||
!*** ./src/agent/azure/build-agent.ts ***!
|
||
\****************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||
}) : (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
o[k2] = m[k];
|
||
}));
|
||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
}) : function(o, v) {
|
||
o["default"] = v;
|
||
});
|
||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||
};
|
||
var __importStar = (this && this.__importStar) || function (mod) {
|
||
if (mod && mod.__esModule) return mod;
|
||
var result = {};
|
||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
__setModuleDefault(result, mod);
|
||
return result;
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.BuildAgent = void 0;
|
||
const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js");
|
||
const taskLib = __importStar(__webpack_require__(/*! azure-pipelines-task-lib/task */ "./node_modules/azure-pipelines-task-lib/task.js"));
|
||
const toolLib = __importStar(__webpack_require__(/*! azure-pipelines-tool-lib/tool */ "./node_modules/azure-pipelines-tool-lib/tool.js"));
|
||
let BuildAgent = class BuildAgent {
|
||
get agentName() {
|
||
return 'Azure Pipelines';
|
||
}
|
||
proxyConfiguration(url) {
|
||
return {
|
||
proxy: taskLib.getHttpProxyConfiguration(url),
|
||
cert: taskLib.getHttpCertConfiguration(),
|
||
ignoreSslError: !!taskLib.getVariable('Agent.SkipCertValidation')
|
||
};
|
||
}
|
||
find(toolName, versionSpec, arch) {
|
||
return toolLib.findLocalTool(toolName, versionSpec, arch);
|
||
}
|
||
cacheDir(sourceDir, tool, version, arch) {
|
||
return toolLib.cacheDir(sourceDir, tool, version, arch);
|
||
}
|
||
createTempDir() {
|
||
return Promise.resolve(taskLib.getVariable('Agent.TempDirectory'));
|
||
}
|
||
debug(message) {
|
||
taskLib.debug(message);
|
||
}
|
||
setFailed(message, done) {
|
||
taskLib.setResult(taskLib.TaskResult.Failed, message, done);
|
||
}
|
||
setSucceeded(message, done) {
|
||
taskLib.setResult(taskLib.TaskResult.Succeeded, message, done);
|
||
}
|
||
exportVariable(name, val) {
|
||
taskLib.setVariable(name, val);
|
||
}
|
||
getVariable(name) {
|
||
return taskLib.getVariable(name);
|
||
}
|
||
addPath(inputPath) {
|
||
toolLib.prependPath(inputPath);
|
||
}
|
||
which(tool, check) {
|
||
return Promise.resolve(taskLib.which(tool, check));
|
||
}
|
||
exec(exec, args) {
|
||
const tr = taskLib.tool(exec);
|
||
tr.arg(args);
|
||
const result = tr.execSync();
|
||
return Promise.resolve({
|
||
code: result.code,
|
||
error: result.error,
|
||
stderr: result.stderr,
|
||
stdout: result.stdout
|
||
});
|
||
}
|
||
getSourceDir() {
|
||
return this.getVariable('Build.SourcesDirectory');
|
||
}
|
||
setOutput(name, value) {
|
||
taskLib.setVariable(name, value);
|
||
}
|
||
getInput(input, required) {
|
||
var _a;
|
||
return (_a = taskLib.getInput(input, required)) === null || _a === void 0 ? void 0 : _a.trim();
|
||
}
|
||
getListInput(input, required) {
|
||
return taskLib
|
||
.getInput(input, required)
|
||
.split('\n')
|
||
.filter(x => x !== '');
|
||
}
|
||
getBooleanInput(input, required) {
|
||
return taskLib.getBoolInput(input, required);
|
||
}
|
||
isValidInputFile(input, file) {
|
||
return taskLib.filePathSupplied(input) && this.fileExists(file);
|
||
}
|
||
fileExists(file) {
|
||
return taskLib.exist(file) && taskLib.stats(file).isFile();
|
||
}
|
||
directoryExists(file) {
|
||
return taskLib.exist(file) && taskLib.stats(file).isDirectory();
|
||
}
|
||
};
|
||
BuildAgent = __decorate([
|
||
inversify_1.injectable()
|
||
], BuildAgent);
|
||
exports.BuildAgent = BuildAgent;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/dotnet-tool.ts":
|
||
/*!*********************************!*\
|
||
!*** ./src/core/dotnet-tool.ts ***!
|
||
\*********************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||
}) : (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
o[k2] = m[k];
|
||
}));
|
||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
}) : function(o, v) {
|
||
o["default"] = v;
|
||
});
|
||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||
};
|
||
var __importStar = (this && this.__importStar) || function (mod) {
|
||
if (mod && mod.__esModule) return mod;
|
||
var result = {};
|
||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
__setModuleDefault(result, mod);
|
||
return result;
|
||
};
|
||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||
};
|
||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||
return function (target, key) { decorator(target, key, paramIndex); }
|
||
};
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
var DotnetTool_1;
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.DotnetTool = void 0;
|
||
const fs = __importStar(__webpack_require__(/*! fs */ "fs"));
|
||
const os = __importStar(__webpack_require__(/*! os */ "os"));
|
||
const path = __importStar(__webpack_require__(/*! path */ "path"));
|
||
const http = __importStar(__webpack_require__(/*! typed-rest-client/HttpClient */ "./node_modules/typed-rest-client/HttpClient.js"));
|
||
const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js");
|
||
const models_1 = __webpack_require__(/*! ./models */ "./src/core/models.ts");
|
||
let DotnetTool = DotnetTool_1 = class DotnetTool {
|
||
constructor(buildAgent, versionManager) {
|
||
this.buildAgent = buildAgent;
|
||
this.versionManager = versionManager;
|
||
this.httpClient = new http.HttpClient('dotnet', undefined, this.buildAgent.proxyConfiguration(DotnetTool_1.nugetRoot));
|
||
}
|
||
disableTelemetry() {
|
||
this.buildAgent.exportVariable('DOTNET_CLI_TELEMETRY_OPTOUT', 'true');
|
||
this.buildAgent.exportVariable('DOTNET_NOLOGO', 'true');
|
||
}
|
||
execute(cmd, args) {
|
||
console.log(`Command: ${cmd} ${args.join(' ')}`);
|
||
return this.buildAgent.exec(cmd, args);
|
||
}
|
||
toolInstall(toolName, versionSpec, checkLatest, includePre) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
console.log('');
|
||
console.log('--------------------------');
|
||
console.log(`Installing ${toolName} version ` + versionSpec);
|
||
console.log('--------------------------');
|
||
if (this.versionManager.isExplicitVersion(versionSpec)) {
|
||
checkLatest = false; // check latest doesn't make sense when explicit version
|
||
}
|
||
let toolPath;
|
||
if (!checkLatest) {
|
||
//
|
||
// Let's try and resolve the version spec locally first
|
||
//
|
||
toolPath = this.buildAgent.find(toolName, versionSpec);
|
||
}
|
||
if (!toolPath) {
|
||
let version;
|
||
if (this.versionManager.isExplicitVersion(versionSpec)) {
|
||
//
|
||
// Explicit version was specified. No need to query for list of versions.
|
||
//
|
||
version = versionSpec;
|
||
}
|
||
else {
|
||
//
|
||
// Let's query and resolve the latest version for the versionSpec.
|
||
// If the version is an explicit version (1.1.1 or v1.1.1) then no need to query.
|
||
// If your tool doesn't offer a mechanism to query,
|
||
// then it can only support exact version inputs.
|
||
//
|
||
version = yield this.queryLatestMatch(toolName, versionSpec, includePre);
|
||
if (!version) {
|
||
throw new Error(`Unable to find ${toolName} version '${versionSpec}'.`);
|
||
}
|
||
//
|
||
// Check the cache for the resolved version.
|
||
//
|
||
toolPath = this.buildAgent.find(toolName, version);
|
||
}
|
||
if (!toolPath) {
|
||
//
|
||
// Download, extract, cache
|
||
//
|
||
toolPath = yield this.acquireTool(toolName, version);
|
||
}
|
||
}
|
||
//
|
||
// Prepend the tools path. This prepends the PATH for the current process and
|
||
// instructs the agent to prepend for each task that follows.
|
||
//
|
||
this.buildAgent.debug(`toolPath: ${toolPath}`);
|
||
if (os.platform() !== 'win32' &&
|
||
!this.buildAgent.getVariable('DOTNET_ROOT')) {
|
||
let dotnetPath = yield this.buildAgent.which('dotnet');
|
||
dotnetPath = fs.readlinkSync(dotnetPath) || dotnetPath;
|
||
const dotnetRoot = path.dirname(dotnetPath);
|
||
this.buildAgent.exportVariable('DOTNET_ROOT', dotnetRoot);
|
||
}
|
||
this.buildAgent.addPath(toolPath);
|
||
return toolPath;
|
||
});
|
||
}
|
||
queryLatestMatch(toolName, versionSpec, includePrerelease) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
this.buildAgent.debug(`querying tool versions for ${toolName}${versionSpec ? `@${versionSpec}` : ''} ${includePrerelease ? 'including pre-releases' : ''}`);
|
||
const downloadPath = `${DotnetTool_1.nugetRoot}query?q=${encodeURIComponent(toolName.toLowerCase())}&prerelease=${includePrerelease ? 'true' : 'false'}&semVerLevel=2.0.0`;
|
||
const res = yield this.httpClient.get(downloadPath);
|
||
if (!res || res.message.statusCode !== 200) {
|
||
return null;
|
||
}
|
||
const body = yield res.readBody();
|
||
const data = JSON.parse(body).data;
|
||
const versions = data[0].versions.map(x => x.version);
|
||
if (!versions || !versions.length) {
|
||
return null;
|
||
}
|
||
this.buildAgent.debug(`got versions: ${versions.join(', ')}`);
|
||
return this.versionManager.evaluateVersions(versions, versionSpec);
|
||
});
|
||
}
|
||
acquireTool(toolName, version) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
const tempDirectory = yield this.buildAgent.createTempDir();
|
||
let args = ['tool', 'install', toolName, '--tool-path', tempDirectory];
|
||
if (version) {
|
||
version = this.versionManager.cleanVersion(version);
|
||
args = args.concat(['--version', version]);
|
||
}
|
||
const result = yield this.execute('dotnet', args);
|
||
const status = result.code === 0 ? 'success' : 'failure';
|
||
const message = result.code === 0 ? result.stdout : result.stderr;
|
||
this.buildAgent.debug(`tool install result: ${status} ${message}`);
|
||
if (result.code) {
|
||
throw new Error('Error installing tool');
|
||
}
|
||
return yield this.buildAgent.cacheDir(tempDirectory, toolName, version);
|
||
});
|
||
}
|
||
};
|
||
DotnetTool.nugetRoot = 'https://api-v2v3search-0.nuget.org/';
|
||
DotnetTool = DotnetTool_1 = __decorate([
|
||
inversify_1.injectable(),
|
||
__param(0, inversify_1.inject(models_1.TYPES.IBuildAgent)),
|
||
__param(1, inversify_1.inject(models_1.TYPES.IVersionManager)),
|
||
__metadata("design:paramtypes", [Object, Object])
|
||
], DotnetTool);
|
||
exports.DotnetTool = DotnetTool;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/ioc.ts":
|
||
/*!*************************!*\
|
||
!*** ./src/core/ioc.ts ***!
|
||
\*************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js");
|
||
const versionManager_1 = __webpack_require__(/*! ./versionManager */ "./src/core/versionManager.ts");
|
||
const models_1 = __webpack_require__(/*! ./models */ "./src/core/models.ts");
|
||
const build_agent_1 = __webpack_require__(/*! ../agent/mock/build-agent */ "./src/agent/azure/build-agent.ts");
|
||
const container = new inversify_1.Container();
|
||
container.bind(models_1.TYPES.IVersionManager).to(versionManager_1.VersionManager);
|
||
container.bind(models_1.TYPES.IBuildAgent).to(build_agent_1.BuildAgent);
|
||
exports.default = container;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/models.ts":
|
||
/*!****************************!*\
|
||
!*** ./src/core/models.ts ***!
|
||
\****************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.SetupFields = exports.TYPES = void 0;
|
||
exports.TYPES = {
|
||
IBuildAgent: Symbol.for('BuildAgent'),
|
||
IDotnetTool: Symbol.for('DotnetTool'),
|
||
IGitVersionTool: Symbol.for('GitVersionTool'),
|
||
IGitReleaseManagerTool: Symbol.for('GitReleaseManagerTool'),
|
||
IVersionManager: Symbol.for('VersionManager')
|
||
};
|
||
var SetupFields;
|
||
(function (SetupFields) {
|
||
SetupFields["includePrerelease"] = "includePrerelease";
|
||
SetupFields["versionSpec"] = "versionSpec";
|
||
})(SetupFields = exports.SetupFields || (exports.SetupFields = {}));
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/settings.ts":
|
||
/*!******************************!*\
|
||
!*** ./src/core/settings.ts ***!
|
||
\******************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Settings = void 0;
|
||
const models_1 = __webpack_require__(/*! ./models */ "./src/core/models.ts");
|
||
class Settings {
|
||
static getSetupSettings(buildAgent) {
|
||
const versionSpec = buildAgent.getInput(models_1.SetupFields.versionSpec);
|
||
const includePrerelease = buildAgent.getBooleanInput(models_1.SetupFields.includePrerelease);
|
||
return {
|
||
versionSpec,
|
||
includePrerelease
|
||
};
|
||
}
|
||
}
|
||
exports.Settings = Settings;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/core/versionManager.ts":
|
||
/*!************************************!*\
|
||
!*** ./src/core/versionManager.ts ***!
|
||
\************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||
}) : (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
o[k2] = m[k];
|
||
}));
|
||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
}) : function(o, v) {
|
||
o["default"] = v;
|
||
});
|
||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||
};
|
||
var __importStar = (this && this.__importStar) || function (mod) {
|
||
if (mod && mod.__esModule) return mod;
|
||
var result = {};
|
||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
__setModuleDefault(result, mod);
|
||
return result;
|
||
};
|
||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||
};
|
||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||
return function (target, key) { decorator(target, key, paramIndex); }
|
||
};
|
||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.VersionManager = void 0;
|
||
const semver_compare_1 = __importDefault(__webpack_require__(/*! semver-compare */ "./node_modules/semver-compare/index.js"));
|
||
const semver = __importStar(__webpack_require__(/*! semver */ "./node_modules/semver/semver.js"));
|
||
const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js");
|
||
const models_1 = __webpack_require__(/*! ./models */ "./src/core/models.ts");
|
||
let VersionManager = class VersionManager {
|
||
constructor(buildAgent) {
|
||
this.buildAgent = buildAgent;
|
||
}
|
||
isExplicitVersion(versionSpec) {
|
||
const c = semver.clean(versionSpec);
|
||
this.buildAgent.debug('isExplicit: ' + c);
|
||
const valid = semver.valid(c) != null;
|
||
this.buildAgent.debug('explicit? ' + valid);
|
||
return valid;
|
||
}
|
||
evaluateVersions(versions, versionSpec) {
|
||
let version;
|
||
this.buildAgent.debug('evaluating ' + versions.length + ' versions');
|
||
versions = versions.sort(semver_compare_1.default);
|
||
for (let i = versions.length - 1; i >= 0; i--) {
|
||
const potential = versions[i];
|
||
const satisfied = semver.satisfies(potential, versionSpec);
|
||
if (satisfied) {
|
||
version = potential;
|
||
break;
|
||
}
|
||
}
|
||
if (version) {
|
||
this.buildAgent.debug('matched: ' + version);
|
||
}
|
||
else {
|
||
this.buildAgent.debug('match not found');
|
||
}
|
||
return version;
|
||
}
|
||
cleanVersion(version) {
|
||
this.buildAgent.debug('cleaning: ' + version);
|
||
return semver.clean(version);
|
||
}
|
||
};
|
||
VersionManager = __decorate([
|
||
inversify_1.injectable(),
|
||
__param(0, inversify_1.inject(models_1.TYPES.IBuildAgent)),
|
||
__metadata("design:paramtypes", [Object])
|
||
], VersionManager);
|
||
exports.VersionManager = VersionManager;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tasks/gitreleasemanager/main.ts":
|
||
/*!*********************************************!*\
|
||
!*** ./src/tasks/gitreleasemanager/main.ts ***!
|
||
\*********************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.addAsset = exports.publish = exports.open = exports.close = exports.discard = exports.create = exports.setup = void 0;
|
||
const models_1 = __webpack_require__(/*! ../../core/models */ "./src/core/models.ts");
|
||
const tool_1 = __webpack_require__(/*! ../../tools/gitreleasemanager/tool */ "./src/tools/gitreleasemanager/tool.ts");
|
||
const settings_1 = __webpack_require__(/*! ../../core/settings */ "./src/core/settings.ts");
|
||
const settings_2 = __webpack_require__(/*! ../../tools/gitreleasemanager/settings */ "./src/tools/gitreleasemanager/settings.ts");
|
||
const ioc_1 = __importDefault(__webpack_require__(/*! ../../core/ioc */ "./src/core/ioc.ts"));
|
||
ioc_1.default
|
||
.bind(models_1.TYPES.IGitReleaseManagerTool)
|
||
.to(tool_1.GitReleaseManagerTool);
|
||
const gitReleaseManagerTool = ioc_1.default.get(models_1.TYPES.IGitReleaseManagerTool);
|
||
const buildAgent = ioc_1.default.get(models_1.TYPES.IBuildAgent);
|
||
function setup() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_1.Settings.getSetupSettings(buildAgent);
|
||
yield gitReleaseManagerTool.install(settings.versionSpec, settings.includePrerelease);
|
||
buildAgent.setSucceeded('GitVersionManager installed successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.setup = setup;
|
||
function create() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getCreateSettings(buildAgent);
|
||
yield gitReleaseManagerTool.create(settings);
|
||
buildAgent.setSucceeded('GitVersionManager created release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.create = create;
|
||
function discard() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getDiscardSettings(buildAgent);
|
||
yield gitReleaseManagerTool.discard(settings);
|
||
buildAgent.setSucceeded('GitVersionManager discarded release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.discard = discard;
|
||
function close() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getCloseSettings(buildAgent);
|
||
yield gitReleaseManagerTool.close(settings);
|
||
buildAgent.setSucceeded('GitVersionManager closed release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.close = close;
|
||
function open() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getOpenSettings(buildAgent);
|
||
yield gitReleaseManagerTool.open(settings);
|
||
buildAgent.setSucceeded('GitVersionManager opened release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.open = open;
|
||
function publish() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getPublishSettings(buildAgent);
|
||
yield gitReleaseManagerTool.publish(settings);
|
||
buildAgent.setSucceeded('GitVersionManager published release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.publish = publish;
|
||
function addAsset() {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
try {
|
||
gitReleaseManagerTool.disableTelemetry();
|
||
const settings = settings_2.Settings.getAddAssetSettings(buildAgent);
|
||
yield gitReleaseManagerTool.addAsset(settings);
|
||
buildAgent.setSucceeded('GitVersionManager added assets to release successfully', true);
|
||
}
|
||
catch (error) {
|
||
buildAgent.setFailed(error.message, true);
|
||
}
|
||
});
|
||
}
|
||
exports.addAsset = addAsset;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tasks/gitreleasemanager/open.ts":
|
||
/*!*********************************************!*\
|
||
!*** ./src/tasks/gitreleasemanager/open.ts ***!
|
||
\*********************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
__webpack_require__(/*! reflect-metadata */ "./node_modules/reflect-metadata/Reflect.js");
|
||
const main_1 = __webpack_require__(/*! ./main */ "./src/tasks/gitreleasemanager/main.ts");
|
||
main_1.open();
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tools/gitreleasemanager/models.ts":
|
||
/*!***********************************************!*\
|
||
!*** ./src/tools/gitreleasemanager/models.ts ***!
|
||
\***********************************************/
|
||
/***/ ((__unused_webpack_module, exports) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.AddAssetFields = exports.PublishFields = exports.OpenFields = exports.CloseFields = exports.DiscardFields = exports.CreateFields = exports.CommonFields = void 0;
|
||
var CommonFields;
|
||
(function (CommonFields) {
|
||
CommonFields["repository"] = "repository";
|
||
CommonFields["owner"] = "owner";
|
||
CommonFields["token"] = "token";
|
||
CommonFields["targetDirectory"] = "targetDirectory";
|
||
})(CommonFields = exports.CommonFields || (exports.CommonFields = {}));
|
||
var CreateFields;
|
||
(function (CreateFields) {
|
||
CreateFields["milestone"] = "milestone";
|
||
CreateFields["name"] = "name";
|
||
CreateFields["inputFileName"] = "inputFileName";
|
||
CreateFields["isPreRelease"] = "isPreRelease";
|
||
CreateFields["commit"] = "commit";
|
||
CreateFields["assets"] = "assets";
|
||
})(CreateFields = exports.CreateFields || (exports.CreateFields = {}));
|
||
var DiscardFields;
|
||
(function (DiscardFields) {
|
||
DiscardFields["milestone"] = "milestone";
|
||
})(DiscardFields = exports.DiscardFields || (exports.DiscardFields = {}));
|
||
var CloseFields;
|
||
(function (CloseFields) {
|
||
CloseFields["milestone"] = "milestone";
|
||
})(CloseFields = exports.CloseFields || (exports.CloseFields = {}));
|
||
var OpenFields;
|
||
(function (OpenFields) {
|
||
OpenFields["milestone"] = "milestone";
|
||
})(OpenFields = exports.OpenFields || (exports.OpenFields = {}));
|
||
var PublishFields;
|
||
(function (PublishFields) {
|
||
PublishFields["tagName"] = "tagName";
|
||
})(PublishFields = exports.PublishFields || (exports.PublishFields = {}));
|
||
var AddAssetFields;
|
||
(function (AddAssetFields) {
|
||
AddAssetFields["tagName"] = "tagName";
|
||
AddAssetFields["assets"] = "assets";
|
||
})(AddAssetFields = exports.AddAssetFields || (exports.AddAssetFields = {}));
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tools/gitreleasemanager/settings.ts":
|
||
/*!*************************************************!*\
|
||
!*** ./src/tools/gitreleasemanager/settings.ts ***!
|
||
\*************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.Settings = void 0;
|
||
const models_1 = __webpack_require__(/*! ./models */ "./src/tools/gitreleasemanager/models.ts");
|
||
class Settings {
|
||
static getCreateSettings(buildAgent) {
|
||
const milestone = buildAgent.getInput(models_1.CreateFields.milestone);
|
||
const name = buildAgent.getInput(models_1.CreateFields.name);
|
||
const inputFileName = buildAgent.getInput(models_1.CreateFields.inputFileName);
|
||
const isPreRelease = buildAgent.getBooleanInput(models_1.CreateFields.isPreRelease);
|
||
const commit = buildAgent.getInput(models_1.CreateFields.commit);
|
||
const assets = buildAgent.getListInput(models_1.CreateFields.assets);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { milestone,
|
||
name,
|
||
inputFileName,
|
||
isPreRelease,
|
||
commit,
|
||
assets });
|
||
}
|
||
static getDiscardSettings(buildAgent) {
|
||
const milestone = buildAgent.getInput(models_1.DiscardFields.milestone);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { milestone });
|
||
}
|
||
static getCloseSettings(buildAgent) {
|
||
const milestone = buildAgent.getInput(models_1.CloseFields.milestone);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { milestone });
|
||
}
|
||
static getOpenSettings(buildAgent) {
|
||
const milestone = buildAgent.getInput(models_1.OpenFields.milestone);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { milestone });
|
||
}
|
||
static getPublishSettings(buildAgent) {
|
||
const tagName = buildAgent.getInput(models_1.PublishFields.tagName);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { tagName });
|
||
}
|
||
static getAddAssetSettings(buildAgent) {
|
||
const tagName = buildAgent.getInput(models_1.AddAssetFields.tagName);
|
||
const assets = buildAgent.getListInput(models_1.AddAssetFields.assets);
|
||
const commonSettings = Settings.getCommonSettings(buildAgent);
|
||
return Object.assign(Object.assign({}, commonSettings), { tagName,
|
||
assets });
|
||
}
|
||
static getCommonSettings(buildAgent) {
|
||
const owner = buildAgent.getInput(models_1.CommonFields.owner, true);
|
||
const repository = buildAgent.getInput(models_1.CommonFields.repository, true);
|
||
const token = buildAgent.getInput(models_1.CommonFields.token, true);
|
||
const targetDirectory = buildAgent.getInput(models_1.CommonFields.targetDirectory);
|
||
return {
|
||
owner,
|
||
repository,
|
||
token,
|
||
targetDirectory
|
||
};
|
||
}
|
||
}
|
||
exports.Settings = Settings;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./src/tools/gitreleasemanager/tool.ts":
|
||
/*!*********************************************!*\
|
||
!*** ./src/tools/gitreleasemanager/tool.ts ***!
|
||
\*********************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||
};
|
||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||
};
|
||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||
return function (target, key) { decorator(target, key, paramIndex); }
|
||
};
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
exports.GitReleaseManagerTool = void 0;
|
||
const path = __webpack_require__(/*! path */ "path");
|
||
const models_1 = __webpack_require__(/*! ../../core/models */ "./src/core/models.ts");
|
||
const inversify_1 = __webpack_require__(/*! inversify */ "./node_modules/inversify/lib/inversify.js");
|
||
const dotnet_tool_1 = __webpack_require__(/*! ../../core/dotnet-tool */ "./src/core/dotnet-tool.ts");
|
||
let GitReleaseManagerTool = class GitReleaseManagerTool extends dotnet_tool_1.DotnetTool {
|
||
constructor(buildAgent, versionManager) {
|
||
super(buildAgent, versionManager);
|
||
}
|
||
install(versionSpec, includePrerelease) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
yield this.toolInstall('GitReleaseManager.Tool', versionSpec, false, includePrerelease);
|
||
});
|
||
}
|
||
create(settings) {
|
||
const args = this.getCreateArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
discard(settings) {
|
||
const args = this.getDiscardArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
close(settings) {
|
||
const args = this.getCloseArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
open(settings) {
|
||
const args = this.getOpenArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
publish(settings) {
|
||
const args = this.getPublishArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
addAsset(settings) {
|
||
const args = this.getAddAssetArguments(settings);
|
||
return this.execute('dotnet-gitreleasemanager', args);
|
||
}
|
||
getCommonArguments(settings) {
|
||
const args = [];
|
||
args.push('--owner', settings.owner);
|
||
args.push('--repository', settings.repository);
|
||
args.push('--token', settings.token);
|
||
settings.targetDirectory = this.getRepoDir(settings.targetDirectory);
|
||
args.push('--targetDirectory', settings.targetDirectory);
|
||
return args;
|
||
}
|
||
getCreateArguments(settings) {
|
||
const args = ['create', ...this.getCommonArguments(settings)];
|
||
if (settings.milestone) {
|
||
args.push('--milestone', settings.milestone);
|
||
}
|
||
if (settings.name) {
|
||
args.push('--name', settings.name);
|
||
}
|
||
if (settings.commit) {
|
||
args.push('--targetcommitish', settings.commit);
|
||
}
|
||
if (settings.inputFileName) {
|
||
if (this.buildAgent.fileExists(settings.inputFileName)) {
|
||
args.push('--inputFilePath', settings.inputFileName);
|
||
}
|
||
else {
|
||
throw new Error('GitReleaseManager inputFilePath not found at ' +
|
||
settings.inputFileName);
|
||
}
|
||
}
|
||
if (settings.isPreRelease) {
|
||
args.push('--pre');
|
||
}
|
||
if (settings.assets && settings.assets.length > 0) {
|
||
settings.assets = settings.assets.map(asset => {
|
||
return path.join(settings.targetDirectory, asset);
|
||
});
|
||
args.push('--assets', settings.assets.join(','));
|
||
}
|
||
return args;
|
||
}
|
||
getDiscardArguments(settings) {
|
||
const args = ['discard', ...this.getCommonArguments(settings)];
|
||
if (settings.milestone) {
|
||
args.push('--milestone', settings.milestone);
|
||
}
|
||
return args;
|
||
}
|
||
getCloseArguments(settings) {
|
||
const args = ['close', ...this.getCommonArguments(settings)];
|
||
if (settings.milestone) {
|
||
args.push('--milestone', settings.milestone);
|
||
}
|
||
return args;
|
||
}
|
||
getOpenArguments(settings) {
|
||
const args = ['open', ...this.getCommonArguments(settings)];
|
||
if (settings.milestone) {
|
||
args.push('--milestone', settings.milestone);
|
||
}
|
||
return args;
|
||
}
|
||
getPublishArguments(settings) {
|
||
const args = ['publish', ...this.getCommonArguments(settings)];
|
||
if (settings.tagName) {
|
||
args.push('--tagName', settings.tagName);
|
||
}
|
||
return args;
|
||
}
|
||
getAddAssetArguments(settings) {
|
||
const args = [
|
||
'addasset',
|
||
...this.getCommonArguments(settings)
|
||
];
|
||
if (settings.tagName) {
|
||
args.push('--tagName', settings.tagName);
|
||
}
|
||
if (settings.assets && settings.assets.length > 0) {
|
||
settings.assets = settings.assets.map(asset => {
|
||
return path.join(settings.targetDirectory, asset);
|
||
});
|
||
args.push('--assets', settings.assets.join(','));
|
||
}
|
||
return args;
|
||
}
|
||
getRepoDir(targetPath) {
|
||
let workDir;
|
||
const srcDir = this.buildAgent.getSourceDir();
|
||
if (!targetPath) {
|
||
workDir = srcDir;
|
||
}
|
||
else {
|
||
if (this.buildAgent.directoryExists(targetPath)) {
|
||
workDir = path.join(srcDir, targetPath);
|
||
}
|
||
else {
|
||
throw new Error('Directory not found at ' + targetPath);
|
||
}
|
||
}
|
||
return workDir.replace(/\\/g, '/');
|
||
}
|
||
};
|
||
GitReleaseManagerTool = __decorate([
|
||
inversify_1.injectable(),
|
||
__param(0, inversify_1.inject(models_1.TYPES.IBuildAgent)),
|
||
__param(1, inversify_1.inject(models_1.TYPES.IVersionManager)),
|
||
__metadata("design:paramtypes", [Object, Object])
|
||
], GitReleaseManagerTool);
|
||
exports.GitReleaseManagerTool = GitReleaseManagerTool;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/typed-rest-client/HttpClient.js":
|
||
/*!******************************************************!*\
|
||
!*** ./node_modules/typed-rest-client/HttpClient.js ***!
|
||
\******************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
// Copyright (c) Microsoft. All rights reserved.
|
||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
const url = __webpack_require__(/*! url */ "url");
|
||
const http = __webpack_require__(/*! http */ "http");
|
||
const https = __webpack_require__(/*! https */ "https");
|
||
const util = __webpack_require__(/*! ./Util */ "./node_modules/typed-rest-client/Util.js");
|
||
let fs;
|
||
let tunnel;
|
||
var HttpCodes;
|
||
(function (HttpCodes) {
|
||
HttpCodes[HttpCodes["OK"] = 200] = "OK";
|
||
HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices";
|
||
HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently";
|
||
HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved";
|
||
HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther";
|
||
HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified";
|
||
HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy";
|
||
HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy";
|
||
HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect";
|
||
HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect";
|
||
HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest";
|
||
HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized";
|
||
HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired";
|
||
HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden";
|
||
HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound";
|
||
HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed";
|
||
HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable";
|
||
HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
|
||
HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
|
||
HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
|
||
HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
|
||
HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests";
|
||
HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
|
||
HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
|
||
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
|
||
HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable";
|
||
HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout";
|
||
})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));
|
||
const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect];
|
||
const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout];
|
||
const NetworkRetryErrors = ['ECONNRESET', 'ENOTFOUND', 'ESOCKETTIMEDOUT', 'ETIMEDOUT', 'ECONNREFUSED'];
|
||
const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
|
||
const ExponentialBackoffCeiling = 10;
|
||
const ExponentialBackoffTimeSlice = 5;
|
||
class HttpClientResponse {
|
||
constructor(message) {
|
||
this.message = message;
|
||
}
|
||
readBody() {
|
||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||
let buffer = Buffer.alloc(0);
|
||
const encodingCharset = util.obtainContentCharset(this);
|
||
// Extract Encoding from header: 'content-encoding'
|
||
// Match `gzip`, `gzip, deflate` variations of GZIP encoding
|
||
const contentEncoding = this.message.headers['content-encoding'] || '';
|
||
const isGzippedEncoded = new RegExp('(gzip$)|(gzip, *deflate)').test(contentEncoding);
|
||
this.message.on('data', function (data) {
|
||
const chunk = (typeof data === 'string') ? Buffer.from(data, encodingCharset) : data;
|
||
buffer = Buffer.concat([buffer, chunk]);
|
||
}).on('end', function () {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
if (isGzippedEncoded) { // Process GZipped Response Body HERE
|
||
const gunzippedBody = yield util.decompressGzippedContent(buffer, encodingCharset);
|
||
resolve(gunzippedBody);
|
||
}
|
||
else {
|
||
resolve(buffer.toString(encodingCharset));
|
||
}
|
||
});
|
||
}).on('error', function (err) {
|
||
reject(err);
|
||
});
|
||
}));
|
||
}
|
||
}
|
||
exports.HttpClientResponse = HttpClientResponse;
|
||
function isHttps(requestUrl) {
|
||
let parsedUrl = url.parse(requestUrl);
|
||
return parsedUrl.protocol === 'https:';
|
||
}
|
||
exports.isHttps = isHttps;
|
||
var EnvironmentVariables;
|
||
(function (EnvironmentVariables) {
|
||
EnvironmentVariables["HTTP_PROXY"] = "HTTP_PROXY";
|
||
EnvironmentVariables["HTTPS_PROXY"] = "HTTPS_PROXY";
|
||
EnvironmentVariables["NO_PROXY"] = "NO_PROXY";
|
||
})(EnvironmentVariables || (EnvironmentVariables = {}));
|
||
class HttpClient {
|
||
constructor(userAgent, handlers, requestOptions) {
|
||
this._ignoreSslError = false;
|
||
this._allowRedirects = true;
|
||
this._allowRedirectDowngrade = false;
|
||
this._maxRedirects = 50;
|
||
this._allowRetries = false;
|
||
this._maxRetries = 1;
|
||
this._keepAlive = false;
|
||
this._disposed = false;
|
||
this.userAgent = userAgent;
|
||
this.handlers = handlers || [];
|
||
let no_proxy = process.env[EnvironmentVariables.NO_PROXY];
|
||
if (no_proxy) {
|
||
this._httpProxyBypassHosts = [];
|
||
no_proxy.split(',').forEach(bypass => {
|
||
this._httpProxyBypassHosts.push(util.buildProxyBypassRegexFromEnv(bypass));
|
||
});
|
||
}
|
||
this.requestOptions = requestOptions;
|
||
if (requestOptions) {
|
||
if (requestOptions.ignoreSslError != null) {
|
||
this._ignoreSslError = requestOptions.ignoreSslError;
|
||
}
|
||
this._socketTimeout = requestOptions.socketTimeout;
|
||
this._httpProxy = requestOptions.proxy;
|
||
if (requestOptions.proxy && requestOptions.proxy.proxyBypassHosts) {
|
||
this._httpProxyBypassHosts = [];
|
||
requestOptions.proxy.proxyBypassHosts.forEach(bypass => {
|
||
this._httpProxyBypassHosts.push(new RegExp(bypass, 'i'));
|
||
});
|
||
}
|
||
this._certConfig = requestOptions.cert;
|
||
if (this._certConfig) {
|
||
// If using cert, need fs
|
||
fs = __webpack_require__(/*! fs */ "fs");
|
||
// cache the cert content into memory, so we don't have to read it from disk every time
|
||
if (this._certConfig.caFile && fs.existsSync(this._certConfig.caFile)) {
|
||
this._ca = fs.readFileSync(this._certConfig.caFile, 'utf8');
|
||
}
|
||
if (this._certConfig.certFile && fs.existsSync(this._certConfig.certFile)) {
|
||
this._cert = fs.readFileSync(this._certConfig.certFile, 'utf8');
|
||
}
|
||
if (this._certConfig.keyFile && fs.existsSync(this._certConfig.keyFile)) {
|
||
this._key = fs.readFileSync(this._certConfig.keyFile, 'utf8');
|
||
}
|
||
}
|
||
if (requestOptions.allowRedirects != null) {
|
||
this._allowRedirects = requestOptions.allowRedirects;
|
||
}
|
||
if (requestOptions.allowRedirectDowngrade != null) {
|
||
this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade;
|
||
}
|
||
if (requestOptions.maxRedirects != null) {
|
||
this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);
|
||
}
|
||
if (requestOptions.keepAlive != null) {
|
||
this._keepAlive = requestOptions.keepAlive;
|
||
}
|
||
if (requestOptions.allowRetries != null) {
|
||
this._allowRetries = requestOptions.allowRetries;
|
||
}
|
||
if (requestOptions.maxRetries != null) {
|
||
this._maxRetries = requestOptions.maxRetries;
|
||
}
|
||
}
|
||
}
|
||
options(requestUrl, additionalHeaders) {
|
||
return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});
|
||
}
|
||
get(requestUrl, additionalHeaders) {
|
||
return this.request('GET', requestUrl, null, additionalHeaders || {});
|
||
}
|
||
del(requestUrl, additionalHeaders) {
|
||
return this.request('DELETE', requestUrl, null, additionalHeaders || {});
|
||
}
|
||
post(requestUrl, data, additionalHeaders) {
|
||
return this.request('POST', requestUrl, data, additionalHeaders || {});
|
||
}
|
||
patch(requestUrl, data, additionalHeaders) {
|
||
return this.request('PATCH', requestUrl, data, additionalHeaders || {});
|
||
}
|
||
put(requestUrl, data, additionalHeaders) {
|
||
return this.request('PUT', requestUrl, data, additionalHeaders || {});
|
||
}
|
||
head(requestUrl, additionalHeaders) {
|
||
return this.request('HEAD', requestUrl, null, additionalHeaders || {});
|
||
}
|
||
sendStream(verb, requestUrl, stream, additionalHeaders) {
|
||
return this.request(verb, requestUrl, stream, additionalHeaders);
|
||
}
|
||
/**
|
||
* Makes a raw http request.
|
||
* All other methods such as get, post, patch, and request ultimately call this.
|
||
* Prefer get, del, post and patch
|
||
*/
|
||
request(verb, requestUrl, data, headers) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
if (this._disposed) {
|
||
throw new Error("Client has already been disposed.");
|
||
}
|
||
let parsedUrl = url.parse(requestUrl);
|
||
let info = this._prepareRequest(verb, parsedUrl, headers);
|
||
// Only perform retries on reads since writes may not be idempotent.
|
||
let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1;
|
||
let numTries = 0;
|
||
let response;
|
||
while (numTries < maxTries) {
|
||
try {
|
||
response = yield this.requestRaw(info, data);
|
||
}
|
||
catch (err) {
|
||
numTries++;
|
||
if (err && err.code && NetworkRetryErrors.indexOf(err.code) > -1 && numTries < maxTries) {
|
||
yield this._performExponentialBackoff(numTries);
|
||
continue;
|
||
}
|
||
throw err;
|
||
}
|
||
// Check if it's an authentication challenge
|
||
if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) {
|
||
let authenticationHandler;
|
||
for (let i = 0; i < this.handlers.length; i++) {
|
||
if (this.handlers[i].canHandleAuthentication(response)) {
|
||
authenticationHandler = this.handlers[i];
|
||
break;
|
||
}
|
||
}
|
||
if (authenticationHandler) {
|
||
return authenticationHandler.handleAuthentication(this, info, data);
|
||
}
|
||
else {
|
||
// We have received an unauthorized response but have no handlers to handle it.
|
||
// Let the response return to the caller.
|
||
return response;
|
||
}
|
||
}
|
||
let redirectsRemaining = this._maxRedirects;
|
||
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1
|
||
&& this._allowRedirects
|
||
&& redirectsRemaining > 0) {
|
||
const redirectUrl = response.message.headers["location"];
|
||
if (!redirectUrl) {
|
||
// if there's no location to redirect to, we won't
|
||
break;
|
||
}
|
||
let parsedRedirectUrl = url.parse(redirectUrl);
|
||
if (parsedUrl.protocol == 'https:' && parsedUrl.protocol != parsedRedirectUrl.protocol && !this._allowRedirectDowngrade) {
|
||
throw new Error("Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.");
|
||
}
|
||
// we need to finish reading the response before reassigning response
|
||
// which will leak the open socket.
|
||
yield response.readBody();
|
||
// let's make the request with the new redirectUrl
|
||
info = this._prepareRequest(verb, parsedRedirectUrl, headers);
|
||
response = yield this.requestRaw(info, data);
|
||
redirectsRemaining--;
|
||
}
|
||
if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) {
|
||
// If not a retry code, return immediately instead of retrying
|
||
return response;
|
||
}
|
||
numTries += 1;
|
||
if (numTries < maxTries) {
|
||
yield response.readBody();
|
||
yield this._performExponentialBackoff(numTries);
|
||
}
|
||
}
|
||
return response;
|
||
});
|
||
}
|
||
/**
|
||
* Needs to be called if keepAlive is set to true in request options.
|
||
*/
|
||
dispose() {
|
||
if (this._agent) {
|
||
this._agent.destroy();
|
||
}
|
||
this._disposed = true;
|
||
}
|
||
/**
|
||
* Raw request.
|
||
* @param info
|
||
* @param data
|
||
*/
|
||
requestRaw(info, data) {
|
||
return new Promise((resolve, reject) => {
|
||
let callbackForResult = function (err, res) {
|
||
if (err) {
|
||
reject(err);
|
||
}
|
||
resolve(res);
|
||
};
|
||
this.requestRawWithCallback(info, data, callbackForResult);
|
||
});
|
||
}
|
||
/**
|
||
* Raw request with callback.
|
||
* @param info
|
||
* @param data
|
||
* @param onResult
|
||
*/
|
||
requestRawWithCallback(info, data, onResult) {
|
||
let socket;
|
||
if (typeof (data) === 'string') {
|
||
info.options.headers["Content-Length"] = Buffer.byteLength(data, 'utf8');
|
||
}
|
||
let callbackCalled = false;
|
||
let handleResult = (err, res) => {
|
||
if (!callbackCalled) {
|
||
callbackCalled = true;
|
||
onResult(err, res);
|
||
}
|
||
};
|
||
let req = info.httpModule.request(info.options, (msg) => {
|
||
let res = new HttpClientResponse(msg);
|
||
handleResult(null, res);
|
||
});
|
||
req.on('socket', (sock) => {
|
||
socket = sock;
|
||
});
|
||
// If we ever get disconnected, we want the socket to timeout eventually
|
||
req.setTimeout(this._socketTimeout || 3 * 60000, () => {
|
||
if (socket) {
|
||
socket.destroy();
|
||
}
|
||
handleResult(new Error('Request timeout: ' + info.options.path), null);
|
||
});
|
||
req.on('error', function (err) {
|
||
// err has statusCode property
|
||
// res should have headers
|
||
handleResult(err, null);
|
||
});
|
||
if (data && typeof (data) === 'string') {
|
||
req.write(data, 'utf8');
|
||
}
|
||
if (data && typeof (data) !== 'string') {
|
||
data.on('close', function () {
|
||
req.end();
|
||
});
|
||
data.pipe(req);
|
||
}
|
||
else {
|
||
req.end();
|
||
}
|
||
}
|
||
_prepareRequest(method, requestUrl, headers) {
|
||
const info = {};
|
||
info.parsedUrl = requestUrl;
|
||
const usingSsl = info.parsedUrl.protocol === 'https:';
|
||
info.httpModule = usingSsl ? https : http;
|
||
const defaultPort = usingSsl ? 443 : 80;
|
||
info.options = {};
|
||
info.options.host = info.parsedUrl.hostname;
|
||
info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort;
|
||
info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
|
||
info.options.method = method;
|
||
info.options.timeout = (this.requestOptions && this.requestOptions.socketTimeout) || this._socketTimeout;
|
||
this._socketTimeout = info.options.timeout;
|
||
info.options.headers = this._mergeHeaders(headers);
|
||
if (this.userAgent != null) {
|
||
info.options.headers["user-agent"] = this.userAgent;
|
||
}
|
||
info.options.agent = this._getAgent(info.parsedUrl);
|
||
// gives handlers an opportunity to participate
|
||
if (this.handlers && !this._isPresigned(url.format(requestUrl))) {
|
||
this.handlers.forEach((handler) => {
|
||
handler.prepareRequest(info.options);
|
||
});
|
||
}
|
||
return info;
|
||
}
|
||
_isPresigned(requestUrl) {
|
||
if (this.requestOptions && this.requestOptions.presignedUrlPatterns) {
|
||
const patterns = this.requestOptions.presignedUrlPatterns;
|
||
for (let i = 0; i < patterns.length; i++) {
|
||
if (requestUrl.match(patterns[i])) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
_mergeHeaders(headers) {
|
||
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {});
|
||
if (this.requestOptions && this.requestOptions.headers) {
|
||
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));
|
||
}
|
||
return lowercaseKeys(headers || {});
|
||
}
|
||
_getAgent(parsedUrl) {
|
||
let agent;
|
||
let proxy = this._getProxy(parsedUrl);
|
||
let useProxy = proxy.proxyUrl && proxy.proxyUrl.hostname && !this._isMatchInBypassProxyList(parsedUrl);
|
||
if (this._keepAlive && useProxy) {
|
||
agent = this._proxyAgent;
|
||
}
|
||
if (this._keepAlive && !useProxy) {
|
||
agent = this._agent;
|
||
}
|
||
// if agent is already assigned use that agent.
|
||
if (!!agent) {
|
||
return agent;
|
||
}
|
||
const usingSsl = parsedUrl.protocol === 'https:';
|
||
let maxSockets = 100;
|
||
if (!!this.requestOptions) {
|
||
maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;
|
||
}
|
||
if (useProxy) {
|
||
// If using proxy, need tunnel
|
||
if (!tunnel) {
|
||
tunnel = __webpack_require__(/*! tunnel */ "./node_modules/typed-rest-client/node_modules/tunnel/index.js");
|
||
}
|
||
const agentOptions = {
|
||
maxSockets: maxSockets,
|
||
keepAlive: this._keepAlive,
|
||
proxy: {
|
||
proxyAuth: proxy.proxyAuth,
|
||
host: proxy.proxyUrl.hostname,
|
||
port: proxy.proxyUrl.port
|
||
},
|
||
};
|
||
let tunnelAgent;
|
||
const overHttps = proxy.proxyUrl.protocol === 'https:';
|
||
if (usingSsl) {
|
||
tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp;
|
||
}
|
||
else {
|
||
tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp;
|
||
}
|
||
agent = tunnelAgent(agentOptions);
|
||
this._proxyAgent = agent;
|
||
}
|
||
// if reusing agent across request and tunneling agent isn't assigned create a new agent
|
||
if (this._keepAlive && !agent) {
|
||
const options = { keepAlive: this._keepAlive, maxSockets: maxSockets };
|
||
agent = usingSsl ? new https.Agent(options) : new http.Agent(options);
|
||
this._agent = agent;
|
||
}
|
||
// if not using private agent and tunnel agent isn't setup then use global agent
|
||
if (!agent) {
|
||
agent = usingSsl ? https.globalAgent : http.globalAgent;
|
||
}
|
||
if (usingSsl && this._ignoreSslError) {
|
||
// we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
|
||
// http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
|
||
// we have to cast it to any and change it directly
|
||
agent.options = Object.assign(agent.options || {}, { rejectUnauthorized: false });
|
||
}
|
||
if (usingSsl && this._certConfig) {
|
||
agent.options = Object.assign(agent.options || {}, { ca: this._ca, cert: this._cert, key: this._key, passphrase: this._certConfig.passphrase });
|
||
}
|
||
return agent;
|
||
}
|
||
_getProxy(parsedUrl) {
|
||
let usingSsl = parsedUrl.protocol === 'https:';
|
||
let proxyConfig = this._httpProxy;
|
||
// fallback to http_proxy and https_proxy env
|
||
let https_proxy = process.env[EnvironmentVariables.HTTPS_PROXY];
|
||
let http_proxy = process.env[EnvironmentVariables.HTTP_PROXY];
|
||
if (!proxyConfig) {
|
||
if (https_proxy && usingSsl) {
|
||
proxyConfig = {
|
||
proxyUrl: https_proxy
|
||
};
|
||
}
|
||
else if (http_proxy) {
|
||
proxyConfig = {
|
||
proxyUrl: http_proxy
|
||
};
|
||
}
|
||
}
|
||
let proxyUrl;
|
||
let proxyAuth;
|
||
if (proxyConfig) {
|
||
if (proxyConfig.proxyUrl.length > 0) {
|
||
proxyUrl = url.parse(proxyConfig.proxyUrl);
|
||
}
|
||
if (proxyConfig.proxyUsername || proxyConfig.proxyPassword) {
|
||
proxyAuth = proxyConfig.proxyUsername + ":" + proxyConfig.proxyPassword;
|
||
}
|
||
}
|
||
return { proxyUrl: proxyUrl, proxyAuth: proxyAuth };
|
||
}
|
||
_isMatchInBypassProxyList(parsedUrl) {
|
||
if (!this._httpProxyBypassHosts) {
|
||
return false;
|
||
}
|
||
let bypass = false;
|
||
this._httpProxyBypassHosts.forEach(bypassHost => {
|
||
if (bypassHost.test(parsedUrl.href)) {
|
||
bypass = true;
|
||
}
|
||
});
|
||
return bypass;
|
||
}
|
||
_performExponentialBackoff(retryNumber) {
|
||
retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);
|
||
const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);
|
||
return new Promise(resolve => setTimeout(() => resolve(), ms));
|
||
}
|
||
}
|
||
exports.HttpClient = HttpClient;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/typed-rest-client/Util.js":
|
||
/*!************************************************!*\
|
||
!*** ./node_modules/typed-rest-client/Util.js ***!
|
||
\************************************************/
|
||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
// Copyright (c) Microsoft. All rights reserved.
|
||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
return new (P || (P = Promise))(function (resolve, reject) {
|
||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
});
|
||
};
|
||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
const qs = __webpack_require__(/*! qs */ "./node_modules/qs/lib/index.js");
|
||
const url = __webpack_require__(/*! url */ "url");
|
||
const path = __webpack_require__(/*! path */ "path");
|
||
const zlib = __webpack_require__(/*! zlib */ "zlib");
|
||
/**
|
||
* creates an url from a request url and optional base url (http://server:8080)
|
||
* @param {string} resource - a fully qualified url or relative path
|
||
* @param {string} baseUrl - an optional baseUrl (http://server:8080)
|
||
* @param {IRequestOptions} options - an optional options object, could include QueryParameters e.g.
|
||
* @return {string} - resultant url
|
||
*/
|
||
function getUrl(resource, baseUrl, queryParams) {
|
||
const pathApi = path.posix || path;
|
||
let requestUrl = '';
|
||
if (!baseUrl) {
|
||
requestUrl = resource;
|
||
}
|
||
else if (!resource) {
|
||
requestUrl = baseUrl;
|
||
}
|
||
else {
|
||
const base = url.parse(baseUrl);
|
||
const resultantUrl = url.parse(resource);
|
||
// resource (specific per request) elements take priority
|
||
resultantUrl.protocol = resultantUrl.protocol || base.protocol;
|
||
resultantUrl.auth = resultantUrl.auth || base.auth;
|
||
resultantUrl.host = resultantUrl.host || base.host;
|
||
resultantUrl.pathname = pathApi.resolve(base.pathname, resultantUrl.pathname);
|
||
if (!resultantUrl.pathname.endsWith('/') && resource.endsWith('/')) {
|
||
resultantUrl.pathname += '/';
|
||
}
|
||
requestUrl = url.format(resultantUrl);
|
||
}
|
||
return queryParams ?
|
||
getUrlWithParsedQueryParams(requestUrl, queryParams) :
|
||
requestUrl;
|
||
}
|
||
exports.getUrl = getUrl;
|
||
/**
|
||
*
|
||
* @param {string} requestUrl
|
||
* @param {IRequestQueryParams} queryParams
|
||
* @return {string} - Request's URL with Query Parameters appended/parsed.
|
||
*/
|
||
function getUrlWithParsedQueryParams(requestUrl, queryParams) {
|
||
const url = requestUrl.replace(/\?$/g, ''); // Clean any extra end-of-string "?" character
|
||
const parsedQueryParams = qs.stringify(queryParams.params, buildParamsStringifyOptions(queryParams));
|
||
return `${url}${parsedQueryParams}`;
|
||
}
|
||
/**
|
||
* Build options for QueryParams Stringifying.
|
||
*
|
||
* @param {IRequestQueryParams} queryParams
|
||
* @return {object}
|
||
*/
|
||
function buildParamsStringifyOptions(queryParams) {
|
||
let options = {
|
||
addQueryPrefix: true,
|
||
delimiter: (queryParams.options || {}).separator || '&',
|
||
allowDots: (queryParams.options || {}).shouldAllowDots || false,
|
||
arrayFormat: (queryParams.options || {}).arrayFormat || 'repeat',
|
||
encodeValuesOnly: (queryParams.options || {}).shouldOnlyEncodeValues || true
|
||
};
|
||
return options;
|
||
}
|
||
/**
|
||
* Decompress/Decode gzip encoded JSON
|
||
* Using Node.js built-in zlib module
|
||
*
|
||
* @param {Buffer} buffer
|
||
* @param {string} charset? - optional; defaults to 'utf-8'
|
||
* @return {Promise<string>}
|
||
*/
|
||
function decompressGzippedContent(buffer, charset) {
|
||
return __awaiter(this, void 0, void 0, function* () {
|
||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||
zlib.gunzip(buffer, function (error, buffer) {
|
||
if (error) {
|
||
reject(error);
|
||
}
|
||
resolve(buffer.toString(charset || 'utf-8'));
|
||
});
|
||
}));
|
||
});
|
||
}
|
||
exports.decompressGzippedContent = decompressGzippedContent;
|
||
/**
|
||
* Builds a RegExp to test urls against for deciding
|
||
* wether to bypass proxy from an entry of the
|
||
* environment variable setting NO_PROXY
|
||
*
|
||
* @param {string} bypass
|
||
* @return {RegExp}
|
||
*/
|
||
function buildProxyBypassRegexFromEnv(bypass) {
|
||
try {
|
||
// We need to keep this around for back-compat purposes
|
||
return new RegExp(bypass, 'i');
|
||
}
|
||
catch (err) {
|
||
if (err instanceof SyntaxError && (bypass || "").startsWith("*")) {
|
||
let wildcardEscaped = bypass.replace('*', '(.*)');
|
||
return new RegExp(wildcardEscaped, 'i');
|
||
}
|
||
throw err;
|
||
}
|
||
}
|
||
exports.buildProxyBypassRegexFromEnv = buildProxyBypassRegexFromEnv;
|
||
/**
|
||
* Obtain Response's Content Charset.
|
||
* Through inspecting `content-type` response header.
|
||
* It Returns 'utf-8' if NO charset specified/matched.
|
||
*
|
||
* @param {IHttpClientResponse} response
|
||
* @return {string} - Content Encoding Charset; Default=utf-8
|
||
*/
|
||
function obtainContentCharset(response) {
|
||
// Find the charset, if specified.
|
||
// Search for the `charset=CHARSET` string, not including `;,\r\n`
|
||
// Example: content-type: 'application/json;charset=utf-8'
|
||
// |__ matches would be ['charset=utf-8', 'utf-8', index: 18, input: 'application/json; charset=utf-8']
|
||
// |_____ matches[1] would have the charset :tada: , in our example it's utf-8
|
||
// However, if the matches Array was empty or no charset found, 'utf-8' would be returned by default.
|
||
const nodeSupportedEncodings = ['ascii', 'utf8', 'utf16le', 'ucs2', 'base64', 'binary', 'hex'];
|
||
const contentType = response.message.headers['content-type'] || '';
|
||
const matches = contentType.match(/charset=([^;,\r\n]+)/i);
|
||
return (matches && matches[1] && nodeSupportedEncodings.indexOf(matches[1]) != -1) ? matches[1] : 'utf-8';
|
||
}
|
||
exports.obtainContentCharset = obtainContentCharset;
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/typed-rest-client/node_modules/tunnel/index.js":
|
||
/*!*********************************************************************!*\
|
||
!*** ./node_modules/typed-rest-client/node_modules/tunnel/index.js ***!
|
||
\*********************************************************************/
|
||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
||
module.exports = __webpack_require__(/*! ./lib/tunnel */ "./node_modules/typed-rest-client/node_modules/tunnel/lib/tunnel.js");
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/typed-rest-client/node_modules/tunnel/lib/tunnel.js":
|
||
/*!**************************************************************************!*\
|
||
!*** ./node_modules/typed-rest-client/node_modules/tunnel/lib/tunnel.js ***!
|
||
\**************************************************************************/
|
||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
||
"use strict";
|
||
|
||
|
||
var net = __webpack_require__(/*! net */ "net");
|
||
var tls = __webpack_require__(/*! tls */ "tls");
|
||
var http = __webpack_require__(/*! http */ "http");
|
||
var https = __webpack_require__(/*! https */ "https");
|
||
var events = __webpack_require__(/*! events */ "events");
|
||
var assert = __webpack_require__(/*! assert */ "assert");
|
||
var util = __webpack_require__(/*! util */ "util");
|
||
|
||
|
||
exports.httpOverHttp = httpOverHttp;
|
||
exports.httpsOverHttp = httpsOverHttp;
|
||
exports.httpOverHttps = httpOverHttps;
|
||
exports.httpsOverHttps = httpsOverHttps;
|
||
|
||
|
||
function httpOverHttp(options) {
|
||
var agent = new TunnelingAgent(options);
|
||
agent.request = http.request;
|
||
return agent;
|
||
}
|
||
|
||
function httpsOverHttp(options) {
|
||
var agent = new TunnelingAgent(options);
|
||
agent.request = http.request;
|
||
agent.createSocket = createSecureSocket;
|
||
agent.defaultPort = 443;
|
||
return agent;
|
||
}
|
||
|
||
function httpOverHttps(options) {
|
||
var agent = new TunnelingAgent(options);
|
||
agent.request = https.request;
|
||
return agent;
|
||
}
|
||
|
||
function httpsOverHttps(options) {
|
||
var agent = new TunnelingAgent(options);
|
||
agent.request = https.request;
|
||
agent.createSocket = createSecureSocket;
|
||
agent.defaultPort = 443;
|
||
return agent;
|
||
}
|
||
|
||
|
||
function TunnelingAgent(options) {
|
||
var self = this;
|
||
self.options = options || {};
|
||
self.proxyOptions = self.options.proxy || {};
|
||
self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;
|
||
self.requests = [];
|
||
self.sockets = [];
|
||
|
||
self.on('free', function onFree(socket, host, port, localAddress) {
|
||
var options = toOptions(host, port, localAddress);
|
||
for (var i = 0, len = self.requests.length; i < len; ++i) {
|
||
var pending = self.requests[i];
|
||
if (pending.host === options.host && pending.port === options.port) {
|
||
// Detect the request to connect same origin server,
|
||
// reuse the connection.
|
||
self.requests.splice(i, 1);
|
||
pending.request.onSocket(socket);
|
||
return;
|
||
}
|
||
}
|
||
socket.destroy();
|
||
self.removeSocket(socket);
|
||
});
|
||
}
|
||
util.inherits(TunnelingAgent, events.EventEmitter);
|
||
|
||
TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) {
|
||
var self = this;
|
||
var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress));
|
||
|
||
if (self.sockets.length >= this.maxSockets) {
|
||
// We are over limit so we'll add it to the queue.
|
||
self.requests.push(options);
|
||
return;
|
||
}
|
||
|
||
// If we are under maxSockets create a new one.
|
||
self.createSocket(options, function(socket) {
|
||
socket.on('free', onFree);
|
||
socket.on('close', onCloseOrRemove);
|
||
socket.on('agentRemove', onCloseOrRemove);
|
||
req.onSocket(socket);
|
||
|
||
function onFree() {
|
||
self.emit('free', socket, options);
|
||
}
|
||
|
||
function onCloseOrRemove(err) {
|
||
self.removeSocket(socket);
|
||
socket.removeListener('free', onFree);
|
||
socket.removeListener('close', onCloseOrRemove);
|
||
socket.removeListener('agentRemove', onCloseOrRemove);
|
||
}
|
||
});
|
||
};
|
||
|
||
TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
|
||
var self = this;
|
||
var placeholder = {};
|
||
self.sockets.push(placeholder);
|
||
|
||
var connectOptions = mergeOptions({}, self.proxyOptions, {
|
||
method: 'CONNECT',
|
||
path: options.host + ':' + options.port,
|
||
agent: false,
|
||
headers: {
|
||
host: options.host + ':' + options.port
|
||
}
|
||
});
|
||
if (options.localAddress) {
|
||
connectOptions.localAddress = options.localAddress;
|
||
}
|
||
if (connectOptions.proxyAuth) {
|
||
connectOptions.headers = connectOptions.headers || {};
|
||
connectOptions.headers['Proxy-Authorization'] = 'Basic ' +
|
||
new Buffer(connectOptions.proxyAuth).toString('base64');
|
||
}
|
||
|
||
debug('making CONNECT request');
|
||
var connectReq = self.request(connectOptions);
|
||
connectReq.useChunkedEncodingByDefault = false; // for v0.6
|
||
connectReq.once('response', onResponse); // for v0.6
|
||
connectReq.once('upgrade', onUpgrade); // for v0.6
|
||
connectReq.once('connect', onConnect); // for v0.7 or later
|
||
connectReq.once('error', onError);
|
||
connectReq.end();
|
||
|
||
function onResponse(res) {
|
||
// Very hacky. This is necessary to avoid http-parser leaks.
|
||
res.upgrade = true;
|
||
}
|
||
|
||
function onUpgrade(res, socket, head) {
|
||
// Hacky.
|
||
process.nextTick(function() {
|
||
onConnect(res, socket, head);
|
||
});
|
||
}
|
||
|
||
function onConnect(res, socket, head) {
|
||
connectReq.removeAllListeners();
|
||
socket.removeAllListeners();
|
||
|
||
if (res.statusCode !== 200) {
|
||
debug('tunneling socket could not be established, statusCode=%d',
|
||
res.statusCode);
|
||
socket.destroy();
|
||
var error = new Error('tunneling socket could not be established, ' +
|
||
'statusCode=' + res.statusCode);
|
||
error.code = 'ECONNRESET';
|
||
options.request.emit('error', error);
|
||
self.removeSocket(placeholder);
|
||
return;
|
||
}
|
||
if (head.length > 0) {
|
||
debug('got illegal response body from proxy');
|
||
socket.destroy();
|
||
var error = new Error('got illegal response body from proxy');
|
||
error.code = 'ECONNRESET';
|
||
options.request.emit('error', error);
|
||
self.removeSocket(placeholder);
|
||
return;
|
||
}
|
||
debug('tunneling connection has established');
|
||
self.sockets[self.sockets.indexOf(placeholder)] = socket;
|
||
return cb(socket);
|
||
}
|
||
|
||
function onError(cause) {
|
||
connectReq.removeAllListeners();
|
||
|
||
debug('tunneling socket could not be established, cause=%s\n',
|
||
cause.message, cause.stack);
|
||
var error = new Error('tunneling socket could not be established, ' +
|
||
'cause=' + cause.message);
|
||
error.code = 'ECONNRESET';
|
||
options.request.emit('error', error);
|
||
self.removeSocket(placeholder);
|
||
}
|
||
};
|
||
|
||
TunnelingAgent.prototype.removeSocket = function removeSocket(socket) {
|
||
var pos = this.sockets.indexOf(socket)
|
||
if (pos === -1) {
|
||
return;
|
||
}
|
||
this.sockets.splice(pos, 1);
|
||
|
||
var pending = this.requests.shift();
|
||
if (pending) {
|
||
// If we have pending requests and a socket gets closed a new one
|
||
// needs to be created to take over in the pool for the one that closed.
|
||
this.createSocket(pending, function(socket) {
|
||
pending.request.onSocket(socket);
|
||
});
|
||
}
|
||
};
|
||
|
||
function createSecureSocket(options, cb) {
|
||
var self = this;
|
||
TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {
|
||
var hostHeader = options.request.getHeader('host');
|
||
var tlsOptions = mergeOptions({}, self.options, {
|
||
socket: socket,
|
||
servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host
|
||
});
|
||
|
||
// 0 is dummy port for v0.6
|
||
var secureSocket = tls.connect(0, tlsOptions);
|
||
self.sockets[self.sockets.indexOf(socket)] = secureSocket;
|
||
cb(secureSocket);
|
||
});
|
||
}
|
||
|
||
|
||
function toOptions(host, port, localAddress) {
|
||
if (typeof host === 'string') { // since v0.10
|
||
return {
|
||
host: host,
|
||
port: port,
|
||
localAddress: localAddress
|
||
};
|
||
}
|
||
return host; // for v0.11 or later
|
||
}
|
||
|
||
function mergeOptions(target) {
|
||
for (var i = 1, len = arguments.length; i < len; ++i) {
|
||
var overrides = arguments[i];
|
||
if (typeof overrides === 'object') {
|
||
var keys = Object.keys(overrides);
|
||
for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {
|
||
var k = keys[j];
|
||
if (overrides[k] !== undefined) {
|
||
target[k] = overrides[k];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return target;
|
||
}
|
||
|
||
|
||
var debug;
|
||
if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) {
|
||
debug = function() {
|
||
var args = Array.prototype.slice.call(arguments);
|
||
if (typeof args[0] === 'string') {
|
||
args[0] = 'TUNNEL: ' + args[0];
|
||
} else {
|
||
args.unshift('TUNNEL:');
|
||
}
|
||
console.error.apply(console, args);
|
||
}
|
||
} else {
|
||
debug = function() {};
|
||
}
|
||
exports.debug = debug; // for test
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "./node_modules/wrappy/wrappy.js":
|
||
/*!***************************************!*\
|
||
!*** ./node_modules/wrappy/wrappy.js ***!
|
||
\***************************************/
|
||
/***/ ((module) => {
|
||
|
||
// Returns a wrapper function that returns a wrapped callback
|
||
// The wrapper function should do some stuff, and return a
|
||
// presumably different callback function.
|
||
// This makes sure that own properties are retained, so that
|
||
// decorations and such are not lost along the way.
|
||
module.exports = wrappy
|
||
function wrappy (fn, cb) {
|
||
if (fn && cb) return wrappy(fn)(cb)
|
||
|
||
if (typeof fn !== 'function')
|
||
throw new TypeError('need wrapper function')
|
||
|
||
Object.keys(fn).forEach(function (k) {
|
||
wrapper[k] = fn[k]
|
||
})
|
||
|
||
return wrapper
|
||
|
||
function wrapper() {
|
||
var args = new Array(arguments.length)
|
||
for (var i = 0; i < args.length; i++) {
|
||
args[i] = arguments[i]
|
||
}
|
||
var ret = fn.apply(this, args)
|
||
var cb = args[args.length-1]
|
||
if (typeof ret === 'function' && ret !== cb) {
|
||
Object.keys(cb).forEach(function (k) {
|
||
ret[k] = cb[k]
|
||
})
|
||
}
|
||
return ret
|
||
}
|
||
}
|
||
|
||
|
||
/***/ }),
|
||
|
||
/***/ "assert":
|
||
/*!*************************!*\
|
||
!*** external "assert" ***!
|
||
\*************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("assert");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "child_process":
|
||
/*!********************************!*\
|
||
!*** external "child_process" ***!
|
||
\********************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("child_process");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "crypto":
|
||
/*!*************************!*\
|
||
!*** external "crypto" ***!
|
||
\*************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("crypto");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "events":
|
||
/*!*************************!*\
|
||
!*** external "events" ***!
|
||
\*************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("events");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "fs":
|
||
/*!*********************!*\
|
||
!*** external "fs" ***!
|
||
\*********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("fs");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "http":
|
||
/*!***********************!*\
|
||
!*** external "http" ***!
|
||
\***********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("http");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "https":
|
||
/*!************************!*\
|
||
!*** external "https" ***!
|
||
\************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("https");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "net":
|
||
/*!**********************!*\
|
||
!*** external "net" ***!
|
||
\**********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("net");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "os":
|
||
/*!*********************!*\
|
||
!*** external "os" ***!
|
||
\*********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("os");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "path":
|
||
/*!***********************!*\
|
||
!*** external "path" ***!
|
||
\***********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("path");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "process":
|
||
/*!**************************!*\
|
||
!*** external "process" ***!
|
||
\**************************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("process");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "tls":
|
||
/*!**********************!*\
|
||
!*** external "tls" ***!
|
||
\**********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("tls");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "url":
|
||
/*!**********************!*\
|
||
!*** external "url" ***!
|
||
\**********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("url");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "util":
|
||
/*!***********************!*\
|
||
!*** external "util" ***!
|
||
\***********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("util");
|
||
|
||
/***/ }),
|
||
|
||
/***/ "zlib":
|
||
/*!***********************!*\
|
||
!*** external "zlib" ***!
|
||
\***********************/
|
||
/***/ ((module) => {
|
||
|
||
"use strict";
|
||
module.exports = require("zlib");
|
||
|
||
/***/ })
|
||
|
||
/******/ });
|
||
/************************************************************************/
|
||
/******/ // The module cache
|
||
/******/ var __webpack_module_cache__ = {};
|
||
/******/
|
||
/******/ // The require function
|
||
/******/ function __webpack_require__(moduleId) {
|
||
/******/ // Check if module is in cache
|
||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||
/******/ if (cachedModule !== undefined) {
|
||
/******/ return cachedModule.exports;
|
||
/******/ }
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||
/******/ id: moduleId,
|
||
/******/ loaded: false,
|
||
/******/ exports: {}
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
/******/
|
||
/******/ // Flag the module as loaded
|
||
/******/ module.loaded = true;
|
||
/******/
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
/******/
|
||
/******/ // expose the module cache
|
||
/******/ __webpack_require__.c = __webpack_module_cache__;
|
||
/******/
|
||
/************************************************************************/
|
||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||
/******/ (() => {
|
||
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
||
/******/ })();
|
||
/******/
|
||
/******/ /* webpack/runtime/node module decorator */
|
||
/******/ (() => {
|
||
/******/ __webpack_require__.nmd = (module) => {
|
||
/******/ module.paths = [];
|
||
/******/ if (!module.children) module.children = [];
|
||
/******/ return module;
|
||
/******/ };
|
||
/******/ })();
|
||
/******/
|
||
/************************************************************************/
|
||
/******/
|
||
/******/ // module cache are used so entry inlining is disabled
|
||
/******/ // startup
|
||
/******/ // Load entry module and return exports
|
||
/******/ var __webpack_exports__ = __webpack_require__(__webpack_require__.s = "./src/tasks/gitreleasemanager/open.ts");
|
||
/******/ module.exports = __webpack_exports__;
|
||
/******/
|
||
/******/ })()
|
||
;
|
||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi9pbnRlcm5hbC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi9ub2RlX21vZHVsZXMvdXVpZC9saWIvYnl0ZXNUb1V1aWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdGFzay1saWIvbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi90YXNrLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliL3Rhc2tjb21tYW5kLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliL3Rvb2xydW5uZXIuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdGFzay1saWIvdmF1bHQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdGFzay1saWJ8c3luYyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi9ub2RlX21vZHVsZXMvdXVpZC9saWIvYnl0ZXNUb1V1aWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdG9vbC1saWIvbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10b29sLWxpYi90b29sLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvYXp1cmUtcGlwZWxpbmVzLXRvb2wtbGlifHN5bmMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9iYWxhbmNlZC1tYXRjaC9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2JyYWNlLWV4cGFuc2lvbi9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2NvbmNhdC1tYXAvaW5kZXguanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9mcy5yZWFscGF0aC9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ZzLnJlYWxwYXRoL29sZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2dsb2IvY29tbW9uLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvZ2xvYi9nbG9iLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvZ2xvYi9zeW5jLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW5mbGlnaHQvaW5mbGlnaHQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0cy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vZGVjb3JhdG9yX3V0aWxzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL2luamVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9pbmplY3RhYmxlLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9hbm5vdGF0aW9uL211bHRpX2luamVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9uYW1lZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9vcHRpb25hbC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi9wb3N0X2NvbnN0cnVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvYW5ub3RhdGlvbi90YWdnZWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vdGFyZ2V0X25hbWUuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2Fubm90YXRpb24vdW5tYW5hZ2VkLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9iaW5kaW5ncy9iaW5kaW5nLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9iaW5kaW5ncy9iaW5kaW5nX2NvdW50LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb25zdGFudHMvZXJyb3JfbXNncy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29uc3RhbnRzL2xpdGVyYWxfdHlwZXMuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb250YWluZXIvY29udGFpbmVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb250YWluZXIvY29udGFpbmVyX21vZHVsZS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29udGFpbmVyL2NvbnRhaW5lcl9zbmFwc2hvdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvY29udGFpbmVyL2xvb2t1cC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvaW52ZXJzaWZ5LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9jb250ZXh0LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcGxhbm5pbmcvbWV0YWRhdGFfcmVhZGVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9wbGFuLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9wbGFubmVyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9xdWVyeWFibGVfc3RyaW5nLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9yZWZsZWN0aW9uX3V0aWxzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9yZXF1ZXN0LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy90YXJnZXQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3Jlc29sdXRpb24vaW5zdGFudGlhdGlvbi5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvcmVzb2x1dGlvbi9yZXNvbHZlci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2JpbmRpbmdfaW5fc3ludGF4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ19pbl93aGVuX29uX3N5bnRheC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2JpbmRpbmdfb25fc3ludGF4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ190b19zeW50YXguanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3N5bnRheC9iaW5kaW5nX3doZW5fb25fc3ludGF4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9zeW50YXgvYmluZGluZ193aGVuX3N5bnRheC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvc3ludGF4L2NvbnN0cmFpbnRfaGVscGVycy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvYmluZGluZ191dGlscy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvZXhjZXB0aW9ucy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL2ludmVyc2lmeS9saWIvdXRpbHMvaWQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9pbnZlcnNpZnkvbGliL3V0aWxzL3NlcmlhbGl6YXRpb24uanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9taW5pbWF0Y2gvbWluaW1hdGNoLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvb25jZS9vbmNlLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcGF0aC1pcy1hYnNvbHV0ZS9pbmRleC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3EvcS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3FzL2xpYi9mb3JtYXRzLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcXMvbGliL2luZGV4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcXMvbGliL3BhcnNlLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvcXMvbGliL3N0cmluZ2lmeS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3FzL2xpYi91dGlscy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3JlZmxlY3QtbWV0YWRhdGEvUmVmbGVjdC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NlbXZlci1jb21wYXJlL2luZGV4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2VtdmVyL3NlbXZlci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvY29tbWFuZHMuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NoZWxsLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2F0LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2QuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jaG1vZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NvbW1vbi5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NwLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZGlycy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2VjaG8uanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9lcnJvci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2V4ZWMtY2hpbGQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9leGVjLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZmluZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2dyZXAuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9oZWFkLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbG4uanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9scy5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL21rZGlyLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbXYuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wb3BkLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvcHVzaGQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wd2QuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9ybS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NlZC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NldC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NvcnQuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy90YWlsLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdGVtcGRpci5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3Rlc3QuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy90by5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RvRW5kLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdG91Y2guanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy91bmlxLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvd2hpY2guanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyY3xzeW5jfC9eLy4qJCIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL2FnZW50L2F6dXJlL2J1aWxkLWFnZW50LnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvY29yZS9kb3RuZXQtdG9vbC50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL2NvcmUvaW9jLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvY29yZS9tb2RlbHMudHMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL3NyYy9jb3JlL3NldHRpbmdzLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvY29yZS92ZXJzaW9uTWFuYWdlci50cyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vc3JjL3Rhc2tzL2dpdHJlbGVhc2VtYW5hZ2VyL21haW4udHMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL3NyYy90YXNrcy9naXRyZWxlYXNlbWFuYWdlci9vcGVuLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvbW9kZWxzLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9zcmMvdG9vbHMvZ2l0cmVsZWFzZW1hbmFnZXIvc2V0dGluZ3MudHMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL3NyYy90b29scy9naXRyZWxlYXNlbWFuYWdlci90b29sLnRzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvdHlwZWQtcmVzdC1jbGllbnQvSHR0cENsaWVudC5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zLy4vbm9kZV9tb2R1bGVzL3R5cGVkLXJlc3QtY2xpZW50L1V0aWwuanMiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy8uL25vZGVfbW9kdWxlcy90eXBlZC1yZXN0LWNsaWVudC9ub2RlX21vZHVsZXMvdHVubmVsL2luZGV4LmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvdHlwZWQtcmVzdC1jbGllbnQvbm9kZV9tb2R1bGVzL3R1bm5lbC9saWIvdHVubmVsLmpzIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvLi9ub2RlX21vZHVsZXMvd3JhcHB5L3dyYXBweS5qcyIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwiYXNzZXJ0XCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcImNoaWxkX3Byb2Nlc3NcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwiY3J5cHRvXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcImV2ZW50c1wiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJmc1wiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJodHRwXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcImh0dHBzXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcIm5ldFwiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJvc1wiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJwYXRoXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcInByb2Nlc3NcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL2V4dGVybmFsIFwidGxzXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcInVybFwiIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvZXh0ZXJuYWwgXCJ1dGlsXCIiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy9leHRlcm5hbCBcInpsaWJcIiIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL2dpdHRvb2xzLWFjdGlvbnMvd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly9naXR0b29scy1hY3Rpb25zL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vZ2l0dG9vbHMtYWN0aW9ucy93ZWJwYWNrL3N0YXJ0dXAiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFhO0FBQ2IsOENBQTZDLENBQUMsY0FBYyxFQUFDO0FBQzdELDJCQUEyQixHQUFHLDRCQUE0QixHQUFHLDRCQUE0QixHQUFHLGlCQUFpQixHQUFHLHlCQUF5QixHQUFHLHFCQUFxQixHQUFHLGlCQUFpQixHQUFHLDRCQUE0QixHQUFHLCtCQUErQixHQUFHLDBCQUEwQixHQUFHLCtDQUErQyxHQUFHLGNBQWMsR0FBRyxrQkFBa0IsR0FBRyxjQUFjLEdBQUcsY0FBYyxHQUFHLGNBQWMsR0FBRyxnQkFBZ0IsR0FBRyxnQkFBZ0IsR0FBRyx1QkFBdUIsR0FBRyxvQkFBb0IsR0FBRyxZQUFZLEdBQUcsd0JBQXdCLEdBQUcscUJBQXFCLEdBQUcscUJBQXFCLEdBQUcsa0JBQWtCLEdBQUcsaUJBQWlCLEdBQUcsbUJBQW1CLEdB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsT0FBTyxPQUFPO0FBQzlDO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLE9BQU8sT0FBTztBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixvQkFBb0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsb0JBQW9CO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtB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Q0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsb0JBQW9CO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLElBQUk7QUFDeEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0wsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsS0FBSztBQUNMLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxJQUFJO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxFQUFFLEVBQUUsS0FBSztBQUN6QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0MsUUFBUTtBQUNoRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxzQkFBc0I7QUFDckM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsNkNBQTZDO0FBQzdDOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7O0FBRUEsYUFBYSxnQkFBZ0I7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSyw2Q0FBNkM7O0FBRWxEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsU0FBUztBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMkJBQTJCO0FBQzNCOzs7Ozs7Ozs7OztBQzE1QkEsYUFBYSxtQkFBTyxDQUFDLCtDQUFRO0FBQzdCO0FBQ0EscUJBQXFCOztBQUVyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsR0FBRztBQUNILENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDekNhOztBQUViO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EseUNBQXlDLEVBQUU7QUFDM0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG9CQUFvQjtBQUNwQixvQkFBb0I7Ozs7Ozs7Ozs7O0FDbkJwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLLFVBQVUsSUFBeUQ7QUFDeEU7O0FBRUE7QUFDQSxLQUFLLE1BQU0sMEJBK0JOOztBQUVMLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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Q0EsV0FBVyxTQUFTO0FBQ3BCLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQyxjQUFjLEVBQUU7QUFDbEQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0NBQWtDLGNBQWMsRUFBRTtBQUNsRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMLGdCQUFnQjtBQUNoQixLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGdCQUFnQjtBQUNoQixLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxXQUFXLFNBQVM7QUFDcEIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHlDQUF5QyxnQ0FBZ0M7QUFDekU7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFlBQVk7QUFDdkI7QUFDQSxhQUFhLGFBQWE7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsS0FBSztBQUNoQixXQUFXLFNBQVM7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxTQUFTO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsS0FBSztBQUNoQixXQUFXLFNBQVM7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0Es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QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsbUJBQW1CLGlCQUFpQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7QUMzUWE7O0FBRWIsWUFBWSxtQkFBTyxDQUFDLCtDQUFTO0FBQzdCLGNBQWMsbUJBQU8sQ0FBQyxtREFBVztBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLG9CQUFvQjtBQUN2Qzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsb0JBQW9CO0FBQ3ZDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJDQUEyQztBQUMzQztBQUNBLFNB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QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1R0FBdUc7QUFDdkc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdGQUFnRjtBQUNoRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUVBQXFFO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRUFBcUU7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsMkNBQTJDO0FBQzNDLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUVBQXVFO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQStDLFFBQVE7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQyxRQUFRO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELHVCQUF1QjtBQUN4RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RCwwQkFBMEI7QUFDakY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUNBLDJCQUEyQjs7QUFFM0I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTLFVBQVU7QUFDbkIsVUFBVSxXQUFXO0FBQ3JCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixvQ0FBb0M7QUFDeEQsMEJBQTBCLG9DQUFvQztBQUM5RCwwQkFBMEIsb0NBQW9DO0FBQzlEOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjOztBQUVkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjs7QUFFMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7O0FBRUEsZUFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBOztBQUVBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7O0FBRUEsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUEsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7O0FBRUEsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0g7O0FBRUE7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDBCQUEwQjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsYUFBYSxTQUFTOzs7Ozs7Ozs7OztBQ3ZRdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNoQ0EsbUM7Ozs7Ozs7Ozs7O0FDQUEsMEM7Ozs7Ozs7Ozs7O0FDQUEsbUM7Ozs7Ozs7Ozs7O0FDQUEsbUM7Ozs7Ozs7Ozs7O0FDQUEsK0I7Ozs7Ozs7Ozs7O0FDQUEsaUM7Ozs7Ozs7Ozs7O0FDQUEsa0M7Ozs7Ozs7Ozs7O0FDQUEsZ0M7Ozs7Ozs7Ozs7O0FDQUEsK0I7Ozs7Ozs7Ozs7O0FDQUEsaUM7Ozs7Ozs7Ozs7O0FDQUEsb0M7Ozs7Ozs7Ozs7O0FDQUEsZ0M7Ozs7Ozs7Ozs7O0FDQUEsZ0M7Ozs7Ozs7Ozs7O0FDQUEsaUM7Ozs7Ozs7Ozs7O0FDQUEsaUM7Ozs7OztVQ0FBO1VBQ0E7O1VBRUE7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7O1VBRUE7VUFDQTs7VUFFQTtVQUNBOztVQUVBO1VBQ0E7VUFDQTs7VUFFQTtVQUNBOzs7OztXQzVCQSx3Rjs7Ozs7V0NBQTtXQUNBO1dBQ0E7V0FDQTtXQUNBLEU7Ozs7O1VDSkE7VUFDQTtVQUNBO1VBQ0EiLCJmaWxlIjoiZ2l0cmVsZWFzZW1hbmFnZXIvb3Blbi9idW5kbGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG5leHBvcnRzLl9leHBvc2VDZXJ0U2V0dGluZ3MgPSBleHBvcnRzLl9leHBvc2VQcm94eVNldHRpbmdzID0gZXhwb3J0cy5fbm9ybWFsaXplU2VwYXJhdG9ycyA9IGV4cG9ydHMuX2lzUm9vdGVkID0gZXhwb3J0cy5fZ2V0RGlyZWN0b3J5TmFtZSA9IGV4cG9ydHMuX2Vuc3VyZVJvb3RlZCA9IGV4cG9ydHMuX2xvYWREYXRhID0gZXhwb3J0cy5fZW5zdXJlUGF0dGVyblJvb3RlZCA9IGV4cG9ydHMuX2dldEZpbmRJbmZvRnJvbVBhdHRlcm4gPSBleHBvcnRzLl9jbG9uZU1hdGNoT3B0aW9ucyA9IGV4cG9ydHMuX2xlZ2FjeUZpbmRGaWxlc19jb252ZXJ0UGF0dGVyblRvUmVnRXhwID0gZXhwb3J0cy5fd2hpY2ggPSBleHBvcnRzLl9jaGVja1BhdGggPSBleHBvcnRzLl9leGlzdCA9IGV4cG9ydHMuX2RlYnVnID0gZXhwb3J0cy5fZXJyb3IgPSBleHBvcnRzLl93YXJuaW5nID0gZXhwb3J0cy5fY29tbWFuZCA9IGV4cG9ydHMuX2dldFZhcmlhYmxlS2V5ID0gZXhwb3J0cy5fZ2V0VmFyaWFibGUgPSBleHBvcnRzLl9sb2MgPSBleHBvcnRzLl9zZXRSZXNvdXJjZVBhdGggPSBleHBvcnRzLl9zZXRFcnJTdHJlYW0gPSBleHBvcnRzLl9zZXRTdGRTdHJlYW0gPSBleHBvcnRzLl93cml0ZUxpbmUgPSBleHBvcnRzLl9lbmRzV2l0aCA9IGV4cG9ydHMuX3N0YXJ0c1dpdGggPSBleHBvcnRzLl92YXVsdCA9IGV4cG9ydHMuX2tub3duVmFyaWFibGVNYXAgPSB2b2lkIDA7XHJcbnZhciBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxudmFyIHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcclxudmFyIG9zID0gcmVxdWlyZShcIm9zXCIpO1xyXG52YXIgbWluaW1hdGNoID0gcmVxdWlyZShcIm1pbmltYXRjaFwiKTtcclxudmFyIHV0aWwgPSByZXF1aXJlKFwidXRpbFwiKTtcclxudmFyIHRjbSA9IHJlcXVpcmUoXCIuL3Rhc2tjb21tYW5kXCIpO1xyXG52YXIgdm0gPSByZXF1aXJlKFwiLi92YXVsdFwiKTtcclxudmFyIHNlbXZlciA9IHJlcXVpcmUoXCJzZW12ZXJcIik7XHJcbnZhciBjcnlwdG8gPSByZXF1aXJlKFwiY3J5cHRvXCIpO1xyXG4vKipcclxuICogSGFzaCB0YWJsZSBvZiBrbm93biB2YXJpYWJsZSBpbmZvLiBUaGUgZm9ybWF0dGVkIGVudiB2YXIgbmFtZSBpcyB0aGUgbG9va3VwIGtleS5cclxuICpcclxuICogVGhlIHB1cnBvc2Ugb2YgdGhpcyBoYXNoIHRhYmxlIGlzIHRvIGtlZXAgdHJhY2sgb2Yga25vd24gdmFyaWFibGVzLiBUaGUgaGFzaCB0YWJsZVxyXG4gKiBuZWVkcyB0byBiZSBtYWludGFpbmVkIGZvciBtdWx0aXBsZSByZWFzb25zOlxyXG4gKiAgMSkgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBlbnYgdmFycyBhbmQgam9iIHZhcnNcclxuICogIDIpIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gc2VjcmV0IHZhcnMgYW5kIHB1YmxpY1xyXG4gKiAgMykgdG8ga25vdyB0aGUgcmVhbCB2YXJpYWJsZSBuYW1lIGFuZCBub3QganVzdCB0aGUgZm9ybWF0dGVkIGVudiB2YXIgbmFtZS5cclxuICovXHJcbmV4cG9ydHMuX2tub3duVmFyaWFibGVNYXAgPSB7fTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBWYWxpZGF0aW9uIENoZWNrc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIGFzeW5jIGF3YWl0IG5lZWRzIGdlbmVyYXRvcnMgaW4gbm9kZSA0LngrXHJcbmlmIChzZW12ZXIubHQocHJvY2Vzcy52ZXJzaW9ucy5ub2RlLCAnNC4yLjAnKSkge1xyXG4gICAgX3dhcm5pbmcoJ1Rhc2tzIHJlcXVpcmUgYSBuZXcgYWdlbnQuICBVcGdyYWRlIHlvdXIgYWdlbnQgb3Igbm9kZSB0byA0LjIuMCBvciBsYXRlcicpO1xyXG59XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gU3RyaW5nIGNvbnZlbmllbmNlXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZnVuY3Rpb24gX3N0YXJ0c1dpdGgoc3RyLCBzdGFydCkge1xyXG4gICAgcmV0dXJuIHN0ci5zbGljZSgwLCBzdGFydC5sZW5ndGgpID09IHN0YXJ0O1xyXG59XHJcbmV4cG9ydHMuX3N0YXJ0c1dpdGggPSBfc3RhcnRzV2l0aDtcclxuZnVuY3Rpb24gX2VuZHNXaXRoKHN0ciwgZW5kKSB7XHJcbiAgICByZXR1cm4gc3RyLnNsaWNlKC1lbmQubGVuZ3RoKSA9PSBlbmQ7XHJcbn1cclxuZXhwb3J0cy5fZW5kc1dpdGggPSBfZW5kc1dpdGg7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gR2VuZXJhbCBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxudmFyIF9vdXRTdHJlYW0gPSBwcm9jZXNzLnN0ZG91dDtcclxudmFyIF9lcnJTdHJlYW0gPSBwcm9jZXNzLnN0ZGVycjtcclxuZnVuY3Rpb24gX3dyaXRlTGluZShzdHIpIHtcclxuICAgIF9vdXRTdHJlYW0ud3JpdGUoc3RyICsgb3MuRU9MKTtcclxufVxyXG5leHBvcnRzLl93cml0ZUxpbmUgPSBfd3JpdGVMaW5lO1xyXG5mdW5jdGlvbiBfc2V0U3RkU3RyZWFtKHN0ZFN0cmVhbSkge1xyXG4gICAgX291dFN0cmVhbSA9IHN0ZFN0cmVhbTtcclxufVxyXG5leHBvcnRzLl9zZXRTdGRTdHJlYW0gPSBfc2V0U3RkU3RyZWFtO1xyXG5mdW5jdGlvbiBfc2V0RXJyU3RyZWFtKGVyclN0cmVhbSkge1xyXG4gICAgX2VyclN0cmVhbSA9IGVyclN0cmVhbTtcclxufVxyXG5leHBvcnRzLl9zZXRFcnJTdHJlYW0gPSBfc2V0RXJyU3RyZWFtO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIExvYyBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxudmFyIF9sb2NTdHJpbmdDYWNoZSA9IHt9O1xyXG52YXIgX3Jlc291cmNlRmlsZXMgPSB7fTtcclxudmFyIF9saWJSZXNvdXJjZUZpbGVMb2FkZWQgPSBmYWxzZTtcclxudmFyIF9yZXNvdXJjZUN1bHR1cmUgPSAnZW4tVVMnO1xyXG5mdW5jdGlvbiBfbG9hZFJlc0pzb24ocmVzanNvbkZpbGUpIHtcclxuICAgIHZhciByZXNKc29uO1xyXG4gICAgaWYgKF9leGlzdChyZXNqc29uRmlsZSkpIHtcclxuICAgICAgICB2YXIgcmVzanNvbkNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMocmVzanNvbkZpbGUsICd1dGY4JykudG9TdHJpbmcoKTtcclxuICAgICAgICAvLyByZW1vdmUgQk9NXHJcbiAgICAgICAgaWYgKHJlc2pzb25Db250ZW50LmluZGV4T2YoJ1xcdUZFRkYnKSA9PSAwKSB7XHJcbiAgICAgICAgICAgIHJlc2pzb25Db250ZW50ID0gcmVzanNvbkNvbnRlbnQuc2xpY2UoMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHJlc0pzb24gPSBKU09OLnBhcnNlKHJlc2pzb25Db250ZW50KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICBfZGVidWcoJ3VuYWJsZSB0byBwYXJzZSByZXNqc29uIHdpdGggZXJyOiAnICsgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIF9kZWJ1ZygnLnJlc2pzb24gZmlsZSBub3QgZm91bmQ6ICcgKyByZXNqc29uRmlsZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzSnNvbjtcclxufVxyXG5mdW5jdGlvbiBfbG9hZExvY1N0cmluZ3MocmVzb3VyY2VGaWxlLCBjdWx0dXJlKSB7XHJcbiAgICB2YXIgbG9jU3RyaW5ncyA9IHt9O1xyXG4gICAgaWYgKF9leGlzdChyZXNvdXJjZUZpbGUpKSB7XHJcbiAgICAgICAgdmFyIHJlc291cmNlSnNvbiA9IHJlcXVpcmUocmVzb3VyY2VGaWxlKTtcclxuICAgICAgICBpZiAocmVzb3VyY2VKc29uICYmIHJlc291cmNlSnNvbi5oYXNPd25Qcm9wZXJ0eSgnbWVzc2FnZXMnKSkge1xyXG4gICAgICAgICAgICB2YXIgbG9jUmVzb3VyY2VKc29uO1xyXG4gICAgICAgICAgICAvLyBsb2FkIHVwIHJlc291cmNlIHJlc2pzb24gZm9yIGRpZmZlcmVudCBjdWx0dXJlXHJcbiAgICAgICAgICAgIHZhciBsb2NhbGl6ZWRSZXNvdXJjZUZpbGUgPSBwYXRoLmpvaW4ocGF0aC5kaXJuYW1lKHJlc291cmNlRmlsZSksICdTdHJpbmdzJywgJ3Jlc291cmNlcy5yZXNqc29uJyk7XHJcbiAgICAgICAgICAgIHZhciB1cHBlckN1bHR1cmUgPSBjdWx0dXJlLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgICAgIHZhciBjdWx0dXJlcyA9IFtdO1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY3VsdHVyZXMgPSBmcy5yZWFkZGlyU3luYyhsb2NhbGl6ZWRSZXNvdXJjZUZpbGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChleCkgeyB9XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY3VsdHVyZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChjdWx0dXJlc1tpXS50b1VwcGVyQ2FzZSgpID09IHVwcGVyQ3VsdHVyZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxvY2FsaXplZFJlc291cmNlRmlsZSA9IHBhdGguam9pbihsb2NhbGl6ZWRSZXNvdXJjZUZpbGUsIGN1bHR1cmVzW2ldLCAncmVzb3VyY2VzLnJlc2pzb24nKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2V4aXN0KGxvY2FsaXplZFJlc291cmNlRmlsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbG9jUmVzb3VyY2VKc29uID0gX2xvYWRSZXNKc29uKGxvY2FsaXplZFJlc291cmNlRmlsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiByZXNvdXJjZUpzb24ubWVzc2FnZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChsb2NSZXNvdXJjZUpzb24gJiYgbG9jUmVzb3VyY2VKc29uLmhhc093blByb3BlcnR5KCdsb2MubWVzc2FnZXMuJyArIGtleSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2NTdHJpbmdzW2tleV0gPSBsb2NSZXNvdXJjZUpzb25bJ2xvYy5tZXNzYWdlcy4nICsga2V5XTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGxvY1N0cmluZ3Nba2V5XSA9IHJlc291cmNlSnNvbi5tZXNzYWdlc1trZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgX3dhcm5pbmcoJ0xJQl9SZXNvdXJjZUZpbGUgZG9lcyBub3QgZXhpc3QnKTtcclxuICAgIH1cclxuICAgIHJldHVybiBsb2NTdHJpbmdzO1xyXG59XHJcbi8qKlxyXG4gKiBTZXRzIHRoZSBsb2NhdGlvbiBvZiB0aGUgcmVzb3VyY2VzIGpzb24uICBUaGlzIGlzIHR5cGljYWxseSB0aGUgdGFzay5qc29uIGZpbGUuXHJcbiAqIENhbGwgb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzY3JpcHQgYmVmb3JlIGFueSBjYWxscyB0byBsb2MuXHJcbiAqIEBwYXJhbSAgICAgcGF0aCAgICAgIEZ1bGwgcGF0aCB0byB0aGUganNvbi5cclxuICogQHBhcmFtICAgICBpZ25vcmVXYXJuaW5ncyAgV29uJ3QgdGhyb3cgd2FybmluZ3MgaWYgcGF0aCBhbHJlYWR5IHNldC5cclxuICogQHJldHVybnMgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBfc2V0UmVzb3VyY2VQYXRoKHBhdGgsIGlnbm9yZVdhcm5pbmdzKSB7XHJcbiAgICBpZiAoaWdub3JlV2FybmluZ3MgPT09IHZvaWQgMCkgeyBpZ25vcmVXYXJuaW5ncyA9IGZhbHNlOyB9XHJcbiAgICBpZiAocHJvY2Vzcy5lbnZbJ1RBU0tMSUJfSU5QUk9DX1VOSVRTJ10pIHtcclxuICAgICAgICBfcmVzb3VyY2VGaWxlcyA9IHt9O1xyXG4gICAgICAgIF9saWJSZXNvdXJjZUZpbGVMb2FkZWQgPSBmYWxzZTtcclxuICAgICAgICBfbG9jU3RyaW5nQ2FjaGUgPSB7fTtcclxuICAgICAgICBfcmVzb3VyY2VDdWx0dXJlID0gJ2VuLVVTJztcclxuICAgIH1cclxuICAgIGlmICghX3Jlc291cmNlRmlsZXNbcGF0aF0pIHtcclxuICAgICAgICBfY2hlY2tQYXRoKHBhdGgsICdyZXNvdXJjZSBmaWxlIHBhdGgnKTtcclxuICAgICAgICBfcmVzb3VyY2VGaWxlc1twYXRoXSA9IHBhdGg7XHJcbiAgICAgICAgX2RlYnVnKCdhZGRpbmcgcmVzb3VyY2UgZmlsZTogJyArIHBhdGgpO1xyXG4gICAgICAgIF9yZXNvdXJjZUN1bHR1cmUgPSBfZ2V0VmFyaWFibGUoJ3N5c3RlbS5jdWx0dXJlJykgfHwgX3Jlc291cmNlQ3VsdHVyZTtcclxuICAgICAgICB2YXIgbG9jU3RycyA9IF9sb2FkTG9jU3RyaW5ncyhwYXRoLCBfcmVzb3VyY2VDdWx0dXJlKTtcclxuICAgICAgICBmb3IgKHZhciBrZXkgaW4gbG9jU3Rycykge1xyXG4gICAgICAgICAgICAvL2NhY2hlIGxvYyBzdHJpbmdcclxuICAgICAgICAgICAgX2xvY1N0cmluZ0NhY2hlW2tleV0gPSBsb2NTdHJzW2tleV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgaWYgKGlnbm9yZVdhcm5pbmdzKSB7XHJcbiAgICAgICAgICAgIF9kZWJ1ZyhfbG9jKCdMSUJfUmVzb3VyY2VGaWxlQWxyZWFkeVNldCcsIHBhdGgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIF93YXJuaW5nKF9sb2MoJ0xJQl9SZXNvdXJjZUZpbGVBbHJlYWR5U2V0JywgcGF0aCkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5leHBvcnRzLl9zZXRSZXNvdXJjZVBhdGggPSBfc2V0UmVzb3VyY2VQYXRoO1xyXG4vKipcclxuICogR2V0cyB0aGUgbG9jYWxpemVkIHN0cmluZyBmcm9tIHRoZSBqc29uIHJlc291cmNlIGZpbGUuICBPcHRpb25hbGx5IGZvcm1hdHMgd2l0aCBhZGRpdGlvbmFsIHBhcmFtcy5cclxuICpcclxuICogQHBhcmFtICAgICBrZXkgICAgICBrZXkgb2YgdGhlIHJlc291cmNlcyBzdHJpbmcgaW4gdGhlIHJlc291cmNlIGZpbGVcclxuICogQHBhcmFtICAgICBwYXJhbSAgICBhZGRpdGlvbmFsIHBhcmFtcyBmb3IgZm9ybWF0dGluZyB0aGUgc3RyaW5nXHJcbiAqIEByZXR1cm5zICAgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBfbG9jKGtleSkge1xyXG4gICAgdmFyIHBhcmFtID0gW107XHJcbiAgICBmb3IgKHZhciBfaSA9IDE7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgIHBhcmFtW19pIC0gMV0gPSBhcmd1bWVudHNbX2ldO1xyXG4gICAgfVxyXG4gICAgaWYgKCFfbGliUmVzb3VyY2VGaWxlTG9hZGVkKSB7XHJcbiAgICAgICAgLy8gbWVyZ2UgbG9jIHN0cmluZ3MgZnJvbSBhenVyZS1waXBlbGluZXMtdGFzay1saWIuXHJcbiAgICAgICAgdmFyIGxpYlJlc291cmNlRmlsZSA9IHBhdGguam9pbihfX2Rpcm5hbWUsICdsaWIuanNvbicpO1xyXG4gICAgICAgIHZhciBsaWJMb2NTdHJzID0gX2xvYWRMb2NTdHJpbmdzKGxpYlJlc291cmNlRmlsZSwgX3Jlc291cmNlQ3VsdHVyZSk7XHJcbiAgICAgICAgZm9yICh2YXIgbGliS2V5IGluIGxpYkxvY1N0cnMpIHtcclxuICAgICAgICAgICAgLy9jYWNoZSBhenVyZS1waXBlbGluZXMtdGFzay1saWIgbG9jIHN0cmluZ1xyXG4gICAgICAgICAgICBfbG9jU3RyaW5nQ2FjaGVbbGliS2V5XSA9IGxpYkxvY1N0cnNbbGliS2V5XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgX2xpYlJlc291cmNlRmlsZUxvYWRlZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB2YXIgbG9jU3RyaW5nO1xyXG4gICAgO1xyXG4gICAgaWYgKF9sb2NTdHJpbmdDYWNoZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgbG9jU3RyaW5nID0gX2xvY1N0cmluZ0NhY2hlW2tleV07XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoX3Jlc291cmNlRmlsZXMpLmxlbmd0aCA8PSAwKSB7XHJcbiAgICAgICAgICAgIF93YXJuaW5nKF9sb2MoJ0xJQl9SZXNvdXJjZUZpbGVOb3RTZXQnLCBrZXkpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIF93YXJuaW5nKF9sb2MoJ0xJQl9Mb2NTdHJpbmdOb3RGb3VuZCcsIGtleSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsb2NTdHJpbmcgPSBrZXk7XHJcbiAgICB9XHJcbiAgICBpZiAocGFyYW0ubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHJldHVybiB1dGlsLmZvcm1hdC5hcHBseSh0aGlzLCBbbG9jU3RyaW5nXS5jb25jYXQocGFyYW0pKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBsb2NTdHJpbmc7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5fbG9jID0gX2xvYztcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBJbnB1dCBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIEdldHMgYSB2YXJpYWJsZSB2YWx1ZSB0aGF0IGlzIGRlZmluZWQgb24gdGhlIGJ1aWxkL3JlbGVhc2UgZGVmaW5pdGlvbiBvciBzZXQgYXQgcnVudGltZS5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICBuYW1lIG9mIHRoZSB2YXJpYWJsZSB0byBnZXRcclxuICogQHJldHVybnMgICBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIF9nZXRWYXJpYWJsZShuYW1lKSB7XHJcbiAgICB2YXIgdmFydmFsO1xyXG4gICAgLy8gZ2V0IHRoZSBtZXRhZGF0YVxyXG4gICAgdmFyIGluZm87XHJcbiAgICB2YXIga2V5ID0gX2dldFZhcmlhYmxlS2V5KG5hbWUpO1xyXG4gICAgaWYgKGV4cG9ydHMuX2tub3duVmFyaWFibGVNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xyXG4gICAgICAgIGluZm8gPSBleHBvcnRzLl9rbm93blZhcmlhYmxlTWFwW2tleV07XHJcbiAgICB9XHJcbiAgICBpZiAoaW5mbyAmJiBpbmZvLnNlY3JldCkge1xyXG4gICAgICAgIC8vIGdldCB0aGUgc2VjcmV0IHZhbHVlXHJcbiAgICAgICAgdmFydmFsID0gZXhwb3J0cy5fdmF1bHQucmV0cmlldmVTZWNyZXQoJ1NFQ1JFVF8nICsga2V5KTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIGdldCB0aGUgcHVibGljIHZhbHVlXHJcbiAgICAgICAgdmFydmFsID0gcHJvY2Vzcy5lbnZba2V5XTtcclxuICAgICAgICAvLyBmYWxsYmFjayBmb3IgcHJlIDIuMTA0LjEgYWdlbnRcclxuICAgICAgICBpZiAoIXZhcnZhbCAmJiBuYW1lLnRvVXBwZXJDYXNlKCkgPT0gJ0FHRU5ULkpPQlNUQVRVUycpIHtcclxuICAgICAgICAgICAgdmFydmFsID0gcHJvY2Vzcy5lbnZbJ2FnZW50LmpvYnN0YXR1cyddO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIF9kZWJ1ZyhuYW1lICsgJz0nICsgdmFydmFsKTtcclxuICAgIHJldHVybiB2YXJ2YWw7XHJcbn1cclxuZXhwb3J0cy5fZ2V0VmFyaWFibGUgPSBfZ2V0VmFyaWFibGU7XHJcbmZ1bmN0aW9uIF9nZXRWYXJpYWJsZUtleShuYW1lKSB7XHJcbiAgICBpZiAoIW5hbWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoX2xvYygnTElCX1BhcmFtZXRlcklzUmVxdWlyZWQnLCAnbmFtZScpKTtcclxuICAgIH1cclxuICAgIHJldHVybiBuYW1lLnJlcGxhY2UoL1xcLi9nLCAnXycpLnJlcGxhY2UoLyAvZywgJ18nKS50b1VwcGVyQ2FzZSgpO1xyXG59XHJcbmV4cG9ydHMuX2dldFZhcmlhYmxlS2V5ID0gX2dldFZhcmlhYmxlS2V5O1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIENtZCBIZWxwZXJzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZnVuY3Rpb24gX2NvbW1hbmQoY29tbWFuZCwgcHJvcGVydGllcywgbWVzc2FnZSkge1xyXG4gICAgdmFyIHRhc2tDbWQgPSBuZXcgdGNtLlRhc2tDb21tYW5kKGNvbW1hbmQsIHByb3BlcnRpZXMsIG1lc3NhZ2UpO1xyXG4gICAgX3dyaXRlTGluZSh0YXNrQ21kLnRvU3RyaW5nKCkpO1xyXG59XHJcbmV4cG9ydHMuX2NvbW1hbmQgPSBfY29tbWFuZDtcclxuZnVuY3Rpb24gX3dhcm5pbmcobWVzc2FnZSkge1xyXG4gICAgX2NvbW1hbmQoJ3Rhc2suaXNzdWUnLCB7ICd0eXBlJzogJ3dhcm5pbmcnIH0sIG1lc3NhZ2UpO1xyXG59XHJcbmV4cG9ydHMuX3dhcm5pbmcgPSBfd2FybmluZztcclxuZnVuY3Rpb24gX2Vycm9yKG1lc3NhZ2UpIHtcclxuICAgIF9jb21tYW5kKCd0YXNrLmlzc3VlJywgeyAndHlwZSc6ICdlcnJvcicgfSwgbWVzc2FnZSk7XHJcbn1cclxuZXhwb3J0cy5fZXJyb3IgPSBfZXJyb3I7XHJcbmZ1bmN0aW9uIF9kZWJ1ZyhtZXNzYWdlKSB7XHJcbiAgICBfY29tbWFuZCgndGFzay5kZWJ1ZycsIG51bGwsIG1lc3NhZ2UpO1xyXG59XHJcbmV4cG9ydHMuX2RlYnVnID0gX2RlYnVnO1xyXG4vLyAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIC8vIERpc2sgRnVuY3Rpb25zXHJcbi8vIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIFJldHVybnMgd2hldGhlciBhIHBhdGggZXhpc3RzLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHBhdGggICAgICBwYXRoIHRvIGNoZWNrXHJcbiAqIEByZXR1cm5zICAgYm9vbGVhblxyXG4gKi9cclxuZnVuY3Rpb24gX2V4aXN0KHBhdGgpIHtcclxuICAgIHZhciBleGlzdCA9IGZhbHNlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICBleGlzdCA9ICEhKHBhdGggJiYgZnMuc3RhdFN5bmMocGF0aCkgIT0gbnVsbCk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgaWYgKGVyciAmJiBlcnIuY29kZSA9PT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgZXhpc3QgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZXhpc3Q7XHJcbn1cclxuZXhwb3J0cy5fZXhpc3QgPSBfZXhpc3Q7XHJcbi8qKlxyXG4gKiBDaGVja3Mgd2hldGhlciBhIHBhdGggZXhpc3RzLlxyXG4gKiBJZiB0aGUgcGF0aCBkb2VzIG5vdCBleGlzdCwgaXQgd2lsbCB0aHJvdy5cclxuICpcclxuICogQHBhcmFtICAgICBwICAgICAgICAgcGF0aCB0byBjaGVja1xyXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgICBuYW1lIG9ubHkgdXNlZCBpbiBlcnJvciBtZXNzYWdlIHRvIGlkZW50aWZ5IHRoZSBwYXRoXHJcbiAqIEByZXR1cm5zICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gX2NoZWNrUGF0aChwLCBuYW1lKSB7XHJcbiAgICBfZGVidWcoJ2NoZWNrIHBhdGggOiAnICsgcCk7XHJcbiAgICBpZiAoIV9leGlzdChwKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihfbG9jKCdMSUJfUGF0aE5vdEZvdW5kJywgbmFtZSwgcCkpO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuX2NoZWNrUGF0aCA9IF9jaGVja1BhdGg7XHJcbi8qKlxyXG4gKiBSZXR1cm5zIHBhdGggb2YgYSB0b29sIGhhZCB0aGUgdG9vbCBhY3R1YWxseSBiZWVuIGludm9rZWQuICBSZXNvbHZlcyB2aWEgcGF0aHMuXHJcbiAqIElmIHlvdSBjaGVjayBhbmQgdGhlIHRvb2wgZG9lcyBub3QgZXhpc3QsIGl0IHdpbGwgdGhyb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgdG9vbCAgICAgICBuYW1lIG9mIHRoZSB0b29sXHJcbiAqIEBwYXJhbSAgICAgY2hlY2sgICAgICB3aGV0aGVyIHRvIGNoZWNrIGlmIHRvb2wgZXhpc3RzXHJcbiAqIEByZXR1cm5zICAgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBfd2hpY2godG9vbCwgY2hlY2spIHtcclxuICAgIGlmICghdG9vbCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncGFyYW1ldGVyIFxcJ3Rvb2xcXCcgaXMgcmVxdWlyZWQnKTtcclxuICAgIH1cclxuICAgIC8vIHJlY3Vyc2l2ZSB3aGVuIGNoZWNrPXRydWVcclxuICAgIGlmIChjaGVjaykge1xyXG4gICAgICAgIHZhciByZXN1bHQgPSBfd2hpY2godG9vbCwgZmFsc2UpO1xyXG4gICAgICAgIGlmIChyZXN1bHQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihfbG9jKCdMSUJfV2hpY2hOb3RGb3VuZF9XaW4nLCB0b29sKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoX2xvYygnTElCX1doaWNoTm90Rm91bmRfTGludXgnLCB0b29sKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBfZGVidWcoXCJ3aGljaCAnXCIgKyB0b29sICsgXCInXCIpO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICAvLyBidWlsZCB0aGUgbGlzdCBvZiBleHRlbnNpb25zIHRvIHRyeVxyXG4gICAgICAgIHZhciBleHRlbnNpb25zID0gW107XHJcbiAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyAmJiBwcm9jZXNzLmVudlsnUEFUSEVYVCddKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBwcm9jZXNzLmVudlsnUEFUSEVYVCddLnNwbGl0KHBhdGguZGVsaW1pdGVyKTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgIHZhciBleHRlbnNpb24gPSBfYVtfaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9ucy5wdXNoKGV4dGVuc2lvbik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaWYgaXQncyByb290ZWQsIHJldHVybiBpdCBpZiBleGlzdHMuIG90aGVyd2lzZSByZXR1cm4gZW1wdHkuXHJcbiAgICAgICAgaWYgKF9pc1Jvb3RlZCh0b29sKSkge1xyXG4gICAgICAgICAgICB2YXIgZmlsZVBhdGggPSBfdHJ5R2V0RXhlY3V0YWJsZVBhdGgodG9vbCwgZXh0ZW5zaW9ucyk7XHJcbiAgICAgICAgICAgIGlmIChmaWxlUGF0aCkge1xyXG4gICAgICAgICAgICAgICAgX2RlYnVnKFwiZm91bmQ6ICdcIiArIGZpbGVQYXRoICsgXCInXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVQYXRoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF9kZWJ1Zygnbm90IGZvdW5kJyk7XHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaWYgYW55IHBhdGggc2VwYXJhdG9ycywgcmV0dXJuIGVtcHR5XHJcbiAgICAgICAgaWYgKHRvb2wuaW5kZXhPZignLycpID49IDAgfHwgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyAmJiB0b29sLmluZGV4T2YoJ1xcXFwnKSA+PSAwKSkge1xyXG4gICAgICAgICAgICBfZGVidWcoJ25vdCBmb3VuZCcpO1xyXG4gICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGJ1aWxkIHRoZSBsaXN0IG9mIGRpcmVjdG9yaWVzXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBOb3RlLCB0ZWNobmljYWxseSBcIndoZXJlXCIgY2hlY2tzIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBvbiBXaW5kb3dzLiBGcm9tIGEgdGFzayBsaWIgcGVyc3BlY3RpdmUsXHJcbiAgICAgICAgLy8gaXQgZmVlbHMgbGlrZSB3ZSBzaG91bGQgbm90IGRvIHRoaXMuIENoZWNraW5nIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBzZWVtcyBsaWtlIG1vcmUgb2YgYSB1c2VcclxuICAgICAgICAvLyBjYXNlIG9mIGEgc2hlbGwsIGFuZCB0aGUgd2hpY2goKSBmdW5jdGlvbiBleHBvc2VkIGJ5IHRoZSB0YXNrIGxpYiBzaG91bGQgc3RyaXZlIGZvciBjb25zaXN0ZW5jeVxyXG4gICAgICAgIC8vIGFjcm9zcyBwbGF0Zm9ybXMuXHJcbiAgICAgICAgdmFyIGRpcmVjdG9yaWVzID0gW107XHJcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52WydQQVRIJ10pIHtcclxuICAgICAgICAgICAgZm9yICh2YXIgX2IgPSAwLCBfYyA9IHByb2Nlc3MuZW52WydQQVRIJ10uc3BsaXQocGF0aC5kZWxpbWl0ZXIpOyBfYiA8IF9jLmxlbmd0aDsgX2IrKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIHAgPSBfY1tfYl07XHJcbiAgICAgICAgICAgICAgICBpZiAocCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRpcmVjdG9yaWVzLnB1c2gocCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gcmV0dXJuIHRoZSBmaXJzdCBtYXRjaFxyXG4gICAgICAgIGZvciAodmFyIF9kID0gMCwgZGlyZWN0b3JpZXNfMSA9IGRpcmVjdG9yaWVzOyBfZCA8IGRpcmVjdG9yaWVzXzEubGVuZ3RoOyBfZCsrKSB7XHJcbiAgICAgICAgICAgIHZhciBkaXJlY3RvcnkgPSBkaXJlY3Rvcmllc18xW19kXTtcclxuICAgICAgICAgICAgdmFyIGZpbGVQYXRoID0gX3RyeUdldEV4ZWN1dGFibGVQYXRoKGRpcmVjdG9yeSArIHBhdGguc2VwICsgdG9vbCwgZXh0ZW5zaW9ucyk7XHJcbiAgICAgICAgICAgIGlmIChmaWxlUGF0aCkge1xyXG4gICAgICAgICAgICAgICAgX2RlYnVnKFwiZm91bmQ6ICdcIiArIGZpbGVQYXRoICsgXCInXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVQYXRoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIF9kZWJ1Zygnbm90IGZvdW5kJyk7XHJcbiAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihfbG9jKCdMSUJfT3BlcmF0aW9uRmFpbGVkJywgJ3doaWNoJywgZXJyLm1lc3NhZ2UpKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLl93aGljaCA9IF93aGljaDtcclxuLyoqXHJcbiAqIEJlc3QgZWZmb3J0IGF0dGVtcHQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBmaWxlIGV4aXN0cyBhbmQgaXMgZXhlY3V0YWJsZS5cclxuICogQHBhcmFtIGZpbGVQYXRoICAgIGZpbGUgcGF0aCB0byBjaGVja1xyXG4gKiBAcGFyYW0gZXh0ZW5zaW9ucyAgYWRkaXRpb25hbCBmaWxlIGV4dGVuc2lvbnMgdG8gdHJ5XHJcbiAqIEByZXR1cm4gaWYgZmlsZSBleGlzdHMgYW5kIGlzIGV4ZWN1dGFibGUsIHJldHVybnMgdGhlIGZpbGUgcGF0aC4gb3RoZXJ3aXNlIGVtcHR5IHN0cmluZy5cclxuICovXHJcbmZ1bmN0aW9uIF90cnlHZXRFeGVjdXRhYmxlUGF0aChmaWxlUGF0aCwgZXh0ZW5zaW9ucykge1xyXG4gICAgdHJ5IHtcclxuICAgICAgICAvLyB0ZXN0IGZpbGUgZXhpc3RzXHJcbiAgICAgICAgdmFyIHN0YXRzID0gZnMuc3RhdFN5bmMoZmlsZVBhdGgpO1xyXG4gICAgICAgIGlmIChzdGF0cy5pc0ZpbGUoKSkge1xyXG4gICAgICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBvbiBXaW5kb3dzLCB0ZXN0IGZvciB2YWxpZCBleHRlbnNpb25cclxuICAgICAgICAgICAgICAgIHZhciBpc0V4ZWN1dGFibGUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHZhciBmaWxlTmFtZSA9IHBhdGguYmFzZW5hbWUoZmlsZVBhdGgpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGRvdEluZGV4ID0gZmlsZU5hbWUubGFzdEluZGV4T2YoJy4nKTtcclxuICAgICAgICAgICAgICAgIGlmIChkb3RJbmRleCA+PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHVwcGVyRXh0XzEgPSBmaWxlTmFtZS5zdWJzdHIoZG90SW5kZXgpLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbnMuc29tZShmdW5jdGlvbiAodmFsaWRFeHQpIHsgcmV0dXJuIHZhbGlkRXh0LnRvVXBwZXJDYXNlKCkgPT0gdXBwZXJFeHRfMTsgfSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVQYXRoO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmIChpc1VuaXhFeGVjdXRhYmxlKHN0YXRzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICBpZiAoZXJyLmNvZGUgIT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgX2RlYnVnKFwiVW5leHBlY3RlZCBlcnJvciBhdHRlbXB0aW5nIHRvIGRldGVybWluZSBpZiBleGVjdXRhYmxlIGZpbGUgZXhpc3RzICdcIiArIGZpbGVQYXRoICsgXCInOiBcIiArIGVycik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gdHJ5IGVhY2ggZXh0ZW5zaW9uXHJcbiAgICB2YXIgb3JpZ2luYWxGaWxlUGF0aCA9IGZpbGVQYXRoO1xyXG4gICAgZm9yICh2YXIgX2kgPSAwLCBleHRlbnNpb25zXzEgPSBleHRlbnNpb25zOyBfaSA8IGV4dGVuc2lvbnNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICB2YXIgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc18xW19pXTtcclxuICAgICAgICB2YXIgZm91bmQgPSBmYWxzZTtcclxuICAgICAgICB2YXIgZmlsZVBhdGhfMSA9IG9yaWdpbmFsRmlsZVBhdGggKyBleHRlbnNpb247XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgdmFyIHN0YXRzID0gZnMuc3RhdFN5bmMoZmlsZVBhdGhfMSk7XHJcbiAgICAgICAgICAgIGlmIChzdGF0cy5pc0ZpbGUoKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHByZXNlcnZlIHRoZSBjYXNlIG9mIHRoZSBhY3R1YWwgZmlsZSAoc2luY2UgYW4gZXh0ZW5zaW9uIHdhcyBhcHBlbmRlZClcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGlyZWN0b3J5ID0gcGF0aC5kaXJuYW1lKGZpbGVQYXRoXzEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdXBwZXJOYW1lID0gcGF0aC5iYXNlbmFtZShmaWxlUGF0aF8xKS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBfYSA9IDAsIF9iID0gZnMucmVhZGRpclN5bmMoZGlyZWN0b3J5KTsgX2EgPCBfYi5sZW5ndGg7IF9hKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhY3R1YWxOYW1lID0gX2JbX2FdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVwcGVyTmFtZSA9PSBhY3R1YWxOYW1lLnRvVXBwZXJDYXNlKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlUGF0aF8xID0gcGF0aC5qb2luKGRpcmVjdG9yeSwgYWN0dWFsTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfZGVidWcoXCJVbmV4cGVjdGVkIGVycm9yIGF0dGVtcHRpbmcgdG8gZGV0ZXJtaW5lIHRoZSBhY3R1YWwgY2FzZSBvZiB0aGUgZmlsZSAnXCIgKyBmaWxlUGF0aF8xICsgXCInOiBcIiArIGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aF8xO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzVW5peEV4ZWN1dGFibGUoc3RhdHMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aF8xO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPSAnRU5PRU5UJykge1xyXG4gICAgICAgICAgICAgICAgX2RlYnVnKFwiVW5leHBlY3RlZCBlcnJvciBhdHRlbXB0aW5nIHRvIGRldGVybWluZSBpZiBleGVjdXRhYmxlIGZpbGUgZXhpc3RzICdcIiArIGZpbGVQYXRoXzEgKyBcIic6IFwiICsgZXJyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiAnJztcclxufVxyXG4vLyBvbiBNYWMvTGludXgsIHRlc3QgdGhlIGV4ZWN1dGUgYml0XHJcbi8vICAgICBSICAgVyAgWCAgUiAgVyBYIFIgVyBYXHJcbi8vICAgMjU2IDEyOCA2NCAzMiAxNiA4IDQgMiAxXHJcbmZ1bmN0aW9uIGlzVW5peEV4ZWN1dGFibGUoc3RhdHMpIHtcclxuICAgIHJldHVybiAoc3RhdHMubW9kZSAmIDEpID4gMCB8fCAoKHN0YXRzLm1vZGUgJiA4KSA+IDAgJiYgc3RhdHMuZ2lkID09PSBwcm9jZXNzLmdldGdpZCgpKSB8fCAoKHN0YXRzLm1vZGUgJiA2NCkgPiAwICYmIHN0YXRzLnVpZCA9PT0gcHJvY2Vzcy5nZXR1aWQoKSk7XHJcbn1cclxuZnVuY3Rpb24gX2xlZ2FjeUZpbmRGaWxlc19jb252ZXJ0UGF0dGVyblRvUmVnRXhwKHBhdHRlcm4pIHtcclxuICAgIHBhdHRlcm4gPSAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybi5yZXBsYWNlKC9cXFxcL2csICcvJykgOiBwYXR0ZXJuKSAvLyBub3JtYWxpemUgc2VwYXJhdG9yIG9uIFdpbmRvd3NcclxuICAgICAgICAucmVwbGFjZSgvWy1cXC9cXFxcXiQqKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJykgLy8gcmVnZXggZXNjYXBlIC0gZnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzM1NjE0OTMvaXMtdGhlcmUtYS1yZWdleHAtZXNjYXBlLWZ1bmN0aW9uLWluLWphdmFzY3JpcHRcclxuICAgICAgICAucmVwbGFjZSgvXFxcXFxcL1xcXFxcXCpcXFxcXFwqXFxcXFxcLy9nLCAnKChcXC8uKy8pfChcXC8pKScpIC8vIHJlcGxhY2UgZGlyZWN0b3J5IGdsb2JzdGFyLCBlLmcuIC9oZWxsby8qKi93b3JsZFxyXG4gICAgICAgIC5yZXBsYWNlKC9cXFxcXFwqXFxcXFxcKi9nLCAnLionKSAvLyByZXBsYWNlIHJlbWFpbmluZyBnbG9ic3RhcnMgd2l0aCBhIHdpbGRjYXJkIHRoYXQgY2FuIHNwYW4gZGlyZWN0b3J5IHNlcGFyYXRvcnMsIGUuZy4gL2hlbGxvLyoqZGxsXHJcbiAgICAgICAgLnJlcGxhY2UoL1xcXFxcXCovZywgJ1teXFwvXSonKSAvLyByZXBsYWNlIGFzdGVyaXNrcyB3aXRoIGEgd2lsZGNhcmQgdGhhdCBjYW5ub3Qgc3BhbiBkaXJlY3Rvcnkgc2VwYXJhdG9ycywgZS5nLiAvaGVsbG8vKi5kbGxcclxuICAgICAgICAucmVwbGFjZSgvXFxcXFxcPy9nLCAnW15cXC9dJyk7IC8vIHJlcGxhY2Ugc2luZ2xlIGNoYXJhY3RlciB3aWxkY2FyZHMsIGUuZy4gL2hlbGxvL2xvZz8uZGxsXHJcbiAgICBwYXR0ZXJuID0gXCJeXCIgKyBwYXR0ZXJuICsgXCIkXCI7XHJcbiAgICB2YXIgZmxhZ3MgPSBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgPyAnaScgOiAnJztcclxuICAgIHJldHVybiBuZXcgUmVnRXhwKHBhdHRlcm4sIGZsYWdzKTtcclxufVxyXG5leHBvcnRzLl9sZWdhY3lGaW5kRmlsZXNfY29udmVydFBhdHRlcm5Ub1JlZ0V4cCA9IF9sZWdhY3lGaW5kRmlsZXNfY29udmVydFBhdHRlcm5Ub1JlZ0V4cDtcclxuZnVuY3Rpb24gX2Nsb25lTWF0Y2hPcHRpb25zKG1hdGNoT3B0aW9ucykge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBkZWJ1ZzogbWF0Y2hPcHRpb25zLmRlYnVnLFxyXG4gICAgICAgIG5vYnJhY2U6IG1hdGNoT3B0aW9ucy5ub2JyYWNlLFxyXG4gICAgICAgIG5vZ2xvYnN0YXI6IG1hdGNoT3B0aW9ucy5ub2dsb2JzdGFyLFxyXG4gICAgICAgIGRvdDogbWF0Y2hPcHRpb25zLmRvdCxcclxuICAgICAgICBub2V4dDogbWF0Y2hPcHRpb25zLm5vZXh0LFxyXG4gICAgICAgIG5vY2FzZTogbWF0Y2hPcHRpb25zLm5vY2FzZSxcclxuICAgICAgICBub251bGw6IG1hdGNoT3B0aW9ucy5ub251bGwsXHJcbiAgICAgICAgbWF0Y2hCYXNlOiBtYXRjaE9wdGlvbnMubWF0Y2hCYXNlLFxyXG4gICAgICAgIG5vY29tbWVudDogbWF0Y2hPcHRpb25zLm5vY29tbWVudCxcclxuICAgICAgICBub25lZ2F0ZTogbWF0Y2hPcHRpb25zLm5vbmVnYXRlLFxyXG4gICAgICAgIGZsaXBOZWdhdGU6IG1hdGNoT3B0aW9ucy5mbGlwTmVnYXRlXHJcbiAgICB9O1xyXG59XHJcbmV4cG9ydHMuX2Nsb25lTWF0Y2hPcHRpb25zID0gX2Nsb25lTWF0Y2hPcHRpb25zO1xyXG5mdW5jdGlvbiBfZ2V0RmluZEluZm9Gcm9tUGF0dGVybihkZWZhdWx0Um9vdCwgcGF0dGVybiwgbWF0Y2hPcHRpb25zKSB7XHJcbiAgICAvLyBwYXJhbWV0ZXIgdmFsaWRhdGlvblxyXG4gICAgaWYgKCFkZWZhdWx0Um9vdCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZ2V0RmluZFJvb3RGcm9tUGF0dGVybigpIHBhcmFtZXRlciBkZWZhdWx0Um9vdCBjYW5ub3QgYmUgZW1wdHknKTtcclxuICAgIH1cclxuICAgIGlmICghcGF0dGVybikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZ2V0RmluZFJvb3RGcm9tUGF0dGVybigpIHBhcmFtZXRlciBwYXR0ZXJuIGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgaWYgKCFtYXRjaE9wdGlvbnMubm9icmFjZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZ2V0RmluZFJvb3RGcm9tUGF0dGVybigpIGV4cGVjdGVkIG1hdGNoT3B0aW9ucy5ub2JyYWNlIHRvIGJlIHRydWUnKTtcclxuICAgIH1cclxuICAgIC8vIGZvciB0aGUgc2FrZSBvZiBkZXRlcm1pbmluZyB0aGUgZmluZFBhdGgsIHByZXRlbmQgbm9jYXNlPWZhbHNlXHJcbiAgICBtYXRjaE9wdGlvbnMgPSBfY2xvbmVNYXRjaE9wdGlvbnMobWF0Y2hPcHRpb25zKTtcclxuICAgIG1hdGNoT3B0aW9ucy5ub2Nhc2UgPSBmYWxzZTtcclxuICAgIC8vIGNoZWNrIGlmIGJhc2VuYW1lIG9ubHkgYW5kIG1hdGNoQmFzZT10cnVlXHJcbiAgICBpZiAobWF0Y2hPcHRpb25zLm1hdGNoQmFzZSAmJlxyXG4gICAgICAgICFfaXNSb290ZWQocGF0dGVybikgJiZcclxuICAgICAgICAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybi5yZXBsYWNlKC9cXFxcL2csICcvJykgOiBwYXR0ZXJuKS5pbmRleE9mKCcvJykgPCAwKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgYWRqdXN0ZWRQYXR0ZXJuOiBwYXR0ZXJuLFxyXG4gICAgICAgICAgICBmaW5kUGF0aDogZGVmYXVsdFJvb3QsXHJcbiAgICAgICAgICAgIHN0YXRPbmx5OiBmYWxzZSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgLy8gdGhlIHRlY2huaXF1ZSBhcHBsaWVkIGJ5IHRoaXMgZnVuY3Rpb24gaXMgdG8gdXNlIHRoZSBpbmZvcm1hdGlvbiBvbiB0aGUgTWluaW1hdGNoIG9iamVjdCBkZXRlcm1pbmVcclxuICAgIC8vIHRoZSBmaW5kUGF0aC4gTWluaW1hdGNoIGJyZWFrcyB0aGUgcGF0dGVybiBpbnRvIHBhdGggc2VnbWVudHMsIGFuZCBleHBvc2VzIGluZm9ybWF0aW9uIGFib3V0IHdoaWNoXHJcbiAgICAvLyBzZWdtZW50cyBhcmUgbGl0ZXJhbCB2cyBwYXR0ZXJucy5cclxuICAgIC8vXHJcbiAgICAvLyBub3RlLCB0aGUgdGVjaG5pcXVlIGN1cnJlbnRseSBpbXBvc2VzIGEgbGltaXRhdGlvbiBmb3IgZHJpdmUtcmVsYXRpdmUgcGF0aHMgd2l0aCBhIGdsb2IgaW4gdGhlXHJcbiAgICAvLyBmaXJzdCBzZWdtZW50LCBlLmcuIEM6aGVsbG8qL3dvcmxkLiBpdCdzIGZlYXNpYmxlIHRvIG92ZXJjb21lIHRoaXMgbGltaXRhdGlvbiwgYnV0IGlzIGxlZnQgdW5zb2x2ZWRcclxuICAgIC8vIGZvciBub3cuXHJcbiAgICB2YXIgbWluaW1hdGNoT2JqID0gbmV3IG1pbmltYXRjaC5NaW5pbWF0Y2gocGF0dGVybiwgbWF0Y2hPcHRpb25zKTtcclxuICAgIC8vIHRoZSBcInNldFwiIHByb3BlcnR5IGlzIGFuIGFycmF5IG9mIGFycmF5cyBvZiBwYXJzZWQgcGF0aCBzZWdtZW50IGluZm8uIHRoZSBvdXRlciBhcnJheSBzaG91bGQgb25seVxyXG4gICAgLy8gY29udGFpbiBvbmUgaXRlbSwgb3RoZXJ3aXNlIHNvbWV0aGluZyB3ZW50IHdyb25nLiBicmFjZSBleHBhbnNpb24gY2FuIHJlc3VsdCBpbiBtdWx0aXBsZSBhcnJheXMsXHJcbiAgICAvLyBidXQgdGhhdCBzaG91bGQgYmUgdHVybmVkIG9mZiBieSB0aGUgdGltZSB0aGlzIGZ1bmN0aW9uIGlzIHJlYWNoZWQuXHJcbiAgICBpZiAobWluaW1hdGNoT2JqLnNldC5sZW5ndGggIT0gMSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZ2V0RmluZFJvb3RGcm9tUGF0dGVybigpIGV4cGVjdGVkIE1pbmltYXRjaCguLi4pLnNldC5sZW5ndGggdG8gYmUgMS4gQWN0dWFsOiAnICsgbWluaW1hdGNoT2JqLnNldC5sZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgdmFyIGxpdGVyYWxTZWdtZW50cyA9IFtdO1xyXG4gICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IG1pbmltYXRjaE9iai5zZXRbMF07IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgdmFyIHBhcnNlZFNlZ21lbnQgPSBfYVtfaV07XHJcbiAgICAgICAgaWYgKHR5cGVvZiBwYXJzZWRTZWdtZW50ID09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIC8vIHRoZSBpdGVtIGlzIGEgc3RyaW5nIHdoZW4gdGhlIG9yaWdpbmFsIGlucHV0IGZvciB0aGUgcGF0aCBzZWdtZW50IGRvZXMgbm90IGNvbnRhaW4gYW55XHJcbiAgICAgICAgICAgIC8vIHVuZXNjYXBlZCBnbG9iIGNoYXJhY3RlcnMuXHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIG5vdGUsIHRoZSBzdHJpbmcgaGVyZSBpcyBhbHJlYWR5IHVuZXNjYXBlZCAoaS5lLiBnbG9iIGVzY2FwaW5nIHJlbW92ZWQpLCBzbyBpdCBpcyByZWFkeVxyXG4gICAgICAgICAgICAvLyB0byBwYXNzIHRvIGZpbmQoKSBhcy1pcy4gZm9yIGV4YW1wbGUsIGFuIGlucHV0IHN0cmluZyAnaGVsbG9cXFxcKndvcmxkJyA9PiAnaGVsbG8qd29ybGQnLlxyXG4gICAgICAgICAgICBsaXRlcmFsU2VnbWVudHMucHVzaChwYXJzZWRTZWdtZW50KTtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gICAgLy8gam9pbiB0aGUgbGl0ZXJhbCBzZWdtZW50cyBiYWNrIHRvZ2V0aGVyLiBNaW5pbWF0Y2ggY29udmVydHMgJ1xcJyB0byAnLycgb24gV2luZG93cywgdGhlbiBzcXVhc2hlc1xyXG4gICAgLy8gY29uc2VxdWV0aXZlIHNsYXNoZXMsIGFuZCBmaW5hbGx5IHNwbGl0cyBvbiBzbGFzaC4gdGhpcyBtZWFucyB0aGF0IFVOQyBmb3JtYXQgaXMgbG9zdCwgYnV0IGNhblxyXG4gICAgLy8gYmUgZGV0ZWN0ZWQgZnJvbSB0aGUgb3JpZ2luYWwgcGF0dGVybi5cclxuICAgIHZhciBqb2luZWRTZWdtZW50cyA9IGxpdGVyYWxTZWdtZW50cy5qb2luKCcvJyk7XHJcbiAgICBpZiAoam9pbmVkU2VnbWVudHMgJiYgcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInICYmIF9zdGFydHNXaXRoKHBhdHRlcm4ucmVwbGFjZSgvXFxcXC9nLCAnLycpLCAnLy8nKSkge1xyXG4gICAgICAgIGpvaW5lZFNlZ21lbnRzID0gJy8nICsgam9pbmVkU2VnbWVudHM7IC8vIHJlc3RvcmUgVU5DIGZvcm1hdFxyXG4gICAgfVxyXG4gICAgLy8gZGV0ZXJtaW5lIHRoZSBmaW5kIHBhdGhcclxuICAgIHZhciBmaW5kUGF0aDtcclxuICAgIGlmIChfaXNSb290ZWQocGF0dGVybikpIHsgLy8gdGhlIHBhdHRlcm4gd2FzIHJvb3RlZFxyXG4gICAgICAgIGZpbmRQYXRoID0gam9pbmVkU2VnbWVudHM7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChqb2luZWRTZWdtZW50cykgeyAvLyB0aGUgcGF0dGVybiB3YXMgbm90IHJvb3RlZCwgYW5kIGxpdGVyYWwgc2VnbWVudHMgd2VyZSBmb3VuZFxyXG4gICAgICAgIGZpbmRQYXRoID0gX2Vuc3VyZVJvb3RlZChkZWZhdWx0Um9vdCwgam9pbmVkU2VnbWVudHMpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7IC8vIHRoZSBwYXR0ZXJuIHdhcyBub3Qgcm9vdGVkLCBhbmQgbm8gbGl0ZXJhbCBzZWdtZW50cyB3ZXJlIGZvdW5kXHJcbiAgICAgICAgZmluZFBhdGggPSBkZWZhdWx0Um9vdDtcclxuICAgIH1cclxuICAgIC8vIGNsZWFuIHVwIHRoZSBwYXRoXHJcbiAgICBpZiAoZmluZFBhdGgpIHtcclxuICAgICAgICBmaW5kUGF0aCA9IF9nZXREaXJlY3RvcnlOYW1lKF9lbnN1cmVSb290ZWQoZmluZFBhdGgsICdfJykpOyAvLyBoYWNrIHRvIHJlbW92ZSB1bm5lY2Vzc2FyeSB0cmFpbGluZyBzbGFzaFxyXG4gICAgICAgIGZpbmRQYXRoID0gX25vcm1hbGl6ZVNlcGFyYXRvcnMoZmluZFBhdGgpOyAvLyBub3JtYWxpemUgc2xhc2hlc1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBhZGp1c3RlZFBhdHRlcm46IF9lbnN1cmVQYXR0ZXJuUm9vdGVkKGRlZmF1bHRSb290LCBwYXR0ZXJuKSxcclxuICAgICAgICBmaW5kUGF0aDogZmluZFBhdGgsXHJcbiAgICAgICAgc3RhdE9ubHk6IGxpdGVyYWxTZWdtZW50cy5sZW5ndGggPT0gbWluaW1hdGNoT2JqLnNldFswXS5sZW5ndGgsXHJcbiAgICB9O1xyXG59XHJcbmV4cG9ydHMuX2dldEZpbmRJbmZvRnJvbVBhdHRlcm4gPSBfZ2V0RmluZEluZm9Gcm9tUGF0dGVybjtcclxuZnVuY3Rpb24gX2Vuc3VyZVBhdHRlcm5Sb290ZWQocm9vdCwgcCkge1xyXG4gICAgaWYgKCFyb290KSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdlbnN1cmVQYXR0ZXJuUm9vdGVkKCkgcGFyYW1ldGVyIFwicm9vdFwiIGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgaWYgKCFwKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdlbnN1cmVQYXR0ZXJuUm9vdGVkKCkgcGFyYW1ldGVyIFwicFwiIGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgaWYgKF9pc1Jvb3RlZChwKSkge1xyXG4gICAgICAgIHJldHVybiBwO1xyXG4gICAgfVxyXG4gICAgLy8gbm9ybWFsaXplIHJvb3RcclxuICAgIHJvb3QgPSBfbm9ybWFsaXplU2VwYXJhdG9ycyhyb290KTtcclxuICAgIC8vIGVzY2FwZSBzcGVjaWFsIGdsb2IgY2hhcmFjdGVyc1xyXG4gICAgcm9vdCA9IChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgPyByb290IDogcm9vdC5yZXBsYWNlKC9cXFxcL2csICdcXFxcXFxcXCcpKSAvLyBlc2NhcGUgJ1xcJyBvbiBPU1gvTGludXhcclxuICAgICAgICAucmVwbGFjZSgvKFxcWykoPz1bXlxcL10rXFxdKS9nLCAnW1tdJykgLy8gZXNjYXBlICdbJyB3aGVuICddJyBmb2xsb3dzIHdpdGhpbiB0aGUgcGF0aCBzZWdtZW50XHJcbiAgICAgICAgLnJlcGxhY2UoL1xcPy9nLCAnWz9dJykgLy8gZXNjYXBlICc/J1xyXG4gICAgICAgIC5yZXBsYWNlKC9cXCovZywgJ1sqXScpIC8vIGVzY2FwZSAnKidcclxuICAgICAgICAucmVwbGFjZSgvXFwrXFwoL2csICdbK10oJykgLy8gZXNjYXBlICcrKCdcclxuICAgICAgICAucmVwbGFjZSgvQFxcKC9nLCAnW0BdKCcpIC8vIGVzY2FwZSAnQCgnXHJcbiAgICAgICAgLnJlcGxhY2UoLyFcXCgvZywgJ1shXSgnKTsgLy8gZXNjYXBlICchKCdcclxuICAgIHJldHVybiBfZW5zdXJlUm9vdGVkKHJvb3QsIHApO1xyXG59XHJcbmV4cG9ydHMuX2Vuc3VyZVBhdHRlcm5Sb290ZWQgPSBfZW5zdXJlUGF0dGVyblJvb3RlZDtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFBvcHVsYXRlIHRoZSB2YXVsdCB3aXRoIHNlbnNpdGl2ZSBkYXRhLiAgSW5wdXRzIGFuZCBFbmRwb2ludHNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9sb2FkRGF0YSgpIHtcclxuICAgIC8vIGluIGFnZW50LCBwcmVmZXIgVGVtcERpcmVjdG9yeSB0aGVuIHdvcmtGb2xkZXIuXHJcbiAgICAvLyBJbiBpbnRlcmFjdGl2ZSBkZXYgbW9kZSwgaXQgd29uJ3QgYmVcclxuICAgIHZhciBrZXlQYXRoID0gX2dldFZhcmlhYmxlKFwiYWdlbnQuVGVtcERpcmVjdG9yeVwiKSB8fCBfZ2V0VmFyaWFibGUoXCJhZ2VudC53b3JrRm9sZGVyXCIpIHx8IHByb2Nlc3MuY3dkKCk7XHJcbiAgICBleHBvcnRzLl92YXVsdCA9IG5ldyB2bS5WYXVsdChrZXlQYXRoKTtcclxuICAgIGV4cG9ydHMuX2tub3duVmFyaWFibGVNYXAgPSB7fTtcclxuICAgIF9kZWJ1ZygnbG9hZGluZyBpbnB1dHMgYW5kIGVuZHBvaW50cycpO1xyXG4gICAgdmFyIGxvYWRlZCA9IDA7XHJcbiAgICBmb3IgKHZhciBlbnZ2YXIgaW4gcHJvY2Vzcy5lbnYpIHtcclxuICAgICAgICBpZiAoX3N0YXJ0c1dpdGgoZW52dmFyLCAnSU5QVVRfJykgfHxcclxuICAgICAgICAgICAgX3N0YXJ0c1dpdGgoZW52dmFyLCAnRU5EUE9JTlRfQVVUSF8nKSB8fFxyXG4gICAgICAgICAgICBfc3RhcnRzV2l0aChlbnZ2YXIsICdTRUNVUkVGSUxFX1RJQ0tFVF8nKSB8fFxyXG4gICAgICAgICAgICBfc3RhcnRzV2l0aChlbnZ2YXIsICdTRUNSRVRfJykgfHxcclxuICAgICAgICAgICAgX3N0YXJ0c1dpdGgoZW52dmFyLCAnVlNUU19UQVNLVkFSSUFCTEVfJykpIHtcclxuICAgICAgICAgICAgLy8gUmVjb3JkIHRoZSBzZWNyZXQgdmFyaWFibGUgbWV0YWRhdGEuIFRoaXMgaXMgcmVxdWlyZWQgYnkgZ2V0VmFyaWFibGUgdG8ga25vdyB3aGV0aGVyXHJcbiAgICAgICAgICAgIC8vIHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmcm9tIHRoZSB2YXVsdC4gSW4gYSAyLjEwNC4xIGFnZW50IG9yIGhpZ2hlciwgdGhpcyBtZXRhZGF0YSB3aWxsXHJcbiAgICAgICAgICAgIC8vIGJlIG92ZXJ3cml0dGVuIHdoZW4gdGhlIFZTVFNfU0VDUkVUX1ZBUklBQkxFUyBlbnYgdmFyIGlzIHByb2Nlc3NlZCBiZWxvdy5cclxuICAgICAgICAgICAgaWYgKF9zdGFydHNXaXRoKGVudnZhciwgJ1NFQ1JFVF8nKSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHZhcmlhYmxlTmFtZSA9IGVudnZhci5zdWJzdHJpbmcoJ1NFQ1JFVF8nLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICBpZiAodmFyaWFibGVOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0ZWNobmljYWxseSBub3QgdGhlIHZhcmlhYmxlIG5hbWUgKGhhcyB1bmRlcnNjb3JlcyBpbnN0ZWFkIG9mIGRvdHMpLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBpdCdzIGdvb2QgZW5vdWdoIHRvIG1ha2UgZ2V0VmFyaWFibGUgd29yayBpbiBhIHByZS0yLjEwNC4xIGFnZW50IHdoZXJlXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIFZTVFNfU0VDUkVUX1ZBUklBQkxFUyBlbnYgdmFyIGlzIG5vdCBkZWZpbmVkLlxyXG4gICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuX2tub3duVmFyaWFibGVNYXBbX2dldFZhcmlhYmxlS2V5KHZhcmlhYmxlTmFtZSldID0geyBuYW1lOiB2YXJpYWJsZU5hbWUsIHNlY3JldDogdHJ1ZSB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHN0b3JlIHRoZSBzZWNyZXRcclxuICAgICAgICAgICAgdmFyIHZhbHVlID0gcHJvY2Vzcy5lbnZbZW52dmFyXTtcclxuICAgICAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICArK2xvYWRlZDtcclxuICAgICAgICAgICAgICAgIF9kZWJ1ZygnbG9hZGluZyAnICsgZW52dmFyKTtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuX3ZhdWx0LnN0b3JlU2VjcmV0KGVudnZhciwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIHByb2Nlc3MuZW52W2VudnZhcl07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBfZGVidWcoJ2xvYWRlZCAnICsgbG9hZGVkKTtcclxuICAgIC8vIHN0b3JlIHB1YmxpYyB2YXJpYWJsZSBtZXRhZGF0YVxyXG4gICAgdmFyIG5hbWVzO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICBuYW1lcyA9IEpTT04ucGFyc2UocHJvY2Vzcy5lbnZbJ1ZTVFNfUFVCTElDX1ZBUklBQkxFUyddIHx8ICdbXScpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIHBhcnNlIFZTVFNfUFVCTElDX1ZBUklBQkxFUyBhcyBKU09OLiAnICsgZXJyKTsgLy8gbWF5IG9jY3VyIGR1cmluZyBpbnRlcmFjdGl2ZSB0ZXN0aW5nXHJcbiAgICB9XHJcbiAgICBuYW1lcy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XHJcbiAgICAgICAgZXhwb3J0cy5fa25vd25WYXJpYWJsZU1hcFtfZ2V0VmFyaWFibGVLZXkobmFtZSldID0geyBuYW1lOiBuYW1lLCBzZWNyZXQ6IGZhbHNlIH07XHJcbiAgICB9KTtcclxuICAgIGRlbGV0ZSBwcm9jZXNzLmVudlsnVlNUU19QVUJMSUNfVkFSSUFCTEVTJ107XHJcbiAgICAvLyBzdG9yZSBzZWNyZXQgdmFyaWFibGUgbWV0YWRhdGFcclxuICAgIHRyeSB7XHJcbiAgICAgICAgbmFtZXMgPSBKU09OLnBhcnNlKHByb2Nlc3MuZW52WydWU1RTX1NFQ1JFVF9WQVJJQUJMRVMnXSB8fCAnW10nKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBwYXJzZSBWU1RTX1NFQ1JFVF9WQVJJQUJMRVMgYXMgSlNPTi4gJyArIGVycik7IC8vIG1heSBvY2N1ciBkdXJpbmcgaW50ZXJhY3RpdmUgdGVzdGluZ1xyXG4gICAgfVxyXG4gICAgbmFtZXMuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xyXG4gICAgICAgIGV4cG9ydHMuX2tub3duVmFyaWFibGVNYXBbX2dldFZhcmlhYmxlS2V5KG5hbWUpXSA9IHsgbmFtZTogbmFtZSwgc2VjcmV0OiB0cnVlIH07XHJcbiAgICB9KTtcclxuICAgIGRlbGV0ZSBwcm9jZXNzLmVudlsnVlNUU19TRUNSRVRfVkFSSUFCTEVTJ107XHJcbiAgICAvLyBhdm9pZCBsb2FkaW5nIHR3aWNlIChvdmVyd3JpdGVzIC50YXNra2V5KVxyXG4gICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9sb2FkZWQnXSA9IHRydWU7XHJcbn1cclxuZXhwb3J0cy5fbG9hZERhdGEgPSBfbG9hZERhdGE7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gSW50ZXJuYWwgcGF0aCBoZWxwZXJzLlxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9lbnN1cmVSb290ZWQocm9vdCwgcCkge1xyXG4gICAgaWYgKCFyb290KSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdlbnN1cmVSb290ZWQoKSBwYXJhbWV0ZXIgXCJyb290XCIgY2Fubm90IGJlIGVtcHR5Jyk7XHJcbiAgICB9XHJcbiAgICBpZiAoIXApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Vuc3VyZVJvb3RlZCgpIHBhcmFtZXRlciBcInBcIiBjYW5ub3QgYmUgZW1wdHknKTtcclxuICAgIH1cclxuICAgIGlmIChfaXNSb290ZWQocCkpIHtcclxuICAgICAgICByZXR1cm4gcDtcclxuICAgIH1cclxuICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgJiYgcm9vdC5tYXRjaCgvXltBLVpdOiQvaSkpIHsgLy8gZS5nLiBDOlxyXG4gICAgICAgIHJldHVybiByb290ICsgcDtcclxuICAgIH1cclxuICAgIC8vIGVuc3VyZSByb290IGVuZHMgd2l0aCBhIHNlcGFyYXRvclxyXG4gICAgaWYgKF9lbmRzV2l0aChyb290LCAnLycpIHx8IChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgJiYgX2VuZHNXaXRoKHJvb3QsICdcXFxcJykpKSB7XHJcbiAgICAgICAgLy8gcm9vdCBhbHJlYWR5IGVuZHMgd2l0aCBhIHNlcGFyYXRvclxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcm9vdCArPSBwYXRoLnNlcDsgLy8gYXBwZW5kIHNlcGFyYXRvclxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJvb3QgKyBwO1xyXG59XHJcbmV4cG9ydHMuX2Vuc3VyZVJvb3RlZCA9IF9lbnN1cmVSb290ZWQ7XHJcbi8qKlxyXG4gKiBEZXRlcm1pbmVzIHRoZSBwYXJlbnQgcGF0aCBhbmQgdHJpbXMgdHJhaWxpbmcgc2xhc2hlcyAod2hlbiBzYWZlKS4gUGF0aCBzZXBhcmF0b3JzIGFyZSBub3JtYWxpemVkXHJcbiAqIGluIHRoZSByZXN1bHQuIFRoaXMgZnVuY3Rpb24gd29ya3Mgc2ltaWxhciB0byB0aGUgLk5FVCBTeXN0ZW0uSU8uUGF0aC5HZXREaXJlY3RvcnlOYW1lKCkgbWV0aG9kLlxyXG4gKiBGb3IgZXhhbXBsZSwgQzpcXGhlbGxvXFx3b3JsZFxcIHJldHVybnMgQzpcXGhlbGxvXFx3b3JsZCAodHJhaWxpbmcgc2xhc2ggcmVtb3ZlZCkuIFJldHVybnMgZW1wdHkgd2hlblxyXG4gKiBubyBoaWdoZXIgZGlyZWN0b3J5IGNhbiBiZSBkZXRlcm1pbmVkLlxyXG4gKi9cclxuZnVuY3Rpb24gX2dldERpcmVjdG9yeU5hbWUocCkge1xyXG4gICAgLy8gc2hvcnQtY2lyY3VpdCBpZiBlbXB0eVxyXG4gICAgaWYgKCFwKSB7XHJcbiAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgfVxyXG4gICAgLy8gbm9ybWFsaXplIHNlcGFyYXRvcnNcclxuICAgIHAgPSBfbm9ybWFsaXplU2VwYXJhdG9ycyhwKTtcclxuICAgIC8vIG9uIFdpbmRvd3MsIHRoZSBnb2FsIG9mIHRoaXMgZnVuY3Rpb24gaXMgdG8gbWF0Y2ggdGhlIGJlaGF2aW9yIG9mXHJcbiAgICAvLyBbU3lzdGVtLklPLlBhdGhdOjpHZXREaXJlY3RvcnlOYW1lKCksIGUuZy5cclxuICAgIC8vICAgICAgQzovICAgICAgICAgICAgID0+XHJcbiAgICAvLyAgICAgIEM6L2hlbGxvICAgICAgICA9PiBDOlxcXHJcbiAgICAvLyAgICAgIEM6L2hlbGxvLyAgICAgICA9PiBDOlxcaGVsbG9cclxuICAgIC8vICAgICAgQzovaGVsbG8vd29ybGQgID0+IEM6XFxoZWxsb1xyXG4gICAgLy8gICAgICBDOi9oZWxsby93b3JsZC8gPT4gQzpcXGhlbGxvXFx3b3JsZFxyXG4gICAgLy8gICAgICBDOiAgICAgICAgICAgICAgPT5cclxuICAgIC8vICAgICAgQzpoZWxsbyAgICAgICAgID0+IEM6XHJcbiAgICAvLyAgICAgIEM6aGVsbG8vICAgICAgICA9PiBDOmhlbGxvXHJcbiAgICAvLyAgICAgIC8gICAgICAgICAgICAgICA9PlxyXG4gICAgLy8gICAgICAvaGVsbG8gICAgICAgICAgPT4gXFxcclxuICAgIC8vICAgICAgL2hlbGxvLyAgICAgICAgID0+IFxcaGVsbG9cclxuICAgIC8vICAgICAgLy9oZWxsbyAgICAgICAgID0+XHJcbiAgICAvLyAgICAgIC8vaGVsbG8vICAgICAgICA9PlxyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkICAgPT5cclxuICAgIC8vICAgICAgLy9oZWxsby93b3JsZC8gID0+IFxcXFxoZWxsb1xcd29ybGRcclxuICAgIC8vXHJcbiAgICAvLyB1bmZvcnR1bmF0ZWx5LCBwYXRoLmRpcm5hbWUoKSBjYW4ndCBzaW1wbHkgYmUgdXNlZC4gZm9yIGV4YW1wbGUsIG9uIFdpbmRvd3NcclxuICAgIC8vIGl0IHlpZWxkcyBkaWZmZXJlbnQgcmVzdWx0cyBmcm9tIFBhdGguR2V0RGlyZWN0b3J5TmFtZTpcclxuICAgIC8vICAgICAgQzovICAgICAgICAgICAgID0+IEM6L1xyXG4gICAgLy8gICAgICBDOi9oZWxsbyAgICAgICAgPT4gQzovXHJcbiAgICAvLyAgICAgIEM6L2hlbGxvLyAgICAgICA9PiBDOi9cclxuICAgIC8vICAgICAgQzovaGVsbG8vd29ybGQgID0+IEM6L2hlbGxvXHJcbiAgICAvLyAgICAgIEM6L2hlbGxvL3dvcmxkLyA9PiBDOi9oZWxsb1xyXG4gICAgLy8gICAgICBDOiAgICAgICAgICAgICAgPT4gQzpcclxuICAgIC8vICAgICAgQzpoZWxsbyAgICAgICAgID0+IEM6XHJcbiAgICAvLyAgICAgIEM6aGVsbG8vICAgICAgICA9PiBDOlxyXG4gICAgLy8gICAgICAvICAgICAgICAgICAgICAgPT4gL1xyXG4gICAgLy8gICAgICAvaGVsbG8gICAgICAgICAgPT4gL1xyXG4gICAgLy8gICAgICAvaGVsbG8vICAgICAgICAgPT4gL1xyXG4gICAgLy8gICAgICAvL2hlbGxvICAgICAgICAgPT4gL1xyXG4gICAgLy8gICAgICAvL2hlbGxvLyAgICAgICAgPT4gL1xyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkICAgPT4gLy9oZWxsby93b3JsZFxyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkLyAgPT4gLy9oZWxsby93b3JsZC9cclxuICAgIC8vICAgICAgLy9oZWxsby93b3JsZC9hZ2FpbiA9PiAvL2hlbGxvL3dvcmxkL1xyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkL2FnYWluLyA9PiAvL2hlbGxvL3dvcmxkL1xyXG4gICAgLy8gICAgICAvL2hlbGxvL3dvcmxkL2FnYWluL2FnYWluID0+IC8vaGVsbG8vd29ybGQvYWdhaW5cclxuICAgIC8vICAgICAgLy9oZWxsby93b3JsZC9hZ2Fpbi9hZ2Fpbi8gPT4gLy9oZWxsby93b3JsZC9hZ2FpblxyXG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgIGlmICgvXltBLVpdOlxcXFw/W15cXFxcXSskL2kudGVzdChwKSkgeyAvLyBlLmcuIEM6XFxoZWxsbyBvciBDOmhlbGxvXHJcbiAgICAgICAgICAgIHJldHVybiBwLmNoYXJBdCgyKSA9PSAnXFxcXCcgPyBwLnN1YnN0cmluZygwLCAzKSA6IHAuc3Vic3RyaW5nKDAsIDIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICgvXltBLVpdOlxcXFw/JC9pLnRlc3QocCkpIHsgLy8gZS5nLiBDOlxcIG9yIEM6XHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGxhc3RTbGFzaEluZGV4ID0gcC5sYXN0SW5kZXhPZignXFxcXCcpO1xyXG4gICAgICAgIGlmIChsYXN0U2xhc2hJbmRleCA8IDApIHsgLy8gZmlsZSBuYW1lIG9ubHlcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChwID09ICdcXFxcJykgeyAvLyByZWxhdGl2ZSByb290XHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAobGFzdFNsYXNoSW5kZXggPT0gMCkgeyAvLyBlLmcuIFxcXFxoZWxsb1xyXG4gICAgICAgICAgICByZXR1cm4gJ1xcXFwnO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICgvXlxcXFxcXFxcW15cXFxcXSsoXFxcXFteXFxcXF0qKT8kLy50ZXN0KHApKSB7IC8vIFVOQyByb290LCBlLmcuIFxcXFxoZWxsbyBvciBcXFxcaGVsbG9cXCBvciBcXFxcaGVsbG9cXHdvcmxkXHJcbiAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHAuc3Vic3RyaW5nKDAsIGxhc3RTbGFzaEluZGV4KTsgLy8gZS5nLiBoZWxsb1xcd29ybGQgPT4gaGVsbG8gb3IgaGVsbG9cXHdvcmxkXFwgPT4gaGVsbG9cXHdvcmxkXHJcbiAgICAgICAgLy8gbm90ZSwgdGhpcyBtZWFucyB0cmFpbGluZyBzbGFzaGVzIGZvciBub24tcm9vdCBkaXJlY3Rvcmllc1xyXG4gICAgICAgIC8vIChpLmUuIG5vdCBDOlxcLCBcXCwgb3IgXFxcXHVuY1xcKSB3aWxsIHNpbXBseSBiZSByZW1vdmVkLlxyXG4gICAgfVxyXG4gICAgLy8gT1NYL0xpbnV4XHJcbiAgICBpZiAocC5pbmRleE9mKCcvJykgPCAwKSB7IC8vIGZpbGUgbmFtZSBvbmx5XHJcbiAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAocCA9PSAnLycpIHtcclxuICAgICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChfZW5kc1dpdGgocCwgJy8nKSkge1xyXG4gICAgICAgIHJldHVybiBwLnN1YnN0cmluZygwLCBwLmxlbmd0aCAtIDEpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHBhdGguZGlybmFtZShwKTtcclxufVxyXG5leHBvcnRzLl9nZXREaXJlY3RvcnlOYW1lID0gX2dldERpcmVjdG9yeU5hbWU7XHJcbi8qKlxyXG4gKiBPbiBPU1gvTGludXgsIHRydWUgaWYgcGF0aCBzdGFydHMgd2l0aCAnLycuIE9uIFdpbmRvd3MsIHRydWUgZm9yIHBhdGhzIGxpa2U6XHJcbiAqIFxcLCBcXGhlbGxvLCBcXFxcaGVsbG9cXHNoYXJlLCBDOiwgYW5kIEM6XFxoZWxsbyAoYW5kIGNvcnJlc3BvbmRpbmcgYWx0ZXJuYXRlIHNlcGFyYXRvciBjYXNlcykuXHJcbiAqL1xyXG5mdW5jdGlvbiBfaXNSb290ZWQocCkge1xyXG4gICAgcCA9IF9ub3JtYWxpemVTZXBhcmF0b3JzKHApO1xyXG4gICAgaWYgKCFwKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpc1Jvb3RlZCgpIHBhcmFtZXRlciBcInBcIiBjYW5ub3QgYmUgZW1wdHknKTtcclxuICAgIH1cclxuICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpIHtcclxuICAgICAgICByZXR1cm4gX3N0YXJ0c1dpdGgocCwgJ1xcXFwnKSB8fCAvLyBlLmcuIFxcIG9yIFxcaGVsbG8gb3IgXFxcXGhlbGxvXHJcbiAgICAgICAgICAgIC9eW0EtWl06L2kudGVzdChwKTsgLy8gZS5nLiBDOiBvciBDOlxcaGVsbG9cclxuICAgIH1cclxuICAgIHJldHVybiBfc3RhcnRzV2l0aChwLCAnLycpOyAvLyBlLmcuIC9oZWxsb1xyXG59XHJcbmV4cG9ydHMuX2lzUm9vdGVkID0gX2lzUm9vdGVkO1xyXG5mdW5jdGlvbiBfbm9ybWFsaXplU2VwYXJhdG9ycyhwKSB7XHJcbiAgICBwID0gcCB8fCAnJztcclxuICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpIHtcclxuICAgICAgICAvLyBjb252ZXJ0IHNsYXNoZXMgb24gV2luZG93c1xyXG4gICAgICAgIHAgPSBwLnJlcGxhY2UoL1xcLy9nLCAnXFxcXCcpO1xyXG4gICAgICAgIC8vIHJlbW92ZSByZWR1bmRhbnQgc2xhc2hlc1xyXG4gICAgICAgIHZhciBpc1VuYyA9IC9eXFxcXFxcXFwrW15cXFxcXS8udGVzdChwKTsgLy8gZS5nLiBcXFxcaGVsbG9cclxuICAgICAgICByZXR1cm4gKGlzVW5jID8gJ1xcXFwnIDogJycpICsgcC5yZXBsYWNlKC9cXFxcXFxcXCsvZywgJ1xcXFwnKTsgLy8gcHJlc2VydmUgbGVhZGluZyAvLyBmb3IgVU5DXHJcbiAgICB9XHJcbiAgICAvLyByZW1vdmUgcmVkdW5kYW50IHNsYXNoZXNcclxuICAgIHJldHVybiBwLnJlcGxhY2UoL1xcL1xcLysvZywgJy8nKTtcclxufVxyXG5leHBvcnRzLl9ub3JtYWxpemVTZXBhcmF0b3JzID0gX25vcm1hbGl6ZVNlcGFyYXRvcnM7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gRXhwb3NlIHByb3h5IGluZm9ybWF0aW9uIHRvIHZzdHMtbm9kZS1hcGlcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5mdW5jdGlvbiBfZXhwb3NlUHJveHlTZXR0aW5ncygpIHtcclxuICAgIHZhciBwcm94eVVybCA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuUHJveHlVcmwnKTtcclxuICAgIGlmIChwcm94eVVybCAmJiBwcm94eVVybC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgdmFyIHByb3h5VXNlcm5hbWUgPSBfZ2V0VmFyaWFibGUoJ0FnZW50LlByb3h5VXNlcm5hbWUnKTtcclxuICAgICAgICB2YXIgcHJveHlQYXNzd29yZCA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuUHJveHlQYXNzd29yZCcpO1xyXG4gICAgICAgIHZhciBwcm94eUJ5cGFzc0hvc3RzSnNvbiA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuUHJveHlCeXBhc3NMaXN0Jyk7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9wcm94eV91cmwnXSA9IHByb3h5VXJsO1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfcHJveHlfdXNlcm5hbWUnXSA9IHByb3h5VXNlcm5hbWU7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9wcm94eV9ieXBhc3MnXSA9IHByb3h5QnlwYXNzSG9zdHNKc29uO1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfcHJveHlfcGFzc3dvcmQnXSA9IF9leHBvc2VUYXNrTGliU2VjcmV0KCdwcm94eScsIHByb3h5UGFzc3dvcmQgfHwgJycpO1xyXG4gICAgICAgIF9kZWJ1ZygnZXhwb3NlIGFnZW50IHByb3h5IGNvbmZpZ3VyYXRpb24uJyk7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9wcm94eSddID0gdHJ1ZTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLl9leHBvc2VQcm94eVNldHRpbmdzID0gX2V4cG9zZVByb3h5U2V0dGluZ3M7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gRXhwb3NlIGNlcnRpZmljYXRlIGluZm9ybWF0aW9uIHRvIHZzdHMtbm9kZS1hcGlcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5mdW5jdGlvbiBfZXhwb3NlQ2VydFNldHRpbmdzKCkge1xyXG4gICAgdmFyIGNhID0gX2dldFZhcmlhYmxlKCdBZ2VudC5DQUluZm8nKTtcclxuICAgIGlmIChjYSkge1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfY2VydF9jYSddID0gY2E7XHJcbiAgICB9XHJcbiAgICB2YXIgY2xpZW50Q2VydCA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuQ2xpZW50Q2VydCcpO1xyXG4gICAgaWYgKGNsaWVudENlcnQpIHtcclxuICAgICAgICB2YXIgY2xpZW50Q2VydEtleSA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuQ2xpZW50Q2VydEtleScpO1xyXG4gICAgICAgIHZhciBjbGllbnRDZXJ0QXJjaGl2ZSA9IF9nZXRWYXJpYWJsZSgnQWdlbnQuQ2xpZW50Q2VydEFyY2hpdmUnKTtcclxuICAgICAgICB2YXIgY2xpZW50Q2VydFBhc3N3b3JkID0gX2dldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0UGFzc3dvcmQnKTtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX2NlcnRfY2xpZW50Y2VydCddID0gY2xpZW50Q2VydDtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX2NlcnRfa2V5J10gPSBjbGllbnRDZXJ0S2V5O1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfY2VydF9hcmNoaXZlJ10gPSBjbGllbnRDZXJ0QXJjaGl2ZTtcclxuICAgICAgICBnbG9iYWxbJ192c3RzX3Rhc2tfbGliX2NlcnRfcGFzc3BocmFzZSddID0gX2V4cG9zZVRhc2tMaWJTZWNyZXQoJ2NlcnQnLCBjbGllbnRDZXJ0UGFzc3dvcmQgfHwgJycpO1xyXG4gICAgfVxyXG4gICAgaWYgKGNhIHx8IGNsaWVudENlcnQpIHtcclxuICAgICAgICBfZGVidWcoJ2V4cG9zZSBhZ2VudCBjZXJ0aWZpY2F0ZSBjb25maWd1cmF0aW9uLicpO1xyXG4gICAgICAgIGdsb2JhbFsnX3ZzdHNfdGFza19saWJfY2VydCddID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHZhciBza2lwQ2VydFZhbGlkYXRpb24gPSBfZ2V0VmFyaWFibGUoJ0FnZW50LlNraXBDZXJ0VmFsaWRhdGlvbicpIHx8ICdmYWxzZSc7XHJcbiAgICBpZiAoc2tpcENlcnRWYWxpZGF0aW9uKSB7XHJcbiAgICAgICAgZ2xvYmFsWydfdnN0c190YXNrX2xpYl9za2lwX2NlcnRfdmFsaWRhdGlvbiddID0gc2tpcENlcnRWYWxpZGF0aW9uLnRvVXBwZXJDYXNlKCkgPT09ICdUUlVFJztcclxuICAgIH1cclxufVxyXG5leHBvcnRzLl9leHBvc2VDZXJ0U2V0dGluZ3MgPSBfZXhwb3NlQ2VydFNldHRpbmdzO1xyXG4vLyBXZSBzdG9yZSB0aGUgZW5jcnlwdGlvbiBrZXkgb24gZGlzayBhbmQgaG9sZCB0aGUgZW5jcnlwdGVkIGNvbnRlbnQgYW5kIGtleSBmaWxlIGluIG1lbW9yeVxyXG4vLyByZXR1cm4gYmFzZTY0ZW5jb2RlZDxrZXlGaWxlUGF0aD46YmFzZTY0ZW5jb2RlZDxlbmNyeXB0ZWRDb250ZW50PlxyXG4vLyBkb3duc3RyZWFtIHZzdHMtbm9kZS1hcGkgd2lsbCByZXRyaWV2ZSB0aGUgc2VjcmV0IGxhdGVyXHJcbmZ1bmN0aW9uIF9leHBvc2VUYXNrTGliU2VjcmV0KGtleUZpbGUsIHNlY3JldCkge1xyXG4gICAgaWYgKHNlY3JldCkge1xyXG4gICAgICAgIHZhciBlbmNyeXB0S2V5ID0gY3J5cHRvLnJhbmRvbUJ5dGVzKDI1Nik7XHJcbiAgICAgICAgdmFyIGNpcGhlciA9IGNyeXB0by5jcmVhdGVDaXBoZXIoXCJhZXMtMjU2LWN0clwiLCBlbmNyeXB0S2V5KTtcclxuICAgICAgICB2YXIgZW5jcnlwdGVkQ29udGVudCA9IGNpcGhlci51cGRhdGUoc2VjcmV0LCBcInV0ZjhcIiwgXCJoZXhcIik7XHJcbiAgICAgICAgZW5jcnlwdGVkQ29udGVudCArPSBjaXBoZXIuZmluYWwoXCJoZXhcIik7XHJcbiAgICAgICAgdmFyIHN0b3JhZ2VGaWxlID0gcGF0aC5qb2luKF9nZXRWYXJpYWJsZSgnQWdlbnQuVGVtcERpcmVjdG9yeScpIHx8IF9nZXRWYXJpYWJsZShcImFnZW50LndvcmtGb2xkZXJcIikgfHwgcHJvY2Vzcy5jd2QoKSwga2V5RmlsZSk7XHJcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhzdG9yYWdlRmlsZSwgZW5jcnlwdEtleS50b1N0cmluZygnYmFzZTY0JyksIHsgZW5jb2Rpbmc6ICd1dGY4JyB9KTtcclxuICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihzdG9yYWdlRmlsZSkudG9TdHJpbmcoJ2Jhc2U2NCcpICsgJzonICsgbmV3IEJ1ZmZlcihlbmNyeXB0ZWRDb250ZW50KS50b1N0cmluZygnYmFzZTY0Jyk7XHJcbiAgICB9XHJcbn1cclxuIiwiLyoqXG4gKiBDb252ZXJ0IGFycmF5IG9mIDE2IGJ5dGUgdmFsdWVzIHRvIFVVSUQgc3RyaW5nIGZvcm1hdCBvZiB0aGUgZm9ybTpcbiAqIFhYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWFxuICovXG52YXIgYnl0ZVRvSGV4ID0gW107XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gIGJ5dGVUb0hleFtpXSA9IChpICsgMHgxMDApLnRvU3RyaW5nKDE2KS5zdWJzdHIoMSk7XG59XG5cbmZ1bmN0aW9uIGJ5dGVzVG9VdWlkKGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gb2Zmc2V0IHx8IDA7XG4gIHZhciBidGggPSBieXRlVG9IZXg7XG4gIC8vIGpvaW4gdXNlZCB0byBmaXggbWVtb3J5IGlzc3VlIGNhdXNlZCBieSBjb25jYXRlbmF0aW9uOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMTc1I2M0XG4gIHJldHVybiAoW1xuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dXG4gIF0pLmpvaW4oJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJ5dGVzVG9VdWlkO1xuIiwiLy8gVW5pcXVlIElEIGNyZWF0aW9uIHJlcXVpcmVzIGEgaGlnaCBxdWFsaXR5IHJhbmRvbSAjIGdlbmVyYXRvci4gIEluIG5vZGUuanNcbi8vIHRoaXMgaXMgcHJldHR5IHN0cmFpZ2h0LWZvcndhcmQgLSB3ZSB1c2UgdGhlIGNyeXB0byBBUEkuXG5cbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBub2RlUk5HKCkge1xuICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKDE2KTtcbn07XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuZXhwb3J0cy51cGRhdGVSZWxlYXNlTmFtZSA9IGV4cG9ydHMuYWRkQnVpbGRUYWcgPSBleHBvcnRzLnVwZGF0ZUJ1aWxkTnVtYmVyID0gZXhwb3J0cy51cGxvYWRCdWlsZExvZyA9IGV4cG9ydHMuYXNzb2NpYXRlQXJ0aWZhY3QgPSBleHBvcnRzLnVwbG9hZEFydGlmYWN0ID0gZXhwb3J0cy5sb2dJc3N1ZSA9IGV4cG9ydHMubG9nRGV0YWlsID0gZXhwb3J0cy5zZXRQcm9ncmVzcyA9IGV4cG9ydHMuc2V0RW5kcG9pbnQgPSBleHBvcnRzLmFkZEF0dGFjaG1lbnQgPSBleHBvcnRzLnVwbG9hZFN1bW1hcnkgPSBleHBvcnRzLnByZXBlbmRQYXRoID0gZXhwb3J0cy51cGxvYWRGaWxlID0gZXhwb3J0cy5Db2RlQ292ZXJhZ2VFbmFibGVyID0gZXhwb3J0cy5Db2RlQ292ZXJhZ2VQdWJsaXNoZXIgPSBleHBvcnRzLlRlc3RQdWJsaXNoZXIgPSBleHBvcnRzLmdldEh0dHBDZXJ0Q29uZmlndXJhdGlvbiA9IGV4cG9ydHMuZ2V0SHR0cFByb3h5Q29uZmlndXJhdGlvbiA9IGV4cG9ydHMuZmluZE1hdGNoID0gZXhwb3J0cy5maWx0ZXIgPSBleHBvcnRzLm1hdGNoID0gZXhwb3J0cy50b29sID0gZXhwb3J0cy5leGVjU3luYyA9IGV4cG9ydHMuZXhlYyA9IGV4cG9ydHMucm1SRiA9IGV4cG9ydHMubGVnYWN5RmluZEZpbGVzID0gZXhwb3J0cy5maW5kID0gZXhwb3J0cy5tdiA9IGV4cG9ydHMuY3AgPSBleHBvcnRzLmxzID0gZXhwb3J0cy53aGljaCA9IGV4cG9ydHMucmVzb2x2ZSA9IGV4cG9ydHMubWtkaXJQID0gZXhwb3J0cy5wb3BkID0gZXhwb3J0cy5wdXNoZCA9IGV4cG9ydHMuY2QgPSBleHBvcnRzLmNoZWNrUGF0aCA9IGV4cG9ydHMuY3dkID0gZXhwb3J0cy5nZXRQbGF0Zm9ybSA9IGV4cG9ydHMub3NUeXBlID0gZXhwb3J0cy53cml0ZUZpbGUgPSBleHBvcnRzLmV4aXN0ID0gZXhwb3J0cy5zdGF0cyA9IGV4cG9ydHMuZGVidWcgPSBleHBvcnRzLmVycm9yID0gZXhwb3J0cy53YXJuaW5nID0gZXhwb3J0cy5jb21tYW5kID0gZXhwb3J0cy5zZXRUYXNrVmFyaWFibGUgPSBleHBvcnRzLmdldFRhc2tWYXJpYWJsZSA9IGV4cG9ydHMuZ2V0U2VjdXJlRmlsZVRpY2tldCA9IGV4cG9ydHMuZ2V0U2VjdXJlRmlsZU5hbWUgPSBleHBvcnRzLmdldEVuZHBvaW50QXV0aG9yaXphdGlvbiA9IGV4cG9ydHMuZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uUGFyYW1ldGVyID0gZXhwb3J0cy5nZXRFbmRwb2ludEF1dGhvcml6YXRpb25TY2hlbWUgPSBleHBvcnRzLmdldEVuZHBvaW50RGF0YVBhcmFtZXRlciA9IGV4cG9ydHMuZ2V0RW5kcG9pbnRVcmwgPSBleHBvcnRzLmdldFBhdGhJbnB1dCA9IGV4cG9ydHMuZmlsZVBhdGhTdXBwbGllZCA9IGV4cG9ydHMuZ2V0RGVsaW1pdGVkSW5wdXQgPSBleHBvcnRzLmdldEJvb2xJbnB1dCA9IGV4cG9ydHMuZ2V0SW5wdXQgPSBleHBvcnRzLnNldFNlY3JldCA9IGV4cG9ydHMuc2V0VmFyaWFibGUgPSBleHBvcnRzLmdldFZhcmlhYmxlcyA9IGV4cG9ydHMuYXNzZXJ0QWdlbnQgPSBleHBvcnRzLmdldFZhcmlhYmxlID0gZXhwb3J0cy5sb2MgPSBleHBvcnRzLnNldFJlc291cmNlUGF0aCA9IGV4cG9ydHMuc2V0UmVzdWx0ID0gZXhwb3J0cy5zZXRFcnJTdHJlYW0gPSBleHBvcnRzLnNldFN0ZFN0cmVhbSA9IGV4cG9ydHMuUGxhdGZvcm0gPSBleHBvcnRzLkZpZWxkVHlwZSA9IGV4cG9ydHMuQXJ0aWZhY3RUeXBlID0gZXhwb3J0cy5Jc3N1ZVR5cGUgPSBleHBvcnRzLlRhc2tTdGF0ZSA9IGV4cG9ydHMuVGFza1Jlc3VsdCA9IHZvaWQgMDtcclxudmFyIHNoZWxsID0gcmVxdWlyZShcInNoZWxsanNcIik7XHJcbnZhciBjaGlsZFByb2Nlc3MgPSByZXF1aXJlKFwiY2hpbGRfcHJvY2Vzc1wiKTtcclxudmFyIGZzID0gcmVxdWlyZShcImZzXCIpO1xyXG52YXIgcGF0aCA9IHJlcXVpcmUoXCJwYXRoXCIpO1xyXG52YXIgb3MgPSByZXF1aXJlKFwib3NcIik7XHJcbnZhciBtaW5pbWF0Y2ggPSByZXF1aXJlKFwibWluaW1hdGNoXCIpO1xyXG52YXIgaW0gPSByZXF1aXJlKFwiLi9pbnRlcm5hbFwiKTtcclxudmFyIHRjbSA9IHJlcXVpcmUoXCIuL3Rhc2tjb21tYW5kXCIpO1xyXG52YXIgdHJtID0gcmVxdWlyZShcIi4vdG9vbHJ1bm5lclwiKTtcclxudmFyIHNlbXZlciA9IHJlcXVpcmUoXCJzZW12ZXJcIik7XHJcbnZhciBUYXNrUmVzdWx0O1xyXG4oZnVuY3Rpb24gKFRhc2tSZXN1bHQpIHtcclxuICAgIFRhc2tSZXN1bHRbVGFza1Jlc3VsdFtcIlN1Y2NlZWRlZFwiXSA9IDBdID0gXCJTdWNjZWVkZWRcIjtcclxuICAgIFRhc2tSZXN1bHRbVGFza1Jlc3VsdFtcIlN1Y2NlZWRlZFdpdGhJc3N1ZXNcIl0gPSAxXSA9IFwiU3VjY2VlZGVkV2l0aElzc3Vlc1wiO1xyXG4gICAgVGFza1Jlc3VsdFtUYXNrUmVzdWx0W1wiRmFpbGVkXCJdID0gMl0gPSBcIkZhaWxlZFwiO1xyXG4gICAgVGFza1Jlc3VsdFtUYXNrUmVzdWx0W1wiQ2FuY2VsbGVkXCJdID0gM10gPSBcIkNhbmNlbGxlZFwiO1xyXG4gICAgVGFza1Jlc3VsdFtUYXNrUmVzdWx0W1wiU2tpcHBlZFwiXSA9IDRdID0gXCJTa2lwcGVkXCI7XHJcbn0pKFRhc2tSZXN1bHQgPSBleHBvcnRzLlRhc2tSZXN1bHQgfHwgKGV4cG9ydHMuVGFza1Jlc3VsdCA9IHt9KSk7XHJcbnZhciBUYXNrU3RhdGU7XHJcbihmdW5jdGlvbiAoVGFza1N0YXRlKSB7XHJcbiAgICBUYXNrU3RhdGVbVGFza1N0YXRlW1wiVW5rbm93blwiXSA9IDBdID0gXCJVbmtub3duXCI7XHJcbiAgICBUYXNrU3RhdGVbVGFza1N0YXRlW1wiSW5pdGlhbGl6ZWRcIl0gPSAxXSA9IFwiSW5pdGlhbGl6ZWRcIjtcclxuICAgIFRhc2tTdGF0ZVtUYXNrU3RhdGVbXCJJblByb2dyZXNzXCJdID0gMl0gPSBcIkluUHJvZ3Jlc3NcIjtcclxuICAgIFRhc2tTdGF0ZVtUYXNrU3RhdGVbXCJDb21wbGV0ZWRcIl0gPSAzXSA9IFwiQ29tcGxldGVkXCI7XHJcbn0pKFRhc2tTdGF0ZSA9IGV4cG9ydHMuVGFza1N0YXRlIHx8IChleHBvcnRzLlRhc2tTdGF0ZSA9IHt9KSk7XHJcbnZhciBJc3N1ZVR5cGU7XHJcbihmdW5jdGlvbiAoSXNzdWVUeXBlKSB7XHJcbiAgICBJc3N1ZVR5cGVbSXNzdWVUeXBlW1wiRXJyb3JcIl0gPSAwXSA9IFwiRXJyb3JcIjtcclxuICAgIElzc3VlVHlwZVtJc3N1ZVR5cGVbXCJXYXJuaW5nXCJdID0gMV0gPSBcIldhcm5pbmdcIjtcclxufSkoSXNzdWVUeXBlID0gZXhwb3J0cy5Jc3N1ZVR5cGUgfHwgKGV4cG9ydHMuSXNzdWVUeXBlID0ge30pKTtcclxudmFyIEFydGlmYWN0VHlwZTtcclxuKGZ1bmN0aW9uIChBcnRpZmFjdFR5cGUpIHtcclxuICAgIEFydGlmYWN0VHlwZVtBcnRpZmFjdFR5cGVbXCJDb250YWluZXJcIl0gPSAwXSA9IFwiQ29udGFpbmVyXCI7XHJcbiAgICBBcnRpZmFjdFR5cGVbQXJ0aWZhY3RUeXBlW1wiRmlsZVBhdGhcIl0gPSAxXSA9IFwiRmlsZVBhdGhcIjtcclxuICAgIEFydGlmYWN0VHlwZVtBcnRpZmFjdFR5cGVbXCJWZXJzaW9uQ29udHJvbFwiXSA9IDJdID0gXCJWZXJzaW9uQ29udHJvbFwiO1xyXG4gICAgQXJ0aWZhY3RUeXBlW0FydGlmYWN0VHlwZVtcIkdpdFJlZlwiXSA9IDNdID0gXCJHaXRSZWZcIjtcclxuICAgIEFydGlmYWN0VHlwZVtBcnRpZmFjdFR5cGVbXCJUZnZjTGFiZWxcIl0gPSA0XSA9IFwiVGZ2Y0xhYmVsXCI7XHJcbn0pKEFydGlmYWN0VHlwZSA9IGV4cG9ydHMuQXJ0aWZhY3RUeXBlIHx8IChleHBvcnRzLkFydGlmYWN0VHlwZSA9IHt9KSk7XHJcbnZhciBGaWVsZFR5cGU7XHJcbihmdW5jdGlvbiAoRmllbGRUeXBlKSB7XHJcbiAgICBGaWVsZFR5cGVbRmllbGRUeXBlW1wiQXV0aFBhcmFtZXRlclwiXSA9IDBdID0gXCJBdXRoUGFyYW1ldGVyXCI7XHJcbiAgICBGaWVsZFR5cGVbRmllbGRUeXBlW1wiRGF0YVBhcmFtZXRlclwiXSA9IDFdID0gXCJEYXRhUGFyYW1ldGVyXCI7XHJcbiAgICBGaWVsZFR5cGVbRmllbGRUeXBlW1wiVXJsXCJdID0gMl0gPSBcIlVybFwiO1xyXG59KShGaWVsZFR5cGUgPSBleHBvcnRzLkZpZWxkVHlwZSB8fCAoZXhwb3J0cy5GaWVsZFR5cGUgPSB7fSkpO1xyXG4vKiogUGxhdGZvcm1zIHN1cHBvcnRlZCBieSBvdXIgYnVpbGQgYWdlbnQgKi9cclxudmFyIFBsYXRmb3JtO1xyXG4oZnVuY3Rpb24gKFBsYXRmb3JtKSB7XHJcbiAgICBQbGF0Zm9ybVtQbGF0Zm9ybVtcIldpbmRvd3NcIl0gPSAwXSA9IFwiV2luZG93c1wiO1xyXG4gICAgUGxhdGZvcm1bUGxhdGZvcm1bXCJNYWNPU1wiXSA9IDFdID0gXCJNYWNPU1wiO1xyXG4gICAgUGxhdGZvcm1bUGxhdGZvcm1bXCJMaW51eFwiXSA9IDJdID0gXCJMaW51eFwiO1xyXG59KShQbGF0Zm9ybSA9IGV4cG9ydHMuUGxhdGZvcm0gfHwgKGV4cG9ydHMuUGxhdGZvcm0gPSB7fSkpO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIEdlbmVyYWwgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmV4cG9ydHMuc2V0U3RkU3RyZWFtID0gaW0uX3NldFN0ZFN0cmVhbTtcclxuZXhwb3J0cy5zZXRFcnJTdHJlYW0gPSBpbS5fc2V0RXJyU3RyZWFtO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFJlc3VsdHNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKipcclxuICogU2V0cyB0aGUgcmVzdWx0IG9mIHRoZSB0YXNrLlxyXG4gKiBFeGVjdXRpb24gd2lsbCBjb250aW51ZS5cclxuICogSWYgbm90IHNldCwgdGFzayB3aWxsIGJlIFN1Y2NlZWRlZC5cclxuICogSWYgbXVsdGlwbGUgY2FsbHMgYXJlIG1hZGUgdG8gc2V0UmVzdWx0IHRoZSBtb3N0IHBlc3NpbWlzdGljIGNhbGwgd2lucyAoRmFpbGVkKSByZWdhcmRsZXNzIG9mIHRoZSBvcmRlciBvZiBjYWxscy5cclxuICpcclxuICogQHBhcmFtIHJlc3VsdCAgICBUYXNrUmVzdWx0IGVudW0gb2YgU3VjY2VlZGVkLCBTdWNjZWVkZWRXaXRoSXNzdWVzLCBGYWlsZWQsIENhbmNlbGxlZCBvciBTa2lwcGVkLlxyXG4gKiBAcGFyYW0gbWVzc2FnZSAgIEEgbWVzc2FnZSB3aGljaCB3aWxsIGJlIGxvZ2dlZCBhcyBhbiBlcnJvciBpc3N1ZSBpZiB0aGUgcmVzdWx0IGlzIEZhaWxlZC5cclxuICogQHBhcmFtIGRvbmUgICAgICBPcHRpb25hbC4gSW5zdHJ1Y3RzIHRoZSBhZ2VudCB0aGUgdGFzayBpcyBkb25lLiBUaGlzIGlzIGhlbHBmdWwgd2hlbiBjaGlsZCBwcm9jZXNzZXNcclxuICogICAgICAgICAgICAgICAgICBtYXkgc3RpbGwgYmUgcnVubmluZyBhbmQgcHJldmVudCBub2RlIGZyb20gZnVsbHkgZXhpdGluZy4gVGhpcyBhcmd1bWVudCBpcyBzdXBwb3J0ZWRcclxuICogICAgICAgICAgICAgICAgICBmcm9tIGFnZW50IHZlcnNpb24gMi4xNDIuMCBvciBoaWdoZXIgKG90aGVyd2lzZSB3aWxsIG5vLW9wKS5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBzZXRSZXN1bHQocmVzdWx0LCBtZXNzYWdlLCBkb25lKSB7XHJcbiAgICBleHBvcnRzLmRlYnVnKCd0YXNrIHJlc3VsdDogJyArIFRhc2tSZXN1bHRbcmVzdWx0XSk7XHJcbiAgICAvLyBhZGQgYW4gZXJyb3IgaXNzdWVcclxuICAgIGlmIChyZXN1bHQgPT0gVGFza1Jlc3VsdC5GYWlsZWQgJiYgbWVzc2FnZSkge1xyXG4gICAgICAgIGV4cG9ydHMuZXJyb3IobWVzc2FnZSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChyZXN1bHQgPT0gVGFza1Jlc3VsdC5TdWNjZWVkZWRXaXRoSXNzdWVzICYmIG1lc3NhZ2UpIHtcclxuICAgICAgICBleHBvcnRzLndhcm5pbmcobWVzc2FnZSk7XHJcbiAgICB9XHJcbiAgICAvLyB0YXNrLmNvbXBsZXRlXHJcbiAgICB2YXIgcHJvcGVydGllcyA9IHsgJ3Jlc3VsdCc6IFRhc2tSZXN1bHRbcmVzdWx0XSB9O1xyXG4gICAgaWYgKGRvbmUpIHtcclxuICAgICAgICBwcm9wZXJ0aWVzWydkb25lJ10gPSAndHJ1ZSc7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoJ3Rhc2suY29tcGxldGUnLCBwcm9wZXJ0aWVzLCBtZXNzYWdlKTtcclxufVxyXG5leHBvcnRzLnNldFJlc3VsdCA9IHNldFJlc3VsdDtcclxuLy9cclxuLy8gQ2F0Y2hpbmcgYWxsIGV4Y2VwdGlvbnNcclxuLy9cclxucHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICBzZXRSZXN1bHQoVGFza1Jlc3VsdC5GYWlsZWQsIGV4cG9ydHMubG9jKCdMSUJfVW5oYW5kbGVkRXgnLCBlcnIubWVzc2FnZSkpO1xyXG59KTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBMb2MgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmV4cG9ydHMuc2V0UmVzb3VyY2VQYXRoID0gaW0uX3NldFJlc291cmNlUGF0aDtcclxuZXhwb3J0cy5sb2MgPSBpbS5fbG9jO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIElucHV0IEhlbHBlcnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5leHBvcnRzLmdldFZhcmlhYmxlID0gaW0uX2dldFZhcmlhYmxlO1xyXG4vKipcclxuICogQXNzZXJ0cyB0aGUgYWdlbnQgdmVyc2lvbiBpcyBhdCBsZWFzdCB0aGUgc3BlY2lmaWVkIG1pbmltdW0uXHJcbiAqXHJcbiAqIEBwYXJhbSAgICBtaW5pbXVtICAgIG1pbmltdW0gdmVyc2lvbiB2ZXJzaW9uIC0gbXVzdCBiZSAyLjEwNC4xIG9yIGhpZ2hlclxyXG4gKi9cclxuZnVuY3Rpb24gYXNzZXJ0QWdlbnQobWluaW11bSkge1xyXG4gICAgaWYgKHNlbXZlci5sdChtaW5pbXVtLCAnMi4xMDQuMScpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhc3NlcnRBZ2VudCgpIHJlcXVpcmVzIHRoZSBwYXJhbWV0ZXIgdG8gYmUgMi4xMDQuMSBvciBoaWdoZXInKTtcclxuICAgIH1cclxuICAgIHZhciBhZ2VudCA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LlZlcnNpb24nKTtcclxuICAgIGlmIChhZ2VudCAmJiBzZW12ZXIubHQoYWdlbnQsIG1pbmltdW0pKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQWdlbnQgdmVyc2lvbiBcIiArIG1pbmltdW0gKyBcIiBvciBoaWdoZXIgaXMgcmVxdWlyZWRcIik7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5hc3NlcnRBZ2VudCA9IGFzc2VydEFnZW50O1xyXG4vKipcclxuICogR2V0cyBhIHNuYXBzaG90IG9mIHRoZSBjdXJyZW50IHN0YXRlIG9mIGFsbCBqb2IgdmFyaWFibGVzIGF2YWlsYWJsZSB0byB0aGUgdGFzay5cclxuICogUmVxdWlyZXMgYSAyLjEwNC4xIGFnZW50IG9yIGhpZ2hlciBmb3IgZnVsbCBmdW5jdGlvbmFsaXR5LlxyXG4gKlxyXG4gKiBMaW1pdGF0aW9ucyBvbiBhbiBhZ2VudCBwcmlvciB0byAyLjEwNC4xOlxyXG4gKiAgMSkgVGhlIHJldHVybiB2YWx1ZSBkb2VzIG5vdCBpbmNsdWRlIGFsbCBwdWJsaWMgdmFyaWFibGVzLiBPbmx5IHB1YmxpYyB2YXJpYWJsZXNcclxuICogICAgIHRoYXQgaGF2ZSBiZWVuIGFkZGVkIHVzaW5nIHNldFZhcmlhYmxlIGFyZSByZXR1cm5lZC5cclxuICogIDIpIFRoZSBuYW1lIHJldHVybmVkIGZvciBlYWNoIHNlY3JldCB2YXJpYWJsZSBpcyB0aGUgZm9ybWF0dGVkIGVudmlyb25tZW50IHZhcmlhYmxlXHJcbiAqICAgICBuYW1lLCBub3QgdGhlIGFjdHVhbCB2YXJpYWJsZSBuYW1lICh1bmxlc3MgaXQgd2FzIHNldCBleHBsaWNpdGx5IGF0IHJ1bnRpbWUgdXNpbmdcclxuICogICAgIHNldFZhcmlhYmxlKS5cclxuICpcclxuICogQHJldHVybnMgVmFyaWFibGVJbmZvW11cclxuICovXHJcbmZ1bmN0aW9uIGdldFZhcmlhYmxlcygpIHtcclxuICAgIHJldHVybiBPYmplY3Qua2V5cyhpbS5fa25vd25WYXJpYWJsZU1hcClcclxuICAgICAgICAubWFwKGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICB2YXIgaW5mbyA9IGltLl9rbm93blZhcmlhYmxlTWFwW2tleV07XHJcbiAgICAgICAgcmV0dXJuIHsgbmFtZTogaW5mby5uYW1lLCB2YWx1ZTogZXhwb3J0cy5nZXRWYXJpYWJsZShpbmZvLm5hbWUpLCBzZWNyZXQ6IGluZm8uc2VjcmV0IH07XHJcbiAgICB9KTtcclxufVxyXG5leHBvcnRzLmdldFZhcmlhYmxlcyA9IGdldFZhcmlhYmxlcztcclxuLyoqXHJcbiAqIFNldHMgYSB2YXJpYWJsZSB3aGljaCB3aWxsIGJlIGF2YWlsYWJsZSB0byBzdWJzZXF1ZW50IHRhc2tzIGFzIHdlbGwuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgbmFtZSBvZiB0aGUgdmFyaWFibGUgdG8gc2V0XHJcbiAqIEBwYXJhbSAgICAgdmFsICAgICAgdmFsdWUgdG8gc2V0XHJcbiAqIEBwYXJhbSAgICAgc2VjcmV0ICAgd2hldGhlciB2YXJpYWJsZSBpcyBzZWNyZXQuICBNdWx0aS1saW5lIHNlY3JldHMgYXJlIG5vdCBhbGxvd2VkLiAgT3B0aW9uYWwsIGRlZmF1bHRzIHRvIGZhbHNlXHJcbiAqIEBwYXJhbSAgICAgaXNPdXRwdXQgd2hldGhlciB2YXJpYWJsZSBpcyBhbiBvdXRwdXQgdmFyaWFibGUuICBPcHRpb25hbCwgZGVmYXVsdHMgdG8gZmFsc2VcclxuICogQHJldHVybnMgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBzZXRWYXJpYWJsZShuYW1lLCB2YWwsIHNlY3JldCwgaXNPdXRwdXQpIHtcclxuICAgIGlmIChzZWNyZXQgPT09IHZvaWQgMCkgeyBzZWNyZXQgPSBmYWxzZTsgfVxyXG4gICAgaWYgKGlzT3V0cHV0ID09PSB2b2lkIDApIHsgaXNPdXRwdXQgPSBmYWxzZTsgfVxyXG4gICAgLy8gb25jZSBhIHNlY3JldCBhbHdheXMgYSBzZWNyZXRcclxuICAgIHZhciBrZXkgPSBpbS5fZ2V0VmFyaWFibGVLZXkobmFtZSk7XHJcbiAgICBpZiAoaW0uX2tub3duVmFyaWFibGVNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xyXG4gICAgICAgIHNlY3JldCA9IHNlY3JldCB8fCBpbS5fa25vd25WYXJpYWJsZU1hcFtrZXldLnNlY3JldDtcclxuICAgIH1cclxuICAgIC8vIHN0b3JlIHRoZSB2YWx1ZVxyXG4gICAgdmFyIHZhclZhbHVlID0gdmFsIHx8ICcnO1xyXG4gICAgZXhwb3J0cy5kZWJ1Zygnc2V0ICcgKyBuYW1lICsgJz0nICsgKHNlY3JldCAmJiB2YXJWYWx1ZSA/ICcqKioqKioqKicgOiB2YXJWYWx1ZSkpO1xyXG4gICAgaWYgKHNlY3JldCkge1xyXG4gICAgICAgIGlmICh2YXJWYWx1ZSAmJiB2YXJWYWx1ZS5tYXRjaCgvXFxyfFxcbi8pICYmIChcIlwiICsgcHJvY2Vzcy5lbnZbJ1NZU1RFTV9VTlNBRkVBTExPV01VTFRJTElORVNFQ1JFVCddKS50b1VwcGVyQ2FzZSgpICE9ICdUUlVFJykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9NdWx0aWxpbmVTZWNyZXQnKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGltLl92YXVsdC5zdG9yZVNlY3JldCgnU0VDUkVUXycgKyBrZXksIHZhclZhbHVlKTtcclxuICAgICAgICBkZWxldGUgcHJvY2Vzcy5lbnZba2V5XTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHByb2Nlc3MuZW52W2tleV0gPSB2YXJWYWx1ZTtcclxuICAgIH1cclxuICAgIC8vIHN0b3JlIHRoZSBtZXRhZGF0YVxyXG4gICAgaW0uX2tub3duVmFyaWFibGVNYXBba2V5XSA9IHsgbmFtZTogbmFtZSwgc2VjcmV0OiBzZWNyZXQgfTtcclxuICAgIC8vIHdyaXRlIHRoZSBzZXR2YXJpYWJsZSBjb21tYW5kXHJcbiAgICBleHBvcnRzLmNvbW1hbmQoJ3Rhc2suc2V0dmFyaWFibGUnLCB7ICd2YXJpYWJsZSc6IG5hbWUgfHwgJycsIGlzT3V0cHV0OiAoaXNPdXRwdXQgfHwgZmFsc2UpLnRvU3RyaW5nKCksICdpc3NlY3JldCc6IChzZWNyZXQgfHwgZmFsc2UpLnRvU3RyaW5nKCkgfSwgdmFyVmFsdWUpO1xyXG59XHJcbmV4cG9ydHMuc2V0VmFyaWFibGUgPSBzZXRWYXJpYWJsZTtcclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhIHZhbHVlIHdpdGggdGhlIGxvZ2dlciwgc28gdGhlIHZhbHVlIHdpbGwgYmUgbWFza2VkIGZyb20gdGhlIGxvZ3MuICBNdWx0aS1saW5lIHNlY3JldHMgYXJlIG5vdCBhbGxvd2VkLlxyXG4gKlxyXG4gKiBAcGFyYW0gdmFsIHZhbHVlIHRvIHJlZ2lzdGVyXHJcbiAqL1xyXG5mdW5jdGlvbiBzZXRTZWNyZXQodmFsKSB7XHJcbiAgICBpZiAodmFsKSB7XHJcbiAgICAgICAgaWYgKHZhbC5tYXRjaCgvXFxyfFxcbi8pICYmIChcIlwiICsgcHJvY2Vzcy5lbnZbJ1NZU1RFTV9VTlNBRkVBTExPV01VTFRJTElORVNFQ1JFVCddKS50b1VwcGVyQ2FzZSgpICE9PSAnVFJVRScpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfTXVsdGlsaW5lU2VjcmV0JykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBleHBvcnRzLmNvbW1hbmQoJ3Rhc2suc2V0c2VjcmV0Jywge30sIHZhbCk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5zZXRTZWNyZXQgPSBzZXRTZWNyZXQ7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhbiBpbnB1dC5cclxuICogSWYgcmVxdWlyZWQgaXMgdHJ1ZSBhbmQgdGhlIHZhbHVlIGlzIG5vdCBzZXQsIGl0IHdpbGwgdGhyb3cuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgbmFtZSBvZiB0aGUgaW5wdXQgdG8gZ2V0XHJcbiAqIEBwYXJhbSAgICAgcmVxdWlyZWQgd2hldGhlciBpbnB1dCBpcyByZXF1aXJlZC4gIG9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0SW5wdXQobmFtZSwgcmVxdWlyZWQpIHtcclxuICAgIHZhciBpbnZhbCA9IGltLl92YXVsdC5yZXRyaWV2ZVNlY3JldCgnSU5QVVRfJyArIGltLl9nZXRWYXJpYWJsZUtleShuYW1lKSk7XHJcbiAgICBpZiAocmVxdWlyZWQgJiYgIWludmFsKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfSW5wdXRSZXF1aXJlZCcsIG5hbWUpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcobmFtZSArICc9JyArIGludmFsKTtcclxuICAgIHJldHVybiBpbnZhbDtcclxufVxyXG5leHBvcnRzLmdldElucHV0ID0gZ2V0SW5wdXQ7XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhbiBpbnB1dCBhbmQgY29udmVydHMgdG8gYSBib29sLiAgQ29udmVuaWVuY2UuXHJcbiAqIElmIHJlcXVpcmVkIGlzIHRydWUgYW5kIHRoZSB2YWx1ZSBpcyBub3Qgc2V0LCBpdCB3aWxsIHRocm93LlxyXG4gKiBJZiByZXF1aXJlZCBpcyBmYWxzZSBhbmQgdGhlIHZhbHVlIGlzIG5vdCBzZXQsIHJldHVybnMgZmFsc2UuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgbmFtZSBvZiB0aGUgYm9vbCBpbnB1dCB0byBnZXRcclxuICogQHBhcmFtICAgICByZXF1aXJlZCB3aGV0aGVyIGlucHV0IGlzIHJlcXVpcmVkLiAgb3B0aW9uYWwsIGRlZmF1bHRzIHRvIGZhbHNlXHJcbiAqIEByZXR1cm5zICAgYm9vbGVhblxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0Qm9vbElucHV0KG5hbWUsIHJlcXVpcmVkKSB7XHJcbiAgICByZXR1cm4gKGdldElucHV0KG5hbWUsIHJlcXVpcmVkKSB8fCAnJykudG9VcHBlckNhc2UoKSA9PSBcIlRSVUVcIjtcclxufVxyXG5leHBvcnRzLmdldEJvb2xJbnB1dCA9IGdldEJvb2xJbnB1dDtcclxuLyoqXHJcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGFuIGlucHV0IGFuZCBzcGxpdHMgdGhlIHZhbHVlIHVzaW5nIGEgZGVsaW1pdGVyIChzcGFjZSwgY29tbWEsIGV0YykuXHJcbiAqIEVtcHR5IHZhbHVlcyBhcmUgcmVtb3ZlZC4gIFRoaXMgZnVuY3Rpb24gaXMgdXNlZnVsIGZvciBzcGxpdHRpbmcgYW4gaW5wdXQgY29udGFpbmluZyBhIHNpbXBsZVxyXG4gKiBsaXN0IG9mIGl0ZW1zIC0gc3VjaCBhcyBidWlsZCB0YXJnZXRzLlxyXG4gKiBJTVBPUlRBTlQ6IERvIG5vdCB1c2UgdGhpcyBmdW5jdGlvbiBmb3Igc3BsaXR0aW5nIGFkZGl0aW9uYWwgYXJncyEgIEluc3RlYWQgdXNlIGFyZ1N0cmluZygpLCB3aGljaFxyXG4gKiBmb2xsb3dzIG5vcm1hbCBhcmd1bWVudCBzcGxpdHRpbmcgcnVsZXMgYW5kIGhhbmRsZXMgdmFsdWVzIGVuY2Fwc3VsYXRlZCBieSBxdW90ZXMuXHJcbiAqIElmIHJlcXVpcmVkIGlzIHRydWUgYW5kIHRoZSB2YWx1ZSBpcyBub3Qgc2V0LCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIG5hbWUgICAgIG5hbWUgb2YgdGhlIGlucHV0IHRvIGdldFxyXG4gKiBAcGFyYW0gICAgIGRlbGltICAgIGRlbGltaXRlciB0byBzcGxpdCBvblxyXG4gKiBAcGFyYW0gICAgIHJlcXVpcmVkIHdoZXRoZXIgaW5wdXQgaXMgcmVxdWlyZWQuICBvcHRpb25hbCwgZGVmYXVsdHMgdG8gZmFsc2VcclxuICogQHJldHVybnMgICBzdHJpbmdbXVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0RGVsaW1pdGVkSW5wdXQobmFtZSwgZGVsaW0sIHJlcXVpcmVkKSB7XHJcbiAgICB2YXIgaW5wdXRWYWwgPSBnZXRJbnB1dChuYW1lLCByZXF1aXJlZCk7XHJcbiAgICBpZiAoIWlucHV0VmFsKSB7XHJcbiAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfVxyXG4gICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgaW5wdXRWYWwuc3BsaXQoZGVsaW0pLmZvckVhY2goZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICBpZiAoeCkge1xyXG4gICAgICAgICAgICByZXN1bHQucHVzaCh4KTtcclxuICAgICAgICB9XHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuZXhwb3J0cy5nZXREZWxpbWl0ZWRJbnB1dCA9IGdldERlbGltaXRlZElucHV0O1xyXG4vKipcclxuICogQ2hlY2tzIHdoZXRoZXIgYSBwYXRoIGlucHV0cyB2YWx1ZSB3YXMgc3VwcGxpZWQgYnkgdGhlIHVzZXJcclxuICogRmlsZSBwYXRocyBhcmUgcmVsYXRpdmUgd2l0aCBhIHBpY2tlciwgc28gYW4gZW1wdHkgcGF0aCBpcyB0aGUgcm9vdCBvZiB0aGUgcmVwby5cclxuICogVXNlZnVsIGlmIHlvdSBuZWVkIHRvIGNvbmRpdGlvbiB3b3JrIChsaWtlIGFwcGVuZCBhbiBhcmcpIGlmIGEgdmFsdWUgd2FzIHN1cHBsaWVkXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgbmFtZSAgICAgIG5hbWUgb2YgdGhlIHBhdGggaW5wdXQgdG8gY2hlY2tcclxuICogQHJldHVybnMgICBib29sZWFuXHJcbiAqL1xyXG5mdW5jdGlvbiBmaWxlUGF0aFN1cHBsaWVkKG5hbWUpIHtcclxuICAgIC8vIG5vcm1hbGl6ZSBwYXRoc1xyXG4gICAgdmFyIHBhdGhWYWx1ZSA9IHRoaXMucmVzb2x2ZSh0aGlzLmdldFBhdGhJbnB1dChuYW1lKSB8fCAnJyk7XHJcbiAgICB2YXIgcmVwb1Jvb3QgPSB0aGlzLnJlc29sdmUoZXhwb3J0cy5nZXRWYXJpYWJsZSgnYnVpbGQuc291cmNlc0RpcmVjdG9yeScpIHx8IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ3N5c3RlbS5kZWZhdWx0V29ya2luZ0RpcmVjdG9yeScpIHx8ICcnKTtcclxuICAgIHZhciBzdXBwbGllZCA9IHBhdGhWYWx1ZSAhPT0gcmVwb1Jvb3Q7XHJcbiAgICBleHBvcnRzLmRlYnVnKG5hbWUgKyAncGF0aCBzdXBwbGllZCA6JyArIHN1cHBsaWVkKTtcclxuICAgIHJldHVybiBzdXBwbGllZDtcclxufVxyXG5leHBvcnRzLmZpbGVQYXRoU3VwcGxpZWQgPSBmaWxlUGF0aFN1cHBsaWVkO1xyXG4vKipcclxuICogR2V0cyB0aGUgdmFsdWUgb2YgYSBwYXRoIGlucHV0XHJcbiAqIEl0IHdpbGwgYmUgcXVvdGVkIGZvciB5b3UgaWYgaXQgaXNuJ3QgYWxyZWFkeSBhbmQgY29udGFpbnMgc3BhY2VzXHJcbiAqIElmIHJlcXVpcmVkIGlzIHRydWUgYW5kIHRoZSB2YWx1ZSBpcyBub3Qgc2V0LCBpdCB3aWxsIHRocm93LlxyXG4gKiBJZiBjaGVjayBpcyB0cnVlIGFuZCB0aGUgcGF0aCBkb2VzIG5vdCBleGlzdCwgaXQgd2lsbCB0aHJvdy5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICAgbmFtZSBvZiB0aGUgaW5wdXQgdG8gZ2V0XHJcbiAqIEBwYXJhbSAgICAgcmVxdWlyZWQgIHdoZXRoZXIgaW5wdXQgaXMgcmVxdWlyZWQuICBvcHRpb25hbCwgZGVmYXVsdHMgdG8gZmFsc2VcclxuICogQHBhcmFtICAgICBjaGVjayAgICAgd2hldGhlciBwYXRoIGlzIGNoZWNrZWQuICBvcHRpb25hbCwgZGVmYXVsdHMgdG8gZmFsc2VcclxuICogQHJldHVybnMgICBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIGdldFBhdGhJbnB1dChuYW1lLCByZXF1aXJlZCwgY2hlY2spIHtcclxuICAgIHZhciBpbnZhbCA9IGdldElucHV0KG5hbWUsIHJlcXVpcmVkKTtcclxuICAgIGlmIChpbnZhbCkge1xyXG4gICAgICAgIGlmIChjaGVjaykge1xyXG4gICAgICAgICAgICBleHBvcnRzLmNoZWNrUGF0aChpbnZhbCwgbmFtZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGludmFsO1xyXG59XHJcbmV4cG9ydHMuZ2V0UGF0aElucHV0ID0gZ2V0UGF0aElucHV0O1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIEVuZHBvaW50IEhlbHBlcnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKipcclxuICogR2V0cyB0aGUgdXJsIGZvciBhIHNlcnZpY2UgZW5kcG9pbnRcclxuICogSWYgdGhlIHVybCB3YXMgbm90IHNldCBhbmQgaXMgbm90IG9wdGlvbmFsLCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIGlkICAgICAgICBuYW1lIG9mIHRoZSBzZXJ2aWNlIGVuZHBvaW50XHJcbiAqIEBwYXJhbSAgICAgb3B0aW9uYWwgIHdoZXRoZXIgdGhlIHVybCBpcyBvcHRpb25hbFxyXG4gKiBAcmV0dXJucyAgIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0RW5kcG9pbnRVcmwoaWQsIG9wdGlvbmFsKSB7XHJcbiAgICB2YXIgdXJsdmFsID0gcHJvY2Vzcy5lbnZbJ0VORFBPSU5UX1VSTF8nICsgaWRdO1xyXG4gICAgaWYgKCFvcHRpb25hbCAmJiAhdXJsdmFsKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfRW5kcG9pbnROb3RFeGlzdCcsIGlkKSk7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKGlkICsgJz0nICsgdXJsdmFsKTtcclxuICAgIHJldHVybiB1cmx2YWw7XHJcbn1cclxuZXhwb3J0cy5nZXRFbmRwb2ludFVybCA9IGdldEVuZHBvaW50VXJsO1xyXG4vKlxyXG4gKiBHZXRzIHRoZSBlbmRwb2ludCBkYXRhIHBhcmFtZXRlciB2YWx1ZSB3aXRoIHNwZWNpZmllZCBrZXkgZm9yIGEgc2VydmljZSBlbmRwb2ludFxyXG4gKiBJZiB0aGUgZW5kcG9pbnQgZGF0YSBwYXJhbWV0ZXIgd2FzIG5vdCBzZXQgYW5kIGlzIG5vdCBvcHRpb25hbCwgaXQgd2lsbCB0aHJvdy5cclxuICpcclxuICogQHBhcmFtIGlkIG5hbWUgb2YgdGhlIHNlcnZpY2UgZW5kcG9pbnRcclxuICogQHBhcmFtIGtleSBvZiB0aGUgcGFyYW1ldGVyXHJcbiAqIEBwYXJhbSBvcHRpb25hbCB3aGV0aGVyIHRoZSBlbmRwb2ludCBkYXRhIGlzIG9wdGlvbmFsXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHZhbHVlIG9mIHRoZSBlbmRwb2ludCBkYXRhIHBhcmFtZXRlclxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0RW5kcG9pbnREYXRhUGFyYW1ldGVyKGlkLCBrZXksIG9wdGlvbmFsKSB7XHJcbiAgICB2YXIgZGF0YVBhcmFtVmFsID0gcHJvY2Vzcy5lbnZbJ0VORFBPSU5UX0RBVEFfJyArIGlkICsgJ18nICsga2V5LnRvVXBwZXJDYXNlKCldO1xyXG4gICAgaWYgKCFvcHRpb25hbCAmJiAhZGF0YVBhcmFtVmFsKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfRW5kcG9pbnREYXRhTm90RXhpc3QnLCBpZCwga2V5KSk7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKGlkICsgJyBkYXRhICcgKyBrZXkgKyAnID0gJyArIGRhdGFQYXJhbVZhbCk7XHJcbiAgICByZXR1cm4gZGF0YVBhcmFtVmFsO1xyXG59XHJcbmV4cG9ydHMuZ2V0RW5kcG9pbnREYXRhUGFyYW1ldGVyID0gZ2V0RW5kcG9pbnREYXRhUGFyYW1ldGVyO1xyXG4vKipcclxuICogR2V0cyB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBzY2hlbWUgZm9yIGEgc2VydmljZSBlbmRwb2ludFxyXG4gKiBJZiB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBzY2hlbWUgaXMgbm90IHNldCBhbmQgaXMgbm90IG9wdGlvbmFsLCBpdCB3aWxsIHRocm93LlxyXG4gKlxyXG4gKiBAcGFyYW0gaWQgbmFtZSBvZiB0aGUgc2VydmljZSBlbmRwb2ludFxyXG4gKiBAcGFyYW0gb3B0aW9uYWwgd2hldGhlciB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBzY2hlbWUgaXMgb3B0aW9uYWxcclxuICogQHJldHVybnMge3N0cmluZ30gdmFsdWUgb2YgdGhlIGVuZHBvaW50IGF1dGhvcml6YXRpb24gc2NoZW1lXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRFbmRwb2ludEF1dGhvcml6YXRpb25TY2hlbWUoaWQsIG9wdGlvbmFsKSB7XHJcbiAgICB2YXIgYXV0aFNjaGVtZSA9IGltLl92YXVsdC5yZXRyaWV2ZVNlY3JldCgnRU5EUE9JTlRfQVVUSF9TQ0hFTUVfJyArIGlkKTtcclxuICAgIGlmICghb3B0aW9uYWwgJiYgIWF1dGhTY2hlbWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9FbmRwb2ludEF1dGhOb3RFeGlzdCcsIGlkKSk7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKGlkICsgJyBhdXRoIHNjaGVtZSA9ICcgKyBhdXRoU2NoZW1lKTtcclxuICAgIHJldHVybiBhdXRoU2NoZW1lO1xyXG59XHJcbmV4cG9ydHMuZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uU2NoZW1lID0gZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uU2NoZW1lO1xyXG4vKipcclxuICogR2V0cyB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBwYXJhbWV0ZXIgdmFsdWUgZm9yIGEgc2VydmljZSBlbmRwb2ludCB3aXRoIHNwZWNpZmllZCBrZXlcclxuICogSWYgdGhlIGVuZHBvaW50IGF1dGhvcml6YXRpb24gcGFyYW1ldGVyIGlzIG5vdCBzZXQgYW5kIGlzIG5vdCBvcHRpb25hbCwgaXQgd2lsbCB0aHJvdy5cclxuICpcclxuICogQHBhcmFtIGlkIG5hbWUgb2YgdGhlIHNlcnZpY2UgZW5kcG9pbnRcclxuICogQHBhcmFtIGtleSBrZXkgdG8gZmluZCB0aGUgZW5kcG9pbnQgYXV0aG9yaXphdGlvbiBwYXJhbWV0ZXJcclxuICogQHBhcmFtIG9wdGlvbmFsIG9wdGlvbmFsIHdoZXRoZXIgdGhlIGVuZHBvaW50IGF1dGhvcml6YXRpb24gc2NoZW1lIGlzIG9wdGlvbmFsXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHZhbHVlIG9mIHRoZSBlbmRwb2ludCBhdXRob3JpemF0aW9uIHBhcmFtZXRlciB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uUGFyYW1ldGVyKGlkLCBrZXksIG9wdGlvbmFsKSB7XHJcbiAgICB2YXIgYXV0aFBhcmFtID0gaW0uX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdFTkRQT0lOVF9BVVRIX1BBUkFNRVRFUl8nICsgaWQgKyAnXycgKyBrZXkudG9VcHBlckNhc2UoKSk7XHJcbiAgICBpZiAoIW9wdGlvbmFsICYmICFhdXRoUGFyYW0pIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9FbmRwb2ludEF1dGhOb3RFeGlzdCcsIGlkKSk7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKGlkICsgJyBhdXRoIHBhcmFtICcgKyBrZXkgKyAnID0gJyArIGF1dGhQYXJhbSk7XHJcbiAgICByZXR1cm4gYXV0aFBhcmFtO1xyXG59XHJcbmV4cG9ydHMuZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uUGFyYW1ldGVyID0gZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uUGFyYW1ldGVyO1xyXG4vKipcclxuICogR2V0cyB0aGUgYXV0aG9yaXphdGlvbiBkZXRhaWxzIGZvciBhIHNlcnZpY2UgZW5kcG9pbnRcclxuICogSWYgdGhlIGF1dGhvcml6YXRpb24gd2FzIG5vdCBzZXQgYW5kIGlzIG5vdCBvcHRpb25hbCwgaXQgd2lsbCB0aHJvdy5cclxuICpcclxuICogQHBhcmFtICAgICBpZCAgICAgICAgbmFtZSBvZiB0aGUgc2VydmljZSBlbmRwb2ludFxyXG4gKiBAcGFyYW0gICAgIG9wdGlvbmFsICB3aGV0aGVyIHRoZSB1cmwgaXMgb3B0aW9uYWxcclxuICogQHJldHVybnMgICBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIGdldEVuZHBvaW50QXV0aG9yaXphdGlvbihpZCwgb3B0aW9uYWwpIHtcclxuICAgIHZhciBhdmFsID0gaW0uX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdFTkRQT0lOVF9BVVRIXycgKyBpZCk7XHJcbiAgICBpZiAoIW9wdGlvbmFsICYmICFhdmFsKSB7XHJcbiAgICAgICAgc2V0UmVzdWx0KFRhc2tSZXN1bHQuRmFpbGVkLCBleHBvcnRzLmxvYygnTElCX0VuZHBvaW50QXV0aE5vdEV4aXN0JywgaWQpKTtcclxuICAgIH1cclxuICAgIGV4cG9ydHMuZGVidWcoaWQgKyAnIGV4aXN0cyAnICsgKGF2YWwgIT09IG51bGwpKTtcclxuICAgIHZhciBhdXRoO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICBpZiAoYXZhbCkge1xyXG4gICAgICAgICAgICBhdXRoID0gSlNPTi5wYXJzZShhdmFsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfSW52YWxpZEVuZHBvaW50QXV0aCcsIGF2YWwpKTtcclxuICAgIH1cclxuICAgIHJldHVybiBhdXRoO1xyXG59XHJcbmV4cG9ydHMuZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uID0gZ2V0RW5kcG9pbnRBdXRob3JpemF0aW9uO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFNlY3VyZUZpbGUgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBuYW1lIGZvciBhIHNlY3VyZSBmaWxlXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgaWQgICAgICAgIHNlY3VyZSBmaWxlIGlkXHJcbiAqIEByZXR1cm5zICAgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRTZWN1cmVGaWxlTmFtZShpZCkge1xyXG4gICAgdmFyIG5hbWUgPSBwcm9jZXNzLmVudlsnU0VDVVJFRklMRV9OQU1FXycgKyBpZF07XHJcbiAgICBleHBvcnRzLmRlYnVnKCdzZWN1cmUgZmlsZSBuYW1lIGZvciBpZCAnICsgaWQgKyAnID0gJyArIG5hbWUpO1xyXG4gICAgcmV0dXJuIG5hbWU7XHJcbn1cclxuZXhwb3J0cy5nZXRTZWN1cmVGaWxlTmFtZSA9IGdldFNlY3VyZUZpbGVOYW1lO1xyXG4vKipcclxuICAqIEdldHMgdGhlIHNlY3VyZSBmaWxlIHRpY2tldCB0aGF0IGNhbiBiZSB1c2VkIHRvIGRvd25sb2FkIHRoZSBzZWN1cmUgZmlsZSBjb250ZW50c1xyXG4gICpcclxuICAqIEBwYXJhbSBpZCBuYW1lIG9mIHRoZSBzZWN1cmUgZmlsZVxyXG4gICogQHJldHVybnMge3N0cmluZ30gc2VjdXJlIGZpbGUgdGlja2V0XHJcbiAgKi9cclxuZnVuY3Rpb24gZ2V0U2VjdXJlRmlsZVRpY2tldChpZCkge1xyXG4gICAgdmFyIHRpY2tldCA9IGltLl92YXVsdC5yZXRyaWV2ZVNlY3JldCgnU0VDVVJFRklMRV9USUNLRVRfJyArIGlkKTtcclxuICAgIGV4cG9ydHMuZGVidWcoJ3NlY3VyZSBmaWxlIHRpY2tldCBmb3IgaWQgJyArIGlkICsgJyA9ICcgKyB0aWNrZXQpO1xyXG4gICAgcmV0dXJuIHRpY2tldDtcclxufVxyXG5leHBvcnRzLmdldFNlY3VyZUZpbGVUaWNrZXQgPSBnZXRTZWN1cmVGaWxlVGlja2V0O1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFRhc2sgVmFyaWFibGUgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBHZXRzIGEgdmFyaWFibGUgdmFsdWUgdGhhdCBpcyBzZXQgYnkgcHJldmlvdXMgc3RlcCBmcm9tIHRoZSBzYW1lIHdyYXBwZXIgdGFzay5cclxuICogUmVxdWlyZXMgYSAyLjExNS4wIGFnZW50IG9yIGhpZ2hlci5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgICBuYW1lIG9mIHRoZSB2YXJpYWJsZSB0byBnZXRcclxuICogQHJldHVybnMgICBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIGdldFRhc2tWYXJpYWJsZShuYW1lKSB7XHJcbiAgICBhc3NlcnRBZ2VudCgnMi4xMTUuMCcpO1xyXG4gICAgdmFyIGludmFsID0gaW0uX3ZhdWx0LnJldHJpZXZlU2VjcmV0KCdWU1RTX1RBU0tWQVJJQUJMRV8nICsgaW0uX2dldFZhcmlhYmxlS2V5KG5hbWUpKTtcclxuICAgIGlmIChpbnZhbCkge1xyXG4gICAgICAgIGludmFsID0gaW52YWwudHJpbSgpO1xyXG4gICAgfVxyXG4gICAgZXhwb3J0cy5kZWJ1ZygndGFzayB2YXJpYWJsZTogJyArIG5hbWUgKyAnPScgKyBpbnZhbCk7XHJcbiAgICByZXR1cm4gaW52YWw7XHJcbn1cclxuZXhwb3J0cy5nZXRUYXNrVmFyaWFibGUgPSBnZXRUYXNrVmFyaWFibGU7XHJcbi8qKlxyXG4gKiBTZXRzIGEgdGFzayB2YXJpYWJsZSB3aGljaCB3aWxsIG9ubHkgYmUgYXZhaWxhYmxlIHRvIHN1YnNlcXVlbnQgc3RlcHMgYmVsb25nIHRvIHRoZSBzYW1lIHdyYXBwZXIgdGFzay5cclxuICogUmVxdWlyZXMgYSAyLjExNS4wIGFnZW50IG9yIGhpZ2hlci5cclxuICpcclxuICogQHBhcmFtICAgICBuYW1lICAgIG5hbWUgb2YgdGhlIHZhcmlhYmxlIHRvIHNldFxyXG4gKiBAcGFyYW0gICAgIHZhbCAgICAgdmFsdWUgdG8gc2V0XHJcbiAqIEBwYXJhbSAgICAgc2VjcmV0ICB3aGV0aGVyIHZhcmlhYmxlIGlzIHNlY3JldC4gIG9wdGlvbmFsLCBkZWZhdWx0cyB0byBmYWxzZVxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHNldFRhc2tWYXJpYWJsZShuYW1lLCB2YWwsIHNlY3JldCkge1xyXG4gICAgaWYgKHNlY3JldCA9PT0gdm9pZCAwKSB7IHNlY3JldCA9IGZhbHNlOyB9XHJcbiAgICBhc3NlcnRBZ2VudCgnMi4xMTUuMCcpO1xyXG4gICAgdmFyIGtleSA9IGltLl9nZXRWYXJpYWJsZUtleShuYW1lKTtcclxuICAgIC8vIHN0b3JlIHRoZSB2YWx1ZVxyXG4gICAgdmFyIHZhclZhbHVlID0gdmFsIHx8ICcnO1xyXG4gICAgZXhwb3J0cy5kZWJ1Zygnc2V0IHRhc2sgdmFyaWFibGU6ICcgKyBuYW1lICsgJz0nICsgKHNlY3JldCAmJiB2YXJWYWx1ZSA/ICcqKioqKioqKicgOiB2YXJWYWx1ZSkpO1xyXG4gICAgaW0uX3ZhdWx0LnN0b3JlU2VjcmV0KCdWU1RTX1RBU0tWQVJJQUJMRV8nICsga2V5LCB2YXJWYWx1ZSk7XHJcbiAgICBkZWxldGUgcHJvY2Vzcy5lbnZba2V5XTtcclxuICAgIC8vIHdyaXRlIHRoZSBjb21tYW5kXHJcbiAgICBleHBvcnRzLmNvbW1hbmQoJ3Rhc2suc2V0dGFza3ZhcmlhYmxlJywgeyAndmFyaWFibGUnOiBuYW1lIHx8ICcnLCAnaXNzZWNyZXQnOiAoc2VjcmV0IHx8IGZhbHNlKS50b1N0cmluZygpIH0sIHZhclZhbHVlKTtcclxufVxyXG5leHBvcnRzLnNldFRhc2tWYXJpYWJsZSA9IHNldFRhc2tWYXJpYWJsZTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBDbWQgSGVscGVyc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmV4cG9ydHMuY29tbWFuZCA9IGltLl9jb21tYW5kO1xyXG5leHBvcnRzLndhcm5pbmcgPSBpbS5fd2FybmluZztcclxuZXhwb3J0cy5lcnJvciA9IGltLl9lcnJvcjtcclxuZXhwb3J0cy5kZWJ1ZyA9IGltLl9kZWJ1ZztcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBEaXNrIEZ1bmN0aW9uc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmZ1bmN0aW9uIF9jaGVja1NoZWxsKGNtZCwgY29udGludWVPbkVycm9yKSB7XHJcbiAgICB2YXIgc2UgPSBzaGVsbC5lcnJvcigpO1xyXG4gICAgaWYgKHNlKSB7XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhjbWQgKyAnIGZhaWxlZCcpO1xyXG4gICAgICAgIHZhciBlcnJNc2cgPSBleHBvcnRzLmxvYygnTElCX09wZXJhdGlvbkZhaWxlZCcsIGNtZCwgc2UpO1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoZXJyTXNnKTtcclxuICAgICAgICBpZiAoIWNvbnRpbnVlT25FcnJvcikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyTXNnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuLyoqXHJcbiAqIEdldCdzIHN0YXQgb24gYSBwYXRoLlxyXG4gKiBVc2VmdWwgZm9yIGNoZWNraW5nIHdoZXRoZXIgYSBmaWxlIG9yIGRpcmVjdG9yeS4gIEFsc28gZ2V0dGluZyBjcmVhdGVkLCBtb2RpZmllZCBhbmQgYWNjZXNzZWQgdGltZS5cclxuICogc2VlIFtmcy5zdGF0XShodHRwczovL25vZGVqcy5vcmcvYXBpL2ZzLmh0bWwjZnNfY2xhc3NfZnNfc3RhdHMpXHJcbiAqXHJcbiAqIEBwYXJhbSAgICAgcGF0aCAgICAgIHBhdGggdG8gY2hlY2tcclxuICogQHJldHVybnMgICBmc1N0YXRcclxuICovXHJcbmZ1bmN0aW9uIHN0YXRzKHBhdGgpIHtcclxuICAgIHJldHVybiBmcy5zdGF0U3luYyhwYXRoKTtcclxufVxyXG5leHBvcnRzLnN0YXRzID0gc3RhdHM7XHJcbmV4cG9ydHMuZXhpc3QgPSBpbS5fZXhpc3Q7XHJcbmZ1bmN0aW9uIHdyaXRlRmlsZShmaWxlLCBkYXRhLCBvcHRpb25zKSB7XHJcbiAgICBpZiAodHlwZW9mIChvcHRpb25zKSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKGZpbGUsIGRhdGEsIHsgZW5jb2Rpbmc6IG9wdGlvbnMgfSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKGZpbGUsIGRhdGEsIG9wdGlvbnMpO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMud3JpdGVGaWxlID0gd3JpdGVGaWxlO1xyXG4vKipcclxuICogQGRlcHJlY2F0ZWQgVXNlIGBnZXRQbGF0Zm9ybWBcclxuICogVXNlZnVsIGZvciBkZXRlcm1pbmluZyB0aGUgaG9zdCBvcGVyYXRpbmcgc3lzdGVtLlxyXG4gKiBzZWUgW29zLnR5cGVdKGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvb3MuaHRtbCNvc19vc190eXBlKVxyXG4gKlxyXG4gKiBAcmV0dXJuICAgICAgdGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW1cclxuICovXHJcbmZ1bmN0aW9uIG9zVHlwZSgpIHtcclxuICAgIHJldHVybiBvcy50eXBlKCk7XHJcbn1cclxuZXhwb3J0cy5vc1R5cGUgPSBvc1R5cGU7XHJcbi8qKlxyXG4gKiBEZXRlcm1pbmUgdGhlIG9wZXJhdGluZyBzeXN0ZW0gdGhlIGJ1aWxkIGFnZW50IGlzIHJ1bm5pbmcgb24uXHJcbiAqIEByZXR1cm5zIHtQbGF0Zm9ybX1cclxuICogQHRocm93cyB7RXJyb3J9IFBsYXRmb3JtIGlzIG5vdCBzdXBwb3J0ZWQgYnkgb3VyIGFnZW50XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRQbGF0Zm9ybSgpIHtcclxuICAgIHN3aXRjaCAocHJvY2Vzcy5wbGF0Zm9ybSkge1xyXG4gICAgICAgIGNhc2UgJ3dpbjMyJzogcmV0dXJuIFBsYXRmb3JtLldpbmRvd3M7XHJcbiAgICAgICAgY2FzZSAnZGFyd2luJzogcmV0dXJuIFBsYXRmb3JtLk1hY09TO1xyXG4gICAgICAgIGNhc2UgJ2xpbnV4JzogcmV0dXJuIFBsYXRmb3JtLkxpbnV4O1xyXG4gICAgICAgIGRlZmF1bHQ6IHRocm93IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfUGxhdGZvcm1Ob3RTdXBwb3J0ZWQnLCBwcm9jZXNzLnBsYXRmb3JtKSk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5nZXRQbGF0Zm9ybSA9IGdldFBsYXRmb3JtO1xyXG4vKipcclxuICogUmV0dXJucyB0aGUgcHJvY2VzcydzIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuXHJcbiAqIHNlZSBbcHJvY2Vzcy5jd2RdKGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvcHJvY2Vzcy5odG1sI3Byb2Nlc3NfcHJvY2Vzc19jd2QpXHJcbiAqXHJcbiAqIEByZXR1cm4gICAgICB0aGUgcGF0aCB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSBvZiB0aGUgcHJvY2Vzc1xyXG4gKi9cclxuZnVuY3Rpb24gY3dkKCkge1xyXG4gICAgcmV0dXJuIHByb2Nlc3MuY3dkKCk7XHJcbn1cclxuZXhwb3J0cy5jd2QgPSBjd2Q7XHJcbmV4cG9ydHMuY2hlY2tQYXRoID0gaW0uX2NoZWNrUGF0aDtcclxuLyoqXHJcbiAqIENoYW5nZSB3b3JraW5nIGRpcmVjdG9yeS5cclxuICpcclxuICogQHBhcmFtICAgICBwYXRoICAgICAgbmV3IHdvcmtpbmcgZGlyZWN0b3J5IHBhdGhcclxuICogQHJldHVybnMgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBjZChwYXRoKSB7XHJcbiAgICBpZiAocGF0aCkge1xyXG4gICAgICAgIHNoZWxsLmNkKHBhdGgpO1xyXG4gICAgICAgIF9jaGVja1NoZWxsKCdjZCcpO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuY2QgPSBjZDtcclxuLyoqXHJcbiAqIENoYW5nZSB3b3JraW5nIGRpcmVjdG9yeSBhbmQgcHVzaCBpdCBvbiB0aGUgc3RhY2tcclxuICpcclxuICogQHBhcmFtICAgICBwYXRoICAgICAgbmV3IHdvcmtpbmcgZGlyZWN0b3J5IHBhdGhcclxuICogQHJldHVybnMgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBwdXNoZChwYXRoKSB7XHJcbiAgICBzaGVsbC5wdXNoZChwYXRoKTtcclxuICAgIF9jaGVja1NoZWxsKCdwdXNoZCcpO1xyXG59XHJcbmV4cG9ydHMucHVzaGQgPSBwdXNoZDtcclxuLyoqXHJcbiAqIENoYW5nZSB3b3JraW5nIGRpcmVjdG9yeSBiYWNrIHRvIHByZXZpb3VzbHkgcHVzaGVkIGRpcmVjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJucyAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHBvcGQoKSB7XHJcbiAgICBzaGVsbC5wb3BkKCk7XHJcbiAgICBfY2hlY2tTaGVsbCgncG9wZCcpO1xyXG59XHJcbmV4cG9ydHMucG9wZCA9IHBvcGQ7XHJcbi8qKlxyXG4gKiBNYWtlIGEgZGlyZWN0b3J5LiAgQ3JlYXRlcyB0aGUgZnVsbCBwYXRoIHdpdGggZm9sZGVycyBpbiBiZXR3ZWVuXHJcbiAqIFdpbGwgdGhyb3cgaWYgaXQgZmFpbHNcclxuICpcclxuICogQHBhcmFtICAgICBwICAgICAgIHBhdGggdG8gY3JlYXRlXHJcbiAqIEByZXR1cm5zICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gbWtkaXJQKHApIHtcclxuICAgIGlmICghcCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX1BhcmFtZXRlcklzUmVxdWlyZWQnLCAncCcpKTtcclxuICAgIH1cclxuICAgIC8vIGJ1aWxkIGEgc3RhY2sgb2YgZGlyZWN0b3JpZXMgdG8gY3JlYXRlXHJcbiAgICB2YXIgc3RhY2sgPSBbXTtcclxuICAgIHZhciB0ZXN0RGlyID0gcDtcclxuICAgIHdoaWxlICh0cnVlKSB7XHJcbiAgICAgICAgLy8gdmFsaWRhdGUgdGhlIGxvb3AgaXMgbm90IG91dCBvZiBjb250cm9sXHJcbiAgICAgICAgaWYgKHN0YWNrLmxlbmd0aCA+PSAocHJvY2Vzcy5lbnZbJ1RBU0tMSUJfVEVTVF9NS0RJUlBfRkFJTFNBRkUnXSB8fCAxMDAwKSkge1xyXG4gICAgICAgICAgICAvLyBsZXQgdGhlIGZyYW1ld29yayB0aHJvd1xyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdsb29wIGlzIG91dCBvZiBjb250cm9sJyk7XHJcbiAgICAgICAgICAgIGZzLm1rZGlyU3luYyhwKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBleHBvcnRzLmRlYnVnKFwidGVzdGluZyBkaXJlY3RvcnkgJ1wiICsgdGVzdERpciArIFwiJ1wiKTtcclxuICAgICAgICB2YXIgc3RhdHNfMSA9IHZvaWQgMDtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBzdGF0c18xID0gZnMuc3RhdFN5bmModGVzdERpcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgaWYgKGVyci5jb2RlID09ICdFTk9FTlQnKSB7XHJcbiAgICAgICAgICAgICAgICAvLyB2YWxpZGF0ZSB0aGUgZGlyZWN0b3J5IGlzIG5vdCB0aGUgZHJpdmUgcm9vdFxyXG4gICAgICAgICAgICAgICAgdmFyIHBhcmVudERpciA9IHBhdGguZGlybmFtZSh0ZXN0RGlyKTtcclxuICAgICAgICAgICAgICAgIGlmICh0ZXN0RGlyID09IHBhcmVudERpcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX01rZGlyRmFpbGVkSW52YWxpZERyaXZlUm9vdCcsIHAsIHRlc3REaXIpKTsgLy8gVW5hYmxlIHRvIGNyZWF0ZSBkaXJlY3RvcnkgJ3twfScuIFJvb3QgZGlyZWN0b3J5IGRvZXMgbm90IGV4aXN0OiAne3Rlc3REaXJ9J1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gcHVzaCB0aGUgZGlyIGFuZCB0ZXN0IHRoZSBwYXJlbnRcclxuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2godGVzdERpcik7XHJcbiAgICAgICAgICAgICAgICB0ZXN0RGlyID0gcGFyZW50RGlyO1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoZXJyLmNvZGUgPT0gJ1VOS05PV04nKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9Na2RpckZhaWxlZEludmFsaWRTaGFyZScsIHAsIHRlc3REaXIpKTsgLy8gVW5hYmxlIHRvIGNyZWF0ZSBkaXJlY3RvcnkgJ3twfScuIFVuYWJsZSB0byB2ZXJpZnkgdGhlIGRpcmVjdG9yeSBleGlzdHM6ICd7dGVzdERpcn0nLiBJZiBkaXJlY3RvcnkgaXMgYSBmaWxlIHNoYXJlLCBwbGVhc2UgdmVyaWZ5IHRoZSBzaGFyZSBuYW1lIGlzIGNvcnJlY3QsIHRoZSBzaGFyZSBpcyBvbmxpbmUsIGFuZCB0aGUgY3VycmVudCBwcm9jZXNzIGhhcyBwZXJtaXNzaW9uIHRvIGFjY2VzcyB0aGUgc2hhcmUuXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFzdGF0c18xLmlzRGlyZWN0b3J5KCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfTWtkaXJGYWlsZWRGaWxlRXhpc3RzJywgcCwgdGVzdERpcikpOyAvLyBVbmFibGUgdG8gY3JlYXRlIGRpcmVjdG9yeSAne3B9Jy4gQ29uZmxpY3RpbmcgZmlsZSBleGlzdHM6ICd7dGVzdERpcn0nXHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHRlc3REaXIgZXhpc3RzXHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgICAvLyBjcmVhdGUgZWFjaCBkaXJlY3RvcnlcclxuICAgIHdoaWxlIChzdGFjay5sZW5ndGgpIHtcclxuICAgICAgICB2YXIgZGlyID0gc3RhY2sucG9wKCk7IC8vIG5vbi1udWxsIGJlY2F1c2UgYHN0YWNrLmxlbmd0aGAgd2FzIHRydXRoeVxyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoXCJta2RpciAnXCIgKyBkaXIgKyBcIidcIik7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgZnMubWtkaXJTeW5jKGRpcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfTWtkaXJGYWlsZWQnLCBwLCBlcnIubWVzc2FnZSkpOyAvLyBVbmFibGUgdG8gY3JlYXRlIGRpcmVjdG9yeSAne3B9Jy4ge2Vyci5tZXNzYWdlfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5leHBvcnRzLm1rZGlyUCA9IG1rZGlyUDtcclxuLyoqXHJcbiAqIFJlc29sdmVzIGEgc2VxdWVuY2Ugb2YgcGF0aHMgb3IgcGF0aCBzZWdtZW50cyBpbnRvIGFuIGFic29sdXRlIHBhdGguXHJcbiAqIENhbGxzIG5vZGUuanMgcGF0aC5yZXNvbHZlKClcclxuICogQWxsb3dzIEwwIHRlc3Rpbmcgd2l0aCBjb25zaXN0ZW50IHBhdGggZm9ybWF0cyBvbiBNYWMvTGludXggYW5kIFdpbmRvd3MgaW4gdGhlIG1vY2sgaW1wbGVtZW50YXRpb25cclxuICogQHBhcmFtIHBhdGhTZWdtZW50c1xyXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxyXG4gKi9cclxuZnVuY3Rpb24gcmVzb2x2ZSgpIHtcclxuICAgIHZhciBwYXRoU2VnbWVudHMgPSBbXTtcclxuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgcGF0aFNlZ21lbnRzW19pXSA9IGFyZ3VtZW50c1tfaV07XHJcbiAgICB9XHJcbiAgICB2YXIgYWJzb2x1dGVQYXRoID0gcGF0aC5yZXNvbHZlLmFwcGx5KHRoaXMsIHBhdGhTZWdtZW50cyk7XHJcbiAgICBleHBvcnRzLmRlYnVnKCdBYnNvbHV0ZSBwYXRoIGZvciBwYXRoU2VnbWVudHM6ICcgKyBwYXRoU2VnbWVudHMgKyAnID0gJyArIGFic29sdXRlUGF0aCk7XHJcbiAgICByZXR1cm4gYWJzb2x1dGVQYXRoO1xyXG59XHJcbmV4cG9ydHMucmVzb2x2ZSA9IHJlc29sdmU7XHJcbmV4cG9ydHMud2hpY2ggPSBpbS5fd2hpY2g7XHJcbi8qKlxyXG4gKiBSZXR1cm5zIGFycmF5IG9mIGZpbGVzIGluIHRoZSBnaXZlbiBwYXRoLCBvciBpbiBjdXJyZW50IGRpcmVjdG9yeSBpZiBubyBwYXRoIHByb3ZpZGVkLiAgU2VlIHNoZWxsanMubHNcclxuICogQHBhcmFtICB7c3RyaW5nfSAgIG9wdGlvbnMgIEF2YWlsYWJsZSBvcHRpb25zOiAtUiAocmVjdXJzaXZlKSwgLUEgKGFsbCBmaWxlcywgaW5jbHVkZSBmaWxlcyBiZWdpbm5pbmcgd2l0aCAuLCBleGNlcHQgZm9yIC4gYW5kIC4uKVxyXG4gKiBAcGFyYW0gIHtzdHJpbmdbXX0gcGF0aHMgICAgUGF0aHMgdG8gc2VhcmNoLlxyXG4gKiBAcmV0dXJuIHtzdHJpbmdbXX0gICAgICAgICAgQW4gYXJyYXkgb2YgZmlsZXMgaW4gdGhlIGdpdmVuIHBhdGgocykuXHJcbiAqL1xyXG5mdW5jdGlvbiBscyhvcHRpb25zLCBwYXRocykge1xyXG4gICAgaWYgKG9wdGlvbnMpIHtcclxuICAgICAgICByZXR1cm4gc2hlbGwubHMob3B0aW9ucywgcGF0aHMpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHNoZWxsLmxzKHBhdGhzKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLmxzID0gbHM7XHJcbi8qKlxyXG4gKiBDb3BpZXMgYSBmaWxlIG9yIGZvbGRlci5cclxuICpcclxuICogQHBhcmFtICAgICBzb3VyY2UgICAgIHNvdXJjZSBwYXRoXHJcbiAqIEBwYXJhbSAgICAgZGVzdCAgICAgICBkZXN0aW5hdGlvbiBwYXRoXHJcbiAqIEBwYXJhbSAgICAgb3B0aW9ucyAgICBzdHJpbmcgLXIsIC1mIG9yIC1yZiBmb3IgcmVjdXJzaXZlIGFuZCBmb3JjZVxyXG4gKiBAcGFyYW0gICAgIGNvbnRpbnVlT25FcnJvciBvcHRpb25hbC4gd2hldGhlciB0byBjb250aW51ZSBvbiBlcnJvclxyXG4gKiBAcGFyYW0gICAgIHJldHJ5Q291bnQgb3B0aW9uYWwuIFJldHJ5IGNvdW50IHRvIGNvcHkgdGhlIGZpbGUuIEl0IG1pZ2h0IGhlbHAgdG8gcmVzb2x2ZSBpbnRlcm1pdHRlbnQgaXNzdWVzIGUuZy4gd2l0aCBVTkMgdGFyZ2V0IHBhdGhzIG9uIGEgcmVtb3RlIGhvc3QuXHJcbiAqL1xyXG5mdW5jdGlvbiBjcChzb3VyY2UsIGRlc3QsIG9wdGlvbnMsIGNvbnRpbnVlT25FcnJvciwgcmV0cnlDb3VudCkge1xyXG4gICAgaWYgKHJldHJ5Q291bnQgPT09IHZvaWQgMCkgeyByZXRyeUNvdW50ID0gMDsgfVxyXG4gICAgd2hpbGUgKHJldHJ5Q291bnQgPj0gMCkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBzaGVsbC5jcChvcHRpb25zLCBzb3VyY2UsIGRlc3QpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc2hlbGwuY3Aoc291cmNlLCBkZXN0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfY2hlY2tTaGVsbCgnY3AnLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBpZiAocmV0cnlDb3VudCA8PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29udGludWVPbkVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy53YXJuaW5nKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGV4cG9ydHMubG9jKCdMSUJfQ29weUZpbGVGYWlsZWQnLCByZXRyeUNvdW50KSk7XHJcbiAgICAgICAgICAgICAgICByZXRyeUNvdW50LS07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5jcCA9IGNwO1xyXG4vKipcclxuICogTW92ZXMgYSBwYXRoLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHNvdXJjZSAgICAgc291cmNlIHBhdGhcclxuICogQHBhcmFtICAgICBkZXN0ICAgICAgIGRlc3RpbmF0aW9uIHBhdGhcclxuICogQHBhcmFtICAgICBvcHRpb25zICAgIHN0cmluZyAtZiBvciAtbiBmb3IgZm9yY2UgYW5kIG5vIGNsb2JiZXJcclxuICogQHBhcmFtICAgICBjb250aW51ZU9uRXJyb3Igb3B0aW9uYWwuIHdoZXRoZXIgdG8gY29udGludWUgb24gZXJyb3JcclxuICovXHJcbmZ1bmN0aW9uIG12KHNvdXJjZSwgZGVzdCwgb3B0aW9ucywgY29udGludWVPbkVycm9yKSB7XHJcbiAgICBpZiAob3B0aW9ucykge1xyXG4gICAgICAgIHNoZWxsLm12KG9wdGlvbnMsIHNvdXJjZSwgZGVzdCk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBzaGVsbC5tdihzb3VyY2UsIGRlc3QpO1xyXG4gICAgfVxyXG4gICAgX2NoZWNrU2hlbGwoJ212JywgY29udGludWVPbkVycm9yKTtcclxufVxyXG5leHBvcnRzLm12ID0gbXY7XHJcbi8qKlxyXG4gKiBSZWN1cnNpdmVseSBmaW5kcyBhbGwgcGF0aHMgYSBnaXZlbiBwYXRoLiBSZXR1cm5zIGFuIGFycmF5IG9mIHBhdGhzLlxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIGZpbmRQYXRoICBwYXRoIHRvIHNlYXJjaFxyXG4gKiBAcGFyYW0gICAgIG9wdGlvbnMgICBvcHRpb25hbC4gZGVmYXVsdHMgdG8geyBmb2xsb3dTeW1ib2xpY0xpbmtzOiB0cnVlIH0uIGZvbGxvd2luZyBzb2Z0IGxpbmtzIGlzIGdlbmVyYWxseSBhcHByb3ByaWF0ZSB1bmxlc3MgZGVsZXRpbmcgZmlsZXMuXHJcbiAqIEByZXR1cm5zICAgc3RyaW5nW11cclxuICovXHJcbmZ1bmN0aW9uIGZpbmQoZmluZFBhdGgsIG9wdGlvbnMpIHtcclxuICAgIGlmICghZmluZFBhdGgpIHtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKCdubyBwYXRoIHNwZWNpZmllZCcpO1xyXG4gICAgICAgIHJldHVybiBbXTtcclxuICAgIH1cclxuICAgIC8vIG5vcm1hbGl6ZSB0aGUgcGF0aCwgb3RoZXJ3aXNlIHRoZSBmaXJzdCByZXN1bHQgaXMgaW5jb25zaXN0ZW50bHkgZm9ybWF0dGVkIGZyb20gdGhlIHJlc3Qgb2YgdGhlIHJlc3VsdHNcclxuICAgIC8vIGJlY2F1c2UgcGF0aC5qb2luKCkgcGVyZm9ybXMgbm9ybWFsaXphdGlvbi5cclxuICAgIGZpbmRQYXRoID0gcGF0aC5ub3JtYWxpemUoZmluZFBhdGgpO1xyXG4gICAgLy8gZGVidWcgdHJhY2UgdGhlIHBhcmFtZXRlcnNcclxuICAgIGV4cG9ydHMuZGVidWcoXCJmaW5kUGF0aDogJ1wiICsgZmluZFBhdGggKyBcIidcIik7XHJcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCBfZ2V0RGVmYXVsdEZpbmRPcHRpb25zKCk7XHJcbiAgICBfZGVidWdGaW5kT3B0aW9ucyhvcHRpb25zKTtcclxuICAgIC8vIHJldHVybiBlbXB0eSBpZiBub3QgZXhpc3RzXHJcbiAgICB0cnkge1xyXG4gICAgICAgIGZzLmxzdGF0U3luYyhmaW5kUGF0aCk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgaWYgKGVyci5jb2RlID09ICdFTk9FTlQnKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJzAgcmVzdWx0cycpO1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRocm93IGVycjtcclxuICAgIH1cclxuICAgIHRyeSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgICAgIC8vIHB1c2ggdGhlIGZpcnN0IGl0ZW1cclxuICAgICAgICB2YXIgc3RhY2sgPSBbbmV3IF9GaW5kSXRlbShmaW5kUGF0aCwgMSldO1xyXG4gICAgICAgIHZhciB0cmF2ZXJzYWxDaGFpbiA9IFtdOyAvLyB1c2VkIHRvIGRldGVjdCBjeWNsZXNcclxuICAgICAgICB2YXIgX2xvb3BfMSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gcG9wIHRoZSBuZXh0IGl0ZW0gYW5kIHB1c2ggdG8gdGhlIHJlc3VsdCBhcnJheVxyXG4gICAgICAgICAgICB2YXIgaXRlbSA9IHN0YWNrLnBvcCgpOyAvLyBub24tbnVsbCBiZWNhdXNlIGBzdGFjay5sZW5ndGhgIHdhcyB0cnV0aHlcclxuICAgICAgICAgICAgcmVzdWx0LnB1c2goaXRlbS5wYXRoKTtcclxuICAgICAgICAgICAgLy8gc3RhdCB0aGUgaXRlbS4gIHRoZSBzdGF0IGluZm8gaXMgdXNlZCBmdXJ0aGVyIGJlbG93IHRvIGRldGVybWluZSB3aGV0aGVyIHRvIHRyYXZlcnNlIGRlZXBlclxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBzdGF0IHJldHVybnMgaW5mbyBhYm91dCB0aGUgdGFyZ2V0IG9mIGEgc3ltbGluayAob3Igc3ltbGluayBjaGFpbiksXHJcbiAgICAgICAgICAgIC8vIGxzdGF0IHJldHVybnMgaW5mbyBhYm91dCBhIHN5bWxpbmsgaXRzZWxmXHJcbiAgICAgICAgICAgIHZhciBzdGF0c18yID0gdm9pZCAwO1xyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5mb2xsb3dTeW1ib2xpY0xpbmtzKSB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHVzZSBzdGF0IChmb2xsb3dpbmcgYWxsIHN5bWxpbmtzKVxyXG4gICAgICAgICAgICAgICAgICAgIHN0YXRzXzIgPSBmcy5zdGF0U3luYyhpdGVtLnBhdGgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PSAnRU5PRU5UJyAmJiBvcHRpb25zLmFsbG93QnJva2VuU3ltYm9saWNMaW5rcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBmYWxsYmFjayB0byBsc3RhdCAoYnJva2VuIHN5bWxpbmtzIGFsbG93ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRzXzIgPSBmcy5sc3RhdFN5bmMoaXRlbS5wYXRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcIiAgXCIgKyBpdGVtLnBhdGggKyBcIiAoYnJva2VuIHN5bWxpbmspXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zLmZvbGxvd1NwZWNpZmllZFN5bWJvbGljTGluayAmJiByZXN1bHQubGVuZ3RoID09IDEpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdXNlIHN0YXQgKGZvbGxvd2luZyBzeW1saW5rcyBmb3IgdGhlIHNwZWNpZmllZCBwYXRoIGFuZCB0aGlzIGlzIHRoZSBzcGVjaWZpZWQgcGF0aClcclxuICAgICAgICAgICAgICAgICAgICBzdGF0c18yID0gZnMuc3RhdFN5bmMoaXRlbS5wYXRoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gJ0VOT0VOVCcgJiYgb3B0aW9ucy5hbGxvd0Jyb2tlblN5bWJvbGljTGlua3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmFsbGJhY2sgdG8gbHN0YXQgKGJyb2tlbiBzeW1saW5rcyBhbGxvd2VkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0c18yID0gZnMubHN0YXRTeW5jKGl0ZW0ucGF0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCIgIFwiICsgaXRlbS5wYXRoICsgXCIgKGJyb2tlbiBzeW1saW5rKVwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyB1c2UgbHN0YXQgKG5vdCBmb2xsb3dpbmcgc3ltbGlua3MpXHJcbiAgICAgICAgICAgICAgICBzdGF0c18yID0gZnMubHN0YXRTeW5jKGl0ZW0ucGF0aCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gbm90ZSwgaXNEaXJlY3RvcnkoKSByZXR1cm5zIGZhbHNlIGZvciB0aGUgbHN0YXQgb2YgYSBzeW1saW5rXHJcbiAgICAgICAgICAgIGlmIChzdGF0c18yLmlzRGlyZWN0b3J5KCkpIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCIgIFwiICsgaXRlbS5wYXRoICsgXCIgKGRpcmVjdG9yeSlcIik7XHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5mb2xsb3dTeW1ib2xpY0xpbmtzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSByZWFscGF0aFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWFsUGF0aF8xID0gZnMucmVhbHBhdGhTeW5jKGl0ZW0ucGF0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZml4dXAgdGhlIHRyYXZlcnNhbCBjaGFpbiB0byBtYXRjaCB0aGUgaXRlbSBsZXZlbFxyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cmF2ZXJzYWxDaGFpbi5sZW5ndGggPj0gaXRlbS5sZXZlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxDaGFpbi5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGVzdCBmb3IgYSBjeWNsZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0cmF2ZXJzYWxDaGFpbi5zb21lKGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ID09IHJlYWxQYXRoXzE7IH0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJyAgICBjeWNsZSBkZXRlY3RlZCcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJjb250aW51ZVwiO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgdGhlIHRyYXZlcnNhbCBjaGFpblxyXG4gICAgICAgICAgICAgICAgICAgIHRyYXZlcnNhbENoYWluLnB1c2gocmVhbFBhdGhfMSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBwdXNoIHRoZSBjaGlsZCBpdGVtcyBpbiByZXZlcnNlIG9udG8gdGhlIHN0YWNrXHJcbiAgICAgICAgICAgICAgICB2YXIgY2hpbGRMZXZlbF8xID0gaXRlbS5sZXZlbCArIDE7XHJcbiAgICAgICAgICAgICAgICB2YXIgY2hpbGRJdGVtcyA9IGZzLnJlYWRkaXJTeW5jKGl0ZW0ucGF0aClcclxuICAgICAgICAgICAgICAgICAgICAubWFwKGZ1bmN0aW9uIChjaGlsZE5hbWUpIHsgcmV0dXJuIG5ldyBfRmluZEl0ZW0ocGF0aC5qb2luKGl0ZW0ucGF0aCwgY2hpbGROYW1lKSwgY2hpbGRMZXZlbF8xKTsgfSk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gY2hpbGRJdGVtcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrLnB1c2goY2hpbGRJdGVtc1tpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwiICBcIiArIGl0ZW0ucGF0aCArIFwiIChmaWxlKVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBfbG9vcF8xKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGV4cG9ydHMuZGVidWcocmVzdWx0Lmxlbmd0aCArIFwiIHJlc3VsdHNcIik7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAnZmluZCcsIGVyci5tZXNzYWdlKSk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5maW5kID0gZmluZDtcclxudmFyIF9GaW5kSXRlbSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIF9GaW5kSXRlbShwYXRoLCBsZXZlbCkge1xyXG4gICAgICAgIHRoaXMucGF0aCA9IHBhdGg7XHJcbiAgICAgICAgdGhpcy5sZXZlbCA9IGxldmVsO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9GaW5kSXRlbTtcclxufSgpKTtcclxuZnVuY3Rpb24gX2RlYnVnRmluZE9wdGlvbnMob3B0aW9ucykge1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcImZpbmRPcHRpb25zLmFsbG93QnJva2VuU3ltYm9saWNMaW5rczogJ1wiICsgb3B0aW9ucy5hbGxvd0Jyb2tlblN5bWJvbGljTGlua3MgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwiZmluZE9wdGlvbnMuZm9sbG93U3BlY2lmaWVkU3ltYm9saWNMaW5rOiAnXCIgKyBvcHRpb25zLmZvbGxvd1NwZWNpZmllZFN5bWJvbGljTGluayArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJmaW5kT3B0aW9ucy5mb2xsb3dTeW1ib2xpY0xpbmtzOiAnXCIgKyBvcHRpb25zLmZvbGxvd1N5bWJvbGljTGlua3MgKyBcIidcIik7XHJcbn1cclxuZnVuY3Rpb24gX2dldERlZmF1bHRGaW5kT3B0aW9ucygpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgYWxsb3dCcm9rZW5TeW1ib2xpY0xpbmtzOiBmYWxzZSxcclxuICAgICAgICBmb2xsb3dTcGVjaWZpZWRTeW1ib2xpY0xpbms6IHRydWUsXHJcbiAgICAgICAgZm9sbG93U3ltYm9saWNMaW5rczogdHJ1ZVxyXG4gICAgfTtcclxufVxyXG4vKipcclxuICogUHJlZmVyIHRsLmZpbmQoKSBhbmQgdGwubWF0Y2goKSBpbnN0ZWFkLiBUaGlzIGZ1bmN0aW9uIGlzIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XHJcbiAqIHdoZW4gcG9ydGluZyB0YXNrcyB0byBOb2RlIGZyb20gdGhlIFBvd2VyU2hlbGwgb3IgUG93ZXJTaGVsbDMgZXhlY3V0aW9uIGhhbmRsZXIuXHJcbiAqXHJcbiAqIEBwYXJhbSAgICByb290RGlyZWN0b3J5ICAgICAgcGF0aCB0byByb290IHVucm9vdGVkIHBhdHRlcm5zIHdpdGhcclxuICogQHBhcmFtICAgIHBhdHRlcm4gICAgICAgICAgICBpbmNsdWRlIGFuZCBleGNsdWRlIHBhdHRlcm5zXHJcbiAqIEBwYXJhbSAgICBpbmNsdWRlRmlsZXMgICAgICAgd2hldGhlciB0byBpbmNsdWRlIGZpbGVzIGluIHRoZSByZXN1bHQuIGRlZmF1bHRzIHRvIHRydWUgd2hlbiBpbmNsdWRlRmlsZXMgYW5kIGluY2x1ZGVEaXJlY3RvcmllcyBhcmUgYm90aCBmYWxzZVxyXG4gKiBAcGFyYW0gICAgaW5jbHVkZURpcmVjdG9yaWVzIHdoZXRoZXIgdG8gaW5jbHVkZSBkaXJlY3RvcmllcyBpbiB0aGUgcmVzdWx0XHJcbiAqIEByZXR1cm5zICBzdHJpbmdbXVxyXG4gKi9cclxuZnVuY3Rpb24gbGVnYWN5RmluZEZpbGVzKHJvb3REaXJlY3RvcnksIHBhdHRlcm4sIGluY2x1ZGVGaWxlcywgaW5jbHVkZURpcmVjdG9yaWVzKSB7XHJcbiAgICBpZiAoIXBhdHRlcm4pIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhdHRlcm4gcGFyYW1ldGVyIGNhbm5vdCBiZSBlbXB0eScpO1xyXG4gICAgfVxyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcImxlZ2FjeUZpbmRGaWxlcyByb290RGlyZWN0b3J5OiAnXCIgKyByb290RGlyZWN0b3J5ICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcInBhdHRlcm46ICdcIiArIHBhdHRlcm4gKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwiaW5jbHVkZUZpbGVzOiAnXCIgKyBpbmNsdWRlRmlsZXMgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwiaW5jbHVkZURpcmVjdG9yaWVzOiAnXCIgKyBpbmNsdWRlRGlyZWN0b3JpZXMgKyBcIidcIik7XHJcbiAgICBpZiAoIWluY2x1ZGVGaWxlcyAmJiAhaW5jbHVkZURpcmVjdG9yaWVzKSB7XHJcbiAgICAgICAgaW5jbHVkZUZpbGVzID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIC8vIG9yZ2FuaXplIHRoZSBwYXR0ZXJucyBpbnRvIGluY2x1ZGUgcGF0dGVybnMgYW5kIGV4Y2x1ZGUgcGF0dGVybnNcclxuICAgIHZhciBpbmNsdWRlUGF0dGVybnMgPSBbXTtcclxuICAgIHZhciBleGNsdWRlUGF0dGVybnMgPSBbXTtcclxuICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnJlcGxhY2UoLzs7L2csICdcXDAnKTtcclxuICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBwYXR0ZXJuLnNwbGl0KCc7Jyk7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgdmFyIHBhdCA9IF9hW19pXTtcclxuICAgICAgICBpZiAoIXBhdCkge1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcGF0ID0gcGF0LnJlcGxhY2UoL1xcMC9nLCAnOycpO1xyXG4gICAgICAgIC8vIGRldGVybWluZSB3aGV0aGVyIGluY2x1ZGUgcGF0dGVybiBhbmQgcmVtb3ZlIGFueSBpbmNsdWRlL2V4Y2x1ZGUgcHJlZml4LlxyXG4gICAgICAgIC8vIGluY2x1ZGUgcGF0dGVybnMgc3RhcnQgd2l0aCArOiBvciBhbnl0aGluZyBvdGhlciB0aGFuIC06XHJcbiAgICAgICAgLy8gZXhjbHVkZSBwYXR0ZXJucyBzdGFydCB3aXRoIC06XHJcbiAgICAgICAgdmFyIGlzSW5jbHVkZVBhdHRlcm4gPSB2b2lkIDA7XHJcbiAgICAgICAgaWYgKGltLl9zdGFydHNXaXRoKHBhdCwgJys6JykpIHtcclxuICAgICAgICAgICAgcGF0ID0gcGF0LnN1YnN0cmluZygyKTtcclxuICAgICAgICAgICAgaXNJbmNsdWRlUGF0dGVybiA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGltLl9zdGFydHNXaXRoKHBhdCwgJy06JykpIHtcclxuICAgICAgICAgICAgcGF0ID0gcGF0LnN1YnN0cmluZygyKTtcclxuICAgICAgICAgICAgaXNJbmNsdWRlUGF0dGVybiA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaXNJbmNsdWRlUGF0dGVybiA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHZhbGlkYXRlIHBhdHRlcm4gZG9lcyBub3QgZW5kIHdpdGggYSBzbGFzaFxyXG4gICAgICAgIGlmIChpbS5fZW5kc1dpdGgocGF0LCAnLycpIHx8IChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgJiYgaW0uX2VuZHNXaXRoKHBhdCwgJ1xcXFwnKSkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfSW52YWxpZFBhdHRlcm4nLCBwYXQpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gcm9vdCB0aGUgcGF0dGVyblxyXG4gICAgICAgIGlmIChyb290RGlyZWN0b3J5ICYmICFwYXRoLmlzQWJzb2x1dGUocGF0KSkge1xyXG4gICAgICAgICAgICBwYXQgPSBwYXRoLmpvaW4ocm9vdERpcmVjdG9yeSwgcGF0KTtcclxuICAgICAgICAgICAgLy8gcmVtb3ZlIHRyYWlsaW5nIHNsYXNoIHNvbWV0aW1lcyBhZGRlZCBieSBwYXRoLmpvaW4oKSBvbiBXaW5kb3dzLCBlLmcuXHJcbiAgICAgICAgICAgIC8vICAgICAgcGF0aC5qb2luKCdcXFxcXFxcXGhlbGxvJywgJ3dvcmxkJykgPT4gJ1xcXFxcXFxcaGVsbG9cXFxcd29ybGRcXFxcJ1xyXG4gICAgICAgICAgICAvLyAgICAgIHBhdGguam9pbignLy9oZWxsbycsICd3b3JsZCcpID0+ICdcXFxcXFxcXGhlbGxvXFxcXHdvcmxkXFxcXCdcclxuICAgICAgICAgICAgaWYgKGltLl9lbmRzV2l0aChwYXQsICdcXFxcJykpIHtcclxuICAgICAgICAgICAgICAgIHBhdCA9IHBhdC5zdWJzdHJpbmcoMCwgcGF0Lmxlbmd0aCAtIDEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpc0luY2x1ZGVQYXR0ZXJuKSB7XHJcbiAgICAgICAgICAgIGluY2x1ZGVQYXR0ZXJucy5wdXNoKHBhdCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBleGNsdWRlUGF0dGVybnMucHVzaChpbS5fbGVnYWN5RmluZEZpbGVzX2NvbnZlcnRQYXR0ZXJuVG9SZWdFeHAocGF0KSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gZmluZCBhbmQgYXBwbHkgcGF0dGVybnNcclxuICAgIHZhciBjb3VudCA9IDA7XHJcbiAgICB2YXIgcmVzdWx0ID0gX2xlZ2FjeUZpbmRGaWxlc19nZXRNYXRjaGluZ0l0ZW1zKGluY2x1ZGVQYXR0ZXJucywgZXhjbHVkZVBhdHRlcm5zLCAhIWluY2x1ZGVGaWxlcywgISFpbmNsdWRlRGlyZWN0b3JpZXMpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZygnYWxsIG1hdGNoZXM6Jyk7XHJcbiAgICBmb3IgKHZhciBfYiA9IDAsIHJlc3VsdF8xID0gcmVzdWx0OyBfYiA8IHJlc3VsdF8xLmxlbmd0aDsgX2IrKykge1xyXG4gICAgICAgIHZhciByZXN1bHRJdGVtID0gcmVzdWx0XzFbX2JdO1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoJyAnICsgcmVzdWx0SXRlbSk7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKCd0b3RhbCBtYXRjaGVkOiAnICsgcmVzdWx0Lmxlbmd0aCk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcbmV4cG9ydHMubGVnYWN5RmluZEZpbGVzID0gbGVnYWN5RmluZEZpbGVzO1xyXG5mdW5jdGlvbiBfbGVnYWN5RmluZEZpbGVzX2dldE1hdGNoaW5nSXRlbXMoaW5jbHVkZVBhdHRlcm5zLCBleGNsdWRlUGF0dGVybnMsIGluY2x1ZGVGaWxlcywgaW5jbHVkZURpcmVjdG9yaWVzKSB7XHJcbiAgICBleHBvcnRzLmRlYnVnKCdnZXRNYXRjaGluZ0l0ZW1zKCknKTtcclxuICAgIGZvciAodmFyIF9pID0gMCwgaW5jbHVkZVBhdHRlcm5zXzEgPSBpbmNsdWRlUGF0dGVybnM7IF9pIDwgaW5jbHVkZVBhdHRlcm5zXzEubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBpbmNsdWRlUGF0dGVybnNfMVtfaV07XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcImluY2x1ZGVQYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuICsgXCInXCIpO1xyXG4gICAgfVxyXG4gICAgZm9yICh2YXIgX2EgPSAwLCBleGNsdWRlUGF0dGVybnNfMSA9IGV4Y2x1ZGVQYXR0ZXJuczsgX2EgPCBleGNsdWRlUGF0dGVybnNfMS5sZW5ndGg7IF9hKyspIHtcclxuICAgICAgICB2YXIgcGF0dGVybiA9IGV4Y2x1ZGVQYXR0ZXJuc18xW19hXTtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKFwiZXhjbHVkZVBhdHRlcm46IFwiICsgcGF0dGVybik7XHJcbiAgICB9XHJcbiAgICBleHBvcnRzLmRlYnVnKCdpbmNsdWRlRmlsZXM6ICcgKyBpbmNsdWRlRmlsZXMpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZygnaW5jbHVkZURpcmVjdG9yaWVzOiAnICsgaW5jbHVkZURpcmVjdG9yaWVzKTtcclxuICAgIHZhciBhbGxGaWxlcyA9IHt9O1xyXG4gICAgdmFyIF9sb29wXzIgPSBmdW5jdGlvbiAocGF0dGVybikge1xyXG4gICAgICAgIC8vIGRldGVybWluZSB0aGUgZGlyZWN0b3J5IHRvIHNlYXJjaFxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gbm90ZSwgZ2V0RGlyZWN0b3J5TmFtZSByZW1vdmVzIHJlZHVuZGFudCBwYXRoIHNlcGFyYXRvcnNcclxuICAgICAgICB2YXIgZmluZFBhdGggPSB2b2lkIDA7XHJcbiAgICAgICAgdmFyIHN0YXJJbmRleCA9IHBhdHRlcm4uaW5kZXhPZignKicpO1xyXG4gICAgICAgIHZhciBxdWVzdGlvbkluZGV4ID0gcGF0dGVybi5pbmRleE9mKCc/Jyk7XHJcbiAgICAgICAgaWYgKHN0YXJJbmRleCA8IDAgJiYgcXVlc3Rpb25JbmRleCA8IDApIHtcclxuICAgICAgICAgICAgLy8gaWYgbm8gd2lsZGNhcmRzIGFyZSBmb3VuZCwgdXNlIHRoZSBkaXJlY3RvcnkgbmFtZSBwb3J0aW9uIG9mIHRoZSBwYXRoLlxyXG4gICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBkaXJlY3RvcnkgbmFtZSAoZmlsZSBuYW1lIG9ubHkgaW4gcGF0dGVybiBvciBkcml2ZSByb290KSxcclxuICAgICAgICAgICAgLy8gdGhpcyB3aWxsIHJldHVybiBlbXB0eSBzdHJpbmcuXHJcbiAgICAgICAgICAgIGZpbmRQYXRoID0gaW0uX2dldERpcmVjdG9yeU5hbWUocGF0dGVybik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBleHRyYWN0IHRoZSBkaXJlY3RvcnkgcHJpb3IgdG8gdGhlIGZpcnN0IHdpbGRjYXJkXHJcbiAgICAgICAgICAgIHZhciBpbmRleCA9IE1hdGgubWluKHN0YXJJbmRleCA+PSAwID8gc3RhckluZGV4IDogcXVlc3Rpb25JbmRleCwgcXVlc3Rpb25JbmRleCA+PSAwID8gcXVlc3Rpb25JbmRleCA6IHN0YXJJbmRleCk7XHJcbiAgICAgICAgICAgIGZpbmRQYXRoID0gaW0uX2dldERpcmVjdG9yeU5hbWUocGF0dGVybi5zdWJzdHJpbmcoMCwgaW5kZXgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gbm90ZSwgZHVlIHRvIHRoaXMgc2hvcnQtY2lyY3VpdCBhbmQgdGhlIGFib3ZlIHVzYWdlIG9mIGdldERpcmVjdG9yeU5hbWUsIHRoaXNcclxuICAgICAgICAvLyBmdW5jdGlvbiBoYXMgdGhlIHNhbWUgbGltaXRhdGlvbnMgcmVnYXJkaW5nIGRyaXZlIHJvb3RzIGFzIHRoZSBwb3dlcnNoZWxsXHJcbiAgICAgICAgLy8gaW1wbGVtZW50YXRpb24uXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBhbHNvIG5vdGUsIHNpbmNlIGdldERpcmVjdG9yeU5hbWUgZWxpbWluYXRlcyBzbGFzaCByZWR1bmRhbmNpZXMsIHNvbWUgYWRkaXRpb25hbFxyXG4gICAgICAgIC8vIHdvcmsgbWF5IGJlIHJlcXVpcmVkIGlmIHJlbW92YWwgb2YgdGhpcyBsaW1pdGF0aW9uIGlzIGF0dGVtcHRlZC5cclxuICAgICAgICBpZiAoIWZpbmRQYXRoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcImNvbnRpbnVlXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBwYXR0ZXJuUmVnZXggPSBpbS5fbGVnYWN5RmluZEZpbGVzX2NvbnZlcnRQYXR0ZXJuVG9SZWdFeHAocGF0dGVybik7XHJcbiAgICAgICAgLy8gZmluZCBmaWxlcy9kaXJlY3Rvcmllc1xyXG4gICAgICAgIHZhciBpdGVtcyA9IGZpbmQoZmluZFBhdGgsIHsgZm9sbG93U3ltYm9saWNMaW5rczogdHJ1ZSB9KVxyXG4gICAgICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgICAgICAgIGlmIChpbmNsdWRlRmlsZXMgJiYgaW5jbHVkZURpcmVjdG9yaWVzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgaXNEaXIgPSBmcy5zdGF0U3luYyhpdGVtKS5pc0RpcmVjdG9yeSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gKGluY2x1ZGVGaWxlcyAmJiAhaXNEaXIpIHx8IChpbmNsdWRlRGlyZWN0b3JpZXMgJiYgaXNEaXIpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgICAgICAgIHZhciBub3JtYWxpemVkUGF0aCA9IHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyA/IGl0ZW0ucmVwbGFjZSgvXFxcXC9nLCAnLycpIDogaXRlbTsgLy8gbm9ybWFsaXplIHNlcGFyYXRvcnNcclxuICAgICAgICAgICAgLy8gKiovdGltZXMvKiogd2lsbCBub3QgbWF0Y2ggQzovZnVuL3RpbWVzIGJlY2F1c2UgdGhlcmUgaXNuJ3QgYSB0cmFpbGluZyBzbGFzaFxyXG4gICAgICAgICAgICAvLyBzbyB0cnkgYm90aCBpZiBpbmNsdWRpbmcgZGlyZWN0b3JpZXNcclxuICAgICAgICAgICAgdmFyIGFsdGVybmF0ZVBhdGggPSBub3JtYWxpemVkUGF0aCArIFwiL1wiOyAvLyBwb3RlbnRpYWwgYnVnOiBpdCBsb29rcyBsaWtlIHRoaXMgd2lsbCByZXN1bHQgaW4gYSBmYWxzZVxyXG4gICAgICAgICAgICAvLyBwb3NpdGl2ZSBpZiB0aGUgaXRlbSBpcyBhIHJlZ3VsYXIgZmlsZSBhbmQgbm90IGEgZGlyZWN0b3J5XHJcbiAgICAgICAgICAgIHZhciBpc01hdGNoID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmIChwYXR0ZXJuUmVnZXgudGVzdChub3JtYWxpemVkUGF0aCkgfHwgKGluY2x1ZGVEaXJlY3RvcmllcyAmJiBwYXR0ZXJuUmVnZXgudGVzdChhbHRlcm5hdGVQYXRoKSkpIHtcclxuICAgICAgICAgICAgICAgIGlzTWF0Y2ggPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgLy8gdGVzdCB3aGV0aGVyIHRoZSBwYXRoIHNob3VsZCBiZSBleGNsdWRlZFxyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBleGNsdWRlUGF0dGVybnNfMiA9IGV4Y2x1ZGVQYXR0ZXJuczsgX2kgPCBleGNsdWRlUGF0dGVybnNfMi5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVnZXggPSBleGNsdWRlUGF0dGVybnNfMltfaV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ2V4LnRlc3Qobm9ybWFsaXplZFBhdGgpIHx8IChpbmNsdWRlRGlyZWN0b3JpZXMgJiYgcmVnZXgudGVzdChhbHRlcm5hdGVQYXRoKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXNNYXRjaCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGlzTWF0Y2gpIHtcclxuICAgICAgICAgICAgICAgIGFsbEZpbGVzW2l0ZW1dID0gaXRlbTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIGZvciAodmFyIF9iID0gMCwgaW5jbHVkZVBhdHRlcm5zXzIgPSBpbmNsdWRlUGF0dGVybnM7IF9iIDwgaW5jbHVkZVBhdHRlcm5zXzIubGVuZ3RoOyBfYisrKSB7XHJcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBpbmNsdWRlUGF0dGVybnNfMltfYl07XHJcbiAgICAgICAgX2xvb3BfMihwYXR0ZXJuKTtcclxuICAgIH1cclxuICAgIHJldHVybiBPYmplY3Qua2V5cyhhbGxGaWxlcykuc29ydCgpO1xyXG59XHJcbi8qKlxyXG4gKiBSZW1vdmUgYSBwYXRoIHJlY3Vyc2l2ZWx5IHdpdGggZm9yY2VcclxuICpcclxuICogQHBhcmFtICAgICBpbnB1dFBhdGggcGF0aCB0byByZW1vdmVcclxuICogQHRocm93cyAgICB3aGVuIHRoZSBmaWxlIG9yIGRpcmVjdG9yeSBleGlzdHMgYnV0IGNvdWxkIG5vdCBiZSBkZWxldGVkLlxyXG4gKi9cclxuZnVuY3Rpb24gcm1SRihpbnB1dFBhdGgpIHtcclxuICAgIGV4cG9ydHMuZGVidWcoJ3JtIC1yZiAnICsgaW5wdXRQYXRoKTtcclxuICAgIGlmIChnZXRQbGF0Zm9ybSgpID09IFBsYXRmb3JtLldpbmRvd3MpIHtcclxuICAgICAgICAvLyBOb2RlIGRvZXNuJ3QgcHJvdmlkZSBhIGRlbGV0ZSBvcGVyYXRpb24sIG9ubHkgYW4gdW5saW5rIGZ1bmN0aW9uLiBUaGlzIG1lYW5zIHRoYXQgaWYgdGhlIGZpbGUgaXMgYmVpbmcgdXNlZCBieSBhbm90aGVyXHJcbiAgICAgICAgLy8gcHJvZ3JhbSAoZS5nLiBhbnRpdmlydXMpLCBpdCB3b24ndCBiZSBkZWxldGVkLiBUbyBhZGRyZXNzIHRoaXMsIHdlIHNoZWxsIG91dCB0aGUgd29yayB0byByZC9kZWwuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGZzLnN0YXRTeW5jKGlucHV0UGF0aCkuaXNEaXJlY3RvcnkoKSkge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygncmVtb3ZpbmcgZGlyZWN0b3J5ICcgKyBpbnB1dFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgY2hpbGRQcm9jZXNzLmV4ZWNTeW5jKFwicmQgL3MgL3EgXFxcIlwiICsgaW5wdXRQYXRoICsgXCJcXFwiXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygncmVtb3ZpbmcgZmlsZSAnICsgaW5wdXRQYXRoKTtcclxuICAgICAgICAgICAgICAgIGNoaWxkUHJvY2Vzcy5leGVjU3luYyhcImRlbCAvZiAvYSBcXFwiXCIgKyBpbnB1dFBhdGggKyBcIlxcXCJcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAvLyBpZiB5b3UgdHJ5IHRvIGRlbGV0ZSBhIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0LCBkZXNpcmVkIHJlc3VsdCBpcyBhY2hpZXZlZFxyXG4gICAgICAgICAgICAvLyBvdGhlciBlcnJvcnMgYXJlIHZhbGlkXHJcbiAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPSAnRU5PRU5UJykge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMubG9jKCdMSUJfT3BlcmF0aW9uRmFpbGVkJywgJ3JtUkYnLCBlcnIubWVzc2FnZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFNoZWxsaW5nIG91dCBmYWlscyB0byByZW1vdmUgYSBzeW1saW5rIGZvbGRlciB3aXRoIG1pc3Npbmcgc291cmNlLCB0aGlzIHVubGluayBjYXRjaGVzIHRoYXRcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBmcy51bmxpbmtTeW5jKGlucHV0UGF0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgLy8gaWYgeW91IHRyeSB0byBkZWxldGUgYSBmaWxlIHRoYXQgZG9lc24ndCBleGlzdCwgZGVzaXJlZCByZXN1bHQgaXMgYWNoaWV2ZWRcclxuICAgICAgICAgICAgLy8gb3RoZXIgZXJyb3JzIGFyZSB2YWxpZFxyXG4gICAgICAgICAgICBpZiAoZXJyLmNvZGUgIT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmxvYygnTElCX09wZXJhdGlvbkZhaWxlZCcsICdybVJGJywgZXJyLm1lc3NhZ2UpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIGdldCB0aGUgbHN0YXRzIGluIG9yZGVyIHRvIHdvcmthcm91bmQgYSBidWcgaW4gc2hlbGxqc0AwLjMuMCB3aGVyZSBzeW1saW5rc1xyXG4gICAgICAgIC8vIHdpdGggbWlzc2luZyB0YXJnZXRzIGFyZSBub3QgaGFuZGxlZCBjb3JyZWN0bHkgYnkgXCJybSgnLXJmJywgcGF0aClcIlxyXG4gICAgICAgIHZhciBsc3RhdHMgPSB2b2lkIDA7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbHN0YXRzID0gZnMubHN0YXRTeW5jKGlucHV0UGF0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgLy8gaWYgeW91IHRyeSB0byBkZWxldGUgYSBmaWxlIHRoYXQgZG9lc24ndCBleGlzdCwgZGVzaXJlZCByZXN1bHQgaXMgYWNoaWV2ZWRcclxuICAgICAgICAgICAgLy8gb3RoZXIgZXJyb3JzIGFyZSB2YWxpZFxyXG4gICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAncm1SRicsIGVyci5tZXNzYWdlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChsc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdyZW1vdmluZyBkaXJlY3RvcnknKTtcclxuICAgICAgICAgICAgc2hlbGwucm0oJy1yZicsIGlucHV0UGF0aCk7XHJcbiAgICAgICAgICAgIHZhciBlcnJNc2cgPSBzaGVsbC5lcnJvcigpO1xyXG4gICAgICAgICAgICBpZiAoZXJyTXNnKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAncm1SRicsIGVyck1zZykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZygncmVtb3ZpbmcgZmlsZScpO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGZzLnVubGlua1N5bmMoaW5wdXRQYXRoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5sb2MoJ0xJQl9PcGVyYXRpb25GYWlsZWQnLCAncm1SRicsIGVyci5tZXNzYWdlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMucm1SRiA9IHJtUkY7XHJcbi8qKlxyXG4gKiBFeGVjIGEgdG9vbC4gIENvbnZlbmllbmNlIHdyYXBwZXIgb3ZlciBUb29sUnVubmVyIHRvIGV4ZWMgd2l0aCBhcmdzIGluIG9uZSBjYWxsLlxyXG4gKiBPdXRwdXQgd2lsbCBiZSBzdHJlYW1lZCB0byB0aGUgbGl2ZSBjb25zb2xlLlxyXG4gKiBSZXR1cm5zIHByb21pc2Ugd2l0aCByZXR1cm4gY29kZVxyXG4gKlxyXG4gKiBAcGFyYW0gICAgIHRvb2wgICAgIHBhdGggdG8gdG9vbCB0byBleGVjXHJcbiAqIEBwYXJhbSAgICAgYXJncyAgICAgYW4gYXJnIHN0cmluZyBvciBhcnJheSBvZiBhcmdzXHJcbiAqIEBwYXJhbSAgICAgb3B0aW9ucyAgb3B0aW9uYWwgZXhlYyBvcHRpb25zLiAgU2VlIElFeGVjT3B0aW9uc1xyXG4gKiBAcmV0dXJucyAgIG51bWJlclxyXG4gKi9cclxuZnVuY3Rpb24gZXhlYyh0b29sLCBhcmdzLCBvcHRpb25zKSB7XHJcbiAgICB2YXIgdHIgPSB0aGlzLnRvb2wodG9vbCk7XHJcbiAgICB0ci5vbignZGVidWcnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoZGF0YSk7XHJcbiAgICB9KTtcclxuICAgIGlmIChhcmdzKSB7XHJcbiAgICAgICAgaWYgKGFyZ3MgaW5zdGFuY2VvZiBBcnJheSkge1xyXG4gICAgICAgICAgICB0ci5hcmcoYXJncyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiAoYXJncykgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIHRyLmxpbmUoYXJncyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRyLmV4ZWMob3B0aW9ucyk7XHJcbn1cclxuZXhwb3J0cy5leGVjID0gZXhlYztcclxuLyoqXHJcbiAqIEV4ZWMgYSB0b29sIHN5bmNocm9ub3VzbHkuICBDb252ZW5pZW5jZSB3cmFwcGVyIG92ZXIgVG9vbFJ1bm5lciB0byBleGVjU3luYyB3aXRoIGFyZ3MgaW4gb25lIGNhbGwuXHJcbiAqIE91dHB1dCB3aWxsIGJlICpub3QqIGJlIHN0cmVhbWVkIHRvIHRoZSBsaXZlIGNvbnNvbGUuICBJdCB3aWxsIGJlIHJldHVybmVkIGFmdGVyIGV4ZWN1dGlvbiBpcyBjb21wbGV0ZS5cclxuICogQXBwcm9wcmlhdGUgZm9yIHNob3J0IHJ1bm5pbmcgdG9vbHNcclxuICogUmV0dXJucyBJRXhlY1Jlc3VsdCB3aXRoIG91dHB1dCBhbmQgcmV0dXJuIGNvZGVcclxuICpcclxuICogQHBhcmFtICAgICB0b29sICAgICBwYXRoIHRvIHRvb2wgdG8gZXhlY1xyXG4gKiBAcGFyYW0gICAgIGFyZ3MgICAgIGFuIGFyZyBzdHJpbmcgb3IgYXJyYXkgb2YgYXJnc1xyXG4gKiBAcGFyYW0gICAgIG9wdGlvbnMgIG9wdGlvbmFsIGV4ZWMgb3B0aW9ucy4gIFNlZSBJRXhlY1N5bmNPcHRpb25zXHJcbiAqIEByZXR1cm5zICAgSUV4ZWNTeW5jUmVzdWx0XHJcbiAqL1xyXG5mdW5jdGlvbiBleGVjU3luYyh0b29sLCBhcmdzLCBvcHRpb25zKSB7XHJcbiAgICB2YXIgdHIgPSB0aGlzLnRvb2wodG9vbCk7XHJcbiAgICB0ci5vbignZGVidWcnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgIGV4cG9ydHMuZGVidWcoZGF0YSk7XHJcbiAgICB9KTtcclxuICAgIGlmIChhcmdzKSB7XHJcbiAgICAgICAgaWYgKGFyZ3MgaW5zdGFuY2VvZiBBcnJheSkge1xyXG4gICAgICAgICAgICB0ci5hcmcoYXJncyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiAoYXJncykgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIHRyLmxpbmUoYXJncyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRyLmV4ZWNTeW5jKG9wdGlvbnMpO1xyXG59XHJcbmV4cG9ydHMuZXhlY1N5bmMgPSBleGVjU3luYztcclxuLyoqXHJcbiAqIENvbnZlbmllbmNlIGZhY3RvcnkgdG8gY3JlYXRlIGEgVG9vbFJ1bm5lci5cclxuICpcclxuICogQHBhcmFtICAgICB0b29sICAgICBwYXRoIHRvIHRvb2wgdG8gZXhlY1xyXG4gKiBAcmV0dXJucyAgIFRvb2xSdW5uZXJcclxuICovXHJcbmZ1bmN0aW9uIHRvb2wodG9vbCkge1xyXG4gICAgdmFyIHRyID0gbmV3IHRybS5Ub29sUnVubmVyKHRvb2wpO1xyXG4gICAgdHIub24oJ2RlYnVnJywgZnVuY3Rpb24gKG1lc3NhZ2UpIHtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKG1lc3NhZ2UpO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdHI7XHJcbn1cclxuZXhwb3J0cy50b29sID0gdG9vbDtcclxuLyoqXHJcbiAqIEFwcGxpZXMgZ2xvYiBwYXR0ZXJucyB0byBhIGxpc3Qgb2YgcGF0aHMuIFN1cHBvcnRzIGludGVybGVhdmVkIGV4Y2x1ZGUgcGF0dGVybnMuXHJcbiAqXHJcbiAqIEBwYXJhbSAgbGlzdCAgICAgICAgIGFycmF5IG9mIHBhdGhzXHJcbiAqIEBwYXJhbSAgcGF0dGVybnMgICAgIHBhdHRlcm5zIHRvIGFwcGx5LiBzdXBwb3J0cyBpbnRlcmxlYXZlZCBleGNsdWRlIHBhdHRlcm5zLlxyXG4gKiBAcGFyYW0gIHBhdHRlcm5Sb290ICBvcHRpb25hbC4gZGVmYXVsdCByb290IHRvIGFwcGx5IHRvIHVucm9vdGVkIHBhdHRlcm5zLiBub3QgYXBwbGllZCB0byBiYXNlbmFtZS1vbmx5IHBhdHRlcm5zIHdoZW4gbWF0Y2hCYXNlOnRydWUuXHJcbiAqIEBwYXJhbSAgb3B0aW9ucyAgICAgIG9wdGlvbmFsLiBkZWZhdWx0cyB0byB7IGRvdDogdHJ1ZSwgbm9icmFjZTogdHJ1ZSwgbm9jYXNlOiBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgfS5cclxuICovXHJcbmZ1bmN0aW9uIG1hdGNoKGxpc3QsIHBhdHRlcm5zLCBwYXR0ZXJuUm9vdCwgb3B0aW9ucykge1xyXG4gICAgLy8gdHJhY2UgcGFyYW1ldGVyc1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcInBhdHRlcm5Sb290OiAnXCIgKyBwYXR0ZXJuUm9vdCArIFwiJ1wiKTtcclxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IF9nZXREZWZhdWx0TWF0Y2hPcHRpb25zKCk7IC8vIGRlZmF1bHQgbWF0Y2ggb3B0aW9uc1xyXG4gICAgX2RlYnVnTWF0Y2hPcHRpb25zKG9wdGlvbnMpO1xyXG4gICAgLy8gY29udmVydCBwYXR0ZXJuIHRvIGFuIGFycmF5XHJcbiAgICBpZiAodHlwZW9mIHBhdHRlcm5zID09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgcGF0dGVybnMgPSBbcGF0dGVybnNdO1xyXG4gICAgfVxyXG4gICAgLy8gaGFzaHRhYmxlIHRvIGtlZXAgdHJhY2sgb2YgbWF0Y2hlc1xyXG4gICAgdmFyIG1hcCA9IHt9O1xyXG4gICAgdmFyIG9yaWdpbmFsT3B0aW9ucyA9IG9wdGlvbnM7XHJcbiAgICBmb3IgKHZhciBfaSA9IDAsIHBhdHRlcm5zXzEgPSBwYXR0ZXJuczsgX2kgPCBwYXR0ZXJuc18xLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgIHZhciBwYXR0ZXJuID0gcGF0dGVybnNfMVtfaV07XHJcbiAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcInBhdHRlcm46ICdcIiArIHBhdHRlcm4gKyBcIidcIik7XHJcbiAgICAgICAgLy8gdHJpbSBhbmQgc2tpcCBlbXB0eVxyXG4gICAgICAgIHBhdHRlcm4gPSAocGF0dGVybiB8fCAnJykudHJpbSgpO1xyXG4gICAgICAgIGlmICghcGF0dGVybikge1xyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdza2lwcGluZyBlbXB0eSBwYXR0ZXJuJyk7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBjbG9uZSBtYXRjaCBvcHRpb25zXHJcbiAgICAgICAgdmFyIG9wdGlvbnNfMSA9IGltLl9jbG9uZU1hdGNoT3B0aW9ucyhvcmlnaW5hbE9wdGlvbnMpO1xyXG4gICAgICAgIC8vIHNraXAgY29tbWVudHNcclxuICAgICAgICBpZiAoIW9wdGlvbnNfMS5ub2NvbW1lbnQgJiYgaW0uX3N0YXJ0c1dpdGgocGF0dGVybiwgJyMnKSkge1xyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdza2lwcGluZyBjb21tZW50Jyk7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBzZXQgbm9jb21tZW50IC0gYnJhY2UgZXhwYW5zaW9uIGNvdWxkIHJlc3VsdCBpbiBhIGxlYWRpbmcgJyMnXHJcbiAgICAgICAgb3B0aW9uc18xLm5vY29tbWVudCA9IHRydWU7XHJcbiAgICAgICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgcGF0dGVybiBpcyBpbmNsdWRlIG9yIGV4Y2x1ZGVcclxuICAgICAgICB2YXIgbmVnYXRlQ291bnQgPSAwO1xyXG4gICAgICAgIGlmICghb3B0aW9uc18xLm5vbmVnYXRlKSB7XHJcbiAgICAgICAgICAgIHdoaWxlIChwYXR0ZXJuLmNoYXJBdChuZWdhdGVDb3VudCkgPT0gJyEnKSB7XHJcbiAgICAgICAgICAgICAgICBuZWdhdGVDb3VudCsrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnN1YnN0cmluZyhuZWdhdGVDb3VudCk7IC8vIHRyaW0gbGVhZGluZyAnISdcclxuICAgICAgICAgICAgaWYgKG5lZ2F0ZUNvdW50KSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwidHJpbW1lZCBsZWFkaW5nICchJy4gcGF0dGVybjogJ1wiICsgcGF0dGVybiArIFwiJ1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaXNJbmNsdWRlUGF0dGVybiA9IG5lZ2F0ZUNvdW50ID09IDAgfHxcclxuICAgICAgICAgICAgKG5lZ2F0ZUNvdW50ICUgMiA9PSAwICYmICFvcHRpb25zXzEuZmxpcE5lZ2F0ZSkgfHxcclxuICAgICAgICAgICAgKG5lZ2F0ZUNvdW50ICUgMiA9PSAxICYmIG9wdGlvbnNfMS5mbGlwTmVnYXRlKTtcclxuICAgICAgICAvLyBzZXQgbm9uZWdhdGUgLSBicmFjZSBleHBhbnNpb24gY291bGQgcmVzdWx0IGluIGEgbGVhZGluZyAnISdcclxuICAgICAgICBvcHRpb25zXzEubm9uZWdhdGUgPSB0cnVlO1xyXG4gICAgICAgIG9wdGlvbnNfMS5mbGlwTmVnYXRlID0gZmFsc2U7XHJcbiAgICAgICAgLy8gZXhwYW5kIGJyYWNlcyAtIHJlcXVpcmVkIHRvIGFjY3VyYXRlbHkgcm9vdCBwYXR0ZXJuc1xyXG4gICAgICAgIHZhciBleHBhbmRlZCA9IHZvaWQgMDtcclxuICAgICAgICB2YXIgcHJlRXhwYW5kZWQgPSBwYXR0ZXJuO1xyXG4gICAgICAgIGlmIChvcHRpb25zXzEubm9icmFjZSkge1xyXG4gICAgICAgICAgICBleHBhbmRlZCA9IFtwYXR0ZXJuXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIGNvbnZlcnQgc2xhc2hlcyBvbiBXaW5kb3dzIGJlZm9yZSBjYWxsaW5nIGJyYWNlRXhwYW5kKCkuIHVuZm9ydHVuYXRlbHkgdGhpcyBtZWFucyBicmFjZXMgY2Fubm90XHJcbiAgICAgICAgICAgIC8vIGJlIGVzY2FwZWQgb24gV2luZG93cywgdGhpcyBsaW1pdGF0aW9uIGlzIGNvbnNpc3RlbnQgd2l0aCBjdXJyZW50IGxpbWl0YXRpb25zIG9mIG1pbmltYXRjaCAoMy4wLjMpLlxyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdleHBhbmRpbmcgYnJhY2VzJyk7XHJcbiAgICAgICAgICAgIHZhciBjb252ZXJ0ZWRQYXR0ZXJuID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybi5yZXBsYWNlKC9cXFxcL2csICcvJykgOiBwYXR0ZXJuO1xyXG4gICAgICAgICAgICBleHBhbmRlZCA9IG1pbmltYXRjaC5icmFjZUV4cGFuZChjb252ZXJ0ZWRQYXR0ZXJuKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gc2V0IG5vYnJhY2VcclxuICAgICAgICBvcHRpb25zXzEubm9icmFjZSA9IHRydWU7XHJcbiAgICAgICAgZm9yICh2YXIgX2EgPSAwLCBleHBhbmRlZF8xID0gZXhwYW5kZWQ7IF9hIDwgZXhwYW5kZWRfMS5sZW5ndGg7IF9hKyspIHtcclxuICAgICAgICAgICAgdmFyIHBhdHRlcm5fMSA9IGV4cGFuZGVkXzFbX2FdO1xyXG4gICAgICAgICAgICBpZiAoZXhwYW5kZWQubGVuZ3RoICE9IDEgfHwgcGF0dGVybl8xICE9IHByZUV4cGFuZGVkKSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwicGF0dGVybjogJ1wiICsgcGF0dGVybl8xICsgXCInXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHRyaW0gYW5kIHNraXAgZW1wdHlcclxuICAgICAgICAgICAgcGF0dGVybl8xID0gKHBhdHRlcm5fMSB8fCAnJykudHJpbSgpO1xyXG4gICAgICAgICAgICBpZiAoIXBhdHRlcm5fMSkge1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1Zygnc2tpcHBpbmcgZW1wdHkgcGF0dGVybicpO1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gcm9vdCB0aGUgcGF0dGVybiB3aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIHRydWU6XHJcbiAgICAgICAgICAgIGlmIChwYXR0ZXJuUm9vdCAmJiAvLyBwYXR0ZXJuUm9vdCBzdXBwbGllZFxyXG4gICAgICAgICAgICAgICAgIWltLl9pc1Jvb3RlZChwYXR0ZXJuXzEpICYmIC8vIEFORCBwYXR0ZXJuIG5vdCByb290ZWRcclxuICAgICAgICAgICAgICAgIC8vIEFORCBtYXRjaEJhc2U6ZmFsc2Ugb3Igbm90IGJhc2VuYW1lIG9ubHlcclxuICAgICAgICAgICAgICAgICghb3B0aW9uc18xLm1hdGNoQmFzZSB8fCAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybl8xLnJlcGxhY2UoL1xcXFwvZywgJy8nKSA6IHBhdHRlcm5fMSkuaW5kZXhPZignLycpID49IDApKSB7XHJcbiAgICAgICAgICAgICAgICBwYXR0ZXJuXzEgPSBpbS5fZW5zdXJlUm9vdGVkKHBhdHRlcm5Sb290LCBwYXR0ZXJuXzEpO1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhcInJvb3RlZCBwYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuXzEgKyBcIidcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGlzSW5jbHVkZVBhdHRlcm4pIHtcclxuICAgICAgICAgICAgICAgIC8vIGFwcGx5IHRoZSBwYXR0ZXJuXHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdhcHBseWluZyBpbmNsdWRlIHBhdHRlcm4gYWdhaW5zdCBvcmlnaW5hbCBsaXN0Jyk7XHJcbiAgICAgICAgICAgICAgICB2YXIgbWF0Y2hSZXN1bHRzID0gbWluaW1hdGNoLm1hdGNoKGxpc3QsIHBhdHRlcm5fMSwgb3B0aW9uc18xKTtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcobWF0Y2hSZXN1bHRzLmxlbmd0aCArICcgbWF0Y2hlcycpO1xyXG4gICAgICAgICAgICAgICAgLy8gdW5pb24gdGhlIHJlc3VsdHNcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9iID0gMCwgbWF0Y2hSZXN1bHRzXzEgPSBtYXRjaFJlc3VsdHM7IF9iIDwgbWF0Y2hSZXN1bHRzXzEubGVuZ3RoOyBfYisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0ID0gbWF0Y2hSZXN1bHRzXzFbX2JdO1xyXG4gICAgICAgICAgICAgICAgICAgIG1hcFttYXRjaFJlc3VsdF0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gYXBwbHkgdGhlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2FwcGx5aW5nIGV4Y2x1ZGUgcGF0dGVybiBhZ2FpbnN0IG9yaWdpbmFsIGxpc3QnKTtcclxuICAgICAgICAgICAgICAgIHZhciBtYXRjaFJlc3VsdHMgPSBtaW5pbWF0Y2gubWF0Y2gobGlzdCwgcGF0dGVybl8xLCBvcHRpb25zXzEpO1xyXG4gICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZyhtYXRjaFJlc3VsdHMubGVuZ3RoICsgJyBtYXRjaGVzJyk7XHJcbiAgICAgICAgICAgICAgICAvLyBzdWJzdHJhY3QgdGhlIHJlc3VsdHNcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9jID0gMCwgbWF0Y2hSZXN1bHRzXzIgPSBtYXRjaFJlc3VsdHM7IF9jIDwgbWF0Y2hSZXN1bHRzXzIubGVuZ3RoOyBfYysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0ID0gbWF0Y2hSZXN1bHRzXzJbX2NdO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBtYXBbbWF0Y2hSZXN1bHRdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gcmV0dXJuIGEgZmlsdGVyZWQgdmVyc2lvbiBvZiB0aGUgb3JpZ2luYWwgbGlzdCAocHJlc2VydmVzIG9yZGVyIGFuZCBwcmV2ZW50cyBkdXBsaWNhdGlvbilcclxuICAgIHZhciByZXN1bHQgPSBsaXN0LmZpbHRlcihmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gbWFwLmhhc093blByb3BlcnR5KGl0ZW0pOyB9KTtcclxuICAgIGV4cG9ydHMuZGVidWcocmVzdWx0Lmxlbmd0aCArICcgZmluYWwgcmVzdWx0cycpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5leHBvcnRzLm1hdGNoID0gbWF0Y2g7XHJcbi8qKlxyXG4gKiBGaWx0ZXIgdG8gYXBwbHkgZ2xvYiBwYXR0ZXJuc1xyXG4gKlxyXG4gKiBAcGFyYW0gIHBhdHRlcm4gIHBhdHRlcm4gdG8gYXBwbHlcclxuICogQHBhcmFtICBvcHRpb25zICBvcHRpb25hbC4gZGVmYXVsdHMgdG8geyBkb3Q6IHRydWUsIG5vYnJhY2U6IHRydWUsIG5vY2FzZTogcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInIH0uXHJcbiAqL1xyXG5mdW5jdGlvbiBmaWx0ZXIocGF0dGVybiwgb3B0aW9ucykge1xyXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwgX2dldERlZmF1bHRNYXRjaE9wdGlvbnMoKTtcclxuICAgIHJldHVybiBtaW5pbWF0Y2guZmlsdGVyKHBhdHRlcm4sIG9wdGlvbnMpO1xyXG59XHJcbmV4cG9ydHMuZmlsdGVyID0gZmlsdGVyO1xyXG5mdW5jdGlvbiBfZGVidWdNYXRjaE9wdGlvbnMob3B0aW9ucykge1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5kZWJ1ZzogJ1wiICsgb3B0aW9ucy5kZWJ1ZyArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJtYXRjaE9wdGlvbnMubm9icmFjZTogJ1wiICsgb3B0aW9ucy5ub2JyYWNlICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub2dsb2JzdGFyOiAnXCIgKyBvcHRpb25zLm5vZ2xvYnN0YXIgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLmRvdDogJ1wiICsgb3B0aW9ucy5kb3QgKyBcIidcIik7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwibWF0Y2hPcHRpb25zLm5vZXh0OiAnXCIgKyBvcHRpb25zLm5vZXh0ICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub2Nhc2U6ICdcIiArIG9wdGlvbnMubm9jYXNlICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub251bGw6ICdcIiArIG9wdGlvbnMubm9udWxsICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5tYXRjaEJhc2U6ICdcIiArIG9wdGlvbnMubWF0Y2hCYXNlICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub2NvbW1lbnQ6ICdcIiArIG9wdGlvbnMubm9jb21tZW50ICsgXCInXCIpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhcIm1hdGNoT3B0aW9ucy5ub25lZ2F0ZTogJ1wiICsgb3B0aW9ucy5ub25lZ2F0ZSArIFwiJ1wiKTtcclxuICAgIGV4cG9ydHMuZGVidWcoXCJtYXRjaE9wdGlvbnMuZmxpcE5lZ2F0ZTogJ1wiICsgb3B0aW9ucy5mbGlwTmVnYXRlICsgXCInXCIpO1xyXG59XHJcbmZ1bmN0aW9uIF9nZXREZWZhdWx0TWF0Y2hPcHRpb25zKCkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBkZWJ1ZzogZmFsc2UsXHJcbiAgICAgICAgbm9icmFjZTogdHJ1ZSxcclxuICAgICAgICBub2dsb2JzdGFyOiBmYWxzZSxcclxuICAgICAgICBkb3Q6IHRydWUsXHJcbiAgICAgICAgbm9leHQ6IGZhbHNlLFxyXG4gICAgICAgIG5vY2FzZTogcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInLFxyXG4gICAgICAgIG5vbnVsbDogZmFsc2UsXHJcbiAgICAgICAgbWF0Y2hCYXNlOiBmYWxzZSxcclxuICAgICAgICBub2NvbW1lbnQ6IGZhbHNlLFxyXG4gICAgICAgIG5vbmVnYXRlOiBmYWxzZSxcclxuICAgICAgICBmbGlwTmVnYXRlOiBmYWxzZVxyXG4gICAgfTtcclxufVxyXG4vKipcclxuICogRGV0ZXJtaW5lcyB0aGUgZmluZCByb290IGZyb20gYSBsaXN0IG9mIHBhdHRlcm5zLiBQZXJmb3JtcyB0aGUgZmluZCBhbmQgdGhlbiBhcHBsaWVzIHRoZSBnbG9iIHBhdHRlcm5zLlxyXG4gKiBTdXBwb3J0cyBpbnRlcmxlYXZlZCBleGNsdWRlIHBhdHRlcm5zLiBVbnJvb3RlZCBwYXR0ZXJucyBhcmUgcm9vdGVkIHVzaW5nIGRlZmF1bHRSb290LCB1bmxlc3NcclxuICogbWF0Y2hPcHRpb25zLm1hdGNoQmFzZSBpcyBzcGVjaWZpZWQgYW5kIHRoZSBwYXR0ZXJuIGlzIGEgYmFzZW5hbWUgb25seS4gRm9yIG1hdGNoQmFzZSBjYXNlcywgdGhlXHJcbiAqIGRlZmF1bHRSb290IGlzIHVzZWQgYXMgdGhlIGZpbmQgcm9vdC5cclxuICpcclxuICogQHBhcmFtICBkZWZhdWx0Um9vdCAgIGRlZmF1bHQgcGF0aCB0byByb290IHVucm9vdGVkIHBhdHRlcm5zLiBmYWxscyBiYWNrIHRvIFN5c3RlbS5EZWZhdWx0V29ya2luZ0RpcmVjdG9yeSBvciBwcm9jZXNzLmN3ZCgpLlxyXG4gKiBAcGFyYW0gIHBhdHRlcm5zICAgICAgcGF0dGVybiBvciBhcnJheSBvZiBwYXR0ZXJucyB0byBhcHBseVxyXG4gKiBAcGFyYW0gIGZpbmRPcHRpb25zICAgZGVmYXVsdHMgdG8geyBmb2xsb3dTeW1ib2xpY0xpbmtzOiB0cnVlIH0uIGZvbGxvd2luZyBzb2Z0IGxpbmtzIGlzIGdlbmVyYWxseSBhcHByb3ByaWF0ZSB1bmxlc3MgZGVsZXRpbmcgZmlsZXMuXHJcbiAqIEBwYXJhbSAgbWF0Y2hPcHRpb25zICBkZWZhdWx0cyB0byB7IGRvdDogdHJ1ZSwgbm9icmFjZTogdHJ1ZSwgbm9jYXNlOiBwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicgfVxyXG4gKi9cclxuZnVuY3Rpb24gZmluZE1hdGNoKGRlZmF1bHRSb290LCBwYXR0ZXJucywgZmluZE9wdGlvbnMsIG1hdGNoT3B0aW9ucykge1xyXG4gICAgLy8gYXBwbHkgZGVmYXVsdHMgZm9yIHBhcmFtZXRlcnMgYW5kIHRyYWNlXHJcbiAgICBkZWZhdWx0Um9vdCA9IGRlZmF1bHRSb290IHx8IHRoaXMuZ2V0VmFyaWFibGUoJ3N5c3RlbS5kZWZhdWx0V29ya2luZ0RpcmVjdG9yeScpIHx8IHByb2Nlc3MuY3dkKCk7XHJcbiAgICBleHBvcnRzLmRlYnVnKFwiZGVmYXVsdFJvb3Q6ICdcIiArIGRlZmF1bHRSb290ICsgXCInXCIpO1xyXG4gICAgcGF0dGVybnMgPSBwYXR0ZXJucyB8fCBbXTtcclxuICAgIHBhdHRlcm5zID0gdHlwZW9mIHBhdHRlcm5zID09ICdzdHJpbmcnID8gW3BhdHRlcm5zXSA6IHBhdHRlcm5zO1xyXG4gICAgZmluZE9wdGlvbnMgPSBmaW5kT3B0aW9ucyB8fCBfZ2V0RGVmYXVsdEZpbmRPcHRpb25zKCk7XHJcbiAgICBfZGVidWdGaW5kT3B0aW9ucyhmaW5kT3B0aW9ucyk7XHJcbiAgICBtYXRjaE9wdGlvbnMgPSBtYXRjaE9wdGlvbnMgfHwgX2dldERlZmF1bHRNYXRjaE9wdGlvbnMoKTtcclxuICAgIF9kZWJ1Z01hdGNoT3B0aW9ucyhtYXRjaE9wdGlvbnMpO1xyXG4gICAgLy8gbm9ybWFsaXplIHNsYXNoZXMgZm9yIHJvb3QgZGlyXHJcbiAgICBkZWZhdWx0Um9vdCA9IGltLl9ub3JtYWxpemVTZXBhcmF0b3JzKGRlZmF1bHRSb290KTtcclxuICAgIHZhciByZXN1bHRzID0ge307XHJcbiAgICB2YXIgb3JpZ2luYWxNYXRjaE9wdGlvbnMgPSBtYXRjaE9wdGlvbnM7XHJcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gKHBhdHRlcm5zIHx8IFtdKTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICB2YXIgcGF0dGVybiA9IF9hW19pXTtcclxuICAgICAgICBleHBvcnRzLmRlYnVnKFwicGF0dGVybjogJ1wiICsgcGF0dGVybiArIFwiJ1wiKTtcclxuICAgICAgICAvLyB0cmltIGFuZCBza2lwIGVtcHR5XHJcbiAgICAgICAgcGF0dGVybiA9IChwYXR0ZXJuIHx8ICcnKS50cmltKCk7XHJcbiAgICAgICAgaWYgKCFwYXR0ZXJuKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3NraXBwaW5nIGVtcHR5IHBhdHRlcm4nKTtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNsb25lIG1hdGNoIG9wdGlvbnNcclxuICAgICAgICB2YXIgbWF0Y2hPcHRpb25zXzEgPSBpbS5fY2xvbmVNYXRjaE9wdGlvbnMob3JpZ2luYWxNYXRjaE9wdGlvbnMpO1xyXG4gICAgICAgIC8vIHNraXAgY29tbWVudHNcclxuICAgICAgICBpZiAoIW1hdGNoT3B0aW9uc18xLm5vY29tbWVudCAmJiBpbS5fc3RhcnRzV2l0aChwYXR0ZXJuLCAnIycpKSB7XHJcbiAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3NraXBwaW5nIGNvbW1lbnQnKTtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNldCBub2NvbW1lbnQgLSBicmFjZSBleHBhbnNpb24gY291bGQgcmVzdWx0IGluIGEgbGVhZGluZyAnIydcclxuICAgICAgICBtYXRjaE9wdGlvbnNfMS5ub2NvbW1lbnQgPSB0cnVlO1xyXG4gICAgICAgIC8vIGRldGVybWluZSB3aGV0aGVyIHBhdHRlcm4gaXMgaW5jbHVkZSBvciBleGNsdWRlXHJcbiAgICAgICAgdmFyIG5lZ2F0ZUNvdW50ID0gMDtcclxuICAgICAgICBpZiAoIW1hdGNoT3B0aW9uc18xLm5vbmVnYXRlKSB7XHJcbiAgICAgICAgICAgIHdoaWxlIChwYXR0ZXJuLmNoYXJBdChuZWdhdGVDb3VudCkgPT0gJyEnKSB7XHJcbiAgICAgICAgICAgICAgICBuZWdhdGVDb3VudCsrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnN1YnN0cmluZyhuZWdhdGVDb3VudCk7IC8vIHRyaW0gbGVhZGluZyAnISdcclxuICAgICAgICAgICAgaWYgKG5lZ2F0ZUNvdW50KSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwidHJpbW1lZCBsZWFkaW5nICchJy4gcGF0dGVybjogJ1wiICsgcGF0dGVybiArIFwiJ1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaXNJbmNsdWRlUGF0dGVybiA9IG5lZ2F0ZUNvdW50ID09IDAgfHxcclxuICAgICAgICAgICAgKG5lZ2F0ZUNvdW50ICUgMiA9PSAwICYmICFtYXRjaE9wdGlvbnNfMS5mbGlwTmVnYXRlKSB8fFxyXG4gICAgICAgICAgICAobmVnYXRlQ291bnQgJSAyID09IDEgJiYgbWF0Y2hPcHRpb25zXzEuZmxpcE5lZ2F0ZSk7XHJcbiAgICAgICAgLy8gc2V0IG5vbmVnYXRlIC0gYnJhY2UgZXhwYW5zaW9uIGNvdWxkIHJlc3VsdCBpbiBhIGxlYWRpbmcgJyEnXHJcbiAgICAgICAgbWF0Y2hPcHRpb25zXzEubm9uZWdhdGUgPSB0cnVlO1xyXG4gICAgICAgIG1hdGNoT3B0aW9uc18xLmZsaXBOZWdhdGUgPSBmYWxzZTtcclxuICAgICAgICAvLyBleHBhbmQgYnJhY2VzIC0gcmVxdWlyZWQgdG8gYWNjdXJhdGVseSBpbnRlcnByZXQgZmluZFBhdGhcclxuICAgICAgICB2YXIgZXhwYW5kZWQgPSB2b2lkIDA7XHJcbiAgICAgICAgdmFyIHByZUV4cGFuZGVkID0gcGF0dGVybjtcclxuICAgICAgICBpZiAobWF0Y2hPcHRpb25zXzEubm9icmFjZSkge1xyXG4gICAgICAgICAgICBleHBhbmRlZCA9IFtwYXR0ZXJuXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIGNvbnZlcnQgc2xhc2hlcyBvbiBXaW5kb3dzIGJlZm9yZSBjYWxsaW5nIGJyYWNlRXhwYW5kKCkuIHVuZm9ydHVuYXRlbHkgdGhpcyBtZWFucyBicmFjZXMgY2Fubm90XHJcbiAgICAgICAgICAgIC8vIGJlIGVzY2FwZWQgb24gV2luZG93cywgdGhpcyBsaW1pdGF0aW9uIGlzIGNvbnNpc3RlbnQgd2l0aCBjdXJyZW50IGxpbWl0YXRpb25zIG9mIG1pbmltYXRjaCAoMy4wLjMpLlxyXG4gICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdleHBhbmRpbmcgYnJhY2VzJyk7XHJcbiAgICAgICAgICAgIHZhciBjb252ZXJ0ZWRQYXR0ZXJuID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybi5yZXBsYWNlKC9cXFxcL2csICcvJykgOiBwYXR0ZXJuO1xyXG4gICAgICAgICAgICBleHBhbmRlZCA9IG1pbmltYXRjaC5icmFjZUV4cGFuZChjb252ZXJ0ZWRQYXR0ZXJuKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gc2V0IG5vYnJhY2VcclxuICAgICAgICBtYXRjaE9wdGlvbnNfMS5ub2JyYWNlID0gdHJ1ZTtcclxuICAgICAgICBmb3IgKHZhciBfYiA9IDAsIGV4cGFuZGVkXzIgPSBleHBhbmRlZDsgX2IgPCBleHBhbmRlZF8yLmxlbmd0aDsgX2IrKykge1xyXG4gICAgICAgICAgICB2YXIgcGF0dGVybl8yID0gZXhwYW5kZWRfMltfYl07XHJcbiAgICAgICAgICAgIGlmIChleHBhbmRlZC5sZW5ndGggIT0gMSB8fCBwYXR0ZXJuXzIgIT0gcHJlRXhwYW5kZWQpIHtcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJwYXR0ZXJuOiAnXCIgKyBwYXR0ZXJuXzIgKyBcIidcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gdHJpbSBhbmQgc2tpcCBlbXB0eVxyXG4gICAgICAgICAgICBwYXR0ZXJuXzIgPSAocGF0dGVybl8yIHx8ICcnKS50cmltKCk7XHJcbiAgICAgICAgICAgIGlmICghcGF0dGVybl8yKSB7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdza2lwcGluZyBlbXB0eSBwYXR0ZXJuJyk7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoaXNJbmNsdWRlUGF0dGVybikge1xyXG4gICAgICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIHRoZSBmaW5kUGF0aFxyXG4gICAgICAgICAgICAgICAgdmFyIGZpbmRJbmZvID0gaW0uX2dldEZpbmRJbmZvRnJvbVBhdHRlcm4oZGVmYXVsdFJvb3QsIHBhdHRlcm5fMiwgbWF0Y2hPcHRpb25zXzEpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGZpbmRQYXRoID0gZmluZEluZm8uZmluZFBhdGg7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwiZmluZFBhdGg6ICdcIiArIGZpbmRQYXRoICsgXCInXCIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFmaW5kUGF0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ3NraXBwaW5nIGVtcHR5IHBhdGgnKTtcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gdGhlIGZpbmRcclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJzdGF0T25seTogJ1wiICsgZmluZEluZm8uc3RhdE9ubHkgKyBcIidcIik7XHJcbiAgICAgICAgICAgICAgICB2YXIgZmluZFJlc3VsdHMgPSBbXTtcclxuICAgICAgICAgICAgICAgIGlmIChmaW5kSW5mby5zdGF0T25seSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHNpbXBseSBzdGF0IHRoZSBwYXRoIC0gYWxsIHBhdGggc2VnbWVudHMgd2VyZSB1c2VkIHRvIGJ1aWxkIHRoZSBwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnMuc3RhdFN5bmMoZmluZFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaW5kUmVzdWx0cy5wdXNoKGZpbmRQYXRoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgIT0gJ0VOT0VOVCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKCdFTk9FTlQnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBmaW5kUmVzdWx0cyA9IGZpbmQoZmluZFBhdGgsIGZpbmRPcHRpb25zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoXCJmb3VuZCBcIiArIGZpbmRSZXN1bHRzLmxlbmd0aCArIFwiIHBhdGhzXCIpO1xyXG4gICAgICAgICAgICAgICAgLy8gYXBwbHkgdGhlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2FwcGx5aW5nIGluY2x1ZGUgcGF0dGVybicpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZpbmRJbmZvLmFkanVzdGVkUGF0dGVybiAhPSBwYXR0ZXJuXzIpIHtcclxuICAgICAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwiYWRqdXN0ZWRQYXR0ZXJuOiAnXCIgKyBmaW5kSW5mby5hZGp1c3RlZFBhdHRlcm4gKyBcIidcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcGF0dGVybl8yID0gZmluZEluZm8uYWRqdXN0ZWRQYXR0ZXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0cyA9IG1pbmltYXRjaC5tYXRjaChmaW5kUmVzdWx0cywgcGF0dGVybl8yLCBtYXRjaE9wdGlvbnNfMSk7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKG1hdGNoUmVzdWx0cy5sZW5ndGggKyAnIG1hdGNoZXMnKTtcclxuICAgICAgICAgICAgICAgIC8vIHVuaW9uIHRoZSByZXN1bHRzXHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfYyA9IDAsIG1hdGNoUmVzdWx0c18zID0gbWF0Y2hSZXN1bHRzOyBfYyA8IG1hdGNoUmVzdWx0c18zLmxlbmd0aDsgX2MrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtYXRjaFJlc3VsdCA9IG1hdGNoUmVzdWx0c18zW19jXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gbWF0Y2hSZXN1bHQudG9VcHBlckNhc2UoKSA6IG1hdGNoUmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHNba2V5XSA9IG1hdGNoUmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgYmFzZW5hbWUgb25seSBhbmQgbWF0Y2hCYXNlPXRydWVcclxuICAgICAgICAgICAgICAgIGlmIChtYXRjaE9wdGlvbnNfMS5tYXRjaEJhc2UgJiZcclxuICAgICAgICAgICAgICAgICAgICAhaW0uX2lzUm9vdGVkKHBhdHRlcm5fMikgJiZcclxuICAgICAgICAgICAgICAgICAgICAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInID8gcGF0dGVybl8yLnJlcGxhY2UoL1xcXFwvZywgJy8nKSA6IHBhdHRlcm5fMikuaW5kZXhPZignLycpIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCByb290IHRoZSBwYXR0ZXJuXHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy5kZWJ1ZygnbWF0Y2hCYXNlIGFuZCBiYXNlbmFtZSBvbmx5Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyByb290IHRoZSBleGNsdWRlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuXzIgPSBpbS5fZW5zdXJlUGF0dGVyblJvb3RlZChkZWZhdWx0Um9vdCwgcGF0dGVybl8yKTtcclxuICAgICAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKFwiYWZ0ZXIgZW5zdXJlUGF0dGVyblJvb3RlZCwgcGF0dGVybjogJ1wiICsgcGF0dGVybl8yICsgXCInXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gYXBwbHkgdGhlIHBhdHRlcm5cclxuICAgICAgICAgICAgICAgIGV4cG9ydHMuZGVidWcoJ2FwcGx5aW5nIGV4Y2x1ZGUgcGF0dGVybicpO1xyXG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoUmVzdWx0cyA9IG1pbmltYXRjaC5tYXRjaChPYmplY3Qua2V5cyhyZXN1bHRzKS5tYXAoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gcmVzdWx0c1trZXldOyB9KSwgcGF0dGVybl8yLCBtYXRjaE9wdGlvbnNfMSk7XHJcbiAgICAgICAgICAgICAgICBleHBvcnRzLmRlYnVnKG1hdGNoUmVzdWx0cy5sZW5ndGggKyAnIG1hdGNoZXMnKTtcclxuICAgICAgICAgICAgICAgIC8vIHN1YnN0cmFjdCB0aGUgcmVzdWx0c1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2QgPSAwLCBtYXRjaFJlc3VsdHNfNCA9IG1hdGNoUmVzdWx0czsgX2QgPCBtYXRjaFJlc3VsdHNfNC5sZW5ndGg7IF9kKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWF0Y2hSZXN1bHQgPSBtYXRjaFJlc3VsdHNfNFtfZF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJyA/IG1hdGNoUmVzdWx0LnRvVXBwZXJDYXNlKCkgOiBtYXRjaFJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcmVzdWx0c1trZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdmFyIGZpbmFsUmVzdWx0ID0gT2JqZWN0LmtleXMocmVzdWx0cylcclxuICAgICAgICAubWFwKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIHJlc3VsdHNba2V5XTsgfSlcclxuICAgICAgICAuc29ydCgpO1xyXG4gICAgZXhwb3J0cy5kZWJ1ZyhmaW5hbFJlc3VsdC5sZW5ndGggKyAnIGZpbmFsIHJlc3VsdHMnKTtcclxuICAgIHJldHVybiBmaW5hbFJlc3VsdDtcclxufVxyXG5leHBvcnRzLmZpbmRNYXRjaCA9IGZpbmRNYXRjaDtcclxuLyoqXHJcbiAqIEdldHMgaHR0cCBwcm94eSBjb25maWd1cmF0aW9uIHVzZWQgYnkgQnVpbGQvUmVsZWFzZSBhZ2VudFxyXG4gKlxyXG4gKiBAcmV0dXJuICBQcm94eUNvbmZpZ3VyYXRpb25cclxuICovXHJcbmZ1bmN0aW9uIGdldEh0dHBQcm94eUNvbmZpZ3VyYXRpb24ocmVxdWVzdFVybCkge1xyXG4gICAgdmFyIHByb3h5VXJsID0gZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuUHJveHlVcmwnKTtcclxuICAgIGlmIChwcm94eVVybCAmJiBwcm94eVVybC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgdmFyIHByb3h5VXNlcm5hbWUgPSBleHBvcnRzLmdldFZhcmlhYmxlKCdBZ2VudC5Qcm94eVVzZXJuYW1lJyk7XHJcbiAgICAgICAgdmFyIHByb3h5UGFzc3dvcmQgPSBleHBvcnRzLmdldFZhcmlhYmxlKCdBZ2VudC5Qcm94eVBhc3N3b3JkJyk7XHJcbiAgICAgICAgdmFyIHByb3h5QnlwYXNzSG9zdHMgPSBKU09OLnBhcnNlKGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LlByb3h5QnlwYXNzTGlzdCcpIHx8ICdbXScpO1xyXG4gICAgICAgIHZhciBieXBhc3NfMSA9IGZhbHNlO1xyXG4gICAgICAgIGlmIChyZXF1ZXN0VXJsKSB7XHJcbiAgICAgICAgICAgIHByb3h5QnlwYXNzSG9zdHMuZm9yRWFjaChmdW5jdGlvbiAoYnlwYXNzSG9zdCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG5ldyBSZWdFeHAoYnlwYXNzSG9zdCwgJ2knKS50ZXN0KHJlcXVlc3RVcmwpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnlwYXNzXzEgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJ5cGFzc18xKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHByb3h5VXJsOiBwcm94eVVybCxcclxuICAgICAgICAgICAgICAgIHByb3h5VXNlcm5hbWU6IHByb3h5VXNlcm5hbWUsXHJcbiAgICAgICAgICAgICAgICBwcm94eVBhc3N3b3JkOiBwcm94eVBhc3N3b3JkLFxyXG4gICAgICAgICAgICAgICAgcHJveHlCeXBhc3NIb3N0czogcHJveHlCeXBhc3NIb3N0c1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuZ2V0SHR0cFByb3h5Q29uZmlndXJhdGlvbiA9IGdldEh0dHBQcm94eUNvbmZpZ3VyYXRpb247XHJcbi8qKlxyXG4gKiBHZXRzIGh0dHAgY2VydGlmaWNhdGUgY29uZmlndXJhdGlvbiB1c2VkIGJ5IEJ1aWxkL1JlbGVhc2UgYWdlbnRcclxuICpcclxuICogQHJldHVybiAgQ2VydENvbmZpZ3VyYXRpb25cclxuICovXHJcbmZ1bmN0aW9uIGdldEh0dHBDZXJ0Q29uZmlndXJhdGlvbigpIHtcclxuICAgIHZhciBjYSA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LkNBSW5mbycpO1xyXG4gICAgdmFyIGNsaWVudENlcnQgPSBleHBvcnRzLmdldFZhcmlhYmxlKCdBZ2VudC5DbGllbnRDZXJ0Jyk7XHJcbiAgICBpZiAoY2EgfHwgY2xpZW50Q2VydCkge1xyXG4gICAgICAgIHZhciBjZXJ0Q29uZmlnID0ge307XHJcbiAgICAgICAgY2VydENvbmZpZy5jYUZpbGUgPSBjYTtcclxuICAgICAgICBjZXJ0Q29uZmlnLmNlcnRGaWxlID0gY2xpZW50Q2VydDtcclxuICAgICAgICBpZiAoY2xpZW50Q2VydCkge1xyXG4gICAgICAgICAgICB2YXIgY2xpZW50Q2VydEtleSA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LkNsaWVudENlcnRLZXknKTtcclxuICAgICAgICAgICAgdmFyIGNsaWVudENlcnRBcmNoaXZlID0gZXhwb3J0cy5nZXRWYXJpYWJsZSgnQWdlbnQuQ2xpZW50Q2VydEFyY2hpdmUnKTtcclxuICAgICAgICAgICAgdmFyIGNsaWVudENlcnRQYXNzd29yZCA9IGV4cG9ydHMuZ2V0VmFyaWFibGUoJ0FnZW50LkNsaWVudENlcnRQYXNzd29yZCcpO1xyXG4gICAgICAgICAgICBjZXJ0Q29uZmlnLmtleUZpbGUgPSBjbGllbnRDZXJ0S2V5O1xyXG4gICAgICAgICAgICBjZXJ0Q29uZmlnLmNlcnRBcmNoaXZlRmlsZSA9IGNsaWVudENlcnRBcmNoaXZlO1xyXG4gICAgICAgICAgICBjZXJ0Q29uZmlnLnBhc3NwaHJhc2UgPSBjbGllbnRDZXJ0UGFzc3dvcmQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjZXJ0Q29uZmlnO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0cy5nZXRIdHRwQ2VydENvbmZpZ3VyYXRpb24gPSBnZXRIdHRwQ2VydENvbmZpZ3VyYXRpb247XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gVGVzdCBQdWJsaXNoZXJcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG52YXIgVGVzdFB1Ymxpc2hlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIFRlc3RQdWJsaXNoZXIodGVzdFJ1bm5lcikge1xyXG4gICAgICAgIHRoaXMudGVzdFJ1bm5lciA9IHRlc3RSdW5uZXI7XHJcbiAgICB9XHJcbiAgICBUZXN0UHVibGlzaGVyLnByb3RvdHlwZS5wdWJsaXNoID0gZnVuY3Rpb24gKHJlc3VsdEZpbGVzLCBtZXJnZVJlc3VsdHMsIHBsYXRmb3JtLCBjb25maWcsIHJ1blRpdGxlLCBwdWJsaXNoUnVuQXR0YWNobWVudHMsIHRlc3RSdW5TeXN0ZW0pIHtcclxuICAgICAgICAvLyBDb3VsZCBoYXZlIHVzZWQgYW4gaW5pdGlhbGl6ZXIsIGJ1dCB3YW50ZWQgdG8gYXZvaWQgcmVvcmRlcmluZyBwYXJhbWV0ZXJzIHdoZW4gY29udmVydGluZyB0byBzdHJpY3QgbnVsbCBjaGVja3NcclxuICAgICAgICAvLyAoQSBwYXJhbWV0ZXIgY2Fubm90IGJvdGggYmUgb3B0aW9uYWwgYW5kIGhhdmUgYW4gaW5pdGlhbGl6ZXIpXHJcbiAgICAgICAgdGVzdFJ1blN5c3RlbSA9IHRlc3RSdW5TeXN0ZW0gfHwgXCJWU1RTVGFza1wiO1xyXG4gICAgICAgIHZhciBwcm9wZXJ0aWVzID0ge307XHJcbiAgICAgICAgcHJvcGVydGllc1sndHlwZSddID0gdGhpcy50ZXN0UnVubmVyO1xyXG4gICAgICAgIGlmIChtZXJnZVJlc3VsdHMpIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1snbWVyZ2VSZXN1bHRzJ10gPSBtZXJnZVJlc3VsdHM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwbGF0Zm9ybSkge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydwbGF0Zm9ybSddID0gcGxhdGZvcm07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjb25maWcpIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1snY29uZmlnJ10gPSBjb25maWc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChydW5UaXRsZSkge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydydW5UaXRsZSddID0gcnVuVGl0bGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwdWJsaXNoUnVuQXR0YWNobWVudHMpIHtcclxuICAgICAgICAgICAgcHJvcGVydGllc1sncHVibGlzaFJ1bkF0dGFjaG1lbnRzJ10gPSBwdWJsaXNoUnVuQXR0YWNobWVudHM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyZXN1bHRGaWxlcykge1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydyZXN1bHRGaWxlcyddID0gQXJyYXkuaXNBcnJheShyZXN1bHRGaWxlcykgPyByZXN1bHRGaWxlcy5qb2luKCkgOiByZXN1bHRGaWxlcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcHJvcGVydGllc1sndGVzdFJ1blN5c3RlbSddID0gdGVzdFJ1blN5c3RlbTtcclxuICAgICAgICBleHBvcnRzLmNvbW1hbmQoJ3Jlc3VsdHMucHVibGlzaCcsIHByb3BlcnRpZXMsICcnKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gVGVzdFB1Ymxpc2hlcjtcclxufSgpKTtcclxuZXhwb3J0cy5UZXN0UHVibGlzaGVyID0gVGVzdFB1Ymxpc2hlcjtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBDb2RlIGNvdmVyYWdlIFB1Ymxpc2hlclxyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbnZhciBDb2RlQ292ZXJhZ2VQdWJsaXNoZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBDb2RlQ292ZXJhZ2VQdWJsaXNoZXIoKSB7XHJcbiAgICB9XHJcbiAgICBDb2RlQ292ZXJhZ2VQdWJsaXNoZXIucHJvdG90eXBlLnB1Ymxpc2ggPSBmdW5jdGlvbiAoY29kZUNvdmVyYWdlVG9vbCwgc3VtbWFyeUZpbGVMb2NhdGlvbiwgcmVwb3J0RGlyZWN0b3J5LCBhZGRpdGlvbmFsQ29kZUNvdmVyYWdlRmlsZXMpIHtcclxuICAgICAgICB2YXIgcHJvcGVydGllcyA9IHt9O1xyXG4gICAgICAgIGlmIChjb2RlQ292ZXJhZ2VUb29sKSB7XHJcbiAgICAgICAgICAgIHByb3BlcnRpZXNbJ2NvZGVjb3ZlcmFnZXRvb2wnXSA9IGNvZGVDb3ZlcmFnZVRvb2w7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzdW1tYXJ5RmlsZUxvY2F0aW9uKSB7XHJcbiAgICAgICAgICAgIHByb3BlcnRpZXNbJ3N1bW1hcnlmaWxlJ10gPSBzdW1tYXJ5RmlsZUxvY2F0aW9uO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocmVwb3J0RGlyZWN0b3J5KSB7XHJcbiAgICAgICAgICAgIHByb3BlcnRpZXNbJ3JlcG9ydGRpcmVjdG9yeSddID0gcmVwb3J0RGlyZWN0b3J5O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYWRkaXRpb25hbENvZGVDb3ZlcmFnZUZpbGVzKSB7XHJcbiAgICAgICAgICAgIHByb3BlcnRpZXNbJ2FkZGl0aW9uYWxjb2RlY292ZXJhZ2VmaWxlcyddID0gQXJyYXkuaXNBcnJheShhZGRpdGlvbmFsQ29kZUNvdmVyYWdlRmlsZXMpID8gYWRkaXRpb25hbENvZGVDb3ZlcmFnZUZpbGVzLmpvaW4oKSA6IGFkZGl0aW9uYWxDb2RlQ292ZXJhZ2VGaWxlcztcclxuICAgICAgICB9XHJcbiAgICAgICAgZXhwb3J0cy5jb21tYW5kKCdjb2RlY292ZXJhZ2UucHVibGlzaCcsIHByb3BlcnRpZXMsIFwiXCIpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBDb2RlQ292ZXJhZ2VQdWJsaXNoZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuQ29kZUNvdmVyYWdlUHVibGlzaGVyID0gQ29kZUNvdmVyYWdlUHVibGlzaGVyO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIENvZGUgY292ZXJhZ2UgUHVibGlzaGVyXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxudmFyIENvZGVDb3ZlcmFnZUVuYWJsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBDb2RlQ292ZXJhZ2VFbmFibGVyKGJ1aWxkVG9vbCwgY2NUb29sKSB7XHJcbiAgICAgICAgdGhpcy5idWlsZFRvb2wgPSBidWlsZFRvb2w7XHJcbiAgICAgICAgdGhpcy5jY1Rvb2wgPSBjY1Rvb2w7XHJcbiAgICB9XHJcbiAgICBDb2RlQ292ZXJhZ2VFbmFibGVyLnByb3RvdHlwZS5lbmFibGVDb2RlQ292ZXJhZ2UgPSBmdW5jdGlvbiAoYnVpbGRQcm9wcykge1xyXG4gICAgICAgIGJ1aWxkUHJvcHNbJ2J1aWxkdG9vbCddID0gdGhpcy5idWlsZFRvb2w7XHJcbiAgICAgICAgYnVpbGRQcm9wc1snY29kZWNvdmVyYWdldG9vbCddID0gdGhpcy5jY1Rvb2w7XHJcbiAgICAgICAgZXhwb3J0cy5jb21tYW5kKCdjb2RlY292ZXJhZ2UuZW5hYmxlJywgYnVpbGRQcm9wcywgXCJcIik7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIENvZGVDb3ZlcmFnZUVuYWJsZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuQ29kZUNvdmVyYWdlRW5hYmxlciA9IENvZGVDb3ZlcmFnZUVuYWJsZXI7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gVGFzayBMb2dnaW5nIENvbW1hbmRzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIFVwbG9hZCB1c2VyIGludGVyZXN0ZWQgZmlsZSBhcyBhZGRpdGlvbmFsIGxvZyBpbmZvcm1hdGlvblxyXG4gKiB0byB0aGUgY3VycmVudCB0aW1lbGluZSByZWNvcmQuXHJcbiAqXHJcbiAqIFRoZSBmaWxlIHNoYWxsIGJlIGF2YWlsYWJsZSBmb3IgZG93bmxvYWQgYWxvbmcgd2l0aCB0YXNrIGxvZ3MuXHJcbiAqXHJcbiAqIEBwYXJhbSBwYXRoICAgICAgUGF0aCB0byB0aGUgZmlsZSB0aGF0IHNob3VsZCBiZSB1cGxvYWRlZC5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiB1cGxvYWRGaWxlKHBhdGgpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInRhc2sudXBsb2FkZmlsZVwiLCBudWxsLCBwYXRoKTtcclxufVxyXG5leHBvcnRzLnVwbG9hZEZpbGUgPSB1cGxvYWRGaWxlO1xyXG4vKipcclxuICogSW5zdHJ1Y3Rpb24gZm9yIHRoZSBhZ2VudCB0byB1cGRhdGUgdGhlIFBBVEggZW52aXJvbm1lbnQgdmFyaWFibGUuXHJcbiAqIFRoZSBzcGVjaWZpZWQgZGlyZWN0b3J5IGlzIHByZXBlbmRlZCB0byB0aGUgUEFUSC5cclxuICogVGhlIHVwZGF0ZWQgZW52aXJvbm1lbnQgdmFyaWFibGUgd2lsbCBiZSByZWZsZWN0ZWQgaW4gc3Vic2VxdWVudCB0YXNrcy5cclxuICpcclxuICogQHBhcmFtIHBhdGggICAgICBMb2NhbCBkaXJlY3RvcnkgcGF0aC5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBwcmVwZW5kUGF0aChwYXRoKSB7XHJcbiAgICBhc3NlcnRBZ2VudChcIjIuMTE1LjBcIik7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJ0YXNrLnByZXBlbmRwYXRoXCIsIG51bGwsIHBhdGgpO1xyXG59XHJcbmV4cG9ydHMucHJlcGVuZFBhdGggPSBwcmVwZW5kUGF0aDtcclxuLyoqXHJcbiAqIFVwbG9hZCBhbmQgYXR0YWNoIHN1bW1hcnkgbWFya2Rvd24gdG8gY3VycmVudCB0aW1lbGluZSByZWNvcmQuXHJcbiAqIFRoaXMgc3VtbWFyeSBzaGFsbCBiZSBhZGRlZCB0byB0aGUgYnVpbGQvcmVsZWFzZSBzdW1tYXJ5IGFuZFxyXG4gKiBub3QgYXZhaWxhYmxlIGZvciBkb3dubG9hZCB3aXRoIGxvZ3MuXHJcbiAqXHJcbiAqIEBwYXJhbSBwYXRoICAgICAgTG9jYWwgZGlyZWN0b3J5IHBhdGguXHJcbiAqIEByZXR1cm5zICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gdXBsb2FkU3VtbWFyeShwYXRoKSB7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJ0YXNrLnVwbG9hZHN1bW1hcnlcIiwgbnVsbCwgcGF0aCk7XHJcbn1cclxuZXhwb3J0cy51cGxvYWRTdW1tYXJ5ID0gdXBsb2FkU3VtbWFyeTtcclxuLyoqXHJcbiAqIFVwbG9hZCBhbmQgYXR0YWNoIGF0dGFjaG1lbnQgdG8gY3VycmVudCB0aW1lbGluZSByZWNvcmQuXHJcbiAqIFRoZXNlIGZpbGVzIGFyZSBub3QgYXZhaWxhYmxlIGZvciBkb3dubG9hZCB3aXRoIGxvZ3MuXHJcbiAqIFRoZXNlIGNhbiBvbmx5IGJlIHJlZmVycmVkIHRvIGJ5IGV4dGVuc2lvbnMgdXNpbmcgdGhlIHR5cGUgb3IgbmFtZSB2YWx1ZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB0eXBlICAgICAgQXR0YWNobWVudCB0eXBlLlxyXG4gKiBAcGFyYW0gbmFtZSAgICAgIEF0dGFjaG1lbnQgbmFtZS5cclxuICogQHBhcmFtIHBhdGggICAgICBBdHRhY2htZW50IHBhdGguXHJcbiAqIEByZXR1cm5zICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gYWRkQXR0YWNobWVudCh0eXBlLCBuYW1lLCBwYXRoKSB7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJ0YXNrLmFkZGF0dGFjaG1lbnRcIiwgeyBcInR5cGVcIjogdHlwZSwgXCJuYW1lXCI6IG5hbWUgfSwgcGF0aCk7XHJcbn1cclxuZXhwb3J0cy5hZGRBdHRhY2htZW50ID0gYWRkQXR0YWNobWVudDtcclxuLyoqXHJcbiAqIFNldCBhbiBlbmRwb2ludCBmaWVsZCB3aXRoIGdpdmVuIHZhbHVlLlxyXG4gKiBWYWx1ZSB1cGRhdGVkIHdpbGwgYmUgcmV0YWluZWQgaW4gdGhlIGVuZHBvaW50IGZvclxyXG4gKiB0aGUgc3Vic2VxdWVudCB0YXNrcyB0aGF0IGV4ZWN1dGUgd2l0aGluIHRoZSBzYW1lIGpvYi5cclxuICpcclxuICogQHBhcmFtIGlkICAgICAgRW5kcG9pbnQgaWQuXHJcbiAqIEBwYXJhbSBmaWVsZCAgIEZpZWxkVHlwZSBlbnVtIG9mIEF1dGhQYXJhbWV0ZXIsIERhdGFQYXJhbWV0ZXIgb3IgVXJsLlxyXG4gKiBAcGFyYW0ga2V5ICAgICBLZXkuXHJcbiAqIEBwYXJhbSB2YWx1ZSAgIFZhbHVlIGZvciBrZXkgb3IgdXJsLlxyXG4gKiBAcmV0dXJucyAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBzZXRFbmRwb2ludChpZCwgZmllbGQsIGtleSwgdmFsdWUpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInRhc2suc2V0ZW5kcG9pbnRcIiwgeyBcImlkXCI6IGlkLCBcImZpZWxkXCI6IEZpZWxkVHlwZVtmaWVsZF0udG9Mb3dlckNhc2UoKSwgXCJrZXlcIjoga2V5IH0sIHZhbHVlKTtcclxufVxyXG5leHBvcnRzLnNldEVuZHBvaW50ID0gc2V0RW5kcG9pbnQ7XHJcbi8qKlxyXG4gKiBTZXQgcHJvZ3Jlc3MgYW5kIGN1cnJlbnQgb3BlcmF0aW9uIGZvciBjdXJyZW50IHRhc2suXHJcbiAqXHJcbiAqIEBwYXJhbSBwZXJjZW50ICAgICAgICAgICBQZXJjZW50YWdlIG9mIGNvbXBsZXRpb24uXHJcbiAqIEBwYXJhbSBjdXJyZW50T3BlcmF0aW9uICBDdXJyZW50IHBwZXJhdGlvbi5cclxuICogQHJldHVybnMgICAgICAgICAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHNldFByb2dyZXNzKHBlcmNlbnQsIGN1cnJlbnRPcGVyYXRpb24pIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcInRhc2suc2V0cHJvZ3Jlc3NcIiwgeyBcInZhbHVlXCI6IFwiXCIgKyBwZXJjZW50IH0sIGN1cnJlbnRPcGVyYXRpb24pO1xyXG59XHJcbmV4cG9ydHMuc2V0UHJvZ3Jlc3MgPSBzZXRQcm9ncmVzcztcclxuLyoqXHJcbiAqIEluZGljYXRlcyB3aGV0aGVyIHRvIHdyaXRlIHRoZSBsb2dnaW5nIGNvbW1hbmQgZGlyZWN0bHkgdG8gdGhlIGhvc3Qgb3IgdG8gdGhlIG91dHB1dCBwaXBlbGluZS5cclxuICpcclxuICogQHBhcmFtIGlkICAgICAgICAgICAgVGltZWxpbmUgcmVjb3JkIEd1aWQuXHJcbiAqIEBwYXJhbSBwYXJlbnRJZCAgICAgIFBhcmVudCB0aW1lbGluZSByZWNvcmQgR3VpZC5cclxuICogQHBhcmFtIHJlY29yZFR5cGUgICAgUmVjb3JkIHR5cGUuXHJcbiAqIEBwYXJhbSByZWNvcmROYW1lICAgIFJlY29yZCBuYW1lLlxyXG4gKiBAcGFyYW0gb3JkZXIgICAgICAgICBPcmRlciBvZiB0aW1lbGluZSByZWNvcmQuXHJcbiAqIEBwYXJhbSBzdGFydFRpbWUgICAgIFN0YXJ0IHRpbWUuXHJcbiAqIEBwYXJhbSBmaW5pc2hUaW1lICAgIEVuZCB0aW1lLlxyXG4gKiBAcGFyYW0gcHJvZ3Jlc3MgICAgICBQZXJjZW50YWdlIG9mIGNvbXBsZXRpb24uXHJcbiAqIEBwYXJhbSBzdGF0ZSAgICAgICAgIFRhc2tTdGF0ZSBlbnVtIG9mIFVua25vd24sIEluaXRpYWxpemVkLCBJblByb2dyZXNzIG9yIENvbXBsZXRlZC5cclxuICogQHBhcmFtIHJlc3VsdCAgICAgICAgVGFza1Jlc3VsdCBlbnVtIG9mIFN1Y2NlZWRlZCwgU3VjY2VlZGVkV2l0aElzc3VlcywgRmFpbGVkLCBDYW5jZWxsZWQgb3IgU2tpcHBlZC5cclxuICogQHBhcmFtIG1lc3NhZ2UgICAgICAgY3VycmVudCBvcGVyYXRpb25cclxuICogQHJldHVybnMgICAgICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gbG9nRGV0YWlsKGlkLCBtZXNzYWdlLCBwYXJlbnRJZCwgcmVjb3JkVHlwZSwgcmVjb3JkTmFtZSwgb3JkZXIsIHN0YXJ0VGltZSwgZmluaXNoVGltZSwgcHJvZ3Jlc3MsIHN0YXRlLCByZXN1bHQpIHtcclxuICAgIHZhciBwcm9wZXJ0aWVzID0ge1xyXG4gICAgICAgIFwiaWRcIjogaWQsXHJcbiAgICAgICAgXCJwYXJlbnRpZFwiOiBwYXJlbnRJZCxcclxuICAgICAgICBcInR5cGVcIjogcmVjb3JkVHlwZSxcclxuICAgICAgICBcIm5hbWVcIjogcmVjb3JkTmFtZSxcclxuICAgICAgICBcIm9yZGVyXCI6IG9yZGVyID8gb3JkZXIudG9TdHJpbmcoKSA6IHVuZGVmaW5lZCxcclxuICAgICAgICBcInN0YXJ0dGltZVwiOiBzdGFydFRpbWUsXHJcbiAgICAgICAgXCJmaW5pc2h0aW1lXCI6IGZpbmlzaFRpbWUsXHJcbiAgICAgICAgXCJwcm9ncmVzc1wiOiBwcm9ncmVzcyA/IHByb2dyZXNzLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgXCJzdGF0ZVwiOiBzdGF0ZSA/IFRhc2tTdGF0ZVtzdGF0ZV0gOiB1bmRlZmluZWQsXHJcbiAgICAgICAgXCJyZXN1bHRcIjogcmVzdWx0ID8gVGFza1Jlc3VsdFtyZXN1bHRdIDogdW5kZWZpbmVkXHJcbiAgICB9O1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwidGFzay5sb2dkZXRhaWxcIiwgcHJvcGVydGllcywgbWVzc2FnZSk7XHJcbn1cclxuZXhwb3J0cy5sb2dEZXRhaWwgPSBsb2dEZXRhaWw7XHJcbi8qKlxyXG4gKiBMb2cgZXJyb3Igb3Igd2FybmluZyBpc3N1ZSB0byB0aW1lbGluZSByZWNvcmQgb2YgY3VycmVudCB0YXNrLlxyXG4gKlxyXG4gKiBAcGFyYW0gdHlwZSAgICAgICAgICBJc3N1ZVR5cGUgZW51bSBvZiBFcnJvciBvciBXYXJuaW5nLlxyXG4gKiBAcGFyYW0gc291cmNlUGF0aCAgICBTb3VyY2UgZmlsZSBsb2NhdGlvbi5cclxuICogQHBhcmFtIGxpbmVOdW1iZXIgICAgTGluZSBudW1iZXIuXHJcbiAqIEBwYXJhbSBjb2x1bW5OdW1iZXIgIENvbHVtbiBudW1iZXIuXHJcbiAqIEBwYXJhbSBjb2RlICAgICAgICAgIEVycm9yIG9yIHdhcm5pbmcgY29kZS5cclxuICogQHBhcmFtIG1lc3NhZ2UgICAgICAgRXJyb3Igb3Igd2FybmluZyBtZXNzYWdlLlxyXG4gKiBAcmV0dXJucyAgICAgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiBsb2dJc3N1ZSh0eXBlLCBtZXNzYWdlLCBzb3VyY2VQYXRoLCBsaW5lTnVtYmVyLCBjb2x1bW5OdW1iZXIsIGVycm9yQ29kZSkge1xyXG4gICAgdmFyIHByb3BlcnRpZXMgPSB7XHJcbiAgICAgICAgXCJ0eXBlXCI6IElzc3VlVHlwZVt0eXBlXS50b0xvd2VyQ2FzZSgpLFxyXG4gICAgICAgIFwiY29kZVwiOiBlcnJvckNvZGUsXHJcbiAgICAgICAgXCJzb3VyY2VwYXRoXCI6IHNvdXJjZVBhdGgsXHJcbiAgICAgICAgXCJsaW5lbnVtYmVyXCI6IGxpbmVOdW1iZXIgPyBsaW5lTnVtYmVyLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgXCJjb2x1bW5udW1iZXJcIjogY29sdW1uTnVtYmVyID8gY29sdW1uTnVtYmVyLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQsXHJcbiAgICB9O1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwidGFzay5sb2dpc3N1ZVwiLCBwcm9wZXJ0aWVzLCBtZXNzYWdlKTtcclxufVxyXG5leHBvcnRzLmxvZ0lzc3VlID0gbG9nSXNzdWU7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gQXJ0aWZhY3QgTG9nZ2luZyBDb21tYW5kc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBVcGxvYWQgdXNlciBpbnRlcmVzdGVkIGZpbGUgYXMgYWRkaXRpb25hbCBsb2cgaW5mb3JtYXRpb25cclxuICogdG8gdGhlIGN1cnJlbnQgdGltZWxpbmUgcmVjb3JkLlxyXG4gKlxyXG4gKiBUaGUgZmlsZSBzaGFsbCBiZSBhdmFpbGFibGUgZm9yIGRvd25sb2FkIGFsb25nIHdpdGggdGFzayBsb2dzLlxyXG4gKlxyXG4gKiBAcGFyYW0gY29udGFpbmVyRm9sZGVyICAgRm9sZGVyIHRoYXQgdGhlIGZpbGUgd2lsbCB1cGxvYWQgdG8sIGZvbGRlciB3aWxsIGJlIGNyZWF0ZWQgaWYgbmVlZGVkLlxyXG4gKiBAcGFyYW0gcGF0aCAgICAgICAgICAgICAgUGF0aCB0byB0aGUgZmlsZSB0aGF0IHNob3VsZCBiZSB1cGxvYWRlZC5cclxuICogQHBhcmFtIG5hbWUgICAgICAgICAgICAgIEFydGlmYWN0IG5hbWUuXHJcbiAqIEByZXR1cm5zICAgICAgICAgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiB1cGxvYWRBcnRpZmFjdChjb250YWluZXJGb2xkZXIsIHBhdGgsIG5hbWUpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcImFydGlmYWN0LnVwbG9hZFwiLCB7IFwiY29udGFpbmVyZm9sZGVyXCI6IGNvbnRhaW5lckZvbGRlciwgXCJhcnRpZmFjdG5hbWVcIjogbmFtZSB9LCBwYXRoKTtcclxufVxyXG5leHBvcnRzLnVwbG9hZEFydGlmYWN0ID0gdXBsb2FkQXJ0aWZhY3Q7XHJcbi8qKlxyXG4gKiBDcmVhdGUgYW4gYXJ0aWZhY3QgbGluaywgYXJ0aWZhY3QgbG9jYXRpb24gaXMgcmVxdWlyZWQgdG8gYmVcclxuICogYSBmaWxlIGNvbnRhaW5lciBwYXRoLCBWQyBwYXRoIG9yIFVOQyBzaGFyZSBwYXRoLlxyXG4gKlxyXG4gKiBUaGUgZmlsZSBzaGFsbCBiZSBhdmFpbGFibGUgZm9yIGRvd25sb2FkIGFsb25nIHdpdGggdGFzayBsb2dzLlxyXG4gKlxyXG4gKiBAcGFyYW0gbmFtZSAgICAgICAgICAgICAgQXJ0aWZhY3QgbmFtZS5cclxuICogQHBhcmFtIHBhdGggICAgICAgICAgICAgIFBhdGggdG8gdGhlIGZpbGUgdGhhdCBzaG91bGQgYmUgYXNzb2NpYXRlZC5cclxuICogQHBhcmFtIGFydGlmYWN0VHlwZSAgICAgIEFydGlmYWN0VHlwZSBlbnVtIG9mIENvbnRhaW5lciwgRmlsZVBhdGgsIFZlcnNpb25Db250cm9sLCBHaXRSZWYgb3IgVGZ2Y0xhYmVsLlxyXG4gKiBAcmV0dXJucyAgICAgICAgICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gYXNzb2NpYXRlQXJ0aWZhY3QobmFtZSwgcGF0aCwgYXJ0aWZhY3RUeXBlKSB7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJhcnRpZmFjdC5hc3NvY2lhdGVcIiwgeyBcInR5cGVcIjogQXJ0aWZhY3RUeXBlW2FydGlmYWN0VHlwZV0udG9Mb3dlckNhc2UoKSwgXCJhcnRpZmFjdG5hbWVcIjogbmFtZSB9LCBwYXRoKTtcclxufVxyXG5leHBvcnRzLmFzc29jaWF0ZUFydGlmYWN0ID0gYXNzb2NpYXRlQXJ0aWZhY3Q7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gQnVpbGQgTG9nZ2luZyBDb21tYW5kc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBVcGxvYWQgdXNlciBpbnRlcmVzdGVkIGxvZyB0byBidWlsZOKAmXMgY29udGFpbmVyIOKAnGxvZ3NcXHRvb2zigJ0gZm9sZGVyLlxyXG4gKlxyXG4gKiBAcGFyYW0gcGF0aCAgICAgIFBhdGggdG8gdGhlIGZpbGUgdGhhdCBzaG91bGQgYmUgdXBsb2FkZWQuXHJcbiAqIEByZXR1cm5zICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gdXBsb2FkQnVpbGRMb2cocGF0aCkge1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwiYnVpbGQudXBsb2FkbG9nXCIsIG51bGwsIHBhdGgpO1xyXG59XHJcbmV4cG9ydHMudXBsb2FkQnVpbGRMb2cgPSB1cGxvYWRCdWlsZExvZztcclxuLyoqXHJcbiAqIFVwZGF0ZSBidWlsZCBudW1iZXIgZm9yIGN1cnJlbnQgYnVpbGQuXHJcbiAqXHJcbiAqIEBwYXJhbSB2YWx1ZSAgICAgVmFsdWUgdG8gYmUgYXNzaWduZWQgYXMgdGhlIGJ1aWxkIG51bWJlci5cclxuICogQHJldHVybnMgICAgICAgICB2b2lkXHJcbiAqL1xyXG5mdW5jdGlvbiB1cGRhdGVCdWlsZE51bWJlcih2YWx1ZSkge1xyXG4gICAgZXhwb3J0cy5jb21tYW5kKFwiYnVpbGQudXBkYXRlYnVpbGRudW1iZXJcIiwgbnVsbCwgdmFsdWUpO1xyXG59XHJcbmV4cG9ydHMudXBkYXRlQnVpbGROdW1iZXIgPSB1cGRhdGVCdWlsZE51bWJlcjtcclxuLyoqXHJcbiAqIEFkZCBhIHRhZyBmb3IgY3VycmVudCBidWlsZC5cclxuICpcclxuICogQHBhcmFtIHZhbHVlICAgICBUYWcgdmFsdWUuXHJcbiAqIEByZXR1cm5zICAgICAgICAgdm9pZFxyXG4gKi9cclxuZnVuY3Rpb24gYWRkQnVpbGRUYWcodmFsdWUpIHtcclxuICAgIGV4cG9ydHMuY29tbWFuZChcImJ1aWxkLmFkZGJ1aWxkdGFnXCIsIG51bGwsIHZhbHVlKTtcclxufVxyXG5leHBvcnRzLmFkZEJ1aWxkVGFnID0gYWRkQnVpbGRUYWc7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gUmVsZWFzZSBMb2dnaW5nIENvbW1hbmRzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyoqXHJcbiAqIFVwZGF0ZSByZWxlYXNlIG5hbWUgZm9yIGN1cnJlbnQgcmVsZWFzZS5cclxuICpcclxuICogQHBhcmFtIHZhbHVlICAgICBWYWx1ZSB0byBiZSBhc3NpZ25lZCBhcyB0aGUgcmVsZWFzZSBuYW1lLlxyXG4gKiBAcmV0dXJucyAgICAgICAgIHZvaWRcclxuICovXHJcbmZ1bmN0aW9uIHVwZGF0ZVJlbGVhc2VOYW1lKG5hbWUpIHtcclxuICAgIGFzc2VydEFnZW50KFwiMi4xMzJcIik7XHJcbiAgICBleHBvcnRzLmNvbW1hbmQoXCJyZWxlYXNlLnVwZGF0ZXJlbGVhc2VuYW1lXCIsIG51bGwsIG5hbWUpO1xyXG59XHJcbmV4cG9ydHMudXBkYXRlUmVsZWFzZU5hbWUgPSB1cGRhdGVSZWxlYXNlTmFtZTtcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBUb29sc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmV4cG9ydHMuVGFza0NvbW1hbmQgPSB0Y20uVGFza0NvbW1hbmQ7XHJcbmV4cG9ydHMuY29tbWFuZEZyb21TdHJpbmcgPSB0Y20uY29tbWFuZEZyb21TdHJpbmc7XHJcbmV4cG9ydHMuVG9vbFJ1bm5lciA9IHRybS5Ub29sUnVubmVyO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFZhbGlkYXRpb24gQ2hlY2tzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gYXN5bmMgYXdhaXQgbmVlZHMgZ2VuZXJhdG9ycyBpbiBub2RlIDQueCtcclxuaWYgKHNlbXZlci5sdChwcm9jZXNzLnZlcnNpb25zLm5vZGUsICc0LjIuMCcpKSB7XHJcbiAgICBleHBvcnRzLndhcm5pbmcoJ1Rhc2tzIHJlcXVpcmUgYSBuZXcgYWdlbnQuICBVcGdyYWRlIHlvdXIgYWdlbnQgb3Igbm9kZSB0byA0LjIuMCBvciBsYXRlcicpO1xyXG59XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBQb3B1bGF0ZSB0aGUgdmF1bHQgd2l0aCBzZW5zaXRpdmUgZGF0YS4gIElucHV0cyBhbmQgRW5kcG9pbnRzXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBhdm9pZCBsb2FkaW5nIHR3aWNlIChvdmVyd3JpdGVzIC50YXNra2V5KVxyXG5pZiAoIWdsb2JhbFsnX3ZzdHNfdGFza19saWJfbG9hZGVkJ10pIHtcclxuICAgIGltLl9sb2FkRGF0YSgpO1xyXG4gICAgaW0uX2V4cG9zZVByb3h5U2V0dGluZ3MoKTtcclxuICAgIGltLl9leHBvc2VDZXJ0U2V0dGluZ3MoKTtcclxufVxyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG5leHBvcnRzLmNvbW1hbmRGcm9tU3RyaW5nID0gZXhwb3J0cy5UYXNrQ29tbWFuZCA9IHZvaWQgMDtcclxuLy9cclxuLy8gQ29tbWFuZCBGb3JtYXQ6XHJcbi8vICAgICMjdnNvW2FydGlmYWN0LmNvbW1hbmQga2V5PXZhbHVlO2tleT12YWx1ZV11c2VyIG1lc3NhZ2VcclxuLy8gICAgXHJcbi8vIEV4YW1wbGVzOlxyXG4vLyAgICAjI3Zzb1t0YXNrLnByb2dyZXNzIHZhbHVlPTU4XVxyXG4vLyAgICAjI3Zzb1t0YXNrLmlzc3VlIHR5cGU9d2FybmluZztdVGhpcyBpcyB0aGUgdXNlciB3YXJuaW5nIG1lc3NhZ2VcclxuLy9cclxudmFyIENNRF9QUkVGSVggPSAnIyN2c29bJztcclxudmFyIFRhc2tDb21tYW5kID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gVGFza0NvbW1hbmQoY29tbWFuZCwgcHJvcGVydGllcywgbWVzc2FnZSkge1xyXG4gICAgICAgIGlmICghY29tbWFuZCkge1xyXG4gICAgICAgICAgICBjb21tYW5kID0gJ21pc3NpbmcuY29tbWFuZCc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY29tbWFuZCA9IGNvbW1hbmQ7XHJcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcclxuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xyXG4gICAgfVxyXG4gICAgVGFza0NvbW1hbmQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBjbWRTdHIgPSBDTURfUFJFRklYICsgdGhpcy5jb21tYW5kO1xyXG4gICAgICAgIGlmICh0aGlzLnByb3BlcnRpZXMgJiYgT2JqZWN0LmtleXModGhpcy5wcm9wZXJ0aWVzKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGNtZFN0ciArPSAnICc7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiB0aGlzLnByb3BlcnRpZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BlcnRpZXMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWwgPSB0aGlzLnByb3BlcnRpZXNba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNhZmVseSBhcHBlbmQgdGhlIHZhbCAtIGF2b2lkIGJsb3dpbmcgdXAgd2hlbiBhdHRlbXB0aW5nIHRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbGwgLnJlcGxhY2UoKSBpZiBtZXNzYWdlIGlzIG5vdCBhIHN0cmluZyBmb3Igc29tZSByZWFzb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgY21kU3RyICs9IGtleSArICc9JyArIGVzY2FwZSgnJyArICh2YWwgfHwgJycpKSArICc7JztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY21kU3RyICs9ICddJztcclxuICAgICAgICAvLyBzYWZlbHkgYXBwZW5kIHRoZSBtZXNzYWdlIC0gYXZvaWQgYmxvd2luZyB1cCB3aGVuIGF0dGVtcHRpbmcgdG9cclxuICAgICAgICAvLyBjYWxsIC5yZXBsYWNlKCkgaWYgbWVzc2FnZSBpcyBub3QgYSBzdHJpbmcgZm9yIHNvbWUgcmVhc29uXHJcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSAnJyArICh0aGlzLm1lc3NhZ2UgfHwgJycpO1xyXG4gICAgICAgIGNtZFN0ciArPSBlc2NhcGVkYXRhKG1lc3NhZ2UpO1xyXG4gICAgICAgIHJldHVybiBjbWRTdHI7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFRhc2tDb21tYW5kO1xyXG59KCkpO1xyXG5leHBvcnRzLlRhc2tDb21tYW5kID0gVGFza0NvbW1hbmQ7XHJcbmZ1bmN0aW9uIGNvbW1hbmRGcm9tU3RyaW5nKGNvbW1hbmRMaW5lKSB7XHJcbiAgICB2YXIgcHJlTGVuID0gQ01EX1BSRUZJWC5sZW5ndGg7XHJcbiAgICB2YXIgbGJQb3MgPSBjb21tYW5kTGluZS5pbmRleE9mKCdbJyk7XHJcbiAgICB2YXIgcmJQb3MgPSBjb21tYW5kTGluZS5pbmRleE9mKCddJyk7XHJcbiAgICBpZiAobGJQb3MgPT0gLTEgfHwgcmJQb3MgPT0gLTEgfHwgcmJQb3MgLSBsYlBvcyA8IDMpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29tbWFuZCBicmFja2V0cycpO1xyXG4gICAgfVxyXG4gICAgdmFyIGNtZEluZm8gPSBjb21tYW5kTGluZS5zdWJzdHJpbmcobGJQb3MgKyAxLCByYlBvcyk7XHJcbiAgICB2YXIgc3BhY2VJZHggPSBjbWRJbmZvLmluZGV4T2YoJyAnKTtcclxuICAgIHZhciBjb21tYW5kID0gY21kSW5mbztcclxuICAgIHZhciBwcm9wZXJ0aWVzID0ge307XHJcbiAgICBpZiAoc3BhY2VJZHggPiAwKSB7XHJcbiAgICAgICAgY29tbWFuZCA9IGNtZEluZm8udHJpbSgpLnN1YnN0cmluZygwLCBzcGFjZUlkeCk7XHJcbiAgICAgICAgdmFyIHByb3BTZWN0aW9uID0gY21kSW5mby50cmltKCkuc3Vic3RyaW5nKHNwYWNlSWR4ICsgMSk7XHJcbiAgICAgICAgdmFyIHByb3BMaW5lcyA9IHByb3BTZWN0aW9uLnNwbGl0KCc7Jyk7XHJcbiAgICAgICAgcHJvcExpbmVzLmZvckVhY2goZnVuY3Rpb24gKHByb3BMaW5lKSB7XHJcbiAgICAgICAgICAgIHByb3BMaW5lID0gcHJvcExpbmUudHJpbSgpO1xyXG4gICAgICAgICAgICBpZiAocHJvcExpbmUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGVxSW5kZXggPSBwcm9wTGluZS5pbmRleE9mKCc9Jyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXFJbmRleCA9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwcm9wZXJ0eTogJyArIHByb3BMaW5lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciBrZXkgPSBwcm9wTGluZS5zdWJzdHJpbmcoMCwgZXFJbmRleCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgdmFsID0gcHJvcExpbmUuc3Vic3RyaW5nKGVxSW5kZXggKyAxKTtcclxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXNba2V5XSA9IHVuZXNjYXBlKHZhbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHZhciBtc2cgPSB1bmVzY2FwZWRhdGEoY29tbWFuZExpbmUuc3Vic3RyaW5nKHJiUG9zICsgMSkpO1xyXG4gICAgdmFyIGNtZCA9IG5ldyBUYXNrQ29tbWFuZChjb21tYW5kLCBwcm9wZXJ0aWVzLCBtc2cpO1xyXG4gICAgcmV0dXJuIGNtZDtcclxufVxyXG5leHBvcnRzLmNvbW1hbmRGcm9tU3RyaW5nID0gY29tbWFuZEZyb21TdHJpbmc7XHJcbmZ1bmN0aW9uIGVzY2FwZWRhdGEocykge1xyXG4gICAgcmV0dXJuIHMucmVwbGFjZSgvJS9nLCAnJUFaUDI1JylcclxuICAgICAgICAucmVwbGFjZSgvXFxyL2csICclMEQnKVxyXG4gICAgICAgIC5yZXBsYWNlKC9cXG4vZywgJyUwQScpO1xyXG59XHJcbmZ1bmN0aW9uIHVuZXNjYXBlZGF0YShzKSB7XHJcbiAgICByZXR1cm4gcy5yZXBsYWNlKC8lMEQvZywgJ1xccicpXHJcbiAgICAgICAgLnJlcGxhY2UoLyUwQS9nLCAnXFxuJylcclxuICAgICAgICAucmVwbGFjZSgvJUFaUDI1L2csICclJyk7XHJcbn1cclxuZnVuY3Rpb24gZXNjYXBlKHMpIHtcclxuICAgIHJldHVybiBzLnJlcGxhY2UoLyUvZywgJyVBWlAyNScpXHJcbiAgICAgICAgLnJlcGxhY2UoL1xcci9nLCAnJTBEJylcclxuICAgICAgICAucmVwbGFjZSgvXFxuL2csICclMEEnKVxyXG4gICAgICAgIC5yZXBsYWNlKC9dL2csICclNUQnKVxyXG4gICAgICAgIC5yZXBsYWNlKC87L2csICclM0InKTtcclxufVxyXG5mdW5jdGlvbiB1bmVzY2FwZShzKSB7XHJcbiAgICByZXR1cm4gcy5yZXBsYWNlKC8lMEQvZywgJ1xccicpXHJcbiAgICAgICAgLnJlcGxhY2UoLyUwQS9nLCAnXFxuJylcclxuICAgICAgICAucmVwbGFjZSgvJTVEL2csICddJylcclxuICAgICAgICAucmVwbGFjZSgvJTNCL2csICc7JylcclxuICAgICAgICAucmVwbGFjZSgvJUFaUDI1L2csICclJyk7XHJcbn1cclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgICAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuZXhwb3J0cy5Ub29sUnVubmVyID0gdm9pZCAwO1xyXG52YXIgUSA9IHJlcXVpcmUoXCJxXCIpO1xyXG52YXIgb3MgPSByZXF1aXJlKFwib3NcIik7XHJcbnZhciBldmVudHMgPSByZXF1aXJlKFwiZXZlbnRzXCIpO1xyXG52YXIgY2hpbGQgPSByZXF1aXJlKFwiY2hpbGRfcHJvY2Vzc1wiKTtcclxudmFyIGltID0gcmVxdWlyZShcIi4vaW50ZXJuYWxcIik7XHJcbnZhciBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxudmFyIFRvb2xSdW5uZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoVG9vbFJ1bm5lciwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFRvb2xSdW5uZXIodG9vbFBhdGgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNtZFNwZWNpYWxDaGFycyA9IFsnICcsICdcXHQnLCAnJicsICcoJywgJyknLCAnWycsICddJywgJ3snLCAnfScsICdeJywgJz0nLCAnOycsICchJywgJ1xcJycsICcrJywgJywnLCAnYCcsICd+JywgJ3wnLCAnPCcsICc+JywgJ1wiJ107XHJcbiAgICAgICAgaWYgKCF0b29sUGF0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhcmFtZXRlciBcXCd0b29sUGF0aFxcJyBjYW5ub3QgYmUgbnVsbCBvciBlbXB0eS4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgX3RoaXMudG9vbFBhdGggPSBpbS5fd2hpY2godG9vbFBhdGgsIHRydWUpO1xyXG4gICAgICAgIF90aGlzLmFyZ3MgPSBbXTtcclxuICAgICAgICBfdGhpcy5fZGVidWcoJ3Rvb2xSdW5uZXIgdG9vbFBhdGg6ICcgKyB0b29sUGF0aCk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2RlYnVnID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLmVtaXQoJ2RlYnVnJywgbWVzc2FnZSk7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2FyZ1N0cmluZ1RvQXJyYXkgPSBmdW5jdGlvbiAoYXJnU3RyaW5nKSB7XHJcbiAgICAgICAgdmFyIGFyZ3MgPSBbXTtcclxuICAgICAgICB2YXIgaW5RdW90ZXMgPSBmYWxzZTtcclxuICAgICAgICB2YXIgZXNjYXBlZCA9IGZhbHNlO1xyXG4gICAgICAgIHZhciBsYXN0Q2hhcldhc1NwYWNlID0gdHJ1ZTtcclxuICAgICAgICB2YXIgYXJnID0gJyc7XHJcbiAgICAgICAgdmFyIGFwcGVuZCA9IGZ1bmN0aW9uIChjKSB7XHJcbiAgICAgICAgICAgIC8vIHdlIG9ubHkgZXNjYXBlIGRvdWJsZSBxdW90ZXMuXHJcbiAgICAgICAgICAgIGlmIChlc2NhcGVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYyAhPT0gJ1wiJykge1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZyArPSAnXFxcXCc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBhcmcuc2xpY2UoMCwgLTEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGFyZyArPSBjO1xyXG4gICAgICAgICAgICBlc2NhcGVkID0gZmFsc2U7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ1N0cmluZy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgYyA9IGFyZ1N0cmluZy5jaGFyQXQoaSk7XHJcbiAgICAgICAgICAgIGlmIChjID09PSAnICcgJiYgIWluUXVvdGVzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWxhc3RDaGFyV2FzU3BhY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBhcmdzLnB1c2goYXJnKTtcclxuICAgICAgICAgICAgICAgICAgICBhcmcgPSAnJztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxhc3RDaGFyV2FzU3BhY2UgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsYXN0Q2hhcldhc1NwYWNlID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGMgPT09ICdcIicpIHtcclxuICAgICAgICAgICAgICAgIGlmICghZXNjYXBlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGluUXVvdGVzID0gIWluUXVvdGVzO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXBwZW5kKGMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGMgPT09IFwiXFxcXFwiICYmIGVzY2FwZWQpIHtcclxuICAgICAgICAgICAgICAgIGFwcGVuZChjKTtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChjID09PSBcIlxcXFxcIiAmJiBpblF1b3Rlcykge1xyXG4gICAgICAgICAgICAgICAgZXNjYXBlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBhcHBlbmQoYyk7XHJcbiAgICAgICAgICAgIGxhc3RDaGFyV2FzU3BhY2UgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFsYXN0Q2hhcldhc1NwYWNlKSB7XHJcbiAgICAgICAgICAgIGFyZ3MucHVzaChhcmcudHJpbSgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFyZ3M7XHJcbiAgICB9O1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2dldENvbW1hbmRTdHJpbmcgPSBmdW5jdGlvbiAob3B0aW9ucywgbm9QcmVmaXgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciB0b29sUGF0aCA9IHRoaXMuX2dldFNwYXduRmlsZU5hbWUoKTtcclxuICAgICAgICB2YXIgYXJncyA9IHRoaXMuX2dldFNwYXduQXJncyhvcHRpb25zKTtcclxuICAgICAgICB2YXIgY21kID0gbm9QcmVmaXggPyAnJyA6ICdbY29tbWFuZF0nOyAvLyBvbWl0IHByZWZpeCB3aGVuIHBpcGVkIHRvIGEgc2Vjb25kIHRvb2xcclxuICAgICAgICB2YXIgY29tbWFuZFBhcnRzID0gW107XHJcbiAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgICAgICAvLyBXaW5kb3dzICsgY21kIGZpbGVcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQ21kRmlsZSgpKSB7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMucHVzaCh0b29sUGF0aCk7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMgPSBjb21tYW5kUGFydHMuY29uY2F0KGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIFdpbmRvd3MgKyB2ZXJiYXRpbVxyXG4gICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zLndpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cykge1xyXG4gICAgICAgICAgICAgICAgY29tbWFuZFBhcnRzLnB1c2goXCJcXFwiXCIgKyB0b29sUGF0aCArIFwiXFxcIlwiKTtcclxuICAgICAgICAgICAgICAgIGNvbW1hbmRQYXJ0cyA9IGNvbW1hbmRQYXJ0cy5jb25jYXQoYXJncyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5zaGVsbCkge1xyXG4gICAgICAgICAgICAgICAgY29tbWFuZFBhcnRzLnB1c2godGhpcy5fd2luZG93c1F1b3RlQ21kQXJnKHRvb2xQYXRoKSk7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMgPSBjb21tYW5kUGFydHMuY29uY2F0KGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIFdpbmRvd3MgKHJlZ3VsYXIpXHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29tbWFuZFBhcnRzLnB1c2godGhpcy5fd2luZG93c1F1b3RlQ21kQXJnKHRvb2xQYXRoKSk7XHJcbiAgICAgICAgICAgICAgICBjb21tYW5kUGFydHMgPSBjb21tYW5kUGFydHMuY29uY2F0KGFyZ3MubWFwKGZ1bmN0aW9uIChhcmcpIHsgcmV0dXJuIF90aGlzLl93aW5kb3dzUXVvdGVDbWRBcmcoYXJnKTsgfSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBPU1gvTGludXggLSB0aGlzIGNhbiBsaWtlbHkgYmUgaW1wcm92ZWQgd2l0aCBzb21lIGZvcm0gb2YgcXVvdGluZy5cclxuICAgICAgICAgICAgLy8gY3JlYXRpbmcgcHJvY2Vzc2VzIG9uIFVuaXggaXMgZnVuZGFtZW50YWxseSBkaWZmZXJlbnQgdGhhbiBXaW5kb3dzLlxyXG4gICAgICAgICAgICAvLyBvbiBVbml4LCBleGVjdnAoKSB0YWtlcyBhbiBhcmcgYXJyYXkuXHJcbiAgICAgICAgICAgIGNvbW1hbmRQYXJ0cy5wdXNoKHRvb2xQYXRoKTtcclxuICAgICAgICAgICAgY29tbWFuZFBhcnRzID0gY29tbWFuZFBhcnRzLmNvbmNhdChhcmdzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY21kICs9IGNvbW1hbmRQYXJ0cy5qb2luKCcgJyk7XHJcbiAgICAgICAgLy8gYXBwZW5kIHNlY29uZCB0b29sXHJcbiAgICAgICAgaWYgKHRoaXMucGlwZU91dHB1dFRvVG9vbCkge1xyXG4gICAgICAgICAgICBjbWQgKz0gJyB8ICcgKyB0aGlzLnBpcGVPdXRwdXRUb1Rvb2wuX2dldENvbW1hbmRTdHJpbmcob3B0aW9ucywgLypub1ByZWZpeDoqLyB0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNtZDtcclxuICAgIH07XHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fcHJvY2Vzc0xpbmVCdWZmZXIgPSBmdW5jdGlvbiAoZGF0YSwgc3RyQnVmZmVyLCBvbkxpbmUpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICB2YXIgcyA9IHN0ckJ1ZmZlciArIGRhdGEudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgdmFyIG4gPSBzLmluZGV4T2Yob3MuRU9MKTtcclxuICAgICAgICAgICAgd2hpbGUgKG4gPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGxpbmUgPSBzLnN1YnN0cmluZygwLCBuKTtcclxuICAgICAgICAgICAgICAgIG9uTGluZShsaW5lKTtcclxuICAgICAgICAgICAgICAgIC8vIHRoZSByZXN0IG9mIHRoZSBzdHJpbmcgLi4uXHJcbiAgICAgICAgICAgICAgICBzID0gcy5zdWJzdHJpbmcobiArIG9zLkVPTC5sZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgbiA9IHMuaW5kZXhPZihvcy5FT0wpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHN0ckJ1ZmZlciA9IHM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgLy8gc3RyZWFtaW5nIGxpbmVzIHRvIGNvbnNvbGUgaXMgYmVzdCBlZmZvcnQuICBEb24ndCBmYWlsIGEgYnVpbGQuXHJcbiAgICAgICAgICAgIHRoaXMuX2RlYnVnKCdlcnJvciBwcm9jZXNzaW5nIGxpbmUnKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBXcmFwcyBhbiBhcmcgc3RyaW5nIHdpdGggc3BlY2lmaWVkIGNoYXIgaWYgaXQncyBub3QgYWxyZWFkeSB3cmFwcGVkXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBBcmcgd3JhcHBlZCB3aXRoIHNwZWNpZmllZCBjaGFyXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYXJnIElucHV0IGFyZ3VtZW50IHN0cmluZ1xyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHdyYXBDaGFyIEEgY2hhciBpbnB1dCBzdHJpbmcgc2hvdWxkIGJlIHdyYXBwZWQgd2l0aFxyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fd3JhcEFyZyA9IGZ1bmN0aW9uIChhcmcsIHdyYXBDaGFyKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9pc1dyYXBwZWQoYXJnLCB3cmFwQ2hhcikpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwiXCIgKyB3cmFwQ2hhciArIGFyZyArIHdyYXBDaGFyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYXJnO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogVW53cmFwcyBhbiBhcmcgc3RyaW5nIHdyYXBwZWQgd2l0aCBzcGVjaWZpZWQgY2hhclxyXG4gICAgICogQHBhcmFtIGFyZyBBcmcgd3JhcHBlZCB3aXRoIHNwZWNpZmllZCBjaGFyXHJcbiAgICAgKiBAcGFyYW0gd3JhcENoYXIgQSBjaGFyIHRvIGJlIHJlbW92ZWRcclxuICAgICAqL1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX3Vud3JhcEFyZyA9IGZ1bmN0aW9uIChhcmcsIHdyYXBDaGFyKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2lzV3JhcHBlZChhcmcsIHdyYXBDaGFyKSkge1xyXG4gICAgICAgICAgICB2YXIgcGF0dGVybiA9IG5ldyBSZWdFeHAoXCIoXlxcXFxcXFxcP1wiICsgd3JhcENoYXIgKyBcIil8KFxcXFxcXFxcP1wiICsgd3JhcENoYXIgKyBcIiQpXCIsICdnJyk7XHJcbiAgICAgICAgICAgIHJldHVybiBhcmcudHJpbSgpLnJlcGxhY2UocGF0dGVybiwgJycpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYXJnO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRGV0ZXJtaW5lIGlmIGFyZyBzdHJpbmcgaXMgd3JhcHBlZCB3aXRoIHNwZWNpZmllZCBjaGFyXHJcbiAgICAgKiBAcGFyYW0gYXJnIElucHV0IGFyZyBzdHJpbmdcclxuICAgICAqL1xyXG4gICAgVG9vbFJ1bm5lci5wcm90b3R5cGUuX2lzV3JhcHBlZCA9IGZ1bmN0aW9uIChhcmcsIHdyYXBDaGFyKSB7XHJcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBuZXcgUmVnRXhwKFwiXlxcXFxcXFxcP1wiICsgd3JhcENoYXIgKyBcIi4rXFxcXFxcXFw/XCIgKyB3cmFwQ2hhciArIFwiJFwiKTtcclxuICAgICAgICByZXR1cm4gcGF0dGVybi50ZXN0KGFyZy50cmltKCkpO1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9nZXRTcGF3bkZpbGVOYW1lID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PSAnd2luMzInKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0NtZEZpbGUoKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3MuZW52WydDT01TUEVDJ10gfHwgJ2NtZC5leGUnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuc2hlbGwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dyYXBBcmcodGhpcy50b29sUGF0aCwgJ1wiJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLnRvb2xQYXRoO1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9nZXRTcGF3bkFyZ3MgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT0gJ3dpbjMyJykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5faXNDbWRGaWxlKCkpIHtcclxuICAgICAgICAgICAgICAgIHZhciBhcmdsaW5lID0gXCIvRCAvUyAvQyBcXFwiXCIgKyB0aGlzLl93aW5kb3dzUXVvdGVDbWRBcmcodGhpcy50b29sUGF0aCk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYXJncy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZ2xpbmUgKz0gJyAnO1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZ2xpbmUgKz0gb3B0aW9ucy53aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMgPyB0aGlzLmFyZ3NbaV0gOiB0aGlzLl93aW5kb3dzUXVvdGVDbWRBcmcodGhpcy5hcmdzW2ldKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGFyZ2xpbmUgKz0gJ1wiJztcclxuICAgICAgICAgICAgICAgIHJldHVybiBbYXJnbGluZV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMud2luZG93c1ZlcmJhdGltQXJndW1lbnRzKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBub3RlLCBpbiBOb2RlIDYueCBvcHRpb25zLmFyZ3YwIGNhbiBiZSB1c2VkIGluc3RlYWQgb2Ygb3ZlcnJpZGluZyBhcmdzLnNsaWNlIGFuZCBhcmdzLnVuc2hpZnQuXHJcbiAgICAgICAgICAgICAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLCByZWZlciB0byBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvYmxvYi92Ni54L2xpYi9jaGlsZF9wcm9jZXNzLmpzXHJcbiAgICAgICAgICAgICAgICB2YXIgYXJnc18xID0gdGhpcy5hcmdzLnNsaWNlKDApOyAvLyBjb3B5IHRoZSBhcnJheVxyXG4gICAgICAgICAgICAgICAgLy8gb3ZlcnJpZGUgc2xpY2UgdG8gcHJldmVudCBOb2RlIGZyb20gY3JlYXRpbmcgYSBjb3B5IG9mIHRoZSBhcmcgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAvLyB3ZSBuZWVkIE5vZGUgdG8gdXNlIHRoZSBcInVuc2hpZnRcIiBvdmVycmlkZSBiZWxvdy5cclxuICAgICAgICAgICAgICAgIGFyZ3NfMS5zbGljZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPSAxIHx8IGFyZ3VtZW50c1swXSAhPSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBhcmd1bWVudHMgcGFzc2VkIHRvIGFyZ3Muc2xpY2Ugd2hlbiB3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMgZmxhZyBpcyBzZXQuJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmdzXzE7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgLy8gb3ZlcnJpZGUgdW5zaGlmdFxyXG4gICAgICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgICAgIC8vIHdoZW4gdXNpbmcgdGhlIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyBvcHRpb24sIE5vZGUgZG9lcyBub3QgcXVvdGUgdGhlIHRvb2wgcGF0aCB3aGVuIGJ1aWxkaW5nXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgY21kbGluZSBwYXJhbWV0ZXIgZm9yIHRoZSB3aW4zMiBmdW5jdGlvbiBDcmVhdGVQcm9jZXNzKCkuIGFuIHVucXVvdGVkIHNwYWNlIGluIHRoZSB0b29sIHBhdGhcclxuICAgICAgICAgICAgICAgIC8vIGNhdXNlcyBwcm9ibGVtcyBmb3IgdG9vbHMgd2hlbiBhdHRlbXB0aW5nIHRvIHBhcnNlIHRoZWlyIG93biBjb21tYW5kIGxpbmUgYXJncy4gdG9vbHMgdHlwaWNhbGx5XHJcbiAgICAgICAgICAgICAgICAvLyBhc3N1bWUgdGhlaXIgYXJndW1lbnRzIGJlZ2luIGFmdGVyIGFyZyAwLlxyXG4gICAgICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgICAgIC8vIGJ5IGhpamFja2luZyB1bnNoaWZ0LCB3ZSBjYW4gcXVvdGUgdGhlIHRvb2wgcGF0aCB3aGVuIGl0IHB1c2hlZCBvbnRvIHRoZSBhcmdzIGFycmF5LiBOb2RlIGJ1aWxkc1xyXG4gICAgICAgICAgICAgICAgLy8gdGhlIGNtZGxpbmUgcGFyYW1ldGVyIGZyb20gdGhlIGFyZ3MgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gbm90ZSwgd2UgY2FuJ3Qgc2ltcGx5IHBhc3MgYSBxdW90ZWQgdG9vbCBwYXRoIHRvIE5vZGUgZm9yIG11bHRpcGxlIHJlYXNvbnM6XHJcbiAgICAgICAgICAgICAgICAvLyAgIDEpIE5vZGUgdmVyaWZpZXMgdGhlIGZpbGUgZXhpc3RzIChjYWxscyB3aW4zMiBmdW5jdGlvbiBHZXRGaWxlQXR0cmlidXRlc1cpIGFuZCB0aGUgY2hlY2sgcmV0dXJuc1xyXG4gICAgICAgICAgICAgICAgLy8gICAgICBmYWxzZSBpZiB0aGUgcGF0aCBpcyBxdW90ZWQuXHJcbiAgICAgICAgICAgICAgICAvLyAgIDIpIE5vZGUgcGFzc2VzIHRoZSB0b29sIHBhdGggYXMgdGhlIGFwcGxpY2F0aW9uIHBhcmFtZXRlciB0byBDcmVhdGVQcm9jZXNzLCB3aGljaCBleHBlY3RzIHRoZVxyXG4gICAgICAgICAgICAgICAgLy8gICAgICBwYXRoIHRvIGJlIHVucXVvdGVkLlxyXG4gICAgICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgICAgIC8vIGFsc28gbm90ZSwgaW4gYWRkaXRpb24gdG8gdGhlIHRvb2wgcGF0aCBiZWluZyBlbWJlZGRlZCB3aXRoaW4gdGhlIGNtZGxpbmUgcGFyYW1ldGVyLCBOb2RlIGFsc29cclxuICAgICAgICAgICAgICAgIC8vIHBhc3NlcyB0aGUgdG9vbCBwYXRoIHRvIENyZWF0ZVByb2Nlc3MgdmlhIHRoZSBhcHBsaWNhdGlvbiBwYXJhbWV0ZXIgKG9wdGlvbmFsIHBhcmFtZXRlcikuIHdoZW5cclxuICAgICAgICAgICAgICAgIC8vIHByZXNlbnQsIFdpbmRvd3MgdXNlcyB0aGUgYXBwbGljYXRpb24gcGFyYW1ldGVyIHRvIGRldGVybWluZSB3aGljaCBmaWxlIHRvIHJ1biwgaW5zdGVhZCBvZlxyXG4gICAgICAgICAgICAgICAgLy8gaW50ZXJwcmV0aW5nIHRoZSBmaWxlIGZyb20gdGhlIGNtZGxpbmUgcGFyYW1ldGVyLlxyXG4gICAgICAgICAgICAgICAgYXJnc18xLnVuc2hpZnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggIT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgYXJndW1lbnRzIHBhc3NlZCB0byBhcmdzLnVuc2hpZnQgd2hlbiB3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHMgZmxhZyBpcyBzZXQuJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUudW5zaGlmdC5jYWxsKGFyZ3NfMSwgXCJcXFwiXCIgKyBhcmd1bWVudHNbMF0gKyBcIlxcXCJcIik7IC8vIHF1b3RlIHRoZSBmaWxlIG5hbWVcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJnc18xO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuc2hlbGwpIHtcclxuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gW107XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy5hcmdzOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhcmcgPSBfYVtfaV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX25lZWRRdW90ZXNGb3JDbWQoYXJnLCAnJScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MucHVzaCh0aGlzLl93cmFwQXJnKGFyZywgJ1wiJykpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3M7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5zaGVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hcmdzLm1hcChmdW5jdGlvbiAoYXJnKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuX2lzV3JhcHBlZChhcmcsIFwiJ1wiKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgd3JhcHBpbmcgZG91YmxlIHF1b3RlcyB0byBhdm9pZCBlc2NhcGluZ1xyXG4gICAgICAgICAgICAgICAgYXJnID0gX3RoaXMuX3Vud3JhcEFyZyhhcmcsICdcIicpO1xyXG4gICAgICAgICAgICAgICAgYXJnID0gX3RoaXMuX2VzY2FwZUNoYXIoYXJnLCAnXCInKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5fd3JhcEFyZyhhcmcsICdcIicpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYXJncztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEVzY2FwZSBzcGVjaWZpZWQgY2hhcmFjdGVyLlxyXG4gICAgICogQHBhcmFtIGFyZyBTdHJpbmcgdG8gZXNjYXBlIGNoYXIgaW5cclxuICAgICAqIEBwYXJhbSBjaGFyVG9Fc2NhcGUgQ2hhciBzaG91bGQgYmUgZXNjYXBlZFxyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fZXNjYXBlQ2hhciA9IGZ1bmN0aW9uIChhcmcsIGNoYXJUb0VzY2FwZSkge1xyXG4gICAgICAgIHZhciBlc2NDaGFyID0gXCJcXFxcXCI7XHJcbiAgICAgICAgdmFyIG91dHB1dCA9ICcnO1xyXG4gICAgICAgIHZhciBjaGFySXNFc2NhcGVkID0gZmFsc2U7XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBhcmdfMSA9IGFyZzsgX2kgPCBhcmdfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIGNoYXIgPSBhcmdfMVtfaV07XHJcbiAgICAgICAgICAgIGlmIChjaGFyID09PSBjaGFyVG9Fc2NhcGUgJiYgIWNoYXJJc0VzY2FwZWQpIHtcclxuICAgICAgICAgICAgICAgIG91dHB1dCArPSBlc2NDaGFyICsgY2hhcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG91dHB1dCArPSBjaGFyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNoYXJJc0VzY2FwZWQgPSBjaGFyID09PSBlc2NDaGFyICYmICFjaGFySXNFc2NhcGVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb3V0cHV0O1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9pc0NtZEZpbGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHVwcGVyVG9vbFBhdGggPSB0aGlzLnRvb2xQYXRoLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgcmV0dXJuIGltLl9lbmRzV2l0aCh1cHBlclRvb2xQYXRoLCAnLkNNRCcpIHx8IGltLl9lbmRzV2l0aCh1cHBlclRvb2xQYXRoLCAnLkJBVCcpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGNtZCBhcmcgbmVlZHMgdG8gYmUgcXVvdGVkLiBSZXR1cm5zIHRydWUgaWYgYXJnIGNvbnRhaW5zIGFueSBvZiBzcGVjaWFsIGNoYXJzIGFycmF5LlxyXG4gICAgICogQHBhcmFtIGFyZyBUaGUgY21kIGNvbW1hbmQgYXJnLlxyXG4gICAgICogQHBhcmFtIGFkZGl0aW9uYWxDaGFycyBBZGRpdGlvbmFsIGNoYXJzIHdoaWNoIHNob3VsZCBiZSBhbHNvIGNoZWNrZWQuXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9uZWVkUXVvdGVzRm9yQ21kID0gZnVuY3Rpb24gKGFyZywgYWRkaXRpb25hbENoYXJzKSB7XHJcbiAgICAgICAgdmFyIHNwZWNpYWxDaGFycyA9IHRoaXMuY21kU3BlY2lhbENoYXJzO1xyXG4gICAgICAgIGlmIChhZGRpdGlvbmFsQ2hhcnMpIHtcclxuICAgICAgICAgICAgc3BlY2lhbENoYXJzID0gdGhpcy5jbWRTcGVjaWFsQ2hhcnMuY29uY2F0KGFkZGl0aW9uYWxDaGFycyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gKGNoYXIpIHtcclxuICAgICAgICAgICAgaWYgKHNwZWNpYWxDaGFycy5zb21lKGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ID09PSBjaGFyOyB9KSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IHRydWUgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBhcmdfMiA9IGFyZzsgX2kgPCBhcmdfMi5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIGNoYXIgPSBhcmdfMltfaV07XHJcbiAgICAgICAgICAgIHZhciBzdGF0ZV8xID0gX2xvb3BfMShjaGFyKTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzdGF0ZV8xID09PSBcIm9iamVjdFwiKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlXzEudmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH07XHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fd2luZG93c1F1b3RlQ21kQXJnID0gZnVuY3Rpb24gKGFyZykge1xyXG4gICAgICAgIC8vIGZvciAuZXhlLCBhcHBseSB0aGUgbm9ybWFsIHF1b3RpbmcgcnVsZXMgdGhhdCBsaWJ1diBhcHBsaWVzXHJcbiAgICAgICAgaWYgKCF0aGlzLl9pc0NtZEZpbGUoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdXZfcXVvdGVfY21kX2FyZyhhcmcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBvdGhlcndpc2UgYXBwbHkgcXVvdGluZyBydWxlcyBzcGVjaWZpYyB0byB0aGUgY21kLmV4ZSBjb21tYW5kIGxpbmUgcGFyc2VyLlxyXG4gICAgICAgIC8vIHRoZSBsaWJ1diBydWxlcyBhcmUgZ2VuZXJpYyBhbmQgYXJlIG5vdCBkZXNpZ25lZCBzcGVjaWZpY2FsbHkgZm9yIGNtZC5leGVcclxuICAgICAgICAvLyBjb21tYW5kIGxpbmUgcGFyc2VyLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gZm9yIGEgZGV0YWlsZWQgZGVzY3JpcHRpb24gb2YgdGhlIGNtZC5leGUgY29tbWFuZCBsaW5lIHBhcnNlciwgcmVmZXIgdG9cclxuICAgICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQwOTQ2OTkvaG93LWRvZXMtdGhlLXdpbmRvd3MtY29tbWFuZC1pbnRlcnByZXRlci1jbWQtZXhlLXBhcnNlLXNjcmlwdHMvNzk3MDkxMiM3OTcwOTEyXHJcbiAgICAgICAgLy8gbmVlZCBxdW90ZXMgZm9yIGVtcHR5IGFyZ1xyXG4gICAgICAgIGlmICghYXJnKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAnXCJcIic7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGRldGVybWluZSB3aGV0aGVyIHRoZSBhcmcgbmVlZHMgdG8gYmUgcXVvdGVkXHJcbiAgICAgICAgdmFyIG5lZWRzUXVvdGVzID0gdGhpcy5fbmVlZFF1b3Rlc0ZvckNtZChhcmcpO1xyXG4gICAgICAgIC8vIHNob3J0LWNpcmN1aXQgaWYgcXVvdGVzIG5vdCBuZWVkZWRcclxuICAgICAgICBpZiAoIW5lZWRzUXVvdGVzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBhcmc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgcXVvdGluZyBydWxlcyBhcmUgdmVyeSBzaW1pbGFyIHRvIHRoZSBydWxlcyB0aGF0IGJ5IGxpYnV2IGFwcGxpZXMuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAxKSB3cmFwIHRoZSBzdHJpbmcgaW4gcXVvdGVzXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAyKSBkb3VibGUtdXAgcXVvdGVzIC0gaS5lLiBcIiA9PiBcIlwiXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAgICB0aGlzIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBsaWJ1diBxdW90aW5nIHJ1bGVzLiBsaWJ1diByZXBsYWNlcyBcIiB3aXRoIFxcXCIsIHdoaWNoIHVuZm9ydHVuYXRlbHlcclxuICAgICAgICAvLyAgICBkb2Vzbid0IHdvcmsgd2VsbCB3aXRoIGEgY21kLmV4ZSBjb21tYW5kIGxpbmUuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAgICBub3RlLCByZXBsYWNpbmcgXCIgd2l0aCBcIlwiIGFsc28gd29ya3Mgd2VsbCBpZiB0aGUgYXJnIGlzIHBhc3NlZCB0byBhIGRvd25zdHJlYW0gLk5FVCBjb25zb2xlIGFwcC5cclxuICAgICAgICAvLyAgICBmb3IgZXhhbXBsZSwgdGhlIGNvbW1hbmQgbGluZTpcclxuICAgICAgICAvLyAgICAgICAgICBmb28uZXhlIFwibXlhcmc6XCJcIm15IHZhbFwiXCJcIlxyXG4gICAgICAgIC8vICAgIGlzIHBhcnNlZCBieSBhIC5ORVQgY29uc29sZSBhcHAgaW50byBhbiBhcmcgYXJyYXk6XHJcbiAgICAgICAgLy8gICAgICAgICAgWyBcIm15YXJnOlxcXCJteSB2YWxcXFwiXCIgXVxyXG4gICAgICAgIC8vICAgIHdoaWNoIGlzIHRoZSBzYW1lIGVuZCByZXN1bHQgd2hlbiBhcHBseWluZyBsaWJ1diBxdW90aW5nIHJ1bGVzLiBhbHRob3VnaCB0aGUgYWN0dWFsXHJcbiAgICAgICAgLy8gICAgY29tbWFuZCBsaW5lIGZyb20gbGlidXYgcXVvdGluZyBydWxlcyB3b3VsZCBsb29rIGxpa2U6XHJcbiAgICAgICAgLy8gICAgICAgICAgZm9vLmV4ZSBcIm15YXJnOlxcXCJteSB2YWxcXFwiXCJcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIDMpIGRvdWJsZS11cCBzbGFzaGVzIHRoYXQgcHJlY2VlZCBhIHF1b3RlLFxyXG4gICAgICAgIC8vICAgIGUuZy4gIGhlbGxvIFxcd29ybGQgICAgPT4gXCJoZWxsbyBcXHdvcmxkXCJcclxuICAgICAgICAvLyAgICAgICAgICBoZWxsb1xcXCJ3b3JsZCAgICA9PiBcImhlbGxvXFxcXFwiXCJ3b3JsZFwiXHJcbiAgICAgICAgLy8gICAgICAgICAgaGVsbG9cXFxcXCJ3b3JsZCAgID0+IFwiaGVsbG9cXFxcXFxcXFwiXCJ3b3JsZFwiXHJcbiAgICAgICAgLy8gICAgICAgICAgaGVsbG8gd29ybGRcXCAgICA9PiBcImhlbGxvIHdvcmxkXFxcXFwiXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAgICB0ZWNobmljYWxseSB0aGlzIGlzIG5vdCByZXF1aXJlZCBmb3IgYSBjbWQuZXhlIGNvbW1hbmQgbGluZSwgb3IgdGhlIGJhdGNoIGFyZ3VtZW50IHBhcnNlci5cclxuICAgICAgICAvLyAgICB0aGUgcmVhc29ucyBmb3IgaW5jbHVkaW5nIHRoaXMgYXMgYSAuY21kIHF1b3RpbmcgcnVsZSBhcmU6XHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAgICBhKSB0aGlzIGlzIG9wdGltaXplZCBmb3IgdGhlIHNjZW5hcmlvIHdoZXJlIHRoZSBhcmd1bWVudCBpcyBwYXNzZWQgZnJvbSB0aGUgLmNtZCBmaWxlIHRvIGFuXHJcbiAgICAgICAgLy8gICAgICAgZXh0ZXJuYWwgcHJvZ3JhbS4gbWFueSBwcm9ncmFtcyAoZS5nLiAuTkVUIGNvbnNvbGUgYXBwcykgcmVseSBvbiB0aGUgc2xhc2gtZG91YmxpbmcgcnVsZS5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgIGIpIGl0J3Mgd2hhdCB3ZSd2ZSBiZWVuIGRvaW5nIHByZXZpb3VzbHkgKGJ5IGRlZmVycmluZyB0byBub2RlIGRlZmF1bHQgYmVoYXZpb3IpIGFuZCB3ZVxyXG4gICAgICAgIC8vICAgICAgIGhhdmVuJ3QgaGVhcmQgYW55IGNvbXBsYWludHMgYWJvdXQgdGhhdCBhc3BlY3QuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBub3RlLCBhIHdlYWtuZXNzIG9mIHRoZSBxdW90aW5nIHJ1bGVzIGNob3NlbiBoZXJlLCBpcyB0aGF0ICUgaXMgbm90IGVzY2FwZWQuIGluIGZhY3QsICUgY2Fubm90IGJlXHJcbiAgICAgICAgLy8gZXNjYXBlZCB3aGVuIHVzZWQgb24gdGhlIGNvbW1hbmQgbGluZSBkaXJlY3RseSAtIGV2ZW4gdGhvdWdoIHdpdGhpbiBhIC5jbWQgZmlsZSAlIGNhbiBiZSBlc2NhcGVkXHJcbiAgICAgICAgLy8gYnkgdXNpbmcgJSUuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyB0aGUgc2F2aW5nIGdyYWNlIGlzLCBvbiB0aGUgY29tbWFuZCBsaW5lLCAldmFyJSBpcyBsZWZ0IGFzLWlzIGlmIHZhciBpcyBub3QgZGVmaW5lZC4gdGhpcyBjb250cmFzdHNcclxuICAgICAgICAvLyB0aGUgbGluZSBwYXJzaW5nIHJ1bGVzIHdpdGhpbiBhIC5jbWQgZmlsZSwgd2hlcmUgaWYgdmFyIGlzIG5vdCBkZWZpbmVkIGl0IGlzIHJlcGxhY2VkIHdpdGggbm90aGluZy5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIG9uZSBvcHRpb24gdGhhdCB3YXMgZXhwbG9yZWQgd2FzIHJlcGxhY2luZyAlIHdpdGggXiUgLSBpLmUuICV2YXIlID0+IF4ldmFyXiUuIHRoaXMgaGFjayB3b3VsZFxyXG4gICAgICAgIC8vIG9mdGVuIHdvcmssIHNpbmNlIGl0IGlzIHVubGlrZWx5IHRoYXQgdmFyXiB3b3VsZCBleGlzdCwgYW5kIHRoZSBeIGNoYXJhY3RlciBpcyByZW1vdmVkIHdoZW4gdGhlXHJcbiAgICAgICAgLy8gdmFyaWFibGUgaXMgdXNlZC4gdGhlIHByb2JsZW0sIGhvd2V2ZXIsIGlzIHRoYXQgXiBpcyBub3QgcmVtb3ZlZCB3aGVuICUqIGlzIHVzZWQgdG8gcGFzcyB0aGUgYXJnc1xyXG4gICAgICAgIC8vIHRvIGFuIGV4dGVybmFsIHByb2dyYW0uXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBhbiB1bmV4cGxvcmVkIHBvdGVudGlhbCBzb2x1dGlvbiBmb3IgdGhlICUgZXNjYXBpbmcgcHJvYmxlbSwgaXMgdG8gY3JlYXRlIGEgd3JhcHBlciAuY21kIGZpbGUuXHJcbiAgICAgICAgLy8gJSBjYW4gYmUgZXNjYXBlZCB3aXRoaW4gYSAuY21kIGZpbGUuXHJcbiAgICAgICAgdmFyIHJldmVyc2UgPSAnXCInO1xyXG4gICAgICAgIHZhciBxdW90ZV9oaXQgPSB0cnVlO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSBhcmcubGVuZ3RoOyBpID4gMDsgaS0tKSB7IC8vIHdhbGsgdGhlIHN0cmluZyBpbiByZXZlcnNlXHJcbiAgICAgICAgICAgIHJldmVyc2UgKz0gYXJnW2kgLSAxXTtcclxuICAgICAgICAgICAgaWYgKHF1b3RlX2hpdCAmJiBhcmdbaSAtIDFdID09ICdcXFxcJykge1xyXG4gICAgICAgICAgICAgICAgcmV2ZXJzZSArPSAnXFxcXCc7IC8vIGRvdWJsZSB0aGUgc2xhc2hcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChhcmdbaSAtIDFdID09ICdcIicpIHtcclxuICAgICAgICAgICAgICAgIHF1b3RlX2hpdCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICByZXZlcnNlICs9ICdcIic7IC8vIGRvdWJsZSB0aGUgcXVvdGVcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHF1b3RlX2hpdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldmVyc2UgKz0gJ1wiJztcclxuICAgICAgICByZXR1cm4gcmV2ZXJzZS5zcGxpdCgnJykucmV2ZXJzZSgpLmpvaW4oJycpO1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl91dl9xdW90ZV9jbWRfYXJnID0gZnVuY3Rpb24gKGFyZykge1xyXG4gICAgICAgIC8vIFRvb2wgcnVubmVyIHdyYXBzIGNoaWxkX3Byb2Nlc3Muc3Bhd24oKSBhbmQgbmVlZHMgdG8gYXBwbHkgdGhlIHNhbWUgcXVvdGluZyBhc1xyXG4gICAgICAgIC8vIE5vZGUgaW4gY2VydGFpbiBjYXNlcyB3aGVyZSB0aGUgdW5kb2N1bWVudGVkIHNwYXduIG9wdGlvbiB3aW5kb3dzVmVyYmF0aW1Bcmd1bWVudHNcclxuICAgICAgICAvLyBpcyB1c2VkLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gU2luY2UgdGhpcyBmdW5jdGlvbiBpcyBhIHBvcnQgb2YgcXVvdGVfY21kX2FyZyBmcm9tIE5vZGUgNC54ICh0ZWNobmljYWxseSwgbGliIFVWLFxyXG4gICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvYmxvYi92NC54L2RlcHMvdXYvc3JjL3dpbi9wcm9jZXNzLmMgZm9yIGRldGFpbHMpLFxyXG4gICAgICAgIC8vIHBhc3RpbmcgY29weXJpZ2h0IG5vdGljZSBmcm9tIE5vZGUgd2l0aGluIHRoaXMgZnVuY3Rpb246XHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAgICAgIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gICAgICBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XHJcbiAgICAgICAgLy8gICAgICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xyXG4gICAgICAgIC8vICAgICAgZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcclxuICAgICAgICAvLyAgICAgIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxyXG4gICAgICAgIC8vICAgICAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcclxuICAgICAgICAvLyAgICAgIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyAgICAgIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXHJcbiAgICAgICAgLy8gICAgICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vICAgICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxyXG4gICAgICAgIC8vICAgICAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXHJcbiAgICAgICAgLy8gICAgICBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcclxuICAgICAgICAvLyAgICAgIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcclxuICAgICAgICAvLyAgICAgIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXHJcbiAgICAgICAgLy8gICAgICBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXHJcbiAgICAgICAgLy8gICAgICBJTiBUSEUgU09GVFdBUkUuXHJcbiAgICAgICAgaWYgKCFhcmcpIHtcclxuICAgICAgICAgICAgLy8gTmVlZCBkb3VibGUgcXVvdGF0aW9uIGZvciBlbXB0eSBhcmd1bWVudFxyXG4gICAgICAgICAgICByZXR1cm4gJ1wiXCInO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYXJnLmluZGV4T2YoJyAnKSA8IDAgJiYgYXJnLmluZGV4T2YoJ1xcdCcpIDwgMCAmJiBhcmcuaW5kZXhPZignXCInKSA8IDApIHtcclxuICAgICAgICAgICAgLy8gTm8gcXVvdGF0aW9uIG5lZWRlZFxyXG4gICAgICAgICAgICByZXR1cm4gYXJnO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYXJnLmluZGV4T2YoJ1wiJykgPCAwICYmIGFyZy5pbmRleE9mKCdcXFxcJykgPCAwKSB7XHJcbiAgICAgICAgICAgIC8vIE5vIGVtYmVkZGVkIGRvdWJsZSBxdW90ZXMgb3IgYmFja3NsYXNoZXMsIHNvIEkgY2FuIGp1c3Qgd3JhcFxyXG4gICAgICAgICAgICAvLyBxdW90ZSBtYXJrcyBhcm91bmQgdGhlIHdob2xlIHRoaW5nLlxyXG4gICAgICAgICAgICByZXR1cm4gXCJcXFwiXCIgKyBhcmcgKyBcIlxcXCJcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gRXhwZWN0ZWQgaW5wdXQvb3V0cHV0OlxyXG4gICAgICAgIC8vICAgaW5wdXQgOiBoZWxsb1wid29ybGRcclxuICAgICAgICAvLyAgIG91dHB1dDogXCJoZWxsb1xcXCJ3b3JsZFwiXHJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvXCJcIndvcmxkXHJcbiAgICAgICAgLy8gICBvdXRwdXQ6IFwiaGVsbG9cXFwiXFxcIndvcmxkXCJcclxuICAgICAgICAvLyAgIGlucHV0IDogaGVsbG9cXHdvcmxkXHJcbiAgICAgICAgLy8gICBvdXRwdXQ6IGhlbGxvXFx3b3JsZFxyXG4gICAgICAgIC8vICAgaW5wdXQgOiBoZWxsb1xcXFx3b3JsZFxyXG4gICAgICAgIC8vICAgb3V0cHV0OiBoZWxsb1xcXFx3b3JsZFxyXG4gICAgICAgIC8vICAgaW5wdXQgOiBoZWxsb1xcXCJ3b3JsZFxyXG4gICAgICAgIC8vICAgb3V0cHV0OiBcImhlbGxvXFxcXFxcXCJ3b3JsZFwiXHJcbiAgICAgICAgLy8gICBpbnB1dCA6IGhlbGxvXFxcXFwid29ybGRcclxuICAgICAgICAvLyAgIG91dHB1dDogXCJoZWxsb1xcXFxcXFxcXFxcIndvcmxkXCJcclxuICAgICAgICAvLyAgIGlucHV0IDogaGVsbG8gd29ybGRcXFxyXG4gICAgICAgIC8vICAgb3V0cHV0OiBcImhlbGxvIHdvcmxkXFxcXFwiIC0gbm90ZSB0aGUgY29tbWVudCBpbiBsaWJ1diBhY3R1YWxseSByZWFkcyBcImhlbGxvIHdvcmxkXFxcIlxyXG4gICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXQgaXQgYXBwZWFycyB0aGUgY29tbWVudCBpcyB3cm9uZywgaXQgc2hvdWxkIGJlIFwiaGVsbG8gd29ybGRcXFxcXCJcclxuICAgICAgICB2YXIgcmV2ZXJzZSA9ICdcIic7XHJcbiAgICAgICAgdmFyIHF1b3RlX2hpdCA9IHRydWU7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IGFyZy5sZW5ndGg7IGkgPiAwOyBpLS0pIHsgLy8gd2FsayB0aGUgc3RyaW5nIGluIHJldmVyc2VcclxuICAgICAgICAgICAgcmV2ZXJzZSArPSBhcmdbaSAtIDFdO1xyXG4gICAgICAgICAgICBpZiAocXVvdGVfaGl0ICYmIGFyZ1tpIC0gMV0gPT0gJ1xcXFwnKSB7XHJcbiAgICAgICAgICAgICAgICByZXZlcnNlICs9ICdcXFxcJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChhcmdbaSAtIDFdID09ICdcIicpIHtcclxuICAgICAgICAgICAgICAgIHF1b3RlX2hpdCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICByZXZlcnNlICs9ICdcXFxcJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHF1b3RlX2hpdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldmVyc2UgKz0gJ1wiJztcclxuICAgICAgICByZXR1cm4gcmV2ZXJzZS5zcGxpdCgnJykucmV2ZXJzZSgpLmpvaW4oJycpO1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9jbG9uZUV4ZWNPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0ge1xyXG4gICAgICAgICAgICBjd2Q6IG9wdGlvbnMuY3dkIHx8IHByb2Nlc3MuY3dkKCksXHJcbiAgICAgICAgICAgIGVudjogb3B0aW9ucy5lbnYgfHwgcHJvY2Vzcy5lbnYsXHJcbiAgICAgICAgICAgIHNpbGVudDogb3B0aW9ucy5zaWxlbnQgfHwgZmFsc2UsXHJcbiAgICAgICAgICAgIGZhaWxPblN0ZEVycjogb3B0aW9ucy5mYWlsT25TdGRFcnIgfHwgZmFsc2UsXHJcbiAgICAgICAgICAgIGlnbm9yZVJldHVybkNvZGU6IG9wdGlvbnMuaWdub3JlUmV0dXJuQ29kZSB8fCBmYWxzZSxcclxuICAgICAgICAgICAgd2luZG93c1ZlcmJhdGltQXJndW1lbnRzOiBvcHRpb25zLndpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyB8fCBmYWxzZSxcclxuICAgICAgICAgICAgc2hlbGw6IG9wdGlvbnMuc2hlbGwgfHwgZmFsc2VcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJlc3VsdC5vdXRTdHJlYW0gPSBvcHRpb25zLm91dFN0cmVhbSB8fCBwcm9jZXNzLnN0ZG91dDtcclxuICAgICAgICByZXN1bHQuZXJyU3RyZWFtID0gb3B0aW9ucy5lcnJTdHJlYW0gfHwgcHJvY2Vzcy5zdGRlcnI7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH07XHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5fZ2V0U3Bhd25PcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICAgICAgcmVzdWx0LmN3ZCA9IG9wdGlvbnMuY3dkO1xyXG4gICAgICAgIHJlc3VsdC5lbnYgPSBvcHRpb25zLmVudjtcclxuICAgICAgICByZXN1bHQuc2hlbGwgPSBvcHRpb25zLnNoZWxsO1xyXG4gICAgICAgIHJlc3VsdFsnd2luZG93c1ZlcmJhdGltQXJndW1lbnRzJ10gPSBvcHRpb25zLndpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyB8fCB0aGlzLl9pc0NtZEZpbGUoKTtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLl9nZXRTcGF3blN5bmNPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICAgICAgcmVzdWx0LmN3ZCA9IG9wdGlvbnMuY3dkO1xyXG4gICAgICAgIHJlc3VsdC5lbnYgPSBvcHRpb25zLmVudjtcclxuICAgICAgICByZXN1bHQuc2hlbGwgPSBvcHRpb25zLnNoZWxsO1xyXG4gICAgICAgIHJlc3VsdFsnd2luZG93c1ZlcmJhdGltQXJndW1lbnRzJ10gPSBvcHRpb25zLndpbmRvd3NWZXJiYXRpbUFyZ3VtZW50cyB8fCB0aGlzLl9pc0NtZEZpbGUoKTtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfTtcclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmV4ZWNXaXRoUGlwaW5nID0gZnVuY3Rpb24gKHBpcGVPdXRwdXRUb1Rvb2wsIG9wdGlvbnMpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBfYSwgX2IsIF9jLCBfZDtcclxuICAgICAgICB2YXIgZGVmZXIgPSBRLmRlZmVyKCk7XHJcbiAgICAgICAgdGhpcy5fZGVidWcoJ2V4ZWMgdG9vbDogJyArIHRoaXMudG9vbFBhdGgpO1xyXG4gICAgICAgIHRoaXMuX2RlYnVnKCdhcmd1bWVudHM6Jyk7XHJcbiAgICAgICAgdGhpcy5hcmdzLmZvckVhY2goZnVuY3Rpb24gKGFyZykge1xyXG4gICAgICAgICAgICBfdGhpcy5fZGVidWcoJyAgICcgKyBhcmcpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBzdWNjZXNzID0gdHJ1ZTtcclxuICAgICAgICB2YXIgb3B0aW9uc05vbk51bGwgPSB0aGlzLl9jbG9uZUV4ZWNPcHRpb25zKG9wdGlvbnMpO1xyXG4gICAgICAgIGlmICghb3B0aW9uc05vbk51bGwuc2lsZW50KSB7XHJcbiAgICAgICAgICAgIG9wdGlvbnNOb25OdWxsLm91dFN0cmVhbS53cml0ZSh0aGlzLl9nZXRDb21tYW5kU3RyaW5nKG9wdGlvbnNOb25OdWxsKSArIG9zLkVPTCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBjcDtcclxuICAgICAgICB2YXIgdG9vbFBhdGggPSBwaXBlT3V0cHV0VG9Ub29sLnRvb2xQYXRoO1xyXG4gICAgICAgIHZhciB0b29sUGF0aEZpcnN0O1xyXG4gICAgICAgIHZhciBzdWNjZXNzRmlyc3QgPSB0cnVlO1xyXG4gICAgICAgIHZhciByZXR1cm5Db2RlRmlyc3Q7XHJcbiAgICAgICAgdmFyIGZpbGVTdHJlYW07XHJcbiAgICAgICAgdmFyIHdhaXRpbmdFdmVudHMgPSAwOyAvLyBudW1iZXIgb2YgcHJvY2VzcyBvciBzdHJlYW0gZXZlbnRzIHdlIGFyZSB3YWl0aW5nIG9uIHRvIGNvbXBsZXRlXHJcbiAgICAgICAgdmFyIHJldHVybkNvZGUgPSAwO1xyXG4gICAgICAgIHZhciBlcnJvcjtcclxuICAgICAgICB0b29sUGF0aEZpcnN0ID0gdGhpcy50b29sUGF0aDtcclxuICAgICAgICAvLyBGb2xsb3dpbmcgbm9kZSBkb2N1bWVudGF0aW9uIGV4YW1wbGUgZnJvbSB0aGlzIGxpbmsgb24gaG93IHRvIHBpcGUgb3V0cHV0IG9mIG9uZSBwcm9jZXNzIHRvIGFub3RoZXJcclxuICAgICAgICAvLyBodHRwczovL25vZGVqcy5vcmcvYXBpL2NoaWxkX3Byb2Nlc3MuaHRtbCNjaGlsZF9wcm9jZXNzX2NoaWxkX3Byb2Nlc3Nfc3Bhd25fY29tbWFuZF9hcmdzX29wdGlvbnNcclxuICAgICAgICAvL3N0YXJ0IHRoZSBjaGlsZCBwcm9jZXNzIGZvciBib3RoIHRvb2xzXHJcbiAgICAgICAgd2FpdGluZ0V2ZW50cysrO1xyXG4gICAgICAgIHZhciBjcEZpcnN0ID0gY2hpbGQuc3Bhd24odGhpcy5fZ2V0U3Bhd25GaWxlTmFtZShvcHRpb25zTm9uTnVsbCksIHRoaXMuX2dldFNwYXduQXJncyhvcHRpb25zTm9uTnVsbCksIHRoaXMuX2dldFNwYXduT3B0aW9ucyhvcHRpb25zTm9uTnVsbCkpO1xyXG4gICAgICAgIHdhaXRpbmdFdmVudHMrKztcclxuICAgICAgICBjcCA9IGNoaWxkLnNwYXduKHBpcGVPdXRwdXRUb1Rvb2wuX2dldFNwYXduRmlsZU5hbWUob3B0aW9uc05vbk51bGwpLCBwaXBlT3V0cHV0VG9Ub29sLl9nZXRTcGF3bkFyZ3Mob3B0aW9uc05vbk51bGwpLCBwaXBlT3V0cHV0VG9Ub29sLl9nZXRTcGF3bk9wdGlvbnMob3B0aW9uc05vbk51bGwpKTtcclxuICAgICAgICBmaWxlU3RyZWFtID0gdGhpcy5waXBlT3V0cHV0VG9GaWxlID8gZnMuY3JlYXRlV3JpdGVTdHJlYW0odGhpcy5waXBlT3V0cHV0VG9GaWxlKSA6IG51bGw7XHJcbiAgICAgICAgaWYgKGZpbGVTdHJlYW0pIHtcclxuICAgICAgICAgICAgd2FpdGluZ0V2ZW50cysrO1xyXG4gICAgICAgICAgICBmaWxlU3RyZWFtLm9uKCdmaW5pc2gnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB3YWl0aW5nRXZlbnRzLS07IC8vZmlsZSB3cml0ZSBpcyBjb21wbGV0ZVxyXG4gICAgICAgICAgICAgICAgZmlsZVN0cmVhbSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBpZiAod2FpdGluZ0V2ZW50cyA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVyLnJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZlci5yZXNvbHZlKHJldHVybkNvZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIGZpbGVTdHJlYW0ub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgICAgICAgICAgd2FpdGluZ0V2ZW50cy0tOyAvL3RoZXJlIHdlcmUgZXJyb3JzIHdyaXRpbmcgdG8gdGhlIGZpbGUsIHdyaXRlIGlzIGRvbmVcclxuICAgICAgICAgICAgICAgIF90aGlzLl9kZWJ1ZyhcIkZhaWxlZCB0byBwaXBlIG91dHB1dCBvZiBcIiArIHRvb2xQYXRoRmlyc3QgKyBcIiB0byBmaWxlIFwiICsgX3RoaXMucGlwZU91dHB1dFRvRmlsZSArIFwiLiBFcnJvciA9IFwiICsgZXJyKTtcclxuICAgICAgICAgICAgICAgIGZpbGVTdHJlYW0gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgaWYgKHdhaXRpbmdFdmVudHMgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZlci5yZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXIucmVzb2x2ZShyZXR1cm5Db2RlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvL3BpcGUgc3Rkb3V0IG9mIGZpcnN0IHRvb2wgdG8gc3RkaW4gb2Ygc2Vjb25kIHRvb2xcclxuICAgICAgICAoX2EgPSBjcEZpcnN0LnN0ZG91dCkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLm9uKCdkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHtcclxuICAgICAgICAgICAgdmFyIF9hO1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGZpbGVTdHJlYW0pIHtcclxuICAgICAgICAgICAgICAgICAgICBmaWxlU3RyZWFtLndyaXRlKGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgKF9hID0gY3Auc3RkaW4pID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS53cml0ZShkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5fZGVidWcoJ0ZhaWxlZCB0byBwaXBlIG91dHB1dCBvZiAnICsgdG9vbFBhdGhGaXJzdCArICcgdG8gJyArIHRvb2xQYXRoKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLl9kZWJ1Zyh0b29sUGF0aCArICcgbWlnaHQgaGF2ZSBleGl0ZWQgZHVlIHRvIGVycm9ycyBwcmVtYXR1cmVseS4gVmVyaWZ5IHRoZSBhcmd1bWVudHMgcGFzc2VkIGFyZSB2YWxpZC4nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIChfYiA9IGNwRmlyc3Quc3RkZXJyKSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Iub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICBpZiAoZmlsZVN0cmVhbSkge1xyXG4gICAgICAgICAgICAgICAgZmlsZVN0cmVhbS53cml0ZShkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzdWNjZXNzRmlyc3QgPSAhb3B0aW9uc05vbk51bGwuZmFpbE9uU3RkRXJyO1xyXG4gICAgICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHMgPSBvcHRpb25zTm9uTnVsbC5mYWlsT25TdGRFcnIgPyBvcHRpb25zTm9uTnVsbC5lcnJTdHJlYW0gOiBvcHRpb25zTm9uTnVsbC5vdXRTdHJlYW07XHJcbiAgICAgICAgICAgICAgICBzLndyaXRlKGRhdGEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgY3BGaXJzdC5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgIHZhciBfYTtcclxuICAgICAgICAgICAgd2FpdGluZ0V2ZW50cy0tOyAvL2ZpcnN0IHByb2Nlc3MgaXMgY29tcGxldGUgd2l0aCBlcnJvcnNcclxuICAgICAgICAgICAgaWYgKGZpbGVTdHJlYW0pIHtcclxuICAgICAgICAgICAgICAgIGZpbGVTdHJlYW0uZW5kKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKF9hID0gY3Auc3RkaW4pID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5lbmQoKTtcclxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IodG9vbFBhdGhGaXJzdCArICcgZmFpbGVkLiAnICsgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICBpZiAod2FpdGluZ0V2ZW50cyA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBkZWZlci5yZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgY3BGaXJzdC5vbignY2xvc2UnLCBmdW5jdGlvbiAoY29kZSwgc2lnbmFsKSB7XHJcbiAgICAgICAgICAgIHZhciBfYTtcclxuICAgICAgICAgICAgd2FpdGluZ0V2ZW50cy0tOyAvL2ZpcnN0IHByb2Nlc3MgaXMgY29tcGxldGVcclxuICAgICAgICAgICAgaWYgKGNvZGUgIT0gMCAmJiAhb3B0aW9uc05vbk51bGwuaWdub3JlUmV0dXJuQ29kZSkge1xyXG4gICAgICAgICAgICAgICAgc3VjY2Vzc0ZpcnN0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICByZXR1cm5Db2RlRmlyc3QgPSBjb2RlO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuQ29kZSA9IHJldHVybkNvZGVGaXJzdDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5fZGVidWcoJ3N1Y2Nlc3Mgb2YgZmlyc3QgdG9vbDonICsgc3VjY2Vzc0ZpcnN0KTtcclxuICAgICAgICAgICAgaWYgKGZpbGVTdHJlYW0pIHtcclxuICAgICAgICAgICAgICAgIGZpbGVTdHJlYW0uZW5kKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKF9hID0gY3Auc3RkaW4pID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5lbmQoKTtcclxuICAgICAgICAgICAgaWYgKHdhaXRpbmdFdmVudHMgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmZXIucmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmVyLnJlc29sdmUocmV0dXJuQ29kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgc3RkYnVmZmVyID0gJyc7XHJcbiAgICAgICAgKF9jID0gY3Auc3Rkb3V0KSA9PT0gbnVsbCB8fCBfYyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Mub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICBfdGhpcy5lbWl0KCdzdGRvdXQnLCBkYXRhKTtcclxuICAgICAgICAgICAgaWYgKCFvcHRpb25zTm9uTnVsbC5zaWxlbnQpIHtcclxuICAgICAgICAgICAgICAgIG9wdGlvbnNOb25OdWxsLm91dFN0cmVhbS53cml0ZShkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5fcHJvY2Vzc0xpbmVCdWZmZXIoZGF0YSwgc3RkYnVmZmVyLCBmdW5jdGlvbiAobGluZSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnc3RkbGluZScsIGxpbmUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgZXJyYnVmZmVyID0gJyc7XHJcbiAgICAgICAgKF9kID0gY3Auc3RkZXJyKSA9PT0gbnVsbCB8fCBfZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Qub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICBfdGhpcy5lbWl0KCdzdGRlcnInLCBkYXRhKTtcclxuICAgICAgICAgICAgc3VjY2VzcyA9ICFvcHRpb25zTm9uTnVsbC5mYWlsT25TdGRFcnI7XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9uc05vbk51bGwuc2lsZW50KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcyA9IG9wdGlvbnNOb25OdWxsLmZhaWxPblN0ZEVyciA/IG9wdGlvbnNOb25OdWxsLmVyclN0cmVhbSA6IG9wdGlvbnNOb25OdWxsLm91dFN0cmVhbTtcclxuICAgICAgICAgICAgICAgIHMud3JpdGUoZGF0YSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX3RoaXMuX3Byb2Nlc3NMaW5lQnVmZmVyKGRhdGEsIGVycmJ1ZmZlciwgZnVuY3Rpb24gKGxpbmUpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ2VycmxpbmUnLCBsaW5lKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgY3Aub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgICAgICB3YWl0aW5nRXZlbnRzLS07IC8vcHJvY2VzcyBpcyBkb25lIHdpdGggZXJyb3JzXHJcbiAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKHRvb2xQYXRoICsgJyBmYWlsZWQuICcgKyBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgICAgIGlmICh3YWl0aW5nRXZlbnRzID09IDApIHtcclxuICAgICAgICAgICAgICAgIGRlZmVyLnJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBjcC5vbignY2xvc2UnLCBmdW5jdGlvbiAoY29kZSwgc2lnbmFsKSB7XHJcbiAgICAgICAgICAgIHdhaXRpbmdFdmVudHMtLTsgLy9wcm9jZXNzIGlzIGNvbXBsZXRlXHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1ZygncmM6JyArIGNvZGUpO1xyXG4gICAgICAgICAgICByZXR1cm5Db2RlID0gY29kZTtcclxuICAgICAgICAgICAgaWYgKHN0ZGJ1ZmZlci5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5lbWl0KCdzdGRsaW5lJywgc3RkYnVmZmVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZXJyYnVmZmVyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ2VycmxpbmUnLCBlcnJidWZmZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChjb2RlICE9IDAgJiYgIW9wdGlvbnNOb25OdWxsLmlnbm9yZVJldHVybkNvZGUpIHtcclxuICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5fZGVidWcoJ3N1Y2Nlc3M6JyArIHN1Y2Nlc3MpO1xyXG4gICAgICAgICAgICBpZiAoIXN1Y2Nlc3NGaXJzdCkgeyAvL2luIHRoZSBjYXNlIG91dHB1dCBpcyBwaXBlZCB0byBhbm90aGVyIHRvb2wsIGNoZWNrIGV4aXQgY29kZSBvZiBib3RoIHRvb2xzXHJcbiAgICAgICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcih0b29sUGF0aEZpcnN0ICsgJyBmYWlsZWQgd2l0aCByZXR1cm4gY29kZTogJyArIHJldHVybkNvZGVGaXJzdCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoIXN1Y2Nlc3MpIHtcclxuICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKHRvb2xQYXRoICsgJyBmYWlsZWQgd2l0aCByZXR1cm4gY29kZTogJyArIGNvZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh3YWl0aW5nRXZlbnRzID09IDApIHtcclxuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmVyLnJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWZlci5yZXNvbHZlKHJldHVybkNvZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIGRlZmVyLnByb21pc2U7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBBZGQgYXJndW1lbnRcclxuICAgICAqIEFwcGVuZCBhbiBhcmd1bWVudCBvciBhbiBhcnJheSBvZiBhcmd1bWVudHNcclxuICAgICAqIHJldHVybnMgVG9vbFJ1bm5lciBmb3IgY2hhaW5pbmdcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gICAgIHZhbCAgICAgICAgc3RyaW5nIGNtZGxpbmUgb3IgYXJyYXkgb2Ygc3RyaW5nc1xyXG4gICAgICogQHJldHVybnMgICBUb29sUnVubmVyXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmFyZyA9IGZ1bmN0aW9uICh2YWwpIHtcclxuICAgICAgICBpZiAoIXZhbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIEFycmF5KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RlYnVnKHRoaXMudG9vbFBhdGggKyAnIGFyZzogJyArIEpTT04uc3RyaW5naWZ5KHZhbCkpO1xyXG4gICAgICAgICAgICB0aGlzLmFyZ3MgPSB0aGlzLmFyZ3MuY29uY2F0KHZhbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiAodmFsKSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgdGhpcy5fZGVidWcodGhpcy50b29sUGF0aCArICcgYXJnOiAnICsgdmFsKTtcclxuICAgICAgICAgICAgdGhpcy5hcmdzID0gdGhpcy5hcmdzLmNvbmNhdCh2YWwudHJpbSgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBQYXJzZXMgYW4gYXJndW1lbnQgbGluZSBpbnRvIG9uZSBvciBtb3JlIGFyZ3VtZW50c1xyXG4gICAgICogZS5nLiAubGluZSgnXCJhcmcgb25lXCIgdHdvIC16JykgaXMgZXF1aXZhbGVudCB0byAuYXJnKFsnYXJnIG9uZScsICd0d28nLCAnLXonXSlcclxuICAgICAqIHJldHVybnMgVG9vbFJ1bm5lciBmb3IgY2hhaW5pbmdcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gICAgIHZhbCAgICAgICAgc3RyaW5nIGFyZ3VtZW50IGxpbmVcclxuICAgICAqIEByZXR1cm5zICAgVG9vbFJ1bm5lclxyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5saW5lID0gZnVuY3Rpb24gKHZhbCkge1xyXG4gICAgICAgIGlmICghdmFsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9kZWJ1Zyh0aGlzLnRvb2xQYXRoICsgJyBhcmc6ICcgKyB2YWwpO1xyXG4gICAgICAgIHRoaXMuYXJncyA9IHRoaXMuYXJncy5jb25jYXQodGhpcy5fYXJnU3RyaW5nVG9BcnJheSh2YWwpKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEFkZCBhcmd1bWVudChzKSBpZiBhIGNvbmRpdGlvbiBpcyBtZXRcclxuICAgICAqIFdyYXBzIGFyZygpLiAgU2VlIGFyZyBmb3IgZGV0YWlsc1xyXG4gICAgICogcmV0dXJucyBUb29sUnVubmVyIGZvciBjaGFpbmluZ1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSAgICAgY29uZGl0aW9uICAgICBib29sZWFuIGNvbmRpdGlvblxyXG4gICAgICogQHBhcmFtICAgICB2YWwgICAgIHN0cmluZyBjbWRsaW5lIG9yIGFycmF5IG9mIHN0cmluZ3NcclxuICAgICAqIEByZXR1cm5zICAgVG9vbFJ1bm5lclxyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5hcmdJZiA9IGZ1bmN0aW9uIChjb25kaXRpb24sIHZhbCkge1xyXG4gICAgICAgIGlmIChjb25kaXRpb24pIHtcclxuICAgICAgICAgICAgdGhpcy5hcmcodmFsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBQaXBlIG91dHB1dCBvZiBleGVjKCkgdG8gYW5vdGhlciB0b29sXHJcbiAgICAgKiBAcGFyYW0gdG9vbFxyXG4gICAgICogQHBhcmFtIGZpbGUgIG9wdGlvbmFsIGZpbGVuYW1lIHRvIGFkZGl0aW9uYWxseSBzdHJlYW0gdGhlIG91dHB1dCB0by5cclxuICAgICAqIEByZXR1cm5zIHtUb29sUnVubmVyfVxyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5waXBlRXhlY091dHB1dFRvVG9vbCA9IGZ1bmN0aW9uICh0b29sLCBmaWxlKSB7XHJcbiAgICAgICAgdGhpcy5waXBlT3V0cHV0VG9Ub29sID0gdG9vbDtcclxuICAgICAgICB0aGlzLnBpcGVPdXRwdXRUb0ZpbGUgPSBmaWxlO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRXhlYyBhIHRvb2wuXHJcbiAgICAgKiBPdXRwdXQgd2lsbCBiZSBzdHJlYW1lZCB0byB0aGUgbGl2ZSBjb25zb2xlLlxyXG4gICAgICogUmV0dXJucyBwcm9taXNlIHdpdGggcmV0dXJuIGNvZGVcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gICAgIHRvb2wgICAgIHBhdGggdG8gdG9vbCB0byBleGVjXHJcbiAgICAgKiBAcGFyYW0gICAgIG9wdGlvbnMgIG9wdGlvbmFsIGV4ZWMgb3B0aW9ucy4gIFNlZSBJRXhlY09wdGlvbnNcclxuICAgICAqIEByZXR1cm5zICAgbnVtYmVyXHJcbiAgICAgKi9cclxuICAgIFRvb2xSdW5uZXIucHJvdG90eXBlLmV4ZWMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIF9hLCBfYiwgX2M7XHJcbiAgICAgICAgaWYgKHRoaXMucGlwZU91dHB1dFRvVG9vbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5leGVjV2l0aFBpcGluZyh0aGlzLnBpcGVPdXRwdXRUb1Rvb2wsIG9wdGlvbnMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgZGVmZXIgPSBRLmRlZmVyKCk7XHJcbiAgICAgICAgdGhpcy5fZGVidWcoJ2V4ZWMgdG9vbDogJyArIHRoaXMudG9vbFBhdGgpO1xyXG4gICAgICAgIHRoaXMuX2RlYnVnKCdhcmd1bWVudHM6Jyk7XHJcbiAgICAgICAgdGhpcy5hcmdzLmZvckVhY2goZnVuY3Rpb24gKGFyZykge1xyXG4gICAgICAgICAgICBfdGhpcy5fZGVidWcoJyAgICcgKyBhcmcpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBvcHRpb25zTm9uTnVsbCA9IHRoaXMuX2Nsb25lRXhlY09wdGlvbnMob3B0aW9ucyk7XHJcbiAgICAgICAgaWYgKCFvcHRpb25zTm9uTnVsbC5zaWxlbnQpIHtcclxuICAgICAgICAgICAgb3B0aW9uc05vbk51bGwub3V0U3RyZWFtLndyaXRlKHRoaXMuX2dldENvbW1hbmRTdHJpbmcob3B0aW9uc05vbk51bGwpICsgb3MuRU9MKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHN0YXRlID0gbmV3IEV4ZWNTdGF0ZShvcHRpb25zTm9uTnVsbCwgdGhpcy50b29sUGF0aCk7XHJcbiAgICAgICAgc3RhdGUub24oJ2RlYnVnJywgZnVuY3Rpb24gKG1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgX3RoaXMuX2RlYnVnKG1lc3NhZ2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBjcCA9IGNoaWxkLnNwYXduKHRoaXMuX2dldFNwYXduRmlsZU5hbWUob3B0aW9ucyksIHRoaXMuX2dldFNwYXduQXJncyhvcHRpb25zTm9uTnVsbCksIHRoaXMuX2dldFNwYXduT3B0aW9ucyhvcHRpb25zKSk7XHJcbiAgICAgICAgdGhpcy5jaGlsZFByb2Nlc3MgPSBjcDtcclxuICAgICAgICAvLyBpdCBpcyBwb3NzaWJsZSBmb3IgdGhlIGNoaWxkIHByb2Nlc3MgdG8gZW5kIGl0cyBsYXN0IGxpbmUgd2l0aG91dCBhIG5ldyBsaW5lLlxyXG4gICAgICAgIC8vIGJlY2F1c2Ugc3Rkb3V0IGlzIGJ1ZmZlcmVkLCB0aGlzIGNhdXNlcyB0aGUgbGFzdCBsaW5lIHRvIG5vdCBnZXQgc2VudCB0byB0aGUgcGFyZW50XHJcbiAgICAgICAgLy8gc3RyZWFtLiBBZGRpbmcgdGhpcyBldmVudCBmb3JjZXMgYSBmbHVzaCBiZWZvcmUgdGhlIGNoaWxkIHN0cmVhbXMgYXJlIGNsb3NlZC5cclxuICAgICAgICAoX2EgPSBjcC5zdGRvdXQpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5vbignZmluaXNoJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoIW9wdGlvbnNOb25OdWxsLnNpbGVudCkge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9uc05vbk51bGwub3V0U3RyZWFtLndyaXRlKG9zLkVPTCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgc3RkYnVmZmVyID0gJyc7XHJcbiAgICAgICAgKF9iID0gY3Auc3Rkb3V0KSA9PT0gbnVsbCB8fCBfYiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Iub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICBfdGhpcy5lbWl0KCdzdGRvdXQnLCBkYXRhKTtcclxuICAgICAgICAgICAgaWYgKCFvcHRpb25zTm9uTnVsbC5zaWxlbnQpIHtcclxuICAgICAgICAgICAgICAgIG9wdGlvbnNOb25OdWxsLm91dFN0cmVhbS53cml0ZShkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5fcHJvY2Vzc0xpbmVCdWZmZXIoZGF0YSwgc3RkYnVmZmVyLCBmdW5jdGlvbiAobGluZSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnc3RkbGluZScsIGxpbmUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgZXJyYnVmZmVyID0gJyc7XHJcbiAgICAgICAgKF9jID0gY3Auc3RkZXJyKSA9PT0gbnVsbCB8fCBfYyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Mub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICBzdGF0ZS5wcm9jZXNzU3RkZXJyID0gdHJ1ZTtcclxuICAgICAgICAgICAgX3RoaXMuZW1pdCgnc3RkZXJyJywgZGF0YSk7XHJcbiAgICAgICAgICAgIGlmICghb3B0aW9uc05vbk51bGwuc2lsZW50KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcyA9IG9wdGlvbnNOb25OdWxsLmZhaWxPblN0ZEVyciA/IG9wdGlvbnNOb25OdWxsLmVyclN0cmVhbSA6IG9wdGlvbnNOb25OdWxsLm91dFN0cmVhbTtcclxuICAgICAgICAgICAgICAgIHMud3JpdGUoZGF0YSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX3RoaXMuX3Byb2Nlc3NMaW5lQnVmZmVyKGRhdGEsIGVycmJ1ZmZlciwgZnVuY3Rpb24gKGxpbmUpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ2VycmxpbmUnLCBsaW5lKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgY3Aub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgICAgICBzdGF0ZS5wcm9jZXNzRXJyb3IgPSBlcnIubWVzc2FnZTtcclxuICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0V4aXRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NDbG9zZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBzdGF0ZS5DaGVja0NvbXBsZXRlKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgY3Aub24oJ2V4aXQnLCBmdW5jdGlvbiAoY29kZSwgc2lnbmFsKSB7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFeGl0Q29kZSA9IGNvZGU7XHJcbiAgICAgICAgICAgIHN0YXRlLnByb2Nlc3NFeGl0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBfdGhpcy5fZGVidWcoXCJFeGl0IGNvZGUgXCIgKyBjb2RlICsgXCIgcmVjZWl2ZWQgZnJvbSB0b29sICdcIiArIF90aGlzLnRvb2xQYXRoICsgXCInXCIpO1xyXG4gICAgICAgICAgICBzdGF0ZS5DaGVja0NvbXBsZXRlKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgY3Aub24oJ2Nsb3NlJywgZnVuY3Rpb24gKGNvZGUsIHNpZ25hbCkge1xyXG4gICAgICAgICAgICBzdGF0ZS5wcm9jZXNzRXhpdENvZGUgPSBjb2RlO1xyXG4gICAgICAgICAgICBzdGF0ZS5wcm9jZXNzRXhpdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgc3RhdGUucHJvY2Vzc0Nsb3NlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1ZyhcIlNURElPIHN0cmVhbXMgaGF2ZSBjbG9zZWQgZm9yIHRvb2wgJ1wiICsgX3RoaXMudG9vbFBhdGggKyBcIidcIik7XHJcbiAgICAgICAgICAgIHN0YXRlLkNoZWNrQ29tcGxldGUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBzdGF0ZS5vbignZG9uZScsIGZ1bmN0aW9uIChlcnJvciwgZXhpdENvZGUpIHtcclxuICAgICAgICAgICAgaWYgKHN0ZGJ1ZmZlci5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5lbWl0KCdzdGRsaW5lJywgc3RkYnVmZmVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZXJyYnVmZmVyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmVtaXQoJ2VycmxpbmUnLCBlcnJidWZmZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNwLnJlbW92ZUFsbExpc3RlbmVycygpO1xyXG4gICAgICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIGRlZmVyLnJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBkZWZlci5yZXNvbHZlKGV4aXRDb2RlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBkZWZlci5wcm9taXNlO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRXhlYyBhIHRvb2wgc3luY2hyb25vdXNseS5cclxuICAgICAqIE91dHB1dCB3aWxsIGJlICpub3QqIGJlIHN0cmVhbWVkIHRvIHRoZSBsaXZlIGNvbnNvbGUuICBJdCB3aWxsIGJlIHJldHVybmVkIGFmdGVyIGV4ZWN1dGlvbiBpcyBjb21wbGV0ZS5cclxuICAgICAqIEFwcHJvcHJpYXRlIGZvciBzaG9ydCBydW5uaW5nIHRvb2xzXHJcbiAgICAgKiBSZXR1cm5zIElFeGVjU3luY1Jlc3VsdCB3aXRoIG91dHB1dCBhbmQgcmV0dXJuIGNvZGVcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gICAgIHRvb2wgICAgIHBhdGggdG8gdG9vbCB0byBleGVjXHJcbiAgICAgKiBAcGFyYW0gICAgIG9wdGlvbnMgIG9wdGlvbmFsIGV4ZWMgb3B0aW9ucy4gIFNlZSBJRXhlY1N5bmNPcHRpb25zXHJcbiAgICAgKiBAcmV0dXJucyAgIElFeGVjU3luY1Jlc3VsdFxyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5leGVjU3luYyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB0aGlzLl9kZWJ1ZygnZXhlYyB0b29sOiAnICsgdGhpcy50b29sUGF0aCk7XHJcbiAgICAgICAgdGhpcy5fZGVidWcoJ2FyZ3VtZW50czonKTtcclxuICAgICAgICB0aGlzLmFyZ3MuZm9yRWFjaChmdW5jdGlvbiAoYXJnKSB7XHJcbiAgICAgICAgICAgIF90aGlzLl9kZWJ1ZygnICAgJyArIGFyZyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIHN1Y2Nlc3MgPSB0cnVlO1xyXG4gICAgICAgIG9wdGlvbnMgPSB0aGlzLl9jbG9uZUV4ZWNPcHRpb25zKG9wdGlvbnMpO1xyXG4gICAgICAgIGlmICghb3B0aW9ucy5zaWxlbnQpIHtcclxuICAgICAgICAgICAgb3B0aW9ucy5vdXRTdHJlYW0ud3JpdGUodGhpcy5fZ2V0Q29tbWFuZFN0cmluZyhvcHRpb25zKSArIG9zLkVPTCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciByID0gY2hpbGQuc3Bhd25TeW5jKHRoaXMuX2dldFNwYXduRmlsZU5hbWUob3B0aW9ucyksIHRoaXMuX2dldFNwYXduQXJncyhvcHRpb25zKSwgdGhpcy5fZ2V0U3Bhd25TeW5jT3B0aW9ucyhvcHRpb25zKSk7XHJcbiAgICAgICAgaWYgKCFvcHRpb25zLnNpbGVudCAmJiByLnN0ZG91dCAmJiByLnN0ZG91dC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIG9wdGlvbnMub3V0U3RyZWFtLndyaXRlKHIuc3Rkb3V0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFvcHRpb25zLnNpbGVudCAmJiByLnN0ZGVyciAmJiByLnN0ZGVyci5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIG9wdGlvbnMuZXJyU3RyZWFtLndyaXRlKHIuc3RkZXJyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHJlcyA9IHsgY29kZTogci5zdGF0dXMsIGVycm9yOiByLmVycm9yIH07XHJcbiAgICAgICAgcmVzLnN0ZG91dCA9IChyLnN0ZG91dCkgPyByLnN0ZG91dC50b1N0cmluZygpIDogJyc7XHJcbiAgICAgICAgcmVzLnN0ZGVyciA9IChyLnN0ZGVycikgPyByLnN0ZGVyci50b1N0cmluZygpIDogJyc7XHJcbiAgICAgICAgcmV0dXJuIHJlcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFVzZWQgdG8gY2xvc2UgY2hpbGQgcHJvY2VzcyBieSBzZW5kaW5nIFNJR05JTlQgc2lnbmFsLlxyXG4gICAgICogSXQgYWxsb3dzIGV4ZWN1dGVkIHNjcmlwdCB0byBoYXZlIHNvbWUgYWRkaXRpb25hbCBsb2dpYyBvbiBTSUdJTlQsIGJlZm9yZSBleGl0aW5nLlxyXG4gICAgICovXHJcbiAgICBUb29sUnVubmVyLnByb3RvdHlwZS5raWxsQ2hpbGRQcm9jZXNzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmNoaWxkUHJvY2Vzcykge1xyXG4gICAgICAgICAgICB0aGlzLmNoaWxkUHJvY2Vzcy5raWxsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBUb29sUnVubmVyO1xyXG59KGV2ZW50cy5FdmVudEVtaXR0ZXIpKTtcclxuZXhwb3J0cy5Ub29sUnVubmVyID0gVG9vbFJ1bm5lcjtcclxudmFyIEV4ZWNTdGF0ZSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhFeGVjU3RhdGUsIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBFeGVjU3RhdGUob3B0aW9ucywgdG9vbFBhdGgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmRlbGF5ID0gMTAwMDA7IC8vIDEwIHNlY29uZHNcclxuICAgICAgICBfdGhpcy50aW1lb3V0ID0gbnVsbDtcclxuICAgICAgICBpZiAoIXRvb2xQYXRoKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndG9vbFBhdGggbXVzdCBub3QgYmUgZW1wdHknKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgX3RoaXMub3B0aW9ucyA9IG9wdGlvbnM7XHJcbiAgICAgICAgX3RoaXMudG9vbFBhdGggPSB0b29sUGF0aDtcclxuICAgICAgICB2YXIgZGVsYXkgPSBwcm9jZXNzLmVudlsnVEFTS0xJQl9URVNUX1RPT0xSVU5ORVJfRVhJVERFTEFZJ107XHJcbiAgICAgICAgaWYgKGRlbGF5KSB7XHJcbiAgICAgICAgICAgIF90aGlzLmRlbGF5ID0gcGFyc2VJbnQoZGVsYXkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBFeGVjU3RhdGUucHJvdG90eXBlLkNoZWNrQ29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZG9uZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLnByb2Nlc3NDbG9zZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2V0UmVzdWx0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMucHJvY2Vzc0V4aXRlZCkge1xyXG4gICAgICAgICAgICB0aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KEV4ZWNTdGF0ZS5IYW5kbGVUaW1lb3V0LCB0aGlzLmRlbGF5LCB0aGlzKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgRXhlY1N0YXRlLnByb3RvdHlwZS5fZGVidWcgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCBtZXNzYWdlKTtcclxuICAgIH07XHJcbiAgICBFeGVjU3RhdGUucHJvdG90eXBlLl9zZXRSZXN1bHQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlcmUgaXMgYW4gZXJyb3JcclxuICAgICAgICB2YXIgZXJyb3I7XHJcbiAgICAgICAgaWYgKHRoaXMucHJvY2Vzc0V4aXRlZCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5wcm9jZXNzRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKGltLl9sb2MoJ0xJQl9Qcm9jZXNzRXJyb3InLCB0aGlzLnRvb2xQYXRoLCB0aGlzLnByb2Nlc3NFcnJvcikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMucHJvY2Vzc0V4aXRDb2RlICE9IDAgJiYgIXRoaXMub3B0aW9ucy5pZ25vcmVSZXR1cm5Db2RlKSB7XHJcbiAgICAgICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihpbS5fbG9jKCdMSUJfUHJvY2Vzc0V4aXRDb2RlJywgdGhpcy50b29sUGF0aCwgdGhpcy5wcm9jZXNzRXhpdENvZGUpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLnByb2Nlc3NTdGRlcnIgJiYgdGhpcy5vcHRpb25zLmZhaWxPblN0ZEVycikge1xyXG4gICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoaW0uX2xvYygnTElCX1Byb2Nlc3NTdGRlcnInLCB0aGlzLnRvb2xQYXRoKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY2xlYXIgdGhlIHRpbWVvdXRcclxuICAgICAgICBpZiAodGhpcy50aW1lb3V0KSB7XHJcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpO1xyXG4gICAgICAgICAgICB0aGlzLnRpbWVvdXQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmRvbmUgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuZW1pdCgnZG9uZScsIGVycm9yLCB0aGlzLnByb2Nlc3NFeGl0Q29kZSk7XHJcbiAgICB9O1xyXG4gICAgRXhlY1N0YXRlLkhhbmRsZVRpbWVvdXQgPSBmdW5jdGlvbiAoc3RhdGUpIHtcclxuICAgICAgICBpZiAoc3RhdGUuZG9uZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghc3RhdGUucHJvY2Vzc0Nsb3NlZCAmJiBzdGF0ZS5wcm9jZXNzRXhpdGVkKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGltLl9sb2MoJ0xJQl9TdGRpb05vdENsb3NlZCcsIHN0YXRlLmRlbGF5IC8gMTAwMCwgc3RhdGUudG9vbFBhdGgpKTtcclxuICAgICAgICAgICAgc3RhdGUuX2RlYnVnKGltLl9sb2MoJ0xJQl9TdGRpb05vdENsb3NlZCcsIHN0YXRlLmRlbGF5IC8gMTAwMCwgc3RhdGUudG9vbFBhdGgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc3RhdGUuX3NldFJlc3VsdCgpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBFeGVjU3RhdGU7XHJcbn0oZXZlbnRzLkV2ZW50RW1pdHRlcikpO1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG5leHBvcnRzLlZhdWx0ID0gdm9pZCAwO1xyXG52YXIgZnMgPSByZXF1aXJlKFwiZnNcIik7XHJcbnZhciBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XHJcbnZhciBjcnlwdG8gPSByZXF1aXJlKFwiY3J5cHRvXCIpO1xyXG52YXIgdXVpZFY0ID0gcmVxdWlyZSgndXVpZC92NCcpO1xyXG52YXIgYWxnb3JpdGhtID0gXCJhZXMtMjU2LWN0clwiO1xyXG52YXIgZW5jcnlwdEVuY29kaW5nID0gJ2hleCc7XHJcbnZhciB1bmVuY3J5cHRlZEVuY29kaW5nID0gJ3V0ZjgnO1xyXG4vL1xyXG4vLyBTdG9yZSBzZW5zaXRpdmUgZGF0YSBpbiBwcm9jLlxyXG4vLyBNYWluIGdvYWw6IFByb3RlY3RzIHRhc2tzIHdoaWNoIHdvdWxkIGR1bXAgZW52dmFycyBmcm9tIGxlYWtpbmcgc2VjcmV0cyBpbmFkdmVydGVudGx5XHJcbi8vICAgICAgICAgICAgdGhlIHRhc2sgbGliIGNsZWFycyBhZnRlciBzdG9yaW5nLlxyXG4vLyBBbHNvIHByb3RlY3RzIGFnYWluc3QgYSBkdW1wIG9mIGEgcHJvY2VzcyBnZXR0aW5nIHRoZSBzZWNyZXRzXHJcbi8vIFRoZSBzZWNyZXQgaXMgZ2VuZXJhdGVkIGFuZCBzdG9yZWQgZXh0ZXJuYWxseSBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZSB0YXNrLlxyXG4vL1xyXG52YXIgVmF1bHQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBWYXVsdChrZXlQYXRoKSB7XHJcbiAgICAgICAgdGhpcy5fa2V5RmlsZSA9IHBhdGguam9pbihrZXlQYXRoLCAnLnRhc2trZXknKTtcclxuICAgICAgICB0aGlzLl9zdG9yZSA9IHt9O1xyXG4gICAgICAgIHRoaXMuZ2VuS2V5KCk7XHJcbiAgICB9XHJcbiAgICBWYXVsdC5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIH07XHJcbiAgICBWYXVsdC5wcm90b3R5cGUuc3RvcmVTZWNyZXQgPSBmdW5jdGlvbiAobmFtZSwgZGF0YSkge1xyXG4gICAgICAgIGlmICghbmFtZSB8fCBuYW1lLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICBpZiAoIWRhdGEgfHwgZGF0YS5sZW5ndGggPT0gMCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RvcmUuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9zdG9yZVtuYW1lXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBrZXkgPSB0aGlzLmdldEtleSgpO1xyXG4gICAgICAgIHZhciBpdiA9IGNyeXB0by5yYW5kb21CeXRlcygxNik7XHJcbiAgICAgICAgdmFyIGNpcGhlciA9IGNyeXB0by5jcmVhdGVDaXBoZXJpdihhbGdvcml0aG0sIGtleSwgaXYpO1xyXG4gICAgICAgIHZhciBjcnlwdGVkID0gY2lwaGVyLnVwZGF0ZShkYXRhLCB1bmVuY3J5cHRlZEVuY29kaW5nLCBlbmNyeXB0RW5jb2RpbmcpO1xyXG4gICAgICAgIHZhciBjcnlwdGVkRmluYWwgPSBjaXBoZXIuZmluYWwoZW5jcnlwdEVuY29kaW5nKTtcclxuICAgICAgICB0aGlzLl9zdG9yZVtuYW1lXSA9IGl2LnRvU3RyaW5nKGVuY3J5cHRFbmNvZGluZykgKyBjcnlwdGVkICsgY3J5cHRlZEZpbmFsO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfTtcclxuICAgIFZhdWx0LnByb3RvdHlwZS5yZXRyaWV2ZVNlY3JldCA9IGZ1bmN0aW9uIChuYW1lKSB7XHJcbiAgICAgICAgdmFyIHNlY3JldDtcclxuICAgICAgICBuYW1lID0gKG5hbWUgfHwgJycpLnRvTG93ZXJDYXNlKCk7XHJcbiAgICAgICAgaWYgKHRoaXMuX3N0b3JlLmhhc093blByb3BlcnR5KG5hbWUpKSB7XHJcbiAgICAgICAgICAgIHZhciBrZXkgPSB0aGlzLmdldEtleSgpO1xyXG4gICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX3N0b3JlW25hbWVdO1xyXG4gICAgICAgICAgICB2YXIgaXZEYXRhQnVmZmVyID0gQnVmZmVyLmZyb20oZGF0YSwgZW5jcnlwdEVuY29kaW5nKTtcclxuICAgICAgICAgICAgdmFyIGl2ID0gaXZEYXRhQnVmZmVyLnNsaWNlKDAsIDE2KTtcclxuICAgICAgICAgICAgdmFyIGVuY3J5cHRlZFRleHQgPSBpdkRhdGFCdWZmZXIuc2xpY2UoMTYpO1xyXG4gICAgICAgICAgICB2YXIgZGVjaXBoZXIgPSBjcnlwdG8uY3JlYXRlRGVjaXBoZXJpdihhbGdvcml0aG0sIGtleSwgaXYpO1xyXG4gICAgICAgICAgICB2YXIgZGVjID0gZGVjaXBoZXIudXBkYXRlKGVuY3J5cHRlZFRleHQsIGVuY3J5cHRFbmNvZGluZywgdW5lbmNyeXB0ZWRFbmNvZGluZyk7XHJcbiAgICAgICAgICAgIHZhciBkZWNGaW5hbCA9IGRlY2lwaGVyLmZpbmFsKHVuZW5jcnlwdGVkRW5jb2RpbmcpO1xyXG4gICAgICAgICAgICBzZWNyZXQgPSBkZWMgKyBkZWNGaW5hbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNlY3JldDtcclxuICAgIH07XHJcbiAgICBWYXVsdC5wcm90b3R5cGUuZ2V0S2V5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBrZXkgPSBmcy5yZWFkRmlsZVN5bmModGhpcy5fa2V5RmlsZSkudG9TdHJpbmcoJ3V0ZjgnKTtcclxuICAgICAgICAvLyBLZXkgbmVlZHMgdG8gYmUgaGFzaGVkIHRvIGNvcnJlY3QgbGVuZ3RoIHRvIG1hdGNoIGFsZ29yaXRobSAoYWVzLTI1Ni1jdHIpXHJcbiAgICAgICAgcmV0dXJuIGNyeXB0by5jcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoa2V5KS5kaWdlc3QoKTtcclxuICAgIH07XHJcbiAgICBWYXVsdC5wcm90b3R5cGUuZ2VuS2V5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmModGhpcy5fa2V5RmlsZSwgdXVpZFY0KCksIHsgZW5jb2Rpbmc6ICd1dGY4JyB9KTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gVmF1bHQ7XHJcbn0oKSk7XHJcbmV4cG9ydHMuVmF1bHQgPSBWYXVsdDtcclxuIiwiZnVuY3Rpb24gd2VicGFja0VtcHR5Q29udGV4dChyZXEpIHtcblx0dmFyIGUgPSBuZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiICsgcmVxICsgXCInXCIpO1xuXHRlLmNvZGUgPSAnTU9EVUxFX05PVF9GT1VORCc7XG5cdHRocm93IGU7XG59XG53ZWJwYWNrRW1wdHlDb250ZXh0LmtleXMgPSAoKSA9PiAoW10pO1xud2VicGFja0VtcHR5Q29udGV4dC5yZXNvbHZlID0gd2VicGFja0VtcHR5Q29udGV4dDtcbndlYnBhY2tFbXB0eUNvbnRleHQuaWQgPSBcIi4vbm9kZV9tb2R1bGVzL2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYiBzeW5jIHJlY3Vyc2l2ZVwiO1xubW9kdWxlLmV4cG9ydHMgPSB3ZWJwYWNrRW1wdHlDb250ZXh0OyIsIi8qKlxuICogQ29udmVydCBhcnJheSBvZiAxNiBieXRlIHZhbHVlcyB0byBVVUlEIHN0cmluZyBmb3JtYXQgb2YgdGhlIGZvcm06XG4gKiBYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFhcbiAqL1xudmFyIGJ5dGVUb0hleCA9IFtdO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXhbaV0gPSAoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpO1xufVxuXG5mdW5jdGlvbiBieXRlc1RvVXVpZChidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IG9mZnNldCB8fCAwO1xuICB2YXIgYnRoID0gYnl0ZVRvSGV4O1xuICAvLyBqb2luIHVzZWQgdG8gZml4IG1lbW9yeSBpc3N1ZSBjYXVzZWQgYnkgY29uY2F0ZW5hdGlvbjogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzE3NSNjNFxuICByZXR1cm4gKFtcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcbiAgICBidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLFxuICAgIGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG4gICAgYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXVxuICBdKS5qb2luKCcnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBieXRlc1RvVXVpZDtcbiIsIi8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuICBJbiBub2RlLmpzXG4vLyB0aGlzIGlzIHByZXR0eSBzdHJhaWdodC1mb3J3YXJkIC0gd2UgdXNlIHRoZSBjcnlwdG8gQVBJLlxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbm9kZVJORygpIHtcbiAgcmV0dXJuIGNyeXB0by5yYW5kb21CeXRlcygxNik7XG59O1xuIiwidmFyIHJuZyA9IHJlcXVpcmUoJy4vbGliL3JuZycpO1xudmFyIGJ5dGVzVG9VdWlkID0gcmVxdWlyZSgnLi9saWIvYnl0ZXNUb1V1aWQnKTtcblxuZnVuY3Rpb24gdjQob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgdmFyIGkgPSBidWYgJiYgb2Zmc2V0IHx8IDA7XG5cbiAgaWYgKHR5cGVvZihvcHRpb25zKSA9PSAnc3RyaW5nJykge1xuICAgIGJ1ZiA9IG9wdGlvbnMgPT09ICdiaW5hcnknID8gbmV3IEFycmF5KDE2KSA6IG51bGw7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdmFyIHJuZHMgPSBvcHRpb25zLnJhbmRvbSB8fCAob3B0aW9ucy5ybmcgfHwgcm5nKSgpO1xuXG4gIC8vIFBlciA0LjQsIHNldCBiaXRzIGZvciB2ZXJzaW9uIGFuZCBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGBcbiAgcm5kc1s2XSA9IChybmRzWzZdICYgMHgwZikgfCAweDQwO1xuICBybmRzWzhdID0gKHJuZHNbOF0gJiAweDNmKSB8IDB4ODA7XG5cbiAgLy8gQ29weSBieXRlcyB0byBidWZmZXIsIGlmIHByb3ZpZGVkXG4gIGlmIChidWYpIHtcbiAgICBmb3IgKHZhciBpaSA9IDA7IGlpIDwgMTY7ICsraWkpIHtcbiAgICAgIGJ1ZltpICsgaWldID0gcm5kc1tpaV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ1ZiB8fCBieXRlc1RvVXVpZChybmRzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB2NDtcbiIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn07XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuZXhwb3J0cy5zY3JhcGUgPSBleHBvcnRzLmV4dHJhY3RaaXAgPSBleHBvcnRzLmV4dHJhY3RUYXIgPSBleHBvcnRzLmV4dHJhY3Q3eiA9IGV4cG9ydHMuY2FjaGVGaWxlID0gZXhwb3J0cy5jYWNoZURpciA9IGV4cG9ydHMuZG93bmxvYWRUb29sID0gZXhwb3J0cy5maW5kTG9jYWxUb29sVmVyc2lvbnMgPSBleHBvcnRzLmZpbmRMb2NhbFRvb2wgPSBleHBvcnRzLmV2YWx1YXRlVmVyc2lvbnMgPSBleHBvcnRzLmNsZWFuVmVyc2lvbiA9IGV4cG9ydHMuaXNFeHBsaWNpdFZlcnNpb24gPSBleHBvcnRzLnByZXBlbmRQYXRoID0gZXhwb3J0cy5kZWJ1ZyA9IHZvaWQgMDtcclxuY29uc3QgaHR0cG0gPSByZXF1aXJlKFwidHlwZWQtcmVzdC1jbGllbnQvSHR0cENsaWVudFwiKTtcclxuY29uc3QgcGF0aCA9IHJlcXVpcmUoXCJwYXRoXCIpO1xyXG5jb25zdCBvcyA9IHJlcXVpcmUoXCJvc1wiKTtcclxuY29uc3QgcHJvY2VzcyA9IHJlcXVpcmUoXCJwcm9jZXNzXCIpO1xyXG5jb25zdCBmcyA9IHJlcXVpcmUoXCJmc1wiKTtcclxuY29uc3Qgc2VtdmVyID0gcmVxdWlyZShcInNlbXZlclwiKTtcclxuY29uc3QgdGwgPSByZXF1aXJlKFwiYXp1cmUtcGlwZWxpbmVzLXRhc2stbGliL3Rhc2tcIik7XHJcbmNvbnN0IGNtcCA9IHJlcXVpcmUoJ3NlbXZlci1jb21wYXJlJyk7XHJcbmNvbnN0IHV1aWRWNCA9IHJlcXVpcmUoJ3V1aWQvdjQnKTtcclxubGV0IHBrZyA9IHJlcXVpcmUocGF0aC5qb2luKF9fZGlybmFtZSwgJ3BhY2thZ2UuanNvbicpKTtcclxubGV0IHVzZXJBZ2VudCA9ICd2c3RzLXRhc2staW5zdGFsbGVyLycgKyBwa2cudmVyc2lvbjtcclxubGV0IHJlcXVlc3RPcHRpb25zID0ge1xyXG4gICAgLy8gaWdub3JlU3NsRXJyb3I6IHRydWUsXHJcbiAgICBwcm94eTogdGwuZ2V0SHR0cFByb3h5Q29uZmlndXJhdGlvbigpLFxyXG4gICAgY2VydDogdGwuZ2V0SHR0cENlcnRDb25maWd1cmF0aW9uKCksXHJcbiAgICBhbGxvd1JlZGlyZWN0czogdHJ1ZSxcclxuICAgIGFsbG93UmV0cmllczogdHJ1ZSxcclxuICAgIG1heFJldHJpZXM6IDJcclxufTtcclxudGwuc2V0UmVzb3VyY2VQYXRoKHBhdGguam9pbihfX2Rpcm5hbWUsICdsaWIuanNvbicpKTtcclxuZnVuY3Rpb24gZGVidWcobWVzc2FnZSkge1xyXG4gICAgdGwuZGVidWcobWVzc2FnZSk7XHJcbn1cclxuZXhwb3J0cy5kZWJ1ZyA9IGRlYnVnO1xyXG5mdW5jdGlvbiBwcmVwZW5kUGF0aCh0b29sUGF0aCkge1xyXG4gICAgdGwuYXNzZXJ0QWdlbnQoJzIuMTE1LjAnKTtcclxuICAgIGlmICghdG9vbFBhdGgpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhcmFtZXRlciB0b29sUGF0aCBtdXN0IG5vdCBiZSBudWxsIG9yIGVtcHR5Jyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICghdGwuZXhpc3QodG9vbFBhdGgpIHx8ICF0bC5zdGF0cyh0b29sUGF0aCkuaXNEaXJlY3RvcnkoKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRGlyZWN0b3J5IGRvZXMgbm90IGV4aXN0OiAnICsgdG9vbFBhdGgpO1xyXG4gICAgfVxyXG4gICAgLy8gdG9kbzogYWRkIGEgdGVzdCBmb3IgcGF0aFxyXG4gICAgY29uc29sZS5sb2codGwubG9jKCdUT09MX0xJQl9QcmVwZW5kUGF0aCcsIHRvb2xQYXRoKSk7XHJcbiAgICBsZXQgbmV3UGF0aCA9IHRvb2xQYXRoICsgcGF0aC5kZWxpbWl0ZXIgKyBwcm9jZXNzLmVudlsnUEFUSCddO1xyXG4gICAgdGwuZGVidWcoJ25ldyBQYXRoOiAnICsgbmV3UGF0aCk7XHJcbiAgICBwcm9jZXNzLmVudlsnUEFUSCddID0gbmV3UGF0aDtcclxuICAgIC8vIGluc3RydWN0IHRoZSBhZ2VudCB0byBzZXQgdGhpcyBwYXRoIG9uIGZ1dHVyZSB0YXNrc1xyXG4gICAgY29uc29sZS5sb2coJyMjdnNvW3Rhc2sucHJlcGVuZHBhdGhdJyArIHRvb2xQYXRoKTtcclxufVxyXG5leHBvcnRzLnByZXBlbmRQYXRoID0gcHJlcGVuZFBhdGg7XHJcbmZ1bmN0aW9uIGRlbGF5KG1zKSB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XHJcbn1cclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBWZXJzaW9uIEZ1bmN0aW9uc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBDaGVja3MgaWYgYSB2ZXJzaW9uIHNwZWMgaXMgYW4gZXhwbGljaXQgdmVyc2lvbiAoZS5nLiAxLjAuMSBvciB2MS4wLjEpXHJcbiAqIEFzIG9wcG9zZWQgdG8gYSB2ZXJzaW9uIHNwZWMgbGlrZSAxLnhcclxuICpcclxuICogQHBhcmFtIHZlcnNpb25TcGVjXHJcbiAqL1xyXG5mdW5jdGlvbiBpc0V4cGxpY2l0VmVyc2lvbih2ZXJzaW9uU3BlYykge1xyXG4gICAgbGV0IGMgPSBzZW12ZXIuY2xlYW4odmVyc2lvblNwZWMpO1xyXG4gICAgdGwuZGVidWcoJ2lzRXhwbGljaXQ6ICcgKyBjKTtcclxuICAgIGxldCB2YWxpZCA9IHNlbXZlci52YWxpZChjKSAhPSBudWxsO1xyXG4gICAgdGwuZGVidWcoJ2V4cGxpY2l0PyAnICsgdmFsaWQpO1xyXG4gICAgcmV0dXJuIHZhbGlkO1xyXG59XHJcbmV4cG9ydHMuaXNFeHBsaWNpdFZlcnNpb24gPSBpc0V4cGxpY2l0VmVyc2lvbjtcclxuLyoqXHJcbiAqIFJldHVybnMgY2xlYW5lZCAocmVtb3ZlZCBsZWFkaW5nL3RyYWlsaW5nIHdoaXRlc3BhY2UsIHJlbW92ZSAnPXYnIHByZWZpeClcclxuICogYW5kIHBhcnNlZCB2ZXJzaW9uLCBvciBudWxsIGlmIHZlcnNpb24gaXMgaW52YWxpZC5cclxuICovXHJcbmZ1bmN0aW9uIGNsZWFuVmVyc2lvbih2ZXJzaW9uKSB7XHJcbiAgICB0bC5kZWJ1ZygnY2xlYW5pbmc6ICcgKyB2ZXJzaW9uKTtcclxuICAgIHJldHVybiBzZW12ZXIuY2xlYW4odmVyc2lvbik7XHJcbn1cclxuZXhwb3J0cy5jbGVhblZlcnNpb24gPSBjbGVhblZlcnNpb247XHJcbi8qKlxyXG4gKiBldmFsdWF0ZXMgYSBsaXN0IG9mIHZlcnNpb25zIGFuZCByZXR1cm5zIHRoZSBsYXRlc3QgdmVyc2lvbiBtYXRjaGluZyB0aGUgdmVyc2lvbiBzcGVjXHJcbiAqXHJcbiAqIEBwYXJhbSB2ZXJzaW9ucyAgICAgIGFuIGFycmF5IG9mIHZlcnNpb25zIHRvIGV2YWx1YXRlXHJcbiAqIEBwYXJhbSB2ZXJzaW9uU3BlYyAgIGEgdmVyc2lvbiBzcGVjIChlLmcuIDEueClcclxuICovXHJcbmZ1bmN0aW9uIGV2YWx1YXRlVmVyc2lvbnModmVyc2lvbnMsIHZlcnNpb25TcGVjKSB7XHJcbiAgICBsZXQgdmVyc2lvbjtcclxuICAgIHRsLmRlYnVnKCdldmFsdWF0aW5nICcgKyB2ZXJzaW9ucy5sZW5ndGggKyAnIHZlcnNpb25zJyk7XHJcbiAgICB2ZXJzaW9ucyA9IHZlcnNpb25zLnNvcnQoY21wKTtcclxuICAgIGZvciAobGV0IGkgPSB2ZXJzaW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIGxldCBwb3RlbnRpYWwgPSB2ZXJzaW9uc1tpXTtcclxuICAgICAgICBsZXQgc2F0aXNmaWVkID0gc2VtdmVyLnNhdGlzZmllcyhwb3RlbnRpYWwsIHZlcnNpb25TcGVjKTtcclxuICAgICAgICBpZiAoc2F0aXNmaWVkKSB7XHJcbiAgICAgICAgICAgIHZlcnNpb24gPSBwb3RlbnRpYWw7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh2ZXJzaW9uKSB7XHJcbiAgICAgICAgdGwuZGVidWcoJ21hdGNoZWQ6ICcgKyB2ZXJzaW9uKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHRsLmRlYnVnKCdtYXRjaCBub3QgZm91bmQnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB2ZXJzaW9uO1xyXG59XHJcbmV4cG9ydHMuZXZhbHVhdGVWZXJzaW9ucyA9IGV2YWx1YXRlVmVyc2lvbnM7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gTG9jYWwgVG9vbCBDYWNoZSBGdW5jdGlvbnNcclxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKipcclxuICogZmluZHMgdGhlIHBhdGggdG8gYSB0b29sIGluIHRoZSBsb2NhbCBpbnN0YWxsZWQgdG9vbCBjYWNoZVxyXG4gKlxyXG4gKiBAcGFyYW0gdG9vbE5hbWUgICAgICBuYW1lIG9mIHRoZSB0b29sXHJcbiAqIEBwYXJhbSB2ZXJzaW9uU3BlYyAgIHZlcnNpb24gb2YgdGhlIHRvb2xcclxuICogQHBhcmFtIGFyY2ggICAgICAgICAgb3B0aW9uYWwgYXJjaC4gIGRlZmF1bHRzIHRvIGFyY2ggb2YgY29tcHV0ZXJcclxuICovXHJcbmZ1bmN0aW9uIGZpbmRMb2NhbFRvb2wodG9vbE5hbWUsIHZlcnNpb25TcGVjLCBhcmNoKSB7XHJcbiAgICBpZiAoIXRvb2xOYW1lKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0b29sTmFtZSBwYXJhbWV0ZXIgaXMgcmVxdWlyZWQnKTtcclxuICAgIH1cclxuICAgIGlmICghdmVyc2lvblNwZWMpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZlcnNpb25TcGVjIHBhcmFtZXRlciBpcyByZXF1aXJlZCcpO1xyXG4gICAgfVxyXG4gICAgYXJjaCA9IGFyY2ggfHwgb3MuYXJjaCgpO1xyXG4gICAgLy8gYXR0ZW1wdCB0byByZXNvbHZlIGFuIGV4cGxpY2l0IHZlcnNpb25cclxuICAgIGlmICghaXNFeHBsaWNpdFZlcnNpb24odmVyc2lvblNwZWMpKSB7XHJcbiAgICAgICAgbGV0IGxvY2FsVmVyc2lvbnMgPSBmaW5kTG9jYWxUb29sVmVyc2lvbnModG9vbE5hbWUsIGFyY2gpO1xyXG4gICAgICAgIGxldCBtYXRjaCA9IGV2YWx1YXRlVmVyc2lvbnMobG9jYWxWZXJzaW9ucywgdmVyc2lvblNwZWMpO1xyXG4gICAgICAgIHZlcnNpb25TcGVjID0gbWF0Y2g7XHJcbiAgICB9XHJcbiAgICAvLyBjaGVjayBmb3IgdGhlIGV4cGxpY2l0IHZlcnNpb24gaW4gdGhlIGNhY2hlXHJcbiAgICBsZXQgdG9vbFBhdGg7XHJcbiAgICBpZiAodmVyc2lvblNwZWMpIHtcclxuICAgICAgICB2ZXJzaW9uU3BlYyA9IHNlbXZlci5jbGVhbih2ZXJzaW9uU3BlYyk7XHJcbiAgICAgICAgbGV0IGNhY2hlUm9vdCA9IF9nZXRDYWNoZVJvb3QoKTtcclxuICAgICAgICBsZXQgY2FjaGVQYXRoID0gcGF0aC5qb2luKGNhY2hlUm9vdCwgdG9vbE5hbWUsIHZlcnNpb25TcGVjLCBhcmNoKTtcclxuICAgICAgICB0bC5kZWJ1ZygnY2hlY2tpbmcgY2FjaGU6ICcgKyBjYWNoZVBhdGgpO1xyXG4gICAgICAgIGlmICh0bC5leGlzdChjYWNoZVBhdGgpICYmIHRsLmV4aXN0KGAke2NhY2hlUGF0aH0uY29tcGxldGVgKSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0bC5sb2MoJ1RPT0xfTElCX0ZvdW5kSW5DYWNoZScsIHRvb2xOYW1lLCB2ZXJzaW9uU3BlYywgYXJjaCkpO1xyXG4gICAgICAgICAgICB0b29sUGF0aCA9IGNhY2hlUGF0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRsLmRlYnVnKCdub3QgZm91bmQnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG9vbFBhdGg7XHJcbn1cclxuZXhwb3J0cy5maW5kTG9jYWxUb29sID0gZmluZExvY2FsVG9vbDtcclxuLyoqXHJcbiAqIFJldHJpZXZlcyB0aGUgdmVyc2lvbnMgb2YgYSB0b29sIHRoYXQgaXMgaW50YWxsZWQgaW4gdGhlIGxvY2FsIHRvb2wgY2FjaGVcclxuICpcclxuICogQHBhcmFtIHRvb2xOYW1lICBuYW1lIG9mIHRoZSB0b29sXHJcbiAqIEBwYXJhbSBhcmNoICAgICAgb3B0aW9uYWwgYXJjaC4gIGRlZmF1bHRzIHRvIGFyY2ggb2YgY29tcHV0ZXJcclxuICovXHJcbmZ1bmN0aW9uIGZpbmRMb2NhbFRvb2xWZXJzaW9ucyh0b29sTmFtZSwgYXJjaCkge1xyXG4gICAgbGV0IHZlcnNpb25zID0gW107XHJcbiAgICBhcmNoID0gYXJjaCB8fCBvcy5hcmNoKCk7XHJcbiAgICBsZXQgdG9vbFBhdGggPSBwYXRoLmpvaW4oX2dldENhY2hlUm9vdCgpLCB0b29sTmFtZSk7XHJcbiAgICBpZiAodGwuZXhpc3QodG9vbFBhdGgpKSB7XHJcbiAgICAgICAgbGV0IGNoaWxkcmVuID0gdGwubHMoJycsIFt0b29sUGF0aF0pO1xyXG4gICAgICAgIGNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChpc0V4cGxpY2l0VmVyc2lvbihjaGlsZCkpIHtcclxuICAgICAgICAgICAgICAgIGxldCBmdWxsUGF0aCA9IHBhdGguam9pbih0b29sUGF0aCwgY2hpbGQsIGFyY2gpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRsLmV4aXN0KGZ1bGxQYXRoKSAmJiB0bC5leGlzdChgJHtmdWxsUGF0aH0uY29tcGxldGVgKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZlcnNpb25zLnB1c2goY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmVyc2lvbnM7XHJcbn1cclxuZXhwb3J0cy5maW5kTG9jYWxUb29sVmVyc2lvbnMgPSBmaW5kTG9jYWxUb29sVmVyc2lvbnM7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIERvd25sb2FkIEZ1bmN0aW9uc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vL1xyXG4vLyBUT0RPOiBrZWVwIGV4dGVuc2lvbiBpbnRhY3RcclxuLy9cclxuLyoqXHJcbiAqIERvd25sb2FkIGEgdG9vbCBmcm9tIGFuIHVybCBhbmQgc3RyZWFtIGl0IGludG8gYSBmaWxlXHJcbiAqXHJcbiAqIEBwYXJhbSB1cmwgICAgICAgdXJsIG9mIHRvb2wgdG8gZG93bmxvYWRcclxuICogQHBhcmFtIGZpbGVOYW1lICBvcHRpb25hbCBmaWxlTmFtZS4gIFNob3VsZCB0eXBpY2FsbHkgbm90IHVzZSAod2lsbCBiZSBhIGd1aWQgZm9yIHJlbGlhYmlsaXR5KS4gQ2FuIHBhc3MgZmlsZU5hbWUgd2l0aCBhbiBhYnNvbHV0ZSBwYXRoLlxyXG4gKiBAcGFyYW0gaGFuZGxlcnMgIG9wdGlvbmFsIGhhbmRsZXJzIGFycmF5LiAgQXV0aCBoYW5kbGVycyB0byBwYXNzIHRvIHRoZSBIdHRwQ2xpZW50IGZvciB0aGUgdG9vbCBkb3dubG9hZC5cclxuICovXHJcbmZ1bmN0aW9uIGRvd25sb2FkVG9vbCh1cmwsIGZpbGVOYW1lLCBoYW5kbGVycykge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgaGFuZGxlcnMgPSBoYW5kbGVycyB8fCBudWxsO1xyXG4gICAgICAgICAgICAgICAgbGV0IGh0dHAgPSBuZXcgaHR0cG0uSHR0cENsaWVudCh1c2VyQWdlbnQsIGhhbmRsZXJzLCByZXF1ZXN0T3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICB0bC5kZWJ1ZyhmaWxlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IGZpbGVOYW1lIHx8IHV1aWRWNCgpO1xyXG4gICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQncyBhbiBhYnNvbHV0ZSBwYXRoIGFscmVhZHlcclxuICAgICAgICAgICAgICAgIHZhciBkZXN0UGF0aDtcclxuICAgICAgICAgICAgICAgIGlmIChwYXRoLmlzQWJzb2x1dGUoZmlsZU5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVzdFBhdGggPSBmaWxlTmFtZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlc3RQYXRoID0gcGF0aC5qb2luKF9nZXRBZ2VudFRlbXAoKSwgZmlsZU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgdGhlIGZvbGRlciBleGlzdHNcclxuICAgICAgICAgICAgICAgIHRsLm1rZGlyUChwYXRoLmRpcm5hbWUoZGVzdFBhdGgpKTtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHRsLmxvYygnVE9PTF9MSUJfRG93bmxvYWRpbmcnLCB1cmwpKTtcclxuICAgICAgICAgICAgICAgIHRsLmRlYnVnKCdkZXN0aW5hdGlvbiAnICsgZGVzdFBhdGgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoZGVzdFBhdGgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGVzdGluYXRpb24gZmlsZSBwYXRoIGFscmVhZHkgZXhpc3RzXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGwuZGVidWcoJ2Rvd25sb2FkaW5nJyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSB5aWVsZCBodHRwLmdldCh1cmwpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZSAhPSAyMDApIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZXJyID0gbmV3IEVycm9yKCdVbmV4cGVjdGVkIEhUVFAgcmVzcG9uc2U6ICcgKyByZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVyclsnaHR0cFN0YXR1c0NvZGUnXSA9IHJlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZTtcclxuICAgICAgICAgICAgICAgICAgICB0bC5kZWJ1ZyhgRmFpbGVkIHRvIGRvd25sb2FkIFwiJHtmaWxlTmFtZX1cIiBmcm9tIFwiJHt1cmx9XCIuIENvZGUoJHtyZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGV9KSBNZXNzYWdlKCR7cmVzcG9uc2UubWVzc2FnZS5zdGF0dXNNZXNzYWdlfSlgKTtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0bC5kZWJ1ZygnY3JlYXRpbmcgc3RyZWFtJyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgZmlsZSA9IGZzLmNyZWF0ZVdyaXRlU3RyZWFtKGRlc3RQYXRoKTtcclxuICAgICAgICAgICAgICAgIGZpbGUub24oJ29wZW4nLCAoZmQpID0+IF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgc3RyZWFtID0gcmVzcG9uc2UubWVzc2FnZS5waXBlKGZpbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0ub24oJ2Nsb3NlJywgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGwuZGVidWcoJ2Rvd25sb2FkIGNvbXBsZXRlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGRlc3RQYXRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICAgICAgZmlsZS5vbignZXJyb3InLCAoZXJyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlsZS5lbmQoKTtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pKTtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuZG93bmxvYWRUb29sID0gZG93bmxvYWRUb29sO1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyBJbnN0YWxsIEZ1bmN0aW9uc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5mdW5jdGlvbiBfY3JlYXRlVG9vbFBhdGgodG9vbCwgdmVyc2lvbiwgYXJjaCkge1xyXG4gICAgLy8gdG9kbzogYWRkIHRlc3QgZm9yIGNsZWFuXHJcbiAgICBsZXQgZm9sZGVyUGF0aCA9IHBhdGguam9pbihfZ2V0Q2FjaGVSb290KCksIHRvb2wsIHNlbXZlci5jbGVhbih2ZXJzaW9uKSwgYXJjaCk7XHJcbiAgICB0bC5kZWJ1ZygnZGVzdGluYXRpb24gJyArIGZvbGRlclBhdGgpO1xyXG4gICAgbGV0IG1hcmtlclBhdGggPSBgJHtmb2xkZXJQYXRofS5jb21wbGV0ZWA7XHJcbiAgICB0bC5ybVJGKGZvbGRlclBhdGgpO1xyXG4gICAgdGwucm1SRihtYXJrZXJQYXRoKTtcclxuICAgIHRsLm1rZGlyUChmb2xkZXJQYXRoKTtcclxuICAgIHJldHVybiBmb2xkZXJQYXRoO1xyXG59XHJcbmZ1bmN0aW9uIF9jb21wbGV0ZVRvb2xQYXRoKHRvb2wsIHZlcnNpb24sIGFyY2gpIHtcclxuICAgIGxldCBmb2xkZXJQYXRoID0gcGF0aC5qb2luKF9nZXRDYWNoZVJvb3QoKSwgdG9vbCwgc2VtdmVyLmNsZWFuKHZlcnNpb24pLCBhcmNoKTtcclxuICAgIGxldCBtYXJrZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0uY29tcGxldGVgO1xyXG4gICAgdGwud3JpdGVGaWxlKG1hcmtlclBhdGgsICcnKTtcclxuICAgIHRsLmRlYnVnKCdmaW5pc2hlZCBjYWNoaW5nIHRvb2wnKTtcclxufVxyXG4vKipcclxuICogQ2FjaGVzIGEgZGlyZWN0b3J5IGFuZCBpbnN0YWxscyBpdCBpbnRvIHRoZSB0b29sIGNhY2hlRGlyXHJcbiAqXHJcbiAqIEBwYXJhbSBzb3VyY2VEaXIgICAgdGhlIGRpcmVjdG9yeSB0byBjYWNoZSBpbnRvIHRvb2xzXHJcbiAqIEBwYXJhbSB0b29sICAgICAgICAgIHRvb2wgbmFtZVxyXG4gKiBAcGFyYW0gdmVyc2lvbiAgICAgICB2ZXJzaW9uIG9mIHRoZSB0b29sLiAgc2VtdmVyIGZvcm1hdFxyXG4gKiBAcGFyYW0gYXJjaCAgICAgICAgICBhcmNoaXRlY3R1cmUgb2YgdGhlIHRvb2wuICBPcHRpb25hbC4gIERlZmF1bHRzIHRvIG1hY2hpbmUgYXJjaGl0ZWN0dXJlXHJcbiAqL1xyXG5mdW5jdGlvbiBjYWNoZURpcihzb3VyY2VEaXIsIHRvb2wsIHZlcnNpb24sIGFyY2gpIHtcclxuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgdmVyc2lvbiA9IHNlbXZlci5jbGVhbih2ZXJzaW9uKTtcclxuICAgICAgICBhcmNoID0gYXJjaCB8fCBvcy5hcmNoKCk7XHJcbiAgICAgICAgY29uc29sZS5sb2codGwubG9jKCdUT09MX0xJQl9DYWNoaW5nVG9vbCcsIHRvb2wsIHZlcnNpb24sIGFyY2gpKTtcclxuICAgICAgICB0bC5kZWJ1Zygnc291cmNlIGRpcjogJyArIHNvdXJjZURpcik7XHJcbiAgICAgICAgaWYgKCF0bC5zdGF0cyhzb3VyY2VEaXIpLmlzRGlyZWN0b3J5KCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VEaXIgaXMgbm90IGEgZGlyZWN0b3J5Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgdG9vbCBkaXJcclxuICAgICAgICBsZXQgZGVzdFBhdGggPSBfY3JlYXRlVG9vbFBhdGgodG9vbCwgdmVyc2lvbiwgYXJjaCk7XHJcbiAgICAgICAgLy8gY29weSBlYWNoIGNoaWxkIGl0ZW0uIGRvIG5vdCBtb3ZlLiBtb3ZlIGNhbiBmYWlsIG9uIFdpbmRvd3NcclxuICAgICAgICAvLyBkdWUgdG8gYW50aS12aXJ1cyBzb2Z0d2FyZSBoYXZpbmcgYW4gb3BlbiBoYW5kbGUgb24gYSBmaWxlLlxyXG4gICAgICAgIGZvciAobGV0IGl0ZW1OYW1lIG9mIGZzLnJlYWRkaXJTeW5jKHNvdXJjZURpcikpIHtcclxuICAgICAgICAgICAgbGV0IHMgPSBwYXRoLmpvaW4oc291cmNlRGlyLCBpdGVtTmFtZSk7XHJcbiAgICAgICAgICAgIHRsLmNwKHMsIGRlc3RQYXRoICsgJy8nLCAnLXInKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gd3JpdGUgLmNvbXBsZXRlXHJcbiAgICAgICAgX2NvbXBsZXRlVG9vbFBhdGgodG9vbCwgdmVyc2lvbiwgYXJjaCk7XHJcbiAgICAgICAgcmV0dXJuIGRlc3RQYXRoO1xyXG4gICAgfSk7XHJcbn1cclxuZXhwb3J0cy5jYWNoZURpciA9IGNhY2hlRGlyO1xyXG4vKipcclxuICogQ2FjaGVzIGEgZG93bmxvYWRlZCBmaWxlIChHVUlEKSBhbmQgaW5zdGFsbHMgaXRcclxuICogaW50byB0aGUgdG9vbCBjYWNoZSB3aXRoIGEgZ2l2ZW4gdGFyZ2V0TmFtZVxyXG4gKlxyXG4gKiBAcGFyYW0gc291cmNlRmlsZSAgICB0aGUgZmlsZSB0byBjYWNoZSBpbnRvIHRvb2xzLiAgVHlwaWNhbGx5IGEgcmVzdWx0IG9mIGRvd25sb2FkVG9vbCB3aGljaCBpcyBhIGd1aWQuXHJcbiAqIEBwYXJhbSB0YXJnZXRGaWxlICAgIHRoZSBuYW1lIG9mIHRoZSBmaWxlIG5hbWUgaW4gdGhlIHRvb2xzIGRpcmVjdG9yeVxyXG4gKiBAcGFyYW0gdG9vbCAgICAgICAgICB0b29sIG5hbWVcclxuICogQHBhcmFtIHZlcnNpb24gICAgICAgdmVyc2lvbiBvZiB0aGUgdG9vbC4gIHNlbXZlciBmb3JtYXRcclxuICogQHBhcmFtIGFyY2ggICAgICAgICAgYXJjaGl0ZWN0dXJlIG9mIHRoZSB0b29sLiAgT3B0aW9uYWwuICBEZWZhdWx0cyB0byBtYWNoaW5lIGFyY2hpdGVjdHVyZVxyXG4gKi9cclxuZnVuY3Rpb24gY2FjaGVGaWxlKHNvdXJjZUZpbGUsIHRhcmdldEZpbGUsIHRvb2wsIHZlcnNpb24sIGFyY2gpIHtcclxuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XHJcbiAgICAgICAgdmVyc2lvbiA9IHNlbXZlci5jbGVhbih2ZXJzaW9uKTtcclxuICAgICAgICBhcmNoID0gYXJjaCB8fCBvcy5hcmNoKCk7XHJcbiAgICAgICAgY29uc29sZS5sb2codGwubG9jKCdUT09MX0xJQl9DYWNoaW5nVG9vbCcsIHRvb2wsIHZlcnNpb24sIGFyY2gpKTtcclxuICAgICAgICB0bC5kZWJ1Zygnc291cmNlIGZpbGU6JyArIHNvdXJjZUZpbGUpO1xyXG4gICAgICAgIGlmICghdGwuc3RhdHMoc291cmNlRmlsZSkuaXNGaWxlKCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VGaWxlIGlzIG5vdCBhIGZpbGUnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY3JlYXRlIHRoZSB0b29sIGRpclxyXG4gICAgICAgIGxldCBkZXN0Rm9sZGVyID0gX2NyZWF0ZVRvb2xQYXRoKHRvb2wsIHZlcnNpb24sIGFyY2gpO1xyXG4gICAgICAgIC8vIGNvcHkgaW5zdGVhZCBvZiBtb3ZlLiBtb3ZlIGNhbiBmYWlsIG9uIFdpbmRvd3MgZHVlIHRvXHJcbiAgICAgICAgLy8gYW50aS12aXJ1cyBzb2Z0d2FyZSBoYXZpbmcgYW4gb3BlbiBoYW5kbGUgb24gYSBmaWxlLlxyXG4gICAgICAgIGxldCBkZXN0UGF0aCA9IHBhdGguam9pbihkZXN0Rm9sZGVyLCB0YXJnZXRGaWxlKTtcclxuICAgICAgICB0bC5kZWJ1ZygnZGVzdGluYXRpb24gZmlsZScgKyBkZXN0UGF0aCk7XHJcbiAgICAgICAgdGwuY3Aoc291cmNlRmlsZSwgZGVzdFBhdGgpO1xyXG4gICAgICAgIC8vIHdyaXRlIC5jb21wbGV0ZVxyXG4gICAgICAgIF9jb21wbGV0ZVRvb2xQYXRoKHRvb2wsIHZlcnNpb24sIGFyY2gpO1xyXG4gICAgICAgIHJldHVybiBkZXN0Rm9sZGVyO1xyXG4gICAgfSk7XHJcbn1cclxuZXhwb3J0cy5jYWNoZUZpbGUgPSBjYWNoZUZpbGU7XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIEV4dHJhY3QgRnVuY3Rpb25zXHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qKlxyXG4gKiBFeHRyYWN0IGEgLjd6IGZpbGVcclxuICpcclxuICogQHBhcmFtIGZpbGUgICAgIHBhdGggdG8gdGhlIC43eiBmaWxlXHJcbiAqIEBwYXJhbSBkZXN0ICAgICBkZXN0aW5hdGlvbiBkaXJlY3RvcnkuIE9wdGlvbmFsLlxyXG4gKiBAcGFyYW0gXzd6UGF0aCAgcGF0aCB0byA3enIuZXhlLiBPcHRpb25hbCwgZm9yIGxvbmcgcGF0aCBzdXBwb3J0LiBNb3N0IC43eiBhcmNoaXZlcyBkbyBub3QgaGF2ZSB0aGlzXHJcbiAqIHByb2JsZW0uIElmIHlvdXIgLjd6IGFyY2hpdmUgY29udGFpbnMgdmVyeSBsb25nIHBhdGhzLCB5b3UgY2FuIHBhc3MgdGhlIHBhdGggdG8gN3pyLmV4ZSB3aGljaCB3aWxsXHJcbiAqIGdyYWNlZnVsbHkgaGFuZGxlIGxvbmcgcGF0aHMuIEJ5IGRlZmF1bHQgN3pkZWMuZXhlIGlzIHVzZWQgYmVjYXVzZSBpdCBpcyBhIHZlcnkgc21hbGwgcHJvZ3JhbSBhbmQgaXNcclxuICogYnVuZGxlZCB3aXRoIHRoZSB0b29sIGxpYi4gSG93ZXZlciBpdCBkb2VzIG5vdCBzdXBwb3J0IGxvbmcgcGF0aHMuIDd6ci5leGUgaXMgdGhlIHJlZHVjZWQgY29tbWFuZCBsaW5lXHJcbiAqIGludGVyZmFjZSwgaXQgaXMgc21hbGxlciB0aGFuIHRoZSBmdWxsIGNvbW1hbmQgbGluZSBpbnRlcmZhY2UsIGFuZCBpdCBkb2VzIHN1cHBvcnQgbG9uZyBwYXRocy4gQXQgdGhlXHJcbiAqIHRpbWUgb2YgdGhpcyB3cml0aW5nLCBpdCBpcyBmcmVlbHkgYXZhaWxhYmxlIGZyb20gdGhlIExaTUEgU0RLIHRoYXQgaXMgYXZhaWxhYmxlIG9uIHRoZSA3emlwIHdlYnNpdGUuXHJcbiAqIEJlIHN1cmUgdG8gY2hlY2sgdGhlIGN1cnJlbnQgbGljZW5zZSBhZ3JlZW1lbnQuIElmIDd6ci5leGUgaXMgYnVuZGxlZCB3aXRoIHlvdXIgdGFzaywgdGhlbiB0aGUgcGF0aFxyXG4gKiB0byA3enIuZXhlIGNhbiBiZSBwYXNzIHRvIHRoaXMgZnVuY3Rpb24uXHJcbiAqIEByZXR1cm5zICAgICAgICBwYXRoIHRvIHRoZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnlcclxuICovXHJcbmZ1bmN0aW9uIGV4dHJhY3Q3eihmaWxlLCBkZXN0LCBfN3pQYXRoKSB7XHJcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtICE9ICd3aW4zMicpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdleHRyYWN0N3ooKSBub3Qgc3VwcG9ydGVkIG9uIGN1cnJlbnQgT1MnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFmaWxlKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInBhcmFtZXRlciAnZmlsZScgaXMgcmVxdWlyZWRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnNvbGUubG9nKHRsLmxvYygnVE9PTF9MSUJfRXh0cmFjdGluZ0FyY2hpdmUnKSk7XHJcbiAgICAgICAgZGVzdCA9IF9jcmVhdGVFeHRyYWN0Rm9sZGVyKGRlc3QpO1xyXG4gICAgICAgIGxldCBvcmlnaW5hbEN3ZCA9IHByb2Nlc3MuY3dkKCk7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcHJvY2Vzcy5jaGRpcihkZXN0KTtcclxuICAgICAgICAgICAgaWYgKF83elBhdGgpIHtcclxuICAgICAgICAgICAgICAgIC8vIGV4dHJhY3RcclxuICAgICAgICAgICAgICAgIGxldCBfN3ogPSB0bC50b29sKF83elBhdGgpXHJcbiAgICAgICAgICAgICAgICAgICAgLmFyZygneCcpIC8vIGVYdHJhY3QgZmlsZXMgd2l0aCBmdWxsIHBhdGhzXHJcbiAgICAgICAgICAgICAgICAgICAgLmFyZygnLWJiMScpIC8vIC1iYlswLTNdIDogc2V0IG91dHB1dCBsb2cgbGV2ZWxcclxuICAgICAgICAgICAgICAgICAgICAuYXJnKCctYmQnKSAvLyBkaXNhYmxlIHByb2dyZXNzIGluZGljYXRvclxyXG4gICAgICAgICAgICAgICAgICAgIC5hcmcoJy1zY2NVVEYtOCcpIC8vIHNldCBjaGFyc2V0IGZvciBmb3IgY29uc29sZSBpbnB1dC9vdXRwdXRcclxuICAgICAgICAgICAgICAgICAgICAuYXJnKGZpbGUpO1xyXG4gICAgICAgICAgICAgICAgeWllbGQgXzd6LmV4ZWMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIGV4dHJhY3RcclxuICAgICAgICAgICAgICAgIGxldCBlc2NhcGVkU2NyaXB0ID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJ0ludm9rZS03emRlYy5wczEnKS5yZXBsYWNlKC8nL2csIFwiJydcIikucmVwbGFjZSgvXCJ8XFxufFxcci9nLCAnJyk7IC8vIGRvdWJsZS11cCBzaW5nbGUgcXVvdGVzLCByZW1vdmUgZG91YmxlIHF1b3RlcyBhbmQgbmV3bGluZXNcclxuICAgICAgICAgICAgICAgIGxldCBlc2NhcGVkRmlsZSA9IGZpbGUucmVwbGFjZSgvJy9nLCBcIicnXCIpLnJlcGxhY2UoL1wifFxcbnxcXHIvZywgJycpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGVzY2FwZWRUYXJnZXQgPSBkZXN0LnJlcGxhY2UoLycvZywgXCInJ1wiKS5yZXBsYWNlKC9cInxcXG58XFxyL2csICcnKTtcclxuICAgICAgICAgICAgICAgIGxldCBjb21tYW5kID0gYCYgJyR7ZXNjYXBlZFNjcmlwdH0nIC1Tb3VyY2UgJyR7ZXNjYXBlZEZpbGV9JyAtVGFyZ2V0ICcke2VzY2FwZWRUYXJnZXR9J2A7XHJcbiAgICAgICAgICAgICAgICBsZXQgcG93ZXJzaGVsbFBhdGggPSB0bC53aGljaCgncG93ZXJzaGVsbCcsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgbGV0IHBvd2Vyc2hlbGwgPSB0bC50b29sKHBvd2Vyc2hlbGxQYXRoKVxyXG4gICAgICAgICAgICAgICAgICAgIC5saW5lKCctTm9Mb2dvIC1TdGEgLU5vUHJvZmlsZSAtTm9uSW50ZXJhY3RpdmUgLUV4ZWN1dGlvblBvbGljeSBVbnJlc3RyaWN0ZWQgLUNvbW1hbmQnKVxyXG4gICAgICAgICAgICAgICAgICAgIC5hcmcoY29tbWFuZCk7XHJcbiAgICAgICAgICAgICAgICBwb3dlcnNoZWxsLm9uKCdzdGRvdXQnLCAoYnVmZmVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoYnVmZmVyKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgcG93ZXJzaGVsbC5vbignc3RkZXJyJywgKGJ1ZmZlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGJ1ZmZlcik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHlpZWxkIHBvd2Vyc2hlbGwuZXhlYyh7IHNpbGVudDogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHtcclxuICAgICAgICAgICAgcHJvY2Vzcy5jaGRpcihvcmlnaW5hbEN3ZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBkZXN0O1xyXG4gICAgfSk7XHJcbn1cclxuZXhwb3J0cy5leHRyYWN0N3ogPSBleHRyYWN0N3o7XHJcbi8qKlxyXG4gKiBpbnN0YWxscyBhIHRvb2wgZnJvbSBhIHRhciBieSBleHRyYWN0aW5nIHRoZSB0YXIgYW5kIGluc3RhbGxpbmcgaXQgaW50byB0aGUgdG9vbCBjYWNoZVxyXG4gKlxyXG4gKiBAcGFyYW0gZmlsZSAgICAgIGZpbGUgcGF0aCBvZiB0aGUgdGFyXHJcbiAqIEBwYXJhbSB0b29sICAgICAgbmFtZSBvZiB0b29sIGluIHRoZSB0b29sIGNhY2hlXHJcbiAqIEBwYXJhbSB2ZXJzaW9uICAgdmVyc2lvbiBvZiB0aGUgdG9vbFxyXG4gKiBAcGFyYW0gYXJjaCAgICAgIGFyY2ggb2YgdGhlIHRvb2wuICBvcHRpb25hbC4gIGRlZmF1bHRzIHRvIHRoZSBhcmNoIG9mIHRoZSBtYWNoaW5lXHJcbiAqIEBwYXJhbSBvcHRpb25zICAgSUV4dHJhY3RPcHRpb25zXHJcbiAqIEBwYXJhbSBkZXN0aW5hdGlvbiAgIGRlc3RpbmF0aW9uIGRpcmVjdG9yeS4gb3B0aW9uYWwuXHJcbiAqL1xyXG5mdW5jdGlvbiBleHRyYWN0VGFyKGZpbGUsIGRlc3RpbmF0aW9uKSB7XHJcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgIC8vIG1rZGlyIC1wIG5vZGUvNC43LjAveDY0XHJcbiAgICAgICAgLy8gdGFyIHh6QyAuL25vZGUvNC43LjAveDY0IC1mIG5vZGUtdjQuNy4wLWRhcndpbi14NjQudGFyLmd6IC0tc3RyaXAtY29tcG9uZW50cyAxXHJcbiAgICAgICAgY29uc29sZS5sb2codGwubG9jKCdUT09MX0xJQl9FeHRyYWN0aW5nQXJjaGl2ZScpKTtcclxuICAgICAgICBsZXQgZGVzdCA9IF9jcmVhdGVFeHRyYWN0Rm9sZGVyKGRlc3RpbmF0aW9uKTtcclxuICAgICAgICBsZXQgdHIgPSB0bC50b29sKCd0YXInKTtcclxuICAgICAgICB0ci5hcmcoWyd4QycsIGRlc3QsICctZicsIGZpbGVdKTtcclxuICAgICAgICB5aWVsZCB0ci5leGVjKCk7XHJcbiAgICAgICAgcmV0dXJuIGRlc3Q7XHJcbiAgICB9KTtcclxufVxyXG5leHBvcnRzLmV4dHJhY3RUYXIgPSBleHRyYWN0VGFyO1xyXG5mdW5jdGlvbiBleHRyYWN0WmlwKGZpbGUsIGRlc3RpbmF0aW9uKSB7XHJcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgIGlmICghZmlsZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwYXJhbWV0ZXIgJ2ZpbGUnIGlzIHJlcXVpcmVkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zb2xlLmxvZyh0bC5sb2MoJ1RPT0xfTElCX0V4dHJhY3RpbmdBcmNoaXZlJykpO1xyXG4gICAgICAgIGxldCBkZXN0ID0gX2NyZWF0ZUV4dHJhY3RGb2xkZXIoZGVzdGluYXRpb24pO1xyXG4gICAgICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09ICd3aW4zMicpIHtcclxuICAgICAgICAgICAgLy8gYnVpbGQgdGhlIHBvd2Vyc2hlbGwgY29tbWFuZFxyXG4gICAgICAgICAgICBsZXQgZXNjYXBlZEZpbGUgPSBmaWxlLnJlcGxhY2UoLycvZywgXCInJ1wiKS5yZXBsYWNlKC9cInxcXG58XFxyL2csICcnKTsgLy8gZG91YmxlLXVwIHNpbmdsZSBxdW90ZXMsIHJlbW92ZSBkb3VibGUgcXVvdGVzIGFuZCBuZXdsaW5lc1xyXG4gICAgICAgICAgICBsZXQgZXNjYXBlZERlc3QgPSBkZXN0LnJlcGxhY2UoLycvZywgXCInJ1wiKS5yZXBsYWNlKC9cInxcXG58XFxyL2csICcnKTtcclxuICAgICAgICAgICAgbGV0IGNvbW1hbmQgPSBgJEVycm9yQWN0aW9uUHJlZmVyZW5jZSA9ICdTdG9wJyA7IHRyeSB7IEFkZC1UeXBlIC1Bc3NlbWJseU5hbWUgU3lzdGVtLklPLkNvbXByZXNzaW9uLkZpbGVTeXN0ZW0gfSBjYXRjaCB7IH0gOyBbU3lzdGVtLklPLkNvbXByZXNzaW9uLlppcEZpbGVdOjpFeHRyYWN0VG9EaXJlY3RvcnkoJyR7ZXNjYXBlZEZpbGV9JywgJyR7ZXNjYXBlZERlc3R9JylgO1xyXG4gICAgICAgICAgICAvLyBjaGFuZ2UgdGhlIGNvbnNvbGUgb3V0cHV0IGNvZGUgcGFnZSB0byBVVEYtOC5cclxuICAgICAgICAgICAgLy8gVE9ETzogRklYIFdISUNIOiBsZXQgY2hjcFBhdGggPSB0bC53aGljaCgnY2hjcC5jb20nLCB0cnVlKTtcclxuICAgICAgICAgICAgbGV0IGNoY3BQYXRoID0gcGF0aC5qb2luKHByb2Nlc3MuZW52LndpbmRpciwgXCJzeXN0ZW0zMlwiLCBcImNoY3AuY29tXCIpO1xyXG4gICAgICAgICAgICB5aWVsZCB0bC5leGVjKGNoY3BQYXRoLCAnNjUwMDEnKTtcclxuICAgICAgICAgICAgLy8gcnVuIHBvd2Vyc2hlbGxcclxuICAgICAgICAgICAgbGV0IHBvd2Vyc2hlbGwgPSB0bC50b29sKCdwb3dlcnNoZWxsJylcclxuICAgICAgICAgICAgICAgIC5saW5lKCctTm9Mb2dvIC1TdGEgLU5vUHJvZmlsZSAtTm9uSW50ZXJhY3RpdmUgLUV4ZWN1dGlvblBvbGljeSBVbnJlc3RyaWN0ZWQgLUNvbW1hbmQnKVxyXG4gICAgICAgICAgICAgICAgLmFyZyhjb21tYW5kKTtcclxuICAgICAgICAgICAgeWllbGQgcG93ZXJzaGVsbC5leGVjKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgdW56aXAgPSB0bC50b29sKCd1bnppcCcpXHJcbiAgICAgICAgICAgICAgICAuYXJnKGZpbGUpO1xyXG4gICAgICAgICAgICB5aWVsZCB1bnppcC5leGVjKHsgY3dkOiBkZXN0IH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZGVzdDtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuZXh0cmFjdFppcCA9IGV4dHJhY3RaaXA7XHJcbmZ1bmN0aW9uIF9jcmVhdGVFeHRyYWN0Rm9sZGVyKGRlc3QpIHtcclxuICAgIGlmICghZGVzdCkge1xyXG4gICAgICAgIC8vIGNyZWF0ZSBhIHRlbXAgZGlyXHJcbiAgICAgICAgZGVzdCA9IHBhdGguam9pbihfZ2V0QWdlbnRUZW1wKCksIHV1aWRWNCgpKTtcclxuICAgIH1cclxuICAgIHRsLm1rZGlyUChkZXN0KTtcclxuICAgIHJldHVybiBkZXN0O1xyXG59XHJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFF1ZXJ5IEZ1bmN0aW9uc1xyXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vLyAgICAgICBkZWZhdWx0IGlucHV0IHdpbGwgYmUgPj0gTFRTIHZlcnNpb24uICBkcm9wIGxhYmVsIGRpZmZlcmVudCB0aGFuIHZhbHVlLlxyXG4vLyAgICAgICB2NCAoTFRTKSB3b3VsZCBoYXZlIGEgdmFsdWUgb2YgNC54XHJcbi8vICAgICAgIG9wdGlvbiB0byBhbHdheXMgZG93bmxvYWQ/ICAobm90IGNhY2hlKSwgVFRMP1xyXG4vKipcclxuICogU2NyYXBlIGEgd2ViIHBhZ2UgZm9yIHZlcnNpb25zIGJ5IHJlZ2V4XHJcbiAqXHJcbiAqIEBwYXJhbSB1cmwgICAgICAgdXJsIHRvIHNjcmFwZVxyXG4gKiBAcGFyYW0gcmVnZXggICAgIHJlZ2V4IHRvIHVzZSBmb3IgdmVyc2lvbiBtYXRjaGVzXHJcbiAqIEBwYXJhbSBoYW5kbGVycyAgb3B0aW9uYWwgaGFuZGxlcnMgYXJyYXkuICBBdXRoIGhhbmRsZXJzIHRvIHBhc3MgdG8gdGhlIEh0dHBDbGllbnQgZm9yIHRoZSB0b29sIGRvd25sb2FkLlxyXG4gKi9cclxuZnVuY3Rpb24gc2NyYXBlKHVybCwgcmVnZXgsIGhhbmRsZXJzKSB7XHJcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgIGhhbmRsZXJzID0gaGFuZGxlcnMgfHwgbnVsbDtcclxuICAgICAgICBsZXQgaHR0cCA9IG5ldyBodHRwbS5IdHRwQ2xpZW50KHVzZXJBZ2VudCwgaGFuZGxlcnMsIHJlcXVlc3RPcHRpb25zKTtcclxuICAgICAgICBsZXQgb3V0cHV0ID0geWllbGQgKHlpZWxkIGh0dHAuZ2V0KHVybCkpLnJlYWRCb2R5KCk7XHJcbiAgICAgICAgbGV0IG1hdGNoZXMgPSBvdXRwdXQubWF0Y2gocmVnZXgpO1xyXG4gICAgICAgIGxldCBzZWVuID0ge307XHJcbiAgICAgICAgbGV0IHZlcnNpb25zID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB2ZXIgPSBzZW12ZXIuY2xlYW4obWF0Y2hlc1tpXSk7XHJcbiAgICAgICAgICAgIGlmICghc2Vlbi5oYXNPd25Qcm9wZXJ0eSh2ZXIpKSB7XHJcbiAgICAgICAgICAgICAgICBzZWVuW3Zlcl0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdmVyc2lvbnMucHVzaCh2ZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB2ZXJzaW9ucztcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuc2NyYXBlID0gc2NyYXBlO1xyXG5mdW5jdGlvbiBfZ2V0Q2FjaGVSb290KCkge1xyXG4gICAgdGwuYXNzZXJ0QWdlbnQoJzIuMTE1LjAnKTtcclxuICAgIGxldCBjYWNoZVJvb3QgPSB0bC5nZXRWYXJpYWJsZSgnQWdlbnQuVG9vbHNEaXJlY3RvcnknKTtcclxuICAgIGlmICghY2FjaGVSb290KSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBZ2VudC5Ub29sc0RpcmVjdG9yeSBpcyBub3Qgc2V0Jyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY2FjaGVSb290O1xyXG59XHJcbmZ1bmN0aW9uIF9nZXRBZ2VudFRlbXAoKSB7XHJcbiAgICB0bC5hc3NlcnRBZ2VudCgnMi4xMTUuMCcpO1xyXG4gICAgbGV0IHRlbXBEaXJlY3RvcnkgPSB0bC5nZXRWYXJpYWJsZSgnQWdlbnQuVGVtcERpcmVjdG9yeScpO1xyXG4gICAgaWYgKCF0ZW1wRGlyZWN0b3J5KSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBZ2VudC5UZW1wRGlyZWN0b3J5IGlzIG5vdCBzZXQnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0ZW1wRGlyZWN0b3J5O1xyXG59XHJcbiIsImZ1bmN0aW9uIHdlYnBhY2tFbXB0eUNvbnRleHQocmVxKSB7XG5cdHZhciBlID0gbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIiArIHJlcSArIFwiJ1wiKTtcblx0ZS5jb2RlID0gJ01PRFVMRV9OT1RfRk9VTkQnO1xuXHR0aHJvdyBlO1xufVxud2VicGFja0VtcHR5Q29udGV4dC5rZXlzID0gKCkgPT4gKFtdKTtcbndlYnBhY2tFbXB0eUNvbnRleHQucmVzb2x2ZSA9IHdlYnBhY2tFbXB0eUNvbnRleHQ7XG53ZWJwYWNrRW1wdHlDb250ZXh0LmlkID0gXCIuL25vZGVfbW9kdWxlcy9henVyZS1waXBlbGluZXMtdG9vbC1saWIgc3luYyByZWN1cnNpdmVcIjtcbm1vZHVsZS5leHBvcnRzID0gd2VicGFja0VtcHR5Q29udGV4dDsiLCIndXNlIHN0cmljdCc7XG5tb2R1bGUuZXhwb3J0cyA9IGJhbGFuY2VkO1xuZnVuY3Rpb24gYmFsYW5jZWQoYSwgYiwgc3RyKSB7XG4gIGlmIChhIGluc3RhbmNlb2YgUmVnRXhwKSBhID0gbWF5YmVNYXRjaChhLCBzdHIpO1xuICBpZiAoYiBpbnN0YW5jZW9mIFJlZ0V4cCkgYiA9IG1heWJlTWF0Y2goYiwgc3RyKTtcblxuICB2YXIgciA9IHJhbmdlKGEsIGIsIHN0cik7XG5cbiAgcmV0dXJuIHIgJiYge1xuICAgIHN0YXJ0OiByWzBdLFxuICAgIGVuZDogclsxXSxcbiAgICBwcmU6IHN0ci5zbGljZSgwLCByWzBdKSxcbiAgICBib2R5OiBzdHIuc2xpY2UoclswXSArIGEubGVuZ3RoLCByWzFdKSxcbiAgICBwb3N0OiBzdHIuc2xpY2UoclsxXSArIGIubGVuZ3RoKVxuICB9O1xufVxuXG5mdW5jdGlvbiBtYXliZU1hdGNoKHJlZywgc3RyKSB7XG4gIHZhciBtID0gc3RyLm1hdGNoKHJlZyk7XG4gIHJldHVybiBtID8gbVswXSA6IG51bGw7XG59XG5cbmJhbGFuY2VkLnJhbmdlID0gcmFuZ2U7XG5mdW5jdGlvbiByYW5nZShhLCBiLCBzdHIpIHtcbiAgdmFyIGJlZ3MsIGJlZywgbGVmdCwgcmlnaHQsIHJlc3VsdDtcbiAgdmFyIGFpID0gc3RyLmluZGV4T2YoYSk7XG4gIHZhciBiaSA9IHN0ci5pbmRleE9mKGIsIGFpICsgMSk7XG4gIHZhciBpID0gYWk7XG5cbiAgaWYgKGFpID49IDAgJiYgYmkgPiAwKSB7XG4gICAgYmVncyA9IFtdO1xuICAgIGxlZnQgPSBzdHIubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGkgPj0gMCAmJiAhcmVzdWx0KSB7XG4gICAgICBpZiAoaSA9PSBhaSkge1xuICAgICAgICBiZWdzLnB1c2goaSk7XG4gICAgICAgIGFpID0gc3RyLmluZGV4T2YoYSwgaSArIDEpO1xuICAgICAgfSBlbHNlIGlmIChiZWdzLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgIHJlc3VsdCA9IFsgYmVncy5wb3AoKSwgYmkgXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJlZyA9IGJlZ3MucG9wKCk7XG4gICAgICAgIGlmIChiZWcgPCBsZWZ0KSB7XG4gICAgICAgICAgbGVmdCA9IGJlZztcbiAgICAgICAgICByaWdodCA9IGJpO1xuICAgICAgICB9XG5cbiAgICAgICAgYmkgPSBzdHIuaW5kZXhPZihiLCBpICsgMSk7XG4gICAgICB9XG5cbiAgICAgIGkgPSBhaSA8IGJpICYmIGFpID49IDAgPyBhaSA6IGJpO1xuICAgIH1cblxuICAgIGlmIChiZWdzLmxlbmd0aCkge1xuICAgICAgcmVzdWx0ID0gWyBsZWZ0LCByaWdodCBdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iLCJ2YXIgY29uY2F0TWFwID0gcmVxdWlyZSgnY29uY2F0LW1hcCcpO1xudmFyIGJhbGFuY2VkID0gcmVxdWlyZSgnYmFsYW5jZWQtbWF0Y2gnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBleHBhbmRUb3A7XG5cbnZhciBlc2NTbGFzaCA9ICdcXDBTTEFTSCcrTWF0aC5yYW5kb20oKSsnXFwwJztcbnZhciBlc2NPcGVuID0gJ1xcME9QRU4nK01hdGgucmFuZG9tKCkrJ1xcMCc7XG52YXIgZXNjQ2xvc2UgPSAnXFwwQ0xPU0UnK01hdGgucmFuZG9tKCkrJ1xcMCc7XG52YXIgZXNjQ29tbWEgPSAnXFwwQ09NTUEnK01hdGgucmFuZG9tKCkrJ1xcMCc7XG52YXIgZXNjUGVyaW9kID0gJ1xcMFBFUklPRCcrTWF0aC5yYW5kb20oKSsnXFwwJztcblxuZnVuY3Rpb24gbnVtZXJpYyhzdHIpIHtcbiAgcmV0dXJuIHBhcnNlSW50KHN0ciwgMTApID09IHN0clxuICAgID8gcGFyc2VJbnQoc3RyLCAxMClcbiAgICA6IHN0ci5jaGFyQ29kZUF0KDApO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVCcmFjZXMoc3RyKSB7XG4gIHJldHVybiBzdHIuc3BsaXQoJ1xcXFxcXFxcJykuam9pbihlc2NTbGFzaClcbiAgICAgICAgICAgIC5zcGxpdCgnXFxcXHsnKS5qb2luKGVzY09wZW4pXG4gICAgICAgICAgICAuc3BsaXQoJ1xcXFx9Jykuam9pbihlc2NDbG9zZSlcbiAgICAgICAgICAgIC5zcGxpdCgnXFxcXCwnKS5qb2luKGVzY0NvbW1hKVxuICAgICAgICAgICAgLnNwbGl0KCdcXFxcLicpLmpvaW4oZXNjUGVyaW9kKTtcbn1cblxuZnVuY3Rpb24gdW5lc2NhcGVCcmFjZXMoc3RyKSB7XG4gIHJldHVybiBzdHIuc3BsaXQoZXNjU2xhc2gpLmpvaW4oJ1xcXFwnKVxuICAgICAgICAgICAgLnNwbGl0KGVzY09wZW4pLmpvaW4oJ3snKVxuICAgICAgICAgICAgLnNwbGl0KGVzY0Nsb3NlKS5qb2luKCd9JylcbiAgICAgICAgICAgIC5zcGxpdChlc2NDb21tYSkuam9pbignLCcpXG4gICAgICAgICAgICAuc3BsaXQoZXNjUGVyaW9kKS5qb2luKCcuJyk7XG59XG5cblxuLy8gQmFzaWNhbGx5IGp1c3Qgc3RyLnNwbGl0KFwiLFwiKSwgYnV0IGhhbmRsaW5nIGNhc2VzXG4vLyB3aGVyZSB3ZSBoYXZlIG5lc3RlZCBicmFjZWQgc2VjdGlvbnMsIHdoaWNoIHNob3VsZCBiZVxuLy8gdHJlYXRlZCBhcyBpbmRpdmlkdWFsIG1lbWJlcnMsIGxpa2Uge2Ese2IsY30sZH1cbmZ1bmN0aW9uIHBhcnNlQ29tbWFQYXJ0cyhzdHIpIHtcbiAgaWYgKCFzdHIpXG4gICAgcmV0dXJuIFsnJ107XG5cbiAgdmFyIHBhcnRzID0gW107XG4gIHZhciBtID0gYmFsYW5jZWQoJ3snLCAnfScsIHN0cik7XG5cbiAgaWYgKCFtKVxuICAgIHJldHVybiBzdHIuc3BsaXQoJywnKTtcblxuICB2YXIgcHJlID0gbS5wcmU7XG4gIHZhciBib2R5ID0gbS5ib2R5O1xuICB2YXIgcG9zdCA9IG0ucG9zdDtcbiAgdmFyIHAgPSBwcmUuc3BsaXQoJywnKTtcblxuICBwW3AubGVuZ3RoLTFdICs9ICd7JyArIGJvZHkgKyAnfSc7XG4gIHZhciBwb3N0UGFydHMgPSBwYXJzZUNvbW1hUGFydHMocG9zdCk7XG4gIGlmIChwb3N0Lmxlbmd0aCkge1xuICAgIHBbcC5sZW5ndGgtMV0gKz0gcG9zdFBhcnRzLnNoaWZ0KCk7XG4gICAgcC5wdXNoLmFwcGx5KHAsIHBvc3RQYXJ0cyk7XG4gIH1cblxuICBwYXJ0cy5wdXNoLmFwcGx5KHBhcnRzLCBwKTtcblxuICByZXR1cm4gcGFydHM7XG59XG5cbmZ1bmN0aW9uIGV4cGFuZFRvcChzdHIpIHtcbiAgaWYgKCFzdHIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIC8vIEkgZG9uJ3Qga25vdyB3aHkgQmFzaCA0LjMgZG9lcyB0aGlzLCBidXQgaXQgZG9lcy5cbiAgLy8gQW55dGhpbmcgc3RhcnRpbmcgd2l0aCB7fSB3aWxsIGhhdmUgdGhlIGZpcnN0IHR3byBieXRlcyBwcmVzZXJ2ZWRcbiAgLy8gYnV0ICpvbmx5KiBhdCB0aGUgdG9wIGxldmVsLCBzbyB7fSxhfWIgd2lsbCBub3QgZXhwYW5kIHRvIGFueXRoaW5nLFxuICAvLyBidXQgYXt9LGJ9YyB3aWxsIGJlIGV4cGFuZGVkIHRvIFthfWMsYWJjXS5cbiAgLy8gT25lIGNvdWxkIGFyZ3VlIHRoYXQgdGhpcyBpcyBhIGJ1ZyBpbiBCYXNoLCBidXQgc2luY2UgdGhlIGdvYWwgb2ZcbiAgLy8gdGhpcyBtb2R1bGUgaXMgdG8gbWF0Y2ggQmFzaCdzIHJ1bGVzLCB3ZSBlc2NhcGUgYSBsZWFkaW5nIHt9XG4gIGlmIChzdHIuc3Vic3RyKDAsIDIpID09PSAne30nKSB7XG4gICAgc3RyID0gJ1xcXFx7XFxcXH0nICsgc3RyLnN1YnN0cigyKTtcbiAgfVxuXG4gIHJldHVybiBleHBhbmQoZXNjYXBlQnJhY2VzKHN0ciksIHRydWUpLm1hcCh1bmVzY2FwZUJyYWNlcyk7XG59XG5cbmZ1bmN0aW9uIGlkZW50aXR5KGUpIHtcbiAgcmV0dXJuIGU7XG59XG5cbmZ1bmN0aW9uIGVtYnJhY2Uoc3RyKSB7XG4gIHJldHVybiAneycgKyBzdHIgKyAnfSc7XG59XG5mdW5jdGlvbiBpc1BhZGRlZChlbCkge1xuICByZXR1cm4gL14tPzBcXGQvLnRlc3QoZWwpO1xufVxuXG5mdW5jdGlvbiBsdGUoaSwgeSkge1xuICByZXR1cm4gaSA8PSB5O1xufVxuZnVuY3Rpb24gZ3RlKGksIHkpIHtcbiAgcmV0dXJuIGkgPj0geTtcbn1cblxuZnVuY3Rpb24gZXhwYW5kKHN0ciwgaXNUb3ApIHtcbiAgdmFyIGV4cGFuc2lvbnMgPSBbXTtcblxuICB2YXIgbSA9IGJhbGFuY2VkKCd7JywgJ30nLCBzdHIpO1xuICBpZiAoIW0gfHwgL1xcJCQvLnRlc3QobS5wcmUpKSByZXR1cm4gW3N0cl07XG5cbiAgdmFyIGlzTnVtZXJpY1NlcXVlbmNlID0gL14tP1xcZCtcXC5cXC4tP1xcZCsoPzpcXC5cXC4tP1xcZCspPyQvLnRlc3QobS5ib2R5KTtcbiAgdmFyIGlzQWxwaGFTZXF1ZW5jZSA9IC9eW2EtekEtWl1cXC5cXC5bYS16QS1aXSg/OlxcLlxcLi0/XFxkKyk/JC8udGVzdChtLmJvZHkpO1xuICB2YXIgaXNTZXF1ZW5jZSA9IGlzTnVtZXJpY1NlcXVlbmNlIHx8IGlzQWxwaGFTZXF1ZW5jZTtcbiAgdmFyIGlzT3B0aW9ucyA9IG0uYm9keS5pbmRleE9mKCcsJykgPj0gMDtcbiAgaWYgKCFpc1NlcXVlbmNlICYmICFpc09wdGlvbnMpIHtcbiAgICAvLyB7YX0sYn1cbiAgICBpZiAobS5wb3N0Lm1hdGNoKC8sLipcXH0vKSkge1xuICAgICAgc3RyID0gbS5wcmUgKyAneycgKyBtLmJvZHkgKyBlc2NDbG9zZSArIG0ucG9zdDtcbiAgICAgIHJldHVybiBleHBhbmQoc3RyKTtcbiAgICB9XG4gICAgcmV0dXJuIFtzdHJdO1xuICB9XG5cbiAgdmFyIG47XG4gIGlmIChpc1NlcXVlbmNlKSB7XG4gICAgbiA9IG0uYm9keS5zcGxpdCgvXFwuXFwuLyk7XG4gIH0gZWxzZSB7XG4gICAgbiA9IHBhcnNlQ29tbWFQYXJ0cyhtLmJvZHkpO1xuICAgIGlmIChuLmxlbmd0aCA9PT0gMSkge1xuICAgICAgLy8geHt7YSxifX15ID09PiB4e2F9eSB4e2J9eVxuICAgICAgbiA9IGV4cGFuZChuWzBdLCBmYWxzZSkubWFwKGVtYnJhY2UpO1xuICAgICAgaWYgKG4ubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHZhciBwb3N0ID0gbS5wb3N0Lmxlbmd0aFxuICAgICAgICAgID8gZXhwYW5kKG0ucG9zdCwgZmFsc2UpXG4gICAgICAgICAgOiBbJyddO1xuICAgICAgICByZXR1cm4gcG9zdC5tYXAoZnVuY3Rpb24ocCkge1xuICAgICAgICAgIHJldHVybiBtLnByZSArIG5bMF0gKyBwO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBhdCB0aGlzIHBvaW50LCBuIGlzIHRoZSBwYXJ0cywgYW5kIHdlIGtub3cgaXQncyBub3QgYSBjb21tYSBzZXRcbiAgLy8gd2l0aCBhIHNpbmdsZSBlbnRyeS5cblxuICAvLyBubyBuZWVkIHRvIGV4cGFuZCBwcmUsIHNpbmNlIGl0IGlzIGd1YXJhbnRlZWQgdG8gYmUgZnJlZSBvZiBicmFjZS1zZXRzXG4gIHZhciBwcmUgPSBtLnByZTtcbiAgdmFyIHBvc3QgPSBtLnBvc3QubGVuZ3RoXG4gICAgPyBleHBhbmQobS5wb3N0LCBmYWxzZSlcbiAgICA6IFsnJ107XG5cbiAgdmFyIE47XG5cbiAgaWYgKGlzU2VxdWVuY2UpIHtcbiAgICB2YXIgeCA9IG51bWVyaWMoblswXSk7XG4gICAgdmFyIHkgPSBudW1lcmljKG5bMV0pO1xuICAgIHZhciB3aWR0aCA9IE1hdGgubWF4KG5bMF0ubGVuZ3RoLCBuWzFdLmxlbmd0aClcbiAgICB2YXIgaW5jciA9IG4ubGVuZ3RoID09IDNcbiAgICAgID8gTWF0aC5hYnMobnVtZXJpYyhuWzJdKSlcbiAgICAgIDogMTtcbiAgICB2YXIgdGVzdCA9IGx0ZTtcbiAgICB2YXIgcmV2ZXJzZSA9IHkgPCB4O1xuICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICBpbmNyICo9IC0xO1xuICAgICAgdGVzdCA9IGd0ZTtcbiAgICB9XG4gICAgdmFyIHBhZCA9IG4uc29tZShpc1BhZGRlZCk7XG5cbiAgICBOID0gW107XG5cbiAgICBmb3IgKHZhciBpID0geDsgdGVzdChpLCB5KTsgaSArPSBpbmNyKSB7XG4gICAgICB2YXIgYztcbiAgICAgIGlmIChpc0FscGhhU2VxdWVuY2UpIHtcbiAgICAgICAgYyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoaSk7XG4gICAgICAgIGlmIChjID09PSAnXFxcXCcpXG4gICAgICAgICAgYyA9ICcnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYyA9IFN0cmluZyhpKTtcbiAgICAgICAgaWYgKHBhZCkge1xuICAgICAgICAgIHZhciBuZWVkID0gd2lkdGggLSBjLmxlbmd0aDtcbiAgICAgICAgICBpZiAobmVlZCA+IDApIHtcbiAgICAgICAgICAgIHZhciB6ID0gbmV3IEFycmF5KG5lZWQgKyAxKS5qb2luKCcwJyk7XG4gICAgICAgICAgICBpZiAoaSA8IDApXG4gICAgICAgICAgICAgIGMgPSAnLScgKyB6ICsgYy5zbGljZSgxKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgYyA9IHogKyBjO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgTi5wdXNoKGMpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBOID0gY29uY2F0TWFwKG4sIGZ1bmN0aW9uKGVsKSB7IHJldHVybiBleHBhbmQoZWwsIGZhbHNlKSB9KTtcbiAgfVxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgTi5sZW5ndGg7IGorKykge1xuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgcG9zdC5sZW5ndGg7IGsrKykge1xuICAgICAgdmFyIGV4cGFuc2lvbiA9IHByZSArIE5bal0gKyBwb3N0W2tdO1xuICAgICAgaWYgKCFpc1RvcCB8fCBpc1NlcXVlbmNlIHx8IGV4cGFuc2lvbilcbiAgICAgICAgZXhwYW5zaW9ucy5wdXNoKGV4cGFuc2lvbik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGV4cGFuc2lvbnM7XG59XG5cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHhzLCBmbikge1xuICAgIHZhciByZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciB4ID0gZm4oeHNbaV0sIGkpO1xuICAgICAgICBpZiAoaXNBcnJheSh4KSkgcmVzLnB1c2guYXBwbHkocmVzLCB4KTtcbiAgICAgICAgZWxzZSByZXMucHVzaCh4KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn07XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoeHMpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHhzKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlYWxwYXRoXG5yZWFscGF0aC5yZWFscGF0aCA9IHJlYWxwYXRoXG5yZWFscGF0aC5zeW5jID0gcmVhbHBhdGhTeW5jXG5yZWFscGF0aC5yZWFscGF0aFN5bmMgPSByZWFscGF0aFN5bmNcbnJlYWxwYXRoLm1vbmtleXBhdGNoID0gbW9ua2V5cGF0Y2hcbnJlYWxwYXRoLnVubW9ua2V5cGF0Y2ggPSB1bm1vbmtleXBhdGNoXG5cbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJylcbnZhciBvcmlnUmVhbHBhdGggPSBmcy5yZWFscGF0aFxudmFyIG9yaWdSZWFscGF0aFN5bmMgPSBmcy5yZWFscGF0aFN5bmNcblxudmFyIHZlcnNpb24gPSBwcm9jZXNzLnZlcnNpb25cbnZhciBvayA9IC9edlswLTVdXFwuLy50ZXN0KHZlcnNpb24pXG52YXIgb2xkID0gcmVxdWlyZSgnLi9vbGQuanMnKVxuXG5mdW5jdGlvbiBuZXdFcnJvciAoZXIpIHtcbiAgcmV0dXJuIGVyICYmIGVyLnN5c2NhbGwgPT09ICdyZWFscGF0aCcgJiYgKFxuICAgIGVyLmNvZGUgPT09ICdFTE9PUCcgfHxcbiAgICBlci5jb2RlID09PSAnRU5PTUVNJyB8fFxuICAgIGVyLmNvZGUgPT09ICdFTkFNRVRPT0xPTkcnXG4gIClcbn1cblxuZnVuY3Rpb24gcmVhbHBhdGggKHAsIGNhY2hlLCBjYikge1xuICBpZiAob2spIHtcbiAgICByZXR1cm4gb3JpZ1JlYWxwYXRoKHAsIGNhY2hlLCBjYilcbiAgfVxuXG4gIGlmICh0eXBlb2YgY2FjaGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGNhY2hlXG4gICAgY2FjaGUgPSBudWxsXG4gIH1cbiAgb3JpZ1JlYWxwYXRoKHAsIGNhY2hlLCBmdW5jdGlvbiAoZXIsIHJlc3VsdCkge1xuICAgIGlmIChuZXdFcnJvcihlcikpIHtcbiAgICAgIG9sZC5yZWFscGF0aChwLCBjYWNoZSwgY2IpXG4gICAgfSBlbHNlIHtcbiAgICAgIGNiKGVyLCByZXN1bHQpXG4gICAgfVxuICB9KVxufVxuXG5mdW5jdGlvbiByZWFscGF0aFN5bmMgKHAsIGNhY2hlKSB7XG4gIGlmIChvaykge1xuICAgIHJldHVybiBvcmlnUmVhbHBhdGhTeW5jKHAsIGNhY2hlKVxuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gb3JpZ1JlYWxwYXRoU3luYyhwLCBjYWNoZSlcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICBpZiAobmV3RXJyb3IoZXIpKSB7XG4gICAgICByZXR1cm4gb2xkLnJlYWxwYXRoU3luYyhwLCBjYWNoZSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgZXJcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbW9ua2V5cGF0Y2ggKCkge1xuICBmcy5yZWFscGF0aCA9IHJlYWxwYXRoXG4gIGZzLnJlYWxwYXRoU3luYyA9IHJlYWxwYXRoU3luY1xufVxuXG5mdW5jdGlvbiB1bm1vbmtleXBhdGNoICgpIHtcbiAgZnMucmVhbHBhdGggPSBvcmlnUmVhbHBhdGhcbiAgZnMucmVhbHBhdGhTeW5jID0gb3JpZ1JlYWxwYXRoU3luY1xufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBwYXRoTW9kdWxlID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGlzV2luZG93cyA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMic7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG4vLyBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHJlYWxwYXRoLCBwb3J0ZWQgZnJvbSBub2RlIHByZS12NlxuXG52YXIgREVCVUcgPSBwcm9jZXNzLmVudi5OT0RFX0RFQlVHICYmIC9mcy8udGVzdChwcm9jZXNzLmVudi5OT0RFX0RFQlVHKTtcblxuZnVuY3Rpb24gcmV0aHJvdygpIHtcbiAgLy8gT25seSBlbmFibGUgaW4gZGVidWcgbW9kZS4gQSBiYWNrdHJhY2UgdXNlcyB+MTAwMCBieXRlcyBvZiBoZWFwIHNwYWNlIGFuZFxuICAvLyBpcyBmYWlybHkgc2xvdyB0byBnZW5lcmF0ZS5cbiAgdmFyIGNhbGxiYWNrO1xuICBpZiAoREVCVUcpIHtcbiAgICB2YXIgYmFja3RyYWNlID0gbmV3IEVycm9yO1xuICAgIGNhbGxiYWNrID0gZGVidWdDYWxsYmFjaztcbiAgfSBlbHNlXG4gICAgY2FsbGJhY2sgPSBtaXNzaW5nQ2FsbGJhY2s7XG5cbiAgcmV0dXJuIGNhbGxiYWNrO1xuXG4gIGZ1bmN0aW9uIGRlYnVnQ2FsbGJhY2soZXJyKSB7XG4gICAgaWYgKGVycikge1xuICAgICAgYmFja3RyYWNlLm1lc3NhZ2UgPSBlcnIubWVzc2FnZTtcbiAgICAgIGVyciA9IGJhY2t0cmFjZTtcbiAgICAgIG1pc3NpbmdDYWxsYmFjayhlcnIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG1pc3NpbmdDYWxsYmFjayhlcnIpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBpZiAocHJvY2Vzcy50aHJvd0RlcHJlY2F0aW9uKVxuICAgICAgICB0aHJvdyBlcnI7ICAvLyBGb3Jnb3QgYSBjYWxsYmFjayBidXQgZG9uJ3Qga25vdyB3aGVyZT8gVXNlIE5PREVfREVCVUc9ZnNcbiAgICAgIGVsc2UgaWYgKCFwcm9jZXNzLm5vRGVwcmVjYXRpb24pIHtcbiAgICAgICAgdmFyIG1zZyA9ICdmczogbWlzc2luZyBjYWxsYmFjayAnICsgKGVyci5zdGFjayB8fCBlcnIubWVzc2FnZSk7XG4gICAgICAgIGlmIChwcm9jZXNzLnRyYWNlRGVwcmVjYXRpb24pXG4gICAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZUNhbGxiYWNrKGNiKSB7XG4gIHJldHVybiB0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicgPyBjYiA6IHJldGhyb3coKTtcbn1cblxudmFyIG5vcm1hbGl6ZSA9IHBhdGhNb2R1bGUubm9ybWFsaXplO1xuXG4vLyBSZWdleHAgdGhhdCBmaW5kcyB0aGUgbmV4dCBwYXJ0aW9uIG9mIGEgKHBhcnRpYWwpIHBhdGhcbi8vIHJlc3VsdCBpcyBbYmFzZV93aXRoX3NsYXNoLCBiYXNlXSwgZS5nLiBbJ3NvbWVkaXIvJywgJ3NvbWVkaXInXVxuaWYgKGlzV2luZG93cykge1xuICB2YXIgbmV4dFBhcnRSZSA9IC8oLio/KSg/OltcXC9cXFxcXSt8JCkvZztcbn0gZWxzZSB7XG4gIHZhciBuZXh0UGFydFJlID0gLyguKj8pKD86W1xcL10rfCQpL2c7XG59XG5cbi8vIFJlZ2V4IHRvIGZpbmQgdGhlIGRldmljZSByb290LCBpbmNsdWRpbmcgdHJhaWxpbmcgc2xhc2guIEUuZy4gJ2M6XFxcXCcuXG5pZiAoaXNXaW5kb3dzKSB7XG4gIHZhciBzcGxpdFJvb3RSZSA9IC9eKD86W2EtekEtWl06fFtcXFxcXFwvXXsyfVteXFxcXFxcL10rW1xcXFxcXC9dW15cXFxcXFwvXSspP1tcXFxcXFwvXSovO1xufSBlbHNlIHtcbiAgdmFyIHNwbGl0Um9vdFJlID0gL15bXFwvXSovO1xufVxuXG5leHBvcnRzLnJlYWxwYXRoU3luYyA9IGZ1bmN0aW9uIHJlYWxwYXRoU3luYyhwLCBjYWNoZSkge1xuICAvLyBtYWtlIHAgaXMgYWJzb2x1dGVcbiAgcCA9IHBhdGhNb2R1bGUucmVzb2x2ZShwKTtcblxuICBpZiAoY2FjaGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGNhY2hlLCBwKSkge1xuICAgIHJldHVybiBjYWNoZVtwXTtcbiAgfVxuXG4gIHZhciBvcmlnaW5hbCA9IHAsXG4gICAgICBzZWVuTGlua3MgPSB7fSxcbiAgICAgIGtub3duSGFyZCA9IHt9O1xuXG4gIC8vIGN1cnJlbnQgY2hhcmFjdGVyIHBvc2l0aW9uIGluIHBcbiAgdmFyIHBvcztcbiAgLy8gdGhlIHBhcnRpYWwgcGF0aCBzbyBmYXIsIGluY2x1ZGluZyBhIHRyYWlsaW5nIHNsYXNoIGlmIGFueVxuICB2YXIgY3VycmVudDtcbiAgLy8gdGhlIHBhcnRpYWwgcGF0aCB3aXRob3V0IGEgdHJhaWxpbmcgc2xhc2ggKGV4Y2VwdCB3aGVuIHBvaW50aW5nIGF0IGEgcm9vdClcbiAgdmFyIGJhc2U7XG4gIC8vIHRoZSBwYXJ0aWFsIHBhdGggc2Nhbm5lZCBpbiB0aGUgcHJldmlvdXMgcm91bmQsIHdpdGggc2xhc2hcbiAgdmFyIHByZXZpb3VzO1xuXG4gIHN0YXJ0KCk7XG5cbiAgZnVuY3Rpb24gc3RhcnQoKSB7XG4gICAgLy8gU2tpcCBvdmVyIHJvb3RzXG4gICAgdmFyIG0gPSBzcGxpdFJvb3RSZS5leGVjKHApO1xuICAgIHBvcyA9IG1bMF0ubGVuZ3RoO1xuICAgIGN1cnJlbnQgPSBtWzBdO1xuICAgIGJhc2UgPSBtWzBdO1xuICAgIHByZXZpb3VzID0gJyc7XG5cbiAgICAvLyBPbiB3aW5kb3dzLCBjaGVjayB0aGF0IHRoZSByb290IGV4aXN0cy4gT24gdW5peCB0aGVyZSBpcyBubyBuZWVkLlxuICAgIGlmIChpc1dpbmRvd3MgJiYgIWtub3duSGFyZFtiYXNlXSkge1xuICAgICAgZnMubHN0YXRTeW5jKGJhc2UpO1xuICAgICAga25vd25IYXJkW2Jhc2VdID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvLyB3YWxrIGRvd24gdGhlIHBhdGgsIHN3YXBwaW5nIG91dCBsaW5rZWQgcGF0aHBhcnRzIGZvciB0aGVpciByZWFsXG4gIC8vIHZhbHVlc1xuICAvLyBOQjogcC5sZW5ndGggY2hhbmdlcy5cbiAgd2hpbGUgKHBvcyA8IHAubGVuZ3RoKSB7XG4gICAgLy8gZmluZCB0aGUgbmV4dCBwYXJ0XG4gICAgbmV4dFBhcnRSZS5sYXN0SW5kZXggPSBwb3M7XG4gICAgdmFyIHJlc3VsdCA9IG5leHRQYXJ0UmUuZXhlYyhwKTtcbiAgICBwcmV2aW91cyA9IGN1cnJlbnQ7XG4gICAgY3VycmVudCArPSByZXN1bHRbMF07XG4gICAgYmFzZSA9IHByZXZpb3VzICsgcmVzdWx0WzFdO1xuICAgIHBvcyA9IG5leHRQYXJ0UmUubGFzdEluZGV4O1xuXG4gICAgLy8gY29udGludWUgaWYgbm90IGEgc3ltbGlua1xuICAgIGlmIChrbm93bkhhcmRbYmFzZV0gfHwgKGNhY2hlICYmIGNhY2hlW2Jhc2VdID09PSBiYXNlKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIHJlc29sdmVkTGluaztcbiAgICBpZiAoY2FjaGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGNhY2hlLCBiYXNlKSkge1xuICAgICAgLy8gc29tZSBrbm93biBzeW1ib2xpYyBsaW5rLiAgbm8gbmVlZCB0byBzdGF0IGFnYWluLlxuICAgICAgcmVzb2x2ZWRMaW5rID0gY2FjaGVbYmFzZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBzdGF0ID0gZnMubHN0YXRTeW5jKGJhc2UpO1xuICAgICAgaWYgKCFzdGF0LmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgICAga25vd25IYXJkW2Jhc2VdID0gdHJ1ZTtcbiAgICAgICAgaWYgKGNhY2hlKSBjYWNoZVtiYXNlXSA9IGJhc2U7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyByZWFkIHRoZSBsaW5rIGlmIGl0IHdhc24ndCByZWFkIGJlZm9yZVxuICAgICAgLy8gZGV2L2lubyBhbHdheXMgcmV0dXJuIDAgb24gd2luZG93cywgc28gc2tpcCB0aGUgY2hlY2suXG4gICAgICB2YXIgbGlua1RhcmdldCA9IG51bGw7XG4gICAgICBpZiAoIWlzV2luZG93cykge1xuICAgICAgICB2YXIgaWQgPSBzdGF0LmRldi50b1N0cmluZygzMikgKyAnOicgKyBzdGF0Lmluby50b1N0cmluZygzMik7XG4gICAgICAgIGlmIChzZWVuTGlua3MuaGFzT3duUHJvcGVydHkoaWQpKSB7XG4gICAgICAgICAgbGlua1RhcmdldCA9IHNlZW5MaW5rc1tpZF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChsaW5rVGFyZ2V0ID09PSBudWxsKSB7XG4gICAgICAgIGZzLnN0YXRTeW5jKGJhc2UpO1xuICAgICAgICBsaW5rVGFyZ2V0ID0gZnMucmVhZGxpbmtTeW5jKGJhc2UpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZWRMaW5rID0gcGF0aE1vZHVsZS5yZXNvbHZlKHByZXZpb3VzLCBsaW5rVGFyZ2V0KTtcbiAgICAgIC8vIHRyYWNrIHRoaXMsIGlmIGdpdmVuIGEgY2FjaGUuXG4gICAgICBpZiAoY2FjaGUpIGNhY2hlW2Jhc2VdID0gcmVzb2x2ZWRMaW5rO1xuICAgICAgaWYgKCFpc1dpbmRvd3MpIHNlZW5MaW5rc1tpZF0gPSBsaW5rVGFyZ2V0O1xuICAgIH1cblxuICAgIC8vIHJlc29sdmUgdGhlIGxpbmssIHRoZW4gc3RhcnQgb3ZlclxuICAgIHAgPSBwYXRoTW9kdWxlLnJlc29sdmUocmVzb2x2ZWRMaW5rLCBwLnNsaWNlKHBvcykpO1xuICAgIHN0YXJ0KCk7XG4gIH1cblxuICBpZiAoY2FjaGUpIGNhY2hlW29yaWdpbmFsXSA9IHA7XG5cbiAgcmV0dXJuIHA7XG59O1xuXG5cbmV4cG9ydHMucmVhbHBhdGggPSBmdW5jdGlvbiByZWFscGF0aChwLCBjYWNoZSwgY2IpIHtcbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gbWF5YmVDYWxsYmFjayhjYWNoZSk7XG4gICAgY2FjaGUgPSBudWxsO1xuICB9XG5cbiAgLy8gbWFrZSBwIGlzIGFic29sdXRlXG4gIHAgPSBwYXRoTW9kdWxlLnJlc29sdmUocCk7XG5cbiAgaWYgKGNhY2hlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChjYWNoZSwgcCkpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhjYi5iaW5kKG51bGwsIG51bGwsIGNhY2hlW3BdKSk7XG4gIH1cblxuICB2YXIgb3JpZ2luYWwgPSBwLFxuICAgICAgc2VlbkxpbmtzID0ge30sXG4gICAgICBrbm93bkhhcmQgPSB7fTtcblxuICAvLyBjdXJyZW50IGNoYXJhY3RlciBwb3NpdGlvbiBpbiBwXG4gIHZhciBwb3M7XG4gIC8vIHRoZSBwYXJ0aWFsIHBhdGggc28gZmFyLCBpbmNsdWRpbmcgYSB0cmFpbGluZyBzbGFzaCBpZiBhbnlcbiAgdmFyIGN1cnJlbnQ7XG4gIC8vIHRoZSBwYXJ0aWFsIHBhdGggd2l0aG91dCBhIHRyYWlsaW5nIHNsYXNoIChleGNlcHQgd2hlbiBwb2ludGluZyBhdCBhIHJvb3QpXG4gIHZhciBiYXNlO1xuICAvLyB0aGUgcGFydGlhbCBwYXRoIHNjYW5uZWQgaW4gdGhlIHByZXZpb3VzIHJvdW5kLCB3aXRoIHNsYXNoXG4gIHZhciBwcmV2aW91cztcblxuICBzdGFydCgpO1xuXG4gIGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgIC8vIFNraXAgb3ZlciByb290c1xuICAgIHZhciBtID0gc3BsaXRSb290UmUuZXhlYyhwKTtcbiAgICBwb3MgPSBtWzBdLmxlbmd0aDtcbiAgICBjdXJyZW50ID0gbVswXTtcbiAgICBiYXNlID0gbVswXTtcbiAgICBwcmV2aW91cyA9ICcnO1xuXG4gICAgLy8gT24gd2luZG93cywgY2hlY2sgdGhhdCB0aGUgcm9vdCBleGlzdHMuIE9uIHVuaXggdGhlcmUgaXMgbm8gbmVlZC5cbiAgICBpZiAoaXNXaW5kb3dzICYmICFrbm93bkhhcmRbYmFzZV0pIHtcbiAgICAgIGZzLmxzdGF0KGJhc2UsIGZ1bmN0aW9uKGVycikge1xuICAgICAgICBpZiAoZXJyKSByZXR1cm4gY2IoZXJyKTtcbiAgICAgICAga25vd25IYXJkW2Jhc2VdID0gdHJ1ZTtcbiAgICAgICAgTE9PUCgpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soTE9PUCk7XG4gICAgfVxuICB9XG5cbiAgLy8gd2FsayBkb3duIHRoZSBwYXRoLCBzd2FwcGluZyBvdXQgbGlua2VkIHBhdGhwYXJ0cyBmb3IgdGhlaXIgcmVhbFxuICAvLyB2YWx1ZXNcbiAgZnVuY3Rpb24gTE9PUCgpIHtcbiAgICAvLyBzdG9wIGlmIHNjYW5uZWQgcGFzdCBlbmQgb2YgcGF0aFxuICAgIGlmIChwb3MgPj0gcC5sZW5ndGgpIHtcbiAgICAgIGlmIChjYWNoZSkgY2FjaGVbb3JpZ2luYWxdID0gcDtcbiAgICAgIHJldHVybiBjYihudWxsLCBwKTtcbiAgICB9XG5cbiAgICAvLyBmaW5kIHRoZSBuZXh0IHBhcnRcbiAgICBuZXh0UGFydFJlLmxhc3RJbmRleCA9IHBvcztcbiAgICB2YXIgcmVzdWx0ID0gbmV4dFBhcnRSZS5leGVjKHApO1xuICAgIHByZXZpb3VzID0gY3VycmVudDtcbiAgICBjdXJyZW50ICs9IHJlc3VsdFswXTtcbiAgICBiYXNlID0gcHJldmlvdXMgKyByZXN1bHRbMV07XG4gICAgcG9zID0gbmV4dFBhcnRSZS5sYXN0SW5kZXg7XG5cbiAgICAvLyBjb250aW51ZSBpZiBub3QgYSBzeW1saW5rXG4gICAgaWYgKGtub3duSGFyZFtiYXNlXSB8fCAoY2FjaGUgJiYgY2FjaGVbYmFzZV0gPT09IGJhc2UpKSB7XG4gICAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhMT09QKTtcbiAgICB9XG5cbiAgICBpZiAoY2FjaGUgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGNhY2hlLCBiYXNlKSkge1xuICAgICAgLy8ga25vd24gc3ltYm9saWMgbGluay4gIG5vIG5lZWQgdG8gc3RhdCBhZ2Fpbi5cbiAgICAgIHJldHVybiBnb3RSZXNvbHZlZExpbmsoY2FjaGVbYmFzZV0pO1xuICAgIH1cblxuICAgIHJldHVybiBmcy5sc3RhdChiYXNlLCBnb3RTdGF0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdvdFN0YXQoZXJyLCBzdGF0KSB7XG4gICAgaWYgKGVycikgcmV0dXJuIGNiKGVycik7XG5cbiAgICAvLyBpZiBub3QgYSBzeW1saW5rLCBza2lwIHRvIHRoZSBuZXh0IHBhdGggcGFydFxuICAgIGlmICghc3RhdC5pc1N5bWJvbGljTGluaygpKSB7XG4gICAgICBrbm93bkhhcmRbYmFzZV0gPSB0cnVlO1xuICAgICAgaWYgKGNhY2hlKSBjYWNoZVtiYXNlXSA9IGJhc2U7XG4gICAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhMT09QKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0ICYgcmVhZCB0aGUgbGluayBpZiBub3QgcmVhZCBiZWZvcmVcbiAgICAvLyBjYWxsIGdvdFRhcmdldCBhcyBzb29uIGFzIHRoZSBsaW5rIHRhcmdldCBpcyBrbm93blxuICAgIC8vIGRldi9pbm8gYWx3YXlzIHJldHVybiAwIG9uIHdpbmRvd3MsIHNvIHNraXAgdGhlIGNoZWNrLlxuICAgIGlmICghaXNXaW5kb3dzKSB7XG4gICAgICB2YXIgaWQgPSBzdGF0LmRldi50b1N0cmluZygzMikgKyAnOicgKyBzdGF0Lmluby50b1N0cmluZygzMik7XG4gICAgICBpZiAoc2VlbkxpbmtzLmhhc093blByb3BlcnR5KGlkKSkge1xuICAgICAgICByZXR1cm4gZ290VGFyZ2V0KG51bGwsIHNlZW5MaW5rc1tpZF0sIGJhc2UpO1xuICAgICAgfVxuICAgIH1cbiAgICBmcy5zdGF0KGJhc2UsIGZ1bmN0aW9uKGVycikge1xuICAgICAgaWYgKGVycikgcmV0dXJuIGNiKGVycik7XG5cbiAgICAgIGZzLnJlYWRsaW5rKGJhc2UsIGZ1bmN0aW9uKGVyciwgdGFyZ2V0KSB7XG4gICAgICAgIGlmICghaXNXaW5kb3dzKSBzZWVuTGlua3NbaWRdID0gdGFyZ2V0O1xuICAgICAgICBnb3RUYXJnZXQoZXJyLCB0YXJnZXQpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnb3RUYXJnZXQoZXJyLCB0YXJnZXQsIGJhc2UpIHtcbiAgICBpZiAoZXJyKSByZXR1cm4gY2IoZXJyKTtcblxuICAgIHZhciByZXNvbHZlZExpbmsgPSBwYXRoTW9kdWxlLnJlc29sdmUocHJldmlvdXMsIHRhcmdldCk7XG4gICAgaWYgKGNhY2hlKSBjYWNoZVtiYXNlXSA9IHJlc29sdmVkTGluaztcbiAgICBnb3RSZXNvbHZlZExpbmsocmVzb2x2ZWRMaW5rKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdvdFJlc29sdmVkTGluayhyZXNvbHZlZExpbmspIHtcbiAgICAvLyByZXNvbHZlIHRoZSBsaW5rLCB0aGVuIHN0YXJ0IG92ZXJcbiAgICBwID0gcGF0aE1vZHVsZS5yZXNvbHZlKHJlc29sdmVkTGluaywgcC5zbGljZShwb3MpKTtcbiAgICBzdGFydCgpO1xuICB9XG59O1xuIiwiZXhwb3J0cy5hbHBoYXNvcnQgPSBhbHBoYXNvcnRcbmV4cG9ydHMuYWxwaGFzb3J0aSA9IGFscGhhc29ydGlcbmV4cG9ydHMuc2V0b3B0cyA9IHNldG9wdHNcbmV4cG9ydHMub3duUHJvcCA9IG93blByb3BcbmV4cG9ydHMubWFrZUFicyA9IG1ha2VBYnNcbmV4cG9ydHMuZmluaXNoID0gZmluaXNoXG5leHBvcnRzLm1hcmsgPSBtYXJrXG5leHBvcnRzLmlzSWdub3JlZCA9IGlzSWdub3JlZFxuZXhwb3J0cy5jaGlsZHJlbklnbm9yZWQgPSBjaGlsZHJlbklnbm9yZWRcblxuZnVuY3Rpb24gb3duUHJvcCAob2JqLCBmaWVsZCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgZmllbGQpXG59XG5cbnZhciBwYXRoID0gcmVxdWlyZShcInBhdGhcIilcbnZhciBtaW5pbWF0Y2ggPSByZXF1aXJlKFwibWluaW1hdGNoXCIpXG52YXIgaXNBYnNvbHV0ZSA9IHJlcXVpcmUoXCJwYXRoLWlzLWFic29sdXRlXCIpXG52YXIgTWluaW1hdGNoID0gbWluaW1hdGNoLk1pbmltYXRjaFxuXG5mdW5jdGlvbiBhbHBoYXNvcnRpIChhLCBiKSB7XG4gIHJldHVybiBhLnRvTG93ZXJDYXNlKCkubG9jYWxlQ29tcGFyZShiLnRvTG93ZXJDYXNlKCkpXG59XG5cbmZ1bmN0aW9uIGFscGhhc29ydCAoYSwgYikge1xuICByZXR1cm4gYS5sb2NhbGVDb21wYXJlKGIpXG59XG5cbmZ1bmN0aW9uIHNldHVwSWdub3JlcyAoc2VsZiwgb3B0aW9ucykge1xuICBzZWxmLmlnbm9yZSA9IG9wdGlvbnMuaWdub3JlIHx8IFtdXG5cbiAgaWYgKCFBcnJheS5pc0FycmF5KHNlbGYuaWdub3JlKSlcbiAgICBzZWxmLmlnbm9yZSA9IFtzZWxmLmlnbm9yZV1cblxuICBpZiAoc2VsZi5pZ25vcmUubGVuZ3RoKSB7XG4gICAgc2VsZi5pZ25vcmUgPSBzZWxmLmlnbm9yZS5tYXAoaWdub3JlTWFwKVxuICB9XG59XG5cbi8vIGlnbm9yZSBwYXR0ZXJucyBhcmUgYWx3YXlzIGluIGRvdDp0cnVlIG1vZGUuXG5mdW5jdGlvbiBpZ25vcmVNYXAgKHBhdHRlcm4pIHtcbiAgdmFyIGdtYXRjaGVyID0gbnVsbFxuICBpZiAocGF0dGVybi5zbGljZSgtMykgPT09ICcvKionKSB7XG4gICAgdmFyIGdwYXR0ZXJuID0gcGF0dGVybi5yZXBsYWNlKC8oXFwvXFwqXFwqKSskLywgJycpXG4gICAgZ21hdGNoZXIgPSBuZXcgTWluaW1hdGNoKGdwYXR0ZXJuLCB7IGRvdDogdHJ1ZSB9KVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtYXRjaGVyOiBuZXcgTWluaW1hdGNoKHBhdHRlcm4sIHsgZG90OiB0cnVlIH0pLFxuICAgIGdtYXRjaGVyOiBnbWF0Y2hlclxuICB9XG59XG5cbmZ1bmN0aW9uIHNldG9wdHMgKHNlbGYsIHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zKVxuICAgIG9wdGlvbnMgPSB7fVxuXG4gIC8vIGJhc2UtbWF0Y2hpbmc6IGp1c3QgdXNlIGdsb2JzdGFyIGZvciB0aGF0LlxuICBpZiAob3B0aW9ucy5tYXRjaEJhc2UgJiYgLTEgPT09IHBhdHRlcm4uaW5kZXhPZihcIi9cIikpIHtcbiAgICBpZiAob3B0aW9ucy5ub2dsb2JzdGFyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJiYXNlIG1hdGNoaW5nIHJlcXVpcmVzIGdsb2JzdGFyXCIpXG4gICAgfVxuICAgIHBhdHRlcm4gPSBcIioqL1wiICsgcGF0dGVyblxuICB9XG5cbiAgc2VsZi5zaWxlbnQgPSAhIW9wdGlvbnMuc2lsZW50XG4gIHNlbGYucGF0dGVybiA9IHBhdHRlcm5cbiAgc2VsZi5zdHJpY3QgPSBvcHRpb25zLnN0cmljdCAhPT0gZmFsc2VcbiAgc2VsZi5yZWFscGF0aCA9ICEhb3B0aW9ucy5yZWFscGF0aFxuICBzZWxmLnJlYWxwYXRoQ2FjaGUgPSBvcHRpb25zLnJlYWxwYXRoQ2FjaGUgfHwgT2JqZWN0LmNyZWF0ZShudWxsKVxuICBzZWxmLmZvbGxvdyA9ICEhb3B0aW9ucy5mb2xsb3dcbiAgc2VsZi5kb3QgPSAhIW9wdGlvbnMuZG90XG4gIHNlbGYubWFyayA9ICEhb3B0aW9ucy5tYXJrXG4gIHNlbGYubm9kaXIgPSAhIW9wdGlvbnMubm9kaXJcbiAgaWYgKHNlbGYubm9kaXIpXG4gICAgc2VsZi5tYXJrID0gdHJ1ZVxuICBzZWxmLnN5bmMgPSAhIW9wdGlvbnMuc3luY1xuICBzZWxmLm5vdW5pcXVlID0gISFvcHRpb25zLm5vdW5pcXVlXG4gIHNlbGYubm9udWxsID0gISFvcHRpb25zLm5vbnVsbFxuICBzZWxmLm5vc29ydCA9ICEhb3B0aW9ucy5ub3NvcnRcbiAgc2VsZi5ub2Nhc2UgPSAhIW9wdGlvbnMubm9jYXNlXG4gIHNlbGYuc3RhdCA9ICEhb3B0aW9ucy5zdGF0XG4gIHNlbGYubm9wcm9jZXNzID0gISFvcHRpb25zLm5vcHJvY2Vzc1xuICBzZWxmLmFic29sdXRlID0gISFvcHRpb25zLmFic29sdXRlXG5cbiAgc2VsZi5tYXhMZW5ndGggPSBvcHRpb25zLm1heExlbmd0aCB8fCBJbmZpbml0eVxuICBzZWxmLmNhY2hlID0gb3B0aW9ucy5jYWNoZSB8fCBPYmplY3QuY3JlYXRlKG51bGwpXG4gIHNlbGYuc3RhdENhY2hlID0gb3B0aW9ucy5zdGF0Q2FjaGUgfHwgT2JqZWN0LmNyZWF0ZShudWxsKVxuICBzZWxmLnN5bWxpbmtzID0gb3B0aW9ucy5zeW1saW5rcyB8fCBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgc2V0dXBJZ25vcmVzKHNlbGYsIG9wdGlvbnMpXG5cbiAgc2VsZi5jaGFuZ2VkQ3dkID0gZmFsc2VcbiAgdmFyIGN3ZCA9IHByb2Nlc3MuY3dkKClcbiAgaWYgKCFvd25Qcm9wKG9wdGlvbnMsIFwiY3dkXCIpKVxuICAgIHNlbGYuY3dkID0gY3dkXG4gIGVsc2Uge1xuICAgIHNlbGYuY3dkID0gcGF0aC5yZXNvbHZlKG9wdGlvbnMuY3dkKVxuICAgIHNlbGYuY2hhbmdlZEN3ZCA9IHNlbGYuY3dkICE9PSBjd2RcbiAgfVxuXG4gIHNlbGYucm9vdCA9IG9wdGlvbnMucm9vdCB8fCBwYXRoLnJlc29sdmUoc2VsZi5jd2QsIFwiL1wiKVxuICBzZWxmLnJvb3QgPSBwYXRoLnJlc29sdmUoc2VsZi5yb290KVxuICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gXCJ3aW4zMlwiKVxuICAgIHNlbGYucm9vdCA9IHNlbGYucm9vdC5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKVxuXG4gIC8vIFRPRE86IGlzIGFuIGFic29sdXRlIGBjd2RgIHN1cHBvc2VkIHRvIGJlIHJlc29sdmVkIGFnYWluc3QgYHJvb3RgP1xuICAvLyBlLmcuIHsgY3dkOiAnL3Rlc3QnLCByb290OiBfX2Rpcm5hbWUgfSA9PT0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy90ZXN0JylcbiAgc2VsZi5jd2RBYnMgPSBpc0Fic29sdXRlKHNlbGYuY3dkKSA/IHNlbGYuY3dkIDogbWFrZUFicyhzZWxmLCBzZWxmLmN3ZClcbiAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT09IFwid2luMzJcIilcbiAgICBzZWxmLmN3ZEFicyA9IHNlbGYuY3dkQWJzLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpXG4gIHNlbGYubm9tb3VudCA9ICEhb3B0aW9ucy5ub21vdW50XG5cbiAgLy8gZGlzYWJsZSBjb21tZW50cyBhbmQgbmVnYXRpb24gaW4gTWluaW1hdGNoLlxuICAvLyBOb3RlIHRoYXQgdGhleSBhcmUgbm90IHN1cHBvcnRlZCBpbiBHbG9iIGl0c2VsZiBhbnl3YXkuXG4gIG9wdGlvbnMubm9uZWdhdGUgPSB0cnVlXG4gIG9wdGlvbnMubm9jb21tZW50ID0gdHJ1ZVxuXG4gIHNlbGYubWluaW1hdGNoID0gbmV3IE1pbmltYXRjaChwYXR0ZXJuLCBvcHRpb25zKVxuICBzZWxmLm9wdGlvbnMgPSBzZWxmLm1pbmltYXRjaC5vcHRpb25zXG59XG5cbmZ1bmN0aW9uIGZpbmlzaCAoc2VsZikge1xuICB2YXIgbm91ID0gc2VsZi5ub3VuaXF1ZVxuICB2YXIgYWxsID0gbm91ID8gW10gOiBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBzZWxmLm1hdGNoZXMubGVuZ3RoOyBpIDwgbDsgaSArKykge1xuICAgIHZhciBtYXRjaGVzID0gc2VsZi5tYXRjaGVzW2ldXG4gICAgaWYgKCFtYXRjaGVzIHx8IE9iamVjdC5rZXlzKG1hdGNoZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKHNlbGYubm9udWxsKSB7XG4gICAgICAgIC8vIGRvIGxpa2UgdGhlIHNoZWxsLCBhbmQgc3BpdCBvdXQgdGhlIGxpdGVyYWwgZ2xvYlxuICAgICAgICB2YXIgbGl0ZXJhbCA9IHNlbGYubWluaW1hdGNoLmdsb2JTZXRbaV1cbiAgICAgICAgaWYgKG5vdSlcbiAgICAgICAgICBhbGwucHVzaChsaXRlcmFsKVxuICAgICAgICBlbHNlXG4gICAgICAgICAgYWxsW2xpdGVyYWxdID0gdHJ1ZVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBoYWQgbWF0Y2hlc1xuICAgICAgdmFyIG0gPSBPYmplY3Qua2V5cyhtYXRjaGVzKVxuICAgICAgaWYgKG5vdSlcbiAgICAgICAgYWxsLnB1c2guYXBwbHkoYWxsLCBtKVxuICAgICAgZWxzZVxuICAgICAgICBtLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICBhbGxbbV0gPSB0cnVlXG4gICAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgaWYgKCFub3UpXG4gICAgYWxsID0gT2JqZWN0LmtleXMoYWxsKVxuXG4gIGlmICghc2VsZi5ub3NvcnQpXG4gICAgYWxsID0gYWxsLnNvcnQoc2VsZi5ub2Nhc2UgPyBhbHBoYXNvcnRpIDogYWxwaGFzb3J0KVxuXG4gIC8vIGF0ICpzb21lKiBwb2ludCB3ZSBzdGF0dGVkIGFsbCBvZiB0aGVzZVxuICBpZiAoc2VsZi5tYXJrKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbGwubGVuZ3RoOyBpKyspIHtcbiAgICAgIGFsbFtpXSA9IHNlbGYuX21hcmsoYWxsW2ldKVxuICAgIH1cbiAgICBpZiAoc2VsZi5ub2Rpcikge1xuICAgICAgYWxsID0gYWxsLmZpbHRlcihmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgbm90RGlyID0gISgvXFwvJC8udGVzdChlKSlcbiAgICAgICAgdmFyIGMgPSBzZWxmLmNhY2hlW2VdIHx8IHNlbGYuY2FjaGVbbWFrZUFicyhzZWxmLCBlKV1cbiAgICAgICAgaWYgKG5vdERpciAmJiBjKVxuICAgICAgICAgIG5vdERpciA9IGMgIT09ICdESVInICYmICFBcnJheS5pc0FycmF5KGMpXG4gICAgICAgIHJldHVybiBub3REaXJcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgaWYgKHNlbGYuaWdub3JlLmxlbmd0aClcbiAgICBhbGwgPSBhbGwuZmlsdGVyKGZ1bmN0aW9uKG0pIHtcbiAgICAgIHJldHVybiAhaXNJZ25vcmVkKHNlbGYsIG0pXG4gICAgfSlcblxuICBzZWxmLmZvdW5kID0gYWxsXG59XG5cbmZ1bmN0aW9uIG1hcmsgKHNlbGYsIHApIHtcbiAgdmFyIGFicyA9IG1ha2VBYnMoc2VsZiwgcClcbiAgdmFyIGMgPSBzZWxmLmNhY2hlW2Fic11cbiAgdmFyIG0gPSBwXG4gIGlmIChjKSB7XG4gICAgdmFyIGlzRGlyID0gYyA9PT0gJ0RJUicgfHwgQXJyYXkuaXNBcnJheShjKVxuICAgIHZhciBzbGFzaCA9IHAuc2xpY2UoLTEpID09PSAnLydcblxuICAgIGlmIChpc0RpciAmJiAhc2xhc2gpXG4gICAgICBtICs9ICcvJ1xuICAgIGVsc2UgaWYgKCFpc0RpciAmJiBzbGFzaClcbiAgICAgIG0gPSBtLnNsaWNlKDAsIC0xKVxuXG4gICAgaWYgKG0gIT09IHApIHtcbiAgICAgIHZhciBtYWJzID0gbWFrZUFicyhzZWxmLCBtKVxuICAgICAgc2VsZi5zdGF0Q2FjaGVbbWFic10gPSBzZWxmLnN0YXRDYWNoZVthYnNdXG4gICAgICBzZWxmLmNhY2hlW21hYnNdID0gc2VsZi5jYWNoZVthYnNdXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1cbn1cblxuLy8gbG90dGEgc2l0dXBzLi4uXG5mdW5jdGlvbiBtYWtlQWJzIChzZWxmLCBmKSB7XG4gIHZhciBhYnMgPSBmXG4gIGlmIChmLmNoYXJBdCgwKSA9PT0gJy8nKSB7XG4gICAgYWJzID0gcGF0aC5qb2luKHNlbGYucm9vdCwgZilcbiAgfSBlbHNlIGlmIChpc0Fic29sdXRlKGYpIHx8IGYgPT09ICcnKSB7XG4gICAgYWJzID0gZlxuICB9IGVsc2UgaWYgKHNlbGYuY2hhbmdlZEN3ZCkge1xuICAgIGFicyA9IHBhdGgucmVzb2x2ZShzZWxmLmN3ZCwgZilcbiAgfSBlbHNlIHtcbiAgICBhYnMgPSBwYXRoLnJlc29sdmUoZilcbiAgfVxuXG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKVxuICAgIGFicyA9IGFicy5yZXBsYWNlKC9cXFxcL2csICcvJylcblxuICByZXR1cm4gYWJzXG59XG5cblxuLy8gUmV0dXJuIHRydWUsIGlmIHBhdHRlcm4gZW5kcyB3aXRoIGdsb2JzdGFyICcqKicsIGZvciB0aGUgYWNjb21wYW55aW5nIHBhcmVudCBkaXJlY3RvcnkuXG4vLyBFeDotIElmIG5vZGVfbW9kdWxlcy8qKiBpcyB0aGUgcGF0dGVybiwgYWRkICdub2RlX21vZHVsZXMnIHRvIGlnbm9yZSBsaXN0IGFsb25nIHdpdGggaXQncyBjb250ZW50c1xuZnVuY3Rpb24gaXNJZ25vcmVkIChzZWxmLCBwYXRoKSB7XG4gIGlmICghc2VsZi5pZ25vcmUubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZVxuXG4gIHJldHVybiBzZWxmLmlnbm9yZS5zb21lKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICByZXR1cm4gaXRlbS5tYXRjaGVyLm1hdGNoKHBhdGgpIHx8ICEhKGl0ZW0uZ21hdGNoZXIgJiYgaXRlbS5nbWF0Y2hlci5tYXRjaChwYXRoKSlcbiAgfSlcbn1cblxuZnVuY3Rpb24gY2hpbGRyZW5JZ25vcmVkIChzZWxmLCBwYXRoKSB7XG4gIGlmICghc2VsZi5pZ25vcmUubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZVxuXG4gIHJldHVybiBzZWxmLmlnbm9yZS5zb21lKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICByZXR1cm4gISEoaXRlbS5nbWF0Y2hlciAmJiBpdGVtLmdtYXRjaGVyLm1hdGNoKHBhdGgpKVxuICB9KVxufVxuIiwiLy8gQXBwcm9hY2g6XG4vL1xuLy8gMS4gR2V0IHRoZSBtaW5pbWF0Y2ggc2V0XG4vLyAyLiBGb3IgZWFjaCBwYXR0ZXJuIGluIHRoZSBzZXQsIFBST0NFU1MocGF0dGVybiwgZmFsc2UpXG4vLyAzLiBTdG9yZSBtYXRjaGVzIHBlci1zZXQsIHRoZW4gdW5pcSB0aGVtXG4vL1xuLy8gUFJPQ0VTUyhwYXR0ZXJuLCBpbkdsb2JTdGFyKVxuLy8gR2V0IHRoZSBmaXJzdCBbbl0gaXRlbXMgZnJvbSBwYXR0ZXJuIHRoYXQgYXJlIGFsbCBzdHJpbmdzXG4vLyBKb2luIHRoZXNlIHRvZ2V0aGVyLiAgVGhpcyBpcyBQUkVGSVguXG4vLyAgIElmIHRoZXJlIGlzIG5vIG1vcmUgcmVtYWluaW5nLCB0aGVuIHN0YXQoUFJFRklYKSBhbmRcbi8vICAgYWRkIHRvIG1hdGNoZXMgaWYgaXQgc3VjY2VlZHMuICBFTkQuXG4vL1xuLy8gSWYgaW5HbG9iU3RhciBhbmQgUFJFRklYIGlzIHN5bWxpbmsgYW5kIHBvaW50cyB0byBkaXJcbi8vICAgc2V0IEVOVFJJRVMgPSBbXVxuLy8gZWxzZSByZWFkZGlyKFBSRUZJWCkgYXMgRU5UUklFU1xuLy8gICBJZiBmYWlsLCBFTkRcbi8vXG4vLyB3aXRoIEVOVFJJRVNcbi8vICAgSWYgcGF0dGVybltuXSBpcyBHTE9CU1RBUlxuLy8gICAgIC8vIGhhbmRsZSB0aGUgY2FzZSB3aGVyZSB0aGUgZ2xvYnN0YXIgbWF0Y2ggaXMgZW1wdHlcbi8vICAgICAvLyBieSBwcnVuaW5nIGl0IG91dCwgYW5kIHRlc3RpbmcgdGhlIHJlc3VsdGluZyBwYXR0ZXJuXG4vLyAgICAgUFJPQ0VTUyhwYXR0ZXJuWzAuLm5dICsgcGF0dGVybltuKzEgLi4gJF0sIGZhbHNlKVxuLy8gICAgIC8vIGhhbmRsZSBvdGhlciBjYXNlcy5cbi8vICAgICBmb3IgRU5UUlkgaW4gRU5UUklFUyAobm90IGRvdGZpbGVzKVxuLy8gICAgICAgLy8gYXR0YWNoIGdsb2JzdGFyICsgdGFpbCBvbnRvIHRoZSBlbnRyeVxuLy8gICAgICAgLy8gTWFyayB0aGF0IHRoaXMgZW50cnkgaXMgYSBnbG9ic3RhciBtYXRjaFxuLy8gICAgICAgUFJPQ0VTUyhwYXR0ZXJuWzAuLm5dICsgRU5UUlkgKyBwYXR0ZXJuW24gLi4gJF0sIHRydWUpXG4vL1xuLy8gICBlbHNlIC8vIG5vdCBnbG9ic3RhclxuLy8gICAgIGZvciBFTlRSWSBpbiBFTlRSSUVTIChub3QgZG90ZmlsZXMsIHVubGVzcyBwYXR0ZXJuW25dIGlzIGRvdClcbi8vICAgICAgIFRlc3QgRU5UUlkgYWdhaW5zdCBwYXR0ZXJuW25dXG4vLyAgICAgICBJZiBmYWlscywgY29udGludWVcbi8vICAgICAgIElmIHBhc3NlcywgUFJPQ0VTUyhwYXR0ZXJuWzAuLm5dICsgaXRlbSArIHBhdHRlcm5bbisxIC4uICRdKVxuLy9cbi8vIENhdmVhdDpcbi8vICAgQ2FjaGUgYWxsIHN0YXRzIGFuZCByZWFkZGlycyByZXN1bHRzIHRvIG1pbmltaXplIHN5c2NhbGwuICBTaW5jZSBhbGxcbi8vICAgd2UgZXZlciBjYXJlIGFib3V0IGlzIGV4aXN0ZW5jZSBhbmQgZGlyZWN0b3J5LW5lc3MsIHdlIGNhbiBqdXN0IGtlZXBcbi8vICAgYHRydWVgIGZvciBmaWxlcywgYW5kIFtjaGlsZHJlbiwuLi5dIGZvciBkaXJlY3Rvcmllcywgb3IgYGZhbHNlYCBmb3Jcbi8vICAgdGhpbmdzIHRoYXQgZG9uJ3QgZXhpc3QuXG5cbm1vZHVsZS5leHBvcnRzID0gZ2xvYlxuXG52YXIgZnMgPSByZXF1aXJlKCdmcycpXG52YXIgcnAgPSByZXF1aXJlKCdmcy5yZWFscGF0aCcpXG52YXIgbWluaW1hdGNoID0gcmVxdWlyZSgnbWluaW1hdGNoJylcbnZhciBNaW5pbWF0Y2ggPSBtaW5pbWF0Y2guTWluaW1hdGNoXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXJcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0JylcbnZhciBpc0Fic29sdXRlID0gcmVxdWlyZSgncGF0aC1pcy1hYnNvbHV0ZScpXG52YXIgZ2xvYlN5bmMgPSByZXF1aXJlKCcuL3N5bmMuanMnKVxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uLmpzJylcbnZhciBhbHBoYXNvcnQgPSBjb21tb24uYWxwaGFzb3J0XG52YXIgYWxwaGFzb3J0aSA9IGNvbW1vbi5hbHBoYXNvcnRpXG52YXIgc2V0b3B0cyA9IGNvbW1vbi5zZXRvcHRzXG52YXIgb3duUHJvcCA9IGNvbW1vbi5vd25Qcm9wXG52YXIgaW5mbGlnaHQgPSByZXF1aXJlKCdpbmZsaWdodCcpXG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKVxudmFyIGNoaWxkcmVuSWdub3JlZCA9IGNvbW1vbi5jaGlsZHJlbklnbm9yZWRcbnZhciBpc0lnbm9yZWQgPSBjb21tb24uaXNJZ25vcmVkXG5cbnZhciBvbmNlID0gcmVxdWlyZSgnb25jZScpXG5cbmZ1bmN0aW9uIGdsb2IgKHBhdHRlcm4sIG9wdGlvbnMsIGNiKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgY2IgPSBvcHRpb25zLCBvcHRpb25zID0ge31cbiAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge31cblxuICBpZiAob3B0aW9ucy5zeW5jKSB7XG4gICAgaWYgKGNiKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignY2FsbGJhY2sgcHJvdmlkZWQgdG8gc3luYyBnbG9iJylcbiAgICByZXR1cm4gZ2xvYlN5bmMocGF0dGVybiwgb3B0aW9ucylcbiAgfVxuXG4gIHJldHVybiBuZXcgR2xvYihwYXR0ZXJuLCBvcHRpb25zLCBjYilcbn1cblxuZ2xvYi5zeW5jID0gZ2xvYlN5bmNcbnZhciBHbG9iU3luYyA9IGdsb2IuR2xvYlN5bmMgPSBnbG9iU3luYy5HbG9iU3luY1xuXG4vLyBvbGQgYXBpIHN1cmZhY2Vcbmdsb2IuZ2xvYiA9IGdsb2JcblxuZnVuY3Rpb24gZXh0ZW5kIChvcmlnaW4sIGFkZCkge1xuICBpZiAoYWRkID09PSBudWxsIHx8IHR5cGVvZiBhZGQgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG9yaWdpblxuICB9XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhZGQpXG4gIHZhciBpID0ga2V5cy5sZW5ndGhcbiAgd2hpbGUgKGktLSkge1xuICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXVxuICB9XG4gIHJldHVybiBvcmlnaW5cbn1cblxuZ2xvYi5oYXNNYWdpYyA9IGZ1bmN0aW9uIChwYXR0ZXJuLCBvcHRpb25zXykge1xuICB2YXIgb3B0aW9ucyA9IGV4dGVuZCh7fSwgb3B0aW9uc18pXG4gIG9wdGlvbnMubm9wcm9jZXNzID0gdHJ1ZVxuXG4gIHZhciBnID0gbmV3IEdsb2IocGF0dGVybiwgb3B0aW9ucylcbiAgdmFyIHNldCA9IGcubWluaW1hdGNoLnNldFxuXG4gIGlmICghcGF0dGVybilcbiAgICByZXR1cm4gZmFsc2VcblxuICBpZiAoc2V0Lmxlbmd0aCA+IDEpXG4gICAgcmV0dXJuIHRydWVcblxuICBmb3IgKHZhciBqID0gMDsgaiA8IHNldFswXS5sZW5ndGg7IGorKykge1xuICAgIGlmICh0eXBlb2Ygc2V0WzBdW2pdICE9PSAnc3RyaW5nJylcbiAgICAgIHJldHVybiB0cnVlXG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxuZ2xvYi5HbG9iID0gR2xvYlxuaW5oZXJpdHMoR2xvYiwgRUUpXG5mdW5jdGlvbiBHbG9iIChwYXR0ZXJuLCBvcHRpb25zLCBjYikge1xuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IG9wdGlvbnNcbiAgICBvcHRpb25zID0gbnVsbFxuICB9XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5zeW5jKSB7XG4gICAgaWYgKGNiKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignY2FsbGJhY2sgcHJvdmlkZWQgdG8gc3luYyBnbG9iJylcbiAgICByZXR1cm4gbmV3IEdsb2JTeW5jKHBhdHRlcm4sIG9wdGlvbnMpXG4gIH1cblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgR2xvYikpXG4gICAgcmV0dXJuIG5ldyBHbG9iKHBhdHRlcm4sIG9wdGlvbnMsIGNiKVxuXG4gIHNldG9wdHModGhpcywgcGF0dGVybiwgb3B0aW9ucylcbiAgdGhpcy5fZGlkUmVhbFBhdGggPSBmYWxzZVxuXG4gIC8vIHByb2Nlc3MgZWFjaCBwYXR0ZXJuIGluIHRoZSBtaW5pbWF0Y2ggc2V0XG4gIHZhciBuID0gdGhpcy5taW5pbWF0Y2guc2V0Lmxlbmd0aFxuXG4gIC8vIFRoZSBtYXRjaGVzIGFyZSBzdG9yZWQgYXMgezxmaWxlbmFtZT46IHRydWUsLi4ufSBzbyB0aGF0XG4gIC8vIGR1cGxpY2F0ZXMgYXJlIGF1dG9tYWdpY2FsbHkgcHJ1bmVkLlxuICAvLyBMYXRlciwgd2UgZG8gYW4gT2JqZWN0LmtleXMoKSBvbiB0aGVzZS5cbiAgLy8gS2VlcCB0aGVtIGFzIGEgbGlzdCBzbyB3ZSBjYW4gZmlsbCBpbiB3aGVuIG5vbnVsbCBpcyBzZXQuXG4gIHRoaXMubWF0Y2hlcyA9IG5ldyBBcnJheShuKVxuXG4gIGlmICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IG9uY2UoY2IpXG4gICAgdGhpcy5vbignZXJyb3InLCBjYilcbiAgICB0aGlzLm9uKCdlbmQnLCBmdW5jdGlvbiAobWF0Y2hlcykge1xuICAgICAgY2IobnVsbCwgbWF0Y2hlcylcbiAgICB9KVxuICB9XG5cbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHRoaXMuX3Byb2Nlc3NpbmcgPSAwXG5cbiAgdGhpcy5fZW1pdFF1ZXVlID0gW11cbiAgdGhpcy5fcHJvY2Vzc1F1ZXVlID0gW11cbiAgdGhpcy5wYXVzZWQgPSBmYWxzZVxuXG4gIGlmICh0aGlzLm5vcHJvY2VzcylcbiAgICByZXR1cm4gdGhpc1xuXG4gIGlmIChuID09PSAwKVxuICAgIHJldHVybiBkb25lKClcblxuICB2YXIgc3luYyA9IHRydWVcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpICsrKSB7XG4gICAgdGhpcy5fcHJvY2Vzcyh0aGlzLm1pbmltYXRjaC5zZXRbaV0sIGksIGZhbHNlLCBkb25lKVxuICB9XG4gIHN5bmMgPSBmYWxzZVxuXG4gIGZ1bmN0aW9uIGRvbmUgKCkge1xuICAgIC0tc2VsZi5fcHJvY2Vzc2luZ1xuICAgIGlmIChzZWxmLl9wcm9jZXNzaW5nIDw9IDApIHtcbiAgICAgIGlmIChzeW5jKSB7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHNlbGYuX2ZpbmlzaCgpXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWxmLl9maW5pc2goKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5HbG9iLnByb3RvdHlwZS5fZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICBhc3NlcnQodGhpcyBpbnN0YW5jZW9mIEdsb2IpXG4gIGlmICh0aGlzLmFib3J0ZWQpXG4gICAgcmV0dXJuXG5cbiAgaWYgKHRoaXMucmVhbHBhdGggJiYgIXRoaXMuX2RpZFJlYWxwYXRoKVxuICAgIHJldHVybiB0aGlzLl9yZWFscGF0aCgpXG5cbiAgY29tbW9uLmZpbmlzaCh0aGlzKVxuICB0aGlzLmVtaXQoJ2VuZCcsIHRoaXMuZm91bmQpXG59XG5cbkdsb2IucHJvdG90eXBlLl9yZWFscGF0aCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX2RpZFJlYWxwYXRoKVxuICAgIHJldHVyblxuXG4gIHRoaXMuX2RpZFJlYWxwYXRoID0gdHJ1ZVxuXG4gIHZhciBuID0gdGhpcy5tYXRjaGVzLmxlbmd0aFxuICBpZiAobiA9PT0gMClcbiAgICByZXR1cm4gdGhpcy5fZmluaXNoKClcblxuICB2YXIgc2VsZiA9IHRoaXNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm1hdGNoZXMubGVuZ3RoOyBpKyspXG4gICAgdGhpcy5fcmVhbHBhdGhTZXQoaSwgbmV4dClcblxuICBmdW5jdGlvbiBuZXh0ICgpIHtcbiAgICBpZiAoLS1uID09PSAwKVxuICAgICAgc2VsZi5fZmluaXNoKClcbiAgfVxufVxuXG5HbG9iLnByb3RvdHlwZS5fcmVhbHBhdGhTZXQgPSBmdW5jdGlvbiAoaW5kZXgsIGNiKSB7XG4gIHZhciBtYXRjaHNldCA9IHRoaXMubWF0Y2hlc1tpbmRleF1cbiAgaWYgKCFtYXRjaHNldClcbiAgICByZXR1cm4gY2IoKVxuXG4gIHZhciBmb3VuZCA9IE9iamVjdC5rZXlzKG1hdGNoc2V0KVxuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIG4gPSBmb3VuZC5sZW5ndGhcblxuICBpZiAobiA9PT0gMClcbiAgICByZXR1cm4gY2IoKVxuXG4gIHZhciBzZXQgPSB0aGlzLm1hdGNoZXNbaW5kZXhdID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuICBmb3VuZC5mb3JFYWNoKGZ1bmN0aW9uIChwLCBpKSB7XG4gICAgLy8gSWYgdGhlcmUncyBhIHByb2JsZW0gd2l0aCB0aGUgc3RhdCwgdGhlbiBpdCBtZWFucyB0aGF0XG4gICAgLy8gb25lIG9yIG1vcmUgb2YgdGhlIGxpbmtzIGluIHRoZSByZWFscGF0aCBjb3VsZG4ndCBiZVxuICAgIC8vIHJlc29sdmVkLiAganVzdCByZXR1cm4gdGhlIGFicyB2YWx1ZSBpbiB0aGF0IGNhc2UuXG4gICAgcCA9IHNlbGYuX21ha2VBYnMocClcbiAgICBycC5yZWFscGF0aChwLCBzZWxmLnJlYWxwYXRoQ2FjaGUsIGZ1bmN0aW9uIChlciwgcmVhbCkge1xuICAgICAgaWYgKCFlcilcbiAgICAgICAgc2V0W3JlYWxdID0gdHJ1ZVxuICAgICAgZWxzZSBpZiAoZXIuc3lzY2FsbCA9PT0gJ3N0YXQnKVxuICAgICAgICBzZXRbcF0gPSB0cnVlXG4gICAgICBlbHNlXG4gICAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCBlcikgLy8gc3JzbHkgd3RmIHJpZ2h0IGhlcmVcblxuICAgICAgaWYgKC0tbiA9PT0gMCkge1xuICAgICAgICBzZWxmLm1hdGNoZXNbaW5kZXhdID0gc2V0XG4gICAgICAgIGNiKClcbiAgICAgIH1cbiAgICB9KVxuICB9KVxufVxuXG5HbG9iLnByb3RvdHlwZS5fbWFyayA9IGZ1bmN0aW9uIChwKSB7XG4gIHJldHVybiBjb21tb24ubWFyayh0aGlzLCBwKVxufVxuXG5HbG9iLnByb3RvdHlwZS5fbWFrZUFicyA9IGZ1bmN0aW9uIChmKSB7XG4gIHJldHVybiBjb21tb24ubWFrZUFicyh0aGlzLCBmKVxufVxuXG5HbG9iLnByb3RvdHlwZS5hYm9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5hYm9ydGVkID0gdHJ1ZVxuICB0aGlzLmVtaXQoJ2Fib3J0Jylcbn1cblxuR2xvYi5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5wYXVzZWQpIHtcbiAgICB0aGlzLnBhdXNlZCA9IHRydWVcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJylcbiAgfVxufVxuXG5HbG9iLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnBhdXNlZCkge1xuICAgIHRoaXMuZW1pdCgncmVzdW1lJylcbiAgICB0aGlzLnBhdXNlZCA9IGZhbHNlXG4gICAgaWYgKHRoaXMuX2VtaXRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgIHZhciBlcSA9IHRoaXMuX2VtaXRRdWV1ZS5zbGljZSgwKVxuICAgICAgdGhpcy5fZW1pdFF1ZXVlLmxlbmd0aCA9IDBcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXEubGVuZ3RoOyBpICsrKSB7XG4gICAgICAgIHZhciBlID0gZXFbaV1cbiAgICAgICAgdGhpcy5fZW1pdE1hdGNoKGVbMF0sIGVbMV0pXG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0aGlzLl9wcm9jZXNzUXVldWUubGVuZ3RoKSB7XG4gICAgICB2YXIgcHEgPSB0aGlzLl9wcm9jZXNzUXVldWUuc2xpY2UoMClcbiAgICAgIHRoaXMuX3Byb2Nlc3NRdWV1ZS5sZW5ndGggPSAwXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBxLmxlbmd0aDsgaSArKykge1xuICAgICAgICB2YXIgcCA9IHBxW2ldXG4gICAgICAgIHRoaXMuX3Byb2Nlc3NpbmctLVxuICAgICAgICB0aGlzLl9wcm9jZXNzKHBbMF0sIHBbMV0sIHBbMl0sIHBbM10pXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbkdsb2IucHJvdG90eXBlLl9wcm9jZXNzID0gZnVuY3Rpb24gKHBhdHRlcm4sIGluZGV4LCBpbkdsb2JTdGFyLCBjYikge1xuICBhc3NlcnQodGhpcyBpbnN0YW5jZW9mIEdsb2IpXG4gIGFzc2VydCh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpXG5cbiAgaWYgKHRoaXMuYWJvcnRlZClcbiAgICByZXR1cm5cblxuICB0aGlzLl9wcm9jZXNzaW5nKytcbiAgaWYgKHRoaXMucGF1c2VkKSB7XG4gICAgdGhpcy5fcHJvY2Vzc1F1ZXVlLnB1c2goW3BhdHRlcm4sIGluZGV4LCBpbkdsb2JTdGFyLCBjYl0pXG4gICAgcmV0dXJuXG4gIH1cblxuICAvL2NvbnNvbGUuZXJyb3IoJ1BST0NFU1MgJWQnLCB0aGlzLl9wcm9jZXNzaW5nLCBwYXR0ZXJuKVxuXG4gIC8vIEdldCB0aGUgZmlyc3QgW25dIHBhcnRzIG9mIHBhdHRlcm4gdGhhdCBhcmUgYWxsIHN0cmluZ3MuXG4gIHZhciBuID0gMFxuICB3aGlsZSAodHlwZW9mIHBhdHRlcm5bbl0gPT09ICdzdHJpbmcnKSB7XG4gICAgbiArK1xuICB9XG4gIC8vIG5vdyBuIGlzIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb25lIHRoYXQgaXMgKm5vdCogYSBzdHJpbmcuXG5cbiAgLy8gc2VlIGlmIHRoZXJlJ3MgYW55dGhpbmcgZWxzZVxuICB2YXIgcHJlZml4XG4gIHN3aXRjaCAobikge1xuICAgIC8vIGlmIG5vdCwgdGhlbiB0aGlzIGlzIHJhdGhlciBzaW1wbGVcbiAgICBjYXNlIHBhdHRlcm4ubGVuZ3RoOlxuICAgICAgdGhpcy5fcHJvY2Vzc1NpbXBsZShwYXR0ZXJuLmpvaW4oJy8nKSwgaW5kZXgsIGNiKVxuICAgICAgcmV0dXJuXG5cbiAgICBjYXNlIDA6XG4gICAgICAvLyBwYXR0ZXJuICpzdGFydHMqIHdpdGggc29tZSBub24tdHJpdmlhbCBpdGVtLlxuICAgICAgLy8gZ29pbmcgdG8gcmVhZGRpcihjd2QpLCBidXQgbm90IGluY2x1ZGUgdGhlIHByZWZpeCBpbiBtYXRjaGVzLlxuICAgICAgcHJlZml4ID0gbnVsbFxuICAgICAgYnJlYWtcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBwYXR0ZXJuIGhhcyBzb21lIHN0cmluZyBiaXRzIGluIHRoZSBmcm9udC5cbiAgICAgIC8vIHdoYXRldmVyIGl0IHN0YXJ0cyB3aXRoLCB3aGV0aGVyIHRoYXQncyAnYWJzb2x1dGUnIGxpa2UgL2Zvby9iYXIsXG4gICAgICAvLyBvciAncmVsYXRpdmUnIGxpa2UgJy4uL2JheidcbiAgICAgIHByZWZpeCA9IHBhdHRlcm4uc2xpY2UoMCwgbikuam9pbignLycpXG4gICAgICBicmVha1xuICB9XG5cbiAgdmFyIHJlbWFpbiA9IHBhdHRlcm4uc2xpY2UobilcblxuICAvLyBnZXQgdGhlIGxpc3Qgb2YgZW50cmllcy5cbiAgdmFyIHJlYWRcbiAgaWYgKHByZWZpeCA9PT0gbnVsbClcbiAgICByZWFkID0gJy4nXG4gIGVsc2UgaWYgKGlzQWJzb2x1dGUocHJlZml4KSB8fCBpc0Fic29sdXRlKHBhdHRlcm4uam9pbignLycpKSkge1xuICAgIGlmICghcHJlZml4IHx8ICFpc0Fic29sdXRlKHByZWZpeCkpXG4gICAgICBwcmVmaXggPSAnLycgKyBwcmVmaXhcbiAgICByZWFkID0gcHJlZml4XG4gIH0gZWxzZVxuICAgIHJlYWQgPSBwcmVmaXhcblxuICB2YXIgYWJzID0gdGhpcy5fbWFrZUFicyhyZWFkKVxuXG4gIC8vaWYgaWdub3JlZCwgc2tpcCBfcHJvY2Vzc2luZ1xuICBpZiAoY2hpbGRyZW5JZ25vcmVkKHRoaXMsIHJlYWQpKVxuICAgIHJldHVybiBjYigpXG5cbiAgdmFyIGlzR2xvYlN0YXIgPSByZW1haW5bMF0gPT09IG1pbmltYXRjaC5HTE9CU1RBUlxuICBpZiAoaXNHbG9iU3RhcilcbiAgICB0aGlzLl9wcm9jZXNzR2xvYlN0YXIocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIsIGNiKVxuICBlbHNlXG4gICAgdGhpcy5fcHJvY2Vzc1JlYWRkaXIocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIsIGNiKVxufVxuXG5HbG9iLnByb3RvdHlwZS5fcHJvY2Vzc1JlYWRkaXIgPSBmdW5jdGlvbiAocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIsIGNiKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB0aGlzLl9yZWFkZGlyKGFicywgaW5HbG9iU3RhciwgZnVuY3Rpb24gKGVyLCBlbnRyaWVzKSB7XG4gICAgcmV0dXJuIHNlbGYuX3Byb2Nlc3NSZWFkZGlyMihwcmVmaXgsIHJlYWQsIGFicywgcmVtYWluLCBpbmRleCwgaW5HbG9iU3RhciwgZW50cmllcywgY2IpXG4gIH0pXG59XG5cbkdsb2IucHJvdG90eXBlLl9wcm9jZXNzUmVhZGRpcjIgPSBmdW5jdGlvbiAocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIsIGVudHJpZXMsIGNiKSB7XG5cbiAgLy8gaWYgdGhlIGFicyBpc24ndCBhIGRpciwgdGhlbiBub3RoaW5nIGNhbiBtYXRjaCFcbiAgaWYgKCFlbnRyaWVzKVxuICAgIHJldHVybiBjYigpXG5cbiAgLy8gSXQgd2lsbCBvbmx5IG1hdGNoIGRvdCBlbnRyaWVzIGlmIGl0IHN0YXJ0cyB3aXRoIGEgZG90LCBvciBpZlxuICAvLyBkb3QgaXMgc2V0LiAgU3R1ZmYgbGlrZSBAKC5mb298LmJhcikgaXNuJ3QgYWxsb3dlZC5cbiAgdmFyIHBuID0gcmVtYWluWzBdXG4gIHZhciBuZWdhdGUgPSAhIXRoaXMubWluaW1hdGNoLm5lZ2F0ZVxuICB2YXIgcmF3R2xvYiA9IHBuLl9nbG9iXG4gIHZhciBkb3RPayA9IHRoaXMuZG90IHx8IHJhd0dsb2IuY2hhckF0KDApID09PSAnLidcblxuICB2YXIgbWF0Y2hlZEVudHJpZXMgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGVudHJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZSA9IGVudHJpZXNbaV1cbiAgICBpZiAoZS5jaGFyQXQoMCkgIT09ICcuJyB8fCBkb3RPaykge1xuICAgICAgdmFyIG1cbiAgICAgIGlmIChuZWdhdGUgJiYgIXByZWZpeCkge1xuICAgICAgICBtID0gIWUubWF0Y2gocG4pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtID0gZS5tYXRjaChwbilcbiAgICAgIH1cbiAgICAgIGlmIChtKVxuICAgICAgICBtYXRjaGVkRW50cmllcy5wdXNoKGUpXG4gICAgfVxuICB9XG5cbiAgLy9jb25zb2xlLmVycm9yKCdwcmQyJywgcHJlZml4LCBlbnRyaWVzLCByZW1haW5bMF0uX2dsb2IsIG1hdGNoZWRFbnRyaWVzKVxuXG4gIHZhciBsZW4gPSBtYXRjaGVkRW50cmllcy5sZW5ndGhcbiAgLy8gSWYgdGhlcmUgYXJlIG5vIG1hdGNoZWQgZW50cmllcywgdGhlbiBub3RoaW5nIG1hdGNoZXMuXG4gIGlmIChsZW4gPT09IDApXG4gICAgcmV0dXJuIGNiKClcblxuICAvLyBpZiB0aGlzIGlzIHRoZSBsYXN0IHJlbWFpbmluZyBwYXR0ZXJuIGJpdCwgdGhlbiBubyBuZWVkIGZvclxuICAvLyBhbiBhZGRpdGlvbmFsIHN0YXQgKnVubGVzcyogdGhlIHVzZXIgaGFzIHNwZWNpZmllZCBtYXJrIG9yXG4gIC8vIHN0YXQgZXhwbGljaXRseS4gIFdlIGtub3cgdGhleSBleGlzdCwgc2luY2UgcmVhZGRpciByZXR1cm5lZFxuICAvLyB0aGVtLlxuXG4gIGlmIChyZW1haW4ubGVuZ3RoID09PSAxICYmICF0aGlzLm1hcmsgJiYgIXRoaXMuc3RhdCkge1xuICAgIGlmICghdGhpcy5tYXRjaGVzW2luZGV4XSlcbiAgICAgIHRoaXMubWF0Y2hlc1tpbmRleF0gPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArKykge1xuICAgICAgdmFyIGUgPSBtYXRjaGVkRW50cmllc1tpXVxuICAgICAgaWYgKHByZWZpeCkge1xuICAgICAgICBpZiAocHJlZml4ICE9PSAnLycpXG4gICAgICAgICAgZSA9IHByZWZpeCArICcvJyArIGVcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGUgPSBwcmVmaXggKyBlXG4gICAgICB9XG5cbiAgICAgIGlmIChlLmNoYXJBdCgwKSA9PT0gJy8nICYmICF0aGlzLm5vbW91bnQpIHtcbiAgICAgICAgZSA9IHBhdGguam9pbih0aGlzLnJvb3QsIGUpXG4gICAgICB9XG4gICAgICB0aGlzLl9lbWl0TWF0Y2goaW5kZXgsIGUpXG4gICAgfVxuICAgIC8vIFRoaXMgd2FzIHRoZSBsYXN0IG9uZSwgYW5kIG5vIHN0YXRzIHdlcmUgbmVlZGVkXG4gICAgcmV0dXJuIGNiKClcbiAgfVxuXG4gIC8vIG5vdyB0ZXN0IGFsbCBtYXRjaGVkIGVudHJpZXMgYXMgc3RhbmQtaW5zIGZvciB0aGF0IHBhcnRcbiAgLy8gb2YgdGhlIHBhdHRlcm4uXG4gIHJlbWFpbi5zaGlmdCgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICsrKSB7XG4gICAgdmFyIGUgPSBtYXRjaGVkRW50cmllc1tpXVxuICAgIHZhciBuZXdQYXR0ZXJuXG4gICAgaWYgKHByZWZpeCkge1xuICAgICAgaWYgKHByZWZpeCAhPT0gJy8nKVxuICAgICAgICBlID0gcHJlZml4ICsgJy8nICsgZVxuICAgICAgZWxzZVxuICAgICAgICBlID0gcHJlZml4ICsgZVxuICAgIH1cbiAgICB0aGlzLl9wcm9jZXNzKFtlXS5jb25jYXQocmVtYWluKSwgaW5kZXgsIGluR2xvYlN0YXIsIGNiKVxuICB9XG4gIGNiKClcbn1cblxuR2xvYi5wcm90b3R5cGUuX2VtaXRNYXRjaCA9IGZ1bmN0aW9uIChpbmRleCwgZSkge1xuICBpZiAodGhpcy5hYm9ydGVkKVxuICAgIHJldHVyblxuXG4gIGlmIChpc0lnbm9yZWQodGhpcywgZSkpXG4gICAgcmV0dXJuXG5cbiAgaWYgKHRoaXMucGF1c2VkKSB7XG4gICAgdGhpcy5fZW1pdFF1ZXVlLnB1c2goW2luZGV4LCBlXSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIHZhciBhYnMgPSBpc0Fic29sdXRlKGUpID8gZSA6IHRoaXMuX21ha2VBYnMoZSlcblxuICBpZiAodGhpcy5tYXJrKVxuICAgIGUgPSB0aGlzLl9tYXJrKGUpXG5cbiAgaWYgKHRoaXMuYWJzb2x1dGUpXG4gICAgZSA9IGFic1xuXG4gIGlmICh0aGlzLm1hdGNoZXNbaW5kZXhdW2VdKVxuICAgIHJldHVyblxuXG4gIGlmICh0aGlzLm5vZGlyKSB7XG4gICAgdmFyIGMgPSB0aGlzLmNhY2hlW2Fic11cbiAgICBpZiAoYyA9PT0gJ0RJUicgfHwgQXJyYXkuaXNBcnJheShjKSlcbiAgICAgIHJldHVyblxuICB9XG5cbiAgdGhpcy5tYXRjaGVzW2luZGV4XVtlXSA9IHRydWVcblxuICB2YXIgc3QgPSB0aGlzLnN0YXRDYWNoZVthYnNdXG4gIGlmIChzdClcbiAgICB0aGlzLmVtaXQoJ3N0YXQnLCBlLCBzdClcblxuICB0aGlzLmVtaXQoJ21hdGNoJywgZSlcbn1cblxuR2xvYi5wcm90b3R5cGUuX3JlYWRkaXJJbkdsb2JTdGFyID0gZnVuY3Rpb24gKGFicywgY2IpIHtcbiAgaWYgKHRoaXMuYWJvcnRlZClcbiAgICByZXR1cm5cblxuICAvLyBmb2xsb3cgYWxsIHN5bWxpbmtlZCBkaXJlY3RvcmllcyBmb3JldmVyXG4gIC8vIGp1c3QgcHJvY2VlZCBhcyBpZiB0aGlzIGlzIGEgbm9uLWdsb2JzdGFyIHNpdHVhdGlvblxuICBpZiAodGhpcy5mb2xsb3cpXG4gICAgcmV0dXJuIHRoaXMuX3JlYWRkaXIoYWJzLCBmYWxzZSwgY2IpXG5cbiAgdmFyIGxzdGF0a2V5ID0gJ2xzdGF0XFwwJyArIGFic1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIGxzdGF0Y2IgPSBpbmZsaWdodChsc3RhdGtleSwgbHN0YXRjYl8pXG5cbiAgaWYgKGxzdGF0Y2IpXG4gICAgZnMubHN0YXQoYWJzLCBsc3RhdGNiKVxuXG4gIGZ1bmN0aW9uIGxzdGF0Y2JfIChlciwgbHN0YXQpIHtcbiAgICBpZiAoZXIgJiYgZXIuY29kZSA9PT0gJ0VOT0VOVCcpXG4gICAgICByZXR1cm4gY2IoKVxuXG4gICAgdmFyIGlzU3ltID0gbHN0YXQgJiYgbHN0YXQuaXNTeW1ib2xpY0xpbmsoKVxuICAgIHNlbGYuc3ltbGlua3NbYWJzXSA9IGlzU3ltXG5cbiAgICAvLyBJZiBpdCdzIG5vdCBhIHN5bWxpbmsgb3IgYSBkaXIsIHRoZW4gaXQncyBkZWZpbml0ZWx5IGEgcmVndWxhciBmaWxlLlxuICAgIC8vIGRvbid0IGJvdGhlciBkb2luZyBhIHJlYWRkaXIgaW4gdGhhdCBjYXNlLlxuICAgIGlmICghaXNTeW0gJiYgbHN0YXQgJiYgIWxzdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIHNlbGYuY2FjaGVbYWJzXSA9ICdGSUxFJ1xuICAgICAgY2IoKVxuICAgIH0gZWxzZVxuICAgICAgc2VsZi5fcmVhZGRpcihhYnMsIGZhbHNlLCBjYilcbiAgfVxufVxuXG5HbG9iLnByb3RvdHlwZS5fcmVhZGRpciA9IGZ1bmN0aW9uIChhYnMsIGluR2xvYlN0YXIsIGNiKSB7XG4gIGlmICh0aGlzLmFib3J0ZWQpXG4gICAgcmV0dXJuXG5cbiAgY2IgPSBpbmZsaWdodCgncmVhZGRpclxcMCcrYWJzKydcXDAnK2luR2xvYlN0YXIsIGNiKVxuICBpZiAoIWNiKVxuICAgIHJldHVyblxuXG4gIC8vY29uc29sZS5lcnJvcignUkQgJWogJWonLCAraW5HbG9iU3RhciwgYWJzKVxuICBpZiAoaW5HbG9iU3RhciAmJiAhb3duUHJvcCh0aGlzLnN5bWxpbmtzLCBhYnMpKVxuICAgIHJldHVybiB0aGlzLl9yZWFkZGlySW5HbG9iU3RhcihhYnMsIGNiKVxuXG4gIGlmIChvd25Qcm9wKHRoaXMuY2FjaGUsIGFicykpIHtcbiAgICB2YXIgYyA9IHRoaXMuY2FjaGVbYWJzXVxuICAgIGlmICghYyB8fCBjID09PSAnRklMRScpXG4gICAgICByZXR1cm4gY2IoKVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYykpXG4gICAgICByZXR1cm4gY2IobnVsbCwgYylcbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpc1xuICBmcy5yZWFkZGlyKGFicywgcmVhZGRpckNiKHRoaXMsIGFicywgY2IpKVxufVxuXG5mdW5jdGlvbiByZWFkZGlyQ2IgKHNlbGYsIGFicywgY2IpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChlciwgZW50cmllcykge1xuICAgIGlmIChlcilcbiAgICAgIHNlbGYuX3JlYWRkaXJFcnJvcihhYnMsIGVyLCBjYilcbiAgICBlbHNlXG4gICAgICBzZWxmLl9yZWFkZGlyRW50cmllcyhhYnMsIGVudHJpZXMsIGNiKVxuICB9XG59XG5cbkdsb2IucHJvdG90eXBlLl9yZWFkZGlyRW50cmllcyA9IGZ1bmN0aW9uIChhYnMsIGVudHJpZXMsIGNiKSB7XG4gIGlmICh0aGlzLmFib3J0ZWQpXG4gICAgcmV0dXJuXG5cbiAgLy8gaWYgd2UgaGF2ZW4ndCBhc2tlZCB0byBzdGF0IGV2ZXJ5dGhpbmcsIHRoZW4ganVzdFxuICAvLyBhc3N1bWUgdGhhdCBldmVyeXRoaW5nIGluIHRoZXJlIGV4aXN0cywgc28gd2UgY2FuIGF2b2lkXG4gIC8vIGhhdmluZyB0byBzdGF0IGl0IGEgc2Vjb25kIHRpbWUuXG4gIGlmICghdGhpcy5tYXJrICYmICF0aGlzLnN0YXQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVudHJpZXMubGVuZ3RoOyBpICsrKSB7XG4gICAgICB2YXIgZSA9IGVudHJpZXNbaV1cbiAgICAgIGlmIChhYnMgPT09ICcvJylcbiAgICAgICAgZSA9IGFicyArIGVcbiAgICAgIGVsc2VcbiAgICAgICAgZSA9IGFicyArICcvJyArIGVcbiAgICAgIHRoaXMuY2FjaGVbZV0gPSB0cnVlXG4gICAgfVxuICB9XG5cbiAgdGhpcy5jYWNoZVthYnNdID0gZW50cmllc1xuICByZXR1cm4gY2IobnVsbCwgZW50cmllcylcbn1cblxuR2xvYi5wcm90b3R5cGUuX3JlYWRkaXJFcnJvciA9IGZ1bmN0aW9uIChmLCBlciwgY2IpIHtcbiAgaWYgKHRoaXMuYWJvcnRlZClcbiAgICByZXR1cm5cblxuICAvLyBoYW5kbGUgZXJyb3JzLCBhbmQgY2FjaGUgdGhlIGluZm9ybWF0aW9uXG4gIHN3aXRjaCAoZXIuY29kZSkge1xuICAgIGNhc2UgJ0VOT1RTVVAnOiAvLyBodHRwczovL2dpdGh1Yi5jb20vaXNhYWNzL25vZGUtZ2xvYi9pc3N1ZXMvMjA1XG4gICAgY2FzZSAnRU5PVERJUic6IC8vIHRvdGFsbHkgbm9ybWFsLiBtZWFucyBpdCAqZG9lcyogZXhpc3QuXG4gICAgICB2YXIgYWJzID0gdGhpcy5fbWFrZUFicyhmKVxuICAgICAgdGhpcy5jYWNoZVthYnNdID0gJ0ZJTEUnXG4gICAgICBpZiAoYWJzID09PSB0aGlzLmN3ZEFicykge1xuICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoZXIuY29kZSArICcgaW52YWxpZCBjd2QgJyArIHRoaXMuY3dkKVxuICAgICAgICBlcnJvci5wYXRoID0gdGhpcy5jd2RcbiAgICAgICAgZXJyb3IuY29kZSA9IGVyLmNvZGVcbiAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKVxuICAgICAgICB0aGlzLmFib3J0KClcbiAgICAgIH1cbiAgICAgIGJyZWFrXG5cbiAgICBjYXNlICdFTk9FTlQnOiAvLyBub3QgdGVycmlibHkgdW51c3VhbFxuICAgIGNhc2UgJ0VMT09QJzpcbiAgICBjYXNlICdFTkFNRVRPT0xPTkcnOlxuICAgIGNhc2UgJ1VOS05PV04nOlxuICAgICAgdGhpcy5jYWNoZVt0aGlzLl9tYWtlQWJzKGYpXSA9IGZhbHNlXG4gICAgICBicmVha1xuXG4gICAgZGVmYXVsdDogLy8gc29tZSB1bnVzdWFsIGVycm9yLiAgVHJlYXQgYXMgZmFpbHVyZS5cbiAgICAgIHRoaXMuY2FjaGVbdGhpcy5fbWFrZUFicyhmKV0gPSBmYWxzZVxuICAgICAgaWYgKHRoaXMuc3RyaWN0KSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCBlcilcbiAgICAgICAgLy8gSWYgdGhlIGVycm9yIGlzIGhhbmRsZWQsIHRoZW4gd2UgYWJvcnRcbiAgICAgICAgLy8gaWYgbm90LCB3ZSB0aHJldyBvdXQgb2YgaGVyZVxuICAgICAgICB0aGlzLmFib3J0KClcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5zaWxlbnQpXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ2dsb2IgZXJyb3InLCBlcilcbiAgICAgIGJyZWFrXG4gIH1cblxuICByZXR1cm4gY2IoKVxufVxuXG5HbG9iLnByb3RvdHlwZS5fcHJvY2Vzc0dsb2JTdGFyID0gZnVuY3Rpb24gKHByZWZpeCwgcmVhZCwgYWJzLCByZW1haW4sIGluZGV4LCBpbkdsb2JTdGFyLCBjYikge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdGhpcy5fcmVhZGRpcihhYnMsIGluR2xvYlN0YXIsIGZ1bmN0aW9uIChlciwgZW50cmllcykge1xuICAgIHNlbGYuX3Byb2Nlc3NHbG9iU3RhcjIocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIsIGVudHJpZXMsIGNiKVxuICB9KVxufVxuXG5cbkdsb2IucHJvdG90eXBlLl9wcm9jZXNzR2xvYlN0YXIyID0gZnVuY3Rpb24gKHByZWZpeCwgcmVhZCwgYWJzLCByZW1haW4sIGluZGV4LCBpbkdsb2JTdGFyLCBlbnRyaWVzLCBjYikge1xuICAvL2NvbnNvbGUuZXJyb3IoJ3BnczInLCBwcmVmaXgsIHJlbWFpblswXSwgZW50cmllcylcblxuICAvLyBubyBlbnRyaWVzIG1lYW5zIG5vdCBhIGRpciwgc28gaXQgY2FuIG5ldmVyIGhhdmUgbWF0Y2hlc1xuICAvLyBmb28udHh0LyoqIGRvZXNuJ3QgbWF0Y2ggZm9vLnR4dFxuICBpZiAoIWVudHJpZXMpXG4gICAgcmV0dXJuIGNiKClcblxuICAvLyB0ZXN0IHdpdGhvdXQgdGhlIGdsb2JzdGFyLCBhbmQgd2l0aCBldmVyeSBjaGlsZCBib3RoIGJlbG93XG4gIC8vIGFuZCByZXBsYWNpbmcgdGhlIGdsb2JzdGFyLlxuICB2YXIgcmVtYWluV2l0aG91dEdsb2JTdGFyID0gcmVtYWluLnNsaWNlKDEpXG4gIHZhciBnc3ByZWYgPSBwcmVmaXggPyBbIHByZWZpeCBdIDogW11cbiAgdmFyIG5vR2xvYlN0YXIgPSBnc3ByZWYuY29uY2F0KHJlbWFpbldpdGhvdXRHbG9iU3RhcilcblxuICAvLyB0aGUgbm9HbG9iU3RhciBwYXR0ZXJuIGV4aXRzIHRoZSBpbkdsb2JTdGFyIHN0YXRlXG4gIHRoaXMuX3Byb2Nlc3Mobm9HbG9iU3RhciwgaW5kZXgsIGZhbHNlLCBjYilcblxuICB2YXIgaXNTeW0gPSB0aGlzLnN5bWxpbmtzW2Fic11cbiAgdmFyIGxlbiA9IGVudHJpZXMubGVuZ3RoXG5cbiAgLy8gSWYgaXQncyBhIHN5bWxpbmssIGFuZCB3ZSdyZSBpbiBhIGdsb2JzdGFyLCB0aGVuIHN0b3BcbiAgaWYgKGlzU3ltICYmIGluR2xvYlN0YXIpXG4gICAgcmV0dXJuIGNiKClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIGUgPSBlbnRyaWVzW2ldXG4gICAgaWYgKGUuY2hhckF0KDApID09PSAnLicgJiYgIXRoaXMuZG90KVxuICAgICAgY29udGludWVcblxuICAgIC8vIHRoZXNlIHR3byBjYXNlcyBlbnRlciB0aGUgaW5HbG9iU3RhciBzdGF0ZVxuICAgIHZhciBpbnN0ZWFkID0gZ3NwcmVmLmNvbmNhdChlbnRyaWVzW2ldLCByZW1haW5XaXRob3V0R2xvYlN0YXIpXG4gICAgdGhpcy5fcHJvY2VzcyhpbnN0ZWFkLCBpbmRleCwgdHJ1ZSwgY2IpXG5cbiAgICB2YXIgYmVsb3cgPSBnc3ByZWYuY29uY2F0KGVudHJpZXNbaV0sIHJlbWFpbilcbiAgICB0aGlzLl9wcm9jZXNzKGJlbG93LCBpbmRleCwgdHJ1ZSwgY2IpXG4gIH1cblxuICBjYigpXG59XG5cbkdsb2IucHJvdG90eXBlLl9wcm9jZXNzU2ltcGxlID0gZnVuY3Rpb24gKHByZWZpeCwgaW5kZXgsIGNiKSB7XG4gIC8vIFhYWCByZXZpZXcgdGhpcy4gIFNob3VsZG4ndCBpdCBiZSBkb2luZyB0aGUgbW91bnRpbmcgZXRjXG4gIC8vIGJlZm9yZSBkb2luZyBzdGF0PyAga2luZGEgd2VpcmQ/XG4gIHZhciBzZWxmID0gdGhpc1xuICB0aGlzLl9zdGF0KHByZWZpeCwgZnVuY3Rpb24gKGVyLCBleGlzdHMpIHtcbiAgICBzZWxmLl9wcm9jZXNzU2ltcGxlMihwcmVmaXgsIGluZGV4LCBlciwgZXhpc3RzLCBjYilcbiAgfSlcbn1cbkdsb2IucHJvdG90eXBlLl9wcm9jZXNzU2ltcGxlMiA9IGZ1bmN0aW9uIChwcmVmaXgsIGluZGV4LCBlciwgZXhpc3RzLCBjYikge1xuXG4gIC8vY29uc29sZS5lcnJvcigncHMyJywgcHJlZml4LCBleGlzdHMpXG5cbiAgaWYgKCF0aGlzLm1hdGNoZXNbaW5kZXhdKVxuICAgIHRoaXMubWF0Y2hlc1tpbmRleF0gPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgLy8gSWYgaXQgZG9lc24ndCBleGlzdCwgdGhlbiBqdXN0IG1hcmsgdGhlIGxhY2sgb2YgcmVzdWx0c1xuICBpZiAoIWV4aXN0cylcbiAgICByZXR1cm4gY2IoKVxuXG4gIGlmIChwcmVmaXggJiYgaXNBYnNvbHV0ZShwcmVmaXgpICYmICF0aGlzLm5vbW91bnQpIHtcbiAgICB2YXIgdHJhaWwgPSAvW1xcL1xcXFxdJC8udGVzdChwcmVmaXgpXG4gICAgaWYgKHByZWZpeC5jaGFyQXQoMCkgPT09ICcvJykge1xuICAgICAgcHJlZml4ID0gcGF0aC5qb2luKHRoaXMucm9vdCwgcHJlZml4KVxuICAgIH0gZWxzZSB7XG4gICAgICBwcmVmaXggPSBwYXRoLnJlc29sdmUodGhpcy5yb290LCBwcmVmaXgpXG4gICAgICBpZiAodHJhaWwpXG4gICAgICAgIHByZWZpeCArPSAnLydcbiAgICB9XG4gIH1cblxuICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJylcbiAgICBwcmVmaXggPSBwcmVmaXgucmVwbGFjZSgvXFxcXC9nLCAnLycpXG5cbiAgLy8gTWFyayB0aGlzIGFzIGEgbWF0Y2hcbiAgdGhpcy5fZW1pdE1hdGNoKGluZGV4LCBwcmVmaXgpXG4gIGNiKClcbn1cblxuLy8gUmV0dXJucyBlaXRoZXIgJ0RJUicsICdGSUxFJywgb3IgZmFsc2Vcbkdsb2IucHJvdG90eXBlLl9zdGF0ID0gZnVuY3Rpb24gKGYsIGNiKSB7XG4gIHZhciBhYnMgPSB0aGlzLl9tYWtlQWJzKGYpXG4gIHZhciBuZWVkRGlyID0gZi5zbGljZSgtMSkgPT09ICcvJ1xuXG4gIGlmIChmLmxlbmd0aCA+IHRoaXMubWF4TGVuZ3RoKVxuICAgIHJldHVybiBjYigpXG5cbiAgaWYgKCF0aGlzLnN0YXQgJiYgb3duUHJvcCh0aGlzLmNhY2hlLCBhYnMpKSB7XG4gICAgdmFyIGMgPSB0aGlzLmNhY2hlW2Fic11cblxuICAgIGlmIChBcnJheS5pc0FycmF5KGMpKVxuICAgICAgYyA9ICdESVInXG5cbiAgICAvLyBJdCBleGlzdHMsIGJ1dCBtYXliZSBub3QgaG93IHdlIG5lZWQgaXRcbiAgICBpZiAoIW5lZWREaXIgfHwgYyA9PT0gJ0RJUicpXG4gICAgICByZXR1cm4gY2IobnVsbCwgYylcblxuICAgIGlmIChuZWVkRGlyICYmIGMgPT09ICdGSUxFJylcbiAgICAgIHJldHVybiBjYigpXG5cbiAgICAvLyBvdGhlcndpc2Ugd2UgaGF2ZSB0byBzdGF0LCBiZWNhdXNlIG1heWJlIGM9dHJ1ZVxuICAgIC8vIGlmIHdlIGtub3cgaXQgZXhpc3RzLCBidXQgbm90IHdoYXQgaXQgaXMuXG4gIH1cblxuICB2YXIgZXhpc3RzXG4gIHZhciBzdGF0ID0gdGhpcy5zdGF0Q2FjaGVbYWJzXVxuICBpZiAoc3RhdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHN0YXQgPT09IGZhbHNlKVxuICAgICAgcmV0dXJuIGNiKG51bGwsIHN0YXQpXG4gICAgZWxzZSB7XG4gICAgICB2YXIgdHlwZSA9IHN0YXQuaXNEaXJlY3RvcnkoKSA/ICdESVInIDogJ0ZJTEUnXG4gICAgICBpZiAobmVlZERpciAmJiB0eXBlID09PSAnRklMRScpXG4gICAgICAgIHJldHVybiBjYigpXG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiBjYihudWxsLCB0eXBlLCBzdGF0KVxuICAgIH1cbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgc3RhdGNiID0gaW5mbGlnaHQoJ3N0YXRcXDAnICsgYWJzLCBsc3RhdGNiXylcbiAgaWYgKHN0YXRjYilcbiAgICBmcy5sc3RhdChhYnMsIHN0YXRjYilcblxuICBmdW5jdGlvbiBsc3RhdGNiXyAoZXIsIGxzdGF0KSB7XG4gICAgaWYgKGxzdGF0ICYmIGxzdGF0LmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgIC8vIElmIGl0J3MgYSBzeW1saW5rLCB0aGVuIHRyZWF0IGl0IGFzIHRoZSB0YXJnZXQsIHVubGVzc1xuICAgICAgLy8gdGhlIHRhcmdldCBkb2VzIG5vdCBleGlzdCwgdGhlbiB0cmVhdCBpdCBhcyBhIGZpbGUuXG4gICAgICByZXR1cm4gZnMuc3RhdChhYnMsIGZ1bmN0aW9uIChlciwgc3RhdCkge1xuICAgICAgICBpZiAoZXIpXG4gICAgICAgICAgc2VsZi5fc3RhdDIoZiwgYWJzLCBudWxsLCBsc3RhdCwgY2IpXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzZWxmLl9zdGF0MihmLCBhYnMsIGVyLCBzdGF0LCBjYilcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGYuX3N0YXQyKGYsIGFicywgZXIsIGxzdGF0LCBjYilcbiAgICB9XG4gIH1cbn1cblxuR2xvYi5wcm90b3R5cGUuX3N0YXQyID0gZnVuY3Rpb24gKGYsIGFicywgZXIsIHN0YXQsIGNiKSB7XG4gIGlmIChlciAmJiAoZXIuY29kZSA9PT0gJ0VOT0VOVCcgfHwgZXIuY29kZSA9PT0gJ0VOT1RESVInKSkge1xuICAgIHRoaXMuc3RhdENhY2hlW2Fic10gPSBmYWxzZVxuICAgIHJldHVybiBjYigpXG4gIH1cblxuICB2YXIgbmVlZERpciA9IGYuc2xpY2UoLTEpID09PSAnLydcbiAgdGhpcy5zdGF0Q2FjaGVbYWJzXSA9IHN0YXRcblxuICBpZiAoYWJzLnNsaWNlKC0xKSA9PT0gJy8nICYmIHN0YXQgJiYgIXN0YXQuaXNEaXJlY3RvcnkoKSlcbiAgICByZXR1cm4gY2IobnVsbCwgZmFsc2UsIHN0YXQpXG5cbiAgdmFyIGMgPSB0cnVlXG4gIGlmIChzdGF0KVxuICAgIGMgPSBzdGF0LmlzRGlyZWN0b3J5KCkgPyAnRElSJyA6ICdGSUxFJ1xuICB0aGlzLmNhY2hlW2Fic10gPSB0aGlzLmNhY2hlW2Fic10gfHwgY1xuXG4gIGlmIChuZWVkRGlyICYmIGMgPT09ICdGSUxFJylcbiAgICByZXR1cm4gY2IoKVxuXG4gIHJldHVybiBjYihudWxsLCBjLCBzdGF0KVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBnbG9iU3luY1xuZ2xvYlN5bmMuR2xvYlN5bmMgPSBHbG9iU3luY1xuXG52YXIgZnMgPSByZXF1aXJlKCdmcycpXG52YXIgcnAgPSByZXF1aXJlKCdmcy5yZWFscGF0aCcpXG52YXIgbWluaW1hdGNoID0gcmVxdWlyZSgnbWluaW1hdGNoJylcbnZhciBNaW5pbWF0Y2ggPSBtaW5pbWF0Y2guTWluaW1hdGNoXG52YXIgR2xvYiA9IHJlcXVpcmUoJy4vZ2xvYi5qcycpLkdsb2JcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpXG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKVxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpXG52YXIgaXNBYnNvbHV0ZSA9IHJlcXVpcmUoJ3BhdGgtaXMtYWJzb2x1dGUnKVxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uLmpzJylcbnZhciBhbHBoYXNvcnQgPSBjb21tb24uYWxwaGFzb3J0XG52YXIgYWxwaGFzb3J0aSA9IGNvbW1vbi5hbHBoYXNvcnRpXG52YXIgc2V0b3B0cyA9IGNvbW1vbi5zZXRvcHRzXG52YXIgb3duUHJvcCA9IGNvbW1vbi5vd25Qcm9wXG52YXIgY2hpbGRyZW5JZ25vcmVkID0gY29tbW9uLmNoaWxkcmVuSWdub3JlZFxudmFyIGlzSWdub3JlZCA9IGNvbW1vbi5pc0lnbm9yZWRcblxuZnVuY3Rpb24gZ2xvYlN5bmMgKHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDMpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignY2FsbGJhY2sgcHJvdmlkZWQgdG8gc3luYyBnbG9iXFxuJytcbiAgICAgICAgICAgICAgICAgICAgICAgICdTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9pc2FhY3Mvbm9kZS1nbG9iL2lzc3Vlcy8xNjcnKVxuXG4gIHJldHVybiBuZXcgR2xvYlN5bmMocGF0dGVybiwgb3B0aW9ucykuZm91bmRcbn1cblxuZnVuY3Rpb24gR2xvYlN5bmMgKHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgaWYgKCFwYXR0ZXJuKVxuICAgIHRocm93IG5ldyBFcnJvcignbXVzdCBwcm92aWRlIHBhdHRlcm4nKVxuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJyB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAzKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NhbGxiYWNrIHByb3ZpZGVkIHRvIHN5bmMgZ2xvYlxcbicrXG4gICAgICAgICAgICAgICAgICAgICAgICAnU2VlOiBodHRwczovL2dpdGh1Yi5jb20vaXNhYWNzL25vZGUtZ2xvYi9pc3N1ZXMvMTY3JylcblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgR2xvYlN5bmMpKVxuICAgIHJldHVybiBuZXcgR2xvYlN5bmMocGF0dGVybiwgb3B0aW9ucylcblxuICBzZXRvcHRzKHRoaXMsIHBhdHRlcm4sIG9wdGlvbnMpXG5cbiAgaWYgKHRoaXMubm9wcm9jZXNzKVxuICAgIHJldHVybiB0aGlzXG5cbiAgdmFyIG4gPSB0aGlzLm1pbmltYXRjaC5zZXQubGVuZ3RoXG4gIHRoaXMubWF0Y2hlcyA9IG5ldyBBcnJheShuKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IG47IGkgKyspIHtcbiAgICB0aGlzLl9wcm9jZXNzKHRoaXMubWluaW1hdGNoLnNldFtpXSwgaSwgZmFsc2UpXG4gIH1cbiAgdGhpcy5fZmluaXNoKClcbn1cblxuR2xvYlN5bmMucHJvdG90eXBlLl9maW5pc2ggPSBmdW5jdGlvbiAoKSB7XG4gIGFzc2VydCh0aGlzIGluc3RhbmNlb2YgR2xvYlN5bmMpXG4gIGlmICh0aGlzLnJlYWxwYXRoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzXG4gICAgdGhpcy5tYXRjaGVzLmZvckVhY2goZnVuY3Rpb24gKG1hdGNoc2V0LCBpbmRleCkge1xuICAgICAgdmFyIHNldCA9IHNlbGYubWF0Y2hlc1tpbmRleF0gPSBPYmplY3QuY3JlYXRlKG51bGwpXG4gICAgICBmb3IgKHZhciBwIGluIG1hdGNoc2V0KSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcCA9IHNlbGYuX21ha2VBYnMocClcbiAgICAgICAgICB2YXIgcmVhbCA9IHJwLnJlYWxwYXRoU3luYyhwLCBzZWxmLnJlYWxwYXRoQ2FjaGUpXG4gICAgICAgICAgc2V0W3JlYWxdID0gdHJ1ZVxuICAgICAgICB9IGNhdGNoIChlcikge1xuICAgICAgICAgIGlmIChlci5zeXNjYWxsID09PSAnc3RhdCcpXG4gICAgICAgICAgICBzZXRbc2VsZi5fbWFrZUFicyhwKV0gPSB0cnVlXG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgZXJcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gIH1cbiAgY29tbW9uLmZpbmlzaCh0aGlzKVxufVxuXG5cbkdsb2JTeW5jLnByb3RvdHlwZS5fcHJvY2VzcyA9IGZ1bmN0aW9uIChwYXR0ZXJuLCBpbmRleCwgaW5HbG9iU3Rhcikge1xuICBhc3NlcnQodGhpcyBpbnN0YW5jZW9mIEdsb2JTeW5jKVxuXG4gIC8vIEdldCB0aGUgZmlyc3QgW25dIHBhcnRzIG9mIHBhdHRlcm4gdGhhdCBhcmUgYWxsIHN0cmluZ3MuXG4gIHZhciBuID0gMFxuICB3aGlsZSAodHlwZW9mIHBhdHRlcm5bbl0gPT09ICdzdHJpbmcnKSB7XG4gICAgbiArK1xuICB9XG4gIC8vIG5vdyBuIGlzIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb25lIHRoYXQgaXMgKm5vdCogYSBzdHJpbmcuXG5cbiAgLy8gU2VlIGlmIHRoZXJlJ3MgYW55dGhpbmcgZWxzZVxuICB2YXIgcHJlZml4XG4gIHN3aXRjaCAobikge1xuICAgIC8vIGlmIG5vdCwgdGhlbiB0aGlzIGlzIHJhdGhlciBzaW1wbGVcbiAgICBjYXNlIHBhdHRlcm4ubGVuZ3RoOlxuICAgICAgdGhpcy5fcHJvY2Vzc1NpbXBsZShwYXR0ZXJuLmpvaW4oJy8nKSwgaW5kZXgpXG4gICAgICByZXR1cm5cblxuICAgIGNhc2UgMDpcbiAgICAgIC8vIHBhdHRlcm4gKnN0YXJ0cyogd2l0aCBzb21lIG5vbi10cml2aWFsIGl0ZW0uXG4gICAgICAvLyBnb2luZyB0byByZWFkZGlyKGN3ZCksIGJ1dCBub3QgaW5jbHVkZSB0aGUgcHJlZml4IGluIG1hdGNoZXMuXG4gICAgICBwcmVmaXggPSBudWxsXG4gICAgICBicmVha1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIHBhdHRlcm4gaGFzIHNvbWUgc3RyaW5nIGJpdHMgaW4gdGhlIGZyb250LlxuICAgICAgLy8gd2hhdGV2ZXIgaXQgc3RhcnRzIHdpdGgsIHdoZXRoZXIgdGhhdCdzICdhYnNvbHV0ZScgbGlrZSAvZm9vL2JhcixcbiAgICAgIC8vIG9yICdyZWxhdGl2ZScgbGlrZSAnLi4vYmF6J1xuICAgICAgcHJlZml4ID0gcGF0dGVybi5zbGljZSgwLCBuKS5qb2luKCcvJylcbiAgICAgIGJyZWFrXG4gIH1cblxuICB2YXIgcmVtYWluID0gcGF0dGVybi5zbGljZShuKVxuXG4gIC8vIGdldCB0aGUgbGlzdCBvZiBlbnRyaWVzLlxuICB2YXIgcmVhZFxuICBpZiAocHJlZml4ID09PSBudWxsKVxuICAgIHJlYWQgPSAnLidcbiAgZWxzZSBpZiAoaXNBYnNvbHV0ZShwcmVmaXgpIHx8IGlzQWJzb2x1dGUocGF0dGVybi5qb2luKCcvJykpKSB7XG4gICAgaWYgKCFwcmVmaXggfHwgIWlzQWJzb2x1dGUocHJlZml4KSlcbiAgICAgIHByZWZpeCA9ICcvJyArIHByZWZpeFxuICAgIHJlYWQgPSBwcmVmaXhcbiAgfSBlbHNlXG4gICAgcmVhZCA9IHByZWZpeFxuXG4gIHZhciBhYnMgPSB0aGlzLl9tYWtlQWJzKHJlYWQpXG5cbiAgLy9pZiBpZ25vcmVkLCBza2lwIHByb2Nlc3NpbmdcbiAgaWYgKGNoaWxkcmVuSWdub3JlZCh0aGlzLCByZWFkKSlcbiAgICByZXR1cm5cblxuICB2YXIgaXNHbG9iU3RhciA9IHJlbWFpblswXSA9PT0gbWluaW1hdGNoLkdMT0JTVEFSXG4gIGlmIChpc0dsb2JTdGFyKVxuICAgIHRoaXMuX3Byb2Nlc3NHbG9iU3RhcihwcmVmaXgsIHJlYWQsIGFicywgcmVtYWluLCBpbmRleCwgaW5HbG9iU3RhcilcbiAgZWxzZVxuICAgIHRoaXMuX3Byb2Nlc3NSZWFkZGlyKHByZWZpeCwgcmVhZCwgYWJzLCByZW1haW4sIGluZGV4LCBpbkdsb2JTdGFyKVxufVxuXG5cbkdsb2JTeW5jLnByb3RvdHlwZS5fcHJvY2Vzc1JlYWRkaXIgPSBmdW5jdGlvbiAocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIpIHtcbiAgdmFyIGVudHJpZXMgPSB0aGlzLl9yZWFkZGlyKGFicywgaW5HbG9iU3RhcilcblxuICAvLyBpZiB0aGUgYWJzIGlzbid0IGEgZGlyLCB0aGVuIG5vdGhpbmcgY2FuIG1hdGNoIVxuICBpZiAoIWVudHJpZXMpXG4gICAgcmV0dXJuXG5cbiAgLy8gSXQgd2lsbCBvbmx5IG1hdGNoIGRvdCBlbnRyaWVzIGlmIGl0IHN0YXJ0cyB3aXRoIGEgZG90LCBvciBpZlxuICAvLyBkb3QgaXMgc2V0LiAgU3R1ZmYgbGlrZSBAKC5mb298LmJhcikgaXNuJ3QgYWxsb3dlZC5cbiAgdmFyIHBuID0gcmVtYWluWzBdXG4gIHZhciBuZWdhdGUgPSAhIXRoaXMubWluaW1hdGNoLm5lZ2F0ZVxuICB2YXIgcmF3R2xvYiA9IHBuLl9nbG9iXG4gIHZhciBkb3RPayA9IHRoaXMuZG90IHx8IHJhd0dsb2IuY2hhckF0KDApID09PSAnLidcblxuICB2YXIgbWF0Y2hlZEVudHJpZXMgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGVudHJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZSA9IGVudHJpZXNbaV1cbiAgICBpZiAoZS5jaGFyQXQoMCkgIT09ICcuJyB8fCBkb3RPaykge1xuICAgICAgdmFyIG1cbiAgICAgIGlmIChuZWdhdGUgJiYgIXByZWZpeCkge1xuICAgICAgICBtID0gIWUubWF0Y2gocG4pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtID0gZS5tYXRjaChwbilcbiAgICAgIH1cbiAgICAgIGlmIChtKVxuICAgICAgICBtYXRjaGVkRW50cmllcy5wdXNoKGUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGxlbiA9IG1hdGNoZWRFbnRyaWVzLmxlbmd0aFxuICAvLyBJZiB0aGVyZSBhcmUgbm8gbWF0Y2hlZCBlbnRyaWVzLCB0aGVuIG5vdGhpbmcgbWF0Y2hlcy5cbiAgaWYgKGxlbiA9PT0gMClcbiAgICByZXR1cm5cblxuICAvLyBpZiB0aGlzIGlzIHRoZSBsYXN0IHJlbWFpbmluZyBwYXR0ZXJuIGJpdCwgdGhlbiBubyBuZWVkIGZvclxuICAvLyBhbiBhZGRpdGlvbmFsIHN0YXQgKnVubGVzcyogdGhlIHVzZXIgaGFzIHNwZWNpZmllZCBtYXJrIG9yXG4gIC8vIHN0YXQgZXhwbGljaXRseS4gIFdlIGtub3cgdGhleSBleGlzdCwgc2luY2UgcmVhZGRpciByZXR1cm5lZFxuICAvLyB0aGVtLlxuXG4gIGlmIChyZW1haW4ubGVuZ3RoID09PSAxICYmICF0aGlzLm1hcmsgJiYgIXRoaXMuc3RhdCkge1xuICAgIGlmICghdGhpcy5tYXRjaGVzW2luZGV4XSlcbiAgICAgIHRoaXMubWF0Y2hlc1tpbmRleF0gPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArKykge1xuICAgICAgdmFyIGUgPSBtYXRjaGVkRW50cmllc1tpXVxuICAgICAgaWYgKHByZWZpeCkge1xuICAgICAgICBpZiAocHJlZml4LnNsaWNlKC0xKSAhPT0gJy8nKVxuICAgICAgICAgIGUgPSBwcmVmaXggKyAnLycgKyBlXG4gICAgICAgIGVsc2VcbiAgICAgICAgICBlID0gcHJlZml4ICsgZVxuICAgICAgfVxuXG4gICAgICBpZiAoZS5jaGFyQXQoMCkgPT09ICcvJyAmJiAhdGhpcy5ub21vdW50KSB7XG4gICAgICAgIGUgPSBwYXRoLmpvaW4odGhpcy5yb290LCBlKVxuICAgICAgfVxuICAgICAgdGhpcy5fZW1pdE1hdGNoKGluZGV4LCBlKVxuICAgIH1cbiAgICAvLyBUaGlzIHdhcyB0aGUgbGFzdCBvbmUsIGFuZCBubyBzdGF0cyB3ZXJlIG5lZWRlZFxuICAgIHJldHVyblxuICB9XG5cbiAgLy8gbm93IHRlc3QgYWxsIG1hdGNoZWQgZW50cmllcyBhcyBzdGFuZC1pbnMgZm9yIHRoYXQgcGFydFxuICAvLyBvZiB0aGUgcGF0dGVybi5cbiAgcmVtYWluLnNoaWZ0KClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKyspIHtcbiAgICB2YXIgZSA9IG1hdGNoZWRFbnRyaWVzW2ldXG4gICAgdmFyIG5ld1BhdHRlcm5cbiAgICBpZiAocHJlZml4KVxuICAgICAgbmV3UGF0dGVybiA9IFtwcmVmaXgsIGVdXG4gICAgZWxzZVxuICAgICAgbmV3UGF0dGVybiA9IFtlXVxuICAgIHRoaXMuX3Byb2Nlc3MobmV3UGF0dGVybi5jb25jYXQocmVtYWluKSwgaW5kZXgsIGluR2xvYlN0YXIpXG4gIH1cbn1cblxuXG5HbG9iU3luYy5wcm90b3R5cGUuX2VtaXRNYXRjaCA9IGZ1bmN0aW9uIChpbmRleCwgZSkge1xuICBpZiAoaXNJZ25vcmVkKHRoaXMsIGUpKVxuICAgIHJldHVyblxuXG4gIHZhciBhYnMgPSB0aGlzLl9tYWtlQWJzKGUpXG5cbiAgaWYgKHRoaXMubWFyaylcbiAgICBlID0gdGhpcy5fbWFyayhlKVxuXG4gIGlmICh0aGlzLmFic29sdXRlKSB7XG4gICAgZSA9IGFic1xuICB9XG5cbiAgaWYgKHRoaXMubWF0Y2hlc1tpbmRleF1bZV0pXG4gICAgcmV0dXJuXG5cbiAgaWYgKHRoaXMubm9kaXIpIHtcbiAgICB2YXIgYyA9IHRoaXMuY2FjaGVbYWJzXVxuICAgIGlmIChjID09PSAnRElSJyB8fCBBcnJheS5pc0FycmF5KGMpKVxuICAgICAgcmV0dXJuXG4gIH1cblxuICB0aGlzLm1hdGNoZXNbaW5kZXhdW2VdID0gdHJ1ZVxuXG4gIGlmICh0aGlzLnN0YXQpXG4gICAgdGhpcy5fc3RhdChlKVxufVxuXG5cbkdsb2JTeW5jLnByb3RvdHlwZS5fcmVhZGRpckluR2xvYlN0YXIgPSBmdW5jdGlvbiAoYWJzKSB7XG4gIC8vIGZvbGxvdyBhbGwgc3ltbGlua2VkIGRpcmVjdG9yaWVzIGZvcmV2ZXJcbiAgLy8ganVzdCBwcm9jZWVkIGFzIGlmIHRoaXMgaXMgYSBub24tZ2xvYnN0YXIgc2l0dWF0aW9uXG4gIGlmICh0aGlzLmZvbGxvdylcbiAgICByZXR1cm4gdGhpcy5fcmVhZGRpcihhYnMsIGZhbHNlKVxuXG4gIHZhciBlbnRyaWVzXG4gIHZhciBsc3RhdFxuICB2YXIgc3RhdFxuICB0cnkge1xuICAgIGxzdGF0ID0gZnMubHN0YXRTeW5jKGFicylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICBpZiAoZXIuY29kZSA9PT0gJ0VOT0VOVCcpIHtcbiAgICAgIC8vIGxzdGF0IGZhaWxlZCwgZG9lc24ndCBleGlzdFxuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gIH1cblxuICB2YXIgaXNTeW0gPSBsc3RhdCAmJiBsc3RhdC5pc1N5bWJvbGljTGluaygpXG4gIHRoaXMuc3ltbGlua3NbYWJzXSA9IGlzU3ltXG5cbiAgLy8gSWYgaXQncyBub3QgYSBzeW1saW5rIG9yIGEgZGlyLCB0aGVuIGl0J3MgZGVmaW5pdGVseSBhIHJlZ3VsYXIgZmlsZS5cbiAgLy8gZG9uJ3QgYm90aGVyIGRvaW5nIGEgcmVhZGRpciBpbiB0aGF0IGNhc2UuXG4gIGlmICghaXNTeW0gJiYgbHN0YXQgJiYgIWxzdGF0LmlzRGlyZWN0b3J5KCkpXG4gICAgdGhpcy5jYWNoZVthYnNdID0gJ0ZJTEUnXG4gIGVsc2VcbiAgICBlbnRyaWVzID0gdGhpcy5fcmVhZGRpcihhYnMsIGZhbHNlKVxuXG4gIHJldHVybiBlbnRyaWVzXG59XG5cbkdsb2JTeW5jLnByb3RvdHlwZS5fcmVhZGRpciA9IGZ1bmN0aW9uIChhYnMsIGluR2xvYlN0YXIpIHtcbiAgdmFyIGVudHJpZXNcblxuICBpZiAoaW5HbG9iU3RhciAmJiAhb3duUHJvcCh0aGlzLnN5bWxpbmtzLCBhYnMpKVxuICAgIHJldHVybiB0aGlzLl9yZWFkZGlySW5HbG9iU3RhcihhYnMpXG5cbiAgaWYgKG93blByb3AodGhpcy5jYWNoZSwgYWJzKSkge1xuICAgIHZhciBjID0gdGhpcy5jYWNoZVthYnNdXG4gICAgaWYgKCFjIHx8IGMgPT09ICdGSUxFJylcbiAgICAgIHJldHVybiBudWxsXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShjKSlcbiAgICAgIHJldHVybiBjXG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiB0aGlzLl9yZWFkZGlyRW50cmllcyhhYnMsIGZzLnJlYWRkaXJTeW5jKGFicykpXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgdGhpcy5fcmVhZGRpckVycm9yKGFicywgZXIpXG4gICAgcmV0dXJuIG51bGxcbiAgfVxufVxuXG5HbG9iU3luYy5wcm90b3R5cGUuX3JlYWRkaXJFbnRyaWVzID0gZnVuY3Rpb24gKGFicywgZW50cmllcykge1xuICAvLyBpZiB3ZSBoYXZlbid0IGFza2VkIHRvIHN0YXQgZXZlcnl0aGluZywgdGhlbiBqdXN0XG4gIC8vIGFzc3VtZSB0aGF0IGV2ZXJ5dGhpbmcgaW4gdGhlcmUgZXhpc3RzLCBzbyB3ZSBjYW4gYXZvaWRcbiAgLy8gaGF2aW5nIHRvIHN0YXQgaXQgYSBzZWNvbmQgdGltZS5cbiAgaWYgKCF0aGlzLm1hcmsgJiYgIXRoaXMuc3RhdCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkgKyspIHtcbiAgICAgIHZhciBlID0gZW50cmllc1tpXVxuICAgICAgaWYgKGFicyA9PT0gJy8nKVxuICAgICAgICBlID0gYWJzICsgZVxuICAgICAgZWxzZVxuICAgICAgICBlID0gYWJzICsgJy8nICsgZVxuICAgICAgdGhpcy5jYWNoZVtlXSA9IHRydWVcbiAgICB9XG4gIH1cblxuICB0aGlzLmNhY2hlW2Fic10gPSBlbnRyaWVzXG5cbiAgLy8gbWFyayBhbmQgY2FjaGUgZGlyLW5lc3NcbiAgcmV0dXJuIGVudHJpZXNcbn1cblxuR2xvYlN5bmMucHJvdG90eXBlLl9yZWFkZGlyRXJyb3IgPSBmdW5jdGlvbiAoZiwgZXIpIHtcbiAgLy8gaGFuZGxlIGVycm9ycywgYW5kIGNhY2hlIHRoZSBpbmZvcm1hdGlvblxuICBzd2l0Y2ggKGVyLmNvZGUpIHtcbiAgICBjYXNlICdFTk9UU1VQJzogLy8gaHR0cHM6Ly9naXRodWIuY29tL2lzYWFjcy9ub2RlLWdsb2IvaXNzdWVzLzIwNVxuICAgIGNhc2UgJ0VOT1RESVInOiAvLyB0b3RhbGx5IG5vcm1hbC4gbWVhbnMgaXQgKmRvZXMqIGV4aXN0LlxuICAgICAgdmFyIGFicyA9IHRoaXMuX21ha2VBYnMoZilcbiAgICAgIHRoaXMuY2FjaGVbYWJzXSA9ICdGSUxFJ1xuICAgICAgaWYgKGFicyA9PT0gdGhpcy5jd2RBYnMpIHtcbiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKGVyLmNvZGUgKyAnIGludmFsaWQgY3dkICcgKyB0aGlzLmN3ZClcbiAgICAgICAgZXJyb3IucGF0aCA9IHRoaXMuY3dkXG4gICAgICAgIGVycm9yLmNvZGUgPSBlci5jb2RlXG4gICAgICAgIHRocm93IGVycm9yXG4gICAgICB9XG4gICAgICBicmVha1xuXG4gICAgY2FzZSAnRU5PRU5UJzogLy8gbm90IHRlcnJpYmx5IHVudXN1YWxcbiAgICBjYXNlICdFTE9PUCc6XG4gICAgY2FzZSAnRU5BTUVUT09MT05HJzpcbiAgICBjYXNlICdVTktOT1dOJzpcbiAgICAgIHRoaXMuY2FjaGVbdGhpcy5fbWFrZUFicyhmKV0gPSBmYWxzZVxuICAgICAgYnJlYWtcblxuICAgIGRlZmF1bHQ6IC8vIHNvbWUgdW51c3VhbCBlcnJvci4gIFRyZWF0IGFzIGZhaWx1cmUuXG4gICAgICB0aGlzLmNhY2hlW3RoaXMuX21ha2VBYnMoZildID0gZmFsc2VcbiAgICAgIGlmICh0aGlzLnN0cmljdClcbiAgICAgICAgdGhyb3cgZXJcbiAgICAgIGlmICghdGhpcy5zaWxlbnQpXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ2dsb2IgZXJyb3InLCBlcilcbiAgICAgIGJyZWFrXG4gIH1cbn1cblxuR2xvYlN5bmMucHJvdG90eXBlLl9wcm9jZXNzR2xvYlN0YXIgPSBmdW5jdGlvbiAocHJlZml4LCByZWFkLCBhYnMsIHJlbWFpbiwgaW5kZXgsIGluR2xvYlN0YXIpIHtcblxuICB2YXIgZW50cmllcyA9IHRoaXMuX3JlYWRkaXIoYWJzLCBpbkdsb2JTdGFyKVxuXG4gIC8vIG5vIGVudHJpZXMgbWVhbnMgbm90IGEgZGlyLCBzbyBpdCBjYW4gbmV2ZXIgaGF2ZSBtYXRjaGVzXG4gIC8vIGZvby50eHQvKiogZG9lc24ndCBtYXRjaCBmb28udHh0XG4gIGlmICghZW50cmllcylcbiAgICByZXR1cm5cblxuICAvLyB0ZXN0IHdpdGhvdXQgdGhlIGdsb2JzdGFyLCBhbmQgd2l0aCBldmVyeSBjaGlsZCBib3RoIGJlbG93XG4gIC8vIGFuZCByZXBsYWNpbmcgdGhlIGdsb2JzdGFyLlxuICB2YXIgcmVtYWluV2l0aG91dEdsb2JTdGFyID0gcmVtYWluLnNsaWNlKDEpXG4gIHZhciBnc3ByZWYgPSBwcmVmaXggPyBbIHByZWZpeCBdIDogW11cbiAgdmFyIG5vR2xvYlN0YXIgPSBnc3ByZWYuY29uY2F0KHJlbWFpbldpdGhvdXRHbG9iU3RhcilcblxuICAvLyB0aGUgbm9HbG9iU3RhciBwYXR0ZXJuIGV4aXRzIHRoZSBpbkdsb2JTdGFyIHN0YXRlXG4gIHRoaXMuX3Byb2Nlc3Mobm9HbG9iU3RhciwgaW5kZXgsIGZhbHNlKVxuXG4gIHZhciBsZW4gPSBlbnRyaWVzLmxlbmd0aFxuICB2YXIgaXNTeW0gPSB0aGlzLnN5bWxpbmtzW2Fic11cblxuICAvLyBJZiBpdCdzIGEgc3ltbGluaywgYW5kIHdlJ3JlIGluIGEgZ2xvYnN0YXIsIHRoZW4gc3RvcFxuICBpZiAoaXNTeW0gJiYgaW5HbG9iU3RhcilcbiAgICByZXR1cm5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIGUgPSBlbnRyaWVzW2ldXG4gICAgaWYgKGUuY2hhckF0KDApID09PSAnLicgJiYgIXRoaXMuZG90KVxuICAgICAgY29udGludWVcblxuICAgIC8vIHRoZXNlIHR3byBjYXNlcyBlbnRlciB0aGUgaW5HbG9iU3RhciBzdGF0ZVxuICAgIHZhciBpbnN0ZWFkID0gZ3NwcmVmLmNvbmNhdChlbnRyaWVzW2ldLCByZW1haW5XaXRob3V0R2xvYlN0YXIpXG4gICAgdGhpcy5fcHJvY2VzcyhpbnN0ZWFkLCBpbmRleCwgdHJ1ZSlcblxuICAgIHZhciBiZWxvdyA9IGdzcHJlZi5jb25jYXQoZW50cmllc1tpXSwgcmVtYWluKVxuICAgIHRoaXMuX3Byb2Nlc3MoYmVsb3csIGluZGV4LCB0cnVlKVxuICB9XG59XG5cbkdsb2JTeW5jLnByb3RvdHlwZS5fcHJvY2Vzc1NpbXBsZSA9IGZ1bmN0aW9uIChwcmVmaXgsIGluZGV4KSB7XG4gIC8vIFhYWCByZXZpZXcgdGhpcy4gIFNob3VsZG4ndCBpdCBiZSBkb2luZyB0aGUgbW91bnRpbmcgZXRjXG4gIC8vIGJlZm9yZSBkb2luZyBzdGF0PyAga2luZGEgd2VpcmQ/XG4gIHZhciBleGlzdHMgPSB0aGlzLl9zdGF0KHByZWZpeClcblxuICBpZiAoIXRoaXMubWF0Y2hlc1tpbmRleF0pXG4gICAgdGhpcy5tYXRjaGVzW2luZGV4XSA9IE9iamVjdC5jcmVhdGUobnVsbClcblxuICAvLyBJZiBpdCBkb2Vzbid0IGV4aXN0LCB0aGVuIGp1c3QgbWFyayB0aGUgbGFjayBvZiByZXN1bHRzXG4gIGlmICghZXhpc3RzKVxuICAgIHJldHVyblxuXG4gIGlmIChwcmVmaXggJiYgaXNBYnNvbHV0ZShwcmVmaXgpICYmICF0aGlzLm5vbW91bnQpIHtcbiAgICB2YXIgdHJhaWwgPSAvW1xcL1xcXFxdJC8udGVzdChwcmVmaXgpXG4gICAgaWYgKHByZWZpeC5jaGFyQXQoMCkgPT09ICcvJykge1xuICAgICAgcHJlZml4ID0gcGF0aC5qb2luKHRoaXMucm9vdCwgcHJlZml4KVxuICAgIH0gZWxzZSB7XG4gICAgICBwcmVmaXggPSBwYXRoLnJlc29sdmUodGhpcy5yb290LCBwcmVmaXgpXG4gICAgICBpZiAodHJhaWwpXG4gICAgICAgIHByZWZpeCArPSAnLydcbiAgICB9XG4gIH1cblxuICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJylcbiAgICBwcmVmaXggPSBwcmVmaXgucmVwbGFjZSgvXFxcXC9nLCAnLycpXG5cbiAgLy8gTWFyayB0aGlzIGFzIGEgbWF0Y2hcbiAgdGhpcy5fZW1pdE1hdGNoKGluZGV4LCBwcmVmaXgpXG59XG5cbi8vIFJldHVybnMgZWl0aGVyICdESVInLCAnRklMRScsIG9yIGZhbHNlXG5HbG9iU3luYy5wcm90b3R5cGUuX3N0YXQgPSBmdW5jdGlvbiAoZikge1xuICB2YXIgYWJzID0gdGhpcy5fbWFrZUFicyhmKVxuICB2YXIgbmVlZERpciA9IGYuc2xpY2UoLTEpID09PSAnLydcblxuICBpZiAoZi5sZW5ndGggPiB0aGlzLm1heExlbmd0aClcbiAgICByZXR1cm4gZmFsc2VcblxuICBpZiAoIXRoaXMuc3RhdCAmJiBvd25Qcm9wKHRoaXMuY2FjaGUsIGFicykpIHtcbiAgICB2YXIgYyA9IHRoaXMuY2FjaGVbYWJzXVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYykpXG4gICAgICBjID0gJ0RJUidcblxuICAgIC8vIEl0IGV4aXN0cywgYnV0IG1heWJlIG5vdCBob3cgd2UgbmVlZCBpdFxuICAgIGlmICghbmVlZERpciB8fCBjID09PSAnRElSJylcbiAgICAgIHJldHVybiBjXG5cbiAgICBpZiAobmVlZERpciAmJiBjID09PSAnRklMRScpXG4gICAgICByZXR1cm4gZmFsc2VcblxuICAgIC8vIG90aGVyd2lzZSB3ZSBoYXZlIHRvIHN0YXQsIGJlY2F1c2UgbWF5YmUgYz10cnVlXG4gICAgLy8gaWYgd2Uga25vdyBpdCBleGlzdHMsIGJ1dCBub3Qgd2hhdCBpdCBpcy5cbiAgfVxuXG4gIHZhciBleGlzdHNcbiAgdmFyIHN0YXQgPSB0aGlzLnN0YXRDYWNoZVthYnNdXG4gIGlmICghc3RhdCkge1xuICAgIHZhciBsc3RhdFxuICAgIHRyeSB7XG4gICAgICBsc3RhdCA9IGZzLmxzdGF0U3luYyhhYnMpXG4gICAgfSBjYXRjaCAoZXIpIHtcbiAgICAgIGlmIChlciAmJiAoZXIuY29kZSA9PT0gJ0VOT0VOVCcgfHwgZXIuY29kZSA9PT0gJ0VOT1RESVInKSkge1xuICAgICAgICB0aGlzLnN0YXRDYWNoZVthYnNdID0gZmFsc2VcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGxzdGF0ICYmIGxzdGF0LmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHN0YXQgPSBmcy5zdGF0U3luYyhhYnMpXG4gICAgICB9IGNhdGNoIChlcikge1xuICAgICAgICBzdGF0ID0gbHN0YXRcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdCA9IGxzdGF0XG4gICAgfVxuICB9XG5cbiAgdGhpcy5zdGF0Q2FjaGVbYWJzXSA9IHN0YXRcblxuICB2YXIgYyA9IHRydWVcbiAgaWYgKHN0YXQpXG4gICAgYyA9IHN0YXQuaXNEaXJlY3RvcnkoKSA/ICdESVInIDogJ0ZJTEUnXG5cbiAgdGhpcy5jYWNoZVthYnNdID0gdGhpcy5jYWNoZVthYnNdIHx8IGNcblxuICBpZiAobmVlZERpciAmJiBjID09PSAnRklMRScpXG4gICAgcmV0dXJuIGZhbHNlXG5cbiAgcmV0dXJuIGNcbn1cblxuR2xvYlN5bmMucHJvdG90eXBlLl9tYXJrID0gZnVuY3Rpb24gKHApIHtcbiAgcmV0dXJuIGNvbW1vbi5tYXJrKHRoaXMsIHApXG59XG5cbkdsb2JTeW5jLnByb3RvdHlwZS5fbWFrZUFicyA9IGZ1bmN0aW9uIChmKSB7XG4gIHJldHVybiBjb21tb24ubWFrZUFicyh0aGlzLCBmKVxufVxuIiwidmFyIHdyYXBweSA9IHJlcXVpcmUoJ3dyYXBweScpXG52YXIgcmVxcyA9IE9iamVjdC5jcmVhdGUobnVsbClcbnZhciBvbmNlID0gcmVxdWlyZSgnb25jZScpXG5cbm1vZHVsZS5leHBvcnRzID0gd3JhcHB5KGluZmxpZ2h0KVxuXG5mdW5jdGlvbiBpbmZsaWdodCAoa2V5LCBjYikge1xuICBpZiAocmVxc1trZXldKSB7XG4gICAgcmVxc1trZXldLnB1c2goY2IpXG4gICAgcmV0dXJuIG51bGxcbiAgfSBlbHNlIHtcbiAgICByZXFzW2tleV0gPSBbY2JdXG4gICAgcmV0dXJuIG1ha2VyZXMoa2V5KVxuICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VyZXMgKGtleSkge1xuICByZXR1cm4gb25jZShmdW5jdGlvbiBSRVMgKCkge1xuICAgIHZhciBjYnMgPSByZXFzW2tleV1cbiAgICB2YXIgbGVuID0gY2JzLmxlbmd0aFxuICAgIHZhciBhcmdzID0gc2xpY2UoYXJndW1lbnRzKVxuXG4gICAgLy8gWFhYIEl0J3Mgc29tZXdoYXQgYW1iaWd1b3VzIHdoZXRoZXIgYSBuZXcgY2FsbGJhY2sgYWRkZWQgaW4gdGhpc1xuICAgIC8vIHBhc3Mgc2hvdWxkIGJlIHF1ZXVlZCBmb3IgbGF0ZXIgZXhlY3V0aW9uIGlmIHNvbWV0aGluZyBpbiB0aGVcbiAgICAvLyBsaXN0IG9mIGNhbGxiYWNrcyB0aHJvd3MsIG9yIGlmIGl0IHNob3VsZCBqdXN0IGJlIGRpc2NhcmRlZC5cbiAgICAvLyBIb3dldmVyLCBpdCdzIHN1Y2ggYW4gZWRnZSBjYXNlIHRoYXQgaXQgaGFyZGx5IG1hdHRlcnMsIGFuZCBlaXRoZXJcbiAgICAvLyBjaG9pY2UgaXMgbGlrZWx5IGFzIHN1cnByaXNpbmcgYXMgdGhlIG90aGVyLlxuICAgIC8vIEFzIGl0IGhhcHBlbnMsIHdlIGRvIGdvIGFoZWFkIGFuZCBzY2hlZHVsZSBpdCBmb3IgbGF0ZXIgZXhlY3V0aW9uLlxuICAgIHRyeSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIGNic1tpXS5hcHBseShudWxsLCBhcmdzKVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAoY2JzLmxlbmd0aCA+IGxlbikge1xuICAgICAgICAvLyBhZGRlZCBtb3JlIGluIHRoZSBpbnRlcmltLlxuICAgICAgICAvLyBkZS16YWxnbywganVzdCBpbiBjYXNlLCBidXQgZG9uJ3QgY2FsbCBhZ2Fpbi5cbiAgICAgICAgY2JzLnNwbGljZSgwLCBsZW4pXG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgIFJFUy5hcHBseShudWxsLCBhcmdzKVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIHJlcXNba2V5XVxuICAgICAgfVxuICAgIH1cbiAgfSlcbn1cblxuZnVuY3Rpb24gc2xpY2UgKGFyZ3MpIHtcbiAgdmFyIGxlbmd0aCA9IGFyZ3MubGVuZ3RoXG4gIHZhciBhcnJheSA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgYXJyYXlbaV0gPSBhcmdzW2ldXG4gIHJldHVybiBhcnJheVxufVxuIiwidHJ5IHtcbiAgdmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmICh0eXBlb2YgdXRpbC5pbmhlcml0cyAhPT0gJ2Z1bmN0aW9uJykgdGhyb3cgJyc7XG4gIG1vZHVsZS5leHBvcnRzID0gdXRpbC5pbmhlcml0cztcbn0gY2F0Y2ggKGUpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2luaGVyaXRzX2Jyb3dzZXIuanMnKTtcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy50YWdQcm9wZXJ0eSA9IGV4cG9ydHMudGFnUGFyYW1ldGVyID0gZXhwb3J0cy5kZWNvcmF0ZSA9IHZvaWQgMDtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbmZ1bmN0aW9uIHRhZ1BhcmFtZXRlcihhbm5vdGF0aW9uVGFyZ2V0LCBwcm9wZXJ0eU5hbWUsIHBhcmFtZXRlckluZGV4LCBtZXRhZGF0YSkge1xuICAgIHZhciBtZXRhZGF0YUtleSA9IE1FVEFEQVRBX0tFWS5UQUdHRUQ7XG4gICAgX3RhZ1BhcmFtZXRlck9yUHJvcGVydHkobWV0YWRhdGFLZXksIGFubm90YXRpb25UYXJnZXQsIHByb3BlcnR5TmFtZSwgbWV0YWRhdGEsIHBhcmFtZXRlckluZGV4KTtcbn1cbmV4cG9ydHMudGFnUGFyYW1ldGVyID0gdGFnUGFyYW1ldGVyO1xuZnVuY3Rpb24gdGFnUHJvcGVydHkoYW5ub3RhdGlvblRhcmdldCwgcHJvcGVydHlOYW1lLCBtZXRhZGF0YSkge1xuICAgIHZhciBtZXRhZGF0YUtleSA9IE1FVEFEQVRBX0tFWS5UQUdHRURfUFJPUDtcbiAgICBfdGFnUGFyYW1ldGVyT3JQcm9wZXJ0eShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldC5jb25zdHJ1Y3RvciwgcHJvcGVydHlOYW1lLCBtZXRhZGF0YSk7XG59XG5leHBvcnRzLnRhZ1Byb3BlcnR5ID0gdGFnUHJvcGVydHk7XG5mdW5jdGlvbiBfdGFnUGFyYW1ldGVyT3JQcm9wZXJ0eShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldCwgcHJvcGVydHlOYW1lLCBtZXRhZGF0YSwgcGFyYW1ldGVySW5kZXgpIHtcbiAgICB2YXIgcGFyYW1zT3JQcm9wZXJ0aWVzTWV0YWRhdGEgPSB7fTtcbiAgICB2YXIgaXNQYXJhbWV0ZXJEZWNvcmF0b3IgPSAodHlwZW9mIHBhcmFtZXRlckluZGV4ID09PSBcIm51bWJlclwiKTtcbiAgICB2YXIga2V5ID0gKHBhcmFtZXRlckluZGV4ICE9PSB1bmRlZmluZWQgJiYgaXNQYXJhbWV0ZXJEZWNvcmF0b3IpID8gcGFyYW1ldGVySW5kZXgudG9TdHJpbmcoKSA6IHByb3BlcnR5TmFtZTtcbiAgICBpZiAoaXNQYXJhbWV0ZXJEZWNvcmF0b3IgJiYgcHJvcGVydHlOYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuSU5WQUxJRF9ERUNPUkFUT1JfT1BFUkFUSU9OKTtcbiAgICB9XG4gICAgaWYgKFJlZmxlY3QuaGFzT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIGFubm90YXRpb25UYXJnZXQpKSB7XG4gICAgICAgIHBhcmFtc09yUHJvcGVydGllc01ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShtZXRhZGF0YUtleSwgYW5ub3RhdGlvblRhcmdldCk7XG4gICAgfVxuICAgIHZhciBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YSA9IHBhcmFtc09yUHJvcGVydGllc01ldGFkYXRhW2tleV07XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhKSkge1xuICAgICAgICBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YSA9IFtdO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YV8xID0gcGFyYW1PclByb3BlcnR5TWV0YWRhdGE7IF9pIDwgcGFyYW1PclByb3BlcnR5TWV0YWRhdGFfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBtID0gcGFyYW1PclByb3BlcnR5TWV0YWRhdGFfMVtfaV07XG4gICAgICAgICAgICBpZiAobS5rZXkgPT09IG1ldGFkYXRhLmtleSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLkRVUExJQ0FURURfTUVUQURBVEEgKyBcIiBcIiArIG0ua2V5LnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHBhcmFtT3JQcm9wZXJ0eU1ldGFkYXRhLnB1c2gobWV0YWRhdGEpO1xuICAgIHBhcmFtc09yUHJvcGVydGllc01ldGFkYXRhW2tleV0gPSBwYXJhbU9yUHJvcGVydHlNZXRhZGF0YTtcbiAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKG1ldGFkYXRhS2V5LCBwYXJhbXNPclByb3BlcnRpZXNNZXRhZGF0YSwgYW5ub3RhdGlvblRhcmdldCk7XG59XG5mdW5jdGlvbiBfZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0KSB7XG4gICAgUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQpO1xufVxuZnVuY3Rpb24gX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfTtcbn1cbmZ1bmN0aW9uIGRlY29yYXRlKGRlY29yYXRvciwgdGFyZ2V0LCBwYXJhbWV0ZXJJbmRleCkge1xuICAgIGlmICh0eXBlb2YgcGFyYW1ldGVySW5kZXggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgX2RlY29yYXRlKFtfcGFyYW0ocGFyYW1ldGVySW5kZXgsIGRlY29yYXRvcildLCB0YXJnZXQpO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgcGFyYW1ldGVySW5kZXggPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgUmVmbGVjdC5kZWNvcmF0ZShbZGVjb3JhdG9yXSwgdGFyZ2V0LCBwYXJhbWV0ZXJJbmRleCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBfZGVjb3JhdGUoW2RlY29yYXRvcl0sIHRhcmdldCk7XG4gICAgfVxufVxuZXhwb3J0cy5kZWNvcmF0ZSA9IGRlY29yYXRlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVjb3JhdG9yX3V0aWxzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5pbmplY3QgPSBleHBvcnRzLkxhenlTZXJ2aWNlSWRlbnRpZmVyID0gdm9pZCAwO1xudmFyIGVycm9yX21zZ3NfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2RlY29yYXRvcl91dGlsc1wiKTtcbnZhciBMYXp5U2VydmljZUlkZW50aWZlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTGF6eVNlcnZpY2VJZGVudGlmZXIoY2IpIHtcbiAgICAgICAgdGhpcy5fY2IgPSBjYjtcbiAgICB9XG4gICAgTGF6eVNlcnZpY2VJZGVudGlmZXIucHJvdG90eXBlLnVud3JhcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NiKCk7XG4gICAgfTtcbiAgICByZXR1cm4gTGF6eVNlcnZpY2VJZGVudGlmZXI7XG59KCkpO1xuZXhwb3J0cy5MYXp5U2VydmljZUlkZW50aWZlciA9IExhenlTZXJ2aWNlSWRlbnRpZmVyO1xuZnVuY3Rpb24gaW5qZWN0KHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgpIHtcbiAgICAgICAgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcl9tc2dzXzEuVU5ERUZJTkVEX0lOSkVDVF9BTk5PVEFUSU9OKHRhcmdldC5uYW1lKSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG1ldGFkYXRhID0gbmV3IG1ldGFkYXRhXzEuTWV0YWRhdGEoTUVUQURBVEFfS0VZLklOSkVDVF9UQUcsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUGFyYW1ldGVyKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUHJvcGVydHkodGFyZ2V0LCB0YXJnZXRLZXksIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5leHBvcnRzLmluamVjdCA9IGluamVjdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluamVjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuaW5qZWN0YWJsZSA9IHZvaWQgMDtcbnZhciBFUlJPUlNfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG5mdW5jdGlvbiBpbmplY3RhYmxlKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgICAgIGlmIChSZWZsZWN0Lmhhc093bk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QQVJBTV9UWVBFUywgdGFyZ2V0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SU19NU0dTLkRVUExJQ0FURURfSU5KRUNUQUJMRV9ERUNPUkFUT1IpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoTUVUQURBVEFfS0VZLkRFU0lHTl9QQVJBTV9UWVBFUywgdGFyZ2V0KSB8fCBbXTtcbiAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShNRVRBREFUQV9LRVkuUEFSQU1fVFlQRVMsIHR5cGVzLCB0YXJnZXQpO1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH07XG59XG5leHBvcnRzLmluamVjdGFibGUgPSBpbmplY3RhYmxlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5qZWN0YWJsZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMubXVsdGlJbmplY3QgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiBtdWx0aUluamVjdChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4KSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5NVUxUSV9JTkpFQ1RfVEFHLCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1BhcmFtZXRlcih0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgsIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1Byb3BlcnR5KHRhcmdldCwgdGFyZ2V0S2V5LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuZXhwb3J0cy5tdWx0aUluamVjdCA9IG11bHRpSW5qZWN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bXVsdGlfaW5qZWN0LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5uYW1lZCA9IHZvaWQgMDtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2RlY29yYXRvcl91dGlsc1wiKTtcbmZ1bmN0aW9uIG5hbWVkKG5hbWUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lKTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUGFyYW1ldGVyKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUHJvcGVydHkodGFyZ2V0LCB0YXJnZXRLZXksIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5leHBvcnRzLm5hbWVkID0gbmFtZWQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYW1lZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMub3B0aW9uYWwgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiBvcHRpb25hbCgpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuT1BUSU9OQUxfVEFHLCB0cnVlKTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUGFyYW1ldGVyKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCwgbWV0YWRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUHJvcGVydHkodGFyZ2V0LCB0YXJnZXRLZXksIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5leHBvcnRzLm9wdGlvbmFsID0gb3B0aW9uYWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vcHRpb25hbC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMucG9zdENvbnN0cnVjdCA9IHZvaWQgMDtcbnZhciBFUlJPUlNfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgbWV0YWRhdGFfMSA9IHJlcXVpcmUoXCIuLi9wbGFubmluZy9tZXRhZGF0YVwiKTtcbmZ1bmN0aW9uIHBvc3RDb25zdHJ1Y3QoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHByb3BlcnR5S2V5LCBkZXNjcmlwdG9yKSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QT1NUX0NPTlNUUlVDVCwgcHJvcGVydHlLZXkpO1xuICAgICAgICBpZiAoUmVmbGVjdC5oYXNPd25NZXRhZGF0YShNRVRBREFUQV9LRVkuUE9TVF9DT05TVFJVQ1QsIHRhcmdldC5jb25zdHJ1Y3RvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUlNfTVNHUy5NVUxUSVBMRV9QT1NUX0NPTlNUUlVDVF9NRVRIT0RTKTtcbiAgICAgICAgfVxuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QT1NUX0NPTlNUUlVDVCwgbWV0YWRhdGEsIHRhcmdldC5jb25zdHJ1Y3Rvcik7XG4gICAgfTtcbn1cbmV4cG9ydHMucG9zdENvbnN0cnVjdCA9IHBvc3RDb25zdHJ1Y3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb3N0X2NvbnN0cnVjdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMudGFnZ2VkID0gdm9pZCAwO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiB0YWdnZWQobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1BhcmFtZXRlcih0YXJnZXQsIHRhcmdldEtleSwgaW5kZXgsIG1ldGFkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlY29yYXRvcl91dGlsc18xLnRhZ1Byb3BlcnR5KHRhcmdldCwgdGFyZ2V0S2V5LCBtZXRhZGF0YSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuZXhwb3J0cy50YWdnZWQgPSB0YWdnZWQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10YWdnZWQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLnRhcmdldE5hbWUgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgZGVjb3JhdG9yX3V0aWxzXzEgPSByZXF1aXJlKFwiLi9kZWNvcmF0b3JfdXRpbHNcIik7XG5mdW5jdGlvbiB0YXJnZXROYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCkge1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuTkFNRV9UQUcsIG5hbWUpO1xuICAgICAgICBkZWNvcmF0b3JfdXRpbHNfMS50YWdQYXJhbWV0ZXIodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4LCBtZXRhZGF0YSk7XG4gICAgfTtcbn1cbmV4cG9ydHMudGFyZ2V0TmFtZSA9IHRhcmdldE5hbWU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10YXJnZXRfbmFtZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMudW5tYW5hZ2VkID0gdm9pZCAwO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBtZXRhZGF0YV8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhXCIpO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vZGVjb3JhdG9yX3V0aWxzXCIpO1xuZnVuY3Rpb24gdW5tYW5hZ2VkKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGluZGV4KSB7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKE1FVEFEQVRBX0tFWS5VTk1BTkFHRURfVEFHLCB0cnVlKTtcbiAgICAgICAgZGVjb3JhdG9yX3V0aWxzXzEudGFnUGFyYW1ldGVyKHRhcmdldCwgdGFyZ2V0S2V5LCBpbmRleCwgbWV0YWRhdGEpO1xuICAgIH07XG59XG5leHBvcnRzLnVubWFuYWdlZCA9IHVubWFuYWdlZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXVubWFuYWdlZC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuQmluZGluZyA9IHZvaWQgMDtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgaWRfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9pZFwiKTtcbnZhciBCaW5kaW5nID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nKHNlcnZpY2VJZGVudGlmaWVyLCBzY29wZSkge1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLmFjdGl2YXRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNlcnZpY2VJZGVudGlmaWVyID0gc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcbiAgICAgICAgdGhpcy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5JbnZhbGlkO1xuICAgICAgICB0aGlzLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkgeyByZXR1cm4gdHJ1ZTsgfTtcbiAgICAgICAgdGhpcy5pbXBsZW1lbnRhdGlvblR5cGUgPSBudWxsO1xuICAgICAgICB0aGlzLmNhY2hlID0gbnVsbDtcbiAgICAgICAgdGhpcy5mYWN0b3J5ID0gbnVsbDtcbiAgICAgICAgdGhpcy5wcm92aWRlciA9IG51bGw7XG4gICAgICAgIHRoaXMub25BY3RpdmF0aW9uID0gbnVsbDtcbiAgICAgICAgdGhpcy5keW5hbWljVmFsdWUgPSBudWxsO1xuICAgIH1cbiAgICBCaW5kaW5nLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNsb25lID0gbmV3IEJpbmRpbmcodGhpcy5zZXJ2aWNlSWRlbnRpZmllciwgdGhpcy5zY29wZSk7XG4gICAgICAgIGNsb25lLmFjdGl2YXRlZCA9IChjbG9uZS5zY29wZSA9PT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uU2luZ2xldG9uKSA/IHRoaXMuYWN0aXZhdGVkIDogZmFsc2U7XG4gICAgICAgIGNsb25lLmltcGxlbWVudGF0aW9uVHlwZSA9IHRoaXMuaW1wbGVtZW50YXRpb25UeXBlO1xuICAgICAgICBjbG9uZS5keW5hbWljVmFsdWUgPSB0aGlzLmR5bmFtaWNWYWx1ZTtcbiAgICAgICAgY2xvbmUuc2NvcGUgPSB0aGlzLnNjb3BlO1xuICAgICAgICBjbG9uZS50eXBlID0gdGhpcy50eXBlO1xuICAgICAgICBjbG9uZS5mYWN0b3J5ID0gdGhpcy5mYWN0b3J5O1xuICAgICAgICBjbG9uZS5wcm92aWRlciA9IHRoaXMucHJvdmlkZXI7XG4gICAgICAgIGNsb25lLmNvbnN0cmFpbnQgPSB0aGlzLmNvbnN0cmFpbnQ7XG4gICAgICAgIGNsb25lLm9uQWN0aXZhdGlvbiA9IHRoaXMub25BY3RpdmF0aW9uO1xuICAgICAgICBjbG9uZS5jYWNoZSA9IHRoaXMuY2FjaGU7XG4gICAgICAgIHJldHVybiBjbG9uZTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nO1xufSgpKTtcbmV4cG9ydHMuQmluZGluZyA9IEJpbmRpbmc7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaW5kaW5nLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CaW5kaW5nQ291bnQgPSB2b2lkIDA7XG52YXIgQmluZGluZ0NvdW50ID0ge1xuICAgIE11bHRpcGxlQmluZGluZ3NBdmFpbGFibGU6IDIsXG4gICAgTm9CaW5kaW5nc0F2YWlsYWJsZTogMCxcbiAgICBPbmx5T25lQmluZGluZ0F2YWlsYWJsZTogMVxufTtcbmV4cG9ydHMuQmluZGluZ0NvdW50ID0gQmluZGluZ0NvdW50O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmluZGluZ19jb3VudC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuU1RBQ0tfT1ZFUkZMT1cgPSBleHBvcnRzLkNJUkNVTEFSX0RFUEVOREVOQ1lfSU5fRkFDVE9SWSA9IGV4cG9ydHMuUE9TVF9DT05TVFJVQ1RfRVJST1IgPSBleHBvcnRzLk1VTFRJUExFX1BPU1RfQ09OU1RSVUNUX01FVEhPRFMgPSBleHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfU0tJUF9CQVNFX0NIRUNLID0gZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX0FVVE9fQklORF9JTkpFQ1RBQkxFID0gZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX0RFRkFVTFRfU0NPUEUgPSBleHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX01VU1RfQkVfQU5fT0JKRUNUID0gZXhwb3J0cy5BUkdVTUVOVFNfTEVOR1RIX01JU01BVENIID0gZXhwb3J0cy5JTlZBTElEX0RFQ09SQVRPUl9PUEVSQVRJT04gPSBleHBvcnRzLklOVkFMSURfVE9fU0VMRl9WQUxVRSA9IGV4cG9ydHMuSU5WQUxJRF9GVU5DVElPTl9CSU5ESU5HID0gZXhwb3J0cy5JTlZBTElEX01JRERMRVdBUkVfUkVUVVJOID0gZXhwb3J0cy5OT19NT1JFX1NOQVBTSE9UU19BVkFJTEFCTEUgPSBleHBvcnRzLklOVkFMSURfQklORElOR19UWVBFID0gZXhwb3J0cy5OT1RfSU1QTEVNRU5URUQgPSBleHBvcnRzLkNJUkNVTEFSX0RFUEVOREVOQ1kgPSBleHBvcnRzLlVOREVGSU5FRF9JTkpFQ1RfQU5OT1RBVElPTiA9IGV4cG9ydHMuTUlTU0lOR19JTkpFQ1RfQU5OT1RBVElPTiA9IGV4cG9ydHMuTUlTU0lOR19JTkpFQ1RBQkxFX0FOTk9UQVRJT04gPSBleHBvcnRzLk5PVF9SRUdJU1RFUkVEID0gZXhwb3J0cy5DQU5OT1RfVU5CSU5EID0gZXhwb3J0cy5BTUJJR1VPVVNfTUFUQ0ggPSBleHBvcnRzLktFWV9OT1RfRk9VTkQgPSBleHBvcnRzLk5VTExfQVJHVU1FTlQgPSBleHBvcnRzLkRVUExJQ0FURURfTUVUQURBVEEgPSBleHBvcnRzLkRVUExJQ0FURURfSU5KRUNUQUJMRV9ERUNPUkFUT1IgPSB2b2lkIDA7XG5leHBvcnRzLkRVUExJQ0FURURfSU5KRUNUQUJMRV9ERUNPUkFUT1IgPSBcIkNhbm5vdCBhcHBseSBAaW5qZWN0YWJsZSBkZWNvcmF0b3IgbXVsdGlwbGUgdGltZXMuXCI7XG5leHBvcnRzLkRVUExJQ0FURURfTUVUQURBVEEgPSBcIk1ldGFkYXRhIGtleSB3YXMgdXNlZCBtb3JlIHRoYW4gb25jZSBpbiBhIHBhcmFtZXRlcjpcIjtcbmV4cG9ydHMuTlVMTF9BUkdVTUVOVCA9IFwiTlVMTCBhcmd1bWVudFwiO1xuZXhwb3J0cy5LRVlfTk9UX0ZPVU5EID0gXCJLZXkgTm90IEZvdW5kXCI7XG5leHBvcnRzLkFNQklHVU9VU19NQVRDSCA9IFwiQW1iaWd1b3VzIG1hdGNoIGZvdW5kIGZvciBzZXJ2aWNlSWRlbnRpZmllcjpcIjtcbmV4cG9ydHMuQ0FOTk9UX1VOQklORCA9IFwiQ291bGQgbm90IHVuYmluZCBzZXJ2aWNlSWRlbnRpZmllcjpcIjtcbmV4cG9ydHMuTk9UX1JFR0lTVEVSRUQgPSBcIk5vIG1hdGNoaW5nIGJpbmRpbmdzIGZvdW5kIGZvciBzZXJ2aWNlSWRlbnRpZmllcjpcIjtcbmV4cG9ydHMuTUlTU0lOR19JTkpFQ1RBQkxFX0FOTk9UQVRJT04gPSBcIk1pc3NpbmcgcmVxdWlyZWQgQGluamVjdGFibGUgYW5ub3RhdGlvbiBpbjpcIjtcbmV4cG9ydHMuTUlTU0lOR19JTkpFQ1RfQU5OT1RBVElPTiA9IFwiTWlzc2luZyByZXF1aXJlZCBAaW5qZWN0IG9yIEBtdWx0aUluamVjdCBhbm5vdGF0aW9uIGluOlwiO1xudmFyIFVOREVGSU5FRF9JTkpFQ1RfQU5OT1RBVElPTiA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgcmV0dXJuIFwiQGluamVjdCBjYWxsZWQgd2l0aCB1bmRlZmluZWQgdGhpcyBjb3VsZCBtZWFuIHRoYXQgdGhlIGNsYXNzIFwiICsgbmFtZSArIFwiIGhhcyBcIiArXG4gICAgICAgIFwiYSBjaXJjdWxhciBkZXBlbmRlbmN5IHByb2JsZW0uIFlvdSBjYW4gdXNlIGEgTGF6eVNlcnZpY2VJZGVudGlmZXIgdG8gIFwiICtcbiAgICAgICAgXCJvdmVyY29tZSB0aGlzIGxpbWl0YXRpb24uXCI7XG59O1xuZXhwb3J0cy5VTkRFRklORURfSU5KRUNUX0FOTk9UQVRJT04gPSBVTkRFRklORURfSU5KRUNUX0FOTk9UQVRJT047XG5leHBvcnRzLkNJUkNVTEFSX0RFUEVOREVOQ1kgPSBcIkNpcmN1bGFyIGRlcGVuZGVuY3kgZm91bmQ6XCI7XG5leHBvcnRzLk5PVF9JTVBMRU1FTlRFRCA9IFwiU29ycnksIHRoaXMgZmVhdHVyZSBpcyBub3QgZnVsbHkgaW1wbGVtZW50ZWQgeWV0LlwiO1xuZXhwb3J0cy5JTlZBTElEX0JJTkRJTkdfVFlQRSA9IFwiSW52YWxpZCBiaW5kaW5nIHR5cGU6XCI7XG5leHBvcnRzLk5PX01PUkVfU05BUFNIT1RTX0FWQUlMQUJMRSA9IFwiTm8gc25hcHNob3QgYXZhaWxhYmxlIHRvIHJlc3RvcmUuXCI7XG5leHBvcnRzLklOVkFMSURfTUlERExFV0FSRV9SRVRVUk4gPSBcIkludmFsaWQgcmV0dXJuIHR5cGUgaW4gbWlkZGxld2FyZS4gTWlkZGxld2FyZSBtdXN0IHJldHVybiFcIjtcbmV4cG9ydHMuSU5WQUxJRF9GVU5DVElPTl9CSU5ESU5HID0gXCJWYWx1ZSBwcm92aWRlZCB0byBmdW5jdGlvbiBiaW5kaW5nIG11c3QgYmUgYSBmdW5jdGlvbiFcIjtcbmV4cG9ydHMuSU5WQUxJRF9UT19TRUxGX1ZBTFVFID0gXCJUaGUgdG9TZWxmIGZ1bmN0aW9uIGNhbiBvbmx5IGJlIGFwcGxpZWQgd2hlbiBhIGNvbnN0cnVjdG9yIGlzIFwiICtcbiAgICBcInVzZWQgYXMgc2VydmljZSBpZGVudGlmaWVyXCI7XG5leHBvcnRzLklOVkFMSURfREVDT1JBVE9SX09QRVJBVElPTiA9IFwiVGhlIEBpbmplY3QgQG11bHRpSW5qZWN0IEB0YWdnZWQgYW5kIEBuYW1lZCBkZWNvcmF0b3JzIFwiICtcbiAgICBcIm11c3QgYmUgYXBwbGllZCB0byB0aGUgcGFyYW1ldGVycyBvZiBhIGNsYXNzIGNvbnN0cnVjdG9yIG9yIGEgY2xhc3MgcHJvcGVydHkuXCI7XG52YXIgQVJHVU1FTlRTX0xFTkdUSF9NSVNNQVRDSCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFsdWVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBcIlRoZSBudW1iZXIgb2YgY29uc3RydWN0b3IgYXJndW1lbnRzIGluIHRoZSBkZXJpdmVkIGNsYXNzIFwiICtcbiAgICAgICAgKHZhbHVlc1swXSArIFwiIG11c3QgYmUgPj0gdGhhbiB0aGUgbnVtYmVyIG9mIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyBvZiBpdHMgYmFzZSBjbGFzcy5cIik7XG59O1xuZXhwb3J0cy5BUkdVTUVOVFNfTEVOR1RIX01JU01BVENIID0gQVJHVU1FTlRTX0xFTkdUSF9NSVNNQVRDSDtcbmV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfTVVTVF9CRV9BTl9PQkpFQ1QgPSBcIkludmFsaWQgQ29udGFpbmVyIGNvbnN0cnVjdG9yIGFyZ3VtZW50LiBDb250YWluZXIgb3B0aW9ucyBcIiArXG4gICAgXCJtdXN0IGJlIGFuIG9iamVjdC5cIjtcbmV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9ERUZBVUxUX1NDT1BFID0gXCJJbnZhbGlkIENvbnRhaW5lciBvcHRpb24uIERlZmF1bHQgc2NvcGUgbXVzdCBcIiArXG4gICAgXCJiZSBhIHN0cmluZyAoJ3NpbmdsZXRvbicgb3IgJ3RyYW5zaWVudCcpLlwiO1xuZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX0FVVE9fQklORF9JTkpFQ1RBQkxFID0gXCJJbnZhbGlkIENvbnRhaW5lciBvcHRpb24uIEF1dG8gYmluZCBpbmplY3RhYmxlIG11c3QgXCIgK1xuICAgIFwiYmUgYSBib29sZWFuXCI7XG5leHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfU0tJUF9CQVNFX0NIRUNLID0gXCJJbnZhbGlkIENvbnRhaW5lciBvcHRpb24uIFNraXAgYmFzZSBjaGVjayBtdXN0IFwiICtcbiAgICBcImJlIGEgYm9vbGVhblwiO1xuZXhwb3J0cy5NVUxUSVBMRV9QT1NUX0NPTlNUUlVDVF9NRVRIT0RTID0gXCJDYW5ub3QgYXBwbHkgQHBvc3RDb25zdHJ1Y3QgZGVjb3JhdG9yIG11bHRpcGxlIHRpbWVzIGluIHRoZSBzYW1lIGNsYXNzXCI7XG52YXIgUE9TVF9DT05TVFJVQ1RfRVJST1IgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhbHVlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgIH1cbiAgICByZXR1cm4gXCJAcG9zdENvbnN0cnVjdCBlcnJvciBpbiBjbGFzcyBcIiArIHZhbHVlc1swXSArIFwiOiBcIiArIHZhbHVlc1sxXTtcbn07XG5leHBvcnRzLlBPU1RfQ09OU1RSVUNUX0VSUk9SID0gUE9TVF9DT05TVFJVQ1RfRVJST1I7XG52YXIgQ0lSQ1VMQVJfREVQRU5ERU5DWV9JTl9GQUNUT1JZID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YWx1ZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIFwiSXQgbG9va3MgbGlrZSB0aGVyZSBpcyBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgXCIgK1xuICAgICAgICAoXCJpbiBvbmUgb2YgdGhlICdcIiArIHZhbHVlc1swXSArIFwiJyBiaW5kaW5ncy4gUGxlYXNlIGludmVzdGlnYXRlIGJpbmRpbmdzIHdpdGhcIikgK1xuICAgICAgICAoXCJzZXJ2aWNlIGlkZW50aWZpZXIgJ1wiICsgdmFsdWVzWzFdICsgXCInLlwiKTtcbn07XG5leHBvcnRzLkNJUkNVTEFSX0RFUEVOREVOQ1lfSU5fRkFDVE9SWSA9IENJUkNVTEFSX0RFUEVOREVOQ1lfSU5fRkFDVE9SWTtcbmV4cG9ydHMuU1RBQ0tfT1ZFUkZMT1cgPSBcIk1heGltdW0gY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lcnJvcl9tc2dzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5UYXJnZXRUeXBlRW51bSA9IGV4cG9ydHMuQmluZGluZ1R5cGVFbnVtID0gZXhwb3J0cy5CaW5kaW5nU2NvcGVFbnVtID0gdm9pZCAwO1xudmFyIEJpbmRpbmdTY29wZUVudW0gPSB7XG4gICAgUmVxdWVzdDogXCJSZXF1ZXN0XCIsXG4gICAgU2luZ2xldG9uOiBcIlNpbmdsZXRvblwiLFxuICAgIFRyYW5zaWVudDogXCJUcmFuc2llbnRcIlxufTtcbmV4cG9ydHMuQmluZGluZ1Njb3BlRW51bSA9IEJpbmRpbmdTY29wZUVudW07XG52YXIgQmluZGluZ1R5cGVFbnVtID0ge1xuICAgIENvbnN0YW50VmFsdWU6IFwiQ29uc3RhbnRWYWx1ZVwiLFxuICAgIENvbnN0cnVjdG9yOiBcIkNvbnN0cnVjdG9yXCIsXG4gICAgRHluYW1pY1ZhbHVlOiBcIkR5bmFtaWNWYWx1ZVwiLFxuICAgIEZhY3Rvcnk6IFwiRmFjdG9yeVwiLFxuICAgIEZ1bmN0aW9uOiBcIkZ1bmN0aW9uXCIsXG4gICAgSW5zdGFuY2U6IFwiSW5zdGFuY2VcIixcbiAgICBJbnZhbGlkOiBcIkludmFsaWRcIixcbiAgICBQcm92aWRlcjogXCJQcm92aWRlclwiXG59O1xuZXhwb3J0cy5CaW5kaW5nVHlwZUVudW0gPSBCaW5kaW5nVHlwZUVudW07XG52YXIgVGFyZ2V0VHlwZUVudW0gPSB7XG4gICAgQ2xhc3NQcm9wZXJ0eTogXCJDbGFzc1Byb3BlcnR5XCIsXG4gICAgQ29uc3RydWN0b3JBcmd1bWVudDogXCJDb25zdHJ1Y3RvckFyZ3VtZW50XCIsXG4gICAgVmFyaWFibGU6IFwiVmFyaWFibGVcIlxufTtcbmV4cG9ydHMuVGFyZ2V0VHlwZUVudW0gPSBUYXJnZXRUeXBlRW51bTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxpdGVyYWxfdHlwZXMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLk5PTl9DVVNUT01fVEFHX0tFWVMgPSBleHBvcnRzLlBPU1RfQ09OU1RSVUNUID0gZXhwb3J0cy5ERVNJR05fUEFSQU1fVFlQRVMgPSBleHBvcnRzLlBBUkFNX1RZUEVTID0gZXhwb3J0cy5UQUdHRURfUFJPUCA9IGV4cG9ydHMuVEFHR0VEID0gZXhwb3J0cy5NVUxUSV9JTkpFQ1RfVEFHID0gZXhwb3J0cy5JTkpFQ1RfVEFHID0gZXhwb3J0cy5PUFRJT05BTF9UQUcgPSBleHBvcnRzLlVOTUFOQUdFRF9UQUcgPSBleHBvcnRzLk5BTUVfVEFHID0gZXhwb3J0cy5OQU1FRF9UQUcgPSB2b2lkIDA7XG5leHBvcnRzLk5BTUVEX1RBRyA9IFwibmFtZWRcIjtcbmV4cG9ydHMuTkFNRV9UQUcgPSBcIm5hbWVcIjtcbmV4cG9ydHMuVU5NQU5BR0VEX1RBRyA9IFwidW5tYW5hZ2VkXCI7XG5leHBvcnRzLk9QVElPTkFMX1RBRyA9IFwib3B0aW9uYWxcIjtcbmV4cG9ydHMuSU5KRUNUX1RBRyA9IFwiaW5qZWN0XCI7XG5leHBvcnRzLk1VTFRJX0lOSkVDVF9UQUcgPSBcIm11bHRpX2luamVjdFwiO1xuZXhwb3J0cy5UQUdHRUQgPSBcImludmVyc2lmeTp0YWdnZWRcIjtcbmV4cG9ydHMuVEFHR0VEX1BST1AgPSBcImludmVyc2lmeTp0YWdnZWRfcHJvcHNcIjtcbmV4cG9ydHMuUEFSQU1fVFlQRVMgPSBcImludmVyc2lmeTpwYXJhbXR5cGVzXCI7XG5leHBvcnRzLkRFU0lHTl9QQVJBTV9UWVBFUyA9IFwiZGVzaWduOnBhcmFtdHlwZXNcIjtcbmV4cG9ydHMuUE9TVF9DT05TVFJVQ1QgPSBcInBvc3RfY29uc3RydWN0XCI7XG5mdW5jdGlvbiBnZXROb25DdXN0b21UYWdLZXlzKCkge1xuICAgIHJldHVybiBbXG4gICAgICAgIGV4cG9ydHMuSU5KRUNUX1RBRyxcbiAgICAgICAgZXhwb3J0cy5NVUxUSV9JTkpFQ1RfVEFHLFxuICAgICAgICBleHBvcnRzLk5BTUVfVEFHLFxuICAgICAgICBleHBvcnRzLlVOTUFOQUdFRF9UQUcsXG4gICAgICAgIGV4cG9ydHMuTkFNRURfVEFHLFxuICAgICAgICBleHBvcnRzLk9QVElPTkFMX1RBRyxcbiAgICBdO1xufVxuZXhwb3J0cy5OT05fQ1VTVE9NX1RBR19LRVlTID0gZ2V0Tm9uQ3VzdG9tVGFnS2V5cygpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWV0YWRhdGFfa2V5cy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2F3YWl0ZXIgPSAodGhpcyAmJiB0aGlzLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XG4gICAgfSk7XG59O1xudmFyIF9fZ2VuZXJhdG9yID0gKHRoaXMgJiYgdGhpcy5fX2dlbmVyYXRvcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIGJvZHkpIHtcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xuICAgIH1cbn07XG52YXIgX19zcHJlYWRBcnJheSA9ICh0aGlzICYmIHRoaXMuX19zcHJlYWRBcnJheSkgfHwgZnVuY3Rpb24gKHRvLCBmcm9tKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGlsID0gZnJvbS5sZW5ndGgsIGogPSB0by5sZW5ndGg7IGkgPCBpbDsgaSsrLCBqKyspXG4gICAgICAgIHRvW2pdID0gZnJvbVtpXTtcbiAgICByZXR1cm4gdG87XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5Db250YWluZXIgPSB2b2lkIDA7XG52YXIgYmluZGluZ18xID0gcmVxdWlyZShcIi4uL2JpbmRpbmdzL2JpbmRpbmdcIik7XG52YXIgRVJST1JfTVNHUyA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvZXJyb3JfbXNnc1wiKTtcbnZhciBsaXRlcmFsX3R5cGVzXzEgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhX3JlYWRlcl8xID0gcmVxdWlyZShcIi4uL3BsYW5uaW5nL21ldGFkYXRhX3JlYWRlclwiKTtcbnZhciBwbGFubmVyXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvcGxhbm5lclwiKTtcbnZhciByZXNvbHZlcl8xID0gcmVxdWlyZShcIi4uL3Jlc29sdXRpb24vcmVzb2x2ZXJcIik7XG52YXIgYmluZGluZ190b19zeW50YXhfMSA9IHJlcXVpcmUoXCIuLi9zeW50YXgvYmluZGluZ190b19zeW50YXhcIik7XG52YXIgaWRfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9pZFwiKTtcbnZhciBzZXJpYWxpemF0aW9uXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvc2VyaWFsaXphdGlvblwiKTtcbnZhciBjb250YWluZXJfc25hcHNob3RfMSA9IHJlcXVpcmUoXCIuL2NvbnRhaW5lcl9zbmFwc2hvdFwiKTtcbnZhciBsb29rdXBfMSA9IHJlcXVpcmUoXCIuL2xvb2t1cFwiKTtcbnZhciBDb250YWluZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENvbnRhaW5lcihjb250YWluZXJPcHRpb25zKSB7XG4gICAgICAgIHRoaXMuX2FwcGxpZWRNaWRkbGV3YXJlID0gW107XG4gICAgICAgIHZhciBvcHRpb25zID0gY29udGFpbmVyT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJcIiArIEVSUk9SX01TR1MuQ09OVEFJTkVSX09QVElPTlNfTVVTVF9CRV9BTl9PQkpFQ1QpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRTY29wZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvcHRpb25zLmRlZmF1bHRTY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlRyYW5zaWVudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvcHRpb25zLmRlZmF1bHRTY29wZSAhPT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uU2luZ2xldG9uICYmXG4gICAgICAgICAgICBvcHRpb25zLmRlZmF1bHRTY29wZSAhPT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uVHJhbnNpZW50ICYmXG4gICAgICAgICAgICBvcHRpb25zLmRlZmF1bHRTY29wZSAhPT0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uUmVxdWVzdCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiXCIgKyBFUlJPUl9NU0dTLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfREVGQVVMVF9TQ09QRSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuYXV0b0JpbmRJbmplY3RhYmxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuYXV0b0JpbmRJbmplY3RhYmxlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMuYXV0b0JpbmRJbmplY3RhYmxlICE9PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiXCIgKyBFUlJPUl9NU0dTLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfQVVUT19CSU5EX0lOSkVDVEFCTEUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLnNraXBCYXNlQ2xhc3NDaGVja3MgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgb3B0aW9ucy5za2lwQmFzZUNsYXNzQ2hlY2tzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMuc2tpcEJhc2VDbGFzc0NoZWNrcyAhPT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlwiICsgRVJST1JfTVNHUy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX1NLSVBfQkFTRV9DSEVDSyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgYXV0b0JpbmRJbmplY3RhYmxlOiBvcHRpb25zLmF1dG9CaW5kSW5qZWN0YWJsZSxcbiAgICAgICAgICAgIGRlZmF1bHRTY29wZTogb3B0aW9ucy5kZWZhdWx0U2NvcGUsXG4gICAgICAgICAgICBza2lwQmFzZUNsYXNzQ2hlY2tzOiBvcHRpb25zLnNraXBCYXNlQ2xhc3NDaGVja3NcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5pZCA9IGlkXzEuaWQoKTtcbiAgICAgICAgdGhpcy5fYmluZGluZ0RpY3Rpb25hcnkgPSBuZXcgbG9va3VwXzEuTG9va3VwKCk7XG4gICAgICAgIHRoaXMuX3NuYXBzaG90cyA9IFtdO1xuICAgICAgICB0aGlzLl9taWRkbGV3YXJlID0gbnVsbDtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLl9tZXRhZGF0YVJlYWRlciA9IG5ldyBtZXRhZGF0YV9yZWFkZXJfMS5NZXRhZGF0YVJlYWRlcigpO1xuICAgIH1cbiAgICBDb250YWluZXIubWVyZ2UgPSBmdW5jdGlvbiAoY29udGFpbmVyMSwgY29udGFpbmVyMikge1xuICAgICAgICB2YXIgY29udGFpbmVyMyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDI7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgY29udGFpbmVyM1tfaSAtIDJdID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY29udGFpbmVyID0gbmV3IENvbnRhaW5lcigpO1xuICAgICAgICB2YXIgdGFyZ2V0Q29udGFpbmVycyA9IF9fc3ByZWFkQXJyYXkoW2NvbnRhaW5lcjEsIGNvbnRhaW5lcjJdLCBjb250YWluZXIzKS5tYXAoZnVuY3Rpb24gKHRhcmdldENvbnRhaW5lcikgeyByZXR1cm4gcGxhbm5lcl8xLmdldEJpbmRpbmdEaWN0aW9uYXJ5KHRhcmdldENvbnRhaW5lcik7IH0pO1xuICAgICAgICB2YXIgYmluZGluZ0RpY3Rpb25hcnkgPSBwbGFubmVyXzEuZ2V0QmluZGluZ0RpY3Rpb25hcnkoY29udGFpbmVyKTtcbiAgICAgICAgZnVuY3Rpb24gY29weURpY3Rpb25hcnkob3JpZ2luLCBkZXN0aW5hdGlvbikge1xuICAgICAgICAgICAgb3JpZ2luLnRyYXZlcnNlKGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUuZm9yRWFjaChmdW5jdGlvbiAoYmluZGluZykge1xuICAgICAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbi5hZGQoYmluZGluZy5zZXJ2aWNlSWRlbnRpZmllciwgYmluZGluZy5jbG9uZSgpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRhcmdldENvbnRhaW5lcnMuZm9yRWFjaChmdW5jdGlvbiAodGFyZ2V0QmluZGluZ0RpY3Rpb25hcnkpIHtcbiAgICAgICAgICAgIGNvcHlEaWN0aW9uYXJ5KHRhcmdldEJpbmRpbmdEaWN0aW9uYXJ5LCBiaW5kaW5nRGljdGlvbmFyeSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY29udGFpbmVyO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbW9kdWxlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgbW9kdWxlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBnZXRIZWxwZXJzID0gdGhpcy5fZ2V0Q29udGFpbmVyTW9kdWxlSGVscGVyc0ZhY3RvcnkoKTtcbiAgICAgICAgZm9yICh2YXIgX2EgPSAwLCBtb2R1bGVzXzEgPSBtb2R1bGVzOyBfYSA8IG1vZHVsZXNfMS5sZW5ndGg7IF9hKyspIHtcbiAgICAgICAgICAgIHZhciBjdXJyZW50TW9kdWxlID0gbW9kdWxlc18xW19hXTtcbiAgICAgICAgICAgIHZhciBjb250YWluZXJNb2R1bGVIZWxwZXJzID0gZ2V0SGVscGVycyhjdXJyZW50TW9kdWxlLmlkKTtcbiAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUucmVnaXN0cnkoY29udGFpbmVyTW9kdWxlSGVscGVycy5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMudW5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMuaXNib3VuZEZ1bmN0aW9uLCBjb250YWluZXJNb2R1bGVIZWxwZXJzLnJlYmluZEZ1bmN0aW9uKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5sb2FkQXN5bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtb2R1bGVzID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBtb2R1bGVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGdldEhlbHBlcnMsIF9hLCBtb2R1bGVzXzIsIGN1cnJlbnRNb2R1bGUsIGNvbnRhaW5lck1vZHVsZUhlbHBlcnM7XG4gICAgICAgICAgICByZXR1cm4gX19nZW5lcmF0b3IodGhpcywgZnVuY3Rpb24gKF9iKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChfYi5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRIZWxwZXJzID0gdGhpcy5fZ2V0Q29udGFpbmVyTW9kdWxlSGVscGVyc0ZhY3RvcnkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9hID0gMCwgbW9kdWxlc18yID0gbW9kdWxlcztcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoX2EgPCBtb2R1bGVzXzIubGVuZ3RoKSkgcmV0dXJuIFszLCA0XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUgPSBtb2R1bGVzXzJbX2FdO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyTW9kdWxlSGVscGVycyA9IGdldEhlbHBlcnMoY3VycmVudE1vZHVsZS5pZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzQsIGN1cnJlbnRNb2R1bGUucmVnaXN0cnkoY29udGFpbmVyTW9kdWxlSGVscGVycy5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMudW5iaW5kRnVuY3Rpb24sIGNvbnRhaW5lck1vZHVsZUhlbHBlcnMuaXNib3VuZEZ1bmN0aW9uLCBjb250YWluZXJNb2R1bGVIZWxwZXJzLnJlYmluZEZ1bmN0aW9uKV07XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLnNlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9iLmxhYmVsID0gMztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgICAgICAgICAgX2ErKztcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbMywgMV07XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNDogcmV0dXJuIFsyXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLnVubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIG1vZHVsZXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIG1vZHVsZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY29uZGl0aW9uRmFjdG9yeSA9IGZ1bmN0aW9uIChleHBlY3RlZCkgeyByZXR1cm4gZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIHJldHVybiBpdGVtLm1vZHVsZUlkID09PSBleHBlY3RlZDtcbiAgICAgICAgfTsgfTtcbiAgICAgICAgbW9kdWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChtb2R1bGUpIHtcbiAgICAgICAgICAgIHZhciBjb25kaXRpb24gPSBjb25kaXRpb25GYWN0b3J5KG1vZHVsZS5pZCk7XG4gICAgICAgICAgICBfdGhpcy5fYmluZGluZ0RpY3Rpb25hcnkucmVtb3ZlQnlDb25kaXRpb24oY29uZGl0aW9uKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgdmFyIHNjb3BlID0gdGhpcy5vcHRpb25zLmRlZmF1bHRTY29wZSB8fCBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5UcmFuc2llbnQ7XG4gICAgICAgIHZhciBiaW5kaW5nID0gbmV3IGJpbmRpbmdfMS5CaW5kaW5nKHNlcnZpY2VJZGVudGlmaWVyLCBzY29wZSk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LmFkZChzZXJ2aWNlSWRlbnRpZmllciwgYmluZGluZyk7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ190b19zeW50YXhfMS5CaW5kaW5nVG9TeW50YXgoYmluZGluZyk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLnJlYmluZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB0aGlzLnVuYmluZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIHJldHVybiB0aGlzLmJpbmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS51bmJpbmQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LnJlbW92ZShzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLkNBTk5PVF9VTkJJTkQgKyBcIiBcIiArIHNlcmlhbGl6YXRpb25fMS5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nKHNlcnZpY2VJZGVudGlmaWVyKSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUudW5iaW5kQWxsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeSA9IG5ldyBsb29rdXBfMS5Mb29rdXAoKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuaXNCb3VuZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICB2YXIgYm91bmQgPSB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5oYXNLZXkoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICBpZiAoIWJvdW5kICYmIHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICBib3VuZCA9IHRoaXMucGFyZW50LmlzQm91bmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBib3VuZDtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuaXNCb3VuZE5hbWVkID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBuYW1lZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc0JvdW5kVGFnZ2VkKHNlcnZpY2VJZGVudGlmaWVyLCBNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lZCk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmlzQm91bmRUYWdnZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGJvdW5kID0gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5oYXNLZXkoc2VydmljZUlkZW50aWZpZXIpKSB7XG4gICAgICAgICAgICB2YXIgYmluZGluZ3MgPSB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeS5nZXQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgdmFyIHJlcXVlc3RfMSA9IHBsYW5uZXJfMS5jcmVhdGVNb2NrUmVxdWVzdCh0aGlzLCBzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICBib3VuZCA9IGJpbmRpbmdzLnNvbWUoZnVuY3Rpb24gKGIpIHsgcmV0dXJuIGIuY29uc3RyYWludChyZXF1ZXN0XzEpOyB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWJvdW5kICYmIHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICBib3VuZCA9IHRoaXMucGFyZW50LmlzQm91bmRUYWdnZWQoc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBib3VuZDtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuc25hcHNob3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX3NuYXBzaG90cy5wdXNoKGNvbnRhaW5lcl9zbmFwc2hvdF8xLkNvbnRhaW5lclNuYXBzaG90Lm9mKHRoaXMuX2JpbmRpbmdEaWN0aW9uYXJ5LmNsb25lKCksIHRoaXMuX21pZGRsZXdhcmUpKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUucmVzdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNuYXBzaG90ID0gdGhpcy5fc25hcHNob3RzLnBvcCgpO1xuICAgICAgICBpZiAoc25hcHNob3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTk9fTU9SRV9TTkFQU0hPVFNfQVZBSUxBQkxFKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9iaW5kaW5nRGljdGlvbmFyeSA9IHNuYXBzaG90LmJpbmRpbmdzO1xuICAgICAgICB0aGlzLl9taWRkbGV3YXJlID0gc25hcHNob3QubWlkZGxld2FyZTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuY3JlYXRlQ2hpbGQgPSBmdW5jdGlvbiAoY29udGFpbmVyT3B0aW9ucykge1xuICAgICAgICB2YXIgY2hpbGQgPSBuZXcgQ29udGFpbmVyKGNvbnRhaW5lck9wdGlvbnMgfHwgdGhpcy5vcHRpb25zKTtcbiAgICAgICAgY2hpbGQucGFyZW50ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5hcHBseU1pZGRsZXdhcmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtaWRkbGV3YXJlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgbWlkZGxld2FyZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hcHBsaWVkTWlkZGxld2FyZSA9IHRoaXMuX2FwcGxpZWRNaWRkbGV3YXJlLmNvbmNhdChtaWRkbGV3YXJlcyk7XG4gICAgICAgIHZhciBpbml0aWFsID0gKHRoaXMuX21pZGRsZXdhcmUpID8gdGhpcy5fbWlkZGxld2FyZSA6IHRoaXMuX3BsYW5BbmRSZXNvbHZlKCk7XG4gICAgICAgIHRoaXMuX21pZGRsZXdhcmUgPSBtaWRkbGV3YXJlcy5yZWR1Y2UoZnVuY3Rpb24gKHByZXYsIGN1cnIpIHsgcmV0dXJuIGN1cnIocHJldik7IH0sIGluaXRpYWwpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5hcHBseUN1c3RvbU1ldGFkYXRhUmVhZGVyID0gZnVuY3Rpb24gKG1ldGFkYXRhUmVhZGVyKSB7XG4gICAgICAgIHRoaXMuX21ldGFkYXRhUmVhZGVyID0gbWV0YWRhdGFSZWFkZXI7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0KGZhbHNlLCBmYWxzZSwgbGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtLlZhcmlhYmxlLCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldFRhZ2dlZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0KGZhbHNlLCBmYWxzZSwgbGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtLlZhcmlhYmxlLCBzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSk7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldE5hbWVkID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyLCBuYW1lZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRUYWdnZWQoc2VydmljZUlkZW50aWZpZXIsIE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcsIG5hbWVkKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0QWxsID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXQodHJ1ZSwgdHJ1ZSwgbGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtLlZhcmlhYmxlLCBzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLmdldEFsbFRhZ2dlZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllciwga2V5LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0KGZhbHNlLCB0cnVlLCBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uVmFyaWFibGUsIHNlcnZpY2VJZGVudGlmaWVyLCBrZXksIHZhbHVlKTtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0QWxsTmFtZWQgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIsIG5hbWVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEFsbFRhZ2dlZChzZXJ2aWNlSWRlbnRpZmllciwgTUVUQURBVEFfS0VZLk5BTUVEX1RBRywgbmFtZWQpO1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5yZXNvbHZlID0gZnVuY3Rpb24gKGNvbnN0cnVjdG9yRnVuY3Rpb24pIHtcbiAgICAgICAgdmFyIHRlbXBDb250YWluZXIgPSB0aGlzLmNyZWF0ZUNoaWxkKCk7XG4gICAgICAgIHRlbXBDb250YWluZXIuYmluZChjb25zdHJ1Y3RvckZ1bmN0aW9uKS50b1NlbGYoKTtcbiAgICAgICAgdGhpcy5fYXBwbGllZE1pZGRsZXdhcmUuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgdGVtcENvbnRhaW5lci5hcHBseU1pZGRsZXdhcmUobSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGVtcENvbnRhaW5lci5nZXQoY29uc3RydWN0b3JGdW5jdGlvbik7XG4gICAgfTtcbiAgICBDb250YWluZXIucHJvdG90eXBlLl9nZXRDb250YWluZXJNb2R1bGVIZWxwZXJzRmFjdG9yeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIHNldE1vZHVsZUlkID0gZnVuY3Rpb24gKGJpbmRpbmdUb1N5bnRheCwgbW9kdWxlSWQpIHtcbiAgICAgICAgICAgIGJpbmRpbmdUb1N5bnRheC5fYmluZGluZy5tb2R1bGVJZCA9IG1vZHVsZUlkO1xuICAgICAgICB9O1xuICAgICAgICB2YXIgZ2V0QmluZEZ1bmN0aW9uID0gZnVuY3Rpb24gKG1vZHVsZUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9iaW5kID0gX3RoaXMuYmluZC5iaW5kKF90aGlzKTtcbiAgICAgICAgICAgICAgICB2YXIgYmluZGluZ1RvU3ludGF4ID0gX2JpbmQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgICAgIHNldE1vZHVsZUlkKGJpbmRpbmdUb1N5bnRheCwgbW9kdWxlSWQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5nVG9TeW50YXg7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgICB2YXIgZ2V0VW5iaW5kRnVuY3Rpb24gPSBmdW5jdGlvbiAobW9kdWxlSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgX3VuYmluZCA9IF90aGlzLnVuYmluZC5iaW5kKF90aGlzKTtcbiAgICAgICAgICAgICAgICBfdW5iaW5kKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIHZhciBnZXRJc2JvdW5kRnVuY3Rpb24gPSBmdW5jdGlvbiAobW9kdWxlSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2lzQm91bmQgPSBfdGhpcy5pc0JvdW5kLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBfaXNCb3VuZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgICB2YXIgZ2V0UmViaW5kRnVuY3Rpb24gPSBmdW5jdGlvbiAobW9kdWxlSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgX3JlYmluZCA9IF90aGlzLnJlYmluZC5iaW5kKF90aGlzKTtcbiAgICAgICAgICAgICAgICB2YXIgYmluZGluZ1RvU3ludGF4ID0gX3JlYmluZChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgc2V0TW9kdWxlSWQoYmluZGluZ1RvU3ludGF4LCBtb2R1bGVJZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpbmRpbmdUb1N5bnRheDtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAobUlkKSB7IHJldHVybiAoe1xuICAgICAgICAgICAgYmluZEZ1bmN0aW9uOiBnZXRCaW5kRnVuY3Rpb24obUlkKSxcbiAgICAgICAgICAgIGlzYm91bmRGdW5jdGlvbjogZ2V0SXNib3VuZEZ1bmN0aW9uKG1JZCksXG4gICAgICAgICAgICByZWJpbmRGdW5jdGlvbjogZ2V0UmViaW5kRnVuY3Rpb24obUlkKSxcbiAgICAgICAgICAgIHVuYmluZEZ1bmN0aW9uOiBnZXRVbmJpbmRGdW5jdGlvbihtSWQpXG4gICAgICAgIH0pOyB9O1xuICAgIH07XG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5fZ2V0ID0gZnVuY3Rpb24gKGF2b2lkQ29uc3RyYWludHMsIGlzTXVsdGlJbmplY3QsIHRhcmdldFR5cGUsIHNlcnZpY2VJZGVudGlmaWVyLCBrZXksIHZhbHVlKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgICB2YXIgZGVmYXVsdEFyZ3MgPSB7XG4gICAgICAgICAgICBhdm9pZENvbnN0cmFpbnRzOiBhdm9pZENvbnN0cmFpbnRzLFxuICAgICAgICAgICAgY29udGV4dEludGVyY2VwdG9yOiBmdW5jdGlvbiAoY29udGV4dCkgeyByZXR1cm4gY29udGV4dDsgfSxcbiAgICAgICAgICAgIGlzTXVsdGlJbmplY3Q6IGlzTXVsdGlJbmplY3QsXG4gICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgIHNlcnZpY2VJZGVudGlmaWVyOiBzZXJ2aWNlSWRlbnRpZmllcixcbiAgICAgICAgICAgIHRhcmdldFR5cGU6IHRhcmdldFR5cGUsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRoaXMuX21pZGRsZXdhcmUpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMuX21pZGRsZXdhcmUoZGVmYXVsdEFyZ3MpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLklOVkFMSURfTUlERExFV0FSRV9SRVRVUk4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fcGxhbkFuZFJlc29sdmUoKShkZWZhdWx0QXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICAgIENvbnRhaW5lci5wcm90b3R5cGUuX3BsYW5BbmRSZXNvbHZlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICAgICAgICAgIHZhciBjb250ZXh0ID0gcGxhbm5lcl8xLnBsYW4oX3RoaXMuX21ldGFkYXRhUmVhZGVyLCBfdGhpcywgYXJncy5pc011bHRpSW5qZWN0LCBhcmdzLnRhcmdldFR5cGUsIGFyZ3Muc2VydmljZUlkZW50aWZpZXIsIGFyZ3Mua2V5LCBhcmdzLnZhbHVlLCBhcmdzLmF2b2lkQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgY29udGV4dCA9IGFyZ3MuY29udGV4dEludGVyY2VwdG9yKGNvbnRleHQpO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHJlc29sdmVyXzEucmVzb2x2ZShjb250ZXh0KTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICByZXR1cm4gQ29udGFpbmVyO1xufSgpKTtcbmV4cG9ydHMuQ29udGFpbmVyID0gQ29udGFpbmVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udGFpbmVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5Bc3luY0NvbnRhaW5lck1vZHVsZSA9IGV4cG9ydHMuQ29udGFpbmVyTW9kdWxlID0gdm9pZCAwO1xudmFyIGlkXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvaWRcIik7XG52YXIgQ29udGFpbmVyTW9kdWxlID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBDb250YWluZXJNb2R1bGUocmVnaXN0cnkpIHtcbiAgICAgICAgdGhpcy5pZCA9IGlkXzEuaWQoKTtcbiAgICAgICAgdGhpcy5yZWdpc3RyeSA9IHJlZ2lzdHJ5O1xuICAgIH1cbiAgICByZXR1cm4gQ29udGFpbmVyTW9kdWxlO1xufSgpKTtcbmV4cG9ydHMuQ29udGFpbmVyTW9kdWxlID0gQ29udGFpbmVyTW9kdWxlO1xudmFyIEFzeW5jQ29udGFpbmVyTW9kdWxlID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBBc3luY0NvbnRhaW5lck1vZHVsZShyZWdpc3RyeSkge1xuICAgICAgICB0aGlzLmlkID0gaWRfMS5pZCgpO1xuICAgICAgICB0aGlzLnJlZ2lzdHJ5ID0gcmVnaXN0cnk7XG4gICAgfVxuICAgIHJldHVybiBBc3luY0NvbnRhaW5lck1vZHVsZTtcbn0oKSk7XG5leHBvcnRzLkFzeW5jQ29udGFpbmVyTW9kdWxlID0gQXN5bmNDb250YWluZXJNb2R1bGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb250YWluZXJfbW9kdWxlLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5Db250YWluZXJTbmFwc2hvdCA9IHZvaWQgMDtcbnZhciBDb250YWluZXJTbmFwc2hvdCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29udGFpbmVyU25hcHNob3QoKSB7XG4gICAgfVxuICAgIENvbnRhaW5lclNuYXBzaG90Lm9mID0gZnVuY3Rpb24gKGJpbmRpbmdzLCBtaWRkbGV3YXJlKSB7XG4gICAgICAgIHZhciBzbmFwc2hvdCA9IG5ldyBDb250YWluZXJTbmFwc2hvdCgpO1xuICAgICAgICBzbmFwc2hvdC5iaW5kaW5ncyA9IGJpbmRpbmdzO1xuICAgICAgICBzbmFwc2hvdC5taWRkbGV3YXJlID0gbWlkZGxld2FyZTtcbiAgICAgICAgcmV0dXJuIHNuYXBzaG90O1xuICAgIH07XG4gICAgcmV0dXJuIENvbnRhaW5lclNuYXBzaG90O1xufSgpKTtcbmV4cG9ydHMuQ29udGFpbmVyU25hcHNob3QgPSBDb250YWluZXJTbmFwc2hvdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnRhaW5lcl9zbmFwc2hvdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuTG9va3VwID0gdm9pZCAwO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgTG9va3VwID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBMb29rdXAoKSB7XG4gICAgICAgIHRoaXMuX21hcCA9IG5ldyBNYXAoKTtcbiAgICB9XG4gICAgTG9va3VwLnByb3RvdHlwZS5nZXRNYXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXA7XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllciwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSBudWxsIHx8IHNlcnZpY2VJZGVudGlmaWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLk5VTExfQVJHVU1FTlQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5OVUxMX0FSR1VNRU5UKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLl9tYXAuZ2V0KHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKGVudHJ5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGVudHJ5LnB1c2godmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5fbWFwLnNldChzZXJ2aWNlSWRlbnRpZmllciwgZW50cnkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fbWFwLnNldChzZXJ2aWNlSWRlbnRpZmllciwgW3ZhbHVlXSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIExvb2t1cC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIGlmIChzZXJ2aWNlSWRlbnRpZmllciA9PT0gbnVsbCB8fCBzZXJ2aWNlSWRlbnRpZmllciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5OVUxMX0FSR1VNRU5UKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLl9tYXAuZ2V0KHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKGVudHJ5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBlbnRyeTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLktFWV9OT1RfRk9VTkQpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBMb29rdXAucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgICAgICBpZiAoc2VydmljZUlkZW50aWZpZXIgPT09IG51bGwgfHwgc2VydmljZUlkZW50aWZpZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuTlVMTF9BUkdVTUVOVCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLl9tYXAuZGVsZXRlKHNlcnZpY2VJZGVudGlmaWVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuS0VZX05PVF9GT1VORCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIExvb2t1cC5wcm90b3R5cGUucmVtb3ZlQnlDb25kaXRpb24gPSBmdW5jdGlvbiAoY29uZGl0aW9uKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMuX21hcC5mb3JFYWNoKGZ1bmN0aW9uIChlbnRyaWVzLCBrZXkpIHtcbiAgICAgICAgICAgIHZhciB1cGRhdGVkRW50cmllcyA9IGVudHJpZXMuZmlsdGVyKGZ1bmN0aW9uIChlbnRyeSkgeyByZXR1cm4gIWNvbmRpdGlvbihlbnRyeSk7IH0pO1xuICAgICAgICAgICAgaWYgKHVwZGF0ZWRFbnRyaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5fbWFwLnNldChrZXksIHVwZGF0ZWRFbnRyaWVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIF90aGlzLl9tYXAuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgTG9va3VwLnByb3RvdHlwZS5oYXNLZXkgPSBmdW5jdGlvbiAoc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSBudWxsIHx8IHNlcnZpY2VJZGVudGlmaWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFUlJPUl9NU0dTLk5VTExfQVJHVU1FTlQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuaGFzKHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICB9O1xuICAgIExvb2t1cC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb3B5ID0gbmV3IExvb2t1cCgpO1xuICAgICAgICB0aGlzLl9tYXAuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICAgICAgdmFsdWUuZm9yRWFjaChmdW5jdGlvbiAoYikgeyByZXR1cm4gY29weS5hZGQoa2V5LCBiLmNsb25lKCkpOyB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjb3B5O1xuICAgIH07XG4gICAgTG9va3VwLnByb3RvdHlwZS50cmF2ZXJzZSA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gICAgICAgIHRoaXMuX21hcC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICBmdW5jKGtleSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIHJldHVybiBMb29rdXA7XG59KCkpO1xuZXhwb3J0cy5Mb29rdXAgPSBMb29rdXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sb29rdXAuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLm11bHRpQmluZFRvU2VydmljZSA9IGV4cG9ydHMuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyA9IGV4cG9ydHMudHlwZUNvbnN0cmFpbnQgPSBleHBvcnRzLm5hbWVkQ29uc3RyYWludCA9IGV4cG9ydHMudGFnZ2VkQ29uc3RyYWludCA9IGV4cG9ydHMudHJhdmVyc2VBbmNlcnN0b3JzID0gZXhwb3J0cy5kZWNvcmF0ZSA9IGV4cG9ydHMuaWQgPSBleHBvcnRzLk1ldGFkYXRhUmVhZGVyID0gZXhwb3J0cy5wb3N0Q29uc3RydWN0ID0gZXhwb3J0cy50YXJnZXROYW1lID0gZXhwb3J0cy5tdWx0aUluamVjdCA9IGV4cG9ydHMudW5tYW5hZ2VkID0gZXhwb3J0cy5vcHRpb25hbCA9IGV4cG9ydHMuTGF6eVNlcnZpY2VJZGVudGlmZXIgPSBleHBvcnRzLmluamVjdCA9IGV4cG9ydHMubmFtZWQgPSBleHBvcnRzLnRhZ2dlZCA9IGV4cG9ydHMuaW5qZWN0YWJsZSA9IGV4cG9ydHMuQ29udGFpbmVyTW9kdWxlID0gZXhwb3J0cy5Bc3luY0NvbnRhaW5lck1vZHVsZSA9IGV4cG9ydHMuVGFyZ2V0VHlwZUVudW0gPSBleHBvcnRzLkJpbmRpbmdUeXBlRW51bSA9IGV4cG9ydHMuQmluZGluZ1Njb3BlRW51bSA9IGV4cG9ydHMuQ29udGFpbmVyID0gZXhwb3J0cy5NRVRBREFUQV9LRVkgPSB2b2lkIDA7XG52YXIga2V5cyA9IHJlcXVpcmUoXCIuL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xuZXhwb3J0cy5NRVRBREFUQV9LRVkgPSBrZXlzO1xudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyL2NvbnRhaW5lclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNvbnRhaW5lclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29udGFpbmVyXzEuQ29udGFpbmVyOyB9IH0pO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQmluZGluZ1Njb3BlRW51bVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW07IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJCaW5kaW5nVHlwZUVudW1cIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW07IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJUYXJnZXRUeXBlRW51bVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbGl0ZXJhbF90eXBlc18xLlRhcmdldFR5cGVFbnVtOyB9IH0pO1xudmFyIGNvbnRhaW5lcl9tb2R1bGVfMSA9IHJlcXVpcmUoXCIuL2NvbnRhaW5lci9jb250YWluZXJfbW9kdWxlXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQXN5bmNDb250YWluZXJNb2R1bGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbnRhaW5lcl9tb2R1bGVfMS5Bc3luY0NvbnRhaW5lck1vZHVsZTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkNvbnRhaW5lck1vZHVsZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29udGFpbmVyX21vZHVsZV8xLkNvbnRhaW5lck1vZHVsZTsgfSB9KTtcbnZhciBpbmplY3RhYmxlXzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL2luamVjdGFibGVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpbmplY3RhYmxlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpbmplY3RhYmxlXzEuaW5qZWN0YWJsZTsgfSB9KTtcbnZhciB0YWdnZWRfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vdGFnZ2VkXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidGFnZ2VkXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0YWdnZWRfMS50YWdnZWQ7IH0gfSk7XG52YXIgbmFtZWRfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vbmFtZWRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJuYW1lZFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbmFtZWRfMS5uYW1lZDsgfSB9KTtcbnZhciBpbmplY3RfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vaW5qZWN0XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiaW5qZWN0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpbmplY3RfMS5pbmplY3Q7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJMYXp5U2VydmljZUlkZW50aWZlclwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaW5qZWN0XzEuTGF6eVNlcnZpY2VJZGVudGlmZXI7IH0gfSk7XG52YXIgb3B0aW9uYWxfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vb3B0aW9uYWxcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJvcHRpb25hbFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gb3B0aW9uYWxfMS5vcHRpb25hbDsgfSB9KTtcbnZhciB1bm1hbmFnZWRfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vdW5tYW5hZ2VkXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidW5tYW5hZ2VkXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB1bm1hbmFnZWRfMS51bm1hbmFnZWQ7IH0gfSk7XG52YXIgbXVsdGlfaW5qZWN0XzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL211bHRpX2luamVjdFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm11bHRpSW5qZWN0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBtdWx0aV9pbmplY3RfMS5tdWx0aUluamVjdDsgfSB9KTtcbnZhciB0YXJnZXRfbmFtZV8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi90YXJnZXRfbmFtZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInRhcmdldE5hbWVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRhcmdldF9uYW1lXzEudGFyZ2V0TmFtZTsgfSB9KTtcbnZhciBwb3N0X2NvbnN0cnVjdF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9wb3N0X2NvbnN0cnVjdFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInBvc3RDb25zdHJ1Y3RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHBvc3RfY29uc3RydWN0XzEucG9zdENvbnN0cnVjdDsgfSB9KTtcbnZhciBtZXRhZGF0YV9yZWFkZXJfMSA9IHJlcXVpcmUoXCIuL3BsYW5uaW5nL21ldGFkYXRhX3JlYWRlclwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIk1ldGFkYXRhUmVhZGVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBtZXRhZGF0YV9yZWFkZXJfMS5NZXRhZGF0YVJlYWRlcjsgfSB9KTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4vdXRpbHMvaWRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpZFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gaWRfMS5pZDsgfSB9KTtcbnZhciBkZWNvcmF0b3JfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vZGVjb3JhdG9yX3V0aWxzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiZGVjb3JhdGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRlY29yYXRvcl91dGlsc18xLmRlY29yYXRlOyB9IH0pO1xudmFyIGNvbnN0cmFpbnRfaGVscGVyc18xID0gcmVxdWlyZShcIi4vc3ludGF4L2NvbnN0cmFpbnRfaGVscGVyc1wiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInRyYXZlcnNlQW5jZXJzdG9yc1wiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidGFnZ2VkQ29uc3RyYWludFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudGFnZ2VkQ29uc3RyYWludDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm5hbWVkQ29uc3RyYWludFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEubmFtZWRDb25zdHJhaW50OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidHlwZUNvbnN0cmFpbnRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbnN0cmFpbnRfaGVscGVyc18xLnR5cGVDb25zdHJhaW50OyB9IH0pO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuL3V0aWxzL3NlcmlhbGl6YXRpb25cIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzZXJpYWxpemF0aW9uXzEuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZzsgfSB9KTtcbnZhciBiaW5kaW5nX3V0aWxzXzEgPSByZXF1aXJlKFwiLi91dGlscy9iaW5kaW5nX3V0aWxzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibXVsdGlCaW5kVG9TZXJ2aWNlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBiaW5kaW5nX3V0aWxzXzEubXVsdGlCaW5kVG9TZXJ2aWNlOyB9IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW52ZXJzaWZ5LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5Db250ZXh0ID0gdm9pZCAwO1xudmFyIGlkXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvaWRcIik7XG52YXIgQ29udGV4dCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29udGV4dChjb250YWluZXIpIHtcbiAgICAgICAgdGhpcy5pZCA9IGlkXzEuaWQoKTtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgfVxuICAgIENvbnRleHQucHJvdG90eXBlLmFkZFBsYW4gPSBmdW5jdGlvbiAocGxhbikge1xuICAgICAgICB0aGlzLnBsYW4gPSBwbGFuO1xuICAgIH07XG4gICAgQ29udGV4dC5wcm90b3R5cGUuc2V0Q3VycmVudFJlcXVlc3QgPSBmdW5jdGlvbiAoY3VycmVudFJlcXVlc3QpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50UmVxdWVzdCA9IGN1cnJlbnRSZXF1ZXN0O1xuICAgIH07XG4gICAgcmV0dXJuIENvbnRleHQ7XG59KCkpO1xuZXhwb3J0cy5Db250ZXh0ID0gQ29udGV4dDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnRleHQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLk1ldGFkYXRhID0gdm9pZCAwO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBNZXRhZGF0YSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTWV0YWRhdGEoa2V5LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLmtleSA9IGtleTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgICBNZXRhZGF0YS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmtleSA9PT0gTUVUQURBVEFfS0VZLk5BTUVEX1RBRykge1xuICAgICAgICAgICAgcmV0dXJuIFwibmFtZWQ6IFwiICsgdGhpcy52YWx1ZS50b1N0cmluZygpICsgXCIgXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gXCJ0YWdnZWQ6IHsga2V5OlwiICsgdGhpcy5rZXkudG9TdHJpbmcoKSArIFwiLCB2YWx1ZTogXCIgKyB0aGlzLnZhbHVlICsgXCIgfVwiO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gTWV0YWRhdGE7XG59KCkpO1xuZXhwb3J0cy5NZXRhZGF0YSA9IE1ldGFkYXRhO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWV0YWRhdGEuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLk1ldGFkYXRhUmVhZGVyID0gdm9pZCAwO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBNZXRhZGF0YVJlYWRlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTWV0YWRhdGFSZWFkZXIoKSB7XG4gICAgfVxuICAgIE1ldGFkYXRhUmVhZGVyLnByb3RvdHlwZS5nZXRDb25zdHJ1Y3Rvck1ldGFkYXRhID0gZnVuY3Rpb24gKGNvbnN0cnVjdG9yRnVuYykge1xuICAgICAgICB2YXIgY29tcGlsZXJHZW5lcmF0ZWRNZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoTUVUQURBVEFfS0VZLlBBUkFNX1RZUEVTLCBjb25zdHJ1Y3RvckZ1bmMpO1xuICAgICAgICB2YXIgdXNlckdlbmVyYXRlZE1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShNRVRBREFUQV9LRVkuVEFHR0VELCBjb25zdHJ1Y3RvckZ1bmMpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29tcGlsZXJHZW5lcmF0ZWRNZXRhZGF0YTogY29tcGlsZXJHZW5lcmF0ZWRNZXRhZGF0YSxcbiAgICAgICAgICAgIHVzZXJHZW5lcmF0ZWRNZXRhZGF0YTogdXNlckdlbmVyYXRlZE1ldGFkYXRhIHx8IHt9XG4gICAgICAgIH07XG4gICAgfTtcbiAgICBNZXRhZGF0YVJlYWRlci5wcm90b3R5cGUuZ2V0UHJvcGVydGllc01ldGFkYXRhID0gZnVuY3Rpb24gKGNvbnN0cnVjdG9yRnVuYykge1xuICAgICAgICB2YXIgdXNlckdlbmVyYXRlZE1ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShNRVRBREFUQV9LRVkuVEFHR0VEX1BST1AsIGNvbnN0cnVjdG9yRnVuYykgfHwgW107XG4gICAgICAgIHJldHVybiB1c2VyR2VuZXJhdGVkTWV0YWRhdGE7XG4gICAgfTtcbiAgICByZXR1cm4gTWV0YWRhdGFSZWFkZXI7XG59KCkpO1xuZXhwb3J0cy5NZXRhZGF0YVJlYWRlciA9IE1ldGFkYXRhUmVhZGVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWV0YWRhdGFfcmVhZGVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5QbGFuID0gdm9pZCAwO1xudmFyIFBsYW4gPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFBsYW4ocGFyZW50Q29udGV4dCwgcm9vdFJlcXVlc3QpIHtcbiAgICAgICAgdGhpcy5wYXJlbnRDb250ZXh0ID0gcGFyZW50Q29udGV4dDtcbiAgICAgICAgdGhpcy5yb290UmVxdWVzdCA9IHJvb3RSZXF1ZXN0O1xuICAgIH1cbiAgICByZXR1cm4gUGxhbjtcbn0oKSk7XG5leHBvcnRzLlBsYW4gPSBQbGFuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGxhbi5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0QmluZGluZ0RpY3Rpb25hcnkgPSBleHBvcnRzLmNyZWF0ZU1vY2tSZXF1ZXN0ID0gZXhwb3J0cy5wbGFuID0gdm9pZCAwO1xudmFyIGJpbmRpbmdfY291bnRfMSA9IHJlcXVpcmUoXCIuLi9iaW5kaW5ncy9iaW5kaW5nX2NvdW50XCIpO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBleGNlcHRpb25zXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvZXhjZXB0aW9uc1wiKTtcbnZhciBzZXJpYWxpemF0aW9uXzEgPSByZXF1aXJlKFwiLi4vdXRpbHMvc2VyaWFsaXphdGlvblwiKTtcbnZhciBjb250ZXh0XzEgPSByZXF1aXJlKFwiLi9jb250ZXh0XCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi9tZXRhZGF0YVwiKTtcbnZhciBwbGFuXzEgPSByZXF1aXJlKFwiLi9wbGFuXCIpO1xudmFyIHJlZmxlY3Rpb25fdXRpbHNfMSA9IHJlcXVpcmUoXCIuL3JlZmxlY3Rpb25fdXRpbHNcIik7XG52YXIgcmVxdWVzdF8xID0gcmVxdWlyZShcIi4vcmVxdWVzdFwiKTtcbnZhciB0YXJnZXRfMSA9IHJlcXVpcmUoXCIuL3RhcmdldFwiKTtcbmZ1bmN0aW9uIGdldEJpbmRpbmdEaWN0aW9uYXJ5KGNudG5yKSB7XG4gICAgcmV0dXJuIGNudG5yLl9iaW5kaW5nRGljdGlvbmFyeTtcbn1cbmV4cG9ydHMuZ2V0QmluZGluZ0RpY3Rpb25hcnkgPSBnZXRCaW5kaW5nRGljdGlvbmFyeTtcbmZ1bmN0aW9uIF9jcmVhdGVUYXJnZXQoaXNNdWx0aUluamVjdCwgdGFyZ2V0VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIG5hbWUsIGtleSwgdmFsdWUpIHtcbiAgICB2YXIgbWV0YWRhdGFLZXkgPSBpc011bHRpSW5qZWN0ID8gTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUcgOiBNRVRBREFUQV9LRVkuSU5KRUNUX1RBRztcbiAgICB2YXIgaW5qZWN0TWV0YWRhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShtZXRhZGF0YUtleSwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgIHZhciB0YXJnZXQgPSBuZXcgdGFyZ2V0XzEuVGFyZ2V0KHRhcmdldFR5cGUsIG5hbWUsIHNlcnZpY2VJZGVudGlmaWVyLCBpbmplY3RNZXRhZGF0YSk7XG4gICAgaWYgKGtleSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciB0YWdNZXRhZGF0YSA9IG5ldyBtZXRhZGF0YV8xLk1ldGFkYXRhKGtleSwgdmFsdWUpO1xuICAgICAgICB0YXJnZXQubWV0YWRhdGEucHVzaCh0YWdNZXRhZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXQ7XG59XG5mdW5jdGlvbiBfZ2V0QWN0aXZlQmluZGluZ3MobWV0YWRhdGFSZWFkZXIsIGF2b2lkQ29uc3RyYWludHMsIGNvbnRleHQsIHBhcmVudFJlcXVlc3QsIHRhcmdldCkge1xuICAgIHZhciBiaW5kaW5ncyA9IGdldEJpbmRpbmdzKGNvbnRleHQuY29udGFpbmVyLCB0YXJnZXQuc2VydmljZUlkZW50aWZpZXIpO1xuICAgIHZhciBhY3RpdmVCaW5kaW5ncyA9IFtdO1xuICAgIGlmIChiaW5kaW5ncy5sZW5ndGggPT09IGJpbmRpbmdfY291bnRfMS5CaW5kaW5nQ291bnQuTm9CaW5kaW5nc0F2YWlsYWJsZSAmJlxuICAgICAgICBjb250ZXh0LmNvbnRhaW5lci5vcHRpb25zLmF1dG9CaW5kSW5qZWN0YWJsZSAmJlxuICAgICAgICB0eXBlb2YgdGFyZ2V0LnNlcnZpY2VJZGVudGlmaWVyID09PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgbWV0YWRhdGFSZWFkZXIuZ2V0Q29uc3RydWN0b3JNZXRhZGF0YSh0YXJnZXQuc2VydmljZUlkZW50aWZpZXIpLmNvbXBpbGVyR2VuZXJhdGVkTWV0YWRhdGEpIHtcbiAgICAgICAgY29udGV4dC5jb250YWluZXIuYmluZCh0YXJnZXQuc2VydmljZUlkZW50aWZpZXIpLnRvU2VsZigpO1xuICAgICAgICBiaW5kaW5ncyA9IGdldEJpbmRpbmdzKGNvbnRleHQuY29udGFpbmVyLCB0YXJnZXQuc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH1cbiAgICBpZiAoIWF2b2lkQ29uc3RyYWludHMpIHtcbiAgICAgICAgYWN0aXZlQmluZGluZ3MgPSBiaW5kaW5ncy5maWx0ZXIoZnVuY3Rpb24gKGJpbmRpbmcpIHtcbiAgICAgICAgICAgIHZhciByZXF1ZXN0ID0gbmV3IHJlcXVlc3RfMS5SZXF1ZXN0KGJpbmRpbmcuc2VydmljZUlkZW50aWZpZXIsIGNvbnRleHQsIHBhcmVudFJlcXVlc3QsIGJpbmRpbmcsIHRhcmdldCk7XG4gICAgICAgICAgICByZXR1cm4gYmluZGluZy5jb25zdHJhaW50KHJlcXVlc3QpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGFjdGl2ZUJpbmRpbmdzID0gYmluZGluZ3M7XG4gICAgfVxuICAgIF92YWxpZGF0ZUFjdGl2ZUJpbmRpbmdDb3VudCh0YXJnZXQuc2VydmljZUlkZW50aWZpZXIsIGFjdGl2ZUJpbmRpbmdzLCB0YXJnZXQsIGNvbnRleHQuY29udGFpbmVyKTtcbiAgICByZXR1cm4gYWN0aXZlQmluZGluZ3M7XG59XG5mdW5jdGlvbiBfdmFsaWRhdGVBY3RpdmVCaW5kaW5nQ291bnQoc2VydmljZUlkZW50aWZpZXIsIGJpbmRpbmdzLCB0YXJnZXQsIGNvbnRhaW5lcikge1xuICAgIHN3aXRjaCAoYmluZGluZ3MubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgYmluZGluZ19jb3VudF8xLkJpbmRpbmdDb3VudC5Ob0JpbmRpbmdzQXZhaWxhYmxlOlxuICAgICAgICAgICAgaWYgKHRhcmdldC5pc09wdGlvbmFsKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ3M7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXJTdHJpbmcgPSBzZXJpYWxpemF0aW9uXzEuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgdmFyIG1zZyA9IEVSUk9SX01TR1MuTk9UX1JFR0lTVEVSRUQ7XG4gICAgICAgICAgICAgICAgbXNnICs9IHNlcmlhbGl6YXRpb25fMS5saXN0TWV0YWRhdGFGb3JUYXJnZXQoc2VydmljZUlkZW50aWZpZXJTdHJpbmcsIHRhcmdldCk7XG4gICAgICAgICAgICAgICAgbXNnICs9IHNlcmlhbGl6YXRpb25fMS5saXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXIoY29udGFpbmVyLCBzZXJ2aWNlSWRlbnRpZmllclN0cmluZywgZ2V0QmluZGluZ3MpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICBjYXNlIGJpbmRpbmdfY291bnRfMS5CaW5kaW5nQ291bnQuT25seU9uZUJpbmRpbmdBdmFpbGFibGU6XG4gICAgICAgICAgICBpZiAoIXRhcmdldC5pc0FycmF5KCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ3M7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgYmluZGluZ19jb3VudF8xLkJpbmRpbmdDb3VudC5NdWx0aXBsZUJpbmRpbmdzQXZhaWxhYmxlOlxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgaWYgKCF0YXJnZXQuaXNBcnJheSgpKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nID0gc2VyaWFsaXphdGlvbl8xLmdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcoc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICAgICAgICAgIHZhciBtc2cgPSBFUlJPUl9NU0dTLkFNQklHVU9VU19NQVRDSCArIFwiIFwiICsgc2VydmljZUlkZW50aWZpZXJTdHJpbmc7XG4gICAgICAgICAgICAgICAgbXNnICs9IHNlcmlhbGl6YXRpb25fMS5saXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXIoY29udGFpbmVyLCBzZXJ2aWNlSWRlbnRpZmllclN0cmluZywgZ2V0QmluZGluZ3MpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpbmRpbmdzO1xuICAgICAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIF9jcmVhdGVTdWJSZXF1ZXN0cyhtZXRhZGF0YVJlYWRlciwgYXZvaWRDb25zdHJhaW50cywgc2VydmljZUlkZW50aWZpZXIsIGNvbnRleHQsIHBhcmVudFJlcXVlc3QsIHRhcmdldCkge1xuICAgIHZhciBhY3RpdmVCaW5kaW5ncztcbiAgICB2YXIgY2hpbGRSZXF1ZXN0O1xuICAgIGlmIChwYXJlbnRSZXF1ZXN0ID09PSBudWxsKSB7XG4gICAgICAgIGFjdGl2ZUJpbmRpbmdzID0gX2dldEFjdGl2ZUJpbmRpbmdzKG1ldGFkYXRhUmVhZGVyLCBhdm9pZENvbnN0cmFpbnRzLCBjb250ZXh0LCBudWxsLCB0YXJnZXQpO1xuICAgICAgICBjaGlsZFJlcXVlc3QgPSBuZXcgcmVxdWVzdF8xLlJlcXVlc3Qoc2VydmljZUlkZW50aWZpZXIsIGNvbnRleHQsIG51bGwsIGFjdGl2ZUJpbmRpbmdzLCB0YXJnZXQpO1xuICAgICAgICB2YXIgdGhlUGxhbiA9IG5ldyBwbGFuXzEuUGxhbihjb250ZXh0LCBjaGlsZFJlcXVlc3QpO1xuICAgICAgICBjb250ZXh0LmFkZFBsYW4odGhlUGxhbik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBhY3RpdmVCaW5kaW5ncyA9IF9nZXRBY3RpdmVCaW5kaW5ncyhtZXRhZGF0YVJlYWRlciwgYXZvaWRDb25zdHJhaW50cywgY29udGV4dCwgcGFyZW50UmVxdWVzdCwgdGFyZ2V0KTtcbiAgICAgICAgY2hpbGRSZXF1ZXN0ID0gcGFyZW50UmVxdWVzdC5hZGRDaGlsZFJlcXVlc3QodGFyZ2V0LnNlcnZpY2VJZGVudGlmaWVyLCBhY3RpdmVCaW5kaW5ncywgdGFyZ2V0KTtcbiAgICB9XG4gICAgYWN0aXZlQmluZGluZ3MuZm9yRWFjaChmdW5jdGlvbiAoYmluZGluZykge1xuICAgICAgICB2YXIgc3ViQ2hpbGRSZXF1ZXN0ID0gbnVsbDtcbiAgICAgICAgaWYgKHRhcmdldC5pc0FycmF5KCkpIHtcbiAgICAgICAgICAgIHN1YkNoaWxkUmVxdWVzdCA9IGNoaWxkUmVxdWVzdC5hZGRDaGlsZFJlcXVlc3QoYmluZGluZy5zZXJ2aWNlSWRlbnRpZmllciwgYmluZGluZywgdGFyZ2V0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChiaW5kaW5nLmNhY2hlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3ViQ2hpbGRSZXF1ZXN0ID0gY2hpbGRSZXF1ZXN0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChiaW5kaW5nLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uSW5zdGFuY2UgJiYgYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBkZXBlbmRlbmNpZXMgPSByZWZsZWN0aW9uX3V0aWxzXzEuZ2V0RGVwZW5kZW5jaWVzKG1ldGFkYXRhUmVhZGVyLCBiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSk7XG4gICAgICAgICAgICBpZiAoIWNvbnRleHQuY29udGFpbmVyLm9wdGlvbnMuc2tpcEJhc2VDbGFzc0NoZWNrcykge1xuICAgICAgICAgICAgICAgIHZhciBiYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQgPSByZWZsZWN0aW9uX3V0aWxzXzEuZ2V0QmFzZUNsYXNzRGVwZW5kZW5jeUNvdW50KG1ldGFkYXRhUmVhZGVyLCBiaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSk7XG4gICAgICAgICAgICAgICAgaWYgKGRlcGVuZGVuY2llcy5sZW5ndGggPCBiYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gRVJST1JfTVNHUy5BUkdVTUVOVFNfTEVOR1RIX01JU01BVENIKHJlZmxlY3Rpb25fdXRpbHNfMS5nZXRGdW5jdGlvbk5hbWUoYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUpKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZXBlbmRlbmNpZXMuZm9yRWFjaChmdW5jdGlvbiAoZGVwZW5kZW5jeSkge1xuICAgICAgICAgICAgICAgIF9jcmVhdGVTdWJSZXF1ZXN0cyhtZXRhZGF0YVJlYWRlciwgZmFsc2UsIGRlcGVuZGVuY3kuc2VydmljZUlkZW50aWZpZXIsIGNvbnRleHQsIHN1YkNoaWxkUmVxdWVzdCwgZGVwZW5kZW5jeSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gZ2V0QmluZGluZ3MoY29udGFpbmVyLCBzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgIHZhciBiaW5kaW5ncyA9IFtdO1xuICAgIHZhciBiaW5kaW5nRGljdGlvbmFyeSA9IGdldEJpbmRpbmdEaWN0aW9uYXJ5KGNvbnRhaW5lcik7XG4gICAgaWYgKGJpbmRpbmdEaWN0aW9uYXJ5Lmhhc0tleShzZXJ2aWNlSWRlbnRpZmllcikpIHtcbiAgICAgICAgYmluZGluZ3MgPSBiaW5kaW5nRGljdGlvbmFyeS5nZXQoc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb250YWluZXIucGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgIGJpbmRpbmdzID0gZ2V0QmluZGluZ3MoY29udGFpbmVyLnBhcmVudCwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgIH1cbiAgICByZXR1cm4gYmluZGluZ3M7XG59XG5mdW5jdGlvbiBwbGFuKG1ldGFkYXRhUmVhZGVyLCBjb250YWluZXIsIGlzTXVsdGlJbmplY3QsIHRhcmdldFR5cGUsIHNlcnZpY2VJZGVudGlmaWVyLCBrZXksIHZhbHVlLCBhdm9pZENvbnN0cmFpbnRzKSB7XG4gICAgaWYgKGF2b2lkQ29uc3RyYWludHMgPT09IHZvaWQgMCkgeyBhdm9pZENvbnN0cmFpbnRzID0gZmFsc2U7IH1cbiAgICB2YXIgY29udGV4dCA9IG5ldyBjb250ZXh0XzEuQ29udGV4dChjb250YWluZXIpO1xuICAgIHZhciB0YXJnZXQgPSBfY3JlYXRlVGFyZ2V0KGlzTXVsdGlJbmplY3QsIHRhcmdldFR5cGUsIHNlcnZpY2VJZGVudGlmaWVyLCBcIlwiLCBrZXksIHZhbHVlKTtcbiAgICB0cnkge1xuICAgICAgICBfY3JlYXRlU3ViUmVxdWVzdHMobWV0YWRhdGFSZWFkZXIsIGF2b2lkQ29uc3RyYWludHMsIHNlcnZpY2VJZGVudGlmaWVyLCBjb250ZXh0LCBudWxsLCB0YXJnZXQpO1xuICAgICAgICByZXR1cm4gY29udGV4dDtcbiAgICB9XG4gICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChleGNlcHRpb25zXzEuaXNTdGFja092ZXJmbG93RXhlcHRpb24oZXJyb3IpKSB7XG4gICAgICAgICAgICBpZiAoY29udGV4dC5wbGFuKSB7XG4gICAgICAgICAgICAgICAgc2VyaWFsaXphdGlvbl8xLmNpcmN1bGFyRGVwZW5kZW5jeVRvRXhjZXB0aW9uKGNvbnRleHQucGxhbi5yb290UmVxdWVzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxufVxuZXhwb3J0cy5wbGFuID0gcGxhbjtcbmZ1bmN0aW9uIGNyZWF0ZU1vY2tSZXF1ZXN0KGNvbnRhaW5lciwgc2VydmljZUlkZW50aWZpZXIsIGtleSwgdmFsdWUpIHtcbiAgICB2YXIgdGFyZ2V0ID0gbmV3IHRhcmdldF8xLlRhcmdldChsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uVmFyaWFibGUsIFwiXCIsIHNlcnZpY2VJZGVudGlmaWVyLCBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShrZXksIHZhbHVlKSk7XG4gICAgdmFyIGNvbnRleHQgPSBuZXcgY29udGV4dF8xLkNvbnRleHQoY29udGFpbmVyKTtcbiAgICB2YXIgcmVxdWVzdCA9IG5ldyByZXF1ZXN0XzEuUmVxdWVzdChzZXJ2aWNlSWRlbnRpZmllciwgY29udGV4dCwgbnVsbCwgW10sIHRhcmdldCk7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG59XG5leHBvcnRzLmNyZWF0ZU1vY2tSZXF1ZXN0ID0gY3JlYXRlTW9ja1JlcXVlc3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wbGFubmVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5RdWVyeWFibGVTdHJpbmcgPSB2b2lkIDA7XG52YXIgUXVlcnlhYmxlU3RyaW5nID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBRdWVyeWFibGVTdHJpbmcoc3RyKSB7XG4gICAgICAgIHRoaXMuc3RyID0gc3RyO1xuICAgIH1cbiAgICBRdWVyeWFibGVTdHJpbmcucHJvdG90eXBlLnN0YXJ0c1dpdGggPSBmdW5jdGlvbiAoc2VhcmNoU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0ci5pbmRleE9mKHNlYXJjaFN0cmluZykgPT09IDA7XG4gICAgfTtcbiAgICBRdWVyeWFibGVTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoID0gZnVuY3Rpb24gKHNlYXJjaFN0cmluZykge1xuICAgICAgICB2YXIgcmV2ZXJzZVN0cmluZyA9IFwiXCI7XG4gICAgICAgIHZhciByZXZlcnNlU2VhcmNoU3RyaW5nID0gc2VhcmNoU3RyaW5nLnNwbGl0KFwiXCIpLnJldmVyc2UoKS5qb2luKFwiXCIpO1xuICAgICAgICByZXZlcnNlU3RyaW5nID0gdGhpcy5zdHIuc3BsaXQoXCJcIikucmV2ZXJzZSgpLmpvaW4oXCJcIik7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXJ0c1dpdGguY2FsbCh7IHN0cjogcmV2ZXJzZVN0cmluZyB9LCByZXZlcnNlU2VhcmNoU3RyaW5nKTtcbiAgICB9O1xuICAgIFF1ZXJ5YWJsZVN0cmluZy5wcm90b3R5cGUuY29udGFpbnMgPSBmdW5jdGlvbiAoc2VhcmNoU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiAodGhpcy5zdHIuaW5kZXhPZihzZWFyY2hTdHJpbmcpICE9PSAtMSk7XG4gICAgfTtcbiAgICBRdWVyeWFibGVTdHJpbmcucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChjb21wYXJlU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0ciA9PT0gY29tcGFyZVN0cmluZztcbiAgICB9O1xuICAgIFF1ZXJ5YWJsZVN0cmluZy5wcm90b3R5cGUudmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0cjtcbiAgICB9O1xuICAgIHJldHVybiBRdWVyeWFibGVTdHJpbmc7XG59KCkpO1xuZXhwb3J0cy5RdWVyeWFibGVTdHJpbmcgPSBRdWVyeWFibGVTdHJpbmc7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1xdWVyeWFibGVfc3RyaW5nLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIF9fc3ByZWFkQXJyYXkgPSAodGhpcyAmJiB0aGlzLl9fc3ByZWFkQXJyYXkpIHx8IGZ1bmN0aW9uICh0bywgZnJvbSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBpbCA9IGZyb20ubGVuZ3RoLCBqID0gdG8ubGVuZ3RoOyBpIDwgaWw7IGkrKywgaisrKVxuICAgICAgICB0b1tqXSA9IGZyb21baV07XG4gICAgcmV0dXJuIHRvO1xufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZ2V0RnVuY3Rpb25OYW1lID0gZXhwb3J0cy5nZXRCYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQgPSBleHBvcnRzLmdldERlcGVuZGVuY2llcyA9IHZvaWQgMDtcbnZhciBpbmplY3RfMSA9IHJlcXVpcmUoXCIuLi9hbm5vdGF0aW9uL2luamVjdFwiKTtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbGl0ZXJhbF90eXBlc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG52YXIgc2VyaWFsaXphdGlvbl8xID0gcmVxdWlyZShcIi4uL3V0aWxzL3NlcmlhbGl6YXRpb25cIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJnZXRGdW5jdGlvbk5hbWVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlcmlhbGl6YXRpb25fMS5nZXRGdW5jdGlvbk5hbWU7IH0gfSk7XG52YXIgdGFyZ2V0XzEgPSByZXF1aXJlKFwiLi90YXJnZXRcIik7XG5mdW5jdGlvbiBnZXREZXBlbmRlbmNpZXMobWV0YWRhdGFSZWFkZXIsIGZ1bmMpIHtcbiAgICB2YXIgY29uc3RydWN0b3JOYW1lID0gc2VyaWFsaXphdGlvbl8xLmdldEZ1bmN0aW9uTmFtZShmdW5jKTtcbiAgICB2YXIgdGFyZ2V0cyA9IGdldFRhcmdldHMobWV0YWRhdGFSZWFkZXIsIGNvbnN0cnVjdG9yTmFtZSwgZnVuYywgZmFsc2UpO1xuICAgIHJldHVybiB0YXJnZXRzO1xufVxuZXhwb3J0cy5nZXREZXBlbmRlbmNpZXMgPSBnZXREZXBlbmRlbmNpZXM7XG5mdW5jdGlvbiBnZXRUYXJnZXRzKG1ldGFkYXRhUmVhZGVyLCBjb25zdHJ1Y3Rvck5hbWUsIGZ1bmMsIGlzQmFzZUNsYXNzKSB7XG4gICAgdmFyIG1ldGFkYXRhID0gbWV0YWRhdGFSZWFkZXIuZ2V0Q29uc3RydWN0b3JNZXRhZGF0YShmdW5jKTtcbiAgICB2YXIgc2VydmljZUlkZW50aWZpZXJzID0gbWV0YWRhdGEuY29tcGlsZXJHZW5lcmF0ZWRNZXRhZGF0YTtcbiAgICBpZiAoc2VydmljZUlkZW50aWZpZXJzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIG1zZyA9IEVSUk9SX01TR1MuTUlTU0lOR19JTkpFQ1RBQkxFX0FOTk9UQVRJT04gKyBcIiBcIiArIGNvbnN0cnVjdG9yTmFtZSArIFwiLlwiO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICB9XG4gICAgdmFyIGNvbnN0cnVjdG9yQXJnc01ldGFkYXRhID0gbWV0YWRhdGEudXNlckdlbmVyYXRlZE1ldGFkYXRhO1xuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoY29uc3RydWN0b3JBcmdzTWV0YWRhdGEpO1xuICAgIHZhciBoYXNVc2VyRGVjbGFyZWRVbmtub3duSW5qZWN0aW9ucyA9IChmdW5jLmxlbmd0aCA9PT0gMCAmJiBrZXlzLmxlbmd0aCA+IDApO1xuICAgIHZhciBoYXNPcHRpb25hbFBhcmFtZXRlcnMgPSBrZXlzLmxlbmd0aCA+IGZ1bmMubGVuZ3RoO1xuICAgIHZhciBpdGVyYXRpb25zID0gKGhhc1VzZXJEZWNsYXJlZFVua25vd25JbmplY3Rpb25zIHx8IGhhc09wdGlvbmFsUGFyYW1ldGVycykgPyBrZXlzLmxlbmd0aCA6IGZ1bmMubGVuZ3RoO1xuICAgIHZhciBjb25zdHJ1Y3RvclRhcmdldHMgPSBnZXRDb25zdHJ1Y3RvckFyZ3NBc1RhcmdldHMoaXNCYXNlQ2xhc3MsIGNvbnN0cnVjdG9yTmFtZSwgc2VydmljZUlkZW50aWZpZXJzLCBjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YSwgaXRlcmF0aW9ucyk7XG4gICAgdmFyIHByb3BlcnR5VGFyZ2V0cyA9IGdldENsYXNzUHJvcHNBc1RhcmdldHMobWV0YWRhdGFSZWFkZXIsIGZ1bmMpO1xuICAgIHZhciB0YXJnZXRzID0gX19zcHJlYWRBcnJheShfX3NwcmVhZEFycmF5KFtdLCBjb25zdHJ1Y3RvclRhcmdldHMpLCBwcm9wZXJ0eVRhcmdldHMpO1xuICAgIHJldHVybiB0YXJnZXRzO1xufVxuZnVuY3Rpb24gZ2V0Q29uc3RydWN0b3JBcmdzQXNUYXJnZXQoaW5kZXgsIGlzQmFzZUNsYXNzLCBjb25zdHJ1Y3Rvck5hbWUsIHNlcnZpY2VJZGVudGlmaWVycywgY29uc3RydWN0b3JBcmdzTWV0YWRhdGEpIHtcbiAgICB2YXIgdGFyZ2V0TWV0YWRhdGEgPSBjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YVtpbmRleC50b1N0cmluZygpXSB8fCBbXTtcbiAgICB2YXIgbWV0YWRhdGEgPSBmb3JtYXRUYXJnZXRNZXRhZGF0YSh0YXJnZXRNZXRhZGF0YSk7XG4gICAgdmFyIGlzTWFuYWdlZCA9IG1ldGFkYXRhLnVubWFuYWdlZCAhPT0gdHJ1ZTtcbiAgICB2YXIgc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcnNbaW5kZXhdO1xuICAgIHZhciBpbmplY3RJZGVudGlmaWVyID0gKG1ldGFkYXRhLmluamVjdCB8fCBtZXRhZGF0YS5tdWx0aUluamVjdCk7XG4gICAgc2VydmljZUlkZW50aWZpZXIgPSAoaW5qZWN0SWRlbnRpZmllcikgPyAoaW5qZWN0SWRlbnRpZmllcikgOiBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICBpZiAoc2VydmljZUlkZW50aWZpZXIgaW5zdGFuY2VvZiBpbmplY3RfMS5MYXp5U2VydmljZUlkZW50aWZlcikge1xuICAgICAgICBzZXJ2aWNlSWRlbnRpZmllciA9IHNlcnZpY2VJZGVudGlmaWVyLnVud3JhcCgpO1xuICAgIH1cbiAgICBpZiAoaXNNYW5hZ2VkKSB7XG4gICAgICAgIHZhciBpc09iamVjdCA9IHNlcnZpY2VJZGVudGlmaWVyID09PSBPYmplY3Q7XG4gICAgICAgIHZhciBpc0Z1bmN0aW9uID0gc2VydmljZUlkZW50aWZpZXIgPT09IEZ1bmN0aW9uO1xuICAgICAgICB2YXIgaXNVbmRlZmluZWQgPSBzZXJ2aWNlSWRlbnRpZmllciA9PT0gdW5kZWZpbmVkO1xuICAgICAgICB2YXIgaXNVbmtub3duVHlwZSA9IChpc09iamVjdCB8fCBpc0Z1bmN0aW9uIHx8IGlzVW5kZWZpbmVkKTtcbiAgICAgICAgaWYgKCFpc0Jhc2VDbGFzcyAmJiBpc1Vua25vd25UeXBlKSB7XG4gICAgICAgICAgICB2YXIgbXNnID0gRVJST1JfTVNHUy5NSVNTSU5HX0lOSkVDVF9BTk5PVEFUSU9OICsgXCIgYXJndW1lbnQgXCIgKyBpbmRleCArIFwiIGluIGNsYXNzIFwiICsgY29uc3RydWN0b3JOYW1lICsgXCIuXCI7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGFyZ2V0ID0gbmV3IHRhcmdldF8xLlRhcmdldChsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uQ29uc3RydWN0b3JBcmd1bWVudCwgbWV0YWRhdGEudGFyZ2V0TmFtZSwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICB0YXJnZXQubWV0YWRhdGEgPSB0YXJnZXRNZXRhZGF0YTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBnZXRDb25zdHJ1Y3RvckFyZ3NBc1RhcmdldHMoaXNCYXNlQ2xhc3MsIGNvbnN0cnVjdG9yTmFtZSwgc2VydmljZUlkZW50aWZpZXJzLCBjb25zdHJ1Y3RvckFyZ3NNZXRhZGF0YSwgaXRlcmF0aW9ucykge1xuICAgIHZhciB0YXJnZXRzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVyYXRpb25zOyBpKyspIHtcbiAgICAgICAgdmFyIGluZGV4ID0gaTtcbiAgICAgICAgdmFyIHRhcmdldCA9IGdldENvbnN0cnVjdG9yQXJnc0FzVGFyZ2V0KGluZGV4LCBpc0Jhc2VDbGFzcywgY29uc3RydWN0b3JOYW1lLCBzZXJ2aWNlSWRlbnRpZmllcnMsIGNvbnN0cnVjdG9yQXJnc01ldGFkYXRhKTtcbiAgICAgICAgaWYgKHRhcmdldCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGFyZ2V0cy5wdXNoKHRhcmdldCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldHM7XG59XG5mdW5jdGlvbiBnZXRDbGFzc1Byb3BzQXNUYXJnZXRzKG1ldGFkYXRhUmVhZGVyLCBjb25zdHJ1Y3RvckZ1bmMpIHtcbiAgICB2YXIgY2xhc3NQcm9wc01ldGFkYXRhID0gbWV0YWRhdGFSZWFkZXIuZ2V0UHJvcGVydGllc01ldGFkYXRhKGNvbnN0cnVjdG9yRnVuYyk7XG4gICAgdmFyIHRhcmdldHMgPSBbXTtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGNsYXNzUHJvcHNNZXRhZGF0YSk7XG4gICAgZm9yICh2YXIgX2kgPSAwLCBrZXlzXzEgPSBrZXlzOyBfaSA8IGtleXNfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNfMVtfaV07XG4gICAgICAgIHZhciB0YXJnZXRNZXRhZGF0YSA9IGNsYXNzUHJvcHNNZXRhZGF0YVtrZXldO1xuICAgICAgICB2YXIgbWV0YWRhdGEgPSBmb3JtYXRUYXJnZXRNZXRhZGF0YShjbGFzc1Byb3BzTWV0YWRhdGFba2V5XSk7XG4gICAgICAgIHZhciB0YXJnZXROYW1lID0gbWV0YWRhdGEudGFyZ2V0TmFtZSB8fCBrZXk7XG4gICAgICAgIHZhciBzZXJ2aWNlSWRlbnRpZmllciA9IChtZXRhZGF0YS5pbmplY3QgfHwgbWV0YWRhdGEubXVsdGlJbmplY3QpO1xuICAgICAgICB2YXIgdGFyZ2V0ID0gbmV3IHRhcmdldF8xLlRhcmdldChsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uQ2xhc3NQcm9wZXJ0eSwgdGFyZ2V0TmFtZSwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICB0YXJnZXQubWV0YWRhdGEgPSB0YXJnZXRNZXRhZGF0YTtcbiAgICAgICAgdGFyZ2V0cy5wdXNoKHRhcmdldCk7XG4gICAgfVxuICAgIHZhciBiYXNlQ29uc3RydWN0b3IgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY29uc3RydWN0b3JGdW5jLnByb3RvdHlwZSkuY29uc3RydWN0b3I7XG4gICAgaWYgKGJhc2VDb25zdHJ1Y3RvciAhPT0gT2JqZWN0KSB7XG4gICAgICAgIHZhciBiYXNlVGFyZ2V0cyA9IGdldENsYXNzUHJvcHNBc1RhcmdldHMobWV0YWRhdGFSZWFkZXIsIGJhc2VDb25zdHJ1Y3Rvcik7XG4gICAgICAgIHRhcmdldHMgPSBfX3NwcmVhZEFycmF5KF9fc3ByZWFkQXJyYXkoW10sIHRhcmdldHMpLCBiYXNlVGFyZ2V0cyk7XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXRzO1xufVxuZnVuY3Rpb24gZ2V0QmFzZUNsYXNzRGVwZW5kZW5jeUNvdW50KG1ldGFkYXRhUmVhZGVyLCBmdW5jKSB7XG4gICAgdmFyIGJhc2VDb25zdHJ1Y3RvciA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihmdW5jLnByb3RvdHlwZSkuY29uc3RydWN0b3I7XG4gICAgaWYgKGJhc2VDb25zdHJ1Y3RvciAhPT0gT2JqZWN0KSB7XG4gICAgICAgIHZhciBiYXNlQ29uc3RydWN0b3JOYW1lID0gc2VyaWFsaXphdGlvbl8xLmdldEZ1bmN0aW9uTmFtZShiYXNlQ29uc3RydWN0b3IpO1xuICAgICAgICB2YXIgdGFyZ2V0cyA9IGdldFRhcmdldHMobWV0YWRhdGFSZWFkZXIsIGJhc2VDb25zdHJ1Y3Rvck5hbWUsIGJhc2VDb25zdHJ1Y3RvciwgdHJ1ZSk7XG4gICAgICAgIHZhciBtZXRhZGF0YSA9IHRhcmdldHMubWFwKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgICByZXR1cm4gdC5tZXRhZGF0YS5maWx0ZXIoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbS5rZXkgPT09IE1FVEFEQVRBX0tFWS5VTk1BTkFHRURfVEFHO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgdW5tYW5hZ2VkQ291bnQgPSBbXS5jb25jYXQuYXBwbHkoW10sIG1ldGFkYXRhKS5sZW5ndGg7XG4gICAgICAgIHZhciBkZXBlbmRlbmN5Q291bnQgPSB0YXJnZXRzLmxlbmd0aCAtIHVubWFuYWdlZENvdW50O1xuICAgICAgICBpZiAoZGVwZW5kZW5jeUNvdW50ID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGRlcGVuZGVuY3lDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRCYXNlQ2xhc3NEZXBlbmRlbmN5Q291bnQobWV0YWRhdGFSZWFkZXIsIGJhc2VDb25zdHJ1Y3Rvcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbn1cbmV4cG9ydHMuZ2V0QmFzZUNsYXNzRGVwZW5kZW5jeUNvdW50ID0gZ2V0QmFzZUNsYXNzRGVwZW5kZW5jeUNvdW50O1xuZnVuY3Rpb24gZm9ybWF0VGFyZ2V0TWV0YWRhdGEodGFyZ2V0TWV0YWRhdGEpIHtcbiAgICB2YXIgdGFyZ2V0TWV0YWRhdGFNYXAgPSB7fTtcbiAgICB0YXJnZXRNZXRhZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgIHRhcmdldE1ldGFkYXRhTWFwW20ua2V5LnRvU3RyaW5nKCldID0gbS52YWx1ZTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgICBpbmplY3Q6IHRhcmdldE1ldGFkYXRhTWFwW01FVEFEQVRBX0tFWS5JTkpFQ1RfVEFHXSxcbiAgICAgICAgbXVsdGlJbmplY3Q6IHRhcmdldE1ldGFkYXRhTWFwW01FVEFEQVRBX0tFWS5NVUxUSV9JTkpFQ1RfVEFHXSxcbiAgICAgICAgdGFyZ2V0TmFtZTogdGFyZ2V0TWV0YWRhdGFNYXBbTUVUQURBVEFfS0VZLk5BTUVfVEFHXSxcbiAgICAgICAgdW5tYW5hZ2VkOiB0YXJnZXRNZXRhZGF0YU1hcFtNRVRBREFUQV9LRVkuVU5NQU5BR0VEX1RBR11cbiAgICB9O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVmbGVjdGlvbl91dGlscy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuUmVxdWVzdCA9IHZvaWQgMDtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIFJlcXVlc3QgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFJlcXVlc3Qoc2VydmljZUlkZW50aWZpZXIsIHBhcmVudENvbnRleHQsIHBhcmVudFJlcXVlc3QsIGJpbmRpbmdzLCB0YXJnZXQpIHtcbiAgICAgICAgdGhpcy5pZCA9IGlkXzEuaWQoKTtcbiAgICAgICAgdGhpcy5zZXJ2aWNlSWRlbnRpZmllciA9IHNlcnZpY2VJZGVudGlmaWVyO1xuICAgICAgICB0aGlzLnBhcmVudENvbnRleHQgPSBwYXJlbnRDb250ZXh0O1xuICAgICAgICB0aGlzLnBhcmVudFJlcXVlc3QgPSBwYXJlbnRSZXF1ZXN0O1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy5jaGlsZFJlcXVlc3RzID0gW107XG4gICAgICAgIHRoaXMuYmluZGluZ3MgPSAoQXJyYXkuaXNBcnJheShiaW5kaW5ncykgPyBiaW5kaW5ncyA6IFtiaW5kaW5nc10pO1xuICAgICAgICB0aGlzLnJlcXVlc3RTY29wZSA9IHBhcmVudFJlcXVlc3QgPT09IG51bGxcbiAgICAgICAgICAgID8gbmV3IE1hcCgpXG4gICAgICAgICAgICA6IG51bGw7XG4gICAgfVxuICAgIFJlcXVlc3QucHJvdG90eXBlLmFkZENoaWxkUmVxdWVzdCA9IGZ1bmN0aW9uIChzZXJ2aWNlSWRlbnRpZmllciwgYmluZGluZ3MsIHRhcmdldCkge1xuICAgICAgICB2YXIgY2hpbGQgPSBuZXcgUmVxdWVzdChzZXJ2aWNlSWRlbnRpZmllciwgdGhpcy5wYXJlbnRDb250ZXh0LCB0aGlzLCBiaW5kaW5ncywgdGFyZ2V0KTtcbiAgICAgICAgdGhpcy5jaGlsZFJlcXVlc3RzLnB1c2goY2hpbGQpO1xuICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgfTtcbiAgICByZXR1cm4gUmVxdWVzdDtcbn0oKSk7XG5leHBvcnRzLlJlcXVlc3QgPSBSZXF1ZXN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVxdWVzdC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuVGFyZ2V0ID0gdm9pZCAwO1xudmFyIE1FVEFEQVRBX0tFWSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbWV0YWRhdGFfa2V5c1wiKTtcbnZhciBpZF8xID0gcmVxdWlyZShcIi4uL3V0aWxzL2lkXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi9tZXRhZGF0YVwiKTtcbnZhciBxdWVyeWFibGVfc3RyaW5nXzEgPSByZXF1aXJlKFwiLi9xdWVyeWFibGVfc3RyaW5nXCIpO1xudmFyIFRhcmdldCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gVGFyZ2V0KHR5cGUsIG5hbWUsIHNlcnZpY2VJZGVudGlmaWVyLCBuYW1lZE9yVGFnZ2VkKSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZF8xLmlkKCk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuc2VydmljZUlkZW50aWZpZXIgPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgdGhpcy5uYW1lID0gbmV3IHF1ZXJ5YWJsZV9zdHJpbmdfMS5RdWVyeWFibGVTdHJpbmcobmFtZSB8fCBcIlwiKTtcbiAgICAgICAgdGhpcy5tZXRhZGF0YSA9IG5ldyBBcnJheSgpO1xuICAgICAgICB2YXIgbWV0YWRhdGFJdGVtID0gbnVsbDtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lZE9yVGFnZ2VkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBtZXRhZGF0YUl0ZW0gPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShNRVRBREFUQV9LRVkuTkFNRURfVEFHLCBuYW1lZE9yVGFnZ2VkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lZE9yVGFnZ2VkIGluc3RhbmNlb2YgbWV0YWRhdGFfMS5NZXRhZGF0YSkge1xuICAgICAgICAgICAgbWV0YWRhdGFJdGVtID0gbmFtZWRPclRhZ2dlZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGFJdGVtICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhLnB1c2gobWV0YWRhdGFJdGVtKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBUYXJnZXQucHJvdG90eXBlLmhhc1RhZyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMubWV0YWRhdGE7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgbSA9IF9hW19pXTtcbiAgICAgICAgICAgIGlmIChtLmtleSA9PT0ga2V5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5pc0FycmF5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNUYWcoTUVUQURBVEFfS0VZLk1VTFRJX0lOSkVDVF9UQUcpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5tYXRjaGVzQXJyYXkgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaGVzVGFnKE1FVEFEQVRBX0tFWS5NVUxUSV9JTkpFQ1RfVEFHKShuYW1lKTtcbiAgICB9O1xuICAgIFRhcmdldC5wcm90b3R5cGUuaXNOYW1lZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzVGFnKE1FVEFEQVRBX0tFWS5OQU1FRF9UQUcpO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5pc1RhZ2dlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGEuc29tZShmdW5jdGlvbiAobWV0YWRhdGEpIHsgcmV0dXJuIE1FVEFEQVRBX0tFWS5OT05fQ1VTVE9NX1RBR19LRVlTLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIG1ldGFkYXRhLmtleSAhPT0ga2V5OyB9KTsgfSk7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLmlzT3B0aW9uYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hdGNoZXNUYWcoTUVUQURBVEFfS0VZLk9QVElPTkFMX1RBRykodHJ1ZSk7XG4gICAgfTtcbiAgICBUYXJnZXQucHJvdG90eXBlLmdldE5hbWVkVGFnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5pc05hbWVkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhLmZpbHRlcihmdW5jdGlvbiAobSkgeyByZXR1cm4gbS5rZXkgPT09IE1FVEFEQVRBX0tFWS5OQU1FRF9UQUc7IH0pWzBdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgVGFyZ2V0LnByb3RvdHlwZS5nZXRDdXN0b21UYWdzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5pc1RhZ2dlZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YS5maWx0ZXIoZnVuY3Rpb24gKG1ldGFkYXRhKSB7IHJldHVybiBNRVRBREFUQV9LRVkuTk9OX0NVU1RPTV9UQUdfS0VZUy5ldmVyeShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBtZXRhZGF0YS5rZXkgIT09IGtleTsgfSk7IH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRhcmdldC5wcm90b3R5cGUubWF0Y2hlc05hbWVkVGFnID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2hlc1RhZyhNRVRBREFUQV9LRVkuTkFNRURfVEFHKShuYW1lKTtcbiAgICB9O1xuICAgIFRhcmdldC5wcm90b3R5cGUubWF0Y2hlc1RhZyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IF90aGlzLm1ldGFkYXRhOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHZhciBtID0gX2FbX2ldO1xuICAgICAgICAgICAgICAgIGlmIChtLmtleSA9PT0ga2V5ICYmIG0udmFsdWUgPT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBUYXJnZXQ7XG59KCkpO1xuZXhwb3J0cy5UYXJnZXQgPSBUYXJnZXQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10YXJnZXQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19zcHJlYWRBcnJheSA9ICh0aGlzICYmIHRoaXMuX19zcHJlYWRBcnJheSkgfHwgZnVuY3Rpb24gKHRvLCBmcm9tKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGlsID0gZnJvbS5sZW5ndGgsIGogPSB0by5sZW5ndGg7IGkgPCBpbDsgaSsrLCBqKyspXG4gICAgICAgIHRvW2pdID0gZnJvbVtpXTtcbiAgICByZXR1cm4gdG87XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5yZXNvbHZlSW5zdGFuY2UgPSB2b2lkIDA7XG52YXIgZXJyb3JfbXNnc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbGl0ZXJhbF90eXBlc1wiKTtcbnZhciBNRVRBREFUQV9LRVkgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG5mdW5jdGlvbiBfaW5qZWN0UHJvcGVydGllcyhpbnN0YW5jZSwgY2hpbGRSZXF1ZXN0cywgcmVzb2x2ZVJlcXVlc3QpIHtcbiAgICB2YXIgcHJvcGVydHlJbmplY3Rpb25zUmVxdWVzdHMgPSBjaGlsZFJlcXVlc3RzLmZpbHRlcihmdW5jdGlvbiAoY2hpbGRSZXF1ZXN0KSB7XG4gICAgICAgIHJldHVybiAoY2hpbGRSZXF1ZXN0LnRhcmdldCAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgY2hpbGRSZXF1ZXN0LnRhcmdldC50eXBlID09PSBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uQ2xhc3NQcm9wZXJ0eSk7XG4gICAgfSk7XG4gICAgdmFyIHByb3BlcnR5SW5qZWN0aW9ucyA9IHByb3BlcnR5SW5qZWN0aW9uc1JlcXVlc3RzLm1hcChyZXNvbHZlUmVxdWVzdCk7XG4gICAgcHJvcGVydHlJbmplY3Rpb25zUmVxdWVzdHMuZm9yRWFjaChmdW5jdGlvbiAociwgaW5kZXgpIHtcbiAgICAgICAgdmFyIHByb3BlcnR5TmFtZSA9IFwiXCI7XG4gICAgICAgIHByb3BlcnR5TmFtZSA9IHIudGFyZ2V0Lm5hbWUudmFsdWUoKTtcbiAgICAgICAgdmFyIGluamVjdGlvbiA9IHByb3BlcnR5SW5qZWN0aW9uc1tpbmRleF07XG4gICAgICAgIGluc3RhbmNlW3Byb3BlcnR5TmFtZV0gPSBpbmplY3Rpb247XG4gICAgfSk7XG4gICAgcmV0dXJuIGluc3RhbmNlO1xufVxuZnVuY3Rpb24gX2NyZWF0ZUluc3RhbmNlKEZ1bmMsIGluamVjdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IChGdW5jLmJpbmQuYXBwbHkoRnVuYywgX19zcHJlYWRBcnJheShbdm9pZCAwXSwgaW5qZWN0aW9ucykpKSgpO1xufVxuZnVuY3Rpb24gX3Bvc3RDb25zdHJ1Y3QoY29uc3RyLCByZXN1bHQpIHtcbiAgICBpZiAoUmVmbGVjdC5oYXNNZXRhZGF0YShNRVRBREFUQV9LRVkuUE9TVF9DT05TVFJVQ1QsIGNvbnN0cikpIHtcbiAgICAgICAgdmFyIGRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKE1FVEFEQVRBX0tFWS5QT1NUX0NPTlNUUlVDVCwgY29uc3RyKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3VsdFtkYXRhLnZhbHVlXSgpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JfbXNnc18xLlBPU1RfQ09OU1RSVUNUX0VSUk9SKGNvbnN0ci5uYW1lLCBlLm1lc3NhZ2UpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIHJlc29sdmVJbnN0YW5jZShjb25zdHIsIGNoaWxkUmVxdWVzdHMsIHJlc29sdmVSZXF1ZXN0KSB7XG4gICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgaWYgKGNoaWxkUmVxdWVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICB2YXIgY29uc3RydWN0b3JJbmplY3Rpb25zUmVxdWVzdHMgPSBjaGlsZFJlcXVlc3RzLmZpbHRlcihmdW5jdGlvbiAoY2hpbGRSZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gKGNoaWxkUmVxdWVzdC50YXJnZXQgIT09IG51bGwgJiYgY2hpbGRSZXF1ZXN0LnRhcmdldC50eXBlID09PSBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW0uQ29uc3RydWN0b3JBcmd1bWVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgY29uc3RydWN0b3JJbmplY3Rpb25zID0gY29uc3RydWN0b3JJbmplY3Rpb25zUmVxdWVzdHMubWFwKHJlc29sdmVSZXF1ZXN0KTtcbiAgICAgICAgcmVzdWx0ID0gX2NyZWF0ZUluc3RhbmNlKGNvbnN0ciwgY29uc3RydWN0b3JJbmplY3Rpb25zKTtcbiAgICAgICAgcmVzdWx0ID0gX2luamVjdFByb3BlcnRpZXMocmVzdWx0LCBjaGlsZFJlcXVlc3RzLCByZXNvbHZlUmVxdWVzdCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXN1bHQgPSBuZXcgY29uc3RyKCk7XG4gICAgfVxuICAgIF9wb3N0Q29uc3RydWN0KGNvbnN0ciwgcmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZXhwb3J0cy5yZXNvbHZlSW5zdGFuY2UgPSByZXNvbHZlSW5zdGFuY2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnN0YW50aWF0aW9uLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5yZXNvbHZlID0gdm9pZCAwO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIGV4Y2VwdGlvbnNfMSA9IHJlcXVpcmUoXCIuLi91dGlscy9leGNlcHRpb25zXCIpO1xudmFyIHNlcmlhbGl6YXRpb25fMSA9IHJlcXVpcmUoXCIuLi91dGlscy9zZXJpYWxpemF0aW9uXCIpO1xudmFyIGluc3RhbnRpYXRpb25fMSA9IHJlcXVpcmUoXCIuL2luc3RhbnRpYXRpb25cIik7XG52YXIgaW52b2tlRmFjdG9yeSA9IGZ1bmN0aW9uIChmYWN0b3J5VHlwZSwgc2VydmljZUlkZW50aWZpZXIsIGZuKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGZuKCk7XG4gICAgfVxuICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoZXhjZXB0aW9uc18xLmlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uKGVycm9yKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuQ0lSQ1VMQVJfREVQRU5ERU5DWV9JTl9GQUNUT1JZKGZhY3RvcnlUeXBlLCBzZXJ2aWNlSWRlbnRpZmllci50b1N0cmluZygpKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbn07XG52YXIgX3Jlc29sdmVSZXF1ZXN0ID0gZnVuY3Rpb24gKHJlcXVlc3RTY29wZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICByZXF1ZXN0LnBhcmVudENvbnRleHQuc2V0Q3VycmVudFJlcXVlc3QocmVxdWVzdCk7XG4gICAgICAgIHZhciBiaW5kaW5ncyA9IHJlcXVlc3QuYmluZGluZ3M7XG4gICAgICAgIHZhciBjaGlsZFJlcXVlc3RzID0gcmVxdWVzdC5jaGlsZFJlcXVlc3RzO1xuICAgICAgICB2YXIgdGFyZ2V0SXNBbkFycmF5ID0gcmVxdWVzdC50YXJnZXQgJiYgcmVxdWVzdC50YXJnZXQuaXNBcnJheSgpO1xuICAgICAgICB2YXIgdGFyZ2V0UGFyZW50SXNOb3RBbkFycmF5ID0gIXJlcXVlc3QucGFyZW50UmVxdWVzdCB8fFxuICAgICAgICAgICAgIXJlcXVlc3QucGFyZW50UmVxdWVzdC50YXJnZXQgfHxcbiAgICAgICAgICAgICFyZXF1ZXN0LnRhcmdldCB8fFxuICAgICAgICAgICAgIXJlcXVlc3QucGFyZW50UmVxdWVzdC50YXJnZXQubWF0Y2hlc0FycmF5KHJlcXVlc3QudGFyZ2V0LnNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKHRhcmdldElzQW5BcnJheSAmJiB0YXJnZXRQYXJlbnRJc05vdEFuQXJyYXkpIHtcbiAgICAgICAgICAgIHJldHVybiBjaGlsZFJlcXVlc3RzLm1hcChmdW5jdGlvbiAoY2hpbGRSZXF1ZXN0KSB7XG4gICAgICAgICAgICAgICAgdmFyIF9mID0gX3Jlc29sdmVSZXF1ZXN0KHJlcXVlc3RTY29wZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9mKGNoaWxkUmVxdWVzdCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgICAgICAgaWYgKHJlcXVlc3QudGFyZ2V0LmlzT3B0aW9uYWwoKSAmJiBiaW5kaW5ncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGJpbmRpbmdfMSA9IGJpbmRpbmdzWzBdO1xuICAgICAgICAgICAgdmFyIGlzU2luZ2xldG9uID0gYmluZGluZ18xLnNjb3BlID09PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgICAgICB2YXIgaXNSZXF1ZXN0U2luZ2xldG9uID0gYmluZGluZ18xLnNjb3BlID09PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5SZXF1ZXN0O1xuICAgICAgICAgICAgaWYgKGlzU2luZ2xldG9uICYmIGJpbmRpbmdfMS5hY3RpdmF0ZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZ18xLmNhY2hlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzUmVxdWVzdFNpbmdsZXRvbiAmJlxuICAgICAgICAgICAgICAgIHJlcXVlc3RTY29wZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgIHJlcXVlc3RTY29wZS5oYXMoYmluZGluZ18xLmlkKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXF1ZXN0U2NvcGUuZ2V0KGJpbmRpbmdfMS5pZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uQ29uc3RhbnRWYWx1ZSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGJpbmRpbmdfMS5jYWNoZTtcbiAgICAgICAgICAgICAgICBiaW5kaW5nXzEuYWN0aXZhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGJpbmRpbmdfMS50eXBlID09PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkZ1bmN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYmluZGluZ18xLmNhY2hlO1xuICAgICAgICAgICAgICAgIGJpbmRpbmdfMS5hY3RpdmF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uQ29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBiaW5kaW5nXzEuaW1wbGVtZW50YXRpb25UeXBlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRHluYW1pY1ZhbHVlICYmIGJpbmRpbmdfMS5keW5hbWljVmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBpbnZva2VGYWN0b3J5KFwidG9EeW5hbWljVmFsdWVcIiwgYmluZGluZ18xLnNlcnZpY2VJZGVudGlmaWVyLCBmdW5jdGlvbiAoKSB7IHJldHVybiBiaW5kaW5nXzEuZHluYW1pY1ZhbHVlKHJlcXVlc3QucGFyZW50Q29udGV4dCk7IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRmFjdG9yeSAmJiBiaW5kaW5nXzEuZmFjdG9yeSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGludm9rZUZhY3RvcnkoXCJ0b0ZhY3RvcnlcIiwgYmluZGluZ18xLnNlcnZpY2VJZGVudGlmaWVyLCBmdW5jdGlvbiAoKSB7IHJldHVybiBiaW5kaW5nXzEuZmFjdG9yeShyZXF1ZXN0LnBhcmVudENvbnRleHQpOyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGJpbmRpbmdfMS50eXBlID09PSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLlByb3ZpZGVyICYmIGJpbmRpbmdfMS5wcm92aWRlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGludm9rZUZhY3RvcnkoXCJ0b1Byb3ZpZGVyXCIsIGJpbmRpbmdfMS5zZXJ2aWNlSWRlbnRpZmllciwgZnVuY3Rpb24gKCkgeyByZXR1cm4gYmluZGluZ18xLnByb3ZpZGVyKHJlcXVlc3QucGFyZW50Q29udGV4dCk7IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYmluZGluZ18xLnR5cGUgPT09IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uSW5zdGFuY2UgJiYgYmluZGluZ18xLmltcGxlbWVudGF0aW9uVHlwZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGluc3RhbnRpYXRpb25fMS5yZXNvbHZlSW5zdGFuY2UoYmluZGluZ18xLmltcGxlbWVudGF0aW9uVHlwZSwgY2hpbGRSZXF1ZXN0cywgX3Jlc29sdmVSZXF1ZXN0KHJlcXVlc3RTY29wZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlcnZpY2VJZGVudGlmaWVyID0gc2VyaWFsaXphdGlvbl8xLmdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcocmVxdWVzdC5zZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuSU5WQUxJRF9CSU5ESU5HX1RZUEUgKyBcIiBcIiArIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmluZGluZ18xLm9uQWN0aXZhdGlvbiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYmluZGluZ18xLm9uQWN0aXZhdGlvbihyZXF1ZXN0LnBhcmVudENvbnRleHQsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNTaW5nbGV0b24pIHtcbiAgICAgICAgICAgICAgICBiaW5kaW5nXzEuY2FjaGUgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgYmluZGluZ18xLmFjdGl2YXRlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNSZXF1ZXN0U2luZ2xldG9uICYmXG4gICAgICAgICAgICAgICAgcmVxdWVzdFNjb3BlICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgIXJlcXVlc3RTY29wZS5oYXMoYmluZGluZ18xLmlkKSkge1xuICAgICAgICAgICAgICAgIHJlcXVlc3RTY29wZS5zZXQoYmluZGluZ18xLmlkLCByZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuZnVuY3Rpb24gcmVzb2x2ZShjb250ZXh0KSB7XG4gICAgdmFyIF9mID0gX3Jlc29sdmVSZXF1ZXN0KGNvbnRleHQucGxhbi5yb290UmVxdWVzdC5yZXF1ZXN0U2NvcGUpO1xuICAgIHJldHVybiBfZihjb250ZXh0LnBsYW4ucm9vdFJlcXVlc3QpO1xufVxuZXhwb3J0cy5yZXNvbHZlID0gcmVzb2x2ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlc29sdmVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CaW5kaW5nSW5TeW50YXggPSB2b2lkIDA7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9saXRlcmFsX3R5cGVzXCIpO1xudmFyIGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfd2hlbl9vbl9zeW50YXhcIik7XG52YXIgQmluZGluZ0luU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nSW5TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICB9XG4gICAgQmluZGluZ0luU3ludGF4LnByb3RvdHlwZS5pblJlcXVlc3RTY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlJlcXVlc3Q7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5TeW50YXgucHJvdG90eXBlLmluU2luZ2xldG9uU2NvcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5TeW50YXgucHJvdG90eXBlLmluVHJhbnNpZW50U2NvcGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5UcmFuc2llbnQ7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ0luU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ0luU3ludGF4ID0gQmluZGluZ0luU3ludGF4O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmluZGluZ19pbl9zeW50YXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJpbmRpbmdJbldoZW5PblN5bnRheCA9IHZvaWQgMDtcbnZhciBiaW5kaW5nX2luX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ19pbl9zeW50YXhcIik7XG52YXIgYmluZGluZ19vbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfb25fc3ludGF4XCIpO1xudmFyIGJpbmRpbmdfd2hlbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfd2hlbl9zeW50YXhcIik7XG52YXIgQmluZGluZ0luV2hlbk9uU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nSW5XaGVuT25TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICAgICAgdGhpcy5fYmluZGluZ1doZW5TeW50YXggPSBuZXcgYmluZGluZ193aGVuX3N5bnRheF8xLkJpbmRpbmdXaGVuU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgICAgICB0aGlzLl9iaW5kaW5nT25TeW50YXggPSBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmdJblN5bnRheCA9IG5ldyBiaW5kaW5nX2luX3N5bnRheF8xLkJpbmRpbmdJblN5bnRheChiaW5kaW5nKTtcbiAgICB9XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS5pblJlcXVlc3RTY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdJblN5bnRheC5pblJlcXVlc3RTY29wZSgpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS5pblNpbmdsZXRvblNjb3BlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ0luU3ludGF4LmluU2luZ2xldG9uU2NvcGUoKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUuaW5UcmFuc2llbnRTY29wZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdJblN5bnRheC5pblRyYW5zaWVudFNjb3BlKCk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW4gPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbihjb25zdHJhaW50KTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldE5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5UYXJnZXROYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldElzRGVmYXVsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5UYXJnZXRJc0RlZmF1bHQoKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldFRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuVGFyZ2V0VGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuSW5qZWN0ZWRJbnRvID0gZnVuY3Rpb24gKHBhcmVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkluamVjdGVkSW50byhwYXJlbnQpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblBhcmVudE5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50VGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5QYXJlbnRUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3RvcklzID0gZnVuY3Rpb24gKGFuY2VzdG9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JJcyhhbmNlc3Rvcik7XG4gICAgfTtcbiAgICBCaW5kaW5nSW5XaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9ySXMoYW5jZXN0b3IpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JOYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JOYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yVGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5BbnlBbmNlc3RvclRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JOYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3Rvck5hbWVkKG5hbWUpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3RvclRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3RvclRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdJbldoZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yTWF0Y2hlcyA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JNYXRjaGVzKGNvbnN0cmFpbnQpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3Rvck1hdGNoZXMgPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JNYXRjaGVzKGNvbnN0cmFpbnQpO1xuICAgIH07XG4gICAgQmluZGluZ0luV2hlbk9uU3ludGF4LnByb3RvdHlwZS5vbkFjdGl2YXRpb24gPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ09uU3ludGF4Lm9uQWN0aXZhdGlvbihoYW5kbGVyKTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nSW5XaGVuT25TeW50YXg7XG59KCkpO1xuZXhwb3J0cy5CaW5kaW5nSW5XaGVuT25TeW50YXggPSBCaW5kaW5nSW5XaGVuT25TeW50YXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaW5kaW5nX2luX3doZW5fb25fc3ludGF4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CaW5kaW5nT25TeW50YXggPSB2b2lkIDA7XG52YXIgYmluZGluZ193aGVuX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ193aGVuX3N5bnRheFwiKTtcbnZhciBCaW5kaW5nT25TeW50YXggPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJpbmRpbmdPblN5bnRheChiaW5kaW5nKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcgPSBiaW5kaW5nO1xuICAgIH1cbiAgICBCaW5kaW5nT25TeW50YXgucHJvdG90eXBlLm9uQWN0aXZhdGlvbiA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcub25BY3RpdmF0aW9uID0gaGFuZGxlcjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fc3ludGF4XzEuQmluZGluZ1doZW5TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICByZXR1cm4gQmluZGluZ09uU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ09uU3ludGF4ID0gQmluZGluZ09uU3ludGF4O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmluZGluZ19vbl9zeW50YXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLkJpbmRpbmdUb1N5bnRheCA9IHZvaWQgMDtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xudmFyIGxpdGVyYWxfdHlwZXNfMSA9IHJlcXVpcmUoXCIuLi9jb25zdGFudHMvbGl0ZXJhbF90eXBlc1wiKTtcbnZhciBiaW5kaW5nX2luX3doZW5fb25fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX2luX3doZW5fb25fc3ludGF4XCIpO1xudmFyIGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMSA9IHJlcXVpcmUoXCIuL2JpbmRpbmdfd2hlbl9vbl9zeW50YXhcIik7XG52YXIgQmluZGluZ1RvU3ludGF4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBCaW5kaW5nVG9TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICB9XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50byA9IGZ1bmN0aW9uIChjb25zdHJ1Y3Rvcikge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkluc3RhbmNlO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSA9IGNvbnN0cnVjdG9yO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfaW5fd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nSW5XaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvU2VsZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9iaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlwiICsgRVJST1JfTVNHUy5JTlZBTElEX1RPX1NFTEZfVkFMVUUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzZWxmID0gdGhpcy5fYmluZGluZy5zZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgcmV0dXJuIHRoaXMudG8oc2VsZik7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvQ29uc3RhbnRWYWx1ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnR5cGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1R5cGVFbnVtLkNvbnN0YW50VmFsdWU7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY2FjaGUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5fYmluZGluZy5keW5hbWljVmFsdWUgPSBudWxsO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmltcGxlbWVudGF0aW9uVHlwZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvRHluYW1pY1ZhbHVlID0gZnVuY3Rpb24gKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5EeW5hbWljVmFsdWU7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY2FjaGUgPSBudWxsO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmR5bmFtaWNWYWx1ZSA9IGZ1bmM7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX2luX3doZW5fb25fc3ludGF4XzEuQmluZGluZ0luV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b0NvbnN0cnVjdG9yID0gZnVuY3Rpb24gKGNvbnN0cnVjdG9yKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uQ29uc3RydWN0b3I7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlID0gY29uc3RydWN0b3I7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvRmFjdG9yeSA9IGZ1bmN0aW9uIChmYWN0b3J5KSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRmFjdG9yeTtcbiAgICAgICAgdGhpcy5fYmluZGluZy5mYWN0b3J5ID0gZmFjdG9yeTtcbiAgICAgICAgdGhpcy5fYmluZGluZy5zY29wZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nU2NvcGVFbnVtLlNpbmdsZXRvbjtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX3doZW5fb25fc3ludGF4XzEuQmluZGluZ1doZW5PblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdUb1N5bnRheC5wcm90b3R5cGUudG9GdW5jdGlvbiA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZnVuYyAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTVNHUy5JTlZBTElEX0ZVTkNUSU9OX0JJTkRJTkcpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBiaW5kaW5nV2hlbk9uU3ludGF4ID0gdGhpcy50b0NvbnN0YW50VmFsdWUoZnVuYyk7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRnVuY3Rpb247XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgIHJldHVybiBiaW5kaW5nV2hlbk9uU3ludGF4O1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b0F1dG9GYWN0b3J5ID0gZnVuY3Rpb24gKHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcudHlwZSA9IGxpdGVyYWxfdHlwZXNfMS5CaW5kaW5nVHlwZUVudW0uRmFjdG9yeTtcbiAgICAgICAgdGhpcy5fYmluZGluZy5mYWN0b3J5ID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgICAgIHZhciBhdXRvZmFjdG9yeSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbnRleHQuY29udGFpbmVyLmdldChzZXJ2aWNlSWRlbnRpZmllcik7IH07XG4gICAgICAgICAgICByZXR1cm4gYXV0b2ZhY3Rvcnk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuc2NvcGUgPSBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bS5TaW5nbGV0b247XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ193aGVuX29uX3N5bnRheF8xLkJpbmRpbmdXaGVuT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nVG9TeW50YXgucHJvdG90eXBlLnRvUHJvdmlkZXIgPSBmdW5jdGlvbiAocHJvdmlkZXIpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy50eXBlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bS5Qcm92aWRlcjtcbiAgICAgICAgdGhpcy5fYmluZGluZy5wcm92aWRlciA9IHByb3ZpZGVyO1xuICAgICAgICB0aGlzLl9iaW5kaW5nLnNjb3BlID0gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdTY29wZUVudW0uU2luZ2xldG9uO1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfd2hlbl9vbl9zeW50YXhfMS5CaW5kaW5nV2hlbk9uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1RvU3ludGF4LnByb3RvdHlwZS50b1NlcnZpY2UgPSBmdW5jdGlvbiAoc2VydmljZSkge1xuICAgICAgICB0aGlzLnRvRHluYW1pY1ZhbHVlKGZ1bmN0aW9uIChjb250ZXh0KSB7IHJldHVybiBjb250ZXh0LmNvbnRhaW5lci5nZXQoc2VydmljZSk7IH0pO1xuICAgIH07XG4gICAgcmV0dXJuIEJpbmRpbmdUb1N5bnRheDtcbn0oKSk7XG5leHBvcnRzLkJpbmRpbmdUb1N5bnRheCA9IEJpbmRpbmdUb1N5bnRheDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJpbmRpbmdfdG9fc3ludGF4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CaW5kaW5nV2hlbk9uU3ludGF4ID0gdm9pZCAwO1xudmFyIGJpbmRpbmdfb25fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX29uX3N5bnRheFwiKTtcbnZhciBiaW5kaW5nX3doZW5fc3ludGF4XzEgPSByZXF1aXJlKFwiLi9iaW5kaW5nX3doZW5fc3ludGF4XCIpO1xudmFyIEJpbmRpbmdXaGVuT25TeW50YXggPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJpbmRpbmdXaGVuT25TeW50YXgoYmluZGluZykge1xuICAgICAgICB0aGlzLl9iaW5kaW5nID0gYmluZGluZztcbiAgICAgICAgdGhpcy5fYmluZGluZ1doZW5TeW50YXggPSBuZXcgYmluZGluZ193aGVuX3N5bnRheF8xLkJpbmRpbmdXaGVuU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgICAgICB0aGlzLl9iaW5kaW5nT25TeW50YXggPSBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfVxuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW4gPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbihjb25zdHJhaW50KTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5UYXJnZXROYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuVGFyZ2V0TmFtZWQobmFtZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0SXNEZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlblRhcmdldElzRGVmYXVsdCgpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldFRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuVGFyZ2V0VGFnZ2VkKHRhZywgdmFsdWUpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbkluamVjdGVkSW50byA9IGZ1bmN0aW9uIChwYXJlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5JbmplY3RlZEludG8ocGFyZW50KTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5QYXJlbnROYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuUGFyZW50TmFtZWQobmFtZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50VGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5QYXJlbnRUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JJcyA9IGZ1bmN0aW9uIChhbmNlc3Rvcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9ySXMoYW5jZXN0b3IpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5PblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JJcyA9IGZ1bmN0aW9uIChhbmNlc3Rvcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbk5vQW5jZXN0b3JJcyhhbmNlc3Rvcik7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuQW55QW5jZXN0b3JOYW1lZCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JOYW1lZChuYW1lKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3RvclRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuQW55QW5jZXN0b3JUYWdnZWQodGFnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3Rvck5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JpbmRpbmdXaGVuU3ludGF4LndoZW5Ob0FuY2VzdG9yTmFtZWQobmFtZSk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3RvclRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3RvclRhZ2dlZCh0YWcsIHZhbHVlKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3Rvck1hdGNoZXMgPSBmdW5jdGlvbiAoY29uc3RyYWludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ1doZW5TeW50YXgud2hlbkFueUFuY2VzdG9yTWF0Y2hlcyhjb25zdHJhaW50KTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuT25TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yTWF0Y2hlcyA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iaW5kaW5nV2hlblN5bnRheC53aGVuTm9BbmNlc3Rvck1hdGNoZXMoY29uc3RyYWludCk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlbk9uU3ludGF4LnByb3RvdHlwZS5vbkFjdGl2YXRpb24gPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmluZGluZ09uU3ludGF4Lm9uQWN0aXZhdGlvbihoYW5kbGVyKTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nV2hlbk9uU3ludGF4O1xufSgpKTtcbmV4cG9ydHMuQmluZGluZ1doZW5PblN5bnRheCA9IEJpbmRpbmdXaGVuT25TeW50YXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaW5kaW5nX3doZW5fb25fc3ludGF4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5CaW5kaW5nV2hlblN5bnRheCA9IHZvaWQgMDtcbnZhciBiaW5kaW5nX29uX3N5bnRheF8xID0gcmVxdWlyZShcIi4vYmluZGluZ19vbl9zeW50YXhcIik7XG52YXIgY29uc3RyYWludF9oZWxwZXJzXzEgPSByZXF1aXJlKFwiLi9jb25zdHJhaW50X2hlbHBlcnNcIik7XG52YXIgQmluZGluZ1doZW5TeW50YXggPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJpbmRpbmdXaGVuU3ludGF4KGJpbmRpbmcpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZyA9IGJpbmRpbmc7XG4gICAgfVxuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuID0gZnVuY3Rpb24gKGNvbnN0cmFpbnQpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gY29uc3RyYWludDtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuVGFyZ2V0TmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBjb25zdHJhaW50X2hlbHBlcnNfMS5uYW1lZENvbnN0cmFpbnQobmFtZSk7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldElzRGVmYXVsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHZhciB0YXJnZXRJc0RlZmF1bHQgPSAocmVxdWVzdC50YXJnZXQgIT09IG51bGwpICYmXG4gICAgICAgICAgICAgICAgKCFyZXF1ZXN0LnRhcmdldC5pc05hbWVkKCkpICYmXG4gICAgICAgICAgICAgICAgKCFyZXF1ZXN0LnRhcmdldC5pc1RhZ2dlZCgpKTtcbiAgICAgICAgICAgIHJldHVybiB0YXJnZXRJc0RlZmF1bHQ7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlblRhcmdldFRhZ2dlZCA9IGZ1bmN0aW9uICh0YWcsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGNvbnN0cmFpbnRfaGVscGVyc18xLnRhZ2dlZENvbnN0cmFpbnQodGFnKSh2YWx1ZSk7XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbkluamVjdGVkSW50byA9IGZ1bmN0aW9uIChwYXJlbnQpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50eXBlQ29uc3RyYWludChwYXJlbnQpKHJlcXVlc3QucGFyZW50UmVxdWVzdCk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlblBhcmVudE5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS5uYW1lZENvbnN0cmFpbnQobmFtZSkocmVxdWVzdC5wYXJlbnRSZXF1ZXN0KTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuUGFyZW50VGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50YWdnZWRDb25zdHJhaW50KHRhZykodmFsdWUpKHJlcXVlc3QucGFyZW50UmVxdWVzdCk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9ySXMgPSBmdW5jdGlvbiAoYW5jZXN0b3IpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludF9oZWxwZXJzXzEudHlwZUNvbnN0cmFpbnQoYW5jZXN0b3IpKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3RvcklzID0gZnVuY3Rpb24gKGFuY2VzdG9yKSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gIWNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50X2hlbHBlcnNfMS50eXBlQ29uc3RyYWludChhbmNlc3RvcikpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5BbnlBbmNlc3Rvck5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludF9oZWxwZXJzXzEubmFtZWRDb25zdHJhaW50KG5hbWUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIEJpbmRpbmdXaGVuU3ludGF4LnByb3RvdHlwZS53aGVuTm9BbmNlc3Rvck5hbWVkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiAhY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnRfaGVscGVyc18xLm5hbWVkQ29uc3RyYWludChuYW1lKSk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yVGFnZ2VkID0gZnVuY3Rpb24gKHRhZywgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5fYmluZGluZy5jb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludF9oZWxwZXJzXzEudGFnZ2VkQ29uc3RyYWludCh0YWcpKHZhbHVlKSk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbk5vQW5jZXN0b3JUYWdnZWQgPSBmdW5jdGlvbiAodGFnLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9iaW5kaW5nLmNvbnN0cmFpbnQgPSBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuICFjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnMocmVxdWVzdCwgY29uc3RyYWludF9oZWxwZXJzXzEudGFnZ2VkQ29uc3RyYWludCh0YWcpKHZhbHVlKSk7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgYmluZGluZ19vbl9zeW50YXhfMS5CaW5kaW5nT25TeW50YXgodGhpcy5fYmluZGluZyk7XG4gICAgfTtcbiAgICBCaW5kaW5nV2hlblN5bnRheC5wcm90b3R5cGUud2hlbkFueUFuY2VzdG9yTWF0Y2hlcyA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudHJhdmVyc2VBbmNlcnN0b3JzKHJlcXVlc3QsIGNvbnN0cmFpbnQpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmdfb25fc3ludGF4XzEuQmluZGluZ09uU3ludGF4KHRoaXMuX2JpbmRpbmcpO1xuICAgIH07XG4gICAgQmluZGluZ1doZW5TeW50YXgucHJvdG90eXBlLndoZW5Ob0FuY2VzdG9yTWF0Y2hlcyA9IGZ1bmN0aW9uIChjb25zdHJhaW50KSB7XG4gICAgICAgIHRoaXMuX2JpbmRpbmcuY29uc3RyYWludCA9IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gIWNvbnN0cmFpbnRfaGVscGVyc18xLnRyYXZlcnNlQW5jZXJzdG9ycyhyZXF1ZXN0LCBjb25zdHJhaW50KTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nX29uX3N5bnRheF8xLkJpbmRpbmdPblN5bnRheCh0aGlzLl9iaW5kaW5nKTtcbiAgICB9O1xuICAgIHJldHVybiBCaW5kaW5nV2hlblN5bnRheDtcbn0oKSk7XG5leHBvcnRzLkJpbmRpbmdXaGVuU3ludGF4ID0gQmluZGluZ1doZW5TeW50YXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaW5kaW5nX3doZW5fc3ludGF4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy50eXBlQ29uc3RyYWludCA9IGV4cG9ydHMubmFtZWRDb25zdHJhaW50ID0gZXhwb3J0cy50YWdnZWRDb25zdHJhaW50ID0gZXhwb3J0cy50cmF2ZXJzZUFuY2Vyc3RvcnMgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIG1ldGFkYXRhXzEgPSByZXF1aXJlKFwiLi4vcGxhbm5pbmcvbWV0YWRhdGFcIik7XG52YXIgdHJhdmVyc2VBbmNlcnN0b3JzID0gZnVuY3Rpb24gKHJlcXVlc3QsIGNvbnN0cmFpbnQpIHtcbiAgICB2YXIgcGFyZW50ID0gcmVxdWVzdC5wYXJlbnRSZXF1ZXN0O1xuICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnQocGFyZW50KSA/IHRydWUgOiB0cmF2ZXJzZUFuY2Vyc3RvcnMocGFyZW50LCBjb25zdHJhaW50KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59O1xuZXhwb3J0cy50cmF2ZXJzZUFuY2Vyc3RvcnMgPSB0cmF2ZXJzZUFuY2Vyc3RvcnM7XG52YXIgdGFnZ2VkQ29uc3RyYWludCA9IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciBjb25zdHJhaW50ID0gZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuIHJlcXVlc3QgIT09IG51bGwgJiYgcmVxdWVzdC50YXJnZXQgIT09IG51bGwgJiYgcmVxdWVzdC50YXJnZXQubWF0Y2hlc1RhZyhrZXkpKHZhbHVlKTtcbiAgICB9O1xuICAgIGNvbnN0cmFpbnQubWV0YURhdGEgPSBuZXcgbWV0YWRhdGFfMS5NZXRhZGF0YShrZXksIHZhbHVlKTtcbiAgICByZXR1cm4gY29uc3RyYWludDtcbn07IH07XG5leHBvcnRzLnRhZ2dlZENvbnN0cmFpbnQgPSB0YWdnZWRDb25zdHJhaW50O1xudmFyIG5hbWVkQ29uc3RyYWludCA9IHRhZ2dlZENvbnN0cmFpbnQoTUVUQURBVEFfS0VZLk5BTUVEX1RBRyk7XG5leHBvcnRzLm5hbWVkQ29uc3RyYWludCA9IG5hbWVkQ29uc3RyYWludDtcbnZhciB0eXBlQ29uc3RyYWludCA9IGZ1bmN0aW9uICh0eXBlKSB7IHJldHVybiBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgIHZhciBiaW5kaW5nID0gbnVsbDtcbiAgICBpZiAocmVxdWVzdCAhPT0gbnVsbCkge1xuICAgICAgICBiaW5kaW5nID0gcmVxdWVzdC5iaW5kaW5nc1swXTtcbiAgICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB2YXIgc2VydmljZUlkZW50aWZpZXIgPSBiaW5kaW5nLnNlcnZpY2VJZGVudGlmaWVyO1xuICAgICAgICAgICAgcmV0dXJuIHNlcnZpY2VJZGVudGlmaWVyID09PSB0eXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGNvbnN0cnVjdG9yID0gcmVxdWVzdC5iaW5kaW5nc1swXS5pbXBsZW1lbnRhdGlvblR5cGU7XG4gICAgICAgICAgICByZXR1cm4gdHlwZSA9PT0gY29uc3RydWN0b3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTsgfTtcbmV4cG9ydHMudHlwZUNvbnN0cmFpbnQgPSB0eXBlQ29uc3RyYWludDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0cmFpbnRfaGVscGVycy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMubXVsdGlCaW5kVG9TZXJ2aWNlID0gdm9pZCAwO1xudmFyIG11bHRpQmluZFRvU2VydmljZSA9IGZ1bmN0aW9uIChjb250YWluZXIpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHNlcnZpY2UpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB0eXBlcyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgICAgICB0eXBlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmZvckVhY2goZnVuY3Rpb24gKHQpIHsgcmV0dXJuIGNvbnRhaW5lci5iaW5kKHQpLnRvU2VydmljZShzZXJ2aWNlKTsgfSk7XG4gICAgICAgIH07XG4gICAgfTtcbn07XG5leHBvcnRzLm11bHRpQmluZFRvU2VydmljZSA9IG11bHRpQmluZFRvU2VydmljZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJpbmRpbmdfdXRpbHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uID0gdm9pZCAwO1xudmFyIEVSUk9SX01TR1MgPSByZXF1aXJlKFwiLi4vY29uc3RhbnRzL2Vycm9yX21zZ3NcIik7XG5mdW5jdGlvbiBpc1N0YWNrT3ZlcmZsb3dFeGVwdGlvbihlcnJvcikge1xuICAgIHJldHVybiAoZXJyb3IgaW5zdGFuY2VvZiBSYW5nZUVycm9yIHx8XG4gICAgICAgIGVycm9yLm1lc3NhZ2UgPT09IEVSUk9SX01TR1MuU1RBQ0tfT1ZFUkZMT1cpO1xufVxuZXhwb3J0cy5pc1N0YWNrT3ZlcmZsb3dFeGVwdGlvbiA9IGlzU3RhY2tPdmVyZmxvd0V4ZXB0aW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXhjZXB0aW9ucy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuaWQgPSB2b2lkIDA7XG52YXIgaWRDb3VudGVyID0gMDtcbmZ1bmN0aW9uIGlkKCkge1xuICAgIHJldHVybiBpZENvdW50ZXIrKztcbn1cbmV4cG9ydHMuaWQgPSBpZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlkLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5jaXJjdWxhckRlcGVuZGVuY3lUb0V4Y2VwdGlvbiA9IGV4cG9ydHMubGlzdE1ldGFkYXRhRm9yVGFyZ2V0ID0gZXhwb3J0cy5saXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXIgPSBleHBvcnRzLmdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmcgPSBleHBvcnRzLmdldEZ1bmN0aW9uTmFtZSA9IHZvaWQgMDtcbnZhciBFUlJPUl9NU0dTID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9lcnJvcl9tc2dzXCIpO1xuZnVuY3Rpb24gZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhzZXJ2aWNlSWRlbnRpZmllcikge1xuICAgIGlmICh0eXBlb2Ygc2VydmljZUlkZW50aWZpZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB2YXIgX3NlcnZpY2VJZGVudGlmaWVyID0gc2VydmljZUlkZW50aWZpZXI7XG4gICAgICAgIHJldHVybiBfc2VydmljZUlkZW50aWZpZXIubmFtZTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHNlcnZpY2VJZGVudGlmaWVyID09PSBcInN5bWJvbFwiKSB7XG4gICAgICAgIHJldHVybiBzZXJ2aWNlSWRlbnRpZmllci50b1N0cmluZygpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIF9zZXJ2aWNlSWRlbnRpZmllciA9IHNlcnZpY2VJZGVudGlmaWVyO1xuICAgICAgICByZXR1cm4gX3NlcnZpY2VJZGVudGlmaWVyO1xuICAgIH1cbn1cbmV4cG9ydHMuZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyA9IGdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmc7XG5mdW5jdGlvbiBsaXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXIoY29udGFpbmVyLCBzZXJ2aWNlSWRlbnRpZmllciwgZ2V0QmluZGluZ3MpIHtcbiAgICB2YXIgcmVnaXN0ZXJlZEJpbmRpbmdzTGlzdCA9IFwiXCI7XG4gICAgdmFyIHJlZ2lzdGVyZWRCaW5kaW5ncyA9IGdldEJpbmRpbmdzKGNvbnRhaW5lciwgc2VydmljZUlkZW50aWZpZXIpO1xuICAgIGlmIChyZWdpc3RlcmVkQmluZGluZ3MubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3QgPSBcIlxcblJlZ2lzdGVyZWQgYmluZGluZ3M6XCI7XG4gICAgICAgIHJlZ2lzdGVyZWRCaW5kaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChiaW5kaW5nKSB7XG4gICAgICAgICAgICB2YXIgbmFtZSA9IFwiT2JqZWN0XCI7XG4gICAgICAgICAgICBpZiAoYmluZGluZy5pbXBsZW1lbnRhdGlvblR5cGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBuYW1lID0gZ2V0RnVuY3Rpb25OYW1lKGJpbmRpbmcuaW1wbGVtZW50YXRpb25UeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3QgPSByZWdpc3RlcmVkQmluZGluZ3NMaXN0ICsgXCJcXG4gXCIgKyBuYW1lO1xuICAgICAgICAgICAgaWYgKGJpbmRpbmcuY29uc3RyYWludC5tZXRhRGF0YSkge1xuICAgICAgICAgICAgICAgIHJlZ2lzdGVyZWRCaW5kaW5nc0xpc3QgPSByZWdpc3RlcmVkQmluZGluZ3NMaXN0ICsgXCIgLSBcIiArIGJpbmRpbmcuY29uc3RyYWludC5tZXRhRGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZWdpc3RlcmVkQmluZGluZ3NMaXN0O1xufVxuZXhwb3J0cy5saXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXIgPSBsaXN0UmVnaXN0ZXJlZEJpbmRpbmdzRm9yU2VydmljZUlkZW50aWZpZXI7XG5mdW5jdGlvbiBhbHJlYWR5RGVwZW5kZW5jeUNoYWluKHJlcXVlc3QsIHNlcnZpY2VJZGVudGlmaWVyKSB7XG4gICAgaWYgKHJlcXVlc3QucGFyZW50UmVxdWVzdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGVsc2UgaWYgKHJlcXVlc3QucGFyZW50UmVxdWVzdC5zZXJ2aWNlSWRlbnRpZmllciA9PT0gc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gYWxyZWFkeURlcGVuZGVuY3lDaGFpbihyZXF1ZXN0LnBhcmVudFJlcXVlc3QsIHNlcnZpY2VJZGVudGlmaWVyKTtcbiAgICB9XG59XG5mdW5jdGlvbiBkZXBlbmRlbmN5Q2hhaW5Ub1N0cmluZyhyZXF1ZXN0KSB7XG4gICAgZnVuY3Rpb24gX2NyZWF0ZVN0cmluZ0FycihyZXEsIHJlc3VsdCkge1xuICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIHsgcmVzdWx0ID0gW107IH1cbiAgICAgICAgdmFyIHNlcnZpY2VJZGVudGlmaWVyID0gZ2V0U2VydmljZUlkZW50aWZpZXJBc1N0cmluZyhyZXEuc2VydmljZUlkZW50aWZpZXIpO1xuICAgICAgICByZXN1bHQucHVzaChzZXJ2aWNlSWRlbnRpZmllcik7XG4gICAgICAgIGlmIChyZXEucGFyZW50UmVxdWVzdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIF9jcmVhdGVTdHJpbmdBcnIocmVxLnBhcmVudFJlcXVlc3QsIHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgdmFyIHN0cmluZ0FyciA9IF9jcmVhdGVTdHJpbmdBcnIocmVxdWVzdCk7XG4gICAgcmV0dXJuIHN0cmluZ0Fyci5yZXZlcnNlKCkuam9pbihcIiAtLT4gXCIpO1xufVxuZnVuY3Rpb24gY2lyY3VsYXJEZXBlbmRlbmN5VG9FeGNlcHRpb24ocmVxdWVzdCkge1xuICAgIHJlcXVlc3QuY2hpbGRSZXF1ZXN0cy5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZFJlcXVlc3QpIHtcbiAgICAgICAgaWYgKGFscmVhZHlEZXBlbmRlbmN5Q2hhaW4oY2hpbGRSZXF1ZXN0LCBjaGlsZFJlcXVlc3Quc2VydmljZUlkZW50aWZpZXIpKSB7XG4gICAgICAgICAgICB2YXIgc2VydmljZXMgPSBkZXBlbmRlbmN5Q2hhaW5Ub1N0cmluZyhjaGlsZFJlcXVlc3QpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX01TR1MuQ0lSQ1VMQVJfREVQRU5ERU5DWSArIFwiIFwiICsgc2VydmljZXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2lyY3VsYXJEZXBlbmRlbmN5VG9FeGNlcHRpb24oY2hpbGRSZXF1ZXN0KTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZXhwb3J0cy5jaXJjdWxhckRlcGVuZGVuY3lUb0V4Y2VwdGlvbiA9IGNpcmN1bGFyRGVwZW5kZW5jeVRvRXhjZXB0aW9uO1xuZnVuY3Rpb24gbGlzdE1ldGFkYXRhRm9yVGFyZ2V0KHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nLCB0YXJnZXQpIHtcbiAgICBpZiAodGFyZ2V0LmlzVGFnZ2VkKCkgfHwgdGFyZ2V0LmlzTmFtZWQoKSkge1xuICAgICAgICB2YXIgbV8xID0gXCJcIjtcbiAgICAgICAgdmFyIG5hbWVkVGFnID0gdGFyZ2V0LmdldE5hbWVkVGFnKCk7XG4gICAgICAgIHZhciBvdGhlclRhZ3MgPSB0YXJnZXQuZ2V0Q3VzdG9tVGFncygpO1xuICAgICAgICBpZiAobmFtZWRUYWcgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG1fMSArPSBuYW1lZFRhZy50b1N0cmluZygpICsgXCJcXG5cIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3RoZXJUYWdzICE9PSBudWxsKSB7XG4gICAgICAgICAgICBvdGhlclRhZ3MuZm9yRWFjaChmdW5jdGlvbiAodGFnKSB7XG4gICAgICAgICAgICAgICAgbV8xICs9IHRhZy50b1N0cmluZygpICsgXCJcXG5cIjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBcIiBcIiArIHNlcnZpY2VJZGVudGlmaWVyU3RyaW5nICsgXCJcXG4gXCIgKyBzZXJ2aWNlSWRlbnRpZmllclN0cmluZyArIFwiIC0gXCIgKyBtXzE7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gXCIgXCIgKyBzZXJ2aWNlSWRlbnRpZmllclN0cmluZztcbiAgICB9XG59XG5leHBvcnRzLmxpc3RNZXRhZGF0YUZvclRhcmdldCA9IGxpc3RNZXRhZGF0YUZvclRhcmdldDtcbmZ1bmN0aW9uIGdldEZ1bmN0aW9uTmFtZSh2KSB7XG4gICAgaWYgKHYubmFtZSkge1xuICAgICAgICByZXR1cm4gdi5uYW1lO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIG5hbWVfMSA9IHYudG9TdHJpbmcoKTtcbiAgICAgICAgdmFyIG1hdGNoID0gbmFtZV8xLm1hdGNoKC9eZnVuY3Rpb25cXHMqKFteXFxzKF0rKS8pO1xuICAgICAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXSA6IFwiQW5vbnltb3VzIGZ1bmN0aW9uOiBcIiArIG5hbWVfMTtcbiAgICB9XG59XG5leHBvcnRzLmdldEZ1bmN0aW9uTmFtZSA9IGdldEZ1bmN0aW9uTmFtZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNlcmlhbGl6YXRpb24uanMubWFwIiwibW9kdWxlLmV4cG9ydHMgPSBtaW5pbWF0Y2hcbm1pbmltYXRjaC5NaW5pbWF0Y2ggPSBNaW5pbWF0Y2hcblxudmFyIHBhdGggPSB7IHNlcDogJy8nIH1cbnRyeSB7XG4gIHBhdGggPSByZXF1aXJlKCdwYXRoJylcbn0gY2F0Y2ggKGVyKSB7fVxuXG52YXIgR0xPQlNUQVIgPSBtaW5pbWF0Y2guR0xPQlNUQVIgPSBNaW5pbWF0Y2guR0xPQlNUQVIgPSB7fVxudmFyIGV4cGFuZCA9IHJlcXVpcmUoJ2JyYWNlLWV4cGFuc2lvbicpXG5cbnZhciBwbFR5cGVzID0ge1xuICAnISc6IHsgb3BlbjogJyg/Oig/ISg/OicsIGNsb3NlOiAnKSlbXi9dKj8pJ30sXG4gICc/JzogeyBvcGVuOiAnKD86JywgY2xvc2U6ICcpPycgfSxcbiAgJysnOiB7IG9wZW46ICcoPzonLCBjbG9zZTogJykrJyB9LFxuICAnKic6IHsgb3BlbjogJyg/OicsIGNsb3NlOiAnKSonIH0sXG4gICdAJzogeyBvcGVuOiAnKD86JywgY2xvc2U6ICcpJyB9XG59XG5cbi8vIGFueSBzaW5nbGUgdGhpbmcgb3RoZXIgdGhhbiAvXG4vLyBkb24ndCBuZWVkIHRvIGVzY2FwZSAvIHdoZW4gdXNpbmcgbmV3IFJlZ0V4cCgpXG52YXIgcW1hcmsgPSAnW14vXSdcblxuLy8gKiA9PiBhbnkgbnVtYmVyIG9mIGNoYXJhY3RlcnNcbnZhciBzdGFyID0gcW1hcmsgKyAnKj8nXG5cbi8vICoqIHdoZW4gZG90cyBhcmUgYWxsb3dlZC4gIEFueXRoaW5nIGdvZXMsIGV4Y2VwdCAuLiBhbmQgLlxuLy8gbm90ICheIG9yIC8gZm9sbG93ZWQgYnkgb25lIG9yIHR3byBkb3RzIGZvbGxvd2VkIGJ5ICQgb3IgLyksXG4vLyBmb2xsb3dlZCBieSBhbnl0aGluZywgYW55IG51bWJlciBvZiB0aW1lcy5cbnZhciB0d29TdGFyRG90ID0gJyg/Oig/ISg/OlxcXFxcXC98XikoPzpcXFxcLnsxLDJ9KSgkfFxcXFxcXC8pKS4pKj8nXG5cbi8vIG5vdCBhIF4gb3IgLyBmb2xsb3dlZCBieSBhIGRvdCxcbi8vIGZvbGxvd2VkIGJ5IGFueXRoaW5nLCBhbnkgbnVtYmVyIG9mIHRpbWVzLlxudmFyIHR3b1N0YXJOb0RvdCA9ICcoPzooPyEoPzpcXFxcXFwvfF4pXFxcXC4pLikqPydcblxuLy8gY2hhcmFjdGVycyB0aGF0IG5lZWQgdG8gYmUgZXNjYXBlZCBpbiBSZWdFeHAuXG52YXIgcmVTcGVjaWFscyA9IGNoYXJTZXQoJygpLip7fSs/W11eJFxcXFwhJylcblxuLy8gXCJhYmNcIiAtPiB7IGE6dHJ1ZSwgYjp0cnVlLCBjOnRydWUgfVxuZnVuY3Rpb24gY2hhclNldCAocykge1xuICByZXR1cm4gcy5zcGxpdCgnJykucmVkdWNlKGZ1bmN0aW9uIChzZXQsIGMpIHtcbiAgICBzZXRbY10gPSB0cnVlXG4gICAgcmV0dXJuIHNldFxuICB9LCB7fSlcbn1cblxuLy8gbm9ybWFsaXplcyBzbGFzaGVzLlxudmFyIHNsYXNoU3BsaXQgPSAvXFwvKy9cblxubWluaW1hdGNoLmZpbHRlciA9IGZpbHRlclxuZnVuY3Rpb24gZmlsdGVyIChwYXR0ZXJuLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG4gIHJldHVybiBmdW5jdGlvbiAocCwgaSwgbGlzdCkge1xuICAgIHJldHVybiBtaW5pbWF0Y2gocCwgcGF0dGVybiwgb3B0aW9ucylcbiAgfVxufVxuXG5mdW5jdGlvbiBleHQgKGEsIGIpIHtcbiAgYSA9IGEgfHwge31cbiAgYiA9IGIgfHwge31cbiAgdmFyIHQgPSB7fVxuICBPYmplY3Qua2V5cyhiKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgdFtrXSA9IGJba11cbiAgfSlcbiAgT2JqZWN0LmtleXMoYSkuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgIHRba10gPSBhW2tdXG4gIH0pXG4gIHJldHVybiB0XG59XG5cbm1pbmltYXRjaC5kZWZhdWx0cyA9IGZ1bmN0aW9uIChkZWYpIHtcbiAgaWYgKCFkZWYgfHwgIU9iamVjdC5rZXlzKGRlZikubGVuZ3RoKSByZXR1cm4gbWluaW1hdGNoXG5cbiAgdmFyIG9yaWcgPSBtaW5pbWF0Y2hcblxuICB2YXIgbSA9IGZ1bmN0aW9uIG1pbmltYXRjaCAocCwgcGF0dGVybiwgb3B0aW9ucykge1xuICAgIHJldHVybiBvcmlnLm1pbmltYXRjaChwLCBwYXR0ZXJuLCBleHQoZGVmLCBvcHRpb25zKSlcbiAgfVxuXG4gIG0uTWluaW1hdGNoID0gZnVuY3Rpb24gTWluaW1hdGNoIChwYXR0ZXJuLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBvcmlnLk1pbmltYXRjaChwYXR0ZXJuLCBleHQoZGVmLCBvcHRpb25zKSlcbiAgfVxuXG4gIHJldHVybiBtXG59XG5cbk1pbmltYXRjaC5kZWZhdWx0cyA9IGZ1bmN0aW9uIChkZWYpIHtcbiAgaWYgKCFkZWYgfHwgIU9iamVjdC5rZXlzKGRlZikubGVuZ3RoKSByZXR1cm4gTWluaW1hdGNoXG4gIHJldHVybiBtaW5pbWF0Y2guZGVmYXVsdHMoZGVmKS5NaW5pbWF0Y2hcbn1cblxuZnVuY3Rpb24gbWluaW1hdGNoIChwLCBwYXR0ZXJuLCBvcHRpb25zKSB7XG4gIGlmICh0eXBlb2YgcGF0dGVybiAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdnbG9iIHBhdHRlcm4gc3RyaW5nIHJlcXVpcmVkJylcbiAgfVxuXG4gIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9XG5cbiAgLy8gc2hvcnRjdXQ6IGNvbW1lbnRzIG1hdGNoIG5vdGhpbmcuXG4gIGlmICghb3B0aW9ucy5ub2NvbW1lbnQgJiYgcGF0dGVybi5jaGFyQXQoMCkgPT09ICcjJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gXCJcIiBvbmx5IG1hdGNoZXMgXCJcIlxuICBpZiAocGF0dGVybi50cmltKCkgPT09ICcnKSByZXR1cm4gcCA9PT0gJydcblxuICByZXR1cm4gbmV3IE1pbmltYXRjaChwYXR0ZXJuLCBvcHRpb25zKS5tYXRjaChwKVxufVxuXG5mdW5jdGlvbiBNaW5pbWF0Y2ggKHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE1pbmltYXRjaCkpIHtcbiAgICByZXR1cm4gbmV3IE1pbmltYXRjaChwYXR0ZXJuLCBvcHRpb25zKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXR0ZXJuICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2dsb2IgcGF0dGVybiBzdHJpbmcgcmVxdWlyZWQnKVxuICB9XG5cbiAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge31cbiAgcGF0dGVybiA9IHBhdHRlcm4udHJpbSgpXG5cbiAgLy8gd2luZG93cyBzdXBwb3J0OiBuZWVkIHRvIHVzZSAvLCBub3QgXFxcbiAgaWYgKHBhdGguc2VwICE9PSAnLycpIHtcbiAgICBwYXR0ZXJuID0gcGF0dGVybi5zcGxpdChwYXRoLnNlcCkuam9pbignLycpXG4gIH1cblxuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gIHRoaXMuc2V0ID0gW11cbiAgdGhpcy5wYXR0ZXJuID0gcGF0dGVyblxuICB0aGlzLnJlZ2V4cCA9IG51bGxcbiAgdGhpcy5uZWdhdGUgPSBmYWxzZVxuICB0aGlzLmNvbW1lbnQgPSBmYWxzZVxuICB0aGlzLmVtcHR5ID0gZmFsc2VcblxuICAvLyBtYWtlIHRoZSBzZXQgb2YgcmVnZXhwcyBldGMuXG4gIHRoaXMubWFrZSgpXG59XG5cbk1pbmltYXRjaC5wcm90b3R5cGUuZGVidWcgPSBmdW5jdGlvbiAoKSB7fVxuXG5NaW5pbWF0Y2gucHJvdG90eXBlLm1ha2UgPSBtYWtlXG5mdW5jdGlvbiBtYWtlICgpIHtcbiAgLy8gZG9uJ3QgZG8gaXQgbW9yZSB0aGFuIG9uY2UuXG4gIGlmICh0aGlzLl9tYWRlKSByZXR1cm5cblxuICB2YXIgcGF0dGVybiA9IHRoaXMucGF0dGVyblxuICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9uc1xuXG4gIC8vIGVtcHR5IHBhdHRlcm5zIGFuZCBjb21tZW50cyBtYXRjaCBub3RoaW5nLlxuICBpZiAoIW9wdGlvbnMubm9jb21tZW50ICYmIHBhdHRlcm4uY2hhckF0KDApID09PSAnIycpIHtcbiAgICB0aGlzLmNvbW1lbnQgPSB0cnVlXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKCFwYXR0ZXJuKSB7XG4gICAgdGhpcy5lbXB0eSA9IHRydWVcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8vIHN0ZXAgMTogZmlndXJlIG91dCBuZWdhdGlvbiwgZXRjLlxuICB0aGlzLnBhcnNlTmVnYXRlKClcblxuICAvLyBzdGVwIDI6IGV4cGFuZCBicmFjZXNcbiAgdmFyIHNldCA9IHRoaXMuZ2xvYlNldCA9IHRoaXMuYnJhY2VFeHBhbmQoKVxuXG4gIGlmIChvcHRpb25zLmRlYnVnKSB0aGlzLmRlYnVnID0gY29uc29sZS5lcnJvclxuXG4gIHRoaXMuZGVidWcodGhpcy5wYXR0ZXJuLCBzZXQpXG5cbiAgLy8gc3RlcCAzOiBub3cgd2UgaGF2ZSBhIHNldCwgc28gdHVybiBlYWNoIG9uZSBpbnRvIGEgc2VyaWVzIG9mIHBhdGgtcG9ydGlvblxuICAvLyBtYXRjaGluZyBwYXR0ZXJucy5cbiAgLy8gVGhlc2Ugd2lsbCBiZSByZWdleHBzLCBleGNlcHQgaW4gdGhlIGNhc2Ugb2YgXCIqKlwiLCB3aGljaCBpc1xuICAvLyBzZXQgdG8gdGhlIEdMT0JTVEFSIG9iamVjdCBmb3IgZ2xvYnN0YXIgYmVoYXZpb3IsXG4gIC8vIGFuZCB3aWxsIG5vdCBjb250YWluIGFueSAvIGNoYXJhY3RlcnNcbiAgc2V0ID0gdGhpcy5nbG9iUGFydHMgPSBzZXQubWFwKGZ1bmN0aW9uIChzKSB7XG4gICAgcmV0dXJuIHMuc3BsaXQoc2xhc2hTcGxpdClcbiAgfSlcblxuICB0aGlzLmRlYnVnKHRoaXMucGF0dGVybiwgc2V0KVxuXG4gIC8vIGdsb2IgLS0+IHJlZ2V4cHNcbiAgc2V0ID0gc2V0Lm1hcChmdW5jdGlvbiAocywgc2ksIHNldCkge1xuICAgIHJldHVybiBzLm1hcCh0aGlzLnBhcnNlLCB0aGlzKVxuICB9LCB0aGlzKVxuXG4gIHRoaXMuZGVidWcodGhpcy5wYXR0ZXJuLCBzZXQpXG5cbiAgLy8gZmlsdGVyIG91dCBldmVyeXRoaW5nIHRoYXQgZGlkbid0IGNvbXBpbGUgcHJvcGVybHkuXG4gIHNldCA9IHNldC5maWx0ZXIoZnVuY3Rpb24gKHMpIHtcbiAgICByZXR1cm4gcy5pbmRleE9mKGZhbHNlKSA9PT0gLTFcbiAgfSlcblxuICB0aGlzLmRlYnVnKHRoaXMucGF0dGVybiwgc2V0KVxuXG4gIHRoaXMuc2V0ID0gc2V0XG59XG5cbk1pbmltYXRjaC5wcm90b3R5cGUucGFyc2VOZWdhdGUgPSBwYXJzZU5lZ2F0ZVxuZnVuY3Rpb24gcGFyc2VOZWdhdGUgKCkge1xuICB2YXIgcGF0dGVybiA9IHRoaXMucGF0dGVyblxuICB2YXIgbmVnYXRlID0gZmFsc2VcbiAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnNcbiAgdmFyIG5lZ2F0ZU9mZnNldCA9IDBcblxuICBpZiAob3B0aW9ucy5ub25lZ2F0ZSkgcmV0dXJuXG5cbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBwYXR0ZXJuLmxlbmd0aFxuICAgIDsgaSA8IGwgJiYgcGF0dGVybi5jaGFyQXQoaSkgPT09ICchJ1xuICAgIDsgaSsrKSB7XG4gICAgbmVnYXRlID0gIW5lZ2F0ZVxuICAgIG5lZ2F0ZU9mZnNldCsrXG4gIH1cblxuICBpZiAobmVnYXRlT2Zmc2V0KSB0aGlzLnBhdHRlcm4gPSBwYXR0ZXJuLnN1YnN0cihuZWdhdGVPZmZzZXQpXG4gIHRoaXMubmVnYXRlID0gbmVnYXRlXG59XG5cbi8vIEJyYWNlIGV4cGFuc2lvbjpcbi8vIGF7YixjfWQgLT4gYWJkIGFjZFxuLy8gYXtiLH1jIC0+IGFiYyBhY1xuLy8gYXswLi4zfWQgLT4gYTBkIGExZCBhMmQgYTNkXG4vLyBhe2IsY3tkLGV9Zn1nIC0+IGFiZyBhY2RmZyBhY2VmZ1xuLy8gYXtiLGN9ZHtlLGZ9ZyAtPiBhYmRlZyBhY2RlZyBhYmRlZyBhYmRmZ1xuLy9cbi8vIEludmFsaWQgc2V0cyBhcmUgbm90IGV4cGFuZGVkLlxuLy8gYXsyLi59YiAtPiBhezIuLn1iXG4vLyBhe2J9YyAtPiBhe2J9Y1xubWluaW1hdGNoLmJyYWNlRXhwYW5kID0gZnVuY3Rpb24gKHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGJyYWNlRXhwYW5kKHBhdHRlcm4sIG9wdGlvbnMpXG59XG5cbk1pbmltYXRjaC5wcm90b3R5cGUuYnJhY2VFeHBhbmQgPSBicmFjZUV4cGFuZFxuXG5mdW5jdGlvbiBicmFjZUV4cGFuZCAocGF0dGVybiwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICBpZiAodGhpcyBpbnN0YW5jZW9mIE1pbmltYXRjaCkge1xuICAgICAgb3B0aW9ucyA9IHRoaXMub3B0aW9uc1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zID0ge31cbiAgICB9XG4gIH1cblxuICBwYXR0ZXJuID0gdHlwZW9mIHBhdHRlcm4gPT09ICd1bmRlZmluZWQnXG4gICAgPyB0aGlzLnBhdHRlcm4gOiBwYXR0ZXJuXG5cbiAgaWYgKHR5cGVvZiBwYXR0ZXJuID09PSAndW5kZWZpbmVkJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3VuZGVmaW5lZCBwYXR0ZXJuJylcbiAgfVxuXG4gIGlmIChvcHRpb25zLm5vYnJhY2UgfHxcbiAgICAhcGF0dGVybi5tYXRjaCgvXFx7LipcXH0vKSkge1xuICAgIC8vIHNob3J0Y3V0LiBubyBuZWVkIHRvIGV4cGFuZC5cbiAgICByZXR1cm4gW3BhdHRlcm5dXG4gIH1cblxuICByZXR1cm4gZXhwYW5kKHBhdHRlcm4pXG59XG5cbi8vIHBhcnNlIGEgY29tcG9uZW50IG9mIHRoZSBleHBhbmRlZCBzZXQuXG4vLyBBdCB0aGlzIHBvaW50LCBubyBwYXR0ZXJuIG1heSBjb250YWluIFwiL1wiIGluIGl0XG4vLyBzbyB3ZSdyZSBnb2luZyB0byByZXR1cm4gYSAyZCBhcnJheSwgd2hlcmUgZWFjaCBlbnRyeSBpcyB0aGUgZnVsbFxuLy8gcGF0dGVybiwgc3BsaXQgb24gJy8nLCBhbmQgdGhlbiB0dXJuZWQgaW50byBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbi8vIEEgcmVnZXhwIGlzIG1hZGUgYXQgdGhlIGVuZCB3aGljaCBqb2lucyBlYWNoIGFycmF5IHdpdGggYW5cbi8vIGVzY2FwZWQgLywgYW5kIGFub3RoZXIgZnVsbCBvbmUgd2hpY2ggam9pbnMgZWFjaCByZWdleHAgd2l0aCB8LlxuLy9cbi8vIEZvbGxvd2luZyB0aGUgbGVhZCBvZiBCYXNoIDQuMSwgbm90ZSB0aGF0IFwiKipcIiBvbmx5IGhhcyBzcGVjaWFsIG1lYW5pbmdcbi8vIHdoZW4gaXQgaXMgdGhlICpvbmx5KiB0aGluZyBpbiBhIHBhdGggcG9ydGlvbi4gIE90aGVyd2lzZSwgYW55IHNlcmllc1xuLy8gb2YgKiBpcyBlcXVpdmFsZW50IHRvIGEgc2luZ2xlICouICBHbG9ic3RhciBiZWhhdmlvciBpcyBlbmFibGVkIGJ5XG4vLyBkZWZhdWx0LCBhbmQgY2FuIGJlIGRpc2FibGVkIGJ5IHNldHRpbmcgb3B0aW9ucy5ub2dsb2JzdGFyLlxuTWluaW1hdGNoLnByb3RvdHlwZS5wYXJzZSA9IHBhcnNlXG52YXIgU1VCUEFSU0UgPSB7fVxuZnVuY3Rpb24gcGFyc2UgKHBhdHRlcm4sIGlzU3ViKSB7XG4gIGlmIChwYXR0ZXJuLmxlbmd0aCA+IDEwMjQgKiA2NCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3BhdHRlcm4gaXMgdG9vIGxvbmcnKVxuICB9XG5cbiAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnNcblxuICAvLyBzaG9ydGN1dHNcbiAgaWYgKCFvcHRpb25zLm5vZ2xvYnN0YXIgJiYgcGF0dGVybiA9PT0gJyoqJykgcmV0dXJuIEdMT0JTVEFSXG4gIGlmIChwYXR0ZXJuID09PSAnJykgcmV0dXJuICcnXG5cbiAgdmFyIHJlID0gJydcbiAgdmFyIGhhc01hZ2ljID0gISFvcHRpb25zLm5vY2FzZVxuICB2YXIgZXNjYXBpbmcgPSBmYWxzZVxuICAvLyA/ID0+IG9uZSBzaW5nbGUgY2hhcmFjdGVyXG4gIHZhciBwYXR0ZXJuTGlzdFN0YWNrID0gW11cbiAgdmFyIG5lZ2F0aXZlTGlzdHMgPSBbXVxuICB2YXIgc3RhdGVDaGFyXG4gIHZhciBpbkNsYXNzID0gZmFsc2VcbiAgdmFyIHJlQ2xhc3NTdGFydCA9IC0xXG4gIHZhciBjbGFzc1N0YXJ0ID0gLTFcbiAgLy8gLiBhbmQgLi4gbmV2ZXIgbWF0Y2ggYW55dGhpbmcgdGhhdCBkb2Vzbid0IHN0YXJ0IHdpdGggLixcbiAgLy8gZXZlbiB3aGVuIG9wdGlvbnMuZG90IGlzIHNldC5cbiAgdmFyIHBhdHRlcm5TdGFydCA9IHBhdHRlcm4uY2hhckF0KDApID09PSAnLicgPyAnJyAvLyBhbnl0aGluZ1xuICAvLyBub3QgKHN0YXJ0IG9yIC8gZm9sbG93ZWQgYnkgLiBvciAuLiBmb2xsb3dlZCBieSAvIG9yIGVuZClcbiAgOiBvcHRpb25zLmRvdCA/ICcoPyEoPzpefFxcXFxcXC8pXFxcXC57MSwyfSg/OiR8XFxcXFxcLykpJ1xuICA6ICcoPyFcXFxcLiknXG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIGZ1bmN0aW9uIGNsZWFyU3RhdGVDaGFyICgpIHtcbiAgICBpZiAoc3RhdGVDaGFyKSB7XG4gICAgICAvLyB3ZSBoYWQgc29tZSBzdGF0ZS10cmFja2luZyBjaGFyYWN0ZXJcbiAgICAgIC8vIHRoYXQgd2Fzbid0IGNvbnN1bWVkIGJ5IHRoaXMgcGFzcy5cbiAgICAgIHN3aXRjaCAoc3RhdGVDaGFyKSB7XG4gICAgICAgIGNhc2UgJyonOlxuICAgICAgICAgIHJlICs9IHN0YXJcbiAgICAgICAgICBoYXNNYWdpYyA9IHRydWVcbiAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnPyc6XG4gICAgICAgICAgcmUgKz0gcW1hcmtcbiAgICAgICAgICBoYXNNYWdpYyA9IHRydWVcbiAgICAgICAgYnJlYWtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZSArPSAnXFxcXCcgKyBzdGF0ZUNoYXJcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIHNlbGYuZGVidWcoJ2NsZWFyU3RhdGVDaGFyICVqICVqJywgc3RhdGVDaGFyLCByZSlcbiAgICAgIHN0YXRlQ2hhciA9IGZhbHNlXG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHBhdHRlcm4ubGVuZ3RoLCBjXG4gICAgOyAoaSA8IGxlbikgJiYgKGMgPSBwYXR0ZXJuLmNoYXJBdChpKSlcbiAgICA7IGkrKykge1xuICAgIHRoaXMuZGVidWcoJyVzXFx0JXMgJXMgJWonLCBwYXR0ZXJuLCBpLCByZSwgYylcblxuICAgIC8vIHNraXAgb3ZlciBhbnkgdGhhdCBhcmUgZXNjYXBlZC5cbiAgICBpZiAoZXNjYXBpbmcgJiYgcmVTcGVjaWFsc1tjXSkge1xuICAgICAgcmUgKz0gJ1xcXFwnICsgY1xuICAgICAgZXNjYXBpbmcgPSBmYWxzZVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGMpIHtcbiAgICAgIGNhc2UgJy8nOlxuICAgICAgICAvLyBjb21wbGV0ZWx5IG5vdCBhbGxvd2VkLCBldmVuIGVzY2FwZWQuXG4gICAgICAgIC8vIFNob3VsZCBhbHJlYWR5IGJlIHBhdGgtc3BsaXQgYnkgbm93LlxuICAgICAgICByZXR1cm4gZmFsc2VcblxuICAgICAgY2FzZSAnXFxcXCc6XG4gICAgICAgIGNsZWFyU3RhdGVDaGFyKClcbiAgICAgICAgZXNjYXBpbmcgPSB0cnVlXG4gICAgICBjb250aW51ZVxuXG4gICAgICAvLyB0aGUgdmFyaW91cyBzdGF0ZUNoYXIgdmFsdWVzXG4gICAgICAvLyBmb3IgdGhlIFwiZXh0Z2xvYlwiIHN0dWZmLlxuICAgICAgY2FzZSAnPyc6XG4gICAgICBjYXNlICcqJzpcbiAgICAgIGNhc2UgJysnOlxuICAgICAgY2FzZSAnQCc6XG4gICAgICBjYXNlICchJzpcbiAgICAgICAgdGhpcy5kZWJ1ZygnJXNcXHQlcyAlcyAlaiA8LS0gc3RhdGVDaGFyJywgcGF0dGVybiwgaSwgcmUsIGMpXG5cbiAgICAgICAgLy8gYWxsIG9mIHRob3NlIGFyZSBsaXRlcmFscyBpbnNpZGUgYSBjbGFzcywgZXhjZXB0IHRoYXRcbiAgICAgICAgLy8gdGhlIGdsb2IgWyFhXSBtZWFucyBbXmFdIGluIHJlZ2V4cFxuICAgICAgICBpZiAoaW5DbGFzcykge1xuICAgICAgICAgIHRoaXMuZGVidWcoJyAgaW4gY2xhc3MnKVxuICAgICAgICAgIGlmIChjID09PSAnIScgJiYgaSA9PT0gY2xhc3NTdGFydCArIDEpIGMgPSAnXidcbiAgICAgICAgICByZSArPSBjXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHdlIGFscmVhZHkgaGF2ZSBhIHN0YXRlQ2hhciwgdGhlbiBpdCBtZWFuc1xuICAgICAgICAvLyB0aGF0IHRoZXJlIHdhcyBzb21ldGhpbmcgbGlrZSAqKiBvciArPyBpbiB0aGVyZS5cbiAgICAgICAgLy8gSGFuZGxlIHRoZSBzdGF0ZUNoYXIsIHRoZW4gcHJvY2VlZCB3aXRoIHRoaXMgb25lLlxuICAgICAgICBzZWxmLmRlYnVnKCdjYWxsIGNsZWFyU3RhdGVDaGFyICVqJywgc3RhdGVDaGFyKVxuICAgICAgICBjbGVhclN0YXRlQ2hhcigpXG4gICAgICAgIHN0YXRlQ2hhciA9IGNcbiAgICAgICAgLy8gaWYgZXh0Z2xvYiBpcyBkaXNhYmxlZCwgdGhlbiArKGFzZGZ8Zm9vKSBpc24ndCBhIHRoaW5nLlxuICAgICAgICAvLyBqdXN0IGNsZWFyIHRoZSBzdGF0ZWNoYXIgKm5vdyosIHJhdGhlciB0aGFuIGV2ZW4gZGl2aW5nIGludG9cbiAgICAgICAgLy8gdGhlIHBhdHRlcm5MaXN0IHN0dWZmLlxuICAgICAgICBpZiAob3B0aW9ucy5ub2V4dCkgY2xlYXJTdGF0ZUNoYXIoKVxuICAgICAgY29udGludWVcblxuICAgICAgY2FzZSAnKCc6XG4gICAgICAgIGlmIChpbkNsYXNzKSB7XG4gICAgICAgICAgcmUgKz0gJygnXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc3RhdGVDaGFyKSB7XG4gICAgICAgICAgcmUgKz0gJ1xcXFwoJ1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBwYXR0ZXJuTGlzdFN0YWNrLnB1c2goe1xuICAgICAgICAgIHR5cGU6IHN0YXRlQ2hhcixcbiAgICAgICAgICBzdGFydDogaSAtIDEsXG4gICAgICAgICAgcmVTdGFydDogcmUubGVuZ3RoLFxuICAgICAgICAgIG9wZW46IHBsVHlwZXNbc3RhdGVDaGFyXS5vcGVuLFxuICAgICAgICAgIGNsb3NlOiBwbFR5cGVzW3N0YXRlQ2hhcl0uY2xvc2VcbiAgICAgICAgfSlcbiAgICAgICAgLy8gbmVnYXRpb24gaXMgKD86KD8hanMpW14vXSopXG4gICAgICAgIHJlICs9IHN0YXRlQ2hhciA9PT0gJyEnID8gJyg/Oig/ISg/OicgOiAnKD86J1xuICAgICAgICB0aGlzLmRlYnVnKCdwbFR5cGUgJWogJWonLCBzdGF0ZUNoYXIsIHJlKVxuICAgICAgICBzdGF0ZUNoYXIgPSBmYWxzZVxuICAgICAgY29udGludWVcblxuICAgICAgY2FzZSAnKSc6XG4gICAgICAgIGlmIChpbkNsYXNzIHx8ICFwYXR0ZXJuTGlzdFN0YWNrLmxlbmd0aCkge1xuICAgICAgICAgIHJlICs9ICdcXFxcKSdcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgY2xlYXJTdGF0ZUNoYXIoKVxuICAgICAgICBoYXNNYWdpYyA9IHRydWVcbiAgICAgICAgdmFyIHBsID0gcGF0dGVybkxpc3RTdGFjay5wb3AoKVxuICAgICAgICAvLyBuZWdhdGlvbiBpcyAoPzooPyFqcylbXi9dKilcbiAgICAgICAgLy8gVGhlIG90aGVycyBhcmUgKD86PHBhdHRlcm4+KTx0eXBlPlxuICAgICAgICByZSArPSBwbC5jbG9zZVxuICAgICAgICBpZiAocGwudHlwZSA9PT0gJyEnKSB7XG4gICAgICAgICAgbmVnYXRpdmVMaXN0cy5wdXNoKHBsKVxuICAgICAgICB9XG4gICAgICAgIHBsLnJlRW5kID0gcmUubGVuZ3RoXG4gICAgICBjb250aW51ZVxuXG4gICAgICBjYXNlICd8JzpcbiAgICAgICAgaWYgKGluQ2xhc3MgfHwgIXBhdHRlcm5MaXN0U3RhY2subGVuZ3RoIHx8IGVzY2FwaW5nKSB7XG4gICAgICAgICAgcmUgKz0gJ1xcXFx8J1xuICAgICAgICAgIGVzY2FwaW5nID0gZmFsc2VcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgY2xlYXJTdGF0ZUNoYXIoKVxuICAgICAgICByZSArPSAnfCdcbiAgICAgIGNvbnRpbnVlXG5cbiAgICAgIC8vIHRoZXNlIGFyZSBtb3N0bHkgdGhlIHNhbWUgaW4gcmVnZXhwIGFuZCBnbG9iXG4gICAgICBjYXNlICdbJzpcbiAgICAgICAgLy8gc3dhbGxvdyBhbnkgc3RhdGUtdHJhY2tpbmcgY2hhciBiZWZvcmUgdGhlIFtcbiAgICAgICAgY2xlYXJTdGF0ZUNoYXIoKVxuXG4gICAgICAgIGlmIChpbkNsYXNzKSB7XG4gICAgICAgICAgcmUgKz0gJ1xcXFwnICsgY1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBpbkNsYXNzID0gdHJ1ZVxuICAgICAgICBjbGFzc1N0YXJ0ID0gaVxuICAgICAgICByZUNsYXNzU3RhcnQgPSByZS5sZW5ndGhcbiAgICAgICAgcmUgKz0gY1xuICAgICAgY29udGludWVcblxuICAgICAgY2FzZSAnXSc6XG4gICAgICAgIC8vICBhIHJpZ2h0IGJyYWNrZXQgc2hhbGwgbG9zZSBpdHMgc3BlY2lhbFxuICAgICAgICAvLyAgbWVhbmluZyBhbmQgcmVwcmVzZW50IGl0c2VsZiBpblxuICAgICAgICAvLyAgYSBicmFja2V0IGV4cHJlc3Npb24gaWYgaXQgb2NjdXJzXG4gICAgICAgIC8vICBmaXJzdCBpbiB0aGUgbGlzdC4gIC0tIFBPU0lYLjIgMi44LjMuMlxuICAgICAgICBpZiAoaSA9PT0gY2xhc3NTdGFydCArIDEgfHwgIWluQ2xhc3MpIHtcbiAgICAgICAgICByZSArPSAnXFxcXCcgKyBjXG4gICAgICAgICAgZXNjYXBpbmcgPSBmYWxzZVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyBoYW5kbGUgdGhlIGNhc2Ugd2hlcmUgd2UgbGVmdCBhIGNsYXNzIG9wZW4uXG4gICAgICAgIC8vIFwiW3otYV1cIiBpcyB2YWxpZCwgZXF1aXZhbGVudCB0byBcIlxcW3otYVxcXVwiXG4gICAgICAgIGlmIChpbkNsYXNzKSB7XG4gICAgICAgICAgLy8gc3BsaXQgd2hlcmUgdGhlIGxhc3QgWyB3YXMsIG1ha2Ugc3VyZSB3ZSBkb24ndCBoYXZlXG4gICAgICAgICAgLy8gYW4gaW52YWxpZCByZS4gaWYgc28sIHJlLXdhbGsgdGhlIGNvbnRlbnRzIG9mIHRoZVxuICAgICAgICAgIC8vIHdvdWxkLWJlIGNsYXNzIHRvIHJlLXRyYW5zbGF0ZSBhbnkgY2hhcmFjdGVycyB0aGF0XG4gICAgICAgICAgLy8gd2VyZSBwYXNzZWQgdGhyb3VnaCBhcy1pc1xuICAgICAgICAgIC8vIFRPRE86IEl0IHdvdWxkIHByb2JhYmx5IGJlIGZhc3RlciB0byBkZXRlcm1pbmUgdGhpc1xuICAgICAgICAgIC8vIHdpdGhvdXQgYSB0cnkvY2F0Y2ggYW5kIGEgbmV3IFJlZ0V4cCwgYnV0IGl0J3MgdHJpY2t5XG4gICAgICAgICAgLy8gdG8gZG8gc2FmZWx5LiAgRm9yIG5vdywgdGhpcyBpcyBzYWZlIGFuZCB3b3Jrcy5cbiAgICAgICAgICB2YXIgY3MgPSBwYXR0ZXJuLnN1YnN0cmluZyhjbGFzc1N0YXJ0ICsgMSwgaSlcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgUmVnRXhwKCdbJyArIGNzICsgJ10nKVxuICAgICAgICAgIH0gY2F0Y2ggKGVyKSB7XG4gICAgICAgICAgICAvLyBub3QgYSB2YWxpZCBjbGFzcyFcbiAgICAgICAgICAgIHZhciBzcCA9IHRoaXMucGFyc2UoY3MsIFNVQlBBUlNFKVxuICAgICAgICAgICAgcmUgPSByZS5zdWJzdHIoMCwgcmVDbGFzc1N0YXJ0KSArICdcXFxcWycgKyBzcFswXSArICdcXFxcXSdcbiAgICAgICAgICAgIGhhc01hZ2ljID0gaGFzTWFnaWMgfHwgc3BbMV1cbiAgICAgICAgICAgIGluQ2xhc3MgPSBmYWxzZVxuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaW5pc2ggdXAgdGhlIGNsYXNzLlxuICAgICAgICBoYXNNYWdpYyA9IHRydWVcbiAgICAgICAgaW5DbGFzcyA9IGZhbHNlXG4gICAgICAgIHJlICs9IGNcbiAgICAgIGNvbnRpbnVlXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIC8vIHN3YWxsb3cgYW55IHN0YXRlIGNoYXIgdGhhdCB3YXNuJ3QgY29uc3VtZWRcbiAgICAgICAgY2xlYXJTdGF0ZUNoYXIoKVxuXG4gICAgICAgIGlmIChlc2NhcGluZykge1xuICAgICAgICAgIC8vIG5vIG5lZWRcbiAgICAgICAgICBlc2NhcGluZyA9IGZhbHNlXG4gICAgICAgIH0gZWxzZSBpZiAocmVTcGVjaWFsc1tjXVxuICAgICAgICAgICYmICEoYyA9PT0gJ14nICYmIGluQ2xhc3MpKSB7XG4gICAgICAgICAgcmUgKz0gJ1xcXFwnXG4gICAgICAgIH1cblxuICAgICAgICByZSArPSBjXG5cbiAgICB9IC8vIHN3aXRjaFxuICB9IC8vIGZvclxuXG4gIC8vIGhhbmRsZSB0aGUgY2FzZSB3aGVyZSB3ZSBsZWZ0IGEgY2xhc3Mgb3Blbi5cbiAgLy8gXCJbYWJjXCIgaXMgdmFsaWQsIGVxdWl2YWxlbnQgdG8gXCJcXFthYmNcIlxuICBpZiAoaW5DbGFzcykge1xuICAgIC8vIHNwbGl0IHdoZXJlIHRoZSBsYXN0IFsgd2FzLCBhbmQgZXNjYXBlIGl0XG4gICAgLy8gdGhpcyBpcyBhIGh1Z2UgcGl0YS4gIFdlIG5vdyBoYXZlIHRvIHJlLXdhbGtcbiAgICAvLyB0aGUgY29udGVudHMgb2YgdGhlIHdvdWxkLWJlIGNsYXNzIHRvIHJlLXRyYW5zbGF0ZVxuICAgIC8vIGFueSBjaGFyYWN0ZXJzIHRoYXQgd2VyZSBwYXNzZWQgdGhyb3VnaCBhcy1pc1xuICAgIGNzID0gcGF0dGVybi5zdWJzdHIoY2xhc3NTdGFydCArIDEpXG4gICAgc3AgPSB0aGlzLnBhcnNlKGNzLCBTVUJQQVJTRSlcbiAgICByZSA9IHJlLnN1YnN0cigwLCByZUNsYXNzU3RhcnQpICsgJ1xcXFxbJyArIHNwWzBdXG4gICAgaGFzTWFnaWMgPSBoYXNNYWdpYyB8fCBzcFsxXVxuICB9XG5cbiAgLy8gaGFuZGxlIHRoZSBjYXNlIHdoZXJlIHdlIGhhZCBhICsoIHRoaW5nIGF0IHRoZSAqZW5kKlxuICAvLyBvZiB0aGUgcGF0dGVybi5cbiAgLy8gZWFjaCBwYXR0ZXJuIGxpc3Qgc3RhY2sgYWRkcyAzIGNoYXJzLCBhbmQgd2UgbmVlZCB0byBnbyB0aHJvdWdoXG4gIC8vIGFuZCBlc2NhcGUgYW55IHwgY2hhcnMgdGhhdCB3ZXJlIHBhc3NlZCB0aHJvdWdoIGFzLWlzIGZvciB0aGUgcmVnZXhwLlxuICAvLyBHbyB0aHJvdWdoIGFuZCBlc2NhcGUgdGhlbSwgdGFraW5nIGNhcmUgbm90IHRvIGRvdWJsZS1lc2NhcGUgYW55XG4gIC8vIHwgY2hhcnMgdGhhdCB3ZXJlIGFscmVhZHkgZXNjYXBlZC5cbiAgZm9yIChwbCA9IHBhdHRlcm5MaXN0U3RhY2sucG9wKCk7IHBsOyBwbCA9IHBhdHRlcm5MaXN0U3RhY2sucG9wKCkpIHtcbiAgICB2YXIgdGFpbCA9IHJlLnNsaWNlKHBsLnJlU3RhcnQgKyBwbC5vcGVuLmxlbmd0aClcbiAgICB0aGlzLmRlYnVnKCdzZXR0aW5nIHRhaWwnLCByZSwgcGwpXG4gICAgLy8gbWF5YmUgc29tZSBldmVuIG51bWJlciBvZiBcXCwgdGhlbiBtYXliZSAxIFxcLCBmb2xsb3dlZCBieSBhIHxcbiAgICB0YWlsID0gdGFpbC5yZXBsYWNlKC8oKD86XFxcXHsyfSl7MCw2NH0pKFxcXFw/KVxcfC9nLCBmdW5jdGlvbiAoXywgJDEsICQyKSB7XG4gICAgICBpZiAoISQyKSB7XG4gICAgICAgIC8vIHRoZSB8IGlzbid0IGFscmVhZHkgZXNjYXBlZCwgc28gZXNjYXBlIGl0LlxuICAgICAgICAkMiA9ICdcXFxcJ1xuICAgICAgfVxuXG4gICAgICAvLyBuZWVkIHRvIGVzY2FwZSBhbGwgdGhvc2Ugc2xhc2hlcyAqYWdhaW4qLCB3aXRob3V0IGVzY2FwaW5nIHRoZVxuICAgICAgLy8gb25lIHRoYXQgd2UgbmVlZCBmb3IgZXNjYXBpbmcgdGhlIHwgY2hhcmFjdGVyLiAgQXMgaXQgd29ya3Mgb3V0LFxuICAgICAgLy8gZXNjYXBpbmcgYW4gZXZlbiBudW1iZXIgb2Ygc2xhc2hlcyBjYW4gYmUgZG9uZSBieSBzaW1wbHkgcmVwZWF0aW5nXG4gICAgICAvLyBpdCBleGFjdGx5IGFmdGVyIGl0c2VsZi4gIFRoYXQncyB3aHkgdGhpcyB0cmljayB3b3Jrcy5cbiAgICAgIC8vXG4gICAgICAvLyBJIGFtIHNvcnJ5IHRoYXQgeW91IGhhdmUgdG8gc2VlIHRoaXMuXG4gICAgICByZXR1cm4gJDEgKyAkMSArICQyICsgJ3wnXG4gICAgfSlcblxuICAgIHRoaXMuZGVidWcoJ3RhaWw9JWpcXG4gICAlcycsIHRhaWwsIHRhaWwsIHBsLCByZSlcbiAgICB2YXIgdCA9IHBsLnR5cGUgPT09ICcqJyA/IHN0YXJcbiAgICAgIDogcGwudHlwZSA9PT0gJz8nID8gcW1hcmtcbiAgICAgIDogJ1xcXFwnICsgcGwudHlwZVxuXG4gICAgaGFzTWFnaWMgPSB0cnVlXG4gICAgcmUgPSByZS5zbGljZSgwLCBwbC5yZVN0YXJ0KSArIHQgKyAnXFxcXCgnICsgdGFpbFxuICB9XG5cbiAgLy8gaGFuZGxlIHRyYWlsaW5nIHRoaW5ncyB0aGF0IG9ubHkgbWF0dGVyIGF0IHRoZSB2ZXJ5IGVuZC5cbiAgY2xlYXJTdGF0ZUNoYXIoKVxuICBpZiAoZXNjYXBpbmcpIHtcbiAgICAvLyB0cmFpbGluZyBcXFxcXG4gICAgcmUgKz0gJ1xcXFxcXFxcJ1xuICB9XG5cbiAgLy8gb25seSBuZWVkIHRvIGFwcGx5IHRoZSBub2RvdCBzdGFydCBpZiB0aGUgcmUgc3RhcnRzIHdpdGhcbiAgLy8gc29tZXRoaW5nIHRoYXQgY291bGQgY29uY2VpdmFibHkgY2FwdHVyZSBhIGRvdFxuICB2YXIgYWRkUGF0dGVyblN0YXJ0ID0gZmFsc2VcbiAgc3dpdGNoIChyZS5jaGFyQXQoMCkpIHtcbiAgICBjYXNlICcuJzpcbiAgICBjYXNlICdbJzpcbiAgICBjYXNlICcoJzogYWRkUGF0dGVyblN0YXJ0ID0gdHJ1ZVxuICB9XG5cbiAgLy8gSGFjayB0byB3b3JrIGFyb3VuZCBsYWNrIG9mIG5lZ2F0aXZlIGxvb2tiZWhpbmQgaW4gSlNcbiAgLy8gQSBwYXR0ZXJuIGxpa2U6ICouISh4KS4hKHl8eikgbmVlZHMgdG8gZW5zdXJlIHRoYXQgYSBuYW1lXG4gIC8vIGxpa2UgJ2EueHl6Lnl6JyBkb2Vzbid0IG1hdGNoLiAgU28sIHRoZSBmaXJzdCBuZWdhdGl2ZVxuICAvLyBsb29rYWhlYWQsIGhhcyB0byBsb29rIEFMTCB0aGUgd2F5IGFoZWFkLCB0byB0aGUgZW5kIG9mXG4gIC8vIHRoZSBwYXR0ZXJuLlxuICBmb3IgKHZhciBuID0gbmVnYXRpdmVMaXN0cy5sZW5ndGggLSAxOyBuID4gLTE7IG4tLSkge1xuICAgIHZhciBubCA9IG5lZ2F0aXZlTGlzdHNbbl1cblxuICAgIHZhciBubEJlZm9yZSA9IHJlLnNsaWNlKDAsIG5sLnJlU3RhcnQpXG4gICAgdmFyIG5sRmlyc3QgPSByZS5zbGljZShubC5yZVN0YXJ0LCBubC5yZUVuZCAtIDgpXG4gICAgdmFyIG5sTGFzdCA9IHJlLnNsaWNlKG5sLnJlRW5kIC0gOCwgbmwucmVFbmQpXG4gICAgdmFyIG5sQWZ0ZXIgPSByZS5zbGljZShubC5yZUVuZClcblxuICAgIG5sTGFzdCArPSBubEFmdGVyXG5cbiAgICAvLyBIYW5kbGUgbmVzdGVkIHN0dWZmIGxpa2UgKigqLmpzfCEoKi5qc29uKSksIHdoZXJlIG9wZW4gcGFyZW5zXG4gICAgLy8gbWVhbiB0aGF0IHdlIHNob3VsZCAqbm90KiBpbmNsdWRlIHRoZSApIGluIHRoZSBiaXQgdGhhdCBpcyBjb25zaWRlcmVkXG4gICAgLy8gXCJhZnRlclwiIHRoZSBuZWdhdGVkIHNlY3Rpb24uXG4gICAgdmFyIG9wZW5QYXJlbnNCZWZvcmUgPSBubEJlZm9yZS5zcGxpdCgnKCcpLmxlbmd0aCAtIDFcbiAgICB2YXIgY2xlYW5BZnRlciA9IG5sQWZ0ZXJcbiAgICBmb3IgKGkgPSAwOyBpIDwgb3BlblBhcmVuc0JlZm9yZTsgaSsrKSB7XG4gICAgICBjbGVhbkFmdGVyID0gY2xlYW5BZnRlci5yZXBsYWNlKC9cXClbKyo/XT8vLCAnJylcbiAgICB9XG4gICAgbmxBZnRlciA9IGNsZWFuQWZ0ZXJcblxuICAgIHZhciBkb2xsYXIgPSAnJ1xuICAgIGlmIChubEFmdGVyID09PSAnJyAmJiBpc1N1YiAhPT0gU1VCUEFSU0UpIHtcbiAgICAgIGRvbGxhciA9ICckJ1xuICAgIH1cbiAgICB2YXIgbmV3UmUgPSBubEJlZm9yZSArIG5sRmlyc3QgKyBubEFmdGVyICsgZG9sbGFyICsgbmxMYXN0XG4gICAgcmUgPSBuZXdSZVxuICB9XG5cbiAgLy8gaWYgdGhlIHJlIGlzIG5vdCBcIlwiIGF0IHRoaXMgcG9pbnQsIHRoZW4gd2UgbmVlZCB0byBtYWtlIHN1cmVcbiAgLy8gaXQgZG9lc24ndCBtYXRjaCBhZ2FpbnN0IGFuIGVtcHR5IHBhdGggcGFydC5cbiAgLy8gT3RoZXJ3aXNlIGEvKiB3aWxsIG1hdGNoIGEvLCB3aGljaCBpdCBzaG91bGQgbm90LlxuICBpZiAocmUgIT09ICcnICYmIGhhc01hZ2ljKSB7XG4gICAgcmUgPSAnKD89LiknICsgcmVcbiAgfVxuXG4gIGlmIChhZGRQYXR0ZXJuU3RhcnQpIHtcbiAgICByZSA9IHBhdHRlcm5TdGFydCArIHJlXG4gIH1cblxuICAvLyBwYXJzaW5nIGp1c3QgYSBwaWVjZSBvZiBhIGxhcmdlciBwYXR0ZXJuLlxuICBpZiAoaXNTdWIgPT09IFNVQlBBUlNFKSB7XG4gICAgcmV0dXJuIFtyZSwgaGFzTWFnaWNdXG4gIH1cblxuICAvLyBza2lwIHRoZSByZWdleHAgZm9yIG5vbi1tYWdpY2FsIHBhdHRlcm5zXG4gIC8vIHVuZXNjYXBlIGFueXRoaW5nIGluIGl0LCB0aG91Z2gsIHNvIHRoYXQgaXQnbGwgYmVcbiAgLy8gYW4gZXhhY3QgbWF0Y2ggYWdhaW5zdCBhIGZpbGUgZXRjLlxuICBpZiAoIWhhc01hZ2ljKSB7XG4gICAgcmV0dXJuIGdsb2JVbmVzY2FwZShwYXR0ZXJuKVxuICB9XG5cbiAgdmFyIGZsYWdzID0gb3B0aW9ucy5ub2Nhc2UgPyAnaScgOiAnJ1xuICB0cnkge1xuICAgIHZhciByZWdFeHAgPSBuZXcgUmVnRXhwKCdeJyArIHJlICsgJyQnLCBmbGFncylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICAvLyBJZiBpdCB3YXMgYW4gaW52YWxpZCByZWd1bGFyIGV4cHJlc3Npb24sIHRoZW4gaXQgY2FuJ3QgbWF0Y2hcbiAgICAvLyBhbnl0aGluZy4gIFRoaXMgdHJpY2sgbG9va3MgZm9yIGEgY2hhcmFjdGVyIGFmdGVyIHRoZSBlbmQgb2ZcbiAgICAvLyB0aGUgc3RyaW5nLCB3aGljaCBpcyBvZiBjb3Vyc2UgaW1wb3NzaWJsZSwgZXhjZXB0IGluIG11bHRpLWxpbmVcbiAgICAvLyBtb2RlLCBidXQgaXQncyBub3QgYSAvbSByZWdleC5cbiAgICByZXR1cm4gbmV3IFJlZ0V4cCgnJC4nKVxuICB9XG5cbiAgcmVnRXhwLl9nbG9iID0gcGF0dGVyblxuICByZWdFeHAuX3NyYyA9IHJlXG5cbiAgcmV0dXJuIHJlZ0V4cFxufVxuXG5taW5pbWF0Y2gubWFrZVJlID0gZnVuY3Rpb24gKHBhdHRlcm4sIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBNaW5pbWF0Y2gocGF0dGVybiwgb3B0aW9ucyB8fCB7fSkubWFrZVJlKClcbn1cblxuTWluaW1hdGNoLnByb3RvdHlwZS5tYWtlUmUgPSBtYWtlUmVcbmZ1bmN0aW9uIG1ha2VSZSAoKSB7XG4gIGlmICh0aGlzLnJlZ2V4cCB8fCB0aGlzLnJlZ2V4cCA9PT0gZmFsc2UpIHJldHVybiB0aGlzLnJlZ2V4cFxuXG4gIC8vIGF0IHRoaXMgcG9pbnQsIHRoaXMuc2V0IGlzIGEgMmQgYXJyYXkgb2YgcGFydGlhbFxuICAvLyBwYXR0ZXJuIHN0cmluZ3MsIG9yIFwiKipcIi5cbiAgLy9cbiAgLy8gSXQncyBiZXR0ZXIgdG8gdXNlIC5tYXRjaCgpLiAgVGhpcyBmdW5jdGlvbiBzaG91bGRuJ3RcbiAgLy8gYmUgdXNlZCwgcmVhbGx5LCBidXQgaXQncyBwcmV0dHkgY29udmVuaWVudCBzb21ldGltZXMsXG4gIC8vIHdoZW4geW91IGp1c3Qgd2FudCB0byB3b3JrIHdpdGggYSByZWdleC5cbiAgdmFyIHNldCA9IHRoaXMuc2V0XG5cbiAgaWYgKCFzZXQubGVuZ3RoKSB7XG4gICAgdGhpcy5yZWdleHAgPSBmYWxzZVxuICAgIHJldHVybiB0aGlzLnJlZ2V4cFxuICB9XG4gIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zXG5cbiAgdmFyIHR3b1N0YXIgPSBvcHRpb25zLm5vZ2xvYnN0YXIgPyBzdGFyXG4gICAgOiBvcHRpb25zLmRvdCA/IHR3b1N0YXJEb3RcbiAgICA6IHR3b1N0YXJOb0RvdFxuICB2YXIgZmxhZ3MgPSBvcHRpb25zLm5vY2FzZSA/ICdpJyA6ICcnXG5cbiAgdmFyIHJlID0gc2V0Lm1hcChmdW5jdGlvbiAocGF0dGVybikge1xuICAgIHJldHVybiBwYXR0ZXJuLm1hcChmdW5jdGlvbiAocCkge1xuICAgICAgcmV0dXJuIChwID09PSBHTE9CU1RBUikgPyB0d29TdGFyXG4gICAgICA6ICh0eXBlb2YgcCA9PT0gJ3N0cmluZycpID8gcmVnRXhwRXNjYXBlKHApXG4gICAgICA6IHAuX3NyY1xuICAgIH0pLmpvaW4oJ1xcXFxcXC8nKVxuICB9KS5qb2luKCd8JylcblxuICAvLyBtdXN0IG1hdGNoIGVudGlyZSBwYXR0ZXJuXG4gIC8vIGVuZGluZyBpbiBhICogb3IgKiogd2lsbCBtYWtlIGl0IGxlc3Mgc3RyaWN0LlxuICByZSA9ICdeKD86JyArIHJlICsgJykkJ1xuXG4gIC8vIGNhbiBtYXRjaCBhbnl0aGluZywgYXMgbG9uZyBhcyBpdCdzIG5vdCB0aGlzLlxuICBpZiAodGhpcy5uZWdhdGUpIHJlID0gJ14oPyEnICsgcmUgKyAnKS4qJCdcblxuICB0cnkge1xuICAgIHRoaXMucmVnZXhwID0gbmV3IFJlZ0V4cChyZSwgZmxhZ3MpXG4gIH0gY2F0Y2ggKGV4KSB7XG4gICAgdGhpcy5yZWdleHAgPSBmYWxzZVxuICB9XG4gIHJldHVybiB0aGlzLnJlZ2V4cFxufVxuXG5taW5pbWF0Y2gubWF0Y2ggPSBmdW5jdGlvbiAobGlzdCwgcGF0dGVybiwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICB2YXIgbW0gPSBuZXcgTWluaW1hdGNoKHBhdHRlcm4sIG9wdGlvbnMpXG4gIGxpc3QgPSBsaXN0LmZpbHRlcihmdW5jdGlvbiAoZikge1xuICAgIHJldHVybiBtbS5tYXRjaChmKVxuICB9KVxuICBpZiAobW0ub3B0aW9ucy5ub251bGwgJiYgIWxpc3QubGVuZ3RoKSB7XG4gICAgbGlzdC5wdXNoKHBhdHRlcm4pXG4gIH1cbiAgcmV0dXJuIGxpc3Rcbn1cblxuTWluaW1hdGNoLnByb3RvdHlwZS5tYXRjaCA9IG1hdGNoXG5mdW5jdGlvbiBtYXRjaCAoZiwgcGFydGlhbCkge1xuICB0aGlzLmRlYnVnKCdtYXRjaCcsIGYsIHRoaXMucGF0dGVybilcbiAgLy8gc2hvcnQtY2lyY3VpdCBpbiB0aGUgY2FzZSBvZiBidXN0ZWQgdGhpbmdzLlxuICAvLyBjb21tZW50cywgZXRjLlxuICBpZiAodGhpcy5jb21tZW50KSByZXR1cm4gZmFsc2VcbiAgaWYgKHRoaXMuZW1wdHkpIHJldHVybiBmID09PSAnJ1xuXG4gIGlmIChmID09PSAnLycgJiYgcGFydGlhbCkgcmV0dXJuIHRydWVcblxuICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9uc1xuXG4gIC8vIHdpbmRvd3M6IG5lZWQgdG8gdXNlIC8sIG5vdCBcXFxuICBpZiAocGF0aC5zZXAgIT09ICcvJykge1xuICAgIGYgPSBmLnNwbGl0KHBhdGguc2VwKS5qb2luKCcvJylcbiAgfVxuXG4gIC8vIHRyZWF0IHRoZSB0ZXN0IHBhdGggYXMgYSBzZXQgb2YgcGF0aHBhcnRzLlxuICBmID0gZi5zcGxpdChzbGFzaFNwbGl0KVxuICB0aGlzLmRlYnVnKHRoaXMucGF0dGVybiwgJ3NwbGl0JywgZilcblxuICAvLyBqdXN0IE9ORSBvZiB0aGUgcGF0dGVybiBzZXRzIGluIHRoaXMuc2V0IG5lZWRzIHRvIG1hdGNoXG4gIC8vIGluIG9yZGVyIGZvciBpdCB0byBiZSB2YWxpZC4gIElmIG5lZ2F0aW5nLCB0aGVuIGp1c3Qgb25lXG4gIC8vIG1hdGNoIG1lYW5zIHRoYXQgd2UgaGF2ZSBmYWlsZWQuXG4gIC8vIEVpdGhlciB3YXksIHJldHVybiBvbiB0aGUgZmlyc3QgaGl0LlxuXG4gIHZhciBzZXQgPSB0aGlzLnNldFxuICB0aGlzLmRlYnVnKHRoaXMucGF0dGVybiwgJ3NldCcsIHNldClcblxuICAvLyBGaW5kIHRoZSBiYXNlbmFtZSBvZiB0aGUgcGF0aCBieSBsb29raW5nIGZvciB0aGUgbGFzdCBub24tZW1wdHkgc2VnbWVudFxuICB2YXIgZmlsZW5hbWVcbiAgdmFyIGlcbiAgZm9yIChpID0gZi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGZpbGVuYW1lID0gZltpXVxuICAgIGlmIChmaWxlbmFtZSkgYnJlYWtcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGF0dGVybiA9IHNldFtpXVxuICAgIHZhciBmaWxlID0gZlxuICAgIGlmIChvcHRpb25zLm1hdGNoQmFzZSAmJiBwYXR0ZXJuLmxlbmd0aCA9PT0gMSkge1xuICAgICAgZmlsZSA9IFtmaWxlbmFtZV1cbiAgICB9XG4gICAgdmFyIGhpdCA9IHRoaXMubWF0Y2hPbmUoZmlsZSwgcGF0dGVybiwgcGFydGlhbClcbiAgICBpZiAoaGl0KSB7XG4gICAgICBpZiAob3B0aW9ucy5mbGlwTmVnYXRlKSByZXR1cm4gdHJ1ZVxuICAgICAgcmV0dXJuICF0aGlzLm5lZ2F0ZVxuICAgIH1cbiAgfVxuXG4gIC8vIGRpZG4ndCBnZXQgYW55IGhpdHMuICB0aGlzIGlzIHN1Y2Nlc3MgaWYgaXQncyBhIG5lZ2F0aXZlXG4gIC8vIHBhdHRlcm4sIGZhaWx1cmUgb3RoZXJ3aXNlLlxuICBpZiAob3B0aW9ucy5mbGlwTmVnYXRlKSByZXR1cm4gZmFsc2VcbiAgcmV0dXJuIHRoaXMubmVnYXRlXG59XG5cbi8vIHNldCBwYXJ0aWFsIHRvIHRydWUgdG8gdGVzdCBpZiwgZm9yIGV4YW1wbGUsXG4vLyBcIi9hL2JcIiBtYXRjaGVzIHRoZSBzdGFydCBvZiBcIi8qL2IvKi9kXCJcbi8vIFBhcnRpYWwgbWVhbnMsIGlmIHlvdSBydW4gb3V0IG9mIGZpbGUgYmVmb3JlIHlvdSBydW5cbi8vIG91dCBvZiBwYXR0ZXJuLCB0aGVuIHRoYXQncyBmaW5lLCBhcyBsb25nIGFzIGFsbFxuLy8gdGhlIHBhcnRzIG1hdGNoLlxuTWluaW1hdGNoLnByb3RvdHlwZS5tYXRjaE9uZSA9IGZ1bmN0aW9uIChmaWxlLCBwYXR0ZXJuLCBwYXJ0aWFsKSB7XG4gIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zXG5cbiAgdGhpcy5kZWJ1ZygnbWF0Y2hPbmUnLFxuICAgIHsgJ3RoaXMnOiB0aGlzLCBmaWxlOiBmaWxlLCBwYXR0ZXJuOiBwYXR0ZXJuIH0pXG5cbiAgdGhpcy5kZWJ1ZygnbWF0Y2hPbmUnLCBmaWxlLmxlbmd0aCwgcGF0dGVybi5sZW5ndGgpXG5cbiAgZm9yICh2YXIgZmkgPSAwLFxuICAgICAgcGkgPSAwLFxuICAgICAgZmwgPSBmaWxlLmxlbmd0aCxcbiAgICAgIHBsID0gcGF0dGVybi5sZW5ndGhcbiAgICAgIDsgKGZpIDwgZmwpICYmIChwaSA8IHBsKVxuICAgICAgOyBmaSsrLCBwaSsrKSB7XG4gICAgdGhpcy5kZWJ1ZygnbWF0Y2hPbmUgbG9vcCcpXG4gICAgdmFyIHAgPSBwYXR0ZXJuW3BpXVxuICAgIHZhciBmID0gZmlsZVtmaV1cblxuICAgIHRoaXMuZGVidWcocGF0dGVybiwgcCwgZilcblxuICAgIC8vIHNob3VsZCBiZSBpbXBvc3NpYmxlLlxuICAgIC8vIHNvbWUgaW52YWxpZCByZWdleHAgc3R1ZmYgaW4gdGhlIHNldC5cbiAgICBpZiAocCA9PT0gZmFsc2UpIHJldHVybiBmYWxzZVxuXG4gICAgaWYgKHAgPT09IEdMT0JTVEFSKSB7XG4gICAgICB0aGlzLmRlYnVnKCdHTE9CU1RBUicsIFtwYXR0ZXJuLCBwLCBmXSlcblxuICAgICAgLy8gXCIqKlwiXG4gICAgICAvLyBhLyoqL2IvKiovYyB3b3VsZCBtYXRjaCB0aGUgZm9sbG93aW5nOlxuICAgICAgLy8gYS9iL3gveS96L2NcbiAgICAgIC8vIGEveC95L3ovYi9jXG4gICAgICAvLyBhL2IveC9iL3gvY1xuICAgICAgLy8gYS9iL2NcbiAgICAgIC8vIFRvIGRvIHRoaXMsIHRha2UgdGhlIHJlc3Qgb2YgdGhlIHBhdHRlcm4gYWZ0ZXJcbiAgICAgIC8vIHRoZSAqKiwgYW5kIHNlZSBpZiBpdCB3b3VsZCBtYXRjaCB0aGUgZmlsZSByZW1haW5kZXIuXG4gICAgICAvLyBJZiBzbywgcmV0dXJuIHN1Y2Nlc3MuXG4gICAgICAvLyBJZiBub3QsIHRoZSAqKiBcInN3YWxsb3dzXCIgYSBzZWdtZW50LCBhbmQgdHJ5IGFnYWluLlxuICAgICAgLy8gVGhpcyBpcyByZWN1cnNpdmVseSBhd2Z1bC5cbiAgICAgIC8vXG4gICAgICAvLyBhLyoqL2IvKiovYyBtYXRjaGluZyBhL2IveC95L3ovY1xuICAgICAgLy8gLSBhIG1hdGNoZXMgYVxuICAgICAgLy8gLSBkb3VibGVzdGFyXG4gICAgICAvLyAgIC0gbWF0Y2hPbmUoYi94L3kvei9jLCBiLyoqL2MpXG4gICAgICAvLyAgICAgLSBiIG1hdGNoZXMgYlxuICAgICAgLy8gICAgIC0gZG91Ymxlc3RhclxuICAgICAgLy8gICAgICAgLSBtYXRjaE9uZSh4L3kvei9jLCBjKSAtPiBub1xuICAgICAgLy8gICAgICAgLSBtYXRjaE9uZSh5L3ovYywgYykgLT4gbm9cbiAgICAgIC8vICAgICAgIC0gbWF0Y2hPbmUoei9jLCBjKSAtPiBub1xuICAgICAgLy8gICAgICAgLSBtYXRjaE9uZShjLCBjKSB5ZXMsIGhpdFxuICAgICAgdmFyIGZyID0gZmlcbiAgICAgIHZhciBwciA9IHBpICsgMVxuICAgICAgaWYgKHByID09PSBwbCkge1xuICAgICAgICB0aGlzLmRlYnVnKCcqKiBhdCB0aGUgZW5kJylcbiAgICAgICAgLy8gYSAqKiBhdCB0aGUgZW5kIHdpbGwganVzdCBzd2FsbG93IHRoZSByZXN0LlxuICAgICAgICAvLyBXZSBoYXZlIGZvdW5kIGEgbWF0Y2guXG4gICAgICAgIC8vIGhvd2V2ZXIsIGl0IHdpbGwgbm90IHN3YWxsb3cgLy54LCB1bmxlc3NcbiAgICAgICAgLy8gb3B0aW9ucy5kb3QgaXMgc2V0LlxuICAgICAgICAvLyAuIGFuZCAuLiBhcmUgKm5ldmVyKiBtYXRjaGVkIGJ5ICoqLCBmb3IgZXhwbG9zaXZlbHlcbiAgICAgICAgLy8gZXhwb25lbnRpYWwgcmVhc29ucy5cbiAgICAgICAgZm9yICg7IGZpIDwgZmw7IGZpKyspIHtcbiAgICAgICAgICBpZiAoZmlsZVtmaV0gPT09ICcuJyB8fCBmaWxlW2ZpXSA9PT0gJy4uJyB8fFxuICAgICAgICAgICAgKCFvcHRpb25zLmRvdCAmJiBmaWxlW2ZpXS5jaGFyQXQoMCkgPT09ICcuJykpIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG5cbiAgICAgIC8vIG9rLCBsZXQncyBzZWUgaWYgd2UgY2FuIHN3YWxsb3cgd2hhdGV2ZXIgd2UgY2FuLlxuICAgICAgd2hpbGUgKGZyIDwgZmwpIHtcbiAgICAgICAgdmFyIHN3YWxsb3dlZSA9IGZpbGVbZnJdXG5cbiAgICAgICAgdGhpcy5kZWJ1ZygnXFxuZ2xvYnN0YXIgd2hpbGUnLCBmaWxlLCBmciwgcGF0dGVybiwgcHIsIHN3YWxsb3dlZSlcblxuICAgICAgICAvLyBYWFggcmVtb3ZlIHRoaXMgc2xpY2UuICBKdXN0IHBhc3MgdGhlIHN0YXJ0IGluZGV4LlxuICAgICAgICBpZiAodGhpcy5tYXRjaE9uZShmaWxlLnNsaWNlKGZyKSwgcGF0dGVybi5zbGljZShwciksIHBhcnRpYWwpKSB7XG4gICAgICAgICAgdGhpcy5kZWJ1ZygnZ2xvYnN0YXIgZm91bmQgbWF0Y2ghJywgZnIsIGZsLCBzd2FsbG93ZWUpXG4gICAgICAgICAgLy8gZm91bmQgYSBtYXRjaC5cbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGNhbid0IHN3YWxsb3cgXCIuXCIgb3IgXCIuLlwiIGV2ZXIuXG4gICAgICAgICAgLy8gY2FuIG9ubHkgc3dhbGxvdyBcIi5mb29cIiB3aGVuIGV4cGxpY2l0bHkgYXNrZWQuXG4gICAgICAgICAgaWYgKHN3YWxsb3dlZSA9PT0gJy4nIHx8IHN3YWxsb3dlZSA9PT0gJy4uJyB8fFxuICAgICAgICAgICAgKCFvcHRpb25zLmRvdCAmJiBzd2FsbG93ZWUuY2hhckF0KDApID09PSAnLicpKSB7XG4gICAgICAgICAgICB0aGlzLmRlYnVnKCdkb3QgZGV0ZWN0ZWQhJywgZmlsZSwgZnIsIHBhdHRlcm4sIHByKVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyAqKiBzd2FsbG93cyBhIHNlZ21lbnQsIGFuZCBjb250aW51ZS5cbiAgICAgICAgICB0aGlzLmRlYnVnKCdnbG9ic3RhciBzd2FsbG93IGEgc2VnbWVudCwgYW5kIGNvbnRpbnVlJylcbiAgICAgICAgICBmcisrXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbm8gbWF0Y2ggd2FzIGZvdW5kLlxuICAgICAgLy8gSG93ZXZlciwgaW4gcGFydGlhbCBtb2RlLCB3ZSBjYW4ndCBzYXkgdGhpcyBpcyBuZWNlc3NhcmlseSBvdmVyLlxuICAgICAgLy8gSWYgdGhlcmUncyBtb3JlICpwYXR0ZXJuKiBsZWZ0LCB0aGVuXG4gICAgICBpZiAocGFydGlhbCkge1xuICAgICAgICAvLyByYW4gb3V0IG9mIGZpbGVcbiAgICAgICAgdGhpcy5kZWJ1ZygnXFxuPj4+IG5vIG1hdGNoLCBwYXJ0aWFsPycsIGZpbGUsIGZyLCBwYXR0ZXJuLCBwcilcbiAgICAgICAgaWYgKGZyID09PSBmbCkgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIHNvbWV0aGluZyBvdGhlciB0aGFuICoqXG4gICAgLy8gbm9uLW1hZ2ljIHBhdHRlcm5zIGp1c3QgaGF2ZSB0byBtYXRjaCBleGFjdGx5XG4gICAgLy8gcGF0dGVybnMgd2l0aCBtYWdpYyBoYXZlIGJlZW4gdHVybmVkIGludG8gcmVnZXhwcy5cbiAgICB2YXIgaGl0XG4gICAgaWYgKHR5cGVvZiBwID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKG9wdGlvbnMubm9jYXNlKSB7XG4gICAgICAgIGhpdCA9IGYudG9Mb3dlckNhc2UoKSA9PT0gcC50b0xvd2VyQ2FzZSgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaXQgPSBmID09PSBwXG4gICAgICB9XG4gICAgICB0aGlzLmRlYnVnKCdzdHJpbmcgbWF0Y2gnLCBwLCBmLCBoaXQpXG4gICAgfSBlbHNlIHtcbiAgICAgIGhpdCA9IGYubWF0Y2gocClcbiAgICAgIHRoaXMuZGVidWcoJ3BhdHRlcm4gbWF0Y2gnLCBwLCBmLCBoaXQpXG4gICAgfVxuXG4gICAgaWYgKCFoaXQpIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gTm90ZTogZW5kaW5nIGluIC8gbWVhbnMgdGhhdCB3ZSdsbCBnZXQgYSBmaW5hbCBcIlwiXG4gIC8vIGF0IHRoZSBlbmQgb2YgdGhlIHBhdHRlcm4uICBUaGlzIGNhbiBvbmx5IG1hdGNoIGFcbiAgLy8gY29ycmVzcG9uZGluZyBcIlwiIGF0IHRoZSBlbmQgb2YgdGhlIGZpbGUuXG4gIC8vIElmIHRoZSBmaWxlIGVuZHMgaW4gLywgdGhlbiBpdCBjYW4gb25seSBtYXRjaCBhXG4gIC8vIGEgcGF0dGVybiB0aGF0IGVuZHMgaW4gLywgdW5sZXNzIHRoZSBwYXR0ZXJuIGp1c3RcbiAgLy8gZG9lc24ndCBoYXZlIGFueSBtb3JlIGZvciBpdC4gQnV0LCBhL2IvIHNob3VsZCAqbm90KlxuICAvLyBtYXRjaCBcImEvYi8qXCIsIGV2ZW4gdGhvdWdoIFwiXCIgbWF0Y2hlcyBhZ2FpbnN0IHRoZVxuICAvLyBbXi9dKj8gcGF0dGVybiwgZXhjZXB0IGluIHBhcnRpYWwgbW9kZSwgd2hlcmUgaXQgbWlnaHRcbiAgLy8gc2ltcGx5IG5vdCBiZSByZWFjaGVkIHlldC5cbiAgLy8gSG93ZXZlciwgYS9iLyBzaG91bGQgc3RpbGwgc2F0aXNmeSBhLypcblxuICAvLyBub3cgZWl0aGVyIHdlIGZlbGwgb2ZmIHRoZSBlbmQgb2YgdGhlIHBhdHRlcm4sIG9yIHdlJ3JlIGRvbmUuXG4gIGlmIChmaSA9PT0gZmwgJiYgcGkgPT09IHBsKSB7XG4gICAgLy8gcmFuIG91dCBvZiBwYXR0ZXJuIGFuZCBmaWxlbmFtZSBhdCB0aGUgc2FtZSB0aW1lLlxuICAgIC8vIGFuIGV4YWN0IGhpdCFcbiAgICByZXR1cm4gdHJ1ZVxuICB9IGVsc2UgaWYgKGZpID09PSBmbCkge1xuICAgIC8vIHJhbiBvdXQgb2YgZmlsZSwgYnV0IHN0aWxsIGhhZCBwYXR0ZXJuIGxlZnQuXG4gICAgLy8gdGhpcyBpcyBvayBpZiB3ZSdyZSBkb2luZyB0aGUgbWF0Y2ggYXMgcGFydCBvZlxuICAgIC8vIGEgZ2xvYiBmcyB0cmF2ZXJzYWwuXG4gICAgcmV0dXJuIHBhcnRpYWxcbiAgfSBlbHNlIGlmIChwaSA9PT0gcGwpIHtcbiAgICAvLyByYW4gb3V0IG9mIHBhdHRlcm4sIHN0aWxsIGhhdmUgZmlsZSBsZWZ0LlxuICAgIC8vIHRoaXMgaXMgb25seSBhY2NlcHRhYmxlIGlmIHdlJ3JlIG9uIHRoZSB2ZXJ5IGxhc3RcbiAgICAvLyBlbXB0eSBzZWdtZW50IG9mIGEgZmlsZSB3aXRoIGEgdHJhaWxpbmcgc2xhc2guXG4gICAgLy8gYS8qIHNob3VsZCBtYXRjaCBhL2IvXG4gICAgdmFyIGVtcHR5RmlsZUVuZCA9IChmaSA9PT0gZmwgLSAxKSAmJiAoZmlsZVtmaV0gPT09ICcnKVxuICAgIHJldHVybiBlbXB0eUZpbGVFbmRcbiAgfVxuXG4gIC8vIHNob3VsZCBiZSB1bnJlYWNoYWJsZS5cbiAgdGhyb3cgbmV3IEVycm9yKCd3dGY/Jylcbn1cblxuLy8gcmVwbGFjZSBzdHVmZiBsaWtlIFxcKiB3aXRoICpcbmZ1bmN0aW9uIGdsb2JVbmVzY2FwZSAocykge1xuICByZXR1cm4gcy5yZXBsYWNlKC9cXFxcKC4pL2csICckMScpXG59XG5cbmZ1bmN0aW9uIHJlZ0V4cEVzY2FwZSAocykge1xuICByZXR1cm4gcy5yZXBsYWNlKC9bLVtcXF17fSgpKis/LixcXFxcXiR8I1xcc10vZywgJ1xcXFwkJicpXG59XG4iLCJ2YXIgd3JhcHB5ID0gcmVxdWlyZSgnd3JhcHB5Jylcbm1vZHVsZS5leHBvcnRzID0gd3JhcHB5KG9uY2UpXG5tb2R1bGUuZXhwb3J0cy5zdHJpY3QgPSB3cmFwcHkob25jZVN0cmljdClcblxub25jZS5wcm90byA9IG9uY2UoZnVuY3Rpb24gKCkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRnVuY3Rpb24ucHJvdG90eXBlLCAnb25jZScsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIG9uY2UodGhpcylcbiAgICB9LFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KVxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGdW5jdGlvbi5wcm90b3R5cGUsICdvbmNlU3RyaWN0Jywge1xuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gb25jZVN0cmljdCh0aGlzKVxuICAgIH0sXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pXG59KVxuXG5mdW5jdGlvbiBvbmNlIChmbikge1xuICB2YXIgZiA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoZi5jYWxsZWQpIHJldHVybiBmLnZhbHVlXG4gICAgZi5jYWxsZWQgPSB0cnVlXG4gICAgcmV0dXJuIGYudmFsdWUgPSBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gIH1cbiAgZi5jYWxsZWQgPSBmYWxzZVxuICByZXR1cm4gZlxufVxuXG5mdW5jdGlvbiBvbmNlU3RyaWN0IChmbikge1xuICB2YXIgZiA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoZi5jYWxsZWQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZi5vbmNlRXJyb3IpXG4gICAgZi5jYWxsZWQgPSB0cnVlXG4gICAgcmV0dXJuIGYudmFsdWUgPSBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gIH1cbiAgdmFyIG5hbWUgPSBmbi5uYW1lIHx8ICdGdW5jdGlvbiB3cmFwcGVkIHdpdGggYG9uY2VgJ1xuICBmLm9uY2VFcnJvciA9IG5hbWUgKyBcIiBzaG91bGRuJ3QgYmUgY2FsbGVkIG1vcmUgdGhhbiBvbmNlXCJcbiAgZi5jYWxsZWQgPSBmYWxzZVxuICByZXR1cm4gZlxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBwb3NpeChwYXRoKSB7XG5cdHJldHVybiBwYXRoLmNoYXJBdCgwKSA9PT0gJy8nO1xufVxuXG5mdW5jdGlvbiB3aW4zMihwYXRoKSB7XG5cdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9ibG9iL2IzZmNjMjQ1ZmIyNTUzOTkwOWVmMWQ1ZWFhMDFkYmY5MmUxNjg2MzMvbGliL3BhdGguanMjTDU2XG5cdHZhciBzcGxpdERldmljZVJlID0gL14oW2EtekEtWl06fFtcXFxcXFwvXXsyfVteXFxcXFxcL10rW1xcXFxcXC9dK1teXFxcXFxcL10rKT8oW1xcXFxcXC9dKT8oW1xcc1xcU10qPykkLztcblx0dmFyIHJlc3VsdCA9IHNwbGl0RGV2aWNlUmUuZXhlYyhwYXRoKTtcblx0dmFyIGRldmljZSA9IHJlc3VsdFsxXSB8fCAnJztcblx0dmFyIGlzVW5jID0gQm9vbGVhbihkZXZpY2UgJiYgZGV2aWNlLmNoYXJBdCgxKSAhPT0gJzonKTtcblxuXHQvLyBVTkMgcGF0aHMgYXJlIGFsd2F5cyBhYnNvbHV0ZVxuXHRyZXR1cm4gQm9vbGVhbihyZXN1bHRbMl0gfHwgaXNVbmMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicgPyB3aW4zMiA6IHBvc2l4O1xubW9kdWxlLmV4cG9ydHMucG9zaXggPSBwb3NpeDtcbm1vZHVsZS5leHBvcnRzLndpbjMyID0gd2luMzI7XG4iLCIvLyB2aW06dHM9NDpzdHM9NDpzdz00OlxuLyohXG4gKlxuICogQ29weXJpZ2h0IDIwMDktMjAxNyBLcmlzIEtvd2FsIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUXG4gKiBsaWNlbnNlIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9ibG9iL3YxL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4oZnVuY3Rpb24gKGRlZmluaXRpb24pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIFRoaXMgZmlsZSB3aWxsIGZ1bmN0aW9uIHByb3Blcmx5IGFzIGEgPHNjcmlwdD4gdGFnLCBvciBhIG1vZHVsZVxuICAgIC8vIHVzaW5nIENvbW1vbkpTIGFuZCBOb2RlSlMgb3IgUmVxdWlyZUpTIG1vZHVsZSBmb3JtYXRzLiAgSW5cbiAgICAvLyBDb21tb24vTm9kZS9SZXF1aXJlSlMsIHRoZSBtb2R1bGUgZXhwb3J0cyB0aGUgUSBBUEkgYW5kIHdoZW5cbiAgICAvLyBleGVjdXRlZCBhcyBhIHNpbXBsZSA8c2NyaXB0PiwgaXQgY3JlYXRlcyBhIFEgZ2xvYmFsIGluc3RlYWQuXG5cbiAgICAvLyBNb250YWdlIFJlcXVpcmVcbiAgICBpZiAodHlwZW9mIGJvb3RzdHJhcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGJvb3RzdHJhcChcInByb21pc2VcIiwgZGVmaW5pdGlvbik7XG5cbiAgICAvLyBDb21tb25KU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcblxuICAgIC8vIFJlcXVpcmVKU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGRlZmluaXRpb24pO1xuXG4gICAgLy8gU0VTIChTZWN1cmUgRWNtYVNjcmlwdClcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKCFzZXMub2soKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VzLm1ha2VRID0gZGVmaW5pdGlvbjtcbiAgICAgICAgfVxuXG4gICAgLy8gPHNjcmlwdD5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gUHJlZmVyIHdpbmRvdyBvdmVyIHNlbGYgZm9yIGFkZC1vbiBzY3JpcHRzLiBVc2Ugc2VsZiBmb3JcbiAgICAgICAgLy8gbm9uLXdpbmRvd2VkIGNvbnRleHRzLlxuICAgICAgICB2YXIgZ2xvYmFsID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHNlbGY7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBgd2luZG93YCBvYmplY3QsIHNhdmUgdGhlIHByZXZpb3VzIFEgZ2xvYmFsXG4gICAgICAgIC8vIGFuZCBpbml0aWFsaXplIFEgYXMgYSBnbG9iYWwuXG4gICAgICAgIHZhciBwcmV2aW91c1EgPSBnbG9iYWwuUTtcbiAgICAgICAgZ2xvYmFsLlEgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAgICAgLy8gQWRkIGEgbm9Db25mbGljdCBmdW5jdGlvbiBzbyBRIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlXG4gICAgICAgIC8vIGdsb2JhbCBuYW1lc3BhY2UuXG4gICAgICAgIGdsb2JhbC5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnbG9iYWwuUSA9IHByZXZpb3VzUTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnZpcm9ubWVudCB3YXMgbm90IGFudGljaXBhdGVkIGJ5IFEuIFBsZWFzZSBmaWxlIGEgYnVnLlwiKTtcbiAgICB9XG5cbn0pKGZ1bmN0aW9uICgpIHtcblwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzU3RhY2tzID0gZmFsc2U7XG50cnkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufSBjYXRjaCAoZSkge1xuICAgIGhhc1N0YWNrcyA9ICEhZS5zdGFjaztcbn1cblxuLy8gQWxsIGNvZGUgYWZ0ZXIgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzIHJlcG9ydGVkXG4vLyBieSBRLlxudmFyIHFTdGFydGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xudmFyIHFGaWxlTmFtZTtcblxuLy8gc2hpbXNcblxuLy8gdXNlZCBmb3IgZmFsbGJhY2sgaW4gXCJhbGxSZXNvbHZlZFwiXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgcG9zc2libGUgbWVhbnMgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gYSBmdXR1cmUgdHVyblxuLy8gb2YgdGhlIGV2ZW50IGxvb3AuXG52YXIgbmV4dFRpY2sgPShmdW5jdGlvbiAoKSB7XG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgdGFza3MgKHNpbmdsZSwgd2l0aCBoZWFkIG5vZGUpXG4gICAgdmFyIGhlYWQgPSB7dGFzazogdm9pZCAwLCBuZXh0OiBudWxsfTtcbiAgICB2YXIgdGFpbCA9IGhlYWQ7XG4gICAgdmFyIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlcXVlc3RUaWNrID0gdm9pZCAwO1xuICAgIHZhciBpc05vZGVKUyA9IGZhbHNlO1xuICAgIC8vIHF1ZXVlIGZvciBsYXRlIHRhc2tzLCB1c2VkIGJ5IHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmdcbiAgICB2YXIgbGF0ZXJRdWV1ZSA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgICAgIC8qIGpzaGludCBsb29wZnVuYzogdHJ1ZSAqL1xuICAgICAgICB2YXIgdGFzaywgZG9tYWluO1xuXG4gICAgICAgIHdoaWxlIChoZWFkLm5leHQpIHtcbiAgICAgICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICAgICAgICB0YXNrID0gaGVhZC50YXNrO1xuICAgICAgICAgICAgaGVhZC50YXNrID0gdm9pZCAwO1xuICAgICAgICAgICAgZG9tYWluID0gaGVhZC5kb21haW47XG5cbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICBoZWFkLmRvbWFpbiA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pO1xuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGxhdGVyUXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXNrID0gbGF0ZXJRdWV1ZS5wb3AoKTtcbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrKTtcbiAgICAgICAgfVxuICAgICAgICBmbHVzaGluZyA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBydW5zIGEgc2luZ2xlIGZ1bmN0aW9uIGluIHRoZSBhc3luYyBxdWV1ZVxuICAgIGZ1bmN0aW9uIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRhc2soKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNOb2RlSlMpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBub2RlLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBjb25zaWRlcmVkIGZhdGFsIGVycm9ycy5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIHN5bmNocm9ub3VzbHkgdG8gaW50ZXJydXB0IGZsdXNoaW5nIVxuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIGNvbnRpbnVhdGlvbiBpZiB0aGUgdW5jYXVnaHQgZXhjZXB0aW9uIGlzIHN1cHByZXNzZWRcbiAgICAgICAgICAgICAgICAvLyBsaXN0ZW5pbmcgXCJ1bmNhdWdodEV4Y2VwdGlvblwiIGV2ZW50cyAoYXMgZG9tYWlucyBkb2VzKS5cbiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBpbiBuZXh0IGV2ZW50IHRvIGF2b2lkIHRpY2sgcmVjdXJzaW9uLlxuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEluIGJyb3dzZXJzLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBhc3luY2hyb25vdXNseSB0byBhdm9pZCBzbG93LWRvd25zLlxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5leHRUaWNrID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgdGFpbCA9IHRhaWwubmV4dCA9IHtcbiAgICAgICAgICAgIHRhc2s6IHRhc2ssXG4gICAgICAgICAgICBkb21haW46IGlzTm9kZUpTICYmIHByb2Nlc3MuZG9tYWluLFxuICAgICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHByb2Nlc3MudG9TdHJpbmcoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIgJiYgcHJvY2Vzcy5uZXh0VGljaykge1xuICAgICAgICAvLyBFbnN1cmUgUSBpcyBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudCwgd2l0aCBhIGBwcm9jZXNzLm5leHRUaWNrYC5cbiAgICAgICAgLy8gVG8gc2VlIHRocm91Z2ggZmFrZSBOb2RlIGVudmlyb25tZW50czpcbiAgICAgICAgLy8gKiBNb2NoYSB0ZXN0IHJ1bm5lciAtIGV4cG9zZXMgYSBgcHJvY2Vzc2AgZ2xvYmFsIHdpdGhvdXQgYSBgbmV4dFRpY2tgXG4gICAgICAgIC8vICogQnJvd3NlcmlmeSAtIGV4cG9zZXMgYSBgcHJvY2Vzcy5uZXhUaWNrYCBmdW5jdGlvbiB0aGF0IHVzZXNcbiAgICAgICAgLy8gICBgc2V0VGltZW91dGAuIEluIHRoaXMgY2FzZSBgc2V0SW1tZWRpYXRlYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgICAgICAvLyAgICBpdCBpcyBmYXN0ZXIuIEJyb3dzZXJpZnkncyBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHNcbiAgICAgICAgLy8gICBcIltvYmplY3QgT2JqZWN0XVwiLCB3aGlsZSBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudFxuICAgICAgICAvLyAgIGBwcm9jZXNzLnRvU3RyaW5nKClgIHlpZWxkcyBcIltvYmplY3QgcHJvY2Vzc11cIi5cbiAgICAgICAgaXNOb2RlSlMgPSB0cnVlO1xuXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBJbiBJRTEwLCBOb2RlLmpzIDAuOSssIG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9Ob2JsZUpTL3NldEltbWVkaWF0ZVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBzZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csIGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgLy8gQXQgbGVhc3QgU2FmYXJpIFZlcnNpb24gNi4wLjUgKDg1MzYuMzAuMSkgaW50ZXJtaXR0ZW50bHkgY2Fubm90IGNyZWF0ZVxuICAgICAgICAvLyB3b3JraW5nIG1lc3NhZ2UgcG9ydHMgdGhlIGZpcnN0IHRpbWUgYSBwYWdlIGxvYWRzLlxuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gcmVxdWVzdFBvcnRUaWNrO1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmbHVzaDtcbiAgICAgICAgICAgIGZsdXNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciByZXF1ZXN0UG9ydFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPcGVyYSByZXF1aXJlcyB1cyB0byBwcm92aWRlIGEgbWVzc2FnZSBwYXlsb2FkLCByZWdhcmRsZXNzIG9mXG4gICAgICAgICAgICAvLyB3aGV0aGVyIHdlIHVzZSBpdC5cbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgICAgIH07XG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICByZXF1ZXN0UG9ydFRpY2soKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9sZCBicm93c2Vyc1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBydW5zIGEgdGFzayBhZnRlciBhbGwgb3RoZXIgdGFza3MgaGF2ZSBiZWVuIHJ1blxuICAgIC8vIHRoaXMgaXMgdXNlZnVsIGZvciB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nIHRoYXQgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgYWxsIGB0aGVuYGQgdGFza3MgaGF2ZSBiZWVuIHJ1bi5cbiAgICBuZXh0VGljay5ydW5BZnRlciA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIGxhdGVyUXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIG5leHRUaWNrO1xufSkoKTtcblxuLy8gQXR0ZW1wdCB0byBtYWtlIGdlbmVyaWNzIHNhZmUgaW4gdGhlIGZhY2Ugb2YgZG93bnN0cmVhbVxuLy8gbW9kaWZpY2F0aW9ucy5cbi8vIFRoZXJlIGlzIG5vIHNpdHVhdGlvbiB3aGVyZSB0aGlzIGlzIG5lY2Vzc2FyeS5cbi8vIElmIHlvdSBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLCB0aGVzZSBwcmltb3JkaWFscyBuZWVkIHRvIGJlXG4vLyBkZWVwbHkgZnJvemVuIGFueXdheSwgYW5kIGlmIHlvdSBkb27igJl0IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsXG4vLyB0aGlzIGlzIGp1c3QgcGxhaW4gcGFyYW5vaWQuXG4vLyBIb3dldmVyLCB0aGlzICoqbWlnaHQqKiBoYXZlIHRoZSBuaWNlIHNpZGUtZWZmZWN0IG9mIHJlZHVjaW5nIHRoZSBzaXplIG9mXG4vLyB0aGUgbWluaWZpZWQgY29kZSBieSByZWR1Y2luZyB4LmNhbGwoKSB0byBtZXJlbHkgeCgpXG4vLyBTZWUgTWFyayBNaWxsZXLigJlzIGV4cGxhbmF0aW9uIG9mIHdoYXQgdGhpcyBkb2VzLlxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9Y29udmVudGlvbnM6c2FmZV9tZXRhX3Byb2dyYW1taW5nXG52YXIgY2FsbCA9IEZ1bmN0aW9uLmNhbGw7XG5mdW5jdGlvbiB1bmN1cnJ5VGhpcyhmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNhbGwuYXBwbHkoZiwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuLy8gVGhpcyBpcyBlcXVpdmFsZW50LCBidXQgc2xvd2VyOlxuLy8gdW5jdXJyeVRoaXMgPSBGdW5jdGlvbl9iaW5kLmJpbmQoRnVuY3Rpb25fYmluZC5jYWxsKTtcbi8vIGh0dHA6Ly9qc3BlcmYuY29tL3VuY3Vycnl0aGlzXG5cbnZhciBhcnJheV9zbGljZSA9IHVuY3VycnlUaGlzKEFycmF5LnByb3RvdHlwZS5zbGljZSk7XG5cbnZhciBhcnJheV9yZWR1Y2UgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgYmFzaXMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAvLyBjb25jZXJuaW5nIHRoZSBpbml0aWFsIHZhbHVlLCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyBzZWVrIHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXksIGFjY291bnRpbmdcbiAgICAgICAgICAgIC8vIGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCBpcyBpcyBhIHNwYXJzZSBhcnJheVxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhc2lzID0gdGhpc1tpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgrK2luZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVkdWNlXG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGFycmF5IGlzIHNwYXJzZVxuICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICBiYXNpcyA9IGNhbGxiYWNrKGJhc2lzLCB0aGlzW2luZGV4XSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNpcztcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfaW5kZXhPZiA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIHx8IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBub3QgYSB2ZXJ5IGdvb2Qgc2hpbSwgYnV0IGdvb2QgZW5vdWdoIGZvciBvdXIgb25lIHVzZSBvZiBpdFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfbWFwID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLm1hcCB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGNvbGxlY3QgPSBbXTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHNlbGYsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgY29sbGVjdC5wdXNoKGNhbGxiYWNrLmNhbGwodGhpc3AsIHZhbHVlLCBpbmRleCwgc2VsZikpO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICByZXR1cm4gY29sbGVjdDtcbiAgICB9XG4pO1xuXG52YXIgb2JqZWN0X2NyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKHByb3RvdHlwZSkge1xuICAgIGZ1bmN0aW9uIFR5cGUoKSB7IH1cbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3IFR5cGUoKTtcbn07XG5cbnZhciBvYmplY3RfZGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkgfHwgZnVuY3Rpb24gKG9iaiwgcHJvcCwgZGVzY3JpcHRvcikge1xuICAgIG9ialtwcm9wXSA9IGRlc2NyaXB0b3IudmFsdWU7XG4gICAgcmV0dXJuIG9iajtcbn07XG5cbnZhciBvYmplY3RfaGFzT3duUHJvcGVydHkgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcblxudmFyIG9iamVjdF9rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0X2hhc093blByb3BlcnR5KG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgb2JqZWN0X3RvU3RyaW5nID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBPYmplY3QodmFsdWUpO1xufVxuXG4vLyBnZW5lcmF0b3IgcmVsYXRlZCBzaGltc1xuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuZnVuY3Rpb24gaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikge1xuICAgIHJldHVybiAoXG4gICAgICAgIG9iamVjdF90b1N0cmluZyhleGNlcHRpb24pID09PSBcIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIiB8fFxuICAgICAgICBleGNlcHRpb24gaW5zdGFuY2VvZiBRUmV0dXJuVmFsdWVcbiAgICApO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaGVscGVyIGFuZCBRLnJldHVybiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpblxuLy8gU3BpZGVyTW9ua2V5LlxudmFyIFFSZXR1cm5WYWx1ZTtcbmlmICh0eXBlb2YgUmV0dXJuVmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBSZXR1cm5WYWx1ZTtcbn0gZWxzZSB7XG4gICAgUVJldHVyblZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9O1xufVxuXG4vLyBsb25nIHN0YWNrIHRyYWNlc1xuXG52YXIgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgPSBcIkZyb20gcHJldmlvdXMgZXZlbnQ6XCI7XG5cbmZ1bmN0aW9uIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSkge1xuICAgIC8vIElmIHBvc3NpYmxlLCB0cmFuc2Zvcm0gdGhlIGVycm9yIHN0YWNrIHRyYWNlIGJ5IHJlbW92aW5nIE5vZGUgYW5kIFFcbiAgICAvLyBjcnVmdCwgdGhlbiBjb25jYXRlbmF0aW5nIHdpdGggdGhlIHN0YWNrIHRyYWNlIG9mIGBwcm9taXNlYC4gU2VlICM1Ny5cbiAgICBpZiAoaGFzU3RhY2tzICYmXG4gICAgICAgIHByb21pc2Uuc3RhY2sgJiZcbiAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICAgIGVycm9yLnN0YWNrXG4gICAgKSB7XG4gICAgICAgIHZhciBzdGFja3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgcCA9IHByb21pc2U7ICEhcDsgcCA9IHAuc291cmNlKSB7XG4gICAgICAgICAgICBpZiAocC5zdGFjayAmJiAoIWVycm9yLl9fbWluaW11bVN0YWNrQ291bnRlcl9fIHx8IGVycm9yLl9fbWluaW11bVN0YWNrQ291bnRlcl9fID4gcC5zdGFja0NvdW50ZXIpKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0X2RlZmluZVByb3BlcnR5KGVycm9yLCBcIl9fbWluaW11bVN0YWNrQ291bnRlcl9fXCIsIHt2YWx1ZTogcC5zdGFja0NvdW50ZXIsIGNvbmZpZ3VyYWJsZTogdHJ1ZX0pO1xuICAgICAgICAgICAgICAgIHN0YWNrcy51bnNoaWZ0KHAuc3RhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0YWNrcy51bnNoaWZ0KGVycm9yLnN0YWNrKTtcblxuICAgICAgICB2YXIgY29uY2F0ZWRTdGFja3MgPSBzdGFja3Muam9pbihcIlxcblwiICsgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgKyBcIlxcblwiKTtcbiAgICAgICAgdmFyIHN0YWNrID0gZmlsdGVyU3RhY2tTdHJpbmcoY29uY2F0ZWRTdGFja3MpO1xuICAgICAgICBvYmplY3RfZGVmaW5lUHJvcGVydHkoZXJyb3IsIFwic3RhY2tcIiwge3ZhbHVlOiBzdGFjaywgY29uZmlndXJhYmxlOiB0cnVlfSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmaWx0ZXJTdGFja1N0cmluZyhzdGFja1N0cmluZykge1xuICAgIHZhciBsaW5lcyA9IHN0YWNrU3RyaW5nLnNwbGl0KFwiXFxuXCIpO1xuICAgIHZhciBkZXNpcmVkTGluZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBsaW5lID0gbGluZXNbaV07XG5cbiAgICAgICAgaWYgKCFpc0ludGVybmFsRnJhbWUobGluZSkgJiYgIWlzTm9kZUZyYW1lKGxpbmUpICYmIGxpbmUpIHtcbiAgICAgICAgICAgIGRlc2lyZWRMaW5lcy5wdXNoKGxpbmUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZXNpcmVkTGluZXMuam9pbihcIlxcblwiKTtcbn1cblxuZnVuY3Rpb24gaXNOb2RlRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgcmV0dXJuIHN0YWNrTGluZS5pbmRleE9mKFwiKG1vZHVsZS5qczpcIikgIT09IC0xIHx8XG4gICAgICAgICAgIHN0YWNrTGluZS5pbmRleE9mKFwiKG5vZGUuanM6XCIpICE9PSAtMTtcbn1cblxuZnVuY3Rpb24gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKHN0YWNrTGluZSkge1xuICAgIC8vIE5hbWVkIGZ1bmN0aW9uczogXCJhdCBmdW5jdGlvbk5hbWUgKGZpbGVuYW1lOmxpbmVOdW1iZXI6Y29sdW1uTnVtYmVyKVwiXG4gICAgLy8gSW4gSUUxMCBmdW5jdGlvbiBuYW1lIGNhbiBoYXZlIHNwYWNlcyAoXCJBbm9ueW1vdXMgZnVuY3Rpb25cIikgT19vXG4gICAgdmFyIGF0dGVtcHQxID0gL2F0IC4rIFxcKCguKyk6KFxcZCspOig/OlxcZCspXFwpJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0MSkge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQxWzFdLCBOdW1iZXIoYXR0ZW1wdDFbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBBbm9ueW1vdXMgZnVuY3Rpb25zOiBcImF0IGZpbGVuYW1lOmxpbmVOdW1iZXI6Y29sdW1uTnVtYmVyXCJcbiAgICB2YXIgYXR0ZW1wdDIgPSAvYXQgKFteIF0rKTooXFxkKyk6KD86XFxkKykkLy5leGVjKHN0YWNrTGluZSk7XG4gICAgaWYgKGF0dGVtcHQyKSB7XG4gICAgICAgIHJldHVybiBbYXR0ZW1wdDJbMV0sIE51bWJlcihhdHRlbXB0MlsyXSldO1xuICAgIH1cblxuICAgIC8vIEZpcmVmb3ggc3R5bGU6IFwiZnVuY3Rpb25AZmlsZW5hbWU6bGluZU51bWJlciBvciBAZmlsZW5hbWU6bGluZU51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQzID0gLy4qQCguKyk6KFxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mykge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQzWzFdLCBOdW1iZXIoYXR0ZW1wdDNbMl0pXTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzSW50ZXJuYWxGcmFtZShzdGFja0xpbmUpIHtcbiAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKHN0YWNrTGluZSk7XG5cbiAgICBpZiAoIWZpbGVOYW1lQW5kTGluZU51bWJlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGZpbGVOYW1lID0gZmlsZU5hbWVBbmRMaW5lTnVtYmVyWzBdO1xuICAgIHZhciBsaW5lTnVtYmVyID0gZmlsZU5hbWVBbmRMaW5lTnVtYmVyWzFdO1xuXG4gICAgcmV0dXJuIGZpbGVOYW1lID09PSBxRmlsZU5hbWUgJiZcbiAgICAgICAgbGluZU51bWJlciA+PSBxU3RhcnRpbmdMaW5lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPD0gcUVuZGluZ0xpbmU7XG59XG5cbi8vIGRpc2NvdmVyIG93biBmaWxlIG5hbWUgYW5kIGxpbmUgbnVtYmVyIHJhbmdlIGZvciBmaWx0ZXJpbmcgc3RhY2tcbi8vIHRyYWNlc1xuZnVuY3Rpb24gY2FwdHVyZUxpbmUoKSB7XG4gICAgaWYgKCFoYXNTdGFja3MpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdmFyIGxpbmVzID0gZS5zdGFjay5zcGxpdChcIlxcblwiKTtcbiAgICAgICAgdmFyIGZpcnN0TGluZSA9IGxpbmVzWzBdLmluZGV4T2YoXCJAXCIpID4gMCA/IGxpbmVzWzFdIDogbGluZXNbMl07XG4gICAgICAgIHZhciBmaWxlTmFtZUFuZExpbmVOdW1iZXIgPSBnZXRGaWxlTmFtZUFuZExpbmVOdW1iZXIoZmlyc3RMaW5lKTtcbiAgICAgICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHFGaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICAgICAgcmV0dXJuIGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZShjYWxsYmFjaywgbmFtZSwgYWx0ZXJuYXRpdmUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiBjb25zb2xlLndhcm4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKG5hbWUgKyBcIiBpcyBkZXByZWNhdGVkLCB1c2UgXCIgKyBhbHRlcm5hdGl2ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgXCIgaW5zdGVhZC5cIiwgbmV3IEVycm9yKFwiXCIpLnN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkoY2FsbGJhY2ssIGFyZ3VtZW50cyk7XG4gICAgfTtcbn1cblxuLy8gZW5kIG9mIHNoaW1zXG4vLyBiZWdpbm5pbmcgb2YgcmVhbCB3b3JrXG5cbi8qKlxuICogQ29uc3RydWN0cyBhIHByb21pc2UgZm9yIGFuIGltbWVkaWF0ZSByZWZlcmVuY2UsIHBhc3NlcyBwcm9taXNlcyB0aHJvdWdoLCBvclxuICogY29lcmNlcyBwcm9taXNlcyBmcm9tIGRpZmZlcmVudCBzeXN0ZW1zLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2Ugb3IgcHJvbWlzZVxuICovXG5mdW5jdGlvbiBRKHZhbHVlKSB7XG4gICAgLy8gSWYgdGhlIG9iamVjdCBpcyBhbHJlYWR5IGEgUHJvbWlzZSwgcmV0dXJuIGl0IGRpcmVjdGx5LiAgVGhpcyBlbmFibGVzXG4gICAgLy8gdGhlIHJlc29sdmUgZnVuY3Rpb24gdG8gYm90aCBiZSB1c2VkIHRvIGNyZWF0ZWQgcmVmZXJlbmNlcyBmcm9tIG9iamVjdHMsXG4gICAgLy8gYnV0IHRvIHRvbGVyYWJseSBjb2VyY2Ugbm9uLXByb21pc2VzIHRvIHByb21pc2VzLlxuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIC8vIGFzc2ltaWxhdGUgdGhlbmFibGVzXG4gICAgaWYgKGlzUHJvbWlzZUFsaWtlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gY29lcmNlKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZnVsZmlsbCh2YWx1ZSk7XG4gICAgfVxufVxuUS5yZXNvbHZlID0gUTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIHRhc2sgaW4gYSBmdXR1cmUgdHVybiBvZiB0aGUgZXZlbnQgbG9vcC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRhc2tcbiAqL1xuUS5uZXh0VGljayA9IG5leHRUaWNrO1xuXG4vKipcbiAqIENvbnRyb2xzIHdoZXRoZXIgb3Igbm90IGxvbmcgc3RhY2sgdHJhY2VzIHdpbGwgYmUgb25cbiAqL1xuUS5sb25nU3RhY2tTdXBwb3J0ID0gZmFsc2U7XG5cbi8qKlxuICogVGhlIGNvdW50ZXIgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIHN0b3BwaW5nIHBvaW50IGZvciBidWlsZGluZ1xuICogbG9uZyBzdGFjayB0cmFjZXMuIEluIG1ha2VTdGFja1RyYWNlTG9uZyB3ZSB3YWxrIGJhY2t3YXJkcyB0aHJvdWdoXG4gKiB0aGUgbGlua2VkIGxpc3Qgb2YgcHJvbWlzZXMsIG9ubHkgc3RhY2tzIHdoaWNoIHdlcmUgY3JlYXRlZCBiZWZvcmVcbiAqIHRoZSByZWplY3Rpb24gYXJlIGNvbmNhdGVuYXRlZC5cbiAqL1xudmFyIGxvbmdTdGFja0NvdW50ZXIgPSAxO1xuXG4vLyBlbmFibGUgbG9uZyBzdGFja3MgaWYgUV9ERUJVRyBpcyBzZXRcbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52LlFfREVCVUcpIHtcbiAgICBRLmxvbmdTdGFja1N1cHBvcnQgPSB0cnVlO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSB7cHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0fSBvYmplY3QuXG4gKlxuICogYHJlc29sdmVgIGlzIGEgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggYSBtb3JlIHJlc29sdmVkIHZhbHVlIGZvciB0aGVcbiAqIHByb21pc2UuIFRvIGZ1bGZpbGwgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhbnkgdmFsdWUgdGhhdCBpc1xuICogbm90IGEgdGhlbmFibGUuIFRvIHJlamVjdCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGEgcmVqZWN0ZWRcbiAqIHRoZW5hYmxlLCBvciBpbnZva2UgYHJlamVjdGAgd2l0aCB0aGUgcmVhc29uIGRpcmVjdGx5LiBUbyByZXNvbHZlIHRoZVxuICogcHJvbWlzZSB0byBhbm90aGVyIHRoZW5hYmxlLCB0aHVzIHB1dHRpbmcgaXQgaW4gdGhlIHNhbWUgc3RhdGUsIGludm9rZVxuICogYHJlc29sdmVgIHdpdGggdGhhdCBvdGhlciB0aGVuYWJsZS5cbiAqL1xuUS5kZWZlciA9IGRlZmVyO1xuZnVuY3Rpb24gZGVmZXIoKSB7XG4gICAgLy8gaWYgXCJtZXNzYWdlc1wiIGlzIGFuIFwiQXJyYXlcIiwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvbWlzZSBoYXMgbm90IHlldFxuICAgIC8vIGJlZW4gcmVzb2x2ZWQuICBJZiBpdCBpcyBcInVuZGVmaW5lZFwiLCBpdCBoYXMgYmVlbiByZXNvbHZlZC4gIEVhY2hcbiAgICAvLyBlbGVtZW50IG9mIHRoZSBtZXNzYWdlcyBhcnJheSBpcyBpdHNlbGYgYW4gYXJyYXkgb2YgY29tcGxldGUgYXJndW1lbnRzIHRvXG4gICAgLy8gZm9yd2FyZCB0byB0aGUgcmVzb2x2ZWQgcHJvbWlzZS4gIFdlIGNvZXJjZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSB0byBhXG4gICAgLy8gcHJvbWlzZSB1c2luZyB0aGUgYHJlc29sdmVgIGZ1bmN0aW9uIGJlY2F1c2UgaXQgaGFuZGxlcyBib3RoIGZ1bGx5XG4gICAgLy8gbm9uLXRoZW5hYmxlIHZhbHVlcyBhbmQgb3RoZXIgdGhlbmFibGVzIGdyYWNlZnVsbHkuXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIHByb2dyZXNzTGlzdGVuZXJzID0gW10sIHJlc29sdmVkUHJvbWlzZTtcblxuICAgIHZhciBkZWZlcnJlZCA9IG9iamVjdF9jcmVhdGUoZGVmZXIucHJvdG90eXBlKTtcbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIG9wZXJhbmRzKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICBtZXNzYWdlcy5wdXNoKGFyZ3MpO1xuICAgICAgICAgICAgaWYgKG9wID09PSBcIndoZW5cIiAmJiBvcGVyYW5kc1sxXSkgeyAvLyBwcm9ncmVzcyBvcGVyYW5kXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChvcGVyYW5kc1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFByb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KHJlc29sdmVkUHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZFxuICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmVhcmVyVmFsdWUgPSBuZWFyZXIocmVzb2x2ZWRQcm9taXNlKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShuZWFyZXJWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5lYXJlclZhbHVlOyAvLyBzaG9ydGVuIGNoYWluXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lYXJlclZhbHVlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJwZW5kaW5nXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRQcm9taXNlLmluc3BlY3QoKTtcbiAgICB9O1xuXG4gICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBkb24ndCB0cnkgdG8gdXNlIGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAgb3IgdHJhbnNmZXIgdGhlXG4gICAgICAgICAgICAvLyBhY2Nlc3NvciBhcm91bmQ7IHRoYXQgY2F1c2VzIG1lbW9yeSBsZWFrcyBhcyBwZXIgR0gtMTExLiBKdXN0XG4gICAgICAgICAgICAvLyByZWlmeSB0aGUgc3RhY2sgdHJhY2UgYXMgYSBzdHJpbmcgQVNBUC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lLCBjdXQgb2ZmIHRoZSBmaXJzdCBsaW5lOyBpdCdzIGFsd2F5cyBqdXN0XG4gICAgICAgICAgICAvLyBcIltvYmplY3QgUHJvbWlzZV1cXG5cIiwgYXMgcGVyIHRoZSBgdG9TdHJpbmdgLlxuICAgICAgICAgICAgcHJvbWlzZS5zdGFjayA9IGUuc3RhY2suc3Vic3RyaW5nKGUuc3RhY2suaW5kZXhPZihcIlxcblwiKSArIDEpO1xuICAgICAgICAgICAgcHJvbWlzZS5zdGFja0NvdW50ZXIgPSBsb25nU3RhY2tDb3VudGVyKys7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBOT1RFOiB3ZSBkbyB0aGUgY2hlY2tzIGZvciBgcmVzb2x2ZWRQcm9taXNlYCBpbiBlYWNoIG1ldGhvZCwgaW5zdGVhZCBvZlxuICAgIC8vIGNvbnNvbGlkYXRpbmcgdGhlbSBpbnRvIGBiZWNvbWVgLCBzaW5jZSBvdGhlcndpc2Ugd2UnZCBjcmVhdGUgbmV3XG4gICAgLy8gcHJvbWlzZXMgd2l0aCB0aGUgbGluZXMgYGJlY29tZSh3aGF0ZXZlcih2YWx1ZSkpYC4gU2VlIGUuZy4gR0gtMjUyLlxuXG4gICAgZnVuY3Rpb24gYmVjb21lKG5ld1Byb21pc2UpIHtcbiAgICAgICAgcmVzb2x2ZWRQcm9taXNlID0gbmV3UHJvbWlzZTtcblxuICAgICAgICBpZiAoUS5sb25nU3RhY2tTdXBwb3J0ICYmIGhhc1N0YWNrcykge1xuICAgICAgICAgICAgLy8gT25seSBob2xkIGEgcmVmZXJlbmNlIHRvIHRoZSBuZXcgcHJvbWlzZSBpZiBsb25nIHN0YWNrc1xuICAgICAgICAgICAgLy8gYXJlIGVuYWJsZWQgdG8gcmVkdWNlIG1lbW9yeSB1c2FnZVxuICAgICAgICAgICAgcHJvbWlzZS5zb3VyY2UgPSBuZXdQcm9taXNlO1xuICAgICAgICB9XG5cbiAgICAgICAgYXJyYXlfcmVkdWNlKG1lc3NhZ2VzLCBmdW5jdGlvbiAodW5kZWZpbmVkLCBtZXNzYWdlKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBuZXdQcm9taXNlLnByb21pc2VEaXNwYXRjaC5hcHBseShuZXdQcm9taXNlLCBtZXNzYWdlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCB2b2lkIDApO1xuXG4gICAgICAgIG1lc3NhZ2VzID0gdm9pZCAwO1xuICAgICAgICBwcm9ncmVzc0xpc3RlbmVycyA9IHZvaWQgMDtcbiAgICB9XG5cbiAgICBkZWZlcnJlZC5wcm9taXNlID0gcHJvbWlzZTtcbiAgICBkZWZlcnJlZC5yZXNvbHZlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJlY29tZShRKHZhbHVlKSk7XG4gICAgfTtcblxuICAgIGRlZmVycmVkLmZ1bGZpbGwgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKGZ1bGZpbGwodmFsdWUpKTtcbiAgICB9O1xuICAgIGRlZmVycmVkLnJlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKHJlamVjdChyZWFzb24pKTtcbiAgICB9O1xuICAgIGRlZmVycmVkLm5vdGlmeSA9IGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBhcnJheV9yZWR1Y2UocHJvZ3Jlc3NMaXN0ZW5lcnMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb2dyZXNzTGlzdGVuZXIpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHByb2dyZXNzTGlzdGVuZXIocHJvZ3Jlc3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG4gICAgfTtcblxuICAgIHJldHVybiBkZWZlcnJlZDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgTm9kZS1zdHlsZSBjYWxsYmFjayB0aGF0IHdpbGwgcmVzb2x2ZSBvciByZWplY3QgdGhlIGRlZmVycmVkXG4gKiBwcm9taXNlLlxuICogQHJldHVybnMgYSBub2RlYmFja1xuICovXG5kZWZlci5wcm90b3R5cGUubWFrZU5vZGVSZXNvbHZlciA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChlcnJvciwgdmFsdWUpIHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICBzZWxmLnJlamVjdChlcnJvcik7XG4gICAgICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgIHNlbGYucmVzb2x2ZShhcnJheV9zbGljZShhcmd1bWVudHMsIDEpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlbGYucmVzb2x2ZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuLyoqXG4gKiBAcGFyYW0gcmVzb2x2ZXIge0Z1bmN0aW9ufSBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBub3RoaW5nIGFuZCBhY2NlcHRzXG4gKiB0aGUgcmVzb2x2ZSwgcmVqZWN0LCBhbmQgbm90aWZ5IGZ1bmN0aW9ucyBmb3IgYSBkZWZlcnJlZC5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IG1heSBiZSByZXNvbHZlZCB3aXRoIHRoZSBnaXZlbiByZXNvbHZlIGFuZCByZWplY3RcbiAqIGZ1bmN0aW9ucywgb3IgcmVqZWN0ZWQgYnkgYSB0aHJvd24gZXhjZXB0aW9uIGluIHJlc29sdmVyXG4gKi9cblEuUHJvbWlzZSA9IHByb21pc2U7IC8vIEVTNlxuUS5wcm9taXNlID0gcHJvbWlzZTtcbmZ1bmN0aW9uIHByb21pc2UocmVzb2x2ZXIpIHtcbiAgICBpZiAodHlwZW9mIHJlc29sdmVyICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInJlc29sdmVyIG11c3QgYmUgYSBmdW5jdGlvbi5cIik7XG4gICAgfVxuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgcmVzb2x2ZXIoZGVmZXJyZWQucmVzb2x2ZSwgZGVmZXJyZWQucmVqZWN0LCBkZWZlcnJlZC5ub3RpZnkpO1xuICAgIH0gY2F0Y2ggKHJlYXNvbikge1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QocmVhc29uKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cbnByb21pc2UucmFjZSA9IHJhY2U7IC8vIEVTNlxucHJvbWlzZS5hbGwgPSBhbGw7IC8vIEVTNlxucHJvbWlzZS5yZWplY3QgPSByZWplY3Q7IC8vIEVTNlxucHJvbWlzZS5yZXNvbHZlID0gUTsgLy8gRVM2XG5cbi8vIFhYWCBleHBlcmltZW50YWwuICBUaGlzIG1ldGhvZCBpcyBhIHdheSB0byBkZW5vdGUgdGhhdCBhIGxvY2FsIHZhbHVlIGlzXG4vLyBzZXJpYWxpemFibGUgYW5kIHNob3VsZCBiZSBpbW1lZGlhdGVseSBkaXNwYXRjaGVkIHRvIGEgcmVtb3RlIHVwb24gcmVxdWVzdCxcbi8vIGluc3RlYWQgb2YgcGFzc2luZyBhIHJlZmVyZW5jZS5cblEucGFzc0J5Q29weSA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICAvL2ZyZWV6ZShvYmplY3QpO1xuICAgIC8vcGFzc0J5Q29waWVzLnNldChvYmplY3QsIHRydWUpO1xuICAgIHJldHVybiBvYmplY3Q7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIElmIHR3byBwcm9taXNlcyBldmVudHVhbGx5IGZ1bGZpbGwgdG8gdGhlIHNhbWUgdmFsdWUsIHByb21pc2VzIHRoYXQgdmFsdWUsXG4gKiBidXQgb3RoZXJ3aXNlIHJlamVjdHMuXG4gKiBAcGFyYW0geCB7QW55Kn1cbiAqIEBwYXJhbSB5IHtBbnkqfVxuICogQHJldHVybnMge0FueSp9IGEgcHJvbWlzZSBmb3IgeCBhbmQgeSBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgYnV0IGEgcmVqZWN0aW9uXG4gKiBvdGhlcndpc2UuXG4gKlxuICovXG5RLmpvaW4gPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIHJldHVybiBRKHgpLmpvaW4oeSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5qb2luID0gZnVuY3Rpb24gKHRoYXQpIHtcbiAgICByZXR1cm4gUShbdGhpcywgdGhhdF0pLnNwcmVhZChmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICBpZiAoeCA9PT0geSkge1xuICAgICAgICAgICAgLy8gVE9ETzogXCI9PT1cIiBzaG91bGQgYmUgT2JqZWN0LmlzIG9yIGVxdWl2XG4gICAgICAgICAgICByZXR1cm4geDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlEgY2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIiArIHggKyBcIiBcIiArIHkpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZmlyc3Qgb2YgYW4gYXJyYXkgb2YgcHJvbWlzZXMgdG8gYmVjb21lIHNldHRsZWQuXG4gKiBAcGFyYW0gYW5zd2VycyB7QXJyYXlbQW55Kl19IHByb21pc2VzIHRvIHJhY2VcbiAqIEByZXR1cm5zIHtBbnkqfSB0aGUgZmlyc3QgcHJvbWlzZSB0byBiZSBzZXR0bGVkXG4gKi9cblEucmFjZSA9IHJhY2U7XG5mdW5jdGlvbiByYWNlKGFuc3dlclBzKSB7XG4gICAgcmV0dXJuIHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdGhpcyBvbmNlIHdlIGNhbiBhc3N1bWUgYXQgbGVhc3QgRVM1XG4gICAgICAgIC8vIGFuc3dlclBzLmZvckVhY2goZnVuY3Rpb24gKGFuc3dlclApIHtcbiAgICAgICAgLy8gICAgIFEoYW5zd2VyUCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gVXNlIHRoaXMgaW4gdGhlIG1lYW50aW1lXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhbnN3ZXJQcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgUShhbnN3ZXJQc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnJhY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihRLnJhY2UpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgUHJvbWlzZSB3aXRoIGEgcHJvbWlzZSBkZXNjcmlwdG9yIG9iamVjdCBhbmQgb3B0aW9uYWwgZmFsbGJhY2tcbiAqIGZ1bmN0aW9uLiAgVGhlIGRlc2NyaXB0b3IgY29udGFpbnMgbWV0aG9kcyBsaWtlIHdoZW4ocmVqZWN0ZWQpLCBnZXQobmFtZSksXG4gKiBzZXQobmFtZSwgdmFsdWUpLCBwb3N0KG5hbWUsIGFyZ3MpLCBhbmQgZGVsZXRlKG5hbWUpLCB3aGljaCBhbGxcbiAqIHJldHVybiBlaXRoZXIgYSB2YWx1ZSwgYSBwcm9taXNlIGZvciBhIHZhbHVlLCBvciBhIHJlamVjdGlvbi4gIFRoZSBmYWxsYmFja1xuICogYWNjZXB0cyB0aGUgb3BlcmF0aW9uIG5hbWUsIGEgcmVzb2x2ZXIsIGFuZCBhbnkgZnVydGhlciBhcmd1bWVudHMgdGhhdCB3b3VsZFxuICogaGF2ZSBiZWVuIGZvcndhcmRlZCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kIGFib3ZlIGhhZCBhIG1ldGhvZCBiZWVuXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBwcm9wZXIgbmFtZS4gIFRoZSBBUEkgbWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlXG4gKiBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LCBhcGFydCBmcm9tIHRoYXQgaXQgaXMgdXNhYmxlIHdoZXJlZXZlciBwcm9taXNlcyBhcmVcbiAqIGJvdWdodCBhbmQgc29sZC5cbiAqL1xuUS5tYWtlUHJvbWlzZSA9IFByb21pc2U7XG5mdW5jdGlvbiBQcm9taXNlKGRlc2NyaXB0b3IsIGZhbGxiYWNrLCBpbnNwZWN0KSB7XG4gICAgaWYgKGZhbGxiYWNrID09PSB2b2lkIDApIHtcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiUHJvbWlzZSBkb2VzIG5vdCBzdXBwb3J0IG9wZXJhdGlvbjogXCIgKyBvcFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnNwZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGU6IFwidW5rbm93blwifTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIGFyZ3MpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yW29wXSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlc2NyaXB0b3Jbb3BdLmFwcGx5KHByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxsYmFjay5jYWxsKHByb21pc2UsIG9wLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGluc3BlY3Q7XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZCBgdmFsdWVPZmAgYW5kIGBleGNlcHRpb25gIHN1cHBvcnRcbiAgICBpZiAoaW5zcGVjdCkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIHByb21pc2UuZXhjZXB0aW9uID0gaW5zcGVjdGVkLnJlYXNvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgIGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgZG9uZSA9IGZhbHNlOyAgIC8vIGVuc3VyZSB0aGUgdW50cnVzdGVkIHByb21pc2UgbWFrZXMgYXQgbW9zdCBhXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5nbGUgY2FsbCB0byBvbmUgb2YgdGhlIGNhbGxiYWNrc1xuXG4gICAgZnVuY3Rpb24gX2Z1bGZpbGxlZCh2YWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmdWxmaWxsZWQgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGZpbGxlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcmVqZWN0ZWQoZXhjZXB0aW9uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGV4Y2VwdGlvbiwgc2VsZik7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3RlZChleGNlcHRpb24pO1xuICAgICAgICAgICAgfSBjYXRjaCAobmV3RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXdFeGNlcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHJvZ3Jlc3NlZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2dyZXNzZWQgPT09IFwiZnVuY3Rpb25cIiA/IHByb2dyZXNzZWQodmFsdWUpIDogdmFsdWU7XG4gICAgfVxuXG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfZnVsZmlsbGVkKHZhbHVlKSk7XG4gICAgICAgIH0sIFwid2hlblwiLCBbZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfcmVqZWN0ZWQoZXhjZXB0aW9uKSk7XG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIC8vIFByb2dyZXNzIHByb3BhZ2F0b3IgbmVlZCB0byBiZSBhdHRhY2hlZCBpbiB0aGUgY3VycmVudCB0aWNrLlxuICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKHZvaWQgMCwgXCJ3aGVuXCIsIFt2b2lkIDAsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG4gICAgICAgIHZhciB0aHJldyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBfcHJvZ3Jlc3NlZCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRocmV3KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkobmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5RLnRhcCA9IGZ1bmN0aW9uIChwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRhcChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFdvcmtzIGFsbW9zdCBsaWtlIFwiZmluYWxseVwiLCBidXQgbm90IGNhbGxlZCBmb3IgcmVqZWN0aW9ucy5cbiAqIE9yaWdpbmFsIHJlc29sdXRpb24gdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggY2FsbGJhY2sgdW5hZmZlY3RlZC5cbiAqIENhbGxiYWNrIG1heSByZXR1cm4gYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBhd2FpdGVkIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7US5Qcm9taXNlfVxuICogQGV4YW1wbGVcbiAqIGRvU29tZXRoaW5nKClcbiAqICAgLnRoZW4oLi4uKVxuICogICAudGFwKGNvbnNvbGUubG9nKVxuICogICAudGhlbiguLi4pO1xuICovXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKHZhbHVlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBvbiBhIHByb21pc2UuXG4gKlxuICogR3VhcmFudGVlczpcbiAqXG4gKiAxLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICogMi4gdGhhdCBlaXRoZXIgdGhlIGZ1bGZpbGxlZCBjYWxsYmFjayBvciB0aGUgcmVqZWN0ZWQgY2FsbGJhY2sgd2lsbCBiZVxuICogICAgY2FsbGVkLCBidXQgbm90IGJvdGguXG4gKiAzLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoaXMgdHVybi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgICAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgdG8gb2JzZXJ2ZVxuICogQHBhcmFtIGZ1bGZpbGxlZCAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogQHBhcmFtIHJlamVjdGVkICAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIHJlamVjdGlvbiBleGNlcHRpb25cbiAqIEBwYXJhbSBwcm9ncmVzc2VkIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGludm9rZWQgY2FsbGJhY2tcbiAqL1xuUS53aGVuID0gd2hlbjtcbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9KTtcbn07XG5cblEudGhlblJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyByZWFzb247IH0pO1xufTtcblxuUS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHJlYXNvbikge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZWplY3QocmVhc29uKTtcbn07XG5cbi8qKlxuICogSWYgYW4gb2JqZWN0IGlzIG5vdCBhIHByb21pc2UsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlLlxuICogSWYgYSBwcm9taXNlIGlzIHJlamVjdGVkLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZSB0b28uXG4gKiBJZiBpdOKAmXMgYSBmdWxmaWxsZWQgcHJvbWlzZSwgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5lYXJlci5cbiAqIElmIGl04oCZcyBhIGRlZmVycmVkIHByb21pc2UgYW5kIHRoZSBkZWZlcnJlZCBoYXMgYmVlbiByZXNvbHZlZCwgdGhlXG4gKiByZXNvbHV0aW9uIGlzIFwibmVhcmVyXCIuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBtb3N0IHJlc29sdmVkIChuZWFyZXN0KSBmb3JtIG9mIHRoZSBvYmplY3RcbiAqL1xuXG4vLyBYWFggc2hvdWxkIHdlIHJlLWRvIHRoaXM/XG5RLm5lYXJlciA9IG5lYXJlcjtcbmZ1bmN0aW9uIG5lYXJlcih2YWx1ZSkge1xuICAgIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSB2YWx1ZS5pbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHByb21pc2UuXG4gKiBPdGhlcndpc2UgaXQgaXMgYSBmdWxmaWxsZWQgdmFsdWUuXG4gKi9cblEuaXNQcm9taXNlID0gaXNQcm9taXNlO1xuZnVuY3Rpb24gaXNQcm9taXNlKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBQcm9taXNlO1xufVxuXG5RLmlzUHJvbWlzZUFsaWtlID0gaXNQcm9taXNlQWxpa2U7XG5mdW5jdGlvbiBpc1Byb21pc2VBbGlrZShvYmplY3QpIHtcbiAgICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiB0eXBlb2Ygb2JqZWN0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwZW5kaW5nIHByb21pc2UsIG1lYW5pbmcgbm90XG4gKiBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG4gKi9cblEuaXNQZW5kaW5nID0gaXNQZW5kaW5nO1xuZnVuY3Rpb24gaXNQZW5kaW5nKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHZhbHVlIG9yIGZ1bGZpbGxlZFxuICogcHJvbWlzZS5cbiAqL1xuUS5pc0Z1bGZpbGxlZCA9IGlzRnVsZmlsbGVkO1xuZnVuY3Rpb24gaXNGdWxmaWxsZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuICFpc1Byb21pc2Uob2JqZWN0KSB8fCBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHJlamVjdGVkIHByb21pc2UuXG4gKi9cblEuaXNSZWplY3RlZCA9IGlzUmVqZWN0ZWQ7XG5mdW5jdGlvbiBpc1JlamVjdGVkKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59O1xuXG4vLy8vIEJFR0lOIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLy8gVGhpcyBwcm9taXNlIGxpYnJhcnkgY29uc3VtZXMgZXhjZXB0aW9ucyB0aHJvd24gaW4gaGFuZGxlcnMgc28gdGhleSBjYW4gYmVcbi8vIGhhbmRsZWQgYnkgYSBzdWJzZXF1ZW50IHByb21pc2UuICBUaGUgZXhjZXB0aW9ucyBnZXQgYWRkZWQgdG8gdGhpcyBhcnJheSB3aGVuXG4vLyB0aGV5IGFyZSBjcmVhdGVkLCBhbmQgcmVtb3ZlZCB3aGVuIHRoZXkgYXJlIGhhbmRsZWQuICBOb3RlIHRoYXQgaW4gRVM2IG9yXG4vLyBzaGltbWVkIGVudmlyb25tZW50cywgdGhpcyB3b3VsZCBuYXR1cmFsbHkgYmUgYSBgU2V0YC5cbnZhciB1bmhhbmRsZWRSZWFzb25zID0gW107XG52YXIgdW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG5cbmZ1bmN0aW9uIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpIHtcbiAgICB1bmhhbmRsZWRSZWFzb25zLmxlbmd0aCA9IDA7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyYWNrUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgaWYgKHJlYXNvbiAmJiB0eXBlb2YgcmVhc29uLnN0YWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChyZWFzb24uc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChcIihubyBzdGFjaykgXCIgKyByZWFzb24pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdW50cmFja1JlamVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdCA9IGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgaWYgKGF0ICE9PSAtMSkge1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXRSZXBvcnQgPSBhcnJheV9pbmRleE9mKHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgaWYgKGF0UmVwb3J0ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsIHVuaGFuZGxlZFJlYXNvbnNbYXRdLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdFJlcG9ydCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXQsIDEpO1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnNwbGljZShhdCwgMSk7XG4gICAgfVxufVxuXG5RLnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucyA9IHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucztcblxuUS5nZXRVbmhhbmRsZWRSZWFzb25zID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIE1ha2UgYSBjb3B5IHNvIHRoYXQgY29uc3VtZXJzIGNhbid0IGludGVyZmVyZSB3aXRoIG91ciBpbnRlcm5hbCBzdGF0ZS5cbiAgICByZXR1cm4gdW5oYW5kbGVkUmVhc29ucy5zbGljZSgpO1xufTtcblxuUS5zdG9wVW5oYW5kbGVkUmVqZWN0aW9uVHJhY2tpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG4gICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gZmFsc2U7XG59O1xuXG5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcblxuLy8vLyBFTkQgVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSByZWplY3RlZCBwcm9taXNlLlxuICogQHBhcmFtIHJlYXNvbiB2YWx1ZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlXG4gKi9cblEucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgIHZhciByZWplY3Rpb24gPSBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSBlcnJvciBoYXMgYmVlbiBoYW5kbGVkXG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB1bnRyYWNrUmVqZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkID8gcmVqZWN0ZWQocmVhc29uKSA6IHRoaXM7XG4gICAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiByZWFzb24gfTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIGhhcyBub3QgYmVlbiBoYW5kbGVkLlxuICAgIHRyYWNrUmVqZWN0aW9uKHJlamVjdGlvbiwgcmVhc29uKTtcblxuICAgIHJldHVybiByZWplY3Rpb247XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIGZ1bGZpbGxlZCBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2VcbiAqL1xuUS5mdWxmaWxsID0gZnVsZmlsbDtcbmZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZ2V0XCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwic2V0XCI6IGZ1bmN0aW9uIChuYW1lLCByaHMpIHtcbiAgICAgICAgICAgIHZhbHVlW25hbWVdID0gcmhzO1xuICAgICAgICB9LFxuICAgICAgICBcImRlbGV0ZVwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInBvc3RcIjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIC8vIE1hcmsgTWlsbGVyIHByb3Bvc2VzIHRoYXQgcG9zdCB3aXRoIG5vIG5hbWUgc2hvdWxkIGFwcGx5IGFcbiAgICAgICAgICAgIC8vIHByb21pc2VkIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG51bGwgfHwgbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFwiYXBwbHlcIjogZnVuY3Rpb24gKHRoaXNwLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodGhpc3AsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBcImtleXNcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdF9rZXlzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sIHZvaWQgMCwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwiZnVsZmlsbGVkXCIsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZW5hYmxlcyB0byBRIHByb21pc2VzLlxuICogQHBhcmFtIHByb21pc2UgdGhlbmFibGUgcHJvbWlzZVxuICogQHJldHVybnMgYSBRIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gY29lcmNlKHByb21pc2UpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZS50aGVuKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBhbiBvYmplY3Qgc3VjaCB0aGF0IGl0IHdpbGwgbmV2ZXIgYmVcbiAqIHRyYW5zZmVycmVkIGF3YXkgZnJvbSB0aGlzIHByb2Nlc3Mgb3ZlciBhbnkgcHJvbWlzZVxuICogY29tbXVuaWNhdGlvbiBjaGFubmVsLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgcHJvbWlzZSBhIHdyYXBwaW5nIG9mIHRoYXQgb2JqZWN0IHRoYXRcbiAqIGFkZGl0aW9uYWxseSByZXNwb25kcyB0byB0aGUgXCJpc0RlZlwiIG1lc3NhZ2VcbiAqIHdpdGhvdXQgYSByZWplY3Rpb24uXG4gKi9cblEubWFzdGVyID0gbWFzdGVyO1xuZnVuY3Rpb24gbWFzdGVyKG9iamVjdCkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJpc0RlZlwiOiBmdW5jdGlvbiAoKSB7fVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKG9wLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKTtcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBRKG9iamVjdCkuaW5zcGVjdCgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNwcmVhZHMgdGhlIHZhbHVlcyBvZiBhIHByb21pc2VkIGFycmF5IG9mIGFyZ3VtZW50cyBpbnRvIHRoZVxuICogZnVsZmlsbG1lbnQgY2FsbGJhY2suXG4gKiBAcGFyYW0gZnVsZmlsbGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdmFyaWFkaWMgYXJndW1lbnRzIGZyb20gdGhlXG4gKiBwcm9taXNlZCBhcnJheVxuICogQHBhcmFtIHJlamVjdGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgcHJvbWlzZVxuICogaXMgcmVqZWN0ZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb3IgdGhyb3duIGV4Y2VwdGlvbiBvZlxuICogZWl0aGVyIGNhbGxiYWNrLlxuICovXG5RLnNwcmVhZCA9IHNwcmVhZDtcbmZ1bmN0aW9uIHNwcmVhZCh2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS5zcHJlYWQoZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkudGhlbihmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGxlZC5hcHBseSh2b2lkIDAsIGFycmF5KTtcbiAgICB9LCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIFRoZSBhc3luYyBmdW5jdGlvbiBpcyBhIGRlY29yYXRvciBmb3IgZ2VuZXJhdG9yIGZ1bmN0aW9ucywgdHVybmluZ1xuICogdGhlbSBpbnRvIGFzeW5jaHJvbm91cyBnZW5lcmF0b3JzLiAgQWx0aG91Z2ggZ2VuZXJhdG9ycyBhcmUgb25seSBwYXJ0XG4gKiBvZiB0aGUgbmV3ZXN0IEVDTUFTY3JpcHQgNiBkcmFmdHMsIHRoaXMgY29kZSBkb2VzIG5vdCBjYXVzZSBzeW50YXhcbiAqIGVycm9ycyBpbiBvbGRlciBlbmdpbmVzLiAgVGhpcyBjb2RlIHNob3VsZCBjb250aW51ZSB0byB3b3JrIGFuZCB3aWxsXG4gKiBpbiBmYWN0IGltcHJvdmUgb3ZlciB0aW1lIGFzIHRoZSBsYW5ndWFnZSBpbXByb3Zlcy5cbiAqXG4gKiBFUzYgZ2VuZXJhdG9ycyBhcmUgY3VycmVudGx5IHBhcnQgb2YgVjggdmVyc2lvbiAzLjE5IHdpdGggdGhlXG4gKiAtLWhhcm1vbnktZ2VuZXJhdG9ycyBydW50aW1lIGZsYWcgZW5hYmxlZC4gIFNwaWRlck1vbmtleSBoYXMgaGFkIHRoZW1cbiAqIGZvciBsb25nZXIsIGJ1dCB1bmRlciBhbiBvbGRlciBQeXRob24taW5zcGlyZWQgZm9ybS4gIFRoaXMgZnVuY3Rpb25cbiAqIHdvcmtzIG9uIGJvdGgga2luZHMgb2YgZ2VuZXJhdG9ycy5cbiAqXG4gKiBEZWNvcmF0ZXMgYSBnZW5lcmF0b3IgZnVuY3Rpb24gc3VjaCB0aGF0OlxuICogIC0gaXQgbWF5IHlpZWxkIHByb21pc2VzXG4gKiAgLSBleGVjdXRpb24gd2lsbCBjb250aW51ZSB3aGVuIHRoYXQgcHJvbWlzZSBpcyBmdWxmaWxsZWRcbiAqICAtIHRoZSB2YWx1ZSBvZiB0aGUgeWllbGQgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqICAtIGl0IHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlICh3aGVuIHRoZSBnZW5lcmF0b3JcbiAqICAgIHN0b3BzIGl0ZXJhdGluZylcbiAqICAtIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24gcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqICAgIG9mIHRoZSBnZW5lcmF0b3Igb3IgdGhlIGZpcnN0IHJlamVjdGVkIHByb21pc2UgYW1vbmcgdGhvc2VcbiAqICAgIHlpZWxkZWQuXG4gKiAgLSBpZiBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhlIGdlbmVyYXRvciwgaXQgcHJvcGFnYXRlcyB0aHJvdWdoXG4gKiAgICBldmVyeSBmb2xsb3dpbmcgeWllbGQgdW50aWwgaXQgaXMgY2F1Z2h0LCBvciB1bnRpbCBpdCBlc2NhcGVzXG4gKiAgICB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGFsdG9nZXRoZXIsIGFuZCBpcyB0cmFuc2xhdGVkIGludG8gYVxuICogICAgcmVqZWN0aW9uIGZvciB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZGVjb3JhdGVkIGdlbmVyYXRvci5cbiAqL1xuUS5hc3luYyA9IGFzeW5jO1xuZnVuY3Rpb24gYXN5bmMobWFrZUdlbmVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInNlbmRcIiwgYXJnIGlzIGEgdmFsdWVcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwidGhyb3dcIiwgYXJnIGlzIGFuIGV4Y2VwdGlvblxuICAgICAgICBmdW5jdGlvbiBjb250aW51ZXIodmVyYiwgYXJnKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICAgICAgICAvLyBVbnRpbCBWOCAzLjE5IC8gQ2hyb21pdW0gMjkgaXMgcmVsZWFzZWQsIFNwaWRlck1vbmtleSBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gZW5naW5lIHRoYXQgaGFzIGEgZGVwbG95ZWQgYmFzZSBvZiBicm93c2VycyB0aGF0IHN1cHBvcnQgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIFNNJ3MgZ2VuZXJhdG9ycyB1c2UgdGhlIFB5dGhvbi1pbnNwaXJlZCBzZW1hbnRpY3Mgb2ZcbiAgICAgICAgICAgIC8vIG91dGRhdGVkIEVTNiBkcmFmdHMuICBXZSB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgRVM2LCBidXQgd2UnZCBhbHNvXG4gICAgICAgICAgICAvLyBsaWtlIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gdXNlIGdlbmVyYXRvcnMgaW4gZGVwbG95ZWQgYnJvd3NlcnMsIHNvXG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHN1cHBvcnQgUHl0aG9uLXN0eWxlIGdlbmVyYXRvcnMuICBBdCBzb21lIHBvaW50IHdlIGNhbiByZW1vdmVcbiAgICAgICAgICAgIC8vIHRoaXMgYmxvY2suXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgU3RvcEl0ZXJhdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIC8vIEVTNiBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBRKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LnZhbHVlLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTcGlkZXJNb25rZXkgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBSZW1vdmUgdGhpcyBjYXNlIHdoZW4gU00gZG9lcyBFUzYgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShleGNlcHRpb24udmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdCwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBnZW5lcmF0b3IgPSBtYWtlR2VuZXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJuZXh0XCIpO1xuICAgICAgICB2YXIgZXJyYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJ0aHJvd1wiKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3Bhd24gZnVuY3Rpb24gaXMgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCBhc3luYyB0aGF0IGltbWVkaWF0ZWx5XG4gKiBjYWxscyB0aGUgZ2VuZXJhdG9yIGFuZCBhbHNvIGVuZHMgdGhlIHByb21pc2UgY2hhaW4sIHNvIHRoYXQgYW55XG4gKiB1bmhhbmRsZWQgZXJyb3JzIGFyZSB0aHJvd24gaW5zdGVhZCBvZiBmb3J3YXJkZWQgdG8gdGhlIGVycm9yXG4gKiBoYW5kbGVyLiBUaGlzIGlzIHVzZWZ1bCBiZWNhdXNlIGl0J3MgZXh0cmVtZWx5IGNvbW1vbiB0byBydW5cbiAqIGdlbmVyYXRvcnMgYXQgdGhlIHRvcC1sZXZlbCB0byB3b3JrIHdpdGggbGlicmFyaWVzLlxuICovXG5RLnNwYXduID0gc3Bhd247XG5mdW5jdGlvbiBzcGF3bihtYWtlR2VuZXJhdG9yKSB7XG4gICAgUS5kb25lKFEuYXN5bmMobWFrZUdlbmVyYXRvcikoKSk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBpbnRlcmZhY2Ugb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuLyoqXG4gKiBUaHJvd3MgYSBSZXR1cm5WYWx1ZSBleGNlcHRpb24gdG8gc3RvcCBhbiBhc3luY2hyb25vdXMgZ2VuZXJhdG9yLlxuICpcbiAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgc3RvcC1nYXAgbWVhc3VyZSB0byBzdXBwb3J0IGdlbmVyYXRvciByZXR1cm5cbiAqIHZhbHVlcyBpbiBvbGRlciBGaXJlZm94L1NwaWRlck1vbmtleS4gIEluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBFUzZcbiAqIGdlbmVyYXRvcnMgbGlrZSBDaHJvbWl1bSAyOSwganVzdCB1c2UgXCJyZXR1cm5cIiBpbiB5b3VyIGdlbmVyYXRvclxuICogZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSB0aGUgcmV0dXJuIHZhbHVlIGZvciB0aGUgc3Vycm91bmRpbmcgZ2VuZXJhdG9yXG4gKiBAdGhyb3dzIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB3aXRoIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBFUzYgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24qICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgcmV0dXJuIGZvbyArIGJhcjtcbiAqIH0pXG4gKiAvLyBPbGRlciBTcGlkZXJNb25rZXkgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24gKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICBRLnJldHVybihmb28gKyBiYXIpO1xuICogfSlcbiAqL1xuUVtcInJldHVyblwiXSA9IF9yZXR1cm47XG5mdW5jdGlvbiBfcmV0dXJuKHZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IFFSZXR1cm5WYWx1ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIHByb21pc2VkIGZ1bmN0aW9uIGRlY29yYXRvciBlbnN1cmVzIHRoYXQgYW55IHByb21pc2UgYXJndW1lbnRzXG4gKiBhcmUgc2V0dGxlZCBhbmQgcGFzc2VkIGFzIHZhbHVlcyAoYHRoaXNgIGlzIGFsc28gc2V0dGxlZCBhbmQgcGFzc2VkXG4gKiBhcyBhIHZhbHVlKS4gIEl0IHdpbGwgYWxzbyBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gaXNcbiAqIGFsd2F5cyBhIHByb21pc2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBRLnByb21pc2VkKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgcmV0dXJuIGEgKyBiO1xuICogfSk7XG4gKiBhZGQoUShhKSwgUShCKSk7XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGRlY29yYXRlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBoYXMgYmVlbiBkZWNvcmF0ZWQuXG4gKi9cblEucHJvbWlzZWQgPSBwcm9taXNlZDtcbmZ1bmN0aW9uIHByb21pc2VkKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNwcmVhZChbdGhpcywgYWxsKGFyZ3VtZW50cyldLCBmdW5jdGlvbiAoc2VsZiwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIHNlbmRzIGEgbWVzc2FnZSB0byBhIHZhbHVlIGluIGEgZnV0dXJlIHR1cm5cbiAqIEBwYXJhbSBvYmplY3QqIHRoZSByZWNpcGllbnRcbiAqIEBwYXJhbSBvcCB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBvcGVyYXRpb24sIGUuZy4sIFwid2hlblwiLFxuICogQHBhcmFtIGFyZ3MgZnVydGhlciBhcmd1bWVudHMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm5zIHJlc3VsdCB7UHJvbWlzZX0gYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb25cbiAqL1xuUS5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZnVuY3Rpb24gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2gob3AsIGFyZ3MpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChvcCwgYXJncykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChkZWZlcnJlZC5yZXNvbHZlLCBvcCwgYXJncyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZ2V0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBwcm9wZXJ0eSB2YWx1ZVxuICovXG5RLmdldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIG9iamVjdCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBzZXRcbiAqIEBwYXJhbSB2YWx1ZSAgICAgbmV3IHZhbHVlIG9mIHByb3BlcnR5XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5kZWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIHZhbHVlICAgICBhIHZhbHVlIHRvIHBvc3QsIHR5cGljYWxseSBhbiBhcnJheSBvZlxuICogICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uIGFyZ3VtZW50cyBmb3IgcHJvbWlzZXMgdGhhdFxuICogICAgICAgICAgICAgICAgICBhcmUgdWx0aW1hdGVseSBiYWNrZWQgd2l0aCBgcmVzb2x2ZWAgdmFsdWVzLFxuICogICAgICAgICAgICAgICAgICBhcyBvcHBvc2VkIHRvIHRob3NlIGJhY2tlZCB3aXRoIFVSTHNcbiAqICAgICAgICAgICAgICAgICAgd2hlcmVpbiB0aGUgcG9zdGVkIHZhbHVlIGNhbiBiZSBhbnlcbiAqICAgICAgICAgICAgICAgICAgSlNPTiBzZXJpYWxpemFibGUgb2JqZWN0LlxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cbi8vIGJvdW5kIGxvY2FsbHkgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IG90aGVyIG1ldGhvZHNcblEubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgaW52b2NhdGlvbiBhcmd1bWVudHNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5Qcm9taXNlLnByb3RvdHlwZS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIGFyZ3MgICAgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYXBwbHkgPSBmdW5jdGlvbiAob2JqZWN0LCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIENhbGxzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUVtcInRyeVwiXSA9XG5RLmZjYWxsID0gZnVuY3Rpb24gKG9iamVjdCAvKiAuLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cyldKTtcbn07XG5cbi8qKlxuICogQmluZHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uLCB0cmFuc2Zvcm1pbmcgcmV0dXJuIHZhbHVlcyBpbnRvIGEgZnVsZmlsbGVkXG4gKiBwcm9taXNlIGFuZCB0aHJvd24gZXJyb3JzIGludG8gYSByZWplY3RlZCBvbmUuXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZiaW5kID0gZnVuY3Rpb24gKG9iamVjdCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gUShvYmplY3QpO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblByb21pc2UucHJvdG90eXBlLmZiaW5kID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgbmFtZXMgb2YgdGhlIG93bmVkIHByb3BlcnRpZXMgb2YgYSBwcm9taXNlZFxuICogb2JqZWN0IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUga2V5cyBvZiB0aGUgZXZlbnR1YWxseSBzZXR0bGVkIG9iamVjdFxuICovXG5RLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkuICBJZiBhbnkgb2ZcbiAqIHRoZSBwcm9taXNlcyBnZXRzIHJlamVjdGVkLCB0aGUgd2hvbGUgYXJyYXkgaXMgcmVqZWN0ZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXNcbiAqL1xuLy8gQnkgTWFyayBNaWxsZXJcbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPXN0cmF3bWFuOmNvbmN1cnJlbmN5JnJldj0xMzA4Nzc2NTIxI2FsbGZ1bGZpbGxlZFxuUS5hbGwgPSBhbGw7XG5mdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb21pc2UsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc25hcHNob3Q7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgaXNQcm9taXNlKHByb21pc2UpICYmXG4gICAgICAgICAgICAgICAgKHNuYXBzaG90ID0gcHJvbWlzZS5pbnNwZWN0KCkpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSBzbmFwc2hvdC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgKytwZW5kaW5nQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hlbihcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHsgaW5kZXg6IGluZGV4LCB2YWx1ZTogcHJvZ3Jlc3MgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2Ugb2YgYW4gYXJyYXkuIFByaW9yIHJlamVjdGVkIHByb21pc2VzIGFyZVxuICogaWdub3JlZC4gIFJlamVjdHMgb25seSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIG9yIHByb21pc2VzIGZvciB2YWx1ZXNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmdWxmaWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2UsXG4gKiBvciBhIHJlamVjdGVkIHByb21pc2UgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqL1xuUS5hbnkgPSBhbnk7XG5cbmZ1bmN0aW9uIGFueShwcm9taXNlcykge1xuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHZhciBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uIChwcmV2LCBjdXJyZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHByb21pc2VzW2luZGV4XTtcblxuICAgICAgICBwZW5kaW5nQ291bnQrKztcblxuICAgICAgICB3aGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvblByb2dyZXNzKTtcbiAgICAgICAgZnVuY3Rpb24gb25GdWxmaWxsZWQocmVzdWx0KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25SZWplY3RlZChlcnIpIHtcbiAgICAgICAgICAgIHBlbmRpbmdDb3VudC0tO1xuICAgICAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHZhciByZWplY3Rpb24gPSBlcnIgfHwgbmV3IEVycm9yKFwiXCIgKyBlcnIpO1xuXG4gICAgICAgICAgICAgICAgcmVqZWN0aW9uLm1lc3NhZ2UgPSAoXCJRIGNhbid0IGdldCBmdWxmaWxsbWVudCB2YWx1ZSBmcm9tIGFueSBwcm9taXNlLCBhbGwgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcInByb21pc2VzIHdlcmUgcmVqZWN0ZWQuIExhc3QgZXJyb3IgbWVzc2FnZTogXCIgKyByZWplY3Rpb24ubWVzc2FnZSk7XG5cbiAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QocmVqZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBvblByb2dyZXNzKHByb2dyZXNzKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkoe1xuICAgICAgICAgICAgICAgIGluZGV4OiBpbmRleCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogcHJvZ3Jlc3NcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSwgdW5kZWZpbmVkKTtcblxuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5hbnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFueSh0aGlzKTtcbn07XG5cbi8qKlxuICogV2FpdHMgZm9yIGFsbCBwcm9taXNlcyB0byBiZSBzZXR0bGVkLCBlaXRoZXIgZnVsZmlsbGVkIG9yXG4gKiByZWplY3RlZC4gIFRoaXMgaXMgZGlzdGluY3QgZnJvbSBgYWxsYCBzaW5jZSB0aGF0IHdvdWxkIHN0b3BcbiAqIHdhaXRpbmcgYXQgdGhlIGZpcnN0IHJlamVjdGlvbi4gIFRoZSBwcm9taXNlIHJldHVybmVkIGJ5XG4gKiBgYWxsUmVzb2x2ZWRgIHdpbGwgbmV2ZXIgYmUgcmVqZWN0ZWQuXG4gKiBAcGFyYW0gcHJvbWlzZXMgYSBwcm9taXNlIGZvciBhbiBhcnJheSAob3IgYW4gYXJyYXkpIG9mIHByb21pc2VzXG4gKiAob3IgdmFsdWVzKVxuICogQHJldHVybiBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHByb21pc2VzXG4gKi9cblEuYWxsUmVzb2x2ZWQgPSBkZXByZWNhdGUoYWxsUmVzb2x2ZWQsIFwiYWxsUmVzb2x2ZWRcIiwgXCJhbGxTZXR0bGVkXCIpO1xuZnVuY3Rpb24gYWxsUmVzb2x2ZWQocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHByb21pc2VzID0gYXJyYXlfbWFwKHByb21pc2VzLCBRKTtcbiAgICAgICAgcmV0dXJuIHdoZW4oYWxsKGFycmF5X21hcChwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybiB3aGVuKHByb21pc2UsIG5vb3AsIG5vb3ApO1xuICAgICAgICB9KSksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlcztcbiAgICAgICAgfSk7XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFsbFJlc29sdmVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGxSZXNvbHZlZCh0aGlzKTtcbn07XG5cbi8qKlxuICogQHNlZSBQcm9taXNlI2FsbFNldHRsZWRcbiAqL1xuUS5hbGxTZXR0bGVkID0gYWxsU2V0dGxlZDtcbmZ1bmN0aW9uIGFsbFNldHRsZWQocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gUShwcm9taXNlcykuYWxsU2V0dGxlZCgpO1xufVxuXG4vKipcbiAqIFR1cm5zIGFuIGFycmF5IG9mIHByb21pc2VzIGludG8gYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGVpciBzdGF0ZXMgKGFzXG4gKiByZXR1cm5lZCBieSBgaW5zcGVjdGApIHdoZW4gdGhleSBoYXZlIGFsbCBzZXR0bGVkLlxuICogQHBhcmFtIHtBcnJheVtBbnkqXX0gdmFsdWVzIGFuIGFycmF5IChvciBwcm9taXNlIGZvciBhbiBhcnJheSkgb2YgdmFsdWVzIChvclxuICogcHJvbWlzZXMgZm9yIHZhbHVlcylcbiAqIEByZXR1cm5zIHtBcnJheVtTdGF0ZV19IGFuIGFycmF5IG9mIHN0YXRlcyBmb3IgdGhlIHJlc3BlY3RpdmUgdmFsdWVzLlxuICovXG5Qcm9taXNlLnByb3RvdHlwZS5hbGxTZXR0bGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHJldHVybiBhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcHJvbWlzZSA9IFEocHJvbWlzZSk7XG4gICAgICAgICAgICBmdW5jdGlvbiByZWdhcmRsZXNzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlLmluc3BlY3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlLnRoZW4ocmVnYXJkbGVzcywgcmVnYXJkbGVzcyk7XG4gICAgICAgIH0pKTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogQ2FwdHVyZXMgdGhlIGZhaWx1cmUgb2YgYSBwcm9taXNlLCBnaXZpbmcgYW4gb3BvcnR1bml0eSB0byByZWNvdmVyXG4gKiB3aXRoIGEgY2FsbGJhY2suICBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSBpcyBmdWxmaWxsZWQsIHRoZSByZXR1cm5lZFxuICogcHJvbWlzZSBpcyBmdWxmaWxsZWQuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gZnVsZmlsbCB0aGUgcmV0dXJuZWQgcHJvbWlzZSBpZiB0aGVcbiAqIGdpdmVuIHByb21pc2UgaXMgcmVqZWN0ZWRcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgY2FsbGJhY2tcbiAqL1xuUS5mYWlsID0gLy8gWFhYIGxlZ2FjeVxuUVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKG9iamVjdCwgcmVqZWN0ZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCByZWplY3RlZCk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5mYWlsID0gLy8gWFhYIGxlZ2FjeVxuUHJvbWlzZS5wcm90b3R5cGVbXCJjYXRjaFwiXSA9IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4odm9pZCAwLCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIEF0dGFjaGVzIGEgbGlzdGVuZXIgdGhhdCBjYW4gcmVzcG9uZCB0byBwcm9ncmVzcyBub3RpZmljYXRpb25zIGZyb20gYVxuICogcHJvbWlzZSdzIG9yaWdpbmF0aW5nIGRlZmVycmVkLiBUaGlzIGxpc3RlbmVyIHJlY2VpdmVzIHRoZSBleGFjdCBhcmd1bWVudHNcbiAqIHBhc3NlZCB0byBgYGRlZmVycmVkLm5vdGlmeWBgLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlIGZvciBzb21ldGhpbmdcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRvIHJlY2VpdmUgYW55IHByb2dyZXNzIG5vdGlmaWNhdGlvbnNcbiAqIEByZXR1cm5zIHRoZSBnaXZlbiBwcm9taXNlLCB1bmNoYW5nZWRcbiAqL1xuUS5wcm9ncmVzcyA9IHByb2dyZXNzO1xuZnVuY3Rpb24gcHJvZ3Jlc3Mob2JqZWN0LCBwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aGVuKHZvaWQgMCwgdm9pZCAwLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUucHJvZ3Jlc3MgPSBmdW5jdGlvbiAocHJvZ3Jlc3NlZCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufTtcblxuLyoqXG4gKiBQcm92aWRlcyBhbiBvcHBvcnR1bml0eSB0byBvYnNlcnZlIHRoZSBzZXR0bGluZyBvZiBhIHByb21pc2UsXG4gKiByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlIHByb21pc2UgaXMgZnVsZmlsbGVkIG9yIHJlamVjdGVkLiAgRm9yd2FyZHNcbiAqIHRoZSByZXNvbHV0aW9uIHRvIHRoZSByZXR1cm5lZCBwcm9taXNlIHdoZW4gdGhlIGNhbGxiYWNrIGlzIGRvbmUuXG4gKiBUaGUgY2FsbGJhY2sgY2FuIHJldHVybiBhIHByb21pc2UgdG8gZGVmZXIgY29tcGxldGlvbi5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gb2JzZXJ2ZSB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW5cbiAqIHByb21pc2UsIHRha2VzIG5vIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2Ugd2hlblxuICogYGBmaW5gYCBpcyBkb25lLlxuICovXG5RLmZpbiA9IC8vIFhYWCBsZWdhY3lcblFbXCJmaW5hbGx5XCJdID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpW1wiZmluYWxseVwiXShjYWxsYmFjayk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5maW4gPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrIHx8IHR5cGVvZiBjYWxsYmFjay5hcHBseSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlEgY2FuJ3QgYXBwbHkgZmluYWxseSBjYWxsYmFja1wiKTtcbiAgICB9XG4gICAgY2FsbGJhY2sgPSBRKGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICAvLyBUT0RPIGF0dGVtcHQgdG8gcmVjeWNsZSB0aGUgcmVqZWN0aW9uIHdpdGggXCJ0aGlzXCIuXG4gICAgICAgIHJldHVybiBjYWxsYmFjay5mY2FsbCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhyb3cgcmVhc29uO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogVGVybWluYXRlcyBhIGNoYWluIG9mIHByb21pc2VzLCBmb3JjaW5nIHJlamVjdGlvbnMgdG8gYmVcbiAqIHRocm93biBhcyBleGNlcHRpb25zLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlIGF0IHRoZSBlbmQgb2YgYSBjaGFpbiBvZiBwcm9taXNlc1xuICogQHJldHVybnMgbm90aGluZ1xuICovXG5RLmRvbmUgPSBmdW5jdGlvbiAob2JqZWN0LCBmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZG9uZShmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kb25lID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzKSB7XG4gICAgdmFyIG9uVW5oYW5kbGVkRXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgLy8gZm9yd2FyZCB0byBhIGZ1dHVyZSB0dXJuIHNvIHRoYXQgYGB3aGVuYGBcbiAgICAgICAgLy8gZG9lcyBub3QgY2F0Y2ggaXQgYW5kIHR1cm4gaXQgaW50byBhIHJlamVjdGlvbi5cbiAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBtYWtlU3RhY2tUcmFjZUxvbmcoZXJyb3IsIHByb21pc2UpO1xuICAgICAgICAgICAgaWYgKFEub25lcnJvcikge1xuICAgICAgICAgICAgICAgIFEub25lcnJvcihlcnJvcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gQXZvaWQgdW5uZWNlc3NhcnkgYG5leHRUaWNrYGluZyB2aWEgYW4gdW5uZWNlc3NhcnkgYHdoZW5gLlxuICAgIHZhciBwcm9taXNlID0gZnVsZmlsbGVkIHx8IHJlamVjdGVkIHx8IHByb2dyZXNzID9cbiAgICAgICAgdGhpcy50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzKSA6XG4gICAgICAgIHRoaXM7XG5cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgcHJvY2VzcyAmJiBwcm9jZXNzLmRvbWFpbikge1xuICAgICAgICBvblVuaGFuZGxlZEVycm9yID0gcHJvY2Vzcy5kb21haW4uYmluZChvblVuaGFuZGxlZEVycm9yKTtcbiAgICB9XG5cbiAgICBwcm9taXNlLnRoZW4odm9pZCAwLCBvblVuaGFuZGxlZEVycm9yKTtcbn07XG5cbi8qKlxuICogQ2F1c2VzIGEgcHJvbWlzZSB0byBiZSByZWplY3RlZCBpZiBpdCBkb2VzIG5vdCBnZXQgZnVsZmlsbGVkIGJlZm9yZVxuICogc29tZSBtaWxsaXNlY29uZHMgdGltZSBvdXQuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2VcbiAqIEBwYXJhbSB7TnVtYmVyfSBtaWxsaXNlY29uZHMgdGltZW91dFxuICogQHBhcmFtIHtBbnkqfSBjdXN0b20gZXJyb3IgbWVzc2FnZSBvciBFcnJvciBvYmplY3QgKG9wdGlvbmFsKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBpZiBpdCBpc1xuICogZnVsZmlsbGVkIGJlZm9yZSB0aGUgdGltZW91dCwgb3RoZXJ3aXNlIHJlamVjdGVkLlxuICovXG5RLnRpbWVvdXQgPSBmdW5jdGlvbiAob2JqZWN0LCBtcywgZXJyb3IpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRpbWVvdXQobXMsIGVycm9yKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRpbWVvdXQgPSBmdW5jdGlvbiAobXMsIGVycm9yKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghZXJyb3IgfHwgXCJzdHJpbmdcIiA9PT0gdHlwZW9mIGVycm9yKSB7XG4gICAgICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihlcnJvciB8fCBcIlRpbWVkIG91dCBhZnRlciBcIiArIG1zICsgXCIgbXNcIik7XG4gICAgICAgICAgICBlcnJvci5jb2RlID0gXCJFVElNRURPVVRcIjtcbiAgICAgICAgfVxuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXJyb3IpO1xuICAgIH0sIG1zKTtcblxuICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIChleGNlcHRpb24pIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChleGNlcHRpb24pO1xuICAgIH0sIGRlZmVycmVkLm5vdGlmeSk7XG5cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSBnaXZlbiB2YWx1ZSAob3IgcHJvbWlzZWQgdmFsdWUpLCBzb21lXG4gKiBtaWxsaXNlY29uZHMgYWZ0ZXIgaXQgcmVzb2x2ZWQuIFBhc3NlcyByZWplY3Rpb25zIGltbWVkaWF0ZWx5LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlbiBwcm9taXNlIGFmdGVyIG1pbGxpc2Vjb25kc1xuICogdGltZSBoYXMgZWxhcHNlZCBzaW5jZSB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZS5cbiAqIElmIHRoZSBnaXZlbiBwcm9taXNlIHJlamVjdHMsIHRoYXQgaXMgcGFzc2VkIGltbWVkaWF0ZWx5LlxuICovXG5RLmRlbGF5ID0gZnVuY3Rpb24gKG9iamVjdCwgdGltZW91dCkge1xuICAgIGlmICh0aW1lb3V0ID09PSB2b2lkIDApIHtcbiAgICAgICAgdGltZW91dCA9IG9iamVjdDtcbiAgICAgICAgb2JqZWN0ID0gdm9pZCAwO1xuICAgIH1cbiAgICByZXR1cm4gUShvYmplY3QpLmRlbGF5KHRpbWVvdXQpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZGVsYXkgPSBmdW5jdGlvbiAodGltZW91dCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZSh2YWx1ZSk7XG4gICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgYXMgYW4gYXJyYXksIGFuZCByZXR1cm5zIGEgcHJvbWlzZS5cbiAqXG4gKiAgICAgIFEubmZhcHBseShGUy5yZWFkRmlsZSwgW19fZmlsZW5hbWVdKVxuICogICAgICAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogICAgICB9KVxuICpcbiAqL1xuUS5uZmFwcGx5ID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEoY2FsbGJhY2spLm5mYXBwbHkoYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uZmFwcGx5ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3MpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBQYXNzZXMgYSBjb250aW51YXRpb24gdG8gYSBOb2RlIGZ1bmN0aW9uLCB3aGljaCBpcyBjYWxsZWQgd2l0aCB0aGUgZ2l2ZW5cbiAqIGFyZ3VtZW50cyBwcm92aWRlZCBpbmRpdmlkdWFsbHksIGFuZCByZXR1cm5zIGEgcHJvbWlzZS5cbiAqIEBleGFtcGxlXG4gKiBRLm5mY2FsbChGUy5yZWFkRmlsZSwgX19maWxlbmFtZSlcbiAqIC50aGVuKGZ1bmN0aW9uIChjb250ZW50KSB7XG4gKiB9KVxuICpcbiAqL1xuUS5uZmNhbGwgPSBmdW5jdGlvbiAoY2FsbGJhY2sgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIFEoY2FsbGJhY2spLm5mYXBwbHkoYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFdyYXBzIGEgTm9kZUpTIGNvbnRpbnVhdGlvbiBwYXNzaW5nIGZ1bmN0aW9uIGFuZCByZXR1cm5zIGFuIGVxdWl2YWxlbnRcbiAqIHZlcnNpb24gdGhhdCByZXR1cm5zIGEgcHJvbWlzZS5cbiAqIEBleGFtcGxlXG4gKiBRLm5mYmluZChGUy5yZWFkRmlsZSwgX19maWxlbmFtZSkoXCJ1dGYtOFwiKVxuICogLnRoZW4oY29uc29sZS5sb2cpXG4gKiAuZG9uZSgpXG4gKi9cblEubmZiaW5kID1cblEuZGVub2RlaWZ5ID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgaWYgKGNhbGxiYWNrID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUSBjYW4ndCB3cmFwIGFuIHVuZGVmaW5lZCBmdW5jdGlvblwiKTtcbiAgICB9XG4gICAgdmFyIGJhc2VBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbm9kZUFyZ3MgPSBiYXNlQXJncy5jb25jYXQoYXJyYXlfc2xpY2UoYXJndW1lbnRzKSk7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICAgICAgUShjYWxsYmFjaykuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH07XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uZmJpbmQgPVxuUHJvbWlzZS5wcm90b3R5cGUuZGVub2RlaWZ5ID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMpO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5kZW5vZGVpZnkuYXBwbHkodm9pZCAwLCBhcmdzKTtcbn07XG5cblEubmJpbmQgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGJhc2VBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbm9kZUFyZ3MgPSBiYXNlQXJncy5jb25jYXQoYXJyYXlfc2xpY2UoYXJndW1lbnRzKSk7XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICAgICAgZnVuY3Rpb24gYm91bmQoKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkodGhpc3AsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgUShib3VuZCkuZmFwcGx5KG5vZGVBcmdzKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH07XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uYmluZCA9IGZ1bmN0aW9uICgvKnRoaXNwLCAuLi5hcmdzKi8pIHtcbiAgICB2YXIgYXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMCk7XG4gICAgYXJncy51bnNoaWZ0KHRoaXMpO1xuICAgIHJldHVybiBRLm5iaW5kLmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2sgd2l0aCBhIGdpdmVuIGFycmF5IG9mIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkIGNhbGxiYWNrLlxuICogQHBhcmFtIG9iamVjdCBhbiBvYmplY3QgdGhhdCBoYXMgdGhlIG5hbWVkIG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgbmFtZSBvZiB0aGUgbWV0aG9kIG9mIG9iamVjdFxuICogQHBhcmFtIHtBcnJheX0gYXJncyBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbWV0aG9kOyB0aGUgY2FsbGJhY2tcbiAqIHdpbGwgYmUgcHJvdmlkZWQgYnkgUSBhbmQgYXBwZW5kZWQgdG8gdGhlc2UgYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgdmFsdWUgb3IgZXJyb3JcbiAqL1xuUS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEubnBvc3QgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lLCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5ucG9zdChuYW1lLCBhcmdzKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5tYXBwbHkgPSAvLyBYWFggQXMgcHJvcG9zZWQgYnkgXCJSZWRzYW5kcm9cIlxuUHJvbWlzZS5wcm90b3R5cGUubnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3MgfHwgW10pO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogQ2FsbHMgYSBtZXRob2Qgb2YgYSBOb2RlLXN0eWxlIG9iamVjdCB0aGF0IGFjY2VwdHMgYSBOb2RlLXN0eWxlXG4gKiBjYWxsYmFjaywgZm9yd2FyZGluZyB0aGUgZ2l2ZW4gdmFyaWFkaWMgYXJndW1lbnRzLCBwbHVzIGEgcHJvdmlkZWRcbiAqIGNhbGxiYWNrIGFyZ3VtZW50LlxuICogQHBhcmFtIG9iamVjdCBhbiBvYmplY3QgdGhhdCBoYXMgdGhlIG5hbWVkIG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgbmFtZSBvZiB0aGUgbWV0aG9kIG9mIG9iamVjdFxuICogQHBhcmFtIC4uLmFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrIHdpbGxcbiAqIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubnNlbmQgPSAvLyBYWFggQmFzZWQgb24gTWFyayBNaWxsZXIncyBwcm9wb3NlZCBcInNlbmRcIlxuUS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5RLm5pbnZva2UgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICBRKG9iamVjdCkuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblByb21pc2UucHJvdG90eXBlLm5tY2FsbCA9IC8vIFhYWCBCYXNlZCBvbiBcIlJlZHNhbmRybydzXCIgcHJvcG9zYWxcblByb21pc2UucHJvdG90eXBlLm5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5kaXNwYXRjaChcInBvc3RcIiwgW25hbWUsIG5vZGVBcmdzXSkuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBJZiBhIGZ1bmN0aW9uIHdvdWxkIGxpa2UgdG8gc3VwcG9ydCBib3RoIE5vZGUgY29udGludWF0aW9uLXBhc3Npbmctc3R5bGUgYW5kXG4gKiBwcm9taXNlLXJldHVybmluZy1zdHlsZSwgaXQgY2FuIGVuZCBpdHMgaW50ZXJuYWwgcHJvbWlzZSBjaGFpbiB3aXRoXG4gKiBgbm9kZWlmeShub2RlYmFjaylgLCBmb3J3YXJkaW5nIHRoZSBvcHRpb25hbCBub2RlYmFjayBhcmd1bWVudC4gIElmIHRoZSB1c2VyXG4gKiBlbGVjdHMgdG8gdXNlIGEgbm9kZWJhY2ssIHRoZSByZXN1bHQgd2lsbCBiZSBzZW50IHRoZXJlLiAgSWYgdGhleSBkbyBub3RcbiAqIHBhc3MgYSBub2RlYmFjaywgdGhleSB3aWxsIHJlY2VpdmUgdGhlIHJlc3VsdCBwcm9taXNlLlxuICogQHBhcmFtIG9iamVjdCBhIHJlc3VsdCAob3IgYSBwcm9taXNlIGZvciBhIHJlc3VsdClcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG5vZGViYWNrIGEgTm9kZS5qcy1zdHlsZSBjYWxsYmFja1xuICogQHJldHVybnMgZWl0aGVyIHRoZSBwcm9taXNlIG9yIG5vdGhpbmdcbiAqL1xuUS5ub2RlaWZ5ID0gbm9kZWlmeTtcbmZ1bmN0aW9uIG5vZGVpZnkob2JqZWN0LCBub2RlYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdCkubm9kZWlmeShub2RlYmFjayk7XG59XG5cblByb21pc2UucHJvdG90eXBlLm5vZGVpZnkgPSBmdW5jdGlvbiAobm9kZWJhY2spIHtcbiAgICBpZiAobm9kZWJhY2spIHtcbiAgICAgICAgdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbm9kZWJhY2sobnVsbCwgdmFsdWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbm9kZWJhY2soZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn07XG5cblEubm9Db25mbGljdCA9IGZ1bmN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlEubm9Db25mbGljdCBvbmx5IHdvcmtzIHdoZW4gUSBpcyB1c2VkIGFzIGEgZ2xvYmFsXCIpO1xufTtcblxuLy8gQWxsIGNvZGUgYmVmb3JlIHRoaXMgcG9pbnQgd2lsbCBiZSBmaWx0ZXJlZCBmcm9tIHN0YWNrIHRyYWNlcy5cbnZhciBxRW5kaW5nTGluZSA9IGNhcHR1cmVMaW5lKCk7XG5cbnJldHVybiBRO1xuXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHJlcGxhY2UgPSBTdHJpbmcucHJvdG90eXBlLnJlcGxhY2U7XG52YXIgcGVyY2VudFR3ZW50aWVzID0gLyUyMC9nO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxudmFyIEZvcm1hdCA9IHtcbiAgICBSRkMxNzM4OiAnUkZDMTczOCcsXG4gICAgUkZDMzk4NjogJ1JGQzM5ODYnXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHV0aWwuYXNzaWduKFxuICAgIHtcbiAgICAgICAgJ2RlZmF1bHQnOiBGb3JtYXQuUkZDMzk4NixcbiAgICAgICAgZm9ybWF0dGVyczoge1xuICAgICAgICAgICAgUkZDMTczODogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcGxhY2UuY2FsbCh2YWx1ZSwgcGVyY2VudFR3ZW50aWVzLCAnKycpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFJGQzM5ODY6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBGb3JtYXRcbik7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBzdHJpbmdpZnkgPSByZXF1aXJlKCcuL3N0cmluZ2lmeScpO1xudmFyIHBhcnNlID0gcmVxdWlyZSgnLi9wYXJzZScpO1xudmFyIGZvcm1hdHMgPSByZXF1aXJlKCcuL2Zvcm1hdHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgZm9ybWF0czogZm9ybWF0cyxcbiAgICBwYXJzZTogcGFyc2UsXG4gICAgc3RyaW5naWZ5OiBzdHJpbmdpZnlcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbnZhciBkZWZhdWx0cyA9IHtcbiAgICBhbGxvd0RvdHM6IGZhbHNlLFxuICAgIGFsbG93UHJvdG90eXBlczogZmFsc2UsXG4gICAgYXJyYXlMaW1pdDogMjAsXG4gICAgY2hhcnNldDogJ3V0Zi04JyxcbiAgICBjaGFyc2V0U2VudGluZWw6IGZhbHNlLFxuICAgIGNvbW1hOiBmYWxzZSxcbiAgICBkZWNvZGVyOiB1dGlscy5kZWNvZGUsXG4gICAgZGVsaW1pdGVyOiAnJicsXG4gICAgZGVwdGg6IDUsXG4gICAgaWdub3JlUXVlcnlQcmVmaXg6IGZhbHNlLFxuICAgIGludGVycHJldE51bWVyaWNFbnRpdGllczogZmFsc2UsXG4gICAgcGFyYW1ldGVyTGltaXQ6IDEwMDAsXG4gICAgcGFyc2VBcnJheXM6IHRydWUsXG4gICAgcGxhaW5PYmplY3RzOiBmYWxzZSxcbiAgICBzdHJpY3ROdWxsSGFuZGxpbmc6IGZhbHNlXG59O1xuXG52YXIgaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzID0gZnVuY3Rpb24gKHN0cikge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvJiMoXFxkKyk7L2csIGZ1bmN0aW9uICgkMCwgbnVtYmVyU3RyKSB7XG4gICAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KG51bWJlclN0ciwgMTApKTtcbiAgICB9KTtcbn07XG5cbnZhciBwYXJzZUFycmF5VmFsdWUgPSBmdW5jdGlvbiAodmFsLCBvcHRpb25zKSB7XG4gICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsID09PSAnc3RyaW5nJyAmJiBvcHRpb25zLmNvbW1hICYmIHZhbC5pbmRleE9mKCcsJykgPiAtMSkge1xuICAgICAgICByZXR1cm4gdmFsLnNwbGl0KCcsJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbDtcbn07XG5cbnZhciBtYXliZU1hcCA9IGZ1bmN0aW9uIG1heWJlTWFwKHZhbCwgZm4pIHtcbiAgICBpZiAoaXNBcnJheSh2YWwpKSB7XG4gICAgICAgIHZhciBtYXBwZWQgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWwubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIG1hcHBlZC5wdXNoKGZuKHZhbFtpXSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXBwZWQ7XG4gICAgfVxuICAgIHJldHVybiBmbih2YWwpO1xufTtcblxuLy8gVGhpcyBpcyB3aGF0IGJyb3dzZXJzIHdpbGwgc3VibWl0IHdoZW4gdGhlIOKckyBjaGFyYWN0ZXIgb2NjdXJzIGluIGFuXG4vLyBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQgYm9keSBhbmQgdGhlIGVuY29kaW5nIG9mIHRoZSBwYWdlIGNvbnRhaW5pbmdcbi8vIHRoZSBmb3JtIGlzIGlzby04ODU5LTEsIG9yIHdoZW4gdGhlIHN1Ym1pdHRlZCBmb3JtIGhhcyBhbiBhY2NlcHQtY2hhcnNldFxuLy8gYXR0cmlidXRlIG9mIGlzby04ODU5LTEuIFByZXN1bWFibHkgYWxzbyB3aXRoIG90aGVyIGNoYXJzZXRzIHRoYXQgZG8gbm90IGNvbnRhaW5cbi8vIHRoZSDinJMgY2hhcmFjdGVyLCBzdWNoIGFzIHVzLWFzY2lpLlxudmFyIGlzb1NlbnRpbmVsID0gJ3V0Zjg9JTI2JTIzMTAwMDMlM0InOyAvLyBlbmNvZGVVUklDb21wb25lbnQoJyYjMTAwMDM7JylcblxuLy8gVGhlc2UgYXJlIHRoZSBwZXJjZW50LWVuY29kZWQgdXRmLTggb2N0ZXRzIHJlcHJlc2VudGluZyBhIGNoZWNrbWFyaywgaW5kaWNhdGluZyB0aGF0IHRoZSByZXF1ZXN0IGFjdHVhbGx5IGlzIHV0Zi04IGVuY29kZWQuXG52YXIgY2hhcnNldFNlbnRpbmVsID0gJ3V0Zjg9JUUyJTlDJTkzJzsgLy8gZW5jb2RlVVJJQ29tcG9uZW50KCfinJMnKVxuXG52YXIgcGFyc2VWYWx1ZXMgPSBmdW5jdGlvbiBwYXJzZVF1ZXJ5U3RyaW5nVmFsdWVzKHN0ciwgb3B0aW9ucykge1xuICAgIHZhciBvYmogPSB7fTtcbiAgICB2YXIgY2xlYW5TdHIgPSBvcHRpb25zLmlnbm9yZVF1ZXJ5UHJlZml4ID8gc3RyLnJlcGxhY2UoL15cXD8vLCAnJykgOiBzdHI7XG4gICAgdmFyIGxpbWl0ID0gb3B0aW9ucy5wYXJhbWV0ZXJMaW1pdCA9PT0gSW5maW5pdHkgPyB1bmRlZmluZWQgOiBvcHRpb25zLnBhcmFtZXRlckxpbWl0O1xuICAgIHZhciBwYXJ0cyA9IGNsZWFuU3RyLnNwbGl0KG9wdGlvbnMuZGVsaW1pdGVyLCBsaW1pdCk7XG4gICAgdmFyIHNraXBJbmRleCA9IC0xOyAvLyBLZWVwIHRyYWNrIG9mIHdoZXJlIHRoZSB1dGY4IHNlbnRpbmVsIHdhcyBmb3VuZFxuICAgIHZhciBpO1xuXG4gICAgdmFyIGNoYXJzZXQgPSBvcHRpb25zLmNoYXJzZXQ7XG4gICAgaWYgKG9wdGlvbnMuY2hhcnNldFNlbnRpbmVsKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKHBhcnRzW2ldLmluZGV4T2YoJ3V0Zjg9JykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBpZiAocGFydHNbaV0gPT09IGNoYXJzZXRTZW50aW5lbCkge1xuICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gJ3V0Zi04JztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnRzW2ldID09PSBpc29TZW50aW5lbCkge1xuICAgICAgICAgICAgICAgICAgICBjaGFyc2V0ID0gJ2lzby04ODU5LTEnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBza2lwSW5kZXggPSBpO1xuICAgICAgICAgICAgICAgIGkgPSBwYXJ0cy5sZW5ndGg7IC8vIFRoZSBlc2xpbnQgc2V0dGluZ3MgZG8gbm90IGFsbG93IGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmIChpID09PSBza2lwSW5kZXgpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwYXJ0ID0gcGFydHNbaV07XG5cbiAgICAgICAgdmFyIGJyYWNrZXRFcXVhbHNQb3MgPSBwYXJ0LmluZGV4T2YoJ109Jyk7XG4gICAgICAgIHZhciBwb3MgPSBicmFja2V0RXF1YWxzUG9zID09PSAtMSA/IHBhcnQuaW5kZXhPZignPScpIDogYnJhY2tldEVxdWFsc1BvcyArIDE7XG5cbiAgICAgICAgdmFyIGtleSwgdmFsO1xuICAgICAgICBpZiAocG9zID09PSAtMSkge1xuICAgICAgICAgICAga2V5ID0gb3B0aW9ucy5kZWNvZGVyKHBhcnQsIGRlZmF1bHRzLmRlY29kZXIsIGNoYXJzZXQsICdrZXknKTtcbiAgICAgICAgICAgIHZhbCA9IG9wdGlvbnMuc3RyaWN0TnVsbEhhbmRsaW5nID8gbnVsbCA6ICcnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAga2V5ID0gb3B0aW9ucy5kZWNvZGVyKHBhcnQuc2xpY2UoMCwgcG9zKSwgZGVmYXVsdHMuZGVjb2RlciwgY2hhcnNldCwgJ2tleScpO1xuICAgICAgICAgICAgdmFsID0gbWF5YmVNYXAoXG4gICAgICAgICAgICAgICAgcGFyc2VBcnJheVZhbHVlKHBhcnQuc2xpY2UocG9zICsgMSksIG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChlbmNvZGVkVmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmRlY29kZXIoZW5jb2RlZFZhbCwgZGVmYXVsdHMuZGVjb2RlciwgY2hhcnNldCwgJ3ZhbHVlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWwgJiYgb3B0aW9ucy5pbnRlcnByZXROdW1lcmljRW50aXRpZXMgJiYgY2hhcnNldCA9PT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgICAgICB2YWwgPSBpbnRlcnByZXROdW1lcmljRW50aXRpZXModmFsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0LmluZGV4T2YoJ1tdPScpID4gLTEpIHtcbiAgICAgICAgICAgIHZhbCA9IGlzQXJyYXkodmFsKSA/IFt2YWxdIDogdmFsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhcy5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAgICAgb2JqW2tleV0gPSB1dGlscy5jb21iaW5lKG9ialtrZXldLCB2YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2JqW2tleV0gPSB2YWw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufTtcblxudmFyIHBhcnNlT2JqZWN0ID0gZnVuY3Rpb24gKGNoYWluLCB2YWwsIG9wdGlvbnMsIHZhbHVlc1BhcnNlZCkge1xuICAgIHZhciBsZWFmID0gdmFsdWVzUGFyc2VkID8gdmFsIDogcGFyc2VBcnJheVZhbHVlKHZhbCwgb3B0aW9ucyk7XG5cbiAgICBmb3IgKHZhciBpID0gY2hhaW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIG9iajtcbiAgICAgICAgdmFyIHJvb3QgPSBjaGFpbltpXTtcblxuICAgICAgICBpZiAocm9vdCA9PT0gJ1tdJyAmJiBvcHRpb25zLnBhcnNlQXJyYXlzKSB7XG4gICAgICAgICAgICBvYmogPSBbXS5jb25jYXQobGVhZik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvYmogPSBvcHRpb25zLnBsYWluT2JqZWN0cyA/IE9iamVjdC5jcmVhdGUobnVsbCkgOiB7fTtcbiAgICAgICAgICAgIHZhciBjbGVhblJvb3QgPSByb290LmNoYXJBdCgwKSA9PT0gJ1snICYmIHJvb3QuY2hhckF0KHJvb3QubGVuZ3RoIC0gMSkgPT09ICddJyA/IHJvb3Quc2xpY2UoMSwgLTEpIDogcm9vdDtcbiAgICAgICAgICAgIHZhciBpbmRleCA9IHBhcnNlSW50KGNsZWFuUm9vdCwgMTApO1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLnBhcnNlQXJyYXlzICYmIGNsZWFuUm9vdCA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICBvYmogPSB7IDA6IGxlYWYgfTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgIWlzTmFOKGluZGV4KVxuICAgICAgICAgICAgICAgICYmIHJvb3QgIT09IGNsZWFuUm9vdFxuICAgICAgICAgICAgICAgICYmIFN0cmluZyhpbmRleCkgPT09IGNsZWFuUm9vdFxuICAgICAgICAgICAgICAgICYmIGluZGV4ID49IDBcbiAgICAgICAgICAgICAgICAmJiAob3B0aW9ucy5wYXJzZUFycmF5cyAmJiBpbmRleCA8PSBvcHRpb25zLmFycmF5TGltaXQpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBvYmogPSBbXTtcbiAgICAgICAgICAgICAgICBvYmpbaW5kZXhdID0gbGVhZjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb2JqW2NsZWFuUm9vdF0gPSBsZWFmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGVhZiA9IG9iajsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICAgIH1cblxuICAgIHJldHVybiBsZWFmO1xufTtcblxudmFyIHBhcnNlS2V5cyA9IGZ1bmN0aW9uIHBhcnNlUXVlcnlTdHJpbmdLZXlzKGdpdmVuS2V5LCB2YWwsIG9wdGlvbnMsIHZhbHVlc1BhcnNlZCkge1xuICAgIGlmICghZ2l2ZW5LZXkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRyYW5zZm9ybSBkb3Qgbm90YXRpb24gdG8gYnJhY2tldCBub3RhdGlvblxuICAgIHZhciBrZXkgPSBvcHRpb25zLmFsbG93RG90cyA/IGdpdmVuS2V5LnJlcGxhY2UoL1xcLihbXi5bXSspL2csICdbJDFdJykgOiBnaXZlbktleTtcblxuICAgIC8vIFRoZSByZWdleCBjaHVua3NcblxuICAgIHZhciBicmFja2V0cyA9IC8oXFxbW15bXFxdXSpdKS87XG4gICAgdmFyIGNoaWxkID0gLyhcXFtbXltcXF1dKl0pL2c7XG5cbiAgICAvLyBHZXQgdGhlIHBhcmVudFxuXG4gICAgdmFyIHNlZ21lbnQgPSBvcHRpb25zLmRlcHRoID4gMCAmJiBicmFja2V0cy5leGVjKGtleSk7XG4gICAgdmFyIHBhcmVudCA9IHNlZ21lbnQgPyBrZXkuc2xpY2UoMCwgc2VnbWVudC5pbmRleCkgOiBrZXk7XG5cbiAgICAvLyBTdGFzaCB0aGUgcGFyZW50IGlmIGl0IGV4aXN0c1xuXG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBpZiAocGFyZW50KSB7XG4gICAgICAgIC8vIElmIHdlIGFyZW4ndCB1c2luZyBwbGFpbiBvYmplY3RzLCBvcHRpb25hbGx5IHByZWZpeCBrZXlzIHRoYXQgd291bGQgb3ZlcndyaXRlIG9iamVjdCBwcm90b3R5cGUgcHJvcGVydGllc1xuICAgICAgICBpZiAoIW9wdGlvbnMucGxhaW5PYmplY3RzICYmIGhhcy5jYWxsKE9iamVjdC5wcm90b3R5cGUsIHBhcmVudCkpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBrZXlzLnB1c2gocGFyZW50KTtcbiAgICB9XG5cbiAgICAvLyBMb29wIHRocm91Z2ggY2hpbGRyZW4gYXBwZW5kaW5nIHRvIHRoZSBhcnJheSB1bnRpbCB3ZSBoaXQgZGVwdGhcblxuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAob3B0aW9ucy5kZXB0aCA+IDAgJiYgKHNlZ21lbnQgPSBjaGlsZC5leGVjKGtleSkpICE9PSBudWxsICYmIGkgPCBvcHRpb25zLmRlcHRoKSB7XG4gICAgICAgIGkgKz0gMTtcbiAgICAgICAgaWYgKCFvcHRpb25zLnBsYWluT2JqZWN0cyAmJiBoYXMuY2FsbChPYmplY3QucHJvdG90eXBlLCBzZWdtZW50WzFdLnNsaWNlKDEsIC0xKSkpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAga2V5cy5wdXNoKHNlZ21lbnRbMV0pO1xuICAgIH1cblxuICAgIC8vIElmIHRoZXJlJ3MgYSByZW1haW5kZXIsIGp1c3QgYWRkIHdoYXRldmVyIGlzIGxlZnRcblxuICAgIGlmIChzZWdtZW50KSB7XG4gICAgICAgIGtleXMucHVzaCgnWycgKyBrZXkuc2xpY2Uoc2VnbWVudC5pbmRleCkgKyAnXScpO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZU9iamVjdChrZXlzLCB2YWwsIG9wdGlvbnMsIHZhbHVlc1BhcnNlZCk7XG59O1xuXG52YXIgbm9ybWFsaXplUGFyc2VPcHRpb25zID0gZnVuY3Rpb24gbm9ybWFsaXplUGFyc2VPcHRpb25zKG9wdHMpIHtcbiAgICBpZiAoIW9wdHMpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRzO1xuICAgIH1cblxuICAgIGlmIChvcHRzLmRlY29kZXIgIT09IG51bGwgJiYgb3B0cy5kZWNvZGVyICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9wdHMuZGVjb2RlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdEZWNvZGVyIGhhcyB0byBiZSBhIGZ1bmN0aW9uLicpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5jaGFyc2V0ICE9PSAndW5kZWZpbmVkJyAmJiBvcHRzLmNoYXJzZXQgIT09ICd1dGYtOCcgJiYgb3B0cy5jaGFyc2V0ICE9PSAnaXNvLTg4NTktMScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGNoYXJzZXQgb3B0aW9uIG11c3QgYmUgZWl0aGVyIHV0Zi04LCBpc28tODg1OS0xLCBvciB1bmRlZmluZWQnKTtcbiAgICB9XG4gICAgdmFyIGNoYXJzZXQgPSB0eXBlb2Ygb3B0cy5jaGFyc2V0ID09PSAndW5kZWZpbmVkJyA/IGRlZmF1bHRzLmNoYXJzZXQgOiBvcHRzLmNoYXJzZXQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBhbGxvd0RvdHM6IHR5cGVvZiBvcHRzLmFsbG93RG90cyA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0cy5hbGxvd0RvdHMgOiAhIW9wdHMuYWxsb3dEb3RzLFxuICAgICAgICBhbGxvd1Byb3RvdHlwZXM6IHR5cGVvZiBvcHRzLmFsbG93UHJvdG90eXBlcyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5hbGxvd1Byb3RvdHlwZXMgOiBkZWZhdWx0cy5hbGxvd1Byb3RvdHlwZXMsXG4gICAgICAgIGFycmF5TGltaXQ6IHR5cGVvZiBvcHRzLmFycmF5TGltaXQgPT09ICdudW1iZXInID8gb3B0cy5hcnJheUxpbWl0IDogZGVmYXVsdHMuYXJyYXlMaW1pdCxcbiAgICAgICAgY2hhcnNldDogY2hhcnNldCxcbiAgICAgICAgY2hhcnNldFNlbnRpbmVsOiB0eXBlb2Ygb3B0cy5jaGFyc2V0U2VudGluZWwgPT09ICdib29sZWFuJyA/IG9wdHMuY2hhcnNldFNlbnRpbmVsIDogZGVmYXVsdHMuY2hhcnNldFNlbnRpbmVsLFxuICAgICAgICBjb21tYTogdHlwZW9mIG9wdHMuY29tbWEgPT09ICdib29sZWFuJyA/IG9wdHMuY29tbWEgOiBkZWZhdWx0cy5jb21tYSxcbiAgICAgICAgZGVjb2RlcjogdHlwZW9mIG9wdHMuZGVjb2RlciA9PT0gJ2Z1bmN0aW9uJyA/IG9wdHMuZGVjb2RlciA6IGRlZmF1bHRzLmRlY29kZXIsXG4gICAgICAgIGRlbGltaXRlcjogdHlwZW9mIG9wdHMuZGVsaW1pdGVyID09PSAnc3RyaW5nJyB8fCB1dGlscy5pc1JlZ0V4cChvcHRzLmRlbGltaXRlcikgPyBvcHRzLmRlbGltaXRlciA6IGRlZmF1bHRzLmRlbGltaXRlcixcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWltcGxpY2l0LWNvZXJjaW9uLCBuby1leHRyYS1wYXJlbnNcbiAgICAgICAgZGVwdGg6ICh0eXBlb2Ygb3B0cy5kZXB0aCA9PT0gJ251bWJlcicgfHwgb3B0cy5kZXB0aCA9PT0gZmFsc2UpID8gK29wdHMuZGVwdGggOiBkZWZhdWx0cy5kZXB0aCxcbiAgICAgICAgaWdub3JlUXVlcnlQcmVmaXg6IG9wdHMuaWdub3JlUXVlcnlQcmVmaXggPT09IHRydWUsXG4gICAgICAgIGludGVycHJldE51bWVyaWNFbnRpdGllczogdHlwZW9mIG9wdHMuaW50ZXJwcmV0TnVtZXJpY0VudGl0aWVzID09PSAnYm9vbGVhbicgPyBvcHRzLmludGVycHJldE51bWVyaWNFbnRpdGllcyA6IGRlZmF1bHRzLmludGVycHJldE51bWVyaWNFbnRpdGllcyxcbiAgICAgICAgcGFyYW1ldGVyTGltaXQ6IHR5cGVvZiBvcHRzLnBhcmFtZXRlckxpbWl0ID09PSAnbnVtYmVyJyA/IG9wdHMucGFyYW1ldGVyTGltaXQgOiBkZWZhdWx0cy5wYXJhbWV0ZXJMaW1pdCxcbiAgICAgICAgcGFyc2VBcnJheXM6IG9wdHMucGFyc2VBcnJheXMgIT09IGZhbHNlLFxuICAgICAgICBwbGFpbk9iamVjdHM6IHR5cGVvZiBvcHRzLnBsYWluT2JqZWN0cyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5wbGFpbk9iamVjdHMgOiBkZWZhdWx0cy5wbGFpbk9iamVjdHMsXG4gICAgICAgIHN0cmljdE51bGxIYW5kbGluZzogdHlwZW9mIG9wdHMuc3RyaWN0TnVsbEhhbmRsaW5nID09PSAnYm9vbGVhbicgPyBvcHRzLnN0cmljdE51bGxIYW5kbGluZyA6IGRlZmF1bHRzLnN0cmljdE51bGxIYW5kbGluZ1xuICAgIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzdHIsIG9wdHMpIHtcbiAgICB2YXIgb3B0aW9ucyA9IG5vcm1hbGl6ZVBhcnNlT3B0aW9ucyhvcHRzKTtcblxuICAgIGlmIChzdHIgPT09ICcnIHx8IHN0ciA9PT0gbnVsbCB8fCB0eXBlb2Ygc3RyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5wbGFpbk9iamVjdHMgPyBPYmplY3QuY3JlYXRlKG51bGwpIDoge307XG4gICAgfVxuXG4gICAgdmFyIHRlbXBPYmogPSB0eXBlb2Ygc3RyID09PSAnc3RyaW5nJyA/IHBhcnNlVmFsdWVzKHN0ciwgb3B0aW9ucykgOiBzdHI7XG4gICAgdmFyIG9iaiA9IG9wdGlvbnMucGxhaW5PYmplY3RzID8gT2JqZWN0LmNyZWF0ZShudWxsKSA6IHt9O1xuXG4gICAgLy8gSXRlcmF0ZSBvdmVyIHRoZSBrZXlzIGFuZCBzZXR1cCB0aGUgbmV3IG9iamVjdFxuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0ZW1wT2JqKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgIHZhciBuZXdPYmogPSBwYXJzZUtleXMoa2V5LCB0ZW1wT2JqW2tleV0sIG9wdGlvbnMsIHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnKTtcbiAgICAgICAgb2JqID0gdXRpbHMubWVyZ2Uob2JqLCBuZXdPYmosIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIHJldHVybiB1dGlscy5jb21wYWN0KG9iaik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgZm9ybWF0cyA9IHJlcXVpcmUoJy4vZm9ybWF0cycpO1xudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBhcnJheVByZWZpeEdlbmVyYXRvcnMgPSB7XG4gICAgYnJhY2tldHM6IGZ1bmN0aW9uIGJyYWNrZXRzKHByZWZpeCkge1xuICAgICAgICByZXR1cm4gcHJlZml4ICsgJ1tdJztcbiAgICB9LFxuICAgIGNvbW1hOiAnY29tbWEnLFxuICAgIGluZGljZXM6IGZ1bmN0aW9uIGluZGljZXMocHJlZml4LCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIHByZWZpeCArICdbJyArIGtleSArICddJztcbiAgICB9LFxuICAgIHJlcGVhdDogZnVuY3Rpb24gcmVwZWF0KHByZWZpeCkge1xuICAgICAgICByZXR1cm4gcHJlZml4O1xuICAgIH1cbn07XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcbnZhciBwdXNoID0gQXJyYXkucHJvdG90eXBlLnB1c2g7XG52YXIgcHVzaFRvQXJyYXkgPSBmdW5jdGlvbiAoYXJyLCB2YWx1ZU9yQXJyYXkpIHtcbiAgICBwdXNoLmFwcGx5KGFyciwgaXNBcnJheSh2YWx1ZU9yQXJyYXkpID8gdmFsdWVPckFycmF5IDogW3ZhbHVlT3JBcnJheV0pO1xufTtcblxudmFyIHRvSVNPID0gRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmc7XG5cbnZhciBkZWZhdWx0Rm9ybWF0ID0gZm9ybWF0c1snZGVmYXVsdCddO1xudmFyIGRlZmF1bHRzID0ge1xuICAgIGFkZFF1ZXJ5UHJlZml4OiBmYWxzZSxcbiAgICBhbGxvd0RvdHM6IGZhbHNlLFxuICAgIGNoYXJzZXQ6ICd1dGYtOCcsXG4gICAgY2hhcnNldFNlbnRpbmVsOiBmYWxzZSxcbiAgICBkZWxpbWl0ZXI6ICcmJyxcbiAgICBlbmNvZGU6IHRydWUsXG4gICAgZW5jb2RlcjogdXRpbHMuZW5jb2RlLFxuICAgIGVuY29kZVZhbHVlc09ubHk6IGZhbHNlLFxuICAgIGZvcm1hdDogZGVmYXVsdEZvcm1hdCxcbiAgICBmb3JtYXR0ZXI6IGZvcm1hdHMuZm9ybWF0dGVyc1tkZWZhdWx0Rm9ybWF0XSxcbiAgICAvLyBkZXByZWNhdGVkXG4gICAgaW5kaWNlczogZmFsc2UsXG4gICAgc2VyaWFsaXplRGF0ZTogZnVuY3Rpb24gc2VyaWFsaXplRGF0ZShkYXRlKSB7XG4gICAgICAgIHJldHVybiB0b0lTTy5jYWxsKGRhdGUpO1xuICAgIH0sXG4gICAgc2tpcE51bGxzOiBmYWxzZSxcbiAgICBzdHJpY3ROdWxsSGFuZGxpbmc6IGZhbHNlXG59O1xuXG52YXIgaXNOb25OdWxsaXNoUHJpbWl0aXZlID0gZnVuY3Rpb24gaXNOb25OdWxsaXNoUHJpbWl0aXZlKHYpIHtcbiAgICByZXR1cm4gdHlwZW9mIHYgPT09ICdzdHJpbmcnXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnbnVtYmVyJ1xuICAgICAgICB8fCB0eXBlb2YgdiA9PT0gJ2Jvb2xlYW4nXG4gICAgICAgIHx8IHR5cGVvZiB2ID09PSAnc3ltYm9sJ1xuICAgICAgICB8fCB0eXBlb2YgdiA9PT0gJ2JpZ2ludCc7XG59O1xuXG52YXIgc3RyaW5naWZ5ID0gZnVuY3Rpb24gc3RyaW5naWZ5KFxuICAgIG9iamVjdCxcbiAgICBwcmVmaXgsXG4gICAgZ2VuZXJhdGVBcnJheVByZWZpeCxcbiAgICBzdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgc2tpcE51bGxzLFxuICAgIGVuY29kZXIsXG4gICAgZmlsdGVyLFxuICAgIHNvcnQsXG4gICAgYWxsb3dEb3RzLFxuICAgIHNlcmlhbGl6ZURhdGUsXG4gICAgZm9ybWF0dGVyLFxuICAgIGVuY29kZVZhbHVlc09ubHksXG4gICAgY2hhcnNldFxuKSB7XG4gICAgdmFyIG9iaiA9IG9iamVjdDtcbiAgICBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBvYmogPSBmaWx0ZXIocHJlZml4LCBvYmopO1xuICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICBvYmogPSBzZXJpYWxpemVEYXRlKG9iaik7XG4gICAgfSBlbHNlIGlmIChnZW5lcmF0ZUFycmF5UHJlZml4ID09PSAnY29tbWEnICYmIGlzQXJyYXkob2JqKSkge1xuICAgICAgICBvYmogPSBvYmouam9pbignLCcpO1xuICAgIH1cblxuICAgIGlmIChvYmogPT09IG51bGwpIHtcbiAgICAgICAgaWYgKHN0cmljdE51bGxIYW5kbGluZykge1xuICAgICAgICAgICAgcmV0dXJuIGVuY29kZXIgJiYgIWVuY29kZVZhbHVlc09ubHkgPyBlbmNvZGVyKHByZWZpeCwgZGVmYXVsdHMuZW5jb2RlciwgY2hhcnNldCwgJ2tleScpIDogcHJlZml4O1xuICAgICAgICB9XG5cbiAgICAgICAgb2JqID0gJyc7XG4gICAgfVxuXG4gICAgaWYgKGlzTm9uTnVsbGlzaFByaW1pdGl2ZShvYmopIHx8IHV0aWxzLmlzQnVmZmVyKG9iaikpIHtcbiAgICAgICAgaWYgKGVuY29kZXIpIHtcbiAgICAgICAgICAgIHZhciBrZXlWYWx1ZSA9IGVuY29kZVZhbHVlc09ubHkgPyBwcmVmaXggOiBlbmNvZGVyKHByZWZpeCwgZGVmYXVsdHMuZW5jb2RlciwgY2hhcnNldCwgJ2tleScpO1xuICAgICAgICAgICAgcmV0dXJuIFtmb3JtYXR0ZXIoa2V5VmFsdWUpICsgJz0nICsgZm9ybWF0dGVyKGVuY29kZXIob2JqLCBkZWZhdWx0cy5lbmNvZGVyLCBjaGFyc2V0LCAndmFsdWUnKSldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbZm9ybWF0dGVyKHByZWZpeCkgKyAnPScgKyBmb3JtYXR0ZXIoU3RyaW5nKG9iaikpXTtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWVzID0gW107XG5cbiAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9XG5cbiAgICB2YXIgb2JqS2V5cztcbiAgICBpZiAoaXNBcnJheShmaWx0ZXIpKSB7XG4gICAgICAgIG9iaktleXMgPSBmaWx0ZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgICAgICBvYmpLZXlzID0gc29ydCA/IGtleXMuc29ydChzb3J0KSA6IGtleXM7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmpLZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBvYmpLZXlzW2ldO1xuXG4gICAgICAgIGlmIChza2lwTnVsbHMgJiYgb2JqW2tleV0gPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgcHVzaFRvQXJyYXkodmFsdWVzLCBzdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAgb2JqW2tleV0sXG4gICAgICAgICAgICAgICAgdHlwZW9mIGdlbmVyYXRlQXJyYXlQcmVmaXggPT09ICdmdW5jdGlvbicgPyBnZW5lcmF0ZUFycmF5UHJlZml4KHByZWZpeCwga2V5KSA6IHByZWZpeCxcbiAgICAgICAgICAgICAgICBnZW5lcmF0ZUFycmF5UHJlZml4LFxuICAgICAgICAgICAgICAgIHN0cmljdE51bGxIYW5kbGluZyxcbiAgICAgICAgICAgICAgICBza2lwTnVsbHMsXG4gICAgICAgICAgICAgICAgZW5jb2RlcixcbiAgICAgICAgICAgICAgICBmaWx0ZXIsXG4gICAgICAgICAgICAgICAgc29ydCxcbiAgICAgICAgICAgICAgICBhbGxvd0RvdHMsXG4gICAgICAgICAgICAgICAgc2VyaWFsaXplRGF0ZSxcbiAgICAgICAgICAgICAgICBmb3JtYXR0ZXIsXG4gICAgICAgICAgICAgICAgZW5jb2RlVmFsdWVzT25seSxcbiAgICAgICAgICAgICAgICBjaGFyc2V0XG4gICAgICAgICAgICApKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHB1c2hUb0FycmF5KHZhbHVlcywgc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgIG9ialtrZXldLFxuICAgICAgICAgICAgICAgIHByZWZpeCArIChhbGxvd0RvdHMgPyAnLicgKyBrZXkgOiAnWycgKyBrZXkgKyAnXScpLFxuICAgICAgICAgICAgICAgIGdlbmVyYXRlQXJyYXlQcmVmaXgsXG4gICAgICAgICAgICAgICAgc3RyaWN0TnVsbEhhbmRsaW5nLFxuICAgICAgICAgICAgICAgIHNraXBOdWxscyxcbiAgICAgICAgICAgICAgICBlbmNvZGVyLFxuICAgICAgICAgICAgICAgIGZpbHRlcixcbiAgICAgICAgICAgICAgICBzb3J0LFxuICAgICAgICAgICAgICAgIGFsbG93RG90cyxcbiAgICAgICAgICAgICAgICBzZXJpYWxpemVEYXRlLFxuICAgICAgICAgICAgICAgIGZvcm1hdHRlcixcbiAgICAgICAgICAgICAgICBlbmNvZGVWYWx1ZXNPbmx5LFxuICAgICAgICAgICAgICAgIGNoYXJzZXRcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbn07XG5cbnZhciBub3JtYWxpemVTdHJpbmdpZnlPcHRpb25zID0gZnVuY3Rpb24gbm9ybWFsaXplU3RyaW5naWZ5T3B0aW9ucyhvcHRzKSB7XG4gICAgaWYgKCFvcHRzKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0cztcbiAgICB9XG5cbiAgICBpZiAob3B0cy5lbmNvZGVyICE9PSBudWxsICYmIG9wdHMuZW5jb2RlciAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRzLmVuY29kZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRW5jb2RlciBoYXMgdG8gYmUgYSBmdW5jdGlvbi4nKTtcbiAgICB9XG5cbiAgICB2YXIgY2hhcnNldCA9IG9wdHMuY2hhcnNldCB8fCBkZWZhdWx0cy5jaGFyc2V0O1xuICAgIGlmICh0eXBlb2Ygb3B0cy5jaGFyc2V0ICE9PSAndW5kZWZpbmVkJyAmJiBvcHRzLmNoYXJzZXQgIT09ICd1dGYtOCcgJiYgb3B0cy5jaGFyc2V0ICE9PSAnaXNvLTg4NTktMScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGNoYXJzZXQgb3B0aW9uIG11c3QgYmUgZWl0aGVyIHV0Zi04LCBpc28tODg1OS0xLCBvciB1bmRlZmluZWQnKTtcbiAgICB9XG5cbiAgICB2YXIgZm9ybWF0ID0gZm9ybWF0c1snZGVmYXVsdCddO1xuICAgIGlmICh0eXBlb2Ygb3B0cy5mb3JtYXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmICghaGFzLmNhbGwoZm9ybWF0cy5mb3JtYXR0ZXJzLCBvcHRzLmZvcm1hdCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZm9ybWF0IG9wdGlvbiBwcm92aWRlZC4nKTtcbiAgICAgICAgfVxuICAgICAgICBmb3JtYXQgPSBvcHRzLmZvcm1hdDtcbiAgICB9XG4gICAgdmFyIGZvcm1hdHRlciA9IGZvcm1hdHMuZm9ybWF0dGVyc1tmb3JtYXRdO1xuXG4gICAgdmFyIGZpbHRlciA9IGRlZmF1bHRzLmZpbHRlcjtcbiAgICBpZiAodHlwZW9mIG9wdHMuZmlsdGVyID09PSAnZnVuY3Rpb24nIHx8IGlzQXJyYXkob3B0cy5maWx0ZXIpKSB7XG4gICAgICAgIGZpbHRlciA9IG9wdHMuZmlsdGVyO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGFkZFF1ZXJ5UHJlZml4OiB0eXBlb2Ygb3B0cy5hZGRRdWVyeVByZWZpeCA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5hZGRRdWVyeVByZWZpeCA6IGRlZmF1bHRzLmFkZFF1ZXJ5UHJlZml4LFxuICAgICAgICBhbGxvd0RvdHM6IHR5cGVvZiBvcHRzLmFsbG93RG90cyA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0cy5hbGxvd0RvdHMgOiAhIW9wdHMuYWxsb3dEb3RzLFxuICAgICAgICBjaGFyc2V0OiBjaGFyc2V0LFxuICAgICAgICBjaGFyc2V0U2VudGluZWw6IHR5cGVvZiBvcHRzLmNoYXJzZXRTZW50aW5lbCA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5jaGFyc2V0U2VudGluZWwgOiBkZWZhdWx0cy5jaGFyc2V0U2VudGluZWwsXG4gICAgICAgIGRlbGltaXRlcjogdHlwZW9mIG9wdHMuZGVsaW1pdGVyID09PSAndW5kZWZpbmVkJyA/IGRlZmF1bHRzLmRlbGltaXRlciA6IG9wdHMuZGVsaW1pdGVyLFxuICAgICAgICBlbmNvZGU6IHR5cGVvZiBvcHRzLmVuY29kZSA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5lbmNvZGUgOiBkZWZhdWx0cy5lbmNvZGUsXG4gICAgICAgIGVuY29kZXI6IHR5cGVvZiBvcHRzLmVuY29kZXIgPT09ICdmdW5jdGlvbicgPyBvcHRzLmVuY29kZXIgOiBkZWZhdWx0cy5lbmNvZGVyLFxuICAgICAgICBlbmNvZGVWYWx1ZXNPbmx5OiB0eXBlb2Ygb3B0cy5lbmNvZGVWYWx1ZXNPbmx5ID09PSAnYm9vbGVhbicgPyBvcHRzLmVuY29kZVZhbHVlc09ubHkgOiBkZWZhdWx0cy5lbmNvZGVWYWx1ZXNPbmx5LFxuICAgICAgICBmaWx0ZXI6IGZpbHRlcixcbiAgICAgICAgZm9ybWF0dGVyOiBmb3JtYXR0ZXIsXG4gICAgICAgIHNlcmlhbGl6ZURhdGU6IHR5cGVvZiBvcHRzLnNlcmlhbGl6ZURhdGUgPT09ICdmdW5jdGlvbicgPyBvcHRzLnNlcmlhbGl6ZURhdGUgOiBkZWZhdWx0cy5zZXJpYWxpemVEYXRlLFxuICAgICAgICBza2lwTnVsbHM6IHR5cGVvZiBvcHRzLnNraXBOdWxscyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5za2lwTnVsbHMgOiBkZWZhdWx0cy5za2lwTnVsbHMsXG4gICAgICAgIHNvcnQ6IHR5cGVvZiBvcHRzLnNvcnQgPT09ICdmdW5jdGlvbicgPyBvcHRzLnNvcnQgOiBudWxsLFxuICAgICAgICBzdHJpY3ROdWxsSGFuZGxpbmc6IHR5cGVvZiBvcHRzLnN0cmljdE51bGxIYW5kbGluZyA9PT0gJ2Jvb2xlYW4nID8gb3B0cy5zdHJpY3ROdWxsSGFuZGxpbmcgOiBkZWZhdWx0cy5zdHJpY3ROdWxsSGFuZGxpbmdcbiAgICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqZWN0LCBvcHRzKSB7XG4gICAgdmFyIG9iaiA9IG9iamVjdDtcbiAgICB2YXIgb3B0aW9ucyA9IG5vcm1hbGl6ZVN0cmluZ2lmeU9wdGlvbnMob3B0cyk7XG5cbiAgICB2YXIgb2JqS2V5cztcbiAgICB2YXIgZmlsdGVyO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmaWx0ZXIgPSBvcHRpb25zLmZpbHRlcjtcbiAgICAgICAgb2JqID0gZmlsdGVyKCcnLCBvYmopO1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvcHRpb25zLmZpbHRlcikpIHtcbiAgICAgICAgZmlsdGVyID0gb3B0aW9ucy5maWx0ZXI7XG4gICAgICAgIG9iaktleXMgPSBmaWx0ZXI7XG4gICAgfVxuXG4gICAgdmFyIGtleXMgPSBbXTtcblxuICAgIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JyB8fCBvYmogPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHZhciBhcnJheUZvcm1hdDtcbiAgICBpZiAob3B0cyAmJiBvcHRzLmFycmF5Rm9ybWF0IGluIGFycmF5UHJlZml4R2VuZXJhdG9ycykge1xuICAgICAgICBhcnJheUZvcm1hdCA9IG9wdHMuYXJyYXlGb3JtYXQ7XG4gICAgfSBlbHNlIGlmIChvcHRzICYmICdpbmRpY2VzJyBpbiBvcHRzKSB7XG4gICAgICAgIGFycmF5Rm9ybWF0ID0gb3B0cy5pbmRpY2VzID8gJ2luZGljZXMnIDogJ3JlcGVhdCc7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYXJyYXlGb3JtYXQgPSAnaW5kaWNlcyc7XG4gICAgfVxuXG4gICAgdmFyIGdlbmVyYXRlQXJyYXlQcmVmaXggPSBhcnJheVByZWZpeEdlbmVyYXRvcnNbYXJyYXlGb3JtYXRdO1xuXG4gICAgaWYgKCFvYmpLZXlzKSB7XG4gICAgICAgIG9iaktleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnNvcnQpIHtcbiAgICAgICAgb2JqS2V5cy5zb3J0KG9wdGlvbnMuc29ydCk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmpLZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBrZXkgPSBvYmpLZXlzW2ldO1xuXG4gICAgICAgIGlmIChvcHRpb25zLnNraXBOdWxscyAmJiBvYmpba2V5XSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcHVzaFRvQXJyYXkoa2V5cywgc3RyaW5naWZ5KFxuICAgICAgICAgICAgb2JqW2tleV0sXG4gICAgICAgICAgICBrZXksXG4gICAgICAgICAgICBnZW5lcmF0ZUFycmF5UHJlZml4LFxuICAgICAgICAgICAgb3B0aW9ucy5zdHJpY3ROdWxsSGFuZGxpbmcsXG4gICAgICAgICAgICBvcHRpb25zLnNraXBOdWxscyxcbiAgICAgICAgICAgIG9wdGlvbnMuZW5jb2RlID8gb3B0aW9ucy5lbmNvZGVyIDogbnVsbCxcbiAgICAgICAgICAgIG9wdGlvbnMuZmlsdGVyLFxuICAgICAgICAgICAgb3B0aW9ucy5zb3J0LFxuICAgICAgICAgICAgb3B0aW9ucy5hbGxvd0RvdHMsXG4gICAgICAgICAgICBvcHRpb25zLnNlcmlhbGl6ZURhdGUsXG4gICAgICAgICAgICBvcHRpb25zLmZvcm1hdHRlcixcbiAgICAgICAgICAgIG9wdGlvbnMuZW5jb2RlVmFsdWVzT25seSxcbiAgICAgICAgICAgIG9wdGlvbnMuY2hhcnNldFxuICAgICAgICApKTtcbiAgICB9XG5cbiAgICB2YXIgam9pbmVkID0ga2V5cy5qb2luKG9wdGlvbnMuZGVsaW1pdGVyKTtcbiAgICB2YXIgcHJlZml4ID0gb3B0aW9ucy5hZGRRdWVyeVByZWZpeCA9PT0gdHJ1ZSA/ICc/JyA6ICcnO1xuXG4gICAgaWYgKG9wdGlvbnMuY2hhcnNldFNlbnRpbmVsKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICAgICAgLy8gZW5jb2RlVVJJQ29tcG9uZW50KCcmIzEwMDAzOycpLCB0aGUgXCJudW1lcmljIGVudGl0eVwiIHJlcHJlc2VudGF0aW9uIG9mIGEgY2hlY2ttYXJrXG4gICAgICAgICAgICBwcmVmaXggKz0gJ3V0Zjg9JTI2JTIzMTAwMDMlM0ImJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGVuY29kZVVSSUNvbXBvbmVudCgn4pyTJylcbiAgICAgICAgICAgIHByZWZpeCArPSAndXRmOD0lRTIlOUMlOTMmJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBqb2luZWQubGVuZ3RoID4gMCA/IHByZWZpeCArIGpvaW5lZCA6ICcnO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbnZhciBoZXhUYWJsZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFycmF5ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICAgICAgICBhcnJheS5wdXNoKCclJyArICgoaSA8IDE2ID8gJzAnIDogJycpICsgaS50b1N0cmluZygxNikpLnRvVXBwZXJDYXNlKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnJheTtcbn0oKSk7XG5cbnZhciBjb21wYWN0UXVldWUgPSBmdW5jdGlvbiBjb21wYWN0UXVldWUocXVldWUpIHtcbiAgICB3aGlsZSAocXVldWUubGVuZ3RoID4gMSkge1xuICAgICAgICB2YXIgaXRlbSA9IHF1ZXVlLnBvcCgpO1xuICAgICAgICB2YXIgb2JqID0gaXRlbS5vYmpbaXRlbS5wcm9wXTtcblxuICAgICAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICB2YXIgY29tcGFjdGVkID0gW107XG5cbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgb2JqLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmpbal0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBhY3RlZC5wdXNoKG9ialtqXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpdGVtLm9ialtpdGVtLnByb3BdID0gY29tcGFjdGVkO1xuICAgICAgICB9XG4gICAgfVxufTtcblxudmFyIGFycmF5VG9PYmplY3QgPSBmdW5jdGlvbiBhcnJheVRvT2JqZWN0KHNvdXJjZSwgb3B0aW9ucykge1xuICAgIHZhciBvYmogPSBvcHRpb25zICYmIG9wdGlvbnMucGxhaW5PYmplY3RzID8gT2JqZWN0LmNyZWF0ZShudWxsKSA6IHt9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc291cmNlW2ldICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgb2JqW2ldID0gc291cmNlW2ldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iajtcbn07XG5cbnZhciBtZXJnZSA9IGZ1bmN0aW9uIG1lcmdlKHRhcmdldCwgc291cmNlLCBvcHRpb25zKSB7XG4gICAgLyogZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOiAwICovXG4gICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgaWYgKGlzQXJyYXkodGFyZ2V0KSkge1xuICAgICAgICAgICAgdGFyZ2V0LnB1c2goc291cmNlKTtcbiAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgJiYgdHlwZW9mIHRhcmdldCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICgob3B0aW9ucyAmJiAob3B0aW9ucy5wbGFpbk9iamVjdHMgfHwgb3B0aW9ucy5hbGxvd1Byb3RvdHlwZXMpKSB8fCAhaGFzLmNhbGwoT2JqZWN0LnByb3RvdHlwZSwgc291cmNlKSkge1xuICAgICAgICAgICAgICAgIHRhcmdldFtzb3VyY2VdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBbdGFyZ2V0LCBzb3VyY2VdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAoIXRhcmdldCB8fCB0eXBlb2YgdGFyZ2V0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gW3RhcmdldF0uY29uY2F0KHNvdXJjZSk7XG4gICAgfVxuXG4gICAgdmFyIG1lcmdlVGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGlmIChpc0FycmF5KHRhcmdldCkgJiYgIWlzQXJyYXkoc291cmNlKSkge1xuICAgICAgICBtZXJnZVRhcmdldCA9IGFycmF5VG9PYmplY3QodGFyZ2V0LCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheSh0YXJnZXQpICYmIGlzQXJyYXkoc291cmNlKSkge1xuICAgICAgICBzb3VyY2UuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSwgaSkge1xuICAgICAgICAgICAgaWYgKGhhcy5jYWxsKHRhcmdldCwgaSkpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0SXRlbSA9IHRhcmdldFtpXTtcbiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0SXRlbSAmJiB0eXBlb2YgdGFyZ2V0SXRlbSA9PT0gJ29iamVjdCcgJiYgaXRlbSAmJiB0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W2ldID0gbWVyZ2UodGFyZ2V0SXRlbSwgaXRlbSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnB1c2goaXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRbaV0gPSBpdGVtO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoc291cmNlKS5yZWR1Y2UoZnVuY3Rpb24gKGFjYywga2V5KSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHNvdXJjZVtrZXldO1xuXG4gICAgICAgIGlmIChoYXMuY2FsbChhY2MsIGtleSkpIHtcbiAgICAgICAgICAgIGFjY1trZXldID0gbWVyZ2UoYWNjW2tleV0sIHZhbHVlLCBvcHRpb25zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFjY1trZXldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBtZXJnZVRhcmdldCk7XG59O1xuXG52YXIgYXNzaWduID0gZnVuY3Rpb24gYXNzaWduU2luZ2xlU291cmNlKHRhcmdldCwgc291cmNlKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHNvdXJjZSkucmVkdWNlKGZ1bmN0aW9uIChhY2MsIGtleSkge1xuICAgICAgICBhY2Nba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHRhcmdldCk7XG59O1xuXG52YXIgZGVjb2RlID0gZnVuY3Rpb24gKHN0ciwgZGVjb2RlciwgY2hhcnNldCkge1xuICAgIHZhciBzdHJXaXRob3V0UGx1cyA9IHN0ci5yZXBsYWNlKC9cXCsvZywgJyAnKTtcbiAgICBpZiAoY2hhcnNldCA9PT0gJ2lzby04ODU5LTEnKSB7XG4gICAgICAgIC8vIHVuZXNjYXBlIG5ldmVyIHRocm93cywgbm8gdHJ5Li4uY2F0Y2ggbmVlZGVkOlxuICAgICAgICByZXR1cm4gc3RyV2l0aG91dFBsdXMucmVwbGFjZSgvJVswLTlhLWZdezJ9L2dpLCB1bmVzY2FwZSk7XG4gICAgfVxuICAgIC8vIHV0Zi04XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHJXaXRob3V0UGx1cyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gc3RyV2l0aG91dFBsdXM7XG4gICAgfVxufTtcblxudmFyIGVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShzdHIsIGRlZmF1bHRFbmNvZGVyLCBjaGFyc2V0KSB7XG4gICAgLy8gVGhpcyBjb2RlIHdhcyBvcmlnaW5hbGx5IHdyaXR0ZW4gYnkgQnJpYW4gV2hpdGUgKG1zY2RleCkgZm9yIHRoZSBpby5qcyBjb3JlIHF1ZXJ5c3RyaW5nIGxpYnJhcnkuXG4gICAgLy8gSXQgaGFzIGJlZW4gYWRhcHRlZCBoZXJlIGZvciBzdHJpY3RlciBhZGhlcmVuY2UgdG8gUkZDIDM5ODZcbiAgICBpZiAoc3RyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gc3RyO1xuICAgIH1cblxuICAgIHZhciBzdHJpbmcgPSBzdHI7XG4gICAgaWYgKHR5cGVvZiBzdHIgPT09ICdzeW1ib2wnKSB7XG4gICAgICAgIHN0cmluZyA9IFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChzdHIpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgc3RyaW5nID0gU3RyaW5nKHN0cik7XG4gICAgfVxuXG4gICAgaWYgKGNoYXJzZXQgPT09ICdpc28tODg1OS0xJykge1xuICAgICAgICByZXR1cm4gZXNjYXBlKHN0cmluZykucmVwbGFjZSgvJXVbMC05YS1mXXs0fS9naSwgZnVuY3Rpb24gKCQwKSB7XG4gICAgICAgICAgICByZXR1cm4gJyUyNiUyMycgKyBwYXJzZUludCgkMC5zbGljZSgyKSwgMTYpICsgJyUzQic7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBvdXQgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgYyA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIGMgPT09IDB4MkQgLy8gLVxuICAgICAgICAgICAgfHwgYyA9PT0gMHgyRSAvLyAuXG4gICAgICAgICAgICB8fCBjID09PSAweDVGIC8vIF9cbiAgICAgICAgICAgIHx8IGMgPT09IDB4N0UgLy8gflxuICAgICAgICAgICAgfHwgKGMgPj0gMHgzMCAmJiBjIDw9IDB4MzkpIC8vIDAtOVxuICAgICAgICAgICAgfHwgKGMgPj0gMHg0MSAmJiBjIDw9IDB4NUEpIC8vIGEtelxuICAgICAgICAgICAgfHwgKGMgPj0gMHg2MSAmJiBjIDw9IDB4N0EpIC8vIEEtWlxuICAgICAgICApIHtcbiAgICAgICAgICAgIG91dCArPSBzdHJpbmcuY2hhckF0KGkpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYyA8IDB4ODApIHtcbiAgICAgICAgICAgIG91dCA9IG91dCArIGhleFRhYmxlW2NdO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYyA8IDB4ODAwKSB7XG4gICAgICAgICAgICBvdXQgPSBvdXQgKyAoaGV4VGFibGVbMHhDMCB8IChjID4+IDYpXSArIGhleFRhYmxlWzB4ODAgfCAoYyAmIDB4M0YpXSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjIDwgMHhEODAwIHx8IGMgPj0gMHhFMDAwKSB7XG4gICAgICAgICAgICBvdXQgPSBvdXQgKyAoaGV4VGFibGVbMHhFMCB8IChjID4+IDEyKV0gKyBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzRildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaSArPSAxO1xuICAgICAgICBjID0gMHgxMDAwMCArICgoKGMgJiAweDNGRikgPDwgMTApIHwgKHN0cmluZy5jaGFyQ29kZUF0KGkpICYgMHgzRkYpKTtcbiAgICAgICAgb3V0ICs9IGhleFRhYmxlWzB4RjAgfCAoYyA+PiAxOCldXG4gICAgICAgICAgICArIGhleFRhYmxlWzB4ODAgfCAoKGMgPj4gMTIpICYgMHgzRildXG4gICAgICAgICAgICArIGhleFRhYmxlWzB4ODAgfCAoKGMgPj4gNikgJiAweDNGKV1cbiAgICAgICAgICAgICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzRildO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQ7XG59O1xuXG52YXIgY29tcGFjdCA9IGZ1bmN0aW9uIGNvbXBhY3QodmFsdWUpIHtcbiAgICB2YXIgcXVldWUgPSBbeyBvYmo6IHsgbzogdmFsdWUgfSwgcHJvcDogJ28nIH1dO1xuICAgIHZhciByZWZzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHF1ZXVlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBpdGVtID0gcXVldWVbaV07XG4gICAgICAgIHZhciBvYmogPSBpdGVtLm9ialtpdGVtLnByb3BdO1xuXG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBrZXlzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tqXTtcbiAgICAgICAgICAgIHZhciB2YWwgPSBvYmpba2V5XTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiB2YWwgIT09IG51bGwgJiYgcmVmcy5pbmRleE9mKHZhbCkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcXVldWUucHVzaCh7IG9iajogb2JqLCBwcm9wOiBrZXkgfSk7XG4gICAgICAgICAgICAgICAgcmVmcy5wdXNoKHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb21wYWN0UXVldWUocXVldWUpO1xuXG4gICAgcmV0dXJuIHZhbHVlO1xufTtcblxudmFyIGlzUmVnRXhwID0gZnVuY3Rpb24gaXNSZWdFeHAob2JqKSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBSZWdFeHBdJztcbn07XG5cbnZhciBpc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyKG9iaikge1xuICAgIGlmICghb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gISEob2JqLmNvbnN0cnVjdG9yICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciAmJiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIob2JqKSk7XG59O1xuXG52YXIgY29tYmluZSA9IGZ1bmN0aW9uIGNvbWJpbmUoYSwgYikge1xuICAgIHJldHVybiBbXS5jb25jYXQoYSwgYik7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBhcnJheVRvT2JqZWN0OiBhcnJheVRvT2JqZWN0LFxuICAgIGFzc2lnbjogYXNzaWduLFxuICAgIGNvbWJpbmU6IGNvbWJpbmUsXG4gICAgY29tcGFjdDogY29tcGFjdCxcbiAgICBkZWNvZGU6IGRlY29kZSxcbiAgICBlbmNvZGU6IGVuY29kZSxcbiAgICBpc0J1ZmZlcjogaXNCdWZmZXIsXG4gICAgaXNSZWdFeHA6IGlzUmVnRXhwLFxuICAgIG1lcmdlOiBtZXJnZVxufTtcbiIsIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuQ29weXJpZ2h0IChDKSBNaWNyb3NvZnQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2VcbnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXG5MaWNlbnNlIGF0IGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5USElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG5LSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIEFOWSBJTVBMSUVEXG5XQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLFxuTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC5cblxuU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXG5hbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xudmFyIFJlZmxlY3Q7XG4oZnVuY3Rpb24gKFJlZmxlY3QpIHtcbiAgICAvLyBNZXRhZGF0YSBQcm9wb3NhbFxuICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvXG4gICAgKGZ1bmN0aW9uIChmYWN0b3J5KSB7XG4gICAgICAgIHZhciByb290ID0gdHlwZW9mIGdsb2JhbCA9PT0gXCJvYmplY3RcIiA/IGdsb2JhbCA6XG4gICAgICAgICAgICB0eXBlb2Ygc2VsZiA9PT0gXCJvYmplY3RcIiA/IHNlbGYgOlxuICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzID09PSBcIm9iamVjdFwiID8gdGhpcyA6XG4gICAgICAgICAgICAgICAgICAgIEZ1bmN0aW9uKFwicmV0dXJuIHRoaXM7XCIpKCk7XG4gICAgICAgIHZhciBleHBvcnRlciA9IG1ha2VFeHBvcnRlcihSZWZsZWN0KTtcbiAgICAgICAgaWYgKHR5cGVvZiByb290LlJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHJvb3QuUmVmbGVjdCA9IFJlZmxlY3Q7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBleHBvcnRlciA9IG1ha2VFeHBvcnRlcihyb290LlJlZmxlY3QsIGV4cG9ydGVyKTtcbiAgICAgICAgfVxuICAgICAgICBmYWN0b3J5KGV4cG9ydGVyKTtcbiAgICAgICAgZnVuY3Rpb24gbWFrZUV4cG9ydGVyKHRhcmdldCwgcHJldmlvdXMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0W2tleV0gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHsgY29uZmlndXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocHJldmlvdXMpXG4gICAgICAgICAgICAgICAgICAgIHByZXZpb3VzKGtleSwgdmFsdWUpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH0pKGZ1bmN0aW9uIChleHBvcnRlcikge1xuICAgICAgICB2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbiAgICAgICAgLy8gZmVhdHVyZSB0ZXN0IGZvciBTeW1ib2wgc3VwcG9ydFxuICAgICAgICB2YXIgc3VwcG9ydHNTeW1ib2wgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCI7XG4gICAgICAgIHZhciB0b1ByaW1pdGl2ZVN5bWJvbCA9IHN1cHBvcnRzU3ltYm9sICYmIHR5cGVvZiBTeW1ib2wudG9QcmltaXRpdmUgIT09IFwidW5kZWZpbmVkXCIgPyBTeW1ib2wudG9QcmltaXRpdmUgOiBcIkBAdG9QcmltaXRpdmVcIjtcbiAgICAgICAgdmFyIGl0ZXJhdG9yU3ltYm9sID0gc3VwcG9ydHNTeW1ib2wgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciAhPT0gXCJ1bmRlZmluZWRcIiA/IFN5bWJvbC5pdGVyYXRvciA6IFwiQEBpdGVyYXRvclwiO1xuICAgICAgICB2YXIgc3VwcG9ydHNDcmVhdGUgPSB0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gXCJmdW5jdGlvblwiOyAvLyBmZWF0dXJlIHRlc3QgZm9yIE9iamVjdC5jcmVhdGUgc3VwcG9ydFxuICAgICAgICB2YXIgc3VwcG9ydHNQcm90byA9IHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXk7IC8vIGZlYXR1cmUgdGVzdCBmb3IgX19wcm90b19fIHN1cHBvcnRcbiAgICAgICAgdmFyIGRvd25MZXZlbCA9ICFzdXBwb3J0c0NyZWF0ZSAmJiAhc3VwcG9ydHNQcm90bztcbiAgICAgICAgdmFyIEhhc2hNYXAgPSB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgYW4gb2JqZWN0IGluIGRpY3Rpb25hcnkgbW9kZSAoYS5rLmEuIFwic2xvd1wiIG1vZGUgaW4gdjgpXG4gICAgICAgICAgICBjcmVhdGU6IHN1cHBvcnRzQ3JlYXRlXG4gICAgICAgICAgICAgICAgPyBmdW5jdGlvbiAoKSB7IHJldHVybiBNYWtlRGljdGlvbmFyeShPYmplY3QuY3JlYXRlKG51bGwpKTsgfVxuICAgICAgICAgICAgICAgIDogc3VwcG9ydHNQcm90b1xuICAgICAgICAgICAgICAgICAgICA/IGZ1bmN0aW9uICgpIHsgcmV0dXJuIE1ha2VEaWN0aW9uYXJ5KHsgX19wcm90b19fOiBudWxsIH0pOyB9XG4gICAgICAgICAgICAgICAgICAgIDogZnVuY3Rpb24gKCkgeyByZXR1cm4gTWFrZURpY3Rpb25hcnkoe30pOyB9LFxuICAgICAgICAgICAgaGFzOiBkb3duTGV2ZWxcbiAgICAgICAgICAgICAgICA/IGZ1bmN0aW9uIChtYXAsIGtleSkgeyByZXR1cm4gaGFzT3duLmNhbGwobWFwLCBrZXkpOyB9XG4gICAgICAgICAgICAgICAgOiBmdW5jdGlvbiAobWFwLCBrZXkpIHsgcmV0dXJuIGtleSBpbiBtYXA7IH0sXG4gICAgICAgICAgICBnZXQ6IGRvd25MZXZlbFxuICAgICAgICAgICAgICAgID8gZnVuY3Rpb24gKG1hcCwga2V5KSB7IHJldHVybiBoYXNPd24uY2FsbChtYXAsIGtleSkgPyBtYXBba2V5XSA6IHVuZGVmaW5lZDsgfVxuICAgICAgICAgICAgICAgIDogZnVuY3Rpb24gKG1hcCwga2V5KSB7IHJldHVybiBtYXBba2V5XTsgfSxcbiAgICAgICAgfTtcbiAgICAgICAgLy8gTG9hZCBnbG9iYWwgb3Igc2hpbSB2ZXJzaW9ucyBvZiBNYXAsIFNldCwgYW5kIFdlYWtNYXBcbiAgICAgICAgdmFyIGZ1bmN0aW9uUHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKEZ1bmN0aW9uKTtcbiAgICAgICAgdmFyIHVzZVBvbHlmaWxsID0gdHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgcHJvY2Vzcy5lbnYgJiYgcHJvY2Vzcy5lbnZbXCJSRUZMRUNUX01FVEFEQVRBX1VTRV9NQVBfUE9MWUZJTExcIl0gPT09IFwidHJ1ZVwiO1xuICAgICAgICB2YXIgX01hcCA9ICF1c2VQb2x5ZmlsbCAmJiB0eXBlb2YgTWFwID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIE1hcC5wcm90b3R5cGUuZW50cmllcyA9PT0gXCJmdW5jdGlvblwiID8gTWFwIDogQ3JlYXRlTWFwUG9seWZpbGwoKTtcbiAgICAgICAgdmFyIF9TZXQgPSAhdXNlUG9seWZpbGwgJiYgdHlwZW9mIFNldCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTZXQucHJvdG90eXBlLmVudHJpZXMgPT09IFwiZnVuY3Rpb25cIiA/IFNldCA6IENyZWF0ZVNldFBvbHlmaWxsKCk7XG4gICAgICAgIHZhciBfV2Vha01hcCA9ICF1c2VQb2x5ZmlsbCAmJiB0eXBlb2YgV2Vha01hcCA9PT0gXCJmdW5jdGlvblwiID8gV2Vha01hcCA6IENyZWF0ZVdlYWtNYXBQb2x5ZmlsbCgpO1xuICAgICAgICAvLyBbW01ldGFkYXRhXV0gaW50ZXJuYWwgc2xvdFxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeS1vYmplY3QtaW50ZXJuYWwtbWV0aG9kcy1hbmQtaW50ZXJuYWwtc2xvdHNcbiAgICAgICAgdmFyIE1ldGFkYXRhID0gbmV3IF9XZWFrTWFwKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBcHBsaWVzIGEgc2V0IG9mIGRlY29yYXRvcnMgdG8gYSBwcm9wZXJ0eSBvZiBhIHRhcmdldCBvYmplY3QuXG4gICAgICAgICAqIEBwYXJhbSBkZWNvcmF0b3JzIEFuIGFycmF5IG9mIGRlY29yYXRvcnMuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3QuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgdG8gZGVjb3JhdGUuXG4gICAgICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgZm9yIHRoZSB0YXJnZXQga2V5LlxuICAgICAgICAgKiBAcmVtYXJrcyBEZWNvcmF0b3JzIGFyZSBhcHBsaWVkIGluIHJldmVyc2Ugb3JkZXIuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIEV4YW1wbGUgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnNBcnJheSwgRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnNBcnJheSwgRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnNBcnJheSwgRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIsXG4gICAgICAgICAqICAgICAgICAgUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzQXJyYXksIEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIsXG4gICAgICAgICAqICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIikpKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiLFxuICAgICAgICAgKiAgICAgICAgIFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9yc0FycmF5LCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIixcbiAgICAgICAgICogICAgICAgICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIikpKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFJc0FycmF5KGRlY29yYXRvcnMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdChhdHRyaWJ1dGVzKSAmJiAhSXNVbmRlZmluZWQoYXR0cmlidXRlcykgJiYgIUlzTnVsbChhdHRyaWJ1dGVzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIGlmIChJc051bGwoYXR0cmlidXRlcykpXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gRGVjb3JhdGVQcm9wZXJ0eShkZWNvcmF0b3JzLCB0YXJnZXQsIHByb3BlcnR5S2V5LCBhdHRyaWJ1dGVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghSXNBcnJheShkZWNvcmF0b3JzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIGlmICghSXNDb25zdHJ1Y3Rvcih0YXJnZXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIERlY29yYXRlQ29uc3RydWN0b3IoZGVjb3JhdG9ycywgdGFyZ2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImRlY29yYXRlXCIsIGRlY29yYXRlKTtcbiAgICAgICAgLy8gNC4xLjIgUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSlcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jcmVmbGVjdC5tZXRhZGF0YVxuICAgICAgICAvKipcbiAgICAgICAgICogQSBkZWZhdWx0IG1ldGFkYXRhIGRlY29yYXRvciBmYWN0b3J5IHRoYXQgY2FuIGJlIHVzZWQgb24gYSBjbGFzcywgY2xhc3MgbWVtYmVyLCBvciBwYXJhbWV0ZXIuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBUaGUga2V5IGZvciB0aGUgbWV0YWRhdGEgZW50cnkuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YVZhbHVlIFRoZSB2YWx1ZSBmb3IgdGhlIG1ldGFkYXRhIGVudHJ5LlxuICAgICAgICAgKiBAcmV0dXJucyBBIGRlY29yYXRvciBmdW5jdGlvbi5cbiAgICAgICAgICogQHJlbWFya3NcbiAgICAgICAgICogSWYgYG1ldGFkYXRhS2V5YCBpcyBhbHJlYWR5IGRlZmluZWQgZm9yIHRoZSB0YXJnZXQgYW5kIHRhcmdldCBrZXksIHRoZVxuICAgICAgICAgKiBtZXRhZGF0YVZhbHVlIGZvciB0aGF0IGtleSB3aWxsIGJlIG92ZXJ3cml0dGVuLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIEBSZWZsZWN0Lm1ldGFkYXRhKGtleSwgdmFsdWUpXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvciwgVHlwZVNjcmlwdCBvbmx5KVxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgQFJlZmxlY3QubWV0YWRhdGEoa2V5LCB2YWx1ZSlcbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlLCBUeXBlU2NyaXB0IG9ubHkpXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICBAUmVmbGVjdC5tZXRhZGF0YShrZXksIHZhbHVlKVxuICAgICAgICAgKiAgICAgICAgIHByb3BlcnR5O1xuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIEBSZWZsZWN0Lm1ldGFkYXRhKGtleSwgdmFsdWUpXG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZCgpIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICBAUmVmbGVjdC5tZXRhZGF0YShrZXksIHZhbHVlKVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZCgpIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uIGRlY29yYXRvcih0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkgJiYgIUlzUHJvcGVydHlLZXkocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgT3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGVjb3JhdG9yO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwibWV0YWRhdGFcIiwgbWV0YWRhdGEpO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGVmaW5lIGEgdW5pcXVlIG1ldGFkYXRhIGVudHJ5IG9uIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBBIGtleSB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIG1ldGFkYXRhVmFsdWUgQSB2YWx1ZSB0aGF0IGNvbnRhaW5zIGF0dGFjaGVkIG1ldGFkYXRhLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRvIGRlZmluZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBvcHRpb25zLCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIG9wdGlvbnMsIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGRlY29yYXRvciBmYWN0b3J5IGFzIG1ldGFkYXRhLXByb2R1Y2luZyBhbm5vdGF0aW9uLlxuICAgICAgICAgKiAgICAgZnVuY3Rpb24gTXlBbm5vdGF0aW9uKG9wdGlvbnMpOiBEZWNvcmF0b3Ige1xuICAgICAgICAgKiAgICAgICAgIHJldHVybiAodGFyZ2V0LCBrZXk/KSA9PiBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgb3B0aW9ucywgdGFyZ2V0LCBrZXkpO1xuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZGVmaW5lTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiZGVmaW5lTWV0YWRhdGFcIiwgZGVmaW5lTWV0YWRhdGEpO1xuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGUgdGFyZ2V0IG9iamVjdCBvciBpdHMgcHJvdG90eXBlIGNoYWluIGhhcyB0aGUgcHJvdmlkZWQgbWV0YWRhdGEga2V5IGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBBIGtleSB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0aGUgbWV0YWRhdGEgaXMgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBtZXRhZGF0YSBrZXkgd2FzIGRlZmluZWQgb24gdGhlIHRhcmdldCBvYmplY3Qgb3IgaXRzIHByb3RvdHlwZSBjaGFpbjsgb3RoZXJ3aXNlLCBgZmFsc2VgLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNQcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5oYXNNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZS5wcm90b3R5cGUsIFwibWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gaGFzTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgICAgIGlmICghSXNPYmplY3QodGFyZ2V0KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICBpZiAoIUlzVW5kZWZpbmVkKHByb3BlcnR5S2V5KSlcbiAgICAgICAgICAgICAgICBwcm9wZXJ0eUtleSA9IFRvUHJvcGVydHlLZXkocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5SGFzTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIGV4cG9ydGVyKFwiaGFzTWV0YWRhdGFcIiwgaGFzTWV0YWRhdGEpO1xuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGUgdGFyZ2V0IG9iamVjdCBoYXMgdGhlIHByb3ZpZGVkIG1ldGFkYXRhIGtleSBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgQSBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbWV0YWRhdGEga2V5IHdhcyBkZWZpbmVkIG9uIHRoZSB0YXJnZXQgb2JqZWN0OyBvdGhlcndpc2UsIGBmYWxzZWAuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0Lmhhc093bk1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuaGFzT3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBoYXNPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlIYXNPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJoYXNPd25NZXRhZGF0YVwiLCBoYXNPd25NZXRhZGF0YSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBtZXRhZGF0YSB2YWx1ZSBmb3IgdGhlIHByb3ZpZGVkIG1ldGFkYXRhIGtleSBvbiB0aGUgdGFyZ2V0IG9iamVjdCBvciBpdHMgcHJvdG90eXBlIGNoYWluLlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgQSBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIFRoZSBtZXRhZGF0YSB2YWx1ZSBmb3IgdGhlIG1ldGFkYXRhIGtleSBpZiBmb3VuZDsgb3RoZXJ3aXNlLCBgdW5kZWZpbmVkYC5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldE1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUdldE1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImdldE1ldGFkYXRhXCIsIGdldE1ldGFkYXRhKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIG1ldGFkYXRhIHZhbHVlIGZvciB0aGUgcHJvdmlkZWQgbWV0YWRhdGEga2V5IG9uIHRoZSB0YXJnZXQgb2JqZWN0LlxuICAgICAgICAgKiBAcGFyYW0gbWV0YWRhdGFLZXkgQSBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIFRoZSBtZXRhZGF0YSB2YWx1ZSBmb3IgdGhlIG1ldGFkYXRhIGtleSBpZiBmb3VuZDsgb3RoZXJ3aXNlLCBgdW5kZWZpbmVkYC5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY01ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShcImN1c3RvbTphbm5vdGF0aW9uXCIsIEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldE93bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUdldE93bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImdldE93bk1ldGFkYXRhXCIsIGdldE93bk1ldGFkYXRhKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIG1ldGFkYXRhIGtleXMgZGVmaW5lZCBvbiB0aGUgdGFyZ2V0IG9iamVjdCBvciBpdHMgcHJvdG90eXBlIGNoYWluLlxuICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IG9uIHdoaWNoIHRoZSBtZXRhZGF0YSBpcyBkZWZpbmVkLlxuICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlLZXkgKE9wdGlvbmFsKSBUaGUgcHJvcGVydHkga2V5IGZvciB0aGUgdGFyZ2V0LlxuICAgICAgICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiB1bmlxdWUgbWV0YWRhdGEga2V5cy5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIGNsYXNzIEV4YW1wbGUge1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5IGRlY2xhcmF0aW9ucyBhcmUgbm90IHBhcnQgb2YgRVM2LCB0aG91Z2ggdGhleSBhcmUgdmFsaWQgaW4gVHlwZVNjcmlwdDpcbiAgICAgICAgICogICAgICAgICAvLyBzdGF0aWMgc3RhdGljUHJvcGVydHk7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAgICAgY29uc3RydWN0b3IocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgc3RhdGljIHN0YXRpY01ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgICAgICBtZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICB9XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvclxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRNZXRhZGF0YUtleXMoRXhhbXBsZSk7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhS2V5cyhFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGFLZXlzKEV4YW1wbGUucHJvdG90eXBlLCBcInByb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0TWV0YWRhdGFLZXlzKEV4YW1wbGUsIFwic3RhdGljTWV0aG9kXCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gbWV0aG9kIChvbiBwcm90b3R5cGUpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE1ldGFkYXRhS2V5cyhFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBnZXRNZXRhZGF0YUtleXModGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICByZXR1cm4gT3JkaW5hcnlNZXRhZGF0YUtleXModGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb3J0ZXIoXCJnZXRNZXRhZGF0YUtleXNcIiwgZ2V0TWV0YWRhdGFLZXlzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIHVuaXF1ZSBtZXRhZGF0YSBrZXlzIGRlZmluZWQgb24gdGhlIHRhcmdldCBvYmplY3QuXG4gICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3Qgb24gd2hpY2ggdGhlIG1ldGFkYXRhIGlzIGRlZmluZWQuXG4gICAgICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAoT3B0aW9uYWwpIFRoZSBwcm9wZXJ0eSBrZXkgZm9yIHRoZSB0YXJnZXQuXG4gICAgICAgICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHVuaXF1ZSBtZXRhZGF0YSBrZXlzLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgY2xhc3MgRXhhbXBsZSB7XG4gICAgICAgICAqICAgICAgICAgLy8gcHJvcGVydHkgZGVjbGFyYXRpb25zIGFyZSBub3QgcGFydCBvZiBFUzYsIHRob3VnaCB0aGV5IGFyZSB2YWxpZCBpbiBUeXBlU2NyaXB0OlxuICAgICAgICAgKiAgICAgICAgIC8vIHN0YXRpYyBzdGF0aWNQcm9wZXJ0eTtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgICAgICBjb25zdHJ1Y3RvcihwKSB7IH1cbiAgICAgICAgICogICAgICAgICBzdGF0aWMgc3RhdGljTWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIG1ldGhvZChwKSB7IH1cbiAgICAgICAgICogICAgIH1cbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmdldE93bk1ldGFkYXRhS2V5cyhFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGFLZXlzKEV4YW1wbGUsIFwic3RhdGljUHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBwcm9wZXJ0eSAob24gcHJvdG90eXBlKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YUtleXMoRXhhbXBsZS5wcm90b3R5cGUsIFwicHJvcGVydHlcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIGNvbnN0cnVjdG9yKVxuICAgICAgICAgKiAgICAgcmVzdWx0ID0gUmVmbGVjdC5nZXRPd25NZXRhZGF0YUtleXMoRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGFLZXlzKEV4YW1wbGUucHJvdG90eXBlLCBcIm1ldGhvZFwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldE93bk1ldGFkYXRhS2V5cyh0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KHRhcmdldCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgaWYgKCFJc1VuZGVmaW5lZChwcm9wZXJ0eUtleSkpXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXkgPSBUb1Byb3BlcnR5S2V5KHByb3BlcnR5S2V5KTtcbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeU93bk1ldGFkYXRhS2V5cyh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImdldE93bk1ldGFkYXRhS2V5c1wiLCBnZXRPd25NZXRhZGF0YUtleXMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGVsZXRlcyB0aGUgbWV0YWRhdGEgZW50cnkgZnJvbSB0aGUgdGFyZ2V0IG9iamVjdCB3aXRoIHRoZSBwcm92aWRlZCBrZXkuXG4gICAgICAgICAqIEBwYXJhbSBtZXRhZGF0YUtleSBBIGtleSB1c2VkIHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YS5cbiAgICAgICAgICogQHBhcmFtIHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdCBvbiB3aGljaCB0aGUgbWV0YWRhdGEgaXMgZGVmaW5lZC5cbiAgICAgICAgICogQHBhcmFtIHByb3BlcnR5S2V5IChPcHRpb25hbCkgVGhlIHByb3BlcnR5IGtleSBmb3IgdGhlIHRhcmdldC5cbiAgICAgICAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBtZXRhZGF0YSBlbnRyeSB3YXMgZm91bmQgYW5kIGRlbGV0ZWQ7IG90aGVyd2lzZSwgZmFsc2UuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqXG4gICAgICAgICAqICAgICBjbGFzcyBFeGFtcGxlIHtcbiAgICAgICAgICogICAgICAgICAvLyBwcm9wZXJ0eSBkZWNsYXJhdGlvbnMgYXJlIG5vdCBwYXJ0IG9mIEVTNiwgdGhvdWdoIHRoZXkgYXJlIHZhbGlkIGluIFR5cGVTY3JpcHQ6XG4gICAgICAgICAqICAgICAgICAgLy8gc3RhdGljIHN0YXRpY1Byb3BlcnR5O1xuICAgICAgICAgKiAgICAgICAgIC8vIHByb3BlcnR5O1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgICAgIGNvbnN0cnVjdG9yKHApIHsgfVxuICAgICAgICAgKiAgICAgICAgIHN0YXRpYyBzdGF0aWNNZXRob2QocCkgeyB9XG4gICAgICAgICAqICAgICAgICAgbWV0aG9kKHApIHsgfVxuICAgICAgICAgKiAgICAgfVxuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gY29uc3RydWN0b3JcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIHByb3BlcnR5IChvbiBjb25zdHJ1Y3RvcilcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLCBcInN0YXRpY1Byb3BlcnR5XCIpO1xuICAgICAgICAgKlxuICAgICAgICAgKiAgICAgLy8gcHJvcGVydHkgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICpcbiAgICAgICAgICogICAgIC8vIG1ldGhvZCAob24gY29uc3RydWN0b3IpXG4gICAgICAgICAqICAgICByZXN1bHQgPSBSZWZsZWN0LmRlbGV0ZU1ldGFkYXRhKFwiY3VzdG9tOmFubm90YXRpb25cIiwgRXhhbXBsZSwgXCJzdGF0aWNNZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqICAgICAvLyBtZXRob2QgKG9uIHByb3RvdHlwZSlcbiAgICAgICAgICogICAgIHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlTWV0YWRhdGEoXCJjdXN0b206YW5ub3RhdGlvblwiLCBFeGFtcGxlLnByb3RvdHlwZSwgXCJtZXRob2RcIik7XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBkZWxldGVNZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICAgICAgaWYgKCFJc09iamVjdCh0YXJnZXQpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQocHJvcGVydHlLZXkpKVxuICAgICAgICAgICAgICAgIHByb3BlcnR5S2V5ID0gVG9Qcm9wZXJ0eUtleShwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSBHZXRPckNyZWF0ZU1ldGFkYXRhTWFwKHRhcmdldCwgcHJvcGVydHlLZXksIC8qQ3JlYXRlKi8gZmFsc2UpO1xuICAgICAgICAgICAgaWYgKElzVW5kZWZpbmVkKG1ldGFkYXRhTWFwKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAoIW1ldGFkYXRhTWFwLmRlbGV0ZShtZXRhZGF0YUtleSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgaWYgKG1ldGFkYXRhTWFwLnNpemUgPiAwKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgdmFyIHRhcmdldE1ldGFkYXRhID0gTWV0YWRhdGEuZ2V0KHRhcmdldCk7XG4gICAgICAgICAgICB0YXJnZXRNZXRhZGF0YS5kZWxldGUocHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgaWYgKHRhcmdldE1ldGFkYXRhLnNpemUgPiAwKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgTWV0YWRhdGEuZGVsZXRlKHRhcmdldCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBleHBvcnRlcihcImRlbGV0ZU1ldGFkYXRhXCIsIGRlbGV0ZU1ldGFkYXRhKTtcbiAgICAgICAgZnVuY3Rpb24gRGVjb3JhdGVDb25zdHJ1Y3RvcihkZWNvcmF0b3JzLCB0YXJnZXQpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRlY29yYXRvciA9IGRlY29yYXRvcnNbaV07XG4gICAgICAgICAgICAgICAgdmFyIGRlY29yYXRlZCA9IGRlY29yYXRvcih0YXJnZXQpO1xuICAgICAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQoZGVjb3JhdGVkKSAmJiAhSXNOdWxsKGRlY29yYXRlZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFJc0NvbnN0cnVjdG9yKGRlY29yYXRlZCkpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IGRlY29yYXRlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIERlY29yYXRlUHJvcGVydHkoZGVjb3JhdG9ycywgdGFyZ2V0LCBwcm9wZXJ0eUtleSwgZGVzY3JpcHRvcikge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVjb3JhdG9yID0gZGVjb3JhdG9yc1tpXTtcbiAgICAgICAgICAgICAgICB2YXIgZGVjb3JhdGVkID0gZGVjb3JhdG9yKHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IpO1xuICAgICAgICAgICAgICAgIGlmICghSXNVbmRlZmluZWQoZGVjb3JhdGVkKSAmJiAhSXNOdWxsKGRlY29yYXRlZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdChkZWNvcmF0ZWQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yID0gZGVjb3JhdGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIEdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgQ3JlYXRlKSB7XG4gICAgICAgICAgICB2YXIgdGFyZ2V0TWV0YWRhdGEgPSBNZXRhZGF0YS5nZXQoTyk7XG4gICAgICAgICAgICBpZiAoSXNVbmRlZmluZWQodGFyZ2V0TWV0YWRhdGEpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFDcmVhdGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgdGFyZ2V0TWV0YWRhdGEgPSBuZXcgX01hcCgpO1xuICAgICAgICAgICAgICAgIE1ldGFkYXRhLnNldChPLCB0YXJnZXRNZXRhZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSB0YXJnZXRNZXRhZGF0YS5nZXQoUCk7XG4gICAgICAgICAgICBpZiAoSXNVbmRlZmluZWQobWV0YWRhdGFNYXApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFDcmVhdGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgbWV0YWRhdGFNYXAgPSBuZXcgX01hcCgpO1xuICAgICAgICAgICAgICAgIHRhcmdldE1ldGFkYXRhLnNldChQLCBtZXRhZGF0YU1hcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWV0YWRhdGFNYXA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjEuMSBPcmRpbmFyeUhhc01ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeWhhc21ldGFkYXRhXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5SGFzTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgICAgICAgICAgIHZhciBoYXNPd24gPSBPcmRpbmFyeUhhc093bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKTtcbiAgICAgICAgICAgIGlmIChoYXNPd24pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB2YXIgcGFyZW50ID0gT3JkaW5hcnlHZXRQcm90b3R5cGVPZihPKTtcbiAgICAgICAgICAgIGlmICghSXNOdWxsKHBhcmVudCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5SGFzTWV0YWRhdGEoTWV0YWRhdGFLZXksIHBhcmVudCwgUCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjIuMSBPcmRpbmFyeUhhc093bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeWhhc293bm1ldGFkYXRhXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5SGFzT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgICAgICAgICAgIHZhciBtZXRhZGF0YU1hcCA9IEdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgLypDcmVhdGUqLyBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoSXNVbmRlZmluZWQobWV0YWRhdGFNYXApKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiBUb0Jvb2xlYW4obWV0YWRhdGFNYXAuaGFzKE1ldGFkYXRhS2V5KSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMy4xLjMuMSBPcmRpbmFyeUdldE1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKVxuICAgICAgICAvLyBodHRwczovL3JidWNrdG9uLmdpdGh1Yi5pby9yZWZsZWN0LW1ldGFkYXRhLyNvcmRpbmFyeWdldG1ldGFkYXRhXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5R2V0TWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgICAgICAgICAgIHZhciBoYXNPd24gPSBPcmRpbmFyeUhhc093bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKTtcbiAgICAgICAgICAgIGlmIChoYXNPd24pXG4gICAgICAgICAgICAgICAgcmV0dXJuIE9yZGluYXJ5R2V0T3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApO1xuICAgICAgICAgICAgdmFyIHBhcmVudCA9IE9yZGluYXJ5R2V0UHJvdG90eXBlT2YoTyk7XG4gICAgICAgICAgICBpZiAoIUlzTnVsbChwYXJlbnQpKVxuICAgICAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeUdldE1ldGFkYXRhKE1ldGFkYXRhS2V5LCBwYXJlbnQsIFApO1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyAzLjEuNC4xIE9yZGluYXJ5R2V0T3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5Z2V0b3dubWV0YWRhdGFcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlHZXRPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCkge1xuICAgICAgICAgICAgdmFyIG1ldGFkYXRhTWFwID0gR2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCAvKkNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgIGlmIChJc1VuZGVmaW5lZChtZXRhZGF0YU1hcCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YU1hcC5nZXQoTWV0YWRhdGFLZXkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuMS41LjEgT3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTWV0YWRhdGFWYWx1ZSwgTywgUClcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnlkZWZpbmVvd25tZXRhZGF0YVxuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeURlZmluZU93bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBNZXRhZGF0YVZhbHVlLCBPLCBQKSB7XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSBHZXRPckNyZWF0ZU1ldGFkYXRhTWFwKE8sIFAsIC8qQ3JlYXRlKi8gdHJ1ZSk7XG4gICAgICAgICAgICBtZXRhZGF0YU1hcC5zZXQoTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDMuMS42LjEgT3JkaW5hcnlNZXRhZGF0YUtleXMoTywgUClcbiAgICAgICAgLy8gaHR0cHM6Ly9yYnVja3Rvbi5naXRodWIuaW8vcmVmbGVjdC1tZXRhZGF0YS8jb3JkaW5hcnltZXRhZGF0YWtleXNcbiAgICAgICAgZnVuY3Rpb24gT3JkaW5hcnlNZXRhZGF0YUtleXMoTywgUCkge1xuICAgICAgICAgICAgdmFyIG93bktleXMgPSBPcmRpbmFyeU93bk1ldGFkYXRhS2V5cyhPLCBQKTtcbiAgICAgICAgICAgIHZhciBwYXJlbnQgPSBPcmRpbmFyeUdldFByb3RvdHlwZU9mKE8pO1xuICAgICAgICAgICAgaWYgKHBhcmVudCA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gb3duS2V5cztcbiAgICAgICAgICAgIHZhciBwYXJlbnRLZXlzID0gT3JkaW5hcnlNZXRhZGF0YUtleXMocGFyZW50LCBQKTtcbiAgICAgICAgICAgIGlmIChwYXJlbnRLZXlzLmxlbmd0aCA8PSAwKVxuICAgICAgICAgICAgICAgIHJldHVybiBvd25LZXlzO1xuICAgICAgICAgICAgaWYgKG93bktleXMubGVuZ3RoIDw9IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudEtleXM7XG4gICAgICAgICAgICB2YXIgc2V0ID0gbmV3IF9TZXQoKTtcbiAgICAgICAgICAgIHZhciBrZXlzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIG93bktleXNfMSA9IG93bktleXM7IF9pIDwgb3duS2V5c18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgIHZhciBrZXkgPSBvd25LZXlzXzFbX2ldO1xuICAgICAgICAgICAgICAgIHZhciBoYXNLZXkgPSBzZXQuaGFzKGtleSk7XG4gICAgICAgICAgICAgICAgaWYgKCFoYXNLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0LmFkZChrZXkpO1xuICAgICAgICAgICAgICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKHZhciBfYSA9IDAsIHBhcmVudEtleXNfMSA9IHBhcmVudEtleXM7IF9hIDwgcGFyZW50S2V5c18xLmxlbmd0aDsgX2ErKykge1xuICAgICAgICAgICAgICAgIHZhciBrZXkgPSBwYXJlbnRLZXlzXzFbX2FdO1xuICAgICAgICAgICAgICAgIHZhciBoYXNLZXkgPSBzZXQuaGFzKGtleSk7XG4gICAgICAgICAgICAgICAgaWYgKCFoYXNLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0LmFkZChrZXkpO1xuICAgICAgICAgICAgICAgICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ga2V5cztcbiAgICAgICAgfVxuICAgICAgICAvLyAzLjEuNy4xIE9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKE8sIFApXG4gICAgICAgIC8vIGh0dHBzOi8vcmJ1Y2t0b24uZ2l0aHViLmlvL3JlZmxlY3QtbWV0YWRhdGEvI29yZGluYXJ5b3dubWV0YWRhdGFrZXlzXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKE8sIFApIHtcbiAgICAgICAgICAgIHZhciBrZXlzID0gW107XG4gICAgICAgICAgICB2YXIgbWV0YWRhdGFNYXAgPSBHZXRPckNyZWF0ZU1ldGFkYXRhTWFwKE8sIFAsIC8qQ3JlYXRlKi8gZmFsc2UpO1xuICAgICAgICAgICAgaWYgKElzVW5kZWZpbmVkKG1ldGFkYXRhTWFwKSlcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5cztcbiAgICAgICAgICAgIHZhciBrZXlzT2JqID0gbWV0YWRhdGFNYXAua2V5cygpO1xuICAgICAgICAgICAgdmFyIGl0ZXJhdG9yID0gR2V0SXRlcmF0b3Ioa2V5c09iaik7XG4gICAgICAgICAgICB2YXIgayA9IDA7XG4gICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgIHZhciBuZXh0ID0gSXRlcmF0b3JTdGVwKGl0ZXJhdG9yKTtcbiAgICAgICAgICAgICAgICBpZiAoIW5leHQpIHtcbiAgICAgICAgICAgICAgICAgICAga2V5cy5sZW5ndGggPSBrO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ga2V5cztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIG5leHRWYWx1ZSA9IEl0ZXJhdG9yVmFsdWUobmV4dCk7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAga2V5c1trXSA9IG5leHRWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhdG9yQ2xvc2UoaXRlcmF0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBrKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gNiBFQ01BU2NyaXB0IERhdGEgVHlwMGVzIGFuZCBWYWx1ZXNcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZWNtYXNjcmlwdC1kYXRhLXR5cGVzLWFuZC12YWx1ZXNcbiAgICAgICAgZnVuY3Rpb24gVHlwZSh4KSB7XG4gICAgICAgICAgICBpZiAoeCA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gMSAvKiBOdWxsICovO1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlb2YgeCkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJ1bmRlZmluZWRcIjogcmV0dXJuIDAgLyogVW5kZWZpbmVkICovO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJib29sZWFuXCI6IHJldHVybiAyIC8qIEJvb2xlYW4gKi87XG4gICAgICAgICAgICAgICAgY2FzZSBcInN0cmluZ1wiOiByZXR1cm4gMyAvKiBTdHJpbmcgKi87XG4gICAgICAgICAgICAgICAgY2FzZSBcInN5bWJvbFwiOiByZXR1cm4gNCAvKiBTeW1ib2wgKi87XG4gICAgICAgICAgICAgICAgY2FzZSBcIm51bWJlclwiOiByZXR1cm4gNSAvKiBOdW1iZXIgKi87XG4gICAgICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOiByZXR1cm4geCA9PT0gbnVsbCA/IDEgLyogTnVsbCAqLyA6IDYgLyogT2JqZWN0ICovO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiA2IC8qIE9iamVjdCAqLztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyA2LjEuMSBUaGUgVW5kZWZpbmVkIFR5cGVcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcy11bmRlZmluZWQtdHlwZVxuICAgICAgICBmdW5jdGlvbiBJc1VuZGVmaW5lZCh4KSB7XG4gICAgICAgICAgICByZXR1cm4geCA9PT0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIDYuMS4yIFRoZSBOdWxsIFR5cGVcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcy1udWxsLXR5cGVcbiAgICAgICAgZnVuY3Rpb24gSXNOdWxsKHgpIHtcbiAgICAgICAgICAgIHJldHVybiB4ID09PSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIC8vIDYuMS41IFRoZSBTeW1ib2wgVHlwZVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzLXN5bWJvbC10eXBlXG4gICAgICAgIGZ1bmN0aW9uIElzU3ltYm9sKHgpIHtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgeCA9PT0gXCJzeW1ib2xcIjtcbiAgICAgICAgfVxuICAgICAgICAvLyA2LjEuNyBUaGUgT2JqZWN0IFR5cGVcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb2JqZWN0LXR5cGVcbiAgICAgICAgZnVuY3Rpb24gSXNPYmplY3QoeCkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcIm9iamVjdFwiID8geCAhPT0gbnVsbCA6IHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4xIFR5cGUgQ29udmVyc2lvblxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10eXBlLWNvbnZlcnNpb25cbiAgICAgICAgLy8gNy4xLjEgVG9QcmltaXRpdmUoaW5wdXQgWywgUHJlZmVycmVkVHlwZV0pXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXRvcHJpbWl0aXZlXG4gICAgICAgIGZ1bmN0aW9uIFRvUHJpbWl0aXZlKGlucHV0LCBQcmVmZXJyZWRUeXBlKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKFR5cGUoaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAwIC8qIFVuZGVmaW5lZCAqLzogcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgIGNhc2UgMSAvKiBOdWxsICovOiByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgY2FzZSAyIC8qIEJvb2xlYW4gKi86IHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgICAgICBjYXNlIDMgLyogU3RyaW5nICovOiByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgY2FzZSA0IC8qIFN5bWJvbCAqLzogcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgIGNhc2UgNSAvKiBOdW1iZXIgKi86IHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBoaW50ID0gUHJlZmVycmVkVHlwZSA9PT0gMyAvKiBTdHJpbmcgKi8gPyBcInN0cmluZ1wiIDogUHJlZmVycmVkVHlwZSA9PT0gNSAvKiBOdW1iZXIgKi8gPyBcIm51bWJlclwiIDogXCJkZWZhdWx0XCI7XG4gICAgICAgICAgICB2YXIgZXhvdGljVG9QcmltID0gR2V0TWV0aG9kKGlucHV0LCB0b1ByaW1pdGl2ZVN5bWJvbCk7XG4gICAgICAgICAgICBpZiAoZXhvdGljVG9QcmltICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gZXhvdGljVG9QcmltLmNhbGwoaW5wdXQsIGhpbnQpO1xuICAgICAgICAgICAgICAgIGlmIChJc09iamVjdChyZXN1bHQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBPcmRpbmFyeVRvUHJpbWl0aXZlKGlucHV0LCBoaW50ID09PSBcImRlZmF1bHRcIiA/IFwibnVtYmVyXCIgOiBoaW50KTtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjEuMS4xIE9yZGluYXJ5VG9QcmltaXRpdmUoTywgaGludClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb3JkaW5hcnl0b3ByaW1pdGl2ZVxuICAgICAgICBmdW5jdGlvbiBPcmRpbmFyeVRvUHJpbWl0aXZlKE8sIGhpbnQpIHtcbiAgICAgICAgICAgIGlmIChoaW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRvU3RyaW5nXzEgPSBPLnRvU3RyaW5nO1xuICAgICAgICAgICAgICAgIGlmIChJc0NhbGxhYmxlKHRvU3RyaW5nXzEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB0b1N0cmluZ18xLmNhbGwoTyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QocmVzdWx0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciB2YWx1ZU9mID0gTy52YWx1ZU9mO1xuICAgICAgICAgICAgICAgIGlmIChJc0NhbGxhYmxlKHZhbHVlT2YpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB2YWx1ZU9mLmNhbGwoTyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QocmVzdWx0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlT2YgPSBPLnZhbHVlT2Y7XG4gICAgICAgICAgICAgICAgaWYgKElzQ2FsbGFibGUodmFsdWVPZikpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHZhbHVlT2YuY2FsbChPKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFJc09iamVjdChyZXN1bHQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHRvU3RyaW5nXzIgPSBPLnRvU3RyaW5nO1xuICAgICAgICAgICAgICAgIGlmIChJc0NhbGxhYmxlKHRvU3RyaW5nXzIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB0b1N0cmluZ18yLmNhbGwoTyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSXNPYmplY3QocmVzdWx0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMS4yIFRvQm9vbGVhbihhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLzIwMTYvI3NlYy10b2Jvb2xlYW5cbiAgICAgICAgZnVuY3Rpb24gVG9Cb29sZWFuKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gISFhcmd1bWVudDtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjEuMTIgVG9TdHJpbmcoYXJndW1lbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXRvc3RyaW5nXG4gICAgICAgIGZ1bmN0aW9uIFRvU3RyaW5nKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gXCJcIiArIGFyZ3VtZW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMS4xNCBUb1Byb3BlcnR5S2V5KGFyZ3VtZW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10b3Byb3BlcnR5a2V5XG4gICAgICAgIGZ1bmN0aW9uIFRvUHJvcGVydHlLZXkoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBUb1ByaW1pdGl2ZShhcmd1bWVudCwgMyAvKiBTdHJpbmcgKi8pO1xuICAgICAgICAgICAgaWYgKElzU3ltYm9sKGtleSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgICAgICAgIHJldHVybiBUb1N0cmluZyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDcuMiBUZXN0aW5nIGFuZCBDb21wYXJpc29uIE9wZXJhdGlvbnNcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdGVzdGluZy1hbmQtY29tcGFyaXNvbi1vcGVyYXRpb25zXG4gICAgICAgIC8vIDcuMi4yIElzQXJyYXkoYXJndW1lbnQpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWlzYXJyYXlcbiAgICAgICAgZnVuY3Rpb24gSXNBcnJheShhcmd1bWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXlcbiAgICAgICAgICAgICAgICA/IEFycmF5LmlzQXJyYXkoYXJndW1lbnQpXG4gICAgICAgICAgICAgICAgOiBhcmd1bWVudCBpbnN0YW5jZW9mIE9iamVjdFxuICAgICAgICAgICAgICAgICAgICA/IGFyZ3VtZW50IGluc3RhbmNlb2YgQXJyYXlcbiAgICAgICAgICAgICAgICAgICAgOiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJndW1lbnQpID09PSBcIltvYmplY3QgQXJyYXldXCI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4yLjMgSXNDYWxsYWJsZShhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtaXNjYWxsYWJsZVxuICAgICAgICBmdW5jdGlvbiBJc0NhbGxhYmxlKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBUaGlzIGlzIGFuIGFwcHJveGltYXRpb24gYXMgd2UgY2Fubm90IGNoZWNrIGZvciBbW0NhbGxdXSBpbnRlcm5hbCBtZXRob2QuXG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGFyZ3VtZW50ID09PSBcImZ1bmN0aW9uXCI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4yLjQgSXNDb25zdHJ1Y3Rvcihhcmd1bWVudClcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtaXNjb25zdHJ1Y3RvclxuICAgICAgICBmdW5jdGlvbiBJc0NvbnN0cnVjdG9yKGFyZ3VtZW50KSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBUaGlzIGlzIGFuIGFwcHJveGltYXRpb24gYXMgd2UgY2Fubm90IGNoZWNrIGZvciBbW0NvbnN0cnVjdF1dIGludGVybmFsIG1ldGhvZC5cbiAgICAgICAgICAgIHJldHVybiB0eXBlb2YgYXJndW1lbnQgPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjIuNyBJc1Byb3BlcnR5S2V5KGFyZ3VtZW50KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1pc3Byb3BlcnR5a2V5XG4gICAgICAgIGZ1bmN0aW9uIElzUHJvcGVydHlLZXkoYXJndW1lbnQpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoVHlwZShhcmd1bWVudCkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDMgLyogU3RyaW5nICovOiByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjYXNlIDQgLyogU3ltYm9sICovOiByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy4zIE9wZXJhdGlvbnMgb24gT2JqZWN0c1xuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1vcGVyYXRpb25zLW9uLW9iamVjdHNcbiAgICAgICAgLy8gNy4zLjkgR2V0TWV0aG9kKFYsIFApXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWdldG1ldGhvZFxuICAgICAgICBmdW5jdGlvbiBHZXRNZXRob2QoViwgUCkge1xuICAgICAgICAgICAgdmFyIGZ1bmMgPSBWW1BdO1xuICAgICAgICAgICAgaWYgKGZ1bmMgPT09IHVuZGVmaW5lZCB8fCBmdW5jID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAoIUlzQ2FsbGFibGUoZnVuYykpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy40IE9wZXJhdGlvbnMgb24gSXRlcmF0b3IgT2JqZWN0c1xuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1vcGVyYXRpb25zLW9uLWl0ZXJhdG9yLW9iamVjdHNcbiAgICAgICAgZnVuY3Rpb24gR2V0SXRlcmF0b3Iob2JqKSB7XG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gR2V0TWV0aG9kKG9iaiwgaXRlcmF0b3JTeW1ib2wpO1xuICAgICAgICAgICAgaWYgKCFJc0NhbGxhYmxlKG1ldGhvZCkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOyAvLyBmcm9tIENhbGxcbiAgICAgICAgICAgIHZhciBpdGVyYXRvciA9IG1ldGhvZC5jYWxsKG9iaik7XG4gICAgICAgICAgICBpZiAoIUlzT2JqZWN0KGl0ZXJhdG9yKSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICByZXR1cm4gaXRlcmF0b3I7XG4gICAgICAgIH1cbiAgICAgICAgLy8gNy40LjQgSXRlcmF0b3JWYWx1ZShpdGVyUmVzdWx0KVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvMjAxNi8jc2VjLWl0ZXJhdG9ydmFsdWVcbiAgICAgICAgZnVuY3Rpb24gSXRlcmF0b3JWYWx1ZShpdGVyUmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gaXRlclJlc3VsdC52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjQuNSBJdGVyYXRvclN0ZXAoaXRlcmF0b3IpXG4gICAgICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLWl0ZXJhdG9yc3RlcFxuICAgICAgICBmdW5jdGlvbiBJdGVyYXRvclN0ZXAoaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LmRvbmUgPyBmYWxzZSA6IHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICAvLyA3LjQuNiBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yLCBjb21wbGV0aW9uKVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1pdGVyYXRvcmNsb3NlXG4gICAgICAgIGZ1bmN0aW9uIEl0ZXJhdG9yQ2xvc2UoaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIHZhciBmID0gaXRlcmF0b3JbXCJyZXR1cm5cIl07XG4gICAgICAgICAgICBpZiAoZilcbiAgICAgICAgICAgICAgICBmLmNhbGwoaXRlcmF0b3IpO1xuICAgICAgICB9XG4gICAgICAgIC8vIDkuMSBPcmRpbmFyeSBPYmplY3QgSW50ZXJuYWwgTWV0aG9kcyBhbmQgSW50ZXJuYWwgU2xvdHNcbiAgICAgICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtb3JkaW5hcnktb2JqZWN0LWludGVybmFsLW1ldGhvZHMtYW5kLWludGVybmFsLXNsb3RzXG4gICAgICAgIC8vIDkuMS4xLjEgT3JkaW5hcnlHZXRQcm90b3R5cGVPZihPKVxuICAgICAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1vcmRpbmFyeWdldHByb3RvdHlwZW9mXG4gICAgICAgIGZ1bmN0aW9uIE9yZGluYXJ5R2V0UHJvdG90eXBlT2YoTykge1xuICAgICAgICAgICAgdmFyIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBPICE9PSBcImZ1bmN0aW9uXCIgfHwgTyA9PT0gZnVuY3Rpb25Qcm90b3R5cGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICAgICAgLy8gVHlwZVNjcmlwdCBkb2Vzbid0IHNldCBfX3Byb3RvX18gaW4gRVM1LCBhcyBpdCdzIG5vbi1zdGFuZGFyZC5cbiAgICAgICAgICAgIC8vIFRyeSB0byBkZXRlcm1pbmUgdGhlIHN1cGVyY2xhc3MgY29uc3RydWN0b3IuIENvbXBhdGlibGUgaW1wbGVtZW50YXRpb25zXG4gICAgICAgICAgICAvLyBtdXN0IGVpdGhlciBzZXQgX19wcm90b19fIG9uIGEgc3ViY2xhc3MgY29uc3RydWN0b3IgdG8gdGhlIHN1cGVyY2xhc3MgY29uc3RydWN0b3IsXG4gICAgICAgICAgICAvLyBvciBlbnN1cmUgZWFjaCBjbGFzcyBoYXMgYSB2YWxpZCBgY29uc3RydWN0b3JgIHByb3BlcnR5IG9uIGl0cyBwcm90b3R5cGUgdGhhdFxuICAgICAgICAgICAgLy8gcG9pbnRzIGJhY2sgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBub3QgdGhlIHNhbWUgYXMgRnVuY3Rpb24uW1tQcm90b3R5cGVdXSwgdGhlbiB0aGlzIGlzIGRlZmluYXRlbHkgaW5oZXJpdGVkLlxuICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgY2FzZSB3aGVuIGluIEVTNiBvciB3aGVuIHVzaW5nIF9fcHJvdG9fXyBpbiBhIGNvbXBhdGlibGUgYnJvd3Nlci5cbiAgICAgICAgICAgIGlmIChwcm90byAhPT0gZnVuY3Rpb25Qcm90b3R5cGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICAgICAgLy8gSWYgdGhlIHN1cGVyIHByb3RvdHlwZSBpcyBPYmplY3QucHJvdG90eXBlLCBudWxsLCBvciB1bmRlZmluZWQsIHRoZW4gd2UgY2Fubm90IGRldGVybWluZSB0aGUgaGVyaXRhZ2UuXG4gICAgICAgICAgICB2YXIgcHJvdG90eXBlID0gTy5wcm90b3R5cGU7XG4gICAgICAgICAgICB2YXIgcHJvdG90eXBlUHJvdG8gPSBwcm90b3R5cGUgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSk7XG4gICAgICAgICAgICBpZiAocHJvdG90eXBlUHJvdG8gPT0gbnVsbCB8fCBwcm90b3R5cGVQcm90byA9PT0gT2JqZWN0LnByb3RvdHlwZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvdG87XG4gICAgICAgICAgICAvLyBJZiB0aGUgY29uc3RydWN0b3Igd2FzIG5vdCBhIGZ1bmN0aW9uLCB0aGVuIHdlIGNhbm5vdCBkZXRlcm1pbmUgdGhlIGhlcml0YWdlLlxuICAgICAgICAgICAgdmFyIGNvbnN0cnVjdG9yID0gcHJvdG90eXBlUHJvdG8uY29uc3RydWN0b3I7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGNvbnN0cnVjdG9yICE9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBzb21lIGtpbmQgb2Ygc2VsZi1yZWZlcmVuY2UsIHRoZW4gd2UgY2Fubm90IGRldGVybWluZSB0aGUgaGVyaXRhZ2UuXG4gICAgICAgICAgICBpZiAoY29uc3RydWN0b3IgPT09IE8pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3RvO1xuICAgICAgICAgICAgLy8gd2UgaGF2ZSBhIHByZXR0eSBnb29kIGd1ZXNzIGF0IHRoZSBoZXJpdGFnZS5cbiAgICAgICAgICAgIHJldHVybiBjb25zdHJ1Y3RvcjtcbiAgICAgICAgfVxuICAgICAgICAvLyBuYWl2ZSBNYXAgc2hpbVxuICAgICAgICBmdW5jdGlvbiBDcmVhdGVNYXBQb2x5ZmlsbCgpIHtcbiAgICAgICAgICAgIHZhciBjYWNoZVNlbnRpbmVsID0ge307XG4gICAgICAgICAgICB2YXIgYXJyYXlTZW50aW5lbCA9IFtdO1xuICAgICAgICAgICAgdmFyIE1hcEl0ZXJhdG9yID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIE1hcEl0ZXJhdG9yKGtleXMsIHZhbHVlcywgc2VsZWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5kZXggPSAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzID0ga2V5cztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzID0gdmFsdWVzO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RvciA9IHNlbGVjdG9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBNYXBJdGVyYXRvci5wcm90b3R5cGVbXCJAQGl0ZXJhdG9yXCJdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfTtcbiAgICAgICAgICAgICAgICBNYXBJdGVyYXRvci5wcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfTtcbiAgICAgICAgICAgICAgICBNYXBJdGVyYXRvci5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5faW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5fa2V5cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9zZWxlY3Rvcih0aGlzLl9rZXlzW2luZGV4XSwgdGhpcy5fdmFsdWVzW2luZGV4XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggKyAxID49IHRoaXMuX2tleXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzID0gYXJyYXlTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMgPSBhcnJheVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiByZXN1bHQsIGRvbmU6IGZhbHNlIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgTWFwSXRlcmF0b3IucHJvdG90eXBlLnRocm93ID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbmRleCA9IC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cyA9IGFycmF5U2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMgPSBhcnJheVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgTWFwSXRlcmF0b3IucHJvdG90eXBlLnJldHVybiA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5faW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMgPSBhcnJheVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzID0gYXJyYXlTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogdmFsdWUsIGRvbmU6IHRydWUgfTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiBNYXBJdGVyYXRvcjtcbiAgICAgICAgICAgIH0oKSk7XG4gICAgICAgICAgICByZXR1cm4gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIE1hcCgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5cyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVLZXkgPSBjYWNoZVNlbnRpbmVsO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUluZGV4ID0gLTI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShNYXAucHJvdG90eXBlLCBcInNpemVcIiwge1xuICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX2tleXMubGVuZ3RoOyB9LFxuICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIHRoaXMuX2ZpbmQoa2V5LCAvKmluc2VydCovIGZhbHNlKSA+PSAwOyB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9maW5kKGtleSwgLyppbnNlcnQqLyBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleCA+PSAwID8gdGhpcy5fdmFsdWVzW2luZGV4XSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fZmluZChrZXksIC8qaW5zZXJ0Ki8gdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLmRlbGV0ZSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fZmluZChrZXksIC8qaW5zZXJ0Ki8gZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemUgPSB0aGlzLl9rZXlzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBpbmRleCArIDE7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzW2kgLSAxXSA9IHRoaXMuX2tleXNbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzW2kgLSAxXSA9IHRoaXMuX3ZhbHVlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleXMubGVuZ3RoLS07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXMubGVuZ3RoLS07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2V5ID09PSB0aGlzLl9jYWNoZUtleSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlS2V5ID0gY2FjaGVTZW50aW5lbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUluZGV4ID0gLTI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzLmxlbmd0aCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcy5sZW5ndGggPSAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUtleSA9IGNhY2hlU2VudGluZWw7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlSW5kZXggPSAtMjtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyBNYXBJdGVyYXRvcih0aGlzLl9rZXlzLCB0aGlzLl92YWx1ZXMsIGdldEtleSk7IH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS52YWx1ZXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBuZXcgTWFwSXRlcmF0b3IodGhpcy5fa2V5cywgdGhpcy5fdmFsdWVzLCBnZXRWYWx1ZSk7IH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZS5lbnRyaWVzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gbmV3IE1hcEl0ZXJhdG9yKHRoaXMuX2tleXMsIHRoaXMuX3ZhbHVlcywgZ2V0RW50cnkpOyB9O1xuICAgICAgICAgICAgICAgIE1hcC5wcm90b3R5cGVbXCJAQGl0ZXJhdG9yXCJdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5lbnRyaWVzKCk7IH07XG4gICAgICAgICAgICAgICAgTWFwLnByb3RvdHlwZVtpdGVyYXRvclN5bWJvbF0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLmVudHJpZXMoKTsgfTtcbiAgICAgICAgICAgICAgICBNYXAucHJvdG90eXBlLl9maW5kID0gZnVuY3Rpb24gKGtleSwgaW5zZXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jYWNoZUtleSAhPT0ga2V5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUluZGV4ID0gdGhpcy5fa2V5cy5pbmRleE9mKHRoaXMuX2NhY2hlS2V5ID0ga2V5KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fY2FjaGVJbmRleCA8IDAgJiYgaW5zZXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUluZGV4ID0gdGhpcy5fa2V5cy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlzLnB1c2goa2V5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcy5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlSW5kZXg7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gTWFwO1xuICAgICAgICAgICAgfSgpKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIGdldEtleShrZXksIF8pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZnVuY3Rpb24gZ2V0VmFsdWUoXywgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiBnZXRFbnRyeShrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtrZXksIHZhbHVlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBuYWl2ZSBTZXQgc2hpbVxuICAgICAgICBmdW5jdGlvbiBDcmVhdGVTZXRQb2x5ZmlsbCgpIHtcbiAgICAgICAgICAgIHJldHVybiAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gU2V0KCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYXAgPSBuZXcgX01hcCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU2V0LnByb3RvdHlwZSwgXCJzaXplXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLl9tYXAuc2l6ZTsgfSxcbiAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHRoaXMuX21hcC5oYXModmFsdWUpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB0aGlzLl9tYXAuc2V0KHZhbHVlLCB2YWx1ZSksIHRoaXM7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHRoaXMuX21hcC5kZWxldGUodmFsdWUpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7IHRoaXMuX21hcC5jbGVhcigpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX21hcC5rZXlzKCk7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS52YWx1ZXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLl9tYXAudmFsdWVzKCk7IH07XG4gICAgICAgICAgICAgICAgU2V0LnByb3RvdHlwZS5lbnRyaWVzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fbWFwLmVudHJpZXMoKTsgfTtcbiAgICAgICAgICAgICAgICBTZXQucHJvdG90eXBlW1wiQEBpdGVyYXRvclwiXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMua2V5cygpOyB9O1xuICAgICAgICAgICAgICAgIFNldC5wcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5rZXlzKCk7IH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIFNldDtcbiAgICAgICAgICAgIH0oKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbmFpdmUgV2Vha01hcCBzaGltXG4gICAgICAgIGZ1bmN0aW9uIENyZWF0ZVdlYWtNYXBQb2x5ZmlsbCgpIHtcbiAgICAgICAgICAgIHZhciBVVUlEX1NJWkUgPSAxNjtcbiAgICAgICAgICAgIHZhciBrZXlzID0gSGFzaE1hcC5jcmVhdGUoKTtcbiAgICAgICAgICAgIHZhciByb290S2V5ID0gQ3JlYXRlVW5pcXVlS2V5KCk7XG4gICAgICAgICAgICByZXR1cm4gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIFdlYWtNYXAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleSA9IENyZWF0ZVVuaXF1ZUtleSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBXZWFrTWFwLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWJsZSA9IEdldE9yQ3JlYXRlV2Vha01hcFRhYmxlKHRhcmdldCwgLypjcmVhdGUqLyBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YWJsZSAhPT0gdW5kZWZpbmVkID8gSGFzaE1hcC5oYXModGFibGUsIHRoaXMuX2tleSkgOiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIFdlYWtNYXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhYmxlID0gR2V0T3JDcmVhdGVXZWFrTWFwVGFibGUodGFyZ2V0LCAvKmNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhYmxlICE9PSB1bmRlZmluZWQgPyBIYXNoTWFwLmdldCh0YWJsZSwgdGhpcy5fa2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIFdlYWtNYXAucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uICh0YXJnZXQsIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWJsZSA9IEdldE9yQ3JlYXRlV2Vha01hcFRhYmxlKHRhcmdldCwgLypjcmVhdGUqLyB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgdGFibGVbdGhpcy5fa2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIFdlYWtNYXAucHJvdG90eXBlLmRlbGV0ZSA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhYmxlID0gR2V0T3JDcmVhdGVXZWFrTWFwVGFibGUodGFyZ2V0LCAvKmNyZWF0ZSovIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhYmxlICE9PSB1bmRlZmluZWQgPyBkZWxldGUgdGFibGVbdGhpcy5fa2V5XSA6IGZhbHNlO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgV2Vha01hcC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE5PVEU6IG5vdCBhIHJlYWwgY2xlYXIsIGp1c3QgbWFrZXMgdGhlIHByZXZpb3VzIGRhdGEgdW5yZWFjaGFibGVcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5ID0gQ3JlYXRlVW5pcXVlS2V5KCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gV2Vha01hcDtcbiAgICAgICAgICAgIH0oKSk7XG4gICAgICAgICAgICBmdW5jdGlvbiBDcmVhdGVVbmlxdWVLZXkoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleTtcbiAgICAgICAgICAgICAgICBkb1xuICAgICAgICAgICAgICAgICAgICBrZXkgPSBcIkBAV2Vha01hcEBAXCIgKyBDcmVhdGVVVUlEKCk7XG4gICAgICAgICAgICAgICAgd2hpbGUgKEhhc2hNYXAuaGFzKGtleXMsIGtleSkpO1xuICAgICAgICAgICAgICAgIGtleXNba2V5XSA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIEdldE9yQ3JlYXRlV2Vha01hcFRhYmxlKHRhcmdldCwgY3JlYXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFoYXNPd24uY2FsbCh0YXJnZXQsIHJvb3RLZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY3JlYXRlKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcm9vdEtleSwgeyB2YWx1ZTogSGFzaE1hcC5jcmVhdGUoKSB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldFtyb290S2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIEZpbGxSYW5kb21CeXRlcyhidWZmZXIsIHNpemUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyW2ldID0gTWF0aC5yYW5kb20oKSAqIDB4ZmYgfCAwO1xuICAgICAgICAgICAgICAgIHJldHVybiBidWZmZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiBHZW5SYW5kb21CeXRlcyhzaXplKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBVaW50OEFycmF5ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjcnlwdG8gIT09IFwidW5kZWZpbmVkXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhuZXcgVWludDhBcnJheShzaXplKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbXNDcnlwdG8gIT09IFwidW5kZWZpbmVkXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKG5ldyBVaW50OEFycmF5KHNpemUpKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZpbGxSYW5kb21CeXRlcyhuZXcgVWludDhBcnJheShzaXplKSwgc2l6ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBGaWxsUmFuZG9tQnl0ZXMobmV3IEFycmF5KHNpemUpLCBzaXplKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIENyZWF0ZVVVSUQoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBHZW5SYW5kb21CeXRlcyhVVUlEX1NJWkUpO1xuICAgICAgICAgICAgICAgIC8vIG1hcmsgYXMgcmFuZG9tIC0gUkZDIDQxMjIgwqcgNC40XG4gICAgICAgICAgICAgICAgZGF0YVs2XSA9IGRhdGFbNl0gJiAweDRmIHwgMHg0MDtcbiAgICAgICAgICAgICAgICBkYXRhWzhdID0gZGF0YVs4XSAmIDB4YmYgfCAweDgwO1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBcIlwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIG9mZnNldCA9IDA7IG9mZnNldCA8IFVVSURfU0laRTsgKytvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJ5dGUgPSBkYXRhW29mZnNldF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPT09IDQgfHwgb2Zmc2V0ID09PSA2IHx8IG9mZnNldCA9PT0gOClcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBcIi1cIjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJ5dGUgPCAxNilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSBcIjBcIjtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IGJ5dGUudG9TdHJpbmcoMTYpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gdXNlcyBhIGhldXJpc3RpYyB1c2VkIGJ5IHY4IGFuZCBjaGFrcmEgdG8gZm9yY2UgYW4gb2JqZWN0IGludG8gZGljdGlvbmFyeSBtb2RlLlxuICAgICAgICBmdW5jdGlvbiBNYWtlRGljdGlvbmFyeShvYmopIHtcbiAgICAgICAgICAgIG9iai5fXyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGRlbGV0ZSBvYmouX187XG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9XG4gICAgfSk7XG59KShSZWZsZWN0IHx8IChSZWZsZWN0ID0ge30pKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY21wIChhLCBiKSB7XG4gICAgdmFyIHBhID0gYS5zcGxpdCgnLicpO1xuICAgIHZhciBwYiA9IGIuc3BsaXQoJy4nKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykge1xuICAgICAgICB2YXIgbmEgPSBOdW1iZXIocGFbaV0pO1xuICAgICAgICB2YXIgbmIgPSBOdW1iZXIocGJbaV0pO1xuICAgICAgICBpZiAobmEgPiBuYikgcmV0dXJuIDE7XG4gICAgICAgIGlmIChuYiA+IG5hKSByZXR1cm4gLTE7XG4gICAgICAgIGlmICghaXNOYU4obmEpICYmIGlzTmFOKG5iKSkgcmV0dXJuIDE7XG4gICAgICAgIGlmIChpc05hTihuYSkgJiYgIWlzTmFOKG5iKSkgcmV0dXJuIC0xO1xuICAgIH1cbiAgICByZXR1cm4gMDtcbn07XG4iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBTZW1WZXJcblxudmFyIGRlYnVnXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuaWYgKHR5cGVvZiBwcm9jZXNzID09PSAnb2JqZWN0JyAmJlxuICAgIHByb2Nlc3MuZW52ICYmXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyAmJlxuICAgIC9cXGJzZW12ZXJcXGIvaS50ZXN0KHByb2Nlc3MuZW52Lk5PREVfREVCVUcpKSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKVxuICAgIGFyZ3MudW5zaGlmdCgnU0VNVkVSJylcbiAgICBjb25zb2xlLmxvZy5hcHBseShjb25zb2xlLCBhcmdzKVxuICB9XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9XG59XG5cbi8vIE5vdGU6IHRoaXMgaXMgdGhlIHNlbXZlci5vcmcgdmVyc2lvbiBvZiB0aGUgc3BlYyB0aGF0IGl0IGltcGxlbWVudHNcbi8vIE5vdCBuZWNlc3NhcmlseSB0aGUgcGFja2FnZSB2ZXJzaW9uIG9mIHRoaXMgY29kZS5cbmV4cG9ydHMuU0VNVkVSX1NQRUNfVkVSU0lPTiA9ICcyLjAuMCdcblxudmFyIE1BWF9MRU5HVEggPSAyNTZcbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfHxcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gOTAwNzE5OTI1NDc0MDk5MVxuXG4vLyBNYXggc2FmZSBzZWdtZW50IGxlbmd0aCBmb3IgY29lcmNpb24uXG52YXIgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCA9IDE2XG5cbi8vIFRoZSBhY3R1YWwgcmVnZXhwcyBnbyBvbiBleHBvcnRzLnJlXG52YXIgcmUgPSBleHBvcnRzLnJlID0gW11cbnZhciBzcmMgPSBleHBvcnRzLnNyYyA9IFtdXG52YXIgUiA9IDBcblxuLy8gVGhlIGZvbGxvd2luZyBSZWd1bGFyIEV4cHJlc3Npb25zIGNhbiBiZSB1c2VkIGZvciB0b2tlbml6aW5nLFxuLy8gdmFsaWRhdGluZywgYW5kIHBhcnNpbmcgU2VtVmVyIHZlcnNpb24gc3RyaW5ncy5cblxuLy8gIyMgTnVtZXJpYyBJZGVudGlmaWVyXG4vLyBBIHNpbmdsZSBgMGAsIG9yIGEgbm9uLXplcm8gZGlnaXQgZm9sbG93ZWQgYnkgemVybyBvciBtb3JlIGRpZ2l0cy5cblxudmFyIE5VTUVSSUNJREVOVElGSUVSID0gUisrXG5zcmNbTlVNRVJJQ0lERU5USUZJRVJdID0gJzB8WzEtOV1cXFxcZConXG52YXIgTlVNRVJJQ0lERU5USUZJRVJMT09TRSA9IFIrK1xuc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdID0gJ1swLTldKydcblxuLy8gIyMgTm9uLW51bWVyaWMgSWRlbnRpZmllclxuLy8gWmVybyBvciBtb3JlIGRpZ2l0cywgZm9sbG93ZWQgYnkgYSBsZXR0ZXIgb3IgaHlwaGVuLCBhbmQgdGhlbiB6ZXJvIG9yXG4vLyBtb3JlIGxldHRlcnMsIGRpZ2l0cywgb3IgaHlwaGVucy5cblxudmFyIE5PTk5VTUVSSUNJREVOVElGSUVSID0gUisrXG5zcmNbTk9OTlVNRVJJQ0lERU5USUZJRVJdID0gJ1xcXFxkKlthLXpBLVotXVthLXpBLVowLTktXSonXG5cbi8vICMjIE1haW4gVmVyc2lvblxuLy8gVGhyZWUgZG90LXNlcGFyYXRlZCBudW1lcmljIGlkZW50aWZpZXJzLlxuXG52YXIgTUFJTlZFUlNJT04gPSBSKytcbnNyY1tNQUlOVkVSU0lPTl0gPSAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gKyAnKVxcXFwuJyArXG4gICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSXSArICcpJ1xuXG52YXIgTUFJTlZFUlNJT05MT09TRSA9IFIrK1xuc3JjW01BSU5WRVJTSU9OTE9PU0VdID0gJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJyknXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb24gSWRlbnRpZmllclxuLy8gQSBudW1lcmljIGlkZW50aWZpZXIsIG9yIGEgbm9uLW51bWVyaWMgaWRlbnRpZmllci5cblxudmFyIFBSRVJFTEVBU0VJREVOVElGSUVSID0gUisrXG5zcmNbUFJFUkVMRUFTRUlERU5USUZJRVJdID0gJyg/OicgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnfCcgKyBzcmNbTk9OTlVNRVJJQ0lERU5USUZJRVJdICsgJyknXG5cbnZhciBQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFID0gUisrXG5zcmNbUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV0gPSAnKD86JyArIHNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnfCcgKyBzcmNbTk9OTlVNRVJJQ0lERU5USUZJRVJdICsgJyknXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb25cbi8vIEh5cGhlbiwgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgZG90LXNlcGFyYXRlZCBwcmUtcmVsZWFzZSB2ZXJzaW9uXG4vLyBpZGVudGlmaWVycy5cblxudmFyIFBSRVJFTEVBU0UgPSBSKytcbnNyY1tQUkVSRUxFQVNFXSA9ICcoPzotKCcgKyBzcmNbUFJFUkVMRUFTRUlERU5USUZJRVJdICtcbiAgICAgICAgICAgICAgICAgICcoPzpcXFxcLicgKyBzcmNbUFJFUkVMRUFTRUlERU5USUZJRVJdICsgJykqKSknXG5cbnZhciBQUkVSRUxFQVNFTE9PU0UgPSBSKytcbnNyY1tQUkVSRUxFQVNFTE9PU0VdID0gJyg/Oi0/KCcgKyBzcmNbUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4nICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdICsgJykqKSknXG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhIElkZW50aWZpZXJcbi8vIEFueSBjb21iaW5hdGlvbiBvZiBkaWdpdHMsIGxldHRlcnMsIG9yIGh5cGhlbnMuXG5cbnZhciBCVUlMRElERU5USUZJRVIgPSBSKytcbnNyY1tCVUlMRElERU5USUZJRVJdID0gJ1swLTlBLVphLXotXSsnXG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhXG4vLyBQbHVzIHNpZ24sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIHBlcmlvZC1zZXBhcmF0ZWQgYnVpbGQgbWV0YWRhdGFcbi8vIGlkZW50aWZpZXJzLlxuXG52YXIgQlVJTEQgPSBSKytcbnNyY1tCVUlMRF0gPSAnKD86XFxcXCsoJyArIHNyY1tCVUlMRElERU5USUZJRVJdICtcbiAgICAgICAgICAgICAnKD86XFxcXC4nICsgc3JjW0JVSUxESURFTlRJRklFUl0gKyAnKSopKSdcblxuLy8gIyMgRnVsbCBWZXJzaW9uIFN0cmluZ1xuLy8gQSBtYWluIHZlcnNpb24sIGZvbGxvd2VkIG9wdGlvbmFsbHkgYnkgYSBwcmUtcmVsZWFzZSB2ZXJzaW9uIGFuZFxuLy8gYnVpbGQgbWV0YWRhdGEuXG5cbi8vIE5vdGUgdGhhdCB0aGUgb25seSBtYWpvciwgbWlub3IsIHBhdGNoLCBhbmQgcHJlLXJlbGVhc2Ugc2VjdGlvbnMgb2Zcbi8vIHRoZSB2ZXJzaW9uIHN0cmluZyBhcmUgY2FwdHVyaW5nIGdyb3Vwcy4gIFRoZSBidWlsZCBtZXRhZGF0YSBpcyBub3QgYVxuLy8gY2FwdHVyaW5nIGdyb3VwLCBiZWNhdXNlIGl0IHNob3VsZCBub3QgZXZlciBiZSB1c2VkIGluIHZlcnNpb25cbi8vIGNvbXBhcmlzb24uXG5cbnZhciBGVUxMID0gUisrXG52YXIgRlVMTFBMQUlOID0gJ3Y/JyArIHNyY1tNQUlOVkVSU0lPTl0gK1xuICAgICAgICAgICAgICAgIHNyY1tQUkVSRUxFQVNFXSArICc/JyArXG4gICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/J1xuXG5zcmNbRlVMTF0gPSAnXicgKyBGVUxMUExBSU4gKyAnJCdcblxuLy8gbGlrZSBmdWxsLCBidXQgYWxsb3dzIHYxLjIuMyBhbmQgPTEuMi4zLCB3aGljaCBwZW9wbGUgZG8gc29tZXRpbWVzLlxuLy8gYWxzbywgMS4wLjBhbHBoYTEgKHByZXJlbGVhc2Ugd2l0aG91dCB0aGUgaHlwaGVuKSB3aGljaCBpcyBwcmV0dHlcbi8vIGNvbW1vbiBpbiB0aGUgbnBtIHJlZ2lzdHJ5LlxudmFyIExPT1NFUExBSU4gPSAnW3Y9XFxcXHNdKicgKyBzcmNbTUFJTlZFUlNJT05MT09TRV0gK1xuICAgICAgICAgICAgICAgICBzcmNbUFJFUkVMRUFTRUxPT1NFXSArICc/JyArXG4gICAgICAgICAgICAgICAgIHNyY1tCVUlMRF0gKyAnPydcblxudmFyIExPT1NFID0gUisrXG5zcmNbTE9PU0VdID0gJ14nICsgTE9PU0VQTEFJTiArICckJ1xuXG52YXIgR1RMVCA9IFIrK1xuc3JjW0dUTFRdID0gJygoPzo8fD4pPz0/KSdcblxuLy8gU29tZXRoaW5nIGxpa2UgXCIyLipcIiBvciBcIjEuMi54XCIuXG4vLyBOb3RlIHRoYXQgXCJ4LnhcIiBpcyBhIHZhbGlkIHhSYW5nZSBpZGVudGlmZXIsIG1lYW5pbmcgXCJhbnkgdmVyc2lvblwiXG4vLyBPbmx5IHRoZSBmaXJzdCBpdGVtIGlzIHN0cmljdGx5IHJlcXVpcmVkLlxudmFyIFhSQU5HRUlERU5USUZJRVJMT09TRSA9IFIrK1xuc3JjW1hSQU5HRUlERU5USUZJRVJMT09TRV0gPSBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnfHh8WHxcXFxcKidcbnZhciBYUkFOR0VJREVOVElGSUVSID0gUisrXG5zcmNbWFJBTkdFSURFTlRJRklFUl0gPSBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJ3x4fFh8XFxcXConXG5cbnZhciBYUkFOR0VQTEFJTiA9IFIrK1xuc3JjW1hSQU5HRVBMQUlOXSA9ICdbdj1cXFxcc10qKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1tYUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OicgKyBzcmNbUFJFUkVMRUFTRV0gKyAnKT8nICtcbiAgICAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgICAnKT8pPydcblxudmFyIFhSQU5HRVBMQUlOTE9PU0UgPSBSKytcbnNyY1tYUkFOR0VQTEFJTkxPT1NFXSA9ICdbdj1cXFxcc10qKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1tYUkFOR0VJREVOVElGSUVSTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJMT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OicgKyBzcmNbUFJFUkVMRUFTRUxPT1NFXSArICcpPycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKT8pPydcblxudmFyIFhSQU5HRSA9IFIrK1xuc3JjW1hSQU5HRV0gPSAnXicgKyBzcmNbR1RMVF0gKyAnXFxcXHMqJyArIHNyY1tYUkFOR0VQTEFJTl0gKyAnJCdcbnZhciBYUkFOR0VMT09TRSA9IFIrK1xuc3JjW1hSQU5HRUxPT1NFXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyonICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyQnXG5cbi8vIENvZXJjaW9uLlxuLy8gRXh0cmFjdCBhbnl0aGluZyB0aGF0IGNvdWxkIGNvbmNlaXZhYmx5IGJlIGEgcGFydCBvZiBhIHZhbGlkIHNlbXZlclxudmFyIENPRVJDRSA9IFIrK1xuc3JjW0NPRVJDRV0gPSAnKD86XnxbXlxcXFxkXSknICtcbiAgICAgICAgICAgICAgJyhcXFxcZHsxLCcgKyBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIICsgJ30pJyArXG4gICAgICAgICAgICAgICcoPzpcXFxcLihcXFxcZHsxLCcgKyBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIICsgJ30pKT8nICtcbiAgICAgICAgICAgICAgJyg/OlxcXFwuKFxcXFxkezEsJyArIE1BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEggKyAnfSkpPycgK1xuICAgICAgICAgICAgICAnKD86JHxbXlxcXFxkXSknXG5cbi8vIFRpbGRlIHJhbmdlcy5cbi8vIE1lYW5pbmcgaXMgXCJyZWFzb25hYmx5IGF0IG9yIGdyZWF0ZXIgdGhhblwiXG52YXIgTE9ORVRJTERFID0gUisrXG5zcmNbTE9ORVRJTERFXSA9ICcoPzp+Pj8pJ1xuXG52YXIgVElMREVUUklNID0gUisrXG5zcmNbVElMREVUUklNXSA9ICcoXFxcXHMqKScgKyBzcmNbTE9ORVRJTERFXSArICdcXFxccysnXG5yZVtUSUxERVRSSU1dID0gbmV3IFJlZ0V4cChzcmNbVElMREVUUklNXSwgJ2cnKVxudmFyIHRpbGRlVHJpbVJlcGxhY2UgPSAnJDF+J1xuXG52YXIgVElMREUgPSBSKytcbnNyY1tUSUxERV0gPSAnXicgKyBzcmNbTE9ORVRJTERFXSArIHNyY1tYUkFOR0VQTEFJTl0gKyAnJCdcbnZhciBUSUxERUxPT1NFID0gUisrXG5zcmNbVElMREVMT09TRV0gPSAnXicgKyBzcmNbTE9ORVRJTERFXSArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICckJ1xuXG4vLyBDYXJldCByYW5nZXMuXG4vLyBNZWFuaW5nIGlzIFwiYXQgbGVhc3QgYW5kIGJhY2t3YXJkcyBjb21wYXRpYmxlIHdpdGhcIlxudmFyIExPTkVDQVJFVCA9IFIrK1xuc3JjW0xPTkVDQVJFVF0gPSAnKD86XFxcXF4pJ1xuXG52YXIgQ0FSRVRUUklNID0gUisrXG5zcmNbQ0FSRVRUUklNXSA9ICcoXFxcXHMqKScgKyBzcmNbTE9ORUNBUkVUXSArICdcXFxccysnXG5yZVtDQVJFVFRSSU1dID0gbmV3IFJlZ0V4cChzcmNbQ0FSRVRUUklNXSwgJ2cnKVxudmFyIGNhcmV0VHJpbVJlcGxhY2UgPSAnJDFeJ1xuXG52YXIgQ0FSRVQgPSBSKytcbnNyY1tDQVJFVF0gPSAnXicgKyBzcmNbTE9ORUNBUkVUXSArIHNyY1tYUkFOR0VQTEFJTl0gKyAnJCdcbnZhciBDQVJFVExPT1NFID0gUisrXG5zcmNbQ0FSRVRMT09TRV0gPSAnXicgKyBzcmNbTE9ORUNBUkVUXSArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICckJ1xuXG4vLyBBIHNpbXBsZSBndC9sdC9lcSB0aGluZywgb3IganVzdCBcIlwiIHRvIGluZGljYXRlIFwiYW55IHZlcnNpb25cIlxudmFyIENPTVBBUkFUT1JMT09TRSA9IFIrK1xuc3JjW0NPTVBBUkFUT1JMT09TRV0gPSAnXicgKyBzcmNbR1RMVF0gKyAnXFxcXHMqKCcgKyBMT09TRVBMQUlOICsgJykkfF4kJ1xudmFyIENPTVBBUkFUT1IgPSBSKytcbnNyY1tDT01QQVJBVE9SXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyooJyArIEZVTExQTEFJTiArICcpJHxeJCdcblxuLy8gQW4gZXhwcmVzc2lvbiB0byBzdHJpcCBhbnkgd2hpdGVzcGFjZSBiZXR3ZWVuIHRoZSBndGx0IGFuZCB0aGUgdGhpbmdcbi8vIGl0IG1vZGlmaWVzLCBzbyB0aGF0IGA+IDEuMi4zYCA9PT4gYD4xLjIuM2BcbnZhciBDT01QQVJBVE9SVFJJTSA9IFIrK1xuc3JjW0NPTVBBUkFUT1JUUklNXSA9ICcoXFxcXHMqKScgKyBzcmNbR1RMVF0gK1xuICAgICAgICAgICAgICAgICAgICAgICdcXFxccyooJyArIExPT1NFUExBSU4gKyAnfCcgKyBzcmNbWFJBTkdFUExBSU5dICsgJyknXG5cbi8vIHRoaXMgb25lIGhhcyB0byB1c2UgdGhlIC9nIGZsYWdcbnJlW0NPTVBBUkFUT1JUUklNXSA9IG5ldyBSZWdFeHAoc3JjW0NPTVBBUkFUT1JUUklNXSwgJ2cnKVxudmFyIGNvbXBhcmF0b3JUcmltUmVwbGFjZSA9ICckMSQyJDMnXG5cbi8vIFNvbWV0aGluZyBsaWtlIGAxLjIuMyAtIDEuMi40YFxuLy8gTm90ZSB0aGF0IHRoZXNlIGFsbCB1c2UgdGhlIGxvb3NlIGZvcm0sIGJlY2F1c2UgdGhleSdsbCBiZVxuLy8gY2hlY2tlZCBhZ2FpbnN0IGVpdGhlciB0aGUgc3RyaWN0IG9yIGxvb3NlIGNvbXBhcmF0b3IgZm9ybVxuLy8gbGF0ZXIuXG52YXIgSFlQSEVOUkFOR0UgPSBSKytcbnNyY1tIWVBIRU5SQU5HRV0gPSAnXlxcXFxzKignICsgc3JjW1hSQU5HRVBMQUlOXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJ1xcXFxzKy1cXFxccysnICtcbiAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbWFJBTkdFUExBSU5dICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnXFxcXHMqJCdcblxudmFyIEhZUEhFTlJBTkdFTE9PU0UgPSBSKytcbnNyY1tIWVBIRU5SQU5HRUxPT1NFXSA9ICdeXFxcXHMqKCcgKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1xcXFxzKy1cXFxccysnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMqJCdcblxuLy8gU3RhciByYW5nZXMgYmFzaWNhbGx5IGp1c3QgYWxsb3cgYW55dGhpbmcgYXQgYWxsLlxudmFyIFNUQVIgPSBSKytcbnNyY1tTVEFSXSA9ICcoPHw+KT89P1xcXFxzKlxcXFwqJ1xuXG4vLyBDb21waWxlIHRvIGFjdHVhbCByZWdleHAgb2JqZWN0cy5cbi8vIEFsbCBhcmUgZmxhZy1mcmVlLCB1bmxlc3MgdGhleSB3ZXJlIGNyZWF0ZWQgYWJvdmUgd2l0aCBhIGZsYWcuXG5mb3IgKHZhciBpID0gMDsgaSA8IFI7IGkrKykge1xuICBkZWJ1ZyhpLCBzcmNbaV0pXG4gIGlmICghcmVbaV0pIHtcbiAgICByZVtpXSA9IG5ldyBSZWdFeHAoc3JjW2ldKVxuICB9XG59XG5cbmV4cG9ydHMucGFyc2UgPSBwYXJzZVxuZnVuY3Rpb24gcGFyc2UgKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICBsb29zZTogISFvcHRpb25zLFxuICAgICAgaW5jbHVkZVByZXJlbGVhc2U6IGZhbHNlXG4gICAgfVxuICB9XG5cbiAgaWYgKHZlcnNpb24gaW5zdGFuY2VvZiBTZW1WZXIpIHtcbiAgICByZXR1cm4gdmVyc2lvblxuICB9XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBpZiAodmVyc2lvbi5sZW5ndGggPiBNQVhfTEVOR1RIKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIHZhciByID0gb3B0aW9ucy5sb29zZSA/IHJlW0xPT1NFXSA6IHJlW0ZVTExdXG4gIGlmICghci50ZXN0KHZlcnNpb24pKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBTZW1WZXIodmVyc2lvbiwgb3B0aW9ucylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbmV4cG9ydHMudmFsaWQgPSB2YWxpZFxuZnVuY3Rpb24gdmFsaWQgKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgdmFyIHYgPSBwYXJzZSh2ZXJzaW9uLCBvcHRpb25zKVxuICByZXR1cm4gdiA/IHYudmVyc2lvbiA6IG51bGxcbn1cblxuZXhwb3J0cy5jbGVhbiA9IGNsZWFuXG5mdW5jdGlvbiBjbGVhbiAodmVyc2lvbiwgb3B0aW9ucykge1xuICB2YXIgcyA9IHBhcnNlKHZlcnNpb24udHJpbSgpLnJlcGxhY2UoL15bPXZdKy8sICcnKSwgb3B0aW9ucylcbiAgcmV0dXJuIHMgPyBzLnZlcnNpb24gOiBudWxsXG59XG5cbmV4cG9ydHMuU2VtVmVyID0gU2VtVmVyXG5cbmZ1bmN0aW9uIFNlbVZlciAodmVyc2lvbiwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGxvb3NlOiAhIW9wdGlvbnMsXG4gICAgICBpbmNsdWRlUHJlcmVsZWFzZTogZmFsc2VcbiAgICB9XG4gIH1cbiAgaWYgKHZlcnNpb24gaW5zdGFuY2VvZiBTZW1WZXIpIHtcbiAgICBpZiAodmVyc2lvbi5sb29zZSA9PT0gb3B0aW9ucy5sb29zZSkge1xuICAgICAgcmV0dXJuIHZlcnNpb25cbiAgICB9IGVsc2Uge1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24udmVyc2lvblxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmVyc2lvbiAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIFZlcnNpb246ICcgKyB2ZXJzaW9uKVxuICB9XG5cbiAgaWYgKHZlcnNpb24ubGVuZ3RoID4gTUFYX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZlcnNpb24gaXMgbG9uZ2VyIHRoYW4gJyArIE1BWF9MRU5HVEggKyAnIGNoYXJhY3RlcnMnKVxuICB9XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICByZXR1cm4gbmV3IFNlbVZlcih2ZXJzaW9uLCBvcHRpb25zKVxuICB9XG5cbiAgZGVidWcoJ1NlbVZlcicsIHZlcnNpb24sIG9wdGlvbnMpXG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnNcbiAgdGhpcy5sb29zZSA9ICEhb3B0aW9ucy5sb29zZVxuXG4gIHZhciBtID0gdmVyc2lvbi50cmltKCkubWF0Y2gob3B0aW9ucy5sb29zZSA/IHJlW0xPT1NFXSA6IHJlW0ZVTExdKVxuXG4gIGlmICghbSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgVmVyc2lvbjogJyArIHZlcnNpb24pXG4gIH1cblxuICB0aGlzLnJhdyA9IHZlcnNpb25cblxuICAvLyB0aGVzZSBhcmUgYWN0dWFsbHkgbnVtYmVyc1xuICB0aGlzLm1ham9yID0gK21bMV1cbiAgdGhpcy5taW5vciA9ICttWzJdXG4gIHRoaXMucGF0Y2ggPSArbVszXVxuXG4gIGlmICh0aGlzLm1ham9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1ham9yIDwgMCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbWFqb3IgdmVyc2lvbicpXG4gIH1cblxuICBpZiAodGhpcy5taW5vciA+IE1BWF9TQUZFX0lOVEVHRVIgfHwgdGhpcy5taW5vciA8IDApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1pbm9yIHZlcnNpb24nKVxuICB9XG5cbiAgaWYgKHRoaXMucGF0Y2ggPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMucGF0Y2ggPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBwYXRjaCB2ZXJzaW9uJylcbiAgfVxuXG4gIC8vIG51bWJlcmlmeSBhbnkgcHJlcmVsZWFzZSBudW1lcmljIGlkc1xuICBpZiAoIW1bNF0pIHtcbiAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICB9IGVsc2Uge1xuICAgIHRoaXMucHJlcmVsZWFzZSA9IG1bNF0uc3BsaXQoJy4nKS5tYXAoZnVuY3Rpb24gKGlkKSB7XG4gICAgICBpZiAoL15bMC05XSskLy50ZXN0KGlkKSkge1xuICAgICAgICB2YXIgbnVtID0gK2lkXG4gICAgICAgIGlmIChudW0gPj0gMCAmJiBudW0gPCBNQVhfU0FGRV9JTlRFR0VSKSB7XG4gICAgICAgICAgcmV0dXJuIG51bVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaWRcbiAgICB9KVxuICB9XG5cbiAgdGhpcy5idWlsZCA9IG1bNV0gPyBtWzVdLnNwbGl0KCcuJykgOiBbXVxuICB0aGlzLmZvcm1hdCgpXG59XG5cblNlbVZlci5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnZlcnNpb24gPSB0aGlzLm1ham9yICsgJy4nICsgdGhpcy5taW5vciArICcuJyArIHRoaXMucGF0Y2hcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICB0aGlzLnZlcnNpb24gKz0gJy0nICsgdGhpcy5wcmVyZWxlYXNlLmpvaW4oJy4nKVxuICB9XG4gIHJldHVybiB0aGlzLnZlcnNpb25cbn1cblxuU2VtVmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMudmVyc2lvblxufVxuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgZGVidWcoJ1NlbVZlci5jb21wYXJlJywgdGhpcy52ZXJzaW9uLCB0aGlzLm9wdGlvbnMsIG90aGVyKVxuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgfVxuXG4gIHJldHVybiB0aGlzLmNvbXBhcmVNYWluKG90aGVyKSB8fCB0aGlzLmNvbXBhcmVQcmUob3RoZXIpXG59XG5cblNlbVZlci5wcm90b3R5cGUuY29tcGFyZU1haW4gPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gIH1cblxuICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKHRoaXMubWFqb3IsIG90aGVyLm1ham9yKSB8fFxuICAgICAgICAgY29tcGFyZUlkZW50aWZpZXJzKHRoaXMubWlub3IsIG90aGVyLm1pbm9yKSB8fFxuICAgICAgICAgY29tcGFyZUlkZW50aWZpZXJzKHRoaXMucGF0Y2gsIG90aGVyLnBhdGNoKVxufVxuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmVQcmUgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gIH1cblxuICAvLyBOT1QgaGF2aW5nIGEgcHJlcmVsZWFzZSBpcyA+IGhhdmluZyBvbmVcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xXG4gIH0gZWxzZSBpZiAoIXRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gMVxuICB9IGVsc2UgaWYgKCF0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmICFvdGhlci5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgIHJldHVybiAwXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgZG8ge1xuICAgIHZhciBhID0gdGhpcy5wcmVyZWxlYXNlW2ldXG4gICAgdmFyIGIgPSBvdGhlci5wcmVyZWxlYXNlW2ldXG4gICAgZGVidWcoJ3ByZXJlbGVhc2UgY29tcGFyZScsIGksIGEsIGIpXG4gICAgaWYgKGEgPT09IHVuZGVmaW5lZCAmJiBiID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAwXG4gICAgfSBlbHNlIGlmIChiID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAxXG4gICAgfSBlbHNlIGlmIChhID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH0gZWxzZSBpZiAoYSA9PT0gYikge1xuICAgICAgY29udGludWVcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyhhLCBiKVxuICAgIH1cbiAgfSB3aGlsZSAoKytpKVxufVxuXG4vLyBwcmVtaW5vciB3aWxsIGJ1bXAgdGhlIHZlcnNpb24gdXAgdG8gdGhlIG5leHQgbWlub3IgcmVsZWFzZSwgYW5kIGltbWVkaWF0ZWx5XG4vLyBkb3duIHRvIHByZS1yZWxlYXNlLiBwcmVtYWpvciBhbmQgcHJlcGF0Y2ggd29yayB0aGUgc2FtZSB3YXkuXG5TZW1WZXIucHJvdG90eXBlLmluYyA9IGZ1bmN0aW9uIChyZWxlYXNlLCBpZGVudGlmaWVyKSB7XG4gIHN3aXRjaCAocmVsZWFzZSkge1xuICAgIGNhc2UgJ3ByZW1ham9yJzpcbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwXG4gICAgICB0aGlzLnBhdGNoID0gMFxuICAgICAgdGhpcy5taW5vciA9IDBcbiAgICAgIHRoaXMubWFqb3IrK1xuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3ByZW1pbm9yJzpcbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwXG4gICAgICB0aGlzLnBhdGNoID0gMFxuICAgICAgdGhpcy5taW5vcisrXG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAncHJlcGF0Y2gnOlxuICAgICAgLy8gSWYgdGhpcyBpcyBhbHJlYWR5IGEgcHJlcmVsZWFzZSwgaXQgd2lsbCBidW1wIHRvIHRoZSBuZXh0IHZlcnNpb25cbiAgICAgIC8vIGRyb3AgYW55IHByZXJlbGVhc2VzIHRoYXQgbWlnaHQgYWxyZWFkeSBleGlzdCwgc2luY2UgdGhleSBhcmUgbm90XG4gICAgICAvLyByZWxldmFudCBhdCB0aGlzIHBvaW50LlxuICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9IDBcbiAgICAgIHRoaXMuaW5jKCdwYXRjaCcsIGlkZW50aWZpZXIpXG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgIGJyZWFrXG4gICAgLy8gSWYgdGhlIGlucHV0IGlzIGEgbm9uLXByZXJlbGVhc2UgdmVyc2lvbiwgdGhpcyBhY3RzIHRoZSBzYW1lIGFzXG4gICAgLy8gcHJlcGF0Y2guXG4gICAgY2FzZSAncHJlcmVsZWFzZSc6XG4gICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLmluYygncGF0Y2gnLCBpZGVudGlmaWVyKVxuICAgICAgfVxuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICBicmVha1xuXG4gICAgY2FzZSAnbWFqb3InOlxuICAgICAgLy8gSWYgdGhpcyBpcyBhIHByZS1tYWpvciB2ZXJzaW9uLCBidW1wIHVwIHRvIHRoZSBzYW1lIG1ham9yIHZlcnNpb24uXG4gICAgICAvLyBPdGhlcndpc2UgaW5jcmVtZW50IG1ham9yLlxuICAgICAgLy8gMS4wLjAtNSBidW1wcyB0byAxLjAuMFxuICAgICAgLy8gMS4xLjAgYnVtcHMgdG8gMi4wLjBcbiAgICAgIGlmICh0aGlzLm1pbm9yICE9PSAwIHx8XG4gICAgICAgICAgdGhpcy5wYXRjaCAhPT0gMCB8fFxuICAgICAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5tYWpvcisrXG4gICAgICB9XG4gICAgICB0aGlzLm1pbm9yID0gMFxuICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgICBicmVha1xuICAgIGNhc2UgJ21pbm9yJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWlub3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtaW5vciB2ZXJzaW9uLlxuICAgICAgLy8gT3RoZXJ3aXNlIGluY3JlbWVudCBtaW5vci5cbiAgICAgIC8vIDEuMi4wLTUgYnVtcHMgdG8gMS4yLjBcbiAgICAgIC8vIDEuMi4xIGJ1bXBzIHRvIDEuMy4wXG4gICAgICBpZiAodGhpcy5wYXRjaCAhPT0gMCB8fCB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMubWlub3IrK1xuICAgICAgfVxuICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3BhdGNoJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgbm90IGEgcHJlLXJlbGVhc2UgdmVyc2lvbiwgaXQgd2lsbCBpbmNyZW1lbnQgdGhlIHBhdGNoLlxuICAgICAgLy8gSWYgaXQgaXMgYSBwcmUtcmVsZWFzZSBpdCB3aWxsIGJ1bXAgdXAgdG8gdGhlIHNhbWUgcGF0Y2ggdmVyc2lvbi5cbiAgICAgIC8vIDEuMi4wLTUgcGF0Y2hlcyB0byAxLjIuMFxuICAgICAgLy8gMS4yLjAgcGF0Y2hlcyB0byAxLjIuMVxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5wYXRjaCsrXG4gICAgICB9XG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICAgICAgYnJlYWtcbiAgICAvLyBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSB1c2VkIHB1YmxpY2x5LlxuICAgIC8vIDEuMC4wIFwicHJlXCIgd291bGQgYmVjb21lIDEuMC4wLTAgd2hpY2ggaXMgdGhlIHdyb25nIGRpcmVjdGlvbi5cbiAgICBjYXNlICdwcmUnOlxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gWzBdXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaSA9IHRoaXMucHJlcmVsZWFzZS5sZW5ndGhcbiAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnByZXJlbGVhc2VbaV0gPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICB0aGlzLnByZXJlbGVhc2VbaV0rK1xuICAgICAgICAgICAgaSA9IC0yXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSAtMSkge1xuICAgICAgICAgIC8vIGRpZG4ndCBpbmNyZW1lbnQgYW55dGhpbmdcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UucHVzaCgwKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaWRlbnRpZmllcikge1xuICAgICAgICAvLyAxLjIuMC1iZXRhLjEgYnVtcHMgdG8gMS4yLjAtYmV0YS4yLFxuICAgICAgICAvLyAxLjIuMC1iZXRhLmZvb2JseiBvciAxLjIuMC1iZXRhIGJ1bXBzIHRvIDEuMi4wLWJldGEuMFxuICAgICAgICBpZiAodGhpcy5wcmVyZWxlYXNlWzBdID09PSBpZGVudGlmaWVyKSB7XG4gICAgICAgICAgaWYgKGlzTmFOKHRoaXMucHJlcmVsZWFzZVsxXSkpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtpZGVudGlmaWVyLCAwXVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbaWRlbnRpZmllciwgMF1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYnJlYWtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5jcmVtZW50IGFyZ3VtZW50OiAnICsgcmVsZWFzZSlcbiAgfVxuICB0aGlzLmZvcm1hdCgpXG4gIHRoaXMucmF3ID0gdGhpcy52ZXJzaW9uXG4gIHJldHVybiB0aGlzXG59XG5cbmV4cG9ydHMuaW5jID0gaW5jXG5mdW5jdGlvbiBpbmMgKHZlcnNpb24sIHJlbGVhc2UsIGxvb3NlLCBpZGVudGlmaWVyKSB7XG4gIGlmICh0eXBlb2YgKGxvb3NlKSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZGVudGlmaWVyID0gbG9vc2VcbiAgICBsb29zZSA9IHVuZGVmaW5lZFxuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gbmV3IFNlbVZlcih2ZXJzaW9uLCBsb29zZSkuaW5jKHJlbGVhc2UsIGlkZW50aWZpZXIpLnZlcnNpb25cbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbmV4cG9ydHMuZGlmZiA9IGRpZmZcbmZ1bmN0aW9uIGRpZmYgKHZlcnNpb24xLCB2ZXJzaW9uMikge1xuICBpZiAoZXEodmVyc2lvbjEsIHZlcnNpb24yKSkge1xuICAgIHJldHVybiBudWxsXG4gIH0gZWxzZSB7XG4gICAgdmFyIHYxID0gcGFyc2UodmVyc2lvbjEpXG4gICAgdmFyIHYyID0gcGFyc2UodmVyc2lvbjIpXG4gICAgdmFyIHByZWZpeCA9ICcnXG4gICAgaWYgKHYxLnByZXJlbGVhc2UubGVuZ3RoIHx8IHYyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgICBwcmVmaXggPSAncHJlJ1xuICAgICAgdmFyIGRlZmF1bHRSZXN1bHQgPSAncHJlcmVsZWFzZSdcbiAgICB9XG4gICAgZm9yICh2YXIga2V5IGluIHYxKSB7XG4gICAgICBpZiAoa2V5ID09PSAnbWFqb3InIHx8IGtleSA9PT0gJ21pbm9yJyB8fCBrZXkgPT09ICdwYXRjaCcpIHtcbiAgICAgICAgaWYgKHYxW2tleV0gIT09IHYyW2tleV0pIHtcbiAgICAgICAgICByZXR1cm4gcHJlZml4ICsga2V5XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlZmF1bHRSZXN1bHQgLy8gbWF5IGJlIHVuZGVmaW5lZFxuICB9XG59XG5cbmV4cG9ydHMuY29tcGFyZUlkZW50aWZpZXJzID0gY29tcGFyZUlkZW50aWZpZXJzXG5cbnZhciBudW1lcmljID0gL15bMC05XSskL1xuZnVuY3Rpb24gY29tcGFyZUlkZW50aWZpZXJzIChhLCBiKSB7XG4gIHZhciBhbnVtID0gbnVtZXJpYy50ZXN0KGEpXG4gIHZhciBibnVtID0gbnVtZXJpYy50ZXN0KGIpXG5cbiAgaWYgKGFudW0gJiYgYm51bSkge1xuICAgIGEgPSArYVxuICAgIGIgPSArYlxuICB9XG5cbiAgcmV0dXJuIGEgPT09IGIgPyAwXG4gICAgOiAoYW51bSAmJiAhYm51bSkgPyAtMVxuICAgIDogKGJudW0gJiYgIWFudW0pID8gMVxuICAgIDogYSA8IGIgPyAtMVxuICAgIDogMVxufVxuXG5leHBvcnRzLnJjb21wYXJlSWRlbnRpZmllcnMgPSByY29tcGFyZUlkZW50aWZpZXJzXG5mdW5jdGlvbiByY29tcGFyZUlkZW50aWZpZXJzIChhLCBiKSB7XG4gIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnMoYiwgYSlcbn1cblxuZXhwb3J0cy5tYWpvciA9IG1ham9yXG5mdW5jdGlvbiBtYWpvciAoYSwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLm1ham9yXG59XG5cbmV4cG9ydHMubWlub3IgPSBtaW5vclxuZnVuY3Rpb24gbWlub3IgKGEsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5taW5vclxufVxuXG5leHBvcnRzLnBhdGNoID0gcGF0Y2hcbmZ1bmN0aW9uIHBhdGNoIChhLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkucGF0Y2hcbn1cblxuZXhwb3J0cy5jb21wYXJlID0gY29tcGFyZVxuZnVuY3Rpb24gY29tcGFyZSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLmNvbXBhcmUobmV3IFNlbVZlcihiLCBsb29zZSkpXG59XG5cbmV4cG9ydHMuY29tcGFyZUxvb3NlID0gY29tcGFyZUxvb3NlXG5mdW5jdGlvbiBjb21wYXJlTG9vc2UgKGEsIGIpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgdHJ1ZSlcbn1cblxuZXhwb3J0cy5yY29tcGFyZSA9IHJjb21wYXJlXG5mdW5jdGlvbiByY29tcGFyZSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYiwgYSwgbG9vc2UpXG59XG5cbmV4cG9ydHMuc29ydCA9IHNvcnRcbmZ1bmN0aW9uIHNvcnQgKGxpc3QsIGxvb3NlKSB7XG4gIHJldHVybiBsaXN0LnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5jb21wYXJlKGEsIGIsIGxvb3NlKVxuICB9KVxufVxuXG5leHBvcnRzLnJzb3J0ID0gcnNvcnRcbmZ1bmN0aW9uIHJzb3J0IChsaXN0LCBsb29zZSkge1xuICByZXR1cm4gbGlzdC5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGV4cG9ydHMucmNvbXBhcmUoYSwgYiwgbG9vc2UpXG4gIH0pXG59XG5cbmV4cG9ydHMuZ3QgPSBndFxuZnVuY3Rpb24gZ3QgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA+IDBcbn1cblxuZXhwb3J0cy5sdCA9IGx0XG5mdW5jdGlvbiBsdCAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpIDwgMFxufVxuXG5leHBvcnRzLmVxID0gZXFcbmZ1bmN0aW9uIGVxIChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPT09IDBcbn1cblxuZXhwb3J0cy5uZXEgPSBuZXFcbmZ1bmN0aW9uIG5lcSAoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpICE9PSAwXG59XG5cbmV4cG9ydHMuZ3RlID0gZ3RlXG5mdW5jdGlvbiBndGUgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA+PSAwXG59XG5cbmV4cG9ydHMubHRlID0gbHRlXG5mdW5jdGlvbiBsdGUgKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA8PSAwXG59XG5cbmV4cG9ydHMuY21wID0gY21wXG5mdW5jdGlvbiBjbXAgKGEsIG9wLCBiLCBsb29zZSkge1xuICBzd2l0Y2ggKG9wKSB7XG4gICAgY2FzZSAnPT09JzpcbiAgICAgIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpXG4gICAgICAgIGEgPSBhLnZlcnNpb25cbiAgICAgIGlmICh0eXBlb2YgYiA9PT0gJ29iamVjdCcpXG4gICAgICAgIGIgPSBiLnZlcnNpb25cbiAgICAgIHJldHVybiBhID09PSBiXG5cbiAgICBjYXNlICchPT0nOlxuICAgICAgaWYgKHR5cGVvZiBhID09PSAnb2JqZWN0JylcbiAgICAgICAgYSA9IGEudmVyc2lvblxuICAgICAgaWYgKHR5cGVvZiBiID09PSAnb2JqZWN0JylcbiAgICAgICAgYiA9IGIudmVyc2lvblxuICAgICAgcmV0dXJuIGEgIT09IGJcblxuICAgIGNhc2UgJyc6XG4gICAgY2FzZSAnPSc6XG4gICAgY2FzZSAnPT0nOlxuICAgICAgcmV0dXJuIGVxKGEsIGIsIGxvb3NlKVxuXG4gICAgY2FzZSAnIT0nOlxuICAgICAgcmV0dXJuIG5lcShhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJz4nOlxuICAgICAgcmV0dXJuIGd0KGEsIGIsIGxvb3NlKVxuXG4gICAgY2FzZSAnPj0nOlxuICAgICAgcmV0dXJuIGd0ZShhLCBiLCBsb29zZSlcblxuICAgIGNhc2UgJzwnOlxuICAgICAgcmV0dXJuIGx0KGEsIGIsIGxvb3NlKVxuXG4gICAgY2FzZSAnPD0nOlxuICAgICAgcmV0dXJuIGx0ZShhLCBiLCBsb29zZSlcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG9wZXJhdG9yOiAnICsgb3ApXG4gIH1cbn1cblxuZXhwb3J0cy5Db21wYXJhdG9yID0gQ29tcGFyYXRvclxuZnVuY3Rpb24gQ29tcGFyYXRvciAoY29tcCwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGxvb3NlOiAhIW9wdGlvbnMsXG4gICAgICBpbmNsdWRlUHJlcmVsZWFzZTogZmFsc2VcbiAgICB9XG4gIH1cblxuICBpZiAoY29tcCBpbnN0YW5jZW9mIENvbXBhcmF0b3IpIHtcbiAgICBpZiAoY29tcC5sb29zZSA9PT0gISFvcHRpb25zLmxvb3NlKSB7XG4gICAgICByZXR1cm4gY29tcFxuICAgIH0gZWxzZSB7XG4gICAgICBjb21wID0gY29tcC52YWx1ZVxuICAgIH1cbiAgfVxuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDb21wYXJhdG9yKSkge1xuICAgIHJldHVybiBuZXcgQ29tcGFyYXRvcihjb21wLCBvcHRpb25zKVxuICB9XG5cbiAgZGVidWcoJ2NvbXBhcmF0b3InLCBjb21wLCBvcHRpb25zKVxuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gIHRoaXMubG9vc2UgPSAhIW9wdGlvbnMubG9vc2VcbiAgdGhpcy5wYXJzZShjb21wKVxuXG4gIGlmICh0aGlzLnNlbXZlciA9PT0gQU5ZKSB7XG4gICAgdGhpcy52YWx1ZSA9ICcnXG4gIH0gZWxzZSB7XG4gICAgdGhpcy52YWx1ZSA9IHRoaXMub3BlcmF0b3IgKyB0aGlzLnNlbXZlci52ZXJzaW9uXG4gIH1cblxuICBkZWJ1ZygnY29tcCcsIHRoaXMpXG59XG5cbnZhciBBTlkgPSB7fVxuQ29tcGFyYXRvci5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAoY29tcCkge1xuICB2YXIgciA9IHRoaXMub3B0aW9ucy5sb29zZSA/IHJlW0NPTVBBUkFUT1JMT09TRV0gOiByZVtDT01QQVJBVE9SXVxuICB2YXIgbSA9IGNvbXAubWF0Y2gocilcblxuICBpZiAoIW0pIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGNvbXBhcmF0b3I6ICcgKyBjb21wKVxuICB9XG5cbiAgdGhpcy5vcGVyYXRvciA9IG1bMV1cbiAgaWYgKHRoaXMub3BlcmF0b3IgPT09ICc9Jykge1xuICAgIHRoaXMub3BlcmF0b3IgPSAnJ1xuICB9XG5cbiAgLy8gaWYgaXQgbGl0ZXJhbGx5IGlzIGp1c3QgJz4nIG9yICcnIHRoZW4gYWxsb3cgYW55dGhpbmcuXG4gIGlmICghbVsyXSkge1xuICAgIHRoaXMuc2VtdmVyID0gQU5ZXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5zZW12ZXIgPSBuZXcgU2VtVmVyKG1bMl0sIHRoaXMub3B0aW9ucy5sb29zZSlcbiAgfVxufVxuXG5Db21wYXJhdG9yLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMudmFsdWVcbn1cblxuQ29tcGFyYXRvci5wcm90b3R5cGUudGVzdCA9IGZ1bmN0aW9uICh2ZXJzaW9uKSB7XG4gIGRlYnVnKCdDb21wYXJhdG9yLnRlc3QnLCB2ZXJzaW9uLCB0aGlzLm9wdGlvbnMubG9vc2UpXG5cbiAgaWYgKHRoaXMuc2VtdmVyID09PSBBTlkpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uID09PSAnc3RyaW5nJykge1xuICAgIHZlcnNpb24gPSBuZXcgU2VtVmVyKHZlcnNpb24sIHRoaXMub3B0aW9ucylcbiAgfVxuXG4gIHJldHVybiBjbXAodmVyc2lvbiwgdGhpcy5vcGVyYXRvciwgdGhpcy5zZW12ZXIsIHRoaXMub3B0aW9ucylcbn1cblxuQ29tcGFyYXRvci5wcm90b3R5cGUuaW50ZXJzZWN0cyA9IGZ1bmN0aW9uIChjb21wLCBvcHRpb25zKSB7XG4gIGlmICghKGNvbXAgaW5zdGFuY2VvZiBDb21wYXJhdG9yKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2EgQ29tcGFyYXRvciBpcyByZXF1aXJlZCcpXG4gIH1cblxuICBpZiAoIW9wdGlvbnMgfHwgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGxvb3NlOiAhIW9wdGlvbnMsXG4gICAgICBpbmNsdWRlUHJlcmVsZWFzZTogZmFsc2VcbiAgICB9XG4gIH1cblxuICB2YXIgcmFuZ2VUbXBcblxuICBpZiAodGhpcy5vcGVyYXRvciA9PT0gJycpIHtcbiAgICByYW5nZVRtcCA9IG5ldyBSYW5nZShjb21wLnZhbHVlLCBvcHRpb25zKVxuICAgIHJldHVybiBzYXRpc2ZpZXModGhpcy52YWx1ZSwgcmFuZ2VUbXAsIG9wdGlvbnMpXG4gIH0gZWxzZSBpZiAoY29tcC5vcGVyYXRvciA9PT0gJycpIHtcbiAgICByYW5nZVRtcCA9IG5ldyBSYW5nZSh0aGlzLnZhbHVlLCBvcHRpb25zKVxuICAgIHJldHVybiBzYXRpc2ZpZXMoY29tcC5zZW12ZXIsIHJhbmdlVG1wLCBvcHRpb25zKVxuICB9XG5cbiAgdmFyIHNhbWVEaXJlY3Rpb25JbmNyZWFzaW5nID1cbiAgICAodGhpcy5vcGVyYXRvciA9PT0gJz49JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPicpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc+PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJz4nKVxuICB2YXIgc2FtZURpcmVjdGlvbkRlY3JlYXNpbmcgPVxuICAgICh0aGlzLm9wZXJhdG9yID09PSAnPD0nIHx8IHRoaXMub3BlcmF0b3IgPT09ICc8JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJzw9JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPCcpXG4gIHZhciBzYW1lU2VtVmVyID0gdGhpcy5zZW12ZXIudmVyc2lvbiA9PT0gY29tcC5zZW12ZXIudmVyc2lvblxuICB2YXIgZGlmZmVyZW50RGlyZWN0aW9uc0luY2x1c2l2ZSA9XG4gICAgKHRoaXMub3BlcmF0b3IgPT09ICc+PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJzw9JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJz49JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPD0nKVxuICB2YXIgb3Bwb3NpdGVEaXJlY3Rpb25zTGVzc1RoYW4gPVxuICAgIGNtcCh0aGlzLnNlbXZlciwgJzwnLCBjb21wLnNlbXZlciwgb3B0aW9ucykgJiZcbiAgICAoKHRoaXMub3BlcmF0b3IgPT09ICc+PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJz4nKSAmJlxuICAgIChjb21wLm9wZXJhdG9yID09PSAnPD0nIHx8IGNvbXAub3BlcmF0b3IgPT09ICc8JykpXG4gIHZhciBvcHBvc2l0ZURpcmVjdGlvbnNHcmVhdGVyVGhhbiA9XG4gICAgY21wKHRoaXMuc2VtdmVyLCAnPicsIGNvbXAuc2VtdmVyLCBvcHRpb25zKSAmJlxuICAgICgodGhpcy5vcGVyYXRvciA9PT0gJzw9JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPCcpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc+PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJz4nKSlcblxuICByZXR1cm4gc2FtZURpcmVjdGlvbkluY3JlYXNpbmcgfHwgc2FtZURpcmVjdGlvbkRlY3JlYXNpbmcgfHxcbiAgICAoc2FtZVNlbVZlciAmJiBkaWZmZXJlbnREaXJlY3Rpb25zSW5jbHVzaXZlKSB8fFxuICAgIG9wcG9zaXRlRGlyZWN0aW9uc0xlc3NUaGFuIHx8IG9wcG9zaXRlRGlyZWN0aW9uc0dyZWF0ZXJUaGFuXG59XG5cbmV4cG9ydHMuUmFuZ2UgPSBSYW5nZVxuZnVuY3Rpb24gUmFuZ2UgKHJhbmdlLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucyB8fCB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbG9vc2U6ICEhb3B0aW9ucyxcbiAgICAgIGluY2x1ZGVQcmVyZWxlYXNlOiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGlmIChyYW5nZSBpbnN0YW5jZW9mIFJhbmdlKSB7XG4gICAgaWYgKHJhbmdlLmxvb3NlID09PSAhIW9wdGlvbnMubG9vc2UgJiZcbiAgICAgICAgcmFuZ2UuaW5jbHVkZVByZXJlbGVhc2UgPT09ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZSkge1xuICAgICAgcmV0dXJuIHJhbmdlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UucmF3LCBvcHRpb25zKVxuICAgIH1cbiAgfVxuXG4gIGlmIChyYW5nZSBpbnN0YW5jZW9mIENvbXBhcmF0b3IpIHtcbiAgICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLnZhbHVlLCBvcHRpb25zKVxuICB9XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJhbmdlKSkge1xuICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpXG4gIH1cblxuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gIHRoaXMubG9vc2UgPSAhIW9wdGlvbnMubG9vc2VcbiAgdGhpcy5pbmNsdWRlUHJlcmVsZWFzZSA9ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZVxuXG4gIC8vIEZpcnN0LCBzcGxpdCBiYXNlZCBvbiBib29sZWFuIG9yIHx8XG4gIHRoaXMucmF3ID0gcmFuZ2VcbiAgdGhpcy5zZXQgPSByYW5nZS5zcGxpdCgvXFxzKlxcfFxcfFxccyovKS5tYXAoZnVuY3Rpb24gKHJhbmdlKSB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VSYW5nZShyYW5nZS50cmltKCkpXG4gIH0sIHRoaXMpLmZpbHRlcihmdW5jdGlvbiAoYykge1xuICAgIC8vIHRocm93IG91dCBhbnkgdGhhdCBhcmUgbm90IHJlbGV2YW50IGZvciB3aGF0ZXZlciByZWFzb25cbiAgICByZXR1cm4gYy5sZW5ndGhcbiAgfSlcblxuICBpZiAoIXRoaXMuc2V0Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgU2VtVmVyIFJhbmdlOiAnICsgcmFuZ2UpXG4gIH1cblxuICB0aGlzLmZvcm1hdCgpXG59XG5cblJhbmdlLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMucmFuZ2UgPSB0aGlzLnNldC5tYXAoZnVuY3Rpb24gKGNvbXBzKSB7XG4gICAgcmV0dXJuIGNvbXBzLmpvaW4oJyAnKS50cmltKClcbiAgfSkuam9pbignfHwnKS50cmltKClcbiAgcmV0dXJuIHRoaXMucmFuZ2Vcbn1cblxuUmFuZ2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5yYW5nZVxufVxuXG5SYW5nZS5wcm90b3R5cGUucGFyc2VSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkge1xuICB2YXIgbG9vc2UgPSB0aGlzLm9wdGlvbnMubG9vc2VcbiAgcmFuZ2UgPSByYW5nZS50cmltKClcbiAgLy8gYDEuMi4zIC0gMS4yLjRgID0+IGA+PTEuMi4zIDw9MS4yLjRgXG4gIHZhciBociA9IGxvb3NlID8gcmVbSFlQSEVOUkFOR0VMT09TRV0gOiByZVtIWVBIRU5SQU5HRV1cbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKGhyLCBoeXBoZW5SZXBsYWNlKVxuICBkZWJ1ZygnaHlwaGVuIHJlcGxhY2UnLCByYW5nZSlcbiAgLy8gYD4gMS4yLjMgPCAxLjIuNWAgPT4gYD4xLjIuMyA8MS4yLjVgXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShyZVtDT01QQVJBVE9SVFJJTV0sIGNvbXBhcmF0b3JUcmltUmVwbGFjZSlcbiAgZGVidWcoJ2NvbXBhcmF0b3IgdHJpbScsIHJhbmdlLCByZVtDT01QQVJBVE9SVFJJTV0pXG5cbiAgLy8gYH4gMS4yLjNgID0+IGB+MS4yLjNgXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShyZVtUSUxERVRSSU1dLCB0aWxkZVRyaW1SZXBsYWNlKVxuXG4gIC8vIGBeIDEuMi4zYCA9PiBgXjEuMi4zYFxuICByYW5nZSA9IHJhbmdlLnJlcGxhY2UocmVbQ0FSRVRUUklNXSwgY2FyZXRUcmltUmVwbGFjZSlcblxuICAvLyBub3JtYWxpemUgc3BhY2VzXG4gIHJhbmdlID0gcmFuZ2Uuc3BsaXQoL1xccysvKS5qb2luKCcgJylcblxuICAvLyBBdCB0aGlzIHBvaW50LCB0aGUgcmFuZ2UgaXMgY29tcGxldGVseSB0cmltbWVkIGFuZFxuICAvLyByZWFkeSB0byBiZSBzcGxpdCBpbnRvIGNvbXBhcmF0b3JzLlxuXG4gIHZhciBjb21wUmUgPSBsb29zZSA/IHJlW0NPTVBBUkFUT1JMT09TRV0gOiByZVtDT01QQVJBVE9SXVxuICB2YXIgc2V0ID0gcmFuZ2Uuc3BsaXQoJyAnKS5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gcGFyc2VDb21wYXJhdG9yKGNvbXAsIHRoaXMub3B0aW9ucylcbiAgfSwgdGhpcykuam9pbignICcpLnNwbGl0KC9cXHMrLylcbiAgaWYgKHRoaXMub3B0aW9ucy5sb29zZSkge1xuICAgIC8vIGluIGxvb3NlIG1vZGUsIHRocm93IG91dCBhbnkgdGhhdCBhcmUgbm90IHZhbGlkIGNvbXBhcmF0b3JzXG4gICAgc2V0ID0gc2V0LmZpbHRlcihmdW5jdGlvbiAoY29tcCkge1xuICAgICAgcmV0dXJuICEhY29tcC5tYXRjaChjb21wUmUpXG4gICAgfSlcbiAgfVxuICBzZXQgPSBzZXQubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIG5ldyBDb21wYXJhdG9yKGNvbXAsIHRoaXMub3B0aW9ucylcbiAgfSwgdGhpcylcblxuICByZXR1cm4gc2V0XG59XG5cblJhbmdlLnByb3RvdHlwZS5pbnRlcnNlY3RzID0gZnVuY3Rpb24gKHJhbmdlLCBvcHRpb25zKSB7XG4gIGlmICghKHJhbmdlIGluc3RhbmNlb2YgUmFuZ2UpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYSBSYW5nZSBpcyByZXF1aXJlZCcpXG4gIH1cblxuICByZXR1cm4gdGhpcy5zZXQuc29tZShmdW5jdGlvbiAodGhpc0NvbXBhcmF0b3JzKSB7XG4gICAgcmV0dXJuIHRoaXNDb21wYXJhdG9ycy5ldmVyeShmdW5jdGlvbiAodGhpc0NvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiByYW5nZS5zZXQuc29tZShmdW5jdGlvbiAocmFuZ2VDb21wYXJhdG9ycykge1xuICAgICAgICByZXR1cm4gcmFuZ2VDb21wYXJhdG9ycy5ldmVyeShmdW5jdGlvbiAocmFuZ2VDb21wYXJhdG9yKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXNDb21wYXJhdG9yLmludGVyc2VjdHMocmFuZ2VDb21wYXJhdG9yLCBvcHRpb25zKVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICB9KVxuICB9KVxufVxuXG4vLyBNb3N0bHkganVzdCBmb3IgdGVzdGluZyBhbmQgbGVnYWN5IEFQSSByZWFzb25zXG5leHBvcnRzLnRvQ29tcGFyYXRvcnMgPSB0b0NvbXBhcmF0b3JzXG5mdW5jdGlvbiB0b0NvbXBhcmF0b3JzIChyYW5nZSwgb3B0aW9ucykge1xuICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKS5zZXQubWFwKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgcmV0dXJuIGNvbXAubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICByZXR1cm4gYy52YWx1ZVxuICAgIH0pLmpvaW4oJyAnKS50cmltKCkuc3BsaXQoJyAnKVxuICB9KVxufVxuXG4vLyBjb21wcmlzZWQgb2YgeHJhbmdlcywgdGlsZGVzLCBzdGFycywgYW5kIGd0bHQncyBhdCB0aGlzIHBvaW50LlxuLy8gYWxyZWFkeSByZXBsYWNlZCB0aGUgaHlwaGVuIHJhbmdlc1xuLy8gdHVybiBpbnRvIGEgc2V0IG9mIEpVU1QgY29tcGFyYXRvcnMuXG5mdW5jdGlvbiBwYXJzZUNvbXBhcmF0b3IgKGNvbXAsIG9wdGlvbnMpIHtcbiAgZGVidWcoJ2NvbXAnLCBjb21wLCBvcHRpb25zKVxuICBjb21wID0gcmVwbGFjZUNhcmV0cyhjb21wLCBvcHRpb25zKVxuICBkZWJ1ZygnY2FyZXQnLCBjb21wKVxuICBjb21wID0gcmVwbGFjZVRpbGRlcyhjb21wLCBvcHRpb25zKVxuICBkZWJ1ZygndGlsZGVzJywgY29tcClcbiAgY29tcCA9IHJlcGxhY2VYUmFuZ2VzKGNvbXAsIG9wdGlvbnMpXG4gIGRlYnVnKCd4cmFuZ2UnLCBjb21wKVxuICBjb21wID0gcmVwbGFjZVN0YXJzKGNvbXAsIG9wdGlvbnMpXG4gIGRlYnVnKCdzdGFycycsIGNvbXApXG4gIHJldHVybiBjb21wXG59XG5cbmZ1bmN0aW9uIGlzWCAoaWQpIHtcbiAgcmV0dXJuICFpZCB8fCBpZC50b0xvd2VyQ2FzZSgpID09PSAneCcgfHwgaWQgPT09ICcqJ1xufVxuXG4vLyB+LCB+PiAtLT4gKiAoYW55LCBraW5kYSBzaWxseSlcbi8vIH4yLCB+Mi54LCB+Mi54LngsIH4+Miwgfj4yLnggfj4yLngueCAtLT4gPj0yLjAuMCA8My4wLjBcbi8vIH4yLjAsIH4yLjAueCwgfj4yLjAsIH4+Mi4wLnggLS0+ID49Mi4wLjAgPDIuMS4wXG4vLyB+MS4yLCB+MS4yLngsIH4+MS4yLCB+PjEuMi54IC0tPiA+PTEuMi4wIDwxLjMuMFxuLy8gfjEuMi4zLCB+PjEuMi4zIC0tPiA+PTEuMi4zIDwxLjMuMFxuLy8gfjEuMi4wLCB+PjEuMi4wIC0tPiA+PTEuMi4wIDwxLjMuMFxuZnVuY3Rpb24gcmVwbGFjZVRpbGRlcyAoY29tcCwgb3B0aW9ucykge1xuICByZXR1cm4gY29tcC50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZVRpbGRlKGNvbXAsIG9wdGlvbnMpXG4gIH0pLmpvaW4oJyAnKVxufVxuXG5mdW5jdGlvbiByZXBsYWNlVGlsZGUgKGNvbXAsIG9wdGlvbnMpIHtcbiAgdmFyIHIgPSBvcHRpb25zLmxvb3NlID8gcmVbVElMREVMT09TRV0gOiByZVtUSUxERV1cbiAgcmV0dXJuIGNvbXAucmVwbGFjZShyLCBmdW5jdGlvbiAoXywgTSwgbSwgcCwgcHIpIHtcbiAgICBkZWJ1ZygndGlsZGUnLCBjb21wLCBfLCBNLCBtLCBwLCBwcilcbiAgICB2YXIgcmV0XG5cbiAgICBpZiAoaXNYKE0pKSB7XG4gICAgICByZXQgPSAnJ1xuICAgIH0gZWxzZSBpZiAoaXNYKG0pKSB7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuMC4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICB9IGVsc2UgaWYgKGlzWChwKSkge1xuICAgICAgLy8gfjEuMiA9PSA+PTEuMi4wIDwxLjMuMFxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgIH0gZWxzZSBpZiAocHIpIHtcbiAgICAgIGRlYnVnKCdyZXBsYWNlVGlsZGUgcHInLCBwcilcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgKyAnLScgKyBwciArXG4gICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJ1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyB+MS4yLjMgPT0gPj0xLjIuMyA8MS4zLjBcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICB9XG5cbiAgICBkZWJ1ZygndGlsZGUgcmV0dXJuJywgcmV0KVxuICAgIHJldHVybiByZXRcbiAgfSlcbn1cblxuLy8gXiAtLT4gKiAoYW55LCBraW5kYSBzaWxseSlcbi8vIF4yLCBeMi54LCBeMi54LnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyBeMi4wLCBeMi4wLnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyBeMS4yLCBeMS4yLnggLS0+ID49MS4yLjAgPDIuMC4wXG4vLyBeMS4yLjMgLS0+ID49MS4yLjMgPDIuMC4wXG4vLyBeMS4yLjAgLS0+ID49MS4yLjAgPDIuMC4wXG5mdW5jdGlvbiByZXBsYWNlQ2FyZXRzIChjb21wLCBvcHRpb25zKSB7XG4gIHJldHVybiBjb21wLnRyaW0oKS5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbiAoY29tcCkge1xuICAgIHJldHVybiByZXBsYWNlQ2FyZXQoY29tcCwgb3B0aW9ucylcbiAgfSkuam9pbignICcpXG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VDYXJldCAoY29tcCwgb3B0aW9ucykge1xuICBkZWJ1ZygnY2FyZXQnLCBjb21wLCBvcHRpb25zKVxuICB2YXIgciA9IG9wdGlvbnMubG9vc2UgPyByZVtDQVJFVExPT1NFXSA6IHJlW0NBUkVUXVxuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uIChfLCBNLCBtLCBwLCBwcikge1xuICAgIGRlYnVnKCdjYXJldCcsIGNvbXAsIF8sIE0sIG0sIHAsIHByKVxuICAgIHZhciByZXRcblxuICAgIGlmIChpc1goTSkpIHtcbiAgICAgIHJldCA9ICcnXG4gICAgfSBlbHNlIGlmIChpc1gobSkpIHtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4wLjAgPCcgKyAoK00gKyAxKSArICcuMC4wJ1xuICAgIH0gZWxzZSBpZiAoaXNYKHApKSB7XG4gICAgICBpZiAoTSA9PT0gJzAnKSB7XG4gICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcikge1xuICAgICAgZGVidWcoJ3JlcGxhY2VDYXJldCBwcicsIHByKVxuICAgICAgaWYgKE0gPT09ICcwJykge1xuICAgICAgICBpZiAobSA9PT0gJzAnKSB7XG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArICctJyArIHByICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArIG0gKyAnLicgKyAoK3AgKyAxKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgKyAnLScgKyBwciArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArICctJyArIHByICtcbiAgICAgICAgICAgICAgJyA8JyArICgrTSArIDEpICsgJy4wLjAnXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKCdubyBwcicpXG4gICAgICBpZiAoTSA9PT0gJzAnKSB7XG4gICAgICAgIGlmIChtID09PSAnMCcpIHtcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArIG0gKyAnLicgKyAoK3AgKyAxKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgICAnIDwnICsgKCtNICsgMSkgKyAnLjAuMCdcbiAgICAgIH1cbiAgICB9XG5cbiAgICBkZWJ1ZygnY2FyZXQgcmV0dXJuJywgcmV0KVxuICAgIHJldHVybiByZXRcbiAgfSlcbn1cblxuZnVuY3Rpb24gcmVwbGFjZVhSYW5nZXMgKGNvbXAsIG9wdGlvbnMpIHtcbiAgZGVidWcoJ3JlcGxhY2VYUmFuZ2VzJywgY29tcCwgb3B0aW9ucylcbiAgcmV0dXJuIGNvbXAuc3BsaXQoL1xccysvKS5tYXAoZnVuY3Rpb24gKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZVhSYW5nZShjb21wLCBvcHRpb25zKVxuICB9KS5qb2luKCcgJylcbn1cblxuZnVuY3Rpb24gcmVwbGFjZVhSYW5nZSAoY29tcCwgb3B0aW9ucykge1xuICBjb21wID0gY29tcC50cmltKClcbiAgdmFyIHIgPSBvcHRpb25zLmxvb3NlID8gcmVbWFJBTkdFTE9PU0VdIDogcmVbWFJBTkdFXVxuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uIChyZXQsIGd0bHQsIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ3hSYW5nZScsIGNvbXAsIHJldCwgZ3RsdCwgTSwgbSwgcCwgcHIpXG4gICAgdmFyIHhNID0gaXNYKE0pXG4gICAgdmFyIHhtID0geE0gfHwgaXNYKG0pXG4gICAgdmFyIHhwID0geG0gfHwgaXNYKHApXG4gICAgdmFyIGFueVggPSB4cFxuXG4gICAgaWYgKGd0bHQgPT09ICc9JyAmJiBhbnlYKSB7XG4gICAgICBndGx0ID0gJydcbiAgICB9XG5cbiAgICBpZiAoeE0pIHtcbiAgICAgIGlmIChndGx0ID09PSAnPicgfHwgZ3RsdCA9PT0gJzwnKSB7XG4gICAgICAgIC8vIG5vdGhpbmcgaXMgYWxsb3dlZFxuICAgICAgICByZXQgPSAnPDAuMC4wJ1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gbm90aGluZyBpcyBmb3JiaWRkZW5cbiAgICAgICAgcmV0ID0gJyonXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChndGx0ICYmIGFueVgpIHtcbiAgICAgIC8vIHdlIGtub3cgcGF0Y2ggaXMgYW4geCwgYmVjYXVzZSB3ZSBoYXZlIGFueSB4IGF0IGFsbC5cbiAgICAgIC8vIHJlcGxhY2UgWCB3aXRoIDBcbiAgICAgIGlmICh4bSkge1xuICAgICAgICBtID0gMFxuICAgICAgfVxuICAgICAgcCA9IDBcblxuICAgICAgaWYgKGd0bHQgPT09ICc+Jykge1xuICAgICAgICAvLyA+MSA9PiA+PTIuMC4wXG4gICAgICAgIC8vID4xLjIgPT4gPj0xLjMuMFxuICAgICAgICAvLyA+MS4yLjMgPT4gPj0gMS4yLjRcbiAgICAgICAgZ3RsdCA9ICc+PSdcbiAgICAgICAgaWYgKHhtKSB7XG4gICAgICAgICAgTSA9ICtNICsgMVxuICAgICAgICAgIG0gPSAwXG4gICAgICAgICAgcCA9IDBcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtID0gK20gKyAxXG4gICAgICAgICAgcCA9IDBcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChndGx0ID09PSAnPD0nKSB7XG4gICAgICAgIC8vIDw9MC43LnggaXMgYWN0dWFsbHkgPDAuOC4wLCBzaW5jZSBhbnkgMC43Lnggc2hvdWxkXG4gICAgICAgIC8vIHBhc3MuICBTaW1pbGFybHksIDw9Ny54IGlzIGFjdHVhbGx5IDw4LjAuMCwgZXRjLlxuICAgICAgICBndGx0ID0gJzwnXG4gICAgICAgIGlmICh4bSkge1xuICAgICAgICAgIE0gPSArTSArIDFcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtID0gK20gKyAxXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0ID0gZ3RsdCArIE0gKyAnLicgKyBtICsgJy4nICsgcFxuICAgIH0gZWxzZSBpZiAoeG0pIHtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4wLjAgPCcgKyAoK00gKyAxKSArICcuMC4wJ1xuICAgIH0gZWxzZSBpZiAoeHApIHtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCdcbiAgICB9XG5cbiAgICBkZWJ1ZygneFJhbmdlIHJldHVybicsIHJldClcblxuICAgIHJldHVybiByZXRcbiAgfSlcbn1cblxuLy8gQmVjYXVzZSAqIGlzIEFORC1lZCB3aXRoIGV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgY29tcGFyYXRvcixcbi8vIGFuZCAnJyBtZWFucyBcImFueSB2ZXJzaW9uXCIsIGp1c3QgcmVtb3ZlIHRoZSAqcyBlbnRpcmVseS5cbmZ1bmN0aW9uIHJlcGxhY2VTdGFycyAoY29tcCwgb3B0aW9ucykge1xuICBkZWJ1ZygncmVwbGFjZVN0YXJzJywgY29tcCwgb3B0aW9ucylcbiAgLy8gTG9vc2VuZXNzIGlzIGlnbm9yZWQgaGVyZS4gIHN0YXIgaXMgYWx3YXlzIGFzIGxvb3NlIGFzIGl0IGdldHMhXG4gIHJldHVybiBjb21wLnRyaW0oKS5yZXBsYWNlKHJlW1NUQVJdLCAnJylcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyBwYXNzZWQgdG8gc3RyaW5nLnJlcGxhY2UocmVbSFlQSEVOUkFOR0VdKVxuLy8gTSwgbSwgcGF0Y2gsIHByZXJlbGVhc2UsIGJ1aWxkXG4vLyAxLjIgLSAzLjQuNSA9PiA+PTEuMi4wIDw9My40LjVcbi8vIDEuMi4zIC0gMy40ID0+ID49MS4yLjAgPDMuNS4wIEFueSAzLjQueCB3aWxsIGRvXG4vLyAxLjIgLSAzLjQgPT4gPj0xLjIuMCA8My41LjBcbmZ1bmN0aW9uIGh5cGhlblJlcGxhY2UgKCQwLFxuICBmcm9tLCBmTSwgZm0sIGZwLCBmcHIsIGZiLFxuICB0bywgdE0sIHRtLCB0cCwgdHByLCB0Yikge1xuICBpZiAoaXNYKGZNKSkge1xuICAgIGZyb20gPSAnJ1xuICB9IGVsc2UgaWYgKGlzWChmbSkpIHtcbiAgICBmcm9tID0gJz49JyArIGZNICsgJy4wLjAnXG4gIH0gZWxzZSBpZiAoaXNYKGZwKSkge1xuICAgIGZyb20gPSAnPj0nICsgZk0gKyAnLicgKyBmbSArICcuMCdcbiAgfSBlbHNlIHtcbiAgICBmcm9tID0gJz49JyArIGZyb21cbiAgfVxuXG4gIGlmIChpc1godE0pKSB7XG4gICAgdG8gPSAnJ1xuICB9IGVsc2UgaWYgKGlzWCh0bSkpIHtcbiAgICB0byA9ICc8JyArICgrdE0gKyAxKSArICcuMC4wJ1xuICB9IGVsc2UgaWYgKGlzWCh0cCkpIHtcbiAgICB0byA9ICc8JyArIHRNICsgJy4nICsgKCt0bSArIDEpICsgJy4wJ1xuICB9IGVsc2UgaWYgKHRwcikge1xuICAgIHRvID0gJzw9JyArIHRNICsgJy4nICsgdG0gKyAnLicgKyB0cCArICctJyArIHRwclxuICB9IGVsc2Uge1xuICAgIHRvID0gJzw9JyArIHRvXG4gIH1cblxuICByZXR1cm4gKGZyb20gKyAnICcgKyB0bykudHJpbSgpXG59XG5cbi8vIGlmIEFOWSBvZiB0aGUgc2V0cyBtYXRjaCBBTEwgb2YgaXRzIGNvbXBhcmF0b3JzLCB0aGVuIHBhc3NcblJhbmdlLnByb3RvdHlwZS50ZXN0ID0gZnVuY3Rpb24gKHZlcnNpb24pIHtcbiAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAodHlwZW9mIHZlcnNpb24gPT09ICdzdHJpbmcnKSB7XG4gICAgdmVyc2lvbiA9IG5ldyBTZW1WZXIodmVyc2lvbiwgdGhpcy5vcHRpb25zKVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnNldC5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0ZXN0U2V0KHRoaXMuc2V0W2ldLCB2ZXJzaW9uLCB0aGlzLm9wdGlvbnMpKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gdGVzdFNldCAoc2V0LCB2ZXJzaW9uLCBvcHRpb25zKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFzZXRbaV0udGVzdCh2ZXJzaW9uKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG5cbiAgaWYgKHZlcnNpb24ucHJlcmVsZWFzZS5sZW5ndGggJiYgIW9wdGlvbnMuaW5jbHVkZVByZXJlbGVhc2UpIHtcbiAgICAvLyBGaW5kIHRoZSBzZXQgb2YgdmVyc2lvbnMgdGhhdCBhcmUgYWxsb3dlZCB0byBoYXZlIHByZXJlbGVhc2VzXG4gICAgLy8gRm9yIGV4YW1wbGUsIF4xLjIuMy1wci4xIGRlc3VnYXJzIHRvID49MS4yLjMtcHIuMSA8Mi4wLjBcbiAgICAvLyBUaGF0IHNob3VsZCBhbGxvdyBgMS4yLjMtcHIuMmAgdG8gcGFzcy5cbiAgICAvLyBIb3dldmVyLCBgMS4yLjQtYWxwaGEubm90cmVhZHlgIHNob3VsZCBOT1QgYmUgYWxsb3dlZCxcbiAgICAvLyBldmVuIHRob3VnaCBpdCdzIHdpdGhpbiB0aGUgcmFuZ2Ugc2V0IGJ5IHRoZSBjb21wYXJhdG9ycy5cbiAgICBmb3IgKGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBkZWJ1ZyhzZXRbaV0uc2VtdmVyKVxuICAgICAgaWYgKHNldFtpXS5zZW12ZXIgPT09IEFOWSkge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoc2V0W2ldLnNlbXZlci5wcmVyZWxlYXNlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdmFyIGFsbG93ZWQgPSBzZXRbaV0uc2VtdmVyXG4gICAgICAgIGlmIChhbGxvd2VkLm1ham9yID09PSB2ZXJzaW9uLm1ham9yICYmXG4gICAgICAgICAgICBhbGxvd2VkLm1pbm9yID09PSB2ZXJzaW9uLm1pbm9yICYmXG4gICAgICAgICAgICBhbGxvd2VkLnBhdGNoID09PSB2ZXJzaW9uLnBhdGNoKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFZlcnNpb24gaGFzIGEgLXByZSwgYnV0IGl0J3Mgbm90IG9uZSBvZiB0aGUgb25lcyB3ZSBsaWtlLlxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cblxuZXhwb3J0cy5zYXRpc2ZpZXMgPSBzYXRpc2ZpZXNcbmZ1bmN0aW9uIHNhdGlzZmllcyAodmVyc2lvbiwgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgdHJ5IHtcbiAgICByYW5nZSA9IG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICByZXR1cm4gcmFuZ2UudGVzdCh2ZXJzaW9uKVxufVxuXG5leHBvcnRzLm1heFNhdGlzZnlpbmcgPSBtYXhTYXRpc2Z5aW5nXG5mdW5jdGlvbiBtYXhTYXRpc2Z5aW5nICh2ZXJzaW9ucywgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgdmFyIG1heCA9IG51bGxcbiAgdmFyIG1heFNWID0gbnVsbFxuICB0cnkge1xuICAgIHZhciByYW5nZU9iaiA9IG5ldyBSYW5nZShyYW5nZSwgb3B0aW9ucylcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG4gIHZlcnNpb25zLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICBpZiAocmFuZ2VPYmoudGVzdCh2KSkge1xuICAgICAgLy8gc2F0aXNmaWVzKHYsIHJhbmdlLCBvcHRpb25zKVxuICAgICAgaWYgKCFtYXggfHwgbWF4U1YuY29tcGFyZSh2KSA9PT0gLTEpIHtcbiAgICAgICAgLy8gY29tcGFyZShtYXgsIHYsIHRydWUpXG4gICAgICAgIG1heCA9IHZcbiAgICAgICAgbWF4U1YgPSBuZXcgU2VtVmVyKG1heCwgb3B0aW9ucylcbiAgICAgIH1cbiAgICB9XG4gIH0pXG4gIHJldHVybiBtYXhcbn1cblxuZXhwb3J0cy5taW5TYXRpc2Z5aW5nID0gbWluU2F0aXNmeWluZ1xuZnVuY3Rpb24gbWluU2F0aXNmeWluZyAodmVyc2lvbnMsIHJhbmdlLCBvcHRpb25zKSB7XG4gIHZhciBtaW4gPSBudWxsXG4gIHZhciBtaW5TViA9IG51bGxcbiAgdHJ5IHtcbiAgICB2YXIgcmFuZ2VPYmogPSBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpXG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuICB2ZXJzaW9ucy5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG4gICAgaWYgKHJhbmdlT2JqLnRlc3QodikpIHtcbiAgICAgIC8vIHNhdGlzZmllcyh2LCByYW5nZSwgb3B0aW9ucylcbiAgICAgIGlmICghbWluIHx8IG1pblNWLmNvbXBhcmUodikgPT09IDEpIHtcbiAgICAgICAgLy8gY29tcGFyZShtaW4sIHYsIHRydWUpXG4gICAgICAgIG1pbiA9IHZcbiAgICAgICAgbWluU1YgPSBuZXcgU2VtVmVyKG1pbiwgb3B0aW9ucylcbiAgICAgIH1cbiAgICB9XG4gIH0pXG4gIHJldHVybiBtaW5cbn1cblxuZXhwb3J0cy5taW5WZXJzaW9uID0gbWluVmVyc2lvblxuZnVuY3Rpb24gbWluVmVyc2lvbiAocmFuZ2UsIGxvb3NlKSB7XG4gIHJhbmdlID0gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSlcblxuICB2YXIgbWludmVyID0gbmV3IFNlbVZlcignMC4wLjAnKVxuICBpZiAocmFuZ2UudGVzdChtaW52ZXIpKSB7XG4gICAgcmV0dXJuIG1pbnZlclxuICB9XG5cbiAgbWludmVyID0gbmV3IFNlbVZlcignMC4wLjAtMCcpXG4gIGlmIChyYW5nZS50ZXN0KG1pbnZlcikpIHtcbiAgICByZXR1cm4gbWludmVyXG4gIH1cblxuICBtaW52ZXIgPSBudWxsXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2Uuc2V0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGNvbXBhcmF0b3JzID0gcmFuZ2Uuc2V0W2ldXG5cbiAgICBjb21wYXJhdG9ycy5mb3JFYWNoKGZ1bmN0aW9uIChjb21wYXJhdG9yKSB7XG4gICAgICAvLyBDbG9uZSB0byBhdm9pZCBtYW5pcHVsYXRpbmcgdGhlIGNvbXBhcmF0b3IncyBzZW12ZXIgb2JqZWN0LlxuICAgICAgdmFyIGNvbXB2ZXIgPSBuZXcgU2VtVmVyKGNvbXBhcmF0b3Iuc2VtdmVyLnZlcnNpb24pXG4gICAgICBzd2l0Y2ggKGNvbXBhcmF0b3Iub3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSAnPic6XG4gICAgICAgICAgaWYgKGNvbXB2ZXIucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGNvbXB2ZXIucGF0Y2grK1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb21wdmVyLnByZXJlbGVhc2UucHVzaCgwKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb21wdmVyLnJhdyA9IGNvbXB2ZXIuZm9ybWF0KClcbiAgICAgICAgICAvKiBmYWxsdGhyb3VnaCAqL1xuICAgICAgICBjYXNlICcnOlxuICAgICAgICBjYXNlICc+PSc6XG4gICAgICAgICAgaWYgKCFtaW52ZXIgfHwgZ3QobWludmVyLCBjb21wdmVyKSkge1xuICAgICAgICAgICAgbWludmVyID0gY29tcHZlclxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlICc8JzpcbiAgICAgICAgY2FzZSAnPD0nOlxuICAgICAgICAgIC8qIElnbm9yZSBtYXhpbXVtIHZlcnNpb25zICovXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgb3BlcmF0aW9uOiAnICsgY29tcGFyYXRvci5vcGVyYXRvcilcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgaWYgKG1pbnZlciAmJiByYW5nZS50ZXN0KG1pbnZlcikpIHtcbiAgICByZXR1cm4gbWludmVyXG4gIH1cblxuICByZXR1cm4gbnVsbFxufVxuXG5leHBvcnRzLnZhbGlkUmFuZ2UgPSB2YWxpZFJhbmdlXG5mdW5jdGlvbiB2YWxpZFJhbmdlIChyYW5nZSwgb3B0aW9ucykge1xuICB0cnkge1xuICAgIC8vIFJldHVybiAnKicgaW5zdGVhZCBvZiAnJyBzbyB0aGF0IHRydXRoaW5lc3Mgd29ya3MuXG4gICAgLy8gVGhpcyB3aWxsIHRocm93IGlmIGl0J3MgaW52YWxpZCBhbnl3YXlcbiAgICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBvcHRpb25zKS5yYW5nZSB8fCAnKidcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbi8vIERldGVybWluZSBpZiB2ZXJzaW9uIGlzIGxlc3MgdGhhbiBhbGwgdGhlIHZlcnNpb25zIHBvc3NpYmxlIGluIHRoZSByYW5nZVxuZXhwb3J0cy5sdHIgPSBsdHJcbmZ1bmN0aW9uIGx0ciAodmVyc2lvbiwgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG91dHNpZGUodmVyc2lvbiwgcmFuZ2UsICc8Jywgb3B0aW9ucylcbn1cblxuLy8gRGV0ZXJtaW5lIGlmIHZlcnNpb24gaXMgZ3JlYXRlciB0aGFuIGFsbCB0aGUgdmVyc2lvbnMgcG9zc2libGUgaW4gdGhlIHJhbmdlLlxuZXhwb3J0cy5ndHIgPSBndHJcbmZ1bmN0aW9uIGd0ciAodmVyc2lvbiwgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG91dHNpZGUodmVyc2lvbiwgcmFuZ2UsICc+Jywgb3B0aW9ucylcbn1cblxuZXhwb3J0cy5vdXRzaWRlID0gb3V0c2lkZVxuZnVuY3Rpb24gb3V0c2lkZSAodmVyc2lvbiwgcmFuZ2UsIGhpbG8sIG9wdGlvbnMpIHtcbiAgdmVyc2lvbiA9IG5ldyBTZW1WZXIodmVyc2lvbiwgb3B0aW9ucylcbiAgcmFuZ2UgPSBuZXcgUmFuZ2UocmFuZ2UsIG9wdGlvbnMpXG5cbiAgdmFyIGd0Zm4sIGx0ZWZuLCBsdGZuLCBjb21wLCBlY29tcFxuICBzd2l0Y2ggKGhpbG8pIHtcbiAgICBjYXNlICc+JzpcbiAgICAgIGd0Zm4gPSBndFxuICAgICAgbHRlZm4gPSBsdGVcbiAgICAgIGx0Zm4gPSBsdFxuICAgICAgY29tcCA9ICc+J1xuICAgICAgZWNvbXAgPSAnPj0nXG4gICAgICBicmVha1xuICAgIGNhc2UgJzwnOlxuICAgICAgZ3RmbiA9IGx0XG4gICAgICBsdGVmbiA9IGd0ZVxuICAgICAgbHRmbiA9IGd0XG4gICAgICBjb21wID0gJzwnXG4gICAgICBlY29tcCA9ICc8PSdcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ011c3QgcHJvdmlkZSBhIGhpbG8gdmFsIG9mIFwiPFwiIG9yIFwiPlwiJylcbiAgfVxuXG4gIC8vIElmIGl0IHNhdGlzaWZlcyB0aGUgcmFuZ2UgaXQgaXMgbm90IG91dHNpZGVcbiAgaWYgKHNhdGlzZmllcyh2ZXJzaW9uLCByYW5nZSwgb3B0aW9ucykpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIEZyb20gbm93IG9uLCB2YXJpYWJsZSB0ZXJtcyBhcmUgYXMgaWYgd2UncmUgaW4gXCJndHJcIiBtb2RlLlxuICAvLyBidXQgbm90ZSB0aGF0IGV2ZXJ5dGhpbmcgaXMgZmxpcHBlZCBmb3IgdGhlIFwibHRyXCIgZnVuY3Rpb24uXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByYW5nZS5zZXQubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgY29tcGFyYXRvcnMgPSByYW5nZS5zZXRbaV1cblxuICAgIHZhciBoaWdoID0gbnVsbFxuICAgIHZhciBsb3cgPSBudWxsXG5cbiAgICBjb21wYXJhdG9ycy5mb3JFYWNoKGZ1bmN0aW9uIChjb21wYXJhdG9yKSB7XG4gICAgICBpZiAoY29tcGFyYXRvci5zZW12ZXIgPT09IEFOWSkge1xuICAgICAgICBjb21wYXJhdG9yID0gbmV3IENvbXBhcmF0b3IoJz49MC4wLjAnKVxuICAgICAgfVxuICAgICAgaGlnaCA9IGhpZ2ggfHwgY29tcGFyYXRvclxuICAgICAgbG93ID0gbG93IHx8IGNvbXBhcmF0b3JcbiAgICAgIGlmIChndGZuKGNvbXBhcmF0b3Iuc2VtdmVyLCBoaWdoLnNlbXZlciwgb3B0aW9ucykpIHtcbiAgICAgICAgaGlnaCA9IGNvbXBhcmF0b3JcbiAgICAgIH0gZWxzZSBpZiAobHRmbihjb21wYXJhdG9yLnNlbXZlciwgbG93LnNlbXZlciwgb3B0aW9ucykpIHtcbiAgICAgICAgbG93ID0gY29tcGFyYXRvclxuICAgICAgfVxuICAgIH0pXG5cbiAgICAvLyBJZiB0aGUgZWRnZSB2ZXJzaW9uIGNvbXBhcmF0b3IgaGFzIGEgb3BlcmF0b3IgdGhlbiBvdXIgdmVyc2lvblxuICAgIC8vIGlzbid0IG91dHNpZGUgaXRcbiAgICBpZiAoaGlnaC5vcGVyYXRvciA9PT0gY29tcCB8fCBoaWdoLm9wZXJhdG9yID09PSBlY29tcCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIGxvd2VzdCB2ZXJzaW9uIGNvbXBhcmF0b3IgaGFzIGFuIG9wZXJhdG9yIGFuZCBvdXIgdmVyc2lvblxuICAgIC8vIGlzIGxlc3MgdGhhbiBpdCB0aGVuIGl0IGlzbid0IGhpZ2hlciB0aGFuIHRoZSByYW5nZVxuICAgIGlmICgoIWxvdy5vcGVyYXRvciB8fCBsb3cub3BlcmF0b3IgPT09IGNvbXApICYmXG4gICAgICAgIGx0ZWZuKHZlcnNpb24sIGxvdy5zZW12ZXIpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9IGVsc2UgaWYgKGxvdy5vcGVyYXRvciA9PT0gZWNvbXAgJiYgbHRmbih2ZXJzaW9uLCBsb3cuc2VtdmVyKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbmV4cG9ydHMucHJlcmVsZWFzZSA9IHByZXJlbGVhc2VcbmZ1bmN0aW9uIHByZXJlbGVhc2UgKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgdmFyIHBhcnNlZCA9IHBhcnNlKHZlcnNpb24sIG9wdGlvbnMpXG4gIHJldHVybiAocGFyc2VkICYmIHBhcnNlZC5wcmVyZWxlYXNlLmxlbmd0aCkgPyBwYXJzZWQucHJlcmVsZWFzZSA6IG51bGxcbn1cblxuZXhwb3J0cy5pbnRlcnNlY3RzID0gaW50ZXJzZWN0c1xuZnVuY3Rpb24gaW50ZXJzZWN0cyAocjEsIHIyLCBvcHRpb25zKSB7XG4gIHIxID0gbmV3IFJhbmdlKHIxLCBvcHRpb25zKVxuICByMiA9IG5ldyBSYW5nZShyMiwgb3B0aW9ucylcbiAgcmV0dXJuIHIxLmludGVyc2VjdHMocjIpXG59XG5cbmV4cG9ydHMuY29lcmNlID0gY29lcmNlXG5mdW5jdGlvbiBjb2VyY2UgKHZlcnNpb24pIHtcbiAgaWYgKHZlcnNpb24gaW5zdGFuY2VvZiBTZW1WZXIpIHtcbiAgICByZXR1cm4gdmVyc2lvblxuICB9XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICB2YXIgbWF0Y2ggPSB2ZXJzaW9uLm1hdGNoKHJlW0NPRVJDRV0pXG5cbiAgaWYgKG1hdGNoID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgcmV0dXJuIHBhcnNlKG1hdGNoWzFdICtcbiAgICAnLicgKyAobWF0Y2hbMl0gfHwgJzAnKSArXG4gICAgJy4nICsgKG1hdGNoWzNdIHx8ICcwJykpXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IFtcbiAgJ2NhdCcsXG4gICdjZCcsXG4gICdjaG1vZCcsXG4gICdjcCcsXG4gICdkaXJzJyxcbiAgJ2VjaG8nLFxuICAnZXhlYycsXG4gICdmaW5kJyxcbiAgJ2dyZXAnLFxuICAnaGVhZCcsXG4gICdsbicsXG4gICdscycsXG4gICdta2RpcicsXG4gICdtdicsXG4gICdwd2QnLFxuICAncm0nLFxuICAnc2VkJyxcbiAgJ3NldCcsXG4gICdzb3J0JyxcbiAgJ3RhaWwnLFxuICAndGVtcGRpcicsXG4gICd0ZXN0JyxcbiAgJ3RvJyxcbiAgJ3RvRW5kJyxcbiAgJ3RvdWNoJyxcbiAgJ3VuaXEnLFxuICAnd2hpY2gnLFxuXTtcbiIsIi8vXG4vLyBTaGVsbEpTXG4vLyBVbml4IHNoZWxsIGNvbW1hbmRzIG9uIHRvcCBvZiBOb2RlJ3MgQVBJXG4vL1xuLy8gQ29weXJpZ2h0IChjKSAyMDEyIEFydHVyIEFkaWJcbi8vIGh0dHA6Ly9naXRodWIuY29tL3NoZWxsanMvc2hlbGxqc1xuLy9cblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vc3JjL2NvbW1vbicpO1xuXG4vL0Bcbi8vQCBBbGwgY29tbWFuZHMgcnVuIHN5bmNocm9ub3VzbHksIHVubGVzcyBvdGhlcndpc2Ugc3RhdGVkLlxuLy9AIEFsbCBjb21tYW5kcyBhY2NlcHQgc3RhbmRhcmQgYmFzaCBnbG9iYmluZyBjaGFyYWN0ZXJzIChgKmAsIGA/YCwgZXRjLiksXG4vL0AgY29tcGF0aWJsZSB3aXRoIHRoZSBbbm9kZSBgZ2xvYmAgbW9kdWxlXShodHRwczovL2dpdGh1Yi5jb20vaXNhYWNzL25vZGUtZ2xvYikuXG4vL0Bcbi8vQCBGb3IgbGVzcy1jb21tb25seSB1c2VkIGNvbW1hbmRzIGFuZCBmZWF0dXJlcywgcGxlYXNlIGNoZWNrIG91dCBvdXIgW3dpa2lcbi8vQCBwYWdlXShodHRwczovL2dpdGh1Yi5jb20vc2hlbGxqcy9zaGVsbGpzL3dpa2kpLlxuLy9AXG5cbi8vIEluY2x1ZGUgdGhlIGRvY3MgZm9yIGFsbCB0aGUgZGVmYXVsdCBjb21tYW5kc1xuLy9AY29tbWFuZHNcblxuLy8gTG9hZCBhbGwgZGVmYXVsdCBjb21tYW5kc1xucmVxdWlyZSgnLi9jb21tYW5kcycpLmZvckVhY2goZnVuY3Rpb24gKGNvbW1hbmQpIHtcbiAgcmVxdWlyZSgnLi9zcmMvJyArIGNvbW1hbmQpO1xufSk7XG5cbi8vQFxuLy9AICMjIyBleGl0KGNvZGUpXG4vL0Bcbi8vQCBFeGl0cyB0aGUgY3VycmVudCBwcm9jZXNzIHdpdGggdGhlIGdpdmVuIGV4aXQgYGNvZGVgLlxuZXhwb3J0cy5leGl0ID0gcHJvY2Vzcy5leGl0O1xuXG4vL0BpbmNsdWRlIC4vc3JjL2Vycm9yXG5leHBvcnRzLmVycm9yID0gcmVxdWlyZSgnLi9zcmMvZXJyb3InKTtcblxuLy9AaW5jbHVkZSAuL3NyYy9jb21tb25cbmV4cG9ydHMuU2hlbGxTdHJpbmcgPSBjb21tb24uU2hlbGxTdHJpbmc7XG5cbi8vQFxuLy9AICMjIyBlbnZbJ1ZBUl9OQU1FJ11cbi8vQFxuLy9AIE9iamVjdCBjb250YWluaW5nIGVudmlyb25tZW50IHZhcmlhYmxlcyAoYm90aCBnZXR0ZXIgYW5kIHNldHRlcikuIFNob3J0Y3V0XG4vL0AgdG8gYHByb2Nlc3MuZW52YC5cbmV4cG9ydHMuZW52ID0gcHJvY2Vzcy5lbnY7XG5cbi8vQFxuLy9AICMjIyBQaXBlc1xuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgZ3JlcCgnZm9vJywgJ2ZpbGUxLnR4dCcsICdmaWxlMi50eHQnKS5zZWQoL28vZywgJ2EnKS50bygnb3V0cHV0LnR4dCcpO1xuLy9AIGVjaG8oJ2ZpbGVzIHdpdGggb1xcJ3MgaW4gdGhlIG5hbWU6XFxuJyArIGxzKCkuZ3JlcCgnbycpKTtcbi8vQCBjYXQoJ3Rlc3QuanMnKS5leGVjKCdub2RlJyk7IC8vIHBpcGUgdG8gZXhlYygpIGNhbGxcbi8vQCBgYGBcbi8vQFxuLy9AIENvbW1hbmRzIGNhbiBzZW5kIHRoZWlyIG91dHB1dCB0byBhbm90aGVyIGNvbW1hbmQgaW4gYSBwaXBlLWxpa2UgZmFzaGlvbi5cbi8vQCBgc2VkYCwgYGdyZXBgLCBgY2F0YCwgYGV4ZWNgLCBgdG9gLCBhbmQgYHRvRW5kYCBjYW4gYXBwZWFyIG9uIHRoZSByaWdodC1oYW5kXG4vL0Agc2lkZSBvZiBhIHBpcGUuIFBpcGVzIGNhbiBiZSBjaGFpbmVkLlxuXG4vL0Bcbi8vQCAjIyBDb25maWd1cmF0aW9uXG4vL0BcblxuZXhwb3J0cy5jb25maWcgPSBjb21tb24uY29uZmlnO1xuXG4vL0Bcbi8vQCAjIyMgY29uZmlnLnNpbGVudFxuLy9AXG4vL0AgRXhhbXBsZTpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCB2YXIgc2ggPSByZXF1aXJlKCdzaGVsbGpzJyk7XG4vL0AgdmFyIHNpbGVudFN0YXRlID0gc2guY29uZmlnLnNpbGVudDsgLy8gc2F2ZSBvbGQgc2lsZW50IHN0YXRlXG4vL0Agc2guY29uZmlnLnNpbGVudCA9IHRydWU7XG4vL0AgLyogLi4uICovXG4vL0Agc2guY29uZmlnLnNpbGVudCA9IHNpbGVudFN0YXRlOyAvLyByZXN0b3JlIG9sZCBzaWxlbnQgc3RhdGVcbi8vQCBgYGBcbi8vQFxuLy9AIFN1cHByZXNzZXMgYWxsIGNvbW1hbmQgb3V0cHV0IGlmIGB0cnVlYCwgZXhjZXB0IGZvciBgZWNobygpYCBjYWxscy5cbi8vQCBEZWZhdWx0IGlzIGBmYWxzZWAuXG5cbi8vQFxuLy9AICMjIyBjb25maWcuZmF0YWxcbi8vQFxuLy9AIEV4YW1wbGU6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgcmVxdWlyZSgnc2hlbGxqcy9nbG9iYWwnKTtcbi8vQCBjb25maWcuZmF0YWwgPSB0cnVlOyAvLyBvciBzZXQoJy1lJyk7XG4vL0AgY3AoJ3RoaXNfZmlsZV9kb2VzX25vdF9leGlzdCcsICcvZGV2L251bGwnKTsgLy8gdGhyb3dzIEVycm9yIGhlcmVcbi8vQCAvKiBtb3JlIGNvbW1hbmRzLi4uICovXG4vL0AgYGBgXG4vL0Bcbi8vQCBJZiBgdHJ1ZWAsIHRoZSBzY3JpcHQgd2lsbCB0aHJvdyBhIEphdmFzY3JpcHQgZXJyb3Igd2hlbiBhbnkgc2hlbGwuanNcbi8vQCBjb21tYW5kIGVuY291bnRlcnMgYW4gZXJyb3IuIERlZmF1bHQgaXMgYGZhbHNlYC4gVGhpcyBpcyBhbmFsb2dvdXMgdG9cbi8vQCBCYXNoJ3MgYHNldCAtZWAuXG5cbi8vQFxuLy9AICMjIyBjb25maWcudmVyYm9zZVxuLy9AXG4vL0AgRXhhbXBsZTpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBjb25maWcudmVyYm9zZSA9IHRydWU7IC8vIG9yIHNldCgnLXYnKTtcbi8vQCBjZCgnZGlyLycpO1xuLy9AIHJtKCctcmYnLCAnZm9vLnR4dCcsICdiYXIudHh0Jyk7XG4vL0AgZXhlYygnZWNobyBoZWxsbycpO1xuLy9AIGBgYFxuLy9AXG4vL0AgV2lsbCBwcmludCBlYWNoIGNvbW1hbmQgYXMgZm9sbG93czpcbi8vQFxuLy9AIGBgYFxuLy9AIGNkIGRpci9cbi8vQCBybSAtcmYgZm9vLnR4dCBiYXIudHh0XG4vL0AgZXhlYyBlY2hvIGhlbGxvXG4vL0AgYGBgXG5cbi8vQFxuLy9AICMjIyBjb25maWcuZ2xvYk9wdGlvbnNcbi8vQFxuLy9AIEV4YW1wbGU6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgY29uZmlnLmdsb2JPcHRpb25zID0ge25vZGlyOiB0cnVlfTtcbi8vQCBgYGBcbi8vQFxuLy9AIFVzZSB0aGlzIHZhbHVlIGZvciBjYWxscyB0byBgZ2xvYi5zeW5jKClgIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb3B0aW9ucy5cblxuLy9AXG4vL0AgIyMjIGNvbmZpZy5yZXNldCgpXG4vL0Bcbi8vQCBFeGFtcGxlOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHZhciBzaGVsbCA9IHJlcXVpcmUoJ3NoZWxsanMnKTtcbi8vQCAvLyBNYWtlIGNoYW5nZXMgdG8gc2hlbGwuY29uZmlnLCBhbmQgZG8gc3R1ZmYuLi5cbi8vQCAvKiAuLi4gKi9cbi8vQCBzaGVsbC5jb25maWcucmVzZXQoKTsgLy8gcmVzZXQgdG8gb3JpZ2luYWwgc3RhdGVcbi8vQCAvLyBEbyBtb3JlIHN0dWZmLCBidXQgd2l0aCBvcmlnaW5hbCBzZXR0aW5nc1xuLy9AIC8qIC4uLiAqL1xuLy9AIGBgYFxuLy9AXG4vL0AgUmVzZXQgYHNoZWxsLmNvbmZpZ2AgdG8gdGhlIGRlZmF1bHRzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHtcbi8vQCAgIGZhdGFsOiBmYWxzZSxcbi8vQCAgIGdsb2JPcHRpb25zOiB7fSxcbi8vQCAgIG1heGRlcHRoOiAyNTUsXG4vL0AgICBub2dsb2I6IGZhbHNlLFxuLy9AICAgc2lsZW50OiBmYWxzZSxcbi8vQCAgIHZlcmJvc2U6IGZhbHNlLFxuLy9AIH1cbi8vQCBgYGBcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCdjYXQnLCBfY2F0LCB7XG4gIGNhblJlY2VpdmVQaXBlOiB0cnVlLFxuICBjbWRPcHRpb25zOiB7XG4gICAgJ24nOiAnbnVtYmVyJyxcbiAgfSxcbn0pO1xuXG4vL0Bcbi8vQCAjIyMgY2F0KFtvcHRpb25zLF0gZmlsZSBbLCBmaWxlIC4uLl0pXG4vL0AgIyMjIGNhdChbb3B0aW9ucyxdIGZpbGVfYXJyYXkpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1uYDogbnVtYmVyIGFsbCBvdXRwdXQgbGluZXNcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHZhciBzdHIgPSBjYXQoJ2ZpbGUqLnR4dCcpO1xuLy9AIHZhciBzdHIgPSBjYXQoJ2ZpbGUxJywgJ2ZpbGUyJyk7XG4vL0AgdmFyIHN0ciA9IGNhdChbJ2ZpbGUxJywgJ2ZpbGUyJ10pOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgYGBgXG4vL0Bcbi8vQCBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGdpdmVuIGZpbGUsIG9yIGEgY29uY2F0ZW5hdGVkIHN0cmluZ1xuLy9AIGNvbnRhaW5pbmcgdGhlIGZpbGVzIGlmIG1vcmUgdGhhbiBvbmUgZmlsZSBpcyBnaXZlbiAoYSBuZXcgbGluZSBjaGFyYWN0ZXIgaXNcbi8vQCBpbnRyb2R1Y2VkIGJldHdlZW4gZWFjaCBmaWxlKS5cbmZ1bmN0aW9uIF9jYXQob3B0aW9ucywgZmlsZXMpIHtcbiAgdmFyIGNhdCA9IGNvbW1vbi5yZWFkRnJvbVBpcGUoKTtcblxuICBpZiAoIWZpbGVzICYmICFjYXQpIGNvbW1vbi5lcnJvcignbm8gcGF0aHMgZ2l2ZW4nKTtcblxuICBmaWxlcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblxuICBmaWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGUpKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBmaWxlKTtcbiAgICB9IGVsc2UgaWYgKGNvbW1vbi5zdGF0Rm9sbG93TGlua3MoZmlsZSkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgY29tbW9uLmVycm9yKGZpbGUgKyAnOiBJcyBhIGRpcmVjdG9yeScpO1xuICAgIH1cblxuICAgIGNhdCArPSBmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0ZjgnKTtcbiAgfSk7XG5cbiAgaWYgKG9wdGlvbnMubnVtYmVyKSB7XG4gICAgY2F0ID0gYWRkTnVtYmVycyhjYXQpO1xuICB9XG5cbiAgcmV0dXJuIGNhdDtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2NhdDtcblxuZnVuY3Rpb24gYWRkTnVtYmVycyhjYXQpIHtcbiAgdmFyIGxpbmVzID0gY2F0LnNwbGl0KCdcXG4nKTtcbiAgdmFyIGxhc3RMaW5lID0gbGluZXMucG9wKCk7XG5cbiAgbGluZXMgPSBsaW5lcy5tYXAoZnVuY3Rpb24gKGxpbmUsIGkpIHtcbiAgICByZXR1cm4gbnVtYmVyZWRMaW5lKGkgKyAxLCBsaW5lKTtcbiAgfSk7XG5cbiAgaWYgKGxhc3RMaW5lLmxlbmd0aCkge1xuICAgIGxhc3RMaW5lID0gbnVtYmVyZWRMaW5lKGxpbmVzLmxlbmd0aCArIDEsIGxhc3RMaW5lKTtcbiAgfVxuICBsaW5lcy5wdXNoKGxhc3RMaW5lKTtcblxuICByZXR1cm4gbGluZXMuam9pbignXFxuJyk7XG59XG5cbmZ1bmN0aW9uIG51bWJlcmVkTGluZShuLCBsaW5lKSB7XG4gIC8vIEdOVSBjYXQgdXNlIHNpeCBwYWQgc3RhcnQgbnVtYmVyICsgdGFiLiBTZWUgaHR0cDovL2xpbmdyb2sub3JnL3hyZWYvY29yZXV0aWxzL3NyYy9jYXQuYyM1N1xuICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9TdHJpbmcvcGFkU3RhcnRcbiAgdmFyIG51bWJlciA9ICgnICAgICAnICsgbikuc2xpY2UoLTYpICsgJ1xcdCc7XG4gIHJldHVybiBudW1iZXIgKyBsaW5lO1xufVxuIiwidmFyIG9zID0gcmVxdWlyZSgnb3MnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2NkJywgX2NkLCB7fSk7XG5cbi8vQFxuLy9AICMjIyBjZChbZGlyXSlcbi8vQFxuLy9AIENoYW5nZXMgdG8gZGlyZWN0b3J5IGBkaXJgIGZvciB0aGUgZHVyYXRpb24gb2YgdGhlIHNjcmlwdC4gQ2hhbmdlcyB0byBob21lXG4vL0AgZGlyZWN0b3J5IGlmIG5vIGFyZ3VtZW50IGlzIHN1cHBsaWVkLlxuZnVuY3Rpb24gX2NkKG9wdGlvbnMsIGRpcikge1xuICBpZiAoIWRpcikgZGlyID0gb3MuaG9tZWRpcigpO1xuXG4gIGlmIChkaXIgPT09ICctJykge1xuICAgIGlmICghcHJvY2Vzcy5lbnYuT0xEUFdEKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ2NvdWxkIG5vdCBmaW5kIHByZXZpb3VzIGRpcmVjdG9yeScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkaXIgPSBwcm9jZXNzLmVudi5PTERQV0Q7XG4gICAgfVxuICB9XG5cbiAgdHJ5IHtcbiAgICB2YXIgY3VyRGlyID0gcHJvY2Vzcy5jd2QoKTtcbiAgICBwcm9jZXNzLmNoZGlyKGRpcik7XG4gICAgcHJvY2Vzcy5lbnYuT0xEUFdEID0gY3VyRGlyO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmcsIGxldCdzIGZpZ3VyZSBvdXQgdGhlIGVycm9yXG4gICAgdmFyIGVycjtcbiAgICB0cnkge1xuICAgICAgY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhkaXIpOyAvLyBpZiB0aGlzIHN1Y2NlZWRzLCBpdCBtdXN0IGJlIHNvbWUgc29ydCBvZiBmaWxlXG4gICAgICBlcnIgPSAnbm90IGEgZGlyZWN0b3J5OiAnICsgZGlyO1xuICAgIH0gY2F0Y2ggKGUyKSB7XG4gICAgICBlcnIgPSAnbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIGRpcjtcbiAgICB9XG4gICAgaWYgKGVycikgY29tbW9uLmVycm9yKGVycik7XG4gIH1cbiAgcmV0dXJuICcnO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfY2Q7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcblxudmFyIFBFUk1TID0gKGZ1bmN0aW9uIChiYXNlKSB7XG4gIHJldHVybiB7XG4gICAgT1RIRVJfRVhFQzogYmFzZS5FWEVDLFxuICAgIE9USEVSX1dSSVRFOiBiYXNlLldSSVRFLFxuICAgIE9USEVSX1JFQUQ6IGJhc2UuUkVBRCxcblxuICAgIEdST1VQX0VYRUM6IGJhc2UuRVhFQyA8PCAzLFxuICAgIEdST1VQX1dSSVRFOiBiYXNlLldSSVRFIDw8IDMsXG4gICAgR1JPVVBfUkVBRDogYmFzZS5SRUFEIDw8IDMsXG5cbiAgICBPV05FUl9FWEVDOiBiYXNlLkVYRUMgPDwgNixcbiAgICBPV05FUl9XUklURTogYmFzZS5XUklURSA8PCA2LFxuICAgIE9XTkVSX1JFQUQ6IGJhc2UuUkVBRCA8PCA2LFxuXG4gICAgLy8gTGl0ZXJhbCBvY3RhbCBudW1iZXJzIGFyZSBhcHBhcmVudGx5IG5vdCBhbGxvd2VkIGluIFwic3RyaWN0XCIgamF2YXNjcmlwdC5cbiAgICBTVElDS1k6IHBhcnNlSW50KCcwMTAwMCcsIDgpLFxuICAgIFNFVEdJRDogcGFyc2VJbnQoJzAyMDAwJywgOCksXG4gICAgU0VUVUlEOiBwYXJzZUludCgnMDQwMDAnLCA4KSxcblxuICAgIFRZUEVfTUFTSzogcGFyc2VJbnQoJzA3NzAwMDAnLCA4KSxcbiAgfTtcbn0oe1xuICBFWEVDOiAxLFxuICBXUklURTogMixcbiAgUkVBRDogNCxcbn0pKTtcblxuY29tbW9uLnJlZ2lzdGVyKCdjaG1vZCcsIF9jaG1vZCwge1xufSk7XG5cbi8vQFxuLy9AICMjIyBjaG1vZChbb3B0aW9ucyxdIG9jdGFsX21vZGUgfHwgb2N0YWxfc3RyaW5nLCBmaWxlKVxuLy9AICMjIyBjaG1vZChbb3B0aW9ucyxdIHN5bWJvbGljX21vZGUsIGZpbGUpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC12YDogb3V0cHV0IGEgZGlhZ25vc3RpYyBmb3IgZXZlcnkgZmlsZSBwcm9jZXNzZWQvL0Bcbi8vQCArIGAtY2A6IGxpa2UgdmVyYm9zZSwgYnV0IHJlcG9ydCBvbmx5IHdoZW4gYSBjaGFuZ2UgaXMgbWFkZS8vQFxuLy9AICsgYC1SYDogY2hhbmdlIGZpbGVzIGFuZCBkaXJlY3RvcmllcyByZWN1cnNpdmVseS8vQFxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgY2htb2QoNzU1LCAnL1VzZXJzL2JyYW5kb24nKTtcbi8vQCBjaG1vZCgnNzU1JywgJy9Vc2Vycy9icmFuZG9uJyk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBjaG1vZCgndSt4JywgJy9Vc2Vycy9icmFuZG9uJyk7XG4vL0AgY2htb2QoJy1SJywgJ2EtdycsICcvVXNlcnMvYnJhbmRvbicpO1xuLy9AIGBgYFxuLy9AXG4vL0AgQWx0ZXJzIHRoZSBwZXJtaXNzaW9ucyBvZiBhIGZpbGUgb3IgZGlyZWN0b3J5IGJ5IGVpdGhlciBzcGVjaWZ5aW5nIHRoZVxuLy9AIGFic29sdXRlIHBlcm1pc3Npb25zIGluIG9jdGFsIGZvcm0gb3IgZXhwcmVzc2luZyB0aGUgY2hhbmdlcyBpbiBzeW1ib2xzLlxuLy9AIFRoaXMgY29tbWFuZCB0cmllcyB0byBtaW1pYyB0aGUgUE9TSVggYmVoYXZpb3IgYXMgbXVjaCBhcyBwb3NzaWJsZS5cbi8vQCBOb3RhYmxlIGV4Y2VwdGlvbnM6XG4vL0Bcbi8vQCArIEluIHN5bWJvbGljIG1vZGVzLCBgYS1yYCBhbmQgYC1yYCBhcmUgaWRlbnRpY2FsLiAgTm8gY29uc2lkZXJhdGlvbiBpc1xuLy9AICAgZ2l2ZW4gdG8gdGhlIGB1bWFza2AuXG4vL0AgKyBUaGVyZSBpcyBubyBcInF1aWV0XCIgb3B0aW9uLCBzaW5jZSBkZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHJ1biBzaWxlbnQuXG5mdW5jdGlvbiBfY2htb2Qob3B0aW9ucywgbW9kZSwgZmlsZVBhdHRlcm4pIHtcbiAgaWYgKCFmaWxlUGF0dGVybikge1xuICAgIGlmIChvcHRpb25zLmxlbmd0aCA+IDAgJiYgb3B0aW9ucy5jaGFyQXQoMCkgPT09ICctJykge1xuICAgICAgLy8gU3BlY2lhbCBjYXNlIHdoZXJlIHRoZSBzcGVjaWZpZWQgZmlsZSBwZXJtaXNzaW9ucyBzdGFydGVkIHdpdGggLSB0byBzdWJ0cmFjdCBwZXJtcywgd2hpY2hcbiAgICAgIC8vIGdldCBwaWNrZWQgdXAgYnkgdGhlIG9wdGlvbiBwYXJzZXIgYXMgY29tbWFuZCBmbGFncy5cbiAgICAgIC8vIElmIHdlIGFyZSBkb3duIGJ5IG9uZSBhcmd1bWVudCBhbmQgb3B0aW9ucyBzdGFydHMgd2l0aCAtLCBzaGlmdCBldmVyeXRoaW5nIG92ZXIuXG4gICAgICBbXS51bnNoaWZ0LmNhbGwoYXJndW1lbnRzLCAnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbW1vbi5lcnJvcignWW91IG11c3Qgc3BlY2lmeSBhIGZpbGUuJyk7XG4gICAgfVxuICB9XG5cbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICdSJzogJ3JlY3Vyc2l2ZScsXG4gICAgJ2MnOiAnY2hhbmdlcycsXG4gICAgJ3YnOiAndmVyYm9zZScsXG4gIH0pO1xuXG4gIGZpbGVQYXR0ZXJuID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuXG4gIHZhciBmaWxlcztcblxuICAvLyBUT0RPOiByZXBsYWNlIHRoaXMgd2l0aCBhIGNhbGwgdG8gY29tbW9uLmV4cGFuZCgpXG4gIGlmIChvcHRpb25zLnJlY3Vyc2l2ZSkge1xuICAgIGZpbGVzID0gW107XG4gICAgZmlsZVBhdHRlcm4uZm9yRWFjaChmdW5jdGlvbiBhZGRGaWxlKGV4cGFuZGVkRmlsZSkge1xuICAgICAgdmFyIHN0YXQgPSBjb21tb24uc3RhdE5vRm9sbG93TGlua3MoZXhwYW5kZWRGaWxlKTtcblxuICAgICAgaWYgKCFzdGF0LmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAgICAgZmlsZXMucHVzaChleHBhbmRlZEZpbGUpO1xuXG4gICAgICAgIGlmIChzdGF0LmlzRGlyZWN0b3J5KCkpIHsgIC8vIGludGVudGlvbmFsbHkgZG9lcyBub3QgZm9sbG93IHN5bWxpbmtzLlxuICAgICAgICAgIGZzLnJlYWRkaXJTeW5jKGV4cGFuZGVkRmlsZSkuZm9yRWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgICAgIGFkZEZpbGUoZXhwYW5kZWRGaWxlICsgJy8nICsgY2hpbGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgZmlsZXMgPSBmaWxlUGF0dGVybjtcbiAgfVxuXG4gIGZpbGVzLmZvckVhY2goZnVuY3Rpb24gaW5uZXJDaG1vZChmaWxlKSB7XG4gICAgZmlsZSA9IHBhdGgucmVzb2x2ZShmaWxlKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZSkpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignRmlsZSBub3QgZm91bmQ6ICcgKyBmaWxlKTtcbiAgICB9XG5cbiAgICAvLyBXaGVuIHJlY3Vyc2luZywgZG9uJ3QgZm9sbG93IHN5bWxpbmtzLlxuICAgIGlmIChvcHRpb25zLnJlY3Vyc2l2ZSAmJiBjb21tb24uc3RhdE5vRm9sbG93TGlua3MoZmlsZSkuaXNTeW1ib2xpY0xpbmsoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBzdGF0ID0gY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhmaWxlKTtcbiAgICB2YXIgaXNEaXIgPSBzdGF0LmlzRGlyZWN0b3J5KCk7XG4gICAgdmFyIHBlcm1zID0gc3RhdC5tb2RlO1xuICAgIHZhciB0eXBlID0gcGVybXMgJiBQRVJNUy5UWVBFX01BU0s7XG5cbiAgICB2YXIgbmV3UGVybXMgPSBwZXJtcztcblxuICAgIGlmIChpc05hTihwYXJzZUludChtb2RlLCA4KSkpIHtcbiAgICAgIC8vIHBhcnNlIG9wdGlvbnNcbiAgICAgIG1vZGUuc3BsaXQoJywnKS5mb3JFYWNoKGZ1bmN0aW9uIChzeW1ib2xpY01vZGUpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSAvKFt1Z29hXSopKFs9XFwrLV0pKFtyd3hYc3RdKikvaTtcbiAgICAgICAgdmFyIG1hdGNoZXMgPSBwYXR0ZXJuLmV4ZWMoc3ltYm9saWNNb2RlKTtcblxuICAgICAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICAgIHZhciBhcHBseVRvID0gbWF0Y2hlc1sxXTtcbiAgICAgICAgICB2YXIgb3BlcmF0b3IgPSBtYXRjaGVzWzJdO1xuICAgICAgICAgIHZhciBjaGFuZ2UgPSBtYXRjaGVzWzNdO1xuXG4gICAgICAgICAgdmFyIGNoYW5nZU93bmVyID0gYXBwbHlUby5pbmRleE9mKCd1JykgIT09IC0xIHx8IGFwcGx5VG8gPT09ICdhJyB8fCBhcHBseVRvID09PSAnJztcbiAgICAgICAgICB2YXIgY2hhbmdlR3JvdXAgPSBhcHBseVRvLmluZGV4T2YoJ2cnKSAhPT0gLTEgfHwgYXBwbHlUbyA9PT0gJ2EnIHx8IGFwcGx5VG8gPT09ICcnO1xuICAgICAgICAgIHZhciBjaGFuZ2VPdGhlciA9IGFwcGx5VG8uaW5kZXhPZignbycpICE9PSAtMSB8fCBhcHBseVRvID09PSAnYScgfHwgYXBwbHlUbyA9PT0gJyc7XG5cbiAgICAgICAgICB2YXIgY2hhbmdlUmVhZCA9IGNoYW5nZS5pbmRleE9mKCdyJykgIT09IC0xO1xuICAgICAgICAgIHZhciBjaGFuZ2VXcml0ZSA9IGNoYW5nZS5pbmRleE9mKCd3JykgIT09IC0xO1xuICAgICAgICAgIHZhciBjaGFuZ2VFeGVjID0gY2hhbmdlLmluZGV4T2YoJ3gnKSAhPT0gLTE7XG4gICAgICAgICAgdmFyIGNoYW5nZUV4ZWNEaXIgPSBjaGFuZ2UuaW5kZXhPZignWCcpICE9PSAtMTtcbiAgICAgICAgICB2YXIgY2hhbmdlU3RpY2t5ID0gY2hhbmdlLmluZGV4T2YoJ3QnKSAhPT0gLTE7XG4gICAgICAgICAgdmFyIGNoYW5nZVNldHVpZCA9IGNoYW5nZS5pbmRleE9mKCdzJykgIT09IC0xO1xuXG4gICAgICAgICAgaWYgKGNoYW5nZUV4ZWNEaXIgJiYgaXNEaXIpIHtcbiAgICAgICAgICAgIGNoYW5nZUV4ZWMgPSB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBtYXNrID0gMDtcbiAgICAgICAgICBpZiAoY2hhbmdlT3duZXIpIHtcbiAgICAgICAgICAgIG1hc2sgfD0gKGNoYW5nZVJlYWQgPyBQRVJNUy5PV05FUl9SRUFEIDogMCkgKyAoY2hhbmdlV3JpdGUgPyBQRVJNUy5PV05FUl9XUklURSA6IDApICsgKGNoYW5nZUV4ZWMgPyBQRVJNUy5PV05FUl9FWEVDIDogMCkgKyAoY2hhbmdlU2V0dWlkID8gUEVSTVMuU0VUVUlEIDogMCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjaGFuZ2VHcm91cCkge1xuICAgICAgICAgICAgbWFzayB8PSAoY2hhbmdlUmVhZCA/IFBFUk1TLkdST1VQX1JFQUQgOiAwKSArIChjaGFuZ2VXcml0ZSA/IFBFUk1TLkdST1VQX1dSSVRFIDogMCkgKyAoY2hhbmdlRXhlYyA/IFBFUk1TLkdST1VQX0VYRUMgOiAwKSArIChjaGFuZ2VTZXR1aWQgPyBQRVJNUy5TRVRHSUQgOiAwKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNoYW5nZU90aGVyKSB7XG4gICAgICAgICAgICBtYXNrIHw9IChjaGFuZ2VSZWFkID8gUEVSTVMuT1RIRVJfUkVBRCA6IDApICsgKGNoYW5nZVdyaXRlID8gUEVSTVMuT1RIRVJfV1JJVEUgOiAwKSArIChjaGFuZ2VFeGVjID8gUEVSTVMuT1RIRVJfRVhFQyA6IDApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFN0aWNreSBiaXQgaXMgc3BlY2lhbCAtIGl0J3Mgbm90IHRpZWQgdG8gdXNlciwgZ3JvdXAgb3Igb3RoZXIuXG4gICAgICAgICAgaWYgKGNoYW5nZVN0aWNreSkge1xuICAgICAgICAgICAgbWFzayB8PSBQRVJNUy5TVElDS1k7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgICAgICAgY2FzZSAnKyc6XG4gICAgICAgICAgICAgIG5ld1Blcm1zIHw9IG1hc2s7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlICctJzpcbiAgICAgICAgICAgICAgbmV3UGVybXMgJj0gfm1hc2s7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlICc9JzpcbiAgICAgICAgICAgICAgbmV3UGVybXMgPSB0eXBlICsgbWFzaztcblxuICAgICAgICAgICAgICAvLyBBY2NvcmRpbmcgdG8gUE9TSVgsIHdoZW4gdXNpbmcgPSB0byBleHBsaWNpdGx5IHNldCB0aGVcbiAgICAgICAgICAgICAgLy8gcGVybWlzc2lvbnMsIHNldHVpZCBhbmQgc2V0Z2lkIGNhbiBuZXZlciBiZSBjbGVhcmVkLlxuICAgICAgICAgICAgICBpZiAoY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgICAgICAgbmV3UGVybXMgfD0gKFBFUk1TLlNFVFVJRCArIFBFUk1TLlNFVEdJRCkgJiBwZXJtcztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGNvbW1vbi5lcnJvcignQ291bGQgbm90IHJlY29nbml6ZSBvcGVyYXRvcjogYCcgKyBvcGVyYXRvciArICdgJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZmlsZSArICcgLT4gJyArIG5ld1Blcm1zLnRvU3RyaW5nKDgpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocGVybXMgIT09IG5ld1Blcm1zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMudmVyYm9zZSAmJiBvcHRpb25zLmNoYW5nZXMpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coZmlsZSArICcgLT4gJyArIG5ld1Blcm1zLnRvU3RyaW5nKDgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZzLmNobW9kU3luYyhmaWxlLCBuZXdQZXJtcyk7XG4gICAgICAgICAgICBwZXJtcyA9IG5ld1Blcm1zOyAvLyBmb3IgdGhlIG5leHQgcm91bmQgb2YgY2hhbmdlcyFcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29tbW9uLmVycm9yKCdJbnZhbGlkIHN5bWJvbGljIG1vZGUgY2hhbmdlOiAnICsgc3ltYm9saWNNb2RlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHRoZXkgZ2F2ZSB1cyBhIGZ1bGwgbnVtYmVyXG4gICAgICBuZXdQZXJtcyA9IHR5cGUgKyBwYXJzZUludChtb2RlLCA4KTtcblxuICAgICAgLy8gUE9TSVggcnVsZXMgYXJlIHRoYXQgc2V0dWlkIGFuZCBzZXRnaWQgY2FuIG9ubHkgYmUgYWRkZWQgdXNpbmcgbnVtZXJpY1xuICAgICAgLy8gZm9ybSwgYnV0IG5vdCBjbGVhcmVkLlxuICAgICAgaWYgKGNvbW1vbi5zdGF0Rm9sbG93TGlua3MoZmlsZSkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBuZXdQZXJtcyB8PSAoUEVSTVMuU0VUVUlEICsgUEVSTVMuU0VUR0lEKSAmIHBlcm1zO1xuICAgICAgfVxuXG4gICAgICBmcy5jaG1vZFN5bmMoZmlsZSwgbmV3UGVybXMpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiAnJztcbn1cbm1vZHVsZS5leHBvcnRzID0gX2NobW9kO1xuIiwiLy8gSWdub3JlIHdhcm5pbmcgYWJvdXQgJ25ldyBTdHJpbmcoKSdcbi8qIGVzbGludCBuby1uZXctd3JhcHBlcnM6IDAgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIG9zID0gcmVxdWlyZSgnb3MnKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgZ2xvYiA9IHJlcXVpcmUoJ2dsb2InKTtcbnZhciBzaGVsbCA9IHJlcXVpcmUoJy4uJyk7XG5cbnZhciBzaGVsbE1ldGhvZHMgPSBPYmplY3QuY3JlYXRlKHNoZWxsKTtcblxuZXhwb3J0cy5leHRlbmQgPSBPYmplY3QuYXNzaWduO1xuXG4vLyBDaGVjayBpZiB3ZSdyZSBydW5uaW5nIHVuZGVyIGVsZWN0cm9uXG52YXIgaXNFbGVjdHJvbiA9IEJvb2xlYW4ocHJvY2Vzcy52ZXJzaW9ucy5lbGVjdHJvbik7XG5cbi8vIE1vZHVsZSBnbG9iYWxzIChhc3N1bWUgbm8gZXhlY1BhdGggYnkgZGVmYXVsdClcbnZhciBERUZBVUxUX0NPTkZJRyA9IHtcbiAgZmF0YWw6IGZhbHNlLFxuICBnbG9iT3B0aW9uczoge30sXG4gIG1heGRlcHRoOiAyNTUsXG4gIG5vZ2xvYjogZmFsc2UsXG4gIHNpbGVudDogZmFsc2UsXG4gIHZlcmJvc2U6IGZhbHNlLFxuICBleGVjUGF0aDogbnVsbCxcbiAgYnVmTGVuZ3RoOiA2NCAqIDEwMjQsIC8vIDY0S0Jcbn07XG5cbnZhciBjb25maWcgPSB7XG4gIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBERUZBVUxUX0NPTkZJRyk7XG4gICAgaWYgKCFpc0VsZWN0cm9uKSB7XG4gICAgICB0aGlzLmV4ZWNQYXRoID0gcHJvY2Vzcy5leGVjUGF0aDtcbiAgICB9XG4gIH0sXG4gIHJlc2V0Rm9yVGVzdGluZzogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVzZXQoKTtcbiAgICB0aGlzLnNpbGVudCA9IHRydWU7XG4gIH0sXG59O1xuXG5jb25maWcucmVzZXQoKTtcbmV4cG9ydHMuY29uZmlnID0gY29uZmlnO1xuXG4vLyBOb3RlOiBjb21tYW5kcyBzaG91bGQgZ2VuZXJhbGx5IGNvbnNpZGVyIHRoZXNlIGFzIHJlYWQtb25seSB2YWx1ZXMuXG52YXIgc3RhdGUgPSB7XG4gIGVycm9yOiBudWxsLFxuICBlcnJvckNvZGU6IDAsXG4gIGN1cnJlbnRDbWQ6ICdzaGVsbC5qcycsXG59O1xuZXhwb3J0cy5zdGF0ZSA9IHN0YXRlO1xuXG5kZWxldGUgcHJvY2Vzcy5lbnYuT0xEUFdEOyAvLyBpbml0aWFsbHksIHRoZXJlJ3Mgbm8gcHJldmlvdXMgZGlyZWN0b3J5XG5cbi8vIFJlbGlhYmx5IHRlc3QgaWYgc29tZXRoaW5nIGlzIGFueSBzb3J0IG9mIGphdmFzY3JpcHQgb2JqZWN0XG5mdW5jdGlvbiBpc09iamVjdChhKSB7XG4gIHJldHVybiB0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiYgYSAhPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gbG9nKCkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAoIWNvbmZpZy5zaWxlbnQpIHtcbiAgICBjb25zb2xlLmVycm9yLmFwcGx5KGNvbnNvbGUsIGFyZ3VtZW50cyk7XG4gIH1cbn1cbmV4cG9ydHMubG9nID0gbG9nO1xuXG4vLyBDb252ZXJ0cyBzdHJpbmdzIHRvIGJlIGVxdWl2YWxlbnQgYWNyb3NzIGFsbCBwbGF0Zm9ybXMuIFByaW1hcmlseSByZXNwb25zaWJsZVxuLy8gZm9yIG1ha2luZyBzdXJlIHdlIHVzZSAnLycgaW5zdGVhZCBvZiAnXFwnIGFzIHBhdGggc2VwYXJhdG9ycywgYnV0IHRoaXMgbWF5IGJlXG4vLyBleHBhbmRlZCBpbiB0aGUgZnV0dXJlIGlmIG5lY2Vzc2FyeVxuZnVuY3Rpb24gY29udmVydEVycm9yT3V0cHV0KG1zZykge1xuICBpZiAodHlwZW9mIG1zZyAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnB1dCBtdXN0IGJlIGEgc3RyaW5nJyk7XG4gIH1cbiAgcmV0dXJuIG1zZy5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG59XG5leHBvcnRzLmNvbnZlcnRFcnJvck91dHB1dCA9IGNvbnZlcnRFcnJvck91dHB1dDtcblxuLy8gU2hvd3MgZXJyb3IgbWVzc2FnZS4gVGhyb3dzIGlmIGNvbmZpZy5mYXRhbCBpcyB0cnVlXG5mdW5jdGlvbiBlcnJvcihtc2csIF9jb2RlLCBvcHRpb25zKSB7XG4gIC8vIFZhbGlkYXRlIGlucHV0XG4gIGlmICh0eXBlb2YgbXNnICE9PSAnc3RyaW5nJykgdGhyb3cgbmV3IEVycm9yKCdtc2cgbXVzdCBiZSBhIHN0cmluZycpO1xuXG4gIHZhciBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY29udGludWU6IGZhbHNlLFxuICAgIGNvZGU6IDEsXG4gICAgcHJlZml4OiBzdGF0ZS5jdXJyZW50Q21kICsgJzogJyxcbiAgICBzaWxlbnQ6IGZhbHNlLFxuICB9O1xuXG4gIGlmICh0eXBlb2YgX2NvZGUgPT09ICdudW1iZXInICYmIGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgb3B0aW9ucy5jb2RlID0gX2NvZGU7XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoX2NvZGUpKSB7IC8vIG5vICdjb2RlJ1xuICAgIG9wdGlvbnMgPSBfY29kZTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgX2NvZGUgPT09ICdudW1iZXInKSB7IC8vIG5vICdvcHRpb25zJ1xuICAgIG9wdGlvbnMgPSB7IGNvZGU6IF9jb2RlIH07XG4gIH0gZWxzZSBpZiAodHlwZW9mIF9jb2RlICE9PSAnbnVtYmVyJykgeyAvLyBvbmx5ICdtc2cnXG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX09QVElPTlMsIG9wdGlvbnMpO1xuXG4gIGlmICghc3RhdGUuZXJyb3JDb2RlKSBzdGF0ZS5lcnJvckNvZGUgPSBvcHRpb25zLmNvZGU7XG5cbiAgdmFyIGxvZ0VudHJ5ID0gY29udmVydEVycm9yT3V0cHV0KG9wdGlvbnMucHJlZml4ICsgbXNnKTtcbiAgc3RhdGUuZXJyb3IgPSBzdGF0ZS5lcnJvciA/IHN0YXRlLmVycm9yICsgJ1xcbicgOiAnJztcbiAgc3RhdGUuZXJyb3IgKz0gbG9nRW50cnk7XG5cbiAgLy8gVGhyb3cgYW4gZXJyb3IsIG9yIGxvZyB0aGUgZW50cnlcbiAgaWYgKGNvbmZpZy5mYXRhbCkgdGhyb3cgbmV3IEVycm9yKGxvZ0VudHJ5KTtcbiAgaWYgKG1zZy5sZW5ndGggPiAwICYmICFvcHRpb25zLnNpbGVudCkgbG9nKGxvZ0VudHJ5KTtcblxuICBpZiAoIW9wdGlvbnMuY29udGludWUpIHtcbiAgICB0aHJvdyB7XG4gICAgICBtc2c6ICdlYXJseUV4aXQnLFxuICAgICAgcmV0VmFsdWU6IChuZXcgU2hlbGxTdHJpbmcoJycsIHN0YXRlLmVycm9yLCBzdGF0ZS5lcnJvckNvZGUpKSxcbiAgICB9O1xuICB9XG59XG5leHBvcnRzLmVycm9yID0gZXJyb3I7XG5cbi8vQFxuLy9AICMjIyBTaGVsbFN0cmluZyhzdHIpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCB2YXIgZm9vID0gU2hlbGxTdHJpbmcoJ2hlbGxvIHdvcmxkJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBUdXJucyBhIHJlZ3VsYXIgc3RyaW5nIGludG8gYSBzdHJpbmctbGlrZSBvYmplY3Qgc2ltaWxhciB0byB3aGF0IGVhY2hcbi8vQCBjb21tYW5kIHJldHVybnMuIFRoaXMgaGFzIHNwZWNpYWwgbWV0aG9kcywgbGlrZSBgLnRvKClgIGFuZCBgLnRvRW5kKClgLlxuZnVuY3Rpb24gU2hlbGxTdHJpbmcoc3Rkb3V0LCBzdGRlcnIsIGNvZGUpIHtcbiAgdmFyIHRoYXQ7XG4gIGlmIChzdGRvdXQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIHRoYXQgPSBzdGRvdXQ7XG4gICAgdGhhdC5zdGRvdXQgPSBzdGRvdXQuam9pbignXFxuJyk7XG4gICAgaWYgKHN0ZG91dC5sZW5ndGggPiAwKSB0aGF0LnN0ZG91dCArPSAnXFxuJztcbiAgfSBlbHNlIHtcbiAgICB0aGF0ID0gbmV3IFN0cmluZyhzdGRvdXQpO1xuICAgIHRoYXQuc3Rkb3V0ID0gc3Rkb3V0O1xuICB9XG4gIHRoYXQuc3RkZXJyID0gc3RkZXJyO1xuICB0aGF0LmNvZGUgPSBjb2RlO1xuICAvLyBBIGxpc3Qgb2YgYWxsIGNvbW1hbmRzIHRoYXQgY2FuIGFwcGVhciBvbiB0aGUgcmlnaHQtaGFuZCBzaWRlIG9mIGEgcGlwZVxuICAvLyAocG9wdWxhdGVkIGJ5IGNhbGxzIHRvIGNvbW1vbi53cmFwKCkpXG4gIHBpcGVNZXRob2RzLmZvckVhY2goZnVuY3Rpb24gKGNtZCkge1xuICAgIHRoYXRbY21kXSA9IHNoZWxsTWV0aG9kc1tjbWRdLmJpbmQodGhhdCk7XG4gIH0pO1xuICByZXR1cm4gdGhhdDtcbn1cblxuZXhwb3J0cy5TaGVsbFN0cmluZyA9IFNoZWxsU3RyaW5nO1xuXG4vLyBSZXR1cm5zIHsnYWxpY2UnOiB0cnVlLCAnYm9iJzogZmFsc2V9IHdoZW4gcGFzc2VkIGEgc3RyaW5nIGFuZCBkaWN0aW9uYXJ5IGFzIGZvbGxvd3M6XG4vLyAgIHBhcnNlT3B0aW9ucygnLWEnLCB7J2EnOidhbGljZScsICdiJzonYm9iJ30pO1xuLy8gUmV0dXJucyB7J3JlZmVyZW5jZSc6ICdzdHJpbmctdmFsdWUnLCAnYm9iJzogZmFsc2V9IHdoZW4gcGFzc2VkIHR3byBkaWN0aW9uYXJpZXMgb2YgdGhlIGZvcm06XG4vLyAgIHBhcnNlT3B0aW9ucyh7Jy1yJzogJ3N0cmluZy12YWx1ZSd9LCB7J3InOidyZWZlcmVuY2UnLCAnYic6J2JvYid9KTtcbi8vIFRocm93cyBhbiBlcnJvciB3aGVuIHBhc3NlZCBhIHN0cmluZyB0aGF0IGRvZXMgbm90IHN0YXJ0IHdpdGggJy0nOlxuLy8gICBwYXJzZU9wdGlvbnMoJ2EnLCB7J2EnOidhbGljZSd9KTsgLy8gdGhyb3dzXG5mdW5jdGlvbiBwYXJzZU9wdGlvbnMob3B0LCBtYXAsIGVycm9yT3B0aW9ucykge1xuICAvLyBWYWxpZGF0ZSBpbnB1dFxuICBpZiAodHlwZW9mIG9wdCAhPT0gJ3N0cmluZycgJiYgIWlzT2JqZWN0KG9wdCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ29wdGlvbnMgbXVzdCBiZSBzdHJpbmdzIG9yIGtleS12YWx1ZSBwYWlycycpO1xuICB9IGVsc2UgaWYgKCFpc09iamVjdChtYXApKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwYXJzZU9wdGlvbnMoKSBpbnRlcm5hbCBlcnJvcjogbWFwIG11c3QgYmUgYW4gb2JqZWN0Jyk7XG4gIH0gZWxzZSBpZiAoZXJyb3JPcHRpb25zICYmICFpc09iamVjdChlcnJvck9wdGlvbnMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwYXJzZU9wdGlvbnMoKSBpbnRlcm5hbCBlcnJvcjogZXJyb3JPcHRpb25zIG11c3QgYmUgb2JqZWN0Jyk7XG4gIH1cblxuICBpZiAob3B0ID09PSAnLS0nKSB7XG4gICAgLy8gVGhpcyBtZWFucyB0aGVyZSBhcmUgbm8gb3B0aW9ucy5cbiAgICByZXR1cm4ge307XG4gIH1cblxuICAvLyBBbGwgb3B0aW9ucyBhcmUgZmFsc2UgYnkgZGVmYXVsdFxuICB2YXIgb3B0aW9ucyA9IHt9O1xuICBPYmplY3Qua2V5cyhtYXApLmZvckVhY2goZnVuY3Rpb24gKGxldHRlcikge1xuICAgIHZhciBvcHROYW1lID0gbWFwW2xldHRlcl07XG4gICAgaWYgKG9wdE5hbWVbMF0gIT09ICchJykge1xuICAgICAgb3B0aW9uc1tvcHROYW1lXSA9IGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKG9wdCA9PT0gJycpIHJldHVybiBvcHRpb25zOyAvLyBkZWZhdWx0c1xuXG4gIGlmICh0eXBlb2Ygb3B0ID09PSAnc3RyaW5nJykge1xuICAgIGlmIChvcHRbMF0gIT09ICctJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiT3B0aW9ucyBzdHJpbmcgbXVzdCBzdGFydCB3aXRoIGEgJy0nXCIpO1xuICAgIH1cblxuICAgIC8vIGUuZy4gY2hhcnMgPSBbJ1InLCAnZiddXG4gICAgdmFyIGNoYXJzID0gb3B0LnNsaWNlKDEpLnNwbGl0KCcnKTtcblxuICAgIGNoYXJzLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgIGlmIChjIGluIG1hcCkge1xuICAgICAgICB2YXIgb3B0aW9uTmFtZSA9IG1hcFtjXTtcbiAgICAgICAgaWYgKG9wdGlvbk5hbWVbMF0gPT09ICchJykge1xuICAgICAgICAgIG9wdGlvbnNbb3B0aW9uTmFtZS5zbGljZSgxKV0gPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcHRpb25zW29wdGlvbk5hbWVdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3IoJ29wdGlvbiBub3QgcmVjb2duaXplZDogJyArIGMsIGVycm9yT3B0aW9ucyB8fCB7fSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSB7IC8vIG9wdCBpcyBhbiBPYmplY3RcbiAgICBPYmplY3Qua2V5cyhvcHQpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgLy8ga2V5IGlzIGEgc3RyaW5nIG9mIHRoZSBmb3JtICctcicsICctZCcsIGV0Yy5cbiAgICAgIHZhciBjID0ga2V5WzFdO1xuICAgICAgaWYgKGMgaW4gbWFwKSB7XG4gICAgICAgIHZhciBvcHRpb25OYW1lID0gbWFwW2NdO1xuICAgICAgICBvcHRpb25zW29wdGlvbk5hbWVdID0gb3B0W2tleV07IC8vIGFzc2lnbiB0aGUgZ2l2ZW4gdmFsdWVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yKCdvcHRpb24gbm90IHJlY29nbml6ZWQ6ICcgKyBjLCBlcnJvck9wdGlvbnMgfHwge30pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIHJldHVybiBvcHRpb25zO1xufVxuZXhwb3J0cy5wYXJzZU9wdGlvbnMgPSBwYXJzZU9wdGlvbnM7XG5cbi8vIEV4cGFuZHMgd2lsZGNhcmRzIHdpdGggbWF0Y2hpbmcgKGllLiBleGlzdGluZykgZmlsZSBuYW1lcy5cbi8vIEZvciBleGFtcGxlOlxuLy8gICBleHBhbmQoWydmaWxlKi5qcyddKSA9IFsnZmlsZTEuanMnLCAnZmlsZTIuanMnLCAuLi5dXG4vLyAgIChpZiB0aGUgZmlsZXMgJ2ZpbGUxLmpzJywgJ2ZpbGUyLmpzJywgZXRjLCBleGlzdCBpbiB0aGUgY3VycmVudCBkaXIpXG5mdW5jdGlvbiBleHBhbmQobGlzdCkge1xuICBpZiAoIUFycmF5LmlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtdXN0IGJlIGFuIGFycmF5Jyk7XG4gIH1cbiAgdmFyIGV4cGFuZGVkID0gW107XG4gIGxpc3QuZm9yRWFjaChmdW5jdGlvbiAobGlzdEVsKSB7XG4gICAgLy8gRG9uJ3QgZXhwYW5kIG5vbi1zdHJpbmdzXG4gICAgaWYgKHR5cGVvZiBsaXN0RWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICBleHBhbmRlZC5wdXNoKGxpc3RFbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciByZXQ7XG4gICAgICB0cnkge1xuICAgICAgICByZXQgPSBnbG9iLnN5bmMobGlzdEVsLCBjb25maWcuZ2xvYk9wdGlvbnMpO1xuICAgICAgICAvLyBpZiBub3RoaW5nIG1hdGNoZWQsIGludGVycHJldCB0aGUgc3RyaW5nIGxpdGVyYWxseVxuICAgICAgICByZXQgPSByZXQubGVuZ3RoID4gMCA/IHJldCA6IFtsaXN0RWxdO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpZiBnbG9iIGZhaWxzLCBpbnRlcnByZXQgdGhlIHN0cmluZyBsaXRlcmFsbHlcbiAgICAgICAgcmV0ID0gW2xpc3RFbF07XG4gICAgICB9XG4gICAgICBleHBhbmRlZCA9IGV4cGFuZGVkLmNvbmNhdChyZXQpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBleHBhbmRlZDtcbn1cbmV4cG9ydHMuZXhwYW5kID0gZXhwYW5kO1xuXG4vLyBOb3JtYWxpemVzIEJ1ZmZlciBjcmVhdGlvbiwgdXNpbmcgQnVmZmVyLmFsbG9jIGlmIHBvc3NpYmxlLlxuLy8gQWxzbyBwcm92aWRlcyBhIGdvb2QgZGVmYXVsdCBidWZmZXIgbGVuZ3RoIGZvciBtb3N0IHVzZSBjYXNlcy5cbnZhciBidWZmZXIgPSB0eXBlb2YgQnVmZmVyLmFsbG9jID09PSAnZnVuY3Rpb24nID9cbiAgZnVuY3Rpb24gKGxlbikge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2MobGVuIHx8IGNvbmZpZy5idWZMZW5ndGgpO1xuICB9IDpcbiAgZnVuY3Rpb24gKGxlbikge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGxlbiB8fCBjb25maWcuYnVmTGVuZ3RoKTtcbiAgfTtcbmV4cG9ydHMuYnVmZmVyID0gYnVmZmVyO1xuXG4vLyBOb3JtYWxpemVzIF91bmxpbmtTeW5jKCkgYWNyb3NzIHBsYXRmb3JtcyB0byBtYXRjaCBVbml4IGJlaGF2aW9yLCBpLmUuXG4vLyBmaWxlIGNhbiBiZSB1bmxpbmtlZCBldmVuIGlmIGl0J3MgcmVhZC1vbmx5LCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2pveWVudC9ub2RlL2lzc3Vlcy8zMDA2XG5mdW5jdGlvbiB1bmxpbmtTeW5jKGZpbGUpIHtcbiAgdHJ5IHtcbiAgICBmcy51bmxpbmtTeW5jKGZpbGUpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gVHJ5IHRvIG92ZXJyaWRlIGZpbGUgcGVybWlzc2lvblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgaWYgKGUuY29kZSA9PT0gJ0VQRVJNJykge1xuICAgICAgZnMuY2htb2RTeW5jKGZpbGUsICcwNjY2Jyk7XG4gICAgICBmcy51bmxpbmtTeW5jKGZpbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0cy51bmxpbmtTeW5jID0gdW5saW5rU3luYztcblxuLy8gd3JhcHBlcnMgYXJvdW5kIGNvbW1vbi5zdGF0Rm9sbG93TGlua3MgYW5kIGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyB0aGF0IGNsYXJpZnkgaW50ZW50XG4vLyBhbmQgaW1wcm92ZSByZWFkYWJpbGl0eVxuZnVuY3Rpb24gc3RhdEZvbGxvd0xpbmtzKCkge1xuICByZXR1cm4gZnMuc3RhdFN5bmMuYXBwbHkoZnMsIGFyZ3VtZW50cyk7XG59XG5leHBvcnRzLnN0YXRGb2xsb3dMaW5rcyA9IHN0YXRGb2xsb3dMaW5rcztcblxuZnVuY3Rpb24gc3RhdE5vRm9sbG93TGlua3MoKSB7XG4gIHJldHVybiBmcy5sc3RhdFN5bmMuYXBwbHkoZnMsIGFyZ3VtZW50cyk7XG59XG5leHBvcnRzLnN0YXROb0ZvbGxvd0xpbmtzID0gc3RhdE5vRm9sbG93TGlua3M7XG5cbi8vIGUuZy4gJ3NoZWxsanNfYTVmMTg1ZDA0NDNjYS4uLidcbmZ1bmN0aW9uIHJhbmRvbUZpbGVOYW1lKCkge1xuICBmdW5jdGlvbiByYW5kb21IYXNoKGNvdW50KSB7XG4gICAgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoMTYgKiBNYXRoLnJhbmRvbSgpLCAxMCkudG9TdHJpbmcoMTYpO1xuICAgIH1cbiAgICB2YXIgaGFzaCA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgaGFzaCArPSByYW5kb21IYXNoKDEpO1xuICAgIH1cbiAgICByZXR1cm4gaGFzaDtcbiAgfVxuXG4gIHJldHVybiAnc2hlbGxqc18nICsgcmFuZG9tSGFzaCgyMCk7XG59XG5leHBvcnRzLnJhbmRvbUZpbGVOYW1lID0gcmFuZG9tRmlsZU5hbWU7XG5cbi8vIENvbW1vbiB3cmFwcGVyIGZvciBhbGwgVW5peC1saWtlIGNvbW1hbmRzIHRoYXQgcGVyZm9ybXMgZ2xvYiBleHBhbnNpb24sXG4vLyBjb21tYW5kLWxvZ2dpbmcsIGFuZCBvdGhlciBuaWNlIHRoaW5nc1xuZnVuY3Rpb24gd3JhcChjbWQsIGZuLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciByZXRWYWx1ZSA9IG51bGw7XG5cbiAgICBzdGF0ZS5jdXJyZW50Q21kID0gY21kO1xuICAgIHN0YXRlLmVycm9yID0gbnVsbDtcbiAgICBzdGF0ZS5lcnJvckNvZGUgPSAwO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuXG4gICAgICAvLyBMb2cgdGhlIGNvbW1hbmQgdG8gc3RkZXJyLCBpZiBhcHByb3ByaWF0ZVxuICAgICAgaWYgKGNvbmZpZy52ZXJib3NlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IuYXBwbHkoY29uc29sZSwgW2NtZF0uY29uY2F0KGFyZ3MpKTtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhpcyBpcyBjb21pbmcgZnJvbSBhIHBpcGUsIGxldCdzIHNldCB0aGUgcGlwZWRWYWx1ZSAob3RoZXJ3aXNlLCBzZXRcbiAgICAgIC8vIGl0IHRvIHRoZSBlbXB0eSBzdHJpbmcpXG4gICAgICBzdGF0ZS5waXBlZFZhbHVlID0gKHRoaXMgJiYgdHlwZW9mIHRoaXMuc3Rkb3V0ID09PSAnc3RyaW5nJykgPyB0aGlzLnN0ZG91dCA6ICcnO1xuXG4gICAgICBpZiAob3B0aW9ucy51bml4ID09PSBmYWxzZSkgeyAvLyB0aGlzIGJyYW5jaCBpcyBmb3IgZXhlYygpXG4gICAgICAgIHJldFZhbHVlID0gZm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICB9IGVsc2UgeyAvLyBhbmQgdGhpcyBicmFuY2ggaXMgZm9yIGV2ZXJ5dGhpbmcgZWxzZVxuICAgICAgICBpZiAoaXNPYmplY3QoYXJnc1swXSkgJiYgYXJnc1swXS5jb25zdHJ1Y3Rvci5uYW1lID09PSAnT2JqZWN0Jykge1xuICAgICAgICAgIC8vIGEgbm8tb3AsIGFsbG93aW5nIHRoZSBzeW50YXggYHRvdWNoKHsnLXInOiBmaWxlfSwgLi4uKWBcbiAgICAgICAgfSBlbHNlIGlmIChhcmdzLmxlbmd0aCA9PT0gMCB8fCB0eXBlb2YgYXJnc1swXSAhPT0gJ3N0cmluZycgfHwgYXJnc1swXS5sZW5ndGggPD0gMSB8fCBhcmdzWzBdWzBdICE9PSAnLScpIHtcbiAgICAgICAgICBhcmdzLnVuc2hpZnQoJycpOyAvLyBvbmx5IGFkZCBkdW1teSBvcHRpb24gaWYgJy1vcHRpb24nIG5vdCBhbHJlYWR5IHByZXNlbnRcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZsYXR0ZW4gb3V0IGFycmF5cyB0aGF0IGFyZSBhcmd1bWVudHMsIHRvIG1ha2UgdGhlIHN5bnRheDpcbiAgICAgICAgLy8gICAgYGNwKFtmaWxlMSwgZmlsZTIsIGZpbGUzXSwgZGVzdCk7YFxuICAgICAgICAvLyBlcXVpdmFsZW50IHRvOlxuICAgICAgICAvLyAgICBgY3AoZmlsZTEsIGZpbGUyLCBmaWxlMywgZGVzdCk7YFxuICAgICAgICBhcmdzID0gYXJncy5yZWR1Y2UoZnVuY3Rpb24gKGFjY3VtLCBjdXIpIHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShjdXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gYWNjdW0uY29uY2F0KGN1cik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFjY3VtLnB1c2goY3VyKTtcbiAgICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICAgIH0sIFtdKTtcblxuICAgICAgICAvLyBDb252ZXJ0IFNoZWxsU3RyaW5ncyAoYmFzaWNhbGx5IGp1c3QgU3RyaW5nIG9iamVjdHMpIHRvIHJlZ3VsYXIgc3RyaW5nc1xuICAgICAgICBhcmdzID0gYXJncy5tYXAoZnVuY3Rpb24gKGFyZykge1xuICAgICAgICAgIGlmIChpc09iamVjdChhcmcpICYmIGFyZy5jb25zdHJ1Y3Rvci5uYW1lID09PSAnU3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGFyZy50b1N0cmluZygpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYXJnO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeHBhbmQgdGhlICd+JyBpZiBhcHByb3ByaWF0ZVxuICAgICAgICB2YXIgaG9tZURpciA9IG9zLmhvbWVkaXIoKTtcbiAgICAgICAgYXJncyA9IGFyZ3MubWFwKGZ1bmN0aW9uIChhcmcpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgJiYgYXJnLnNsaWNlKDAsIDIpID09PSAnfi8nIHx8IGFyZyA9PT0gJ34nKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJnLnJlcGxhY2UoL15+LywgaG9tZURpcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhcmc7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFBlcmZvcm0gZ2xvYi1leHBhbnNpb24gb24gYWxsIGFyZ3VtZW50cyBhZnRlciBnbG9iU3RhcnQsIGJ1dCBwcmVzZXJ2ZVxuICAgICAgICAvLyB0aGUgYXJndW1lbnRzIGJlZm9yZSBpdCAobGlrZSByZWdleGVzIGZvciBzZWQgYW5kIGdyZXApXG4gICAgICAgIGlmICghY29uZmlnLm5vZ2xvYiAmJiBvcHRpb25zLmFsbG93R2xvYmJpbmcgPT09IHRydWUpIHtcbiAgICAgICAgICBhcmdzID0gYXJncy5zbGljZSgwLCBvcHRpb25zLmdsb2JTdGFydCkuY29uY2F0KGV4cGFuZChhcmdzLnNsaWNlKG9wdGlvbnMuZ2xvYlN0YXJ0KSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBwYXJzZSBvcHRpb25zIGlmIG9wdGlvbnMgYXJlIHByb3ZpZGVkXG4gICAgICAgICAgaWYgKGlzT2JqZWN0KG9wdGlvbnMuY21kT3B0aW9ucykpIHtcbiAgICAgICAgICAgIGFyZ3NbMF0gPSBwYXJzZU9wdGlvbnMoYXJnc1swXSwgb3B0aW9ucy5jbWRPcHRpb25zKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXRWYWx1ZSA9IGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgICBpZiAoZS5tc2cgPT09ICdlYXJseUV4aXQnKSB7XG4gICAgICAgICAgICByZXRWYWx1ZSA9IGUucmV0VmFsdWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGU7IC8vIHRoaXMgaXMgcHJvYmFibHkgYSBidWcgdGhhdCBzaG91bGQgYmUgdGhyb3duIHVwIHRoZSBjYWxsIHN0YWNrXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGlmICghc3RhdGUuZXJyb3IpIHtcbiAgICAgICAgLy8gSWYgc3RhdGUuZXJyb3IgaGFzbid0IGJlZW4gc2V0IGl0J3MgYW4gZXJyb3IgdGhyb3duIGJ5IE5vZGUsIG5vdCB1cyAtIHByb2JhYmx5IGEgYnVnLi4uXG4gICAgICAgIGUubmFtZSA9ICdTaGVsbEpTSW50ZXJuYWxFcnJvcic7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLmZhdGFsKSB0aHJvdyBlO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLndyYXBPdXRwdXQgJiZcbiAgICAgICAgKHR5cGVvZiByZXRWYWx1ZSA9PT0gJ3N0cmluZycgfHwgQXJyYXkuaXNBcnJheShyZXRWYWx1ZSkpKSB7XG4gICAgICByZXRWYWx1ZSA9IG5ldyBTaGVsbFN0cmluZyhyZXRWYWx1ZSwgc3RhdGUuZXJyb3IsIHN0YXRlLmVycm9yQ29kZSk7XG4gICAgfVxuXG4gICAgc3RhdGUuY3VycmVudENtZCA9ICdzaGVsbC5qcyc7XG4gICAgcmV0dXJuIHJldFZhbHVlO1xuICB9O1xufSAvLyB3cmFwXG5leHBvcnRzLndyYXAgPSB3cmFwO1xuXG4vLyBUaGlzIHJldHVybnMgYWxsIHRoZSBpbnB1dCB0aGF0IGlzIHBpcGVkIGludG8gdGhlIGN1cnJlbnQgY29tbWFuZCAob3IgdGhlXG4vLyBlbXB0eSBzdHJpbmcsIGlmIHRoaXMgaXNuJ3Qgb24gdGhlIHJpZ2h0LWhhbmQgc2lkZSBvZiBhIHBpcGVcbmZ1bmN0aW9uIF9yZWFkRnJvbVBpcGUoKSB7XG4gIHJldHVybiBzdGF0ZS5waXBlZFZhbHVlO1xufVxuZXhwb3J0cy5yZWFkRnJvbVBpcGUgPSBfcmVhZEZyb21QaXBlO1xuXG52YXIgREVGQVVMVF9XUkFQX09QVElPTlMgPSB7XG4gIGFsbG93R2xvYmJpbmc6IHRydWUsXG4gIGNhblJlY2VpdmVQaXBlOiBmYWxzZSxcbiAgY21kT3B0aW9uczogbnVsbCxcbiAgZ2xvYlN0YXJ0OiAxLFxuICBwaXBlT25seTogZmFsc2UsXG4gIHdyYXBPdXRwdXQ6IHRydWUsXG4gIHVuaXg6IHRydWUsXG59O1xuXG4vLyBUaGlzIGlzIHBvcHVsYXRlZCBkdXJpbmcgcGx1Z2luIHJlZ2lzdHJhdGlvblxudmFyIHBpcGVNZXRob2RzID0gW107XG5cbi8vIFJlZ2lzdGVyIGEgbmV3IFNoZWxsSlMgY29tbWFuZFxuZnVuY3Rpb24gX3JlZ2lzdGVyKG5hbWUsIGltcGxlbWVudGF0aW9uLCB3cmFwT3B0aW9ucykge1xuICB3cmFwT3B0aW9ucyA9IHdyYXBPcHRpb25zIHx8IHt9O1xuXG4gIC8vIFZhbGlkYXRlIG9wdGlvbnNcbiAgT2JqZWN0LmtleXMod3JhcE9wdGlvbnMpLmZvckVhY2goZnVuY3Rpb24gKG9wdGlvbikge1xuICAgIGlmICghREVGQVVMVF9XUkFQX09QVElPTlMuaGFzT3duUHJvcGVydHkob3B0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvcHRpb24gJ1wiICsgb3B0aW9uICsgXCInXCIpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHdyYXBPcHRpb25zW29wdGlvbl0gIT09IHR5cGVvZiBERUZBVUxUX1dSQVBfT1BUSU9OU1tvcHRpb25dKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5zdXBwb3J0ZWQgdHlwZSAnXCIgKyB0eXBlb2Ygd3JhcE9wdGlvbnNbb3B0aW9uXSArXG4gICAgICAgIFwiJyBmb3Igb3B0aW9uICdcIiArIG9wdGlvbiArIFwiJ1wiKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIElmIGFuIG9wdGlvbiBpc24ndCBzcGVjaWZpZWQsIHVzZSB0aGUgZGVmYXVsdFxuICB3cmFwT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIERFRkFVTFRfV1JBUF9PUFRJT05TLCB3cmFwT3B0aW9ucyk7XG5cbiAgaWYgKHNoZWxsLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb21tYW5kIGAnICsgbmFtZSArICdgIGFscmVhZHkgZXhpc3RzJyk7XG4gIH1cblxuICBpZiAod3JhcE9wdGlvbnMucGlwZU9ubHkpIHtcbiAgICB3cmFwT3B0aW9ucy5jYW5SZWNlaXZlUGlwZSA9IHRydWU7XG4gICAgc2hlbGxNZXRob2RzW25hbWVdID0gd3JhcChuYW1lLCBpbXBsZW1lbnRhdGlvbiwgd3JhcE9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIHNoZWxsW25hbWVdID0gd3JhcChuYW1lLCBpbXBsZW1lbnRhdGlvbiwgd3JhcE9wdGlvbnMpO1xuICB9XG5cbiAgaWYgKHdyYXBPcHRpb25zLmNhblJlY2VpdmVQaXBlKSB7XG4gICAgcGlwZU1ldGhvZHMucHVzaChuYW1lKTtcbiAgfVxufVxuZXhwb3J0cy5yZWdpc3RlciA9IF9yZWdpc3RlcjtcbiIsInZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2NwJywgX2NwLCB7XG4gIGNtZE9wdGlvbnM6IHtcbiAgICAnZic6ICchbm9fZm9yY2UnLFxuICAgICduJzogJ25vX2ZvcmNlJyxcbiAgICAndSc6ICd1cGRhdGUnLFxuICAgICdSJzogJ3JlY3Vyc2l2ZScsXG4gICAgJ3InOiAncmVjdXJzaXZlJyxcbiAgICAnTCc6ICdmb2xsb3dzeW1saW5rJyxcbiAgICAnUCc6ICdub0ZvbGxvd3N5bWxpbmsnLFxuICB9LFxuICB3cmFwT3V0cHV0OiBmYWxzZSxcbn0pO1xuXG4vLyBCdWZmZXJlZCBmaWxlIGNvcHksIHN5bmNocm9ub3VzXG4vLyAoVXNpbmcgcmVhZEZpbGVTeW5jKCkgKyB3cml0ZUZpbGVTeW5jKCkgY291bGQgZWFzaWx5IGNhdXNlIGEgbWVtb3J5IG92ZXJmbG93XG4vLyAgd2l0aCBsYXJnZSBmaWxlcylcbmZ1bmN0aW9uIGNvcHlGaWxlU3luYyhzcmNGaWxlLCBkZXN0RmlsZSwgb3B0aW9ucykge1xuICBpZiAoIWZzLmV4aXN0c1N5bmMoc3JjRmlsZSkpIHtcbiAgICBjb21tb24uZXJyb3IoJ2NvcHlGaWxlU3luYzogbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIHNyY0ZpbGUpO1xuICB9XG5cbiAgdmFyIGlzV2luZG93cyA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMic7XG5cbiAgLy8gQ2hlY2sgdGhlIG10aW1lcyBvZiB0aGUgZmlsZXMgaWYgdGhlICctdScgZmxhZyBpcyBwcm92aWRlZFxuICB0cnkge1xuICAgIGlmIChvcHRpb25zLnVwZGF0ZSAmJiBjb21tb24uc3RhdEZvbGxvd0xpbmtzKHNyY0ZpbGUpLm10aW1lIDwgZnMuc3RhdFN5bmMoZGVzdEZpbGUpLm10aW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gSWYgd2UncmUgaGVyZSwgZGVzdEZpbGUgcHJvYmFibHkgZG9lc24ndCBleGlzdCwgc28ganVzdCBkbyBhIG5vcm1hbCBjb3B5XG4gIH1cblxuICBpZiAoY29tbW9uLnN0YXROb0ZvbGxvd0xpbmtzKHNyY0ZpbGUpLmlzU3ltYm9saWNMaW5rKCkgJiYgIW9wdGlvbnMuZm9sbG93c3ltbGluaykge1xuICAgIHRyeSB7XG4gICAgICBjb21tb24uc3RhdE5vRm9sbG93TGlua3MoZGVzdEZpbGUpO1xuICAgICAgY29tbW9uLnVubGlua1N5bmMoZGVzdEZpbGUpOyAvLyByZS1saW5rIGl0XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gaXQgZG9lc24ndCBleGlzdCwgc28gbm8gd29yayBuZWVkcyB0byBiZSBkb25lXG4gICAgfVxuXG4gICAgdmFyIHN5bWxpbmtGdWxsID0gZnMucmVhZGxpbmtTeW5jKHNyY0ZpbGUpO1xuICAgIGZzLnN5bWxpbmtTeW5jKHN5bWxpbmtGdWxsLCBkZXN0RmlsZSwgaXNXaW5kb3dzID8gJ2p1bmN0aW9uJyA6IG51bGwpO1xuICB9IGVsc2Uge1xuICAgIHZhciBidWYgPSBjb21tb24uYnVmZmVyKCk7XG4gICAgdmFyIGJ1Zkxlbmd0aCA9IGJ1Zi5sZW5ndGg7XG4gICAgdmFyIGJ5dGVzUmVhZCA9IGJ1Zkxlbmd0aDtcbiAgICB2YXIgcG9zID0gMDtcbiAgICB2YXIgZmRyID0gbnVsbDtcbiAgICB2YXIgZmR3ID0gbnVsbDtcblxuICAgIHRyeSB7XG4gICAgICBmZHIgPSBmcy5vcGVuU3luYyhzcmNGaWxlLCAncicpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICBjb21tb24uZXJyb3IoJ2NvcHlGaWxlU3luYzogY291bGQgbm90IHJlYWQgc3JjIGZpbGUgKCcgKyBzcmNGaWxlICsgJyknKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgZmR3ID0gZnMub3BlblN5bmMoZGVzdEZpbGUsICd3Jyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGNvbW1vbi5lcnJvcignY29weUZpbGVTeW5jOiBjb3VsZCBub3Qgd3JpdGUgdG8gZGVzdCBmaWxlIChjb2RlPScgKyBlLmNvZGUgKyAnKTonICsgZGVzdEZpbGUpO1xuICAgIH1cblxuICAgIHdoaWxlIChieXRlc1JlYWQgPT09IGJ1Zkxlbmd0aCkge1xuICAgICAgYnl0ZXNSZWFkID0gZnMucmVhZFN5bmMoZmRyLCBidWYsIDAsIGJ1Zkxlbmd0aCwgcG9zKTtcbiAgICAgIGZzLndyaXRlU3luYyhmZHcsIGJ1ZiwgMCwgYnl0ZXNSZWFkKTtcbiAgICAgIHBvcyArPSBieXRlc1JlYWQ7XG4gICAgfVxuXG4gICAgZnMuY2xvc2VTeW5jKGZkcik7XG4gICAgZnMuY2xvc2VTeW5jKGZkdyk7XG5cbiAgICBmcy5jaG1vZFN5bmMoZGVzdEZpbGUsIGNvbW1vbi5zdGF0Rm9sbG93TGlua3Moc3JjRmlsZSkubW9kZSk7XG4gIH1cbn1cblxuLy8gUmVjdXJzaXZlbHkgY29waWVzICdzb3VyY2VEaXInIGludG8gJ2Rlc3REaXInXG4vLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3J5YW5tY2dyYXRoL3dyZW5jaC1qc1xuLy9cbi8vIENvcHlyaWdodCAoYykgMjAxMCBSeWFuIE1jR3JhdGhcbi8vIENvcHlyaWdodCAoYykgMjAxMiBBcnR1ciBBZGliXG4vL1xuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlXG4vLyBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuZnVuY3Rpb24gY3BkaXJTeW5jUmVjdXJzaXZlKHNvdXJjZURpciwgZGVzdERpciwgY3VycmVudERlcHRoLCBvcHRzKSB7XG4gIGlmICghb3B0cykgb3B0cyA9IHt9O1xuXG4gIC8vIEVuc3VyZSB0aGVyZSBpcyBub3QgYSBydW4gYXdheSByZWN1cnNpdmUgY29weVxuICBpZiAoY3VycmVudERlcHRoID49IGNvbW1vbi5jb25maWcubWF4ZGVwdGgpIHJldHVybjtcbiAgY3VycmVudERlcHRoKys7XG5cbiAgdmFyIGlzV2luZG93cyA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMic7XG5cbiAgLy8gQ3JlYXRlIHRoZSBkaXJlY3Rvcnkgd2hlcmUgYWxsIG91ciBqdW5rIGlzIG1vdmluZyB0bzsgcmVhZCB0aGUgbW9kZSBvZiB0aGVcbiAgLy8gc291cmNlIGRpcmVjdG9yeSBhbmQgbWlycm9yIGl0XG4gIHRyeSB7XG4gICAgZnMubWtkaXJTeW5jKGRlc3REaXIpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gaWYgdGhlIGRpcmVjdG9yeSBhbHJlYWR5IGV4aXN0cywgdGhhdCdzIG9rYXlcbiAgICBpZiAoZS5jb2RlICE9PSAnRUVYSVNUJykgdGhyb3cgZTtcbiAgfVxuXG4gIHZhciBmaWxlcyA9IGZzLnJlYWRkaXJTeW5jKHNvdXJjZURpcik7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBzcmNGaWxlID0gc291cmNlRGlyICsgJy8nICsgZmlsZXNbaV07XG4gICAgdmFyIGRlc3RGaWxlID0gZGVzdERpciArICcvJyArIGZpbGVzW2ldO1xuICAgIHZhciBzcmNGaWxlU3RhdCA9IGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhzcmNGaWxlKTtcblxuICAgIHZhciBzeW1saW5rRnVsbDtcbiAgICBpZiAob3B0cy5mb2xsb3dzeW1saW5rKSB7XG4gICAgICBpZiAoY3BjaGVja2N5Y2xlKHNvdXJjZURpciwgc3JjRmlsZSkpIHtcbiAgICAgICAgLy8gQ3ljbGUgbGluayBmb3VuZC5cbiAgICAgICAgY29uc29sZS5lcnJvcignQ3ljbGUgbGluayBmb3VuZC4nKTtcbiAgICAgICAgc3ltbGlua0Z1bGwgPSBmcy5yZWFkbGlua1N5bmMoc3JjRmlsZSk7XG4gICAgICAgIGZzLnN5bWxpbmtTeW5jKHN5bWxpbmtGdWxsLCBkZXN0RmlsZSwgaXNXaW5kb3dzID8gJ2p1bmN0aW9uJyA6IG51bGwpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNyY0ZpbGVTdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIC8qIHJlY3Vyc2lvbiB0aGlzIHRoaW5nIHJpZ2h0IG9uIGJhY2suICovXG4gICAgICBjcGRpclN5bmNSZWN1cnNpdmUoc3JjRmlsZSwgZGVzdEZpbGUsIGN1cnJlbnREZXB0aCwgb3B0cyk7XG4gICAgfSBlbHNlIGlmIChzcmNGaWxlU3RhdC5pc1N5bWJvbGljTGluaygpICYmICFvcHRzLmZvbGxvd3N5bWxpbmspIHtcbiAgICAgIHN5bWxpbmtGdWxsID0gZnMucmVhZGxpbmtTeW5jKHNyY0ZpbGUpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29tbW9uLnN0YXROb0ZvbGxvd0xpbmtzKGRlc3RGaWxlKTtcbiAgICAgICAgY29tbW9uLnVubGlua1N5bmMoZGVzdEZpbGUpOyAvLyByZS1saW5rIGl0XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGl0IGRvZXNuJ3QgZXhpc3QsIHNvIG5vIHdvcmsgbmVlZHMgdG8gYmUgZG9uZVxuICAgICAgfVxuICAgICAgZnMuc3ltbGlua1N5bmMoc3ltbGlua0Z1bGwsIGRlc3RGaWxlLCBpc1dpbmRvd3MgPyAnanVuY3Rpb24nIDogbnVsbCk7XG4gICAgfSBlbHNlIGlmIChzcmNGaWxlU3RhdC5pc1N5bWJvbGljTGluaygpICYmIG9wdHMuZm9sbG93c3ltbGluaykge1xuICAgICAgc3JjRmlsZVN0YXQgPSBjb21tb24uc3RhdEZvbGxvd0xpbmtzKHNyY0ZpbGUpO1xuICAgICAgaWYgKHNyY0ZpbGVTdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgY3BkaXJTeW5jUmVjdXJzaXZlKHNyY0ZpbGUsIGRlc3RGaWxlLCBjdXJyZW50RGVwdGgsIG9wdHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29weUZpbGVTeW5jKHNyY0ZpbGUsIGRlc3RGaWxlLCBvcHRzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLyogQXQgdGhpcyBwb2ludCwgd2UndmUgaGl0IGEgZmlsZSBhY3R1YWxseSB3b3J0aCBjb3B5aW5nLi4uIHNvIGNvcHkgaXQgb24gb3Zlci4gKi9cbiAgICAgIGlmIChmcy5leGlzdHNTeW5jKGRlc3RGaWxlKSAmJiBvcHRzLm5vX2ZvcmNlKSB7XG4gICAgICAgIGNvbW1vbi5sb2coJ3NraXBwaW5nIGV4aXN0aW5nIGZpbGU6ICcgKyBmaWxlc1tpXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb3B5RmlsZVN5bmMoc3JjRmlsZSwgZGVzdEZpbGUsIG9wdHMpO1xuICAgICAgfVxuICAgIH1cbiAgfSAvLyBmb3IgZmlsZXNcblxuICAvLyBmaW5hbGx5IGNoYW5nZSB0aGUgbW9kZSBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgZGlyZWN0b3J5IChvdGhlcndpc2UsIHdlXG4gIC8vIGNvdWxkbid0IGFkZCBmaWxlcyB0byBhIHJlYWQtb25seSBkaXJlY3RvcnkpLlxuICB2YXIgY2hlY2tEaXIgPSBjb21tb24uc3RhdEZvbGxvd0xpbmtzKHNvdXJjZURpcik7XG4gIGZzLmNobW9kU3luYyhkZXN0RGlyLCBjaGVja0Rpci5tb2RlKTtcbn0gLy8gY3BkaXJTeW5jUmVjdXJzaXZlXG5cbi8vIENoZWNrcyBpZiBjdXJlZW50IGZpbGUgd2FzIGNyZWF0ZWQgcmVjZW50bHlcbmZ1bmN0aW9uIGNoZWNrUmVjZW50Q3JlYXRlZChzb3VyY2VzLCBpbmRleCkge1xuICB2YXIgbG9va2VkU291cmNlID0gc291cmNlc1tpbmRleF07XG4gIHJldHVybiBzb3VyY2VzLnNsaWNlKDAsIGluZGV4KS5zb21lKGZ1bmN0aW9uIChzcmMpIHtcbiAgICByZXR1cm4gcGF0aC5iYXNlbmFtZShzcmMpID09PSBwYXRoLmJhc2VuYW1lKGxvb2tlZFNvdXJjZSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBjcGNoZWNrY3ljbGUoc291cmNlRGlyLCBzcmNGaWxlKSB7XG4gIHZhciBzcmNGaWxlU3RhdCA9IGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhzcmNGaWxlKTtcbiAgaWYgKHNyY0ZpbGVTdGF0LmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICAvLyBEbyBjeWNsZSBjaGVjay4gRm9yIGV4YW1wbGU6XG4gICAgLy8gICAkIG1rZGlyIC1wIDEvMi8zLzRcbiAgICAvLyAgICQgY2QgIDEvMi8zLzRcbiAgICAvLyAgICQgbG4gLXMgLi4vLi4vMyBsaW5rXG4gICAgLy8gICAkIGNkIC4uLy4uLy4uLy4uXG4gICAgLy8gICAkIGNwIC1STCAxIGNvcHlcbiAgICB2YXIgY3ljbGVjaGVjayA9IGNvbW1vbi5zdGF0Rm9sbG93TGlua3Moc3JjRmlsZSk7XG4gICAgaWYgKGN5Y2xlY2hlY2suaXNEaXJlY3RvcnkoKSkge1xuICAgICAgdmFyIHNvdXJjZXJlYWxwYXRoID0gZnMucmVhbHBhdGhTeW5jKHNvdXJjZURpcik7XG4gICAgICB2YXIgc3ltbGlua3JlYWxwYXRoID0gZnMucmVhbHBhdGhTeW5jKHNyY0ZpbGUpO1xuICAgICAgdmFyIHJlID0gbmV3IFJlZ0V4cChzeW1saW5rcmVhbHBhdGgpO1xuICAgICAgaWYgKHJlLnRlc3Qoc291cmNlcmVhbHBhdGgpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8vQFxuLy9AICMjIyBjcChbb3B0aW9ucyxdIHNvdXJjZSBbLCBzb3VyY2UgLi4uXSwgZGVzdClcbi8vQCAjIyMgY3AoW29wdGlvbnMsXSBzb3VyY2VfYXJyYXksIGRlc3QpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1mYDogZm9yY2UgKGRlZmF1bHQgYmVoYXZpb3IpXG4vL0AgKyBgLW5gOiBuby1jbG9iYmVyXG4vL0AgKyBgLXVgOiBvbmx5IGNvcHkgaWYgYHNvdXJjZWAgaXMgbmV3ZXIgdGhhbiBgZGVzdGBcbi8vQCArIGAtcmAsIGAtUmA6IHJlY3Vyc2l2ZVxuLy9AICsgYC1MYDogZm9sbG93IHN5bWxpbmtzXG4vL0AgKyBgLVBgOiBkb24ndCBmb2xsb3cgc3ltbGlua3Ncbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIGNwKCdmaWxlMScsICdkaXIxJyk7XG4vL0AgY3AoJy1SJywgJ3BhdGgvdG8vZGlyLycsICd+L25ld0NvcHkvJyk7XG4vL0AgY3AoJy1SZicsICcvdG1wLyonLCAnL3Vzci9sb2NhbC8qJywgJy9ob21lL3RtcCcpO1xuLy9AIGNwKCctUmYnLCBbJy90bXAvKicsICcvdXNyL2xvY2FsLyonXSwgJy9ob21lL3RtcCcpOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgYGBgXG4vL0Bcbi8vQCBDb3BpZXMgZmlsZXMuXG5mdW5jdGlvbiBfY3Aob3B0aW9ucywgc291cmNlcywgZGVzdCkge1xuICAvLyBJZiB3ZSdyZSBtaXNzaW5nIC1SLCBpdCBhY3R1YWxseSBpbXBsaWVzIC1MICh1bmxlc3MgLVAgaXMgZXhwbGljaXQpXG4gIGlmIChvcHRpb25zLmZvbGxvd3N5bWxpbmspIHtcbiAgICBvcHRpb25zLm5vRm9sbG93c3ltbGluayA9IGZhbHNlO1xuICB9XG4gIGlmICghb3B0aW9ucy5yZWN1cnNpdmUgJiYgIW9wdGlvbnMubm9Gb2xsb3dzeW1saW5rKSB7XG4gICAgb3B0aW9ucy5mb2xsb3dzeW1saW5rID0gdHJ1ZTtcbiAgfVxuXG4gIC8vIEdldCBzb3VyY2VzLCBkZXN0XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykge1xuICAgIGNvbW1vbi5lcnJvcignbWlzc2luZyA8c291cmNlPiBhbmQvb3IgPGRlc3Q+Jyk7XG4gIH0gZWxzZSB7XG4gICAgc291cmNlcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxLCBhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgZGVzdCA9IGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMV07XG4gIH1cblxuICB2YXIgZGVzdEV4aXN0cyA9IGZzLmV4aXN0c1N5bmMoZGVzdCk7XG4gIHZhciBkZXN0U3RhdCA9IGRlc3RFeGlzdHMgJiYgY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhkZXN0KTtcblxuICAvLyBEZXN0IGlzIG5vdCBleGlzdGluZyBkaXIsIGJ1dCBtdWx0aXBsZSBzb3VyY2VzIGdpdmVuXG4gIGlmICgoIWRlc3RFeGlzdHMgfHwgIWRlc3RTdGF0LmlzRGlyZWN0b3J5KCkpICYmIHNvdXJjZXMubGVuZ3RoID4gMSkge1xuICAgIGNvbW1vbi5lcnJvcignZGVzdCBpcyBub3QgYSBkaXJlY3RvcnkgKHRvbyBtYW55IHNvdXJjZXMpJyk7XG4gIH1cblxuICAvLyBEZXN0IGlzIGFuIGV4aXN0aW5nIGZpbGUsIGJ1dCAtbiBpcyBnaXZlblxuICBpZiAoZGVzdEV4aXN0cyAmJiBkZXN0U3RhdC5pc0ZpbGUoKSAmJiBvcHRpb25zLm5vX2ZvcmNlKSB7XG4gICAgcmV0dXJuIG5ldyBjb21tb24uU2hlbGxTdHJpbmcoJycsICcnLCAwKTtcbiAgfVxuXG4gIHNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbiAoc3JjLCBzcmNJbmRleCkge1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhzcmMpKSB7XG4gICAgICBpZiAoc3JjID09PSAnJykgc3JjID0gXCInJ1wiOyAvLyBpZiBzcmMgd2FzIGVtcHR5IHN0cmluZywgZGlzcGxheSBlbXB0eSBzdHJpbmdcbiAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIHNyYywgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIHJldHVybjsgLy8gc2tpcCBmaWxlXG4gICAgfVxuICAgIHZhciBzcmNTdGF0ID0gY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhzcmMpO1xuICAgIGlmICghb3B0aW9ucy5ub0ZvbGxvd3N5bWxpbmsgJiYgc3JjU3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICBpZiAoIW9wdGlvbnMucmVjdXJzaXZlKSB7XG4gICAgICAgIC8vIE5vbi1SZWN1cnNpdmVcbiAgICAgICAgY29tbW9uLmVycm9yKFwib21pdHRpbmcgZGlyZWN0b3J5ICdcIiArIHNyYyArIFwiJ1wiLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlXG4gICAgICAgIC8vICdjcCAvYS9zb3VyY2UgZGVzdCcgc2hvdWxkIGNyZWF0ZSAnc291cmNlJyBpbiAnZGVzdCdcbiAgICAgICAgdmFyIG5ld0Rlc3QgPSAoZGVzdFN0YXQgJiYgZGVzdFN0YXQuaXNEaXJlY3RvcnkoKSkgP1xuICAgICAgICAgICAgcGF0aC5qb2luKGRlc3QsIHBhdGguYmFzZW5hbWUoc3JjKSkgOlxuICAgICAgICAgICAgZGVzdDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbW1vbi5zdGF0Rm9sbG93TGlua3MocGF0aC5kaXJuYW1lKGRlc3QpKTtcbiAgICAgICAgICBjcGRpclN5bmNSZWN1cnNpdmUoc3JjLCBuZXdEZXN0LCAwLCB7IG5vX2ZvcmNlOiBvcHRpb25zLm5vX2ZvcmNlLCBmb2xsb3dzeW1saW5rOiBvcHRpb25zLmZvbGxvd3N5bWxpbmsgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgIGNvbW1vbi5lcnJvcihcImNhbm5vdCBjcmVhdGUgZGlyZWN0b3J5ICdcIiArIGRlc3QgKyBcIic6IE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnlcIik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgaGVyZSwgc3JjIGlzIGEgZmlsZVxuXG4gICAgICAvLyBXaGVuIGNvcHlpbmcgdG8gJy9wYXRoL2Rpcic6XG4gICAgICAvLyAgICB0aGlzRGVzdCA9ICcvcGF0aC9kaXIvZmlsZTEnXG4gICAgICB2YXIgdGhpc0Rlc3QgPSBkZXN0O1xuICAgICAgaWYgKGRlc3RTdGF0ICYmIGRlc3RTdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgdGhpc0Rlc3QgPSBwYXRoLm5vcm1hbGl6ZShkZXN0ICsgJy8nICsgcGF0aC5iYXNlbmFtZShzcmMpKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHRoaXNEZXN0RXhpc3RzID0gZnMuZXhpc3RzU3luYyh0aGlzRGVzdCk7XG4gICAgICBpZiAodGhpc0Rlc3RFeGlzdHMgJiYgY2hlY2tSZWNlbnRDcmVhdGVkKHNvdXJjZXMsIHNyY0luZGV4KSkge1xuICAgICAgICAvLyBjYW5ub3Qgb3ZlcndyaXRlIGZpbGUgY3JlYXRlZCByZWNlbnRseSBpbiBjdXJyZW50IGV4ZWN1dGlvbiwgYnV0IHdlIHdhbnQgdG8gY29udGludWUgY29weWluZyBvdGhlciBmaWxlc1xuICAgICAgICBpZiAoIW9wdGlvbnMubm9fZm9yY2UpIHtcbiAgICAgICAgICBjb21tb24uZXJyb3IoXCJ3aWxsIG5vdCBvdmVyd3JpdGUganVzdC1jcmVhdGVkICdcIiArIHRoaXNEZXN0ICsgXCInIHdpdGggJ1wiICsgc3JjICsgXCInXCIsIHsgY29udGludWU6IHRydWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpc0Rlc3RFeGlzdHMgJiYgb3B0aW9ucy5ub19mb3JjZSkge1xuICAgICAgICByZXR1cm47IC8vIHNraXAgZmlsZVxuICAgICAgfVxuXG4gICAgICBpZiAocGF0aC5yZWxhdGl2ZShzcmMsIHRoaXNEZXN0KSA9PT0gJycpIHtcbiAgICAgICAgLy8gYSBmaWxlIGNhbm5vdCBiZSBjb3BpZWQgdG8gaXRzZWxmLCBidXQgd2Ugd2FudCB0byBjb250aW51ZSBjb3B5aW5nIG90aGVyIGZpbGVzXG4gICAgICAgIGNvbW1vbi5lcnJvcihcIidcIiArIHRoaXNEZXN0ICsgXCInIGFuZCAnXCIgKyBzcmMgKyBcIicgYXJlIHRoZSBzYW1lIGZpbGVcIiwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb3B5RmlsZVN5bmMoc3JjLCB0aGlzRGVzdCwgb3B0aW9ucyk7XG4gICAgfVxuICB9KTsgLy8gZm9yRWFjaChzcmMpXG5cbiAgcmV0dXJuIG5ldyBjb21tb24uU2hlbGxTdHJpbmcoJycsIGNvbW1vbi5zdGF0ZS5lcnJvciwgY29tbW9uLnN0YXRlLmVycm9yQ29kZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9jcDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIF9jZCA9IHJlcXVpcmUoJy4vY2QnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2RpcnMnLCBfZGlycywge1xuICB3cmFwT3V0cHV0OiBmYWxzZSxcbn0pO1xuY29tbW9uLnJlZ2lzdGVyKCdwdXNoZCcsIF9wdXNoZCwge1xuICB3cmFwT3V0cHV0OiBmYWxzZSxcbn0pO1xuY29tbW9uLnJlZ2lzdGVyKCdwb3BkJywgX3BvcGQsIHtcbiAgd3JhcE91dHB1dDogZmFsc2UsXG59KTtcblxuLy8gUHVzaGQvcG9wZC9kaXJzIGludGVybmFsc1xudmFyIF9kaXJTdGFjayA9IFtdO1xuXG5mdW5jdGlvbiBfaXNTdGFja0luZGV4KGluZGV4KSB7XG4gIHJldHVybiAoL15bXFwtK11cXGQrJC8pLnRlc3QoaW5kZXgpO1xufVxuXG5mdW5jdGlvbiBfcGFyc2VTdGFja0luZGV4KGluZGV4KSB7XG4gIGlmIChfaXNTdGFja0luZGV4KGluZGV4KSkge1xuICAgIGlmIChNYXRoLmFicyhpbmRleCkgPCBfZGlyU3RhY2subGVuZ3RoICsgMSkgeyAvLyArMSBmb3IgcHdkXG4gICAgICByZXR1cm4gKC9eLS8pLnRlc3QoaW5kZXgpID8gTnVtYmVyKGluZGV4KSAtIDEgOiBOdW1iZXIoaW5kZXgpO1xuICAgIH1cbiAgICBjb21tb24uZXJyb3IoaW5kZXggKyAnOiBkaXJlY3Rvcnkgc3RhY2sgaW5kZXggb3V0IG9mIHJhbmdlJyk7XG4gIH0gZWxzZSB7XG4gICAgY29tbW9uLmVycm9yKGluZGV4ICsgJzogaW52YWxpZCBudW1iZXInKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfYWN0dWFsRGlyU3RhY2soKSB7XG4gIHJldHVybiBbcHJvY2Vzcy5jd2QoKV0uY29uY2F0KF9kaXJTdGFjayk7XG59XG5cbi8vQFxuLy9AICMjIyBwdXNoZChbb3B0aW9ucyxdIFtkaXIgfCAnLU4nIHwgJytOJ10pXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1uYDogU3VwcHJlc3NlcyB0aGUgbm9ybWFsIGNoYW5nZSBvZiBkaXJlY3Rvcnkgd2hlbiBhZGRpbmcgZGlyZWN0b3JpZXMgdG8gdGhlIHN0YWNrLCBzbyB0aGF0IG9ubHkgdGhlIHN0YWNrIGlzIG1hbmlwdWxhdGVkLlxuLy9AICsgYC1xYDogU3VwcmVzc2VzIG91dHB1dCB0byB0aGUgY29uc29sZS5cbi8vQFxuLy9AIEFyZ3VtZW50czpcbi8vQFxuLy9AICsgYGRpcmA6IFNldHMgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkgdG8gdGhlIHRvcCBvZiB0aGUgc3RhY2ssIHRoZW4gZXhlY3V0ZXMgdGhlIGVxdWl2YWxlbnQgb2YgYGNkIGRpcmAuXG4vL0AgKyBgK05gOiBCcmluZ3MgdGhlIE50aCBkaXJlY3RvcnkgKGNvdW50aW5nIGZyb20gdGhlIGxlZnQgb2YgdGhlIGxpc3QgcHJpbnRlZCBieSBkaXJzLCBzdGFydGluZyB3aXRoIHplcm8pIHRvIHRoZSB0b3Agb2YgdGhlIGxpc3QgYnkgcm90YXRpbmcgdGhlIHN0YWNrLlxuLy9AICsgYC1OYDogQnJpbmdzIHRoZSBOdGggZGlyZWN0b3J5IChjb3VudGluZyBmcm9tIHRoZSByaWdodCBvZiB0aGUgbGlzdCBwcmludGVkIGJ5IGRpcnMsIHN0YXJ0aW5nIHdpdGggemVybykgdG8gdGhlIHRvcCBvZiB0aGUgbGlzdCBieSByb3RhdGluZyB0aGUgc3RhY2suXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCAvLyBwcm9jZXNzLmN3ZCgpID09PSAnL3Vzcidcbi8vQCBwdXNoZCgnL2V0YycpOyAvLyBSZXR1cm5zIC9ldGMgL3VzclxuLy9AIHB1c2hkKCcrMScpOyAgIC8vIFJldHVybnMgL3VzciAvZXRjXG4vL0AgYGBgXG4vL0Bcbi8vQCBTYXZlIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBvbiB0aGUgdG9wIG9mIHRoZSBkaXJlY3Rvcnkgc3RhY2sgYW5kIHRoZW4gYGNkYCB0byBgZGlyYC4gV2l0aCBubyBhcmd1bWVudHMsIGBwdXNoZGAgZXhjaGFuZ2VzIHRoZSB0b3AgdHdvIGRpcmVjdG9yaWVzLiBSZXR1cm5zIGFuIGFycmF5IG9mIHBhdGhzIGluIHRoZSBzdGFjay5cbmZ1bmN0aW9uIF9wdXNoZChvcHRpb25zLCBkaXIpIHtcbiAgaWYgKF9pc1N0YWNrSW5kZXgob3B0aW9ucykpIHtcbiAgICBkaXIgPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgPSAnJztcbiAgfVxuXG4gIG9wdGlvbnMgPSBjb21tb24ucGFyc2VPcHRpb25zKG9wdGlvbnMsIHtcbiAgICAnbic6ICduby1jZCcsXG4gICAgJ3EnOiAncXVpZXQnLFxuICB9KTtcblxuICB2YXIgZGlycyA9IF9hY3R1YWxEaXJTdGFjaygpO1xuXG4gIGlmIChkaXIgPT09ICcrMCcpIHtcbiAgICByZXR1cm4gZGlyczsgLy8gKzAgaXMgYSBub29wXG4gIH0gZWxzZSBpZiAoIWRpcikge1xuICAgIGlmIChkaXJzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGRpcnMgPSBkaXJzLnNwbGljZSgxLCAxKS5jb25jYXQoZGlycyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjb21tb24uZXJyb3IoJ25vIG90aGVyIGRpcmVjdG9yeScpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChfaXNTdGFja0luZGV4KGRpcikpIHtcbiAgICB2YXIgbiA9IF9wYXJzZVN0YWNrSW5kZXgoZGlyKTtcbiAgICBkaXJzID0gZGlycy5zbGljZShuKS5jb25jYXQoZGlycy5zbGljZSgwLCBuKSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKG9wdGlvbnNbJ25vLWNkJ10pIHtcbiAgICAgIGRpcnMuc3BsaWNlKDEsIDAsIGRpcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRpcnMudW5zaGlmdChkaXIpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRpb25zWyduby1jZCddKSB7XG4gICAgZGlycyA9IGRpcnMuc2xpY2UoMSk7XG4gIH0gZWxzZSB7XG4gICAgZGlyID0gcGF0aC5yZXNvbHZlKGRpcnMuc2hpZnQoKSk7XG4gICAgX2NkKCcnLCBkaXIpO1xuICB9XG5cbiAgX2RpclN0YWNrID0gZGlycztcbiAgcmV0dXJuIF9kaXJzKG9wdGlvbnMucXVpZXQgPyAnLXEnIDogJycpO1xufVxuZXhwb3J0cy5wdXNoZCA9IF9wdXNoZDtcblxuLy9AXG4vL0Bcbi8vQCAjIyMgcG9wZChbb3B0aW9ucyxdIFsnLU4nIHwgJytOJ10pXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1uYDogU3VwcHJlc3MgdGhlIG5vcm1hbCBkaXJlY3RvcnkgY2hhbmdlIHdoZW4gcmVtb3ZpbmcgZGlyZWN0b3JpZXMgZnJvbSB0aGUgc3RhY2ssIHNvIHRoYXQgb25seSB0aGUgc3RhY2sgaXMgbWFuaXB1bGF0ZWQuXG4vL0AgKyBgLXFgOiBTdXByZXNzZXMgb3V0cHV0IHRvIHRoZSBjb25zb2xlLlxuLy9AXG4vL0AgQXJndW1lbnRzOlxuLy9AXG4vL0AgKyBgK05gOiBSZW1vdmVzIHRoZSBOdGggZGlyZWN0b3J5IChjb3VudGluZyBmcm9tIHRoZSBsZWZ0IG9mIHRoZSBsaXN0IHByaW50ZWQgYnkgZGlycyksIHN0YXJ0aW5nIHdpdGggemVyby5cbi8vQCArIGAtTmA6IFJlbW92ZXMgdGhlIE50aCBkaXJlY3RvcnkgKGNvdW50aW5nIGZyb20gdGhlIHJpZ2h0IG9mIHRoZSBsaXN0IHByaW50ZWQgYnkgZGlycyksIHN0YXJ0aW5nIHdpdGggemVyby5cbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIGVjaG8ocHJvY2Vzcy5jd2QoKSk7IC8vICcvdXNyJ1xuLy9AIHB1c2hkKCcvZXRjJyk7ICAgICAgIC8vICcvZXRjIC91c3InXG4vL0AgZWNobyhwcm9jZXNzLmN3ZCgpKTsgLy8gJy9ldGMnXG4vL0AgcG9wZCgpOyAgICAgICAgICAgICAgLy8gJy91c3InXG4vL0AgZWNobyhwcm9jZXNzLmN3ZCgpKTsgLy8gJy91c3InXG4vL0AgYGBgXG4vL0Bcbi8vQCBXaGVuIG5vIGFyZ3VtZW50cyBhcmUgZ2l2ZW4sIGBwb3BkYCByZW1vdmVzIHRoZSB0b3AgZGlyZWN0b3J5IGZyb20gdGhlIHN0YWNrIGFuZCBwZXJmb3JtcyBhIGBjZGAgdG8gdGhlIG5ldyB0b3AgZGlyZWN0b3J5LiBUaGUgZWxlbWVudHMgYXJlIG51bWJlcmVkIGZyb20gMCwgc3RhcnRpbmcgYXQgdGhlIGZpcnN0IGRpcmVjdG9yeSBsaXN0ZWQgd2l0aCBkaXJzIChpLmUuLCBgcG9wZGAgaXMgZXF1aXZhbGVudCB0byBgcG9wZCArMGApLiBSZXR1cm5zIGFuIGFycmF5IG9mIHBhdGhzIGluIHRoZSBzdGFjay5cbmZ1bmN0aW9uIF9wb3BkKG9wdGlvbnMsIGluZGV4KSB7XG4gIGlmIChfaXNTdGFja0luZGV4KG9wdGlvbnMpKSB7XG4gICAgaW5kZXggPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgPSAnJztcbiAgfVxuXG4gIG9wdGlvbnMgPSBjb21tb24ucGFyc2VPcHRpb25zKG9wdGlvbnMsIHtcbiAgICAnbic6ICduby1jZCcsXG4gICAgJ3EnOiAncXVpZXQnLFxuICB9KTtcblxuICBpZiAoIV9kaXJTdGFjay5sZW5ndGgpIHtcbiAgICByZXR1cm4gY29tbW9uLmVycm9yKCdkaXJlY3Rvcnkgc3RhY2sgZW1wdHknKTtcbiAgfVxuXG4gIGluZGV4ID0gX3BhcnNlU3RhY2tJbmRleChpbmRleCB8fCAnKzAnKTtcblxuICBpZiAob3B0aW9uc1snbm8tY2QnXSB8fCBpbmRleCA+IDAgfHwgX2RpclN0YWNrLmxlbmd0aCArIGluZGV4ID09PSAwKSB7XG4gICAgaW5kZXggPSBpbmRleCA+IDAgPyBpbmRleCAtIDEgOiBpbmRleDtcbiAgICBfZGlyU3RhY2suc3BsaWNlKGluZGV4LCAxKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZGlyID0gcGF0aC5yZXNvbHZlKF9kaXJTdGFjay5zaGlmdCgpKTtcbiAgICBfY2QoJycsIGRpcik7XG4gIH1cblxuICByZXR1cm4gX2RpcnMob3B0aW9ucy5xdWlldCA/ICctcScgOiAnJyk7XG59XG5leHBvcnRzLnBvcGQgPSBfcG9wZDtcblxuLy9AXG4vL0Bcbi8vQCAjIyMgZGlycyhbb3B0aW9ucyB8ICcrTicgfCAnLU4nXSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLWNgOiBDbGVhcnMgdGhlIGRpcmVjdG9yeSBzdGFjayBieSBkZWxldGluZyBhbGwgb2YgdGhlIGVsZW1lbnRzLlxuLy9AICsgYC1xYDogU3VwcmVzc2VzIG91dHB1dCB0byB0aGUgY29uc29sZS5cbi8vQFxuLy9AIEFyZ3VtZW50czpcbi8vQFxuLy9AICsgYCtOYDogRGlzcGxheXMgdGhlIE50aCBkaXJlY3RvcnkgKGNvdW50aW5nIGZyb20gdGhlIGxlZnQgb2YgdGhlIGxpc3QgcHJpbnRlZCBieSBkaXJzIHdoZW4gaW52b2tlZCB3aXRob3V0IG9wdGlvbnMpLCBzdGFydGluZyB3aXRoIHplcm8uXG4vL0AgKyBgLU5gOiBEaXNwbGF5cyB0aGUgTnRoIGRpcmVjdG9yeSAoY291bnRpbmcgZnJvbSB0aGUgcmlnaHQgb2YgdGhlIGxpc3QgcHJpbnRlZCBieSBkaXJzIHdoZW4gaW52b2tlZCB3aXRob3V0IG9wdGlvbnMpLCBzdGFydGluZyB3aXRoIHplcm8uXG4vL0Bcbi8vQCBEaXNwbGF5IHRoZSBsaXN0IG9mIGN1cnJlbnRseSByZW1lbWJlcmVkIGRpcmVjdG9yaWVzLiBSZXR1cm5zIGFuIGFycmF5IG9mIHBhdGhzIGluIHRoZSBzdGFjaywgb3IgYSBzaW5nbGUgcGF0aCBpZiBgK05gIG9yIGAtTmAgd2FzIHNwZWNpZmllZC5cbi8vQFxuLy9AIFNlZSBhbHNvOiBgcHVzaGRgLCBgcG9wZGBcbmZ1bmN0aW9uIF9kaXJzKG9wdGlvbnMsIGluZGV4KSB7XG4gIGlmIChfaXNTdGFja0luZGV4KG9wdGlvbnMpKSB7XG4gICAgaW5kZXggPSBvcHRpb25zO1xuICAgIG9wdGlvbnMgPSAnJztcbiAgfVxuXG4gIG9wdGlvbnMgPSBjb21tb24ucGFyc2VPcHRpb25zKG9wdGlvbnMsIHtcbiAgICAnYyc6ICdjbGVhcicsXG4gICAgJ3EnOiAncXVpZXQnLFxuICB9KTtcblxuICBpZiAob3B0aW9ucy5jbGVhcikge1xuICAgIF9kaXJTdGFjayA9IFtdO1xuICAgIHJldHVybiBfZGlyU3RhY2s7XG4gIH1cblxuICB2YXIgc3RhY2sgPSBfYWN0dWFsRGlyU3RhY2soKTtcblxuICBpZiAoaW5kZXgpIHtcbiAgICBpbmRleCA9IF9wYXJzZVN0YWNrSW5kZXgoaW5kZXgpO1xuXG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgaW5kZXggPSBzdGFjay5sZW5ndGggKyBpbmRleDtcbiAgICB9XG5cbiAgICBpZiAoIW9wdGlvbnMucXVpZXQpIHtcbiAgICAgIGNvbW1vbi5sb2coc3RhY2tbaW5kZXhdKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0YWNrW2luZGV4XTtcbiAgfVxuXG4gIGlmICghb3B0aW9ucy5xdWlldCkge1xuICAgIGNvbW1vbi5sb2coc3RhY2suam9pbignICcpKTtcbiAgfVxuXG4gIHJldHVybiBzdGFjaztcbn1cbmV4cG9ydHMuZGlycyA9IF9kaXJzO1xuIiwidmFyIGZvcm1hdCA9IHJlcXVpcmUoJ3V0aWwnKS5mb3JtYXQ7XG5cbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2VjaG8nLCBfZWNobywge1xuICBhbGxvd0dsb2JiaW5nOiBmYWxzZSxcbn0pO1xuXG4vL0Bcbi8vQCAjIyMgZWNobyhbb3B0aW9ucyxdIHN0cmluZyBbLCBzdHJpbmcgLi4uXSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLWVgOiBpbnRlcnByZXQgYmFja3NsYXNoIGVzY2FwZXMgKGRlZmF1bHQpXG4vL0AgKyBgLW5gOiByZW1vdmUgdHJhaWxpbmcgbmV3bGluZSBmcm9tIG91dHB1dFxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgZWNobygnaGVsbG8gd29ybGQnKTtcbi8vQCB2YXIgc3RyID0gZWNobygnaGVsbG8gd29ybGQnKTtcbi8vQCBlY2hvKCctbicsICdubyBuZXdsaW5lIGF0IGVuZCcpO1xuLy9AIGBgYFxuLy9AXG4vL0AgUHJpbnRzIGBzdHJpbmdgIHRvIHN0ZG91dCwgYW5kIHJldHVybnMgc3RyaW5nIHdpdGggYWRkaXRpb25hbCB1dGlsaXR5IG1ldGhvZHNcbi8vQCBsaWtlIGAudG8oKWAuXG5mdW5jdGlvbiBfZWNobyhvcHRzKSB7XG4gIC8vIGFsbG93IHN0cmluZ3Mgc3RhcnRpbmcgd2l0aCAnLScsIHNlZSBpc3N1ZSAjMjBcbiAgdmFyIG1lc3NhZ2VzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIG9wdHMgPyAwIDogMSk7XG4gIHZhciBvcHRpb25zID0ge307XG5cbiAgLy8gSWYgdGhlIGZpcnN0IGFyZ3VtZW50IHN0YXJ0cyB3aXRoICctJywgcGFyc2UgaXQgYXMgb3B0aW9ucyBzdHJpbmcuXG4gIC8vIElmIHBhcnNlT3B0aW9ucyB0aHJvd3MsIGl0IHdhc24ndCBhbiBvcHRpb25zIHN0cmluZy5cbiAgdHJ5IHtcbiAgICBvcHRpb25zID0gY29tbW9uLnBhcnNlT3B0aW9ucyhtZXNzYWdlc1swXSwge1xuICAgICAgJ2UnOiAnZXNjYXBlcycsXG4gICAgICAnbic6ICdub19uZXdsaW5lJyxcbiAgICB9LCB7XG4gICAgICBzaWxlbnQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICAvLyBBbGxvdyBudWxsIHRvIGJlIGVjaG9lZFxuICAgIGlmIChtZXNzYWdlc1swXSkge1xuICAgICAgbWVzc2FnZXMuc2hpZnQoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKF8pIHtcbiAgICAvLyBDbGVhciBvdXQgZXJyb3IgaWYgYW4gZXJyb3Igb2NjdXJyZWRcbiAgICBjb21tb24uc3RhdGUuZXJyb3IgPSBudWxsO1xuICB9XG5cbiAgdmFyIG91dHB1dCA9IGZvcm1hdC5hcHBseShudWxsLCBtZXNzYWdlcyk7XG5cbiAgLy8gQWRkIG5ld2xpbmUgaWYgLW4gaXMgbm90IHBhc3NlZC5cbiAgaWYgKCFvcHRpb25zLm5vX25ld2xpbmUpIHtcbiAgICBvdXRwdXQgKz0gJ1xcbic7XG4gIH1cblxuICBwcm9jZXNzLnN0ZG91dC53cml0ZShvdXRwdXQpO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2VjaG87XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxuLy9AXG4vL0AgIyMjIGVycm9yKClcbi8vQFxuLy9AIFRlc3RzIGlmIGVycm9yIG9jY3VycmVkIGluIHRoZSBsYXN0IGNvbW1hbmQuIFJldHVybnMgYSB0cnV0aHkgdmFsdWUgaWYgYW5cbi8vQCBlcnJvciByZXR1cm5lZCwgb3IgYSBmYWxzeSB2YWx1ZSBvdGhlcndpc2UuXG4vL0Bcbi8vQCAqKk5vdGUqKjogZG8gbm90IHJlbHkgb24gdGhlXG4vL0AgcmV0dXJuIHZhbHVlIHRvIGJlIGFuIGVycm9yIG1lc3NhZ2UuIElmIHlvdSBuZWVkIHRoZSBsYXN0IGVycm9yIG1lc3NhZ2UsIHVzZVxuLy9AIHRoZSBgLnN0ZGVycmAgYXR0cmlidXRlIGZyb20gdGhlIGxhc3QgY29tbWFuZCdzIHJldHVybiB2YWx1ZSBpbnN0ZWFkLlxuZnVuY3Rpb24gZXJyb3IoKSB7XG4gIHJldHVybiBjb21tb24uc3RhdGUuZXJyb3I7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGVycm9yO1xuIiwiaWYgKHJlcXVpcmUubWFpbiAhPT0gbW9kdWxlKSB7XG4gIHRocm93IG5ldyBFcnJvcignVGhpcyBmaWxlIHNob3VsZCBub3QgYmUgcmVxdWlyZWQnKTtcbn1cblxudmFyIGNoaWxkUHJvY2VzcyA9IHJlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbnZhciBwYXJhbUZpbGVQYXRoID0gcHJvY2Vzcy5hcmd2WzJdO1xuXG52YXIgc2VyaWFsaXplZFBhcmFtcyA9IGZzLnJlYWRGaWxlU3luYyhwYXJhbUZpbGVQYXRoLCAndXRmOCcpO1xudmFyIHBhcmFtcyA9IEpTT04ucGFyc2Uoc2VyaWFsaXplZFBhcmFtcyk7XG5cbnZhciBjbWQgPSBwYXJhbXMuY29tbWFuZDtcbnZhciBleGVjT3B0aW9ucyA9IHBhcmFtcy5leGVjT3B0aW9ucztcbnZhciBwaXBlID0gcGFyYW1zLnBpcGU7XG52YXIgc3Rkb3V0RmlsZSA9IHBhcmFtcy5zdGRvdXRGaWxlO1xudmFyIHN0ZGVyckZpbGUgPSBwYXJhbXMuc3RkZXJyRmlsZTtcblxudmFyIGMgPSBjaGlsZFByb2Nlc3MuZXhlYyhjbWQsIGV4ZWNPcHRpb25zLCBmdW5jdGlvbiAoZXJyKSB7XG4gIGlmICghZXJyKSB7XG4gICAgcHJvY2Vzcy5leGl0Q29kZSA9IDA7XG4gIH0gZWxzZSBpZiAoZXJyLmNvZGUgPT09IHVuZGVmaW5lZCkge1xuICAgIHByb2Nlc3MuZXhpdENvZGUgPSAxO1xuICB9IGVsc2Uge1xuICAgIHByb2Nlc3MuZXhpdENvZGUgPSBlcnIuY29kZTtcbiAgfVxufSk7XG5cbnZhciBzdGRvdXRTdHJlYW0gPSBmcy5jcmVhdGVXcml0ZVN0cmVhbShzdGRvdXRGaWxlKTtcbnZhciBzdGRlcnJTdHJlYW0gPSBmcy5jcmVhdGVXcml0ZVN0cmVhbShzdGRlcnJGaWxlKTtcblxuYy5zdGRvdXQucGlwZShzdGRvdXRTdHJlYW0pO1xuYy5zdGRlcnIucGlwZShzdGRlcnJTdHJlYW0pO1xuYy5zdGRvdXQucGlwZShwcm9jZXNzLnN0ZG91dCk7XG5jLnN0ZGVyci5waXBlKHByb2Nlc3Muc3RkZXJyKTtcblxuaWYgKHBpcGUpIHtcbiAgYy5zdGRpbi5lbmQocGlwZSk7XG59XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBfdGVtcERpciA9IHJlcXVpcmUoJy4vdGVtcGRpcicpLnRlbXBEaXI7XG52YXIgX3B3ZCA9IHJlcXVpcmUoJy4vcHdkJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgY2hpbGQgPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJyk7XG5cbnZhciBERUZBVUxUX01BWEJVRkZFUl9TSVpFID0gMjAgKiAxMDI0ICogMTAyNDtcbnZhciBERUZBVUxUX0VSUk9SX0NPREUgPSAxO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2V4ZWMnLCBfZXhlYywge1xuICB1bml4OiBmYWxzZSxcbiAgY2FuUmVjZWl2ZVBpcGU6IHRydWUsXG4gIHdyYXBPdXRwdXQ6IGZhbHNlLFxufSk7XG5cbi8vIFdlIHVzZSB0aGlzIGZ1bmN0aW9uIHRvIHJ1biBgZXhlY2Agc3luY2hyb25vdXNseSB3aGlsZSBhbHNvIHByb3ZpZGluZyByZWFsdGltZVxuLy8gb3V0cHV0LlxuZnVuY3Rpb24gZXhlY1N5bmMoY21kLCBvcHRzLCBwaXBlKSB7XG4gIGlmICghY29tbW9uLmNvbmZpZy5leGVjUGF0aCkge1xuICAgIGNvbW1vbi5lcnJvcignVW5hYmxlIHRvIGZpbmQgYSBwYXRoIHRvIHRoZSBub2RlIGJpbmFyeS4gUGxlYXNlIG1hbnVhbGx5IHNldCBjb25maWcuZXhlY1BhdGgnKTtcbiAgfVxuXG4gIHZhciB0ZW1wRGlyID0gX3RlbXBEaXIoKTtcbiAgdmFyIHBhcmFtc0ZpbGUgPSBwYXRoLnJlc29sdmUodGVtcERpciArICcvJyArIGNvbW1vbi5yYW5kb21GaWxlTmFtZSgpKTtcbiAgdmFyIHN0ZGVyckZpbGUgPSBwYXRoLnJlc29sdmUodGVtcERpciArICcvJyArIGNvbW1vbi5yYW5kb21GaWxlTmFtZSgpKTtcbiAgdmFyIHN0ZG91dEZpbGUgPSBwYXRoLnJlc29sdmUodGVtcERpciArICcvJyArIGNvbW1vbi5yYW5kb21GaWxlTmFtZSgpKTtcblxuICBvcHRzID0gY29tbW9uLmV4dGVuZCh7XG4gICAgc2lsZW50OiBjb21tb24uY29uZmlnLnNpbGVudCxcbiAgICBjd2Q6IF9wd2QoKS50b1N0cmluZygpLFxuICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgbWF4QnVmZmVyOiBERUZBVUxUX01BWEJVRkZFUl9TSVpFLFxuICAgIGVuY29kaW5nOiAndXRmOCcsXG4gIH0sIG9wdHMpO1xuXG4gIGlmIChmcy5leGlzdHNTeW5jKHBhcmFtc0ZpbGUpKSBjb21tb24udW5saW5rU3luYyhwYXJhbXNGaWxlKTtcbiAgaWYgKGZzLmV4aXN0c1N5bmMoc3RkZXJyRmlsZSkpIGNvbW1vbi51bmxpbmtTeW5jKHN0ZGVyckZpbGUpO1xuICBpZiAoZnMuZXhpc3RzU3luYyhzdGRvdXRGaWxlKSkgY29tbW9uLnVubGlua1N5bmMoc3Rkb3V0RmlsZSk7XG5cbiAgb3B0cy5jd2QgPSBwYXRoLnJlc29sdmUob3B0cy5jd2QpO1xuXG4gIHZhciBwYXJhbXNUb1NlcmlhbGl6ZSA9IHtcbiAgICBjb21tYW5kOiBjbWQsXG4gICAgZXhlY09wdGlvbnM6IG9wdHMsXG4gICAgcGlwZTogcGlwZSxcbiAgICBzdGRvdXRGaWxlOiBzdGRvdXRGaWxlLFxuICAgIHN0ZGVyckZpbGU6IHN0ZGVyckZpbGUsXG4gIH07XG5cbiAgZnMud3JpdGVGaWxlU3luYyhwYXJhbXNGaWxlLCBKU09OLnN0cmluZ2lmeShwYXJhbXNUb1NlcmlhbGl6ZSksICd1dGY4Jyk7XG5cbiAgdmFyIGV4ZWNBcmdzID0gW1xuICAgIHBhdGguam9pbihfX2Rpcm5hbWUsICdleGVjLWNoaWxkLmpzJyksXG4gICAgcGFyYW1zRmlsZSxcbiAgXTtcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAob3B0cy5zaWxlbnQpIHtcbiAgICBvcHRzLnN0ZGlvID0gJ2lnbm9yZSc7XG4gIH0gZWxzZSB7XG4gICAgb3B0cy5zdGRpbyA9IFswLCAxLCAyXTtcbiAgfVxuXG4gIHZhciBjb2RlID0gMDtcblxuICAvLyBXZWxjb21lIHRvIHRoZSBmdXR1cmVcbiAgdHJ5IHtcbiAgICAvLyBCYWQgdGhpbmdzIGlmIHdlIHBhc3MgaW4gYSBgc2hlbGxgIG9wdGlvbiB0byBjaGlsZF9wcm9jZXNzLmV4ZWNGaWxlU3luYyxcbiAgICAvLyBzbyB3ZSBuZWVkIHRvIGV4cGxpY2l0bHkgcmVtb3ZlIGl0IGhlcmUuXG4gICAgZGVsZXRlIG9wdHMuc2hlbGw7XG5cbiAgICBjaGlsZC5leGVjRmlsZVN5bmMoY29tbW9uLmNvbmZpZy5leGVjUGF0aCwgZXhlY0FyZ3MsIG9wdHMpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gQ29tbWFuZHMgd2l0aCBub24temVybyBleGl0IGNvZGUgcmFpc2UgYW4gZXhjZXB0aW9uLlxuICAgIGNvZGUgPSBlLnN0YXR1cyB8fCBERUZBVUxUX0VSUk9SX0NPREU7XG4gIH1cblxuICAvLyBmcy5yZWFkRmlsZVN5bmMgdXNlcyBidWZmZXIgZW5jb2RpbmcgYnkgZGVmYXVsdCwgc28gY2FsbFxuICAvLyBpdCB3aXRob3V0IHRoZSBlbmNvZGluZyBvcHRpb24gaWYgdGhlIGVuY29kaW5nIGlzICdidWZmZXInLlxuICAvLyBBbHNvLCBpZiB0aGUgZXhlYyB0aW1lb3V0IGlzIHRvbyBzaG9ydCBmb3Igbm9kZSB0byBzdGFydCB1cCxcbiAgLy8gdGhlIGZpbGVzIHdpbGwgbm90IGJlIGNyZWF0ZWQsIHNvIHRoZXNlIGNhbGxzIHdpbGwgdGhyb3cuXG4gIHZhciBzdGRvdXQgPSAnJztcbiAgdmFyIHN0ZGVyciA9ICcnO1xuICBpZiAob3B0cy5lbmNvZGluZyA9PT0gJ2J1ZmZlcicpIHtcbiAgICBzdGRvdXQgPSBmcy5yZWFkRmlsZVN5bmMoc3Rkb3V0RmlsZSk7XG4gICAgc3RkZXJyID0gZnMucmVhZEZpbGVTeW5jKHN0ZGVyckZpbGUpO1xuICB9IGVsc2Uge1xuICAgIHN0ZG91dCA9IGZzLnJlYWRGaWxlU3luYyhzdGRvdXRGaWxlLCBvcHRzLmVuY29kaW5nKTtcbiAgICBzdGRlcnIgPSBmcy5yZWFkRmlsZVN5bmMoc3RkZXJyRmlsZSwgb3B0cy5lbmNvZGluZyk7XG4gIH1cblxuICAvLyBObyBiaWdnaWUgaWYgd2UgY2FuJ3QgZXJhc2UgdGhlIGZpbGVzIG5vdyAtLSB0aGV5J3JlIGluIGEgdGVtcCBkaXIgYW55d2F5XG4gIHRyeSB7IGNvbW1vbi51bmxpbmtTeW5jKHBhcmFtc0ZpbGUpOyB9IGNhdGNoIChlKSB7fVxuICB0cnkgeyBjb21tb24udW5saW5rU3luYyhzdGRlcnJGaWxlKTsgfSBjYXRjaCAoZSkge31cbiAgdHJ5IHsgY29tbW9uLnVubGlua1N5bmMoc3Rkb3V0RmlsZSk7IH0gY2F0Y2ggKGUpIHt9XG5cbiAgaWYgKGNvZGUgIT09IDApIHtcbiAgICAvLyBOb3RlOiBgc2lsZW50YCBzaG91bGQgYmUgdW5jb25kaXRpb25hbGx5IHRydWUgdG8gYXZvaWQgZG91YmxlLXByaW50aW5nXG4gICAgLy8gdGhlIGNvbW1hbmQncyBzdGRlcnIsIGFuZCB0byBhdm9pZCBwcmludGluZyBhbnkgc3RkZXJyIHdoZW4gdGhlIHVzZXIgaGFzXG4gICAgLy8gc2V0IGBzaGVsbC5jb25maWcuc2lsZW50YC5cbiAgICBjb21tb24uZXJyb3Ioc3RkZXJyLCBjb2RlLCB7IGNvbnRpbnVlOiB0cnVlLCBzaWxlbnQ6IHRydWUgfSk7XG4gIH1cbiAgdmFyIG9iaiA9IGNvbW1vbi5TaGVsbFN0cmluZyhzdGRvdXQsIHN0ZGVyciwgY29kZSk7XG4gIHJldHVybiBvYmo7XG59IC8vIGV4ZWNTeW5jKClcblxuLy8gV3JhcHBlciBhcm91bmQgZXhlYygpIHRvIGVuYWJsZSBlY2hvaW5nIG91dHB1dCB0byBjb25zb2xlIGluIHJlYWwgdGltZVxuZnVuY3Rpb24gZXhlY0FzeW5jKGNtZCwgb3B0cywgcGlwZSwgY2FsbGJhY2spIHtcbiAgb3B0cyA9IGNvbW1vbi5leHRlbmQoe1xuICAgIHNpbGVudDogY29tbW9uLmNvbmZpZy5zaWxlbnQsXG4gICAgY3dkOiBfcHdkKCkudG9TdHJpbmcoKSxcbiAgICBlbnY6IHByb2Nlc3MuZW52LFxuICAgIG1heEJ1ZmZlcjogREVGQVVMVF9NQVhCVUZGRVJfU0laRSxcbiAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICB9LCBvcHRzKTtcblxuICB2YXIgYyA9IGNoaWxkLmV4ZWMoY21kLCBvcHRzLCBmdW5jdGlvbiAoZXJyLCBzdGRvdXQsIHN0ZGVycikge1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgaWYgKCFlcnIpIHtcbiAgICAgICAgY2FsbGJhY2soMCwgc3Rkb3V0LCBzdGRlcnIpO1xuICAgICAgfSBlbHNlIGlmIChlcnIuY29kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIFNlZSBpc3N1ZSAjNTM2XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGNhbGxiYWNrKDEsIHN0ZG91dCwgc3RkZXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrKGVyci5jb2RlLCBzdGRvdXQsIHN0ZGVycik7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBpZiAocGlwZSkgYy5zdGRpbi5lbmQocGlwZSk7XG5cbiAgaWYgKCFvcHRzLnNpbGVudCkge1xuICAgIGMuc3Rkb3V0LnBpcGUocHJvY2Vzcy5zdGRvdXQpO1xuICAgIGMuc3RkZXJyLnBpcGUocHJvY2Vzcy5zdGRlcnIpO1xuICB9XG5cbiAgcmV0dXJuIGM7XG59XG5cbi8vQFxuLy9AICMjIyBleGVjKGNvbW1hbmQgWywgb3B0aW9uc10gWywgY2FsbGJhY2tdKVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGBhc3luY2A6IEFzeW5jaHJvbm91cyBleGVjdXRpb24uIElmIGEgY2FsbGJhY2sgaXMgcHJvdmlkZWQsIGl0IHdpbGwgYmUgc2V0IHRvXG4vL0AgICBgdHJ1ZWAsIHJlZ2FyZGxlc3Mgb2YgdGhlIHBhc3NlZCB2YWx1ZSAoZGVmYXVsdDogYGZhbHNlYCkuXG4vL0AgKyBgc2lsZW50YDogRG8gbm90IGVjaG8gcHJvZ3JhbSBvdXRwdXQgdG8gY29uc29sZSAoZGVmYXVsdDogYGZhbHNlYCkuXG4vL0AgKyBgZW5jb2RpbmdgOiBDaGFyYWN0ZXIgZW5jb2RpbmcgdG8gdXNlLiBBZmZlY3RzIHRoZSB2YWx1ZXMgcmV0dXJuZWQgdG8gc3Rkb3V0IGFuZCBzdGRlcnIsIGFuZFxuLy9AICAgd2hhdCBpcyB3cml0dGVuIHRvIHN0ZG91dCBhbmQgc3RkZXJyIHdoZW4gbm90IGluIHNpbGVudCBtb2RlIChkZWZhdWx0OiBgJ3V0ZjgnYCkuXG4vL0AgKyBhbmQgYW55IG9wdGlvbiBhdmFpbGFibGUgdG8gTm9kZS5qcydzXG4vL0AgICBbYGNoaWxkX3Byb2Nlc3MuZXhlYygpYF0oaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9jaGlsZF9wcm9jZXNzLmh0bWwjY2hpbGRfcHJvY2Vzc19jaGlsZF9wcm9jZXNzX2V4ZWNfY29tbWFuZF9vcHRpb25zX2NhbGxiYWNrKVxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgdmFyIHZlcnNpb24gPSBleGVjKCdub2RlIC0tdmVyc2lvbicsIHtzaWxlbnQ6dHJ1ZX0pLnN0ZG91dDtcbi8vQFxuLy9AIHZhciBjaGlsZCA9IGV4ZWMoJ3NvbWVfbG9uZ19ydW5uaW5nX3Byb2Nlc3MnLCB7YXN5bmM6dHJ1ZX0pO1xuLy9AIGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGZ1bmN0aW9uKGRhdGEpIHtcbi8vQCAgIC8qIC4uLiBkbyBzb21ldGhpbmcgd2l0aCBkYXRhIC4uLiAqL1xuLy9AIH0pO1xuLy9AXG4vL0AgZXhlYygnc29tZV9sb25nX3J1bm5pbmdfcHJvY2VzcycsIGZ1bmN0aW9uKGNvZGUsIHN0ZG91dCwgc3RkZXJyKSB7XG4vL0AgICBjb25zb2xlLmxvZygnRXhpdCBjb2RlOicsIGNvZGUpO1xuLy9AICAgY29uc29sZS5sb2coJ1Byb2dyYW0gb3V0cHV0OicsIHN0ZG91dCk7XG4vL0AgICBjb25zb2xlLmxvZygnUHJvZ3JhbSBzdGRlcnI6Jywgc3RkZXJyKTtcbi8vQCB9KTtcbi8vQCBgYGBcbi8vQFxuLy9AIEV4ZWN1dGVzIHRoZSBnaXZlbiBgY29tbWFuZGAgX3N5bmNocm9ub3VzbHlfLCB1bmxlc3Mgb3RoZXJ3aXNlIHNwZWNpZmllZC4gIFdoZW4gaW4gc3luY2hyb25vdXNcbi8vQCBtb2RlLCB0aGlzIHJldHVybnMgYSBgU2hlbGxTdHJpbmdgIChjb21wYXRpYmxlIHdpdGggU2hlbGxKUyB2MC42LngsIHdoaWNoIHJldHVybnMgYW4gb2JqZWN0XG4vL0Agb2YgdGhlIGZvcm0gYHsgY29kZTouLi4sIHN0ZG91dDouLi4gLCBzdGRlcnI6Li4uIH1gKS4gT3RoZXJ3aXNlLCB0aGlzIHJldHVybnMgdGhlIGNoaWxkIHByb2Nlc3Ncbi8vQCBvYmplY3QsIGFuZCB0aGUgYGNhbGxiYWNrYCByZWNlaXZlcyB0aGUgYXJndW1lbnRzIGAoY29kZSwgc3Rkb3V0LCBzdGRlcnIpYC5cbi8vQFxuLy9AIE5vdCBzZWVpbmcgdGhlIGJlaGF2aW9yIHlvdSB3YW50PyBgZXhlYygpYCBydW5zIGV2ZXJ5dGhpbmcgdGhyb3VnaCBgc2hgXG4vL0AgYnkgZGVmYXVsdCAob3IgYGNtZC5leGVgIG9uIFdpbmRvd3MpLCB3aGljaCBkaWZmZXJzIGZyb20gYGJhc2hgLiBJZiB5b3Vcbi8vQCBuZWVkIGJhc2gtc3BlY2lmaWMgYmVoYXZpb3IsIHRyeSBvdXQgdGhlIGB7c2hlbGw6ICdwYXRoL3RvL2Jhc2gnfWAgb3B0aW9uLlxuZnVuY3Rpb24gX2V4ZWMoY29tbWFuZCwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmICghY29tbWFuZCkgY29tbW9uLmVycm9yKCdtdXN0IHNwZWNpZnkgY29tbWFuZCcpO1xuXG4gIHZhciBwaXBlID0gY29tbW9uLnJlYWRGcm9tUGlwZSgpO1xuXG4gIC8vIENhbGxiYWNrIGlzIGRlZmluZWQgaW5zdGVhZCBvZiBvcHRpb25zLlxuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IHsgYXN5bmM6IHRydWUgfTtcbiAgfVxuXG4gIC8vIENhbGxiYWNrIGlzIGRlZmluZWQgd2l0aCBvcHRpb25zLlxuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIG9wdGlvbnMuYXN5bmMgPSB0cnVlO1xuICB9XG5cbiAgb3B0aW9ucyA9IGNvbW1vbi5leHRlbmQoe1xuICAgIHNpbGVudDogY29tbW9uLmNvbmZpZy5zaWxlbnQsXG4gICAgYXN5bmM6IGZhbHNlLFxuICB9LCBvcHRpb25zKTtcblxuICBpZiAob3B0aW9ucy5hc3luYykge1xuICAgIHJldHVybiBleGVjQXN5bmMoY29tbWFuZCwgb3B0aW9ucywgcGlwZSwgY2FsbGJhY2spO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBleGVjU3luYyhjb21tYW5kLCBvcHRpb25zLCBwaXBlKTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBfZXhlYztcbiIsInZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgX2xzID0gcmVxdWlyZSgnLi9scycpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2ZpbmQnLCBfZmluZCwge30pO1xuXG4vL0Bcbi8vQCAjIyMgZmluZChwYXRoIFssIHBhdGggLi4uXSlcbi8vQCAjIyMgZmluZChwYXRoX2FycmF5KVxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgZmluZCgnc3JjJywgJ2xpYicpO1xuLy9AIGZpbmQoWydzcmMnLCAnbGliJ10pOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgZmluZCgnLicpLmZpbHRlcihmdW5jdGlvbihmaWxlKSB7IHJldHVybiBmaWxlLm1hdGNoKC9cXC5qcyQvKTsgfSk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBSZXR1cm5zIGFycmF5IG9mIGFsbCBmaWxlcyAoaG93ZXZlciBkZWVwKSBpbiB0aGUgZ2l2ZW4gcGF0aHMuXG4vL0Bcbi8vQCBUaGUgbWFpbiBkaWZmZXJlbmNlIGZyb20gYGxzKCctUicsIHBhdGgpYCBpcyB0aGF0IHRoZSByZXN1bHRpbmcgZmlsZSBuYW1lc1xuLy9AIGluY2x1ZGUgdGhlIGJhc2UgZGlyZWN0b3JpZXMgKGUuZy4sIGBsaWIvcmVzb3VyY2VzL2ZpbGUxYCBpbnN0ZWFkIG9mIGp1c3QgYGZpbGUxYCkuXG5mdW5jdGlvbiBfZmluZChvcHRpb25zLCBwYXRocykge1xuICBpZiAoIXBhdGhzKSB7XG4gICAgY29tbW9uLmVycm9yKCdubyBwYXRoIHNwZWNpZmllZCcpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBwYXRocyA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXRocyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgfVxuXG4gIHZhciBsaXN0ID0gW107XG5cbiAgZnVuY3Rpb24gcHVzaEZpbGUoZmlsZSkge1xuICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgICBmaWxlID0gZmlsZS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgfVxuICAgIGxpc3QucHVzaChmaWxlKTtcbiAgfVxuXG4gIC8vIHdoeSBub3Qgc2ltcGx5IGRvIGBscygnLVInLCBwYXRocylgPyBiZWNhdXNlIHRoZSBvdXRwdXQgd291bGRuJ3QgZ2l2ZSB0aGUgYmFzZSBkaXJzXG4gIC8vIHRvIGdldCB0aGUgYmFzZSBkaXIgaW4gdGhlIG91dHB1dCwgd2UgbmVlZCBpbnN0ZWFkIGBscygnLVInLCAnZGlyLyonKWAgZm9yIGV2ZXJ5IGRpcmVjdG9yeVxuXG4gIHBhdGhzLmZvckVhY2goZnVuY3Rpb24gKGZpbGUpIHtcbiAgICB2YXIgc3RhdDtcbiAgICB0cnkge1xuICAgICAgc3RhdCA9IGNvbW1vbi5zdGF0Rm9sbG93TGlua3MoZmlsZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgZmlsZSk7XG4gICAgfVxuXG4gICAgcHVzaEZpbGUoZmlsZSk7XG5cbiAgICBpZiAoc3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICBfbHMoeyByZWN1cnNpdmU6IHRydWUsIGFsbDogdHJ1ZSB9LCBmaWxlKS5mb3JFYWNoKGZ1bmN0aW9uIChzdWJmaWxlKSB7XG4gICAgICAgIHB1c2hGaWxlKHBhdGguam9pbihmaWxlLCBzdWJmaWxlKSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBsaXN0O1xufVxubW9kdWxlLmV4cG9ydHMgPSBfZmluZDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCdncmVwJywgX2dyZXAsIHtcbiAgZ2xvYlN0YXJ0OiAyLCAvLyBkb24ndCBnbG9iLWV4cGFuZCB0aGUgcmVnZXhcbiAgY2FuUmVjZWl2ZVBpcGU6IHRydWUsXG4gIGNtZE9wdGlvbnM6IHtcbiAgICAndic6ICdpbnZlcnNlJyxcbiAgICAnbCc6ICduYW1lT25seScsXG4gICAgJ2knOiAnaWdub3JlQ2FzZScsXG4gIH0sXG59KTtcblxuLy9AXG4vL0AgIyMjIGdyZXAoW29wdGlvbnMsXSByZWdleF9maWx0ZXIsIGZpbGUgWywgZmlsZSAuLi5dKVxuLy9AICMjIyBncmVwKFtvcHRpb25zLF0gcmVnZXhfZmlsdGVyLCBmaWxlX2FycmF5KVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtdmA6IEludmVydCBgcmVnZXhfZmlsdGVyYCAob25seSBwcmludCBub24tbWF0Y2hpbmcgbGluZXMpLlxuLy9AICsgYC1sYDogUHJpbnQgb25seSBmaWxlbmFtZXMgb2YgbWF0Y2hpbmcgZmlsZXMuXG4vL0AgKyBgLWlgOiBJZ25vcmUgY2FzZS5cbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIGdyZXAoJy12JywgJ0dMT0JBTF9WQVJJQUJMRScsICcqLmpzJyk7XG4vL0AgZ3JlcCgnR0xPQkFMX1ZBUklBQkxFJywgJyouanMnKTtcbi8vQCBgYGBcbi8vQFxuLy9AIFJlYWRzIGlucHV0IHN0cmluZyBmcm9tIGdpdmVuIGZpbGVzIGFuZCByZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYWxsIGxpbmVzIG9mIHRoZVxuLy9AIGZpbGUgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gYHJlZ2V4X2ZpbHRlcmAuXG5mdW5jdGlvbiBfZ3JlcChvcHRpb25zLCByZWdleCwgZmlsZXMpIHtcbiAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBjb21pbmcgZnJvbSBhIHBpcGVcbiAgdmFyIHBpcGUgPSBjb21tb24ucmVhZEZyb21QaXBlKCk7XG5cbiAgaWYgKCFmaWxlcyAmJiAhcGlwZSkgY29tbW9uLmVycm9yKCdubyBwYXRocyBnaXZlbicsIDIpO1xuXG4gIGZpbGVzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuXG4gIGlmIChwaXBlKSB7XG4gICAgZmlsZXMudW5zaGlmdCgnLScpO1xuICB9XG5cbiAgdmFyIGdyZXAgPSBbXTtcbiAgaWYgKG9wdGlvbnMuaWdub3JlQ2FzZSkge1xuICAgIHJlZ2V4ID0gbmV3IFJlZ0V4cChyZWdleCwgJ2knKTtcbiAgfVxuICBmaWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGUpICYmIGZpbGUgIT09ICctJykge1xuICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgZmlsZSwgMiwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY29udGVudHMgPSBmaWxlID09PSAnLScgPyBwaXBlIDogZnMucmVhZEZpbGVTeW5jKGZpbGUsICd1dGY4Jyk7XG4gICAgaWYgKG9wdGlvbnMubmFtZU9ubHkpIHtcbiAgICAgIGlmIChjb250ZW50cy5tYXRjaChyZWdleCkpIHtcbiAgICAgICAgZ3JlcC5wdXNoKGZpbGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbGluZXMgPSBjb250ZW50cy5zcGxpdCgnXFxuJyk7XG4gICAgICBsaW5lcy5mb3JFYWNoKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIHZhciBtYXRjaGVkID0gbGluZS5tYXRjaChyZWdleCk7XG4gICAgICAgIGlmICgob3B0aW9ucy5pbnZlcnNlICYmICFtYXRjaGVkKSB8fCAoIW9wdGlvbnMuaW52ZXJzZSAmJiBtYXRjaGVkKSkge1xuICAgICAgICAgIGdyZXAucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gZ3JlcC5qb2luKCdcXG4nKSArICdcXG4nO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfZ3JlcDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCdoZWFkJywgX2hlYWQsIHtcbiAgY2FuUmVjZWl2ZVBpcGU6IHRydWUsXG4gIGNtZE9wdGlvbnM6IHtcbiAgICAnbic6ICdudW1MaW5lcycsXG4gIH0sXG59KTtcblxuLy8gUmVhZHMgfG51bUxpbmVzfCBsaW5lcyBvciB0aGUgZW50aXJlIGZpbGUsIHdoaWNoZXZlciBpcyBsZXNzLlxuZnVuY3Rpb24gcmVhZFNvbWVMaW5lcyhmaWxlLCBudW1MaW5lcykge1xuICB2YXIgYnVmID0gY29tbW9uLmJ1ZmZlcigpO1xuICB2YXIgYnVmTGVuZ3RoID0gYnVmLmxlbmd0aDtcbiAgdmFyIGJ5dGVzUmVhZCA9IGJ1Zkxlbmd0aDtcbiAgdmFyIHBvcyA9IDA7XG5cbiAgdmFyIGZkciA9IGZzLm9wZW5TeW5jKGZpbGUsICdyJyk7XG4gIHZhciBudW1MaW5lc1JlYWQgPSAwO1xuICB2YXIgcmV0ID0gJyc7XG4gIHdoaWxlIChieXRlc1JlYWQgPT09IGJ1Zkxlbmd0aCAmJiBudW1MaW5lc1JlYWQgPCBudW1MaW5lcykge1xuICAgIGJ5dGVzUmVhZCA9IGZzLnJlYWRTeW5jKGZkciwgYnVmLCAwLCBidWZMZW5ndGgsIHBvcyk7XG4gICAgdmFyIGJ1ZlN0ciA9IGJ1Zi50b1N0cmluZygndXRmOCcsIDAsIGJ5dGVzUmVhZCk7XG4gICAgbnVtTGluZXNSZWFkICs9IGJ1ZlN0ci5zcGxpdCgnXFxuJykubGVuZ3RoIC0gMTtcbiAgICByZXQgKz0gYnVmU3RyO1xuICAgIHBvcyArPSBieXRlc1JlYWQ7XG4gIH1cblxuICBmcy5jbG9zZVN5bmMoZmRyKTtcbiAgcmV0dXJuIHJldDtcbn1cblxuLy9AXG4vL0AgIyMjIGhlYWQoW3snLW4nOiBcXDxudW1cXD59LF0gZmlsZSBbLCBmaWxlIC4uLl0pXG4vL0AgIyMjIGhlYWQoW3snLW4nOiBcXDxudW1cXD59LF0gZmlsZV9hcnJheSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLW4gPG51bT5gOiBTaG93IHRoZSBmaXJzdCBgPG51bT5gIGxpbmVzIG9mIHRoZSBmaWxlc1xuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgdmFyIHN0ciA9IGhlYWQoeyctbic6IDF9LCAnZmlsZSoudHh0Jyk7XG4vL0AgdmFyIHN0ciA9IGhlYWQoJ2ZpbGUxJywgJ2ZpbGUyJyk7XG4vL0AgdmFyIHN0ciA9IGhlYWQoWydmaWxlMScsICdmaWxlMiddKTsgLy8gc2FtZSBhcyBhYm92ZVxuLy9AIGBgYFxuLy9AXG4vL0AgUmVhZCB0aGUgc3RhcnQgb2YgYSBmaWxlLlxuZnVuY3Rpb24gX2hlYWQob3B0aW9ucywgZmlsZXMpIHtcbiAgdmFyIGhlYWQgPSBbXTtcbiAgdmFyIHBpcGUgPSBjb21tb24ucmVhZEZyb21QaXBlKCk7XG5cbiAgaWYgKCFmaWxlcyAmJiAhcGlwZSkgY29tbW9uLmVycm9yKCdubyBwYXRocyBnaXZlbicpO1xuXG4gIHZhciBpZHggPSAxO1xuICBpZiAob3B0aW9ucy5udW1MaW5lcyA9PT0gdHJ1ZSkge1xuICAgIGlkeCA9IDI7XG4gICAgb3B0aW9ucy5udW1MaW5lcyA9IE51bWJlcihhcmd1bWVudHNbMV0pO1xuICB9IGVsc2UgaWYgKG9wdGlvbnMubnVtTGluZXMgPT09IGZhbHNlKSB7XG4gICAgb3B0aW9ucy5udW1MaW5lcyA9IDEwO1xuICB9XG4gIGZpbGVzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIGlkeCk7XG5cbiAgaWYgKHBpcGUpIHtcbiAgICBmaWxlcy51bnNoaWZ0KCctJyk7XG4gIH1cblxuICB2YXIgc2hvdWxkQXBwZW5kTmV3bGluZSA9IGZhbHNlO1xuICBmaWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChmaWxlKSB7XG4gICAgaWYgKGZpbGUgIT09ICctJykge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGUpKSB7XG4gICAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIGZpbGUsIHsgY29udGludWU6IHRydWUgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAoY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGNvbW1vbi5lcnJvcihcImVycm9yIHJlYWRpbmcgJ1wiICsgZmlsZSArIFwiJzogSXMgYSBkaXJlY3RvcnlcIiwge1xuICAgICAgICAgIGNvbnRpbnVlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBjb250ZW50cztcbiAgICBpZiAoZmlsZSA9PT0gJy0nKSB7XG4gICAgICBjb250ZW50cyA9IHBpcGU7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLm51bUxpbmVzIDwgMCkge1xuICAgICAgY29udGVudHMgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0ZjgnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGVudHMgPSByZWFkU29tZUxpbmVzKGZpbGUsIG9wdGlvbnMubnVtTGluZXMpO1xuICAgIH1cblxuICAgIHZhciBsaW5lcyA9IGNvbnRlbnRzLnNwbGl0KCdcXG4nKTtcbiAgICB2YXIgaGFzVHJhaWxpbmdOZXdsaW5lID0gKGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdID09PSAnJyk7XG4gICAgaWYgKGhhc1RyYWlsaW5nTmV3bGluZSkge1xuICAgICAgbGluZXMucG9wKCk7XG4gICAgfVxuICAgIHNob3VsZEFwcGVuZE5ld2xpbmUgPSAoaGFzVHJhaWxpbmdOZXdsaW5lIHx8IG9wdGlvbnMubnVtTGluZXMgPCBsaW5lcy5sZW5ndGgpO1xuXG4gICAgaGVhZCA9IGhlYWQuY29uY2F0KGxpbmVzLnNsaWNlKDAsIG9wdGlvbnMubnVtTGluZXMpKTtcbiAgfSk7XG5cbiAgaWYgKHNob3VsZEFwcGVuZE5ld2xpbmUpIHtcbiAgICBoZWFkLnB1c2goJycpOyAvLyB0byBhZGQgYSB0cmFpbGluZyBuZXdsaW5lIG9uY2Ugd2Ugam9pblxuICB9XG4gIHJldHVybiBoZWFkLmpvaW4oJ1xcbicpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfaGVhZDtcbiIsInZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ2xuJywgX2xuLCB7XG4gIGNtZE9wdGlvbnM6IHtcbiAgICAncyc6ICdzeW1saW5rJyxcbiAgICAnZic6ICdmb3JjZScsXG4gIH0sXG59KTtcblxuLy9AXG4vL0AgIyMjIGxuKFtvcHRpb25zLF0gc291cmNlLCBkZXN0KVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtc2A6IHN5bWxpbmtcbi8vQCArIGAtZmA6IGZvcmNlXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBsbignZmlsZScsICduZXdsaW5rJyk7XG4vL0AgbG4oJy1zZicsICdmaWxlJywgJ2V4aXN0aW5nJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBMaW5rcyBgc291cmNlYCB0byBgZGVzdGAuIFVzZSBgLWZgIHRvIGZvcmNlIHRoZSBsaW5rLCBzaG91bGQgYGRlc3RgIGFscmVhZHkgZXhpc3QuXG5mdW5jdGlvbiBfbG4ob3B0aW9ucywgc291cmNlLCBkZXN0KSB7XG4gIGlmICghc291cmNlIHx8ICFkZXN0KSB7XG4gICAgY29tbW9uLmVycm9yKCdNaXNzaW5nIDxzb3VyY2U+IGFuZC9vciA8ZGVzdD4nKTtcbiAgfVxuXG4gIHNvdXJjZSA9IFN0cmluZyhzb3VyY2UpO1xuICB2YXIgc291cmNlUGF0aCA9IHBhdGgubm9ybWFsaXplKHNvdXJjZSkucmVwbGFjZShSZWdFeHAocGF0aC5zZXAgKyAnJCcpLCAnJyk7XG4gIHZhciBpc0Fic29sdXRlID0gKHBhdGgucmVzb2x2ZShzb3VyY2UpID09PSBzb3VyY2VQYXRoKTtcbiAgZGVzdCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBTdHJpbmcoZGVzdCkpO1xuXG4gIGlmIChmcy5leGlzdHNTeW5jKGRlc3QpKSB7XG4gICAgaWYgKCFvcHRpb25zLmZvcmNlKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ0Rlc3RpbmF0aW9uIGZpbGUgZXhpc3RzJywgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBmcy51bmxpbmtTeW5jKGRlc3QpO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuc3ltbGluaykge1xuICAgIHZhciBpc1dpbmRvd3MgPSBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInO1xuICAgIHZhciBsaW5rVHlwZSA9IGlzV2luZG93cyA/ICdmaWxlJyA6IG51bGw7XG4gICAgdmFyIHJlc29sdmVkU291cmNlUGF0aCA9IGlzQWJzb2x1dGUgPyBzb3VyY2VQYXRoIDogcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIHBhdGguZGlybmFtZShkZXN0KSwgc291cmNlKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVzb2x2ZWRTb3VyY2VQYXRoKSkge1xuICAgICAgY29tbW9uLmVycm9yKCdTb3VyY2UgZmlsZSBkb2VzIG5vdCBleGlzdCcsIHsgY29udGludWU6IHRydWUgfSk7XG4gICAgfSBlbHNlIGlmIChpc1dpbmRvd3MgJiYgY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhyZXNvbHZlZFNvdXJjZVBhdGgpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGxpbmtUeXBlID0gJ2p1bmN0aW9uJztcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgZnMuc3ltbGlua1N5bmMobGlua1R5cGUgPT09ICdqdW5jdGlvbicgPyByZXNvbHZlZFNvdXJjZVBhdGggOiBzb3VyY2UsIGRlc3QsIGxpbmtUeXBlKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbW1vbi5lcnJvcihlcnIubWVzc2FnZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhzb3VyY2UpKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ1NvdXJjZSBmaWxlIGRvZXMgbm90IGV4aXN0JywgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGZzLmxpbmtTeW5jKHNvdXJjZSwgZGVzdCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb21tb24uZXJyb3IoZXJyLm1lc3NhZ2UpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gJyc7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9sbjtcbiIsInZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGdsb2IgPSByZXF1aXJlKCdnbG9iJyk7XG5cbnZhciBnbG9iUGF0dGVyblJlY3Vyc2l2ZSA9IHBhdGguc2VwICsgJyoqJztcblxuY29tbW9uLnJlZ2lzdGVyKCdscycsIF9scywge1xuICBjbWRPcHRpb25zOiB7XG4gICAgJ1InOiAncmVjdXJzaXZlJyxcbiAgICAnQSc6ICdhbGwnLFxuICAgICdMJzogJ2xpbmsnLFxuICAgICdhJzogJ2FsbF9kZXByZWNhdGVkJyxcbiAgICAnZCc6ICdkaXJlY3RvcnknLFxuICAgICdsJzogJ2xvbmcnLFxuICB9LFxufSk7XG5cbi8vQFxuLy9AICMjIyBscyhbb3B0aW9ucyxdIFtwYXRoLCAuLi5dKVxuLy9AICMjIyBscyhbb3B0aW9ucyxdIHBhdGhfYXJyYXkpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1SYDogcmVjdXJzaXZlXG4vL0AgKyBgLUFgOiBhbGwgZmlsZXMgKGluY2x1ZGUgZmlsZXMgYmVnaW5uaW5nIHdpdGggYC5gLCBleGNlcHQgZm9yIGAuYCBhbmQgYC4uYClcbi8vQCArIGAtTGA6IGZvbGxvdyBzeW1saW5rc1xuLy9AICsgYC1kYDogbGlzdCBkaXJlY3RvcmllcyB0aGVtc2VsdmVzLCBub3QgdGhlaXIgY29udGVudHNcbi8vQCArIGAtbGA6IGxpc3Qgb2JqZWN0cyByZXByZXNlbnRpbmcgZWFjaCBmaWxlLCBlYWNoIHdpdGggZmllbGRzIGNvbnRhaW5pbmcgYGxzXG4vL0AgICAgICAgICAtbGAgb3V0cHV0IGZpZWxkcy4gU2VlXG4vL0AgICAgICAgICBbYGZzLlN0YXRzYF0oaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9mcy5odG1sI2ZzX2NsYXNzX2ZzX3N0YXRzKVxuLy9AICAgICAgICAgZm9yIG1vcmUgaW5mb1xuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgbHMoJ3Byb2pzLyouanMnKTtcbi8vQCBscygnLVInLCAnL3VzZXJzL21lJywgJy90bXAnKTtcbi8vQCBscygnLVInLCBbJy91c2Vycy9tZScsICcvdG1wJ10pOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgbHMoJy1sJywgJ2ZpbGUudHh0Jyk7IC8vIHsgbmFtZTogJ2ZpbGUudHh0JywgbW9kZTogMzMxODgsIG5saW5rOiAxLCAuLi59XG4vL0AgYGBgXG4vL0Bcbi8vQCBSZXR1cm5zIGFycmF5IG9mIGZpbGVzIGluIHRoZSBnaXZlbiBgcGF0aGAsIG9yIGZpbGVzIGluXG4vL0AgdGhlIGN1cnJlbnQgZGlyZWN0b3J5IGlmIG5vIGBwYXRoYCBpcyAgcHJvdmlkZWQuXG5mdW5jdGlvbiBfbHMob3B0aW9ucywgcGF0aHMpIHtcbiAgaWYgKG9wdGlvbnMuYWxsX2RlcHJlY2F0ZWQpIHtcbiAgICAvLyBXZSB3b24ndCBzdXBwb3J0IHRoZSAtYSBvcHRpb24gYXMgaXQncyBoYXJkIHRvIGltYWdlIHdoeSBpdCdzIHVzZWZ1bFxuICAgIC8vIChpdCBpbmNsdWRlcyAnLicgYW5kICcuLicgaW4gYWRkaXRpb24gdG8gJy4qJyBmaWxlcylcbiAgICAvLyBGb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgd2UnbGwgZHVtcCBhIGRlcHJlY2F0ZWQgbWVzc2FnZSBhbmQgcHJvY2VlZCBhcyBiZWZvcmVcbiAgICBjb21tb24ubG9nKCdsczogT3B0aW9uIC1hIGlzIGRlcHJlY2F0ZWQuIFVzZSAtQSBpbnN0ZWFkJyk7XG4gICAgb3B0aW9ucy5hbGwgPSB0cnVlO1xuICB9XG5cbiAgaWYgKCFwYXRocykge1xuICAgIHBhdGhzID0gWycuJ107XG4gIH0gZWxzZSB7XG4gICAgcGF0aHMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIH1cblxuICB2YXIgbGlzdCA9IFtdO1xuXG4gIGZ1bmN0aW9uIHB1c2hGaWxlKGFicywgcmVsTmFtZSwgc3RhdCkge1xuICAgIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgICByZWxOYW1lID0gcmVsTmFtZS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmxvbmcpIHtcbiAgICAgIHN0YXQgPSBzdGF0IHx8IChvcHRpb25zLmxpbmsgPyBjb21tb24uc3RhdEZvbGxvd0xpbmtzKGFicykgOiBjb21tb24uc3RhdE5vRm9sbG93TGlua3MoYWJzKSk7XG4gICAgICBsaXN0LnB1c2goYWRkTHNBdHRyaWJ1dGVzKHJlbE5hbWUsIHN0YXQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbGlzdC5wdXNoKHBhdGgucmVsYXRpdmUocmVsIHx8ICcuJywgZmlsZSkpO1xuICAgICAgbGlzdC5wdXNoKHJlbE5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIHBhdGhzLmZvckVhY2goZnVuY3Rpb24gKHApIHtcbiAgICB2YXIgc3RhdDtcblxuICAgIHRyeSB7XG4gICAgICBzdGF0ID0gb3B0aW9ucy5saW5rID8gY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhwKSA6IGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhwKTtcbiAgICAgIC8vIGZvbGxvdyBsaW5rcyB0byBkaXJlY3RvcmllcyBieSBkZWZhdWx0XG4gICAgICBpZiAoc3RhdC5pc1N5bWJvbGljTGluaygpKSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIC8vIHdvcmthcm91bmQgZm9yIGh0dHBzOi8vZ2l0aHViLmNvbS9zaGVsbGpzL3NoZWxsanMvaXNzdWVzLzc5NVxuICAgICAgICAvLyBjb2RlY292IHNlZW1zIHRvIGhhdmUgYSBidWcgdGhhdCBtaXNjYWxjdWxhdGUgdGhpcyBibG9jayBhcyB1bmNvdmVyZWQuXG4gICAgICAgIC8vIGJ1dCBhY2NvcmRpbmcgdG8gbnljIHJlcG9ydCB0aGlzIGJsb2NrIGRvZXMgZ2V0IGNvdmVyZWQuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdmFyIF9zdGF0ID0gY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhwKTtcbiAgICAgICAgICBpZiAoX3N0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgICAgc3RhdCA9IF9zdGF0O1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoXykge30gLy8gYmFkIHN5bWxpbmssIHRyZWF0IGl0IGxpa2UgYSBmaWxlXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgcCwgMiwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgc3RhdCBzdWNjZWVkZWRcbiAgICBpZiAoc3RhdC5pc0RpcmVjdG9yeSgpICYmICFvcHRpb25zLmRpcmVjdG9yeSkge1xuICAgICAgaWYgKG9wdGlvbnMucmVjdXJzaXZlKSB7XG4gICAgICAgIC8vIHVzZSBnbG9iLCBiZWNhdXNlIGl0J3Mgc2ltcGxlXG4gICAgICAgIGdsb2Iuc3luYyhwICsgZ2xvYlBhdHRlcm5SZWN1cnNpdmUsIHsgZG90OiBvcHRpb25zLmFsbCwgZm9sbG93OiBvcHRpb25zLmxpbmsgfSlcbiAgICAgICAgICAuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgLy8gR2xvYiBwYXR0ZXJuIHJldHVybnMgdGhlIGRpcmVjdG9yeSBpdHNlbGYgYW5kIG5lZWRzIHRvIGJlIGZpbHRlcmVkIG91dC5cbiAgICAgICAgICAgIGlmIChwYXRoLnJlbGF0aXZlKHAsIGl0ZW0pKSB7XG4gICAgICAgICAgICAgIHB1c2hGaWxlKGl0ZW0sIHBhdGgucmVsYXRpdmUocCwgaXRlbSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmFsbCkge1xuICAgICAgICAvLyB1c2UgZnMucmVhZGRpclN5bmMsIGJlY2F1c2UgaXQncyBmYXN0XG4gICAgICAgIGZzLnJlYWRkaXJTeW5jKHApLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICBwdXNoRmlsZShwYXRoLmpvaW4ocCwgaXRlbSksIGl0ZW0pO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHVzZSBmcy5yZWFkZGlyU3luYyBhbmQgdGhlbiBmaWx0ZXIgb3V0IHNlY3JldCBmaWxlc1xuICAgICAgICBmcy5yZWFkZGlyU3luYyhwKS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgaWYgKGl0ZW1bMF0gIT09ICcuJykge1xuICAgICAgICAgICAgcHVzaEZpbGUocGF0aC5qb2luKHAsIGl0ZW0pLCBpdGVtKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwdXNoRmlsZShwLCBwLCBzdGF0KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIEFkZCBtZXRob2RzLCB0byBtYWtlIHRoaXMgbW9yZSBjb21wYXRpYmxlIHdpdGggU2hlbGxTdHJpbmdzXG4gIHJldHVybiBsaXN0O1xufVxuXG5mdW5jdGlvbiBhZGRMc0F0dHJpYnV0ZXMocGF0aE5hbWUsIHN0YXRzKSB7XG4gIC8vIE5vdGU6IHRoaXMgb2JqZWN0IHdpbGwgY29udGFpbiBtb3JlIGluZm9ybWF0aW9uIHRoYW4gLnRvU3RyaW5nKCkgcmV0dXJuc1xuICBzdGF0cy5uYW1lID0gcGF0aE5hbWU7XG4gIHN0YXRzLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIFJldHVybiBhIHN0cmluZyByZXNlbWJsaW5nIHVuaXgncyBgbHMgLWxgIGZvcm1hdFxuICAgIHJldHVybiBbdGhpcy5tb2RlLCB0aGlzLm5saW5rLCB0aGlzLnVpZCwgdGhpcy5naWQsIHRoaXMuc2l6ZSwgdGhpcy5tdGltZSwgdGhpcy5uYW1lXS5qb2luKCcgJyk7XG4gIH07XG4gIHJldHVybiBzdGF0cztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfbHM7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCdta2RpcicsIF9ta2Rpciwge1xuICBjbWRPcHRpb25zOiB7XG4gICAgJ3AnOiAnZnVsbHBhdGgnLFxuICB9LFxufSk7XG5cbi8vIFJlY3Vyc2l2ZWx5IGNyZWF0ZXMgYGRpcmBcbmZ1bmN0aW9uIG1rZGlyU3luY1JlY3Vyc2l2ZShkaXIpIHtcbiAgdmFyIGJhc2VEaXIgPSBwYXRoLmRpcm5hbWUoZGlyKTtcblxuICAvLyBQcmV2ZW50cyBzb21lIHBvdGVudGlhbCBwcm9ibGVtcyBhcmlzaW5nIGZyb20gbWFsZm9ybWVkIFVOQ3Mgb3JcbiAgLy8gaW5zdWZmaWNpZW50IHBlcm1pc3Npb25zLlxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAoYmFzZURpciA9PT0gZGlyKSB7XG4gICAgY29tbW9uLmVycm9yKCdkaXJuYW1lKCkgZmFpbGVkOiBbJyArIGRpciArICddJyk7XG4gIH1cblxuICAvLyBCYXNlIGRpciBleGlzdHMsIG5vIHJlY3Vyc2lvbiBuZWNlc3NhcnlcbiAgaWYgKGZzLmV4aXN0c1N5bmMoYmFzZURpcikpIHtcbiAgICBmcy5ta2RpclN5bmMoZGlyLCBwYXJzZUludCgnMDc3NycsIDgpKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBCYXNlIGRpciBkb2VzIG5vdCBleGlzdCwgZ28gcmVjdXJzaXZlXG4gIG1rZGlyU3luY1JlY3Vyc2l2ZShiYXNlRGlyKTtcblxuICAvLyBCYXNlIGRpciBjcmVhdGVkLCBjYW4gY3JlYXRlIGRpclxuICBmcy5ta2RpclN5bmMoZGlyLCBwYXJzZUludCgnMDc3NycsIDgpKTtcbn1cblxuLy9AXG4vL0AgIyMjIG1rZGlyKFtvcHRpb25zLF0gZGlyIFssIGRpciAuLi5dKVxuLy9AICMjIyBta2Rpcihbb3B0aW9ucyxdIGRpcl9hcnJheSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLXBgOiBmdWxsIHBhdGggKGFuZCBjcmVhdGUgaW50ZXJtZWRpYXRlIGRpcmVjdG9yaWVzLCBpZiBuZWNlc3NhcnkpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBta2RpcignLXAnLCAnL3RtcC9hL2IvYy9kJywgJy90bXAvZS9mL2cnKTtcbi8vQCBta2RpcignLXAnLCBbJy90bXAvYS9iL2MvZCcsICcvdG1wL2UvZi9nJ10pOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgYGBgXG4vL0Bcbi8vQCBDcmVhdGVzIGRpcmVjdG9yaWVzLlxuZnVuY3Rpb24gX21rZGlyKG9wdGlvbnMsIGRpcnMpIHtcbiAgaWYgKCFkaXJzKSBjb21tb24uZXJyb3IoJ25vIHBhdGhzIGdpdmVuJyk7XG5cbiAgaWYgKHR5cGVvZiBkaXJzID09PSAnc3RyaW5nJykge1xuICAgIGRpcnMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIH1cbiAgLy8gaWYgaXQncyBhcnJheSBsZWF2ZSBpdCBhcyBpdCBpc1xuXG4gIGRpcnMuZm9yRWFjaChmdW5jdGlvbiAoZGlyKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciBzdGF0ID0gY29tbW9uLnN0YXROb0ZvbGxvd0xpbmtzKGRpcik7XG4gICAgICBpZiAoIW9wdGlvbnMuZnVsbHBhdGgpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKCdwYXRoIGFscmVhZHkgZXhpc3RzOiAnICsgZGlyLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgfSBlbHNlIGlmIChzdGF0LmlzRmlsZSgpKSB7XG4gICAgICAgIGNvbW1vbi5lcnJvcignY2Fubm90IGNyZWF0ZSBkaXJlY3RvcnkgJyArIGRpciArICc6IEZpbGUgZXhpc3RzJywgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjsgLy8gc2tpcCBkaXJcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBkbyBub3RoaW5nXG4gICAgfVxuXG4gICAgLy8gQmFzZSBkaXIgZG9lcyBub3QgZXhpc3QsIGFuZCBubyAtcCBvcHRpb24gZ2l2ZW5cbiAgICB2YXIgYmFzZURpciA9IHBhdGguZGlybmFtZShkaXIpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhiYXNlRGlyKSAmJiAhb3B0aW9ucy5mdWxscGF0aCkge1xuICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgYmFzZURpciwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIHJldHVybjsgLy8gc2tpcCBkaXJcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgaWYgKG9wdGlvbnMuZnVsbHBhdGgpIHtcbiAgICAgICAgbWtkaXJTeW5jUmVjdXJzaXZlKHBhdGgucmVzb2x2ZShkaXIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZzLm1rZGlyU3luYyhkaXIsIHBhcnNlSW50KCcwNzc3JywgOCkpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHZhciByZWFzb247XG4gICAgICBpZiAoZS5jb2RlID09PSAnRUFDQ0VTJykge1xuICAgICAgICByZWFzb24gPSAnUGVybWlzc2lvbiBkZW5pZWQnO1xuICAgICAgfSBlbHNlIGlmIChlLmNvZGUgPT09ICdFTk9URElSJyB8fCBlLmNvZGUgPT09ICdFTk9FTlQnKSB7XG4gICAgICAgIHJlYXNvbiA9ICdOb3QgYSBkaXJlY3RvcnknO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICAgIGNvbW1vbi5lcnJvcignY2Fubm90IGNyZWF0ZSBkaXJlY3RvcnkgJyArIGRpciArICc6ICcgKyByZWFzb24sIHsgY29udGludWU6IHRydWUgfSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuICcnO1xufSAvLyBta2RpclxubW9kdWxlLmV4cG9ydHMgPSBfbWtkaXI7XG4iLCJ2YXIgZnMgPSByZXF1aXJlKCdmcycpO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBjcCA9IHJlcXVpcmUoJy4vY3AnKTtcbnZhciBybSA9IHJlcXVpcmUoJy4vcm0nKTtcblxuY29tbW9uLnJlZ2lzdGVyKCdtdicsIF9tdiwge1xuICBjbWRPcHRpb25zOiB7XG4gICAgJ2YnOiAnIW5vX2ZvcmNlJyxcbiAgICAnbic6ICdub19mb3JjZScsXG4gIH0sXG59KTtcblxuLy8gQ2hlY2tzIGlmIGN1cmVlbnQgZmlsZSB3YXMgY3JlYXRlZCByZWNlbnRseVxuZnVuY3Rpb24gY2hlY2tSZWNlbnRDcmVhdGVkKHNvdXJjZXMsIGluZGV4KSB7XG4gIHZhciBsb29rZWRTb3VyY2UgPSBzb3VyY2VzW2luZGV4XTtcbiAgcmV0dXJuIHNvdXJjZXMuc2xpY2UoMCwgaW5kZXgpLnNvbWUoZnVuY3Rpb24gKHNyYykge1xuICAgIHJldHVybiBwYXRoLmJhc2VuYW1lKHNyYykgPT09IHBhdGguYmFzZW5hbWUobG9va2VkU291cmNlKTtcbiAgfSk7XG59XG5cbi8vQFxuLy9AICMjIyBtdihbb3B0aW9ucyAsXSBzb3VyY2UgWywgc291cmNlIC4uLl0sIGRlc3QnKVxuLy9AICMjIyBtdihbb3B0aW9ucyAsXSBzb3VyY2VfYXJyYXksIGRlc3QnKVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtZmA6IGZvcmNlIChkZWZhdWx0IGJlaGF2aW9yKVxuLy9AICsgYC1uYDogbm8tY2xvYmJlclxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgbXYoJy1uJywgJ2ZpbGUnLCAnZGlyLycpO1xuLy9AIG12KCdmaWxlMScsICdmaWxlMicsICdkaXIvJyk7XG4vL0AgbXYoWydmaWxlMScsICdmaWxlMiddLCAnZGlyLycpOyAvLyBzYW1lIGFzIGFib3ZlXG4vL0AgYGBgXG4vL0Bcbi8vQCBNb3ZlcyBgc291cmNlYCBmaWxlKHMpIHRvIGBkZXN0YC5cbmZ1bmN0aW9uIF9tdihvcHRpb25zLCBzb3VyY2VzLCBkZXN0KSB7XG4gIC8vIEdldCBzb3VyY2VzLCBkZXN0XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykge1xuICAgIGNvbW1vbi5lcnJvcignbWlzc2luZyA8c291cmNlPiBhbmQvb3IgPGRlc3Q+Jyk7XG4gIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDMpIHtcbiAgICBzb3VyY2VzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEsIGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBkZXN0ID0gYXJndW1lbnRzW2FyZ3VtZW50cy5sZW5ndGggLSAxXTtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygc291cmNlcyA9PT0gJ3N0cmluZycpIHtcbiAgICBzb3VyY2VzID0gW3NvdXJjZXNdO1xuICB9IGVsc2Uge1xuICAgIC8vIFRPRE8obmF0ZSk6IGZpZ3VyZSBvdXQgaWYgd2UgYWN0dWFsbHkgbmVlZCB0aGlzIGxpbmVcbiAgICBjb21tb24uZXJyb3IoJ2ludmFsaWQgYXJndW1lbnRzJyk7XG4gIH1cblxuICB2YXIgZXhpc3RzID0gZnMuZXhpc3RzU3luYyhkZXN0KTtcbiAgdmFyIHN0YXRzID0gZXhpc3RzICYmIGNvbW1vbi5zdGF0Rm9sbG93TGlua3MoZGVzdCk7XG5cbiAgLy8gRGVzdCBpcyBub3QgZXhpc3RpbmcgZGlyLCBidXQgbXVsdGlwbGUgc291cmNlcyBnaXZlblxuICBpZiAoKCFleGlzdHMgfHwgIXN0YXRzLmlzRGlyZWN0b3J5KCkpICYmIHNvdXJjZXMubGVuZ3RoID4gMSkge1xuICAgIGNvbW1vbi5lcnJvcignZGVzdCBpcyBub3QgYSBkaXJlY3RvcnkgKHRvbyBtYW55IHNvdXJjZXMpJyk7XG4gIH1cblxuICAvLyBEZXN0IGlzIGFuIGV4aXN0aW5nIGZpbGUsIGJ1dCBubyAtZiBnaXZlblxuICBpZiAoZXhpc3RzICYmIHN0YXRzLmlzRmlsZSgpICYmIG9wdGlvbnMubm9fZm9yY2UpIHtcbiAgICBjb21tb24uZXJyb3IoJ2Rlc3QgZmlsZSBhbHJlYWR5IGV4aXN0czogJyArIGRlc3QpO1xuICB9XG5cbiAgc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uIChzcmMsIHNyY0luZGV4KSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHNyYykpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIHNyYywgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIHJldHVybjsgLy8gc2tpcCBmaWxlXG4gICAgfVxuXG4gICAgLy8gSWYgaGVyZSwgc3JjIGV4aXN0c1xuXG4gICAgLy8gV2hlbiBjb3B5aW5nIHRvICcvcGF0aC9kaXInOlxuICAgIC8vICAgIHRoaXNEZXN0ID0gJy9wYXRoL2Rpci9maWxlMSdcbiAgICB2YXIgdGhpc0Rlc3QgPSBkZXN0O1xuICAgIGlmIChmcy5leGlzdHNTeW5jKGRlc3QpICYmIGNvbW1vbi5zdGF0Rm9sbG93TGlua3MoZGVzdCkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgdGhpc0Rlc3QgPSBwYXRoLm5vcm1hbGl6ZShkZXN0ICsgJy8nICsgcGF0aC5iYXNlbmFtZShzcmMpKTtcbiAgICB9XG5cbiAgICB2YXIgdGhpc0Rlc3RFeGlzdHMgPSBmcy5leGlzdHNTeW5jKHRoaXNEZXN0KTtcblxuICAgIGlmICh0aGlzRGVzdEV4aXN0cyAmJiBjaGVja1JlY2VudENyZWF0ZWQoc291cmNlcywgc3JjSW5kZXgpKSB7XG4gICAgICAvLyBjYW5ub3Qgb3ZlcndyaXRlIGZpbGUgY3JlYXRlZCByZWNlbnRseSBpbiBjdXJyZW50IGV4ZWN1dGlvbiwgYnV0IHdlIHdhbnQgdG8gY29udGludWUgY29weWluZyBvdGhlciBmaWxlc1xuICAgICAgaWYgKCFvcHRpb25zLm5vX2ZvcmNlKSB7XG4gICAgICAgIGNvbW1vbi5lcnJvcihcIndpbGwgbm90IG92ZXJ3cml0ZSBqdXN0LWNyZWF0ZWQgJ1wiICsgdGhpc0Rlc3QgKyBcIicgd2l0aCAnXCIgKyBzcmMgKyBcIidcIiwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZnMuZXhpc3RzU3luYyh0aGlzRGVzdCkgJiYgb3B0aW9ucy5ub19mb3JjZSkge1xuICAgICAgY29tbW9uLmVycm9yKCdkZXN0IGZpbGUgYWxyZWFkeSBleGlzdHM6ICcgKyB0aGlzRGVzdCwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIHJldHVybjsgLy8gc2tpcCBmaWxlXG4gICAgfVxuXG4gICAgaWYgKHBhdGgucmVzb2x2ZShzcmMpID09PSBwYXRoLmRpcm5hbWUocGF0aC5yZXNvbHZlKHRoaXNEZXN0KSkpIHtcbiAgICAgIGNvbW1vbi5lcnJvcignY2Fubm90IG1vdmUgdG8gc2VsZjogJyArIHNyYywgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIHJldHVybjsgLy8gc2tpcCBmaWxlXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGZzLnJlbmFtZVN5bmMoc3JjLCB0aGlzRGVzdCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGlmIChlLmNvZGUgPT09ICdFWERFVicpIHtcbiAgICAgICAgLy8gSWYgd2UncmUgdHJ5aW5nIHRvIGBtdmAgdG8gYW4gZXh0ZXJuYWwgcGFydGl0aW9uLCB3ZSdsbCBhY3R1YWxseSBuZWVkXG4gICAgICAgIC8vIHRvIHBlcmZvcm0gYSBjb3B5IGFuZCB0aGVuIGNsZWFuIHVwIHRoZSBvcmlnaW5hbCBmaWxlLiBJZiBlaXRoZXIgdGhlXG4gICAgICAgIC8vIGNvcHkgb3IgdGhlIHJtIGZhaWxzIHdpdGggYW4gZXhjZXB0aW9uLCB3ZSBzaG91bGQgYWxsb3cgdGhpc1xuICAgICAgICAvLyBleGNlcHRpb24gdG8gcGFzcyB1cCB0byB0aGUgdG9wIGxldmVsLlxuICAgICAgICBjcCgnLXInLCBzcmMsIHRoaXNEZXN0KTtcbiAgICAgICAgcm0oJy1yZicsIHNyYyk7XG4gICAgICB9XG4gICAgfVxuICB9KTsgLy8gZm9yRWFjaChzcmMpXG4gIHJldHVybiAnJztcbn0gLy8gbXZcbm1vZHVsZS5leHBvcnRzID0gX212O1xuIiwiLy8gc2VlIGRpcnMuanNcbiIsIi8vIHNlZSBkaXJzLmpzXG4iLCJ2YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbnZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ3B3ZCcsIF9wd2QsIHtcbiAgYWxsb3dHbG9iYmluZzogZmFsc2UsXG59KTtcblxuLy9AXG4vL0AgIyMjIHB3ZCgpXG4vL0Bcbi8vQCBSZXR1cm5zIHRoZSBjdXJyZW50IGRpcmVjdG9yeS5cbmZ1bmN0aW9uIF9wd2QoKSB7XG4gIHZhciBwd2QgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSk7XG4gIHJldHVybiBwd2Q7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9wd2Q7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbmNvbW1vbi5yZWdpc3Rlcigncm0nLCBfcm0sIHtcbiAgY21kT3B0aW9uczoge1xuICAgICdmJzogJ2ZvcmNlJyxcbiAgICAncic6ICdyZWN1cnNpdmUnLFxuICAgICdSJzogJ3JlY3Vyc2l2ZScsXG4gIH0sXG59KTtcblxuLy8gUmVjdXJzaXZlbHkgcmVtb3ZlcyAnZGlyJ1xuLy8gQWRhcHRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9yeWFubWNncmF0aC93cmVuY2gtanNcbi8vXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTAgUnlhbiBNY0dyYXRoXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTIgQXJ0dXIgQWRpYlxuLy9cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZVxuLy8gaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHBcbmZ1bmN0aW9uIHJtZGlyU3luY1JlY3Vyc2l2ZShkaXIsIGZvcmNlLCBmcm9tU3ltbGluaykge1xuICB2YXIgZmlsZXM7XG5cbiAgZmlsZXMgPSBmcy5yZWFkZGlyU3luYyhkaXIpO1xuXG4gIC8vIExvb3AgdGhyb3VnaCBhbmQgZGVsZXRlIGV2ZXJ5dGhpbmcgaW4gdGhlIHN1Yi10cmVlIGFmdGVyIGNoZWNraW5nIGl0XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZmlsZSA9IGRpciArICcvJyArIGZpbGVzW2ldO1xuICAgIHZhciBjdXJyRmlsZSA9IGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhmaWxlKTtcblxuICAgIGlmIChjdXJyRmlsZS5pc0RpcmVjdG9yeSgpKSB7IC8vIFJlY3Vyc2l2ZSBmdW5jdGlvbiBiYWNrIHRvIHRoZSBiZWdpbm5pbmdcbiAgICAgIHJtZGlyU3luY1JlY3Vyc2l2ZShmaWxlLCBmb3JjZSk7XG4gICAgfSBlbHNlIHsgLy8gQXNzdW1lIGl0J3MgYSBmaWxlIC0gcGVyaGFwcyBhIHRyeS9jYXRjaCBiZWxvbmdzIGhlcmU/XG4gICAgICBpZiAoZm9yY2UgfHwgaXNXcml0ZWFibGUoZmlsZSkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb21tb24udW5saW5rU3luYyhmaWxlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgY29tbW9uLmVycm9yKCdjb3VsZCBub3QgcmVtb3ZlIGZpbGUgKGNvZGUgJyArIGUuY29kZSArICcpOiAnICsgZmlsZSwge1xuICAgICAgICAgICAgY29udGludWU6IHRydWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiB3YXMgZGlyZWN0b3J5IHdhcyByZWZlcmVuY2VkIHRocm91Z2ggYSBzeW1ib2xpYyBsaW5rLFxuICAvLyB0aGUgY29udGVudHMgc2hvdWxkIGJlIHJlbW92ZWQsIGJ1dCBub3QgdGhlIGRpcmVjdG9yeSBpdHNlbGZcbiAgaWYgKGZyb21TeW1saW5rKSByZXR1cm47XG5cbiAgLy8gTm93IHRoYXQgd2Uga25vdyBldmVyeXRoaW5nIGluIHRoZSBzdWItdHJlZSBoYXMgYmVlbiBkZWxldGVkLCB3ZSBjYW4gZGVsZXRlIHRoZSBtYWluIGRpcmVjdG9yeS5cbiAgLy8gSHV6emFoIGZvciB0aGUgc2hvcGtlZXAuXG5cbiAgdmFyIHJlc3VsdDtcbiAgdHJ5IHtcbiAgICAvLyBSZXRyeSBvbiB3aW5kb3dzLCBzb21ldGltZXMgaXQgdGFrZXMgYSBsaXR0bGUgdGltZSBiZWZvcmUgYWxsIHRoZSBmaWxlcyBpbiB0aGUgZGlyZWN0b3J5IGFyZSBnb25lXG4gICAgdmFyIHN0YXJ0ID0gRGF0ZS5ub3coKTtcblxuICAgIC8vIFRPRE86IHJlcGxhY2UgdGhpcyB3aXRoIGEgZmluaXRlIGxvb3BcbiAgICBmb3IgKDs7KSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXN1bHQgPSBmcy5ybWRpclN5bmMoZGlyKTtcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoZGlyKSkgdGhyb3cgeyBjb2RlOiAnRUFHQUlOJyB9O1xuICAgICAgICBicmVhaztcbiAgICAgIH0gY2F0Y2ggKGVyKSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIC8vIEluIGFkZGl0aW9uIHRvIGVycm9yIGNvZGVzLCBhbHNvIGNoZWNrIGlmIHRoZSBkaXJlY3Rvcnkgc3RpbGwgZXhpc3RzIGFuZCBsb29wIGFnYWluIGlmIHRydWVcbiAgICAgICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicgJiYgKGVyLmNvZGUgPT09ICdFTk9URU1QVFknIHx8IGVyLmNvZGUgPT09ICdFQlVTWScgfHwgZXIuY29kZSA9PT0gJ0VQRVJNJyB8fCBlci5jb2RlID09PSAnRUFHQUlOJykpIHtcbiAgICAgICAgICBpZiAoRGF0ZS5ub3coKSAtIHN0YXJ0ID4gMTAwMCkgdGhyb3cgZXI7XG4gICAgICAgIH0gZWxzZSBpZiAoZXIuY29kZSA9PT0gJ0VOT0VOVCcpIHtcbiAgICAgICAgICAvLyBEaXJlY3RvcnkgZGlkIG5vdCBleGlzdCwgZGVsZXRpb24gd2FzIHN1Y2Nlc3NmdWxcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbW1vbi5lcnJvcignY291bGQgbm90IHJlbW92ZSBkaXJlY3RvcnkgKGNvZGUgJyArIGUuY29kZSArICcpOiAnICsgZGlyLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn0gLy8gcm1kaXJTeW5jUmVjdXJzaXZlXG5cbi8vIEhhY2sgdG8gZGV0ZXJtaW5lIGlmIGZpbGUgaGFzIHdyaXRlIHBlcm1pc3Npb25zIGZvciBjdXJyZW50IHVzZXJcbi8vIEF2b2lkcyBoYXZpbmcgdG8gY2hlY2sgdXNlciwgZ3JvdXAsIGV0YywgYnV0IGl0J3MgcHJvYmFibHkgc2xvd1xuZnVuY3Rpb24gaXNXcml0ZWFibGUoZmlsZSkge1xuICB2YXIgd3JpdGVQZXJtaXNzaW9uID0gdHJ1ZTtcbiAgdHJ5IHtcbiAgICB2YXIgX19mZCA9IGZzLm9wZW5TeW5jKGZpbGUsICdhJyk7XG4gICAgZnMuY2xvc2VTeW5jKF9fZmQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgd3JpdGVQZXJtaXNzaW9uID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gd3JpdGVQZXJtaXNzaW9uO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVGaWxlKGZpbGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMuZm9yY2UgfHwgaXNXcml0ZWFibGUoZmlsZSkpIHtcbiAgICAvLyAtZiB3YXMgcGFzc2VkLCBvciBmaWxlIGlzIHdyaXRhYmxlLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZFxuICAgIGNvbW1vbi51bmxpbmtTeW5jKGZpbGUpO1xuICB9IGVsc2Uge1xuICAgIGNvbW1vbi5lcnJvcigncGVybWlzc2lvbiBkZW5pZWQ6ICcgKyBmaWxlLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZURpcmVjdG9yeShmaWxlLCBvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zLnJlY3Vyc2l2ZSkge1xuICAgIC8vIC1yIHdhcyBwYXNzZWQsIHNvIGRpcmVjdG9yeSBjYW4gYmUgcmVtb3ZlZFxuICAgIHJtZGlyU3luY1JlY3Vyc2l2ZShmaWxlLCBvcHRpb25zLmZvcmNlKTtcbiAgfSBlbHNlIHtcbiAgICBjb21tb24uZXJyb3IoJ3BhdGggaXMgYSBkaXJlY3RvcnknLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZVN5bWJvbGljTGluayhmaWxlLCBvcHRpb25zKSB7XG4gIHZhciBzdGF0cztcbiAgdHJ5IHtcbiAgICBzdGF0cyA9IGNvbW1vbi5zdGF0Rm9sbG93TGlua3MoZmlsZSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBzeW1saW5rIGlzIGJyb2tlbiwgc28gcmVtb3ZlIHRoZSBzeW1saW5rIGl0c2VsZlxuICAgIGNvbW1vbi51bmxpbmtTeW5jKGZpbGUpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChzdGF0cy5pc0ZpbGUoKSkge1xuICAgIGNvbW1vbi51bmxpbmtTeW5jKGZpbGUpO1xuICB9IGVsc2UgaWYgKHN0YXRzLmlzRGlyZWN0b3J5KCkpIHtcbiAgICBpZiAoZmlsZVtmaWxlLmxlbmd0aCAtIDFdID09PSAnLycpIHtcbiAgICAgIC8vIHRyYWlsaW5nIHNlcGFyYXRvciwgc28gcmVtb3ZlIHRoZSBjb250ZW50cywgbm90IHRoZSBsaW5rXG4gICAgICBpZiAob3B0aW9ucy5yZWN1cnNpdmUpIHtcbiAgICAgICAgLy8gLXIgd2FzIHBhc3NlZCwgc28gZGlyZWN0b3J5IGNhbiBiZSByZW1vdmVkXG4gICAgICAgIHZhciBmcm9tU3ltbGluayA9IHRydWU7XG4gICAgICAgIHJtZGlyU3luY1JlY3Vyc2l2ZShmaWxlLCBvcHRpb25zLmZvcmNlLCBmcm9tU3ltbGluayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb21tb24uZXJyb3IoJ3BhdGggaXMgYSBkaXJlY3RvcnknLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBubyB0cmFpbGluZyBzZXBhcmF0b3IsIHNvIHJlbW92ZSB0aGUgbGlua1xuICAgICAgY29tbW9uLnVubGlua1N5bmMoZmlsZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUZJRk8oZmlsZSkge1xuICBjb21tb24udW5saW5rU3luYyhmaWxlKTtcbn1cblxuLy9AXG4vL0AgIyMjIHJtKFtvcHRpb25zLF0gZmlsZSBbLCBmaWxlIC4uLl0pXG4vL0AgIyMjIHJtKFtvcHRpb25zLF0gZmlsZV9hcnJheSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLWZgOiBmb3JjZVxuLy9AICsgYC1yLCAtUmA6IHJlY3Vyc2l2ZVxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0Agcm0oJy1yZicsICcvdG1wLyonKTtcbi8vQCBybSgnc29tZV9maWxlLnR4dCcsICdhbm90aGVyX2ZpbGUudHh0Jyk7XG4vL0Agcm0oWydzb21lX2ZpbGUudHh0JywgJ2Fub3RoZXJfZmlsZS50eHQnXSk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBgYGBcbi8vQFxuLy9AIFJlbW92ZXMgZmlsZXMuXG5mdW5jdGlvbiBfcm0ob3B0aW9ucywgZmlsZXMpIHtcbiAgaWYgKCFmaWxlcykgY29tbW9uLmVycm9yKCdubyBwYXRocyBnaXZlbicpO1xuXG4gIC8vIENvbnZlcnQgdG8gYXJyYXlcbiAgZmlsZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cbiAgZmlsZXMuZm9yRWFjaChmdW5jdGlvbiAoZmlsZSkge1xuICAgIHZhciBsc3RhdHM7XG4gICAgdHJ5IHtcbiAgICAgIHZhciBmaWxlcGF0aCA9IChmaWxlW2ZpbGUubGVuZ3RoIC0gMV0gPT09ICcvJylcbiAgICAgICAgPyBmaWxlLnNsaWNlKDAsIC0xKSAvLyByZW1vdmUgdGhlICcvJyBzbyBsc3RhdFN5bmMgY2FuIGRldGVjdCBzeW1saW5rc1xuICAgICAgICA6IGZpbGU7XG4gICAgICBsc3RhdHMgPSBjb21tb24uc3RhdE5vRm9sbG93TGlua3MoZmlsZXBhdGgpOyAvLyB0ZXN0IGZvciBleGlzdGVuY2VcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBQYXRoIGRvZXMgbm90IGV4aXN0LCBubyBmb3JjZSBmbGFnIGdpdmVuXG4gICAgICBpZiAoIW9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgZmlsZSwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjsgLy8gc2tpcCBmaWxlXG4gICAgfVxuXG4gICAgLy8gSWYgaGVyZSwgcGF0aCBleGlzdHNcbiAgICBpZiAobHN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICBoYW5kbGVGaWxlKGZpbGUsIG9wdGlvbnMpO1xuICAgIH0gZWxzZSBpZiAobHN0YXRzLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGhhbmRsZURpcmVjdG9yeShmaWxlLCBvcHRpb25zKTtcbiAgICB9IGVsc2UgaWYgKGxzdGF0cy5pc1N5bWJvbGljTGluaygpKSB7XG4gICAgICBoYW5kbGVTeW1ib2xpY0xpbmsoZmlsZSwgb3B0aW9ucyk7XG4gICAgfSBlbHNlIGlmIChsc3RhdHMuaXNGSUZPKCkpIHtcbiAgICAgIGhhbmRsZUZJRk8oZmlsZSk7XG4gICAgfVxuICB9KTsgLy8gZm9yRWFjaChmaWxlKVxuICByZXR1cm4gJyc7XG59IC8vIHJtXG5tb2R1bGUuZXhwb3J0cyA9IF9ybTtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCdzZWQnLCBfc2VkLCB7XG4gIGdsb2JTdGFydDogMywgLy8gZG9uJ3QgZ2xvYi1leHBhbmQgcmVnZXhlc1xuICBjYW5SZWNlaXZlUGlwZTogdHJ1ZSxcbiAgY21kT3B0aW9uczoge1xuICAgICdpJzogJ2lucGxhY2UnLFxuICB9LFxufSk7XG5cbi8vQFxuLy9AICMjIyBzZWQoW29wdGlvbnMsXSBzZWFyY2hfcmVnZXgsIHJlcGxhY2VtZW50LCBmaWxlIFssIGZpbGUgLi4uXSlcbi8vQCAjIyMgc2VkKFtvcHRpb25zLF0gc2VhcmNoX3JlZ2V4LCByZXBsYWNlbWVudCwgZmlsZV9hcnJheSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLWlgOiBSZXBsYWNlIGNvbnRlbnRzIG9mIGBmaWxlYCBpbi1wbGFjZS4gX05vdGUgdGhhdCBubyBiYWNrdXBzIHdpbGwgYmUgY3JlYXRlZCFfXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBzZWQoJy1pJywgJ1BST0dSQU1fVkVSU0lPTicsICd2MC4xLjMnLCAnc291cmNlLmpzJyk7XG4vL0Agc2VkKC8uKkRFTEVURV9USElTX0xJTkUuKlxcbi8sICcnLCAnc291cmNlLmpzJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBSZWFkcyBhbiBpbnB1dCBzdHJpbmcgZnJvbSBgZmlsZWBzLCBhbmQgcGVyZm9ybXMgYSBKYXZhU2NyaXB0IGByZXBsYWNlKClgIG9uIHRoZSBpbnB1dFxuLy9AIHVzaW5nIHRoZSBnaXZlbiBgc2VhcmNoX3JlZ2V4YCBhbmQgYHJlcGxhY2VtZW50YCBzdHJpbmcgb3IgZnVuY3Rpb24uIFJldHVybnMgdGhlIG5ldyBzdHJpbmcgYWZ0ZXIgcmVwbGFjZW1lbnQuXG4vL0Bcbi8vQCBOb3RlOlxuLy9AXG4vL0AgTGlrZSB1bml4IGBzZWRgLCBTaGVsbEpTIGBzZWRgIHN1cHBvcnRzIGNhcHR1cmUgZ3JvdXBzLiBDYXB0dXJlIGdyb3VwcyBhcmUgc3BlY2lmaWVkXG4vL0AgdXNpbmcgdGhlIGAkbmAgc3ludGF4OlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHNlZCgvKFxcdyspXFxzKFxcdyspLywgJyQyLCAkMScsICdmaWxlLnR4dCcpO1xuLy9AIGBgYFxuZnVuY3Rpb24gX3NlZChvcHRpb25zLCByZWdleCwgcmVwbGFjZW1lbnQsIGZpbGVzKSB7XG4gIC8vIENoZWNrIGlmIHRoaXMgaXMgY29taW5nIGZyb20gYSBwaXBlXG4gIHZhciBwaXBlID0gY29tbW9uLnJlYWRGcm9tUGlwZSgpO1xuXG4gIGlmICh0eXBlb2YgcmVwbGFjZW1lbnQgIT09ICdzdHJpbmcnICYmIHR5cGVvZiByZXBsYWNlbWVudCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIGlmICh0eXBlb2YgcmVwbGFjZW1lbnQgPT09ICdudW1iZXInKSB7XG4gICAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50LnRvU3RyaW5nKCk7IC8vIGZhbGxiYWNrXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbW1vbi5lcnJvcignaW52YWxpZCByZXBsYWNlbWVudCBzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICAvLyBDb252ZXJ0IGFsbCBzZWFyY2ggc3RyaW5ncyB0byBSZWdFeHBcbiAgaWYgKHR5cGVvZiByZWdleCA9PT0gJ3N0cmluZycpIHtcbiAgICByZWdleCA9IFJlZ0V4cChyZWdleCk7XG4gIH1cblxuICBpZiAoIWZpbGVzICYmICFwaXBlKSB7XG4gICAgY29tbW9uLmVycm9yKCdubyBmaWxlcyBnaXZlbicpO1xuICB9XG5cbiAgZmlsZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMyk7XG5cbiAgaWYgKHBpcGUpIHtcbiAgICBmaWxlcy51bnNoaWZ0KCctJyk7XG4gIH1cblxuICB2YXIgc2VkID0gW107XG4gIGZpbGVzLmZvckVhY2goZnVuY3Rpb24gKGZpbGUpIHtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZSkgJiYgZmlsZSAhPT0gJy0nKSB7XG4gICAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBmaWxlLCAyLCB7IGNvbnRpbnVlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBjb250ZW50cyA9IGZpbGUgPT09ICctJyA/IHBpcGUgOiBmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0ZjgnKTtcbiAgICB2YXIgbGluZXMgPSBjb250ZW50cy5zcGxpdCgnXFxuJyk7XG4gICAgdmFyIHJlc3VsdCA9IGxpbmVzLm1hcChmdW5jdGlvbiAobGluZSkge1xuICAgICAgcmV0dXJuIGxpbmUucmVwbGFjZShyZWdleCwgcmVwbGFjZW1lbnQpO1xuICAgIH0pLmpvaW4oJ1xcbicpO1xuXG4gICAgc2VkLnB1c2gocmVzdWx0KTtcblxuICAgIGlmIChvcHRpb25zLmlucGxhY2UpIHtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZSwgcmVzdWx0LCAndXRmOCcpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHNlZC5qb2luKCdcXG4nKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX3NlZDtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ3NldCcsIF9zZXQsIHtcbiAgYWxsb3dHbG9iYmluZzogZmFsc2UsXG4gIHdyYXBPdXRwdXQ6IGZhbHNlLFxufSk7XG5cbi8vQFxuLy9AICMjIyBzZXQob3B0aW9ucylcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgKy8tZWA6IGV4aXQgdXBvbiBlcnJvciAoYGNvbmZpZy5mYXRhbGApXG4vL0AgKyBgKy8tdmA6IHZlcmJvc2U6IHNob3cgYWxsIGNvbW1hbmRzIChgY29uZmlnLnZlcmJvc2VgKVxuLy9AICsgYCsvLWZgOiBkaXNhYmxlIGZpbGVuYW1lIGV4cGFuc2lvbiAoZ2xvYmJpbmcpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCBzZXQoJy1lJyk7IC8vIGV4aXQgdXBvbiBmaXJzdCBlcnJvclxuLy9AIHNldCgnK2UnKTsgLy8gdGhpcyB1bmRvZXMgYSBcInNldCgnLWUnKVwiXG4vL0AgYGBgXG4vL0Bcbi8vQCBTZXRzIGdsb2JhbCBjb25maWd1cmF0aW9uIHZhcmlhYmxlcy5cbmZ1bmN0aW9uIF9zZXQob3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgICBpZiAoYXJncy5sZW5ndGggPCAyKSBjb21tb24uZXJyb3IoJ211c3QgcHJvdmlkZSBhbiBhcmd1bWVudCcpO1xuICAgIG9wdGlvbnMgPSBhcmdzWzFdO1xuICB9XG4gIHZhciBuZWdhdGUgPSAob3B0aW9uc1swXSA9PT0gJysnKTtcbiAgaWYgKG5lZ2F0ZSkge1xuICAgIG9wdGlvbnMgPSAnLScgKyBvcHRpb25zLnNsaWNlKDEpOyAvLyBwYXJzZU9wdGlvbnMgbmVlZHMgYSAnLScgcHJlZml4XG4gIH1cbiAgb3B0aW9ucyA9IGNvbW1vbi5wYXJzZU9wdGlvbnMob3B0aW9ucywge1xuICAgICdlJzogJ2ZhdGFsJyxcbiAgICAndic6ICd2ZXJib3NlJyxcbiAgICAnZic6ICdub2dsb2InLFxuICB9KTtcblxuICBpZiAobmVnYXRlKSB7XG4gICAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBvcHRpb25zW2tleV0gPSAhb3B0aW9uc1trZXldO1xuICAgIH0pO1xuICB9XG5cbiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgLy8gT25seSBjaGFuZ2UgdGhlIGdsb2JhbCBjb25maWcgaWYgYG5lZ2F0ZWAgaXMgZmFsc2UgYW5kIHRoZSBvcHRpb24gaXMgdHJ1ZVxuICAgIC8vIG9yIGlmIGBuZWdhdGVgIGlzIHRydWUgYW5kIHRoZSBvcHRpb24gaXMgZmFsc2UgKGFrYSBuZWdhdGUgIT09IG9wdGlvbilcbiAgICBpZiAobmVnYXRlICE9PSBvcHRpb25zW2tleV0pIHtcbiAgICAgIGNvbW1vbi5jb25maWdba2V5XSA9IG9wdGlvbnNba2V5XTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm47XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9zZXQ7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbmNvbW1vbi5yZWdpc3Rlcignc29ydCcsIF9zb3J0LCB7XG4gIGNhblJlY2VpdmVQaXBlOiB0cnVlLFxuICBjbWRPcHRpb25zOiB7XG4gICAgJ3InOiAncmV2ZXJzZScsXG4gICAgJ24nOiAnbnVtZXJpY2FsJyxcbiAgfSxcbn0pO1xuXG4vLyBwYXJzZSBvdXQgdGhlIG51bWJlciBwcmVmaXggb2YgYSBsaW5lXG5mdW5jdGlvbiBwYXJzZU51bWJlcihzdHIpIHtcbiAgdmFyIG1hdGNoID0gc3RyLm1hdGNoKC9eXFxzKihcXGQqKVxccyooLiopJC8pO1xuICByZXR1cm4geyBudW06IE51bWJlcihtYXRjaFsxXSksIHZhbHVlOiBtYXRjaFsyXSB9O1xufVxuXG4vLyBjb21wYXJlIHR3byBzdHJpbmdzIGNhc2UtaW5zZW5zaXRpdmVseSwgYnV0IGV4YW1pbmUgY2FzZSBmb3Igc3RyaW5ncyB0aGF0IGFyZVxuLy8gY2FzZS1pbnNlbnNpdGl2ZSBlcXVpdmFsZW50XG5mdW5jdGlvbiB1bml4Q21wKGEsIGIpIHtcbiAgdmFyIGFMb3dlciA9IGEudG9Mb3dlckNhc2UoKTtcbiAgdmFyIGJMb3dlciA9IGIudG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIChhTG93ZXIgPT09IGJMb3dlciA/XG4gICAgICAtMSAqIGEubG9jYWxlQ29tcGFyZShiKSA6IC8vIHVuaXggc29ydCB0cmVhdHMgY2FzZSBvcHBvc2l0ZSBob3cgamF2YXNjcmlwdCBkb2VzXG4gICAgICBhTG93ZXIubG9jYWxlQ29tcGFyZShiTG93ZXIpKTtcbn1cblxuLy8gY29tcGFyZSB0d28gc3RyaW5ncyBpbiB0aGUgZmFzaGlvbiB0aGF0IHVuaXggc29ydCdzIC1uIG9wdGlvbiB3b3Jrc1xuZnVuY3Rpb24gbnVtZXJpY2FsQ21wKGEsIGIpIHtcbiAgdmFyIG9iakEgPSBwYXJzZU51bWJlcihhKTtcbiAgdmFyIG9iakIgPSBwYXJzZU51bWJlcihiKTtcbiAgaWYgKG9iakEuaGFzT3duUHJvcGVydHkoJ251bScpICYmIG9iakIuaGFzT3duUHJvcGVydHkoJ251bScpKSB7XG4gICAgcmV0dXJuICgob2JqQS5udW0gIT09IG9iakIubnVtKSA/XG4gICAgICAgIChvYmpBLm51bSAtIG9iakIubnVtKSA6XG4gICAgICAgIHVuaXhDbXAob2JqQS52YWx1ZSwgb2JqQi52YWx1ZSkpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bml4Q21wKG9iakEudmFsdWUsIG9iakIudmFsdWUpO1xuICB9XG59XG5cbi8vQFxuLy9AICMjIyBzb3J0KFtvcHRpb25zLF0gZmlsZSBbLCBmaWxlIC4uLl0pXG4vL0AgIyMjIHNvcnQoW29wdGlvbnMsXSBmaWxlX2FycmF5KVxuLy9AXG4vL0AgQXZhaWxhYmxlIG9wdGlvbnM6XG4vL0Bcbi8vQCArIGAtcmA6IFJldmVyc2UgdGhlIHJlc3VsdHNcbi8vQCArIGAtbmA6IENvbXBhcmUgYWNjb3JkaW5nIHRvIG51bWVyaWNhbCB2YWx1ZVxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0Agc29ydCgnZm9vLnR4dCcsICdiYXIudHh0Jyk7XG4vL0Agc29ydCgnLXInLCAnZm9vLnR4dCcpO1xuLy9AIGBgYFxuLy9AXG4vL0AgUmV0dXJuIHRoZSBjb250ZW50cyBvZiB0aGUgYGZpbGVgcywgc29ydGVkIGxpbmUtYnktbGluZS4gU29ydGluZyBtdWx0aXBsZVxuLy9AIGZpbGVzIG1peGVzIHRoZWlyIGNvbnRlbnQgKGp1c3QgYXMgdW5peCBgc29ydGAgZG9lcykuXG5mdW5jdGlvbiBfc29ydChvcHRpb25zLCBmaWxlcykge1xuICAvLyBDaGVjayBpZiB0aGlzIGlzIGNvbWluZyBmcm9tIGEgcGlwZVxuICB2YXIgcGlwZSA9IGNvbW1vbi5yZWFkRnJvbVBpcGUoKTtcblxuICBpZiAoIWZpbGVzICYmICFwaXBlKSBjb21tb24uZXJyb3IoJ25vIGZpbGVzIGdpdmVuJyk7XG5cbiAgZmlsZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cbiAgaWYgKHBpcGUpIHtcbiAgICBmaWxlcy51bnNoaWZ0KCctJyk7XG4gIH1cblxuICB2YXIgbGluZXMgPSBmaWxlcy5yZWR1Y2UoZnVuY3Rpb24gKGFjY3VtLCBmaWxlKSB7XG4gICAgaWYgKGZpbGUgIT09ICctJykge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGZpbGUpKSB7XG4gICAgICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIGZpbGUsIHsgY29udGludWU6IHRydWUgfSk7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0gZWxzZSBpZiAoY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGNvbW1vbi5lcnJvcigncmVhZCBmYWlsZWQ6ICcgKyBmaWxlICsgJzogSXMgYSBkaXJlY3RvcnknLCB7XG4gICAgICAgICAgY29udGludWU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGNvbnRlbnRzID0gZmlsZSA9PT0gJy0nID8gcGlwZSA6IGZzLnJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpO1xuICAgIHJldHVybiBhY2N1bS5jb25jYXQoY29udGVudHMudHJpbVJpZ2h0KCkuc3BsaXQoJ1xcbicpKTtcbiAgfSwgW10pO1xuXG4gIHZhciBzb3J0ZWQgPSBsaW5lcy5zb3J0KG9wdGlvbnMubnVtZXJpY2FsID8gbnVtZXJpY2FsQ21wIDogdW5peENtcCk7XG5cbiAgaWYgKG9wdGlvbnMucmV2ZXJzZSkge1xuICAgIHNvcnRlZCA9IHNvcnRlZC5yZXZlcnNlKCk7XG4gIH1cblxuICByZXR1cm4gc29ydGVkLmpvaW4oJ1xcbicpICsgJ1xcbic7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX3NvcnQ7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbmNvbW1vbi5yZWdpc3RlcigndGFpbCcsIF90YWlsLCB7XG4gIGNhblJlY2VpdmVQaXBlOiB0cnVlLFxuICBjbWRPcHRpb25zOiB7XG4gICAgJ24nOiAnbnVtTGluZXMnLFxuICB9LFxufSk7XG5cbi8vQFxuLy9AICMjIyB0YWlsKFt7Jy1uJzogXFw8bnVtXFw+fSxdIGZpbGUgWywgZmlsZSAuLi5dKVxuLy9AICMjIyB0YWlsKFt7Jy1uJzogXFw8bnVtXFw+fSxdIGZpbGVfYXJyYXkpXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1uIDxudW0+YDogU2hvdyB0aGUgbGFzdCBgPG51bT5gIGxpbmVzIG9mIGBmaWxlYHNcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHZhciBzdHIgPSB0YWlsKHsnLW4nOiAxfSwgJ2ZpbGUqLnR4dCcpO1xuLy9AIHZhciBzdHIgPSB0YWlsKCdmaWxlMScsICdmaWxlMicpO1xuLy9AIHZhciBzdHIgPSB0YWlsKFsnZmlsZTEnLCAnZmlsZTInXSk7IC8vIHNhbWUgYXMgYWJvdmVcbi8vQCBgYGBcbi8vQFxuLy9AIFJlYWQgdGhlIGVuZCBvZiBhIGBmaWxlYC5cbmZ1bmN0aW9uIF90YWlsKG9wdGlvbnMsIGZpbGVzKSB7XG4gIHZhciB0YWlsID0gW107XG4gIHZhciBwaXBlID0gY29tbW9uLnJlYWRGcm9tUGlwZSgpO1xuXG4gIGlmICghZmlsZXMgJiYgIXBpcGUpIGNvbW1vbi5lcnJvcignbm8gcGF0aHMgZ2l2ZW4nKTtcblxuICB2YXIgaWR4ID0gMTtcbiAgaWYgKG9wdGlvbnMubnVtTGluZXMgPT09IHRydWUpIHtcbiAgICBpZHggPSAyO1xuICAgIG9wdGlvbnMubnVtTGluZXMgPSBOdW1iZXIoYXJndW1lbnRzWzFdKTtcbiAgfSBlbHNlIGlmIChvcHRpb25zLm51bUxpbmVzID09PSBmYWxzZSkge1xuICAgIG9wdGlvbnMubnVtTGluZXMgPSAxMDtcbiAgfVxuICBvcHRpb25zLm51bUxpbmVzID0gLTEgKiBNYXRoLmFicyhvcHRpb25zLm51bUxpbmVzKTtcbiAgZmlsZXMgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgaWR4KTtcblxuICBpZiAocGlwZSkge1xuICAgIGZpbGVzLnVuc2hpZnQoJy0nKTtcbiAgfVxuXG4gIHZhciBzaG91bGRBcHBlbmROZXdsaW5lID0gZmFsc2U7XG4gIGZpbGVzLmZvckVhY2goZnVuY3Rpb24gKGZpbGUpIHtcbiAgICBpZiAoZmlsZSAhPT0gJy0nKSB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZSkpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKCdubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5OiAnICsgZmlsZSwgeyBjb250aW51ZTogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIGlmIChjb21tb24uc3RhdEZvbGxvd0xpbmtzKGZpbGUpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgY29tbW9uLmVycm9yKFwiZXJyb3IgcmVhZGluZyAnXCIgKyBmaWxlICsgXCInOiBJcyBhIGRpcmVjdG9yeVwiLCB7XG4gICAgICAgICAgY29udGludWU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGNvbnRlbnRzID0gZmlsZSA9PT0gJy0nID8gcGlwZSA6IGZzLnJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpO1xuXG4gICAgdmFyIGxpbmVzID0gY29udGVudHMuc3BsaXQoJ1xcbicpO1xuICAgIGlmIChsaW5lc1tsaW5lcy5sZW5ndGggLSAxXSA9PT0gJycpIHtcbiAgICAgIGxpbmVzLnBvcCgpO1xuICAgICAgc2hvdWxkQXBwZW5kTmV3bGluZSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNob3VsZEFwcGVuZE5ld2xpbmUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICB0YWlsID0gdGFpbC5jb25jYXQobGluZXMuc2xpY2Uob3B0aW9ucy5udW1MaW5lcykpO1xuICB9KTtcblxuICBpZiAoc2hvdWxkQXBwZW5kTmV3bGluZSkge1xuICAgIHRhaWwucHVzaCgnJyk7IC8vIHRvIGFkZCBhIHRyYWlsaW5nIG5ld2xpbmUgb25jZSB3ZSBqb2luXG4gIH1cbiAgcmV0dXJuIHRhaWwuam9pbignXFxuJyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF90YWlsO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgb3MgPSByZXF1aXJlKCdvcycpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCd0ZW1wZGlyJywgX3RlbXBEaXIsIHtcbiAgYWxsb3dHbG9iYmluZzogZmFsc2UsXG4gIHdyYXBPdXRwdXQ6IGZhbHNlLFxufSk7XG5cbi8vIFJldHVybnMgZmFsc2UgaWYgJ2RpcicgaXMgbm90IGEgd3JpdGVhYmxlIGRpcmVjdG9yeSwgJ2Rpcicgb3RoZXJ3aXNlXG5mdW5jdGlvbiB3cml0ZWFibGVEaXIoZGlyKSB7XG4gIGlmICghZGlyIHx8ICFmcy5leGlzdHNTeW5jKGRpcikpIHJldHVybiBmYWxzZTtcblxuICBpZiAoIWNvbW1vbi5zdGF0Rm9sbG93TGlua3MoZGlyKS5pc0RpcmVjdG9yeSgpKSByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIHRlc3RGaWxlID0gZGlyICsgJy8nICsgY29tbW9uLnJhbmRvbUZpbGVOYW1lKCk7XG4gIHRyeSB7XG4gICAgZnMud3JpdGVGaWxlU3luYyh0ZXN0RmlsZSwgJyAnKTtcbiAgICBjb21tb24udW5saW5rU3luYyh0ZXN0RmlsZSk7XG4gICAgcmV0dXJuIGRpcjtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8vIFZhcmlhYmxlIHRvIGNhY2hlIHRoZSB0ZW1wZGlyIHZhbHVlIGZvciBzdWNjZXNzaXZlIGxvb2t1cHMuXG52YXIgY2FjaGVkVGVtcERpcjtcblxuLy9AXG4vL0AgIyMjIHRlbXBkaXIoKVxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgdmFyIHRtcCA9IHRlbXBkaXIoKTsgLy8gXCIvdG1wXCIgZm9yIG1vc3QgKm5peCBwbGF0Zm9ybXNcbi8vQCBgYGBcbi8vQFxuLy9AIFNlYXJjaGVzIGFuZCByZXR1cm5zIHN0cmluZyBjb250YWluaW5nIGEgd3JpdGVhYmxlLCBwbGF0Zm9ybS1kZXBlbmRlbnQgdGVtcG9yYXJ5IGRpcmVjdG9yeS5cbi8vQCBGb2xsb3dzIFB5dGhvbidzIFt0ZW1wZmlsZSBhbGdvcml0aG1dKGh0dHA6Ly9kb2NzLnB5dGhvbi5vcmcvbGlicmFyeS90ZW1wZmlsZS5odG1sI3RlbXBmaWxlLnRlbXBkaXIpLlxuZnVuY3Rpb24gX3RlbXBEaXIoKSB7XG4gIGlmIChjYWNoZWRUZW1wRGlyKSByZXR1cm4gY2FjaGVkVGVtcERpcjtcblxuICBjYWNoZWRUZW1wRGlyID0gd3JpdGVhYmxlRGlyKG9zLnRtcGRpcigpKSB8fFxuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKHByb2Nlc3MuZW52LlRNUERJUikgfHxcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcihwcm9jZXNzLmVudi5URU1QKSB8fFxuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKHByb2Nlc3MuZW52LlRNUCkgfHxcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcihwcm9jZXNzLmVudi5XaW1wJFNjcmFwRGlyKSB8fCAvLyBSaXNjT1NcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignQzpcXFxcVEVNUCcpIHx8IC8vIFdpbmRvd3NcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignQzpcXFxcVE1QJykgfHwgLy8gV2luZG93c1xuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKCdcXFxcVEVNUCcpIHx8IC8vIFdpbmRvd3NcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignXFxcXFRNUCcpIHx8IC8vIFdpbmRvd3NcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignL3RtcCcpIHx8XG4gICAgICAgICAgICAgICAgICB3cml0ZWFibGVEaXIoJy92YXIvdG1wJykgfHxcbiAgICAgICAgICAgICAgICAgIHdyaXRlYWJsZURpcignL3Vzci90bXAnKSB8fFxuICAgICAgICAgICAgICAgICAgd3JpdGVhYmxlRGlyKCcuJyk7IC8vIGxhc3QgcmVzb3J0XG5cbiAgcmV0dXJuIGNhY2hlZFRlbXBEaXI7XG59XG5cbi8vIEluZGljYXRlcyBpZiB0aGUgdGVtcGRpciB2YWx1ZSBpcyBjdXJyZW50bHkgY2FjaGVkLiBUaGlzIGlzIGV4cG9zZWQgZm9yIHRlc3RzXG4vLyBvbmx5LiBUaGUgcmV0dXJuIHZhbHVlIHNob3VsZCBvbmx5IGJlIHRlc3RlZCBmb3IgdHJ1dGhpbmVzcy5cbmZ1bmN0aW9uIGlzQ2FjaGVkKCkge1xuICByZXR1cm4gY2FjaGVkVGVtcERpcjtcbn1cblxuLy8gQ2xlYXJzIHRoZSBjYWNoZWQgdGVtcERpciB2YWx1ZSwgaWYgb25lIGlzIGNhY2hlZC4gVGhpcyBpcyBleHBvc2VkIGZvciB0ZXN0c1xuLy8gb25seS5cbmZ1bmN0aW9uIGNsZWFyQ2FjaGUoKSB7XG4gIGNhY2hlZFRlbXBEaXIgPSB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzLnRlbXBEaXIgPSBfdGVtcERpcjtcbm1vZHVsZS5leHBvcnRzLmlzQ2FjaGVkID0gaXNDYWNoZWQ7XG5tb2R1bGUuZXhwb3J0cy5jbGVhckNhY2hlID0gY2xlYXJDYWNoZTtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCd0ZXN0JywgX3Rlc3QsIHtcbiAgY21kT3B0aW9uczoge1xuICAgICdiJzogJ2Jsb2NrJyxcbiAgICAnYyc6ICdjaGFyYWN0ZXInLFxuICAgICdkJzogJ2RpcmVjdG9yeScsXG4gICAgJ2UnOiAnZXhpc3RzJyxcbiAgICAnZic6ICdmaWxlJyxcbiAgICAnTCc6ICdsaW5rJyxcbiAgICAncCc6ICdwaXBlJyxcbiAgICAnUyc6ICdzb2NrZXQnLFxuICB9LFxuICB3cmFwT3V0cHV0OiBmYWxzZSxcbiAgYWxsb3dHbG9iYmluZzogZmFsc2UsXG59KTtcblxuXG4vL0Bcbi8vQCAjIyMgdGVzdChleHByZXNzaW9uKVxuLy9AXG4vL0AgQXZhaWxhYmxlIGV4cHJlc3Npb24gcHJpbWFyaWVzOlxuLy9AXG4vL0AgKyBgJy1iJywgJ3BhdGgnYDogdHJ1ZSBpZiBwYXRoIGlzIGEgYmxvY2sgZGV2aWNlXG4vL0AgKyBgJy1jJywgJ3BhdGgnYDogdHJ1ZSBpZiBwYXRoIGlzIGEgY2hhcmFjdGVyIGRldmljZVxuLy9AICsgYCctZCcsICdwYXRoJ2A6IHRydWUgaWYgcGF0aCBpcyBhIGRpcmVjdG9yeVxuLy9AICsgYCctZScsICdwYXRoJ2A6IHRydWUgaWYgcGF0aCBleGlzdHNcbi8vQCArIGAnLWYnLCAncGF0aCdgOiB0cnVlIGlmIHBhdGggaXMgYSByZWd1bGFyIGZpbGVcbi8vQCArIGAnLUwnLCAncGF0aCdgOiB0cnVlIGlmIHBhdGggaXMgYSBzeW1ib2xpYyBsaW5rXG4vL0AgKyBgJy1wJywgJ3BhdGgnYDogdHJ1ZSBpZiBwYXRoIGlzIGEgcGlwZSAoRklGTylcbi8vQCArIGAnLVMnLCAncGF0aCdgOiB0cnVlIGlmIHBhdGggaXMgYSBzb2NrZXRcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIGlmICh0ZXN0KCctZCcsIHBhdGgpKSB7IC8qIGRvIHNvbWV0aGluZyB3aXRoIGRpciAqLyB9O1xuLy9AIGlmICghdGVzdCgnLWYnLCBwYXRoKSkgY29udGludWU7IC8vIHNraXAgaWYgaXQncyBhIHJlZ3VsYXIgZmlsZVxuLy9AIGBgYFxuLy9AXG4vL0AgRXZhbHVhdGVzIGBleHByZXNzaW9uYCB1c2luZyB0aGUgYXZhaWxhYmxlIHByaW1hcmllcyBhbmQgcmV0dXJucyBjb3JyZXNwb25kaW5nIHZhbHVlLlxuZnVuY3Rpb24gX3Rlc3Qob3B0aW9ucywgcGF0aCkge1xuICBpZiAoIXBhdGgpIGNvbW1vbi5lcnJvcignbm8gcGF0aCBnaXZlbicpO1xuXG4gIHZhciBjYW5JbnRlcnByZXQgPSBmYWxzZTtcbiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgaWYgKG9wdGlvbnNba2V5XSA9PT0gdHJ1ZSkge1xuICAgICAgY2FuSW50ZXJwcmV0ID0gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIGlmICghY2FuSW50ZXJwcmV0KSBjb21tb24uZXJyb3IoJ2NvdWxkIG5vdCBpbnRlcnByZXQgZXhwcmVzc2lvbicpO1xuXG4gIGlmIChvcHRpb25zLmxpbmspIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGNvbW1vbi5zdGF0Tm9Gb2xsb3dMaW5rcyhwYXRoKS5pc1N5bWJvbGljTGluaygpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBpZiAoIWZzLmV4aXN0c1N5bmMocGF0aCkpIHJldHVybiBmYWxzZTtcblxuICBpZiAob3B0aW9ucy5leGlzdHMpIHJldHVybiB0cnVlO1xuXG4gIHZhciBzdGF0cyA9IGNvbW1vbi5zdGF0Rm9sbG93TGlua3MocGF0aCk7XG5cbiAgaWYgKG9wdGlvbnMuYmxvY2spIHJldHVybiBzdGF0cy5pc0Jsb2NrRGV2aWNlKCk7XG5cbiAgaWYgKG9wdGlvbnMuY2hhcmFjdGVyKSByZXR1cm4gc3RhdHMuaXNDaGFyYWN0ZXJEZXZpY2UoKTtcblxuICBpZiAob3B0aW9ucy5kaXJlY3RvcnkpIHJldHVybiBzdGF0cy5pc0RpcmVjdG9yeSgpO1xuXG4gIGlmIChvcHRpb25zLmZpbGUpIHJldHVybiBzdGF0cy5pc0ZpbGUoKTtcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAob3B0aW9ucy5waXBlKSByZXR1cm4gc3RhdHMuaXNGSUZPKCk7XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgaWYgKG9wdGlvbnMuc29ja2V0KSByZXR1cm4gc3RhdHMuaXNTb2NrZXQoKTtcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICByZXR1cm4gZmFsc2U7IC8vIGZhbGxiYWNrXG59IC8vIHRlc3Rcbm1vZHVsZS5leHBvcnRzID0gX3Rlc3Q7XG4iLCJ2YXIgY29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcblxuY29tbW9uLnJlZ2lzdGVyKCd0bycsIF90bywge1xuICBwaXBlT25seTogdHJ1ZSxcbiAgd3JhcE91dHB1dDogZmFsc2UsXG59KTtcblxuLy9AXG4vL0AgIyMjIFNoZWxsU3RyaW5nLnByb3RvdHlwZS50byhmaWxlKVxuLy9AXG4vL0AgRXhhbXBsZXM6XG4vL0Bcbi8vQCBgYGBqYXZhc2NyaXB0XG4vL0AgY2F0KCdpbnB1dC50eHQnKS50bygnb3V0cHV0LnR4dCcpO1xuLy9AIGBgYFxuLy9AXG4vL0AgQW5hbG9nb3VzIHRvIHRoZSByZWRpcmVjdGlvbiBvcGVyYXRvciBgPmAgaW4gVW5peCwgYnV0IHdvcmtzIHdpdGhcbi8vQCBgU2hlbGxTdHJpbmdzYCAoc3VjaCBhcyB0aG9zZSByZXR1cm5lZCBieSBgY2F0YCwgYGdyZXBgLCBldGMuKS4gX0xpa2UgVW5peFxuLy9AIHJlZGlyZWN0aW9ucywgYHRvKClgIHdpbGwgb3ZlcndyaXRlIGFueSBleGlzdGluZyBmaWxlIV9cbmZ1bmN0aW9uIF90byhvcHRpb25zLCBmaWxlKSB7XG4gIGlmICghZmlsZSkgY29tbW9uLmVycm9yKCd3cm9uZyBhcmd1bWVudHMnKTtcblxuICBpZiAoIWZzLmV4aXN0c1N5bmMocGF0aC5kaXJuYW1lKGZpbGUpKSkge1xuICAgIGNvbW1vbi5lcnJvcignbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeTogJyArIHBhdGguZGlybmFtZShmaWxlKSk7XG4gIH1cblxuICB0cnkge1xuICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZSwgdGhpcy5zdGRvdXQgfHwgdGhpcy50b1N0cmluZygpLCAndXRmOCcpO1xuICAgIHJldHVybiB0aGlzO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBjb21tb24uZXJyb3IoJ2NvdWxkIG5vdCB3cml0ZSB0byBmaWxlIChjb2RlICcgKyBlLmNvZGUgKyAnKTogJyArIGZpbGUsIHsgY29udGludWU6IHRydWUgfSk7XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gX3RvO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5cbmNvbW1vbi5yZWdpc3RlcigndG9FbmQnLCBfdG9FbmQsIHtcbiAgcGlwZU9ubHk6IHRydWUsXG4gIHdyYXBPdXRwdXQ6IGZhbHNlLFxufSk7XG5cbi8vQFxuLy9AICMjIyBTaGVsbFN0cmluZy5wcm90b3R5cGUudG9FbmQoZmlsZSlcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIGNhdCgnaW5wdXQudHh0JykudG9FbmQoJ291dHB1dC50eHQnKTtcbi8vQCBgYGBcbi8vQFxuLy9AIEFuYWxvZ291cyB0byB0aGUgcmVkaXJlY3QtYW5kLWFwcGVuZCBvcGVyYXRvciBgPj5gIGluIFVuaXgsIGJ1dCB3b3JrcyB3aXRoXG4vL0AgYFNoZWxsU3RyaW5nc2AgKHN1Y2ggYXMgdGhvc2UgcmV0dXJuZWQgYnkgYGNhdGAsIGBncmVwYCwgZXRjLikuXG5mdW5jdGlvbiBfdG9FbmQob3B0aW9ucywgZmlsZSkge1xuICBpZiAoIWZpbGUpIGNvbW1vbi5lcnJvcignd3JvbmcgYXJndW1lbnRzJyk7XG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKHBhdGguZGlybmFtZShmaWxlKSkpIHtcbiAgICBjb21tb24uZXJyb3IoJ25vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnk6ICcgKyBwYXRoLmRpcm5hbWUoZmlsZSkpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBmcy5hcHBlbmRGaWxlU3luYyhmaWxlLCB0aGlzLnN0ZG91dCB8fCB0aGlzLnRvU3RyaW5nKCksICd1dGY4Jyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGNvbW1vbi5lcnJvcignY291bGQgbm90IGFwcGVuZCB0byBmaWxlIChjb2RlICcgKyBlLmNvZGUgKyAnKTogJyArIGZpbGUsIHsgY29udGludWU6IHRydWUgfSk7XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gX3RvRW5kO1xuIiwidmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgZnMgPSByZXF1aXJlKCdmcycpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ3RvdWNoJywgX3RvdWNoLCB7XG4gIGNtZE9wdGlvbnM6IHtcbiAgICAnYSc6ICdhdGltZV9vbmx5JyxcbiAgICAnYyc6ICdub19jcmVhdGUnLFxuICAgICdkJzogJ2RhdGUnLFxuICAgICdtJzogJ210aW1lX29ubHknLFxuICAgICdyJzogJ3JlZmVyZW5jZScsXG4gIH0sXG59KTtcblxuLy9AXG4vL0AgIyMjIHRvdWNoKFtvcHRpb25zLF0gZmlsZSBbLCBmaWxlIC4uLl0pXG4vL0AgIyMjIHRvdWNoKFtvcHRpb25zLF0gZmlsZV9hcnJheSlcbi8vQFxuLy9AIEF2YWlsYWJsZSBvcHRpb25zOlxuLy9AXG4vL0AgKyBgLWFgOiBDaGFuZ2Ugb25seSB0aGUgYWNjZXNzIHRpbWVcbi8vQCArIGAtY2A6IERvIG5vdCBjcmVhdGUgYW55IGZpbGVzXG4vL0AgKyBgLW1gOiBDaGFuZ2Ugb25seSB0aGUgbW9kaWZpY2F0aW9uIHRpbWVcbi8vQCArIGAtZCBEQVRFYDogUGFyc2UgYERBVEVgIGFuZCB1c2UgaXQgaW5zdGVhZCBvZiBjdXJyZW50IHRpbWVcbi8vQCArIGAtciBGSUxFYDogVXNlIGBGSUxFYCdzIHRpbWVzIGluc3RlYWQgb2YgY3VycmVudCB0aW1lXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCB0b3VjaCgnc291cmNlLmpzJyk7XG4vL0AgdG91Y2goJy1jJywgJy9wYXRoL3RvL3NvbWUvZGlyL3NvdXJjZS5qcycpO1xuLy9AIHRvdWNoKHsgJy1yJzogRklMRSB9LCAnL3BhdGgvdG8vc29tZS9kaXIvc291cmNlLmpzJyk7XG4vL0AgYGBgXG4vL0Bcbi8vQCBVcGRhdGUgdGhlIGFjY2VzcyBhbmQgbW9kaWZpY2F0aW9uIHRpbWVzIG9mIGVhY2ggYEZJTEVgIHRvIHRoZSBjdXJyZW50IHRpbWUuXG4vL0AgQSBgRklMRWAgYXJndW1lbnQgdGhhdCBkb2VzIG5vdCBleGlzdCBpcyBjcmVhdGVkIGVtcHR5LCB1bmxlc3MgYC1jYCBpcyBzdXBwbGllZC5cbi8vQCBUaGlzIGlzIGEgcGFydGlhbCBpbXBsZW1lbnRhdGlvbiBvZiBbYHRvdWNoKDEpYF0oaHR0cDovL2xpbnV4LmRpZS5uZXQvbWFuLzEvdG91Y2gpLlxuZnVuY3Rpb24gX3RvdWNoKG9wdHMsIGZpbGVzKSB7XG4gIGlmICghZmlsZXMpIHtcbiAgICBjb21tb24uZXJyb3IoJ25vIGZpbGVzIGdpdmVuJyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGZpbGVzID09PSAnc3RyaW5nJykge1xuICAgIGZpbGVzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICB9IGVsc2Uge1xuICAgIGNvbW1vbi5lcnJvcignZmlsZSBhcmcgc2hvdWxkIGJlIGEgc3RyaW5nIGZpbGUgcGF0aCBvciBhbiBBcnJheSBvZiBzdHJpbmcgZmlsZSBwYXRocycpO1xuICB9XG5cbiAgZmlsZXMuZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgIHRvdWNoRmlsZShvcHRzLCBmKTtcbiAgfSk7XG4gIHJldHVybiAnJztcbn1cblxuZnVuY3Rpb24gdG91Y2hGaWxlKG9wdHMsIGZpbGUpIHtcbiAgdmFyIHN0YXQgPSB0cnlTdGF0RmlsZShmaWxlKTtcblxuICBpZiAoc3RhdCAmJiBzdGF0LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAvLyBkb24ndCBlcnJvciBqdXN0IGV4aXRcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBpZiB0aGUgZmlsZSBkb2Vzbid0IGFscmVhZHkgZXhpc3QgYW5kIHRoZSB1c2VyIGhhcyBzcGVjaWZpZWQgLS1uby1jcmVhdGUgdGhlblxuICAvLyB0aGlzIHNjcmlwdCBpcyBmaW5pc2hlZFxuICBpZiAoIXN0YXQgJiYgb3B0cy5ub19jcmVhdGUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBvcGVuIHRoZSBmaWxlIGFuZCB0aGVuIGNsb3NlIGl0LiB0aGlzIHdpbGwgY3JlYXRlIGl0IGlmIGl0IGRvZXNuJ3QgZXhpc3QgYnV0IHdpbGxcbiAgLy8gbm90IHRydW5jYXRlIHRoZSBmaWxlXG4gIGZzLmNsb3NlU3luYyhmcy5vcGVuU3luYyhmaWxlLCAnYScpKTtcblxuICAvL1xuICAvLyBTZXQgdGltZXN0YW1wc1xuICAvL1xuXG4gIC8vIHNldHVwIHNvbWUgZGVmYXVsdHNcbiAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7XG4gIHZhciBtdGltZSA9IG9wdHMuZGF0ZSB8fCBub3c7XG4gIHZhciBhdGltZSA9IG9wdHMuZGF0ZSB8fCBub3c7XG5cbiAgLy8gdXNlIHJlZmVyZW5jZSBmaWxlXG4gIGlmIChvcHRzLnJlZmVyZW5jZSkge1xuICAgIHZhciByZWZTdGF0ID0gdHJ5U3RhdEZpbGUob3B0cy5yZWZlcmVuY2UpO1xuICAgIGlmICghcmVmU3RhdCkge1xuICAgICAgY29tbW9uLmVycm9yKCdmYWlsZWQgdG8gZ2V0IGF0dHJpYnV0ZXNzIG9mICcgKyBvcHRzLnJlZmVyZW5jZSk7XG4gICAgfVxuICAgIG10aW1lID0gcmVmU3RhdC5tdGltZTtcbiAgICBhdGltZSA9IHJlZlN0YXQuYXRpbWU7XG4gIH0gZWxzZSBpZiAob3B0cy5kYXRlKSB7XG4gICAgbXRpbWUgPSBvcHRzLmRhdGU7XG4gICAgYXRpbWUgPSBvcHRzLmRhdGU7XG4gIH1cblxuICBpZiAob3B0cy5hdGltZV9vbmx5ICYmIG9wdHMubXRpbWVfb25seSkge1xuICAgIC8vIGtlZXAgdGhlIG5ldyB2YWx1ZXMgb2YgbXRpbWUgYW5kIGF0aW1lIGxpa2UgR05VXG4gIH0gZWxzZSBpZiAob3B0cy5hdGltZV9vbmx5KSB7XG4gICAgbXRpbWUgPSBzdGF0Lm10aW1lO1xuICB9IGVsc2UgaWYgKG9wdHMubXRpbWVfb25seSkge1xuICAgIGF0aW1lID0gc3RhdC5hdGltZTtcbiAgfVxuXG4gIGZzLnV0aW1lc1N5bmMoZmlsZSwgYXRpbWUsIG10aW1lKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfdG91Y2g7XG5cbmZ1bmN0aW9uIHRyeVN0YXRGaWxlKGZpbGVQYXRoKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGNvbW1vbi5zdGF0Rm9sbG93TGlua3MoZmlsZVBhdGgpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuLy8gYWRkIGMgc3BhY2VzIHRvIHRoZSBsZWZ0IG9mIHN0clxuZnVuY3Rpb24gbHBhZChjLCBzdHIpIHtcbiAgdmFyIHJlcyA9ICcnICsgc3RyO1xuICBpZiAocmVzLmxlbmd0aCA8IGMpIHtcbiAgICByZXMgPSBBcnJheSgoYyAtIHJlcy5sZW5ndGgpICsgMSkuam9pbignICcpICsgcmVzO1xuICB9XG4gIHJldHVybiByZXM7XG59XG5cbmNvbW1vbi5yZWdpc3RlcigndW5pcScsIF91bmlxLCB7XG4gIGNhblJlY2VpdmVQaXBlOiB0cnVlLFxuICBjbWRPcHRpb25zOiB7XG4gICAgJ2knOiAnaWdub3JlQ2FzZScsXG4gICAgJ2MnOiAnY291bnQnLFxuICAgICdkJzogJ2R1cGxpY2F0ZXMnLFxuICB9LFxufSk7XG5cbi8vQFxuLy9AICMjIyB1bmlxKFtvcHRpb25zLF0gW2lucHV0LCBbb3V0cHV0XV0pXG4vL0Bcbi8vQCBBdmFpbGFibGUgb3B0aW9uczpcbi8vQFxuLy9AICsgYC1pYDogSWdub3JlIGNhc2Ugd2hpbGUgY29tcGFyaW5nXG4vL0AgKyBgLWNgOiBQcmVmaXggbGluZXMgYnkgdGhlIG51bWJlciBvZiBvY2N1cnJlbmNlc1xuLy9AICsgYC1kYDogT25seSBwcmludCBkdXBsaWNhdGUgbGluZXMsIG9uZSBmb3IgZWFjaCBncm91cCBvZiBpZGVudGljYWwgbGluZXNcbi8vQFxuLy9AIEV4YW1wbGVzOlxuLy9AXG4vL0AgYGBgamF2YXNjcmlwdFxuLy9AIHVuaXEoJ2Zvby50eHQnKTtcbi8vQCB1bmlxKCctaScsICdmb28udHh0Jyk7XG4vL0AgdW5pcSgnLWNkJywgJ2Zvby50eHQnLCAnYmFyLnR4dCcpO1xuLy9AIGBgYFxuLy9AXG4vL0AgRmlsdGVyIGFkamFjZW50IG1hdGNoaW5nIGxpbmVzIGZyb20gYGlucHV0YC5cbmZ1bmN0aW9uIF91bmlxKG9wdGlvbnMsIGlucHV0LCBvdXRwdXQpIHtcbiAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBjb21pbmcgZnJvbSBhIHBpcGVcbiAgdmFyIHBpcGUgPSBjb21tb24ucmVhZEZyb21QaXBlKCk7XG5cbiAgaWYgKCFwaXBlKSB7XG4gICAgaWYgKCFpbnB1dCkgY29tbW9uLmVycm9yKCdubyBpbnB1dCBnaXZlbicpO1xuXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGlucHV0KSkge1xuICAgICAgY29tbW9uLmVycm9yKGlucHV0ICsgJzogTm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeScpO1xuICAgIH0gZWxzZSBpZiAoY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhpbnB1dCkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgY29tbW9uLmVycm9yKFwiZXJyb3IgcmVhZGluZyAnXCIgKyBpbnB1dCArIFwiJ1wiKTtcbiAgICB9XG4gIH1cbiAgaWYgKG91dHB1dCAmJiBmcy5leGlzdHNTeW5jKG91dHB1dCkgJiYgY29tbW9uLnN0YXRGb2xsb3dMaW5rcyhvdXRwdXQpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICBjb21tb24uZXJyb3Iob3V0cHV0ICsgJzogSXMgYSBkaXJlY3RvcnknKTtcbiAgfVxuXG4gIHZhciBsaW5lcyA9IChpbnB1dCA/IGZzLnJlYWRGaWxlU3luYyhpbnB1dCwgJ3V0ZjgnKSA6IHBpcGUpLlxuICAgICAgICAgICAgICB0cmltUmlnaHQoKS5cbiAgICAgICAgICAgICAgc3BsaXQoJ1xcbicpO1xuXG4gIHZhciBjb21wYXJlID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gb3B0aW9ucy5pZ25vcmVDYXNlID9cbiAgICAgICAgICAgYS50b0xvY2FsZUxvd2VyQ2FzZSgpLmxvY2FsZUNvbXBhcmUoYi50b0xvY2FsZUxvd2VyQ2FzZSgpKSA6XG4gICAgICAgICAgIGEubG9jYWxlQ29tcGFyZShiKTtcbiAgfTtcbiAgdmFyIHVuaXFlZCA9IGxpbmVzLnJlZHVjZVJpZ2h0KGZ1bmN0aW9uIChyZXMsIGUpIHtcbiAgICAvLyBQZXJmb3JtIHVuaXEgLWMgb24gdGhlIGlucHV0XG4gICAgaWYgKHJlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbeyBjb3VudDogMSwgbG46IGUgfV07XG4gICAgfSBlbHNlIGlmIChjb21wYXJlKHJlc1swXS5sbiwgZSkgPT09IDApIHtcbiAgICAgIHJldHVybiBbeyBjb3VudDogcmVzWzBdLmNvdW50ICsgMSwgbG46IGUgfV0uY29uY2F0KHJlcy5zbGljZSgxKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBbeyBjb3VudDogMSwgbG46IGUgfV0uY29uY2F0KHJlcyk7XG4gICAgfVxuICB9LCBbXSkuZmlsdGVyKGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgICAgICAgLy8gRG8gd2Ugd2FudCBvbmx5IGR1cGxpY2F0ZWQgb2JqZWN0cz9cbiAgICByZXR1cm4gb3B0aW9ucy5kdXBsaWNhdGVzID8gb2JqLmNvdW50ID4gMSA6IHRydWU7XG4gIH0pLm1hcChmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICAgICAgIC8vIEFyZSB3ZSB0cmFja2luZyB0aGUgY291bnRzIG9mIGVhY2ggbGluZT9cbiAgICByZXR1cm4gKG9wdGlvbnMuY291bnQgPyAobHBhZCg3LCBvYmouY291bnQpICsgJyAnKSA6ICcnKSArIG9iai5sbjtcbiAgfSkuam9pbignXFxuJykgKyAnXFxuJztcblxuICBpZiAob3V0cHV0KSB7XG4gICAgKG5ldyBjb21tb24uU2hlbGxTdHJpbmcodW5pcWVkKSkudG8ob3V0cHV0KTtcbiAgICAvLyBpZiB1bmlxIHdyaXRlcyB0byBvdXRwdXQsIG5vdGhpbmcgaXMgcGFzc2VkIHRvIHRoZSBuZXh0IGNvbW1hbmQgaW4gdGhlIHBpcGVsaW5lIChpZiBhbnkpXG4gICAgcmV0dXJuICcnO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bmlxZWQ7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfdW5pcTtcbiIsInZhciBjb21tb24gPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuXG5jb21tb24ucmVnaXN0ZXIoJ3doaWNoJywgX3doaWNoLCB7XG4gIGFsbG93R2xvYmJpbmc6IGZhbHNlLFxuICBjbWRPcHRpb25zOiB7XG4gICAgJ2EnOiAnYWxsJyxcbiAgfSxcbn0pO1xuXG4vLyBYUCdzIHN5c3RlbSBkZWZhdWx0IHZhbHVlIGZvciBgUEFUSEVYVGAgc3lzdGVtIHZhcmlhYmxlLCBqdXN0IGluIGNhc2UgaXQncyBub3Rcbi8vIHNldCBvbiBXaW5kb3dzLlxudmFyIFhQX0RFRkFVTFRfUEFUSEVYVCA9ICcuY29tOy5leGU7LmJhdDsuY21kOy52YnM7LnZiZTsuanM7LmpzZTsud3NmOy53c2gnO1xuXG4vLyBGb3IgZWFybGllciB2ZXJzaW9ucyBvZiBOb2RlSlMgdGhhdCBkb2Vzbid0IGhhdmUgYSBsaXN0IG9mIGNvbnN0YW50cyAoPCB2NilcbnZhciBGSUxFX0VYRUNVVEFCTEVfTU9ERSA9IDE7XG5cbmZ1bmN0aW9uIGlzV2luZG93c1BsYXRmb3JtKCkge1xuICByZXR1cm4gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJztcbn1cblxuLy8gQ3Jvc3MtcGxhdGZvcm0gbWV0aG9kIGZvciBzcGxpdHRpbmcgZW52aXJvbm1lbnQgYFBBVEhgIHZhcmlhYmxlc1xuZnVuY3Rpb24gc3BsaXRQYXRoKHApIHtcbiAgcmV0dXJuIHAgPyBwLnNwbGl0KHBhdGguZGVsaW1pdGVyKSA6IFtdO1xufVxuXG4vLyBUZXN0cyBhcmUgcnVubmluZyBhbGwgY2FzZXMgZm9yIHRoaXMgZnVuYyBidXQgaXQgc3RheXMgdW5jb3ZlcmVkIGJ5IGNvZGVjb3YgZHVlIHRvIHVua25vd24gcmVhc29uXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gaXNFeGVjdXRhYmxlKHBhdGhOYW1lKSB7XG4gIHRyeSB7XG4gICAgLy8gVE9ETyhub2RlLXN1cHBvcnQpOiByZXBsYWNlIHdpdGggZnMuY29uc3RhbnRzLlhfT0sgb25jZSByZW1vdmUgc3VwcG9ydCBmb3Igbm9kZSA8IHY2XG4gICAgZnMuYWNjZXNzU3luYyhwYXRoTmFtZSwgRklMRV9FWEVDVVRBQkxFX01PREUpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNoZWNrUGF0aChwYXRoTmFtZSkge1xuICByZXR1cm4gZnMuZXhpc3RzU3luYyhwYXRoTmFtZSkgJiYgIWNvbW1vbi5zdGF0Rm9sbG93TGlua3MocGF0aE5hbWUpLmlzRGlyZWN0b3J5KClcbiAgICAmJiAoaXNXaW5kb3dzUGxhdGZvcm0oKSB8fCBpc0V4ZWN1dGFibGUocGF0aE5hbWUpKTtcbn1cblxuLy9AXG4vL0AgIyMjIHdoaWNoKGNvbW1hbmQpXG4vL0Bcbi8vQCBFeGFtcGxlczpcbi8vQFxuLy9AIGBgYGphdmFzY3JpcHRcbi8vQCB2YXIgbm9kZUV4ZWMgPSB3aGljaCgnbm9kZScpO1xuLy9AIGBgYFxuLy9AXG4vL0AgU2VhcmNoZXMgZm9yIGBjb21tYW5kYCBpbiB0aGUgc3lzdGVtJ3MgYFBBVEhgLiBPbiBXaW5kb3dzLCB0aGlzIHVzZXMgdGhlXG4vL0AgYFBBVEhFWFRgIHZhcmlhYmxlIHRvIGFwcGVuZCB0aGUgZXh0ZW5zaW9uIGlmIGl0J3Mgbm90IGFscmVhZHkgZXhlY3V0YWJsZS5cbi8vQCBSZXR1cm5zIHN0cmluZyBjb250YWluaW5nIHRoZSBhYnNvbHV0ZSBwYXRoIHRvIGBjb21tYW5kYC5cbmZ1bmN0aW9uIF93aGljaChvcHRpb25zLCBjbWQpIHtcbiAgaWYgKCFjbWQpIGNvbW1vbi5lcnJvcignbXVzdCBzcGVjaWZ5IGNvbW1hbmQnKTtcblxuICB2YXIgaXNXaW5kb3dzID0gaXNXaW5kb3dzUGxhdGZvcm0oKTtcbiAgdmFyIHBhdGhBcnJheSA9IHNwbGl0UGF0aChwcm9jZXNzLmVudi5QQVRIKTtcblxuICB2YXIgcXVlcnlNYXRjaGVzID0gW107XG5cbiAgLy8gTm8gcmVsYXRpdmUvYWJzb2x1dGUgcGF0aHMgcHJvdmlkZWQ/XG4gIGlmIChjbWQuaW5kZXhPZignLycpID09PSAtMSkge1xuICAgIC8vIEFzc3VtZSB0aGF0IHRoZXJlIGFyZSBubyBleHRlbnNpb25zIHRvIGFwcGVuZCB0byBxdWVyaWVzICh0aGlzIGlzIHRoZVxuICAgIC8vIGNhc2UgZm9yIHVuaXgpXG4gICAgdmFyIHBhdGhFeHRBcnJheSA9IFsnJ107XG4gICAgaWYgKGlzV2luZG93cykge1xuICAgICAgLy8gSW4gY2FzZSB0aGUgUEFUSEVYVCB2YXJpYWJsZSBpcyBzb21laG93IG5vdCBzZXQgKGUuZy5cbiAgICAgIC8vIGNoaWxkX3Byb2Nlc3Muc3Bhd24gd2l0aCBhbiBlbXB0eSBlbnZpcm9ubWVudCksIHVzZSB0aGUgWFAgZGVmYXVsdC5cbiAgICAgIHZhciBwYXRoRXh0RW52ID0gcHJvY2Vzcy5lbnYuUEFUSEVYVCB8fCBYUF9ERUZBVUxUX1BBVEhFWFQ7XG4gICAgICBwYXRoRXh0QXJyYXkgPSBzcGxpdFBhdGgocGF0aEV4dEVudi50b1VwcGVyQ2FzZSgpKTtcbiAgICB9XG5cbiAgICAvLyBTZWFyY2ggZm9yIGNvbW1hbmQgaW4gUEFUSFxuICAgIGZvciAodmFyIGsgPSAwOyBrIDwgcGF0aEFycmF5Lmxlbmd0aDsgaysrKSB7XG4gICAgICAvLyBhbHJlYWR5IGZvdW5kIGl0XG4gICAgICBpZiAocXVlcnlNYXRjaGVzLmxlbmd0aCA+IDAgJiYgIW9wdGlvbnMuYWxsKSBicmVhaztcblxuICAgICAgdmFyIGF0dGVtcHQgPSBwYXRoLnJlc29sdmUocGF0aEFycmF5W2tdLCBjbWQpO1xuXG4gICAgICBpZiAoaXNXaW5kb3dzKSB7XG4gICAgICAgIGF0dGVtcHQgPSBhdHRlbXB0LnRvVXBwZXJDYXNlKCk7XG4gICAgICB9XG5cbiAgICAgIHZhciBtYXRjaCA9IGF0dGVtcHQubWF0Y2goL1xcLltePD46XCIvXFx8PyouXSskLyk7XG4gICAgICBpZiAobWF0Y2ggJiYgcGF0aEV4dEFycmF5LmluZGV4T2YobWF0Y2hbMF0pID49IDApIHsgLy8gdGhpcyBpcyBXaW5kb3dzLW9ubHlcbiAgICAgICAgLy8gVGhlIHVzZXIgdHlwZWQgYSBxdWVyeSB3aXRoIHRoZSBmaWxlIGV4dGVuc2lvbiwgbGlrZVxuICAgICAgICAvLyBgd2hpY2goJ25vZGUuZXhlJylgXG4gICAgICAgIGlmIChjaGVja1BhdGgoYXR0ZW1wdCkpIHtcbiAgICAgICAgICBxdWVyeU1hdGNoZXMucHVzaChhdHRlbXB0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHsgLy8gQWxsLXBsYXRmb3Jtc1xuICAgICAgICAvLyBDeWNsZSB0aHJvdWdoIHRoZSBQQVRIRVhUIGFycmF5LCBhbmQgY2hlY2sgZWFjaCBleHRlbnNpb25cbiAgICAgICAgLy8gTm90ZTogdGhlIGFycmF5IGlzIGFsd2F5cyBbJyddIG9uIFVuaXhcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRoRXh0QXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2YXIgZXh0ID0gcGF0aEV4dEFycmF5W2ldO1xuICAgICAgICAgIHZhciBuZXdBdHRlbXB0ID0gYXR0ZW1wdCArIGV4dDtcbiAgICAgICAgICBpZiAoY2hlY2tQYXRoKG5ld0F0dGVtcHQpKSB7XG4gICAgICAgICAgICBxdWVyeU1hdGNoZXMucHVzaChuZXdBdHRlbXB0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChjaGVja1BhdGgoY21kKSkgeyAvLyBhIHZhbGlkIGFic29sdXRlIG9yIHJlbGF0aXZlIHBhdGhcbiAgICBxdWVyeU1hdGNoZXMucHVzaChwYXRoLnJlc29sdmUoY21kKSk7XG4gIH1cblxuICBpZiAocXVlcnlNYXRjaGVzLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gb3B0aW9ucy5hbGwgPyBxdWVyeU1hdGNoZXMgOiBxdWVyeU1hdGNoZXNbMF07XG4gIH1cbiAgcmV0dXJuIG9wdGlvbnMuYWxsID8gW10gOiBudWxsO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfd2hpY2g7XG4iLCJ2YXIgbWFwID0ge1xuXHRcIi4vY2F0XCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2F0LmpzXCIsXG5cdFwiLi9jYXQuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9jYXQuanNcIixcblx0XCIuL2NkXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2QuanNcIixcblx0XCIuL2NkLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2QuanNcIixcblx0XCIuL2NobW9kXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2htb2QuanNcIixcblx0XCIuL2NobW9kLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY2htb2QuanNcIixcblx0XCIuL2NvbW1vblwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NvbW1vbi5qc1wiLFxuXHRcIi4vY29tbW9uLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvY29tbW9uLmpzXCIsXG5cdFwiLi9jcFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NwLmpzXCIsXG5cdFwiLi9jcC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2NwLmpzXCIsXG5cdFwiLi9kaXJzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZGlycy5qc1wiLFxuXHRcIi4vZGlycy5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2RpcnMuanNcIixcblx0XCIuL2VjaG9cIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9lY2hvLmpzXCIsXG5cdFwiLi9lY2hvLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZWNoby5qc1wiLFxuXHRcIi4vZXJyb3JcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9lcnJvci5qc1wiLFxuXHRcIi4vZXJyb3IuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9lcnJvci5qc1wiLFxuXHRcIi4vZXhlY1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2V4ZWMuanNcIixcblx0XCIuL2V4ZWMtY2hpbGRcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9leGVjLWNoaWxkLmpzXCIsXG5cdFwiLi9leGVjLWNoaWxkLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZXhlYy1jaGlsZC5qc1wiLFxuXHRcIi4vZXhlYy5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2V4ZWMuanNcIixcblx0XCIuL2ZpbmRcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9maW5kLmpzXCIsXG5cdFwiLi9maW5kLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvZmluZC5qc1wiLFxuXHRcIi4vZ3JlcFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2dyZXAuanNcIixcblx0XCIuL2dyZXAuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9ncmVwLmpzXCIsXG5cdFwiLi9oZWFkXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvaGVhZC5qc1wiLFxuXHRcIi4vaGVhZC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL2hlYWQuanNcIixcblx0XCIuL2xuXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbG4uanNcIixcblx0XCIuL2xuLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbG4uanNcIixcblx0XCIuL2xzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbHMuanNcIixcblx0XCIuL2xzLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbHMuanNcIixcblx0XCIuL21rZGlyXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbWtkaXIuanNcIixcblx0XCIuL21rZGlyLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbWtkaXIuanNcIixcblx0XCIuL212XCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbXYuanNcIixcblx0XCIuL212LmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvbXYuanNcIixcblx0XCIuL3BvcGRcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wb3BkLmpzXCIsXG5cdFwiLi9wb3BkLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvcG9wZC5qc1wiLFxuXHRcIi4vcHVzaGRcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wdXNoZC5qc1wiLFxuXHRcIi4vcHVzaGQuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wdXNoZC5qc1wiLFxuXHRcIi4vcHdkXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvcHdkLmpzXCIsXG5cdFwiLi9wd2QuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9wd2QuanNcIixcblx0XCIuL3JtXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvcm0uanNcIixcblx0XCIuL3JtLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvcm0uanNcIixcblx0XCIuL3NlZFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NlZC5qc1wiLFxuXHRcIi4vc2VkLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvc2VkLmpzXCIsXG5cdFwiLi9zZXRcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9zZXQuanNcIixcblx0XCIuL3NldC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NldC5qc1wiLFxuXHRcIi4vc29ydFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3NvcnQuanNcIixcblx0XCIuL3NvcnQuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy9zb3J0LmpzXCIsXG5cdFwiLi90YWlsXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdGFpbC5qc1wiLFxuXHRcIi4vdGFpbC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RhaWwuanNcIixcblx0XCIuL3RlbXBkaXJcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy90ZW1wZGlyLmpzXCIsXG5cdFwiLi90ZW1wZGlyLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdGVtcGRpci5qc1wiLFxuXHRcIi4vdGVzdFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3Rlc3QuanNcIixcblx0XCIuL3Rlc3QuanNcIjogXCIuL25vZGVfbW9kdWxlcy9zaGVsbGpzL3NyYy90ZXN0LmpzXCIsXG5cdFwiLi90b1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RvLmpzXCIsXG5cdFwiLi90by5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RvLmpzXCIsXG5cdFwiLi90b0VuZFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RvRW5kLmpzXCIsXG5cdFwiLi90b0VuZC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RvRW5kLmpzXCIsXG5cdFwiLi90b3VjaFwiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RvdWNoLmpzXCIsXG5cdFwiLi90b3VjaC5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3RvdWNoLmpzXCIsXG5cdFwiLi91bmlxXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvdW5pcS5qc1wiLFxuXHRcIi4vdW5pcS5qc1wiOiBcIi4vbm9kZV9tb2R1bGVzL3NoZWxsanMvc3JjL3VuaXEuanNcIixcblx0XCIuL3doaWNoXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvd2hpY2guanNcIixcblx0XCIuL3doaWNoLmpzXCI6IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMvd2hpY2guanNcIlxufTtcblxuXG5mdW5jdGlvbiB3ZWJwYWNrQ29udGV4dChyZXEpIHtcblx0dmFyIGlkID0gd2VicGFja0NvbnRleHRSZXNvbHZlKHJlcSk7XG5cdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKGlkKTtcbn1cbmZ1bmN0aW9uIHdlYnBhY2tDb250ZXh0UmVzb2x2ZShyZXEpIHtcblx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhtYXAsIHJlcSkpIHtcblx0XHR2YXIgZSA9IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIgKyByZXEgKyBcIidcIik7XG5cdFx0ZS5jb2RlID0gJ01PRFVMRV9OT1RfRk9VTkQnO1xuXHRcdHRocm93IGU7XG5cdH1cblx0cmV0dXJuIG1hcFtyZXFdO1xufVxud2VicGFja0NvbnRleHQua2V5cyA9IGZ1bmN0aW9uIHdlYnBhY2tDb250ZXh0S2V5cygpIHtcblx0cmV0dXJuIE9iamVjdC5rZXlzKG1hcCk7XG59O1xud2VicGFja0NvbnRleHQucmVzb2x2ZSA9IHdlYnBhY2tDb250ZXh0UmVzb2x2ZTtcbm1vZHVsZS5leHBvcnRzID0gd2VicGFja0NvbnRleHQ7XG53ZWJwYWNrQ29udGV4dC5pZCA9IFwiLi9ub2RlX21vZHVsZXMvc2hlbGxqcy9zcmMgc3luYyByZWN1cnNpdmUgXlxcXFwuXFxcXC8uKiRcIjsiLCJpbXBvcnQgeyBpbmplY3RhYmxlIH0gZnJvbSAnaW52ZXJzaWZ5J1xuXG5pbXBvcnQgKiBhcyB0YXNrTGliIGZyb20gJ2F6dXJlLXBpcGVsaW5lcy10YXNrLWxpYi90YXNrJ1xuaW1wb3J0ICogYXMgdG9vbExpYiBmcm9tICdhenVyZS1waXBlbGluZXMtdG9vbC1saWIvdG9vbCdcblxuaW1wb3J0IHsgSUJ1aWxkQWdlbnQsIElFeGVjUmVzdWx0IH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMnXG5pbXBvcnQgeyBJUmVxdWVzdE9wdGlvbnMgfSBmcm9tICd0eXBlZC1yZXN0LWNsaWVudC9JbnRlcmZhY2VzJ1xuXG5AaW5qZWN0YWJsZSgpXG5jbGFzcyBCdWlsZEFnZW50IGltcGxlbWVudHMgSUJ1aWxkQWdlbnQge1xuICAgIHB1YmxpYyBnZXQgYWdlbnROYW1lKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAnQXp1cmUgUGlwZWxpbmVzJ1xuICAgIH1cblxuICAgIHB1YmxpYyBwcm94eUNvbmZpZ3VyYXRpb24odXJsOiBzdHJpbmcpOiBJUmVxdWVzdE9wdGlvbnMge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJveHk6IHRhc2tMaWIuZ2V0SHR0cFByb3h5Q29uZmlndXJhdGlvbih1cmwpLFxuICAgICAgICAgICAgY2VydDogdGFza0xpYi5nZXRIdHRwQ2VydENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgIGlnbm9yZVNzbEVycm9yOiAhIXRhc2tMaWIuZ2V0VmFyaWFibGUoJ0FnZW50LlNraXBDZXJ0VmFsaWRhdGlvbicpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZmluZCh0b29sTmFtZTogc3RyaW5nLCB2ZXJzaW9uU3BlYzogc3RyaW5nLCBhcmNoPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRvb2xMaWIuZmluZExvY2FsVG9vbCh0b29sTmFtZSwgdmVyc2lvblNwZWMsIGFyY2gpXG4gICAgfVxuXG4gICAgcHVibGljIGNhY2hlRGlyKFxuICAgICAgICBzb3VyY2VEaXI6IHN0cmluZyxcbiAgICAgICAgdG9vbDogc3RyaW5nLFxuICAgICAgICB2ZXJzaW9uOiBzdHJpbmcsXG4gICAgICAgIGFyY2g/OiBzdHJpbmdcbiAgICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gdG9vbExpYi5jYWNoZURpcihzb3VyY2VEaXIsIHRvb2wsIHZlcnNpb24sIGFyY2gpXG4gICAgfVxuXG4gICAgcHVibGljIGNyZWF0ZVRlbXBEaXIoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0YXNrTGliLmdldFZhcmlhYmxlKCdBZ2VudC5UZW1wRGlyZWN0b3J5JykpXG4gICAgfVxuXG4gICAgcHVibGljIGRlYnVnKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0YXNrTGliLmRlYnVnKG1lc3NhZ2UpXG4gICAgfVxuXG4gICAgcHVibGljIHNldEZhaWxlZChtZXNzYWdlOiBzdHJpbmcsIGRvbmU/OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHRhc2tMaWIuc2V0UmVzdWx0KHRhc2tMaWIuVGFza1Jlc3VsdC5GYWlsZWQsIG1lc3NhZ2UsIGRvbmUpXG4gICAgfVxuXG4gICAgcHVibGljIHNldFN1Y2NlZWRlZChtZXNzYWdlOiBzdHJpbmcsIGRvbmU/OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHRhc2tMaWIuc2V0UmVzdWx0KHRhc2tMaWIuVGFza1Jlc3VsdC5TdWNjZWVkZWQsIG1lc3NhZ2UsIGRvbmUpXG4gICAgfVxuXG4gICAgcHVibGljIGV4cG9ydFZhcmlhYmxlKG5hbWU6IHN0cmluZywgdmFsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGFza0xpYi5zZXRWYXJpYWJsZShuYW1lLCB2YWwpXG4gICAgfVxuXG4gICAgcHVibGljIGdldFZhcmlhYmxlKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0YXNrTGliLmdldFZhcmlhYmxlKG5hbWUpXG4gICAgfVxuXG4gICAgcHVibGljIGFkZFBhdGgoaW5wdXRQYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdG9vbExpYi5wcmVwZW5kUGF0aChpbnB1dFBhdGgpXG4gICAgfVxuXG4gICAgcHVibGljIHdoaWNoKHRvb2w6IHN0cmluZywgY2hlY2s/OiBib29sZWFuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0YXNrTGliLndoaWNoKHRvb2wsIGNoZWNrKSlcbiAgICB9XG5cbiAgICBwdWJsaWMgZXhlYyhleGVjOiBzdHJpbmcsIGFyZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD4ge1xuICAgICAgICBjb25zdCB0ciA9IHRhc2tMaWIudG9vbChleGVjKVxuICAgICAgICB0ci5hcmcoYXJncylcblxuICAgICAgICBjb25zdCByZXN1bHQgPSB0ci5leGVjU3luYygpXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgY29kZTogcmVzdWx0LmNvZGUsXG4gICAgICAgICAgICBlcnJvcjogcmVzdWx0LmVycm9yLFxuICAgICAgICAgICAgc3RkZXJyOiByZXN1bHQuc3RkZXJyLFxuICAgICAgICAgICAgc3Rkb3V0OiByZXN1bHQuc3Rkb3V0XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcHVibGljIGdldFNvdXJjZURpcigpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRWYXJpYWJsZSgnQnVpbGQuU291cmNlc0RpcmVjdG9yeScpXG4gICAgfVxuXG4gICAgcHVibGljIHNldE91dHB1dChuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGFza0xpYi5zZXRWYXJpYWJsZShuYW1lLCB2YWx1ZSlcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0SW5wdXQoaW5wdXQ6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWIuZ2V0SW5wdXQoaW5wdXQsIHJlcXVpcmVkKT8udHJpbSgpXG4gICAgfVxuXG4gICAgcHVibGljIGdldExpc3RJbnB1dChpbnB1dDogc3RyaW5nLCByZXF1aXJlZD86IGJvb2xlYW4pOiBzdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiB0YXNrTGliXG4gICAgICAgICAgICAuZ2V0SW5wdXQoaW5wdXQsIHJlcXVpcmVkKVxuICAgICAgICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgICAgICAgLmZpbHRlcih4ID0+IHggIT09ICcnKVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRCb29sZWFuSW5wdXQoaW5wdXQ6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0YXNrTGliLmdldEJvb2xJbnB1dChpbnB1dCwgcmVxdWlyZWQpXG4gICAgfVxuXG4gICAgcHVibGljIGlzVmFsaWRJbnB1dEZpbGUoaW5wdXQ6IHN0cmluZywgZmlsZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0YXNrTGliLmZpbGVQYXRoU3VwcGxpZWQoaW5wdXQpICYmIHRoaXMuZmlsZUV4aXN0cyhmaWxlKVxuICAgIH1cblxuICAgIHB1YmxpYyBmaWxlRXhpc3RzKGZpbGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGFza0xpYi5leGlzdChmaWxlKSAmJiB0YXNrTGliLnN0YXRzKGZpbGUpLmlzRmlsZSgpXG4gICAgfVxuXG4gICAgcHVibGljIGRpcmVjdG9yeUV4aXN0cyhmaWxlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRhc2tMaWIuZXhpc3QoZmlsZSkgJiYgdGFza0xpYi5zdGF0cyhmaWxlKS5pc0RpcmVjdG9yeSgpXG4gICAgfVxufVxuXG5leHBvcnQgeyBCdWlsZEFnZW50IH1cbiIsImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJ1xuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgKiBhcyBodHRwIGZyb20gJ3R5cGVkLXJlc3QtY2xpZW50L0h0dHBDbGllbnQnXG5cbmltcG9ydCB7IGluamVjdCwgaW5qZWN0YWJsZSB9IGZyb20gJ2ludmVyc2lmeSdcbmltcG9ydCB7IFRZUEVTLCBJRXhlY1Jlc3VsdCwgSUJ1aWxkQWdlbnQgfSBmcm9tICcuL21vZGVscydcbmltcG9ydCB7IElWZXJzaW9uTWFuYWdlciB9IGZyb20gJy4vdmVyc2lvbk1hbmFnZXInXG5cbmV4cG9ydCBpbnRlcmZhY2UgSURvdG5ldFRvb2wge1xuICAgIGRpc2FibGVUZWxlbWV0cnkoKTogdm9pZFxuICAgIHRvb2xJbnN0YWxsKFxuICAgICAgICB0b29sTmFtZTogc3RyaW5nLFxuICAgICAgICB2ZXJzaW9uU3BlYzogc3RyaW5nLFxuICAgICAgICBjaGVja0xhdGVzdDogYm9vbGVhbixcbiAgICAgICAgaW5jbHVkZVByZTogYm9vbGVhblxuICAgICk6IFByb21pc2U8c3RyaW5nPlxufVxuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRG90bmV0VG9vbCBpbXBsZW1lbnRzIElEb3RuZXRUb29sIHtcbiAgICBwcm90ZWN0ZWQgYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnRcbiAgICBwcm90ZWN0ZWQgdmVyc2lvbk1hbmFnZXI6IElWZXJzaW9uTWFuYWdlclxuICAgIHByaXZhdGUgaHR0cENsaWVudDogaHR0cC5IdHRwQ2xpZW50XG5cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBudWdldFJvb3Q6IHN0cmluZyA9XG4gICAgICAgICdodHRwczovL2FwaS12MnYzc2VhcmNoLTAubnVnZXQub3JnLydcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBAaW5qZWN0KFRZUEVTLklCdWlsZEFnZW50KSBidWlsZEFnZW50OiBJQnVpbGRBZ2VudCxcbiAgICAgICAgQGluamVjdChUWVBFUy5JVmVyc2lvbk1hbmFnZXIpIHZlcnNpb25NYW5hZ2VyOiBJVmVyc2lvbk1hbmFnZXJcbiAgICApIHtcbiAgICAgICAgdGhpcy5idWlsZEFnZW50ID0gYnVpbGRBZ2VudFxuICAgICAgICB0aGlzLnZlcnNpb25NYW5hZ2VyID0gdmVyc2lvbk1hbmFnZXJcbiAgICAgICAgdGhpcy5odHRwQ2xpZW50ID0gbmV3IGh0dHAuSHR0cENsaWVudChcbiAgICAgICAgICAgICdkb3RuZXQnLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgdGhpcy5idWlsZEFnZW50LnByb3h5Q29uZmlndXJhdGlvbihEb3RuZXRUb29sLm51Z2V0Um9vdClcbiAgICAgICAgKVxuICAgIH1cblxuICAgIHB1YmxpYyBkaXNhYmxlVGVsZW1ldHJ5KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZXhwb3J0VmFyaWFibGUoJ0RPVE5FVF9DTElfVEVMRU1FVFJZX09QVE9VVCcsICd0cnVlJylcbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmV4cG9ydFZhcmlhYmxlKCdET1RORVRfTk9MT0dPJywgJ3RydWUnKVxuICAgIH1cblxuICAgIHB1YmxpYyBleGVjdXRlKGNtZDogc3RyaW5nLCBhcmdzOiBzdHJpbmdbXSk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcbiAgICAgICAgY29uc29sZS5sb2coYENvbW1hbmQ6ICR7Y21kfSAke2FyZ3Muam9pbignICcpfWApXG4gICAgICAgIHJldHVybiB0aGlzLmJ1aWxkQWdlbnQuZXhlYyhjbWQsIGFyZ3MpXG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHRvb2xJbnN0YWxsKFxuICAgICAgICB0b29sTmFtZTogc3RyaW5nLFxuICAgICAgICB2ZXJzaW9uU3BlYzogc3RyaW5nLFxuICAgICAgICBjaGVja0xhdGVzdDogYm9vbGVhbixcbiAgICAgICAgaW5jbHVkZVByZTogYm9vbGVhblxuICAgICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgICBjb25zb2xlLmxvZygnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKVxuICAgICAgICBjb25zb2xlLmxvZyhgSW5zdGFsbGluZyAke3Rvb2xOYW1lfSB2ZXJzaW9uIGAgKyB2ZXJzaW9uU3BlYylcbiAgICAgICAgY29uc29sZS5sb2coJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJylcblxuICAgICAgICBpZiAodGhpcy52ZXJzaW9uTWFuYWdlci5pc0V4cGxpY2l0VmVyc2lvbih2ZXJzaW9uU3BlYykpIHtcbiAgICAgICAgICAgIGNoZWNrTGF0ZXN0ID0gZmFsc2UgLy8gY2hlY2sgbGF0ZXN0IGRvZXNuJ3QgbWFrZSBzZW5zZSB3aGVuIGV4cGxpY2l0IHZlcnNpb25cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCB0b29sUGF0aDogc3RyaW5nXG4gICAgICAgIGlmICghY2hlY2tMYXRlc3QpIHtcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBMZXQncyB0cnkgYW5kIHJlc29sdmUgdGhlIHZlcnNpb24gc3BlYyBsb2NhbGx5IGZpcnN0XG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgdG9vbFBhdGggPSB0aGlzLmJ1aWxkQWdlbnQuZmluZCh0b29sTmFtZSwgdmVyc2lvblNwZWMpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRvb2xQYXRoKSB7XG4gICAgICAgICAgICBsZXQgdmVyc2lvbjogc3RyaW5nXG4gICAgICAgICAgICBpZiAodGhpcy52ZXJzaW9uTWFuYWdlci5pc0V4cGxpY2l0VmVyc2lvbih2ZXJzaW9uU3BlYykpIHtcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIEV4cGxpY2l0IHZlcnNpb24gd2FzIHNwZWNpZmllZC4gTm8gbmVlZCB0byBxdWVyeSBmb3IgbGlzdCBvZiB2ZXJzaW9ucy5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIHZlcnNpb24gPSB2ZXJzaW9uU3BlY1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIExldCdzIHF1ZXJ5IGFuZCByZXNvbHZlIHRoZSBsYXRlc3QgdmVyc2lvbiBmb3IgdGhlIHZlcnNpb25TcGVjLlxuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2ZXJzaW9uIGlzIGFuIGV4cGxpY2l0IHZlcnNpb24gKDEuMS4xIG9yIHYxLjEuMSkgdGhlbiBubyBuZWVkIHRvIHF1ZXJ5LlxuICAgICAgICAgICAgICAgIC8vIElmIHlvdXIgdG9vbCBkb2Vzbid0IG9mZmVyIGEgbWVjaGFuaXNtIHRvIHF1ZXJ5LFxuICAgICAgICAgICAgICAgIC8vIHRoZW4gaXQgY2FuIG9ubHkgc3VwcG9ydCBleGFjdCB2ZXJzaW9uIGlucHV0cy5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIHZlcnNpb24gPSBhd2FpdCB0aGlzLnF1ZXJ5TGF0ZXN0TWF0Y2goXG4gICAgICAgICAgICAgICAgICAgIHRvb2xOYW1lLFxuICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uU3BlYyxcbiAgICAgICAgICAgICAgICAgICAgaW5jbHVkZVByZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICBpZiAoIXZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYFVuYWJsZSB0byBmaW5kICR7dG9vbE5hbWV9IHZlcnNpb24gJyR7dmVyc2lvblNwZWN9Jy5gXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoZSBjYWNoZSBmb3IgdGhlIHJlc29sdmVkIHZlcnNpb24uXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICB0b29sUGF0aCA9IHRoaXMuYnVpbGRBZ2VudC5maW5kKHRvb2xOYW1lLCB2ZXJzaW9uKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCF0b29sUGF0aCkge1xuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gRG93bmxvYWQsIGV4dHJhY3QsIGNhY2hlXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICB0b29sUGF0aCA9IGF3YWl0IHRoaXMuYWNxdWlyZVRvb2wodG9vbE5hbWUsIHZlcnNpb24pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvL1xuICAgICAgICAvLyBQcmVwZW5kIHRoZSB0b29scyBwYXRoLiBUaGlzIHByZXBlbmRzIHRoZSBQQVRIIGZvciB0aGUgY3VycmVudCBwcm9jZXNzIGFuZFxuICAgICAgICAvLyBpbnN0cnVjdHMgdGhlIGFnZW50IHRvIHByZXBlbmQgZm9yIGVhY2ggdGFzayB0aGF0IGZvbGxvd3MuXG4gICAgICAgIC8vXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhgdG9vbFBhdGg6ICR7dG9vbFBhdGh9YClcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBvcy5wbGF0Zm9ybSgpICE9PSAnd2luMzInICYmXG4gICAgICAgICAgICAhdGhpcy5idWlsZEFnZW50LmdldFZhcmlhYmxlKCdET1RORVRfUk9PVCcpXG4gICAgICAgICkge1xuICAgICAgICAgICAgbGV0IGRvdG5ldFBhdGggPSBhd2FpdCB0aGlzLmJ1aWxkQWdlbnQud2hpY2goJ2RvdG5ldCcpXG4gICAgICAgICAgICBkb3RuZXRQYXRoID0gZnMucmVhZGxpbmtTeW5jKGRvdG5ldFBhdGgpIHx8IGRvdG5ldFBhdGhcbiAgICAgICAgICAgIGNvbnN0IGRvdG5ldFJvb3QgPSBwYXRoLmRpcm5hbWUoZG90bmV0UGF0aClcbiAgICAgICAgICAgIHRoaXMuYnVpbGRBZ2VudC5leHBvcnRWYXJpYWJsZSgnRE9UTkVUX1JPT1QnLCBkb3RuZXRSb290KVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5hZGRQYXRoKHRvb2xQYXRoKVxuXG4gICAgICAgIHJldHVybiB0b29sUGF0aFxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcXVlcnlMYXRlc3RNYXRjaChcbiAgICAgICAgdG9vbE5hbWU6IHN0cmluZyxcbiAgICAgICAgdmVyc2lvblNwZWM6IHN0cmluZyxcbiAgICAgICAgaW5jbHVkZVByZXJlbGVhc2U6IGJvb2xlYW5cbiAgICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZGVidWcoXG4gICAgICAgICAgICBgcXVlcnlpbmcgdG9vbCB2ZXJzaW9ucyBmb3IgJHt0b29sTmFtZX0ke1xuICAgICAgICAgICAgICAgIHZlcnNpb25TcGVjID8gYEAke3ZlcnNpb25TcGVjfWAgOiAnJ1xuICAgICAgICAgICAgfSAke2luY2x1ZGVQcmVyZWxlYXNlID8gJ2luY2x1ZGluZyBwcmUtcmVsZWFzZXMnIDogJyd9YFxuICAgICAgICApXG5cbiAgICAgICAgY29uc3QgZG93bmxvYWRQYXRoID0gYCR7XG4gICAgICAgICAgICBEb3RuZXRUb29sLm51Z2V0Um9vdFxuICAgICAgICB9cXVlcnk/cT0ke2VuY29kZVVSSUNvbXBvbmVudCh0b29sTmFtZS50b0xvd2VyQ2FzZSgpKX0mcHJlcmVsZWFzZT0ke1xuICAgICAgICAgICAgaW5jbHVkZVByZXJlbGVhc2UgPyAndHJ1ZScgOiAnZmFsc2UnXG4gICAgICAgIH0mc2VtVmVyTGV2ZWw9Mi4wLjBgXG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5odHRwQ2xpZW50LmdldChkb3dubG9hZFBhdGgpXG5cbiAgICAgICAgaWYgKCFyZXMgfHwgcmVzLm1lc3NhZ2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYm9keTogc3RyaW5nID0gYXdhaXQgcmVzLnJlYWRCb2R5KClcbiAgICAgICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UoYm9keSkuZGF0YVxuXG4gICAgICAgIGNvbnN0IHZlcnNpb25zID0gKGRhdGFbMF0udmVyc2lvbnMgYXMgeyB2ZXJzaW9uOiBzdHJpbmcgfVtdKS5tYXAoXG4gICAgICAgICAgICB4ID0+IHgudmVyc2lvblxuICAgICAgICApXG4gICAgICAgIGlmICghdmVyc2lvbnMgfHwgIXZlcnNpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZyhgZ290IHZlcnNpb25zOiAke3ZlcnNpb25zLmpvaW4oJywgJyl9YClcblxuICAgICAgICByZXR1cm4gdGhpcy52ZXJzaW9uTWFuYWdlci5ldmFsdWF0ZVZlcnNpb25zKHZlcnNpb25zLCB2ZXJzaW9uU3BlYylcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGFjcXVpcmVUb29sKFxuICAgICAgICB0b29sTmFtZTogc3RyaW5nLFxuICAgICAgICB2ZXJzaW9uOiBzdHJpbmdcbiAgICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICBjb25zdCB0ZW1wRGlyZWN0b3J5ID0gYXdhaXQgdGhpcy5idWlsZEFnZW50LmNyZWF0ZVRlbXBEaXIoKVxuICAgICAgICBsZXQgYXJncyA9IFsndG9vbCcsICdpbnN0YWxsJywgdG9vbE5hbWUsICctLXRvb2wtcGF0aCcsIHRlbXBEaXJlY3RvcnldXG5cbiAgICAgICAgaWYgKHZlcnNpb24pIHtcbiAgICAgICAgICAgIHZlcnNpb24gPSB0aGlzLnZlcnNpb25NYW5hZ2VyLmNsZWFuVmVyc2lvbih2ZXJzaW9uKVxuICAgICAgICAgICAgYXJncyA9IGFyZ3MuY29uY2F0KFsnLS12ZXJzaW9uJywgdmVyc2lvbl0pXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmV4ZWN1dGUoJ2RvdG5ldCcsIGFyZ3MpXG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IHJlc3VsdC5jb2RlID09PSAwID8gJ3N1Y2Nlc3MnIDogJ2ZhaWx1cmUnXG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSByZXN1bHQuY29kZSA9PT0gMCA/IHJlc3VsdC5zdGRvdXQgOiByZXN1bHQuc3RkZXJyXG5cbiAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKGB0b29sIGluc3RhbGwgcmVzdWx0OiAke3N0YXR1c30gJHttZXNzYWdlfWApXG5cbiAgICAgICAgaWYgKHJlc3VsdC5jb2RlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIGluc3RhbGxpbmcgdG9vbCcpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5idWlsZEFnZW50LmNhY2hlRGlyKHRlbXBEaXJlY3RvcnksIHRvb2xOYW1lLCB2ZXJzaW9uKVxuICAgIH1cbn1cbiIsImltcG9ydCB7IENvbnRhaW5lciB9IGZyb20gJ2ludmVyc2lmeSdcbmltcG9ydCB7IElWZXJzaW9uTWFuYWdlciwgVmVyc2lvbk1hbmFnZXIgfSBmcm9tICcuL3ZlcnNpb25NYW5hZ2VyJ1xuaW1wb3J0IHsgVFlQRVMsIElCdWlsZEFnZW50IH0gZnJvbSAnLi9tb2RlbHMnXG5pbXBvcnQgeyBCdWlsZEFnZW50IH0gZnJvbSAnLi4vYWdlbnQvbW9jay9idWlsZC1hZ2VudCdcblxuY29uc3QgY29udGFpbmVyID0gbmV3IENvbnRhaW5lcigpXG5cbmNvbnRhaW5lci5iaW5kPElWZXJzaW9uTWFuYWdlcj4oVFlQRVMuSVZlcnNpb25NYW5hZ2VyKS50byhWZXJzaW9uTWFuYWdlcilcbmNvbnRhaW5lci5iaW5kPElCdWlsZEFnZW50PihUWVBFUy5JQnVpbGRBZ2VudCkudG8oQnVpbGRBZ2VudClcblxuZXhwb3J0IGRlZmF1bHQgY29udGFpbmVyXG4iLCJpbXBvcnQgeyBJUmVxdWVzdE9wdGlvbnMgfSBmcm9tICd0eXBlZC1yZXN0LWNsaWVudC9JbnRlcmZhY2VzJ1xuXG5leHBvcnQgY29uc3QgVFlQRVMgPSB7XG4gICAgSUJ1aWxkQWdlbnQ6IFN5bWJvbC5mb3IoJ0J1aWxkQWdlbnQnKSxcbiAgICBJRG90bmV0VG9vbDogU3ltYm9sLmZvcignRG90bmV0VG9vbCcpLFxuICAgIElHaXRWZXJzaW9uVG9vbDogU3ltYm9sLmZvcignR2l0VmVyc2lvblRvb2wnKSxcbiAgICBJR2l0UmVsZWFzZU1hbmFnZXJUb29sOiBTeW1ib2wuZm9yKCdHaXRSZWxlYXNlTWFuYWdlclRvb2wnKSxcbiAgICBJVmVyc2lvbk1hbmFnZXI6IFN5bWJvbC5mb3IoJ1ZlcnNpb25NYW5hZ2VyJylcbn1cblxuZXhwb3J0IGVudW0gU2V0dXBGaWVsZHMge1xuICAgIGluY2x1ZGVQcmVyZWxlYXNlID0gJ2luY2x1ZGVQcmVyZWxlYXNlJyxcbiAgICB2ZXJzaW9uU3BlYyA9ICd2ZXJzaW9uU3BlYydcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJU2V0dXBTZXR0aW5ncyB7XG4gICAgW1NldHVwRmllbGRzLnZlcnNpb25TcGVjXTogc3RyaW5nXG4gICAgW1NldHVwRmllbGRzLmluY2x1ZGVQcmVyZWxlYXNlXTogYm9vbGVhblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElFeGVjUmVzdWx0IHtcbiAgICBzdGRvdXQ6IHN0cmluZ1xuICAgIHN0ZGVycjogc3RyaW5nXG4gICAgY29kZTogbnVtYmVyXG4gICAgZXJyb3I6IEVycm9yXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUJ1aWxkQWdlbnQge1xuICAgIGFnZW50TmFtZTogc3RyaW5nXG4gICAgcHJveHlDb25maWd1cmF0aW9uKHVybDogc3RyaW5nKTogSVJlcXVlc3RPcHRpb25zXG4gICAgZmluZCh0b29sTmFtZTogc3RyaW5nLCB2ZXJzaW9uU3BlYzogc3RyaW5nLCBhcmNoPzogc3RyaW5nKTogc3RyaW5nXG4gICAgY2FjaGVEaXIoXG4gICAgICAgIHNvdXJjZURpcjogc3RyaW5nLFxuICAgICAgICB0b29sOiBzdHJpbmcsXG4gICAgICAgIHZlcnNpb246IHN0cmluZyxcbiAgICAgICAgYXJjaD86IHN0cmluZ1xuICAgICk6IFByb21pc2U8c3RyaW5nPlxuICAgIGNyZWF0ZVRlbXBEaXIoKTogUHJvbWlzZTxzdHJpbmc+XG4gICAgZGVidWcobWVzc2FnZTogc3RyaW5nKTogdm9pZFxuICAgIHNldEZhaWxlZChtZXNzYWdlOiBzdHJpbmcsIGRvbmU/OiBib29sZWFuKTogdm9pZFxuICAgIHNldFN1Y2NlZWRlZChtZXNzYWdlOiBzdHJpbmcsIGRvbmU/OiBib29sZWFuKTogdm9pZFxuICAgIGV4cG9ydFZhcmlhYmxlKG5hbWU6IHN0cmluZywgdmFsOiBzdHJpbmcpOiB2b2lkXG4gICAgZ2V0VmFyaWFibGUobmFtZTogc3RyaW5nKTogc3RyaW5nXG4gICAgYWRkUGF0aChpbnB1dFBhdGg6IHN0cmluZyk6IHZvaWRcbiAgICB3aGljaCh0b29sOiBzdHJpbmcsIGNoZWNrPzogYm9vbGVhbik6IFByb21pc2U8c3RyaW5nPlxuICAgIGV4ZWMoZXhlYzogc3RyaW5nLCBhcmdzOiBzdHJpbmdbXSk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+XG5cbiAgICBnZXRTb3VyY2VEaXIoKTogc3RyaW5nXG4gICAgaXNWYWxpZElucHV0RmlsZShpbnB1dDogc3RyaW5nLCBmaWxlOiBzdHJpbmcpOiBib29sZWFuXG4gICAgZmlsZUV4aXN0cyhmaWxlOiBzdHJpbmcpOiBib29sZWFuXG4gICAgZGlyZWN0b3J5RXhpc3RzKGZpbGU6IHN0cmluZyk6IGJvb2xlYW5cblxuICAgIHNldE91dHB1dChuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkXG4gICAgZ2V0SW5wdXQoaW5wdXQ6IHN0cmluZywgcmVxdWlyZWQ/OiBib29sZWFuKTogc3RyaW5nXG4gICAgZ2V0TGlzdElucHV0KGlucHV0OiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbik6IHN0cmluZ1tdXG4gICAgZ2V0Qm9vbGVhbklucHV0KGlucHV0OiBzdHJpbmcsIHJlcXVpcmVkPzogYm9vbGVhbik6IGJvb2xlYW5cbn1cbiIsImltcG9ydCB7IElCdWlsZEFnZW50LCBTZXR1cEZpZWxkcywgSVNldHVwU2V0dGluZ3MgfSBmcm9tICcuL21vZGVscydcblxuZXhwb3J0IGNsYXNzIFNldHRpbmdzIHtcbiAgICBwdWJsaWMgc3RhdGljIGdldFNldHVwU2V0dGluZ3MoYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnQpOiBJU2V0dXBTZXR0aW5ncyB7XG4gICAgICAgIGNvbnN0IHZlcnNpb25TcGVjID0gYnVpbGRBZ2VudC5nZXRJbnB1dChTZXR1cEZpZWxkcy52ZXJzaW9uU3BlYylcbiAgICAgICAgY29uc3QgaW5jbHVkZVByZXJlbGVhc2UgPSBidWlsZEFnZW50LmdldEJvb2xlYW5JbnB1dChcbiAgICAgICAgICAgIFNldHVwRmllbGRzLmluY2x1ZGVQcmVyZWxlYXNlXG4gICAgICAgIClcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmVyc2lvblNwZWMsXG4gICAgICAgICAgICBpbmNsdWRlUHJlcmVsZWFzZVxuICAgICAgICB9XG4gICAgfVxufVxuIiwiaW1wb3J0IGNtcCBmcm9tICdzZW12ZXItY29tcGFyZSdcbmltcG9ydCAqIGFzIHNlbXZlciBmcm9tICdzZW12ZXInXG5pbXBvcnQgeyBpbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdpbnZlcnNpZnknXG5cbmltcG9ydCB7IElCdWlsZEFnZW50LCBUWVBFUyB9IGZyb20gJy4vbW9kZWxzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIElWZXJzaW9uTWFuYWdlciB7XG4gICAgaXNFeHBsaWNpdFZlcnNpb24odmVyc2lvblNwZWM6IHN0cmluZyk6IGJvb2xlYW5cbiAgICBldmFsdWF0ZVZlcnNpb25zKHZlcnNpb25zOiBzdHJpbmdbXSwgdmVyc2lvblNwZWM6IHN0cmluZyk6IHN0cmluZ1xuICAgIGNsZWFuVmVyc2lvbih2ZXJzaW9uOiBzdHJpbmcpOiBzdHJpbmdcbn1cblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFZlcnNpb25NYW5hZ2VyIGltcGxlbWVudHMgSVZlcnNpb25NYW5hZ2VyIHtcbiAgICBwcml2YXRlIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgY29uc3RydWN0b3IoQGluamVjdChUWVBFUy5JQnVpbGRBZ2VudCkgYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnQpIHtcbiAgICAgICAgdGhpcy5idWlsZEFnZW50ID0gYnVpbGRBZ2VudFxuICAgIH1cblxuICAgIHB1YmxpYyBpc0V4cGxpY2l0VmVyc2lvbih2ZXJzaW9uU3BlYzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGMgPSBzZW12ZXIuY2xlYW4odmVyc2lvblNwZWMpXG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZygnaXNFeHBsaWNpdDogJyArIGMpXG5cbiAgICAgICAgY29uc3QgdmFsaWQgPSBzZW12ZXIudmFsaWQoYykgIT0gbnVsbFxuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZGVidWcoJ2V4cGxpY2l0PyAnICsgdmFsaWQpXG5cbiAgICAgICAgcmV0dXJuIHZhbGlkXG4gICAgfVxuXG4gICAgcHVibGljIGV2YWx1YXRlVmVyc2lvbnModmVyc2lvbnM6IHN0cmluZ1tdLCB2ZXJzaW9uU3BlYzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHZlcnNpb246IHN0cmluZ1xuICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZGVidWcoJ2V2YWx1YXRpbmcgJyArIHZlcnNpb25zLmxlbmd0aCArICcgdmVyc2lvbnMnKVxuICAgICAgICB2ZXJzaW9ucyA9IHZlcnNpb25zLnNvcnQoY21wKVxuICAgICAgICBmb3IgKGxldCBpID0gdmVyc2lvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNvbnN0IHBvdGVudGlhbDogc3RyaW5nID0gdmVyc2lvbnNbaV1cbiAgICAgICAgICAgIGNvbnN0IHNhdGlzZmllZDogYm9vbGVhbiA9IHNlbXZlci5zYXRpc2ZpZXMocG90ZW50aWFsLCB2ZXJzaW9uU3BlYylcbiAgICAgICAgICAgIGlmIChzYXRpc2ZpZWQpIHtcbiAgICAgICAgICAgICAgICB2ZXJzaW9uID0gcG90ZW50aWFsXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2ZXJzaW9uKSB7XG4gICAgICAgICAgICB0aGlzLmJ1aWxkQWdlbnQuZGVidWcoJ21hdGNoZWQ6ICcgKyB2ZXJzaW9uKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5idWlsZEFnZW50LmRlYnVnKCdtYXRjaCBub3QgZm91bmQnKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHZlcnNpb25cbiAgICB9XG5cbiAgICBwdWJsaWMgY2xlYW5WZXJzaW9uKHZlcnNpb246IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHRoaXMuYnVpbGRBZ2VudC5kZWJ1ZygnY2xlYW5pbmc6ICcgKyB2ZXJzaW9uKVxuICAgICAgICByZXR1cm4gc2VtdmVyLmNsZWFuKHZlcnNpb24pXG4gICAgfVxufVxuIiwiaW1wb3J0IHsgSUJ1aWxkQWdlbnQsIFRZUEVTIH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMnXG5pbXBvcnQge1xuICAgIElHaXRSZWxlYXNlTWFuYWdlclRvb2wsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJUb29sXG59IGZyb20gJy4uLy4uL3Rvb2xzL2dpdHJlbGVhc2VtYW5hZ2VyL3Rvb2wnXG5pbXBvcnQgeyBTZXR0aW5ncyBhcyBDb21tb25TZXR0aW5ncyB9IGZyb20gJy4uLy4uL2NvcmUvc2V0dGluZ3MnXG5pbXBvcnQgeyBTZXR0aW5ncyB9IGZyb20gJy4uLy4uL3Rvb2xzL2dpdHJlbGVhc2VtYW5hZ2VyL3NldHRpbmdzJ1xuXG5pbXBvcnQgY29udGFpbmVyIGZyb20gJy4uLy4uL2NvcmUvaW9jJ1xuXG5jb250YWluZXJcbiAgICAuYmluZDxJR2l0UmVsZWFzZU1hbmFnZXJUb29sPihUWVBFUy5JR2l0UmVsZWFzZU1hbmFnZXJUb29sKVxuICAgIC50byhHaXRSZWxlYXNlTWFuYWdlclRvb2wpXG5cbmNvbnN0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbCA9IGNvbnRhaW5lci5nZXQ8SUdpdFJlbGVhc2VNYW5hZ2VyVG9vbD4oXG4gICAgVFlQRVMuSUdpdFJlbGVhc2VNYW5hZ2VyVG9vbFxuKVxuY29uc3QgYnVpbGRBZ2VudCA9IGNvbnRhaW5lci5nZXQ8SUJ1aWxkQWdlbnQ+KFRZUEVTLklCdWlsZEFnZW50KVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0dXAoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gQ29tbW9uU2V0dGluZ3MuZ2V0U2V0dXBTZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5pbnN0YWxsKFxuICAgICAgICAgICAgc2V0dGluZ3MudmVyc2lvblNwZWMsXG4gICAgICAgICAgICBzZXR0aW5ncy5pbmNsdWRlUHJlcmVsZWFzZVxuICAgICAgICApXG5cbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXG4gICAgICAgICAgICAnR2l0VmVyc2lvbk1hbmFnZXIgaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICB0cnkge1xuICAgICAgICBnaXRSZWxlYXNlTWFuYWdlclRvb2wuZGlzYWJsZVRlbGVtZXRyeSgpXG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDcmVhdGVTZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5jcmVhdGUoc2V0dGluZ3MpXG5cbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXG4gICAgICAgICAgICAnR2l0VmVyc2lvbk1hbmFnZXIgY3JlYXRlZCByZWxlYXNlIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRpc2NhcmQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gU2V0dGluZ3MuZ2V0RGlzY2FyZFNldHRpbmdzKGJ1aWxkQWdlbnQpXG5cbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2NhcmQoc2V0dGluZ3MpXG5cbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXG4gICAgICAgICAgICAnR2l0VmVyc2lvbk1hbmFnZXIgZGlzY2FyZGVkIHJlbGVhc2Ugc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0RmFpbGVkKGVycm9yLm1lc3NhZ2UsIHRydWUpXG4gICAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q2xvc2VTZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5jbG9zZShzZXR0aW5ncylcblxuICAgICAgICBidWlsZEFnZW50LnNldFN1Y2NlZWRlZChcbiAgICAgICAgICAgICdHaXRWZXJzaW9uTWFuYWdlciBjbG9zZWQgcmVsZWFzZSBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYnVpbGRBZ2VudC5zZXRGYWlsZWQoZXJyb3IubWVzc2FnZSwgdHJ1ZSlcbiAgICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5kaXNhYmxlVGVsZW1ldHJ5KClcblxuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IFNldHRpbmdzLmdldE9wZW5TZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5vcGVuKHNldHRpbmdzKVxuXG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0U3VjY2VlZGVkKFxuICAgICAgICAgICAgJ0dpdFZlcnNpb25NYW5hZ2VyIG9wZW5lZCByZWxlYXNlIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBidWlsZEFnZW50LnNldEZhaWxlZChlcnJvci5tZXNzYWdlLCB0cnVlKVxuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHB1Ymxpc2goKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gU2V0dGluZ3MuZ2V0UHVibGlzaFNldHRpbmdzKGJ1aWxkQWdlbnQpXG5cbiAgICAgICAgYXdhaXQgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLnB1Ymxpc2goc2V0dGluZ3MpXG5cbiAgICAgICAgYnVpbGRBZ2VudC5zZXRTdWNjZWVkZWQoXG4gICAgICAgICAgICAnR2l0VmVyc2lvbk1hbmFnZXIgcHVibGlzaGVkIHJlbGVhc2Ugc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgIHRydWVcbiAgICAgICAgKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGJ1aWxkQWdlbnQuc2V0RmFpbGVkKGVycm9yLm1lc3NhZ2UsIHRydWUpXG4gICAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWRkQXNzZXQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgZ2l0UmVsZWFzZU1hbmFnZXJUb29sLmRpc2FibGVUZWxlbWV0cnkoKVxuXG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gU2V0dGluZ3MuZ2V0QWRkQXNzZXRTZXR0aW5ncyhidWlsZEFnZW50KVxuXG4gICAgICAgIGF3YWl0IGdpdFJlbGVhc2VNYW5hZ2VyVG9vbC5hZGRBc3NldChzZXR0aW5ncylcblxuICAgICAgICBidWlsZEFnZW50LnNldFN1Y2NlZWRlZChcbiAgICAgICAgICAgICdHaXRWZXJzaW9uTWFuYWdlciBhZGRlZCBhc3NldHMgdG8gcmVsZWFzZSBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYnVpbGRBZ2VudC5zZXRGYWlsZWQoZXJyb3IubWVzc2FnZSwgdHJ1ZSlcbiAgICB9XG59XG4iLCJpbXBvcnQgJ3JlZmxlY3QtbWV0YWRhdGEnXG5pbXBvcnQgeyBvcGVuIH0gZnJvbSAnLi9tYWluJ1xuXG5vcGVuKClcbiIsImV4cG9ydCBlbnVtIENvbW1vbkZpZWxkcyB7XG4gICAgcmVwb3NpdG9yeSA9ICdyZXBvc2l0b3J5JyxcbiAgICBvd25lciA9ICdvd25lcicsXG4gICAgdG9rZW4gPSAndG9rZW4nLFxuICAgIHRhcmdldERpcmVjdG9yeSA9ICd0YXJnZXREaXJlY3RvcnknXG59XG5cbmV4cG9ydCBlbnVtIENyZWF0ZUZpZWxkcyB7XG4gICAgbWlsZXN0b25lID0gJ21pbGVzdG9uZScsXG4gICAgbmFtZSA9ICduYW1lJyxcbiAgICBpbnB1dEZpbGVOYW1lID0gJ2lucHV0RmlsZU5hbWUnLFxuICAgIGlzUHJlUmVsZWFzZSA9ICdpc1ByZVJlbGVhc2UnLFxuICAgIGNvbW1pdCA9ICdjb21taXQnLFxuICAgIGFzc2V0cyA9ICdhc3NldHMnXG59XG5cbmV4cG9ydCBlbnVtIERpc2NhcmRGaWVsZHMge1xuICAgIG1pbGVzdG9uZSA9ICdtaWxlc3RvbmUnXG59XG5cbmV4cG9ydCBlbnVtIENsb3NlRmllbGRzIHtcbiAgICBtaWxlc3RvbmUgPSAnbWlsZXN0b25lJ1xufVxuXG5leHBvcnQgZW51bSBPcGVuRmllbGRzIHtcbiAgICBtaWxlc3RvbmUgPSAnbWlsZXN0b25lJ1xufVxuXG5leHBvcnQgZW51bSBQdWJsaXNoRmllbGRzIHtcbiAgICB0YWdOYW1lID0gJ3RhZ05hbWUnXG59XG5cbmV4cG9ydCBlbnVtIEFkZEFzc2V0RmllbGRzIHtcbiAgICB0YWdOYW1lID0gJ3RhZ05hbWUnLFxuICAgIGFzc2V0cyA9ICdhc3NldHMnXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyB7XG4gICAgW0NvbW1vbkZpZWxkcy5yZXBvc2l0b3J5XTogc3RyaW5nXG4gICAgW0NvbW1vbkZpZWxkcy5vd25lcl06IHN0cmluZ1xuICAgIFtDb21tb25GaWVsZHMudG9rZW5dOiBzdHJpbmdcbiAgICBbQ29tbW9uRmllbGRzLnRhcmdldERpcmVjdG9yeV06IHN0cmluZ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdpdFJlbGVhc2VNYW5hZ2VyQ3JlYXRlU2V0dGluZ3NcbiAgICBleHRlbmRzIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtDcmVhdGVGaWVsZHMubWlsZXN0b25lXTogc3RyaW5nXG4gICAgW0NyZWF0ZUZpZWxkcy5uYW1lXTogc3RyaW5nXG4gICAgW0NyZWF0ZUZpZWxkcy5pbnB1dEZpbGVOYW1lXTogc3RyaW5nXG4gICAgW0NyZWF0ZUZpZWxkcy5pc1ByZVJlbGVhc2VdOiBib29sZWFuXG4gICAgW0NyZWF0ZUZpZWxkcy5jb21taXRdOiBzdHJpbmdcbiAgICBbQ3JlYXRlRmllbGRzLmFzc2V0c10/OiBzdHJpbmdbXVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdpdFJlbGVhc2VNYW5hZ2VyRGlzY2FyZFNldHRpbmdzXG4gICAgZXh0ZW5kcyBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzIHtcbiAgICBbRGlzY2FyZEZpZWxkcy5taWxlc3RvbmVdOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRSZWxlYXNlTWFuYWdlckNsb3NlU2V0dGluZ3NcbiAgICBleHRlbmRzIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtDbG9zZUZpZWxkcy5taWxlc3RvbmVdOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRSZWxlYXNlTWFuYWdlck9wZW5TZXR0aW5nc1xuICAgIGV4dGVuZHMgR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyB7XG4gICAgW09wZW5GaWVsZHMubWlsZXN0b25lXTogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3NcbiAgICBleHRlbmRzIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtQdWJsaXNoRmllbGRzLnRhZ05hbWVdOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRSZWxlYXNlTWFuYWdlckFkZEFzc2V0U2V0dGluZ3NcbiAgICBleHRlbmRzIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3Mge1xuICAgIFtBZGRBc3NldEZpZWxkcy50YWdOYW1lXTogc3RyaW5nXG4gICAgW0FkZEFzc2V0RmllbGRzLmFzc2V0c106IHN0cmluZ1tdXG59XG4iLCJpbXBvcnQgeyBJQnVpbGRBZ2VudCB9IGZyb20gJy4uLy4uL2NvcmUvbW9kZWxzJ1xuaW1wb3J0IHtcbiAgICBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzLFxuICAgIENvbW1vbkZpZWxkcyxcbiAgICBDcmVhdGVGaWVsZHMsXG4gICAgRGlzY2FyZEZpZWxkcyxcbiAgICBDbG9zZUZpZWxkcyxcbiAgICBPcGVuRmllbGRzLFxuICAgIFB1Ymxpc2hGaWVsZHMsXG4gICAgQWRkQXNzZXRGaWVsZHMsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5ncyxcbiAgICBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5ncyxcbiAgICBHaXRSZWxlYXNlTWFuYWdlckNsb3NlU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJPcGVuU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzXG59IGZyb20gJy4vbW9kZWxzJ1xuXG5leHBvcnQgY2xhc3MgU2V0dGluZ3Mge1xuICAgIHB1YmxpYyBzdGF0aWMgZ2V0Q3JlYXRlU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5ncyB7XG4gICAgICAgIGNvbnN0IG1pbGVzdG9uZSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ3JlYXRlRmllbGRzLm1pbGVzdG9uZSlcbiAgICAgICAgY29uc3QgbmFtZSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ3JlYXRlRmllbGRzLm5hbWUpXG4gICAgICAgIGNvbnN0IGlucHV0RmlsZU5hbWUgPSBidWlsZEFnZW50LmdldElucHV0KENyZWF0ZUZpZWxkcy5pbnB1dEZpbGVOYW1lKVxuICAgICAgICBjb25zdCBpc1ByZVJlbGVhc2UgPSBidWlsZEFnZW50LmdldEJvb2xlYW5JbnB1dChcbiAgICAgICAgICAgIENyZWF0ZUZpZWxkcy5pc1ByZVJlbGVhc2VcbiAgICAgICAgKVxuICAgICAgICBjb25zdCBjb21taXQgPSBidWlsZEFnZW50LmdldElucHV0KENyZWF0ZUZpZWxkcy5jb21taXQpXG4gICAgICAgIGNvbnN0IGFzc2V0cyA9IGJ1aWxkQWdlbnQuZ2V0TGlzdElucHV0KENyZWF0ZUZpZWxkcy5hc3NldHMpXG5cbiAgICAgICAgY29uc3QgY29tbW9uU2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDb21tb25TZXR0aW5ncyhidWlsZEFnZW50KVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY29tbW9uU2V0dGluZ3MsXG4gICAgICAgICAgICBtaWxlc3RvbmUsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgaW5wdXRGaWxlTmFtZSxcbiAgICAgICAgICAgIGlzUHJlUmVsZWFzZSxcbiAgICAgICAgICAgIGNvbW1pdCxcbiAgICAgICAgICAgIGFzc2V0c1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBnZXREaXNjYXJkU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJEaXNjYXJkU2V0dGluZ3Mge1xuICAgICAgICBjb25zdCBtaWxlc3RvbmUgPSBidWlsZEFnZW50LmdldElucHV0KERpc2NhcmRGaWVsZHMubWlsZXN0b25lKVxuXG4gICAgICAgIGNvbnN0IGNvbW1vblNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q29tbW9uU2V0dGluZ3MoYnVpbGRBZ2VudClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vblNldHRpbmdzLFxuICAgICAgICAgICAgbWlsZXN0b25lXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGdldENsb3NlU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJDbG9zZVNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgbWlsZXN0b25lID0gYnVpbGRBZ2VudC5nZXRJbnB1dChDbG9zZUZpZWxkcy5taWxlc3RvbmUpXG5cbiAgICAgICAgY29uc3QgY29tbW9uU2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDb21tb25TZXR0aW5ncyhidWlsZEFnZW50KVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY29tbW9uU2V0dGluZ3MsXG4gICAgICAgICAgICBtaWxlc3RvbmVcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0T3BlblNldHRpbmdzKFxuICAgICAgICBidWlsZEFnZW50OiBJQnVpbGRBZ2VudFxuICAgICk6IEdpdFJlbGVhc2VNYW5hZ2VyT3BlblNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgbWlsZXN0b25lID0gYnVpbGRBZ2VudC5nZXRJbnB1dChPcGVuRmllbGRzLm1pbGVzdG9uZSlcblxuICAgICAgICBjb25zdCBjb21tb25TZXR0aW5ncyA9IFNldHRpbmdzLmdldENvbW1vblNldHRpbmdzKGJ1aWxkQWdlbnQpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5jb21tb25TZXR0aW5ncyxcbiAgICAgICAgICAgIG1pbGVzdG9uZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBnZXRQdWJsaXNoU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3Mge1xuICAgICAgICBjb25zdCB0YWdOYW1lID0gYnVpbGRBZ2VudC5nZXRJbnB1dChQdWJsaXNoRmllbGRzLnRhZ05hbWUpXG5cbiAgICAgICAgY29uc3QgY29tbW9uU2V0dGluZ3MgPSBTZXR0aW5ncy5nZXRDb21tb25TZXR0aW5ncyhidWlsZEFnZW50KVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY29tbW9uU2V0dGluZ3MsXG4gICAgICAgICAgICB0YWdOYW1lXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGdldEFkZEFzc2V0U2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzIHtcbiAgICAgICAgY29uc3QgdGFnTmFtZSA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQWRkQXNzZXRGaWVsZHMudGFnTmFtZSlcbiAgICAgICAgY29uc3QgYXNzZXRzID0gYnVpbGRBZ2VudC5nZXRMaXN0SW5wdXQoQWRkQXNzZXRGaWVsZHMuYXNzZXRzKVxuXG4gICAgICAgIGNvbnN0IGNvbW1vblNldHRpbmdzID0gU2V0dGluZ3MuZ2V0Q29tbW9uU2V0dGluZ3MoYnVpbGRBZ2VudClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vblNldHRpbmdzLFxuICAgICAgICAgICAgdGFnTmFtZSxcbiAgICAgICAgICAgIGFzc2V0c1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgZ2V0Q29tbW9uU2V0dGluZ3MoXG4gICAgICAgIGJ1aWxkQWdlbnQ6IElCdWlsZEFnZW50XG4gICAgKTogR2l0UmVsZWFzZU1hbmFnZXJTZXR0aW5ncyB7XG4gICAgICAgIGNvbnN0IG93bmVyID0gYnVpbGRBZ2VudC5nZXRJbnB1dChDb21tb25GaWVsZHMub3duZXIsIHRydWUpXG4gICAgICAgIGNvbnN0IHJlcG9zaXRvcnkgPSBidWlsZEFnZW50LmdldElucHV0KENvbW1vbkZpZWxkcy5yZXBvc2l0b3J5LCB0cnVlKVxuICAgICAgICBjb25zdCB0b2tlbiA9IGJ1aWxkQWdlbnQuZ2V0SW5wdXQoQ29tbW9uRmllbGRzLnRva2VuLCB0cnVlKVxuICAgICAgICBjb25zdCB0YXJnZXREaXJlY3RvcnkgPSBidWlsZEFnZW50LmdldElucHV0KFxuICAgICAgICAgICAgQ29tbW9uRmllbGRzLnRhcmdldERpcmVjdG9yeVxuICAgICAgICApXG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG93bmVyLFxuICAgICAgICAgICAgcmVwb3NpdG9yeSxcbiAgICAgICAgICAgIHRva2VuLFxuICAgICAgICAgICAgdGFyZ2V0RGlyZWN0b3J5XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKVxuXG5pbXBvcnQgeyBUWVBFUywgSUJ1aWxkQWdlbnQsIElFeGVjUmVzdWx0IH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMnXG5pbXBvcnQgeyBpbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdpbnZlcnNpZnknXG5pbXBvcnQgeyBEb3RuZXRUb29sLCBJRG90bmV0VG9vbCB9IGZyb20gJy4uLy4uL2NvcmUvZG90bmV0LXRvb2wnXG5pbXBvcnQgeyBJVmVyc2lvbk1hbmFnZXIgfSBmcm9tICcuLi8uLi9jb3JlL3ZlcnNpb25NYW5hZ2VyJ1xuXG5pbXBvcnQge1xuICAgIEdpdFJlbGVhc2VNYW5hZ2VyU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5ncyxcbiAgICBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5ncyxcbiAgICBHaXRSZWxlYXNlTWFuYWdlckNsb3NlU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJPcGVuU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3MsXG4gICAgR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzXG59IGZyb20gJy4vbW9kZWxzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIElHaXRSZWxlYXNlTWFuYWdlclRvb2wgZXh0ZW5kcyBJRG90bmV0VG9vbCB7XG4gICAgaW5zdGFsbCh2ZXJzaW9uU3BlYzogc3RyaW5nLCBpbmNsdWRlUHJlcmVsZWFzZTogYm9vbGVhbik6IFByb21pc2U8dm9pZD5cbiAgICBjcmVhdGUoc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQ3JlYXRlU2V0dGluZ3MpOiBQcm9taXNlPElFeGVjUmVzdWx0PlxuICAgIGRpc2NhcmQoc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyRGlzY2FyZFNldHRpbmdzKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD5cbiAgICBjbG9zZShzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJDbG9zZVNldHRpbmdzKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD5cbiAgICBvcGVuKHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlck9wZW5TZXR0aW5ncyk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+XG4gICAgcHVibGlzaChzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJQdWJsaXNoU2V0dGluZ3MpOiBQcm9taXNlPElFeGVjUmVzdWx0PlxuICAgIGFkZEFzc2V0KHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckFkZEFzc2V0U2V0dGluZ3MpOiBQcm9taXNlPElFeGVjUmVzdWx0PlxufVxuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgR2l0UmVsZWFzZU1hbmFnZXJUb29sXG4gICAgZXh0ZW5kcyBEb3RuZXRUb29sXG4gICAgaW1wbGVtZW50cyBJR2l0UmVsZWFzZU1hbmFnZXJUb29sIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgQGluamVjdChUWVBFUy5JQnVpbGRBZ2VudCkgYnVpbGRBZ2VudDogSUJ1aWxkQWdlbnQsXG4gICAgICAgIEBpbmplY3QoVFlQRVMuSVZlcnNpb25NYW5hZ2VyKSB2ZXJzaW9uTWFuYWdlcjogSVZlcnNpb25NYW5hZ2VyXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGJ1aWxkQWdlbnQsIHZlcnNpb25NYW5hZ2VyKVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBpbnN0YWxsKFxuICAgICAgICB2ZXJzaW9uU3BlYzogc3RyaW5nLFxuICAgICAgICBpbmNsdWRlUHJlcmVsZWFzZTogYm9vbGVhblxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnRvb2xJbnN0YWxsKFxuICAgICAgICAgICAgJ0dpdFJlbGVhc2VNYW5hZ2VyLlRvb2wnLFxuICAgICAgICAgICAgdmVyc2lvblNwZWMsXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgIGluY2x1ZGVQcmVyZWxlYXNlXG4gICAgICAgIClcbiAgICB9XG5cbiAgICBwdWJsaWMgY3JlYXRlKFxuICAgICAgICBzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJDcmVhdGVTZXR0aW5nc1xuICAgICk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMuZ2V0Q3JlYXRlQXJndW1lbnRzKHNldHRpbmdzKVxuXG4gICAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoJ2RvdG5ldC1naXRyZWxlYXNlbWFuYWdlcicsIGFyZ3MpXG4gICAgfVxuXG4gICAgcHVibGljIGRpc2NhcmQoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5nc1xuICAgICk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMuZ2V0RGlzY2FyZEFyZ3VtZW50cyhzZXR0aW5ncylcblxuICAgICAgICByZXR1cm4gdGhpcy5leGVjdXRlKCdkb3RuZXQtZ2l0cmVsZWFzZW1hbmFnZXInLCBhcmdzKVxuICAgIH1cblxuICAgIHB1YmxpYyBjbG9zZShcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQ2xvc2VTZXR0aW5nc1xuICAgICk6IFByb21pc2U8SUV4ZWNSZXN1bHQ+IHtcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMuZ2V0Q2xvc2VBcmd1bWVudHMoc2V0dGluZ3MpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSgnZG90bmV0LWdpdHJlbGVhc2VtYW5hZ2VyJywgYXJncylcbiAgICB9XG5cbiAgICBwdWJsaWMgb3BlbihzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJPcGVuU2V0dGluZ3MpOiBQcm9taXNlPElFeGVjUmVzdWx0PiB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB0aGlzLmdldE9wZW5Bcmd1bWVudHMoc2V0dGluZ3MpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSgnZG90bmV0LWdpdHJlbGVhc2VtYW5hZ2VyJywgYXJncylcbiAgICB9XG5cbiAgICBwdWJsaWMgcHVibGlzaChcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyUHVibGlzaFNldHRpbmdzXG4gICAgKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD4ge1xuICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5nZXRQdWJsaXNoQXJndW1lbnRzKHNldHRpbmdzKVxuXG4gICAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoJ2RvdG5ldC1naXRyZWxlYXNlbWFuYWdlcicsIGFyZ3MpXG4gICAgfVxuXG4gICAgcHVibGljIGFkZEFzc2V0KFxuICAgICAgICBzZXR0aW5nczogR2l0UmVsZWFzZU1hbmFnZXJBZGRBc3NldFNldHRpbmdzXG4gICAgKTogUHJvbWlzZTxJRXhlY1Jlc3VsdD4ge1xuICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5nZXRBZGRBc3NldEFyZ3VtZW50cyhzZXR0aW5ncylcblxuICAgICAgICByZXR1cm4gdGhpcy5leGVjdXRlKCdkb3RuZXQtZ2l0cmVsZWFzZW1hbmFnZXInLCBhcmdzKVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q29tbW9uQXJndW1lbnRzKHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlclNldHRpbmdzKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFtdXG5cbiAgICAgICAgYXJncy5wdXNoKCctLW93bmVyJywgc2V0dGluZ3Mub3duZXIpXG4gICAgICAgIGFyZ3MucHVzaCgnLS1yZXBvc2l0b3J5Jywgc2V0dGluZ3MucmVwb3NpdG9yeSlcbiAgICAgICAgYXJncy5wdXNoKCctLXRva2VuJywgc2V0dGluZ3MudG9rZW4pXG5cbiAgICAgICAgc2V0dGluZ3MudGFyZ2V0RGlyZWN0b3J5ID0gdGhpcy5nZXRSZXBvRGlyKHNldHRpbmdzLnRhcmdldERpcmVjdG9yeSlcblxuICAgICAgICBhcmdzLnB1c2goJy0tdGFyZ2V0RGlyZWN0b3J5Jywgc2V0dGluZ3MudGFyZ2V0RGlyZWN0b3J5KVxuXG4gICAgICAgIHJldHVybiBhcmdzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRDcmVhdGVBcmd1bWVudHMoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckNyZWF0ZVNldHRpbmdzXG4gICAgKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFsnY3JlYXRlJywgLi4udGhpcy5nZXRDb21tb25Bcmd1bWVudHMoc2V0dGluZ3MpXVxuXG4gICAgICAgIGlmIChzZXR0aW5ncy5taWxlc3RvbmUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1taWxlc3RvbmUnLCBzZXR0aW5ncy5taWxlc3RvbmUpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNldHRpbmdzLm5hbWUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1uYW1lJywgc2V0dGluZ3MubmFtZSlcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0dGluZ3MuY29tbWl0KSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tdGFyZ2V0Y29tbWl0aXNoJywgc2V0dGluZ3MuY29tbWl0KVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNldHRpbmdzLmlucHV0RmlsZU5hbWUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1aWxkQWdlbnQuZmlsZUV4aXN0cyhzZXR0aW5ncy5pbnB1dEZpbGVOYW1lKSkge1xuICAgICAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1pbnB1dEZpbGVQYXRoJywgc2V0dGluZ3MuaW5wdXRGaWxlTmFtZSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAnR2l0UmVsZWFzZU1hbmFnZXIgaW5wdXRGaWxlUGF0aCBub3QgZm91bmQgYXQgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5ncy5pbnB1dEZpbGVOYW1lXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5pc1ByZVJlbGVhc2UpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1wcmUnKVxuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5hc3NldHMgJiYgc2V0dGluZ3MuYXNzZXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNldHRpbmdzLmFzc2V0cyA9IHNldHRpbmdzLmFzc2V0cy5tYXAoYXNzZXQgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoLmpvaW4oc2V0dGluZ3MudGFyZ2V0RGlyZWN0b3J5LCBhc3NldClcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1hc3NldHMnLCBzZXR0aW5ncy5hc3NldHMuam9pbignLCcpKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyZ3NcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERpc2NhcmRBcmd1bWVudHMoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlckRpc2NhcmRTZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbJ2Rpc2NhcmQnLCAuLi50aGlzLmdldENvbW1vbkFyZ3VtZW50cyhzZXR0aW5ncyldXG5cbiAgICAgICAgaWYgKHNldHRpbmdzLm1pbGVzdG9uZSkge1xuICAgICAgICAgICAgYXJncy5wdXNoKCctLW1pbGVzdG9uZScsIHNldHRpbmdzLm1pbGVzdG9uZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcmdzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRDbG9zZUFyZ3VtZW50cyhcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQ2xvc2VTZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbJ2Nsb3NlJywgLi4udGhpcy5nZXRDb21tb25Bcmd1bWVudHMoc2V0dGluZ3MpXVxuXG4gICAgICAgIGlmIChzZXR0aW5ncy5taWxlc3RvbmUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1taWxlc3RvbmUnLCBzZXR0aW5ncy5taWxlc3RvbmUpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJnc1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0T3BlbkFyZ3VtZW50cyhcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyT3BlblNldHRpbmdzXG4gICAgKTogc3RyaW5nW10ge1xuICAgICAgICBjb25zdCBhcmdzOiBzdHJpbmdbXSA9IFsnb3BlbicsIC4uLnRoaXMuZ2V0Q29tbW9uQXJndW1lbnRzKHNldHRpbmdzKV1cblxuICAgICAgICBpZiAoc2V0dGluZ3MubWlsZXN0b25lKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goJy0tbWlsZXN0b25lJywgc2V0dGluZ3MubWlsZXN0b25lKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyZ3NcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFB1Ymxpc2hBcmd1bWVudHMoXG4gICAgICAgIHNldHRpbmdzOiBHaXRSZWxlYXNlTWFuYWdlclB1Ymxpc2hTZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbJ3B1Ymxpc2gnLCAuLi50aGlzLmdldENvbW1vbkFyZ3VtZW50cyhzZXR0aW5ncyldXG5cbiAgICAgICAgaWYgKHNldHRpbmdzLnRhZ05hbWUpIHtcbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS10YWdOYW1lJywgc2V0dGluZ3MudGFnTmFtZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcmdzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRBZGRBc3NldEFyZ3VtZW50cyhcbiAgICAgICAgc2V0dGluZ3M6IEdpdFJlbGVhc2VNYW5hZ2VyQWRkQXNzZXRTZXR0aW5nc1xuICAgICk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgYXJnczogc3RyaW5nW10gPSBbXG4gICAgICAgICAgICAnYWRkYXNzZXQnLFxuICAgICAgICAgICAgLi4udGhpcy5nZXRDb21tb25Bcmd1bWVudHMoc2V0dGluZ3MpXG4gICAgICAgIF1cblxuICAgICAgICBpZiAoc2V0dGluZ3MudGFnTmFtZSkge1xuICAgICAgICAgICAgYXJncy5wdXNoKCctLXRhZ05hbWUnLCBzZXR0aW5ncy50YWdOYW1lKVxuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5hc3NldHMgJiYgc2V0dGluZ3MuYXNzZXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNldHRpbmdzLmFzc2V0cyA9IHNldHRpbmdzLmFzc2V0cy5tYXAoYXNzZXQgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoLmpvaW4oc2V0dGluZ3MudGFyZ2V0RGlyZWN0b3J5LCBhc3NldClcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGFyZ3MucHVzaCgnLS1hc3NldHMnLCBzZXR0aW5ncy5hc3NldHMuam9pbignLCcpKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyZ3NcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFJlcG9EaXIodGFyZ2V0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHdvcmtEaXI6IHN0cmluZ1xuICAgICAgICBjb25zdCBzcmNEaXIgPSB0aGlzLmJ1aWxkQWdlbnQuZ2V0U291cmNlRGlyKClcbiAgICAgICAgaWYgKCF0YXJnZXRQYXRoKSB7XG4gICAgICAgICAgICB3b3JrRGlyID0gc3JjRGlyXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy5idWlsZEFnZW50LmRpcmVjdG9yeUV4aXN0cyh0YXJnZXRQYXRoKSkge1xuICAgICAgICAgICAgICAgIHdvcmtEaXIgPSBwYXRoLmpvaW4oc3JjRGlyLCB0YXJnZXRQYXRoKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpcmVjdG9yeSBub3QgZm91bmQgYXQgJyArIHRhcmdldFBhdGgpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdvcmtEaXIucmVwbGFjZSgvXFxcXC9nLCAnLycpXG4gICAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIGZpbGUgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG52YXIgX19hd2FpdGVyID0gKHRoaXMgJiYgdGhpcy5fX2F3YWl0ZXIpIHx8IGZ1bmN0aW9uICh0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59O1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbmNvbnN0IHVybCA9IHJlcXVpcmUoXCJ1cmxcIik7XHJcbmNvbnN0IGh0dHAgPSByZXF1aXJlKFwiaHR0cFwiKTtcclxuY29uc3QgaHR0cHMgPSByZXF1aXJlKFwiaHR0cHNcIik7XHJcbmNvbnN0IHV0aWwgPSByZXF1aXJlKFwiLi9VdGlsXCIpO1xyXG5sZXQgZnM7XHJcbmxldCB0dW5uZWw7XHJcbnZhciBIdHRwQ29kZXM7XHJcbihmdW5jdGlvbiAoSHR0cENvZGVzKSB7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiT0tcIl0gPSAyMDBdID0gXCJPS1wiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk11bHRpcGxlQ2hvaWNlc1wiXSA9IDMwMF0gPSBcIk11bHRpcGxlQ2hvaWNlc1wiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk1vdmVkUGVybWFuZW50bHlcIl0gPSAzMDFdID0gXCJNb3ZlZFBlcm1hbmVudGx5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUmVzb3VyY2VNb3ZlZFwiXSA9IDMwMl0gPSBcIlJlc291cmNlTW92ZWRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJTZWVPdGhlclwiXSA9IDMwM10gPSBcIlNlZU90aGVyXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTm90TW9kaWZpZWRcIl0gPSAzMDRdID0gXCJOb3RNb2RpZmllZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlVzZVByb3h5XCJdID0gMzA1XSA9IFwiVXNlUHJveHlcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJTd2l0Y2hQcm94eVwiXSA9IDMwNl0gPSBcIlN3aXRjaFByb3h5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiVGVtcG9yYXJ5UmVkaXJlY3RcIl0gPSAzMDddID0gXCJUZW1wb3JhcnlSZWRpcmVjdFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlBlcm1hbmVudFJlZGlyZWN0XCJdID0gMzA4XSA9IFwiUGVybWFuZW50UmVkaXJlY3RcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJCYWRSZXF1ZXN0XCJdID0gNDAwXSA9IFwiQmFkUmVxdWVzdFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlVuYXV0aG9yaXplZFwiXSA9IDQwMV0gPSBcIlVuYXV0aG9yaXplZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlBheW1lbnRSZXF1aXJlZFwiXSA9IDQwMl0gPSBcIlBheW1lbnRSZXF1aXJlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkZvcmJpZGRlblwiXSA9IDQwM10gPSBcIkZvcmJpZGRlblwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk5vdEZvdW5kXCJdID0gNDA0XSA9IFwiTm90Rm91bmRcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJNZXRob2ROb3RBbGxvd2VkXCJdID0gNDA1XSA9IFwiTWV0aG9kTm90QWxsb3dlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIk5vdEFjY2VwdGFibGVcIl0gPSA0MDZdID0gXCJOb3RBY2NlcHRhYmxlXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCJdID0gNDA3XSA9IFwiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiUmVxdWVzdFRpbWVvdXRcIl0gPSA0MDhdID0gXCJSZXF1ZXN0VGltZW91dFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkNvbmZsaWN0XCJdID0gNDA5XSA9IFwiQ29uZmxpY3RcIjtcclxuICAgIEh0dHBDb2Rlc1tIdHRwQ29kZXNbXCJHb25lXCJdID0gNDEwXSA9IFwiR29uZVwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIlRvb01hbnlSZXF1ZXN0c1wiXSA9IDQyOV0gPSBcIlRvb01hbnlSZXF1ZXN0c1wiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkludGVybmFsU2VydmVyRXJyb3JcIl0gPSA1MDBdID0gXCJJbnRlcm5hbFNlcnZlckVycm9yXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiTm90SW1wbGVtZW50ZWRcIl0gPSA1MDFdID0gXCJOb3RJbXBsZW1lbnRlZFwiO1xyXG4gICAgSHR0cENvZGVzW0h0dHBDb2Rlc1tcIkJhZEdhdGV3YXlcIl0gPSA1MDJdID0gXCJCYWRHYXRld2F5XCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiU2VydmljZVVuYXZhaWxhYmxlXCJdID0gNTAzXSA9IFwiU2VydmljZVVuYXZhaWxhYmxlXCI7XHJcbiAgICBIdHRwQ29kZXNbSHR0cENvZGVzW1wiR2F0ZXdheVRpbWVvdXRcIl0gPSA1MDRdID0gXCJHYXRld2F5VGltZW91dFwiO1xyXG59KShIdHRwQ29kZXMgPSBleHBvcnRzLkh0dHBDb2RlcyB8fCAoZXhwb3J0cy5IdHRwQ29kZXMgPSB7fSkpO1xyXG5jb25zdCBIdHRwUmVkaXJlY3RDb2RlcyA9IFtIdHRwQ29kZXMuTW92ZWRQZXJtYW5lbnRseSwgSHR0cENvZGVzLlJlc291cmNlTW92ZWQsIEh0dHBDb2Rlcy5TZWVPdGhlciwgSHR0cENvZGVzLlRlbXBvcmFyeVJlZGlyZWN0LCBIdHRwQ29kZXMuUGVybWFuZW50UmVkaXJlY3RdO1xyXG5jb25zdCBIdHRwUmVzcG9uc2VSZXRyeUNvZGVzID0gW0h0dHBDb2Rlcy5CYWRHYXRld2F5LCBIdHRwQ29kZXMuU2VydmljZVVuYXZhaWxhYmxlLCBIdHRwQ29kZXMuR2F0ZXdheVRpbWVvdXRdO1xyXG5jb25zdCBOZXR3b3JrUmV0cnlFcnJvcnMgPSBbJ0VDT05OUkVTRVQnLCAnRU5PVEZPVU5EJywgJ0VTT0NLRVRUSU1FRE9VVCcsICdFVElNRURPVVQnLCAnRUNPTk5SRUZVU0VEJ107XHJcbmNvbnN0IFJldHJ5YWJsZUh0dHBWZXJicyA9IFsnT1BUSU9OUycsICdHRVQnLCAnREVMRVRFJywgJ0hFQUQnXTtcclxuY29uc3QgRXhwb25lbnRpYWxCYWNrb2ZmQ2VpbGluZyA9IDEwO1xyXG5jb25zdCBFeHBvbmVudGlhbEJhY2tvZmZUaW1lU2xpY2UgPSA1O1xyXG5jbGFzcyBIdHRwQ2xpZW50UmVzcG9uc2Uge1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XHJcbiAgICB9XHJcbiAgICByZWFkQm9keSgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICBsZXQgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDApO1xyXG4gICAgICAgICAgICBjb25zdCBlbmNvZGluZ0NoYXJzZXQgPSB1dGlsLm9idGFpbkNvbnRlbnRDaGFyc2V0KHRoaXMpO1xyXG4gICAgICAgICAgICAvLyBFeHRyYWN0IEVuY29kaW5nIGZyb20gaGVhZGVyOiAnY29udGVudC1lbmNvZGluZydcclxuICAgICAgICAgICAgLy8gTWF0Y2ggYGd6aXBgLCBgZ3ppcCwgZGVmbGF0ZWAgdmFyaWF0aW9ucyBvZiBHWklQIGVuY29kaW5nXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRFbmNvZGluZyA9IHRoaXMubWVzc2FnZS5oZWFkZXJzWydjb250ZW50LWVuY29kaW5nJ10gfHwgJyc7XHJcbiAgICAgICAgICAgIGNvbnN0IGlzR3ppcHBlZEVuY29kZWQgPSBuZXcgUmVnRXhwKCcoZ3ppcCQpfChnemlwLCAqZGVmbGF0ZSknKS50ZXN0KGNvbnRlbnRFbmNvZGluZyk7XHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZS5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaHVuayA9ICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpID8gQnVmZmVyLmZyb20oZGF0YSwgZW5jb2RpbmdDaGFyc2V0KSA6IGRhdGE7XHJcbiAgICAgICAgICAgICAgICBidWZmZXIgPSBCdWZmZXIuY29uY2F0KFtidWZmZXIsIGNodW5rXSk7XHJcbiAgICAgICAgICAgIH0pLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0d6aXBwZWRFbmNvZGVkKSB7IC8vIFByb2Nlc3MgR1ppcHBlZCBSZXNwb25zZSBCb2R5IEhFUkVcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ3VuemlwcGVkQm9keSA9IHlpZWxkIHV0aWwuZGVjb21wcmVzc0d6aXBwZWRDb250ZW50KGJ1ZmZlciwgZW5jb2RpbmdDaGFyc2V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShndW56aXBwZWRCb2R5KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoYnVmZmVyLnRvU3RyaW5nKGVuY29kaW5nQ2hhcnNldCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSkpO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuSHR0cENsaWVudFJlc3BvbnNlID0gSHR0cENsaWVudFJlc3BvbnNlO1xyXG5mdW5jdGlvbiBpc0h0dHBzKHJlcXVlc3RVcmwpIHtcclxuICAgIGxldCBwYXJzZWRVcmwgPSB1cmwucGFyc2UocmVxdWVzdFVybCk7XHJcbiAgICByZXR1cm4gcGFyc2VkVXJsLnByb3RvY29sID09PSAnaHR0cHM6JztcclxufVxyXG5leHBvcnRzLmlzSHR0cHMgPSBpc0h0dHBzO1xyXG52YXIgRW52aXJvbm1lbnRWYXJpYWJsZXM7XHJcbihmdW5jdGlvbiAoRW52aXJvbm1lbnRWYXJpYWJsZXMpIHtcclxuICAgIEVudmlyb25tZW50VmFyaWFibGVzW1wiSFRUUF9QUk9YWVwiXSA9IFwiSFRUUF9QUk9YWVwiO1xyXG4gICAgRW52aXJvbm1lbnRWYXJpYWJsZXNbXCJIVFRQU19QUk9YWVwiXSA9IFwiSFRUUFNfUFJPWFlcIjtcclxuICAgIEVudmlyb25tZW50VmFyaWFibGVzW1wiTk9fUFJPWFlcIl0gPSBcIk5PX1BST1hZXCI7XHJcbn0pKEVudmlyb25tZW50VmFyaWFibGVzIHx8IChFbnZpcm9ubWVudFZhcmlhYmxlcyA9IHt9KSk7XHJcbmNsYXNzIEh0dHBDbGllbnQge1xyXG4gICAgY29uc3RydWN0b3IodXNlckFnZW50LCBoYW5kbGVycywgcmVxdWVzdE9wdGlvbnMpIHtcclxuICAgICAgICB0aGlzLl9pZ25vcmVTc2xFcnJvciA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuX2FsbG93UmVkaXJlY3RzID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9hbGxvd1JlZGlyZWN0RG93bmdyYWRlID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fbWF4UmVkaXJlY3RzID0gNTA7XHJcbiAgICAgICAgdGhpcy5fYWxsb3dSZXRyaWVzID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fbWF4UmV0cmllcyA9IDE7XHJcbiAgICAgICAgdGhpcy5fa2VlcEFsaXZlID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fZGlzcG9zZWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnVzZXJBZ2VudCA9IHVzZXJBZ2VudDtcclxuICAgICAgICB0aGlzLmhhbmRsZXJzID0gaGFuZGxlcnMgfHwgW107XHJcbiAgICAgICAgbGV0IG5vX3Byb3h5ID0gcHJvY2Vzcy5lbnZbRW52aXJvbm1lbnRWYXJpYWJsZXMuTk9fUFJPWFldO1xyXG4gICAgICAgIGlmIChub19wcm94eSkge1xyXG4gICAgICAgICAgICB0aGlzLl9odHRwUHJveHlCeXBhc3NIb3N0cyA9IFtdO1xyXG4gICAgICAgICAgICBub19wcm94eS5zcGxpdCgnLCcpLmZvckVhY2goYnlwYXNzID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2h0dHBQcm94eUJ5cGFzc0hvc3RzLnB1c2godXRpbC5idWlsZFByb3h5QnlwYXNzUmVnZXhGcm9tRW52KGJ5cGFzcykpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5yZXF1ZXN0T3B0aW9ucyA9IHJlcXVlc3RPcHRpb25zO1xyXG4gICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucykge1xyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMuaWdub3JlU3NsRXJyb3IgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faWdub3JlU3NsRXJyb3IgPSByZXF1ZXN0T3B0aW9ucy5pZ25vcmVTc2xFcnJvcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9zb2NrZXRUaW1lb3V0ID0gcmVxdWVzdE9wdGlvbnMuc29ja2V0VGltZW91dDtcclxuICAgICAgICAgICAgdGhpcy5faHR0cFByb3h5ID0gcmVxdWVzdE9wdGlvbnMucHJveHk7XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5wcm94eSAmJiByZXF1ZXN0T3B0aW9ucy5wcm94eS5wcm94eUJ5cGFzc0hvc3RzKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9odHRwUHJveHlCeXBhc3NIb3N0cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgcmVxdWVzdE9wdGlvbnMucHJveHkucHJveHlCeXBhc3NIb3N0cy5mb3JFYWNoKGJ5cGFzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faHR0cFByb3h5QnlwYXNzSG9zdHMucHVzaChuZXcgUmVnRXhwKGJ5cGFzcywgJ2knKSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9jZXJ0Q29uZmlnID0gcmVxdWVzdE9wdGlvbnMuY2VydDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2NlcnRDb25maWcpIHtcclxuICAgICAgICAgICAgICAgIC8vIElmIHVzaW5nIGNlcnQsIG5lZWQgZnNcclxuICAgICAgICAgICAgICAgIGZzID0gcmVxdWlyZSgnZnMnKTtcclxuICAgICAgICAgICAgICAgIC8vIGNhY2hlIHRoZSBjZXJ0IGNvbnRlbnQgaW50byBtZW1vcnksIHNvIHdlIGRvbid0IGhhdmUgdG8gcmVhZCBpdCBmcm9tIGRpc2sgZXZlcnkgdGltZVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NlcnRDb25maWcuY2FGaWxlICYmIGZzLmV4aXN0c1N5bmModGhpcy5fY2VydENvbmZpZy5jYUZpbGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2EgPSBmcy5yZWFkRmlsZVN5bmModGhpcy5fY2VydENvbmZpZy5jYUZpbGUsICd1dGY4Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fY2VydENvbmZpZy5jZXJ0RmlsZSAmJiBmcy5leGlzdHNTeW5jKHRoaXMuX2NlcnRDb25maWcuY2VydEZpbGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2VydCA9IGZzLnJlYWRGaWxlU3luYyh0aGlzLl9jZXJ0Q29uZmlnLmNlcnRGaWxlLCAndXRmOCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NlcnRDb25maWcua2V5RmlsZSAmJiBmcy5leGlzdHNTeW5jKHRoaXMuX2NlcnRDb25maWcua2V5RmlsZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXkgPSBmcy5yZWFkRmlsZVN5bmModGhpcy5fY2VydENvbmZpZy5rZXlGaWxlLCAndXRmOCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0cyAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxvd1JlZGlyZWN0cyA9IHJlcXVlc3RPcHRpb25zLmFsbG93UmVkaXJlY3RzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0RG93bmdyYWRlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FsbG93UmVkaXJlY3REb3duZ3JhZGUgPSByZXF1ZXN0T3B0aW9ucy5hbGxvd1JlZGlyZWN0RG93bmdyYWRlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0T3B0aW9ucy5tYXhSZWRpcmVjdHMgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWF4UmVkaXJlY3RzID0gTWF0aC5tYXgocmVxdWVzdE9wdGlvbnMubWF4UmVkaXJlY3RzLCAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMua2VlcEFsaXZlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2tlZXBBbGl2ZSA9IHJlcXVlc3RPcHRpb25zLmtlZXBBbGl2ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMuYWxsb3dSZXRyaWVzICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FsbG93UmV0cmllcyA9IHJlcXVlc3RPcHRpb25zLmFsbG93UmV0cmllcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVxdWVzdE9wdGlvbnMubWF4UmV0cmllcyAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9tYXhSZXRyaWVzID0gcmVxdWVzdE9wdGlvbnMubWF4UmV0cmllcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIG9wdGlvbnMocmVxdWVzdFVybCwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdPUFRJT05TJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgZ2V0KHJlcXVlc3RVcmwsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnR0VUJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgZGVsKHJlcXVlc3RVcmwsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnREVMRVRFJywgcmVxdWVzdFVybCwgbnVsbCwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgcG9zdChyZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ1BPU1QnLCByZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBwYXRjaChyZXF1ZXN0VXJsLCBkYXRhLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ1BBVENIJywgcmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgcHV0KHJlcXVlc3RVcmwsIGRhdGEsIGFkZGl0aW9uYWxIZWFkZXJzKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnUFVUJywgcmVxdWVzdFVybCwgZGF0YSwgYWRkaXRpb25hbEhlYWRlcnMgfHwge30pO1xyXG4gICAgfVxyXG4gICAgaGVhZChyZXF1ZXN0VXJsLCBhZGRpdGlvbmFsSGVhZGVycykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ0hFQUQnLCByZXF1ZXN0VXJsLCBudWxsLCBhZGRpdGlvbmFsSGVhZGVycyB8fCB7fSk7XHJcbiAgICB9XHJcbiAgICBzZW5kU3RyZWFtKHZlcmIsIHJlcXVlc3RVcmwsIHN0cmVhbSwgYWRkaXRpb25hbEhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHZlcmIsIHJlcXVlc3RVcmwsIHN0cmVhbSwgYWRkaXRpb25hbEhlYWRlcnMpO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBNYWtlcyBhIHJhdyBodHRwIHJlcXVlc3QuXHJcbiAgICAgKiBBbGwgb3RoZXIgbWV0aG9kcyBzdWNoIGFzIGdldCwgcG9zdCwgcGF0Y2gsIGFuZCByZXF1ZXN0IHVsdGltYXRlbHkgY2FsbCB0aGlzLlxyXG4gICAgICogUHJlZmVyIGdldCwgZGVsLCBwb3N0IGFuZCBwYXRjaFxyXG4gICAgICovXHJcbiAgICByZXF1ZXN0KHZlcmIsIHJlcXVlc3RVcmwsIGRhdGEsIGhlYWRlcnMpIHtcclxuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fZGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNsaWVudCBoYXMgYWxyZWFkeSBiZWVuIGRpc3Bvc2VkLlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBsZXQgcGFyc2VkVXJsID0gdXJsLnBhcnNlKHJlcXVlc3RVcmwpO1xyXG4gICAgICAgICAgICBsZXQgaW5mbyA9IHRoaXMuX3ByZXBhcmVSZXF1ZXN0KHZlcmIsIHBhcnNlZFVybCwgaGVhZGVycyk7XHJcbiAgICAgICAgICAgIC8vIE9ubHkgcGVyZm9ybSByZXRyaWVzIG9uIHJlYWRzIHNpbmNlIHdyaXRlcyBtYXkgbm90IGJlIGlkZW1wb3RlbnQuXHJcbiAgICAgICAgICAgIGxldCBtYXhUcmllcyA9ICh0aGlzLl9hbGxvd1JldHJpZXMgJiYgUmV0cnlhYmxlSHR0cFZlcmJzLmluZGV4T2YodmVyYikgIT0gLTEpID8gdGhpcy5fbWF4UmV0cmllcyArIDEgOiAxO1xyXG4gICAgICAgICAgICBsZXQgbnVtVHJpZXMgPSAwO1xyXG4gICAgICAgICAgICBsZXQgcmVzcG9uc2U7XHJcbiAgICAgICAgICAgIHdoaWxlIChudW1UcmllcyA8IG1heFRyaWVzKSB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0geWllbGQgdGhpcy5yZXF1ZXN0UmF3KGluZm8sIGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgIG51bVRyaWVzKys7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVyciAmJiBlcnIuY29kZSAmJiBOZXR3b3JrUmV0cnlFcnJvcnMuaW5kZXhPZihlcnIuY29kZSkgPiAtMSAmJiBudW1UcmllcyA8IG1heFRyaWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHlpZWxkIHRoaXMuX3BlcmZvcm1FeHBvbmVudGlhbEJhY2tvZmYobnVtVHJpZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhbiBhdXRoZW50aWNhdGlvbiBjaGFsbGVuZ2VcclxuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5tZXNzYWdlICYmIHJlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZSA9PT0gSHR0cENvZGVzLlVuYXV0aG9yaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBhdXRoZW50aWNhdGlvbkhhbmRsZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmhhbmRsZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhbmRsZXJzW2ldLmNhbkhhbmRsZUF1dGhlbnRpY2F0aW9uKHJlc3BvbnNlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0aGVudGljYXRpb25IYW5kbGVyID0gdGhpcy5oYW5kbGVyc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdXRoZW50aWNhdGlvbkhhbmRsZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF1dGhlbnRpY2F0aW9uSGFuZGxlci5oYW5kbGVBdXRoZW50aWNhdGlvbih0aGlzLCBpbmZvLCBkYXRhKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgcmVjZWl2ZWQgYW4gdW5hdXRob3JpemVkIHJlc3BvbnNlIGJ1dCBoYXZlIG5vIGhhbmRsZXJzIHRvIGhhbmRsZSBpdC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGV0IHRoZSByZXNwb25zZSByZXR1cm4gdG8gdGhlIGNhbGxlci5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxldCByZWRpcmVjdHNSZW1haW5pbmcgPSB0aGlzLl9tYXhSZWRpcmVjdHM7XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoSHR0cFJlZGlyZWN0Q29kZXMuaW5kZXhPZihyZXNwb25zZS5tZXNzYWdlLnN0YXR1c0NvZGUpICE9IC0xXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5fYWxsb3dSZWRpcmVjdHNcclxuICAgICAgICAgICAgICAgICAgICAmJiByZWRpcmVjdHNSZW1haW5pbmcgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVkaXJlY3RVcmwgPSByZXNwb25zZS5tZXNzYWdlLmhlYWRlcnNbXCJsb2NhdGlvblwiXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXJlZGlyZWN0VXJsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlJ3Mgbm8gbG9jYXRpb24gdG8gcmVkaXJlY3QgdG8sIHdlIHdvbid0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBsZXQgcGFyc2VkUmVkaXJlY3RVcmwgPSB1cmwucGFyc2UocmVkaXJlY3RVcmwpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZWRVcmwucHJvdG9jb2wgPT0gJ2h0dHBzOicgJiYgcGFyc2VkVXJsLnByb3RvY29sICE9IHBhcnNlZFJlZGlyZWN0VXJsLnByb3RvY29sICYmICF0aGlzLl9hbGxvd1JlZGlyZWN0RG93bmdyYWRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlZGlyZWN0IGZyb20gSFRUUFMgdG8gSFRUUCBwcm90b2NvbC4gVGhpcyBkb3duZ3JhZGUgaXMgbm90IGFsbG93ZWQgZm9yIHNlY3VyaXR5IHJlYXNvbnMuIElmIHlvdSB3YW50IHRvIGFsbG93IHRoaXMgYmVoYXZpb3IsIHNldCB0aGUgYWxsb3dSZWRpcmVjdERvd25ncmFkZSBvcHRpb24gdG8gdHJ1ZS5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gZmluaXNoIHJlYWRpbmcgdGhlIHJlc3BvbnNlIGJlZm9yZSByZWFzc2lnbmluZyByZXNwb25zZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHdoaWNoIHdpbGwgbGVhayB0aGUgb3BlbiBzb2NrZXQuXHJcbiAgICAgICAgICAgICAgICAgICAgeWllbGQgcmVzcG9uc2UucmVhZEJvZHkoKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBsZXQncyBtYWtlIHRoZSByZXF1ZXN0IHdpdGggdGhlIG5ldyByZWRpcmVjdFVybFxyXG4gICAgICAgICAgICAgICAgICAgIGluZm8gPSB0aGlzLl9wcmVwYXJlUmVxdWVzdCh2ZXJiLCBwYXJzZWRSZWRpcmVjdFVybCwgaGVhZGVycyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSB5aWVsZCB0aGlzLnJlcXVlc3RSYXcoaW5mbywgZGF0YSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3RzUmVtYWluaW5nLS07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoSHR0cFJlc3BvbnNlUmV0cnlDb2Rlcy5pbmRleE9mKHJlc3BvbnNlLm1lc3NhZ2Uuc3RhdHVzQ29kZSkgPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBJZiBub3QgYSByZXRyeSBjb2RlLCByZXR1cm4gaW1tZWRpYXRlbHkgaW5zdGVhZCBvZiByZXRyeWluZ1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG51bVRyaWVzICs9IDE7XHJcbiAgICAgICAgICAgICAgICBpZiAobnVtVHJpZXMgPCBtYXhUcmllcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIHJlc3BvbnNlLnJlYWRCb2R5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgeWllbGQgdGhpcy5fcGVyZm9ybUV4cG9uZW50aWFsQmFja29mZihudW1Ucmllcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBOZWVkcyB0byBiZSBjYWxsZWQgaWYga2VlcEFsaXZlIGlzIHNldCB0byB0cnVlIGluIHJlcXVlc3Qgb3B0aW9ucy5cclxuICAgICAqL1xyXG4gICAgZGlzcG9zZSgpIHtcclxuICAgICAgICBpZiAodGhpcy5fYWdlbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5fYWdlbnQuZGVzdHJveSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9kaXNwb3NlZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFJhdyByZXF1ZXN0LlxyXG4gICAgICogQHBhcmFtIGluZm9cclxuICAgICAqIEBwYXJhbSBkYXRhXHJcbiAgICAgKi9cclxuICAgIHJlcXVlc3RSYXcoaW5mbywgZGF0YSkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBjYWxsYmFja0ZvclJlc3VsdCA9IGZ1bmN0aW9uIChlcnIsIHJlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB0aGlzLnJlcXVlc3RSYXdXaXRoQ2FsbGJhY2soaW5mbywgZGF0YSwgY2FsbGJhY2tGb3JSZXN1bHQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBSYXcgcmVxdWVzdCB3aXRoIGNhbGxiYWNrLlxyXG4gICAgICogQHBhcmFtIGluZm9cclxuICAgICAqIEBwYXJhbSBkYXRhXHJcbiAgICAgKiBAcGFyYW0gb25SZXN1bHRcclxuICAgICAqL1xyXG4gICAgcmVxdWVzdFJhd1dpdGhDYWxsYmFjayhpbmZvLCBkYXRhLCBvblJlc3VsdCkge1xyXG4gICAgICAgIGxldCBzb2NrZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiAoZGF0YSkgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIGluZm8ub3B0aW9ucy5oZWFkZXJzW1wiQ29udGVudC1MZW5ndGhcIl0gPSBCdWZmZXIuYnl0ZUxlbmd0aChkYXRhLCAndXRmOCcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgY2FsbGJhY2tDYWxsZWQgPSBmYWxzZTtcclxuICAgICAgICBsZXQgaGFuZGxlUmVzdWx0ID0gKGVyciwgcmVzKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghY2FsbGJhY2tDYWxsZWQpIHtcclxuICAgICAgICAgICAgICAgIGNhbGxiYWNrQ2FsbGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIG9uUmVzdWx0KGVyciwgcmVzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgbGV0IHJlcSA9IGluZm8uaHR0cE1vZHVsZS5yZXF1ZXN0KGluZm8ub3B0aW9ucywgKG1zZykgPT4ge1xyXG4gICAgICAgICAgICBsZXQgcmVzID0gbmV3IEh0dHBDbGllbnRSZXNwb25zZShtc2cpO1xyXG4gICAgICAgICAgICBoYW5kbGVSZXN1bHQobnVsbCwgcmVzKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXEub24oJ3NvY2tldCcsIChzb2NrKSA9PiB7XHJcbiAgICAgICAgICAgIHNvY2tldCA9IHNvY2s7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gSWYgd2UgZXZlciBnZXQgZGlzY29ubmVjdGVkLCB3ZSB3YW50IHRoZSBzb2NrZXQgdG8gdGltZW91dCBldmVudHVhbGx5XHJcbiAgICAgICAgcmVxLnNldFRpbWVvdXQodGhpcy5fc29ja2V0VGltZW91dCB8fCAzICogNjAwMDAsICgpID0+IHtcclxuICAgICAgICAgICAgaWYgKHNvY2tldCkge1xyXG4gICAgICAgICAgICAgICAgc29ja2V0LmRlc3Ryb3koKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBoYW5kbGVSZXN1bHQobmV3IEVycm9yKCdSZXF1ZXN0IHRpbWVvdXQ6ICcgKyBpbmZvLm9wdGlvbnMucGF0aCksIG51bGwpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgIC8vIGVyciBoYXMgc3RhdHVzQ29kZSBwcm9wZXJ0eVxyXG4gICAgICAgICAgICAvLyByZXMgc2hvdWxkIGhhdmUgaGVhZGVyc1xyXG4gICAgICAgICAgICBoYW5kbGVSZXN1bHQoZXJyLCBudWxsKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAoZGF0YSAmJiB0eXBlb2YgKGRhdGEpID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICByZXEud3JpdGUoZGF0YSwgJ3V0ZjgnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGRhdGEgJiYgdHlwZW9mIChkYXRhKSAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgZGF0YS5vbignY2xvc2UnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXEuZW5kKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBkYXRhLnBpcGUocmVxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJlcS5lbmQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBfcHJlcGFyZVJlcXVlc3QobWV0aG9kLCByZXF1ZXN0VXJsLCBoZWFkZXJzKSB7XHJcbiAgICAgICAgY29uc3QgaW5mbyA9IHt9O1xyXG4gICAgICAgIGluZm8ucGFyc2VkVXJsID0gcmVxdWVzdFVybDtcclxuICAgICAgICBjb25zdCB1c2luZ1NzbCA9IGluZm8ucGFyc2VkVXJsLnByb3RvY29sID09PSAnaHR0cHM6JztcclxuICAgICAgICBpbmZvLmh0dHBNb2R1bGUgPSB1c2luZ1NzbCA/IGh0dHBzIDogaHR0cDtcclxuICAgICAgICBjb25zdCBkZWZhdWx0UG9ydCA9IHVzaW5nU3NsID8gNDQzIDogODA7XHJcbiAgICAgICAgaW5mby5vcHRpb25zID0ge307XHJcbiAgICAgICAgaW5mby5vcHRpb25zLmhvc3QgPSBpbmZvLnBhcnNlZFVybC5ob3N0bmFtZTtcclxuICAgICAgICBpbmZvLm9wdGlvbnMucG9ydCA9IGluZm8ucGFyc2VkVXJsLnBvcnQgPyBwYXJzZUludChpbmZvLnBhcnNlZFVybC5wb3J0KSA6IGRlZmF1bHRQb3J0O1xyXG4gICAgICAgIGluZm8ub3B0aW9ucy5wYXRoID0gKGluZm8ucGFyc2VkVXJsLnBhdGhuYW1lIHx8ICcnKSArIChpbmZvLnBhcnNlZFVybC5zZWFyY2ggfHwgJycpO1xyXG4gICAgICAgIGluZm8ub3B0aW9ucy5tZXRob2QgPSBtZXRob2Q7XHJcbiAgICAgICAgaW5mby5vcHRpb25zLnRpbWVvdXQgPSAodGhpcy5yZXF1ZXN0T3B0aW9ucyAmJiB0aGlzLnJlcXVlc3RPcHRpb25zLnNvY2tldFRpbWVvdXQpIHx8IHRoaXMuX3NvY2tldFRpbWVvdXQ7XHJcbiAgICAgICAgdGhpcy5fc29ja2V0VGltZW91dCA9IGluZm8ub3B0aW9ucy50aW1lb3V0O1xyXG4gICAgICAgIGluZm8ub3B0aW9ucy5oZWFkZXJzID0gdGhpcy5fbWVyZ2VIZWFkZXJzKGhlYWRlcnMpO1xyXG4gICAgICAgIGlmICh0aGlzLnVzZXJBZ2VudCAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIGluZm8ub3B0aW9ucy5oZWFkZXJzW1widXNlci1hZ2VudFwiXSA9IHRoaXMudXNlckFnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpbmZvLm9wdGlvbnMuYWdlbnQgPSB0aGlzLl9nZXRBZ2VudChpbmZvLnBhcnNlZFVybCk7XHJcbiAgICAgICAgLy8gZ2l2ZXMgaGFuZGxlcnMgYW4gb3Bwb3J0dW5pdHkgdG8gcGFydGljaXBhdGVcclxuICAgICAgICBpZiAodGhpcy5oYW5kbGVycyAmJiAhdGhpcy5faXNQcmVzaWduZWQodXJsLmZvcm1hdChyZXF1ZXN0VXJsKSkpIHtcclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVycy5mb3JFYWNoKChoYW5kbGVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBoYW5kbGVyLnByZXBhcmVSZXF1ZXN0KGluZm8ub3B0aW9ucyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaW5mbztcclxuICAgIH1cclxuICAgIF9pc1ByZXNpZ25lZChyZXF1ZXN0VXJsKSB7XHJcbiAgICAgICAgaWYgKHRoaXMucmVxdWVzdE9wdGlvbnMgJiYgdGhpcy5yZXF1ZXN0T3B0aW9ucy5wcmVzaWduZWRVcmxQYXR0ZXJucykge1xyXG4gICAgICAgICAgICBjb25zdCBwYXR0ZXJucyA9IHRoaXMucmVxdWVzdE9wdGlvbnMucHJlc2lnbmVkVXJsUGF0dGVybnM7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0dGVybnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0VXJsLm1hdGNoKHBhdHRlcm5zW2ldKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIF9tZXJnZUhlYWRlcnMoaGVhZGVycykge1xyXG4gICAgICAgIGNvbnN0IGxvd2VyY2FzZUtleXMgPSBvYmogPT4gT2JqZWN0LmtleXMob2JqKS5yZWR1Y2UoKGMsIGspID0+IChjW2sudG9Mb3dlckNhc2UoKV0gPSBvYmpba10sIGMpLCB7fSk7XHJcbiAgICAgICAgaWYgKHRoaXMucmVxdWVzdE9wdGlvbnMgJiYgdGhpcy5yZXF1ZXN0T3B0aW9ucy5oZWFkZXJzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBsb3dlcmNhc2VLZXlzKHRoaXMucmVxdWVzdE9wdGlvbnMuaGVhZGVycyksIGxvd2VyY2FzZUtleXMoaGVhZGVycykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbG93ZXJjYXNlS2V5cyhoZWFkZXJzIHx8IHt9KTtcclxuICAgIH1cclxuICAgIF9nZXRBZ2VudChwYXJzZWRVcmwpIHtcclxuICAgICAgICBsZXQgYWdlbnQ7XHJcbiAgICAgICAgbGV0IHByb3h5ID0gdGhpcy5fZ2V0UHJveHkocGFyc2VkVXJsKTtcclxuICAgICAgICBsZXQgdXNlUHJveHkgPSBwcm94eS5wcm94eVVybCAmJiBwcm94eS5wcm94eVVybC5ob3N0bmFtZSAmJiAhdGhpcy5faXNNYXRjaEluQnlwYXNzUHJveHlMaXN0KHBhcnNlZFVybCk7XHJcbiAgICAgICAgaWYgKHRoaXMuX2tlZXBBbGl2ZSAmJiB1c2VQcm94eSkge1xyXG4gICAgICAgICAgICBhZ2VudCA9IHRoaXMuX3Byb3h5QWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9rZWVwQWxpdmUgJiYgIXVzZVByb3h5KSB7XHJcbiAgICAgICAgICAgIGFnZW50ID0gdGhpcy5fYWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIGFnZW50IGlzIGFscmVhZHkgYXNzaWduZWQgdXNlIHRoYXQgYWdlbnQuXHJcbiAgICAgICAgaWYgKCEhYWdlbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCB1c2luZ1NzbCA9IHBhcnNlZFVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XHJcbiAgICAgICAgbGV0IG1heFNvY2tldHMgPSAxMDA7XHJcbiAgICAgICAgaWYgKCEhdGhpcy5yZXF1ZXN0T3B0aW9ucykge1xyXG4gICAgICAgICAgICBtYXhTb2NrZXRzID0gdGhpcy5yZXF1ZXN0T3B0aW9ucy5tYXhTb2NrZXRzIHx8IGh0dHAuZ2xvYmFsQWdlbnQubWF4U29ja2V0cztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHVzZVByb3h5KSB7XHJcbiAgICAgICAgICAgIC8vIElmIHVzaW5nIHByb3h5LCBuZWVkIHR1bm5lbFxyXG4gICAgICAgICAgICBpZiAoIXR1bm5lbCkge1xyXG4gICAgICAgICAgICAgICAgdHVubmVsID0gcmVxdWlyZSgndHVubmVsJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgYWdlbnRPcHRpb25zID0ge1xyXG4gICAgICAgICAgICAgICAgbWF4U29ja2V0czogbWF4U29ja2V0cyxcclxuICAgICAgICAgICAgICAgIGtlZXBBbGl2ZTogdGhpcy5fa2VlcEFsaXZlLFxyXG4gICAgICAgICAgICAgICAgcHJveHk6IHtcclxuICAgICAgICAgICAgICAgICAgICBwcm94eUF1dGg6IHByb3h5LnByb3h5QXV0aCxcclxuICAgICAgICAgICAgICAgICAgICBob3N0OiBwcm94eS5wcm94eVVybC5ob3N0bmFtZSxcclxuICAgICAgICAgICAgICAgICAgICBwb3J0OiBwcm94eS5wcm94eVVybC5wb3J0XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBsZXQgdHVubmVsQWdlbnQ7XHJcbiAgICAgICAgICAgIGNvbnN0IG92ZXJIdHRwcyA9IHByb3h5LnByb3h5VXJsLnByb3RvY29sID09PSAnaHR0cHM6JztcclxuICAgICAgICAgICAgaWYgKHVzaW5nU3NsKSB7XHJcbiAgICAgICAgICAgICAgICB0dW5uZWxBZ2VudCA9IG92ZXJIdHRwcyA/IHR1bm5lbC5odHRwc092ZXJIdHRwcyA6IHR1bm5lbC5odHRwc092ZXJIdHRwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdHVubmVsQWdlbnQgPSBvdmVySHR0cHMgPyB0dW5uZWwuaHR0cE92ZXJIdHRwcyA6IHR1bm5lbC5odHRwT3Zlckh0dHA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYWdlbnQgPSB0dW5uZWxBZ2VudChhZ2VudE9wdGlvbnMpO1xyXG4gICAgICAgICAgICB0aGlzLl9wcm94eUFnZW50ID0gYWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIHJldXNpbmcgYWdlbnQgYWNyb3NzIHJlcXVlc3QgYW5kIHR1bm5lbGluZyBhZ2VudCBpc24ndCBhc3NpZ25lZCBjcmVhdGUgYSBuZXcgYWdlbnRcclxuICAgICAgICBpZiAodGhpcy5fa2VlcEFsaXZlICYmICFhZ2VudCkge1xyXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zID0geyBrZWVwQWxpdmU6IHRoaXMuX2tlZXBBbGl2ZSwgbWF4U29ja2V0czogbWF4U29ja2V0cyB9O1xyXG4gICAgICAgICAgICBhZ2VudCA9IHVzaW5nU3NsID8gbmV3IGh0dHBzLkFnZW50KG9wdGlvbnMpIDogbmV3IGh0dHAuQWdlbnQob3B0aW9ucyk7XHJcbiAgICAgICAgICAgIHRoaXMuX2FnZW50ID0gYWdlbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmIG5vdCB1c2luZyBwcml2YXRlIGFnZW50IGFuZCB0dW5uZWwgYWdlbnQgaXNuJ3Qgc2V0dXAgdGhlbiB1c2UgZ2xvYmFsIGFnZW50XHJcbiAgICAgICAgaWYgKCFhZ2VudCkge1xyXG4gICAgICAgICAgICBhZ2VudCA9IHVzaW5nU3NsID8gaHR0cHMuZ2xvYmFsQWdlbnQgOiBodHRwLmdsb2JhbEFnZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodXNpbmdTc2wgJiYgdGhpcy5faWdub3JlU3NsRXJyb3IpIHtcclxuICAgICAgICAgICAgLy8gd2UgZG9uJ3Qgd2FudCB0byBzZXQgTk9ERV9UTFNfUkVKRUNUX1VOQVVUSE9SSVpFRD0wIHNpbmNlIHRoYXQgd2lsbCBhZmZlY3QgcmVxdWVzdCBmb3IgZW50aXJlIHByb2Nlc3NcclxuICAgICAgICAgICAgLy8gaHR0cC5SZXF1ZXN0T3B0aW9ucyBkb2Vzbid0IGV4cG9zZSBhIHdheSB0byBtb2RpZnkgUmVxdWVzdE9wdGlvbnMuYWdlbnQub3B0aW9uc1xyXG4gICAgICAgICAgICAvLyB3ZSBoYXZlIHRvIGNhc3QgaXQgdG8gYW55IGFuZCBjaGFuZ2UgaXQgZGlyZWN0bHlcclxuICAgICAgICAgICAgYWdlbnQub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oYWdlbnQub3B0aW9ucyB8fCB7fSwgeyByZWplY3RVbmF1dGhvcml6ZWQ6IGZhbHNlIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodXNpbmdTc2wgJiYgdGhpcy5fY2VydENvbmZpZykge1xyXG4gICAgICAgICAgICBhZ2VudC5vcHRpb25zID0gT2JqZWN0LmFzc2lnbihhZ2VudC5vcHRpb25zIHx8IHt9LCB7IGNhOiB0aGlzLl9jYSwgY2VydDogdGhpcy5fY2VydCwga2V5OiB0aGlzLl9rZXksIHBhc3NwaHJhc2U6IHRoaXMuX2NlcnRDb25maWcucGFzc3BocmFzZSB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFnZW50O1xyXG4gICAgfVxyXG4gICAgX2dldFByb3h5KHBhcnNlZFVybCkge1xyXG4gICAgICAgIGxldCB1c2luZ1NzbCA9IHBhcnNlZFVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOic7XHJcbiAgICAgICAgbGV0IHByb3h5Q29uZmlnID0gdGhpcy5faHR0cFByb3h5O1xyXG4gICAgICAgIC8vIGZhbGxiYWNrIHRvIGh0dHBfcHJveHkgYW5kIGh0dHBzX3Byb3h5IGVudlxyXG4gICAgICAgIGxldCBodHRwc19wcm94eSA9IHByb2Nlc3MuZW52W0Vudmlyb25tZW50VmFyaWFibGVzLkhUVFBTX1BST1hZXTtcclxuICAgICAgICBsZXQgaHR0cF9wcm94eSA9IHByb2Nlc3MuZW52W0Vudmlyb25tZW50VmFyaWFibGVzLkhUVFBfUFJPWFldO1xyXG4gICAgICAgIGlmICghcHJveHlDb25maWcpIHtcclxuICAgICAgICAgICAgaWYgKGh0dHBzX3Byb3h5ICYmIHVzaW5nU3NsKSB7XHJcbiAgICAgICAgICAgICAgICBwcm94eUNvbmZpZyA9IHtcclxuICAgICAgICAgICAgICAgICAgICBwcm94eVVybDogaHR0cHNfcHJveHlcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoaHR0cF9wcm94eSkge1xyXG4gICAgICAgICAgICAgICAgcHJveHlDb25maWcgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJveHlVcmw6IGh0dHBfcHJveHlcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IHByb3h5VXJsO1xyXG4gICAgICAgIGxldCBwcm94eUF1dGg7XHJcbiAgICAgICAgaWYgKHByb3h5Q29uZmlnKSB7XHJcbiAgICAgICAgICAgIGlmIChwcm94eUNvbmZpZy5wcm94eVVybC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBwcm94eVVybCA9IHVybC5wYXJzZShwcm94eUNvbmZpZy5wcm94eVVybCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHByb3h5Q29uZmlnLnByb3h5VXNlcm5hbWUgfHwgcHJveHlDb25maWcucHJveHlQYXNzd29yZCkge1xyXG4gICAgICAgICAgICAgICAgcHJveHlBdXRoID0gcHJveHlDb25maWcucHJveHlVc2VybmFtZSArIFwiOlwiICsgcHJveHlDb25maWcucHJveHlQYXNzd29yZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4geyBwcm94eVVybDogcHJveHlVcmwsIHByb3h5QXV0aDogcHJveHlBdXRoIH07XHJcbiAgICB9XHJcbiAgICBfaXNNYXRjaEluQnlwYXNzUHJveHlMaXN0KHBhcnNlZFVybCkge1xyXG4gICAgICAgIGlmICghdGhpcy5faHR0cFByb3h5QnlwYXNzSG9zdHMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgYnlwYXNzID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5faHR0cFByb3h5QnlwYXNzSG9zdHMuZm9yRWFjaChieXBhc3NIb3N0ID0+IHtcclxuICAgICAgICAgICAgaWYgKGJ5cGFzc0hvc3QudGVzdChwYXJzZWRVcmwuaHJlZikpIHtcclxuICAgICAgICAgICAgICAgIGJ5cGFzcyA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gYnlwYXNzO1xyXG4gICAgfVxyXG4gICAgX3BlcmZvcm1FeHBvbmVudGlhbEJhY2tvZmYocmV0cnlOdW1iZXIpIHtcclxuICAgICAgICByZXRyeU51bWJlciA9IE1hdGgubWluKEV4cG9uZW50aWFsQmFja29mZkNlaWxpbmcsIHJldHJ5TnVtYmVyKTtcclxuICAgICAgICBjb25zdCBtcyA9IEV4cG9uZW50aWFsQmFja29mZlRpbWVTbGljZSAqIE1hdGgucG93KDIsIHJldHJ5TnVtYmVyKTtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KCgpID0+IHJlc29sdmUoKSwgbXMpKTtcclxuICAgIH1cclxufVxyXG5leHBvcnRzLkh0dHBDbGllbnQgPSBIdHRwQ2xpZW50O1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4gU2VlIExJQ0VOU0UgZmlsZSBpbiB0aGUgcHJvamVjdCByb290IGZvciBmdWxsIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbnZhciBfX2F3YWl0ZXIgPSAodGhpcyAmJiB0aGlzLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZShyZXN1bHQudmFsdWUpOyB9KS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn07XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuY29uc3QgcXMgPSByZXF1aXJlKFwicXNcIik7XHJcbmNvbnN0IHVybCA9IHJlcXVpcmUoXCJ1cmxcIik7XHJcbmNvbnN0IHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcclxuY29uc3QgemxpYiA9IHJlcXVpcmUoXCJ6bGliXCIpO1xyXG4vKipcclxuICogY3JlYXRlcyBhbiB1cmwgZnJvbSBhIHJlcXVlc3QgdXJsIGFuZCBvcHRpb25hbCBiYXNlIHVybCAoaHR0cDovL3NlcnZlcjo4MDgwKVxyXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVzb3VyY2UgLSBhIGZ1bGx5IHF1YWxpZmllZCB1cmwgb3IgcmVsYXRpdmUgcGF0aFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gYmFzZVVybCAtIGFuIG9wdGlvbmFsIGJhc2VVcmwgKGh0dHA6Ly9zZXJ2ZXI6ODA4MClcclxuICogQHBhcmFtIHtJUmVxdWVzdE9wdGlvbnN9IG9wdGlvbnMgLSBhbiBvcHRpb25hbCBvcHRpb25zIG9iamVjdCwgY291bGQgaW5jbHVkZSBRdWVyeVBhcmFtZXRlcnMgZS5nLlxyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IC0gcmVzdWx0YW50IHVybFxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VXJsKHJlc291cmNlLCBiYXNlVXJsLCBxdWVyeVBhcmFtcykge1xyXG4gICAgY29uc3QgcGF0aEFwaSA9IHBhdGgucG9zaXggfHwgcGF0aDtcclxuICAgIGxldCByZXF1ZXN0VXJsID0gJyc7XHJcbiAgICBpZiAoIWJhc2VVcmwpIHtcclxuICAgICAgICByZXF1ZXN0VXJsID0gcmVzb3VyY2U7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICghcmVzb3VyY2UpIHtcclxuICAgICAgICByZXF1ZXN0VXJsID0gYmFzZVVybDtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IGJhc2UgPSB1cmwucGFyc2UoYmFzZVVybCk7XHJcbiAgICAgICAgY29uc3QgcmVzdWx0YW50VXJsID0gdXJsLnBhcnNlKHJlc291cmNlKTtcclxuICAgICAgICAvLyByZXNvdXJjZSAoc3BlY2lmaWMgcGVyIHJlcXVlc3QpIGVsZW1lbnRzIHRha2UgcHJpb3JpdHlcclxuICAgICAgICByZXN1bHRhbnRVcmwucHJvdG9jb2wgPSByZXN1bHRhbnRVcmwucHJvdG9jb2wgfHwgYmFzZS5wcm90b2NvbDtcclxuICAgICAgICByZXN1bHRhbnRVcmwuYXV0aCA9IHJlc3VsdGFudFVybC5hdXRoIHx8IGJhc2UuYXV0aDtcclxuICAgICAgICByZXN1bHRhbnRVcmwuaG9zdCA9IHJlc3VsdGFudFVybC5ob3N0IHx8IGJhc2UuaG9zdDtcclxuICAgICAgICByZXN1bHRhbnRVcmwucGF0aG5hbWUgPSBwYXRoQXBpLnJlc29sdmUoYmFzZS5wYXRobmFtZSwgcmVzdWx0YW50VXJsLnBhdGhuYW1lKTtcclxuICAgICAgICBpZiAoIXJlc3VsdGFudFVybC5wYXRobmFtZS5lbmRzV2l0aCgnLycpICYmIHJlc291cmNlLmVuZHNXaXRoKCcvJykpIHtcclxuICAgICAgICAgICAgcmVzdWx0YW50VXJsLnBhdGhuYW1lICs9ICcvJztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmVxdWVzdFVybCA9IHVybC5mb3JtYXQocmVzdWx0YW50VXJsKTtcclxuICAgIH1cclxuICAgIHJldHVybiBxdWVyeVBhcmFtcyA/XHJcbiAgICAgICAgZ2V0VXJsV2l0aFBhcnNlZFF1ZXJ5UGFyYW1zKHJlcXVlc3RVcmwsIHF1ZXJ5UGFyYW1zKSA6XHJcbiAgICAgICAgcmVxdWVzdFVybDtcclxufVxyXG5leHBvcnRzLmdldFVybCA9IGdldFVybDtcclxuLyoqXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSByZXF1ZXN0VXJsXHJcbiAqIEBwYXJhbSB7SVJlcXVlc3RRdWVyeVBhcmFtc30gcXVlcnlQYXJhbXNcclxuICogQHJldHVybiB7c3RyaW5nfSAtIFJlcXVlc3QncyBVUkwgd2l0aCBRdWVyeSBQYXJhbWV0ZXJzIGFwcGVuZGVkL3BhcnNlZC5cclxuICovXHJcbmZ1bmN0aW9uIGdldFVybFdpdGhQYXJzZWRRdWVyeVBhcmFtcyhyZXF1ZXN0VXJsLCBxdWVyeVBhcmFtcykge1xyXG4gICAgY29uc3QgdXJsID0gcmVxdWVzdFVybC5yZXBsYWNlKC9cXD8kL2csICcnKTsgLy8gQ2xlYW4gYW55IGV4dHJhIGVuZC1vZi1zdHJpbmcgXCI/XCIgY2hhcmFjdGVyXHJcbiAgICBjb25zdCBwYXJzZWRRdWVyeVBhcmFtcyA9IHFzLnN0cmluZ2lmeShxdWVyeVBhcmFtcy5wYXJhbXMsIGJ1aWxkUGFyYW1zU3RyaW5naWZ5T3B0aW9ucyhxdWVyeVBhcmFtcykpO1xyXG4gICAgcmV0dXJuIGAke3VybH0ke3BhcnNlZFF1ZXJ5UGFyYW1zfWA7XHJcbn1cclxuLyoqXHJcbiAqIEJ1aWxkIG9wdGlvbnMgZm9yIFF1ZXJ5UGFyYW1zIFN0cmluZ2lmeWluZy5cclxuICpcclxuICogQHBhcmFtIHtJUmVxdWVzdFF1ZXJ5UGFyYW1zfSBxdWVyeVBhcmFtc1xyXG4gKiBAcmV0dXJuIHtvYmplY3R9XHJcbiAqL1xyXG5mdW5jdGlvbiBidWlsZFBhcmFtc1N0cmluZ2lmeU9wdGlvbnMocXVlcnlQYXJhbXMpIHtcclxuICAgIGxldCBvcHRpb25zID0ge1xyXG4gICAgICAgIGFkZFF1ZXJ5UHJlZml4OiB0cnVlLFxyXG4gICAgICAgIGRlbGltaXRlcjogKHF1ZXJ5UGFyYW1zLm9wdGlvbnMgfHwge30pLnNlcGFyYXRvciB8fCAnJicsXHJcbiAgICAgICAgYWxsb3dEb3RzOiAocXVlcnlQYXJhbXMub3B0aW9ucyB8fCB7fSkuc2hvdWxkQWxsb3dEb3RzIHx8IGZhbHNlLFxyXG4gICAgICAgIGFycmF5Rm9ybWF0OiAocXVlcnlQYXJhbXMub3B0aW9ucyB8fCB7fSkuYXJyYXlGb3JtYXQgfHwgJ3JlcGVhdCcsXHJcbiAgICAgICAgZW5jb2RlVmFsdWVzT25seTogKHF1ZXJ5UGFyYW1zLm9wdGlvbnMgfHwge30pLnNob3VsZE9ubHlFbmNvZGVWYWx1ZXMgfHwgdHJ1ZVxyXG4gICAgfTtcclxuICAgIHJldHVybiBvcHRpb25zO1xyXG59XHJcbi8qKlxyXG4gKiBEZWNvbXByZXNzL0RlY29kZSBnemlwIGVuY29kZWQgSlNPTlxyXG4gKiBVc2luZyBOb2RlLmpzIGJ1aWx0LWluIHpsaWIgbW9kdWxlXHJcbiAqXHJcbiAqIEBwYXJhbSB7QnVmZmVyfSBidWZmZXJcclxuICogQHBhcmFtIHtzdHJpbmd9IGNoYXJzZXQ/IC0gb3B0aW9uYWw7IGRlZmF1bHRzIHRvICd1dGYtOCdcclxuICogQHJldHVybiB7UHJvbWlzZTxzdHJpbmc+fVxyXG4gKi9cclxuZnVuY3Rpb24gZGVjb21wcmVzc0d6aXBwZWRDb250ZW50KGJ1ZmZlciwgY2hhcnNldCkge1xyXG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xyXG4gICAgICAgICAgICB6bGliLmd1bnppcChidWZmZXIsIGZ1bmN0aW9uIChlcnJvciwgYnVmZmVyKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShidWZmZXIudG9TdHJpbmcoY2hhcnNldCB8fCAndXRmLTgnKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pKTtcclxuICAgIH0pO1xyXG59XHJcbmV4cG9ydHMuZGVjb21wcmVzc0d6aXBwZWRDb250ZW50ID0gZGVjb21wcmVzc0d6aXBwZWRDb250ZW50O1xyXG4vKipcclxuICogQnVpbGRzIGEgUmVnRXhwIHRvIHRlc3QgdXJscyBhZ2FpbnN0IGZvciBkZWNpZGluZ1xyXG4gKiB3ZXRoZXIgdG8gYnlwYXNzIHByb3h5IGZyb20gYW4gZW50cnkgb2YgdGhlXHJcbiAqIGVudmlyb25tZW50IHZhcmlhYmxlIHNldHRpbmcgTk9fUFJPWFlcclxuICpcclxuICogQHBhcmFtIHtzdHJpbmd9IGJ5cGFzc1xyXG4gKiBAcmV0dXJuIHtSZWdFeHB9XHJcbiAqL1xyXG5mdW5jdGlvbiBidWlsZFByb3h5QnlwYXNzUmVnZXhGcm9tRW52KGJ5cGFzcykge1xyXG4gICAgdHJ5IHtcclxuICAgICAgICAvLyBXZSBuZWVkIHRvIGtlZXAgdGhpcyBhcm91bmQgZm9yIGJhY2stY29tcGF0IHB1cnBvc2VzXHJcbiAgICAgICAgcmV0dXJuIG5ldyBSZWdFeHAoYnlwYXNzLCAnaScpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBTeW50YXhFcnJvciAmJiAoYnlwYXNzIHx8IFwiXCIpLnN0YXJ0c1dpdGgoXCIqXCIpKSB7XHJcbiAgICAgICAgICAgIGxldCB3aWxkY2FyZEVzY2FwZWQgPSBieXBhc3MucmVwbGFjZSgnKicsICcoLiopJyk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVnRXhwKHdpbGRjYXJkRXNjYXBlZCwgJ2knKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgfVxyXG59XHJcbmV4cG9ydHMuYnVpbGRQcm94eUJ5cGFzc1JlZ2V4RnJvbUVudiA9IGJ1aWxkUHJveHlCeXBhc3NSZWdleEZyb21FbnY7XHJcbi8qKlxyXG4gKiBPYnRhaW4gUmVzcG9uc2UncyBDb250ZW50IENoYXJzZXQuXHJcbiAqIFRocm91Z2ggaW5zcGVjdGluZyBgY29udGVudC10eXBlYCByZXNwb25zZSBoZWFkZXIuXHJcbiAqIEl0IFJldHVybnMgJ3V0Zi04JyBpZiBOTyBjaGFyc2V0IHNwZWNpZmllZC9tYXRjaGVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0lIdHRwQ2xpZW50UmVzcG9uc2V9IHJlc3BvbnNlXHJcbiAqIEByZXR1cm4ge3N0cmluZ30gLSBDb250ZW50IEVuY29kaW5nIENoYXJzZXQ7IERlZmF1bHQ9dXRmLThcclxuICovXHJcbmZ1bmN0aW9uIG9idGFpbkNvbnRlbnRDaGFyc2V0KHJlc3BvbnNlKSB7XHJcbiAgICAvLyBGaW5kIHRoZSBjaGFyc2V0LCBpZiBzcGVjaWZpZWQuXHJcbiAgICAvLyBTZWFyY2ggZm9yIHRoZSBgY2hhcnNldD1DSEFSU0VUYCBzdHJpbmcsIG5vdCBpbmNsdWRpbmcgYDssXFxyXFxuYFxyXG4gICAgLy8gRXhhbXBsZTogY29udGVudC10eXBlOiAnYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04J1xyXG4gICAgLy8gfF9fIG1hdGNoZXMgd291bGQgYmUgWydjaGFyc2V0PXV0Zi04JywgJ3V0Zi04JywgaW5kZXg6IDE4LCBpbnB1dDogJ2FwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLTgnXVxyXG4gICAgLy8gfF9fX19fIG1hdGNoZXNbMV0gd291bGQgaGF2ZSB0aGUgY2hhcnNldCA6dGFkYTogLCBpbiBvdXIgZXhhbXBsZSBpdCdzIHV0Zi04XHJcbiAgICAvLyBIb3dldmVyLCBpZiB0aGUgbWF0Y2hlcyBBcnJheSB3YXMgZW1wdHkgb3Igbm8gY2hhcnNldCBmb3VuZCwgJ3V0Zi04JyB3b3VsZCBiZSByZXR1cm5lZCBieSBkZWZhdWx0LlxyXG4gICAgY29uc3Qgbm9kZVN1cHBvcnRlZEVuY29kaW5ncyA9IFsnYXNjaWknLCAndXRmOCcsICd1dGYxNmxlJywgJ3VjczInLCAnYmFzZTY0JywgJ2JpbmFyeScsICdoZXgnXTtcclxuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVzcG9uc2UubWVzc2FnZS5oZWFkZXJzWydjb250ZW50LXR5cGUnXSB8fCAnJztcclxuICAgIGNvbnN0IG1hdGNoZXMgPSBjb250ZW50VHlwZS5tYXRjaCgvY2hhcnNldD0oW147LFxcclxcbl0rKS9pKTtcclxuICAgIHJldHVybiAobWF0Y2hlcyAmJiBtYXRjaGVzWzFdICYmIG5vZGVTdXBwb3J0ZWRFbmNvZGluZ3MuaW5kZXhPZihtYXRjaGVzWzFdKSAhPSAtMSkgPyBtYXRjaGVzWzFdIDogJ3V0Zi04JztcclxufVxyXG5leHBvcnRzLm9idGFpbkNvbnRlbnRDaGFyc2V0ID0gb2J0YWluQ29udGVudENoYXJzZXQ7XHJcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvdHVubmVsJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBuZXQgPSByZXF1aXJlKCduZXQnKTtcbnZhciB0bHMgPSByZXF1aXJlKCd0bHMnKTtcbnZhciBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xudmFyIGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbnZhciBldmVudHMgPSByZXF1aXJlKCdldmVudHMnKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG5cbmV4cG9ydHMuaHR0cE92ZXJIdHRwID0gaHR0cE92ZXJIdHRwO1xuZXhwb3J0cy5odHRwc092ZXJIdHRwID0gaHR0cHNPdmVySHR0cDtcbmV4cG9ydHMuaHR0cE92ZXJIdHRwcyA9IGh0dHBPdmVySHR0cHM7XG5leHBvcnRzLmh0dHBzT3Zlckh0dHBzID0gaHR0cHNPdmVySHR0cHM7XG5cblxuZnVuY3Rpb24gaHR0cE92ZXJIdHRwKG9wdGlvbnMpIHtcbiAgdmFyIGFnZW50ID0gbmV3IFR1bm5lbGluZ0FnZW50KG9wdGlvbnMpO1xuICBhZ2VudC5yZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0O1xuICByZXR1cm4gYWdlbnQ7XG59XG5cbmZ1bmN0aW9uIGh0dHBzT3Zlckh0dHAob3B0aW9ucykge1xuICB2YXIgYWdlbnQgPSBuZXcgVHVubmVsaW5nQWdlbnQob3B0aW9ucyk7XG4gIGFnZW50LnJlcXVlc3QgPSBodHRwLnJlcXVlc3Q7XG4gIGFnZW50LmNyZWF0ZVNvY2tldCA9IGNyZWF0ZVNlY3VyZVNvY2tldDtcbiAgYWdlbnQuZGVmYXVsdFBvcnQgPSA0NDM7XG4gIHJldHVybiBhZ2VudDtcbn1cblxuZnVuY3Rpb24gaHR0cE92ZXJIdHRwcyhvcHRpb25zKSB7XG4gIHZhciBhZ2VudCA9IG5ldyBUdW5uZWxpbmdBZ2VudChvcHRpb25zKTtcbiAgYWdlbnQucmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Q7XG4gIHJldHVybiBhZ2VudDtcbn1cblxuZnVuY3Rpb24gaHR0cHNPdmVySHR0cHMob3B0aW9ucykge1xuICB2YXIgYWdlbnQgPSBuZXcgVHVubmVsaW5nQWdlbnQob3B0aW9ucyk7XG4gIGFnZW50LnJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0O1xuICBhZ2VudC5jcmVhdGVTb2NrZXQgPSBjcmVhdGVTZWN1cmVTb2NrZXQ7XG4gIGFnZW50LmRlZmF1bHRQb3J0ID0gNDQzO1xuICByZXR1cm4gYWdlbnQ7XG59XG5cblxuZnVuY3Rpb24gVHVubmVsaW5nQWdlbnQob3B0aW9ucykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGYub3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHNlbGYucHJveHlPcHRpb25zID0gc2VsZi5vcHRpb25zLnByb3h5IHx8IHt9O1xuICBzZWxmLm1heFNvY2tldHMgPSBzZWxmLm9wdGlvbnMubWF4U29ja2V0cyB8fCBodHRwLkFnZW50LmRlZmF1bHRNYXhTb2NrZXRzO1xuICBzZWxmLnJlcXVlc3RzID0gW107XG4gIHNlbGYuc29ja2V0cyA9IFtdO1xuXG4gIHNlbGYub24oJ2ZyZWUnLCBmdW5jdGlvbiBvbkZyZWUoc29ja2V0LCBob3N0LCBwb3J0LCBsb2NhbEFkZHJlc3MpIHtcbiAgICB2YXIgb3B0aW9ucyA9IHRvT3B0aW9ucyhob3N0LCBwb3J0LCBsb2NhbEFkZHJlc3MpO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzZWxmLnJlcXVlc3RzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB2YXIgcGVuZGluZyA9IHNlbGYucmVxdWVzdHNbaV07XG4gICAgICBpZiAocGVuZGluZy5ob3N0ID09PSBvcHRpb25zLmhvc3QgJiYgcGVuZGluZy5wb3J0ID09PSBvcHRpb25zLnBvcnQpIHtcbiAgICAgICAgLy8gRGV0ZWN0IHRoZSByZXF1ZXN0IHRvIGNvbm5lY3Qgc2FtZSBvcmlnaW4gc2VydmVyLFxuICAgICAgICAvLyByZXVzZSB0aGUgY29ubmVjdGlvbi5cbiAgICAgICAgc2VsZi5yZXF1ZXN0cy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIHBlbmRpbmcucmVxdWVzdC5vblNvY2tldChzb2NrZXQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgc2VsZi5yZW1vdmVTb2NrZXQoc29ja2V0KTtcbiAgfSk7XG59XG51dGlsLmluaGVyaXRzKFR1bm5lbGluZ0FnZW50LCBldmVudHMuRXZlbnRFbWl0dGVyKTtcblxuVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLmFkZFJlcXVlc3QgPSBmdW5jdGlvbiBhZGRSZXF1ZXN0KHJlcSwgaG9zdCwgcG9ydCwgbG9jYWxBZGRyZXNzKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIG9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoe3JlcXVlc3Q6IHJlcX0sIHNlbGYub3B0aW9ucywgdG9PcHRpb25zKGhvc3QsIHBvcnQsIGxvY2FsQWRkcmVzcykpO1xuXG4gIGlmIChzZWxmLnNvY2tldHMubGVuZ3RoID49IHRoaXMubWF4U29ja2V0cykge1xuICAgIC8vIFdlIGFyZSBvdmVyIGxpbWl0IHNvIHdlJ2xsIGFkZCBpdCB0byB0aGUgcXVldWUuXG4gICAgc2VsZi5yZXF1ZXN0cy5wdXNoKG9wdGlvbnMpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIElmIHdlIGFyZSB1bmRlciBtYXhTb2NrZXRzIGNyZWF0ZSBhIG5ldyBvbmUuXG4gIHNlbGYuY3JlYXRlU29ja2V0KG9wdGlvbnMsIGZ1bmN0aW9uKHNvY2tldCkge1xuICAgIHNvY2tldC5vbignZnJlZScsIG9uRnJlZSk7XG4gICAgc29ja2V0Lm9uKCdjbG9zZScsIG9uQ2xvc2VPclJlbW92ZSk7XG4gICAgc29ja2V0Lm9uKCdhZ2VudFJlbW92ZScsIG9uQ2xvc2VPclJlbW92ZSk7XG4gICAgcmVxLm9uU29ja2V0KHNvY2tldCk7XG5cbiAgICBmdW5jdGlvbiBvbkZyZWUoKSB7XG4gICAgICBzZWxmLmVtaXQoJ2ZyZWUnLCBzb2NrZXQsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9uQ2xvc2VPclJlbW92ZShlcnIpIHtcbiAgICAgIHNlbGYucmVtb3ZlU29ja2V0KHNvY2tldCk7XG4gICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2ZyZWUnLCBvbkZyZWUpO1xuICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uQ2xvc2VPclJlbW92ZSk7XG4gICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2FnZW50UmVtb3ZlJywgb25DbG9zZU9yUmVtb3ZlKTtcbiAgICB9XG4gIH0pO1xufTtcblxuVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLmNyZWF0ZVNvY2tldCA9IGZ1bmN0aW9uIGNyZWF0ZVNvY2tldChvcHRpb25zLCBjYikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBwbGFjZWhvbGRlciA9IHt9O1xuICBzZWxmLnNvY2tldHMucHVzaChwbGFjZWhvbGRlcik7XG5cbiAgdmFyIGNvbm5lY3RPcHRpb25zID0gbWVyZ2VPcHRpb25zKHt9LCBzZWxmLnByb3h5T3B0aW9ucywge1xuICAgIG1ldGhvZDogJ0NPTk5FQ1QnLFxuICAgIHBhdGg6IG9wdGlvbnMuaG9zdCArICc6JyArIG9wdGlvbnMucG9ydCxcbiAgICBhZ2VudDogZmFsc2UsXG4gICAgaGVhZGVyczoge1xuICAgICAgaG9zdDogb3B0aW9ucy5ob3N0ICsgJzonICsgb3B0aW9ucy5wb3J0XG4gICAgfVxuICB9KTtcbiAgaWYgKG9wdGlvbnMubG9jYWxBZGRyZXNzKSB7XG4gICAgY29ubmVjdE9wdGlvbnMubG9jYWxBZGRyZXNzID0gb3B0aW9ucy5sb2NhbEFkZHJlc3M7XG4gIH1cbiAgaWYgKGNvbm5lY3RPcHRpb25zLnByb3h5QXV0aCkge1xuICAgIGNvbm5lY3RPcHRpb25zLmhlYWRlcnMgPSBjb25uZWN0T3B0aW9ucy5oZWFkZXJzIHx8IHt9O1xuICAgIGNvbm5lY3RPcHRpb25zLmhlYWRlcnNbJ1Byb3h5LUF1dGhvcml6YXRpb24nXSA9ICdCYXNpYyAnICtcbiAgICAgICAgbmV3IEJ1ZmZlcihjb25uZWN0T3B0aW9ucy5wcm94eUF1dGgpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgfVxuXG4gIGRlYnVnKCdtYWtpbmcgQ09OTkVDVCByZXF1ZXN0Jyk7XG4gIHZhciBjb25uZWN0UmVxID0gc2VsZi5yZXF1ZXN0KGNvbm5lY3RPcHRpb25zKTtcbiAgY29ubmVjdFJlcS51c2VDaHVua2VkRW5jb2RpbmdCeURlZmF1bHQgPSBmYWxzZTsgLy8gZm9yIHYwLjZcbiAgY29ubmVjdFJlcS5vbmNlKCdyZXNwb25zZScsIG9uUmVzcG9uc2UpOyAvLyBmb3IgdjAuNlxuICBjb25uZWN0UmVxLm9uY2UoJ3VwZ3JhZGUnLCBvblVwZ3JhZGUpOyAgIC8vIGZvciB2MC42XG4gIGNvbm5lY3RSZXEub25jZSgnY29ubmVjdCcsIG9uQ29ubmVjdCk7ICAgLy8gZm9yIHYwLjcgb3IgbGF0ZXJcbiAgY29ubmVjdFJlcS5vbmNlKCdlcnJvcicsIG9uRXJyb3IpO1xuICBjb25uZWN0UmVxLmVuZCgpO1xuXG4gIGZ1bmN0aW9uIG9uUmVzcG9uc2UocmVzKSB7XG4gICAgLy8gVmVyeSBoYWNreS4gVGhpcyBpcyBuZWNlc3NhcnkgdG8gYXZvaWQgaHR0cC1wYXJzZXIgbGVha3MuXG4gICAgcmVzLnVwZ3JhZGUgPSB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gb25VcGdyYWRlKHJlcywgc29ja2V0LCBoZWFkKSB7XG4gICAgLy8gSGFja3kuXG4gICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbigpIHtcbiAgICAgIG9uQ29ubmVjdChyZXMsIHNvY2tldCwgaGVhZCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkNvbm5lY3QocmVzLCBzb2NrZXQsIGhlYWQpIHtcbiAgICBjb25uZWN0UmVxLnJlbW92ZUFsbExpc3RlbmVycygpO1xuICAgIHNvY2tldC5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcblxuICAgIGlmIChyZXMuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgICBkZWJ1ZygndHVubmVsaW5nIHNvY2tldCBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQsIHN0YXR1c0NvZGU9JWQnLFxuICAgICAgICByZXMuc3RhdHVzQ29kZSk7XG4gICAgICBzb2NrZXQuZGVzdHJveSgpO1xuICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCd0dW5uZWxpbmcgc29ja2V0IGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCwgJyArXG4gICAgICAgICdzdGF0dXNDb2RlPScgKyByZXMuc3RhdHVzQ29kZSk7XG4gICAgICBlcnJvci5jb2RlID0gJ0VDT05OUkVTRVQnO1xuICAgICAgb3B0aW9ucy5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgICAgc2VsZi5yZW1vdmVTb2NrZXQocGxhY2Vob2xkZXIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaGVhZC5sZW5ndGggPiAwKSB7XG4gICAgICBkZWJ1ZygnZ290IGlsbGVnYWwgcmVzcG9uc2UgYm9keSBmcm9tIHByb3h5Jyk7XG4gICAgICBzb2NrZXQuZGVzdHJveSgpO1xuICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdnb3QgaWxsZWdhbCByZXNwb25zZSBib2R5IGZyb20gcHJveHknKTtcbiAgICAgIGVycm9yLmNvZGUgPSAnRUNPTk5SRVNFVCc7XG4gICAgICBvcHRpb25zLnJlcXVlc3QuZW1pdCgnZXJyb3InLCBlcnJvcik7XG4gICAgICBzZWxmLnJlbW92ZVNvY2tldChwbGFjZWhvbGRlcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRlYnVnKCd0dW5uZWxpbmcgY29ubmVjdGlvbiBoYXMgZXN0YWJsaXNoZWQnKTtcbiAgICBzZWxmLnNvY2tldHNbc2VsZi5zb2NrZXRzLmluZGV4T2YocGxhY2Vob2xkZXIpXSA9IHNvY2tldDtcbiAgICByZXR1cm4gY2Ioc29ja2V0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uRXJyb3IoY2F1c2UpIHtcbiAgICBjb25uZWN0UmVxLnJlbW92ZUFsbExpc3RlbmVycygpO1xuXG4gICAgZGVidWcoJ3R1bm5lbGluZyBzb2NrZXQgY291bGQgbm90IGJlIGVzdGFibGlzaGVkLCBjYXVzZT0lc1xcbicsXG4gICAgICAgICAgY2F1c2UubWVzc2FnZSwgY2F1c2Uuc3RhY2spO1xuICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcigndHVubmVsaW5nIHNvY2tldCBjb3VsZCBub3QgYmUgZXN0YWJsaXNoZWQsICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnY2F1c2U9JyArIGNhdXNlLm1lc3NhZ2UpO1xuICAgIGVycm9yLmNvZGUgPSAnRUNPTk5SRVNFVCc7XG4gICAgb3B0aW9ucy5yZXF1ZXN0LmVtaXQoJ2Vycm9yJywgZXJyb3IpO1xuICAgIHNlbGYucmVtb3ZlU29ja2V0KHBsYWNlaG9sZGVyKTtcbiAgfVxufTtcblxuVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLnJlbW92ZVNvY2tldCA9IGZ1bmN0aW9uIHJlbW92ZVNvY2tldChzb2NrZXQpIHtcbiAgdmFyIHBvcyA9IHRoaXMuc29ja2V0cy5pbmRleE9mKHNvY2tldClcbiAgaWYgKHBvcyA9PT0gLTEpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5zb2NrZXRzLnNwbGljZShwb3MsIDEpO1xuXG4gIHZhciBwZW5kaW5nID0gdGhpcy5yZXF1ZXN0cy5zaGlmdCgpO1xuICBpZiAocGVuZGluZykge1xuICAgIC8vIElmIHdlIGhhdmUgcGVuZGluZyByZXF1ZXN0cyBhbmQgYSBzb2NrZXQgZ2V0cyBjbG9zZWQgYSBuZXcgb25lXG4gICAgLy8gbmVlZHMgdG8gYmUgY3JlYXRlZCB0byB0YWtlIG92ZXIgaW4gdGhlIHBvb2wgZm9yIHRoZSBvbmUgdGhhdCBjbG9zZWQuXG4gICAgdGhpcy5jcmVhdGVTb2NrZXQocGVuZGluZywgZnVuY3Rpb24oc29ja2V0KSB7XG4gICAgICBwZW5kaW5nLnJlcXVlc3Qub25Tb2NrZXQoc29ja2V0KTtcbiAgICB9KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gY3JlYXRlU2VjdXJlU29ja2V0KG9wdGlvbnMsIGNiKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgVHVubmVsaW5nQWdlbnQucHJvdG90eXBlLmNyZWF0ZVNvY2tldC5jYWxsKHNlbGYsIG9wdGlvbnMsIGZ1bmN0aW9uKHNvY2tldCkge1xuICAgIHZhciBob3N0SGVhZGVyID0gb3B0aW9ucy5yZXF1ZXN0LmdldEhlYWRlcignaG9zdCcpO1xuICAgIHZhciB0bHNPcHRpb25zID0gbWVyZ2VPcHRpb25zKHt9LCBzZWxmLm9wdGlvbnMsIHtcbiAgICAgIHNvY2tldDogc29ja2V0LFxuICAgICAgc2VydmVybmFtZTogaG9zdEhlYWRlciA/IGhvc3RIZWFkZXIucmVwbGFjZSgvOi4qJC8sICcnKSA6IG9wdGlvbnMuaG9zdFxuICAgIH0pO1xuXG4gICAgLy8gMCBpcyBkdW1teSBwb3J0IGZvciB2MC42XG4gICAgdmFyIHNlY3VyZVNvY2tldCA9IHRscy5jb25uZWN0KDAsIHRsc09wdGlvbnMpO1xuICAgIHNlbGYuc29ja2V0c1tzZWxmLnNvY2tldHMuaW5kZXhPZihzb2NrZXQpXSA9IHNlY3VyZVNvY2tldDtcbiAgICBjYihzZWN1cmVTb2NrZXQpO1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiB0b09wdGlvbnMoaG9zdCwgcG9ydCwgbG9jYWxBZGRyZXNzKSB7XG4gIGlmICh0eXBlb2YgaG9zdCA9PT0gJ3N0cmluZycpIHsgLy8gc2luY2UgdjAuMTBcbiAgICByZXR1cm4ge1xuICAgICAgaG9zdDogaG9zdCxcbiAgICAgIHBvcnQ6IHBvcnQsXG4gICAgICBsb2NhbEFkZHJlc3M6IGxvY2FsQWRkcmVzc1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGhvc3Q7IC8vIGZvciB2MC4xMSBvciBsYXRlclxufVxuXG5mdW5jdGlvbiBtZXJnZU9wdGlvbnModGFyZ2V0KSB7XG4gIGZvciAodmFyIGkgPSAxLCBsZW4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICB2YXIgb3ZlcnJpZGVzID0gYXJndW1lbnRzW2ldO1xuICAgIGlmICh0eXBlb2Ygb3ZlcnJpZGVzID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvdmVycmlkZXMpO1xuICAgICAgZm9yICh2YXIgaiA9IDAsIGtleUxlbiA9IGtleXMubGVuZ3RoOyBqIDwga2V5TGVuOyArK2opIHtcbiAgICAgICAgdmFyIGsgPSBrZXlzW2pdO1xuICAgICAgICBpZiAob3ZlcnJpZGVzW2tdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0YXJnZXRba10gPSBvdmVycmlkZXNba107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuXG52YXIgZGVidWc7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyAmJiAvXFxidHVubmVsXFxiLy50ZXN0KHByb2Nlc3MuZW52Lk5PREVfREVCVUcpKSB7XG4gIGRlYnVnID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGFyZ3NbMF0gPSAnVFVOTkVMOiAnICsgYXJnc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXJncy51bnNoaWZ0KCdUVU5ORUw6Jyk7XG4gICAgfVxuICAgIGNvbnNvbGUuZXJyb3IuYXBwbHkoY29uc29sZSwgYXJncyk7XG4gIH1cbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24oKSB7fTtcbn1cbmV4cG9ydHMuZGVidWcgPSBkZWJ1ZzsgLy8gZm9yIHRlc3RcbiIsIi8vIFJldHVybnMgYSB3cmFwcGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIHdyYXBwZWQgY2FsbGJhY2tcbi8vIFRoZSB3cmFwcGVyIGZ1bmN0aW9uIHNob3VsZCBkbyBzb21lIHN0dWZmLCBhbmQgcmV0dXJuIGFcbi8vIHByZXN1bWFibHkgZGlmZmVyZW50IGNhbGxiYWNrIGZ1bmN0aW9uLlxuLy8gVGhpcyBtYWtlcyBzdXJlIHRoYXQgb3duIHByb3BlcnRpZXMgYXJlIHJldGFpbmVkLCBzbyB0aGF0XG4vLyBkZWNvcmF0aW9ucyBhbmQgc3VjaCBhcmUgbm90IGxvc3QgYWxvbmcgdGhlIHdheS5cbm1vZHVsZS5leHBvcnRzID0gd3JhcHB5XG5mdW5jdGlvbiB3cmFwcHkgKGZuLCBjYikge1xuICBpZiAoZm4gJiYgY2IpIHJldHVybiB3cmFwcHkoZm4pKGNiKVxuXG4gIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbmVlZCB3cmFwcGVyIGZ1bmN0aW9uJylcblxuICBPYmplY3Qua2V5cyhmbikuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgIHdyYXBwZXJba10gPSBmbltrXVxuICB9KVxuXG4gIHJldHVybiB3cmFwcGVyXG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXVxuICAgIH1cbiAgICB2YXIgcmV0ID0gZm4uYXBwbHkodGhpcywgYXJncylcbiAgICB2YXIgY2IgPSBhcmdzW2FyZ3MubGVuZ3RoLTFdXG4gICAgaWYgKHR5cGVvZiByZXQgPT09ICdmdW5jdGlvbicgJiYgcmV0ICE9PSBjYikge1xuICAgICAgT2JqZWN0LmtleXMoY2IpLmZvckVhY2goZnVuY3Rpb24gKGspIHtcbiAgICAgICAgcmV0W2tdID0gY2Jba11cbiAgICAgIH0pXG4gICAgfVxuICAgIHJldHVybiByZXRcbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYXNzZXJ0XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNoaWxkX3Byb2Nlc3NcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiY3J5cHRvXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImV2ZW50c1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJmc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJodHRwXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImh0dHBzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIm5ldFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJvc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXRoXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInByb2Nlc3NcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidGxzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInVybFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1dGlsXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInpsaWJcIik7IiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHRpZDogbW9kdWxlSWQsXG5cdFx0bG9hZGVkOiBmYWxzZSxcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG5cdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuLy8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbl9fd2VicGFja19yZXF1aXJlX18uYyA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfXztcblxuIiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIl9fd2VicGFja19yZXF1aXJlX18ubm1kID0gKG1vZHVsZSkgPT4ge1xuXHRtb2R1bGUucGF0aHMgPSBbXTtcblx0aWYgKCFtb2R1bGUuY2hpbGRyZW4pIG1vZHVsZS5jaGlsZHJlbiA9IFtdO1xuXHRyZXR1cm4gbW9kdWxlO1xufTsiLCIvLyBtb2R1bGUgY2FjaGUgYXJlIHVzZWQgc28gZW50cnkgaW5saW5pbmcgaXMgZGlzYWJsZWRcbi8vIHN0YXJ0dXBcbi8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xudmFyIF9fd2VicGFja19leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IFwiLi9zcmMvdGFza3MvZ2l0cmVsZWFzZW1hbmFnZXIvb3Blbi50c1wiKTtcbiJdLCJzb3VyY2VSb290IjoiIn0= |