/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __reExport = (target, module2, desc) => { if (module2 && typeof module2 === "object" || typeof module2 === "function") { for (let key of __getOwnPropNames(module2)) if (!__hasOwnProp.call(target, key) && key !== "default") __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); } return target; }; var __toModule = (module2) => { return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // main.ts __export(exports, { BetterCodeBlocks: () => BetterCodeBlocks, default: () => BetterCodeBlock }); var import_obsidian = __toModule(require("obsidian")); var DEFAULT_LANG = ""; var LANG_REG = /^language-/; var LINE_SPLIT_MARK = "\n"; var titleRegExp = /TI:"([^"]*)"/i; var highLightLinesRegExp = /HL:"([^"]*)"/i; var foldRegExp = /"FOLD"/i; var CB_PADDING_TOP = "35px"; var DEFAULT_SETTINGS = { substitutionTokenForSpace: void 0, titleBackgroundColor: "#00000020", titleFontColor: void 0, highLightColor: "#2d82cc20", excludeLangs: [], showLineNumber: true, showDividingLine: false, showLangNameInTopRight: true }; var BetterCodeBlock = class extends import_obsidian.Plugin { onload() { return __async(this, null, function* () { console.log("Loading Better Code Block Plugin"); yield this.loadSettings(); this.addSettingTab(new BetterCodeBlockTab(this.app, this)); this.registerMarkdownPostProcessor((el, ctx) => { BetterCodeBlocks(el, ctx, this); app.workspace.on("resize", () => { resizeNumWrapAndHLWrap(el, ctx); }); }); }); } onunload() { console.log("Unloading Better Code Block Plugin"); } loadSettings() { return __async(this, null, function* () { this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData()); }); } saveSettings() { return __async(this, null, function* () { yield this.saveData(this.settings); }); } }; var BetterCodeBlockTab = class extends import_obsidian.PluginSettingTab { constructor(app2, plugin) { super(app2, plugin); this.plugin = plugin; } display() { let { containerEl } = this; containerEl.empty(); new import_obsidian.Setting(containerEl).setName("Exclude language list").setDesc("Title and line numbers do not apply in these languages, separate by `,`").addText((text) => text.setPlaceholder("like todoist,other,...").setValue(this.plugin.settings.excludeLangs.join(",")).onChange((value) => __async(this, null, function* () { this.plugin.settings.excludeLangs = value.split(","); yield this.plugin.saveSettings(); }))); new import_obsidian.Setting(containerEl).setName("Font color of title").addText((tc) => tc.setPlaceholder("Enter a color").setValue(this.plugin.settings.titleFontColor).onChange((value) => __async(this, null, function* () { this.plugin.settings.titleFontColor = value; yield this.plugin.saveSettings(); }))); new import_obsidian.Setting(containerEl).setName("Background color of title").addText((tc) => tc.setPlaceholder("#00000020").setValue(this.plugin.settings.titleBackgroundColor).onChange((value) => __async(this, null, function* () { this.plugin.settings.titleBackgroundColor = value; yield this.plugin.saveSettings(); }))); new import_obsidian.Setting(containerEl).setName("HighLight Color").addText((tc) => tc.setPlaceholder("#2d82cc20").setValue(this.plugin.settings.highLightColor).onChange((value) => __async(this, null, function* () { this.plugin.settings.highLightColor = value; yield this.plugin.saveSettings(); }))); new import_obsidian.Setting(containerEl).setName("Show line number").addToggle((tc) => tc.setValue(this.plugin.settings.showLineNumber).onChange((value) => __async(this, null, function* () { this.plugin.settings.showLineNumber = value; yield this.plugin.saveSettings(); }))); new import_obsidian.Setting(containerEl).setName("Show dividing line").addToggle((tc) => tc.setValue(this.plugin.settings.showDividingLine).onChange((value) => __async(this, null, function* () { this.plugin.settings.showDividingLine = value; yield this.plugin.saveSettings(); }))); new import_obsidian.Setting(containerEl).setName("Show language name in the top right").addToggle((tc) => tc.setValue(this.plugin.settings.showLangNameInTopRight).onChange((value) => __async(this, null, function* () { this.plugin.settings.showLangNameInTopRight = value; yield this.plugin.saveSettings(); }))); } }; function BetterCodeBlocks(el, context, plugin) { return __async(this, null, function* () { var _a; const settings = plugin.settings; const codeElm = el.querySelector("pre > code"); if (!codeElm) { return; } let lang = DEFAULT_LANG; if (plugin.settings.excludeLangs.some((eLangName) => codeElm.classList.contains(`language-${eLangName}`))) { return; } codeElm.classList.forEach((value, key, parent) => { if (LANG_REG.test(value)) { lang = value.replace("language-", ""); return; } }); if (lang == DEFAULT_LANG) { return; } let codeBlock = context.getSectionInfo(codeElm); let codeBlockFirstLine = ""; if (codeBlock) { let view = app.workspace.getActiveViewOfType(import_obsidian.MarkdownView); codeBlockFirstLine = view.editor.getLine(codeBlock.lineStart); } else { let file = app.vault.getAbstractFileByPath(context.sourcePath); let cache = app.metadataCache.getCache(context.sourcePath); let fileContent = yield app.vault.cachedRead(file); let fileContentLines = fileContent.split(/\n/g); let codeBlockFirstLines = []; let codeBlockSections = []; (_a = cache.sections) == null ? void 0 : _a.forEach((element) => __async(this, null, function* () { if (element.type == "code") { let lineStart = element.position.start.line; codeBlockFirstLine = fileContentLines[lineStart]; codeBlockSections.push(element); codeBlockFirstLines.push(codeBlockFirstLine); } })); exportPDF(el, plugin, codeBlockFirstLines, codeBlockSections); return; } let title = ""; let highLightLines = []; if (codeBlockFirstLine.match(titleRegExp) != null) { title = codeBlockFirstLine.match(titleRegExp)[1]; } if (codeBlockFirstLine.match(highLightLinesRegExp) != null) { let highLightLinesInfo = codeBlockFirstLine.match(highLightLinesRegExp)[1]; highLightLines = analyseHighLightLines(highLightLinesInfo); } let isCollapse = false; if (foldRegExp.test(codeBlockFirstLine)) { isCollapse = true; } const pre = codeElm.parentElement; const div = pre.parentElement; const contentList = codeElm.textContent.split(LINE_SPLIT_MARK); const lineSize = codeBlock.lineEnd - codeBlock.lineStart - 1; const cbMeta = { langName: lang, lineSize, pre, code: codeElm, title, isCollapse, div, contentList, highLightLines }; const { showLineNumber } = plugin.settings; addCodeTitleWrapper(plugin, pre, cbMeta); addCodeTitle(plugin, pre, cbMeta); if (showLineNumber) { addLineNumber(plugin, cbMeta); } addLineHighLight(plugin, pre, cbMeta); resizeNumWrapAndHLWrap(el, context); }); } function createElement(tagName, defaultClassName) { const element = document.createElement(tagName); if (defaultClassName) { element.className = defaultClassName; } return element; } function addCodeTitleWrapper(plugin, preElm, cbMeta) { preElm.style.setProperty("position", "relative", "important"); preElm.style.setProperty("padding-top", CB_PADDING_TOP, "important"); let wrapper = document.createElement("pre"); if (cbMeta.isCollapse) { wrapper.setAttribute("closed", ""); } wrapper.className = "obsidian-embedded-code-title__code-block-title"; wrapper.style.backgroundColor = plugin.settings.titleBackgroundColor || "#00000020"; let collapser = createElement("div", "collapser"); let handle = createElement("div", "handle"); collapser.appendChild(handle); wrapper.appendChild(collapser); wrapper.addEventListener("click", function() { if (wrapper.hasAttribute("closed")) { wrapper.removeAttribute("closed"); } else { wrapper.setAttribute("closed", ""); } }); preElm.appendChild(wrapper); } function addCodeTitle(plugin, preElm, cbMeta) { let wrapper = preElm.querySelector(".obsidian-embedded-code-title__code-block-title"); let titleElm = document.createElement("div"); titleElm.className = "title"; titleElm.appendText(cbMeta.title); wrapper.appendChild(titleElm); if (plugin.settings.titleFontColor) { titleElm.style.setProperty("color", plugin.settings.titleFontColor, "important"); } if (plugin.settings.showLangNameInTopRight) { let langName = document.createElement("div"); let langNameString = cbMeta.langName; langNameString = langNameString[0].toUpperCase() + langNameString.slice(1); langName.appendText(langNameString); langName.className = "langName"; wrapper.appendChild(langName); } preElm.prepend(wrapper); } function addLineNumber(plugin, cbMeta) { const { lineSize, pre, div } = cbMeta; div.classList.add("code-block-wrap"); const lineNumber = createElement("span", "code-block-linenum-wrap"); lineNumber.style.top = CB_PADDING_TOP; Array.from({ length: lineSize }, (v, k) => k).forEach((i) => { const singleLine = createElement("span", "code-block-linenum"); lineNumber.appendChild(singleLine); }); if (plugin.settings.showDividingLine) { lineNumber.style.borderRight = "1px currentColor solid"; } pre.appendChild(lineNumber); pre.classList.add("code-block-pre__has-linenum"); } function addLineHighLight(plugin, preElm, cbMeta) { if (cbMeta.highLightLines.length == 0) return; let highLightWrap = document.createElement("pre"); highLightWrap.className = "code-block-highlight-wrap"; for (let i = 0; i < cbMeta.lineSize; i++) { const singleLine = createElement("span", "code-block-highlight"); if (cbMeta.highLightLines.contains(i + 1)) { singleLine.style.backgroundColor = plugin.settings.highLightColor || "#2d82cc20"; } highLightWrap.appendChild(singleLine); } preElm.appendChild(highLightWrap); } function analyseHighLightLines(str) { str = str.replace(/\s*/g, ""); const result = []; let strs = str.split(","); strs.forEach((it) => { if (/\w+-\w+/.test(it)) { let left = Number(it.split("-")[0]); let right = Number(it.split("-")[1]); for (let i = left; i <= right; i++) { result.push(i); } } else { result.push(Number(it)); } }); return result; } function resizeNumWrapAndHLWrap(el, context) { setTimeout(function() { return __async(this, null, function* () { let codeBlockEl = el.querySelector("pre > code"); if (!codeBlockEl) return; let numWrap = el.querySelector(".code-block-linenum-wrap"); let highWrap = el.querySelector(".code-block-highlight-wrap"); let codeBlockInfo = context.getSectionInfo(codeBlockEl); let view; let codeBlockLineNum; let lineStart = 0; let lineEnd = 0; if (codeBlockInfo) { view = app.workspace.getActiveViewOfType(import_obsidian.MarkdownView); codeBlockLineNum = codeBlockInfo.lineEnd - codeBlockInfo.lineStart - 1; } else { return; } let span = createElement("span"); for (let i = 0; i < codeBlockLineNum; i++) { let oneLineText; if (view) { oneLineText = view.editor.getLine(codeBlockInfo.lineStart + i + 1); } else { } span.innerHTML = oneLineText || "0"; codeBlockEl.appendChild(span); span.style.display = "block"; let lineHeight = span.getBoundingClientRect().height + "px"; let numOneLine = numWrap ? numWrap.childNodes[i] : null; let hlOneLine = highWrap ? highWrap.childNodes[i] : null; if (numOneLine) numOneLine.style.height = lineHeight; if (hlOneLine) hlOneLine.style.height = lineHeight; span.remove(); } }); }, 100); } function exportPDF(el, plugin, codeBlockFirstLines, codeBlockSections) { let codeBlocks = el.querySelectorAll("pre > code"); codeBlocks.forEach((codeElm, key) => { let langName = "", title = "", highLightLines = []; codeElm.classList.forEach((value) => { if (LANG_REG.test(value)) { langName = value.replace("language-", ""); return; } }); if (codeBlockFirstLines[key].match(titleRegExp) != null) { title = codeBlockFirstLines[key].match(titleRegExp)[1]; } if (codeBlockFirstLines[key].match(highLightLinesRegExp) != null) { let highLightLinesInfo = codeBlockFirstLines[key].match(highLightLinesRegExp)[1]; highLightLines = analyseHighLightLines(highLightLinesInfo); } let lineSize = codeBlockSections[key].position.end.line - codeBlockSections[key].position.start.line - 1; let cbMeta = { langName, lineSize, pre: codeElm.parentElement, code: codeElm, title, isCollapse: false, div: codeElm.parentElement.parentElement, contentList: [], highLightLines }; addCodeTitleWrapper(plugin, codeElm.parentElement, cbMeta); addCodeTitle(plugin, cbMeta.pre, cbMeta); if (plugin.settings.showLineNumber) { addLineNumber(plugin, cbMeta); } addLineHighLight(plugin, cbMeta.pre, cbMeta); }); } //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgbGlua1N5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBBcHAsIEVkaXRvciwgTWFya2Rvd25WaWV3LCBNb2RhbCwgTm90aWNlLCBQbHVnaW4sIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcsIE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIE1lbnUsIFNldHRpbmdUYWIsIFRBYnN0cmFjdEZpbGUsIFRGaWxlLCBTZWN0aW9uQ2FjaGUsIFZhdWx0IH0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHsganNvbiB9IGZyb20gJ3N0cmVhbS9jb25zdW1lcnMnO1xuXG5jb25zdCBERUZBVUxUX0xBTkdfQVRUUiA9ICdsYW5ndWFnZS10ZXh0J1xuY29uc3QgREVGQVVMVF9MQU5HID0gJydcbmNvbnN0IExBTkdfUkVHID0gL15sYW5ndWFnZS0vXG5jb25zdCBMSU5FX1NQTElUX01BUksgPSAnXFxuJ1xuXG5jb25zdCB0aXRsZVJlZ0V4cCA9IC9USTpcIihbXlwiXSopXCIvaVxuY29uc3QgaGlnaExpZ2h0TGluZXNSZWdFeHAgPSAvSEw6XCIoW15cIl0qKVwiL2lcbmNvbnN0IGZvbGRSZWdFeHAgPSAvXCJGT0xEXCIvaVxuXG5jb25zdCBDQl9QQURESU5HX1RPUCA9IFwiMzVweFwiIC8vIFx1NEVFM1x1NzgwMVx1NTc1N1x1NEUwQVx1OEZCOVx1OERERFxuXG5pbnRlcmZhY2UgU2V0dGluZ3Mge1xuXHRzdWJzdGl0dXRpb25Ub2tlbkZvclNwYWNlOiBzdHJpbmc7XG5cdHRpdGxlQmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XG5cdHRpdGxlRm9udENvbG9yOiBzdHJpbmc7XG5cdGhpZ2hMaWdodENvbG9yOiBzdHJpbmc7XG5cblx0ZXhjbHVkZUxhbmdzOiBzdHJpbmdbXTsgLy8gXHU5NzAwXHU4OTgxXHU2MzkyXHU5NjY0XHU3Njg0XHU4QkVEXHU4QTAwXG5cblx0c2hvd0xpbmVOdW1iZXI6IGJvb2xlYW47IC8vIFx1NjYzRVx1NzkzQVx1ODg0Q1x1NTNGN1xuXHRzaG93RGl2aWRpbmdMaW5lOiBib29sZWFuO1xuXHRzaG93TGFuZ05hbWVJblRvcFJpZ2h0OiBib29sZWFuO1xufVxuXG5jb25zdCBERUZBVUxUX1NFVFRJTkdTOiBTZXR0aW5ncyA9IHtcblx0c3Vic3RpdHV0aW9uVG9rZW5Gb3JTcGFjZTogdW5kZWZpbmVkLFxuXHR0aXRsZUJhY2tncm91bmRDb2xvcjogXCIjMDAwMDAwMjBcIixcblx0dGl0bGVGb250Q29sb3I6IHVuZGVmaW5lZCxcblx0aGlnaExpZ2h0Q29sb3I6IFwiIzJkODJjYzIwXCIsXG5cblx0ZXhjbHVkZUxhbmdzOiBbXSxcblxuXHRzaG93TGluZU51bWJlcjogdHJ1ZSxcblx0c2hvd0RpdmlkaW5nTGluZTogZmFsc2UsXG5cdHNob3dMYW5nTmFtZUluVG9wUmlnaHQ6IHRydWVcbn07XG5cbmludGVyZmFjZSBDb2RlQmxvY2tNZXRhIHtcblx0Ly8gTGFuZ3VhZ2UgbmFtZVxuXHRsYW5nTmFtZTogc3RyaW5nO1xuXG5cdC8vIENvZGUgYmxvY2sgdG90YWwgbGluZSBzaXplXG5cdGxpbmVTaXplOiBudW1iZXI7XG5cblx0Ly8gQ29kZSBibG9jayAncHJlJyBIVE1MRWxlbWVudFxuXHRwcmU6IEhUTUxFbGVtZW50O1xuXG5cdC8vIENvZGUgYmxvY2sgJ2NvZGUnIEhUTUxFbGVtZW50XG5cdGNvZGU6IEhUTUxFbGVtZW50O1xuXG5cdHRpdGxlOiBzdHJpbmc7IC8vIFx1NEVFM1x1NzgwMVx1NTc1N1x1NjgwN1x1OTg5OFxuXHRpc0NvbGxhcHNlOmJvb2xlYW47IC8vIFx1NjYyRlx1NTQyNlx1OUVEOFx1OEJBNFx1NjI5OFx1NTNFMFxuXG5cdC8vIENvZGUgYmxvY2sgd3JhcCBkaXZcblx0ZGl2OiBIVE1MRWxlbWVudDtcblx0Y29udGVudExpc3Q6IHN0cmluZ1tdO1xuXHRoaWdoTGlnaHRMaW5lczogbnVtYmVyW107XG59XG5cbi8vIFJlZmVyIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2phL2RvY3MvV2ViL0phdmFTY3JpcHQvR3VpZGUvUmVndWxhcl9FeHByZXNzaW9ucyNlc2NhcGluZ1xuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcblx0cmV0dXJuIHN0ci5yZXBsYWNlKC9bLiorP149IToke30oKXxbXFxdXFwvXFxcXF0vZywgXCJcXFxcJCZcIik7IC8vIFx1NEUzQVx1NzI3OVx1NkI4QVx1N0IyNlx1NTNGN1x1NTJBMFx1NEUwQVx1OEY2Q1x1NEU0OVx1N0IyNlx1NTNGN1wiXFxcIlxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCZXR0ZXJDb2RlQmxvY2sgZXh0ZW5kcyBQbHVnaW4ge1xuXHRzZXR0aW5nczogU2V0dGluZ3M7XG5cblx0YXN5bmMgb25sb2FkKCkge1xuXHRcdGNvbnNvbGUubG9nKFwiTG9hZGluZyBCZXR0ZXIgQ29kZSBCbG9jayBQbHVnaW5cIik7XG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IEJldHRlckNvZGVCbG9ja1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXHRcdHRoaXMucmVnaXN0ZXJNYXJrZG93blBvc3RQcm9jZXNzb3IoKGVsLCBjdHgpID0+IHtcblx0XHRcdEJldHRlckNvZGVCbG9ja3MoZWwsIGN0eCwgdGhpcylcblx0XHRcdGFwcC53b3Jrc3BhY2Uub24oJ3Jlc2l6ZScsICgpID0+IHtcblx0XHRcdFx0cmVzaXplTnVtV3JhcEFuZEhMV3JhcChlbCwgY3R4KVxuXHRcdFx0fSlcblx0XHR9KVxuXG5cdH1cblxuXHRvbnVubG9hZCAoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1VubG9hZGluZyBCZXR0ZXIgQ29kZSBCbG9jayBQbHVnaW4nKTtcblx0fVxuXHRcblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xuXHR9XG5cdFxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKSB7XG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblx0fVxufVxuXG5jbGFzcyBCZXR0ZXJDb2RlQmxvY2tUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblx0cGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2s7XG4gIFxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2spIHtcblx0ICBzdXBlcihhcHAsIHBsdWdpbik7XG5cdCAgdGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cbiAgXG5cdGRpc3BsYXkoKTogdm9pZCB7XG5cdCAgbGV0IHsgY29udGFpbmVyRWwgfSA9IHRoaXM7XG4gIFxuXHQgIGNvbnRhaW5lckVsLmVtcHR5KCk7XG5cdFxuXHQgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiRXhjbHVkZSBsYW5ndWFnZSBsaXN0XCIpXG5cdFx0LnNldERlc2MoXCJUaXRsZSBhbmQgbGluZSBudW1iZXJzIGRvIG5vdCBhcHBseSBpbiB0aGVzZSBsYW5ndWFnZXMsIHNlcGFyYXRlIGJ5IGAsYFwiKVxuXHRcdC5hZGRUZXh0KHRleHQgPT4gdGV4dC5zZXRQbGFjZWhvbGRlcignbGlrZSB0b2RvaXN0LG90aGVyLC4uLicpXG5cdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVMYW5ncy5qb2luKCcsJykpXG5cdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUxhbmdzID0gdmFsdWUuc3BsaXQoJywnKTtcblx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdH0pXG5cdFx0KVxuICBcblx0ICBuZXcgU2V0dGluZyhjb250YWluZXJFbCkuc2V0TmFtZShcIkZvbnQgY29sb3Igb2YgdGl0bGVcIikuYWRkVGV4dCgodGMpID0+XG5cdFx0dGNcblx0XHQgIC5zZXRQbGFjZWhvbGRlcihcIkVudGVyIGEgY29sb3JcIilcblx0XHQgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy50aXRsZUZvbnRDb2xvcilcblx0XHQgIC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnRpdGxlRm9udENvbG9yID0gdmFsdWU7XG5cdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHQgIH0pXG5cdCAgKTtcbiAgXG5cdCAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoXCJCYWNrZ3JvdW5kIGNvbG9yIG9mIHRpdGxlXCIpXG5cdFx0LmFkZFRleHQoKHRjKSA9PlxuXHRcdCAgdGNcblx0XHRcdC5zZXRQbGFjZWhvbGRlcihcIiMwMDAwMDAyMFwiKVxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnRpdGxlQmFja2dyb3VuZENvbG9yKVxuXHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0ICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50aXRsZUJhY2tncm91bmRDb2xvciA9IHZhbHVlO1xuXHRcdFx0ICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiSGlnaExpZ2h0IENvbG9yXCIpXG5cdFx0LmFkZFRleHQoKHRjKSA9PlxuXHRcdCAgdGNcblx0XHRcdC5zZXRQbGFjZWhvbGRlcihcIiMyZDgyY2MyMFwiKVxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmhpZ2hMaWdodENvbG9yKVxuXHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0ICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5oaWdoTGlnaHRDb2xvciA9IHZhbHVlO1xuXHRcdFx0ICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiU2hvdyBsaW5lIG51bWJlclwiKVxuXHRcdC5hZGRUb2dnbGUoKHRjKSA9PiBcblx0XHR0Yy5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93TGluZU51bWJlcilcblx0XHQub25DaGFuZ2UoYXN5bmModmFsdWUpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dMaW5lTnVtYmVyID0gdmFsdWU7XG5cdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHR9KVxuXHRcdClcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiU2hvdyBkaXZpZGluZyBsaW5lXCIpXG5cdFx0LmFkZFRvZ2dsZSgodGMpID0+XG5cdFx0dGMuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd0RpdmlkaW5nTGluZSlcblx0XHQub25DaGFuZ2UoYXN5bmModmFsdWUpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEaXZpZGluZ0xpbmUgPSB2YWx1ZTtcblx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdH0pXG5cdFx0KVxuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoXCJTaG93IGxhbmd1YWdlIG5hbWUgaW4gdGhlIHRvcCByaWdodFwiKVxuXHRcdC5hZGRUb2dnbGUoKHRjKSA9PlxuXHRcdHRjLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dMYW5nTmFtZUluVG9wUmlnaHQpXG5cdFx0Lm9uQ2hhbmdlKGFzeW5jKHZhbHVlKSA9PiB7XG5cdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93TGFuZ05hbWVJblRvcFJpZ2h0ID0gdmFsdWU7XG5cdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHR9KVxuXHRcdClcblx0fVxuICB9XG5cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIEJldHRlckNvZGVCbG9ja3MoZWw6IEhUTUxFbGVtZW50LCBjb250ZXh0OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LCBwbHVnaW46IEJldHRlckNvZGVCbG9jaykge1xuXHRjb25zdCBzZXR0aW5ncyA9IHBsdWdpbi5zZXR0aW5nc1xuXHRjb25zdCBjb2RlRWxtOiBIVE1MRWxlbWVudCA9IGVsLnF1ZXJ5U2VsZWN0b3IoJ3ByZSA+IGNvZGUnKVxuXHQvLyBvbmx5IGNoYW5nZSBwcmU+Y29kZVxuXHRpZiAoIWNvZGVFbG0pIHsgcmV0dXJuIH1cblxuXHRsZXQgbGFuZyA9IERFRkFVTFRfTEFOR1xuXHQvLyByZXR1cm4gd2hlbiBsYW5nIGlzIGluIGV4Y2x1ZGUgbGlzdFxuXHRpZiAocGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVMYW5ncy5zb21lKGVMYW5nTmFtZSA9PiBjb2RlRWxtLmNsYXNzTGlzdC5jb250YWlucyhgbGFuZ3VhZ2UtJHtlTGFuZ05hbWV9YCkpKSB7XG5cdCAgcmV0dXJuXG5cdH1cblx0XG5cdGNvZGVFbG0uY2xhc3NMaXN0LmZvckVhY2goKHZhbHVlLCBrZXksIHBhcmVudCkgPT4ge1xuXHQgIGlmIChMQU5HX1JFRy50ZXN0KHZhbHVlKSkge1xuXHRcdGxhbmcgPSB2YWx1ZS5yZXBsYWNlKCdsYW5ndWFnZS0nLCAnJylcblx0XHRyZXR1cm5cblx0ICB9XG5cdH0pXG5cblx0Ly8gaWYgdGhlIGNvZGUgYmxvY2sgaXMgbm90IGRlc2NyaWJlZCwgcmV0dXJuXG5cdGlmKGxhbmcgPT0gREVGQVVMVF9MQU5HKSB7XG5cdFx0cmV0dXJuXG5cdH1cblxuXHRsZXQgY29kZUJsb2NrID0gY29udGV4dC5nZXRTZWN0aW9uSW5mbyhjb2RlRWxtKVxuXHRsZXQgY29kZUJsb2NrRmlyc3RMaW5lID0gXCJcIlxuXG5cdGlmKGNvZGVCbG9jaykge1xuXHRcdGxldCB2aWV3ID0gYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldylcblx0XHRjb2RlQmxvY2tGaXJzdExpbmUgPSB2aWV3LmVkaXRvci5nZXRMaW5lKGNvZGVCbG9jay5saW5lU3RhcnQpXG5cdH0gZWxzZSB7IFxuXHRcdGxldCBmaWxlID0gYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChjb250ZXh0LnNvdXJjZVBhdGgpXG5cdFx0bGV0IGNhY2hlID0gYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0Q2FjaGUoY29udGV4dC5zb3VyY2VQYXRoKVxuXHRcdGxldCBmaWxlQ29udGVudCA9IGF3YWl0IGFwcC52YXVsdC5jYWNoZWRSZWFkKDxURmlsZT4gZmlsZSlcblx0XHRsZXQgZmlsZUNvbnRlbnRMaW5lcyA9IGZpbGVDb250ZW50LnNwbGl0KC9cXG4vZylcblxuXHRcdGxldCBjb2RlQmxvY2tGaXJzdExpbmVzOiBzdHJpbmdbXSA9IFtdXG5cdFx0bGV0IGNvZGVCbG9ja1NlY3Rpb25zOiBTZWN0aW9uQ2FjaGVbXSA9IFtdXG5cblx0XHRjYWNoZS5zZWN0aW9ucz8uZm9yRWFjaChhc3luYyBlbGVtZW50ID0+IHtcblx0XHRcdGlmKGVsZW1lbnQudHlwZSA9PSBcImNvZGVcIikge1xuXHRcdFx0XHRsZXQgbGluZVN0YXJ0ID0gZWxlbWVudC5wb3NpdGlvbi5zdGFydC5saW5lXG5cdFx0XHRcdGNvZGVCbG9ja0ZpcnN0TGluZSA9IGZpbGVDb250ZW50TGluZXNbbGluZVN0YXJ0XVxuXHRcdFx0XHRjb2RlQmxvY2tTZWN0aW9ucy5wdXNoKGVsZW1lbnQpXG5cdFx0XHRcdGNvZGVCbG9ja0ZpcnN0TGluZXMucHVzaChjb2RlQmxvY2tGaXJzdExpbmUpXG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0ZXhwb3J0UERGKGVsLCBwbHVnaW4sIGNvZGVCbG9ja0ZpcnN0TGluZXMsIGNvZGVCbG9ja1NlY3Rpb25zKVxuXHRcdHJldHVyblxuXHR9XG5cblx0bGV0IHRpdGxlOiBzdHJpbmcgPSBcIlwiXG5cdGxldCBoaWdoTGlnaHRMaW5lczogbnVtYmVyW10gPSBbXVxuXHRpZihjb2RlQmxvY2tGaXJzdExpbmUubWF0Y2godGl0bGVSZWdFeHApICE9IG51bGwpIHtcblx0XHR0aXRsZSA9IGNvZGVCbG9ja0ZpcnN0TGluZS5tYXRjaCh0aXRsZVJlZ0V4cClbMV1cblx0fVxuXHRpZihjb2RlQmxvY2tGaXJzdExpbmUubWF0Y2goaGlnaExpZ2h0TGluZXNSZWdFeHApICE9IG51bGwpIHtcblx0XHRsZXQgaGlnaExpZ2h0TGluZXNJbmZvID0gY29kZUJsb2NrRmlyc3RMaW5lLm1hdGNoKGhpZ2hMaWdodExpbmVzUmVnRXhwKVsxXVxuXHRcdGhpZ2hMaWdodExpbmVzID0gYW5hbHlzZUhpZ2hMaWdodExpbmVzKGhpZ2hMaWdodExpbmVzSW5mbylcblx0fVxuXG5cdGxldCBpc0NvbGxhcHNlID0gZmFsc2U7XG5cdGlmKGZvbGRSZWdFeHAudGVzdChjb2RlQmxvY2tGaXJzdExpbmUpKSB7XG5cdFx0aXNDb2xsYXBzZSA9IHRydWVcblx0fVxuXG5cdGNvbnN0IHByZSA9IGNvZGVFbG0ucGFyZW50RWxlbWVudCAvLyBjb2RlLWJsb2NrLXByZV9faGFzLWxpbmVudW1cblx0Y29uc3QgZGl2ID0gcHJlLnBhcmVudEVsZW1lbnQgLy8gY2xhc3MgY29kZS1ibG9jay13cmFwXG5cblx0LyogY29uc3QgeyBsaW5lU3RhcnQsIGxpbmVFbmQgfSA9IGN0eC5nZXRTZWN0aW9uSW5mbyhlbClcblx0Y29uc3QgbGluZVNpemUgPSBsaW5lRW5kIC0gbGluZVN0YXJ0IC0gMSAqL1xuXHRjb25zdCBjb250ZW50TGlzdDogc3RyaW5nW10gPSBjb2RlRWxtLnRleHRDb250ZW50LnNwbGl0KExJTkVfU1BMSVRfTUFSSylcblx0Ly8gY29uc3QgbGluZVNpemUgPSBjb250ZW50TGlzdC5sZW5ndGggLSAxXG5cdGNvbnN0IGxpbmVTaXplID0gY29kZUJsb2NrLmxpbmVFbmQgLSBjb2RlQmxvY2subGluZVN0YXJ0IC0gMVxuXG5cdGNvbnN0IGNiTWV0YSA9IHsgbGFuZ05hbWU6IGxhbmcsIGxpbmVTaXplLCBwcmUsIGNvZGU6IGNvZGVFbG0sIHRpdGxlLCBpc0NvbGxhcHNlLCBkaXYsIGNvbnRlbnRMaXN0LCBoaWdoTGlnaHRMaW5lc31cblxuXHRjb25zdCB7c2hvd0xpbmVOdW1iZXJ9ID0gcGx1Z2luLnNldHRpbmdzXG5cblx0YWRkQ29kZVRpdGxlV3JhcHBlcihwbHVnaW4sIHByZSwgY2JNZXRhKVxuXHQvL2FkZEljb25Ub1RpdGxlKHBsdWdpbiwgcHJlLCBjYk1ldGEpXG5cdGFkZENvZGVUaXRsZShwbHVnaW4sIHByZSwgY2JNZXRhKTtcblxuXHQvLyBhZGQgbGluZSBudW1iZXJcblx0aWYgKHNob3dMaW5lTnVtYmVyKSB7XG5cdFx0YWRkTGluZU51bWJlcihwbHVnaW4sIGNiTWV0YSlcblx0fVxuXG5cdGFkZExpbmVIaWdoTGlnaHQocGx1Z2luLCBwcmUsIGNiTWV0YSlcblxuXHRyZXNpemVOdW1XcmFwQW5kSExXcmFwKGVsLGNvbnRleHQpIC8vIFx1OEMwM1x1NzUyOFx1NEUwMFx1NkIyMVx1NEVFNVx1ODlFM1x1NTFCM1x1NjdEMFx1NEU5Qlx1NjVGNlx1NTAxOVx1NjI1M1x1NUYwMFx1NjU4N1x1NEVGNlx1ODg0Q1x1OUFEOFx1NjcyQVx1ODhBQlx1OTFDRFx1OEJCRVx1OUFEOFx1NUVBNlxufVxuXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50ICh0YWdOYW1lOiBzdHJpbmcsIGRlZmF1bHRDbGFzc05hbWU/OiBzdHJpbmcpIHtcblx0Y29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSlcblx0aWYgKGRlZmF1bHRDbGFzc05hbWUpIHtcblx0ICBlbGVtZW50LmNsYXNzTmFtZSA9IGRlZmF1bHRDbGFzc05hbWVcblx0fVxuXHRyZXR1cm4gZWxlbWVudFxufVxuXG5mdW5jdGlvbiBhZGRDb2RlVGl0bGVXcmFwcGVyKHBsdWdpbjogQmV0dGVyQ29kZUJsb2NrLCBwcmVFbG06IEhUTUxFbGVtZW50LCBjYk1ldGE6IENvZGVCbG9ja01ldGEpIHtcblx0cHJlRWxtLnN0eWxlLnNldFByb3BlcnR5KFwicG9zaXRpb25cIiwgXCJyZWxhdGl2ZVwiLCBcImltcG9ydGFudFwiKTtcblx0cHJlRWxtLnN0eWxlLnNldFByb3BlcnR5KFwicGFkZGluZy10b3BcIiwgQ0JfUEFERElOR19UT1AsIFwiaW1wb3J0YW50XCIpO1xuXG5cdGxldCB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInByZVwiKVxuXHRpZihjYk1ldGEuaXNDb2xsYXBzZSkge1xuXHRcdHdyYXBwZXIuc2V0QXR0cmlidXRlKFwiY2xvc2VkXCIsXCJcIilcblx0fVxuXHR3cmFwcGVyLmNsYXNzTmFtZSA9IFwib2JzaWRpYW4tZW1iZWRkZWQtY29kZS10aXRsZV9fY29kZS1ibG9jay10aXRsZVwiXG5cblx0d3JhcHBlci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBwbHVnaW4uc2V0dGluZ3MudGl0bGVCYWNrZ3JvdW5kQ29sb3IgfHwgXCIjMDAwMDAwMjBcIjtcblxuXHRsZXQgY29sbGFwc2VyID0gY3JlYXRlRWxlbWVudChcImRpdlwiLFwiY29sbGFwc2VyXCIpXG5cdGxldCBoYW5kbGUgPSBjcmVhdGVFbGVtZW50KFwiZGl2XCIsIFwiaGFuZGxlXCIpXG5cdGNvbGxhcHNlci5hcHBlbmRDaGlsZChoYW5kbGUpXG5cdHdyYXBwZXIuYXBwZW5kQ2hpbGQoY29sbGFwc2VyKVxuXG5cdHdyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGZ1bmN0aW9uKHRoaXM6IGFueSkge1xuXHRcdGlmKHdyYXBwZXIuaGFzQXR0cmlidXRlKFwiY2xvc2VkXCIpKXtcblx0XHRcdHdyYXBwZXIucmVtb3ZlQXR0cmlidXRlKFwiY2xvc2VkXCIpXG5cdFx0fSBlbHNlIHtcblx0XHRcdHdyYXBwZXIuc2V0QXR0cmlidXRlKFwiY2xvc2VkXCIsJycpXG5cdFx0fVxuXHR9KVxuXG5cdHByZUVsbS5hcHBlbmRDaGlsZCh3cmFwcGVyKVxufVxuXG5mdW5jdGlvbiBhZGRDb2RlVGl0bGUgKHBsdWdpbjogQmV0dGVyQ29kZUJsb2NrLCBwcmVFbG06IEhUTUxFbGVtZW50LCBjYk1ldGE6IENvZGVCbG9ja01ldGEpIHtcblx0bGV0IHdyYXBwZXIgPSBwcmVFbG0ucXVlcnlTZWxlY3RvcihcIi5vYnNpZGlhbi1lbWJlZGRlZC1jb2RlLXRpdGxlX19jb2RlLWJsb2NrLXRpdGxlXCIpXG5cblx0bGV0IHRpdGxlRWxtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKVxuXHR0aXRsZUVsbS5jbGFzc05hbWUgPSBcInRpdGxlXCJcblxuXHR0aXRsZUVsbS5hcHBlbmRUZXh0KGNiTWV0YS50aXRsZSlcblx0d3JhcHBlci5hcHBlbmRDaGlsZCh0aXRsZUVsbSlcblxuXHRpZihwbHVnaW4uc2V0dGluZ3MudGl0bGVGb250Q29sb3IpIHtcblx0XHR0aXRsZUVsbS5zdHlsZS5zZXRQcm9wZXJ0eShcImNvbG9yXCIsIHBsdWdpbi5zZXR0aW5ncy50aXRsZUZvbnRDb2xvciwgXCJpbXBvcnRhbnRcIilcblx0fVxuXHRcblx0aWYocGx1Z2luLnNldHRpbmdzLnNob3dMYW5nTmFtZUluVG9wUmlnaHQpIHtcblx0XHRsZXQgbGFuZ05hbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpOyAvLyBcdTU3MjhcdTUzRjNcdTRGQTdcdTZERkJcdTUyQTBcdTRFRTNcdTc4MDFcdTdDN0JcdTU3OEJcblx0XHRsZXQgbGFuZ05hbWVTdHJpbmcgPSBjYk1ldGEubGFuZ05hbWVcblx0XHRsYW5nTmFtZVN0cmluZyA9IGxhbmdOYW1lU3RyaW5nWzBdLnRvVXBwZXJDYXNlKCkgKyBsYW5nTmFtZVN0cmluZy5zbGljZSgxKSAvLyBcdTk5OTZcdTVCNTdcdTZCQ0RcdTU5MjdcdTUxOTlcblx0XHRsYW5nTmFtZS5hcHBlbmRUZXh0KGxhbmdOYW1lU3RyaW5nKTtcblx0XHRsYW5nTmFtZS5jbGFzc05hbWUgPSBcImxhbmdOYW1lXCI7XG5cdFx0d3JhcHBlci5hcHBlbmRDaGlsZChsYW5nTmFtZSk7XG5cdH1cblxuXHRwcmVFbG0ucHJlcGVuZCh3cmFwcGVyKTtcblxufVxuXG5mdW5jdGlvbiBhZGRMaW5lTnVtYmVyIChwbHVnaW46IEJldHRlckNvZGVCbG9jaywgY2JNZXRhOiBDb2RlQmxvY2tNZXRhKSB7XG5cdGNvbnN0IHsgbGluZVNpemUsIHByZSwgZGl2IH0gPSBjYk1ldGFcblx0Ly8gbGV0IGRpdiBwb3NpdGlvbjogcmVsYXRpdmU7XG5cdGRpdi5jbGFzc0xpc3QuYWRkKCdjb2RlLWJsb2NrLXdyYXAnKVxuXG5cdC8vIGNvbnN0IHsgZm9udFNpemUsIGxpbmVIZWlnaHQgfSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNiTWV0YS5jb2RlKVxuXHRjb25zdCBsaW5lTnVtYmVyID0gY3JlYXRlRWxlbWVudCgnc3BhbicsICdjb2RlLWJsb2NrLWxpbmVudW0td3JhcCcpXG5cdGxpbmVOdW1iZXIuc3R5bGUudG9wID0gQ0JfUEFERElOR19UT1A7XG5cdEFycmF5LmZyb20oeyBsZW5ndGg6IGxpbmVTaXplIH0sICh2LCBrKSA9PiBrKS5mb3JFYWNoKGkgPT4ge1xuXHQgIGNvbnN0IHNpbmdsZUxpbmUgPSBjcmVhdGVFbGVtZW50KCdzcGFuJywgJ2NvZGUtYmxvY2stbGluZW51bScpXG5cdCAgLy8gc2luZ2xlTGluZS5zdHlsZS5mb250U2l6ZSA9IGZvbnRTaXplXG5cdCAgLy8gc2luZ2xlTGluZS5zdHlsZS5saW5lSGVpZ2h0ID0gbGluZUhlaWdodFxuXHQgIGxpbmVOdW1iZXIuYXBwZW5kQ2hpbGQoc2luZ2xlTGluZSlcblx0fSlcblx0XG5cdGlmKHBsdWdpbi5zZXR0aW5ncy5zaG93RGl2aWRpbmdMaW5lKSB7XG5cdFx0bGluZU51bWJlci5zdHlsZS5ib3JkZXJSaWdodCA9IFwiMXB4IGN1cnJlbnRDb2xvciBzb2xpZFwiXG5cdH1cblxuXHRwcmUuYXBwZW5kQ2hpbGQobGluZU51bWJlcilcblx0cHJlLmNsYXNzTGlzdC5hZGQoJ2NvZGUtYmxvY2stcHJlX19oYXMtbGluZW51bScpXG59XG5cbmZ1bmN0aW9uIGFkZExpbmVIaWdoTGlnaHQocGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2ssIHByZUVsbTogSFRNTEVsZW1lbnQsIGNiTWV0YTogQ29kZUJsb2NrTWV0YSkge1xuXHRpZihjYk1ldGEuaGlnaExpZ2h0TGluZXMubGVuZ3RoID09IDApIHJldHVyblxuXG5cdGxldCBoaWdoTGlnaHRXcmFwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInByZVwiKVxuXHRoaWdoTGlnaHRXcmFwLmNsYXNzTmFtZSA9IFwiY29kZS1ibG9jay1oaWdobGlnaHQtd3JhcFwiXG5cdGZvcihsZXQgaSA9IDA7IGkgPCBjYk1ldGEubGluZVNpemU7IGkrKykge1xuXHRcdGNvbnN0IHNpbmdsZUxpbmUgPSBjcmVhdGVFbGVtZW50KFwic3BhblwiLCAnY29kZS1ibG9jay1oaWdobGlnaHQnKVxuXHRcdGlmKGNiTWV0YS5oaWdoTGlnaHRMaW5lcy5jb250YWlucyhpKzEpKSB7XG5cdFx0XHRzaW5nbGVMaW5lLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHBsdWdpbi5zZXR0aW5ncy5oaWdoTGlnaHRDb2xvciB8fCBcIiMyZDgyY2MyMFwiXG5cdFx0fVxuXHRcdGhpZ2hMaWdodFdyYXAuYXBwZW5kQ2hpbGQoc2luZ2xlTGluZSlcblx0fVxuXG5cdHByZUVsbS5hcHBlbmRDaGlsZChoaWdoTGlnaHRXcmFwKVxufVxuXG5mdW5jdGlvbiBhbmFseXNlSGlnaExpZ2h0TGluZXMoc3RyOiBzdHJpbmcpOiBudW1iZXJbXSB7XG5cdHN0ciA9IHN0ci5yZXBsYWNlKC9cXHMqL2csIFwiXCIpIC8vIFx1NTNCQlx1OTY2NFx1NUI1N1x1N0IyNlx1NEUzMlx1NEUyRFx1NjI0MFx1NjcwOVx1N0E3QVx1NjgzQ1xuXHRjb25zdCByZXN1bHQ6IG51bWJlcltdID0gW11cblxuXHRsZXQgc3RycyA9IHN0ci5zcGxpdChcIixcIilcblx0c3Rycy5mb3JFYWNoKGl0ID0+IHtcblx0XHRpZigvXFx3Ky1cXHcrLy50ZXN0KGl0KSkgeyAvLyBcdTU5ODJcdTY3OUNcdTUzMzlcdTkxNEQgMS0zIFx1OEZEOVx1NjgzN1x1NzY4NFx1NjgzQ1x1NUYwRlx1RkYwQ1x1NEY5RFx1NkIyMVx1NkRGQlx1NTJBMFx1NjU3MFx1NUI1N1xuXHRcdFx0bGV0IGxlZnQgPSBOdW1iZXIoaXQuc3BsaXQoJy0nKVswXSlcblx0XHRcdGxldCByaWdodCA9IE51bWJlcihpdC5zcGxpdCgnLScpWzFdKVxuXHRcdFx0Zm9yKGxldCBpID0gbGVmdDsgaSA8PSByaWdodDsgaSsrKSB7XG5cdFx0XHRcdHJlc3VsdC5wdXNoKGkpXG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJlc3VsdC5wdXNoKE51bWJlcihpdCkpXG5cdFx0fVxuXHR9KVxuXG5cdHJldHVybiByZXN1bHRcbn1cblxuZnVuY3Rpb24gYWRkSWNvblRvVGl0bGUocGx1Z2luOiBCZXR0ZXJDb2RlQmxvY2ssIHByZUVsbTogSFRNTEVsZW1lbnQsIGNiTWV0YTogQ29kZUJsb2NrTWV0YSkge1xuXHRsZXQgdGl0bGUgPSBwcmVFbG0ucXVlcnlTZWxlY3RvckFsbChcIi5vYnNpZGlhbi1lbWJlZGRlZC1jb2RlLXRpdGxlX19jb2RlLWJsb2NrLXRpdGxlXCIpXG5cblx0dGl0bGUuZm9yRWFjaChpdCA9PiB7XG5cdFx0bGV0IGljb25XcmFwID0gY3JlYXRlRWxlbWVudChcImRpdlwiLFwiaWNvbi13cmFwXCIpXG5cdFx0bGV0IGljb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW1nXCIpXG5cdFx0aWNvbi5zcmMgPSBcIlwiXG5cdFx0aWNvbldyYXAuYXBwZW5kQ2hpbGQoaWNvbilcblx0XHRpdC5hcHBlbmRDaGlsZChpY29uV3JhcClcblx0fSlcblx0XG59XG5cbi8vIFx1NTcyOFx1ODFFQVx1NTJBOFx1NjM2Mlx1ODg0Q1x1NjVGNlx1NUJGOVx1NjU3MFx1NUI1N1x1NTQ4Q1x1OUFEOFx1NEVBRVx1ODg0Q1x1OTFDRFx1NjVCMFx1OEJCRVx1N0Y2RVx1OUFEOFx1NUVBNlxuLy8gVGhlc2UgY29kZXMgcmVmZXIgdG8gdGhlIGh0dHBzOi8vZ2l0aHViLmNvbS9saWp5emUvb2JzaWRpYW4tYWR2YW5jZWQtY29kZWJsb2NrXG5mdW5jdGlvbiByZXNpemVOdW1XcmFwQW5kSExXcmFwKGVsOiBIVE1MRWxlbWVudCwgY29udGV4dDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCkge1xuXHRzZXRUaW1lb3V0KGFzeW5jIGZ1bmN0aW9uKCl7IC8vIFx1NUVGNlx1NjVGNjEwMFx1NkJFQlx1NzlEMlx1NEVFNVx1ODlFM1x1NTFCM1x1NjdEMFx1NEU5Qlx1NjVGNlx1NTAxOVx1NjI1M1x1NUYwMFx1NjU4N1x1NEVGNlx1ODg0Q1x1OUFEOFx1NjcyQVx1ODhBQlx1OTFDRFx1OEJCRVx1OUFEOFx1NUVBNlxuXHRcdC8vIGNvbnNvbGUubG9nKCdvbiByZXNpemUnKVxuXHRcdGxldCBjb2RlQmxvY2tFbCA6IEhUTUxFbGVtZW50ID0gZWwucXVlcnlTZWxlY3RvcigncHJlID4gY29kZScpXG5cdFx0aWYoIWNvZGVCbG9ja0VsKSByZXR1cm5cblxuXHRcdGxldCBudW1XcmFwID0gZWwucXVlcnlTZWxlY3RvcignLmNvZGUtYmxvY2stbGluZW51bS13cmFwJylcblx0XHRsZXQgaGlnaFdyYXAgPSBlbC5xdWVyeVNlbGVjdG9yKCcuY29kZS1ibG9jay1oaWdobGlnaHQtd3JhcCcpXG5cblx0XHRsZXQgY29kZUJsb2NrSW5mbyA9IGNvbnRleHQuZ2V0U2VjdGlvbkluZm8oY29kZUJsb2NrRWwpXG5cdFx0Ly8gbGV0IHZpZXcgPSBhcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KVxuXHRcdC8vIGxldCBjb2RlQmxvY2tMaW5lTnVtID0gY29kZUJsb2NrSW5mby5saW5lRW5kIC0gY29kZUJsb2NrSW5mby5saW5lU3RhcnQgLSAxIC8vIFx1OTY2NFx1NTNCQlx1OTk5Nlx1NUMzRVx1NEUyNFx1ODg0Q1xuXHRcdGxldCB2aWV3XG5cdFx0bGV0IGNvZGVCbG9ja0xpbmVOdW1cblxuXHRcdGxldCBsaW5lU3RhcnQgPSAwXG5cdFx0bGV0IGxpbmVFbmQgPSAwXG5cdFx0aWYoY29kZUJsb2NrSW5mbykge1xuXHRcdFx0dmlldyA9IGFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpXG5cdFx0XHRjb2RlQmxvY2tMaW5lTnVtID0gY29kZUJsb2NrSW5mby5saW5lRW5kIC0gY29kZUJsb2NrSW5mby5saW5lU3RhcnQgLSAxIC8vIFx1OTY2NFx1NTNCQlx1OTk5Nlx1NUMzRVx1NEUyNFx1ODg0Q1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm5cblx0XHRcdC8vIGxldCBmaWxlID0gYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChjb250ZXh0LnNvdXJjZVBhdGgpXG5cdFx0XHQvLyBsZXQgY2FjaGUgPSBhcHAubWV0YWRhdGFDYWNoZS5nZXRDYWNoZShjb250ZXh0LnNvdXJjZVBhdGgpXG5cdFxuXHRcdFx0Ly8gY2FjaGUuc2VjdGlvbnM/LmZvckVhY2goYXN5bmMgZWxlbWVudCA9PiB7XG5cdFx0XHQvLyBcdGlmKGVsZW1lbnQudHlwZSA9PSBcImNvZGVcIikge1xuXHRcdFx0Ly8gXHRcdGxpbmVTdGFydCA9IGVsZW1lbnQucG9zaXRpb24uc3RhcnQubGluZVxuXHRcdFx0Ly8gXHRcdGxpbmVFbmQgPSBlbGVtZW50LnBvc2l0aW9uLmVuZC5saW5lXG5cdFx0XHQvLyBcdFx0Y29kZUJsb2NrTGluZU51bSA9IGxpbmVFbmQgLSBsaW5lU3RhcnQgLSAxXG5cdFx0XHQvLyBcdFx0cmV0dXJuXG5cdFx0XHQvLyBcdH1cblx0XHRcdC8vIH0pO1xuXHRcdFx0Ly8gbGV0IGZpbGUgPSBhcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGNvbnRleHQuc291cmNlUGF0aClcblx0XHRcdC8vIGxldCBjYWNoZSA9IGFwcC5tZXRhZGF0YUNhY2hlLmdldENhY2hlKGNvbnRleHQuc291cmNlUGF0aClcblx0XHRcdC8vIGxldCBmaWxlQ29udGVudCA9IGF3YWl0IGFwcC52YXVsdC5jYWNoZWRSZWFkKDxURmlsZT4gZmlsZSlcblx0XHRcdC8vIGxldCBmaWxlQ29udGVudExpbmVzID0gZmlsZUNvbnRlbnQuc3BsaXQoL1xcbi9nKVxuXHRcdH1cblxuXHRcdGxldCBzcGFuID0gY3JlYXRlRWxlbWVudChcInNwYW5cIilcblxuXHRcdGZvcihsZXQgaSA9IDA7IGkgPCBjb2RlQmxvY2tMaW5lTnVtOyBpKyspIHtcblx0XHRcdGxldCBvbmVMaW5lVGV4dFxuXHRcdFx0aWYodmlldyl7XG5cdFx0XHRcdG9uZUxpbmVUZXh0ID0gdmlldy5lZGl0b3IuZ2V0TGluZShjb2RlQmxvY2tJbmZvLmxpbmVTdGFydCArIGkgKyAxKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gb25lTGluZVRleHQgPSBmaWxlQ29udGVudExpbmVzW2xpbmVTdGFydCArIDEgKyBpXVxuXHRcdFx0XHQvLyBsZXQgZmlsZSA9IGFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoY29udGV4dC5zb3VyY2VQYXRoKVxuXHRcdFx0XHQvLyBsZXQgY2FjaGUgPSBhcHAubWV0YWRhdGFDYWNoZS5nZXRDYWNoZShjb250ZXh0LnNvdXJjZVBhdGgpXG5cdFx0XHRcdC8vIGxldCBmaWxlQ29udGVudCA9IGF3YWl0IGFwcC52YXVsdC5jYWNoZWRSZWFkKDxURmlsZT4gZmlsZSlcblx0XHRcdFx0Ly8gbGV0IGZpbGVDb250ZW50TGluZXMgPSBmaWxlQ29udGVudC5zcGxpdCgvXFxuL2cpXG5cdFx0XHRcdC8vIG9uZUxpbmVUZXh0ID0gZmlsZUNvbnRlbnRMaW5lc1tjYWNoZS5zZWN0aW9uc11cblx0XHRcdH1cblx0XHRcdHNwYW4uaW5uZXJIVE1MID0gb25lTGluZVRleHQgfHwgXCIwXCJcblxuXHRcdFx0Y29kZUJsb2NrRWwuYXBwZW5kQ2hpbGQoc3Bhbilcblx0XHRcdHNwYW4uc3R5bGUuZGlzcGxheSA9ICdibG9jaydcblxuXHRcdFx0bGV0IGxpbmVIZWlnaHQgPSBzcGFuLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodCArICdweCcgLy8gXHU2RDRCXHU5MUNGXHU2NzJDXHU4ODRDXHU2NTg3XHU1QjU3XHU3Njg0XHU5QUQ4XHU1RUE2XG5cblx0XHRcdC8vIGNvbnNvbGUubG9nKGxpbmVIZWlnaHQgKyAnICAgICcgKyBzcGFuLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoKTtcblx0XHRcdFxuXHRcdFx0bGV0IG51bU9uZUxpbmUgPSBudW1XcmFwPyBudW1XcmFwLmNoaWxkTm9kZXNbaV0gYXMgSFRNTEVsZW1lbnQgOiBudWxsXG5cdFx0XHRsZXQgaGxPbmVMaW5lID0gaGlnaFdyYXA/IGhpZ2hXcmFwLmNoaWxkTm9kZXNbaV0gYXMgSFRNTEVsZW1lbnQgOiBudWxsXG5cblx0XHRcdGlmKG51bU9uZUxpbmUpIG51bU9uZUxpbmUuc3R5bGUuaGVpZ2h0ID0gbGluZUhlaWdodDtcblx0XHRcdGlmKGhsT25lTGluZSkgaGxPbmVMaW5lLnN0eWxlLmhlaWdodCA9IGxpbmVIZWlnaHQ7XG5cblx0XHRcdHNwYW4ucmVtb3ZlKCkgLy8gXHU2RDRCXHU5MUNGXHU1QjhDXHU1NDBFXHU1MjIwXHU2Mzg5XG5cdFx0fVxuXHR9LCAxMDApXG59XG5cbmZ1bmN0aW9uIGV4cG9ydFBERihlbDogSFRNTEVsZW1lbnQsIHBsdWdpbjogQmV0dGVyQ29kZUJsb2NrLCBjb2RlQmxvY2tGaXJzdExpbmVzOiBzdHJpbmdbXSwgY29kZUJsb2NrU2VjdGlvbnM6IFNlY3Rpb25DYWNoZVtdKSB7XG5cdGxldCBjb2RlQmxvY2tzID0gZWwucXVlcnlTZWxlY3RvckFsbCgncHJlID4gY29kZScpXG5cdGNvZGVCbG9ja3MuZm9yRWFjaCgoY29kZUVsbSwga2V5KSA9PiB7XG5cdFx0bGV0IGxhbmdOYW1lID0gXCJcIiwgdGl0bGUgPSBcIlwiLCBoaWdoTGlnaHRMaW5lczogbnVtYmVyW10gPSBbXVxuXHRcdGNvZGVFbG0uY2xhc3NMaXN0LmZvckVhY2godmFsdWUgPT4ge1xuXHRcdFx0aWYoTEFOR19SRUcudGVzdCh2YWx1ZSkpIHtcblx0XHRcdFx0bGFuZ05hbWUgPSB2YWx1ZS5yZXBsYWNlKCdsYW5ndWFnZS0nLCAnJylcblx0XHRcdFx0cmV0dXJuXG5cdFx0XHR9XG5cdFx0fSlcblxuXHRcdGlmKGNvZGVCbG9ja0ZpcnN0TGluZXNba2V5XS5tYXRjaCh0aXRsZVJlZ0V4cCkgIT0gbnVsbCkge1xuXHRcdFx0dGl0bGUgPSBjb2RlQmxvY2tGaXJzdExpbmVzW2tleV0ubWF0Y2godGl0bGVSZWdFeHApWzFdXG5cdFx0fVxuXHRcdGlmKGNvZGVCbG9ja0ZpcnN0TGluZXNba2V5XS5tYXRjaChoaWdoTGlnaHRMaW5lc1JlZ0V4cCkgIT0gbnVsbCkge1xuXHRcdFx0bGV0IGhpZ2hMaWdodExpbmVzSW5mbyA9IGNvZGVCbG9ja0ZpcnN0TGluZXNba2V5XS5tYXRjaChoaWdoTGlnaHRMaW5lc1JlZ0V4cClbMV1cblx0XHRcdGhpZ2hMaWdodExpbmVzID0gYW5hbHlzZUhpZ2hMaWdodExpbmVzKGhpZ2hMaWdodExpbmVzSW5mbylcblx0XHR9XG5cblx0XHRsZXQgbGluZVNpemUgPSBjb2RlQmxvY2tTZWN0aW9uc1trZXldLnBvc2l0aW9uLmVuZC5saW5lIC0gY29kZUJsb2NrU2VjdGlvbnNba2V5XS5wb3NpdGlvbi5zdGFydC5saW5lIC0gMVxuXG5cdFx0bGV0IGNiTWV0YTogQ29kZUJsb2NrTWV0YSA9IHtcblx0XHRcdGxhbmdOYW1lOiBsYW5nTmFtZSxcblx0XHRcdGxpbmVTaXplOiBsaW5lU2l6ZSxcblx0XHRcdHByZTogY29kZUVsbS5wYXJlbnRFbGVtZW50LFxuXHRcdFx0Y29kZTogY29kZUVsbSBhcyBIVE1MRWxlbWVudCxcblx0XHRcdHRpdGxlOiB0aXRsZSxcblx0XHRcdGlzQ29sbGFwc2U6IGZhbHNlLFxuXHRcdFx0ZGl2OiBjb2RlRWxtLnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudCxcblx0XHRcdGNvbnRlbnRMaXN0OiBbXSxcblx0XHRcdGhpZ2hMaWdodExpbmVzOiBoaWdoTGlnaHRMaW5lc1xuXHRcdH1cblx0XHRhZGRDb2RlVGl0bGVXcmFwcGVyKHBsdWdpbiwgY29kZUVsbS5wYXJlbnRFbGVtZW50LCBjYk1ldGEpIC8vIFx1NUJGQ1x1NTFGQVx1NTNENlx1NkQ4OFx1NEVFM1x1NzgwMVx1NTc1N1x1NjI5OFx1NTNFMFxuXHRcdGFkZENvZGVUaXRsZShwbHVnaW4sIGNiTWV0YS5wcmUsIGNiTWV0YSlcblx0XHRpZihwbHVnaW4uc2V0dGluZ3Muc2hvd0xpbmVOdW1iZXIpIHtcblx0XHRcdGFkZExpbmVOdW1iZXIocGx1Z2luLCBjYk1ldGEpXG5cdFx0fVxuXHRcdGFkZExpbmVIaWdoTGlnaHQocGx1Z2luLCBjYk1ldGEucHJlLCBjYk1ldGEpXG5cdH0pXG59Il0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBLHNCQUF1TDtBQUl2TCxJQUFNLGVBQWU7QUFDckIsSUFBTSxXQUFXO0FBQ2pCLElBQU0sa0JBQWtCO0FBRXhCLElBQU0sY0FBYztBQUNwQixJQUFNLHVCQUF1QjtBQUM3QixJQUFNLGFBQWE7QUFFbkIsSUFBTSxpQkFBaUI7QUFldkIsSUFBTSxtQkFBNkI7QUFBQSxFQUNsQywyQkFBMkI7QUFBQSxFQUMzQixzQkFBc0I7QUFBQSxFQUN0QixnQkFBZ0I7QUFBQSxFQUNoQixnQkFBZ0I7QUFBQSxFQUVoQixjQUFjO0FBQUEsRUFFZCxnQkFBZ0I7QUFBQSxFQUNoQixrQkFBa0I7QUFBQSxFQUNsQix3QkFBd0I7QUFBQTtBQThCekIsb0NBQTZDLHVCQUFPO0FBQUEsRUFHN0MsU0FBUztBQUFBO0FBQ2QsY0FBUSxJQUFJO0FBQ1osWUFBTSxLQUFLO0FBQ1gsV0FBSyxjQUFjLElBQUksbUJBQW1CLEtBQUssS0FBSztBQUNwRCxXQUFLLDhCQUE4QixDQUFDLElBQUksUUFBUTtBQUMvQyx5QkFBaUIsSUFB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