UNPKG

@cdktf/hcl2json

Version:
177 lines • 21.7 kB
"use strict"; // Copyright (c) HashiCorp, Inc // SPDX-License-Identifier: MPL-2.0 // eslint-disable-next-line @typescript-eslint/triple-slash-reference /// <reference lib="dom" /> 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; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getExpressionAst = exports.getReferencesInExpression = exports.convertFiles = exports.parse = void 0; // Inspired by // https://github.com/ts-terraform/ts-terraform // https://github.com/aaronpowell/webpack-golang-wasm-async-loader const fs = __importStar(require("fs-extra")); const path_1 = require("path"); const deepmerge_1 = require("./deepmerge"); const zlib_1 = require("zlib"); const references_1 = require("./references"); const util_1 = require("./util"); // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type const jsRoot = {}; function sleep() { return new Promise((resolve) => { setTimeout(resolve, 0); }); } function goBridge(getBytes) { let ready = false; async function init() { // After: https://github.com/golang/go/commit/680caf15355057ca84857a2a291b6f5c44e73329 // Go 1.19+ has a different entrypoint await Promise.resolve().then(() => __importStar(require(`../wasm/bridge_wasm_exec.js`))); const go = new global.Go(); const bytes = await getBytes; const result = await WebAssembly.instantiate(bytes, go.importObject); global.__parse_terraform_config_wasm__ = jsRoot; void go.run(result.instance); ready = true; } init().catch((error) => { throw error; }); const proxy = new Proxy({}, { get: (_, key) => { return async (...args) => { while (!ready) { await sleep(); } if (!(key in jsRoot)) { throw new Error(`There is nothing defined with the name "${key.toString()}"`); } if (typeof jsRoot[key] !== "function") { return jsRoot[key]; } return new Promise((resolve, reject) => { const cb = (err, ...msg) => // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore err ? reject(new Error(err)) : resolve(...msg); const run = () => { jsRoot[key].apply(undefined, [...args, cb]); }; run(); }); }; }, }); return proxy; } const loadWasm = async () => { return (0, zlib_1.gunzipSync)(await fs.readFile((0, path_1.join)(__dirname, "..", "main.wasm.gz"))); }; const wasm = goBridge(loadWasm()); async function parse(filename, contents) { const res = await wasm.parse(filename, contents); return JSON.parse(res); } exports.parse = parse; async function convertFiles(workingDirectory) { let tfFileContents = ""; const tfJSONFileContents = []; for (const file of fs.readdirSync(workingDirectory)) { const filePath = (0, path_1.resolve)(workingDirectory, file); if (!fs.lstatSync(filePath).isDirectory()) { if (file.match(/\.tf$/)) { tfFileContents += fs.readFileSync(filePath, "utf-8"); tfFileContents += "\n"; } else if (file.match(/\.tf\.json$/)) { tfJSONFileContents.push(JSON.parse(fs.readFileSync(filePath, "utf-8"))); } } } if (tfFileContents === "" && tfJSONFileContents.length === 0) { console.error(`No '.tf' or '.tf.json' files found in ${workingDirectory}`); return {}; } return (0, deepmerge_1.deepMerge)(await parse("hcl2json.tf", tfFileContents), ...tfJSONFileContents); } exports.convertFiles = convertFiles; /** * Parse a Terraform expression and return the AST. This function expects a string input, and will wrap the expression in quotes if it is not already quoted. * @param filename The filename to use for the expression. This is used for error reporting. * @param expression The expression to parse. * @returns An array of References found in the expression. */ async function getReferencesInExpression(filename, expression) { // We have to do this twice because of the problem with HEREDOCS // Our current hcl2json implementation removes HEREDOCS and replaces them // with a multi-line string, which is causing all kinds of problems let offset = 0; let quoteWrappedExpression = expression; if (!expression.startsWith('"')) { quoteWrappedExpression = `"${expression}"`; offset = 1; } const { wrap: wrappedExpression, wrapOffset: startOffset } = (0, util_1.wrapTerraformExpression)(`${quoteWrappedExpression}`); offset += startOffset; const ast = await getExpressionAst(filename, wrappedExpression); if (!ast) { return []; } const refs = (0, references_1.findAllReferencesInAst)(expression, ast); if (wrappedExpression === expression) { return refs; } return refs.map((ref) => { return { ...ref, startPosition: ref.startPosition - offset, endPosition: ref.endPosition - offset, }; }); } exports.getReferencesInExpression = getReferencesInExpression; /** * Parse a Terraform expression and return the AST. The expression does not need to be a Terraform string. * @param filename The filename to use for the expression. This is used for error reporting. * @param expression The expression to parse. * @returns The AST for the expression. * * The returned AST has the following structure: * - type: The type of the node. This is a string. * - range: This contains the start and end of the node in the expression. * - children: This contains the children of the node. This is an array of nodes. * - meta: This contains metadata about the node. This is an object, and varies depending on the type of the node. */ async function getExpressionAst(filename, expression) { const res = await wasm.getExpressionAst(filename, expression); const ast = JSON.parse(res); if (!ast) { return null; } return ast; } exports.getExpressionAst = getExpressionAst; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJpZGdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYnJpZGdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLHFFQUFxRTtBQUNyRSwyQkFBMkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRTNCLGNBQWM7QUFDZCwrQ0FBK0M7QUFDL0Msa0VBQWtFO0FBRWxFLDZDQUErQjtBQUMvQiwrQkFBcUM7QUFDckMsMkNBQXdDO0FBQ3hDLCtCQUFrQztBQUNsQyw2Q0FBaUU7QUFFakUsaUNBQWlEO0FBUWpELHNFQUFzRTtBQUN0RSxNQUFNLE1BQU0sR0FBNkIsRUFBRSxDQUFDO0FBRTVDLFNBQVMsS0FBSztJQUNaLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUM3QixVQUFVLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3pCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsUUFBUSxDQUFDLFFBQXlCO0lBQ3pDLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQztJQUVsQixLQUFLLFVBQVUsSUFBSTtRQUNqQixzRkFBc0Y7UUFDdEYsc0NBQXNDO1FBQ3RDLHdEQUFhLDZCQUE2QixHQUFDLENBQUM7UUFDNUMsTUFBTSxFQUFFLEdBQUcsSUFBSyxNQUFjLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDcEMsTUFBTSxLQUFLLEdBQUcsTUFBTSxRQUFRLENBQUM7UUFDN0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxXQUFXLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEUsTUFBYyxDQUFDLCtCQUErQixHQUFHLE1BQU0sQ0FBQztRQUN6RCxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzdCLEtBQUssR0FBRyxJQUFJLENBQUM7SUFDZixDQUFDO0lBRUQs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QUFHLHNCQUFzQixFQUFFLENBQUMsQ0FBQztJQUV2RCxNQUFNLElBQUksV0FBVyxDQUFDO0lBRXRCLE1BQU0sR0FBRyxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsUUFBUSxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDaEUsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ1QsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsSUFBQSxtQ0FBc0IsRUFBQyxVQUFVLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDckQsSUFBSSxpQkFBaUIsS0FBSyxVQUFVLEVBQUUsQ0FBQztRQUNyQyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtRQUN0QixPQUFPO1lBQ0wsR0FBRyxHQUFHO1lBQ04sYUFBYSxFQUFFLEdBQUcsQ0FBQyxhQUFhLEdBQUcsTUFBTTtZQUN6QyxXQUFXLEVBQUUsR0FBRyxDQUFDLFdBQVcsR0FBRyxNQUFNO1NBQ3RDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFwQ0QsOERBb0NDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSSxLQUFLLFVBQVUsZ0JBQWdCLENBQ3BDLFFBQWdCLEVBQ2hCLFVBQWtCO0lBRWxCLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUM5RCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBbUIsQ0FBQztJQUU5QyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDVCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFaRCw0Q0FZQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgSGFzaGlDb3JwLCBJbmNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNUEwtMi4wXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3RyaXBsZS1zbGFzaC1yZWZlcmVuY2Vcbi8vLyA8cmVmZXJlbmNlIGxpYj1cImRvbVwiIC8+XG5cbi8vIEluc3BpcmVkIGJ5XG4vLyBodHRwczovL2dpdGh1Yi5jb20vdHMtdGVycmFmb3JtL3RzLXRlcnJhZm9ybVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2Fhcm9ucG93ZWxsL3dlYnBhY2stZ29sYW5nLXdhc20tYXN5bmMtbG9hZGVyXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gXCJmcy1leHRyYVwiO1xuaW1wb3J0IHsgam9pbiwgcmVzb2x2ZSB9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UgfSBmcm9tIFwiLi9kZWVwbWVyZ2VcIjtcbmltcG9ydCB7IGd1bnppcFN5bmMgfSBmcm9tIFwiemxpYlwiO1xuaW1wb3J0IHsgUmVmZXJlbmNlLCBmaW5kQWxsUmVmZXJlbmNlc0luQXN0IH0gZnJvbSBcIi4vcmVmZXJlbmNlc1wiO1xuaW1wb3J0IHsgRXhwcmVzc2lvblR5cGUgfSBmcm9tIFwiLi9zeW50YXgtdHJlZVwiO1xuaW1wb3J0IHsgd3JhcFRlcnJhZm9ybUV4cHJlc3Npb24gfSBmcm9tIFwiLi91dGlsXCI7XG5cbmludGVyZmFjZSBHb0JyaWRnZSB7XG4gIHBhcnNlOiAoZmlsZW5hbWU6IHN0cmluZywgaGNsOiBzdHJpbmcpID0+IFByb21pc2U8c3RyaW5nPjtcbiAgcGFyc2VFeHByZXNzaW9uOiAoZmlsZW5hbWU6IHN0cmluZywgaGNsOiBzdHJpbmcpID0+IFByb21pc2U8c3RyaW5nPjtcbiAgZ2V0RXhwcmVzc2lvbkFzdDogKGZpbGVuYW1lOiBzdHJpbmcsIGhjbDogc3RyaW5nKSA9PiBQcm9taXNlPHN0cmluZz47XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWZ1bmN0aW9uLXR5cGVcbmNvbnN0IGpzUm9vdDogUmVjb3JkPHN0cmluZywgRnVuY3Rpb24+ID0ge307XG5cbmZ1bmN0aW9uIHNsZWVwKCkge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBzZXRUaW1lb3V0KHJlc29sdmUsIDApO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZ29CcmlkZ2UoZ2V0Qnl0ZXM6IFByb21pc2U8QnVmZmVyPikge1xuICBsZXQgcmVhZHkgPSBmYWxzZTtcblxuICBhc3luYyBmdW5jdGlvbiBpbml0KCkge1xuICAgIC8vIEFmdGVyOiBodHRwczovL2dpdGh1Yi5jb20vZ29sYW5nL2dvL2NvbW1pdC82ODBjYWYxNTM1NTA1N2NhODQ4NTdhMmEyOTFiNmY1YzQ0ZTczMzI5XG4gICAgLy8gR28gMS4xOSsgaGFzIGEgZGlmZmVyZW50IGVudHJ5cG9pbnRcbiAgICBhd2FpdCBpbXBvcnQoYC4uL3dhc20vYnJpZGdlX3dhc21fZXhlYy5qc2ApO1xuICAgIGNvbnN0IGdvID0gbmV3IChnbG9iYWwgYXMgYW55KS5HbygpO1xuICAgIGNvbnN0IGJ5dGVzID0gYXdhaXQgZ2V0Qnl0ZXM7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgV2ViQXNzZW1ibHkuaW5zdGFudGlhdGUoYnl0ZXMsIGdvLmltcG9ydE9iamVjdCk7XG4gICAgKGdsb2JhbCBhcyBhbnkpLl9fcGFyc2VfdGVycmFmb3JtX2NvbmZpZ193YXNtX18gPSBqc1Jvb3Q7XG4gICAgdm9pZCBnby5ydW4ocmVzdWx0Lmluc3RhbmNlKTtcbiAgICByZWFkeSA9IHRydWU7XG4gIH1cblxuICBpbml0KCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH0pO1xuXG4gIGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KHt9IGFzIEdvQnJpZGdlLCB7XG4gICAgZ2V0OiAoXywga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgIHJldHVybiBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgICAgIHdoaWxlICghcmVhZHkpIHtcbiAgICAgICAgICBhd2FpdCBzbGVlcCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCEoa2V5IGluIGpzUm9vdCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgVGhlcmUgaXMgbm90aGluZyBkZWZpbmVkIHdpdGggdGhlIG5hbWUgXCIke2tleS50b1N0cmluZygpfVwiYCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBqc1Jvb3Rba2V5XSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgcmV0dXJuIGpzUm9vdFtrZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBjb25zdCBjYiA9IChlcnI6IHN0cmluZywgLi4ubXNnOiBzdHJpbmdbXSkgPT5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnRcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGVyciA/IHJlamVjdChuZXcgRXJyb3IoZXJyKSkgOiByZXNvbHZlKC4uLm1zZyk7XG5cbiAgICAgICAgICBjb25zdCBydW4gPSAoKSA9PiB7XG4gICAgICAgICAgICBqc1Jvb3Rba2V5XS5hcHBseSh1bmRlZmluZWQsIFsuLi5hcmdzLCBjYl0pO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICBydW4oKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH0sXG4gIH0pO1xuXG4gIHJldHVybiBwcm94eTtcbn1cblxuY29uc3QgbG9hZFdhc20gPSBhc3luYyAoKSA9PiB7XG4gIHJldHVybiBndW56aXBTeW5jKGF3YWl0IGZzLnJlYWRGaWxlKGpvaW4oX19kaXJuYW1lLCBcIi4uXCIsIFwibWFpbi53YXNtLmd6XCIpKSk7XG59O1xuXG5jb25zdCB3YXNtID0gZ29CcmlkZ2UobG9hZFdhc20oKSk7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZShcbiAgZmlsZW5hbWU6IHN0cmluZyxcbiAgY29udGVudHM6IHN0cmluZyxcbik6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICBjb25zdCByZXMgPSBhd2FpdCB3YXNtLnBhcnNlKGZpbGVuYW1lLCBjb250ZW50cyk7XG4gIHJldHVybiBKU09OLnBhcnNlKHJlcyk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb252ZXJ0RmlsZXMoXG4gIHdvcmtpbmdEaXJlY3Rvcnk6IHN0cmluZyxcbik6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICBsZXQgdGZGaWxlQ29udGVudHMgPSBcIlwiO1xuICBjb25zdCB0ZkpTT05GaWxlQ29udGVudHM6IFJlY29yZDxzdHJpbmcsIGFueT5bXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgZmlsZSBvZiBmcy5yZWFkZGlyU3luYyh3b3JraW5nRGlyZWN0b3J5KSkge1xuICAgIGNvbnN0IGZpbGVQYXRoID0gcmVzb2x2ZSh3b3JraW5nRGlyZWN0b3J5LCBmaWxlKTtcbiAgICBpZiAoIWZzLmxzdGF0U3luYyhmaWxlUGF0aCkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgaWYgKGZpbGUubWF0Y2goL1xcLnRmJC8pKSB7XG4gICAgICAgIHRmRmlsZUNvbnRlbnRzICs9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgXCJ1dGYtOFwiKTtcbiAgICAgICAgdGZGaWxlQ29udGVudHMgKz0gXCJcXG5cIjtcbiAgICAgIH0gZWxzZSBpZiAoZmlsZS5tYXRjaCgvXFwudGZcXC5qc29uJC8pKSB7XG4gICAgICAgIHRmSlNPTkZpbGVDb250ZW50cy5wdXNoKEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCBcInV0Zi04XCIpKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKHRmRmlsZUNvbnRlbnRzID09PSBcIlwiICYmIHRmSlNPTkZpbGVDb250ZW50cy5sZW5ndGggPT09IDApIHtcbiAgICBjb25zb2xlLmVycm9yKGBObyAnLnRmJyBvciAnLnRmLmpzb24nIGZpbGVzIGZvdW5kIGluICR7d29ya2luZ0RpcmVjdG9yeX1gKTtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICByZXR1cm4gZGVlcE1lcmdlKFxuICAgIGF3YWl0IHBhcnNlKFwiaGNsMmpzb24udGZcIiwgdGZGaWxlQ29udGVudHMpLFxuICAgIC4uLnRmSlNPTkZpbGVDb250ZW50cyxcbiAgKTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhIFRlcnJhZm9ybSBleHByZXNzaW9uIGFuZCByZXR1cm4gdGhlIEFTVC4gVGhpcyBmdW5jdGlvbiBleHBlY3RzIGEgc3RyaW5nIGlucHV0LCBhbmQgd2lsbCB3cmFwIHRoZSBleHByZXNzaW9uIGluIHF1b3RlcyBpZiBpdCBpcyBub3QgYWxyZWFkeSBxdW90ZWQuXG4gKiBAcGFyYW0gZmlsZW5hbWUgVGhlIGZpbGVuYW1lIHRvIHVzZSBmb3IgdGhlIGV4cHJlc3Npb24uIFRoaXMgaXMgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gcGFyc2UuXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBSZWZlcmVuY2VzIGZvdW5kIGluIHRoZSBleHByZXNzaW9uLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlc0luRXhwcmVzc2lvbihcbiAgZmlsZW5hbWU6IHN0cmluZyxcbiAgZXhwcmVzc2lvbjogc3RyaW5nLFxuKTogUHJvbWlzZTxSZWZlcmVuY2VbXT4ge1xuICAvLyBXZSBoYXZlIHRvIGRvIHRoaXMgdHdpY2UgYmVjYXVzZSBvZiB0aGUgcHJvYmxlbSB3aXRoIEhFUkVET0NTXG4gIC8vIE91ciBjdXJyZW50IGhjbDJqc29uIGltcGxlbWVudGF0aW9uIHJlbW92ZXMgSEVSRURPQ1MgYW5kIHJlcGxhY2VzIHRoZW1cbiAgLy8gd2l0aCBhIG11bHRpLWxpbmUgc3RyaW5nLCB3aGljaCBpcyBjYXVzaW5nIGFsbCBraW5kcyBvZiBwcm9ibGVtc1xuICBsZXQgb2Zmc2V0ID0gMDtcbiAgbGV0IHF1b3RlV3JhcHBlZEV4cHJlc3Npb24gPSBleHByZXNzaW9uO1xuICBpZiAoIWV4cHJlc3Npb24uc3RhcnRzV2l0aCgnXCInKSkge1xuICAgIHF1b3RlV3JhcHBlZEV4cHJlc3Npb24gPSBgXCIke2V4cHJlc3Npb259XCJgO1xuICAgIG9mZnNldCA9IDE7XG4gIH1cblxuICBjb25zdCB7IHdyYXA6IHdyYXBwZWRFeHByZXNzaW9uLCB3cmFwT2Zmc2V0OiBzdGFydE9mZnNldCB9ID1cbiAgICB3cmFwVGVycmFmb3JtRXhwcmVzc2lvbihgJHtxdW90ZVdyYXBwZWRFeHByZXNzaW9ufWApO1xuXG4gIG9mZnNldCArPSBzdGFydE9mZnNldDtcblxuICBjb25zdCBhc3QgPSBhd2FpdCBnZXRFeHByZXNzaW9uQXN0KGZpbGVuYW1lLCB3cmFwcGVkRXhwcmVzc2lvbik7XG4gIGlmICghYXN0KSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgcmVmcyA9IGZpbmRBbGxSZWZlcmVuY2VzSW5Bc3QoZXhwcmVzc2lvbiwgYXN0KTtcbiAgaWYgKHdyYXBwZWRFeHByZXNzaW9uID09PSBleHByZXNzaW9uKSB7XG4gICAgcmV0dXJuIHJlZnM7XG4gIH1cblxuICByZXR1cm4gcmVmcy5tYXAoKHJlZikgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5yZWYsXG4gICAgICBzdGFydFBvc2l0aW9uOiByZWYuc3RhcnRQb3NpdGlvbiAtIG9mZnNldCxcbiAgICAgIGVuZFBvc2l0aW9uOiByZWYuZW5kUG9zaXRpb24gLSBvZmZzZXQsXG4gICAgfTtcbiAgfSk7XG59XG5cbi8qKlxuICogUGFyc2UgYSBUZXJyYWZvcm0gZXhwcmVzc2lvbiBhbmQgcmV0dXJuIHRoZSBBU1QuIFRoZSBleHByZXNzaW9uIGRvZXMgbm90IG5lZWQgdG8gYmUgYSBUZXJyYWZvcm0gc3RyaW5nLlxuICogQHBhcmFtIGZpbGVuYW1lIFRoZSBmaWxlbmFtZSB0byB1c2UgZm9yIHRoZSBleHByZXNzaW9uLiBUaGlzIGlzIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy5cbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIHBhcnNlLlxuICogQHJldHVybnMgVGhlIEFTVCBmb3IgdGhlIGV4cHJlc3Npb24uXG4gKlxuICogICBUaGUgcmV0dXJuZWQgQVNUIGhhcyB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAqICAgLSB0eXBlOiBUaGUgdHlwZSBvZiB0aGUgbm9kZS4gVGhpcyBpcyBhIHN0cmluZy5cbiAqICAgLSByYW5nZTogVGhpcyBjb250YWlucyB0aGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgbm9kZSBpbiB0aGUgZXhwcmVzc2lvbi5cbiAqICAgLSBjaGlsZHJlbjogVGhpcyBjb250YWlucyB0aGUgY2hpbGRyZW4gb2YgdGhlIG5vZGUuIFRoaXMgaXMgYW4gYXJyYXkgb2Ygbm9kZXMuXG4gKiAgIC0gbWV0YTogVGhpcyBjb250YWlucyBtZXRhZGF0YSBhYm91dCB0aGUgbm9kZS4gVGhpcyBpcyBhbiBvYmplY3QsIGFuZCB2YXJpZXMgZGVwZW5kaW5nIG9uIHRoZSB0eXBlIG9mIHRoZSBub2RlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbkFzdChcbiAgZmlsZW5hbWU6IHN0cmluZyxcbiAgZXhwcmVzc2lvbjogc3RyaW5nLFxuKTogUHJvbWlzZTxFeHByZXNzaW9uVHlwZSB8IG51bGw+IHtcbiAgY29uc3QgcmVzID0gYXdhaXQgd2FzbS5nZXRFeHByZXNzaW9uQXN0KGZpbGVuYW1lLCBleHByZXNzaW9uKTtcbiAgY29uc3QgYXN0ID0gSlNPTi5wYXJzZShyZXMpIGFzIEV4cHJlc3Npb25UeXBlO1xuXG4gIGlmICghYXN0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gYXN0O1xufVxuIl19