/* 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()); }); }; // src/main.ts __export(exports, { default: () => ObsidianAdvancedCodeblockPlugin }); var import_obsidian3 = __toModule(require("obsidian")); // src/postProcessor.ts var import_obsidian2 = __toModule(require("obsidian")); // src/util.ts var paramRegex = /\{.+\}|\w+/g; var braceSurroundingRegex = /^{.+}$/; // src/extendPrism.ts var import_obsidian = __toModule(require("obsidian")); // lib/prism-line-numbers.js function extendLineNumberPlugin(Prism) { if (typeof Prism === "undefined" || typeof document === "undefined") { return; } var PLUGIN_NAME = "line-numbers"; var NEW_LINE_EXP = /\n(?!$)/g; var config = Prism.plugins.lineNumbers = { getLine: function(element, number) { if (element.tagName !== "PRE" || !element.classList.contains(PLUGIN_NAME)) { return; } var lineNumberRows = element.querySelector(".line-numbers-rows"); if (!lineNumberRows) { return; } var lineNumberStart = parseInt(element.getAttribute("data-start"), 10) || 1; var lineNumberEnd = lineNumberStart + (lineNumberRows.children.length - 1); if (number < lineNumberStart) { number = lineNumberStart; } if (number > lineNumberEnd) { number = lineNumberEnd; } var lineIndex = number - lineNumberStart; return lineNumberRows.children[lineIndex]; }, resize: function(element) { resizeElements([element]); }, assumeViewportIndependence: true }; function resizeElements(elements) { elements = elements.filter(function(e) { var codeStyles = getStyles(e); var whiteSpace = codeStyles["white-space"]; return whiteSpace === "pre-wrap" || whiteSpace === "pre-line"; }); if (elements.length == 0) { return; } var infos = elements.map(function(element) { var codeElement = element.querySelector("code"); var lineNumbersWrapper = element.querySelector(".line-numbers-rows"); if (!codeElement || !lineNumbersWrapper) { return void 0; } var lineNumberSizer = element.querySelector(".line-numbers-sizer"); var codeLines = codeElement.textContent.split(NEW_LINE_EXP); if (!lineNumberSizer) { lineNumberSizer = document.createElement("span"); lineNumberSizer.className = "line-numbers-sizer"; codeElement.appendChild(lineNumberSizer); } lineNumberSizer.innerHTML = "0"; lineNumberSizer.style.display = "block"; var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height; lineNumberSizer.innerHTML = ""; return { element, lines: codeLines, lineHeights: [], oneLinerHeight, sizer: lineNumberSizer }; }).filter(Boolean); infos.forEach(function(info) { var lineNumberSizer = info.sizer; var lines = info.lines; var lineHeights = info.lineHeights; var oneLinerHeight = info.oneLinerHeight; lineHeights[lines.length - 1] = void 0; lines.forEach(function(line, index) { if (line && line.length > 1) { var e = lineNumberSizer.appendChild(document.createElement("span")); e.style.display = "block"; e.textContent = line; } else { lineHeights[index] = oneLinerHeight; } }); }); infos.forEach(function(info) { var lineNumberSizer = info.sizer; var lineHeights = info.lineHeights; var childIndex = 0; for (var i = 0; i < lineHeights.length; i++) { if (lineHeights[i] === void 0) { lineHeights[i] = lineNumberSizer.children[childIndex++].getBoundingClientRect().height; } } }); infos.forEach(function(info) { var lineNumberSizer = info.sizer; var wrapper = info.element.querySelector(".line-numbers-rows"); lineNumberSizer.style.display = "none"; lineNumberSizer.innerHTML = ""; info.lineHeights.forEach(function(height, lineNumber) { wrapper.children[lineNumber].style.height = height + "px"; }); }); } function getStyles(element) { if (!element) { return null; } return window.getComputedStyle ? getComputedStyle(element) : element.currentStyle || null; } Prism.hooks.add("complete", function(env) { if (!env.code) { return; } var code = env.element; var pre = code.parentNode; if (!pre || !/pre/i.test(pre.nodeName)) { return; } if (code.querySelector(".line-numbers-rows")) { return; } if (!Prism.util.isActive(code, PLUGIN_NAME)) { return; } code.classList.remove(PLUGIN_NAME); pre.classList.add(PLUGIN_NAME); var match = env.code.match(NEW_LINE_EXP); var linesNum = match ? match.length + 1 : 1; var lineNumbersWrapper; var lines = new Array(linesNum + 1).join(""); lineNumbersWrapper = document.createElement("span"); lineNumbersWrapper.setAttribute("aria-hidden", "true"); lineNumbersWrapper.className = "line-numbers-rows"; lineNumbersWrapper.innerHTML = lines; if (pre.hasAttribute("data-start")) { pre.style.counterReset = "linenumber " + (parseInt(pre.getAttribute("data-start"), 10) - 1); } env.element.appendChild(lineNumbersWrapper); resizeElements([pre]); Prism.hooks.run("line-numbers", env); }); Prism.hooks.add("line-numbers", function(env) { env.plugins = env.plugins || {}; env.plugins.lineNumbers = true; }); } // lib/prism-line-highlight.js function extendLineHighlightPlugin(Prism) { if (typeof Prism === "undefined" || typeof document === "undefined" || !document.querySelector) { return; } var LINE_NUMBERS_CLASS = "line-numbers"; var LINKABLE_LINE_NUMBERS_CLASS = "linkable-line-numbers"; var NEW_LINE_REGEX = /\n(?!$)/g; function $$(selector, container) { return Array.prototype.slice.call((container || document).querySelectorAll(selector)); } function hasClass(element, className) { return element.classList.contains(className); } function callFunction(func) { func(); } var isLineHeightRounded = function() { var res; return function() { if (typeof res === "undefined") { var d = document.createElement("div"); d.style.fontSize = "13px"; d.style.lineHeight = "1.5"; d.style.padding = "0"; d.style.border = "0"; d.innerHTML = " 
 "; document.body.appendChild(d); res = d.offsetHeight === 38; document.body.removeChild(d); } return res; }; }(); function getContentBoxTopOffset(parent, child) { var parentStyle = getComputedStyle(parent); var childStyle = getComputedStyle(child); function pxToNumber(px) { return +px.substr(0, px.length - 2); } return child.offsetTop + pxToNumber(childStyle.borderTopWidth) + pxToNumber(childStyle.paddingTop) - pxToNumber(parentStyle.paddingTop); } function isActiveFor(pre) { if (!pre || !/pre/i.test(pre.nodeName)) { return false; } if (pre.hasAttribute("data-line")) { return true; } if (pre.id && Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS)) { return true; } return false; } var scrollIntoView = true; Prism.plugins.lineHighlight = { highlightLines: function highlightLines(pre, lines, classes) { lines = typeof lines === "string" ? lines : pre.getAttribute("data-line") || ""; var ranges = lines.replace(/\s+/g, "").split(",").filter(Boolean); var offset = +pre.getAttribute("data-line-offset") || 0; var parseMethod = isLineHeightRounded() ? parseInt : parseFloat; var codeElement = pre.querySelector("code"); var lineHeight = parseMethod(getComputedStyle(codeElement).lineHeight); var hasLineNumbers = Prism.util.isActive(pre, LINE_NUMBERS_CLASS); var parentElement = hasLineNumbers ? pre : codeElement || pre; var mutateActions = []; var lineBreakMatch = codeElement.textContent.match(NEW_LINE_REGEX); var numberOfLines = lineBreakMatch ? lineBreakMatch.length + 1 : 1; var codePreOffset = !codeElement || parentElement == codeElement ? 0 : getContentBoxTopOffset(pre, codeElement); ranges.forEach(function(currentRange) { var range = currentRange.split("-"); var start2 = +range[0]; var end = +range[1] || start2; end = Math.min(numberOfLines, end); if (end < start2) return; var line = pre.querySelector('.line-highlight[data-range="' + currentRange + '"]') || document.createElement("div"); mutateActions.push(function() { line.setAttribute("aria-hidden", "true"); line.setAttribute("data-range", currentRange); line.className = (classes || "") + " line-highlight"; }); if (hasLineNumbers && Prism.plugins.lineNumbers) { var startNode = Prism.plugins.lineNumbers.getLine(pre, start2); var endNode = Prism.plugins.lineNumbers.getLine(pre, end); if (startNode) { var top = startNode.offsetTop + codePreOffset + "px"; mutateActions.push(function() { line.style.top = top; }); } if (endNode) { var height = endNode.offsetTop - startNode.offsetTop + endNode.offsetHeight + "px"; mutateActions.push(function() { line.style.height = height; }); } } else { mutateActions.push(function() { line.setAttribute("data-start", String(start2)); if (end > start2) { line.setAttribute("data-end", String(end)); } line.style.top = (start2 - offset - 1) * lineHeight + codePreOffset + "px"; line.textContent = new Array(end - start2 + 2).join(" \n"); }); } mutateActions.push(function() { line.style.width = pre.scrollWidth + "px"; }); mutateActions.push(function() { parentElement.appendChild(line); }); }); var id = pre.id; if (hasLineNumbers && Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS) && id) { if (!hasClass(pre, LINKABLE_LINE_NUMBERS_CLASS)) { mutateActions.push(function() { pre.classList.add(LINKABLE_LINE_NUMBERS_CLASS); }); } var start = parseInt(pre.getAttribute("data-start") || "1"); $$(".line-numbers-rows > span", pre).forEach(function(lineSpan, i) { var lineNumber = i + start; lineSpan.onclick = function() { var hash = id + "." + lineNumber; scrollIntoView = false; location.hash = hash; setTimeout(function() { scrollIntoView = true; }, 1); }; }); } return function() { mutateActions.forEach(callFunction); }; } }; function applyHash() { var hash = location.hash.slice(1); $$(".temporary.line-highlight").forEach(function(line) { line.parentNode.removeChild(line); }); var range = (hash.match(/\.([\d,-]+)$/) || [, ""])[1]; if (!range || document.getElementById(hash)) { return; } var id = hash.slice(0, hash.lastIndexOf(".")); var pre = document.getElementById(id); if (!pre) { return; } if (!pre.hasAttribute("data-line")) { pre.setAttribute("data-line", ""); } var mutateDom = Prism.plugins.lineHighlight.highlightLines(pre, range, "temporary "); mutateDom(); if (scrollIntoView) { document.querySelector(".temporary.line-highlight").scrollIntoView(); } } var fakeTimer = 0; Prism.hooks.add("before-sanity-check", function(env) { var pre = env.element.parentElement; if (!isActiveFor(pre)) { return; } var num = 0; $$(".line-highlight", pre).forEach(function(line) { num += line.textContent.length; line.parentNode.removeChild(line); }); if (num && /^(?: \n)+$/.test(env.code.slice(-num))) { env.code = env.code.slice(0, -num); } }); Prism.hooks.add("complete", function completeHook(env) { var pre = env.element.parentElement; if (!isActiveFor(pre)) { return; } clearTimeout(fakeTimer); var hasLineNumbers = Prism.plugins.lineNumbers; var isLineNumbersLoaded = env.plugins && env.plugins.lineNumbers; if (hasClass(pre, LINE_NUMBERS_CLASS) && hasLineNumbers && !isLineNumbersLoaded) { Prism.hooks.add("line-numbers", completeHook); } else { var mutateDom = Prism.plugins.lineHighlight.highlightLines(pre); mutateDom(); fakeTimer = setTimeout(applyHash, 1); } }); window.addEventListener("hashchange", applyHash); } // src/extendPrism.ts (0, import_obsidian.loadPrism)().then((val) => { extendLineNumberPlugin(window.Prism); extendLineHighlightPlugin(window.Prism); }); // src/postProcessor.ts function processParams(element, context, app) { var _a; const pre = element.querySelector("pre:not(.frontmatter)"); if (!pre) return null; const codeBlock = context.getSectionInfo(element); if (!codeBlock) return null; const origin = (_a = app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView)) == null ? void 0 : _a.editor.getLine(codeBlock.lineStart).slice(3); if (!origin) return null; const codeBlockInfo = origin.match(paramRegex); const params = codeBlockInfo.slice(1); if (!params.length) return null; return { pre, params }; } function onMounted(element, onAttachCallback) { const observer = new MutationObserver(function() { function isAttached(el) { if (el.parentNode === document) { return true; } else if (el.parentNode === null) { return false; } else { return isAttached(el.parentNode); } } if (isAttached(element)) { observer.disconnect(); onAttachCallback(); } }); observer.observe(document, { childList: true, subtree: true }); } function handleLineNumbers(pre, params, initHandlers) { if (!params.includes("nums")) return; pre.classList.add("line-numbers"); const initLineNumbers = () => { window.Prism.plugins.lineNumbers.resize(pre); }; initHandlers.push(initLineNumbers); } function handleLineHighlight(pre, params, initHandlers) { const lineHightlightParamIdx = params.findIndex((param) => braceSurroundingRegex.test(param)); if (lineHightlightParamIdx === -1) return; pre.dataset.line = params[lineHightlightParamIdx].slice(1, -1); const initLineHighlight = () => { window.Prism.plugins.lineHighlight.highlightLines(pre)(); }; initHandlers.push(initLineHighlight); } function commonCodeblockPostProcessor(element, context, app, plugin) { const processResult = processParams(element, context, app); if (!processResult) return; const { pre, params } = processResult; const initHandlers = []; handleLineNumbers(pre, params, initHandlers); handleLineHighlight(pre, params, initHandlers); onMounted(pre, () => { initHandlers.forEach((handler) => { handler(); }); }); plugin.registerEvent(app.workspace.on("resize", () => { initHandlers.forEach((handler) => { handler(); }); })); } // src/CM6Extensions.ts var import_view = __toModule(require("@codemirror/view")); var import_state = __toModule(require("@codemirror/state")); var import_language = __toModule(require("@codemirror/language")); var LineNumberWidget = class extends import_view.WidgetType { constructor(idx) { super(); this.idx = idx; } toDOM() { const el = document.createElement("span"); el.className = "live-preview-codeblock-line-nums"; el.textContent = "" + this.idx; return el; } }; var livePreviewCM6Extension = import_view.ViewPlugin.fromClass(class { constructor(view) { this.decorations = this.buildDecorations(view); } update(update) { if (update.docChanged || update.viewportChanged) this.decorations = this.buildDecorations(update.view); } destory() { } buildDecorations(view) { const builder = new import_state.RangeSetBuilder(); const codeblockInfo = { showLineNumbers: false, highlightLines: null }; let startLineNum; for (const { from, to } of view.visibleRanges) { try { const tree = (0, import_language.syntaxTree)(view.state); tree.iterate({ from, to, enter: ({ type, from: from2, to: to2 }) => { var _a, _b; const lineClasses = type.prop(import_language.lineClassNodeProp); if (!lineClasses) return; const classes = new Set(lineClasses.split(" ")); const isCodeblockBegin = classes.has("HyperMD-codeblock-begin"); const isCodeblockLine = classes.has("HyperMD-codeblock-bg") && !classes.has("HyperMD-codeblock-begin") && !classes.has("HyperMD-codeblock-end"); if (isCodeblockBegin) { const startLine = view.state.doc.lineAt(from2); const codeblockParams = startLine.text.match(paramRegex).slice(1); const highlightParam = (_a = codeblockParams.find((param) => braceSurroundingRegex.test(param))) == null ? void 0 : _a.slice(1, -1); startLineNum = startLine.number; codeblockInfo.showLineNumbers = false; codeblockInfo.highlightLines = null; if (codeblockParams.includes("nums")) codeblockInfo.showLineNumbers = true; if (highlightParam) codeblockInfo.highlightLines = highlightParam.replace(" ", "").split(",").flatMap((line) => { if (!+line) { const res = []; const [start, end] = line.split("-"); for (let i = +start; i <= +end; i++) { res.push(i); } return res; } return [+line]; }); } if (!isCodeblockLine) return; const currentLineNum = view.state.doc.lineAt(from2).number; if (codeblockInfo.showLineNumbers) { const deco = import_view.Decoration.widget({ widget: new LineNumberWidget(currentLineNum - startLineNum), side: -1e4 }); builder.add(from2, from2, deco); } if (codeblockInfo.highlightLines) { if (codeblockInfo.highlightLines.includes(currentLineNum - startLineNum)) { const line = view.state.doc.lineAt(from2); const deco = import_view.Decoration.line({ attributes: { class: "live-preview-codeblock-highlight" } }); if ((_b = builder.last) == null ? void 0 : _b.startSide) { deco.startSide = builder.last.startSide; deco.endSide = deco.startSide; } builder.add(line.from, line.from, deco); } } } }); } catch (error) { console.log(error); } } return builder.finish(); } }, { decorations: (v) => v.decorations }); // src/main.ts var ObsidianAdvancedCodeblockPlugin = class extends import_obsidian3.Plugin { onload() { return __async(this, null, function* () { console.log("Loading Advanced Codeblock"); this.registerEditorExtension([livePreviewCM6Extension]); this.registerMarkdownPostProcessor((element, context) => { commonCodeblockPostProcessor(element, context, this.app, this); }); }); } onunload() { } }; //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL3Bvc3RQcm9jZXNzb3IudHMiLCAic3JjL3V0aWwudHMiLCAic3JjL2V4dGVuZFByaXNtLnRzIiwgImxpYi9wcmlzbS1saW5lLW51bWJlcnMuanMiLCAibGliL3ByaXNtLWxpbmUtaGlnaGxpZ2h0LmpzIiwgInNyYy9DTTZFeHRlbnNpb25zLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBQbHVnaW4gfSBmcm9tIFwib2JzaWRpYW5cIjtcclxuaW1wb3J0IHsgY29tbW9uQ29kZWJsb2NrUG9zdFByb2Nlc3NvciB9IGZyb20gXCIuL3Bvc3RQcm9jZXNzb3JcIjtcclxuaW1wb3J0IHsgbGl2ZVByZXZpZXdDTTZFeHRlbnNpb24gfSBmcm9tICcuL0NNNkV4dGVuc2lvbnMnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgT2JzaWRpYW5BZHZhbmNlZENvZGVibG9ja1BsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblx0YXN5bmMgb25sb2FkKCkge1xyXG5cdFx0Y29uc29sZS5sb2coXCJMb2FkaW5nIEFkdmFuY2VkIENvZGVibG9ja1wiKTtcclxuXHJcblx0XHQvLyBBZGQgZnVuY3Rpb25hbGl0eSB0byBsaXZlLXByZXZpZXcgbW9kZVxyXG5cdFx0dGhpcy5yZWdpc3RlckVkaXRvckV4dGVuc2lvbihbbGl2ZVByZXZpZXdDTTZFeHRlbnNpb25dKTtcclxuXHJcblx0XHQvLyBBZGQgZnVuY3Rpb25hbGl0eSB0byBwcmV2aWV3IG1vZGVcclxuXHRcdHRoaXMucmVnaXN0ZXJNYXJrZG93blBvc3RQcm9jZXNzb3IoKGVsZW1lbnQsIGNvbnRleHQpID0+IHtcclxuXHRcdFx0Y29tbW9uQ29kZWJsb2NrUG9zdFByb2Nlc3NvcihlbGVtZW50LCBjb250ZXh0LCB0aGlzLmFwcCwgdGhpcyk7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdG9udW5sb2FkKCkge31cclxufVxyXG4iLCAiaW1wb3J0IHtcclxuXHRBcHAsXHJcblx0TWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCxcclxuXHRNYXJrZG93blZpZXcsXHJcblx0UGx1Z2luLFxyXG59IGZyb20gXCJvYnNpZGlhblwiO1xyXG5pbXBvcnQgeyBwYXJhbVJlZ2V4LCBicmFjZVN1cnJvdW5kaW5nUmVnZXggfSBmcm9tIFwiLi91dGlsXCI7XHJcbmltcG9ydCBcIi4vZXh0ZW5kUHJpc21cIjtcclxuXHJcbnR5cGUgSGFuZGxlclNldCA9ICgoKSA9PiB2b2lkKVtdO1xyXG5cclxuZnVuY3Rpb24gcHJvY2Vzc1BhcmFtcyhcclxuXHRlbGVtZW50OiBIVE1MRWxlbWVudCxcclxuXHRjb250ZXh0OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LFxyXG5cdGFwcDogQXBwXHJcbikge1xyXG5cdC8vIE9ubHkgd29ya3Mgd2l0aCBjb2RlIGJsb2NrcztcclxuXHRjb25zdCBwcmU6IEhUTUxQcmVFbGVtZW50ID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yKFwicHJlOm5vdCguZnJvbnRtYXR0ZXIpXCIpO1xyXG5cdGlmICghcHJlKSByZXR1cm4gbnVsbDtcclxuXHJcblx0Y29uc3QgY29kZUJsb2NrID0gY29udGV4dC5nZXRTZWN0aW9uSW5mbyhlbGVtZW50KTtcclxuXHRpZiAoIWNvZGVCbG9jaykgcmV0dXJuIG51bGw7XHJcblxyXG5cdGNvbnN0IG9yaWdpbiA9IGFwcC53b3Jrc3BhY2VcclxuXHRcdC5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldylcclxuXHRcdD8uZWRpdG9yLmdldExpbmUoY29kZUJsb2NrLmxpbmVTdGFydClcclxuXHRcdC5zbGljZSgzKTtcclxuXHJcblx0Ly8gbm90IHNwZWNpZnkgYW55dGhpbmcgb3Igbm8gYWN0aXZlIHZpZXdcclxuXHRpZiAoIW9yaWdpbikgcmV0dXJuIG51bGw7XHJcblxyXG5cdGNvbnN0IGNvZGVCbG9ja0luZm8gPSBvcmlnaW4ubWF0Y2gocGFyYW1SZWdleCk7XHJcblx0Y29uc3QgcGFyYW1zID0gY29kZUJsb2NrSW5mby5zbGljZSgxKTtcclxuXHJcblx0Ly8gcmV0dXJuIGlmIG5vIHBhcmFtXHJcblx0aWYgKCFwYXJhbXMubGVuZ3RoKSByZXR1cm4gbnVsbDtcclxuXHJcblx0cmV0dXJuIHsgcHJlLCBwYXJhbXMgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Nb3VudGVkKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBvbkF0dGFjaENhbGxiYWNrOiAoKSA9PiB2b2lkKSB7XHJcblx0Y29uc3Qgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihmdW5jdGlvbiAoKSB7XHJcblx0XHRmdW5jdGlvbiBpc0F0dGFjaGVkKGVsOiBIVE1MRWxlbWVudCB8IG51bGwpOiBib29sZWFuIHtcclxuXHRcdFx0aWYgKGVsLnBhcmVudE5vZGUgPT09IGRvY3VtZW50KSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH0gZWxzZSBpZiAoZWwucGFyZW50Tm9kZSA9PT0gbnVsbCkge1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRyZXR1cm4gaXNBdHRhY2hlZChlbC5wYXJlbnROb2RlIGFzIEhUTUxFbGVtZW50KTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChpc0F0dGFjaGVkKGVsZW1lbnQpKSB7XHJcblx0XHRcdG9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcclxuXHRcdFx0b25BdHRhY2hDYWxsYmFjaygpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cclxuXHRvYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LCB7XHJcblx0XHRjaGlsZExpc3Q6IHRydWUsXHJcblx0XHRzdWJ0cmVlOiB0cnVlLFxyXG5cdH0pO1xyXG59XHJcblxyXG4vLyBoYW5kbGUgbGluZSBudW1iZXJcclxuZnVuY3Rpb24gaGFuZGxlTGluZU51bWJlcnMoXHJcblx0cHJlOiBIVE1MUHJlRWxlbWVudCxcclxuXHRwYXJhbXM6IHN0cmluZ1tdLFxyXG5cdGluaXRIYW5kbGVyczogSGFuZGxlclNldCxcclxuKSB7XHJcblx0aWYgKCFwYXJhbXMuaW5jbHVkZXMoXCJudW1zXCIpKSByZXR1cm47XHJcblxyXG5cdHByZS5jbGFzc0xpc3QuYWRkKFwibGluZS1udW1iZXJzXCIpO1xyXG5cclxuXHRjb25zdCBpbml0TGluZU51bWJlcnMgPSAoKSA9PiB7XHJcblx0XHR3aW5kb3cuUHJpc20ucGx1Z2lucy5saW5lTnVtYmVycy5yZXNpemUocHJlKTtcclxuXHR9XHJcblxyXG5cdGluaXRIYW5kbGVycy5wdXNoKGluaXRMaW5lTnVtYmVycyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGhhbmRsZUxpbmVIaWdobGlnaHQoXHJcblx0cHJlOiBIVE1MUHJlRWxlbWVudCxcclxuXHRwYXJhbXM6IHN0cmluZ1tdLFxyXG5cdGluaXRIYW5kbGVyczogSGFuZGxlclNldCxcclxuKSB7XHJcblx0Y29uc3QgbGluZUhpZ2h0bGlnaHRQYXJhbUlkeCA9IHBhcmFtcy5maW5kSW5kZXgoKHBhcmFtKSA9PlxyXG5cdFx0YnJhY2VTdXJyb3VuZGluZ1JlZ2V4LnRlc3QocGFyYW0pXHJcblx0KTtcclxuXHRpZiAobGluZUhpZ2h0bGlnaHRQYXJhbUlkeCA9PT0gLTEpIHJldHVybiA7XHJcblxyXG5cdHByZS5kYXRhc2V0LmxpbmUgPSBwYXJhbXNbbGluZUhpZ2h0bGlnaHRQYXJhbUlkeF0uc2xpY2UoMSwgLTEpO1xyXG5cclxuXHRjb25zdCBpbml0TGluZUhpZ2hsaWdodCA9ICgpID0+IHtcclxuXHRcdHdpbmRvdy5QcmlzbS5wbHVnaW5zLmxpbmVIaWdobGlnaHQuaGlnaGxpZ2h0TGluZXMocHJlKSgpO1xyXG5cdH1cclxuXHJcblx0aW5pdEhhbmRsZXJzLnB1c2goaW5pdExpbmVIaWdobGlnaHQpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY29tbW9uQ29kZWJsb2NrUG9zdFByb2Nlc3NvcihcclxuXHRlbGVtZW50OiBIVE1MRWxlbWVudCxcclxuXHRjb250ZXh0OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LFxyXG5cdGFwcDogQXBwLFxyXG5cdHBsdWdpbjogUGx1Z2luXHJcbikge1xyXG5cdC8vIGNoZWNrIGlmIHByb2Nlc3NvciBzaG91bGQgcnVuXHJcblx0Y29uc3QgcHJvY2Vzc1Jlc3VsdCA9IHByb2Nlc3NQYXJhbXMoZWxlbWVudCwgY29udGV4dCwgYXBwKTtcclxuXHRpZiAoIXByb2Nlc3NSZXN1bHQpIHJldHVybjtcclxuXHJcblx0Y29uc3QgeyBwcmUsIHBhcmFtcyB9ID0gcHJvY2Vzc1Jlc3VsdDtcclxuXHRjb25zdCBpbml0SGFuZGxlcnM6IEhhbmRsZXJTZXQgPSBbXTtcclxuXHJcblx0Ly8gYWRkIGxpbmUgbnVtYmVycy5cclxuXHRoYW5kbGVMaW5lTnVtYmVycyhwcmUsIHBhcmFtcywgaW5pdEhhbmRsZXJzKTtcclxuXHJcblx0Ly8gYWRkIGxpbmUgaGlnaGxpZ2h0XHJcblx0aGFuZGxlTGluZUhpZ2hsaWdodChwcmUsIHBhcmFtcywgaW5pdEhhbmRsZXJzKTtcclxuXHJcblx0Ly8gUmVpbml0IGFmdGVyIG1vdW50XHJcblx0b25Nb3VudGVkKHByZSwgKCkgPT4ge1xyXG5cdFx0aW5pdEhhbmRsZXJzLmZvckVhY2goKGhhbmRsZXIpID0+IHtcclxuXHRcdFx0aGFuZGxlcigpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblxyXG5cdC8vIFJlaW5pdCBhZnRlciByZXNpemVcclxuXHRwbHVnaW4ucmVnaXN0ZXJFdmVudChhcHAud29ya3NwYWNlLm9uKCdyZXNpemUnLCAoKSA9PiB7XHJcblx0XHRpbml0SGFuZGxlcnMuZm9yRWFjaCgoaGFuZGxlcikgPT4ge1xyXG5cdFx0XHRoYW5kbGVyKCk7XHJcblx0XHR9KVxyXG5cdH0pKVxyXG59XHJcbiIsICJleHBvcnQgY29uc3QgcGFyYW1SZWdleCA9IC9cXHsuK1xcfXxcXHcrL2c7XHJcbmV4cG9ydCBjb25zdCBicmFjZVN1cnJvdW5kaW5nUmVnZXggPSAvXnsuK30kLzsiLCAiaW1wb3J0IHsgbG9hZFByaXNtIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBleHRlbmRMaW5lTnVtYmVyUGx1Z2luIH0gZnJvbSAnLi8uLi9saWIvcHJpc20tbGluZS1udW1iZXJzJztcclxuaW1wb3J0IHsgZXh0ZW5kTGluZUhpZ2hsaWdodFBsdWdpbiB9IGZyb20gJy4vLi4vbGliL3ByaXNtLWxpbmUtaGlnaGxpZ2h0J1xyXG5cclxubG9hZFByaXNtKCkudGhlbigodmFsKSA9PiB7XHJcbiAgZXh0ZW5kTGluZU51bWJlclBsdWdpbih3aW5kb3cuUHJpc20pXHJcbiAgZXh0ZW5kTGluZUhpZ2hsaWdodFBsdWdpbih3aW5kb3cuUHJpc20pXHJcbn0pOyIsICJleHBvcnQgZnVuY3Rpb24gZXh0ZW5kTGluZU51bWJlclBsdWdpbiAoUHJpc20pIHtcclxuXHJcblx0aWYgKHR5cGVvZiBQcmlzbSA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUGx1Z2luIG5hbWUgd2hpY2ggaXMgdXNlZCBhcyBhIGNsYXNzIG5hbWUgZm9yIDxwcmU+IHdoaWNoIGlzIGFjdGl2YXRpbmcgdGhlIHBsdWdpblxyXG5cdCAqXHJcblx0ICogQHR5cGUge3N0cmluZ31cclxuXHQgKi9cclxuXHR2YXIgUExVR0lOX05BTUUgPSAnbGluZS1udW1iZXJzJztcclxuXHJcblx0LyoqXHJcblx0ICogUmVndWxhciBleHByZXNzaW9uIHVzZWQgZm9yIGRldGVybWluaW5nIGxpbmUgYnJlYWtzXHJcblx0ICpcclxuXHQgKiBAdHlwZSB7UmVnRXhwfVxyXG5cdCAqL1xyXG5cdHZhciBORVdfTElORV9FWFAgPSAvXFxuKD8hJCkvZztcclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEdsb2JhbCBleHBvcnRzXHJcblx0ICovXHJcblx0dmFyIGNvbmZpZyA9IFByaXNtLnBsdWdpbnMubGluZU51bWJlcnMgPSB7XHJcblx0XHQvKipcclxuXHRcdCAqIEdldCBub2RlIGZvciBwcm92aWRlZCBsaW5lIG51bWJlclxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBwcmUgZWxlbWVudFxyXG5cdFx0ICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBsaW5lIG51bWJlclxyXG5cdFx0ICogQHJldHVybnMge0VsZW1lbnR8dW5kZWZpbmVkfVxyXG5cdFx0ICovXHJcblx0XHRnZXRMaW5lOiBmdW5jdGlvbiAoZWxlbWVudCwgbnVtYmVyKSB7XHJcblx0XHRcdGlmIChlbGVtZW50LnRhZ05hbWUgIT09ICdQUkUnIHx8ICFlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhQTFVHSU5fTkFNRSkpIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHZhciBsaW5lTnVtYmVyUm93cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcignLmxpbmUtbnVtYmVycy1yb3dzJyk7XHJcblx0XHRcdGlmICghbGluZU51bWJlclJvd3MpIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHRcdFx0dmFyIGxpbmVOdW1iZXJTdGFydCA9IHBhcnNlSW50KGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXN0YXJ0JyksIDEwKSB8fCAxO1xyXG5cdFx0XHR2YXIgbGluZU51bWJlckVuZCA9IGxpbmVOdW1iZXJTdGFydCArIChsaW5lTnVtYmVyUm93cy5jaGlsZHJlbi5sZW5ndGggLSAxKTtcclxuXHJcblx0XHRcdGlmIChudW1iZXIgPCBsaW5lTnVtYmVyU3RhcnQpIHtcclxuXHRcdFx0XHRudW1iZXIgPSBsaW5lTnVtYmVyU3RhcnQ7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKG51bWJlciA+IGxpbmVOdW1iZXJFbmQpIHtcclxuXHRcdFx0XHRudW1iZXIgPSBsaW5lTnVtYmVyRW5kO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR2YXIgbGluZUluZGV4ID0gbnVtYmVyIC0gbGluZU51bWJlclN0YXJ0O1xyXG5cclxuXHRcdFx0cmV0dXJuIGxpbmVOdW1iZXJSb3dzLmNoaWxkcmVuW2xpbmVJbmRleF07XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogUmVzaXplcyB0aGUgbGluZSBudW1iZXJzIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxyXG5cdFx0ICpcclxuXHRcdCAqIFRoaXMgZnVuY3Rpb24gd2lsbCBub3QgYWRkIGxpbmUgbnVtYmVycy4gSXQgd2lsbCBvbmx5IHJlc2l6ZSBleGlzdGluZyBvbmVzLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnQgQSBgPHByZT5gIGVsZW1lbnQgd2l0aCBsaW5lIG51bWJlcnMuXHJcblx0XHQgKiBAcmV0dXJucyB7dm9pZH1cclxuXHRcdCAqL1xyXG5cdFx0cmVzaXplOiBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG5cdFx0XHRyZXNpemVFbGVtZW50cyhbZWxlbWVudF0pO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFdoZXRoZXIgdGhlIHBsdWdpbiBjYW4gYXNzdW1lIHRoYXQgdGhlIHVuaXRzIGZvbnQgc2l6ZXMgYW5kIG1hcmdpbnMgYXJlIG5vdCBkZXBlbmRlZCBvbiB0aGUgc2l6ZSBvZlxyXG5cdFx0ICogdGhlIGN1cnJlbnQgdmlld3BvcnQuXHJcblx0XHQgKlxyXG5cdFx0ICogU2V0dGluZyB0aGlzIHRvIGB0cnVlYCB3aWxsIGFsbG93IHRoZSBwbHVnaW4gdG8gZG8gY2VydGFpbiBvcHRpbWl6YXRpb25zIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuXHJcblx0XHQgKlxyXG5cdFx0ICogU2V0IHRoaXMgdG8gYGZhbHNlYCBpZiB5b3UgdXNlIGFueSBvZiB0aGUgZm9sbG93aW5nIENTUyB1bml0czogYHZoYCwgYHZ3YCwgYHZtaW5gLCBgdm1heGAuXHJcblx0XHQgKlxyXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XHJcblx0XHQgKi9cclxuXHRcdGFzc3VtZVZpZXdwb3J0SW5kZXBlbmRlbmNlOiB0cnVlXHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogUmVzaXplcyB0aGUgZ2l2ZW4gZWxlbWVudHMuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge0hUTUxFbGVtZW50W119IGVsZW1lbnRzXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gcmVzaXplRWxlbWVudHMoZWxlbWVudHMpIHtcclxuXHRcdGVsZW1lbnRzID0gZWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdHZhciBjb2RlU3R5bGVzID0gZ2V0U3R5bGVzKGUpO1xyXG5cdFx0XHR2YXIgd2hpdGVTcGFjZSA9IGNvZGVTdHlsZXNbJ3doaXRlLXNwYWNlJ107XHJcblx0XHRcdHJldHVybiB3aGl0ZVNwYWNlID09PSAncHJlLXdyYXAnIHx8IHdoaXRlU3BhY2UgPT09ICdwcmUtbGluZSc7XHJcblx0XHR9KTtcclxuXHJcblx0XHRpZiAoZWxlbWVudHMubGVuZ3RoID09IDApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBpbmZvcyA9IGVsZW1lbnRzLm1hcChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG5cdFx0XHR2YXIgY29kZUVsZW1lbnQgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ2NvZGUnKTtcclxuXHRcdFx0dmFyIGxpbmVOdW1iZXJzV3JhcHBlciA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcignLmxpbmUtbnVtYmVycy1yb3dzJyk7XHJcblx0XHRcdGlmICghY29kZUVsZW1lbnQgfHwgIWxpbmVOdW1iZXJzV3JhcHBlcikge1xyXG5cdFx0XHRcdHJldHVybiB1bmRlZmluZWQ7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8qKiBAdHlwZSB7SFRNTEVsZW1lbnR9ICovXHJcblx0XHRcdHZhciBsaW5lTnVtYmVyU2l6ZXIgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5saW5lLW51bWJlcnMtc2l6ZXInKTtcclxuXHRcdFx0dmFyIGNvZGVMaW5lcyA9IGNvZGVFbGVtZW50LnRleHRDb250ZW50LnNwbGl0KE5FV19MSU5FX0VYUCk7XHJcblxyXG5cdFx0XHRpZiAoIWxpbmVOdW1iZXJTaXplcikge1xyXG5cdFx0XHRcdGxpbmVOdW1iZXJTaXplciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcclxuXHRcdFx0XHRsaW5lTnVtYmVyU2l6ZXIuY2xhc3NOYW1lID0gJ2xpbmUtbnVtYmVycy1zaXplcic7XHJcblxyXG5cdFx0XHRcdGNvZGVFbGVtZW50LmFwcGVuZENoaWxkKGxpbmVOdW1iZXJTaXplcik7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGxpbmVOdW1iZXJTaXplci5pbm5lckhUTUwgPSAnMCc7XHJcblx0XHRcdGxpbmVOdW1iZXJTaXplci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuXHJcblx0XHRcdHZhciBvbmVMaW5lckhlaWdodCA9IGxpbmVOdW1iZXJTaXplci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7XHJcblx0XHRcdGxpbmVOdW1iZXJTaXplci5pbm5lckhUTUwgPSAnJztcclxuXHJcblx0XHRcdHJldHVybiB7XHJcblx0XHRcdFx0ZWxlbWVudDogZWxlbWVudCxcclxuXHRcdFx0XHRsaW5lczogY29kZUxpbmVzLFxyXG5cdFx0XHRcdGxpbmVIZWlnaHRzOiBbXSxcclxuXHRcdFx0XHRvbmVMaW5lckhlaWdodDogb25lTGluZXJIZWlnaHQsXHJcblx0XHRcdFx0c2l6ZXI6IGxpbmVOdW1iZXJTaXplcixcclxuXHRcdFx0fTtcclxuXHRcdH0pLmZpbHRlcihCb29sZWFuKTtcclxuXHJcblx0XHRpbmZvcy5mb3JFYWNoKGZ1bmN0aW9uIChpbmZvKSB7XHJcblx0XHRcdHZhciBsaW5lTnVtYmVyU2l6ZXIgPSBpbmZvLnNpemVyO1xyXG5cdFx0XHR2YXIgbGluZXMgPSBpbmZvLmxpbmVzO1xyXG5cdFx0XHR2YXIgbGluZUhlaWdodHMgPSBpbmZvLmxpbmVIZWlnaHRzO1xyXG5cdFx0XHR2YXIgb25lTGluZXJIZWlnaHQgPSBpbmZvLm9uZUxpbmVySGVpZ2h0O1xyXG5cclxuXHRcdFx0bGluZUhlaWdodHNbbGluZXMubGVuZ3RoIC0gMV0gPSB1bmRlZmluZWQ7XHJcblx0XHRcdGxpbmVzLmZvckVhY2goZnVuY3Rpb24gKGxpbmUsIGluZGV4KSB7XHJcblx0XHRcdFx0aWYgKGxpbmUgJiYgbGluZS5sZW5ndGggPiAxKSB7XHJcblx0XHRcdFx0XHR2YXIgZSA9IGxpbmVOdW1iZXJTaXplci5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJykpO1xyXG5cdFx0XHRcdFx0ZS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuXHRcdFx0XHRcdGUudGV4dENvbnRlbnQgPSBsaW5lO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRsaW5lSGVpZ2h0c1tpbmRleF0gPSBvbmVMaW5lckhlaWdodDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0aW5mb3MuZm9yRWFjaChmdW5jdGlvbiAoaW5mbykge1xyXG5cdFx0XHR2YXIgbGluZU51bWJlclNpemVyID0gaW5mby5zaXplcjtcclxuXHRcdFx0dmFyIGxpbmVIZWlnaHRzID0gaW5mby5saW5lSGVpZ2h0cztcclxuXHJcblx0XHRcdHZhciBjaGlsZEluZGV4ID0gMDtcclxuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lSGVpZ2h0cy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHRcdGlmIChsaW5lSGVpZ2h0c1tpXSA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdFx0XHRsaW5lSGVpZ2h0c1tpXSA9IGxpbmVOdW1iZXJTaXplci5jaGlsZHJlbltjaGlsZEluZGV4KytdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdGluZm9zLmZvckVhY2goZnVuY3Rpb24gKGluZm8pIHtcclxuXHRcdFx0dmFyIGxpbmVOdW1iZXJTaXplciA9IGluZm8uc2l6ZXI7XHJcblx0XHRcdHZhciB3cmFwcGVyID0gaW5mby5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5saW5lLW51bWJlcnMtcm93cycpO1xyXG5cclxuXHRcdFx0bGluZU51bWJlclNpemVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcblx0XHRcdGxpbmVOdW1iZXJTaXplci5pbm5lckhUTUwgPSAnJztcclxuXHJcblx0XHRcdGluZm8ubGluZUhlaWdodHMuZm9yRWFjaChmdW5jdGlvbiAoaGVpZ2h0LCBsaW5lTnVtYmVyKSB7XHJcblx0XHRcdFx0d3JhcHBlci5jaGlsZHJlbltsaW5lTnVtYmVyXS5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyAncHgnO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyBzdHlsZSBkZWNsYXJhdGlvbnMgZm9yIHRoZSBlbGVtZW50XHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiBnZXRTdHlsZXMoZWxlbWVudCkge1xyXG5cdFx0aWYgKCFlbGVtZW50KSB7XHJcblx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSA/IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkgOiAoZWxlbWVudC5jdXJyZW50U3R5bGUgfHwgbnVsbCk7XHJcblx0fVxyXG5cclxuXHQvLyB2YXIgbGFzdFdpZHRoID0gdW5kZWZpbmVkO1xyXG5cdC8vIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBmdW5jdGlvbiAoKSB7XHJcblx0Ly8gXHRpZiAoY29uZmlnLmFzc3VtZVZpZXdwb3J0SW5kZXBlbmRlbmNlICYmIGxhc3RXaWR0aCA9PT0gd2luZG93LmlubmVyV2lkdGgpIHtcclxuXHQvLyBcdFx0cmV0dXJuO1xyXG5cdC8vIFx0fVxyXG5cdC8vIFx0bGFzdFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcblxyXG5cdC8vIFx0cmVzaXplRWxlbWVudHMoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgncHJlLicgKyBQTFVHSU5fTkFNRSkpKTtcclxuXHQvLyB9KTtcclxuXHJcblx0UHJpc20uaG9va3MuYWRkKCdjb21wbGV0ZScsIGZ1bmN0aW9uIChlbnYpIHtcclxuXHRcdGlmICghZW52LmNvZGUpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBjb2RlID0gLyoqIEB0eXBlIHtFbGVtZW50fSAqLyAoZW52LmVsZW1lbnQpO1xyXG5cdFx0dmFyIHByZSA9IC8qKiBAdHlwZSB7SFRNTEVsZW1lbnR9ICovIChjb2RlLnBhcmVudE5vZGUpO1xyXG5cclxuXHRcdC8vIHdvcmtzIG9ubHkgZm9yIDxjb2RlPiB3cmFwcGVkIGluc2lkZSA8cHJlPiAobm90IGlubGluZSlcclxuXHRcdGlmICghcHJlIHx8ICEvcHJlL2kudGVzdChwcmUubm9kZU5hbWUpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBBYm9ydCBpZiBsaW5lIG51bWJlcnMgYWxyZWFkeSBleGlzdHNcclxuXHRcdGlmIChjb2RlLnF1ZXJ5U2VsZWN0b3IoJy5saW5lLW51bWJlcnMtcm93cycpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBvbmx5IGFkZCBsaW5lIG51bWJlcnMgaWYgPGNvZGU+IG9yIG9uZSBvZiBpdHMgYW5jZXN0b3JzIGhhcyB0aGUgYGxpbmUtbnVtYmVyc2AgY2xhc3NcclxuXHRcdGlmICghUHJpc20udXRpbC5pc0FjdGl2ZShjb2RlLCBQTFVHSU5fTkFNRSkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlbW92ZSB0aGUgY2xhc3MgJ2xpbmUtbnVtYmVycycgZnJvbSB0aGUgPGNvZGU+XHJcblx0XHRjb2RlLmNsYXNzTGlzdC5yZW1vdmUoUExVR0lOX05BTUUpO1xyXG5cdFx0Ly8gQWRkIHRoZSBjbGFzcyAnbGluZS1udW1iZXJzJyB0byB0aGUgPHByZT5cclxuXHRcdHByZS5jbGFzc0xpc3QuYWRkKFBMVUdJTl9OQU1FKTtcclxuXHJcblx0XHR2YXIgbWF0Y2ggPSBlbnYuY29kZS5tYXRjaChORVdfTElORV9FWFApO1xyXG5cdFx0dmFyIGxpbmVzTnVtID0gbWF0Y2ggPyBtYXRjaC5sZW5ndGggKyAxIDogMTtcclxuXHRcdHZhciBsaW5lTnVtYmVyc1dyYXBwZXI7XHJcblxyXG5cdFx0dmFyIGxpbmVzID0gbmV3IEFycmF5KGxpbmVzTnVtICsgMSkuam9pbignPHNwYW4+PC9zcGFuPicpO1xyXG5cclxuXHRcdGxpbmVOdW1iZXJzV3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcclxuXHRcdGxpbmVOdW1iZXJzV3JhcHBlci5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcclxuXHRcdGxpbmVOdW1iZXJzV3JhcHBlci5jbGFzc05hbWUgPSAnbGluZS1udW1iZXJzLXJvd3MnO1xyXG5cdFx0bGluZU51bWJlcnNXcmFwcGVyLmlubmVySFRNTCA9IGxpbmVzO1xyXG5cclxuXHRcdGlmIChwcmUuaGFzQXR0cmlidXRlKCdkYXRhLXN0YXJ0JykpIHtcclxuXHRcdFx0cHJlLnN0eWxlLmNvdW50ZXJSZXNldCA9ICdsaW5lbnVtYmVyICcgKyAocGFyc2VJbnQocHJlLmdldEF0dHJpYnV0ZSgnZGF0YS1zdGFydCcpLCAxMCkgLSAxKTtcclxuXHRcdH1cclxuXHJcblx0XHRlbnYuZWxlbWVudC5hcHBlbmRDaGlsZChsaW5lTnVtYmVyc1dyYXBwZXIpO1xyXG5cclxuXHRcdHJlc2l6ZUVsZW1lbnRzKFtwcmVdKTtcclxuXHJcblx0XHRQcmlzbS5ob29rcy5ydW4oJ2xpbmUtbnVtYmVycycsIGVudik7XHJcblx0fSk7XHJcblxyXG5cdFByaXNtLmhvb2tzLmFkZCgnbGluZS1udW1iZXJzJywgZnVuY3Rpb24gKGVudikge1xyXG5cdFx0ZW52LnBsdWdpbnMgPSBlbnYucGx1Z2lucyB8fCB7fTtcclxuXHRcdGVudi5wbHVnaW5zLmxpbmVOdW1iZXJzID0gdHJ1ZTtcclxuXHR9KTtcclxuXHJcbn1cclxuIiwgImV4cG9ydCBmdW5jdGlvbiBleHRlbmRMaW5lSGlnaGxpZ2h0UGx1Z2luIChQcmlzbSkge1xyXG5cclxuXHRpZiAodHlwZW9mIFByaXNtID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICFkb2N1bWVudC5xdWVyeVNlbGVjdG9yKSB7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHR2YXIgTElORV9OVU1CRVJTX0NMQVNTID0gJ2xpbmUtbnVtYmVycyc7XHJcblx0dmFyIExJTktBQkxFX0xJTkVfTlVNQkVSU19DTEFTUyA9ICdsaW5rYWJsZS1saW5lLW51bWJlcnMnO1xyXG5cdHZhciBORVdfTElORV9SRUdFWCA9IC9cXG4oPyEkKS9nXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzZWxlY3RvclxyXG5cdCAqIEBwYXJhbSB7UGFyZW50Tm9kZX0gW2NvbnRhaW5lcl1cclxuXHQgKiBAcmV0dXJucyB7SFRNTEVsZW1lbnRbXX1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiAkJChzZWxlY3RvciwgY29udGFpbmVyKSB7XHJcblx0XHRyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoKGNvbnRhaW5lciB8fCBkb2N1bWVudCkucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikpO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBlbGVtZW50IGhhcyB0aGUgZ2l2ZW4gY2xhc3MuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXHJcblx0ICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gaGFzQ2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lKSB7XHJcblx0XHRyZXR1cm4gZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENhbGxzIHRoZSBnaXZlbiBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7KCkgPT4gYW55fSBmdW5jXHJcblx0ICogQHJldHVybnMge3ZvaWR9XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gY2FsbEZ1bmN0aW9uKGZ1bmMpIHtcclxuXHRcdGZ1bmMoKTtcclxuXHR9XHJcblxyXG5cdC8vIFNvbWUgYnJvd3NlcnMgcm91bmQgdGhlIGxpbmUtaGVpZ2h0LCBvdGhlcnMgZG9uJ3QuXHJcblx0Ly8gV2UgbmVlZCB0byB0ZXN0IGZvciBpdCB0byBwb3NpdGlvbiB0aGUgZWxlbWVudHMgcHJvcGVybHkuXHJcblx0dmFyIGlzTGluZUhlaWdodFJvdW5kZWQgPSAoZnVuY3Rpb24gKCkge1xyXG5cdFx0dmFyIHJlcztcclxuXHRcdHJldHVybiBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdGlmICh0eXBlb2YgcmVzID09PSAndW5kZWZpbmVkJykge1xyXG5cdFx0XHRcdHZhciBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcblx0XHRcdFx0ZC5zdHlsZS5mb250U2l6ZSA9ICcxM3B4JztcclxuXHRcdFx0XHRkLnN0eWxlLmxpbmVIZWlnaHQgPSAnMS41JztcclxuXHRcdFx0XHRkLnN0eWxlLnBhZGRpbmcgPSAnMCc7XHJcblx0XHRcdFx0ZC5zdHlsZS5ib3JkZXIgPSAnMCc7XHJcblx0XHRcdFx0ZC5pbm5lckhUTUwgPSAnJm5ic3A7PGJyIC8+Jm5ic3A7JztcclxuXHRcdFx0XHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGQpO1xyXG5cdFx0XHRcdC8vIEJyb3dzZXJzIHRoYXQgcm91bmQgdGhlIGxpbmUtaGVpZ2h0IHNob3VsZCBoYXZlIG9mZnNldEhlaWdodCA9PT0gMzhcclxuXHRcdFx0XHQvLyBUaGUgb3RoZXJzIHNob3VsZCBoYXZlIDM5LlxyXG5cdFx0XHRcdHJlcyA9IGQub2Zmc2V0SGVpZ2h0ID09PSAzODtcclxuXHRcdFx0XHRkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGQpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZXM7XHJcblx0XHR9O1xyXG5cdH0oKSk7XHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdGhlIHRvcCBvZmZzZXQgb2YgdGhlIGNvbnRlbnQgYm94IG9mIHRoZSBnaXZlbiBwYXJlbnQgYW5kIHRoZSBjb250ZW50IGJveCBvZiBvbmUgb2YgaXRzIGNoaWxkcmVuLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50XHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gY2hpbGRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiBnZXRDb250ZW50Qm94VG9wT2Zmc2V0KHBhcmVudCwgY2hpbGQpIHtcclxuXHRcdHZhciBwYXJlbnRTdHlsZSA9IGdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcclxuXHRcdHZhciBjaGlsZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShjaGlsZCk7XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBSZXR1cm5zIHRoZSBudW1lcmljIHZhbHVlIG9mIHRoZSBnaXZlbiBwaXhlbCB2YWx1ZS5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gcHhcclxuXHRcdCAqL1xyXG5cdFx0ZnVuY3Rpb24gcHhUb051bWJlcihweCkge1xyXG5cdFx0XHRyZXR1cm4gK3B4LnN1YnN0cigwLCBweC5sZW5ndGggLSAyKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gY2hpbGQub2Zmc2V0VG9wXHJcblx0XHRcdCsgcHhUb051bWJlcihjaGlsZFN0eWxlLmJvcmRlclRvcFdpZHRoKVxyXG5cdFx0XHQrIHB4VG9OdW1iZXIoY2hpbGRTdHlsZS5wYWRkaW5nVG9wKVxyXG5cdFx0XHQtIHB4VG9OdW1iZXIocGFyZW50U3R5bGUucGFkZGluZ1RvcCk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIExpbmUgSGlnaGxpZ2h0IHBsdWdpbiBpcyBhY3RpdmUgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxyXG5cdCAqXHJcblx0ICogSWYgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGBmYWxzZWAsIGRvIG5vdCBjYWxsIGBoaWdobGlnaHRMaW5lc2AgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudCB8IG51bGwgfCB1bmRlZmluZWR9IHByZVxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIGlzQWN0aXZlRm9yKHByZSkge1xyXG5cdFx0aWYgKCFwcmUgfHwgIS9wcmUvaS50ZXN0KHByZS5ub2RlTmFtZSkpIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChwcmUuaGFzQXR0cmlidXRlKCdkYXRhLWxpbmUnKSkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAocHJlLmlkICYmIFByaXNtLnV0aWwuaXNBY3RpdmUocHJlLCBMSU5LQUJMRV9MSU5FX05VTUJFUlNfQ0xBU1MpKSB7XHJcblx0XHRcdC8vIFRlY2huaWNhbGx5LCB0aGUgbGluZSBudW1iZXJzIHBsdWdpbiBpcyBhbHNvIG5lY2Vzc2FyeSBidXQgdGhpcyBwbHVnaW4gZG9lc24ndCBjb250cm9sIHRoZSBjbGFzc2VzIG9mXHJcblx0XHRcdC8vIHRoZSBsaW5lIG51bWJlcnMgcGx1Z2luLCBzbyB3ZSBjYW4ndCBhc3N1bWUgdGhhdCB0aGV5IGFyZSBwcmVzZW50LlxyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cclxuXHR2YXIgc2Nyb2xsSW50b1ZpZXcgPSB0cnVlO1xyXG5cclxuXHRQcmlzbS5wbHVnaW5zLmxpbmVIaWdobGlnaHQgPSB7XHJcblx0XHQvKipcclxuXHRcdCAqIEhpZ2hsaWdodHMgdGhlIGxpbmVzIG9mIHRoZSBnaXZlbiBwcmUuXHJcblx0XHQgKlxyXG5cdFx0ICogVGhpcyBmdW5jdGlvbiBpcyBzcGxpdCBpbnRvIGEgRE9NIG1lYXN1cmluZyBhbmQgbXV0YXRlIHBoYXNlIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuXHJcblx0XHQgKiBUaGUgcmV0dXJuZWQgZnVuY3Rpb24gbXV0YXRlcyB0aGUgRE9NIHdoZW4gY2FsbGVkLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHByZVxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmcgfCBudWxsfSBbbGluZXNdXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gW2NsYXNzZXM9JyddXHJcblx0XHQgKiBAcmV0dXJucyB7KCkgPT4gdm9pZH1cclxuXHRcdCAqL1xyXG5cdFx0aGlnaGxpZ2h0TGluZXM6IGZ1bmN0aW9uIGhpZ2hsaWdodExpbmVzKHByZSwgbGluZXMsIGNsYXNzZXMpIHtcclxuXHRcdFx0bGluZXMgPSB0eXBlb2YgbGluZXMgPT09ICdzdHJpbmcnID8gbGluZXMgOiAocHJlLmdldEF0dHJpYnV0ZSgnZGF0YS1saW5lJykgfHwgJycpO1xyXG5cclxuXHRcdFx0dmFyIHJhbmdlcyA9IGxpbmVzLnJlcGxhY2UoL1xccysvZywgJycpLnNwbGl0KCcsJykuZmlsdGVyKEJvb2xlYW4pO1xyXG5cdFx0XHR2YXIgb2Zmc2V0ID0gK3ByZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtbGluZS1vZmZzZXQnKSB8fCAwO1xyXG5cclxuXHRcdFx0dmFyIHBhcnNlTWV0aG9kID0gaXNMaW5lSGVpZ2h0Um91bmRlZCgpID8gcGFyc2VJbnQgOiBwYXJzZUZsb2F0O1xyXG5cdFx0XHR2YXIgY29kZUVsZW1lbnQgPSBwcmUucXVlcnlTZWxlY3RvcignY29kZScpO1xyXG5cdFx0XHR2YXIgbGluZUhlaWdodCA9IHBhcnNlTWV0aG9kKGdldENvbXB1dGVkU3R5bGUoY29kZUVsZW1lbnQpLmxpbmVIZWlnaHQpO1xyXG5cdFx0XHR2YXIgaGFzTGluZU51bWJlcnMgPSBQcmlzbS51dGlsLmlzQWN0aXZlKHByZSwgTElORV9OVU1CRVJTX0NMQVNTKTtcclxuXHRcdFx0dmFyIHBhcmVudEVsZW1lbnQgPSBoYXNMaW5lTnVtYmVycyA/IHByZSA6IGNvZGVFbGVtZW50IHx8IHByZTtcclxuXHRcdFx0dmFyIG11dGF0ZUFjdGlvbnMgPSAvKiogQHR5cGUgeygoKSA9PiB2b2lkKVtdfSAqLyAoW10pO1xyXG5cdFx0XHR2YXIgbGluZUJyZWFrTWF0Y2ggPSBjb2RlRWxlbWVudC50ZXh0Q29udGVudC5tYXRjaChORVdfTElORV9SRUdFWCk7XHJcblx0XHRcdHZhciBudW1iZXJPZkxpbmVzID0gbGluZUJyZWFrTWF0Y2g/IGxpbmVCcmVha01hdGNoLmxlbmd0aCArIDE6IDFcclxuXHJcblx0XHRcdC8qKlxyXG5cdFx0XHQgKiBUaGUgdG9wIG9mZnNldCBiZXR3ZWVuIHRoZSBjb250ZW50IGJveCBvZiB0aGUgPGNvZGU+IGVsZW1lbnQgYW5kIHRoZSBjb250ZW50IGJveCBvZiB0aGUgcGFyZW50IGVsZW1lbnQgb2ZcclxuXHRcdFx0ICogdGhlIGxpbmUgaGlnaGxpZ2h0IGVsZW1lbnQgKGVpdGhlciBgPHByZT5gIG9yIGA8Y29kZT5gKS5cclxuXHRcdFx0ICpcclxuXHRcdFx0ICogVGhpcyBvZmZzZXQgbWlnaHQgbm90IGJlIHplcm8gZm9yIHNvbWUgdGhlbWVzIHdoZXJlIHRoZSA8Y29kZT4gZWxlbWVudCBoYXMgYSB0b3AgbWFyZ2luLiBTb21lIHBsdWdpbnNcclxuXHRcdFx0ICogKG9yIHVzZXJzKSBtaWdodCBhbHNvIGFkZCBlbGVtZW50IGFib3ZlIHRoZSA8Y29kZT4gZWxlbWVudC4gQmVjYXVzZSB0aGUgbGluZSBoaWdobGlnaHQgaXMgYWxpZ25lZCByZWxhdGl2ZVxyXG5cdFx0XHQgKiB0byB0aGUgPHByZT4gZWxlbWVudCwgd2UgaGF2ZSB0byB0YWtlIHRoaXMgaW50byBhY2NvdW50LlxyXG5cdFx0XHQgKlxyXG5cdFx0XHQgKiBUaGlzIG9mZnNldCB3aWxsIGJlIDAgaWYgdGhlIHBhcmVudCBlbGVtZW50IG9mIHRoZSBsaW5lIGhpZ2hsaWdodCBlbGVtZW50IGlzIHRoZSBgPGNvZGU+YCBlbGVtZW50LlxyXG5cdFx0XHQgKi9cclxuXHRcdFx0dmFyIGNvZGVQcmVPZmZzZXQgPSAhY29kZUVsZW1lbnQgfHwgcGFyZW50RWxlbWVudCA9PSBjb2RlRWxlbWVudCA/IDAgOiBnZXRDb250ZW50Qm94VG9wT2Zmc2V0KHByZSwgY29kZUVsZW1lbnQpO1xyXG5cclxuXHRcdFx0cmFuZ2VzLmZvckVhY2goZnVuY3Rpb24gKGN1cnJlbnRSYW5nZSkge1xyXG5cdFx0XHRcdHZhciByYW5nZSA9IGN1cnJlbnRSYW5nZS5zcGxpdCgnLScpO1xyXG5cclxuXHRcdFx0XHR2YXIgc3RhcnQgPSArcmFuZ2VbMF07XHJcblx0XHRcdFx0dmFyIGVuZCA9ICtyYW5nZVsxXSB8fCBzdGFydDtcclxuXHRcdFx0XHRlbmQgPSBNYXRoLm1pbihudW1iZXJPZkxpbmVzLCBlbmQpO1xyXG5cclxuXHRcdFx0XHRpZiAoZW5kIDwgc3RhcnQpIHJldHVybiA7XHJcblxyXG5cdFx0XHRcdC8qKiBAdHlwZSB7SFRNTEVsZW1lbnR9ICovXHJcblx0XHRcdFx0dmFyIGxpbmUgPSBwcmUucXVlcnlTZWxlY3RvcignLmxpbmUtaGlnaGxpZ2h0W2RhdGEtcmFuZ2U9XCInICsgY3VycmVudFJhbmdlICsgJ1wiXScpIHx8IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG5cclxuXHRcdFx0XHRtdXRhdGVBY3Rpb25zLnB1c2goZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0bGluZS5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcclxuXHRcdFx0XHRcdGxpbmUuc2V0QXR0cmlidXRlKCdkYXRhLXJhbmdlJywgY3VycmVudFJhbmdlKTtcclxuXHRcdFx0XHRcdGxpbmUuY2xhc3NOYW1lID0gKGNsYXNzZXMgfHwgJycpICsgJyBsaW5lLWhpZ2hsaWdodCc7XHJcblx0XHRcdFx0fSk7XHJcblxyXG5cdFx0XHRcdC8vIGlmIHRoZSBsaW5lLW51bWJlcnMgcGx1Z2luIGlzIGVuYWJsZWQsIHRoZW4gdGhlcmUgaXMgbm8gcmVhc29uIGZvciB0aGlzIHBsdWdpbiB0byBkaXNwbGF5IHRoZSBsaW5lIG51bWJlcnNcclxuXHRcdFx0XHRpZiAoaGFzTGluZU51bWJlcnMgJiYgUHJpc20ucGx1Z2lucy5saW5lTnVtYmVycykge1xyXG5cdFx0XHRcdFx0dmFyIHN0YXJ0Tm9kZSA9IFByaXNtLnBsdWdpbnMubGluZU51bWJlcnMuZ2V0TGluZShwcmUsIHN0YXJ0KTtcclxuXHRcdFx0XHRcdHZhciBlbmROb2RlID0gUHJpc20ucGx1Z2lucy5saW5lTnVtYmVycy5nZXRMaW5lKHByZSwgZW5kKTtcclxuXHJcblx0XHRcdFx0XHRpZiAoc3RhcnROb2RlKSB7XHJcblx0XHRcdFx0XHRcdHZhciB0b3AgPSBzdGFydE5vZGUub2Zmc2V0VG9wICsgY29kZVByZU9mZnNldCArICdweCc7XHJcblx0XHRcdFx0XHRcdG11dGF0ZUFjdGlvbnMucHVzaChmdW5jdGlvbiAoKSB7XHJcblx0XHRcdFx0XHRcdFx0bGluZS5zdHlsZS50b3AgPSB0b3A7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdGlmIChlbmROb2RlKSB7XHJcblx0XHRcdFx0XHRcdHZhciBoZWlnaHQgPSAoZW5kTm9kZS5vZmZzZXRUb3AgLSBzdGFydE5vZGUub2Zmc2V0VG9wKSArIGVuZE5vZGUub2Zmc2V0SGVpZ2h0ICsgJ3B4JztcclxuXHRcdFx0XHRcdFx0bXV0YXRlQWN0aW9ucy5wdXNoKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdFx0XHRsaW5lLnN0eWxlLmhlaWdodCA9IGhlaWdodDtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0bXV0YXRlQWN0aW9ucy5wdXNoKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdFx0bGluZS5zZXRBdHRyaWJ1dGUoJ2RhdGEtc3RhcnQnLCBTdHJpbmcoc3RhcnQpKTtcclxuXHJcblx0XHRcdFx0XHRcdGlmIChlbmQgPiBzdGFydCkge1xyXG5cdFx0XHRcdFx0XHRcdGxpbmUuc2V0QXR0cmlidXRlKCdkYXRhLWVuZCcsIFN0cmluZyhlbmQpKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0bGluZS5zdHlsZS50b3AgPSAoc3RhcnQgLSBvZmZzZXQgLSAxKSAqIGxpbmVIZWlnaHQgKyBjb2RlUHJlT2Zmc2V0ICsgJ3B4JztcclxuXHJcblx0XHRcdFx0XHRcdGxpbmUudGV4dENvbnRlbnQgPSBuZXcgQXJyYXkoZW5kIC0gc3RhcnQgKyAyKS5qb2luKCcgXFxuJyk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdG11dGF0ZUFjdGlvbnMucHVzaChmdW5jdGlvbiAoKSB7XHJcblx0XHRcdFx0XHRsaW5lLnN0eWxlLndpZHRoID0gcHJlLnNjcm9sbFdpZHRoICsgJ3B4JztcclxuXHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0bXV0YXRlQWN0aW9ucy5wdXNoKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdC8vIGFsbG93IHRoaXMgdG8gcGxheSBuaWNlbHkgd2l0aCB0aGUgbGluZS1udW1iZXJzIHBsdWdpblxyXG5cdFx0XHRcdFx0Ly8gbmVlZCB0byBhdHRhY2sgdG8gcHJlIGFzIHdoZW4gbGluZS1udW1iZXJzIGlzIGVuYWJsZWQsIHRoZSBjb2RlIHRhZyBpcyByZWxhdGl2ZWx5IHdoaWNoIHNjcmV3cyB1cCB0aGUgcG9zaXRpb25pbmdcclxuXHRcdFx0XHRcdHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQobGluZSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0dmFyIGlkID0gcHJlLmlkO1xyXG5cdFx0XHRpZiAoaGFzTGluZU51bWJlcnMgJiYgUHJpc20udXRpbC5pc0FjdGl2ZShwcmUsIExJTktBQkxFX0xJTkVfTlVNQkVSU19DTEFTUykgJiYgaWQpIHtcclxuXHRcdFx0XHQvLyBUaGlzIGltcGxlbWVudHMgbGlua2FibGUgbGluZSBudW1iZXJzLiBMaW5rYWJsZSBsaW5lIG51bWJlcnMgdXNlIExpbmUgSGlnaGxpZ2h0IHRvIGNyZWF0ZSBhIGxpbmsgdG8gYVxyXG5cdFx0XHRcdC8vIHNwZWNpZmljIGxpbmUuIEZvciB0aGlzIHRvIHdvcmssIHRoZSBwcmUgZWxlbWVudCBoYXMgdG86XHJcblx0XHRcdFx0Ly8gIDEpIGhhdmUgbGluZSBudW1iZXJzLFxyXG5cdFx0XHRcdC8vICAyKSBoYXZlIHRoZSBgbGlua2FibGUtbGluZS1udW1iZXJzYCBjbGFzcyBvciBhbiBhc2NlbmRhbnQgdGhhdCBoYXMgdGhhdCBjbGFzcywgYW5kXHJcblx0XHRcdFx0Ly8gIDMpIGhhdmUgYW4gaWQuXHJcblxyXG5cdFx0XHRcdGlmICghaGFzQ2xhc3MocHJlLCBMSU5LQUJMRV9MSU5FX05VTUJFUlNfQ0xBU1MpKSB7XHJcblx0XHRcdFx0XHQvLyBhZGQgY2xhc3MgdG8gcHJlXHJcblx0XHRcdFx0XHRtdXRhdGVBY3Rpb25zLnB1c2goZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0XHRwcmUuY2xhc3NMaXN0LmFkZChMSU5LQUJMRV9MSU5FX05VTUJFUlNfQ0xBU1MpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR2YXIgc3RhcnQgPSBwYXJzZUludChwcmUuZ2V0QXR0cmlidXRlKCdkYXRhLXN0YXJ0JykgfHwgJzEnKTtcclxuXHJcblx0XHRcdFx0Ly8gaXRlcmF0ZSBhbGwgbGluZSBudW1iZXIgc3BhbnNcclxuXHRcdFx0XHQkJCgnLmxpbmUtbnVtYmVycy1yb3dzID4gc3BhbicsIHByZSkuZm9yRWFjaChmdW5jdGlvbiAobGluZVNwYW4sIGkpIHtcclxuXHRcdFx0XHRcdHZhciBsaW5lTnVtYmVyID0gaSArIHN0YXJ0O1xyXG5cdFx0XHRcdFx0bGluZVNwYW4ub25jbGljayA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdFx0dmFyIGhhc2ggPSBpZCArICcuJyArIGxpbmVOdW1iZXI7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyB0aGlzIHdpbGwgcHJldmVudCBzY3JvbGxpbmcgc2luY2UgdGhlIHNwYW4gaXMgb2J2aW91c2x5IGluIHZpZXdcclxuXHRcdFx0XHRcdFx0c2Nyb2xsSW50b1ZpZXcgPSBmYWxzZTtcclxuXHRcdFx0XHRcdFx0bG9jYXRpb24uaGFzaCA9IGhhc2g7XHJcblx0XHRcdFx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0XHRcdHNjcm9sbEludG9WaWV3ID0gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0fSwgMSk7XHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdG11dGF0ZUFjdGlvbnMuZm9yRWFjaChjYWxsRnVuY3Rpb24pO1xyXG5cdFx0XHR9O1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cclxuXHRmdW5jdGlvbiBhcHBseUhhc2goKSB7XHJcblx0XHR2YXIgaGFzaCA9IGxvY2F0aW9uLmhhc2guc2xpY2UoMSk7XHJcblxyXG5cdFx0Ly8gUmVtb3ZlIHByZS1leGlzdGluZyB0ZW1wb3JhcnkgbGluZXNcclxuXHRcdCQkKCcudGVtcG9yYXJ5LmxpbmUtaGlnaGxpZ2h0JykuZm9yRWFjaChmdW5jdGlvbiAobGluZSkge1xyXG5cdFx0XHRsaW5lLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGluZSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR2YXIgcmFuZ2UgPSAoaGFzaC5tYXRjaCgvXFwuKFtcXGQsLV0rKSQvKSB8fCBbLCAnJ10pWzFdO1xyXG5cclxuXHRcdGlmICghcmFuZ2UgfHwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaGFzaCkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBpZCA9IGhhc2guc2xpY2UoMCwgaGFzaC5sYXN0SW5kZXhPZignLicpKTtcclxuXHRcdHZhciBwcmUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XHJcblxyXG5cdFx0aWYgKCFwcmUpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICghcHJlLmhhc0F0dHJpYnV0ZSgnZGF0YS1saW5lJykpIHtcclxuXHRcdFx0cHJlLnNldEF0dHJpYnV0ZSgnZGF0YS1saW5lJywgJycpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBtdXRhdGVEb20gPSBQcmlzbS5wbHVnaW5zLmxpbmVIaWdobGlnaHQuaGlnaGxpZ2h0TGluZXMocHJlLCByYW5nZSwgJ3RlbXBvcmFyeSAnKTtcclxuXHRcdG11dGF0ZURvbSgpO1xyXG5cclxuXHRcdGlmIChzY3JvbGxJbnRvVmlldykge1xyXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudGVtcG9yYXJ5LmxpbmUtaGlnaGxpZ2h0Jykuc2Nyb2xsSW50b1ZpZXcoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHZhciBmYWtlVGltZXIgPSAwOyAvLyBIYWNrIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgdGltZXMgYXBwbHlIYXNoKCkgcnVuc1xyXG5cclxuXHRQcmlzbS5ob29rcy5hZGQoJ2JlZm9yZS1zYW5pdHktY2hlY2snLCBmdW5jdGlvbiAoZW52KSB7XHJcblx0XHR2YXIgcHJlID0gZW52LmVsZW1lbnQucGFyZW50RWxlbWVudDtcclxuXHRcdGlmICghaXNBY3RpdmVGb3IocHJlKSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0LypcclxuXHRcdCAqIENsZWFudXAgZm9yIG90aGVyIHBsdWdpbnMgKGUuZy4gYXV0b2xvYWRlcikuXHJcblx0XHQgKlxyXG5cdFx0ICogU29tZXRpbWVzIDxjb2RlPiBibG9ja3MgYXJlIGhpZ2hsaWdodGVkIG11bHRpcGxlIHRpbWVzLiBJdCBpcyBuZWNlc3NhcnlcclxuXHRcdCAqIHRvIGNsZWFudXAgYW55IGxlZnQtb3ZlciB0YWdzLCBiZWNhdXNlIHRoZSB3aGl0ZXNwYWNlIGluc2lkZSBvZiB0aGUgPGRpdj5cclxuXHRcdCAqIHRhZ3MgY2hhbmdlIHRoZSBjb250ZW50IG9mIHRoZSA8Y29kZT4gdGFnLlxyXG5cdFx0ICovXHJcblx0XHR2YXIgbnVtID0gMDtcclxuXHRcdCQkKCcubGluZS1oaWdobGlnaHQnLCBwcmUpLmZvckVhY2goZnVuY3Rpb24gKGxpbmUpIHtcclxuXHRcdFx0bnVtICs9IGxpbmUudGV4dENvbnRlbnQubGVuZ3RoO1xyXG5cdFx0XHRsaW5lLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGluZSk7XHJcblx0XHR9KTtcclxuXHRcdC8vIFJlbW92ZSBleHRyYSB3aGl0ZXNwYWNlXHJcblx0XHRpZiAobnVtICYmIC9eKD86IFxcbikrJC8udGVzdChlbnYuY29kZS5zbGljZSgtbnVtKSkpIHtcclxuXHRcdFx0ZW52LmNvZGUgPSBlbnYuY29kZS5zbGljZSgwLCAtbnVtKTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHJcblx0UHJpc20uaG9va3MuYWRkKCdjb21wbGV0ZScsIGZ1bmN0aW9uIGNvbXBsZXRlSG9vayhlbnYpIHtcclxuXHRcdHZhciBwcmUgPSBlbnYuZWxlbWVudC5wYXJlbnRFbGVtZW50O1xyXG5cdFx0aWYgKCFpc0FjdGl2ZUZvcihwcmUpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRjbGVhclRpbWVvdXQoZmFrZVRpbWVyKTtcclxuXHJcblx0XHR2YXIgaGFzTGluZU51bWJlcnMgPSBQcmlzbS5wbHVnaW5zLmxpbmVOdW1iZXJzO1xyXG5cdFx0dmFyIGlzTGluZU51bWJlcnNMb2FkZWQgPSBlbnYucGx1Z2lucyAmJiBlbnYucGx1Z2lucy5saW5lTnVtYmVycztcclxuXHJcblx0XHRpZiAoaGFzQ2xhc3MocHJlLCBMSU5FX05VTUJFUlNfQ0xBU1MpICYmIGhhc0xpbmVOdW1iZXJzICYmICFpc0xpbmVOdW1iZXJzTG9hZGVkKSB7XHJcblx0XHRcdFByaXNtLmhvb2tzLmFkZCgnbGluZS1udW1iZXJzJywgY29tcGxldGVIb29rKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHZhciBtdXRhdGVEb20gPSBQcmlzbS5wbHVnaW5zLmxpbmVIaWdobGlnaHQuaGlnaGxpZ2h0TGluZXMocHJlKTtcclxuXHRcdFx0bXV0YXRlRG9tKCk7XHJcblx0XHRcdGZha2VUaW1lciA9IHNldFRpbWVvdXQoYXBwbHlIYXNoLCAxKTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHJcblx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2hhc2hjaGFuZ2UnLCBhcHBseUhhc2gpO1xyXG5cdC8vIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBmdW5jdGlvbiAoKSB7XHJcblx0Ly8gXHR2YXIgYWN0aW9ucyA9ICQkKCdwcmUnKVxyXG5cdC8vIFx0XHQuZmlsdGVyKGlzQWN0aXZlRm9yKVxyXG5cdC8vIFx0XHQubWFwKGZ1bmN0aW9uIChwcmUpIHtcclxuXHQvLyBcdFx0XHRyZXR1cm4gUHJpc20ucGx1Z2lucy5saW5lSGlnaGxpZ2h0LmhpZ2hsaWdodExpbmVzKHByZSk7XHJcblx0Ly8gXHRcdH0pO1xyXG5cdC8vIFx0YWN0aW9ucy5mb3JFYWNoKGNhbGxGdW5jdGlvbik7XHJcblx0Ly8gfSk7XHJcblxyXG59XHJcbiIsICJpbXBvcnQgeyBWaWV3UGx1Z2luLCBWaWV3VXBkYXRlLCBFZGl0b3JWaWV3LCBEZWNvcmF0aW9uU2V0LCBEZWNvcmF0aW9uLCBXaWRnZXRUeXBlIH0gZnJvbSAnQGNvZGVtaXJyb3IvdmlldydcclxuLy8gQHRzLWlnbm9yZVxyXG5pbXBvcnQgeyBSYW5nZVNldEJ1aWxkZXIgfSBmcm9tICdAY29kZW1pcnJvci9zdGF0ZSdcclxuLy8gQHRzLWlnbm9yZVxyXG5pbXBvcnQgeyBzeW50YXhUcmVlLCBsaW5lQ2xhc3NOb2RlUHJvcCB9IGZyb20gJ0Bjb2RlbWlycm9yL2xhbmd1YWdlJ1xyXG4vLyBpbXBvcnQgeyBsaW5lQ2xhc3NOb2RlUHJvcCB9IGZyb20gJ0Bjb2RlbWlycm9yL3N0cmVhbS1wYXJzZXInXHJcbmltcG9ydCB7IGJyYWNlU3Vycm91bmRpbmdSZWdleCwgcGFyYW1SZWdleCB9IGZyb20gJy4vdXRpbCdcclxuXHJcbmludGVyZmFjZSBDb2RlYmxvY2tJbmZvIHtcclxuICBzaG93TGluZU51bWJlcnM6IGJvb2xlYW47XHJcbiAgaGlnaGxpZ2h0TGluZXM6IG51bWJlcltdIHwgbnVsbDtcclxufVxyXG5cclxuY2xhc3MgTGluZU51bWJlcldpZGdldCBleHRlbmRzIFdpZGdldFR5cGUge1xyXG4gIGlkeDogbnVtYmVyO1xyXG5cclxuICBjb25zdHJ1Y3RvcihpZHg6IG51bWJlcikge1xyXG4gICAgc3VwZXIoKTtcclxuICAgIHRoaXMuaWR4ID0gaWR4XHJcbiAgfVxyXG5cclxuICB0b0RPTSgpIHtcclxuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xyXG4gICAgZWwuY2xhc3NOYW1lID0gJ2xpdmUtcHJldmlldy1jb2RlYmxvY2stbGluZS1udW1zJztcclxuICAgIGVsLnRleHRDb250ZW50ID0gJycgKyB0aGlzLmlkeDtcclxuICAgIHJldHVybiBlbDtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBsaXZlUHJldmlld0NNNkV4dGVuc2lvbiA9IFZpZXdQbHVnaW4uZnJvbUNsYXNzKGNsYXNzIHtcclxuICBkZWNvcmF0aW9uczogRGVjb3JhdGlvblNldFxyXG5cclxuICBjb25zdHJ1Y3Rvcih2aWV3OiBFZGl0b3JWaWV3KSB7XHJcbiAgICB0aGlzLmRlY29yYXRpb25zID0gdGhpcy5idWlsZERlY29yYXRpb25zKHZpZXcpO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlKHVwZGF0ZTogVmlld1VwZGF0ZSkge1xyXG4gICAgaWYgKHVwZGF0ZS5kb2NDaGFuZ2VkIHx8IHVwZGF0ZS52aWV3cG9ydENoYW5nZWQpIHRoaXMuZGVjb3JhdGlvbnMgPSB0aGlzLmJ1aWxkRGVjb3JhdGlvbnModXBkYXRlLnZpZXcpO1xyXG4gIH1cclxuXHJcbiAgZGVzdG9yeSgpIHt9XHJcblxyXG4gIGJ1aWxkRGVjb3JhdGlvbnModmlldzogRWRpdG9yVmlldykge1xyXG4gICAgY29uc3QgYnVpbGRlciA9IG5ldyBSYW5nZVNldEJ1aWxkZXI8RGVjb3JhdGlvbj4oKTtcclxuICAgIGNvbnN0IGNvZGVibG9ja0luZm86IENvZGVibG9ja0luZm8gPSB7XHJcbiAgICAgIHNob3dMaW5lTnVtYmVyczogZmFsc2UsXHJcbiAgICAgIGhpZ2hsaWdodExpbmVzOiBudWxsLFxyXG4gICAgfVxyXG4gICAgbGV0IHN0YXJ0TGluZU51bTogbnVtYmVyO1xyXG5cclxuICAgIGZvciAoY29uc3Qge2Zyb20sIHRvfSBvZiB2aWV3LnZpc2libGVSYW5nZXMpIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCB0cmVlID0gc3ludGF4VHJlZSh2aWV3LnN0YXRlKVxyXG5cclxuICAgICAgICB0cmVlLml0ZXJhdGUoe1xyXG4gICAgICAgICAgZnJvbSwgdG8sXHJcbiAgICAgICAgICAvLyBAdHMtaWdub3JlXHJcbiAgICAgICAgICBlbnRlcjogKHt0eXBlLCBmcm9tLCB0b30pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgbGluZUNsYXNzZXMgPSB0eXBlLnByb3AobGluZUNsYXNzTm9kZVByb3ApXHJcblxyXG4gICAgICAgICAgICBpZiAoIWxpbmVDbGFzc2VzKSByZXR1cm4gO1xyXG4gICAgICAgICAgICBjb25zdCBjbGFzc2VzID0gbmV3IFNldChsaW5lQ2xhc3Nlcy5zcGxpdCgnICcpKTtcclxuICAgICAgICAgICAgY29uc3QgaXNDb2RlYmxvY2tCZWdpbiA9IGNsYXNzZXMuaGFzKCdIeXBlck1ELWNvZGVibG9jay1iZWdpbicpO1xyXG4gICAgICAgICAgICBjb25zdCBpc0NvZGVibG9ja0xpbmUgPSBcclxuICAgICAgICAgICAgICBjbGFzc2VzLmhhcygnSHlwZXJNRC1jb2RlYmxvY2stYmcnKSBcclxuICAgICAgICAgICAgICAmJiAhY2xhc3Nlcy5oYXMoJ0h5cGVyTUQtY29kZWJsb2NrLWJlZ2luJylcclxuICAgICAgICAgICAgICAmJiAhY2xhc3Nlcy5oYXMoJ0h5cGVyTUQtY29kZWJsb2NrLWVuZCcpO1xyXG5cclxuICAgICAgICAgICAgLy8gcmVzZXQgZGF0YSB3aGVuIGZvdW5kIGNvZGVibG9jayBiZWdpbiBsaW5lLlxyXG4gICAgICAgICAgICBpZiAoaXNDb2RlYmxvY2tCZWdpbikge1xyXG4gICAgICAgICAgICAgIGNvbnN0IHN0YXJ0TGluZSA9IHZpZXcuc3RhdGUuZG9jLmxpbmVBdChmcm9tKTtcclxuICAgICAgICAgICAgICBjb25zdCBjb2RlYmxvY2tQYXJhbXMgPSBzdGFydExpbmUudGV4dC5tYXRjaChwYXJhbVJlZ2V4KS5zbGljZSgxKTtcclxuICAgICAgICAgICAgICBjb25zdCBoaWdobGlnaHRQYXJhbSA9IGNvZGVibG9ja1BhcmFtcy5maW5kKChwYXJhbSkgPT4gYnJhY2VTdXJyb3VuZGluZ1JlZ2V4LnRlc3QocGFyYW0pKT8uc2xpY2UoMSwgLTEpO1xyXG5cclxuICAgICAgICAgICAgICBzdGFydExpbmVOdW0gPSBzdGFydExpbmUubnVtYmVyO1xyXG4gICAgICAgICAgICAgIGNvZGVibG9ja0luZm8uc2hvd0xpbmVOdW1iZXJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgY29kZWJsb2NrSW5mby5oaWdobGlnaHRMaW5lcyA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICAgIGlmIChjb2RlYmxvY2tQYXJhbXMuaW5jbHVkZXMoJ251bXMnKSkgY29kZWJsb2NrSW5mby5zaG93TGluZU51bWJlcnMgPSB0cnVlO1xyXG4gICAgICAgICAgICAgIGlmIChoaWdobGlnaHRQYXJhbSkgY29kZWJsb2NrSW5mby5oaWdobGlnaHRMaW5lcyA9IGhpZ2hsaWdodFBhcmFtLnJlcGxhY2UoJyAnLCAnJykuc3BsaXQoJywnKS5mbGF0TWFwKChsaW5lKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIStsaW5lKSB7XHJcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICBjb25zdCBbc3RhcnQsIGVuZF0gPSBsaW5lLnNwbGl0KCctJyk7XHJcbiAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSArc3RhcnQ7IGkgPD0gK2VuZDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzLnB1c2goaSk7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgIHJldHVybiByZXM7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFsrbGluZV07XHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghaXNDb2RlYmxvY2tMaW5lKSByZXR1cm4gO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudExpbmVOdW0gPSB2aWV3LnN0YXRlLmRvYy5saW5lQXQoZnJvbSkubnVtYmVyO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvZGVibG9ja0luZm8uc2hvd0xpbmVOdW1iZXJzKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgZGVjbyA9IERlY29yYXRpb24ud2lkZ2V0KHtcclxuICAgICAgICAgICAgICAgIHdpZGdldDogbmV3IExpbmVOdW1iZXJXaWRnZXQoY3VycmVudExpbmVOdW0gLSBzdGFydExpbmVOdW0pLFxyXG4gICAgICAgICAgICAgICAgc2lkZTogLTEwMDAwXHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgYnVpbGRlci5hZGQoZnJvbSwgZnJvbSwgZGVjbyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChjb2RlYmxvY2tJbmZvLmhpZ2hsaWdodExpbmVzKSB7XHJcbiAgICAgICAgICAgICAgaWYgKGNvZGVibG9ja0luZm8uaGlnaGxpZ2h0TGluZXMuaW5jbHVkZXMoY3VycmVudExpbmVOdW0gLSBzdGFydExpbmVOdW0pKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBsaW5lID0gdmlldy5zdGF0ZS5kb2MubGluZUF0KGZyb20pO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGVjbyA9IERlY29yYXRpb24ubGluZSh7XHJcbiAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtjbGFzczogJ2xpdmUtcHJldmlldy1jb2RlYmxvY2staGlnaGxpZ2h0J31cclxuICAgICAgICAgICAgICAgIH0pXHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgICAgICAgICAgICAgaWYgKGJ1aWxkZXIubGFzdD8uc3RhcnRTaWRlKSB7XHJcbiAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcclxuICAgICAgICAgICAgICAgICAgZGVjby5zdGFydFNpZGUgPSBidWlsZGVyLmxhc3Quc3RhcnRTaWRlO1xyXG4gICAgICAgICAgICAgICAgICBkZWNvLmVuZFNpZGUgPSBkZWNvLnN0YXJ0U2lkZVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGJ1aWxkZXIuYWRkKGxpbmUuZnJvbSwgbGluZS5mcm9tLCBkZWNvKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGVycm9yKVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGJ1aWxkZXIuZmluaXNoKCk7XHJcbiAgfVxyXG59LCBcclxu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