From 8c84faecd39f526a2c49c1029868b0904addcb45 Mon Sep 17 00:00:00 2001
From: Lost Paul <70213368+LostPaul@users.noreply.github.com>
Date: Tue, 1 Aug 2023 21:42:33 +0200
Subject: [PATCH 1/2] Create main.js
---
main.js | 4250 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 4250 insertions(+)
create mode 100644 main.js
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..9d02e2e
--- /dev/null
+++ b/main.js
@@ -0,0 +1,4250 @@
+/*
+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 __commonJS = (cb, mod) => function __require() {
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+};
+var __export = (target, all) => {
+ for (var name in all)
+ __defProp(target, name, { get: all[name], enumerable: true });
+};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
+var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
+
+// node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js
+var require_Api = __commonJS({
+ "node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js"(exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ }
+});
+
+// node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js
+var require_EventDispatcher = __commonJS({
+ "node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js"(exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ }
+});
+
+// node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js
+var require_Resolver = __commonJS({
+ "node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js"(exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ }
+});
+
+// node_modules/front-matter-plugin-api-provider/lib/index.js
+var require_lib = __commonJS({
+ "node_modules/front-matter-plugin-api-provider/lib/index.js"(exports) {
+ "use strict";
+ var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
+ if (k2 === void 0)
+ k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() {
+ return m[k];
+ } };
+ }
+ Object.defineProperty(o, k2, desc);
+ } : function(o, m, k, k2) {
+ if (k2 === void 0)
+ k2 = k;
+ o[k2] = m[k];
+ });
+ var __exportStar = exports && exports.__exportStar || function(m, exports2) {
+ for (var p in m)
+ if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
+ __createBinding(exports2, m, p);
+ };
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.getApiSafe = exports.getDefer = exports.isPluginEnabled = exports.PluginNotEnabledError = exports.pluginId = void 0;
+ __exportStar(require_Api(), exports);
+ __exportStar(require_EventDispatcher(), exports);
+ __exportStar(require_Resolver(), exports);
+ exports.pluginId = "obsidian-front-matter-title-plugin";
+ var PluginNotEnabledError = class extends Error {
+ };
+ exports.PluginNotEnabledError = PluginNotEnabledError;
+ function isPluginEnabled(app2) {
+ var _a, _b, _c;
+ return (_c = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.enabledPlugins) === null || _b === void 0 ? void 0 : _b.has(exports.pluginId)) !== null && _c !== void 0 ? _c : false;
+ }
+ exports.isPluginEnabled = isPluginEnabled;
+ function getDefer2(app2) {
+ var _a, _b, _c, _d;
+ const plugin = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.getPlugin(exports.pluginId)) !== null && _b !== void 0 ? _b : null;
+ const defer = (_d = (_c = plugin === null || plugin === void 0 ? void 0 : plugin.getDefer) === null || _c === void 0 ? void 0 : _c.call(plugin)) !== null && _d !== void 0 ? _d : null;
+ if (defer === null) {
+ throw new PluginNotEnabledError(`Plugin ${exports.pluginId} is not enabled or old version`);
+ }
+ return defer;
+ }
+ exports.getDefer = getDefer2;
+ function getApiSafe(app2) {
+ return new ApiWrapper(null, app2);
+ }
+ exports.getApiSafe = getApiSafe;
+ var ApiWrapper = class {
+ constructor(api, app2) {
+ this.api = api;
+ this.app = app2;
+ }
+ before() {
+ if (this.api !== null) {
+ return;
+ }
+ const defer = this.getDeffer();
+ if (defer === null) {
+ return;
+ }
+ const api = defer.getApi();
+ if (api === null) {
+ return defer.awaitPlugin().then(() => {
+ this.api = defer.getApi();
+ });
+ } else {
+ this.api = api;
+ }
+ }
+ getDeffer() {
+ try {
+ return getDefer2(this.app);
+ } catch (e) {
+ if (e instanceof PluginNotEnabledError) {
+ return null;
+ }
+ throw e;
+ }
+ }
+ getResolverFactory() {
+ var _a, _b;
+ this.before();
+ return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getResolverFactory()) !== null && _b !== void 0 ? _b : null;
+ }
+ getEventDispatcher() {
+ var _a, _b;
+ this.before();
+ return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEventDispatcher()) !== null && _b !== void 0 ? _b : null;
+ }
+ getEnabledFeatures() {
+ var _a, _b;
+ this.before();
+ return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEnabledFeatures()) !== null && _b !== void 0 ? _b : [];
+ }
+ };
+ }
+});
+
+// src/main.ts
+var main_exports = {};
+__export(main_exports, {
+ default: () => FolderNotesPlugin
+});
+module.exports = __toCommonJS(main_exports);
+var import_obsidian19 = require("obsidian");
+
+// src/settings.ts
+var import_obsidian12 = require("obsidian");
+
+// src/suggesters/templateSuggester.ts
+var import_obsidian3 = require("obsidian");
+
+// src/suggesters/suggest.ts
+var import_obsidian = require("obsidian");
+
+// node_modules/@popperjs/core/lib/enums.js
+var top = "top";
+var bottom = "bottom";
+var right = "right";
+var left = "left";
+var auto = "auto";
+var basePlacements = [top, bottom, right, left];
+var start = "start";
+var end = "end";
+var clippingParents = "clippingParents";
+var viewport = "viewport";
+var popper = "popper";
+var reference = "reference";
+var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) {
+ return acc.concat([placement + "-" + start, placement + "-" + end]);
+}, []);
+var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) {
+ return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
+}, []);
+var beforeRead = "beforeRead";
+var read = "read";
+var afterRead = "afterRead";
+var beforeMain = "beforeMain";
+var main = "main";
+var afterMain = "afterMain";
+var beforeWrite = "beforeWrite";
+var write = "write";
+var afterWrite = "afterWrite";
+var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];
+
+// node_modules/@popperjs/core/lib/dom-utils/getNodeName.js
+function getNodeName(element) {
+ return element ? (element.nodeName || "").toLowerCase() : null;
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getWindow.js
+function getWindow(node) {
+ if (node == null) {
+ return window;
+ }
+ if (node.toString() !== "[object Window]") {
+ var ownerDocument = node.ownerDocument;
+ return ownerDocument ? ownerDocument.defaultView || window : window;
+ }
+ return node;
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/instanceOf.js
+function isElement(node) {
+ var OwnElement = getWindow(node).Element;
+ return node instanceof OwnElement || node instanceof Element;
+}
+function isHTMLElement(node) {
+ var OwnElement = getWindow(node).HTMLElement;
+ return node instanceof OwnElement || node instanceof HTMLElement;
+}
+function isShadowRoot(node) {
+ if (typeof ShadowRoot === "undefined") {
+ return false;
+ }
+ var OwnElement = getWindow(node).ShadowRoot;
+ return node instanceof OwnElement || node instanceof ShadowRoot;
+}
+
+// node_modules/@popperjs/core/lib/modifiers/applyStyles.js
+function applyStyles(_ref) {
+ var state = _ref.state;
+ Object.keys(state.elements).forEach(function(name) {
+ var style = state.styles[name] || {};
+ var attributes = state.attributes[name] || {};
+ var element = state.elements[name];
+ if (!isHTMLElement(element) || !getNodeName(element)) {
+ return;
+ }
+ Object.assign(element.style, style);
+ Object.keys(attributes).forEach(function(name2) {
+ var value = attributes[name2];
+ if (value === false) {
+ element.removeAttribute(name2);
+ } else {
+ element.setAttribute(name2, value === true ? "" : value);
+ }
+ });
+ });
+}
+function effect(_ref2) {
+ var state = _ref2.state;
+ var initialStyles = {
+ popper: {
+ position: state.options.strategy,
+ left: "0",
+ top: "0",
+ margin: "0"
+ },
+ arrow: {
+ position: "absolute"
+ },
+ reference: {}
+ };
+ Object.assign(state.elements.popper.style, initialStyles.popper);
+ state.styles = initialStyles;
+ if (state.elements.arrow) {
+ Object.assign(state.elements.arrow.style, initialStyles.arrow);
+ }
+ return function() {
+ Object.keys(state.elements).forEach(function(name) {
+ var element = state.elements[name];
+ var attributes = state.attributes[name] || {};
+ var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]);
+ var style = styleProperties.reduce(function(style2, property) {
+ style2[property] = "";
+ return style2;
+ }, {});
+ if (!isHTMLElement(element) || !getNodeName(element)) {
+ return;
+ }
+ Object.assign(element.style, style);
+ Object.keys(attributes).forEach(function(attribute) {
+ element.removeAttribute(attribute);
+ });
+ });
+ };
+}
+var applyStyles_default = {
+ name: "applyStyles",
+ enabled: true,
+ phase: "write",
+ fn: applyStyles,
+ effect,
+ requires: ["computeStyles"]
+};
+
+// node_modules/@popperjs/core/lib/utils/getBasePlacement.js
+function getBasePlacement(placement) {
+ return placement.split("-")[0];
+}
+
+// node_modules/@popperjs/core/lib/utils/math.js
+var max = Math.max;
+var min = Math.min;
+var round = Math.round;
+
+// node_modules/@popperjs/core/lib/utils/userAgent.js
+function getUAString() {
+ var uaData = navigator.userAgentData;
+ if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {
+ return uaData.brands.map(function(item) {
+ return item.brand + "/" + item.version;
+ }).join(" ");
+ }
+ return navigator.userAgent;
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js
+function isLayoutViewport() {
+ return !/^((?!chrome|android).)*safari/i.test(getUAString());
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js
+function getBoundingClientRect(element, includeScale, isFixedStrategy) {
+ if (includeScale === void 0) {
+ includeScale = false;
+ }
+ if (isFixedStrategy === void 0) {
+ isFixedStrategy = false;
+ }
+ var clientRect = element.getBoundingClientRect();
+ var scaleX = 1;
+ var scaleY = 1;
+ if (includeScale && isHTMLElement(element)) {
+ scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
+ scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
+ }
+ var _ref = isElement(element) ? getWindow(element) : window, visualViewport = _ref.visualViewport;
+ var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
+ var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;
+ var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;
+ var width = clientRect.width / scaleX;
+ var height = clientRect.height / scaleY;
+ return {
+ width,
+ height,
+ top: y,
+ right: x + width,
+ bottom: y + height,
+ left: x,
+ x,
+ y
+ };
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js
+function getLayoutRect(element) {
+ var clientRect = getBoundingClientRect(element);
+ var width = element.offsetWidth;
+ var height = element.offsetHeight;
+ if (Math.abs(clientRect.width - width) <= 1) {
+ width = clientRect.width;
+ }
+ if (Math.abs(clientRect.height - height) <= 1) {
+ height = clientRect.height;
+ }
+ return {
+ x: element.offsetLeft,
+ y: element.offsetTop,
+ width,
+ height
+ };
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/contains.js
+function contains(parent, child) {
+ var rootNode = child.getRootNode && child.getRootNode();
+ if (parent.contains(child)) {
+ return true;
+ } else if (rootNode && isShadowRoot(rootNode)) {
+ var next = child;
+ do {
+ if (next && parent.isSameNode(next)) {
+ return true;
+ }
+ next = next.parentNode || next.host;
+ } while (next);
+ }
+ return false;
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js
+function getComputedStyle(element) {
+ return getWindow(element).getComputedStyle(element);
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/isTableElement.js
+function isTableElement(element) {
+ return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0;
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js
+function getDocumentElement(element) {
+ return ((isElement(element) ? element.ownerDocument : element.document) || window.document).documentElement;
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getParentNode.js
+function getParentNode(element) {
+ if (getNodeName(element) === "html") {
+ return element;
+ }
+ return element.assignedSlot || element.parentNode || (isShadowRoot(element) ? element.host : null) || getDocumentElement(element);
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js
+function getTrueOffsetParent(element) {
+ if (!isHTMLElement(element) || getComputedStyle(element).position === "fixed") {
+ return null;
+ }
+ return element.offsetParent;
+}
+function getContainingBlock(element) {
+ var isFirefox = /firefox/i.test(getUAString());
+ var isIE = /Trident/i.test(getUAString());
+ if (isIE && isHTMLElement(element)) {
+ var elementCss = getComputedStyle(element);
+ if (elementCss.position === "fixed") {
+ return null;
+ }
+ }
+ var currentNode = getParentNode(element);
+ if (isShadowRoot(currentNode)) {
+ currentNode = currentNode.host;
+ }
+ while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) {
+ var css = getComputedStyle(currentNode);
+ if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") {
+ return currentNode;
+ } else {
+ currentNode = currentNode.parentNode;
+ }
+ }
+ return null;
+}
+function getOffsetParent(element) {
+ var window2 = getWindow(element);
+ var offsetParent = getTrueOffsetParent(element);
+ while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === "static") {
+ offsetParent = getTrueOffsetParent(offsetParent);
+ }
+ if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle(offsetParent).position === "static")) {
+ return window2;
+ }
+ return offsetParent || getContainingBlock(element) || window2;
+}
+
+// node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js
+function getMainAxisFromPlacement(placement) {
+ return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y";
+}
+
+// node_modules/@popperjs/core/lib/utils/within.js
+function within(min2, value, max2) {
+ return max(min2, min(value, max2));
+}
+function withinMaxClamp(min2, value, max2) {
+ var v = within(min2, value, max2);
+ return v > max2 ? max2 : v;
+}
+
+// node_modules/@popperjs/core/lib/utils/getFreshSideObject.js
+function getFreshSideObject() {
+ return {
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0
+ };
+}
+
+// node_modules/@popperjs/core/lib/utils/mergePaddingObject.js
+function mergePaddingObject(paddingObject) {
+ return Object.assign({}, getFreshSideObject(), paddingObject);
+}
+
+// node_modules/@popperjs/core/lib/utils/expandToHashMap.js
+function expandToHashMap(value, keys) {
+ return keys.reduce(function(hashMap, key) {
+ hashMap[key] = value;
+ return hashMap;
+ }, {});
+}
+
+// node_modules/@popperjs/core/lib/modifiers/arrow.js
+var toPaddingObject = function toPaddingObject2(padding, state) {
+ padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, {
+ placement: state.placement
+ })) : padding;
+ return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements));
+};
+function arrow(_ref) {
+ var _state$modifiersData$;
+ var state = _ref.state, name = _ref.name, options = _ref.options;
+ var arrowElement = state.elements.arrow;
+ var popperOffsets2 = state.modifiersData.popperOffsets;
+ var basePlacement = getBasePlacement(state.placement);
+ var axis = getMainAxisFromPlacement(basePlacement);
+ var isVertical = [left, right].indexOf(basePlacement) >= 0;
+ var len = isVertical ? "height" : "width";
+ if (!arrowElement || !popperOffsets2) {
+ return;
+ }
+ var paddingObject = toPaddingObject(options.padding, state);
+ var arrowRect = getLayoutRect(arrowElement);
+ var minProp = axis === "y" ? top : left;
+ var maxProp = axis === "y" ? bottom : right;
+ var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len];
+ var startDiff = popperOffsets2[axis] - state.rects.reference[axis];
+ var arrowOffsetParent = getOffsetParent(arrowElement);
+ var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
+ var centerToReference = endDiff / 2 - startDiff / 2;
+ var min2 = paddingObject[minProp];
+ var max2 = clientSize - arrowRect[len] - paddingObject[maxProp];
+ var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
+ var offset2 = within(min2, center, max2);
+ var axisProp = axis;
+ state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$);
+}
+function effect2(_ref2) {
+ var state = _ref2.state, options = _ref2.options;
+ var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element;
+ if (arrowElement == null) {
+ return;
+ }
+ if (typeof arrowElement === "string") {
+ arrowElement = state.elements.popper.querySelector(arrowElement);
+ if (!arrowElement) {
+ return;
+ }
+ }
+ if (!contains(state.elements.popper, arrowElement)) {
+ return;
+ }
+ state.elements.arrow = arrowElement;
+}
+var arrow_default = {
+ name: "arrow",
+ enabled: true,
+ phase: "main",
+ fn: arrow,
+ effect: effect2,
+ requires: ["popperOffsets"],
+ requiresIfExists: ["preventOverflow"]
+};
+
+// node_modules/@popperjs/core/lib/utils/getVariation.js
+function getVariation(placement) {
+ return placement.split("-")[1];
+}
+
+// node_modules/@popperjs/core/lib/modifiers/computeStyles.js
+var unsetSides = {
+ top: "auto",
+ right: "auto",
+ bottom: "auto",
+ left: "auto"
+};
+function roundOffsetsByDPR(_ref, win) {
+ var x = _ref.x, y = _ref.y;
+ var dpr = win.devicePixelRatio || 1;
+ return {
+ x: round(x * dpr) / dpr || 0,
+ y: round(y * dpr) / dpr || 0
+ };
+}
+function mapToStyles(_ref2) {
+ var _Object$assign2;
+ var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed;
+ var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y;
+ var _ref3 = typeof roundOffsets === "function" ? roundOffsets({
+ x,
+ y
+ }) : {
+ x,
+ y
+ };
+ x = _ref3.x;
+ y = _ref3.y;
+ var hasX = offsets.hasOwnProperty("x");
+ var hasY = offsets.hasOwnProperty("y");
+ var sideX = left;
+ var sideY = top;
+ var win = window;
+ if (adaptive) {
+ var offsetParent = getOffsetParent(popper2);
+ var heightProp = "clientHeight";
+ var widthProp = "clientWidth";
+ if (offsetParent === getWindow(popper2)) {
+ offsetParent = getDocumentElement(popper2);
+ if (getComputedStyle(offsetParent).position !== "static" && position === "absolute") {
+ heightProp = "scrollHeight";
+ widthProp = "scrollWidth";
+ }
+ }
+ offsetParent = offsetParent;
+ if (placement === top || (placement === left || placement === right) && variation === end) {
+ sideY = bottom;
+ var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : offsetParent[heightProp];
+ y -= offsetY - popperRect.height;
+ y *= gpuAcceleration ? 1 : -1;
+ }
+ if (placement === left || (placement === top || placement === bottom) && variation === end) {
+ sideX = right;
+ var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : offsetParent[widthProp];
+ x -= offsetX - popperRect.width;
+ x *= gpuAcceleration ? 1 : -1;
+ }
+ }
+ var commonStyles = Object.assign({
+ position
+ }, adaptive && unsetSides);
+ var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
+ x,
+ y
+ }, getWindow(popper2)) : {
+ x,
+ y
+ };
+ x = _ref4.x;
+ y = _ref4.y;
+ if (gpuAcceleration) {
+ var _Object$assign;
+ return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
+ }
+ return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2));
+}
+function computeStyles(_ref5) {
+ var state = _ref5.state, options = _ref5.options;
+ var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
+ var commonStyles = {
+ placement: getBasePlacement(state.placement),
+ variation: getVariation(state.placement),
+ popper: state.elements.popper,
+ popperRect: state.rects.popper,
+ gpuAcceleration,
+ isFixed: state.options.strategy === "fixed"
+ };
+ if (state.modifiersData.popperOffsets != null) {
+ state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
+ offsets: state.modifiersData.popperOffsets,
+ position: state.options.strategy,
+ adaptive,
+ roundOffsets
+ })));
+ }
+ if (state.modifiersData.arrow != null) {
+ state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
+ offsets: state.modifiersData.arrow,
+ position: "absolute",
+ adaptive: false,
+ roundOffsets
+ })));
+ }
+ state.attributes.popper = Object.assign({}, state.attributes.popper, {
+ "data-popper-placement": state.placement
+ });
+}
+var computeStyles_default = {
+ name: "computeStyles",
+ enabled: true,
+ phase: "beforeWrite",
+ fn: computeStyles,
+ data: {}
+};
+
+// node_modules/@popperjs/core/lib/modifiers/eventListeners.js
+var passive = {
+ passive: true
+};
+function effect3(_ref) {
+ var state = _ref.state, instance = _ref.instance, options = _ref.options;
+ var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize;
+ var window2 = getWindow(state.elements.popper);
+ var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
+ if (scroll) {
+ scrollParents.forEach(function(scrollParent) {
+ scrollParent.addEventListener("scroll", instance.update, passive);
+ });
+ }
+ if (resize) {
+ window2.addEventListener("resize", instance.update, passive);
+ }
+ return function() {
+ if (scroll) {
+ scrollParents.forEach(function(scrollParent) {
+ scrollParent.removeEventListener("scroll", instance.update, passive);
+ });
+ }
+ if (resize) {
+ window2.removeEventListener("resize", instance.update, passive);
+ }
+ };
+}
+var eventListeners_default = {
+ name: "eventListeners",
+ enabled: true,
+ phase: "write",
+ fn: function fn() {
+ },
+ effect: effect3,
+ data: {}
+};
+
+// node_modules/@popperjs/core/lib/utils/getOppositePlacement.js
+var hash = {
+ left: "right",
+ right: "left",
+ bottom: "top",
+ top: "bottom"
+};
+function getOppositePlacement(placement) {
+ return placement.replace(/left|right|bottom|top/g, function(matched) {
+ return hash[matched];
+ });
+}
+
+// node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js
+var hash2 = {
+ start: "end",
+ end: "start"
+};
+function getOppositeVariationPlacement(placement) {
+ return placement.replace(/start|end/g, function(matched) {
+ return hash2[matched];
+ });
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js
+function getWindowScroll(node) {
+ var win = getWindow(node);
+ var scrollLeft = win.pageXOffset;
+ var scrollTop = win.pageYOffset;
+ return {
+ scrollLeft,
+ scrollTop
+ };
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js
+function getWindowScrollBarX(element) {
+ return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js
+function getViewportRect(element, strategy) {
+ var win = getWindow(element);
+ var html = getDocumentElement(element);
+ var visualViewport = win.visualViewport;
+ var width = html.clientWidth;
+ var height = html.clientHeight;
+ var x = 0;
+ var y = 0;
+ if (visualViewport) {
+ width = visualViewport.width;
+ height = visualViewport.height;
+ var layoutViewport = isLayoutViewport();
+ if (layoutViewport || !layoutViewport && strategy === "fixed") {
+ x = visualViewport.offsetLeft;
+ y = visualViewport.offsetTop;
+ }
+ }
+ return {
+ width,
+ height,
+ x: x + getWindowScrollBarX(element),
+ y
+ };
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js
+function getDocumentRect(element) {
+ var _element$ownerDocumen;
+ var html = getDocumentElement(element);
+ var winScroll = getWindowScroll(element);
+ var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
+ var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
+ var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
+ var x = -winScroll.scrollLeft + getWindowScrollBarX(element);
+ var y = -winScroll.scrollTop;
+ if (getComputedStyle(body || html).direction === "rtl") {
+ x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
+ }
+ return {
+ width,
+ height,
+ x,
+ y
+ };
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js
+function isScrollParent(element) {
+ var _getComputedStyle = getComputedStyle(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY;
+ return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js
+function getScrollParent(node) {
+ if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) {
+ return node.ownerDocument.body;
+ }
+ if (isHTMLElement(node) && isScrollParent(node)) {
+ return node;
+ }
+ return getScrollParent(getParentNode(node));
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js
+function listScrollParents(element, list) {
+ var _element$ownerDocumen;
+ if (list === void 0) {
+ list = [];
+ }
+ var scrollParent = getScrollParent(element);
+ var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
+ var win = getWindow(scrollParent);
+ var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
+ var updatedList = list.concat(target);
+ return isBody ? updatedList : updatedList.concat(listScrollParents(getParentNode(target)));
+}
+
+// node_modules/@popperjs/core/lib/utils/rectToClientRect.js
+function rectToClientRect(rect) {
+ return Object.assign({}, rect, {
+ left: rect.x,
+ top: rect.y,
+ right: rect.x + rect.width,
+ bottom: rect.y + rect.height
+ });
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js
+function getInnerBoundingClientRect(element, strategy) {
+ var rect = getBoundingClientRect(element, false, strategy === "fixed");
+ rect.top = rect.top + element.clientTop;
+ rect.left = rect.left + element.clientLeft;
+ rect.bottom = rect.top + element.clientHeight;
+ rect.right = rect.left + element.clientWidth;
+ rect.width = element.clientWidth;
+ rect.height = element.clientHeight;
+ rect.x = rect.left;
+ rect.y = rect.top;
+ return rect;
+}
+function getClientRectFromMixedType(element, clippingParent, strategy) {
+ return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
+}
+function getClippingParents(element) {
+ var clippingParents2 = listScrollParents(getParentNode(element));
+ var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle(element).position) >= 0;
+ var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
+ if (!isElement(clipperElement)) {
+ return [];
+ }
+ return clippingParents2.filter(function(clippingParent) {
+ return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body";
+ });
+}
+function getClippingRect(element, boundary, rootBoundary, strategy) {
+ var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary);
+ var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]);
+ var firstClippingParent = clippingParents2[0];
+ var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) {
+ var rect = getClientRectFromMixedType(element, clippingParent, strategy);
+ accRect.top = max(rect.top, accRect.top);
+ accRect.right = min(rect.right, accRect.right);
+ accRect.bottom = min(rect.bottom, accRect.bottom);
+ accRect.left = max(rect.left, accRect.left);
+ return accRect;
+ }, getClientRectFromMixedType(element, firstClippingParent, strategy));
+ clippingRect.width = clippingRect.right - clippingRect.left;
+ clippingRect.height = clippingRect.bottom - clippingRect.top;
+ clippingRect.x = clippingRect.left;
+ clippingRect.y = clippingRect.top;
+ return clippingRect;
+}
+
+// node_modules/@popperjs/core/lib/utils/computeOffsets.js
+function computeOffsets(_ref) {
+ var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement;
+ var basePlacement = placement ? getBasePlacement(placement) : null;
+ var variation = placement ? getVariation(placement) : null;
+ var commonX = reference2.x + reference2.width / 2 - element.width / 2;
+ var commonY = reference2.y + reference2.height / 2 - element.height / 2;
+ var offsets;
+ switch (basePlacement) {
+ case top:
+ offsets = {
+ x: commonX,
+ y: reference2.y - element.height
+ };
+ break;
+ case bottom:
+ offsets = {
+ x: commonX,
+ y: reference2.y + reference2.height
+ };
+ break;
+ case right:
+ offsets = {
+ x: reference2.x + reference2.width,
+ y: commonY
+ };
+ break;
+ case left:
+ offsets = {
+ x: reference2.x - element.width,
+ y: commonY
+ };
+ break;
+ default:
+ offsets = {
+ x: reference2.x,
+ y: reference2.y
+ };
+ }
+ var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;
+ if (mainAxis != null) {
+ var len = mainAxis === "y" ? "height" : "width";
+ switch (variation) {
+ case start:
+ offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2);
+ break;
+ case end:
+ offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2);
+ break;
+ default:
+ }
+ }
+ return offsets;
+}
+
+// node_modules/@popperjs/core/lib/utils/detectOverflow.js
+function detectOverflow(state, options) {
+ if (options === void 0) {
+ options = {};
+ }
+ var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$strategy = _options.strategy, strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding;
+ var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements));
+ var altContext = elementContext === popper ? reference : popper;
+ var popperRect = state.rects.popper;
+ var element = state.elements[altBoundary ? altContext : elementContext];
+ var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);
+ var referenceClientRect = getBoundingClientRect(state.elements.reference);
+ var popperOffsets2 = computeOffsets({
+ reference: referenceClientRect,
+ element: popperRect,
+ strategy: "absolute",
+ placement
+ });
+ var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2));
+ var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect;
+ var overflowOffsets = {
+ top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
+ bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
+ left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
+ right: elementClientRect.right - clippingClientRect.right + paddingObject.right
+ };
+ var offsetData = state.modifiersData.offset;
+ if (elementContext === popper && offsetData) {
+ var offset2 = offsetData[placement];
+ Object.keys(overflowOffsets).forEach(function(key) {
+ var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
+ var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x";
+ overflowOffsets[key] += offset2[axis] * multiply;
+ });
+ }
+ return overflowOffsets;
+}
+
+// node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js
+function computeAutoPlacement(state, options) {
+ if (options === void 0) {
+ options = {};
+ }
+ var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;
+ var variation = getVariation(placement);
+ var placements2 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) {
+ return getVariation(placement2) === variation;
+ }) : basePlacements;
+ var allowedPlacements = placements2.filter(function(placement2) {
+ return allowedAutoPlacements.indexOf(placement2) >= 0;
+ });
+ if (allowedPlacements.length === 0) {
+ allowedPlacements = placements2;
+ }
+ var overflows = allowedPlacements.reduce(function(acc, placement2) {
+ acc[placement2] = detectOverflow(state, {
+ placement: placement2,
+ boundary,
+ rootBoundary,
+ padding
+ })[getBasePlacement(placement2)];
+ return acc;
+ }, {});
+ return Object.keys(overflows).sort(function(a, b) {
+ return overflows[a] - overflows[b];
+ });
+}
+
+// node_modules/@popperjs/core/lib/modifiers/flip.js
+function getExpandedFallbackPlacements(placement) {
+ if (getBasePlacement(placement) === auto) {
+ return [];
+ }
+ var oppositePlacement = getOppositePlacement(placement);
+ return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
+}
+function flip(_ref) {
+ var state = _ref.state, options = _ref.options, name = _ref.name;
+ if (state.modifiersData[name]._skip) {
+ return;
+ }
+ var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements;
+ var preferredPlacement = state.options.placement;
+ var basePlacement = getBasePlacement(preferredPlacement);
+ var isBasePlacement = basePlacement === preferredPlacement;
+ var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
+ var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) {
+ return acc.concat(getBasePlacement(placement2) === auto ? computeAutoPlacement(state, {
+ placement: placement2,
+ boundary,
+ rootBoundary,
+ padding,
+ flipVariations,
+ allowedAutoPlacements
+ }) : placement2);
+ }, []);
+ var referenceRect = state.rects.reference;
+ var popperRect = state.rects.popper;
+ var checksMap = /* @__PURE__ */ new Map();
+ var makeFallbackChecks = true;
+ var firstFittingPlacement = placements2[0];
+ for (var i = 0; i < placements2.length; i++) {
+ var placement = placements2[i];
+ var _basePlacement = getBasePlacement(placement);
+ var isStartVariation = getVariation(placement) === start;
+ var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
+ var len = isVertical ? "width" : "height";
+ var overflow = detectOverflow(state, {
+ placement,
+ boundary,
+ rootBoundary,
+ altBoundary,
+ padding
+ });
+ var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;
+ if (referenceRect[len] > popperRect[len]) {
+ mainVariationSide = getOppositePlacement(mainVariationSide);
+ }
+ var altVariationSide = getOppositePlacement(mainVariationSide);
+ var checks = [];
+ if (checkMainAxis) {
+ checks.push(overflow[_basePlacement] <= 0);
+ }
+ if (checkAltAxis) {
+ checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
+ }
+ if (checks.every(function(check) {
+ return check;
+ })) {
+ firstFittingPlacement = placement;
+ makeFallbackChecks = false;
+ break;
+ }
+ checksMap.set(placement, checks);
+ }
+ if (makeFallbackChecks) {
+ var numberOfChecks = flipVariations ? 3 : 1;
+ var _loop = function _loop2(_i2) {
+ var fittingPlacement = placements2.find(function(placement2) {
+ var checks2 = checksMap.get(placement2);
+ if (checks2) {
+ return checks2.slice(0, _i2).every(function(check) {
+ return check;
+ });
+ }
+ });
+ if (fittingPlacement) {
+ firstFittingPlacement = fittingPlacement;
+ return "break";
+ }
+ };
+ for (var _i = numberOfChecks; _i > 0; _i--) {
+ var _ret = _loop(_i);
+ if (_ret === "break")
+ break;
+ }
+ }
+ if (state.placement !== firstFittingPlacement) {
+ state.modifiersData[name]._skip = true;
+ state.placement = firstFittingPlacement;
+ state.reset = true;
+ }
+}
+var flip_default = {
+ name: "flip",
+ enabled: true,
+ phase: "main",
+ fn: flip,
+ requiresIfExists: ["offset"],
+ data: {
+ _skip: false
+ }
+};
+
+// node_modules/@popperjs/core/lib/modifiers/hide.js
+function getSideOffsets(overflow, rect, preventedOffsets) {
+ if (preventedOffsets === void 0) {
+ preventedOffsets = {
+ x: 0,
+ y: 0
+ };
+ }
+ return {
+ top: overflow.top - rect.height - preventedOffsets.y,
+ right: overflow.right - rect.width + preventedOffsets.x,
+ bottom: overflow.bottom - rect.height + preventedOffsets.y,
+ left: overflow.left - rect.width - preventedOffsets.x
+ };
+}
+function isAnySideFullyClipped(overflow) {
+ return [top, right, bottom, left].some(function(side) {
+ return overflow[side] >= 0;
+ });
+}
+function hide(_ref) {
+ var state = _ref.state, name = _ref.name;
+ var referenceRect = state.rects.reference;
+ var popperRect = state.rects.popper;
+ var preventedOffsets = state.modifiersData.preventOverflow;
+ var referenceOverflow = detectOverflow(state, {
+ elementContext: "reference"
+ });
+ var popperAltOverflow = detectOverflow(state, {
+ altBoundary: true
+ });
+ var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
+ var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
+ var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
+ var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
+ state.modifiersData[name] = {
+ referenceClippingOffsets,
+ popperEscapeOffsets,
+ isReferenceHidden,
+ hasPopperEscaped
+ };
+ state.attributes.popper = Object.assign({}, state.attributes.popper, {
+ "data-popper-reference-hidden": isReferenceHidden,
+ "data-popper-escaped": hasPopperEscaped
+ });
+}
+var hide_default = {
+ name: "hide",
+ enabled: true,
+ phase: "main",
+ requiresIfExists: ["preventOverflow"],
+ fn: hide
+};
+
+// node_modules/@popperjs/core/lib/modifiers/offset.js
+function distanceAndSkiddingToXY(placement, rects, offset2) {
+ var basePlacement = getBasePlacement(placement);
+ var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
+ var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, {
+ placement
+ })) : offset2, skidding = _ref[0], distance = _ref[1];
+ skidding = skidding || 0;
+ distance = (distance || 0) * invertDistance;
+ return [left, right].indexOf(basePlacement) >= 0 ? {
+ x: distance,
+ y: skidding
+ } : {
+ x: skidding,
+ y: distance
+ };
+}
+function offset(_ref2) {
+ var state = _ref2.state, options = _ref2.options, name = _ref2.name;
+ var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset;
+ var data = placements.reduce(function(acc, placement) {
+ acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2);
+ return acc;
+ }, {});
+ var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y;
+ if (state.modifiersData.popperOffsets != null) {
+ state.modifiersData.popperOffsets.x += x;
+ state.modifiersData.popperOffsets.y += y;
+ }
+ state.modifiersData[name] = data;
+}
+var offset_default = {
+ name: "offset",
+ enabled: true,
+ phase: "main",
+ requires: ["popperOffsets"],
+ fn: offset
+};
+
+// node_modules/@popperjs/core/lib/modifiers/popperOffsets.js
+function popperOffsets(_ref) {
+ var state = _ref.state, name = _ref.name;
+ state.modifiersData[name] = computeOffsets({
+ reference: state.rects.reference,
+ element: state.rects.popper,
+ strategy: "absolute",
+ placement: state.placement
+ });
+}
+var popperOffsets_default = {
+ name: "popperOffsets",
+ enabled: true,
+ phase: "read",
+ fn: popperOffsets,
+ data: {}
+};
+
+// node_modules/@popperjs/core/lib/utils/getAltAxis.js
+function getAltAxis(axis) {
+ return axis === "x" ? "y" : "x";
+}
+
+// node_modules/@popperjs/core/lib/modifiers/preventOverflow.js
+function preventOverflow(_ref) {
+ var state = _ref.state, options = _ref.options, name = _ref.name;
+ var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
+ var overflow = detectOverflow(state, {
+ boundary,
+ rootBoundary,
+ padding,
+ altBoundary
+ });
+ var basePlacement = getBasePlacement(state.placement);
+ var variation = getVariation(state.placement);
+ var isBasePlacement = !variation;
+ var mainAxis = getMainAxisFromPlacement(basePlacement);
+ var altAxis = getAltAxis(mainAxis);
+ var popperOffsets2 = state.modifiersData.popperOffsets;
+ var referenceRect = state.rects.reference;
+ var popperRect = state.rects.popper;
+ var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, {
+ placement: state.placement
+ })) : tetherOffset;
+ var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? {
+ mainAxis: tetherOffsetValue,
+ altAxis: tetherOffsetValue
+ } : Object.assign({
+ mainAxis: 0,
+ altAxis: 0
+ }, tetherOffsetValue);
+ var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;
+ var data = {
+ x: 0,
+ y: 0
+ };
+ if (!popperOffsets2) {
+ return;
+ }
+ if (checkMainAxis) {
+ var _offsetModifierState$;
+ var mainSide = mainAxis === "y" ? top : left;
+ var altSide = mainAxis === "y" ? bottom : right;
+ var len = mainAxis === "y" ? "height" : "width";
+ var offset2 = popperOffsets2[mainAxis];
+ var min2 = offset2 + overflow[mainSide];
+ var max2 = offset2 - overflow[altSide];
+ var additive = tether ? -popperRect[len] / 2 : 0;
+ var minLen = variation === start ? referenceRect[len] : popperRect[len];
+ var maxLen = variation === start ? -popperRect[len] : -referenceRect[len];
+ var arrowElement = state.elements.arrow;
+ var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
+ width: 0,
+ height: 0
+ };
+ var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject();
+ var arrowPaddingMin = arrowPaddingObject[mainSide];
+ var arrowPaddingMax = arrowPaddingObject[altSide];
+ var arrowLen = within(0, referenceRect[len], arrowRect[len]);
+ var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;
+ var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;
+ var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
+ var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
+ var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;
+ var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset;
+ var tetherMax = offset2 + maxOffset - offsetModifierValue;
+ var preventedOffset = within(tether ? min(min2, tetherMin) : min2, offset2, tether ? max(max2, tetherMax) : max2);
+ popperOffsets2[mainAxis] = preventedOffset;
+ data[mainAxis] = preventedOffset - offset2;
+ }
+ if (checkAltAxis) {
+ var _offsetModifierState$2;
+ var _mainSide = mainAxis === "x" ? top : left;
+ var _altSide = mainAxis === "x" ? bottom : right;
+ var _offset = popperOffsets2[altAxis];
+ var _len = altAxis === "y" ? "height" : "width";
+ var _min = _offset + overflow[_mainSide];
+ var _max = _offset - overflow[_altSide];
+ var isOriginSide = [top, left].indexOf(basePlacement) !== -1;
+ var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;
+ var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;
+ var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;
+ var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);
+ popperOffsets2[altAxis] = _preventedOffset;
+ data[altAxis] = _preventedOffset - _offset;
+ }
+ state.modifiersData[name] = data;
+}
+var preventOverflow_default = {
+ name: "preventOverflow",
+ enabled: true,
+ phase: "main",
+ fn: preventOverflow,
+ requiresIfExists: ["offset"]
+};
+
+// node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js
+function getHTMLElementScroll(element) {
+ return {
+ scrollLeft: element.scrollLeft,
+ scrollTop: element.scrollTop
+ };
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js
+function getNodeScroll(node) {
+ if (node === getWindow(node) || !isHTMLElement(node)) {
+ return getWindowScroll(node);
+ } else {
+ return getHTMLElementScroll(node);
+ }
+}
+
+// node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js
+function isElementScaled(element) {
+ var rect = element.getBoundingClientRect();
+ var scaleX = round(rect.width) / element.offsetWidth || 1;
+ var scaleY = round(rect.height) / element.offsetHeight || 1;
+ return scaleX !== 1 || scaleY !== 1;
+}
+function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
+ if (isFixed === void 0) {
+ isFixed = false;
+ }
+ var isOffsetParentAnElement = isHTMLElement(offsetParent);
+ var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
+ var documentElement = getDocumentElement(offsetParent);
+ var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);
+ var scroll = {
+ scrollLeft: 0,
+ scrollTop: 0
+ };
+ var offsets = {
+ x: 0,
+ y: 0
+ };
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
+ if (getNodeName(offsetParent) !== "body" || isScrollParent(documentElement)) {
+ scroll = getNodeScroll(offsetParent);
+ }
+ if (isHTMLElement(offsetParent)) {
+ offsets = getBoundingClientRect(offsetParent, true);
+ offsets.x += offsetParent.clientLeft;
+ offsets.y += offsetParent.clientTop;
+ } else if (documentElement) {
+ offsets.x = getWindowScrollBarX(documentElement);
+ }
+ }
+ return {
+ x: rect.left + scroll.scrollLeft - offsets.x,
+ y: rect.top + scroll.scrollTop - offsets.y,
+ width: rect.width,
+ height: rect.height
+ };
+}
+
+// node_modules/@popperjs/core/lib/utils/orderModifiers.js
+function order(modifiers) {
+ var map = /* @__PURE__ */ new Map();
+ var visited = /* @__PURE__ */ new Set();
+ var result = [];
+ modifiers.forEach(function(modifier) {
+ map.set(modifier.name, modifier);
+ });
+ function sort(modifier) {
+ visited.add(modifier.name);
+ var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
+ requires.forEach(function(dep) {
+ if (!visited.has(dep)) {
+ var depModifier = map.get(dep);
+ if (depModifier) {
+ sort(depModifier);
+ }
+ }
+ });
+ result.push(modifier);
+ }
+ modifiers.forEach(function(modifier) {
+ if (!visited.has(modifier.name)) {
+ sort(modifier);
+ }
+ });
+ return result;
+}
+function orderModifiers(modifiers) {
+ var orderedModifiers = order(modifiers);
+ return modifierPhases.reduce(function(acc, phase) {
+ return acc.concat(orderedModifiers.filter(function(modifier) {
+ return modifier.phase === phase;
+ }));
+ }, []);
+}
+
+// node_modules/@popperjs/core/lib/utils/debounce.js
+function debounce(fn2) {
+ var pending;
+ return function() {
+ if (!pending) {
+ pending = new Promise(function(resolve) {
+ Promise.resolve().then(function() {
+ pending = void 0;
+ resolve(fn2());
+ });
+ });
+ }
+ return pending;
+ };
+}
+
+// node_modules/@popperjs/core/lib/utils/mergeByName.js
+function mergeByName(modifiers) {
+ var merged = modifiers.reduce(function(merged2, current) {
+ var existing = merged2[current.name];
+ merged2[current.name] = existing ? Object.assign({}, existing, current, {
+ options: Object.assign({}, existing.options, current.options),
+ data: Object.assign({}, existing.data, current.data)
+ }) : current;
+ return merged2;
+ }, {});
+ return Object.keys(merged).map(function(key) {
+ return merged[key];
+ });
+}
+
+// node_modules/@popperjs/core/lib/createPopper.js
+var DEFAULT_OPTIONS = {
+ placement: "bottom",
+ modifiers: [],
+ strategy: "absolute"
+};
+function areValidElements() {
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+ return !args.some(function(element) {
+ return !(element && typeof element.getBoundingClientRect === "function");
+ });
+}
+function popperGenerator(generatorOptions) {
+ if (generatorOptions === void 0) {
+ generatorOptions = {};
+ }
+ var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
+ return function createPopper2(reference2, popper2, options) {
+ if (options === void 0) {
+ options = defaultOptions;
+ }
+ var state = {
+ placement: "bottom",
+ orderedModifiers: [],
+ options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
+ modifiersData: {},
+ elements: {
+ reference: reference2,
+ popper: popper2
+ },
+ attributes: {},
+ styles: {}
+ };
+ var effectCleanupFns = [];
+ var isDestroyed = false;
+ var instance = {
+ state,
+ setOptions: function setOptions(setOptionsAction) {
+ var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction;
+ cleanupModifierEffects();
+ state.options = Object.assign({}, defaultOptions, state.options, options2);
+ state.scrollParents = {
+ reference: isElement(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [],
+ popper: listScrollParents(popper2)
+ };
+ var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers)));
+ state.orderedModifiers = orderedModifiers.filter(function(m) {
+ return m.enabled;
+ });
+ runModifierEffects();
+ return instance.update();
+ },
+ forceUpdate: function forceUpdate() {
+ if (isDestroyed) {
+ return;
+ }
+ var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper;
+ if (!areValidElements(reference3, popper3)) {
+ return;
+ }
+ state.rects = {
+ reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"),
+ popper: getLayoutRect(popper3)
+ };
+ state.reset = false;
+ state.placement = state.options.placement;
+ state.orderedModifiers.forEach(function(modifier) {
+ return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
+ });
+ for (var index = 0; index < state.orderedModifiers.length; index++) {
+ if (state.reset === true) {
+ state.reset = false;
+ index = -1;
+ continue;
+ }
+ var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name;
+ if (typeof fn2 === "function") {
+ state = fn2({
+ state,
+ options: _options,
+ name,
+ instance
+ }) || state;
+ }
+ }
+ },
+ update: debounce(function() {
+ return new Promise(function(resolve) {
+ instance.forceUpdate();
+ resolve(state);
+ });
+ }),
+ destroy: function destroy() {
+ cleanupModifierEffects();
+ isDestroyed = true;
+ }
+ };
+ if (!areValidElements(reference2, popper2)) {
+ return instance;
+ }
+ instance.setOptions(options).then(function(state2) {
+ if (!isDestroyed && options.onFirstUpdate) {
+ options.onFirstUpdate(state2);
+ }
+ });
+ function runModifierEffects() {
+ state.orderedModifiers.forEach(function(_ref) {
+ var name = _ref.name, _ref$options = _ref.options, options2 = _ref$options === void 0 ? {} : _ref$options, effect4 = _ref.effect;
+ if (typeof effect4 === "function") {
+ var cleanupFn = effect4({
+ state,
+ name,
+ instance,
+ options: options2
+ });
+ var noopFn = function noopFn2() {
+ };
+ effectCleanupFns.push(cleanupFn || noopFn);
+ }
+ });
+ }
+ function cleanupModifierEffects() {
+ effectCleanupFns.forEach(function(fn2) {
+ return fn2();
+ });
+ effectCleanupFns = [];
+ }
+ return instance;
+ };
+}
+
+// node_modules/@popperjs/core/lib/popper.js
+var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default, offset_default, flip_default, preventOverflow_default, arrow_default, hide_default];
+var createPopper = /* @__PURE__ */ popperGenerator({
+ defaultModifiers
+});
+
+// src/suggesters/suggest.ts
+var wrapAround = (value, size) => {
+ return (value % size + size) % size;
+};
+var Suggest = class {
+ constructor(owner, containerEl, scope) {
+ this.owner = owner;
+ this.containerEl = containerEl;
+ containerEl.on("click", ".suggestion-item", this.onSuggestionClick.bind(this));
+ containerEl.on("mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this));
+ scope.register([], "ArrowUp", (event) => {
+ if (!event.isComposing) {
+ this.setSelectedItem(this.selectedItem - 1, true);
+ return false;
+ }
+ });
+ scope.register([], "ArrowDown", (event) => {
+ if (!event.isComposing) {
+ this.setSelectedItem(this.selectedItem + 1, true);
+ return false;
+ }
+ });
+ scope.register([], "Enter", (event) => {
+ if (!event.isComposing) {
+ this.useSelectedItem(event);
+ return false;
+ }
+ });
+ }
+ onSuggestionClick(event, el) {
+ event.preventDefault();
+ const item = this.suggestions.indexOf(el);
+ this.setSelectedItem(item, false);
+ this.useSelectedItem(event);
+ }
+ onSuggestionMouseover(_event, el) {
+ const item = this.suggestions.indexOf(el);
+ this.setSelectedItem(item, false);
+ }
+ setSuggestions(values) {
+ this.containerEl.empty();
+ const suggestionEls = [];
+ values.forEach((value) => {
+ const suggestionEl = this.containerEl.createDiv("suggestion-item");
+ this.owner.renderSuggestion(value, suggestionEl);
+ suggestionEls.push(suggestionEl);
+ });
+ this.values = values;
+ this.suggestions = suggestionEls;
+ this.setSelectedItem(0, false);
+ }
+ useSelectedItem(event) {
+ const currentValue = this.values[this.selectedItem];
+ if (currentValue) {
+ this.owner.selectSuggestion(currentValue, event);
+ }
+ }
+ setSelectedItem(selectedIndex, scrollIntoView) {
+ const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length);
+ const prevSelectedSuggestion = this.suggestions[this.selectedItem];
+ const selectedSuggestion = this.suggestions[normalizedIndex];
+ prevSelectedSuggestion == null ? void 0 : prevSelectedSuggestion.removeClass("is-selected");
+ selectedSuggestion == null ? void 0 : selectedSuggestion.addClass("is-selected");
+ this.selectedItem = normalizedIndex;
+ if (scrollIntoView) {
+ selectedSuggestion.scrollIntoView(false);
+ }
+ }
+};
+var TextInputSuggest = class {
+ constructor(inputEl) {
+ this.inputEl = inputEl;
+ this.scope = new import_obsidian.Scope();
+ this.suggestEl = createDiv("suggestion-container");
+ const suggestion = this.suggestEl.createDiv("suggestion");
+ this.suggest = new Suggest(this, suggestion, this.scope);
+ this.scope.register([], "Escape", this.close.bind(this));
+ this.inputEl.addEventListener("input", this.onInputChanged.bind(this));
+ this.inputEl.addEventListener("focus", this.onInputChanged.bind(this));
+ this.inputEl.addEventListener("blur", this.close.bind(this));
+ this.suggestEl.on("mousedown", ".suggestion-container", (event) => {
+ event.preventDefault();
+ });
+ }
+ onInputChanged() {
+ const inputStr = this.inputEl.value;
+ const suggestions = this.getSuggestions(inputStr);
+ if (!suggestions) {
+ this.close();
+ return;
+ }
+ if (suggestions.length > 0) {
+ this.suggest.setSuggestions(suggestions);
+ this.open(app.dom.appContainerEl, this.inputEl);
+ } else {
+ this.close();
+ }
+ }
+ open(container, inputEl) {
+ app.keymap.pushScope(this.scope);
+ container.appendChild(this.suggestEl);
+ this.popper = createPopper(inputEl, this.suggestEl, {
+ placement: "bottom-start",
+ modifiers: [
+ {
+ name: "sameWidth",
+ enabled: true,
+ fn: ({ state, instance }) => {
+ const targetWidth = `${state.rects.reference.width}px`;
+ if (state.styles.popper.width === targetWidth) {
+ return;
+ }
+ state.styles.popper.width = targetWidth;
+ instance.update();
+ },
+ phase: "beforeWrite",
+ requires: ["computeStyles"]
+ }
+ ]
+ });
+ }
+ close() {
+ app.keymap.popScope(this.scope);
+ this.suggest.setSuggestions([]);
+ if (this.popper)
+ this.popper.destroy();
+ this.suggestEl.detach();
+ }
+};
+
+// src/template.ts
+var import_obsidian2 = require("obsidian");
+async function applyTemplate(plugin, file, templatePath) {
+ const templateFile = templatePath ? plugin.app.vault.getAbstractFileByPath(templatePath) : null;
+ if (templateFile && templateFile instanceof import_obsidian2.TFile) {
+ try {
+ const {
+ templatesEnabled,
+ templaterEnabled,
+ templatesPlugin,
+ templaterPlugin
+ } = getTemplatePlugins(plugin.app);
+ const templateContent = await plugin.app.vault.read(templateFile);
+ if (templatesEnabled && templaterEnabled) {
+ if (/<%/.test(templateContent)) {
+ return await templaterPlugin.write_template_to_file(templateFile, file);
+ }
+ return await templatesPlugin.instance.insertTemplate(templateFile);
+ }
+ if (templatesEnabled) {
+ return await templatesPlugin.instance.insertTemplate(templateFile);
+ }
+ if (templaterEnabled) {
+ return await templaterPlugin.write_template_to_file(templateFile, file);
+ }
+ } catch (e) {
+ console.error(e);
+ }
+ }
+}
+function getTemplatePlugins(app2) {
+ var _a;
+ const templatesPlugin = app2.internalPlugins.plugins.templates;
+ const templatesEnabled = templatesPlugin.enabled;
+ const templaterPlugin = app2.plugins.plugins["templater-obsidian"];
+ const templaterEnabled = app2.plugins.enabledPlugins.has("templater-obsidian");
+ const templaterEmptyFileTemplate = templaterPlugin && ((_a = this.app.plugins.plugins["templater-obsidian"].settings) == null ? void 0 : _a.empty_file_template);
+ const templateFolder = templatesEnabled ? templatesPlugin.instance.options.folder : templaterPlugin ? templaterPlugin.settings.template_folder : void 0;
+ return {
+ templatesPlugin,
+ templatesEnabled,
+ templaterPlugin: templaterPlugin == null ? void 0 : templaterPlugin.templater,
+ templaterEnabled,
+ templaterEmptyFileTemplate,
+ templateFolder
+ };
+}
+
+// src/suggesters/templateSuggester.ts
+var TemplateSuggest = class extends TextInputSuggest {
+ constructor(inputEl, plugin) {
+ super(inputEl);
+ this.inputEl = inputEl;
+ this.plugin = plugin;
+ }
+ get_error_msg(mode) {
+ switch (mode) {
+ case 0 /* TemplateFiles */:
+ return "Templates folder doesn't exist";
+ case 1 /* ScriptFiles */:
+ return "User Scripts folder doesn't exist";
+ }
+ }
+ getSuggestions(input_str) {
+ var _a, _b;
+ const { templateFolder, templaterPlugin } = getTemplatePlugins(this.plugin.app);
+ if ((!templateFolder || (templateFolder == null ? void 0 : templateFolder.trim()) === "") && !templaterPlugin) {
+ this.plugin.settings.templatePath = "";
+ this.plugin.saveSettings();
+ return [];
+ }
+ let folder;
+ if (templaterPlugin) {
+ folder = this.plugin.app.vault.getAbstractFileByPath((_b = (_a = templaterPlugin.plugin) == null ? void 0 : _a.settings) == null ? void 0 : _b.templates_folder);
+ } else {
+ folder = this.plugin.app.vault.getAbstractFileByPath(templateFolder);
+ }
+ const files = [];
+ const lower_input_str = input_str.toLowerCase();
+ import_obsidian3.Vault.recurseChildren(folder, (file) => {
+ if (file instanceof import_obsidian3.TFile && file.path.toLowerCase().contains(lower_input_str)) {
+ files.push(file);
+ }
+ });
+ return files;
+ }
+ renderSuggestion(file, el) {
+ el.setText(file.name.replace(".md", ""));
+ }
+ selectSuggestion(file) {
+ this.inputEl.value = file.name.replace(".md", "");
+ this.inputEl.trigger("input");
+ this.plugin.settings.templatePath = file.path;
+ this.plugin.saveSettings();
+ this.close();
+ }
+};
+
+// src/modals/existingNote.ts
+var import_obsidian4 = require("obsidian");
+var ExistingFolderNoteModal = class extends import_obsidian4.Modal {
+ constructor(app2, plugin, file, folder, folderNote) {
+ super(app2);
+ this.plugin = plugin;
+ this.app = app2;
+ this.file = file;
+ this.folder = folder;
+ this.folderNote = folderNote;
+ }
+ onOpen() {
+ var _a;
+ const { contentEl } = this;
+ contentEl.createEl("h2", { text: "A folder note for this folder already exists" });
+ const setting = new import_obsidian4.Setting(contentEl);
+ setting.infoEl.createEl("p", { text: "Are you sure you want to turn the note into a folder note and rename the existing folder note?" });
+ (_a = setting.infoEl.parentElement) == null ? void 0 : _a.classList.add("fn-delete-confirmation-modal");
+ const buttonContainer = setting.infoEl.createEl("div", { cls: "fn-delete-confirmation-modal-buttons" });
+ if (import_obsidian4.Platform.isMobileApp) {
+ const confirmButton = buttonContainer.createEl("button", { text: "Rename and don't ask again" });
+ confirmButton.classList.add("mod-warning", "fn-confirmation-modal-button");
+ confirmButton.addEventListener("click", async () => {
+ this.plugin.settings.showRenameConfirmation = false;
+ this.plugin.saveSettings();
+ this.close();
+ turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true);
+ });
+ } else {
+ const checkbox = buttonContainer.createEl("input", { type: "checkbox" });
+ checkbox.addEventListener("change", (e) => {
+ const target = e.target;
+ if (target.checked) {
+ this.plugin.settings.showRenameConfirmation = false;
+ } else {
+ this.plugin.settings.showRenameConfirmation = true;
+ }
+ });
+ const checkBoxText = buttonContainer.createEl("span", { text: "Don't ask again" });
+ checkBoxText.addEventListener("click", () => {
+ checkbox.click();
+ });
+ }
+ const button = buttonContainer.createEl("button", { text: "Rename" });
+ button.classList.add("mod-warning", "fn-confirmation-modal-button");
+ button.addEventListener("click", async () => {
+ this.plugin.saveSettings();
+ this.close();
+ turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true);
+ });
+ button.focus();
+ const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
+ cancelButton.addEventListener("click", async () => {
+ this.close();
+ });
+ }
+ onClose() {
+ const { contentEl } = this;
+ contentEl.empty();
+ }
+};
+
+// src/functions/folderNoteFunctions.ts
+var import_obsidian10 = require("obsidian");
+
+// src/modals/deleteConfirmation.ts
+var import_obsidian5 = require("obsidian");
+var DeleteConfirmationModal = class extends import_obsidian5.Modal {
+ constructor(app2, plugin, file) {
+ super(app2);
+ this.plugin = plugin;
+ this.app = app2;
+ this.file = file;
+ }
+ onOpen() {
+ var _a;
+ const { contentEl } = this;
+ contentEl.createEl("h2", { text: "Delete folder note" });
+ const setting = new import_obsidian5.Setting(contentEl);
+ setting.infoEl.createEl("p", { text: `Are you sure you want to delete the folder note "${this.file.name}" ?` });
+ setting.infoEl.createEl("p", { text: "It will be moved to your system trash." });
+ (_a = setting.infoEl.parentElement) == null ? void 0 : _a.classList.add("fn-delete-confirmation-modal");
+ const buttonContainer = setting.infoEl.createEl("div", { cls: "fn-delete-confirmation-modal-buttons" });
+ if (import_obsidian5.Platform.isMobileApp) {
+ const confirmButton = buttonContainer.createEl("button", { text: "Delete and don't ask again" });
+ confirmButton.classList.add("mod-warning", "fn-confirmation-modal-button");
+ confirmButton.addEventListener("click", async () => {
+ this.plugin.settings.showDeleteConfirmation = false;
+ this.plugin.saveSettings();
+ this.close();
+ const folder = getFolder(this.plugin, this.file);
+ if (!folder)
+ return;
+ this.plugin.removeCSSClassFromEL(folder == null ? void 0 : folder.path, "has-folder-note");
+ this.app.vault.delete(this.file);
+ });
+ } else {
+ const checkbox = buttonContainer.createEl("input", { type: "checkbox" });
+ checkbox.addEventListener("change", (e) => {
+ const target = e.target;
+ if (target.checked) {
+ this.plugin.settings.showDeleteConfirmation = false;
+ } else {
+ this.plugin.settings.showDeleteConfirmation = true;
+ }
+ this.plugin.saveSettings();
+ });
+ const checkBoxText = buttonContainer.createEl("span", { text: "Don't ask again" });
+ checkBoxText.addEventListener("click", () => {
+ checkbox.click();
+ });
+ }
+ const button = buttonContainer.createEl("button", { text: "Delete" });
+ button.classList.add("mod-warning", "fn-confirmation-modal-button");
+ button.addEventListener("click", async () => {
+ this.close();
+ const folder = getFolder(this.plugin, this.file);
+ if (!folder)
+ return;
+ this.plugin.removeCSSClassFromEL(folder.path, "has-folder-note");
+ this.app.vault.delete(this.file);
+ });
+ button.focus();
+ const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
+ cancelButton.addEventListener("click", async () => {
+ this.close();
+ });
+ }
+ onClose() {
+ const { contentEl } = this;
+ contentEl.empty();
+ }
+};
+
+// src/excludedFolder.ts
+var import_obsidian9 = require("obsidian");
+
+// src/modals/excludeFolderSettings.ts
+var import_obsidian6 = require("obsidian");
+var ExcludedFolderSettings = class extends import_obsidian6.Modal {
+ constructor(app2, plugin, excludedFolder) {
+ super(app2);
+ this.plugin = plugin;
+ this.app = app2;
+ this.excludedFolder = excludedFolder;
+ }
+ onOpen() {
+ this.display();
+ }
+ display() {
+ const { contentEl } = this;
+ contentEl.empty();
+ contentEl.createEl("h2", { text: "Excluded folder settings" });
+ new import_obsidian6.Setting(contentEl).setName("Include subfolders").setDesc("Choose if the subfolders of the folder should also be excluded").addToggle((toggle) => toggle.setValue(this.excludedFolder.subFolders).onChange(async (value) => {
+ this.excludedFolder.subFolders = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian6.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder note should be renamed when the folder name is changed").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableSync).onChange(async (value) => {
+ this.excludedFolder.disableSync = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian6.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableAutoCreate).onChange(async (value) => {
+ this.excludedFolder.disableAutoCreate = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian6.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableFolderNote).onChange(async (value) => {
+ this.excludedFolder.disableFolderNote = value;
+ await this.plugin.saveSettings();
+ this.display();
+ }));
+ if (!this.excludedFolder.disableFolderNote) {
+ new import_obsidian6.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.enableCollapsing).onChange(async (value) => {
+ this.excludedFolder.enableCollapsing = value;
+ await this.plugin.saveSettings();
+ }));
+ }
+ }
+ onClose() {
+ const { contentEl } = this;
+ contentEl.empty();
+ }
+};
+
+// src/suggesters/FolderSuggester.ts
+var import_obsidian7 = require("obsidian");
+var FolderSuggest = class extends TextInputSuggest {
+ constructor(inputEl, plugin) {
+ super(inputEl);
+ this.inputEl = inputEl;
+ this.plugin = plugin;
+ }
+ get_error_msg(mode) {
+ switch (mode) {
+ case 0 /* TemplateFiles */:
+ return "Templates folder doesn't exist";
+ case 1 /* ScriptFiles */:
+ return "User Scripts folder doesn't exist";
+ }
+ }
+ getSuggestions(input_str) {
+ const folders = [];
+ const lower_input_str = input_str.toLowerCase();
+ this.plugin.app.vault.getAllLoadedFiles().forEach((folder) => {
+ if (folder instanceof import_obsidian7.TFolder && folder.path.toLowerCase().contains(lower_input_str) && !this.plugin.settings.excludeFolders.find((f) => f.path === folder.path)) {
+ folders.push(folder);
+ }
+ });
+ return folders;
+ }
+ renderSuggestion(folder, el) {
+ el.setText(folder.path);
+ }
+ selectSuggestion(folder) {
+ this.inputEl.value = folder.path;
+ this.inputEl.trigger("input");
+ this.close();
+ }
+};
+
+// src/modals/patternSettings.ts
+var import_obsidian8 = require("obsidian");
+var PatternSettings = class extends import_obsidian8.Modal {
+ constructor(app2, plugin, pattern) {
+ super(app2);
+ this.plugin = plugin;
+ this.app = app2;
+ this.pattern = pattern;
+ }
+ onOpen() {
+ this.display();
+ }
+ display() {
+ const { contentEl } = this;
+ contentEl.empty();
+ contentEl.createEl("h2", { text: "Pattern settings" });
+ new import_obsidian8.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder name should be renamed when the file name has been changed").addToggle((toggle) => toggle.setValue(this.pattern.disableSync).onChange(async (value) => {
+ this.pattern.disableSync = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian8.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created that matches this pattern").addToggle((toggle) => toggle.setValue(this.pattern.disableAutoCreate).onChange(async (value) => {
+ this.pattern.disableAutoCreate = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian8.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.pattern.disableFolderNote).onChange(async (value) => {
+ this.pattern.disableFolderNote = value;
+ await this.plugin.saveSettings();
+ this.display();
+ }));
+ if (!this.pattern.disableFolderNote) {
+ new import_obsidian8.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.pattern.enableCollapsing).onChange(async (value) => {
+ this.pattern.enableCollapsing = value;
+ await this.plugin.saveSettings();
+ }));
+ }
+ }
+ onClose() {
+ const { contentEl } = this;
+ contentEl.empty();
+ }
+};
+
+// src/excludedFolder.ts
+var ExcludedFolder = class {
+ constructor(path, position) {
+ this.type = "folder";
+ this.path = path;
+ this.subFolders = true;
+ this.disableSync = true;
+ this.disableAutoCreate = true;
+ this.disableFolderNote = false;
+ this.enableCollapsing = false;
+ this.position = position;
+ this.string = "";
+ }
+};
+var ExcludePattern = class {
+ constructor(pattern, position) {
+ this.type = "pattern";
+ this.string = pattern;
+ this.position = position;
+ this.subFolders = false;
+ this.disableSync = true;
+ this.disableAutoCreate = true;
+ this.disableFolderNote = false;
+ this.enableCollapsing = false;
+ this.path = "";
+ }
+};
+function getExcludedFolder(plugin, path) {
+ const folderName = plugin.getFolderNameFromPathString(path);
+ const matchedPattern = getExcludedFolderByPattern(plugin, folderName);
+ if (matchedPattern) {
+ return matchedPattern;
+ }
+ const excludedFolder = getExcludedFolderByPath(plugin, path);
+ return excludedFolder;
+}
+function getExcludedFolderByPattern(plugin, folderName) {
+ return plugin.settings.excludeFolders.filter((s) => s.path === "").find((pattern) => {
+ if (!pattern.string) {
+ return false;
+ }
+ if (pattern.string.toLocaleLowerCase().startsWith("{regex}") && pattern.string.slice(7).trim() !== "") {
+ const match = new RegExp(pattern.string.slice(7).trim()).exec(folderName);
+ if (match) {
+ return true;
+ }
+ } else if (pattern.string.startsWith("*") && pattern.string.endsWith("*")) {
+ if (folderName.includes(pattern.string.slice(1, -1))) {
+ return true;
+ }
+ } else if (pattern.string.startsWith("*")) {
+ if (folderName.endsWith(pattern.string.slice(1))) {
+ return true;
+ }
+ } else if (pattern.string.endsWith("*")) {
+ if (folderName.startsWith(pattern.string.slice(0, -1))) {
+ return true;
+ }
+ }
+ });
+}
+function getExcludedFolderByPath(plugin, path) {
+ return plugin.settings.excludeFolders.find((excludedFolder) => {
+ if (excludedFolder.path === path) {
+ return true;
+ }
+ if (!excludedFolder.subFolders) {
+ return false;
+ }
+ return plugin.getFolderPathFromString(path).startsWith(excludedFolder.path);
+ });
+}
+function addExcludedFolder(plugin, excludedFolder) {
+ plugin.settings.excludeFolders.push(excludedFolder);
+ plugin.saveSettings();
+}
+function deleteExcludedFolder(plugin, excludedFolder) {
+ plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path || folder.type === "pattern");
+ plugin.saveSettings();
+ resyncArray(plugin);
+}
+function deletePattern(plugin, pattern) {
+ plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string || folder.type === "folder");
+ plugin.saveSettings();
+ resyncArray(plugin);
+}
+function updateExcludedFolder(plugin, excludedFolder, newExcludeFolder) {
+ plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path);
+ addExcludedFolder(plugin, newExcludeFolder);
+}
+function updatePattern(plugin, pattern, newPattern) {
+ plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string);
+ addExcludedFolder(plugin, newPattern);
+}
+function resyncArray(plugin) {
+ plugin.settings.excludeFolders = plugin.settings.excludeFolders.sort((a, b) => a.position - b.position);
+ plugin.settings.excludeFolders.forEach((folder, index) => {
+ folder.position = index;
+ });
+ plugin.saveSettings();
+}
+function addExcludePatternListItem(settings, containerEl, pattern) {
+ const plugin = settings.plugin;
+ const setting = new import_obsidian9.Setting(containerEl);
+ setting.setClass("fn-exclude-folder-list");
+ setting.addSearch((cb) => {
+ cb.containerEl.addClass("fn-exclude-folder-path");
+ cb.setPlaceholder("Pattern");
+ cb.setValue(pattern.string);
+ cb.onChange((value) => {
+ if (plugin.settings.excludeFolders.find((folder) => folder.string === value)) {
+ return;
+ }
+ pattern.string = value;
+ updatePattern(plugin, pattern, pattern);
+ });
+ });
+ setting.addButton((cb) => {
+ cb.setIcon("edit");
+ cb.setTooltip("Edit pattern");
+ cb.onClick(() => {
+ new PatternSettings(plugin.app, plugin, pattern).open();
+ });
+ });
+ setting.addButton((cb) => {
+ cb.setIcon("up-chevron-glyph");
+ cb.setTooltip("Move up");
+ cb.onClick(() => {
+ if (pattern.position === 0) {
+ return;
+ }
+ pattern.position -= 1;
+ updatePattern(plugin, pattern, pattern);
+ const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position);
+ if (oldPattern) {
+ oldPattern.position += 1;
+ if (oldPattern.type === "pattern") {
+ updatePattern(plugin, oldPattern, oldPattern);
+ } else {
+ updateExcludedFolder(plugin, oldPattern, oldPattern);
+ }
+ }
+ settings.display();
+ });
+ });
+ setting.addButton((cb) => {
+ cb.setIcon("down-chevron-glyph");
+ cb.setTooltip("Move down");
+ cb.onClick(() => {
+ if (pattern.position === plugin.settings.excludeFolders.length - 1) {
+ return;
+ }
+ pattern.position += 1;
+ updatePattern(plugin, pattern, pattern);
+ const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position);
+ if (oldPattern) {
+ oldPattern.position -= 1;
+ if (oldPattern.type === "pattern") {
+ updatePattern(plugin, oldPattern, oldPattern);
+ } else {
+ updateExcludedFolder(plugin, oldPattern, oldPattern);
+ }
+ }
+ settings.display();
+ });
+ });
+ setting.addButton((cb) => {
+ cb.setIcon("trash-2");
+ cb.setTooltip("Delete pattern");
+ cb.onClick(() => {
+ deletePattern(plugin, pattern);
+ setting.clear();
+ setting.settingEl.remove();
+ });
+ });
+}
+function addExcludeFolderListItem(settings, containerEl, excludedFolder) {
+ const plugin = settings.plugin;
+ const setting = new import_obsidian9.Setting(containerEl);
+ setting.setClass("fn-exclude-folder-list");
+ setting.addSearch((cb) => {
+ new FolderSuggest(cb.inputEl, plugin);
+ cb.containerEl.addClass("fn-exclude-folder-path");
+ cb.setPlaceholder("Folder path");
+ cb.setValue(excludedFolder.path);
+ cb.onChange((value) => {
+ if (value.startsWith("{regex}") || value.includes("*")) {
+ deleteExcludedFolder(plugin, excludedFolder);
+ const pattern = new ExcludePattern(value, plugin.settings.excludeFolders.length);
+ addExcludedFolder(plugin, pattern);
+ addExcludePatternListItem(settings, containerEl, pattern);
+ setting.clear();
+ setting.settingEl.remove();
+ }
+ if (!plugin.app.vault.getAbstractFileByPath(value))
+ return;
+ excludedFolder.path = value;
+ updateExcludedFolder(plugin, excludedFolder, excludedFolder);
+ });
+ });
+ setting.addButton((cb) => {
+ cb.setIcon("edit");
+ cb.setTooltip("Edit folder note");
+ cb.onClick(() => {
+ new ExcludedFolderSettings(plugin.app, plugin, excludedFolder).open();
+ });
+ });
+ setting.addButton((cb) => {
+ cb.setIcon("up-chevron-glyph");
+ cb.setTooltip("Move up");
+ cb.onClick(() => {
+ if (excludedFolder.position === 0) {
+ return;
+ }
+ excludedFolder.position -= 1;
+ updateExcludedFolder(plugin, excludedFolder, excludedFolder);
+ const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position);
+ if (oldExcludedFolder) {
+ oldExcludedFolder.position += 1;
+ if (oldExcludedFolder.type === "pattern") {
+ updatePattern(plugin, oldExcludedFolder, oldExcludedFolder);
+ } else {
+ updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder);
+ }
+ }
+ settings.display();
+ });
+ });
+ setting.addButton((cb) => {
+ cb.setIcon("down-chevron-glyph");
+ cb.setTooltip("Move down");
+ cb.onClick(() => {
+ if (excludedFolder.position === plugin.settings.excludeFolders.length - 1) {
+ return;
+ }
+ excludedFolder.position += 1;
+ updateExcludedFolder(plugin, excludedFolder, excludedFolder);
+ const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position);
+ if (oldExcludedFolder) {
+ oldExcludedFolder.position -= 1;
+ if (oldExcludedFolder.type === "pattern") {
+ updatePattern(plugin, oldExcludedFolder, oldExcludedFolder);
+ } else {
+ updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder);
+ }
+ }
+ settings.display();
+ });
+ });
+ setting.addButton((cb) => {
+ cb.setIcon("trash-2");
+ cb.setTooltip("Delete excluded folder");
+ cb.onClick(() => {
+ deleteExcludedFolder(plugin, excludedFolder);
+ setting.clear();
+ setting.settingEl.remove();
+ });
+ });
+}
+
+// src/functions/folderNoteFunctions.ts
+async function createFolderNote(plugin, folderPath, openFile, useModal, existingNote) {
+ const leaf = plugin.app.workspace.getLeaf(false);
+ const folderName = plugin.getFolderNameFromPathString(folderPath);
+ const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName);
+ let path = "";
+ if (plugin.settings.storageLocation === "parentFolder") {
+ const parentFolderPath = plugin.getFolderPathFromString(folderPath);
+ if (parentFolderPath.trim() === "") {
+ path = `${fileName}${plugin.settings.folderNoteType}`;
+ } else {
+ path = `${parentFolderPath}/${fileName}${plugin.settings.folderNoteType}`;
+ }
+ } else if (plugin.settings.storageLocation === "vaultFolder") {
+ path = `${fileName}${plugin.settings.folderNoteType}`;
+ } else {
+ path = `${folderPath}/${fileName}${plugin.settings.folderNoteType}`;
+ }
+ let file;
+ if (!existingNote) {
+ file = await plugin.app.vault.create(path, "");
+ } else {
+ file = existingNote;
+ plugin.app.vault.rename(existingNote, path);
+ }
+ if (openFile) {
+ await leaf.openFile(file);
+ }
+ if (file && !existingNote) {
+ applyTemplate(this, file, plugin.settings.templatePath);
+ }
+ const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
+ if (!(folder instanceof import_obsidian10.TFolder))
+ return;
+ plugin.addCSSClassToTitleEL(path, "is-folder-note", true);
+ plugin.addCSSClassToTitleEL(folder.path, "has-folder-note");
+}
+async function turnIntoFolderNote(plugin, file, folder, folderNote, skipConfirmation) {
+ var _a;
+ if (folderNote) {
+ if (plugin.settings.showRenameConfirmation && !skipConfirmation) {
+ return new ExistingFolderNoteModal(plugin.app, plugin, file, folder, folderNote).open();
+ }
+ plugin.removeCSSClassFromEL(folderNote.path, "is-folder-note");
+ let excludedFolder = getExcludedFolder(plugin, folder.path);
+ let excludedFolderExisted = true;
+ let disabledSync = false;
+ if (!excludedFolder) {
+ excludedFolderExisted = false;
+ excludedFolder = new ExcludedFolder(folder.path, plugin.settings.excludeFolders.length);
+ addExcludedFolder(plugin, excludedFolder);
+ } else if (!excludedFolder.disableSync) {
+ disabledSync = false;
+ excludedFolder.disableSync = true;
+ updateExcludedFolder(plugin, excludedFolder, excludedFolder);
+ }
+ const newPath = `${folder.path}/${folder.name} (${file.stat.ctime.toString().slice(10) + Math.floor(Math.random() * 1e3)})${plugin.settings.folderNoteType}`;
+ plugin.app.vault.rename(folderNote, newPath).then(() => {
+ if (!excludedFolder) {
+ return;
+ }
+ if (!excludedFolderExisted) {
+ deleteExcludedFolder(plugin, excludedFolder);
+ } else if (!disabledSync) {
+ excludedFolder.disableSync = false;
+ updateExcludedFolder(plugin, excludedFolder, excludedFolder);
+ }
+ });
+ }
+ const folderName = folder.name;
+ const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName);
+ let path = `${folder.path}/${fileName}${plugin.settings.folderNoteType}`;
+ if (plugin.settings.storageLocation === "parentFolder") {
+ const parentFolderPath = (_a = folder.parent) == null ? void 0 : _a.path;
+ if (!parentFolderPath)
+ return;
+ if (parentFolderPath.trim() === "") {
+ path = `${fileName}${plugin.settings.folderNoteType}`;
+ } else {
+ path = `${parentFolderPath}/${fileName}${plugin.settings.folderNoteType}`;
+ }
+ }
+ await plugin.app.vault.rename(file, path);
+ plugin.addCSSClassToTitleEL(path, "is-folder-note", true);
+ plugin.addCSSClassToTitleEL(folder.path, "has-folder-note");
+}
+async function openFolderNote(plugin, file, evt) {
+ var _a;
+ const path = file.path;
+ if (((_a = plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path) === path) {
+ return;
+ }
+ const leaf = plugin.app.workspace.getLeaf(import_obsidian10.Keymap.isModEvent(evt) || plugin.settings.openInNewTab);
+ if (file instanceof import_obsidian10.TFile) {
+ await leaf.openFile(file);
+ }
+}
+async function deleteFolderNote(plugin, file) {
+ if (plugin.settings.showDeleteConfirmation) {
+ return new DeleteConfirmationModal(plugin.app, plugin, file).open();
+ }
+ const folder = getFolder(plugin, file);
+ if (!folder)
+ return;
+ plugin.removeCSSClassFromEL(folder.path, "has-folder-note");
+ await plugin.app.vault.delete(file);
+}
+function extractFolderName(template, changedFileName) {
+ const [prefix, suffix] = template.split("{{folder_name}}");
+ if (prefix.trim() === "" && suffix.trim() === "") {
+ return changedFileName;
+ }
+ if (!changedFileName.startsWith(prefix) || !changedFileName.endsWith(suffix)) {
+ return null;
+ }
+ if (changedFileName.startsWith(prefix) && prefix.trim() !== "") {
+ return changedFileName.slice(prefix.length).replace(suffix, "");
+ } else if (changedFileName.endsWith(suffix) && suffix.trim() !== "") {
+ return changedFileName.slice(0, -suffix.length);
+ }
+ return null;
+}
+function getFolderNote(plugin, folderPath, storageLocation, file) {
+ if (!folderPath)
+ return null;
+ const folder = {
+ path: folderPath,
+ name: plugin.getFolderNameFromPathString(folderPath)
+ };
+ let fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folder.name);
+ if (file) {
+ fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.basename);
+ }
+ if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") {
+ folder.path = plugin.getFolderPathFromString(folderPath);
+ }
+ let path = `${folder.path}/${fileName}`;
+ if (folder.path.trim() === "") {
+ folder.path = fileName;
+ path = `${fileName}`;
+ }
+ let folderNote = plugin.app.vault.getAbstractFileByPath(path + plugin.settings.folderNoteType);
+ if (folderNote instanceof import_obsidian10.TFile) {
+ return folderNote;
+ } else {
+ if (plugin.settings.folderNoteType === ".canvas") {
+ folderNote = plugin.app.vault.getAbstractFileByPath(path + ".md");
+ } else {
+ folderNote = plugin.app.vault.getAbstractFileByPath(path + ".canvas");
+ }
+ return folderNote;
+ }
+}
+function getFolder(plugin, file, storageLocation) {
+ if (!file)
+ return null;
+ const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename);
+ if (!folderName)
+ return null;
+ let folderPath = plugin.getFolderPathFromString(file.path);
+ let folder = null;
+ if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") {
+ if (folderPath.trim() === "") {
+ folderPath = folderName;
+ } else {
+ folderPath = `${folderPath}/${folderName}`;
+ }
+ folder = plugin.app.vault.getAbstractFileByPath(folderPath);
+ } else {
+ folder = plugin.app.vault.getAbstractFileByPath(folderPath);
+ }
+ if (!folder) {
+ return null;
+ }
+ return folder;
+}
+function getFolderNoteFolder(plugin, folderNote, fileName) {
+ if (!folderNote)
+ return null;
+ let filePath = "";
+ if (typeof folderNote === "string") {
+ filePath = folderNote;
+ } else {
+ fileName = folderNote.basename;
+ filePath = folderNote.path;
+ }
+ const folderName = extractFolderName(plugin.settings.folderNoteName, fileName);
+ if (!folderName)
+ return null;
+ let folderPath = plugin.getFolderPathFromString(filePath);
+ if (plugin.settings.storageLocation === "parentFolder") {
+ if (folderPath.trim() === "") {
+ folderPath = folderName;
+ } else {
+ folderPath = `${folderPath}/${folderName}`;
+ }
+ } else {
+ folderPath = plugin.getFolderPathFromString(filePath);
+ }
+ const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
+ if (!folder) {
+ return null;
+ }
+ return folder;
+}
+
+// src/events/frontMatterTitle.ts
+var import_front_matter_plugin_api_provider = __toESM(require_lib());
+var import_obsidian11 = require("obsidian");
+var FrontMatterTitlePluginHandler = class {
+ constructor(plugin) {
+ this.api = null;
+ this.deffer = null;
+ this.modifiedFolders = /* @__PURE__ */ new Map();
+ this.plugin = plugin;
+ this.app = plugin.app;
+ (async () => {
+ var _a;
+ this.deffer = (0, import_front_matter_plugin_api_provider.getDefer)(this.app);
+ if (this.deffer.isPluginReady()) {
+ this.api = this.deffer.getApi();
+ } else {
+ await this.deffer.awaitPlugin();
+ this.api = this.deffer.getApi();
+ if (!this.deffer.isFeaturesReady()) {
+ await this.deffer.awaitFeatures();
+ }
+ }
+ const dispatcher = (_a = this.api) == null ? void 0 : _a.getEventDispatcher();
+ if (dispatcher) {
+ this.dispatcher = dispatcher;
+ }
+ const event = {
+ name: "manager:update",
+ cb: (data) => {
+ this.handleRename(data, true);
+ }
+ };
+ const ref = dispatcher == null ? void 0 : dispatcher.addListener(event);
+ if (ref) {
+ this.eventRef = ref;
+ }
+ this.plugin.app.vault.getFiles().forEach((file) => {
+ this.handleRename({ id: "", result: false, path: file.path }, false);
+ });
+ this.plugin.updateBreadcrumbs();
+ })();
+ }
+ deleteEvent() {
+ if (this.eventRef) {
+ this.dispatcher.removeListener(this.eventRef);
+ }
+ }
+ async handleRename(data, isEvent) {
+ var _a, _b, _c;
+ if (data.data)
+ data = data.data;
+ const file = this.app.vault.getAbstractFileByPath(data.path);
+ if (!(file instanceof import_obsidian11.TFile)) {
+ return;
+ }
+ const resolver = (_b = (_a = this.api) == null ? void 0 : _a.getResolverFactory()) == null ? void 0 : _b.createResolver("#feature-id#");
+ const newName = resolver == null ? void 0 : resolver.resolve((_c = file == null ? void 0 : file.path) != null ? _c : "");
+ const folder = getFolder(this.plugin, file);
+ if ((extractFolderName(this.plugin.settings.folderNoteName, file.basename) || file.basename) !== (folder == null ? void 0 : folder.name)) {
+ return;
+ }
+ if (!(folder instanceof import_obsidian11.TFolder)) {
+ return;
+ }
+ if (isEvent) {
+ this.plugin.changeName(folder, newName, true);
+ } else {
+ this.plugin.changeName(folder, newName, false);
+ }
+ if (newName) {
+ folder.newName = newName;
+ this.modifiedFolders.set(folder.path, folder);
+ } else {
+ folder.newName = null;
+ this.modifiedFolders.delete(folder.path);
+ }
+ }
+};
+
+// src/settings.ts
+var DEFAULT_SETTINGS = {
+ syncFolderName: true,
+ ctrlKey: true,
+ altKey: false,
+ hideFolderNote: true,
+ templatePath: "",
+ autoCreate: false,
+ enableCollapsing: false,
+ excludeFolders: [],
+ showDeleteConfirmation: true,
+ underlineFolder: true,
+ allowWhitespaceCollapsing: false,
+ underlineFolderInPath: true,
+ openFolderNoteOnClickInPath: true,
+ openInNewTab: false,
+ folderNoteName: "{{folder_name}}",
+ folderNoteType: ".md",
+ disableFolderHighlighting: false,
+ newFolderNoteName: "{{folder_name}}",
+ storageLocation: "insideFolder",
+ syncDelete: false,
+ showRenameConfirmation: true,
+ defaultOverview: {
+ title: "{{folderName}} overview",
+ disableTitle: false,
+ depth: 3,
+ includeTypes: ["folder", "markdown"],
+ style: "list",
+ disableFileTag: false
+ },
+ useSubmenus: true,
+ syncMove: true,
+ frontMatterTitle: {
+ enabled: false,
+ explorer: true,
+ path: true
+ }
+};
+var SettingsTab = class extends import_obsidian12.PluginSettingTab {
+ constructor(app2, plugin) {
+ super(app2, plugin);
+ }
+ display() {
+ const { containerEl } = this;
+ containerEl.empty();
+ containerEl.createEl("h2", { text: "Folder notes settings" });
+ const nameSetting = new import_obsidian12.Setting(containerEl).setName("Folder note name").setDesc("{{folder_name}} will be replaced with the name of the folder").addText((text) => text.setValue(this.plugin.settings.newFolderNoteName).onChange(async (value) => {
+ if (value.trim() === "") {
+ return;
+ }
+ this.plugin.settings.newFolderNoteName = value;
+ await this.plugin.saveSettings();
+ })).addButton((button) => button.setButtonText("Rename existing folder notes").setCta().onClick(async () => {
+ this.updateFolderNotes(this.plugin.settings.folderNoteName, this.plugin.settings.newFolderNoteName);
+ }));
+ nameSetting.infoEl.appendText("Make sure to back up your vault before renaming all folder notes and restart Obsidian after renaming them");
+ nameSetting.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
+ new import_obsidian12.Setting(containerEl).setName("Folder note type").setDesc("Choose the file type for creating new folder notes (markdown or canvas) old folder notes will not be changed and you can also create canvas/markdown files and change the name manually to the custom folder note name or to the name of the folder.").addDropdown((dropdown) => dropdown.addOption(".md", "markdown").addOption(".canvas", "canvas").setValue(this.plugin.settings.folderNoteType).onChange(async (value) => {
+ this.plugin.settings.folderNoteType = value;
+ await this.plugin.saveSettings();
+ }));
+ const setting = new import_obsidian12.Setting(containerEl);
+ const desc = document.createDocumentFragment();
+ desc.append("After setting the template path, restart Obsidian if the template folder path (from templater/templates) had been changed beforehand.", desc.createEl("br"), "Obsidian should also be restarted if the template path was removed.");
+ setting.setName("Template path");
+ setting.setDesc(desc).descEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
+ setting.addSearch((cb) => {
+ var _a;
+ new TemplateSuggest(cb.inputEl, this.plugin);
+ cb.setPlaceholder("Template path");
+ cb.setValue(((_a = this.plugin.app.vault.getAbstractFileByPath(this.plugin.settings.templatePath)) == null ? void 0 : _a.name.replace(".md", "")) || "");
+ cb.onChange(async (value) => {
+ if (value.trim() === "") {
+ this.plugin.settings.templatePath = "";
+ await this.plugin.saveSettings();
+ this.display();
+ return;
+ }
+ });
+ });
+ const storageLocation = new import_obsidian12.Setting(containerEl).setName("Storage location").setDesc("Choose where to store the folder notes").addDropdown((dropdown) => dropdown.addOption("insideFolder", "Inside the folder").addOption("parentFolder", "In the parent folder").setValue(this.plugin.settings.storageLocation).onChange(async (value) => {
+ this.plugin.settings.storageLocation = value;
+ await this.plugin.saveSettings();
+ this.display();
+ this.plugin.loadFileClasses();
+ }));
+ storageLocation.infoEl.appendText("Requires a restart to take effect");
+ storageLocation.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
+ const switchLocation = new import_obsidian12.Setting(containerEl).setName("Switch to new storage location").setDesc("Move all folder notes to the new storage location").addButton((button) => button.setButtonText("Switch").setCta().onClick(async () => {
+ let oldStorageLocation = this.plugin.settings.storageLocation;
+ if (this.plugin.settings.storageLocation === "parentFolder") {
+ oldStorageLocation = "insideFolder";
+ } else if (this.plugin.settings.storageLocation === "insideFolder") {
+ oldStorageLocation = "parentFolder";
+ }
+ this.switchStorageLocation(oldStorageLocation);
+ }));
+ switchLocation.infoEl.appendText("Requires a restart to take effect");
+ switchLocation.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
+ if (this.plugin.settings.storageLocation === "parentFolder") {
+ new import_obsidian12.Setting(containerEl).setName("Delete folder notes when deleting the folder").setDesc("Delete the folder note when deleting the folder").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncDelete).onChange(async (value) => {
+ this.plugin.settings.syncDelete = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian12.Setting(containerEl).setName("Move folder notes when moving the folder").setDesc("Move the folder note when moving the folder").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncMove).onChange(async (value) => {
+ this.plugin.settings.syncMove = value;
+ await this.plugin.saveSettings();
+ }));
+ }
+ const disableSetting = new import_obsidian12.Setting(containerEl);
+ disableSetting.setName("Disable folder collapsing");
+ disableSetting.setDesc("Disable the ability to collapse folders by clicking exactly on the folder name");
+ disableSetting.addToggle((toggle) => toggle.setValue(!this.plugin.settings.enableCollapsing).onChange(async (value) => {
+ this.plugin.settings.enableCollapsing = !value;
+ await this.plugin.saveSettings();
+ }));
+ disableSetting.infoEl.appendText("Requires a restart to take effect");
+ disableSetting.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
+ if (import_obsidian12.Platform.isDesktopApp) {
+ new import_obsidian12.Setting(containerEl).setName("Key for creating folder note").setDesc("The key combination to create a folder note").addDropdown((dropdown) => {
+ if (!import_obsidian12.Platform.isMacOS) {
+ dropdown.addOption("ctrl", "Ctrl + Click");
+ } else {
+ dropdown.addOption("ctrl", "Cmd + Click");
+ }
+ dropdown.addOption("alt", "Alt + Click");
+ dropdown.setValue(this.plugin.settings.ctrlKey ? "ctrl" : "alt");
+ dropdown.onChange(async (value) => {
+ this.plugin.settings.ctrlKey = value === "ctrl";
+ this.plugin.settings.altKey = value === "alt";
+ await this.plugin.saveSettings();
+ this.display();
+ });
+ });
+ }
+ new import_obsidian12.Setting(containerEl).setName("Only open folder notes through the name").setDesc("Only open folder notes in the file explorer by clicking on the folder name").addToggle((toggle) => toggle.setValue(this.plugin.settings.allowWhitespaceCollapsing).onChange(async (value) => {
+ if (!value) {
+ document.body.classList.add("fn-whitespace-stop-collapsing");
+ } else {
+ document.body.classList.remove("fn-whitespace-stop-collapsing");
+ }
+ this.plugin.settings.allowWhitespaceCollapsing = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian12.Setting(containerEl).setName("Hide folder note").setDesc("Hide the folder note in the file explorer").addToggle((toggle) => toggle.setValue(this.plugin.settings.hideFolderNote).onChange(async (value) => {
+ this.plugin.settings.hideFolderNote = value;
+ await this.plugin.saveSettings();
+ if (value) {
+ document.body.classList.add("hide-folder-note");
+ } else {
+ document.body.classList.remove("hide-folder-note");
+ }
+ this.display();
+ }));
+ new import_obsidian12.Setting(containerEl).setName("Sync folder name").setDesc("Automatically rename the folder note when the folder name is changed").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncFolderName).onChange(async (value) => {
+ this.plugin.settings.syncFolderName = value;
+ await this.plugin.saveSettings();
+ this.display();
+ }));
+ if (import_obsidian12.Platform.isDesktop) {
+ const setting3 = new import_obsidian12.Setting(containerEl);
+ setting3.setName("Open folder note in a new tab by default");
+ setting3.setDesc("Always open folder notes in a new tab (except when you try to open the same note) instead of having to use ctrl/cmd + click to open in a new tab");
+ setting3.addToggle((toggle) => toggle.setValue(this.plugin.settings.openInNewTab).onChange(async (value) => {
+ this.plugin.settings.openInNewTab = value;
+ await this.plugin.saveSettings();
+ this.display();
+ }));
+ setting3.infoEl.appendText("Requires a restart to take effect");
+ setting3.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
+ }
+ new import_obsidian12.Setting(containerEl).setName("Automatically create folder notes").setDesc("Automatically create a folder note when a new folder is created").addToggle((toggle) => toggle.setValue(this.plugin.settings.autoCreate).onChange(async (value) => {
+ this.plugin.settings.autoCreate = value;
+ await this.plugin.saveSettings();
+ this.display();
+ }));
+ new import_obsidian12.Setting(containerEl).setName("Use submenus").setDesc("Use submenus for file/folder commands").addToggle((toggle) => toggle.setValue(this.plugin.settings.useSubmenus).onChange(async (value) => {
+ this.plugin.settings.useSubmenus = value;
+ await this.plugin.saveSettings();
+ this.display();
+ }));
+ new import_obsidian12.Setting(containerEl).setName("Add underline to folders with folder notes").setDesc("Add an underline to folders that have a folder note in the file explorer").addToggle((toggle) => toggle.setValue(this.plugin.settings.underlineFolder).onChange(async (value) => {
+ this.plugin.settings.underlineFolder = value;
+ if (value) {
+ document.body.classList.add("folder-note-underline");
+ } else {
+ document.body.classList.remove("folder-note-underline");
+ }
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian12.Setting(containerEl).setName("Open folder note through path").setDesc("Open a folder note when clicking on a folder name in the path if it is a folder note").addToggle((toggle) => toggle.setValue(this.plugin.settings.openFolderNoteOnClickInPath).onChange(async (value) => {
+ this.plugin.settings.openFolderNoteOnClickInPath = value;
+ await this.plugin.saveSettings();
+ this.display();
+ }));
+ if (this.plugin.settings.openFolderNoteOnClickInPath) {
+ new import_obsidian12.Setting(containerEl).setName("Underline folders in the path").setDesc("Add an underline to folders that have a folder note in the path above a note").addToggle((toggle) => toggle.setValue(this.plugin.settings.underlineFolderInPath).onChange(async (value) => {
+ this.plugin.settings.underlineFolderInPath = value;
+ if (value) {
+ document.body.classList.add("folder-note-underline-path");
+ } else {
+ document.body.classList.remove("folder-note-underline-path");
+ }
+ await this.plugin.saveSettings();
+ }));
+ }
+ new import_obsidian12.Setting(containerEl).setName("Enable front matter title plugin integration").setDesc("Automatically rename a folder name when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.enabled).onChange(async (value) => {
+ var _a;
+ this.plugin.settings.frontMatterTitle.enabled = value;
+ await this.plugin.saveSettings();
+ if (value) {
+ this.plugin.fmtpHandler = new FrontMatterTitlePluginHandler(this.plugin);
+ } else {
+ if (this.plugin.fmtpHandler) {
+ this.plugin.updateBreadcrumbs(true);
+ }
+ this.plugin.app.vault.getFiles().forEach((file) => {
+ var _a2;
+ (_a2 = this.plugin.fmtpHandler) == null ? void 0 : _a2.handleRename({ id: "", result: false, path: file.path }, false);
+ });
+ (_a = this.plugin.fmtpHandler) == null ? void 0 : _a.deleteEvent();
+ this.plugin.fmtpHandler = null;
+ }
+ this.display();
+ }));
+ if (this.plugin.settings.frontMatterTitle.enabled) {
+ new import_obsidian12.Setting(containerEl).setName("Include file explorer").setDesc("Automatically rename a folder name in the file explorer when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.explorer).onChange(async (value) => {
+ this.plugin.settings.frontMatterTitle.explorer = value;
+ await this.plugin.saveSettings();
+ this.plugin.app.vault.getFiles().forEach((file) => {
+ var _a;
+ (_a = this.plugin.fmtpHandler) == null ? void 0 : _a.handleRename({ id: "", result: false, path: file.path }, false);
+ });
+ }));
+ new import_obsidian12.Setting(containerEl).setName("Include path above note").setDesc("Automatically rename a folder name in the path above a note when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.path).onChange(async (value) => {
+ this.plugin.settings.frontMatterTitle.path = value;
+ await this.plugin.saveSettings();
+ if (value) {
+ this.plugin.updateBreadcrumbs();
+ } else {
+ this.plugin.updateBreadcrumbs(true);
+ }
+ }));
+ }
+ const manageExcluded = new import_obsidian12.Setting(containerEl).setHeading().setClass("fn-excluded-folder-heading").setName("Manage excluded folders");
+ const desc3 = document.createDocumentFragment();
+ desc3.append("Add {regex} at the beginning of the folder name to use a regex pattern.", desc.createEl("br"), "Use * before and after to exclude folders that include the name between the *s.", desc.createEl("br"), "Use * before the folder name to exclude folders that end with the folder name.", desc.createEl("br"), "Use * after the folder name to exclude folders that start with the folder name.");
+ manageExcluded.setDesc(desc3);
+ manageExcluded.infoEl.appendText("The regexes and wildcards are only for the folder name, not the path.");
+ manageExcluded.infoEl.createEl("br");
+ manageExcluded.infoEl.appendText("If you want to switch to a folder path delete the pattern first.");
+ manageExcluded.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
+ new import_obsidian12.Setting(containerEl).setName("Add excluded folder").setClass("add-exclude-folder-item").addButton((cb) => {
+ cb.setIcon("plus");
+ cb.setClass("add-exclude-folder");
+ cb.setTooltip("Add excluded folder");
+ cb.onClick(() => {
+ const excludedFolder = new ExcludedFolder("", this.plugin.settings.excludeFolders.length);
+ addExcludeFolderListItem(this, containerEl, excludedFolder);
+ addExcludedFolder(this.plugin, excludedFolder);
+ this.display();
+ });
+ });
+ this.plugin.settings.excludeFolders.sort((a, b) => a.position - b.position).forEach((excludedFolder) => {
+ var _a, _b;
+ if (((_a = excludedFolder.string) == null ? void 0 : _a.trim()) !== "" && ((_b = excludedFolder.path) == null ? void 0 : _b.trim()) === "") {
+ addExcludePatternListItem(this, containerEl, excludedFolder);
+ } else {
+ addExcludeFolderListItem(this, containerEl, excludedFolder);
+ }
+ });
+ }
+ updateFolderNotes(oldTemplate, newTemplate) {
+ this.plugin.settings.folderNoteName = newTemplate;
+ this.plugin.saveSettings();
+ new import_obsidian12.Notice("Starting to update folder notes...");
+ this.app.vault.getFiles().forEach((file) => {
+ if (file instanceof import_obsidian12.TFile) {
+ const folderPath = this.plugin.getFolderPathFromString(file.path);
+ let folder = this.app.vault.getAbstractFileByPath(folderPath);
+ let folderName = file.name.slice(0, -file.extension.length - 1);
+ folderName = extractFolderName(oldTemplate, folderName) || "";
+ if (!(folder instanceof import_obsidian12.TFolder) || folderName !== (folder == null ? void 0 : folder.name)) {
+ if (folderPath.trim() === "") {
+ folder = this.app.vault.getAbstractFileByPath(folderName);
+ } else {
+ folder = this.app.vault.getAbstractFileByPath(folderPath + "/" + folderName);
+ }
+ }
+ if (!(folder instanceof import_obsidian12.TFolder)) {
+ return;
+ }
+ if (folderName === (folder == null ? void 0 : folder.name)) {
+ const newPath = `${folder == null ? void 0 : folder.path}/${this.plugin.settings.folderNoteName.replace("{{folder_name}}", folderName)}.${file.extension}`;
+ this.app.vault.rename(file, newPath);
+ } else if ((folder == null ? void 0 : folder.name) === file.name.slice(0, -file.extension.length - 1) || "") {
+ const newPath = `${folder == null ? void 0 : folder.path}/${this.plugin.settings.folderNoteName.replace("{{folder_name}}", file.name.slice(0, -file.extension.length - 1) || "")}.${file.extension}`;
+ this.app.vault.rename(file, newPath);
+ }
+ }
+ });
+ new import_obsidian12.Notice("Finished updating folder notes");
+ }
+ switchStorageLocation(oldMethod) {
+ new import_obsidian12.Notice("Starting to switch storage location...");
+ this.app.vault.getAllLoadedFiles().forEach((file) => {
+ if (file instanceof import_obsidian12.TFolder) {
+ const folderNote = getFolderNote(this.plugin, file.path, oldMethod);
+ if (folderNote instanceof import_obsidian12.TFile) {
+ if (this.plugin.settings.storageLocation === "parentFolder") {
+ let newPath = "";
+ if (this.plugin.getFolderPathFromString(file.path).trim() === "") {
+ newPath = `${folderNote.name}`;
+ } else {
+ newPath = `${this.plugin.getFolderPathFromString(file.path)}/${folderNote.name}`;
+ }
+ this.app.vault.rename(folderNote, newPath);
+ } else if (this.plugin.settings.storageLocation === "insideFolder") {
+ if (this.plugin.getFolderPathFromString(folderNote.path) === file.path) {
+ return;
+ } else {
+ const newPath = `${file.path}/${folderNote.name}`;
+ this.app.vault.rename(folderNote, newPath);
+ }
+ }
+ }
+ }
+ });
+ new import_obsidian12.Notice("Finished switching storage location");
+ }
+};
+
+// src/commands.ts
+var import_obsidian13 = require("obsidian");
+var Commands = class {
+ constructor(app2, plugin) {
+ this.plugin = plugin;
+ this.app = app2;
+ }
+ registerCommands() {
+ this.plugin.registerEvent(this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => {
+ const text = editor.getSelection().trim();
+ menu.addItem((item) => {
+ item.setTitle("Create folder overview").setIcon("edit").onClick(() => {
+ editor.replaceSelection("```folder-overview\n```\n");
+ });
+ });
+ if (!text || text.trim() === "")
+ return;
+ menu.addItem((item) => {
+ item.setTitle("Create folder note").setIcon("edit").onClick(() => {
+ const file = view.file;
+ if (!(file instanceof import_obsidian13.TFile))
+ return;
+ const blacklist = ["*", "\\", '"', "/", "<", ">", "?", "|", ":"];
+ for (const char of blacklist) {
+ if (text.includes(char)) {
+ new import_obsidian13.Notice('File name cannot contain any of the following characters: * " \\ / < > : | ?');
+ return;
+ }
+ }
+ if (text.endsWith(".")) {
+ new import_obsidian13.Notice("File name cannot end with a dot");
+ return;
+ }
+ let folder;
+ const folderPath = this.plugin.getFolderPathFromString(file.path);
+ if (folderPath === "") {
+ folder = this.plugin.app.vault.getAbstractFileByPath(text);
+ if (folder instanceof import_obsidian13.TFolder) {
+ return new import_obsidian13.Notice("Folder note already exists");
+ } else {
+ this.plugin.app.vault.createFolder(text);
+ createFolderNote(this.plugin, text, false);
+ }
+ } else {
+ folder = this.plugin.app.vault.getAbstractFileByPath(folderPath + "/" + text);
+ if (folder instanceof import_obsidian13.TFolder) {
+ return new import_obsidian13.Notice("Folder note already exists");
+ }
+ if (this.plugin.settings.storageLocation === "parentFolder") {
+ if (this.app.vault.getAbstractFileByPath(folderPath + "/" + text + this.plugin.settings.folderNoteType)) {
+ return new import_obsidian13.Notice("File already exists");
+ }
+ }
+ this.plugin.app.vault.createFolder(folderPath + "/" + text);
+ createFolderNote(this.plugin, folderPath + "/" + text, false);
+ }
+ const fileName = this.plugin.settings.folderNoteName.replace("{{folder_name}}", text);
+ if (fileName === text) {
+ editor.replaceSelection(`[[${fileName}]]`);
+ } else {
+ editor.replaceSelection(`[[${fileName}|${text}]]`);
+ }
+ });
+ });
+ }));
+ this.plugin.registerEvent(this.app.workspace.on("file-menu", (menu, file) => {
+ var _a, _b, _c;
+ let folder = file.parent;
+ if (file instanceof import_obsidian13.TFile) {
+ if (this.plugin.settings.storageLocation === "insideFolder") {
+ folder = file.parent;
+ } else {
+ const fileName = extractFolderName(this.plugin.settings.folderNoteName, file.basename);
+ if (fileName) {
+ if (((_a = file.parent) == null ? void 0 : _a.path) === "" || ((_b = file.parent) == null ? void 0 : _b.path) === "/") {
+ folder = this.plugin.app.vault.getAbstractFileByPath(fileName);
+ } else {
+ folder = this.plugin.app.vault.getAbstractFileByPath(((_c = file.parent) == null ? void 0 : _c.path) + "/" + fileName);
+ }
+ }
+ }
+ if (folder instanceof import_obsidian13.TFolder) {
+ const folderNote = getFolderNote(this.plugin, folder.path);
+ if ((folderNote == null ? void 0 : folderNote.path) === file.path) {
+ return;
+ }
+ } else if (file.parent instanceof import_obsidian13.TFolder) {
+ folder = file.parent;
+ }
+ }
+ menu.addItem((item) => {
+ if (import_obsidian13.Platform.isDesktop && !import_obsidian13.Platform.isTablet && this.plugin.settings.useSubmenus) {
+ item.setTitle("Folder Note Commands").setIcon("folder-edit");
+ }
+ let subMenu;
+ if (!import_obsidian13.Platform.isDesktopApp || !import_obsidian13.Platform.isDesktop || import_obsidian13.Platform.isTablet || !this.plugin.settings.useSubmenus) {
+ subMenu = menu;
+ item.setDisabled(true);
+ } else {
+ subMenu = item.setSubmenu();
+ }
+ if (file instanceof import_obsidian13.TFile) {
+ subMenu.addItem((item2) => {
+ item2.setTitle("Create folder note").setIcon("edit").onClick(async () => {
+ if (!folder)
+ return;
+ let newPath = folder.path + "/" + file.basename;
+ if (folder.path === "" || folder.path === "/") {
+ newPath = file.basename;
+ }
+ if (this.plugin.app.vault.getAbstractFileByPath(newPath)) {
+ return new import_obsidian13.Notice("Folder already exists");
+ }
+ await this.plugin.app.vault.createFolder(newPath);
+ const newFolder = this.plugin.app.vault.getAbstractFileByPath(newPath);
+ if (!(newFolder instanceof import_obsidian13.TFolder))
+ return;
+ createFolderNote(this.plugin, newFolder.path, true, false, file);
+ });
+ });
+ if (this.plugin.getFolderPathFromString(file.path) === "")
+ return;
+ if (!(folder instanceof import_obsidian13.TFolder))
+ return;
+ subMenu.addItem((item2) => {
+ item2.setTitle("Turn into folder note").setIcon("edit").onClick(() => {
+ if (!folder || !(folder instanceof import_obsidian13.TFolder))
+ return;
+ const folderNote2 = getFolderNote(this.plugin, folder.path);
+ turnIntoFolderNote(this.plugin, file, folder, folderNote2);
+ });
+ });
+ }
+ if (!(file instanceof import_obsidian13.TFolder))
+ return;
+ if (this.plugin.settings.excludeFolders.find((folder2) => folder2.path === file.path)) {
+ subMenu.addItem((item2) => {
+ item2.setTitle("Remove folder from excluded folders").setIcon("trash").onClick(() => {
+ this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter((folder2) => folder2.path !== file.path);
+ this.plugin.saveSettings();
+ new import_obsidian13.Notice("Successfully removed folder from excluded folders");
+ });
+ });
+ return;
+ }
+ subMenu.addItem((item2) => {
+ item2.setTitle("Exclude folder from folder notes").setIcon("x-circle").onClick(() => {
+ const excludedFolder = new ExcludedFolder(file.path, this.plugin.settings.excludeFolders.length);
+ this.plugin.settings.excludeFolders.push(excludedFolder);
+ this.plugin.saveSettings();
+ new import_obsidian13.Notice("Successfully excluded folder from folder notes");
+ });
+ });
+ if (!(file instanceof import_obsidian13.TFolder))
+ return;
+ const folderNote = getFolderNote(this.plugin, file.path);
+ if (folderNote instanceof import_obsidian13.TFile) {
+ subMenu.addItem((item2) => {
+ item2.setTitle("Delete folder note").setIcon("trash").onClick(() => {
+ deleteFolderNote(this.plugin, folderNote);
+ });
+ });
+ subMenu.addItem((item2) => {
+ item2.setTitle("Open folder note").setIcon("chevron-right-square").onClick(() => {
+ openFolderNote(this.plugin, folderNote);
+ });
+ });
+ } else {
+ subMenu.addItem((item2) => {
+ item2.setTitle("Create folder note").setIcon("edit").onClick(() => {
+ createFolderNote(this.plugin, file.path, true);
+ });
+ });
+ }
+ });
+ }));
+ }
+};
+
+// src/events/handleClick.ts
+var import_obsidian14 = require("obsidian");
+async function handleViewHeaderClick(event, plugin) {
+ if (!(event.target instanceof HTMLElement))
+ return;
+ if (!plugin.settings.openFolderNoteOnClickInPath)
+ return;
+ const folderPath = event.target.getAttribute("data-path");
+ if (!folderPath) {
+ return;
+ }
+ const excludedFolder = getExcludedFolder(plugin, folderPath);
+ if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
+ event.target.onclick = null;
+ event.target.click();
+ return;
+ } else if ((excludedFolder == null ? void 0 : excludedFolder.enableCollapsing) || plugin.settings.enableCollapsing) {
+ event.target.onclick = null;
+ event.target.click();
+ }
+ const folderNote = getFolderNote(plugin, folderPath);
+ if (folderNote) {
+ return openFolderNote(plugin, folderNote, event);
+ } else if (event.altKey || import_obsidian14.Keymap.isModEvent(event) === "tab") {
+ if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian14.Keymap.isModEvent(event) === "tab") {
+ await createFolderNote(plugin, folderPath, true, true);
+ plugin.addCSSClassToTitleEL(folderPath, "has-folder-note");
+ plugin.removeCSSClassFromEL(folderPath, "has-not-folder-note");
+ return;
+ }
+ }
+ event.target.onclick = null;
+ event.target.click();
+}
+async function handleFolderClick(event, plugin) {
+ var _a;
+ if (!(event.target instanceof HTMLElement))
+ return;
+ event.stopImmediatePropagation();
+ const folderPath = (_a = event.target.parentElement) == null ? void 0 : _a.getAttribute("data-path");
+ if (!folderPath) {
+ return;
+ }
+ const excludedFolder = getExcludedFolder(plugin, folderPath);
+ if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
+ event.target.onclick = null;
+ event.target.click();
+ return;
+ } else if ((excludedFolder == null ? void 0 : excludedFolder.enableCollapsing) || plugin.settings.enableCollapsing) {
+ event.target.onclick = null;
+ event.target.click();
+ }
+ const folderNote = getFolderNote(plugin, folderPath);
+ if (folderNote) {
+ return openFolderNote(plugin, folderNote, event);
+ } else if (event.altKey || import_obsidian14.Keymap.isModEvent(event) === "tab") {
+ if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian14.Keymap.isModEvent(event) === "tab") {
+ await createFolderNote(plugin, folderPath, true, true);
+ plugin.addCSSClassToTitleEL(folderPath, "has-folder-note");
+ plugin.removeCSSClassFromEL(folderPath, "has-not-folder-note");
+ return;
+ }
+ }
+ event.target.onclick = null;
+ event.target.click();
+}
+
+// src/events/handleRename.ts
+var import_obsidian15 = require("obsidian");
+function handleFolderRename(file, oldPath, plugin) {
+ const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.name);
+ const folder = plugin.app.vault.getAbstractFileByPath(file.path);
+ const folderNote = getFolderNote(plugin, oldPath);
+ if (!(folderNote instanceof import_obsidian15.TFile))
+ return;
+ if (!(folder instanceof import_obsidian15.TFolder))
+ return;
+ const excludedFolders = plugin.settings.excludeFolders.filter((excludedFolder2) => excludedFolder2.path.includes(oldPath));
+ excludedFolders.forEach((excludedFolder2) => {
+ if (excludedFolder2.path === oldPath) {
+ excludedFolder2.path = folder.path;
+ return;
+ }
+ const folders = excludedFolder2.path.split("/");
+ if (folders.length < 1) {
+ folders.push(excludedFolder2.path);
+ }
+ folders[folders.indexOf(folder.name)] = folder.name;
+ excludedFolder2.path = folders.join("/");
+ });
+ plugin.saveSettings();
+ const excludedFolder = getExcludedFolder(plugin, file.path);
+ if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && !folderNote) {
+ return plugin.removeCSSClassFromEL(file.path, "has-folder-note");
+ }
+ let newPath = "";
+ if (plugin.settings.storageLocation === "parentFolder") {
+ const parentFolderPath = plugin.getFolderPathFromString(file.path);
+ const oldParentFolderPath = plugin.getFolderPathFromString(oldPath);
+ if (parentFolderPath !== oldParentFolderPath) {
+ if (!plugin.settings.syncMove) {
+ return;
+ }
+ newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`;
+ } else if (parentFolderPath.trim() === "") {
+ folderNote.path = `${folderNote.name}`;
+ newPath = `${fileName}.${folderNote.extension}`;
+ } else {
+ folderNote.path = `${parentFolderPath}/${folderNote.name}`;
+ newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`;
+ }
+ } else {
+ folderNote.path = `${file.path}/${folderNote.name}`;
+ newPath = `${file.path}/${fileName}.${folderNote.extension}`;
+ }
+ plugin.app.vault.rename(folderNote, newPath);
+}
+function handleFileRename(file, oldPath, plugin) {
+ const oldFileName = plugin.removeExtension(plugin.getFileNameFromPathString(oldPath));
+ const oldFolder = getFolderNoteFolder(plugin, oldPath, oldFileName);
+ const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename) || file.basename;
+ const oldFolderName = extractFolderName(plugin.settings.folderNoteName, oldFileName) || oldFileName;
+ const newFolder = getFolderNoteFolder(plugin, file, file.basename);
+ let excludedFolder = getExcludedFolder(plugin, (newFolder == null ? void 0 : newFolder.path) || "");
+ const folderNote = getFolderNote(plugin, oldPath, plugin.settings.storageLocation, file);
+ if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && folderName === (newFolder == null ? void 0 : newFolder.name)) {
+ plugin.addCSSClassToTitleEL(file.path, "is-folder-note");
+ plugin.addCSSClassToTitleEL(newFolder.path, "has-folder-note");
+ return;
+ } else if (excludedFolder == null ? void 0 : excludedFolder.disableSync) {
+ plugin.removeCSSClassFromEL(file.path, "is-folder-note");
+ plugin.removeCSSClassFromEL((newFolder == null ? void 0 : newFolder.path) || "", "has-folder-note");
+ return;
+ }
+ if (folderName === (newFolder == null ? void 0 : newFolder.name) && folderNote) {
+ new import_obsidian15.Notice("Folder with same name already exists!");
+ let excludedFolderExisted = true;
+ let disabledSync = false;
+ if (!excludedFolder) {
+ excludedFolderExisted = false;
+ excludedFolder = new ExcludedFolder((oldFolder == null ? void 0 : oldFolder.path) || "", plugin.settings.excludeFolders.length);
+ addExcludedFolder(plugin, excludedFolder);
+ } else if (!excludedFolder.disableSync) {
+ disabledSync = false;
+ excludedFolder.disableSync = true;
+ updateExcludedFolder(plugin, excludedFolder, excludedFolder);
+ }
+ return plugin.app.vault.rename(file, oldPath).then(() => {
+ if (!excludedFolder) {
+ return;
+ }
+ if (!excludedFolderExisted) {
+ deleteExcludedFolder(plugin, excludedFolder);
+ } else if (!disabledSync) {
+ excludedFolder.disableSync = false;
+ updateExcludedFolder(plugin, excludedFolder, excludedFolder);
+ }
+ });
+ }
+ if (folderName === (newFolder == null ? void 0 : newFolder.name)) {
+ plugin.addCSSClassToTitleEL(file.path, "is-folder-note");
+ plugin.addCSSClassToTitleEL(newFolder.path, "has-folder-note");
+ plugin.removeCSSClassFromEL(oldFolder == null ? void 0 : oldFolder.path, "has-folder-note");
+ return;
+ }
+ if (!oldFolder)
+ return;
+ if (oldFolderName === oldFolder.name && (newFolder == null ? void 0 : newFolder.path) === oldFolder.path) {
+ return renameFolderOnFileRename(file, oldPath, oldFolder, plugin);
+ } else if (folderNote && oldFolderName === oldFolder.name) {
+ return renameFolderOnFileRename(file, oldPath, oldFolder, plugin);
+ }
+ if (oldFolder.name === oldFileName && (newFolder == null ? void 0 : newFolder.path) !== oldFolder.path) {
+ plugin.removeCSSClassFromEL(oldFolder.path, "has-folder-note");
+ plugin.removeCSSClassFromEL(file.path, "is-folder-note");
+ plugin.removeCSSClassFromEL(oldPath, "is-folder-note");
+ }
+}
+async function renameFolderOnFileRename(file, oldPath, oldFolder, plugin) {
+ var _a;
+ const newFolderName = extractFolderName(plugin.settings.folderNoteName, file.basename);
+ if (!newFolderName) {
+ plugin.removeCSSClassFromEL(oldFolder.path, "has-folder-note");
+ plugin.removeCSSClassFromEL(file.path, "is-folder-note");
+ return;
+ } else if (newFolderName === oldFolder.name) {
+ plugin.addCSSClassToTitleEL(oldFolder.path, "has-folder-note");
+ plugin.addCSSClassToTitleEL(file.path, "is-folder-note");
+ return;
+ }
+ let newFolderPath = "";
+ if (plugin.settings.storageLocation === "insideFolder") {
+ newFolderPath = ((_a = oldFolder.parent) == null ? void 0 : _a.path) + "/" + newFolderName;
+ } else {
+ const parentFolderPath = plugin.getFolderPathFromString(file.path);
+ if (parentFolderPath.trim() === "") {
+ newFolderPath = `${newFolderName}`;
+ } else {
+ newFolderPath = `${parentFolderPath}/${newFolderName}`;
+ }
+ }
+ if (plugin.app.vault.getAbstractFileByPath(newFolderPath) || plugin.app.vault.getAbstractFileByPath(newFolderName || "")) {
+ await plugin.app.vault.rename(file, oldPath);
+ return new import_obsidian15.Notice("A folder with the same name already exists");
+ }
+ await plugin.app.vault.rename(oldFolder, newFolderPath);
+}
+
+// src/folderOverview.ts
+var import_obsidian16 = require("obsidian");
+function createOverview(plugin, source, el, ctx) {
+ let yaml = (0, import_obsidian16.parseYaml)(source);
+ if (!yaml) {
+ yaml = {
+ title: plugin.settings.defaultOverview.title,
+ disableTitle: plugin.settings.defaultOverview.disableTitle,
+ depth: plugin.settings.defaultOverview.depth,
+ type: plugin.settings.defaultOverview.type,
+ includeTypes: plugin.settings.defaultOverview.includeTypes,
+ style: plugin.settings.defaultOverview.style,
+ disableFileTag: plugin.settings.defaultOverview.disableFileTag,
+ sortBy: plugin.settings.defaultOverview.sortBy,
+ showEmptyFolders: plugin.settings.defaultOverview.showEmptyFolders,
+ onlyIncludeSubfolders: plugin.settings.defaultOverview.onlyIncludeSubfolders
+ };
+ }
+ const depth = (yaml == null ? void 0 : yaml.depth) || 1;
+ let title = (yaml == null ? void 0 : yaml.title) || plugin.settings.defaultOverview.title || "{{folderName}} overview";
+ const folderName = extractFolderName(plugin.settings.folderNoteName, plugin.removeExtension(plugin.getFolderNameFromPathString(ctx.sourcePath)));
+ title = title.replaceAll("{{folderName}}", folderName || "");
+ const disableTitle = (yaml == null ? void 0 : yaml.disableTitle) || plugin.settings.defaultOverview.disableTitle || false;
+ let includeTypes = (yaml == null ? void 0 : yaml.includeTypes) || plugin.settings.defaultOverview.includeTypes || ["folder", "markdown"];
+ includeTypes = includeTypes.map((type) => type.toLowerCase());
+ const style = (yaml == null ? void 0 : yaml.style) || "list";
+ const disableFileTag = (yaml == null ? void 0 : yaml.disableFileTag) || plugin.settings.defaultOverview.disableFileTag || false;
+ const showEmptyFolders = (yaml == null ? void 0 : yaml.showEmptyFolders) || plugin.settings.defaultOverview.showEmptyFolders || false;
+ const root = el.createEl("div", { cls: "folder-overview" });
+ const titleEl = root.createEl("h1", { cls: "folder-overview-title" });
+ const ul = root.createEl("ul", { cls: "folder-overview-list" });
+ if (!disableTitle) {
+ titleEl.innerText = title;
+ }
+ if (includeTypes.length === 0) {
+ return;
+ }
+ let files = [];
+ const sourceFile = plugin.app.vault.getAbstractFileByPath(ctx.sourcePath);
+ if (!sourceFile)
+ return;
+ const sourceFolderPath = plugin.getFolderPathFromString(ctx.sourcePath);
+ let sourceFolder;
+ if (sourceFile.parent instanceof import_obsidian16.TFolder) {
+ sourceFolder = sourceFile.parent;
+ } else {
+ sourceFolder = plugin.app.vault.getAbstractFileByPath(plugin.getFolderPathFromString(ctx.sourcePath));
+ }
+ files = sourceFolder.children;
+ files = files.filter((file) => {
+ const folderPath = plugin.getFolderPathFromString(file.path);
+ if (!folderPath.startsWith(sourceFolderPath)) {
+ return false;
+ }
+ if (file.path === ctx.sourcePath) {
+ return false;
+ }
+ if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth) {
+ return true;
+ }
+ });
+ if (!includeTypes.includes("folder")) {
+ files = getAllFiles(files, sourceFolderPath, depth);
+ }
+ files = sortFiles(files, yaml, plugin);
+ if (style === "grid") {
+ const grid = root.createEl("div", { cls: "folder-overview-grid" });
+ files.forEach(async (file) => {
+ const gridItem = grid.createEl("div", { cls: "folder-overview-grid-item" });
+ const gridArticle = gridItem.createEl("article", { cls: "folder-overview-grid-item-article" });
+ if (file instanceof import_obsidian16.TFile) {
+ const fileContent = await plugin.app.vault.read(file);
+ const descriptionEl = gridArticle.createEl("p", { cls: "folder-overview-grid-item-description" });
+ let description = fileContent.split("\n")[0];
+ if (description.length > 64) {
+ description = description.slice(0, 64) + "...";
+ }
+ descriptionEl.innerText = description;
+ const link = gridArticle.createEl("a", { cls: "folder-overview-grid-item-link internal-link" });
+ const title2 = link.createEl("h1", { cls: "folder-overview-grid-item-link-title" });
+ title2.innerText = file.name.replace(".md", "").replace(".canvas", "");
+ link.href = file.path;
+ } else if (file instanceof import_obsidian16.TFolder) {
+ const folderItem = gridArticle.createEl("div", { cls: "folder-overview-grid-item-folder" });
+ const folderName2 = folderItem.createEl("h1", { cls: "folder-overview-grid-item-folder-name" });
+ folderName2.innerText = file.name;
+ }
+ });
+ } else if (style === "list") {
+ const pathBlacklist = [];
+ files.forEach((file) => {
+ if (file instanceof import_obsidian16.TFolder) {
+ const folderItem = addFolderList(plugin, ul, pathBlacklist, file);
+ goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag);
+ } else if (file instanceof import_obsidian16.TFile) {
+ addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag);
+ }
+ });
+ } else if (style === "explorer") {
+ }
+ if (includeTypes.length > 1 && style !== "grid" && (!showEmptyFolders || yaml.onlyIncludeSubfolders)) {
+ removeEmptyFolders(ul, 1, yaml);
+ }
+}
+function goThroughFolders(plugin, list, folder, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag) {
+ if (sourceFolderPath === "") {
+ depth--;
+ }
+ let files = folder.children.filter((file) => {
+ const folderPath = plugin.getFolderPathFromString(file.path);
+ if (!folderPath.startsWith(sourceFolderPath)) {
+ return false;
+ }
+ if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth) {
+ return true;
+ }
+ });
+ files = sortFiles(files, yaml, plugin);
+ const ul = list.createEl("ul", { cls: "folder-overview-list" });
+ files.forEach((file) => {
+ if (file instanceof import_obsidian16.TFolder) {
+ const folderItem = addFolderList(plugin, ul, pathBlacklist, file);
+ goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag);
+ } else if (file instanceof import_obsidian16.TFile) {
+ addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag);
+ }
+ });
+}
+function sortFiles(files, yaml, plugin) {
+ if (!(yaml == null ? void 0 : yaml.sortBy)) {
+ yaml.sortBy = plugin.settings.defaultOverview.sortBy || "name";
+ }
+ return files.sort((a, b) => {
+ if (a instanceof import_obsidian16.TFolder && !(b instanceof import_obsidian16.TFolder)) {
+ return -1;
+ }
+ if (!(a instanceof import_obsidian16.TFolder) && b instanceof import_obsidian16.TFolder) {
+ return 1;
+ }
+ if (!(a instanceof import_obsidian16.TFile) || !(b instanceof import_obsidian16.TFile)) {
+ return -1;
+ }
+ if (yaml.sortBy === "created") {
+ if (a.stat.ctime > b.stat.ctime) {
+ return -1;
+ } else if (a.stat.ctime < b.stat.ctime) {
+ return 1;
+ }
+ } else if (yaml.sortBy === "createdAsc") {
+ if (a.stat.ctime < b.stat.ctime) {
+ return -1;
+ } else if (a.stat.ctime > b.stat.ctime) {
+ return 1;
+ }
+ } else if (yaml.sortBy === "modified") {
+ if (a.stat.mtime > b.stat.mtime) {
+ return -1;
+ } else if (a.stat.mtime < b.stat.mtime) {
+ return 1;
+ }
+ } else if (yaml.sortBy === "modifiedAsc") {
+ if (a.stat.mtime < b.stat.mtime) {
+ return -1;
+ } else if (a.stat.mtime > b.stat.mtime) {
+ return 1;
+ }
+ }
+ if (a.name < b.name && yaml.sortBy === "name") {
+ return -1;
+ } else if (a.name > b.name && yaml.sortBy === "nameAsc") {
+ return -1;
+ }
+ if (a.name > b.name && yaml.sortBy === "name") {
+ return 1;
+ } else if (a.name < b.name && yaml.sortBy === "nameAsc") {
+ return 1;
+ }
+ return 0;
+ });
+}
+function removeEmptyFolders(ul, depth, yaml) {
+ const childrensToRemove = [];
+ ul.childNodes.forEach((el) => {
+ const childrens = el.querySelector("ul");
+ if (!childrens || childrens === null) {
+ return;
+ }
+ if (childrens && !(childrens == null ? void 0 : childrens.hasChildNodes()) && !(el instanceof HTMLUListElement)) {
+ childrensToRemove.push(el);
+ } else if (el instanceof HTMLUListElement || el instanceof HTMLLIElement) {
+ removeEmptyFolders(el, depth + 1, yaml);
+ }
+ });
+ childrensToRemove.forEach((el) => {
+ if (yaml.onlyIncludeSubfolders && depth === 1) {
+ return;
+ }
+ el.remove();
+ });
+}
+function addFolderList(plugin, list, pathBlacklist, folder) {
+ const folderItem = list.createEl("li", { cls: "folder-overview-list folder-list" });
+ const folderNote = getFolderNote(plugin, folder.path);
+ if (folderNote instanceof import_obsidian16.TFile) {
+ const folderNoteLink = folderItem.createEl("a", { cls: "folder-overview-list-item folder-name-item internal-link", href: folderNote.path });
+ folderNoteLink.innerText = folder.name;
+ pathBlacklist.push(folderNote.path);
+ } else {
+ const folderName = folderItem.createEl("span", { cls: "folder-overview-list-item folder-name-item" });
+ folderName.innerText = folder.name;
+ }
+ return folderItem;
+}
+function addFileList(plugin, list, pathBlacklist, file, includeTypes, disableFileTag) {
+ if (includeTypes.length > 0 && !includeTypes.includes("all")) {
+ if (file.extension === "md" && !includeTypes.includes("markdown"))
+ return;
+ if (file.extension === "canvas" && !includeTypes.includes("canvas"))
+ return;
+ if (file.extension === "pdf" && !includeTypes.includes("pdf"))
+ return;
+ const imageTypes = ["jpg", "jpeg", "png", "gif", "svg", "webp"];
+ if (imageTypes.includes(file.extension) && !includeTypes.includes("image"))
+ return;
+ const videoTypes = ["mp4", "webm", "ogv", "mov", "mkv"];
+ if (videoTypes.includes(file.extension) && !includeTypes.includes("video"))
+ return;
+ const audioTypes = ["mp3", "wav", "m4a", "3gp", "flac", "ogg", "oga", "opus"];
+ if (audioTypes.includes(file.extension) && includeTypes.includes("audio"))
+ return;
+ const allTypes = ["md", "canvas", "pdf", ...imageTypes, ...videoTypes, ...audioTypes];
+ if (!allTypes.includes(file.extension) && !includeTypes.includes("other"))
+ return;
+ }
+ if (pathBlacklist.includes(file.path))
+ return;
+ const listItem = list.createEl("li", { cls: "folder-overview-list file-link" });
+ const nameItem = listItem.createEl("div", { cls: "folder-overview-list-item" });
+ const link = nameItem.createEl("a", { cls: "internal-link", href: file.path });
+ link.innerText = file.basename;
+ if (file.extension !== "md" && !disableFileTag) {
+ nameItem.createDiv({ cls: "nav-file-tag" }).innerText = file.extension;
+ }
+}
+function getAllFiles(files, sourceFolderPath, depth) {
+ const allFiles = [];
+ files.forEach((file) => {
+ if (file instanceof import_obsidian16.TFolder) {
+ if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth - 1) {
+ allFiles.push(...getAllFiles(file.children, sourceFolderPath, depth));
+ }
+ } else {
+ allFiles.push(file);
+ }
+ });
+ return allFiles;
+}
+
+// src/modals/folderOverview.ts
+var import_obsidian17 = require("obsidian");
+var FolderOverviewSettings = class extends import_obsidian17.Modal {
+ constructor(app2, plugin, yaml, ctx, el) {
+ super(app2);
+ this.plugin = plugin;
+ this.app = app2;
+ this.yaml = yaml;
+ this.ctx = ctx;
+ this.el = el;
+ if (!this.yaml) {
+ this.yaml = {
+ title: this.plugin.settings.defaultOverview.title,
+ disableTitle: this.plugin.settings.defaultOverview.disableTitle,
+ depth: this.plugin.settings.defaultOverview.depth,
+ type: this.plugin.settings.defaultOverview.type,
+ includeTypes: this.plugin.settings.defaultOverview.includeTypes,
+ style: this.plugin.settings.defaultOverview.style,
+ disableFileTag: this.plugin.settings.defaultOverview.disableFileTag,
+ sortBy: this.plugin.settings.defaultOverview.sortBy,
+ showEmptyFolders: this.plugin.settings.defaultOverview.showEmptyFolders,
+ onlyIncludeSubfolders: this.plugin.settings.defaultOverview.onlyIncludeSubfolders
+ };
+ }
+ }
+ onOpen() {
+ this.display();
+ }
+ display() {
+ var _a, _b, _c, _d;
+ const { contentEl } = this;
+ contentEl.empty();
+ contentEl.addEventListener("keydown", (e) => {
+ if (e.key === "Enter") {
+ this.close();
+ }
+ });
+ contentEl.createEl("h2", { text: "Folder overview settings" });
+ new import_obsidian17.Setting(contentEl).setName("Disable the title").setDesc("Choose if the title should be shown").addToggle((toggle) => toggle.setValue(this.yaml.disableTitle || false).onChange(async (value) => {
+ this.yaml.disableTitle = value;
+ this.display();
+ await this.updateYaml();
+ }));
+ if (!this.yaml.disableTitle) {
+ new import_obsidian17.Setting(contentEl).setName("Title").setDesc("Choose the title of the folder overview").addText((text) => {
+ var _a2;
+ return text.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.title) || "{{folderName}} overview").onChange(async (value) => {
+ this.yaml.title = value;
+ await this.updateYaml();
+ });
+ });
+ }
+ const setting = new import_obsidian17.Setting(contentEl);
+ setting.setName("Include types");
+ const list = setting.createList((list2) => {
+ var _a2;
+ return list2.addModal(this).setValues(((_a2 = this.yaml) == null ? void 0 : _a2.includeTypes) || this.plugin.settings.defaultOverview.includeTypes || []).addResetButton();
+ });
+ if ((((_b = (_a = this.yaml) == null ? void 0 : _a.includeTypes) == null ? void 0 : _b.length) || 0) < 8 && !((_c = this.yaml.includeTypes) == null ? void 0 : _c.includes("all"))) {
+ setting.addDropdown((dropdown) => {
+ if (!this.yaml.includeTypes)
+ this.yaml.includeTypes = this.plugin.settings.defaultOverview.includeTypes || [];
+ this.yaml.includeTypes = this.yaml.includeTypes.map((type) => type.toLowerCase());
+ const options = [
+ { value: "markdown", label: "Markdown" },
+ { value: "folder", label: "Folder" },
+ { value: "canvas", label: "Canvas" },
+ { value: "pdf", label: "PDF" },
+ { value: "image", label: "Image" },
+ { value: "audio", label: "Audio" },
+ { value: "video", label: "Video" },
+ { value: "other", label: "All other file types" },
+ { value: "all", label: "All file types" }
+ ];
+ options.forEach((option) => {
+ var _a2;
+ if (!((_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.includes(option.value))) {
+ dropdown.addOption(option.value, option.label);
+ }
+ });
+ dropdown.addOption("+", "+");
+ dropdown.setValue("+");
+ dropdown.onChange(async (value) => {
+ var _a2;
+ if (value === "all") {
+ this.yaml.includeTypes = (_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.filter((type) => type === "folder");
+ list.setValues(this.yaml.includeTypes);
+ }
+ await list.addValue(value.toLowerCase());
+ await this.updateYaml();
+ this.display();
+ });
+ });
+ }
+ let disableFileTag;
+ (_d = this.yaml.includeTypes) == null ? void 0 : _d.forEach((type) => {
+ type === "folder" || type === "markdown" ? disableFileTag = true : null;
+ });
+ if (disableFileTag) {
+ new import_obsidian17.Setting(contentEl).setName("Disable file tag").setDesc("Choose if the file tag should be shown after the file name").addToggle((toggle) => {
+ toggle.setValue(this.yaml.disableFileTag || this.plugin.settings.defaultOverview.disableFileTag || false).onChange(async (value) => {
+ this.yaml.disableFileTag = value;
+ await this.updateYaml();
+ });
+ });
+ }
+ new import_obsidian17.Setting(contentEl).setName("File depth").setDesc("File & folder = +1 depth").addSlider((slider) => {
+ var _a2;
+ return slider.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.depth) || 2).setLimits(1, 10, 1).onChange(async (value) => {
+ this.yaml.depth = value;
+ await this.updateYaml();
+ });
+ });
+ new import_obsidian17.Setting(contentEl).setName("Overview style").setDesc("Choose the style of the overview (grid style soon)").addDropdown((dropdown) => {
+ var _a2;
+ return dropdown.addOption("list", "List").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.style) || "list").onChange(async (value) => {
+ this.yaml.style = value;
+ await this.updateYaml();
+ });
+ });
+ new import_obsidian17.Setting(contentEl).setName("Sort files by").setDesc("Choose how the files should be sorted").addDropdown((dropdown) => {
+ var _a2;
+ return dropdown.addOption("name", "Name descending").addOption("created", "Created descending").addOption("modified", "Modified descending").addOption("nameAsc", "Name ascending").addOption("createdAsc", "Created ascending").addOption("modifiedAsc", "Modified ascending").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.sortBy) || "name").onChange(async (value) => {
+ this.yaml.sortBy = value;
+ await this.updateYaml();
+ });
+ });
+ new import_obsidian17.Setting(contentEl).setName("Show folder names of empty folders").setDesc("That includes subfolders of the current folder when you are on file depth 1").addToggle((toggle) => {
+ toggle.setValue(this.yaml.showEmptyFolders || this.plugin.settings.defaultOverview.showEmptyFolders || false).onChange(async (value) => {
+ this.yaml.showEmptyFolders = value;
+ this.yaml.onlyIncludeSubfolders = false;
+ this.display();
+ await this.updateYaml();
+ });
+ });
+ if (this.yaml.showEmptyFolders) {
+ new import_obsidian17.Setting(contentEl).setName("Only show first empty subfolders of current folder").addToggle((toggle) => {
+ toggle.setValue(this.yaml.onlyIncludeSubfolders || this.plugin.settings.defaultOverview.onlyIncludeSubfolders || false).onChange(async (value) => {
+ this.yaml.onlyIncludeSubfolders = value;
+ await this.updateYaml();
+ });
+ });
+ }
+ }
+ onClose() {
+ const { contentEl } = this;
+ contentEl.empty();
+ }
+ async updateYaml() {
+ const file = this.plugin.app.vault.getAbstractFileByPath(this.ctx.sourcePath);
+ if (!(file instanceof import_obsidian17.TFile))
+ return;
+ let stringYaml = (0, import_obsidian17.stringifyYaml)(this.yaml);
+ await this.plugin.app.vault.process(file, (text) => {
+ const info = this.ctx.getSectionInfo(this.el);
+ if (stringYaml[stringYaml.length - 1] !== "\n") {
+ stringYaml += "\n";
+ }
+ if (info) {
+ const { lineStart } = info;
+ const lineEnd = this.getCodeBlockEndLine(text, lineStart);
+ if (lineEnd === -1 || !lineEnd)
+ return text;
+ const lineLength = lineEnd - lineStart;
+ const lines = text.split("\n");
+ lines.splice(lineStart, lineLength + 1, `\`\`\`folder-overview
+${stringYaml}\`\`\``);
+ return lines.join("\n");
+ }
+ return `\`\`\`folder-overview
+${stringYaml}\`\`\``;
+ });
+ }
+ getCodeBlockEndLine(text, startLine, count = 1) {
+ let line = startLine + 1;
+ const lines = text.split("\n");
+ while (line < lines.length) {
+ if (count > 20) {
+ return -1;
+ }
+ if (lines[line].startsWith("```")) {
+ return line;
+ }
+ line++;
+ count++;
+ }
+ return line;
+ }
+};
+
+// src/functions/ListComponent.ts
+var import_obsidian18 = require("obsidian");
+var ListComponent = class {
+ constructor(containerEl) {
+ this.containerEl = containerEl;
+ this.controlEl = containerEl.querySelector(".setting-item-control") || containerEl;
+ this.listEl = this.controlEl.createDiv("setting-command-hotkeys");
+ }
+ addModal(modal) {
+ this.modal = modal;
+ this.values = modal.yaml.includeTypes || [];
+ return this;
+ }
+ setValues(values) {
+ this.listEl.empty();
+ this.values = values;
+ this.modal.yaml.includeTypes = values;
+ if (values.length !== 0) {
+ values.forEach((value) => {
+ this.addElement(value);
+ });
+ }
+ this.modal.updateYaml();
+ return this;
+ }
+ addElement(value) {
+ this.listEl.createSpan("setting-hotkey", (span) => {
+ span.innerText = value;
+ const removeSpan = span.createEl("span", { cls: "ofn-list-item-remove setting-hotkey-icon" });
+ const svg = '';
+ const svgElement = removeSpan.createEl("span", { cls: "ofn-list-item-remove-icon" });
+ svgElement.innerHTML = svg;
+ removeSpan.onClickEvent((e) => {
+ this.removeValue(value);
+ span.remove();
+ });
+ });
+ }
+ async addValue(value) {
+ this.values.push(value);
+ this.addElement(value);
+ this.modal.yaml.includeTypes = this.values;
+ return this;
+ }
+ addResetButton() {
+ const resetButton = this.controlEl.createEl("span", { cls: "clickable-icon setting-restore-hotkey-button" });
+ const svg = '';
+ resetButton.innerHTML = svg;
+ resetButton.onClickEvent((e) => {
+ this.modal.plugin.loadSettings();
+ this.setValues(this.modal.plugin.settings.defaultOverview.includeTypes || []);
+ this.modal.display();
+ });
+ return this;
+ }
+ removeValue(value) {
+ this.values = this.values.filter((v) => v !== value);
+ this.setValues(this.values);
+ this.modal.display();
+ }
+};
+function createList(cb) {
+ const list = new ListComponent(this.settingEl);
+ cb(list);
+ return list;
+}
+import_obsidian18.Setting.prototype.createList = createList;
+
+// src/main.ts
+var FolderNotesPlugin = class extends import_obsidian19.Plugin {
+ constructor() {
+ super(...arguments);
+ this.fmtpHandler = null;
+ }
+ async onload() {
+ console.log("loading folder notes plugin");
+ await this.loadSettings();
+ this.settingsTab = new SettingsTab(this.app, this);
+ this.addSettingTab(this.settingsTab);
+ this.saveSettings();
+ document.body.classList.add("folder-notes-plugin");
+ if (this.settings.hideFolderNote) {
+ document.body.classList.add("hide-folder-note");
+ }
+ if (this.settings.underlineFolder) {
+ document.body.classList.add("folder-note-underline");
+ }
+ if (this.settings.underlineFolderInPath) {
+ document.body.classList.add("folder-note-underline-path");
+ }
+ if (!this.settings.allowWhitespaceCollapsing) {
+ document.body.classList.add("fn-whitespace-stop-collapsing");
+ }
+ new Commands(this.app, this).registerCommands();
+ this.app.workspace.onLayoutReady(() => {
+ if (this.settings.frontMatterTitle.enabled) {
+ this.fmtpHandler = new FrontMatterTitlePluginHandler(this);
+ }
+ });
+ this.observer = new MutationObserver((mutations) => {
+ mutations.forEach((rec) => {
+ if (rec.type === "childList") {
+ rec.target.querySelectorAll("div.nav-folder-title-content").forEach((element) => {
+ if (element.onclick)
+ return;
+ element.onclick = (event) => handleFolderClick(event, this);
+ });
+ if (!this.settings.openFolderNoteOnClickInPath) {
+ return;
+ }
+ rec.target.querySelectorAll("span.view-header-breadcrumb").forEach((element) => {
+ var _a, _b;
+ const breadcrumbs = (_a = element.parentElement) == null ? void 0 : _a.querySelectorAll("span.view-header-breadcrumb");
+ if (!breadcrumbs)
+ return;
+ let path = "";
+ breadcrumbs.forEach((breadcrumb) => {
+ var _a2;
+ if (breadcrumb.hasAttribute("old-name")) {
+ path += breadcrumb.getAttribute("old-name") + "/";
+ } else {
+ path += breadcrumb.innerText.trim() + "/";
+ }
+ const folderPath = path.slice(0, -1);
+ breadcrumb.setAttribute("data-path", folderPath);
+ const folder = (_a2 = this.fmtpHandler) == null ? void 0 : _a2.modifiedFolders.get(folderPath);
+ if (folder && this.settings.frontMatterTitle.path && this.settings.frontMatterTitle.enabled) {
+ breadcrumb.setAttribute("old-name", folder.name || "");
+ breadcrumb.innerText = folder.newName || "";
+ }
+ const folderNote = getFolderNote(this, folderPath);
+ if (folderNote) {
+ breadcrumb.classList.add("has-folder-note");
+ }
+ });
+ (_b = element.parentElement) == null ? void 0 : _b.setAttribute("data-path", path.slice(0, -1));
+ if (breadcrumbs.length > 0) {
+ breadcrumbs.forEach((breadcrumb) => {
+ if (breadcrumb.onclick)
+ return;
+ breadcrumb.onclick = (event) => handleViewHeaderClick(event, this);
+ });
+ }
+ });
+ }
+ });
+ });
+ this.observer.observe(document.body, {
+ childList: true,
+ subtree: true
+ });
+ this.registerEvent(this.app.workspace.on("layout-change", () => {
+ this.loadFileClasses();
+ }));
+ this.registerEvent(this.app.vault.on("delete", (file) => {
+ if (!(file instanceof import_obsidian19.TFile)) {
+ return;
+ }
+ const parentPath = this.getFolderPathFromString(file.path);
+ const parentName = this.getFileNameFromPathString(parentPath);
+ if (parentName !== file.basename) {
+ return;
+ }
+ this.removeCSSClassFromEL(parentPath, "has-folder-note");
+ }));
+ this.registerEvent(this.app.vault.on("create", (file) => {
+ if (file instanceof import_obsidian19.TFile) {
+ const folderName = extractFolderName(this.settings.folderNoteName, file.basename);
+ const folder = getFolder(this, file);
+ if (!folder) {
+ return;
+ }
+ if (folderName !== folder.name) {
+ return;
+ }
+ this.addCSSClassToTitleEL(folder.path, "has-folder-note");
+ this.addCSSClassToTitleEL(file.path, "is-folder-note");
+ }
+ if (!this.app.workspace.layoutReady)
+ return;
+ if (!this.settings.autoCreate)
+ return;
+ if (!(file instanceof import_obsidian19.TFolder))
+ return;
+ const excludedFolder = getExcludedFolder(this, file.path);
+ if (excludedFolder == null ? void 0 : excludedFolder.disableAutoCreate)
+ return;
+ const folderNote = getFolderNote(this, file.path);
+ if (folderNote)
+ return;
+ createFolderNote(this, file.path, true, true);
+ this.addCSSClassToTitleEL(file.path, "has-folder-note");
+ }));
+ this.registerEvent(this.app.workspace.on("file-open", (openFile) => {
+ if (this.activeFolderDom) {
+ this.activeFolderDom.removeClass("is-active");
+ this.activeFolderDom = null;
+ }
+ if (!openFile || !openFile.basename) {
+ return;
+ }
+ const folder = getFolder(this, openFile);
+ if (!folder) {
+ return;
+ }
+ if (extractFolderName(this.settings.folderNoteName, openFile.basename) !== folder.name) {
+ return;
+ }
+ this.activeFolderDom = this.getEL(folder.path);
+ if (this.activeFolderDom)
+ this.activeFolderDom.addClass("is-active");
+ }));
+ this.registerEvent(this.app.vault.on("rename", (file, oldPath) => {
+ if (!this.settings.syncFolderName) {
+ this.removeCSSClassFromEL(file.path, "has-folder-note");
+ this.removeCSSClassFromEL(file.path, "is-folder-note");
+ return;
+ }
+ if (file instanceof import_obsidian19.TFolder) {
+ return handleFolderRename(file, oldPath, this);
+ } else if (file instanceof import_obsidian19.TFile) {
+ return handleFileRename(file, oldPath, this);
+ }
+ }));
+ this.registerEvent(this.app.vault.on("delete", (file) => {
+ if (file instanceof import_obsidian19.TFile) {
+ const folder = getFolder(this, file);
+ if (!folder) {
+ return;
+ }
+ this.removeCSSClassFromEL(folder.path, "has-folder-note");
+ }
+ if (!(file instanceof import_obsidian19.TFolder)) {
+ return;
+ }
+ const folderNote = getFolderNote(this, file.path);
+ if (!folderNote) {
+ return;
+ }
+ this.removeCSSClassFromEL(folderNote.path, "is-folder-note");
+ if (!this.settings.syncDelete) {
+ return;
+ }
+ this.app.vault.delete(folderNote);
+ }));
+ this.registerMarkdownCodeBlockProcessor("folder-overview", (source, el, ctx) => {
+ const observer = new MutationObserver(() => {
+ var _a;
+ const editButton = (_a = el.parentElement) == null ? void 0 : _a.childNodes.item(1);
+ if (editButton) {
+ editButton.addEventListener("click", (e) => {
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ e.stopPropagation();
+ new FolderOverviewSettings(this.app, this, (0, import_obsidian19.parseYaml)(source), ctx, el).open();
+ }, { capture: true });
+ }
+ });
+ observer.observe(el, {
+ childList: true,
+ subtree: true
+ });
+ createOverview(this, source, el, ctx);
+ });
+ if (this.app.workspace.layoutReady) {
+ this.loadFileClasses();
+ } else {
+ this.app.workspace.onLayoutReady(async () => this.loadFileClasses());
+ }
+ }
+ getFileNameFromPathString(path) {
+ return path.substring(path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") + 1 : 0);
+ }
+ getFolderNameFromPathString(path) {
+ if (path.endsWith(".md") || path.endsWith(".canvas")) {
+ return path.split("/").slice(-2)[0];
+ } else {
+ return path.split("/").slice(-1)[0];
+ }
+ }
+ removeExtension(name) {
+ return name.replace(/\.[^/.]+$/, "");
+ }
+ getExtensionFromPathString(path) {
+ return path.slice(path.lastIndexOf(".") >= 0 ? path.lastIndexOf(".") : 0);
+ }
+ getFolderPathFromString(path) {
+ const subString = path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") : 0;
+ return path.substring(0, subString);
+ }
+ getParentFolderPath(path) {
+ return this.getFolderPathFromString(this.getFolderPathFromString(path));
+ }
+ getFileExplorer() {
+ return this.app.workspace.getLeavesOfType("file-explorer")[0];
+ }
+ getFileExplorerView() {
+ return this.getFileExplorer().view;
+ }
+ async addCSSClassToTitleEL(path, cssClass, waitForCreate = false, count = 0) {
+ const fileExplorerItem = this.getEL(path);
+ if (!fileExplorerItem) {
+ if (waitForCreate && count < 5) {
+ await new Promise((r) => setTimeout(r, 500));
+ this.addCSSClassToTitleEL(path, cssClass, waitForCreate, count + 1);
+ return;
+ }
+ return;
+ }
+ fileExplorerItem.addClass(cssClass);
+ const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`);
+ viewHeaderItems.forEach((item) => {
+ item.addClass(cssClass);
+ });
+ }
+ async changeName(folder, name, replacePath, waitForCreate = false, count = 0) {
+ if (!name)
+ name = folder.name;
+ let fileExplorerItem = this.getEL(folder.path);
+ if (!fileExplorerItem) {
+ if (waitForCreate && count < 5) {
+ await new Promise((r) => setTimeout(r, 500));
+ this.changeName(folder, name, replacePath, waitForCreate, count + 1);
+ return;
+ }
+ return;
+ }
+ fileExplorerItem = fileExplorerItem.querySelector("div.nav-folder-title-content");
+ if (!fileExplorerItem) {
+ return;
+ }
+ if (this.settings.frontMatterTitle.explorer && this.settings.frontMatterTitle.enabled) {
+ fileExplorerItem.innerText = name;
+ fileExplorerItem.setAttribute("old-name", folder.name);
+ } else {
+ fileExplorerItem.innerText = folder.name;
+ fileExplorerItem.removeAttribute("old-name");
+ }
+ if (replacePath) {
+ this.updateBreadcrumbs();
+ }
+ }
+ updateBreadcrumbs(remove) {
+ if (!this.settings.frontMatterTitle.path && !remove) {
+ return;
+ }
+ const viewHeaderItems = document.querySelectorAll("span.view-header-breadcrumb");
+ const files = this.app.vault.getAllLoadedFiles().filter((file) => file instanceof import_obsidian19.TFolder);
+ viewHeaderItems.forEach((item) => {
+ if (!item.hasAttribute("data-path")) {
+ return;
+ }
+ const path = item.getAttribute("data-path");
+ const folder = files.find((file) => file.path === path);
+ if (!(folder instanceof import_obsidian19.TFolder)) {
+ return;
+ }
+ if (remove) {
+ item.textContent = folder.name;
+ item.removeAttribute("old-name");
+ } else {
+ item.textContent = folder.newName || folder.name;
+ item.setAttribute("old-name", folder.name);
+ item.setAttribute("data-path", folder.path);
+ }
+ });
+ }
+ removeCSSClassFromEL(path, cssClass) {
+ if (!path)
+ return;
+ const fileExplorerItem = this.getEL(path);
+ const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`);
+ viewHeaderItems.forEach((item) => {
+ item.removeClass(cssClass);
+ });
+ if (!fileExplorerItem) {
+ return;
+ }
+ fileExplorerItem.removeClass(cssClass);
+ }
+ getEL(path) {
+ const fileExplorer = this.getFileExplorer();
+ if (!fileExplorer) {
+ return null;
+ }
+ const fileExplorerItem = fileExplorer.view.fileItems[path];
+ if (!fileExplorerItem) {
+ return null;
+ }
+ if (fileExplorerItem.selfEl)
+ return fileExplorerItem.selfEl;
+ return fileExplorerItem.titleEl;
+ }
+ loadFileClasses(forceReload = false) {
+ if (this.activeFileExplorer === this.getFileExplorer() && !forceReload) {
+ return;
+ }
+ this.activeFileExplorer = this.getFileExplorer();
+ this.app.vault.getAllLoadedFiles().forEach((file) => {
+ if (!(file instanceof import_obsidian19.TFolder)) {
+ return;
+ }
+ const folderNote = getFolderNote(this, file.path);
+ if (!folderNote) {
+ this.removeCSSClassFromEL(file == null ? void 0 : file.path, "has-folder-note");
+ return;
+ }
+ const excludedFolder = getExcludedFolder(this, file.path);
+ if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
+ this.removeCSSClassFromEL(folderNote.path, "is-folder-note");
+ this.removeCSSClassFromEL(file.path, "has-folder-note");
+ } else {
+ this.addCSSClassToTitleEL(folderNote.path, "is-folder-note");
+ this.addCSSClassToTitleEL(file.path, "has-folder-note");
+ }
+ });
+ }
+ reloadHandlers() {
+ document.querySelectorAll("div.nav-folder-title-content").forEach((element) => {
+ if (element.onclick)
+ return;
+ element.onclick = (event) => handleFolderClick(event, this);
+ });
+ }
+ onunload() {
+ console.log("unloading folder notes plugin");
+ this.observer.disconnect();
+ document.body.classList.remove("folder-notes-plugin");
+ document.body.classList.remove("folder-note-underline");
+ document.body.classList.remove("hide-folder-note");
+ document.body.classList.remove("fn-whitespace-stop-collapsing");
+ if (this.activeFolderDom) {
+ this.activeFolderDom.removeClass("is-active");
+ }
+ if (this.fmtpHandler) {
+ this.fmtpHandler.deleteEvent();
+ }
+ }
+ async loadSettings() {
+ this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
+ }
+ async saveSettings() {
+ await this.saveData(this.settings);
+ this.loadFileClasses(true);
+ }
+};
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibm9kZV9tb2R1bGVzL2Zyb250LW1hdHRlci1wbHVnaW4tYXBpLXByb3ZpZGVyL2xpYi9jb250cmFjdHMvQXBpLmpzIiwgIm5vZGVfbW9kdWxlcy9mcm9udC1tYXR0ZXItcGx1Z2luLWFwaS1wcm92aWRlci9saWIvY29udHJhY3RzL0V2ZW50RGlzcGF0Y2hlci5qcyIsICJub2RlX21vZHVsZXMvZnJvbnQtbWF0dGVyLXBsdWdpbi1hcGktcHJvdmlkZXIvbGliL2NvbnRyYWN0cy9SZXNvbHZlci5qcyIsICJub2RlX21vZHVsZXMvZnJvbnQtbWF0dGVyLXBsdWdpbi1hcGktcHJvdmlkZXIvbGliL2luZGV4LmpzIiwgInNyYy9tYWluLnRzIiwgInNyYy9zZXR0aW5ncy50cyIsICJzcmMvc3VnZ2VzdGVycy90ZW1wbGF0ZVN1Z2dlc3Rlci50cyIsICJzcmMvc3VnZ2VzdGVycy9zdWdnZXN0LnRzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZW51bXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZU5hbWUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0V2luZG93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2luc3RhbmNlT2YuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvYXBwbHlTdHlsZXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWF0aC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL3VzZXJBZ2VudC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9pc0xheW91dFZpZXdwb3J0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2NvbnRhaW5zLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldENvbXB1dGVkU3R5bGUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNUYWJsZUVsZW1lbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRFbGVtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFBhcmVudE5vZGUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvd2l0aGluLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0RnJlc2hTaWRlT2JqZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWVyZ2VQYWRkaW5nT2JqZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZXhwYW5kVG9IYXNoTWFwLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2Fycm93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0VmFyaWF0aW9uLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2NvbXB1dGVTdHlsZXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRPcHBvc2l0ZVBsYWNlbWVudC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFdpbmRvd1Njcm9sbC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRXaW5kb3dTY3JvbGxCYXJYLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFZpZXdwb3J0UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXREb2N1bWVudFJlY3QuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNTY3JvbGxQYXJlbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0U2Nyb2xsUGFyZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2xpc3RTY3JvbGxQYXJlbnRzLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvcmVjdFRvQ2xpZW50UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9jb21wdXRlT2Zmc2V0cy5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvY29tcHV0ZUF1dG9QbGFjZW1lbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZmxpcC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9oaWRlLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL29mZnNldC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0QWx0QXhpcy5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wcmV2ZW50T3ZlcmZsb3cuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZVNjcm9sbC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDb21wb3NpdGVSZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvb3JkZXJNb2RpZmllcnMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9kZWJvdW5jZS5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL21lcmdlQnlOYW1lLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvY3JlYXRlUG9wcGVyLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvcG9wcGVyLmpzIiwgInNyYy90ZW1wbGF0ZS50cyIsICJzcmMvbW9kYWxzL2V4aXN0aW5nTm90ZS50cyIsICJzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMudHMiLCAic3JjL21vZGFscy9kZWxldGVDb25maXJtYXRpb24udHMiLCAic3JjL2V4Y2x1ZGVkRm9sZGVyLnRzIiwgInNyYy9tb2RhbHMvZXhjbHVkZUZvbGRlclNldHRpbmdzLnRzIiwgInNyYy9zdWdnZXN0ZXJzL0ZvbGRlclN1Z2dlc3Rlci50cyIsICJzcmMvbW9kYWxzL3BhdHRlcm5TZXR0aW5ncy50cyIsICJzcmMvZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUudHMiLCAic3JjL2NvbW1hbmRzLnRzIiwgInNyYy9ldmVudHMvaGFuZGxlQ2xpY2sudHMiLCAic3JjL2V2ZW50cy9oYW5kbGVSZW5hbWUudHMiLCAic3JjL2ZvbGRlck92ZXJ2aWV3LnRzIiwgInNyYy9tb2RhbHMvZm9sZGVyT3ZlcnZpZXcudHMiLCAic3JjL2Z1bmN0aW9ucy9MaXN0Q29tcG9uZW50LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2NyZWF0ZUJpbmRpbmcgPSAodGhpcyAmJiB0aGlzLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcbiAgICBvW2syXSA9IG1ba107XG59KSk7XG52YXIgX19leHBvcnRTdGFyID0gKHRoaXMgJiYgdGhpcy5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRBcGlTYWZlID0gZXhwb3J0cy5nZXREZWZlciA9IGV4cG9ydHMuaXNQbHVnaW5FbmFibGVkID0gZXhwb3J0cy5QbHVnaW5Ob3RFbmFibGVkRXJyb3IgPSBleHBvcnRzLnBsdWdpbklkID0gdm9pZCAwO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9BcGlcIiksIGV4cG9ydHMpO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9FdmVudERpc3BhdGNoZXJcIiksIGV4cG9ydHMpO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9SZXNvbHZlclwiKSwgZXhwb3J0cyk7XG5leHBvcnRzLnBsdWdpbklkID0gJ29ic2lkaWFuLWZyb250LW1hdHRlci10aXRsZS1wbHVnaW4nO1xuY2xhc3MgUGx1Z2luTm90RW5hYmxlZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuZXhwb3J0cy5QbHVnaW5Ob3RFbmFibGVkRXJyb3IgPSBQbHVnaW5Ob3RFbmFibGVkRXJyb3I7XG4vKipcbiAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgb2JzaWRpYW4tZnJvbnQtbWF0dGVyLXRpdGxlLXBsdWdpbiBpcyBlbmFibGVkXG4gKiBAcGFyYW0gYXBwXG4gKi9cbmZ1bmN0aW9uIGlzUGx1Z2luRW5hYmxlZChhcHApIHtcbiAgICB2YXIgX2EsIF9iLCBfYztcbiAgICAvL0B0cy1pZ25vcmVcbiAgICByZXR1cm4gKF9jID0gKF9iID0gKF9hID0gYXBwID09PSBudWxsIHx8IGFwcCA9PT0gdm9pZCAwID8gdm9pZCAwIDogYXBwLnBsdWdpbnMpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5lbmFibGVkUGx1Z2lucykgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmhhcyhleHBvcnRzLnBsdWdpbklkKSkgIT09IG51bGwgJiYgX2MgIT09IHZvaWQgMCA/IF9jIDogZmFsc2U7XG59XG5leHBvcnRzLmlzUGx1Z2luRW5hYmxlZCA9IGlzUGx1Z2luRW5hYmxlZDtcbi8qKlxuICpcbiAqIEB0aHJvd3MgUGx1Z2luTm90RW5hYmxlZEVycm9yXG4gKi9cbmZ1bmN0aW9uIGdldERlZmVyKGFwcCkge1xuICAgIHZhciBfYSwgX2IsIF9jLCBfZDtcbiAgICAvL0B0cy1pZ25vcmVcbiAgICBjb25zdCBwbHVnaW4gPSAoX2IgPSAoX2EgPSBhcHAgPT09IG51bGwgfHwgYXBwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBhcHAucGx1Z2lucykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldFBsdWdpbihleHBvcnRzLnBsdWdpbklkKSkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogbnVsbDtcbiAgICBjb25zdCBkZWZlciA9IChfZCA9IChfYyA9IHBsdWdpbiA9PT0gbnVsbCB8fCBwbHVnaW4gPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBsdWdpbi5nZXREZWZlcikgPT09IG51bGwgfHwgX2MgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9jLmNhbGwocGx1Z2luKSkgIT09IG51bGwgJiYgX2QgIT09IHZvaWQgMCA/IF9kIDogbnVsbDtcbiAgICBpZiAoZGVmZXIgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBsdWdpbk5vdEVuYWJsZWRFcnJvcihgUGx1Z2luICR7ZXhwb3J0cy5wbHVnaW5JZH0gaXMgbm90IGVuYWJsZWQgb3Igb2xkIHZlcnNpb25gKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmVyO1xufVxuZXhwb3J0cy5nZXREZWZlciA9IGdldERlZmVyO1xuLyoqXG4gKiBXcmFwcGVyIGZvciBvYmplY3QuIEl0IHdpbGwgY2hlY2sgaXRzZWxmIGlmIHBsdWdpbiBpcyBlbmFibGVkIGFuZCByZWFkeVxuICogQHBhcmFtIGFwcFxuICovXG5mdW5jdGlvbiBnZXRBcGlTYWZlKGFwcCkge1xuICAgIHJldHVybiBuZXcgQXBpV3JhcHBlcihudWxsLCBhcHApO1xufVxuZXhwb3J0cy5nZXRBcGlTYWZlID0gZ2V0QXBpU2FmZTtcbmNsYXNzIEFwaVdyYXBwZXIge1xuICAgIGNvbnN0cnVjdG9yKGFwaSwgYXBwKSB7XG4gICAgICAgIHRoaXMuYXBpID0gYXBpO1xuICAgICAgICB0aGlzLmFwcCA9IGFwcDtcbiAgICB9XG4gICAgYmVmb3JlKCkge1xuICAgICAgICBpZiAodGhpcy5hcGkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWZlciA9IHRoaXMuZ2V0RGVmZmVyKCk7XG4gICAgICAgIGlmIChkZWZlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaSA9IGRlZmVyLmdldEFwaSgpO1xuICAgICAgICBpZiAoYXBpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVmZXIuYXdhaXRQbHVnaW4oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwaSA9IGRlZmVyLmdldEFwaSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmFwaSA9IGFwaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXREZWZmZXIoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0RGVmZXIodGhpcy5hcHApO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFBsdWdpbk5vdEVuYWJsZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRSZXNvbHZlckZhY3RvcnkoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldFJlc29sdmVyRmFjdG9yeSgpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBudWxsO1xuICAgIH1cbiAgICBnZXRFdmVudERpc3BhdGNoZXIoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldEV2ZW50RGlzcGF0Y2hlcigpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBudWxsO1xuICAgIH1cbiAgICBnZXRFbmFibGVkRmVhdHVyZXMoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldEVuYWJsZWRGZWF0dXJlcygpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBbXTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBURmlsZSwgVEZvbGRlciwgVEFic3RyYWN0RmlsZSwgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgcGFyc2VZYW1sIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBERUZBVUxUX1NFVFRJTkdTLCBGb2xkZXJOb3Rlc1NldHRpbmdzLCBTZXR0aW5nc1RhYiB9IGZyb20gJy4vc2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBDb21tYW5kcyB9IGZyb20gJy4vY29tbWFuZHMnO1xyXG5pbXBvcnQgeyBGaWxlRXhwbG9yZXJXb3Jrc3BhY2VMZWFmIH0gZnJvbSAnLi9nbG9iYWxzJztcclxuaW1wb3J0IHsgaGFuZGxlVmlld0hlYWRlckNsaWNrLCBoYW5kbGVGb2xkZXJDbGljayB9IGZyb20gJy4vZXZlbnRzL2hhbmRsZUNsaWNrJztcclxuaW1wb3J0IHsgaGFuZGxlRmlsZVJlbmFtZSwgaGFuZGxlRm9sZGVyUmVuYW1lIH0gZnJvbSAnLi9ldmVudHMvaGFuZGxlUmVuYW1lJztcclxuaW1wb3J0IHsgY3JlYXRlRm9sZGVyTm90ZSwgZXh0cmFjdEZvbGRlck5hbWUsIGdldEZvbGRlck5vdGUsIGdldEZvbGRlciB9IGZyb20gJy4vZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBnZXRFeGNsdWRlZEZvbGRlciB9IGZyb20gJy4vZXhjbHVkZWRGb2xkZXInO1xyXG5pbXBvcnQgeyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlciB9IGZyb20gJy4vZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUnO1xyXG5pbXBvcnQgeyBjcmVhdGVPdmVydmlldyBhcyBjcmVhdGVGb2xkZXJPdmVydmlldyB9IGZyb20gJy4vZm9sZGVyT3ZlcnZpZXcnO1xyXG5pbXBvcnQgeyBGb2xkZXJPdmVydmlld1NldHRpbmdzIH0gZnJvbSAnLi9tb2RhbHMvZm9sZGVyT3ZlcnZpZXcnO1xyXG5pbXBvcnQgJy4vZnVuY3Rpb25zL0xpc3RDb21wb25lbnQnO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGb2xkZXJOb3Rlc1BsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblx0b2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXI7XHJcblx0c2V0dGluZ3M6IEZvbGRlck5vdGVzU2V0dGluZ3M7XHJcblx0c2V0dGluZ3NUYWI6IFNldHRpbmdzVGFiO1xyXG5cdGFjdGl2ZUZvbGRlckRvbTogSFRNTEVsZW1lbnQgfCBudWxsO1xyXG5cdGFjdGl2ZUZpbGVFeHBsb3JlcjogRmlsZUV4cGxvcmVyV29ya3NwYWNlTGVhZjtcclxuXHRmbXRwSGFuZGxlcjogRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIgfCBudWxsID0gbnVsbDtcclxuXHRhc3luYyBvbmxvYWQoKSB7XHJcblx0XHRjb25zb2xlLmxvZygnbG9hZGluZyBmb2xkZXIgbm90ZXMgcGx1Z2luJyk7XHJcblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xyXG5cdFx0dGhpcy5zZXR0aW5nc1RhYiA9IG5ldyBTZXR0aW5nc1RhYih0aGlzLmFwcCwgdGhpcyk7XHJcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIodGhpcy5zZXR0aW5nc1RhYik7XHJcblx0XHR0aGlzLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRcdC8vIEFkZCBDU1MgQ2xhc3Nlc1xyXG5cdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmb2xkZXItbm90ZXMtcGx1Z2luJyk7XHJcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5oaWRlRm9sZGVyTm90ZSkgeyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2hpZGUtZm9sZGVyLW5vdGUnKTsgfVxyXG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVyKSB7IGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lJyk7IH1cclxuXHRcdGlmICh0aGlzLnNldHRpbmdzLnVuZGVybGluZUZvbGRlckluUGF0aCkgeyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2ZvbGRlci1ub3RlLXVuZGVybGluZS1wYXRoJyk7IH1cclxuXHRcdGlmICghdGhpcy5zZXR0aW5ncy5hbGxvd1doaXRlc3BhY2VDb2xsYXBzaW5nKSB7IGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTsgfVxyXG5cclxuXHRcdG5ldyBDb21tYW5kcyh0aGlzLmFwcCwgdGhpcykucmVnaXN0ZXJDb21tYW5kcygpO1xyXG5cclxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbkxheW91dFJlYWR5KCgpID0+IHtcclxuXHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5lbmFibGVkKSB7XHJcblx0XHRcdFx0dGhpcy5mbXRwSGFuZGxlciA9IG5ldyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlcih0aGlzKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5vYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnM6IE11dGF0aW9uUmVjb3JkW10pID0+IHtcclxuXHRcdFx0bXV0YXRpb25zLmZvckVhY2goKHJlYykgPT4ge1xyXG5cdFx0XHRcdGlmIChyZWMudHlwZSA9PT0gJ2NoaWxkTGlzdCcpIHtcclxuXHRcdFx0XHRcdCg8RWxlbWVudD5yZWMudGFyZ2V0KS5xdWVyeVNlbGVjdG9yQWxsKCdkaXYubmF2LWZvbGRlci10aXRsZS1jb250ZW50JylcclxuXHRcdFx0XHRcdFx0LmZvckVhY2goKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGVsZW1lbnQub25jbGljaykgcmV0dXJuO1xyXG5cdFx0XHRcdFx0XHRcdGVsZW1lbnQub25jbGljayA9IChldmVudDogTW91c2VFdmVudCkgPT4gaGFuZGxlRm9sZGVyQ2xpY2soZXZlbnQsIHRoaXMpO1xyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdGlmICghdGhpcy5zZXR0aW5ncy5vcGVuRm9sZGVyTm90ZU9uQ2xpY2tJblBhdGgpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0XHQoPEVsZW1lbnQ+cmVjLnRhcmdldCkucXVlcnlTZWxlY3RvckFsbCgnc3Bhbi52aWV3LWhlYWRlci1icmVhZGNydW1iJylcclxuXHRcdFx0XHRcdFx0LmZvckVhY2goKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgYnJlYWRjcnVtYnMgPSBlbGVtZW50LnBhcmVudEVsZW1lbnQ/LnF1ZXJ5U2VsZWN0b3JBbGwoJ3NwYW4udmlldy1oZWFkZXItYnJlYWRjcnVtYicpO1xyXG5cdFx0XHRcdFx0XHRcdGlmICghYnJlYWRjcnVtYnMpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRsZXQgcGF0aCA9ICcnO1xyXG5cdFx0XHRcdFx0XHRcdGJyZWFkY3J1bWJzLmZvckVhY2goKGJyZWFkY3J1bWI6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoYnJlYWRjcnVtYi5oYXNBdHRyaWJ1dGUoJ29sZC1uYW1lJykpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cGF0aCArPSBicmVhZGNydW1iLmdldEF0dHJpYnV0ZSgnb2xkLW5hbWUnKSArICcvJztcclxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHBhdGggKz0gYnJlYWRjcnVtYi5pbm5lclRleHQudHJpbSgpICsgJy8nO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyUGF0aCA9IHBhdGguc2xpY2UoMCwgLTEpO1xyXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5zZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcsIGZvbGRlclBhdGgpO1xyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyID0gdGhpcy5mbXRwSGFuZGxlcj8ubW9kaWZpZWRGb2xkZXJzLmdldChmb2xkZXJQYXRoKTtcclxuXHRcdFx0XHRcdFx0XHRcdGlmIChmb2xkZXIgJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLnBhdGggJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5zZXRBdHRyaWJ1dGUoJ29sZC1uYW1lJywgZm9sZGVyLm5hbWUgfHwgJycpO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhZGNydW1iLmlubmVyVGV4dCA9IGZvbGRlci5uZXdOYW1lIHx8ICcnO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcywgZm9sZGVyUGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoZm9sZGVyTm90ZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhZGNydW1iLmNsYXNzTGlzdC5hZGQoJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHRcdGVsZW1lbnQucGFyZW50RWxlbWVudD8uc2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnLCBwYXRoLnNsaWNlKDAsIC0xKSk7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGJyZWFkY3J1bWJzLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRcdFx0XHRcdGJyZWFkY3J1bWJzLmZvckVhY2goKGJyZWFkY3J1bWI6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGlmIChicmVhZGNydW1iLm9uY2xpY2spIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5vbmNsaWNrID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiBoYW5kbGVWaWV3SGVhZGVyQ2xpY2soZXZlbnQsIHRoaXMpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5vYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LmJvZHksIHtcclxuXHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRzdWJ0cmVlOiB0cnVlLFxyXG5cdFx0fSk7XHJcblx0XHR0aGlzLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAud29ya3NwYWNlLm9uKCdsYXlvdXQtY2hhbmdlJywgKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmxvYWRGaWxlQ2xhc3NlcygpO1xyXG5cdFx0fSkpO1xyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKCdkZWxldGUnLCAoZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7IHJldHVybjsgfVxyXG5cdFx0XHQvLyBwYXJlbnQgaXMgbnVsbCBoZXJlIGV2ZW4gaWYgdGhlIHBhcmVudCBleGlzdHNcclxuXHRcdFx0Ly8gbm90IGVudGlyZWx5IHN1cmUgd2h5XHJcblx0XHRcdGNvbnN0IHBhcmVudFBhdGggPSB0aGlzLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCk7XHJcblx0XHRcdGNvbnN0IHBhcmVudE5hbWUgPSB0aGlzLmdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcocGFyZW50UGF0aCk7XHJcblx0XHRcdGlmIChwYXJlbnROYW1lICE9PSBmaWxlLmJhc2VuYW1lKSB7IHJldHVybjsgfVxyXG5cdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKHBhcmVudFBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbignY3JlYXRlJywgKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBmaWxlLmJhc2VuYW1lKTtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIodGhpcywgZmlsZSk7XHJcblx0XHRcdFx0aWYgKCFmb2xkZXIpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0aWYgKGZvbGRlck5hbWUgIT09IGZvbGRlci5uYW1lKSB7IHJldHVybjsgfVxyXG5cdFx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCF0aGlzLmFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHkpIHJldHVybjtcclxuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLmF1dG9DcmVhdGUpIHJldHVybjtcclxuXHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSByZXR1cm47XHJcblx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gZ2V0RXhjbHVkZWRGb2xkZXIodGhpcywgZmlsZS5wYXRoKTtcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlQXV0b0NyZWF0ZSkgcmV0dXJuO1xyXG5cdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRpZiAoZm9sZGVyTm90ZSkgcmV0dXJuO1xyXG5cdFx0XHRjcmVhdGVGb2xkZXJOb3RlKHRoaXMsIGZpbGUucGF0aCwgdHJ1ZSwgdHJ1ZSk7XHJcblx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZmlsZS5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblxyXG5cdFx0fSkpO1xyXG5cclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC53b3Jrc3BhY2Uub24oJ2ZpbGUtb3BlbicsIChvcGVuRmlsZTogVEZpbGUgfCBudWxsKSA9PiB7XHJcblx0XHRcdGlmICh0aGlzLmFjdGl2ZUZvbGRlckRvbSkge1xyXG5cdFx0XHRcdHRoaXMuYWN0aXZlRm9sZGVyRG9tLnJlbW92ZUNsYXNzKCdpcy1hY3RpdmUnKTtcclxuXHRcdFx0XHR0aGlzLmFjdGl2ZUZvbGRlckRvbSA9IG51bGw7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCFvcGVuRmlsZSB8fCAhb3BlbkZpbGUuYmFzZW5hbWUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLCBvcGVuRmlsZSk7XHJcblx0XHRcdGlmICghZm9sZGVyKSB7IHJldHVybjsgfVxyXG5cdFx0XHRpZiAoZXh0cmFjdEZvbGRlck5hbWUodGhpcy5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgb3BlbkZpbGUuYmFzZW5hbWUpICE9PSBmb2xkZXIubmFtZSkgeyByZXR1cm47IH1cclxuXHRcdFx0dGhpcy5hY3RpdmVGb2xkZXJEb20gPSB0aGlzLmdldEVMKGZvbGRlci5wYXRoKTtcclxuXHRcdFx0aWYgKHRoaXMuYWN0aXZlRm9sZGVyRG9tKSB0aGlzLmFjdGl2ZUZvbGRlckRvbS5hZGRDbGFzcygnaXMtYWN0aXZlJyk7XHJcblx0XHR9KSk7XHJcblxyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKCdyZW5hbWUnLCAoZmlsZTogVEFic3RyYWN0RmlsZSwgb2xkUGF0aDogc3RyaW5nKSA9PiB7XHJcblx0XHRcdGlmICghdGhpcy5zZXR0aW5ncy5zeW5jRm9sZGVyTmFtZSkge1xyXG5cdFx0XHRcdC8vIGNsZWFudXAgYWZ0ZXIgb3Vyc2VsdmVzXHJcblx0XHRcdFx0dGhpcy5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdHJldHVybiBoYW5kbGVGb2xkZXJSZW5hbWUoZmlsZSwgb2xkUGF0aCwgdGhpcyk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0cmV0dXJuIGhhbmRsZUZpbGVSZW5hbWUoZmlsZSwgb2xkUGF0aCwgdGhpcyk7XHJcblx0XHRcdH1cclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbignZGVsZXRlJywgKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLCBmaWxlKTtcclxuXHRcdFx0XHRpZiAoIWZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRpZiAoIWZvbGRlck5vdGUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHRoaXMucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLnN5bmNEZWxldGUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHRoaXMuYXBwLnZhdWx0LmRlbGV0ZShmb2xkZXJOb3RlKTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJNYXJrZG93bkNvZGVCbG9ja1Byb2Nlc3NvcignZm9sZGVyLW92ZXJ2aWV3JywgKHNvdXJjZTogc3RyaW5nLCBlbDogSFRNTEVsZW1lbnQsIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCkgPT4ge1xyXG5cdFx0XHRjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHtcclxuXHRcdFx0XHRjb25zdCBlZGl0QnV0dG9uID0gZWwucGFyZW50RWxlbWVudD8uY2hpbGROb2Rlcy5pdGVtKDEpO1xyXG5cdFx0XHRcdGlmIChlZGl0QnV0dG9uKSB7XHJcblx0XHRcdFx0XHRlZGl0QnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGUpID0+IHtcclxuXHRcdFx0XHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuXHRcdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRcdFx0XHRuZXcgRm9sZGVyT3ZlcnZpZXdTZXR0aW5ncyh0aGlzLmFwcCwgdGhpcywgcGFyc2VZYW1sKHNvdXJjZSksIGN0eCwgZWwpLm9wZW4oKTtcclxuXHRcdFx0XHRcdH0sIHsgY2FwdHVyZTogdHJ1ZSB9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRvYnNlcnZlci5vYnNlcnZlKGVsLCB7XHJcblx0XHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRcdHN1YnRyZWU6IHRydWUsXHJcblx0XHRcdH0pO1xyXG5cdFx0XHRjcmVhdGVGb2xkZXJPdmVydmlldyh0aGlzLCBzb3VyY2UsIGVsLCBjdHgpO1xyXG5cdFx0fSk7XHJcblx0XHRpZiAodGhpcy5hcHAud29ya3NwYWNlLmxheW91dFJlYWR5KSB7XHJcblx0XHRcdHRoaXMubG9hZEZpbGVDbGFzc2VzKCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeShhc3luYyAoKSA9PiB0aGlzLmxvYWRGaWxlQ2xhc3NlcygpKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBwYXRoLnN1YnN0cmluZyhwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpICsgMSA6IDApO1xyXG5cdH1cclxuXHJcblx0Z2V0Rm9sZGVyTmFtZUZyb21QYXRoU3RyaW5nKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRpZiAocGF0aC5lbmRzV2l0aCgnLm1kJykgfHwgcGF0aC5lbmRzV2l0aCgnLmNhbnZhcycpKSB7XHJcblx0XHRcdHJldHVybiBwYXRoLnNwbGl0KCcvJykuc2xpY2UoLTIpWzBdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIHBhdGguc3BsaXQoJy8nKS5zbGljZSgtMSlbMF07XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZW1vdmVFeHRlbnNpb24obmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBuYW1lLnJlcGxhY2UoL1xcLlteLy5dKyQvLCAnJyk7XHJcblx0fVxyXG5cclxuXHRnZXRFeHRlbnNpb25Gcm9tUGF0aFN0cmluZyhwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdFx0cmV0dXJuIHBhdGguc2xpY2UocGF0aC5sYXN0SW5kZXhPZignLicpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcuJykgOiAwKTtcclxuXHR9XHJcblxyXG5cdGdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRjb25zdCBzdWJTdHJpbmcgPSBwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcvJykgOiAwO1xyXG5cdFx0cmV0dXJuIHBhdGguc3Vic3RyaW5nKDAsIHN1YlN0cmluZyk7XHJcblx0fVxyXG5cclxuXHRnZXRQYXJlbnRGb2xkZXJQYXRoKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyh0aGlzLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGgpKTtcclxuXHR9XHJcblxyXG5cdGdldEZpbGVFeHBsb3JlcigpIHtcclxuXHRcdHJldHVybiB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhdmVzT2ZUeXBlKCdmaWxlLWV4cGxvcmVyJylbMF0gYXMgRmlsZUV4cGxvcmVyV29ya3NwYWNlTGVhZjtcclxuXHR9XHJcblxyXG5cdGdldEZpbGVFeHBsb3JlclZpZXcoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRGaWxlRXhwbG9yZXIoKS52aWV3O1xyXG5cdH1cclxuXHJcblx0YXN5bmMgYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aDogc3RyaW5nLCBjc3NDbGFzczogc3RyaW5nLCB3YWl0Rm9yQ3JlYXRlID0gZmFsc2UsIGNvdW50ID0gMCkge1xyXG5cdFx0Y29uc3QgZmlsZUV4cGxvcmVySXRlbSA9IHRoaXMuZ2V0RUwocGF0aCk7XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHtcclxuXHRcdFx0aWYgKHdhaXRGb3JDcmVhdGUgJiYgY291bnQgPCA1KSB7XHJcblx0XHRcdFx0Ly8gc2xlZXAgZm9yIGEgc2Vjb25kIGZvciB0aGUgZmlsZS1leHBsb3JlciBldmVudCB0byBjYXRjaCB1cFxyXG5cdFx0XHRcdC8vIHRoaXMgaXMgYW5ub3lpbmcgYXMgaW4gbW9zdCBzY2FuYXJpb3Mgb3VyIHBsdWdpbiByZWNpZXZlcyB0aGUgZXZlbnQgYmVmb3JlIGZpbGUgZXhwbG9yZXJcclxuXHRcdFx0XHQvLyBJZiB3ZSBjb3VsZCBndWFycmFudGVlIGxvYWQgb3JkZXIgaXQgd291bGRuJ3QgYmUgYW4gaXNzdWUgYnV0IHdlIGNhbid0XHJcblx0XHRcdFx0Ly8gcmVhbGlzZSB0aGlzIGlzIHJhY2V5IGFuZCBuZWVkcyB0byBiZSBmaXhlZC5cclxuXHRcdFx0XHRhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCA1MDApKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKHBhdGgsIGNzc0NsYXNzLCB3YWl0Rm9yQ3JlYXRlLCBjb3VudCArIDEpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtLmFkZENsYXNzKGNzc0NsYXNzKTtcclxuXHRcdGNvbnN0IHZpZXdIZWFkZXJJdGVtcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYFtkYXRhLXBhdGg9XCIke3BhdGh9XCJdYCk7XHJcblx0XHR2aWV3SGVhZGVySXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG5cdFx0XHRpdGVtLmFkZENsYXNzKGNzc0NsYXNzKTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgY2hhbmdlTmFtZShmb2xkZXI6IFRGb2xkZXIsIG5hbWU6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQsIHJlcGxhY2VQYXRoOiBib29sZWFuLCB3YWl0Rm9yQ3JlYXRlID0gZmFsc2UsIGNvdW50ID0gMCkge1xyXG5cdFx0aWYgKCFuYW1lKSBuYW1lID0gZm9sZGVyLm5hbWU7XHJcblx0XHRsZXQgZmlsZUV4cGxvcmVySXRlbSA9IHRoaXMuZ2V0RUwoZm9sZGVyLnBhdGgpO1xyXG5cdFx0aWYgKCFmaWxlRXhwbG9yZXJJdGVtKSB7XHJcblx0XHRcdGlmICh3YWl0Rm9yQ3JlYXRlICYmIGNvdW50IDwgNSkge1xyXG5cdFx0XHRcdGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDUwMCkpO1xyXG5cdFx0XHRcdHRoaXMuY2hhbmdlTmFtZShmb2xkZXIsIG5hbWUsIHJlcGxhY2VQYXRoLCB3YWl0Rm9yQ3JlYXRlLCBjb3VudCArIDEpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtID0gZmlsZUV4cGxvcmVySXRlbS5xdWVyeVNlbGVjdG9yKCdkaXYubmF2LWZvbGRlci10aXRsZS1jb250ZW50JylcclxuXHRcdGlmICghZmlsZUV4cGxvcmVySXRlbSkgeyByZXR1cm47IH1cclxuXHRcdGlmICh0aGlzLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZXhwbG9yZXIgJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpIHtcclxuXHRcdFx0ZmlsZUV4cGxvcmVySXRlbS5pbm5lclRleHQgPSBuYW1lO1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLnNldEF0dHJpYnV0ZSgnb2xkLW5hbWUnLCBmb2xkZXIubmFtZSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLmlubmVyVGV4dCA9IGZvbGRlci5uYW1lO1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLnJlbW92ZUF0dHJpYnV0ZSgnb2xkLW5hbWUnKTtcclxuXHRcdH1cclxuXHRcdGlmIChyZXBsYWNlUGF0aCkge1xyXG5cdFx0XHR0aGlzLnVwZGF0ZUJyZWFkY3J1bWJzKCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHR1cGRhdGVCcmVhZGNydW1icyhyZW1vdmU/OiBib29sZWFuKSB7XHJcblx0XHRpZiAoIXRoaXMuc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5wYXRoICYmICFyZW1vdmUpIHsgcmV0dXJuOyB9XHJcblx0XHRjb25zdCB2aWV3SGVhZGVySXRlbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuLnZpZXctaGVhZGVyLWJyZWFkY3J1bWInKTtcclxuXHRcdGNvbnN0IGZpbGVzID0gdGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKS5maWx0ZXIoKGZpbGUpID0+IGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKTtcclxuXHRcdHZpZXdIZWFkZXJJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdGlmICghaXRlbS5oYXNBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRjb25zdCBwYXRoID0gaXRlbS5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpO1xyXG5cdFx0XHRjb25zdCBmb2xkZXIgPSBmaWxlcy5maW5kKChmaWxlKSA9PiBmaWxlLnBhdGggPT09IHBhdGgpO1xyXG5cdFx0XHRpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKHJlbW92ZSkge1xyXG5cdFx0XHRcdGl0ZW0udGV4dENvbnRlbnQgPSBmb2xkZXIubmFtZTtcclxuXHRcdFx0XHRpdGVtLnJlbW92ZUF0dHJpYnV0ZSgnb2xkLW5hbWUnKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRpdGVtLnRleHRDb250ZW50ID0gZm9sZGVyLm5ld05hbWUgfHwgZm9sZGVyLm5hbWU7XHJcblx0XHRcdFx0aXRlbS5zZXRBdHRyaWJ1dGUoJ29sZC1uYW1lJywgZm9sZGVyLm5hbWUpO1xyXG5cdFx0XHRcdGl0ZW0uc2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnLCBmb2xkZXIucGF0aCk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0cmVtb3ZlQ1NTQ2xhc3NGcm9tRUwocGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLCBjc3NDbGFzczogc3RyaW5nKSB7XHJcblx0XHRpZiAoIXBhdGgpIHJldHVybjtcclxuXHRcdGNvbnN0IGZpbGVFeHBsb3Jlckl0ZW0gPSB0aGlzLmdldEVMKHBhdGgpO1xyXG5cdFx0Y29uc3Qgdmlld0hlYWRlckl0ZW1zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgW2RhdGEtcGF0aD1cIiR7cGF0aH1cIl1gKTtcclxuXHRcdHZpZXdIZWFkZXJJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdGl0ZW0ucmVtb3ZlQ2xhc3MoY3NzQ2xhc3MpO1xyXG5cdFx0fSk7XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHsgcmV0dXJuOyB9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtLnJlbW92ZUNsYXNzKGNzc0NsYXNzKTtcclxuXHR9XHJcblxyXG5cdGdldEVMKHBhdGg6IHN0cmluZyk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XHJcblx0XHRjb25zdCBmaWxlRXhwbG9yZXIgPSB0aGlzLmdldEZpbGVFeHBsb3JlcigpO1xyXG5cdFx0aWYgKCFmaWxlRXhwbG9yZXIpIHsgcmV0dXJuIG51bGw7IH1cclxuXHRcdGNvbnN0IGZpbGVFeHBsb3Jlckl0ZW0gPSBmaWxlRXhwbG9yZXIudmlldy5maWxlSXRlbXNbcGF0aF07XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHsgcmV0dXJuIG51bGw7IH1cclxuXHRcdGlmIChmaWxlRXhwbG9yZXJJdGVtLnNlbGZFbCkgcmV0dXJuIGZpbGVFeHBsb3Jlckl0ZW0uc2VsZkVsO1xyXG5cdFx0cmV0dXJuIGZpbGVFeHBsb3Jlckl0ZW0udGl0bGVFbDtcclxuXHR9XHJcblxyXG5cdGxvYWRGaWxlQ2xhc3Nlcyhmb3JjZVJlbG9hZCA9IGZhbHNlKSB7XHJcblx0XHRpZiAodGhpcy5hY3RpdmVGaWxlRXhwbG9yZXIgPT09IHRoaXMuZ2V0RmlsZUV4cGxvcmVyKCkgJiYgIWZvcmNlUmVsb2FkKSB7IHJldHVybjsgfVxyXG5cdFx0dGhpcy5hY3RpdmVGaWxlRXhwbG9yZXIgPSB0aGlzLmdldEZpbGVFeHBsb3JlcigpO1xyXG5cdFx0dGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKS5mb3JFYWNoKChmaWxlKSA9PiB7XHJcblx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSkgeyByZXR1cm47IH1cclxuXHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcywgZmlsZS5wYXRoKTtcclxuXHRcdFx0aWYgKCFmb2xkZXJOb3RlKSB7XHJcblx0XHRcdFx0dGhpcy5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlPy5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHRoaXMsIGZpbGUucGF0aCk7XHJcblx0XHRcdC8vIGNsZWFudXAgYWZ0ZXIgb3Vyc2VsdmVzXHJcblx0XHRcdC8vIEluY2FzZSBzZXR0aW5ncyBoYXZlIGNoYW5nZWRcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRcdHRoaXMucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHJlbG9hZEhhbmRsZXJzKCkge1xyXG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZGl2Lm5hdi1mb2xkZXItdGl0bGUtY29udGVudCcpXHJcblx0XHRcdC5mb3JFYWNoKChlbGVtZW50OiBIVE1MRWxlbWVudCkgPT4ge1xyXG5cdFx0XHRcdGlmIChlbGVtZW50Lm9uY2xpY2spIHJldHVybjtcclxuXHRcdFx0XHRlbGVtZW50Lm9uY2xpY2sgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IGhhbmRsZUZvbGRlckNsaWNrKGV2ZW50LCB0aGlzKTtcclxuXHRcdFx0fSk7XHJcblx0fVxyXG5cclxuXHRvbnVubG9hZCgpIHtcclxuXHRcdGNvbnNvbGUubG9nKCd1bmxvYWRpbmcgZm9sZGVyIG5vdGVzIHBsdWdpbicpO1xyXG5cdFx0dGhpcy5vYnNlcnZlci5kaXNjb25uZWN0KCk7XHJcblx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZvbGRlci1ub3Rlcy1wbHVnaW4nKTtcclxuXHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lJyk7XHJcblx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUtZm9sZGVyLW5vdGUnKTtcclxuXHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTtcclxuXHRcdGlmICh0aGlzLmFjdGl2ZUZvbGRlckRvbSkgeyB0aGlzLmFjdGl2ZUZvbGRlckRvbS5yZW1vdmVDbGFzcygnaXMtYWN0aXZlJyk7IH1cclxuXHRcdGlmICh0aGlzLmZtdHBIYW5kbGVyKSB7XHJcblx0XHRcdHRoaXMuZm10cEhhbmRsZXIuZGVsZXRlRXZlbnQoKTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cclxuXHRhc3luYyBsb2FkU2V0dGluZ3MoKSB7XHJcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcclxuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XHJcblx0XHQvLyBjbGVhbnVwIGFueSBjc3MgaWYgd2UgbmVlZCB0b29cclxuXHRcdHRoaXMubG9hZEZpbGVDbGFzc2VzKHRydWUpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBOb3RpY2UsIFBsYXRmb3JtLCBQbHVnaW5TZXR0aW5nVGFiLCBTZXR0aW5nLCBURmlsZSwgVEZvbGRlciB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4vbWFpbic7XHJcbmltcG9ydCB7IFRlbXBsYXRlU3VnZ2VzdCB9IGZyb20gJy4vc3VnZ2VzdGVycy90ZW1wbGF0ZVN1Z2dlc3Rlcic7XHJcbmltcG9ydCB7IGV4dHJhY3RGb2xkZXJOYW1lLCBnZXRGb2xkZXJOb3RlIH0gZnJvbSAnLi9mdW5jdGlvbnMvZm9sZGVyTm90ZUZ1bmN0aW9ucyc7XHJcbmltcG9ydCB7IGFkZEV4Y2x1ZGVGb2xkZXJMaXN0SXRlbSwgRXhjbHVkZWRGb2xkZXIsIGFkZEV4Y2x1ZGVkRm9sZGVyLCBFeGNsdWRlUGF0dGVybiwgYWRkRXhjbHVkZVBhdHRlcm5MaXN0SXRlbSB9IGZyb20gJy4vZXhjbHVkZWRGb2xkZXInO1xyXG5pbXBvcnQgeyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlciB9IGZyb20gJy4vZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUnO1xyXG4vLyBpbXBvcnQgQ29uZmlybWF0aW9uTW9kYWwgZnJvbSBcIi4vbW9kYWxzL2NvbmZpcm1DcmVhdGlvblwiO1xyXG5pbXBvcnQgeyB5YW1sU2V0dGluZ3MgfSBmcm9tICcuL2ZvbGRlck92ZXJ2aWV3JztcclxuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJOb3Rlc1NldHRpbmdzIHtcclxuXHRzeW5jRm9sZGVyTmFtZTogYm9vbGVhbjtcclxuXHRjdHJsS2V5OiBib29sZWFuO1xyXG5cdGFsdEtleTogYm9vbGVhbjtcclxuXHRoaWRlRm9sZGVyTm90ZTogYm9vbGVhbjtcclxuXHR0ZW1wbGF0ZVBhdGg6IHN0cmluZztcclxuXHRhdXRvQ3JlYXRlOiBib29sZWFuO1xyXG5cdGVuYWJsZUNvbGxhcHNpbmc6IGJvb2xlYW47XHJcblx0ZXhjbHVkZUZvbGRlcnM6IChFeGNsdWRlUGF0dGVybiB8IEV4Y2x1ZGVkRm9sZGVyKVtdO1xyXG5cdHNob3dEZWxldGVDb25maXJtYXRpb246IGJvb2xlYW47XHJcblx0c2hvd1JlbmFtZUNvbmZpcm1hdGlvbjogYm9vbGVhbjtcclxuXHR1bmRlcmxpbmVGb2xkZXI6IGJvb2xlYW47XHJcblx0YWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZzogYm9vbGVhbjtcclxuXHR1bmRlcmxpbmVGb2xkZXJJblBhdGg6IGJvb2xlYW47XHJcblx0b3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoOiBib29sZWFuO1xyXG5cdG9wZW5Jbk5ld1RhYjogYm9vbGVhbjtcclxuXHRmb2xkZXJOb3RlTmFtZTogc3RyaW5nO1xyXG5cdG5ld0ZvbGRlck5vdGVOYW1lOiBzdHJpbmc7XHJcblx0Zm9sZGVyTm90ZVR5cGU6ICcubWQnIHwgJy5jYW52YXMnO1xyXG5cdGRpc2FibGVGb2xkZXJIaWdobGlnaHRpbmc6IGJvb2xlYW47XHJcblx0c3RvcmFnZUxvY2F0aW9uOiAnaW5zaWRlRm9sZGVyJyB8ICdwYXJlbnRGb2xkZXInIHwgJ3ZhdWx0Rm9sZGVyJztcclxuXHRzeW5jRGVsZXRlOiBib29sZWFuO1xyXG5cdGRlZmF1bHRPdmVydmlldzogeWFtbFNldHRpbmdzO1xyXG5cdHVzZVN1Ym1lbnVzOiBib29sZWFuO1xyXG5cdHN5bmNNb3ZlOiBib29sZWFuO1xyXG5cdGZyb250TWF0dGVyVGl0bGU6IHtcclxuXHRcdGVuYWJsZWQ6IGJvb2xlYW47XHJcblx0XHRleHBsb3JlcjogYm9vbGVhbjtcclxuXHRcdHBhdGg6IGJvb2xlYW47XHJcblx0fVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogRm9sZGVyTm90ZXNTZXR0aW5ncyA9IHtcclxuXHRzeW5jRm9sZGVyTmFtZTogdHJ1ZSxcclxuXHRjdHJsS2V5OiB0cnVlLFxyXG5cdGFsdEtleTogZmFsc2UsXHJcblx0aGlkZUZvbGRlck5vdGU6IHRydWUsXHJcblx0dGVtcGxhdGVQYXRoOiAnJyxcclxuXHRhdXRvQ3JlYXRlOiBmYWxzZSxcclxuXHRlbmFibGVDb2xsYXBzaW5nOiBmYWxzZSxcclxuXHRleGNsdWRlRm9sZGVyczogW10sXHJcblx0c2hvd0RlbGV0ZUNvbmZpcm1hdGlvbjogdHJ1ZSxcclxuXHR1bmRlcmxpbmVGb2xkZXI6IHRydWUsXHJcblx0YWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZzogZmFsc2UsXHJcblx0dW5kZXJsaW5lRm9sZGVySW5QYXRoOiB0cnVlLFxyXG5cdG9wZW5Gb2xkZXJOb3RlT25DbGlja0luUGF0aDogdHJ1ZSxcclxuXHRvcGVuSW5OZXdUYWI6IGZhbHNlLFxyXG5cdGZvbGRlck5vdGVOYW1lOiAne3tmb2xkZXJfbmFtZX19JyxcclxuXHRmb2xkZXJOb3RlVHlwZTogJy5tZCcsXHJcblx0ZGlzYWJsZUZvbGRlckhpZ2hsaWdodGluZzogZmFsc2UsXHJcblx0bmV3Rm9sZGVyTm90ZU5hbWU6ICd7e2ZvbGRlcl9uYW1lfX0nLFxyXG5cdHN0b3JhZ2VMb2NhdGlvbjogJ2luc2lkZUZvbGRlcicsXHJcblx0c3luY0RlbGV0ZTogZmFsc2UsXHJcblx0c2hvd1JlbmFtZUNvbmZpcm1hdGlvbjogdHJ1ZSxcclxuXHRkZWZhdWx0T3ZlcnZpZXc6IHtcclxuXHRcdHRpdGxlOiAne3tmb2xkZXJOYW1lfX0gb3ZlcnZpZXcnLFxyXG5cdFx0ZGlzYWJsZVRpdGxlOiBmYWxzZSxcclxuXHRcdGRlcHRoOiAzLFxyXG5cdFx0aW5jbHVkZVR5cGVzOiBbJ2ZvbGRlcicsICdtYXJrZG93biddLFxyXG5cdFx0c3R5bGU6ICdsaXN0JyxcclxuXHRcdGRpc2FibGVGaWxlVGFnOiBmYWxzZSxcclxuXHR9LFxyXG5cdHVzZVN1Ym1lbnVzOiB0cnVlLFxyXG5cdHN5bmNNb3ZlOiB0cnVlLFxyXG5cdGZyb250TWF0dGVyVGl0bGU6IHtcclxuXHRcdGVuYWJsZWQ6IGZhbHNlLFxyXG5cdFx0ZXhwbG9yZXI6IHRydWUsXHJcblx0XHRwYXRoOiB0cnVlLFxyXG5cdH1cclxufTtcclxuZXhwb3J0IGNsYXNzIFNldHRpbmdzVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XHJcblx0cGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbjtcclxuXHRhcHA6IEFwcDtcclxuXHRleGNsdWRlRm9sZGVyczogRXhjbHVkZWRGb2xkZXJbXTtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdFx0c3VwZXIoYXBwLCBwbHVnaW4pO1xyXG5cdH1cclxuXHRkaXNwbGF5KCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcclxuXHJcblx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xyXG5cclxuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0ZvbGRlciBub3RlcyBzZXR0aW5ncycgfSk7XHJcblxyXG5cdFx0Y29uc3QgbmFtZVNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0ZvbGRlciBub3RlIG5hbWUnKVxyXG5cdFx0XHQuc2V0RGVzYygne3tmb2xkZXJfbmFtZX19IHdpbGwgYmUgcmVwbGFjZWQgd2l0aCB0aGUgbmFtZSBvZiB0aGUgZm9sZGVyJylcclxuXHRcdFx0LmFkZFRleHQoKHRleHQpID0+XHJcblx0XHRcdFx0dGV4dFxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm5ld0ZvbGRlck5vdGVOYW1lKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpZiAodmFsdWUudHJpbSgpID09PSAnJykgeyByZXR1cm47IH1cclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubmV3Rm9sZGVyTm90ZU5hbWUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpXHJcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cclxuXHRcdFx0XHRidXR0b25cclxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KCdSZW5hbWUgZXhpc3RpbmcgZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0XHRcdC5zZXRDdGEoKVxyXG5cdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUZvbGRlck5vdGVzKHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCB0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdGb2xkZXJOb3RlTmFtZSk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0bmFtZVNldHRpbmcuaW5mb0VsLmFwcGVuZFRleHQoJ01ha2Ugc3VyZSB0byBiYWNrIHVwIHlvdXIgdmF1bHQgYmVmb3JlIHJlbmFtaW5nIGFsbCBmb2xkZXIgbm90ZXMgYW5kIHJlc3RhcnQgT2JzaWRpYW4gYWZ0ZXIgcmVuYW1pbmcgdGhlbScpO1xyXG5cdFx0bmFtZVNldHRpbmcuaW5mb0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdGb2xkZXIgbm90ZSB0eXBlJylcclxuXHRcdFx0LnNldERlc2MoJ0Nob29zZSB0aGUgZmlsZSB0eXBlIGZvciBjcmVhdGluZyBuZXcgZm9sZGVyIG5vdGVzIChtYXJrZG93biBvciBjYW52YXMpIG9sZCBmb2xkZXIgbm90ZXMgd2lsbCBub3QgYmUgY2hhbmdlZCBhbmQgeW91IGNhbiBhbHNvIGNyZWF0ZSBjYW52YXMvbWFya2Rvd24gZmlsZXMgYW5kIGNoYW5nZSB0aGUgbmFtZSBtYW51YWxseSB0byB0aGUgY3VzdG9tIGZvbGRlciBub3RlIG5hbWUgb3IgdG8gdGhlIG5hbWUgb2YgdGhlIGZvbGRlci4nKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCcubWQnLCAnbWFya2Rvd24nKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignLmNhbnZhcycsICdjYW52YXMnKVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogJy5tZCcgfCAnLmNhbnZhcycpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCk7XHJcblx0XHRjb25zdCBkZXNjID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xyXG5cdFx0ZGVzYy5hcHBlbmQoXHJcblx0XHRcdCdBZnRlciBzZXR0aW5nIHRoZSB0ZW1wbGF0ZSBwYXRoLCByZXN0YXJ0IE9ic2lkaWFuIGlmIHRoZSB0ZW1wbGF0ZSBmb2xkZXIgcGF0aCAoZnJvbSB0ZW1wbGF0ZXIvdGVtcGxhdGVzKSBoYWQgYmVlbiBjaGFuZ2VkIGJlZm9yZWhhbmQuJyxcclxuXHRcdFx0ZGVzYy5jcmVhdGVFbCgnYnInKSxcclxuXHRcdFx0J09ic2lkaWFuIHNob3VsZCBhbHNvIGJlIHJlc3RhcnRlZCBpZiB0aGUgdGVtcGxhdGUgcGF0aCB3YXMgcmVtb3ZlZC4nXHJcblx0XHQpO1xyXG5cdFx0c2V0dGluZy5zZXROYW1lKCdUZW1wbGF0ZSBwYXRoJyk7XHJcblx0XHRzZXR0aW5nLnNldERlc2MoZGVzYykuZGVzY0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblx0XHRzZXR0aW5nLmFkZFNlYXJjaCgoY2IpID0+IHtcclxuXHRcdFx0bmV3IFRlbXBsYXRlU3VnZ2VzdChjYi5pbnB1dEVsLCB0aGlzLnBsdWdpbik7XHJcblx0XHRcdGNiLnNldFBsYWNlaG9sZGVyKCdUZW1wbGF0ZSBwYXRoJyk7XHJcblx0XHRcdGNiLnNldFZhbHVlKHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgodGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoKT8ubmFtZS5yZXBsYWNlKCcubWQnLCAnJykgfHwgJycpO1xyXG5cdFx0XHRjYi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRpZiAodmFsdWUudHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoID0gJyc7XHJcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRjb25zdCBzdG9yYWdlTG9jYXRpb24gPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ1N0b3JhZ2UgbG9jYXRpb24nKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHdoZXJlIHRvIHN0b3JlIHRoZSBmb2xkZXIgbm90ZXMnKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCdpbnNpZGVGb2xkZXInLCAnSW5zaWRlIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbigncGFyZW50Rm9sZGVyJywgJ0luIHRoZSBwYXJlbnQgZm9sZGVyJylcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24pXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiAnaW5zaWRlRm9sZGVyJyB8ICdwYXJlbnRGb2xkZXInIHwgJ3ZhdWx0Rm9sZGVyJykgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5sb2FkRmlsZUNsYXNzZXMoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblx0XHRzdG9yYWdlTG9jYXRpb24uaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0c3RvcmFnZUxvY2F0aW9uLmluZm9FbC5zdHlsZS5jb2xvciA9IHRoaXMuYXBwLnZhdWx0LmdldENvbmZpZygnYWNjZW50Q29sb3InKSBhcyBzdHJpbmcgfHwgJyM3ZDViZWQnO1xyXG5cclxuXHRcdGNvbnN0IHN3aXRjaExvY2F0aW9uID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdTd2l0Y2ggdG8gbmV3IHN0b3JhZ2UgbG9jYXRpb24nKVxyXG5cdFx0XHQuc2V0RGVzYygnTW92ZSBhbGwgZm9sZGVyIG5vdGVzIHRvIHRoZSBuZXcgc3RvcmFnZSBsb2NhdGlvbicpXHJcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cclxuXHRcdFx0XHRidXR0b25cclxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KCdTd2l0Y2gnKVxyXG5cdFx0XHRcdFx0LnNldEN0YSgpXHJcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XHJcblx0XHRcdFx0XHRcdGxldCBvbGRTdG9yYWdlTG9jYXRpb24gPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb247XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdFx0b2xkU3RvcmFnZUxvY2F0aW9uID0gJ2luc2lkZUZvbGRlcic7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAnaW5zaWRlRm9sZGVyJykge1xyXG5cdFx0XHRcdFx0XHRcdG9sZFN0b3JhZ2VMb2NhdGlvbiA9ICdwYXJlbnRGb2xkZXInO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHRoaXMuc3dpdGNoU3RvcmFnZUxvY2F0aW9uKG9sZFN0b3JhZ2VMb2NhdGlvbik7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0c3dpdGNoTG9jYXRpb24uaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0c3dpdGNoTG9jYXRpb24uaW5mb0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0RlbGV0ZSBmb2xkZXIgbm90ZXMgd2hlbiBkZWxldGluZyB0aGUgZm9sZGVyJylcclxuXHRcdFx0XHQuc2V0RGVzYygnRGVsZXRlIHRoZSBmb2xkZXIgbm90ZSB3aGVuIGRlbGV0aW5nIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Muc3luY0RlbGV0ZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNEZWxldGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ01vdmUgZm9sZGVyIG5vdGVzIHdoZW4gbW92aW5nIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdNb3ZlIHRoZSBmb2xkZXIgbm90ZSB3aGVuIG1vdmluZyB0aGUgZm9sZGVyJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNNb3ZlKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc3luY01vdmUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBkaXNhYmxlU2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKTtcclxuXHRcdGRpc2FibGVTZXR0aW5nLnNldE5hbWUoJ0Rpc2FibGUgZm9sZGVyIGNvbGxhcHNpbmcnKTtcclxuXHRcdGRpc2FibGVTZXR0aW5nLnNldERlc2MoJ0Rpc2FibGUgdGhlIGFiaWxpdHkgdG8gY29sbGFwc2UgZm9sZGVycyBieSBjbGlja2luZyBleGFjdGx5IG9uIHRoZSBmb2xkZXIgbmFtZScpO1xyXG5cdFx0ZGlzYWJsZVNldHRpbmcuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdC5zZXRWYWx1ZSghdGhpcy5wbHVnaW4uc2V0dGluZ3MuZW5hYmxlQ29sbGFwc2luZylcclxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5lbmFibGVDb2xsYXBzaW5nID0gIXZhbHVlO1xyXG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0fSlcclxuXHRcdCk7XHJcblx0XHRkaXNhYmxlU2V0dGluZy5pbmZvRWwuYXBwZW5kVGV4dCgnUmVxdWlyZXMgYSByZXN0YXJ0IHRvIHRha2UgZWZmZWN0Jyk7XHJcblx0XHRkaXNhYmxlU2V0dGluZy5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHJcblx0XHRpZiAoUGxhdGZvcm0uaXNEZXNrdG9wQXBwKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdLZXkgZm9yIGNyZWF0aW5nIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHQuc2V0RGVzYygnVGhlIGtleSBjb21iaW5hdGlvbiB0byBjcmVhdGUgYSBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0LmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xyXG5cdFx0XHRcdFx0aWYgKCFQbGF0Zm9ybS5pc01hY09TKSB7XHJcblx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignY3RybCcsICdDdHJsICsgQ2xpY2snKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignY3RybCcsICdDbWQgKyBDbGljaycpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKCdhbHQnLCAnQWx0ICsgQ2xpY2snKTtcclxuXHRcdFx0XHRcdGRyb3Bkb3duLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmN0cmxLZXkgPyAnY3RybCcgOiAnYWx0Jyk7XHJcblx0XHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuY3RybEtleSA9IHZhbHVlID09PSAnY3RybCc7XHJcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmFsdEtleSA9IHZhbHVlID09PSAnYWx0JztcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdPbmx5IG9wZW4gZm9sZGVyIG5vdGVzIHRocm91Z2ggdGhlIG5hbWUnKVxyXG5cdFx0XHQuc2V0RGVzYygnT25seSBvcGVuIGZvbGRlciBub3RlcyBpbiB0aGUgZmlsZSBleHBsb3JlciBieSBjbGlja2luZyBvbiB0aGUgZm9sZGVyIG5hbWUnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuYWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0aWYgKCF2YWx1ZSkge1xyXG5cdFx0XHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZuLXdoaXRlc3BhY2Utc3RvcC1jb2xsYXBzaW5nJyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdIaWRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0LnNldERlc2MoJ0hpZGUgdGhlIGZvbGRlciBub3RlIGluIHRoZSBmaWxlIGV4cGxvcmVyJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmhpZGVGb2xkZXJOb3RlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5oaWRlRm9sZGVyTm90ZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdoaWRlLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdTeW5jIGZvbGRlciBuYW1lJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgcmVuYW1lIHRoZSBmb2xkZXIgbm90ZSB3aGVuIHRoZSBmb2xkZXIgbmFtZSBpcyBjaGFuZ2VkJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNGb2xkZXJOYW1lKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zeW5jRm9sZGVyTmFtZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0aWYgKFBsYXRmb3JtLmlzRGVza3RvcCkge1xyXG5cdFx0XHRjb25zdCBzZXR0aW5nMyA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKTtcclxuXHRcdFx0c2V0dGluZzMuc2V0TmFtZSgnT3BlbiBmb2xkZXIgbm90ZSBpbiBhIG5ldyB0YWIgYnkgZGVmYXVsdCcpO1xyXG5cdFx0XHRzZXR0aW5nMy5zZXREZXNjKCdBbHdheXMgb3BlbiBmb2xkZXIgbm90ZXMgaW4gYSBuZXcgdGFiIChleGNlcHQgd2hlbiB5b3UgdHJ5IHRvIG9wZW4gdGhlIHNhbWUgbm90ZSkgaW5zdGVhZCBvZiBoYXZpbmcgdG8gdXNlIGN0cmwvY21kICsgY2xpY2sgdG8gb3BlbiBpbiBhIG5ldyB0YWInKTtcclxuXHRcdFx0c2V0dGluZzMuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkluTmV3VGFiKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuSW5OZXdUYWIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdFx0c2V0dGluZzMuaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0XHRzZXR0aW5nMy5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHRcdH1cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnQXV0b21hdGljYWxseSBjcmVhdGUgZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgY3JlYXRlIGEgZm9sZGVyIG5vdGUgd2hlbiBhIG5ldyBmb2xkZXIgaXMgY3JlYXRlZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvQ3JlYXRlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvQ3JlYXRlID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdVc2Ugc3VibWVudXMnKVxyXG5cdFx0XHQuc2V0RGVzYygnVXNlIHN1Ym1lbnVzIGZvciBmaWxlL2ZvbGRlciBjb21tYW5kcycpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VTdWJtZW51cylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlU3VibWVudXMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0FkZCB1bmRlcmxpbmUgdG8gZm9sZGVycyB3aXRoIGZvbGRlciBub3RlcycpXHJcblx0XHRcdC5zZXREZXNjKCdBZGQgYW4gdW5kZXJsaW5lIHRvIGZvbGRlcnMgdGhhdCBoYXZlIGEgZm9sZGVyIG5vdGUgaW4gdGhlIGZpbGUgZXhwbG9yZXInKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVyKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy51bmRlcmxpbmVGb2xkZXIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmb2xkZXItbm90ZS11bmRlcmxpbmUnKTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZvbGRlci1ub3RlLXVuZGVybGluZScpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdPcGVuIGZvbGRlciBub3RlIHRocm91Z2ggcGF0aCcpXHJcblx0XHRcdC5zZXREZXNjKCdPcGVuIGEgZm9sZGVyIG5vdGUgd2hlbiBjbGlja2luZyBvbiBhIGZvbGRlciBuYW1lIGluIHRoZSBwYXRoIGlmIGl0IGlzIGEgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuRm9sZGVyTm90ZU9uQ2xpY2tJblBhdGggPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdVbmRlcmxpbmUgZm9sZGVycyBpbiB0aGUgcGF0aCcpXHJcblx0XHRcdFx0LnNldERlc2MoJ0FkZCBhbiB1bmRlcmxpbmUgdG8gZm9sZGVycyB0aGF0IGhhdmUgYSBmb2xkZXIgbm90ZSBpbiB0aGUgcGF0aCBhYm92ZSBhIG5vdGUnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVySW5QYXRoKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVySW5QYXRoID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2ZvbGRlci1ub3RlLXVuZGVybGluZS1wYXRoJyk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lLXBhdGgnKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0VuYWJsZSBmcm9udCBtYXR0ZXIgdGl0bGUgcGx1Z2luIGludGVncmF0aW9uJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgcmVuYW1lIGEgZm9sZGVyIG5hbWUgd2hlbiB0aGUgZm9sZGVyIG5vdGUgaXMgcmVuYW1lZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZW5hYmxlZCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXIgPSBuZXcgRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIodGhpcy5wbHVnaW4pO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5mbXRwSGFuZGxlcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnModHJ1ZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRGaWxlcygpLmZvckVhY2goKGZpbGUpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmZtdHBIYW5kbGVyPy5oYW5kbGVSZW5hbWUoeyBpZDogJycsIHJlc3VsdDogZmFsc2UsIHBhdGg6IGZpbGUucGF0aCB9LCBmYWxzZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXI/LmRlbGV0ZUV2ZW50KCk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXIgPSBudWxsO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5lbmFibGVkKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdJbmNsdWRlIGZpbGUgZXhwbG9yZXInKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdBdXRvbWF0aWNhbGx5IHJlbmFtZSBhIGZvbGRlciBuYW1lIGluIHRoZSBmaWxlIGV4cGxvcmVyIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIHJlbmFtZWQnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5leHBsb3JlcilcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZXhwbG9yZXIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0RmlsZXMoKS5mb3JFYWNoKChmaWxlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5mbXRwSGFuZGxlcj8uaGFuZGxlUmVuYW1lKHsgaWQ6ICcnLCByZXN1bHQ6IGZhbHNlLCBwYXRoOiBmaWxlLnBhdGggfSwgZmFsc2UpO1xyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0XHQuc2V0TmFtZSgnSW5jbHVkZSBwYXRoIGFib3ZlIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdBdXRvbWF0aWNhbGx5IHJlbmFtZSBhIGZvbGRlciBuYW1lIGluIHRoZSBwYXRoIGFib3ZlIGEgbm90ZSB3aGVuIHRoZSBmb2xkZXIgbm90ZSBpcyByZW5hbWVkJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUucGF0aClcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUucGF0aCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHRcdGlmICh2YWx1ZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnModHJ1ZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRHVlIHRvIGFuIGlzc3VlIHdpdGggdGVtcGxhdGVyIGl0IGhhcyBiZWVuIGRpc2FibGVkIGZvciBub3dcclxuXHRcdC8vIElmIHlvdSB3YW50IHRvIHRyeSBpdCB5b3Vyc2VsZiBtYWtlIGEgcHJcclxuXHRcdC8vIFRoZSBpc3N1ZSB3YXMgdGhhdCBpdCBvbmx5IHVzZWQgdGhlIGZpcnN0IGZvbGRlciBmb3IgYWxsIG9mIHRoZSBvdGhlciBmb2xkZXIgbm90ZXNcclxuXHRcdC8qXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdC5zZXROYW1lKCdDcmVhdGUgZm9sZGVyIG5vdGUgZm9yIGV2ZXJ5IGZvbGRlcicpXHJcblx0XHQuc2V0RGVzYygnQ3JlYXRlIGEgZm9sZGVyIG5vdGUgZm9yIGV2ZXJ5IGZvbGRlciBpbiB0aGUgdmF1bHQnKVxyXG5cdFx0LmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdFx0Y2Iuc2V0SWNvbigncGx1cycpO1xyXG5cdFx0XHRjYi5zZXRUb29sdGlwKCdDcmVhdGUgZm9sZGVyIG5vdGVzJyk7XHJcblx0XHRcdGNiLm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdG5ldyBDb25maXJtYXRpb25Nb2RhbCh0aGlzLmFwcCwgdGhpcy5wbHVnaW4pLm9wZW4oKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHRcdCovXHJcblxyXG5cclxuXHRcdGNvbnN0IG1hbmFnZUV4Y2x1ZGVkID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXRIZWFkaW5nKClcclxuXHRcdFx0LnNldENsYXNzKCdmbi1leGNsdWRlZC1mb2xkZXItaGVhZGluZycpXHJcblx0XHRcdC5zZXROYW1lKCdNYW5hZ2UgZXhjbHVkZWQgZm9sZGVycycpO1xyXG5cdFx0Y29uc3QgZGVzYzMgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XHJcblx0XHRkZXNjMy5hcHBlbmQoXHJcblx0XHRcdCdBZGQge3JlZ2V4fSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmb2xkZXIgbmFtZSB0byB1c2UgYSByZWdleCBwYXR0ZXJuLicsXHJcblx0XHRcdGRlc2MuY3JlYXRlRWwoJ2JyJyksXHJcblx0XHRcdCdVc2UgKiBiZWZvcmUgYW5kIGFmdGVyIHRvIGV4Y2x1ZGUgZm9sZGVycyB0aGF0IGluY2x1ZGUgdGhlIG5hbWUgYmV0d2VlbiB0aGUgKnMuJyxcclxuXHRcdFx0ZGVzYy5jcmVhdGVFbCgnYnInKSxcclxuXHRcdFx0J1VzZSAqIGJlZm9yZSB0aGUgZm9sZGVyIG5hbWUgdG8gZXhjbHVkZSBmb2xkZXJzIHRoYXQgZW5kIHdpdGggdGhlIGZvbGRlciBuYW1lLicsXHJcblx0XHRcdGRlc2MuY3JlYXRlRWwoJ2JyJyksXHJcblx0XHRcdCdVc2UgKiBhZnRlciB0aGUgZm9sZGVyIG5hbWUgdG8gZXhjbHVkZSBmb2xkZXJzIHRoYXQgc3RhcnQgd2l0aCB0aGUgZm9sZGVyIG5hbWUuJyxcclxuXHRcdCk7XHJcblx0XHRtYW5hZ2VFeGNsdWRlZC5zZXREZXNjKGRlc2MzKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5hcHBlbmRUZXh0KCdUaGUgcmVnZXhlcyBhbmQgd2lsZGNhcmRzIGFyZSBvbmx5IGZvciB0aGUgZm9sZGVyIG5hbWUsIG5vdCB0aGUgcGF0aC4nKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5jcmVhdGVFbCgnYnInKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5hcHBlbmRUZXh0KCdJZiB5b3Ugd2FudCB0byBzd2l0Y2ggdG8gYSBmb2xkZXIgcGF0aCBkZWxldGUgdGhlIHBhdHRlcm4gZmlyc3QuJyk7XHJcblx0XHRtYW5hZ2VFeGNsdWRlZC5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0FkZCBleGNsdWRlZCBmb2xkZXInKVxyXG5cdFx0XHQuc2V0Q2xhc3MoJ2FkZC1leGNsdWRlLWZvbGRlci1pdGVtJylcclxuXHRcdFx0LmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdFx0XHRjYi5zZXRJY29uKCdwbHVzJyk7XHJcblx0XHRcdFx0Y2Iuc2V0Q2xhc3MoJ2FkZC1leGNsdWRlLWZvbGRlcicpO1xyXG5cdFx0XHRcdGNiLnNldFRvb2x0aXAoJ0FkZCBleGNsdWRlZCBmb2xkZXInKTtcclxuXHRcdFx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gbmV3IEV4Y2x1ZGVkRm9sZGVyKCcnLCB0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRcdFx0YWRkRXhjbHVkZUZvbGRlckxpc3RJdGVtKHRoaXMsIGNvbnRhaW5lckVsLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdFx0XHRhZGRFeGNsdWRlZEZvbGRlcih0aGlzLnBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuc29ydCgoYSwgYikgPT4gYS5wb3NpdGlvbiAtIGIucG9zaXRpb24pLmZvckVhY2goKGV4Y2x1ZGVkRm9sZGVyKSA9PiB7XHJcblx0XHRcdGlmIChleGNsdWRlZEZvbGRlci5zdHJpbmc/LnRyaW0oKSAhPT0gJycgJiYgZXhjbHVkZWRGb2xkZXIucGF0aD8udHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRcdGFkZEV4Y2x1ZGVQYXR0ZXJuTGlzdEl0ZW0odGhpcywgY29udGFpbmVyRWwsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRhZGRFeGNsdWRlRm9sZGVyTGlzdEl0ZW0odGhpcywgY29udGFpbmVyRWwsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHR1cGRhdGVGb2xkZXJOb3RlcyhvbGRUZW1wbGF0ZTogc3RyaW5nLCBuZXdUZW1wbGF0ZTogc3RyaW5nKSB7XHJcblx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSA9IG5ld1RlbXBsYXRlO1xyXG5cdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRuZXcgTm90aWNlKCdTdGFydGluZyB0byB1cGRhdGUgZm9sZGVyIG5vdGVzLi4uJyk7XHJcblx0XHR0aGlzLmFwcC52YXVsdC5nZXRGaWxlcygpLmZvckVhY2goKGZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlclBhdGggPSB0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpO1xyXG5cdFx0XHRcdGxldCBmb2xkZXIgPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0XHRcdFx0bGV0IGZvbGRlck5hbWUgPSBmaWxlLm5hbWUuc2xpY2UoMCwgLWZpbGUuZXh0ZW5zaW9uLmxlbmd0aCAtIDEpO1xyXG5cdFx0XHRcdGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShvbGRUZW1wbGF0ZSwgZm9sZGVyTmFtZSkgfHwgJyc7XHJcblx0XHRcdFx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikgfHwgZm9sZGVyTmFtZSAhPT0gZm9sZGVyPy5uYW1lKSB7XHJcblx0XHRcdFx0XHRpZiAoZm9sZGVyUGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJOYW1lKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoICsgJy8nICsgZm9sZGVyTmFtZSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICghKGZvbGRlciBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRcdGlmIChmb2xkZXJOYW1lID09PSBmb2xkZXI/Lm5hbWUpIHtcclxuXHRcdFx0XHRcdGNvbnN0IG5ld1BhdGggPSBgJHtmb2xkZXI/LnBhdGh9LyR7dGhpcy5wbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUucmVwbGFjZSgne3tmb2xkZXJfbmFtZX19JywgZm9sZGVyTmFtZSl9LiR7ZmlsZS5leHRlbnNpb259YDtcclxuXHRcdFx0XHRcdHRoaXMuYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBuZXdQYXRoKTtcclxuXHRcdFx0XHR9IGVsc2UgaWYgKGZvbGRlcj8ubmFtZSA9PT0gZmlsZS5uYW1lLnNsaWNlKDAsIC1maWxlLmV4dGVuc2lvbi5sZW5ndGggLSAxKSB8fCAnJykge1xyXG5cdFx0XHRcdFx0Y29uc3QgbmV3UGF0aCA9IGAke2ZvbGRlcj8ucGF0aH0vJHt0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZS5yZXBsYWNlKCd7e2ZvbGRlcl9uYW1lfX0nLCBmaWxlLm5hbWUuc2xpY2UoMCwgLWZpbGUuZXh0ZW5zaW9uLmxlbmd0aCAtIDEpIHx8ICcnKX0uJHtmaWxlLmV4dGVuc2lvbn1gO1xyXG5cdFx0XHRcdFx0dGhpcy5hcHAudmF1bHQucmVuYW1lKGZpbGUsIG5ld1BhdGgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHRuZXcgTm90aWNlKCdGaW5pc2hlZCB1cGRhdGluZyBmb2xkZXIgbm90ZXMnKTtcclxuXHR9XHJcblxyXG5cdHN3aXRjaFN0b3JhZ2VMb2NhdGlvbihvbGRNZXRob2Q6IHN0cmluZykge1xyXG5cdFx0bmV3IE5vdGljZSgnU3RhcnRpbmcgdG8gc3dpdGNoIHN0b3JhZ2UgbG9jYXRpb24uLi4nKTtcclxuXHRcdHRoaXMuYXBwLnZhdWx0LmdldEFsbExvYWRlZEZpbGVzKCkuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZmlsZS5wYXRoLCBvbGRNZXRob2QpO1xyXG5cdFx0XHRcdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdGxldCBuZXdQYXRoID0gJyc7XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXdQYXRoID0gYCR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0bmV3UGF0aCA9IGAke3RoaXMucGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCl9LyR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5hcHAudmF1bHQucmVuYW1lKGZvbGRlck5vdGUsIG5ld1BhdGgpO1xyXG5cdFx0XHRcdFx0fSBlbHNlIGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmb2xkZXJOb3RlLnBhdGgpID09PSBmaWxlLnBhdGgpIHtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgbmV3UGF0aCA9IGAke2ZpbGUucGF0aH0vJHtmb2xkZXJOb3RlLm5hbWV9YDtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmFwcC52YXVsdC5yZW5hbWUoZm9sZGVyTm90ZSwgbmV3UGF0aCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0bmV3IE5vdGljZSgnRmluaXNoZWQgc3dpdGNoaW5nIHN0b3JhZ2UgbG9jYXRpb24nKTtcclxuXHR9XHJcblxyXG59XHJcbiIsICIvLyBDcmVkaXRzIGdvIHRvIExpYW0ncyBQZXJpb2RpYyBOb3RlcyBQbHVnaW46IGh0dHBzOi8vZ2l0aHViLmNvbS9saWFtY2Fpbi9vYnNpZGlhbi1wZXJpb2RpYy1ub3RlcyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL1NpbGVudFZvaWQxMy9UZW1wbGF0ZXJcclxuXHJcbmltcG9ydCB7IFRBYnN0cmFjdEZpbGUsIFRGaWxlLCBURm9sZGVyLCBWYXVsdCB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IHsgVGV4dElucHV0U3VnZ2VzdCB9IGZyb20gJy4vc3VnZ2VzdCc7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IHsgZ2V0VGVtcGxhdGVQbHVnaW5zIH0gZnJvbSAnc3JjL3RlbXBsYXRlJztcclxuZXhwb3J0IGVudW0gRmlsZVN1Z2dlc3RNb2RlIHtcclxuICAgIFRlbXBsYXRlRmlsZXMsXHJcbiAgICBTY3JpcHRGaWxlcyxcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFRlbXBsYXRlU3VnZ2VzdCBleHRlbmRzIFRleHRJbnB1dFN1Z2dlc3Q8VEZpbGU+IHtcclxuXHRjb25zdHJ1Y3RvcihcclxuICAgICAgICBwdWJsaWMgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudCxcclxuICAgICAgICBwcml2YXRlIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW5cclxuXHQpIHtcclxuXHRcdHN1cGVyKGlucHV0RWwpO1xyXG5cdH1cclxuXHJcblxyXG5cdGdldF9lcnJvcl9tc2cobW9kZTogRmlsZVN1Z2dlc3RNb2RlKTogc3RyaW5nIHtcclxuXHRcdHN3aXRjaCAobW9kZSkge1xyXG5cdFx0XHRjYXNlIEZpbGVTdWdnZXN0TW9kZS5UZW1wbGF0ZUZpbGVzOlxyXG5cdFx0XHRcdHJldHVybiAnVGVtcGxhdGVzIGZvbGRlciBkb2VzblxcJ3QgZXhpc3QnO1xyXG5cdFx0XHRjYXNlIEZpbGVTdWdnZXN0TW9kZS5TY3JpcHRGaWxlczpcclxuXHRcdFx0XHRyZXR1cm4gJ1VzZXIgU2NyaXB0cyBmb2xkZXIgZG9lc25cXCd0IGV4aXN0JztcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGdldFN1Z2dlc3Rpb25zKGlucHV0X3N0cjogc3RyaW5nKTogVEZpbGVbXSB7XHJcblx0XHRjb25zdCB7IHRlbXBsYXRlRm9sZGVyLCB0ZW1wbGF0ZXJQbHVnaW4gfSA9IGdldFRlbXBsYXRlUGx1Z2lucyh0aGlzLnBsdWdpbi5hcHApO1xyXG5cdFx0aWYgKCghdGVtcGxhdGVGb2xkZXIgfHwgdGVtcGxhdGVGb2xkZXI/LnRyaW0oKSA9PT0gJycpICYmICF0ZW1wbGF0ZXJQbHVnaW4pIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoID0gJyc7XHJcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRyZXR1cm4gW107XHJcblx0XHR9XHJcblx0XHRsZXQgZm9sZGVyOiBURm9sZGVyO1xyXG5cdFx0aWYgKHRlbXBsYXRlclBsdWdpbikge1xyXG5cdFx0XHRmb2xkZXIgPSB0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHRlbXBsYXRlclBsdWdpbi5wbHVnaW4/LnNldHRpbmdzPy50ZW1wbGF0ZXNfZm9sZGVyIGFzIHN0cmluZykgYXMgVEZvbGRlcjtcclxuXHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXIgPSB0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHRlbXBsYXRlRm9sZGVyKSBhcyBURm9sZGVyO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGZpbGVzOiBURmlsZVtdID0gW107XHJcblx0XHRjb25zdCBsb3dlcl9pbnB1dF9zdHIgPSBpbnB1dF9zdHIudG9Mb3dlckNhc2UoKTtcclxuXHJcblx0XHRWYXVsdC5yZWN1cnNlQ2hpbGRyZW4oZm9sZGVyLCAoZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlICYmXHJcbiAgICAgICAgICAgICAgICBmaWxlLnBhdGgudG9Mb3dlckNhc2UoKS5jb250YWlucyhsb3dlcl9pbnB1dF9zdHIpXHJcblx0XHRcdCkge1xyXG5cdFx0XHRcdGZpbGVzLnB1c2goZmlsZSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHJldHVybiBmaWxlcztcclxuXHR9XHJcblxyXG5cdHJlbmRlclN1Z2dlc3Rpb24oZmlsZTogVEZpbGUsIGVsOiBIVE1MRWxlbWVudCk6IHZvaWQge1xyXG5cdFx0ZWwuc2V0VGV4dChmaWxlLm5hbWUucmVwbGFjZSgnLm1kJywgJycpKTtcclxuXHR9XHJcblxyXG5cdHNlbGVjdFN1Z2dlc3Rpb24oZmlsZTogVEZpbGUpOiB2b2lkIHtcclxuXHRcdHRoaXMuaW5wdXRFbC52YWx1ZSA9IGZpbGUubmFtZS5yZXBsYWNlKCcubWQnLCAnJyk7XHJcblx0XHR0aGlzLmlucHV0RWwudHJpZ2dlcignaW5wdXQnKTtcclxuXHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlUGF0aCA9IGZpbGUucGF0aDtcclxuXHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0dGhpcy5jbG9zZSgpO1xyXG5cdH1cclxufVxyXG4iLCAiLy8gQ3JlZGl0cyBnbyB0byBMaWFtJ3MgUGVyaW9kaWMgTm90ZXMgUGx1Z2luOiBodHRwczovL2dpdGh1Yi5jb20vbGlhbWNhaW4vb2JzaWRpYW4tcGVyaW9kaWMtbm90ZXMgYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9TaWxlbnRWb2lkMTMvVGVtcGxhdGVyXHJcblxyXG5cclxuaW1wb3J0IHsgSVN1Z2dlc3RPd25lciwgU2NvcGUgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IGNyZWF0ZVBvcHBlciwgSW5zdGFuY2UgYXMgUG9wcGVySW5zdGFuY2UgfSBmcm9tICdAcG9wcGVyanMvY29yZSc7XHJcblxyXG5jb25zdCB3cmFwQXJvdW5kID0gKHZhbHVlOiBudW1iZXIsIHNpemU6IG51bWJlcik6IG51bWJlciA9PiB7XHJcblx0cmV0dXJuICgodmFsdWUgJSBzaXplKSArIHNpemUpICUgc2l6ZTtcclxufTtcclxuXHJcbmNsYXNzIFN1Z2dlc3Q8VD4ge1xyXG5cdHByaXZhdGUgb3duZXI6IElTdWdnZXN0T3duZXI8VD47XHJcblx0cHJpdmF0ZSB2YWx1ZXM6IFRbXTtcclxuXHRwcml2YXRlIHN1Z2dlc3Rpb25zOiBIVE1MRGl2RWxlbWVudFtdO1xyXG5cdHByaXZhdGUgc2VsZWN0ZWRJdGVtOiBudW1iZXI7XHJcblx0cHJpdmF0ZSBjb250YWluZXJFbDogSFRNTEVsZW1lbnQ7XHJcblxyXG5cdGNvbnN0cnVjdG9yKFxyXG5cdFx0b3duZXI6IElTdWdnZXN0T3duZXI8VD4sXHJcblx0XHRjb250YWluZXJFbDogSFRNTEVsZW1lbnQsXHJcblx0XHRzY29wZTogU2NvcGVcclxuXHQpIHtcclxuXHRcdHRoaXMub3duZXIgPSBvd25lcjtcclxuXHRcdHRoaXMuY29udGFpbmVyRWwgPSBjb250YWluZXJFbDtcclxuXHJcblx0XHRjb250YWluZXJFbC5vbihcclxuXHRcdFx0J2NsaWNrJyxcclxuXHRcdFx0Jy5zdWdnZXN0aW9uLWl0ZW0nLFxyXG5cdFx0XHR0aGlzLm9uU3VnZ2VzdGlvbkNsaWNrLmJpbmQodGhpcylcclxuXHRcdCk7XHJcblx0XHRjb250YWluZXJFbC5vbihcclxuXHRcdFx0J21vdXNlbW92ZScsXHJcblx0XHRcdCcuc3VnZ2VzdGlvbi1pdGVtJyxcclxuXHRcdFx0dGhpcy5vblN1Z2dlc3Rpb25Nb3VzZW92ZXIuYmluZCh0aGlzKVxyXG5cdFx0KTtcclxuXHJcblx0XHRzY29wZS5yZWdpc3RlcihbXSwgJ0Fycm93VXAnLCAoZXZlbnQpID0+IHtcclxuXHRcdFx0aWYgKCFldmVudC5pc0NvbXBvc2luZykge1xyXG5cdFx0XHRcdHRoaXMuc2V0U2VsZWN0ZWRJdGVtKHRoaXMuc2VsZWN0ZWRJdGVtIC0gMSwgdHJ1ZSk7XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRzY29wZS5yZWdpc3RlcihbXSwgJ0Fycm93RG93bicsIChldmVudCkgPT4ge1xyXG5cdFx0XHRpZiAoIWV2ZW50LmlzQ29tcG9zaW5nKSB7XHJcblx0XHRcdFx0dGhpcy5zZXRTZWxlY3RlZEl0ZW0odGhpcy5zZWxlY3RlZEl0ZW0gKyAxLCB0cnVlKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHNjb3BlLnJlZ2lzdGVyKFtdLCAnRW50ZXInLCAoZXZlbnQpID0+IHtcclxuXHRcdFx0aWYgKCFldmVudC5pc0NvbXBvc2luZykge1xyXG5cdFx0XHRcdHRoaXMudXNlU2VsZWN0ZWRJdGVtKGV2ZW50KTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0b25TdWdnZXN0aW9uQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIGVsOiBIVE1MRGl2RWxlbWVudCk6IHZvaWQge1xyXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHJcblx0XHRjb25zdCBpdGVtID0gdGhpcy5zdWdnZXN0aW9ucy5pbmRleE9mKGVsKTtcclxuXHRcdHRoaXMuc2V0U2VsZWN0ZWRJdGVtKGl0ZW0sIGZhbHNlKTtcclxuXHRcdHRoaXMudXNlU2VsZWN0ZWRJdGVtKGV2ZW50KTtcclxuXHR9XHJcblxyXG5cdG9uU3VnZ2VzdGlvbk1vdXNlb3ZlcihfZXZlbnQ6IE1vdXNlRXZlbnQsIGVsOiBIVE1MRGl2RWxlbWVudCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaXRlbSA9IHRoaXMuc3VnZ2VzdGlvbnMuaW5kZXhPZihlbCk7XHJcblx0XHR0aGlzLnNldFNlbGVjdGVkSXRlbShpdGVtLCBmYWxzZSk7XHJcblx0fVxyXG5cclxuXHRzZXRTdWdnZXN0aW9ucyh2YWx1ZXM6IFRbXSkge1xyXG5cdFx0dGhpcy5jb250YWluZXJFbC5lbXB0eSgpO1xyXG5cdFx0Y29uc3Qgc3VnZ2VzdGlvbkVsczogSFRNTERpdkVsZW1lbnRbXSA9IFtdO1xyXG5cclxuXHRcdHZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBzdWdnZXN0aW9uRWwgPSB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZURpdignc3VnZ2VzdGlvbi1pdGVtJyk7XHJcblx0XHRcdHRoaXMub3duZXIucmVuZGVyU3VnZ2VzdGlvbih2YWx1ZSwgc3VnZ2VzdGlvbkVsKTtcclxuXHRcdFx0c3VnZ2VzdGlvbkVscy5wdXNoKHN1Z2dlc3Rpb25FbCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR0aGlzLnZhbHVlcyA9IHZhbHVlcztcclxuXHRcdHRoaXMuc3VnZ2VzdGlvbnMgPSBzdWdnZXN0aW9uRWxzO1xyXG5cdFx0dGhpcy5zZXRTZWxlY3RlZEl0ZW0oMCwgZmFsc2UpO1xyXG5cdH1cclxuXHJcblx0dXNlU2VsZWN0ZWRJdGVtKGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCkge1xyXG5cdFx0Y29uc3QgY3VycmVudFZhbHVlID0gdGhpcy52YWx1ZXNbdGhpcy5zZWxlY3RlZEl0ZW1dO1xyXG5cdFx0aWYgKGN1cnJlbnRWYWx1ZSkge1xyXG5cdFx0XHR0aGlzLm93bmVyLnNlbGVjdFN1Z2dlc3Rpb24oY3VycmVudFZhbHVlLCBldmVudCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRzZXRTZWxlY3RlZEl0ZW0oc2VsZWN0ZWRJbmRleDogbnVtYmVyLCBzY3JvbGxJbnRvVmlldzogYm9vbGVhbikge1xyXG5cdFx0Y29uc3Qgbm9ybWFsaXplZEluZGV4ID0gd3JhcEFyb3VuZChcclxuXHRcdFx0c2VsZWN0ZWRJbmRleCxcclxuXHRcdFx0dGhpcy5zdWdnZXN0aW9ucy5sZW5ndGhcclxuXHRcdCk7XHJcblx0XHRjb25zdCBwcmV2U2VsZWN0ZWRTdWdnZXN0aW9uID0gdGhpcy5zdWdnZXN0aW9uc1t0aGlzLnNlbGVjdGVkSXRlbV07XHJcblx0XHRjb25zdCBzZWxlY3RlZFN1Z2dlc3Rpb24gPSB0aGlzLnN1Z2dlc3Rpb25zW25vcm1hbGl6ZWRJbmRleF07XHJcblxyXG5cdFx0cHJldlNlbGVjdGVkU3VnZ2VzdGlvbj8ucmVtb3ZlQ2xhc3MoJ2lzLXNlbGVjdGVkJyk7XHJcblx0XHRzZWxlY3RlZFN1Z2dlc3Rpb24/LmFkZENsYXNzKCdpcy1zZWxlY3RlZCcpO1xyXG5cclxuXHRcdHRoaXMuc2VsZWN0ZWRJdGVtID0gbm9ybWFsaXplZEluZGV4O1xyXG5cclxuXHRcdGlmIChzY3JvbGxJbnRvVmlldykge1xyXG5cdFx0XHRzZWxlY3RlZFN1Z2dlc3Rpb24uc2Nyb2xsSW50b1ZpZXcoZmFsc2UpO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFRleHRJbnB1dFN1Z2dlc3Q8VD4gaW1wbGVtZW50cyBJU3VnZ2VzdE93bmVyPFQ+IHtcclxuXHRwcm90ZWN0ZWQgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudCB8IEhUTUxUZXh0QXJlYUVsZW1lbnQ7XHJcblxyXG5cdHByaXZhdGUgcG9wcGVyOiBQb3BwZXJJbnN0YW5jZTtcclxuXHRwcml2YXRlIHNjb3BlOiBTY29wZTtcclxuXHRwcml2YXRlIHN1Z2dlc3RFbDogSFRNTEVsZW1lbnQ7XHJcblx0cHJpdmF0ZSBzdWdnZXN0OiBTdWdnZXN0PFQ+O1xyXG5cclxuXHRjb25zdHJ1Y3RvcihpbnB1dEVsOiBIVE1MSW5wdXRFbGVtZW50IHwgSFRNTFRleHRBcmVhRWxlbWVudCkge1xyXG5cdFx0dGhpcy5pbnB1dEVsID0gaW5wdXRFbDtcclxuXHRcdHRoaXMuc2NvcGUgPSBuZXcgU2NvcGUoKTtcclxuXHJcblx0XHR0aGlzLnN1Z2dlc3RFbCA9IGNyZWF0ZURpdignc3VnZ2VzdGlvbi1jb250YWluZXInKTtcclxuXHRcdGNvbnN0IHN1Z2dlc3Rpb24gPSB0aGlzLnN1Z2dlc3RFbC5jcmVhdGVEaXYoJ3N1Z2dlc3Rpb24nKTtcclxuXHRcdHRoaXMuc3VnZ2VzdCA9IG5ldyBTdWdnZXN0KHRoaXMsIHN1Z2dlc3Rpb24sIHRoaXMuc2NvcGUpO1xyXG5cclxuXHRcdHRoaXMuc2NvcGUucmVnaXN0ZXIoW10sICdFc2NhcGUnLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xyXG5cclxuXHRcdHRoaXMuaW5wdXRFbC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHRoaXMub25JbnB1dENoYW5nZWQuYmluZCh0aGlzKSk7XHJcblx0XHR0aGlzLmlucHV0RWwuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCB0aGlzLm9uSW5wdXRDaGFuZ2VkLmJpbmQodGhpcykpO1xyXG5cdFx0dGhpcy5pbnB1dEVsLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xyXG5cdFx0dGhpcy5zdWdnZXN0RWwub24oXHJcblx0XHRcdCdtb3VzZWRvd24nLFxyXG5cdFx0XHQnLnN1Z2dlc3Rpb24tY29udGFpbmVyJyxcclxuXHRcdFx0KGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0fVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdG9uSW5wdXRDaGFuZ2VkKCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaW5wdXRTdHIgPSB0aGlzLmlucHV0RWwudmFsdWU7XHJcblx0XHRjb25zdCBzdWdnZXN0aW9ucyA9IHRoaXMuZ2V0U3VnZ2VzdGlvbnMoaW5wdXRTdHIpO1xyXG5cclxuXHRcdGlmICghc3VnZ2VzdGlvbnMpIHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHN1Z2dlc3Rpb25zLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0dGhpcy5zdWdnZXN0LnNldFN1Z2dlc3Rpb25zKHN1Z2dlc3Rpb25zKTtcclxuXHRcdFx0Ly8gQHRzLWlnbm9yZVxyXG5cdFx0XHR0aGlzLm9wZW4oYXBwLmRvbS5hcHBDb250YWluZXJFbCwgdGhpcy5pbnB1dEVsKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdG9wZW4oY29udGFpbmVyOiBIVE1MRWxlbWVudCwgaW5wdXRFbDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcclxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XHJcblx0XHRhcHAua2V5bWFwLnB1c2hTY29wZSh0aGlzLnNjb3BlKTtcclxuXHJcblx0XHRjb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5zdWdnZXN0RWwpO1xyXG5cdFx0dGhpcy5wb3BwZXIgPSBjcmVhdGVQb3BwZXIoaW5wdXRFbCwgdGhpcy5zdWdnZXN0RWwsIHtcclxuXHRcdFx0cGxhY2VtZW50OiAnYm90dG9tLXN0YXJ0JyxcclxuXHRcdFx0bW9kaWZpZXJzOiBbXHJcblx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0bmFtZTogJ3NhbWVXaWR0aCcsXHJcblx0XHRcdFx0XHRlbmFibGVkOiB0cnVlLFxyXG5cdFx0XHRcdFx0Zm46ICh7IHN0YXRlLCBpbnN0YW5jZSB9KSA9PiB7XHJcblx0XHRcdFx0XHRcdC8vIE5vdGU6IHBvc2l0aW9uaW5nIG5lZWRzIHRvIGJlIGNhbGN1bGF0ZWQgdHdpY2UgLVxyXG5cdFx0XHRcdFx0XHQvLyBmaXJzdCBwYXNzIC0gcG9zaXRpb25pbmcgaXQgYWNjb3JkaW5nIHRvIHRoZSB3aWR0aCBvZiB0aGUgcG9wcGVyXHJcblx0XHRcdFx0XHRcdC8vIHNlY29uZCBwYXNzIC0gcG9zaXRpb24gaXQgd2l0aCB0aGUgd2lkdGggYm91bmQgdG8gdGhlIHJlZmVyZW5jZSBlbGVtZW50XHJcblx0XHRcdFx0XHRcdC8vIHdlIG5lZWQgdG8gZWFybHkgZXhpdCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wXHJcblx0XHRcdFx0XHRcdGNvbnN0IHRhcmdldFdpZHRoID0gYCR7c3RhdGUucmVjdHMucmVmZXJlbmNlLndpZHRofXB4YDtcclxuXHRcdFx0XHRcdFx0aWYgKHN0YXRlLnN0eWxlcy5wb3BwZXIud2lkdGggPT09IHRhcmdldFdpZHRoKSB7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHN0YXRlLnN0eWxlcy5wb3BwZXIud2lkdGggPSB0YXJnZXRXaWR0aDtcclxuXHRcdFx0XHRcdFx0aW5zdGFuY2UudXBkYXRlKCk7XHJcblx0XHRcdFx0XHR9LFxyXG5cdFx0XHRcdFx0cGhhc2U6ICdiZWZvcmVXcml0ZScsXHJcblx0XHRcdFx0XHRyZXF1aXJlczogWydjb21wdXRlU3R5bGVzJ10sXHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XSxcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Y2xvc2UoKTogdm9pZCB7XHJcblx0XHRhcHAua2V5bWFwLnBvcFNjb3BlKHRoaXMuc2NvcGUpO1xyXG5cclxuXHRcdHRoaXMuc3VnZ2VzdC5zZXRTdWdnZXN0aW9ucyhbXSk7XHJcblx0XHRpZiAodGhpcy5wb3BwZXIpIHRoaXMucG9wcGVyLmRlc3Ryb3koKTtcclxuXHRcdHRoaXMuc3VnZ2VzdEVsLmRldGFjaCgpO1xyXG5cdH1cclxuXHJcbiAgICBhYnN0cmFjdCBnZXRTdWdnZXN0aW9ucyhpbnB1dFN0cjogc3RyaW5nKTogVFtdO1xyXG4gICAgYWJzdHJhY3QgcmVuZGVyU3VnZ2VzdGlvbihpdGVtOiBULCBlbDogSFRNTEVsZW1lbnQpOiB2b2lkO1xyXG4gICAgYWJzdHJhY3Qgc2VsZWN0U3VnZ2VzdGlvbihpdGVtOiBUKTogdm9pZDtcclxufVxyXG4iLCAiZXhwb3J0IHZhciB0b3AgPSAndG9wJztcbmV4cG9ydCB2YXIgYm90dG9tID0gJ2JvdHRvbSc7XG5leHBvcnQgdmFyIHJpZ2h0ID0gJ3JpZ2h0JztcbmV4cG9ydCB2YXIgbGVmdCA9ICdsZWZ0JztcbmV4cG9ydCB2YXIgYXV0byA9ICdhdXRvJztcbmV4cG9ydCB2YXIgYmFzZVBsYWNlbWVudHMgPSBbdG9wLCBib3R0b20sIHJpZ2h0LCBsZWZ0XTtcbmV4cG9ydCB2YXIgc3RhcnQgPSAnc3RhcnQnO1xuZXhwb3J0IHZhciBlbmQgPSAnZW5kJztcbmV4cG9ydCB2YXIgY2xpcHBpbmdQYXJlbnRzID0gJ2NsaXBwaW5nUGFyZW50cyc7XG5leHBvcnQgdmFyIHZpZXdwb3J0ID0gJ3ZpZXdwb3J0JztcbmV4cG9ydCB2YXIgcG9wcGVyID0gJ3BvcHBlcic7XG5leHBvcnQgdmFyIHJlZmVyZW5jZSA9ICdyZWZlcmVuY2UnO1xuZXhwb3J0IHZhciB2YXJpYXRpb25QbGFjZW1lbnRzID0gLyojX19QVVJFX18qL2Jhc2VQbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIGFjYy5jb25jYXQoW3BsYWNlbWVudCArIFwiLVwiICsgc3RhcnQsIHBsYWNlbWVudCArIFwiLVwiICsgZW5kXSk7XG59LCBbXSk7XG5leHBvcnQgdmFyIHBsYWNlbWVudHMgPSAvKiNfX1BVUkVfXyovW10uY29uY2F0KGJhc2VQbGFjZW1lbnRzLCBbYXV0b10pLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIGFjYy5jb25jYXQoW3BsYWNlbWVudCwgcGxhY2VtZW50ICsgXCItXCIgKyBzdGFydCwgcGxhY2VtZW50ICsgXCItXCIgKyBlbmRdKTtcbn0sIFtdKTsgLy8gbW9kaWZpZXJzIHRoYXQgbmVlZCB0byByZWFkIHRoZSBET01cblxuZXhwb3J0IHZhciBiZWZvcmVSZWFkID0gJ2JlZm9yZVJlYWQnO1xuZXhwb3J0IHZhciByZWFkID0gJ3JlYWQnO1xuZXhwb3J0IHZhciBhZnRlclJlYWQgPSAnYWZ0ZXJSZWFkJzsgLy8gcHVyZS1sb2dpYyBtb2RpZmllcnNcblxuZXhwb3J0IHZhciBiZWZvcmVNYWluID0gJ2JlZm9yZU1haW4nO1xuZXhwb3J0IHZhciBtYWluID0gJ21haW4nO1xuZXhwb3J0IHZhciBhZnRlck1haW4gPSAnYWZ0ZXJNYWluJzsgLy8gbW9kaWZpZXIgd2l0aCB0aGUgcHVycG9zZSB0byB3cml0ZSB0byB0aGUgRE9NIChvciB3cml0ZSBpbnRvIGEgZnJhbWV3b3JrIHN0YXRlKVxuXG5leHBvcnQgdmFyIGJlZm9yZVdyaXRlID0gJ2JlZm9yZVdyaXRlJztcbmV4cG9ydCB2YXIgd3JpdGUgPSAnd3JpdGUnO1xuZXhwb3J0IHZhciBhZnRlcldyaXRlID0gJ2FmdGVyV3JpdGUnO1xuZXhwb3J0IHZhciBtb2RpZmllclBoYXNlcyA9IFtiZWZvcmVSZWFkLCByZWFkLCBhZnRlclJlYWQsIGJlZm9yZU1haW4sIG1haW4sIGFmdGVyTWFpbiwgYmVmb3JlV3JpdGUsIHdyaXRlLCBhZnRlcldyaXRlXTsiLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Tm9kZU5hbWUoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudCA/IChlbGVtZW50Lm5vZGVOYW1lIHx8ICcnKS50b0xvd2VyQ2FzZSgpIDogbnVsbDtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHtcbiAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgIHJldHVybiB3aW5kb3c7XG4gIH1cblxuICBpZiAobm9kZS50b1N0cmluZygpICE9PSAnW29iamVjdCBXaW5kb3ddJykge1xuICAgIHZhciBvd25lckRvY3VtZW50ID0gbm9kZS5vd25lckRvY3VtZW50O1xuICAgIHJldHVybiBvd25lckRvY3VtZW50ID8gb3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3cgOiB3aW5kb3c7XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn0iLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcblxuZnVuY3Rpb24gaXNFbGVtZW50KG5vZGUpIHtcbiAgdmFyIE93bkVsZW1lbnQgPSBnZXRXaW5kb3cobm9kZSkuRWxlbWVudDtcbiAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBPd25FbGVtZW50IHx8IG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50O1xufVxuXG5mdW5jdGlvbiBpc0hUTUxFbGVtZW50KG5vZGUpIHtcbiAgdmFyIE93bkVsZW1lbnQgPSBnZXRXaW5kb3cobm9kZSkuSFRNTEVsZW1lbnQ7XG4gIHJldHVybiBub2RlIGluc3RhbmNlb2YgT3duRWxlbWVudCB8fCBub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGlzU2hhZG93Um9vdChub2RlKSB7XG4gIC8vIElFIDExIGhhcyBubyBTaGFkb3dSb290XG4gIGlmICh0eXBlb2YgU2hhZG93Um9vdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgT3duRWxlbWVudCA9IGdldFdpbmRvdyhub2RlKS5TaGFkb3dSb290O1xuICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIE93bkVsZW1lbnQgfHwgbm9kZSBpbnN0YW5jZW9mIFNoYWRvd1Jvb3Q7XG59XG5cbmV4cG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCwgaXNTaGFkb3dSb290IH07IiwgImltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4uL2RvbS11dGlscy9pbnN0YW5jZU9mLmpzXCI7IC8vIFRoaXMgbW9kaWZpZXIgdGFrZXMgdGhlIHN0eWxlcyBwcmVwYXJlZCBieSB0aGUgYGNvbXB1dGVTdHlsZXNgIG1vZGlmaWVyXG4vLyBhbmQgYXBwbGllcyB0aGVtIHRvIHRoZSBIVE1MRWxlbWVudHMgc3VjaCBhcyBwb3BwZXIgYW5kIGFycm93XG5cbmZ1bmN0aW9uIGFwcGx5U3R5bGVzKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZTtcbiAgT2JqZWN0LmtleXMoc3RhdGUuZWxlbWVudHMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB2YXIgc3R5bGUgPSBzdGF0ZS5zdHlsZXNbbmFtZV0gfHwge307XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSBzdGF0ZS5hdHRyaWJ1dGVzW25hbWVdIHx8IHt9O1xuICAgIHZhciBlbGVtZW50ID0gc3RhdGUuZWxlbWVudHNbbmFtZV07IC8vIGFycm93IGlzIG9wdGlvbmFsICsgdmlydHVhbCBlbGVtZW50c1xuXG4gICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsZW1lbnQpIHx8ICFnZXROb2RlTmFtZShlbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gRmxvdyBkb2Vzbid0IHN1cHBvcnQgdG8gZXh0ZW5kIHRoaXMgcHJvcGVydHksIGJ1dCBpdCdzIHRoZSBtb3N0XG4gICAgLy8gZWZmZWN0aXZlIHdheSB0byBhcHBseSBzdHlsZXMgdG8gYW4gSFRNTEVsZW1lbnRcbiAgICAvLyAkRmxvd0ZpeE1lW2Nhbm5vdC13cml0ZV1cblxuXG4gICAgT2JqZWN0LmFzc2lnbihlbGVtZW50LnN0eWxlLCBzdHlsZSk7XG4gICAgT2JqZWN0LmtleXMoYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgICAgdmFyIHZhbHVlID0gYXR0cmlidXRlc1tuYW1lXTtcblxuICAgICAgaWYgKHZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlID09PSB0cnVlID8gJycgOiB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGU7XG4gIHZhciBpbml0aWFsU3R5bGVzID0ge1xuICAgIHBvcHBlcjoge1xuICAgICAgcG9zaXRpb246IHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBsZWZ0OiAnMCcsXG4gICAgICB0b3A6ICcwJyxcbiAgICAgIG1hcmdpbjogJzAnXG4gICAgfSxcbiAgICBhcnJvdzoge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcbiAgICB9LFxuICAgIHJlZmVyZW5jZToge31cbiAgfTtcbiAgT2JqZWN0LmFzc2lnbihzdGF0ZS5lbGVtZW50cy5wb3BwZXIuc3R5bGUsIGluaXRpYWxTdHlsZXMucG9wcGVyKTtcbiAgc3RhdGUuc3R5bGVzID0gaW5pdGlhbFN0eWxlcztcblxuICBpZiAoc3RhdGUuZWxlbWVudHMuYXJyb3cpIHtcbiAgICBPYmplY3QuYXNzaWduKHN0YXRlLmVsZW1lbnRzLmFycm93LnN0eWxlLCBpbml0aWFsU3R5bGVzLmFycm93KTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgT2JqZWN0LmtleXMoc3RhdGUuZWxlbWVudHMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gc3RhdGUuZWxlbWVudHNbbmFtZV07XG4gICAgICB2YXIgYXR0cmlidXRlcyA9IHN0YXRlLmF0dHJpYnV0ZXNbbmFtZV0gfHwge307XG4gICAgICB2YXIgc3R5bGVQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoc3RhdGUuc3R5bGVzLmhhc093blByb3BlcnR5KG5hbWUpID8gc3RhdGUuc3R5bGVzW25hbWVdIDogaW5pdGlhbFN0eWxlc1tuYW1lXSk7IC8vIFNldCBhbGwgdmFsdWVzIHRvIGFuIGVtcHR5IHN0cmluZyB0byB1bnNldCB0aGVtXG5cbiAgICAgIHZhciBzdHlsZSA9IHN0eWxlUHJvcGVydGllcy5yZWR1Y2UoZnVuY3Rpb24gKHN0eWxlLCBwcm9wZXJ0eSkge1xuICAgICAgICBzdHlsZVtwcm9wZXJ0eV0gPSAnJztcbiAgICAgICAgcmV0dXJuIHN0eWxlO1xuICAgICAgfSwge30pOyAvLyBhcnJvdyBpcyBvcHRpb25hbCArIHZpcnR1YWwgZWxlbWVudHNcblxuICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsZW1lbnQpIHx8ICFnZXROb2RlTmFtZShlbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIE9iamVjdC5hc3NpZ24oZWxlbWVudC5zdHlsZSwgc3R5bGUpO1xuICAgICAgT2JqZWN0LmtleXMoYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKGF0dHJpYnV0ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2FwcGx5U3R5bGVzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICd3cml0ZScsXG4gIGZuOiBhcHBseVN0eWxlcyxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIHJlcXVpcmVzOiBbJ2NvbXB1dGVTdHlsZXMnXVxufTsiLCAiaW1wb3J0IHsgYXV0byB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5zcGxpdCgnLScpWzBdO1xufSIsICJleHBvcnQgdmFyIG1heCA9IE1hdGgubWF4O1xuZXhwb3J0IHZhciBtaW4gPSBNYXRoLm1pbjtcbmV4cG9ydCB2YXIgcm91bmQgPSBNYXRoLnJvdW5kOyIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRVQVN0cmluZygpIHtcbiAgdmFyIHVhRGF0YSA9IG5hdmlnYXRvci51c2VyQWdlbnREYXRhO1xuXG4gIGlmICh1YURhdGEgIT0gbnVsbCAmJiB1YURhdGEuYnJhbmRzICYmIEFycmF5LmlzQXJyYXkodWFEYXRhLmJyYW5kcykpIHtcbiAgICByZXR1cm4gdWFEYXRhLmJyYW5kcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBpdGVtLmJyYW5kICsgXCIvXCIgKyBpdGVtLnZlcnNpb247XG4gICAgfSkuam9pbignICcpO1xuICB9XG5cbiAgcmV0dXJuIG5hdmlnYXRvci51c2VyQWdlbnQ7XG59IiwgImltcG9ydCBnZXRVQVN0cmluZyBmcm9tIFwiLi4vdXRpbHMvdXNlckFnZW50LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc0xheW91dFZpZXdwb3J0KCkge1xuICByZXR1cm4gIS9eKCg/IWNocm9tZXxhbmRyb2lkKS4pKnNhZmFyaS9pLnRlc3QoZ2V0VUFTdHJpbmcoKSk7XG59IiwgImltcG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcbmltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgaXNMYXlvdXRWaWV3cG9ydCBmcm9tIFwiLi9pc0xheW91dFZpZXdwb3J0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCwgaW5jbHVkZVNjYWxlLCBpc0ZpeGVkU3RyYXRlZ3kpIHtcbiAgaWYgKGluY2x1ZGVTY2FsZSA9PT0gdm9pZCAwKSB7XG4gICAgaW5jbHVkZVNjYWxlID0gZmFsc2U7XG4gIH1cblxuICBpZiAoaXNGaXhlZFN0cmF0ZWd5ID09PSB2b2lkIDApIHtcbiAgICBpc0ZpeGVkU3RyYXRlZ3kgPSBmYWxzZTtcbiAgfVxuXG4gIHZhciBjbGllbnRSZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgdmFyIHNjYWxlWCA9IDE7XG4gIHZhciBzY2FsZVkgPSAxO1xuXG4gIGlmIChpbmNsdWRlU2NhbGUgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSkge1xuICAgIHNjYWxlWCA9IGVsZW1lbnQub2Zmc2V0V2lkdGggPiAwID8gcm91bmQoY2xpZW50UmVjdC53aWR0aCkgLyBlbGVtZW50Lm9mZnNldFdpZHRoIHx8IDEgOiAxO1xuICAgIHNjYWxlWSA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0ID4gMCA/IHJvdW5kKGNsaWVudFJlY3QuaGVpZ2h0KSAvIGVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IDEgOiAxO1xuICB9XG5cbiAgdmFyIF9yZWYgPSBpc0VsZW1lbnQoZWxlbWVudCkgPyBnZXRXaW5kb3coZWxlbWVudCkgOiB3aW5kb3csXG4gICAgICB2aXN1YWxWaWV3cG9ydCA9IF9yZWYudmlzdWFsVmlld3BvcnQ7XG5cbiAgdmFyIGFkZFZpc3VhbE9mZnNldHMgPSAhaXNMYXlvdXRWaWV3cG9ydCgpICYmIGlzRml4ZWRTdHJhdGVneTtcbiAgdmFyIHggPSAoY2xpZW50UmVjdC5sZWZ0ICsgKGFkZFZpc3VhbE9mZnNldHMgJiYgdmlzdWFsVmlld3BvcnQgPyB2aXN1YWxWaWV3cG9ydC5vZmZzZXRMZWZ0IDogMCkpIC8gc2NhbGVYO1xuICB2YXIgeSA9IChjbGllbnRSZWN0LnRvcCArIChhZGRWaXN1YWxPZmZzZXRzICYmIHZpc3VhbFZpZXdwb3J0ID8gdmlzdWFsVmlld3BvcnQub2Zmc2V0VG9wIDogMCkpIC8gc2NhbGVZO1xuICB2YXIgd2lkdGggPSBjbGllbnRSZWN0LndpZHRoIC8gc2NhbGVYO1xuICB2YXIgaGVpZ2h0ID0gY2xpZW50UmVjdC5oZWlnaHQgLyBzY2FsZVk7XG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0LFxuICAgIHRvcDogeSxcbiAgICByaWdodDogeCArIHdpZHRoLFxuICAgIGJvdHRvbTogeSArIGhlaWdodCxcbiAgICBsZWZ0OiB4LFxuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiOyAvLyBSZXR1cm5zIHRoZSBsYXlvdXQgcmVjdCBvZiBhbiBlbGVtZW50IHJlbGF0aXZlIHRvIGl0cyBvZmZzZXRQYXJlbnQuIExheW91dFxuLy8gbWVhbnMgaXQgZG9lc24ndCB0YWtlIGludG8gYWNjb3VudCB0cmFuc2Zvcm1zLlxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRMYXlvdXRSZWN0KGVsZW1lbnQpIHtcbiAgdmFyIGNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCk7IC8vIFVzZSB0aGUgY2xpZW50UmVjdCBzaXplcyBpZiBpdCdzIG5vdCBiZWVuIHRyYW5zZm9ybWVkLlxuICAvLyBGaXhlcyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzEyMjNcblxuICB2YXIgd2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuICB2YXIgaGVpZ2h0ID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG5cbiAgaWYgKE1hdGguYWJzKGNsaWVudFJlY3Qud2lkdGggLSB3aWR0aCkgPD0gMSkge1xuICAgIHdpZHRoID0gY2xpZW50UmVjdC53aWR0aDtcbiAgfVxuXG4gIGlmIChNYXRoLmFicyhjbGllbnRSZWN0LmhlaWdodCAtIGhlaWdodCkgPD0gMSkge1xuICAgIGhlaWdodCA9IGNsaWVudFJlY3QuaGVpZ2h0O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBlbGVtZW50Lm9mZnNldExlZnQsXG4gICAgeTogZWxlbWVudC5vZmZzZXRUb3AsXG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0XG4gIH07XG59IiwgImltcG9ydCB7IGlzU2hhZG93Um9vdCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbnRhaW5zKHBhcmVudCwgY2hpbGQpIHtcbiAgdmFyIHJvb3ROb2RlID0gY2hpbGQuZ2V0Um9vdE5vZGUgJiYgY2hpbGQuZ2V0Um9vdE5vZGUoKTsgLy8gRmlyc3QsIGF0dGVtcHQgd2l0aCBmYXN0ZXIgbmF0aXZlIG1ldGhvZFxuXG4gIGlmIChwYXJlbnQuY29udGFpbnMoY2hpbGQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gLy8gdGhlbiBmYWxsYmFjayB0byBjdXN0b20gaW1wbGVtZW50YXRpb24gd2l0aCBTaGFkb3cgRE9NIHN1cHBvcnRcbiAgZWxzZSBpZiAocm9vdE5vZGUgJiYgaXNTaGFkb3dSb290KHJvb3ROb2RlKSkge1xuICAgICAgdmFyIG5leHQgPSBjaGlsZDtcblxuICAgICAgZG8ge1xuICAgICAgICBpZiAobmV4dCAmJiBwYXJlbnQuaXNTYW1lTm9kZShuZXh0KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXTogbmVlZCBhIGJldHRlciB3YXkgdG8gaGFuZGxlIHRoaXMuLi5cblxuXG4gICAgICAgIG5leHQgPSBuZXh0LnBhcmVudE5vZGUgfHwgbmV4dC5ob3N0O1xuICAgICAgfSB3aGlsZSAobmV4dCk7XG4gICAgfSAvLyBHaXZlIHVwLCB0aGUgcmVzdWx0IGlzIGZhbHNlXG5cblxuICByZXR1cm4gZmFsc2U7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFdpbmRvdyhlbGVtZW50KS5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xufSIsICJpbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGlzVGFibGVFbGVtZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuIFsndGFibGUnLCAndGQnLCAndGgnXS5pbmRleE9mKGdldE5vZGVOYW1lKGVsZW1lbnQpKSA+PSAwO1xufSIsICJpbXBvcnQgeyBpc0VsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkge1xuICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dOiBhc3N1bWUgYm9keSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gIHJldHVybiAoKGlzRWxlbWVudChlbGVtZW50KSA/IGVsZW1lbnQub3duZXJEb2N1bWVudCA6IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICBlbGVtZW50LmRvY3VtZW50KSB8fCB3aW5kb3cuZG9jdW1lbnQpLmRvY3VtZW50RWxlbWVudDtcbn0iLCAiaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IHsgaXNTaGFkb3dSb290IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0UGFyZW50Tm9kZShlbGVtZW50KSB7XG4gIGlmIChnZXROb2RlTmFtZShlbGVtZW50KSA9PT0gJ2h0bWwnKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICByZXR1cm4gKC8vIHRoaXMgaXMgYSBxdWlja2VyIChidXQgbGVzcyB0eXBlIHNhZmUpIHdheSB0byBzYXZlIHF1aXRlIHNvbWUgYnl0ZXMgZnJvbSB0aGUgYnVuZGxlXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtcmV0dXJuXVxuICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgIGVsZW1lbnQuYXNzaWduZWRTbG90IHx8IC8vIHN0ZXAgaW50byB0aGUgc2hhZG93IERPTSBvZiB0aGUgcGFyZW50IG9mIGEgc2xvdHRlZCBub2RlXG4gICAgZWxlbWVudC5wYXJlbnROb2RlIHx8ICggLy8gRE9NIEVsZW1lbnQgZGV0ZWN0ZWRcbiAgICBpc1NoYWRvd1Jvb3QoZWxlbWVudCkgPyBlbGVtZW50Lmhvc3QgOiBudWxsKSB8fCAvLyBTaGFkb3dSb290IGRldGVjdGVkXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF06IEhUTUxFbGVtZW50IGlzIGEgTm9kZVxuICAgIGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KSAvLyBmYWxsYmFja1xuXG4gICk7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCBnZXRDb21wdXRlZFN0eWxlIGZyb20gXCIuL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQsIGlzU2hhZG93Um9vdCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBpc1RhYmxlRWxlbWVudCBmcm9tIFwiLi9pc1RhYmxlRWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGdldFVBU3RyaW5nIGZyb20gXCIuLi91dGlscy91c2VyQWdlbnQuanNcIjtcblxuZnVuY3Rpb24gZ2V0VHJ1ZU9mZnNldFBhcmVudChlbGVtZW50KSB7XG4gIGlmICghaXNIVE1MRWxlbWVudChlbGVtZW50KSB8fCAvLyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzgzN1xuICBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLnBvc2l0aW9uID09PSAnZml4ZWQnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudC5vZmZzZXRQYXJlbnQ7XG59IC8vIGAub2Zmc2V0UGFyZW50YCByZXBvcnRzIGBudWxsYCBmb3IgZml4ZWQgZWxlbWVudHMsIHdoaWxlIGFic29sdXRlIGVsZW1lbnRzXG4vLyByZXR1cm4gdGhlIGNvbnRhaW5pbmcgYmxvY2tcblxuXG5mdW5jdGlvbiBnZXRDb250YWluaW5nQmxvY2soZWxlbWVudCkge1xuICB2YXIgaXNGaXJlZm94ID0gL2ZpcmVmb3gvaS50ZXN0KGdldFVBU3RyaW5nKCkpO1xuICB2YXIgaXNJRSA9IC9UcmlkZW50L2kudGVzdChnZXRVQVN0cmluZygpKTtcblxuICBpZiAoaXNJRSAmJiBpc0hUTUxFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgLy8gSW4gSUUgOSwgMTAgYW5kIDExIGZpeGVkIGVsZW1lbnRzIGNvbnRhaW5pbmcgYmxvY2sgaXMgYWx3YXlzIGVzdGFibGlzaGVkIGJ5IHRoZSB2aWV3cG9ydFxuICAgIHZhciBlbGVtZW50Q3NzID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcblxuICAgIGlmIChlbGVtZW50Q3NzLnBvc2l0aW9uID09PSAnZml4ZWQnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICB2YXIgY3VycmVudE5vZGUgPSBnZXRQYXJlbnROb2RlKGVsZW1lbnQpO1xuXG4gIGlmIChpc1NoYWRvd1Jvb3QoY3VycmVudE5vZGUpKSB7XG4gICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5ob3N0O1xuICB9XG5cbiAgd2hpbGUgKGlzSFRNTEVsZW1lbnQoY3VycmVudE5vZGUpICYmIFsnaHRtbCcsICdib2R5J10uaW5kZXhPZihnZXROb2RlTmFtZShjdXJyZW50Tm9kZSkpIDwgMCkge1xuICAgIHZhciBjc3MgPSBnZXRDb21wdXRlZFN0eWxlKGN1cnJlbnROb2RlKTsgLy8gVGhpcyBpcyBub24tZXhoYXVzdGl2ZSBidXQgY292ZXJzIHRoZSBtb3N0IGNvbW1vbiBDU1MgcHJvcGVydGllcyB0aGF0XG4gICAgLy8gY3JlYXRlIGEgY29udGFpbmluZyBibG9jay5cbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ29udGFpbmluZ19ibG9jayNpZGVudGlmeWluZ190aGVfY29udGFpbmluZ19ibG9ja1xuXG4gICAgaWYgKGNzcy50cmFuc2Zvcm0gIT09ICdub25lJyB8fCBjc3MucGVyc3BlY3RpdmUgIT09ICdub25lJyB8fCBjc3MuY29udGFpbiA9PT0gJ3BhaW50JyB8fCBbJ3RyYW5zZm9ybScsICdwZXJzcGVjdGl2ZSddLmluZGV4T2YoY3NzLndpbGxDaGFuZ2UpICE9PSAtMSB8fCBpc0ZpcmVmb3ggJiYgY3NzLndpbGxDaGFuZ2UgPT09ICdmaWx0ZXInIHx8IGlzRmlyZWZveCAmJiBjc3MuZmlsdGVyICYmIGNzcy5maWx0ZXIgIT09ICdub25lJykge1xuICAgICAgcmV0dXJuIGN1cnJlbnROb2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLnBhcmVudE5vZGU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59IC8vIEdldHMgdGhlIGNsb3Nlc3QgYW5jZXN0b3IgcG9zaXRpb25lZCBlbGVtZW50LiBIYW5kbGVzIHNvbWUgZWRnZSBjYXNlcyxcbi8vIHN1Y2ggYXMgdGFibGUgYW5jZXN0b3JzIGFuZCBjcm9zcyBicm93c2VyIGJ1Z3MuXG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpIHtcbiAgdmFyIHdpbmRvdyA9IGdldFdpbmRvdyhlbGVtZW50KTtcbiAgdmFyIG9mZnNldFBhcmVudCA9IGdldFRydWVPZmZzZXRQYXJlbnQoZWxlbWVudCk7XG5cbiAgd2hpbGUgKG9mZnNldFBhcmVudCAmJiBpc1RhYmxlRWxlbWVudChvZmZzZXRQYXJlbnQpICYmIGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpIHtcbiAgICBvZmZzZXRQYXJlbnQgPSBnZXRUcnVlT2Zmc2V0UGFyZW50KG9mZnNldFBhcmVudCk7XG4gIH1cblxuICBpZiAob2Zmc2V0UGFyZW50ICYmIChnZXROb2RlTmFtZShvZmZzZXRQYXJlbnQpID09PSAnaHRtbCcgfHwgZ2V0Tm9kZU5hbWUob2Zmc2V0UGFyZW50KSA9PT0gJ2JvZHknICYmIGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpKSB7XG4gICAgcmV0dXJuIHdpbmRvdztcbiAgfVxuXG4gIHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZ2V0Q29udGFpbmluZ0Jsb2NrKGVsZW1lbnQpIHx8IHdpbmRvdztcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KHBsYWNlbWVudCkge1xuICByZXR1cm4gWyd0b3AnLCAnYm90dG9tJ10uaW5kZXhPZihwbGFjZW1lbnQpID49IDAgPyAneCcgOiAneSc7XG59IiwgImltcG9ydCB7IG1heCBhcyBtYXRoTWF4LCBtaW4gYXMgbWF0aE1pbiB9IGZyb20gXCIuL21hdGguanNcIjtcbmV4cG9ydCBmdW5jdGlvbiB3aXRoaW4obWluLCB2YWx1ZSwgbWF4KSB7XG4gIHJldHVybiBtYXRoTWF4KG1pbiwgbWF0aE1pbih2YWx1ZSwgbWF4KSk7XG59XG5leHBvcnQgZnVuY3Rpb24gd2l0aGluTWF4Q2xhbXAobWluLCB2YWx1ZSwgbWF4KSB7XG4gIHZhciB2ID0gd2l0aGluKG1pbiwgdmFsdWUsIG1heCk7XG4gIHJldHVybiB2ID4gbWF4ID8gbWF4IDogdjtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RnJlc2hTaWRlT2JqZWN0KCkge1xuICByZXR1cm4ge1xuICAgIHRvcDogMCxcbiAgICByaWdodDogMCxcbiAgICBib3R0b206IDAsXG4gICAgbGVmdDogMFxuICB9O1xufSIsICJpbXBvcnQgZ2V0RnJlc2hTaWRlT2JqZWN0IGZyb20gXCIuL2dldEZyZXNoU2lkZU9iamVjdC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbWVyZ2VQYWRkaW5nT2JqZWN0KHBhZGRpbmdPYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGdldEZyZXNoU2lkZU9iamVjdCgpLCBwYWRkaW5nT2JqZWN0KTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZXhwYW5kVG9IYXNoTWFwKHZhbHVlLCBrZXlzKSB7XG4gIHJldHVybiBrZXlzLnJlZHVjZShmdW5jdGlvbiAoaGFzaE1hcCwga2V5KSB7XG4gICAgaGFzaE1hcFtrZXldID0gdmFsdWU7XG4gICAgcmV0dXJuIGhhc2hNYXA7XG4gIH0sIHt9KTtcbn0iLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGNvbnRhaW5zIGZyb20gXCIuLi9kb20tdXRpbHMvY29udGFpbnMuanNcIjtcbmltcG9ydCBnZXRPZmZzZXRQYXJlbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE1haW5BeGlzRnJvbVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgd2l0aGluIH0gZnJvbSBcIi4uL3V0aWxzL3dpdGhpbi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi4vdXRpbHMvbWVyZ2VQYWRkaW5nT2JqZWN0LmpzXCI7XG5pbXBvcnQgZXhwYW5kVG9IYXNoTWFwIGZyb20gXCIuLi91dGlscy9leHBhbmRUb0hhc2hNYXAuanNcIjtcbmltcG9ydCB7IGxlZnQsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdG9wLCBib3R0b20gfSBmcm9tIFwiLi4vZW51bXMuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG52YXIgdG9QYWRkaW5nT2JqZWN0ID0gZnVuY3Rpb24gdG9QYWRkaW5nT2JqZWN0KHBhZGRpbmcsIHN0YXRlKSB7XG4gIHBhZGRpbmcgPSB0eXBlb2YgcGFkZGluZyA9PT0gJ2Z1bmN0aW9uJyA/IHBhZGRpbmcoT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVjdHMsIHtcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KSkgOiBwYWRkaW5nO1xuICByZXR1cm4gbWVyZ2VQYWRkaW5nT2JqZWN0KHR5cGVvZiBwYWRkaW5nICE9PSAnbnVtYmVyJyA/IHBhZGRpbmcgOiBleHBhbmRUb0hhc2hNYXAocGFkZGluZywgYmFzZVBsYWNlbWVudHMpKTtcbn07XG5cbmZ1bmN0aW9uIGFycm93KF9yZWYpIHtcbiAgdmFyIF9zdGF0ZSRtb2RpZmllcnNEYXRhJDtcblxuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XG4gIHZhciBhcnJvd0VsZW1lbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdztcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHM7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgYXhpcyA9IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudChiYXNlUGxhY2VtZW50KTtcbiAgdmFyIGlzVmVydGljYWwgPSBbbGVmdCwgcmlnaHRdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgPj0gMDtcbiAgdmFyIGxlbiA9IGlzVmVydGljYWwgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG5cbiAgaWYgKCFhcnJvd0VsZW1lbnQgfHwgIXBvcHBlck9mZnNldHMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGFkZGluZ09iamVjdCA9IHRvUGFkZGluZ09iamVjdChvcHRpb25zLnBhZGRpbmcsIHN0YXRlKTtcbiAgdmFyIGFycm93UmVjdCA9IGdldExheW91dFJlY3QoYXJyb3dFbGVtZW50KTtcbiAgdmFyIG1pblByb3AgPSBheGlzID09PSAneScgPyB0b3AgOiBsZWZ0O1xuICB2YXIgbWF4UHJvcCA9IGF4aXMgPT09ICd5JyA/IGJvdHRvbSA6IHJpZ2h0O1xuICB2YXIgZW5kRGlmZiA9IHN0YXRlLnJlY3RzLnJlZmVyZW5jZVtsZW5dICsgc3RhdGUucmVjdHMucmVmZXJlbmNlW2F4aXNdIC0gcG9wcGVyT2Zmc2V0c1theGlzXSAtIHN0YXRlLnJlY3RzLnBvcHBlcltsZW5dO1xuICB2YXIgc3RhcnREaWZmID0gcG9wcGVyT2Zmc2V0c1theGlzXSAtIHN0YXRlLnJlY3RzLnJlZmVyZW5jZVtheGlzXTtcbiAgdmFyIGFycm93T2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KGFycm93RWxlbWVudCk7XG4gIHZhciBjbGllbnRTaXplID0gYXJyb3dPZmZzZXRQYXJlbnQgPyBheGlzID09PSAneScgPyBhcnJvd09mZnNldFBhcmVudC5jbGllbnRIZWlnaHQgfHwgMCA6IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudFdpZHRoIHx8IDAgOiAwO1xuICB2YXIgY2VudGVyVG9SZWZlcmVuY2UgPSBlbmREaWZmIC8gMiAtIHN0YXJ0RGlmZiAvIDI7IC8vIE1ha2Ugc3VyZSB0aGUgYXJyb3cgZG9lc24ndCBvdmVyZmxvdyB0aGUgcG9wcGVyIGlmIHRoZSBjZW50ZXIgcG9pbnQgaXNcbiAgLy8gb3V0c2lkZSBvZiB0aGUgcG9wcGVyIGJvdW5kc1xuXG4gIHZhciBtaW4gPSBwYWRkaW5nT2JqZWN0W21pblByb3BdO1xuICB2YXIgbWF4ID0gY2xpZW50U2l6ZSAtIGFycm93UmVjdFtsZW5dIC0gcGFkZGluZ09iamVjdFttYXhQcm9wXTtcbiAgdmFyIGNlbnRlciA9IGNsaWVudFNpemUgLyAyIC0gYXJyb3dSZWN0W2xlbl0gLyAyICsgY2VudGVyVG9SZWZlcmVuY2U7XG4gIHZhciBvZmZzZXQgPSB3aXRoaW4obWluLCBjZW50ZXIsIG1heCk7IC8vIFByZXZlbnRzIGJyZWFraW5nIHN5bnRheCBoaWdobGlnaHRpbmcuLi5cblxuICB2YXIgYXhpc1Byb3AgPSBheGlzO1xuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gKF9zdGF0ZSRtb2RpZmllcnNEYXRhJCA9IHt9LCBfc3RhdGUkbW9kaWZpZXJzRGF0YSRbYXhpc1Byb3BdID0gb2Zmc2V0LCBfc3RhdGUkbW9kaWZpZXJzRGF0YSQuY2VudGVyT2Zmc2V0ID0gb2Zmc2V0IC0gY2VudGVyLCBfc3RhdGUkbW9kaWZpZXJzRGF0YSQpO1xufVxuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZjIub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJGVsZW1lbnQgPSBvcHRpb25zLmVsZW1lbnQsXG4gICAgICBhcnJvd0VsZW1lbnQgPSBfb3B0aW9ucyRlbGVtZW50ID09PSB2b2lkIDAgPyAnW2RhdGEtcG9wcGVyLWFycm93XScgOiBfb3B0aW9ucyRlbGVtZW50O1xuXG4gIGlmIChhcnJvd0VsZW1lbnQgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfSAvLyBDU1Mgc2VsZWN0b3JcblxuXG4gIGlmICh0eXBlb2YgYXJyb3dFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgIGFycm93RWxlbWVudCA9IHN0YXRlLmVsZW1lbnRzLnBvcHBlci5xdWVyeVNlbGVjdG9yKGFycm93RWxlbWVudCk7XG5cbiAgICBpZiAoIWFycm93RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmICghY29udGFpbnMoc3RhdGUuZWxlbWVudHMucG9wcGVyLCBhcnJvd0VsZW1lbnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgc3RhdGUuZWxlbWVudHMuYXJyb3cgPSBhcnJvd0VsZW1lbnQ7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdhcnJvdycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBhcnJvdyxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIHJlcXVpcmVzOiBbJ3BvcHBlck9mZnNldHMnXSxcbiAgcmVxdWlyZXNJZkV4aXN0czogWydwcmV2ZW50T3ZlcmZsb3cnXVxufTsiLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCkge1xuICByZXR1cm4gcGxhY2VtZW50LnNwbGl0KCctJylbMV07XG59IiwgImltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgZW5kIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG52YXIgdW5zZXRTaWRlcyA9IHtcbiAgdG9wOiAnYXV0bycsXG4gIHJpZ2h0OiAnYXV0bycsXG4gIGJvdHRvbTogJ2F1dG8nLFxuICBsZWZ0OiAnYXV0bydcbn07IC8vIFJvdW5kIHRoZSBvZmZzZXRzIHRvIHRoZSBuZWFyZXN0IHN1aXRhYmxlIHN1YnBpeGVsIGJhc2VkIG9uIHRoZSBEUFIuXG4vLyBab29taW5nIGNhbiBjaGFuZ2UgdGhlIERQUiwgYnV0IGl0IHNlZW1zIHRvIHJlcG9ydCBhIHZhbHVlIHRoYXQgd2lsbFxuLy8gY2xlYW5seSBkaXZpZGUgdGhlIHZhbHVlcyBpbnRvIHRoZSBhcHByb3ByaWF0ZSBzdWJwaXhlbHMuXG5cbmZ1bmN0aW9uIHJvdW5kT2Zmc2V0c0J5RFBSKF9yZWYsIHdpbikge1xuICB2YXIgeCA9IF9yZWYueCxcbiAgICAgIHkgPSBfcmVmLnk7XG4gIHZhciBkcHIgPSB3aW4uZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuICByZXR1cm4ge1xuICAgIHg6IHJvdW5kKHggKiBkcHIpIC8gZHByIHx8IDAsXG4gICAgeTogcm91bmQoeSAqIGRwcikgLyBkcHIgfHwgMFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFwVG9TdHlsZXMoX3JlZjIpIHtcbiAgdmFyIF9PYmplY3QkYXNzaWduMjtcblxuICB2YXIgcG9wcGVyID0gX3JlZjIucG9wcGVyLFxuICAgICAgcG9wcGVyUmVjdCA9IF9yZWYyLnBvcHBlclJlY3QsXG4gICAgICBwbGFjZW1lbnQgPSBfcmVmMi5wbGFjZW1lbnQsXG4gICAgICB2YXJpYXRpb24gPSBfcmVmMi52YXJpYXRpb24sXG4gICAgICBvZmZzZXRzID0gX3JlZjIub2Zmc2V0cyxcbiAgICAgIHBvc2l0aW9uID0gX3JlZjIucG9zaXRpb24sXG4gICAgICBncHVBY2NlbGVyYXRpb24gPSBfcmVmMi5ncHVBY2NlbGVyYXRpb24sXG4gICAgICBhZGFwdGl2ZSA9IF9yZWYyLmFkYXB0aXZlLFxuICAgICAgcm91bmRPZmZzZXRzID0gX3JlZjIucm91bmRPZmZzZXRzLFxuICAgICAgaXNGaXhlZCA9IF9yZWYyLmlzRml4ZWQ7XG4gIHZhciBfb2Zmc2V0cyR4ID0gb2Zmc2V0cy54LFxuICAgICAgeCA9IF9vZmZzZXRzJHggPT09IHZvaWQgMCA/IDAgOiBfb2Zmc2V0cyR4LFxuICAgICAgX29mZnNldHMkeSA9IG9mZnNldHMueSxcbiAgICAgIHkgPSBfb2Zmc2V0cyR5ID09PSB2b2lkIDAgPyAwIDogX29mZnNldHMkeTtcblxuICB2YXIgX3JlZjMgPSB0eXBlb2Ygcm91bmRPZmZzZXRzID09PSAnZnVuY3Rpb24nID8gcm91bmRPZmZzZXRzKHtcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfSkgOiB7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG5cbiAgeCA9IF9yZWYzLng7XG4gIHkgPSBfcmVmMy55O1xuICB2YXIgaGFzWCA9IG9mZnNldHMuaGFzT3duUHJvcGVydHkoJ3gnKTtcbiAgdmFyIGhhc1kgPSBvZmZzZXRzLmhhc093blByb3BlcnR5KCd5Jyk7XG4gIHZhciBzaWRlWCA9IGxlZnQ7XG4gIHZhciBzaWRlWSA9IHRvcDtcbiAgdmFyIHdpbiA9IHdpbmRvdztcblxuICBpZiAoYWRhcHRpdmUpIHtcbiAgICB2YXIgb2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KHBvcHBlcik7XG4gICAgdmFyIGhlaWdodFByb3AgPSAnY2xpZW50SGVpZ2h0JztcbiAgICB2YXIgd2lkdGhQcm9wID0gJ2NsaWVudFdpZHRoJztcblxuICAgIGlmIChvZmZzZXRQYXJlbnQgPT09IGdldFdpbmRvdyhwb3BwZXIpKSB7XG4gICAgICBvZmZzZXRQYXJlbnQgPSBnZXREb2N1bWVudEVsZW1lbnQocG9wcGVyKTtcblxuICAgICAgaWYgKGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiAhPT0gJ3N0YXRpYycgJiYgcG9zaXRpb24gPT09ICdhYnNvbHV0ZScpIHtcbiAgICAgICAgaGVpZ2h0UHJvcCA9ICdzY3JvbGxIZWlnaHQnO1xuICAgICAgICB3aWR0aFByb3AgPSAnc2Nyb2xsV2lkdGgnO1xuICAgICAgfVxuICAgIH0gLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FzdF06IGZvcmNlIHR5cGUgcmVmaW5lbWVudCwgd2UgY29tcGFyZSBvZmZzZXRQYXJlbnQgd2l0aCB3aW5kb3cgYWJvdmUsIGJ1dCBGbG93IGRvZXNuJ3QgZGV0ZWN0IGl0XG5cblxuICAgIG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudDtcblxuICAgIGlmIChwbGFjZW1lbnQgPT09IHRvcCB8fCAocGxhY2VtZW50ID09PSBsZWZ0IHx8IHBsYWNlbWVudCA9PT0gcmlnaHQpICYmIHZhcmlhdGlvbiA9PT0gZW5kKSB7XG4gICAgICBzaWRlWSA9IGJvdHRvbTtcbiAgICAgIHZhciBvZmZzZXRZID0gaXNGaXhlZCAmJiBvZmZzZXRQYXJlbnQgPT09IHdpbiAmJiB3aW4udmlzdWFsVmlld3BvcnQgPyB3aW4udmlzdWFsVmlld3BvcnQuaGVpZ2h0IDogLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddXG4gICAgICBvZmZzZXRQYXJlbnRbaGVpZ2h0UHJvcF07XG4gICAgICB5IC09IG9mZnNldFkgLSBwb3BwZXJSZWN0LmhlaWdodDtcbiAgICAgIHkgKj0gZ3B1QWNjZWxlcmF0aW9uID8gMSA6IC0xO1xuICAgIH1cblxuICAgIGlmIChwbGFjZW1lbnQgPT09IGxlZnQgfHwgKHBsYWNlbWVudCA9PT0gdG9wIHx8IHBsYWNlbWVudCA9PT0gYm90dG9tKSAmJiB2YXJpYXRpb24gPT09IGVuZCkge1xuICAgICAgc2lkZVggPSByaWdodDtcbiAgICAgIHZhciBvZmZzZXRYID0gaXNGaXhlZCAmJiBvZmZzZXRQYXJlbnQgPT09IHdpbiAmJiB3aW4udmlzdWFsVmlld3BvcnQgPyB3aW4udmlzdWFsVmlld3BvcnQud2lkdGggOiAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgIG9mZnNldFBhcmVudFt3aWR0aFByb3BdO1xuICAgICAgeCAtPSBvZmZzZXRYIC0gcG9wcGVyUmVjdC53aWR0aDtcbiAgICAgIHggKj0gZ3B1QWNjZWxlcmF0aW9uID8gMSA6IC0xO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjb21tb25TdHlsZXMgPSBPYmplY3QuYXNzaWduKHtcbiAgICBwb3NpdGlvbjogcG9zaXRpb25cbiAgfSwgYWRhcHRpdmUgJiYgdW5zZXRTaWRlcyk7XG5cbiAgdmFyIF9yZWY0ID0gcm91bmRPZmZzZXRzID09PSB0cnVlID8gcm91bmRPZmZzZXRzQnlEUFIoe1xuICAgIHg6IHgsXG4gICAgeTogeVxuICB9LCBnZXRXaW5kb3cocG9wcGVyKSkgOiB7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG5cbiAgeCA9IF9yZWY0Lng7XG4gIHkgPSBfcmVmNC55O1xuXG4gIGlmIChncHVBY2NlbGVyYXRpb24pIHtcbiAgICB2YXIgX09iamVjdCRhc3NpZ247XG5cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCAoX09iamVjdCRhc3NpZ24gPSB7fSwgX09iamVjdCRhc3NpZ25bc2lkZVldID0gaGFzWSA/ICcwJyA6ICcnLCBfT2JqZWN0JGFzc2lnbltzaWRlWF0gPSBoYXNYID8gJzAnIDogJycsIF9PYmplY3QkYXNzaWduLnRyYW5zZm9ybSA9ICh3aW4uZGV2aWNlUGl4ZWxSYXRpbyB8fCAxKSA8PSAxID8gXCJ0cmFuc2xhdGUoXCIgKyB4ICsgXCJweCwgXCIgKyB5ICsgXCJweClcIiA6IFwidHJhbnNsYXRlM2QoXCIgKyB4ICsgXCJweCwgXCIgKyB5ICsgXCJweCwgMClcIiwgX09iamVjdCRhc3NpZ24pKTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBjb21tb25TdHlsZXMsIChfT2JqZWN0JGFzc2lnbjIgPSB7fSwgX09iamVjdCRhc3NpZ24yW3NpZGVZXSA9IGhhc1kgPyB5ICsgXCJweFwiIDogJycsIF9PYmplY3QkYXNzaWduMltzaWRlWF0gPSBoYXNYID8geCArIFwicHhcIiA6ICcnLCBfT2JqZWN0JGFzc2lnbjIudHJhbnNmb3JtID0gJycsIF9PYmplY3QkYXNzaWduMikpO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlU3R5bGVzKF9yZWY1KSB7XG4gIHZhciBzdGF0ZSA9IF9yZWY1LnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWY1Lm9wdGlvbnM7XG4gIHZhciBfb3B0aW9ucyRncHVBY2NlbGVyYXQgPSBvcHRpb25zLmdwdUFjY2VsZXJhdGlvbixcbiAgICAgIGdwdUFjY2VsZXJhdGlvbiA9IF9vcHRpb25zJGdwdUFjY2VsZXJhdCA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGdwdUFjY2VsZXJhdCxcbiAgICAgIF9vcHRpb25zJGFkYXB0aXZlID0gb3B0aW9ucy5hZGFwdGl2ZSxcbiAgICAgIGFkYXB0aXZlID0gX29wdGlvbnMkYWRhcHRpdmUgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRhZGFwdGl2ZSxcbiAgICAgIF9vcHRpb25zJHJvdW5kT2Zmc2V0cyA9IG9wdGlvbnMucm91bmRPZmZzZXRzLFxuICAgICAgcm91bmRPZmZzZXRzID0gX29wdGlvbnMkcm91bmRPZmZzZXRzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkcm91bmRPZmZzZXRzO1xuICB2YXIgY29tbW9uU3R5bGVzID0ge1xuICAgIHBsYWNlbWVudDogZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpLFxuICAgIHZhcmlhdGlvbjogZ2V0VmFyaWF0aW9uKHN0YXRlLnBsYWNlbWVudCksXG4gICAgcG9wcGVyOiBzdGF0ZS5lbGVtZW50cy5wb3BwZXIsXG4gICAgcG9wcGVyUmVjdDogc3RhdGUucmVjdHMucG9wcGVyLFxuICAgIGdwdUFjY2VsZXJhdGlvbjogZ3B1QWNjZWxlcmF0aW9uLFxuICAgIGlzRml4ZWQ6IHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3kgPT09ICdmaXhlZCdcbiAgfTtcblxuICBpZiAoc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzICE9IG51bGwpIHtcbiAgICBzdGF0ZS5zdHlsZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuc3R5bGVzLnBvcHBlciwgbWFwVG9TdHlsZXMoT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCB7XG4gICAgICBvZmZzZXRzOiBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMsXG4gICAgICBwb3NpdGlvbjogc3RhdGUub3B0aW9ucy5zdHJhdGVneSxcbiAgICAgIGFkYXB0aXZlOiBhZGFwdGl2ZSxcbiAgICAgIHJvdW5kT2Zmc2V0czogcm91bmRPZmZzZXRzXG4gICAgfSkpKTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5tb2RpZmllcnNEYXRhLmFycm93ICE9IG51bGwpIHtcbiAgICBzdGF0ZS5zdHlsZXMuYXJyb3cgPSBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5zdHlsZXMuYXJyb3csIG1hcFRvU3R5bGVzKE9iamVjdC5hc3NpZ24oe30sIGNvbW1vblN0eWxlcywge1xuICAgICAgb2Zmc2V0czogc3RhdGUubW9kaWZpZXJzRGF0YS5hcnJvdyxcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgYWRhcHRpdmU6IGZhbHNlLFxuICAgICAgcm91bmRPZmZzZXRzOiByb3VuZE9mZnNldHNcbiAgICB9KSkpO1xuICB9XG5cbiAgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIgPSBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5hdHRyaWJ1dGVzLnBvcHBlciwge1xuICAgICdkYXRhLXBvcHBlci1wbGFjZW1lbnQnOiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSk7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdjb21wdXRlU3R5bGVzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdiZWZvcmVXcml0ZScsXG4gIGZuOiBjb21wdXRlU3R5bGVzLFxuICBkYXRhOiB7fVxufTsiLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldFdpbmRvdy5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbnZhciBwYXNzaXZlID0ge1xuICBwYXNzaXZlOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgaW5zdGFuY2UgPSBfcmVmLmluc3RhbmNlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJHNjcm9sbCA9IG9wdGlvbnMuc2Nyb2xsLFxuICAgICAgc2Nyb2xsID0gX29wdGlvbnMkc2Nyb2xsID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkc2Nyb2xsLFxuICAgICAgX29wdGlvbnMkcmVzaXplID0gb3B0aW9ucy5yZXNpemUsXG4gICAgICByZXNpemUgPSBfb3B0aW9ucyRyZXNpemUgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRyZXNpemU7XG4gIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coc3RhdGUuZWxlbWVudHMucG9wcGVyKTtcbiAgdmFyIHNjcm9sbFBhcmVudHMgPSBbXS5jb25jYXQoc3RhdGUuc2Nyb2xsUGFyZW50cy5yZWZlcmVuY2UsIHN0YXRlLnNjcm9sbFBhcmVudHMucG9wcGVyKTtcblxuICBpZiAoc2Nyb2xsKSB7XG4gICAgc2Nyb2xsUGFyZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChzY3JvbGxQYXJlbnQpIHtcbiAgICAgIHNjcm9sbFBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHJlc2l6ZSkge1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc2Nyb2xsKSB7XG4gICAgICBzY3JvbGxQYXJlbnRzLmZvckVhY2goZnVuY3Rpb24gKHNjcm9sbFBhcmVudCkge1xuICAgICAgICBzY3JvbGxQYXJlbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgaW5zdGFuY2UudXBkYXRlLCBwYXNzaXZlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChyZXNpemUpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH1cbiAgfTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2V2ZW50TGlzdGVuZXJzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICd3cml0ZScsXG4gIGZuOiBmdW5jdGlvbiBmbigpIHt9LFxuICBlZmZlY3Q6IGVmZmVjdCxcbiAgZGF0YToge31cbn07IiwgInZhciBoYXNoID0ge1xuICBsZWZ0OiAncmlnaHQnLFxuICByaWdodDogJ2xlZnQnLFxuICBib3R0b206ICd0b3AnLFxuICB0b3A6ICdib3R0b20nXG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T3Bwb3NpdGVQbGFjZW1lbnQocGxhY2VtZW50KSB7XG4gIHJldHVybiBwbGFjZW1lbnQucmVwbGFjZSgvbGVmdHxyaWdodHxib3R0b218dG9wL2csIGZ1bmN0aW9uIChtYXRjaGVkKSB7XG4gICAgcmV0dXJuIGhhc2hbbWF0Y2hlZF07XG4gIH0pO1xufSIsICJ2YXIgaGFzaCA9IHtcbiAgc3RhcnQ6ICdlbmQnLFxuICBlbmQ6ICdzdGFydCdcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5yZXBsYWNlKC9zdGFydHxlbmQvZywgZnVuY3Rpb24gKG1hdGNoZWQpIHtcbiAgICByZXR1cm4gaGFzaFttYXRjaGVkXTtcbiAgfSk7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRXaW5kb3dTY3JvbGwobm9kZSkge1xuICB2YXIgd2luID0gZ2V0V2luZG93KG5vZGUpO1xuICB2YXIgc2Nyb2xsTGVmdCA9IHdpbi5wYWdlWE9mZnNldDtcbiAgdmFyIHNjcm9sbFRvcCA9IHdpbi5wYWdlWU9mZnNldDtcbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBzY3JvbGxMZWZ0LFxuICAgIHNjcm9sbFRvcDogc2Nyb2xsVG9wXG4gIH07XG59IiwgImltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4vZ2V0Qm91bmRpbmdDbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldFdpbmRvd1Njcm9sbEJhclgoZWxlbWVudCkge1xuICAvLyBJZiA8aHRtbD4gaGFzIGEgQ1NTIHdpZHRoIGdyZWF0ZXIgdGhhbiB0aGUgdmlld3BvcnQsIHRoZW4gdGhpcyB3aWxsIGJlXG4gIC8vIGluY29ycmVjdCBmb3IgUlRMLlxuICAvLyBQb3BwZXIgMSBpcyBicm9rZW4gaW4gdGhpcyBjYXNlIGFuZCBuZXZlciBoYWQgYSBidWcgcmVwb3J0IHNvIGxldCdzIGFzc3VtZVxuICAvLyBpdCdzIG5vdCBhbiBpc3N1ZS4gSSBkb24ndCB0aGluayBhbnlvbmUgZXZlciBzcGVjaWZpZXMgd2lkdGggb24gPGh0bWw+XG4gIC8vIGFueXdheS5cbiAgLy8gQnJvd3NlcnMgd2hlcmUgdGhlIGxlZnQgc2Nyb2xsYmFyIGRvZXNuJ3QgY2F1c2UgYW4gaXNzdWUgcmVwb3J0IGAwYCBmb3JcbiAgLy8gdGhpcyAoZS5nLiBFZGdlIDIwMTksIElFMTEsIFNhZmFyaSlcbiAgcmV0dXJuIGdldEJvdW5kaW5nQ2xpZW50UmVjdChnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkpLmxlZnQgKyBnZXRXaW5kb3dTY3JvbGwoZWxlbWVudCkuc2Nyb2xsTGVmdDtcbn0iLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93U2Nyb2xsQmFyWCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGxCYXJYLmpzXCI7XG5pbXBvcnQgaXNMYXlvdXRWaWV3cG9ydCBmcm9tIFwiLi9pc0xheW91dFZpZXdwb3J0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRWaWV3cG9ydFJlY3QoZWxlbWVudCwgc3RyYXRlZ3kpIHtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhlbGVtZW50KTtcbiAgdmFyIGh0bWwgPSBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCk7XG4gIHZhciB2aXN1YWxWaWV3cG9ydCA9IHdpbi52aXN1YWxWaWV3cG9ydDtcbiAgdmFyIHdpZHRoID0gaHRtbC5jbGllbnRXaWR0aDtcbiAgdmFyIGhlaWdodCA9IGh0bWwuY2xpZW50SGVpZ2h0O1xuICB2YXIgeCA9IDA7XG4gIHZhciB5ID0gMDtcblxuICBpZiAodmlzdWFsVmlld3BvcnQpIHtcbiAgICB3aWR0aCA9IHZpc3VhbFZpZXdwb3J0LndpZHRoO1xuICAgIGhlaWdodCA9IHZpc3VhbFZpZXdwb3J0LmhlaWdodDtcbiAgICB2YXIgbGF5b3V0Vmlld3BvcnQgPSBpc0xheW91dFZpZXdwb3J0KCk7XG5cbiAgICBpZiAobGF5b3V0Vmlld3BvcnQgfHwgIWxheW91dFZpZXdwb3J0ICYmIHN0cmF0ZWd5ID09PSAnZml4ZWQnKSB7XG4gICAgICB4ID0gdmlzdWFsVmlld3BvcnQub2Zmc2V0TGVmdDtcbiAgICAgIHkgPSB2aXN1YWxWaWV3cG9ydC5vZmZzZXRUb3A7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogd2lkdGgsXG4gICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgeDogeCArIGdldFdpbmRvd1Njcm9sbEJhclgoZWxlbWVudCksXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldENvbXB1dGVkU3R5bGUgZnJvbSBcIi4vZ2V0Q29tcHV0ZWRTdHlsZS5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbEJhclggZnJvbSBcIi4vZ2V0V2luZG93U2Nyb2xsQmFyWC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGwuanNcIjtcbmltcG9ydCB7IG1heCB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7IC8vIEdldHMgdGhlIGVudGlyZSBzaXplIG9mIHRoZSBzY3JvbGxhYmxlIGRvY3VtZW50IGFyZWEsIGV2ZW4gZXh0ZW5kaW5nIG91dHNpZGVcbi8vIG9mIHRoZSBgPGh0bWw+YCBhbmQgYDxib2R5PmAgcmVjdCBib3VuZHMgaWYgaG9yaXpvbnRhbGx5IHNjcm9sbGFibGVcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RG9jdW1lbnRSZWN0KGVsZW1lbnQpIHtcbiAgdmFyIF9lbGVtZW50JG93bmVyRG9jdW1lbjtcblxuICB2YXIgaHRtbCA9IGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KTtcbiAgdmFyIHdpblNjcm9sbCA9IGdldFdpbmRvd1Njcm9sbChlbGVtZW50KTtcbiAgdmFyIGJvZHkgPSAoX2VsZW1lbnQkb3duZXJEb2N1bWVuID0gZWxlbWVudC5vd25lckRvY3VtZW50KSA9PSBudWxsID8gdm9pZCAwIDogX2VsZW1lbnQkb3duZXJEb2N1bWVuLmJvZHk7XG4gIHZhciB3aWR0aCA9IG1heChodG1sLnNjcm9sbFdpZHRoLCBodG1sLmNsaWVudFdpZHRoLCBib2R5ID8gYm9keS5zY3JvbGxXaWR0aCA6IDAsIGJvZHkgPyBib2R5LmNsaWVudFdpZHRoIDogMCk7XG4gIHZhciBoZWlnaHQgPSBtYXgoaHRtbC5zY3JvbGxIZWlnaHQsIGh0bWwuY2xpZW50SGVpZ2h0LCBib2R5ID8gYm9keS5zY3JvbGxIZWlnaHQgOiAwLCBib2R5ID8gYm9keS5jbGllbnRIZWlnaHQgOiAwKTtcbiAgdmFyIHggPSAtd2luU2Nyb2xsLnNjcm9sbExlZnQgKyBnZXRXaW5kb3dTY3JvbGxCYXJYKGVsZW1lbnQpO1xuICB2YXIgeSA9IC13aW5TY3JvbGwuc2Nyb2xsVG9wO1xuXG4gIGlmIChnZXRDb21wdXRlZFN0eWxlKGJvZHkgfHwgaHRtbCkuZGlyZWN0aW9uID09PSAncnRsJykge1xuICAgIHggKz0gbWF4KGh0bWwuY2xpZW50V2lkdGgsIGJvZHkgPyBib2R5LmNsaWVudFdpZHRoIDogMCkgLSB3aWR0aDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0LFxuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc1Njcm9sbFBhcmVudChlbGVtZW50KSB7XG4gIC8vIEZpcmVmb3ggd2FudHMgdXMgdG8gY2hlY2sgYC14YCBhbmQgYC15YCB2YXJpYXRpb25zIGFzIHdlbGxcbiAgdmFyIF9nZXRDb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KSxcbiAgICAgIG92ZXJmbG93ID0gX2dldENvbXB1dGVkU3R5bGUub3ZlcmZsb3csXG4gICAgICBvdmVyZmxvd1ggPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1gsXG4gICAgICBvdmVyZmxvd1kgPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1k7XG5cbiAgcmV0dXJuIC9hdXRvfHNjcm9sbHxvdmVybGF5fGhpZGRlbi8udGVzdChvdmVyZmxvdyArIG92ZXJmbG93WSArIG92ZXJmbG93WCk7XG59IiwgImltcG9ydCBnZXRQYXJlbnROb2RlIGZyb20gXCIuL2dldFBhcmVudE5vZGUuanNcIjtcbmltcG9ydCBpc1Njcm9sbFBhcmVudCBmcm9tIFwiLi9pc1Njcm9sbFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0U2Nyb2xsUGFyZW50KG5vZGUpIHtcbiAgaWYgKFsnaHRtbCcsICdib2R5JywgJyNkb2N1bWVudCddLmluZGV4T2YoZ2V0Tm9kZU5hbWUobm9kZSkpID49IDApIHtcbiAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dOiBhc3N1bWUgYm9keSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gICAgcmV0dXJuIG5vZGUub3duZXJEb2N1bWVudC5ib2R5O1xuICB9XG5cbiAgaWYgKGlzSFRNTEVsZW1lbnQobm9kZSkgJiYgaXNTY3JvbGxQYXJlbnQobm9kZSkpIHtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHJldHVybiBnZXRTY3JvbGxQYXJlbnQoZ2V0UGFyZW50Tm9kZShub2RlKSk7XG59IiwgImltcG9ydCBnZXRTY3JvbGxQYXJlbnQgZnJvbSBcIi4vZ2V0U2Nyb2xsUGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0UGFyZW50Tm9kZSBmcm9tIFwiLi9nZXRQYXJlbnROb2RlLmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuL2dldFdpbmRvdy5qc1wiO1xuaW1wb3J0IGlzU2Nyb2xsUGFyZW50IGZyb20gXCIuL2lzU2Nyb2xsUGFyZW50LmpzXCI7XG4vKlxuZ2l2ZW4gYSBET00gZWxlbWVudCwgcmV0dXJuIHRoZSBsaXN0IG9mIGFsbCBzY3JvbGwgcGFyZW50cywgdXAgdGhlIGxpc3Qgb2YgYW5jZXNvcnNcbnVudGlsIHdlIGdldCB0byB0aGUgdG9wIHdpbmRvdyBvYmplY3QuIFRoaXMgbGlzdCBpcyB3aGF0IHdlIGF0dGFjaCBzY3JvbGwgbGlzdGVuZXJzXG50bywgYmVjYXVzZSBpZiBhbnkgb2YgdGhlc2UgcGFyZW50IGVsZW1lbnRzIHNjcm9sbCwgd2UnbGwgbmVlZCB0byByZS1jYWxjdWxhdGUgdGhlXG5yZWZlcmVuY2UgZWxlbWVudCdzIHBvc2l0aW9uLlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGlzdFNjcm9sbFBhcmVudHMoZWxlbWVudCwgbGlzdCkge1xuICB2YXIgX2VsZW1lbnQkb3duZXJEb2N1bWVuO1xuXG4gIGlmIChsaXN0ID09PSB2b2lkIDApIHtcbiAgICBsaXN0ID0gW107XG4gIH1cblxuICB2YXIgc2Nyb2xsUGFyZW50ID0gZ2V0U2Nyb2xsUGFyZW50KGVsZW1lbnQpO1xuICB2YXIgaXNCb2R5ID0gc2Nyb2xsUGFyZW50ID09PSAoKF9lbGVtZW50JG93bmVyRG9jdW1lbiA9IGVsZW1lbnQub3duZXJEb2N1bWVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9lbGVtZW50JG93bmVyRG9jdW1lbi5ib2R5KTtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhzY3JvbGxQYXJlbnQpO1xuICB2YXIgdGFyZ2V0ID0gaXNCb2R5ID8gW3dpbl0uY29uY2F0KHdpbi52aXN1YWxWaWV3cG9ydCB8fCBbXSwgaXNTY3JvbGxQYXJlbnQoc2Nyb2xsUGFyZW50KSA/IHNjcm9sbFBhcmVudCA6IFtdKSA6IHNjcm9sbFBhcmVudDtcbiAgdmFyIHVwZGF0ZWRMaXN0ID0gbGlzdC5jb25jYXQodGFyZ2V0KTtcbiAgcmV0dXJuIGlzQm9keSA/IHVwZGF0ZWRMaXN0IDogLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF06IGlzQm9keSB0ZWxscyB1cyB0YXJnZXQgd2lsbCBiZSBhbiBIVE1MRWxlbWVudCBoZXJlXG4gIHVwZGF0ZWRMaXN0LmNvbmNhdChsaXN0U2Nyb2xsUGFyZW50cyhnZXRQYXJlbnROb2RlKHRhcmdldCkpKTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVjdFRvQ2xpZW50UmVjdChyZWN0KSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCByZWN0LCB7XG4gICAgbGVmdDogcmVjdC54LFxuICAgIHRvcDogcmVjdC55LFxuICAgIHJpZ2h0OiByZWN0LnggKyByZWN0LndpZHRoLFxuICAgIGJvdHRvbTogcmVjdC55ICsgcmVjdC5oZWlnaHRcbiAgfSk7XG59IiwgImltcG9ydCB7IHZpZXdwb3J0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0Vmlld3BvcnRSZWN0IGZyb20gXCIuL2dldFZpZXdwb3J0UmVjdC5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50UmVjdCBmcm9tIFwiLi9nZXREb2N1bWVudFJlY3QuanNcIjtcbmltcG9ydCBsaXN0U2Nyb2xsUGFyZW50cyBmcm9tIFwiLi9saXN0U2Nyb2xsUGFyZW50cy5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5pbXBvcnQgeyBpc0VsZW1lbnQsIGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGNvbnRhaW5zIGZyb20gXCIuL2NvbnRhaW5zLmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCByZWN0VG9DbGllbnRSZWN0IGZyb20gXCIuLi91dGlscy9yZWN0VG9DbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgeyBtYXgsIG1pbiB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7XG5cbmZ1bmN0aW9uIGdldElubmVyQm91bmRpbmdDbGllbnRSZWN0KGVsZW1lbnQsIHN0cmF0ZWd5KSB7XG4gIHZhciByZWN0ID0gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KGVsZW1lbnQsIGZhbHNlLCBzdHJhdGVneSA9PT0gJ2ZpeGVkJyk7XG4gIHJlY3QudG9wID0gcmVjdC50b3AgKyBlbGVtZW50LmNsaWVudFRvcDtcbiAgcmVjdC5sZWZ0ID0gcmVjdC5sZWZ0ICsgZWxlbWVudC5jbGllbnRMZWZ0O1xuICByZWN0LmJvdHRvbSA9IHJlY3QudG9wICsgZWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gIHJlY3QucmlnaHQgPSByZWN0LmxlZnQgKyBlbGVtZW50LmNsaWVudFdpZHRoO1xuICByZWN0LndpZHRoID0gZWxlbWVudC5jbGllbnRXaWR0aDtcbiAgcmVjdC5oZWlnaHQgPSBlbGVtZW50LmNsaWVudEhlaWdodDtcbiAgcmVjdC54ID0gcmVjdC5sZWZ0O1xuICByZWN0LnkgPSByZWN0LnRvcDtcbiAgcmV0dXJuIHJlY3Q7XG59XG5cbmZ1bmN0aW9uIGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGNsaXBwaW5nUGFyZW50LCBzdHJhdGVneSkge1xuICByZXR1cm4gY2xpcHBpbmdQYXJlbnQgPT09IHZpZXdwb3J0ID8gcmVjdFRvQ2xpZW50UmVjdChnZXRWaWV3cG9ydFJlY3QoZWxlbWVudCwgc3RyYXRlZ3kpKSA6IGlzRWxlbWVudChjbGlwcGluZ1BhcmVudCkgPyBnZXRJbm5lckJvdW5kaW5nQ2xpZW50UmVjdChjbGlwcGluZ1BhcmVudCwgc3RyYXRlZ3kpIDogcmVjdFRvQ2xpZW50UmVjdChnZXREb2N1bWVudFJlY3QoZ2V0RG9jdW1lbnRFbGVtZW50KGVsZW1lbnQpKSk7XG59IC8vIEEgXCJjbGlwcGluZyBwYXJlbnRcIiBpcyBhbiBvdmVyZmxvd2FibGUgY29udGFpbmVyIHdpdGggdGhlIGNoYXJhY3RlcmlzdGljIG9mXG4vLyBjbGlwcGluZyAob3IgaGlkaW5nKSBvdmVyZmxvd2luZyBlbGVtZW50cyB3aXRoIGEgcG9zaXRpb24gZGlmZmVyZW50IGZyb21cbi8vIGBpbml0aWFsYFxuXG5cbmZ1bmN0aW9uIGdldENsaXBwaW5nUGFyZW50cyhlbGVtZW50KSB7XG4gIHZhciBjbGlwcGluZ1BhcmVudHMgPSBsaXN0U2Nyb2xsUGFyZW50cyhnZXRQYXJlbnROb2RlKGVsZW1lbnQpKTtcbiAgdmFyIGNhbkVzY2FwZUNsaXBwaW5nID0gWydhYnNvbHV0ZScsICdmaXhlZCddLmluZGV4T2YoZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5wb3NpdGlvbikgPj0gMDtcbiAgdmFyIGNsaXBwZXJFbGVtZW50ID0gY2FuRXNjYXBlQ2xpcHBpbmcgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSA/IGdldE9mZnNldFBhcmVudChlbGVtZW50KSA6IGVsZW1lbnQ7XG5cbiAgaWYgKCFpc0VsZW1lbnQoY2xpcHBlckVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9IC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXJldHVybl06IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9mbG93L2lzc3Vlcy8xNDE0XG5cblxuICByZXR1cm4gY2xpcHBpbmdQYXJlbnRzLmZpbHRlcihmdW5jdGlvbiAoY2xpcHBpbmdQYXJlbnQpIHtcbiAgICByZXR1cm4gaXNFbGVtZW50KGNsaXBwaW5nUGFyZW50KSAmJiBjb250YWlucyhjbGlwcGluZ1BhcmVudCwgY2xpcHBlckVsZW1lbnQpICYmIGdldE5vZGVOYW1lKGNsaXBwaW5nUGFyZW50KSAhPT0gJ2JvZHknO1xuICB9KTtcbn0gLy8gR2V0cyB0aGUgbWF4aW11bSBhcmVhIHRoYXQgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBpbiBkdWUgdG8gYW55IG51bWJlciBvZlxuLy8gY2xpcHBpbmcgcGFyZW50c1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENsaXBwaW5nUmVjdChlbGVtZW50LCBib3VuZGFyeSwgcm9vdEJvdW5kYXJ5LCBzdHJhdGVneSkge1xuICB2YXIgbWFpbkNsaXBwaW5nUGFyZW50cyA9IGJvdW5kYXJ5ID09PSAnY2xpcHBpbmdQYXJlbnRzJyA/IGdldENsaXBwaW5nUGFyZW50cyhlbGVtZW50KSA6IFtdLmNvbmNhdChib3VuZGFyeSk7XG4gIHZhciBjbGlwcGluZ1BhcmVudHMgPSBbXS5jb25jYXQobWFpbkNsaXBwaW5nUGFyZW50cywgW3Jvb3RCb3VuZGFyeV0pO1xuICB2YXIgZmlyc3RDbGlwcGluZ1BhcmVudCA9IGNsaXBwaW5nUGFyZW50c1swXTtcbiAgdmFyIGNsaXBwaW5nUmVjdCA9IGNsaXBwaW5nUGFyZW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFjY1JlY3QsIGNsaXBwaW5nUGFyZW50KSB7XG4gICAgdmFyIHJlY3QgPSBnZXRDbGllbnRSZWN0RnJvbU1peGVkVHlwZShlbGVtZW50LCBjbGlwcGluZ1BhcmVudCwgc3RyYXRlZ3kpO1xuICAgIGFjY1JlY3QudG9wID0gbWF4KHJlY3QudG9wLCBhY2NSZWN0LnRvcCk7XG4gICAgYWNjUmVjdC5yaWdodCA9IG1pbihyZWN0LnJpZ2h0LCBhY2NSZWN0LnJpZ2h0KTtcbiAgICBhY2NSZWN0LmJvdHRvbSA9IG1pbihyZWN0LmJvdHRvbSwgYWNjUmVjdC5ib3R0b20pO1xuICAgIGFjY1JlY3QubGVmdCA9IG1heChyZWN0LmxlZnQsIGFjY1JlY3QubGVmdCk7XG4gICAgcmV0dXJuIGFjY1JlY3Q7XG4gIH0sIGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGZpcnN0Q2xpcHBpbmdQYXJlbnQsIHN0cmF0ZWd5KSk7XG4gIGNsaXBwaW5nUmVjdC53aWR0aCA9IGNsaXBwaW5nUmVjdC5yaWdodCAtIGNsaXBwaW5nUmVjdC5sZWZ0O1xuICBjbGlwcGluZ1JlY3QuaGVpZ2h0ID0gY2xpcHBpbmdSZWN0LmJvdHRvbSAtIGNsaXBwaW5nUmVjdC50b3A7XG4gIGNsaXBwaW5nUmVjdC54ID0gY2xpcHBpbmdSZWN0LmxlZnQ7XG4gIGNsaXBwaW5nUmVjdC55ID0gY2xpcHBpbmdSZWN0LnRvcDtcbiAgcmV0dXJuIGNsaXBwaW5nUmVjdDtcbn0iLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4vZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQgZnJvbSBcIi4vZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgeyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQsIHN0YXJ0LCBlbmQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbXB1dGVPZmZzZXRzKF9yZWYpIHtcbiAgdmFyIHJlZmVyZW5jZSA9IF9yZWYucmVmZXJlbmNlLFxuICAgICAgZWxlbWVudCA9IF9yZWYuZWxlbWVudCxcbiAgICAgIHBsYWNlbWVudCA9IF9yZWYucGxhY2VtZW50O1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IHBsYWNlbWVudCA/IGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA6IG51bGw7XG4gIHZhciB2YXJpYXRpb24gPSBwbGFjZW1lbnQgPyBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA6IG51bGw7XG4gIHZhciBjb21tb25YID0gcmVmZXJlbmNlLnggKyByZWZlcmVuY2Uud2lkdGggLyAyIC0gZWxlbWVudC53aWR0aCAvIDI7XG4gIHZhciBjb21tb25ZID0gcmVmZXJlbmNlLnkgKyByZWZlcmVuY2UuaGVpZ2h0IC8gMiAtIGVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgdmFyIG9mZnNldHM7XG5cbiAgc3dpdGNoIChiYXNlUGxhY2VtZW50KSB7XG4gICAgY2FzZSB0b3A6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiBjb21tb25YLFxuICAgICAgICB5OiByZWZlcmVuY2UueSAtIGVsZW1lbnQuaGVpZ2h0XG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIGJvdHRvbTpcbiAgICAgIG9mZnNldHMgPSB7XG4gICAgICAgIHg6IGNvbW1vblgsXG4gICAgICAgIHk6IHJlZmVyZW5jZS55ICsgcmVmZXJlbmNlLmhlaWdodFxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSByaWdodDpcbiAgICAgIG9mZnNldHMgPSB7XG4gICAgICAgIHg6IHJlZmVyZW5jZS54ICsgcmVmZXJlbmNlLndpZHRoLFxuICAgICAgICB5OiBjb21tb25ZXG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIGxlZnQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCAtIGVsZW1lbnQud2lkdGgsXG4gICAgICAgIHk6IGNvbW1vbllcbiAgICAgIH07XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCxcbiAgICAgICAgeTogcmVmZXJlbmNlLnlcbiAgICAgIH07XG4gIH1cblxuICB2YXIgbWFpbkF4aXMgPSBiYXNlUGxhY2VtZW50ID8gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KGJhc2VQbGFjZW1lbnQpIDogbnVsbDtcblxuICBpZiAobWFpbkF4aXMgIT0gbnVsbCkge1xuICAgIHZhciBsZW4gPSBtYWluQXhpcyA9PT0gJ3knID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuXG4gICAgc3dpdGNoICh2YXJpYXRpb24pIHtcbiAgICAgIGNhc2Ugc3RhcnQ6XG4gICAgICAgIG9mZnNldHNbbWFpbkF4aXNdID0gb2Zmc2V0c1ttYWluQXhpc10gLSAocmVmZXJlbmNlW2xlbl0gLyAyIC0gZWxlbWVudFtsZW5dIC8gMik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIGVuZDpcbiAgICAgICAgb2Zmc2V0c1ttYWluQXhpc10gPSBvZmZzZXRzW21haW5BeGlzXSArIChyZWZlcmVuY2VbbGVuXSAvIDIgLSBlbGVtZW50W2xlbl0gLyAyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9mZnNldHM7XG59IiwgImltcG9ydCBnZXRDbGlwcGluZ1JlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBjb21wdXRlT2Zmc2V0cyBmcm9tIFwiLi9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuaW1wb3J0IHJlY3RUb0NsaWVudFJlY3QgZnJvbSBcIi4vcmVjdFRvQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IHsgY2xpcHBpbmdQYXJlbnRzLCByZWZlcmVuY2UsIHBvcHBlciwgYm90dG9tLCB0b3AsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdmlld3BvcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCB7IGlzRWxlbWVudCB9IGZyb20gXCIuLi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi9tZXJnZVBhZGRpbmdPYmplY3QuanNcIjtcbmltcG9ydCBleHBhbmRUb0hhc2hNYXAgZnJvbSBcIi4vZXhwYW5kVG9IYXNoTWFwLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBfb3B0aW9ucyRwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucyRwbGFjZW1lbnQgPT09IHZvaWQgMCA/IHN0YXRlLnBsYWNlbWVudCA6IF9vcHRpb25zJHBsYWNlbWVudCxcbiAgICAgIF9vcHRpb25zJHN0cmF0ZWd5ID0gX29wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBzdHJhdGVneSA9IF9vcHRpb25zJHN0cmF0ZWd5ID09PSB2b2lkIDAgPyBzdGF0ZS5zdHJhdGVneSA6IF9vcHRpb25zJHN0cmF0ZWd5LFxuICAgICAgX29wdGlvbnMkYm91bmRhcnkgPSBfb3B0aW9ucy5ib3VuZGFyeSxcbiAgICAgIGJvdW5kYXJ5ID0gX29wdGlvbnMkYm91bmRhcnkgPT09IHZvaWQgMCA/IGNsaXBwaW5nUGFyZW50cyA6IF9vcHRpb25zJGJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyB2aWV3cG9ydCA6IF9vcHRpb25zJHJvb3RCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJGVsZW1lbnRDb250ZSA9IF9vcHRpb25zLmVsZW1lbnRDb250ZXh0LFxuICAgICAgZWxlbWVudENvbnRleHQgPSBfb3B0aW9ucyRlbGVtZW50Q29udGUgPT09IHZvaWQgMCA/IHBvcHBlciA6IF9vcHRpb25zJGVsZW1lbnRDb250ZSxcbiAgICAgIF9vcHRpb25zJGFsdEJvdW5kYXJ5ID0gX29wdGlvbnMuYWx0Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeSA9IF9vcHRpb25zJGFsdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyBmYWxzZSA6IF9vcHRpb25zJGFsdEJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcGFkZGluZyA9IF9vcHRpb25zLnBhZGRpbmcsXG4gICAgICBwYWRkaW5nID0gX29wdGlvbnMkcGFkZGluZyA9PT0gdm9pZCAwID8gMCA6IF9vcHRpb25zJHBhZGRpbmc7XG4gIHZhciBwYWRkaW5nT2JqZWN0ID0gbWVyZ2VQYWRkaW5nT2JqZWN0KHR5cGVvZiBwYWRkaW5nICE9PSAnbnVtYmVyJyA/IHBhZGRpbmcgOiBleHBhbmRUb0hhc2hNYXAocGFkZGluZywgYmFzZVBsYWNlbWVudHMpKTtcbiAgdmFyIGFsdENvbnRleHQgPSBlbGVtZW50Q29udGV4dCA9PT0gcG9wcGVyID8gcmVmZXJlbmNlIDogcG9wcGVyO1xuICB2YXIgcG9wcGVyUmVjdCA9IHN0YXRlLnJlY3RzLnBvcHBlcjtcbiAgdmFyIGVsZW1lbnQgPSBzdGF0ZS5lbGVtZW50c1thbHRCb3VuZGFyeSA/IGFsdENvbnRleHQgOiBlbGVtZW50Q29udGV4dF07XG4gIHZhciBjbGlwcGluZ0NsaWVudFJlY3QgPSBnZXRDbGlwcGluZ1JlY3QoaXNFbGVtZW50KGVsZW1lbnQpID8gZWxlbWVudCA6IGVsZW1lbnQuY29udGV4dEVsZW1lbnQgfHwgZ2V0RG9jdW1lbnRFbGVtZW50KHN0YXRlLmVsZW1lbnRzLnBvcHBlciksIGJvdW5kYXJ5LCByb290Qm91bmRhcnksIHN0cmF0ZWd5KTtcbiAgdmFyIHJlZmVyZW5jZUNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3Qoc3RhdGUuZWxlbWVudHMucmVmZXJlbmNlKTtcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBjb21wdXRlT2Zmc2V0cyh7XG4gICAgcmVmZXJlbmNlOiByZWZlcmVuY2VDbGllbnRSZWN0LFxuICAgIGVsZW1lbnQ6IHBvcHBlclJlY3QsXG4gICAgc3RyYXRlZ3k6ICdhYnNvbHV0ZScsXG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSk7XG4gIHZhciBwb3BwZXJDbGllbnRSZWN0ID0gcmVjdFRvQ2xpZW50UmVjdChPYmplY3QuYXNzaWduKHt9LCBwb3BwZXJSZWN0LCBwb3BwZXJPZmZzZXRzKSk7XG4gIHZhciBlbGVtZW50Q2xpZW50UmVjdCA9IGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgPyBwb3BwZXJDbGllbnRSZWN0IDogcmVmZXJlbmNlQ2xpZW50UmVjdDsgLy8gcG9zaXRpdmUgPSBvdmVyZmxvd2luZyB0aGUgY2xpcHBpbmcgcmVjdFxuICAvLyAwIG9yIG5lZ2F0aXZlID0gd2l0aGluIHRoZSBjbGlwcGluZyByZWN0XG5cbiAgdmFyIG92ZXJmbG93T2Zmc2V0cyA9IHtcbiAgICB0b3A6IGNsaXBwaW5nQ2xpZW50UmVjdC50b3AgLSBlbGVtZW50Q2xpZW50UmVjdC50b3AgKyBwYWRkaW5nT2JqZWN0LnRvcCxcbiAgICBib3R0b206IGVsZW1lbnRDbGllbnRSZWN0LmJvdHRvbSAtIGNsaXBwaW5nQ2xpZW50UmVjdC5ib3R0b20gKyBwYWRkaW5nT2JqZWN0LmJvdHRvbSxcbiAgICBsZWZ0OiBjbGlwcGluZ0NsaWVudFJlY3QubGVmdCAtIGVsZW1lbnRDbGllbnRSZWN0LmxlZnQgKyBwYWRkaW5nT2JqZWN0LmxlZnQsXG4gICAgcmlnaHQ6IGVsZW1lbnRDbGllbnRSZWN0LnJpZ2h0IC0gY2xpcHBpbmdDbGllbnRSZWN0LnJpZ2h0ICsgcGFkZGluZ09iamVjdC5yaWdodFxuICB9O1xuICB2YXIgb2Zmc2V0RGF0YSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0OyAvLyBPZmZzZXRzIGNhbiBiZSBhcHBsaWVkIG9ubHkgdG8gdGhlIHBvcHBlciBlbGVtZW50XG5cbiAgaWYgKGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgJiYgb2Zmc2V0RGF0YSkge1xuICAgIHZhciBvZmZzZXQgPSBvZmZzZXREYXRhW3BsYWNlbWVudF07XG4gICAgT2JqZWN0LmtleXMob3ZlcmZsb3dPZmZzZXRzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHZhciBtdWx0aXBseSA9IFtyaWdodCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/IDEgOiAtMTtcbiAgICAgIHZhciBheGlzID0gW3RvcCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/ICd5JyA6ICd4JztcbiAgICAgIG92ZXJmbG93T2Zmc2V0c1trZXldICs9IG9mZnNldFtheGlzXSAqIG11bHRpcGx5O1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG92ZXJmbG93T2Zmc2V0cztcbn0iLCAiaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCB7IHZhcmlhdGlvblBsYWNlbWVudHMsIGJhc2VQbGFjZW1lbnRzLCBwbGFjZW1lbnRzIGFzIGFsbFBsYWNlbWVudHMgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCBkZXRlY3RPdmVyZmxvdyBmcm9tIFwiLi9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4vZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29tcHV0ZUF1dG9QbGFjZW1lbnQoc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBib3VuZGFyeSA9IF9vcHRpb25zLmJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZyA9IF9vcHRpb25zLnBhZGRpbmcsXG4gICAgICBmbGlwVmFyaWF0aW9ucyA9IF9vcHRpb25zLmZsaXBWYXJpYXRpb25zLFxuICAgICAgX29wdGlvbnMkYWxsb3dlZEF1dG9QID0gX29wdGlvbnMuYWxsb3dlZEF1dG9QbGFjZW1lbnRzLFxuICAgICAgYWxsb3dlZEF1dG9QbGFjZW1lbnRzID0gX29wdGlvbnMkYWxsb3dlZEF1dG9QID09PSB2b2lkIDAgPyBhbGxQbGFjZW1lbnRzIDogX29wdGlvbnMkYWxsb3dlZEF1dG9QO1xuICB2YXIgdmFyaWF0aW9uID0gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCk7XG4gIHZhciBwbGFjZW1lbnRzID0gdmFyaWF0aW9uID8gZmxpcFZhcmlhdGlvbnMgPyB2YXJpYXRpb25QbGFjZW1lbnRzIDogdmFyaWF0aW9uUGxhY2VtZW50cy5maWx0ZXIoZnVuY3Rpb24gKHBsYWNlbWVudCkge1xuICAgIHJldHVybiBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA9PT0gdmFyaWF0aW9uO1xuICB9KSA6IGJhc2VQbGFjZW1lbnRzO1xuICB2YXIgYWxsb3dlZFBsYWNlbWVudHMgPSBwbGFjZW1lbnRzLmZpbHRlcihmdW5jdGlvbiAocGxhY2VtZW50KSB7XG4gICAgcmV0dXJuIGFsbG93ZWRBdXRvUGxhY2VtZW50cy5pbmRleE9mKHBsYWNlbWVudCkgPj0gMDtcbiAgfSk7XG5cbiAgaWYgKGFsbG93ZWRQbGFjZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGFsbG93ZWRQbGFjZW1lbnRzID0gcGxhY2VtZW50cztcbiAgfSAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS10eXBlXTogRmxvdyBzZWVtcyB0byBoYXZlIHByb2JsZW1zIHdpdGggdHdvIGFycmF5IHVuaW9ucy4uLlxuXG5cbiAgdmFyIG92ZXJmbG93cyA9IGFsbG93ZWRQbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgICBhY2NbcGxhY2VtZW50XSA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZ1xuICAgIH0pW2dldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KV07XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xuICByZXR1cm4gT2JqZWN0LmtleXMob3ZlcmZsb3dzKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIG92ZXJmbG93c1thXSAtIG92ZXJmbG93c1tiXTtcbiAgfSk7XG59IiwgImltcG9ydCBnZXRPcHBvc2l0ZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0T3Bwb3NpdGVQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgY29tcHV0ZUF1dG9QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2NvbXB1dGVBdXRvUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgeyBib3R0b20sIHRvcCwgc3RhcnQsIHJpZ2h0LCBsZWZ0LCBhdXRvIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5mdW5jdGlvbiBnZXRFeHBhbmRlZEZhbGxiYWNrUGxhY2VtZW50cyhwbGFjZW1lbnQpIHtcbiAgaWYgKGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA9PT0gYXV0bykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHZhciBvcHBvc2l0ZVBsYWNlbWVudCA9IGdldE9wcG9zaXRlUGxhY2VtZW50KHBsYWNlbWVudCk7XG4gIHJldHVybiBbZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQocGxhY2VtZW50KSwgb3Bwb3NpdGVQbGFjZW1lbnQsIGdldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50KG9wcG9zaXRlUGxhY2VtZW50KV07XG59XG5cbmZ1bmN0aW9uIGZsaXAoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucyxcbiAgICAgIG5hbWUgPSBfcmVmLm5hbWU7XG5cbiAgaWYgKHN0YXRlLm1vZGlmaWVyc0RhdGFbbmFtZV0uX3NraXApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgX29wdGlvbnMkbWFpbkF4aXMgPSBvcHRpb25zLm1haW5BeGlzLFxuICAgICAgY2hlY2tNYWluQXhpcyA9IF9vcHRpb25zJG1haW5BeGlzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkbWFpbkF4aXMsXG4gICAgICBfb3B0aW9ucyRhbHRBeGlzID0gb3B0aW9ucy5hbHRBeGlzLFxuICAgICAgY2hlY2tBbHRBeGlzID0gX29wdGlvbnMkYWx0QXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGFsdEF4aXMsXG4gICAgICBzcGVjaWZpZWRGYWxsYmFja1BsYWNlbWVudHMgPSBvcHRpb25zLmZhbGxiYWNrUGxhY2VtZW50cyxcbiAgICAgIHBhZGRpbmcgPSBvcHRpb25zLnBhZGRpbmcsXG4gICAgICBib3VuZGFyeSA9IG9wdGlvbnMuYm91bmRhcnksXG4gICAgICByb290Qm91bmRhcnkgPSBvcHRpb25zLnJvb3RCb3VuZGFyeSxcbiAgICAgIGFsdEJvdW5kYXJ5ID0gb3B0aW9ucy5hbHRCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJGZsaXBWYXJpYXRpbyA9IG9wdGlvbnMuZmxpcFZhcmlhdGlvbnMsXG4gICAgICBmbGlwVmFyaWF0aW9ucyA9IF9vcHRpb25zJGZsaXBWYXJpYXRpbyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGZsaXBWYXJpYXRpbyxcbiAgICAgIGFsbG93ZWRBdXRvUGxhY2VtZW50cyA9IG9wdGlvbnMuYWxsb3dlZEF1dG9QbGFjZW1lbnRzO1xuICB2YXIgcHJlZmVycmVkUGxhY2VtZW50ID0gc3RhdGUub3B0aW9ucy5wbGFjZW1lbnQ7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwcmVmZXJyZWRQbGFjZW1lbnQpO1xuICB2YXIgaXNCYXNlUGxhY2VtZW50ID0gYmFzZVBsYWNlbWVudCA9PT0gcHJlZmVycmVkUGxhY2VtZW50O1xuICB2YXIgZmFsbGJhY2tQbGFjZW1lbnRzID0gc3BlY2lmaWVkRmFsbGJhY2tQbGFjZW1lbnRzIHx8IChpc0Jhc2VQbGFjZW1lbnQgfHwgIWZsaXBWYXJpYXRpb25zID8gW2dldE9wcG9zaXRlUGxhY2VtZW50KHByZWZlcnJlZFBsYWNlbWVudCldIDogZ2V0RXhwYW5kZWRGYWxsYmFja1BsYWNlbWVudHMocHJlZmVycmVkUGxhY2VtZW50KSk7XG4gIHZhciBwbGFjZW1lbnRzID0gW3ByZWZlcnJlZFBsYWNlbWVudF0uY29uY2F0KGZhbGxiYWNrUGxhY2VtZW50cykucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICAgIHJldHVybiBhY2MuY29uY2F0KGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA9PT0gYXV0byA/IGNvbXB1dGVBdXRvUGxhY2VtZW50KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZyxcbiAgICAgIGZsaXBWYXJpYXRpb25zOiBmbGlwVmFyaWF0aW9ucyxcbiAgICAgIGFsbG93ZWRBdXRvUGxhY2VtZW50czogYWxsb3dlZEF1dG9QbGFjZW1lbnRzXG4gICAgfSkgOiBwbGFjZW1lbnQpO1xuICB9LCBbXSk7XG4gIHZhciByZWZlcmVuY2VSZWN0ID0gc3RhdGUucmVjdHMucmVmZXJlbmNlO1xuICB2YXIgcG9wcGVyUmVjdCA9IHN0YXRlLnJlY3RzLnBvcHBlcjtcbiAgdmFyIGNoZWNrc01hcCA9IG5ldyBNYXAoKTtcbiAgdmFyIG1ha2VGYWxsYmFja0NoZWNrcyA9IHRydWU7XG4gIHZhciBmaXJzdEZpdHRpbmdQbGFjZW1lbnQgPSBwbGFjZW1lbnRzWzBdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGxhY2VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwbGFjZW1lbnQgPSBwbGFjZW1lbnRzW2ldO1xuXG4gICAgdmFyIF9iYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuXG4gICAgdmFyIGlzU3RhcnRWYXJpYXRpb24gPSBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA9PT0gc3RhcnQ7XG4gICAgdmFyIGlzVmVydGljYWwgPSBbdG9wLCBib3R0b21dLmluZGV4T2YoX2Jhc2VQbGFjZW1lbnQpID49IDA7XG4gICAgdmFyIGxlbiA9IGlzVmVydGljYWwgPyAnd2lkdGgnIDogJ2hlaWdodCc7XG4gICAgdmFyIG92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICAgIHBsYWNlbWVudDogcGxhY2VtZW50LFxuICAgICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5OiByb290Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeTogYWx0Qm91bmRhcnksXG4gICAgICBwYWRkaW5nOiBwYWRkaW5nXG4gICAgfSk7XG4gICAgdmFyIG1haW5WYXJpYXRpb25TaWRlID0gaXNWZXJ0aWNhbCA/IGlzU3RhcnRWYXJpYXRpb24gPyByaWdodCA6IGxlZnQgOiBpc1N0YXJ0VmFyaWF0aW9uID8gYm90dG9tIDogdG9wO1xuXG4gICAgaWYgKHJlZmVyZW5jZVJlY3RbbGVuXSA+IHBvcHBlclJlY3RbbGVuXSkge1xuICAgICAgbWFpblZhcmlhdGlvblNpZGUgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChtYWluVmFyaWF0aW9uU2lkZSk7XG4gICAgfVxuXG4gICAgdmFyIGFsdFZhcmlhdGlvblNpZGUgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChtYWluVmFyaWF0aW9uU2lkZSk7XG4gICAgdmFyIGNoZWNrcyA9IFtdO1xuXG4gICAgaWYgKGNoZWNrTWFpbkF4aXMpIHtcbiAgICAgIGNoZWNrcy5wdXNoKG92ZXJmbG93W19iYXNlUGxhY2VtZW50XSA8PSAwKTtcbiAgICB9XG5cbiAgICBpZiAoY2hlY2tBbHRBeGlzKSB7XG4gICAgICBjaGVja3MucHVzaChvdmVyZmxvd1ttYWluVmFyaWF0aW9uU2lkZV0gPD0gMCwgb3ZlcmZsb3dbYWx0VmFyaWF0aW9uU2lkZV0gPD0gMCk7XG4gICAgfVxuXG4gICAgaWYgKGNoZWNrcy5ldmVyeShmdW5jdGlvbiAoY2hlY2spIHtcbiAgICAgIHJldHVybiBjaGVjaztcbiAgICB9KSkge1xuICAgICAgZmlyc3RGaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50O1xuICAgICAgbWFrZUZhbGxiYWNrQ2hlY2tzID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjaGVja3NNYXAuc2V0KHBsYWNlbWVudCwgY2hlY2tzKTtcbiAgfVxuXG4gIGlmIChtYWtlRmFsbGJhY2tDaGVja3MpIHtcbiAgICAvLyBgMmAgbWF5IGJlIGRlc2lyZWQgaW4gc29tZSBjYXNlcyBcdTIwMTMgcmVzZWFyY2ggbGF0ZXJcbiAgICB2YXIgbnVtYmVyT2ZDaGVja3MgPSBmbGlwVmFyaWF0aW9ucyA/IDMgOiAxO1xuXG4gICAgdmFyIF9sb29wID0gZnVuY3Rpb24gX2xvb3AoX2kpIHtcbiAgICAgIHZhciBmaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50cy5maW5kKGZ1bmN0aW9uIChwbGFjZW1lbnQpIHtcbiAgICAgICAgdmFyIGNoZWNrcyA9IGNoZWNrc01hcC5nZXQocGxhY2VtZW50KTtcblxuICAgICAgICBpZiAoY2hlY2tzKSB7XG4gICAgICAgICAgcmV0dXJuIGNoZWNrcy5zbGljZSgwLCBfaSkuZXZlcnkoZnVuY3Rpb24gKGNoZWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gY2hlY2s7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAoZml0dGluZ1BsYWNlbWVudCkge1xuICAgICAgICBmaXJzdEZpdHRpbmdQbGFjZW1lbnQgPSBmaXR0aW5nUGxhY2VtZW50O1xuICAgICAgICByZXR1cm4gXCJicmVha1wiO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKHZhciBfaSA9IG51bWJlck9mQ2hlY2tzOyBfaSA+IDA7IF9pLS0pIHtcbiAgICAgIHZhciBfcmV0ID0gX2xvb3AoX2kpO1xuXG4gICAgICBpZiAoX3JldCA9PT0gXCJicmVha1wiKSBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUucGxhY2VtZW50ICE9PSBmaXJzdEZpdHRpbmdQbGFjZW1lbnQpIHtcbiAgICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdLl9za2lwID0gdHJ1ZTtcbiAgICBzdGF0ZS5wbGFjZW1lbnQgPSBmaXJzdEZpdHRpbmdQbGFjZW1lbnQ7XG4gICAgc3RhdGUucmVzZXQgPSB0cnVlO1xuICB9XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdmbGlwJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdtYWluJyxcbiAgZm46IGZsaXAsXG4gIHJlcXVpcmVzSWZFeGlzdHM6IFsnb2Zmc2V0J10sXG4gIGRhdGE6IHtcbiAgICBfc2tpcDogZmFsc2VcbiAgfVxufTsiLCAiaW1wb3J0IHsgdG9wLCBib3R0b20sIGxlZnQsIHJpZ2h0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5cbmZ1bmN0aW9uIGdldFNpZGVPZmZzZXRzKG92ZXJmbG93LCByZWN0LCBwcmV2ZW50ZWRPZmZzZXRzKSB7XG4gIGlmIChwcmV2ZW50ZWRPZmZzZXRzID09PSB2b2lkIDApIHtcbiAgICBwcmV2ZW50ZWRPZmZzZXRzID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0b3A6IG92ZXJmbG93LnRvcCAtIHJlY3QuaGVpZ2h0IC0gcHJldmVudGVkT2Zmc2V0cy55LFxuICAgIHJpZ2h0OiBvdmVyZmxvdy5yaWdodCAtIHJlY3Qud2lkdGggKyBwcmV2ZW50ZWRPZmZzZXRzLngsXG4gICAgYm90dG9tOiBvdmVyZmxvdy5ib3R0b20gLSByZWN0LmhlaWdodCArIHByZXZlbnRlZE9mZnNldHMueSxcbiAgICBsZWZ0OiBvdmVyZmxvdy5sZWZ0IC0gcmVjdC53aWR0aCAtIHByZXZlbnRlZE9mZnNldHMueFxuICB9O1xufVxuXG5mdW5jdGlvbiBpc0FueVNpZGVGdWxseUNsaXBwZWQob3ZlcmZsb3cpIHtcbiAgcmV0dXJuIFt0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRdLnNvbWUoZnVuY3Rpb24gKHNpZGUpIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dbc2lkZV0gPj0gMDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGhpZGUoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgcHJldmVudGVkT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucHJldmVudE92ZXJmbG93O1xuICB2YXIgcmVmZXJlbmNlT3ZlcmZsb3cgPSBkZXRlY3RPdmVyZmxvdyhzdGF0ZSwge1xuICAgIGVsZW1lbnRDb250ZXh0OiAncmVmZXJlbmNlJ1xuICB9KTtcbiAgdmFyIHBvcHBlckFsdE92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICBhbHRCb3VuZGFyeTogdHJ1ZVxuICB9KTtcbiAgdmFyIHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyA9IGdldFNpZGVPZmZzZXRzKHJlZmVyZW5jZU92ZXJmbG93LCByZWZlcmVuY2VSZWN0KTtcbiAgdmFyIHBvcHBlckVzY2FwZU9mZnNldHMgPSBnZXRTaWRlT2Zmc2V0cyhwb3BwZXJBbHRPdmVyZmxvdywgcG9wcGVyUmVjdCwgcHJldmVudGVkT2Zmc2V0cyk7XG4gIHZhciBpc1JlZmVyZW5jZUhpZGRlbiA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChyZWZlcmVuY2VDbGlwcGluZ09mZnNldHMpO1xuICB2YXIgaGFzUG9wcGVyRXNjYXBlZCA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChwb3BwZXJFc2NhcGVPZmZzZXRzKTtcbiAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXSA9IHtcbiAgICByZWZlcmVuY2VDbGlwcGluZ09mZnNldHM6IHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyxcbiAgICBwb3BwZXJFc2NhcGVPZmZzZXRzOiBwb3BwZXJFc2NhcGVPZmZzZXRzLFxuICAgIGlzUmVmZXJlbmNlSGlkZGVuOiBpc1JlZmVyZW5jZUhpZGRlbixcbiAgICBoYXNQb3BwZXJFc2NhcGVkOiBoYXNQb3BwZXJFc2NhcGVkXG4gIH07XG4gIHN0YXRlLmF0dHJpYnV0ZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIsIHtcbiAgICAnZGF0YS1wb3BwZXItcmVmZXJlbmNlLWhpZGRlbic6IGlzUmVmZXJlbmNlSGlkZGVuLFxuICAgICdkYXRhLXBvcHBlci1lc2NhcGVkJzogaGFzUG9wcGVyRXNjYXBlZFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2hpZGUnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ21haW4nLFxuICByZXF1aXJlc0lmRXhpc3RzOiBbJ3ByZXZlbnRPdmVyZmxvdyddLFxuICBmbjogaGlkZVxufTsiLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIHBsYWNlbWVudHMgfSBmcm9tIFwiLi4vZW51bXMuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2VBbmRTa2lkZGluZ1RvWFkocGxhY2VtZW50LCByZWN0cywgb2Zmc2V0KSB7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuICB2YXIgaW52ZXJ0RGlzdGFuY2UgPSBbbGVmdCwgdG9wXS5pbmRleE9mKGJhc2VQbGFjZW1lbnQpID49IDAgPyAtMSA6IDE7XG5cbiAgdmFyIF9yZWYgPSB0eXBlb2Ygb2Zmc2V0ID09PSAnZnVuY3Rpb24nID8gb2Zmc2V0KE9iamVjdC5hc3NpZ24oe30sIHJlY3RzLCB7XG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSkpIDogb2Zmc2V0LFxuICAgICAgc2tpZGRpbmcgPSBfcmVmWzBdLFxuICAgICAgZGlzdGFuY2UgPSBfcmVmWzFdO1xuXG4gIHNraWRkaW5nID0gc2tpZGRpbmcgfHwgMDtcbiAgZGlzdGFuY2UgPSAoZGlzdGFuY2UgfHwgMCkgKiBpbnZlcnREaXN0YW5jZTtcbiAgcmV0dXJuIFtsZWZ0LCByaWdodF0uaW5kZXhPZihiYXNlUGxhY2VtZW50KSA+PSAwID8ge1xuICAgIHg6IGRpc3RhbmNlLFxuICAgIHk6IHNraWRkaW5nXG4gIH0gOiB7XG4gICAgeDogc2tpZGRpbmcsXG4gICAgeTogZGlzdGFuY2VcbiAgfTtcbn1cblxuZnVuY3Rpb24gb2Zmc2V0KF9yZWYyKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYyLnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYyLm9wdGlvbnMsXG4gICAgICBuYW1lID0gX3JlZjIubmFtZTtcbiAgdmFyIF9vcHRpb25zJG9mZnNldCA9IG9wdGlvbnMub2Zmc2V0LFxuICAgICAgb2Zmc2V0ID0gX29wdGlvbnMkb2Zmc2V0ID09PSB2b2lkIDAgPyBbMCwgMF0gOiBfb3B0aW9ucyRvZmZzZXQ7XG4gIHZhciBkYXRhID0gcGxhY2VtZW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcGxhY2VtZW50KSB7XG4gICAgYWNjW3BsYWNlbWVudF0gPSBkaXN0YW5jZUFuZFNraWRkaW5nVG9YWShwbGFjZW1lbnQsIHN0YXRlLnJlY3RzLCBvZmZzZXQpO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbiAgdmFyIF9kYXRhJHN0YXRlJHBsYWNlbWVudCA9IGRhdGFbc3RhdGUucGxhY2VtZW50XSxcbiAgICAgIHggPSBfZGF0YSRzdGF0ZSRwbGFjZW1lbnQueCxcbiAgICAgIHkgPSBfZGF0YSRzdGF0ZSRwbGFjZW1lbnQueTtcblxuICBpZiAoc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzICE9IG51bGwpIHtcbiAgICBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMueCArPSB4O1xuICAgIHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cy55ICs9IHk7XG4gIH1cblxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gZGF0YTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ29mZnNldCcsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIHJlcXVpcmVzOiBbJ3BvcHBlck9mZnNldHMnXSxcbiAgZm46IG9mZnNldFxufTsiLCAiaW1wb3J0IGNvbXB1dGVPZmZzZXRzIGZyb20gXCIuLi91dGlscy9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuXG5mdW5jdGlvbiBwb3BwZXJPZmZzZXRzKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIG5hbWUgPSBfcmVmLm5hbWU7XG4gIC8vIE9mZnNldHMgYXJlIHRoZSBhY3R1YWwgcG9zaXRpb24gdGhlIHBvcHBlciBuZWVkcyB0byBoYXZlIHRvIGJlXG4gIC8vIHByb3Blcmx5IHBvc2l0aW9uZWQgbmVhciBpdHMgcmVmZXJlbmNlIGVsZW1lbnRcbiAgLy8gVGhpcyBpcyB0aGUgbW9zdCBiYXNpYyBwbGFjZW1lbnQsIGFuZCB3aWxsIGJlIGFkanVzdGVkIGJ5XG4gIC8vIHRoZSBtb2RpZmllcnMgaW4gdGhlIG5leHQgc3RlcFxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gY29tcHV0ZU9mZnNldHMoe1xuICAgIHJlZmVyZW5jZTogc3RhdGUucmVjdHMucmVmZXJlbmNlLFxuICAgIGVsZW1lbnQ6IHN0YXRlLnJlY3RzLnBvcHBlcixcbiAgICBzdHJhdGVneTogJ2Fic29sdXRlJyxcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ3BvcHBlck9mZnNldHMnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ3JlYWQnLFxuICBmbjogcG9wcGVyT2Zmc2V0cyxcbiAgZGF0YToge31cbn07IiwgImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEFsdEF4aXMoYXhpcykge1xuICByZXR1cm4gYXhpcyA9PT0gJ3gnID8gJ3knIDogJ3gnO1xufSIsICJpbXBvcnQgeyB0b3AsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHN0YXJ0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0QWx0QXhpcyBmcm9tIFwiLi4vdXRpbHMvZ2V0QWx0QXhpcy5qc1wiO1xuaW1wb3J0IHsgd2l0aGluLCB3aXRoaW5NYXhDbGFtcCB9IGZyb20gXCIuLi91dGlscy93aXRoaW4uanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE9mZnNldFBhcmVudC5qc1wiO1xuaW1wb3J0IGRldGVjdE92ZXJmbG93IGZyb20gXCIuLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi4vdXRpbHMvZ2V0VmFyaWF0aW9uLmpzXCI7XG5pbXBvcnQgZ2V0RnJlc2hTaWRlT2JqZWN0IGZyb20gXCIuLi91dGlscy9nZXRGcmVzaFNpZGVPYmplY3QuanNcIjtcbmltcG9ydCB7IG1pbiBhcyBtYXRoTWluLCBtYXggYXMgbWF0aE1heCB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7XG5cbmZ1bmN0aW9uIHByZXZlbnRPdmVyZmxvdyhfcmVmKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZi5vcHRpb25zLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIF9vcHRpb25zJG1haW5BeGlzID0gb3B0aW9ucy5tYWluQXhpcyxcbiAgICAgIGNoZWNrTWFpbkF4aXMgPSBfb3B0aW9ucyRtYWluQXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJG1haW5BeGlzLFxuICAgICAgX29wdGlvbnMkYWx0QXhpcyA9IG9wdGlvbnMuYWx0QXhpcyxcbiAgICAgIGNoZWNrQWx0QXhpcyA9IF9vcHRpb25zJGFsdEF4aXMgPT09IHZvaWQgMCA/IGZhbHNlIDogX29wdGlvbnMkYWx0QXhpcyxcbiAgICAgIGJvdW5kYXJ5ID0gb3B0aW9ucy5ib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeSA9IG9wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgYWx0Qm91bmRhcnkgPSBvcHRpb25zLmFsdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZyA9IG9wdGlvbnMucGFkZGluZyxcbiAgICAgIF9vcHRpb25zJHRldGhlciA9IG9wdGlvbnMudGV0aGVyLFxuICAgICAgdGV0aGVyID0gX29wdGlvbnMkdGV0aGVyID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkdGV0aGVyLFxuICAgICAgX29wdGlvbnMkdGV0aGVyT2Zmc2V0ID0gb3B0aW9ucy50ZXRoZXJPZmZzZXQsXG4gICAgICB0ZXRoZXJPZmZzZXQgPSBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQgPT09IHZvaWQgMCA/IDAgOiBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQ7XG4gIHZhciBvdmVyZmxvdyA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgIHBhZGRpbmc6IHBhZGRpbmcsXG4gICAgYWx0Qm91bmRhcnk6IGFsdEJvdW5kYXJ5XG4gIH0pO1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IGdldEJhc2VQbGFjZW1lbnQoc3RhdGUucGxhY2VtZW50KTtcbiAgdmFyIHZhcmlhdGlvbiA9IGdldFZhcmlhdGlvbihzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgaXNCYXNlUGxhY2VtZW50ID0gIXZhcmlhdGlvbjtcbiAgdmFyIG1haW5BeGlzID0gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KGJhc2VQbGFjZW1lbnQpO1xuICB2YXIgYWx0QXhpcyA9IGdldEFsdEF4aXMobWFpbkF4aXMpO1xuICB2YXIgcG9wcGVyT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cztcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgdGV0aGVyT2Zmc2V0VmFsdWUgPSB0eXBlb2YgdGV0aGVyT2Zmc2V0ID09PSAnZnVuY3Rpb24nID8gdGV0aGVyT2Zmc2V0KE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnJlY3RzLCB7XG4gICAgcGxhY2VtZW50OiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSkpIDogdGV0aGVyT2Zmc2V0O1xuICB2YXIgbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlID0gdHlwZW9mIHRldGhlck9mZnNldFZhbHVlID09PSAnbnVtYmVyJyA/IHtcbiAgICBtYWluQXhpczogdGV0aGVyT2Zmc2V0VmFsdWUsXG4gICAgYWx0QXhpczogdGV0aGVyT2Zmc2V0VmFsdWVcbiAgfSA6IE9iamVjdC5hc3NpZ24oe1xuICAgIG1haW5BeGlzOiAwLFxuICAgIGFsdEF4aXM6IDBcbiAgfSwgdGV0aGVyT2Zmc2V0VmFsdWUpO1xuICB2YXIgb2Zmc2V0TW9kaWZpZXJTdGF0ZSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0ID8gc3RhdGUubW9kaWZpZXJzRGF0YS5vZmZzZXRbc3RhdGUucGxhY2VtZW50XSA6IG51bGw7XG4gIHZhciBkYXRhID0ge1xuICAgIHg6IDAsXG4gICAgeTogMFxuICB9O1xuXG4gIGlmICghcG9wcGVyT2Zmc2V0cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChjaGVja01haW5BeGlzKSB7XG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclN0YXRlJDtcblxuICAgIHZhciBtYWluU2lkZSA9IG1haW5BeGlzID09PSAneScgPyB0b3AgOiBsZWZ0O1xuICAgIHZhciBhbHRTaWRlID0gbWFpbkF4aXMgPT09ICd5JyA/IGJvdHRvbSA6IHJpZ2h0O1xuICAgIHZhciBsZW4gPSBtYWluQXhpcyA9PT0gJ3knID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuICAgIHZhciBvZmZzZXQgPSBwb3BwZXJPZmZzZXRzW21haW5BeGlzXTtcbiAgICB2YXIgbWluID0gb2Zmc2V0ICsgb3ZlcmZsb3dbbWFpblNpZGVdO1xuICAgIHZhciBtYXggPSBvZmZzZXQgLSBvdmVyZmxvd1thbHRTaWRlXTtcbiAgICB2YXIgYWRkaXRpdmUgPSB0ZXRoZXIgPyAtcG9wcGVyUmVjdFtsZW5dIC8gMiA6IDA7XG4gICAgdmFyIG1pbkxlbiA9IHZhcmlhdGlvbiA9PT0gc3RhcnQgPyByZWZlcmVuY2VSZWN0W2xlbl0gOiBwb3BwZXJSZWN0W2xlbl07XG4gICAgdmFyIG1heExlbiA9IHZhcmlhdGlvbiA9PT0gc3RhcnQgPyAtcG9wcGVyUmVjdFtsZW5dIDogLXJlZmVyZW5jZVJlY3RbbGVuXTsgLy8gV2UgbmVlZCB0byBpbmNsdWRlIHRoZSBhcnJvdyBpbiB0aGUgY2FsY3VsYXRpb24gc28gdGhlIGFycm93IGRvZXNuJ3QgZ29cbiAgICAvLyBvdXRzaWRlIHRoZSByZWZlcmVuY2UgYm91bmRzXG5cbiAgICB2YXIgYXJyb3dFbGVtZW50ID0gc3RhdGUuZWxlbWVudHMuYXJyb3c7XG4gICAgdmFyIGFycm93UmVjdCA9IHRldGhlciAmJiBhcnJvd0VsZW1lbnQgPyBnZXRMYXlvdXRSZWN0KGFycm93RWxlbWVudCkgOiB7XG4gICAgICB3aWR0aDogMCxcbiAgICAgIGhlaWdodDogMFxuICAgIH07XG4gICAgdmFyIGFycm93UGFkZGluZ09iamVjdCA9IHN0YXRlLm1vZGlmaWVyc0RhdGFbJ2Fycm93I3BlcnNpc3RlbnQnXSA/IHN0YXRlLm1vZGlmaWVyc0RhdGFbJ2Fycm93I3BlcnNpc3RlbnQnXS5wYWRkaW5nIDogZ2V0RnJlc2hTaWRlT2JqZWN0KCk7XG4gICAgdmFyIGFycm93UGFkZGluZ01pbiA9IGFycm93UGFkZGluZ09iamVjdFttYWluU2lkZV07XG4gICAgdmFyIGFycm93UGFkZGluZ01heCA9IGFycm93UGFkZGluZ09iamVjdFthbHRTaWRlXTsgLy8gSWYgdGhlIHJlZmVyZW5jZSBsZW5ndGggaXMgc21hbGxlciB0aGFuIHRoZSBhcnJvdyBsZW5ndGgsIHdlIGRvbid0IHdhbnRcbiAgICAvLyB0byBpbmNsdWRlIGl0cyBmdWxsIHNpemUgaW4gdGhlIGNhbGN1bGF0aW9uLiBJZiB0aGUgcmVmZXJlbmNlIGlzIHNtYWxsXG4gICAgLy8gYW5kIG5lYXIgdGhlIGVkZ2Ugb2YgYSBib3VuZGFyeSwgdGhlIHBvcHBlciBjYW4gb3ZlcmZsb3cgZXZlbiBpZiB0aGVcbiAgICAvLyByZWZlcmVuY2UgaXMgbm90IG92ZXJmbG93aW5nIGFzIHdlbGwgKGUuZy4gdmlydHVhbCBlbGVtZW50cyB3aXRoIG5vXG4gICAgLy8gd2lkdGggb3IgaGVpZ2h0KVxuXG4gICAgdmFyIGFycm93TGVuID0gd2l0aGluKDAsIHJlZmVyZW5jZVJlY3RbbGVuXSwgYXJyb3dSZWN0W2xlbl0pO1xuICAgIHZhciBtaW5PZmZzZXQgPSBpc0Jhc2VQbGFjZW1lbnQgPyByZWZlcmVuY2VSZWN0W2xlbl0gLyAyIC0gYWRkaXRpdmUgLSBhcnJvd0xlbiAtIGFycm93UGFkZGluZ01pbiAtIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcyA6IG1pbkxlbiAtIGFycm93TGVuIC0gYXJyb3dQYWRkaW5nTWluIC0gbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLm1haW5BeGlzO1xuICAgIHZhciBtYXhPZmZzZXQgPSBpc0Jhc2VQbGFjZW1lbnQgPyAtcmVmZXJlbmNlUmVjdFtsZW5dIC8gMiArIGFkZGl0aXZlICsgYXJyb3dMZW4gKyBhcnJvd1BhZGRpbmdNYXggKyBub3JtYWxpemVkVGV0aGVyT2Zmc2V0VmFsdWUubWFpbkF4aXMgOiBtYXhMZW4gKyBhcnJvd0xlbiArIGFycm93UGFkZGluZ01heCArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcztcbiAgICB2YXIgYXJyb3dPZmZzZXRQYXJlbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdyAmJiBnZXRPZmZzZXRQYXJlbnQoc3RhdGUuZWxlbWVudHMuYXJyb3cpO1xuICAgIHZhciBjbGllbnRPZmZzZXQgPSBhcnJvd09mZnNldFBhcmVudCA/IG1haW5BeGlzID09PSAneScgPyBhcnJvd09mZnNldFBhcmVudC5jbGllbnRUb3AgfHwgMCA6IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudExlZnQgfHwgMCA6IDA7XG4gICAgdmFyIG9mZnNldE1vZGlmaWVyVmFsdWUgPSAoX29mZnNldE1vZGlmaWVyU3RhdGUkID0gb2Zmc2V0TW9kaWZpZXJTdGF0ZSA9PSBudWxsID8gdm9pZCAwIDogb2Zmc2V0TW9kaWZpZXJTdGF0ZVttYWluQXhpc10pICE9IG51bGwgPyBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQgOiAwO1xuICAgIHZhciB0ZXRoZXJNaW4gPSBvZmZzZXQgKyBtaW5PZmZzZXQgLSBvZmZzZXRNb2RpZmllclZhbHVlIC0gY2xpZW50T2Zmc2V0O1xuICAgIHZhciB0ZXRoZXJNYXggPSBvZmZzZXQgKyBtYXhPZmZzZXQgLSBvZmZzZXRNb2RpZmllclZhbHVlO1xuICAgIHZhciBwcmV2ZW50ZWRPZmZzZXQgPSB3aXRoaW4odGV0aGVyID8gbWF0aE1pbihtaW4sIHRldGhlck1pbikgOiBtaW4sIG9mZnNldCwgdGV0aGVyID8gbWF0aE1heChtYXgsIHRldGhlck1heCkgOiBtYXgpO1xuICAgIHBvcHBlck9mZnNldHNbbWFpbkF4aXNdID0gcHJldmVudGVkT2Zmc2V0O1xuICAgIGRhdGFbbWFpbkF4aXNdID0gcHJldmVudGVkT2Zmc2V0IC0gb2Zmc2V0O1xuICB9XG5cbiAgaWYgKGNoZWNrQWx0QXhpcykge1xuICAgIHZhciBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQyO1xuXG4gICAgdmFyIF9tYWluU2lkZSA9IG1haW5BeGlzID09PSAneCcgPyB0b3AgOiBsZWZ0O1xuXG4gICAgdmFyIF9hbHRTaWRlID0gbWFpbkF4aXMgPT09ICd4JyA/IGJvdHRvbSA6IHJpZ2h0O1xuXG4gICAgdmFyIF9vZmZzZXQgPSBwb3BwZXJPZmZzZXRzW2FsdEF4aXNdO1xuXG4gICAgdmFyIF9sZW4gPSBhbHRBeGlzID09PSAneScgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG5cbiAgICB2YXIgX21pbiA9IF9vZmZzZXQgKyBvdmVyZmxvd1tfbWFpblNpZGVdO1xuXG4gICAgdmFyIF9tYXggPSBfb2Zmc2V0IC0gb3ZlcmZsb3dbX2FsdFNpZGVdO1xuXG4gICAgdmFyIGlzT3JpZ2luU2lkZSA9IFt0b3AsIGxlZnRdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgIT09IC0xO1xuXG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclZhbHVlID0gKF9vZmZzZXRNb2RpZmllclN0YXRlJDIgPSBvZmZzZXRNb2RpZmllclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBvZmZzZXRNb2RpZmllclN0YXRlW2FsdEF4aXNdKSAhPSBudWxsID8gX29mZnNldE1vZGlmaWVyU3RhdGUkMiA6IDA7XG5cbiAgICB2YXIgX3RldGhlck1pbiA9IGlzT3JpZ2luU2lkZSA/IF9taW4gOiBfb2Zmc2V0IC0gcmVmZXJlbmNlUmVjdFtfbGVuXSAtIHBvcHBlclJlY3RbX2xlbl0gLSBfb2Zmc2V0TW9kaWZpZXJWYWx1ZSArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5hbHRBeGlzO1xuXG4gICAgdmFyIF90ZXRoZXJNYXggPSBpc09yaWdpblNpZGUgPyBfb2Zmc2V0ICsgcmVmZXJlbmNlUmVjdFtfbGVuXSArIHBvcHBlclJlY3RbX2xlbl0gLSBfb2Zmc2V0TW9kaWZpZXJWYWx1ZSAtIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5hbHRBeGlzIDogX21heDtcblxuICAgIHZhciBfcHJldmVudGVkT2Zmc2V0ID0gdGV0aGVyICYmIGlzT3JpZ2luU2lkZSA/IHdpdGhpbk1heENsYW1wKF90ZXRoZXJNaW4sIF9vZmZzZXQsIF90ZXRoZXJNYXgpIDogd2l0aGluKHRldGhlciA/IF90ZXRoZXJNaW4gOiBfbWluLCBfb2Zmc2V0LCB0ZXRoZXIgPyBfdGV0aGVyTWF4IDogX21heCk7XG5cbiAgICBwb3BwZXJPZmZzZXRzW2FsdEF4aXNdID0gX3ByZXZlbnRlZE9mZnNldDtcbiAgICBkYXRhW2FsdEF4aXNdID0gX3ByZXZlbnRlZE9mZnNldCAtIF9vZmZzZXQ7XG4gIH1cblxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gZGF0YTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ3ByZXZlbnRPdmVyZmxvdycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBwcmV2ZW50T3ZlcmZsb3csXG4gIHJlcXVpcmVzSWZFeGlzdHM6IFsnb2Zmc2V0J11cbn07IiwgImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEhUTUxFbGVtZW50U2Nyb2xsKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBlbGVtZW50LnNjcm9sbExlZnQsXG4gICAgc2Nyb2xsVG9wOiBlbGVtZW50LnNjcm9sbFRvcFxuICB9O1xufSIsICJpbXBvcnQgZ2V0V2luZG93U2Nyb2xsIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0SFRNTEVsZW1lbnRTY3JvbGwgZnJvbSBcIi4vZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE5vZGVTY3JvbGwobm9kZSkge1xuICBpZiAobm9kZSA9PT0gZ2V0V2luZG93KG5vZGUpIHx8ICFpc0hUTUxFbGVtZW50KG5vZGUpKSB7XG4gICAgcmV0dXJuIGdldFdpbmRvd1Njcm9sbChub2RlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZ2V0SFRNTEVsZW1lbnRTY3JvbGwobm9kZSk7XG4gIH1cbn0iLCAiaW1wb3J0IGdldEJvdW5kaW5nQ2xpZW50UmVjdCBmcm9tIFwiLi9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBnZXROb2RlU2Nyb2xsIGZyb20gXCIuL2dldE5vZGVTY3JvbGwuanNcIjtcbmltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi9nZXROb2RlTmFtZS5qc1wiO1xuaW1wb3J0IHsgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBnZXRXaW5kb3dTY3JvbGxCYXJYIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbEJhclguanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgaXNTY3JvbGxQYXJlbnQgZnJvbSBcIi4vaXNTY3JvbGxQYXJlbnQuanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcblxuZnVuY3Rpb24gaXNFbGVtZW50U2NhbGVkKGVsZW1lbnQpIHtcbiAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB2YXIgc2NhbGVYID0gcm91bmQocmVjdC53aWR0aCkgLyBlbGVtZW50Lm9mZnNldFdpZHRoIHx8IDE7XG4gIHZhciBzY2FsZVkgPSByb3VuZChyZWN0LmhlaWdodCkgLyBlbGVtZW50Lm9mZnNldEhlaWdodCB8fCAxO1xuICByZXR1cm4gc2NhbGVYICE9PSAxIHx8IHNjYWxlWSAhPT0gMTtcbn0gLy8gUmV0dXJucyB0aGUgY29tcG9zaXRlIHJlY3Qgb2YgYW4gZWxlbWVudCByZWxhdGl2ZSB0byBpdHMgb2Zmc2V0UGFyZW50LlxuLy8gQ29tcG9zaXRlIG1lYW5zIGl0IHRha2VzIGludG8gYWNjb3VudCB0cmFuc2Zvcm1zIGFzIHdlbGwgYXMgbGF5b3V0LlxuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENvbXBvc2l0ZVJlY3QoZWxlbWVudE9yVmlydHVhbEVsZW1lbnQsIG9mZnNldFBhcmVudCwgaXNGaXhlZCkge1xuICBpZiAoaXNGaXhlZCA9PT0gdm9pZCAwKSB7XG4gICAgaXNGaXhlZCA9IGZhbHNlO1xuICB9XG5cbiAgdmFyIGlzT2Zmc2V0UGFyZW50QW5FbGVtZW50ID0gaXNIVE1MRWxlbWVudChvZmZzZXRQYXJlbnQpO1xuICB2YXIgb2Zmc2V0UGFyZW50SXNTY2FsZWQgPSBpc0hUTUxFbGVtZW50KG9mZnNldFBhcmVudCkgJiYgaXNFbGVtZW50U2NhbGVkKG9mZnNldFBhcmVudCk7XG4gIHZhciBkb2N1bWVudEVsZW1lbnQgPSBnZXREb2N1bWVudEVsZW1lbnQob2Zmc2V0UGFyZW50KTtcbiAgdmFyIHJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudE9yVmlydHVhbEVsZW1lbnQsIG9mZnNldFBhcmVudElzU2NhbGVkLCBpc0ZpeGVkKTtcbiAgdmFyIHNjcm9sbCA9IHtcbiAgICBzY3JvbGxMZWZ0OiAwLFxuICAgIHNjcm9sbFRvcDogMFxuICB9O1xuICB2YXIgb2Zmc2V0cyA9IHtcbiAgICB4OiAwLFxuICAgIHk6IDBcbiAgfTtcblxuICBpZiAoaXNPZmZzZXRQYXJlbnRBbkVsZW1lbnQgfHwgIWlzT2Zmc2V0UGFyZW50QW5FbGVtZW50ICYmICFpc0ZpeGVkKSB7XG4gICAgaWYgKGdldE5vZGVOYW1lKG9mZnNldFBhcmVudCkgIT09ICdib2R5JyB8fCAvLyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzEwNzhcbiAgICBpc1Njcm9sbFBhcmVudChkb2N1bWVudEVsZW1lbnQpKSB7XG4gICAgICBzY3JvbGwgPSBnZXROb2RlU2Nyb2xsKG9mZnNldFBhcmVudCk7XG4gICAgfVxuXG4gICAgaWYgKGlzSFRNTEVsZW1lbnQob2Zmc2V0UGFyZW50KSkge1xuICAgICAgb2Zmc2V0cyA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChvZmZzZXRQYXJlbnQsIHRydWUpO1xuICAgICAgb2Zmc2V0cy54ICs9IG9mZnNldFBhcmVudC5jbGllbnRMZWZ0O1xuICAgICAgb2Zmc2V0cy55ICs9IG9mZnNldFBhcmVudC5jbGllbnRUb3A7XG4gICAgfSBlbHNlIGlmIChkb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgIG9mZnNldHMueCA9IGdldFdpbmRvd1Njcm9sbEJhclgoZG9jdW1lbnRFbGVtZW50KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHg6IHJlY3QubGVmdCArIHNjcm9sbC5zY3JvbGxMZWZ0IC0gb2Zmc2V0cy54LFxuICAgIHk6IHJlY3QudG9wICsgc2Nyb2xsLnNjcm9sbFRvcCAtIG9mZnNldHMueSxcbiAgICB3aWR0aDogcmVjdC53aWR0aCxcbiAgICBoZWlnaHQ6IHJlY3QuaGVpZ2h0XG4gIH07XG59IiwgImltcG9ydCB7IG1vZGlmaWVyUGhhc2VzIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7IC8vIHNvdXJjZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDk4NzUyNTVcblxuZnVuY3Rpb24gb3JkZXIobW9kaWZpZXJzKSB7XG4gIHZhciBtYXAgPSBuZXcgTWFwKCk7XG4gIHZhciB2aXNpdGVkID0gbmV3IFNldCgpO1xuICB2YXIgcmVzdWx0ID0gW107XG4gIG1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgIG1hcC5zZXQobW9kaWZpZXIubmFtZSwgbW9kaWZpZXIpO1xuICB9KTsgLy8gT24gdmlzaXRpbmcgb2JqZWN0LCBjaGVjayBmb3IgaXRzIGRlcGVuZGVuY2llcyBhbmQgdmlzaXQgdGhlbSByZWN1cnNpdmVseVxuXG4gIGZ1bmN0aW9uIHNvcnQobW9kaWZpZXIpIHtcbiAgICB2aXNpdGVkLmFkZChtb2RpZmllci5uYW1lKTtcbiAgICB2YXIgcmVxdWlyZXMgPSBbXS5jb25jYXQobW9kaWZpZXIucmVxdWlyZXMgfHwgW10sIG1vZGlmaWVyLnJlcXVpcmVzSWZFeGlzdHMgfHwgW10pO1xuICAgIHJlcXVpcmVzLmZvckVhY2goZnVuY3Rpb24gKGRlcCkge1xuICAgICAgaWYgKCF2aXNpdGVkLmhhcyhkZXApKSB7XG4gICAgICAgIHZhciBkZXBNb2RpZmllciA9IG1hcC5nZXQoZGVwKTtcblxuICAgICAgICBpZiAoZGVwTW9kaWZpZXIpIHtcbiAgICAgICAgICBzb3J0KGRlcE1vZGlmaWVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJlc3VsdC5wdXNoKG1vZGlmaWVyKTtcbiAgfVxuXG4gIG1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgIGlmICghdmlzaXRlZC5oYXMobW9kaWZpZXIubmFtZSkpIHtcbiAgICAgIC8vIGNoZWNrIGZvciB2aXNpdGVkIG9iamVjdFxuICAgICAgc29ydChtb2RpZmllcik7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gb3JkZXJNb2RpZmllcnMobW9kaWZpZXJzKSB7XG4gIC8vIG9yZGVyIGJhc2VkIG9uIGRlcGVuZGVuY2llc1xuICB2YXIgb3JkZXJlZE1vZGlmaWVycyA9IG9yZGVyKG1vZGlmaWVycyk7IC8vIG9yZGVyIGJhc2VkIG9uIHBoYXNlXG5cbiAgcmV0dXJuIG1vZGlmaWVyUGhhc2VzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwaGFzZSkge1xuICAgIHJldHVybiBhY2MuY29uY2F0KG9yZGVyZWRNb2RpZmllcnMuZmlsdGVyKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgICAgcmV0dXJuIG1vZGlmaWVyLnBoYXNlID09PSBwaGFzZTtcbiAgICB9KSk7XG4gIH0sIFtdKTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVib3VuY2UoZm4pIHtcbiAgdmFyIHBlbmRpbmc7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFwZW5kaW5nKSB7XG4gICAgICBwZW5kaW5nID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcGVuZGluZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXNvbHZlKGZuKCkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwZW5kaW5nO1xuICB9O1xufSIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtZXJnZUJ5TmFtZShtb2RpZmllcnMpIHtcbiAgdmFyIG1lcmdlZCA9IG1vZGlmaWVycy5yZWR1Y2UoZnVuY3Rpb24gKG1lcmdlZCwgY3VycmVudCkge1xuICAgIHZhciBleGlzdGluZyA9IG1lcmdlZFtjdXJyZW50Lm5hbWVdO1xuICAgIG1lcmdlZFtjdXJyZW50Lm5hbWVdID0gZXhpc3RpbmcgPyBPYmplY3QuYXNzaWduKHt9LCBleGlzdGluZywgY3VycmVudCwge1xuICAgICAgb3B0aW9uczogT2JqZWN0LmFzc2lnbih7fSwgZXhpc3Rpbmcub3B0aW9ucywgY3VycmVudC5vcHRpb25zKSxcbiAgICAgIGRhdGE6IE9iamVjdC5hc3NpZ24oe30sIGV4aXN0aW5nLmRhdGEsIGN1cnJlbnQuZGF0YSlcbiAgICB9KSA6IGN1cnJlbnQ7XG4gICAgcmV0dXJuIG1lcmdlZDtcbiAgfSwge30pOyAvLyBJRTExIGRvZXMgbm90IHN1cHBvcnQgT2JqZWN0LnZhbHVlc1xuXG4gIHJldHVybiBPYmplY3Qua2V5cyhtZXJnZWQpLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIG1lcmdlZFtrZXldO1xuICB9KTtcbn0iLCAiaW1wb3J0IGdldENvbXBvc2l0ZVJlY3QgZnJvbSBcIi4vZG9tLXV0aWxzL2dldENvbXBvc2l0ZVJlY3QuanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzXCI7XG5pbXBvcnQgbGlzdFNjcm9sbFBhcmVudHMgZnJvbSBcIi4vZG9tLXV0aWxzL2xpc3RTY3JvbGxQYXJlbnRzLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBvcmRlck1vZGlmaWVycyBmcm9tIFwiLi91dGlscy9vcmRlck1vZGlmaWVycy5qc1wiO1xuaW1wb3J0IGRlYm91bmNlIGZyb20gXCIuL3V0aWxzL2RlYm91bmNlLmpzXCI7XG5pbXBvcnQgbWVyZ2VCeU5hbWUgZnJvbSBcIi4vdXRpbHMvbWVyZ2VCeU5hbWUuanNcIjtcbmltcG9ydCBkZXRlY3RPdmVyZmxvdyBmcm9tIFwiLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IHsgaXNFbGVtZW50IH0gZnJvbSBcIi4vZG9tLXV0aWxzL2luc3RhbmNlT2YuanNcIjtcbnZhciBERUZBVUxUX09QVElPTlMgPSB7XG4gIHBsYWNlbWVudDogJ2JvdHRvbScsXG4gIG1vZGlmaWVyczogW10sXG4gIHN0cmF0ZWd5OiAnYWJzb2x1dGUnXG59O1xuXG5mdW5jdGlvbiBhcmVWYWxpZEVsZW1lbnRzKCkge1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuICFhcmdzLnNvbWUoZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gIShlbGVtZW50ICYmIHR5cGVvZiBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCA9PT0gJ2Z1bmN0aW9uJyk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcG9wcGVyR2VuZXJhdG9yKGdlbmVyYXRvck9wdGlvbnMpIHtcbiAgaWYgKGdlbmVyYXRvck9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIGdlbmVyYXRvck9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfZ2VuZXJhdG9yT3B0aW9ucyA9IGdlbmVyYXRvck9wdGlvbnMsXG4gICAgICBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYgPSBfZ2VuZXJhdG9yT3B0aW9ucy5kZWZhdWx0TW9kaWZpZXJzLFxuICAgICAgZGVmYXVsdE1vZGlmaWVycyA9IF9nZW5lcmF0b3JPcHRpb25zJGRlZiA9PT0gdm9pZCAwID8gW10gOiBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYsXG4gICAgICBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYyID0gX2dlbmVyYXRvck9wdGlvbnMuZGVmYXVsdE9wdGlvbnMsXG4gICAgICBkZWZhdWx0T3B0aW9ucyA9IF9nZW5lcmF0b3JPcHRpb25zJGRlZjIgPT09IHZvaWQgMCA/IERFRkFVTFRfT1BUSU9OUyA6IF9nZW5lcmF0b3JPcHRpb25zJGRlZjI7XG4gIHJldHVybiBmdW5jdGlvbiBjcmVhdGVQb3BwZXIocmVmZXJlbmNlLCBwb3BwZXIsIG9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgICBvcHRpb25zID0gZGVmYXVsdE9wdGlvbnM7XG4gICAgfVxuXG4gICAgdmFyIHN0YXRlID0ge1xuICAgICAgcGxhY2VtZW50OiAnYm90dG9tJyxcbiAgICAgIG9yZGVyZWRNb2RpZmllcnM6IFtdLFxuICAgICAgb3B0aW9uczogT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9PUFRJT05TLCBkZWZhdWx0T3B0aW9ucyksXG4gICAgICBtb2RpZmllcnNEYXRhOiB7fSxcbiAgICAgIGVsZW1lbnRzOiB7XG4gICAgICAgIHJlZmVyZW5jZTogcmVmZXJlbmNlLFxuICAgICAgICBwb3BwZXI6IHBvcHBlclxuICAgICAgfSxcbiAgICAgIGF0dHJpYnV0ZXM6IHt9LFxuICAgICAgc3R5bGVzOiB7fVxuICAgIH07XG4gICAgdmFyIGVmZmVjdENsZWFudXBGbnMgPSBbXTtcbiAgICB2YXIgaXNEZXN0cm95ZWQgPSBmYWxzZTtcbiAgICB2YXIgaW5zdGFuY2UgPSB7XG4gICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICBzZXRPcHRpb25zOiBmdW5jdGlvbiBzZXRPcHRpb25zKHNldE9wdGlvbnNBY3Rpb24pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0eXBlb2Ygc2V0T3B0aW9uc0FjdGlvbiA9PT0gJ2Z1bmN0aW9uJyA/IHNldE9wdGlvbnNBY3Rpb24oc3RhdGUub3B0aW9ucykgOiBzZXRPcHRpb25zQWN0aW9uO1xuICAgICAgICBjbGVhbnVwTW9kaWZpZXJFZmZlY3RzKCk7XG4gICAgICAgIHN0YXRlLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0T3B0aW9ucywgc3RhdGUub3B0aW9ucywgb3B0aW9ucyk7XG4gICAgICAgIHN0YXRlLnNjcm9sbFBhcmVudHMgPSB7XG4gICAgICAgICAgcmVmZXJlbmNlOiBpc0VsZW1lbnQocmVmZXJlbmNlKSA/IGxpc3RTY3JvbGxQYXJlbnRzKHJlZmVyZW5jZSkgOiByZWZlcmVuY2UuY29udGV4dEVsZW1lbnQgPyBsaXN0U2Nyb2xsUGFyZW50cyhyZWZlcmVuY2UuY29udGV4dEVsZW1lbnQpIDogW10sXG4gICAgICAgICAgcG9wcGVyOiBsaXN0U2Nyb2xsUGFyZW50cyhwb3BwZXIpXG4gICAgICAgIH07IC8vIE9yZGVycyB0aGUgbW9kaWZpZXJzIGJhc2VkIG9uIHRoZWlyIGRlcGVuZGVuY2llcyBhbmQgYHBoYXNlYFxuICAgICAgICAvLyBwcm9wZXJ0aWVzXG5cbiAgICAgICAgdmFyIG9yZGVyZWRNb2RpZmllcnMgPSBvcmRlck1vZGlmaWVycyhtZXJnZUJ5TmFtZShbXS5jb25jYXQoZGVmYXVsdE1vZGlmaWVycywgc3RhdGUub3B0aW9ucy5tb2RpZmllcnMpKSk7IC8vIFN0cmlwIG91dCBkaXNhYmxlZCBtb2RpZmllcnNcblxuICAgICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzID0gb3JkZXJlZE1vZGlmaWVycy5maWx0ZXIoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICByZXR1cm4gbS5lbmFibGVkO1xuICAgICAgICB9KTtcbiAgICAgICAgcnVuTW9kaWZpZXJFZmZlY3RzKCk7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZS51cGRhdGUoKTtcbiAgICAgIH0sXG4gICAgICAvLyBTeW5jIHVwZGF0ZSBcdTIwMTMgaXQgd2lsbCBhbHdheXMgYmUgZXhlY3V0ZWQsIGV2ZW4gaWYgbm90IG5lY2Vzc2FyeS4gVGhpc1xuICAgICAgLy8gaXMgdXNlZnVsIGZvciBsb3cgZnJlcXVlbmN5IHVwZGF0ZXMgd2hlcmUgc3luYyBiZWhhdmlvciBzaW1wbGlmaWVzIHRoZVxuICAgICAgLy8gbG9naWMuXG4gICAgICAvLyBGb3IgaGlnaCBmcmVxdWVuY3kgdXBkYXRlcyAoZS5nLiBgcmVzaXplYCBhbmQgYHNjcm9sbGAgZXZlbnRzKSwgYWx3YXlzXG4gICAgICAvLyBwcmVmZXIgdGhlIGFzeW5jIFBvcHBlciN1cGRhdGUgbWV0aG9kXG4gICAgICBmb3JjZVVwZGF0ZTogZnVuY3Rpb24gZm9yY2VVcGRhdGUoKSB7XG4gICAgICAgIGlmIChpc0Rlc3Ryb3llZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBfc3RhdGUkZWxlbWVudHMgPSBzdGF0ZS5lbGVtZW50cyxcbiAgICAgICAgICAgIHJlZmVyZW5jZSA9IF9zdGF0ZSRlbGVtZW50cy5yZWZlcmVuY2UsXG4gICAgICAgICAgICBwb3BwZXIgPSBfc3RhdGUkZWxlbWVudHMucG9wcGVyOyAvLyBEb24ndCBwcm9jZWVkIGlmIGByZWZlcmVuY2VgIG9yIGBwb3BwZXJgIGFyZSBub3QgdmFsaWQgZWxlbWVudHNcbiAgICAgICAgLy8gYW55bW9yZVxuXG4gICAgICAgIGlmICghYXJlVmFsaWRFbGVtZW50cyhyZWZlcmVuY2UsIHBvcHBlcikpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gLy8gU3RvcmUgdGhlIHJlZmVyZW5jZSBhbmQgcG9wcGVyIHJlY3RzIHRvIGJlIHJlYWQgYnkgbW9kaWZpZXJzXG5cblxuICAgICAgICBzdGF0ZS5yZWN0cyA9IHtcbiAgICAgICAgICByZWZlcmVuY2U6IGdldENvbXBvc2l0ZVJlY3QocmVmZXJlbmNlLCBnZXRPZmZzZXRQYXJlbnQocG9wcGVyKSwgc3RhdGUub3B0aW9ucy5zdHJhdGVneSA9PT0gJ2ZpeGVkJyksXG4gICAgICAgICAgcG9wcGVyOiBnZXRMYXlvdXRSZWN0KHBvcHBlcilcbiAgICAgICAgfTsgLy8gTW9kaWZpZXJzIGhhdmUgdGhlIGFiaWxpdHkgdG8gcmVzZXQgdGhlIGN1cnJlbnQgdXBkYXRlIGN5Y2xlLiBUaGVcbiAgICAgICAgLy8gbW9zdCBjb21tb24gdXNlIGNhc2UgZm9yIHRoaXMgaXMgdGhlIGBmbGlwYCBtb2RpZmllciBjaGFuZ2luZyB0aGVcbiAgICAgICAgLy8gcGxhY2VtZW50LCB3aGljaCB0aGVuIG5lZWRzIHRvIHJlLXJ1biBhbGwgdGhlIG1vZGlmaWVycywgYmVjYXVzZSB0aGVcbiAgICAgICAgLy8gbG9naWMgd2FzIHByZXZpb3VzbHkgcmFuIGZvciB0aGUgcHJldmlvdXMgcGxhY2VtZW50IGFuZCBpcyB0aGVyZWZvcmVcbiAgICAgICAgLy8gc3RhbGUvaW5jb3JyZWN0XG5cbiAgICAgICAgc3RhdGUucmVzZXQgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUucGxhY2VtZW50ID0gc3RhdGUub3B0aW9ucy5wbGFjZW1lbnQ7IC8vIE9uIGVhY2ggdXBkYXRlIGN5Y2xlLCB0aGUgYG1vZGlmaWVyc0RhdGFgIHByb3BlcnR5IGZvciBlYWNoIG1vZGlmaWVyXG4gICAgICAgIC8vIGlzIGZpbGxlZCB3aXRoIHRoZSBpbml0aWFsIGRhdGEgc3BlY2lmaWVkIGJ5IHRoZSBtb2RpZmllci4gVGhpcyBtZWFuc1xuICAgICAgICAvLyBpdCBkb2Vzbid0IHBlcnNpc3QgYW5kIGlzIGZyZXNoIG9uIGVhY2ggdXBkYXRlLlxuICAgICAgICAvLyBUbyBlbnN1cmUgcGVyc2lzdGVudCBkYXRhLCB1c2UgYCR7bmFtZX0jcGVyc2lzdGVudGBcblxuICAgICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzLmZvckVhY2goZnVuY3Rpb24gKG1vZGlmaWVyKSB7XG4gICAgICAgICAgcmV0dXJuIHN0YXRlLm1vZGlmaWVyc0RhdGFbbW9kaWZpZXIubmFtZV0gPSBPYmplY3QuYXNzaWduKHt9LCBtb2RpZmllci5kYXRhKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHN0YXRlLm9yZGVyZWRNb2RpZmllcnMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgaWYgKHN0YXRlLnJlc2V0ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBzdGF0ZS5yZXNldCA9IGZhbHNlO1xuICAgICAgICAgICAgaW5kZXggPSAtMTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfc3RhdGUkb3JkZXJlZE1vZGlmaWUgPSBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzW2luZGV4XSxcbiAgICAgICAgICAgICAgZm4gPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUuZm4sXG4gICAgICAgICAgICAgIF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUub3B0aW9ucyxcbiAgICAgICAgICAgICAgX29wdGlvbnMgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUyID09PSB2b2lkIDAgPyB7fSA6IF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIsXG4gICAgICAgICAgICAgIG5hbWUgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUubmFtZTtcblxuICAgICAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHN0YXRlID0gZm4oe1xuICAgICAgICAgICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICAgICAgICAgIG9wdGlvbnM6IF9vcHRpb25zLFxuICAgICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgICBpbnN0YW5jZTogaW5zdGFuY2VcbiAgICAgICAgICAgIH0pIHx8IHN0YXRlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIEFzeW5jIGFuZCBvcHRpbWlzdGljYWxseSBvcHRpbWl6ZWQgdXBkYXRlIFx1MjAxMyBpdCB3aWxsIG5vdCBiZSBleGVjdXRlZCBpZlxuICAgICAgLy8gbm90IG5lY2Vzc2FyeSAoZGVib3VuY2VkIHRvIHJ1biBhdCBtb3N0IG9uY2UtcGVyLXRpY2spXG4gICAgICB1cGRhdGU6IGRlYm91bmNlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgaW5zdGFuY2UuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgICByZXNvbHZlKHN0YXRlKTtcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICAgIGNsZWFudXBNb2RpZmllckVmZmVjdHMoKTtcbiAgICAgICAgaXNEZXN0cm95ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoIWFyZVZhbGlkRWxlbWVudHMocmVmZXJlbmNlLCBwb3BwZXIpKSB7XG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgaW5zdGFuY2Uuc2V0T3B0aW9ucyhvcHRpb25zKS50aGVuKGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgICAgaWYgKCFpc0Rlc3Ryb3llZCAmJiBvcHRpb25zLm9uRmlyc3RVcGRhdGUpIHtcbiAgICAgICAgb3B0aW9ucy5vbkZpcnN0VXBkYXRlKHN0YXRlKTtcbiAgICAgIH1cbiAgICB9KTsgLy8gTW9kaWZpZXJzIGhhdmUgdGhlIGFiaWxpdHkgdG8gZXhlY3V0ZSBhcmJpdHJhcnkgY29kZSBiZWZvcmUgdGhlIGZpcnN0XG4gICAgLy8gdXBkYXRlIGN5Y2xlIHJ1bnMuIFRoZXkgd2lsbCBiZSBleGVjdXRlZCBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgdXBkYXRlXG4gICAgLy8gY3ljbGUuIFRoaXMgaXMgdXNlZnVsIHdoZW4gYSBtb2RpZmllciBhZGRzIHNvbWUgcGVyc2lzdGVudCBkYXRhIHRoYXRcbiAgICAvLyBvdGhlciBtb2RpZmllcnMgbmVlZCB0byB1c2UsIGJ1dCB0aGUgbW9kaWZpZXIgaXMgcnVuIGFmdGVyIHRoZSBkZXBlbmRlbnRcbiAgICAvLyBvbmUuXG5cbiAgICBmdW5jdGlvbiBydW5Nb2RpZmllckVmZmVjdHMoKSB7XG4gICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzLmZvckVhY2goZnVuY3Rpb24gKF9yZWYpIHtcbiAgICAgICAgdmFyIG5hbWUgPSBfcmVmLm5hbWUsXG4gICAgICAgICAgICBfcmVmJG9wdGlvbnMgPSBfcmVmLm9wdGlvbnMsXG4gICAgICAgICAgICBvcHRpb25zID0gX3JlZiRvcHRpb25zID09PSB2b2lkIDAgPyB7fSA6IF9yZWYkb3B0aW9ucyxcbiAgICAgICAgICAgIGVmZmVjdCA9IF9yZWYuZWZmZWN0O1xuXG4gICAgICAgIGlmICh0eXBlb2YgZWZmZWN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdmFyIGNsZWFudXBGbiA9IGVmZmVjdCh7XG4gICAgICAgICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgaW5zdGFuY2U6IGluc3RhbmNlLFxuICAgICAgICAgICAgb3B0aW9uczogb3B0aW9uc1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdmFyIG5vb3BGbiA9IGZ1bmN0aW9uIG5vb3BGbigpIHt9O1xuXG4gICAgICAgICAgZWZmZWN0Q2xlYW51cEZucy5wdXNoKGNsZWFudXBGbiB8fCBub29wRm4pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwTW9kaWZpZXJFZmZlY3RzKCkge1xuICAgICAgZWZmZWN0Q2xlYW51cEZucy5mb3JFYWNoKGZ1bmN0aW9uIChmbikge1xuICAgICAgICByZXR1cm4gZm4oKTtcbiAgICAgIH0pO1xuICAgICAgZWZmZWN0Q2xlYW51cEZucyA9IFtdO1xuICAgIH1cblxuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfTtcbn1cbmV4cG9ydCB2YXIgY3JlYXRlUG9wcGVyID0gLyojX19QVVJFX18qL3BvcHBlckdlbmVyYXRvcigpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbmV4cG9ydCB7IGRldGVjdE92ZXJmbG93IH07IiwgImltcG9ydCB7IHBvcHBlckdlbmVyYXRvciwgZGV0ZWN0T3ZlcmZsb3cgfSBmcm9tIFwiLi9jcmVhdGVQb3BwZXIuanNcIjtcbmltcG9ydCBldmVudExpc3RlbmVycyBmcm9tIFwiLi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanNcIjtcbmltcG9ydCBwb3BwZXJPZmZzZXRzIGZyb20gXCIuL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzXCI7XG5pbXBvcnQgY29tcHV0ZVN0eWxlcyBmcm9tIFwiLi9tb2RpZmllcnMvY29tcHV0ZVN0eWxlcy5qc1wiO1xuaW1wb3J0IGFwcGx5U3R5bGVzIGZyb20gXCIuL21vZGlmaWVycy9hcHBseVN0eWxlcy5qc1wiO1xuaW1wb3J0IG9mZnNldCBmcm9tIFwiLi9tb2RpZmllcnMvb2Zmc2V0LmpzXCI7XG5pbXBvcnQgZmxpcCBmcm9tIFwiLi9tb2RpZmllcnMvZmxpcC5qc1wiO1xuaW1wb3J0IHByZXZlbnRPdmVyZmxvdyBmcm9tIFwiLi9tb2RpZmllcnMvcHJldmVudE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgYXJyb3cgZnJvbSBcIi4vbW9kaWZpZXJzL2Fycm93LmpzXCI7XG5pbXBvcnQgaGlkZSBmcm9tIFwiLi9tb2RpZmllcnMvaGlkZS5qc1wiO1xudmFyIGRlZmF1bHRNb2RpZmllcnMgPSBbZXZlbnRMaXN0ZW5lcnMsIHBvcHBlck9mZnNldHMsIGNvbXB1dGVTdHlsZXMsIGFwcGx5U3R5bGVzLCBvZmZzZXQsIGZsaXAsIHByZXZlbnRPdmVyZmxvdywgYXJyb3csIGhpZGVdO1xudmFyIGNyZWF0ZVBvcHBlciA9IC8qI19fUFVSRV9fKi9wb3BwZXJHZW5lcmF0b3Ioe1xuICBkZWZhdWx0TW9kaWZpZXJzOiBkZWZhdWx0TW9kaWZpZXJzXG59KTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgeyBjcmVhdGVQb3BwZXIsIHBvcHBlckdlbmVyYXRvciwgZGVmYXVsdE1vZGlmaWVycywgZGV0ZWN0T3ZlcmZsb3cgfTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgeyBjcmVhdGVQb3BwZXIgYXMgY3JlYXRlUG9wcGVyTGl0ZSB9IGZyb20gXCIuL3BvcHBlci1saXRlLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0ICogZnJvbSBcIi4vbW9kaWZpZXJzL2luZGV4LmpzXCI7IiwgIi8vIFRoYW5rcyB0byBAbWdtZXllcnMgZm9yIHRoZSBjcmVhdGluZyB0aGUgb2JzaWRpYW4ga2FuYmFuIHBsdWdpbiBodHRwczovL2dpdGh1Yi5jb20vbWdtZXllcnMvb2JzaWRpYW4ta2FuYmFuXHJcbi8vIGZyb20gd2hlcmUgSSBnb3QgdGhlIHRlbXBsYXRlIGNvZGUgZm9yIHRoaXMgcGx1Z2luXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tZ21leWVycy9vYnNpZGlhbi1rYW5iYW4vYmxvYi80OGU2YzI3OGNlOTE0MGI3ZTAzNGIxODE0MzIzMjFmNjk3ZDZlNDVlL3NyYy9jb21wb25lbnRzL2hlbHBlcnMudHNcclxuXHJcbmltcG9ydCB7IFRGaWxlLCBBcHAgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuL21haW4nO1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXBwbHlUZW1wbGF0ZShcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLFxyXG5cdGZpbGU6IFRGaWxlLFxyXG5cdHRlbXBsYXRlUGF0aD86IHN0cmluZ1xyXG4pIHtcclxuXHRjb25zdCB0ZW1wbGF0ZUZpbGUgPSB0ZW1wbGF0ZVBhdGhcclxuXHRcdD8gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgodGVtcGxhdGVQYXRoKVxyXG5cdFx0OiBudWxsO1xyXG5cclxuXHRpZiAodGVtcGxhdGVGaWxlICYmIHRlbXBsYXRlRmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHR0cnkge1xyXG5cclxuXHRcdFx0Y29uc3Qge1xyXG5cdFx0XHRcdHRlbXBsYXRlc0VuYWJsZWQsXHJcblx0XHRcdFx0dGVtcGxhdGVyRW5hYmxlZCxcclxuXHRcdFx0XHR0ZW1wbGF0ZXNQbHVnaW4sXHJcblx0XHRcdFx0dGVtcGxhdGVyUGx1Z2luLFxyXG5cdFx0XHR9ID0gZ2V0VGVtcGxhdGVQbHVnaW5zKHBsdWdpbi5hcHApO1xyXG5cdFx0XHRjb25zdCB0ZW1wbGF0ZUNvbnRlbnQgPSBhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlYWQodGVtcGxhdGVGaWxlKTtcclxuXHJcblx0XHRcdC8vIElmIGJvdGggcGx1Z2lucyBhcmUgZW5hYmxlZCwgYXR0ZW1wdCB0byBkZXRlY3QgdGVtcGxhdGVyIGZpcnN0XHJcblxyXG5cdFx0XHRpZiAodGVtcGxhdGVzRW5hYmxlZCAmJiB0ZW1wbGF0ZXJFbmFibGVkKSB7XHJcblx0XHRcdFx0aWYgKC88JS8udGVzdCh0ZW1wbGF0ZUNvbnRlbnQpKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gYXdhaXQgdGVtcGxhdGVyUGx1Z2luLndyaXRlX3RlbXBsYXRlX3RvX2ZpbGUoXHJcblx0XHRcdFx0XHRcdHRlbXBsYXRlRmlsZSxcclxuXHRcdFx0XHRcdFx0ZmlsZVxyXG5cdFx0XHRcdFx0KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIGF3YWl0IHRlbXBsYXRlc1BsdWdpbi5pbnN0YW5jZS5pbnNlcnRUZW1wbGF0ZSh0ZW1wbGF0ZUZpbGUpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAodGVtcGxhdGVzRW5hYmxlZCkge1xyXG5cdFx0XHRcdHJldHVybiBhd2FpdCB0ZW1wbGF0ZXNQbHVnaW4uaW5zdGFuY2UuaW5zZXJ0VGVtcGxhdGUodGVtcGxhdGVGaWxlKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKHRlbXBsYXRlckVuYWJsZWQpIHtcclxuXHRcdFx0XHRyZXR1cm4gYXdhaXQgdGVtcGxhdGVyUGx1Z2luLndyaXRlX3RlbXBsYXRlX3RvX2ZpbGUoXHJcblx0XHRcdFx0XHR0ZW1wbGF0ZUZpbGUsXHJcblx0XHRcdFx0XHRmaWxlXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdH0gY2F0Y2ggKGUpIHtcclxuXHRcdFx0Y29uc29sZS5lcnJvcihlKTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRUZW1wbGF0ZVBsdWdpbnMoYXBwOiBBcHApIHtcclxuXHRjb25zdCB0ZW1wbGF0ZXNQbHVnaW4gPSAoYXBwIGFzIGFueSkuaW50ZXJuYWxQbHVnaW5zLnBsdWdpbnMudGVtcGxhdGVzO1xyXG5cdGNvbnN0IHRlbXBsYXRlc0VuYWJsZWQgPSB0ZW1wbGF0ZXNQbHVnaW4uZW5hYmxlZDtcclxuXHRjb25zdCB0ZW1wbGF0ZXJQbHVnaW4gPSAoYXBwIGFzIGFueSkucGx1Z2lucy5wbHVnaW5zWyd0ZW1wbGF0ZXItb2JzaWRpYW4nXTtcclxuXHRjb25zdCB0ZW1wbGF0ZXJFbmFibGVkID0gKGFwcCBhcyBhbnkpLnBsdWdpbnMuZW5hYmxlZFBsdWdpbnMuaGFzKFxyXG5cdFx0J3RlbXBsYXRlci1vYnNpZGlhbidcclxuXHQpO1xyXG5cdGNvbnN0IHRlbXBsYXRlckVtcHR5RmlsZVRlbXBsYXRlID1cclxuXHRcdHRlbXBsYXRlclBsdWdpbiAmJlxyXG5cdFx0KHRoaXMuYXBwIGFzIGFueSkucGx1Z2lucy5wbHVnaW5zWyd0ZW1wbGF0ZXItb2JzaWRpYW4nXS5zZXR0aW5nc1xyXG5cdFx0XHQ/LmVtcHR5X2ZpbGVfdGVtcGxhdGU7XHJcblxyXG5cdGNvbnN0IHRlbXBsYXRlRm9sZGVyID0gdGVtcGxhdGVzRW5hYmxlZFxyXG5cdFx0PyB0ZW1wbGF0ZXNQbHVnaW4uaW5zdGFuY2Uub3B0aW9ucy5mb2xkZXJcclxuXHRcdDogdGVtcGxhdGVyUGx1Z2luXHJcblx0XHRcdD8gdGVtcGxhdGVyUGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlX2ZvbGRlclxyXG5cdFx0XHQ6IHVuZGVmaW5lZDtcclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdHRlbXBsYXRlc1BsdWdpbixcclxuXHRcdHRlbXBsYXRlc0VuYWJsZWQsXHJcblx0XHR0ZW1wbGF0ZXJQbHVnaW46IHRlbXBsYXRlclBsdWdpbj8udGVtcGxhdGVyLFxyXG5cdFx0dGVtcGxhdGVyRW5hYmxlZCxcclxuXHRcdHRlbXBsYXRlckVtcHR5RmlsZVRlbXBsYXRlLFxyXG5cdFx0dGVtcGxhdGVGb2xkZXIsXHJcblx0fTtcclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZywgVEZpbGUsIFBsYXRmb3JtLCBURm9sZGVyLCBUQWJzdHJhY3RGaWxlIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCB7IHR1cm5JbnRvRm9sZGVyTm90ZSB9IGZyb20gJ3NyYy9mdW5jdGlvbnMvZm9sZGVyTm90ZUZ1bmN0aW9ucyc7XHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV4aXN0aW5nRm9sZGVyTm90ZU1vZGFsIGV4dGVuZHMgTW9kYWwge1xyXG5cdHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW47XHJcblx0YXBwOiBBcHA7XHJcblx0ZmlsZTogVEZpbGU7XHJcblx0Zm9sZGVyOiBURm9sZGVyO1xyXG5cdGZvbGRlck5vdGU6IFRBYnN0cmFjdEZpbGU7XHJcblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIGZpbGU6IFRGaWxlLCBmb2xkZXI6IFRGb2xkZXIsIGZvbGRlck5vdGU6IFRBYnN0cmFjdEZpbGUpIHtcclxuXHRcdHN1cGVyKGFwcCk7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gYXBwO1xyXG5cdFx0dGhpcy5maWxlID0gZmlsZTtcclxuXHRcdHRoaXMuZm9sZGVyID0gZm9sZGVyO1xyXG5cdFx0dGhpcy5mb2xkZXJOb3RlID0gZm9sZGVyTm90ZTtcclxuXHR9XHJcblx0b25PcGVuKCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnQSBmb2xkZXIgbm90ZSBmb3IgdGhpcyBmb2xkZXIgYWxyZWFkeSBleGlzdHMnIH0pO1xyXG5cdFx0Y29uc3Qgc2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRlbnRFbCk7XHJcblx0XHRzZXR0aW5nLmluZm9FbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byB0dXJuIHRoZSBub3RlIGludG8gYSBmb2xkZXIgbm90ZSBhbmQgcmVuYW1lIHRoZSBleGlzdGluZyBmb2xkZXIgbm90ZT8nIH0pO1xyXG5cclxuXHRcdHNldHRpbmcuaW5mb0VsLnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5hZGQoJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwnKTtcclxuXHJcblx0XHQvLyBDcmVhdGUgYSBjb250YWluZXIgZm9yIHRoZSBidXR0b25zIGFuZCB0aGUgY2hlY2tib3hcclxuXHRcdGNvbnN0IGJ1dHRvbkNvbnRhaW5lciA9IHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdkaXYnLCB7IGNsczogJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9ucycgfSk7XHJcblx0XHRpZiAoUGxhdGZvcm0uaXNNb2JpbGVBcHApIHtcclxuXHRcdFx0Y29uc3QgY29uZmlybUJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnUmVuYW1lIGFuZCBkb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNvbmZpcm1CdXR0b24uY2xhc3NMaXN0LmFkZCgnbW9kLXdhcm5pbmcnLCAnZm4tY29uZmlybWF0aW9uLW1vZGFsLWJ1dHRvbicpO1xyXG5cdFx0XHRjb25maXJtQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dSZW5hbWVDb25maXJtYXRpb24gPSBmYWxzZTtcclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdFx0dHVybkludG9Gb2xkZXJOb3RlKHRoaXMucGx1Z2luLCB0aGlzLmZpbGUsIHRoaXMuZm9sZGVyLCB0aGlzLmZvbGRlck5vdGUsIHRydWUpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGNvbnN0IGNoZWNrYm94ID0gYnV0dG9uQ29udGFpbmVyLmNyZWF0ZUVsKCdpbnB1dCcsIHsgdHlwZTogJ2NoZWNrYm94JyB9KTtcclxuXHRcdFx0Y2hlY2tib3guYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGUpID0+IHtcclxuXHRcdFx0XHRjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG5cdFx0XHRcdGlmICh0YXJnZXQuY2hlY2tlZCkge1xyXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd1JlbmFtZUNvbmZpcm1hdGlvbiA9IGZhbHNlO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93UmVuYW1lQ29uZmlybWF0aW9uID0gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRjb25zdCBjaGVja0JveFRleHQgPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ3NwYW4nLCB7IHRleHQ6ICdEb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNoZWNrQm94VGV4dC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcclxuXHRcdFx0XHRjaGVja2JveC5jbGljaygpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnUmVuYW1lJyB9KTtcclxuXHRcdGJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdtb2Qtd2FybmluZycsICdmbi1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9uJyk7XHJcblx0XHRidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XHJcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdHR1cm5JbnRvRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgdGhpcy5maWxlLCB0aGlzLmZvbGRlciwgdGhpcy5mb2xkZXJOb3RlLCB0cnVlKTtcclxuXHRcdH0pO1xyXG5cdFx0YnV0dG9uLmZvY3VzKCk7XHJcblx0XHRjb25zdCBjYW5jZWxCdXR0b24gPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ2J1dHRvbicsIHsgdGV4dDogJ0NhbmNlbCcgfSk7XHJcblx0XHRjYW5jZWxCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XHJcblx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdH0pO1xyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCBFeGlzdGluZ0ZvbGRlck5vdGVNb2RhbCBmcm9tICcuLi9tb2RhbHMvZXhpc3RpbmdOb3RlJztcclxuaW1wb3J0IHsgYXBwbHlUZW1wbGF0ZSB9IGZyb20gJy4uL3RlbXBsYXRlJztcclxuaW1wb3J0IHsgVEZvbGRlciwgVEZpbGUsIFRBYnN0cmFjdEZpbGUsIEtleW1hcCB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IERlbGV0ZUNvbmZpcm1hdGlvbk1vZGFsIGZyb20gJy4uL21vZGFscy9kZWxldGVDb25maXJtYXRpb24nO1xyXG5pbXBvcnQgeyBhZGRFeGNsdWRlZEZvbGRlciwgZGVsZXRlRXhjbHVkZWRGb2xkZXIsIGdldEV4Y2x1ZGVkRm9sZGVyLCBFeGNsdWRlZEZvbGRlciwgdXBkYXRlRXhjbHVkZWRGb2xkZXIgfSBmcm9tICcuLi9leGNsdWRlZEZvbGRlcic7XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlRm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmb2xkZXJQYXRoOiBzdHJpbmcsIG9wZW5GaWxlOiBib29sZWFuLCB1c2VNb2RhbD86IGJvb2xlYW4sIGV4aXN0aW5nTm90ZT86IFRGaWxlKSB7XHJcblx0Y29uc3QgbGVhZiA9IHBsdWdpbi5hcHAud29ya3NwYWNlLmdldExlYWYoZmFsc2UpO1xyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBwbHVnaW4uZ2V0Rm9sZGVyTmFtZUZyb21QYXRoU3RyaW5nKGZvbGRlclBhdGgpO1xyXG5cdGNvbnN0IGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZvbGRlck5hbWUpO1xyXG5cdGxldCBwYXRoID0gJyc7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRjb25zdCBwYXJlbnRGb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZvbGRlclBhdGgpO1xyXG5cdFx0aWYgKHBhcmVudEZvbGRlclBhdGgudHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRwYXRoID0gYCR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHBhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke2ZpbGVOYW1lfSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIGlmIChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAndmF1bHRGb2xkZXInKSB7XHJcblx0XHRwYXRoID0gYCR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0cGF0aCA9IGAke2ZvbGRlclBhdGh9LyR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHR9XHJcblx0bGV0IGZpbGU6IFRGaWxlO1xyXG5cdGlmICghZXhpc3RpbmdOb3RlKSB7XHJcblx0XHRmaWxlID0gYXdhaXQgcGx1Z2luLmFwcC52YXVsdC5jcmVhdGUocGF0aCwgJycpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRmaWxlID0gZXhpc3RpbmdOb3RlO1xyXG5cdFx0cGx1Z2luLmFwcC52YXVsdC5yZW5hbWUoZXhpc3RpbmdOb3RlLCBwYXRoKTtcclxuXHR9XHJcblx0aWYgKG9wZW5GaWxlKSB7XHJcblx0XHRhd2FpdCBsZWFmLm9wZW5GaWxlKGZpbGUpO1xyXG5cdH1cclxuXHRpZiAoZmlsZSAmJiAhZXhpc3RpbmdOb3RlKSB7XHJcblx0XHRhcHBseVRlbXBsYXRlKHRoaXMsIGZpbGUsIHBsdWdpbi5zZXR0aW5ncy50ZW1wbGF0ZVBhdGgpO1xyXG5cdH1cclxuXHJcblx0Y29uc3QgZm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aCwgJ2lzLWZvbGRlci1ub3RlJywgdHJ1ZSk7XHJcblx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0dXJuSW50b0ZvbGRlck5vdGUocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZmlsZTogVEZpbGUsIGZvbGRlcjogVEZvbGRlciwgZm9sZGVyTm90ZT86IFRGaWxlIHwgbnVsbCB8IFRBYnN0cmFjdEZpbGUsIHNraXBDb25maXJtYXRpb24/OiBib29sZWFuKSB7XHJcblx0aWYgKGZvbGRlck5vdGUpIHtcclxuXHRcdGlmIChwbHVnaW4uc2V0dGluZ3Muc2hvd1JlbmFtZUNvbmZpcm1hdGlvbiAmJiAhc2tpcENvbmZpcm1hdGlvbikge1xyXG5cdFx0XHRyZXR1cm4gbmV3IEV4aXN0aW5nRm9sZGVyTm90ZU1vZGFsKHBsdWdpbi5hcHAsIHBsdWdpbiwgZmlsZSwgZm9sZGVyLCBmb2xkZXJOb3RlKS5vcGVuKCk7XHJcblx0XHR9XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdGxldCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZm9sZGVyLnBhdGgpO1xyXG5cdFx0bGV0IGV4Y2x1ZGVkRm9sZGVyRXhpc3RlZCA9IHRydWU7XHJcblx0XHRsZXQgZGlzYWJsZWRTeW5jID0gZmFsc2U7XHJcblxyXG5cdFx0aWYgKCFleGNsdWRlZEZvbGRlcikge1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlckV4aXN0ZWQgPSBmYWxzZTtcclxuXHRcdFx0ZXhjbHVkZWRGb2xkZXIgPSBuZXcgRXhjbHVkZWRGb2xkZXIoZm9sZGVyLnBhdGgsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0gZWxzZSBpZiAoIWV4Y2x1ZGVkRm9sZGVyLmRpc2FibGVTeW5jKSB7XHJcblx0XHRcdGRpc2FibGVkU3luYyA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHRydWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IG5ld1BhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmb2xkZXIubmFtZX0gKCR7ZmlsZS5zdGF0LmN0aW1lLnRvU3RyaW5nKCkuc2xpY2UoMTApICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMCl9KSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHRwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmb2xkZXJOb3RlLCBuZXdQYXRoKS50aGVuKCgpID0+IHtcclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlckV4aXN0ZWQpIHtcclxuXHRcdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIGlmICghZGlzYWJsZWRTeW5jKSB7XHJcblx0XHRcdFx0ZXhjbHVkZWRGb2xkZXIuZGlzYWJsZVN5bmMgPSBmYWxzZTtcclxuXHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXJOYW1lID0gZm9sZGVyLm5hbWU7XHJcblx0Y29uc3QgZmlsZU5hbWUgPSBwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUucmVwbGFjZSgne3tmb2xkZXJfbmFtZX19JywgZm9sZGVyTmFtZSk7XHJcblx0bGV0IHBhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmaWxlTmFtZX0ke3BsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZX1gO1xyXG5cdGlmIChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAncGFyZW50Rm9sZGVyJykge1xyXG5cdFx0Y29uc3QgcGFyZW50Rm9sZGVyUGF0aCA9IGZvbGRlci5wYXJlbnQ/LnBhdGg7XHJcblx0XHRpZiAoIXBhcmVudEZvbGRlclBhdGgpIHJldHVybjtcclxuXHRcdGlmIChwYXJlbnRGb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0cGF0aCA9IGAke2ZpbGVOYW1lfSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRwYXRoID0gYCR7cGFyZW50Rm9sZGVyUGF0aH0vJHtmaWxlTmFtZX0ke3BsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZX1gO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBwYXRoKTtcclxuXHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aCwgJ2lzLWZvbGRlci1ub3RlJywgdHJ1ZSk7XHJcblx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuRm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBUQWJzdHJhY3RGaWxlLCBldnQ/OiBNb3VzZUV2ZW50KSB7XHJcblx0Y29uc3QgcGF0aCA9IGZpbGUucGF0aDtcclxuXHRpZiAocGx1Z2luLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpPy5wYXRoID09PSBwYXRoKSB7IHJldHVybjsgfVxyXG5cdGNvbnN0IGxlYWYgPSBwbHVnaW4uYXBwLndvcmtzcGFjZS5nZXRMZWFmKEtleW1hcC5pc01vZEV2ZW50KGV2dCkgfHwgcGx1Z2luLnNldHRpbmdzLm9wZW5Jbk5ld1RhYik7XHJcblx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0YXdhaXQgbGVhZi5vcGVuRmlsZShmaWxlKTtcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWxldGVGb2xkZXJOb3RlKHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIGZpbGU6IFRGaWxlKSB7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zaG93RGVsZXRlQ29uZmlybWF0aW9uKSB7XHJcblx0XHRyZXR1cm4gbmV3IERlbGV0ZUNvbmZpcm1hdGlvbk1vZGFsKHBsdWdpbi5hcHAsIHBsdWdpbiwgZmlsZSkub3BlbigpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIocGx1Z2luLCBmaWxlKTtcclxuXHRpZiAoIWZvbGRlcikgcmV0dXJuO1xyXG5cdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChmb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdGF3YWl0IHBsdWdpbi5hcHAudmF1bHQuZGVsZXRlKGZpbGUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEZvbGRlck5hbWUodGVtcGxhdGU6IHN0cmluZywgY2hhbmdlZEZpbGVOYW1lOiBzdHJpbmcpIHtcclxuXHRjb25zdCBbcHJlZml4LCBzdWZmaXhdID0gdGVtcGxhdGUuc3BsaXQoJ3t7Zm9sZGVyX25hbWV9fScpO1xyXG5cdGlmIChwcmVmaXgudHJpbSgpID09PSAnJyAmJiBzdWZmaXgudHJpbSgpID09PSAnJykge1xyXG5cdFx0cmV0dXJuIGNoYW5nZWRGaWxlTmFtZTtcclxuXHR9XHJcblx0aWYgKCFjaGFuZ2VkRmlsZU5hbWUuc3RhcnRzV2l0aChwcmVmaXgpIHx8ICFjaGFuZ2VkRmlsZU5hbWUuZW5kc1dpdGgoc3VmZml4KSkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cdGlmIChjaGFuZ2VkRmlsZU5hbWUuc3RhcnRzV2l0aChwcmVmaXgpICYmIHByZWZpeC50cmltKCkgIT09ICcnKSB7XHJcblx0XHRyZXR1cm4gY2hhbmdlZEZpbGVOYW1lLnNsaWNlKHByZWZpeC5sZW5ndGgpLnJlcGxhY2Uoc3VmZml4LCAnJyk7XHJcblx0fSBlbHNlIGlmIChjaGFuZ2VkRmlsZU5hbWUuZW5kc1dpdGgoc3VmZml4KSAmJiBzdWZmaXgudHJpbSgpICE9PSAnJykge1xyXG5cdFx0cmV0dXJuIGNoYW5nZWRGaWxlTmFtZS5zbGljZSgwLCAtc3VmZml4Lmxlbmd0aCk7XHJcblx0fVxyXG5cdHJldHVybiBudWxsO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmb2xkZXJQYXRoOiBzdHJpbmcsIHN0b3JhZ2VMb2NhdGlvbj86IHN0cmluZywgZmlsZT86IFRGaWxlKSB7XHJcblx0aWYgKCFmb2xkZXJQYXRoKSByZXR1cm4gbnVsbDtcclxuXHRjb25zdCBmb2xkZXIgPSB7XHJcblx0XHRwYXRoOiBmb2xkZXJQYXRoLFxyXG5cdFx0bmFtZTogcGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhmb2xkZXJQYXRoKSxcclxuXHR9O1xyXG5cdGxldCBmaWxlTmFtZSA9IHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZS5yZXBsYWNlKCd7e2ZvbGRlcl9uYW1lfX0nLCBmb2xkZXIubmFtZSk7XHJcblx0aWYgKGZpbGUpIHtcclxuXHRcdGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZpbGUuYmFzZW5hbWUpO1xyXG5cdH1cclxuXHJcblx0aWYgKChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAncGFyZW50Rm9sZGVyJyB8fCBzdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSAmJiBzdG9yYWdlTG9jYXRpb24gIT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRmb2xkZXIucGF0aCA9IHBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmb2xkZXJQYXRoKTtcclxuXHR9XHJcblx0bGV0IHBhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmaWxlTmFtZX1gO1xyXG5cdGlmIChmb2xkZXIucGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRmb2xkZXIucGF0aCA9IGZpbGVOYW1lO1xyXG5cdFx0cGF0aCA9IGAke2ZpbGVOYW1lfWA7XHJcblx0fVxyXG5cdGxldCBmb2xkZXJOb3RlID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGF0aCArIHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZSk7XHJcblx0aWYgKGZvbGRlck5vdGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0cmV0dXJuIGZvbGRlck5vdGU7XHJcblx0fSBlbHNlIHtcclxuXHRcdGlmIChwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGUgPT09ICcuY2FudmFzJykge1xyXG5cdFx0XHRmb2xkZXJOb3RlID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGF0aCArICcubWQnKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvbGRlck5vdGUgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChwYXRoICsgJy5jYW52YXMnKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmb2xkZXJOb3RlO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBURmlsZSwgc3RvcmFnZUxvY2F0aW9uPzogc3RyaW5nKSB7XHJcblx0aWYgKCFmaWxlKSByZXR1cm4gbnVsbDtcclxuXHRjb25zdCBmb2xkZXJOYW1lID0gZXh0cmFjdEZvbGRlck5hbWUocGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBmaWxlLmJhc2VuYW1lKTtcclxuXHRpZiAoIWZvbGRlck5hbWUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCk7XHJcblx0bGV0IGZvbGRlcjogVEZvbGRlciB8IFRBYnN0cmFjdEZpbGUgfCBudWxsID0gbnVsbDtcclxuXHRpZiAoKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInIHx8IHN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpICYmIHN0b3JhZ2VMb2NhdGlvbiAhPT0gJ2luc2lkZUZvbGRlcicpIHtcclxuXHRcdGlmIChmb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0Zm9sZGVyUGF0aCA9IGZvbGRlck5hbWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0vJHtmb2xkZXJOYW1lfWA7XHJcblx0XHR9XHJcblx0XHRmb2xkZXIgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0Zm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0fVxyXG5cdGlmICghZm9sZGVyKSB7IHJldHVybiBudWxsOyB9XHJcblx0cmV0dXJuIGZvbGRlcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlck5vdGVGb2xkZXIocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZm9sZGVyTm90ZTogVEZpbGUgfCBzdHJpbmcsIGZpbGVOYW1lOiBzdHJpbmcpIHtcclxuXHRpZiAoIWZvbGRlck5vdGUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmaWxlUGF0aCA9ICcnO1xyXG5cdGlmICh0eXBlb2YgZm9sZGVyTm90ZSA9PT0gJ3N0cmluZycpIHtcclxuXHRcdGZpbGVQYXRoID0gZm9sZGVyTm90ZTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0ZmlsZU5hbWUgPSBmb2xkZXJOb3RlLmJhc2VuYW1lO1xyXG5cdFx0ZmlsZVBhdGggPSBmb2xkZXJOb3RlLnBhdGg7XHJcblx0fVxyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUsIGZpbGVOYW1lKTtcclxuXHRpZiAoIWZvbGRlck5hbWUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGVQYXRoKTtcclxuXHRpZiAocGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdGlmIChmb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0Zm9sZGVyUGF0aCA9IGZvbGRlck5hbWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0vJHtmb2xkZXJOYW1lfWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIHtcclxuXHRcdGZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZVBhdGgpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXIgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoKTtcclxuXHRpZiAoIWZvbGRlcikgeyByZXR1cm4gbnVsbDsgfVxyXG5cdHJldHVybiBmb2xkZXI7XHJcbn1cclxuIiwgImltcG9ydCB7IEFwcCwgTW9kYWwsIFNldHRpbmcsIFRGaWxlLCBQbGF0Zm9ybSB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBnZXRGb2xkZXIgfSBmcm9tICdzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEZWxldGVDb25maXJtYXRpb25Nb2RhbCBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGZpbGU6IFRGaWxlO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBURmlsZSkge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLmZpbGUgPSBmaWxlO1xyXG5cdH1cclxuXHRvbk9wZW4oKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdEZWxldGUgZm9sZGVyIG5vdGUnIH0pO1xyXG5cdFx0Y29uc3Qgc2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRlbnRFbCk7XHJcblx0XHRzZXR0aW5nLmluZm9FbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogYEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhlIGZvbGRlciBub3RlIFwiJHt0aGlzLmZpbGUubmFtZX1cIiA/YCB9KTtcclxuXHRcdHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdwJywgeyB0ZXh0OiAnSXQgd2lsbCBiZSBtb3ZlZCB0byB5b3VyIHN5c3RlbSB0cmFzaC4nIH0pO1xyXG5cclxuXHRcdHNldHRpbmcuaW5mb0VsLnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5hZGQoJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwnKTtcclxuXHJcblx0XHQvLyBDcmVhdGUgYSBjb250YWluZXIgZm9yIHRoZSBidXR0b25zIGFuZCB0aGUgY2hlY2tib3hcclxuXHRcdGNvbnN0IGJ1dHRvbkNvbnRhaW5lciA9IHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdkaXYnLCB7IGNsczogJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9ucycgfSk7XHJcblx0XHRpZiAoUGxhdGZvcm0uaXNNb2JpbGVBcHApIHtcclxuXHRcdFx0Y29uc3QgY29uZmlybUJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnRGVsZXRlIGFuZCBkb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNvbmZpcm1CdXR0b24uY2xhc3NMaXN0LmFkZCgnbW9kLXdhcm5pbmcnLCAnZm4tY29uZmlybWF0aW9uLW1vZGFsLWJ1dHRvbicpO1xyXG5cdFx0XHRjb25maXJtQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEZWxldGVDb25maXJtYXRpb24gPSBmYWxzZTtcclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdFx0Y29uc3QgZm9sZGVyID0gZ2V0Rm9sZGVyKHRoaXMucGx1Z2luLCB0aGlzLmZpbGUpO1xyXG5cdFx0XHRcdGlmICghZm9sZGVyKSByZXR1cm47XHJcblx0XHRcdFx0dGhpcy5wbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyPy5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0dGhpcy5hcHAudmF1bHQuZGVsZXRlKHRoaXMuZmlsZSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Y29uc3QgY2hlY2tib3ggPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ2lucHV0JywgeyB0eXBlOiAnY2hlY2tib3gnIH0pO1xyXG5cdFx0XHRjaGVja2JveC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZSkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcblx0XHRcdFx0aWYgKHRhcmdldC5jaGVja2VkKSB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93RGVsZXRlQ29uZmlybWF0aW9uID0gZmFsc2U7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEZWxldGVDb25maXJtYXRpb24gPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0fSk7XHJcblx0XHRcdGNvbnN0IGNoZWNrQm94VGV4dCA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnc3BhbicsIHsgdGV4dDogJ0RvblxcJ3QgYXNrIGFnYWluJyB9KTtcclxuXHRcdFx0Y2hlY2tCb3hUZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xyXG5cdFx0XHRcdGNoZWNrYm94LmNsaWNrKCk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgYnV0dG9uID0gYnV0dG9uQ29udGFpbmVyLmNyZWF0ZUVsKCdidXR0b24nLCB7IHRleHQ6ICdEZWxldGUnIH0pO1xyXG5cdFx0YnV0dG9uLmNsYXNzTGlzdC5hZGQoJ21vZC13YXJuaW5nJywgJ2ZuLWNvbmZpcm1hdGlvbi1tb2RhbC1idXR0b24nKTtcclxuXHRcdGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIodGhpcy5wbHVnaW4sIHRoaXMuZmlsZSk7XHJcblx0XHRcdGlmICghZm9sZGVyKSByZXR1cm47XHJcblx0XHRcdHRoaXMucGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHRoaXMuYXBwLnZhdWx0LmRlbGV0ZSh0aGlzLmZpbGUpO1xyXG5cdFx0fSk7XHJcblx0XHRidXR0b24uZm9jdXMoKTtcclxuXHRcdGNvbnN0IGNhbmNlbEJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnQ2FuY2VsJyB9KTtcclxuXHRcdGNhbmNlbEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0fSk7XHJcblxyXG5cdH1cclxuXHRvbkNsb3NlKCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcclxuXHR9XHJcbn1cclxuIiwgImltcG9ydCB7IFNldHRpbmcgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuL21haW4nO1xyXG5pbXBvcnQgRXhjbHVkZWRGb2xkZXJTZXR0aW5ncyBmcm9tICcuL21vZGFscy9leGNsdWRlRm9sZGVyU2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBGb2xkZXJTdWdnZXN0IH0gZnJvbSAnLi9zdWdnZXN0ZXJzL0ZvbGRlclN1Z2dlc3Rlcic7XHJcbmltcG9ydCB7IFNldHRpbmdzVGFiIH0gZnJvbSAnLi9zZXR0aW5ncyc7XHJcbmltcG9ydCBQYXR0ZXJuU2V0dGluZ3MgZnJvbSAnLi9tb2RhbHMvcGF0dGVyblNldHRpbmdzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFeGNsdWRlZEZvbGRlciB7XHJcblx0dHlwZTogc3RyaW5nO1xyXG5cdHBhdGg6IHN0cmluZztcclxuXHRzdHJpbmc6IHN0cmluZztcclxuXHRzdWJGb2xkZXJzOiBib29sZWFuO1xyXG5cdGRpc2FibGVTeW5jOiBib29sZWFuO1xyXG5cdGRpc2FibGVBdXRvQ3JlYXRlOiBib29sZWFuO1xyXG5cdGRpc2FibGVGb2xkZXJOb3RlOiBib29sZWFuO1xyXG5cdGVuYWJsZUNvbGxhcHNpbmc6IGJvb2xlYW47XHJcblx0cG9zaXRpb246IG51bWJlcjtcclxuXHRjb25zdHJ1Y3RvcihwYXRoOiBzdHJpbmcsIHBvc2l0aW9uOiBudW1iZXIpIHtcclxuXHRcdHRoaXMudHlwZSA9ICdmb2xkZXInO1xyXG5cdFx0dGhpcy5wYXRoID0gcGF0aDtcclxuXHRcdHRoaXMuc3ViRm9sZGVycyA9IHRydWU7XHJcblx0XHR0aGlzLmRpc2FibGVTeW5jID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGlzYWJsZUF1dG9DcmVhdGUgPSB0cnVlO1xyXG5cdFx0dGhpcy5kaXNhYmxlRm9sZGVyTm90ZSA9IGZhbHNlO1xyXG5cdFx0dGhpcy5lbmFibGVDb2xsYXBzaW5nID0gZmFsc2U7XHJcblx0XHR0aGlzLnBvc2l0aW9uID0gcG9zaXRpb247XHJcblx0XHR0aGlzLnN0cmluZyA9ICcnO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEV4Y2x1ZGVQYXR0ZXJuIHtcclxuXHR0eXBlOiBzdHJpbmc7XHJcblx0c3RyaW5nOiBzdHJpbmc7XHJcblx0cGF0aDogc3RyaW5nO1xyXG5cdHBvc2l0aW9uOiBudW1iZXI7XHJcblx0c3ViRm9sZGVyczogYm9vbGVhbjtcclxuXHRkaXNhYmxlU3luYzogYm9vbGVhbjtcclxuXHRkaXNhYmxlQXV0b0NyZWF0ZTogYm9vbGVhbjtcclxuXHRkaXNhYmxlRm9sZGVyTm90ZTogYm9vbGVhbjtcclxuXHRlbmFibGVDb2xsYXBzaW5nOiBib29sZWFuO1xyXG5cdGNvbnN0cnVjdG9yKHBhdHRlcm46IHN0cmluZywgcG9zaXRpb246IG51bWJlcikge1xyXG5cdFx0dGhpcy50eXBlID0gJ3BhdHRlcm4nO1xyXG5cdFx0dGhpcy5zdHJpbmcgPSBwYXR0ZXJuO1xyXG5cdFx0dGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xyXG5cdFx0dGhpcy5zdWJGb2xkZXJzID0gZmFsc2U7XHJcblx0XHR0aGlzLmRpc2FibGVTeW5jID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGlzYWJsZUF1dG9DcmVhdGUgPSB0cnVlO1xyXG5cdFx0dGhpcy5kaXNhYmxlRm9sZGVyTm90ZSA9IGZhbHNlO1xyXG5cdFx0dGhpcy5lbmFibGVDb2xsYXBzaW5nID0gZmFsc2U7XHJcblx0XHR0aGlzLnBhdGggPSAnJztcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBwYXRoOiBzdHJpbmcpIHtcclxuXHRjb25zdCBmb2xkZXJOYW1lID0gcGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhwYXRoKTtcclxuXHRjb25zdCBtYXRjaGVkUGF0dGVybiA9IGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXR0ZXJuKHBsdWdpbiwgZm9sZGVyTmFtZSk7XHJcblx0aWYgKG1hdGNoZWRQYXR0ZXJuKSB7IHJldHVybiBtYXRjaGVkUGF0dGVybjsgfVxyXG5cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXRoKHBsdWdpbiwgcGF0aCk7XHJcblx0cmV0dXJuIGV4Y2x1ZGVkRm9sZGVyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXhjbHVkZWRGb2xkZXJCeVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZm9sZGVyTmFtZTogc3RyaW5nKSB7XHJcblx0cmV0dXJuIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maWx0ZXIoKHMpID0+IHMucGF0aCA9PT0gJycpLmZpbmQoKHBhdHRlcm4pID0+IHtcclxuXHRcdGlmICghcGF0dGVybi5zdHJpbmcpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRpZiAocGF0dGVybi5zdHJpbmcudG9Mb2NhbGVMb3dlckNhc2UoKS5zdGFydHNXaXRoKCd7cmVnZXh9JykgJiYgcGF0dGVybi5zdHJpbmcuc2xpY2UoNykudHJpbSgpICE9PSAnJykge1xyXG5cdFx0XHRjb25zdCBtYXRjaCA9IG5ldyBSZWdFeHAocGF0dGVybi5zdHJpbmcuc2xpY2UoNykudHJpbSgpKS5leGVjKGZvbGRlck5hbWUpO1xyXG5cdFx0XHRpZiAobWF0Y2gpIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIGlmIChwYXR0ZXJuLnN0cmluZy5zdGFydHNXaXRoKCcqJykgJiYgcGF0dGVybi5zdHJpbmcuZW5kc1dpdGgoJyonKSkge1xyXG5cdFx0XHRpZiAoZm9sZGVyTmFtZS5pbmNsdWRlcyhwYXR0ZXJuLnN0cmluZy5zbGljZSgxLCAtMSkpKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSBpZiAocGF0dGVybi5zdHJpbmcuc3RhcnRzV2l0aCgnKicpKSB7XHJcblx0XHRcdGlmIChmb2xkZXJOYW1lLmVuZHNXaXRoKHBhdHRlcm4uc3RyaW5nLnNsaWNlKDEpKSkge1xyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHBhdHRlcm4uc3RyaW5nLmVuZHNXaXRoKCcqJykpIHtcclxuXHRcdFx0aWYgKGZvbGRlck5hbWUuc3RhcnRzV2l0aChwYXR0ZXJuLnN0cmluZy5zbGljZSgwLCAtMSkpKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXRoKHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIHBhdGg6IHN0cmluZykge1xyXG5cdHJldHVybiBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZXhjbHVkZWRGb2xkZXIpID0+IHtcclxuXHRcdGlmIChleGNsdWRlZEZvbGRlci5wYXRoID09PSBwYXRoKSB7IHJldHVybiB0cnVlOyB9XHJcblx0XHRpZiAoIWV4Y2x1ZGVkRm9sZGVyLnN1YkZvbGRlcnMpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRyZXR1cm4gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGgpLnN0YXJ0c1dpdGgoZXhjbHVkZWRGb2xkZXIucGF0aCk7XHJcblx0fSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMucHVzaChleGNsdWRlZEZvbGRlcik7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZXhjbHVkZWRGb2xkZXI6IEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIucGF0aCAhPT0gZXhjbHVkZWRGb2xkZXIucGF0aCB8fCBmb2xkZXIudHlwZSA9PT0gJ3BhdHRlcm4nKTtcclxuXHRwbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0cmVzeW5jQXJyYXkocGx1Z2luKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgcGF0dGVybjogRXhjbHVkZVBhdHRlcm4pIHtcclxuXHRwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmlsdGVyKChmb2xkZXIpID0+IGZvbGRlci5zdHJpbmcgIT09IHBhdHRlcm4uc3RyaW5nIHx8IGZvbGRlci50eXBlID09PSAnZm9sZGVyJyk7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdHJlc3luY0FycmF5KHBsdWdpbik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZVBhdHRlcm4sIG5ld0V4Y2x1ZGVGb2xkZXI6IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIucGF0aCAhPT0gZXhjbHVkZWRGb2xkZXIucGF0aCk7XHJcblx0YWRkRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBuZXdFeGNsdWRlRm9sZGVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgcGF0dGVybjogRXhjbHVkZVBhdHRlcm4sIG5ld1BhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIuc3RyaW5nICE9PSBwYXR0ZXJuLnN0cmluZyk7XHJcblx0YWRkRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBuZXdQYXR0ZXJuKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVzeW5jQXJyYXkocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycyA9IHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5zb3J0KChhLCBiKSA9PiBhLnBvc2l0aW9uIC0gYi5wb3NpdGlvbik7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZvckVhY2goKGZvbGRlciwgaW5kZXgpID0+IHtcclxuXHRcdGZvbGRlci5wb3NpdGlvbiA9IGluZGV4O1xyXG5cdH0pO1xyXG5cdHBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGFkZEV4Y2x1ZGVQYXR0ZXJuTGlzdEl0ZW0oc2V0dGluZ3M6IFNldHRpbmdzVGFiLCBjb250YWluZXJFbDogSFRNTEVsZW1lbnQsIHBhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0Y29uc3QgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiA9IHNldHRpbmdzLnBsdWdpbjtcclxuXHRjb25zdCBzZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpO1xyXG5cdHNldHRpbmcuc2V0Q2xhc3MoJ2ZuLWV4Y2x1ZGUtZm9sZGVyLWxpc3QnKTtcclxuXHRzZXR0aW5nLmFkZFNlYXJjaCgoY2IpID0+IHtcclxuXHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKCdmbi1leGNsdWRlLWZvbGRlci1wYXRoJyk7XHJcblx0XHRjYi5zZXRQbGFjZWhvbGRlcignUGF0dGVybicpO1xyXG5cdFx0Y2Iuc2V0VmFsdWUocGF0dGVybi5zdHJpbmcpO1xyXG5cdFx0Y2Iub25DaGFuZ2UoKHZhbHVlKSA9PiB7XHJcblx0XHRcdGlmIChwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIuc3RyaW5nID09PSB2YWx1ZSkpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHBhdHRlcm4uc3RyaW5nID0gdmFsdWU7XHJcblx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBwYXR0ZXJuLCBwYXR0ZXJuKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdHNldHRpbmcuYWRkQnV0dG9uKChjYikgPT4ge1xyXG5cdFx0Y2Iuc2V0SWNvbignZWRpdCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnRWRpdCBwYXR0ZXJuJyk7XHJcblx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0bmV3IFBhdHRlcm5TZXR0aW5ncyhwbHVnaW4uYXBwLCBwbHVnaW4sIHBhdHRlcm4pLm9wZW4oKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3VwLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgdXAnKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRpZiAocGF0dGVybi5wb3NpdGlvbiA9PT0gMCkgeyByZXR1cm47IH1cclxuXHRcdFx0cGF0dGVybi5wb3NpdGlvbiAtPSAxO1xyXG5cdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgcGF0dGVybiwgcGF0dGVybik7XHJcblx0XHRcdGNvbnN0IG9sZFBhdHRlcm4gPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IHBhdHRlcm4ucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkUGF0dGVybikge1xyXG5cdFx0XHRcdG9sZFBhdHRlcm4ucG9zaXRpb24gKz0gMTtcclxuXHRcdFx0XHRpZiAob2xkUGF0dGVybi50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0c2V0dGluZ3MuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblx0c2V0dGluZy5hZGRCdXR0b24oKGNiKSA9PiB7XHJcblx0XHRjYi5zZXRJY29uKCdkb3duLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgZG93bicpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdGlmIChwYXR0ZXJuLnBvc2l0aW9uID09PSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRwYXR0ZXJuLnBvc2l0aW9uICs9IDE7XHJcblxyXG5cdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgcGF0dGVybiwgcGF0dGVybik7XHJcblx0XHRcdGNvbnN0IG9sZFBhdHRlcm4gPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IHBhdHRlcm4ucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkUGF0dGVybikge1xyXG5cdFx0XHRcdG9sZFBhdHRlcm4ucG9zaXRpb24gLT0gMTtcclxuXHRcdFx0XHRpZiAob2xkUGF0dGVybi50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0c2V0dGluZ3MuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblx0c2V0dGluZy5hZGRCdXR0b24oKGNiKSA9PiB7XHJcblx0XHRjYi5zZXRJY29uKCd0cmFzaC0yJyk7XHJcblx0XHRjYi5zZXRUb29sdGlwKCdEZWxldGUgcGF0dGVybicpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdGRlbGV0ZVBhdHRlcm4ocGx1Z2luLCBwYXR0ZXJuKTtcclxuXHRcdFx0c2V0dGluZy5jbGVhcigpO1xyXG5cdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gYWRkRXhjbHVkZUZvbGRlckxpc3RJdGVtKHNldHRpbmdzOiBTZXR0aW5nc1RhYiwgY29udGFpbmVyRWw6IEhUTUxFbGVtZW50LCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRjb25zdCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luID0gc2V0dGluZ3MucGx1Z2luO1xyXG5cdGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCk7XHJcblx0c2V0dGluZy5zZXRDbGFzcygnZm4tZXhjbHVkZS1mb2xkZXItbGlzdCcpO1xyXG5cdHNldHRpbmcuYWRkU2VhcmNoKChjYikgPT4ge1xyXG5cdFx0bmV3IEZvbGRlclN1Z2dlc3QoXHJcblx0XHRcdGNiLmlucHV0RWwsXHJcblx0XHRcdHBsdWdpblxyXG5cdFx0KTtcclxuXHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKCdmbi1leGNsdWRlLWZvbGRlci1wYXRoJyk7XHJcblx0XHRjYi5zZXRQbGFjZWhvbGRlcignRm9sZGVyIHBhdGgnKTtcclxuXHRcdGNiLnNldFZhbHVlKGV4Y2x1ZGVkRm9sZGVyLnBhdGgpO1xyXG5cdFx0Y2Iub25DaGFuZ2UoKHZhbHVlKSA9PiB7XHJcblx0XHRcdGlmICh2YWx1ZS5zdGFydHNXaXRoKCd7cmVnZXh9JykgfHwgdmFsdWUuaW5jbHVkZXMoJyonKSkge1xyXG5cdFx0XHRcdGRlbGV0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdGNvbnN0IHBhdHRlcm4gPSBuZXcgRXhjbHVkZVBhdHRlcm4odmFsdWUsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRcdGFkZEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgcGF0dGVybik7XHJcblx0XHRcdFx0YWRkRXhjbHVkZVBhdHRlcm5MaXN0SXRlbShzZXR0aW5ncywgY29udGFpbmVyRWwsIHBhdHRlcm4pO1xyXG5cdFx0XHRcdHNldHRpbmcuY2xlYXIoKTtcclxuXHRcdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoIXBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHZhbHVlKSkgcmV0dXJuO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gdmFsdWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdHNldHRpbmcuYWRkQnV0dG9uKChjYikgPT4ge1xyXG5cdFx0Y2Iuc2V0SWNvbignZWRpdCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnRWRpdCBmb2xkZXIgbm90ZScpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdG5ldyBFeGNsdWRlZEZvbGRlclNldHRpbmdzKHBsdWdpbi5hcHAsIHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpLm9wZW4oKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3VwLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgdXAnKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRpZiAoZXhjbHVkZWRGb2xkZXIucG9zaXRpb24gPT09IDApIHsgcmV0dXJuOyB9XHJcblx0XHRcdGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uIC09IDE7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0Y29uc3Qgb2xkRXhjbHVkZWRGb2xkZXIgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uKTtcclxuXHRcdFx0aWYgKG9sZEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRcdFx0b2xkRXhjbHVkZWRGb2xkZXIucG9zaXRpb24gKz0gMTtcclxuXHRcdFx0XHRpZiAob2xkRXhjbHVkZWRGb2xkZXIudHlwZSA9PT0gJ3BhdHRlcm4nKSB7XHJcblx0XHRcdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgb2xkRXhjbHVkZWRGb2xkZXIsIG9sZEV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRFeGNsdWRlZEZvbGRlciwgb2xkRXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRzZXR0aW5ncy5kaXNwbGF5KCk7XHJcblx0XHR9KTtcclxuXHR9KTtcclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ2Rvd24tY2hldnJvbi1nbHlwaCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnTW92ZSBkb3duJyk7XHJcblx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uID09PSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wb3NpdGlvbiArPSAxO1xyXG5cclxuXHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBleGNsdWRlZEZvbGRlciwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRjb25zdCBvbGRFeGNsdWRlZEZvbGRlciA9IHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maW5kKChmb2xkZXIpID0+IGZvbGRlci5wb3NpdGlvbiA9PT0gZXhjbHVkZWRGb2xkZXIucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRcdFx0XHRvbGRFeGNsdWRlZEZvbGRlci5wb3NpdGlvbiAtPSAxO1xyXG5cdFx0XHRcdGlmIChvbGRFeGNsdWRlZEZvbGRlci50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRFeGNsdWRlZEZvbGRlciwgb2xkRXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIG9sZEV4Y2x1ZGVkRm9sZGVyLCBvbGRFeGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRzZXR0aW5ncy5kaXNwbGF5KCk7XHJcblx0XHR9KTtcclxuXHR9KTtcclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3RyYXNoLTInKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ0RlbGV0ZSBleGNsdWRlZCBmb2xkZXInKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0c2V0dGluZy5jbGVhcigpO1xyXG5cdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG59XHJcbiIsICJpbXBvcnQgeyBBcHAsIE1vZGFsLCBTZXR0aW5nIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCB7IEV4Y2x1ZGVkRm9sZGVyIH0gZnJvbSAnc3JjL2V4Y2x1ZGVkRm9sZGVyJztcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXhjbHVkZWRGb2xkZXJTZXR0aW5ncyBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGV4Y2x1ZGVkRm9sZGVyOiBFeGNsdWRlZEZvbGRlcjtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZXhjbHVkZWRGb2xkZXI6IEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRzdXBlcihhcHApO1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0XHR0aGlzLmFwcCA9IGFwcDtcclxuXHRcdHRoaXMuZXhjbHVkZWRGb2xkZXIgPSBleGNsdWRlZEZvbGRlcjtcclxuXHR9XHJcblx0b25PcGVuKCkge1xyXG5cdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0fVxyXG5cdGRpc3BsYXkoKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xyXG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0V4Y2x1ZGVkIGZvbGRlciBzZXR0aW5ncycgfSk7XHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdJbmNsdWRlIHN1YmZvbGRlcnMnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBzdWJmb2xkZXJzIG9mIHRoZSBmb2xkZXIgc2hvdWxkIGFsc28gYmUgZXhjbHVkZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5zdWJGb2xkZXJzKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLmV4Y2x1ZGVkRm9sZGVyLnN1YkZvbGRlcnMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0Rpc2FibGUgZm9sZGVyIG5hbWUgc3luYycpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBub3RlIHNob3VsZCBiZSByZW5hbWVkIHdoZW4gdGhlIGZvbGRlciBuYW1lIGlzIGNoYW5nZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBhdXRvIGNyZWF0aW9uIG9mIGZvbGRlciBub3RlcyBpbiB0aGlzIGZvbGRlcicpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgYSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgY3JlYXRlZCB3aGVuIGEgbmV3IGZvbGRlciBpcyBjcmVhdGVkJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMuZXhjbHVkZWRGb2xkZXIuZGlzYWJsZUF1dG9DcmVhdGUpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMuZXhjbHVkZWRGb2xkZXIuZGlzYWJsZUF1dG9DcmVhdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIG9wZW4gZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgb3BlbmVkIHdoZW4gdGhlIGZvbGRlciBpcyBvcGVuZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSlcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdGlmICghdGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0NvbGxhcHNlIGZvbGRlciB3aGVuIG9wZW5pbmcgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBzaG91bGQgYmUgY29sbGFwc2VkIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIG9wZW5lZCcpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLmV4Y2x1ZGVkRm9sZGVyLmVuYWJsZUNvbGxhcHNpbmcpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmV4Y2x1ZGVkRm9sZGVyLmVuYWJsZUNvbGxhcHNpbmcgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fSlcclxuXHRcdFx0XHQpO1xyXG5cdFx0fVxyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG59XHJcbiIsICIvLyBDcmVkaXRzIGdvIHRvIExpYW0ncyBQZXJpb2RpYyBOb3RlcyBQbHVnaW46IGh0dHBzOi8vZ2l0aHViLmNvbS9saWFtY2Fpbi9vYnNpZGlhbi1wZXJpb2RpYy1ub3RlcyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL1NpbGVudFZvaWQxMy9UZW1wbGF0ZXJcclxuXHJcbmltcG9ydCB7IFRBYnN0cmFjdEZpbGUsIFRGb2xkZXIgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IFRleHRJbnB1dFN1Z2dlc3QgfSBmcm9tICcuL3N1Z2dlc3QnO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmV4cG9ydCBlbnVtIEZpbGVTdWdnZXN0TW9kZSB7XHJcbiAgICBUZW1wbGF0ZUZpbGVzLFxyXG4gICAgU2NyaXB0RmlsZXMsXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBGb2xkZXJTdWdnZXN0IGV4dGVuZHMgVGV4dElucHV0U3VnZ2VzdDxURm9sZGVyPiB7XHJcblx0Y29uc3RydWN0b3IoXHJcbiAgICAgICAgcHVibGljIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQsXHJcbiAgICAgICAgcHJpdmF0ZSBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luXHJcblx0KSB7XHJcblx0XHRzdXBlcihpbnB1dEVsKTtcclxuXHR9XHJcblxyXG5cclxuXHRnZXRfZXJyb3JfbXNnKG1vZGU6IEZpbGVTdWdnZXN0TW9kZSk6IHN0cmluZyB7XHJcblx0XHRzd2l0Y2ggKG1vZGUpIHtcclxuXHRcdFx0Y2FzZSBGaWxlU3VnZ2VzdE1vZGUuVGVtcGxhdGVGaWxlczpcclxuXHRcdFx0XHRyZXR1cm4gJ1RlbXBsYXRlcyBmb2xkZXIgZG9lc25cXCd0IGV4aXN0JztcclxuXHRcdFx0Y2FzZSBGaWxlU3VnZ2VzdE1vZGUuU2NyaXB0RmlsZXM6XHJcblx0XHRcdFx0cmV0dXJuICdVc2VyIFNjcmlwdHMgZm9sZGVyIGRvZXNuXFwndCBleGlzdCc7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRnZXRTdWdnZXN0aW9ucyhpbnB1dF9zdHI6IHN0cmluZyk6IFRGb2xkZXJbXSB7XHJcblx0XHRjb25zdCBmb2xkZXJzOiBURm9sZGVyW10gPSBbXTtcclxuXHRcdGNvbnN0IGxvd2VyX2lucHV0X3N0ciA9IGlucHV0X3N0ci50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFsbExvYWRlZEZpbGVzKCkuZm9yRWFjaCgoZm9sZGVyOiBUQWJzdHJhY3RGaWxlKSA9PiB7XHJcblx0XHRcdGlmIChcclxuXHRcdFx0XHRmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyICYmXHJcbiAgICAgICAgICAgICAgICBmb2xkZXIucGF0aC50b0xvd2VyQ2FzZSgpLmNvbnRhaW5zKGxvd2VyX2lucHV0X3N0cikgJiZcclxuICAgICAgICAgICAgICAgICF0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maW5kKChmKSA9PiBmLnBhdGggPT09IGZvbGRlci5wYXRoKVxyXG5cdFx0XHQpIHtcclxuXHRcdFx0XHRmb2xkZXJzLnB1c2goZm9sZGVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0cmV0dXJuIGZvbGRlcnM7XHJcblx0fVxyXG5cclxuXHRyZW5kZXJTdWdnZXN0aW9uKGZvbGRlcjogVEZvbGRlciwgZWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XHJcblx0XHRlbC5zZXRUZXh0KGZvbGRlci5wYXRoKTtcclxuXHR9XHJcblxyXG5cdHNlbGVjdFN1Z2dlc3Rpb24oZm9sZGVyOiBURm9sZGVyKTogdm9pZCB7XHJcblx0XHR0aGlzLmlucHV0RWwudmFsdWUgPSBmb2xkZXIucGF0aDtcclxuXHRcdHRoaXMuaW5wdXRFbC50cmlnZ2VyKCdpbnB1dCcpO1xyXG5cdFx0dGhpcy5jbG9zZSgpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZyB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBFeGNsdWRlUGF0dGVybiB9IGZyb20gJ3NyYy9leGNsdWRlZEZvbGRlcic7XHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhdHRlcm5TZXR0aW5ncyBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdHBhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBwYXR0ZXJuOiBFeGNsdWRlUGF0dGVybikge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLnBhdHRlcm4gPSBwYXR0ZXJuO1xyXG5cdH1cclxuXHRvbk9wZW4oKSB7XHJcblx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHR9XHJcblx0ZGlzcGxheSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnUGF0dGVybiBzZXR0aW5ncycgfSk7XHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIGZvbGRlciBuYW1lIHN5bmMnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbmFtZSBzaG91bGQgYmUgcmVuYW1lZCB3aGVuIHRoZSBmaWxlIG5hbWUgaGFzIGJlZW4gY2hhbmdlZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBhdHRlcm4uZGlzYWJsZVN5bmMpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMucGF0dGVybi5kaXNhYmxlU3luYyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBhdXRvIGNyZWF0aW9uIG9mIGZvbGRlciBub3RlcyBpbiB0aGlzIGZvbGRlcicpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgYSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgY3JlYXRlZCB3aGVuIGEgbmV3IGZvbGRlciBpcyBjcmVhdGVkIHRoYXQgbWF0Y2hlcyB0aGlzIHBhdHRlcm4nKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wYXR0ZXJuLmRpc2FibGVBdXRvQ3JlYXRlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBhdHRlcm4uZGlzYWJsZUF1dG9DcmVhdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIG9wZW4gZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgb3BlbmVkIHdoZW4gdGhlIGZvbGRlciBpcyBvcGVuZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wYXR0ZXJuLmRpc2FibGVGb2xkZXJOb3RlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBhdHRlcm4uZGlzYWJsZUZvbGRlck5vdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAoIXRoaXMucGF0dGVybi5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0NvbGxhcHNlIGZvbGRlciB3aGVuIG9wZW5pbmcgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBzaG91bGQgYmUgY29sbGFwc2VkIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIG9wZW5lZCcpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBhdHRlcm4uZW5hYmxlQ29sbGFwc2luZylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGF0dGVybi5lbmFibGVDb2xsYXBzaW5nID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cdG9uQ2xvc2UoKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJ3NyYy9tYWluJztcclxuaW1wb3J0IHsgZ2V0RGVmZXIsIExpc3RlbmVyLCBFdmVudHMsIEFwaUludGVyZmFjZSwgRGVmZXJJbnRlcmZhY2UsIExpc3RlbmVyUmVmLCBFdmVudERpc3BhdGNoZXJJbnRlcmZhY2UgfSBmcm9tICdmcm9udC1tYXR0ZXItcGx1Z2luLWFwaS1wcm92aWRlcic7XHJcbmltcG9ydCB7IEFwcCwgVEZpbGUsIFRGb2xkZXIgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IGV4dHJhY3RGb2xkZXJOYW1lLCBnZXRGb2xkZXIgfSBmcm9tICdzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5leHBvcnQgY2xhc3MgRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIge1xyXG5cdHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW47XHJcblx0YXBwOiBBcHA7XHJcblx0YXBpOiBBcGlJbnRlcmZhY2UgfCBudWxsID0gbnVsbDtcclxuXHRkZWZmZXI6IERlZmVySW50ZXJmYWNlIHwgbnVsbCA9IG51bGw7XHJcblx0bW9kaWZpZWRGb2xkZXJzOiBNYXA8c3RyaW5nLCBURm9sZGVyPiA9IG5ldyBNYXAoKTtcclxuXHRldmVudFJlZjogTGlzdGVuZXJSZWY8J21hbmFnZXI6dXBkYXRlJz47XHJcblx0ZGlzcGF0Y2hlcjogRXZlbnREaXNwYXRjaGVySW50ZXJmYWNlPEV2ZW50cz5cclxuXHRjb25zdHJ1Y3RvcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gcGx1Z2luLmFwcDtcclxuXHJcblx0XHQoYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmRlZmZlciA9IGdldERlZmVyKHRoaXMuYXBwKTtcclxuXHRcdFx0aWYgKHRoaXMuZGVmZmVyLmlzUGx1Z2luUmVhZHkoKSkge1xyXG5cdFx0XHRcdHRoaXMuYXBpID0gdGhpcy5kZWZmZXIuZ2V0QXBpKCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0YXdhaXQgdGhpcy5kZWZmZXIuYXdhaXRQbHVnaW4oKTtcclxuXHRcdFx0XHR0aGlzLmFwaSA9IHRoaXMuZGVmZmVyLmdldEFwaSgpO1xyXG5cdFx0XHRcdC8vIGlmIHlvdSB3YW50IHRvIHdhaXQgZmVhdHVyZXMgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBjaGFpblxyXG5cdFx0XHRcdGlmICghdGhpcy5kZWZmZXIuaXNGZWF0dXJlc1JlYWR5KCkpIHtcclxuXHRcdFx0XHRcdGF3YWl0IHRoaXMuZGVmZmVyLmF3YWl0RmVhdHVyZXMoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0Y29uc3QgZGlzcGF0Y2hlciA9IHRoaXMuYXBpPy5nZXRFdmVudERpc3BhdGNoZXIoKTtcclxuXHRcdFx0aWYgKGRpc3BhdGNoZXIpIHtcclxuXHRcdFx0XHR0aGlzLmRpc3BhdGNoZXIgPSBkaXNwYXRjaGVyO1xyXG5cdFx0XHR9XHJcblx0XHRcdGNvbnN0IGV2ZW50OiBMaXN0ZW5lcjxFdmVudHMsICdtYW5hZ2VyOnVwZGF0ZSc+ID0ge1xyXG5cdFx0XHRcdG5hbWU6ICdtYW5hZ2VyOnVwZGF0ZScsXHJcblx0XHRcdFx0Y2I6IChkYXRhKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLmhhbmRsZVJlbmFtZShkYXRhIGFzIGFueSwgdHJ1ZSk7XHJcblx0XHRcdFx0fSxcclxuXHRcdFx0fTtcclxuXHRcdFx0Ly8gS2VlcCByZWYgdG8gcmVtb3ZlIGxpc3RlbmVyXHJcblx0XHRcdGNvbnN0IHJlZiA9IGRpc3BhdGNoZXI/LmFkZExpc3RlbmVyKGV2ZW50KTtcclxuXHRcdFx0aWYgKHJlZikge1xyXG5cdFx0XHRcdHRoaXMuZXZlbnRSZWYgPSByZWY7XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEZpbGVzKCkuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRcdHRoaXMuaGFuZGxlUmVuYW1lKHsgaWQ6ICcnLCByZXN1bHQ6IGZhbHNlLCBwYXRoOiBmaWxlLnBhdGggfSwgZmFsc2UpO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuXHRcdH0pKCk7XHJcblx0fVxyXG5cdGRlbGV0ZUV2ZW50KCkge1xyXG5cdFx0aWYgKHRoaXMuZXZlbnRSZWYpIHtcclxuXHRcdFx0dGhpcy5kaXNwYXRjaGVyLnJlbW92ZUxpc3RlbmVyKHRoaXMuZXZlbnRSZWYpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRhc3luYyBoYW5kbGVSZW5hbWUoZGF0YToge1xyXG5cdFx0aWQ6IHN0cmluZztcclxuXHRcdHJlc3VsdDogYm9vbGVhbjtcclxuXHRcdHBhdGg6IHN0cmluZztcclxuXHR9LCBpc0V2ZW50OiBib29sZWFuKSB7XHJcblx0XHRpZiAoKGRhdGEgYXMgYW55KS5kYXRhKSBkYXRhID0gKGRhdGEgYXMgYW55KS5kYXRhXHJcblx0XHRjb25zdCBmaWxlID0gdGhpcy5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGRhdGEucGF0aCk7XHJcblx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7IHJldHVybjsgfVxyXG5cclxuXHRcdGNvbnN0IHJlc29sdmVyID0gdGhpcy5hcGk/LmdldFJlc29sdmVyRmFjdG9yeSgpPy5jcmVhdGVSZXNvbHZlcignI2ZlYXR1cmUtaWQjJyk7XHJcblx0XHRjb25zdCBuZXdOYW1lID0gcmVzb2x2ZXI/LnJlc29sdmUoZmlsZT8ucGF0aCA/PyAnJylcclxuXHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLnBsdWdpbiwgZmlsZSk7XHJcblxyXG5cdFx0aWYgKChleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSkgfHwgZmlsZS5iYXNlbmFtZSkgIT09IGZvbGRlcj8ubmFtZSkgeyByZXR1cm47IH1cclxuXHRcdGlmICghKGZvbGRlciBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0aWYgKGlzRXZlbnQpIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uY2hhbmdlTmFtZShmb2xkZXIsIG5ld05hbWUsIHRydWUpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uY2hhbmdlTmFtZShmb2xkZXIsIG5ld05hbWUsIGZhbHNlKTtcclxuXHRcdH1cclxuXHRcdGlmIChuZXdOYW1lKSB7XHJcblx0XHRcdGZvbGRlci5uZXdOYW1lID0gbmV3TmFtZTtcclxuXHRcdFx0dGhpcy5tb2RpZmllZEZvbGRlcnMuc2V0KGZvbGRlci5wYXRoLCBmb2xkZXIpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Zm9sZGVyLm5ld05hbWUgPSBudWxsO1xyXG5cdFx0XHR0aGlzLm1vZGlmaWVkRm9sZGVycy5kZWxldGUoZm9sZGVyLnBhdGgpO1xyXG5cdFx0fVxyXG5cclxuXHR9XHJcbn1cclxuIiwgImltcG9ydCB7IEFwcCwgVEZvbGRlciwgTWVudSwgVEFic3RyYWN0RmlsZSwgTm90aWNlLCBURmlsZSwgRWRpdG9yLCBNYXJrZG93blZpZXcsIFBsYXRmb3JtIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi9tYWluJztcclxuaW1wb3J0IHsgZ2V0Rm9sZGVyTm90ZSwgY3JlYXRlRm9sZGVyTm90ZSwgZGVsZXRlRm9sZGVyTm90ZSwgdHVybkludG9Gb2xkZXJOb3RlLCBvcGVuRm9sZGVyTm90ZSwgZXh0cmFjdEZvbGRlck5hbWUgfSBmcm9tICcuL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgRXhjbHVkZWRGb2xkZXIgfSBmcm9tICcuL2V4Y2x1ZGVkRm9sZGVyJztcclxuZXhwb3J0IGNsYXNzIENvbW1hbmRzIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gYXBwO1xyXG5cdH1cclxuXHRyZWdpc3RlckNvbW1hbmRzKCkge1xyXG5cdFx0dGhpcy5wbHVnaW4ucmVnaXN0ZXJFdmVudCh0aGlzLnBsdWdpbi5hcHAud29ya3NwYWNlLm9uKCdlZGl0b3ItbWVudScsIChtZW51OiBNZW51LCBlZGl0b3I6IEVkaXRvciwgdmlldzogTWFya2Rvd25WaWV3KSA9PiB7XHJcblx0XHRcdGNvbnN0IHRleHQgPSBlZGl0b3IuZ2V0U2VsZWN0aW9uKCkudHJpbSgpO1xyXG5cdFx0XHRtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpdGVtLnNldFRpdGxlKCdDcmVhdGUgZm9sZGVyIG92ZXJ2aWV3JylcclxuXHRcdFx0XHRcdC5zZXRJY29uKCdlZGl0JylcclxuXHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oJ2BgYGZvbGRlci1vdmVydmlld1xcbmBgYFxcbicpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRpZiAoIXRleHQgfHwgdGV4dC50cmltKCkgPT09ICcnKSByZXR1cm47XHJcblx0XHRcdG1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ0NyZWF0ZSBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IGZpbGUgPSB2aWV3LmZpbGU7XHJcblx0XHRcdFx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0Y29uc3QgYmxhY2tsaXN0ID0gWycqJywgJ1xcXFwnLCAnXCInLCAnLycsICc8JywgJz4nLCAnPycsICd8JywgJzonXTtcclxuXHRcdFx0XHRcdFx0Zm9yIChjb25zdCBjaGFyIG9mIGJsYWNrbGlzdCkge1xyXG5cdFx0XHRcdFx0XHRcdGlmICh0ZXh0LmluY2x1ZGVzKGNoYXIpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdGaWxlIG5hbWUgY2Fubm90IGNvbnRhaW4gYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKiBcIiBcXFxcIC8gPCA+IDogfCA/Jyk7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGlmICh0ZXh0LmVuZHNXaXRoKCcuJykpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdGaWxlIG5hbWUgY2Fubm90IGVuZCB3aXRoIGEgZG90Jyk7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGxldCBmb2xkZXI6IFRBYnN0cmFjdEZpbGUgfCBudWxsO1xyXG5cdFx0XHRcdFx0XHRjb25zdCBmb2xkZXJQYXRoID0gdGhpcy5wbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdFx0XHRcdFx0aWYgKGZvbGRlclBhdGggPT09ICcnKSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aCh0ZXh0KTtcclxuXHRcdFx0XHRcdFx0XHRpZiAoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZvbGRlciBub3RlIGFscmVhZHkgZXhpc3RzJyk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5jcmVhdGVGb2xkZXIodGV4dCk7XHJcblx0XHRcdFx0XHRcdFx0XHRjcmVhdGVGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCB0ZXh0LCBmYWxzZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCArICcvJyArIHRleHQpO1xyXG5cdFx0XHRcdFx0XHRcdGlmIChmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbmV3IE5vdGljZSgnRm9sZGVyIG5vdGUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICh0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCArICcvJyArIHRleHQgKyB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZSkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZpbGUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihmb2xkZXJQYXRoICsgJy8nICsgdGV4dCk7XHJcblx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZm9sZGVyUGF0aCArICcvJyArIHRleHQsIGZhbHNlKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRjb25zdCBmaWxlTmFtZSA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIHRleHQpO1xyXG5cdFx0XHRcdFx0XHRpZiAoZmlsZU5hbWUgPT09IHRleHQpIHtcclxuXHRcdFx0XHRcdFx0XHRlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgW1ske2ZpbGVOYW1lfV1dYCk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oYFtbJHtmaWxlTmFtZX18JHt0ZXh0fV1dYCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucGx1Z2luLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAud29ya3NwYWNlLm9uKCdmaWxlLW1lbnUnLCAobWVudTogTWVudSwgZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRsZXQgZm9sZGVyOiBUQWJzdHJhY3RGaWxlIHwgVEZvbGRlciB8IG51bGwgPSBmaWxlLnBhcmVudDtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRmb2xkZXIgPSBmaWxlLnBhcmVudDtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0Y29uc3QgZmlsZU5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSk7XHJcblx0XHRcdFx0XHRpZiAoZmlsZU5hbWUpIHtcclxuXHRcdFx0XHRcdFx0aWYgKGZpbGUucGFyZW50Py5wYXRoID09PSAnJyB8fCBmaWxlLnBhcmVudD8ucGF0aCA9PT0gJy8nKSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlTmFtZSk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlLnBhcmVudD8ucGF0aCArICcvJyArIGZpbGVOYW1lKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcy5wbHVnaW4sIGZvbGRlci5wYXRoKTtcclxuXHRcdFx0XHRcdGlmIChmb2xkZXJOb3RlPy5wYXRoID09PSBmaWxlLnBhdGgpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0fSBlbHNlIGlmIChmaWxlLnBhcmVudCBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRcdGZvbGRlciA9IGZpbGUucGFyZW50O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpZiAoUGxhdGZvcm0uaXNEZXNrdG9wICYmICFQbGF0Zm9ybS5pc1RhYmxldCAmJiB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VTdWJtZW51cykge1xyXG5cdFx0XHRcdFx0aXRlbVxyXG5cdFx0XHRcdFx0XHQuc2V0VGl0bGUoJ0ZvbGRlciBOb3RlIENvbW1hbmRzJylcclxuXHRcdFx0XHRcdFx0LnNldEljb24oJ2ZvbGRlci1lZGl0Jyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGxldCBzdWJNZW51OiBNZW51O1xyXG5cdFx0XHRcdGlmICghUGxhdGZvcm0uaXNEZXNrdG9wQXBwIHx8ICFQbGF0Zm9ybS5pc0Rlc2t0b3AgfHwgUGxhdGZvcm0uaXNUYWJsZXQgfHwgIXRoaXMucGx1Z2luLnNldHRpbmdzLnVzZVN1Ym1lbnVzKSB7XHJcblx0XHRcdFx0XHRzdWJNZW51ID0gbWVudTtcclxuXHRcdFx0XHRcdGl0ZW0uc2V0RGlzYWJsZWQodHJ1ZSk7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdFx0XHRcdHN1Yk1lbnUgPSBpdGVtLnNldFN1Ym1lbnUoKSBhcyBNZW51O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXHJcblx0XHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdFx0aXRlbS5zZXRUaXRsZSgnQ3JlYXRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCFmb2xkZXIpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdGxldCBuZXdQYXRoID0gZm9sZGVyLnBhdGggKyAnLycgKyBmaWxlLmJhc2VuYW1lO1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKGZvbGRlci5wYXRoID09PSAnJyB8fCBmb2xkZXIucGF0aCA9PT0gJy8nKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdG5ld1BhdGggPSBmaWxlLmJhc2VuYW1lO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobmV3UGF0aCkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZvbGRlciBhbHJlYWR5IGV4aXN0cycpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihuZXdQYXRoKTtcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IG5ld0ZvbGRlciA9IHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobmV3UGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIShuZXdGb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgbmV3Rm9sZGVyLnBhdGgsIHRydWUsIGZhbHNlLCBmaWxlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCkgPT09ICcnKSByZXR1cm47XHJcblx0XHRcdFx0XHRpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdFx0c3ViTWVudS5hZGRJdGVtKChpdGVtKSA9PiB7XHJcblx0XHRcdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ1R1cm4gaW50byBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0XHRcdFx0LnNldEljb24oJ2VkaXQnKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICghZm9sZGVyIHx8ICEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmb2xkZXIucGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHR0dXJuSW50b0ZvbGRlck5vdGUodGhpcy5wbHVnaW4sIGZpbGUsIGZvbGRlciwgZm9sZGVyTm90ZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSByZXR1cm47XHJcblx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbmQoKGZvbGRlcikgPT4gZm9sZGVyLnBhdGggPT09IGZpbGUucGF0aCkpIHtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdSZW1vdmUgZm9sZGVyIGZyb20gZXhjbHVkZWQgZm9sZGVycycpXHJcblx0XHRcdFx0XHRcdFx0LnNldEljb24oJ3RyYXNoJylcclxuXHRcdFx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcihcclxuXHRcdFx0XHRcdFx0XHRcdFx0KGZvbGRlcikgPT4gZm9sZGVyLnBhdGggIT09IGZpbGUucGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoJ1N1Y2Nlc3NmdWxseSByZW1vdmVkIGZvbGRlciBmcm9tIGV4Y2x1ZGVkIGZvbGRlcnMnKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ0V4Y2x1ZGUgZm9sZGVyIGZyb20gZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0XHRcdFx0LnNldEljb24oJ3gtY2lyY2xlJylcclxuXHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gbmV3IEV4Y2x1ZGVkRm9sZGVyKGZpbGUucGF0aCwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5wdXNoKGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdTdWNjZXNzZnVsbHkgZXhjbHVkZWQgZm9sZGVyIGZyb20gZm9sZGVyIG5vdGVzJyk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRcdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdEZWxldGUgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdFx0XHRcdC5zZXRJY29uKCd0cmFzaCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0ZGVsZXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZm9sZGVyTm90ZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdPcGVuIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignY2hldnJvbi1yaWdodC1zcXVhcmUnKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdG9wZW5Gb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmb2xkZXJOb3RlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdFx0aXRlbS5zZXRUaXRsZSgnQ3JlYXRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZmlsZS5wYXRoLCB0cnVlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KSk7XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgeyBLZXltYXAgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICdzcmMvbWFpbic7XHJcbmltcG9ydCB7IG9wZW5Gb2xkZXJOb3RlLCBjcmVhdGVGb2xkZXJOb3RlLCBnZXRGb2xkZXJOb3RlIH0gZnJvbSAnc3JjL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgZ2V0RXhjbHVkZWRGb2xkZXIgfSBmcm9tICdzcmMvZXhjbHVkZWRGb2xkZXInO1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlVmlld0hlYWRlckNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50LCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0aWYgKCEoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSByZXR1cm47XHJcblx0aWYgKCFwbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKSByZXR1cm47XHJcblxyXG5cdGNvbnN0IGZvbGRlclBhdGggPSBldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnKTtcclxuXHRpZiAoIWZvbGRlclBhdGgpIHsgcmV0dXJuOyB9XHJcblx0Y29uc3QgZXhjbHVkZWRGb2xkZXIgPSBnZXRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChleGNsdWRlZEZvbGRlcj8uZGlzYWJsZUZvbGRlck5vdGUpIHtcclxuXHRcdGV2ZW50LnRhcmdldC5vbmNsaWNrID0gbnVsbDtcclxuXHRcdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH0gZWxzZSBpZiAoZXhjbHVkZWRGb2xkZXI/LmVuYWJsZUNvbGxhcHNpbmcgfHwgcGx1Z2luLnNldHRpbmdzLmVuYWJsZUNvbGxhcHNpbmcpIHtcclxuXHRcdGV2ZW50LnRhcmdldC5vbmNsaWNrID0gbnVsbDtcclxuXHRcdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gb3BlbkZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJOb3RlLCBldmVudCk7XHJcblx0fSBlbHNlIGlmIChldmVudC5hbHRLZXkgfHwgS2V5bWFwLmlzTW9kRXZlbnQoZXZlbnQpID09PSAndGFiJykge1xyXG5cdFx0aWYgKChwbHVnaW4uc2V0dGluZ3MuYWx0S2V5ICYmIGV2ZW50LmFsdEtleSkgfHwgKHBsdWdpbi5zZXR0aW5ncy5jdHJsS2V5ICYmIEtleW1hcC5pc01vZEV2ZW50KGV2ZW50KSA9PT0gJ3RhYicpKSB7XHJcblx0XHRcdGF3YWl0IGNyZWF0ZUZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJQYXRoLCB0cnVlLCB0cnVlKTtcclxuXHRcdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlclBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlclBhdGgsICdoYXMtbm90LWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHR9XHJcblx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG59XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlRm9sZGVyQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4pIHtcclxuXHRpZiAoIShldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybjtcclxuXHRldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuXHJcblx0Y29uc3QgZm9sZGVyUGF0aCA9IGV2ZW50LnRhcmdldC5wYXJlbnRFbGVtZW50Py5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpO1xyXG5cdGlmICghZm9sZGVyUGF0aCkgeyByZXR1cm47IH1cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZm9sZGVyUGF0aCk7XHJcblx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdFx0ZXZlbnQudGFyZ2V0LmNsaWNrKCk7XHJcblx0XHRyZXR1cm47XHJcblx0fSBlbHNlIGlmIChleGNsdWRlZEZvbGRlcj8uZW5hYmxlQ29sbGFwc2luZyB8fCBwbHVnaW4uc2V0dGluZ3MuZW5hYmxlQ29sbGFwc2luZykge1xyXG5cdFx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdFx0ZXZlbnQudGFyZ2V0LmNsaWNrKCk7XHJcblx0fVxyXG5cclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gb3BlbkZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJOb3RlLCBldmVudCk7XHJcblx0fSBlbHNlIGlmIChldmVudC5hbHRLZXkgfHwgS2V5bWFwLmlzTW9kRXZlbnQoZXZlbnQpID09PSAndGFiJykge1xyXG5cdFx0aWYgKChwbHVnaW4uc2V0dGluZ3MuYWx0S2V5ICYmIGV2ZW50LmFsdEtleSkgfHwgKHBsdWdpbi5zZXR0aW5ncy5jdHJsS2V5ICYmIEtleW1hcC5pc01vZEV2ZW50KGV2ZW50KSA9PT0gJ3RhYicpKSB7XHJcblx0XHRcdGF3YWl0IGNyZWF0ZUZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJQYXRoLCB0cnVlLCB0cnVlKTtcclxuXHRcdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlclBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlclBhdGgsICdoYXMtbm90LWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHR9XHJcblx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG59XHJcbiIsICJpbXBvcnQgeyBURmlsZSwgVEZvbGRlciwgVEFic3RyYWN0RmlsZSwgTm90aWNlIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnc3JjL21haW4nO1xyXG5pbXBvcnQgeyBleHRyYWN0Rm9sZGVyTmFtZSwgZ2V0Rm9sZGVyTm90ZSwgZ2V0Rm9sZGVyTm90ZUZvbGRlciB9IGZyb20gJy4uL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgZ2V0RXhjbHVkZWRGb2xkZXIsIEV4Y2x1ZGVkRm9sZGVyLCBhZGRFeGNsdWRlZEZvbGRlciwgdXBkYXRlRXhjbHVkZWRGb2xkZXIsIGRlbGV0ZUV4Y2x1ZGVkRm9sZGVyIH0gZnJvbSAnLi4vZXhjbHVkZWRGb2xkZXInO1xyXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRm9sZGVyUmVuYW1lKGZpbGU6IFRGb2xkZXIsIG9sZFBhdGg6IHN0cmluZywgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdGNvbnN0IGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZpbGUubmFtZSk7XHJcblx0Y29uc3QgZm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZmlsZS5wYXRoKTtcclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIG9sZFBhdGgpO1xyXG5cdGlmICghKGZvbGRlck5vdGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHJcblx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRjb25zdCBleGNsdWRlZEZvbGRlcnMgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmlsdGVyKFxyXG5cdFx0KGV4Y2x1ZGVkRm9sZGVyKSA9PiBleGNsdWRlZEZvbGRlci5wYXRoLmluY2x1ZGVzKG9sZFBhdGgpXHJcblx0KTtcclxuXHJcblx0ZXhjbHVkZWRGb2xkZXJzLmZvckVhY2goKGV4Y2x1ZGVkRm9sZGVyKSA9PiB7XHJcblx0XHRpZiAoZXhjbHVkZWRGb2xkZXIucGF0aCA9PT0gb2xkUGF0aCkge1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gZm9sZGVyLnBhdGg7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGZvbGRlcnMgPSBleGNsdWRlZEZvbGRlci5wYXRoLnNwbGl0KCcvJyk7XHJcblx0XHRpZiAoZm9sZGVycy5sZW5ndGggPCAxKSB7XHJcblx0XHRcdGZvbGRlcnMucHVzaChleGNsdWRlZEZvbGRlci5wYXRoKTtcclxuXHRcdH1cclxuXHJcblx0XHRmb2xkZXJzW2ZvbGRlcnMuaW5kZXhPZihmb2xkZXIubmFtZSldID0gZm9sZGVyLm5hbWU7XHJcblx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gZm9sZGVycy5qb2luKCcvJyk7XHJcblx0fSk7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZmlsZS5wYXRoKTtcclxuXHRpZiAoZXhjbHVkZWRGb2xkZXI/LmRpc2FibGVTeW5jICYmICFmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gcGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdH1cclxuXHJcblx0bGV0IG5ld1BhdGggPSAnJztcclxuXHRpZiAocGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdGNvbnN0IHBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGNvbnN0IG9sZFBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcob2xkUGF0aCk7XHJcblx0XHRpZiAocGFyZW50Rm9sZGVyUGF0aCAhPT0gb2xkUGFyZW50Rm9sZGVyUGF0aCkge1xyXG5cdFx0XHRpZiAoIXBsdWdpbi5zZXR0aW5ncy5zeW5jTW92ZSkgeyByZXR1cm47IH1cclxuXHRcdFx0bmV3UGF0aCA9IGAke3BhcmVudEZvbGRlclBhdGh9LyR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHRcdH0gZWxzZSBpZiAocGFyZW50Rm9sZGVyUGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRcdGZvbGRlck5vdGUucGF0aCA9IGAke2ZvbGRlck5vdGUubmFtZX1gO1xyXG5cdFx0XHRuZXdQYXRoID0gYCR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvbGRlck5vdGUucGF0aCA9IGAke3BhcmVudEZvbGRlclBhdGh9LyR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdG5ld1BhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke2ZpbGVOYW1lfS4ke2ZvbGRlck5vdGUuZXh0ZW5zaW9ufWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIHtcclxuXHRcdGZvbGRlck5vdGUucGF0aCA9IGAke2ZpbGUucGF0aH0vJHtmb2xkZXJOb3RlLm5hbWV9YDtcclxuXHRcdG5ld1BhdGggPSBgJHtmaWxlLnBhdGh9LyR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHR9XHJcblx0cGx1Z2luLmFwcC52YXVsdC5yZW5hbWUoZm9sZGVyTm90ZSwgbmV3UGF0aCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVGaWxlUmVuYW1lKGZpbGU6IFRGaWxlLCBvbGRQYXRoOiBzdHJpbmcsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4pIHtcclxuXHRjb25zdCBvbGRGaWxlTmFtZSA9IHBsdWdpbi5yZW1vdmVFeHRlbnNpb24ocGx1Z2luLmdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcob2xkUGF0aCkpO1xyXG5cdGNvbnN0IG9sZEZvbGRlciA9IGdldEZvbGRlck5vdGVGb2xkZXIocGx1Z2luLCBvbGRQYXRoLCBvbGRGaWxlTmFtZSk7XHJcblx0Y29uc3QgZm9sZGVyTmFtZSA9IGV4dHJhY3RGb2xkZXJOYW1lKHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSkgfHwgZmlsZS5iYXNlbmFtZTtcclxuXHRjb25zdCBvbGRGb2xkZXJOYW1lID0gZXh0cmFjdEZvbGRlck5hbWUocGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBvbGRGaWxlTmFtZSkgfHwgb2xkRmlsZU5hbWU7XHJcblx0Y29uc3QgbmV3Rm9sZGVyID0gZ2V0Rm9sZGVyTm90ZUZvbGRlcihwbHVnaW4sIGZpbGUsIGZpbGUuYmFzZW5hbWUpO1xyXG5cdGxldCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgbmV3Rm9sZGVyPy5wYXRoIHx8ICcnKTtcclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIG9sZFBhdGgsIHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24sIGZpbGUpO1xyXG5cclxuXHRpZiAoZXhjbHVkZWRGb2xkZXI/LmRpc2FibGVTeW5jICYmIGZvbGRlck5hbWUgPT09IG5ld0ZvbGRlcj8ubmFtZSkge1xyXG5cdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwobmV3Rm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHJldHVybjtcclxuXHR9IGVsc2UgaWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlU3luYykge1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwobmV3Rm9sZGVyPy5wYXRoIHx8ICcnLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHQvLyBmaWxlIGhhcyBiZWVuIG1vdmVkIGludG8gcG9zaXRpb24gd2hlcmUgaXQgY2FuIGJlIGEgZm9sZGVyIG5vdGUhXHJcblx0aWYgKGZvbGRlck5hbWUgPT09IG5ld0ZvbGRlcj8ubmFtZSAmJiBmb2xkZXJOb3RlKSB7XHJcblx0XHRuZXcgTm90aWNlKCdGb2xkZXIgd2l0aCBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdHMhJyk7XHJcblx0XHRsZXQgZXhjbHVkZWRGb2xkZXJFeGlzdGVkID0gdHJ1ZTtcclxuXHRcdGxldCBkaXNhYmxlZFN5bmMgPSBmYWxzZTtcclxuXHJcblx0XHRpZiAoIWV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRcdGV4Y2x1ZGVkRm9sZGVyRXhpc3RlZCA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlciA9IG5ldyBFeGNsdWRlZEZvbGRlcihvbGRGb2xkZXI/LnBhdGggfHwgJycsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0gZWxzZSBpZiAoIWV4Y2x1ZGVkRm9sZGVyLmRpc2FibGVTeW5jKSB7XHJcblx0XHRcdGRpc2FibGVkU3luYyA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHRydWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBvbGRQYXRoKS50aGVuKCgpID0+IHtcclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlckV4aXN0ZWQpIHtcclxuXHRcdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIGlmICghZGlzYWJsZWRTeW5jKSB7XHJcblx0XHRcdFx0ZXhjbHVkZWRGb2xkZXIuZGlzYWJsZVN5bmMgPSBmYWxzZTtcclxuXHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHRpZiAoZm9sZGVyTmFtZSA9PT0gbmV3Rm9sZGVyPy5uYW1lKSB7XHJcblx0XHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZmlsZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHBsdWdpbi5hZGRDU1NDbGFzc1RvVGl0bGVFTChuZXdGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKG9sZEZvbGRlcj8ucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0Ly8gZmlsZSBtYXRjaGVkIGZvbGRlciBuYW1lIGJlZm9yZSByZW5hbWVcclxuXHQvLyBmaWxlIGhhc250IG1vdmVkIGp1c3QgcmVuYW1lZFxyXG5cdC8vIE5lZWQgdG8gcmVuYW1lIHRoZSBmb2xkZXJcclxuXHRpZiAoIW9sZEZvbGRlcikgcmV0dXJuO1xyXG5cdGlmIChvbGRGb2xkZXJOYW1lID09PSBvbGRGb2xkZXIubmFtZSAmJiBuZXdGb2xkZXI/LnBhdGggPT09IG9sZEZvbGRlci5wYXRoKSB7XHJcblx0XHRyZXR1cm4gcmVuYW1lRm9sZGVyT25GaWxlUmVuYW1lKGZpbGUsIG9sZFBhdGgsIG9sZEZvbGRlciwgcGx1Z2luKTtcclxuXHR9IGVsc2UgaWYgKGZvbGRlck5vdGUgJiYgb2xkRm9sZGVyTmFtZSA9PT0gb2xkRm9sZGVyLm5hbWUpIHtcclxuXHRcdHJldHVybiByZW5hbWVGb2xkZXJPbkZpbGVSZW5hbWUoZmlsZSwgb2xkUGF0aCwgb2xkRm9sZGVyLCBwbHVnaW4pO1xyXG5cdH1cclxuXHJcblx0Ly8gdGhlIG5vdGUgaGFzIGJlZW4gbW92ZWQgc29tZXdoZXJlIGFuZCBpcyBubyBsb25nZXIgYSBmb2xkZXIgbm90ZVxyXG5cdC8vIGNsZWFudXAgY3NzIG9uIHRoZSBmb2xkZXIgYW5kIG5vdGVcclxuXHRpZiAob2xkRm9sZGVyLm5hbWUgPT09IG9sZEZpbGVOYW1lICYmIG5ld0ZvbGRlcj8ucGF0aCAhPT0gb2xkRm9sZGVyLnBhdGgpIHtcclxuXHRcdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChvbGRGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwob2xkUGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0fVxyXG59XHJcblxyXG5hc3luYyBmdW5jdGlvbiByZW5hbWVGb2xkZXJPbkZpbGVSZW5hbWUoZmlsZTogVEZpbGUsIG9sZFBhdGg6IHN0cmluZywgb2xkRm9sZGVyOiBUQWJzdHJhY3RGaWxlLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0Y29uc3QgbmV3Rm9sZGVyTmFtZSA9IGV4dHJhY3RGb2xkZXJOYW1lKHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSk7XHJcblx0aWYgKCFuZXdGb2xkZXJOYW1lKSB7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwob2xkRm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlLnBhdGgsICdpcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH0gZWxzZSBpZiAobmV3Rm9sZGVyTmFtZSA9PT0gb2xkRm9sZGVyLm5hbWUpIHtcclxuXHRcdHBsdWdpbi5hZGRDU1NDbGFzc1RvVGl0bGVFTChvbGRGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdGxldCBuZXdGb2xkZXJQYXRoID0gJyc7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRuZXdGb2xkZXJQYXRoID0gb2xkRm9sZGVyLnBhcmVudD8ucGF0aCArICcvJyArIG5ld0ZvbGRlck5hbWU7XHJcblx0fSBlbHNlIHtcclxuXHRcdGNvbnN0IHBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGlmIChwYXJlbnRGb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0bmV3Rm9sZGVyUGF0aCA9IGAke25ld0ZvbGRlck5hbWV9YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG5ld0ZvbGRlclBhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke25ld0ZvbGRlck5hbWV9YDtcclxuXHRcdH1cclxuXHR9XHJcblx0aWYgKHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG5ld0ZvbGRlclBhdGgpIHx8IHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG5ld0ZvbGRlck5hbWUgfHwgJycpKSB7XHJcblx0XHRhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBvbGRQYXRoKTtcclxuXHRcdHJldHVybiBuZXcgTm90aWNlKCdBIGZvbGRlciB3aXRoIHRoZSBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHR9XHJcblx0YXdhaXQgcGx1Z2luLmFwcC52YXVsdC5yZW5hbWUob2xkRm9sZGVyLCBuZXdGb2xkZXJQYXRoKTtcclxufVxyXG4iLCAiaW1wb3J0IHsgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgcGFyc2VZYW1sLCBUQWJzdHJhY3RGaWxlLCBURm9sZGVyLCBURmlsZSB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IHsgZXh0cmFjdEZvbGRlck5hbWUsIGdldEZvbGRlck5vdGUgfSBmcm9tICcuL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4vbWFpbic7XHJcbmV4cG9ydCB0eXBlIHlhbWxTZXR0aW5ncyA9IHtcclxuXHR0aXRsZT86IHN0cmluZztcclxuXHRkaXNhYmxlVGl0bGU/OiBib29sZWFuO1xyXG5cdGRlcHRoPzogbnVtYmVyO1xyXG5cdHR5cGU/OiAnZm9sZGVyJyB8ICdtYXJrZG93bicgfCAnY2FudmFzJyB8ICdvdGhlcicgfCAncGRmJyB8ICdpbWFnZXMnIHwgJ2F1ZGlvJyB8ICd2aWRlbycgfCAnYWxsJztcclxuXHRpbmNsdWRlVHlwZXM/OiBzdHJpbmdbXTtcclxuXHRzdHlsZT86ICdsaXN0JyB8ICdncmlkJztcclxuXHRkaXNhYmxlRmlsZVRhZz86IGJvb2xlYW47XHJcblx0c29ydEJ5PzogJ25hbWUnIHwgJ2NyZWF0ZWQnIHwgJ21vZGlmaWVkJyB8ICduYW1lQXNjJyB8ICdjcmVhdGVkQXNjJyB8ICdtb2RpZmllZEFzYyc7XHJcblx0c2hvd0VtcHR5Rm9sZGVycz86IGJvb2xlYW47XHJcblx0b25seUluY2x1ZGVTdWJmb2xkZXJzPzogYm9vbGVhbjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDYW52YXNPdmVydmlldygpIHtcclxuXHQvLyBjb25zb2xlLmxvZygndGVzdCcpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3ZlcnZpZXcocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgc291cmNlOiBzdHJpbmcsIGVsOiBIVE1MRWxlbWVudCwgY3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0KSB7XHJcblx0Ly8gcGFyc2Ugc291cmNlIHRvIHlhbWxcclxuXHRsZXQgeWFtbDogeWFtbFNldHRpbmdzID0gcGFyc2VZYW1sKHNvdXJjZSk7XHJcblx0aWYgKCF5YW1sKSB7XHJcblx0XHR5YW1sID0ge1xyXG5cdFx0XHR0aXRsZTogcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSxcclxuXHRcdFx0ZGlzYWJsZVRpdGxlOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVUaXRsZSxcclxuXHRcdFx0ZGVwdGg6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuZGVwdGgsXHJcblx0XHRcdHR5cGU6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcudHlwZSxcclxuXHRcdFx0aW5jbHVkZVR5cGVzOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyxcclxuXHRcdFx0c3R5bGU6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc3R5bGUsXHJcblx0XHRcdGRpc2FibGVGaWxlVGFnOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnLFxyXG5cdFx0XHRzb3J0Qnk6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc29ydEJ5LFxyXG5cdFx0XHRzaG93RW1wdHlGb2xkZXJzOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNob3dFbXB0eUZvbGRlcnMsXHJcblx0XHRcdG9ubHlJbmNsdWRlU3ViZm9sZGVyczogcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5vbmx5SW5jbHVkZVN1YmZvbGRlcnMsXHJcblx0XHR9O1xyXG5cdH1cclxuXHRjb25zdCBkZXB0aCA9IHlhbWw/LmRlcHRoIHx8IDE7XHJcblx0bGV0IHRpdGxlID0geWFtbD8udGl0bGUgfHwgcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSB8fCAne3tmb2xkZXJOYW1lfX0gb3ZlcnZpZXcnO1xyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUsIHBsdWdpbi5yZW1vdmVFeHRlbnNpb24ocGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhjdHguc291cmNlUGF0aCkpKTtcclxuXHR0aXRsZSA9IHRpdGxlLnJlcGxhY2VBbGwoJ3t7Zm9sZGVyTmFtZX19JywgZm9sZGVyTmFtZSB8fCAnJyk7XHJcblx0Y29uc3QgZGlzYWJsZVRpdGxlID0geWFtbD8uZGlzYWJsZVRpdGxlIHx8IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuZGlzYWJsZVRpdGxlIHx8IGZhbHNlO1xyXG5cdGxldCBpbmNsdWRlVHlwZXM6IHN0cmluZ1tdID0geWFtbD8uaW5jbHVkZVR5cGVzIHx8IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuaW5jbHVkZVR5cGVzIHx8IFsnZm9sZGVyJywgJ21hcmtkb3duJ107XHJcblx0aW5jbHVkZVR5cGVzID0gaW5jbHVkZVR5cGVzLm1hcCgodHlwZSkgPT4gdHlwZS50b0xvd2VyQ2FzZSgpKTtcclxuXHRjb25zdCBzdHlsZTogJ2xpc3QnIHwgJ2dyaWQnID0geWFtbD8uc3R5bGUgfHwgJ2xpc3QnO1xyXG5cdGNvbnN0IGRpc2FibGVGaWxlVGFnID0geWFtbD8uZGlzYWJsZUZpbGVUYWcgfHwgcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kaXNhYmxlRmlsZVRhZyB8fCBmYWxzZTtcclxuXHRjb25zdCBzaG93RW1wdHlGb2xkZXJzID0geWFtbD8uc2hvd0VtcHR5Rm9sZGVycyB8fCBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNob3dFbXB0eUZvbGRlcnMgfHwgZmFsc2U7XHJcblxyXG5cdGNvbnN0IHJvb3QgPSBlbC5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXcnIH0pO1xyXG5cdGNvbnN0IHRpdGxlRWwgPSByb290LmNyZWF0ZUVsKCdoMScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LXRpdGxlJyB9KTtcclxuXHRjb25zdCB1bCA9IHJvb3QuY3JlYXRlRWwoJ3VsJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdCcgfSk7XHJcblx0aWYgKCFkaXNhYmxlVGl0bGUpIHtcclxuXHRcdHRpdGxlRWwuaW5uZXJUZXh0ID0gdGl0bGU7XHJcblx0fVxyXG5cdGlmIChpbmNsdWRlVHlwZXMubGVuZ3RoID09PSAwKSB7IHJldHVybjsgfVxyXG5cdGxldCBmaWxlczogVEFic3RyYWN0RmlsZVtdID0gW107XHJcblx0Y29uc3Qgc291cmNlRmlsZSA9IHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGN0eC5zb3VyY2VQYXRoKTtcclxuXHRpZiAoIXNvdXJjZUZpbGUpIHJldHVybjtcclxuXHRjb25zdCBzb3VyY2VGb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKTtcclxuXHRsZXQgc291cmNlRm9sZGVyOiBURm9sZGVyIHwgdW5kZWZpbmVkO1xyXG5cclxuXHRpZiAoc291cmNlRmlsZS5wYXJlbnQgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRzb3VyY2VGb2xkZXIgPSBzb3VyY2VGaWxlLnBhcmVudDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0c291cmNlRm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKSkgYXMgVEZvbGRlcjtcclxuXHR9XHJcblxyXG5cdGZpbGVzID0gc291cmNlRm9sZGVyLmNoaWxkcmVuO1xyXG5cclxuXHRmaWxlcyA9IGZpbGVzLmZpbHRlcigoZmlsZSkgPT4ge1xyXG5cdFx0Y29uc3QgZm9sZGVyUGF0aCA9IHBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpO1xyXG5cdFx0aWYgKCFmb2xkZXJQYXRoLnN0YXJ0c1dpdGgoc291cmNlRm9sZGVyUGF0aCkpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRpZiAoZmlsZS5wYXRoID09PSBjdHguc291cmNlUGF0aCkgeyByZXR1cm4gZmFsc2U7IH1cclxuXHRcdGlmICgoZmlsZS5wYXRoLnNwbGl0KCcvJykubGVuZ3RoIC0gc291cmNlRm9sZGVyUGF0aC5zcGxpdCgnLycpLmxlbmd0aCkgLSAxIDwgZGVwdGgpIHtcclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9XHJcblx0fSk7XHJcblx0aWYgKCFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ2ZvbGRlcicpKSB7XHJcblx0XHRmaWxlcyA9IGdldEFsbEZpbGVzKGZpbGVzLCBzb3VyY2VGb2xkZXJQYXRoLCBkZXB0aCk7XHJcblx0fVxyXG5cdGZpbGVzID0gc29ydEZpbGVzKGZpbGVzLCB5YW1sLCBwbHVnaW4pO1xyXG5cclxuXHRpZiAoc3R5bGUgPT09ICdncmlkJykge1xyXG5cdFx0Y29uc3QgZ3JpZCA9IHJvb3QuY3JlYXRlRWwoJ2RpdicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQnIH0pO1xyXG5cdFx0ZmlsZXMuZm9yRWFjaChhc3luYyAoZmlsZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBncmlkSXRlbSA9IGdyaWQuY3JlYXRlRWwoJ2RpdicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQtaXRlbScgfSk7XHJcblx0XHRcdGNvbnN0IGdyaWRBcnRpY2xlID0gZ3JpZEl0ZW0uY3JlYXRlRWwoJ2FydGljbGUnLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1ncmlkLWl0ZW0tYXJ0aWNsZScgfSk7XHJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRjb25zdCBmaWxlQ29udGVudCA9IGF3YWl0IHBsdWdpbi5hcHAudmF1bHQucmVhZChmaWxlKTtcclxuXHRcdFx0XHQvLyBza2lwIC0tLSB5YW1sXHJcblx0XHRcdFx0Y29uc3QgZGVzY3JpcHRpb25FbCA9IGdyaWRBcnRpY2xlLmNyZWF0ZUVsKCdwJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWRlc2NyaXB0aW9uJyB9KTtcclxuXHRcdFx0XHRsZXQgZGVzY3JpcHRpb24gPSBmaWxlQ29udGVudC5zcGxpdCgnXFxuJylbMF07XHJcblx0XHRcdFx0aWYgKGRlc2NyaXB0aW9uLmxlbmd0aCA+IDY0KSB7XHJcblx0XHRcdFx0XHRkZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLnNsaWNlKDAsIDY0KSArICcuLi4nO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRkZXNjcmlwdGlvbkVsLmlubmVyVGV4dCA9IGRlc2NyaXB0aW9uO1xyXG5cdFx0XHRcdGNvbnN0IGxpbmsgPSBncmlkQXJ0aWNsZS5jcmVhdGVFbCgnYScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQtaXRlbS1saW5rIGludGVybmFsLWxpbmsnIH0pO1xyXG5cdFx0XHRcdGNvbnN0IHRpdGxlID0gbGluay5jcmVhdGVFbCgnaDEnLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1ncmlkLWl0ZW0tbGluay10aXRsZScgfSk7XHJcblx0XHRcdFx0dGl0bGUuaW5uZXJUZXh0ID0gZmlsZS5uYW1lLnJlcGxhY2UoJy5tZCcsICcnKS5yZXBsYWNlKCcuY2FudmFzJywgJycpO1xyXG5cdFx0XHRcdGxpbmsuaHJlZiA9IGZpbGUucGF0aDtcclxuXHRcdFx0fSBlbHNlIGlmIChmaWxlIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlckl0ZW0gPSBncmlkQXJ0aWNsZS5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWZvbGRlcicgfSk7XHJcblx0XHRcdFx0Y29uc3QgZm9sZGVyTmFtZSA9IGZvbGRlckl0ZW0uY3JlYXRlRWwoJ2gxJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWZvbGRlci1uYW1lJyB9KTtcclxuXHRcdFx0XHRmb2xkZXJOYW1lLmlubmVyVGV4dCA9IGZpbGUubmFtZTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSBlbHNlIGlmIChzdHlsZSA9PT0gJ2xpc3QnKSB7XHJcblx0XHRjb25zdCBwYXRoQmxhY2tsaXN0OiBzdHJpbmdbXSA9IFtdO1xyXG5cdFx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXJJdGVtID0gYWRkRm9sZGVyTGlzdChwbHVnaW4sIHVsLCBwYXRoQmxhY2tsaXN0LCBmaWxlKTtcclxuXHRcdFx0XHRnb1Rocm91Z2hGb2xkZXJzKHBsdWdpbiwgZm9sZGVySXRlbSwgZmlsZSwgZGVwdGgsIHNvdXJjZUZvbGRlclBhdGgsIGN0eCwgeWFtbCwgcGF0aEJsYWNrbGlzdCwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0YWRkRmlsZUxpc3QocGx1Z2luLCB1bCwgcGF0aEJsYWNrbGlzdCwgZmlsZSwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH0gZWxzZSBpZiAoc3R5bGUgPT09ICdleHBsb3JlcicpIHtcclxuXHRcdC8qXHJcblx0XHRjb25zdCB2aWV3ID0gcGx1Z2luLmdldEZpbGVFeHBsb3JlclZpZXcoKTtcclxuXHRcdGNvbnN0IGZvbGRlckVsZW1lbnQgPSBwbHVnaW4uZ2V0RUwocGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKSk/LnBhcmVudEVsZW1lbnQ7XHJcblx0XHRpZiAoIWZvbGRlckVsZW1lbnQpIHJldHVybjtcclxuXHRcdC8vIGNvcHkgZm9sZGVyRWxlbWVudFxyXG5cdFx0Y29uc3QgbmV3Rm9sZGVyRWxlbWVudCA9IGZvbGRlckVsZW1lbnQuY2xvbmVOb2RlKHRydWUpIGFzIEhUTUxFbGVtZW50O1xyXG5cdFx0bmV3Rm9sZGVyRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCcubmF2LWZvbGRlcicpLmZvckVhY2goKGVsKSA9PiB7XHJcblx0XHRcdGVsLmNsYXNzTGlzdC5yZW1vdmUoJ2lzLWNvbGxhcHNlZCcpO1xyXG5cdFx0fSk7XHJcblx0XHRyb290LmFwcGVuZENoaWxkKGZvbGRlckVsZW1lbnQpO1xyXG5cdFx0Ki9cclxuXHR9XHJcblx0aWYgKGluY2x1ZGVUeXBlcy5sZW5ndGggPiAxICYmIHN0eWxlICE9PSAnZ3JpZCcgJiYgKCFzaG93RW1wdHlGb2xkZXJzIHx8IHlhbWwub25seUluY2x1ZGVTdWJmb2xkZXJzKSkge1xyXG5cdFx0cmVtb3ZlRW1wdHlGb2xkZXJzKHVsLCAxLCB5YW1sKTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdvVGhyb3VnaEZvbGRlcnMocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgbGlzdDogSFRNTExJRWxlbWVudCB8IEhUTUxVTGlzdEVsZW1lbnQsIGZvbGRlcjogVEZvbGRlcixcclxuXHRkZXB0aDogbnVtYmVyLCBzb3VyY2VGb2xkZXJQYXRoOiBzdHJpbmcsIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgeWFtbDogeWFtbFNldHRpbmdzLCBwYXRoQmxhY2tsaXN0OiBzdHJpbmdbXSwgaW5jbHVkZVR5cGVzOiBzdHJpbmdbXSwgZGlzYWJsZUZpbGVUYWc6IGJvb2xlYW4pIHtcclxuXHRpZiAoc291cmNlRm9sZGVyUGF0aCA9PT0gJycpIHtcclxuXHRcdGRlcHRoLS07XHJcblx0fVxyXG5cdGxldCBmaWxlcyA9IGZvbGRlci5jaGlsZHJlbi5maWx0ZXIoKGZpbGUpID0+IHtcclxuXHRcdGNvbnN0IGZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGlmICghZm9sZGVyUGF0aC5zdGFydHNXaXRoKHNvdXJjZUZvbGRlclBhdGgpKSB7IHJldHVybiBmYWxzZTsgfVxyXG5cdFx0aWYgKChmaWxlLnBhdGguc3BsaXQoJy8nKS5sZW5ndGggLSBzb3VyY2VGb2xkZXJQYXRoLnNwbGl0KCcvJykubGVuZ3RoKSAtIDEgPCBkZXB0aCkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHRmaWxlcyA9IHNvcnRGaWxlcyhmaWxlcywgeWFtbCwgcGx1Z2luKTtcclxuXHRjb25zdCB1bCA9IGxpc3QuY3JlYXRlRWwoJ3VsJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdCcgfSk7XHJcblx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdGNvbnN0IGZvbGRlckl0ZW0gPSBhZGRGb2xkZXJMaXN0KHBsdWdpbiwgdWwsIHBhdGhCbGFja2xpc3QsIGZpbGUpO1xyXG5cdFx0XHRnb1Rocm91Z2hGb2xkZXJzKHBsdWdpbiwgZm9sZGVySXRlbSwgZmlsZSwgZGVwdGgsIHNvdXJjZUZvbGRlclBhdGgsIGN0eCwgeWFtbCwgcGF0aEJsYWNrbGlzdCwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHR9IGVsc2UgaWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRhZGRGaWxlTGlzdChwbHVnaW4sIHVsLCBwYXRoQmxhY2tsaXN0LCBmaWxlLCBpbmNsdWRlVHlwZXMsIGRpc2FibGVGaWxlVGFnKTtcclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gc29ydEZpbGVzKGZpbGVzOiBUQWJzdHJhY3RGaWxlW10sIHlhbWw6IHlhbWxTZXR0aW5ncywgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdGlmICgheWFtbD8uc29ydEJ5KSB7XHJcblx0XHR5YW1sLnNvcnRCeSA9IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc29ydEJ5IHx8ICduYW1lJztcclxuXHR9XHJcblx0cmV0dXJuIGZpbGVzLnNvcnQoKGEsIGIpID0+IHtcclxuXHRcdC8vIHNvcnQgYnkgZm9sZGVyIGZpcnN0XHJcblx0XHRpZiAoYSBpbnN0YW5jZW9mIFRGb2xkZXIgJiYgIShiIGluc3RhbmNlb2YgVEZvbGRlcikpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCEoYSBpbnN0YW5jZW9mIFRGb2xkZXIpICYmIGIgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdHJldHVybiAxO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCEoYSBpbnN0YW5jZW9mIFRGaWxlKSB8fCAhKGIgaW5zdGFuY2VvZiBURmlsZSkpIHsgcmV0dXJuIC0xOyB9XHJcblx0XHRpZiAoeWFtbC5zb3J0QnkgPT09ICdjcmVhdGVkJykge1xyXG5cdFx0XHRpZiAoYS5zdGF0LmN0aW1lID4gYi5zdGF0LmN0aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGEuc3RhdC5jdGltZSA8IGIuc3RhdC5jdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHlhbWwuc29ydEJ5ID09PSAnY3JlYXRlZEFzYycpIHtcclxuXHRcdFx0aWYgKGEuc3RhdC5jdGltZSA8IGIuc3RhdC5jdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAtMTtcclxuXHRcdFx0fSBlbHNlIGlmIChhLnN0YXQuY3RpbWUgPiBiLnN0YXQuY3RpbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gMTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIGlmICh5YW1sLnNvcnRCeSA9PT0gJ21vZGlmaWVkJykge1xyXG5cdFx0XHRpZiAoYS5zdGF0Lm10aW1lID4gYi5zdGF0Lm10aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGEuc3RhdC5tdGltZSA8IGIuc3RhdC5tdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHlhbWwuc29ydEJ5ID09PSAnbW9kaWZpZWRBc2MnKSB7XHJcblx0XHRcdGlmIChhLnN0YXQubXRpbWUgPCBiLnN0YXQubXRpbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gLTE7XHJcblx0XHRcdH0gZWxzZSBpZiAoYS5zdGF0Lm10aW1lID4gYi5zdGF0Lm10aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIDE7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdC8vIHNvcnQgYnkgbmFtZVxyXG5cdFx0aWYgKGEubmFtZSA8IGIubmFtZSAmJiB5YW1sLnNvcnRCeSA9PT0gJ25hbWUnKSB7XHJcblx0XHRcdHJldHVybiAtMTtcclxuXHRcdH0gZWxzZSBpZiAoYS5uYW1lID4gYi5uYW1lICYmIHlhbWwuc29ydEJ5ID09PSAnbmFtZUFzYycpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChhLm5hbWUgPiBiLm5hbWUgJiYgeWFtbC5zb3J0QnkgPT09ICduYW1lJykge1xyXG5cdFx0XHRyZXR1cm4gMTtcclxuXHRcdH0gZWxzZSBpZiAoYS5uYW1lIDwgYi5uYW1lICYmIHlhbWwuc29ydEJ5ID09PSAnbmFtZUFzYycpIHtcclxuXHRcdFx0cmV0dXJuIDE7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gMDtcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlRW1wdHlGb2xkZXJzKHVsOiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgZGVwdGg6IG51bWJlciwgeWFtbDogeWFtbFNldHRpbmdzKSB7XHJcblx0Y29uc3QgY2hpbGRyZW5zVG9SZW1vdmU6IENoaWxkTm9kZVtdID0gW107XHJcblx0dWwuY2hpbGROb2Rlcy5mb3JFYWNoKChlbCkgPT4ge1xyXG5cdFx0Y29uc3QgY2hpbGRyZW5zID0gKGVsIGFzIEVsZW1lbnQpLnF1ZXJ5U2VsZWN0b3IoJ3VsJyk7XHJcblx0XHRpZiAoIWNoaWxkcmVucyB8fCBjaGlsZHJlbnMgPT09IG51bGwpIHsgcmV0dXJuOyB9XHJcblx0XHRpZiAoY2hpbGRyZW5zICYmICFjaGlsZHJlbnM/Lmhhc0NoaWxkTm9kZXMoKSAmJiAhKGVsIGluc3RhbmNlb2YgSFRNTFVMaXN0RWxlbWVudCkpIHtcclxuXHRcdFx0Y2hpbGRyZW5zVG9SZW1vdmUucHVzaChlbCk7XHJcblx0XHR9IGVsc2UgaWYgKGVsIGluc3RhbmNlb2YgSFRNTFVMaXN0RWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxMSUVsZW1lbnQpIHtcclxuXHRcdFx0cmVtb3ZlRW1wdHlGb2xkZXJzKGVsLCBkZXB0aCArIDEsIHlhbWwpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cdGNoaWxkcmVuc1RvUmVtb3ZlLmZvckVhY2goKGVsKSA9PiB7XHJcblx0XHRpZiAoeWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgJiYgZGVwdGggPT09IDEpIHsgcmV0dXJuOyB9XHJcblx0XHRlbC5yZW1vdmUoKTtcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkRm9sZGVyTGlzdChwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBsaXN0OiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgcGF0aEJsYWNrbGlzdDogc3RyaW5nW10sIGZvbGRlcjogVEZvbGRlcikge1xyXG5cdGNvbnN0IGZvbGRlckl0ZW0gPSBsaXN0LmNyZWF0ZUVsKCdsaScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QgZm9sZGVyLWxpc3QnIH0pO1xyXG5cdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHBsdWdpbiwgZm9sZGVyLnBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdGNvbnN0IGZvbGRlck5vdGVMaW5rID0gZm9sZGVySXRlbS5jcmVhdGVFbCgnYScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QtaXRlbSBmb2xkZXItbmFtZS1pdGVtIGludGVybmFsLWxpbmsnLCBocmVmOiBmb2xkZXJOb3RlLnBhdGggfSk7XHJcblx0XHRmb2xkZXJOb3RlTGluay5pbm5lclRleHQgPSBmb2xkZXIubmFtZTtcclxuXHRcdHBhdGhCbGFja2xpc3QucHVzaChmb2xkZXJOb3RlLnBhdGgpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRjb25zdCBmb2xkZXJOYW1lID0gZm9sZGVySXRlbS5jcmVhdGVFbCgnc3BhbicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QtaXRlbSBmb2xkZXItbmFtZS1pdGVtJyB9KTtcclxuXHRcdGZvbGRlck5hbWUuaW5uZXJUZXh0ID0gZm9sZGVyLm5hbWU7XHJcblx0fVxyXG5cdHJldHVybiBmb2xkZXJJdGVtO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRGaWxlTGlzdChwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBsaXN0OiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgcGF0aEJsYWNrbGlzdDogc3RyaW5nW10sIGZpbGU6IFRGaWxlLCBpbmNsdWRlVHlwZXM6IHN0cmluZ1tdLCBkaXNhYmxlRmlsZVRhZzogYm9vbGVhbikge1xyXG5cdGlmIChpbmNsdWRlVHlwZXMubGVuZ3RoID4gMCAmJiAhaW5jbHVkZVR5cGVzLmluY2x1ZGVzKCdhbGwnKSkge1xyXG5cdFx0aWYgKGZpbGUuZXh0ZW5zaW9uID09PSAnbWQnICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ21hcmtkb3duJykpIHJldHVybjtcclxuXHRcdGlmIChmaWxlLmV4dGVuc2lvbiA9PT0gJ2NhbnZhcycgJiYgIWluY2x1ZGVUeXBlcy5pbmNsdWRlcygnY2FudmFzJykpIHJldHVybjtcclxuXHRcdGlmIChmaWxlLmV4dGVuc2lvbiA9PT0gJ3BkZicgJiYgIWluY2x1ZGVUeXBlcy5pbmNsdWRlcygncGRmJykpIHJldHVybjtcclxuXHRcdGNvbnN0IGltYWdlVHlwZXMgPSBbJ2pwZycsICdqcGVnJywgJ3BuZycsICdnaWYnLCAnc3ZnJywgJ3dlYnAnXTtcclxuXHRcdGlmIChpbWFnZVR5cGVzLmluY2x1ZGVzKGZpbGUuZXh0ZW5zaW9uKSAmJiAhaW5jbHVkZVR5cGVzLmluY2x1ZGVzKCdpbWFnZScpKSByZXR1cm47XHJcblx0XHRjb25zdCB2aWRlb1R5cGVzID0gWydtcDQnLCAnd2VibScsICdvZ3YnLCAnbW92JywgJ21rdiddO1xyXG5cdFx0aWYgKHZpZGVvVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ3ZpZGVvJykpIHJldHVybjtcclxuXHRcdGNvbnN0IGF1ZGlvVHlwZXMgPSBbJ21wMycsICd3YXYnLCAnbTRhJywgJzNncCcsICdmbGFjJywgJ29nZycsICdvZ2EnLCAnb3B1cyddO1xyXG5cdFx0aWYgKGF1ZGlvVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmIGluY2x1ZGVUeXBlcy5pbmNsdWRlcygnYXVkaW8nKSkgcmV0dXJuO1xyXG5cdFx0Y29uc3QgYWxsVHlwZXMgPSBbJ21kJywgJ2NhbnZhcycsICdwZGYnLCAuLi5pbWFnZVR5cGVzLCAuLi52aWRlb1R5cGVzLCAuLi5hdWRpb1R5cGVzXTtcclxuXHRcdGlmICghYWxsVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ290aGVyJykpIHJldHVybjtcclxuXHR9XHJcblx0aWYgKHBhdGhCbGFja2xpc3QuaW5jbHVkZXMoZmlsZS5wYXRoKSkgcmV0dXJuO1xyXG5cdGNvbnN0IGxpc3RJdGVtID0gbGlzdC5jcmVhdGVFbCgnbGknLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1saXN0IGZpbGUtbGluaycgfSk7XHJcblx0Y29uc3QgbmFtZUl0ZW0gPSBsaXN0SXRlbS5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdC1pdGVtJyB9KTtcclxuXHRjb25zdCBsaW5rID0gbmFtZUl0ZW0uY3JlYXRlRWwoJ2EnLCB7IGNsczogJ2ludGVybmFsLWxpbmsnLCBocmVmOiBmaWxlLnBhdGggfSk7XHJcblx0bGluay5pbm5lclRleHQgPSBmaWxlLmJhc2VuYW1lO1xyXG5cdGlmIChmaWxlLmV4dGVuc2lvbiAhPT0gJ21kJyAmJiAhZGlzYWJsZUZpbGVUYWcpIHtcclxuXHRcdG5hbWVJdGVtLmNyZWF0ZURpdih7IGNsczogJ25hdi1maWxlLXRhZycgfSkuaW5uZXJUZXh0ID0gZmlsZS5leHRlbnNpb247XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRBbGxGaWxlcyhmaWxlczogVEFic3RyYWN0RmlsZVtdLCBzb3VyY2VGb2xkZXJQYXRoOiBzdHJpbmcsIGRlcHRoOiBudW1iZXIpIHtcclxuXHRjb25zdCBhbGxGaWxlczogVEFic3RyYWN0RmlsZVtdID0gW107XHJcblx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdGlmICgoZmlsZS5wYXRoLnNwbGl0KCcvJykubGVuZ3RoIC0gc291cmNlRm9sZGVyUGF0aC5zcGxpdCgnLycpLmxlbmd0aCkgLSAxIDwgZGVwdGggLSAxKSB7XHJcblx0XHRcdFx0YWxsRmlsZXMucHVzaCguLi5nZXRBbGxGaWxlcyhmaWxlLmNoaWxkcmVuLCBzb3VyY2VGb2xkZXJQYXRoLCBkZXB0aCkpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRhbGxGaWxlcy5wdXNoKGZpbGUpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cdHJldHVybiBhbGxGaWxlcztcclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZywgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgc3RyaW5naWZ5WWFtbCwgVEZpbGUgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IHlhbWxTZXR0aW5ncyB9IGZyb20gJ3NyYy9mb2xkZXJPdmVydmlldyc7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IExpc3RDb21wb25lbnQgZnJvbSAnc3JjL2Z1bmN0aW9ucy9MaXN0Q29tcG9uZW50JztcclxuZXhwb3J0IGNsYXNzIEZvbGRlck92ZXJ2aWV3U2V0dGluZ3MgZXh0ZW5kcyBNb2RhbCB7XHJcblx0cGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbjtcclxuXHRhcHA6IEFwcDtcclxuXHR5YW1sOiB5YW1sU2V0dGluZ3M7XHJcblx0Y3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0O1xyXG5cdGVsOiBIVE1MRWxlbWVudDtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgeWFtbDogeWFtbFNldHRpbmdzLCBjdHg6IE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIGVsOiBIVE1MRWxlbWVudCkge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLnlhbWwgPSB5YW1sO1xyXG5cdFx0dGhpcy5jdHggPSBjdHg7XHJcblx0XHR0aGlzLmVsID0gZWw7XHJcblx0XHRpZiAoIXRoaXMueWFtbCkge1xyXG5cdFx0XHR0aGlzLnlhbWwgPSB7XHJcblx0XHRcdFx0dGl0bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSxcclxuXHRcdFx0XHRkaXNhYmxlVGl0bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kaXNhYmxlVGl0bGUsXHJcblx0XHRcdFx0ZGVwdGg6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kZXB0aCxcclxuXHRcdFx0XHR0eXBlOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcudHlwZSxcclxuXHRcdFx0XHRpbmNsdWRlVHlwZXM6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5pbmNsdWRlVHlwZXMsXHJcblx0XHRcdFx0c3R5bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5zdHlsZSxcclxuXHRcdFx0XHRkaXNhYmxlRmlsZVRhZzogdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnLFxyXG5cdFx0XHRcdHNvcnRCeTogdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNvcnRCeSxcclxuXHRcdFx0XHRzaG93RW1wdHlGb2xkZXJzOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc2hvd0VtcHR5Rm9sZGVycyxcclxuXHRcdFx0XHRvbmx5SW5jbHVkZVN1YmZvbGRlcnM6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5vbmx5SW5jbHVkZVN1YmZvbGRlcnMsXHJcblx0XHRcdH07XHJcblx0XHR9XHJcblx0fVxyXG5cdG9uT3BlbigpIHtcclxuXHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdH1cclxuXHRkaXNwbGF5KCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcclxuXHRcdC8vIGNsb3NlIHdoZW4gdXNlciBwcmVzc2VzIGVudGVyXHJcblx0XHRjb250ZW50RWwuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XHJcblx0XHRcdGlmIChlLmtleSA9PT0gJ0VudGVyJykge1xyXG5cdFx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnRm9sZGVyIG92ZXJ2aWV3IHNldHRpbmdzJyB9KTtcclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0Rpc2FibGUgdGhlIHRpdGxlJylcclxuXHRcdFx0LnNldERlc2MoJ0Nob29zZSBpZiB0aGUgdGl0bGUgc2hvdWxkIGJlIHNob3duJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5kaXNhYmxlVGl0bGUgfHwgZmFsc2UpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5kaXNhYmxlVGl0bGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdGlmICghdGhpcy55YW1sLmRpc2FibGVUaXRsZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ1RpdGxlJylcclxuXHRcdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHRoZSB0aXRsZSBvZiB0aGUgZm9sZGVyIG92ZXJ2aWV3JylcclxuXHRcdFx0XHQuYWRkVGV4dCgodGV4dCkgPT5cclxuXHRcdFx0XHRcdHRleHRcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8udGl0bGUgfHwgJ3t7Zm9sZGVyTmFtZX19IG92ZXJ2aWV3JylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMueWFtbC50aXRsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblx0XHR9XHJcblx0XHRjb25zdCBzZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGVudEVsKTtcclxuXHRcdHNldHRpbmcuc2V0TmFtZSgnSW5jbHVkZSB0eXBlcycpO1xyXG5cdFx0Y29uc3QgbGlzdCA9IHNldHRpbmcuY3JlYXRlTGlzdCgobGlzdDogTGlzdENvbXBvbmVudCkgPT5cclxuXHRcdFx0bGlzdFxyXG5cdFx0XHRcdC5hZGRNb2RhbCh0aGlzKVxyXG5cdFx0XHRcdC5zZXRWYWx1ZXModGhpcy55YW1sPy5pbmNsdWRlVHlwZXMgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyB8fCBbXSlcclxuXHRcdFx0XHQuYWRkUmVzZXRCdXR0b24oKVxyXG5cdFx0KTtcclxuXHRcdGlmICgodGhpcy55YW1sPy5pbmNsdWRlVHlwZXM/Lmxlbmd0aCB8fCAwKSA8IDggJiYgIXRoaXMueWFtbC5pbmNsdWRlVHlwZXM/LmluY2x1ZGVzKCdhbGwnKSkge1xyXG5cdFx0XHRzZXR0aW5nLmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xyXG5cdFx0XHRcdGlmICghdGhpcy55YW1sLmluY2x1ZGVUeXBlcykgdGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5pbmNsdWRlVHlwZXMgfHwgW107XHJcblx0XHRcdFx0dGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMueWFtbC5pbmNsdWRlVHlwZXMubWFwKCh0eXBlOiBzdHJpbmcpID0+IHR5cGUudG9Mb3dlckNhc2UoKSk7XHJcblx0XHRcdFx0Y29uc3Qgb3B0aW9ucyA9IFtcclxuXHRcdFx0XHRcdHsgdmFsdWU6ICdtYXJrZG93bicsIGxhYmVsOiAnTWFya2Rvd24nIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnZm9sZGVyJywgbGFiZWw6ICdGb2xkZXInIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnY2FudmFzJywgbGFiZWw6ICdDYW52YXMnIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAncGRmJywgbGFiZWw6ICdQREYnIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnaW1hZ2UnLCBsYWJlbDogJ0ltYWdlJyB9LFxyXG5cdFx0XHRcdFx0eyB2YWx1ZTogJ2F1ZGlvJywgbGFiZWw6ICdBdWRpbycgfSxcclxuXHRcdFx0XHRcdHsgdmFsdWU6ICd2aWRlbycsIGxhYmVsOiAnVmlkZW8nIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnb3RoZXInLCBsYWJlbDogJ0FsbCBvdGhlciBmaWxlIHR5cGVzJyB9LFxyXG5cdFx0XHRcdFx0eyB2YWx1ZTogJ2FsbCcsIGxhYmVsOiAnQWxsIGZpbGUgdHlwZXMnIH0sXHJcblx0XHRcdFx0XTtcclxuXHJcblx0XHRcdFx0b3B0aW9ucy5mb3JFYWNoKChvcHRpb24pID0+IHtcclxuXHRcdFx0XHRcdGlmICghdGhpcy55YW1sLmluY2x1ZGVUeXBlcz8uaW5jbHVkZXMob3B0aW9uLnZhbHVlKSkge1xyXG5cdFx0XHRcdFx0XHRkcm9wZG93bi5hZGRPcHRpb24ob3B0aW9uLnZhbHVlLCBvcHRpb24ubGFiZWwpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignKycsICcrJyk7XHJcblx0XHRcdFx0ZHJvcGRvd24uc2V0VmFsdWUoJysnKTtcclxuXHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdGlmICh2YWx1ZSA9PT0gJ2FsbCcpIHtcclxuXHRcdFx0XHRcdFx0dGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMueWFtbC5pbmNsdWRlVHlwZXM/LmZpbHRlcigodHlwZTogc3RyaW5nKSA9PiB0eXBlID09PSAnZm9sZGVyJyk7XHJcblx0XHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdFx0XHRcdFx0bGlzdC5zZXRWYWx1ZXModGhpcy55YW1sLmluY2x1ZGVUeXBlcyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXHJcblx0XHRcdFx0XHRhd2FpdCBsaXN0LmFkZFZhbHVlKHZhbHVlLnRvTG93ZXJDYXNlKCkpO1xyXG5cdFx0XHRcdFx0YXdhaXQgdGhpcy51cGRhdGVZYW1sKCk7XHJcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHRsZXQgZGlzYWJsZUZpbGVUYWc7XHJcblx0XHR0aGlzLnlhbWwuaW5jbHVkZVR5cGVzPy5mb3JFYWNoKCh0eXBlOiBzdHJpbmcpID0+IHtcclxuXHRcdFx0dHlwZSA9PT0gJ2ZvbGRlcicgfHwgdHlwZSA9PT0gJ21hcmtkb3duJyA/IChkaXNhYmxlRmlsZVRhZyA9IHRydWUpIDogbnVsbDtcclxuXHRcdH0pO1xyXG5cdFx0aWYgKGRpc2FibGVGaWxlVGFnKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBmaWxlIHRhZycpXHJcblx0XHRcdFx0LnNldERlc2MoJ0Nob29zZSBpZiB0aGUgZmlsZSB0YWcgc2hvdWxkIGJlIHNob3duIGFmdGVyIHRoZSBmaWxlIG5hbWUnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnlhbWwuZGlzYWJsZUZpbGVUYWcgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnIHx8IGZhbHNlKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy55YW1sLmRpc2FibGVGaWxlVGFnID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy51cGRhdGVZYW1sKCk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0ZpbGUgZGVwdGgnKVxyXG5cdFx0XHQuc2V0RGVzYygnRmlsZSAmIGZvbGRlciA9ICsxIGRlcHRoJylcclxuXHRcdFx0LmFkZFNsaWRlcigoc2xpZGVyKSA9PlxyXG5cdFx0XHRcdHNsaWRlclxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8uZGVwdGggfHwgMilcclxuXHRcdFx0XHRcdC5zZXRMaW1pdHMoMSwgMTAsIDEpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5kZXB0aCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnT3ZlcnZpZXcgc3R5bGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHRoZSBzdHlsZSBvZiB0aGUgb3ZlcnZpZXcgKGdyaWQgc3R5bGUgc29vbiknKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCdsaXN0JywgJ0xpc3QnKVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8uc3R5bGUgfHwgJ2xpc3QnKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogJ2xpc3QnKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5zdHlsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnU29ydCBmaWxlcyBieScpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaG93IHRoZSBmaWxlcyBzaG91bGQgYmUgc29ydGVkJylcclxuXHRcdFx0LmFkZERyb3Bkb3duKChkcm9wZG93bikgPT5cclxuXHRcdFx0XHRkcm9wZG93blxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbmFtZScsICdOYW1lIGRlc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignY3JlYXRlZCcsICdDcmVhdGVkIGRlc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbW9kaWZpZWQnLCAnTW9kaWZpZWQgZGVzY2VuZGluZycpXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCduYW1lQXNjJywgJ05hbWUgYXNjZW5kaW5nJylcclxuXHRcdFx0XHRcdC5hZGRPcHRpb24oJ2NyZWF0ZWRBc2MnLCAnQ3JlYXRlZCBhc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbW9kaWZpZWRBc2MnLCAnTW9kaWZpZWQgYXNjZW5kaW5nJylcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnlhbWw/LnNvcnRCeSB8fCAnbmFtZScpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiAnbmFtZScgfCAnY3JlYXRlZCcgfCAnbW9kaWZpZWQnIHwgJ25hbWVBc2MnIHwgJ2NyZWF0ZWRBc2MnIHwgJ21vZGlmaWVkQXNjJykgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwuc29ydEJ5ID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdTaG93IGZvbGRlciBuYW1lcyBvZiBlbXB0eSBmb2xkZXJzJylcclxuXHRcdFx0LnNldERlc2MoJ1RoYXQgaW5jbHVkZXMgc3ViZm9sZGVycyBvZiB0aGUgY3VycmVudCBmb2xkZXIgd2hlbiB5b3UgYXJlIG9uIGZpbGUgZGVwdGggMScpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5zaG93RW1wdHlGb2xkZXJzIHx8IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5zaG93RW1wdHlGb2xkZXJzIHx8IGZhbHNlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwuc2hvd0VtcHR5Rm9sZGVycyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwub25seUluY2x1ZGVTdWJmb2xkZXJzID0gZmFsc2U7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRpZiAodGhpcy55YW1sLnNob3dFbXB0eUZvbGRlcnMpIHtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdPbmx5IHNob3cgZmlyc3QgZW1wdHkgc3ViZm9sZGVycyBvZiBjdXJyZW50IGZvbGRlcicpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3Lm9ubHlJbmNsdWRlU3ViZm9sZGVycyB8fCBmYWxzZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMueWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG5cdGFzeW5jIHVwZGF0ZVlhbWwoKSB7XHJcblx0XHRjb25zdCBmaWxlID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aCh0aGlzLmN0eC5zb3VyY2VQYXRoKTtcclxuXHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHRcdGxldCBzdHJpbmdZYW1sID0gc3RyaW5naWZ5WWFtbCh0aGlzLnlhbWwpO1xyXG5cdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LnByb2Nlc3MoZmlsZSwgKHRleHQpID0+IHtcclxuXHRcdFx0Y29uc3QgaW5mbyA9IHRoaXMuY3R4LmdldFNlY3Rpb25JbmZvKHRoaXMuZWwpO1xyXG5cdFx0XHQvLyBjaGVjayBpZiBzdHJpbmdZYW1sIGVuZHMgd2l0aCBhIG5ld2xpbmVcclxuXHRcdFx0aWYgKHN0cmluZ1lhbWxbc3RyaW5nWWFtbC5sZW5ndGggLSAxXSAhPT0gJ1xcbicpIHtcclxuXHRcdFx0XHRzdHJpbmdZYW1sICs9ICdcXG4nO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChpbmZvKSB7XHJcblx0XHRcdFx0Y29uc3QgeyBsaW5lU3RhcnQgfSA9IGluZm87XHJcblx0XHRcdFx0Y29uc3QgbGluZUVuZCA9IHRoaXMuZ2V0Q29kZUJsb2NrRW5kTGluZSh0ZXh0LCBsaW5lU3RhcnQpO1xyXG5cdFx0XHRcdGlmIChsaW5lRW5kID09PSAtMSB8fCAhbGluZUVuZCkgcmV0dXJuIHRleHQ7XHJcblx0XHRcdFx0Y29uc3QgbGluZUxlbmd0aCA9IGxpbmVFbmQgLSBsaW5lU3RhcnQ7XHJcblx0XHRcdFx0Y29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcclxuXHRcdFx0XHRsaW5lcy5zcGxpY2UobGluZVN0YXJ0LCBsaW5lTGVuZ3RoICsgMSwgYFxcYFxcYFxcYGZvbGRlci1vdmVydmlld1xcbiR7c3RyaW5nWWFtbH1cXGBcXGBcXGBgKTtcclxuXHRcdFx0XHRyZXR1cm4gbGluZXMuam9pbignXFxuJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGBcXGBcXGBcXGBmb2xkZXItb3ZlcnZpZXdcXG4ke3N0cmluZ1lhbWx9XFxgXFxgXFxgYDtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRnZXRDb2RlQmxvY2tFbmRMaW5lKHRleHQ6IHN0cmluZywgc3RhcnRMaW5lOiBudW1iZXIsIGNvdW50ID0gMSkge1xyXG5cdFx0bGV0IGxpbmUgPSBzdGFydExpbmUgKyAxO1xyXG5cdFx0Y29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcclxuXHRcdHdoaWxlIChsaW5lIDwgbGluZXMubGVuZ3RoKSB7XHJcblx0XHRcdGlmIChjb3VudCA+IDIwKSB7IHJldHVybiAtMTsgfVxyXG5cdFx0XHRpZiAobGluZXNbbGluZV0uc3RhcnRzV2l0aCgnYGBgJykpIHtcclxuXHRcdFx0XHRyZXR1cm4gbGluZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRsaW5lKys7XHJcblx0XHRcdGNvdW50Kys7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbGluZTtcclxuXHR9XHJcbn1cclxuXHJcbiIsICJpbXBvcnQgeyBTZXR0aW5nIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBGb2xkZXJPdmVydmlld1NldHRpbmdzIH0gZnJvbSAnLi4vbW9kYWxzL2ZvbGRlck92ZXJ2aWV3JztcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGlzdENvbXBvbmVudCB7XHJcblx0Y29udGFpbmVyRWw6IEhUTUxFbGVtZW50O1xyXG5cdGNvbnRyb2xFbDogSFRNTEVsZW1lbnQ7XHJcblx0ZW1wdHlTdGF0ZUVsOiBIVE1MRWxlbWVudDtcclxuXHRsaXN0RWw6IEhUTUxFbGVtZW50O1xyXG5cdHZhbHVlczogc3RyaW5nW107XHJcblx0bW9kYWw6IEZvbGRlck92ZXJ2aWV3U2V0dGluZ3M7XHJcblx0Y29uc3RydWN0b3IoY29udGFpbmVyRWw6IEhUTUxFbGVtZW50KSB7XHJcblx0XHR0aGlzLmNvbnRhaW5lckVsID0gY29udGFpbmVyRWw7XHJcblx0XHR0aGlzLmNvbnRyb2xFbCA9IGNvbnRhaW5lckVsLnF1ZXJ5U2VsZWN0b3IoJy5zZXR0aW5nLWl0ZW0tY29udHJvbCcpIHx8IGNvbnRhaW5lckVsO1xyXG5cdFx0dGhpcy5saXN0RWwgPSB0aGlzLmNvbnRyb2xFbC5jcmVhdGVEaXYoJ3NldHRpbmctY29tbWFuZC1ob3RrZXlzJyk7XHJcblx0fVxyXG5cdGFkZE1vZGFsKG1vZGFsOiBGb2xkZXJPdmVydmlld1NldHRpbmdzKSB7XHJcblx0XHR0aGlzLm1vZGFsID0gbW9kYWw7XHJcblx0XHR0aGlzLnZhbHVlcyA9IG1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzIHx8IFtdO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdHNldFZhbHVlcyh2YWx1ZXM6IHN0cmluZ1tdKSB7XHJcblx0XHR0aGlzLmxpc3RFbC5lbXB0eSgpO1xyXG5cdFx0dGhpcy52YWx1ZXMgPSB2YWx1ZXM7XHJcblx0XHR0aGlzLm1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzID0gdmFsdWVzO1xyXG5cdFx0aWYgKHZhbHVlcy5sZW5ndGggIT09IDApIHtcclxuXHRcdFx0dmFsdWVzLmZvckVhY2goKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0dGhpcy5hZGRFbGVtZW50KHZhbHVlKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHR0aGlzLm1vZGFsLnVwZGF0ZVlhbWwoKTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHRhZGRFbGVtZW50KHZhbHVlOiBzdHJpbmcpIHtcclxuXHRcdHRoaXMubGlzdEVsLmNyZWF0ZVNwYW4oJ3NldHRpbmctaG90a2V5JywgKHNwYW4pID0+IHtcclxuXHRcdFx0c3Bhbi5pbm5lclRleHQgPSB2YWx1ZTtcclxuXHRcdFx0Y29uc3QgcmVtb3ZlU3BhbiA9IHNwYW4uY3JlYXRlRWwoJ3NwYW4nLCB7IGNsczogJ29mbi1saXN0LWl0ZW0tcmVtb3ZlIHNldHRpbmctaG90a2V5LWljb24nIH0pO1xyXG5cdFx0XHQvLyBhZGQgc3ZnIGljb25cclxuXHRcdFx0Y29uc3Qgc3ZnID0gJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBjbGFzcz1cInN2Zy1pY29uIGx1Y2lkZS14XCI+PGxpbmUgeDE9XCIxOFwiIHkxPVwiNlwiIHgyPVwiNlwiIHkyPVwiMThcIj48L2xpbmU+PGxpbmUgeDE9XCI2XCIgeTE9XCI2XCIgeDI9XCIxOFwiIHkyPVwiMThcIj48L2xpbmU+PC9zdmc+JztcclxuXHRcdFx0Y29uc3Qgc3ZnRWxlbWVudCA9IHJlbW92ZVNwYW4uY3JlYXRlRWwoJ3NwYW4nLCB7IGNsczogJ29mbi1saXN0LWl0ZW0tcmVtb3ZlLWljb24nIH0pO1xyXG5cdFx0XHRzdmdFbGVtZW50LmlubmVySFRNTCA9IHN2ZztcclxuXHRcdFx0cmVtb3ZlU3Bhbi5vbkNsaWNrRXZlbnQoKGUpID0+IHtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZVZhbHVlKHZhbHVlKTtcclxuXHRcdFx0XHRzcGFuLnJlbW92ZSgpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRhc3luYyBhZGRWYWx1ZSh2YWx1ZTogc3RyaW5nKSB7XHJcblx0XHR0aGlzLnZhbHVlcy5wdXNoKHZhbHVlKTtcclxuXHRcdHRoaXMuYWRkRWxlbWVudCh2YWx1ZSk7XHJcblx0XHR0aGlzLm1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzID0gdGhpcy52YWx1ZXM7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0YWRkUmVzZXRCdXR0b24oKSB7XHJcblx0XHRjb25zdCByZXNldEJ1dHRvbiA9IHRoaXMuY29udHJvbEVsLmNyZWF0ZUVsKCdzcGFuJywgeyBjbHM6ICdjbGlja2FibGUtaWNvbiBzZXR0aW5nLXJlc3RvcmUtaG90a2V5LWJ1dHRvbicgfSk7XHJcblx0XHRjb25zdCBzdmcgPSAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIGNsYXNzPVwic3ZnLWljb24gbHVjaWRlLXJvdGF0ZS1jY3dcIj48cGF0aCBkPVwiTTMgMnY2aDZcIj48L3BhdGg+PHBhdGggZD1cIk0zIDEzYTkgOSAwIDEgMCAzLTcuN0wzIDhcIj48L3BhdGg+PC9zdmc+JztcclxuXHRcdHJlc2V0QnV0dG9uLmlubmVySFRNTCA9IHN2ZztcclxuXHRcdHJlc2V0QnV0dG9uLm9uQ2xpY2tFdmVudCgoZSkgPT4ge1xyXG5cdFx0XHR0aGlzLm1vZGFsLnBsdWdpbi5sb2FkU2V0dGluZ3MoKTtcclxuXHRcdFx0dGhpcy5zZXRWYWx1ZXModGhpcy5tb2RhbC5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyB8fCBbXSk7XHJcblx0XHRcdHRoaXMubW9kYWwuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0cmVtb3ZlVmFsdWUodmFsdWU6IHN0cmluZykge1xyXG5cdFx0dGhpcy52YWx1ZXMgPSB0aGlzLnZhbHVlcy5maWx0ZXIoKHYpID0+IHYgIT09IHZhbHVlKTtcclxuXHRcdHRoaXMuc2V0VmFsdWVzKHRoaXMudmFsdWVzKTtcclxuXHRcdHRoaXMubW9kYWwuZGlzcGxheSgpO1xyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlTGlzdCh0aGlzOiBTZXR0aW5nLCBjYjogKGxpc3Q6IExpc3RDb21wb25lbnQpID0+IExpc3RDb21wb25lbnQpIHtcclxuXHRjb25zdCBsaXN0ID0gbmV3IExpc3RDb21wb25lbnQodGhpcy5zZXR0aW5nRWwpO1xyXG5cdGNiKGxpc3QpO1xyXG5cdHJldHVybiBsaXN0O1xyXG59XHJcblxyXG4vLyBMaXN0Q29tcG9uZW50LnByb3RvdHlwZS5zZXRWYWx1ZXMgPSBzZXRWYWx1ZXM7XHJcbihTZXR0aW5nIGFzIGFueSkucHJvdG90eXBlLmNyZWF0ZUxpc3QgPSBjcmVhdGVMaXN0O1xyXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFDQSxXQUFPLGVBQWUsU0FBUyxjQUFjLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFBQTtBQUFBOzs7QUNENUQ7QUFBQTtBQUFBO0FBQ0EsV0FBTyxlQUFlLFNBQVMsY0FBYyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQUE7QUFBQTs7O0FDRDVEO0FBQUE7QUFBQTtBQUNBLFdBQU8sZUFBZSxTQUFTLGNBQWMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUFBO0FBQUE7OztBQ0Q1RDtBQUFBO0FBQUE7QUFDQSxRQUFJLGtCQUFtQixXQUFRLFFBQUssbUJBQXFCLFFBQU8sU0FBVSxTQUFTLEdB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QUFrQixFQUFFLFFBQVEsQ0FBQyxTQUFTO0FBQ3BELFVBQUksQ0FBRSxpQkFBZ0IsNEJBQVU7QUFBRTtBQUFBLE1BQVE7QUFDMUMsWUFBTSxhQUFhLGNBQWMsTUFBTSxLQUFLLElBQUk7QUFDaEQsVUFBSSxDQUFDLFlBQVk7QUFDaEIsYUFBSyxxQkFBcUIsNkJBQU0sTUFBTSxpQkFBaUI7QUFDdkQ7QUFBQSxNQUNEO0FBRUEsWUFBTSxpQkFBaUIsa0JBQWtCLE1BQU0sS0FBSyxJQUFJO0FBR3hELFVBQUksaURBQWdCLG1CQUFtQjtBQUN0QyxhQUFLLHFCQUFxQixXQUFXLE1BQU0sZ0JBQWdCO0FBQzNELGFBQUsscUJBQXFCLEtBQUssTUFBTSxpQkFBaUI7QUFBQSxNQUN2RCxPQUFPO0FBQ04sYUFBSyxxQkFBcUIsV0FBVyxNQUFNLGdCQUFnQjtBQUMzRCxhQUFLLHFCQUFxQixLQUFLLE1BQU0saUJBQWlCO0FBQUEsTUFDdkQ7QUFBQSxJQUNELENBQUM7QUFBQSxFQUNGO0FBQUEsRUFFQSxpQkFBaUI7QUFDaEIsYUFBUyxpQkFBaUIsOEJBQThCLEVBQ3RELFFBQVEsQ0FBQyxZQUF5QjtBQUNsQyxVQUFJLFFBQVE7QUFBUztBQUNyQixjQUFRLFVBQVUsQ0FBQyxVQUFzQixrQkFBa0IsT0FBTyxJQUFJO0FBQUEsSUFDdkUsQ0FBQztBQUFBLEVBQ0g7QUFBQSxFQUVBLFdBQVc7QUFDVixZQUFRLElBQUksK0JBQStCO0FBQzNDLFNBQUssU0FBUyxXQUFXO0FBQ3pCLGFBQVMsS0FBSyxVQUFVLE9BQU8scUJBQXFCO0FBQ3BELGFBQVMsS0FBSyxVQUFVLE9BQU8sdUJBQXVCO0FBQ3RELGFBQVMsS0FBSyxVQUFVLE9BQU8sa0JBQWtCO0FBQ2pELGFBQVMsS0FBSyxVQUFVLE9BQU8sK0JBQStCO0FBQzlELFFBQUksS0FBSyxpQkFBaUI7QUFBRSxXQUFLLGdCQUFnQixZQUFZLFdBQVc7QUFBQSxJQUFHO0FBQzNFLFFBQUksS0FBSyxhQUFhO0FBQ3JCLFdBQUssWUFBWSxZQUFZO0FBQUEsSUFDOUI7QUFBQSxFQUVEO0FBQUEsRUFFQSxNQUFNLGVBQWU7QUFDcEIsU0FBSyxXQUFXLE9BQU8sT0FBTyxDQUFDLEdBQUcsa0JBQWtCLE1BQU0sS0FBSyxTQUFTLENBQUM7QUFBQSxFQUMxRTtBQUFBLEVBRUEsTUFBTSxlQUFlO0FBQ3BCLFVBQU0sS0FBSyxTQUFTLEtBQUssUUFBUTtBQUVqQyxTQUFLLGdCQUFnQixJQUFJO0FBQUEsRUFDMUI7QUFDRDsiLAogICJuYW1lcyI6IFtdCn0K
From e04f41d25fc411ddb8836df86e48a94ee5fbeec4 Mon Sep 17 00:00:00 2001
From: Lost Paul <70213368+LostPaul@users.noreply.github.com>
Date: Tue, 1 Aug 2023 21:44:42 +0200
Subject: [PATCH 2/2] Delete main.js
---
main.js | 4250 -------------------------------------------------------
1 file changed, 4250 deletions(-)
delete mode 100644 main.js
diff --git a/main.js b/main.js
deleted file mode 100644
index 9d02e2e..0000000
--- a/main.js
+++ /dev/null
@@ -1,4250 +0,0 @@
-/*
-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 __commonJS = (cb, mod) => function __require() {
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
-};
-var __export = (target, all) => {
- for (var name in all)
- __defProp(target, name, { get: all[name], enumerable: true });
-};
-var __copyProps = (to, from, except, desc) => {
- if (from && typeof from === "object" || typeof from === "function") {
- for (let key of __getOwnPropNames(from))
- if (!__hasOwnProp.call(to, key) && key !== except)
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
- }
- return to;
-};
-var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
-var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
-
-// node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js
-var require_Api = __commonJS({
- "node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js"(exports) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- }
-});
-
-// node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js
-var require_EventDispatcher = __commonJS({
- "node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js"(exports) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- }
-});
-
-// node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js
-var require_Resolver = __commonJS({
- "node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js"(exports) {
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- }
-});
-
-// node_modules/front-matter-plugin-api-provider/lib/index.js
-var require_lib = __commonJS({
- "node_modules/front-matter-plugin-api-provider/lib/index.js"(exports) {
- "use strict";
- var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
- if (k2 === void 0)
- k2 = k;
- var desc = Object.getOwnPropertyDescriptor(m, k);
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
- desc = { enumerable: true, get: function() {
- return m[k];
- } };
- }
- Object.defineProperty(o, k2, desc);
- } : function(o, m, k, k2) {
- if (k2 === void 0)
- k2 = k;
- o[k2] = m[k];
- });
- var __exportStar = exports && exports.__exportStar || function(m, exports2) {
- for (var p in m)
- if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
- __createBinding(exports2, m, p);
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.getApiSafe = exports.getDefer = exports.isPluginEnabled = exports.PluginNotEnabledError = exports.pluginId = void 0;
- __exportStar(require_Api(), exports);
- __exportStar(require_EventDispatcher(), exports);
- __exportStar(require_Resolver(), exports);
- exports.pluginId = "obsidian-front-matter-title-plugin";
- var PluginNotEnabledError = class extends Error {
- };
- exports.PluginNotEnabledError = PluginNotEnabledError;
- function isPluginEnabled(app2) {
- var _a, _b, _c;
- return (_c = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.enabledPlugins) === null || _b === void 0 ? void 0 : _b.has(exports.pluginId)) !== null && _c !== void 0 ? _c : false;
- }
- exports.isPluginEnabled = isPluginEnabled;
- function getDefer2(app2) {
- var _a, _b, _c, _d;
- const plugin = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.getPlugin(exports.pluginId)) !== null && _b !== void 0 ? _b : null;
- const defer = (_d = (_c = plugin === null || plugin === void 0 ? void 0 : plugin.getDefer) === null || _c === void 0 ? void 0 : _c.call(plugin)) !== null && _d !== void 0 ? _d : null;
- if (defer === null) {
- throw new PluginNotEnabledError(`Plugin ${exports.pluginId} is not enabled or old version`);
- }
- return defer;
- }
- exports.getDefer = getDefer2;
- function getApiSafe(app2) {
- return new ApiWrapper(null, app2);
- }
- exports.getApiSafe = getApiSafe;
- var ApiWrapper = class {
- constructor(api, app2) {
- this.api = api;
- this.app = app2;
- }
- before() {
- if (this.api !== null) {
- return;
- }
- const defer = this.getDeffer();
- if (defer === null) {
- return;
- }
- const api = defer.getApi();
- if (api === null) {
- return defer.awaitPlugin().then(() => {
- this.api = defer.getApi();
- });
- } else {
- this.api = api;
- }
- }
- getDeffer() {
- try {
- return getDefer2(this.app);
- } catch (e) {
- if (e instanceof PluginNotEnabledError) {
- return null;
- }
- throw e;
- }
- }
- getResolverFactory() {
- var _a, _b;
- this.before();
- return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getResolverFactory()) !== null && _b !== void 0 ? _b : null;
- }
- getEventDispatcher() {
- var _a, _b;
- this.before();
- return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEventDispatcher()) !== null && _b !== void 0 ? _b : null;
- }
- getEnabledFeatures() {
- var _a, _b;
- this.before();
- return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEnabledFeatures()) !== null && _b !== void 0 ? _b : [];
- }
- };
- }
-});
-
-// src/main.ts
-var main_exports = {};
-__export(main_exports, {
- default: () => FolderNotesPlugin
-});
-module.exports = __toCommonJS(main_exports);
-var import_obsidian19 = require("obsidian");
-
-// src/settings.ts
-var import_obsidian12 = require("obsidian");
-
-// src/suggesters/templateSuggester.ts
-var import_obsidian3 = require("obsidian");
-
-// src/suggesters/suggest.ts
-var import_obsidian = require("obsidian");
-
-// node_modules/@popperjs/core/lib/enums.js
-var top = "top";
-var bottom = "bottom";
-var right = "right";
-var left = "left";
-var auto = "auto";
-var basePlacements = [top, bottom, right, left];
-var start = "start";
-var end = "end";
-var clippingParents = "clippingParents";
-var viewport = "viewport";
-var popper = "popper";
-var reference = "reference";
-var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) {
- return acc.concat([placement + "-" + start, placement + "-" + end]);
-}, []);
-var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) {
- return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
-}, []);
-var beforeRead = "beforeRead";
-var read = "read";
-var afterRead = "afterRead";
-var beforeMain = "beforeMain";
-var main = "main";
-var afterMain = "afterMain";
-var beforeWrite = "beforeWrite";
-var write = "write";
-var afterWrite = "afterWrite";
-var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];
-
-// node_modules/@popperjs/core/lib/dom-utils/getNodeName.js
-function getNodeName(element) {
- return element ? (element.nodeName || "").toLowerCase() : null;
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getWindow.js
-function getWindow(node) {
- if (node == null) {
- return window;
- }
- if (node.toString() !== "[object Window]") {
- var ownerDocument = node.ownerDocument;
- return ownerDocument ? ownerDocument.defaultView || window : window;
- }
- return node;
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/instanceOf.js
-function isElement(node) {
- var OwnElement = getWindow(node).Element;
- return node instanceof OwnElement || node instanceof Element;
-}
-function isHTMLElement(node) {
- var OwnElement = getWindow(node).HTMLElement;
- return node instanceof OwnElement || node instanceof HTMLElement;
-}
-function isShadowRoot(node) {
- if (typeof ShadowRoot === "undefined") {
- return false;
- }
- var OwnElement = getWindow(node).ShadowRoot;
- return node instanceof OwnElement || node instanceof ShadowRoot;
-}
-
-// node_modules/@popperjs/core/lib/modifiers/applyStyles.js
-function applyStyles(_ref) {
- var state = _ref.state;
- Object.keys(state.elements).forEach(function(name) {
- var style = state.styles[name] || {};
- var attributes = state.attributes[name] || {};
- var element = state.elements[name];
- if (!isHTMLElement(element) || !getNodeName(element)) {
- return;
- }
- Object.assign(element.style, style);
- Object.keys(attributes).forEach(function(name2) {
- var value = attributes[name2];
- if (value === false) {
- element.removeAttribute(name2);
- } else {
- element.setAttribute(name2, value === true ? "" : value);
- }
- });
- });
-}
-function effect(_ref2) {
- var state = _ref2.state;
- var initialStyles = {
- popper: {
- position: state.options.strategy,
- left: "0",
- top: "0",
- margin: "0"
- },
- arrow: {
- position: "absolute"
- },
- reference: {}
- };
- Object.assign(state.elements.popper.style, initialStyles.popper);
- state.styles = initialStyles;
- if (state.elements.arrow) {
- Object.assign(state.elements.arrow.style, initialStyles.arrow);
- }
- return function() {
- Object.keys(state.elements).forEach(function(name) {
- var element = state.elements[name];
- var attributes = state.attributes[name] || {};
- var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]);
- var style = styleProperties.reduce(function(style2, property) {
- style2[property] = "";
- return style2;
- }, {});
- if (!isHTMLElement(element) || !getNodeName(element)) {
- return;
- }
- Object.assign(element.style, style);
- Object.keys(attributes).forEach(function(attribute) {
- element.removeAttribute(attribute);
- });
- });
- };
-}
-var applyStyles_default = {
- name: "applyStyles",
- enabled: true,
- phase: "write",
- fn: applyStyles,
- effect,
- requires: ["computeStyles"]
-};
-
-// node_modules/@popperjs/core/lib/utils/getBasePlacement.js
-function getBasePlacement(placement) {
- return placement.split("-")[0];
-}
-
-// node_modules/@popperjs/core/lib/utils/math.js
-var max = Math.max;
-var min = Math.min;
-var round = Math.round;
-
-// node_modules/@popperjs/core/lib/utils/userAgent.js
-function getUAString() {
- var uaData = navigator.userAgentData;
- if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {
- return uaData.brands.map(function(item) {
- return item.brand + "/" + item.version;
- }).join(" ");
- }
- return navigator.userAgent;
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js
-function isLayoutViewport() {
- return !/^((?!chrome|android).)*safari/i.test(getUAString());
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js
-function getBoundingClientRect(element, includeScale, isFixedStrategy) {
- if (includeScale === void 0) {
- includeScale = false;
- }
- if (isFixedStrategy === void 0) {
- isFixedStrategy = false;
- }
- var clientRect = element.getBoundingClientRect();
- var scaleX = 1;
- var scaleY = 1;
- if (includeScale && isHTMLElement(element)) {
- scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
- scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
- }
- var _ref = isElement(element) ? getWindow(element) : window, visualViewport = _ref.visualViewport;
- var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
- var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;
- var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;
- var width = clientRect.width / scaleX;
- var height = clientRect.height / scaleY;
- return {
- width,
- height,
- top: y,
- right: x + width,
- bottom: y + height,
- left: x,
- x,
- y
- };
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js
-function getLayoutRect(element) {
- var clientRect = getBoundingClientRect(element);
- var width = element.offsetWidth;
- var height = element.offsetHeight;
- if (Math.abs(clientRect.width - width) <= 1) {
- width = clientRect.width;
- }
- if (Math.abs(clientRect.height - height) <= 1) {
- height = clientRect.height;
- }
- return {
- x: element.offsetLeft,
- y: element.offsetTop,
- width,
- height
- };
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/contains.js
-function contains(parent, child) {
- var rootNode = child.getRootNode && child.getRootNode();
- if (parent.contains(child)) {
- return true;
- } else if (rootNode && isShadowRoot(rootNode)) {
- var next = child;
- do {
- if (next && parent.isSameNode(next)) {
- return true;
- }
- next = next.parentNode || next.host;
- } while (next);
- }
- return false;
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js
-function getComputedStyle(element) {
- return getWindow(element).getComputedStyle(element);
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/isTableElement.js
-function isTableElement(element) {
- return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0;
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js
-function getDocumentElement(element) {
- return ((isElement(element) ? element.ownerDocument : element.document) || window.document).documentElement;
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getParentNode.js
-function getParentNode(element) {
- if (getNodeName(element) === "html") {
- return element;
- }
- return element.assignedSlot || element.parentNode || (isShadowRoot(element) ? element.host : null) || getDocumentElement(element);
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js
-function getTrueOffsetParent(element) {
- if (!isHTMLElement(element) || getComputedStyle(element).position === "fixed") {
- return null;
- }
- return element.offsetParent;
-}
-function getContainingBlock(element) {
- var isFirefox = /firefox/i.test(getUAString());
- var isIE = /Trident/i.test(getUAString());
- if (isIE && isHTMLElement(element)) {
- var elementCss = getComputedStyle(element);
- if (elementCss.position === "fixed") {
- return null;
- }
- }
- var currentNode = getParentNode(element);
- if (isShadowRoot(currentNode)) {
- currentNode = currentNode.host;
- }
- while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) {
- var css = getComputedStyle(currentNode);
- if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") {
- return currentNode;
- } else {
- currentNode = currentNode.parentNode;
- }
- }
- return null;
-}
-function getOffsetParent(element) {
- var window2 = getWindow(element);
- var offsetParent = getTrueOffsetParent(element);
- while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === "static") {
- offsetParent = getTrueOffsetParent(offsetParent);
- }
- if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle(offsetParent).position === "static")) {
- return window2;
- }
- return offsetParent || getContainingBlock(element) || window2;
-}
-
-// node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js
-function getMainAxisFromPlacement(placement) {
- return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y";
-}
-
-// node_modules/@popperjs/core/lib/utils/within.js
-function within(min2, value, max2) {
- return max(min2, min(value, max2));
-}
-function withinMaxClamp(min2, value, max2) {
- var v = within(min2, value, max2);
- return v > max2 ? max2 : v;
-}
-
-// node_modules/@popperjs/core/lib/utils/getFreshSideObject.js
-function getFreshSideObject() {
- return {
- top: 0,
- right: 0,
- bottom: 0,
- left: 0
- };
-}
-
-// node_modules/@popperjs/core/lib/utils/mergePaddingObject.js
-function mergePaddingObject(paddingObject) {
- return Object.assign({}, getFreshSideObject(), paddingObject);
-}
-
-// node_modules/@popperjs/core/lib/utils/expandToHashMap.js
-function expandToHashMap(value, keys) {
- return keys.reduce(function(hashMap, key) {
- hashMap[key] = value;
- return hashMap;
- }, {});
-}
-
-// node_modules/@popperjs/core/lib/modifiers/arrow.js
-var toPaddingObject = function toPaddingObject2(padding, state) {
- padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, {
- placement: state.placement
- })) : padding;
- return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements));
-};
-function arrow(_ref) {
- var _state$modifiersData$;
- var state = _ref.state, name = _ref.name, options = _ref.options;
- var arrowElement = state.elements.arrow;
- var popperOffsets2 = state.modifiersData.popperOffsets;
- var basePlacement = getBasePlacement(state.placement);
- var axis = getMainAxisFromPlacement(basePlacement);
- var isVertical = [left, right].indexOf(basePlacement) >= 0;
- var len = isVertical ? "height" : "width";
- if (!arrowElement || !popperOffsets2) {
- return;
- }
- var paddingObject = toPaddingObject(options.padding, state);
- var arrowRect = getLayoutRect(arrowElement);
- var minProp = axis === "y" ? top : left;
- var maxProp = axis === "y" ? bottom : right;
- var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len];
- var startDiff = popperOffsets2[axis] - state.rects.reference[axis];
- var arrowOffsetParent = getOffsetParent(arrowElement);
- var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
- var centerToReference = endDiff / 2 - startDiff / 2;
- var min2 = paddingObject[minProp];
- var max2 = clientSize - arrowRect[len] - paddingObject[maxProp];
- var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
- var offset2 = within(min2, center, max2);
- var axisProp = axis;
- state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$);
-}
-function effect2(_ref2) {
- var state = _ref2.state, options = _ref2.options;
- var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element;
- if (arrowElement == null) {
- return;
- }
- if (typeof arrowElement === "string") {
- arrowElement = state.elements.popper.querySelector(arrowElement);
- if (!arrowElement) {
- return;
- }
- }
- if (!contains(state.elements.popper, arrowElement)) {
- return;
- }
- state.elements.arrow = arrowElement;
-}
-var arrow_default = {
- name: "arrow",
- enabled: true,
- phase: "main",
- fn: arrow,
- effect: effect2,
- requires: ["popperOffsets"],
- requiresIfExists: ["preventOverflow"]
-};
-
-// node_modules/@popperjs/core/lib/utils/getVariation.js
-function getVariation(placement) {
- return placement.split("-")[1];
-}
-
-// node_modules/@popperjs/core/lib/modifiers/computeStyles.js
-var unsetSides = {
- top: "auto",
- right: "auto",
- bottom: "auto",
- left: "auto"
-};
-function roundOffsetsByDPR(_ref, win) {
- var x = _ref.x, y = _ref.y;
- var dpr = win.devicePixelRatio || 1;
- return {
- x: round(x * dpr) / dpr || 0,
- y: round(y * dpr) / dpr || 0
- };
-}
-function mapToStyles(_ref2) {
- var _Object$assign2;
- var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed;
- var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y;
- var _ref3 = typeof roundOffsets === "function" ? roundOffsets({
- x,
- y
- }) : {
- x,
- y
- };
- x = _ref3.x;
- y = _ref3.y;
- var hasX = offsets.hasOwnProperty("x");
- var hasY = offsets.hasOwnProperty("y");
- var sideX = left;
- var sideY = top;
- var win = window;
- if (adaptive) {
- var offsetParent = getOffsetParent(popper2);
- var heightProp = "clientHeight";
- var widthProp = "clientWidth";
- if (offsetParent === getWindow(popper2)) {
- offsetParent = getDocumentElement(popper2);
- if (getComputedStyle(offsetParent).position !== "static" && position === "absolute") {
- heightProp = "scrollHeight";
- widthProp = "scrollWidth";
- }
- }
- offsetParent = offsetParent;
- if (placement === top || (placement === left || placement === right) && variation === end) {
- sideY = bottom;
- var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : offsetParent[heightProp];
- y -= offsetY - popperRect.height;
- y *= gpuAcceleration ? 1 : -1;
- }
- if (placement === left || (placement === top || placement === bottom) && variation === end) {
- sideX = right;
- var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : offsetParent[widthProp];
- x -= offsetX - popperRect.width;
- x *= gpuAcceleration ? 1 : -1;
- }
- }
- var commonStyles = Object.assign({
- position
- }, adaptive && unsetSides);
- var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
- x,
- y
- }, getWindow(popper2)) : {
- x,
- y
- };
- x = _ref4.x;
- y = _ref4.y;
- if (gpuAcceleration) {
- var _Object$assign;
- return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
- }
- return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2));
-}
-function computeStyles(_ref5) {
- var state = _ref5.state, options = _ref5.options;
- var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
- var commonStyles = {
- placement: getBasePlacement(state.placement),
- variation: getVariation(state.placement),
- popper: state.elements.popper,
- popperRect: state.rects.popper,
- gpuAcceleration,
- isFixed: state.options.strategy === "fixed"
- };
- if (state.modifiersData.popperOffsets != null) {
- state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
- offsets: state.modifiersData.popperOffsets,
- position: state.options.strategy,
- adaptive,
- roundOffsets
- })));
- }
- if (state.modifiersData.arrow != null) {
- state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
- offsets: state.modifiersData.arrow,
- position: "absolute",
- adaptive: false,
- roundOffsets
- })));
- }
- state.attributes.popper = Object.assign({}, state.attributes.popper, {
- "data-popper-placement": state.placement
- });
-}
-var computeStyles_default = {
- name: "computeStyles",
- enabled: true,
- phase: "beforeWrite",
- fn: computeStyles,
- data: {}
-};
-
-// node_modules/@popperjs/core/lib/modifiers/eventListeners.js
-var passive = {
- passive: true
-};
-function effect3(_ref) {
- var state = _ref.state, instance = _ref.instance, options = _ref.options;
- var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize;
- var window2 = getWindow(state.elements.popper);
- var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
- if (scroll) {
- scrollParents.forEach(function(scrollParent) {
- scrollParent.addEventListener("scroll", instance.update, passive);
- });
- }
- if (resize) {
- window2.addEventListener("resize", instance.update, passive);
- }
- return function() {
- if (scroll) {
- scrollParents.forEach(function(scrollParent) {
- scrollParent.removeEventListener("scroll", instance.update, passive);
- });
- }
- if (resize) {
- window2.removeEventListener("resize", instance.update, passive);
- }
- };
-}
-var eventListeners_default = {
- name: "eventListeners",
- enabled: true,
- phase: "write",
- fn: function fn() {
- },
- effect: effect3,
- data: {}
-};
-
-// node_modules/@popperjs/core/lib/utils/getOppositePlacement.js
-var hash = {
- left: "right",
- right: "left",
- bottom: "top",
- top: "bottom"
-};
-function getOppositePlacement(placement) {
- return placement.replace(/left|right|bottom|top/g, function(matched) {
- return hash[matched];
- });
-}
-
-// node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js
-var hash2 = {
- start: "end",
- end: "start"
-};
-function getOppositeVariationPlacement(placement) {
- return placement.replace(/start|end/g, function(matched) {
- return hash2[matched];
- });
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js
-function getWindowScroll(node) {
- var win = getWindow(node);
- var scrollLeft = win.pageXOffset;
- var scrollTop = win.pageYOffset;
- return {
- scrollLeft,
- scrollTop
- };
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js
-function getWindowScrollBarX(element) {
- return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js
-function getViewportRect(element, strategy) {
- var win = getWindow(element);
- var html = getDocumentElement(element);
- var visualViewport = win.visualViewport;
- var width = html.clientWidth;
- var height = html.clientHeight;
- var x = 0;
- var y = 0;
- if (visualViewport) {
- width = visualViewport.width;
- height = visualViewport.height;
- var layoutViewport = isLayoutViewport();
- if (layoutViewport || !layoutViewport && strategy === "fixed") {
- x = visualViewport.offsetLeft;
- y = visualViewport.offsetTop;
- }
- }
- return {
- width,
- height,
- x: x + getWindowScrollBarX(element),
- y
- };
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js
-function getDocumentRect(element) {
- var _element$ownerDocumen;
- var html = getDocumentElement(element);
- var winScroll = getWindowScroll(element);
- var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
- var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
- var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
- var x = -winScroll.scrollLeft + getWindowScrollBarX(element);
- var y = -winScroll.scrollTop;
- if (getComputedStyle(body || html).direction === "rtl") {
- x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
- }
- return {
- width,
- height,
- x,
- y
- };
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js
-function isScrollParent(element) {
- var _getComputedStyle = getComputedStyle(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY;
- return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js
-function getScrollParent(node) {
- if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) {
- return node.ownerDocument.body;
- }
- if (isHTMLElement(node) && isScrollParent(node)) {
- return node;
- }
- return getScrollParent(getParentNode(node));
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js
-function listScrollParents(element, list) {
- var _element$ownerDocumen;
- if (list === void 0) {
- list = [];
- }
- var scrollParent = getScrollParent(element);
- var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
- var win = getWindow(scrollParent);
- var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
- var updatedList = list.concat(target);
- return isBody ? updatedList : updatedList.concat(listScrollParents(getParentNode(target)));
-}
-
-// node_modules/@popperjs/core/lib/utils/rectToClientRect.js
-function rectToClientRect(rect) {
- return Object.assign({}, rect, {
- left: rect.x,
- top: rect.y,
- right: rect.x + rect.width,
- bottom: rect.y + rect.height
- });
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js
-function getInnerBoundingClientRect(element, strategy) {
- var rect = getBoundingClientRect(element, false, strategy === "fixed");
- rect.top = rect.top + element.clientTop;
- rect.left = rect.left + element.clientLeft;
- rect.bottom = rect.top + element.clientHeight;
- rect.right = rect.left + element.clientWidth;
- rect.width = element.clientWidth;
- rect.height = element.clientHeight;
- rect.x = rect.left;
- rect.y = rect.top;
- return rect;
-}
-function getClientRectFromMixedType(element, clippingParent, strategy) {
- return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
-}
-function getClippingParents(element) {
- var clippingParents2 = listScrollParents(getParentNode(element));
- var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle(element).position) >= 0;
- var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
- if (!isElement(clipperElement)) {
- return [];
- }
- return clippingParents2.filter(function(clippingParent) {
- return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body";
- });
-}
-function getClippingRect(element, boundary, rootBoundary, strategy) {
- var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary);
- var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]);
- var firstClippingParent = clippingParents2[0];
- var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) {
- var rect = getClientRectFromMixedType(element, clippingParent, strategy);
- accRect.top = max(rect.top, accRect.top);
- accRect.right = min(rect.right, accRect.right);
- accRect.bottom = min(rect.bottom, accRect.bottom);
- accRect.left = max(rect.left, accRect.left);
- return accRect;
- }, getClientRectFromMixedType(element, firstClippingParent, strategy));
- clippingRect.width = clippingRect.right - clippingRect.left;
- clippingRect.height = clippingRect.bottom - clippingRect.top;
- clippingRect.x = clippingRect.left;
- clippingRect.y = clippingRect.top;
- return clippingRect;
-}
-
-// node_modules/@popperjs/core/lib/utils/computeOffsets.js
-function computeOffsets(_ref) {
- var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement;
- var basePlacement = placement ? getBasePlacement(placement) : null;
- var variation = placement ? getVariation(placement) : null;
- var commonX = reference2.x + reference2.width / 2 - element.width / 2;
- var commonY = reference2.y + reference2.height / 2 - element.height / 2;
- var offsets;
- switch (basePlacement) {
- case top:
- offsets = {
- x: commonX,
- y: reference2.y - element.height
- };
- break;
- case bottom:
- offsets = {
- x: commonX,
- y: reference2.y + reference2.height
- };
- break;
- case right:
- offsets = {
- x: reference2.x + reference2.width,
- y: commonY
- };
- break;
- case left:
- offsets = {
- x: reference2.x - element.width,
- y: commonY
- };
- break;
- default:
- offsets = {
- x: reference2.x,
- y: reference2.y
- };
- }
- var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;
- if (mainAxis != null) {
- var len = mainAxis === "y" ? "height" : "width";
- switch (variation) {
- case start:
- offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2);
- break;
- case end:
- offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2);
- break;
- default:
- }
- }
- return offsets;
-}
-
-// node_modules/@popperjs/core/lib/utils/detectOverflow.js
-function detectOverflow(state, options) {
- if (options === void 0) {
- options = {};
- }
- var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$strategy = _options.strategy, strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding;
- var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements));
- var altContext = elementContext === popper ? reference : popper;
- var popperRect = state.rects.popper;
- var element = state.elements[altBoundary ? altContext : elementContext];
- var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);
- var referenceClientRect = getBoundingClientRect(state.elements.reference);
- var popperOffsets2 = computeOffsets({
- reference: referenceClientRect,
- element: popperRect,
- strategy: "absolute",
- placement
- });
- var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2));
- var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect;
- var overflowOffsets = {
- top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
- bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
- left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
- right: elementClientRect.right - clippingClientRect.right + paddingObject.right
- };
- var offsetData = state.modifiersData.offset;
- if (elementContext === popper && offsetData) {
- var offset2 = offsetData[placement];
- Object.keys(overflowOffsets).forEach(function(key) {
- var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
- var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x";
- overflowOffsets[key] += offset2[axis] * multiply;
- });
- }
- return overflowOffsets;
-}
-
-// node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js
-function computeAutoPlacement(state, options) {
- if (options === void 0) {
- options = {};
- }
- var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;
- var variation = getVariation(placement);
- var placements2 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) {
- return getVariation(placement2) === variation;
- }) : basePlacements;
- var allowedPlacements = placements2.filter(function(placement2) {
- return allowedAutoPlacements.indexOf(placement2) >= 0;
- });
- if (allowedPlacements.length === 0) {
- allowedPlacements = placements2;
- }
- var overflows = allowedPlacements.reduce(function(acc, placement2) {
- acc[placement2] = detectOverflow(state, {
- placement: placement2,
- boundary,
- rootBoundary,
- padding
- })[getBasePlacement(placement2)];
- return acc;
- }, {});
- return Object.keys(overflows).sort(function(a, b) {
- return overflows[a] - overflows[b];
- });
-}
-
-// node_modules/@popperjs/core/lib/modifiers/flip.js
-function getExpandedFallbackPlacements(placement) {
- if (getBasePlacement(placement) === auto) {
- return [];
- }
- var oppositePlacement = getOppositePlacement(placement);
- return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
-}
-function flip(_ref) {
- var state = _ref.state, options = _ref.options, name = _ref.name;
- if (state.modifiersData[name]._skip) {
- return;
- }
- var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements;
- var preferredPlacement = state.options.placement;
- var basePlacement = getBasePlacement(preferredPlacement);
- var isBasePlacement = basePlacement === preferredPlacement;
- var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
- var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) {
- return acc.concat(getBasePlacement(placement2) === auto ? computeAutoPlacement(state, {
- placement: placement2,
- boundary,
- rootBoundary,
- padding,
- flipVariations,
- allowedAutoPlacements
- }) : placement2);
- }, []);
- var referenceRect = state.rects.reference;
- var popperRect = state.rects.popper;
- var checksMap = /* @__PURE__ */ new Map();
- var makeFallbackChecks = true;
- var firstFittingPlacement = placements2[0];
- for (var i = 0; i < placements2.length; i++) {
- var placement = placements2[i];
- var _basePlacement = getBasePlacement(placement);
- var isStartVariation = getVariation(placement) === start;
- var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
- var len = isVertical ? "width" : "height";
- var overflow = detectOverflow(state, {
- placement,
- boundary,
- rootBoundary,
- altBoundary,
- padding
- });
- var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;
- if (referenceRect[len] > popperRect[len]) {
- mainVariationSide = getOppositePlacement(mainVariationSide);
- }
- var altVariationSide = getOppositePlacement(mainVariationSide);
- var checks = [];
- if (checkMainAxis) {
- checks.push(overflow[_basePlacement] <= 0);
- }
- if (checkAltAxis) {
- checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
- }
- if (checks.every(function(check) {
- return check;
- })) {
- firstFittingPlacement = placement;
- makeFallbackChecks = false;
- break;
- }
- checksMap.set(placement, checks);
- }
- if (makeFallbackChecks) {
- var numberOfChecks = flipVariations ? 3 : 1;
- var _loop = function _loop2(_i2) {
- var fittingPlacement = placements2.find(function(placement2) {
- var checks2 = checksMap.get(placement2);
- if (checks2) {
- return checks2.slice(0, _i2).every(function(check) {
- return check;
- });
- }
- });
- if (fittingPlacement) {
- firstFittingPlacement = fittingPlacement;
- return "break";
- }
- };
- for (var _i = numberOfChecks; _i > 0; _i--) {
- var _ret = _loop(_i);
- if (_ret === "break")
- break;
- }
- }
- if (state.placement !== firstFittingPlacement) {
- state.modifiersData[name]._skip = true;
- state.placement = firstFittingPlacement;
- state.reset = true;
- }
-}
-var flip_default = {
- name: "flip",
- enabled: true,
- phase: "main",
- fn: flip,
- requiresIfExists: ["offset"],
- data: {
- _skip: false
- }
-};
-
-// node_modules/@popperjs/core/lib/modifiers/hide.js
-function getSideOffsets(overflow, rect, preventedOffsets) {
- if (preventedOffsets === void 0) {
- preventedOffsets = {
- x: 0,
- y: 0
- };
- }
- return {
- top: overflow.top - rect.height - preventedOffsets.y,
- right: overflow.right - rect.width + preventedOffsets.x,
- bottom: overflow.bottom - rect.height + preventedOffsets.y,
- left: overflow.left - rect.width - preventedOffsets.x
- };
-}
-function isAnySideFullyClipped(overflow) {
- return [top, right, bottom, left].some(function(side) {
- return overflow[side] >= 0;
- });
-}
-function hide(_ref) {
- var state = _ref.state, name = _ref.name;
- var referenceRect = state.rects.reference;
- var popperRect = state.rects.popper;
- var preventedOffsets = state.modifiersData.preventOverflow;
- var referenceOverflow = detectOverflow(state, {
- elementContext: "reference"
- });
- var popperAltOverflow = detectOverflow(state, {
- altBoundary: true
- });
- var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
- var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
- var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
- var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
- state.modifiersData[name] = {
- referenceClippingOffsets,
- popperEscapeOffsets,
- isReferenceHidden,
- hasPopperEscaped
- };
- state.attributes.popper = Object.assign({}, state.attributes.popper, {
- "data-popper-reference-hidden": isReferenceHidden,
- "data-popper-escaped": hasPopperEscaped
- });
-}
-var hide_default = {
- name: "hide",
- enabled: true,
- phase: "main",
- requiresIfExists: ["preventOverflow"],
- fn: hide
-};
-
-// node_modules/@popperjs/core/lib/modifiers/offset.js
-function distanceAndSkiddingToXY(placement, rects, offset2) {
- var basePlacement = getBasePlacement(placement);
- var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
- var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, {
- placement
- })) : offset2, skidding = _ref[0], distance = _ref[1];
- skidding = skidding || 0;
- distance = (distance || 0) * invertDistance;
- return [left, right].indexOf(basePlacement) >= 0 ? {
- x: distance,
- y: skidding
- } : {
- x: skidding,
- y: distance
- };
-}
-function offset(_ref2) {
- var state = _ref2.state, options = _ref2.options, name = _ref2.name;
- var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset;
- var data = placements.reduce(function(acc, placement) {
- acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2);
- return acc;
- }, {});
- var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y;
- if (state.modifiersData.popperOffsets != null) {
- state.modifiersData.popperOffsets.x += x;
- state.modifiersData.popperOffsets.y += y;
- }
- state.modifiersData[name] = data;
-}
-var offset_default = {
- name: "offset",
- enabled: true,
- phase: "main",
- requires: ["popperOffsets"],
- fn: offset
-};
-
-// node_modules/@popperjs/core/lib/modifiers/popperOffsets.js
-function popperOffsets(_ref) {
- var state = _ref.state, name = _ref.name;
- state.modifiersData[name] = computeOffsets({
- reference: state.rects.reference,
- element: state.rects.popper,
- strategy: "absolute",
- placement: state.placement
- });
-}
-var popperOffsets_default = {
- name: "popperOffsets",
- enabled: true,
- phase: "read",
- fn: popperOffsets,
- data: {}
-};
-
-// node_modules/@popperjs/core/lib/utils/getAltAxis.js
-function getAltAxis(axis) {
- return axis === "x" ? "y" : "x";
-}
-
-// node_modules/@popperjs/core/lib/modifiers/preventOverflow.js
-function preventOverflow(_ref) {
- var state = _ref.state, options = _ref.options, name = _ref.name;
- var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
- var overflow = detectOverflow(state, {
- boundary,
- rootBoundary,
- padding,
- altBoundary
- });
- var basePlacement = getBasePlacement(state.placement);
- var variation = getVariation(state.placement);
- var isBasePlacement = !variation;
- var mainAxis = getMainAxisFromPlacement(basePlacement);
- var altAxis = getAltAxis(mainAxis);
- var popperOffsets2 = state.modifiersData.popperOffsets;
- var referenceRect = state.rects.reference;
- var popperRect = state.rects.popper;
- var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, {
- placement: state.placement
- })) : tetherOffset;
- var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? {
- mainAxis: tetherOffsetValue,
- altAxis: tetherOffsetValue
- } : Object.assign({
- mainAxis: 0,
- altAxis: 0
- }, tetherOffsetValue);
- var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;
- var data = {
- x: 0,
- y: 0
- };
- if (!popperOffsets2) {
- return;
- }
- if (checkMainAxis) {
- var _offsetModifierState$;
- var mainSide = mainAxis === "y" ? top : left;
- var altSide = mainAxis === "y" ? bottom : right;
- var len = mainAxis === "y" ? "height" : "width";
- var offset2 = popperOffsets2[mainAxis];
- var min2 = offset2 + overflow[mainSide];
- var max2 = offset2 - overflow[altSide];
- var additive = tether ? -popperRect[len] / 2 : 0;
- var minLen = variation === start ? referenceRect[len] : popperRect[len];
- var maxLen = variation === start ? -popperRect[len] : -referenceRect[len];
- var arrowElement = state.elements.arrow;
- var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
- width: 0,
- height: 0
- };
- var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject();
- var arrowPaddingMin = arrowPaddingObject[mainSide];
- var arrowPaddingMax = arrowPaddingObject[altSide];
- var arrowLen = within(0, referenceRect[len], arrowRect[len]);
- var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;
- var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;
- var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
- var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
- var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;
- var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset;
- var tetherMax = offset2 + maxOffset - offsetModifierValue;
- var preventedOffset = within(tether ? min(min2, tetherMin) : min2, offset2, tether ? max(max2, tetherMax) : max2);
- popperOffsets2[mainAxis] = preventedOffset;
- data[mainAxis] = preventedOffset - offset2;
- }
- if (checkAltAxis) {
- var _offsetModifierState$2;
- var _mainSide = mainAxis === "x" ? top : left;
- var _altSide = mainAxis === "x" ? bottom : right;
- var _offset = popperOffsets2[altAxis];
- var _len = altAxis === "y" ? "height" : "width";
- var _min = _offset + overflow[_mainSide];
- var _max = _offset - overflow[_altSide];
- var isOriginSide = [top, left].indexOf(basePlacement) !== -1;
- var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;
- var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;
- var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;
- var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);
- popperOffsets2[altAxis] = _preventedOffset;
- data[altAxis] = _preventedOffset - _offset;
- }
- state.modifiersData[name] = data;
-}
-var preventOverflow_default = {
- name: "preventOverflow",
- enabled: true,
- phase: "main",
- fn: preventOverflow,
- requiresIfExists: ["offset"]
-};
-
-// node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js
-function getHTMLElementScroll(element) {
- return {
- scrollLeft: element.scrollLeft,
- scrollTop: element.scrollTop
- };
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js
-function getNodeScroll(node) {
- if (node === getWindow(node) || !isHTMLElement(node)) {
- return getWindowScroll(node);
- } else {
- return getHTMLElementScroll(node);
- }
-}
-
-// node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js
-function isElementScaled(element) {
- var rect = element.getBoundingClientRect();
- var scaleX = round(rect.width) / element.offsetWidth || 1;
- var scaleY = round(rect.height) / element.offsetHeight || 1;
- return scaleX !== 1 || scaleY !== 1;
-}
-function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
- if (isFixed === void 0) {
- isFixed = false;
- }
- var isOffsetParentAnElement = isHTMLElement(offsetParent);
- var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
- var documentElement = getDocumentElement(offsetParent);
- var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);
- var scroll = {
- scrollLeft: 0,
- scrollTop: 0
- };
- var offsets = {
- x: 0,
- y: 0
- };
- if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
- if (getNodeName(offsetParent) !== "body" || isScrollParent(documentElement)) {
- scroll = getNodeScroll(offsetParent);
- }
- if (isHTMLElement(offsetParent)) {
- offsets = getBoundingClientRect(offsetParent, true);
- offsets.x += offsetParent.clientLeft;
- offsets.y += offsetParent.clientTop;
- } else if (documentElement) {
- offsets.x = getWindowScrollBarX(documentElement);
- }
- }
- return {
- x: rect.left + scroll.scrollLeft - offsets.x,
- y: rect.top + scroll.scrollTop - offsets.y,
- width: rect.width,
- height: rect.height
- };
-}
-
-// node_modules/@popperjs/core/lib/utils/orderModifiers.js
-function order(modifiers) {
- var map = /* @__PURE__ */ new Map();
- var visited = /* @__PURE__ */ new Set();
- var result = [];
- modifiers.forEach(function(modifier) {
- map.set(modifier.name, modifier);
- });
- function sort(modifier) {
- visited.add(modifier.name);
- var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
- requires.forEach(function(dep) {
- if (!visited.has(dep)) {
- var depModifier = map.get(dep);
- if (depModifier) {
- sort(depModifier);
- }
- }
- });
- result.push(modifier);
- }
- modifiers.forEach(function(modifier) {
- if (!visited.has(modifier.name)) {
- sort(modifier);
- }
- });
- return result;
-}
-function orderModifiers(modifiers) {
- var orderedModifiers = order(modifiers);
- return modifierPhases.reduce(function(acc, phase) {
- return acc.concat(orderedModifiers.filter(function(modifier) {
- return modifier.phase === phase;
- }));
- }, []);
-}
-
-// node_modules/@popperjs/core/lib/utils/debounce.js
-function debounce(fn2) {
- var pending;
- return function() {
- if (!pending) {
- pending = new Promise(function(resolve) {
- Promise.resolve().then(function() {
- pending = void 0;
- resolve(fn2());
- });
- });
- }
- return pending;
- };
-}
-
-// node_modules/@popperjs/core/lib/utils/mergeByName.js
-function mergeByName(modifiers) {
- var merged = modifiers.reduce(function(merged2, current) {
- var existing = merged2[current.name];
- merged2[current.name] = existing ? Object.assign({}, existing, current, {
- options: Object.assign({}, existing.options, current.options),
- data: Object.assign({}, existing.data, current.data)
- }) : current;
- return merged2;
- }, {});
- return Object.keys(merged).map(function(key) {
- return merged[key];
- });
-}
-
-// node_modules/@popperjs/core/lib/createPopper.js
-var DEFAULT_OPTIONS = {
- placement: "bottom",
- modifiers: [],
- strategy: "absolute"
-};
-function areValidElements() {
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
- return !args.some(function(element) {
- return !(element && typeof element.getBoundingClientRect === "function");
- });
-}
-function popperGenerator(generatorOptions) {
- if (generatorOptions === void 0) {
- generatorOptions = {};
- }
- var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
- return function createPopper2(reference2, popper2, options) {
- if (options === void 0) {
- options = defaultOptions;
- }
- var state = {
- placement: "bottom",
- orderedModifiers: [],
- options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
- modifiersData: {},
- elements: {
- reference: reference2,
- popper: popper2
- },
- attributes: {},
- styles: {}
- };
- var effectCleanupFns = [];
- var isDestroyed = false;
- var instance = {
- state,
- setOptions: function setOptions(setOptionsAction) {
- var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction;
- cleanupModifierEffects();
- state.options = Object.assign({}, defaultOptions, state.options, options2);
- state.scrollParents = {
- reference: isElement(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [],
- popper: listScrollParents(popper2)
- };
- var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers)));
- state.orderedModifiers = orderedModifiers.filter(function(m) {
- return m.enabled;
- });
- runModifierEffects();
- return instance.update();
- },
- forceUpdate: function forceUpdate() {
- if (isDestroyed) {
- return;
- }
- var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper;
- if (!areValidElements(reference3, popper3)) {
- return;
- }
- state.rects = {
- reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"),
- popper: getLayoutRect(popper3)
- };
- state.reset = false;
- state.placement = state.options.placement;
- state.orderedModifiers.forEach(function(modifier) {
- return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
- });
- for (var index = 0; index < state.orderedModifiers.length; index++) {
- if (state.reset === true) {
- state.reset = false;
- index = -1;
- continue;
- }
- var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name;
- if (typeof fn2 === "function") {
- state = fn2({
- state,
- options: _options,
- name,
- instance
- }) || state;
- }
- }
- },
- update: debounce(function() {
- return new Promise(function(resolve) {
- instance.forceUpdate();
- resolve(state);
- });
- }),
- destroy: function destroy() {
- cleanupModifierEffects();
- isDestroyed = true;
- }
- };
- if (!areValidElements(reference2, popper2)) {
- return instance;
- }
- instance.setOptions(options).then(function(state2) {
- if (!isDestroyed && options.onFirstUpdate) {
- options.onFirstUpdate(state2);
- }
- });
- function runModifierEffects() {
- state.orderedModifiers.forEach(function(_ref) {
- var name = _ref.name, _ref$options = _ref.options, options2 = _ref$options === void 0 ? {} : _ref$options, effect4 = _ref.effect;
- if (typeof effect4 === "function") {
- var cleanupFn = effect4({
- state,
- name,
- instance,
- options: options2
- });
- var noopFn = function noopFn2() {
- };
- effectCleanupFns.push(cleanupFn || noopFn);
- }
- });
- }
- function cleanupModifierEffects() {
- effectCleanupFns.forEach(function(fn2) {
- return fn2();
- });
- effectCleanupFns = [];
- }
- return instance;
- };
-}
-
-// node_modules/@popperjs/core/lib/popper.js
-var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default, offset_default, flip_default, preventOverflow_default, arrow_default, hide_default];
-var createPopper = /* @__PURE__ */ popperGenerator({
- defaultModifiers
-});
-
-// src/suggesters/suggest.ts
-var wrapAround = (value, size) => {
- return (value % size + size) % size;
-};
-var Suggest = class {
- constructor(owner, containerEl, scope) {
- this.owner = owner;
- this.containerEl = containerEl;
- containerEl.on("click", ".suggestion-item", this.onSuggestionClick.bind(this));
- containerEl.on("mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this));
- scope.register([], "ArrowUp", (event) => {
- if (!event.isComposing) {
- this.setSelectedItem(this.selectedItem - 1, true);
- return false;
- }
- });
- scope.register([], "ArrowDown", (event) => {
- if (!event.isComposing) {
- this.setSelectedItem(this.selectedItem + 1, true);
- return false;
- }
- });
- scope.register([], "Enter", (event) => {
- if (!event.isComposing) {
- this.useSelectedItem(event);
- return false;
- }
- });
- }
- onSuggestionClick(event, el) {
- event.preventDefault();
- const item = this.suggestions.indexOf(el);
- this.setSelectedItem(item, false);
- this.useSelectedItem(event);
- }
- onSuggestionMouseover(_event, el) {
- const item = this.suggestions.indexOf(el);
- this.setSelectedItem(item, false);
- }
- setSuggestions(values) {
- this.containerEl.empty();
- const suggestionEls = [];
- values.forEach((value) => {
- const suggestionEl = this.containerEl.createDiv("suggestion-item");
- this.owner.renderSuggestion(value, suggestionEl);
- suggestionEls.push(suggestionEl);
- });
- this.values = values;
- this.suggestions = suggestionEls;
- this.setSelectedItem(0, false);
- }
- useSelectedItem(event) {
- const currentValue = this.values[this.selectedItem];
- if (currentValue) {
- this.owner.selectSuggestion(currentValue, event);
- }
- }
- setSelectedItem(selectedIndex, scrollIntoView) {
- const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length);
- const prevSelectedSuggestion = this.suggestions[this.selectedItem];
- const selectedSuggestion = this.suggestions[normalizedIndex];
- prevSelectedSuggestion == null ? void 0 : prevSelectedSuggestion.removeClass("is-selected");
- selectedSuggestion == null ? void 0 : selectedSuggestion.addClass("is-selected");
- this.selectedItem = normalizedIndex;
- if (scrollIntoView) {
- selectedSuggestion.scrollIntoView(false);
- }
- }
-};
-var TextInputSuggest = class {
- constructor(inputEl) {
- this.inputEl = inputEl;
- this.scope = new import_obsidian.Scope();
- this.suggestEl = createDiv("suggestion-container");
- const suggestion = this.suggestEl.createDiv("suggestion");
- this.suggest = new Suggest(this, suggestion, this.scope);
- this.scope.register([], "Escape", this.close.bind(this));
- this.inputEl.addEventListener("input", this.onInputChanged.bind(this));
- this.inputEl.addEventListener("focus", this.onInputChanged.bind(this));
- this.inputEl.addEventListener("blur", this.close.bind(this));
- this.suggestEl.on("mousedown", ".suggestion-container", (event) => {
- event.preventDefault();
- });
- }
- onInputChanged() {
- const inputStr = this.inputEl.value;
- const suggestions = this.getSuggestions(inputStr);
- if (!suggestions) {
- this.close();
- return;
- }
- if (suggestions.length > 0) {
- this.suggest.setSuggestions(suggestions);
- this.open(app.dom.appContainerEl, this.inputEl);
- } else {
- this.close();
- }
- }
- open(container, inputEl) {
- app.keymap.pushScope(this.scope);
- container.appendChild(this.suggestEl);
- this.popper = createPopper(inputEl, this.suggestEl, {
- placement: "bottom-start",
- modifiers: [
- {
- name: "sameWidth",
- enabled: true,
- fn: ({ state, instance }) => {
- const targetWidth = `${state.rects.reference.width}px`;
- if (state.styles.popper.width === targetWidth) {
- return;
- }
- state.styles.popper.width = targetWidth;
- instance.update();
- },
- phase: "beforeWrite",
- requires: ["computeStyles"]
- }
- ]
- });
- }
- close() {
- app.keymap.popScope(this.scope);
- this.suggest.setSuggestions([]);
- if (this.popper)
- this.popper.destroy();
- this.suggestEl.detach();
- }
-};
-
-// src/template.ts
-var import_obsidian2 = require("obsidian");
-async function applyTemplate(plugin, file, templatePath) {
- const templateFile = templatePath ? plugin.app.vault.getAbstractFileByPath(templatePath) : null;
- if (templateFile && templateFile instanceof import_obsidian2.TFile) {
- try {
- const {
- templatesEnabled,
- templaterEnabled,
- templatesPlugin,
- templaterPlugin
- } = getTemplatePlugins(plugin.app);
- const templateContent = await plugin.app.vault.read(templateFile);
- if (templatesEnabled && templaterEnabled) {
- if (/<%/.test(templateContent)) {
- return await templaterPlugin.write_template_to_file(templateFile, file);
- }
- return await templatesPlugin.instance.insertTemplate(templateFile);
- }
- if (templatesEnabled) {
- return await templatesPlugin.instance.insertTemplate(templateFile);
- }
- if (templaterEnabled) {
- return await templaterPlugin.write_template_to_file(templateFile, file);
- }
- } catch (e) {
- console.error(e);
- }
- }
-}
-function getTemplatePlugins(app2) {
- var _a;
- const templatesPlugin = app2.internalPlugins.plugins.templates;
- const templatesEnabled = templatesPlugin.enabled;
- const templaterPlugin = app2.plugins.plugins["templater-obsidian"];
- const templaterEnabled = app2.plugins.enabledPlugins.has("templater-obsidian");
- const templaterEmptyFileTemplate = templaterPlugin && ((_a = this.app.plugins.plugins["templater-obsidian"].settings) == null ? void 0 : _a.empty_file_template);
- const templateFolder = templatesEnabled ? templatesPlugin.instance.options.folder : templaterPlugin ? templaterPlugin.settings.template_folder : void 0;
- return {
- templatesPlugin,
- templatesEnabled,
- templaterPlugin: templaterPlugin == null ? void 0 : templaterPlugin.templater,
- templaterEnabled,
- templaterEmptyFileTemplate,
- templateFolder
- };
-}
-
-// src/suggesters/templateSuggester.ts
-var TemplateSuggest = class extends TextInputSuggest {
- constructor(inputEl, plugin) {
- super(inputEl);
- this.inputEl = inputEl;
- this.plugin = plugin;
- }
- get_error_msg(mode) {
- switch (mode) {
- case 0 /* TemplateFiles */:
- return "Templates folder doesn't exist";
- case 1 /* ScriptFiles */:
- return "User Scripts folder doesn't exist";
- }
- }
- getSuggestions(input_str) {
- var _a, _b;
- const { templateFolder, templaterPlugin } = getTemplatePlugins(this.plugin.app);
- if ((!templateFolder || (templateFolder == null ? void 0 : templateFolder.trim()) === "") && !templaterPlugin) {
- this.plugin.settings.templatePath = "";
- this.plugin.saveSettings();
- return [];
- }
- let folder;
- if (templaterPlugin) {
- folder = this.plugin.app.vault.getAbstractFileByPath((_b = (_a = templaterPlugin.plugin) == null ? void 0 : _a.settings) == null ? void 0 : _b.templates_folder);
- } else {
- folder = this.plugin.app.vault.getAbstractFileByPath(templateFolder);
- }
- const files = [];
- const lower_input_str = input_str.toLowerCase();
- import_obsidian3.Vault.recurseChildren(folder, (file) => {
- if (file instanceof import_obsidian3.TFile && file.path.toLowerCase().contains(lower_input_str)) {
- files.push(file);
- }
- });
- return files;
- }
- renderSuggestion(file, el) {
- el.setText(file.name.replace(".md", ""));
- }
- selectSuggestion(file) {
- this.inputEl.value = file.name.replace(".md", "");
- this.inputEl.trigger("input");
- this.plugin.settings.templatePath = file.path;
- this.plugin.saveSettings();
- this.close();
- }
-};
-
-// src/modals/existingNote.ts
-var import_obsidian4 = require("obsidian");
-var ExistingFolderNoteModal = class extends import_obsidian4.Modal {
- constructor(app2, plugin, file, folder, folderNote) {
- super(app2);
- this.plugin = plugin;
- this.app = app2;
- this.file = file;
- this.folder = folder;
- this.folderNote = folderNote;
- }
- onOpen() {
- var _a;
- const { contentEl } = this;
- contentEl.createEl("h2", { text: "A folder note for this folder already exists" });
- const setting = new import_obsidian4.Setting(contentEl);
- setting.infoEl.createEl("p", { text: "Are you sure you want to turn the note into a folder note and rename the existing folder note?" });
- (_a = setting.infoEl.parentElement) == null ? void 0 : _a.classList.add("fn-delete-confirmation-modal");
- const buttonContainer = setting.infoEl.createEl("div", { cls: "fn-delete-confirmation-modal-buttons" });
- if (import_obsidian4.Platform.isMobileApp) {
- const confirmButton = buttonContainer.createEl("button", { text: "Rename and don't ask again" });
- confirmButton.classList.add("mod-warning", "fn-confirmation-modal-button");
- confirmButton.addEventListener("click", async () => {
- this.plugin.settings.showRenameConfirmation = false;
- this.plugin.saveSettings();
- this.close();
- turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true);
- });
- } else {
- const checkbox = buttonContainer.createEl("input", { type: "checkbox" });
- checkbox.addEventListener("change", (e) => {
- const target = e.target;
- if (target.checked) {
- this.plugin.settings.showRenameConfirmation = false;
- } else {
- this.plugin.settings.showRenameConfirmation = true;
- }
- });
- const checkBoxText = buttonContainer.createEl("span", { text: "Don't ask again" });
- checkBoxText.addEventListener("click", () => {
- checkbox.click();
- });
- }
- const button = buttonContainer.createEl("button", { text: "Rename" });
- button.classList.add("mod-warning", "fn-confirmation-modal-button");
- button.addEventListener("click", async () => {
- this.plugin.saveSettings();
- this.close();
- turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true);
- });
- button.focus();
- const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
- cancelButton.addEventListener("click", async () => {
- this.close();
- });
- }
- onClose() {
- const { contentEl } = this;
- contentEl.empty();
- }
-};
-
-// src/functions/folderNoteFunctions.ts
-var import_obsidian10 = require("obsidian");
-
-// src/modals/deleteConfirmation.ts
-var import_obsidian5 = require("obsidian");
-var DeleteConfirmationModal = class extends import_obsidian5.Modal {
- constructor(app2, plugin, file) {
- super(app2);
- this.plugin = plugin;
- this.app = app2;
- this.file = file;
- }
- onOpen() {
- var _a;
- const { contentEl } = this;
- contentEl.createEl("h2", { text: "Delete folder note" });
- const setting = new import_obsidian5.Setting(contentEl);
- setting.infoEl.createEl("p", { text: `Are you sure you want to delete the folder note "${this.file.name}" ?` });
- setting.infoEl.createEl("p", { text: "It will be moved to your system trash." });
- (_a = setting.infoEl.parentElement) == null ? void 0 : _a.classList.add("fn-delete-confirmation-modal");
- const buttonContainer = setting.infoEl.createEl("div", { cls: "fn-delete-confirmation-modal-buttons" });
- if (import_obsidian5.Platform.isMobileApp) {
- const confirmButton = buttonContainer.createEl("button", { text: "Delete and don't ask again" });
- confirmButton.classList.add("mod-warning", "fn-confirmation-modal-button");
- confirmButton.addEventListener("click", async () => {
- this.plugin.settings.showDeleteConfirmation = false;
- this.plugin.saveSettings();
- this.close();
- const folder = getFolder(this.plugin, this.file);
- if (!folder)
- return;
- this.plugin.removeCSSClassFromEL(folder == null ? void 0 : folder.path, "has-folder-note");
- this.app.vault.delete(this.file);
- });
- } else {
- const checkbox = buttonContainer.createEl("input", { type: "checkbox" });
- checkbox.addEventListener("change", (e) => {
- const target = e.target;
- if (target.checked) {
- this.plugin.settings.showDeleteConfirmation = false;
- } else {
- this.plugin.settings.showDeleteConfirmation = true;
- }
- this.plugin.saveSettings();
- });
- const checkBoxText = buttonContainer.createEl("span", { text: "Don't ask again" });
- checkBoxText.addEventListener("click", () => {
- checkbox.click();
- });
- }
- const button = buttonContainer.createEl("button", { text: "Delete" });
- button.classList.add("mod-warning", "fn-confirmation-modal-button");
- button.addEventListener("click", async () => {
- this.close();
- const folder = getFolder(this.plugin, this.file);
- if (!folder)
- return;
- this.plugin.removeCSSClassFromEL(folder.path, "has-folder-note");
- this.app.vault.delete(this.file);
- });
- button.focus();
- const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
- cancelButton.addEventListener("click", async () => {
- this.close();
- });
- }
- onClose() {
- const { contentEl } = this;
- contentEl.empty();
- }
-};
-
-// src/excludedFolder.ts
-var import_obsidian9 = require("obsidian");
-
-// src/modals/excludeFolderSettings.ts
-var import_obsidian6 = require("obsidian");
-var ExcludedFolderSettings = class extends import_obsidian6.Modal {
- constructor(app2, plugin, excludedFolder) {
- super(app2);
- this.plugin = plugin;
- this.app = app2;
- this.excludedFolder = excludedFolder;
- }
- onOpen() {
- this.display();
- }
- display() {
- const { contentEl } = this;
- contentEl.empty();
- contentEl.createEl("h2", { text: "Excluded folder settings" });
- new import_obsidian6.Setting(contentEl).setName("Include subfolders").setDesc("Choose if the subfolders of the folder should also be excluded").addToggle((toggle) => toggle.setValue(this.excludedFolder.subFolders).onChange(async (value) => {
- this.excludedFolder.subFolders = value;
- await this.plugin.saveSettings();
- }));
- new import_obsidian6.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder note should be renamed when the folder name is changed").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableSync).onChange(async (value) => {
- this.excludedFolder.disableSync = value;
- await this.plugin.saveSettings();
- }));
- new import_obsidian6.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableAutoCreate).onChange(async (value) => {
- this.excludedFolder.disableAutoCreate = value;
- await this.plugin.saveSettings();
- }));
- new import_obsidian6.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableFolderNote).onChange(async (value) => {
- this.excludedFolder.disableFolderNote = value;
- await this.plugin.saveSettings();
- this.display();
- }));
- if (!this.excludedFolder.disableFolderNote) {
- new import_obsidian6.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.enableCollapsing).onChange(async (value) => {
- this.excludedFolder.enableCollapsing = value;
- await this.plugin.saveSettings();
- }));
- }
- }
- onClose() {
- const { contentEl } = this;
- contentEl.empty();
- }
-};
-
-// src/suggesters/FolderSuggester.ts
-var import_obsidian7 = require("obsidian");
-var FolderSuggest = class extends TextInputSuggest {
- constructor(inputEl, plugin) {
- super(inputEl);
- this.inputEl = inputEl;
- this.plugin = plugin;
- }
- get_error_msg(mode) {
- switch (mode) {
- case 0 /* TemplateFiles */:
- return "Templates folder doesn't exist";
- case 1 /* ScriptFiles */:
- return "User Scripts folder doesn't exist";
- }
- }
- getSuggestions(input_str) {
- const folders = [];
- const lower_input_str = input_str.toLowerCase();
- this.plugin.app.vault.getAllLoadedFiles().forEach((folder) => {
- if (folder instanceof import_obsidian7.TFolder && folder.path.toLowerCase().contains(lower_input_str) && !this.plugin.settings.excludeFolders.find((f) => f.path === folder.path)) {
- folders.push(folder);
- }
- });
- return folders;
- }
- renderSuggestion(folder, el) {
- el.setText(folder.path);
- }
- selectSuggestion(folder) {
- this.inputEl.value = folder.path;
- this.inputEl.trigger("input");
- this.close();
- }
-};
-
-// src/modals/patternSettings.ts
-var import_obsidian8 = require("obsidian");
-var PatternSettings = class extends import_obsidian8.Modal {
- constructor(app2, plugin, pattern) {
- super(app2);
- this.plugin = plugin;
- this.app = app2;
- this.pattern = pattern;
- }
- onOpen() {
- this.display();
- }
- display() {
- const { contentEl } = this;
- contentEl.empty();
- contentEl.createEl("h2", { text: "Pattern settings" });
- new import_obsidian8.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder name should be renamed when the file name has been changed").addToggle((toggle) => toggle.setValue(this.pattern.disableSync).onChange(async (value) => {
- this.pattern.disableSync = value;
- await this.plugin.saveSettings();
- }));
- new import_obsidian8.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created that matches this pattern").addToggle((toggle) => toggle.setValue(this.pattern.disableAutoCreate).onChange(async (value) => {
- this.pattern.disableAutoCreate = value;
- await this.plugin.saveSettings();
- }));
- new import_obsidian8.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.pattern.disableFolderNote).onChange(async (value) => {
- this.pattern.disableFolderNote = value;
- await this.plugin.saveSettings();
- this.display();
- }));
- if (!this.pattern.disableFolderNote) {
- new import_obsidian8.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.pattern.enableCollapsing).onChange(async (value) => {
- this.pattern.enableCollapsing = value;
- await this.plugin.saveSettings();
- }));
- }
- }
- onClose() {
- const { contentEl } = this;
- contentEl.empty();
- }
-};
-
-// src/excludedFolder.ts
-var ExcludedFolder = class {
- constructor(path, position) {
- this.type = "folder";
- this.path = path;
- this.subFolders = true;
- this.disableSync = true;
- this.disableAutoCreate = true;
- this.disableFolderNote = false;
- this.enableCollapsing = false;
- this.position = position;
- this.string = "";
- }
-};
-var ExcludePattern = class {
- constructor(pattern, position) {
- this.type = "pattern";
- this.string = pattern;
- this.position = position;
- this.subFolders = false;
- this.disableSync = true;
- this.disableAutoCreate = true;
- this.disableFolderNote = false;
- this.enableCollapsing = false;
- this.path = "";
- }
-};
-function getExcludedFolder(plugin, path) {
- const folderName = plugin.getFolderNameFromPathString(path);
- const matchedPattern = getExcludedFolderByPattern(plugin, folderName);
- if (matchedPattern) {
- return matchedPattern;
- }
- const excludedFolder = getExcludedFolderByPath(plugin, path);
- return excludedFolder;
-}
-function getExcludedFolderByPattern(plugin, folderName) {
- return plugin.settings.excludeFolders.filter((s) => s.path === "").find((pattern) => {
- if (!pattern.string) {
- return false;
- }
- if (pattern.string.toLocaleLowerCase().startsWith("{regex}") && pattern.string.slice(7).trim() !== "") {
- const match = new RegExp(pattern.string.slice(7).trim()).exec(folderName);
- if (match) {
- return true;
- }
- } else if (pattern.string.startsWith("*") && pattern.string.endsWith("*")) {
- if (folderName.includes(pattern.string.slice(1, -1))) {
- return true;
- }
- } else if (pattern.string.startsWith("*")) {
- if (folderName.endsWith(pattern.string.slice(1))) {
- return true;
- }
- } else if (pattern.string.endsWith("*")) {
- if (folderName.startsWith(pattern.string.slice(0, -1))) {
- return true;
- }
- }
- });
-}
-function getExcludedFolderByPath(plugin, path) {
- return plugin.settings.excludeFolders.find((excludedFolder) => {
- if (excludedFolder.path === path) {
- return true;
- }
- if (!excludedFolder.subFolders) {
- return false;
- }
- return plugin.getFolderPathFromString(path).startsWith(excludedFolder.path);
- });
-}
-function addExcludedFolder(plugin, excludedFolder) {
- plugin.settings.excludeFolders.push(excludedFolder);
- plugin.saveSettings();
-}
-function deleteExcludedFolder(plugin, excludedFolder) {
- plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path || folder.type === "pattern");
- plugin.saveSettings();
- resyncArray(plugin);
-}
-function deletePattern(plugin, pattern) {
- plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string || folder.type === "folder");
- plugin.saveSettings();
- resyncArray(plugin);
-}
-function updateExcludedFolder(plugin, excludedFolder, newExcludeFolder) {
- plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path);
- addExcludedFolder(plugin, newExcludeFolder);
-}
-function updatePattern(plugin, pattern, newPattern) {
- plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string);
- addExcludedFolder(plugin, newPattern);
-}
-function resyncArray(plugin) {
- plugin.settings.excludeFolders = plugin.settings.excludeFolders.sort((a, b) => a.position - b.position);
- plugin.settings.excludeFolders.forEach((folder, index) => {
- folder.position = index;
- });
- plugin.saveSettings();
-}
-function addExcludePatternListItem(settings, containerEl, pattern) {
- const plugin = settings.plugin;
- const setting = new import_obsidian9.Setting(containerEl);
- setting.setClass("fn-exclude-folder-list");
- setting.addSearch((cb) => {
- cb.containerEl.addClass("fn-exclude-folder-path");
- cb.setPlaceholder("Pattern");
- cb.setValue(pattern.string);
- cb.onChange((value) => {
- if (plugin.settings.excludeFolders.find((folder) => folder.string === value)) {
- return;
- }
- pattern.string = value;
- updatePattern(plugin, pattern, pattern);
- });
- });
- setting.addButton((cb) => {
- cb.setIcon("edit");
- cb.setTooltip("Edit pattern");
- cb.onClick(() => {
- new PatternSettings(plugin.app, plugin, pattern).open();
- });
- });
- setting.addButton((cb) => {
- cb.setIcon("up-chevron-glyph");
- cb.setTooltip("Move up");
- cb.onClick(() => {
- if (pattern.position === 0) {
- return;
- }
- pattern.position -= 1;
- updatePattern(plugin, pattern, pattern);
- const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position);
- if (oldPattern) {
- oldPattern.position += 1;
- if (oldPattern.type === "pattern") {
- updatePattern(plugin, oldPattern, oldPattern);
- } else {
- updateExcludedFolder(plugin, oldPattern, oldPattern);
- }
- }
- settings.display();
- });
- });
- setting.addButton((cb) => {
- cb.setIcon("down-chevron-glyph");
- cb.setTooltip("Move down");
- cb.onClick(() => {
- if (pattern.position === plugin.settings.excludeFolders.length - 1) {
- return;
- }
- pattern.position += 1;
- updatePattern(plugin, pattern, pattern);
- const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position);
- if (oldPattern) {
- oldPattern.position -= 1;
- if (oldPattern.type === "pattern") {
- updatePattern(plugin, oldPattern, oldPattern);
- } else {
- updateExcludedFolder(plugin, oldPattern, oldPattern);
- }
- }
- settings.display();
- });
- });
- setting.addButton((cb) => {
- cb.setIcon("trash-2");
- cb.setTooltip("Delete pattern");
- cb.onClick(() => {
- deletePattern(plugin, pattern);
- setting.clear();
- setting.settingEl.remove();
- });
- });
-}
-function addExcludeFolderListItem(settings, containerEl, excludedFolder) {
- const plugin = settings.plugin;
- const setting = new import_obsidian9.Setting(containerEl);
- setting.setClass("fn-exclude-folder-list");
- setting.addSearch((cb) => {
- new FolderSuggest(cb.inputEl, plugin);
- cb.containerEl.addClass("fn-exclude-folder-path");
- cb.setPlaceholder("Folder path");
- cb.setValue(excludedFolder.path);
- cb.onChange((value) => {
- if (value.startsWith("{regex}") || value.includes("*")) {
- deleteExcludedFolder(plugin, excludedFolder);
- const pattern = new ExcludePattern(value, plugin.settings.excludeFolders.length);
- addExcludedFolder(plugin, pattern);
- addExcludePatternListItem(settings, containerEl, pattern);
- setting.clear();
- setting.settingEl.remove();
- }
- if (!plugin.app.vault.getAbstractFileByPath(value))
- return;
- excludedFolder.path = value;
- updateExcludedFolder(plugin, excludedFolder, excludedFolder);
- });
- });
- setting.addButton((cb) => {
- cb.setIcon("edit");
- cb.setTooltip("Edit folder note");
- cb.onClick(() => {
- new ExcludedFolderSettings(plugin.app, plugin, excludedFolder).open();
- });
- });
- setting.addButton((cb) => {
- cb.setIcon("up-chevron-glyph");
- cb.setTooltip("Move up");
- cb.onClick(() => {
- if (excludedFolder.position === 0) {
- return;
- }
- excludedFolder.position -= 1;
- updateExcludedFolder(plugin, excludedFolder, excludedFolder);
- const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position);
- if (oldExcludedFolder) {
- oldExcludedFolder.position += 1;
- if (oldExcludedFolder.type === "pattern") {
- updatePattern(plugin, oldExcludedFolder, oldExcludedFolder);
- } else {
- updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder);
- }
- }
- settings.display();
- });
- });
- setting.addButton((cb) => {
- cb.setIcon("down-chevron-glyph");
- cb.setTooltip("Move down");
- cb.onClick(() => {
- if (excludedFolder.position === plugin.settings.excludeFolders.length - 1) {
- return;
- }
- excludedFolder.position += 1;
- updateExcludedFolder(plugin, excludedFolder, excludedFolder);
- const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position);
- if (oldExcludedFolder) {
- oldExcludedFolder.position -= 1;
- if (oldExcludedFolder.type === "pattern") {
- updatePattern(plugin, oldExcludedFolder, oldExcludedFolder);
- } else {
- updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder);
- }
- }
- settings.display();
- });
- });
- setting.addButton((cb) => {
- cb.setIcon("trash-2");
- cb.setTooltip("Delete excluded folder");
- cb.onClick(() => {
- deleteExcludedFolder(plugin, excludedFolder);
- setting.clear();
- setting.settingEl.remove();
- });
- });
-}
-
-// src/functions/folderNoteFunctions.ts
-async function createFolderNote(plugin, folderPath, openFile, useModal, existingNote) {
- const leaf = plugin.app.workspace.getLeaf(false);
- const folderName = plugin.getFolderNameFromPathString(folderPath);
- const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName);
- let path = "";
- if (plugin.settings.storageLocation === "parentFolder") {
- const parentFolderPath = plugin.getFolderPathFromString(folderPath);
- if (parentFolderPath.trim() === "") {
- path = `${fileName}${plugin.settings.folderNoteType}`;
- } else {
- path = `${parentFolderPath}/${fileName}${plugin.settings.folderNoteType}`;
- }
- } else if (plugin.settings.storageLocation === "vaultFolder") {
- path = `${fileName}${plugin.settings.folderNoteType}`;
- } else {
- path = `${folderPath}/${fileName}${plugin.settings.folderNoteType}`;
- }
- let file;
- if (!existingNote) {
- file = await plugin.app.vault.create(path, "");
- } else {
- file = existingNote;
- plugin.app.vault.rename(existingNote, path);
- }
- if (openFile) {
- await leaf.openFile(file);
- }
- if (file && !existingNote) {
- applyTemplate(this, file, plugin.settings.templatePath);
- }
- const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
- if (!(folder instanceof import_obsidian10.TFolder))
- return;
- plugin.addCSSClassToTitleEL(path, "is-folder-note", true);
- plugin.addCSSClassToTitleEL(folder.path, "has-folder-note");
-}
-async function turnIntoFolderNote(plugin, file, folder, folderNote, skipConfirmation) {
- var _a;
- if (folderNote) {
- if (plugin.settings.showRenameConfirmation && !skipConfirmation) {
- return new ExistingFolderNoteModal(plugin.app, plugin, file, folder, folderNote).open();
- }
- plugin.removeCSSClassFromEL(folderNote.path, "is-folder-note");
- let excludedFolder = getExcludedFolder(plugin, folder.path);
- let excludedFolderExisted = true;
- let disabledSync = false;
- if (!excludedFolder) {
- excludedFolderExisted = false;
- excludedFolder = new ExcludedFolder(folder.path, plugin.settings.excludeFolders.length);
- addExcludedFolder(plugin, excludedFolder);
- } else if (!excludedFolder.disableSync) {
- disabledSync = false;
- excludedFolder.disableSync = true;
- updateExcludedFolder(plugin, excludedFolder, excludedFolder);
- }
- const newPath = `${folder.path}/${folder.name} (${file.stat.ctime.toString().slice(10) + Math.floor(Math.random() * 1e3)})${plugin.settings.folderNoteType}`;
- plugin.app.vault.rename(folderNote, newPath).then(() => {
- if (!excludedFolder) {
- return;
- }
- if (!excludedFolderExisted) {
- deleteExcludedFolder(plugin, excludedFolder);
- } else if (!disabledSync) {
- excludedFolder.disableSync = false;
- updateExcludedFolder(plugin, excludedFolder, excludedFolder);
- }
- });
- }
- const folderName = folder.name;
- const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName);
- let path = `${folder.path}/${fileName}${plugin.settings.folderNoteType}`;
- if (plugin.settings.storageLocation === "parentFolder") {
- const parentFolderPath = (_a = folder.parent) == null ? void 0 : _a.path;
- if (!parentFolderPath)
- return;
- if (parentFolderPath.trim() === "") {
- path = `${fileName}${plugin.settings.folderNoteType}`;
- } else {
- path = `${parentFolderPath}/${fileName}${plugin.settings.folderNoteType}`;
- }
- }
- await plugin.app.vault.rename(file, path);
- plugin.addCSSClassToTitleEL(path, "is-folder-note", true);
- plugin.addCSSClassToTitleEL(folder.path, "has-folder-note");
-}
-async function openFolderNote(plugin, file, evt) {
- var _a;
- const path = file.path;
- if (((_a = plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path) === path) {
- return;
- }
- const leaf = plugin.app.workspace.getLeaf(import_obsidian10.Keymap.isModEvent(evt) || plugin.settings.openInNewTab);
- if (file instanceof import_obsidian10.TFile) {
- await leaf.openFile(file);
- }
-}
-async function deleteFolderNote(plugin, file) {
- if (plugin.settings.showDeleteConfirmation) {
- return new DeleteConfirmationModal(plugin.app, plugin, file).open();
- }
- const folder = getFolder(plugin, file);
- if (!folder)
- return;
- plugin.removeCSSClassFromEL(folder.path, "has-folder-note");
- await plugin.app.vault.delete(file);
-}
-function extractFolderName(template, changedFileName) {
- const [prefix, suffix] = template.split("{{folder_name}}");
- if (prefix.trim() === "" && suffix.trim() === "") {
- return changedFileName;
- }
- if (!changedFileName.startsWith(prefix) || !changedFileName.endsWith(suffix)) {
- return null;
- }
- if (changedFileName.startsWith(prefix) && prefix.trim() !== "") {
- return changedFileName.slice(prefix.length).replace(suffix, "");
- } else if (changedFileName.endsWith(suffix) && suffix.trim() !== "") {
- return changedFileName.slice(0, -suffix.length);
- }
- return null;
-}
-function getFolderNote(plugin, folderPath, storageLocation, file) {
- if (!folderPath)
- return null;
- const folder = {
- path: folderPath,
- name: plugin.getFolderNameFromPathString(folderPath)
- };
- let fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folder.name);
- if (file) {
- fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.basename);
- }
- if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") {
- folder.path = plugin.getFolderPathFromString(folderPath);
- }
- let path = `${folder.path}/${fileName}`;
- if (folder.path.trim() === "") {
- folder.path = fileName;
- path = `${fileName}`;
- }
- let folderNote = plugin.app.vault.getAbstractFileByPath(path + plugin.settings.folderNoteType);
- if (folderNote instanceof import_obsidian10.TFile) {
- return folderNote;
- } else {
- if (plugin.settings.folderNoteType === ".canvas") {
- folderNote = plugin.app.vault.getAbstractFileByPath(path + ".md");
- } else {
- folderNote = plugin.app.vault.getAbstractFileByPath(path + ".canvas");
- }
- return folderNote;
- }
-}
-function getFolder(plugin, file, storageLocation) {
- if (!file)
- return null;
- const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename);
- if (!folderName)
- return null;
- let folderPath = plugin.getFolderPathFromString(file.path);
- let folder = null;
- if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") {
- if (folderPath.trim() === "") {
- folderPath = folderName;
- } else {
- folderPath = `${folderPath}/${folderName}`;
- }
- folder = plugin.app.vault.getAbstractFileByPath(folderPath);
- } else {
- folder = plugin.app.vault.getAbstractFileByPath(folderPath);
- }
- if (!folder) {
- return null;
- }
- return folder;
-}
-function getFolderNoteFolder(plugin, folderNote, fileName) {
- if (!folderNote)
- return null;
- let filePath = "";
- if (typeof folderNote === "string") {
- filePath = folderNote;
- } else {
- fileName = folderNote.basename;
- filePath = folderNote.path;
- }
- const folderName = extractFolderName(plugin.settings.folderNoteName, fileName);
- if (!folderName)
- return null;
- let folderPath = plugin.getFolderPathFromString(filePath);
- if (plugin.settings.storageLocation === "parentFolder") {
- if (folderPath.trim() === "") {
- folderPath = folderName;
- } else {
- folderPath = `${folderPath}/${folderName}`;
- }
- } else {
- folderPath = plugin.getFolderPathFromString(filePath);
- }
- const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
- if (!folder) {
- return null;
- }
- return folder;
-}
-
-// src/events/frontMatterTitle.ts
-var import_front_matter_plugin_api_provider = __toESM(require_lib());
-var import_obsidian11 = require("obsidian");
-var FrontMatterTitlePluginHandler = class {
- constructor(plugin) {
- this.api = null;
- this.deffer = null;
- this.modifiedFolders = /* @__PURE__ */ new Map();
- this.plugin = plugin;
- this.app = plugin.app;
- (async () => {
- var _a;
- this.deffer = (0, import_front_matter_plugin_api_provider.getDefer)(this.app);
- if (this.deffer.isPluginReady()) {
- this.api = this.deffer.getApi();
- } else {
- await this.deffer.awaitPlugin();
- this.api = this.deffer.getApi();
- if (!this.deffer.isFeaturesReady()) {
- await this.deffer.awaitFeatures();
- }
- }
- const dispatcher = (_a = this.api) == null ? void 0 : _a.getEventDispatcher();
- if (dispatcher) {
- this.dispatcher = dispatcher;
- }
- const event = {
- name: "manager:update",
- cb: (data) => {
- this.handleRename(data, true);
- }
- };
- const ref = dispatcher == null ? void 0 : dispatcher.addListener(event);
- if (ref) {
- this.eventRef = ref;
- }
- this.plugin.app.vault.getFiles().forEach((file) => {
- this.handleRename({ id: "", result: false, path: file.path }, false);
- });
- this.plugin.updateBreadcrumbs();
- })();
- }
- deleteEvent() {
- if (this.eventRef) {
- this.dispatcher.removeListener(this.eventRef);
- }
- }
- async handleRename(data, isEvent) {
- var _a, _b, _c;
- if (data.data)
- data = data.data;
- const file = this.app.vault.getAbstractFileByPath(data.path);
- if (!(file instanceof import_obsidian11.TFile)) {
- return;
- }
- const resolver = (_b = (_a = this.api) == null ? void 0 : _a.getResolverFactory()) == null ? void 0 : _b.createResolver("#feature-id#");
- const newName = resolver == null ? void 0 : resolver.resolve((_c = file == null ? void 0 : file.path) != null ? _c : "");
- const folder = getFolder(this.plugin, file);
- if ((extractFolderName(this.plugin.settings.folderNoteName, file.basename) || file.basename) !== (folder == null ? void 0 : folder.name)) {
- return;
- }
- if (!(folder instanceof import_obsidian11.TFolder)) {
- return;
- }
- if (isEvent) {
- this.plugin.changeName(folder, newName, true);
- } else {
- this.plugin.changeName(folder, newName, false);
- }
- if (newName) {
- folder.newName = newName;
- this.modifiedFolders.set(folder.path, folder);
- } else {
- folder.newName = null;
- this.modifiedFolders.delete(folder.path);
- }
- }
-};
-
-// src/settings.ts
-var DEFAULT_SETTINGS = {
- syncFolderName: true,
- ctrlKey: true,
- altKey: false,
- hideFolderNote: true,
- templatePath: "",
- autoCreate: false,
- enableCollapsing: false,
- excludeFolders: [],
- showDeleteConfirmation: true,
- underlineFolder: true,
- allowWhitespaceCollapsing: false,
- underlineFolderInPath: true,
- openFolderNoteOnClickInPath: true,
- openInNewTab: false,
- folderNoteName: "{{folder_name}}",
- folderNoteType: ".md",
- disableFolderHighlighting: false,
- newFolderNoteName: "{{folder_name}}",
- storageLocation: "insideFolder",
- syncDelete: false,
- showRenameConfirmation: true,
- defaultOverview: {
- title: "{{folderName}} overview",
- disableTitle: false,
- depth: 3,
- includeTypes: ["folder", "markdown"],
- style: "list",
- disableFileTag: false
- },
- useSubmenus: true,
- syncMove: true,
- frontMatterTitle: {
- enabled: false,
- explorer: true,
- path: true
- }
-};
-var SettingsTab = class extends import_obsidian12.PluginSettingTab {
- constructor(app2, plugin) {
- super(app2, plugin);
- }
- display() {
- const { containerEl } = this;
- containerEl.empty();
- containerEl.createEl("h2", { text: "Folder notes settings" });
- const nameSetting = new import_obsidian12.Setting(containerEl).setName("Folder note name").setDesc("{{folder_name}} will be replaced with the name of the folder").addText((text) => text.setValue(this.plugin.settings.newFolderNoteName).onChange(async (value) => {
- if (value.trim() === "") {
- return;
- }
- this.plugin.settings.newFolderNoteName = value;
- await this.plugin.saveSettings();
- })).addButton((button) => button.setButtonText("Rename existing folder notes").setCta().onClick(async () => {
- this.updateFolderNotes(this.plugin.settings.folderNoteName, this.plugin.settings.newFolderNoteName);
- }));
- nameSetting.infoEl.appendText("Make sure to back up your vault before renaming all folder notes and restart Obsidian after renaming them");
- nameSetting.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
- new import_obsidian12.Setting(containerEl).setName("Folder note type").setDesc("Choose the file type for creating new folder notes (markdown or canvas) old folder notes will not be changed and you can also create canvas/markdown files and change the name manually to the custom folder note name or to the name of the folder.").addDropdown((dropdown) => dropdown.addOption(".md", "markdown").addOption(".canvas", "canvas").setValue(this.plugin.settings.folderNoteType).onChange(async (value) => {
- this.plugin.settings.folderNoteType = value;
- await this.plugin.saveSettings();
- }));
- const setting = new import_obsidian12.Setting(containerEl);
- const desc = document.createDocumentFragment();
- desc.append("After setting the template path, restart Obsidian if the template folder path (from templater/templates) had been changed beforehand.", desc.createEl("br"), "Obsidian should also be restarted if the template path was removed.");
- setting.setName("Template path");
- setting.setDesc(desc).descEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
- setting.addSearch((cb) => {
- var _a;
- new TemplateSuggest(cb.inputEl, this.plugin);
- cb.setPlaceholder("Template path");
- cb.setValue(((_a = this.plugin.app.vault.getAbstractFileByPath(this.plugin.settings.templatePath)) == null ? void 0 : _a.name.replace(".md", "")) || "");
- cb.onChange(async (value) => {
- if (value.trim() === "") {
- this.plugin.settings.templatePath = "";
- await this.plugin.saveSettings();
- this.display();
- return;
- }
- });
- });
- const storageLocation = new import_obsidian12.Setting(containerEl).setName("Storage location").setDesc("Choose where to store the folder notes").addDropdown((dropdown) => dropdown.addOption("insideFolder", "Inside the folder").addOption("parentFolder", "In the parent folder").setValue(this.plugin.settings.storageLocation).onChange(async (value) => {
- this.plugin.settings.storageLocation = value;
- await this.plugin.saveSettings();
- this.display();
- this.plugin.loadFileClasses();
- }));
- storageLocation.infoEl.appendText("Requires a restart to take effect");
- storageLocation.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
- const switchLocation = new import_obsidian12.Setting(containerEl).setName("Switch to new storage location").setDesc("Move all folder notes to the new storage location").addButton((button) => button.setButtonText("Switch").setCta().onClick(async () => {
- let oldStorageLocation = this.plugin.settings.storageLocation;
- if (this.plugin.settings.storageLocation === "parentFolder") {
- oldStorageLocation = "insideFolder";
- } else if (this.plugin.settings.storageLocation === "insideFolder") {
- oldStorageLocation = "parentFolder";
- }
- this.switchStorageLocation(oldStorageLocation);
- }));
- switchLocation.infoEl.appendText("Requires a restart to take effect");
- switchLocation.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
- if (this.plugin.settings.storageLocation === "parentFolder") {
- new import_obsidian12.Setting(containerEl).setName("Delete folder notes when deleting the folder").setDesc("Delete the folder note when deleting the folder").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncDelete).onChange(async (value) => {
- this.plugin.settings.syncDelete = value;
- await this.plugin.saveSettings();
- }));
- new import_obsidian12.Setting(containerEl).setName("Move folder notes when moving the folder").setDesc("Move the folder note when moving the folder").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncMove).onChange(async (value) => {
- this.plugin.settings.syncMove = value;
- await this.plugin.saveSettings();
- }));
- }
- const disableSetting = new import_obsidian12.Setting(containerEl);
- disableSetting.setName("Disable folder collapsing");
- disableSetting.setDesc("Disable the ability to collapse folders by clicking exactly on the folder name");
- disableSetting.addToggle((toggle) => toggle.setValue(!this.plugin.settings.enableCollapsing).onChange(async (value) => {
- this.plugin.settings.enableCollapsing = !value;
- await this.plugin.saveSettings();
- }));
- disableSetting.infoEl.appendText("Requires a restart to take effect");
- disableSetting.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
- if (import_obsidian12.Platform.isDesktopApp) {
- new import_obsidian12.Setting(containerEl).setName("Key for creating folder note").setDesc("The key combination to create a folder note").addDropdown((dropdown) => {
- if (!import_obsidian12.Platform.isMacOS) {
- dropdown.addOption("ctrl", "Ctrl + Click");
- } else {
- dropdown.addOption("ctrl", "Cmd + Click");
- }
- dropdown.addOption("alt", "Alt + Click");
- dropdown.setValue(this.plugin.settings.ctrlKey ? "ctrl" : "alt");
- dropdown.onChange(async (value) => {
- this.plugin.settings.ctrlKey = value === "ctrl";
- this.plugin.settings.altKey = value === "alt";
- await this.plugin.saveSettings();
- this.display();
- });
- });
- }
- new import_obsidian12.Setting(containerEl).setName("Only open folder notes through the name").setDesc("Only open folder notes in the file explorer by clicking on the folder name").addToggle((toggle) => toggle.setValue(this.plugin.settings.allowWhitespaceCollapsing).onChange(async (value) => {
- if (!value) {
- document.body.classList.add("fn-whitespace-stop-collapsing");
- } else {
- document.body.classList.remove("fn-whitespace-stop-collapsing");
- }
- this.plugin.settings.allowWhitespaceCollapsing = value;
- await this.plugin.saveSettings();
- }));
- new import_obsidian12.Setting(containerEl).setName("Hide folder note").setDesc("Hide the folder note in the file explorer").addToggle((toggle) => toggle.setValue(this.plugin.settings.hideFolderNote).onChange(async (value) => {
- this.plugin.settings.hideFolderNote = value;
- await this.plugin.saveSettings();
- if (value) {
- document.body.classList.add("hide-folder-note");
- } else {
- document.body.classList.remove("hide-folder-note");
- }
- this.display();
- }));
- new import_obsidian12.Setting(containerEl).setName("Sync folder name").setDesc("Automatically rename the folder note when the folder name is changed").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncFolderName).onChange(async (value) => {
- this.plugin.settings.syncFolderName = value;
- await this.plugin.saveSettings();
- this.display();
- }));
- if (import_obsidian12.Platform.isDesktop) {
- const setting3 = new import_obsidian12.Setting(containerEl);
- setting3.setName("Open folder note in a new tab by default");
- setting3.setDesc("Always open folder notes in a new tab (except when you try to open the same note) instead of having to use ctrl/cmd + click to open in a new tab");
- setting3.addToggle((toggle) => toggle.setValue(this.plugin.settings.openInNewTab).onChange(async (value) => {
- this.plugin.settings.openInNewTab = value;
- await this.plugin.saveSettings();
- this.display();
- }));
- setting3.infoEl.appendText("Requires a restart to take effect");
- setting3.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
- }
- new import_obsidian12.Setting(containerEl).setName("Automatically create folder notes").setDesc("Automatically create a folder note when a new folder is created").addToggle((toggle) => toggle.setValue(this.plugin.settings.autoCreate).onChange(async (value) => {
- this.plugin.settings.autoCreate = value;
- await this.plugin.saveSettings();
- this.display();
- }));
- new import_obsidian12.Setting(containerEl).setName("Use submenus").setDesc("Use submenus for file/folder commands").addToggle((toggle) => toggle.setValue(this.plugin.settings.useSubmenus).onChange(async (value) => {
- this.plugin.settings.useSubmenus = value;
- await this.plugin.saveSettings();
- this.display();
- }));
- new import_obsidian12.Setting(containerEl).setName("Add underline to folders with folder notes").setDesc("Add an underline to folders that have a folder note in the file explorer").addToggle((toggle) => toggle.setValue(this.plugin.settings.underlineFolder).onChange(async (value) => {
- this.plugin.settings.underlineFolder = value;
- if (value) {
- document.body.classList.add("folder-note-underline");
- } else {
- document.body.classList.remove("folder-note-underline");
- }
- await this.plugin.saveSettings();
- }));
- new import_obsidian12.Setting(containerEl).setName("Open folder note through path").setDesc("Open a folder note when clicking on a folder name in the path if it is a folder note").addToggle((toggle) => toggle.setValue(this.plugin.settings.openFolderNoteOnClickInPath).onChange(async (value) => {
- this.plugin.settings.openFolderNoteOnClickInPath = value;
- await this.plugin.saveSettings();
- this.display();
- }));
- if (this.plugin.settings.openFolderNoteOnClickInPath) {
- new import_obsidian12.Setting(containerEl).setName("Underline folders in the path").setDesc("Add an underline to folders that have a folder note in the path above a note").addToggle((toggle) => toggle.setValue(this.plugin.settings.underlineFolderInPath).onChange(async (value) => {
- this.plugin.settings.underlineFolderInPath = value;
- if (value) {
- document.body.classList.add("folder-note-underline-path");
- } else {
- document.body.classList.remove("folder-note-underline-path");
- }
- await this.plugin.saveSettings();
- }));
- }
- new import_obsidian12.Setting(containerEl).setName("Enable front matter title plugin integration").setDesc("Automatically rename a folder name when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.enabled).onChange(async (value) => {
- var _a;
- this.plugin.settings.frontMatterTitle.enabled = value;
- await this.plugin.saveSettings();
- if (value) {
- this.plugin.fmtpHandler = new FrontMatterTitlePluginHandler(this.plugin);
- } else {
- if (this.plugin.fmtpHandler) {
- this.plugin.updateBreadcrumbs(true);
- }
- this.plugin.app.vault.getFiles().forEach((file) => {
- var _a2;
- (_a2 = this.plugin.fmtpHandler) == null ? void 0 : _a2.handleRename({ id: "", result: false, path: file.path }, false);
- });
- (_a = this.plugin.fmtpHandler) == null ? void 0 : _a.deleteEvent();
- this.plugin.fmtpHandler = null;
- }
- this.display();
- }));
- if (this.plugin.settings.frontMatterTitle.enabled) {
- new import_obsidian12.Setting(containerEl).setName("Include file explorer").setDesc("Automatically rename a folder name in the file explorer when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.explorer).onChange(async (value) => {
- this.plugin.settings.frontMatterTitle.explorer = value;
- await this.plugin.saveSettings();
- this.plugin.app.vault.getFiles().forEach((file) => {
- var _a;
- (_a = this.plugin.fmtpHandler) == null ? void 0 : _a.handleRename({ id: "", result: false, path: file.path }, false);
- });
- }));
- new import_obsidian12.Setting(containerEl).setName("Include path above note").setDesc("Automatically rename a folder name in the path above a note when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.path).onChange(async (value) => {
- this.plugin.settings.frontMatterTitle.path = value;
- await this.plugin.saveSettings();
- if (value) {
- this.plugin.updateBreadcrumbs();
- } else {
- this.plugin.updateBreadcrumbs(true);
- }
- }));
- }
- const manageExcluded = new import_obsidian12.Setting(containerEl).setHeading().setClass("fn-excluded-folder-heading").setName("Manage excluded folders");
- const desc3 = document.createDocumentFragment();
- desc3.append("Add {regex} at the beginning of the folder name to use a regex pattern.", desc.createEl("br"), "Use * before and after to exclude folders that include the name between the *s.", desc.createEl("br"), "Use * before the folder name to exclude folders that end with the folder name.", desc.createEl("br"), "Use * after the folder name to exclude folders that start with the folder name.");
- manageExcluded.setDesc(desc3);
- manageExcluded.infoEl.appendText("The regexes and wildcards are only for the folder name, not the path.");
- manageExcluded.infoEl.createEl("br");
- manageExcluded.infoEl.appendText("If you want to switch to a folder path delete the pattern first.");
- manageExcluded.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed";
- new import_obsidian12.Setting(containerEl).setName("Add excluded folder").setClass("add-exclude-folder-item").addButton((cb) => {
- cb.setIcon("plus");
- cb.setClass("add-exclude-folder");
- cb.setTooltip("Add excluded folder");
- cb.onClick(() => {
- const excludedFolder = new ExcludedFolder("", this.plugin.settings.excludeFolders.length);
- addExcludeFolderListItem(this, containerEl, excludedFolder);
- addExcludedFolder(this.plugin, excludedFolder);
- this.display();
- });
- });
- this.plugin.settings.excludeFolders.sort((a, b) => a.position - b.position).forEach((excludedFolder) => {
- var _a, _b;
- if (((_a = excludedFolder.string) == null ? void 0 : _a.trim()) !== "" && ((_b = excludedFolder.path) == null ? void 0 : _b.trim()) === "") {
- addExcludePatternListItem(this, containerEl, excludedFolder);
- } else {
- addExcludeFolderListItem(this, containerEl, excludedFolder);
- }
- });
- }
- updateFolderNotes(oldTemplate, newTemplate) {
- this.plugin.settings.folderNoteName = newTemplate;
- this.plugin.saveSettings();
- new import_obsidian12.Notice("Starting to update folder notes...");
- this.app.vault.getFiles().forEach((file) => {
- if (file instanceof import_obsidian12.TFile) {
- const folderPath = this.plugin.getFolderPathFromString(file.path);
- let folder = this.app.vault.getAbstractFileByPath(folderPath);
- let folderName = file.name.slice(0, -file.extension.length - 1);
- folderName = extractFolderName(oldTemplate, folderName) || "";
- if (!(folder instanceof import_obsidian12.TFolder) || folderName !== (folder == null ? void 0 : folder.name)) {
- if (folderPath.trim() === "") {
- folder = this.app.vault.getAbstractFileByPath(folderName);
- } else {
- folder = this.app.vault.getAbstractFileByPath(folderPath + "/" + folderName);
- }
- }
- if (!(folder instanceof import_obsidian12.TFolder)) {
- return;
- }
- if (folderName === (folder == null ? void 0 : folder.name)) {
- const newPath = `${folder == null ? void 0 : folder.path}/${this.plugin.settings.folderNoteName.replace("{{folder_name}}", folderName)}.${file.extension}`;
- this.app.vault.rename(file, newPath);
- } else if ((folder == null ? void 0 : folder.name) === file.name.slice(0, -file.extension.length - 1) || "") {
- const newPath = `${folder == null ? void 0 : folder.path}/${this.plugin.settings.folderNoteName.replace("{{folder_name}}", file.name.slice(0, -file.extension.length - 1) || "")}.${file.extension}`;
- this.app.vault.rename(file, newPath);
- }
- }
- });
- new import_obsidian12.Notice("Finished updating folder notes");
- }
- switchStorageLocation(oldMethod) {
- new import_obsidian12.Notice("Starting to switch storage location...");
- this.app.vault.getAllLoadedFiles().forEach((file) => {
- if (file instanceof import_obsidian12.TFolder) {
- const folderNote = getFolderNote(this.plugin, file.path, oldMethod);
- if (folderNote instanceof import_obsidian12.TFile) {
- if (this.plugin.settings.storageLocation === "parentFolder") {
- let newPath = "";
- if (this.plugin.getFolderPathFromString(file.path).trim() === "") {
- newPath = `${folderNote.name}`;
- } else {
- newPath = `${this.plugin.getFolderPathFromString(file.path)}/${folderNote.name}`;
- }
- this.app.vault.rename(folderNote, newPath);
- } else if (this.plugin.settings.storageLocation === "insideFolder") {
- if (this.plugin.getFolderPathFromString(folderNote.path) === file.path) {
- return;
- } else {
- const newPath = `${file.path}/${folderNote.name}`;
- this.app.vault.rename(folderNote, newPath);
- }
- }
- }
- }
- });
- new import_obsidian12.Notice("Finished switching storage location");
- }
-};
-
-// src/commands.ts
-var import_obsidian13 = require("obsidian");
-var Commands = class {
- constructor(app2, plugin) {
- this.plugin = plugin;
- this.app = app2;
- }
- registerCommands() {
- this.plugin.registerEvent(this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => {
- const text = editor.getSelection().trim();
- menu.addItem((item) => {
- item.setTitle("Create folder overview").setIcon("edit").onClick(() => {
- editor.replaceSelection("```folder-overview\n```\n");
- });
- });
- if (!text || text.trim() === "")
- return;
- menu.addItem((item) => {
- item.setTitle("Create folder note").setIcon("edit").onClick(() => {
- const file = view.file;
- if (!(file instanceof import_obsidian13.TFile))
- return;
- const blacklist = ["*", "\\", '"', "/", "<", ">", "?", "|", ":"];
- for (const char of blacklist) {
- if (text.includes(char)) {
- new import_obsidian13.Notice('File name cannot contain any of the following characters: * " \\ / < > : | ?');
- return;
- }
- }
- if (text.endsWith(".")) {
- new import_obsidian13.Notice("File name cannot end with a dot");
- return;
- }
- let folder;
- const folderPath = this.plugin.getFolderPathFromString(file.path);
- if (folderPath === "") {
- folder = this.plugin.app.vault.getAbstractFileByPath(text);
- if (folder instanceof import_obsidian13.TFolder) {
- return new import_obsidian13.Notice("Folder note already exists");
- } else {
- this.plugin.app.vault.createFolder(text);
- createFolderNote(this.plugin, text, false);
- }
- } else {
- folder = this.plugin.app.vault.getAbstractFileByPath(folderPath + "/" + text);
- if (folder instanceof import_obsidian13.TFolder) {
- return new import_obsidian13.Notice("Folder note already exists");
- }
- if (this.plugin.settings.storageLocation === "parentFolder") {
- if (this.app.vault.getAbstractFileByPath(folderPath + "/" + text + this.plugin.settings.folderNoteType)) {
- return new import_obsidian13.Notice("File already exists");
- }
- }
- this.plugin.app.vault.createFolder(folderPath + "/" + text);
- createFolderNote(this.plugin, folderPath + "/" + text, false);
- }
- const fileName = this.plugin.settings.folderNoteName.replace("{{folder_name}}", text);
- if (fileName === text) {
- editor.replaceSelection(`[[${fileName}]]`);
- } else {
- editor.replaceSelection(`[[${fileName}|${text}]]`);
- }
- });
- });
- }));
- this.plugin.registerEvent(this.app.workspace.on("file-menu", (menu, file) => {
- var _a, _b, _c;
- let folder = file.parent;
- if (file instanceof import_obsidian13.TFile) {
- if (this.plugin.settings.storageLocation === "insideFolder") {
- folder = file.parent;
- } else {
- const fileName = extractFolderName(this.plugin.settings.folderNoteName, file.basename);
- if (fileName) {
- if (((_a = file.parent) == null ? void 0 : _a.path) === "" || ((_b = file.parent) == null ? void 0 : _b.path) === "/") {
- folder = this.plugin.app.vault.getAbstractFileByPath(fileName);
- } else {
- folder = this.plugin.app.vault.getAbstractFileByPath(((_c = file.parent) == null ? void 0 : _c.path) + "/" + fileName);
- }
- }
- }
- if (folder instanceof import_obsidian13.TFolder) {
- const folderNote = getFolderNote(this.plugin, folder.path);
- if ((folderNote == null ? void 0 : folderNote.path) === file.path) {
- return;
- }
- } else if (file.parent instanceof import_obsidian13.TFolder) {
- folder = file.parent;
- }
- }
- menu.addItem((item) => {
- if (import_obsidian13.Platform.isDesktop && !import_obsidian13.Platform.isTablet && this.plugin.settings.useSubmenus) {
- item.setTitle("Folder Note Commands").setIcon("folder-edit");
- }
- let subMenu;
- if (!import_obsidian13.Platform.isDesktopApp || !import_obsidian13.Platform.isDesktop || import_obsidian13.Platform.isTablet || !this.plugin.settings.useSubmenus) {
- subMenu = menu;
- item.setDisabled(true);
- } else {
- subMenu = item.setSubmenu();
- }
- if (file instanceof import_obsidian13.TFile) {
- subMenu.addItem((item2) => {
- item2.setTitle("Create folder note").setIcon("edit").onClick(async () => {
- if (!folder)
- return;
- let newPath = folder.path + "/" + file.basename;
- if (folder.path === "" || folder.path === "/") {
- newPath = file.basename;
- }
- if (this.plugin.app.vault.getAbstractFileByPath(newPath)) {
- return new import_obsidian13.Notice("Folder already exists");
- }
- await this.plugin.app.vault.createFolder(newPath);
- const newFolder = this.plugin.app.vault.getAbstractFileByPath(newPath);
- if (!(newFolder instanceof import_obsidian13.TFolder))
- return;
- createFolderNote(this.plugin, newFolder.path, true, false, file);
- });
- });
- if (this.plugin.getFolderPathFromString(file.path) === "")
- return;
- if (!(folder instanceof import_obsidian13.TFolder))
- return;
- subMenu.addItem((item2) => {
- item2.setTitle("Turn into folder note").setIcon("edit").onClick(() => {
- if (!folder || !(folder instanceof import_obsidian13.TFolder))
- return;
- const folderNote2 = getFolderNote(this.plugin, folder.path);
- turnIntoFolderNote(this.plugin, file, folder, folderNote2);
- });
- });
- }
- if (!(file instanceof import_obsidian13.TFolder))
- return;
- if (this.plugin.settings.excludeFolders.find((folder2) => folder2.path === file.path)) {
- subMenu.addItem((item2) => {
- item2.setTitle("Remove folder from excluded folders").setIcon("trash").onClick(() => {
- this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter((folder2) => folder2.path !== file.path);
- this.plugin.saveSettings();
- new import_obsidian13.Notice("Successfully removed folder from excluded folders");
- });
- });
- return;
- }
- subMenu.addItem((item2) => {
- item2.setTitle("Exclude folder from folder notes").setIcon("x-circle").onClick(() => {
- const excludedFolder = new ExcludedFolder(file.path, this.plugin.settings.excludeFolders.length);
- this.plugin.settings.excludeFolders.push(excludedFolder);
- this.plugin.saveSettings();
- new import_obsidian13.Notice("Successfully excluded folder from folder notes");
- });
- });
- if (!(file instanceof import_obsidian13.TFolder))
- return;
- const folderNote = getFolderNote(this.plugin, file.path);
- if (folderNote instanceof import_obsidian13.TFile) {
- subMenu.addItem((item2) => {
- item2.setTitle("Delete folder note").setIcon("trash").onClick(() => {
- deleteFolderNote(this.plugin, folderNote);
- });
- });
- subMenu.addItem((item2) => {
- item2.setTitle("Open folder note").setIcon("chevron-right-square").onClick(() => {
- openFolderNote(this.plugin, folderNote);
- });
- });
- } else {
- subMenu.addItem((item2) => {
- item2.setTitle("Create folder note").setIcon("edit").onClick(() => {
- createFolderNote(this.plugin, file.path, true);
- });
- });
- }
- });
- }));
- }
-};
-
-// src/events/handleClick.ts
-var import_obsidian14 = require("obsidian");
-async function handleViewHeaderClick(event, plugin) {
- if (!(event.target instanceof HTMLElement))
- return;
- if (!plugin.settings.openFolderNoteOnClickInPath)
- return;
- const folderPath = event.target.getAttribute("data-path");
- if (!folderPath) {
- return;
- }
- const excludedFolder = getExcludedFolder(plugin, folderPath);
- if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
- event.target.onclick = null;
- event.target.click();
- return;
- } else if ((excludedFolder == null ? void 0 : excludedFolder.enableCollapsing) || plugin.settings.enableCollapsing) {
- event.target.onclick = null;
- event.target.click();
- }
- const folderNote = getFolderNote(plugin, folderPath);
- if (folderNote) {
- return openFolderNote(plugin, folderNote, event);
- } else if (event.altKey || import_obsidian14.Keymap.isModEvent(event) === "tab") {
- if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian14.Keymap.isModEvent(event) === "tab") {
- await createFolderNote(plugin, folderPath, true, true);
- plugin.addCSSClassToTitleEL(folderPath, "has-folder-note");
- plugin.removeCSSClassFromEL(folderPath, "has-not-folder-note");
- return;
- }
- }
- event.target.onclick = null;
- event.target.click();
-}
-async function handleFolderClick(event, plugin) {
- var _a;
- if (!(event.target instanceof HTMLElement))
- return;
- event.stopImmediatePropagation();
- const folderPath = (_a = event.target.parentElement) == null ? void 0 : _a.getAttribute("data-path");
- if (!folderPath) {
- return;
- }
- const excludedFolder = getExcludedFolder(plugin, folderPath);
- if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
- event.target.onclick = null;
- event.target.click();
- return;
- } else if ((excludedFolder == null ? void 0 : excludedFolder.enableCollapsing) || plugin.settings.enableCollapsing) {
- event.target.onclick = null;
- event.target.click();
- }
- const folderNote = getFolderNote(plugin, folderPath);
- if (folderNote) {
- return openFolderNote(plugin, folderNote, event);
- } else if (event.altKey || import_obsidian14.Keymap.isModEvent(event) === "tab") {
- if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian14.Keymap.isModEvent(event) === "tab") {
- await createFolderNote(plugin, folderPath, true, true);
- plugin.addCSSClassToTitleEL(folderPath, "has-folder-note");
- plugin.removeCSSClassFromEL(folderPath, "has-not-folder-note");
- return;
- }
- }
- event.target.onclick = null;
- event.target.click();
-}
-
-// src/events/handleRename.ts
-var import_obsidian15 = require("obsidian");
-function handleFolderRename(file, oldPath, plugin) {
- const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.name);
- const folder = plugin.app.vault.getAbstractFileByPath(file.path);
- const folderNote = getFolderNote(plugin, oldPath);
- if (!(folderNote instanceof import_obsidian15.TFile))
- return;
- if (!(folder instanceof import_obsidian15.TFolder))
- return;
- const excludedFolders = plugin.settings.excludeFolders.filter((excludedFolder2) => excludedFolder2.path.includes(oldPath));
- excludedFolders.forEach((excludedFolder2) => {
- if (excludedFolder2.path === oldPath) {
- excludedFolder2.path = folder.path;
- return;
- }
- const folders = excludedFolder2.path.split("/");
- if (folders.length < 1) {
- folders.push(excludedFolder2.path);
- }
- folders[folders.indexOf(folder.name)] = folder.name;
- excludedFolder2.path = folders.join("/");
- });
- plugin.saveSettings();
- const excludedFolder = getExcludedFolder(plugin, file.path);
- if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && !folderNote) {
- return plugin.removeCSSClassFromEL(file.path, "has-folder-note");
- }
- let newPath = "";
- if (plugin.settings.storageLocation === "parentFolder") {
- const parentFolderPath = plugin.getFolderPathFromString(file.path);
- const oldParentFolderPath = plugin.getFolderPathFromString(oldPath);
- if (parentFolderPath !== oldParentFolderPath) {
- if (!plugin.settings.syncMove) {
- return;
- }
- newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`;
- } else if (parentFolderPath.trim() === "") {
- folderNote.path = `${folderNote.name}`;
- newPath = `${fileName}.${folderNote.extension}`;
- } else {
- folderNote.path = `${parentFolderPath}/${folderNote.name}`;
- newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`;
- }
- } else {
- folderNote.path = `${file.path}/${folderNote.name}`;
- newPath = `${file.path}/${fileName}.${folderNote.extension}`;
- }
- plugin.app.vault.rename(folderNote, newPath);
-}
-function handleFileRename(file, oldPath, plugin) {
- const oldFileName = plugin.removeExtension(plugin.getFileNameFromPathString(oldPath));
- const oldFolder = getFolderNoteFolder(plugin, oldPath, oldFileName);
- const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename) || file.basename;
- const oldFolderName = extractFolderName(plugin.settings.folderNoteName, oldFileName) || oldFileName;
- const newFolder = getFolderNoteFolder(plugin, file, file.basename);
- let excludedFolder = getExcludedFolder(plugin, (newFolder == null ? void 0 : newFolder.path) || "");
- const folderNote = getFolderNote(plugin, oldPath, plugin.settings.storageLocation, file);
- if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && folderName === (newFolder == null ? void 0 : newFolder.name)) {
- plugin.addCSSClassToTitleEL(file.path, "is-folder-note");
- plugin.addCSSClassToTitleEL(newFolder.path, "has-folder-note");
- return;
- } else if (excludedFolder == null ? void 0 : excludedFolder.disableSync) {
- plugin.removeCSSClassFromEL(file.path, "is-folder-note");
- plugin.removeCSSClassFromEL((newFolder == null ? void 0 : newFolder.path) || "", "has-folder-note");
- return;
- }
- if (folderName === (newFolder == null ? void 0 : newFolder.name) && folderNote) {
- new import_obsidian15.Notice("Folder with same name already exists!");
- let excludedFolderExisted = true;
- let disabledSync = false;
- if (!excludedFolder) {
- excludedFolderExisted = false;
- excludedFolder = new ExcludedFolder((oldFolder == null ? void 0 : oldFolder.path) || "", plugin.settings.excludeFolders.length);
- addExcludedFolder(plugin, excludedFolder);
- } else if (!excludedFolder.disableSync) {
- disabledSync = false;
- excludedFolder.disableSync = true;
- updateExcludedFolder(plugin, excludedFolder, excludedFolder);
- }
- return plugin.app.vault.rename(file, oldPath).then(() => {
- if (!excludedFolder) {
- return;
- }
- if (!excludedFolderExisted) {
- deleteExcludedFolder(plugin, excludedFolder);
- } else if (!disabledSync) {
- excludedFolder.disableSync = false;
- updateExcludedFolder(plugin, excludedFolder, excludedFolder);
- }
- });
- }
- if (folderName === (newFolder == null ? void 0 : newFolder.name)) {
- plugin.addCSSClassToTitleEL(file.path, "is-folder-note");
- plugin.addCSSClassToTitleEL(newFolder.path, "has-folder-note");
- plugin.removeCSSClassFromEL(oldFolder == null ? void 0 : oldFolder.path, "has-folder-note");
- return;
- }
- if (!oldFolder)
- return;
- if (oldFolderName === oldFolder.name && (newFolder == null ? void 0 : newFolder.path) === oldFolder.path) {
- return renameFolderOnFileRename(file, oldPath, oldFolder, plugin);
- } else if (folderNote && oldFolderName === oldFolder.name) {
- return renameFolderOnFileRename(file, oldPath, oldFolder, plugin);
- }
- if (oldFolder.name === oldFileName && (newFolder == null ? void 0 : newFolder.path) !== oldFolder.path) {
- plugin.removeCSSClassFromEL(oldFolder.path, "has-folder-note");
- plugin.removeCSSClassFromEL(file.path, "is-folder-note");
- plugin.removeCSSClassFromEL(oldPath, "is-folder-note");
- }
-}
-async function renameFolderOnFileRename(file, oldPath, oldFolder, plugin) {
- var _a;
- const newFolderName = extractFolderName(plugin.settings.folderNoteName, file.basename);
- if (!newFolderName) {
- plugin.removeCSSClassFromEL(oldFolder.path, "has-folder-note");
- plugin.removeCSSClassFromEL(file.path, "is-folder-note");
- return;
- } else if (newFolderName === oldFolder.name) {
- plugin.addCSSClassToTitleEL(oldFolder.path, "has-folder-note");
- plugin.addCSSClassToTitleEL(file.path, "is-folder-note");
- return;
- }
- let newFolderPath = "";
- if (plugin.settings.storageLocation === "insideFolder") {
- newFolderPath = ((_a = oldFolder.parent) == null ? void 0 : _a.path) + "/" + newFolderName;
- } else {
- const parentFolderPath = plugin.getFolderPathFromString(file.path);
- if (parentFolderPath.trim() === "") {
- newFolderPath = `${newFolderName}`;
- } else {
- newFolderPath = `${parentFolderPath}/${newFolderName}`;
- }
- }
- if (plugin.app.vault.getAbstractFileByPath(newFolderPath) || plugin.app.vault.getAbstractFileByPath(newFolderName || "")) {
- await plugin.app.vault.rename(file, oldPath);
- return new import_obsidian15.Notice("A folder with the same name already exists");
- }
- await plugin.app.vault.rename(oldFolder, newFolderPath);
-}
-
-// src/folderOverview.ts
-var import_obsidian16 = require("obsidian");
-function createOverview(plugin, source, el, ctx) {
- let yaml = (0, import_obsidian16.parseYaml)(source);
- if (!yaml) {
- yaml = {
- title: plugin.settings.defaultOverview.title,
- disableTitle: plugin.settings.defaultOverview.disableTitle,
- depth: plugin.settings.defaultOverview.depth,
- type: plugin.settings.defaultOverview.type,
- includeTypes: plugin.settings.defaultOverview.includeTypes,
- style: plugin.settings.defaultOverview.style,
- disableFileTag: plugin.settings.defaultOverview.disableFileTag,
- sortBy: plugin.settings.defaultOverview.sortBy,
- showEmptyFolders: plugin.settings.defaultOverview.showEmptyFolders,
- onlyIncludeSubfolders: plugin.settings.defaultOverview.onlyIncludeSubfolders
- };
- }
- const depth = (yaml == null ? void 0 : yaml.depth) || 1;
- let title = (yaml == null ? void 0 : yaml.title) || plugin.settings.defaultOverview.title || "{{folderName}} overview";
- const folderName = extractFolderName(plugin.settings.folderNoteName, plugin.removeExtension(plugin.getFolderNameFromPathString(ctx.sourcePath)));
- title = title.replaceAll("{{folderName}}", folderName || "");
- const disableTitle = (yaml == null ? void 0 : yaml.disableTitle) || plugin.settings.defaultOverview.disableTitle || false;
- let includeTypes = (yaml == null ? void 0 : yaml.includeTypes) || plugin.settings.defaultOverview.includeTypes || ["folder", "markdown"];
- includeTypes = includeTypes.map((type) => type.toLowerCase());
- const style = (yaml == null ? void 0 : yaml.style) || "list";
- const disableFileTag = (yaml == null ? void 0 : yaml.disableFileTag) || plugin.settings.defaultOverview.disableFileTag || false;
- const showEmptyFolders = (yaml == null ? void 0 : yaml.showEmptyFolders) || plugin.settings.defaultOverview.showEmptyFolders || false;
- const root = el.createEl("div", { cls: "folder-overview" });
- const titleEl = root.createEl("h1", { cls: "folder-overview-title" });
- const ul = root.createEl("ul", { cls: "folder-overview-list" });
- if (!disableTitle) {
- titleEl.innerText = title;
- }
- if (includeTypes.length === 0) {
- return;
- }
- let files = [];
- const sourceFile = plugin.app.vault.getAbstractFileByPath(ctx.sourcePath);
- if (!sourceFile)
- return;
- const sourceFolderPath = plugin.getFolderPathFromString(ctx.sourcePath);
- let sourceFolder;
- if (sourceFile.parent instanceof import_obsidian16.TFolder) {
- sourceFolder = sourceFile.parent;
- } else {
- sourceFolder = plugin.app.vault.getAbstractFileByPath(plugin.getFolderPathFromString(ctx.sourcePath));
- }
- files = sourceFolder.children;
- files = files.filter((file) => {
- const folderPath = plugin.getFolderPathFromString(file.path);
- if (!folderPath.startsWith(sourceFolderPath)) {
- return false;
- }
- if (file.path === ctx.sourcePath) {
- return false;
- }
- if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth) {
- return true;
- }
- });
- if (!includeTypes.includes("folder")) {
- files = getAllFiles(files, sourceFolderPath, depth);
- }
- files = sortFiles(files, yaml, plugin);
- if (style === "grid") {
- const grid = root.createEl("div", { cls: "folder-overview-grid" });
- files.forEach(async (file) => {
- const gridItem = grid.createEl("div", { cls: "folder-overview-grid-item" });
- const gridArticle = gridItem.createEl("article", { cls: "folder-overview-grid-item-article" });
- if (file instanceof import_obsidian16.TFile) {
- const fileContent = await plugin.app.vault.read(file);
- const descriptionEl = gridArticle.createEl("p", { cls: "folder-overview-grid-item-description" });
- let description = fileContent.split("\n")[0];
- if (description.length > 64) {
- description = description.slice(0, 64) + "...";
- }
- descriptionEl.innerText = description;
- const link = gridArticle.createEl("a", { cls: "folder-overview-grid-item-link internal-link" });
- const title2 = link.createEl("h1", { cls: "folder-overview-grid-item-link-title" });
- title2.innerText = file.name.replace(".md", "").replace(".canvas", "");
- link.href = file.path;
- } else if (file instanceof import_obsidian16.TFolder) {
- const folderItem = gridArticle.createEl("div", { cls: "folder-overview-grid-item-folder" });
- const folderName2 = folderItem.createEl("h1", { cls: "folder-overview-grid-item-folder-name" });
- folderName2.innerText = file.name;
- }
- });
- } else if (style === "list") {
- const pathBlacklist = [];
- files.forEach((file) => {
- if (file instanceof import_obsidian16.TFolder) {
- const folderItem = addFolderList(plugin, ul, pathBlacklist, file);
- goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag);
- } else if (file instanceof import_obsidian16.TFile) {
- addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag);
- }
- });
- } else if (style === "explorer") {
- }
- if (includeTypes.length > 1 && style !== "grid" && (!showEmptyFolders || yaml.onlyIncludeSubfolders)) {
- removeEmptyFolders(ul, 1, yaml);
- }
-}
-function goThroughFolders(plugin, list, folder, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag) {
- if (sourceFolderPath === "") {
- depth--;
- }
- let files = folder.children.filter((file) => {
- const folderPath = plugin.getFolderPathFromString(file.path);
- if (!folderPath.startsWith(sourceFolderPath)) {
- return false;
- }
- if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth) {
- return true;
- }
- });
- files = sortFiles(files, yaml, plugin);
- const ul = list.createEl("ul", { cls: "folder-overview-list" });
- files.forEach((file) => {
- if (file instanceof import_obsidian16.TFolder) {
- const folderItem = addFolderList(plugin, ul, pathBlacklist, file);
- goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag);
- } else if (file instanceof import_obsidian16.TFile) {
- addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag);
- }
- });
-}
-function sortFiles(files, yaml, plugin) {
- if (!(yaml == null ? void 0 : yaml.sortBy)) {
- yaml.sortBy = plugin.settings.defaultOverview.sortBy || "name";
- }
- return files.sort((a, b) => {
- if (a instanceof import_obsidian16.TFolder && !(b instanceof import_obsidian16.TFolder)) {
- return -1;
- }
- if (!(a instanceof import_obsidian16.TFolder) && b instanceof import_obsidian16.TFolder) {
- return 1;
- }
- if (!(a instanceof import_obsidian16.TFile) || !(b instanceof import_obsidian16.TFile)) {
- return -1;
- }
- if (yaml.sortBy === "created") {
- if (a.stat.ctime > b.stat.ctime) {
- return -1;
- } else if (a.stat.ctime < b.stat.ctime) {
- return 1;
- }
- } else if (yaml.sortBy === "createdAsc") {
- if (a.stat.ctime < b.stat.ctime) {
- return -1;
- } else if (a.stat.ctime > b.stat.ctime) {
- return 1;
- }
- } else if (yaml.sortBy === "modified") {
- if (a.stat.mtime > b.stat.mtime) {
- return -1;
- } else if (a.stat.mtime < b.stat.mtime) {
- return 1;
- }
- } else if (yaml.sortBy === "modifiedAsc") {
- if (a.stat.mtime < b.stat.mtime) {
- return -1;
- } else if (a.stat.mtime > b.stat.mtime) {
- return 1;
- }
- }
- if (a.name < b.name && yaml.sortBy === "name") {
- return -1;
- } else if (a.name > b.name && yaml.sortBy === "nameAsc") {
- return -1;
- }
- if (a.name > b.name && yaml.sortBy === "name") {
- return 1;
- } else if (a.name < b.name && yaml.sortBy === "nameAsc") {
- return 1;
- }
- return 0;
- });
-}
-function removeEmptyFolders(ul, depth, yaml) {
- const childrensToRemove = [];
- ul.childNodes.forEach((el) => {
- const childrens = el.querySelector("ul");
- if (!childrens || childrens === null) {
- return;
- }
- if (childrens && !(childrens == null ? void 0 : childrens.hasChildNodes()) && !(el instanceof HTMLUListElement)) {
- childrensToRemove.push(el);
- } else if (el instanceof HTMLUListElement || el instanceof HTMLLIElement) {
- removeEmptyFolders(el, depth + 1, yaml);
- }
- });
- childrensToRemove.forEach((el) => {
- if (yaml.onlyIncludeSubfolders && depth === 1) {
- return;
- }
- el.remove();
- });
-}
-function addFolderList(plugin, list, pathBlacklist, folder) {
- const folderItem = list.createEl("li", { cls: "folder-overview-list folder-list" });
- const folderNote = getFolderNote(plugin, folder.path);
- if (folderNote instanceof import_obsidian16.TFile) {
- const folderNoteLink = folderItem.createEl("a", { cls: "folder-overview-list-item folder-name-item internal-link", href: folderNote.path });
- folderNoteLink.innerText = folder.name;
- pathBlacklist.push(folderNote.path);
- } else {
- const folderName = folderItem.createEl("span", { cls: "folder-overview-list-item folder-name-item" });
- folderName.innerText = folder.name;
- }
- return folderItem;
-}
-function addFileList(plugin, list, pathBlacklist, file, includeTypes, disableFileTag) {
- if (includeTypes.length > 0 && !includeTypes.includes("all")) {
- if (file.extension === "md" && !includeTypes.includes("markdown"))
- return;
- if (file.extension === "canvas" && !includeTypes.includes("canvas"))
- return;
- if (file.extension === "pdf" && !includeTypes.includes("pdf"))
- return;
- const imageTypes = ["jpg", "jpeg", "png", "gif", "svg", "webp"];
- if (imageTypes.includes(file.extension) && !includeTypes.includes("image"))
- return;
- const videoTypes = ["mp4", "webm", "ogv", "mov", "mkv"];
- if (videoTypes.includes(file.extension) && !includeTypes.includes("video"))
- return;
- const audioTypes = ["mp3", "wav", "m4a", "3gp", "flac", "ogg", "oga", "opus"];
- if (audioTypes.includes(file.extension) && includeTypes.includes("audio"))
- return;
- const allTypes = ["md", "canvas", "pdf", ...imageTypes, ...videoTypes, ...audioTypes];
- if (!allTypes.includes(file.extension) && !includeTypes.includes("other"))
- return;
- }
- if (pathBlacklist.includes(file.path))
- return;
- const listItem = list.createEl("li", { cls: "folder-overview-list file-link" });
- const nameItem = listItem.createEl("div", { cls: "folder-overview-list-item" });
- const link = nameItem.createEl("a", { cls: "internal-link", href: file.path });
- link.innerText = file.basename;
- if (file.extension !== "md" && !disableFileTag) {
- nameItem.createDiv({ cls: "nav-file-tag" }).innerText = file.extension;
- }
-}
-function getAllFiles(files, sourceFolderPath, depth) {
- const allFiles = [];
- files.forEach((file) => {
- if (file instanceof import_obsidian16.TFolder) {
- if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth - 1) {
- allFiles.push(...getAllFiles(file.children, sourceFolderPath, depth));
- }
- } else {
- allFiles.push(file);
- }
- });
- return allFiles;
-}
-
-// src/modals/folderOverview.ts
-var import_obsidian17 = require("obsidian");
-var FolderOverviewSettings = class extends import_obsidian17.Modal {
- constructor(app2, plugin, yaml, ctx, el) {
- super(app2);
- this.plugin = plugin;
- this.app = app2;
- this.yaml = yaml;
- this.ctx = ctx;
- this.el = el;
- if (!this.yaml) {
- this.yaml = {
- title: this.plugin.settings.defaultOverview.title,
- disableTitle: this.plugin.settings.defaultOverview.disableTitle,
- depth: this.plugin.settings.defaultOverview.depth,
- type: this.plugin.settings.defaultOverview.type,
- includeTypes: this.plugin.settings.defaultOverview.includeTypes,
- style: this.plugin.settings.defaultOverview.style,
- disableFileTag: this.plugin.settings.defaultOverview.disableFileTag,
- sortBy: this.plugin.settings.defaultOverview.sortBy,
- showEmptyFolders: this.plugin.settings.defaultOverview.showEmptyFolders,
- onlyIncludeSubfolders: this.plugin.settings.defaultOverview.onlyIncludeSubfolders
- };
- }
- }
- onOpen() {
- this.display();
- }
- display() {
- var _a, _b, _c, _d;
- const { contentEl } = this;
- contentEl.empty();
- contentEl.addEventListener("keydown", (e) => {
- if (e.key === "Enter") {
- this.close();
- }
- });
- contentEl.createEl("h2", { text: "Folder overview settings" });
- new import_obsidian17.Setting(contentEl).setName("Disable the title").setDesc("Choose if the title should be shown").addToggle((toggle) => toggle.setValue(this.yaml.disableTitle || false).onChange(async (value) => {
- this.yaml.disableTitle = value;
- this.display();
- await this.updateYaml();
- }));
- if (!this.yaml.disableTitle) {
- new import_obsidian17.Setting(contentEl).setName("Title").setDesc("Choose the title of the folder overview").addText((text) => {
- var _a2;
- return text.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.title) || "{{folderName}} overview").onChange(async (value) => {
- this.yaml.title = value;
- await this.updateYaml();
- });
- });
- }
- const setting = new import_obsidian17.Setting(contentEl);
- setting.setName("Include types");
- const list = setting.createList((list2) => {
- var _a2;
- return list2.addModal(this).setValues(((_a2 = this.yaml) == null ? void 0 : _a2.includeTypes) || this.plugin.settings.defaultOverview.includeTypes || []).addResetButton();
- });
- if ((((_b = (_a = this.yaml) == null ? void 0 : _a.includeTypes) == null ? void 0 : _b.length) || 0) < 8 && !((_c = this.yaml.includeTypes) == null ? void 0 : _c.includes("all"))) {
- setting.addDropdown((dropdown) => {
- if (!this.yaml.includeTypes)
- this.yaml.includeTypes = this.plugin.settings.defaultOverview.includeTypes || [];
- this.yaml.includeTypes = this.yaml.includeTypes.map((type) => type.toLowerCase());
- const options = [
- { value: "markdown", label: "Markdown" },
- { value: "folder", label: "Folder" },
- { value: "canvas", label: "Canvas" },
- { value: "pdf", label: "PDF" },
- { value: "image", label: "Image" },
- { value: "audio", label: "Audio" },
- { value: "video", label: "Video" },
- { value: "other", label: "All other file types" },
- { value: "all", label: "All file types" }
- ];
- options.forEach((option) => {
- var _a2;
- if (!((_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.includes(option.value))) {
- dropdown.addOption(option.value, option.label);
- }
- });
- dropdown.addOption("+", "+");
- dropdown.setValue("+");
- dropdown.onChange(async (value) => {
- var _a2;
- if (value === "all") {
- this.yaml.includeTypes = (_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.filter((type) => type === "folder");
- list.setValues(this.yaml.includeTypes);
- }
- await list.addValue(value.toLowerCase());
- await this.updateYaml();
- this.display();
- });
- });
- }
- let disableFileTag;
- (_d = this.yaml.includeTypes) == null ? void 0 : _d.forEach((type) => {
- type === "folder" || type === "markdown" ? disableFileTag = true : null;
- });
- if (disableFileTag) {
- new import_obsidian17.Setting(contentEl).setName("Disable file tag").setDesc("Choose if the file tag should be shown after the file name").addToggle((toggle) => {
- toggle.setValue(this.yaml.disableFileTag || this.plugin.settings.defaultOverview.disableFileTag || false).onChange(async (value) => {
- this.yaml.disableFileTag = value;
- await this.updateYaml();
- });
- });
- }
- new import_obsidian17.Setting(contentEl).setName("File depth").setDesc("File & folder = +1 depth").addSlider((slider) => {
- var _a2;
- return slider.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.depth) || 2).setLimits(1, 10, 1).onChange(async (value) => {
- this.yaml.depth = value;
- await this.updateYaml();
- });
- });
- new import_obsidian17.Setting(contentEl).setName("Overview style").setDesc("Choose the style of the overview (grid style soon)").addDropdown((dropdown) => {
- var _a2;
- return dropdown.addOption("list", "List").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.style) || "list").onChange(async (value) => {
- this.yaml.style = value;
- await this.updateYaml();
- });
- });
- new import_obsidian17.Setting(contentEl).setName("Sort files by").setDesc("Choose how the files should be sorted").addDropdown((dropdown) => {
- var _a2;
- return dropdown.addOption("name", "Name descending").addOption("created", "Created descending").addOption("modified", "Modified descending").addOption("nameAsc", "Name ascending").addOption("createdAsc", "Created ascending").addOption("modifiedAsc", "Modified ascending").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.sortBy) || "name").onChange(async (value) => {
- this.yaml.sortBy = value;
- await this.updateYaml();
- });
- });
- new import_obsidian17.Setting(contentEl).setName("Show folder names of empty folders").setDesc("That includes subfolders of the current folder when you are on file depth 1").addToggle((toggle) => {
- toggle.setValue(this.yaml.showEmptyFolders || this.plugin.settings.defaultOverview.showEmptyFolders || false).onChange(async (value) => {
- this.yaml.showEmptyFolders = value;
- this.yaml.onlyIncludeSubfolders = false;
- this.display();
- await this.updateYaml();
- });
- });
- if (this.yaml.showEmptyFolders) {
- new import_obsidian17.Setting(contentEl).setName("Only show first empty subfolders of current folder").addToggle((toggle) => {
- toggle.setValue(this.yaml.onlyIncludeSubfolders || this.plugin.settings.defaultOverview.onlyIncludeSubfolders || false).onChange(async (value) => {
- this.yaml.onlyIncludeSubfolders = value;
- await this.updateYaml();
- });
- });
- }
- }
- onClose() {
- const { contentEl } = this;
- contentEl.empty();
- }
- async updateYaml() {
- const file = this.plugin.app.vault.getAbstractFileByPath(this.ctx.sourcePath);
- if (!(file instanceof import_obsidian17.TFile))
- return;
- let stringYaml = (0, import_obsidian17.stringifyYaml)(this.yaml);
- await this.plugin.app.vault.process(file, (text) => {
- const info = this.ctx.getSectionInfo(this.el);
- if (stringYaml[stringYaml.length - 1] !== "\n") {
- stringYaml += "\n";
- }
- if (info) {
- const { lineStart } = info;
- const lineEnd = this.getCodeBlockEndLine(text, lineStart);
- if (lineEnd === -1 || !lineEnd)
- return text;
- const lineLength = lineEnd - lineStart;
- const lines = text.split("\n");
- lines.splice(lineStart, lineLength + 1, `\`\`\`folder-overview
-${stringYaml}\`\`\``);
- return lines.join("\n");
- }
- return `\`\`\`folder-overview
-${stringYaml}\`\`\``;
- });
- }
- getCodeBlockEndLine(text, startLine, count = 1) {
- let line = startLine + 1;
- const lines = text.split("\n");
- while (line < lines.length) {
- if (count > 20) {
- return -1;
- }
- if (lines[line].startsWith("```")) {
- return line;
- }
- line++;
- count++;
- }
- return line;
- }
-};
-
-// src/functions/ListComponent.ts
-var import_obsidian18 = require("obsidian");
-var ListComponent = class {
- constructor(containerEl) {
- this.containerEl = containerEl;
- this.controlEl = containerEl.querySelector(".setting-item-control") || containerEl;
- this.listEl = this.controlEl.createDiv("setting-command-hotkeys");
- }
- addModal(modal) {
- this.modal = modal;
- this.values = modal.yaml.includeTypes || [];
- return this;
- }
- setValues(values) {
- this.listEl.empty();
- this.values = values;
- this.modal.yaml.includeTypes = values;
- if (values.length !== 0) {
- values.forEach((value) => {
- this.addElement(value);
- });
- }
- this.modal.updateYaml();
- return this;
- }
- addElement(value) {
- this.listEl.createSpan("setting-hotkey", (span) => {
- span.innerText = value;
- const removeSpan = span.createEl("span", { cls: "ofn-list-item-remove setting-hotkey-icon" });
- const svg = '';
- const svgElement = removeSpan.createEl("span", { cls: "ofn-list-item-remove-icon" });
- svgElement.innerHTML = svg;
- removeSpan.onClickEvent((e) => {
- this.removeValue(value);
- span.remove();
- });
- });
- }
- async addValue(value) {
- this.values.push(value);
- this.addElement(value);
- this.modal.yaml.includeTypes = this.values;
- return this;
- }
- addResetButton() {
- const resetButton = this.controlEl.createEl("span", { cls: "clickable-icon setting-restore-hotkey-button" });
- const svg = '';
- resetButton.innerHTML = svg;
- resetButton.onClickEvent((e) => {
- this.modal.plugin.loadSettings();
- this.setValues(this.modal.plugin.settings.defaultOverview.includeTypes || []);
- this.modal.display();
- });
- return this;
- }
- removeValue(value) {
- this.values = this.values.filter((v) => v !== value);
- this.setValues(this.values);
- this.modal.display();
- }
-};
-function createList(cb) {
- const list = new ListComponent(this.settingEl);
- cb(list);
- return list;
-}
-import_obsidian18.Setting.prototype.createList = createList;
-
-// src/main.ts
-var FolderNotesPlugin = class extends import_obsidian19.Plugin {
- constructor() {
- super(...arguments);
- this.fmtpHandler = null;
- }
- async onload() {
- console.log("loading folder notes plugin");
- await this.loadSettings();
- this.settingsTab = new SettingsTab(this.app, this);
- this.addSettingTab(this.settingsTab);
- this.saveSettings();
- document.body.classList.add("folder-notes-plugin");
- if (this.settings.hideFolderNote) {
- document.body.classList.add("hide-folder-note");
- }
- if (this.settings.underlineFolder) {
- document.body.classList.add("folder-note-underline");
- }
- if (this.settings.underlineFolderInPath) {
- document.body.classList.add("folder-note-underline-path");
- }
- if (!this.settings.allowWhitespaceCollapsing) {
- document.body.classList.add("fn-whitespace-stop-collapsing");
- }
- new Commands(this.app, this).registerCommands();
- this.app.workspace.onLayoutReady(() => {
- if (this.settings.frontMatterTitle.enabled) {
- this.fmtpHandler = new FrontMatterTitlePluginHandler(this);
- }
- });
- this.observer = new MutationObserver((mutations) => {
- mutations.forEach((rec) => {
- if (rec.type === "childList") {
- rec.target.querySelectorAll("div.nav-folder-title-content").forEach((element) => {
- if (element.onclick)
- return;
- element.onclick = (event) => handleFolderClick(event, this);
- });
- if (!this.settings.openFolderNoteOnClickInPath) {
- return;
- }
- rec.target.querySelectorAll("span.view-header-breadcrumb").forEach((element) => {
- var _a, _b;
- const breadcrumbs = (_a = element.parentElement) == null ? void 0 : _a.querySelectorAll("span.view-header-breadcrumb");
- if (!breadcrumbs)
- return;
- let path = "";
- breadcrumbs.forEach((breadcrumb) => {
- var _a2;
- if (breadcrumb.hasAttribute("old-name")) {
- path += breadcrumb.getAttribute("old-name") + "/";
- } else {
- path += breadcrumb.innerText.trim() + "/";
- }
- const folderPath = path.slice(0, -1);
- breadcrumb.setAttribute("data-path", folderPath);
- const folder = (_a2 = this.fmtpHandler) == null ? void 0 : _a2.modifiedFolders.get(folderPath);
- if (folder && this.settings.frontMatterTitle.path && this.settings.frontMatterTitle.enabled) {
- breadcrumb.setAttribute("old-name", folder.name || "");
- breadcrumb.innerText = folder.newName || "";
- }
- const folderNote = getFolderNote(this, folderPath);
- if (folderNote) {
- breadcrumb.classList.add("has-folder-note");
- }
- });
- (_b = element.parentElement) == null ? void 0 : _b.setAttribute("data-path", path.slice(0, -1));
- if (breadcrumbs.length > 0) {
- breadcrumbs.forEach((breadcrumb) => {
- if (breadcrumb.onclick)
- return;
- breadcrumb.onclick = (event) => handleViewHeaderClick(event, this);
- });
- }
- });
- }
- });
- });
- this.observer.observe(document.body, {
- childList: true,
- subtree: true
- });
- this.registerEvent(this.app.workspace.on("layout-change", () => {
- this.loadFileClasses();
- }));
- this.registerEvent(this.app.vault.on("delete", (file) => {
- if (!(file instanceof import_obsidian19.TFile)) {
- return;
- }
- const parentPath = this.getFolderPathFromString(file.path);
- const parentName = this.getFileNameFromPathString(parentPath);
- if (parentName !== file.basename) {
- return;
- }
- this.removeCSSClassFromEL(parentPath, "has-folder-note");
- }));
- this.registerEvent(this.app.vault.on("create", (file) => {
- if (file instanceof import_obsidian19.TFile) {
- const folderName = extractFolderName(this.settings.folderNoteName, file.basename);
- const folder = getFolder(this, file);
- if (!folder) {
- return;
- }
- if (folderName !== folder.name) {
- return;
- }
- this.addCSSClassToTitleEL(folder.path, "has-folder-note");
- this.addCSSClassToTitleEL(file.path, "is-folder-note");
- }
- if (!this.app.workspace.layoutReady)
- return;
- if (!this.settings.autoCreate)
- return;
- if (!(file instanceof import_obsidian19.TFolder))
- return;
- const excludedFolder = getExcludedFolder(this, file.path);
- if (excludedFolder == null ? void 0 : excludedFolder.disableAutoCreate)
- return;
- const folderNote = getFolderNote(this, file.path);
- if (folderNote)
- return;
- createFolderNote(this, file.path, true, true);
- this.addCSSClassToTitleEL(file.path, "has-folder-note");
- }));
- this.registerEvent(this.app.workspace.on("file-open", (openFile) => {
- if (this.activeFolderDom) {
- this.activeFolderDom.removeClass("is-active");
- this.activeFolderDom = null;
- }
- if (!openFile || !openFile.basename) {
- return;
- }
- const folder = getFolder(this, openFile);
- if (!folder) {
- return;
- }
- if (extractFolderName(this.settings.folderNoteName, openFile.basename) !== folder.name) {
- return;
- }
- this.activeFolderDom = this.getEL(folder.path);
- if (this.activeFolderDom)
- this.activeFolderDom.addClass("is-active");
- }));
- this.registerEvent(this.app.vault.on("rename", (file, oldPath) => {
- if (!this.settings.syncFolderName) {
- this.removeCSSClassFromEL(file.path, "has-folder-note");
- this.removeCSSClassFromEL(file.path, "is-folder-note");
- return;
- }
- if (file instanceof import_obsidian19.TFolder) {
- return handleFolderRename(file, oldPath, this);
- } else if (file instanceof import_obsidian19.TFile) {
- return handleFileRename(file, oldPath, this);
- }
- }));
- this.registerEvent(this.app.vault.on("delete", (file) => {
- if (file instanceof import_obsidian19.TFile) {
- const folder = getFolder(this, file);
- if (!folder) {
- return;
- }
- this.removeCSSClassFromEL(folder.path, "has-folder-note");
- }
- if (!(file instanceof import_obsidian19.TFolder)) {
- return;
- }
- const folderNote = getFolderNote(this, file.path);
- if (!folderNote) {
- return;
- }
- this.removeCSSClassFromEL(folderNote.path, "is-folder-note");
- if (!this.settings.syncDelete) {
- return;
- }
- this.app.vault.delete(folderNote);
- }));
- this.registerMarkdownCodeBlockProcessor("folder-overview", (source, el, ctx) => {
- const observer = new MutationObserver(() => {
- var _a;
- const editButton = (_a = el.parentElement) == null ? void 0 : _a.childNodes.item(1);
- if (editButton) {
- editButton.addEventListener("click", (e) => {
- e.stopImmediatePropagation();
- e.preventDefault();
- e.stopPropagation();
- new FolderOverviewSettings(this.app, this, (0, import_obsidian19.parseYaml)(source), ctx, el).open();
- }, { capture: true });
- }
- });
- observer.observe(el, {
- childList: true,
- subtree: true
- });
- createOverview(this, source, el, ctx);
- });
- if (this.app.workspace.layoutReady) {
- this.loadFileClasses();
- } else {
- this.app.workspace.onLayoutReady(async () => this.loadFileClasses());
- }
- }
- getFileNameFromPathString(path) {
- return path.substring(path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") + 1 : 0);
- }
- getFolderNameFromPathString(path) {
- if (path.endsWith(".md") || path.endsWith(".canvas")) {
- return path.split("/").slice(-2)[0];
- } else {
- return path.split("/").slice(-1)[0];
- }
- }
- removeExtension(name) {
- return name.replace(/\.[^/.]+$/, "");
- }
- getExtensionFromPathString(path) {
- return path.slice(path.lastIndexOf(".") >= 0 ? path.lastIndexOf(".") : 0);
- }
- getFolderPathFromString(path) {
- const subString = path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") : 0;
- return path.substring(0, subString);
- }
- getParentFolderPath(path) {
- return this.getFolderPathFromString(this.getFolderPathFromString(path));
- }
- getFileExplorer() {
- return this.app.workspace.getLeavesOfType("file-explorer")[0];
- }
- getFileExplorerView() {
- return this.getFileExplorer().view;
- }
- async addCSSClassToTitleEL(path, cssClass, waitForCreate = false, count = 0) {
- const fileExplorerItem = this.getEL(path);
- if (!fileExplorerItem) {
- if (waitForCreate && count < 5) {
- await new Promise((r) => setTimeout(r, 500));
- this.addCSSClassToTitleEL(path, cssClass, waitForCreate, count + 1);
- return;
- }
- return;
- }
- fileExplorerItem.addClass(cssClass);
- const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`);
- viewHeaderItems.forEach((item) => {
- item.addClass(cssClass);
- });
- }
- async changeName(folder, name, replacePath, waitForCreate = false, count = 0) {
- if (!name)
- name = folder.name;
- let fileExplorerItem = this.getEL(folder.path);
- if (!fileExplorerItem) {
- if (waitForCreate && count < 5) {
- await new Promise((r) => setTimeout(r, 500));
- this.changeName(folder, name, replacePath, waitForCreate, count + 1);
- return;
- }
- return;
- }
- fileExplorerItem = fileExplorerItem.querySelector("div.nav-folder-title-content");
- if (!fileExplorerItem) {
- return;
- }
- if (this.settings.frontMatterTitle.explorer && this.settings.frontMatterTitle.enabled) {
- fileExplorerItem.innerText = name;
- fileExplorerItem.setAttribute("old-name", folder.name);
- } else {
- fileExplorerItem.innerText = folder.name;
- fileExplorerItem.removeAttribute("old-name");
- }
- if (replacePath) {
- this.updateBreadcrumbs();
- }
- }
- updateBreadcrumbs(remove) {
- if (!this.settings.frontMatterTitle.path && !remove) {
- return;
- }
- const viewHeaderItems = document.querySelectorAll("span.view-header-breadcrumb");
- const files = this.app.vault.getAllLoadedFiles().filter((file) => file instanceof import_obsidian19.TFolder);
- viewHeaderItems.forEach((item) => {
- if (!item.hasAttribute("data-path")) {
- return;
- }
- const path = item.getAttribute("data-path");
- const folder = files.find((file) => file.path === path);
- if (!(folder instanceof import_obsidian19.TFolder)) {
- return;
- }
- if (remove) {
- item.textContent = folder.name;
- item.removeAttribute("old-name");
- } else {
- item.textContent = folder.newName || folder.name;
- item.setAttribute("old-name", folder.name);
- item.setAttribute("data-path", folder.path);
- }
- });
- }
- removeCSSClassFromEL(path, cssClass) {
- if (!path)
- return;
- const fileExplorerItem = this.getEL(path);
- const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`);
- viewHeaderItems.forEach((item) => {
- item.removeClass(cssClass);
- });
- if (!fileExplorerItem) {
- return;
- }
- fileExplorerItem.removeClass(cssClass);
- }
- getEL(path) {
- const fileExplorer = this.getFileExplorer();
- if (!fileExplorer) {
- return null;
- }
- const fileExplorerItem = fileExplorer.view.fileItems[path];
- if (!fileExplorerItem) {
- return null;
- }
- if (fileExplorerItem.selfEl)
- return fileExplorerItem.selfEl;
- return fileExplorerItem.titleEl;
- }
- loadFileClasses(forceReload = false) {
- if (this.activeFileExplorer === this.getFileExplorer() && !forceReload) {
- return;
- }
- this.activeFileExplorer = this.getFileExplorer();
- this.app.vault.getAllLoadedFiles().forEach((file) => {
- if (!(file instanceof import_obsidian19.TFolder)) {
- return;
- }
- const folderNote = getFolderNote(this, file.path);
- if (!folderNote) {
- this.removeCSSClassFromEL(file == null ? void 0 : file.path, "has-folder-note");
- return;
- }
- const excludedFolder = getExcludedFolder(this, file.path);
- if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
- this.removeCSSClassFromEL(folderNote.path, "is-folder-note");
- this.removeCSSClassFromEL(file.path, "has-folder-note");
- } else {
- this.addCSSClassToTitleEL(folderNote.path, "is-folder-note");
- this.addCSSClassToTitleEL(file.path, "has-folder-note");
- }
- });
- }
- reloadHandlers() {
- document.querySelectorAll("div.nav-folder-title-content").forEach((element) => {
- if (element.onclick)
- return;
- element.onclick = (event) => handleFolderClick(event, this);
- });
- }
- onunload() {
- console.log("unloading folder notes plugin");
- this.observer.disconnect();
- document.body.classList.remove("folder-notes-plugin");
- document.body.classList.remove("folder-note-underline");
- document.body.classList.remove("hide-folder-note");
- document.body.classList.remove("fn-whitespace-stop-collapsing");
- if (this.activeFolderDom) {
- this.activeFolderDom.removeClass("is-active");
- }
- if (this.fmtpHandler) {
- this.fmtpHandler.deleteEvent();
- }
- }
- async loadSettings() {
- this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
- }
- async saveSettings() {
- await this.saveData(this.settings);
- this.loadFileClasses(true);
- }
-};
-//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibm9kZV9tb2R1bGVzL2Zyb250LW1hdHRlci1wbHVnaW4tYXBpLXByb3ZpZGVyL2xpYi9jb250cmFjdHMvQXBpLmpzIiwgIm5vZGVfbW9kdWxlcy9mcm9udC1tYXR0ZXItcGx1Z2luLWFwaS1wcm92aWRlci9saWIvY29udHJhY3RzL0V2ZW50RGlzcGF0Y2hlci5qcyIsICJub2RlX21vZHVsZXMvZnJvbnQtbWF0dGVyLXBsdWdpbi1hcGktcHJvdmlkZXIvbGliL2NvbnRyYWN0cy9SZXNvbHZlci5qcyIsICJub2RlX21vZHVsZXMvZnJvbnQtbWF0dGVyLXBsdWdpbi1hcGktcHJvdmlkZXIvbGliL2luZGV4LmpzIiwgInNyYy9tYWluLnRzIiwgInNyYy9zZXR0aW5ncy50cyIsICJzcmMvc3VnZ2VzdGVycy90ZW1wbGF0ZVN1Z2dlc3Rlci50cyIsICJzcmMvc3VnZ2VzdGVycy9zdWdnZXN0LnRzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZW51bXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZU5hbWUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0V2luZG93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2luc3RhbmNlT2YuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvYXBwbHlTdHlsZXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWF0aC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL3VzZXJBZ2VudC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9pc0xheW91dFZpZXdwb3J0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2NvbnRhaW5zLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldENvbXB1dGVkU3R5bGUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNUYWJsZUVsZW1lbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRFbGVtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFBhcmVudE5vZGUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvd2l0aGluLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0RnJlc2hTaWRlT2JqZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWVyZ2VQYWRkaW5nT2JqZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZXhwYW5kVG9IYXNoTWFwLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2Fycm93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0VmFyaWF0aW9uLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2NvbXB1dGVTdHlsZXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRPcHBvc2l0ZVBsYWNlbWVudC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFdpbmRvd1Njcm9sbC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRXaW5kb3dTY3JvbGxCYXJYLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFZpZXdwb3J0UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXREb2N1bWVudFJlY3QuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNTY3JvbGxQYXJlbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0U2Nyb2xsUGFyZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2xpc3RTY3JvbGxQYXJlbnRzLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvcmVjdFRvQ2xpZW50UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9jb21wdXRlT2Zmc2V0cy5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvY29tcHV0ZUF1dG9QbGFjZW1lbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZmxpcC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9oaWRlLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL29mZnNldC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0QWx0QXhpcy5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wcmV2ZW50T3ZlcmZsb3cuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZVNjcm9sbC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDb21wb3NpdGVSZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvb3JkZXJNb2RpZmllcnMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9kZWJvdW5jZS5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL21lcmdlQnlOYW1lLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvY3JlYXRlUG9wcGVyLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvcG9wcGVyLmpzIiwgInNyYy90ZW1wbGF0ZS50cyIsICJzcmMvbW9kYWxzL2V4aXN0aW5nTm90ZS50cyIsICJzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMudHMiLCAic3JjL21vZGFscy9kZWxldGVDb25maXJtYXRpb24udHMiLCAic3JjL2V4Y2x1ZGVkRm9sZGVyLnRzIiwgInNyYy9tb2RhbHMvZXhjbHVkZUZvbGRlclNldHRpbmdzLnRzIiwgInNyYy9zdWdnZXN0ZXJzL0ZvbGRlclN1Z2dlc3Rlci50cyIsICJzcmMvbW9kYWxzL3BhdHRlcm5TZXR0aW5ncy50cyIsICJzcmMvZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUudHMiLCAic3JjL2NvbW1hbmRzLnRzIiwgInNyYy9ldmVudHMvaGFuZGxlQ2xpY2sudHMiLCAic3JjL2V2ZW50cy9oYW5kbGVSZW5hbWUudHMiLCAic3JjL2ZvbGRlck92ZXJ2aWV3LnRzIiwgInNyYy9tb2RhbHMvZm9sZGVyT3ZlcnZpZXcudHMiLCAic3JjL2Z1bmN0aW9ucy9MaXN0Q29tcG9uZW50LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2NyZWF0ZUJpbmRpbmcgPSAodGhpcyAmJiB0aGlzLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcbiAgICBvW2syXSA9IG1ba107XG59KSk7XG52YXIgX19leHBvcnRTdGFyID0gKHRoaXMgJiYgdGhpcy5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRBcGlTYWZlID0gZXhwb3J0cy5nZXREZWZlciA9IGV4cG9ydHMuaXNQbHVnaW5FbmFibGVkID0gZXhwb3J0cy5QbHVnaW5Ob3RFbmFibGVkRXJyb3IgPSBleHBvcnRzLnBsdWdpbklkID0gdm9pZCAwO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9BcGlcIiksIGV4cG9ydHMpO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9FdmVudERpc3BhdGNoZXJcIiksIGV4cG9ydHMpO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9SZXNvbHZlclwiKSwgZXhwb3J0cyk7XG5leHBvcnRzLnBsdWdpbklkID0gJ29ic2lkaWFuLWZyb250LW1hdHRlci10aXRsZS1wbHVnaW4nO1xuY2xhc3MgUGx1Z2luTm90RW5hYmxlZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuZXhwb3J0cy5QbHVnaW5Ob3RFbmFibGVkRXJyb3IgPSBQbHVnaW5Ob3RFbmFibGVkRXJyb3I7XG4vKipcbiAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgb2JzaWRpYW4tZnJvbnQtbWF0dGVyLXRpdGxlLXBsdWdpbiBpcyBlbmFibGVkXG4gKiBAcGFyYW0gYXBwXG4gKi9cbmZ1bmN0aW9uIGlzUGx1Z2luRW5hYmxlZChhcHApIHtcbiAgICB2YXIgX2EsIF9iLCBfYztcbiAgICAvL0B0cy1pZ25vcmVcbiAgICByZXR1cm4gKF9jID0gKF9iID0gKF9hID0gYXBwID09PSBudWxsIHx8IGFwcCA9PT0gdm9pZCAwID8gdm9pZCAwIDogYXBwLnBsdWdpbnMpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5lbmFibGVkUGx1Z2lucykgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmhhcyhleHBvcnRzLnBsdWdpbklkKSkgIT09IG51bGwgJiYgX2MgIT09IHZvaWQgMCA/IF9jIDogZmFsc2U7XG59XG5leHBvcnRzLmlzUGx1Z2luRW5hYmxlZCA9IGlzUGx1Z2luRW5hYmxlZDtcbi8qKlxuICpcbiAqIEB0aHJvd3MgUGx1Z2luTm90RW5hYmxlZEVycm9yXG4gKi9cbmZ1bmN0aW9uIGdldERlZmVyKGFwcCkge1xuICAgIHZhciBfYSwgX2IsIF9jLCBfZDtcbiAgICAvL0B0cy1pZ25vcmVcbiAgICBjb25zdCBwbHVnaW4gPSAoX2IgPSAoX2EgPSBhcHAgPT09IG51bGwgfHwgYXBwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBhcHAucGx1Z2lucykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldFBsdWdpbihleHBvcnRzLnBsdWdpbklkKSkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogbnVsbDtcbiAgICBjb25zdCBkZWZlciA9IChfZCA9IChfYyA9IHBsdWdpbiA9PT0gbnVsbCB8fCBwbHVnaW4gPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBsdWdpbi5nZXREZWZlcikgPT09IG51bGwgfHwgX2MgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9jLmNhbGwocGx1Z2luKSkgIT09IG51bGwgJiYgX2QgIT09IHZvaWQgMCA/IF9kIDogbnVsbDtcbiAgICBpZiAoZGVmZXIgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBsdWdpbk5vdEVuYWJsZWRFcnJvcihgUGx1Z2luICR7ZXhwb3J0cy5wbHVnaW5JZH0gaXMgbm90IGVuYWJsZWQgb3Igb2xkIHZlcnNpb25gKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmVyO1xufVxuZXhwb3J0cy5nZXREZWZlciA9IGdldERlZmVyO1xuLyoqXG4gKiBXcmFwcGVyIGZvciBvYmplY3QuIEl0IHdpbGwgY2hlY2sgaXRzZWxmIGlmIHBsdWdpbiBpcyBlbmFibGVkIGFuZCByZWFkeVxuICogQHBhcmFtIGFwcFxuICovXG5mdW5jdGlvbiBnZXRBcGlTYWZlKGFwcCkge1xuICAgIHJldHVybiBuZXcgQXBpV3JhcHBlcihudWxsLCBhcHApO1xufVxuZXhwb3J0cy5nZXRBcGlTYWZlID0gZ2V0QXBpU2FmZTtcbmNsYXNzIEFwaVdyYXBwZXIge1xuICAgIGNvbnN0cnVjdG9yKGFwaSwgYXBwKSB7XG4gICAgICAgIHRoaXMuYXBpID0gYXBpO1xuICAgICAgICB0aGlzLmFwcCA9IGFwcDtcbiAgICB9XG4gICAgYmVmb3JlKCkge1xuICAgICAgICBpZiAodGhpcy5hcGkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWZlciA9IHRoaXMuZ2V0RGVmZmVyKCk7XG4gICAgICAgIGlmIChkZWZlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaSA9IGRlZmVyLmdldEFwaSgpO1xuICAgICAgICBpZiAoYXBpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVmZXIuYXdhaXRQbHVnaW4oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwaSA9IGRlZmVyLmdldEFwaSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmFwaSA9IGFwaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXREZWZmZXIoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0RGVmZXIodGhpcy5hcHApO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFBsdWdpbk5vdEVuYWJsZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRSZXNvbHZlckZhY3RvcnkoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldFJlc29sdmVyRmFjdG9yeSgpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBudWxsO1xuICAgIH1cbiAgICBnZXRFdmVudERpc3BhdGNoZXIoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldEV2ZW50RGlzcGF0Y2hlcigpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBudWxsO1xuICAgIH1cbiAgICBnZXRFbmFibGVkRmVhdHVyZXMoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldEVuYWJsZWRGZWF0dXJlcygpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBbXTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBURmlsZSwgVEZvbGRlciwgVEFic3RyYWN0RmlsZSwgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgcGFyc2VZYW1sIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBERUZBVUxUX1NFVFRJTkdTLCBGb2xkZXJOb3Rlc1NldHRpbmdzLCBTZXR0aW5nc1RhYiB9IGZyb20gJy4vc2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBDb21tYW5kcyB9IGZyb20gJy4vY29tbWFuZHMnO1xyXG5pbXBvcnQgeyBGaWxlRXhwbG9yZXJXb3Jrc3BhY2VMZWFmIH0gZnJvbSAnLi9nbG9iYWxzJztcclxuaW1wb3J0IHsgaGFuZGxlVmlld0hlYWRlckNsaWNrLCBoYW5kbGVGb2xkZXJDbGljayB9IGZyb20gJy4vZXZlbnRzL2hhbmRsZUNsaWNrJztcclxuaW1wb3J0IHsgaGFuZGxlRmlsZVJlbmFtZSwgaGFuZGxlRm9sZGVyUmVuYW1lIH0gZnJvbSAnLi9ldmVudHMvaGFuZGxlUmVuYW1lJztcclxuaW1wb3J0IHsgY3JlYXRlRm9sZGVyTm90ZSwgZXh0cmFjdEZvbGRlck5hbWUsIGdldEZvbGRlck5vdGUsIGdldEZvbGRlciB9IGZyb20gJy4vZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBnZXRFeGNsdWRlZEZvbGRlciB9IGZyb20gJy4vZXhjbHVkZWRGb2xkZXInO1xyXG5pbXBvcnQgeyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlciB9IGZyb20gJy4vZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUnO1xyXG5pbXBvcnQgeyBjcmVhdGVPdmVydmlldyBhcyBjcmVhdGVGb2xkZXJPdmVydmlldyB9IGZyb20gJy4vZm9sZGVyT3ZlcnZpZXcnO1xyXG5pbXBvcnQgeyBGb2xkZXJPdmVydmlld1NldHRpbmdzIH0gZnJvbSAnLi9tb2RhbHMvZm9sZGVyT3ZlcnZpZXcnO1xyXG5pbXBvcnQgJy4vZnVuY3Rpb25zL0xpc3RDb21wb25lbnQnO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGb2xkZXJOb3Rlc1BsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblx0b2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXI7XHJcblx0c2V0dGluZ3M6IEZvbGRlck5vdGVzU2V0dGluZ3M7XHJcblx0c2V0dGluZ3NUYWI6IFNldHRpbmdzVGFiO1xyXG5cdGFjdGl2ZUZvbGRlckRvbTogSFRNTEVsZW1lbnQgfCBudWxsO1xyXG5cdGFjdGl2ZUZpbGVFeHBsb3JlcjogRmlsZUV4cGxvcmVyV29ya3NwYWNlTGVhZjtcclxuXHRmbXRwSGFuZGxlcjogRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIgfCBudWxsID0gbnVsbDtcclxuXHRhc3luYyBvbmxvYWQoKSB7XHJcblx0XHRjb25zb2xlLmxvZygnbG9hZGluZyBmb2xkZXIgbm90ZXMgcGx1Z2luJyk7XHJcblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xyXG5cdFx0dGhpcy5zZXR0aW5nc1RhYiA9IG5ldyBTZXR0aW5nc1RhYih0aGlzLmFwcCwgdGhpcyk7XHJcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIodGhpcy5zZXR0aW5nc1RhYik7XHJcblx0XHR0aGlzLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRcdC8vIEFkZCBDU1MgQ2xhc3Nlc1xyXG5cdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmb2xkZXItbm90ZXMtcGx1Z2luJyk7XHJcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5oaWRlRm9sZGVyTm90ZSkgeyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2hpZGUtZm9sZGVyLW5vdGUnKTsgfVxyXG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVyKSB7IGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lJyk7IH1cclxuXHRcdGlmICh0aGlzLnNldHRpbmdzLnVuZGVybGluZUZvbGRlckluUGF0aCkgeyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2ZvbGRlci1ub3RlLXVuZGVybGluZS1wYXRoJyk7IH1cclxuXHRcdGlmICghdGhpcy5zZXR0aW5ncy5hbGxvd1doaXRlc3BhY2VDb2xsYXBzaW5nKSB7IGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTsgfVxyXG5cclxuXHRcdG5ldyBDb21tYW5kcyh0aGlzLmFwcCwgdGhpcykucmVnaXN0ZXJDb21tYW5kcygpO1xyXG5cclxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbkxheW91dFJlYWR5KCgpID0+IHtcclxuXHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5lbmFibGVkKSB7XHJcblx0XHRcdFx0dGhpcy5mbXRwSGFuZGxlciA9IG5ldyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlcih0aGlzKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5vYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnM6IE11dGF0aW9uUmVjb3JkW10pID0+IHtcclxuXHRcdFx0bXV0YXRpb25zLmZvckVhY2goKHJlYykgPT4ge1xyXG5cdFx0XHRcdGlmIChyZWMudHlwZSA9PT0gJ2NoaWxkTGlzdCcpIHtcclxuXHRcdFx0XHRcdCg8RWxlbWVudD5yZWMudGFyZ2V0KS5xdWVyeVNlbGVjdG9yQWxsKCdkaXYubmF2LWZvbGRlci10aXRsZS1jb250ZW50JylcclxuXHRcdFx0XHRcdFx0LmZvckVhY2goKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGVsZW1lbnQub25jbGljaykgcmV0dXJuO1xyXG5cdFx0XHRcdFx0XHRcdGVsZW1lbnQub25jbGljayA9IChldmVudDogTW91c2VFdmVudCkgPT4gaGFuZGxlRm9sZGVyQ2xpY2soZXZlbnQsIHRoaXMpO1xyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdGlmICghdGhpcy5zZXR0aW5ncy5vcGVuRm9sZGVyTm90ZU9uQ2xpY2tJblBhdGgpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0XHQoPEVsZW1lbnQ+cmVjLnRhcmdldCkucXVlcnlTZWxlY3RvckFsbCgnc3Bhbi52aWV3LWhlYWRlci1icmVhZGNydW1iJylcclxuXHRcdFx0XHRcdFx0LmZvckVhY2goKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgYnJlYWRjcnVtYnMgPSBlbGVtZW50LnBhcmVudEVsZW1lbnQ/LnF1ZXJ5U2VsZWN0b3JBbGwoJ3NwYW4udmlldy1oZWFkZXItYnJlYWRjcnVtYicpO1xyXG5cdFx0XHRcdFx0XHRcdGlmICghYnJlYWRjcnVtYnMpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRsZXQgcGF0aCA9ICcnO1xyXG5cdFx0XHRcdFx0XHRcdGJyZWFkY3J1bWJzLmZvckVhY2goKGJyZWFkY3J1bWI6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoYnJlYWRjcnVtYi5oYXNBdHRyaWJ1dGUoJ29sZC1uYW1lJykpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cGF0aCArPSBicmVhZGNydW1iLmdldEF0dHJpYnV0ZSgnb2xkLW5hbWUnKSArICcvJztcclxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHBhdGggKz0gYnJlYWRjcnVtYi5pbm5lclRleHQudHJpbSgpICsgJy8nO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyUGF0aCA9IHBhdGguc2xpY2UoMCwgLTEpO1xyXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5zZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcsIGZvbGRlclBhdGgpO1xyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyID0gdGhpcy5mbXRwSGFuZGxlcj8ubW9kaWZpZWRGb2xkZXJzLmdldChmb2xkZXJQYXRoKTtcclxuXHRcdFx0XHRcdFx0XHRcdGlmIChmb2xkZXIgJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLnBhdGggJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5zZXRBdHRyaWJ1dGUoJ29sZC1uYW1lJywgZm9sZGVyLm5hbWUgfHwgJycpO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhZGNydW1iLmlubmVyVGV4dCA9IGZvbGRlci5uZXdOYW1lIHx8ICcnO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcywgZm9sZGVyUGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoZm9sZGVyTm90ZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhZGNydW1iLmNsYXNzTGlzdC5hZGQoJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHRcdGVsZW1lbnQucGFyZW50RWxlbWVudD8uc2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnLCBwYXRoLnNsaWNlKDAsIC0xKSk7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGJyZWFkY3J1bWJzLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRcdFx0XHRcdGJyZWFkY3J1bWJzLmZvckVhY2goKGJyZWFkY3J1bWI6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGlmIChicmVhZGNydW1iLm9uY2xpY2spIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5vbmNsaWNrID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiBoYW5kbGVWaWV3SGVhZGVyQ2xpY2soZXZlbnQsIHRoaXMpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5vYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LmJvZHksIHtcclxuXHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRzdWJ0cmVlOiB0cnVlLFxyXG5cdFx0fSk7XHJcblx0XHR0aGlzLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAud29ya3NwYWNlLm9uKCdsYXlvdXQtY2hhbmdlJywgKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmxvYWRGaWxlQ2xhc3NlcygpO1xyXG5cdFx0fSkpO1xyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKCdkZWxldGUnLCAoZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7IHJldHVybjsgfVxyXG5cdFx0XHQvLyBwYXJlbnQgaXMgbnVsbCBoZXJlIGV2ZW4gaWYgdGhlIHBhcmVudCBleGlzdHNcclxuXHRcdFx0Ly8gbm90IGVudGlyZWx5IHN1cmUgd2h5XHJcblx0XHRcdGNvbnN0IHBhcmVudFBhdGggPSB0aGlzLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCk7XHJcblx0XHRcdGNvbnN0IHBhcmVudE5hbWUgPSB0aGlzLmdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcocGFyZW50UGF0aCk7XHJcblx0XHRcdGlmIChwYXJlbnROYW1lICE9PSBmaWxlLmJhc2VuYW1lKSB7IHJldHVybjsgfVxyXG5cdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKHBhcmVudFBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbignY3JlYXRlJywgKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBmaWxlLmJhc2VuYW1lKTtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIodGhpcywgZmlsZSk7XHJcblx0XHRcdFx0aWYgKCFmb2xkZXIpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0aWYgKGZvbGRlck5hbWUgIT09IGZvbGRlci5uYW1lKSB7IHJldHVybjsgfVxyXG5cdFx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCF0aGlzLmFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHkpIHJldHVybjtcclxuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLmF1dG9DcmVhdGUpIHJldHVybjtcclxuXHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSByZXR1cm47XHJcblx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gZ2V0RXhjbHVkZWRGb2xkZXIodGhpcywgZmlsZS5wYXRoKTtcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlQXV0b0NyZWF0ZSkgcmV0dXJuO1xyXG5cdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRpZiAoZm9sZGVyTm90ZSkgcmV0dXJuO1xyXG5cdFx0XHRjcmVhdGVGb2xkZXJOb3RlKHRoaXMsIGZpbGUucGF0aCwgdHJ1ZSwgdHJ1ZSk7XHJcblx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZmlsZS5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblxyXG5cdFx0fSkpO1xyXG5cclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC53b3Jrc3BhY2Uub24oJ2ZpbGUtb3BlbicsIChvcGVuRmlsZTogVEZpbGUgfCBudWxsKSA9PiB7XHJcblx0XHRcdGlmICh0aGlzLmFjdGl2ZUZvbGRlckRvbSkge1xyXG5cdFx0XHRcdHRoaXMuYWN0aXZlRm9sZGVyRG9tLnJlbW92ZUNsYXNzKCdpcy1hY3RpdmUnKTtcclxuXHRcdFx0XHR0aGlzLmFjdGl2ZUZvbGRlckRvbSA9IG51bGw7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCFvcGVuRmlsZSB8fCAhb3BlbkZpbGUuYmFzZW5hbWUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLCBvcGVuRmlsZSk7XHJcblx0XHRcdGlmICghZm9sZGVyKSB7IHJldHVybjsgfVxyXG5cdFx0XHRpZiAoZXh0cmFjdEZvbGRlck5hbWUodGhpcy5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgb3BlbkZpbGUuYmFzZW5hbWUpICE9PSBmb2xkZXIubmFtZSkgeyByZXR1cm47IH1cclxuXHRcdFx0dGhpcy5hY3RpdmVGb2xkZXJEb20gPSB0aGlzLmdldEVMKGZvbGRlci5wYXRoKTtcclxuXHRcdFx0aWYgKHRoaXMuYWN0aXZlRm9sZGVyRG9tKSB0aGlzLmFjdGl2ZUZvbGRlckRvbS5hZGRDbGFzcygnaXMtYWN0aXZlJyk7XHJcblx0XHR9KSk7XHJcblxyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKCdyZW5hbWUnLCAoZmlsZTogVEFic3RyYWN0RmlsZSwgb2xkUGF0aDogc3RyaW5nKSA9PiB7XHJcblx0XHRcdGlmICghdGhpcy5zZXR0aW5ncy5zeW5jRm9sZGVyTmFtZSkge1xyXG5cdFx0XHRcdC8vIGNsZWFudXAgYWZ0ZXIgb3Vyc2VsdmVzXHJcblx0XHRcdFx0dGhpcy5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdHJldHVybiBoYW5kbGVGb2xkZXJSZW5hbWUoZmlsZSwgb2xkUGF0aCwgdGhpcyk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0cmV0dXJuIGhhbmRsZUZpbGVSZW5hbWUoZmlsZSwgb2xkUGF0aCwgdGhpcyk7XHJcblx0XHRcdH1cclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbignZGVsZXRlJywgKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLCBmaWxlKTtcclxuXHRcdFx0XHRpZiAoIWZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRpZiAoIWZvbGRlck5vdGUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHRoaXMucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLnN5bmNEZWxldGUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHRoaXMuYXBwLnZhdWx0LmRlbGV0ZShmb2xkZXJOb3RlKTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJNYXJrZG93bkNvZGVCbG9ja1Byb2Nlc3NvcignZm9sZGVyLW92ZXJ2aWV3JywgKHNvdXJjZTogc3RyaW5nLCBlbDogSFRNTEVsZW1lbnQsIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCkgPT4ge1xyXG5cdFx0XHRjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHtcclxuXHRcdFx0XHRjb25zdCBlZGl0QnV0dG9uID0gZWwucGFyZW50RWxlbWVudD8uY2hpbGROb2Rlcy5pdGVtKDEpO1xyXG5cdFx0XHRcdGlmIChlZGl0QnV0dG9uKSB7XHJcblx0XHRcdFx0XHRlZGl0QnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGUpID0+IHtcclxuXHRcdFx0XHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuXHRcdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRcdFx0XHRuZXcgRm9sZGVyT3ZlcnZpZXdTZXR0aW5ncyh0aGlzLmFwcCwgdGhpcywgcGFyc2VZYW1sKHNvdXJjZSksIGN0eCwgZWwpLm9wZW4oKTtcclxuXHRcdFx0XHRcdH0sIHsgY2FwdHVyZTogdHJ1ZSB9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRvYnNlcnZlci5vYnNlcnZlKGVsLCB7XHJcblx0XHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRcdHN1YnRyZWU6IHRydWUsXHJcblx0XHRcdH0pO1xyXG5cdFx0XHRjcmVhdGVGb2xkZXJPdmVydmlldyh0aGlzLCBzb3VyY2UsIGVsLCBjdHgpO1xyXG5cdFx0fSk7XHJcblx0XHRpZiAodGhpcy5hcHAud29ya3NwYWNlLmxheW91dFJlYWR5KSB7XHJcblx0XHRcdHRoaXMubG9hZEZpbGVDbGFzc2VzKCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeShhc3luYyAoKSA9PiB0aGlzLmxvYWRGaWxlQ2xhc3NlcygpKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBwYXRoLnN1YnN0cmluZyhwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpICsgMSA6IDApO1xyXG5cdH1cclxuXHJcblx0Z2V0Rm9sZGVyTmFtZUZyb21QYXRoU3RyaW5nKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRpZiAocGF0aC5lbmRzV2l0aCgnLm1kJykgfHwgcGF0aC5lbmRzV2l0aCgnLmNhbnZhcycpKSB7XHJcblx0XHRcdHJldHVybiBwYXRoLnNwbGl0KCcvJykuc2xpY2UoLTIpWzBdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIHBhdGguc3BsaXQoJy8nKS5zbGljZSgtMSlbMF07XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZW1vdmVFeHRlbnNpb24obmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBuYW1lLnJlcGxhY2UoL1xcLlteLy5dKyQvLCAnJyk7XHJcblx0fVxyXG5cclxuXHRnZXRFeHRlbnNpb25Gcm9tUGF0aFN0cmluZyhwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdFx0cmV0dXJuIHBhdGguc2xpY2UocGF0aC5sYXN0SW5kZXhPZignLicpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcuJykgOiAwKTtcclxuXHR9XHJcblxyXG5cdGdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRjb25zdCBzdWJTdHJpbmcgPSBwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcvJykgOiAwO1xyXG5cdFx0cmV0dXJuIHBhdGguc3Vic3RyaW5nKDAsIHN1YlN0cmluZyk7XHJcblx0fVxyXG5cclxuXHRnZXRQYXJlbnRGb2xkZXJQYXRoKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyh0aGlzLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGgpKTtcclxuXHR9XHJcblxyXG5cdGdldEZpbGVFeHBsb3JlcigpIHtcclxuXHRcdHJldHVybiB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhdmVzT2ZUeXBlKCdmaWxlLWV4cGxvcmVyJylbMF0gYXMgRmlsZUV4cGxvcmVyV29ya3NwYWNlTGVhZjtcclxuXHR9XHJcblxyXG5cdGdldEZpbGVFeHBsb3JlclZpZXcoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRGaWxlRXhwbG9yZXIoKS52aWV3O1xyXG5cdH1cclxuXHJcblx0YXN5bmMgYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aDogc3RyaW5nLCBjc3NDbGFzczogc3RyaW5nLCB3YWl0Rm9yQ3JlYXRlID0gZmFsc2UsIGNvdW50ID0gMCkge1xyXG5cdFx0Y29uc3QgZmlsZUV4cGxvcmVySXRlbSA9IHRoaXMuZ2V0RUwocGF0aCk7XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHtcclxuXHRcdFx0aWYgKHdhaXRGb3JDcmVhdGUgJiYgY291bnQgPCA1KSB7XHJcblx0XHRcdFx0Ly8gc2xlZXAgZm9yIGEgc2Vjb25kIGZvciB0aGUgZmlsZS1leHBsb3JlciBldmVudCB0byBjYXRjaCB1cFxyXG5cdFx0XHRcdC8vIHRoaXMgaXMgYW5ub3lpbmcgYXMgaW4gbW9zdCBzY2FuYXJpb3Mgb3VyIHBsdWdpbiByZWNpZXZlcyB0aGUgZXZlbnQgYmVmb3JlIGZpbGUgZXhwbG9yZXJcclxuXHRcdFx0XHQvLyBJZiB3ZSBjb3VsZCBndWFycmFudGVlIGxvYWQgb3JkZXIgaXQgd291bGRuJ3QgYmUgYW4gaXNzdWUgYnV0IHdlIGNhbid0XHJcblx0XHRcdFx0Ly8gcmVhbGlzZSB0aGlzIGlzIHJhY2V5IGFuZCBuZWVkcyB0byBiZSBmaXhlZC5cclxuXHRcdFx0XHRhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCA1MDApKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKHBhdGgsIGNzc0NsYXNzLCB3YWl0Rm9yQ3JlYXRlLCBjb3VudCArIDEpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtLmFkZENsYXNzKGNzc0NsYXNzKTtcclxuXHRcdGNvbnN0IHZpZXdIZWFkZXJJdGVtcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYFtkYXRhLXBhdGg9XCIke3BhdGh9XCJdYCk7XHJcblx0XHR2aWV3SGVhZGVySXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG5cdFx0XHRpdGVtLmFkZENsYXNzKGNzc0NsYXNzKTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgY2hhbmdlTmFtZShmb2xkZXI6IFRGb2xkZXIsIG5hbWU6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQsIHJlcGxhY2VQYXRoOiBib29sZWFuLCB3YWl0Rm9yQ3JlYXRlID0gZmFsc2UsIGNvdW50ID0gMCkge1xyXG5cdFx0aWYgKCFuYW1lKSBuYW1lID0gZm9sZGVyLm5hbWU7XHJcblx0XHRsZXQgZmlsZUV4cGxvcmVySXRlbSA9IHRoaXMuZ2V0RUwoZm9sZGVyLnBhdGgpO1xyXG5cdFx0aWYgKCFmaWxlRXhwbG9yZXJJdGVtKSB7XHJcblx0XHRcdGlmICh3YWl0Rm9yQ3JlYXRlICYmIGNvdW50IDwgNSkge1xyXG5cdFx0XHRcdGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDUwMCkpO1xyXG5cdFx0XHRcdHRoaXMuY2hhbmdlTmFtZShmb2xkZXIsIG5hbWUsIHJlcGxhY2VQYXRoLCB3YWl0Rm9yQ3JlYXRlLCBjb3VudCArIDEpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtID0gZmlsZUV4cGxvcmVySXRlbS5xdWVyeVNlbGVjdG9yKCdkaXYubmF2LWZvbGRlci10aXRsZS1jb250ZW50JylcclxuXHRcdGlmICghZmlsZUV4cGxvcmVySXRlbSkgeyByZXR1cm47IH1cclxuXHRcdGlmICh0aGlzLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZXhwbG9yZXIgJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpIHtcclxuXHRcdFx0ZmlsZUV4cGxvcmVySXRlbS5pbm5lclRleHQgPSBuYW1lO1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLnNldEF0dHJpYnV0ZSgnb2xkLW5hbWUnLCBmb2xkZXIubmFtZSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLmlubmVyVGV4dCA9IGZvbGRlci5uYW1lO1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLnJlbW92ZUF0dHJpYnV0ZSgnb2xkLW5hbWUnKTtcclxuXHRcdH1cclxuXHRcdGlmIChyZXBsYWNlUGF0aCkge1xyXG5cdFx0XHR0aGlzLnVwZGF0ZUJyZWFkY3J1bWJzKCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHR1cGRhdGVCcmVhZGNydW1icyhyZW1vdmU/OiBib29sZWFuKSB7XHJcblx0XHRpZiAoIXRoaXMuc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5wYXRoICYmICFyZW1vdmUpIHsgcmV0dXJuOyB9XHJcblx0XHRjb25zdCB2aWV3SGVhZGVySXRlbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuLnZpZXctaGVhZGVyLWJyZWFkY3J1bWInKTtcclxuXHRcdGNvbnN0IGZpbGVzID0gdGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKS5maWx0ZXIoKGZpbGUpID0+IGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKTtcclxuXHRcdHZpZXdIZWFkZXJJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdGlmICghaXRlbS5oYXNBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRjb25zdCBwYXRoID0gaXRlbS5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpO1xyXG5cdFx0XHRjb25zdCBmb2xkZXIgPSBmaWxlcy5maW5kKChmaWxlKSA9PiBmaWxlLnBhdGggPT09IHBhdGgpO1xyXG5cdFx0XHRpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKHJlbW92ZSkge1xyXG5cdFx0XHRcdGl0ZW0udGV4dENvbnRlbnQgPSBmb2xkZXIubmFtZTtcclxuXHRcdFx0XHRpdGVtLnJlbW92ZUF0dHJpYnV0ZSgnb2xkLW5hbWUnKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRpdGVtLnRleHRDb250ZW50ID0gZm9sZGVyLm5ld05hbWUgfHwgZm9sZGVyLm5hbWU7XHJcblx0XHRcdFx0aXRlbS5zZXRBdHRyaWJ1dGUoJ29sZC1uYW1lJywgZm9sZGVyLm5hbWUpO1xyXG5cdFx0XHRcdGl0ZW0uc2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnLCBmb2xkZXIucGF0aCk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0cmVtb3ZlQ1NTQ2xhc3NGcm9tRUwocGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLCBjc3NDbGFzczogc3RyaW5nKSB7XHJcblx0XHRpZiAoIXBhdGgpIHJldHVybjtcclxuXHRcdGNvbnN0IGZpbGVFeHBsb3Jlckl0ZW0gPSB0aGlzLmdldEVMKHBhdGgpO1xyXG5cdFx0Y29uc3Qgdmlld0hlYWRlckl0ZW1zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgW2RhdGEtcGF0aD1cIiR7cGF0aH1cIl1gKTtcclxuXHRcdHZpZXdIZWFkZXJJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdGl0ZW0ucmVtb3ZlQ2xhc3MoY3NzQ2xhc3MpO1xyXG5cdFx0fSk7XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHsgcmV0dXJuOyB9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtLnJlbW92ZUNsYXNzKGNzc0NsYXNzKTtcclxuXHR9XHJcblxyXG5cdGdldEVMKHBhdGg6IHN0cmluZyk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XHJcblx0XHRjb25zdCBmaWxlRXhwbG9yZXIgPSB0aGlzLmdldEZpbGVFeHBsb3JlcigpO1xyXG5cdFx0aWYgKCFmaWxlRXhwbG9yZXIpIHsgcmV0dXJuIG51bGw7IH1cclxuXHRcdGNvbnN0IGZpbGVFeHBsb3Jlckl0ZW0gPSBmaWxlRXhwbG9yZXIudmlldy5maWxlSXRlbXNbcGF0aF07XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHsgcmV0dXJuIG51bGw7IH1cclxuXHRcdGlmIChmaWxlRXhwbG9yZXJJdGVtLnNlbGZFbCkgcmV0dXJuIGZpbGVFeHBsb3Jlckl0ZW0uc2VsZkVsO1xyXG5cdFx0cmV0dXJuIGZpbGVFeHBsb3Jlckl0ZW0udGl0bGVFbDtcclxuXHR9XHJcblxyXG5cdGxvYWRGaWxlQ2xhc3Nlcyhmb3JjZVJlbG9hZCA9IGZhbHNlKSB7XHJcblx0XHRpZiAodGhpcy5hY3RpdmVGaWxlRXhwbG9yZXIgPT09IHRoaXMuZ2V0RmlsZUV4cGxvcmVyKCkgJiYgIWZvcmNlUmVsb2FkKSB7IHJldHVybjsgfVxyXG5cdFx0dGhpcy5hY3RpdmVGaWxlRXhwbG9yZXIgPSB0aGlzLmdldEZpbGVFeHBsb3JlcigpO1xyXG5cdFx0dGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKS5mb3JFYWNoKChmaWxlKSA9PiB7XHJcblx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSkgeyByZXR1cm47IH1cclxuXHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcywgZmlsZS5wYXRoKTtcclxuXHRcdFx0aWYgKCFmb2xkZXJOb3RlKSB7XHJcblx0XHRcdFx0dGhpcy5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlPy5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHRoaXMsIGZpbGUucGF0aCk7XHJcblx0XHRcdC8vIGNsZWFudXAgYWZ0ZXIgb3Vyc2VsdmVzXHJcblx0XHRcdC8vIEluY2FzZSBzZXR0aW5ncyBoYXZlIGNoYW5nZWRcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRcdHRoaXMucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHJlbG9hZEhhbmRsZXJzKCkge1xyXG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZGl2Lm5hdi1mb2xkZXItdGl0bGUtY29udGVudCcpXHJcblx0XHRcdC5mb3JFYWNoKChlbGVtZW50OiBIVE1MRWxlbWVudCkgPT4ge1xyXG5cdFx0XHRcdGlmIChlbGVtZW50Lm9uY2xpY2spIHJldHVybjtcclxuXHRcdFx0XHRlbGVtZW50Lm9uY2xpY2sgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IGhhbmRsZUZvbGRlckNsaWNrKGV2ZW50LCB0aGlzKTtcclxuXHRcdFx0fSk7XHJcblx0fVxyXG5cclxuXHRvbnVubG9hZCgpIHtcclxuXHRcdGNvbnNvbGUubG9nKCd1bmxvYWRpbmcgZm9sZGVyIG5vdGVzIHBsdWdpbicpO1xyXG5cdFx0dGhpcy5vYnNlcnZlci5kaXNjb25uZWN0KCk7XHJcblx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZvbGRlci1ub3Rlcy1wbHVnaW4nKTtcclxuXHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lJyk7XHJcblx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUtZm9sZGVyLW5vdGUnKTtcclxuXHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTtcclxuXHRcdGlmICh0aGlzLmFjdGl2ZUZvbGRlckRvbSkgeyB0aGlzLmFjdGl2ZUZvbGRlckRvbS5yZW1vdmVDbGFzcygnaXMtYWN0aXZlJyk7IH1cclxuXHRcdGlmICh0aGlzLmZtdHBIYW5kbGVyKSB7XHJcblx0XHRcdHRoaXMuZm10cEhhbmRsZXIuZGVsZXRlRXZlbnQoKTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cclxuXHRhc3luYyBsb2FkU2V0dGluZ3MoKSB7XHJcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcclxuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XHJcblx0XHQvLyBjbGVhbnVwIGFueSBjc3MgaWYgd2UgbmVlZCB0b29cclxuXHRcdHRoaXMubG9hZEZpbGVDbGFzc2VzKHRydWUpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBOb3RpY2UsIFBsYXRmb3JtLCBQbHVnaW5TZXR0aW5nVGFiLCBTZXR0aW5nLCBURmlsZSwgVEZvbGRlciB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4vbWFpbic7XHJcbmltcG9ydCB7IFRlbXBsYXRlU3VnZ2VzdCB9IGZyb20gJy4vc3VnZ2VzdGVycy90ZW1wbGF0ZVN1Z2dlc3Rlcic7XHJcbmltcG9ydCB7IGV4dHJhY3RGb2xkZXJOYW1lLCBnZXRGb2xkZXJOb3RlIH0gZnJvbSAnLi9mdW5jdGlvbnMvZm9sZGVyTm90ZUZ1bmN0aW9ucyc7XHJcbmltcG9ydCB7IGFkZEV4Y2x1ZGVGb2xkZXJMaXN0SXRlbSwgRXhjbHVkZWRGb2xkZXIsIGFkZEV4Y2x1ZGVkRm9sZGVyLCBFeGNsdWRlUGF0dGVybiwgYWRkRXhjbHVkZVBhdHRlcm5MaXN0SXRlbSB9IGZyb20gJy4vZXhjbHVkZWRGb2xkZXInO1xyXG5pbXBvcnQgeyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlciB9IGZyb20gJy4vZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUnO1xyXG4vLyBpbXBvcnQgQ29uZmlybWF0aW9uTW9kYWwgZnJvbSBcIi4vbW9kYWxzL2NvbmZpcm1DcmVhdGlvblwiO1xyXG5pbXBvcnQgeyB5YW1sU2V0dGluZ3MgfSBmcm9tICcuL2ZvbGRlck92ZXJ2aWV3JztcclxuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJOb3Rlc1NldHRpbmdzIHtcclxuXHRzeW5jRm9sZGVyTmFtZTogYm9vbGVhbjtcclxuXHRjdHJsS2V5OiBib29sZWFuO1xyXG5cdGFsdEtleTogYm9vbGVhbjtcclxuXHRoaWRlRm9sZGVyTm90ZTogYm9vbGVhbjtcclxuXHR0ZW1wbGF0ZVBhdGg6IHN0cmluZztcclxuXHRhdXRvQ3JlYXRlOiBib29sZWFuO1xyXG5cdGVuYWJsZUNvbGxhcHNpbmc6IGJvb2xlYW47XHJcblx0ZXhjbHVkZUZvbGRlcnM6IChFeGNsdWRlUGF0dGVybiB8IEV4Y2x1ZGVkRm9sZGVyKVtdO1xyXG5cdHNob3dEZWxldGVDb25maXJtYXRpb246IGJvb2xlYW47XHJcblx0c2hvd1JlbmFtZUNvbmZpcm1hdGlvbjogYm9vbGVhbjtcclxuXHR1bmRlcmxpbmVGb2xkZXI6IGJvb2xlYW47XHJcblx0YWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZzogYm9vbGVhbjtcclxuXHR1bmRlcmxpbmVGb2xkZXJJblBhdGg6IGJvb2xlYW47XHJcblx0b3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoOiBib29sZWFuO1xyXG5cdG9wZW5Jbk5ld1RhYjogYm9vbGVhbjtcclxuXHRmb2xkZXJOb3RlTmFtZTogc3RyaW5nO1xyXG5cdG5ld0ZvbGRlck5vdGVOYW1lOiBzdHJpbmc7XHJcblx0Zm9sZGVyTm90ZVR5cGU6ICcubWQnIHwgJy5jYW52YXMnO1xyXG5cdGRpc2FibGVGb2xkZXJIaWdobGlnaHRpbmc6IGJvb2xlYW47XHJcblx0c3RvcmFnZUxvY2F0aW9uOiAnaW5zaWRlRm9sZGVyJyB8ICdwYXJlbnRGb2xkZXInIHwgJ3ZhdWx0Rm9sZGVyJztcclxuXHRzeW5jRGVsZXRlOiBib29sZWFuO1xyXG5cdGRlZmF1bHRPdmVydmlldzogeWFtbFNldHRpbmdzO1xyXG5cdHVzZVN1Ym1lbnVzOiBib29sZWFuO1xyXG5cdHN5bmNNb3ZlOiBib29sZWFuO1xyXG5cdGZyb250TWF0dGVyVGl0bGU6IHtcclxuXHRcdGVuYWJsZWQ6IGJvb2xlYW47XHJcblx0XHRleHBsb3JlcjogYm9vbGVhbjtcclxuXHRcdHBhdGg6IGJvb2xlYW47XHJcblx0fVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogRm9sZGVyTm90ZXNTZXR0aW5ncyA9IHtcclxuXHRzeW5jRm9sZGVyTmFtZTogdHJ1ZSxcclxuXHRjdHJsS2V5OiB0cnVlLFxyXG5cdGFsdEtleTogZmFsc2UsXHJcblx0aGlkZUZvbGRlck5vdGU6IHRydWUsXHJcblx0dGVtcGxhdGVQYXRoOiAnJyxcclxuXHRhdXRvQ3JlYXRlOiBmYWxzZSxcclxuXHRlbmFibGVDb2xsYXBzaW5nOiBmYWxzZSxcclxuXHRleGNsdWRlRm9sZGVyczogW10sXHJcblx0c2hvd0RlbGV0ZUNvbmZpcm1hdGlvbjogdHJ1ZSxcclxuXHR1bmRlcmxpbmVGb2xkZXI6IHRydWUsXHJcblx0YWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZzogZmFsc2UsXHJcblx0dW5kZXJsaW5lRm9sZGVySW5QYXRoOiB0cnVlLFxyXG5cdG9wZW5Gb2xkZXJOb3RlT25DbGlja0luUGF0aDogdHJ1ZSxcclxuXHRvcGVuSW5OZXdUYWI6IGZhbHNlLFxyXG5cdGZvbGRlck5vdGVOYW1lOiAne3tmb2xkZXJfbmFtZX19JyxcclxuXHRmb2xkZXJOb3RlVHlwZTogJy5tZCcsXHJcblx0ZGlzYWJsZUZvbGRlckhpZ2hsaWdodGluZzogZmFsc2UsXHJcblx0bmV3Rm9sZGVyTm90ZU5hbWU6ICd7e2ZvbGRlcl9uYW1lfX0nLFxyXG5cdHN0b3JhZ2VMb2NhdGlvbjogJ2luc2lkZUZvbGRlcicsXHJcblx0c3luY0RlbGV0ZTogZmFsc2UsXHJcblx0c2hvd1JlbmFtZUNvbmZpcm1hdGlvbjogdHJ1ZSxcclxuXHRkZWZhdWx0T3ZlcnZpZXc6IHtcclxuXHRcdHRpdGxlOiAne3tmb2xkZXJOYW1lfX0gb3ZlcnZpZXcnLFxyXG5cdFx0ZGlzYWJsZVRpdGxlOiBmYWxzZSxcclxuXHRcdGRlcHRoOiAzLFxyXG5cdFx0aW5jbHVkZVR5cGVzOiBbJ2ZvbGRlcicsICdtYXJrZG93biddLFxyXG5cdFx0c3R5bGU6ICdsaXN0JyxcclxuXHRcdGRpc2FibGVGaWxlVGFnOiBmYWxzZSxcclxuXHR9LFxyXG5cdHVzZVN1Ym1lbnVzOiB0cnVlLFxyXG5cdHN5bmNNb3ZlOiB0cnVlLFxyXG5cdGZyb250TWF0dGVyVGl0bGU6IHtcclxuXHRcdGVuYWJsZWQ6IGZhbHNlLFxyXG5cdFx0ZXhwbG9yZXI6IHRydWUsXHJcblx0XHRwYXRoOiB0cnVlLFxyXG5cdH1cclxufTtcclxuZXhwb3J0IGNsYXNzIFNldHRpbmdzVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XHJcblx0cGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbjtcclxuXHRhcHA6IEFwcDtcclxuXHRleGNsdWRlRm9sZGVyczogRXhjbHVkZWRGb2xkZXJbXTtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdFx0c3VwZXIoYXBwLCBwbHVnaW4pO1xyXG5cdH1cclxuXHRkaXNwbGF5KCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcclxuXHJcblx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xyXG5cclxuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0ZvbGRlciBub3RlcyBzZXR0aW5ncycgfSk7XHJcblxyXG5cdFx0Y29uc3QgbmFtZVNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0ZvbGRlciBub3RlIG5hbWUnKVxyXG5cdFx0XHQuc2V0RGVzYygne3tmb2xkZXJfbmFtZX19IHdpbGwgYmUgcmVwbGFjZWQgd2l0aCB0aGUgbmFtZSBvZiB0aGUgZm9sZGVyJylcclxuXHRcdFx0LmFkZFRleHQoKHRleHQpID0+XHJcblx0XHRcdFx0dGV4dFxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm5ld0ZvbGRlck5vdGVOYW1lKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpZiAodmFsdWUudHJpbSgpID09PSAnJykgeyByZXR1cm47IH1cclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubmV3Rm9sZGVyTm90ZU5hbWUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpXHJcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cclxuXHRcdFx0XHRidXR0b25cclxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KCdSZW5hbWUgZXhpc3RpbmcgZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0XHRcdC5zZXRDdGEoKVxyXG5cdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUZvbGRlck5vdGVzKHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCB0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdGb2xkZXJOb3RlTmFtZSk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0bmFtZVNldHRpbmcuaW5mb0VsLmFwcGVuZFRleHQoJ01ha2Ugc3VyZSB0byBiYWNrIHVwIHlvdXIgdmF1bHQgYmVmb3JlIHJlbmFtaW5nIGFsbCBmb2xkZXIgbm90ZXMgYW5kIHJlc3RhcnQgT2JzaWRpYW4gYWZ0ZXIgcmVuYW1pbmcgdGhlbScpO1xyXG5cdFx0bmFtZVNldHRpbmcuaW5mb0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdGb2xkZXIgbm90ZSB0eXBlJylcclxuXHRcdFx0LnNldERlc2MoJ0Nob29zZSB0aGUgZmlsZSB0eXBlIGZvciBjcmVhdGluZyBuZXcgZm9sZGVyIG5vdGVzIChtYXJrZG93biBvciBjYW52YXMpIG9sZCBmb2xkZXIgbm90ZXMgd2lsbCBub3QgYmUgY2hhbmdlZCBhbmQgeW91IGNhbiBhbHNvIGNyZWF0ZSBjYW52YXMvbWFya2Rvd24gZmlsZXMgYW5kIGNoYW5nZSB0aGUgbmFtZSBtYW51YWxseSB0byB0aGUgY3VzdG9tIGZvbGRlciBub3RlIG5hbWUgb3IgdG8gdGhlIG5hbWUgb2YgdGhlIGZvbGRlci4nKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCcubWQnLCAnbWFya2Rvd24nKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignLmNhbnZhcycsICdjYW52YXMnKVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogJy5tZCcgfCAnLmNhbnZhcycpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCk7XHJcblx0XHRjb25zdCBkZXNjID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xyXG5cdFx0ZGVzYy5hcHBlbmQoXHJcblx0XHRcdCdBZnRlciBzZXR0aW5nIHRoZSB0ZW1wbGF0ZSBwYXRoLCByZXN0YXJ0IE9ic2lkaWFuIGlmIHRoZSB0ZW1wbGF0ZSBmb2xkZXIgcGF0aCAoZnJvbSB0ZW1wbGF0ZXIvdGVtcGxhdGVzKSBoYWQgYmVlbiBjaGFuZ2VkIGJlZm9yZWhhbmQuJyxcclxuXHRcdFx0ZGVzYy5jcmVhdGVFbCgnYnInKSxcclxuXHRcdFx0J09ic2lkaWFuIHNob3VsZCBhbHNvIGJlIHJlc3RhcnRlZCBpZiB0aGUgdGVtcGxhdGUgcGF0aCB3YXMgcmVtb3ZlZC4nXHJcblx0XHQpO1xyXG5cdFx0c2V0dGluZy5zZXROYW1lKCdUZW1wbGF0ZSBwYXRoJyk7XHJcblx0XHRzZXR0aW5nLnNldERlc2MoZGVzYykuZGVzY0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblx0XHRzZXR0aW5nLmFkZFNlYXJjaCgoY2IpID0+IHtcclxuXHRcdFx0bmV3IFRlbXBsYXRlU3VnZ2VzdChjYi5pbnB1dEVsLCB0aGlzLnBsdWdpbik7XHJcblx0XHRcdGNiLnNldFBsYWNlaG9sZGVyKCdUZW1wbGF0ZSBwYXRoJyk7XHJcblx0XHRcdGNiLnNldFZhbHVlKHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgodGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoKT8ubmFtZS5yZXBsYWNlKCcubWQnLCAnJykgfHwgJycpO1xyXG5cdFx0XHRjYi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRpZiAodmFsdWUudHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoID0gJyc7XHJcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRjb25zdCBzdG9yYWdlTG9jYXRpb24gPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ1N0b3JhZ2UgbG9jYXRpb24nKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHdoZXJlIHRvIHN0b3JlIHRoZSBmb2xkZXIgbm90ZXMnKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCdpbnNpZGVGb2xkZXInLCAnSW5zaWRlIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbigncGFyZW50Rm9sZGVyJywgJ0luIHRoZSBwYXJlbnQgZm9sZGVyJylcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24pXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiAnaW5zaWRlRm9sZGVyJyB8ICdwYXJlbnRGb2xkZXInIHwgJ3ZhdWx0Rm9sZGVyJykgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5sb2FkRmlsZUNsYXNzZXMoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblx0XHRzdG9yYWdlTG9jYXRpb24uaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0c3RvcmFnZUxvY2F0aW9uLmluZm9FbC5zdHlsZS5jb2xvciA9IHRoaXMuYXBwLnZhdWx0LmdldENvbmZpZygnYWNjZW50Q29sb3InKSBhcyBzdHJpbmcgfHwgJyM3ZDViZWQnO1xyXG5cclxuXHRcdGNvbnN0IHN3aXRjaExvY2F0aW9uID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdTd2l0Y2ggdG8gbmV3IHN0b3JhZ2UgbG9jYXRpb24nKVxyXG5cdFx0XHQuc2V0RGVzYygnTW92ZSBhbGwgZm9sZGVyIG5vdGVzIHRvIHRoZSBuZXcgc3RvcmFnZSBsb2NhdGlvbicpXHJcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cclxuXHRcdFx0XHRidXR0b25cclxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KCdTd2l0Y2gnKVxyXG5cdFx0XHRcdFx0LnNldEN0YSgpXHJcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XHJcblx0XHRcdFx0XHRcdGxldCBvbGRTdG9yYWdlTG9jYXRpb24gPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb247XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdFx0b2xkU3RvcmFnZUxvY2F0aW9uID0gJ2luc2lkZUZvbGRlcic7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAnaW5zaWRlRm9sZGVyJykge1xyXG5cdFx0XHRcdFx0XHRcdG9sZFN0b3JhZ2VMb2NhdGlvbiA9ICdwYXJlbnRGb2xkZXInO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHRoaXMuc3dpdGNoU3RvcmFnZUxvY2F0aW9uKG9sZFN0b3JhZ2VMb2NhdGlvbik7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0c3dpdGNoTG9jYXRpb24uaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0c3dpdGNoTG9jYXRpb24uaW5mb0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0RlbGV0ZSBmb2xkZXIgbm90ZXMgd2hlbiBkZWxldGluZyB0aGUgZm9sZGVyJylcclxuXHRcdFx0XHQuc2V0RGVzYygnRGVsZXRlIHRoZSBmb2xkZXIgbm90ZSB3aGVuIGRlbGV0aW5nIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Muc3luY0RlbGV0ZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNEZWxldGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ01vdmUgZm9sZGVyIG5vdGVzIHdoZW4gbW92aW5nIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdNb3ZlIHRoZSBmb2xkZXIgbm90ZSB3aGVuIG1vdmluZyB0aGUgZm9sZGVyJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNNb3ZlKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc3luY01vdmUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBkaXNhYmxlU2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKTtcclxuXHRcdGRpc2FibGVTZXR0aW5nLnNldE5hbWUoJ0Rpc2FibGUgZm9sZGVyIGNvbGxhcHNpbmcnKTtcclxuXHRcdGRpc2FibGVTZXR0aW5nLnNldERlc2MoJ0Rpc2FibGUgdGhlIGFiaWxpdHkgdG8gY29sbGFwc2UgZm9sZGVycyBieSBjbGlja2luZyBleGFjdGx5IG9uIHRoZSBmb2xkZXIgbmFtZScpO1xyXG5cdFx0ZGlzYWJsZVNldHRpbmcuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdC5zZXRWYWx1ZSghdGhpcy5wbHVnaW4uc2V0dGluZ3MuZW5hYmxlQ29sbGFwc2luZylcclxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5lbmFibGVDb2xsYXBzaW5nID0gIXZhbHVlO1xyXG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0fSlcclxuXHRcdCk7XHJcblx0XHRkaXNhYmxlU2V0dGluZy5pbmZvRWwuYXBwZW5kVGV4dCgnUmVxdWlyZXMgYSByZXN0YXJ0IHRvIHRha2UgZWZmZWN0Jyk7XHJcblx0XHRkaXNhYmxlU2V0dGluZy5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHJcblx0XHRpZiAoUGxhdGZvcm0uaXNEZXNrdG9wQXBwKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdLZXkgZm9yIGNyZWF0aW5nIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHQuc2V0RGVzYygnVGhlIGtleSBjb21iaW5hdGlvbiB0byBjcmVhdGUgYSBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0LmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xyXG5cdFx0XHRcdFx0aWYgKCFQbGF0Zm9ybS5pc01hY09TKSB7XHJcblx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignY3RybCcsICdDdHJsICsgQ2xpY2snKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignY3RybCcsICdDbWQgKyBDbGljaycpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKCdhbHQnLCAnQWx0ICsgQ2xpY2snKTtcclxuXHRcdFx0XHRcdGRyb3Bkb3duLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmN0cmxLZXkgPyAnY3RybCcgOiAnYWx0Jyk7XHJcblx0XHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuY3RybEtleSA9IHZhbHVlID09PSAnY3RybCc7XHJcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmFsdEtleSA9IHZhbHVlID09PSAnYWx0JztcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdPbmx5IG9wZW4gZm9sZGVyIG5vdGVzIHRocm91Z2ggdGhlIG5hbWUnKVxyXG5cdFx0XHQuc2V0RGVzYygnT25seSBvcGVuIGZvbGRlciBub3RlcyBpbiB0aGUgZmlsZSBleHBsb3JlciBieSBjbGlja2luZyBvbiB0aGUgZm9sZGVyIG5hbWUnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuYWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0aWYgKCF2YWx1ZSkge1xyXG5cdFx0XHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZuLXdoaXRlc3BhY2Utc3RvcC1jb2xsYXBzaW5nJyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdIaWRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0LnNldERlc2MoJ0hpZGUgdGhlIGZvbGRlciBub3RlIGluIHRoZSBmaWxlIGV4cGxvcmVyJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmhpZGVGb2xkZXJOb3RlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5oaWRlRm9sZGVyTm90ZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdoaWRlLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdTeW5jIGZvbGRlciBuYW1lJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgcmVuYW1lIHRoZSBmb2xkZXIgbm90ZSB3aGVuIHRoZSBmb2xkZXIgbmFtZSBpcyBjaGFuZ2VkJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNGb2xkZXJOYW1lKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zeW5jRm9sZGVyTmFtZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0aWYgKFBsYXRmb3JtLmlzRGVza3RvcCkge1xyXG5cdFx0XHRjb25zdCBzZXR0aW5nMyA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKTtcclxuXHRcdFx0c2V0dGluZzMuc2V0TmFtZSgnT3BlbiBmb2xkZXIgbm90ZSBpbiBhIG5ldyB0YWIgYnkgZGVmYXVsdCcpO1xyXG5cdFx0XHRzZXR0aW5nMy5zZXREZXNjKCdBbHdheXMgb3BlbiBmb2xkZXIgbm90ZXMgaW4gYSBuZXcgdGFiIChleGNlcHQgd2hlbiB5b3UgdHJ5IHRvIG9wZW4gdGhlIHNhbWUgbm90ZSkgaW5zdGVhZCBvZiBoYXZpbmcgdG8gdXNlIGN0cmwvY21kICsgY2xpY2sgdG8gb3BlbiBpbiBhIG5ldyB0YWInKTtcclxuXHRcdFx0c2V0dGluZzMuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkluTmV3VGFiKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuSW5OZXdUYWIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdFx0c2V0dGluZzMuaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0XHRzZXR0aW5nMy5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHRcdH1cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnQXV0b21hdGljYWxseSBjcmVhdGUgZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgY3JlYXRlIGEgZm9sZGVyIG5vdGUgd2hlbiBhIG5ldyBmb2xkZXIgaXMgY3JlYXRlZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvQ3JlYXRlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvQ3JlYXRlID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdVc2Ugc3VibWVudXMnKVxyXG5cdFx0XHQuc2V0RGVzYygnVXNlIHN1Ym1lbnVzIGZvciBmaWxlL2ZvbGRlciBjb21tYW5kcycpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VTdWJtZW51cylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlU3VibWVudXMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0FkZCB1bmRlcmxpbmUgdG8gZm9sZGVycyB3aXRoIGZvbGRlciBub3RlcycpXHJcblx0XHRcdC5zZXREZXNjKCdBZGQgYW4gdW5kZXJsaW5lIHRvIGZvbGRlcnMgdGhhdCBoYXZlIGEgZm9sZGVyIG5vdGUgaW4gdGhlIGZpbGUgZXhwbG9yZXInKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVyKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy51bmRlcmxpbmVGb2xkZXIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmb2xkZXItbm90ZS11bmRlcmxpbmUnKTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZvbGRlci1ub3RlLXVuZGVybGluZScpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdPcGVuIGZvbGRlciBub3RlIHRocm91Z2ggcGF0aCcpXHJcblx0XHRcdC5zZXREZXNjKCdPcGVuIGEgZm9sZGVyIG5vdGUgd2hlbiBjbGlja2luZyBvbiBhIGZvbGRlciBuYW1lIGluIHRoZSBwYXRoIGlmIGl0IGlzIGEgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuRm9sZGVyTm90ZU9uQ2xpY2tJblBhdGggPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdVbmRlcmxpbmUgZm9sZGVycyBpbiB0aGUgcGF0aCcpXHJcblx0XHRcdFx0LnNldERlc2MoJ0FkZCBhbiB1bmRlcmxpbmUgdG8gZm9sZGVycyB0aGF0IGhhdmUgYSBmb2xkZXIgbm90ZSBpbiB0aGUgcGF0aCBhYm92ZSBhIG5vdGUnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVySW5QYXRoKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVySW5QYXRoID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2ZvbGRlci1ub3RlLXVuZGVybGluZS1wYXRoJyk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lLXBhdGgnKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0VuYWJsZSBmcm9udCBtYXR0ZXIgdGl0bGUgcGx1Z2luIGludGVncmF0aW9uJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgcmVuYW1lIGEgZm9sZGVyIG5hbWUgd2hlbiB0aGUgZm9sZGVyIG5vdGUgaXMgcmVuYW1lZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZW5hYmxlZCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXIgPSBuZXcgRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIodGhpcy5wbHVnaW4pO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5mbXRwSGFuZGxlcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnModHJ1ZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRGaWxlcygpLmZvckVhY2goKGZpbGUpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmZtdHBIYW5kbGVyPy5oYW5kbGVSZW5hbWUoeyBpZDogJycsIHJlc3VsdDogZmFsc2UsIHBhdGg6IGZpbGUucGF0aCB9LCBmYWxzZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXI/LmRlbGV0ZUV2ZW50KCk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXIgPSBudWxsO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5lbmFibGVkKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdJbmNsdWRlIGZpbGUgZXhwbG9yZXInKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdBdXRvbWF0aWNhbGx5IHJlbmFtZSBhIGZvbGRlciBuYW1lIGluIHRoZSBmaWxlIGV4cGxvcmVyIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIHJlbmFtZWQnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5leHBsb3JlcilcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZXhwbG9yZXIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0RmlsZXMoKS5mb3JFYWNoKChmaWxlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5mbXRwSGFuZGxlcj8uaGFuZGxlUmVuYW1lKHsgaWQ6ICcnLCByZXN1bHQ6IGZhbHNlLCBwYXRoOiBmaWxlLnBhdGggfSwgZmFsc2UpO1xyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0XHQuc2V0TmFtZSgnSW5jbHVkZSBwYXRoIGFib3ZlIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdBdXRvbWF0aWNhbGx5IHJlbmFtZSBhIGZvbGRlciBuYW1lIGluIHRoZSBwYXRoIGFib3ZlIGEgbm90ZSB3aGVuIHRoZSBmb2xkZXIgbm90ZSBpcyByZW5hbWVkJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUucGF0aClcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUucGF0aCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHRcdGlmICh2YWx1ZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnModHJ1ZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRHVlIHRvIGFuIGlzc3VlIHdpdGggdGVtcGxhdGVyIGl0IGhhcyBiZWVuIGRpc2FibGVkIGZvciBub3dcclxuXHRcdC8vIElmIHlvdSB3YW50IHRvIHRyeSBpdCB5b3Vyc2VsZiBtYWtlIGEgcHJcclxuXHRcdC8vIFRoZSBpc3N1ZSB3YXMgdGhhdCBpdCBvbmx5IHVzZWQgdGhlIGZpcnN0IGZvbGRlciBmb3IgYWxsIG9mIHRoZSBvdGhlciBmb2xkZXIgbm90ZXNcclxuXHRcdC8qXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdC5zZXROYW1lKCdDcmVhdGUgZm9sZGVyIG5vdGUgZm9yIGV2ZXJ5IGZvbGRlcicpXHJcblx0XHQuc2V0RGVzYygnQ3JlYXRlIGEgZm9sZGVyIG5vdGUgZm9yIGV2ZXJ5IGZvbGRlciBpbiB0aGUgdmF1bHQnKVxyXG5cdFx0LmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdFx0Y2Iuc2V0SWNvbigncGx1cycpO1xyXG5cdFx0XHRjYi5zZXRUb29sdGlwKCdDcmVhdGUgZm9sZGVyIG5vdGVzJyk7XHJcblx0XHRcdGNiLm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdG5ldyBDb25maXJtYXRpb25Nb2RhbCh0aGlzLmFwcCwgdGhpcy5wbHVnaW4pLm9wZW4oKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHRcdCovXHJcblxyXG5cclxuXHRcdGNvbnN0IG1hbmFnZUV4Y2x1ZGVkID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXRIZWFkaW5nKClcclxuXHRcdFx0LnNldENsYXNzKCdmbi1leGNsdWRlZC1mb2xkZXItaGVhZGluZycpXHJcblx0XHRcdC5zZXROYW1lKCdNYW5hZ2UgZXhjbHVkZWQgZm9sZGVycycpO1xyXG5cdFx0Y29uc3QgZGVzYzMgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XHJcblx0XHRkZXNjMy5hcHBlbmQoXHJcblx0XHRcdCdBZGQge3JlZ2V4fSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmb2xkZXIgbmFtZSB0byB1c2UgYSByZWdleCBwYXR0ZXJuLicsXHJcblx0XHRcdGRlc2MuY3JlYXRlRWwoJ2JyJyksXHJcblx0XHRcdCdVc2UgKiBiZWZvcmUgYW5kIGFmdGVyIHRvIGV4Y2x1ZGUgZm9sZGVycyB0aGF0IGluY2x1ZGUgdGhlIG5hbWUgYmV0d2VlbiB0aGUgKnMuJyxcclxuXHRcdFx0ZGVzYy5jcmVhdGVFbCgnYnInKSxcclxuXHRcdFx0J1VzZSAqIGJlZm9yZSB0aGUgZm9sZGVyIG5hbWUgdG8gZXhjbHVkZSBmb2xkZXJzIHRoYXQgZW5kIHdpdGggdGhlIGZvbGRlciBuYW1lLicsXHJcblx0XHRcdGRlc2MuY3JlYXRlRWwoJ2JyJyksXHJcblx0XHRcdCdVc2UgKiBhZnRlciB0aGUgZm9sZGVyIG5hbWUgdG8gZXhjbHVkZSBmb2xkZXJzIHRoYXQgc3RhcnQgd2l0aCB0aGUgZm9sZGVyIG5hbWUuJyxcclxuXHRcdCk7XHJcblx0XHRtYW5hZ2VFeGNsdWRlZC5zZXREZXNjKGRlc2MzKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5hcHBlbmRUZXh0KCdUaGUgcmVnZXhlcyBhbmQgd2lsZGNhcmRzIGFyZSBvbmx5IGZvciB0aGUgZm9sZGVyIG5hbWUsIG5vdCB0aGUgcGF0aC4nKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5jcmVhdGVFbCgnYnInKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5hcHBlbmRUZXh0KCdJZiB5b3Ugd2FudCB0byBzd2l0Y2ggdG8gYSBmb2xkZXIgcGF0aCBkZWxldGUgdGhlIHBhdHRlcm4gZmlyc3QuJyk7XHJcblx0XHRtYW5hZ2VFeGNsdWRlZC5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0FkZCBleGNsdWRlZCBmb2xkZXInKVxyXG5cdFx0XHQuc2V0Q2xhc3MoJ2FkZC1leGNsdWRlLWZvbGRlci1pdGVtJylcclxuXHRcdFx0LmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdFx0XHRjYi5zZXRJY29uKCdwbHVzJyk7XHJcblx0XHRcdFx0Y2Iuc2V0Q2xhc3MoJ2FkZC1leGNsdWRlLWZvbGRlcicpO1xyXG5cdFx0XHRcdGNiLnNldFRvb2x0aXAoJ0FkZCBleGNsdWRlZCBmb2xkZXInKTtcclxuXHRcdFx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gbmV3IEV4Y2x1ZGVkRm9sZGVyKCcnLCB0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRcdFx0YWRkRXhjbHVkZUZvbGRlckxpc3RJdGVtKHRoaXMsIGNvbnRhaW5lckVsLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdFx0XHRhZGRFeGNsdWRlZEZvbGRlcih0aGlzLnBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuc29ydCgoYSwgYikgPT4gYS5wb3NpdGlvbiAtIGIucG9zaXRpb24pLmZvckVhY2goKGV4Y2x1ZGVkRm9sZGVyKSA9PiB7XHJcblx0XHRcdGlmIChleGNsdWRlZEZvbGRlci5zdHJpbmc/LnRyaW0oKSAhPT0gJycgJiYgZXhjbHVkZWRGb2xkZXIucGF0aD8udHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRcdGFkZEV4Y2x1ZGVQYXR0ZXJuTGlzdEl0ZW0odGhpcywgY29udGFpbmVyRWwsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRhZGRFeGNsdWRlRm9sZGVyTGlzdEl0ZW0odGhpcywgY29udGFpbmVyRWwsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHR1cGRhdGVGb2xkZXJOb3RlcyhvbGRUZW1wbGF0ZTogc3RyaW5nLCBuZXdUZW1wbGF0ZTogc3RyaW5nKSB7XHJcblx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSA9IG5ld1RlbXBsYXRlO1xyXG5cdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRuZXcgTm90aWNlKCdTdGFydGluZyB0byB1cGRhdGUgZm9sZGVyIG5vdGVzLi4uJyk7XHJcblx0XHR0aGlzLmFwcC52YXVsdC5nZXRGaWxlcygpLmZvckVhY2goKGZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlclBhdGggPSB0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpO1xyXG5cdFx0XHRcdGxldCBmb2xkZXIgPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0XHRcdFx0bGV0IGZvbGRlck5hbWUgPSBmaWxlLm5hbWUuc2xpY2UoMCwgLWZpbGUuZXh0ZW5zaW9uLmxlbmd0aCAtIDEpO1xyXG5cdFx0XHRcdGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShvbGRUZW1wbGF0ZSwgZm9sZGVyTmFtZSkgfHwgJyc7XHJcblx0XHRcdFx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikgfHwgZm9sZGVyTmFtZSAhPT0gZm9sZGVyPy5uYW1lKSB7XHJcblx0XHRcdFx0XHRpZiAoZm9sZGVyUGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJOYW1lKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoICsgJy8nICsgZm9sZGVyTmFtZSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICghKGZvbGRlciBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRcdGlmIChmb2xkZXJOYW1lID09PSBmb2xkZXI/Lm5hbWUpIHtcclxuXHRcdFx0XHRcdGNvbnN0IG5ld1BhdGggPSBgJHtmb2xkZXI/LnBhdGh9LyR7dGhpcy5wbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUucmVwbGFjZSgne3tmb2xkZXJfbmFtZX19JywgZm9sZGVyTmFtZSl9LiR7ZmlsZS5leHRlbnNpb259YDtcclxuXHRcdFx0XHRcdHRoaXMuYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBuZXdQYXRoKTtcclxuXHRcdFx0XHR9IGVsc2UgaWYgKGZvbGRlcj8ubmFtZSA9PT0gZmlsZS5uYW1lLnNsaWNlKDAsIC1maWxlLmV4dGVuc2lvbi5sZW5ndGggLSAxKSB8fCAnJykge1xyXG5cdFx0XHRcdFx0Y29uc3QgbmV3UGF0aCA9IGAke2ZvbGRlcj8ucGF0aH0vJHt0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZS5yZXBsYWNlKCd7e2ZvbGRlcl9uYW1lfX0nLCBmaWxlLm5hbWUuc2xpY2UoMCwgLWZpbGUuZXh0ZW5zaW9uLmxlbmd0aCAtIDEpIHx8ICcnKX0uJHtmaWxlLmV4dGVuc2lvbn1gO1xyXG5cdFx0XHRcdFx0dGhpcy5hcHAudmF1bHQucmVuYW1lKGZpbGUsIG5ld1BhdGgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHRuZXcgTm90aWNlKCdGaW5pc2hlZCB1cGRhdGluZyBmb2xkZXIgbm90ZXMnKTtcclxuXHR9XHJcblxyXG5cdHN3aXRjaFN0b3JhZ2VMb2NhdGlvbihvbGRNZXRob2Q6IHN0cmluZykge1xyXG5cdFx0bmV3IE5vdGljZSgnU3RhcnRpbmcgdG8gc3dpdGNoIHN0b3JhZ2UgbG9jYXRpb24uLi4nKTtcclxuXHRcdHRoaXMuYXBwLnZhdWx0LmdldEFsbExvYWRlZEZpbGVzKCkuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZmlsZS5wYXRoLCBvbGRNZXRob2QpO1xyXG5cdFx0XHRcdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdGxldCBuZXdQYXRoID0gJyc7XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXdQYXRoID0gYCR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0bmV3UGF0aCA9IGAke3RoaXMucGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCl9LyR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5hcHAudmF1bHQucmVuYW1lKGZvbGRlck5vdGUsIG5ld1BhdGgpO1xyXG5cdFx0XHRcdFx0fSBlbHNlIGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmb2xkZXJOb3RlLnBhdGgpID09PSBmaWxlLnBhdGgpIHtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgbmV3UGF0aCA9IGAke2ZpbGUucGF0aH0vJHtmb2xkZXJOb3RlLm5hbWV9YDtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmFwcC52YXVsdC5yZW5hbWUoZm9sZGVyTm90ZSwgbmV3UGF0aCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0bmV3IE5vdGljZSgnRmluaXNoZWQgc3dpdGNoaW5nIHN0b3JhZ2UgbG9jYXRpb24nKTtcclxuXHR9XHJcblxyXG59XHJcbiIsICIvLyBDcmVkaXRzIGdvIHRvIExpYW0ncyBQZXJpb2RpYyBOb3RlcyBQbHVnaW46IGh0dHBzOi8vZ2l0aHViLmNvbS9saWFtY2Fpbi9vYnNpZGlhbi1wZXJpb2RpYy1ub3RlcyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL1NpbGVudFZvaWQxMy9UZW1wbGF0ZXJcclxuXHJcbmltcG9ydCB7IFRBYnN0cmFjdEZpbGUsIFRGaWxlLCBURm9sZGVyLCBWYXVsdCB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IHsgVGV4dElucHV0U3VnZ2VzdCB9IGZyb20gJy4vc3VnZ2VzdCc7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IHsgZ2V0VGVtcGxhdGVQbHVnaW5zIH0gZnJvbSAnc3JjL3RlbXBsYXRlJztcclxuZXhwb3J0IGVudW0gRmlsZVN1Z2dlc3RNb2RlIHtcclxuICAgIFRlbXBsYXRlRmlsZXMsXHJcbiAgICBTY3JpcHRGaWxlcyxcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFRlbXBsYXRlU3VnZ2VzdCBleHRlbmRzIFRleHRJbnB1dFN1Z2dlc3Q8VEZpbGU+IHtcclxuXHRjb25zdHJ1Y3RvcihcclxuICAgICAgICBwdWJsaWMgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudCxcclxuICAgICAgICBwcml2YXRlIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW5cclxuXHQpIHtcclxuXHRcdHN1cGVyKGlucHV0RWwpO1xyXG5cdH1cclxuXHJcblxyXG5cdGdldF9lcnJvcl9tc2cobW9kZTogRmlsZVN1Z2dlc3RNb2RlKTogc3RyaW5nIHtcclxuXHRcdHN3aXRjaCAobW9kZSkge1xyXG5cdFx0XHRjYXNlIEZpbGVTdWdnZXN0TW9kZS5UZW1wbGF0ZUZpbGVzOlxyXG5cdFx0XHRcdHJldHVybiAnVGVtcGxhdGVzIGZvbGRlciBkb2VzblxcJ3QgZXhpc3QnO1xyXG5cdFx0XHRjYXNlIEZpbGVTdWdnZXN0TW9kZS5TY3JpcHRGaWxlczpcclxuXHRcdFx0XHRyZXR1cm4gJ1VzZXIgU2NyaXB0cyBmb2xkZXIgZG9lc25cXCd0IGV4aXN0JztcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGdldFN1Z2dlc3Rpb25zKGlucHV0X3N0cjogc3RyaW5nKTogVEZpbGVbXSB7XHJcblx0XHRjb25zdCB7IHRlbXBsYXRlRm9sZGVyLCB0ZW1wbGF0ZXJQbHVnaW4gfSA9IGdldFRlbXBsYXRlUGx1Z2lucyh0aGlzLnBsdWdpbi5hcHApO1xyXG5cdFx0aWYgKCghdGVtcGxhdGVGb2xkZXIgfHwgdGVtcGxhdGVGb2xkZXI/LnRyaW0oKSA9PT0gJycpICYmICF0ZW1wbGF0ZXJQbHVnaW4pIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoID0gJyc7XHJcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRyZXR1cm4gW107XHJcblx0XHR9XHJcblx0XHRsZXQgZm9sZGVyOiBURm9sZGVyO1xyXG5cdFx0aWYgKHRlbXBsYXRlclBsdWdpbikge1xyXG5cdFx0XHRmb2xkZXIgPSB0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHRlbXBsYXRlclBsdWdpbi5wbHVnaW4/LnNldHRpbmdzPy50ZW1wbGF0ZXNfZm9sZGVyIGFzIHN0cmluZykgYXMgVEZvbGRlcjtcclxuXHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXIgPSB0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHRlbXBsYXRlRm9sZGVyKSBhcyBURm9sZGVyO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGZpbGVzOiBURmlsZVtdID0gW107XHJcblx0XHRjb25zdCBsb3dlcl9pbnB1dF9zdHIgPSBpbnB1dF9zdHIudG9Mb3dlckNhc2UoKTtcclxuXHJcblx0XHRWYXVsdC5yZWN1cnNlQ2hpbGRyZW4oZm9sZGVyLCAoZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlICYmXHJcbiAgICAgICAgICAgICAgICBmaWxlLnBhdGgudG9Mb3dlckNhc2UoKS5jb250YWlucyhsb3dlcl9pbnB1dF9zdHIpXHJcblx0XHRcdCkge1xyXG5cdFx0XHRcdGZpbGVzLnB1c2goZmlsZSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHJldHVybiBmaWxlcztcclxuXHR9XHJcblxyXG5cdHJlbmRlclN1Z2dlc3Rpb24oZmlsZTogVEZpbGUsIGVsOiBIVE1MRWxlbWVudCk6IHZvaWQge1xyXG5cdFx0ZWwuc2V0VGV4dChmaWxlLm5hbWUucmVwbGFjZSgnLm1kJywgJycpKTtcclxuXHR9XHJcblxyXG5cdHNlbGVjdFN1Z2dlc3Rpb24oZmlsZTogVEZpbGUpOiB2b2lkIHtcclxuXHRcdHRoaXMuaW5wdXRFbC52YWx1ZSA9IGZpbGUubmFtZS5yZXBsYWNlKCcubWQnLCAnJyk7XHJcblx0XHR0aGlzLmlucHV0RWwudHJpZ2dlcignaW5wdXQnKTtcclxuXHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlUGF0aCA9IGZpbGUucGF0aDtcclxuXHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0dGhpcy5jbG9zZSgpO1xyXG5cdH1cclxufVxyXG4iLCAiLy8gQ3JlZGl0cyBnbyB0byBMaWFtJ3MgUGVyaW9kaWMgTm90ZXMgUGx1Z2luOiBodHRwczovL2dpdGh1Yi5jb20vbGlhbWNhaW4vb2JzaWRpYW4tcGVyaW9kaWMtbm90ZXMgYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9TaWxlbnRWb2lkMTMvVGVtcGxhdGVyXHJcblxyXG5cclxuaW1wb3J0IHsgSVN1Z2dlc3RPd25lciwgU2NvcGUgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IGNyZWF0ZVBvcHBlciwgSW5zdGFuY2UgYXMgUG9wcGVySW5zdGFuY2UgfSBmcm9tICdAcG9wcGVyanMvY29yZSc7XHJcblxyXG5jb25zdCB3cmFwQXJvdW5kID0gKHZhbHVlOiBudW1iZXIsIHNpemU6IG51bWJlcik6IG51bWJlciA9PiB7XHJcblx0cmV0dXJuICgodmFsdWUgJSBzaXplKSArIHNpemUpICUgc2l6ZTtcclxufTtcclxuXHJcbmNsYXNzIFN1Z2dlc3Q8VD4ge1xyXG5cdHByaXZhdGUgb3duZXI6IElTdWdnZXN0T3duZXI8VD47XHJcblx0cHJpdmF0ZSB2YWx1ZXM6IFRbXTtcclxuXHRwcml2YXRlIHN1Z2dlc3Rpb25zOiBIVE1MRGl2RWxlbWVudFtdO1xyXG5cdHByaXZhdGUgc2VsZWN0ZWRJdGVtOiBudW1iZXI7XHJcblx0cHJpdmF0ZSBjb250YWluZXJFbDogSFRNTEVsZW1lbnQ7XHJcblxyXG5cdGNvbnN0cnVjdG9yKFxyXG5cdFx0b3duZXI6IElTdWdnZXN0T3duZXI8VD4sXHJcblx0XHRjb250YWluZXJFbDogSFRNTEVsZW1lbnQsXHJcblx0XHRzY29wZTogU2NvcGVcclxuXHQpIHtcclxuXHRcdHRoaXMub3duZXIgPSBvd25lcjtcclxuXHRcdHRoaXMuY29udGFpbmVyRWwgPSBjb250YWluZXJFbDtcclxuXHJcblx0XHRjb250YWluZXJFbC5vbihcclxuXHRcdFx0J2NsaWNrJyxcclxuXHRcdFx0Jy5zdWdnZXN0aW9uLWl0ZW0nLFxyXG5cdFx0XHR0aGlzLm9uU3VnZ2VzdGlvbkNsaWNrLmJpbmQodGhpcylcclxuXHRcdCk7XHJcblx0XHRjb250YWluZXJFbC5vbihcclxuXHRcdFx0J21vdXNlbW92ZScsXHJcblx0XHRcdCcuc3VnZ2VzdGlvbi1pdGVtJyxcclxuXHRcdFx0dGhpcy5vblN1Z2dlc3Rpb25Nb3VzZW92ZXIuYmluZCh0aGlzKVxyXG5cdFx0KTtcclxuXHJcblx0XHRzY29wZS5yZWdpc3RlcihbXSwgJ0Fycm93VXAnLCAoZXZlbnQpID0+IHtcclxuXHRcdFx0aWYgKCFldmVudC5pc0NvbXBvc2luZykge1xyXG5cdFx0XHRcdHRoaXMuc2V0U2VsZWN0ZWRJdGVtKHRoaXMuc2VsZWN0ZWRJdGVtIC0gMSwgdHJ1ZSk7XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRzY29wZS5yZWdpc3RlcihbXSwgJ0Fycm93RG93bicsIChldmVudCkgPT4ge1xyXG5cdFx0XHRpZiAoIWV2ZW50LmlzQ29tcG9zaW5nKSB7XHJcblx0XHRcdFx0dGhpcy5zZXRTZWxlY3RlZEl0ZW0odGhpcy5zZWxlY3RlZEl0ZW0gKyAxLCB0cnVlKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHNjb3BlLnJlZ2lzdGVyKFtdLCAnRW50ZXInLCAoZXZlbnQpID0+IHtcclxuXHRcdFx0aWYgKCFldmVudC5pc0NvbXBvc2luZykge1xyXG5cdFx0XHRcdHRoaXMudXNlU2VsZWN0ZWRJdGVtKGV2ZW50KTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0b25TdWdnZXN0aW9uQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIGVsOiBIVE1MRGl2RWxlbWVudCk6IHZvaWQge1xyXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHJcblx0XHRjb25zdCBpdGVtID0gdGhpcy5zdWdnZXN0aW9ucy5pbmRleE9mKGVsKTtcclxuXHRcdHRoaXMuc2V0U2VsZWN0ZWRJdGVtKGl0ZW0sIGZhbHNlKTtcclxuXHRcdHRoaXMudXNlU2VsZWN0ZWRJdGVtKGV2ZW50KTtcclxuXHR9XHJcblxyXG5cdG9uU3VnZ2VzdGlvbk1vdXNlb3ZlcihfZXZlbnQ6IE1vdXNlRXZlbnQsIGVsOiBIVE1MRGl2RWxlbWVudCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaXRlbSA9IHRoaXMuc3VnZ2VzdGlvbnMuaW5kZXhPZihlbCk7XHJcblx0XHR0aGlzLnNldFNlbGVjdGVkSXRlbShpdGVtLCBmYWxzZSk7XHJcblx0fVxyXG5cclxuXHRzZXRTdWdnZXN0aW9ucyh2YWx1ZXM6IFRbXSkge1xyXG5cdFx0dGhpcy5jb250YWluZXJFbC5lbXB0eSgpO1xyXG5cdFx0Y29uc3Qgc3VnZ2VzdGlvbkVsczogSFRNTERpdkVsZW1lbnRbXSA9IFtdO1xyXG5cclxuXHRcdHZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBzdWdnZXN0aW9uRWwgPSB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZURpdignc3VnZ2VzdGlvbi1pdGVtJyk7XHJcblx0XHRcdHRoaXMub3duZXIucmVuZGVyU3VnZ2VzdGlvbih2YWx1ZSwgc3VnZ2VzdGlvbkVsKTtcclxuXHRcdFx0c3VnZ2VzdGlvbkVscy5wdXNoKHN1Z2dlc3Rpb25FbCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR0aGlzLnZhbHVlcyA9IHZhbHVlcztcclxuXHRcdHRoaXMuc3VnZ2VzdGlvbnMgPSBzdWdnZXN0aW9uRWxzO1xyXG5cdFx0dGhpcy5zZXRTZWxlY3RlZEl0ZW0oMCwgZmFsc2UpO1xyXG5cdH1cclxuXHJcblx0dXNlU2VsZWN0ZWRJdGVtKGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCkge1xyXG5cdFx0Y29uc3QgY3VycmVudFZhbHVlID0gdGhpcy52YWx1ZXNbdGhpcy5zZWxlY3RlZEl0ZW1dO1xyXG5cdFx0aWYgKGN1cnJlbnRWYWx1ZSkge1xyXG5cdFx0XHR0aGlzLm93bmVyLnNlbGVjdFN1Z2dlc3Rpb24oY3VycmVudFZhbHVlLCBldmVudCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRzZXRTZWxlY3RlZEl0ZW0oc2VsZWN0ZWRJbmRleDogbnVtYmVyLCBzY3JvbGxJbnRvVmlldzogYm9vbGVhbikge1xyXG5cdFx0Y29uc3Qgbm9ybWFsaXplZEluZGV4ID0gd3JhcEFyb3VuZChcclxuXHRcdFx0c2VsZWN0ZWRJbmRleCxcclxuXHRcdFx0dGhpcy5zdWdnZXN0aW9ucy5sZW5ndGhcclxuXHRcdCk7XHJcblx0XHRjb25zdCBwcmV2U2VsZWN0ZWRTdWdnZXN0aW9uID0gdGhpcy5zdWdnZXN0aW9uc1t0aGlzLnNlbGVjdGVkSXRlbV07XHJcblx0XHRjb25zdCBzZWxlY3RlZFN1Z2dlc3Rpb24gPSB0aGlzLnN1Z2dlc3Rpb25zW25vcm1hbGl6ZWRJbmRleF07XHJcblxyXG5cdFx0cHJldlNlbGVjdGVkU3VnZ2VzdGlvbj8ucmVtb3ZlQ2xhc3MoJ2lzLXNlbGVjdGVkJyk7XHJcblx0XHRzZWxlY3RlZFN1Z2dlc3Rpb24/LmFkZENsYXNzKCdpcy1zZWxlY3RlZCcpO1xyXG5cclxuXHRcdHRoaXMuc2VsZWN0ZWRJdGVtID0gbm9ybWFsaXplZEluZGV4O1xyXG5cclxuXHRcdGlmIChzY3JvbGxJbnRvVmlldykge1xyXG5cdFx0XHRzZWxlY3RlZFN1Z2dlc3Rpb24uc2Nyb2xsSW50b1ZpZXcoZmFsc2UpO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFRleHRJbnB1dFN1Z2dlc3Q8VD4gaW1wbGVtZW50cyBJU3VnZ2VzdE93bmVyPFQ+IHtcclxuXHRwcm90ZWN0ZWQgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudCB8IEhUTUxUZXh0QXJlYUVsZW1lbnQ7XHJcblxyXG5cdHByaXZhdGUgcG9wcGVyOiBQb3BwZXJJbnN0YW5jZTtcclxuXHRwcml2YXRlIHNjb3BlOiBTY29wZTtcclxuXHRwcml2YXRlIHN1Z2dlc3RFbDogSFRNTEVsZW1lbnQ7XHJcblx0cHJpdmF0ZSBzdWdnZXN0OiBTdWdnZXN0PFQ+O1xyXG5cclxuXHRjb25zdHJ1Y3RvcihpbnB1dEVsOiBIVE1MSW5wdXRFbGVtZW50IHwgSFRNTFRleHRBcmVhRWxlbWVudCkge1xyXG5cdFx0dGhpcy5pbnB1dEVsID0gaW5wdXRFbDtcclxuXHRcdHRoaXMuc2NvcGUgPSBuZXcgU2NvcGUoKTtcclxuXHJcblx0XHR0aGlzLnN1Z2dlc3RFbCA9IGNyZWF0ZURpdignc3VnZ2VzdGlvbi1jb250YWluZXInKTtcclxuXHRcdGNvbnN0IHN1Z2dlc3Rpb24gPSB0aGlzLnN1Z2dlc3RFbC5jcmVhdGVEaXYoJ3N1Z2dlc3Rpb24nKTtcclxuXHRcdHRoaXMuc3VnZ2VzdCA9IG5ldyBTdWdnZXN0KHRoaXMsIHN1Z2dlc3Rpb24sIHRoaXMuc2NvcGUpO1xyXG5cclxuXHRcdHRoaXMuc2NvcGUucmVnaXN0ZXIoW10sICdFc2NhcGUnLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xyXG5cclxuXHRcdHRoaXMuaW5wdXRFbC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHRoaXMub25JbnB1dENoYW5nZWQuYmluZCh0aGlzKSk7XHJcblx0XHR0aGlzLmlucHV0RWwuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCB0aGlzLm9uSW5wdXRDaGFuZ2VkLmJpbmQodGhpcykpO1xyXG5cdFx0dGhpcy5pbnB1dEVsLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xyXG5cdFx0dGhpcy5zdWdnZXN0RWwub24oXHJcblx0XHRcdCdtb3VzZWRvd24nLFxyXG5cdFx0XHQnLnN1Z2dlc3Rpb24tY29udGFpbmVyJyxcclxuXHRcdFx0KGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0fVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdG9uSW5wdXRDaGFuZ2VkKCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaW5wdXRTdHIgPSB0aGlzLmlucHV0RWwudmFsdWU7XHJcblx0XHRjb25zdCBzdWdnZXN0aW9ucyA9IHRoaXMuZ2V0U3VnZ2VzdGlvbnMoaW5wdXRTdHIpO1xyXG5cclxuXHRcdGlmICghc3VnZ2VzdGlvbnMpIHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHN1Z2dlc3Rpb25zLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0dGhpcy5zdWdnZXN0LnNldFN1Z2dlc3Rpb25zKHN1Z2dlc3Rpb25zKTtcclxuXHRcdFx0Ly8gQHRzLWlnbm9yZVxyXG5cdFx0XHR0aGlzLm9wZW4oYXBwLmRvbS5hcHBDb250YWluZXJFbCwgdGhpcy5pbnB1dEVsKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdG9wZW4oY29udGFpbmVyOiBIVE1MRWxlbWVudCwgaW5wdXRFbDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcclxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XHJcblx0XHRhcHAua2V5bWFwLnB1c2hTY29wZSh0aGlzLnNjb3BlKTtcclxuXHJcblx0XHRjb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5zdWdnZXN0RWwpO1xyXG5cdFx0dGhpcy5wb3BwZXIgPSBjcmVhdGVQb3BwZXIoaW5wdXRFbCwgdGhpcy5zdWdnZXN0RWwsIHtcclxuXHRcdFx0cGxhY2VtZW50OiAnYm90dG9tLXN0YXJ0JyxcclxuXHRcdFx0bW9kaWZpZXJzOiBbXHJcblx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0bmFtZTogJ3NhbWVXaWR0aCcsXHJcblx0XHRcdFx0XHRlbmFibGVkOiB0cnVlLFxyXG5cdFx0XHRcdFx0Zm46ICh7IHN0YXRlLCBpbnN0YW5jZSB9KSA9PiB7XHJcblx0XHRcdFx0XHRcdC8vIE5vdGU6IHBvc2l0aW9uaW5nIG5lZWRzIHRvIGJlIGNhbGN1bGF0ZWQgdHdpY2UgLVxyXG5cdFx0XHRcdFx0XHQvLyBmaXJzdCBwYXNzIC0gcG9zaXRpb25pbmcgaXQgYWNjb3JkaW5nIHRvIHRoZSB3aWR0aCBvZiB0aGUgcG9wcGVyXHJcblx0XHRcdFx0XHRcdC8vIHNlY29uZCBwYXNzIC0gcG9zaXRpb24gaXQgd2l0aCB0aGUgd2lkdGggYm91bmQgdG8gdGhlIHJlZmVyZW5jZSBlbGVtZW50XHJcblx0XHRcdFx0XHRcdC8vIHdlIG5lZWQgdG8gZWFybHkgZXhpdCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wXHJcblx0XHRcdFx0XHRcdGNvbnN0IHRhcmdldFdpZHRoID0gYCR7c3RhdGUucmVjdHMucmVmZXJlbmNlLndpZHRofXB4YDtcclxuXHRcdFx0XHRcdFx0aWYgKHN0YXRlLnN0eWxlcy5wb3BwZXIud2lkdGggPT09IHRhcmdldFdpZHRoKSB7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHN0YXRlLnN0eWxlcy5wb3BwZXIud2lkdGggPSB0YXJnZXRXaWR0aDtcclxuXHRcdFx0XHRcdFx0aW5zdGFuY2UudXBkYXRlKCk7XHJcblx0XHRcdFx0XHR9LFxyXG5cdFx0XHRcdFx0cGhhc2U6ICdiZWZvcmVXcml0ZScsXHJcblx0XHRcdFx0XHRyZXF1aXJlczogWydjb21wdXRlU3R5bGVzJ10sXHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XSxcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Y2xvc2UoKTogdm9pZCB7XHJcblx0XHRhcHAua2V5bWFwLnBvcFNjb3BlKHRoaXMuc2NvcGUpO1xyXG5cclxuXHRcdHRoaXMuc3VnZ2VzdC5zZXRTdWdnZXN0aW9ucyhbXSk7XHJcblx0XHRpZiAodGhpcy5wb3BwZXIpIHRoaXMucG9wcGVyLmRlc3Ryb3koKTtcclxuXHRcdHRoaXMuc3VnZ2VzdEVsLmRldGFjaCgpO1xyXG5cdH1cclxuXHJcbiAgICBhYnN0cmFjdCBnZXRTdWdnZXN0aW9ucyhpbnB1dFN0cjogc3RyaW5nKTogVFtdO1xyXG4gICAgYWJzdHJhY3QgcmVuZGVyU3VnZ2VzdGlvbihpdGVtOiBULCBlbDogSFRNTEVsZW1lbnQpOiB2b2lkO1xyXG4gICAgYWJzdHJhY3Qgc2VsZWN0U3VnZ2VzdGlvbihpdGVtOiBUKTogdm9pZDtcclxufVxyXG4iLCAiZXhwb3J0IHZhciB0b3AgPSAndG9wJztcbmV4cG9ydCB2YXIgYm90dG9tID0gJ2JvdHRvbSc7XG5leHBvcnQgdmFyIHJpZ2h0ID0gJ3JpZ2h0JztcbmV4cG9ydCB2YXIgbGVmdCA9ICdsZWZ0JztcbmV4cG9ydCB2YXIgYXV0byA9ICdhdXRvJztcbmV4cG9ydCB2YXIgYmFzZVBsYWNlbWVudHMgPSBbdG9wLCBib3R0b20sIHJpZ2h0LCBsZWZ0XTtcbmV4cG9ydCB2YXIgc3RhcnQgPSAnc3RhcnQnO1xuZXhwb3J0IHZhciBlbmQgPSAnZW5kJztcbmV4cG9ydCB2YXIgY2xpcHBpbmdQYXJlbnRzID0gJ2NsaXBwaW5nUGFyZW50cyc7XG5leHBvcnQgdmFyIHZpZXdwb3J0ID0gJ3ZpZXdwb3J0JztcbmV4cG9ydCB2YXIgcG9wcGVyID0gJ3BvcHBlcic7XG5leHBvcnQgdmFyIHJlZmVyZW5jZSA9ICdyZWZlcmVuY2UnO1xuZXhwb3J0IHZhciB2YXJpYXRpb25QbGFjZW1lbnRzID0gLyojX19QVVJFX18qL2Jhc2VQbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIGFjYy5jb25jYXQoW3BsYWNlbWVudCArIFwiLVwiICsgc3RhcnQsIHBsYWNlbWVudCArIFwiLVwiICsgZW5kXSk7XG59LCBbXSk7XG5leHBvcnQgdmFyIHBsYWNlbWVudHMgPSAvKiNfX1BVUkVfXyovW10uY29uY2F0KGJhc2VQbGFjZW1lbnRzLCBbYXV0b10pLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIGFjYy5jb25jYXQoW3BsYWNlbWVudCwgcGxhY2VtZW50ICsgXCItXCIgKyBzdGFydCwgcGxhY2VtZW50ICsgXCItXCIgKyBlbmRdKTtcbn0sIFtdKTsgLy8gbW9kaWZpZXJzIHRoYXQgbmVlZCB0byByZWFkIHRoZSBET01cblxuZXhwb3J0IHZhciBiZWZvcmVSZWFkID0gJ2JlZm9yZVJlYWQnO1xuZXhwb3J0IHZhciByZWFkID0gJ3JlYWQnO1xuZXhwb3J0IHZhciBhZnRlclJlYWQgPSAnYWZ0ZXJSZWFkJzsgLy8gcHVyZS1sb2dpYyBtb2RpZmllcnNcblxuZXhwb3J0IHZhciBiZWZvcmVNYWluID0gJ2JlZm9yZU1haW4nO1xuZXhwb3J0IHZhciBtYWluID0gJ21haW4nO1xuZXhwb3J0IHZhciBhZnRlck1haW4gPSAnYWZ0ZXJNYWluJzsgLy8gbW9kaWZpZXIgd2l0aCB0aGUgcHVycG9zZSB0byB3cml0ZSB0byB0aGUgRE9NIChvciB3cml0ZSBpbnRvIGEgZnJhbWV3b3JrIHN0YXRlKVxuXG5leHBvcnQgdmFyIGJlZm9yZVdyaXRlID0gJ2JlZm9yZVdyaXRlJztcbmV4cG9ydCB2YXIgd3JpdGUgPSAnd3JpdGUnO1xuZXhwb3J0IHZhciBhZnRlcldyaXRlID0gJ2FmdGVyV3JpdGUnO1xuZXhwb3J0IHZhciBtb2RpZmllclBoYXNlcyA9IFtiZWZvcmVSZWFkLCByZWFkLCBhZnRlclJlYWQsIGJlZm9yZU1haW4sIG1haW4sIGFmdGVyTWFpbiwgYmVmb3JlV3JpdGUsIHdyaXRlLCBhZnRlcldyaXRlXTsiLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Tm9kZU5hbWUoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudCA/IChlbGVtZW50Lm5vZGVOYW1lIHx8ICcnKS50b0xvd2VyQ2FzZSgpIDogbnVsbDtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHtcbiAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgIHJldHVybiB3aW5kb3c7XG4gIH1cblxuICBpZiAobm9kZS50b1N0cmluZygpICE9PSAnW29iamVjdCBXaW5kb3ddJykge1xuICAgIHZhciBvd25lckRvY3VtZW50ID0gbm9kZS5vd25lckRvY3VtZW50O1xuICAgIHJldHVybiBvd25lckRvY3VtZW50ID8gb3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3cgOiB3aW5kb3c7XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn0iLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcblxuZnVuY3Rpb24gaXNFbGVtZW50KG5vZGUpIHtcbiAgdmFyIE93bkVsZW1lbnQgPSBnZXRXaW5kb3cobm9kZSkuRWxlbWVudDtcbiAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBPd25FbGVtZW50IHx8IG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50O1xufVxuXG5mdW5jdGlvbiBpc0hUTUxFbGVtZW50KG5vZGUpIHtcbiAgdmFyIE93bkVsZW1lbnQgPSBnZXRXaW5kb3cobm9kZSkuSFRNTEVsZW1lbnQ7XG4gIHJldHVybiBub2RlIGluc3RhbmNlb2YgT3duRWxlbWVudCB8fCBub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGlzU2hhZG93Um9vdChub2RlKSB7XG4gIC8vIElFIDExIGhhcyBubyBTaGFkb3dSb290XG4gIGlmICh0eXBlb2YgU2hhZG93Um9vdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgT3duRWxlbWVudCA9IGdldFdpbmRvdyhub2RlKS5TaGFkb3dSb290O1xuICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIE93bkVsZW1lbnQgfHwgbm9kZSBpbnN0YW5jZW9mIFNoYWRvd1Jvb3Q7XG59XG5cbmV4cG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCwgaXNTaGFkb3dSb290IH07IiwgImltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4uL2RvbS11dGlscy9pbnN0YW5jZU9mLmpzXCI7IC8vIFRoaXMgbW9kaWZpZXIgdGFrZXMgdGhlIHN0eWxlcyBwcmVwYXJlZCBieSB0aGUgYGNvbXB1dGVTdHlsZXNgIG1vZGlmaWVyXG4vLyBhbmQgYXBwbGllcyB0aGVtIHRvIHRoZSBIVE1MRWxlbWVudHMgc3VjaCBhcyBwb3BwZXIgYW5kIGFycm93XG5cbmZ1bmN0aW9uIGFwcGx5U3R5bGVzKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZTtcbiAgT2JqZWN0LmtleXMoc3RhdGUuZWxlbWVudHMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB2YXIgc3R5bGUgPSBzdGF0ZS5zdHlsZXNbbmFtZV0gfHwge307XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSBzdGF0ZS5hdHRyaWJ1dGVzW25hbWVdIHx8IHt9O1xuICAgIHZhciBlbGVtZW50ID0gc3RhdGUuZWxlbWVudHNbbmFtZV07IC8vIGFycm93IGlzIG9wdGlvbmFsICsgdmlydHVhbCBlbGVtZW50c1xuXG4gICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsZW1lbnQpIHx8ICFnZXROb2RlTmFtZShlbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gRmxvdyBkb2Vzbid0IHN1cHBvcnQgdG8gZXh0ZW5kIHRoaXMgcHJvcGVydHksIGJ1dCBpdCdzIHRoZSBtb3N0XG4gICAgLy8gZWZmZWN0aXZlIHdheSB0byBhcHBseSBzdHlsZXMgdG8gYW4gSFRNTEVsZW1lbnRcbiAgICAvLyAkRmxvd0ZpeE1lW2Nhbm5vdC13cml0ZV1cblxuXG4gICAgT2JqZWN0LmFzc2lnbihlbGVtZW50LnN0eWxlLCBzdHlsZSk7XG4gICAgT2JqZWN0LmtleXMoYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgICAgdmFyIHZhbHVlID0gYXR0cmlidXRlc1tuYW1lXTtcblxuICAgICAgaWYgKHZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlID09PSB0cnVlID8gJycgOiB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGU7XG4gIHZhciBpbml0aWFsU3R5bGVzID0ge1xuICAgIHBvcHBlcjoge1xuICAgICAgcG9zaXRpb246IHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBsZWZ0OiAnMCcsXG4gICAgICB0b3A6ICcwJyxcbiAgICAgIG1hcmdpbjogJzAnXG4gICAgfSxcbiAgICBhcnJvdzoge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcbiAgICB9LFxuICAgIHJlZmVyZW5jZToge31cbiAgfTtcbiAgT2JqZWN0LmFzc2lnbihzdGF0ZS5lbGVtZW50cy5wb3BwZXIuc3R5bGUsIGluaXRpYWxTdHlsZXMucG9wcGVyKTtcbiAgc3RhdGUuc3R5bGVzID0gaW5pdGlhbFN0eWxlcztcblxuICBpZiAoc3RhdGUuZWxlbWVudHMuYXJyb3cpIHtcbiAgICBPYmplY3QuYXNzaWduKHN0YXRlLmVsZW1lbnRzLmFycm93LnN0eWxlLCBpbml0aWFsU3R5bGVzLmFycm93KTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgT2JqZWN0LmtleXMoc3RhdGUuZWxlbWVudHMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gc3RhdGUuZWxlbWVudHNbbmFtZV07XG4gICAgICB2YXIgYXR0cmlidXRlcyA9IHN0YXRlLmF0dHJpYnV0ZXNbbmFtZV0gfHwge307XG4gICAgICB2YXIgc3R5bGVQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoc3RhdGUuc3R5bGVzLmhhc093blByb3BlcnR5KG5hbWUpID8gc3RhdGUuc3R5bGVzW25hbWVdIDogaW5pdGlhbFN0eWxlc1tuYW1lXSk7IC8vIFNldCBhbGwgdmFsdWVzIHRvIGFuIGVtcHR5IHN0cmluZyB0byB1bnNldCB0aGVtXG5cbiAgICAgIHZhciBzdHlsZSA9IHN0eWxlUHJvcGVydGllcy5yZWR1Y2UoZnVuY3Rpb24gKHN0eWxlLCBwcm9wZXJ0eSkge1xuICAgICAgICBzdHlsZVtwcm9wZXJ0eV0gPSAnJztcbiAgICAgICAgcmV0dXJuIHN0eWxlO1xuICAgICAgfSwge30pOyAvLyBhcnJvdyBpcyBvcHRpb25hbCArIHZpcnR1YWwgZWxlbWVudHNcblxuICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsZW1lbnQpIHx8ICFnZXROb2RlTmFtZShlbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIE9iamVjdC5hc3NpZ24oZWxlbWVudC5zdHlsZSwgc3R5bGUpO1xuICAgICAgT2JqZWN0LmtleXMoYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKGF0dHJpYnV0ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2FwcGx5U3R5bGVzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICd3cml0ZScsXG4gIGZuOiBhcHBseVN0eWxlcyxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIHJlcXVpcmVzOiBbJ2NvbXB1dGVTdHlsZXMnXVxufTsiLCAiaW1wb3J0IHsgYXV0byB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5zcGxpdCgnLScpWzBdO1xufSIsICJleHBvcnQgdmFyIG1heCA9IE1hdGgubWF4O1xuZXhwb3J0IHZhciBtaW4gPSBNYXRoLm1pbjtcbmV4cG9ydCB2YXIgcm91bmQgPSBNYXRoLnJvdW5kOyIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRVQVN0cmluZygpIHtcbiAgdmFyIHVhRGF0YSA9IG5hdmlnYXRvci51c2VyQWdlbnREYXRhO1xuXG4gIGlmICh1YURhdGEgIT0gbnVsbCAmJiB1YURhdGEuYnJhbmRzICYmIEFycmF5LmlzQXJyYXkodWFEYXRhLmJyYW5kcykpIHtcbiAgICByZXR1cm4gdWFEYXRhLmJyYW5kcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBpdGVtLmJyYW5kICsgXCIvXCIgKyBpdGVtLnZlcnNpb247XG4gICAgfSkuam9pbignICcpO1xuICB9XG5cbiAgcmV0dXJuIG5hdmlnYXRvci51c2VyQWdlbnQ7XG59IiwgImltcG9ydCBnZXRVQVN0cmluZyBmcm9tIFwiLi4vdXRpbHMvdXNlckFnZW50LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc0xheW91dFZpZXdwb3J0KCkge1xuICByZXR1cm4gIS9eKCg/IWNocm9tZXxhbmRyb2lkKS4pKnNhZmFyaS9pLnRlc3QoZ2V0VUFTdHJpbmcoKSk7XG59IiwgImltcG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcbmltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgaXNMYXlvdXRWaWV3cG9ydCBmcm9tIFwiLi9pc0xheW91dFZpZXdwb3J0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCwgaW5jbHVkZVNjYWxlLCBpc0ZpeGVkU3RyYXRlZ3kpIHtcbiAgaWYgKGluY2x1ZGVTY2FsZSA9PT0gdm9pZCAwKSB7XG4gICAgaW5jbHVkZVNjYWxlID0gZmFsc2U7XG4gIH1cblxuICBpZiAoaXNGaXhlZFN0cmF0ZWd5ID09PSB2b2lkIDApIHtcbiAgICBpc0ZpeGVkU3RyYXRlZ3kgPSBmYWxzZTtcbiAgfVxuXG4gIHZhciBjbGllbnRSZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgdmFyIHNjYWxlWCA9IDE7XG4gIHZhciBzY2FsZVkgPSAxO1xuXG4gIGlmIChpbmNsdWRlU2NhbGUgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSkge1xuICAgIHNjYWxlWCA9IGVsZW1lbnQub2Zmc2V0V2lkdGggPiAwID8gcm91bmQoY2xpZW50UmVjdC53aWR0aCkgLyBlbGVtZW50Lm9mZnNldFdpZHRoIHx8IDEgOiAxO1xuICAgIHNjYWxlWSA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0ID4gMCA/IHJvdW5kKGNsaWVudFJlY3QuaGVpZ2h0KSAvIGVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IDEgOiAxO1xuICB9XG5cbiAgdmFyIF9yZWYgPSBpc0VsZW1lbnQoZWxlbWVudCkgPyBnZXRXaW5kb3coZWxlbWVudCkgOiB3aW5kb3csXG4gICAgICB2aXN1YWxWaWV3cG9ydCA9IF9yZWYudmlzdWFsVmlld3BvcnQ7XG5cbiAgdmFyIGFkZFZpc3VhbE9mZnNldHMgPSAhaXNMYXlvdXRWaWV3cG9ydCgpICYmIGlzRml4ZWRTdHJhdGVneTtcbiAgdmFyIHggPSAoY2xpZW50UmVjdC5sZWZ0ICsgKGFkZFZpc3VhbE9mZnNldHMgJiYgdmlzdWFsVmlld3BvcnQgPyB2aXN1YWxWaWV3cG9ydC5vZmZzZXRMZWZ0IDogMCkpIC8gc2NhbGVYO1xuICB2YXIgeSA9IChjbGllbnRSZWN0LnRvcCArIChhZGRWaXN1YWxPZmZzZXRzICYmIHZpc3VhbFZpZXdwb3J0ID8gdmlzdWFsVmlld3BvcnQub2Zmc2V0VG9wIDogMCkpIC8gc2NhbGVZO1xuICB2YXIgd2lkdGggPSBjbGllbnRSZWN0LndpZHRoIC8gc2NhbGVYO1xuICB2YXIgaGVpZ2h0ID0gY2xpZW50UmVjdC5oZWlnaHQgLyBzY2FsZVk7XG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0LFxuICAgIHRvcDogeSxcbiAgICByaWdodDogeCArIHdpZHRoLFxuICAgIGJvdHRvbTogeSArIGhlaWdodCxcbiAgICBsZWZ0OiB4LFxuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiOyAvLyBSZXR1cm5zIHRoZSBsYXlvdXQgcmVjdCBvZiBhbiBlbGVtZW50IHJlbGF0aXZlIHRvIGl0cyBvZmZzZXRQYXJlbnQuIExheW91dFxuLy8gbWVhbnMgaXQgZG9lc24ndCB0YWtlIGludG8gYWNjb3VudCB0cmFuc2Zvcm1zLlxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRMYXlvdXRSZWN0KGVsZW1lbnQpIHtcbiAgdmFyIGNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCk7IC8vIFVzZSB0aGUgY2xpZW50UmVjdCBzaXplcyBpZiBpdCdzIG5vdCBiZWVuIHRyYW5zZm9ybWVkLlxuICAvLyBGaXhlcyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzEyMjNcblxuICB2YXIgd2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuICB2YXIgaGVpZ2h0ID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG5cbiAgaWYgKE1hdGguYWJzKGNsaWVudFJlY3Qud2lkdGggLSB3aWR0aCkgPD0gMSkge1xuICAgIHdpZHRoID0gY2xpZW50UmVjdC53aWR0aDtcbiAgfVxuXG4gIGlmIChNYXRoLmFicyhjbGllbnRSZWN0LmhlaWdodCAtIGhlaWdodCkgPD0gMSkge1xuICAgIGhlaWdodCA9IGNsaWVudFJlY3QuaGVpZ2h0O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBlbGVtZW50Lm9mZnNldExlZnQsXG4gICAgeTogZWxlbWVudC5vZmZzZXRUb3AsXG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0XG4gIH07XG59IiwgImltcG9ydCB7IGlzU2hhZG93Um9vdCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbnRhaW5zKHBhcmVudCwgY2hpbGQpIHtcbiAgdmFyIHJvb3ROb2RlID0gY2hpbGQuZ2V0Um9vdE5vZGUgJiYgY2hpbGQuZ2V0Um9vdE5vZGUoKTsgLy8gRmlyc3QsIGF0dGVtcHQgd2l0aCBmYXN0ZXIgbmF0aXZlIG1ldGhvZFxuXG4gIGlmIChwYXJlbnQuY29udGFpbnMoY2hpbGQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gLy8gdGhlbiBmYWxsYmFjayB0byBjdXN0b20gaW1wbGVtZW50YXRpb24gd2l0aCBTaGFkb3cgRE9NIHN1cHBvcnRcbiAgZWxzZSBpZiAocm9vdE5vZGUgJiYgaXNTaGFkb3dSb290KHJvb3ROb2RlKSkge1xuICAgICAgdmFyIG5leHQgPSBjaGlsZDtcblxuICAgICAgZG8ge1xuICAgICAgICBpZiAobmV4dCAmJiBwYXJlbnQuaXNTYW1lTm9kZShuZXh0KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXTogbmVlZCBhIGJldHRlciB3YXkgdG8gaGFuZGxlIHRoaXMuLi5cblxuXG4gICAgICAgIG5leHQgPSBuZXh0LnBhcmVudE5vZGUgfHwgbmV4dC5ob3N0O1xuICAgICAgfSB3aGlsZSAobmV4dCk7XG4gICAgfSAvLyBHaXZlIHVwLCB0aGUgcmVzdWx0IGlzIGZhbHNlXG5cblxuICByZXR1cm4gZmFsc2U7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFdpbmRvdyhlbGVtZW50KS5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xufSIsICJpbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGlzVGFibGVFbGVtZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuIFsndGFibGUnLCAndGQnLCAndGgnXS5pbmRleE9mKGdldE5vZGVOYW1lKGVsZW1lbnQpKSA+PSAwO1xufSIsICJpbXBvcnQgeyBpc0VsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkge1xuICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dOiBhc3N1bWUgYm9keSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gIHJldHVybiAoKGlzRWxlbWVudChlbGVtZW50KSA/IGVsZW1lbnQub3duZXJEb2N1bWVudCA6IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICBlbGVtZW50LmRvY3VtZW50KSB8fCB3aW5kb3cuZG9jdW1lbnQpLmRvY3VtZW50RWxlbWVudDtcbn0iLCAiaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IHsgaXNTaGFkb3dSb290IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0UGFyZW50Tm9kZShlbGVtZW50KSB7XG4gIGlmIChnZXROb2RlTmFtZShlbGVtZW50KSA9PT0gJ2h0bWwnKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICByZXR1cm4gKC8vIHRoaXMgaXMgYSBxdWlja2VyIChidXQgbGVzcyB0eXBlIHNhZmUpIHdheSB0byBzYXZlIHF1aXRlIHNvbWUgYnl0ZXMgZnJvbSB0aGUgYnVuZGxlXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtcmV0dXJuXVxuICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgIGVsZW1lbnQuYXNzaWduZWRTbG90IHx8IC8vIHN0ZXAgaW50byB0aGUgc2hhZG93IERPTSBvZiB0aGUgcGFyZW50IG9mIGEgc2xvdHRlZCBub2RlXG4gICAgZWxlbWVudC5wYXJlbnROb2RlIHx8ICggLy8gRE9NIEVsZW1lbnQgZGV0ZWN0ZWRcbiAgICBpc1NoYWRvd1Jvb3QoZWxlbWVudCkgPyBlbGVtZW50Lmhvc3QgOiBudWxsKSB8fCAvLyBTaGFkb3dSb290IGRldGVjdGVkXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF06IEhUTUxFbGVtZW50IGlzIGEgTm9kZVxuICAgIGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KSAvLyBmYWxsYmFja1xuXG4gICk7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCBnZXRDb21wdXRlZFN0eWxlIGZyb20gXCIuL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQsIGlzU2hhZG93Um9vdCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBpc1RhYmxlRWxlbWVudCBmcm9tIFwiLi9pc1RhYmxlRWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGdldFVBU3RyaW5nIGZyb20gXCIuLi91dGlscy91c2VyQWdlbnQuanNcIjtcblxuZnVuY3Rpb24gZ2V0VHJ1ZU9mZnNldFBhcmVudChlbGVtZW50KSB7XG4gIGlmICghaXNIVE1MRWxlbWVudChlbGVtZW50KSB8fCAvLyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzgzN1xuICBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLnBvc2l0aW9uID09PSAnZml4ZWQnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudC5vZmZzZXRQYXJlbnQ7XG59IC8vIGAub2Zmc2V0UGFyZW50YCByZXBvcnRzIGBudWxsYCBmb3IgZml4ZWQgZWxlbWVudHMsIHdoaWxlIGFic29sdXRlIGVsZW1lbnRzXG4vLyByZXR1cm4gdGhlIGNvbnRhaW5pbmcgYmxvY2tcblxuXG5mdW5jdGlvbiBnZXRDb250YWluaW5nQmxvY2soZWxlbWVudCkge1xuICB2YXIgaXNGaXJlZm94ID0gL2ZpcmVmb3gvaS50ZXN0KGdldFVBU3RyaW5nKCkpO1xuICB2YXIgaXNJRSA9IC9UcmlkZW50L2kudGVzdChnZXRVQVN0cmluZygpKTtcblxuICBpZiAoaXNJRSAmJiBpc0hUTUxFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgLy8gSW4gSUUgOSwgMTAgYW5kIDExIGZpeGVkIGVsZW1lbnRzIGNvbnRhaW5pbmcgYmxvY2sgaXMgYWx3YXlzIGVzdGFibGlzaGVkIGJ5IHRoZSB2aWV3cG9ydFxuICAgIHZhciBlbGVtZW50Q3NzID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcblxuICAgIGlmIChlbGVtZW50Q3NzLnBvc2l0aW9uID09PSAnZml4ZWQnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICB2YXIgY3VycmVudE5vZGUgPSBnZXRQYXJlbnROb2RlKGVsZW1lbnQpO1xuXG4gIGlmIChpc1NoYWRvd1Jvb3QoY3VycmVudE5vZGUpKSB7XG4gICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5ob3N0O1xuICB9XG5cbiAgd2hpbGUgKGlzSFRNTEVsZW1lbnQoY3VycmVudE5vZGUpICYmIFsnaHRtbCcsICdib2R5J10uaW5kZXhPZihnZXROb2RlTmFtZShjdXJyZW50Tm9kZSkpIDwgMCkge1xuICAgIHZhciBjc3MgPSBnZXRDb21wdXRlZFN0eWxlKGN1cnJlbnROb2RlKTsgLy8gVGhpcyBpcyBub24tZXhoYXVzdGl2ZSBidXQgY292ZXJzIHRoZSBtb3N0IGNvbW1vbiBDU1MgcHJvcGVydGllcyB0aGF0XG4gICAgLy8gY3JlYXRlIGEgY29udGFpbmluZyBibG9jay5cbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ29udGFpbmluZ19ibG9jayNpZGVudGlmeWluZ190aGVfY29udGFpbmluZ19ibG9ja1xuXG4gICAgaWYgKGNzcy50cmFuc2Zvcm0gIT09ICdub25lJyB8fCBjc3MucGVyc3BlY3RpdmUgIT09ICdub25lJyB8fCBjc3MuY29udGFpbiA9PT0gJ3BhaW50JyB8fCBbJ3RyYW5zZm9ybScsICdwZXJzcGVjdGl2ZSddLmluZGV4T2YoY3NzLndpbGxDaGFuZ2UpICE9PSAtMSB8fCBpc0ZpcmVmb3ggJiYgY3NzLndpbGxDaGFuZ2UgPT09ICdmaWx0ZXInIHx8IGlzRmlyZWZveCAmJiBjc3MuZmlsdGVyICYmIGNzcy5maWx0ZXIgIT09ICdub25lJykge1xuICAgICAgcmV0dXJuIGN1cnJlbnROb2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLnBhcmVudE5vZGU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59IC8vIEdldHMgdGhlIGNsb3Nlc3QgYW5jZXN0b3IgcG9zaXRpb25lZCBlbGVtZW50LiBIYW5kbGVzIHNvbWUgZWRnZSBjYXNlcyxcbi8vIHN1Y2ggYXMgdGFibGUgYW5jZXN0b3JzIGFuZCBjcm9zcyBicm93c2VyIGJ1Z3MuXG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpIHtcbiAgdmFyIHdpbmRvdyA9IGdldFdpbmRvdyhlbGVtZW50KTtcbiAgdmFyIG9mZnNldFBhcmVudCA9IGdldFRydWVPZmZzZXRQYXJlbnQoZWxlbWVudCk7XG5cbiAgd2hpbGUgKG9mZnNldFBhcmVudCAmJiBpc1RhYmxlRWxlbWVudChvZmZzZXRQYXJlbnQpICYmIGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpIHtcbiAgICBvZmZzZXRQYXJlbnQgPSBnZXRUcnVlT2Zmc2V0UGFyZW50KG9mZnNldFBhcmVudCk7XG4gIH1cblxuICBpZiAob2Zmc2V0UGFyZW50ICYmIChnZXROb2RlTmFtZShvZmZzZXRQYXJlbnQpID09PSAnaHRtbCcgfHwgZ2V0Tm9kZU5hbWUob2Zmc2V0UGFyZW50KSA9PT0gJ2JvZHknICYmIGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpKSB7XG4gICAgcmV0dXJuIHdpbmRvdztcbiAgfVxuXG4gIHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZ2V0Q29udGFpbmluZ0Jsb2NrKGVsZW1lbnQpIHx8IHdpbmRvdztcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KHBsYWNlbWVudCkge1xuICByZXR1cm4gWyd0b3AnLCAnYm90dG9tJ10uaW5kZXhPZihwbGFjZW1lbnQpID49IDAgPyAneCcgOiAneSc7XG59IiwgImltcG9ydCB7IG1heCBhcyBtYXRoTWF4LCBtaW4gYXMgbWF0aE1pbiB9IGZyb20gXCIuL21hdGguanNcIjtcbmV4cG9ydCBmdW5jdGlvbiB3aXRoaW4obWluLCB2YWx1ZSwgbWF4KSB7XG4gIHJldHVybiBtYXRoTWF4KG1pbiwgbWF0aE1pbih2YWx1ZSwgbWF4KSk7XG59XG5leHBvcnQgZnVuY3Rpb24gd2l0aGluTWF4Q2xhbXAobWluLCB2YWx1ZSwgbWF4KSB7XG4gIHZhciB2ID0gd2l0aGluKG1pbiwgdmFsdWUsIG1heCk7XG4gIHJldHVybiB2ID4gbWF4ID8gbWF4IDogdjtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RnJlc2hTaWRlT2JqZWN0KCkge1xuICByZXR1cm4ge1xuICAgIHRvcDogMCxcbiAgICByaWdodDogMCxcbiAgICBib3R0b206IDAsXG4gICAgbGVmdDogMFxuICB9O1xufSIsICJpbXBvcnQgZ2V0RnJlc2hTaWRlT2JqZWN0IGZyb20gXCIuL2dldEZyZXNoU2lkZU9iamVjdC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbWVyZ2VQYWRkaW5nT2JqZWN0KHBhZGRpbmdPYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGdldEZyZXNoU2lkZU9iamVjdCgpLCBwYWRkaW5nT2JqZWN0KTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZXhwYW5kVG9IYXNoTWFwKHZhbHVlLCBrZXlzKSB7XG4gIHJldHVybiBrZXlzLnJlZHVjZShmdW5jdGlvbiAoaGFzaE1hcCwga2V5KSB7XG4gICAgaGFzaE1hcFtrZXldID0gdmFsdWU7XG4gICAgcmV0dXJuIGhhc2hNYXA7XG4gIH0sIHt9KTtcbn0iLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGNvbnRhaW5zIGZyb20gXCIuLi9kb20tdXRpbHMvY29udGFpbnMuanNcIjtcbmltcG9ydCBnZXRPZmZzZXRQYXJlbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE1haW5BeGlzRnJvbVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgd2l0aGluIH0gZnJvbSBcIi4uL3V0aWxzL3dpdGhpbi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi4vdXRpbHMvbWVyZ2VQYWRkaW5nT2JqZWN0LmpzXCI7XG5pbXBvcnQgZXhwYW5kVG9IYXNoTWFwIGZyb20gXCIuLi91dGlscy9leHBhbmRUb0hhc2hNYXAuanNcIjtcbmltcG9ydCB7IGxlZnQsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdG9wLCBib3R0b20gfSBmcm9tIFwiLi4vZW51bXMuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG52YXIgdG9QYWRkaW5nT2JqZWN0ID0gZnVuY3Rpb24gdG9QYWRkaW5nT2JqZWN0KHBhZGRpbmcsIHN0YXRlKSB7XG4gIHBhZGRpbmcgPSB0eXBlb2YgcGFkZGluZyA9PT0gJ2Z1bmN0aW9uJyA/IHBhZGRpbmcoT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVjdHMsIHtcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KSkgOiBwYWRkaW5nO1xuICByZXR1cm4gbWVyZ2VQYWRkaW5nT2JqZWN0KHR5cGVvZiBwYWRkaW5nICE9PSAnbnVtYmVyJyA/IHBhZGRpbmcgOiBleHBhbmRUb0hhc2hNYXAocGFkZGluZywgYmFzZVBsYWNlbWVudHMpKTtcbn07XG5cbmZ1bmN0aW9uIGFycm93KF9yZWYpIHtcbiAgdmFyIF9zdGF0ZSRtb2RpZmllcnNEYXRhJDtcblxuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XG4gIHZhciBhcnJvd0VsZW1lbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdztcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHM7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgYXhpcyA9IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudChiYXNlUGxhY2VtZW50KTtcbiAgdmFyIGlzVmVydGljYWwgPSBbbGVmdCwgcmlnaHRdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgPj0gMDtcbiAgdmFyIGxlbiA9IGlzVmVydGljYWwgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG5cbiAgaWYgKCFhcnJvd0VsZW1lbnQgfHwgIXBvcHBlck9mZnNldHMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGFkZGluZ09iamVjdCA9IHRvUGFkZGluZ09iamVjdChvcHRpb25zLnBhZGRpbmcsIHN0YXRlKTtcbiAgdmFyIGFycm93UmVjdCA9IGdldExheW91dFJlY3QoYXJyb3dFbGVtZW50KTtcbiAgdmFyIG1pblByb3AgPSBheGlzID09PSAneScgPyB0b3AgOiBsZWZ0O1xuICB2YXIgbWF4UHJvcCA9IGF4aXMgPT09ICd5JyA/IGJvdHRvbSA6IHJpZ2h0O1xuICB2YXIgZW5kRGlmZiA9IHN0YXRlLnJlY3RzLnJlZmVyZW5jZVtsZW5dICsgc3RhdGUucmVjdHMucmVmZXJlbmNlW2F4aXNdIC0gcG9wcGVyT2Zmc2V0c1theGlzXSAtIHN0YXRlLnJlY3RzLnBvcHBlcltsZW5dO1xuICB2YXIgc3RhcnREaWZmID0gcG9wcGVyT2Zmc2V0c1theGlzXSAtIHN0YXRlLnJlY3RzLnJlZmVyZW5jZVtheGlzXTtcbiAgdmFyIGFycm93T2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KGFycm93RWxlbWVudCk7XG4gIHZhciBjbGllbnRTaXplID0gYXJyb3dPZmZzZXRQYXJlbnQgPyBheGlzID09PSAneScgPyBhcnJvd09mZnNldFBhcmVudC5jbGllbnRIZWlnaHQgfHwgMCA6IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudFdpZHRoIHx8IDAgOiAwO1xuICB2YXIgY2VudGVyVG9SZWZlcmVuY2UgPSBlbmREaWZmIC8gMiAtIHN0YXJ0RGlmZiAvIDI7IC8vIE1ha2Ugc3VyZSB0aGUgYXJyb3cgZG9lc24ndCBvdmVyZmxvdyB0aGUgcG9wcGVyIGlmIHRoZSBjZW50ZXIgcG9pbnQgaXNcbiAgLy8gb3V0c2lkZSBvZiB0aGUgcG9wcGVyIGJvdW5kc1xuXG4gIHZhciBtaW4gPSBwYWRkaW5nT2JqZWN0W21pblByb3BdO1xuICB2YXIgbWF4ID0gY2xpZW50U2l6ZSAtIGFycm93UmVjdFtsZW5dIC0gcGFkZGluZ09iamVjdFttYXhQcm9wXTtcbiAgdmFyIGNlbnRlciA9IGNsaWVudFNpemUgLyAyIC0gYXJyb3dSZWN0W2xlbl0gLyAyICsgY2VudGVyVG9SZWZlcmVuY2U7XG4gIHZhciBvZmZzZXQgPSB3aXRoaW4obWluLCBjZW50ZXIsIG1heCk7IC8vIFByZXZlbnRzIGJyZWFraW5nIHN5bnRheCBoaWdobGlnaHRpbmcuLi5cblxuICB2YXIgYXhpc1Byb3AgPSBheGlzO1xuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gKF9zdGF0ZSRtb2RpZmllcnNEYXRhJCA9IHt9LCBfc3RhdGUkbW9kaWZpZXJzRGF0YSRbYXhpc1Byb3BdID0gb2Zmc2V0LCBfc3RhdGUkbW9kaWZpZXJzRGF0YSQuY2VudGVyT2Zmc2V0ID0gb2Zmc2V0IC0gY2VudGVyLCBfc3RhdGUkbW9kaWZpZXJzRGF0YSQpO1xufVxuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZjIub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJGVsZW1lbnQgPSBvcHRpb25zLmVsZW1lbnQsXG4gICAgICBhcnJvd0VsZW1lbnQgPSBfb3B0aW9ucyRlbGVtZW50ID09PSB2b2lkIDAgPyAnW2RhdGEtcG9wcGVyLWFycm93XScgOiBfb3B0aW9ucyRlbGVtZW50O1xuXG4gIGlmIChhcnJvd0VsZW1lbnQgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfSAvLyBDU1Mgc2VsZWN0b3JcblxuXG4gIGlmICh0eXBlb2YgYXJyb3dFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgIGFycm93RWxlbWVudCA9IHN0YXRlLmVsZW1lbnRzLnBvcHBlci5xdWVyeVNlbGVjdG9yKGFycm93RWxlbWVudCk7XG5cbiAgICBpZiAoIWFycm93RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmICghY29udGFpbnMoc3RhdGUuZWxlbWVudHMucG9wcGVyLCBhcnJvd0VsZW1lbnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgc3RhdGUuZWxlbWVudHMuYXJyb3cgPSBhcnJvd0VsZW1lbnQ7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdhcnJvdycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBhcnJvdyxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIHJlcXVpcmVzOiBbJ3BvcHBlck9mZnNldHMnXSxcbiAgcmVxdWlyZXNJZkV4aXN0czogWydwcmV2ZW50T3ZlcmZsb3cnXVxufTsiLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCkge1xuICByZXR1cm4gcGxhY2VtZW50LnNwbGl0KCctJylbMV07XG59IiwgImltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgZW5kIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG52YXIgdW5zZXRTaWRlcyA9IHtcbiAgdG9wOiAnYXV0bycsXG4gIHJpZ2h0OiAnYXV0bycsXG4gIGJvdHRvbTogJ2F1dG8nLFxuICBsZWZ0OiAnYXV0bydcbn07IC8vIFJvdW5kIHRoZSBvZmZzZXRzIHRvIHRoZSBuZWFyZXN0IHN1aXRhYmxlIHN1YnBpeGVsIGJhc2VkIG9uIHRoZSBEUFIuXG4vLyBab29taW5nIGNhbiBjaGFuZ2UgdGhlIERQUiwgYnV0IGl0IHNlZW1zIHRvIHJlcG9ydCBhIHZhbHVlIHRoYXQgd2lsbFxuLy8gY2xlYW5seSBkaXZpZGUgdGhlIHZhbHVlcyBpbnRvIHRoZSBhcHByb3ByaWF0ZSBzdWJwaXhlbHMuXG5cbmZ1bmN0aW9uIHJvdW5kT2Zmc2V0c0J5RFBSKF9yZWYsIHdpbikge1xuICB2YXIgeCA9IF9yZWYueCxcbiAgICAgIHkgPSBfcmVmLnk7XG4gIHZhciBkcHIgPSB3aW4uZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuICByZXR1cm4ge1xuICAgIHg6IHJvdW5kKHggKiBkcHIpIC8gZHByIHx8IDAsXG4gICAgeTogcm91bmQoeSAqIGRwcikgLyBkcHIgfHwgMFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFwVG9TdHlsZXMoX3JlZjIpIHtcbiAgdmFyIF9PYmplY3QkYXNzaWduMjtcblxuICB2YXIgcG9wcGVyID0gX3JlZjIucG9wcGVyLFxuICAgICAgcG9wcGVyUmVjdCA9IF9yZWYyLnBvcHBlclJlY3QsXG4gICAgICBwbGFjZW1lbnQgPSBfcmVmMi5wbGFjZW1lbnQsXG4gICAgICB2YXJpYXRpb24gPSBfcmVmMi52YXJpYXRpb24sXG4gICAgICBvZmZzZXRzID0gX3JlZjIub2Zmc2V0cyxcbiAgICAgIHBvc2l0aW9uID0gX3JlZjIucG9zaXRpb24sXG4gICAgICBncHVBY2NlbGVyYXRpb24gPSBfcmVmMi5ncHVBY2NlbGVyYXRpb24sXG4gICAgICBhZGFwdGl2ZSA9IF9yZWYyLmFkYXB0aXZlLFxuICAgICAgcm91bmRPZmZzZXRzID0gX3JlZjIucm91bmRPZmZzZXRzLFxuICAgICAgaXNGaXhlZCA9IF9yZWYyLmlzRml4ZWQ7XG4gIHZhciBfb2Zmc2V0cyR4ID0gb2Zmc2V0cy54LFxuICAgICAgeCA9IF9vZmZzZXRzJHggPT09IHZvaWQgMCA/IDAgOiBfb2Zmc2V0cyR4LFxuICAgICAgX29mZnNldHMkeSA9IG9mZnNldHMueSxcbiAgICAgIHkgPSBfb2Zmc2V0cyR5ID09PSB2b2lkIDAgPyAwIDogX29mZnNldHMkeTtcblxuICB2YXIgX3JlZjMgPSB0eXBlb2Ygcm91bmRPZmZzZXRzID09PSAnZnVuY3Rpb24nID8gcm91bmRPZmZzZXRzKHtcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfSkgOiB7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG5cbiAgeCA9IF9yZWYzLng7XG4gIHkgPSBfcmVmMy55O1xuICB2YXIgaGFzWCA9IG9mZnNldHMuaGFzT3duUHJvcGVydHkoJ3gnKTtcbiAgdmFyIGhhc1kgPSBvZmZzZXRzLmhhc093blByb3BlcnR5KCd5Jyk7XG4gIHZhciBzaWRlWCA9IGxlZnQ7XG4gIHZhciBzaWRlWSA9IHRvcDtcbiAgdmFyIHdpbiA9IHdpbmRvdztcblxuICBpZiAoYWRhcHRpdmUpIHtcbiAgICB2YXIgb2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KHBvcHBlcik7XG4gICAgdmFyIGhlaWdodFByb3AgPSAnY2xpZW50SGVpZ2h0JztcbiAgICB2YXIgd2lkdGhQcm9wID0gJ2NsaWVudFdpZHRoJztcblxuICAgIGlmIChvZmZzZXRQYXJlbnQgPT09IGdldFdpbmRvdyhwb3BwZXIpKSB7XG4gICAgICBvZmZzZXRQYXJlbnQgPSBnZXREb2N1bWVudEVsZW1lbnQocG9wcGVyKTtcblxuICAgICAgaWYgKGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiAhPT0gJ3N0YXRpYycgJiYgcG9zaXRpb24gPT09ICdhYnNvbHV0ZScpIHtcbiAgICAgICAgaGVpZ2h0UHJvcCA9ICdzY3JvbGxIZWlnaHQnO1xuICAgICAgICB3aWR0aFByb3AgPSAnc2Nyb2xsV2lkdGgnO1xuICAgICAgfVxuICAgIH0gLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FzdF06IGZvcmNlIHR5cGUgcmVmaW5lbWVudCwgd2UgY29tcGFyZSBvZmZzZXRQYXJlbnQgd2l0aCB3aW5kb3cgYWJvdmUsIGJ1dCBGbG93IGRvZXNuJ3QgZGV0ZWN0IGl0XG5cblxuICAgIG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudDtcblxuICAgIGlmIChwbGFjZW1lbnQgPT09IHRvcCB8fCAocGxhY2VtZW50ID09PSBsZWZ0IHx8IHBsYWNlbWVudCA9PT0gcmlnaHQpICYmIHZhcmlhdGlvbiA9PT0gZW5kKSB7XG4gICAgICBzaWRlWSA9IGJvdHRvbTtcbiAgICAgIHZhciBvZmZzZXRZID0gaXNGaXhlZCAmJiBvZmZzZXRQYXJlbnQgPT09IHdpbiAmJiB3aW4udmlzdWFsVmlld3BvcnQgPyB3aW4udmlzdWFsVmlld3BvcnQuaGVpZ2h0IDogLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddXG4gICAgICBvZmZzZXRQYXJlbnRbaGVpZ2h0UHJvcF07XG4gICAgICB5IC09IG9mZnNldFkgLSBwb3BwZXJSZWN0LmhlaWdodDtcbiAgICAgIHkgKj0gZ3B1QWNjZWxlcmF0aW9uID8gMSA6IC0xO1xuICAgIH1cblxuICAgIGlmIChwbGFjZW1lbnQgPT09IGxlZnQgfHwgKHBsYWNlbWVudCA9PT0gdG9wIHx8IHBsYWNlbWVudCA9PT0gYm90dG9tKSAmJiB2YXJpYXRpb24gPT09IGVuZCkge1xuICAgICAgc2lkZVggPSByaWdodDtcbiAgICAgIHZhciBvZmZzZXRYID0gaXNGaXhlZCAmJiBvZmZzZXRQYXJlbnQgPT09IHdpbiAmJiB3aW4udmlzdWFsVmlld3BvcnQgPyB3aW4udmlzdWFsVmlld3BvcnQud2lkdGggOiAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgIG9mZnNldFBhcmVudFt3aWR0aFByb3BdO1xuICAgICAgeCAtPSBvZmZzZXRYIC0gcG9wcGVyUmVjdC53aWR0aDtcbiAgICAgIHggKj0gZ3B1QWNjZWxlcmF0aW9uID8gMSA6IC0xO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjb21tb25TdHlsZXMgPSBPYmplY3QuYXNzaWduKHtcbiAgICBwb3NpdGlvbjogcG9zaXRpb25cbiAgfSwgYWRhcHRpdmUgJiYgdW5zZXRTaWRlcyk7XG5cbiAgdmFyIF9yZWY0ID0gcm91bmRPZmZzZXRzID09PSB0cnVlID8gcm91bmRPZmZzZXRzQnlEUFIoe1xuICAgIHg6IHgsXG4gICAgeTogeVxuICB9LCBnZXRXaW5kb3cocG9wcGVyKSkgOiB7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG5cbiAgeCA9IF9yZWY0Lng7XG4gIHkgPSBfcmVmNC55O1xuXG4gIGlmIChncHVBY2NlbGVyYXRpb24pIHtcbiAgICB2YXIgX09iamVjdCRhc3NpZ247XG5cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCAoX09iamVjdCRhc3NpZ24gPSB7fSwgX09iamVjdCRhc3NpZ25bc2lkZVldID0gaGFzWSA/ICcwJyA6ICcnLCBfT2JqZWN0JGFzc2lnbltzaWRlWF0gPSBoYXNYID8gJzAnIDogJycsIF9PYmplY3QkYXNzaWduLnRyYW5zZm9ybSA9ICh3aW4uZGV2aWNlUGl4ZWxSYXRpbyB8fCAxKSA8PSAxID8gXCJ0cmFuc2xhdGUoXCIgKyB4ICsgXCJweCwgXCIgKyB5ICsgXCJweClcIiA6IFwidHJhbnNsYXRlM2QoXCIgKyB4ICsgXCJweCwgXCIgKyB5ICsgXCJweCwgMClcIiwgX09iamVjdCRhc3NpZ24pKTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBjb21tb25TdHlsZXMsIChfT2JqZWN0JGFzc2lnbjIgPSB7fSwgX09iamVjdCRhc3NpZ24yW3NpZGVZXSA9IGhhc1kgPyB5ICsgXCJweFwiIDogJycsIF9PYmplY3QkYXNzaWduMltzaWRlWF0gPSBoYXNYID8geCArIFwicHhcIiA6ICcnLCBfT2JqZWN0JGFzc2lnbjIudHJhbnNmb3JtID0gJycsIF9PYmplY3QkYXNzaWduMikpO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlU3R5bGVzKF9yZWY1KSB7XG4gIHZhciBzdGF0ZSA9IF9yZWY1LnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWY1Lm9wdGlvbnM7XG4gIHZhciBfb3B0aW9ucyRncHVBY2NlbGVyYXQgPSBvcHRpb25zLmdwdUFjY2VsZXJhdGlvbixcbiAgICAgIGdwdUFjY2VsZXJhdGlvbiA9IF9vcHRpb25zJGdwdUFjY2VsZXJhdCA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGdwdUFjY2VsZXJhdCxcbiAgICAgIF9vcHRpb25zJGFkYXB0aXZlID0gb3B0aW9ucy5hZGFwdGl2ZSxcbiAgICAgIGFkYXB0aXZlID0gX29wdGlvbnMkYWRhcHRpdmUgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRhZGFwdGl2ZSxcbiAgICAgIF9vcHRpb25zJHJvdW5kT2Zmc2V0cyA9IG9wdGlvbnMucm91bmRPZmZzZXRzLFxuICAgICAgcm91bmRPZmZzZXRzID0gX29wdGlvbnMkcm91bmRPZmZzZXRzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkcm91bmRPZmZzZXRzO1xuICB2YXIgY29tbW9uU3R5bGVzID0ge1xuICAgIHBsYWNlbWVudDogZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpLFxuICAgIHZhcmlhdGlvbjogZ2V0VmFyaWF0aW9uKHN0YXRlLnBsYWNlbWVudCksXG4gICAgcG9wcGVyOiBzdGF0ZS5lbGVtZW50cy5wb3BwZXIsXG4gICAgcG9wcGVyUmVjdDogc3RhdGUucmVjdHMucG9wcGVyLFxuICAgIGdwdUFjY2VsZXJhdGlvbjogZ3B1QWNjZWxlcmF0aW9uLFxuICAgIGlzRml4ZWQ6IHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3kgPT09ICdmaXhlZCdcbiAgfTtcblxuICBpZiAoc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzICE9IG51bGwpIHtcbiAgICBzdGF0ZS5zdHlsZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuc3R5bGVzLnBvcHBlciwgbWFwVG9TdHlsZXMoT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCB7XG4gICAgICBvZmZzZXRzOiBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMsXG4gICAgICBwb3NpdGlvbjogc3RhdGUub3B0aW9ucy5zdHJhdGVneSxcbiAgICAgIGFkYXB0aXZlOiBhZGFwdGl2ZSxcbiAgICAgIHJvdW5kT2Zmc2V0czogcm91bmRPZmZzZXRzXG4gICAgfSkpKTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5tb2RpZmllcnNEYXRhLmFycm93ICE9IG51bGwpIHtcbiAgICBzdGF0ZS5zdHlsZXMuYXJyb3cgPSBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5zdHlsZXMuYXJyb3csIG1hcFRvU3R5bGVzKE9iamVjdC5hc3NpZ24oe30sIGNvbW1vblN0eWxlcywge1xuICAgICAgb2Zmc2V0czogc3RhdGUubW9kaWZpZXJzRGF0YS5hcnJvdyxcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgYWRhcHRpdmU6IGZhbHNlLFxuICAgICAgcm91bmRPZmZzZXRzOiByb3VuZE9mZnNldHNcbiAgICB9KSkpO1xuICB9XG5cbiAgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIgPSBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5hdHRyaWJ1dGVzLnBvcHBlciwge1xuICAgICdkYXRhLXBvcHBlci1wbGFjZW1lbnQnOiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSk7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdjb21wdXRlU3R5bGVzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdiZWZvcmVXcml0ZScsXG4gIGZuOiBjb21wdXRlU3R5bGVzLFxuICBkYXRhOiB7fVxufTsiLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldFdpbmRvdy5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbnZhciBwYXNzaXZlID0ge1xuICBwYXNzaXZlOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgaW5zdGFuY2UgPSBfcmVmLmluc3RhbmNlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJHNjcm9sbCA9IG9wdGlvbnMuc2Nyb2xsLFxuICAgICAgc2Nyb2xsID0gX29wdGlvbnMkc2Nyb2xsID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkc2Nyb2xsLFxuICAgICAgX29wdGlvbnMkcmVzaXplID0gb3B0aW9ucy5yZXNpemUsXG4gICAgICByZXNpemUgPSBfb3B0aW9ucyRyZXNpemUgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRyZXNpemU7XG4gIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coc3RhdGUuZWxlbWVudHMucG9wcGVyKTtcbiAgdmFyIHNjcm9sbFBhcmVudHMgPSBbXS5jb25jYXQoc3RhdGUuc2Nyb2xsUGFyZW50cy5yZWZlcmVuY2UsIHN0YXRlLnNjcm9sbFBhcmVudHMucG9wcGVyKTtcblxuICBpZiAoc2Nyb2xsKSB7XG4gICAgc2Nyb2xsUGFyZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChzY3JvbGxQYXJlbnQpIHtcbiAgICAgIHNjcm9sbFBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHJlc2l6ZSkge1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc2Nyb2xsKSB7XG4gICAgICBzY3JvbGxQYXJlbnRzLmZvckVhY2goZnVuY3Rpb24gKHNjcm9sbFBhcmVudCkge1xuICAgICAgICBzY3JvbGxQYXJlbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgaW5zdGFuY2UudXBkYXRlLCBwYXNzaXZlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChyZXNpemUpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH1cbiAgfTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2V2ZW50TGlzdGVuZXJzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICd3cml0ZScsXG4gIGZuOiBmdW5jdGlvbiBmbigpIHt9LFxuICBlZmZlY3Q6IGVmZmVjdCxcbiAgZGF0YToge31cbn07IiwgInZhciBoYXNoID0ge1xuICBsZWZ0OiAncmlnaHQnLFxuICByaWdodDogJ2xlZnQnLFxuICBib3R0b206ICd0b3AnLFxuICB0b3A6ICdib3R0b20nXG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T3Bwb3NpdGVQbGFjZW1lbnQocGxhY2VtZW50KSB7XG4gIHJldHVybiBwbGFjZW1lbnQucmVwbGFjZSgvbGVmdHxyaWdodHxib3R0b218dG9wL2csIGZ1bmN0aW9uIChtYXRjaGVkKSB7XG4gICAgcmV0dXJuIGhhc2hbbWF0Y2hlZF07XG4gIH0pO1xufSIsICJ2YXIgaGFzaCA9IHtcbiAgc3RhcnQ6ICdlbmQnLFxuICBlbmQ6ICdzdGFydCdcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5yZXBsYWNlKC9zdGFydHxlbmQvZywgZnVuY3Rpb24gKG1hdGNoZWQpIHtcbiAgICByZXR1cm4gaGFzaFttYXRjaGVkXTtcbiAgfSk7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRXaW5kb3dTY3JvbGwobm9kZSkge1xuICB2YXIgd2luID0gZ2V0V2luZG93KG5vZGUpO1xuICB2YXIgc2Nyb2xsTGVmdCA9IHdpbi5wYWdlWE9mZnNldDtcbiAgdmFyIHNjcm9sbFRvcCA9IHdpbi5wYWdlWU9mZnNldDtcbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBzY3JvbGxMZWZ0LFxuICAgIHNjcm9sbFRvcDogc2Nyb2xsVG9wXG4gIH07XG59IiwgImltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4vZ2V0Qm91bmRpbmdDbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldFdpbmRvd1Njcm9sbEJhclgoZWxlbWVudCkge1xuICAvLyBJZiA8aHRtbD4gaGFzIGEgQ1NTIHdpZHRoIGdyZWF0ZXIgdGhhbiB0aGUgdmlld3BvcnQsIHRoZW4gdGhpcyB3aWxsIGJlXG4gIC8vIGluY29ycmVjdCBmb3IgUlRMLlxuICAvLyBQb3BwZXIgMSBpcyBicm9rZW4gaW4gdGhpcyBjYXNlIGFuZCBuZXZlciBoYWQgYSBidWcgcmVwb3J0IHNvIGxldCdzIGFzc3VtZVxuICAvLyBpdCdzIG5vdCBhbiBpc3N1ZS4gSSBkb24ndCB0aGluayBhbnlvbmUgZXZlciBzcGVjaWZpZXMgd2lkdGggb24gPGh0bWw+XG4gIC8vIGFueXdheS5cbiAgLy8gQnJvd3NlcnMgd2hlcmUgdGhlIGxlZnQgc2Nyb2xsYmFyIGRvZXNuJ3QgY2F1c2UgYW4gaXNzdWUgcmVwb3J0IGAwYCBmb3JcbiAgLy8gdGhpcyAoZS5nLiBFZGdlIDIwMTksIElFMTEsIFNhZmFyaSlcbiAgcmV0dXJuIGdldEJvdW5kaW5nQ2xpZW50UmVjdChnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkpLmxlZnQgKyBnZXRXaW5kb3dTY3JvbGwoZWxlbWVudCkuc2Nyb2xsTGVmdDtcbn0iLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93U2Nyb2xsQmFyWCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGxCYXJYLmpzXCI7XG5pbXBvcnQgaXNMYXlvdXRWaWV3cG9ydCBmcm9tIFwiLi9pc0xheW91dFZpZXdwb3J0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRWaWV3cG9ydFJlY3QoZWxlbWVudCwgc3RyYXRlZ3kpIHtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhlbGVtZW50KTtcbiAgdmFyIGh0bWwgPSBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCk7XG4gIHZhciB2aXN1YWxWaWV3cG9ydCA9IHdpbi52aXN1YWxWaWV3cG9ydDtcbiAgdmFyIHdpZHRoID0gaHRtbC5jbGllbnRXaWR0aDtcbiAgdmFyIGhlaWdodCA9IGh0bWwuY2xpZW50SGVpZ2h0O1xuICB2YXIgeCA9IDA7XG4gIHZhciB5ID0gMDtcblxuICBpZiAodmlzdWFsVmlld3BvcnQpIHtcbiAgICB3aWR0aCA9IHZpc3VhbFZpZXdwb3J0LndpZHRoO1xuICAgIGhlaWdodCA9IHZpc3VhbFZpZXdwb3J0LmhlaWdodDtcbiAgICB2YXIgbGF5b3V0Vmlld3BvcnQgPSBpc0xheW91dFZpZXdwb3J0KCk7XG5cbiAgICBpZiAobGF5b3V0Vmlld3BvcnQgfHwgIWxheW91dFZpZXdwb3J0ICYmIHN0cmF0ZWd5ID09PSAnZml4ZWQnKSB7XG4gICAgICB4ID0gdmlzdWFsVmlld3BvcnQub2Zmc2V0TGVmdDtcbiAgICAgIHkgPSB2aXN1YWxWaWV3cG9ydC5vZmZzZXRUb3A7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogd2lkdGgsXG4gICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgeDogeCArIGdldFdpbmRvd1Njcm9sbEJhclgoZWxlbWVudCksXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldENvbXB1dGVkU3R5bGUgZnJvbSBcIi4vZ2V0Q29tcHV0ZWRTdHlsZS5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbEJhclggZnJvbSBcIi4vZ2V0V2luZG93U2Nyb2xsQmFyWC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGwuanNcIjtcbmltcG9ydCB7IG1heCB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7IC8vIEdldHMgdGhlIGVudGlyZSBzaXplIG9mIHRoZSBzY3JvbGxhYmxlIGRvY3VtZW50IGFyZWEsIGV2ZW4gZXh0ZW5kaW5nIG91dHNpZGVcbi8vIG9mIHRoZSBgPGh0bWw+YCBhbmQgYDxib2R5PmAgcmVjdCBib3VuZHMgaWYgaG9yaXpvbnRhbGx5IHNjcm9sbGFibGVcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RG9jdW1lbnRSZWN0KGVsZW1lbnQpIHtcbiAgdmFyIF9lbGVtZW50JG93bmVyRG9jdW1lbjtcblxuICB2YXIgaHRtbCA9IGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KTtcbiAgdmFyIHdpblNjcm9sbCA9IGdldFdpbmRvd1Njcm9sbChlbGVtZW50KTtcbiAgdmFyIGJvZHkgPSAoX2VsZW1lbnQkb3duZXJEb2N1bWVuID0gZWxlbWVudC5vd25lckRvY3VtZW50KSA9PSBudWxsID8gdm9pZCAwIDogX2VsZW1lbnQkb3duZXJEb2N1bWVuLmJvZHk7XG4gIHZhciB3aWR0aCA9IG1heChodG1sLnNjcm9sbFdpZHRoLCBodG1sLmNsaWVudFdpZHRoLCBib2R5ID8gYm9keS5zY3JvbGxXaWR0aCA6IDAsIGJvZHkgPyBib2R5LmNsaWVudFdpZHRoIDogMCk7XG4gIHZhciBoZWlnaHQgPSBtYXgoaHRtbC5zY3JvbGxIZWlnaHQsIGh0bWwuY2xpZW50SGVpZ2h0LCBib2R5ID8gYm9keS5zY3JvbGxIZWlnaHQgOiAwLCBib2R5ID8gYm9keS5jbGllbnRIZWlnaHQgOiAwKTtcbiAgdmFyIHggPSAtd2luU2Nyb2xsLnNjcm9sbExlZnQgKyBnZXRXaW5kb3dTY3JvbGxCYXJYKGVsZW1lbnQpO1xuICB2YXIgeSA9IC13aW5TY3JvbGwuc2Nyb2xsVG9wO1xuXG4gIGlmIChnZXRDb21wdXRlZFN0eWxlKGJvZHkgfHwgaHRtbCkuZGlyZWN0aW9uID09PSAncnRsJykge1xuICAgIHggKz0gbWF4KGh0bWwuY2xpZW50V2lkdGgsIGJvZHkgPyBib2R5LmNsaWVudFdpZHRoIDogMCkgLSB3aWR0aDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0LFxuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc1Njcm9sbFBhcmVudChlbGVtZW50KSB7XG4gIC8vIEZpcmVmb3ggd2FudHMgdXMgdG8gY2hlY2sgYC14YCBhbmQgYC15YCB2YXJpYXRpb25zIGFzIHdlbGxcbiAgdmFyIF9nZXRDb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KSxcbiAgICAgIG92ZXJmbG93ID0gX2dldENvbXB1dGVkU3R5bGUub3ZlcmZsb3csXG4gICAgICBvdmVyZmxvd1ggPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1gsXG4gICAgICBvdmVyZmxvd1kgPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1k7XG5cbiAgcmV0dXJuIC9hdXRvfHNjcm9sbHxvdmVybGF5fGhpZGRlbi8udGVzdChvdmVyZmxvdyArIG92ZXJmbG93WSArIG92ZXJmbG93WCk7XG59IiwgImltcG9ydCBnZXRQYXJlbnROb2RlIGZyb20gXCIuL2dldFBhcmVudE5vZGUuanNcIjtcbmltcG9ydCBpc1Njcm9sbFBhcmVudCBmcm9tIFwiLi9pc1Njcm9sbFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0U2Nyb2xsUGFyZW50KG5vZGUpIHtcbiAgaWYgKFsnaHRtbCcsICdib2R5JywgJyNkb2N1bWVudCddLmluZGV4T2YoZ2V0Tm9kZU5hbWUobm9kZSkpID49IDApIHtcbiAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dOiBhc3N1bWUgYm9keSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gICAgcmV0dXJuIG5vZGUub3duZXJEb2N1bWVudC5ib2R5O1xuICB9XG5cbiAgaWYgKGlzSFRNTEVsZW1lbnQobm9kZSkgJiYgaXNTY3JvbGxQYXJlbnQobm9kZSkpIHtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHJldHVybiBnZXRTY3JvbGxQYXJlbnQoZ2V0UGFyZW50Tm9kZShub2RlKSk7XG59IiwgImltcG9ydCBnZXRTY3JvbGxQYXJlbnQgZnJvbSBcIi4vZ2V0U2Nyb2xsUGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0UGFyZW50Tm9kZSBmcm9tIFwiLi9nZXRQYXJlbnROb2RlLmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuL2dldFdpbmRvdy5qc1wiO1xuaW1wb3J0IGlzU2Nyb2xsUGFyZW50IGZyb20gXCIuL2lzU2Nyb2xsUGFyZW50LmpzXCI7XG4vKlxuZ2l2ZW4gYSBET00gZWxlbWVudCwgcmV0dXJuIHRoZSBsaXN0IG9mIGFsbCBzY3JvbGwgcGFyZW50cywgdXAgdGhlIGxpc3Qgb2YgYW5jZXNvcnNcbnVudGlsIHdlIGdldCB0byB0aGUgdG9wIHdpbmRvdyBvYmplY3QuIFRoaXMgbGlzdCBpcyB3aGF0IHdlIGF0dGFjaCBzY3JvbGwgbGlzdGVuZXJzXG50bywgYmVjYXVzZSBpZiBhbnkgb2YgdGhlc2UgcGFyZW50IGVsZW1lbnRzIHNjcm9sbCwgd2UnbGwgbmVlZCB0byByZS1jYWxjdWxhdGUgdGhlXG5yZWZlcmVuY2UgZWxlbWVudCdzIHBvc2l0aW9uLlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGlzdFNjcm9sbFBhcmVudHMoZWxlbWVudCwgbGlzdCkge1xuICB2YXIgX2VsZW1lbnQkb3duZXJEb2N1bWVuO1xuXG4gIGlmIChsaXN0ID09PSB2b2lkIDApIHtcbiAgICBsaXN0ID0gW107XG4gIH1cblxuICB2YXIgc2Nyb2xsUGFyZW50ID0gZ2V0U2Nyb2xsUGFyZW50KGVsZW1lbnQpO1xuICB2YXIgaXNCb2R5ID0gc2Nyb2xsUGFyZW50ID09PSAoKF9lbGVtZW50JG93bmVyRG9jdW1lbiA9IGVsZW1lbnQub3duZXJEb2N1bWVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9lbGVtZW50JG93bmVyRG9jdW1lbi5ib2R5KTtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhzY3JvbGxQYXJlbnQpO1xuICB2YXIgdGFyZ2V0ID0gaXNCb2R5ID8gW3dpbl0uY29uY2F0KHdpbi52aXN1YWxWaWV3cG9ydCB8fCBbXSwgaXNTY3JvbGxQYXJlbnQoc2Nyb2xsUGFyZW50KSA/IHNjcm9sbFBhcmVudCA6IFtdKSA6IHNjcm9sbFBhcmVudDtcbiAgdmFyIHVwZGF0ZWRMaXN0ID0gbGlzdC5jb25jYXQodGFyZ2V0KTtcbiAgcmV0dXJuIGlzQm9keSA/IHVwZGF0ZWRMaXN0IDogLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF06IGlzQm9keSB0ZWxscyB1cyB0YXJnZXQgd2lsbCBiZSBhbiBIVE1MRWxlbWVudCBoZXJlXG4gIHVwZGF0ZWRMaXN0LmNvbmNhdChsaXN0U2Nyb2xsUGFyZW50cyhnZXRQYXJlbnROb2RlKHRhcmdldCkpKTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVjdFRvQ2xpZW50UmVjdChyZWN0KSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCByZWN0LCB7XG4gICAgbGVmdDogcmVjdC54LFxuICAgIHRvcDogcmVjdC55LFxuICAgIHJpZ2h0OiByZWN0LnggKyByZWN0LndpZHRoLFxuICAgIGJvdHRvbTogcmVjdC55ICsgcmVjdC5oZWlnaHRcbiAgfSk7XG59IiwgImltcG9ydCB7IHZpZXdwb3J0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0Vmlld3BvcnRSZWN0IGZyb20gXCIuL2dldFZpZXdwb3J0UmVjdC5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50UmVjdCBmcm9tIFwiLi9nZXREb2N1bWVudFJlY3QuanNcIjtcbmltcG9ydCBsaXN0U2Nyb2xsUGFyZW50cyBmcm9tIFwiLi9saXN0U2Nyb2xsUGFyZW50cy5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5pbXBvcnQgeyBpc0VsZW1lbnQsIGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGNvbnRhaW5zIGZyb20gXCIuL2NvbnRhaW5zLmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCByZWN0VG9DbGllbnRSZWN0IGZyb20gXCIuLi91dGlscy9yZWN0VG9DbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgeyBtYXgsIG1pbiB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7XG5cbmZ1bmN0aW9uIGdldElubmVyQm91bmRpbmdDbGllbnRSZWN0KGVsZW1lbnQsIHN0cmF0ZWd5KSB7XG4gIHZhciByZWN0ID0gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KGVsZW1lbnQsIGZhbHNlLCBzdHJhdGVneSA9PT0gJ2ZpeGVkJyk7XG4gIHJlY3QudG9wID0gcmVjdC50b3AgKyBlbGVtZW50LmNsaWVudFRvcDtcbiAgcmVjdC5sZWZ0ID0gcmVjdC5sZWZ0ICsgZWxlbWVudC5jbGllbnRMZWZ0O1xuICByZWN0LmJvdHRvbSA9IHJlY3QudG9wICsgZWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gIHJlY3QucmlnaHQgPSByZWN0LmxlZnQgKyBlbGVtZW50LmNsaWVudFdpZHRoO1xuICByZWN0LndpZHRoID0gZWxlbWVudC5jbGllbnRXaWR0aDtcbiAgcmVjdC5oZWlnaHQgPSBlbGVtZW50LmNsaWVudEhlaWdodDtcbiAgcmVjdC54ID0gcmVjdC5sZWZ0O1xuICByZWN0LnkgPSByZWN0LnRvcDtcbiAgcmV0dXJuIHJlY3Q7XG59XG5cbmZ1bmN0aW9uIGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGNsaXBwaW5nUGFyZW50LCBzdHJhdGVneSkge1xuICByZXR1cm4gY2xpcHBpbmdQYXJlbnQgPT09IHZpZXdwb3J0ID8gcmVjdFRvQ2xpZW50UmVjdChnZXRWaWV3cG9ydFJlY3QoZWxlbWVudCwgc3RyYXRlZ3kpKSA6IGlzRWxlbWVudChjbGlwcGluZ1BhcmVudCkgPyBnZXRJbm5lckJvdW5kaW5nQ2xpZW50UmVjdChjbGlwcGluZ1BhcmVudCwgc3RyYXRlZ3kpIDogcmVjdFRvQ2xpZW50UmVjdChnZXREb2N1bWVudFJlY3QoZ2V0RG9jdW1lbnRFbGVtZW50KGVsZW1lbnQpKSk7XG59IC8vIEEgXCJjbGlwcGluZyBwYXJlbnRcIiBpcyBhbiBvdmVyZmxvd2FibGUgY29udGFpbmVyIHdpdGggdGhlIGNoYXJhY3RlcmlzdGljIG9mXG4vLyBjbGlwcGluZyAob3IgaGlkaW5nKSBvdmVyZmxvd2luZyBlbGVtZW50cyB3aXRoIGEgcG9zaXRpb24gZGlmZmVyZW50IGZyb21cbi8vIGBpbml0aWFsYFxuXG5cbmZ1bmN0aW9uIGdldENsaXBwaW5nUGFyZW50cyhlbGVtZW50KSB7XG4gIHZhciBjbGlwcGluZ1BhcmVudHMgPSBsaXN0U2Nyb2xsUGFyZW50cyhnZXRQYXJlbnROb2RlKGVsZW1lbnQpKTtcbiAgdmFyIGNhbkVzY2FwZUNsaXBwaW5nID0gWydhYnNvbHV0ZScsICdmaXhlZCddLmluZGV4T2YoZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5wb3NpdGlvbikgPj0gMDtcbiAgdmFyIGNsaXBwZXJFbGVtZW50ID0gY2FuRXNjYXBlQ2xpcHBpbmcgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSA/IGdldE9mZnNldFBhcmVudChlbGVtZW50KSA6IGVsZW1lbnQ7XG5cbiAgaWYgKCFpc0VsZW1lbnQoY2xpcHBlckVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9IC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXJldHVybl06IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9mbG93L2lzc3Vlcy8xNDE0XG5cblxuICByZXR1cm4gY2xpcHBpbmdQYXJlbnRzLmZpbHRlcihmdW5jdGlvbiAoY2xpcHBpbmdQYXJlbnQpIHtcbiAgICByZXR1cm4gaXNFbGVtZW50KGNsaXBwaW5nUGFyZW50KSAmJiBjb250YWlucyhjbGlwcGluZ1BhcmVudCwgY2xpcHBlckVsZW1lbnQpICYmIGdldE5vZGVOYW1lKGNsaXBwaW5nUGFyZW50KSAhPT0gJ2JvZHknO1xuICB9KTtcbn0gLy8gR2V0cyB0aGUgbWF4aW11bSBhcmVhIHRoYXQgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBpbiBkdWUgdG8gYW55IG51bWJlciBvZlxuLy8gY2xpcHBpbmcgcGFyZW50c1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENsaXBwaW5nUmVjdChlbGVtZW50LCBib3VuZGFyeSwgcm9vdEJvdW5kYXJ5LCBzdHJhdGVneSkge1xuICB2YXIgbWFpbkNsaXBwaW5nUGFyZW50cyA9IGJvdW5kYXJ5ID09PSAnY2xpcHBpbmdQYXJlbnRzJyA/IGdldENsaXBwaW5nUGFyZW50cyhlbGVtZW50KSA6IFtdLmNvbmNhdChib3VuZGFyeSk7XG4gIHZhciBjbGlwcGluZ1BhcmVudHMgPSBbXS5jb25jYXQobWFpbkNsaXBwaW5nUGFyZW50cywgW3Jvb3RCb3VuZGFyeV0pO1xuICB2YXIgZmlyc3RDbGlwcGluZ1BhcmVudCA9IGNsaXBwaW5nUGFyZW50c1swXTtcbiAgdmFyIGNsaXBwaW5nUmVjdCA9IGNsaXBwaW5nUGFyZW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFjY1JlY3QsIGNsaXBwaW5nUGFyZW50KSB7XG4gICAgdmFyIHJlY3QgPSBnZXRDbGllbnRSZWN0RnJvbU1peGVkVHlwZShlbGVtZW50LCBjbGlwcGluZ1BhcmVudCwgc3RyYXRlZ3kpO1xuICAgIGFjY1JlY3QudG9wID0gbWF4KHJlY3QudG9wLCBhY2NSZWN0LnRvcCk7XG4gICAgYWNjUmVjdC5yaWdodCA9IG1pbihyZWN0LnJpZ2h0LCBhY2NSZWN0LnJpZ2h0KTtcbiAgICBhY2NSZWN0LmJvdHRvbSA9IG1pbihyZWN0LmJvdHRvbSwgYWNjUmVjdC5ib3R0b20pO1xuICAgIGFjY1JlY3QubGVmdCA9IG1heChyZWN0LmxlZnQsIGFjY1JlY3QubGVmdCk7XG4gICAgcmV0dXJuIGFjY1JlY3Q7XG4gIH0sIGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGZpcnN0Q2xpcHBpbmdQYXJlbnQsIHN0cmF0ZWd5KSk7XG4gIGNsaXBwaW5nUmVjdC53aWR0aCA9IGNsaXBwaW5nUmVjdC5yaWdodCAtIGNsaXBwaW5nUmVjdC5sZWZ0O1xuICBjbGlwcGluZ1JlY3QuaGVpZ2h0ID0gY2xpcHBpbmdSZWN0LmJvdHRvbSAtIGNsaXBwaW5nUmVjdC50b3A7XG4gIGNsaXBwaW5nUmVjdC54ID0gY2xpcHBpbmdSZWN0LmxlZnQ7XG4gIGNsaXBwaW5nUmVjdC55ID0gY2xpcHBpbmdSZWN0LnRvcDtcbiAgcmV0dXJuIGNsaXBwaW5nUmVjdDtcbn0iLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4vZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQgZnJvbSBcIi4vZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgeyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQsIHN0YXJ0LCBlbmQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbXB1dGVPZmZzZXRzKF9yZWYpIHtcbiAgdmFyIHJlZmVyZW5jZSA9IF9yZWYucmVmZXJlbmNlLFxuICAgICAgZWxlbWVudCA9IF9yZWYuZWxlbWVudCxcbiAgICAgIHBsYWNlbWVudCA9IF9yZWYucGxhY2VtZW50O1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IHBsYWNlbWVudCA/IGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA6IG51bGw7XG4gIHZhciB2YXJpYXRpb24gPSBwbGFjZW1lbnQgPyBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA6IG51bGw7XG4gIHZhciBjb21tb25YID0gcmVmZXJlbmNlLnggKyByZWZlcmVuY2Uud2lkdGggLyAyIC0gZWxlbWVudC53aWR0aCAvIDI7XG4gIHZhciBjb21tb25ZID0gcmVmZXJlbmNlLnkgKyByZWZlcmVuY2UuaGVpZ2h0IC8gMiAtIGVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgdmFyIG9mZnNldHM7XG5cbiAgc3dpdGNoIChiYXNlUGxhY2VtZW50KSB7XG4gICAgY2FzZSB0b3A6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiBjb21tb25YLFxuICAgICAgICB5OiByZWZlcmVuY2UueSAtIGVsZW1lbnQuaGVpZ2h0XG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIGJvdHRvbTpcbiAgICAgIG9mZnNldHMgPSB7XG4gICAgICAgIHg6IGNvbW1vblgsXG4gICAgICAgIHk6IHJlZmVyZW5jZS55ICsgcmVmZXJlbmNlLmhlaWdodFxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSByaWdodDpcbiAgICAgIG9mZnNldHMgPSB7XG4gICAgICAgIHg6IHJlZmVyZW5jZS54ICsgcmVmZXJlbmNlLndpZHRoLFxuICAgICAgICB5OiBjb21tb25ZXG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIGxlZnQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCAtIGVsZW1lbnQud2lkdGgsXG4gICAgICAgIHk6IGNvbW1vbllcbiAgICAgIH07XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCxcbiAgICAgICAgeTogcmVmZXJlbmNlLnlcbiAgICAgIH07XG4gIH1cblxuICB2YXIgbWFpbkF4aXMgPSBiYXNlUGxhY2VtZW50ID8gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KGJhc2VQbGFjZW1lbnQpIDogbnVsbDtcblxuICBpZiAobWFpbkF4aXMgIT0gbnVsbCkge1xuICAgIHZhciBsZW4gPSBtYWluQXhpcyA9PT0gJ3knID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuXG4gICAgc3dpdGNoICh2YXJpYXRpb24pIHtcbiAgICAgIGNhc2Ugc3RhcnQ6XG4gICAgICAgIG9mZnNldHNbbWFpbkF4aXNdID0gb2Zmc2V0c1ttYWluQXhpc10gLSAocmVmZXJlbmNlW2xlbl0gLyAyIC0gZWxlbWVudFtsZW5dIC8gMik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIGVuZDpcbiAgICAgICAgb2Zmc2V0c1ttYWluQXhpc10gPSBvZmZzZXRzW21haW5BeGlzXSArIChyZWZlcmVuY2VbbGVuXSAvIDIgLSBlbGVtZW50W2xlbl0gLyAyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9mZnNldHM7XG59IiwgImltcG9ydCBnZXRDbGlwcGluZ1JlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBjb21wdXRlT2Zmc2V0cyBmcm9tIFwiLi9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuaW1wb3J0IHJlY3RUb0NsaWVudFJlY3QgZnJvbSBcIi4vcmVjdFRvQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IHsgY2xpcHBpbmdQYXJlbnRzLCByZWZlcmVuY2UsIHBvcHBlciwgYm90dG9tLCB0b3AsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdmlld3BvcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCB7IGlzRWxlbWVudCB9IGZyb20gXCIuLi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi9tZXJnZVBhZGRpbmdPYmplY3QuanNcIjtcbmltcG9ydCBleHBhbmRUb0hhc2hNYXAgZnJvbSBcIi4vZXhwYW5kVG9IYXNoTWFwLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBfb3B0aW9ucyRwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucyRwbGFjZW1lbnQgPT09IHZvaWQgMCA/IHN0YXRlLnBsYWNlbWVudCA6IF9vcHRpb25zJHBsYWNlbWVudCxcbiAgICAgIF9vcHRpb25zJHN0cmF0ZWd5ID0gX29wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBzdHJhdGVneSA9IF9vcHRpb25zJHN0cmF0ZWd5ID09PSB2b2lkIDAgPyBzdGF0ZS5zdHJhdGVneSA6IF9vcHRpb25zJHN0cmF0ZWd5LFxuICAgICAgX29wdGlvbnMkYm91bmRhcnkgPSBfb3B0aW9ucy5ib3VuZGFyeSxcbiAgICAgIGJvdW5kYXJ5ID0gX29wdGlvbnMkYm91bmRhcnkgPT09IHZvaWQgMCA/IGNsaXBwaW5nUGFyZW50cyA6IF9vcHRpb25zJGJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyB2aWV3cG9ydCA6IF9vcHRpb25zJHJvb3RCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJGVsZW1lbnRDb250ZSA9IF9vcHRpb25zLmVsZW1lbnRDb250ZXh0LFxuICAgICAgZWxlbWVudENvbnRleHQgPSBfb3B0aW9ucyRlbGVtZW50Q29udGUgPT09IHZvaWQgMCA/IHBvcHBlciA6IF9vcHRpb25zJGVsZW1lbnRDb250ZSxcbiAgICAgIF9vcHRpb25zJGFsdEJvdW5kYXJ5ID0gX29wdGlvbnMuYWx0Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeSA9IF9vcHRpb25zJGFsdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyBmYWxzZSA6IF9vcHRpb25zJGFsdEJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcGFkZGluZyA9IF9vcHRpb25zLnBhZGRpbmcsXG4gICAgICBwYWRkaW5nID0gX29wdGlvbnMkcGFkZGluZyA9PT0gdm9pZCAwID8gMCA6IF9vcHRpb25zJHBhZGRpbmc7XG4gIHZhciBwYWRkaW5nT2JqZWN0ID0gbWVyZ2VQYWRkaW5nT2JqZWN0KHR5cGVvZiBwYWRkaW5nICE9PSAnbnVtYmVyJyA/IHBhZGRpbmcgOiBleHBhbmRUb0hhc2hNYXAocGFkZGluZywgYmFzZVBsYWNlbWVudHMpKTtcbiAgdmFyIGFsdENvbnRleHQgPSBlbGVtZW50Q29udGV4dCA9PT0gcG9wcGVyID8gcmVmZXJlbmNlIDogcG9wcGVyO1xuICB2YXIgcG9wcGVyUmVjdCA9IHN0YXRlLnJlY3RzLnBvcHBlcjtcbiAgdmFyIGVsZW1lbnQgPSBzdGF0ZS5lbGVtZW50c1thbHRCb3VuZGFyeSA/IGFsdENvbnRleHQgOiBlbGVtZW50Q29udGV4dF07XG4gIHZhciBjbGlwcGluZ0NsaWVudFJlY3QgPSBnZXRDbGlwcGluZ1JlY3QoaXNFbGVtZW50KGVsZW1lbnQpID8gZWxlbWVudCA6IGVsZW1lbnQuY29udGV4dEVsZW1lbnQgfHwgZ2V0RG9jdW1lbnRFbGVtZW50KHN0YXRlLmVsZW1lbnRzLnBvcHBlciksIGJvdW5kYXJ5LCByb290Qm91bmRhcnksIHN0cmF0ZWd5KTtcbiAgdmFyIHJlZmVyZW5jZUNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3Qoc3RhdGUuZWxlbWVudHMucmVmZXJlbmNlKTtcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBjb21wdXRlT2Zmc2V0cyh7XG4gICAgcmVmZXJlbmNlOiByZWZlcmVuY2VDbGllbnRSZWN0LFxuICAgIGVsZW1lbnQ6IHBvcHBlclJlY3QsXG4gICAgc3RyYXRlZ3k6ICdhYnNvbHV0ZScsXG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSk7XG4gIHZhciBwb3BwZXJDbGllbnRSZWN0ID0gcmVjdFRvQ2xpZW50UmVjdChPYmplY3QuYXNzaWduKHt9LCBwb3BwZXJSZWN0LCBwb3BwZXJPZmZzZXRzKSk7XG4gIHZhciBlbGVtZW50Q2xpZW50UmVjdCA9IGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgPyBwb3BwZXJDbGllbnRSZWN0IDogcmVmZXJlbmNlQ2xpZW50UmVjdDsgLy8gcG9zaXRpdmUgPSBvdmVyZmxvd2luZyB0aGUgY2xpcHBpbmcgcmVjdFxuICAvLyAwIG9yIG5lZ2F0aXZlID0gd2l0aGluIHRoZSBjbGlwcGluZyByZWN0XG5cbiAgdmFyIG92ZXJmbG93T2Zmc2V0cyA9IHtcbiAgICB0b3A6IGNsaXBwaW5nQ2xpZW50UmVjdC50b3AgLSBlbGVtZW50Q2xpZW50UmVjdC50b3AgKyBwYWRkaW5nT2JqZWN0LnRvcCxcbiAgICBib3R0b206IGVsZW1lbnRDbGllbnRSZWN0LmJvdHRvbSAtIGNsaXBwaW5nQ2xpZW50UmVjdC5ib3R0b20gKyBwYWRkaW5nT2JqZWN0LmJvdHRvbSxcbiAgICBsZWZ0OiBjbGlwcGluZ0NsaWVudFJlY3QubGVmdCAtIGVsZW1lbnRDbGllbnRSZWN0LmxlZnQgKyBwYWRkaW5nT2JqZWN0LmxlZnQsXG4gICAgcmlnaHQ6IGVsZW1lbnRDbGllbnRSZWN0LnJpZ2h0IC0gY2xpcHBpbmdDbGllbnRSZWN0LnJpZ2h0ICsgcGFkZGluZ09iamVjdC5yaWdodFxuICB9O1xuICB2YXIgb2Zmc2V0RGF0YSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0OyAvLyBPZmZzZXRzIGNhbiBiZSBhcHBsaWVkIG9ubHkgdG8gdGhlIHBvcHBlciBlbGVtZW50XG5cbiAgaWYgKGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgJiYgb2Zmc2V0RGF0YSkge1xuICAgIHZhciBvZmZzZXQgPSBvZmZzZXREYXRhW3BsYWNlbWVudF07XG4gICAgT2JqZWN0LmtleXMob3ZlcmZsb3dPZmZzZXRzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHZhciBtdWx0aXBseSA9IFtyaWdodCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/IDEgOiAtMTtcbiAgICAgIHZhciBheGlzID0gW3RvcCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/ICd5JyA6ICd4JztcbiAgICAgIG92ZXJmbG93T2Zmc2V0c1trZXldICs9IG9mZnNldFtheGlzXSAqIG11bHRpcGx5O1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG92ZXJmbG93T2Zmc2V0cztcbn0iLCAiaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCB7IHZhcmlhdGlvblBsYWNlbWVudHMsIGJhc2VQbGFjZW1lbnRzLCBwbGFjZW1lbnRzIGFzIGFsbFBsYWNlbWVudHMgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCBkZXRlY3RPdmVyZmxvdyBmcm9tIFwiLi9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4vZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29tcHV0ZUF1dG9QbGFjZW1lbnQoc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBib3VuZGFyeSA9IF9vcHRpb25zLmJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZyA9IF9vcHRpb25zLnBhZGRpbmcsXG4gICAgICBmbGlwVmFyaWF0aW9ucyA9IF9vcHRpb25zLmZsaXBWYXJpYXRpb25zLFxuICAgICAgX29wdGlvbnMkYWxsb3dlZEF1dG9QID0gX29wdGlvbnMuYWxsb3dlZEF1dG9QbGFjZW1lbnRzLFxuICAgICAgYWxsb3dlZEF1dG9QbGFjZW1lbnRzID0gX29wdGlvbnMkYWxsb3dlZEF1dG9QID09PSB2b2lkIDAgPyBhbGxQbGFjZW1lbnRzIDogX29wdGlvbnMkYWxsb3dlZEF1dG9QO1xuICB2YXIgdmFyaWF0aW9uID0gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCk7XG4gIHZhciBwbGFjZW1lbnRzID0gdmFyaWF0aW9uID8gZmxpcFZhcmlhdGlvbnMgPyB2YXJpYXRpb25QbGFjZW1lbnRzIDogdmFyaWF0aW9uUGxhY2VtZW50cy5maWx0ZXIoZnVuY3Rpb24gKHBsYWNlbWVudCkge1xuICAgIHJldHVybiBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA9PT0gdmFyaWF0aW9uO1xuICB9KSA6IGJhc2VQbGFjZW1lbnRzO1xuICB2YXIgYWxsb3dlZFBsYWNlbWVudHMgPSBwbGFjZW1lbnRzLmZpbHRlcihmdW5jdGlvbiAocGxhY2VtZW50KSB7XG4gICAgcmV0dXJuIGFsbG93ZWRBdXRvUGxhY2VtZW50cy5pbmRleE9mKHBsYWNlbWVudCkgPj0gMDtcbiAgfSk7XG5cbiAgaWYgKGFsbG93ZWRQbGFjZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGFsbG93ZWRQbGFjZW1lbnRzID0gcGxhY2VtZW50cztcbiAgfSAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS10eXBlXTogRmxvdyBzZWVtcyB0byBoYXZlIHByb2JsZW1zIHdpdGggdHdvIGFycmF5IHVuaW9ucy4uLlxuXG5cbiAgdmFyIG92ZXJmbG93cyA9IGFsbG93ZWRQbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgICBhY2NbcGxhY2VtZW50XSA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZ1xuICAgIH0pW2dldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KV07XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xuICByZXR1cm4gT2JqZWN0LmtleXMob3ZlcmZsb3dzKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIG92ZXJmbG93c1thXSAtIG92ZXJmbG93c1tiXTtcbiAgfSk7XG59IiwgImltcG9ydCBnZXRPcHBvc2l0ZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0T3Bwb3NpdGVQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgY29tcHV0ZUF1dG9QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2NvbXB1dGVBdXRvUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgeyBib3R0b20sIHRvcCwgc3RhcnQsIHJpZ2h0LCBsZWZ0LCBhdXRvIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5mdW5jdGlvbiBnZXRFeHBhbmRlZEZhbGxiYWNrUGxhY2VtZW50cyhwbGFjZW1lbnQpIHtcbiAgaWYgKGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA9PT0gYXV0bykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHZhciBvcHBvc2l0ZVBsYWNlbWVudCA9IGdldE9wcG9zaXRlUGxhY2VtZW50KHBsYWNlbWVudCk7XG4gIHJldHVybiBbZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQocGxhY2VtZW50KSwgb3Bwb3NpdGVQbGFjZW1lbnQsIGdldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50KG9wcG9zaXRlUGxhY2VtZW50KV07XG59XG5cbmZ1bmN0aW9uIGZsaXAoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucyxcbiAgICAgIG5hbWUgPSBfcmVmLm5hbWU7XG5cbiAgaWYgKHN0YXRlLm1vZGlmaWVyc0RhdGFbbmFtZV0uX3NraXApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgX29wdGlvbnMkbWFpbkF4aXMgPSBvcHRpb25zLm1haW5BeGlzLFxuICAgICAgY2hlY2tNYWluQXhpcyA9IF9vcHRpb25zJG1haW5BeGlzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkbWFpbkF4aXMsXG4gICAgICBfb3B0aW9ucyRhbHRBeGlzID0gb3B0aW9ucy5hbHRBeGlzLFxuICAgICAgY2hlY2tBbHRBeGlzID0gX29wdGlvbnMkYWx0QXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGFsdEF4aXMsXG4gICAgICBzcGVjaWZpZWRGYWxsYmFja1BsYWNlbWVudHMgPSBvcHRpb25zLmZhbGxiYWNrUGxhY2VtZW50cyxcbiAgICAgIHBhZGRpbmcgPSBvcHRpb25zLnBhZGRpbmcsXG4gICAgICBib3VuZGFyeSA9IG9wdGlvbnMuYm91bmRhcnksXG4gICAgICByb290Qm91bmRhcnkgPSBvcHRpb25zLnJvb3RCb3VuZGFyeSxcbiAgICAgIGFsdEJvdW5kYXJ5ID0gb3B0aW9ucy5hbHRCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJGZsaXBWYXJpYXRpbyA9IG9wdGlvbnMuZmxpcFZhcmlhdGlvbnMsXG4gICAgICBmbGlwVmFyaWF0aW9ucyA9IF9vcHRpb25zJGZsaXBWYXJpYXRpbyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGZsaXBWYXJpYXRpbyxcbiAgICAgIGFsbG93ZWRBdXRvUGxhY2VtZW50cyA9IG9wdGlvbnMuYWxsb3dlZEF1dG9QbGFjZW1lbnRzO1xuICB2YXIgcHJlZmVycmVkUGxhY2VtZW50ID0gc3RhdGUub3B0aW9ucy5wbGFjZW1lbnQ7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwcmVmZXJyZWRQbGFjZW1lbnQpO1xuICB2YXIgaXNCYXNlUGxhY2VtZW50ID0gYmFzZVBsYWNlbWVudCA9PT0gcHJlZmVycmVkUGxhY2VtZW50O1xuICB2YXIgZmFsbGJhY2tQbGFjZW1lbnRzID0gc3BlY2lmaWVkRmFsbGJhY2tQbGFjZW1lbnRzIHx8IChpc0Jhc2VQbGFjZW1lbnQgfHwgIWZsaXBWYXJpYXRpb25zID8gW2dldE9wcG9zaXRlUGxhY2VtZW50KHByZWZlcnJlZFBsYWNlbWVudCldIDogZ2V0RXhwYW5kZWRGYWxsYmFja1BsYWNlbWVudHMocHJlZmVycmVkUGxhY2VtZW50KSk7XG4gIHZhciBwbGFjZW1lbnRzID0gW3ByZWZlcnJlZFBsYWNlbWVudF0uY29uY2F0KGZhbGxiYWNrUGxhY2VtZW50cykucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICAgIHJldHVybiBhY2MuY29uY2F0KGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA9PT0gYXV0byA/IGNvbXB1dGVBdXRvUGxhY2VtZW50KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZyxcbiAgICAgIGZsaXBWYXJpYXRpb25zOiBmbGlwVmFyaWF0aW9ucyxcbiAgICAgIGFsbG93ZWRBdXRvUGxhY2VtZW50czogYWxsb3dlZEF1dG9QbGFjZW1lbnRzXG4gICAgfSkgOiBwbGFjZW1lbnQpO1xuICB9LCBbXSk7XG4gIHZhciByZWZlcmVuY2VSZWN0ID0gc3RhdGUucmVjdHMucmVmZXJlbmNlO1xuICB2YXIgcG9wcGVyUmVjdCA9IHN0YXRlLnJlY3RzLnBvcHBlcjtcbiAgdmFyIGNoZWNrc01hcCA9IG5ldyBNYXAoKTtcbiAgdmFyIG1ha2VGYWxsYmFja0NoZWNrcyA9IHRydWU7XG4gIHZhciBmaXJzdEZpdHRpbmdQbGFjZW1lbnQgPSBwbGFjZW1lbnRzWzBdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGxhY2VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwbGFjZW1lbnQgPSBwbGFjZW1lbnRzW2ldO1xuXG4gICAgdmFyIF9iYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuXG4gICAgdmFyIGlzU3RhcnRWYXJpYXRpb24gPSBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA9PT0gc3RhcnQ7XG4gICAgdmFyIGlzVmVydGljYWwgPSBbdG9wLCBib3R0b21dLmluZGV4T2YoX2Jhc2VQbGFjZW1lbnQpID49IDA7XG4gICAgdmFyIGxlbiA9IGlzVmVydGljYWwgPyAnd2lkdGgnIDogJ2hlaWdodCc7XG4gICAgdmFyIG92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICAgIHBsYWNlbWVudDogcGxhY2VtZW50LFxuICAgICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5OiByb290Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeTogYWx0Qm91bmRhcnksXG4gICAgICBwYWRkaW5nOiBwYWRkaW5nXG4gICAgfSk7XG4gICAgdmFyIG1haW5WYXJpYXRpb25TaWRlID0gaXNWZXJ0aWNhbCA/IGlzU3RhcnRWYXJpYXRpb24gPyByaWdodCA6IGxlZnQgOiBpc1N0YXJ0VmFyaWF0aW9uID8gYm90dG9tIDogdG9wO1xuXG4gICAgaWYgKHJlZmVyZW5jZVJlY3RbbGVuXSA+IHBvcHBlclJlY3RbbGVuXSkge1xuICAgICAgbWFpblZhcmlhdGlvblNpZGUgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChtYWluVmFyaWF0aW9uU2lkZSk7XG4gICAgfVxuXG4gICAgdmFyIGFsdFZhcmlhdGlvblNpZGUgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChtYWluVmFyaWF0aW9uU2lkZSk7XG4gICAgdmFyIGNoZWNrcyA9IFtdO1xuXG4gICAgaWYgKGNoZWNrTWFpbkF4aXMpIHtcbiAgICAgIGNoZWNrcy5wdXNoKG92ZXJmbG93W19iYXNlUGxhY2VtZW50XSA8PSAwKTtcbiAgICB9XG5cbiAgICBpZiAoY2hlY2tBbHRBeGlzKSB7XG4gICAgICBjaGVja3MucHVzaChvdmVyZmxvd1ttYWluVmFyaWF0aW9uU2lkZV0gPD0gMCwgb3ZlcmZsb3dbYWx0VmFyaWF0aW9uU2lkZV0gPD0gMCk7XG4gICAgfVxuXG4gICAgaWYgKGNoZWNrcy5ldmVyeShmdW5jdGlvbiAoY2hlY2spIHtcbiAgICAgIHJldHVybiBjaGVjaztcbiAgICB9KSkge1xuICAgICAgZmlyc3RGaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50O1xuICAgICAgbWFrZUZhbGxiYWNrQ2hlY2tzID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjaGVja3NNYXAuc2V0KHBsYWNlbWVudCwgY2hlY2tzKTtcbiAgfVxuXG4gIGlmIChtYWtlRmFsbGJhY2tDaGVja3MpIHtcbiAgICAvLyBgMmAgbWF5IGJlIGRlc2lyZWQgaW4gc29tZSBjYXNlcyBcdTIwMTMgcmVzZWFyY2ggbGF0ZXJcbiAgICB2YXIgbnVtYmVyT2ZDaGVja3MgPSBmbGlwVmFyaWF0aW9ucyA/IDMgOiAxO1xuXG4gICAgdmFyIF9sb29wID0gZnVuY3Rpb24gX2xvb3AoX2kpIHtcbiAgICAgIHZhciBmaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50cy5maW5kKGZ1bmN0aW9uIChwbGFjZW1lbnQpIHtcbiAgICAgICAgdmFyIGNoZWNrcyA9IGNoZWNrc01hcC5nZXQocGxhY2VtZW50KTtcblxuICAgICAgICBpZiAoY2hlY2tzKSB7XG4gICAgICAgICAgcmV0dXJuIGNoZWNrcy5zbGljZSgwLCBfaSkuZXZlcnkoZnVuY3Rpb24gKGNoZWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gY2hlY2s7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAoZml0dGluZ1BsYWNlbWVudCkge1xuICAgICAgICBmaXJzdEZpdHRpbmdQbGFjZW1lbnQgPSBmaXR0aW5nUGxhY2VtZW50O1xuICAgICAgICByZXR1cm4gXCJicmVha1wiO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKHZhciBfaSA9IG51bWJlck9mQ2hlY2tzOyBfaSA+IDA7IF9pLS0pIHtcbiAgICAgIHZhciBfcmV0ID0gX2xvb3AoX2kpO1xuXG4gICAgICBpZiAoX3JldCA9PT0gXCJicmVha1wiKSBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUucGxhY2VtZW50ICE9PSBmaXJzdEZpdHRpbmdQbGFjZW1lbnQpIHtcbiAgICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdLl9za2lwID0gdHJ1ZTtcbiAgICBzdGF0ZS5wbGFjZW1lbnQgPSBmaXJzdEZpdHRpbmdQbGFjZW1lbnQ7XG4gICAgc3RhdGUucmVzZXQgPSB0cnVlO1xuICB9XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdmbGlwJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdtYWluJyxcbiAgZm46IGZsaXAsXG4gIHJlcXVpcmVzSWZFeGlzdHM6IFsnb2Zmc2V0J10sXG4gIGRhdGE6IHtcbiAgICBfc2tpcDogZmFsc2VcbiAgfVxufTsiLCAiaW1wb3J0IHsgdG9wLCBib3R0b20sIGxlZnQsIHJpZ2h0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5cbmZ1bmN0aW9uIGdldFNpZGVPZmZzZXRzKG92ZXJmbG93LCByZWN0LCBwcmV2ZW50ZWRPZmZzZXRzKSB7XG4gIGlmIChwcmV2ZW50ZWRPZmZzZXRzID09PSB2b2lkIDApIHtcbiAgICBwcmV2ZW50ZWRPZmZzZXRzID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0b3A6IG92ZXJmbG93LnRvcCAtIHJlY3QuaGVpZ2h0IC0gcHJldmVudGVkT2Zmc2V0cy55LFxuICAgIHJpZ2h0OiBvdmVyZmxvdy5yaWdodCAtIHJlY3Qud2lkdGggKyBwcmV2ZW50ZWRPZmZzZXRzLngsXG4gICAgYm90dG9tOiBvdmVyZmxvdy5ib3R0b20gLSByZWN0LmhlaWdodCArIHByZXZlbnRlZE9mZnNldHMueSxcbiAgICBsZWZ0OiBvdmVyZmxvdy5sZWZ0IC0gcmVjdC53aWR0aCAtIHByZXZlbnRlZE9mZnNldHMueFxuICB9O1xufVxuXG5mdW5jdGlvbiBpc0FueVNpZGVGdWxseUNsaXBwZWQob3ZlcmZsb3cpIHtcbiAgcmV0dXJuIFt0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRdLnNvbWUoZnVuY3Rpb24gKHNpZGUpIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dbc2lkZV0gPj0gMDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGhpZGUoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgcHJldmVudGVkT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucHJldmVudE92ZXJmbG93O1xuICB2YXIgcmVmZXJlbmNlT3ZlcmZsb3cgPSBkZXRlY3RPdmVyZmxvdyhzdGF0ZSwge1xuICAgIGVsZW1lbnRDb250ZXh0OiAncmVmZXJlbmNlJ1xuICB9KTtcbiAgdmFyIHBvcHBlckFsdE92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICBhbHRCb3VuZGFyeTogdHJ1ZVxuICB9KTtcbiAgdmFyIHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyA9IGdldFNpZGVPZmZzZXRzKHJlZmVyZW5jZU92ZXJmbG93LCByZWZlcmVuY2VSZWN0KTtcbiAgdmFyIHBvcHBlckVzY2FwZU9mZnNldHMgPSBnZXRTaWRlT2Zmc2V0cyhwb3BwZXJBbHRPdmVyZmxvdywgcG9wcGVyUmVjdCwgcHJldmVudGVkT2Zmc2V0cyk7XG4gIHZhciBpc1JlZmVyZW5jZUhpZGRlbiA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChyZWZlcmVuY2VDbGlwcGluZ09mZnNldHMpO1xuICB2YXIgaGFzUG9wcGVyRXNjYXBlZCA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChwb3BwZXJFc2NhcGVPZmZzZXRzKTtcbiAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXSA9IHtcbiAgICByZWZlcmVuY2VDbGlwcGluZ09mZnNldHM6IHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyxcbiAgICBwb3BwZXJFc2NhcGVPZmZzZXRzOiBwb3BwZXJFc2NhcGVPZmZzZXRzLFxuICAgIGlzUmVmZXJlbmNlSGlkZGVuOiBpc1JlZmVyZW5jZUhpZGRlbixcbiAgICBoYXNQb3BwZXJFc2NhcGVkOiBoYXNQb3BwZXJFc2NhcGVkXG4gIH07XG4gIHN0YXRlLmF0dHJpYnV0ZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIsIHtcbiAgICAnZGF0YS1wb3BwZXItcmVmZXJlbmNlLWhpZGRlbic6IGlzUmVmZXJlbmNlSGlkZGVuLFxuICAgICdkYXRhLXBvcHBlci1lc2NhcGVkJzogaGFzUG9wcGVyRXNjYXBlZFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2hpZGUnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ21haW4nLFxuICByZXF1aXJlc0lmRXhpc3RzOiBbJ3ByZXZlbnRPdmVyZmxvdyddLFxuICBmbjogaGlkZVxufTsiLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIHBsYWNlbWVudHMgfSBmcm9tIFwiLi4vZW51bXMuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2VBbmRTa2lkZGluZ1RvWFkocGxhY2VtZW50LCByZWN0cywgb2Zmc2V0KSB7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuICB2YXIgaW52ZXJ0RGlzdGFuY2UgPSBbbGVmdCwgdG9wXS5pbmRleE9mKGJhc2VQbGFjZW1lbnQpID49IDAgPyAtMSA6IDE7XG5cbiAgdmFyIF9yZWYgPSB0eXBlb2Ygb2Zmc2V0ID09PSAnZnVuY3Rpb24nID8gb2Zmc2V0KE9iamVjdC5hc3NpZ24oe30sIHJlY3RzLCB7XG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSkpIDogb2Zmc2V0LFxuICAgICAgc2tpZGRpbmcgPSBfcmVmWzBdLFxuICAgICAgZGlzdGFuY2UgPSBfcmVmWzFdO1xuXG4gIHNraWRkaW5nID0gc2tpZGRpbmcgfHwgMDtcbiAgZGlzdGFuY2UgPSAoZGlzdGFuY2UgfHwgMCkgKiBpbnZlcnREaXN0YW5jZTtcbiAgcmV0dXJuIFtsZWZ0LCByaWdodF0uaW5kZXhPZihiYXNlUGxhY2VtZW50KSA+PSAwID8ge1xuICAgIHg6IGRpc3RhbmNlLFxuICAgIHk6IHNraWRkaW5nXG4gIH0gOiB7XG4gICAgeDogc2tpZGRpbmcsXG4gICAgeTogZGlzdGFuY2VcbiAgfTtcbn1cblxuZnVuY3Rpb24gb2Zmc2V0KF9yZWYyKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYyLnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYyLm9wdGlvbnMsXG4gICAgICBuYW1lID0gX3JlZjIubmFtZTtcbiAgdmFyIF9vcHRpb25zJG9mZnNldCA9IG9wdGlvbnMub2Zmc2V0LFxuICAgICAgb2Zmc2V0ID0gX29wdGlvbnMkb2Zmc2V0ID09PSB2b2lkIDAgPyBbMCwgMF0gOiBfb3B0aW9ucyRvZmZzZXQ7XG4gIHZhciBkYXRhID0gcGxhY2VtZW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcGxhY2VtZW50KSB7XG4gICAgYWNjW3BsYWNlbWVudF0gPSBkaXN0YW5jZUFuZFNraWRkaW5nVG9YWShwbGFjZW1lbnQsIHN0YXRlLnJlY3RzLCBvZmZzZXQpO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbiAgdmFyIF9kYXRhJHN0YXRlJHBsYWNlbWVudCA9IGRhdGFbc3RhdGUucGxhY2VtZW50XSxcbiAgICAgIHggPSBfZGF0YSRzdGF0ZSRwbGFjZW1lbnQueCxcbiAgICAgIHkgPSBfZGF0YSRzdGF0ZSRwbGFjZW1lbnQueTtcblxuICBpZiAoc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzICE9IG51bGwpIHtcbiAgICBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMueCArPSB4O1xuICAgIHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cy55ICs9IHk7XG4gIH1cblxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gZGF0YTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ29mZnNldCcsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIHJlcXVpcmVzOiBbJ3BvcHBlck9mZnNldHMnXSxcbiAgZm46IG9mZnNldFxufTsiLCAiaW1wb3J0IGNvbXB1dGVPZmZzZXRzIGZyb20gXCIuLi91dGlscy9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuXG5mdW5jdGlvbiBwb3BwZXJPZmZzZXRzKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIG5hbWUgPSBfcmVmLm5hbWU7XG4gIC8vIE9mZnNldHMgYXJlIHRoZSBhY3R1YWwgcG9zaXRpb24gdGhlIHBvcHBlciBuZWVkcyB0byBoYXZlIHRvIGJlXG4gIC8vIHByb3Blcmx5IHBvc2l0aW9uZWQgbmVhciBpdHMgcmVmZXJlbmNlIGVsZW1lbnRcbiAgLy8gVGhpcyBpcyB0aGUgbW9zdCBiYXNpYyBwbGFjZW1lbnQsIGFuZCB3aWxsIGJlIGFkanVzdGVkIGJ5XG4gIC8vIHRoZSBtb2RpZmllcnMgaW4gdGhlIG5leHQgc3RlcFxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gY29tcHV0ZU9mZnNldHMoe1xuICAgIHJlZmVyZW5jZTogc3RhdGUucmVjdHMucmVmZXJlbmNlLFxuICAgIGVsZW1lbnQ6IHN0YXRlLnJlY3RzLnBvcHBlcixcbiAgICBzdHJhdGVneTogJ2Fic29sdXRlJyxcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ3BvcHBlck9mZnNldHMnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ3JlYWQnLFxuICBmbjogcG9wcGVyT2Zmc2V0cyxcbiAgZGF0YToge31cbn07IiwgImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEFsdEF4aXMoYXhpcykge1xuICByZXR1cm4gYXhpcyA9PT0gJ3gnID8gJ3knIDogJ3gnO1xufSIsICJpbXBvcnQgeyB0b3AsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHN0YXJ0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0QWx0QXhpcyBmcm9tIFwiLi4vdXRpbHMvZ2V0QWx0QXhpcy5qc1wiO1xuaW1wb3J0IHsgd2l0aGluLCB3aXRoaW5NYXhDbGFtcCB9IGZyb20gXCIuLi91dGlscy93aXRoaW4uanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE9mZnNldFBhcmVudC5qc1wiO1xuaW1wb3J0IGRldGVjdE92ZXJmbG93IGZyb20gXCIuLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi4vdXRpbHMvZ2V0VmFyaWF0aW9uLmpzXCI7XG5pbXBvcnQgZ2V0RnJlc2hTaWRlT2JqZWN0IGZyb20gXCIuLi91dGlscy9nZXRGcmVzaFNpZGVPYmplY3QuanNcIjtcbmltcG9ydCB7IG1pbiBhcyBtYXRoTWluLCBtYXggYXMgbWF0aE1heCB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7XG5cbmZ1bmN0aW9uIHByZXZlbnRPdmVyZmxvdyhfcmVmKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZi5vcHRpb25zLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIF9vcHRpb25zJG1haW5BeGlzID0gb3B0aW9ucy5tYWluQXhpcyxcbiAgICAgIGNoZWNrTWFpbkF4aXMgPSBfb3B0aW9ucyRtYWluQXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJG1haW5BeGlzLFxuICAgICAgX29wdGlvbnMkYWx0QXhpcyA9IG9wdGlvbnMuYWx0QXhpcyxcbiAgICAgIGNoZWNrQWx0QXhpcyA9IF9vcHRpb25zJGFsdEF4aXMgPT09IHZvaWQgMCA/IGZhbHNlIDogX29wdGlvbnMkYWx0QXhpcyxcbiAgICAgIGJvdW5kYXJ5ID0gb3B0aW9ucy5ib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeSA9IG9wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgYWx0Qm91bmRhcnkgPSBvcHRpb25zLmFsdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZyA9IG9wdGlvbnMucGFkZGluZyxcbiAgICAgIF9vcHRpb25zJHRldGhlciA9IG9wdGlvbnMudGV0aGVyLFxuICAgICAgdGV0aGVyID0gX29wdGlvbnMkdGV0aGVyID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkdGV0aGVyLFxuICAgICAgX29wdGlvbnMkdGV0aGVyT2Zmc2V0ID0gb3B0aW9ucy50ZXRoZXJPZmZzZXQsXG4gICAgICB0ZXRoZXJPZmZzZXQgPSBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQgPT09IHZvaWQgMCA/IDAgOiBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQ7XG4gIHZhciBvdmVyZmxvdyA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgIHBhZGRpbmc6IHBhZGRpbmcsXG4gICAgYWx0Qm91bmRhcnk6IGFsdEJvdW5kYXJ5XG4gIH0pO1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IGdldEJhc2VQbGFjZW1lbnQoc3RhdGUucGxhY2VtZW50KTtcbiAgdmFyIHZhcmlhdGlvbiA9IGdldFZhcmlhdGlvbihzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgaXNCYXNlUGxhY2VtZW50ID0gIXZhcmlhdGlvbjtcbiAgdmFyIG1haW5BeGlzID0gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KGJhc2VQbGFjZW1lbnQpO1xuICB2YXIgYWx0QXhpcyA9IGdldEFsdEF4aXMobWFpbkF4aXMpO1xuICB2YXIgcG9wcGVyT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cztcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgdGV0aGVyT2Zmc2V0VmFsdWUgPSB0eXBlb2YgdGV0aGVyT2Zmc2V0ID09PSAnZnVuY3Rpb24nID8gdGV0aGVyT2Zmc2V0KE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnJlY3RzLCB7XG4gICAgcGxhY2VtZW50OiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSkpIDogdGV0aGVyT2Zmc2V0O1xuICB2YXIgbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlID0gdHlwZW9mIHRldGhlck9mZnNldFZhbHVlID09PSAnbnVtYmVyJyA/IHtcbiAgICBtYWluQXhpczogdGV0aGVyT2Zmc2V0VmFsdWUsXG4gICAgYWx0QXhpczogdGV0aGVyT2Zmc2V0VmFsdWVcbiAgfSA6IE9iamVjdC5hc3NpZ24oe1xuICAgIG1haW5BeGlzOiAwLFxuICAgIGFsdEF4aXM6IDBcbiAgfSwgdGV0aGVyT2Zmc2V0VmFsdWUpO1xuICB2YXIgb2Zmc2V0TW9kaWZpZXJTdGF0ZSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0ID8gc3RhdGUubW9kaWZpZXJzRGF0YS5vZmZzZXRbc3RhdGUucGxhY2VtZW50XSA6IG51bGw7XG4gIHZhciBkYXRhID0ge1xuICAgIHg6IDAsXG4gICAgeTogMFxuICB9O1xuXG4gIGlmICghcG9wcGVyT2Zmc2V0cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChjaGVja01haW5BeGlzKSB7XG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclN0YXRlJDtcblxuICAgIHZhciBtYWluU2lkZSA9IG1haW5BeGlzID09PSAneScgPyB0b3AgOiBsZWZ0O1xuICAgIHZhciBhbHRTaWRlID0gbWFpbkF4aXMgPT09ICd5JyA/IGJvdHRvbSA6IHJpZ2h0O1xuICAgIHZhciBsZW4gPSBtYWluQXhpcyA9PT0gJ3knID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuICAgIHZhciBvZmZzZXQgPSBwb3BwZXJPZmZzZXRzW21haW5BeGlzXTtcbiAgICB2YXIgbWluID0gb2Zmc2V0ICsgb3ZlcmZsb3dbbWFpblNpZGVdO1xuICAgIHZhciBtYXggPSBvZmZzZXQgLSBvdmVyZmxvd1thbHRTaWRlXTtcbiAgICB2YXIgYWRkaXRpdmUgPSB0ZXRoZXIgPyAtcG9wcGVyUmVjdFtsZW5dIC8gMiA6IDA7XG4gICAgdmFyIG1pbkxlbiA9IHZhcmlhdGlvbiA9PT0gc3RhcnQgPyByZWZlcmVuY2VSZWN0W2xlbl0gOiBwb3BwZXJSZWN0W2xlbl07XG4gICAgdmFyIG1heExlbiA9IHZhcmlhdGlvbiA9PT0gc3RhcnQgPyAtcG9wcGVyUmVjdFtsZW5dIDogLXJlZmVyZW5jZVJlY3RbbGVuXTsgLy8gV2UgbmVlZCB0byBpbmNsdWRlIHRoZSBhcnJvdyBpbiB0aGUgY2FsY3VsYXRpb24gc28gdGhlIGFycm93IGRvZXNuJ3QgZ29cbiAgICAvLyBvdXRzaWRlIHRoZSByZWZlcmVuY2UgYm91bmRzXG5cbiAgICB2YXIgYXJyb3dFbGVtZW50ID0gc3RhdGUuZWxlbWVudHMuYXJyb3c7XG4gICAgdmFyIGFycm93UmVjdCA9IHRldGhlciAmJiBhcnJvd0VsZW1lbnQgPyBnZXRMYXlvdXRSZWN0KGFycm93RWxlbWVudCkgOiB7XG4gICAgICB3aWR0aDogMCxcbiAgICAgIGhlaWdodDogMFxuICAgIH07XG4gICAgdmFyIGFycm93UGFkZGluZ09iamVjdCA9IHN0YXRlLm1vZGlmaWVyc0RhdGFbJ2Fycm93I3BlcnNpc3RlbnQnXSA/IHN0YXRlLm1vZGlmaWVyc0RhdGFbJ2Fycm93I3BlcnNpc3RlbnQnXS5wYWRkaW5nIDogZ2V0RnJlc2hTaWRlT2JqZWN0KCk7XG4gICAgdmFyIGFycm93UGFkZGluZ01pbiA9IGFycm93UGFkZGluZ09iamVjdFttYWluU2lkZV07XG4gICAgdmFyIGFycm93UGFkZGluZ01heCA9IGFycm93UGFkZGluZ09iamVjdFthbHRTaWRlXTsgLy8gSWYgdGhlIHJlZmVyZW5jZSBsZW5ndGggaXMgc21hbGxlciB0aGFuIHRoZSBhcnJvdyBsZW5ndGgsIHdlIGRvbid0IHdhbnRcbiAgICAvLyB0byBpbmNsdWRlIGl0cyBmdWxsIHNpemUgaW4gdGhlIGNhbGN1bGF0aW9uLiBJZiB0aGUgcmVmZXJlbmNlIGlzIHNtYWxsXG4gICAgLy8gYW5kIG5lYXIgdGhlIGVkZ2Ugb2YgYSBib3VuZGFyeSwgdGhlIHBvcHBlciBjYW4gb3ZlcmZsb3cgZXZlbiBpZiB0aGVcbiAgICAvLyByZWZlcmVuY2UgaXMgbm90IG92ZXJmbG93aW5nIGFzIHdlbGwgKGUuZy4gdmlydHVhbCBlbGVtZW50cyB3aXRoIG5vXG4gICAgLy8gd2lkdGggb3IgaGVpZ2h0KVxuXG4gICAgdmFyIGFycm93TGVuID0gd2l0aGluKDAsIHJlZmVyZW5jZVJlY3RbbGVuXSwgYXJyb3dSZWN0W2xlbl0pO1xuICAgIHZhciBtaW5PZmZzZXQgPSBpc0Jhc2VQbGFjZW1lbnQgPyByZWZlcmVuY2VSZWN0W2xlbl0gLyAyIC0gYWRkaXRpdmUgLSBhcnJvd0xlbiAtIGFycm93UGFkZGluZ01pbiAtIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcyA6IG1pbkxlbiAtIGFycm93TGVuIC0gYXJyb3dQYWRkaW5nTWluIC0gbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLm1haW5BeGlzO1xuICAgIHZhciBtYXhPZmZzZXQgPSBpc0Jhc2VQbGFjZW1lbnQgPyAtcmVmZXJlbmNlUmVjdFtsZW5dIC8gMiArIGFkZGl0aXZlICsgYXJyb3dMZW4gKyBhcnJvd1BhZGRpbmdNYXggKyBub3JtYWxpemVkVGV0aGVyT2Zmc2V0VmFsdWUubWFpbkF4aXMgOiBtYXhMZW4gKyBhcnJvd0xlbiArIGFycm93UGFkZGluZ01heCArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcztcbiAgICB2YXIgYXJyb3dPZmZzZXRQYXJlbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdyAmJiBnZXRPZmZzZXRQYXJlbnQoc3RhdGUuZWxlbWVudHMuYXJyb3cpO1xuICAgIHZhciBjbGllbnRPZmZzZXQgPSBhcnJvd09mZnNldFBhcmVudCA/IG1haW5BeGlzID09PSAneScgPyBhcnJvd09mZnNldFBhcmVudC5jbGllbnRUb3AgfHwgMCA6IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudExlZnQgfHwgMCA6IDA7XG4gICAgdmFyIG9mZnNldE1vZGlmaWVyVmFsdWUgPSAoX29mZnNldE1vZGlmaWVyU3RhdGUkID0gb2Zmc2V0TW9kaWZpZXJTdGF0ZSA9PSBudWxsID8gdm9pZCAwIDogb2Zmc2V0TW9kaWZpZXJTdGF0ZVttYWluQXhpc10pICE9IG51bGwgPyBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQgOiAwO1xuICAgIHZhciB0ZXRoZXJNaW4gPSBvZmZzZXQgKyBtaW5PZmZzZXQgLSBvZmZzZXRNb2RpZmllclZhbHVlIC0gY2xpZW50T2Zmc2V0O1xuICAgIHZhciB0ZXRoZXJNYXggPSBvZmZzZXQgKyBtYXhPZmZzZXQgLSBvZmZzZXRNb2RpZmllclZhbHVlO1xuICAgIHZhciBwcmV2ZW50ZWRPZmZzZXQgPSB3aXRoaW4odGV0aGVyID8gbWF0aE1pbihtaW4sIHRldGhlck1pbikgOiBtaW4sIG9mZnNldCwgdGV0aGVyID8gbWF0aE1heChtYXgsIHRldGhlck1heCkgOiBtYXgpO1xuICAgIHBvcHBlck9mZnNldHNbbWFpbkF4aXNdID0gcHJldmVudGVkT2Zmc2V0O1xuICAgIGRhdGFbbWFpbkF4aXNdID0gcHJldmVudGVkT2Zmc2V0IC0gb2Zmc2V0O1xuICB9XG5cbiAgaWYgKGNoZWNrQWx0QXhpcykge1xuICAgIHZhciBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQyO1xuXG4gICAgdmFyIF9tYWluU2lkZSA9IG1haW5BeGlzID09PSAneCcgPyB0b3AgOiBsZWZ0O1xuXG4gICAgdmFyIF9hbHRTaWRlID0gbWFpbkF4aXMgPT09ICd4JyA/IGJvdHRvbSA6IHJpZ2h0O1xuXG4gICAgdmFyIF9vZmZzZXQgPSBwb3BwZXJPZmZzZXRzW2FsdEF4aXNdO1xuXG4gICAgdmFyIF9sZW4gPSBhbHRBeGlzID09PSAneScgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG5cbiAgICB2YXIgX21pbiA9IF9vZmZzZXQgKyBvdmVyZmxvd1tfbWFpblNpZGVdO1xuXG4gICAgdmFyIF9tYXggPSBfb2Zmc2V0IC0gb3ZlcmZsb3dbX2FsdFNpZGVdO1xuXG4gICAgdmFyIGlzT3JpZ2luU2lkZSA9IFt0b3AsIGxlZnRdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgIT09IC0xO1xuXG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclZhbHVlID0gKF9vZmZzZXRNb2RpZmllclN0YXRlJDIgPSBvZmZzZXRNb2RpZmllclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBvZmZzZXRNb2RpZmllclN0YXRlW2FsdEF4aXNdKSAhPSBudWxsID8gX29mZnNldE1vZGlmaWVyU3RhdGUkMiA6IDA7XG5cbiAgICB2YXIgX3RldGhlck1pbiA9IGlzT3JpZ2luU2lkZSA/IF9taW4gOiBfb2Zmc2V0IC0gcmVmZXJlbmNlUmVjdFtfbGVuXSAtIHBvcHBlclJlY3RbX2xlbl0gLSBfb2Zmc2V0TW9kaWZpZXJWYWx1ZSArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5hbHRBeGlzO1xuXG4gICAgdmFyIF90ZXRoZXJNYXggPSBpc09yaWdpblNpZGUgPyBfb2Zmc2V0ICsgcmVmZXJlbmNlUmVjdFtfbGVuXSArIHBvcHBlclJlY3RbX2xlbl0gLSBfb2Zmc2V0TW9kaWZpZXJWYWx1ZSAtIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5hbHRBeGlzIDogX21heDtcblxuICAgIHZhciBfcHJldmVudGVkT2Zmc2V0ID0gdGV0aGVyICYmIGlzT3JpZ2luU2lkZSA/IHdpdGhpbk1heENsYW1wKF90ZXRoZXJNaW4sIF9vZmZzZXQsIF90ZXRoZXJNYXgpIDogd2l0aGluKHRldGhlciA/IF90ZXRoZXJNaW4gOiBfbWluLCBfb2Zmc2V0LCB0ZXRoZXIgPyBfdGV0aGVyTWF4IDogX21heCk7XG5cbiAgICBwb3BwZXJPZmZzZXRzW2FsdEF4aXNdID0gX3ByZXZlbnRlZE9mZnNldDtcbiAgICBkYXRhW2FsdEF4aXNdID0gX3ByZXZlbnRlZE9mZnNldCAtIF9vZmZzZXQ7XG4gIH1cblxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gZGF0YTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ3ByZXZlbnRPdmVyZmxvdycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBwcmV2ZW50T3ZlcmZsb3csXG4gIHJlcXVpcmVzSWZFeGlzdHM6IFsnb2Zmc2V0J11cbn07IiwgImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEhUTUxFbGVtZW50U2Nyb2xsKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBlbGVtZW50LnNjcm9sbExlZnQsXG4gICAgc2Nyb2xsVG9wOiBlbGVtZW50LnNjcm9sbFRvcFxuICB9O1xufSIsICJpbXBvcnQgZ2V0V2luZG93U2Nyb2xsIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0SFRNTEVsZW1lbnRTY3JvbGwgZnJvbSBcIi4vZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE5vZGVTY3JvbGwobm9kZSkge1xuICBpZiAobm9kZSA9PT0gZ2V0V2luZG93KG5vZGUpIHx8ICFpc0hUTUxFbGVtZW50KG5vZGUpKSB7XG4gICAgcmV0dXJuIGdldFdpbmRvd1Njcm9sbChub2RlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZ2V0SFRNTEVsZW1lbnRTY3JvbGwobm9kZSk7XG4gIH1cbn0iLCAiaW1wb3J0IGdldEJvdW5kaW5nQ2xpZW50UmVjdCBmcm9tIFwiLi9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBnZXROb2RlU2Nyb2xsIGZyb20gXCIuL2dldE5vZGVTY3JvbGwuanNcIjtcbmltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi9nZXROb2RlTmFtZS5qc1wiO1xuaW1wb3J0IHsgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBnZXRXaW5kb3dTY3JvbGxCYXJYIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbEJhclguanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgaXNTY3JvbGxQYXJlbnQgZnJvbSBcIi4vaXNTY3JvbGxQYXJlbnQuanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcblxuZnVuY3Rpb24gaXNFbGVtZW50U2NhbGVkKGVsZW1lbnQpIHtcbiAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB2YXIgc2NhbGVYID0gcm91bmQocmVjdC53aWR0aCkgLyBlbGVtZW50Lm9mZnNldFdpZHRoIHx8IDE7XG4gIHZhciBzY2FsZVkgPSByb3VuZChyZWN0LmhlaWdodCkgLyBlbGVtZW50Lm9mZnNldEhlaWdodCB8fCAxO1xuICByZXR1cm4gc2NhbGVYICE9PSAxIHx8IHNjYWxlWSAhPT0gMTtcbn0gLy8gUmV0dXJucyB0aGUgY29tcG9zaXRlIHJlY3Qgb2YgYW4gZWxlbWVudCByZWxhdGl2ZSB0byBpdHMgb2Zmc2V0UGFyZW50LlxuLy8gQ29tcG9zaXRlIG1lYW5zIGl0IHRha2VzIGludG8gYWNjb3VudCB0cmFuc2Zvcm1zIGFzIHdlbGwgYXMgbGF5b3V0LlxuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENvbXBvc2l0ZVJlY3QoZWxlbWVudE9yVmlydHVhbEVsZW1lbnQsIG9mZnNldFBhcmVudCwgaXNGaXhlZCkge1xuICBpZiAoaXNGaXhlZCA9PT0gdm9pZCAwKSB7XG4gICAgaXNGaXhlZCA9IGZhbHNlO1xuICB9XG5cbiAgdmFyIGlzT2Zmc2V0UGFyZW50QW5FbGVtZW50ID0gaXNIVE1MRWxlbWVudChvZmZzZXRQYXJlbnQpO1xuICB2YXIgb2Zmc2V0UGFyZW50SXNTY2FsZWQgPSBpc0hUTUxFbGVtZW50KG9mZnNldFBhcmVudCkgJiYgaXNFbGVtZW50U2NhbGVkKG9mZnNldFBhcmVudCk7XG4gIHZhciBkb2N1bWVudEVsZW1lbnQgPSBnZXREb2N1bWVudEVsZW1lbnQob2Zmc2V0UGFyZW50KTtcbiAgdmFyIHJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudE9yVmlydHVhbEVsZW1lbnQsIG9mZnNldFBhcmVudElzU2NhbGVkLCBpc0ZpeGVkKTtcbiAgdmFyIHNjcm9sbCA9IHtcbiAgICBzY3JvbGxMZWZ0OiAwLFxuICAgIHNjcm9sbFRvcDogMFxuICB9O1xuICB2YXIgb2Zmc2V0cyA9IHtcbiAgICB4OiAwLFxuICAgIHk6IDBcbiAgfTtcblxuICBpZiAoaXNPZmZzZXRQYXJlbnRBbkVsZW1lbnQgfHwgIWlzT2Zmc2V0UGFyZW50QW5FbGVtZW50ICYmICFpc0ZpeGVkKSB7XG4gICAgaWYgKGdldE5vZGVOYW1lKG9mZnNldFBhcmVudCkgIT09ICdib2R5JyB8fCAvLyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzEwNzhcbiAgICBpc1Njcm9sbFBhcmVudChkb2N1bWVudEVsZW1lbnQpKSB7XG4gICAgICBzY3JvbGwgPSBnZXROb2RlU2Nyb2xsKG9mZnNldFBhcmVudCk7XG4gICAgfVxuXG4gICAgaWYgKGlzSFRNTEVsZW1lbnQob2Zmc2V0UGFyZW50KSkge1xuICAgICAgb2Zmc2V0cyA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChvZmZzZXRQYXJlbnQsIHRydWUpO1xuICAgICAgb2Zmc2V0cy54ICs9IG9mZnNldFBhcmVudC5jbGllbnRMZWZ0O1xuICAgICAgb2Zmc2V0cy55ICs9IG9mZnNldFBhcmVudC5jbGllbnRUb3A7XG4gICAgfSBlbHNlIGlmIChkb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgIG9mZnNldHMueCA9IGdldFdpbmRvd1Njcm9sbEJhclgoZG9jdW1lbnRFbGVtZW50KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHg6IHJlY3QubGVmdCArIHNjcm9sbC5zY3JvbGxMZWZ0IC0gb2Zmc2V0cy54LFxuICAgIHk6IHJlY3QudG9wICsgc2Nyb2xsLnNjcm9sbFRvcCAtIG9mZnNldHMueSxcbiAgICB3aWR0aDogcmVjdC53aWR0aCxcbiAgICBoZWlnaHQ6IHJlY3QuaGVpZ2h0XG4gIH07XG59IiwgImltcG9ydCB7IG1vZGlmaWVyUGhhc2VzIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7IC8vIHNvdXJjZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDk4NzUyNTVcblxuZnVuY3Rpb24gb3JkZXIobW9kaWZpZXJzKSB7XG4gIHZhciBtYXAgPSBuZXcgTWFwKCk7XG4gIHZhciB2aXNpdGVkID0gbmV3IFNldCgpO1xuICB2YXIgcmVzdWx0ID0gW107XG4gIG1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgIG1hcC5zZXQobW9kaWZpZXIubmFtZSwgbW9kaWZpZXIpO1xuICB9KTsgLy8gT24gdmlzaXRpbmcgb2JqZWN0LCBjaGVjayBmb3IgaXRzIGRlcGVuZGVuY2llcyBhbmQgdmlzaXQgdGhlbSByZWN1cnNpdmVseVxuXG4gIGZ1bmN0aW9uIHNvcnQobW9kaWZpZXIpIHtcbiAgICB2aXNpdGVkLmFkZChtb2RpZmllci5uYW1lKTtcbiAgICB2YXIgcmVxdWlyZXMgPSBbXS5jb25jYXQobW9kaWZpZXIucmVxdWlyZXMgfHwgW10sIG1vZGlmaWVyLnJlcXVpcmVzSWZFeGlzdHMgfHwgW10pO1xuICAgIHJlcXVpcmVzLmZvckVhY2goZnVuY3Rpb24gKGRlcCkge1xuICAgICAgaWYgKCF2aXNpdGVkLmhhcyhkZXApKSB7XG4gICAgICAgIHZhciBkZXBNb2RpZmllciA9IG1hcC5nZXQoZGVwKTtcblxuICAgICAgICBpZiAoZGVwTW9kaWZpZXIpIHtcbiAgICAgICAgICBzb3J0KGRlcE1vZGlmaWVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJlc3VsdC5wdXNoKG1vZGlmaWVyKTtcbiAgfVxuXG4gIG1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgIGlmICghdmlzaXRlZC5oYXMobW9kaWZpZXIubmFtZSkpIHtcbiAgICAgIC8vIGNoZWNrIGZvciB2aXNpdGVkIG9iamVjdFxuICAgICAgc29ydChtb2RpZmllcik7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gb3JkZXJNb2RpZmllcnMobW9kaWZpZXJzKSB7XG4gIC8vIG9yZGVyIGJhc2VkIG9uIGRlcGVuZGVuY2llc1xuICB2YXIgb3JkZXJlZE1vZGlmaWVycyA9IG9yZGVyKG1vZGlmaWVycyk7IC8vIG9yZGVyIGJhc2VkIG9uIHBoYXNlXG5cbiAgcmV0dXJuIG1vZGlmaWVyUGhhc2VzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwaGFzZSkge1xuICAgIHJldHVybiBhY2MuY29uY2F0KG9yZGVyZWRNb2RpZmllcnMuZmlsdGVyKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgICAgcmV0dXJuIG1vZGlmaWVyLnBoYXNlID09PSBwaGFzZTtcbiAgICB9KSk7XG4gIH0sIFtdKTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVib3VuY2UoZm4pIHtcbiAgdmFyIHBlbmRpbmc7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFwZW5kaW5nKSB7XG4gICAgICBwZW5kaW5nID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcGVuZGluZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXNvbHZlKGZuKCkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwZW5kaW5nO1xuICB9O1xufSIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtZXJnZUJ5TmFtZShtb2RpZmllcnMpIHtcbiAgdmFyIG1lcmdlZCA9IG1vZGlmaWVycy5yZWR1Y2UoZnVuY3Rpb24gKG1lcmdlZCwgY3VycmVudCkge1xuICAgIHZhciBleGlzdGluZyA9IG1lcmdlZFtjdXJyZW50Lm5hbWVdO1xuICAgIG1lcmdlZFtjdXJyZW50Lm5hbWVdID0gZXhpc3RpbmcgPyBPYmplY3QuYXNzaWduKHt9LCBleGlzdGluZywgY3VycmVudCwge1xuICAgICAgb3B0aW9uczogT2JqZWN0LmFzc2lnbih7fSwgZXhpc3Rpbmcub3B0aW9ucywgY3VycmVudC5vcHRpb25zKSxcbiAgICAgIGRhdGE6IE9iamVjdC5hc3NpZ24oe30sIGV4aXN0aW5nLmRhdGEsIGN1cnJlbnQuZGF0YSlcbiAgICB9KSA6IGN1cnJlbnQ7XG4gICAgcmV0dXJuIG1lcmdlZDtcbiAgfSwge30pOyAvLyBJRTExIGRvZXMgbm90IHN1cHBvcnQgT2JqZWN0LnZhbHVlc1xuXG4gIHJldHVybiBPYmplY3Qua2V5cyhtZXJnZWQpLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIG1lcmdlZFtrZXldO1xuICB9KTtcbn0iLCAiaW1wb3J0IGdldENvbXBvc2l0ZVJlY3QgZnJvbSBcIi4vZG9tLXV0aWxzL2dldENvbXBvc2l0ZVJlY3QuanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzXCI7XG5pbXBvcnQgbGlzdFNjcm9sbFBhcmVudHMgZnJvbSBcIi4vZG9tLXV0aWxzL2xpc3RTY3JvbGxQYXJlbnRzLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBvcmRlck1vZGlmaWVycyBmcm9tIFwiLi91dGlscy9vcmRlck1vZGlmaWVycy5qc1wiO1xuaW1wb3J0IGRlYm91bmNlIGZyb20gXCIuL3V0aWxzL2RlYm91bmNlLmpzXCI7XG5pbXBvcnQgbWVyZ2VCeU5hbWUgZnJvbSBcIi4vdXRpbHMvbWVyZ2VCeU5hbWUuanNcIjtcbmltcG9ydCBkZXRlY3RPdmVyZmxvdyBmcm9tIFwiLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IHsgaXNFbGVtZW50IH0gZnJvbSBcIi4vZG9tLXV0aWxzL2luc3RhbmNlT2YuanNcIjtcbnZhciBERUZBVUxUX09QVElPTlMgPSB7XG4gIHBsYWNlbWVudDogJ2JvdHRvbScsXG4gIG1vZGlmaWVyczogW10sXG4gIHN0cmF0ZWd5OiAnYWJzb2x1dGUnXG59O1xuXG5mdW5jdGlvbiBhcmVWYWxpZEVsZW1lbnRzKCkge1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuICFhcmdzLnNvbWUoZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gIShlbGVtZW50ICYmIHR5cGVvZiBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCA9PT0gJ2Z1bmN0aW9uJyk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcG9wcGVyR2VuZXJhdG9yKGdlbmVyYXRvck9wdGlvbnMpIHtcbiAgaWYgKGdlbmVyYXRvck9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIGdlbmVyYXRvck9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfZ2VuZXJhdG9yT3B0aW9ucyA9IGdlbmVyYXRvck9wdGlvbnMsXG4gICAgICBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYgPSBfZ2VuZXJhdG9yT3B0aW9ucy5kZWZhdWx0TW9kaWZpZXJzLFxuICAgICAgZGVmYXVsdE1vZGlmaWVycyA9IF9nZW5lcmF0b3JPcHRpb25zJGRlZiA9PT0gdm9pZCAwID8gW10gOiBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYsXG4gICAgICBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYyID0gX2dlbmVyYXRvck9wdGlvbnMuZGVmYXVsdE9wdGlvbnMsXG4gICAgICBkZWZhdWx0T3B0aW9ucyA9IF9nZW5lcmF0b3JPcHRpb25zJGRlZjIgPT09IHZvaWQgMCA/IERFRkFVTFRfT1BUSU9OUyA6IF9nZW5lcmF0b3JPcHRpb25zJGRlZjI7XG4gIHJldHVybiBmdW5jdGlvbiBjcmVhdGVQb3BwZXIocmVmZXJlbmNlLCBwb3BwZXIsIG9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgICBvcHRpb25zID0gZGVmYXVsdE9wdGlvbnM7XG4gICAgfVxuXG4gICAgdmFyIHN0YXRlID0ge1xuICAgICAgcGxhY2VtZW50OiAnYm90dG9tJyxcbiAgICAgIG9yZGVyZWRNb2RpZmllcnM6IFtdLFxuICAgICAgb3B0aW9uczogT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9PUFRJT05TLCBkZWZhdWx0T3B0aW9ucyksXG4gICAgICBtb2RpZmllcnNEYXRhOiB7fSxcbiAgICAgIGVsZW1lbnRzOiB7XG4gICAgICAgIHJlZmVyZW5jZTogcmVmZXJlbmNlLFxuICAgICAgICBwb3BwZXI6IHBvcHBlclxuICAgICAgfSxcbiAgICAgIGF0dHJpYnV0ZXM6IHt9LFxuICAgICAgc3R5bGVzOiB7fVxuICAgIH07XG4gICAgdmFyIGVmZmVjdENsZWFudXBGbnMgPSBbXTtcbiAgICB2YXIgaXNEZXN0cm95ZWQgPSBmYWxzZTtcbiAgICB2YXIgaW5zdGFuY2UgPSB7XG4gICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICBzZXRPcHRpb25zOiBmdW5jdGlvbiBzZXRPcHRpb25zKHNldE9wdGlvbnNBY3Rpb24pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0eXBlb2Ygc2V0T3B0aW9uc0FjdGlvbiA9PT0gJ2Z1bmN0aW9uJyA/IHNldE9wdGlvbnNBY3Rpb24oc3RhdGUub3B0aW9ucykgOiBzZXRPcHRpb25zQWN0aW9uO1xuICAgICAgICBjbGVhbnVwTW9kaWZpZXJFZmZlY3RzKCk7XG4gICAgICAgIHN0YXRlLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0T3B0aW9ucywgc3RhdGUub3B0aW9ucywgb3B0aW9ucyk7XG4gICAgICAgIHN0YXRlLnNjcm9sbFBhcmVudHMgPSB7XG4gICAgICAgICAgcmVmZXJlbmNlOiBpc0VsZW1lbnQocmVmZXJlbmNlKSA/IGxpc3RTY3JvbGxQYXJlbnRzKHJlZmVyZW5jZSkgOiByZWZlcmVuY2UuY29udGV4dEVsZW1lbnQgPyBsaXN0U2Nyb2xsUGFyZW50cyhyZWZlcmVuY2UuY29udGV4dEVsZW1lbnQpIDogW10sXG4gICAgICAgICAgcG9wcGVyOiBsaXN0U2Nyb2xsUGFyZW50cyhwb3BwZXIpXG4gICAgICAgIH07IC8vIE9yZGVycyB0aGUgbW9kaWZpZXJzIGJhc2VkIG9uIHRoZWlyIGRlcGVuZGVuY2llcyBhbmQgYHBoYXNlYFxuICAgICAgICAvLyBwcm9wZXJ0aWVzXG5cbiAgICAgICAgdmFyIG9yZGVyZWRNb2RpZmllcnMgPSBvcmRlck1vZGlmaWVycyhtZXJnZUJ5TmFtZShbXS5jb25jYXQoZGVmYXVsdE1vZGlmaWVycywgc3RhdGUub3B0aW9ucy5tb2RpZmllcnMpKSk7IC8vIFN0cmlwIG91dCBkaXNhYmxlZCBtb2RpZmllcnNcblxuICAgICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzID0gb3JkZXJlZE1vZGlmaWVycy5maWx0ZXIoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICByZXR1cm4gbS5lbmFibGVkO1xuICAgICAgICB9KTtcbiAgICAgICAgcnVuTW9kaWZpZXJFZmZlY3RzKCk7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZS51cGRhdGUoKTtcbiAgICAgIH0sXG4gICAgICAvLyBTeW5jIHVwZGF0ZSBcdTIwMTMgaXQgd2lsbCBhbHdheXMgYmUgZXhlY3V0ZWQsIGV2ZW4gaWYgbm90IG5lY2Vzc2FyeS4gVGhpc1xuICAgICAgLy8gaXMgdXNlZnVsIGZvciBsb3cgZnJlcXVlbmN5IHVwZGF0ZXMgd2hlcmUgc3luYyBiZWhhdmlvciBzaW1wbGlmaWVzIHRoZVxuICAgICAgLy8gbG9naWMuXG4gICAgICAvLyBGb3IgaGlnaCBmcmVxdWVuY3kgdXBkYXRlcyAoZS5nLiBgcmVzaXplYCBhbmQgYHNjcm9sbGAgZXZlbnRzKSwgYWx3YXlzXG4gICAgICAvLyBwcmVmZXIgdGhlIGFzeW5jIFBvcHBlciN1cGRhdGUgbWV0aG9kXG4gICAgICBmb3JjZVVwZGF0ZTogZnVuY3Rpb24gZm9yY2VVcGRhdGUoKSB7XG4gICAgICAgIGlmIChpc0Rlc3Ryb3llZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBfc3RhdGUkZWxlbWVudHMgPSBzdGF0ZS5lbGVtZW50cyxcbiAgICAgICAgICAgIHJlZmVyZW5jZSA9IF9zdGF0ZSRlbGVtZW50cy5yZWZlcmVuY2UsXG4gICAgICAgICAgICBwb3BwZXIgPSBfc3RhdGUkZWxlbWVudHMucG9wcGVyOyAvLyBEb24ndCBwcm9jZWVkIGlmIGByZWZlcmVuY2VgIG9yIGBwb3BwZXJgIGFyZSBub3QgdmFsaWQgZWxlbWVudHNcbiAgICAgICAgLy8gYW55bW9yZVxuXG4gICAgICAgIGlmICghYXJlVmFsaWRFbGVtZW50cyhyZWZlcmVuY2UsIHBvcHBlcikpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gLy8gU3RvcmUgdGhlIHJlZmVyZW5jZSBhbmQgcG9wcGVyIHJlY3RzIHRvIGJlIHJlYWQgYnkgbW9kaWZpZXJzXG5cblxuICAgICAgICBzdGF0ZS5yZWN0cyA9IHtcbiAgICAgICAgICByZWZlcmVuY2U6IGdldENvbXBvc2l0ZVJlY3QocmVmZXJlbmNlLCBnZXRPZmZzZXRQYXJlbnQocG9wcGVyKSwgc3RhdGUub3B0aW9ucy5zdHJhdGVneSA9PT0gJ2ZpeGVkJyksXG4gICAgICAgICAgcG9wcGVyOiBnZXRMYXlvdXRSZWN0KHBvcHBlcilcbiAgICAgICAgfTsgLy8gTW9kaWZpZXJzIGhhdmUgdGhlIGFiaWxpdHkgdG8gcmVzZXQgdGhlIGN1cnJlbnQgdXBkYXRlIGN5Y2xlLiBUaGVcbiAgICAgICAgLy8gbW9zdCBjb21tb24gdXNlIGNhc2UgZm9yIHRoaXMgaXMgdGhlIGBmbGlwYCBtb2RpZmllciBjaGFuZ2luZyB0aGVcbiAgICAgICAgLy8gcGxhY2VtZW50LCB3aGljaCB0aGVuIG5lZWRzIHRvIHJlLXJ1biBhbGwgdGhlIG1vZGlmaWVycywgYmVjYXVzZSB0aGVcbiAgICAgICAgLy8gbG9naWMgd2FzIHByZXZpb3VzbHkgcmFuIGZvciB0aGUgcHJldmlvdXMgcGxhY2VtZW50IGFuZCBpcyB0aGVyZWZvcmVcbiAgICAgICAgLy8gc3RhbGUvaW5jb3JyZWN0XG5cbiAgICAgICAgc3RhdGUucmVzZXQgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUucGxhY2VtZW50ID0gc3RhdGUub3B0aW9ucy5wbGFjZW1lbnQ7IC8vIE9uIGVhY2ggdXBkYXRlIGN5Y2xlLCB0aGUgYG1vZGlmaWVyc0RhdGFgIHByb3BlcnR5IGZvciBlYWNoIG1vZGlmaWVyXG4gICAgICAgIC8vIGlzIGZpbGxlZCB3aXRoIHRoZSBpbml0aWFsIGRhdGEgc3BlY2lmaWVkIGJ5IHRoZSBtb2RpZmllci4gVGhpcyBtZWFuc1xuICAgICAgICAvLyBpdCBkb2Vzbid0IHBlcnNpc3QgYW5kIGlzIGZyZXNoIG9uIGVhY2ggdXBkYXRlLlxuICAgICAgICAvLyBUbyBlbnN1cmUgcGVyc2lzdGVudCBkYXRhLCB1c2UgYCR7bmFtZX0jcGVyc2lzdGVudGBcblxuICAgICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzLmZvckVhY2goZnVuY3Rpb24gKG1vZGlmaWVyKSB7XG4gICAgICAgICAgcmV0dXJuIHN0YXRlLm1vZGlmaWVyc0RhdGFbbW9kaWZpZXIubmFtZV0gPSBPYmplY3QuYXNzaWduKHt9LCBtb2RpZmllci5kYXRhKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHN0YXRlLm9yZGVyZWRNb2RpZmllcnMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgaWYgKHN0YXRlLnJlc2V0ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBzdGF0ZS5yZXNldCA9IGZhbHNlO1xuICAgICAgICAgICAgaW5kZXggPSAtMTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfc3RhdGUkb3JkZXJlZE1vZGlmaWUgPSBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzW2luZGV4XSxcbiAgICAgICAgICAgICAgZm4gPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUuZm4sXG4gICAgICAgICAgICAgIF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUub3B0aW9ucyxcbiAgICAgICAgICAgICAgX29wdGlvbnMgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUyID09PSB2b2lkIDAgPyB7fSA6IF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIsXG4gICAgICAgICAgICAgIG5hbWUgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUubmFtZTtcblxuICAgICAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHN0YXRlID0gZm4oe1xuICAgICAgICAgICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICAgICAgICAgIG9wdGlvbnM6IF9vcHRpb25zLFxuICAgICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgICBpbnN0YW5jZTogaW5zdGFuY2VcbiAgICAgICAgICAgIH0pIHx8IHN0YXRlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIEFzeW5jIGFuZCBvcHRpbWlzdGljYWxseSBvcHRpbWl6ZWQgdXBkYXRlIFx1MjAxMyBpdCB3aWxsIG5vdCBiZSBleGVjdXRlZCBpZlxuICAgICAgLy8gbm90IG5lY2Vzc2FyeSAoZGVib3VuY2VkIHRvIHJ1biBhdCBtb3N0IG9uY2UtcGVyLXRpY2spXG4gICAgICB1cGRhdGU6IGRlYm91bmNlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgaW5zdGFuY2UuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgICByZXNvbHZlKHN0YXRlKTtcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICAgIGNsZWFudXBNb2RpZmllckVmZmVjdHMoKTtcbiAgICAgICAgaXNEZXN0cm95ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoIWFyZVZhbGlkRWxlbWVudHMocmVmZXJlbmNlLCBwb3BwZXIpKSB7XG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgaW5zdGFuY2Uuc2V0T3B0aW9ucyhvcHRpb25zKS50aGVuKGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgICAgaWYgKCFpc0Rlc3Ryb3llZCAmJiBvcHRpb25zLm9uRmlyc3RVcGRhdGUpIHtcbiAgICAgICAgb3B0aW9ucy5vbkZpcnN0VXBkYXRlKHN0YXRlKTtcbiAgICAgIH1cbiAgICB9KTsgLy8gTW9kaWZpZXJzIGhhdmUgdGhlIGFiaWxpdHkgdG8gZXhlY3V0ZSBhcmJpdHJhcnkgY29kZSBiZWZvcmUgdGhlIGZpcnN0XG4gICAgLy8gdXBkYXRlIGN5Y2xlIHJ1bnMuIFRoZXkgd2lsbCBiZSBleGVjdXRlZCBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgdXBkYXRlXG4gICAgLy8gY3ljbGUuIFRoaXMgaXMgdXNlZnVsIHdoZW4gYSBtb2RpZmllciBhZGRzIHNvbWUgcGVyc2lzdGVudCBkYXRhIHRoYXRcbiAgICAvLyBvdGhlciBtb2RpZmllcnMgbmVlZCB0byB1c2UsIGJ1dCB0aGUgbW9kaWZpZXIgaXMgcnVuIGFmdGVyIHRoZSBkZXBlbmRlbnRcbiAgICAvLyBvbmUuXG5cbiAgICBmdW5jdGlvbiBydW5Nb2RpZmllckVmZmVjdHMoKSB7XG4gICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzLmZvckVhY2goZnVuY3Rpb24gKF9yZWYpIHtcbiAgICAgICAgdmFyIG5hbWUgPSBfcmVmLm5hbWUsXG4gICAgICAgICAgICBfcmVmJG9wdGlvbnMgPSBfcmVmLm9wdGlvbnMsXG4gICAgICAgICAgICBvcHRpb25zID0gX3JlZiRvcHRpb25zID09PSB2b2lkIDAgPyB7fSA6IF9yZWYkb3B0aW9ucyxcbiAgICAgICAgICAgIGVmZmVjdCA9IF9yZWYuZWZmZWN0O1xuXG4gICAgICAgIGlmICh0eXBlb2YgZWZmZWN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdmFyIGNsZWFudXBGbiA9IGVmZmVjdCh7XG4gICAgICAgICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgaW5zdGFuY2U6IGluc3RhbmNlLFxuICAgICAgICAgICAgb3B0aW9uczogb3B0aW9uc1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdmFyIG5vb3BGbiA9IGZ1bmN0aW9uIG5vb3BGbigpIHt9O1xuXG4gICAgICAgICAgZWZmZWN0Q2xlYW51cEZucy5wdXNoKGNsZWFudXBGbiB8fCBub29wRm4pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwTW9kaWZpZXJFZmZlY3RzKCkge1xuICAgICAgZWZmZWN0Q2xlYW51cEZucy5mb3JFYWNoKGZ1bmN0aW9uIChmbikge1xuICAgICAgICByZXR1cm4gZm4oKTtcbiAgICAgIH0pO1xuICAgICAgZWZmZWN0Q2xlYW51cEZucyA9IFtdO1xuICAgIH1cblxuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfTtcbn1cbmV4cG9ydCB2YXIgY3JlYXRlUG9wcGVyID0gLyojX19QVVJFX18qL3BvcHBlckdlbmVyYXRvcigpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbmV4cG9ydCB7IGRldGVjdE92ZXJmbG93IH07IiwgImltcG9ydCB7IHBvcHBlckdlbmVyYXRvciwgZGV0ZWN0T3ZlcmZsb3cgfSBmcm9tIFwiLi9jcmVhdGVQb3BwZXIuanNcIjtcbmltcG9ydCBldmVudExpc3RlbmVycyBmcm9tIFwiLi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanNcIjtcbmltcG9ydCBwb3BwZXJPZmZzZXRzIGZyb20gXCIuL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzXCI7XG5pbXBvcnQgY29tcHV0ZVN0eWxlcyBmcm9tIFwiLi9tb2RpZmllcnMvY29tcHV0ZVN0eWxlcy5qc1wiO1xuaW1wb3J0IGFwcGx5U3R5bGVzIGZyb20gXCIuL21vZGlmaWVycy9hcHBseVN0eWxlcy5qc1wiO1xuaW1wb3J0IG9mZnNldCBmcm9tIFwiLi9tb2RpZmllcnMvb2Zmc2V0LmpzXCI7XG5pbXBvcnQgZmxpcCBmcm9tIFwiLi9tb2RpZmllcnMvZmxpcC5qc1wiO1xuaW1wb3J0IHByZXZlbnRPdmVyZmxvdyBmcm9tIFwiLi9tb2RpZmllcnMvcHJldmVudE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgYXJyb3cgZnJvbSBcIi4vbW9kaWZpZXJzL2Fycm93LmpzXCI7XG5pbXBvcnQgaGlkZSBmcm9tIFwiLi9tb2RpZmllcnMvaGlkZS5qc1wiO1xudmFyIGRlZmF1bHRNb2RpZmllcnMgPSBbZXZlbnRMaXN0ZW5lcnMsIHBvcHBlck9mZnNldHMsIGNvbXB1dGVTdHlsZXMsIGFwcGx5U3R5bGVzLCBvZmZzZXQsIGZsaXAsIHByZXZlbnRPdmVyZmxvdywgYXJyb3csIGhpZGVdO1xudmFyIGNyZWF0ZVBvcHBlciA9IC8qI19fUFVSRV9fKi9wb3BwZXJHZW5lcmF0b3Ioe1xuICBkZWZhdWx0TW9kaWZpZXJzOiBkZWZhdWx0TW9kaWZpZXJzXG59KTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgeyBjcmVhdGVQb3BwZXIsIHBvcHBlckdlbmVyYXRvciwgZGVmYXVsdE1vZGlmaWVycywgZGV0ZWN0T3ZlcmZsb3cgfTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgeyBjcmVhdGVQb3BwZXIgYXMgY3JlYXRlUG9wcGVyTGl0ZSB9IGZyb20gXCIuL3BvcHBlci1saXRlLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0ICogZnJvbSBcIi4vbW9kaWZpZXJzL2luZGV4LmpzXCI7IiwgIi8vIFRoYW5rcyB0byBAbWdtZXllcnMgZm9yIHRoZSBjcmVhdGluZyB0aGUgb2JzaWRpYW4ga2FuYmFuIHBsdWdpbiBodHRwczovL2dpdGh1Yi5jb20vbWdtZXllcnMvb2JzaWRpYW4ta2FuYmFuXHJcbi8vIGZyb20gd2hlcmUgSSBnb3QgdGhlIHRlbXBsYXRlIGNvZGUgZm9yIHRoaXMgcGx1Z2luXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tZ21leWVycy9vYnNpZGlhbi1rYW5iYW4vYmxvYi80OGU2YzI3OGNlOTE0MGI3ZTAzNGIxODE0MzIzMjFmNjk3ZDZlNDVlL3NyYy9jb21wb25lbnRzL2hlbHBlcnMudHNcclxuXHJcbmltcG9ydCB7IFRGaWxlLCBBcHAgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuL21haW4nO1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXBwbHlUZW1wbGF0ZShcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLFxyXG5cdGZpbGU6IFRGaWxlLFxyXG5cdHRlbXBsYXRlUGF0aD86IHN0cmluZ1xyXG4pIHtcclxuXHRjb25zdCB0ZW1wbGF0ZUZpbGUgPSB0ZW1wbGF0ZVBhdGhcclxuXHRcdD8gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgodGVtcGxhdGVQYXRoKVxyXG5cdFx0OiBudWxsO1xyXG5cclxuXHRpZiAodGVtcGxhdGVGaWxlICYmIHRlbXBsYXRlRmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHR0cnkge1xyXG5cclxuXHRcdFx0Y29uc3Qge1xyXG5cdFx0XHRcdHRlbXBsYXRlc0VuYWJsZWQsXHJcblx0XHRcdFx0dGVtcGxhdGVyRW5hYmxlZCxcclxuXHRcdFx0XHR0ZW1wbGF0ZXNQbHVnaW4sXHJcblx0XHRcdFx0dGVtcGxhdGVyUGx1Z2luLFxyXG5cdFx0XHR9ID0gZ2V0VGVtcGxhdGVQbHVnaW5zKHBsdWdpbi5hcHApO1xyXG5cdFx0XHRjb25zdCB0ZW1wbGF0ZUNvbnRlbnQgPSBhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlYWQodGVtcGxhdGVGaWxlKTtcclxuXHJcblx0XHRcdC8vIElmIGJvdGggcGx1Z2lucyBhcmUgZW5hYmxlZCwgYXR0ZW1wdCB0byBkZXRlY3QgdGVtcGxhdGVyIGZpcnN0XHJcblxyXG5cdFx0XHRpZiAodGVtcGxhdGVzRW5hYmxlZCAmJiB0ZW1wbGF0ZXJFbmFibGVkKSB7XHJcblx0XHRcdFx0aWYgKC88JS8udGVzdCh0ZW1wbGF0ZUNvbnRlbnQpKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gYXdhaXQgdGVtcGxhdGVyUGx1Z2luLndyaXRlX3RlbXBsYXRlX3RvX2ZpbGUoXHJcblx0XHRcdFx0XHRcdHRlbXBsYXRlRmlsZSxcclxuXHRcdFx0XHRcdFx0ZmlsZVxyXG5cdFx0XHRcdFx0KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIGF3YWl0IHRlbXBsYXRlc1BsdWdpbi5pbnN0YW5jZS5pbnNlcnRUZW1wbGF0ZSh0ZW1wbGF0ZUZpbGUpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAodGVtcGxhdGVzRW5hYmxlZCkge1xyXG5cdFx0XHRcdHJldHVybiBhd2FpdCB0ZW1wbGF0ZXNQbHVnaW4uaW5zdGFuY2UuaW5zZXJ0VGVtcGxhdGUodGVtcGxhdGVGaWxlKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKHRlbXBsYXRlckVuYWJsZWQpIHtcclxuXHRcdFx0XHRyZXR1cm4gYXdhaXQgdGVtcGxhdGVyUGx1Z2luLndyaXRlX3RlbXBsYXRlX3RvX2ZpbGUoXHJcblx0XHRcdFx0XHR0ZW1wbGF0ZUZpbGUsXHJcblx0XHRcdFx0XHRmaWxlXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdH0gY2F0Y2ggKGUpIHtcclxuXHRcdFx0Y29uc29sZS5lcnJvcihlKTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRUZW1wbGF0ZVBsdWdpbnMoYXBwOiBBcHApIHtcclxuXHRjb25zdCB0ZW1wbGF0ZXNQbHVnaW4gPSAoYXBwIGFzIGFueSkuaW50ZXJuYWxQbHVnaW5zLnBsdWdpbnMudGVtcGxhdGVzO1xyXG5cdGNvbnN0IHRlbXBsYXRlc0VuYWJsZWQgPSB0ZW1wbGF0ZXNQbHVnaW4uZW5hYmxlZDtcclxuXHRjb25zdCB0ZW1wbGF0ZXJQbHVnaW4gPSAoYXBwIGFzIGFueSkucGx1Z2lucy5wbHVnaW5zWyd0ZW1wbGF0ZXItb2JzaWRpYW4nXTtcclxuXHRjb25zdCB0ZW1wbGF0ZXJFbmFibGVkID0gKGFwcCBhcyBhbnkpLnBsdWdpbnMuZW5hYmxlZFBsdWdpbnMuaGFzKFxyXG5cdFx0J3RlbXBsYXRlci1vYnNpZGlhbidcclxuXHQpO1xyXG5cdGNvbnN0IHRlbXBsYXRlckVtcHR5RmlsZVRlbXBsYXRlID1cclxuXHRcdHRlbXBsYXRlclBsdWdpbiAmJlxyXG5cdFx0KHRoaXMuYXBwIGFzIGFueSkucGx1Z2lucy5wbHVnaW5zWyd0ZW1wbGF0ZXItb2JzaWRpYW4nXS5zZXR0aW5nc1xyXG5cdFx0XHQ/LmVtcHR5X2ZpbGVfdGVtcGxhdGU7XHJcblxyXG5cdGNvbnN0IHRlbXBsYXRlRm9sZGVyID0gdGVtcGxhdGVzRW5hYmxlZFxyXG5cdFx0PyB0ZW1wbGF0ZXNQbHVnaW4uaW5zdGFuY2Uub3B0aW9ucy5mb2xkZXJcclxuXHRcdDogdGVtcGxhdGVyUGx1Z2luXHJcblx0XHRcdD8gdGVtcGxhdGVyUGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlX2ZvbGRlclxyXG5cdFx0XHQ6IHVuZGVmaW5lZDtcclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdHRlbXBsYXRlc1BsdWdpbixcclxuXHRcdHRlbXBsYXRlc0VuYWJsZWQsXHJcblx0XHR0ZW1wbGF0ZXJQbHVnaW46IHRlbXBsYXRlclBsdWdpbj8udGVtcGxhdGVyLFxyXG5cdFx0dGVtcGxhdGVyRW5hYmxlZCxcclxuXHRcdHRlbXBsYXRlckVtcHR5RmlsZVRlbXBsYXRlLFxyXG5cdFx0dGVtcGxhdGVGb2xkZXIsXHJcblx0fTtcclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZywgVEZpbGUsIFBsYXRmb3JtLCBURm9sZGVyLCBUQWJzdHJhY3RGaWxlIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCB7IHR1cm5JbnRvRm9sZGVyTm90ZSB9IGZyb20gJ3NyYy9mdW5jdGlvbnMvZm9sZGVyTm90ZUZ1bmN0aW9ucyc7XHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV4aXN0aW5nRm9sZGVyTm90ZU1vZGFsIGV4dGVuZHMgTW9kYWwge1xyXG5cdHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW47XHJcblx0YXBwOiBBcHA7XHJcblx0ZmlsZTogVEZpbGU7XHJcblx0Zm9sZGVyOiBURm9sZGVyO1xyXG5cdGZvbGRlck5vdGU6IFRBYnN0cmFjdEZpbGU7XHJcblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIGZpbGU6IFRGaWxlLCBmb2xkZXI6IFRGb2xkZXIsIGZvbGRlck5vdGU6IFRBYnN0cmFjdEZpbGUpIHtcclxuXHRcdHN1cGVyKGFwcCk7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gYXBwO1xyXG5cdFx0dGhpcy5maWxlID0gZmlsZTtcclxuXHRcdHRoaXMuZm9sZGVyID0gZm9sZGVyO1xyXG5cdFx0dGhpcy5mb2xkZXJOb3RlID0gZm9sZGVyTm90ZTtcclxuXHR9XHJcblx0b25PcGVuKCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnQSBmb2xkZXIgbm90ZSBmb3IgdGhpcyBmb2xkZXIgYWxyZWFkeSBleGlzdHMnIH0pO1xyXG5cdFx0Y29uc3Qgc2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRlbnRFbCk7XHJcblx0XHRzZXR0aW5nLmluZm9FbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byB0dXJuIHRoZSBub3RlIGludG8gYSBmb2xkZXIgbm90ZSBhbmQgcmVuYW1lIHRoZSBleGlzdGluZyBmb2xkZXIgbm90ZT8nIH0pO1xyXG5cclxuXHRcdHNldHRpbmcuaW5mb0VsLnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5hZGQoJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwnKTtcclxuXHJcblx0XHQvLyBDcmVhdGUgYSBjb250YWluZXIgZm9yIHRoZSBidXR0b25zIGFuZCB0aGUgY2hlY2tib3hcclxuXHRcdGNvbnN0IGJ1dHRvbkNvbnRhaW5lciA9IHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdkaXYnLCB7IGNsczogJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9ucycgfSk7XHJcblx0XHRpZiAoUGxhdGZvcm0uaXNNb2JpbGVBcHApIHtcclxuXHRcdFx0Y29uc3QgY29uZmlybUJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnUmVuYW1lIGFuZCBkb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNvbmZpcm1CdXR0b24uY2xhc3NMaXN0LmFkZCgnbW9kLXdhcm5pbmcnLCAnZm4tY29uZmlybWF0aW9uLW1vZGFsLWJ1dHRvbicpO1xyXG5cdFx0XHRjb25maXJtQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dSZW5hbWVDb25maXJtYXRpb24gPSBmYWxzZTtcclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdFx0dHVybkludG9Gb2xkZXJOb3RlKHRoaXMucGx1Z2luLCB0aGlzLmZpbGUsIHRoaXMuZm9sZGVyLCB0aGlzLmZvbGRlck5vdGUsIHRydWUpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGNvbnN0IGNoZWNrYm94ID0gYnV0dG9uQ29udGFpbmVyLmNyZWF0ZUVsKCdpbnB1dCcsIHsgdHlwZTogJ2NoZWNrYm94JyB9KTtcclxuXHRcdFx0Y2hlY2tib3guYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGUpID0+IHtcclxuXHRcdFx0XHRjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG5cdFx0XHRcdGlmICh0YXJnZXQuY2hlY2tlZCkge1xyXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd1JlbmFtZUNvbmZpcm1hdGlvbiA9IGZhbHNlO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93UmVuYW1lQ29uZmlybWF0aW9uID0gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRjb25zdCBjaGVja0JveFRleHQgPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ3NwYW4nLCB7IHRleHQ6ICdEb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNoZWNrQm94VGV4dC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcclxuXHRcdFx0XHRjaGVja2JveC5jbGljaygpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnUmVuYW1lJyB9KTtcclxuXHRcdGJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdtb2Qtd2FybmluZycsICdmbi1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9uJyk7XHJcblx0XHRidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XHJcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdHR1cm5JbnRvRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgdGhpcy5maWxlLCB0aGlzLmZvbGRlciwgdGhpcy5mb2xkZXJOb3RlLCB0cnVlKTtcclxuXHRcdH0pO1xyXG5cdFx0YnV0dG9uLmZvY3VzKCk7XHJcblx0XHRjb25zdCBjYW5jZWxCdXR0b24gPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ2J1dHRvbicsIHsgdGV4dDogJ0NhbmNlbCcgfSk7XHJcblx0XHRjYW5jZWxCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XHJcblx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdH0pO1xyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCBFeGlzdGluZ0ZvbGRlck5vdGVNb2RhbCBmcm9tICcuLi9tb2RhbHMvZXhpc3RpbmdOb3RlJztcclxuaW1wb3J0IHsgYXBwbHlUZW1wbGF0ZSB9IGZyb20gJy4uL3RlbXBsYXRlJztcclxuaW1wb3J0IHsgVEZvbGRlciwgVEZpbGUsIFRBYnN0cmFjdEZpbGUsIEtleW1hcCB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IERlbGV0ZUNvbmZpcm1hdGlvbk1vZGFsIGZyb20gJy4uL21vZGFscy9kZWxldGVDb25maXJtYXRpb24nO1xyXG5pbXBvcnQgeyBhZGRFeGNsdWRlZEZvbGRlciwgZGVsZXRlRXhjbHVkZWRGb2xkZXIsIGdldEV4Y2x1ZGVkRm9sZGVyLCBFeGNsdWRlZEZvbGRlciwgdXBkYXRlRXhjbHVkZWRGb2xkZXIgfSBmcm9tICcuLi9leGNsdWRlZEZvbGRlcic7XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlRm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmb2xkZXJQYXRoOiBzdHJpbmcsIG9wZW5GaWxlOiBib29sZWFuLCB1c2VNb2RhbD86IGJvb2xlYW4sIGV4aXN0aW5nTm90ZT86IFRGaWxlKSB7XHJcblx0Y29uc3QgbGVhZiA9IHBsdWdpbi5hcHAud29ya3NwYWNlLmdldExlYWYoZmFsc2UpO1xyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBwbHVnaW4uZ2V0Rm9sZGVyTmFtZUZyb21QYXRoU3RyaW5nKGZvbGRlclBhdGgpO1xyXG5cdGNvbnN0IGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZvbGRlck5hbWUpO1xyXG5cdGxldCBwYXRoID0gJyc7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRjb25zdCBwYXJlbnRGb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZvbGRlclBhdGgpO1xyXG5cdFx0aWYgKHBhcmVudEZvbGRlclBhdGgudHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRwYXRoID0gYCR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHBhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke2ZpbGVOYW1lfSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIGlmIChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAndmF1bHRGb2xkZXInKSB7XHJcblx0XHRwYXRoID0gYCR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0cGF0aCA9IGAke2ZvbGRlclBhdGh9LyR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHR9XHJcblx0bGV0IGZpbGU6IFRGaWxlO1xyXG5cdGlmICghZXhpc3RpbmdOb3RlKSB7XHJcblx0XHRmaWxlID0gYXdhaXQgcGx1Z2luLmFwcC52YXVsdC5jcmVhdGUocGF0aCwgJycpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRmaWxlID0gZXhpc3RpbmdOb3RlO1xyXG5cdFx0cGx1Z2luLmFwcC52YXVsdC5yZW5hbWUoZXhpc3RpbmdOb3RlLCBwYXRoKTtcclxuXHR9XHJcblx0aWYgKG9wZW5GaWxlKSB7XHJcblx0XHRhd2FpdCBsZWFmLm9wZW5GaWxlKGZpbGUpO1xyXG5cdH1cclxuXHRpZiAoZmlsZSAmJiAhZXhpc3RpbmdOb3RlKSB7XHJcblx0XHRhcHBseVRlbXBsYXRlKHRoaXMsIGZpbGUsIHBsdWdpbi5zZXR0aW5ncy50ZW1wbGF0ZVBhdGgpO1xyXG5cdH1cclxuXHJcblx0Y29uc3QgZm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aCwgJ2lzLWZvbGRlci1ub3RlJywgdHJ1ZSk7XHJcblx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0dXJuSW50b0ZvbGRlck5vdGUocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZmlsZTogVEZpbGUsIGZvbGRlcjogVEZvbGRlciwgZm9sZGVyTm90ZT86IFRGaWxlIHwgbnVsbCB8IFRBYnN0cmFjdEZpbGUsIHNraXBDb25maXJtYXRpb24/OiBib29sZWFuKSB7XHJcblx0aWYgKGZvbGRlck5vdGUpIHtcclxuXHRcdGlmIChwbHVnaW4uc2V0dGluZ3Muc2hvd1JlbmFtZUNvbmZpcm1hdGlvbiAmJiAhc2tpcENvbmZpcm1hdGlvbikge1xyXG5cdFx0XHRyZXR1cm4gbmV3IEV4aXN0aW5nRm9sZGVyTm90ZU1vZGFsKHBsdWdpbi5hcHAsIHBsdWdpbiwgZmlsZSwgZm9sZGVyLCBmb2xkZXJOb3RlKS5vcGVuKCk7XHJcblx0XHR9XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdGxldCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZm9sZGVyLnBhdGgpO1xyXG5cdFx0bGV0IGV4Y2x1ZGVkRm9sZGVyRXhpc3RlZCA9IHRydWU7XHJcblx0XHRsZXQgZGlzYWJsZWRTeW5jID0gZmFsc2U7XHJcblxyXG5cdFx0aWYgKCFleGNsdWRlZEZvbGRlcikge1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlckV4aXN0ZWQgPSBmYWxzZTtcclxuXHRcdFx0ZXhjbHVkZWRGb2xkZXIgPSBuZXcgRXhjbHVkZWRGb2xkZXIoZm9sZGVyLnBhdGgsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0gZWxzZSBpZiAoIWV4Y2x1ZGVkRm9sZGVyLmRpc2FibGVTeW5jKSB7XHJcblx0XHRcdGRpc2FibGVkU3luYyA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHRydWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IG5ld1BhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmb2xkZXIubmFtZX0gKCR7ZmlsZS5zdGF0LmN0aW1lLnRvU3RyaW5nKCkuc2xpY2UoMTApICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMCl9KSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHRwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmb2xkZXJOb3RlLCBuZXdQYXRoKS50aGVuKCgpID0+IHtcclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlckV4aXN0ZWQpIHtcclxuXHRcdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIGlmICghZGlzYWJsZWRTeW5jKSB7XHJcblx0XHRcdFx0ZXhjbHVkZWRGb2xkZXIuZGlzYWJsZVN5bmMgPSBmYWxzZTtcclxuXHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXJOYW1lID0gZm9sZGVyLm5hbWU7XHJcblx0Y29uc3QgZmlsZU5hbWUgPSBwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUucmVwbGFjZSgne3tmb2xkZXJfbmFtZX19JywgZm9sZGVyTmFtZSk7XHJcblx0bGV0IHBhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmaWxlTmFtZX0ke3BsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZX1gO1xyXG5cdGlmIChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAncGFyZW50Rm9sZGVyJykge1xyXG5cdFx0Y29uc3QgcGFyZW50Rm9sZGVyUGF0aCA9IGZvbGRlci5wYXJlbnQ/LnBhdGg7XHJcblx0XHRpZiAoIXBhcmVudEZvbGRlclBhdGgpIHJldHVybjtcclxuXHRcdGlmIChwYXJlbnRGb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0cGF0aCA9IGAke2ZpbGVOYW1lfSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRwYXRoID0gYCR7cGFyZW50Rm9sZGVyUGF0aH0vJHtmaWxlTmFtZX0ke3BsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZX1gO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBwYXRoKTtcclxuXHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aCwgJ2lzLWZvbGRlci1ub3RlJywgdHJ1ZSk7XHJcblx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuRm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBUQWJzdHJhY3RGaWxlLCBldnQ/OiBNb3VzZUV2ZW50KSB7XHJcblx0Y29uc3QgcGF0aCA9IGZpbGUucGF0aDtcclxuXHRpZiAocGx1Z2luLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpPy5wYXRoID09PSBwYXRoKSB7IHJldHVybjsgfVxyXG5cdGNvbnN0IGxlYWYgPSBwbHVnaW4uYXBwLndvcmtzcGFjZS5nZXRMZWFmKEtleW1hcC5pc01vZEV2ZW50KGV2dCkgfHwgcGx1Z2luLnNldHRpbmdzLm9wZW5Jbk5ld1RhYik7XHJcblx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0YXdhaXQgbGVhZi5vcGVuRmlsZShmaWxlKTtcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWxldGVGb2xkZXJOb3RlKHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIGZpbGU6IFRGaWxlKSB7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zaG93RGVsZXRlQ29uZmlybWF0aW9uKSB7XHJcblx0XHRyZXR1cm4gbmV3IERlbGV0ZUNvbmZpcm1hdGlvbk1vZGFsKHBsdWdpbi5hcHAsIHBsdWdpbiwgZmlsZSkub3BlbigpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIocGx1Z2luLCBmaWxlKTtcclxuXHRpZiAoIWZvbGRlcikgcmV0dXJuO1xyXG5cdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChmb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdGF3YWl0IHBsdWdpbi5hcHAudmF1bHQuZGVsZXRlKGZpbGUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEZvbGRlck5hbWUodGVtcGxhdGU6IHN0cmluZywgY2hhbmdlZEZpbGVOYW1lOiBzdHJpbmcpIHtcclxuXHRjb25zdCBbcHJlZml4LCBzdWZmaXhdID0gdGVtcGxhdGUuc3BsaXQoJ3t7Zm9sZGVyX25hbWV9fScpO1xyXG5cdGlmIChwcmVmaXgudHJpbSgpID09PSAnJyAmJiBzdWZmaXgudHJpbSgpID09PSAnJykge1xyXG5cdFx0cmV0dXJuIGNoYW5nZWRGaWxlTmFtZTtcclxuXHR9XHJcblx0aWYgKCFjaGFuZ2VkRmlsZU5hbWUuc3RhcnRzV2l0aChwcmVmaXgpIHx8ICFjaGFuZ2VkRmlsZU5hbWUuZW5kc1dpdGgoc3VmZml4KSkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cdGlmIChjaGFuZ2VkRmlsZU5hbWUuc3RhcnRzV2l0aChwcmVmaXgpICYmIHByZWZpeC50cmltKCkgIT09ICcnKSB7XHJcblx0XHRyZXR1cm4gY2hhbmdlZEZpbGVOYW1lLnNsaWNlKHByZWZpeC5sZW5ndGgpLnJlcGxhY2Uoc3VmZml4LCAnJyk7XHJcblx0fSBlbHNlIGlmIChjaGFuZ2VkRmlsZU5hbWUuZW5kc1dpdGgoc3VmZml4KSAmJiBzdWZmaXgudHJpbSgpICE9PSAnJykge1xyXG5cdFx0cmV0dXJuIGNoYW5nZWRGaWxlTmFtZS5zbGljZSgwLCAtc3VmZml4Lmxlbmd0aCk7XHJcblx0fVxyXG5cdHJldHVybiBudWxsO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmb2xkZXJQYXRoOiBzdHJpbmcsIHN0b3JhZ2VMb2NhdGlvbj86IHN0cmluZywgZmlsZT86IFRGaWxlKSB7XHJcblx0aWYgKCFmb2xkZXJQYXRoKSByZXR1cm4gbnVsbDtcclxuXHRjb25zdCBmb2xkZXIgPSB7XHJcblx0XHRwYXRoOiBmb2xkZXJQYXRoLFxyXG5cdFx0bmFtZTogcGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhmb2xkZXJQYXRoKSxcclxuXHR9O1xyXG5cdGxldCBmaWxlTmFtZSA9IHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZS5yZXBsYWNlKCd7e2ZvbGRlcl9uYW1lfX0nLCBmb2xkZXIubmFtZSk7XHJcblx0aWYgKGZpbGUpIHtcclxuXHRcdGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZpbGUuYmFzZW5hbWUpO1xyXG5cdH1cclxuXHJcblx0aWYgKChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAncGFyZW50Rm9sZGVyJyB8fCBzdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSAmJiBzdG9yYWdlTG9jYXRpb24gIT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRmb2xkZXIucGF0aCA9IHBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmb2xkZXJQYXRoKTtcclxuXHR9XHJcblx0bGV0IHBhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmaWxlTmFtZX1gO1xyXG5cdGlmIChmb2xkZXIucGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRmb2xkZXIucGF0aCA9IGZpbGVOYW1lO1xyXG5cdFx0cGF0aCA9IGAke2ZpbGVOYW1lfWA7XHJcblx0fVxyXG5cdGxldCBmb2xkZXJOb3RlID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGF0aCArIHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZSk7XHJcblx0aWYgKGZvbGRlck5vdGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0cmV0dXJuIGZvbGRlck5vdGU7XHJcblx0fSBlbHNlIHtcclxuXHRcdGlmIChwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGUgPT09ICcuY2FudmFzJykge1xyXG5cdFx0XHRmb2xkZXJOb3RlID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGF0aCArICcubWQnKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvbGRlck5vdGUgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChwYXRoICsgJy5jYW52YXMnKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmb2xkZXJOb3RlO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBURmlsZSwgc3RvcmFnZUxvY2F0aW9uPzogc3RyaW5nKSB7XHJcblx0aWYgKCFmaWxlKSByZXR1cm4gbnVsbDtcclxuXHRjb25zdCBmb2xkZXJOYW1lID0gZXh0cmFjdEZvbGRlck5hbWUocGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBmaWxlLmJhc2VuYW1lKTtcclxuXHRpZiAoIWZvbGRlck5hbWUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCk7XHJcblx0bGV0IGZvbGRlcjogVEZvbGRlciB8IFRBYnN0cmFjdEZpbGUgfCBudWxsID0gbnVsbDtcclxuXHRpZiAoKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInIHx8IHN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpICYmIHN0b3JhZ2VMb2NhdGlvbiAhPT0gJ2luc2lkZUZvbGRlcicpIHtcclxuXHRcdGlmIChmb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0Zm9sZGVyUGF0aCA9IGZvbGRlck5hbWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0vJHtmb2xkZXJOYW1lfWA7XHJcblx0XHR9XHJcblx0XHRmb2xkZXIgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0Zm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0fVxyXG5cdGlmICghZm9sZGVyKSB7IHJldHVybiBudWxsOyB9XHJcblx0cmV0dXJuIGZvbGRlcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlck5vdGVGb2xkZXIocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZm9sZGVyTm90ZTogVEZpbGUgfCBzdHJpbmcsIGZpbGVOYW1lOiBzdHJpbmcpIHtcclxuXHRpZiAoIWZvbGRlck5vdGUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmaWxlUGF0aCA9ICcnO1xyXG5cdGlmICh0eXBlb2YgZm9sZGVyTm90ZSA9PT0gJ3N0cmluZycpIHtcclxuXHRcdGZpbGVQYXRoID0gZm9sZGVyTm90ZTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0ZmlsZU5hbWUgPSBmb2xkZXJOb3RlLmJhc2VuYW1lO1xyXG5cdFx0ZmlsZVBhdGggPSBmb2xkZXJOb3RlLnBhdGg7XHJcblx0fVxyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUsIGZpbGVOYW1lKTtcclxuXHRpZiAoIWZvbGRlck5hbWUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGVQYXRoKTtcclxuXHRpZiAocGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdGlmIChmb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0Zm9sZGVyUGF0aCA9IGZvbGRlck5hbWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0vJHtmb2xkZXJOYW1lfWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIHtcclxuXHRcdGZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZVBhdGgpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXIgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoKTtcclxuXHRpZiAoIWZvbGRlcikgeyByZXR1cm4gbnVsbDsgfVxyXG5cdHJldHVybiBmb2xkZXI7XHJcbn1cclxuIiwgImltcG9ydCB7IEFwcCwgTW9kYWwsIFNldHRpbmcsIFRGaWxlLCBQbGF0Zm9ybSB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBnZXRGb2xkZXIgfSBmcm9tICdzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEZWxldGVDb25maXJtYXRpb25Nb2RhbCBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGZpbGU6IFRGaWxlO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBURmlsZSkge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLmZpbGUgPSBmaWxlO1xyXG5cdH1cclxuXHRvbk9wZW4oKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdEZWxldGUgZm9sZGVyIG5vdGUnIH0pO1xyXG5cdFx0Y29uc3Qgc2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRlbnRFbCk7XHJcblx0XHRzZXR0aW5nLmluZm9FbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogYEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhlIGZvbGRlciBub3RlIFwiJHt0aGlzLmZpbGUubmFtZX1cIiA/YCB9KTtcclxuXHRcdHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdwJywgeyB0ZXh0OiAnSXQgd2lsbCBiZSBtb3ZlZCB0byB5b3VyIHN5c3RlbSB0cmFzaC4nIH0pO1xyXG5cclxuXHRcdHNldHRpbmcuaW5mb0VsLnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5hZGQoJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwnKTtcclxuXHJcblx0XHQvLyBDcmVhdGUgYSBjb250YWluZXIgZm9yIHRoZSBidXR0b25zIGFuZCB0aGUgY2hlY2tib3hcclxuXHRcdGNvbnN0IGJ1dHRvbkNvbnRhaW5lciA9IHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdkaXYnLCB7IGNsczogJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9ucycgfSk7XHJcblx0XHRpZiAoUGxhdGZvcm0uaXNNb2JpbGVBcHApIHtcclxuXHRcdFx0Y29uc3QgY29uZmlybUJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnRGVsZXRlIGFuZCBkb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNvbmZpcm1CdXR0b24uY2xhc3NMaXN0LmFkZCgnbW9kLXdhcm5pbmcnLCAnZm4tY29uZmlybWF0aW9uLW1vZGFsLWJ1dHRvbicpO1xyXG5cdFx0XHRjb25maXJtQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEZWxldGVDb25maXJtYXRpb24gPSBmYWxzZTtcclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdFx0Y29uc3QgZm9sZGVyID0gZ2V0Rm9sZGVyKHRoaXMucGx1Z2luLCB0aGlzLmZpbGUpO1xyXG5cdFx0XHRcdGlmICghZm9sZGVyKSByZXR1cm47XHJcblx0XHRcdFx0dGhpcy5wbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyPy5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0dGhpcy5hcHAudmF1bHQuZGVsZXRlKHRoaXMuZmlsZSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Y29uc3QgY2hlY2tib3ggPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ2lucHV0JywgeyB0eXBlOiAnY2hlY2tib3gnIH0pO1xyXG5cdFx0XHRjaGVja2JveC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZSkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcblx0XHRcdFx0aWYgKHRhcmdldC5jaGVja2VkKSB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93RGVsZXRlQ29uZmlybWF0aW9uID0gZmFsc2U7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEZWxldGVDb25maXJtYXRpb24gPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0fSk7XHJcblx0XHRcdGNvbnN0IGNoZWNrQm94VGV4dCA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnc3BhbicsIHsgdGV4dDogJ0RvblxcJ3QgYXNrIGFnYWluJyB9KTtcclxuXHRcdFx0Y2hlY2tCb3hUZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xyXG5cdFx0XHRcdGNoZWNrYm94LmNsaWNrKCk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgYnV0dG9uID0gYnV0dG9uQ29udGFpbmVyLmNyZWF0ZUVsKCdidXR0b24nLCB7IHRleHQ6ICdEZWxldGUnIH0pO1xyXG5cdFx0YnV0dG9uLmNsYXNzTGlzdC5hZGQoJ21vZC13YXJuaW5nJywgJ2ZuLWNvbmZpcm1hdGlvbi1tb2RhbC1idXR0b24nKTtcclxuXHRcdGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIodGhpcy5wbHVnaW4sIHRoaXMuZmlsZSk7XHJcblx0XHRcdGlmICghZm9sZGVyKSByZXR1cm47XHJcblx0XHRcdHRoaXMucGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHRoaXMuYXBwLnZhdWx0LmRlbGV0ZSh0aGlzLmZpbGUpO1xyXG5cdFx0fSk7XHJcblx0XHRidXR0b24uZm9jdXMoKTtcclxuXHRcdGNvbnN0IGNhbmNlbEJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnQ2FuY2VsJyB9KTtcclxuXHRcdGNhbmNlbEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0fSk7XHJcblxyXG5cdH1cclxuXHRvbkNsb3NlKCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcclxuXHR9XHJcbn1cclxuIiwgImltcG9ydCB7IFNldHRpbmcgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuL21haW4nO1xyXG5pbXBvcnQgRXhjbHVkZWRGb2xkZXJTZXR0aW5ncyBmcm9tICcuL21vZGFscy9leGNsdWRlRm9sZGVyU2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBGb2xkZXJTdWdnZXN0IH0gZnJvbSAnLi9zdWdnZXN0ZXJzL0ZvbGRlclN1Z2dlc3Rlcic7XHJcbmltcG9ydCB7IFNldHRpbmdzVGFiIH0gZnJvbSAnLi9zZXR0aW5ncyc7XHJcbmltcG9ydCBQYXR0ZXJuU2V0dGluZ3MgZnJvbSAnLi9tb2RhbHMvcGF0dGVyblNldHRpbmdzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFeGNsdWRlZEZvbGRlciB7XHJcblx0dHlwZTogc3RyaW5nO1xyXG5cdHBhdGg6IHN0cmluZztcclxuXHRzdHJpbmc6IHN0cmluZztcclxuXHRzdWJGb2xkZXJzOiBib29sZWFuO1xyXG5cdGRpc2FibGVTeW5jOiBib29sZWFuO1xyXG5cdGRpc2FibGVBdXRvQ3JlYXRlOiBib29sZWFuO1xyXG5cdGRpc2FibGVGb2xkZXJOb3RlOiBib29sZWFuO1xyXG5cdGVuYWJsZUNvbGxhcHNpbmc6IGJvb2xlYW47XHJcblx0cG9zaXRpb246IG51bWJlcjtcclxuXHRjb25zdHJ1Y3RvcihwYXRoOiBzdHJpbmcsIHBvc2l0aW9uOiBudW1iZXIpIHtcclxuXHRcdHRoaXMudHlwZSA9ICdmb2xkZXInO1xyXG5cdFx0dGhpcy5wYXRoID0gcGF0aDtcclxuXHRcdHRoaXMuc3ViRm9sZGVycyA9IHRydWU7XHJcblx0XHR0aGlzLmRpc2FibGVTeW5jID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGlzYWJsZUF1dG9DcmVhdGUgPSB0cnVlO1xyXG5cdFx0dGhpcy5kaXNhYmxlRm9sZGVyTm90ZSA9IGZhbHNlO1xyXG5cdFx0dGhpcy5lbmFibGVDb2xsYXBzaW5nID0gZmFsc2U7XHJcblx0XHR0aGlzLnBvc2l0aW9uID0gcG9zaXRpb247XHJcblx0XHR0aGlzLnN0cmluZyA9ICcnO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEV4Y2x1ZGVQYXR0ZXJuIHtcclxuXHR0eXBlOiBzdHJpbmc7XHJcblx0c3RyaW5nOiBzdHJpbmc7XHJcblx0cGF0aDogc3RyaW5nO1xyXG5cdHBvc2l0aW9uOiBudW1iZXI7XHJcblx0c3ViRm9sZGVyczogYm9vbGVhbjtcclxuXHRkaXNhYmxlU3luYzogYm9vbGVhbjtcclxuXHRkaXNhYmxlQXV0b0NyZWF0ZTogYm9vbGVhbjtcclxuXHRkaXNhYmxlRm9sZGVyTm90ZTogYm9vbGVhbjtcclxuXHRlbmFibGVDb2xsYXBzaW5nOiBib29sZWFuO1xyXG5cdGNvbnN0cnVjdG9yKHBhdHRlcm46IHN0cmluZywgcG9zaXRpb246IG51bWJlcikge1xyXG5cdFx0dGhpcy50eXBlID0gJ3BhdHRlcm4nO1xyXG5cdFx0dGhpcy5zdHJpbmcgPSBwYXR0ZXJuO1xyXG5cdFx0dGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xyXG5cdFx0dGhpcy5zdWJGb2xkZXJzID0gZmFsc2U7XHJcblx0XHR0aGlzLmRpc2FibGVTeW5jID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGlzYWJsZUF1dG9DcmVhdGUgPSB0cnVlO1xyXG5cdFx0dGhpcy5kaXNhYmxlRm9sZGVyTm90ZSA9IGZhbHNlO1xyXG5cdFx0dGhpcy5lbmFibGVDb2xsYXBzaW5nID0gZmFsc2U7XHJcblx0XHR0aGlzLnBhdGggPSAnJztcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBwYXRoOiBzdHJpbmcpIHtcclxuXHRjb25zdCBmb2xkZXJOYW1lID0gcGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhwYXRoKTtcclxuXHRjb25zdCBtYXRjaGVkUGF0dGVybiA9IGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXR0ZXJuKHBsdWdpbiwgZm9sZGVyTmFtZSk7XHJcblx0aWYgKG1hdGNoZWRQYXR0ZXJuKSB7IHJldHVybiBtYXRjaGVkUGF0dGVybjsgfVxyXG5cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXRoKHBsdWdpbiwgcGF0aCk7XHJcblx0cmV0dXJuIGV4Y2x1ZGVkRm9sZGVyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXhjbHVkZWRGb2xkZXJCeVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZm9sZGVyTmFtZTogc3RyaW5nKSB7XHJcblx0cmV0dXJuIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maWx0ZXIoKHMpID0+IHMucGF0aCA9PT0gJycpLmZpbmQoKHBhdHRlcm4pID0+IHtcclxuXHRcdGlmICghcGF0dGVybi5zdHJpbmcpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRpZiAocGF0dGVybi5zdHJpbmcudG9Mb2NhbGVMb3dlckNhc2UoKS5zdGFydHNXaXRoKCd7cmVnZXh9JykgJiYgcGF0dGVybi5zdHJpbmcuc2xpY2UoNykudHJpbSgpICE9PSAnJykge1xyXG5cdFx0XHRjb25zdCBtYXRjaCA9IG5ldyBSZWdFeHAocGF0dGVybi5zdHJpbmcuc2xpY2UoNykudHJpbSgpKS5leGVjKGZvbGRlck5hbWUpO1xyXG5cdFx0XHRpZiAobWF0Y2gpIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIGlmIChwYXR0ZXJuLnN0cmluZy5zdGFydHNXaXRoKCcqJykgJiYgcGF0dGVybi5zdHJpbmcuZW5kc1dpdGgoJyonKSkge1xyXG5cdFx0XHRpZiAoZm9sZGVyTmFtZS5pbmNsdWRlcyhwYXR0ZXJuLnN0cmluZy5zbGljZSgxLCAtMSkpKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSBpZiAocGF0dGVybi5zdHJpbmcuc3RhcnRzV2l0aCgnKicpKSB7XHJcblx0XHRcdGlmIChmb2xkZXJOYW1lLmVuZHNXaXRoKHBhdHRlcm4uc3RyaW5nLnNsaWNlKDEpKSkge1xyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHBhdHRlcm4uc3RyaW5nLmVuZHNXaXRoKCcqJykpIHtcclxuXHRcdFx0aWYgKGZvbGRlck5hbWUuc3RhcnRzV2l0aChwYXR0ZXJuLnN0cmluZy5zbGljZSgwLCAtMSkpKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXRoKHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIHBhdGg6IHN0cmluZykge1xyXG5cdHJldHVybiBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZXhjbHVkZWRGb2xkZXIpID0+IHtcclxuXHRcdGlmIChleGNsdWRlZEZvbGRlci5wYXRoID09PSBwYXRoKSB7IHJldHVybiB0cnVlOyB9XHJcblx0XHRpZiAoIWV4Y2x1ZGVkRm9sZGVyLnN1YkZvbGRlcnMpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRyZXR1cm4gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGgpLnN0YXJ0c1dpdGgoZXhjbHVkZWRGb2xkZXIucGF0aCk7XHJcblx0fSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMucHVzaChleGNsdWRlZEZvbGRlcik7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZXhjbHVkZWRGb2xkZXI6IEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIucGF0aCAhPT0gZXhjbHVkZWRGb2xkZXIucGF0aCB8fCBmb2xkZXIudHlwZSA9PT0gJ3BhdHRlcm4nKTtcclxuXHRwbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0cmVzeW5jQXJyYXkocGx1Z2luKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgcGF0dGVybjogRXhjbHVkZVBhdHRlcm4pIHtcclxuXHRwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmlsdGVyKChmb2xkZXIpID0+IGZvbGRlci5zdHJpbmcgIT09IHBhdHRlcm4uc3RyaW5nIHx8IGZvbGRlci50eXBlID09PSAnZm9sZGVyJyk7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdHJlc3luY0FycmF5KHBsdWdpbik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZVBhdHRlcm4sIG5ld0V4Y2x1ZGVGb2xkZXI6IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIucGF0aCAhPT0gZXhjbHVkZWRGb2xkZXIucGF0aCk7XHJcblx0YWRkRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBuZXdFeGNsdWRlRm9sZGVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgcGF0dGVybjogRXhjbHVkZVBhdHRlcm4sIG5ld1BhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIuc3RyaW5nICE9PSBwYXR0ZXJuLnN0cmluZyk7XHJcblx0YWRkRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBuZXdQYXR0ZXJuKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVzeW5jQXJyYXkocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycyA9IHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5zb3J0KChhLCBiKSA9PiBhLnBvc2l0aW9uIC0gYi5wb3NpdGlvbik7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZvckVhY2goKGZvbGRlciwgaW5kZXgpID0+IHtcclxuXHRcdGZvbGRlci5wb3NpdGlvbiA9IGluZGV4O1xyXG5cdH0pO1xyXG5cdHBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGFkZEV4Y2x1ZGVQYXR0ZXJuTGlzdEl0ZW0oc2V0dGluZ3M6IFNldHRpbmdzVGFiLCBjb250YWluZXJFbDogSFRNTEVsZW1lbnQsIHBhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0Y29uc3QgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiA9IHNldHRpbmdzLnBsdWdpbjtcclxuXHRjb25zdCBzZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpO1xyXG5cdHNldHRpbmcuc2V0Q2xhc3MoJ2ZuLWV4Y2x1ZGUtZm9sZGVyLWxpc3QnKTtcclxuXHRzZXR0aW5nLmFkZFNlYXJjaCgoY2IpID0+IHtcclxuXHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKCdmbi1leGNsdWRlLWZvbGRlci1wYXRoJyk7XHJcblx0XHRjYi5zZXRQbGFjZWhvbGRlcignUGF0dGVybicpO1xyXG5cdFx0Y2Iuc2V0VmFsdWUocGF0dGVybi5zdHJpbmcpO1xyXG5cdFx0Y2Iub25DaGFuZ2UoKHZhbHVlKSA9PiB7XHJcblx0XHRcdGlmIChwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIuc3RyaW5nID09PSB2YWx1ZSkpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHBhdHRlcm4uc3RyaW5nID0gdmFsdWU7XHJcblx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBwYXR0ZXJuLCBwYXR0ZXJuKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdHNldHRpbmcuYWRkQnV0dG9uKChjYikgPT4ge1xyXG5cdFx0Y2Iuc2V0SWNvbignZWRpdCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnRWRpdCBwYXR0ZXJuJyk7XHJcblx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0bmV3IFBhdHRlcm5TZXR0aW5ncyhwbHVnaW4uYXBwLCBwbHVnaW4sIHBhdHRlcm4pLm9wZW4oKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3VwLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgdXAnKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRpZiAocGF0dGVybi5wb3NpdGlvbiA9PT0gMCkgeyByZXR1cm47IH1cclxuXHRcdFx0cGF0dGVybi5wb3NpdGlvbiAtPSAxO1xyXG5cdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgcGF0dGVybiwgcGF0dGVybik7XHJcblx0XHRcdGNvbnN0IG9sZFBhdHRlcm4gPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IHBhdHRlcm4ucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkUGF0dGVybikge1xyXG5cdFx0XHRcdG9sZFBhdHRlcm4ucG9zaXRpb24gKz0gMTtcclxuXHRcdFx0XHRpZiAob2xkUGF0dGVybi50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0c2V0dGluZ3MuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblx0c2V0dGluZy5hZGRCdXR0b24oKGNiKSA9PiB7XHJcblx0XHRjYi5zZXRJY29uKCdkb3duLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgZG93bicpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdGlmIChwYXR0ZXJuLnBvc2l0aW9uID09PSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRwYXR0ZXJuLnBvc2l0aW9uICs9IDE7XHJcblxyXG5cdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgcGF0dGVybiwgcGF0dGVybik7XHJcblx0XHRcdGNvbnN0IG9sZFBhdHRlcm4gPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IHBhdHRlcm4ucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkUGF0dGVybikge1xyXG5cdFx0XHRcdG9sZFBhdHRlcm4ucG9zaXRpb24gLT0gMTtcclxuXHRcdFx0XHRpZiAob2xkUGF0dGVybi50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0c2V0dGluZ3MuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblx0c2V0dGluZy5hZGRCdXR0b24oKGNiKSA9PiB7XHJcblx0XHRjYi5zZXRJY29uKCd0cmFzaC0yJyk7XHJcblx0XHRjYi5zZXRUb29sdGlwKCdEZWxldGUgcGF0dGVybicpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdGRlbGV0ZVBhdHRlcm4ocGx1Z2luLCBwYXR0ZXJuKTtcclxuXHRcdFx0c2V0dGluZy5jbGVhcigpO1xyXG5cdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gYWRkRXhjbHVkZUZvbGRlckxpc3RJdGVtKHNldHRpbmdzOiBTZXR0aW5nc1RhYiwgY29udGFpbmVyRWw6IEhUTUxFbGVtZW50LCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRjb25zdCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luID0gc2V0dGluZ3MucGx1Z2luO1xyXG5cdGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCk7XHJcblx0c2V0dGluZy5zZXRDbGFzcygnZm4tZXhjbHVkZS1mb2xkZXItbGlzdCcpO1xyXG5cdHNldHRpbmcuYWRkU2VhcmNoKChjYikgPT4ge1xyXG5cdFx0bmV3IEZvbGRlclN1Z2dlc3QoXHJcblx0XHRcdGNiLmlucHV0RWwsXHJcblx0XHRcdHBsdWdpblxyXG5cdFx0KTtcclxuXHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKCdmbi1leGNsdWRlLWZvbGRlci1wYXRoJyk7XHJcblx0XHRjYi5zZXRQbGFjZWhvbGRlcignRm9sZGVyIHBhdGgnKTtcclxuXHRcdGNiLnNldFZhbHVlKGV4Y2x1ZGVkRm9sZGVyLnBhdGgpO1xyXG5cdFx0Y2Iub25DaGFuZ2UoKHZhbHVlKSA9PiB7XHJcblx0XHRcdGlmICh2YWx1ZS5zdGFydHNXaXRoKCd7cmVnZXh9JykgfHwgdmFsdWUuaW5jbHVkZXMoJyonKSkge1xyXG5cdFx0XHRcdGRlbGV0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdGNvbnN0IHBhdHRlcm4gPSBuZXcgRXhjbHVkZVBhdHRlcm4odmFsdWUsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRcdGFkZEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgcGF0dGVybik7XHJcblx0XHRcdFx0YWRkRXhjbHVkZVBhdHRlcm5MaXN0SXRlbShzZXR0aW5ncywgY29udGFpbmVyRWwsIHBhdHRlcm4pO1xyXG5cdFx0XHRcdHNldHRpbmcuY2xlYXIoKTtcclxuXHRcdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoIXBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHZhbHVlKSkgcmV0dXJuO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gdmFsdWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdHNldHRpbmcuYWRkQnV0dG9uKChjYikgPT4ge1xyXG5cdFx0Y2Iuc2V0SWNvbignZWRpdCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnRWRpdCBmb2xkZXIgbm90ZScpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdG5ldyBFeGNsdWRlZEZvbGRlclNldHRpbmdzKHBsdWdpbi5hcHAsIHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpLm9wZW4oKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3VwLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgdXAnKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRpZiAoZXhjbHVkZWRGb2xkZXIucG9zaXRpb24gPT09IDApIHsgcmV0dXJuOyB9XHJcblx0XHRcdGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uIC09IDE7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0Y29uc3Qgb2xkRXhjbHVkZWRGb2xkZXIgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uKTtcclxuXHRcdFx0aWYgKG9sZEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRcdFx0b2xkRXhjbHVkZWRGb2xkZXIucG9zaXRpb24gKz0gMTtcclxuXHRcdFx0XHRpZiAob2xkRXhjbHVkZWRGb2xkZXIudHlwZSA9PT0gJ3BhdHRlcm4nKSB7XHJcblx0XHRcdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgb2xkRXhjbHVkZWRGb2xkZXIsIG9sZEV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRFeGNsdWRlZEZvbGRlciwgb2xkRXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRzZXR0aW5ncy5kaXNwbGF5KCk7XHJcblx0XHR9KTtcclxuXHR9KTtcclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ2Rvd24tY2hldnJvbi1nbHlwaCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnTW92ZSBkb3duJyk7XHJcblx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uID09PSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wb3NpdGlvbiArPSAxO1xyXG5cclxuXHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBleGNsdWRlZEZvbGRlciwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRjb25zdCBvbGRFeGNsdWRlZEZvbGRlciA9IHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maW5kKChmb2xkZXIpID0+IGZvbGRlci5wb3NpdGlvbiA9PT0gZXhjbHVkZWRGb2xkZXIucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRcdFx0XHRvbGRFeGNsdWRlZEZvbGRlci5wb3NpdGlvbiAtPSAxO1xyXG5cdFx0XHRcdGlmIChvbGRFeGNsdWRlZEZvbGRlci50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRFeGNsdWRlZEZvbGRlciwgb2xkRXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIG9sZEV4Y2x1ZGVkRm9sZGVyLCBvbGRFeGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRzZXR0aW5ncy5kaXNwbGF5KCk7XHJcblx0XHR9KTtcclxuXHR9KTtcclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3RyYXNoLTInKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ0RlbGV0ZSBleGNsdWRlZCBmb2xkZXInKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0c2V0dGluZy5jbGVhcigpO1xyXG5cdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG59XHJcbiIsICJpbXBvcnQgeyBBcHAsIE1vZGFsLCBTZXR0aW5nIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCB7IEV4Y2x1ZGVkRm9sZGVyIH0gZnJvbSAnc3JjL2V4Y2x1ZGVkRm9sZGVyJztcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXhjbHVkZWRGb2xkZXJTZXR0aW5ncyBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGV4Y2x1ZGVkRm9sZGVyOiBFeGNsdWRlZEZvbGRlcjtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZXhjbHVkZWRGb2xkZXI6IEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRzdXBlcihhcHApO1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0XHR0aGlzLmFwcCA9IGFwcDtcclxuXHRcdHRoaXMuZXhjbHVkZWRGb2xkZXIgPSBleGNsdWRlZEZvbGRlcjtcclxuXHR9XHJcblx0b25PcGVuKCkge1xyXG5cdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0fVxyXG5cdGRpc3BsYXkoKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xyXG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0V4Y2x1ZGVkIGZvbGRlciBzZXR0aW5ncycgfSk7XHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdJbmNsdWRlIHN1YmZvbGRlcnMnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBzdWJmb2xkZXJzIG9mIHRoZSBmb2xkZXIgc2hvdWxkIGFsc28gYmUgZXhjbHVkZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5zdWJGb2xkZXJzKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLmV4Y2x1ZGVkRm9sZGVyLnN1YkZvbGRlcnMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0Rpc2FibGUgZm9sZGVyIG5hbWUgc3luYycpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBub3RlIHNob3VsZCBiZSByZW5hbWVkIHdoZW4gdGhlIGZvbGRlciBuYW1lIGlzIGNoYW5nZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBhdXRvIGNyZWF0aW9uIG9mIGZvbGRlciBub3RlcyBpbiB0aGlzIGZvbGRlcicpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgYSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgY3JlYXRlZCB3aGVuIGEgbmV3IGZvbGRlciBpcyBjcmVhdGVkJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMuZXhjbHVkZWRGb2xkZXIuZGlzYWJsZUF1dG9DcmVhdGUpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMuZXhjbHVkZWRGb2xkZXIuZGlzYWJsZUF1dG9DcmVhdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIG9wZW4gZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgb3BlbmVkIHdoZW4gdGhlIGZvbGRlciBpcyBvcGVuZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSlcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdGlmICghdGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0NvbGxhcHNlIGZvbGRlciB3aGVuIG9wZW5pbmcgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBzaG91bGQgYmUgY29sbGFwc2VkIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIG9wZW5lZCcpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLmV4Y2x1ZGVkRm9sZGVyLmVuYWJsZUNvbGxhcHNpbmcpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmV4Y2x1ZGVkRm9sZGVyLmVuYWJsZUNvbGxhcHNpbmcgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fSlcclxuXHRcdFx0XHQpO1xyXG5cdFx0fVxyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG59XHJcbiIsICIvLyBDcmVkaXRzIGdvIHRvIExpYW0ncyBQZXJpb2RpYyBOb3RlcyBQbHVnaW46IGh0dHBzOi8vZ2l0aHViLmNvbS9saWFtY2Fpbi9vYnNpZGlhbi1wZXJpb2RpYy1ub3RlcyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL1NpbGVudFZvaWQxMy9UZW1wbGF0ZXJcclxuXHJcbmltcG9ydCB7IFRBYnN0cmFjdEZpbGUsIFRGb2xkZXIgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IFRleHRJbnB1dFN1Z2dlc3QgfSBmcm9tICcuL3N1Z2dlc3QnO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmV4cG9ydCBlbnVtIEZpbGVTdWdnZXN0TW9kZSB7XHJcbiAgICBUZW1wbGF0ZUZpbGVzLFxyXG4gICAgU2NyaXB0RmlsZXMsXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBGb2xkZXJTdWdnZXN0IGV4dGVuZHMgVGV4dElucHV0U3VnZ2VzdDxURm9sZGVyPiB7XHJcblx0Y29uc3RydWN0b3IoXHJcbiAgICAgICAgcHVibGljIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQsXHJcbiAgICAgICAgcHJpdmF0ZSBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luXHJcblx0KSB7XHJcblx0XHRzdXBlcihpbnB1dEVsKTtcclxuXHR9XHJcblxyXG5cclxuXHRnZXRfZXJyb3JfbXNnKG1vZGU6IEZpbGVTdWdnZXN0TW9kZSk6IHN0cmluZyB7XHJcblx0XHRzd2l0Y2ggKG1vZGUpIHtcclxuXHRcdFx0Y2FzZSBGaWxlU3VnZ2VzdE1vZGUuVGVtcGxhdGVGaWxlczpcclxuXHRcdFx0XHRyZXR1cm4gJ1RlbXBsYXRlcyBmb2xkZXIgZG9lc25cXCd0IGV4aXN0JztcclxuXHRcdFx0Y2FzZSBGaWxlU3VnZ2VzdE1vZGUuU2NyaXB0RmlsZXM6XHJcblx0XHRcdFx0cmV0dXJuICdVc2VyIFNjcmlwdHMgZm9sZGVyIGRvZXNuXFwndCBleGlzdCc7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRnZXRTdWdnZXN0aW9ucyhpbnB1dF9zdHI6IHN0cmluZyk6IFRGb2xkZXJbXSB7XHJcblx0XHRjb25zdCBmb2xkZXJzOiBURm9sZGVyW10gPSBbXTtcclxuXHRcdGNvbnN0IGxvd2VyX2lucHV0X3N0ciA9IGlucHV0X3N0ci50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFsbExvYWRlZEZpbGVzKCkuZm9yRWFjaCgoZm9sZGVyOiBUQWJzdHJhY3RGaWxlKSA9PiB7XHJcblx0XHRcdGlmIChcclxuXHRcdFx0XHRmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyICYmXHJcbiAgICAgICAgICAgICAgICBmb2xkZXIucGF0aC50b0xvd2VyQ2FzZSgpLmNvbnRhaW5zKGxvd2VyX2lucHV0X3N0cikgJiZcclxuICAgICAgICAgICAgICAgICF0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maW5kKChmKSA9PiBmLnBhdGggPT09IGZvbGRlci5wYXRoKVxyXG5cdFx0XHQpIHtcclxuXHRcdFx0XHRmb2xkZXJzLnB1c2goZm9sZGVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0cmV0dXJuIGZvbGRlcnM7XHJcblx0fVxyXG5cclxuXHRyZW5kZXJTdWdnZXN0aW9uKGZvbGRlcjogVEZvbGRlciwgZWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XHJcblx0XHRlbC5zZXRUZXh0KGZvbGRlci5wYXRoKTtcclxuXHR9XHJcblxyXG5cdHNlbGVjdFN1Z2dlc3Rpb24oZm9sZGVyOiBURm9sZGVyKTogdm9pZCB7XHJcblx0XHR0aGlzLmlucHV0RWwudmFsdWUgPSBmb2xkZXIucGF0aDtcclxuXHRcdHRoaXMuaW5wdXRFbC50cmlnZ2VyKCdpbnB1dCcpO1xyXG5cdFx0dGhpcy5jbG9zZSgpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZyB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBFeGNsdWRlUGF0dGVybiB9IGZyb20gJ3NyYy9leGNsdWRlZEZvbGRlcic7XHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhdHRlcm5TZXR0aW5ncyBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdHBhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBwYXR0ZXJuOiBFeGNsdWRlUGF0dGVybikge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLnBhdHRlcm4gPSBwYXR0ZXJuO1xyXG5cdH1cclxuXHRvbk9wZW4oKSB7XHJcblx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHR9XHJcblx0ZGlzcGxheSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnUGF0dGVybiBzZXR0aW5ncycgfSk7XHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIGZvbGRlciBuYW1lIHN5bmMnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbmFtZSBzaG91bGQgYmUgcmVuYW1lZCB3aGVuIHRoZSBmaWxlIG5hbWUgaGFzIGJlZW4gY2hhbmdlZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBhdHRlcm4uZGlzYWJsZVN5bmMpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMucGF0dGVybi5kaXNhYmxlU3luYyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBhdXRvIGNyZWF0aW9uIG9mIGZvbGRlciBub3RlcyBpbiB0aGlzIGZvbGRlcicpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgYSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgY3JlYXRlZCB3aGVuIGEgbmV3IGZvbGRlciBpcyBjcmVhdGVkIHRoYXQgbWF0Y2hlcyB0aGlzIHBhdHRlcm4nKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wYXR0ZXJuLmRpc2FibGVBdXRvQ3JlYXRlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBhdHRlcm4uZGlzYWJsZUF1dG9DcmVhdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIG9wZW4gZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgb3BlbmVkIHdoZW4gdGhlIGZvbGRlciBpcyBvcGVuZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wYXR0ZXJuLmRpc2FibGVGb2xkZXJOb3RlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBhdHRlcm4uZGlzYWJsZUZvbGRlck5vdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAoIXRoaXMucGF0dGVybi5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0NvbGxhcHNlIGZvbGRlciB3aGVuIG9wZW5pbmcgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBzaG91bGQgYmUgY29sbGFwc2VkIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIG9wZW5lZCcpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBhdHRlcm4uZW5hYmxlQ29sbGFwc2luZylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGF0dGVybi5lbmFibGVDb2xsYXBzaW5nID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cdG9uQ2xvc2UoKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJ3NyYy9tYWluJztcclxuaW1wb3J0IHsgZ2V0RGVmZXIsIExpc3RlbmVyLCBFdmVudHMsIEFwaUludGVyZmFjZSwgRGVmZXJJbnRlcmZhY2UsIExpc3RlbmVyUmVmLCBFdmVudERpc3BhdGNoZXJJbnRlcmZhY2UgfSBmcm9tICdmcm9udC1tYXR0ZXItcGx1Z2luLWFwaS1wcm92aWRlcic7XHJcbmltcG9ydCB7IEFwcCwgVEZpbGUsIFRGb2xkZXIgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IGV4dHJhY3RGb2xkZXJOYW1lLCBnZXRGb2xkZXIgfSBmcm9tICdzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5leHBvcnQgY2xhc3MgRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIge1xyXG5cdHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW47XHJcblx0YXBwOiBBcHA7XHJcblx0YXBpOiBBcGlJbnRlcmZhY2UgfCBudWxsID0gbnVsbDtcclxuXHRkZWZmZXI6IERlZmVySW50ZXJmYWNlIHwgbnVsbCA9IG51bGw7XHJcblx0bW9kaWZpZWRGb2xkZXJzOiBNYXA8c3RyaW5nLCBURm9sZGVyPiA9IG5ldyBNYXAoKTtcclxuXHRldmVudFJlZjogTGlzdGVuZXJSZWY8J21hbmFnZXI6dXBkYXRlJz47XHJcblx0ZGlzcGF0Y2hlcjogRXZlbnREaXNwYXRjaGVySW50ZXJmYWNlPEV2ZW50cz5cclxuXHRjb25zdHJ1Y3RvcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gcGx1Z2luLmFwcDtcclxuXHJcblx0XHQoYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmRlZmZlciA9IGdldERlZmVyKHRoaXMuYXBwKTtcclxuXHRcdFx0aWYgKHRoaXMuZGVmZmVyLmlzUGx1Z2luUmVhZHkoKSkge1xyXG5cdFx0XHRcdHRoaXMuYXBpID0gdGhpcy5kZWZmZXIuZ2V0QXBpKCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0YXdhaXQgdGhpcy5kZWZmZXIuYXdhaXRQbHVnaW4oKTtcclxuXHRcdFx0XHR0aGlzLmFwaSA9IHRoaXMuZGVmZmVyLmdldEFwaSgpO1xyXG5cdFx0XHRcdC8vIGlmIHlvdSB3YW50IHRvIHdhaXQgZmVhdHVyZXMgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBjaGFpblxyXG5cdFx0XHRcdGlmICghdGhpcy5kZWZmZXIuaXNGZWF0dXJlc1JlYWR5KCkpIHtcclxuXHRcdFx0XHRcdGF3YWl0IHRoaXMuZGVmZmVyLmF3YWl0RmVhdHVyZXMoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0Y29uc3QgZGlzcGF0Y2hlciA9IHRoaXMuYXBpPy5nZXRFdmVudERpc3BhdGNoZXIoKTtcclxuXHRcdFx0aWYgKGRpc3BhdGNoZXIpIHtcclxuXHRcdFx0XHR0aGlzLmRpc3BhdGNoZXIgPSBkaXNwYXRjaGVyO1xyXG5cdFx0XHR9XHJcblx0XHRcdGNvbnN0IGV2ZW50OiBMaXN0ZW5lcjxFdmVudHMsICdtYW5hZ2VyOnVwZGF0ZSc+ID0ge1xyXG5cdFx0XHRcdG5hbWU6ICdtYW5hZ2VyOnVwZGF0ZScsXHJcblx0XHRcdFx0Y2I6IChkYXRhKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLmhhbmRsZVJlbmFtZShkYXRhIGFzIGFueSwgdHJ1ZSk7XHJcblx0XHRcdFx0fSxcclxuXHRcdFx0fTtcclxuXHRcdFx0Ly8gS2VlcCByZWYgdG8gcmVtb3ZlIGxpc3RlbmVyXHJcblx0XHRcdGNvbnN0IHJlZiA9IGRpc3BhdGNoZXI/LmFkZExpc3RlbmVyKGV2ZW50KTtcclxuXHRcdFx0aWYgKHJlZikge1xyXG5cdFx0XHRcdHRoaXMuZXZlbnRSZWYgPSByZWY7XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEZpbGVzKCkuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRcdHRoaXMuaGFuZGxlUmVuYW1lKHsgaWQ6ICcnLCByZXN1bHQ6IGZhbHNlLCBwYXRoOiBmaWxlLnBhdGggfSwgZmFsc2UpO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuXHRcdH0pKCk7XHJcblx0fVxyXG5cdGRlbGV0ZUV2ZW50KCkge1xyXG5cdFx0aWYgKHRoaXMuZXZlbnRSZWYpIHtcclxuXHRcdFx0dGhpcy5kaXNwYXRjaGVyLnJlbW92ZUxpc3RlbmVyKHRoaXMuZXZlbnRSZWYpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRhc3luYyBoYW5kbGVSZW5hbWUoZGF0YToge1xyXG5cdFx0aWQ6IHN0cmluZztcclxuXHRcdHJlc3VsdDogYm9vbGVhbjtcclxuXHRcdHBhdGg6IHN0cmluZztcclxuXHR9LCBpc0V2ZW50OiBib29sZWFuKSB7XHJcblx0XHRpZiAoKGRhdGEgYXMgYW55KS5kYXRhKSBkYXRhID0gKGRhdGEgYXMgYW55KS5kYXRhXHJcblx0XHRjb25zdCBmaWxlID0gdGhpcy5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGRhdGEucGF0aCk7XHJcblx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7IHJldHVybjsgfVxyXG5cclxuXHRcdGNvbnN0IHJlc29sdmVyID0gdGhpcy5hcGk/LmdldFJlc29sdmVyRmFjdG9yeSgpPy5jcmVhdGVSZXNvbHZlcignI2ZlYXR1cmUtaWQjJyk7XHJcblx0XHRjb25zdCBuZXdOYW1lID0gcmVzb2x2ZXI/LnJlc29sdmUoZmlsZT8ucGF0aCA/PyAnJylcclxuXHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLnBsdWdpbiwgZmlsZSk7XHJcblxyXG5cdFx0aWYgKChleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSkgfHwgZmlsZS5iYXNlbmFtZSkgIT09IGZvbGRlcj8ubmFtZSkgeyByZXR1cm47IH1cclxuXHRcdGlmICghKGZvbGRlciBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0aWYgKGlzRXZlbnQpIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uY2hhbmdlTmFtZShmb2xkZXIsIG5ld05hbWUsIHRydWUpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uY2hhbmdlTmFtZShmb2xkZXIsIG5ld05hbWUsIGZhbHNlKTtcclxuXHRcdH1cclxuXHRcdGlmIChuZXdOYW1lKSB7XHJcblx0XHRcdGZvbGRlci5uZXdOYW1lID0gbmV3TmFtZTtcclxuXHRcdFx0dGhpcy5tb2RpZmllZEZvbGRlcnMuc2V0KGZvbGRlci5wYXRoLCBmb2xkZXIpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Zm9sZGVyLm5ld05hbWUgPSBudWxsO1xyXG5cdFx0XHR0aGlzLm1vZGlmaWVkRm9sZGVycy5kZWxldGUoZm9sZGVyLnBhdGgpO1xyXG5cdFx0fVxyXG5cclxuXHR9XHJcbn1cclxuIiwgImltcG9ydCB7IEFwcCwgVEZvbGRlciwgTWVudSwgVEFic3RyYWN0RmlsZSwgTm90aWNlLCBURmlsZSwgRWRpdG9yLCBNYXJrZG93blZpZXcsIFBsYXRmb3JtIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi9tYWluJztcclxuaW1wb3J0IHsgZ2V0Rm9sZGVyTm90ZSwgY3JlYXRlRm9sZGVyTm90ZSwgZGVsZXRlRm9sZGVyTm90ZSwgdHVybkludG9Gb2xkZXJOb3RlLCBvcGVuRm9sZGVyTm90ZSwgZXh0cmFjdEZvbGRlck5hbWUgfSBmcm9tICcuL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgRXhjbHVkZWRGb2xkZXIgfSBmcm9tICcuL2V4Y2x1ZGVkRm9sZGVyJztcclxuZXhwb3J0IGNsYXNzIENvbW1hbmRzIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gYXBwO1xyXG5cdH1cclxuXHRyZWdpc3RlckNvbW1hbmRzKCkge1xyXG5cdFx0dGhpcy5wbHVnaW4ucmVnaXN0ZXJFdmVudCh0aGlzLnBsdWdpbi5hcHAud29ya3NwYWNlLm9uKCdlZGl0b3ItbWVudScsIChtZW51OiBNZW51LCBlZGl0b3I6IEVkaXRvciwgdmlldzogTWFya2Rvd25WaWV3KSA9PiB7XHJcblx0XHRcdGNvbnN0IHRleHQgPSBlZGl0b3IuZ2V0U2VsZWN0aW9uKCkudHJpbSgpO1xyXG5cdFx0XHRtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpdGVtLnNldFRpdGxlKCdDcmVhdGUgZm9sZGVyIG92ZXJ2aWV3JylcclxuXHRcdFx0XHRcdC5zZXRJY29uKCdlZGl0JylcclxuXHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oJ2BgYGZvbGRlci1vdmVydmlld1xcbmBgYFxcbicpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRpZiAoIXRleHQgfHwgdGV4dC50cmltKCkgPT09ICcnKSByZXR1cm47XHJcblx0XHRcdG1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ0NyZWF0ZSBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IGZpbGUgPSB2aWV3LmZpbGU7XHJcblx0XHRcdFx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0Y29uc3QgYmxhY2tsaXN0ID0gWycqJywgJ1xcXFwnLCAnXCInLCAnLycsICc8JywgJz4nLCAnPycsICd8JywgJzonXTtcclxuXHRcdFx0XHRcdFx0Zm9yIChjb25zdCBjaGFyIG9mIGJsYWNrbGlzdCkge1xyXG5cdFx0XHRcdFx0XHRcdGlmICh0ZXh0LmluY2x1ZGVzKGNoYXIpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdGaWxlIG5hbWUgY2Fubm90IGNvbnRhaW4gYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKiBcIiBcXFxcIC8gPCA+IDogfCA/Jyk7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGlmICh0ZXh0LmVuZHNXaXRoKCcuJykpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdGaWxlIG5hbWUgY2Fubm90IGVuZCB3aXRoIGEgZG90Jyk7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGxldCBmb2xkZXI6IFRBYnN0cmFjdEZpbGUgfCBudWxsO1xyXG5cdFx0XHRcdFx0XHRjb25zdCBmb2xkZXJQYXRoID0gdGhpcy5wbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdFx0XHRcdFx0aWYgKGZvbGRlclBhdGggPT09ICcnKSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aCh0ZXh0KTtcclxuXHRcdFx0XHRcdFx0XHRpZiAoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZvbGRlciBub3RlIGFscmVhZHkgZXhpc3RzJyk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5jcmVhdGVGb2xkZXIodGV4dCk7XHJcblx0XHRcdFx0XHRcdFx0XHRjcmVhdGVGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCB0ZXh0LCBmYWxzZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCArICcvJyArIHRleHQpO1xyXG5cdFx0XHRcdFx0XHRcdGlmIChmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbmV3IE5vdGljZSgnRm9sZGVyIG5vdGUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICh0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCArICcvJyArIHRleHQgKyB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZSkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZpbGUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihmb2xkZXJQYXRoICsgJy8nICsgdGV4dCk7XHJcblx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZm9sZGVyUGF0aCArICcvJyArIHRleHQsIGZhbHNlKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRjb25zdCBmaWxlTmFtZSA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIHRleHQpO1xyXG5cdFx0XHRcdFx0XHRpZiAoZmlsZU5hbWUgPT09IHRleHQpIHtcclxuXHRcdFx0XHRcdFx0XHRlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgW1ske2ZpbGVOYW1lfV1dYCk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oYFtbJHtmaWxlTmFtZX18JHt0ZXh0fV1dYCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucGx1Z2luLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAud29ya3NwYWNlLm9uKCdmaWxlLW1lbnUnLCAobWVudTogTWVudSwgZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRsZXQgZm9sZGVyOiBUQWJzdHJhY3RGaWxlIHwgVEZvbGRlciB8IG51bGwgPSBmaWxlLnBhcmVudDtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRmb2xkZXIgPSBmaWxlLnBhcmVudDtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0Y29uc3QgZmlsZU5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSk7XHJcblx0XHRcdFx0XHRpZiAoZmlsZU5hbWUpIHtcclxuXHRcdFx0XHRcdFx0aWYgKGZpbGUucGFyZW50Py5wYXRoID09PSAnJyB8fCBmaWxlLnBhcmVudD8ucGF0aCA9PT0gJy8nKSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlTmFtZSk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlLnBhcmVudD8ucGF0aCArICcvJyArIGZpbGVOYW1lKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcy5wbHVnaW4sIGZvbGRlci5wYXRoKTtcclxuXHRcdFx0XHRcdGlmIChmb2xkZXJOb3RlPy5wYXRoID09PSBmaWxlLnBhdGgpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0fSBlbHNlIGlmIChmaWxlLnBhcmVudCBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRcdGZvbGRlciA9IGZpbGUucGFyZW50O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpZiAoUGxhdGZvcm0uaXNEZXNrdG9wICYmICFQbGF0Zm9ybS5pc1RhYmxldCAmJiB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VTdWJtZW51cykge1xyXG5cdFx0XHRcdFx0aXRlbVxyXG5cdFx0XHRcdFx0XHQuc2V0VGl0bGUoJ0ZvbGRlciBOb3RlIENvbW1hbmRzJylcclxuXHRcdFx0XHRcdFx0LnNldEljb24oJ2ZvbGRlci1lZGl0Jyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGxldCBzdWJNZW51OiBNZW51O1xyXG5cdFx0XHRcdGlmICghUGxhdGZvcm0uaXNEZXNrdG9wQXBwIHx8ICFQbGF0Zm9ybS5pc0Rlc2t0b3AgfHwgUGxhdGZvcm0uaXNUYWJsZXQgfHwgIXRoaXMucGx1Z2luLnNldHRpbmdzLnVzZVN1Ym1lbnVzKSB7XHJcblx0XHRcdFx0XHRzdWJNZW51ID0gbWVudTtcclxuXHRcdFx0XHRcdGl0ZW0uc2V0RGlzYWJsZWQodHJ1ZSk7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdFx0XHRcdHN1Yk1lbnUgPSBpdGVtLnNldFN1Ym1lbnUoKSBhcyBNZW51O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXHJcblx0XHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdFx0aXRlbS5zZXRUaXRsZSgnQ3JlYXRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCFmb2xkZXIpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdGxldCBuZXdQYXRoID0gZm9sZGVyLnBhdGggKyAnLycgKyBmaWxlLmJhc2VuYW1lO1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKGZvbGRlci5wYXRoID09PSAnJyB8fCBmb2xkZXIucGF0aCA9PT0gJy8nKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdG5ld1BhdGggPSBmaWxlLmJhc2VuYW1lO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobmV3UGF0aCkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZvbGRlciBhbHJlYWR5IGV4aXN0cycpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihuZXdQYXRoKTtcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IG5ld0ZvbGRlciA9IHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobmV3UGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIShuZXdGb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgbmV3Rm9sZGVyLnBhdGgsIHRydWUsIGZhbHNlLCBmaWxlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCkgPT09ICcnKSByZXR1cm47XHJcblx0XHRcdFx0XHRpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdFx0c3ViTWVudS5hZGRJdGVtKChpdGVtKSA9PiB7XHJcblx0XHRcdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ1R1cm4gaW50byBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0XHRcdFx0LnNldEljb24oJ2VkaXQnKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICghZm9sZGVyIHx8ICEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmb2xkZXIucGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHR0dXJuSW50b0ZvbGRlck5vdGUodGhpcy5wbHVnaW4sIGZpbGUsIGZvbGRlciwgZm9sZGVyTm90ZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSByZXR1cm47XHJcblx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbmQoKGZvbGRlcikgPT4gZm9sZGVyLnBhdGggPT09IGZpbGUucGF0aCkpIHtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdSZW1vdmUgZm9sZGVyIGZyb20gZXhjbHVkZWQgZm9sZGVycycpXHJcblx0XHRcdFx0XHRcdFx0LnNldEljb24oJ3RyYXNoJylcclxuXHRcdFx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcihcclxuXHRcdFx0XHRcdFx0XHRcdFx0KGZvbGRlcikgPT4gZm9sZGVyLnBhdGggIT09IGZpbGUucGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoJ1N1Y2Nlc3NmdWxseSByZW1vdmVkIGZvbGRlciBmcm9tIGV4Y2x1ZGVkIGZvbGRlcnMnKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ0V4Y2x1ZGUgZm9sZGVyIGZyb20gZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0XHRcdFx0LnNldEljb24oJ3gtY2lyY2xlJylcclxuXHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gbmV3IEV4Y2x1ZGVkRm9sZGVyKGZpbGUucGF0aCwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5wdXNoKGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdTdWNjZXNzZnVsbHkgZXhjbHVkZWQgZm9sZGVyIGZyb20gZm9sZGVyIG5vdGVzJyk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRcdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdEZWxldGUgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdFx0XHRcdC5zZXRJY29uKCd0cmFzaCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0ZGVsZXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZm9sZGVyTm90ZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdPcGVuIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignY2hldnJvbi1yaWdodC1zcXVhcmUnKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdG9wZW5Gb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmb2xkZXJOb3RlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdFx0aXRlbS5zZXRUaXRsZSgnQ3JlYXRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZmlsZS5wYXRoLCB0cnVlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KSk7XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgeyBLZXltYXAgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICdzcmMvbWFpbic7XHJcbmltcG9ydCB7IG9wZW5Gb2xkZXJOb3RlLCBjcmVhdGVGb2xkZXJOb3RlLCBnZXRGb2xkZXJOb3RlIH0gZnJvbSAnc3JjL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgZ2V0RXhjbHVkZWRGb2xkZXIgfSBmcm9tICdzcmMvZXhjbHVkZWRGb2xkZXInO1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlVmlld0hlYWRlckNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50LCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0aWYgKCEoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSByZXR1cm47XHJcblx0aWYgKCFwbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKSByZXR1cm47XHJcblxyXG5cdGNvbnN0IGZvbGRlclBhdGggPSBldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnKTtcclxuXHRpZiAoIWZvbGRlclBhdGgpIHsgcmV0dXJuOyB9XHJcblx0Y29uc3QgZXhjbHVkZWRGb2xkZXIgPSBnZXRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChleGNsdWRlZEZvbGRlcj8uZGlzYWJsZUZvbGRlck5vdGUpIHtcclxuXHRcdGV2ZW50LnRhcmdldC5vbmNsaWNrID0gbnVsbDtcclxuXHRcdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH0gZWxzZSBpZiAoZXhjbHVkZWRGb2xkZXI/LmVuYWJsZUNvbGxhcHNpbmcgfHwgcGx1Z2luLnNldHRpbmdzLmVuYWJsZUNvbGxhcHNpbmcpIHtcclxuXHRcdGV2ZW50LnRhcmdldC5vbmNsaWNrID0gbnVsbDtcclxuXHRcdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gb3BlbkZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJOb3RlLCBldmVudCk7XHJcblx0fSBlbHNlIGlmIChldmVudC5hbHRLZXkgfHwgS2V5bWFwLmlzTW9kRXZlbnQoZXZlbnQpID09PSAndGFiJykge1xyXG5cdFx0aWYgKChwbHVnaW4uc2V0dGluZ3MuYWx0S2V5ICYmIGV2ZW50LmFsdEtleSkgfHwgKHBsdWdpbi5zZXR0aW5ncy5jdHJsS2V5ICYmIEtleW1hcC5pc01vZEV2ZW50KGV2ZW50KSA9PT0gJ3RhYicpKSB7XHJcblx0XHRcdGF3YWl0IGNyZWF0ZUZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJQYXRoLCB0cnVlLCB0cnVlKTtcclxuXHRcdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlclBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlclBhdGgsICdoYXMtbm90LWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHR9XHJcblx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG59XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlRm9sZGVyQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4pIHtcclxuXHRpZiAoIShldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybjtcclxuXHRldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuXHJcblx0Y29uc3QgZm9sZGVyUGF0aCA9IGV2ZW50LnRhcmdldC5wYXJlbnRFbGVtZW50Py5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpO1xyXG5cdGlmICghZm9sZGVyUGF0aCkgeyByZXR1cm47IH1cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZm9sZGVyUGF0aCk7XHJcblx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdFx0ZXZlbnQudGFyZ2V0LmNsaWNrKCk7XHJcblx0XHRyZXR1cm47XHJcblx0fSBlbHNlIGlmIChleGNsdWRlZEZvbGRlcj8uZW5hYmxlQ29sbGFwc2luZyB8fCBwbHVnaW4uc2V0dGluZ3MuZW5hYmxlQ29sbGFwc2luZykge1xyXG5cdFx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdFx0ZXZlbnQudGFyZ2V0LmNsaWNrKCk7XHJcblx0fVxyXG5cclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gb3BlbkZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJOb3RlLCBldmVudCk7XHJcblx0fSBlbHNlIGlmIChldmVudC5hbHRLZXkgfHwgS2V5bWFwLmlzTW9kRXZlbnQoZXZlbnQpID09PSAndGFiJykge1xyXG5cdFx0aWYgKChwbHVnaW4uc2V0dGluZ3MuYWx0S2V5ICYmIGV2ZW50LmFsdEtleSkgfHwgKHBsdWdpbi5zZXR0aW5ncy5jdHJsS2V5ICYmIEtleW1hcC5pc01vZEV2ZW50KGV2ZW50KSA9PT0gJ3RhYicpKSB7XHJcblx0XHRcdGF3YWl0IGNyZWF0ZUZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJQYXRoLCB0cnVlLCB0cnVlKTtcclxuXHRcdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlclBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlclBhdGgsICdoYXMtbm90LWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHR9XHJcblx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG59XHJcbiIsICJpbXBvcnQgeyBURmlsZSwgVEZvbGRlciwgVEFic3RyYWN0RmlsZSwgTm90aWNlIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnc3JjL21haW4nO1xyXG5pbXBvcnQgeyBleHRyYWN0Rm9sZGVyTmFtZSwgZ2V0Rm9sZGVyTm90ZSwgZ2V0Rm9sZGVyTm90ZUZvbGRlciB9IGZyb20gJy4uL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgZ2V0RXhjbHVkZWRGb2xkZXIsIEV4Y2x1ZGVkRm9sZGVyLCBhZGRFeGNsdWRlZEZvbGRlciwgdXBkYXRlRXhjbHVkZWRGb2xkZXIsIGRlbGV0ZUV4Y2x1ZGVkRm9sZGVyIH0gZnJvbSAnLi4vZXhjbHVkZWRGb2xkZXInO1xyXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRm9sZGVyUmVuYW1lKGZpbGU6IFRGb2xkZXIsIG9sZFBhdGg6IHN0cmluZywgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdGNvbnN0IGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZpbGUubmFtZSk7XHJcblx0Y29uc3QgZm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZmlsZS5wYXRoKTtcclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIG9sZFBhdGgpO1xyXG5cdGlmICghKGZvbGRlck5vdGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHJcblx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRjb25zdCBleGNsdWRlZEZvbGRlcnMgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmlsdGVyKFxyXG5cdFx0KGV4Y2x1ZGVkRm9sZGVyKSA9PiBleGNsdWRlZEZvbGRlci5wYXRoLmluY2x1ZGVzKG9sZFBhdGgpXHJcblx0KTtcclxuXHJcblx0ZXhjbHVkZWRGb2xkZXJzLmZvckVhY2goKGV4Y2x1ZGVkRm9sZGVyKSA9PiB7XHJcblx0XHRpZiAoZXhjbHVkZWRGb2xkZXIucGF0aCA9PT0gb2xkUGF0aCkge1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gZm9sZGVyLnBhdGg7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGZvbGRlcnMgPSBleGNsdWRlZEZvbGRlci5wYXRoLnNwbGl0KCcvJyk7XHJcblx0XHRpZiAoZm9sZGVycy5sZW5ndGggPCAxKSB7XHJcblx0XHRcdGZvbGRlcnMucHVzaChleGNsdWRlZEZvbGRlci5wYXRoKTtcclxuXHRcdH1cclxuXHJcblx0XHRmb2xkZXJzW2ZvbGRlcnMuaW5kZXhPZihmb2xkZXIubmFtZSldID0gZm9sZGVyLm5hbWU7XHJcblx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gZm9sZGVycy5qb2luKCcvJyk7XHJcblx0fSk7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZmlsZS5wYXRoKTtcclxuXHRpZiAoZXhjbHVkZWRGb2xkZXI/LmRpc2FibGVTeW5jICYmICFmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gcGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdH1cclxuXHJcblx0bGV0IG5ld1BhdGggPSAnJztcclxuXHRpZiAocGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdGNvbnN0IHBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGNvbnN0IG9sZFBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcob2xkUGF0aCk7XHJcblx0XHRpZiAocGFyZW50Rm9sZGVyUGF0aCAhPT0gb2xkUGFyZW50Rm9sZGVyUGF0aCkge1xyXG5cdFx0XHRpZiAoIXBsdWdpbi5zZXR0aW5ncy5zeW5jTW92ZSkgeyByZXR1cm47IH1cclxuXHRcdFx0bmV3UGF0aCA9IGAke3BhcmVudEZvbGRlclBhdGh9LyR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHRcdH0gZWxzZSBpZiAocGFyZW50Rm9sZGVyUGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRcdGZvbGRlck5vdGUucGF0aCA9IGAke2ZvbGRlck5vdGUubmFtZX1gO1xyXG5cdFx0XHRuZXdQYXRoID0gYCR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvbGRlck5vdGUucGF0aCA9IGAke3BhcmVudEZvbGRlclBhdGh9LyR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdG5ld1BhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke2ZpbGVOYW1lfS4ke2ZvbGRlck5vdGUuZXh0ZW5zaW9ufWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIHtcclxuXHRcdGZvbGRlck5vdGUucGF0aCA9IGAke2ZpbGUucGF0aH0vJHtmb2xkZXJOb3RlLm5hbWV9YDtcclxuXHRcdG5ld1BhdGggPSBgJHtmaWxlLnBhdGh9LyR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHR9XHJcblx0cGx1Z2luLmFwcC52YXVsdC5yZW5hbWUoZm9sZGVyTm90ZSwgbmV3UGF0aCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVGaWxlUmVuYW1lKGZpbGU6IFRGaWxlLCBvbGRQYXRoOiBzdHJpbmcsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4pIHtcclxuXHRjb25zdCBvbGRGaWxlTmFtZSA9IHBsdWdpbi5yZW1vdmVFeHRlbnNpb24ocGx1Z2luLmdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcob2xkUGF0aCkpO1xyXG5cdGNvbnN0IG9sZEZvbGRlciA9IGdldEZvbGRlck5vdGVGb2xkZXIocGx1Z2luLCBvbGRQYXRoLCBvbGRGaWxlTmFtZSk7XHJcblx0Y29uc3QgZm9sZGVyTmFtZSA9IGV4dHJhY3RGb2xkZXJOYW1lKHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSkgfHwgZmlsZS5iYXNlbmFtZTtcclxuXHRjb25zdCBvbGRGb2xkZXJOYW1lID0gZXh0cmFjdEZvbGRlck5hbWUocGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBvbGRGaWxlTmFtZSkgfHwgb2xkRmlsZU5hbWU7XHJcblx0Y29uc3QgbmV3Rm9sZGVyID0gZ2V0Rm9sZGVyTm90ZUZvbGRlcihwbHVnaW4sIGZpbGUsIGZpbGUuYmFzZW5hbWUpO1xyXG5cdGxldCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgbmV3Rm9sZGVyPy5wYXRoIHx8ICcnKTtcclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIG9sZFBhdGgsIHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24sIGZpbGUpO1xyXG5cclxuXHRpZiAoZXhjbHVkZWRGb2xkZXI/LmRpc2FibGVTeW5jICYmIGZvbGRlck5hbWUgPT09IG5ld0ZvbGRlcj8ubmFtZSkge1xyXG5cdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwobmV3Rm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHJldHVybjtcclxuXHR9IGVsc2UgaWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlU3luYykge1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwobmV3Rm9sZGVyPy5wYXRoIHx8ICcnLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHQvLyBmaWxlIGhhcyBiZWVuIG1vdmVkIGludG8gcG9zaXRpb24gd2hlcmUgaXQgY2FuIGJlIGEgZm9sZGVyIG5vdGUhXHJcblx0aWYgKGZvbGRlck5hbWUgPT09IG5ld0ZvbGRlcj8ubmFtZSAmJiBmb2xkZXJOb3RlKSB7XHJcblx0XHRuZXcgTm90aWNlKCdGb2xkZXIgd2l0aCBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdHMhJyk7XHJcblx0XHRsZXQgZXhjbHVkZWRGb2xkZXJFeGlzdGVkID0gdHJ1ZTtcclxuXHRcdGxldCBkaXNhYmxlZFN5bmMgPSBmYWxzZTtcclxuXHJcblx0XHRpZiAoIWV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRcdGV4Y2x1ZGVkRm9sZGVyRXhpc3RlZCA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlciA9IG5ldyBFeGNsdWRlZEZvbGRlcihvbGRGb2xkZXI/LnBhdGggfHwgJycsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0gZWxzZSBpZiAoIWV4Y2x1ZGVkRm9sZGVyLmRpc2FibGVTeW5jKSB7XHJcblx0XHRcdGRpc2FibGVkU3luYyA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHRydWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBvbGRQYXRoKS50aGVuKCgpID0+IHtcclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlckV4aXN0ZWQpIHtcclxuXHRcdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIGlmICghZGlzYWJsZWRTeW5jKSB7XHJcblx0XHRcdFx0ZXhjbHVkZWRGb2xkZXIuZGlzYWJsZVN5bmMgPSBmYWxzZTtcclxuXHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHRpZiAoZm9sZGVyTmFtZSA9PT0gbmV3Rm9sZGVyPy5uYW1lKSB7XHJcblx0XHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZmlsZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHBsdWdpbi5hZGRDU1NDbGFzc1RvVGl0bGVFTChuZXdGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKG9sZEZvbGRlcj8ucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0Ly8gZmlsZSBtYXRjaGVkIGZvbGRlciBuYW1lIGJlZm9yZSByZW5hbWVcclxuXHQvLyBmaWxlIGhhc250IG1vdmVkIGp1c3QgcmVuYW1lZFxyXG5cdC8vIE5lZWQgdG8gcmVuYW1lIHRoZSBmb2xkZXJcclxuXHRpZiAoIW9sZEZvbGRlcikgcmV0dXJuO1xyXG5cdGlmIChvbGRGb2xkZXJOYW1lID09PSBvbGRGb2xkZXIubmFtZSAmJiBuZXdGb2xkZXI/LnBhdGggPT09IG9sZEZvbGRlci5wYXRoKSB7XHJcblx0XHRyZXR1cm4gcmVuYW1lRm9sZGVyT25GaWxlUmVuYW1lKGZpbGUsIG9sZFBhdGgsIG9sZEZvbGRlciwgcGx1Z2luKTtcclxuXHR9IGVsc2UgaWYgKGZvbGRlck5vdGUgJiYgb2xkRm9sZGVyTmFtZSA9PT0gb2xkRm9sZGVyLm5hbWUpIHtcclxuXHRcdHJldHVybiByZW5hbWVGb2xkZXJPbkZpbGVSZW5hbWUoZmlsZSwgb2xkUGF0aCwgb2xkRm9sZGVyLCBwbHVnaW4pO1xyXG5cdH1cclxuXHJcblx0Ly8gdGhlIG5vdGUgaGFzIGJlZW4gbW92ZWQgc29tZXdoZXJlIGFuZCBpcyBubyBsb25nZXIgYSBmb2xkZXIgbm90ZVxyXG5cdC8vIGNsZWFudXAgY3NzIG9uIHRoZSBmb2xkZXIgYW5kIG5vdGVcclxuXHRpZiAob2xkRm9sZGVyLm5hbWUgPT09IG9sZEZpbGVOYW1lICYmIG5ld0ZvbGRlcj8ucGF0aCAhPT0gb2xkRm9sZGVyLnBhdGgpIHtcclxuXHRcdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChvbGRGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwob2xkUGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0fVxyXG59XHJcblxyXG5hc3luYyBmdW5jdGlvbiByZW5hbWVGb2xkZXJPbkZpbGVSZW5hbWUoZmlsZTogVEZpbGUsIG9sZFBhdGg6IHN0cmluZywgb2xkRm9sZGVyOiBUQWJzdHJhY3RGaWxlLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0Y29uc3QgbmV3Rm9sZGVyTmFtZSA9IGV4dHJhY3RGb2xkZXJOYW1lKHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSk7XHJcblx0aWYgKCFuZXdGb2xkZXJOYW1lKSB7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwob2xkRm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlLnBhdGgsICdpcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH0gZWxzZSBpZiAobmV3Rm9sZGVyTmFtZSA9PT0gb2xkRm9sZGVyLm5hbWUpIHtcclxuXHRcdHBsdWdpbi5hZGRDU1NDbGFzc1RvVGl0bGVFTChvbGRGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdGxldCBuZXdGb2xkZXJQYXRoID0gJyc7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRuZXdGb2xkZXJQYXRoID0gb2xkRm9sZGVyLnBhcmVudD8ucGF0aCArICcvJyArIG5ld0ZvbGRlck5hbWU7XHJcblx0fSBlbHNlIHtcclxuXHRcdGNvbnN0IHBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGlmIChwYXJlbnRGb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0bmV3Rm9sZGVyUGF0aCA9IGAke25ld0ZvbGRlck5hbWV9YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG5ld0ZvbGRlclBhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke25ld0ZvbGRlck5hbWV9YDtcclxuXHRcdH1cclxuXHR9XHJcblx0aWYgKHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG5ld0ZvbGRlclBhdGgpIHx8IHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG5ld0ZvbGRlck5hbWUgfHwgJycpKSB7XHJcblx0XHRhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBvbGRQYXRoKTtcclxuXHRcdHJldHVybiBuZXcgTm90aWNlKCdBIGZvbGRlciB3aXRoIHRoZSBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHR9XHJcblx0YXdhaXQgcGx1Z2luLmFwcC52YXVsdC5yZW5hbWUob2xkRm9sZGVyLCBuZXdGb2xkZXJQYXRoKTtcclxufVxyXG4iLCAiaW1wb3J0IHsgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgcGFyc2VZYW1sLCBUQWJzdHJhY3RGaWxlLCBURm9sZGVyLCBURmlsZSB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IHsgZXh0cmFjdEZvbGRlck5hbWUsIGdldEZvbGRlck5vdGUgfSBmcm9tICcuL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4vbWFpbic7XHJcbmV4cG9ydCB0eXBlIHlhbWxTZXR0aW5ncyA9IHtcclxuXHR0aXRsZT86IHN0cmluZztcclxuXHRkaXNhYmxlVGl0bGU/OiBib29sZWFuO1xyXG5cdGRlcHRoPzogbnVtYmVyO1xyXG5cdHR5cGU/OiAnZm9sZGVyJyB8ICdtYXJrZG93bicgfCAnY2FudmFzJyB8ICdvdGhlcicgfCAncGRmJyB8ICdpbWFnZXMnIHwgJ2F1ZGlvJyB8ICd2aWRlbycgfCAnYWxsJztcclxuXHRpbmNsdWRlVHlwZXM/OiBzdHJpbmdbXTtcclxuXHRzdHlsZT86ICdsaXN0JyB8ICdncmlkJztcclxuXHRkaXNhYmxlRmlsZVRhZz86IGJvb2xlYW47XHJcblx0c29ydEJ5PzogJ25hbWUnIHwgJ2NyZWF0ZWQnIHwgJ21vZGlmaWVkJyB8ICduYW1lQXNjJyB8ICdjcmVhdGVkQXNjJyB8ICdtb2RpZmllZEFzYyc7XHJcblx0c2hvd0VtcHR5Rm9sZGVycz86IGJvb2xlYW47XHJcblx0b25seUluY2x1ZGVTdWJmb2xkZXJzPzogYm9vbGVhbjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDYW52YXNPdmVydmlldygpIHtcclxuXHQvLyBjb25zb2xlLmxvZygndGVzdCcpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3ZlcnZpZXcocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgc291cmNlOiBzdHJpbmcsIGVsOiBIVE1MRWxlbWVudCwgY3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0KSB7XHJcblx0Ly8gcGFyc2Ugc291cmNlIHRvIHlhbWxcclxuXHRsZXQgeWFtbDogeWFtbFNldHRpbmdzID0gcGFyc2VZYW1sKHNvdXJjZSk7XHJcblx0aWYgKCF5YW1sKSB7XHJcblx0XHR5YW1sID0ge1xyXG5cdFx0XHR0aXRsZTogcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSxcclxuXHRcdFx0ZGlzYWJsZVRpdGxlOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVUaXRsZSxcclxuXHRcdFx0ZGVwdGg6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuZGVwdGgsXHJcblx0XHRcdHR5cGU6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcudHlwZSxcclxuXHRcdFx0aW5jbHVkZVR5cGVzOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyxcclxuXHRcdFx0c3R5bGU6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc3R5bGUsXHJcblx0XHRcdGRpc2FibGVGaWxlVGFnOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnLFxyXG5cdFx0XHRzb3J0Qnk6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc29ydEJ5LFxyXG5cdFx0XHRzaG93RW1wdHlGb2xkZXJzOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNob3dFbXB0eUZvbGRlcnMsXHJcblx0XHRcdG9ubHlJbmNsdWRlU3ViZm9sZGVyczogcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5vbmx5SW5jbHVkZVN1YmZvbGRlcnMsXHJcblx0XHR9O1xyXG5cdH1cclxuXHRjb25zdCBkZXB0aCA9IHlhbWw/LmRlcHRoIHx8IDE7XHJcblx0bGV0IHRpdGxlID0geWFtbD8udGl0bGUgfHwgcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSB8fCAne3tmb2xkZXJOYW1lfX0gb3ZlcnZpZXcnO1xyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUsIHBsdWdpbi5yZW1vdmVFeHRlbnNpb24ocGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhjdHguc291cmNlUGF0aCkpKTtcclxuXHR0aXRsZSA9IHRpdGxlLnJlcGxhY2VBbGwoJ3t7Zm9sZGVyTmFtZX19JywgZm9sZGVyTmFtZSB8fCAnJyk7XHJcblx0Y29uc3QgZGlzYWJsZVRpdGxlID0geWFtbD8uZGlzYWJsZVRpdGxlIHx8IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuZGlzYWJsZVRpdGxlIHx8IGZhbHNlO1xyXG5cdGxldCBpbmNsdWRlVHlwZXM6IHN0cmluZ1tdID0geWFtbD8uaW5jbHVkZVR5cGVzIHx8IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuaW5jbHVkZVR5cGVzIHx8IFsnZm9sZGVyJywgJ21hcmtkb3duJ107XHJcblx0aW5jbHVkZVR5cGVzID0gaW5jbHVkZVR5cGVzLm1hcCgodHlwZSkgPT4gdHlwZS50b0xvd2VyQ2FzZSgpKTtcclxuXHRjb25zdCBzdHlsZTogJ2xpc3QnIHwgJ2dyaWQnID0geWFtbD8uc3R5bGUgfHwgJ2xpc3QnO1xyXG5cdGNvbnN0IGRpc2FibGVGaWxlVGFnID0geWFtbD8uZGlzYWJsZUZpbGVUYWcgfHwgcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kaXNhYmxlRmlsZVRhZyB8fCBmYWxzZTtcclxuXHRjb25zdCBzaG93RW1wdHlGb2xkZXJzID0geWFtbD8uc2hvd0VtcHR5Rm9sZGVycyB8fCBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNob3dFbXB0eUZvbGRlcnMgfHwgZmFsc2U7XHJcblxyXG5cdGNvbnN0IHJvb3QgPSBlbC5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXcnIH0pO1xyXG5cdGNvbnN0IHRpdGxlRWwgPSByb290LmNyZWF0ZUVsKCdoMScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LXRpdGxlJyB9KTtcclxuXHRjb25zdCB1bCA9IHJvb3QuY3JlYXRlRWwoJ3VsJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdCcgfSk7XHJcblx0aWYgKCFkaXNhYmxlVGl0bGUpIHtcclxuXHRcdHRpdGxlRWwuaW5uZXJUZXh0ID0gdGl0bGU7XHJcblx0fVxyXG5cdGlmIChpbmNsdWRlVHlwZXMubGVuZ3RoID09PSAwKSB7IHJldHVybjsgfVxyXG5cdGxldCBmaWxlczogVEFic3RyYWN0RmlsZVtdID0gW107XHJcblx0Y29uc3Qgc291cmNlRmlsZSA9IHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGN0eC5zb3VyY2VQYXRoKTtcclxuXHRpZiAoIXNvdXJjZUZpbGUpIHJldHVybjtcclxuXHRjb25zdCBzb3VyY2VGb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKTtcclxuXHRsZXQgc291cmNlRm9sZGVyOiBURm9sZGVyIHwgdW5kZWZpbmVkO1xyXG5cclxuXHRpZiAoc291cmNlRmlsZS5wYXJlbnQgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRzb3VyY2VGb2xkZXIgPSBzb3VyY2VGaWxlLnBhcmVudDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0c291cmNlRm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKSkgYXMgVEZvbGRlcjtcclxuXHR9XHJcblxyXG5cdGZpbGVzID0gc291cmNlRm9sZGVyLmNoaWxkcmVuO1xyXG5cclxuXHRmaWxlcyA9IGZpbGVzLmZpbHRlcigoZmlsZSkgPT4ge1xyXG5cdFx0Y29uc3QgZm9sZGVyUGF0aCA9IHBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpO1xyXG5cdFx0aWYgKCFmb2xkZXJQYXRoLnN0YXJ0c1dpdGgoc291cmNlRm9sZGVyUGF0aCkpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRpZiAoZmlsZS5wYXRoID09PSBjdHguc291cmNlUGF0aCkgeyByZXR1cm4gZmFsc2U7IH1cclxuXHRcdGlmICgoZmlsZS5wYXRoLnNwbGl0KCcvJykubGVuZ3RoIC0gc291cmNlRm9sZGVyUGF0aC5zcGxpdCgnLycpLmxlbmd0aCkgLSAxIDwgZGVwdGgpIHtcclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9XHJcblx0fSk7XHJcblx0aWYgKCFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ2ZvbGRlcicpKSB7XHJcblx0XHRmaWxlcyA9IGdldEFsbEZpbGVzKGZpbGVzLCBzb3VyY2VGb2xkZXJQYXRoLCBkZXB0aCk7XHJcblx0fVxyXG5cdGZpbGVzID0gc29ydEZpbGVzKGZpbGVzLCB5YW1sLCBwbHVnaW4pO1xyXG5cclxuXHRpZiAoc3R5bGUgPT09ICdncmlkJykge1xyXG5cdFx0Y29uc3QgZ3JpZCA9IHJvb3QuY3JlYXRlRWwoJ2RpdicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQnIH0pO1xyXG5cdFx0ZmlsZXMuZm9yRWFjaChhc3luYyAoZmlsZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBncmlkSXRlbSA9IGdyaWQuY3JlYXRlRWwoJ2RpdicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQtaXRlbScgfSk7XHJcblx0XHRcdGNvbnN0IGdyaWRBcnRpY2xlID0gZ3JpZEl0ZW0uY3JlYXRlRWwoJ2FydGljbGUnLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1ncmlkLWl0ZW0tYXJ0aWNsZScgfSk7XHJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRjb25zdCBmaWxlQ29udGVudCA9IGF3YWl0IHBsdWdpbi5hcHAudmF1bHQucmVhZChmaWxlKTtcclxuXHRcdFx0XHQvLyBza2lwIC0tLSB5YW1sXHJcblx0XHRcdFx0Y29uc3QgZGVzY3JpcHRpb25FbCA9IGdyaWRBcnRpY2xlLmNyZWF0ZUVsKCdwJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWRlc2NyaXB0aW9uJyB9KTtcclxuXHRcdFx0XHRsZXQgZGVzY3JpcHRpb24gPSBmaWxlQ29udGVudC5zcGxpdCgnXFxuJylbMF07XHJcblx0XHRcdFx0aWYgKGRlc2NyaXB0aW9uLmxlbmd0aCA+IDY0KSB7XHJcblx0XHRcdFx0XHRkZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLnNsaWNlKDAsIDY0KSArICcuLi4nO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRkZXNjcmlwdGlvbkVsLmlubmVyVGV4dCA9IGRlc2NyaXB0aW9uO1xyXG5cdFx0XHRcdGNvbnN0IGxpbmsgPSBncmlkQXJ0aWNsZS5jcmVhdGVFbCgnYScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQtaXRlbS1saW5rIGludGVybmFsLWxpbmsnIH0pO1xyXG5cdFx0XHRcdGNvbnN0IHRpdGxlID0gbGluay5jcmVhdGVFbCgnaDEnLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1ncmlkLWl0ZW0tbGluay10aXRsZScgfSk7XHJcblx0XHRcdFx0dGl0bGUuaW5uZXJUZXh0ID0gZmlsZS5uYW1lLnJlcGxhY2UoJy5tZCcsICcnKS5yZXBsYWNlKCcuY2FudmFzJywgJycpO1xyXG5cdFx0XHRcdGxpbmsuaHJlZiA9IGZpbGUucGF0aDtcclxuXHRcdFx0fSBlbHNlIGlmIChmaWxlIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlckl0ZW0gPSBncmlkQXJ0aWNsZS5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWZvbGRlcicgfSk7XHJcblx0XHRcdFx0Y29uc3QgZm9sZGVyTmFtZSA9IGZvbGRlckl0ZW0uY3JlYXRlRWwoJ2gxJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWZvbGRlci1uYW1lJyB9KTtcclxuXHRcdFx0XHRmb2xkZXJOYW1lLmlubmVyVGV4dCA9IGZpbGUubmFtZTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSBlbHNlIGlmIChzdHlsZSA9PT0gJ2xpc3QnKSB7XHJcblx0XHRjb25zdCBwYXRoQmxhY2tsaXN0OiBzdHJpbmdbXSA9IFtdO1xyXG5cdFx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXJJdGVtID0gYWRkRm9sZGVyTGlzdChwbHVnaW4sIHVsLCBwYXRoQmxhY2tsaXN0LCBmaWxlKTtcclxuXHRcdFx0XHRnb1Rocm91Z2hGb2xkZXJzKHBsdWdpbiwgZm9sZGVySXRlbSwgZmlsZSwgZGVwdGgsIHNvdXJjZUZvbGRlclBhdGgsIGN0eCwgeWFtbCwgcGF0aEJsYWNrbGlzdCwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0YWRkRmlsZUxpc3QocGx1Z2luLCB1bCwgcGF0aEJsYWNrbGlzdCwgZmlsZSwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH0gZWxzZSBpZiAoc3R5bGUgPT09ICdleHBsb3JlcicpIHtcclxuXHRcdC8qXHJcblx0XHRjb25zdCB2aWV3ID0gcGx1Z2luLmdldEZpbGVFeHBsb3JlclZpZXcoKTtcclxuXHRcdGNvbnN0IGZvbGRlckVsZW1lbnQgPSBwbHVnaW4uZ2V0RUwocGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKSk/LnBhcmVudEVsZW1lbnQ7XHJcblx0XHRpZiAoIWZvbGRlckVsZW1lbnQpIHJldHVybjtcclxuXHRcdC8vIGNvcHkgZm9sZGVyRWxlbWVudFxyXG5cdFx0Y29uc3QgbmV3Rm9sZGVyRWxlbWVudCA9IGZvbGRlckVsZW1lbnQuY2xvbmVOb2RlKHRydWUpIGFzIEhUTUxFbGVtZW50O1xyXG5cdFx0bmV3Rm9sZGVyRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCcubmF2LWZvbGRlcicpLmZvckVhY2goKGVsKSA9PiB7XHJcblx0XHRcdGVsLmNsYXNzTGlzdC5yZW1vdmUoJ2lzLWNvbGxhcHNlZCcpO1xyXG5cdFx0fSk7XHJcblx0XHRyb290LmFwcGVuZENoaWxkKGZvbGRlckVsZW1lbnQpO1xyXG5cdFx0Ki9cclxuXHR9XHJcblx0aWYgKGluY2x1ZGVUeXBlcy5sZW5ndGggPiAxICYmIHN0eWxlICE9PSAnZ3JpZCcgJiYgKCFzaG93RW1wdHlGb2xkZXJzIHx8IHlhbWwub25seUluY2x1ZGVTdWJmb2xkZXJzKSkge1xyXG5cdFx0cmVtb3ZlRW1wdHlGb2xkZXJzKHVsLCAxLCB5YW1sKTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdvVGhyb3VnaEZvbGRlcnMocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgbGlzdDogSFRNTExJRWxlbWVudCB8IEhUTUxVTGlzdEVsZW1lbnQsIGZvbGRlcjogVEZvbGRlcixcclxuXHRkZXB0aDogbnVtYmVyLCBzb3VyY2VGb2xkZXJQYXRoOiBzdHJpbmcsIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgeWFtbDogeWFtbFNldHRpbmdzLCBwYXRoQmxhY2tsaXN0OiBzdHJpbmdbXSwgaW5jbHVkZVR5cGVzOiBzdHJpbmdbXSwgZGlzYWJsZUZpbGVUYWc6IGJvb2xlYW4pIHtcclxuXHRpZiAoc291cmNlRm9sZGVyUGF0aCA9PT0gJycpIHtcclxuXHRcdGRlcHRoLS07XHJcblx0fVxyXG5cdGxldCBmaWxlcyA9IGZvbGRlci5jaGlsZHJlbi5maWx0ZXIoKGZpbGUpID0+IHtcclxuXHRcdGNvbnN0IGZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGlmICghZm9sZGVyUGF0aC5zdGFydHNXaXRoKHNvdXJjZUZvbGRlclBhdGgpKSB7IHJldHVybiBmYWxzZTsgfVxyXG5cdFx0aWYgKChmaWxlLnBhdGguc3BsaXQoJy8nKS5sZW5ndGggLSBzb3VyY2VGb2xkZXJQYXRoLnNwbGl0KCcvJykubGVuZ3RoKSAtIDEgPCBkZXB0aCkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHRmaWxlcyA9IHNvcnRGaWxlcyhmaWxlcywgeWFtbCwgcGx1Z2luKTtcclxuXHRjb25zdCB1bCA9IGxpc3QuY3JlYXRlRWwoJ3VsJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdCcgfSk7XHJcblx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdGNvbnN0IGZvbGRlckl0ZW0gPSBhZGRGb2xkZXJMaXN0KHBsdWdpbiwgdWwsIHBhdGhCbGFja2xpc3QsIGZpbGUpO1xyXG5cdFx0XHRnb1Rocm91Z2hGb2xkZXJzKHBsdWdpbiwgZm9sZGVySXRlbSwgZmlsZSwgZGVwdGgsIHNvdXJjZUZvbGRlclBhdGgsIGN0eCwgeWFtbCwgcGF0aEJsYWNrbGlzdCwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHR9IGVsc2UgaWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRhZGRGaWxlTGlzdChwbHVnaW4sIHVsLCBwYXRoQmxhY2tsaXN0LCBmaWxlLCBpbmNsdWRlVHlwZXMsIGRpc2FibGVGaWxlVGFnKTtcclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gc29ydEZpbGVzKGZpbGVzOiBUQWJzdHJhY3RGaWxlW10sIHlhbWw6IHlhbWxTZXR0aW5ncywgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdGlmICgheWFtbD8uc29ydEJ5KSB7XHJcblx0XHR5YW1sLnNvcnRCeSA9IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc29ydEJ5IHx8ICduYW1lJztcclxuXHR9XHJcblx0cmV0dXJuIGZpbGVzLnNvcnQoKGEsIGIpID0+IHtcclxuXHRcdC8vIHNvcnQgYnkgZm9sZGVyIGZpcnN0XHJcblx0XHRpZiAoYSBpbnN0YW5jZW9mIFRGb2xkZXIgJiYgIShiIGluc3RhbmNlb2YgVEZvbGRlcikpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCEoYSBpbnN0YW5jZW9mIFRGb2xkZXIpICYmIGIgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdHJldHVybiAxO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCEoYSBpbnN0YW5jZW9mIFRGaWxlKSB8fCAhKGIgaW5zdGFuY2VvZiBURmlsZSkpIHsgcmV0dXJuIC0xOyB9XHJcblx0XHRpZiAoeWFtbC5zb3J0QnkgPT09ICdjcmVhdGVkJykge1xyXG5cdFx0XHRpZiAoYS5zdGF0LmN0aW1lID4gYi5zdGF0LmN0aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGEuc3RhdC5jdGltZSA8IGIuc3RhdC5jdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHlhbWwuc29ydEJ5ID09PSAnY3JlYXRlZEFzYycpIHtcclxuXHRcdFx0aWYgKGEuc3RhdC5jdGltZSA8IGIuc3RhdC5jdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAtMTtcclxuXHRcdFx0fSBlbHNlIGlmIChhLnN0YXQuY3RpbWUgPiBiLnN0YXQuY3RpbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gMTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIGlmICh5YW1sLnNvcnRCeSA9PT0gJ21vZGlmaWVkJykge1xyXG5cdFx0XHRpZiAoYS5zdGF0Lm10aW1lID4gYi5zdGF0Lm10aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGEuc3RhdC5tdGltZSA8IGIuc3RhdC5tdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHlhbWwuc29ydEJ5ID09PSAnbW9kaWZpZWRBc2MnKSB7XHJcblx0XHRcdGlmIChhLnN0YXQubXRpbWUgPCBiLnN0YXQubXRpbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gLTE7XHJcblx0XHRcdH0gZWxzZSBpZiAoYS5zdGF0Lm10aW1lID4gYi5zdGF0Lm10aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIDE7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdC8vIHNvcnQgYnkgbmFtZVxyXG5cdFx0aWYgKGEubmFtZSA8IGIubmFtZSAmJiB5YW1sLnNvcnRCeSA9PT0gJ25hbWUnKSB7XHJcblx0XHRcdHJldHVybiAtMTtcclxuXHRcdH0gZWxzZSBpZiAoYS5uYW1lID4gYi5uYW1lICYmIHlhbWwuc29ydEJ5ID09PSAnbmFtZUFzYycpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChhLm5hbWUgPiBiLm5hbWUgJiYgeWFtbC5zb3J0QnkgPT09ICduYW1lJykge1xyXG5cdFx0XHRyZXR1cm4gMTtcclxuXHRcdH0gZWxzZSBpZiAoYS5uYW1lIDwgYi5uYW1lICYmIHlhbWwuc29ydEJ5ID09PSAnbmFtZUFzYycpIHtcclxuXHRcdFx0cmV0dXJuIDE7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gMDtcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlRW1wdHlGb2xkZXJzKHVsOiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgZGVwdGg6IG51bWJlciwgeWFtbDogeWFtbFNldHRpbmdzKSB7XHJcblx0Y29uc3QgY2hpbGRyZW5zVG9SZW1vdmU6IENoaWxkTm9kZVtdID0gW107XHJcblx0dWwuY2hpbGROb2Rlcy5mb3JFYWNoKChlbCkgPT4ge1xyXG5cdFx0Y29uc3QgY2hpbGRyZW5zID0gKGVsIGFzIEVsZW1lbnQpLnF1ZXJ5U2VsZWN0b3IoJ3VsJyk7XHJcblx0XHRpZiAoIWNoaWxkcmVucyB8fCBjaGlsZHJlbnMgPT09IG51bGwpIHsgcmV0dXJuOyB9XHJcblx0XHRpZiAoY2hpbGRyZW5zICYmICFjaGlsZHJlbnM/Lmhhc0NoaWxkTm9kZXMoKSAmJiAhKGVsIGluc3RhbmNlb2YgSFRNTFVMaXN0RWxlbWVudCkpIHtcclxuXHRcdFx0Y2hpbGRyZW5zVG9SZW1vdmUucHVzaChlbCk7XHJcblx0XHR9IGVsc2UgaWYgKGVsIGluc3RhbmNlb2YgSFRNTFVMaXN0RWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxMSUVsZW1lbnQpIHtcclxuXHRcdFx0cmVtb3ZlRW1wdHlGb2xkZXJzKGVsLCBkZXB0aCArIDEsIHlhbWwpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cdGNoaWxkcmVuc1RvUmVtb3ZlLmZvckVhY2goKGVsKSA9PiB7XHJcblx0XHRpZiAoeWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgJiYgZGVwdGggPT09IDEpIHsgcmV0dXJuOyB9XHJcblx0XHRlbC5yZW1vdmUoKTtcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkRm9sZGVyTGlzdChwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBsaXN0OiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgcGF0aEJsYWNrbGlzdDogc3RyaW5nW10sIGZvbGRlcjogVEZvbGRlcikge1xyXG5cdGNvbnN0IGZvbGRlckl0ZW0gPSBsaXN0LmNyZWF0ZUVsKCdsaScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QgZm9sZGVyLWxpc3QnIH0pO1xyXG5cdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHBsdWdpbiwgZm9sZGVyLnBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdGNvbnN0IGZvbGRlck5vdGVMaW5rID0gZm9sZGVySXRlbS5jcmVhdGVFbCgnYScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QtaXRlbSBmb2xkZXItbmFtZS1pdGVtIGludGVybmFsLWxpbmsnLCBocmVmOiBmb2xkZXJOb3RlLnBhdGggfSk7XHJcblx0XHRmb2xkZXJOb3RlTGluay5pbm5lclRleHQgPSBmb2xkZXIubmFtZTtcclxuXHRcdHBhdGhCbGFja2xpc3QucHVzaChmb2xkZXJOb3RlLnBhdGgpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRjb25zdCBmb2xkZXJOYW1lID0gZm9sZGVySXRlbS5jcmVhdGVFbCgnc3BhbicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QtaXRlbSBmb2xkZXItbmFtZS1pdGVtJyB9KTtcclxuXHRcdGZvbGRlck5hbWUuaW5uZXJUZXh0ID0gZm9sZGVyLm5hbWU7XHJcblx0fVxyXG5cdHJldHVybiBmb2xkZXJJdGVtO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRGaWxlTGlzdChwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBsaXN0OiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgcGF0aEJsYWNrbGlzdDogc3RyaW5nW10sIGZpbGU6IFRGaWxlLCBpbmNsdWRlVHlwZXM6IHN0cmluZ1tdLCBkaXNhYmxlRmlsZVRhZzogYm9vbGVhbikge1xyXG5cdGlmIChpbmNsdWRlVHlwZXMubGVuZ3RoID4gMCAmJiAhaW5jbHVkZVR5cGVzLmluY2x1ZGVzKCdhbGwnKSkge1xyXG5cdFx0aWYgKGZpbGUuZXh0ZW5zaW9uID09PSAnbWQnICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ21hcmtkb3duJykpIHJldHVybjtcclxuXHRcdGlmIChmaWxlLmV4dGVuc2lvbiA9PT0gJ2NhbnZhcycgJiYgIWluY2x1ZGVUeXBlcy5pbmNsdWRlcygnY2FudmFzJykpIHJldHVybjtcclxuXHRcdGlmIChmaWxlLmV4dGVuc2lvbiA9PT0gJ3BkZicgJiYgIWluY2x1ZGVUeXBlcy5pbmNsdWRlcygncGRmJykpIHJldHVybjtcclxuXHRcdGNvbnN0IGltYWdlVHlwZXMgPSBbJ2pwZycsICdqcGVnJywgJ3BuZycsICdnaWYnLCAnc3ZnJywgJ3dlYnAnXTtcclxuXHRcdGlmIChpbWFnZVR5cGVzLmluY2x1ZGVzKGZpbGUuZXh0ZW5zaW9uKSAmJiAhaW5jbHVkZVR5cGVzLmluY2x1ZGVzKCdpbWFnZScpKSByZXR1cm47XHJcblx0XHRjb25zdCB2aWRlb1R5cGVzID0gWydtcDQnLCAnd2VibScsICdvZ3YnLCAnbW92JywgJ21rdiddO1xyXG5cdFx0aWYgKHZpZGVvVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ3ZpZGVvJykpIHJldHVybjtcclxuXHRcdGNvbnN0IGF1ZGlvVHlwZXMgPSBbJ21wMycsICd3YXYnLCAnbTRhJywgJzNncCcsICdmbGFjJywgJ29nZycsICdvZ2EnLCAnb3B1cyddO1xyXG5cdFx0aWYgKGF1ZGlvVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmIGluY2x1ZGVUeXBlcy5pbmNsdWRlcygnYXVkaW8nKSkgcmV0dXJuO1xyXG5cdFx0Y29uc3QgYWxsVHlwZXMgPSBbJ21kJywgJ2NhbnZhcycsICdwZGYnLCAuLi5pbWFnZVR5cGVzLCAuLi52aWRlb1R5cGVzLCAuLi5hdWRpb1R5cGVzXTtcclxuXHRcdGlmICghYWxsVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ290aGVyJykpIHJldHVybjtcclxuXHR9XHJcblx0aWYgKHBhdGhCbGFja2xpc3QuaW5jbHVkZXMoZmlsZS5wYXRoKSkgcmV0dXJuO1xyXG5cdGNvbnN0IGxpc3RJdGVtID0gbGlzdC5jcmVhdGVFbCgnbGknLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1saXN0IGZpbGUtbGluaycgfSk7XHJcblx0Y29uc3QgbmFtZUl0ZW0gPSBsaXN0SXRlbS5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdC1pdGVtJyB9KTtcclxuXHRjb25zdCBsaW5rID0gbmFtZUl0ZW0uY3JlYXRlRWwoJ2EnLCB7IGNsczogJ2ludGVybmFsLWxpbmsnLCBocmVmOiBmaWxlLnBhdGggfSk7XHJcblx0bGluay5pbm5lclRleHQgPSBmaWxlLmJhc2VuYW1lO1xyXG5cdGlmIChmaWxlLmV4dGVuc2lvbiAhPT0gJ21kJyAmJiAhZGlzYWJsZUZpbGVUYWcpIHtcclxuXHRcdG5hbWVJdGVtLmNyZWF0ZURpdih7IGNsczogJ25hdi1maWxlLXRhZycgfSkuaW5uZXJUZXh0ID0gZmlsZS5leHRlbnNpb247XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRBbGxGaWxlcyhmaWxlczogVEFic3RyYWN0RmlsZVtdLCBzb3VyY2VGb2xkZXJQYXRoOiBzdHJpbmcsIGRlcHRoOiBudW1iZXIpIHtcclxuXHRjb25zdCBhbGxGaWxlczogVEFic3RyYWN0RmlsZVtdID0gW107XHJcblx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdGlmICgoZmlsZS5wYXRoLnNwbGl0KCcvJykubGVuZ3RoIC0gc291cmNlRm9sZGVyUGF0aC5zcGxpdCgnLycpLmxlbmd0aCkgLSAxIDwgZGVwdGggLSAxKSB7XHJcblx0XHRcdFx0YWxsRmlsZXMucHVzaCguLi5nZXRBbGxGaWxlcyhmaWxlLmNoaWxkcmVuLCBzb3VyY2VGb2xkZXJQYXRoLCBkZXB0aCkpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRhbGxGaWxlcy5wdXNoKGZpbGUpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cdHJldHVybiBhbGxGaWxlcztcclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZywgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgc3RyaW5naWZ5WWFtbCwgVEZpbGUgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IHlhbWxTZXR0aW5ncyB9IGZyb20gJ3NyYy9mb2xkZXJPdmVydmlldyc7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IExpc3RDb21wb25lbnQgZnJvbSAnc3JjL2Z1bmN0aW9ucy9MaXN0Q29tcG9uZW50JztcclxuZXhwb3J0IGNsYXNzIEZvbGRlck92ZXJ2aWV3U2V0dGluZ3MgZXh0ZW5kcyBNb2RhbCB7XHJcblx0cGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbjtcclxuXHRhcHA6IEFwcDtcclxuXHR5YW1sOiB5YW1sU2V0dGluZ3M7XHJcblx0Y3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0O1xyXG5cdGVsOiBIVE1MRWxlbWVudDtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgeWFtbDogeWFtbFNldHRpbmdzLCBjdHg6IE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIGVsOiBIVE1MRWxlbWVudCkge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLnlhbWwgPSB5YW1sO1xyXG5cdFx0dGhpcy5jdHggPSBjdHg7XHJcblx0XHR0aGlzLmVsID0gZWw7XHJcblx0XHRpZiAoIXRoaXMueWFtbCkge1xyXG5cdFx0XHR0aGlzLnlhbWwgPSB7XHJcblx0XHRcdFx0dGl0bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSxcclxuXHRcdFx0XHRkaXNhYmxlVGl0bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kaXNhYmxlVGl0bGUsXHJcblx0XHRcdFx0ZGVwdGg6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kZXB0aCxcclxuXHRcdFx0XHR0eXBlOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcudHlwZSxcclxuXHRcdFx0XHRpbmNsdWRlVHlwZXM6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5pbmNsdWRlVHlwZXMsXHJcblx0XHRcdFx0c3R5bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5zdHlsZSxcclxuXHRcdFx0XHRkaXNhYmxlRmlsZVRhZzogdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnLFxyXG5cdFx0XHRcdHNvcnRCeTogdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNvcnRCeSxcclxuXHRcdFx0XHRzaG93RW1wdHlGb2xkZXJzOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc2hvd0VtcHR5Rm9sZGVycyxcclxuXHRcdFx0XHRvbmx5SW5jbHVkZVN1YmZvbGRlcnM6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5vbmx5SW5jbHVkZVN1YmZvbGRlcnMsXHJcblx0XHRcdH07XHJcblx0XHR9XHJcblx0fVxyXG5cdG9uT3BlbigpIHtcclxuXHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdH1cclxuXHRkaXNwbGF5KCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcclxuXHRcdC8vIGNsb3NlIHdoZW4gdXNlciBwcmVzc2VzIGVudGVyXHJcblx0XHRjb250ZW50RWwuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XHJcblx0XHRcdGlmIChlLmtleSA9PT0gJ0VudGVyJykge1xyXG5cdFx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnRm9sZGVyIG92ZXJ2aWV3IHNldHRpbmdzJyB9KTtcclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0Rpc2FibGUgdGhlIHRpdGxlJylcclxuXHRcdFx0LnNldERlc2MoJ0Nob29zZSBpZiB0aGUgdGl0bGUgc2hvdWxkIGJlIHNob3duJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5kaXNhYmxlVGl0bGUgfHwgZmFsc2UpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5kaXNhYmxlVGl0bGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdGlmICghdGhpcy55YW1sLmRpc2FibGVUaXRsZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ1RpdGxlJylcclxuXHRcdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHRoZSB0aXRsZSBvZiB0aGUgZm9sZGVyIG92ZXJ2aWV3JylcclxuXHRcdFx0XHQuYWRkVGV4dCgodGV4dCkgPT5cclxuXHRcdFx0XHRcdHRleHRcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8udGl0bGUgfHwgJ3t7Zm9sZGVyTmFtZX19IG92ZXJ2aWV3JylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMueWFtbC50aXRsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblx0XHR9XHJcblx0XHRjb25zdCBzZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGVudEVsKTtcclxuXHRcdHNldHRpbmcuc2V0TmFtZSgnSW5jbHVkZSB0eXBlcycpO1xyXG5cdFx0Y29uc3QgbGlzdCA9IHNldHRpbmcuY3JlYXRlTGlzdCgobGlzdDogTGlzdENvbXBvbmVudCkgPT5cclxuXHRcdFx0bGlzdFxyXG5cdFx0XHRcdC5hZGRNb2RhbCh0aGlzKVxyXG5cdFx0XHRcdC5zZXRWYWx1ZXModGhpcy55YW1sPy5pbmNsdWRlVHlwZXMgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyB8fCBbXSlcclxuXHRcdFx0XHQuYWRkUmVzZXRCdXR0b24oKVxyXG5cdFx0KTtcclxuXHRcdGlmICgodGhpcy55YW1sPy5pbmNsdWRlVHlwZXM/Lmxlbmd0aCB8fCAwKSA8IDggJiYgIXRoaXMueWFtbC5pbmNsdWRlVHlwZXM/LmluY2x1ZGVzKCdhbGwnKSkge1xyXG5cdFx0XHRzZXR0aW5nLmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xyXG5cdFx0XHRcdGlmICghdGhpcy55YW1sLmluY2x1ZGVUeXBlcykgdGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5pbmNsdWRlVHlwZXMgfHwgW107XHJcblx0XHRcdFx0dGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMueWFtbC5pbmNsdWRlVHlwZXMubWFwKCh0eXBlOiBzdHJpbmcpID0+IHR5cGUudG9Mb3dlckNhc2UoKSk7XHJcblx0XHRcdFx0Y29uc3Qgb3B0aW9ucyA9IFtcclxuXHRcdFx0XHRcdHsgdmFsdWU6ICdtYXJrZG93bicsIGxhYmVsOiAnTWFya2Rvd24nIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnZm9sZGVyJywgbGFiZWw6ICdGb2xkZXInIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnY2FudmFzJywgbGFiZWw6ICdDYW52YXMnIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAncGRmJywgbGFiZWw6ICdQREYnIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnaW1hZ2UnLCBsYWJlbDogJ0ltYWdlJyB9LFxyXG5cdFx0XHRcdFx0eyB2YWx1ZTogJ2F1ZGlvJywgbGFiZWw6ICdBdWRpbycgfSxcclxuXHRcdFx0XHRcdHsgdmFsdWU6ICd2aWRlbycsIGxhYmVsOiAnVmlkZW8nIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnb3RoZXInLCBsYWJlbDogJ0FsbCBvdGhlciBmaWxlIHR5cGVzJyB9LFxyXG5cdFx0XHRcdFx0eyB2YWx1ZTogJ2FsbCcsIGxhYmVsOiAnQWxsIGZpbGUgdHlwZXMnIH0sXHJcblx0XHRcdFx0XTtcclxuXHJcblx0XHRcdFx0b3B0aW9ucy5mb3JFYWNoKChvcHRpb24pID0+IHtcclxuXHRcdFx0XHRcdGlmICghdGhpcy55YW1sLmluY2x1ZGVUeXBlcz8uaW5jbHVkZXMob3B0aW9uLnZhbHVlKSkge1xyXG5cdFx0XHRcdFx0XHRkcm9wZG93bi5hZGRPcHRpb24ob3B0aW9uLnZhbHVlLCBvcHRpb24ubGFiZWwpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignKycsICcrJyk7XHJcblx0XHRcdFx0ZHJvcGRvd24uc2V0VmFsdWUoJysnKTtcclxuXHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdGlmICh2YWx1ZSA9PT0gJ2FsbCcpIHtcclxuXHRcdFx0XHRcdFx0dGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMueWFtbC5pbmNsdWRlVHlwZXM/LmZpbHRlcigodHlwZTogc3RyaW5nKSA9PiB0eXBlID09PSAnZm9sZGVyJyk7XHJcblx0XHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdFx0XHRcdFx0bGlzdC5zZXRWYWx1ZXModGhpcy55YW1sLmluY2x1ZGVUeXBlcyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXHJcblx0XHRcdFx0XHRhd2FpdCBsaXN0LmFkZFZhbHVlKHZhbHVlLnRvTG93ZXJDYXNlKCkpO1xyXG5cdFx0XHRcdFx0YXdhaXQgdGhpcy51cGRhdGVZYW1sKCk7XHJcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHRsZXQgZGlzYWJsZUZpbGVUYWc7XHJcblx0XHR0aGlzLnlhbWwuaW5jbHVkZVR5cGVzPy5mb3JFYWNoKCh0eXBlOiBzdHJpbmcpID0+IHtcclxuXHRcdFx0dHlwZSA9PT0gJ2ZvbGRlcicgfHwgdHlwZSA9PT0gJ21hcmtkb3duJyA/IChkaXNhYmxlRmlsZVRhZyA9IHRydWUpIDogbnVsbDtcclxuXHRcdH0pO1xyXG5cdFx0aWYgKGRpc2FibGVGaWxlVGFnKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBmaWxlIHRhZycpXHJcblx0XHRcdFx0LnNldERlc2MoJ0Nob29zZSBpZiB0aGUgZmlsZSB0YWcgc2hvdWxkIGJlIHNob3duIGFmdGVyIHRoZSBmaWxlIG5hbWUnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnlhbWwuZGlzYWJsZUZpbGVUYWcgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnIHx8IGZhbHNlKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy55YW1sLmRpc2FibGVGaWxlVGFnID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy51cGRhdGVZYW1sKCk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0ZpbGUgZGVwdGgnKVxyXG5cdFx0XHQuc2V0RGVzYygnRmlsZSAmIGZvbGRlciA9ICsxIGRlcHRoJylcclxuXHRcdFx0LmFkZFNsaWRlcigoc2xpZGVyKSA9PlxyXG5cdFx0XHRcdHNsaWRlclxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8uZGVwdGggfHwgMilcclxuXHRcdFx0XHRcdC5zZXRMaW1pdHMoMSwgMTAsIDEpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5kZXB0aCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnT3ZlcnZpZXcgc3R5bGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHRoZSBzdHlsZSBvZiB0aGUgb3ZlcnZpZXcgKGdyaWQgc3R5bGUgc29vbiknKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCdsaXN0JywgJ0xpc3QnKVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8uc3R5bGUgfHwgJ2xpc3QnKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogJ2xpc3QnKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5zdHlsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnU29ydCBmaWxlcyBieScpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaG93IHRoZSBmaWxlcyBzaG91bGQgYmUgc29ydGVkJylcclxuXHRcdFx0LmFkZERyb3Bkb3duKChkcm9wZG93bikgPT5cclxuXHRcdFx0XHRkcm9wZG93blxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbmFtZScsICdOYW1lIGRlc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignY3JlYXRlZCcsICdDcmVhdGVkIGRlc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbW9kaWZpZWQnLCAnTW9kaWZpZWQgZGVzY2VuZGluZycpXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCduYW1lQXNjJywgJ05hbWUgYXNjZW5kaW5nJylcclxuXHRcdFx0XHRcdC5hZGRPcHRpb24oJ2NyZWF0ZWRBc2MnLCAnQ3JlYXRlZCBhc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbW9kaWZpZWRBc2MnLCAnTW9kaWZpZWQgYXNjZW5kaW5nJylcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnlhbWw/LnNvcnRCeSB8fCAnbmFtZScpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiAnbmFtZScgfCAnY3JlYXRlZCcgfCAnbW9kaWZpZWQnIHwgJ25hbWVBc2MnIHwgJ2NyZWF0ZWRBc2MnIHwgJ21vZGlmaWVkQXNjJykgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwuc29ydEJ5ID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdTaG93IGZvbGRlciBuYW1lcyBvZiBlbXB0eSBmb2xkZXJzJylcclxuXHRcdFx0LnNldERlc2MoJ1RoYXQgaW5jbHVkZXMgc3ViZm9sZGVycyBvZiB0aGUgY3VycmVudCBmb2xkZXIgd2hlbiB5b3UgYXJlIG9uIGZpbGUgZGVwdGggMScpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5zaG93RW1wdHlGb2xkZXJzIHx8IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5zaG93RW1wdHlGb2xkZXJzIHx8IGZhbHNlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwuc2hvd0VtcHR5Rm9sZGVycyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwub25seUluY2x1ZGVTdWJmb2xkZXJzID0gZmFsc2U7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRpZiAodGhpcy55YW1sLnNob3dFbXB0eUZvbGRlcnMpIHtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdPbmx5IHNob3cgZmlyc3QgZW1wdHkgc3ViZm9sZGVycyBvZiBjdXJyZW50IGZvbGRlcicpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3Lm9ubHlJbmNsdWRlU3ViZm9sZGVycyB8fCBmYWxzZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMueWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG5cdGFzeW5jIHVwZGF0ZVlhbWwoKSB7XHJcblx0XHRjb25zdCBmaWxlID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aCh0aGlzLmN0eC5zb3VyY2VQYXRoKTtcclxuXHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHRcdGxldCBzdHJpbmdZYW1sID0gc3RyaW5naWZ5WWFtbCh0aGlzLnlhbWwpO1xyXG5cdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LnByb2Nlc3MoZmlsZSwgKHRleHQpID0+IHtcclxuXHRcdFx0Y29uc3QgaW5mbyA9IHRoaXMuY3R4LmdldFNlY3Rpb25JbmZvKHRoaXMuZWwpO1xyXG5cdFx0XHQvLyBjaGVjayBpZiBzdHJpbmdZYW1sIGVuZHMgd2l0aCBhIG5ld2xpbmVcclxuXHRcdFx0aWYgKHN0cmluZ1lhbWxbc3RyaW5nWWFtbC5sZW5ndGggLSAxXSAhPT0gJ1xcbicpIHtcclxuXHRcdFx0XHRzdHJpbmdZYW1sICs9ICdcXG4nO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChpbmZvKSB7XHJcblx0XHRcdFx0Y29uc3QgeyBsaW5lU3RhcnQgfSA9IGluZm87XHJcblx0XHRcdFx0Y29uc3QgbGluZUVuZCA9IHRoaXMuZ2V0Q29kZUJsb2NrRW5kTGluZSh0ZXh0LCBsaW5lU3RhcnQpO1xyXG5cdFx0XHRcdGlmIChsaW5lRW5kID09PSAtMSB8fCAhbGluZUVuZCkgcmV0dXJuIHRleHQ7XHJcblx0XHRcdFx0Y29uc3QgbGluZUxlbmd0aCA9IGxpbmVFbmQgLSBsaW5lU3RhcnQ7XHJcblx0XHRcdFx0Y29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcclxuXHRcdFx0XHRsaW5lcy5zcGxpY2UobGluZVN0YXJ0LCBsaW5lTGVuZ3RoICsgMSwgYFxcYFxcYFxcYGZvbGRlci1vdmVydmlld1xcbiR7c3RyaW5nWWFtbH1cXGBcXGBcXGBgKTtcclxuXHRcdFx0XHRyZXR1cm4gbGluZXMuam9pbignXFxuJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGBcXGBcXGBcXGBmb2xkZXItb3ZlcnZpZXdcXG4ke3N0cmluZ1lhbWx9XFxgXFxgXFxgYDtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRnZXRDb2RlQmxvY2tFbmRMaW5lKHRleHQ6IHN0cmluZywgc3RhcnRMaW5lOiBudW1iZXIsIGNvdW50ID0gMSkge1xyXG5cdFx0bGV0IGxpbmUgPSBzdGFydExpbmUgKyAxO1xyXG5cdFx0Y29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcclxuXHRcdHdoaWxlIChsaW5lIDwgbGluZXMubGVuZ3RoKSB7XHJcblx0XHRcdGlmIChjb3VudCA+IDIwKSB7IHJldHVybiAtMTsgfVxyXG5cdFx0XHRpZiAobGluZXNbbGluZV0uc3RhcnRzV2l0aCgnYGBgJykpIHtcclxuXHRcdFx0XHRyZXR1cm4gbGluZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRsaW5lKys7XHJcblx0XHRcdGNvdW50Kys7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbGluZTtcclxuXHR9XHJcbn1cclxuXHJcbiIsICJpbXBvcnQgeyBTZXR0aW5nIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBGb2xkZXJPdmVydmlld1NldHRpbmdzIH0gZnJvbSAnLi4vbW9kYWxzL2ZvbGRlck92ZXJ2aWV3JztcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGlzdENvbXBvbmVudCB7XHJcblx0Y29udGFpbmVyRWw6IEhUTUxFbGVtZW50O1xyXG5cdGNvbnRyb2xFbDogSFRNTEVsZW1lbnQ7XHJcblx0ZW1wdHlTdGF0ZUVsOiBIVE1MRWxlbWVudDtcclxuXHRsaXN0RWw6IEhUTUxFbGVtZW50O1xyXG5cdHZhbHVlczogc3RyaW5nW107XHJcblx0bW9kYWw6IEZvbGRlck92ZXJ2aWV3U2V0dGluZ3M7XHJcblx0Y29uc3RydWN0b3IoY29udGFpbmVyRWw6IEhUTUxFbGVtZW50KSB7XHJcblx0XHR0aGlzLmNvbnRhaW5lckVsID0gY29udGFpbmVyRWw7XHJcblx0XHR0aGlzLmNvbnRyb2xFbCA9IGNvbnRhaW5lckVsLnF1ZXJ5U2VsZWN0b3IoJy5zZXR0aW5nLWl0ZW0tY29udHJvbCcpIHx8IGNvbnRhaW5lckVsO1xyXG5cdFx0dGhpcy5saXN0RWwgPSB0aGlzLmNvbnRyb2xFbC5jcmVhdGVEaXYoJ3NldHRpbmctY29tbWFuZC1ob3RrZXlzJyk7XHJcblx0fVxyXG5cdGFkZE1vZGFsKG1vZGFsOiBGb2xkZXJPdmVydmlld1NldHRpbmdzKSB7XHJcblx0XHR0aGlzLm1vZGFsID0gbW9kYWw7XHJcblx0XHR0aGlzLnZhbHVlcyA9IG1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzIHx8IFtdO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdHNldFZhbHVlcyh2YWx1ZXM6IHN0cmluZ1tdKSB7XHJcblx0XHR0aGlzLmxpc3RFbC5lbXB0eSgpO1xyXG5cdFx0dGhpcy52YWx1ZXMgPSB2YWx1ZXM7XHJcblx0XHR0aGlzLm1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzID0gdmFsdWVzO1xyXG5cdFx0aWYgKHZhbHVlcy5sZW5ndGggIT09IDApIHtcclxuXHRcdFx0dmFsdWVzLmZvckVhY2goKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0dGhpcy5hZGRFbGVtZW50KHZhbHVlKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHR0aGlzLm1vZGFsLnVwZGF0ZVlhbWwoKTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHRhZGRFbGVtZW50KHZhbHVlOiBzdHJpbmcpIHtcclxuXHRcdHRoaXMubGlzdEVsLmNyZWF0ZVNwYW4oJ3NldHRpbmctaG90a2V5JywgKHNwYW4pID0+IHtcclxuXHRcdFx0c3Bhbi5pbm5lclRleHQgPSB2YWx1ZTtcclxuXHRcdFx0Y29uc3QgcmVtb3ZlU3BhbiA9IHNwYW4uY3JlYXRlRWwoJ3NwYW4nLCB7IGNsczogJ29mbi1saXN0LWl0ZW0tcmVtb3ZlIHNldHRpbmctaG90a2V5LWljb24nIH0pO1xyXG5cdFx0XHQvLyBhZGQgc3ZnIGljb25cclxuXHRcdFx0Y29uc3Qgc3ZnID0gJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBjbGFzcz1cInN2Zy1pY29uIGx1Y2lkZS14XCI+PGxpbmUgeDE9XCIxOFwiIHkxPVwiNlwiIHgyPVwiNlwiIHkyPVwiMThcIj48L2xpbmU+PGxpbmUgeDE9XCI2XCIgeTE9XCI2XCIgeDI9XCIxOFwiIHkyPVwiMThcIj48L2xpbmU+PC9zdmc+JztcclxuXHRcdFx0Y29uc3Qgc3ZnRWxlbWVudCA9IHJlbW92ZVNwYW4uY3JlYXRlRWwoJ3NwYW4nLCB7IGNsczogJ29mbi1saXN0LWl0ZW0tcmVtb3ZlLWljb24nIH0pO1xyXG5cdFx0XHRzdmdFbGVtZW50LmlubmVySFRNTCA9IHN2ZztcclxuXHRcdFx0cmVtb3ZlU3Bhbi5vbkNsaWNrRXZlbnQoKGUpID0+IHtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZVZhbHVlKHZhbHVlKTtcclxuXHRcdFx0XHRzcGFuLnJlbW92ZSgpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRhc3luYyBhZGRWYWx1ZSh2YWx1ZTogc3RyaW5nKSB7XHJcblx0XHR0aGlzLnZhbHVlcy5wdXNoKHZhbHVlKTtcclxuXHRcdHRoaXMuYWRkRWxlbWVudCh2YWx1ZSk7XHJcblx0XHR0aGlzLm1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzID0gdGhpcy52YWx1ZXM7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0YWRkUmVzZXRCdXR0b24oKSB7XHJcblx0XHRjb25zdCByZXNldEJ1dHRvbiA9IHRoaXMuY29udHJvbEVsLmNyZWF0ZUVsKCdzcGFuJywgeyBjbHM6ICdjbGlja2FibGUtaWNvbiBzZXR0aW5nLXJlc3RvcmUtaG90a2V5LWJ1dHRvbicgfSk7XHJcblx0XHRjb25zdCBzdmcgPSAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIGNsYXNzPVwic3ZnLWljb24gbHVjaWRlLXJvdGF0ZS1jY3dcIj48cGF0aCBkPVwiTTMgMnY2aDZcIj48L3BhdGg+PHBhdGggZD1cIk0zIDEzYTkgOSAwIDEgMCAzLTcuN0wzIDhcIj48L3BhdGg+PC9zdmc+JztcclxuXHRcdHJlc2V0QnV0dG9uLmlubmVySFRNTCA9IHN2ZztcclxuXHRcdHJlc2V0QnV0dG9uLm9uQ2xpY2tFdmVudCgoZSkgPT4ge1xyXG5cdFx0XHR0aGlzLm1vZGFsLnBsdWdpbi5sb2FkU2V0dGluZ3MoKTtcclxuXHRcdFx0dGhpcy5zZXRWYWx1ZXModGhpcy5tb2RhbC5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyB8fCBbXSk7XHJcblx0XHRcdHRoaXMubW9kYWwuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0cmVtb3ZlVmFsdWUodmFsdWU6IHN0cmluZykge1xyXG5cdFx0dGhpcy52YWx1ZXMgPSB0aGlzLnZhbHVlcy5maWx0ZXIoKHYpID0+IHYgIT09IHZhbHVlKTtcclxuXHRcdHRoaXMuc2V0VmFsdWVzKHRoaXMudmFsdWVzKTtcclxuXHRcdHRoaXMubW9kYWwuZGlzcGxheSgpO1xyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlTGlzdCh0aGlzOiBTZXR0aW5nLCBjYjogKGxpc3Q6IExpc3RDb21wb25lbnQpID0+IExpc3RDb21wb25lbnQpIHtcclxuXHRjb25zdCBsaXN0ID0gbmV3IExpc3RDb21wb25lbnQodGhpcy5zZXR0aW5nRWwpO1xyXG5cdGNiKGxpc3QpO1xyXG5cdHJldHVybiBsaXN0O1xyXG59XHJcblxyXG4vLyBMaXN0Q29tcG9uZW50LnByb3RvdHlwZS5zZXRWYWx1ZXMgPSBzZXRWYWx1ZXM7XHJcbihTZXR0aW5nIGFzIGFueSkucHJvdG90eXBlLmNyZWF0ZUxpc3QgPSBjcmVhdGVMaXN0O1xyXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFDQSxXQUFPLGVBQWUsU0FBUyxjQUFjLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFBQTtBQUFBOzs7QUNENUQ7QUFBQTtBQUFBO0FBQ0EsV0FBTyxlQUFlLFNBQVMsY0FBYyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQUE7QUFBQTs7O0FDRDVEO0FBQUE7QUFBQTtBQUNBLFdBQU8sZUFBZSxTQUFTLGNBQWMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUFBO0FBQUE7OztBQ0Q1RDtBQUFBO0FBQUE7QUFDQSxRQUFJLGtCQUFtQixXQUFRLFFBQUssbUJBQXFCLFFBQU8sU0FBVSxTQUFTLEdB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QUFrQixFQUFFLFFBQVEsQ0FBQyxTQUFTO0FBQ3BELFVBQUksQ0FBRSxpQkFBZ0IsNEJBQVU7QUFBRTtBQUFBLE1BQVE7QUFDMUMsWUFBTSxhQUFhLGNBQWMsTUFBTSxLQUFLLElBQUk7QUFDaEQsVUFBSSxDQUFDLFlBQVk7QUFDaEIsYUFBSyxxQkFBcUIsNkJBQU0sTUFBTSxpQkFBaUI7QUFDdkQ7QUFBQSxNQUNEO0FBRUEsWUFBTSxpQkFBaUIsa0JBQWtCLE1BQU0sS0FBSyxJQUFJO0FBR3hELFVBQUksaURBQWdCLG1CQUFtQjtBQUN0QyxhQUFLLHFCQUFxQixXQUFXLE1BQU0sZ0JBQWdCO0FBQzNELGFBQUsscUJBQXFCLEtBQUssTUFBTSxpQkFBaUI7QUFBQSxNQUN2RCxPQUFPO0FBQ04sYUFBSyxxQkFBcUIsV0FBVyxNQUFNLGdCQUFnQjtBQUMzRCxhQUFLLHFCQUFxQixLQUFLLE1BQU0saUJBQWlCO0FBQUEsTUFDdkQ7QUFBQSxJQUNELENBQUM7QUFBQSxFQUNGO0FBQUEsRUFFQSxpQkFBaUI7QUFDaEIsYUFBUyxpQkFBaUIsOEJBQThCLEVBQ3RELFFBQVEsQ0FBQyxZQUF5QjtBQUNsQyxVQUFJLFFBQVE7QUFBUztBQUNyQixjQUFRLFVBQVUsQ0FBQyxVQUFzQixrQkFBa0IsT0FBTyxJQUFJO0FBQUEsSUFDdkUsQ0FBQztBQUFBLEVBQ0g7QUFBQSxFQUVBLFdBQVc7QUFDVixZQUFRLElBQUksK0JBQStCO0FBQzNDLFNBQUssU0FBUyxXQUFXO0FBQ3pCLGFBQVMsS0FBSyxVQUFVLE9BQU8scUJBQXFCO0FBQ3BELGFBQVMsS0FBSyxVQUFVLE9BQU8sdUJBQXVCO0FBQ3RELGFBQVMsS0FBSyxVQUFVLE9BQU8sa0JBQWtCO0FBQ2pELGFBQVMsS0FBSyxVQUFVLE9BQU8sK0JBQStCO0FBQzlELFFBQUksS0FBSyxpQkFBaUI7QUFBRSxXQUFLLGdCQUFnQixZQUFZLFdBQVc7QUFBQSxJQUFHO0FBQzNFLFFBQUksS0FBSyxhQUFhO0FBQ3JCLFdBQUssWUFBWSxZQUFZO0FBQUEsSUFDOUI7QUFBQSxFQUVEO0FBQUEsRUFFQSxNQUFNLGVBQWU7QUFDcEIsU0FBSyxXQUFXLE9BQU8sT0FBTyxDQUFDLEdBQUcsa0JBQWtCLE1BQU0sS0FBSyxTQUFTLENBQUM7QUFBQSxFQUMxRTtBQUFBLEVBRUEsTUFBTSxlQUFlO0FBQ3BCLFVBQU0sS0FBSyxTQUFTLEtBQUssUUFBUTtBQUVqQyxTQUFLLGdCQUFnQixJQUFJO0FBQUEsRUFDMUI7QUFDRDsiLAogICJuYW1lcyI6IFtdCn0K