UNPKG

cdktg

Version:
194 lines 31 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.BusinessCriticality = exports.Model = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const constructs_1 = require("constructs"); const aspect_1 = require("./aspect"); const data_asset_1 = require("./data-asset"); const risk_category_1 = require("./risk-category"); const risk_tracking_1 = require("./risk-tracking"); const risks_1 = require("./risks"); const shared_runtime_1 = require("./shared-runtime"); const synthesizer_1 = require("./synthesizer"); const technical_asset_1 = require("./technical-asset"); const trust_boundary_1 = require("./trust-boundary"); const MODEL_SYMBOL = Symbol.for("cdktg/Model"); class Model extends constructs_1.Construct { constructor(project, id, props) { super(project, id); Object.defineProperty(this, MODEL_SYMBOL, { value: true }); this.synthesizer = new synthesizer_1.ModelSynthesizer(this, false); this.version = props.version; this.title = props.title ?? id; this.date = props.date ? new Date(props.date).toISOString().split("T")[0] : undefined; this.author = props.author; this.managementSummary = props.managementSummary; this.businessCriticality = props.businessCriticality; this.businessOverview = props.businessOverview; if (this.businessOverview && this.businessOverview.images && this.businessOverview.images.length > 0) { this.businessOverview.images.forEach((i) => i._bind(this)); } this.technicalOverview = props.technicalOverview; this.questions = new Map(); props.questions?.forEach((q) => { this.addQuestion(q.text, q.answer); }); this.abuseCases = new Map(); if (props.abuseCases && props.abuseCases.length > 0) { this.addAbuseCases(...props.abuseCases); } this.securityRequirements = new Map(); if (props.securityRequirements && props.securityRequirements.length > 0) { this.addSecurityRequirements(...props.securityRequirements); } this.tags = new Set(); this.riskTracking = new Map(); this.rawOverrides = {}; aspect_1.Aspects.of(this).add(new risks_1.RiskAspect()); } static isModel(x) { return x !== null && typeof x === "object" && MODEL_SYMBOL in x; } static of(construct) { return _lookup(construct); function _lookup(c) { if (Model.isModel(c)) { return c; } const node = c.node; if (!node.scope) { throw new Error(`No model could be identified for the construct at path '${construct.node.path}'`); } return _lookup(node.scope); } } addTag(tag) { this.addTags(tag); } addTags(...tags) { tags.forEach((tag) => { this.tags.add(tag); }); } addQuestion(text, answer = "") { // "" as answer signals "unanswered" if (this.questions.has(text)) { throw new Error(`Duplicated question "${text}"`); } this.questions.set(text, answer); } addAbuseCases(...cases) { cases.forEach((c) => { if (this.abuseCases.has(c.name)) { throw new Error(`Duplicated abuse case "${c.name}"`); } this.abuseCases.set(c.name, c.description); }); } addSecurityRequirements(...requirements) { requirements.forEach((r) => { if (this.abuseCases.has(r.name)) { throw new Error(`Duplicated security requirement "${r.name}"`); } this.securityRequirements.set(r.name, r.description); }); } trackRisk(id, options = {}) { if (this.riskTracking.has(id)) { throw new Error(`Duplicated risk tracking "${id}"`); } this.riskTracking.set(id, new risk_tracking_1.RiskTracking(id, options)); } addOverride(path, value) { const parts = path.split("."); let curr = this.rawOverrides; while (parts.length > 1) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const key = parts.shift(); // if we can't recurse further or the previous value is not an // object overwrite it with an object. const isObject = curr[key] != null && typeof curr[key] === "object" && !Array.isArray(curr[key]); if (!isObject) { curr[key] = {}; } curr = curr[key]; } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const lastKey = parts.shift(); curr[lastKey] = value; } /** * @internal */ _toThreagile() { const dataAssets = new Array(); const technicalAssets = new Array(); const trustBoundaries = new Array(); const sharedRuntimes = new Array(); const individualRiskCategories = new Array(); this.node.findAll().map((n) => { if (n instanceof data_asset_1.DataAsset) { dataAssets.push(n); } else if (n instanceof technical_asset_1.TechnicalAsset) { technicalAssets.push(n); } else if (n instanceof trust_boundary_1.TrustBoundary) { trustBoundaries.push(n); } else if (n instanceof shared_runtime_1.SharedRuntime) { sharedRuntimes.push(n); } else if (n instanceof risk_category_1.RiskCategory) { individualRiskCategories.push(n); } }); const threagile = { threagile_version: this.version, title: this.title, data: this.date, author: this.author._toThreagile(), management_summary_comment: this.managementSummary, business_overview: this.businessOverview?._toThreagile(), technical_overview: this.technicalOverview?._toThreagile(), business_criticality: this.businessCriticality, questions: Object.fromEntries(this.questions), abuse_cases: Object.fromEntries(this.abuseCases), security_requirements: Object.fromEntries(this.securityRequirements), tags_available: Array.from(this.tags), }; threagile.data_assets = dataAssets.reduce((prev, current) => Object.assign(prev, current._toThreagile()), {}); threagile.technical_assets = technicalAssets.reduce((prev, current) => Object.assign(prev, current._toThreagile()), {}); threagile.trust_boundaries = trustBoundaries.reduce((prev, current) => Object.assign(prev, current._toThreagile()), {}); threagile.shared_runtimes = sharedRuntimes.reduce((prev, current) => Object.assign(prev, current._toThreagile()), {}); threagile.individual_risk_categories = individualRiskCategories.reduce((prev, current) => Object.assign(prev, current._toThreagile()), {}); if (this.riskTracking.size > 0) { threagile.risk_tracking = Array.from(this.riskTracking.values()).reduce((prev, current) => Object.assign(prev, current._toThreagile()), {}); } return { ...threagile, ...(Object.keys(this.rawOverrides).length > 0 ? { overrides: { stack: Object.keys(this.rawOverrides) } } : {}), }; } } exports.Model = Model; _a = JSII_RTTI_SYMBOL_1; Model[_a] = { fqn: "cdktg.Model", version: "0.0.40" }; var BusinessCriticality; (function (BusinessCriticality) { BusinessCriticality["ARCHIVE"] = "archive"; BusinessCriticality["OPERATIONAL"] = "operational"; BusinessCriticality["IMPORTANT"] = "important"; BusinessCriticality["CRITICAL"] = "critical"; BusinessCriticality["MISSION_CRITICAL"] = "mission-critical"; })(BusinessCriticality = exports.BusinessCriticality || (exports.BusinessCriticality = {})); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwyQ0FBbUQ7QUFFbkQscUNBQW1DO0FBR25DLDZDQUF5QztBQUV6QyxtREFBK0M7QUFDL0MsbURBQWtFO0FBQ2xFLG1DQUFxQztBQUVyQyxxREFBaUQ7QUFFakQsK0NBQW9FO0FBQ3BFLHVEQUFtRDtBQUNuRCxxREFBaUQ7QUFFakQsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQWdFL0MsTUFBYSxLQUFNLFNBQVEsc0JBQVM7SUEyQ2xDLFlBQVksT0FBa0IsRUFBRSxFQUFVLEVBQUUsS0FBaUI7UUFDM0QsS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVuQixNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUUzRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksOEJBQWdCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXJELElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUM3QixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUk7WUFDcEIsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xELENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDZCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDM0IsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUss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LElBQVksbUJBTVg7QUFORCxXQUFZLG1CQUFtQjtJQUM3QiwwQ0FBbUIsQ0FBQTtJQUNuQixrREFBMkIsQ0FBQTtJQUMzQiw4Q0FBdUIsQ0FBQTtJQUN2Qiw0Q0FBcUIsQ0FBQTtJQUNyQiw0REFBcUMsQ0FBQTtBQUN2QyxDQUFDLEVBTlcsbUJBQW1CLEdBQW5CLDJCQUFtQixLQUFuQiwyQkFBbUIsUUFNOUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25zdHJ1Y3QsIElDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgQWJ1c2VDYXNlIH0gZnJvbSBcIi4vYWJ1c2UtY2FzZVwiO1xuaW1wb3J0IHsgQXNwZWN0cyB9IGZyb20gXCIuL2FzcGVjdFwiO1xuXG5pbXBvcnQgeyBBdXRob3IgfSBmcm9tIFwiLi9hdXRob3JcIjtcbmltcG9ydCB7IERhdGFBc3NldCB9IGZyb20gXCIuL2RhdGEtYXNzZXRcIjtcbmltcG9ydCB7IE92ZXJ2aWV3IH0gZnJvbSBcIi4vb3ZlcnZpZXdcIjtcbmltcG9ydCB7IFJpc2tDYXRlZ29yeSB9IGZyb20gXCIuL3Jpc2stY2F0ZWdvcnlcIjtcbmltcG9ydCB7IFJpc2tUcmFja2luZywgUmlza1RyYWNraW5nUHJvcHMgfSBmcm9tIFwiLi9yaXNrLXRyYWNraW5nXCI7XG5pbXBvcnQgeyBSaXNrQXNwZWN0IH0gZnJvbSBcIi4vcmlza3NcIjtcbmltcG9ydCB7IFNlY3VyaXR5UmVxdWlyZW1lbnQgfSBmcm9tIFwiLi9zZWN1cml0eS1yZXF1aXJlbWVudFwiO1xuaW1wb3J0IHsgU2hhcmVkUnVudGltZSB9IGZyb20gXCIuL3NoYXJlZC1ydW50aW1lXCI7XG5pbXBvcnQgeyBUaHJlYWdpbGUgfSBmcm9tIFwiLi9zcGVjL3RocmVhdGdpbGUuZ2VuZXJhdGVkXCI7XG5pbXBvcnQgeyBJTW9kZWxTeW50aGVzaXplciwgTW9kZWxTeW50aGVzaXplciB9IGZyb20gXCIuL3N5bnRoZXNpemVyXCI7XG5pbXBvcnQgeyBUZWNobmljYWxBc3NldCB9IGZyb20gXCIuL3RlY2huaWNhbC1hc3NldFwiO1xuaW1wb3J0IHsgVHJ1c3RCb3VuZGFyeSB9IGZyb20gXCIuL3RydXN0LWJvdW5kYXJ5XCI7XG5cbmNvbnN0IE1PREVMX1NZTUJPTCA9IFN5bWJvbC5mb3IoXCJjZGt0Zy9Nb2RlbFwiKTtcblxuZXhwb3J0IGludGVyZmFjZSBRdWVzdGlvbiB7XG4gIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcbiAgcmVhZG9ubHkgYW5zd2VyPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1vZGVsUHJvcHMge1xuICAvKipcbiAgICogVmVyc2lvbiBvZiB0aGUgVGhyZWFnaWxlIHRvb2xraXRcbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcblxuICAvKipcbiAgICogVGl0bGUgb2YgdGhlIG1vZGVsXG4gICAqL1xuICByZWFkb25seSB0aXRsZT86IHN0cmluZztcblxuICAvKipcbiAgICogRGF0ZSBvZiB0aGUgbW9kZWxcbiAgICovXG4gIHJlYWRvbmx5IGRhdGU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEF1dGhvciBvZiB0aGUgbW9kZWxcbiAgICovXG4gIHJlYWRvbmx5IGF1dGhvcjogQXV0aG9yO1xuXG4gIC8qKlxuICAgKiBJbmRpdmlkdWFsIG1hbmFnZW1lbnQgc3VtbWFyeSBmb3IgdGhlIHJlcG9ydFxuICAgKi9cbiAgcmVhZG9ubHkgbWFuYWdlbWVudFN1bW1hcnk/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEJ1c2luZXNzIGNyaXRpY2FsaXR5IG9mIHRoZSB0YXJnZXRcbiAgICovXG4gIHJlYWRvbmx5IGJ1c2luZXNzQ3JpdGljYWxpdHk6IEJ1c2luZXNzQ3JpdGljYWxpdHk7XG5cbiAgLyoqXG4gICAqIEluZGl2aWR1YWwgYnVzaW5lc3Mgb3ZlcnZpZXcgZm9yIHRoZSByZXBvcnRcbiAgICovXG4gIHJlYWRvbmx5IGJ1c2luZXNzT3ZlcnZpZXc/OiBPdmVydmlldztcblxuICAvKipcbiAgICogSW5kaXZpZHVhbCB0ZWNobmljYWwgb3ZlcnZpZXcgZm9yIHRoZSByZXBvcnRcbiAgICovXG4gIHJlYWRvbmx5IHRlY2huaWNhbE92ZXJ2aWV3PzogT3ZlcnZpZXc7XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBxdWVzdGlvbnMgZm9yIHRoZSByZXBvcnRcbiAgICovXG4gIHJlYWRvbmx5IHF1ZXN0aW9ucz86IFF1ZXN0aW9uW107XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBhYnVzZSBjYXNlcyBmb3IgdGhlIHJlcG9ydFxuICAgKi9cbiAgcmVhZG9ubHkgYWJ1c2VDYXNlcz86IEFidXNlQ2FzZVtdO1xuXG4gIC8qKlxuICAgKiBDdXN0b20gc2VjdXJpdHkgcmVxdWlyZW1lbnRzIGZvciB0aGUgcmVwb3J0XG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eVJlcXVpcmVtZW50cz86IFNlY3VyaXR5UmVxdWlyZW1lbnRbXTtcbn1cblxuZXhwb3J0IGNsYXNzIE1vZGVsIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcHVibGljIHN0YXRpYyBpc01vZGVsKHg6IGFueSk6IHggaXMgTW9kZWwge1xuICAgIHJldHVybiB4ICE9PSBudWxsICYmIHR5cGVvZiB4ID09PSBcIm9iamVjdFwiICYmIE1PREVMX1NZTUJPTCBpbiB4O1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBvZihjb25zdHJ1Y3Q6IElDb25zdHJ1Y3QpOiBNb2RlbCB7XG4gICAgcmV0dXJuIF9sb29rdXAoY29uc3RydWN0KTtcblxuICAgIGZ1bmN0aW9uIF9sb29rdXAoYzogSUNvbnN0cnVjdCk6IE1vZGVsIHtcbiAgICAgIGlmIChNb2RlbC5pc01vZGVsKGMpKSB7XG4gICAgICAgIHJldHVybiBjO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBub2RlID0gYy5ub2RlO1xuXG4gICAgICBpZiAoIW5vZGUuc2NvcGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBObyBtb2RlbCBjb3VsZCBiZSBpZGVudGlmaWVkIGZvciB0aGUgY29uc3RydWN0IGF0IHBhdGggJyR7Y29uc3RydWN0Lm5vZGUucGF0aH0nYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gX2xvb2t1cChub2RlLnNjb3BlKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgdmVyc2lvbjogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGRhdGU/OiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBhdXRob3I6IEF1dGhvcjtcbiAgcHVibGljIHJlYWRvbmx5IG1hbmFnZW1lbnRTdW1tYXJ5Pzogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgYnVzaW5lc3NPdmVydmlldz86IE92ZXJ2aWV3O1xuICBwdWJsaWMgcmVhZG9ubHkgdGVjaG5pY2FsT3ZlcnZpZXc/OiBPdmVydmlldztcbiAgcHVibGljIHJlYWRvbmx5IGJ1c2luZXNzQ3JpdGljYWxpdHk6IEJ1c2luZXNzQ3JpdGljYWxpdHk7XG5cbiAgcHVibGljIHN5bnRoZXNpemVyOiBJTW9kZWxTeW50aGVzaXplcjtcblxuICBwcml2YXRlIHJlYWRvbmx5IHF1ZXN0aW9uczogTWFwPHN0cmluZywgc3RyaW5nPjtcbiAgcHJpdmF0ZSByZWFkb25seSBhYnVzZUNhc2VzOiBNYXA8c3RyaW5nLCBzdHJpbmc+O1xuICBwcml2YXRlIHJlYWRvbmx5IHNlY3VyaXR5UmVxdWlyZW1lbnRzOiBNYXA8c3RyaW5nLCBzdHJpbmc+O1xuICBwcml2YXRlIHJlYWRvbmx5IHRhZ3M6IFNldDxzdHJpbmc+O1xuICBwcml2YXRlIHJlYWRvbmx5IHJpc2tUcmFja2luZzogTWFwPHN0cmluZywgUmlza1RyYWNraW5nPjtcbiAgcHJpdmF0ZSByZWFkb25seSByYXdPdmVycmlkZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG4gIGNvbnN0cnVjdG9yKHByb2plY3Q6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE1vZGVsUHJvcHMpIHtcbiAgICBzdXBlcihwcm9qZWN0LCBpZCk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgTU9ERUxfU1lNQk9MLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4gICAgdGhpcy5zeW50aGVzaXplciA9IG5ldyBNb2RlbFN5bnRoZXNpemVyKHRoaXMsIGZhbHNlKTtcblxuICAgIHRoaXMudmVyc2lvbiA9IHByb3BzLnZlcnNpb247XG4gICAgdGhpcy50aXRsZSA9IHByb3BzLnRpdGxlID8/IGlkO1xuICAgIHRoaXMuZGF0ZSA9IHByb3BzLmRhdGVcbiAgICAgID8gbmV3IERhdGUocHJvcHMuZGF0ZSkudG9JU09TdHJpbmcoKS5zcGxpdChcIlRcIilbMF1cbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIHRoaXMuYXV0aG9yID0gcHJvcHMuYXV0aG9yO1xuICAgIHRoaXMubWFuYWdlbWVudFN1bW1hcnkgPSBwcm9wcy5tYW5hZ2VtZW50U3VtbWFyeTtcbiAgICB0aGlzLmJ1c2luZXNzQ3JpdGljYWxpdHkgPSBwcm9wcy5idXNpbmVzc0NyaXRpY2FsaXR5O1xuXG4gICAgdGhpcy5idXNpbmVzc092ZXJ2aWV3ID0gcHJvcHMuYnVzaW5lc3NPdmVydmlldztcbiAgICBpZiAoXG4gICAgICB0aGlzLmJ1c2luZXNzT3ZlcnZpZXcgJiZcbiAgICAgIHRoaXMuYnVzaW5lc3NPdmVydmlldy5pbWFnZXMgJiZcbiAgICAgIHRoaXMuYnVzaW5lc3NPdmVydmlldy5pbWFnZXMubGVuZ3RoID4gMFxuICAgICkge1xuICAgICAgdGhpcy5idXNpbmVzc092ZXJ2aWV3LmltYWdlcy5mb3JFYWNoKChpKSA9PiBpLl9iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0aGlzLnRlY2huaWNhbE92ZXJ2aWV3ID0gcHJvcHMudGVjaG5pY2FsT3ZlcnZpZXc7XG5cbiAgICB0aGlzLnF1ZXN0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgcHJvcHMucXVlc3Rpb25zPy5mb3JFYWNoKChxKSA9PiB7XG4gICAgICB0aGlzLmFkZFF1ZXN0aW9uKHEudGV4dCwgcS5hbnN3ZXIpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hYnVzZUNhc2VzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICBpZiAocHJvcHMuYWJ1c2VDYXNlcyAmJiBwcm9wcy5hYnVzZUNhc2VzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYWRkQWJ1c2VDYXNlcyguLi5wcm9wcy5hYnVzZUNhc2VzKTtcbiAgICB9XG5cbiAgICB0aGlzLnNlY3VyaXR5UmVxdWlyZW1lbnRzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICBpZiAocHJvcHMuc2VjdXJpdHlSZXF1aXJlbWVudHMgJiYgcHJvcHMuc2VjdXJpdHlSZXF1aXJlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5hZGRTZWN1cml0eVJlcXVpcmVtZW50cyguLi5wcm9wcy5zZWN1cml0eVJlcXVpcmVtZW50cyk7XG4gICAgfVxuXG4gICAgdGhpcy50YWdzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgdGhpcy5yaXNrVHJhY2tpbmcgPSBuZXcgTWFwPHN0cmluZywgUmlza1RyYWNraW5nPigpO1xuICAgIHRoaXMucmF3T3ZlcnJpZGVzID0ge307XG5cbiAgICBBc3BlY3RzLm9mKHRoaXMpLmFkZChuZXcgUmlza0FzcGVjdCgpKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRUYWcodGFnOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFkZFRhZ3ModGFnKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRUYWdzKC4uLnRhZ3M6IHN0cmluZ1tdKSB7XG4gICAgdGFncy5mb3JFYWNoKCh0YWcpID0+IHtcbiAgICAgIHRoaXMudGFncy5hZGQodGFnKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRRdWVzdGlvbih0ZXh0OiBzdHJpbmcsIGFuc3dlciA9IFwiXCIpIHtcbiAgICAvLyBcIlwiIGFzIGFuc3dlciBzaWduYWxzIFwidW5hbnN3ZXJlZFwiXG4gICAgaWYgKHRoaXMucXVlc3Rpb25zLmhhcyh0ZXh0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBEdXBsaWNhdGVkIHF1ZXN0aW9uIFwiJHt0ZXh0fVwiYCk7XG4gICAgfVxuXG4gICAgdGhpcy5xdWVzdGlvbnMuc2V0KHRleHQsIGFuc3dlcik7XG4gIH1cblxuICBwdWJsaWMgYWRkQWJ1c2VDYXNlcyguLi5jYXNlczogQWJ1c2VDYXNlW10pIHtcbiAgICBjYXNlcy5mb3JFYWNoKChjKSA9PiB7XG4gICAgICBpZiAodGhpcy5hYnVzZUNhc2VzLmhhcyhjLm5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRHVwbGljYXRlZCBhYnVzZSBjYXNlIFwiJHtjLm5hbWV9XCJgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hYnVzZUNhc2VzLnNldChjLm5hbWUsIGMuZGVzY3JpcHRpb24pO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFkZFNlY3VyaXR5UmVxdWlyZW1lbnRzKC4uLnJlcXVpcmVtZW50czogU2VjdXJpdHlSZXF1aXJlbWVudFtdKSB7XG4gICAgcmVxdWlyZW1lbnRzLmZvckVhY2goKHIpID0+IHtcbiAgICAgIGlmICh0aGlzLmFidXNlQ2FzZXMuaGFzKHIubmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEdXBsaWNhdGVkIHNlY3VyaXR5IHJlcXVpcmVtZW50IFwiJHtyLm5hbWV9XCJgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZWN1cml0eVJlcXVpcmVtZW50cy5zZXQoci5uYW1lLCByLmRlc2NyaXB0aW9uKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyB0cmFja1Jpc2soaWQ6IHN0cmluZywgb3B0aW9uczogUmlza1RyYWNraW5nUHJvcHMgPSB7fSkge1xuICAgIGlmICh0aGlzLnJpc2tUcmFja2luZy5oYXMoaWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYER1cGxpY2F0ZWQgcmlzayB0cmFja2luZyBcIiR7aWR9XCJgKTtcbiAgICB9XG5cbiAgICB0aGlzLnJpc2tUcmFja2luZy5zZXQoaWQsIG5ldyBSaXNrVHJhY2tpbmcoaWQsIG9wdGlvbnMpKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRPdmVycmlkZShwYXRoOiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKSB7XG4gICAgY29uc3QgcGFydHMgPSBwYXRoLnNwbGl0KFwiLlwiKTtcbiAgICBsZXQgY3VycjogYW55ID0gdGhpcy5yYXdPdmVycmlkZXM7XG5cbiAgICB3aGlsZSAocGFydHMubGVuZ3RoID4gMSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgIGNvbnN0IGtleSA9IHBhcnRzLnNoaWZ0KCkhO1xuXG4gICAgICAvLyBpZiB3ZSBjYW4ndCByZWN1cnNlIGZ1cnRoZXIgb3IgdGhlIHByZXZpb3VzIHZhbHVlIGlzIG5vdCBhblxuICAgICAgLy8gb2JqZWN0IG92ZXJ3cml0ZSBpdCB3aXRoIGFuIG9iamVjdC5cbiAgICAgIGNvbnN0IGlzT2JqZWN0ID1cbiAgICAgICAgY3VycltrZXldICE9IG51bGwgJiZcbiAgICAgICAgdHlwZW9mIGN1cnJba2V5XSA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICAhQXJyYXkuaXNBcnJheShjdXJyW2tleV0pO1xuICAgICAgaWYgKCFpc09iamVjdCkge1xuICAgICAgICBjdXJyW2tleV0gPSB7fTtcbiAgICAgIH1cblxuICAgICAgY3VyciA9IGN1cnJba2V5XTtcbiAgICB9XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgIGNvbnN0IGxhc3RLZXkgPSBwYXJ0cy5zaGlmdCgpITtcbiAgICBjdXJyW2xhc3RLZXldID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgX3RvVGhyZWFnaWxlKCk6IFRocmVhZ2lsZSB7XG4gICAgY29uc3QgZGF0YUFzc2V0cyA9IG5ldyBBcnJheTxEYXRhQXNzZXQ+KCk7XG4gICAgY29uc3QgdGVjaG5pY2FsQXNzZXRzID0gbmV3IEFycmF5PFRlY2huaWNhbEFzc2V0PigpO1xuICAgIGNvbnN0IHRydXN0Qm91bmRhcmllcyA9IG5ldyBBcnJheTxUcnVzdEJvdW5kYXJ5PigpO1xuICAgIGNvbnN0IHNoYXJlZFJ1bnRpbWVzID0gbmV3IEFycmF5PFNoYXJlZFJ1bnRpbWU+KCk7XG4gICAgY29uc3QgaW5kaXZpZHVhbFJpc2tDYXRlZ29yaWVzID0gbmV3IEFycmF5PFJpc2tDYXRlZ29yeT4oKTtcblxuICAgIHRoaXMubm9kZS5maW5kQWxsKCkubWFwKChuKSA9PiB7XG4gICAgICBpZiAobiBpbnN0YW5jZW9mIERhdGFBc3NldCkge1xuICAgICAgICBkYXRhQXNzZXRzLnB1c2gobik7XG4gICAgICB9IGVsc2UgaWYgKG4gaW5zdGFuY2VvZiBUZWNobmljYWxBc3NldCkge1xuICAgICAgICB0ZWNobmljYWxBc3NldHMucHVzaChuKTtcbiAgICAgIH0gZWxzZSBpZiAobiBpbnN0YW5jZW9mIFRydXN0Qm91bmRhcnkpIHtcbiAgICAgICAgdHJ1c3RCb3VuZGFyaWVzLnB1c2gobik7XG4gICAgICB9IGVsc2UgaWYgKG4gaW5zdGFuY2VvZiBTaGFyZWRSdW50aW1lKSB7XG4gICAgICAgIHNoYXJlZFJ1bnRpbWVzLnB1c2gobik7XG4gICAgICB9IGVsc2UgaWYgKG4gaW5zdGFuY2VvZiBSaXNrQ2F0ZWdvcnkpIHtcbiAgICAgICAgaW5kaXZpZHVhbFJpc2tDYXRlZ29yaWVzLnB1c2gobik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCB0aHJlYWdpbGU6IGFueSA9IHtcbiAgICAgIHRocmVhZ2lsZV92ZXJzaW9uOiB0aGlzLnZlcnNpb24sXG4gICAgICB0aXRsZTogdGhpcy50aXRsZSxcbiAgICAgIGRhdGE6IHRoaXMuZGF0ZSxcbiAgICAgIGF1dGhvcjogdGhpcy5hdXRob3IuX3RvVGhyZWFnaWxlKCksXG4gICAgICBtYW5hZ2VtZW50X3N1bW1hcnlfY29tbWVudDogdGhpcy5tYW5hZ2VtZW50U3VtbWFyeSxcbiAgICAgIGJ1c2luZXNzX292ZXJ2aWV3OiB0aGlzLmJ1c2luZXNzT3ZlcnZpZXc/Ll90b1RocmVhZ2lsZSgpLFxuICAgICAgdGVjaG5pY2FsX292ZXJ2aWV3OiB0aGlzLnRlY2huaWNhbE92ZXJ2aWV3Py5fdG9UaHJlYWdpbGUoKSxcbiAgICAgIGJ1c2luZXNzX2NyaXRpY2FsaXR5OiB0aGlzLmJ1c2luZXNzQ3JpdGljYWxpdHksXG4gICAgICBxdWVzdGlvbnM6IE9iamVjdC5mcm9tRW50cmllcyh0aGlzLnF1ZXN0aW9ucyksXG4gICAgICBhYnVzZV9jYXNlczogT2JqZWN0LmZyb21FbnRyaWVzKHRoaXMuYWJ1c2VDYXNlcyksXG4gICAgICBzZWN1cml0eV9yZXF1aXJlbWVudHM6IE9iamVjdC5mcm9tRW50cmllcyh0aGlzLnNlY3VyaXR5UmVxdWlyZW1lbnRzKSxcbiAgICAgIHRhZ3NfYXZhaWxhYmxlOiBBcnJheS5mcm9tKHRoaXMudGFncyksXG4gICAgfTtcblxuICAgIHRocmVhZ2lsZS5kYXRhX2Fzc2V0cyA9IGRhdGFBc3NldHMucmVkdWNlKFxuICAgICAgKHByZXYsIGN1cnJlbnQpID0+IE9iamVjdC5hc3NpZ24ocHJldiwgY3VycmVudC5fdG9UaHJlYWdpbGUoKSksXG4gICAgICB7fVxuICAgICk7XG5cbiAgICB0aHJlYWdpbGUudGVjaG5pY2FsX2Fzc2V0cyA9IHRlY2huaWNhbEFzc2V0cy5yZWR1Y2UoXG4gICAgICAocHJldiwgY3VycmVudCkgPT4gT2JqZWN0LmFzc2lnbihwcmV2LCBjdXJyZW50Ll90b1RocmVhZ2lsZSgpKSxcbiAgICAgIHt9XG4gICAgKTtcblxuICAgIHRocmVhZ2lsZS50cnVzdF9ib3VuZGFyaWVzID0gdHJ1c3RCb3VuZGFyaWVzLnJlZHVjZShcbiAgICAgIChwcmV2LCBjdXJyZW50KSA9PiBPYmplY3QuYXNzaWduKHByZXYsIGN1cnJlbnQuX3RvVGhyZWFnaWxlKCkpLFxuICAgICAge31cbiAgICApO1xuXG4gICAgdGhyZWFnaWxlLnNoYXJlZF9ydW50aW1lcyA9IHNoYXJlZFJ1bnRpbWVzLnJlZHVjZShcbiAgICAgIChwcmV2LCBjdXJyZW50KSA9PiBPYmplY3QuYXNzaWduKHByZXYsIGN1cnJlbnQuX3RvVGhyZWFnaWxlKCkpLFxuICAgICAge31cbiAgICApO1xuXG4gICAgdGhyZWFnaWxlLmluZGl2aWR1YWxfcmlza19jYXRlZ29yaWVzID0gaW5kaXZpZHVhbFJpc2tDYXRlZ29yaWVzLnJlZHVjZShcbiAgICAgIChwcmV2LCBjdXJyZW50KSA9PiBPYmplY3QuYXNzaWduKHByZXYsIGN1cnJlbnQuX3RvVGhyZWFnaWxlKCkpLFxuICAgICAge31cbiAgICApO1xuXG4gICAgaWYgKHRoaXMucmlza1RyYWNraW5nLnNpemUgPiAwKSB7XG4gICAgICB0aHJlYWdpbGUucmlza190cmFja2luZyA9IEFycmF5LmZyb20odGhpcy5yaXNrVHJhY2tpbmcudmFsdWVzKCkpLnJlZHVjZShcbiAgICAgICAgKHByZXYsIGN1cnJlbnQpID0+IE9iamVjdC5hc3NpZ24ocHJldiwgY3VycmVudC5fdG9UaHJlYWdpbGUoKSksXG4gICAgICAgIHt9XG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAuLi50aHJlYWdpbGUsXG4gICAgICAuLi4oT2JqZWN0LmtleXModGhpcy5yYXdPdmVycmlkZXMpLmxlbmd0aCA+IDBcbiAgICAgICAgPyB7IG92ZXJyaWRlczogeyBzdGFjazogT2JqZWN0LmtleXModGhpcy5yYXdPdmVycmlkZXMpIH0gfVxuICAgICAgICA6IHt9KSxcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBlbnVtIEJ1c2luZXNzQ3JpdGljYWxpdHkge1xuICBBUkNISVZFID0gXCJhcmNoaXZlXCIsXG4gIE9QRVJBVElPTkFMID0gXCJvcGVyYXRpb25hbFwiLFxuICBJTVBPUlRBTlQgPSBcImltcG9ydGFudFwiLFxuICBDUklUSUNBTCA9IFwiY3JpdGljYWxcIixcbiAgTUlTU0lPTl9DUklUSUNBTCA9IFwibWlzc2lvbi1jcml0aWNhbFwiLFxufVxuIl19