@aws/pdk
Version:
All documentation is located at: https://aws.github.io/aws-pdk
194 lines • 31.2 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CdkGraphDiagramPlugin = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 */
const child_process_1 = require("child_process");
const path = require("path");
const cdk_graph_1 = require("../cdk-graph");
const chalk = require("chalk"); // eslint-disable-line @typescript-eslint/no-require-imports
const fs = require("fs-extra");
const adapter_1 = require("ts-graphviz/adapter");
const config_1 = require("./config");
const debug_1 = require("./internal/debug");
const diagram_1 = require("./internal/graphviz/diagram");
const svg_1 = require("./internal/utils/svg");
/**
* CdkGraphDiagramPlugin is a {@link ICdkGraphPlugin CdkGraph Plugin} implementation for generating
* diagram artifacts from the {@link CdkGraph} framework.
*/
class CdkGraphDiagramPlugin {
/** Get standardized artifact id for diagram artifacts */
static artifactId(name, format) {
if (name === config_1.DEFAULT_DIAGRAM_NAME) {
return `${this.ARTIFACT_NS}_${format.toUpperCase()}`;
}
return `${this.ARTIFACT_NS}_${name.toUpperCase()}_${format.toUpperCase()}`;
}
/** Get standardized artifact file name for diagram artifacts */
static artifactFilename(name, format) {
if (name === config_1.DEFAULT_DIAGRAM_NAME) {
return `${this.ARTIFACT_NS.toLowerCase()}.${format}`;
}
return `${this.ARTIFACT_NS.toLowerCase()}.${name}.${format}`;
}
/** @inheritdoc */
get id() {
return CdkGraphDiagramPlugin.ID;
}
/** @inheritdoc */
get version() {
return CdkGraphDiagramPlugin.VERSION;
}
/** Get default dot artifact */
get defaultDotArtifact() {
try {
return this.getDiagramArtifact(config_1.DEFAULT_DIAGRAM_NAME, config_1.DiagramFormat.DOT);
}
catch {
return;
}
}
/** Get default PNG artifact */
get defaultPngArtifact() {
try {
return this.getDiagramArtifact(config_1.DEFAULT_DIAGRAM_NAME, config_1.DiagramFormat.PNG);
}
catch {
return;
}
}
/** Get diagram plugin config */
get config() {
if (this._config != null) {
return this._config;
}
throw new Error("Plugin config has not been instantiated, ensure bind is called");
}
constructor(config) {
/** @inheritdoc */
this.dependencies = [];
/** @inheritdoc */
this.bind = (graph) => {
this._graph = graph;
const rc = (graph.config[CdkGraphDiagramPlugin.ID] ||
{});
let diagrams = [
...(rc.diagrams || []),
...(this._config?.diagrams || []),
];
if (diagrams.length === 0) {
diagrams = [config_1.DEFAULT_DIAGRAM];
}
this._config = {
defaults: {
...config_1.CONFIG_DEFAULTS,
...rc.defaults,
...this._config?.defaults,
},
diagrams,
};
};
this.streamToBuffer = (stream) => {
const chunks = [];
return new Promise((resolve, reject) => {
stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
stream.on("error", (err) => reject(err));
stream.on("end", () => resolve(Buffer.concat(chunks)));
});
};
this.isGraphvizInstalledGlobally = () => {
try {
(0, child_process_1.execSync)("dot -V", { stdio: "ignore" });
return true;
}
catch (e) {
console.warn(chalk.yellowBright("SVG and PNG are not supported as graphviz is not installed. Please install graphviz (https://graphviz.org/download/) globally and re-try."));
return false;
}
};
/** @inheritdoc */
this.report = async (context) => {
const pluginConfig = this.config;
for (const diagramConfig of pluginConfig.diagrams) {
const config = {
...(diagramConfig.ignoreDefaults ? {} : pluginConfig.defaults),
...diagramConfig,
};
let formats = Array.isArray(config.format)
? config.format
: [config.format || config_1.DiagramFormat.PNG];
if (!formats.length) {
throw new Error(`Diagram config specifies empty list of formats; must provide at least 1 or undefined to use default.`);
}
// each diagram is destructive, so we need a clone
const store = context.store.clone();
if (config.filterPlan) {
(0, cdk_graph_1.performGraphFilterPlan)(store, config.filterPlan);
}
const generatePng = formats.includes(config_1.DiagramFormat.PNG);
const generateSvg = generatePng || formats.includes(config_1.DiagramFormat.SVG);
const generateDot = generateSvg || formats.includes(config_1.DiagramFormat.DOT);
debug_1.IS_DEBUG &&
context.writeArtifact(this, "filtered.graph." + config.name + "", "debug/filtered-graph/" + config.name + ".json", JSON.stringify(store.serialize(), null, 2), "DEBUG");
const diagram = (0, diagram_1.buildDiagram)(store, {
title: config.title,
preset: config.filterPlan?.preset,
theme: config.theme,
nodePositions: config.nodePositions,
});
// Only the neato- and fdp layout engines support node positions
const layout = config.nodePositions ? "fdp" : undefined;
const dot = diagram.toDot();
if (generateDot) {
// Graphviz provider
context.writeArtifact(this, CdkGraphDiagramPlugin.artifactId(config.name, config_1.DiagramFormat.DOT), CdkGraphDiagramPlugin.artifactFilename(config.name, config_1.DiagramFormat.DOT), dot, `Diagram generated "dot" file for ${config.name} - "${config.title}"`);
if (generateSvg && this.isGraphvizInstalledGlobally()) {
const svgFile = path.join(context.outdir, CdkGraphDiagramPlugin.artifactFilename(config.name, config_1.DiagramFormat.SVG));
const svg = await this.streamToBuffer(await (0, adapter_1.toStream)(dot, { format: "svg", layout }));
const resolvedSvg = await (0, svg_1.resolveSvgAwsArchAssetImagesInline)(svg.toString());
fs.ensureDirSync(path.dirname(svgFile));
fs.writeFileSync(svgFile, resolvedSvg);
context.logArtifact(this, CdkGraphDiagramPlugin.artifactId(config.name, config_1.DiagramFormat.SVG), svgFile, `Diagram generated "svg" file for ${config.name} - "${config.title}"`);
if (generatePng && this.isGraphvizInstalledGlobally()) {
const pngFile = path.join(context.outdir, CdkGraphDiagramPlugin.artifactFilename(config.name, config_1.DiagramFormat.PNG));
try {
// SVG's don't render correctly in non-svg formats. Replace with png equivalent.
const pngifiedDot = dot.replace(/\.svg/g, ".png");
const png = await this.streamToBuffer(await (0, adapter_1.toStream)(pngifiedDot, {
format: "png",
layout,
}));
fs.ensureDirSync(path.dirname(pngFile));
fs.writeFileSync(pngFile, png);
context.logArtifact(this, CdkGraphDiagramPlugin.artifactId(config.name, config_1.DiagramFormat.PNG), pngFile, `Diagram generated "png" file for ${config.name} - "${config.title}"`);
}
catch (error) {
console.error(error);
throw new Error(`Failed to generate PNG diagram for ${config.name} at "${pngFile}" - ${String(error)}`);
}
}
}
}
// NB: add drawio provider support here
}
};
this._config = config;
}
/** Get diagram artifact for a given name and format */
getDiagramArtifact(name, format) {
return this._graph?.graphContext?.getArtifact(CdkGraphDiagramPlugin.artifactId(name, format));
}
}
exports.CdkGraphDiagramPlugin = CdkGraphDiagramPlugin;
_a = JSII_RTTI_SYMBOL_1;
CdkGraphDiagramPlugin[_a] = { fqn: "@aws/pdk.cdk_graph_plugin_diagram.CdkGraphDiagramPlugin", version: "0.26.13" };
/** Namespace for artifacts of the diagram plugin */
CdkGraphDiagramPlugin.ARTIFACT_NS = "DIAGRAM";
/** Fixed id of the diagram plugin */
CdkGraphDiagramPlugin.ID = "diagram";
/** Current semantic version of the diagram plugin */
CdkGraphDiagramPlugin.VERSION = "0.0.0";
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7c0NBQ3NDO0FBQ3RDLGlEQUF5QztBQUN6Qyw2QkFBNkI7QUFDN0IsOENBUXdCO0FBQ3hCLCtCQUFnQyxDQUFDLDREQUE0RDtBQUM3RiwrQkFBK0I7QUFDL0IsaURBQStDO0FBQy9DLHFDQU9rQjtBQUNsQiw0Q0FBNEM7QUFDNUMseURBQTJEO0FBQzNELDhDQUEwRTtBQUUxRTs7O0dBR0c7QUFDSCxNQUFhLHFCQUFxQjtJQVFoQyx5REFBeUQ7SUFDekQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFZLEVBQUUsTUFBcUI7UUFDbkQsSUFBSSxJQUFJLEtBQUssNkJBQW9CLEVBQUUsQ0FBQztZQUNsQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztRQUN2RCxDQUFDO1FBQ0QsT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLE1BQU0sQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDO0lBQzdFLENBQUM7SUFDRCxnRUFBZ0U7SUFDaEUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLElBQVksRUFBRSxNQUFxQjtRQUN6RCxJQUFJLElBQUksS0FBSyw2QkFBb0IsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ3ZELENBQUM7UUFDRCxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsSUFBSSxJQUFJLElBQUksTUFBTSxFQUFFLENBQUM7SUFDL0QsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixJQUFJLEVBQUU7UUFDSixPQUFPLHFCQUFxQixDQUFDLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBQ0Qsa0JBQWtCO0lBQ2xC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Q0FBdUM7WUFDekMsQ0FBQztRQUNILENBQUMsQ0FBQztRQW5NQSxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztJQUN4QixDQUFDO0lBRUQsdURBQXVEO0lBQ3ZELGtCQUFrQixDQUNoQixJQUFZLEVBQ1osTUFBcUI7UUFFckIsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxXQUFXLENBQzNDLHFCQUFxQixDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQy9DLENBQUM7SUFDSixDQUFDOztBQWpGSCxzREEwUUM7OztBQXpRQyxvREFBb0Q7QUFDcEMsaUNBQVcsR0FBRyxTQUFTLEFBQVosQ0FBYTtBQUN4QyxxQ0FBcUM7QUFDckIsd0JBQUUsR0FBRyxTQUFTLEFBQVosQ0FBYTtBQUMvQixxREFBcUQ7QUFDckMsNkJBQU8sR0FBRyxPQUFPLEFBQVYsQ0FBVyIsInNvdXJjZXNDb250ZW50IjpbIi8qISBDb3B5cmlnaHQgW0FtYXpvbi5jb21dKGh0dHA6Ly9hbWF6b24uY29tLyksIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMCAqL1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHtcbiAgQ2RrR3JhcGgsXG4gIENka0dyYXBoQXJ0aWZhY3QsXG4gIENka0dyYXBoQ29udGV4dCxcbiAgSUNka0dyYXBoUGx1Z2luLFxuICBJR3JhcGhQbHVnaW5CaW5kQ2FsbGJhY2ssXG4gIElHcmFwaFJlcG9ydENhbGxiYWNrLFxuICBwZXJmb3JtR3JhcGhGaWx0ZXJQbGFuLFxufSBmcm9tIFwiQGF3cy9jZGstZ3JhcGhcIjtcbmltcG9ydCBjaGFsayA9IHJlcXVpcmUoXCJjaGFsa1wiKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG5pbXBvcnQgKiBhcyBmcyBmcm9tIFwiZnMtZXh0cmFcIjtcbmltcG9ydCB7IHRvU3RyZWFtIH0gZnJvbSBcInRzLWdyYXBodml6L2FkYXB0ZXJcIjtcbmltcG9ydCB7XG4gIENPTkZJR19ERUZBVUxUUyxcbiAgREVGQVVMVF9ESUFHUkFNLFxuICBERUZBVUxUX0RJQUdSQU1fTkFNRSxcbiAgRGlhZ3JhbUZvcm1hdCxcbiAgSURpYWdyYW1Db25maWcsXG4gIElQbHVnaW5Db25maWcsXG59IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0IHsgSVNfREVCVUcgfSBmcm9tIFwiLi9pbnRlcm5hbC9kZWJ1Z1wiO1xuaW1wb3J0IHsgYnVpbGREaWFncmFtIH0gZnJvbSBcIi4vaW50ZXJuYWwvZ3JhcGh2aXovZGlhZ3JhbVwiO1xuaW1wb3J0IHsgcmVzb2x2ZVN2Z0F3c0FyY2hBc3NldEltYWdlc0lubGluZSB9IGZyb20gXCIuL2ludGVybmFsL3V0aWxzL3N2Z1wiO1xuXG4vKipcbiAqIENka0dyYXBoRGlhZ3JhbVBsdWdpbiBpcyBhIHtAbGluayBJQ2RrR3JhcGhQbHVnaW4gQ2RrR3JhcGggUGx1Z2lufSBpbXBsZW1lbnRhdGlvbiBmb3IgZ2VuZXJhdGluZ1xuICogZGlhZ3JhbSBhcnRpZmFjdHMgZnJvbSB0aGUge0BsaW5rIENka0dyYXBofSBmcmFtZXdvcmsuXG4gKi9cbmV4cG9ydCBjbGFzcyBDZGtHcmFwaERpYWdyYW1QbHVnaW4gaW1wbGVtZW50cyBJQ2RrR3JhcGhQbHVnaW4ge1xuICAvKiogTmFtZXNwYWNlIGZvciBhcnRpZmFjdHMgb2YgdGhlIGRpYWdyYW0gcGx1Z2luICovXG4gIHN0YXRpYyByZWFkb25seSBBUlRJRkFDVF9OUyA9IFwiRElBR1JBTVwiO1xuICAvKiogRml4ZWQgaWQgb2YgdGhlIGRpYWdyYW0gcGx1Z2luICovXG4gIHN0YXRpYyByZWFkb25seSBJRCA9IFwiZGlhZ3JhbVwiO1xuICAvKiogQ3VycmVudCBzZW1hbnRpYyB2ZXJzaW9uIG9mIHRoZSBkaWFncmFtIHBsdWdpbiAqL1xuICBzdGF0aWMgcmVhZG9ubHkgVkVSU0lPTiA9IFwiMC4wLjBcIjtcblxuICAvKiogR2V0IHN0YW5kYXJkaXplZCBhcnRpZmFjdCBpZCBmb3IgZGlhZ3JhbSBhcnRpZmFjdHMgKi9cbiAgc3RhdGljIGFydGlmYWN0SWQobmFtZTogc3RyaW5nLCBmb3JtYXQ6IERpYWdyYW1Gb3JtYXQpOiBzdHJpbmcge1xuICAgIGlmIChuYW1lID09PSBERUZBVUxUX0RJQUdSQU1fTkFNRSkge1xuICAgICAgcmV0dXJuIGAke3RoaXMuQVJUSUZBQ1RfTlN9XyR7Zm9ybWF0LnRvVXBwZXJDYXNlKCl9YDtcbiAgICB9XG4gICAgcmV0dXJuIGAke3RoaXMuQVJUSUZBQ1RfTlN9XyR7bmFtZS50b1VwcGVyQ2FzZSgpfV8ke2Zvcm1hdC50b1VwcGVyQ2FzZSgpfWA7XG4gIH1cbiAgLyoqIEdldCBzdGFuZGFyZGl6ZWQgYXJ0aWZhY3QgZmlsZSBuYW1lIGZvciBkaWFncmFtIGFydGlmYWN0cyAqL1xuICBzdGF0aWMgYXJ0aWZhY3RGaWxlbmFtZShuYW1lOiBzdHJpbmcsIGZvcm1hdDogRGlhZ3JhbUZvcm1hdCk6IHN0cmluZyB7XG4gICAgaWYgKG5hbWUgPT09IERFRkFVTFRfRElBR1JBTV9OQU1FKSB7XG4gICAgICByZXR1cm4gYCR7dGhpcy5BUlRJRkFDVF9OUy50b0xvd2VyQ2FzZSgpfS4ke2Zvcm1hdH1gO1xuICAgIH1cbiAgICByZXR1cm4gYCR7dGhpcy5BUlRJRkFDVF9OUy50b0xvd2VyQ2FzZSgpfS4ke25hbWV9LiR7Zm9ybWF0fWA7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgZ2V0IGlkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIENka0dyYXBoRGlhZ3JhbVBsdWdpbi5JRDtcbiAgfVxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgZ2V0IHZlcnNpb24oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gQ2RrR3JhcGhEaWFncmFtUGx1Z2luLlZFUlNJT047XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgcmVhZG9ubHkgZGVwZW5kZW5jaWVzPzogc3RyaW5nW10gPSBbXTtcblxuICAvKiogQGludGVybmFsICovXG4gIHByaXZhdGUgX2dyYXBoPzogQ2RrR3JhcGg7XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcml2YXRlIF9jb25maWc/OiBJUGx1Z2luQ29uZmlnO1xuXG4gIC8qKiBHZXQgZGVmYXVsdCBkb3QgYXJ0aWZhY3QgKi9cbiAgZ2V0IGRlZmF1bHREb3RBcnRpZmFjdCgpOiBDZGtHcmFwaEFydGlmYWN0IHwgdW5kZWZpbmVkIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0RGlhZ3JhbUFydGlmYWN0KERFRkFVTFRfRElBR1JBTV9OQU1FLCBEaWFncmFtRm9ybWF0LkRPVCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgLyoqIEdldCBkZWZhdWx0IFBORyBhcnRpZmFjdCAqL1xuICBnZXQgZGVmYXVsdFBuZ0FydGlmYWN0KCk6IENka0dyYXBoQXJ0aWZhY3QgfCB1bmRlZmluZWQge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXREaWFncmFtQXJ0aWZhY3QoREVGQVVMVF9ESUFHUkFNX05BTUUsIERpYWdyYW1Gb3JtYXQuUE5HKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICAvKiogR2V0IGRpYWdyYW0gcGx1Z2luIGNvbmZpZyAqL1xuICBnZXQgY29uZmlnKCk6IElQbHVnaW5Db25maWcge1xuICAgIGlmICh0aGlzLl9jb25maWcgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NvbmZpZztcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJQbHVnaW4gY29uZmlnIGhhcyBub3QgYmVlbiBpbnN0YW50aWF0ZWQsIGVuc3VyZSBiaW5kIGlzIGNhbGxlZFwiXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZz86IElQbHVnaW5Db25maWcpIHtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gIH1cblxuICAvKiogR2V0IGRpYWdyYW0gYXJ0aWZhY3QgZm9yIGEgZ2l2ZW4gbmFtZSBhbmQgZm9ybWF0ICovXG4gIGdldERpYWdyYW1BcnRpZmFjdChcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgZm9ybWF0OiBEaWFncmFtRm9ybWF0XG4gICk6IENka0dyYXBoQXJ0aWZhY3QgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9ncmFwaD8uZ3JhcGhDb250ZXh0Py5nZXRBcnRpZmFjdChcbiAgICAgIENka0dyYXBoRGlhZ3JhbVBsdWdpbi5hcnRpZmFjdElkKG5hbWUsIGZvcm1hdClcbiAgICApO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGJpbmQ6IElHcmFwaFBsdWdpbkJpbmRDYWxsYmFjayA9IChncmFwaDogQ2RrR3JhcGgpOiB2b2lkID0+IHtcbiAgICB0aGlzLl9ncmFwaCA9IGdyYXBoO1xuICAgIGNvbnN0IHJjID0gKGdyYXBoLmNvbmZpZ1tDZGtHcmFwaERpYWdyYW1QbHVnaW4uSURdIHx8XG4gICAgICB7fSkgYXMgUGFydGlhbDxJUGx1Z2luQ29uZmlnPjtcbiAgICBsZXQgZGlhZ3JhbXM6IElEaWFncmFtQ29uZmlnW10gPSBbXG4gICAgICAuLi4ocmMuZGlhZ3JhbXMgfHwgW10pLFxuICAgICAgLi4uKHRoaXMuX2NvbmZpZz8uZGlhZ3JhbXMgfHwgW10pLFxuICAgIF07XG4gICAgaWYgKGRpYWdyYW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZGlhZ3JhbXMgPSBbREVGQVVMVF9ESUFHUkFNXTtcbiAgICB9XG4gICAgdGhpcy5fY29uZmlnID0ge1xuICAgICAgZGVmYXVsdHM6IHtcbiAgICAgICAgLi4uQ09ORklHX0RFRkFVTFRTLFxuICAgICAgICAuLi5yYy5kZWZhdWx0cyxcbiAgICAgICAgLi4udGhpcy5fY29uZmlnPy5kZWZhdWx0cyxcbiAgICAgIH0sXG4gICAgICBkaWFncmFtcyxcbiAgICB9O1xuICB9O1xuXG4gIHByaXZhdGUgc3RyZWFtVG9CdWZmZXIgPSAoc3RyZWFtOiBOb2RlSlMuUmVhZGFibGVTdHJlYW0pOiBQcm9taXNlPEJ1ZmZlcj4gPT4ge1xuICAgIGNvbnN0IGNodW5rczogQnVmZmVyW10gPSBbXTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgc3RyZWFtLm9uKFwiZGF0YVwiLCAoY2h1bmspID0+IGNodW5rcy5wdXNoKEJ1ZmZlci5mcm9tKGNodW5rKSkpO1xuICAgICAgc3RyZWFtLm9uKFwiZXJyb3JcIiwgKGVycikgPT4gcmVqZWN0KGVycikpO1xuICAgICAgc3RyZWFtLm9uKFwiZW5kXCIsICgpID0+IHJlc29sdmUoQnVmZmVyLmNvbmNhdChjaHVua3MpKSk7XG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBpc0dyYXBodml6SW5zdGFsbGVkR2xvYmFsbHkgPSAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGV4ZWNTeW5jKFwiZG90IC1WXCIsIHsgc3RkaW86IFwiaWdub3JlXCIgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGNoYWxrLnllbGxvd0JyaWdodChcbiAgICAgICAgICBcIlNWRyBhbmQgUE5HIGFyZSBub3Qgc3VwcG9ydGVkIGFzIGdyYXBodml6IGlzIG5vdCBpbnN0YWxsZWQuIFBsZWFzZSBpbnN0YWxsIGdyYXBodml6IChodHRwczovL2dyYXBodml6Lm9yZy9kb3dubG9hZC8pIGdsb2JhbGx5IGFuZCByZS10cnkuXCJcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH07XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHJlcG9ydD86IElHcmFwaFJlcG9ydENhbGxiYWNrID0gYXN5bmMgKFxuICAgIGNvbnRleHQ6IENka0dyYXBoQ29udGV4dFxuICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBjb25zdCBwbHVnaW5Db25maWcgPSB0aGlzLmNvbmZpZyBhcyBSZXF1aXJlZDxJUGx1Z2luQ29uZmlnPjtcblxuICAgIGZvciAoY29uc3QgZGlhZ3JhbUNvbmZpZyBvZiBwbHVnaW5Db25maWcuZGlhZ3JhbXMpIHtcbiAgICAgIGNvbnN0IGNvbmZpZzogSURpYWdyYW1Db25maWcgPSB7XG4gICAgICAgIC4uLihkaWFncmFtQ29uZmlnLmlnbm9yZURlZmF1bHRzID8ge30gOiBwbHVnaW5Db25maWcuZGVmYXVsdHMpLFxuICAgICAgICAuLi5kaWFncmFtQ29uZmlnLFxuICAgICAgfTtcblxuICAgICAgbGV0IGZvcm1hdHM6IERpYWdyYW1Gb3JtYXRbXSA9IEFycmF5LmlzQXJyYXkoY29uZmlnLmZvcm1hdClcbiAgICAgICAgPyBjb25maWcuZm9ybWF0XG4gICAgICAgIDogW2NvbmZpZy5mb3JtYXQgfHwgRGlhZ3JhbUZvcm1hdC5QTkddO1xuICAgICAgaWYgKCFmb3JtYXRzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYERpYWdyYW0gY29uZmlnIHNwZWNpZmllcyBlbXB0eSBsaXN0IG9mIGZvcm1hdHM7IG11c3QgcHJvdmlkZSBhdCBsZWFzdCAxIG9yIHVuZGVmaW5lZCB0byB1c2UgZGVmYXVsdC5gXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIGVhY2ggZGlhZ3JhbSBpcyBkZXN0cnVjdGl2ZSwgc28gd2UgbmVlZCBhIGNsb25lXG4gICAgICBjb25zdCBzdG9yZSA9IGNvbnRleHQuc3RvcmUuY2xvbmUoKTtcblxuICAgICAgaWYgKGNvbmZpZy5maWx0ZXJQbGFuKSB7XG4gICAgICAgIHBlcmZvcm1HcmFwaEZpbHRlclBsYW4oc3RvcmUsIGNvbmZpZy5maWx0ZXJQbGFuKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZ2VuZXJhdGVQbmcgPSBmb3JtYXRzLmluY2x1ZGVzKERpYWdyYW1Gb3JtYXQuUE5HKTtcbiAgICAgIGNvbnN0IGdlbmVyYXRlU3ZnID0gZ2VuZXJhdGVQbmcgfHwgZm9ybWF0cy5pbmNsdWRlcyhEaWFncmFtRm9ybWF0LlNWRyk7XG4gICAgICBjb25zdCBnZW5lcmF0ZURvdCA9IGdlbmVyYXRlU3ZnIHx8IGZvcm1hdHMuaW5jbHVkZXMoRGlhZ3JhbUZvcm1hdC5ET1QpO1xuXG4gICAgICBJU19ERUJVRyAmJlxuICAgICAgICBjb250ZXh0LndyaXRlQXJ0aWZhY3QoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBcImZpbHRlcmVkLmdyYXBoLlwiICsgY29uZmlnLm5hbWUgKyBcIlwiLFxuICAgICAgICAgIFwiZGVidWcvZmlsdGVyZWQtZ3JhcGgvXCIgKyBjb25maWcubmFtZSArIFwiLmpzb25cIixcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShzdG9yZS5zZXJpYWxpemUoKSwgbnVsbCwgMiksXG4gICAgICAgICAgXCJERUJVR1wiXG4gICAgICAgICk7XG5cbiAgICAgIGNvbnN0IGRpYWdyYW0gPSBidWlsZERpYWdyYW0oc3RvcmUsIHtcbiAgICAgICAgdGl0bGU6IGNvbmZpZy50aXRsZSxcbiAgICAgICAgcHJlc2V0OiBjb25maWcuZmlsdGVyUGxhbj8ucHJlc2V0LFxuICAgICAgICB0aGVtZTogY29uZmlnLnRoZW1lLFxuICAgICAgICBub2RlUG9zaXRpb25zOiBjb25maWcubm9kZVBvc2l0aW9ucyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBPbmx5IHRoZSBuZWF0by0gYW5kIGZkcCBsYXlvdXQgZW5naW5lcyBzdXBwb3J0IG5vZGUgcG9zaXRpb25zXG4gICAgICBjb25zdCBsYXlvdXQgPSBjb25maWcubm9kZVBvc2l0aW9ucyA/IFwiZmRwXCIgOiB1bmRlZmluZWQ7XG5cbiAgICAgIGNvbnN0IGRvdCA9IGRpYWdyYW0udG9Eb3QoKTtcblxuICAgICAgaWYgKGdlbmVyYXRlRG90KSB7XG4gICAgICAgIC8vIEdyYXBodml6IHByb3ZpZGVyXG4gICAgICAgIGNvbnRleHQud3JpdGVBcnRpZmFjdChcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIENka0dyYXBoRGlhZ3JhbVBsdWdpbi5hcnRpZmFjdElkKGNvbmZpZy5uYW1lLCBEaWFncmFtRm9ybWF0LkRPVCksXG4gICAgICAgICAgQ2RrR3JhcGhEaWFncmFtUGx1Z2luLmFydGlmYWN0RmlsZW5hbWUoXG4gICAgICAgICAgICBjb25maWcubmFtZSxcbiAgICAgICAgICAgIERpYWdyYW1Gb3JtYXQuRE9UXG4gICAgICAgICAgKSxcbiAgICAgICAgICBkb3QsXG4gICAgICAgICAgYERpYWdyYW0gZ2VuZXJhdGVkIFwiZG90XCIgZmlsZSBmb3IgJHtjb25maWcubmFtZX0gLSBcIiR7Y29uZmlnLnRpdGxlfVwiYFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChnZW5lcmF0ZVN2ZyAmJiB0aGlzLmlzR3JhcGh2aXpJbnN0YWxsZWRHbG9iYWxseSgpKSB7XG4gICAgICAgICAgY29uc3Qgc3ZnRmlsZSA9IHBhdGguam9pbihcbiAgICAgICAgICAgIGNvbnRleHQub3V0ZGlyLFxuICAgICAgICAgICAgQ2RrR3JhcGhEaWFncmFtUGx1Z2luLmFydGlmYWN0RmlsZW5hbWUoXG4gICAgICAgICAgICAgIGNvbmZpZy5uYW1lLFxuICAgICAgICAgICAgICBEaWFncmFtRm9ybWF0LlNWR1xuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCBzdmcgPSBhd2FpdCB0aGlzLnN0cmVhbVRvQnVmZmVyKFxuICAgICAgICAgICAgYXdhaXQgdG9TdHJlYW0oZG90LCB7IGZvcm1hdDogXCJzdmdcIiwgbGF5b3V0IH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCByZXNvbHZlZFN2ZyA9IGF3YWl0IHJlc29sdmVTdmdBd3NBcmNoQXNzZXRJbWFnZXNJbmxpbmUoXG4gICAgICAgICAgICBzdmcudG9TdHJpbmcoKVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBmcy5lbnN1cmVEaXJTeW5jKHBhdGguZGlybmFtZShzdmdGaWxlKSk7XG4gICAgICAgICAgZnMud3JpdGVGaWxlU3luYyhzdmdGaWxlLCByZXNvbHZlZFN2Zyk7XG5cbiAgICAgICAgICBjb250ZXh0LmxvZ0FydGlmYWN0KFxuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIENka0dyYXBoRGlhZ3JhbVBsdWdpbi5hcnRpZmFjdElkKGNvbmZpZy5uYW1lLCBEaWFncmFtRm9ybWF0LlNWRyksXG4gICAgICAgICAgICBzdmdGaWxlLFxuICAgICAgICAgICAgYERpYWdyYW0gZ2VuZXJhdGVkIFwic3ZnXCIgZmlsZSBmb3IgJHtjb25maWcubmFtZX0gLSBcIiR7Y29uZmlnLnRpdGxlfVwiYFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoZ2VuZXJhdGVQbmcgJiYgdGhpcy5pc0dyYXBodml6SW5zdGFsbGVkR2xvYmFsbHkoKSkge1xuICAgICAgICAgICAgY29uc3QgcG5nRmlsZSA9IHBhdGguam9pbihcbiAgICAgICAgICAgICAgY29udGV4dC5vdXRkaXIsXG4gICAgICAgICAgICAgIENka0dyYXBoRGlhZ3JhbVBsdWdpbi5hcnRpZmFjdEZpbGVuYW1lKFxuICAgICAgICAgICAgICAgIGNvbmZpZy5uYW1lLFxuICAgICAgICAgICAgICAgIERpYWdyYW1Gb3JtYXQuUE5HXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIC8vIFNWRydzIGRvbid0IHJlbmRlciBjb3JyZWN0bHkgaW4gbm9uLXN2ZyBmb3JtYXRzLiBSZXBsYWNlIHdpdGggcG5nIGVxdWl2YWxlbnQuXG4gICAgICAgICAgICAgIGNvbnN0IHBuZ2lmaWVkRG90ID0gZG90LnJlcGxhY2UoL1xcLnN2Zy9nLCBcIi5wbmdcIik7XG4gICAgICAgICAgICAgIGNvbnN0IHBuZyA9IGF3YWl0IHRoaXMuc3RyZWFtVG9CdWZmZXIoXG4gICAgICAgICAgICAgICAgYXdhaXQgdG9TdHJlYW0ocG5naWZpZWREb3QsIHtcbiAgICAgICAgICAgICAgICAgIGZvcm1hdDogXCJwbmdcIixcbiAgICAgICAgICAgICAgICAgIGxheW91dCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgIGZzLmVuc3VyZURpclN5bmMocGF0aC5kaXJuYW1lKHBuZ0ZpbGUpKTtcbiAgICAgICAgICAgICAgZnMud3JpdGVGaWxlU3luYyhwbmdGaWxlLCBwbmcpO1xuXG4gICAgICAgICAgICAgIGNvbnRleHQubG9nQXJ0aWZhY3QoXG4gICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICBDZGtHcmFwaERpYWdyYW1QbHVnaW4uYXJ0aWZhY3RJZChcbiAgICAgICAgICAgICAgICAgIGNvbmZpZy5uYW1lLFxuICAgICAgICAgICAgICAgICAgRGlhZ3JhbUZvcm1hdC5QTkdcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIHBuZ0ZpbGUsXG4gICAgICAgICAgICAgICAgYERpYWdyYW0gZ2VuZXJhdGVkIFwicG5nXCIgZmlsZSBmb3IgJHtjb25maWcubmFtZX0gLSBcIiR7Y29uZmlnLnRpdGxlfVwiYFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgRmFpbGVkIHRvIGdlbmVyYXRlIFBORyBkaWFncmFtIGZvciAke1xuICAgICAgICAgICAgICAgICAgY29uZmlnLm5hbWVcbiAgICAgICAgICAgICAgICB9IGF0IFwiJHtwbmdGaWxlfVwiIC0gJHtTdHJpbmcoZXJyb3IpfWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gTkI6IGFkZCBkcmF3aW8gcHJvdmlkZXIgc3VwcG9ydCBoZXJlXG4gICAgfVxuICB9O1xufVxuIl19