projen
Version:
CDK for software projects
259 lines • 35.6 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.ModuleImports = void 0;
exports.renderProjenInitOptions = renderProjenInitOptions;
exports.resolveInitProject = resolveInitProject;
exports.renderJavaScriptOptions = renderJavaScriptOptions;
const inventory = __importStar(require("../inventory"));
const option_hints_1 = require("../option-hints");
const PROJEN_NEW = "__new__";
const TAB = makePadding(2);
/**
* Renders options as if the project was created via `projen new` (embeds the __new__ field).
*/
function renderProjenInitOptions(fqn, args, comments = option_hints_1.InitProjectOptionHints.NONE, synth = true, post = true) {
return {
...args,
[PROJEN_NEW]: { fqn, args, comments, synth, post },
};
}
function resolveInitProject(opts) {
const f = opts[PROJEN_NEW];
if (!f) {
return undefined;
}
const type = inventory.resolveProjectType(f.fqn);
if (!type) {
throw new Error(`unable to resolve project type for ${f.fqn}`);
}
return {
args: f.args,
fqn: f.fqn,
type: type,
comments: f.comments,
synth: f.synth ?? true,
post: f.post ?? true,
};
}
class ModuleImports {
imports = new Map();
/**
* Add a named import from a module
*/
add(moduleName, importName) {
const moduleImports = this.imports.get(moduleName) ?? new Set();
moduleImports.add(importName);
this.imports.set(moduleName, moduleImports);
}
/**
* Get all named imports for a module
*/
get(moduleName) {
const moduleImports = this.imports.get(moduleName) ?? new Set();
return Array.from(moduleImports);
}
/**
* Get a list of all used modules
*/
get modules() {
return Array.from(this.imports.keys());
}
/**
* Return all imports as ESM import statements
*/
asEsmImports() {
return this.all().map(([moduleName, namedImports]) => `import { ${[...namedImports].join(", ")} } from "${moduleName}";`);
}
/**
* Return all imports as CJS require statements
*/
asCjsRequire() {
return this.all().map(([moduleName, namedImports]) => `const { ${[...namedImports].join(", ")} } = require("${moduleName}");`);
}
all() {
const allImports = Object.fromEntries(this.imports);
return Object.entries(allImports).map(([key, value]) => [
key,
Array.from(value).sort(),
]);
}
}
exports.ModuleImports = ModuleImports;
/**
* Prints all parameters that can be used in a project type, alongside their descriptions.
*
* Parameters in `params` that aren't undefined are rendered as defaults,
* while all other parameters are rendered as commented out.
*
* Returns the printed output and a set of required imports as an object
* in the form { options, imports }.
*/
function renderJavaScriptOptions(opts) {
const renders = {};
const optionsWithDefaults = [];
const allImports = new ModuleImports();
for (const option of opts.type.options) {
if (option.deprecated) {
continue;
}
const optionName = option.name;
if (opts.args[optionName] !== undefined) {
const arg = opts.args[optionName];
const { js, moduleName, importName } = renderArgAsJavaScript(arg, option);
renders[optionName] = `${optionName}: ${js},`;
optionsWithDefaults.push(optionName);
if (moduleName && importName) {
allImports.add(moduleName, importName);
if (opts.prefixImports) {
const prefix = `${opts.prefixImports}["${moduleName}"].`;
renders[optionName] = `${optionName}: ${prefix}${js},`;
}
}
}
else {
const defaultValue = option.default?.startsWith("-")
? undefined
: (option.default ?? undefined);
renders[optionName] = `// ${optionName}: ${defaultValue},`;
}
}
const bootstrap = opts.bootstrap ?? false;
if (bootstrap) {
for (const arg of opts.omitFromBootstrap ?? []) {
delete opts.args[arg];
}
renders[PROJEN_NEW] = `${PROJEN_NEW}: ${JSON.stringify({
args: opts.args,
fqn: opts.type.fqn,
comments: opts.comments,
synth: opts.synth ?? true,
post: opts.post ?? true,
})},`;
optionsWithDefaults.push(PROJEN_NEW);
}
// generate rendering
const result = [];
result.push("{");
// render options with defaults
optionsWithDefaults.sort();
for (const optionName of optionsWithDefaults) {
result.push(`${TAB}${renders[optionName]}`);
}
if (result.length > 1) {
result.push("");
}
// render options without defaults as comments
if (opts.comments === option_hints_1.InitProjectOptionHints.ALL) {
const options = opts.type.options.filter((opt) => !opt.deprecated && opts.args[opt.name] === undefined);
result.push(...renderCommentedOptionsByModule(renders, options));
}
else if (opts.comments === option_hints_1.InitProjectOptionHints.FEATURED) {
const options = opts.type.options.filter((opt) => !opt.deprecated && opts.args[opt.name] === undefined && opt.featured);
result.push(...renderCommentedOptionsInOrder(renders, options));
}
else if (opts.comments === option_hints_1.InitProjectOptionHints.NONE) {
// don't render any extra options
}
if (result[result.length - 1] === "") {
result.pop();
}
result.push("}");
return { renderedOptions: result.join("\n"), imports: allImports };
}
function renderCommentedOptionsByModule(renders, options) {
const optionsByModule = {};
for (const option of options) {
const parentModule = option.parent;
optionsByModule[parentModule] = optionsByModule[parentModule] ?? [];
optionsByModule[parentModule].push(option);
}
for (const parentModule in optionsByModule) {
optionsByModule[parentModule].sort((o1, o2) => o1.name.localeCompare(o2.name));
}
const result = [];
const marginSize = Math.max(...options.map((opt) => renders[opt.name].length));
for (const [moduleName, optionGroup] of Object.entries(optionsByModule).sort()) {
result.push(`${TAB}/* ${moduleName} */`);
for (const option of optionGroup) {
const paramRender = renders[option.name];
const docstring = option.docs || "No documentation found.";
result.push(`${TAB}${paramRender}${makePadding(marginSize - paramRender.length + 2)}/* ${docstring} */`);
}
result.push("");
}
return result;
}
function renderCommentedOptionsInOrder(renders, options) {
const result = [];
const marginSize = Math.max(...options.map((opt) => renders[opt.name].length));
for (const option of options) {
const paramRender = renders[option.name];
const docstring = option.docs || "No documentation found.";
result.push(`${TAB}${paramRender}${makePadding(marginSize - paramRender.length + 2)}/* ${docstring} */`);
}
return result;
}
/**
* Renders a value as a JavaScript value, converting strings to enums where
* appropriate. The type must be JSON-like (string, number, boolean, array,
* enum, or JSON object).
*
* Returns a JavaScript expression as a string, and the names of any
* necessary imports.
*/
function renderArgAsJavaScript(arg, option) {
if (option.kind === "enum") {
if (!option.fqn) {
throw new Error(`fqn field is missing from enum option ${option.name}`);
}
const parts = option.fqn.split("."); // -> ['projen', 'web', 'MyEnum']
const enumChoice = String(arg).toUpperCase().replace(/-/g, "_"); // custom-value -> CUSTOM_VALUE
const js = `${parts.slice(1).join(".")}.${enumChoice}`; // -> web.MyEnum.CUSTOM_VALUE
const moduleName = parts[0]; // -> projen
const importName = parts[1]; // -> web
return { js, moduleName, importName };
}
else if (option.jsonLike) {
return { js: JSON.stringify(arg) };
}
else {
throw new Error(`Unexpected option ${option.name} - cannot render a value for this option because it does not have a JSON-like type.`);
}
}
function makePadding(paddingLength) {
return " ".repeat(paddingLength);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLW9wdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvamF2YXNjcmlwdC9yZW5kZXItb3B0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFxR0EsMERBV0M7QUFFRCxnREFrQkM7QUFtRUQsMERBc0ZDO0FBN1JELHdEQUEwQztBQUMxQyxrREFBeUQ7QUFFekQsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDO0FBQzdCLE1BQU0sR0FBRyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQThGM0I7O0dBRUc7QUFDSCxTQUFnQix1QkFBdUIsQ0FDckMsR0FBVyxFQUNYLElBQXlCLEVBQ3pCLFdBQW1DLHFDQUFzQixDQUFDLElBQUksRUFDOUQsUUFBaUIsSUFBSSxFQUNyQixPQUFnQixJQUFJO0lBRXBCLE9BQU87UUFDTCxHQUFHLElBQUk7UUFDUCxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBZ0I7S0FDakUsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFnQixrQkFBa0IsQ0FBQyxJQUFTO0lBQzFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQWUsQ0FBQztJQUN6QyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDUCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBQ0QsT0FBTztRQUNMLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSTtR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L2ludmVudG9yeVwiO1xuaW1wb3J0IHsgSW5pdFByb2plY3RPcHRpb25IaW50cyB9IGZyb20gXCIuLi9vcHRpb24taGludHNcIjtcblxuY29uc3QgUFJPSkVOX05FVyA9IFwiX19uZXdfX1wiO1xuY29uc3QgVEFCID0gbWFrZVBhZGRpbmcoMik7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYHJlbmRlclByb2plY3RPcHRpb25zYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW5kZXJQcm9qZWN0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgcHJvamVjdCB0eXBlIHRvIHJlbmRlci5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU6IGludmVudG9yeS5JbnZlbnRvcnlQcm9qZWN0VHlwZTtcblxuICAvKipcbiAgICogUHJvamVjdCBhcmd1bWVudHMgYXMgcGFzc2VkIHRvIGBwcm9qZW4gbmV3YC5cbiAgICovXG4gIHJlYWRvbmx5IGFyZ3M6IFJlY29yZDxzdHJpbmcsIGFueT47XG5cbiAgLyoqXG4gICAqIEluY2x1ZGUgY29tbWVudGVkIG91dCBvcHRpb25zLlxuICAgKiBAZGVmYXVsdCBJbml0UHJvamVjdE9wdGlvbkhpbnRzLkZFQVRVUkVEXG4gICAqL1xuICByZWFkb25seSBjb21tZW50cz86IEluaXRQcm9qZWN0T3B0aW9uSGludHM7XG5cbiAgLyoqXG4gICAqIEluamVjdCBhIGBfX25ld19fYCBhdHRyaWJ1dGUgdG8gdGhlIHByb2plY3QgY29uc3RydWN0b3Igd2l0aCBhIHN0cmluZ2lmaWVkXG4gICAqIHZlcnNpb24gb2YgdGhlIHByb2plY3QgcGFyYW1ldGVycyBhbmQgYSBganNpaUZxbmAgYXR0cmlidXRlIHRoYXQgaW5jbHVkZXNcbiAgICogdGhlIEZRTiBvZiB0aGUgcHJvamVjdCB0eXBlLiBUaGlzIGlzIG5lZWRlZCBpbiBvcmRlciB0byBnZW5lcmF0ZSBpbml0aWFsXG4gICAqIHByb2plbnJjIGZpbGVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgYm9vdHN0cmFwPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIGZpZWxkcyB0byBvbWl0IGZyb20gdGhlIGluaXRpYWwgcHJvamVucmMgZmlsZS5cbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSBvbWl0RnJvbUJvb3RzdHJhcD86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGBwcm9qZW4gbmV3YCB3aWxsIGNhbGwgYHByb2plY3Quc3ludGgoKWAgYWZ0ZXIgY29uc3RydWN0aW9uLlxuICAgKiBFbWJlZGRlZCBpbiB0aGUgYF9fbmV3X19gIGZpZWxkIHNvIGBQcm9qZWN0LnN5bnRoKClgIGNhbiBkZXRlY3QgYC0tbm8tc3ludGhgLlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBzeW50aD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgYHByb2plbiBuZXdgIHdpbGwgcnVuIHBvc3Qtc3ludGhlc2lzIHN0ZXBzIChlLmcuIHBhY2thZ2UgbWFuYWdlciBpbnN0YWxsKS5cbiAgICogRW1iZWRkZWQgaW4gdGhlIGBfX25ld19fYCBmaWVsZCBmb3IgY29tcG9uZW50cyB0aGF0IG5lZWQgdG8ga25vdy5cbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgcG9zdD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFByZWZpeCBhbGwgaW1wb3J0cyB3aXRoIHRoaXMgc3RyaW5nIGFuZCB0aGUgZnVsbCBtb2R1bGUgbmFtZVxuICAgKiBUaGlzIGlzIHJlcXVpcmVkIHdoZW4gZXhlY3V0aW5nIG9wdGlvbnMgY29kZSBpbiBhIHZtXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gb25seSB1c2Ugc3VibW9kdWxlIGFzIHByZWZpeFxuICAgKi9cbiAgcmVhZG9ubHkgcHJlZml4SW1wb3J0cz86IHN0cmluZztcbn1cblxuLyoqXG4gKiBJbmZvcm1hdGlvbiBwYXNzZWQgZnJvbSBgcHJvamVuIG5ld2AgdG8gdGhlIHByb2plY3Qgb2JqZWN0IHdoZW4gdGhlIHByb2plY3RcbiAqIGlzIGZpcnN0IGNyZWF0ZWQuIEl0IGlzIHVzZWQgdG8gZ2VuZXJhdGUgcHJvamVucmMgZmlsZXMgaW4gdmFyaW91cyBsYW5ndWFnZXMuXG4gKi9cbmludGVyZmFjZSBQcm9qZW5Jbml0IHtcbiAgLyoqXG4gICAqIFRoZSBKU0lJIEZRTiBvZiB0aGUgcHJvamVjdCB0eXBlLlxuICAgKi9cbiAgcmVhZG9ubHkgZnFuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEluaXRpYWwgYXJndW1lbnRzIHBhc3NlZCB0byBgcHJvamVuIG5ld2AuXG4gICAqL1xuICByZWFkb25seSBhcmdzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG4gIC8qKlxuICAgKiBJbmNsdWRlIGNvbW1lbnRlZCBvdXQgb3B0aW9ucy4gRG9lcyBub3QgYXBwbHkgdG8gcHJvamVucmMuanNvbiBmaWxlcy5cbiAgICovXG4gIHJlYWRvbmx5IGNvbW1lbnRzOiBJbml0UHJvamVjdE9wdGlvbkhpbnRzO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGBwcm9qZW4gbmV3YCB3aWxsIGNhbGwgYHByb2plY3Quc3ludGgoKWAgYWZ0ZXIgY29uc3RydWN0aW9uLlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBzeW50aDogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciBgcHJvamVuIG5ld2Agd2lsbCBydW4gcG9zdC1zeW50aGVzaXMgc3RlcHMgKGUuZy4gcGFja2FnZSBtYW5hZ2VyIGluc3RhbGwpLlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBwb3N0OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgb3B0aW9ucyBhcyBpZiB0aGUgcHJvamVjdCB3YXMgY3JlYXRlZCB2aWEgYHByb2plbiBuZXdgIChlbWJlZHMgdGhlIF9fbmV3X18gZmllbGQpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyUHJvamVuSW5pdE9wdGlvbnMoXG4gIGZxbjogc3RyaW5nLFxuICBhcmdzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBjb21tZW50czogSW5pdFByb2plY3RPcHRpb25IaW50cyA9IEluaXRQcm9qZWN0T3B0aW9uSGludHMuTk9ORSxcbiAgc3ludGg6IGJvb2xlYW4gPSB0cnVlLFxuICBwb3N0OiBib29sZWFuID0gdHJ1ZSxcbik6IGFueSB7XG4gIHJldHVybiB7XG4gICAgLi4uYXJncyxcbiAgICBbUFJPSkVOX05FV106IHsgZnFuLCBhcmdzLCBjb21tZW50cywgc3ludGgsIHBvc3QgfSBhcyBQcm9qZW5Jbml0LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUluaXRQcm9qZWN0KG9wdHM6IGFueSkge1xuICBjb25zdCBmID0gb3B0c1tQUk9KRU5fTkVXXSBhcyBQcm9qZW5Jbml0O1xuICBpZiAoIWYpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgdHlwZSA9IGludmVudG9yeS5yZXNvbHZlUHJvamVjdFR5cGUoZi5mcW4pO1xuICBpZiAoIXR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHVuYWJsZSB0byByZXNvbHZlIHByb2plY3QgdHlwZSBmb3IgJHtmLmZxbn1gKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGFyZ3M6IGYuYXJncyxcbiAgICBmcW46IGYuZnFuLFxuICAgIHR5cGU6IHR5cGUsXG4gICAgY29tbWVudHM6IGYuY29tbWVudHMsXG4gICAgc3ludGg6IGYuc3ludGggPz8gdHJ1ZSxcbiAgICBwb3N0OiBmLnBvc3QgPz8gdHJ1ZSxcbiAgfTtcbn1cblxuZXhwb3J0IGNsYXNzIE1vZHVsZUltcG9ydHMge1xuICBwcml2YXRlIGltcG9ydHM6IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+PiA9IG5ldyBNYXAoKTtcblxuICAvKipcbiAgICogQWRkIGEgbmFtZWQgaW1wb3J0IGZyb20gYSBtb2R1bGVcbiAgICovXG4gIHB1YmxpYyBhZGQobW9kdWxlTmFtZTogc3RyaW5nLCBpbXBvcnROYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtb2R1bGVJbXBvcnRzID0gdGhpcy5pbXBvcnRzLmdldChtb2R1bGVOYW1lKSA/PyBuZXcgU2V0KCk7XG4gICAgbW9kdWxlSW1wb3J0cy5hZGQoaW1wb3J0TmFtZSk7XG4gICAgdGhpcy5pbXBvcnRzLnNldChtb2R1bGVOYW1lLCBtb2R1bGVJbXBvcnRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIG5hbWVkIGltcG9ydHMgZm9yIGEgbW9kdWxlXG4gICAqL1xuICBwdWJsaWMgZ2V0KG1vZHVsZU5hbWU6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBtb2R1bGVJbXBvcnRzID0gdGhpcy5pbXBvcnRzLmdldChtb2R1bGVOYW1lKSA/PyBuZXcgU2V0KCk7XG4gICAgcmV0dXJuIEFycmF5LmZyb20obW9kdWxlSW1wb3J0cyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgbGlzdCBvZiBhbGwgdXNlZCBtb2R1bGVzXG4gICAqL1xuICBwdWJsaWMgZ2V0IG1vZHVsZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuaW1wb3J0cy5rZXlzKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbGwgaW1wb3J0cyBhcyBFU00gaW1wb3J0IHN0YXRlbWVudHNcbiAgICovXG4gIHB1YmxpYyBhc0VzbUltcG9ydHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmFsbCgpLm1hcChcbiAgICAgIChbbW9kdWxlTmFtZSwgbmFtZWRJbXBvcnRzXSkgPT5cbiAgICAgICAgYGltcG9ydCB7ICR7Wy4uLm5hbWVkSW1wb3J0c10uam9pbihcIiwgXCIpfSB9IGZyb20gXCIke21vZHVsZU5hbWV9XCI7YCxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbGwgaW1wb3J0cyBhcyBDSlMgcmVxdWlyZSBzdGF0ZW1lbnRzXG4gICAqL1xuICBwdWJsaWMgYXNDanNSZXF1aXJlKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5hbGwoKS5tYXAoXG4gICAgICAoW21vZHVsZU5hbWUsIG5hbWVkSW1wb3J0c10pID0+XG4gICAgICAgIGBjb25zdCB7ICR7Wy4uLm5hbWVkSW1wb3J0c10uam9pbihcIiwgXCIpfSB9ID0gcmVxdWlyZShcIiR7bW9kdWxlTmFtZX1cIik7YCxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhbGwoKTogQXJyYXk8W3N0cmluZywgc3RyaW5nW11dPiB7XG4gICAgY29uc3QgYWxsSW1wb3J0cyA9IE9iamVjdC5mcm9tRW50cmllcyh0aGlzLmltcG9ydHMpO1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhhbGxJbXBvcnRzKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW1xuICAgICAga2V5LFxuICAgICAgQXJyYXkuZnJvbSh2YWx1ZSkuc29ydCgpLFxuICAgIF0pO1xuICB9XG59XG5cbi8qKlxuICogUHJpbnRzIGFsbCBwYXJhbWV0ZXJzIHRoYXQgY2FuIGJlIHVzZWQgaW4gYSBwcm9qZWN0IHR5cGUsIGFsb25nc2lkZSB0aGVpciBkZXNjcmlwdGlvbnMuXG4gKlxuICogUGFyYW1ldGVycyBpbiBgcGFyYW1zYCB0aGF0IGFyZW4ndCB1bmRlZmluZWQgYXJlIHJlbmRlcmVkIGFzIGRlZmF1bHRzLFxuICogd2hpbGUgYWxsIG90aGVyIHBhcmFtZXRlcnMgYXJlIHJlbmRlcmVkIGFzIGNvbW1lbnRlZCBvdXQuXG4gKlxuICogUmV0dXJucyB0aGUgcHJpbnRlZCBvdXRwdXQgYW5kIGEgc2V0IG9mIHJlcXVpcmVkIGltcG9ydHMgYXMgYW4gb2JqZWN0XG4gKiBpbiB0aGUgZm9ybSB7IG9wdGlvbnMsIGltcG9ydHMgfS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlckphdmFTY3JpcHRPcHRpb25zKG9wdHM6IFJlbmRlclByb2plY3RPcHRpb25zKToge1xuICByZW5kZXJlZE9wdGlvbnM6IHN0cmluZztcbiAgaW1wb3J0czogTW9kdWxlSW1wb3J0cztcbn0ge1xuICBjb25zdCByZW5kZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGNvbnN0IG9wdGlvbnNXaXRoRGVmYXVsdHM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IGFsbEltcG9ydHMgPSBuZXcgTW9kdWxlSW1wb3J0cygpO1xuXG4gIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdHMudHlwZS5vcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbi5kZXByZWNhdGVkKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25OYW1lID0gb3B0aW9uLm5hbWU7XG5cbiAgICBpZiAob3B0cy5hcmdzW29wdGlvbk5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGFyZyA9IG9wdHMuYXJnc1tvcHRpb25OYW1lXTtcbiAgICAgIGNvbnN0IHsganMsIG1vZHVsZU5hbWUsIGltcG9ydE5hbWUgfSA9IHJlbmRlckFyZ0FzSmF2YVNjcmlwdChhcmcsIG9wdGlvbik7XG5cbiAgICAgIHJlbmRlcnNbb3B0aW9uTmFtZV0gPSBgJHtvcHRpb25OYW1lfTogJHtqc30sYDtcbiAgICAgIG9wdGlvbnNXaXRoRGVmYXVsdHMucHVzaChvcHRpb25OYW1lKTtcblxuICAgICAgaWYgKG1vZHVsZU5hbWUgJiYgaW1wb3J0TmFtZSkge1xuICAgICAgICBhbGxJbXBvcnRzLmFkZChtb2R1bGVOYW1lLCBpbXBvcnROYW1lKTtcbiAgICAgICAgaWYgKG9wdHMucHJlZml4SW1wb3J0cykge1xuICAgICAgICAgIGNvbnN0IHByZWZpeCA9IGAke29wdHMucHJlZml4SW1wb3J0c31bXCIke21vZHVsZU5hbWV9XCJdLmA7XG4gICAgICAgICAgcmVuZGVyc1tvcHRpb25OYW1lXSA9IGAke29wdGlvbk5hbWV9OiAke3ByZWZpeH0ke2pzfSxgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IG9wdGlvbi5kZWZhdWx0Py5zdGFydHNXaXRoKFwiLVwiKVxuICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICA6IChvcHRpb24uZGVmYXVsdCA/PyB1bmRlZmluZWQpO1xuICAgICAgcmVuZGVyc1tvcHRpb25OYW1lXSA9IGAvLyAke29wdGlvbk5hbWV9OiAke2RlZmF1bHRWYWx1ZX0sYDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBib290c3RyYXAgPSBvcHRzLmJvb3RzdHJhcCA/PyBmYWxzZTtcbiAgaWYgKGJvb3RzdHJhcCkge1xuICAgIGZvciAoY29uc3QgYXJnIG9mIG9wdHMub21pdEZyb21Cb290c3RyYXAgPz8gW10pIHtcbiAgICAgIGRlbGV0ZSBvcHRzLmFyZ3NbYXJnXTtcbiAgICB9XG4gICAgcmVuZGVyc1tQUk9KRU5fTkVXXSA9IGAke1BST0pFTl9ORVd9OiAke0pTT04uc3RyaW5naWZ5KHtcbiAgICAgIGFyZ3M6IG9wdHMuYXJncyxcbiAgICAgIGZxbjogb3B0cy50eXBlLmZxbixcbiAgICAgIGNvbW1lbnRzOiBvcHRzLmNvbW1lbnRzLFxuICAgICAgc3ludGg6IG9wdHMuc3ludGggPz8gdHJ1ZSxcbiAgICAgIHBvc3Q6IG9wdHMucG9zdCA/PyB0cnVlLFxuICAgIH0gYXMgUHJvamVuSW5pdCl9LGA7XG4gICAgb3B0aW9uc1dpdGhEZWZhdWx0cy5wdXNoKFBST0pFTl9ORVcpO1xuICB9XG5cbiAgLy8gZ2VuZXJhdGUgcmVuZGVyaW5nXG4gIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcbiAgcmVzdWx0LnB1c2goXCJ7XCIpO1xuXG4gIC8vIHJlbmRlciBvcHRpb25zIHdpdGggZGVmYXVsdHNcbiAgb3B0aW9uc1dpdGhEZWZhdWx0cy5zb3J0KCk7XG4gIGZvciAoY29uc3Qgb3B0aW9uTmFtZSBvZiBvcHRpb25zV2l0aERlZmF1bHRzKSB7XG4gICAgcmVzdWx0LnB1c2goYCR7VEFCfSR7cmVuZGVyc1tvcHRpb25OYW1lXX1gKTtcbiAgfVxuICBpZiAocmVzdWx0Lmxlbmd0aCA+IDEpIHtcbiAgICByZXN1bHQucHVzaChcIlwiKTtcbiAgfVxuXG4gIC8vIHJlbmRlciBvcHRpb25zIHdpdGhvdXQgZGVmYXVsdHMgYXMgY29tbWVudHNcbiAgaWYgKG9wdHMuY29tbWVudHMgPT09IEluaXRQcm9qZWN0T3B0aW9uSGludHMuQUxMKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IG9wdHMudHlwZS5vcHRpb25zLmZpbHRlcihcbiAgICAgIChvcHQpID0+ICFvcHQuZGVwcmVjYXRlZCAmJiBvcHRzLmFyZ3Nbb3B0Lm5hbWVdID09PSB1bmRlZmluZWQsXG4gICAgKTtcbiAgICByZXN1bHQucHVzaCguLi5yZW5kZXJDb21tZW50ZWRPcHRpb25zQnlNb2R1bGUocmVuZGVycywgb3B0aW9ucykpO1xuICB9IGVsc2UgaWYgKG9wdHMuY29tbWVudHMgPT09IEluaXRQcm9qZWN0T3B0aW9uSGludHMuRkVBVFVSRUQpIHtcbiAgICBjb25zdCBvcHRpb25zID0gb3B0cy50eXBlLm9wdGlvbnMuZmlsdGVyKFxuICAgICAgKG9wdCkgPT5cbiAgICAgICAgIW9wdC5kZXByZWNhdGVkICYmIG9wdHMuYXJnc1tvcHQubmFtZV0gPT09IHVuZGVmaW5lZCAmJiBvcHQuZmVhdHVyZWQsXG4gICAgKTtcbiAgICByZXN1bHQucHVzaCguLi5yZW5kZXJDb21tZW50ZWRPcHRpb25zSW5PcmRlcihyZW5kZXJzLCBvcHRpb25zKSk7XG4gIH0gZWxzZSBpZiAob3B0cy5jb21tZW50cyA9PT0gSW5pdFByb2plY3RPcHRpb25IaW50cy5OT05FKSB7XG4gICAgLy8gZG9uJ3QgcmVuZGVyIGFueSBleHRyYSBvcHRpb25zXG4gIH1cblxuICBpZiAocmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXSA9PT0gXCJcIikge1xuICAgIHJlc3VsdC5wb3AoKTtcbiAgfVxuICByZXN1bHQucHVzaChcIn1cIik7XG4gIHJldHVybiB7IHJlbmRlcmVkT3B0aW9uczogcmVzdWx0LmpvaW4oXCJcXG5cIiksIGltcG9ydHM6IGFsbEltcG9ydHMgfTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyQ29tbWVudGVkT3B0aW9uc0J5TW9kdWxlKFxuICByZW5kZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICBvcHRpb25zOiBpbnZlbnRvcnkuSW52ZW50b3J5UHJvamVjdE9wdGlvbltdLFxuKSB7XG4gIGNvbnN0IG9wdGlvbnNCeU1vZHVsZTogUmVjb3JkPHN0cmluZywgaW52ZW50b3J5LkludmVudG9yeVByb2plY3RPcHRpb25bXT4gPVxuICAgIHt9O1xuXG4gIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbnMpIHtcbiAgICBjb25zdCBwYXJlbnRNb2R1bGUgPSBvcHRpb24ucGFyZW50O1xuICAgIG9wdGlvbnNCeU1vZHVsZVtwYXJlbnRNb2R1bGVdID0gb3B0aW9uc0J5TW9kdWxlW3BhcmVudE1vZHVsZV0gPz8gW107XG4gICAgb3B0aW9uc0J5TW9kdWxlW3BhcmVudE1vZHVsZV0ucHVzaChvcHRpb24pO1xuICB9XG5cbiAgZm9yIChjb25zdCBwYXJlbnRNb2R1bGUgaW4gb3B0aW9uc0J5TW9kdWxlKSB7XG4gICAgb3B0aW9uc0J5TW9kdWxlW3BhcmVudE1vZHVsZV0uc29ydCgobzEsIG8yKSA9PlxuICAgICAgbzEubmFtZS5sb2NhbGVDb21wYXJlKG8yLm5hbWUpLFxuICAgICk7XG4gIH1cblxuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgY29uc3QgbWFyZ2luU2l6ZSA9IE1hdGgubWF4KFxuICAgIC4uLm9wdGlvbnMubWFwKChvcHQpID0+IHJlbmRlcnNbb3B0Lm5hbWVdLmxlbmd0aCksXG4gICk7XG4gIGZvciAoY29uc3QgW21vZHVsZU5hbWUsIG9wdGlvbkdyb3VwXSBvZiBPYmplY3QuZW50cmllcyhcbiAgICBvcHRpb25zQnlNb2R1bGUsXG4gICkuc29ydCgpKSB7XG4gICAgcmVzdWx0LnB1c2goYCR7VEFCfS8qICR7bW9kdWxlTmFtZX0gKi9gKTtcbiAgICBmb3IgKGNvbnN0IG9wdGlvbiBvZiBvcHRpb25Hcm91cCkge1xuICAgICAgY29uc3QgcGFyYW1SZW5kZXIgPSByZW5kZXJzW29wdGlvbi5uYW1lXTtcbiAgICAgIGNvbnN0IGRvY3N0cmluZyA9IG9wdGlvbi5kb2NzIHx8IFwiTm8gZG9jdW1lbnRhdGlvbiBmb3VuZC5cIjtcbiAgICAgIHJlc3VsdC5wdXNoKFxuICAgICAgICBgJHtUQUJ9JHtwYXJhbVJlbmRlcn0ke21ha2VQYWRkaW5nKFxuICAgICAgICAgIG1hcmdpblNpemUgLSBwYXJhbVJlbmRlci5sZW5ndGggKyAyLFxuICAgICAgICApfS8qICR7ZG9jc3RyaW5nfSAqL2AsXG4gICAgICApO1xuICAgIH1cbiAgICByZXN1bHQucHVzaChcIlwiKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiByZW5kZXJDb21tZW50ZWRPcHRpb25zSW5PcmRlcihcbiAgcmVuZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgb3B0aW9uczogaW52ZW50b3J5LlByb2plY3RPcHRpb25bXSxcbikge1xuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgY29uc3QgbWFyZ2luU2l6ZSA9IE1hdGgubWF4KFxuICAgIC4uLm9wdGlvbnMubWFwKChvcHQpID0+IHJlbmRlcnNbb3B0Lm5hbWVdLmxlbmd0aCksXG4gICk7XG4gIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbnMpIHtcbiAgICBjb25zdCBwYXJhbVJlbmRlciA9IHJlbmRlcnNbb3B0aW9uLm5hbWVdO1xuICAgIGNvbnN0IGRvY3N0cmluZyA9IG9wdGlvbi5kb2NzIHx8IFwiTm8gZG9jdW1lbnRhdGlvbiBmb3VuZC5cIjtcbiAgICByZXN1bHQucHVzaChcbiAgICAgIGAke1RBQn0ke3BhcmFtUmVuZGVyfSR7bWFrZVBhZGRpbmcoXG4gICAgICAgIG1hcmdpblNpemUgLSBwYXJhbVJlbmRlci5sZW5ndGggKyAyLFxuICAgICAgKX0vKiAke2RvY3N0cmluZ30gKi9gLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIGEgdmFsdWUgYXMgYSBKYXZhU2NyaXB0IHZhbHVlLCBjb252ZXJ0aW5nIHN0cmluZ3MgdG8gZW51bXMgd2hlcmVcbiAqIGFwcHJvcHJpYXRlLiBUaGUgdHlwZSBtdXN0IGJlIEpTT04tbGlrZSAoc3RyaW5nLCBudW1iZXIsIGJvb2xlYW4sIGFycmF5LFxuICogZW51bSwgb3IgSlNPTiBvYmplY3QpLlxuICpcbiAqIFJldHVybnMgYSBKYXZhU2NyaXB0IGV4cHJlc3Npb24gYXMgYSBzdHJpbmcsIGFuZCB0aGUgbmFtZXMgb2YgYW55XG4gKiBuZWNlc3NhcnkgaW1wb3J0cy5cbiAqL1xuZnVuY3Rpb24gcmVuZGVyQXJnQXNKYXZhU2NyaXB0KFxuICBhcmc6IGFueSxcbiAgb3B0aW9uOiBpbnZlbnRvcnkuSW52ZW50b3J5UHJvamVjdE9wdGlvbixcbikge1xuICBpZiAob3B0aW9uLmtpbmQgPT09IFwiZW51bVwiKSB7XG4gICAgaWYgKCFvcHRpb24uZnFuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGZxbiBmaWVsZCBpcyBtaXNzaW5nIGZyb20gZW51bSBvcHRpb24gJHtvcHRpb24ubmFtZX1gKTtcbiAgICB9XG4gICAgY29uc3QgcGFydHMgPSBvcHRpb24uZnFuLnNwbGl0KFwiLlwiKTsgLy8gLT4gWydwcm9qZW4nLCAnd2ViJywgJ015RW51bSddXG4gICAgY29uc3QgZW51bUNob2ljZSA9IFN0cmluZyhhcmcpLnRvVXBwZXJDYXNlKCkucmVwbGFjZSgvLS9nLCBcIl9cIik7IC8vIGN1c3RvbS12YWx1ZSAtPiBDVVNUT01fVkFMVUVcbiAgICBjb25zdCBqcyA9IGAke3BhcnRzLnNsaWNlKDEpLmpvaW4oXCIuXCIpfS4ke2VudW1DaG9pY2V9YDsgLy8gLT4gd2ViLk15RW51bS5DVVNUT01fVkFMVUVcbiAgICBjb25zdCBtb2R1bGVOYW1lID0gcGFydHNbMF07IC8vIC0+IHByb2plblxuICAgIGNvbnN0IGltcG9ydE5hbWUgPSBwYXJ0c1sxXTsgLy8gLT4gd2ViXG4gICAgcmV0dXJuIHsganMsIG1vZHVsZU5hbWUsIGltcG9ydE5hbWUgfTtcbiAgfSBlbHNlIGlmIChvcHRpb24uanNvbkxpa2UpIHtcbiAgICByZXR1cm4geyBqczogSlNPTi5zdHJpbmdpZnkoYXJnKSB9O1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBVbmV4cGVjdGVkIG9wdGlvbiAke29wdGlvbi5uYW1lfSAtIGNhbm5vdCByZW5kZXIgYSB2YWx1ZSBmb3IgdGhpcyBvcHRpb24gYmVjYXVzZSBpdCBkb2VzIG5vdCBoYXZlIGEgSlNPTi1saWtlIHR5cGUuYCxcbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VQYWRkaW5nKHBhZGRpbmdMZW5ndGg6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBcIiBcIi5yZXBlYXQocGFkZGluZ0xlbmd0aCk7XG59XG4iXX0=