projen
Version:
CDK for software projects
414 lines • 55.2 kB
JavaScript
"use strict";
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 });
const semver = __importStar(require("semver"));
const yargs = __importStar(require("yargs"));
const inventory = __importStar(require("../../inventory"));
const logging = __importStar(require("../../logging"));
const option_hints_1 = require("../../option-hints");
const projects_1 = require("../../projects");
const util_1 = require("../../util");
const exec_1 = require("../../util/exec");
const macros_1 = require("../macros");
const util_2 = require("../util");
class Command {
command = "new [PROJECT-TYPE-NAME] [OPTIONS]";
describe = [
"Creates a new projen project",
"",
"For a complete list of the available options for a specific project type, run:",
"projen new [PROJECT-TYPE-NAME] --help",
].join("\n");
builder(args) {
args.positional("PROJECT-TYPE-NAME", {
describe: "only optional with --from and the external module has only a single project type",
type: "string",
});
args.option("synth", {
type: "boolean",
default: true,
desc: "Synthesize after creating .projenrc.js",
});
args.option("comments", {
type: "boolean",
default: true,
desc: "Include commented out options in .projenrc.js (use --no-comments to disable)",
});
args.option("from", {
type: "string",
alias: "f",
desc: 'External jsii npm module to create project from. Supports any package spec supported by npm (such as "my-pack@^2.0")',
});
args.option("git", {
type: "boolean",
default: true,
desc: "Run `git init` and create an initial commit (use --no-git to disable)",
});
args.example("projen new awscdk-app-ts", 'Creates a new project of built-in type "awscdk-app-ts"');
args.example("projen new --from projen-vue@^2", 'Creates a new project from an external module "projen-vue" with the specified version');
args.example("projen new python --help", 'Shows all options available for the built-in project type "python"');
for (const type of inventory.discover()) {
args.command(type.pjid, type.docs ?? "", {
builder: (cargs) => {
cargs.showHelpOnFail(false);
cargs.strictOptions();
for (const option of type.options ?? []) {
// not all types can be represented in the cli
if (!argTypeSupported(option)) {
continue;
}
const defaultValue = argInitialValue(option);
cargs.option(option.switch, {
group: !option.optional ? "Required:" : "Optional:",
type: argType(option),
description: argDesc(option),
required: !option.optional,
// yargs behaves differently for arrays if the defaultValue property is present or not
...(!option.optional && defaultValue
? { default: defaultValue }
: {}),
});
}
return cargs;
},
handler: (argv) => initProject(process.cwd(), type, argv),
});
}
// Disable strict mode, otherwise the catch-all doesn't work
args.strictCommands(false);
args
.command({
command: "*",
describe: false,
handler,
})
.middleware((argv) => {
// manually set the matched command as the project type
argv.projectTypeName = argv._[1];
}, true);
return args;
}
async handler(args) {
return handler(args);
}
}
async function handler(args) {
try {
// handle --from which means we want to first install a jsii module and then
// create a project defined within this module.
if (args.from) {
args.from = (0, util_1.normalizePersistedPath)(args.from);
return await initProjectFromModule(process.cwd(), args.from, args);
}
// project type is defined but was not matched by yargs, so print the list of supported types
if (args.projectTypeName) {
const types = inventory.discover();
throw new util_2.CliError(`Project type "${args.projectTypeName}" not found. Available types:\n`, ...types.map((t) => ` ${t.pjid}`), "", `Please specify a project type.`, `Example: pnpm dlx projen new ${types[0].pjid}`);
}
// Handles the use case that nothing was specified since PROJECT-TYPE is now an optional positional parameter
yargs.showHelp();
}
catch (error) {
if (error instanceof util_2.CliError) {
logging.error(error.message);
logging.empty();
process.exitCode = 1;
return;
}
// unknown error, likely a node runtime exception in project code
// rethrow so the full stack trace is displayed
throw error;
}
}
/**
* Returns the yargs option type for a given project option
*/
function argType(option) {
if (option.kind === "enum") {
return "string";
}
if (isPrimitiveArrayOption(option)) {
return "array";
}
return option.simpleType;
}
/**
* Returns the description for a given project option
*/
function argDesc(option) {
let desc = [option.docs?.replace(/\ *\.$/, "") ?? ""];
const helpDefault = option.initialValue ?? option.default;
if (option.optional && helpDefault) {
desc.push(`[default: ${helpDefault.replace(/^\ *-/, "").replace(/\.$/, "").trim()}]`);
}
return desc.join(" ");
}
/**
* Compute the initial value for a given project option
*/
function argInitialValue(option, cwd = process.cwd()) {
// if we have determined an initial value for the field
// we can show that value in --help
if (option.initialValue) {
return renderDefault(cwd, option.initialValue);
}
}
/**
* Currently we only support these field types as command line options:
* - primitives (string, number, boolean)
* - lists of primitives
* - enums
*/
function argTypeSupported(option) {
return (option.simpleType === "string" ||
option.simpleType === "number" ||
option.simpleType === "boolean" ||
option.kind === "enum" ||
isPrimitiveArrayOption(option));
}
/**
* Checks if the given option is a primitive array
*/
function isPrimitiveArrayOption(option) {
return Boolean(option.jsonLike &&
option.type.collection?.kind === "array" &&
option.type.collection.elementtype.primitive &&
["string", "number"].includes(option.type.collection.elementtype.primitive));
}
/**
* Given a value from "@default", processes macros and returns a stringified
* (quoted) result.
*
* @returns a javascript primitive (could be a string, number or boolean)
*/
function renderDefault(cwd, value) {
return (0, macros_1.tryProcessMacro)(cwd, value) ?? JSON.parse(value);
}
/**
* Converts yargs command line switches to project type props.
* @param type Project type
* @param argv Command line switches
*/
function commandLineToProps(cwd, type, argv) {
const props = {};
// initialize props with default values
for (const prop of type.options) {
props[prop.name] = argInitialValue(prop, cwd);
}
for (const [arg, value] of Object.entries(argv)) {
for (const prop of type.options) {
if (prop.switch === arg) {
let curr = props;
const queue = [...prop.path];
while (true) {
const p = queue.shift();
if (!p) {
break;
}
if (queue.length === 0) {
curr[p] = value;
}
else {
curr[p] = curr[p] ?? {};
curr = curr[p];
}
}
}
}
}
return props;
}
/**
* Generates a new project from an external module.
*
* @param spec The name of the external module to load
* @param args Command line arguments (incl. project type)
*/
async function initProjectFromModule(baseDir, spec, args) {
const projenVersion = args.projenVersion ?? "latest";
const installArgs = (0, util_2.renderInstallArgs)(baseDir, `projen@${projenVersion}`);
if (args.projenVersion) {
await exec_1.npm.run(installArgs, { cwd: baseDir });
}
else {
// do not overwrite an existing installation: only install if `npm ls` fails
try {
await exec_1.npm.run(["ls", `--prefix=${baseDir}`, "--depth=0", "--pattern", "projen"], { cwd: baseDir });
}
catch {
await exec_1.npm.run(installArgs, { cwd: baseDir });
}
}
const installPackageWithCliError = async (b, s) => {
try {
return await (0, util_2.installPackage)(b, s);
}
catch (error) {
const stderr = error?.stderr?.toString() ?? "";
const isLocal = stderr.includes("code ENOENT");
const isRegistry = stderr.includes("code E404");
if (isLocal || isRegistry) {
const moduleSource = isLocal ? "path" : "registry";
throw new util_2.CliError(`Could not find '${s}' in this ${moduleSource}. Please ensure that the package exists, you have access it and try again.`);
}
throw error;
}
};
const moduleName = await installPackageWithCliError(baseDir, spec);
logging.empty();
// Find the just installed package and discover the rest recursively from this package folder
const moduleDir = (0, util_2.findJsiiFilePath)(baseDir, moduleName);
if (!moduleDir) {
throw new util_2.CliError(`Module '${moduleName}' does not look like it is compatible with projen. Reason: Cannot find '${moduleName}/.jsii'. All projen modules must be jsii modules!`);
}
// Only leave projects from the main (requested) package
const projects = inventory
.discover(moduleDir)
.filter((x) => x.moduleName === moduleName); // Only list project types from the requested 'from' module
if (projects.length < 1) {
throw new util_2.CliError(`No project types found after installing "${spec}". The module must export at least one class which extends "projen.Project".`);
}
const requested = args.projectTypeName;
const types = projects.map((p) => p.pjid);
// if user did not specify a project type but the module has more than one, we need them to tell us which one...
if (!requested && projects.length > 1) {
throw new util_2.CliError(`Multiple project types found after installing "${spec}":\n`, ...types.map((t) => ` ${t}`), "", `Please specify a project type.`, `Example: pnpm dlx projen new --from ${spec} ${types[0]}`);
}
// if user did not specify a type (and we know we have only one), the select it. otherwise, search by pjid.
const type = !requested
? projects[0]
: projects.find((p) => p.pjid === requested);
if (!type) {
throw new util_2.CliError(`Project type "${requested}" not found in "${spec}". Found:\n`, ...types.map((t) => ` ${t}`), "", `Please specify a valid project type.`, `Example: pnpm dlx projen new --from ${spec} ${types[0]}`);
}
const missingOptions = [];
for (const option of type.options ?? []) {
// not all types can be represented in the cli
if (!argTypeSupported(option)) {
continue;
}
// parse allowed types
if (args[option.name] !== undefined) {
args[option.name] = parseArg(args[option.name], argType(option), option);
args[option.switch] = args[option.name];
continue;
}
// Required option with a default
if (!option.optional && option.default && option.default !== "undefined") {
const defaultValue = renderDefault(baseDir, option.default);
args[option.name] = defaultValue;
args[option.switch] = defaultValue;
}
// Required option, but we could not find a value
if (!option.optional && !args[option.name]) {
missingOptions.push(`--${option.switch} [${argType(option)}] ${argDesc(option)}`);
}
}
// We are missing some required options
if (missingOptions.length) {
throw new util_2.CliError(`Cannot create "${type.fqn}". Missing required option${missingOptions.length > 1 ? "s" : ""}:`, ...missingOptions.map((m) => ` ${m}`));
}
// include a dev dependency for the external module
args.devDeps = [spec];
args["dev-deps"] = [spec];
await initProject(baseDir, type, args);
}
/**
* Parse command line value as option type
*/
function parseArg(value, type, option) {
switch (type) {
case "number":
return parseInt(value);
case "boolean":
return typeof value === "string" ? (0, util_1.isTruthy)(value) : value;
case "array":
if (!Array.isArray(value)) {
value = [value];
}
return value.map((v) => parseArg(v, option?.type.collection?.elementtype.primitive || "string"));
// return value unchanged
case "string":
default:
// if we have an unexpected array, use the first element
if (Array.isArray(value)) {
return value[0];
}
return value;
}
}
/**
* Generates a new project.
* @param type Project type
* @param args Command line arguments
* @param additionalProps Additional parameters to include in .projenrc.js
*/
async function initProject(baseDir, type, args) {
// convert command line arguments to project props using type information
const props = commandLineToProps(baseDir, type, args);
projects_1.Projects.createProject({
dir: props.outdir ?? baseDir,
projectFqn: type.fqn,
projectOptions: props,
optionHints: args.comments
? option_hints_1.InitProjectOptionHints.FEATURED
: option_hints_1.InitProjectOptionHints.NONE,
synth: args.synth,
post: args.post,
});
if (args.git) {
const opts = { cwd: baseDir };
const gitversion = (0, util_1.getGitVersion)(exec_1.git.capture(["--version"], opts));
logging.debug("system using git version ", gitversion);
// `git config init.defaultBranch` and `git init -b` are only available since git 2.28.0
if (gitversion && semver.gte(gitversion, "2.28.0")) {
const defaultGitInitBranch = exec_1.git.tryCapture(["config", "init.defaultBranch"], opts)?.trim() ||
"main";
exec_1.git.run(["init", "-b", defaultGitInitBranch], opts);
exec_1.git.run(["add", "."], opts);
exec_1.git.run(["commit", "--allow-empty", "-m", "chore: project created with projen"], opts);
logging.debug(`default branch name set to ${defaultGitInitBranch}`);
}
else {
exec_1.git.run(["init"], opts);
exec_1.git.run(["add", "."], opts);
exec_1.git.run(["commit", "--allow-empty", "-m", "chore: project created with projen"], opts);
logging.debug("older version of git detected, changed default branch name to main");
exec_1.git.run(["branch", "-M", "main"], opts);
}
}
}
exports.default = new Command();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV3LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jbWRzL25ldy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyw2Q0FBK0I7QUFDL0IsMkRBQTZDO0FBQzdDLHVEQUF5QztBQUN6QyxxREFBNEQ7QUFDNUQsNkNBQTBDO0FBQzFDLHFDQUE2RTtBQUM3RSwwQ0FBMkM7QUFDM0Msc0NBQTRDO0FBQzVDLGtDQUtpQjtBQUVqQixNQUFNLE9BQU87SUFDSyxPQUFPLEdBQUcsbUNBQW1DLENBQUM7SUFDOUMsUUFBUSxHQUFHO1FBQ3pCLDhCQUE4QjtRQUM5QixFQUFFO1FBQ0YsZ0ZBQWdGO1FBQ2hGLHVDQUF1QztLQUN4QyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVOLE9BQU8sQ0FBQyxJQUFnQjtRQUM3QixJQUFJLENBQUMsVUFBVSxDQUFDLG1CQUFtQixFQUFFO1lBQ25DLFFBQVEsRUFDTixrRkFBa0Y7WUFDcEYsSUFBSSxFQUFFLFFBQVE7U0FDZixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtZQUNuQixJQUFJLEVBQUUsU0FBUztZQUNmLE9BQU8sRUFBRSxJQUFJO1lBQ2IsSUFBSSxFQUFFLHdDQUF3QztTQUMvQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRTtZQUN0QixJQUFJLEVBQUUsU0FBUztZQUNmLE9BQU8sRUFBRSxJQUFJO1lBQ2IsSUFBSSxFQUFFLDhFQUE4RTtTQUNyRixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRTtZQUNsQixJQUFJLEVBQUUsUUFBUTtZQUNkLEtBQUssRUFBRSxHQUFHO1lBQ1YsSUFBSSxFQUFFLHNIQUFzSDtTQUM3SCxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsTUFBTSxD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QUcsQ0FDTCxDQUFDLFFBQVEsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLG9DQUFvQyxDQUFDLEVBQ3ZFLElBQUksQ0FDTCxDQUFDO1lBQ0YsT0FBTyxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7YUFBTSxDQUFDO1lBQ04sVUFBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3hCLFVBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDNUIsVUFBRyxDQUFDLEdBQUcsQ0FDTCxDQUFDLFFBQVEsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLG9DQUFvQyxDQUFDLEVBQ3ZFLElBQUksQ0FDTCxDQUFDO1lBQ0YsT0FBTyxDQUFDLEtBQUssQ0FDWCxvRUFBb0UsQ0FDckUsQ0FBQztZQUNGLFVBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFDLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVELGtCQUFlLElBQUksT0FBTyxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBzZW12ZXIgZnJvbSBcInNlbXZlclwiO1xuaW1wb3J0ICogYXMgeWFyZ3MgZnJvbSBcInlhcmdzXCI7XG5pbXBvcnQgKiBhcyBpbnZlbnRvcnkgZnJvbSBcIi4uLy4uL2ludmVudG9yeVwiO1xuaW1wb3J0ICogYXMgbG9nZ2luZyBmcm9tIFwiLi4vLi4vbG9nZ2luZ1wiO1xuaW1wb3J0IHsgSW5pdFByb2plY3RPcHRpb25IaW50cyB9IGZyb20gXCIuLi8uLi9vcHRpb24taGludHNcIjtcbmltcG9ydCB7IFByb2plY3RzIH0gZnJvbSBcIi4uLy4uL3Byb2plY3RzXCI7XG5pbXBvcnQgeyBnZXRHaXRWZXJzaW9uLCBpc1RydXRoeSwgbm9ybWFsaXplUGVyc2lzdGVkUGF0aCB9IGZyb20gXCIuLi8uLi91dGlsXCI7XG5pbXBvcnQgeyBnaXQsIG5wbSB9IGZyb20gXCIuLi8uLi91dGlsL2V4ZWNcIjtcbmltcG9ydCB7IHRyeVByb2Nlc3NNYWNybyB9IGZyb20gXCIuLi9tYWNyb3NcIjtcbmltcG9ydCB7XG4gIENsaUVycm9yLFxuICBmaW5kSnNpaUZpbGVQYXRoLFxuICBpbnN0YWxsUGFja2FnZSxcbiAgcmVuZGVySW5zdGFsbEFyZ3MsXG59IGZyb20gXCIuLi91dGlsXCI7XG5cbmNsYXNzIENvbW1hbmQgaW1wbGVtZW50cyB5YXJncy5Db21tYW5kTW9kdWxlIHtcbiAgcHVibGljIHJlYWRvbmx5IGNvbW1hbmQgPSBcIm5ldyBbUFJPSkVDVC1UWVBFLU5BTUVdIFtPUFRJT05TXVwiO1xuICBwdWJsaWMgcmVhZG9ubHkgZGVzY3JpYmUgPSBbXG4gICAgXCJDcmVhdGVzIGEgbmV3IHByb2plbiBwcm9qZWN0XCIsXG4gICAgXCJcIixcbiAgICBcIkZvciBhIGNvbXBsZXRlIGxpc3Qgb2YgdGhlIGF2YWlsYWJsZSBvcHRpb25zIGZvciBhIHNwZWNpZmljIHByb2plY3QgdHlwZSwgcnVuOlwiLFxuICAgIFwicHJvamVuIG5ldyBbUFJPSkVDVC1UWVBFLU5BTUVdIC0taGVscFwiLFxuICBdLmpvaW4oXCJcXG5cIik7XG5cbiAgcHVibGljIGJ1aWxkZXIoYXJnczogeWFyZ3MuQXJndikge1xuICAgIGFyZ3MucG9zaXRpb25hbChcIlBST0pFQ1QtVFlQRS1OQU1FXCIsIHtcbiAgICAgIGRlc2NyaWJlOlxuICAgICAgICBcIm9ubHkgb3B0aW9uYWwgd2l0aCAtLWZyb20gYW5kIHRoZSBleHRlcm5hbCBtb2R1bGUgaGFzIG9ubHkgYSBzaW5nbGUgcHJvamVjdCB0eXBlXCIsXG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgIH0pO1xuICAgIGFyZ3Mub3B0aW9uKFwic3ludGhcIiwge1xuICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgZGVzYzogXCJTeW50aGVzaXplIGFmdGVyIGNyZWF0aW5nIC5wcm9qZW5yYy5qc1wiLFxuICAgIH0pO1xuICAgIGFyZ3Mub3B0aW9uKFwiY29tbWVudHNcIiwge1xuICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgZGVzYzogXCJJbmNsdWRlIGNvbW1lbnRlZCBvdXQgb3B0aW9ucyBpbiAucHJvamVucmMuanMgKHVzZSAtLW5vLWNvbW1lbnRzIHRvIGRpc2FibGUpXCIsXG4gICAgfSk7XG4gICAgYXJncy5vcHRpb24oXCJmcm9tXCIsIHtcbiAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICBhbGlhczogXCJmXCIsXG4gICAgICBkZXNjOiAnRXh0ZXJuYWwganNpaSBucG0gbW9kdWxlIHRvIGNyZWF0ZSBwcm9qZWN0IGZyb20uIFN1cHBvcnRzIGFueSBwYWNrYWdlIHNwZWMgc3VwcG9ydGVkIGJ5IG5wbSAoc3VjaCBhcyBcIm15LXBhY2tAXjIuMFwiKScsXG4gICAgfSk7XG4gICAgYXJncy5vcHRpb24oXCJnaXRcIiwge1xuICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgZGVzYzogXCJSdW4gYGdpdCBpbml0YCBhbmQgY3JlYXRlIGFuIGluaXRpYWwgY29tbWl0ICh1c2UgLS1uby1naXQgdG8gZGlzYWJsZSlcIixcbiAgICB9KTtcbiAgICBhcmdzLmV4YW1wbGUoXG4gICAgICBcInByb2plbiBuZXcgYXdzY2RrLWFwcC10c1wiLFxuICAgICAgJ0NyZWF0ZXMgYSBuZXcgcHJvamVjdCBvZiBidWlsdC1pbiB0eXBlIFwiYXdzY2RrLWFwcC10c1wiJyxcbiAgICApO1xuICAgIGFyZ3MuZXhhbXBsZShcbiAgICAgIFwicHJvamVuIG5ldyAtLWZyb20gcHJvamVuLXZ1ZUBeMlwiLFxuICAgICAgJ0NyZWF0ZXMgYSBuZXcgcHJvamVjdCBmcm9tIGFuIGV4dGVybmFsIG1vZHVsZSBcInByb2plbi12dWVcIiB3aXRoIHRoZSBzcGVjaWZpZWQgdmVyc2lvbicsXG4gICAgKTtcbiAgICBhcmdzLmV4YW1wbGUoXG4gICAgICBcInByb2plbiBuZXcgcHl0aG9uIC0taGVscFwiLFxuICAgICAgJ1Nob3dzIGFsbCBvcHRpb25zIGF2YWlsYWJsZSBmb3IgdGhlIGJ1aWx0LWluIHByb2plY3QgdHlwZSBcInB5dGhvblwiJyxcbiAgICApO1xuXG4gICAgZm9yIChjb25zdCB0eXBlIG9mIGludmVudG9yeS5kaXNjb3ZlcigpKSB7XG4gICAgICBhcmdzLmNvbW1hbmQodHlwZS5wamlkLCB0eXBlLmRvY3MgPz8gXCJcIiwge1xuICAgICAgICBidWlsZGVyOiAoY2FyZ3MpID0+IHtcbiAgICAgICAgICBjYXJncy5zaG93SGVscE9uRmFpbChmYWxzZSk7XG4gICAgICAgICAgY2FyZ3Muc3RyaWN0T3B0aW9ucygpO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBvcHRpb24gb2YgdHlwZS5vcHRpb25zID8/IFtdKSB7XG4gICAgICAgICAgICAvLyBub3QgYWxsIHR5cGVzIGNhbiBiZSByZXByZXNlbnRlZCBpbiB0aGUgY2xpXG4gICAgICAgICAgICBpZiAoIWFyZ1R5cGVTdXBwb3J0ZWQob3B0aW9uKSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gYXJnSW5pdGlhbFZhbHVlKG9wdGlvbik7XG4gICAgICAgICAgICBjYXJncy5vcHRpb24ob3B0aW9uLnN3aXRjaCwge1xuICAgICAgICAgICAgICBncm91cDogIW9wdGlvbi5vcHRpb25hbCA/IFwiUmVxdWlyZWQ6XCIgOiBcIk9wdGlvbmFsOlwiLFxuICAgICAgICAgICAgICB0eXBlOiBhcmdUeXBlKG9wdGlvbiksXG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBhcmdEZXNjKG9wdGlvbiksXG4gICAgICAgICAgICAgIHJlcXVpcmVkOiAhb3B0aW9uLm9wdGlvbmFsLFxuICAgICAgICAgICAgICAvLyB5YXJncyBiZWhhdmVzIGRpZmZlcmVudGx5IGZvciBhcnJheXMgaWYgdGhlIGRlZmF1bHRWYWx1ZSBwcm9wZXJ0eSBpcyBwcmVzZW50IG9yIG5vdFxuICAgICAgICAgICAgICAuLi4oIW9wdGlvbi5vcHRpb25hbCAmJiBkZWZhdWx0VmFsdWVcbiAgICAgICAgICAgICAgICA/IHsgZGVmYXVsdDogZGVmYXVsdFZhbHVlIH1cbiAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBjYXJncztcbiAgICAgICAgfSxcbiAgICAgICAgaGFuZGxlcjogKGFyZ3YpID0+IGluaXRQcm9qZWN0KHByb2Nlc3MuY3dkKCksIHR5cGUsIGFyZ3YpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gRGlzYWJsZSBzdHJpY3QgbW9kZSwgb3RoZXJ3aXNlIHRoZSBjYXRjaC1hbGwgZG9lc24ndCB3b3JrXG4gICAgYXJncy5zdHJpY3RDb21tYW5kcyhmYWxzZSk7XG4gICAgYXJnc1xuICAgICAgLmNvbW1hbmQoe1xuICAgICAgICBjb21tYW5kOiBcIipcIixcbiAgICAgICAgZGVzY3JpYmU6IGZhbHNlLFxuICAgICAgICBoYW5kbGVyLFxuICAgICAgfSlcbiAgICAgIC5taWRkbGV3YXJlKChhcmd2KSA9PiB7XG4gICAgICAgIC8vIG1hbnVhbGx5IHNldCB0aGUgbWF0Y2hlZCBjb21tYW5kIGFzIHRoZSBwcm9qZWN0IHR5cGVcbiAgICAgICAgYXJndi5wcm9qZWN0VHlwZU5hbWUgPSBhcmd2Ll9bMV07XG4gICAgICB9LCB0cnVlKTtcblxuICAgIHJldHVybiBhcmdzO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGhhbmRsZXIoYXJnczogYW55KSB7XG4gICAgcmV0dXJuIGhhbmRsZXIoYXJncyk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihhcmdzOiBhbnkpIHtcbiAgdHJ5IHtcbiAgICAvLyBoYW5kbGUgLS1mcm9tIHdoaWNoIG1lYW5zIHdlIHdhbnQgdG8gZmlyc3QgaW5zdGFsbCBhIGpzaWkgbW9kdWxlIGFuZCB0aGVuXG4gICAgLy8gY3JlYXRlIGEgcHJvamVjdCBkZWZpbmVkIHdpdGhpbiB0aGlzIG1vZHVsZS5cbiAgICBpZiAoYXJncy5mcm9tKSB7XG4gICAgICBhcmdzLmZyb20gPSBub3JtYWxpemVQZXJzaXN0ZWRQYXRoKGFyZ3MuZnJvbSk7XG5cbiAgICAgIHJldHVybiBhd2FpdCBpbml0UHJvamVjdEZyb21Nb2R1bGUocHJvY2Vzcy5jd2QoKSwgYXJncy5mcm9tLCBhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBwcm9qZWN0IHR5cGUgaXMgZGVmaW5lZCBidXQgd2FzIG5vdCBtYXRjaGVkIGJ5IHlhcmdzLCBzbyBwcmludCB0aGUgbGlzdCBvZiBzdXBwb3J0ZWQgdHlwZXNcbiAgICBpZiAoYXJncy5wcm9qZWN0VHlwZU5hbWUpIHtcbiAgICAgIGNvbnN0IHR5cGVzID0gaW52ZW50b3J5LmRpc2NvdmVyKCk7XG4gICAgICB0aHJvdyBuZXcgQ2xpRXJyb3IoXG4gICAgICAgIGBQcm9qZWN0IHR5cGUgXCIke2FyZ3MucHJvamVjdFR5cGVOYW1lfVwiIG5vdCBmb3VuZC4gQXZhaWxhYmxlIHR5cGVzOlxcbmAsXG4gICAgICAgIC4uLnR5cGVzLm1hcCgodCkgPT4gYCAgICAke3QucGppZH1gKSxcbiAgICAgICAgXCJcIixcbiAgICAgICAgYFBsZWFzZSBzcGVjaWZ5IGEgcHJvamVjdCB0eXBlLmAsXG4gICAgICAgIGBFeGFtcGxlOiBwbnBtIGRseCBwcm9qZW4gbmV3ICR7dHlwZXNbMF0ucGppZH1gLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGVzIHRoZSB1c2UgY2FzZSB0aGF0IG5vdGhpbmcgd2FzIHNwZWNpZmllZCBzaW5jZSBQUk9KRUNULVRZUEUgaXMgbm93IGFuIG9wdGlvbmFsIHBvc2l0aW9uYWwgcGFyYW1ldGVyXG4gICAgeWFyZ3Muc2hvd0hlbHAoKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBDbGlFcnJvcikge1xuICAgICAgbG9nZ2luZy5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgIGxvZ2dpbmcuZW1wdHkoKTtcbiAgICAgIHByb2Nlc3MuZXhpdENvZGUgPSAxO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHVua25vd24gZXJyb3IsIGxpa2VseSBhIG5vZGUgcnVudGltZSBleGNlcHRpb24gaW4gcHJvamVjdCBjb2RlXG4gICAgLy8gcmV0aHJvdyBzbyB0aGUgZnVsbCBzdGFjayB0cmFjZSBpcyBkaXNwbGF5ZWRcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHlhcmdzIG9wdGlvbiB0eXBlIGZvciBhIGdpdmVuIHByb2plY3Qgb3B0aW9uXG4gKi9cbmZ1bmN0aW9uIGFyZ1R5cGUoXG4gIG9wdGlvbjogaW52ZW50b3J5LkludmVudG9yeVByb2plY3RPcHRpb24sXG4pOiBcInN0cmluZ1wiIHwgXCJib29sZWFuXCIgfCBcIm51bWJlclwiIHwgXCJhcnJheVwiIHtcbiAgaWYgKG9wdGlvbi5raW5kID09PSBcImVudW1cIikge1xuICAgIHJldHVybiBcInN0cmluZ1wiO1xuICB9XG5cbiAgaWYgKGlzUHJpbWl0aXZlQXJyYXlPcHRpb24ob3B0aW9uKSkge1xuICAgIHJldHVybiBcImFycmF5XCI7XG4gIH1cblxuICByZXR1cm4gb3B0aW9uLnNpbXBsZVR5cGUgYXMgXCJzdHJpbmdcIiB8IFwiYm9vbGVhblwiIHwgXCJudW1iZXJcIjtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBkZXNjcmlwdGlvbiBmb3IgYSBnaXZlbiBwcm9qZWN0IG9wdGlvblxuICovXG5mdW5jdGlvbiBhcmdEZXNjKG9wdGlvbjogaW52ZW50b3J5LkludmVudG9yeVByb2plY3RPcHRpb24pOiBzdHJpbmcge1xuICBsZXQgZGVzYyA9IFtvcHRpb24uZG9jcz8ucmVwbGFjZSgvXFwgKlxcLiQvLCBcIlwiKSA/PyBcIlwiXTtcblxuICBjb25zdCBoZWxwRGVmYXVsdCA9IG9wdGlvbi5pbml0aWFsVmFsdWUgPz8gb3B0aW9uLmRlZmF1bHQ7XG4gIGlmIChvcHRpb24ub3B0aW9uYWwgJiYgaGVscERlZmF1bHQpIHtcbiAgICBkZXNjLnB1c2goXG4gICAgICBgW2RlZmF1bHQ6ICR7aGVscERlZmF1bHQucmVwbGFjZSgvXlxcICotLywgXCJcIikucmVwbGFjZSgvXFwuJC8sIFwiXCIpLnRyaW0oKX1dYCxcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIGRlc2Muam9pbihcIiBcIik7XG59XG5cbi8qKlxuICogQ29tcHV0ZSB0aGUgaW5pdGlhbCB2YWx1ZSBmb3IgYSBnaXZlbiBwcm9qZWN0IG9wdGlvblxuICovXG5mdW5jdGlvbiBhcmdJbml0aWFsVmFsdWUoXG4gIG9wdGlvbjogaW52ZW50b3J5LkludmVudG9yeVByb2plY3RPcHRpb24sXG4gIGN3ZCA9IHByb2Nlc3MuY3dkKCksXG4pOiBhbnkge1xuICAvLyBpZiB3ZSBoYXZlIGRldGVybWluZWQgYW4gaW5pdGlhbCB2YWx1ZSBmb3IgdGhlIGZpZWxkXG4gIC8vIHdlIGNhbiBzaG93IHRoYXQgdmFsdWUgaW4gLS1oZWxwXG4gIGlmIChvcHRpb24uaW5pdGlhbFZhbHVlKSB7XG4gICAgcmV0dXJuIHJlbmRlckRlZmF1bHQoY3dkLCBvcHRpb24uaW5pdGlhbFZhbHVlKTtcbiAgfVxufVxuXG4vKipcbiAqIEN1cnJlbnRseSB3ZSBvbmx5IHN1cHBvcnQgdGhlc2UgZmllbGQgdHlwZXMgYXMgY29tbWFuZCBsaW5lIG9wdGlvbnM6XG4gKiAtIHByaW1pdGl2ZXMgKHN0cmluZywgbnVtYmVyLCBib29sZWFuKVxuICogLSBsaXN0cyBvZiBwcmltaXRpdmVzXG4gKiAtIGVudW1zXG4gKi9cbmZ1bmN0aW9uIGFyZ1R5cGVTdXBwb3J0ZWQob3B0aW9uOiBpbnZlbnRvcnkuSW52ZW50b3J5UHJvamVjdE9wdGlvbik6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIG9wdGlvbi5zaW1wbGVUeXBlID09PSBcInN0cmluZ1wiIHx8XG4gICAgb3B0aW9uLnNpbXBsZVR5cGUgPT09IFwibnVtYmVyXCIgfHxcbiAgICBvcHRpb24uc2ltcGxlVHlwZSA9PT0gXCJib29sZWFuXCIgfHxcbiAgICBvcHRpb24ua2luZCA9PT0gXCJlbnVtXCIgfHxcbiAgICBpc1ByaW1pdGl2ZUFycmF5T3B0aW9uKG9wdGlvbilcbiAgKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIG9wdGlvbiBpcyBhIHByaW1pdGl2ZSBhcnJheVxuICovXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZUFycmF5T3B0aW9uKFxuICBvcHRpb246IGludmVudG9yeS5JbnZlbnRvcnlQcm9qZWN0T3B0aW9uLFxuKTogYm9vbGVhbiB7XG4gIHJldHVybiBCb29sZWFuKFxuICAgIG9wdGlvbi5qc29uTGlrZSAmJlxuICAgIG9wdGlvbi50eXBlLmNvbGxlY3Rpb24/LmtpbmQgPT09IFwiYXJyYXlcIiAmJlxuICAgIG9wdGlvbi50eXBlLmNvbGxlY3Rpb24uZWxlbWVudHR5cGUucHJpbWl0aXZlICYmXG4gICAgW1wic3RyaW5nXCIsIFwibnVtYmVyXCJdLmluY2x1ZGVzKG9wdGlvbi50eXBlLmNvbGxlY3Rpb24uZWxlbWVudHR5cGUucHJpbWl0aXZlKSxcbiAgKTtcbn1cblxuLyoqXG4gKiBHaXZlbiBhIHZhbHVlIGZyb20gXCJAZGVmYXVsdFwiLCBwcm9jZXNzZXMgbWFjcm9zIGFuZCByZXR1cm5zIGEgc3RyaW5naWZpZWRcbiAqIChxdW90ZWQpIHJlc3VsdC5cbiAqXG4gKiBAcmV0dXJucyBhIGphdmFzY3JpcHQgcHJpbWl0aXZlIChjb3VsZCBiZSBhIHN0cmluZywgbnVtYmVyIG9yIGJvb2xlYW4pXG4gKi9cbmZ1bmN0aW9uIHJlbmRlckRlZmF1bHQoY3dkOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHRyeVByb2Nlc3NNYWNybyhjd2QsIHZhbHVlKSA/PyBKU09OLnBhcnNlKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB5YXJncyBjb21tYW5kIGxpbmUgc3dpdGNoZXMgdG8gcHJvamVjdCB0eXBlIHByb3BzLlxuICogQHBhcmFtIHR5cGUgUHJvamVjdCB0eXBlXG4gKiBAcGFyYW0gYXJndiBDb21tYW5kIGxpbmUgc3dpdGNoZXNcbiAqL1xuZnVuY3Rpb24gY29tbWFuZExpbmVUb1Byb3BzKFxuICBjd2Q6IHN0cmluZyxcbiAgdHlwZTogaW52ZW50b3J5LkludmVudG9yeVByb2plY3RUeXBlLFxuICBhcmd2OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBjb25zdCBwcm9wczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuXG4gIC8vIGluaXRpYWxpemUgcHJvcHMgd2l0aCBkZWZhdWx0IHZhbHVlc1xuICBmb3IgKGNvbnN0IHByb3Agb2YgdHlwZS5vcHRpb25zKSB7XG4gICAgcHJvcHNbcHJvcC5uYW1lXSA9IGFyZ0luaXRpYWxWYWx1ZShwcm9wLCBjd2QpO1xuICB9XG5cbiAgZm9yIChjb25zdCBbYXJnLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYXJndikpIHtcbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgdHlwZS5vcHRpb25zKSB7XG4gICAgICBpZiAocHJvcC5zd2l0Y2ggPT09IGFyZykge1xuICAgICAgICBsZXQgY3VyciA9IHByb3BzO1xuICAgICAgICBjb25zdCBxdWV1ZSA9IFsuLi5wcm9wLnBhdGhdO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIGNvbnN0IHAgPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgIGlmICghcCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGN1cnJbcF0gPSB2YWx1ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3VycltwXSA9IGN1cnJbcF0gPz8ge307XG4gICAgICAgICAgICBjdXJyID0gY3VycltwXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcHJvcHM7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgbmV3IHByb2plY3QgZnJvbSBhbiBleHRlcm5hbCBtb2R1bGUuXG4gKlxuICogQHBhcmFtIHNwZWMgVGhlIG5hbWUgb2YgdGhlIGV4dGVybmFsIG1vZHVsZSB0byBsb2FkXG4gKiBAcGFyYW0gYXJncyBDb21tYW5kIGxpbmUgYXJndW1lbnRzIChpbmNsLiBwcm9qZWN0IHR5cGUpXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluaXRQcm9qZWN0RnJvbU1vZHVsZShiYXNlRGlyOiBzdHJpbmcsIHNwZWM6IHN0cmluZywgYXJnczogYW55KSB7XG4gIGNvbnN0IHByb2plblZlcnNpb24gPSBhcmdzLnByb2plblZlcnNpb24gPz8gXCJsYXRlc3RcIjtcbiAgY29uc3QgaW5zdGFsbEFyZ3MgPSByZW5kZXJJbnN0YWxsQXJncyhiYXNlRGlyLCBgcHJvamVuQCR7cHJvamVuVmVyc2lvbn1gKTtcbiAgaWYgKGFyZ3MucHJvamVuVmVyc2lvbikge1xuICAgIGF3YWl0IG5wbS5ydW4oaW5zdGFsbEFyZ3MsIHsgY3dkOiBiYXNlRGlyIH0pO1xuICB9IGVsc2Uge1xuICAgIC8vIGRvIG5vdCBvdmVyd3JpdGUgYW4gZXhpc3RpbmcgaW5zdGFsbGF0aW9uOiBvbmx5IGluc3RhbGwgaWYgYG5wbSBsc2AgZmFpbHNcbiAgICB0cnkge1xuICAgICAgYXdhaXQgbnBtLnJ1bihcbiAgICAgICAgW1wibHNcIiwgYC0tcHJlZml4PSR7YmFzZURpcn1gLCBcIi0tZGVwdGg9MFwiLCBcIi0tcGF0dGVyblwiLCBcInByb2plblwiXSxcbiAgICAgICAgeyBjd2Q6IGJhc2VEaXIgfSxcbiAgICAgICk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBhd2FpdCBucG0ucnVuKGluc3RhbGxBcmdzLCB7IGN3ZDogYmFzZURpciB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBpbnN0YWxsUGFja2FnZVdpdGhDbGlFcnJvciA9IGFzeW5jIChcbiAgICBiOiBzdHJpbmcsXG4gICAgczogc3RyaW5nLFxuICApOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgaW5zdGFsbFBhY2thZ2UoYiwgcyk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGNvbnN0IHN0ZGVyciA9IChlcnJvciBhcyB7IHN0ZGVycj86IEJ1ZmZlciB9KT8uc3RkZXJyPy50b1N0cmluZygpID8/IFwiXCI7XG4gICAgICBjb25zdCBpc0xvY2FsID0gc3RkZXJyLmluY2x1ZGVzKFwiY29kZSBFTk9FTlRcIik7XG4gICAgICBjb25zdCBpc1JlZ2lzdHJ5ID0gc3RkZXJyLmluY2x1ZGVzKFwiY29kZSBFNDA0XCIpO1xuICAgICAgaWYgKGlzTG9jYWwgfHwgaXNSZWdpc3RyeSkge1xuICAgICAgICBjb25zdCBtb2R1bGVTb3VyY2UgPSBpc0xvY2FsID8gXCJwYXRoXCIgOiBcInJlZ2lzdHJ5XCI7XG4gICAgICAgIHRocm93IG5ldyBDbGlFcnJvcihcbiAgICAgICAgICBgQ291bGQgbm90IGZpbmQgJyR7c30nIGluIHRoaXMgJHttb2R1bGVTb3VyY2V9LiBQbGVhc2UgZW5zdXJlIHRoYXQgdGhlIHBhY2thZ2UgZXhpc3RzLCB5b3UgaGF2ZSBhY2Nlc3MgaXQgYW5kIHRyeSBhZ2Fpbi5gLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgbW9kdWxlTmFtZSA9IGF3YWl0IGluc3RhbGxQYWNrYWdlV2l0aENsaUVycm9yKGJhc2VEaXIsIHNwZWMpO1xuICBsb2dnaW5nLmVtcHR5KCk7XG5cbiAgLy8gRmluZCB0aGUganVzdCBpbnN0YWxsZWQgcGFja2FnZSBhbmQgZGlzY292ZXIgdGhlIHJlc3QgcmVjdXJzaXZlbHkgZnJvbSB0aGlzIHBhY2thZ2UgZm9sZGVyXG4gIGNvbnN0IG1vZHVsZURpciA9IGZpbmRKc2lpRmlsZVBhdGgoYmFzZURpciwgbW9kdWxlTmFtZSk7XG5cbiAgaWYgKCFtb2R1bGVEaXIpIHtcbiAgICB0aHJvdyBuZXcgQ2xpRXJyb3IoXG4gICAgICBgTW9kdWxlICcke21vZHVsZU5hbWV9JyBkb2VzIG5vdCBsb29rIGxpa2UgaXQgaXMgY29tcGF0aWJsZSB3aXRoIHByb2plbi4gUmVhc29uOiBDYW5ub3QgZmluZCAnJHttb2R1bGVOYW1lfS8uanNpaScuIEFsbCBwcm9qZW4gbW9kdWxlcyBtdXN0IGJlIGpzaWkgbW9kdWxlcyFgLFxuICAgICk7XG4gIH1cblxuICAvLyBPbmx5IGxlYXZlIHByb2plY3RzIGZyb20gdGhlIG1haW4gKHJlcXVlc3RlZCkgcGFja2FnZVxuICBjb25zdCBwcm9qZWN0cyA9IGludmVudG9yeVxuICAgIC5kaXNjb3Zlcihtb2R1bGVEaXIpXG4gICAgLmZpbHRlcigoeCkgPT4geC5tb2R1bGVOYW1lID09PSBtb2R1bGVOYW1lKTsgLy8gT25seSBsaXN0IHByb2plY3QgdHlwZXMgZnJvbSB0aGUgcmVxdWVzdGVkICdmcm9tJyBtb2R1bGVcblxuICBpZiAocHJvamVjdHMubGVuZ3RoIDwgMSkge1xuICAgIHRocm93IG5ldyBDbGlFcnJvcihcbiAgICAgIGBObyBwcm9qZWN0IHR5cGVzIGZvdW5kIGFmdGVyIGluc3RhbGxpbmcgXCIke3NwZWN9XCIuIFRoZSBtb2R1bGUgbXVzdCBleHBvcnQgYXQgbGVhc3Qgb25lIGNsYXNzIHdoaWNoIGV4dGVuZHMgXCJwcm9qZW4uUHJvamVjdFwiLmAsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHJlcXVlc3RlZCA9IGFyZ3MucHJvamVjdFR5cGVOYW1lO1xuICBjb25zdCB0eXBlcyA9IHByb2plY3RzLm1hcCgocCkgPT4gcC5wamlkKTtcblxuICAvLyBpZiB1c2VyIGRpZCBub3Qgc3BlY2lmeSBhIHByb2plY3QgdHlwZSBidXQgdGhlIG1vZHVsZSBoYXMgbW9yZSB0aGFuIG9uZSwgd2UgbmVlZCB0aGVtIHRvIHRlbGwgdXMgd2hpY2ggb25lLi4uXG4gIGlmICghcmVxdWVzdGVkICYmIHByb2plY3RzLmxlbmd0aCA+IDEpIHtcbiAgICB0aHJvdyBuZXcgQ2xpRXJyb3IoXG4gICAgICBgTXVsdGlwbGUgcHJvamVjdCB0eXBlcyBmb3VuZCBhZnRlciBpbnN0YWxsaW5nIFwiJHtzcGVjfVwiOlxcbmAsXG4gICAgICAuLi50eXBlcy5tYXAoKHQpID0+IGAgICAgJHt0fWApLFxuICAgICAgXCJcIixcbiAgICAgIGBQbGVhc2Ugc3BlY2lmeSBhIHByb2plY3QgdHlwZS5gLFxuICAgICAgYEV4YW1wbGU6IHBucG0gZGx4IHByb2plbiBuZXcgLS1mcm9tICR7c3BlY30gJHt0eXBlc1swXX1gLFxuICAgICk7XG4gIH1cblxuICAvLyBpZiB1c2VyIGRpZCBub3Qgc3BlY2lmeSBhIHR5cGUgKGFuZCB3ZSBrbm93IHdlIGhhdmUgb25seSBvbmUpLCB0aGUgc2VsZWN0IGl0LiBvdGhlcndpc2UsIHNlYXJjaCBieSBwamlkLlxuICBjb25zdCB0eXBlID0gIXJlcXVlc3RlZFxuICAgID8gcHJvamVjdHNbMF1cbiAgICA6IHByb2plY3RzLmZpbmQoKHApID0+IHAucGppZCA9PT0gcmVxdWVzdGVkKTtcbiAgaWYgKCF0eXBlKSB7XG4gICAgdGhyb3cgbmV3IENsaUVycm9yKFxuICAgICAgYFByb2plY3QgdHlwZSBcIiR7cmVxdWVzdGVkfVwiIG5vdCBmb3VuZCBpbiBcIiR7c3BlY31cIi4gRm91bmQ6XFxuYCxcbiAgICAgIC4uLnR5cGVzLm1hcCgodCkgPT4gYCAgICAke3R9YCksXG4gICAgICBcIlwiLFxuICAgICAgYFBsZWFzZSBzcGVjaWZ5IGEgdmFsaWQgcHJvamVjdCB0eXBlLmAsXG4gICAgICBgRXhhbXBsZTogcG5wbSBkbHggcHJvamVuIG5ldyAtLWZyb20gJHtzcGVjfSAke3R5cGVzWzBdfWAsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IG1pc3NpbmdPcHRpb25zID0gW107XG5cbiAgZm9yIChjb25zdCBvcHRpb24gb2YgdHlwZS5vcHRpb25zID8/IFtdKSB7XG4gICAgLy8gbm90IGFsbCB0eXBlcyBjYW4gYmUgcmVwcmVzZW50ZWQgaW4gdGhlIGNsaVxuICAgIGlmICghYXJnVHlwZVN1cHBvcnRlZChvcHRpb24pKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBwYXJzZSBhbGxvd2VkIHR5cGVzXG4gICAgaWYgKGFyZ3Nbb3B0aW9uLm5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGFyZ3Nbb3B0aW9uLm5hbWVdID0gcGFyc2VBcmcoYXJnc1tvcHRpb24ubmFtZV0sIGFyZ1R5cGUob3B0aW9uKSwgb3B0aW9uKTtcbiAgICAgIGFyZ3Nbb3B0aW9uLnN3aXRjaF0gPSBhcmdzW29wdGlvbi5uYW1lXTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIFJlcXVpcmVkIG9wdGlvbiB3aXRoIGEgZGVmYXVsdFxuICAgIGlmICghb3B0aW9uLm9wdGlvbmFsICYmIG9wdGlvbi5kZWZhdWx0ICYmIG9wdGlvbi5kZWZhdWx0ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSByZW5kZXJEZWZhdWx0KGJhc2VEaXIsIG9wdGlvbi5kZWZhdWx0KTtcbiAgICAgIGFyZ3Nbb3B0aW9uLm5hbWVdID0gZGVmYXVsdFZhbHVlO1xuICAgICAgYXJnc1tvcHRpb24uc3dpdGNoXSA9IGRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICAvLyBSZXF1aXJlZCBvcHRpb24sIGJ1dCB3ZSBjb3VsZCBub3QgZmluZCBhIHZhbHVlXG4gICAgaWYgKCFvcHRpb24ub3B0aW9uYWwgJiYgIWFyZ3Nbb3B0aW9uLm5hbWVdKSB7XG4gICAgICBtaXNzaW5nT3B0aW9ucy5wdXNoKFxuICAgICAgICBgLS0ke29wdGlvbi5zd2l0Y2h9IFske2FyZ1R5cGUob3B0aW9uKX1dICR7YXJnRGVzYyhvcHRpb24pfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIFdlIGFyZSBtaXNzaW5nIHNvbWUgcmVxdWlyZWQgb3B0aW9uc1xuICBpZiAobWlzc2luZ09wdGlvbnMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IENsaUVycm9yKFxuICAgICAgYENhbm5vdCBjcmVhdGUgXCIke3R5cGUuZnFufVwiLiBNaXNzaW5nIHJlcXVpcmVkIG9wdGlvbiR7XG4gICAgICAgIG1pc3NpbmdPcHRpb25zLmxlbmd0aCA+IDEgPyBcInNcIiA6IFwiXCJcbiAgICAgIH06YCxcbiAgICAgIC4uLm1pc3NpbmdPcHRpb25zLm1hcCgobSkgPT4gYCAgICAke219YCksXG4gICAgKTtcbiAgfVxuXG4gIC8vIGluY2x1ZGUgYSBkZXYgZGVwZW5kZW5jeSBmb3IgdGhlIGV4dGVybmFsIG1vZHVsZVxuICBhcmdzLmRldkRlcHMgPSBbc3BlY107XG4gIGFyZ3NbXCJkZXYtZGVwc1wiXSA9IFtzcGVjXTtcblxuICBhd2FpdCBpbml0UHJvamVjdChiYXNlRGlyLCB0eXBlLCBhcmdzKTtcbn1cblxuLyoqXG4gKiBQYXJzZSBjb21tYW5kIGxpbmUgdmFsdWUgYXMgb3B0aW9uIHR5cGVcbiAqL1xuZnVuY3Rpb24gcGFyc2VBcmcoXG4gIHZhbHVlOiBhbnksXG4gIHR5cGU6IHN0cmluZyxcbiAgb3B0aW9uPzogaW52ZW50b3J5LkludmVudG9yeVByb2plY3RPcHRpb24sXG4pOiBhbnkge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICByZXR1cm4gcGFyc2VJbnQodmFsdWUpO1xuICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gaXNUcnV0aHkodmFsdWUpIDogdmFsdWU7XG4gICAgY2FzZSBcImFycmF5XCI6XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlID0gW3ZhbHVlXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZS5tYXAoKHY6IGFueSkgPT5cbiAgICAgICAgcGFyc2VBcmcodiwgb3B0aW9uPy50eXBlLmNvbGxlY3Rpb24/LmVsZW1lbnR0eXBlLnByaW1pdGl2ZSB8fCBcInN0cmluZ1wiKSxcbiAgICAgICk7XG4gICAgLy8gcmV0dXJuIHZhbHVlIHVuY2hhbmdlZFxuICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gaWYgd2UgaGF2ZSBhbiB1bmV4cGVjdGVkIGFycmF5LCB1c2UgdGhlIGZpcnN0IGVsZW1lbnRcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdmFsdWVbMF07XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBuZXcgcHJvamVjdC5cbiAqIEBwYXJhbSB0eXBlIFByb2plY3QgdHlwZVxuICogQHBhcmFtIGFyZ3MgQ29tbWFuZCBsaW5lIGFyZ3VtZW50c1xuICogQHBhcmFtIGFkZGl0aW9uYWxQcm9wcyBBZGRpdGlvbmFsIHBhcmFtZXRlcnMgdG8gaW5jbHVkZSBpbiAucHJvamVucmMuanNcbiAqL1xuYXN5bmMgZnVuY3Rpb24gaW5pdFByb2plY3QoXG4gIGJhc2VEaXI6IHN0cmluZyxcbiAgdHlwZTogaW52ZW50b3J5LkludmVudG9yeVByb2plY3RUeXBlLFxuICBhcmdzOiBhbnksXG4pIHtcbiAgLy8gY29udmVydCBjb21tYW5kIGxpbmUgYXJndW1lbnRzIHRvIHByb2plY3QgcHJvcHMgdXNpbmcgdHlwZSBpbmZvcm1hdGlvblxuICBjb25zdCBwcm9wcyA9IGNvbW1hbmRMaW5lVG9Qcm9wcyhiYXNlRGlyLCB0eXBlLCBhcmdzKTtcblxuICBQcm9qZWN0cy5jcmVhdGVQcm9qZWN0KHtcbiAgICBkaXI6IHByb3BzLm91dGRpciA/PyBiYXNlRGlyLFxuICAgIHByb2plY3RGcW46IHR5cGUuZnFuLFxuICAgIHByb2plY3RPcHRpb25zOiBwcm9wcyxcbiAgICBvcHRpb25IaW50czogYXJncy5jb21tZW50c1xuICAgICAgPyBJbml0UHJvamVjdE9wdGlvbkhpbnRzLkZFQVRVUkVEXG4gICAgICA6IEluaXRQcm9qZWN0T3B0aW9uSGludHMuTk9ORSxcbiAgICBzeW50aDogYXJncy5zeW50aCxcbiAgICBwb3N0OiBhcmdzLnBvc3QsXG4gIH0pO1xuXG4gIGlmIChhcmdzLmdpdCkge1xuICAgIGNvbnN0IG9wdHMgPSB7IGN3ZDogYmFzZURpciB9O1xuICAgIGNvbnN0IGdpdHZlcnNpb246IHN0cmluZyA9IGdldEdpdFZlcnNpb24oZ2l0LmNhcHR1cmUoW1wiLS12ZXJzaW9uXCJdLCBvcHRzKSk7XG4gICAgbG9nZ2luZy5kZWJ1ZyhcInN5c3RlbSB1c2luZyBnaXQgdmVyc2lvbiBcIiwgZ2l0dmVyc2lvbik7XG4gICAgLy8gYGdpdCBjb25maWcgaW5pdC5kZWZhdWx0QnJhbmNoYCBhbmQgYGdpdCBpbml0IC1iYCBhcmUgb25seSBhdmFpbGFibGUgc2luY2UgZ2l0IDIuMjguMFxuICAgIGlmIChnaXR2ZXJzaW9uICYmIHNlbXZlci5ndGUoZ2l0dmVyc2lvbiwgXCIyLjI4LjBcIikpIHtcbiAgICAgIGNvbnN0IGRlZmF1bHRHaXRJbml0QnJhbmNoID1cbiAgICAgICAgZ2l0LnRyeUNhcHR1cmUoW1wiY29uZmlnXCIsIFwiaW5pdC5kZWZhdWx0QnJhbmNoXCJdLCBvcHRzKT8udHJpbSgpIHx8XG4gICAgICAgIFwibWFpblwiO1xuICAgICAgZ2l0LnJ1bihbXCJpbml0XCIsIFwiLWJcIiwgZGVmYXVsdEdpdEluaXRCcmFuY2hdLCBvcHRzKTtcbiAgICAgIGdpdC5ydW4oW1wiYWRkXCIsIFwiLlwiXSwgb3B0cyk7XG4gICAgICBnaXQucnVuKFxuICAgICAgICBbXCJjb21taXRcIiwgXCItLWFsbG93LWVtcHR5XCIsIFwiLW1cIiwgXCJjaG9yZTogcHJvamVjdCBjcmVhdGVkIHdpdGggcHJvamVuXCJdLFxuICAgICAgICBvcHRzLFxuICAgICAgKTtcbiAgICAgIGxvZ2dpbmcuZGVidWcoYGRlZmF1bHQgYnJhbmNoIG5hbWUgc2V0IHRvICR7ZGVmYXVsdEdpdEluaXRCcmFuY2h9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdpdC5ydW4oW1wiaW5pdFwiXSwgb3B0cyk7XG4gICAgICBnaXQucnVuKFtcImFkZFwiLCBcIi5cIl0sIG9wdHMpO1xuICAgICAgZ2l0LnJ1bihcbiAgICAgICAgW1wiY29tbWl0XCIsIFwiLS1hbGxvdy1lbXB0eVwiLCBcIi1tXCIsIFwiY2hvcmU6IHByb2plY3QgY3JlYXRlZCB3aXRoIHByb2plblwiXSxcbiAgICAgICAgb3B0cyxcbiAgICAgICk7XG4gICAgICBsb2dnaW5nLmRlYnVnKFxuICAgICAgICBcIm9sZGVyIHZlcnNpb24gb2YgZ2l0IGRldGVjdGVkLCBjaGFuZ2VkIGRlZmF1bHQgYnJhbmNoIG5hbWUgdG8gbWFpblwiLFxuICAgICAgKTtcbiAgICAgIGdpdC5ydW4oW1wiYnJhbmNoXCIsIFwiLU1cIiwgXCJtYWluXCJdLCBvcHRzKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbmV3IENvbW1hbmQoKTtcbiJdfQ==