@cdktf/hcl2cdk
Version:
Transform HCL into CDK
415 lines (414 loc) • 52 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.referenceToAst = void 0;
// Copyright (c) HashiCorp, Inc
// SPDX-License-Identifier: MPL-2.0
const generator_1 = __importDefault(require("@babel/generator"));
const t = __importStar(require("@babel/types"));
const expressions_1 = require("../expressions");
const references_1 = require("../references");
const hcl2json_1 = require("@cdktf/hcl2json");
const utils_1 = require("../utils");
const nodeIds = [
"var.input",
"module.vpc",
"data.aws_s3_bucket.examplebucket",
"aws_s3_bucket.examplebucket",
"aws_s3_bucket.otherbucket",
"var.users",
"aws_kms_key.key",
"local.service_name",
];
// Transforms a path with segments into literals describing the path
function getPropertyAccessPath(input) {
return input
.split(/(\[|\]|\.)/g)
.filter((p) => p.length > 0 && p !== "." && p !== "[" && p !== "]")
.map((p) => (p.startsWith(`"`) && p.endsWith(`"`) ? p.slice(1, -1) : p));
}
function referenceToAst(scope, ref) {
const [resource, , ...selector] = ref.referencee.full.split(".");
const variableReference = t.identifier((0, utils_1.camelCase)((0, references_1.referenceToVariableName)(scope, ref)));
if (resource === "data") {
selector.shift(); // remove the data part so that the name is not used in the selector
}
const accessor = selector.reduce((carry, member, index) => t.memberExpression(carry, t.identifier(index === 0 && resource === "module"
? (0, utils_1.camelCase)(member + "Output")
: (0, utils_1.camelCase)(member))), variableReference);
if (ref.useFqn) {
return t.memberExpression(accessor, t.identifier("fqn"));
}
if (ref.isVariable) {
return t.memberExpression(accessor, t.identifier("value"));
}
return accessor;
}
exports.referenceToAst = referenceToAst;
describe("expressions", () => {
describe("#extractReferencesFromExpression", () => {
it("finds no references in literals", () => {
return expect((0, references_1.extractReferencesFromExpression)("nothingtobeseen", nodeIds)).resolves.toEqual([]);
});
it("finds no references in literals with functions", () => {
return expect((0, references_1.extractReferencesFromExpression)("${foo(nothingtobeseen)}", nodeIds)).resolves.toEqual([]);
});
it("finds no references in literals with functions and artihmetics", () => {
return expect((0, references_1.extractReferencesFromExpression)("${foo(nothingtobeseen - 2) + 3}", nodeIds)).resolves.toEqual([]);
});
it("finds plain var reference", () => {
return expect((0, references_1.extractReferencesFromExpression)("${var.input}", nodeIds)).resolves.toEqual([
{
referencee: { id: "var.input", full: "var.input" },
useFqn: false,
isVariable: true,
start: 2,
end: 11,
},
]);
});
it("finds plain module reference", () => {
return expect((0, references_1.extractReferencesFromExpression)("${module.vpc.public_subnets}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "module.vpc",
full: "module.vpc.public_subnets",
},
useFqn: false,
isVariable: false,
start: 2,
end: 27,
},
]);
});
it("finds plain data reference", () => {
return expect((0, references_1.extractReferencesFromExpression)("${data.aws_s3_bucket.examplebucket.arn}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "data.aws_s3_bucket.examplebucket",
full: "data.aws_s3_bucket.examplebucket.arn",
},
useFqn: false,
isVariable: false,
start: 2,
end: 38,
},
]);
});
it("finds plain local reference", () => {
return expect((0, references_1.extractReferencesFromExpression)("${local.service_name}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "local.service_name",
full: "local.service_name",
},
useFqn: false,
isVariable: false,
start: 2,
end: 20,
},
]);
});
it("finds plain resource reference", () => {
return expect((0, references_1.extractReferencesFromExpression)("${aws_s3_bucket.examplebucket.id}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket.id",
},
useFqn: false,
isVariable: false,
start: 2,
end: 32,
},
]);
});
it("finds plain resource references in artihmetics", () => {
return expect((0, references_1.extractReferencesFromExpression)("${aws_s3_bucket.examplebucket.count + aws_s3_bucket.otherbucket.count }", nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket.count",
},
useFqn: false,
isVariable: false,
start: 2,
end: 35,
},
{
referencee: {
id: "aws_s3_bucket.otherbucket",
full: "aws_s3_bucket.otherbucket.count",
},
useFqn: false,
isVariable: false,
start: 38,
end: 69,
},
]);
});
it("use fqn for splat reference", () => {
return expect((0, references_1.extractReferencesFromExpression)("${aws_s3_bucket.examplebucket.*.id}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket",
},
useFqn: true,
isVariable: false,
start: 2,
end: 29,
},
]);
});
it("use no fqn if property is present on numeric access", () => {
return expect((0, references_1.extractReferencesFromExpression)("${aws_s3_bucket.examplebucket.network_interface.0.access_config.0.assigned_nat_ip}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket",
},
useFqn: true,
isVariable: false,
start: 2,
end: 81,
},
]);
});
it("detect splat reference within function", () => {
return expect((0, references_1.extractReferencesFromExpression)("${toset(aws_s3_bucket.examplebucket.*)}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket",
},
useFqn: true,
isVariable: false,
start: 8,
end: 35,
},
]);
});
it("finds all resources in conditional", () => {
return expect((0, references_1.extractReferencesFromExpression)("${aws_kms_key.key.deletion_window_in_days > 3 ? aws_s3_bucket.examplebucket.id : []}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_kms_key.key",
full: "aws_kms_key.key.deletion_window_in_days",
},
useFqn: false,
isVariable: false,
start: 2,
end: 41,
},
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket.id",
},
useFqn: false,
isVariable: false,
start: 48,
end: 78,
},
]);
});
it("finds all resources in functions", () => {
return expect((0, references_1.extractReferencesFromExpression)("${element(aws_s3_bucket.examplebucket, 0).id}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket",
},
useFqn: false,
isVariable: false,
start: 10,
end: 37,
},
]);
});
it("finds all resources in functions with splat", () => {
return expect((0, references_1.extractReferencesFromExpression)("${element(aws_s3_bucket.examplebucket.*.id, 0)}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket",
},
useFqn: true,
isVariable: false,
start: 10,
end: 37,
},
]);
});
it("finds all resources in for loops", () => {
return expect((0, references_1.extractReferencesFromExpression)("${{ for name, user in var.users : user.role => name...}}", nodeIds)).resolves.toEqual([
{
referencee: { id: "var.users", full: "var.users" },
useFqn: false,
isVariable: true,
start: 22,
end: 31,
},
]);
});
it("finds resources with property access", () => {
return expect((0, references_1.extractReferencesFromExpression)("${aws_s3_bucket.examplebucket[0].id}", nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket",
},
useFqn: true,
isVariable: false,
start: 2,
end: 35,
},
]);
});
it("finds references within functions that use arrays and comments", () => {
return expect((0, references_1.extractReferencesFromExpression)(`\${compact([
# The example "bucket"
aws_s3_bucket.examplebucket,
# The "Learn" single page application. This is not configured in all environments.
var.input,
])}`, nodeIds)).resolves.toEqual([
{
referencee: {
id: "aws_s3_bucket.examplebucket",
full: "aws_s3_bucket.examplebucket",
},
useFqn: false,
isVariable: false,
start: 59,
end: 86,
},
{
referencee: {
id: "var.input",
full: "var.input",
},
useFqn: false,
isVariable: true,
start: 204,
end: 213,
},
]);
});
it("finds references for same referencees", () => {
return expect((0, references_1.extractReferencesFromExpression)(`\${var.input == "test" ? "azure-ad-int" : "azure-ad-\${var.input}"}`, nodeIds)).resolves.toEqual([
{
referencee: {
id: "var.input",
full: "var.input",
},
useFqn: false,
isVariable: true,
start: 2,
end: 11,
},
{
referencee: {
id: "var.input",
full: "var.input",
},
useFqn: false,
isVariable: true,
start: 53,
end: 62,
},
]);
});
});
describe("#referenceToAst", () => {
it("property access", () => {
const scope = {
providerSchema: { format_version: "0.1" },
providerGenerator: {},
constructs: new Set(),
variables: {},
hasTokenBasedTypeCoercion: false,
nodeIds: [],
importables: [],
topLevelConfig: {},
};
expect((0, generator_1.default)(t.program([
t.expressionStatement(referenceToAst(scope, {
start: 0,
end: 0,
useFqn: false,
isVariable: false,
referencee: {
id: "aws_kms_key.key",
full: "aws_kms_key.key.deletion_window_in_days",
},
})),
])).code).toMatchInlineSnapshot(`"key.deletionWindowInDays;"`);
});
});
describe("#iteratorVariableToAst", () => {
async function run(value) {
const scope = {
providerSchema: { format_version: "0.1" },
providerGenerator: {},
constructs: new Set(),
variables: {},
hasTokenBasedTypeCoercion: false,
nodeIds: [],
importables: [],
topLevelConfig: {},
};
const ast = await (0, hcl2json_1.getExpressionAst)("main.tf", value);
return (0, generator_1.default)(t.program([
t.expressionStatement((0, expressions_1.dynamicVariableToAst)(scope, ast.children[0], "myIterator")),
])).code;
}
it("should convert iterator key accessor", async () => {
expect(await run('"${each.key}"')).toMatchInlineSnapshot(`"myIterator.key;"`);
});
it("should convert iterator value accessor", async () => {
expect(await run('"${each.value}"')).toMatchInlineSnapshot(`"myIterator.value;"`);
});
it("should convert iterator value deep accessor", async () => {
expect(await run('"${each.value.list.map.name}"')).toMatchInlineSnapshot(`"Fn.lookupNested(myIterator.value, ["list", "map", "name"]);"`);
});
it("should convert iterator value with map access", async () => {
expect(await run('"${each.value[0]["map"]["name"]}"')).toMatchInlineSnapshot(`"Fn.lookupNested(myIterator.value, ["[0]", "[\\"map\\"]", "[\\"name\\"]"]);"`);
});
});
describe("#getPropertyAccessPath", () => {
it.each([
[".list.map.name", ["list", "map", "name"]],
[`[0]["map"]["name"]`, ["0", "map", "name"]],
[`[0].map["name"]`, ["0", "map", "name"]],
])("should return the correct path for %s", (input, expected) => {
expect(getPropertyAccessPath(input)).toEqual(expected);
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzc2lvbnMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImV4cHJlc3Npb25zLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLGlFQUF3QztBQUN4QyxnREFBa0M7QUFDbEMsZ0RBQXNEO0FBRXRELDhDQUd1QjtBQUN2Qiw4Q0FBbUQ7QUFFbkQsb0NBQXFDO0FBRXJDLE1BQU0sT0FBTyxHQUFHO0lBQ2QsV0FBVztJQUNYLFlBQVk7SUFDWixrQ0FBa0M7SUFDbEMsNkJBQTZCO0lBQzdCLDJCQUEyQjtJQUMzQixXQUFXO0lBQ1gsaUJBQWlCO0lBQ2pCLG9CQUFvQjtDQUNyQixDQUFDO0FBRUYsb0VBQW9FO0FBQ3BFLFNBQVMscUJBQXFCLENBQUMsS0FBYTtJQUMxQyxPQUFPLEtBQUs7U0FDVCxLQUFLLENBQUMsYUFBYSxDQUFDO1NBQ3BCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUM7U0FDbEUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RSxDQUFDO0FBRUQsU0FBZ0IsY0FBYyxDQUFDLEtBQW1CLEVBQUUsR0FBYztJQUNoRSxNQUFNLENBQUMsUUFBUSxFQUFFLEFBQUQsRUFBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEdBQUcs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QUFNLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQ3RFLCtEQUErRCxDQUNoRSxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0NBQStDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDN0QsTUFBTSxDQUNKLE1BQU0sR0FBRyxDQUFDLG1DQUFtQyxDQUFDLENBQy9DLENBQUMscUJBQXFCLENBQ3JCLDhFQUE4RSxDQUMvRSxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUU7UUFDdEMsRUFBRSxDQUFDLElBQUksQ0FBQztZQUNOLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzNDLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVDLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1NBQzFDLENBQUMsQ0FBQyx1Q0FBdUMsRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRTtZQUM5RCxNQUFNLENBQUMscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDekQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSBIYXNoaUNvcnAsIEluY1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1QTC0yLjBcbmltcG9ydCBnZW5lcmF0ZSBmcm9tIFwiQGJhYmVsL2dlbmVyYXRvclwiO1xuaW1wb3J0ICogYXMgdCBmcm9tIFwiQGJhYmVsL3R5cGVzXCI7XG5pbXBvcnQgeyBkeW5hbWljVmFyaWFibGVUb0FzdCB9IGZyb20gXCIuLi9leHByZXNzaW9uc1wiO1xuaW1wb3J0IHsgUHJvZ3JhbVNjb3BlLCBSZWZlcmVuY2UgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIGV4dHJhY3RSZWZlcmVuY2VzRnJvbUV4cHJlc3Npb24sXG4gIHJlZmVyZW5jZVRvVmFyaWFibGVOYW1lLFxufSBmcm9tIFwiLi4vcmVmZXJlbmNlc1wiO1xuaW1wb3J0IHsgZ2V0RXhwcmVzc2lvbkFzdCB9IGZyb20gXCJAY2RrdGYvaGNsMmpzb25cIjtcbmltcG9ydCB7IFRGRXhwcmVzc2lvblN5bnRheFRyZWUgYXMgdGV4IH0gZnJvbSBcIkBjZGt0Zi9oY2wyanNvblwiO1xuaW1wb3J0IHsgY2FtZWxDYXNlIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5cbmNvbnN0IG5vZGVJZHMgPSBbXG4gIFwidmFyLmlucHV0XCIsXG4gIFwibW9kdWxlLnZwY1wiLFxuICBcImRhdGEuYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCIsXG4gIFwiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCIsXG4gIFwiYXdzX3MzX2J1Y2tldC5vdGhlcmJ1Y2tldFwiLFxuICBcInZhci51c2Vyc1wiLFxuICBcImF3c19rbXNfa2V5LmtleVwiLFxuICBcImxvY2FsLnNlcnZpY2VfbmFtZVwiLFxuXTtcblxuLy8gVHJhbnNmb3JtcyBhIHBhdGggd2l0aCBzZWdtZW50cyBpbnRvIGxpdGVyYWxzIGRlc2NyaWJpbmcgdGhlIHBhdGhcbmZ1bmN0aW9uIGdldFByb3BlcnR5QWNjZXNzUGF0aChpbnB1dDogc3RyaW5nKTogc3RyaW5nW10ge1xuICByZXR1cm4gaW5wdXRcbiAgICAuc3BsaXQoLyhcXFt8XFxdfFxcLikvZylcbiAgICAuZmlsdGVyKChwKSA9PiBwLmxlbmd0aCA+IDAgJiYgcCAhPT0gXCIuXCIgJiYgcCAhPT0gXCJbXCIgJiYgcCAhPT0gXCJdXCIpXG4gICAgLm1hcCgocCkgPT4gKHAuc3RhcnRzV2l0aChgXCJgKSAmJiBwLmVuZHNXaXRoKGBcImApID8gcC5zbGljZSgxLCAtMSkgOiBwKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWZlcmVuY2VUb0FzdChzY29wZTogUHJvZ3JhbVNjb3BlLCByZWY6IFJlZmVyZW5jZSkge1xuICBjb25zdCBbcmVzb3VyY2UsICwgLi4uc2VsZWN0b3JdID0gcmVmLnJlZmVyZW5jZWUuZnVsbC5zcGxpdChcIi5cIik7XG5cbiAgY29uc3QgdmFyaWFibGVSZWZlcmVuY2UgPSB0LmlkZW50aWZpZXIoXG4gICAgY2FtZWxDYXNlKHJlZmVyZW5jZVRvVmFyaWFibGVOYW1lKHNjb3BlLCByZWYpKSxcbiAgKTtcblxuICBpZiAocmVzb3VyY2UgPT09IFwiZGF0YVwiKSB7XG4gICAgc2VsZWN0b3Iuc2hpZnQoKTsgLy8gcmVtb3ZlIHRoZSBkYXRhIHBhcnQgc28gdGhhdCB0aGUgbmFtZSBpcyBub3QgdXNlZCBpbiB0aGUgc2VsZWN0b3JcbiAgfVxuXG4gIGNvbnN0IGFjY2Vzc29yID0gc2VsZWN0b3IucmVkdWNlKFxuICAgIChjYXJyeSwgbWVtYmVyLCBpbmRleCkgPT5cbiAgICAgIHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICAgICAgY2FycnksXG4gICAgICAgIHQuaWRlbnRpZmllcihcbiAgICAgICAgICBpbmRleCA9PT0gMCAmJiByZXNvdXJjZSA9PT0gXCJtb2R1bGVcIlxuICAgICAgICAgICAgPyBjYW1lbENhc2UobWVtYmVyICsgXCJPdXRwdXRcIilcbiAgICAgICAgICAgIDogY2FtZWxDYXNlKG1lbWJlciksXG4gICAgICAgICksXG4gICAgICApLFxuICAgIHZhcmlhYmxlUmVmZXJlbmNlIGFzIHQuRXhwcmVzc2lvbixcbiAgKTtcblxuICBpZiAocmVmLnVzZUZxbikge1xuICAgIHJldHVybiB0Lm1lbWJlckV4cHJlc3Npb24oYWNjZXNzb3IsIHQuaWRlbnRpZmllcihcImZxblwiKSk7XG4gIH1cblxuICBpZiAocmVmLmlzVmFyaWFibGUpIHtcbiAgICByZXR1cm4gdC5tZW1iZXJFeHByZXNzaW9uKGFjY2Vzc29yLCB0LmlkZW50aWZpZXIoXCJ2YWx1ZVwiKSk7XG4gIH1cbiAgcmV0dXJuIGFjY2Vzc29yO1xufVxuXG5kZXNjcmliZShcImV4cHJlc3Npb25zXCIsICgpID0+IHtcbiAgZGVzY3JpYmUoXCIjZXh0cmFjdFJlZmVyZW5jZXNGcm9tRXhwcmVzc2lvblwiLCAoKSA9PiB7XG4gICAgaXQoXCJmaW5kcyBubyByZWZlcmVuY2VzIGluIGxpdGVyYWxzXCIsICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoXG4gICAgICAgIGV4dHJhY3RSZWZlcmVuY2VzRnJvbUV4cHJlc3Npb24oXCJub3RoaW5ndG9iZXNlZW5cIiwgbm9kZUlkcyksXG4gICAgICApLnJlc29sdmVzLnRvRXF1YWwoW10pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJmaW5kcyBubyByZWZlcmVuY2VzIGluIGxpdGVyYWxzIHdpdGggZnVuY3Rpb25zXCIsICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoXG4gICAgICAgIGV4dHJhY3RSZWZlcmVuY2VzRnJvbUV4cHJlc3Npb24oXCIke2Zvbyhub3RoaW5ndG9iZXNlZW4pfVwiLCBub2RlSWRzKSxcbiAgICAgICkucmVzb2x2ZXMudG9FcXVhbChbXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImZpbmRzIG5vIHJlZmVyZW5jZXMgaW4gbGl0ZXJhbHMgd2l0aCBmdW5jdGlvbnMgYW5kIGFydGlobWV0aWNzXCIsICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoXG4gICAgICAgIGV4dHJhY3RSZWZlcmVuY2VzRnJvbUV4cHJlc3Npb24oXG4gICAgICAgICAgXCIke2Zvbyhub3RoaW5ndG9iZXNlZW4gLSAyKSArIDN9XCIsXG4gICAgICAgICAgbm9kZUlkcyxcbiAgICAgICAgKSxcbiAgICAgICkucmVzb2x2ZXMudG9FcXVhbChbXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImZpbmRzIHBsYWluIHZhciByZWZlcmVuY2VcIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuIGV4cGVjdChcbiAgICAgICAgZXh0cmFjdFJlZmVyZW5jZXNGcm9tRXhwcmVzc2lvbihcIiR7dmFyLmlucHV0fVwiLCBub2RlSWRzKSxcbiAgICAgICkucmVzb2x2ZXMudG9FcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICByZWZlcmVuY2VlOiB7IGlkOiBcInZhci5pbnB1dFwiLCBmdWxsOiBcInZhci5pbnB1dFwiIH0sXG4gICAgICAgICAgdXNlRnFuOiBmYWxzZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiB0cnVlLFxuICAgICAgICAgIHN0YXJ0OiAyLFxuICAgICAgICAgIGVuZDogMTEsXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KFwiZmluZHMgcGxhaW4gbW9kdWxlIHJlZmVyZW5jZVwiLCAoKSA9PiB7XG4gICAgICByZXR1cm4gZXhwZWN0KFxuICAgICAgICBleHRyYWN0UmVmZXJlbmNlc0Zyb21FeHByZXNzaW9uKFxuICAgICAgICAgIFwiJHttb2R1bGUudnBjLnB1YmxpY19zdWJuZXRzfVwiLFxuICAgICAgICAgIG5vZGVJZHMsXG4gICAgICAgICksXG4gICAgICApLnJlc29sdmVzLnRvRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgcmVmZXJlbmNlZToge1xuICAgICAgICAgICAgaWQ6IFwibW9kdWxlLnZwY1wiLFxuICAgICAgICAgICAgZnVsbDogXCJtb2R1bGUudnBjLnB1YmxpY19zdWJuZXRzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB1c2VGcW46IGZhbHNlLFxuICAgICAgICAgIGlzVmFyaWFibGU6IGZhbHNlLFxuICAgICAgICAgIHN0YXJ0OiAyLFxuICAgICAgICAgIGVuZDogMjcsXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KFwiZmluZHMgcGxhaW4gZGF0YSByZWZlcmVuY2VcIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuIGV4cGVjdChcbiAgICAgICAgZXh0cmFjdFJlZmVyZW5jZXNGcm9tRXhwcmVzc2lvbihcbiAgICAgICAgICBcIiR7ZGF0YS5hd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQuYXJufVwiLFxuICAgICAgICAgIG5vZGVJZHMsXG4gICAgICAgICksXG4gICAgICApLnJlc29sdmVzLnRvRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgcmVmZXJlbmNlZToge1xuICAgICAgICAgICAgaWQ6IFwiZGF0YS5hd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRcIixcbiAgICAgICAgICAgIGZ1bGw6IFwiZGF0YS5hd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQuYXJuXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB1c2VGcW46IGZhbHNlLFxuICAgICAgICAgIGlzVmFyaWFibGU6IGZhbHNlLFxuICAgICAgICAgIHN0YXJ0OiAyLFxuICAgICAgICAgIGVuZDogMzgsXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KFwiZmluZHMgcGxhaW4gbG9jYWwgcmVmZXJlbmNlXCIsICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoXG4gICAgICAgIGV4dHJhY3RSZWZlcmVuY2VzRnJvbUV4cHJlc3Npb24oXCIke2xvY2FsLnNlcnZpY2VfbmFtZX1cIiwgbm9kZUlkcyksXG4gICAgICApLnJlc29sdmVzLnRvRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgcmVmZXJlbmNlZToge1xuICAgICAgICAgICAgaWQ6IFwibG9jYWwuc2VydmljZV9uYW1lXCIsXG4gICAgICAgICAgICBmdWxsOiBcImxvY2FsLnNlcnZpY2VfbmFtZVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdXNlRnFuOiBmYWxzZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiBmYWxzZSxcbiAgICAgICAgICBzdGFydDogMixcbiAgICAgICAgICBlbmQ6IDIwLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImZpbmRzIHBsYWluIHJlc291cmNlIHJlZmVyZW5jZVwiLCAoKSA9PiB7XG4gICAgICByZXR1cm4gZXhwZWN0KFxuICAgICAgICBleHRyYWN0UmVmZXJlbmNlc0Zyb21FeHByZXNzaW9uKFxuICAgICAgICAgIFwiJHthd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQuaWR9XCIsXG4gICAgICAgICAgbm9kZUlkcyxcbiAgICAgICAgKSxcbiAgICAgICkucmVzb2x2ZXMudG9FcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICByZWZlcmVuY2VlOiB7XG4gICAgICAgICAgICBpZDogXCJhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRcIixcbiAgICAgICAgICAgIGZ1bGw6IFwiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0LmlkXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB1c2VGcW46IGZhbHNlLFxuICAgICAgICAgIGlzVmFyaWFibGU6IGZhbHNlLFxuICAgICAgICAgIHN0YXJ0OiAyLFxuICAgICAgICAgIGVuZDogMzIsXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KFwiZmluZHMgcGxhaW4gcmVzb3VyY2UgcmVmZXJlbmNlcyBpbiBhcnRpaG1ldGljc1wiLCAoKSA9PiB7XG4gICAgICByZXR1cm4gZXhwZWN0KFxuICAgICAgICBleHRyYWN0UmVmZXJlbmNlc0Zyb21FeHByZXNzaW9uKFxuICAgICAgICAgIFwiJHthd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQuY291bnQgKyBhd3NfczNfYnVja2V0Lm90aGVyYnVja2V0LmNvdW50IH1cIixcbiAgICAgICAgICBub2RlSWRzLFxuICAgICAgICApLFxuICAgICAgKS5yZXNvbHZlcy50b0VxdWFsKFtcbiAgICAgICAge1xuICAgICAgICAgIHJlZmVyZW5jZWU6IHtcbiAgICAgICAgICAgIGlkOiBcImF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldFwiLFxuICAgICAgICAgICAgZnVsbDogXCJhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQuY291bnRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHVzZUZxbjogZmFsc2UsXG4gICAgICAgICAgaXNWYXJpYWJsZTogZmFsc2UsXG4gICAgICAgICAgc3RhcnQ6IDIsXG4gICAgICAgICAgZW5kOiAzNSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHJlZmVyZW5jZWU6IHtcbiAgICAgICAgICAgIGlkOiBcImF3c19zM19idWNrZXQub3RoZXJidWNrZXRcIixcbiAgICAgICAgICAgIGZ1bGw6IFwiYXdzX3MzX2J1Y2tldC5vdGhlcmJ1Y2tldC5jb3VudFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdXNlRnFuOiBmYWxzZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiBmYWxzZSxcbiAgICAgICAgICBzdGFydDogMzgsXG4gICAgICAgICAgZW5kOiA2OSxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJ1c2UgZnFuIGZvciBzcGxhdCByZWZlcmVuY2VcIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuIGV4cGVjdChcbiAgICAgICAgZXh0cmFjdFJlZmVyZW5jZXNGcm9tRXhwcmVzc2lvbihcbiAgICAgICAgICBcIiR7YXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0LiouaWR9XCIsXG4gICAgICAgICAgbm9kZUlkcyxcbiAgICAgICAgKSxcbiAgICAgICkucmVzb2x2ZXMudG9FcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICByZWZlcmVuY2VlOiB7XG4gICAgICAgICAgICBpZDogXCJhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRcIixcbiAgICAgICAgICAgIGZ1bGw6IFwiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB1c2VGcW46IHRydWUsXG4gICAgICAgICAgaXNWYXJpYWJsZTogZmFsc2UsXG4gICAgICAgICAgc3RhcnQ6IDIsXG4gICAgICAgICAgZW5kOiAyOSxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJ1c2Ugbm8gZnFuIGlmIHByb3BlcnR5IGlzIHByZXNlbnQgb24gbnVtZXJpYyBhY2Nlc3NcIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuIGV4cGVjdChcbiAgICAgICAgZXh0cmFjdFJlZmVyZW5jZXNGcm9tRXhwcmVzc2lvbihcbiAgICAgICAgICBcIiR7YXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0Lm5ldHdvcmtfaW50ZXJmYWNlLjAuYWNjZXNzX2NvbmZpZy4wLmFzc2lnbmVkX25hdF9pcH1cIixcbiAgICAgICAgICBub2RlSWRzLFxuICAgICAgICApLFxuICAgICAgKS5yZXNvbHZlcy50b0VxdWFsKFtcbiAgICAgICAge1xuICAgICAgICAgIHJlZmVyZW5jZWU6IHtcbiAgICAgICAgICAgIGlkOiBcImF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldFwiLFxuICAgICAgICAgICAgZnVsbDogXCJhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHVzZUZxbjogdHJ1ZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiBmYWxzZSxcbiAgICAgICAgICBzdGFydDogMixcbiAgICAgICAgICBlbmQ6IDgxLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImRldGVjdCBzcGxhdCByZWZlcmVuY2Ugd2l0aGluIGZ1bmN0aW9uXCIsICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoXG4gICAgICAgIGV4dHJhY3RSZWZlcmVuY2VzRnJvbUV4cHJlc3Npb24oXG4gICAgICAgICAgXCIke3Rvc2V0KGF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldC4qKX1cIixcbiAgICAgICAgICBub2RlSWRzLFxuICAgICAgICApLFxuICAgICAgKS5yZXNvbHZlcy50b0VxdWFsKFtcbiAgICAgICAge1xuICAgICAgICAgIHJlZmVyZW5jZWU6IHtcbiAgICAgICAgICAgIGlkOiBcImF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldFwiLFxuICAgICAgICAgICAgZnVsbDogXCJhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHVzZUZxbjogdHJ1ZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiBmYWxzZSxcbiAgICAgICAgICBzdGFydDogOCxcbiAgICAgICAgICBlbmQ6IDM1LFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImZpbmRzIGFsbCByZXNvdXJjZXMgaW4gY29uZGl0aW9uYWxcIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuIGV4cGVjdChcbiAgICAgICAgZXh0cmFjdFJlZmVyZW5jZXNGcm9tRXhwcmVzc2lvbihcbiAgICAgICAgICBcIiR7YXdzX2ttc19rZXkua2V5LmRlbGV0aW9uX3dpbmRvd19pbl9kYXlzID4gMyA/IGF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldC5pZCA6IFtdfVwiLFxuICAgICAgICAgIG5vZGVJZHMsXG4gICAgICAgICksXG4gICAgICApLnJlc29sdmVzLnRvRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgcmVmZXJlbmNlZToge1xuICAgICAgICAgICAgaWQ6IFwiYXdzX2ttc19rZXkua2V5XCIsXG4gICAgICAgICAgICBmdWxsOiBcImF3c19rbXNfa2V5LmtleS5kZWxldGlvbl93aW5kb3dfaW5fZGF5c1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdXNlRnFuOiBmYWxzZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiBmYWxzZSxcbiAgICAgICAgICBzdGFydDogMixcbiAgICAgICAgICBlbmQ6IDQxLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcmVmZXJlbmNlZToge1xuICAgICAgICAgICAgaWQ6IFwiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCIsXG4gICAgICAgICAgICBmdWxsOiBcImF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldC5pZFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdXNlRnFuOiBmYWxzZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiBmYWxzZSxcbiAgICAgICAgICBzdGFydDogNDgsXG4gICAgICAgICAgZW5kOiA3OCxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJmaW5kcyBhbGwgcmVzb3VyY2VzIGluIGZ1bmN0aW9uc1wiLCAoKSA9PiB7XG4gICAgICByZXR1cm4gZXhwZWN0KFxuICAgICAgICBleHRyYWN0UmVmZXJlbmNlc0Zyb21FeHByZXNzaW9uKFxuICAgICAgICAgIFwiJHtlbGVtZW50KGF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldCwgMCkuaWR9XCIsXG4gICAgICAgICAgbm9kZUlkcyxcbiAgICAgICAgKSxcbiAgICAgICkucmVzb2x2ZXMudG9FcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICByZWZlcmVuY2VlOiB7XG4gICAgICAgICAgICBpZDogXCJhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRcIixcbiAgICAgICAgICAgIGZ1bGw6IFwiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB1c2VGcW46IGZhbHNlLFxuICAgICAgICAgIGlzVmFyaWFibGU6IGZhbHNlLFxuICAgICAgICAgIHN0YXJ0OiAxMCxcbiAgICAgICAgICBlbmQ6IDM3LFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImZpbmRzIGFsbCByZXNvdXJjZXMgaW4gZnVuY3Rpb25zIHdpdGggc3BsYXRcIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuIGV4cGVjdChcbiAgICAgICAgZXh0cmFjdFJlZmVyZW5jZXNGcm9tRXhwcmVzc2lvbihcbiAgICAgICAgICBcIiR7ZWxlbWVudChhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXQuKi5pZCwgMCl9XCIsXG4gICAgICAgICAgbm9kZUlkcyxcbiAgICAgICAgKSxcbiAgICAgICkucmVzb2x2ZXMudG9FcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICByZWZlcmVuY2VlOiB7XG4gICAgICAgICAgICBpZDogXCJhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRcIixcbiAgICAgICAgICAgIGZ1bGw6IFwiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB1c2VGcW46IHRydWUsXG4gICAgICAgICAgaXNWYXJpYWJsZTogZmFsc2UsXG4gICAgICAgICAgc3RhcnQ6IDEwLFxuICAgICAgICAgIGVuZDogMzcsXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KFwiZmluZHMgYWxsIHJlc291cmNlcyBpbiBmb3IgbG9vcHNcIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuIGV4cGVjdChcbiAgICAgICAgZXh0cmFjdFJlZmVyZW5jZXNGcm9tRXhwcmVzc2lvbihcbiAgICAgICAgICBcIiR7eyBmb3IgbmFtZSwgdXNlciBpbiB2YXIudXNlcnMgOiB1c2VyLnJvbGUgPT4gbmFtZS4uLn19XCIsXG4gICAgICAgICAgbm9kZUlkcyxcbiAgICAgICAgKSxcbiAgICAgICkucmVzb2x2ZXMudG9FcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICByZWZlcmVuY2VlOiB7IGlkOiBcInZhci51c2Vyc1wiLCBmdWxsOiBcInZhci51c2Vyc1wiIH0sXG4gICAgICAgICAgdXNlRnFuOiBmYWxzZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiB0cnVlLFxuICAgICAgICAgIHN0YXJ0OiAyMixcbiAgICAgICAgICBlbmQ6IDMxLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImZpbmRzIHJlc291cmNlcyB3aXRoIHByb3BlcnR5IGFjY2Vzc1wiLCAoKSA9PiB7XG4gICAgICByZXR1cm4gZXhwZWN0KFxuICAgICAgICBleHRyYWN0UmVmZXJlbmNlc0Zyb21FeHByZXNzaW9uKFxuICAgICAgICAgIFwiJHthd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRbMF0uaWR9XCIsXG4gICAgICAgICAgbm9kZUlkcyxcbiAgICAgICAgKSxcbiAgICAgICkucmVzb2x2ZXMudG9FcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICByZWZlcmVuY2VlOiB7XG4gICAgICAgICAgICBpZDogXCJhd3NfczNfYnVja2V0LmV4YW1wbGVidWNrZXRcIixcbiAgICAgICAgICAgIGZ1bGw6IFwiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB1c2VGcW46IHRydWUsXG4gICAgICAgICAgaXNWYXJpYWJsZTogZmFsc2UsXG4gICAgICAgICAgc3RhcnQ6IDIsXG4gICAgICAgICAgZW5kOiAzNSxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJmaW5kcyByZWZlcmVuY2VzIHdpdGhpbiBmdW5jdGlvbnMgdGhhdCB1c2UgYXJyYXlzIGFuZCBjb21tZW50c1wiLCAoKSA9PiB7XG4gICAgICByZXR1cm4gZXhwZWN0KFxuICAgICAgICBleHRyYWN0UmVmZXJlbmNlc0Zyb21FeHByZXNzaW9uKFxuICAgICAgICAgIGBcXCR7Y29tcGFjdChbXG4gICAgICAgICAgICAjIFRoZSBleGFtcGxlIFwiYnVja2V0XCJcbiAgICAgICAgICAgIGF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldCxcbiAgICAgICAgXG4gICAgICAgICAgICAjIFRoZSBcIkxlYXJuXCIgc2luZ2xlIHBhZ2UgYXBwbGljYXRpb24uIFRoaXMgaXMgbm90IGNvbmZpZ3VyZWQgaW4gYWxsIGVudmlyb25tZW50cy5cbiAgICAgICAgICAgIHZhci5pbnB1dCxcbiAgICAgICAgICBdKX1gLFxuICAgICAgICAgIG5vZGVJZHMsXG4gICAgICAgICksXG4gICAgICApLnJlc29sdmVzLnRvRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgcmVmZXJlbmNlZToge1xuICAgICAgICAgICAgaWQ6IFwiYXdzX3MzX2J1Y2tldC5leGFtcGxlYnVja2V0XCIsXG4gICAgICAgICAgICBmdWxsOiBcImF3c19zM19idWNrZXQuZXhhbXBsZWJ1Y2tldFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdXNlRnFuOiBmYWxzZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiBmYWxzZSxcbiAgICAgICAgICBzdGFydDogNTksXG4gICAgICAgICAgZW5kOiA4NixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHJlZmVyZW5jZWU6IHtcbiAgICAgICAgICAgIGlkOiBcInZhci5pbnB1dFwiLFxuICAgICAgICAgICAgZnVsbDogXCJ2YXIuaW5wdXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHVzZUZxbjogZmFsc2UsXG4gICAgICAgICAgaXNWYXJpYWJsZTogdHJ1ZSxcbiAgICAgICAgICBzdGFydDogMjA0LFxuICAgICAgICAgIGVuZDogMjEzLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcImZpbmRzIHJlZmVyZW5jZXMgZm9yIHNhbWUgcmVmZXJlbmNlZXNcIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuIGV4cGVjdChcbiAgICAgICAgZXh0cmFjdFJlZmVyZW5jZXNGcm9tRXhwcmVzc2lvbihcbiAgICAgICAgICBgXFwke3Zhci5pbnB1dCA9PSBcInRlc3RcIiA/IFwiYXp1cmUtYWQtaW50XCIgOiBcImF6dXJlLWFkLVxcJHt2YXIuaW5wdXR9XCJ9YCxcbiAgICAgICAgICBub2RlSWRzLFxuICAgICAgICApLFxuICAgICAgKS5yZXNvbHZlcy50b0VxdWFsKFtcbiAgICAgICAge1xuICAgICAgICAgIHJlZmVyZW5jZWU6IHtcbiAgICAgICAgICAgIGlkOiBcInZhci5pbnB1dFwiLFxuICAgICAgICAgICAgZnVsbDogXCJ2YXIuaW5wdXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHVzZUZxbjogZmFsc2UsXG4gICAgICAgICAgaXNWYXJpYWJsZTogdHJ1ZSxcbiAgICAgICAgICBzdGFydDogMixcbiAgICAgICAgICBlbmQ6IDExLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcmVmZXJlbmNlZToge1xuICAgICAgICAgICAgaWQ6IFwidmFyLmlucHV0XCIsXG4gICAgICAgICAgICBmdWxsOiBcInZhci5pbnB1dFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdXNlRnFuOiBmYWxzZSxcbiAgICAgICAgICBpc1ZhcmlhYmxlOiB0cnVlLFxuICAgICAgICAgIHN0YXJ0OiA1MyxcbiAgICAgICAgICBlbmQ6IDYyLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiI3JlZmVyZW5jZVRvQXN0XCIsICgpID0+IHtcbiAgICBpdChcInByb3BlcnR5IGFjY2Vzc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBzY29wZTogUHJvZ3JhbVNjb3BlID0ge1xuICAgICAgICBwcm92aWRlclNjaGVtYTogeyBmb3JtYXRfdmVyc2lvbjogXCIwLjFcIiB9LFxuICAgICAgICBwcm92aWRlckdlbmVyYXRvcjoge30sXG4gICAgICAgIGNvbnN0cnVjdHM6IG5ldyBTZXQ8c3RyaW5nPigpLFxuICAgICAgICB2YXJpYWJsZXM6IHt9LFxuICAgICAgICBoYXNUb2tlbkJhc2VkVHlwZUNvZXJjaW9uOiBmYWxzZSxcbiAgICAgICAgbm9kZUlkczogW10sXG4gICAgICAgIGltcG9ydGFibGVzOiBbXSxcbiAgICAgICAgdG9wTGV2ZWxDb25maWc6IHt9LFxuICAgICAgfTtcbiAgICAgIGV4cGVjdChcbiAgICAgICAgZ2VuZXJhdGUoXG4gICAgICAgICAgdC5wcm9ncmFtKFtcbiAgICAgICAgICAgIHQuZXhwcmVzc2lvblN0YXRlbWVudChcbiAgICAgICAgICAgICAgcmVmZXJlbmNlVG9Bc3Qoc2NvcGUsIHtcbiAgICAgICAgICAgICAgICBzdGFydDogMCxcbiAgICAgICAgICAgICAgICBlbmQ6IDAsXG4gICAgICAgICAgICAgICAgdXNlRnFuOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBpc1ZhcmlhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICByZWZlcmVuY2VlOiB7XG4gICAgICAgICAgICAgICAgICBpZDogXCJhd3Nfa21zX2tleS5rZXlcIixcbiAgICAgICAgICAgICAgICAgIGZ1bGw6IFwiYXdzX2ttc19rZXkua2V5LmRlbGV0aW9uX3dpbmRvd19pbl9kYXlzXCIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIF0pIGFzIGFueSxcbiAgICAgICAgKS5jb2RlLFxuICAgICAgKS50b01hdGNoSW5saW5lU25hcHNob3QoYFwia2V5LmRlbGV0aW9uV2luZG93SW5EYXlzO1wiYCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiI2l0ZXJhdG9yVmFyaWFibGVUb0FzdFwiLCAoKSA9PiB7XG4gICAgYXN5bmMgZnVuY3Rpb24gcnVuKHZhbHVlOiBzdHJpbmcpIHtcbiAgICAgIGNvbnN0IHNjb3BlOiBQcm9ncmFtU2NvcGUgPSB7XG4gICAgICAgIHByb3ZpZGVyU2NoZW1hOiB7IGZvcm1hdF92ZXJzaW9uOiBcIjAuMVwiIH0sXG4gICAgICAgIHByb3ZpZGVyR2VuZXJhdG9yOiB7fSxcbiAgICAgICAgY29uc3RydWN0czogbmV3IFNldDxzdHJpbmc+KCksXG4gICAgICAgIHZhcmlhYmxlczoge30sXG4gICAgICAgIGhhc1Rva2VuQmFzZWRUeXBlQ29lcmNpb246IGZhbHNlLFxuICAgICAgICBub2RlSWRzOiBbXSxcbiAgICAgICAgaW1wb3J0YWJsZXM6IFtdLFxuICAgICAgICB0b3BMZXZlbENvbmZpZzoge30sXG4gICAgICB9O1xuICAgICAgY29uc3QgYXN0ID0gYXdhaXQgZ2V0RXhwcmVzc2lvbkFzdChcIm1haW4udGZcIiwgdmFsdWUpO1xuICAgICAgcmV0dXJuIGdlbmVyYXRlKFxuICAgICAgICB0LnByb2dyYW0oW1xuICAgICAgICAgIHQuZXhwcmVzc2lvblN0YXRlbWVudChcbiAgICAgICAgICAgIGR5bmFtaWNWYXJpYWJsZVRvQXN0KFxuICAgICAgICAgICAgICBzY29wZSxcbiAgICAgICAgICAgICAgYXN0IS5jaGlsZH