aws-cdk
Version:
AWS CDK Toolkit CLI, the command line tool for CDK apps
400 lines • 47.5 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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 __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Configuration = exports.Command = exports.USER_DEFAULTS = exports.PROJECT_CONTEXT = exports.PROJECT_CONFIG = void 0;
exports.commandLineArgumentsToSettings = commandLineArgumentsToSettings;
const os = __importStar(require("os"));
const fs_path = __importStar(require("path"));
const toolkit_lib_1 = require("@aws-cdk/toolkit-lib");
const fs = __importStar(require("fs-extra"));
const context_1 = require("../api/context");
const settings_1 = require("../api/settings");
exports.PROJECT_CONFIG = 'cdk.json';
var context_2 = require("../api/context");
Object.defineProperty(exports, "PROJECT_CONTEXT", { enumerable: true, get: function () { return context_2.PROJECT_CONTEXT; } });
exports.USER_DEFAULTS = '~/.cdk.json';
const CONTEXT_KEY = 'context';
var Command;
(function (Command) {
Command["LS"] = "ls";
Command["LIST"] = "list";
Command["DIFF"] = "diff";
Command["BOOTSTRAP"] = "bootstrap";
Command["DEPLOY"] = "deploy";
Command["DESTROY"] = "destroy";
Command["SYNTHESIZE"] = "synthesize";
Command["SYNTH"] = "synth";
Command["METADATA"] = "metadata";
Command["INIT"] = "init";
Command["VERSION"] = "version";
Command["WATCH"] = "watch";
Command["GC"] = "gc";
Command["FLAGS"] = "flags";
Command["ROLLBACK"] = "rollback";
Command["PUBLISH_ASSETS"] = "publish-assets";
Command["IMPORT"] = "import";
Command["ACKNOWLEDGE"] = "acknowledge";
Command["ACK"] = "ack";
Command["NOTICES"] = "notices";
Command["MIGRATE"] = "migrate";
Command["CONTEXT"] = "context";
Command["DOCS"] = "docs";
Command["DOC"] = "doc";
Command["DOCTOR"] = "doctor";
Command["LSP"] = "lsp";
Command["ORPHAN"] = "orphan";
Command["REFACTOR"] = "refactor";
Command["DRIFT"] = "drift";
Command["CLI_TELEMETRY"] = "cli-telemetry";
Command["DIAGNOSE"] = "diagnose";
Command["VALIDATE"] = "validate";
})(Command || (exports.Command = Command = {}));
const BUNDLING_COMMANDS = [
Command.DEPLOY,
Command.DIFF,
Command.SYNTH,
Command.SYNTHESIZE,
Command.WATCH,
Command.IMPORT,
Command.PUBLISH_ASSETS,
Command.REFACTOR,
];
/**
* All sources of settings combined
*/
class Configuration {
/**
* Creates user configuration from commandLineArguments
*/
static async fromArgs(ioHelper, args) {
const commandLineArguments = args
? await commandLineArgumentsToSettings(ioHelper, args)
: new settings_1.Settings();
return new Configuration(ioHelper, commandLineArguments);
}
/**
* Creates user configuration from commandLineArguments and loads
*/
static async fromArgsAndFiles(ioHelper, props = {}) {
const configuration = await Configuration.fromArgs(ioHelper, props.commandLineArguments);
return configuration.loadConfigFiles(props.readUserContext ?? true);
}
settings = new settings_1.Settings();
context = new context_1.Context();
defaultConfig = new settings_1.Settings({
versionReporting: true,
assetMetadata: true,
pathMetadata: true,
output: 'cdk.out',
});
commandLineArguments;
commandLineContext;
_projectConfig;
_projectContext;
contextFileBags = [];
loaded = false;
ioHelper;
constructor(ioHelper, commandLineArguments) {
this.ioHelper = ioHelper;
this.commandLineArguments = commandLineArguments;
this.commandLineContext = this.commandLineArguments
.subSettings([CONTEXT_KEY])
.makeReadOnly();
}
get projectConfig() {
if (!this._projectConfig) {
throw new toolkit_lib_1.ToolkitError('ConfigNotLoaded', '#load has not been called yet!');
}
return this._projectConfig;
}
get projectContext() {
if (!this._projectContext) {
throw new toolkit_lib_1.ToolkitError('ConfigNotLoaded', '#load has not been called yet!');
}
return this._projectContext;
}
/**
* The names of the context files that currently contain at least one
* context value, in lookup precedence order.
*/
get contextSourceFiles() {
return this.contextFileBags
.filter(({ bag }) => Object.keys(bag.all).length > 0)
.map(({ fileName }) => fileName);
}
/**
* Load all config
*/
async loadConfigFiles(readUserContext) {
const userConfig = await loadAndLog(this.ioHelper, exports.USER_DEFAULTS);
this._projectConfig = await loadAndLog(this.ioHelper, exports.PROJECT_CONFIG);
this._projectContext = await loadAndLog(this.ioHelper, context_1.PROJECT_CONTEXT);
if (userConfig.get(['build'])) {
throw new toolkit_lib_1.ToolkitError('BuildKeyInUserConfig', 'The `build` key cannot be specified in the user config (~/.cdk.json), specify it in the project config (cdk.json) instead');
}
const contextSources = [
{ bag: this.commandLineContext },
{
fileName: exports.PROJECT_CONFIG,
bag: this.projectConfig.subSettings([CONTEXT_KEY]).makeReadOnly(),
},
{ fileName: context_1.PROJECT_CONTEXT, bag: this.projectContext },
];
if (readUserContext) {
contextSources.push({
fileName: exports.USER_DEFAULTS,
bag: userConfig.subSettings([CONTEXT_KEY]).makeReadOnly(),
});
}
this.context = new context_1.Context(...contextSources);
this.contextFileBags = contextSources.filter((s) => s.fileName != null);
// Build settings from what's left
const mergedSettings = this.defaultConfig
.merge(userConfig)
.merge(this.projectConfig)
.merge(this.commandLineArguments);
// Backwards compatibility: a `debug: true` in a config file (cdk.json / ~/.cdk.json)
// implies both debug targets, mirroring the `--debug` CLI flag.
if (mergedSettings.get(['debug'])) {
mergedSettings.set(['debugApp'], true);
mergedSettings.set(['debugCli'], true);
}
this.settings = mergedSettings.makeReadOnly();
await this.ioHelper.defaults.debug('merged settings:', this.settings.all);
this.loaded = true;
return this;
}
/**
* Save the project context
*/
async saveContext() {
if (!this.loaded) {
return this;
} // Avoid overwriting files with nothing
await this.projectContext.save(context_1.PROJECT_CONTEXT);
return this;
}
}
exports.Configuration = Configuration;
async function loadAndLog(ioHelper, fileName) {
const ret = await settingsFromFile(ioHelper, fileName);
if (!ret.empty) {
await ioHelper.defaults.debug(fileName + ':', JSON.stringify(ret.all, undefined, 2));
}
return ret;
}
async function settingsFromFile(ioHelper, fileName) {
let settings;
const expanded = expandHomeDir(fileName);
if (await fs.pathExists(expanded)) {
const data = await fs.readJson(expanded);
settings = new settings_1.Settings(data);
}
else {
settings = new settings_1.Settings();
}
// See https://github.com/aws/aws-cdk/issues/59
prohibitContextKeys(settings, ['default-account', 'default-region'], fileName);
await warnAboutContextKey(ioHelper, settings, 'aws:', fileName);
return settings;
}
function prohibitContextKeys(settings, keys, fileName) {
const context = settings.get(['context']);
if (!context || typeof context !== 'object') {
return;
}
for (const key of keys) {
if (key in context) {
throw new toolkit_lib_1.ToolkitError('UnsupportedContextKey', `The 'context.${key}' key was found in ${fs_path.resolve(fileName)}, but it is no longer supported. Please remove it.`);
}
}
}
async function warnAboutContextKey(ioHelper, settings, prefix, fileName) {
const context = settings.get(['context']);
if (!context || typeof context !== 'object') {
return;
}
for (const contextKey of Object.keys(context)) {
if (contextKey.startsWith(prefix)) {
await ioHelper.defaults.warning(`A reserved context key ('context.${prefix}') key was found in ${fs_path.resolve(fileName)}, it might cause surprising behavior and should be removed.`);
}
}
}
function expandHomeDir(x) {
if (x.startsWith('~')) {
return fs_path.join(os.homedir(), x.slice(1));
}
return x;
}
/**
* Parse CLI arguments into Settings
*
* CLI arguments in must be accessed in the CLI code via
* `configuration.settings.get(['argName'])` instead of via `args.argName`.
*
* The advantage is that they can be configured via `cdk.json` and
* `$HOME/.cdk.json`. Arguments not listed below and accessed via this object
* can only be specified on the command line.
*
* @param argv - the received CLI arguments.
* @returns a new Settings object.
*/
async function commandLineArgumentsToSettings(ioHelper, argv) {
const context = await parseStringContextListToObject(ioHelper, argv);
const tags = await parseStringTagsListToObject(ioHelper, expectStringList(argv.tags));
// Determine bundling stacks
let bundlingStacks;
if (BUNDLING_COMMANDS.includes(argv._[0])) {
// If we deploy, diff, synth or watch a list of stacks exclusively we skip
// bundling for all other stacks.
bundlingStacks = argv.exclusively ? argv.STACKS ?? ['**'] : ['**'];
}
else {
// Skip bundling for all stacks
bundlingStacks = [];
}
return new settings_1.Settings({
app: argv.app,
browser: argv.browser,
build: argv.build,
caBundlePath: argv.caBundlePath,
context,
// The `--debug` implication (both debug targets) is resolved during argument
// parsing, so here we only read the resolved per-target flags.
debugApp: argv.debugApp,
debugCli: argv.debugCli,
verbose: argv.verbose,
tags,
language: argv.language,
pathMetadata: argv.pathMetadata,
assetMetadata: argv.assetMetadata,
validation: argv.validation,
profile: argv.profile,
region: argv.region,
plugin: argv.plugin,
requireApproval: argv.requireApproval,
toolkitStackName: argv.toolkitStackName,
toolkitBucket: {
bucketName: argv.bootstrapBucketName,
kmsKeyId: argv.bootstrapKmsKeyId,
},
versionReporting: argv.versionReporting,
staging: argv.staging,
output: argv.output,
outputsFile: argv.outputsFile,
progress: argv.progress,
proxy: argv.proxy,
bundlingStacks,
lookups: argv.lookups,
rollback: argv.rollback,
notices: argv.notices,
assetParallelism: argv['asset-parallelism'],
assetBuildConcurrency: argv['asset-build-concurrency'],
assetPrebuild: argv['asset-prebuild'],
ignoreNoStacks: argv['ignore-no-stacks'],
hotswap: {
ecs: {
minimumHealthyPercent: argv.hotswapEcsMinimumHealthyPercent,
maximumHealthyPercent: argv.hotswapEcsMaximumHealthyPercent,
stabilizationTimeoutSeconds: argv.hotswapEcsStabilizationTimeoutSeconds,
},
},
unstable: argv.unstable,
});
}
function expectStringList(x) {
if (x === undefined) {
return undefined;
}
if (!Array.isArray(x)) {
throw new toolkit_lib_1.ToolkitError('ExpectedArray', `Expected array, got '${x}'`);
}
const nonStrings = x.filter((e) => typeof e !== 'string');
if (nonStrings.length > 0) {
throw new toolkit_lib_1.ToolkitError('ExpectedStringList', `Expected list of strings, found ${nonStrings}`);
}
return x;
}
async function parseStringContextListToObject(ioHelper, argv) {
const context = {};
for (const assignment of argv.context || []) {
const parts = assignment.split(/=(.*)/, 2);
if (parts.length === 2) {
await ioHelper.defaults.debug('CLI argument context: %s=%s', parts[0], parts[1]);
if (parts[0].match(/^aws:.+/)) {
throw new toolkit_lib_1.ToolkitError('ReservedContextPrefix', `User-provided context cannot use keys prefixed with 'aws:', but ${parts[0]} was provided.`);
}
context[parts[0]] = parts[1];
}
else {
await ioHelper.defaults.warn('Context argument is not an assignment (key=value): %s', assignment);
}
}
return context;
}
/**
* Parse tags out of arguments
*
* Return undefined if no tags were provided, return an empty array if only empty
* strings were provided
*/
async function parseStringTagsListToObject(ioHelper, argTags) {
if (argTags === undefined) {
return undefined;
}
if (argTags.length === 0) {
return undefined;
}
const nonEmptyTags = argTags.filter((t) => t !== '');
if (nonEmptyTags.length === 0) {
return [];
}
const tags = [];
for (const assignment of nonEmptyTags) {
const parts = assignment.split(/=(.*)/, 2);
if (parts.length === 2) {
await ioHelper.defaults.debug('CLI argument tags: %s=%s', parts[0], parts[1]);
tags.push({
Key: parts[0],
Value: parts[1],
});
}
else {
await ioHelper.defaults.warn('Tags argument is not an assignment (key=value): %s', assignment);
}
}
return tags.length > 0 ? tags : undefined;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1jb25maWd1cmF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidXNlci1jb25maWd1cmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1UQSx3RUErREM7QUFsWEQsdUNBQXlCO0FBQ3pCLDhDQUFnQztBQUNoQyxzREFBb0Q7QUFDcEQsNkNBQStCO0FBQy9CLDRDQUEwRDtBQUMxRCw4Q0FBMkM7QUFJOUIsUUFBQSxjQUFjLEdBQUcsVUFBVSxDQUFDO0FBQ3pDLDBDQUFpRDtBQUF4QywwR0FBQSxlQUFlLE9BQUE7QUFDWCxRQUFBLGFBQWEsR0FBRyxhQUFhLENBQUM7QUFDM0MsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDO0FBRTlCLElBQVksT0FpQ1g7QUFqQ0QsV0FBWSxPQUFPO0lBQ2pCLG9CQUFTLENBQUE7SUFDVCx3QkFBYSxDQUFBO0lBQ2Isd0JBQWEsQ0FBQTtJQUNiLGtDQUF1QixDQUFBO0lBQ3ZCLDRCQUFpQixDQUFBO0lBQ2pCLDhCQUFtQixDQUFBO0lBQ25CLG9DQUF5QixDQUFBO0lBQ3pCLDBCQUFlLENBQUE7SUFDZixnQ0FBcUIsQ0FBQTtJQUNyQix3QkFBYSxDQUFBO0lBQ2IsOEJBQW1CLENBQUE7SUFDbkIsMEJBQWUsQ0FBQTtJQUNmLG9CQUFTLENBQUE7SUFDVCwwQkFBZSxDQUFBO0lBQ2YsZ0NBQXFCLENBQUE7SUFDckIsNENBQWlDLENBQUE7SUFDakMsNEJBQWlCLENBQUE7SUFDakIsc0NBQTJCLENBQUE7SUFDM0Isc0JBQVcsQ0FBQTtJQUNYLDhCQUFtQixDQUFBO0lBQ25CLDhCQUFtQixDQUFBO0lBQ25CLDhCQUFtQixDQUFBO0lBQ25CLHdCQUFhLENBQUE7SUFDYixzQkFBVyxDQUFBO0lBQ1gsNEJBQWlCLENBQUE7SUFDakIsc0JBQVcsQ0FBQTtJQUNYLDRCQUFpQixDQUFBO0lBQ2pCLGdDQUFxQixDQUFBO0lBQ3JCLDBCQUFlLENBQUE7SUFDZiwwQ0FBK0IsQ0FBQTtJQUMvQixnQ0FBcUIsQ0FBQTtJQUNyQixnQ0FBcUIsQ0FBQTtBQUN2QixDQUFDLEVBakNXLE9BQU8sdUJBQVAsT0FBTyxRQWlDbEI7QUFFRCxNQUFNLGlCQUFpQixHQUFHO0lBQ3hCLE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLElBQUk7SUFDWixPQUFPLENBQUMsS0FBSztJQUNiLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxLQUFLO0lBQ2IsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsY0FBYztJQUN0QixPQUFPLENBQUMsUUFBUTtDQUNqQixDQUFDO0FBMEJGOztHQUVHO0FBQ0gsTUFBYSxhQUFhO0lBQ3hCOztPQUVHO0lBQ0ksTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsUUFBa0IsRUFBRSxJQUFnQjtRQUMvRCxNQUFNLG9CQUFvQixHQUFHLElBQUk7WUFDL0IsQ0FBQyxDQUFDLE1BQU0sOEJBQThCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQztZQUN0RCxDQUFDLENBQUMsSUFBSSxtQkFBUSxFQUFFLENBQUM7UUFFbkIsT0FBTyxJQUFJLGFBQWEsQ0FBQyxRQUFRLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFFBQWtCLEVBQUUsUUFBNEIsRUFBRTtRQUNyRixNQUFNLGFBQWEsR0FBRyxNQUFNLGFBQWEsQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3pGLE9BQU8sYUFBYSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFTSxRQUFRLEdBQUcsSUFBSSxtQkFBUSxFQUFFLENBQUM7SUFDMUIsT0FBTyxHQUFHLElBQUksaUJBQU8sRUFBRSxDQUFDO0lBRWYsYUFBYSxHQUFHLElBQUksbUJBQVEsQ0FBQztRQUMzQyxnQkFBZ0IsRUFBRSxJQUFJO1FBQ3RCLGFBQWEsRUFBRSxJQUFJO1FBQ25CLFlBQVksRUFBRSxJQUFJO1FBQ2xCLE1BQU0sRUFBRSxTQUFTO0tBQ2xCLENBQUMsQ0FBQztJQUVjLG9CQUFvQixDQUFXO0lBQy9CLGtCQUFrQixDQUFXO0lBQ3RDLGNBQWMsQ0FBWTtJQUMxQixlQUFlLENBQVk7SUFDM0IsZUFBZSxHQUErQyxFQUFFLENBQUM7SUFDakUsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUVmLFFBQVEsQ0FBVztJQUUzQixZQUFvQixRQUFrQixFQUFFLG9CQUE4QjtRQUNwRSxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsb0JBQW9CLEdBQUcsb0JBQW9CLENBQUM7UUFDakQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxvQkFBb0I7YUFDaEQsV0FBVyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7YUFDMUIsWUFBWSxFQUFFLENBQUM7SUFDcEIsQ0FBQztJQUVELElBQVksYUFBYTtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3pCLE1BQU0sSUFBSSwwQkFBWSxDQUFDLGlCQUFpQixFQUFFLGdDQUFnQyxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQztJQUM3QixDQUFDO0lBRUQsSUFBVyxjQUFjO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDMUIsTUFBTSxJQUFJLDBCQUFZLENBQUMsaUJBQWlCLEVBQUUsZ0NBQWdDLENBQUMsQ0FBQztRQUM5RSxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQzlCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFXLGtCQUFrQjtRQUMzQixPQUFPLElBQUksQ0FBQyxlQUFlO2FBQ3hCLE1BQU0sQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7YUFDcEQsR0FBRyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSyxDQUFDLGVBQWUsQ0FBQyxlQUF3QjtRQUNwRCxNQUFNLFVBQVUsR0FBRyxNQUFNLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLHFCQUFhLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsY0FBYyxHQUFHLE1BQU0sVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsc0JBQWMsQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxlQUFlLEdBQUcsTUFBTSxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSx5QkFBZSxDQUFDLENBQUM7UUFFeEUsSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzlCLE1BQU0sSUFBSSwwQkFBWSxDQUNwQixzQkFBc0IsRUFDdEIsMkhBQTJILENBQzVILENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxjQUFjLEdBQUc7WUFDckIsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQ2hDO2dCQUNFLFFBQVEsRUFBRSxzQkFBYztnQkFDeEIsR0FBRyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUU7YUFDbEU7WUFDRCxFQUFFLFFBQVEsRUFBRSx5QkFBZSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFO1NBQ3hELENBQUM7UUFDRixJQUFJLGVBQWUsRUFBRSxDQUFDO1lBQ3BCLGNBQWMsQ0FBQyxJQUFJLENBQUM7Z0JBQ2xCLFFBQVEsRUFBRSxxQkFBYTtnQkFDdkIsR0FBRyxFQUFFLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFlBQVksRUFBRTthQUMxRCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLGlCQUFPLENBQUMsR0FBRyxjQUFjLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsZUFBZSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQTRDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxDQUFDO1FBRWxILGtDQUFrQztRQUNsQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYTthQUN0QyxLQUFLLENBQUMsVUFBVSxDQUFDO2FBQ2pCLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO2FBQ3pCLEtBQUssQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUVwQyxxRkFBcUY7UUFDckYsZ0VBQWdFO1FBQ2hFLElBQUksY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNsQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDdkMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFFRCxJQUFJLENBQUMsUUFBUSxHQUFHLGNBQWMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUU5QyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRTFFLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBRW5CLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFdBQVc7UUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FBQyx1Q0FBdUM7UUFFekMsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyx5QkFBZSxDQUFDLENBQUM7UUFFaEQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0NBQ0Y7QUExSUQsc0NBMElDO0FBRUQsS0FBSyxVQUFVLFVBQVUsQ0FBQyxRQUFrQixFQUFFLFFBQWdCO0lBQzVELE1BQU0sR0FBRyxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZELElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDZixNQUFNLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxHQUFHLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCxLQUFLLFVBQVUsZ0JBQWdCLENBQUMsUUFBa0IsRUFBRSxRQUFnQjtJQUNsRSxJQUFJLFFBQVEsQ0FBQztJQUNiLE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN6QyxJQUFJLE1BQU0sRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN6QyxRQUFRLEdBQUcsSUFBSSxtQkFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7U0FBTSxDQUFDO1FBQ04sUUFBUSxHQUFHLElBQUksbUJBQVEsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCwrQ0FBK0M7SUFDL0MsbUJBQW1CLENBQUMsUUFBUSxFQUFFLENBQUMsaUJBQWlCLEVBQUUsZ0JBQWdCLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMvRSxNQUFNLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBRWhFLE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUM7QUFFRCxTQUFTLG1CQUFtQixDQUFDLFFBQWtCLEVBQUUsSUFBYyxFQUFFLFFBQWdCO0lBQy9FLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQzFDLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDNUMsT0FBTztJQUNULENBQUM7SUFFRCxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQUksR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ25CLE1BQU0sSUFBSSwwQkFBWSxDQUNwQix1QkFBdUIsRUFDdkIsZ0JBQWdCLEdBQUcsc0JBQXNCLE9BQU8sQ0FBQyxPQUFPLENBQ3RELFFBQVEsQ0FDVCxvREFBb0QsQ0FDdEQsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVELEtBQUssVUFBVSxtQkFBbUIsQ0FBQyxRQUFrQixFQUFFLFFBQWtCLEVBQUUsTUFBYyxFQUFFLFFBQWdCO0lBQ3pHLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQzFDLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDNUMsT0FBTztJQUNULENBQUM7SUFFRCxLQUFLLE1BQU0sVUFBVSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUM5QyxJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUNsQyxNQUFNLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUM3QixvQ0FBb0MsTUFBTSx1QkFBdUIsT0FBTyxDQUFDLE9BQU8sQ0FDOUUsUUFBUSxDQUNULDZEQUE2RCxDQUMvRCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsQ0FBUztJQUM5QixJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN0QixPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBQ0QsT0FBTyxDQUFDLENBQUM7QUFDWCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0ksS0FBSyxVQUFVLDhCQUE4QixDQUFDLFFBQWtCLEVBQUUsSUFBZTtJQUN0RixNQUFNLE9BQU8sR0FBRyxNQUFNLDhCQUE4QixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNyRSxNQUFNLElBQUksR0FBRyxNQUFNLDJCQUEyQixDQUFDLFFBQVEsRUFBRSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUV0Riw0QkFBNEI7SUFDNUIsSUFBSSxjQUF3QixDQUFDO0lBQzdCLElBQUksaUJBQWlCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzFDLDBFQUEwRTtRQUMxRSxpQ0FBaUM7UUFDakMsY0FBYyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNyRSxDQUFDO1NBQU0sQ0FBQztRQUNOLCtCQUErQjtRQUMvQixjQUFjLEdBQUcsRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxPQUFPLElBQUksbUJBQVEsQ0FBQztRQUNsQixHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7UUFDYixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87UUFDckIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1FBQ2pCLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtRQUMvQixPQUFPO1FBQ1AsNkVBQTZFO1FBQzdFLCtEQUErRDtRQUMvRCxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7UUFDdkIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1FBQ3ZCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztRQUNyQixJQUFJO1FBQ0osUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1FBQ3ZCLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtRQUMvQixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7UUFDakMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1FBQzNCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztRQUNyQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07UUFDbkIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1FBQ25CLGVBQWUsRUFBRSxJQUFJLENBQUMsZUFBZTtRQUNyQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO1FBQ3ZDLGFBQWEsRUFBRTtZQUNiLFVBQVUsRUFBRSxJQUFJLENBQUMsbUJBQW1CO1lBQ3BDLFFBQVEsRUFBRSxJQUFJLENBQUMsaUJBQWlCO1NBQ2pDO1FBQ0QsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtRQUN2QyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87UUFDckIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1FBQ25CLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztRQUM3QixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7UUFDdkIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1FBQ2pCLGNBQWM7UUFDZCxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87UUFDckIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1FBQ3ZCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztRQUNyQixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUM7UUFDM0MscUJBQXFCLEVBQUUsSUFBSSxDQUFDLHlCQUF5QixDQUFDO1FBQ3RELGFBQWEsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUM7UUFDckMsY0FBYyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztRQUN4QyxPQUFPLEVBQUU7WUFDUCxHQUFHLEVBQUU7Z0JBQ0gscUJBQXFCLEVBQUUsSUFBSSxDQUFDLCtCQUErQjtnQkFDM0QscUJBQXFCLEVBQUUsSUFBSSxDQUFDLCtCQUErQjtnQkFDM0QsMkJBQTJCLEVBQUUsSUFBSSxDQUFDLHFDQUFxQzthQUN4RTtTQUNGO1FBQ0QsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO0tBQ3hCLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLENBQVU7SUFDbEMsSUFBSSxDQUFDLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDcEIsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUNELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdEIsTUFBTSxJQUFJLDBCQUFZLENBQUMsZUFBZSxFQUFFLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFDRCxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQztJQUMxRCxJQUFJLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDMUIsTUFBTSxJQUFJLDBCQUFZLENBQUMsb0JBQW9CLEVBQUUsbUNBQW1DLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDaEcsQ0FBQztJQUNELE9BQU8sQ0FBQyxDQUFDO0FBQ1gsQ0FBQztBQUVELEtBQUssVUFBVSw4QkFBOEIsQ0FBQyxRQUFrQixFQUFFLElBQWU7SUFDL0UsTUFBTSxPQUFPLEdBQVEsRUFBRSxDQUFDO0lBRXhCLEtBQUssTUFBTSxVQUFVLElBQUssSUFBWSxDQUFDLE9BQU8sSUFBSSxFQUFFLEVBQUUsQ0FBQztRQUNyRCxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdkIsTUFBTSxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakYsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBQzlCLE1BQU0sSUFBSSwwQkFBWSxDQUNwQix1QkFBdUIsRUFDdkIsbUVBQW1FLEtBQUssQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQzVGLENBQUM7WUFDSixDQUFDO1lBQ0QsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQixDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQzFCLHVEQUF1RCxFQUN2RCxVQUFVLENBQ1gsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsS0FBSyxVQUFVLDJCQUEyQixDQUN4QyxRQUFrQixFQUNsQixPQUE2QjtJQUU3QixJQUFJLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUMxQixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDckQsSUFBSSxZQUFZLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzlCLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFVLEVBQUUsQ0FBQztJQUV2QixLQUFLLE1BQU0sVUFBVSxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3RDLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzNDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN2QixNQUFNLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLDBCQUEwQixFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5RSxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNSLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNiLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2FBQ2hCLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxvREFBb0QsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNqRyxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQzVDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgKiBhcyBmc19wYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgVG9vbGtpdEVycm9yIH0gZnJvbSAnQGF3cy1jZGsvdG9vbGtpdC1saWInO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHsgQ29udGV4dCwgUFJPSkVDVF9DT05URVhUIH0gZnJvbSAnLi4vYXBpL2NvbnRleHQnO1xuaW1wb3J0IHsgU2V0dGluZ3MgfSBmcm9tICcuLi9hcGkvc2V0dGluZ3MnO1xuaW1wb3J0IHR5cGUgeyBUYWcgfSBmcm9tICcuLi9hcGkvdGFncyc7XG5pbXBvcnQgdHlwZSB7IElvSGVscGVyIH0gZnJvbSAnLi4vYXBpLXByaXZhdGUnO1xuXG5leHBvcnQgY29uc3QgUFJPSkVDVF9DT05GSUcgPSAnY2RrLmpzb24nO1xuZXhwb3J0IHsgUFJPSkVDVF9DT05URVhUIH0gZnJvbSAnLi4vYXBpL2NvbnRleHQnO1xuZXhwb3J0IGNvbnN0IFVTRVJfREVGQVVMVFMgPSAnfi8uY2RrLmpzb24nO1xuY29uc3QgQ09OVEVYVF9LRVkgPSAnY29udGV4dCc7XG5cbmV4cG9ydCBlbnVtIENvbW1hbmQge1xuICBMUyA9ICdscycsXG4gIExJU1QgPSAnbGlzdCcsXG4gIERJRkYgPSAnZGlmZicsXG4gIEJPT1RTVFJBUCA9ICdib290c3RyYXAnLFxuICBERVBMT1kgPSAnZGVwbG95JyxcbiAgREVTVFJPWSA9ICdkZXN0cm95JyxcbiAgU1lOVEhFU0laRSA9ICdzeW50aGVzaXplJyxcbiAgU1lOVEggPSAnc3ludGgnLFxuICBNRVRBREFUQSA9ICdtZXRhZGF0YScsXG4gIElOSVQgPSAnaW5pdCcsXG4gIFZFUlNJT04gPSAndmVyc2lvbicsXG4gIFdBVENIID0gJ3dhdGNoJyxcbiAgR0MgPSAnZ2MnLFxuICBGTEFHUyA9ICdmbGFncycsXG4gIFJPTExCQUNLID0gJ3JvbGxiYWNrJyxcbiAgUFVCTElTSF9BU1NFVFMgPSAncHVibGlzaC1hc3NldHMnLFxuICBJTVBPUlQgPSAnaW1wb3J0JyxcbiAgQUNLTk9XTEVER0UgPSAnYWNrbm93bGVkZ2UnLFxuICBBQ0sgPSAnYWNrJyxcbiAgTk9USUNFUyA9ICdub3RpY2VzJyxcbiAgTUlHUkFURSA9ICdtaWdyYXRlJyxcbiAgQ09OVEVYVCA9ICdjb250ZXh0JyxcbiAgRE9DUyA9ICdkb2NzJyxcbiAgRE9DID0gJ2RvYycsXG4gIERPQ1RPUiA9ICdkb2N0b3InLFxuICBMU1AgPSAnbHNwJyxcbiAgT1JQSEFOID0gJ29ycGhhbicsXG4gIFJFRkFDVE9SID0gJ3JlZmFjdG9yJyxcbiAgRFJJRlQgPSAnZHJpZnQnLFxuICBDTElfVEVMRU1FVFJZID0gJ2NsaS10ZWxlbWV0cnknLFxuICBESUFHTk9TRSA9ICdkaWFnbm9zZScsXG4gIFZBTElEQVRFID0gJ3ZhbGlkYXRlJyxcbn1cblxuY29uc3QgQlVORExJTkdfQ09NTUFORFMgPSBbXG4gIENvbW1hbmQuREVQTE9ZLFxuICBDb21tYW5kLkRJRkYsXG4gIENvbW1hbmQuU1lOVEgsXG4gIENvbW1hbmQuU1lOVEhFU0laRSxcbiAgQ29tbWFuZC5XQVRDSCxcbiAgQ29tbWFuZC5JTVBPUlQsXG4gIENvbW1hbmQuUFVCTElTSF9BU1NFVFMsXG4gIENvbW1hbmQuUkVGQUNUT1IsXG5dO1xuXG5leHBvcnQgdHlwZSBBcmd1bWVudHMgPSB7XG4gIHJlYWRvbmx5IF86IFtDb21tYW5kLCAuLi5zdHJpbmdbXV07XG4gIHJlYWRvbmx5IGV4Y2x1c2l2ZWx5PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgU1RBQ0tTPzogc3RyaW5nW107XG4gIHJlYWRvbmx5IGxvb2t1cHM/OiBib29sZWFuO1xuICByZWFkb25seSBbbmFtZTogc3RyaW5nXTogdW5rbm93bjtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlndXJhdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gcGFzc2VkIHZpYSBjb21tYW5kIGxpbmUgYXJndW1lbnRzXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm90aGluZyBwYXNzZWRcbiAgICovXG4gIHJlYWRvbmx5IGNvbW1hbmRMaW5lQXJndW1lbnRzPzogQXJndW1lbnRzO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0byB1c2UgY29udGV4dCBmcm9tIGAuY2RrLmpzb25gIGluIHVzZXIgaG9tZSBkaXJlY3RvcnlcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVhZFVzZXJDb250ZXh0PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBbGwgc291cmNlcyBvZiBzZXR0aW5ncyBjb21iaW5lZFxuICovXG5leHBvcnQgY2xhc3MgQ29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIHVzZXIgY29uZmlndXJhdGlvbiBmcm9tIGNvbW1hbmRMaW5lQXJndW1lbnRzXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIGZyb21BcmdzKGlvSGVscGVyOiBJb0hlbHBlciwgYXJncz86IEFyZ3VtZW50cykge1xuICAgIGNvbnN0IGNvbW1hbmRMaW5lQXJndW1lbnRzID0gYXJnc1xuICAgICAgPyBhd2FpdCBjb21tYW5kTGluZUFyZ3VtZW50c1RvU2V0dGluZ3MoaW9IZWxwZXIsIGFyZ3MpXG4gICAgICA6IG5ldyBTZXR0aW5ncygpO1xuXG4gICAgcmV0dXJuIG5ldyBDb25maWd1cmF0aW9uKGlvSGVscGVyLCBjb21tYW5kTGluZUFyZ3VtZW50cyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB1c2VyIGNvbmZpZ3VyYXRpb24gZnJvbSBjb21tYW5kTGluZUFyZ3VtZW50cyBhbmQgbG9hZHNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZnJvbUFyZ3NBbmRGaWxlcyhpb0hlbHBlcjogSW9IZWxwZXIsIHByb3BzOiBDb25maWd1cmF0aW9uUHJvcHMgPSB7fSkge1xuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSBhd2FpdCBDb25maWd1cmF0aW9uLmZyb21BcmdzKGlvSGVscGVyLCBwcm9wcy5jb21tYW5kTGluZUFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGNvbmZpZ3VyYXRpb24ubG9hZENvbmZpZ0ZpbGVzKHByb3BzLnJlYWRVc2VyQ29udGV4dCA/PyB0cnVlKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXR0aW5ncyA9IG5ldyBTZXR0aW5ncygpO1xuICBwdWJsaWMgY29udGV4dCA9IG5ldyBDb250ZXh0KCk7XG5cbiAgcHVibGljIHJlYWRvbmx5IGRlZmF1bHRDb25maWcgPSBuZXcgU2V0dGluZ3Moe1xuICAgIHZlcnNpb25SZXBvcnRpbmc6IHRydWUsXG4gICAgYXNzZXRNZXRhZGF0YTogdHJ1ZSxcbiAgICBwYXRoTWV0YWRhdGE6IHRydWUsXG4gICAgb3V0cHV0OiAnY2RrLm91dCcsXG4gIH0pO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZExpbmVBcmd1bWVudHM6IFNldHRpbmdzO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbW1hbmRMaW5lQ29udGV4dDogU2V0dGluZ3M7XG4gIHByaXZhdGUgX3Byb2plY3RDb25maWc/OiBTZXR0aW5ncztcbiAgcHJpdmF0ZSBfcHJvamVjdENvbnRleHQ/OiBTZXR0aW5ncztcbiAgcHJpdmF0ZSBjb250ZXh0RmlsZUJhZ3M6IEFycmF5PHsgZmlsZU5hbWU6IHN0cmluZzsgYmFnOiBTZXR0aW5ncyB9PiA9IFtdO1xuICBwcml2YXRlIGxvYWRlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgaW9IZWxwZXI6IElvSGVscGVyO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoaW9IZWxwZXI6IElvSGVscGVyLCBjb21tYW5kTGluZUFyZ3VtZW50czogU2V0dGluZ3MpIHtcbiAgICB0aGlzLmlvSGVscGVyID0gaW9IZWxwZXI7XG4gICAgdGhpcy5jb21tYW5kTGluZUFyZ3VtZW50cyA9IGNvbW1hbmRMaW5lQXJndW1lbnRzO1xuICAgIHRoaXMuY29tbWFuZExpbmVDb250ZXh0ID0gdGhpcy5jb21tYW5kTGluZUFyZ3VtZW50c1xuICAgICAgLnN1YlNldHRpbmdzKFtDT05URVhUX0tFWV0pXG4gICAgICAubWFrZVJlYWRPbmx5KCk7XG4gIH1cblxuICBwcml2YXRlIGdldCBwcm9qZWN0Q29uZmlnKCkge1xuICAgIGlmICghdGhpcy5fcHJvamVjdENvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignQ29uZmlnTm90TG9hZGVkJywgJyNsb2FkIGhhcyBub3QgYmVlbiBjYWxsZWQgeWV0IScpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcHJvamVjdENvbmZpZztcbiAgfVxuXG4gIHB1YmxpYyBnZXQgcHJvamVjdENvbnRleHQoKSB7XG4gICAgaWYgKCF0aGlzLl9wcm9qZWN0Q29udGV4dCkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignQ29uZmlnTm90TG9hZGVkJywgJyNsb2FkIGhhcyBub3QgYmVlbiBjYWxsZWQgeWV0IScpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcHJvamVjdENvbnRleHQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG5hbWVzIG9mIHRoZSBjb250ZXh0IGZpbGVzIHRoYXQgY3VycmVudGx5IGNvbnRhaW4gYXQgbGVhc3Qgb25lXG4gICAqIGNvbnRleHQgdmFsdWUsIGluIGxvb2t1cCBwcmVjZWRlbmNlIG9yZGVyLlxuICAgKi9cbiAgcHVibGljIGdldCBjb250ZXh0U291cmNlRmlsZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHRGaWxlQmFnc1xuICAgICAgLmZpbHRlcigoeyBiYWcgfSkgPT4gT2JqZWN0LmtleXMoYmFnLmFsbCkubGVuZ3RoID4gMClcbiAgICAgIC5tYXAoKHsgZmlsZU5hbWUgfSkgPT4gZmlsZU5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgYWxsIGNvbmZpZ1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkQ29uZmlnRmlsZXMocmVhZFVzZXJDb250ZXh0OiBib29sZWFuKTogUHJvbWlzZTx0aGlzPiB7XG4gICAgY29uc3QgdXNlckNvbmZpZyA9IGF3YWl0IGxvYWRBbmRMb2codGhpcy5pb0hlbHBlciwgVVNFUl9ERUZBVUxUUyk7XG4gICAgdGhpcy5fcHJvamVjdENvbmZpZyA9IGF3YWl0IGxvYWRBbmRMb2codGhpcy5pb0hlbHBlciwgUFJPSkVDVF9DT05GSUcpO1xuICAgIHRoaXMuX3Byb2plY3RDb250ZXh0ID0gYXdhaXQgbG9hZEFuZExvZyh0aGlzLmlvSGVscGVyLCBQUk9KRUNUX0NPTlRFWFQpO1xuXG4gICAgaWYgKHVzZXJDb25maWcuZ2V0KFsnYnVpbGQnXSkpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICdCdWlsZEtleUluVXNlckNvbmZpZycsXG4gICAgICAgICdUaGUgYGJ1aWxkYCBrZXkgY2Fubm90IGJlIHNwZWNpZmllZCBpbiB0aGUgdXNlciBjb25maWcgKH4vLmNkay5qc29uKSwgc3BlY2lmeSBpdCBpbiB0aGUgcHJvamVjdCBjb25maWcgKGNkay5qc29uKSBpbnN0ZWFkJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgY29udGV4dFNvdXJjZXMgPSBbXG4gICAgICB7IGJhZzogdGhpcy5jb21tYW5kTGluZUNvbnRleHQgfSxcbiAgICAgIHtcbiAgICAgICAgZmlsZU5hbWU6IFBST0pFQ1RfQ09ORklHLFxuICAgICAgICBiYWc6IHRoaXMucHJvamVjdENvbmZpZy5zdWJTZXR0aW5ncyhbQ09OVEVYVF9LRVldKS5tYWtlUmVhZE9ubHkoKSxcbiAgICAgIH0sXG4gICAgICB7IGZpbGVOYW1lOiBQUk9KRUNUX0NPTlRFWFQsIGJhZzogdGhpcy5wcm9qZWN0Q29udGV4dCB9LFxuICAgIF07XG4gICAgaWYgKHJlYWRVc2VyQ29udGV4dCkge1xuICAgICAgY29udGV4dFNvdXJjZXMucHVzaCh7XG4gICAgICAgIGZpbGVOYW1lOiBVU0VSX0RFRkFVTFRTLFxuICAgICAgICBiYWc6IHVzZXJDb25maWcuc3ViU2V0dGluZ3MoW0NPTlRFWFRfS0VZXSkubWFrZVJlYWRPbmx5KCksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnRleHQgPSBuZXcgQ29udGV4dCguLi5jb250ZXh0U291cmNlcyk7XG4gICAgdGhpcy5jb250ZXh0RmlsZUJhZ3MgPSBjb250ZXh0U291cmNlcy5maWx0ZXIoKHMpOiBzIGlzIHsgZmlsZU5hbWU6IHN0cmluZzsgYmFnOiBTZXR0aW5ncyB9ID0+IHMuZmlsZU5hbWUgIT0gbnVsbCk7XG5cbiAgICAvLyBCdWlsZCBzZXR0aW5ncyBmcm9tIHdoYXQncyBsZWZ0XG4gICAgY29uc3QgbWVyZ2VkU2V0dGluZ3MgPSB0aGlzLmRlZmF1bHRDb25maWdcbiAgICAgIC5tZXJnZSh1c2VyQ29uZmlnKVxuICAgICAgLm1lcmdlKHRoaXMucHJvamVjdENvbmZpZylcbiAgICAgIC5tZXJnZSh0aGlzLmNvbW1hbmRMaW5lQXJndW1lbnRzKTtcblxuICAgIC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5OiBhIGBkZWJ1ZzogdHJ1ZWAgaW4gYSBjb25maWcgZmlsZSAoY2RrLmpzb24gLyB+Ly5jZGsuanNvbilcbiAgICAvLyBpbXBsaWVzIGJvdGggZGVidWcgdGFyZ2V0cywgbWlycm9yaW5nIHRoZSBgLS1kZWJ1Z2AgQ0xJIGZsYWcuXG4gICAgaWYgKG1lcmdlZFNldHRpbmdzLmdldChbJ2RlYnVnJ10pKSB7XG4gICAgICBtZXJnZWRTZXR0aW5ncy5zZXQoWydkZWJ1Z0FwcCddLCB0cnVlKTtcbiAgICAgIG1lcmdlZFNldHRpbmdzLnNldChbJ2RlYnVnQ2xpJ10sIHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0dGluZ3MgPSBtZXJnZWRTZXR0aW5ncy5tYWtlUmVhZE9ubHkoKTtcblxuICAgIGF3YWl0IHRoaXMuaW9IZWxwZXIuZGVmYXVsdHMuZGVidWcoJ21lcmdlZCBzZXR0aW5nczonLCB0aGlzLnNldHRpbmdzLmFsbCk7XG5cbiAgICB0aGlzLmxvYWRlZCA9IHRydWU7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTYXZlIHRoZSBwcm9qZWN0IGNvbnRleHRcbiAgICovXG4gIHB1YmxpYyBhc3luYyBzYXZlQ29udGV4dCgpOiBQcm9taXNlPHRoaXM+IHtcbiAgICBpZiAoIXRoaXMubG9hZGVkKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IC8vIEF2b2lkIG92ZXJ3cml0aW5nIGZpbGVzIHdpdGggbm90aGluZ1xuXG4gICAgYXdhaXQgdGhpcy5wcm9qZWN0Q29udGV4dC5zYXZlKFBST0pFQ1RfQ09OVEVYVCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBsb2FkQW5kTG9nKGlvSGVscGVyOiBJb0hlbHBlciwgZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8U2V0dGluZ3M+IHtcbiAgY29uc3QgcmV0ID0gYXdhaXQgc2V0dGluZ3NGcm9tRmlsZShpb0hlbHBlciwgZmlsZU5hbWUpO1xuICBpZiAoIXJldC5lbXB0eSkge1xuICAgIGF3YWl0IGlvSGVscGVyLmRlZmF1bHRzLmRlYnVnKGZpbGVOYW1lICsgJzonLCBKU09OLnN0cmluZ2lmeShyZXQuYWxsLCB1bmRlZmluZWQsIDIpKTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXR0aW5nc0Zyb21GaWxlKGlvSGVscGVyOiBJb0hlbHBlciwgZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8U2V0dGluZ3M+IHtcbiAgbGV0IHNldHRpbmdzO1xuICBjb25zdCBleHBhbmRlZCA9IGV4cGFuZEhvbWVEaXIoZmlsZU5hbWUpO1xuICBpZiAoYXdhaXQgZnMucGF0aEV4aXN0cyhleHBhbmRlZCkpIHtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgZnMucmVhZEpzb24oZXhwYW5kZWQpO1xuICAgIHNldHRpbmdzID0gbmV3IFNldHRpbmdzKGRhdGEpO1xuICB9IGVsc2Uge1xuICAgIHNldHRpbmdzID0gbmV3IFNldHRpbmdzKCk7XG4gIH1cblxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy81OVxuICBwcm9oaWJpdENvbnRleHRLZXlzKHNldHRpbmdzLCBbJ2RlZmF1bHQtYWNjb3VudCcsICdkZWZhdWx0LXJlZ2lvbiddLCBmaWxlTmFtZSk7XG4gIGF3YWl0IHdhcm5BYm91dENvbnRleHRLZXkoaW9IZWxwZXIsIHNldHRpbmdzLCAnYXdzOicsIGZpbGVOYW1lKTtcblxuICByZXR1cm4gc2V0dGluZ3M7XG59XG5cbmZ1bmN0aW9uIHByb2hpYml0Q29udGV4dEtleXMoc2V0dGluZ3M6IFNldHRpbmdzLCBrZXlzOiBzdHJpbmdbXSwgZmlsZU5hbWU6IHN0cmluZykge1xuICBjb25zdCBjb250ZXh0ID0gc2V0dGluZ3MuZ2V0KFsnY29udGV4dCddKTtcbiAgaWYgKCFjb250ZXh0IHx8IHR5cGVvZiBjb250ZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICBpZiAoa2V5IGluIGNvbnRleHQpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICdVbnN1cHBvcnRlZENvbnRleHRLZXknLFxuICAgICAgICBgVGhlICdjb250ZXh0LiR7a2V5fScga2V5IHdhcyBmb3VuZCBpbiAke2ZzX3BhdGgucmVzb2x2ZShcbiAgICAgICAgICBmaWxlTmFtZSxcbiAgICAgICAgKX0sIGJ1dCBpdCBpcyBubyBsb25nZXIgc3VwcG9ydGVkLiBQbGVhc2UgcmVtb3ZlIGl0LmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB3YXJuQWJvdXRDb250ZXh0S2V5KGlvSGVscGVyOiBJb0hlbHBlciwgc2V0dGluZ3M6IFNldHRpbmdzLCBwcmVmaXg6IHN0cmluZywgZmlsZU5hbWU6IHN0cmluZykge1xuICBjb25zdCBjb250ZXh0ID0gc2V0dGluZ3MuZ2V0KFsnY29udGV4dCddKTtcbiAgaWYgKCFjb250ZXh0IHx8IHR5cGVvZiBjb250ZXh0ICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAoY29uc3QgY29udGV4dEtleSBvZiBPYmplY3Qua2V5cyhjb250ZXh0KSkge1xuICAgIGlmIChjb250ZXh0S2V5LnN0YXJ0c1dpdGgocHJlZml4KSkge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMud2FybmluZyhcbiAgICAgICAgYEEgcmVzZXJ2ZWQgY29udGV4dCBrZXkgKCdjb250ZXh0LiR7cHJlZml4fScpIGtleSB3YXMgZm91bmQgaW4gJHtmc19wYXRoLnJlc29sdmUoXG4gICAgICAgICAgZmlsZU5hbWUsXG4gICAgICAgICl9LCBpdCBtaWdodCBjYXVzZSBzdXJwcmlzaW5nIGJlaGF2aW9yIGFuZCBzaG91bGQgYmUgcmVtb3ZlZC5gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZXhwYW5kSG9tZURpcih4OiBzdHJpbmcpIHtcbiAgaWYgKHguc3RhcnRzV2l0aCgnficpKSB7XG4gICAgcmV0dXJuIGZzX3BhdGguam9pbihvcy5ob21lZGlyKCksIHguc2xpY2UoMSkpO1xuICB9XG4gIHJldHVybiB4O1xufVxuXG4vKipcbiAqIFBhcnNlIENMSSBhcmd1bWVudHMgaW50byBTZXR0aW5nc1xuICpcbiAqIENMSSBhcmd1bWVudHMgaW4gbXVzdCBiZSBhY2Nlc3NlZCBpbiB0aGUgQ0xJIGNvZGUgdmlhXG4gKiBgY29uZmlndXJhdGlvbi5zZXR0aW5ncy5nZXQoWydhcmdOYW1lJ10pYCBpbnN0ZWFkIG9mIHZpYSBgYXJncy5hcmdOYW1lYC5cbiAqXG4gKiBUaGUgYWR2YW50YWdlIGlzIHRoYXQgdGhleSBjYW4gYmUgY29uZmlndXJlZCB2aWEgYGNkay5qc29uYCBhbmRcbiAqIGAkSE9NRS8uY2RrLmpzb25gLiBBcmd1bWVudHMgbm90IGxpc3RlZCBiZWxvdyBhbmQgYWNjZXNzZWQgdmlhIHRoaXMgb2JqZWN0XG4gKiBjYW4gb25seSBiZSBzcGVjaWZpZWQgb24gdGhlIGNvbW1hbmQgbGluZS5cbiAqXG4gKiBAcGFyYW0gYXJndiAtIHRoZSByZWNlaXZlZCBDTEkgYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBuZXcgU2V0dGluZ3Mgb2JqZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29tbWFuZExpbmVBcmd1bWVudHNUb1NldHRpbmdzKGlvSGVscGVyOiBJb0hlbHBlciwgYXJndjogQXJndW1lbnRzKTogUHJvbWlzZTxTZXR0aW5ncz4ge1xuICBjb25zdCBjb250ZXh0ID0gYXdhaXQgcGFyc2VTdHJpbmdDb250ZXh0TGlzdFRvT2JqZWN0KGlvSGVscGVyLCBhcmd2KTtcbiAgY29uc3QgdGFncyA9IGF3YWl0IHBhcnNlU3RyaW5nVGFnc0xpc3RUb09iamVjdChpb0hlbHBlciwgZXhwZWN0U3RyaW5nTGlzdChhcmd2LnRhZ3MpKTtcblxuICAvLyBEZXRlcm1pbmUgYnVuZGxpbmcgc3RhY2tzXG4gIGxldCBidW5kbGluZ1N0YWNrczogc3RyaW5nW107XG4gIGlmIChCVU5ETElOR19DT01NQU5EUy5pbmNsdWRlcyhhcmd2Ll9bMF0pKSB7XG4gICAgLy8gSWYgd2UgZGVwbG95LCBkaWZmLCBzeW50aCBvciB3YXRjaCBhIGxpc3Qgb2Ygc3RhY2tzIGV4Y2x1c2l2ZWx5IHdlIHNraXBcbiAgICAvLyBidW5kbGluZyBmb3IgYWxsIG90aGVyIHN0YWNrcy5cbiAgICBidW5kbGluZ1N0YWNrcyA9IGFyZ3YuZXhjbHVzaXZlbHkgPyBhcmd2LlNUQUNLUyA/PyBbJyoqJ10gOiBbJyoqJ107XG4gIH0gZWxzZSB7XG4gICAgLy8gU2tpcCBidW5kbGluZyBmb3IgYWxsIHN0YWNrc1xuICAgIGJ1bmRsaW5nU3RhY2tzID0gW107XG4gIH1cblxuICByZXR1cm4gbmV3IFNldHRpbmdzKHtcbiAgICBhcHA6IGFyZ3YuYXBwLFxuICAgIGJyb3dzZXI6IGFyZ3YuYnJvd3NlcixcbiAgICBidWlsZDogYXJndi5idWlsZCxcbiAgICBjYUJ1bmRsZVBhdGg6IGFyZ3YuY2FCdW5kbGVQYXRoLFxuICAgIGNvbnRleHQsXG4gICAgLy8gVGhlIGAtLWRlYnVnYCBpbXBsaWNhdGlvbiAoYm90aCBkZWJ1ZyB0YXJnZXRzKSBpcyByZXNvbHZlZCBkdXJpbmcgYXJndW1lbnRcbiAgICAvLyBwYXJzaW5nLCBzbyBoZXJlIHdlIG9ubHkgcmVhZCB0aGUgcmVzb2x2ZWQgcGVyLXRhcmdldCBmbGFncy5cbiAgICBkZWJ1Z0FwcDogYXJndi5kZWJ1Z0FwcCxcbiAgICBkZWJ1Z0NsaTogYXJndi5kZWJ1Z0NsaSxcbiAgICB2ZXJib3NlOiBhcmd2LnZlcmJvc2UsXG4gICAgdGFncyxcbiAgICBsYW5ndWFnZTogYXJndi5sYW5ndWFnZSxcbiAgICBwYXRoTWV0YWRhdGE6IGFyZ3YucGF0aE1ldGFkYXRhLFxuICAgIGFzc2V0TWV0YWRhdGE6IGFyZ3YuYXNzZXRNZXRhZGF0YSxcbiAgICB2YWxpZGF0aW9uOiBhcmd2LnZhbGlkYXRpb24sXG4gICAgcHJvZmlsZTogYXJndi5wcm9maWxlLFxuICAgIHJlZ2lvbjogYXJndi5yZWdpb24sXG4gICAgcGx1Z2luOiBhcmd2LnBsdWdpbixcbiAgICByZXF1aXJlQXBwcm92YWw6IGFyZ3YucmVxdWlyZUFwcHJvdmFsLFxuICAgIHRvb2xraXRTdGFja05hbWU6IGFyZ3YudG9vbGtpdFN0YWNrTmFtZSxcbiAgICB0b29sa2l0QnVja2V0OiB7XG4gICAgICBidWNrZXROYW1lOiBhcmd2LmJvb3RzdHJhcEJ1Y2tldE5hbWUsXG4gICAgICBrbXNLZXlJZDogYXJndi5ib290c3RyYXBLbXNLZXlJZCxcbiAgICB9LFxuICAgIHZlcnNpb25SZXBvcnRpbmc6IGFyZ3YudmVyc2lvblJlcG9ydGluZyxcbiAgICBzdGFnaW5nOiBhcmd2LnN0YWdpbmcsXG4gICAgb3V0cHV0OiBhcmd2Lm91dHB1dCxcbiAgICBvdXRwdXRzRmlsZTogYXJndi5vdXRwdXRzRmlsZSxcbiAgICBwcm9ncmVzczogYXJndi5wcm9ncmVzcyxcbiAgICBwcm94eTogYXJndi5wcm94eSxcbiAgICBidW5kbGluZ1N0YWNrcyxcbiAgICBsb29rdXBzOiBhcmd2Lmxvb2t1cHMsXG4gICAgcm9sbGJhY2s6IGFyZ3Yucm9sbGJhY2ssXG4gICAgbm90aWNlczogYXJndi5ub3RpY2VzLFxuICAgIGFzc2V0UGFyYWxsZWxpc206IGFyZ3ZbJ2Fzc2V0LXBhcmFsbGVsaXNtJ10sXG4gICAgYXNzZXRCdWlsZENvbmN1cnJlbmN5OiBhcmd2Wydhc3NldC1idWlsZC1jb25jdXJyZW5jeSddLFxuICAgIGFzc2V0UHJlYnVpbGQ6IGFyZ3ZbJ2Fzc2V0LXByZWJ1aWxkJ10sXG4gICAgaWdub3JlTm9TdGFja3M6IGFyZ3ZbJ2lnbm9yZS1uby1zdGFja3MnXSxcbiAgICBob3Rzd2FwOiB7XG4gICAgICBlY3M6IHtcbiAgICAgICAgbWluaW11bUhlYWx0aHlQZXJjZW50OiBhcmd2LmhvdHN3YXBFY3NNaW5pbXVtSGVhbHRoeVBlcmNlbnQsXG4gICAgICAgIG1heGltdW1IZWFsdGh5UGVyY2VudDogYXJndi5ob3Rzd2FwRWNzTWF4aW11bUhlYWx0aHlQZXJjZW50LFxuICAgICAgICBzdGFiaWxpemF0aW9uVGltZW91dFNlY29uZHM6IGFyZ3YuaG90c3dhcEVjc1N0YWJpbGl6YXRpb25UaW1lb3V0U2Vjb25kcyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB1bnN0YWJsZTogYXJndi51bnN0YWJsZSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGV4cGVjdFN0cmluZ0xpc3QoeDogdW5rbm93bik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKCFBcnJheS5pc0FycmF5KHgpKSB7XG4gICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignRXhwZWN0ZWRBcnJheScsIGBFeHBlY3RlZCBhcnJheSwgZ290ICcke3h9J2ApO1xuICB9XG4gIGNvbnN0IG5vblN0cmluZ3MgPSB4LmZpbHRlcigoZSkgPT4gdHlwZW9mIGUgIT09ICdzdHJpbmcnKTtcbiAgaWYgKG5vblN0cmluZ3MubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0V4cGVjdGVkU3RyaW5nTGlzdCcsIGBFeHBlY3RlZCBsaXN0IG9mIHN0cmluZ3MsIGZvdW5kICR7bm9uU3RyaW5nc31gKTtcbiAgfVxuICByZXR1cm4geDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcGFyc2VTdHJpbmdDb250ZXh0TGlzdFRvT2JqZWN0KGlvSGVscGVyOiBJb0hlbHBlciwgYXJndjogQXJndW1lbnRzKTogUHJvbWlzZTxhbnk+IHtcbiAgY29uc3QgY29udGV4dDogYW55ID0ge307XG5cbiAgZm9yIChjb25zdCBhc3NpZ25tZW50IG9mIChhcmd2IGFzIGFueSkuY29udGV4dCB8fCBbXSkge1xuICAgIGNvbnN0IHBhcnRzID0gYXNzaWdubWVudC5zcGxpdCgvPSguKikvLCAyKTtcbiAgICBpZiAocGFydHMubGVuZ3RoID09PSAyKSB7XG4gICAgICBhd2FpdCBpb0hlbHBlci5kZWZhdWx0cy5kZWJ1ZygnQ0xJIGFyZ3VtZW50IGNvbnRleHQ6ICVzPSVzJywgcGFydHNbMF0sIHBhcnRzWzFdKTtcbiAgICAgIGlmIChwYXJ0c1swXS5tYXRjaCgvXmF3czouKy8pKSB7XG4gICAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoXG4gICAgICAgICAgJ1Jlc2VydmVkQ29udGV4dFByZWZpeCcsXG4gICAgICAgICAgYFVzZXItcHJvdmlkZWQgY29udGV4dCBjYW5ub3QgdXNlIGtleXMgcHJlZml4ZWQgd2l0aCAnYXdzOicsIGJ1dCAke3BhcnRzWzBdfSB3YXMgcHJvdmlkZWQuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnRleHRbcGFydHNbMF1dID0gcGFydHNbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IGlvSGVscGVyLmRlZmF1bHRzLndhcm4oXG4gICAgICAgICdDb250ZXh0IGFyZ3VtZW50IGlzIG5vdCBhbiBhc3NpZ25tZW50IChrZXk9dmFsdWUpOiAlcycsXG4gICAgICAgIGFzc2lnbm1lbnQsXG4gICAgICApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY29udGV4dDtcbn1cblxuLyoqXG4gKiBQYXJzZSB0YWdzIG91dCBvZiBhcmd1bWVudHNcbiAqXG4gKiBSZXR1cm4gdW5kZWZpbmVkIGlmIG5vIHRhZ3Mgd2VyZSBwcm92aWRlZCwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG9ubHkgZW1wdHlcbiAqIHN0cmluZ3Mgd2VyZSBwcm92aWRlZFxuICovXG5hc3luYyBmdW5jdGlvbiBwYXJzZVN0cmluZ1RhZ3NMaXN0VG9PYmplY3QoXG4gIGlvSGVscGVyOiBJb0hlbHBlcixcbiAgYXJnVGFnczogc3RyaW5nW10gfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPFRhZ1tdIHwgdW5kZWZpbmVkPiB7XG4gIGlmIChhcmdUYWdzID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGlmIChhcmdUYWdzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgbm9uRW1wdHlUYWdzID0gYXJnVGFncy5maWx0ZXIoKHQpID0+IHQgIT09ICcnKTtcbiAgaWYgKG5vbkVtcHR5VGFncy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCB0YWdzOiBUYWdbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgYXNzaWdubWVudCBvZiBub25FbXB0eVRhZ3MpIHtcbiAgICBjb25zdCBwYXJ0cyA9IGFzc2lnbm1lbnQuc3BsaXQoLz0oLiopLywgMik7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMuZGVidWcoJ0NMSSBhcmd1bWVudCB0YWdzOiAlcz0lcycsIHBhcnRzWzBdLCBwYXJ0c1sxXSk7XG4gICAgICB0YWdzLnB1c2goe1xuICAgICAgICBLZXk6IHBhcnRzWzBdLFxuICAgICAgICBWYWx1ZTogcGFydHNbMV0sXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgaW9IZWxwZXIuZGVmYXVsdHMud2FybignVGFncyBhcmd1bWVudCBpcyBub3QgYW4gYXNzaWdubWVudCAoa2V5PXZhbHVlKTogJXMnLCBhc3NpZ25tZW50KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRhZ3MubGVuZ3RoID4gMCA/IHRhZ3MgOiB1bmRlZmluZWQ7XG59XG4iXX0=