UNPKG

cdktg

Version:
144 lines 22 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.addCustomSynthesis = exports.invokeAspects = exports.ModelSynthesizer = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const path = require("path"); const constructs_1 = require("constructs"); const fs = require("fs-extra"); const annotations_1 = require("./annotations"); const aspect_1 = require("./aspect"); const yaml_1 = require("./private/yaml"); class ModelSynthesizer { constructor(model, continueOnErrorAnnotations = false) { this.model = model; this.continueOnErrorAnnotations = continueOnErrorAnnotations; this.fileAssets = new Array(); } addFileAsset(filePath) { this.fileAssets.push(filePath); } synthesize(session) { invokeAspects(this.model); if (!session.skipValidation) { const errors = this.model.node .findAll() .map((node) => node.node .validate() .map((error) => ({ message: error, source: node }))) .reduce((prev, curr) => [...prev, ...curr], []); if (errors.length > 0) { const errorList = errors .map((e) => `[${e.source.node.path}] ${e.message}`) .join("\n "); throw new Error(`Validation failed with the following errors:\n ${errorList}`); } const manifest = session.manifest; const modelManifest = manifest.forModel(this.model); const workingDirectory = path.join(session.outdir, modelManifest.workingDirectory); if (!fs.existsSync(workingDirectory)) fs.mkdirSync(workingDirectory); // call custom synthesis on child nodes (leafs first) this.model.node .findAll(constructs_1.ConstructOrder.POSTORDER) .forEach((node) => getCustomSynthesis(node)?.onSynthesize(session)); // copy file assets this.fileAssets.forEach((asset) => { const targetPath = path.join(workingDirectory, path.basename(asset)); fs.copyFileSync(asset, targetPath); }); // collect annotations into manifest const annotations = this.model.node .findAll() .map((node) => ({ node, metadatas: node.node.metadata.filter(isAnnotationMetadata), })) .map(({ node, metadatas }) => metadatas.map((metadata) => ({ constructPath: node.node.path, level: metadata.type, message: metadata.data, stacktrace: metadata.trace, }))) .reduce((list, metadatas) => [...list, ...metadatas], []); modelManifest.annotations.push(...annotations); // abort if one or more error annotations have been encountered if (!this.continueOnErrorAnnotations && annotations.some(isErrorAnnotation)) { throw new Error(`Encountered Annotations with level "ERROR":\n${annotations .filter(isErrorAnnotation) .map((a) => `[${a.constructPath}] ${a.message}`) .join("\n")}`); } const threagile = this.model._toThreagile(); yaml_1.Yaml.save(path.join(session.outdir, modelManifest.synthesizedModelPath), [ threagile, ]); } } } exports.ModelSynthesizer = ModelSynthesizer; _a = JSII_RTTI_SYMBOL_1; ModelSynthesizer[_a] = { fqn: "cdktg.ModelSynthesizer", version: "0.0.40" }; const invokedByPath = {}; /** * Invoke aspects on the given construct tree. * * originally from https://github.com/aws/aws-cdk/blob/dcae3eead0dbf9acb1ed80ba95bb104c64cb1bd7/packages/@aws-cdk/core/lib/private/synthesis.ts#L99-L137 */ function invokeAspects(root) { let nestedAspectWarning = false; recurse(root, []); function recurse(construct, inheritedAspects) { const node = construct.node; const aspects = aspect_1.Aspects.of(construct); const allAspectsHere = [...(inheritedAspects ?? []), ...aspects.all]; const nodeAspectsCount = aspects.all.length; for (const aspect of allAspectsHere) { let invoked = invokedByPath[node.path]; if (!invoked) { invoked = invokedByPath[node.path] = []; } if (invoked.includes(aspect)) { continue; } aspect.visit(construct); // if an aspect was added to the node while invoking another aspect it will not be invoked, emit a warning // the `nestedAspectWarning` flag is used to prevent the warning from being emitted for every child if (!nestedAspectWarning && nodeAspectsCount !== aspects.all.length) { annotations_1.Annotations.of(construct).addWarning("We detected an Aspect was added via another Aspect, and will not be applied"); nestedAspectWarning = true; } // mark as invoked for this node invoked.push(aspect); } for (const child of construct.node.children) { recurse(child, allAspectsHere); } } } exports.invokeAspects = invokeAspects; const annotationMetadataEntryTypes = [ annotations_1.AnnotationMetadataEntryType.INFO, annotations_1.AnnotationMetadataEntryType.WARN, annotations_1.AnnotationMetadataEntryType.ERROR, ]; function isAnnotationMetadata(metadata) { return annotationMetadataEntryTypes.includes(metadata.type); } function isErrorAnnotation(annotation) { return annotation.level === annotations_1.AnnotationMetadataEntryType.ERROR; } // originally from https://github.com/aws/aws-cdk/blob/9cee4d00539bed61872126a07bdc14aedba041d8/packages/%40aws-cdk/core/lib/private/synthesis.ts#L44 const CUSTOM_SYNTHESIS_SYM = Symbol.for("cdktg/customSynthesis"); function addCustomSynthesis(construct, synthesis) { Object.defineProperty(construct, CUSTOM_SYNTHESIS_SYM, { value: synthesis, enumerable: false, }); } exports.addCustomSynthesis = addCustomSynthesis; function getCustomSynthesis(construct) { return construct[CUSTOM_SYNTHESIS_SYM]; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ludGhlc2l6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3ludGhlc2l6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2QkFBNkI7QUFDN0IsMkNBQXVFO0FBQ3ZFLCtCQUErQjtBQUUvQiwrQ0FBeUU7QUFDekUscUNBQTRDO0FBRzVDLHlDQUFzQztBQXNCdEMsTUFBYSxnQkFBZ0I7SUFHM0IsWUFDWSxLQUFZLEVBQ2QsNkJBQTZCLEtBQUs7UUFEaEMsVUFBSyxHQUFMLEtBQUssQ0FBTztRQUNkLCtCQUEwQixHQUExQiwwQkFBMEIsQ0FBUTtRQUUxQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7SUFDeEMsQ0FBQztJQUVNLFlBQVksQ0FBQyxRQUFnQjtRQUNsQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsVUFBVSxDQUFDLE9BQTBCO1FBQ25DLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUU7WUFDM0IsTUFBTSxNQUFNLEdBQThDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTtpQkFDdEUsT0FBTyxFQUFFO2lCQUNULEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQ1osSUFBSSxDQUFDLElBQUk7aUJBQ04sUUFBUSxFQUFFO2lCQUNWLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FDdEQ7aUJBQ0EsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRWxELElBQUks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LFNBQWdCLGtCQUFrQixDQUNoQyxTQUFxQixFQUNyQixTQUEyQjtJQUUzQixNQUFNLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxvQkFBb0IsRUFBRTtRQUNyRCxLQUFLLEVBQUUsU0FBUztRQUNoQixVQUFVLEVBQUUsS0FBSztLQUNsQixDQUFDLENBQUM7QUFDTCxDQUFDO0FBUkQsZ0RBUUM7QUFFRCxTQUFTLGtCQUFrQixDQUN6QixTQUFxQjtJQUVyQixPQUFRLFNBQWlCLENBQUMsb0JBQW9CLENBQUMsQ0FBQztBQUNsRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgSUNvbnN0cnVjdCwgTWV0YWRhdGFFbnRyeSwgQ29uc3RydWN0T3JkZXIgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0ICogYXMgZnMgZnJvbSBcImZzLWV4dHJhXCI7XG5cbmltcG9ydCB7IEFubm90YXRpb25zLCBBbm5vdGF0aW9uTWV0YWRhdGFFbnRyeVR5cGUgfSBmcm9tIFwiLi9hbm5vdGF0aW9uc1wiO1xuaW1wb3J0IHsgQXNwZWN0cywgSUFzcGVjdCB9IGZyb20gXCIuL2FzcGVjdFwiO1xuaW1wb3J0IHsgTWFuaWZlc3QsIE1vZGVsQW5ub3RhdGlvbiB9IGZyb20gXCIuL21hbmlmZXN0XCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuL21vZGVsXCI7XG5pbXBvcnQgeyBZYW1sIH0gZnJvbSBcIi4vcHJpdmF0ZS95YW1sXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVN5bnRoZXNpc1Nlc3Npb24ge1xuICAvKipcbiAgICogVGhlIG91dHB1dCBkaXJlY3RvcnkgZm9yIHRoaXMgc3ludGhlc2lzIHNlc3Npb24uXG4gICAqL1xuICByZWFkb25seSBvdXRkaXI6IHN0cmluZztcblxuICByZWFkb25seSBza2lwVmFsaWRhdGlvbj86IGJvb2xlYW47XG5cbiAgcmVhZG9ubHkgbWFuaWZlc3Q6IE1hbmlmZXN0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElNb2RlbFN5bnRoZXNpemVyIHtcbiAgLyoqXG4gICAqIFN5bnRoZXNpemUgdGhlIGFzc29jaWF0ZWQgbW9kZWwgdG8gdGhlIHNlc3Npb25cbiAgICovXG4gIHN5bnRoZXNpemUoc2Vzc2lvbjogSVN5bnRoZXNpc1Nlc3Npb24pOiB2b2lkO1xuXG4gIGFkZEZpbGVBc3NldChmaWxlUGF0aDogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGNsYXNzIE1vZGVsU3ludGhlc2l6ZXIgaW1wbGVtZW50cyBJTW9kZWxTeW50aGVzaXplciB7XG4gIHByaXZhdGUgZmlsZUFzc2V0czogc3RyaW5nW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIG1vZGVsOiBNb2RlbCxcbiAgICBwcml2YXRlIGNvbnRpbnVlT25FcnJvckFubm90YXRpb25zID0gZmFsc2VcbiAgKSB7XG4gICAgdGhpcy5maWxlQXNzZXRzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRGaWxlQXNzZXQoZmlsZVBhdGg6IHN0cmluZykge1xuICAgIHRoaXMuZmlsZUFzc2V0cy5wdXNoKGZpbGVQYXRoKTtcbiAgfVxuXG4gIHN5bnRoZXNpemUoc2Vzc2lvbjogSVN5bnRoZXNpc1Nlc3Npb24pIHtcbiAgICBpbnZva2VBc3BlY3RzKHRoaXMubW9kZWwpO1xuXG4gICAgaWYgKCFzZXNzaW9uLnNraXBWYWxpZGF0aW9uKSB7XG4gICAgICBjb25zdCBlcnJvcnM6IHsgbWVzc2FnZTogc3RyaW5nOyBzb3VyY2U6IElDb25zdHJ1Y3QgfVtdID0gdGhpcy5tb2RlbC5ub2RlXG4gICAgICAgIC5maW5kQWxsKClcbiAgICAgICAgLm1hcCgobm9kZSkgPT5cbiAgICAgICAgICBub2RlLm5vZGVcbiAgICAgICAgICAgIC52YWxpZGF0ZSgpXG4gICAgICAgICAgICAubWFwKChlcnJvcikgPT4gKHsgbWVzc2FnZTogZXJyb3IsIHNvdXJjZTogbm9kZSB9KSlcbiAgICAgICAgKVxuICAgICAgICAucmVkdWNlKChwcmV2LCBjdXJyKSA9PiBbLi4ucHJldiwgLi4uY3Vycl0sIFtdKTtcblxuICAgICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGVycm9yTGlzdCA9IGVycm9yc1xuICAgICAgICAgIC5tYXAoKGUpID0+IGBbJHtlLnNvdXJjZS5ub2RlLnBhdGh9XSAke2UubWVzc2FnZX1gKVxuICAgICAgICAgIC5qb2luKFwiXFxuICBcIik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgVmFsaWRhdGlvbiBmYWlsZWQgd2l0aCB0aGUgZm9sbG93aW5nIGVycm9yczpcXG4gICR7ZXJyb3JMaXN0fWBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWFuaWZlc3QgPSBzZXNzaW9uLm1hbmlmZXN0O1xuXG4gICAgICBjb25zdCBtb2RlbE1hbmlmZXN0ID0gbWFuaWZlc3QuZm9yTW9kZWwodGhpcy5tb2RlbCk7XG5cbiAgICAgIGNvbnN0IHdvcmtpbmdEaXJlY3RvcnkgPSBwYXRoLmpvaW4oXG4gICAgICAgIHNlc3Npb24ub3V0ZGlyLFxuICAgICAgICBtb2RlbE1hbmlmZXN0LndvcmtpbmdEaXJlY3RvcnlcbiAgICAgICk7XG5cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyh3b3JraW5nRGlyZWN0b3J5KSkgZnMubWtkaXJTeW5jKHdvcmtpbmdEaXJlY3RvcnkpO1xuXG4gICAgICAvLyBjYWxsIGN1c3RvbSBzeW50aGVzaXMgb24gY2hpbGQgbm9kZXMgKGxlYWZzIGZpcnN0KVxuICAgICAgdGhpcy5tb2RlbC5ub2RlXG4gICAgICAgIC5maW5kQWxsKENvbnN0cnVjdE9yZGVyLlBPU1RPUkRFUilcbiAgICAgICAgLmZvckVhY2goKG5vZGUpID0+IGdldEN1c3RvbVN5bnRoZXNpcyhub2RlKT8ub25TeW50aGVzaXplKHNlc3Npb24pKTtcblxuICAgICAgLy8gY29weSBmaWxlIGFzc2V0c1xuICAgICAgdGhpcy5maWxlQXNzZXRzLmZvckVhY2goKGFzc2V0KSA9PiB7XG4gICAgICAgIGNvbnN0IHRhcmdldFBhdGggPSBwYXRoLmpvaW4od29ya2luZ0RpcmVjdG9yeSwgcGF0aC5iYXNlbmFtZShhc3NldCkpO1xuICAgICAgICBmcy5jb3B5RmlsZVN5bmMoYXNzZXQsIHRhcmdldFBhdGgpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGNvbGxlY3QgYW5ub3RhdGlvbnMgaW50byBtYW5pZmVzdFxuICAgICAgY29uc3QgYW5ub3RhdGlvbnMgPSB0aGlzLm1vZGVsLm5vZGVcbiAgICAgICAgLmZpbmRBbGwoKVxuICAgICAgICAubWFwKChub2RlKSA9PiAoe1xuICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgbWV0YWRhdGFzOiBub2RlLm5vZGUubWV0YWRhdGEuZmlsdGVyKGlzQW5ub3RhdGlvbk1ldGFkYXRhKSxcbiAgICAgICAgfSkpXG4gICAgICAgIC5tYXA8TW9kZWxBbm5vdGF0aW9uW10+KCh7IG5vZGUsIG1ldGFkYXRhcyB9KSA9PlxuICAgICAgICAgIG1ldGFkYXRhcy5tYXAoKG1ldGFkYXRhKSA9PiAoe1xuICAgICAgICAgICAgY29uc3RydWN0UGF0aDogbm9kZS5ub2RlLnBhdGgsXG4gICAgICAgICAgICBsZXZlbDogbWV0YWRhdGEudHlwZSBhcyBBbm5vdGF0aW9uTWV0YWRhdGFFbnRyeVR5cGUsXG4gICAgICAgICAgICBtZXNzYWdlOiBtZXRhZGF0YS5kYXRhLFxuICAgICAgICAgICAgc3RhY2t0cmFjZTogbWV0YWRhdGEudHJhY2UsXG4gICAgICAgICAgfSkpXG4gICAgICAgIClcbiAgICAgICAgLnJlZHVjZSgobGlzdCwgbWV0YWRhdGFzKSA9PiBbLi4ubGlzdCwgLi4ubWV0YWRhdGFzXSwgW10pO1xuXG4gICAgICBtb2RlbE1hbmlmZXN0LmFubm90YXRpb25zLnB1c2goLi4uYW5ub3RhdGlvbnMpO1xuXG4gICAgICAvLyBhYm9ydCBpZiBvbmUgb3IgbW9yZSBlcnJvciBhbm5vdGF0aW9ucyBoYXZlIGJlZW4gZW5jb3VudGVyZWRcbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuY29udGludWVPbkVycm9yQW5ub3RhdGlvbnMgJiZcbiAgICAgICAgYW5ub3RhdGlvbnMuc29tZShpc0Vycm9yQW5ub3RhdGlvbilcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYEVuY291bnRlcmVkIEFubm90YXRpb25zIHdpdGggbGV2ZWwgXCJFUlJPUlwiOlxcbiR7YW5ub3RhdGlvbnNcbiAgICAgICAgICAgIC5maWx0ZXIoaXNFcnJvckFubm90YXRpb24pXG4gICAgICAgICAgICAubWFwKChhKSA9PiBgWyR7YS5jb25zdHJ1Y3RQYXRofV0gJHthLm1lc3NhZ2V9YClcbiAgICAgICAgICAgIC5qb2luKFwiXFxuXCIpfWBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGhyZWFnaWxlID0gdGhpcy5tb2RlbC5fdG9UaHJlYWdpbGUoKTtcblxuICAgICAgWWFtbC5zYXZlKHBhdGguam9pbihzZXNzaW9uLm91dGRpciwgbW9kZWxNYW5pZmVzdC5zeW50aGVzaXplZE1vZGVsUGF0aCksIFtcbiAgICAgICAgdGhyZWFnaWxlLFxuICAgICAgXSk7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IGludm9rZWRCeVBhdGg6IHsgW25vZGVQYXRoOiBzdHJpbmddOiBJQXNwZWN0W10gfSA9IHt9O1xuXG4vKipcbiAqIEludm9rZSBhc3BlY3RzIG9uIHRoZSBnaXZlbiBjb25zdHJ1Y3QgdHJlZS5cbiAqXG4gKiBvcmlnaW5hbGx5IGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2Jsb2IvZGNhZTNlZWFkMGRiZjlhY2IxZWQ4MGJhOTViYjEwNGM2NGNiMWJkNy9wYWNrYWdlcy9AYXdzLWNkay9jb3JlL2xpYi9wcml2YXRlL3N5bnRoZXNpcy50cyNMOTktTDEzN1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW52b2tlQXNwZWN0cyhyb290OiBJQ29uc3RydWN0KSB7XG4gIGxldCBuZXN0ZWRBc3BlY3RXYXJuaW5nID0gZmFsc2U7XG4gIHJlY3Vyc2Uocm9vdCwgW10pO1xuXG4gIGZ1bmN0aW9uIHJlY3Vyc2UoY29uc3RydWN0OiBJQ29uc3RydWN0LCBpbmhlcml0ZWRBc3BlY3RzOiBJQXNwZWN0W10pIHtcbiAgICBjb25zdCBub2RlID0gY29uc3RydWN0Lm5vZGU7XG4gICAgY29uc3QgYXNwZWN0cyA9IEFzcGVjdHMub2YoY29uc3RydWN0KTtcbiAgICBjb25zdCBhbGxBc3BlY3RzSGVyZSA9IFsuLi4oaW5oZXJpdGVkQXNwZWN0cyA/PyBbXSksIC4uLmFzcGVjdHMuYWxsXTtcbiAgICBjb25zdCBub2RlQXNwZWN0c0NvdW50ID0gYXNwZWN0cy5hbGwubGVuZ3RoO1xuXG4gICAgZm9yIChjb25zdCBhc3BlY3Qgb2YgYWxsQXNwZWN0c0hlcmUpIHtcbiAgICAgIGxldCBpbnZva2VkID0gaW52b2tlZEJ5UGF0aFtub2RlLnBhdGhdO1xuICAgICAgaWYgKCFpbnZva2VkKSB7XG4gICAgICAgIGludm9rZWQgPSBpbnZva2VkQnlQYXRoW25vZGUucGF0aF0gPSBbXTtcbiAgICAgIH1cblxuICAgICAgaWYgKGludm9rZWQuaW5jbHVkZXMoYXNwZWN0KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgYXNwZWN0LnZpc2l0KGNvbnN0cnVjdCk7XG5cbiAgICAgIC8vIGlmIGFuIGFzcGVjdCB3YXMgYWRkZWQgdG8gdGhlIG5vZGUgd2hpbGUgaW52b2tpbmcgYW5vdGhlciBhc3BlY3QgaXQgd2lsbCBub3QgYmUgaW52b2tlZCwgZW1pdCBhIHdhcm5pbmdcbiAgICAgIC8vIHRoZSBgbmVzdGVkQXNwZWN0V2FybmluZ2AgZmxhZyBpcyB1c2VkIHRvIHByZXZlbnQgdGhlIHdhcm5pbmcgZnJvbSBiZWluZyBlbWl0dGVkIGZvciBldmVyeSBjaGlsZFxuICAgICAgaWYgKCFuZXN0ZWRBc3BlY3RXYXJuaW5nICYmIG5vZGVBc3BlY3RzQ291bnQgIT09IGFzcGVjdHMuYWxsLmxlbmd0aCkge1xuICAgICAgICBBbm5vdGF0aW9ucy5vZihjb25zdHJ1Y3QpLmFkZFdhcm5pbmcoXG4gICAgICAgICAgXCJXZSBkZXRlY3RlZCBhbiBBc3BlY3Qgd2FzIGFkZGVkIHZpYSBhbm90aGVyIEFzcGVjdCwgYW5kIHdpbGwgbm90IGJlIGFwcGxpZWRcIlxuICAgICAgICApO1xuICAgICAgICBuZXN0ZWRBc3BlY3RXYXJuaW5nID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gbWFyayBhcyBpbnZva2VkIGZvciB0aGlzIG5vZGVcbiAgICAgIGludm9rZWQucHVzaChhc3BlY3QpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgY29uc3RydWN0Lm5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIHJlY3Vyc2UoY2hpbGQsIGFsbEFzcGVjdHNIZXJlKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgYW5ub3RhdGlvbk1ldGFkYXRhRW50cnlUeXBlcyA9IFtcbiAgQW5ub3RhdGlvbk1ldGFkYXRhRW50cnlUeXBlLklORk8sXG4gIEFubm90YXRpb25NZXRhZGF0YUVudHJ5VHlwZS5XQVJOLFxuICBBbm5vdGF0aW9uTWV0YWRhdGFFbnRyeVR5cGUuRVJST1IsXG5dIGFzIHN0cmluZ1tdO1xuXG5mdW5jdGlvbiBpc0Fubm90YXRpb25NZXRhZGF0YShtZXRhZGF0YTogTWV0YWRhdGFFbnRyeSk6IGJvb2xlYW4ge1xuICByZXR1cm4gYW5ub3RhdGlvbk1ldGFkYXRhRW50cnlUeXBlcy5pbmNsdWRlcyhtZXRhZGF0YS50eXBlKTtcbn1cblxuZnVuY3Rpb24gaXNFcnJvckFubm90YXRpb24oYW5ub3RhdGlvbjogTW9kZWxBbm5vdGF0aW9uKTogYm9vbGVhbiB7XG4gIHJldHVybiBhbm5vdGF0aW9uLmxldmVsID09PSBBbm5vdGF0aW9uTWV0YWRhdGFFbnRyeVR5cGUuRVJST1I7XG59XG5cbi8vICBvcmlnaW5hbGx5IGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2Jsb2IvOWNlZTRkMDA1MzliZWQ2MTg3MjEyNmEwN2JkYzE0YWVkYmEwNDFkOC9wYWNrYWdlcy8lNDBhd3MtY2RrL2NvcmUvbGliL3ByaXZhdGUvc3ludGhlc2lzLnRzI0w0NFxuY29uc3QgQ1VTVE9NX1NZTlRIRVNJU19TWU0gPSBTeW1ib2wuZm9yKFwiY2RrdGcvY3VzdG9tU3ludGhlc2lzXCIpO1xuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgY29uc3RydWN0cyB0aGF0IHdhbnQgdG8gZG8gc29tZXRoaW5nIGN1c3RvbSBkdXJpbmcgc3ludGhlc2lzXG4gKlxuICogVGhpcyBmZWF0dXJlIGlzIGludGVuZGVkIGZvciB1c2UgYnkgY2RrdGcgb25seTsgM3JkIHBhcnR5XG4gKiBsaWJyYXJ5IGF1dGhvcnMgYW5kIENESyB1c2VycyBzaG91bGQgbm90IHVzZSB0aGlzIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElDdXN0b21TeW50aGVzaXMge1xuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gdGhlIGNvbnN0cnVjdCBpcyBzeW50aGVzaXplZFxuICAgKi9cbiAgb25TeW50aGVzaXplKHNlc3Npb246IElTeW50aGVzaXNTZXNzaW9uKTogdm9pZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEN1c3RvbVN5bnRoZXNpcyhcbiAgY29uc3RydWN0OiBJQ29uc3RydWN0LFxuICBzeW50aGVzaXM6IElDdXN0b21TeW50aGVzaXNcbik6IHZvaWQge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29uc3RydWN0LCBDVVNUT01fU1lOVEhFU0lTX1NZTSwge1xuICAgIHZhbHVlOiBzeW50aGVzaXMsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRDdXN0b21TeW50aGVzaXMoXG4gIGNvbnN0cnVjdDogSUNvbnN0cnVjdFxuKTogSUN1c3RvbVN5bnRoZXNpcyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiAoY29uc3RydWN0IGFzIGFueSlbQ1VTVE9NX1NZTlRIRVNJU19TWU1dO1xufVxuIl19