projen
Version:
CDK for software projects
109 lines • 15.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.synthSnapshot = synthSnapshot;
exports.directorySnapshot = directorySnapshot;
const fs = require("fs");
const os = require("os");
const path = require("path");
const JSONC = require("comment-json");
const comment_json_1 = require("comment-json");
const glob = require("fast-glob");
const json_1 = require("../json");
/**
* Creates a snapshot of the files generated by a project. Ignores any non-text
* files so that the snapshots are human readable.
*/
function synthSnapshot(project, options = {}) {
// defensive: verify that "outdir" is actually in a temporary directory
if (!path.resolve(project.outdir).startsWith(os.tmpdir()) &&
!project.outdir.includes("project-temp-dir")) {
throw new Error("Trying to capture a snapshot of a project outside of tmpdir, which implies this test might corrupt an existing project");
}
const synthed = Symbol.for("synthed");
if (synthed in project) {
throw new Error("duplicate synth()");
}
project[synthed] = true;
const ENV_PROJEN_DISABLE_POST = process.env.PROJEN_DISABLE_POST;
try {
process.env.PROJEN_DISABLE_POST = "true";
project.synth();
const ignoreExts = ["png", "ico"];
return directorySnapshot(project.outdir, {
...options,
excludeGlobs: ignoreExts.map((ext) => `**/*.${ext}`),
supportJsonComments: project.files.some(
// At least one json file in project supports comments
(file) => file instanceof json_1.JsonFile && file.supportsComments),
});
}
finally {
fs.rmSync(project.outdir, { force: true, recursive: true });
// values assigned to process.env.XYZ are automatically converted to strings
if (ENV_PROJEN_DISABLE_POST === undefined) {
delete process.env.PROJEN_DISABLE_POST;
}
else {
process.env.PROJEN_DISABLE_POST = ENV_PROJEN_DISABLE_POST;
}
}
}
function isJsonLikeFile(filePath) {
const file = filePath.toLowerCase();
return (file.endsWith(".json") || file.endsWith(".json5") || file.endsWith(".jsonc"));
}
function directorySnapshot(root, options = {}) {
const output = {};
const files = glob.sync("**", {
ignore: [".git/**", ...(options.excludeGlobs ?? [])],
cwd: root,
onlyFiles: true,
followSymbolicLinks: false,
dot: true,
}); // returns relative file paths with POSIX separators
const parseJson = options.parseJson ?? true;
for (const file of files) {
const filePath = path.join(root, file);
let content;
if (!options.onlyFileNames) {
content = fs.readFileSync(filePath, "utf-8");
if (parseJson && isJsonLikeFile(filePath)) {
content = cleanCommentArrays(JSONC.parse(content, undefined, !options.supportJsonComments));
}
}
else {
content = true;
}
output[file] = content;
}
return output;
}
/**
* Converts type "CommentArray" back to regular JS "Array"
* if there are no comments stored in it.
* Prevents strict checks from failing.
*/
function cleanCommentArrays(obj) {
if (Array.isArray(obj) || isCommentArrayWithoutComments(obj)) {
return Array.from(obj).map(cleanCommentArrays);
}
if (obj instanceof Object) {
for (const p of Object.keys(obj)) {
if (isCommentArrayWithoutComments(obj[p])) {
obj[p] = Array.from(obj[p]).map(cleanCommentArrays);
}
else if (obj[p] instanceof Object) {
obj[p] = cleanCommentArrays(obj[p]);
}
}
}
return obj;
}
/**
* Checks if a "CommentArray" has no comments stored in it.
*/
function isCommentArrayWithoutComments(obj) {
return (obj instanceof comment_json_1.CommentArray &&
Object.getOwnPropertySymbols(obj).length === 0);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ludGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbC9zeW50aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQThCQSxzQ0E0Q0M7QUFnQ0QsOENBbUNDO0FBN0lELHlCQUF5QjtBQUN6Qix5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLHNDQUFzQztBQUN0QywrQ0FBNEM7QUFDNUMsa0NBQWtDO0FBQ2xDLGtDQUFtQztBQW9CbkM7OztHQUdHO0FBQ0gsU0FBZ0IsYUFBYSxDQUMzQixPQUFnQixFQUNoQixVQUEyQixFQUFFO0lBRTdCLHVFQUF1RTtJQUN2RSxJQUNFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNyRCxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLEVBQzVDLENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUNiLHdIQUF3SCxDQUN6SCxDQUFDO0lBQ0osQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEMsSUFBSSxPQUFPLElBQUksT0FBTyxFQUFFLENBQUM7UUFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFQSxPQUFlLENBQUMsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDO0lBRWpDLE1BQU0sdUJBQXVCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQztJQUNoRSxJQUFJLENBQUM7UUFDSCxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixHQUFHLE1BQU0sQ0FBQztRQUN6QyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDaEIsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbEMsT0FBTyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFO1lBQ3ZDLEdBQUcsT0FBTztZQUNWLFlBQVksRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO1lBQ3BELG1CQUFtQixFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUNyQyxzREFBc0Q7WUFDdEQsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksWUFBWSxlQUFRLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUM1RDtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7WUFBUyxDQUFDO1FBQ1QsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUU1RCw0RUFBNEU7UUFDNUUsSUFBSSx1QkFBdUIsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMxQyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUM7UUFDekMsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixHQUFHLHVCQUF1QixDQUFDO1FBQzVELENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQXlCRCxTQUFTLGNBQWMsQ0FBQyxRQUFnQjtJQUN0QyxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDcEMsT0FBTyxDQUNMLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUM3RSxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQWdCLGlCQUFpQixDQUMvQixJQUFZLEVBQ1osVUFBb0MsRUFBRTtJQUV0QyxNQUFNLE1BQU0sR0FBZ0IsRUFBRSxDQUFDO0lBRS9CLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO1FBQzVCLE1BQU0sRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLFlBQVksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNwRCxHQUFHLEVBQUUsSUFBSTtRQUNULFNBQVMsRUFBRSxJQUFJO1FBQ2YsbUJBQW1CLEVBQUUsS0FBSztRQUMxQixHQUFHLEVBQUUsSUFBSTtLQUNWLENBQUMsQ0FBQyxDQUFDLG9EQUFvRDtJQUV4RCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQztJQUU1QyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3pCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRXZDLElBQUksT0FBTyxDQUFDO1FBQ1osSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUMzQixPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDN0MsSUFBSSxTQUFTLElBQUksY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLE9BQU8sR0FBRyxrQkFBa0IsQ0FDMUIsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQzlELENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLENBQUM7UUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsa0JBQWtCLENBQUMsR0FBUTtJQUNsQyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksNkJBQTZCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM3RCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVELElBQUksR0FBRyxZQUFZLE1BQU0sRUFBRSxDQUFDO1FBQzFCLEtBQUssTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2pDLElBQUksNkJBQTZCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDMUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDdEQsQ0FBQztpQkFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsWUFBWSxNQUFNLEVBQUUsQ0FBQztnQkFDcEMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyw2QkFBNkIsQ0FBQyxHQUFRO0lBQzdDLE9BQU8sQ0FDTCxHQUFHLFlBQVksMkJBQVk7UUFDM0IsTUFBTSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQy9DLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgKiBhcyBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCAqIGFzIEpTT05DIGZyb20gXCJjb21tZW50LWpzb25cIjtcbmltcG9ydCB7IENvbW1lbnRBcnJheSB9IGZyb20gXCJjb21tZW50LWpzb25cIjtcbmltcG9ydCAqIGFzIGdsb2IgZnJvbSBcImZhc3QtZ2xvYlwiO1xuaW1wb3J0IHsgSnNvbkZpbGUgfSBmcm9tIFwiLi4vanNvblwiO1xuaW1wb3J0IHsgUHJvamVjdCB9IGZyb20gXCIuLi9wcm9qZWN0XCI7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgdGhlIFNuYXBzaG90IHN5bnRoZXNpc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNuYXBzaG90T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBQYXJzZSAuanNvbiBmaWxlcyBhcyBhIEpTIG9iamVjdCBmb3IgaW1wcm92ZWQgaW5zcGVjdGlvbi5cbiAgICogVGhpcyB3aWxsIGZhaWwgaWYgdGhlIGNvbnRlbnRzIGFyZSBpbnZhbGlkIEpTT04uXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWUgcGFyc2UgLmpzb24gZmlsZXMgaW50byBhbiBvYmplY3RcbiAgICovXG4gIHJlYWRvbmx5IHBhcnNlSnNvbj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3ludGhPdXRwdXQge1xuICBbZmlsZVBhdGg6IHN0cmluZ106IGFueTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgc25hcHNob3Qgb2YgdGhlIGZpbGVzIGdlbmVyYXRlZCBieSBhIHByb2plY3QuIElnbm9yZXMgYW55IG5vbi10ZXh0XG4gKiBmaWxlcyBzbyB0aGF0IHRoZSBzbmFwc2hvdHMgYXJlIGh1bWFuIHJlYWRhYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3ludGhTbmFwc2hvdChcbiAgcHJvamVjdDogUHJvamVjdCxcbiAgb3B0aW9uczogU25hcHNob3RPcHRpb25zID0ge30sXG4pOiBTeW50aE91dHB1dCB7XG4gIC8vIGRlZmVuc2l2ZTogdmVyaWZ5IHRoYXQgXCJvdXRkaXJcIiBpcyBhY3R1YWxseSBpbiBhIHRlbXBvcmFyeSBkaXJlY3RvcnlcbiAgaWYgKFxuICAgICFwYXRoLnJlc29sdmUocHJvamVjdC5vdXRkaXIpLnN0YXJ0c1dpdGgob3MudG1wZGlyKCkpICYmXG4gICAgIXByb2plY3Qub3V0ZGlyLmluY2x1ZGVzKFwicHJvamVjdC10ZW1wLWRpclwiKVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcIlRyeWluZyB0byBjYXB0dXJlIGEgc25hcHNob3Qgb2YgYSBwcm9qZWN0IG91dHNpZGUgb2YgdG1wZGlyLCB3aGljaCBpbXBsaWVzIHRoaXMgdGVzdCBtaWdodCBjb3JydXB0IGFuIGV4aXN0aW5nIHByb2plY3RcIixcbiAgICApO1xuICB9XG5cbiAgY29uc3Qgc3ludGhlZCA9IFN5bWJvbC5mb3IoXCJzeW50aGVkXCIpO1xuICBpZiAoc3ludGhlZCBpbiBwcm9qZWN0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiZHVwbGljYXRlIHN5bnRoKClcIik7XG4gIH1cblxuICAocHJvamVjdCBhcyBhbnkpW3N5bnRoZWRdID0gdHJ1ZTtcblxuICBjb25zdCBFTlZfUFJPSkVOX0RJU0FCTEVfUE9TVCA9IHByb2Nlc3MuZW52LlBST0pFTl9ESVNBQkxFX1BPU1Q7XG4gIHRyeSB7XG4gICAgcHJvY2Vzcy5lbnYuUFJPSkVOX0RJU0FCTEVfUE9TVCA9IFwidHJ1ZVwiO1xuICAgIHByb2plY3Quc3ludGgoKTtcbiAgICBjb25zdCBpZ25vcmVFeHRzID0gW1wicG5nXCIsIFwiaWNvXCJdO1xuICAgIHJldHVybiBkaXJlY3RvcnlTbmFwc2hvdChwcm9qZWN0Lm91dGRpciwge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIGV4Y2x1ZGVHbG9iczogaWdub3JlRXh0cy5tYXAoKGV4dCkgPT4gYCoqLyouJHtleHR9YCksXG4gICAgICBzdXBwb3J0SnNvbkNvbW1lbnRzOiBwcm9qZWN0LmZpbGVzLnNvbWUoXG4gICAgICAgIC8vIEF0IGxlYXN0IG9uZSBqc29uIGZpbGUgaW4gcHJvamVjdCBzdXBwb3J0cyBjb21tZW50c1xuICAgICAgICAoZmlsZSkgPT4gZmlsZSBpbnN0YW5jZW9mIEpzb25GaWxlICYmIGZpbGUuc3VwcG9ydHNDb21tZW50cyxcbiAgICAgICksXG4gICAgfSk7XG4gIH0gZmluYWxseSB7XG4gICAgZnMucm1TeW5jKHByb2plY3Qub3V0ZGlyLCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICAvLyB2YWx1ZXMgYXNzaWduZWQgdG8gcHJvY2Vzcy5lbnYuWFlaIGFyZSBhdXRvbWF0aWNhbGx5IGNvbnZlcnRlZCB0byBzdHJpbmdzXG4gICAgaWYgKEVOVl9QUk9KRU5fRElTQUJMRV9QT1NUID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudi5QUk9KRU5fRElTQUJMRV9QT1NUO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9jZXNzLmVudi5QUk9KRU5fRElTQUJMRV9QT1NUID0gRU5WX1BST0pFTl9ESVNBQkxFX1BPU1Q7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGlyZWN0b3J5U25hcHNob3RPcHRpb25zIGV4dGVuZHMgU25hcHNob3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIEdsb2JzIG9mIGZpbGVzIHRvIGV4Y2x1ZGUuXG4gICAqIEBkZWZhdWx0IFtdIGluY2x1ZGUgYWxsIGZpbGVzXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlR2xvYnM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogT25seSBzbmFwc2hvdCB0aGUgbmFtZXMgb2YgZmlsZXMgYW5kIG5vdCB0aGVpciBjb250ZW50cy5cbiAgICogVGhlIHZhbHVlIGZvciBhIHBhdGggd2lsbCBiZSBgdHJ1ZWAgaWYgaXQgZXhpc3RzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZSBpbmNsdWRlIGZpbGUgY29udGVudFxuICAgKi9cbiAgcmVhZG9ubHkgb25seUZpbGVOYW1lcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFBhcnNlcyBmaWxlcyB3aXRoIGRpZmZlcmVudCBwYXJzZXIsIHN1cHBvcnRpbmcgY29tbWVudHNcbiAgICogaW5zaWRlIC5qc29uIGZpbGVzLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgc3VwcG9ydEpzb25Db21tZW50cz86IGJvb2xlYW47XG59XG5cbmZ1bmN0aW9uIGlzSnNvbkxpa2VGaWxlKGZpbGVQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgZmlsZSA9IGZpbGVQYXRoLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiAoXG4gICAgZmlsZS5lbmRzV2l0aChcIi5qc29uXCIpIHx8IGZpbGUuZW5kc1dpdGgoXCIuanNvbjVcIikgfHwgZmlsZS5lbmRzV2l0aChcIi5qc29uY1wiKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGlyZWN0b3J5U25hcHNob3QoXG4gIHJvb3Q6IHN0cmluZyxcbiAgb3B0aW9uczogRGlyZWN0b3J5U25hcHNob3RPcHRpb25zID0ge30sXG4pIHtcbiAgY29uc3Qgb3V0cHV0OiBTeW50aE91dHB1dCA9IHt9O1xuXG4gIGNvbnN0IGZpbGVzID0gZ2xvYi5zeW5jKFwiKipcIiwge1xuICAgIGlnbm9yZTogW1wiLmdpdC8qKlwiLCAuLi4ob3B0aW9ucy5leGNsdWRlR2xvYnMgPz8gW10pXSxcbiAgICBjd2Q6IHJvb3QsXG4gICAgb25seUZpbGVzOiB0cnVlLFxuICAgIGZvbGxvd1N5bWJvbGljTGlua3M6IGZhbHNlLFxuICAgIGRvdDogdHJ1ZSxcbiAgfSk7IC8vIHJldHVybnMgcmVsYXRpdmUgZmlsZSBwYXRocyB3aXRoIFBPU0lYIHNlcGFyYXRvcnNcblxuICBjb25zdCBwYXJzZUpzb24gPSBvcHRpb25zLnBhcnNlSnNvbiA/PyB0cnVlO1xuXG4gIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKHJvb3QsIGZpbGUpO1xuXG4gICAgbGV0IGNvbnRlbnQ7XG4gICAgaWYgKCFvcHRpb25zLm9ubHlGaWxlTmFtZXMpIHtcbiAgICAgIGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIFwidXRmLThcIik7XG4gICAgICBpZiAocGFyc2VKc29uICYmIGlzSnNvbkxpa2VGaWxlKGZpbGVQYXRoKSkge1xuICAgICAgICBjb250ZW50ID0gY2xlYW5Db21tZW50QXJyYXlzKFxuICAgICAgICAgIEpTT05DLnBhcnNlKGNvbnRlbnQsIHVuZGVmaW5lZCwgIW9wdGlvbnMuc3VwcG9ydEpzb25Db21tZW50cyksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRlbnQgPSB0cnVlO1xuICAgIH1cblxuICAgIG91dHB1dFtmaWxlXSA9IGNvbnRlbnQ7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHR5cGUgXCJDb21tZW50QXJyYXlcIiBiYWNrIHRvIHJlZ3VsYXIgSlMgXCJBcnJheVwiXG4gKiBpZiB0aGVyZSBhcmUgbm8gY29tbWVudHMgc3RvcmVkIGluIGl0LlxuICogUHJldmVudHMgc3RyaWN0IGNoZWNrcyBmcm9tIGZhaWxpbmcuXG4gKi9cbmZ1bmN0aW9uIGNsZWFuQ29tbWVudEFycmF5cyhvYmo6IGFueSk6IHR5cGVvZiBvYmoge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopIHx8IGlzQ29tbWVudEFycmF5V2l0aG91dENvbW1lbnRzKG9iaikpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShvYmopLm1hcChjbGVhbkNvbW1lbnRBcnJheXMpO1xuICB9XG5cbiAgaWYgKG9iaiBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgIGZvciAoY29uc3QgcCBvZiBPYmplY3Qua2V5cyhvYmopKSB7XG4gICAgICBpZiAoaXNDb21tZW50QXJyYXlXaXRob3V0Q29tbWVudHMob2JqW3BdKSkge1xuICAgICAgICBvYmpbcF0gPSBBcnJheS5mcm9tKG9ialtwXSkubWFwKGNsZWFuQ29tbWVudEFycmF5cyk7XG4gICAgICB9IGVsc2UgaWYgKG9ialtwXSBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICBvYmpbcF0gPSBjbGVhbkNvbW1lbnRBcnJheXMob2JqW3BdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIFwiQ29tbWVudEFycmF5XCIgaGFzIG5vIGNvbW1lbnRzIHN0b3JlZCBpbiBpdC5cbiAqL1xuZnVuY3Rpb24gaXNDb21tZW50QXJyYXlXaXRob3V0Q29tbWVudHMob2JqOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBvYmogaW5zdGFuY2VvZiBDb21tZW50QXJyYXkgJiZcbiAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iaikubGVuZ3RoID09PSAwXG4gICk7XG59XG4iXX0=