projen
Version:
CDK for software projects
99 lines • 14.2 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Projects = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path = require("path");
const vm = require("vm");
const inventory_1 = require("./inventory");
const render_options_1 = require("./javascript/render-options");
const option_hints_1 = require("./option-hints");
/**
* Programmatic API for projen.
*/
class Projects {
/**
* Creates a new project with defaults.
*
* This function creates the project type in-process (with in VM) and calls
* `.synth()` on it (if `options.synth` is not `false`).
*
* At the moment, it also generates a `.projenrc.js` file with the same code
* that was just executed. In the future, this will also be done by the project
* type, so we can easily support multiple languages of projenrc.
*
* An environment variable (PROJEN_CREATE_PROJECT=true) is set within the VM
* so that custom project types can detect whether the current synthesis is the
* result of a new project creation (and take additional steps accordingly)
*/
static createProject(options) {
createProject(options);
}
constructor() { }
}
exports.Projects = Projects;
_a = JSII_RTTI_SYMBOL_1;
Projects[_a] = { fqn: "projen.Projects", version: "0.95.2" };
function resolveModulePath(moduleName) {
// Default project resolution location
if (moduleName === "projen") {
return "./index";
}
// External projects need to load the module from the modules directory
try {
return path.dirname(require.resolve(path.join(moduleName, "package.json"), {
paths: [process.cwd()],
}));
}
catch (err) {
throw new Error(`External project module '${moduleName}' could not be resolved.`);
}
}
function createProject(opts) {
const projectType = (0, inventory_1.resolveProjectType)(opts.projectFqn);
const mod = resolveModulePath(projectType.moduleName);
// "dir" is exposed as a top-level option to require users to specify a value for it
opts.projectOptions.outdir = opts.dir;
// Generated a random name space for imports used by options
// This is so we can keep the top-level namespace as clean as possible
const optionsImports = "_options" + Math.random().toString(36).slice(2);
// pass the FQN of the project type to the project initializer so it can
// generate the projenrc file.
const { renderedOptions, imports } = (0, render_options_1.renderJavaScriptOptions)({
bootstrap: true,
comments: opts.optionHints ?? option_hints_1.InitProjectOptionHints.FEATURED,
type: projectType,
args: opts.projectOptions,
omitFromBootstrap: ["outdir"],
prefixImports: optionsImports,
});
const initProjectCode = new Array();
// generate a random variable name because jest tests appear to share
// VM contexts, causing
//
// > SyntaxError: Identifier 'project' has already been declared
//
// errors if this isn't unique
const varName = "project" + Math.random().toString(36).slice(2);
initProjectCode.push(`const ${varName} = new ${projectType.typename}(${renderedOptions});`);
if (opts.synth ?? true) {
initProjectCode.push(`${varName}.synth();`);
}
// eslint-disable-next-line @typescript-eslint/no-require-imports
const mainModule = require(mod);
const ctx = vm.createContext({
...mainModule,
[optionsImports]: {
...imports.modules.reduce((optionsContext, currentModule) => ({
...optionsContext,
// eslint-disable-next-line @typescript-eslint/no-require-imports
[currentModule]: require(resolveModulePath(currentModule)),
}), {}),
},
});
const postSynth = opts.post ?? true;
process.env.PROJEN_DISABLE_POST = (!postSynth).toString();
process.env.PROJEN_CREATE_PROJECT = "true";
vm.runInContext(initProjectCode.join("\n"), ctx);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvamVjdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvamVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2QkFBNkI7QUFDN0IseUJBQXlCO0FBQ3pCLDJDQUFpRDtBQUNqRCxnRUFBc0U7QUFDdEUsaURBQXdEO0FBaUR4RDs7R0FFRztBQUNILE1BQWEsUUFBUTtJQUNuQjs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0ksTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUE2QjtRQUN2RCxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVELGdCQUF1QixDQUFDOztBQW5CMUIsNEJBb0JDOzs7QUFFRCxTQUFTLGlCQUFpQixDQUFDLFVBQWtCO0lBQzNDLHNDQUFzQztJQUN0QyxJQUFJLFVBQVUsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM1QixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsdUVBQXVFO0lBQ3ZFLElBQUksQ0FBQztRQUNILE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FDakIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUMsRUFBRTtZQUNyRCxLQUFLLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7U0FDdkIsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE1BQU0sSUFBSSxLQUFLLENBQ2IsNEJBQTRCLFVBQVUsMEJBQTBCLENBQ2pFLENBQUM7SUFDSixDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLElBQTBCO0lBQy9DLE1BQU0sV0FBVyxHQUFHLElBQUEsOEJBQWtCLEVBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sR0FBRyxHQUFHLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUV0RCxvRkFBb0Y7SUFDcEYsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUV0Qyw0REFBNEQ7SUFDNUQsc0VBQXNFO0lBQ3RFLE1BQU0sY0FBYyxHQUFHLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV4RSx3RUFBd0U7SUFDeEUsOEJBQThCO0lBQzlCLE1BQU0sRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBQSx3Q0FBdUIsRUFBQztRQUMzRCxTQUFTLEVBQUUsSUFBSTtRQUNmLFFBQVEsRUFBRSxJQUFJLENBQUMsV0FBVyxJQUFJLHFDQUFzQixDQUFDLFFBQVE7UUFDN0QsSUFBSSxFQUFFLFdBQVc7UUFDakIsSUFBSSxFQUFFLElBQUksQ0FBQyxjQUFjO1FBQ3pCLGlCQUFpQixFQUFFLENBQUMsUUFBUSxDQUFDO1FBQzdCLGFBQWEsRUFBRSxjQUFjO0tBQzlCLENBQUMsQ0FBQztJQUVILE1BQU0sZUFBZSxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7SUFFNUMscUVBQXFFO0lBQ3JFLHVCQUF1QjtJQUN2QixFQUFFO0lBQ0YsZ0VBQWdFO0lBQ2hFLEVBQUU7SUFDRiw4QkFBOEI7SUFDOUIsTUFBTSxPQUFPLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLGVBQWUsQ0FBQyxJQUFJLENBQ2xCLFNBQVMsT0FBTyxVQUFVLFdBQVcsQ0FBQyxRQUFRLElBQUksZUFBZSxJQUFJLENBQ3RFLENBQUM7SUFFRixJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxFQUFFLENBQUM7UUFDdkIsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLE9BQU8sV0FBVyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELGlFQUFpRTtJQUNqRSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDaEMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQztRQUMzQixHQUFHLFVBQVU7UUFDYixDQUFDLGNBQWMsQ0FBQyxFQUFFO1lBQ2hCLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQ3ZCLENBQUMsY0FBYyxFQUFFLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDbEMsR0FBRyxjQUFjO2dCQUNqQixpRUFBaUU7Z0JBQ2pFLENBQUMsYUFBYSxDQUFDLEVBQUUsT0FBTyxDQUFDLGlCQUFpQixDQUFDLGFBQWEsQ0FBQyxDQUFDO2FBQzNELENBQUMsRUFDRixFQUFFLENBQ0g7U0FDRjtLQUNGLENBQUMsQ0FBQztJQUVILE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDO0lBQ3BDLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzFELE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLEdBQUcsTUFBTSxDQUFDO0lBQzNDLEVBQUUsQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNuRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0ICogYXMgdm0gZnJvbSBcInZtXCI7XG5pbXBvcnQgeyByZXNvbHZlUHJvamVjdFR5cGUgfSBmcm9tIFwiLi9pbnZlbnRvcnlcIjtcbmltcG9ydCB7IHJlbmRlckphdmFTY3JpcHRPcHRpb25zIH0gZnJvbSBcIi4vamF2YXNjcmlwdC9yZW5kZXItb3B0aW9uc1wiO1xuaW1wb3J0IHsgSW5pdFByb2plY3RPcHRpb25IaW50cyB9IGZyb20gXCIuL29wdGlvbi1oaW50c1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZVByb2plY3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIERpcmVjdG9yeSB0aGF0IHRoZSBwcm9qZWN0IHdpbGwgYmUgZ2VuZXJhdGVkIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgZGlyOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEZ1bGx5LXF1YWxpZmllZCBuYW1lIG9mIHRoZSBwcm9qZWN0IHR5cGUgKHVzdWFsbHkgZm9ybWF0dGVkXG4gICAqIGFzIGBwcm9qZW4ubW9kdWxlLlByb2plY3RUeXBlYCkuXG4gICAqIEBleGFtcGxlIGBwcm9qZW4udHlwZXNjcmlwdC5UeXBlc2NyaXB0UHJvamVjdGBcbiAgICovXG4gIHJlYWRvbmx5IHByb2plY3RGcW46IHN0cmluZztcblxuICAvKipcbiAgICogUHJvamVjdCBvcHRpb25zLiBPbmx5IEpTT04tbGlrZSB2YWx1ZXMgY2FuIGJlIHBhc3NlZCBpbiAoc3RyaW5ncyxcbiAgICogYm9vbGVhbnMsIG51bWJlcnMsIGVudW1zLCBhcnJheXMsIGFuZCBvYmplY3RzIHRoYXQgYXJlIG5vdFxuICAgKiBkZXJpdmVkIGZyb20gY2xhc3NlcykuXG4gICAqXG4gICAqIENvbnN1bHQgdGhlIEFQSSByZWZlcmVuY2Ugb2YgdGhlIHByb2plY3QgdHlwZSB5b3UgYXJlIGdlbmVyYXRpbmcgZm9yXG4gICAqIGluZm9ybWF0aW9uIGFib3V0IHdoYXQgZmllbGRzIGFuZCB0eXBlcyBhcmUgYXZhaWxhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvamVjdE9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIGFueT47XG5cbiAgLyoqXG4gICAqIFNob3VsZCB3ZSByZW5kZXIgY29tbWVudGVkLW91dCBkZWZhdWx0IG9wdGlvbnMgaW4gdGhlIHByb2plbnJjIGZpbGU/XG4gICAqIERvZXMgbm90IGFwcGx5IHRvIHByb2plbnJjLmpzb24gZmlsZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IEluaXRQcm9qZWN0T3B0aW9uSGludHMuRkVBVFVSRURcbiAgICovXG4gIHJlYWRvbmx5IG9wdGlvbkhpbnRzPzogSW5pdFByb2plY3RPcHRpb25IaW50cztcblxuICAvKipcbiAgICogU2hvdWxkIHdlIGNhbGwgYHByb2plY3Quc3ludGgoKWAgb3IgaW5zdGFudGlhdGUgdGhlIHByb2plY3QgKGNvdWxkIHN0aWxsXG4gICAqIGhhdmUgc2lkZS1lZmZlY3RzKSBhbmQgcmVuZGVyIHRoZSAucHJvamVucmMgZmlsZS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgc3ludGg/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBTaG91bGQgd2UgZXhlY3V0ZSBwb3N0IHN5bnRoZXNpcyBob29rcz8gKHVzdWFsbHkgcGFja2FnZSBtYW5hZ2VyIGluc3RhbGwpLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBwb3N0PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBQcm9ncmFtbWF0aWMgQVBJIGZvciBwcm9qZW4uXG4gKi9cbmV4cG9ydCBjbGFzcyBQcm9qZWN0cyB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IHByb2plY3Qgd2l0aCBkZWZhdWx0cy5cbiAgICpcbiAgICogVGhpcyBmdW5jdGlvbiBjcmVhdGVzIHRoZSBwcm9qZWN0IHR5cGUgaW4tcHJvY2VzcyAod2l0aCBpbiBWTSkgYW5kIGNhbGxzXG4gICAqIGAuc3ludGgoKWAgb24gaXQgKGlmIGBvcHRpb25zLnN5bnRoYCBpcyBub3QgYGZhbHNlYCkuXG4gICAqXG4gICAqIEF0IHRoZSBtb21lbnQsIGl0IGFsc28gZ2VuZXJhdGVzIGEgYC5wcm9qZW5yYy5qc2AgZmlsZSB3aXRoIHRoZSBzYW1lIGNvZGVcbiAgICogdGhhdCB3YXMganVzdCBleGVjdXRlZC4gSW4gdGhlIGZ1dHVyZSwgdGhpcyB3aWxsIGFsc28gYmUgZG9uZSBieSB0aGUgcHJvamVjdFxuICAgKiB0eXBlLCBzbyB3ZSBjYW4gZWFzaWx5IHN1cHBvcnQgbXVsdGlwbGUgbGFuZ3VhZ2VzIG9mIHByb2plbnJjLlxuICAgKlxuICAgKiBBbiBlbnZpcm9ubWVudCB2YXJpYWJsZSAoUFJPSkVOX0NSRUFURV9QUk9KRUNUPXRydWUpIGlzIHNldCB3aXRoaW4gdGhlIFZNXG4gICAqIHNvIHRoYXQgY3VzdG9tIHByb2plY3QgdHlwZXMgY2FuIGRldGVjdCB3aGV0aGVyIHRoZSBjdXJyZW50IHN5bnRoZXNpcyBpcyB0aGVcbiAgICogcmVzdWx0IG9mIGEgbmV3IHByb2plY3QgY3JlYXRpb24gKGFuZCB0YWtlIGFkZGl0aW9uYWwgc3RlcHMgYWNjb3JkaW5nbHkpXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNyZWF0ZVByb2plY3Qob3B0aW9uczogQ3JlYXRlUHJvamVjdE9wdGlvbnMpIHtcbiAgICBjcmVhdGVQcm9qZWN0KG9wdGlvbnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVNb2R1bGVQYXRoKG1vZHVsZU5hbWU6IHN0cmluZykge1xuICAvLyBEZWZhdWx0IHByb2plY3QgcmVzb2x1dGlvbiBsb2NhdGlvblxuICBpZiAobW9kdWxlTmFtZSA9PT0gXCJwcm9qZW5cIikge1xuICAgIHJldHVybiBcIi4vaW5kZXhcIjtcbiAgfVxuXG4gIC8vIEV4dGVybmFsIHByb2plY3RzIG5lZWQgdG8gbG9hZCB0aGUgbW9kdWxlIGZyb20gdGhlIG1vZHVsZXMgZGlyZWN0b3J5XG4gIHRyeSB7XG4gICAgcmV0dXJuIHBhdGguZGlybmFtZShcbiAgICAgIHJlcXVpcmUucmVzb2x2ZShwYXRoLmpvaW4obW9kdWxlTmFtZSwgXCJwYWNrYWdlLmpzb25cIiksIHtcbiAgICAgICAgcGF0aHM6IFtwcm9jZXNzLmN3ZCgpXSxcbiAgICAgIH0pXG4gICAgKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEV4dGVybmFsIHByb2plY3QgbW9kdWxlICcke21vZHVsZU5hbWV9JyBjb3VsZCBub3QgYmUgcmVzb2x2ZWQuYFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUHJvamVjdChvcHRzOiBDcmVhdGVQcm9qZWN0T3B0aW9ucykge1xuICBjb25zdCBwcm9qZWN0VHlwZSA9IHJlc29sdmVQcm9qZWN0VHlwZShvcHRzLnByb2plY3RGcW4pO1xuICBjb25zdCBtb2QgPSByZXNvbHZlTW9kdWxlUGF0aChwcm9qZWN0VHlwZS5tb2R1bGVOYW1lKTtcblxuICAvLyBcImRpclwiIGlzIGV4cG9zZWQgYXMgYSB0b3AtbGV2ZWwgb3B0aW9uIHRvIHJlcXVpcmUgdXNlcnMgdG8gc3BlY2lmeSBhIHZhbHVlIGZvciBpdFxuICBvcHRzLnByb2plY3RPcHRpb25zLm91dGRpciA9IG9wdHMuZGlyO1xuXG4gIC8vIEdlbmVyYXRlZCBhIHJhbmRvbSBuYW1lIHNwYWNlIGZvciBpbXBvcnRzIHVzZWQgYnkgb3B0aW9uc1xuICAvLyBUaGlzIGlzIHNvIHdlIGNhbiBrZWVwIHRoZSB0b3AtbGV2ZWwgbmFtZXNwYWNlIGFzIGNsZWFuIGFzIHBvc3NpYmxlXG4gIGNvbnN0IG9wdGlvbnNJbXBvcnRzID0gXCJfb3B0aW9uc1wiICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMik7XG5cbiAgLy8gcGFzcyB0aGUgRlFOIG9mIHRoZSBwcm9qZWN0IHR5cGUgdG8gdGhlIHByb2plY3QgaW5pdGlhbGl6ZXIgc28gaXQgY2FuXG4gIC8vIGdlbmVyYXRlIHRoZSBwcm9qZW5yYyBmaWxlLlxuICBjb25zdCB7IHJlbmRlcmVkT3B0aW9ucywgaW1wb3J0cyB9ID0gcmVuZGVySmF2YVNjcmlwdE9wdGlvbnMoe1xuICAgIGJvb3RzdHJhcDogdHJ1ZSxcbiAgICBjb21tZW50czogb3B0cy5vcHRpb25IaW50cyA/PyBJbml0UHJvamVjdE9wdGlvbkhpbnRzLkZFQVRVUkVELFxuICAgIHR5cGU6IHByb2plY3RUeXBlLFxuICAgIGFyZ3M6IG9wdHMucHJvamVjdE9wdGlvbnMsXG4gICAgb21pdEZyb21Cb290c3RyYXA6IFtcIm91dGRpclwiXSxcbiAgICBwcmVmaXhJbXBvcnRzOiBvcHRpb25zSW1wb3J0cyxcbiAgfSk7XG5cbiAgY29uc3QgaW5pdFByb2plY3RDb2RlID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblxuICAvLyBnZW5lcmF0ZSBhIHJhbmRvbSB2YXJpYWJsZSBuYW1lIGJlY2F1c2UgamVzdCB0ZXN0cyBhcHBlYXIgdG8gc2hhcmVcbiAgLy8gVk0gY29udGV4dHMsIGNhdXNpbmdcbiAgLy9cbiAgLy8gPiBTeW50YXhFcnJvcjogSWRlbnRpZmllciAncHJvamVjdCcgaGFzIGFscmVhZHkgYmVlbiBkZWNsYXJlZFxuICAvL1xuICAvLyBlcnJvcnMgaWYgdGhpcyBpc24ndCB1bmlxdWVcbiAgY29uc3QgdmFyTmFtZSA9IFwicHJvamVjdFwiICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMik7XG4gIGluaXRQcm9qZWN0Q29kZS5wdXNoKFxuICAgIGBjb25zdCAke3Zhck5hbWV9ID0gbmV3ICR7cHJvamVjdFR5cGUudHlwZW5hbWV9KCR7cmVuZGVyZWRPcHRpb25zfSk7YFxuICApO1xuXG4gIGlmIChvcHRzLnN5bnRoID8/IHRydWUpIHtcbiAgICBpbml0UHJvamVjdENvZGUucHVzaChgJHt2YXJOYW1lfS5zeW50aCgpO2ApO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgY29uc3QgbWFpbk1vZHVsZSA9IHJlcXVpcmUobW9kKTtcbiAgY29uc3QgY3R4ID0gdm0uY3JlYXRlQ29udGV4dCh7XG4gICAgLi4ubWFpbk1vZHVsZSxcbiAgICBbb3B0aW9uc0ltcG9ydHNdOiB7XG4gICAgICAuLi5pbXBvcnRzLm1vZHVsZXMucmVkdWNlKFxuICAgICAgICAob3B0aW9uc0NvbnRleHQsIGN1cnJlbnRNb2R1bGUpID0+ICh7XG4gICAgICAgICAgLi4ub3B0aW9uc0NvbnRleHQsXG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICAgICAgICBbY3VycmVudE1vZHVsZV06IHJlcXVpcmUocmVzb2x2ZU1vZHVsZVBhdGgoY3VycmVudE1vZHVsZSkpLFxuICAgICAgICB9KSxcbiAgICAgICAge31cbiAgICAgICksXG4gICAgfSxcbiAgfSk7XG5cbiAgY29uc3QgcG9zdFN5bnRoID0gb3B0cy5wb3N0ID8/IHRydWU7XG4gIHByb2Nlc3MuZW52LlBST0pFTl9ESVNBQkxFX1BPU1QgPSAoIXBvc3RTeW50aCkudG9TdHJpbmcoKTtcbiAgcHJvY2Vzcy5lbnYuUFJPSkVOX0NSRUFURV9QUk9KRUNUID0gXCJ0cnVlXCI7XG4gIHZtLnJ1bkluQ29udGV4dChpbml0UHJvamVjdENvZGUuam9pbihcIlxcblwiKSwgY3R4KTtcbn1cbiJdfQ==