"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.printers = exports.parsers = exports.languages = exports.options = void 0; const prettier_1 = require("prettier"); const doc_1 = require("prettier/doc"); const parser_html_1 = require("prettier/parser-html"); const parse_1 = require("./parse"); const htmlParser = parser_html_1.parsers.html; const PLUGIN_KEY = "go-template"; exports.options = { goTemplateBracketSpacing: { type: "boolean", category: "Global", description: "Specifies whether the brackets should have spacing around the statement.", default: true, }, }; exports.languages = [ { name: "GoTemplate", parsers: [PLUGIN_KEY], extensions: [ ".go.html", ".gohtml", ".gotmpl", ".go.tmpl", ".tmpl", ".tpl", ".html.tmpl", ".html.tpl", ], vscodeLanguageIds: ["gotemplate", "gohtml", "GoTemplate", "GoHTML"], }, ]; exports.parsers = { [PLUGIN_KEY]: { astFormat: PLUGIN_KEY, preprocess: (text) => text.endsWith("\n") ? text.slice(0, text.length - 1) : text, parse: parse_1.parseGoTemplate, locStart: (node) => node.index, locEnd: (node) => node.index + node.length, }, }; exports.printers = { [PLUGIN_KEY]: { print: (path, options, print) => { const node = path.getNode(); switch (node === null || node === void 0 ? void 0 : node.type) { case "inline": return printInline(node, path, options, print); case "double-block": return printMultiBlock(node, path, print); case "unformattable": return printUnformattable(node, options); } throw new Error(`An error occured during printing. Found invalid node ${node === null || node === void 0 ? void 0 : node.type}.`); }, embed: (path, options) => { try { return embed(path, options); } catch (e) { console.error("Formatting failed.", e); throw e; } }, }, }; const embed = () => { return (textToDoc, print, path, optionsA) => __awaiter(void 0, void 0, void 0, function* () { const node = path.getNode(); const options = optionsA; if (!node) { return undefined; } if (hasPrettierIgnoreLine(node)) { return options.originalText.substring(options.locStart(node), options.locEnd(node)); } if (node.type !== "block" && node.type !== "root") { return undefined; } const html = yield textToDoc(node.aliasedContent, Object.assign(Object.assign({}, options), { parser: "html", parentParser: "go-template" })); const mapped = doc_1.utils.stripTrailingHardline(doc_1.utils.mapDoc(html, (currentDoc) => { if (typeof currentDoc !== "string") { return currentDoc; } let result = currentDoc; Object.keys(node.children).forEach((key) => (result = prettier_1.doc.utils.mapDoc(result, (docNode) => typeof docNode !== "string" || !docNode.includes(key) ? docNode : [ docNode.substring(0, docNode.indexOf(key)), path.call(print, "children", key), docNode.substring(docNode.indexOf(key) + key.length), ]))); return result; })); if ((0, parse_1.isRoot)(node)) { return [mapped, doc_1.builders.hardline]; } const startStatement = path.call(print, "start"); const endStatement = node.end ? path.call(print, "end") : ""; if (isPrettierIgnoreBlock(node)) { return [ doc_1.utils.removeLines(path.call(print, "start")), printPlainBlock(node.content), endStatement, ]; } const content = node.aliasedContent.trim() ? doc_1.builders.indent([doc_1.builders.softline, mapped]) : ""; const result = [startStatement, content, doc_1.builders.softline, endStatement]; const emptyLine = !!node.end && isFollowedByEmptyLine(node.end, options.originalText) ? doc_1.builders.softline : ""; if ((0, parse_1.isMultiBlock)(node.parent)) { return [result, emptyLine]; } return doc_1.builders.group([doc_1.builders.group(result), emptyLine], { shouldBreak: !!node.end && hasNodeLinebreak(node.end, options.originalText), }); }); }; function printMultiBlock(node, path, print) { return [...path.map(print, "blocks")]; } function isFollowedByNode(node) { const parent = getFirstBlockParent(node).parent; const start = parent.aliasedContent.indexOf(node.id) + node.id.length; let nextNodeIndex = -1; Object.keys(parent.children).forEach((key) => { const index = parent.aliasedContent.indexOf(key, start); if (nextNodeIndex == -1 || index < nextNodeIndex) { nextNodeIndex = index; } }); return !!parent.aliasedContent .substring(start, nextNodeIndex) .match(/^\s+$/m); } function printInline(node, path, options, print) { const isBlockNode = isBlockEnd(node) || isBlockStart(node); const emptyLine = isFollowedByEmptyLine(node, options.originalText) && isFollowedByNode(node) ? doc_1.builders.softline : ""; const result = [ printStatement(node.statement, options.goTemplateBracketSpacing, { start: node.startDelimiter, end: node.endDelimiter, }), ]; return doc_1.builders.group([...result, emptyLine], { shouldBreak: hasNodeLinebreak(node, options.originalText) && !isBlockNode, }); } function isBlockEnd(node) { const { parent } = getFirstBlockParent(node); return (0, parse_1.isBlock)(parent) && parent.end === node; } function isBlockStart(node) { const { parent } = getFirstBlockParent(node); return (0, parse_1.isBlock)(parent) && parent.start === node; } function printStatement(statement, addSpaces, delimiter = { start: "", end: "", }) { const space = addSpaces ? " " : ""; const shouldBreak = statement.includes("\n"); const content = shouldBreak ? statement .trim() .split("\n") .map((line, _, array) => array.indexOf(line) === array.length - 1 ? [line.trim(), doc_1.builders.softline] : doc_1.builders.indent([line.trim(), doc_1.builders.softline])) : [statement.trim()]; return doc_1.builders.group([ "{{", delimiter.start, space, ...content, shouldBreak ? "" : space, delimiter.end, "}}", ], { shouldBreak }); } function hasPrettierIgnoreLine(node) { if ((0, parse_1.isRoot)(node)) { return false; } const { parent, child } = getFirstBlockParent(node); const regex = new RegExp(`(?:|}})\n.*${child.id}`); return !!parent.aliasedContent.match(regex); } function isPrettierIgnoreBlock(node) { return (0, parse_1.isBlock)(node) && node.keyword === "prettier-ignore-start"; } function hasNodeLinebreak(node, source) { const start = node.index + node.length; const end = source.indexOf("\n", start); const suffix = source.substring(start, end); return !suffix; } function isFollowedByEmptyLine(node, source) { const start = node.index + node.length; const firstLineBreak = source.indexOf("\n", start); const secondLineBreak = source.indexOf("\n", firstLineBreak + 1); const emptyLine = source .substring(firstLineBreak + 1, secondLineBreak) .trim(); const isLastNode = !!source.substring(start).match(/^\s*$/); return (firstLineBreak !== -1 && secondLineBreak !== -1 && !emptyLine && !isLastNode); } function getFirstBlockParent(node) { let previous = node; let current = node.parent; while (!(0, parse_1.isBlock)(current) && !(0, parse_1.isRoot)(current)) { previous = current; current = current.parent; } return { child: previous, parent: current, }; } function printUnformattable(node, options) { var _a, _b; const start = options.originalText.lastIndexOf("\n", node.index - 1); const line = options.originalText.substring(start, node.index + node.length); const lineWithoutAdditionalContent = (_b = (_a = line.replace(node.content, "").match(/\s*$/)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : ""; return printPlainBlock(lineWithoutAdditionalContent + node.content, false); } function printPlainBlock(text, hardlines = true) { const isTextEmpty = (input) => !!input.match(/^\s*$/); const lines = text.split("\n"); const segments = lines.filter((value, i) => !(i == 0 || i == lines.length - 1) || !isTextEmpty(value)); return [ ...segments.map((content, i) => [ hardlines || i ? doc_1.builders.hardline : "", doc_1.builders.trim, content, ]), hardlines ? doc_1.builders.hardline : "", ]; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsdUNBT2tCO0FBQ2xCLHNDQUErQztBQUMvQyxzREFBOEQ7QUFDOUQsbUNBYWlCO0FBRWpCLE1BQU0sVUFBVSxHQUFHLHFCQUFXLENBQUMsSUFBSSxDQUFDO0FBQ3BDLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQztBQVNwQixRQUFBLE9BQU8sR0FFaEI7SUFDRix3QkFBd0IsRUFBRTtRQUN4QixJQUFJLEVBQUUsU0FBUztRQUNmLFFBQVEsRUFBRSxRQUFRO1FBQ2xCLFdBQVcsRUFDVCwwRUFBMEU7UUFDNUUsT0FBTyxFQUFFLElBQUk7S0FDZDtDQUNGLENBQUM7QUFFVyxRQUFBLFNBQVMsR0FBc0I7SUFDMUM7UUFDRSxJQUFJLEVBQUUsWUFBWTtRQUNsQixPQUFPLEVBQUUsQ0FBQyxVQUFVLENBQUM7UUFDckIsVUFBVSxFQUFFO1lBQ1YsVUFBVTtZQUNWLFNBQVM7WUFDVCxTQUFTO1lBQ1QsVUFBVTtZQUNWLE9BQU87WUFDUCxNQUFNO1lBQ04sWUFBWTtZQUNaLFdBQVc7U0FDWjtRQUNELGlCQUFpQixFQUFFLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDO0tBQ3BFO0NBQ0YsQ0FBQztBQUNXLFFBQUEsT0FBTyxHQUFHO0lBQ3JCLENBQUMsVUFBVSxDQUFDLEVBQWtCO1FBQzVCLFNBQVMsRUFBRSxVQUFVO1FBQ3JCLFVBQVUsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBRW5CLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUk7UUFDN0QsS0FBSyxFQUFFLHVCQUFlO1FBQ3RCLFFBQVEs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QUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFL0IsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FDM0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FDeEUsQ0FBQztJQUVGLE9BQU87UUFDTCxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUM5QixTQUFTLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ3ZDLGNBQVEsQ0FBQyxJQUFJO1lBQ2IsT0FBTztTQUNSLENBQUM7UUFDRixTQUFTLENBQUMsQ0FBQyxDQUFDLGNBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUU7S0FDbkMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBkb2MsXG4gIEZhc3RQYXRoLFxuICBQYXJzZXIsXG4gIFBhcnNlck9wdGlvbnMsXG4gIFByaW50ZXIsXG4gIFN1cHBvcnRMYW5ndWFnZSxcbn0gZnJvbSBcInByZXR0aWVyXCI7XG5pbXBvcnQgeyBidWlsZGVycywgdXRpbHMgfSBmcm9tIFwicHJldHRpZXIvZG9jXCI7XG5pbXBvcnQgeyBwYXJzZXJzIGFzIGh0bWxQYXJzZXJzIH0gZnJvbSBcInByZXR0aWVyL3BhcnNlci1odG1sXCI7XG5pbXBvcnQge1xuICBHb0Jsb2NrLFxuICBHb0lubGluZSxcbiAgR29JbmxpbmVFbmREZWxpbWl0ZXIsXG4gIEdvSW5saW5lU3RhcnREZWxpbWl0ZXIsXG4gIEdvTXVsdGlCbG9jayxcbiAgR29Ob2RlLFxuICBHb1Jvb3QsXG4gIEdvVW5mb3JtYXR0YWJsZSxcbiAgaXNCbG9jayxcbiAgaXNNdWx0aUJsb2NrLFxuICBpc1Jvb3QsXG4gIHBhcnNlR29UZW1wbGF0ZSxcbn0gZnJvbSBcIi4vcGFyc2VcIjtcblxuY29uc3QgaHRtbFBhcnNlciA9IGh0bWxQYXJzZXJzLmh0bWw7XG5jb25zdCBQTFVHSU5fS0VZID0gXCJnby10ZW1wbGF0ZVwiO1xuXG50eXBlIEV4dGVuZGVkUGFyc2VyT3B0aW9ucyA9IFBhcnNlck9wdGlvbnM8R29Ob2RlPiAmXG4gIFByZXR0aWVyUGx1Z2luR29UZW1wbGF0ZVBhcnNlck9wdGlvbnM7XG5cbmV4cG9ydCB0eXBlIFByZXR0aWVyUGx1Z2luR29UZW1wbGF0ZVBhcnNlck9wdGlvbnMgPSB7XG4gIGdvVGVtcGxhdGVCcmFja2V0U3BhY2luZzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBjb25zdCBvcHRpb25zOiB7XG4gIFtLIGluIGtleW9mIFByZXR0aWVyUGx1Z2luR29UZW1wbGF0ZVBhcnNlck9wdGlvbnNdOiBhbnk7XG59ID0ge1xuICBnb1RlbXBsYXRlQnJhY2tldFNwYWNpbmc6IHtcbiAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICBjYXRlZ29yeTogXCJHbG9iYWxcIixcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgIFwiU3BlY2lmaWVzIHdoZXRoZXIgdGhlIGJyYWNrZXRzIHNob3VsZCBoYXZlIHNwYWNpbmcgYXJvdW5kIHRoZSBzdGF0ZW1lbnQuXCIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbn07XG5cbmV4cG9ydCBjb25zdCBsYW5ndWFnZXM6IFN1cHBvcnRMYW5ndWFnZVtdID0gW1xuICB7XG4gICAgbmFtZTogXCJHb1RlbXBsYXRlXCIsXG4gICAgcGFyc2VyczogW1BMVUdJTl9LRVldLFxuICAgIGV4dGVuc2lvbnM6IFtcbiAgICAgIFwiLmdvLmh0bWxcIixcbiAgICAgIFwiLmdvaHRtbFwiLFxuICAgICAgXCIuZ290bXBsXCIsXG4gICAgICBcIi5nby50bXBsXCIsXG4gICAgICBcIi50bXBsXCIsXG4gICAgICBcIi50cGxcIixcbiAgICAgIFwiLmh0bWwudG1wbFwiLFxuICAgICAgXCIuaHRtbC50cGxcIixcbiAgICBdLFxuICAgIHZzY29kZUxhbmd1YWdlSWRzOiBbXCJnb3RlbXBsYXRlXCIsIFwiZ29odG1sXCIsIFwiR29UZW1wbGF0ZVwiLCBcIkdvSFRNTFwiXSxcbiAgfSxcbl07XG5leHBvcnQgY29uc3QgcGFyc2VycyA9IHtcbiAgW1BMVUdJTl9LRVldOiA8UGFyc2VyPEdvTm9kZT4+e1xuICAgIGFzdEZvcm1hdDogUExVR0lOX0tFWSxcbiAgICBwcmVwcm9jZXNzOiAodGV4dCkgPT5cbiAgICAgIC8vIEN1dCBhd2F5IHRyYWlsaW5nIG5ld2xpbmUgdG8gbm9ybWFsaXplIGZvcm1hdHRpbmcuXG4gICAgICB0ZXh0LmVuZHNXaXRoKFwiXFxuXCIpID8gdGV4dC5zbGljZSgwLCB0ZXh0Lmxlbmd0aCAtIDEpIDogdGV4dCxcbiAgICBwYXJzZTogcGFyc2VHb1RlbXBsYXRlLFxuICAgIGxvY1N0YXJ0OiAobm9kZSkgPT4gbm9kZS5pbmRleCxcbiAgICBsb2NFbmQ6IChub2RlKSA9PiBub2RlLmluZGV4ICsgbm9kZS5sZW5ndGgsXG4gIH0sXG59O1xuZXhwb3J0IGNvbnN0IHByaW50ZXJzID0ge1xuICBbUExVR0lOX0tFWV06IDxQcmludGVyPEdvTm9kZT4+e1xuICAgIHByaW50OiAocGF0aCwgb3B0aW9uczogRXh0ZW5kZWRQYXJzZXJPcHRpb25zLCBwcmludCkgPT4ge1xuICAgICAgY29uc3Qgbm9kZSA9IHBhdGguZ2V0Tm9kZSgpO1xuXG4gICAgICBzd2l0Y2ggKG5vZGU/LnR5cGUpIHtcbiAgICAgICAgY2FzZSBcImlubGluZVwiOlxuICAgICAgICAgIHJldHVybiBwcmludElubGluZShub2RlLCBwYXRoLCBvcHRpb25zLCBwcmludCk7XG4gICAgICAgIGNhc2UgXCJkb3VibGUtYmxvY2tcIjpcbiAgICAgICAgICByZXR1cm4gcHJpbnRNdWx0aUJsb2NrKG5vZGUsIHBhdGgsIHByaW50KTtcbiAgICAgICAgY2FzZSBcInVuZm9ybWF0dGFibGVcIjpcbiAgICAgICAgICByZXR1cm4gcHJpbnRVbmZvcm1hdHRhYmxlKG5vZGUsIG9wdGlvbnMpO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBBbiBlcnJvciBvY2N1cmVkIGR1cmluZyBwcmludGluZy4gRm91bmQgaW52YWxpZCBub2RlICR7bm9kZT8udHlwZX0uYCxcbiAgICAgICk7XG4gICAgfSxcbiAgICBlbWJlZDogKHBhdGgsIG9wdGlvbnMpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBlbWJlZChwYXRoLCBvcHRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkZvcm1hdHRpbmcgZmFpbGVkLlwiLCBlKTtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9LFxuICB9LFxufTtcblxuY29uc3QgZW1iZWQ6IEV4Y2x1ZGU8UHJpbnRlcjxHb05vZGU+W1wiZW1iZWRcIl0sIHVuZGVmaW5lZD4gPSAoKSA9PiB7XG4gIHJldHVybiBhc3luYyAodGV4dFRvRG9jLCBwcmludCwgcGF0aCwgb3B0aW9uc0EpID0+IHtcbiAgICBjb25zdCBub2RlID0gcGF0aC5nZXROb2RlKCk7XG5cbiAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0EgYXMgUGFyc2VyT3B0aW9ucztcblxuICAgIGlmICghbm9kZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoaGFzUHJldHRpZXJJZ25vcmVMaW5lKG5vZGUpKSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5vcmlnaW5hbFRleHQuc3Vic3RyaW5nKFxuICAgICAgICBvcHRpb25zLmxvY1N0YXJ0KG5vZGUpLFxuICAgICAgICBvcHRpb25zLmxvY0VuZChub2RlKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUudHlwZSAhPT0gXCJibG9ja1wiICYmIG5vZGUudHlwZSAhPT0gXCJyb290XCIpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgaHRtbCA9IGF3YWl0IHRleHRUb0RvYyhub2RlLmFsaWFzZWRDb250ZW50LCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgcGFyc2VyOiBcImh0bWxcIixcbiAgICAgIHBhcmVudFBhcnNlcjogXCJnby10ZW1wbGF0ZVwiLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWFwcGVkID0gdXRpbHMuc3RyaXBUcmFpbGluZ0hhcmRsaW5lKFxuICAgICAgdXRpbHMubWFwRG9jKGh0bWwsIChjdXJyZW50RG9jKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgY3VycmVudERvYyAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHJldHVybiBjdXJyZW50RG9jO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJlc3VsdDogYnVpbGRlcnMuRG9jID0gY3VycmVudERvYztcblxuICAgICAgICBPYmplY3Qua2V5cyhub2RlLmNoaWxkcmVuKS5mb3JFYWNoKFxuICAgICAgICAgIChrZXkpID0+XG4gICAgICAgICAgICAocmVzdWx0ID0gZG9jLnV0aWxzLm1hcERvYyhyZXN1bHQsIChkb2NOb2RlKSA9PlxuICAgICAgICAgICAgICB0eXBlb2YgZG9jTm9kZSAhPT0gXCJzdHJpbmdcIiB8fCAhZG9jTm9kZS5pbmNsdWRlcyhrZXkpXG4gICAgICAgICAgICAgICAgPyBkb2NOb2RlXG4gICAgICAgICAgICAgICAgOiBbXG4gICAgICAgICAgICAgICAgICAgIGRvY05vZGUuc3Vic3RyaW5nKDAsIGRvY05vZGUuaW5kZXhPZihrZXkpKSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aC5jYWxsKHByaW50LCBcImNoaWxkcmVuXCIsIGtleSksXG4gICAgICAgICAgICAgICAgICAgIGRvY05vZGUuc3Vic3RyaW5nKGRvY05vZGUuaW5kZXhPZihrZXkpICsga2V5Lmxlbmd0aCksXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgKSksXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBpZiAoaXNSb290KG5vZGUpKSB7XG4gICAgICByZXR1cm4gW21hcHBlZCwgYnVpbGRlcnMuaGFyZGxpbmVdO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0U3RhdGVtZW50ID0gcGF0aC5jYWxsKHByaW50LCBcInN0YXJ0XCIpO1xuICAgIGNvbnN0IGVuZFN0YXRlbWVudCA9IG5vZGUuZW5kID8gcGF0aC5jYWxsKHByaW50LCBcImVuZFwiKSA6IFwiXCI7XG5cbiAgICBpZiAoaXNQcmV0dGllcklnbm9yZUJsb2NrKG5vZGUpKSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB1dGlscy5yZW1vdmVMaW5lcyhwYXRoLmNhbGwocHJpbnQsIFwic3RhcnRcIikpLFxuICAgICAgICBwcmludFBsYWluQmxvY2sobm9kZS5jb250ZW50KSxcbiAgICAgICAgZW5kU3RhdGVtZW50LFxuICAgICAgXTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250ZW50ID0gbm9kZS5hbGlhc2VkQ29udGVudC50cmltKClcbiAgICAgID8gYnVpbGRlcnMuaW5kZW50KFtidWlsZGVycy5zb2Z0bGluZSwgbWFwcGVkXSlcbiAgICAgIDogXCJcIjtcblxuICAgIGNvbnN0IHJlc3VsdCA9IFtzdGFydFN0YXRlbWVudCwgY29udGVudCwgYnVpbGRlcnMuc29mdGxpbmUsIGVuZFN0YXRlbWVudF07XG5cbiAgICBjb25zdCBlbXB0eUxpbmUgPVxuICAgICAgISFub2RlLmVuZCAmJiBpc0ZvbGxvd2VkQnlFbXB0eUxpbmUobm9kZS5lbmQsIG9wdGlvbnMub3JpZ2luYWxUZXh0KVxuICAgICAgICA/IGJ1aWxkZXJzLnNvZnRsaW5lXG4gICAgICAgIDogXCJcIjtcblxuICAgIGlmIChpc011bHRpQmxvY2sobm9kZS5wYXJlbnQpKSB7XG4gICAgICByZXR1cm4gW3Jlc3VsdCwgZW1wdHlMaW5lXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVpbGRlcnMuZ3JvdXAoW2J1aWxkZXJzLmdyb3VwKHJlc3VsdCksIGVtcHR5TGluZV0sIHtcbiAgICAgIHNob3VsZEJyZWFrOlxuICAgICAgICAhIW5vZGUuZW5kICYmIGhhc05vZGVMaW5lYnJlYWsobm9kZS5lbmQsIG9wdGlvbnMub3JpZ2luYWxUZXh0KSxcbiAgICB9KTtcbiAgfTtcbn07XG5cbnR5cGUgUHJpbnRGbiA9IChwYXRoOiBGYXN0UGF0aDxHb05vZGU+KSA9PiBidWlsZGVycy5Eb2M7XG5cbmZ1bmN0aW9uIHByaW50TXVsdGlCbG9jayhcbiAgbm9kZTogR29NdWx0aUJsb2NrLFxuICBwYXRoOiBGYXN0UGF0aDxHb05vZGU+LFxuICBwcmludDogUHJpbnRGbixcbik6IGJ1aWxkZXJzLkRvYyB7XG4gIHJldHVybiBbLi4ucGF0aC5tYXAocHJpbnQsIFwiYmxvY2tzXCIpXTtcbn1cblxuZnVuY3Rpb24gaXNGb2xsb3dlZEJ5Tm9kZShub2RlOiBHb0lubGluZSk6IGJvb2xlYW4ge1xuICBjb25zdCBwYXJlbnQgPSBnZXRGaXJzdEJsb2NrUGFyZW50KG5vZGUpLnBhcmVudDtcbiAgY29uc3Qgc3RhcnQgPSBwYXJlbnQuYWxpYXNlZENvbnRlbnQuaW5kZXhPZihub2RlLmlkKSArIG5vZGUuaWQubGVuZ3RoO1xuXG4gIGxldCBuZXh0Tm9kZUluZGV4ID0gLTE7XG4gIE9iamVjdC5rZXlzKHBhcmVudC5jaGlsZHJlbikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgY29uc3QgaW5kZXggPSBwYXJlbnQuYWxpYXNlZENvbnRlbnQuaW5kZXhPZihrZXksIHN0YXJ0KTtcbiAgICBpZiAobmV4dE5vZGVJbmRleCA9PSAtMSB8fCBpbmRleCA8IG5leHROb2RlSW5kZXgpIHtcbiAgICAgIG5leHROb2RlSW5kZXggPSBpbmRleDtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiAhIXBhcmVudC5hbGlhc2VkQ29udGVudFxuICAgIC5zdWJzdHJpbmcoc3RhcnQsIG5leHROb2RlSW5kZXgpXG4gICAgLm1hdGNoKC9eXFxzKyQvbSk7XG59XG5cbmZ1bmN0aW9uIHByaW50SW5saW5lKFxuICBub2RlOiBHb0lubGluZSxcbiAgcGF0aDogRmFzdFBhdGg8R29Ob2RlPixcbiAgb3B0aW9uczogRXh0ZW5kZWRQYXJzZXJPcHRpb25zLFxuICBwcmludDogUHJpbnRGbixcbik6IGJ1aWxkZXJzLkRvYyB7XG4gIGNvbnN0IGlzQmxvY2tOb2RlID0gaXNCbG9ja0VuZChub2RlKSB8fCBpc0Jsb2NrU3RhcnQobm9kZSk7XG4gIGNvbnN0IGVtcHR5TGluZSA9XG4gICAgaXNGb2xsb3dlZEJ5RW1wdHlMaW5lKG5vZGUsIG9wdGlvbnMub3JpZ2luYWxUZXh0KSAmJiBpc0ZvbGxvd2VkQnlOb2RlKG5vZGUpXG4gICAgICA/IGJ1aWxkZXJzLnNvZnRsaW5lXG4gICAgICA6IFwiXCI7XG5cbiAgY29uc3QgcmVzdWx0OiBidWlsZGVycy5Eb2NbXSA9IFtcbiAgICBwcmludFN0YXRlbWVudChub2RlLnN0YXRlbWVudCwgb3B0aW9ucy5nb1RlbXBsYXRlQnJhY2tldFNwYWNpbmcsIHtcbiAgICAgIHN0YXJ0OiBub2RlLnN0YXJ0RGVsaW1pdGVyLFxuICAgICAgZW5kOiBub2RlLmVuZERlbGltaXRlcixcbiAgICB9KSxcbiAgXTtcblxuICByZXR1cm4gYnVpbGRlcnMuZ3JvdXAoWy4uLnJlc3VsdCwgZW1wdHlMaW5lXSwge1xuICAgIHNob3VsZEJyZWFrOiBoYXNOb2RlTGluZWJyZWFrKG5vZGUsIG9wdGlvbnMub3JpZ2luYWxUZXh0KSAmJiAhaXNCbG9ja05vZGUsXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpc0Jsb2NrRW5kKG5vZGU6IEdvSW5saW5lKSB7XG4gIGNvbnN0IHsgcGFyZW50IH0gPSBnZXRGaXJzdEJsb2NrUGFyZW50KG5vZGUpO1xuICByZXR1cm4gaXNCbG9jayhwYXJlbnQpICYmIHBhcmVudC5lbmQgPT09IG5vZGU7XG59XG5cbmZ1bmN0aW9uIGlzQmxvY2tTdGFydChub2RlOiBHb0lubGluZSkge1xuICBjb25zdCB7IHBhcmVudCB9ID0gZ2V0Rmlyc3RCbG9ja1BhcmVudChub2RlKTtcbiAgcmV0dXJuIGlzQmxvY2socGFyZW50KSAmJiBwYXJlbnQuc3RhcnQgPT09IG5vZGU7XG59XG5cbmZ1bmN0aW9uIHByaW50U3RhdGVtZW50KFxuICBzdGF0ZW1lbnQ6IHN0cmluZyxcbiAgYWRkU3BhY2VzOiBib29sZWFuLFxuICBkZWxpbWl0ZXI6IHsgc3RhcnQ6IEdvSW5saW5lU3RhcnREZWxpbWl0ZXI7IGVuZDogR29JbmxpbmVFbmREZWxpbWl0ZXIgfSA9IHtcbiAgICBzdGFydDogXCJcIixcbiAgICBlbmQ6IFwiXCIsXG4gIH0sXG4pIHtcbiAgY29uc3Qgc3BhY2UgPSBhZGRTcGFjZXMgPyBcIiBcIiA6IFwiXCI7XG4gIGNvbnN0IHNob3VsZEJyZWFrID0gc3RhdGVtZW50LmluY2x1ZGVzKFwiXFxuXCIpO1xuXG4gIGNvbnN0IGNvbnRlbnQgPSBzaG91bGRCcmVha1xuICAgID8gc3RhdGVtZW50XG4gICAgICAgIC50cmltKClcbiAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgICAgIC5tYXAoKGxpbmUsIF8sIGFycmF5KSA9PlxuICAgICAgICAgIGFycmF5LmluZGV4T2YobGluZSkgPT09IGFycmF5Lmxlbmd0aCAtIDFcbiAgICAgICAgICAgID8gW2xpbmUudHJpbSgpLCBidWlsZGVycy5zb2Z0bGluZV1cbiAgICAgICAgICAgIDogYnVpbGRlcnMuaW5kZW50KFtsaW5lLnRyaW0oKSwgYnVpbGRlcnMuc29mdGxpbmVdKSxcbiAgICAgICAgKVxuICAgIDogW3N0YXRlbWVudC50cmltKCldO1xuXG4gIHJldHVybiBidWlsZGVycy5ncm91cChcbiAgICBbXG4gICAgICBcInt7XCIsXG4gICAgICBkZWxpbWl0ZXIuc3RhcnQsXG4gICAgICBzcGFjZSxcbiAgICAgIC4uLmNvbnRlbnQsXG4gICAgICBzaG91bGRCcmVhayA/IFwiXCIgOiBzcGFjZSxcbiAgICAgIGRlbGltaXRlci5lbmQsXG4gICAgICBcIn19XCIsXG4gICAgXSxcbiAgICB7IHNob3VsZEJyZWFrIH0sXG4gICk7XG59XG5cbmZ1bmN0aW9uIGhhc1ByZXR0aWVySWdub3JlTGluZShub2RlOiBHb05vZGUpIHtcbiAgaWYgKGlzUm9vdChub2RlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHsgcGFyZW50LCBjaGlsZCB9ID0gZ2V0Rmlyc3RCbG9ja1BhcmVudChub2RlKTtcblxuICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgYCg/OjwhLS18e3spLio/cHJldHRpZXItaWdub3JlLio/KD86LS0+fH19KVxcbi4qJHtjaGlsZC5pZH1gLFxuICApO1xuXG4gIHJldHVybiAhIXBhcmVudC5hbGlhc2VkQ29udGVudC5tYXRjaChyZWdleCk7XG59XG5cbmZ1bmN0aW9uIGlzUHJldHRpZXJJZ25vcmVCbG9jayhub2RlOiBHb05vZGUpIHtcbiAgcmV0dXJuIGlzQmxvY2sobm9kZSkgJiYgbm9kZS5rZXl3b3JkID09PSBcInByZXR0aWVyLWlnbm9yZS1zdGFydFwiO1xufVxuXG5mdW5jdGlvbiBoYXNOb2RlTGluZWJyZWFrKG5vZGU6IEdvSW5saW5lLCBzb3VyY2U6IHN0cmluZykge1xuICBjb25zdCBzdGFydCA9IG5vZGUuaW5kZXggKyBub2RlLmxlbmd0aDtcbiAgY29uc3QgZW5kID0gc291cmNlLmluZGV4T2YoXCJcXG5cIiwgc3RhcnQpO1xuICBjb25zdCBzdWZmaXggPSBzb3VyY2Uuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpO1xuXG4gIHJldHVybiAhc3VmZml4O1xufVxuXG5mdW5jdGlvbiBpc0ZvbGxvd2VkQnlFbXB0eUxpbmUobm9kZTogR29JbmxpbmUsIHNvdXJjZTogc3RyaW5nKSB7XG4gIGNvbnN0IHN0YXJ0ID0gbm9kZS5pbmRleCArIG5vZGUubGVuZ3RoO1xuICBjb25zdCBmaXJzdExpbmVCcmVhayA9IHNvdXJjZS5pbmRleE9mKFwiXFxuXCIsIHN0YXJ0KTtcbiAgY29uc3Qgc2Vjb25kTGluZUJyZWFrID0gc291cmNlLmluZGV4T2YoXCJcXG5cIiwgZmlyc3RMaW5lQnJlYWsgKyAxKTtcbiAgY29uc3QgZW1wdHlMaW5lID0gc291cmNlXG4gICAgLnN1YnN0cmluZyhmaXJzdExpbmVCcmVhayArIDEsIHNlY29uZExpbmVCcmVhaylcbiAgICAudHJpbSgpO1xuICBjb25zdCBpc0xhc3ROb2RlID0gISFzb3VyY2Uuc3Vic3RyaW5nKHN0YXJ0KS5tYXRjaCgvXlxccyokLyk7XG5cbiAgcmV0dXJuIChcbiAgICBmaXJzdExpbmVCcmVhayAhPT0gLTEgJiYgc2Vjb25kTGluZUJyZWFrICE9PSAtMSAmJiAhZW1wdHlMaW5lICYmICFpc0xhc3ROb2RlXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldEZpcnN0QmxvY2tQYXJlbnQobm9kZTogRXhjbHVkZTxHb05vZGUsIEdvUm9vdD4pOiB7XG4gIHBhcmVudDogR29CbG9jayB8IEdvUm9vdDtcbiAgY2hpbGQ6IHR5cGVvZiBub2RlO1xufSB7XG4gIGxldCBwcmV2aW91cyA9IG5vZGU7XG4gIGxldCBjdXJyZW50ID0gbm9kZS5wYXJlbnQ7XG5cbiAgd2hpbGUgKCFpc0Jsb2NrKGN1cnJlbnQpICYmICFpc1Jvb3QoY3VycmVudCkpIHtcbiAgICBwcmV2aW91cyA9IGN1cnJlbnQ7XG4gICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjaGlsZDogcHJldmlvdXMsXG4gICAgcGFyZW50OiBjdXJyZW50LFxuICB9O1xufVxuXG5mdW5jdGlvbiBwcmludFVuZm9ybWF0dGFibGUoXG4gIG5vZGU6IEdvVW5mb3JtYXR0YWJsZSxcbiAgb3B0aW9uczogRXh0ZW5kZWRQYXJzZXJPcHRpb25zLFxuKSB7XG4gIGNvbnN0IHN0YXJ0ID0gb3B0aW9ucy5vcmlnaW5hbFRleHQubGFzdEluZGV4T2YoXCJcXG5cIiwgbm9kZS5pbmRleCAtIDEpO1xuICBjb25zdCBsaW5lID0gb3B0aW9ucy5vcmlnaW5hbFRleHQuc3Vic3RyaW5nKHN0YXJ0LCBub2RlLmluZGV4ICsgbm9kZS5sZW5ndGgpO1xuICBjb25zdCBsaW5lV2l0aG91dEFkZGl0aW9uYWxDb250ZW50ID1cbiAgICBsaW5lLnJlcGxhY2Uobm9kZS5jb250ZW50LCBcIlwiKS5tYXRjaCgvXFxzKiQvKT8uWzBdID8/IFwiXCI7XG5cbiAgcmV0dXJuIHByaW50UGxhaW5CbG9jayhsaW5lV2l0aG91dEFkZGl0aW9uYWxDb250ZW50ICsgbm9kZS5jb250ZW50LCBmYWxzZSk7XG59XG5cbmZ1bmN0aW9uIHByaW50UGxhaW5CbG9jayh0ZXh0OiBzdHJpbmcsIGhhcmRsaW5lcyA9IHRydWUpOiBidWlsZGVycy5Eb2Mge1xuICBjb25zdCBpc1RleHRFbXB0eSA9IChpbnB1dDogc3RyaW5nKSA9PiAhIWlucHV0Lm1hdGNoKC9eXFxzKiQvKTtcblxuICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoXCJcXG5cIik7XG5cbiAgY29uc3Qgc2VnbWVudHMgPSBsaW5lcy5maWx0ZXIoXG4gICAgKHZhbHVlLCBpKSA9PiAhKGkgPT0gMCB8fCBpID09IGxpbmVzLmxlbmd0aCAtIDEpIHx8ICFpc1RleHRFbXB0eSh2YWx1ZSksXG4gICk7XG5cbiAgcmV0dXJuIFtcbiAgICAuLi5zZWdtZW50cy5tYXAoKGNvbnRlbnQsIGkpID0+IFtcbiAgICAgIGhhcmRsaW5lcyB8fCBpID8gYnVpbGRlcnMuaGFyZGxpbmUgOiBcIlwiLFxuICAgICAgYnVpbGRlcnMudHJpbSxcbiAgICAgIGNvbnRlbnQsXG4gICAgXSksXG4gICAgaGFyZGxpbmVzID8gYnVpbGRlcnMuaGFyZGxpbmUgOiBcIlwiLFxuICBdO1xufVxuIl19