|
|
'use strict';
|
|
|
|
|
|
var obsidian_module = require('obsidian');
|
|
|
var child_process = require('child_process');
|
|
|
var util = require('util');
|
|
|
var fs = require('fs');
|
|
|
var path = require('path');
|
|
|
|
|
|
function _interopNamespace(e) {
|
|
|
if (e && e.__esModule) return e;
|
|
|
var n = Object.create(null);
|
|
|
if (e) {
|
|
|
Object.keys(e).forEach(function (k) {
|
|
|
if (k !== 'default') {
|
|
|
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
|
Object.defineProperty(n, k, d.get ? d : {
|
|
|
enumerable: true,
|
|
|
get: function () {
|
|
|
return e[k];
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
n['default'] = e;
|
|
|
return Object.freeze(n);
|
|
|
}
|
|
|
|
|
|
var obsidian_module__namespace = /*#__PURE__*/_interopNamespace(obsidian_module);
|
|
|
|
|
|
/*! *****************************************************************************
|
|
|
Copyright (c) Microsoft Corporation.
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
|
purpose with or without fee is hereby granted.
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|
|
***************************************************************************** */
|
|
|
|
|
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function log_error(e) {
|
|
|
const notice = new obsidian_module.Notice("", 8000);
|
|
|
if (e instanceof TemplaterError && e.console_msg) {
|
|
|
// TODO: Find a better way for this
|
|
|
// @ts-ignore
|
|
|
notice.noticeEl.innerHTML = `<b>Templater Error</b>:<br/>${e.message}<br/>Check console for more informations`;
|
|
|
console.error(`Templater Error:`, e.message, "\n", e.console_msg);
|
|
|
}
|
|
|
else {
|
|
|
// @ts-ignore
|
|
|
notice.noticeEl.innerHTML = `<b>Templater Error</b>:<br/>${e.message}`;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class TemplaterError extends Error {
|
|
|
constructor(msg, console_msg) {
|
|
|
super(msg);
|
|
|
this.console_msg = console_msg;
|
|
|
this.name = this.constructor.name;
|
|
|
Error.captureStackTrace(this, this.constructor);
|
|
|
}
|
|
|
}
|
|
|
function errorWrapper(fn, msg) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
try {
|
|
|
return yield fn();
|
|
|
}
|
|
|
catch (e) {
|
|
|
if (!(e instanceof TemplaterError)) {
|
|
|
log_error(new TemplaterError(msg, e.message));
|
|
|
}
|
|
|
else {
|
|
|
log_error(e);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
function errorWrapperSync(fn, msg) {
|
|
|
try {
|
|
|
return fn();
|
|
|
}
|
|
|
catch (e) {
|
|
|
log_error(new TemplaterError(msg, e.message));
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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]);
|
|
|
}, []); // modifiers that need to read the DOM
|
|
|
|
|
|
var beforeRead = 'beforeRead';
|
|
|
var read = 'read';
|
|
|
var afterRead = 'afterRead'; // pure-logic modifiers
|
|
|
|
|
|
var beforeMain = 'beforeMain';
|
|
|
var main = 'main';
|
|
|
var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)
|
|
|
|
|
|
var beforeWrite = 'beforeWrite';
|
|
|
var write = 'write';
|
|
|
var afterWrite = 'afterWrite';
|
|
|
var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];
|
|
|
|
|
|
function getNodeName(element) {
|
|
|
return element ? (element.nodeName || '').toLowerCase() : null;
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
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) {
|
|
|
// IE 11 has no ShadowRoot
|
|
|
if (typeof ShadowRoot === 'undefined') {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
var OwnElement = getWindow(node).ShadowRoot;
|
|
|
return node instanceof OwnElement || node instanceof ShadowRoot;
|
|
|
}
|
|
|
|
|
|
// and applies them to the HTMLElements such as popper and arrow
|
|
|
|
|
|
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]; // arrow is optional + virtual elements
|
|
|
|
|
|
if (!isHTMLElement(element) || !getNodeName(element)) {
|
|
|
return;
|
|
|
} // Flow doesn't support to extend this property, but it's the most
|
|
|
// effective way to apply styles to an HTMLElement
|
|
|
// $FlowFixMe[cannot-write]
|
|
|
|
|
|
|
|
|
Object.assign(element.style, style);
|
|
|
Object.keys(attributes).forEach(function (name) {
|
|
|
var value = attributes[name];
|
|
|
|
|
|
if (value === false) {
|
|
|
element.removeAttribute(name);
|
|
|
} else {
|
|
|
element.setAttribute(name, value === true ? '' : value);
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function effect$2(_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]); // Set all values to an empty string to unset them
|
|
|
|
|
|
var style = styleProperties.reduce(function (style, property) {
|
|
|
style[property] = '';
|
|
|
return style;
|
|
|
}, {}); // arrow is optional + virtual elements
|
|
|
|
|
|
if (!isHTMLElement(element) || !getNodeName(element)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
Object.assign(element.style, style);
|
|
|
Object.keys(attributes).forEach(function (attribute) {
|
|
|
element.removeAttribute(attribute);
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
} // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
|
|
|
var applyStyles$1 = {
|
|
|
name: 'applyStyles',
|
|
|
enabled: true,
|
|
|
phase: 'write',
|
|
|
fn: applyStyles,
|
|
|
effect: effect$2,
|
|
|
requires: ['computeStyles']
|
|
|
};
|
|
|
|
|
|
function getBasePlacement(placement) {
|
|
|
return placement.split('-')[0];
|
|
|
}
|
|
|
|
|
|
var max = Math.max;
|
|
|
var min = Math.min;
|
|
|
var round = Math.round;
|
|
|
|
|
|
function getBoundingClientRect(element, includeScale) {
|
|
|
if (includeScale === void 0) {
|
|
|
includeScale = false;
|
|
|
}
|
|
|
|
|
|
var rect = element.getBoundingClientRect();
|
|
|
var scaleX = 1;
|
|
|
var scaleY = 1;
|
|
|
|
|
|
if (isHTMLElement(element) && includeScale) {
|
|
|
var offsetHeight = element.offsetHeight;
|
|
|
var offsetWidth = element.offsetWidth; // Do not attempt to divide by 0, otherwise we get `Infinity` as scale
|
|
|
// Fallback to 1 in case both values are `0`
|
|
|
|
|
|
if (offsetWidth > 0) {
|
|
|
scaleX = round(rect.width) / offsetWidth || 1;
|
|
|
}
|
|
|
|
|
|
if (offsetHeight > 0) {
|
|
|
scaleY = round(rect.height) / offsetHeight || 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
width: rect.width / scaleX,
|
|
|
height: rect.height / scaleY,
|
|
|
top: rect.top / scaleY,
|
|
|
right: rect.right / scaleX,
|
|
|
bottom: rect.bottom / scaleY,
|
|
|
left: rect.left / scaleX,
|
|
|
x: rect.left / scaleX,
|
|
|
y: rect.top / scaleY
|
|
|
};
|
|
|
}
|
|
|
|
|
|
// means it doesn't take into account transforms.
|
|
|
|
|
|
function getLayoutRect(element) {
|
|
|
var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.
|
|
|
// Fixes https://github.com/popperjs/popper-core/issues/1223
|
|
|
|
|
|
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: width,
|
|
|
height: height
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function contains(parent, child) {
|
|
|
var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method
|
|
|
|
|
|
if (parent.contains(child)) {
|
|
|
return true;
|
|
|
} // then fallback to custom implementation with Shadow DOM support
|
|
|
else if (rootNode && isShadowRoot(rootNode)) {
|
|
|
var next = child;
|
|
|
|
|
|
do {
|
|
|
if (next && parent.isSameNode(next)) {
|
|
|
return true;
|
|
|
} // $FlowFixMe[prop-missing]: need a better way to handle this...
|
|
|
|
|
|
|
|
|
next = next.parentNode || next.host;
|
|
|
} while (next);
|
|
|
} // Give up, the result is false
|
|
|
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
function getComputedStyle(element) {
|
|
|
return getWindow(element).getComputedStyle(element);
|
|
|
}
|
|
|
|
|
|
function isTableElement(element) {
|
|
|
return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;
|
|
|
}
|
|
|
|
|
|
function getDocumentElement(element) {
|
|
|
// $FlowFixMe[incompatible-return]: assume body is always available
|
|
|
return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]
|
|
|
element.document) || window.document).documentElement;
|
|
|
}
|
|
|
|
|
|
function getParentNode(element) {
|
|
|
if (getNodeName(element) === 'html') {
|
|
|
return element;
|
|
|
}
|
|
|
|
|
|
return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle
|
|
|
// $FlowFixMe[incompatible-return]
|
|
|
// $FlowFixMe[prop-missing]
|
|
|
element.assignedSlot || // step into the shadow DOM of the parent of a slotted node
|
|
|
element.parentNode || ( // DOM Element detected
|
|
|
isShadowRoot(element) ? element.host : null) || // ShadowRoot detected
|
|
|
// $FlowFixMe[incompatible-call]: HTMLElement is a Node
|
|
|
getDocumentElement(element) // fallback
|
|
|
|
|
|
);
|
|
|
}
|
|
|
|
|
|
function getTrueOffsetParent(element) {
|
|
|
if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837
|
|
|
getComputedStyle(element).position === 'fixed') {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
return element.offsetParent;
|
|
|
} // `.offsetParent` reports `null` for fixed elements, while absolute elements
|
|
|
// return the containing block
|
|
|
|
|
|
|
|
|
function getContainingBlock(element) {
|
|
|
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') !== -1;
|
|
|
var isIE = navigator.userAgent.indexOf('Trident') !== -1;
|
|
|
|
|
|
if (isIE && isHTMLElement(element)) {
|
|
|
// In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
|
|
|
var elementCss = getComputedStyle(element);
|
|
|
|
|
|
if (elementCss.position === 'fixed') {
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var currentNode = getParentNode(element);
|
|
|
|
|
|
while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {
|
|
|
var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that
|
|
|
// create a containing block.
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
|
|
|
|
|
|
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;
|
|
|
} // Gets the closest ancestor positioned element. Handles some edge cases,
|
|
|
// such as table ancestors and cross browser bugs.
|
|
|
|
|
|
|
|
|
function getOffsetParent(element) {
|
|
|
var window = 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 window;
|
|
|
}
|
|
|
|
|
|
return offsetParent || getContainingBlock(element) || window;
|
|
|
}
|
|
|
|
|
|
function getMainAxisFromPlacement(placement) {
|
|
|
return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';
|
|
|
}
|
|
|
|
|
|
function within(min$1, value, max$1) {
|
|
|
return max(min$1, min(value, max$1));
|
|
|
}
|
|
|
function withinMaxClamp(min, value, max) {
|
|
|
var v = within(min, value, max);
|
|
|
return v > max ? max : v;
|
|
|
}
|
|
|
|
|
|
function getFreshSideObject() {
|
|
|
return {
|
|
|
top: 0,
|
|
|
right: 0,
|
|
|
bottom: 0,
|
|
|
left: 0
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function mergePaddingObject(paddingObject) {
|
|
|
return Object.assign({}, getFreshSideObject(), paddingObject);
|
|
|
}
|
|
|
|
|
|
function expandToHashMap(value, keys) {
|
|
|
return keys.reduce(function (hashMap, key) {
|
|
|
hashMap[key] = value;
|
|
|
return hashMap;
|
|
|
}, {});
|
|
|
}
|
|
|
|
|
|
var toPaddingObject = function toPaddingObject(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 popperOffsets = 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 || !popperOffsets) {
|
|
|
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] - popperOffsets[axis] - state.rects.popper[len];
|
|
|
var startDiff = popperOffsets[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; // Make sure the arrow doesn't overflow the popper if the center point is
|
|
|
// outside of the popper bounds
|
|
|
|
|
|
var min = paddingObject[minProp];
|
|
|
var max = clientSize - arrowRect[len] - paddingObject[maxProp];
|
|
|
var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
|
|
|
var offset = within(min, center, max); // Prevents breaking syntax highlighting...
|
|
|
|
|
|
var axisProp = axis;
|
|
|
state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);
|
|
|
}
|
|
|
|
|
|
function effect$1(_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;
|
|
|
} // CSS selector
|
|
|
|
|
|
|
|
|
if (typeof arrowElement === 'string') {
|
|
|
arrowElement = state.elements.popper.querySelector(arrowElement);
|
|
|
|
|
|
if (!arrowElement) {
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
|
if (!isHTMLElement(arrowElement)) {
|
|
|
console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' '));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!contains(state.elements.popper, arrowElement)) {
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
|
console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' '));
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
state.elements.arrow = arrowElement;
|
|
|
} // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
|
|
|
var arrow$1 = {
|
|
|
name: 'arrow',
|
|
|
enabled: true,
|
|
|
phase: 'main',
|
|
|
fn: arrow,
|
|
|
effect: effect$1,
|
|
|
requires: ['popperOffsets'],
|
|
|
requiresIfExists: ['preventOverflow']
|
|
|
};
|
|
|
|
|
|
function getVariation(placement) {
|
|
|
return placement.split('-')[1];
|
|
|
}
|
|
|
|
|
|
var unsetSides = {
|
|
|
top: 'auto',
|
|
|
right: 'auto',
|
|
|
bottom: 'auto',
|
|
|
left: 'auto'
|
|
|
}; // Round the offsets to the nearest suitable subpixel based on the DPR.
|
|
|
// Zooming can change the DPR, but it seems to report a value that will
|
|
|
// cleanly divide the values into the appropriate subpixels.
|
|
|
|
|
|
function roundOffsetsByDPR(_ref) {
|
|
|
var x = _ref.x,
|
|
|
y = _ref.y;
|
|
|
var win = window;
|
|
|
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 popper = _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: x,
|
|
|
y: y
|
|
|
}) : {
|
|
|
x: x,
|
|
|
y: 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(popper);
|
|
|
var heightProp = 'clientHeight';
|
|
|
var widthProp = 'clientWidth';
|
|
|
|
|
|
if (offsetParent === getWindow(popper)) {
|
|
|
offsetParent = getDocumentElement(popper);
|
|
|
|
|
|
if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {
|
|
|
heightProp = 'scrollHeight';
|
|
|
widthProp = 'scrollWidth';
|
|
|
}
|
|
|
} // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
|
|
|
|
|
|
|
|
|
offsetParent = offsetParent;
|
|
|
|
|
|
if (placement === top || (placement === left || placement === right) && variation === end) {
|
|
|
sideY = bottom;
|
|
|
var offsetY = isFixed && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
|
|
|
offsetParent[heightProp];
|
|
|
y -= offsetY - popperRect.height;
|
|
|
y *= gpuAcceleration ? 1 : -1;
|
|
|
}
|
|
|
|
|
|
if (placement === left || (placement === top || placement === bottom) && variation === end) {
|
|
|
sideX = right;
|
|
|
var offsetX = isFixed && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
|
|
|
offsetParent[widthProp];
|
|
|
x -= offsetX - popperRect.width;
|
|
|
x *= gpuAcceleration ? 1 : -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var commonStyles = Object.assign({
|
|
|
position: position
|
|
|
}, adaptive && unsetSides);
|
|
|
|
|
|
var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
|
|
|
x: x,
|
|
|
y: y
|
|
|
}) : {
|
|
|
x: x,
|
|
|
y: 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;
|
|
|
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
|
var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || '';
|
|
|
|
|
|
if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {
|
|
|
return transitionProperty.indexOf(property) >= 0;
|
|
|
})) {
|
|
|
console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: "transform", "top", "right", "bottom", "left".', '\n\n', 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\n\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' '));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var commonStyles = {
|
|
|
placement: getBasePlacement(state.placement),
|
|
|
variation: getVariation(state.placement),
|
|
|
popper: state.elements.popper,
|
|
|
popperRect: state.rects.popper,
|
|
|
gpuAcceleration: 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: adaptive,
|
|
|
roundOffsets: 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: roundOffsets
|
|
|
})));
|
|
|
}
|
|
|
|
|
|
state.attributes.popper = Object.assign({}, state.attributes.popper, {
|
|
|
'data-popper-placement': state.placement
|
|
|
});
|
|
|
} // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
|
|
|
var computeStyles$1 = {
|
|
|
name: 'computeStyles',
|
|
|
enabled: true,
|
|
|
phase: 'beforeWrite',
|
|
|
fn: computeStyles,
|
|
|
data: {}
|
|
|
};
|
|
|
|
|
|
var passive = {
|
|
|
passive: true
|
|
|
};
|
|
|
|
|
|
function effect(_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 window = 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) {
|
|
|
window.addEventListener('resize', instance.update, passive);
|
|
|
}
|
|
|
|
|
|
return function () {
|
|
|
if (scroll) {
|
|
|
scrollParents.forEach(function (scrollParent) {
|
|
|
scrollParent.removeEventListener('scroll', instance.update, passive);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
if (resize) {
|
|
|
window.removeEventListener('resize', instance.update, passive);
|
|
|
}
|
|
|
};
|
|
|
} // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
|
|
|
var eventListeners = {
|
|
|
name: 'eventListeners',
|
|
|
enabled: true,
|
|
|
phase: 'write',
|
|
|
fn: function fn() {},
|
|
|
effect: effect,
|
|
|
data: {}
|
|
|
};
|
|
|
|
|
|
var hash$1 = {
|
|
|
left: 'right',
|
|
|
right: 'left',
|
|
|
bottom: 'top',
|
|
|
top: 'bottom'
|
|
|
};
|
|
|
function getOppositePlacement(placement) {
|
|
|
return placement.replace(/left|right|bottom|top/g, function (matched) {
|
|
|
return hash$1[matched];
|
|
|
});
|
|
|
}
|
|
|
|
|
|
var hash = {
|
|
|
start: 'end',
|
|
|
end: 'start'
|
|
|
};
|
|
|
function getOppositeVariationPlacement(placement) {
|
|
|
return placement.replace(/start|end/g, function (matched) {
|
|
|
return hash[matched];
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function getWindowScroll(node) {
|
|
|
var win = getWindow(node);
|
|
|
var scrollLeft = win.pageXOffset;
|
|
|
var scrollTop = win.pageYOffset;
|
|
|
return {
|
|
|
scrollLeft: scrollLeft,
|
|
|
scrollTop: scrollTop
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function getWindowScrollBarX(element) {
|
|
|
// If <html> has a CSS width greater than the viewport, then this will be
|
|
|
// incorrect for RTL.
|
|
|
// Popper 1 is broken in this case and never had a bug report so let's assume
|
|
|
// it's not an issue. I don't think anyone ever specifies width on <html>
|
|
|
// anyway.
|
|
|
// Browsers where the left scrollbar doesn't cause an issue report `0` for
|
|
|
// this (e.g. Edge 2019, IE11, Safari)
|
|
|
return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
|
|
|
}
|
|
|
|
|
|
function getViewportRect(element) {
|
|
|
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; // NB: This isn't supported on iOS <= 12. If the keyboard is open, the popper
|
|
|
// can be obscured underneath it.
|
|
|
// Also, `html.clientHeight` adds the bottom bar height in Safari iOS, even
|
|
|
// if it isn't open, so if this isn't available, the popper will be detected
|
|
|
// to overflow the bottom of the screen too early.
|
|
|
|
|
|
if (visualViewport) {
|
|
|
width = visualViewport.width;
|
|
|
height = visualViewport.height; // Uses Layout Viewport (like Chrome; Safari does not currently)
|
|
|
// In Chrome, it returns a value very close to 0 (+/-) but contains rounding
|
|
|
// errors due to floating point numbers, so we need to check precision.
|
|
|
// Safari returns a number <= 0, usually < -1 when pinch-zoomed
|
|
|
// Feature detection fails in mobile emulation mode in Chrome.
|
|
|
// Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) <
|
|
|
// 0.001
|
|
|
// Fallback here: "Not Safari" userAgent
|
|
|
|
|
|
if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
|
|
|
x = visualViewport.offsetLeft;
|
|
|
y = visualViewport.offsetTop;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
width: width,
|
|
|
height: height,
|
|
|
x: x + getWindowScrollBarX(element),
|
|
|
y: y
|
|
|
};
|
|
|
}
|
|
|
|
|
|
// of the `<html>` and `<body>` rect bounds if horizontally scrollable
|
|
|
|
|
|
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: width,
|
|
|
height: height,
|
|
|
x: x,
|
|
|
y: y
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function isScrollParent(element) {
|
|
|
// Firefox wants us to check `-x` and `-y` variations as well
|
|
|
var _getComputedStyle = getComputedStyle(element),
|
|
|
overflow = _getComputedStyle.overflow,
|
|
|
overflowX = _getComputedStyle.overflowX,
|
|
|
overflowY = _getComputedStyle.overflowY;
|
|
|
|
|
|
return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
|
|
|
}
|
|
|
|
|
|
function getScrollParent(node) {
|
|
|
if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {
|
|
|
// $FlowFixMe[incompatible-return]: assume body is always available
|
|
|
return node.ownerDocument.body;
|
|
|
}
|
|
|
|
|
|
if (isHTMLElement(node) && isScrollParent(node)) {
|
|
|
return node;
|
|
|
}
|
|
|
|
|
|
return getScrollParent(getParentNode(node));
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
given a DOM element, return the list of all scroll parents, up the list of ancesors
|
|
|
until we get to the top window object. This list is what we attach scroll listeners
|
|
|
to, because if any of these parent elements scroll, we'll need to re-calculate the
|
|
|
reference element's position.
|
|
|
*/
|
|
|
|
|
|
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 : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
|
|
|
updatedList.concat(listScrollParents(getParentNode(target)));
|
|
|
}
|
|
|
|
|
|
function rectToClientRect(rect) {
|
|
|
return Object.assign({}, rect, {
|
|
|
left: rect.x,
|
|
|
top: rect.y,
|
|
|
right: rect.x + rect.width,
|
|
|
bottom: rect.y + rect.height
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function getInnerBoundingClientRect(element) {
|
|
|
var rect = getBoundingClientRect(element);
|
|
|
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) {
|
|
|
return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
|
|
|
} // A "clipping parent" is an overflowable container with the characteristic of
|
|
|
// clipping (or hiding) overflowing elements with a position different from
|
|
|
// `initial`
|
|
|
|
|
|
|
|
|
function getClippingParents(element) {
|
|
|
var clippingParents = listScrollParents(getParentNode(element));
|
|
|
var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;
|
|
|
var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
|
|
|
|
|
|
if (!isElement(clipperElement)) {
|
|
|
return [];
|
|
|
} // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414
|
|
|
|
|
|
|
|
|
return clippingParents.filter(function (clippingParent) {
|
|
|
return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';
|
|
|
});
|
|
|
} // Gets the maximum area that the element is visible in due to any number of
|
|
|
// clipping parents
|
|
|
|
|
|
|
|
|
function getClippingRect(element, boundary, rootBoundary) {
|
|
|
var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);
|
|
|
var clippingParents = [].concat(mainClippingParents, [rootBoundary]);
|
|
|
var firstClippingParent = clippingParents[0];
|
|
|
var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {
|
|
|
var rect = getClientRectFromMixedType(element, clippingParent);
|
|
|
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));
|
|
|
clippingRect.width = clippingRect.right - clippingRect.left;
|
|
|
clippingRect.height = clippingRect.bottom - clippingRect.top;
|
|
|
clippingRect.x = clippingRect.left;
|
|
|
clippingRect.y = clippingRect.top;
|
|
|
return clippingRect;
|
|
|
}
|
|
|
|
|
|
function computeOffsets(_ref) {
|
|
|
var reference = _ref.reference,
|
|
|
element = _ref.element,
|
|
|
placement = _ref.placement;
|
|
|
var basePlacement = placement ? getBasePlacement(placement) : null;
|
|
|
var variation = placement ? getVariation(placement) : null;
|
|
|
var commonX = reference.x + reference.width / 2 - element.width / 2;
|
|
|
var commonY = reference.y + reference.height / 2 - element.height / 2;
|
|
|
var offsets;
|
|
|
|
|
|
switch (basePlacement) {
|
|
|
case top:
|
|
|
offsets = {
|
|
|
x: commonX,
|
|
|
y: reference.y - element.height
|
|
|
};
|
|
|
break;
|
|
|
|
|
|
case bottom:
|
|
|
offsets = {
|
|
|
x: commonX,
|
|
|
y: reference.y + reference.height
|
|
|
};
|
|
|
break;
|
|
|
|
|
|
case right:
|
|
|
offsets = {
|
|
|
x: reference.x + reference.width,
|
|
|
y: commonY
|
|
|
};
|
|
|
break;
|
|
|
|
|
|
case left:
|
|
|
offsets = {
|
|
|
x: reference.x - element.width,
|
|
|
y: commonY
|
|
|
};
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
offsets = {
|
|
|
x: reference.x,
|
|
|
y: reference.y
|
|
|
};
|
|
|
}
|
|
|
|
|
|
var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;
|
|
|
|
|
|
if (mainAxis != null) {
|
|
|
var len = mainAxis === 'y' ? 'height' : 'width';
|
|
|
|
|
|
switch (variation) {
|
|
|
case start:
|
|
|
offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);
|
|
|
break;
|
|
|
|
|
|
case end:
|
|
|
offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return offsets;
|
|
|
}
|
|
|
|
|
|
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$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);
|
|
|
var referenceClientRect = getBoundingClientRect(state.elements.reference);
|
|
|
var popperOffsets = computeOffsets({
|
|
|
reference: referenceClientRect,
|
|
|
element: popperRect,
|
|
|
strategy: 'absolute',
|
|
|
placement: placement
|
|
|
});
|
|
|
var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));
|
|
|
var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect
|
|
|
// 0 or negative = within the clipping rect
|
|
|
|
|
|
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; // Offsets can be applied only to the popper element
|
|
|
|
|
|
if (elementContext === popper && offsetData) {
|
|
|
var offset = 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] += offset[axis] * multiply;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return overflowOffsets;
|
|
|
}
|
|
|
|
|
|
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 placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {
|
|
|
return getVariation(placement) === variation;
|
|
|
}) : basePlacements;
|
|
|
var allowedPlacements = placements$1.filter(function (placement) {
|
|
|
return allowedAutoPlacements.indexOf(placement) >= 0;
|
|
|
});
|
|
|
|
|
|
if (allowedPlacements.length === 0) {
|
|
|
allowedPlacements = placements$1;
|
|
|
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
|
console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(' '));
|
|
|
}
|
|
|
} // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...
|
|
|
|
|
|
|
|
|
var overflows = allowedPlacements.reduce(function (acc, placement) {
|
|
|
acc[placement] = detectOverflow(state, {
|
|
|
placement: placement,
|
|
|
boundary: boundary,
|
|
|
rootBoundary: rootBoundary,
|
|
|
padding: padding
|
|
|
})[getBasePlacement(placement)];
|
|
|
return acc;
|
|
|
}, {});
|
|
|
return Object.keys(overflows).sort(function (a, b) {
|
|
|
return overflows[a] - overflows[b];
|
|
|
});
|
|
|
}
|
|
|
|
|
|
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 placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {
|
|
|
return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {
|
|
|
placement: placement,
|
|
|
boundary: boundary,
|
|
|
rootBoundary: rootBoundary,
|
|
|
padding: padding,
|
|
|
flipVariations: flipVariations,
|
|
|
allowedAutoPlacements: allowedAutoPlacements
|
|
|
}) : placement);
|
|
|
}, []);
|
|
|
var referenceRect = state.rects.reference;
|
|
|
var popperRect = state.rects.popper;
|
|
|
var checksMap = new Map();
|
|
|
var makeFallbackChecks = true;
|
|
|
var firstFittingPlacement = placements[0];
|
|
|
|
|
|
for (var i = 0; i < placements.length; i++) {
|
|
|
var placement = placements[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: placement,
|
|
|
boundary: boundary,
|
|
|
rootBoundary: rootBoundary,
|
|
|
altBoundary: altBoundary,
|
|
|
padding: 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) {
|
|
|
// `2` may be desired in some cases – research later
|
|
|
var numberOfChecks = flipVariations ? 3 : 1;
|
|
|
|
|
|
var _loop = function _loop(_i) {
|
|
|
var fittingPlacement = placements.find(function (placement) {
|
|
|
var checks = checksMap.get(placement);
|
|
|
|
|
|
if (checks) {
|
|
|
return checks.slice(0, _i).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;
|
|
|
}
|
|
|
} // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
|
|
|
var flip$1 = {
|
|
|
name: 'flip',
|
|
|
enabled: true,
|
|
|
phase: 'main',
|
|
|
fn: flip,
|
|
|
requiresIfExists: ['offset'],
|
|
|
data: {
|
|
|
_skip: false
|
|
|
}
|
|
|
};
|
|
|
|
|
|
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: referenceClippingOffsets,
|
|
|
popperEscapeOffsets: popperEscapeOffsets,
|
|
|
isReferenceHidden: isReferenceHidden,
|
|
|
hasPopperEscaped: hasPopperEscaped
|
|
|
};
|
|
|
state.attributes.popper = Object.assign({}, state.attributes.popper, {
|
|
|
'data-popper-reference-hidden': isReferenceHidden,
|
|
|
'data-popper-escaped': hasPopperEscaped
|
|
|
});
|
|
|
} // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
|
|
|
var hide$1 = {
|
|
|
name: 'hide',
|
|
|
enabled: true,
|
|
|
phase: 'main',
|
|
|
requiresIfExists: ['preventOverflow'],
|
|
|
fn: hide
|
|
|
};
|
|
|
|
|
|
function distanceAndSkiddingToXY(placement, rects, offset) {
|
|
|
var basePlacement = getBasePlacement(placement);
|
|
|
var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
|
|
|
|
|
|
var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {
|
|
|
placement: placement
|
|
|
})) : offset,
|
|
|
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,
|
|
|
offset = _options$offset === void 0 ? [0, 0] : _options$offset;
|
|
|
var data = placements.reduce(function (acc, placement) {
|
|
|
acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);
|
|
|
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;
|
|
|
} // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
|
|
|
var offset$1 = {
|
|
|
name: 'offset',
|
|
|
enabled: true,
|
|
|
phase: 'main',
|
|
|
requires: ['popperOffsets'],
|
|
|
fn: offset
|
|
|
};
|
|
|
|
|
|
function popperOffsets(_ref) {
|
|
|
var state = _ref.state,
|
|
|
name = _ref.name;
|
|
|
// Offsets are the actual position the popper needs to have to be
|
|
|
// properly positioned near its reference element
|
|
|
// This is the most basic placement, and will be adjusted by
|
|
|
// the modifiers in the next step
|
|
|
state.modifiersData[name] = computeOffsets({
|
|
|
reference: state.rects.reference,
|
|
|
element: state.rects.popper,
|
|
|
strategy: 'absolute',
|
|
|
placement: state.placement
|
|
|
});
|
|
|
} // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
|
|
|
var popperOffsets$1 = {
|
|
|
name: 'popperOffsets',
|
|
|
enabled: true,
|
|
|
phase: 'read',
|
|
|
fn: popperOffsets,
|
|
|
data: {}
|
|
|
};
|
|
|
|
|
|
function getAltAxis(axis) {
|
|
|
return axis === 'x' ? 'y' : 'x';
|
|
|
}
|
|
|
|
|
|
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: boundary,
|
|
|
rootBoundary: rootBoundary,
|
|
|
padding: padding,
|
|
|
altBoundary: altBoundary
|
|
|
});
|
|
|
var basePlacement = getBasePlacement(state.placement);
|
|
|
var variation = getVariation(state.placement);
|
|
|
var isBasePlacement = !variation;
|
|
|
var mainAxis = getMainAxisFromPlacement(basePlacement);
|
|
|
var altAxis = getAltAxis(mainAxis);
|
|
|
var popperOffsets = 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 (!popperOffsets) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (checkMainAxis) {
|
|
|
var _offsetModifierState$;
|
|
|
|
|
|
var mainSide = mainAxis === 'y' ? top : left;
|
|
|
var altSide = mainAxis === 'y' ? bottom : right;
|
|
|
var len = mainAxis === 'y' ? 'height' : 'width';
|
|
|
var offset = popperOffsets[mainAxis];
|
|
|
var min$1 = offset + overflow[mainSide];
|
|
|
var max$1 = offset - 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]; // We need to include the arrow in the calculation so the arrow doesn't go
|
|
|
// outside the reference bounds
|
|
|
|
|
|
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]; // If the reference length is smaller than the arrow length, we don't want
|
|
|
// to include its full size in the calculation. If the reference is small
|
|
|
// and near the edge of a boundary, the popper can overflow even if the
|
|
|
// reference is not overflowing as well (e.g. virtual elements with no
|
|
|
// width or height)
|
|
|
|
|
|
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 = offset + minOffset - offsetModifierValue - clientOffset;
|
|
|
var tetherMax = offset + maxOffset - offsetModifierValue;
|
|
|
var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1);
|
|
|
popperOffsets[mainAxis] = preventedOffset;
|
|
|
data[mainAxis] = preventedOffset - offset;
|
|
|
}
|
|
|
|
|
|
if (checkAltAxis) {
|
|
|
var _offsetModifierState$2;
|
|
|
|
|
|
var _mainSide = mainAxis === 'x' ? top : left;
|
|
|
|
|
|
var _altSide = mainAxis === 'x' ? bottom : right;
|
|
|
|
|
|
var _offset = popperOffsets[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);
|
|
|
|
|
|
popperOffsets[altAxis] = _preventedOffset;
|
|
|
data[altAxis] = _preventedOffset - _offset;
|
|
|
}
|
|
|
|
|
|
state.modifiersData[name] = data;
|
|
|
} // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
|
|
|
var preventOverflow$1 = {
|
|
|
name: 'preventOverflow',
|
|
|
enabled: true,
|
|
|
phase: 'main',
|
|
|
fn: preventOverflow,
|
|
|
requiresIfExists: ['offset']
|
|
|
};
|
|
|
|
|
|
function getHTMLElementScroll(element) {
|
|
|
return {
|
|
|
scrollLeft: element.scrollLeft,
|
|
|
scrollTop: element.scrollTop
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function getNodeScroll(node) {
|
|
|
if (node === getWindow(node) || !isHTMLElement(node)) {
|
|
|
return getWindowScroll(node);
|
|
|
} else {
|
|
|
return getHTMLElementScroll(node);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
} // Returns the composite rect of an element relative to its offsetParent.
|
|
|
// Composite means it takes into account transforms as well as layout.
|
|
|
|
|
|
|
|
|
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);
|
|
|
var scroll = {
|
|
|
scrollLeft: 0,
|
|
|
scrollTop: 0
|
|
|
};
|
|
|
var offsets = {
|
|
|
x: 0,
|
|
|
y: 0
|
|
|
};
|
|
|
|
|
|
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
|
|
|
if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078
|
|
|
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
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function order(modifiers) {
|
|
|
var map = new Map();
|
|
|
var visited = new Set();
|
|
|
var result = [];
|
|
|
modifiers.forEach(function (modifier) {
|
|
|
map.set(modifier.name, modifier);
|
|
|
}); // On visiting object, check for its dependencies and visit them recursively
|
|
|
|
|
|
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)) {
|
|
|
// check for visited object
|
|
|
sort(modifier);
|
|
|
}
|
|
|
});
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
function orderModifiers(modifiers) {
|
|
|
// order based on dependencies
|
|
|
var orderedModifiers = order(modifiers); // order based on phase
|
|
|
|
|
|
return modifierPhases.reduce(function (acc, phase) {
|
|
|
return acc.concat(orderedModifiers.filter(function (modifier) {
|
|
|
return modifier.phase === phase;
|
|
|
}));
|
|
|
}, []);
|
|
|
}
|
|
|
|
|
|
function debounce(fn) {
|
|
|
var pending;
|
|
|
return function () {
|
|
|
if (!pending) {
|
|
|
pending = new Promise(function (resolve) {
|
|
|
Promise.resolve().then(function () {
|
|
|
pending = undefined;
|
|
|
resolve(fn());
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
|
|
|
return pending;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function format(str) {
|
|
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
|
args[_key - 1] = arguments[_key];
|
|
|
}
|
|
|
|
|
|
return [].concat(args).reduce(function (p, c) {
|
|
|
return p.replace(/%s/, c);
|
|
|
}, str);
|
|
|
}
|
|
|
|
|
|
var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s';
|
|
|
var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available';
|
|
|
var VALID_PROPERTIES = ['name', 'enabled', 'phase', 'fn', 'effect', 'requires', 'options'];
|
|
|
function validateModifiers(modifiers) {
|
|
|
modifiers.forEach(function (modifier) {
|
|
|
[].concat(Object.keys(modifier), VALID_PROPERTIES) // IE11-compatible replacement for `new Set(iterable)`
|
|
|
.filter(function (value, index, self) {
|
|
|
return self.indexOf(value) === index;
|
|
|
}).forEach(function (key) {
|
|
|
switch (key) {
|
|
|
case 'name':
|
|
|
if (typeof modifier.name !== 'string') {
|
|
|
console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', "\"" + String(modifier.name) + "\""));
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'enabled':
|
|
|
if (typeof modifier.enabled !== 'boolean') {
|
|
|
console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', "\"" + String(modifier.enabled) + "\""));
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'phase':
|
|
|
if (modifierPhases.indexOf(modifier.phase) < 0) {
|
|
|
console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(', '), "\"" + String(modifier.phase) + "\""));
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'fn':
|
|
|
if (typeof modifier.fn !== 'function') {
|
|
|
console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', "\"" + String(modifier.fn) + "\""));
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'effect':
|
|
|
if (modifier.effect != null && typeof modifier.effect !== 'function') {
|
|
|
console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', "\"" + String(modifier.fn) + "\""));
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'requires':
|
|
|
if (modifier.requires != null && !Array.isArray(modifier.requires)) {
|
|
|
console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', "\"" + String(modifier.requires) + "\""));
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'requiresIfExists':
|
|
|
if (!Array.isArray(modifier.requiresIfExists)) {
|
|
|
console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', "\"" + String(modifier.requiresIfExists) + "\""));
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'options':
|
|
|
case 'data':
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
console.error("PopperJS: an invalid property has been provided to the \"" + modifier.name + "\" modifier, valid properties are " + VALID_PROPERTIES.map(function (s) {
|
|
|
return "\"" + s + "\"";
|
|
|
}).join(', ') + "; but \"" + key + "\" was provided.");
|
|
|
}
|
|
|
|
|
|
modifier.requires && modifier.requires.forEach(function (requirement) {
|
|
|
if (modifiers.find(function (mod) {
|
|
|
return mod.name === requirement;
|
|
|
}) == null) {
|
|
|
console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement));
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function uniqueBy(arr, fn) {
|
|
|
var identifiers = new Set();
|
|
|
return arr.filter(function (item) {
|
|
|
var identifier = fn(item);
|
|
|
|
|
|
if (!identifiers.has(identifier)) {
|
|
|
identifiers.add(identifier);
|
|
|
return true;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function mergeByName(modifiers) {
|
|
|
var merged = modifiers.reduce(function (merged, current) {
|
|
|
var existing = merged[current.name];
|
|
|
merged[current.name] = existing ? Object.assign({}, existing, current, {
|
|
|
options: Object.assign({}, existing.options, current.options),
|
|
|
data: Object.assign({}, existing.data, current.data)
|
|
|
}) : current;
|
|
|
return merged;
|
|
|
}, {}); // IE11 does not support Object.values
|
|
|
|
|
|
return Object.keys(merged).map(function (key) {
|
|
|
return merged[key];
|
|
|
});
|
|
|
}
|
|
|
|
|
|
var INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.';
|
|
|
var INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.';
|
|
|
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,
|
|
|
defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,
|
|
|
_generatorOptions$def2 = _generatorOptions.defaultOptions,
|
|
|
defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
|
|
|
return function createPopper(reference, popper, options) {
|
|
|
if (options === void 0) {
|
|
|
options = defaultOptions;
|
|
|
}
|
|
|
|
|
|
var state = {
|
|
|
placement: 'bottom',
|
|
|
orderedModifiers: [],
|
|
|
options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
|
|
|
modifiersData: {},
|
|
|
elements: {
|
|
|
reference: reference,
|
|
|
popper: popper
|
|
|
},
|
|
|
attributes: {},
|
|
|
styles: {}
|
|
|
};
|
|
|
var effectCleanupFns = [];
|
|
|
var isDestroyed = false;
|
|
|
var instance = {
|
|
|
state: state,
|
|
|
setOptions: function setOptions(setOptionsAction) {
|
|
|
var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;
|
|
|
cleanupModifierEffects();
|
|
|
state.options = Object.assign({}, defaultOptions, state.options, options);
|
|
|
state.scrollParents = {
|
|
|
reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],
|
|
|
popper: listScrollParents(popper)
|
|
|
}; // Orders the modifiers based on their dependencies and `phase`
|
|
|
// properties
|
|
|
|
|
|
var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers
|
|
|
|
|
|
state.orderedModifiers = orderedModifiers.filter(function (m) {
|
|
|
return m.enabled;
|
|
|
}); // Validate the provided modifiers so that the consumer will get warned
|
|
|
// if one of the modifiers is invalid for any reason
|
|
|
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
|
var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) {
|
|
|
var name = _ref.name;
|
|
|
return name;
|
|
|
});
|
|
|
validateModifiers(modifiers);
|
|
|
|
|
|
if (getBasePlacement(state.options.placement) === auto) {
|
|
|
var flipModifier = state.orderedModifiers.find(function (_ref2) {
|
|
|
var name = _ref2.name;
|
|
|
return name === 'flip';
|
|
|
});
|
|
|
|
|
|
if (!flipModifier) {
|
|
|
console.error(['Popper: "auto" placements require the "flip" modifier be', 'present and enabled to work.'].join(' '));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var _getComputedStyle = getComputedStyle(popper),
|
|
|
marginTop = _getComputedStyle.marginTop,
|
|
|
marginRight = _getComputedStyle.marginRight,
|
|
|
marginBottom = _getComputedStyle.marginBottom,
|
|
|
marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can
|
|
|
// cause bugs with positioning, so we'll warn the consumer
|
|
|
|
|
|
|
|
|
if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) {
|
|
|
return parseFloat(margin);
|
|
|
})) {
|
|
|
console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' '));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
runModifierEffects();
|
|
|
return instance.update();
|
|
|
},
|
|
|
// Sync update – it will always be executed, even if not necessary. This
|
|
|
// is useful for low frequency updates where sync behavior simplifies the
|
|
|
// logic.
|
|
|
// For high frequency updates (e.g. `resize` and `scroll` events), always
|
|
|
// prefer the async Popper#update method
|
|
|
forceUpdate: function forceUpdate() {
|
|
|
if (isDestroyed) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var _state$elements = state.elements,
|
|
|
reference = _state$elements.reference,
|
|
|
popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements
|
|
|
// anymore
|
|
|
|
|
|
if (!areValidElements(reference, popper)) {
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
|
console.error(INVALID_ELEMENT_ERROR);
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
} // Store the reference and popper rects to be read by modifiers
|
|
|
|
|
|
|
|
|
state.rects = {
|
|
|
reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),
|
|
|
popper: getLayoutRect(popper)
|
|
|
}; // Modifiers have the ability to reset the current update cycle. The
|
|
|
// most common use case for this is the `flip` modifier changing the
|
|
|
// placement, which then needs to re-run all the modifiers, because the
|
|
|
// logic was previously ran for the previous placement and is therefore
|
|
|
// stale/incorrect
|
|
|
|
|
|
state.reset = false;
|
|
|
state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier
|
|
|
// is filled with the initial data specified by the modifier. This means
|
|
|
// it doesn't persist and is fresh on each update.
|
|
|
// To ensure persistent data, use `${name}#persistent`
|
|
|
|
|
|
state.orderedModifiers.forEach(function (modifier) {
|
|
|
return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
|
|
|
});
|
|
|
var __debug_loops__ = 0;
|
|
|
|
|
|
for (var index = 0; index < state.orderedModifiers.length; index++) {
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
|
__debug_loops__ += 1;
|
|
|
|
|
|
if (__debug_loops__ > 100) {
|
|
|
console.error(INFINITE_LOOP_ERROR);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (state.reset === true) {
|
|
|
state.reset = false;
|
|
|
index = -1;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
var _state$orderedModifie = state.orderedModifiers[index],
|
|
|
fn = _state$orderedModifie.fn,
|
|
|
_state$orderedModifie2 = _state$orderedModifie.options,
|
|
|
_options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,
|
|
|
name = _state$orderedModifie.name;
|
|
|
|
|
|
if (typeof fn === 'function') {
|
|
|
state = fn({
|
|
|
state: state,
|
|
|
options: _options,
|
|
|
name: name,
|
|
|
instance: instance
|
|
|
}) || state;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
// Async and optimistically optimized update – it will not be executed if
|
|
|
// not necessary (debounced to run at most once-per-tick)
|
|
|
update: debounce(function () {
|
|
|
return new Promise(function (resolve) {
|
|
|
instance.forceUpdate();
|
|
|
resolve(state);
|
|
|
});
|
|
|
}),
|
|
|
destroy: function destroy() {
|
|
|
cleanupModifierEffects();
|
|
|
isDestroyed = true;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
if (!areValidElements(reference, popper)) {
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
|
console.error(INVALID_ELEMENT_ERROR);
|
|
|
}
|
|
|
|
|
|
return instance;
|
|
|
}
|
|
|
|
|
|
instance.setOptions(options).then(function (state) {
|
|
|
if (!isDestroyed && options.onFirstUpdate) {
|
|
|
options.onFirstUpdate(state);
|
|
|
}
|
|
|
}); // Modifiers have the ability to execute arbitrary code before the first
|
|
|
// update cycle runs. They will be executed in the same order as the update
|
|
|
// cycle. This is useful when a modifier adds some persistent data that
|
|
|
// other modifiers need to use, but the modifier is run after the dependent
|
|
|
// one.
|
|
|
|
|
|
function runModifierEffects() {
|
|
|
state.orderedModifiers.forEach(function (_ref3) {
|
|
|
var name = _ref3.name,
|
|
|
_ref3$options = _ref3.options,
|
|
|
options = _ref3$options === void 0 ? {} : _ref3$options,
|
|
|
effect = _ref3.effect;
|
|
|
|
|
|
if (typeof effect === 'function') {
|
|
|
var cleanupFn = effect({
|
|
|
state: state,
|
|
|
name: name,
|
|
|
instance: instance,
|
|
|
options: options
|
|
|
});
|
|
|
|
|
|
var noopFn = function noopFn() {};
|
|
|
|
|
|
effectCleanupFns.push(cleanupFn || noopFn);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function cleanupModifierEffects() {
|
|
|
effectCleanupFns.forEach(function (fn) {
|
|
|
return fn();
|
|
|
});
|
|
|
effectCleanupFns = [];
|
|
|
}
|
|
|
|
|
|
return instance;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1];
|
|
|
var createPopper = /*#__PURE__*/popperGenerator({
|
|
|
defaultModifiers: defaultModifiers
|
|
|
}); // eslint-disable-next-line import/no-unused-modules
|
|
|
|
|
|
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes
|
|
|
const wrapAround = (value, size) => {
|
|
|
return ((value % size) + size) % size;
|
|
|
};
|
|
|
class Suggest {
|
|
|
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 || prevSelectedSuggestion === void 0 ? void 0 : prevSelectedSuggestion.removeClass("is-selected");
|
|
|
selectedSuggestion === null || selectedSuggestion === void 0 ? void 0 : selectedSuggestion.addClass("is-selected");
|
|
|
this.selectedItem = normalizedIndex;
|
|
|
if (scrollIntoView) {
|
|
|
selectedSuggestion.scrollIntoView(false);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
class TextInputSuggest {
|
|
|
constructor(app, inputEl) {
|
|
|
this.app = app;
|
|
|
this.inputEl = inputEl;
|
|
|
this.scope = new obsidian_module.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);
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
this.open(this.app.dom.appContainerEl, this.inputEl);
|
|
|
}
|
|
|
else {
|
|
|
this.close();
|
|
|
}
|
|
|
}
|
|
|
open(container, inputEl) {
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
this.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 }) => {
|
|
|
// Note: positioning needs to be calculated twice -
|
|
|
// first pass - positioning it according to the width of the popper
|
|
|
// second pass - position it with the width bound to the reference element
|
|
|
// we need to early exit to avoid an infinite loop
|
|
|
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() {
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
this.app.keymap.popScope(this.scope);
|
|
|
this.suggest.setSuggestions([]);
|
|
|
if (this.popper)
|
|
|
this.popper.destroy();
|
|
|
this.suggestEl.detach();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes
|
|
|
class FolderSuggest extends TextInputSuggest {
|
|
|
getSuggestions(inputStr) {
|
|
|
const abstractFiles = this.app.vault.getAllLoadedFiles();
|
|
|
const folders = [];
|
|
|
const lowerCaseInputStr = inputStr.toLowerCase();
|
|
|
abstractFiles.forEach((folder) => {
|
|
|
if (folder instanceof obsidian_module.TFolder &&
|
|
|
folder.path.toLowerCase().contains(lowerCaseInputStr)) {
|
|
|
folders.push(folder);
|
|
|
}
|
|
|
});
|
|
|
return folders;
|
|
|
}
|
|
|
renderSuggestion(file, el) {
|
|
|
el.setText(file.path);
|
|
|
}
|
|
|
selectSuggestion(file) {
|
|
|
this.inputEl.value = file.path;
|
|
|
this.inputEl.trigger("input");
|
|
|
this.close();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function delay(ms) {
|
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
}
|
|
|
function escape_RegExp(str) {
|
|
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
|
|
}
|
|
|
function generate_dynamic_command_regex() {
|
|
|
return /(<%(?:-|_)?\s*[*~]{0,1})\+((?:.|\s)*?%>)/g;
|
|
|
}
|
|
|
function resolve_tfolder(app, folder_str) {
|
|
|
folder_str = obsidian_module.normalizePath(folder_str);
|
|
|
const folder = app.vault.getAbstractFileByPath(folder_str);
|
|
|
if (!folder) {
|
|
|
throw new TemplaterError(`Folder "${folder_str}" doesn't exist`);
|
|
|
}
|
|
|
if (!(folder instanceof obsidian_module.TFolder)) {
|
|
|
throw new TemplaterError(`${folder_str} is a file, not a folder`);
|
|
|
}
|
|
|
return folder;
|
|
|
}
|
|
|
function resolve_tfile(app, file_str) {
|
|
|
file_str = obsidian_module.normalizePath(file_str);
|
|
|
const file = app.vault.getAbstractFileByPath(file_str);
|
|
|
if (!file) {
|
|
|
throw new TemplaterError(`File "${file_str}" doesn't exist`);
|
|
|
}
|
|
|
if (!(file instanceof obsidian_module.TFile)) {
|
|
|
throw new TemplaterError(`${file_str} is a folder, not a file`);
|
|
|
}
|
|
|
return file;
|
|
|
}
|
|
|
function get_tfiles_from_folder(app, folder_str) {
|
|
|
const folder = resolve_tfolder(app, folder_str);
|
|
|
const files = [];
|
|
|
obsidian_module.Vault.recurseChildren(folder, (file) => {
|
|
|
if (file instanceof obsidian_module.TFile) {
|
|
|
files.push(file);
|
|
|
}
|
|
|
});
|
|
|
files.sort((a, b) => {
|
|
|
return a.basename.localeCompare(b.basename);
|
|
|
});
|
|
|
return files;
|
|
|
}
|
|
|
function arraymove(arr, fromIndex, toIndex) {
|
|
|
if (toIndex < 0 || toIndex === arr.length) {
|
|
|
return;
|
|
|
}
|
|
|
const element = arr[fromIndex];
|
|
|
arr[fromIndex] = arr[toIndex];
|
|
|
arr[toIndex] = element;
|
|
|
}
|
|
|
|
|
|
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes
|
|
|
var FileSuggestMode;
|
|
|
(function (FileSuggestMode) {
|
|
|
FileSuggestMode[FileSuggestMode["TemplateFiles"] = 0] = "TemplateFiles";
|
|
|
FileSuggestMode[FileSuggestMode["ScriptFiles"] = 1] = "ScriptFiles";
|
|
|
})(FileSuggestMode || (FileSuggestMode = {}));
|
|
|
class FileSuggest extends TextInputSuggest {
|
|
|
constructor(app, inputEl, plugin, mode) {
|
|
|
super(app, inputEl);
|
|
|
this.app = app;
|
|
|
this.inputEl = inputEl;
|
|
|
this.plugin = plugin;
|
|
|
this.mode = mode;
|
|
|
}
|
|
|
get_folder(mode) {
|
|
|
switch (mode) {
|
|
|
case FileSuggestMode.TemplateFiles:
|
|
|
return this.plugin.settings.templates_folder;
|
|
|
case FileSuggestMode.ScriptFiles:
|
|
|
return this.plugin.settings.user_scripts_folder;
|
|
|
}
|
|
|
}
|
|
|
get_error_msg(mode) {
|
|
|
switch (mode) {
|
|
|
case FileSuggestMode.TemplateFiles:
|
|
|
return `Templates folder doesn't exist`;
|
|
|
case FileSuggestMode.ScriptFiles:
|
|
|
return `User Scripts folder doesn't exist`;
|
|
|
}
|
|
|
}
|
|
|
getSuggestions(input_str) {
|
|
|
const all_files = errorWrapperSync(() => get_tfiles_from_folder(this.app, this.get_folder(this.mode)), this.get_error_msg(this.mode));
|
|
|
if (!all_files) {
|
|
|
return [];
|
|
|
}
|
|
|
const files = [];
|
|
|
const lower_input_str = input_str.toLowerCase();
|
|
|
all_files.forEach((file) => {
|
|
|
if (file instanceof obsidian_module.TFile &&
|
|
|
file.extension === "md" &&
|
|
|
file.path.toLowerCase().contains(lower_input_str)) {
|
|
|
files.push(file);
|
|
|
}
|
|
|
});
|
|
|
return files;
|
|
|
}
|
|
|
renderSuggestion(file, el) {
|
|
|
el.setText(file.path);
|
|
|
}
|
|
|
selectSuggestion(file) {
|
|
|
this.inputEl.value = file.path;
|
|
|
this.inputEl.trigger("input");
|
|
|
this.close();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const DEFAULT_SETTINGS = {
|
|
|
command_timeout: 5,
|
|
|
templates_folder: "",
|
|
|
templates_pairs: [["", ""]],
|
|
|
trigger_on_file_creation: false,
|
|
|
auto_jump_to_cursor: false,
|
|
|
enable_system_commands: false,
|
|
|
shell_path: "",
|
|
|
user_scripts_folder: "",
|
|
|
enable_folder_templates: true,
|
|
|
folder_templates: [{ folder: "", template: "" }],
|
|
|
syntax_highlighting: true,
|
|
|
enabled_templates_hotkeys: [""],
|
|
|
startup_templates: [""],
|
|
|
};
|
|
|
class TemplaterSettingTab extends obsidian_module.PluginSettingTab {
|
|
|
constructor(app, plugin) {
|
|
|
super(app, plugin);
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
}
|
|
|
display() {
|
|
|
this.containerEl.empty();
|
|
|
this.add_general_setting_header();
|
|
|
this.add_template_folder_setting();
|
|
|
this.add_internal_functions_setting();
|
|
|
this.add_syntax_highlighting_setting();
|
|
|
this.add_auto_jump_to_cursor();
|
|
|
this.add_trigger_on_new_file_creation_setting();
|
|
|
this.add_templates_hotkeys_setting();
|
|
|
if (this.plugin.settings.trigger_on_file_creation) {
|
|
|
this.add_folder_templates_setting();
|
|
|
}
|
|
|
this.add_startup_templates_setting();
|
|
|
this.add_user_script_functions_setting();
|
|
|
this.add_user_system_command_functions_setting();
|
|
|
}
|
|
|
add_general_setting_header() {
|
|
|
this.containerEl.createEl("h2", { text: "General Settings" });
|
|
|
}
|
|
|
add_template_folder_setting() {
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Template folder location")
|
|
|
.setDesc("Files in this folder will be available as templates.")
|
|
|
.addSearch((cb) => {
|
|
|
new FolderSuggest(this.app, cb.inputEl);
|
|
|
cb.setPlaceholder("Example: folder1/folder2")
|
|
|
.setValue(this.plugin.settings.templates_folder)
|
|
|
.onChange((new_folder) => {
|
|
|
this.plugin.settings.templates_folder = new_folder;
|
|
|
this.plugin.save_settings();
|
|
|
});
|
|
|
// @ts-ignore
|
|
|
cb.containerEl.addClass("templater_search");
|
|
|
});
|
|
|
}
|
|
|
add_internal_functions_setting() {
|
|
|
const desc = document.createDocumentFragment();
|
|
|
desc.append("Templater provides multiples predefined variables / functions that you can use.", desc.createEl("br"), "Check the ", desc.createEl("a", {
|
|
|
href: "https://silentvoid13.github.io/Templater/",
|
|
|
text: "documentation",
|
|
|
}), " to get a list of all the available internal variables / functions.");
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Internal Variables and Functions")
|
|
|
.setDesc(desc);
|
|
|
}
|
|
|
add_syntax_highlighting_setting() {
|
|
|
const desc = document.createDocumentFragment();
|
|
|
desc.append("Adds syntax highlighting for Templater commands in edit mode.");
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Syntax Highlighting")
|
|
|
.setDesc(desc)
|
|
|
.addToggle((toggle) => {
|
|
|
toggle
|
|
|
.setValue(this.plugin.settings.syntax_highlighting)
|
|
|
.onChange((syntax_highlighting) => {
|
|
|
this.plugin.settings.syntax_highlighting =
|
|
|
syntax_highlighting;
|
|
|
this.plugin.save_settings();
|
|
|
this.plugin.event_handler.update_syntax_highlighting();
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
add_auto_jump_to_cursor() {
|
|
|
const desc = document.createDocumentFragment();
|
|
|
desc.append("Automatically triggers ", desc.createEl("code", { text: "tp.file.cursor" }), " after inserting a template.", desc.createEl("br"), "You can also set a hotkey to manually trigger ", desc.createEl("code", { text: "tp.file.cursor" }), ".");
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Automatic jump to cursor")
|
|
|
.setDesc(desc)
|
|
|
.addToggle((toggle) => {
|
|
|
toggle
|
|
|
.setValue(this.plugin.settings.auto_jump_to_cursor)
|
|
|
.onChange((auto_jump_to_cursor) => {
|
|
|
this.plugin.settings.auto_jump_to_cursor =
|
|
|
auto_jump_to_cursor;
|
|
|
this.plugin.save_settings();
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
add_trigger_on_new_file_creation_setting() {
|
|
|
const desc = document.createDocumentFragment();
|
|
|
desc.append("Templater will listen for the new file creation event, and replace every command it finds in the new file's content.", desc.createEl("br"), "This makes Templater compatible with other plugins like the Daily note core plugin, Calendar plugin, Review plugin, Note refactor plugin, ...", desc.createEl("br"), desc.createEl("b", {
|
|
|
text: "Warning: ",
|
|
|
}), "This can be dangerous if you create new files with unknown / unsafe content on creation. Make sure that every new file's content is safe on creation.");
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Trigger Templater on new file creation")
|
|
|
.setDesc(desc)
|
|
|
.addToggle((toggle) => {
|
|
|
toggle
|
|
|
.setValue(this.plugin.settings.trigger_on_file_creation)
|
|
|
.onChange((trigger_on_file_creation) => {
|
|
|
this.plugin.settings.trigger_on_file_creation =
|
|
|
trigger_on_file_creation;
|
|
|
this.plugin.save_settings();
|
|
|
this.plugin.event_handler.update_trigger_file_on_creation();
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
add_templates_hotkeys_setting() {
|
|
|
this.containerEl.createEl("h2", { text: "Template Hotkeys" });
|
|
|
const desc = document.createDocumentFragment();
|
|
|
desc.append("Template Hotkeys allows you to bind a template to a hotkey.");
|
|
|
new obsidian_module.Setting(this.containerEl).setDesc(desc);
|
|
|
this.plugin.settings.enabled_templates_hotkeys.forEach((template, index) => {
|
|
|
const s = new obsidian_module.Setting(this.containerEl)
|
|
|
.addSearch((cb) => {
|
|
|
new FileSuggest(this.app, cb.inputEl, this.plugin, FileSuggestMode.TemplateFiles);
|
|
|
cb.setPlaceholder("Example: folder1/template_file")
|
|
|
.setValue(template)
|
|
|
.onChange((new_template) => {
|
|
|
if (new_template &&
|
|
|
this.plugin.settings.enabled_templates_hotkeys.contains(new_template)) {
|
|
|
log_error(new TemplaterError("This template is already bound to a hotkey"));
|
|
|
return;
|
|
|
}
|
|
|
this.plugin.command_handler.add_template_hotkey(this.plugin.settings
|
|
|
.enabled_templates_hotkeys[index], new_template);
|
|
|
this.plugin.settings.enabled_templates_hotkeys[index] = new_template;
|
|
|
this.plugin.save_settings();
|
|
|
});
|
|
|
// @ts-ignore
|
|
|
cb.containerEl.addClass("templater_search");
|
|
|
})
|
|
|
.addExtraButton((cb) => {
|
|
|
cb.setIcon("any-key")
|
|
|
.setTooltip("Configure Hotkey")
|
|
|
.onClick(() => {
|
|
|
// TODO: Replace with future "official" way to do this
|
|
|
// @ts-ignore
|
|
|
this.app.setting.openTabById("hotkeys");
|
|
|
// @ts-ignore
|
|
|
const tab = this.app.setting.activeTab;
|
|
|
tab.searchInputEl.value = "Templater: Insert";
|
|
|
tab.updateHotkeyVisibility();
|
|
|
});
|
|
|
})
|
|
|
.addExtraButton((cb) => {
|
|
|
cb.setIcon("up-chevron-glyph")
|
|
|
.setTooltip("Move up")
|
|
|
.onClick(() => {
|
|
|
arraymove(this.plugin.settings
|
|
|
.enabled_templates_hotkeys, index, index - 1);
|
|
|
this.plugin.save_settings();
|
|
|
this.display();
|
|
|
});
|
|
|
})
|
|
|
.addExtraButton((cb) => {
|
|
|
cb.setIcon("down-chevron-glyph")
|
|
|
.setTooltip("Move down")
|
|
|
.onClick(() => {
|
|
|
arraymove(this.plugin.settings
|
|
|
.enabled_templates_hotkeys, index, index + 1);
|
|
|
this.plugin.save_settings();
|
|
|
this.display();
|
|
|
});
|
|
|
})
|
|
|
.addExtraButton((cb) => {
|
|
|
cb.setIcon("cross")
|
|
|
.setTooltip("Delete")
|
|
|
.onClick(() => {
|
|
|
this.plugin.command_handler.remove_template_hotkey(this.plugin.settings
|
|
|
.enabled_templates_hotkeys[index]);
|
|
|
this.plugin.settings.enabled_templates_hotkeys.splice(index, 1);
|
|
|
this.plugin.save_settings();
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
s.infoEl.remove();
|
|
|
});
|
|
|
new obsidian_module.Setting(this.containerEl).addButton((cb) => {
|
|
|
cb.setButtonText("Add new hotkey for template")
|
|
|
.setCta()
|
|
|
.onClick(() => {
|
|
|
this.plugin.settings.enabled_templates_hotkeys.push("");
|
|
|
this.plugin.save_settings();
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
add_folder_templates_setting() {
|
|
|
this.containerEl.createEl("h2", { text: "Folder Templates" });
|
|
|
const descHeading = document.createDocumentFragment();
|
|
|
descHeading.append("Folder Templates are triggered when a new ", descHeading.createEl("strong", { text: "empty " }), "file is created in a given folder.", descHeading.createEl("br"), "Templater will fill the empty file with the specified template.", descHeading.createEl("br"), "The deepest match is used. A global default template would be defined on the root ", descHeading.createEl("code", { text: "/" }), ".");
|
|
|
new obsidian_module.Setting(this.containerEl).setDesc(descHeading);
|
|
|
const descUseNewFileTemplate = document.createDocumentFragment();
|
|
|
descUseNewFileTemplate.append("When enabled Templater will make use of the folder templates defined below.");
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Enable Folder Templates")
|
|
|
.setDesc(descUseNewFileTemplate)
|
|
|
.addToggle((toggle) => {
|
|
|
toggle
|
|
|
.setValue(this.plugin.settings.enable_folder_templates)
|
|
|
.onChange((use_new_file_templates) => {
|
|
|
this.plugin.settings.enable_folder_templates =
|
|
|
use_new_file_templates;
|
|
|
this.plugin.save_settings();
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
if (!this.plugin.settings.enable_folder_templates) {
|
|
|
return;
|
|
|
}
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Add New")
|
|
|
.setDesc("Add new folder template")
|
|
|
.addButton((button) => {
|
|
|
button
|
|
|
.setTooltip("Add additional folder template")
|
|
|
.setButtonText("+")
|
|
|
.setCta()
|
|
|
.onClick(() => {
|
|
|
this.plugin.settings.folder_templates.push({
|
|
|
folder: "",
|
|
|
template: "",
|
|
|
});
|
|
|
this.plugin.save_settings();
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
this.plugin.settings.folder_templates.forEach((folder_template, index) => {
|
|
|
const s = new obsidian_module.Setting(this.containerEl)
|
|
|
.addSearch((cb) => {
|
|
|
new FolderSuggest(this.app, cb.inputEl);
|
|
|
cb.setPlaceholder("Folder")
|
|
|
.setValue(folder_template.folder)
|
|
|
.onChange((new_folder) => {
|
|
|
if (new_folder &&
|
|
|
this.plugin.settings.folder_templates.some((e) => e.folder == new_folder)) {
|
|
|
log_error(new TemplaterError("This folder already has a template associated with it"));
|
|
|
return;
|
|
|
}
|
|
|
this.plugin.settings.folder_templates[index].folder = new_folder;
|
|
|
this.plugin.save_settings();
|
|
|
});
|
|
|
// @ts-ignore
|
|
|
cb.containerEl.addClass("templater_search");
|
|
|
})
|
|
|
.addSearch((cb) => {
|
|
|
new FileSuggest(this.app, cb.inputEl, this.plugin, FileSuggestMode.TemplateFiles);
|
|
|
cb.setPlaceholder("Template")
|
|
|
.setValue(folder_template.template)
|
|
|
.onChange((new_template) => {
|
|
|
this.plugin.settings.folder_templates[index].template = new_template;
|
|
|
this.plugin.save_settings();
|
|
|
});
|
|
|
// @ts-ignore
|
|
|
cb.containerEl.addClass("templater_search");
|
|
|
})
|
|
|
.addExtraButton((cb) => {
|
|
|
cb.setIcon("up-chevron-glyph")
|
|
|
.setTooltip("Move up")
|
|
|
.onClick(() => {
|
|
|
arraymove(this.plugin.settings.folder_templates, index, index - 1);
|
|
|
this.plugin.save_settings();
|
|
|
this.display();
|
|
|
});
|
|
|
})
|
|
|
.addExtraButton((cb) => {
|
|
|
cb.setIcon("down-chevron-glyph")
|
|
|
.setTooltip("Move down")
|
|
|
.onClick(() => {
|
|
|
arraymove(this.plugin.settings.folder_templates, index, index + 1);
|
|
|
this.plugin.save_settings();
|
|
|
this.display();
|
|
|
});
|
|
|
})
|
|
|
.addExtraButton((cb) => {
|
|
|
cb.setIcon("cross")
|
|
|
.setTooltip("Delete")
|
|
|
.onClick(() => {
|
|
|
this.plugin.settings.folder_templates.splice(index, 1);
|
|
|
this.plugin.save_settings();
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
s.infoEl.remove();
|
|
|
});
|
|
|
}
|
|
|
add_startup_templates_setting() {
|
|
|
this.containerEl.createEl("h2", { text: "Startup Templates" });
|
|
|
const desc = document.createDocumentFragment();
|
|
|
desc.append("Startup Templates are templates that will get executed once when Templater starts.", desc.createEl("br"), "These templates won't output anything.", desc.createEl("br"), "This can be useful to set up templates adding hooks to obsidian events for example.");
|
|
|
new obsidian_module.Setting(this.containerEl).setDesc(desc);
|
|
|
this.plugin.settings.startup_templates.forEach((template, index) => {
|
|
|
const s = new obsidian_module.Setting(this.containerEl)
|
|
|
.addSearch((cb) => {
|
|
|
new FileSuggest(this.app, cb.inputEl, this.plugin, FileSuggestMode.TemplateFiles);
|
|
|
cb.setPlaceholder("Example: folder1/template_file")
|
|
|
.setValue(template)
|
|
|
.onChange((new_template) => {
|
|
|
if (new_template &&
|
|
|
this.plugin.settings.startup_templates.contains(new_template)) {
|
|
|
log_error(new TemplaterError("This startup template already exist"));
|
|
|
return;
|
|
|
}
|
|
|
this.plugin.settings.startup_templates[index] =
|
|
|
new_template;
|
|
|
this.plugin.save_settings();
|
|
|
});
|
|
|
// @ts-ignore
|
|
|
cb.containerEl.addClass("templater_search");
|
|
|
})
|
|
|
.addExtraButton((cb) => {
|
|
|
cb.setIcon("cross")
|
|
|
.setTooltip("Delete")
|
|
|
.onClick(() => {
|
|
|
this.plugin.settings.startup_templates.splice(index, 1);
|
|
|
this.plugin.save_settings();
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
s.infoEl.remove();
|
|
|
});
|
|
|
new obsidian_module.Setting(this.containerEl).addButton((cb) => {
|
|
|
cb.setButtonText("Add new startup template")
|
|
|
.setCta()
|
|
|
.onClick(() => {
|
|
|
this.plugin.settings.startup_templates.push("");
|
|
|
this.plugin.save_settings();
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
add_user_script_functions_setting() {
|
|
|
this.containerEl.createEl("h2", { text: "User Script Functions" });
|
|
|
let desc = document.createDocumentFragment();
|
|
|
desc.append("All JavaScript files in this folder will be loaded as CommonJS modules, to import custom user functions.", desc.createEl("br"), "The folder needs to be accessible from the vault.", desc.createEl("br"), "Check the ", desc.createEl("a", {
|
|
|
href: "https://silentvoid13.github.io/Templater/",
|
|
|
text: "documentation",
|
|
|
}), " for more informations.");
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Script files folder location")
|
|
|
.setDesc(desc)
|
|
|
.addSearch((cb) => {
|
|
|
new FolderSuggest(this.app, cb.inputEl);
|
|
|
cb.setPlaceholder("Example: folder1/folder2")
|
|
|
.setValue(this.plugin.settings.user_scripts_folder)
|
|
|
.onChange((new_folder) => {
|
|
|
this.plugin.settings.user_scripts_folder = new_folder;
|
|
|
this.plugin.save_settings();
|
|
|
});
|
|
|
// @ts-ignore
|
|
|
cb.containerEl.addClass("templater_search");
|
|
|
});
|
|
|
desc = document.createDocumentFragment();
|
|
|
let name;
|
|
|
if (!this.plugin.settings.user_scripts_folder) {
|
|
|
name = "No User Scripts folder set";
|
|
|
}
|
|
|
else {
|
|
|
const files = errorWrapperSync(() => get_tfiles_from_folder(this.app, this.plugin.settings.user_scripts_folder), `User Scripts folder doesn't exist`);
|
|
|
if (!files || files.length === 0) {
|
|
|
name = "No User Scripts detected";
|
|
|
}
|
|
|
else {
|
|
|
let count = 0;
|
|
|
for (const file of files) {
|
|
|
if (file.extension === "js") {
|
|
|
count++;
|
|
|
desc.append(desc.createEl("li", {
|
|
|
text: `tp.user.${file.basename}`,
|
|
|
}));
|
|
|
}
|
|
|
}
|
|
|
name = `Detected ${count} User Script(s)`;
|
|
|
}
|
|
|
}
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName(name)
|
|
|
.setDesc(desc)
|
|
|
.addExtraButton((extra) => {
|
|
|
extra
|
|
|
.setIcon("sync")
|
|
|
.setTooltip("Refresh")
|
|
|
.onClick(() => {
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
add_user_system_command_functions_setting() {
|
|
|
let desc = document.createDocumentFragment();
|
|
|
desc.append("Allows you to create user functions linked to system commands.", desc.createEl("br"), desc.createEl("b", {
|
|
|
text: "Warning: ",
|
|
|
}), "It can be dangerous to execute arbitrary system commands from untrusted sources. Only run system commands that you understand, from trusted sources.");
|
|
|
this.containerEl.createEl("h2", {
|
|
|
text: "User System Command Functions",
|
|
|
});
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Enable User System Command Functions")
|
|
|
.setDesc(desc)
|
|
|
.addToggle((toggle) => {
|
|
|
toggle
|
|
|
.setValue(this.plugin.settings.enable_system_commands)
|
|
|
.onChange((enable_system_commands) => {
|
|
|
this.plugin.settings.enable_system_commands =
|
|
|
enable_system_commands;
|
|
|
this.plugin.save_settings();
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
if (this.plugin.settings.enable_system_commands) {
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Timeout")
|
|
|
.setDesc("Maximum timeout in seconds for a system command.")
|
|
|
.addText((text) => {
|
|
|
text.setPlaceholder("Timeout")
|
|
|
.setValue(this.plugin.settings.command_timeout.toString())
|
|
|
.onChange((new_value) => {
|
|
|
const new_timeout = Number(new_value);
|
|
|
if (isNaN(new_timeout)) {
|
|
|
log_error(new TemplaterError("Timeout must be a number"));
|
|
|
return;
|
|
|
}
|
|
|
this.plugin.settings.command_timeout = new_timeout;
|
|
|
this.plugin.save_settings();
|
|
|
});
|
|
|
});
|
|
|
desc = document.createDocumentFragment();
|
|
|
desc.append("Full path to the shell binary to execute the command with.", desc.createEl("br"), "This setting is optional and will default to the system's default shell if not specified.", desc.createEl("br"), "You can use forward slashes ('/') as path separators on all platforms if in doubt.");
|
|
|
new obsidian_module.Setting(this.containerEl)
|
|
|
.setName("Shell binary location")
|
|
|
.setDesc(desc)
|
|
|
.addText((text) => {
|
|
|
text.setPlaceholder("Example: /bin/bash, ...")
|
|
|
.setValue(this.plugin.settings.shell_path)
|
|
|
.onChange((shell_path) => {
|
|
|
this.plugin.settings.shell_path = shell_path;
|
|
|
this.plugin.save_settings();
|
|
|
});
|
|
|
});
|
|
|
let i = 1;
|
|
|
this.plugin.settings.templates_pairs.forEach((template_pair) => {
|
|
|
const div = this.containerEl.createEl("div");
|
|
|
div.addClass("templater_div");
|
|
|
const title = this.containerEl.createEl("h4", {
|
|
|
text: "User Function n°" + i,
|
|
|
});
|
|
|
title.addClass("templater_title");
|
|
|
const setting = new obsidian_module.Setting(this.containerEl)
|
|
|
.addExtraButton((extra) => {
|
|
|
extra
|
|
|
.setIcon("cross")
|
|
|
.setTooltip("Delete")
|
|
|
.onClick(() => {
|
|
|
const index = this.plugin.settings.templates_pairs.indexOf(template_pair);
|
|
|
if (index > -1) {
|
|
|
this.plugin.settings.templates_pairs.splice(index, 1);
|
|
|
this.plugin.save_settings();
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
}
|
|
|
});
|
|
|
})
|
|
|
.addText((text) => {
|
|
|
const t = text
|
|
|
.setPlaceholder("Function name")
|
|
|
.setValue(template_pair[0])
|
|
|
.onChange((new_value) => {
|
|
|
const index = this.plugin.settings.templates_pairs.indexOf(template_pair);
|
|
|
if (index > -1) {
|
|
|
this.plugin.settings.templates_pairs[index][0] = new_value;
|
|
|
this.plugin.save_settings();
|
|
|
}
|
|
|
});
|
|
|
t.inputEl.addClass("templater_template");
|
|
|
return t;
|
|
|
})
|
|
|
.addTextArea((text) => {
|
|
|
const t = text
|
|
|
.setPlaceholder("System Command")
|
|
|
.setValue(template_pair[1])
|
|
|
.onChange((new_cmd) => {
|
|
|
const index = this.plugin.settings.templates_pairs.indexOf(template_pair);
|
|
|
if (index > -1) {
|
|
|
this.plugin.settings.templates_pairs[index][1] = new_cmd;
|
|
|
this.plugin.save_settings();
|
|
|
}
|
|
|
});
|
|
|
t.inputEl.setAttr("rows", 2);
|
|
|
t.inputEl.addClass("templater_cmd");
|
|
|
return t;
|
|
|
});
|
|
|
setting.infoEl.remove();
|
|
|
div.appendChild(title);
|
|
|
div.appendChild(this.containerEl.lastChild);
|
|
|
i += 1;
|
|
|
});
|
|
|
const div = this.containerEl.createEl("div");
|
|
|
div.addClass("templater_div2");
|
|
|
const setting = new obsidian_module.Setting(this.containerEl).addButton((button) => {
|
|
|
button
|
|
|
.setButtonText("Add New User Function")
|
|
|
.setCta()
|
|
|
.onClick(() => {
|
|
|
this.plugin.settings.templates_pairs.push(["", ""]);
|
|
|
this.plugin.save_settings();
|
|
|
// Force refresh
|
|
|
this.display();
|
|
|
});
|
|
|
});
|
|
|
setting.infoEl.remove();
|
|
|
div.appendChild(this.containerEl.lastChild);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var OpenMode;
|
|
|
(function (OpenMode) {
|
|
|
OpenMode[OpenMode["InsertTemplate"] = 0] = "InsertTemplate";
|
|
|
OpenMode[OpenMode["CreateNoteTemplate"] = 1] = "CreateNoteTemplate";
|
|
|
})(OpenMode || (OpenMode = {}));
|
|
|
class FuzzySuggester extends obsidian_module.FuzzySuggestModal {
|
|
|
constructor(app, plugin) {
|
|
|
super(app);
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
this.setPlaceholder("Type name of a template...");
|
|
|
}
|
|
|
getItems() {
|
|
|
if (!this.plugin.settings.templates_folder) {
|
|
|
return this.app.vault.getMarkdownFiles();
|
|
|
}
|
|
|
const files = errorWrapperSync(() => get_tfiles_from_folder(this.app, this.plugin.settings.templates_folder), `Couldn't retrieve template files from templates folder ${this.plugin.settings.templates_folder}`);
|
|
|
if (!files) {
|
|
|
return [];
|
|
|
}
|
|
|
return files;
|
|
|
}
|
|
|
getItemText(item) {
|
|
|
return item.basename;
|
|
|
}
|
|
|
onChooseItem(item) {
|
|
|
switch (this.open_mode) {
|
|
|
case OpenMode.InsertTemplate:
|
|
|
this.plugin.templater.append_template_to_active_file(item);
|
|
|
break;
|
|
|
case OpenMode.CreateNoteTemplate:
|
|
|
this.plugin.templater.create_new_note_from_template(item, this.creation_folder);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
start() {
|
|
|
try {
|
|
|
this.open();
|
|
|
}
|
|
|
catch (e) {
|
|
|
log_error(e);
|
|
|
}
|
|
|
}
|
|
|
insert_template() {
|
|
|
this.open_mode = OpenMode.InsertTemplate;
|
|
|
this.start();
|
|
|
}
|
|
|
create_new_note_from_template(folder) {
|
|
|
this.creation_folder = folder;
|
|
|
this.open_mode = OpenMode.CreateNoteTemplate;
|
|
|
this.start();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const UNSUPPORTED_MOBILE_TEMPLATE = "Error_MobileUnsupportedTemplate";
|
|
|
const ICON_DATA = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 51.1328 28.7"><path d="M0 15.14 0 10.15 18.67 1.51 18.67 6.03 4.72 12.33 4.72 12.76 18.67 19.22 18.67 23.74 0 15.14ZM33.6928 1.84C33.6928 1.84 33.9761 2.1467 34.5428 2.76C35.1094 3.38 35.3928 4.56 35.3928 6.3C35.3928 8.0466 34.8195 9.54 33.6728 10.78C32.5261 12.02 31.0995 12.64 29.3928 12.64C27.6862 12.64 26.2661 12.0267 25.1328 10.8C23.9928 9.5733 23.4228 8.0867 23.4228 6.34C23.4228 4.6 23.9995 3.1066 25.1528 1.86C26.2994.62 27.7261 0 29.4328 0C31.1395 0 32.5594.6133 33.6928 1.84M49.8228.67 29.5328 28.38 24.4128 28.38 44.7128.67 49.8228.67M31.0328 8.38C31.0328 8.38 31.1395 8.2467 31.3528 7.98C31.5662 7.7067 31.6728 7.1733 31.6728 6.38C31.6728 5.5867 31.4461 4.92 30.9928 4.38C30.5461 3.84 29.9995 3.57 29.3528 3.57C28.7061 3.57 28.1695 3.84 27.7428 4.38C27.3228 4.92 27.1128 5.5867 27.1128 6.38C27.1128 7.1733 27.3361 7.84 27.7828 8.38C28.2361 8.9267 28.7861 9.2 29.4328 9.2C30.0795 9.2 30.6128 8.9267 31.0328 8.38M49.4328 17.9C49.4328 17.9 49.7161 18.2067 50.2828 18.82C50.8495 19.4333 51.1328 20.6133 51.1328 22.36C51.1328 24.1 50.5594 25.59 49.4128 26.83C48.2595 28.0766 46.8295 28.7 45.1228 28.7C43.4228 28.7 42.0028 28.0833 40.8628 26.85C39.7295 25.6233 39.1628 24.1366 39.1628 22.39C39.1628 20.65 39.7361 19.16 40.8828 17.92C42.0361 16.6733 43.4628 16.05 45.1628 16.05C46.8694 16.05 48.2928 16.6667 49.4328 17.9M46.8528 24.52C46.8528 24.52 46.9595 24.3833 47.1728 24.11C47.3795 23.8367 47.4828 23.3033 47.4828 22.51C47.4828 21.7167 47.2595 21.05 46.8128 20.51C46.3661 19.97 45.8162 19.7 45.1628 19.7C44.5161 19.7 43.9828 19.97 43.5628 20.51C43.1428 21.05 42.9328 21.7167 42.9328 22.51C42.9328 23.3033 43.1561 23.9733 43.6028 24.52C44.0494 25.06 44.5961 25.33 45.2428 25.33C45.8895 25.33 46.4261 25.06 46.8528 24.52Z" fill="currentColor"/></svg>`;
|
|
|
|
|
|
class InternalModule {
|
|
|
constructor(app, plugin) {
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
this.static_functions = new Map();
|
|
|
this.dynamic_functions = new Map();
|
|
|
}
|
|
|
getName() {
|
|
|
return this.name;
|
|
|
}
|
|
|
init() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
yield this.create_static_templates();
|
|
|
this.static_object = Object.fromEntries(this.static_functions);
|
|
|
});
|
|
|
}
|
|
|
generate_object(new_config) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.config = new_config;
|
|
|
yield this.create_dynamic_templates();
|
|
|
return Object.assign(Object.assign({}, this.static_object), Object.fromEntries(this.dynamic_functions));
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class InternalModuleDate extends InternalModule {
|
|
|
constructor() {
|
|
|
super(...arguments);
|
|
|
this.name = "date";
|
|
|
}
|
|
|
create_static_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.static_functions.set("now", this.generate_now());
|
|
|
this.static_functions.set("tomorrow", this.generate_tomorrow());
|
|
|
this.static_functions.set("weekday", this.generate_weekday());
|
|
|
this.static_functions.set("yesterday", this.generate_yesterday());
|
|
|
});
|
|
|
}
|
|
|
create_dynamic_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () { });
|
|
|
}
|
|
|
generate_now() {
|
|
|
return (format = "YYYY-MM-DD", offset, reference, reference_format) => {
|
|
|
if (reference &&
|
|
|
!window.moment(reference, reference_format).isValid()) {
|
|
|
throw new TemplaterError("Invalid reference date format, try specifying one with the argument 'reference_format'");
|
|
|
}
|
|
|
let duration;
|
|
|
if (typeof offset === "string") {
|
|
|
duration = window.moment.duration(offset);
|
|
|
}
|
|
|
else if (typeof offset === "number") {
|
|
|
duration = window.moment.duration(offset, "days");
|
|
|
}
|
|
|
return window
|
|
|
.moment(reference, reference_format)
|
|
|
.add(duration)
|
|
|
.format(format);
|
|
|
};
|
|
|
}
|
|
|
generate_tomorrow() {
|
|
|
return (format = "YYYY-MM-DD") => {
|
|
|
return window.moment().add(1, "days").format(format);
|
|
|
};
|
|
|
}
|
|
|
generate_weekday() {
|
|
|
return (format = "YYYY-MM-DD", weekday, reference, reference_format) => {
|
|
|
if (reference &&
|
|
|
!window.moment(reference, reference_format).isValid()) {
|
|
|
throw new TemplaterError("Invalid reference date format, try specifying one with the argument 'reference_format'");
|
|
|
}
|
|
|
return window
|
|
|
.moment(reference, reference_format)
|
|
|
.weekday(weekday)
|
|
|
.format(format);
|
|
|
};
|
|
|
}
|
|
|
generate_yesterday() {
|
|
|
return (format = "YYYY-MM-DD") => {
|
|
|
return window.moment().add(-1, "days").format(format);
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const DEPTH_LIMIT = 10;
|
|
|
class InternalModuleFile extends InternalModule {
|
|
|
constructor() {
|
|
|
super(...arguments);
|
|
|
this.name = "file";
|
|
|
this.include_depth = 0;
|
|
|
this.create_new_depth = 0;
|
|
|
this.linkpath_regex = new RegExp("^\\[\\[(.*)\\]\\]$");
|
|
|
}
|
|
|
create_static_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.static_functions.set("creation_date", this.generate_creation_date());
|
|
|
this.static_functions.set("create_new", this.generate_create_new());
|
|
|
this.static_functions.set("cursor", this.generate_cursor());
|
|
|
this.static_functions.set("cursor_append", this.generate_cursor_append());
|
|
|
this.static_functions.set("exists", this.generate_exists());
|
|
|
this.static_functions.set("find_tfile", this.generate_find_tfile());
|
|
|
this.static_functions.set("folder", this.generate_folder());
|
|
|
this.static_functions.set("include", this.generate_include());
|
|
|
this.static_functions.set("last_modified_date", this.generate_last_modified_date());
|
|
|
this.static_functions.set("move", this.generate_move());
|
|
|
this.static_functions.set("path", this.generate_path());
|
|
|
this.static_functions.set("rename", this.generate_rename());
|
|
|
this.static_functions.set("selection", this.generate_selection());
|
|
|
});
|
|
|
}
|
|
|
create_dynamic_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.dynamic_functions.set("content", yield this.generate_content());
|
|
|
this.dynamic_functions.set("tags", this.generate_tags());
|
|
|
this.dynamic_functions.set("title", this.generate_title());
|
|
|
});
|
|
|
}
|
|
|
generate_content() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
return yield this.app.vault.read(this.config.target_file);
|
|
|
});
|
|
|
}
|
|
|
generate_create_new() {
|
|
|
return (template, filename, open_new = false, folder) => __awaiter(this, void 0, void 0, function* () {
|
|
|
this.create_new_depth += 1;
|
|
|
if (this.create_new_depth > DEPTH_LIMIT) {
|
|
|
this.create_new_depth = 0;
|
|
|
throw new TemplaterError("Reached create_new depth limit (max = 10)");
|
|
|
}
|
|
|
const new_file = yield this.plugin.templater.create_new_note_from_template(template, folder, filename, open_new);
|
|
|
this.create_new_depth -= 1;
|
|
|
return new_file;
|
|
|
});
|
|
|
}
|
|
|
generate_creation_date() {
|
|
|
return (format = "YYYY-MM-DD HH:mm") => {
|
|
|
return window
|
|
|
.moment(this.config.target_file.stat.ctime)
|
|
|
.format(format);
|
|
|
};
|
|
|
}
|
|
|
generate_cursor() {
|
|
|
return (order) => {
|
|
|
// Hack to prevent empty output
|
|
|
return `<% tp.file.cursor(${order !== null && order !== void 0 ? order : ""}) %>`;
|
|
|
};
|
|
|
}
|
|
|
generate_cursor_append() {
|
|
|
return (content) => {
|
|
|
const active_view = this.app.workspace.getActiveViewOfType(obsidian_module.MarkdownView);
|
|
|
if (active_view === null) {
|
|
|
log_error(new TemplaterError("No active view, can't append to cursor."));
|
|
|
return;
|
|
|
}
|
|
|
const editor = active_view.editor;
|
|
|
const doc = editor.getDoc();
|
|
|
doc.replaceSelection(content);
|
|
|
return "";
|
|
|
};
|
|
|
}
|
|
|
generate_exists() {
|
|
|
return (filename) => {
|
|
|
// TODO: Remove this, only here to support the old way
|
|
|
let match;
|
|
|
if ((match = this.linkpath_regex.exec(filename)) !== null) {
|
|
|
filename = match[1];
|
|
|
}
|
|
|
const file = this.app.metadataCache.getFirstLinkpathDest(filename, "");
|
|
|
return file != null;
|
|
|
};
|
|
|
}
|
|
|
generate_find_tfile() {
|
|
|
return (filename) => {
|
|
|
const path = obsidian_module.normalizePath(filename);
|
|
|
return this.app.metadataCache.getFirstLinkpathDest(path, "");
|
|
|
};
|
|
|
}
|
|
|
generate_folder() {
|
|
|
return (relative = false) => {
|
|
|
const parent = this.config.target_file.parent;
|
|
|
let folder;
|
|
|
if (relative) {
|
|
|
folder = parent.path;
|
|
|
}
|
|
|
else {
|
|
|
folder = parent.name;
|
|
|
}
|
|
|
return folder;
|
|
|
};
|
|
|
}
|
|
|
generate_include() {
|
|
|
return (include_link) => __awaiter(this, void 0, void 0, function* () {
|
|
|
var _a;
|
|
|
// TODO: Add mutex for this, this may currently lead to a race condition.
|
|
|
// While not very impactful, that could still be annoying.
|
|
|
this.include_depth += 1;
|
|
|
if (this.include_depth > DEPTH_LIMIT) {
|
|
|
this.include_depth -= 1;
|
|
|
throw new TemplaterError("Reached inclusion depth limit (max = 10)");
|
|
|
}
|
|
|
let inc_file_content;
|
|
|
if (include_link instanceof obsidian_module.TFile) {
|
|
|
inc_file_content = yield this.app.vault.read(include_link);
|
|
|
}
|
|
|
else {
|
|
|
let match;
|
|
|
if ((match = this.linkpath_regex.exec(include_link)) === null) {
|
|
|
this.include_depth -= 1;
|
|
|
throw new TemplaterError("Invalid file format, provide an obsidian link between quotes.");
|
|
|
}
|
|
|
const { path, subpath } = obsidian_module.parseLinktext(match[1]);
|
|
|
const inc_file = this.app.metadataCache.getFirstLinkpathDest(path, "");
|
|
|
if (!inc_file) {
|
|
|
this.include_depth -= 1;
|
|
|
throw new TemplaterError(`File ${include_link} doesn't exist`);
|
|
|
}
|
|
|
inc_file_content = yield this.app.vault.read(inc_file);
|
|
|
if (subpath) {
|
|
|
const cache = this.app.metadataCache.getFileCache(inc_file);
|
|
|
if (cache) {
|
|
|
const result = obsidian_module.resolveSubpath(cache, subpath);
|
|
|
if (result) {
|
|
|
inc_file_content = inc_file_content.slice(result.start.offset, (_a = result.end) === null || _a === void 0 ? void 0 : _a.offset);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
try {
|
|
|
const parsed_content = yield this.plugin.templater.parser.parse_commands(inc_file_content, this.plugin.templater.current_functions_object);
|
|
|
this.include_depth -= 1;
|
|
|
return parsed_content;
|
|
|
}
|
|
|
catch (e) {
|
|
|
this.include_depth -= 1;
|
|
|
throw e;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
generate_last_modified_date() {
|
|
|
return (format = "YYYY-MM-DD HH:mm") => {
|
|
|
return window
|
|
|
.moment(this.config.target_file.stat.mtime)
|
|
|
.format(format);
|
|
|
};
|
|
|
}
|
|
|
generate_move() {
|
|
|
return (path) => __awaiter(this, void 0, void 0, function* () {
|
|
|
const new_path = obsidian_module.normalizePath(`${path}.${this.config.target_file.extension}`);
|
|
|
yield this.app.fileManager.renameFile(this.config.target_file, new_path);
|
|
|
return "";
|
|
|
});
|
|
|
}
|
|
|
generate_path() {
|
|
|
return (relative = false) => {
|
|
|
// TODO: Add mobile support
|
|
|
if (obsidian_module.Platform.isMobileApp) {
|
|
|
return UNSUPPORTED_MOBILE_TEMPLATE;
|
|
|
}
|
|
|
if (!(this.app.vault.adapter instanceof obsidian_module.FileSystemAdapter)) {
|
|
|
throw new TemplaterError("app.vault is not a FileSystemAdapter instance");
|
|
|
}
|
|
|
const vault_path = this.app.vault.adapter.getBasePath();
|
|
|
if (relative) {
|
|
|
return this.config.target_file.path;
|
|
|
}
|
|
|
else {
|
|
|
return `${vault_path}/${this.config.target_file.path}`;
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
generate_rename() {
|
|
|
return (new_title) => __awaiter(this, void 0, void 0, function* () {
|
|
|
if (new_title.match(/[\\/:]+/g)) {
|
|
|
throw new TemplaterError("File name cannot contain any of these characters: \\ / :");
|
|
|
}
|
|
|
const new_path = obsidian_module.normalizePath(`${this.config.target_file.parent.path}/${new_title}.${this.config.target_file.extension}`);
|
|
|
yield this.app.fileManager.renameFile(this.config.target_file, new_path);
|
|
|
return "";
|
|
|
});
|
|
|
}
|
|
|
generate_selection() {
|
|
|
return () => {
|
|
|
const active_view = this.app.workspace.getActiveViewOfType(obsidian_module.MarkdownView);
|
|
|
if (active_view == null) {
|
|
|
throw new TemplaterError("Active view is null, can't read selection.");
|
|
|
}
|
|
|
const editor = active_view.editor;
|
|
|
return editor.getSelection();
|
|
|
};
|
|
|
}
|
|
|
// TODO: Turn this into a function
|
|
|
generate_tags() {
|
|
|
const cache = this.app.metadataCache.getFileCache(this.config.target_file);
|
|
|
return obsidian_module.getAllTags(cache);
|
|
|
}
|
|
|
// TODO: Turn this into a function
|
|
|
generate_title() {
|
|
|
return this.config.target_file.basename;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class InternalModuleWeb extends InternalModule {
|
|
|
constructor() {
|
|
|
super(...arguments);
|
|
|
this.name = "web";
|
|
|
}
|
|
|
create_static_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.static_functions.set("daily_quote", this.generate_daily_quote());
|
|
|
this.static_functions.set("random_picture", this.generate_random_picture());
|
|
|
});
|
|
|
}
|
|
|
create_dynamic_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () { });
|
|
|
}
|
|
|
getRequest(url) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const response = yield fetch(url);
|
|
|
if (!response.ok) {
|
|
|
throw new TemplaterError("Error performing GET request");
|
|
|
}
|
|
|
return response;
|
|
|
});
|
|
|
}
|
|
|
generate_daily_quote() {
|
|
|
return () => __awaiter(this, void 0, void 0, function* () {
|
|
|
const response = yield this.getRequest("https://api.quotable.io/random");
|
|
|
const json = yield response.json();
|
|
|
const author = json.author;
|
|
|
const quote = json.content;
|
|
|
const new_content = `> ${quote}\n> — <cite>${author}</cite>`;
|
|
|
return new_content;
|
|
|
});
|
|
|
}
|
|
|
generate_random_picture() {
|
|
|
return (size, query) => __awaiter(this, void 0, void 0, function* () {
|
|
|
const response = yield this.getRequest(`https://source.unsplash.com/random/${size !== null && size !== void 0 ? size : ""}?${query !== null && query !== void 0 ? query : ""}`);
|
|
|
const url = response.url;
|
|
|
return `![tp.web.random_picture](${url})`;
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class InternalModuleFrontmatter extends InternalModule {
|
|
|
constructor() {
|
|
|
super(...arguments);
|
|
|
this.name = "frontmatter";
|
|
|
}
|
|
|
create_static_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () { });
|
|
|
}
|
|
|
create_dynamic_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const cache = this.app.metadataCache.getFileCache(this.config.target_file);
|
|
|
this.dynamic_functions = new Map(Object.entries((cache === null || cache === void 0 ? void 0 : cache.frontmatter) || {}));
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class PromptModal extends obsidian_module.Modal {
|
|
|
constructor(app, prompt_text, default_value) {
|
|
|
super(app);
|
|
|
this.prompt_text = prompt_text;
|
|
|
this.default_value = default_value;
|
|
|
this.submitted = false;
|
|
|
}
|
|
|
onOpen() {
|
|
|
this.titleEl.setText(this.prompt_text);
|
|
|
this.createForm();
|
|
|
}
|
|
|
onClose() {
|
|
|
this.contentEl.empty();
|
|
|
if (!this.submitted) {
|
|
|
this.reject(new TemplaterError("Cancelled prompt"));
|
|
|
}
|
|
|
}
|
|
|
createForm() {
|
|
|
var _a;
|
|
|
const div = this.contentEl.createDiv();
|
|
|
div.addClass("templater-prompt-div");
|
|
|
const form = div.createEl("form");
|
|
|
form.addClass("templater-prompt-form");
|
|
|
form.type = "submit";
|
|
|
form.onsubmit = (e) => {
|
|
|
this.submitted = true;
|
|
|
e.preventDefault();
|
|
|
this.resolve(this.promptEl.value);
|
|
|
this.close();
|
|
|
};
|
|
|
this.promptEl = form.createEl("input");
|
|
|
this.promptEl.type = "text";
|
|
|
this.promptEl.placeholder = "Type text here...";
|
|
|
this.promptEl.value = (_a = this.default_value) !== null && _a !== void 0 ? _a : "";
|
|
|
this.promptEl.addClass("templater-prompt-input");
|
|
|
this.promptEl.select();
|
|
|
}
|
|
|
openAndGetValue(resolve, reject) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.resolve = resolve;
|
|
|
this.reject = reject;
|
|
|
this.open();
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class SuggesterModal extends obsidian_module.FuzzySuggestModal {
|
|
|
constructor(app, text_items, items, placeholder) {
|
|
|
super(app);
|
|
|
this.text_items = text_items;
|
|
|
this.items = items;
|
|
|
this.submitted = false;
|
|
|
this.setPlaceholder(placeholder);
|
|
|
}
|
|
|
getItems() {
|
|
|
return this.items;
|
|
|
}
|
|
|
onClose() {
|
|
|
if (!this.submitted) {
|
|
|
this.reject(new TemplaterError("Cancelled prompt"));
|
|
|
}
|
|
|
}
|
|
|
selectSuggestion(value, evt) {
|
|
|
this.submitted = true;
|
|
|
this.close();
|
|
|
this.onChooseSuggestion(value, evt);
|
|
|
}
|
|
|
getItemText(item) {
|
|
|
if (this.text_items instanceof Function) {
|
|
|
return this.text_items(item);
|
|
|
}
|
|
|
return (this.text_items[this.items.indexOf(item)] || "Undefined Text Item");
|
|
|
}
|
|
|
onChooseItem(item) {
|
|
|
this.resolve(item);
|
|
|
}
|
|
|
openAndGetValue(resolve, reject) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.resolve = resolve;
|
|
|
this.reject = reject;
|
|
|
this.open();
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class InternalModuleSystem extends InternalModule {
|
|
|
constructor() {
|
|
|
super(...arguments);
|
|
|
this.name = "system";
|
|
|
}
|
|
|
create_static_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.static_functions.set("clipboard", this.generate_clipboard());
|
|
|
this.static_functions.set("prompt", this.generate_prompt());
|
|
|
this.static_functions.set("suggester", this.generate_suggester());
|
|
|
});
|
|
|
}
|
|
|
create_dynamic_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () { });
|
|
|
}
|
|
|
generate_clipboard() {
|
|
|
return () => __awaiter(this, void 0, void 0, function* () {
|
|
|
// TODO: Add mobile support
|
|
|
if (obsidian_module.Platform.isMobileApp) {
|
|
|
return UNSUPPORTED_MOBILE_TEMPLATE;
|
|
|
}
|
|
|
return yield navigator.clipboard.readText();
|
|
|
});
|
|
|
}
|
|
|
generate_prompt() {
|
|
|
return (prompt_text, default_value, throw_on_cancel = false) => __awaiter(this, void 0, void 0, function* () {
|
|
|
const prompt = new PromptModal(this.app, prompt_text, default_value);
|
|
|
const promise = new Promise((resolve, reject) => prompt.openAndGetValue(resolve, reject));
|
|
|
try {
|
|
|
return yield promise;
|
|
|
}
|
|
|
catch (error) {
|
|
|
if (throw_on_cancel) {
|
|
|
throw error;
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
generate_suggester() {
|
|
|
return (text_items, items, throw_on_cancel = false, placeholder = "") => __awaiter(this, void 0, void 0, function* () {
|
|
|
const suggester = new SuggesterModal(this.app, text_items, items, placeholder);
|
|
|
const promise = new Promise((resolve, reject) => suggester.openAndGetValue(resolve, reject));
|
|
|
try {
|
|
|
return yield promise;
|
|
|
}
|
|
|
catch (error) {
|
|
|
if (throw_on_cancel) {
|
|
|
throw error;
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class InternalModuleConfig extends InternalModule {
|
|
|
constructor() {
|
|
|
super(...arguments);
|
|
|
this.name = "config";
|
|
|
}
|
|
|
create_static_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () { });
|
|
|
}
|
|
|
create_dynamic_templates() {
|
|
|
return __awaiter(this, void 0, void 0, function* () { });
|
|
|
}
|
|
|
generate_object(config) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
return config;
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class InternalFunctions {
|
|
|
constructor(app, plugin) {
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
this.modules_array = [];
|
|
|
this.modules_array.push(new InternalModuleDate(this.app, this.plugin));
|
|
|
this.modules_array.push(new InternalModuleFile(this.app, this.plugin));
|
|
|
this.modules_array.push(new InternalModuleWeb(this.app, this.plugin));
|
|
|
this.modules_array.push(new InternalModuleFrontmatter(this.app, this.plugin));
|
|
|
this.modules_array.push(new InternalModuleSystem(this.app, this.plugin));
|
|
|
this.modules_array.push(new InternalModuleConfig(this.app, this.plugin));
|
|
|
}
|
|
|
init() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
for (const mod of this.modules_array) {
|
|
|
yield mod.init();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
generate_object(config) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const internal_functions_object = {};
|
|
|
for (const mod of this.modules_array) {
|
|
|
internal_functions_object[mod.getName()] =
|
|
|
yield mod.generate_object(config);
|
|
|
}
|
|
|
return internal_functions_object;
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class UserSystemFunctions {
|
|
|
constructor(app, plugin) {
|
|
|
this.plugin = plugin;
|
|
|
if (obsidian_module.Platform.isMobileApp ||
|
|
|
!(app.vault.adapter instanceof obsidian_module.FileSystemAdapter)) {
|
|
|
this.cwd = "";
|
|
|
}
|
|
|
else {
|
|
|
this.cwd = app.vault.adapter.getBasePath();
|
|
|
this.exec_promise = util.promisify(child_process.exec);
|
|
|
}
|
|
|
}
|
|
|
// TODO: Add mobile support
|
|
|
generate_system_functions(config) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const user_system_functions = new Map();
|
|
|
const internal_functions_object = yield this.plugin.templater.functions_generator.generate_object(config, FunctionsMode.INTERNAL);
|
|
|
for (const template_pair of this.plugin.settings.templates_pairs) {
|
|
|
const template = template_pair[0];
|
|
|
let cmd = template_pair[1];
|
|
|
if (!template || !cmd) {
|
|
|
continue;
|
|
|
}
|
|
|
if (obsidian_module.Platform.isMobileApp) {
|
|
|
user_system_functions.set(template, () => {
|
|
|
return new Promise((resolve) => resolve(UNSUPPORTED_MOBILE_TEMPLATE));
|
|
|
});
|
|
|
}
|
|
|
else {
|
|
|
cmd = yield this.plugin.templater.parser.parse_commands(cmd, internal_functions_object);
|
|
|
user_system_functions.set(template, (user_args) => __awaiter(this, void 0, void 0, function* () {
|
|
|
const process_env = Object.assign(Object.assign({}, process.env), user_args);
|
|
|
const cmd_options = Object.assign({ timeout: this.plugin.settings.command_timeout * 1000, cwd: this.cwd, env: process_env }, (this.plugin.settings.shell_path && {
|
|
|
shell: this.plugin.settings.shell_path,
|
|
|
}));
|
|
|
try {
|
|
|
const { stdout } = yield this.exec_promise(cmd, cmd_options);
|
|
|
return stdout.trimRight();
|
|
|
}
|
|
|
catch (error) {
|
|
|
throw new TemplaterError(`Error with User Template ${template}`, error);
|
|
|
}
|
|
|
}));
|
|
|
}
|
|
|
}
|
|
|
return user_system_functions;
|
|
|
});
|
|
|
}
|
|
|
generate_object(config) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const user_system_functions = yield this.generate_system_functions(config);
|
|
|
return Object.fromEntries(user_system_functions);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class UserScriptFunctions {
|
|
|
constructor(app, plugin) {
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
}
|
|
|
generate_user_script_functions(config) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const user_script_functions = new Map();
|
|
|
const files = errorWrapperSync(() => get_tfiles_from_folder(this.app, this.plugin.settings.user_scripts_folder), `Couldn't find user script folder "${this.plugin.settings.user_scripts_folder}"`);
|
|
|
if (!files) {
|
|
|
return new Map();
|
|
|
}
|
|
|
for (const file of files) {
|
|
|
if (file.extension.toLowerCase() === "js") {
|
|
|
yield this.load_user_script_function(config, file, user_script_functions);
|
|
|
}
|
|
|
}
|
|
|
return user_script_functions;
|
|
|
});
|
|
|
}
|
|
|
load_user_script_function(config, file, user_script_functions) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
if (!(this.app.vault.adapter instanceof obsidian_module.FileSystemAdapter)) {
|
|
|
throw new TemplaterError("app.vault is not a FileSystemAdapter instance");
|
|
|
}
|
|
|
const vault_path = this.app.vault.adapter.getBasePath();
|
|
|
const file_path = `${vault_path}/${file.path}`;
|
|
|
// https://stackoverflow.com/questions/26633901/reload-module-at-runtime
|
|
|
// https://stackoverflow.com/questions/1972242/how-to-auto-reload-files-in-node-js
|
|
|
if (Object.keys(window.require.cache).contains(file_path)) {
|
|
|
delete window.require.cache[window.require.resolve(file_path)];
|
|
|
}
|
|
|
const user_function = yield Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(file_path)); });
|
|
|
if (!user_function.default) {
|
|
|
throw new TemplaterError(`Failed to load user script ${file_path}. No exports detected.`);
|
|
|
}
|
|
|
if (!(user_function.default instanceof Function)) {
|
|
|
throw new TemplaterError(`Failed to load user script ${file_path}. Default export is not a function.`);
|
|
|
}
|
|
|
user_script_functions.set(`${file.basename}`, user_function.default);
|
|
|
});
|
|
|
}
|
|
|
generate_object(config) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const user_script_functions = yield this.generate_user_script_functions(config);
|
|
|
return Object.fromEntries(user_script_functions);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class UserFunctions {
|
|
|
constructor(app, plugin) {
|
|
|
this.plugin = plugin;
|
|
|
this.user_system_functions = new UserSystemFunctions(app, plugin);
|
|
|
this.user_script_functions = new UserScriptFunctions(app, plugin);
|
|
|
}
|
|
|
generate_object(config) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
let user_system_functions = {};
|
|
|
let user_script_functions = {};
|
|
|
if (this.plugin.settings.enable_system_commands) {
|
|
|
user_system_functions =
|
|
|
yield this.user_system_functions.generate_object(config);
|
|
|
}
|
|
|
// TODO: Add mobile support
|
|
|
// user_scripts_folder needs to be explicitly set to '/' to query from root
|
|
|
if (obsidian_module.Platform.isDesktopApp && this.plugin.settings.user_scripts_folder) {
|
|
|
user_script_functions =
|
|
|
yield this.user_script_functions.generate_object(config);
|
|
|
}
|
|
|
return Object.assign(Object.assign({}, user_system_functions), user_script_functions);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var FunctionsMode;
|
|
|
(function (FunctionsMode) {
|
|
|
FunctionsMode[FunctionsMode["INTERNAL"] = 0] = "INTERNAL";
|
|
|
FunctionsMode[FunctionsMode["USER_INTERNAL"] = 1] = "USER_INTERNAL";
|
|
|
})(FunctionsMode || (FunctionsMode = {}));
|
|
|
class FunctionsGenerator {
|
|
|
constructor(app, plugin) {
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
this.internal_functions = new InternalFunctions(this.app, this.plugin);
|
|
|
this.user_functions = new UserFunctions(this.app, this.plugin);
|
|
|
}
|
|
|
init() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
yield this.internal_functions.init();
|
|
|
});
|
|
|
}
|
|
|
additional_functions() {
|
|
|
return {
|
|
|
obsidian: obsidian_module__namespace,
|
|
|
};
|
|
|
}
|
|
|
generate_object(config, functions_mode = FunctionsMode.USER_INTERNAL) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const final_object = {};
|
|
|
const additional_functions_object = this.additional_functions();
|
|
|
const internal_functions_object = yield this.internal_functions.generate_object(config);
|
|
|
let user_functions_object = {};
|
|
|
Object.assign(final_object, additional_functions_object);
|
|
|
switch (functions_mode) {
|
|
|
case FunctionsMode.INTERNAL:
|
|
|
Object.assign(final_object, internal_functions_object);
|
|
|
break;
|
|
|
case FunctionsMode.USER_INTERNAL:
|
|
|
user_functions_object =
|
|
|
yield this.user_functions.generate_object(config);
|
|
|
Object.assign(final_object, Object.assign(Object.assign({}, internal_functions_object), { user: user_functions_object }));
|
|
|
break;
|
|
|
}
|
|
|
return final_object;
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class CursorJumper {
|
|
|
constructor(app) {
|
|
|
this.app = app;
|
|
|
}
|
|
|
jump_to_next_cursor_location() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const active_view = this.app.workspace.getActiveViewOfType(obsidian_module.MarkdownView);
|
|
|
if (!active_view) {
|
|
|
return;
|
|
|
}
|
|
|
const active_file = active_view.file;
|
|
|
yield active_view.save();
|
|
|
const content = yield this.app.vault.read(active_file);
|
|
|
const { new_content, positions } = this.replace_and_get_cursor_positions(content);
|
|
|
if (positions) {
|
|
|
yield this.app.vault.modify(active_file, new_content);
|
|
|
this.set_cursor_location(positions);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
get_editor_position_from_index(content, index) {
|
|
|
const substr = content.substr(0, index);
|
|
|
let l = 0;
|
|
|
let offset = -1;
|
|
|
let r = -1;
|
|
|
for (; (r = substr.indexOf("\n", r + 1)) !== -1; l++, offset = r)
|
|
|
;
|
|
|
offset += 1;
|
|
|
const ch = content.substr(offset, index - offset).length;
|
|
|
return { line: l, ch: ch };
|
|
|
}
|
|
|
replace_and_get_cursor_positions(content) {
|
|
|
let cursor_matches = [];
|
|
|
let match;
|
|
|
const cursor_regex = new RegExp("<%\\s*tp.file.cursor\\((?<order>[0-9]{0,2})\\)\\s*%>", "g");
|
|
|
while ((match = cursor_regex.exec(content)) != null) {
|
|
|
cursor_matches.push(match);
|
|
|
}
|
|
|
if (cursor_matches.length === 0) {
|
|
|
return {};
|
|
|
}
|
|
|
cursor_matches.sort((m1, m2) => {
|
|
|
return Number(m1.groups["order"]) - Number(m2.groups["order"]);
|
|
|
});
|
|
|
const match_str = cursor_matches[0][0];
|
|
|
cursor_matches = cursor_matches.filter((m) => {
|
|
|
return m[0] === match_str;
|
|
|
});
|
|
|
const positions = [];
|
|
|
let index_offset = 0;
|
|
|
for (const match of cursor_matches) {
|
|
|
const index = match.index - index_offset;
|
|
|
positions.push(this.get_editor_position_from_index(content, index));
|
|
|
content = content.replace(new RegExp(escape_RegExp(match[0])), "");
|
|
|
index_offset += match[0].length;
|
|
|
// For tp.file.cursor(), we keep the default top to bottom
|
|
|
if (match[1] === "") {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return { new_content: content, positions: positions };
|
|
|
}
|
|
|
set_cursor_location(positions) {
|
|
|
const active_view = this.app.workspace.getActiveViewOfType(obsidian_module.MarkdownView);
|
|
|
if (!active_view) {
|
|
|
return;
|
|
|
}
|
|
|
const editor = active_view.editor;
|
|
|
editor.focus();
|
|
|
const selections = [];
|
|
|
for (const pos of positions) {
|
|
|
selections.push({ from: pos });
|
|
|
}
|
|
|
const transaction = {
|
|
|
selections: selections,
|
|
|
};
|
|
|
editor.transaction(transaction);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const tp = {
|
|
|
config: {
|
|
|
name: "config",
|
|
|
description: "This module exposes Templater's running configuration.\n\nThis is mostly useful when writing scripts requiring some context informations.\n",
|
|
|
functions: {
|
|
|
template_file: {
|
|
|
name: "template_file",
|
|
|
description: "The `TFile` object representing the template file.",
|
|
|
definition: "tp.file.template_file"
|
|
|
},
|
|
|
target_file: {
|
|
|
name: "target_file",
|
|
|
description: "The `TFile` object representing the target file where the template will be inserted.",
|
|
|
definition: "tp.config.target_file"
|
|
|
},
|
|
|
run_mode: {
|
|
|
name: "run_mode",
|
|
|
description: "The `RunMode`, representing the way Templater was launched (Create new from template, Append to active file, ...)",
|
|
|
definition: "tp.config.run_mode"
|
|
|
},
|
|
|
active_file: {
|
|
|
name: "active_file",
|
|
|
description: "The active file (if existing) when launching Templater.",
|
|
|
definition: "tp.config.active_file?"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
date: {
|
|
|
name: "date",
|
|
|
description: "This module contains every internal function related to dates.",
|
|
|
functions: {
|
|
|
now: {
|
|
|
name: "now",
|
|
|
description: "Retrieves the date.",
|
|
|
definition: "tp.date.now(format: string = \"YYYY-MM-DD\", offset?: number⎮string, reference?: string, reference_format?: string)",
|
|
|
args: {
|
|
|
format: {
|
|
|
name: "format",
|
|
|
description: "Format for the date, refer to [format reference](https://momentjs.com/docs/#/displaying/format/)"
|
|
|
},
|
|
|
offset: {
|
|
|
name: "offset",
|
|
|
description: "Offset for the day, e.g. set this to `-7` to get last week's date. You can also specify the offset as a string using the ISO 8601 format"
|
|
|
},
|
|
|
reference: {
|
|
|
name: "reference",
|
|
|
description: "The date referential, e.g. set this to the note's title"
|
|
|
},
|
|
|
reference_format: {
|
|
|
name: "reference_format",
|
|
|
description: "The date reference format."
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
tomorrow: {
|
|
|
name: "tomorrow",
|
|
|
description: "Retrieves tomorrow's date.",
|
|
|
definition: "tp.date.tomorrow(format: string = \"YYYY-MM-DD\")",
|
|
|
args: {
|
|
|
format: {
|
|
|
name: "format",
|
|
|
description: "Format for the date, refer to [format reference](https://momentjs.com/docs/#/displaying/format/)"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
yesterday: {
|
|
|
name: "yesterday",
|
|
|
description: "Retrieves yesterday's date.",
|
|
|
definition: "tp.date.yesterday(format: string = \"YYYY-MM-DD\")",
|
|
|
args: {
|
|
|
format: {
|
|
|
name: "format",
|
|
|
description: "Format for the date, refer to [format reference](https://momentjs.com/docs/#/displaying/format/)"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
weekday: {
|
|
|
name: "weekday",
|
|
|
description: "",
|
|
|
definition: "tp.date.weekday(format: string = \"YYYY-MM-DD\", weekday: number, reference?: string, reference_format?: string)",
|
|
|
args: {
|
|
|
format: {
|
|
|
name: "format",
|
|
|
description: "Format for the date, refer to [format reference](https://momentjs.com/docs/#/displaying/format/)"
|
|
|
},
|
|
|
weekday: {
|
|
|
name: "weekday",
|
|
|
description: "Week day number. If the locale assigns Monday as the first day of the week, `0` will be Monday, `-7` will be last week's day."
|
|
|
},
|
|
|
reference: {
|
|
|
name: "reference",
|
|
|
description: "The date referential, e.g. set this to the note's title"
|
|
|
},
|
|
|
reference_format: {
|
|
|
name: "reference_format",
|
|
|
description: "The date reference format."
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
file: {
|
|
|
name: "file",
|
|
|
description: "This module contains every internal function related to files.",
|
|
|
functions: {
|
|
|
content: {
|
|
|
name: "content",
|
|
|
description: "Retrieves the file's content",
|
|
|
definition: "tp.file.content"
|
|
|
},
|
|
|
create_new: {
|
|
|
name: "create_new",
|
|
|
description: "Creates a new file using a specified template or with a specified content.",
|
|
|
definition: "tp.file.create_new(template: TFile ⎮ string, filename?: string, open_new: boolean = false, folder?: TFolder)",
|
|
|
args: {
|
|
|
template: {
|
|
|
name: "template",
|
|
|
description: "Either the template used for the new file content, or the file content as a string."
|
|
|
},
|
|
|
filename: {
|
|
|
name: "filename",
|
|
|
description: "The filename of the new file, defaults to \"Untitled\"."
|
|
|
},
|
|
|
open_new: {
|
|
|
name: "open_new",
|
|
|
description: "Whether to open or not the newly created file. Warning: if you use this option, since commands are executed asynchronously, the file can be opened first and then other commands are appended to that new file and not the previous file."
|
|
|
},
|
|
|
folder: {
|
|
|
name: "folder",
|
|
|
description: "The folder to put the new file in, defaults to obsidian's default location."
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
creation_date: {
|
|
|
name: "creation_date",
|
|
|
description: "Retrieves the file's creation date.",
|
|
|
definition: "tp.file.creation_date(format: string = \"YYYY-MM-DD HH:mm\")",
|
|
|
args: {
|
|
|
format: {
|
|
|
name: "format",
|
|
|
description: "Format for the date, refer to format reference"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
cursor: {
|
|
|
name: "cursor",
|
|
|
description: "Sets the cursor to this location after the template has been inserted. \n\nYou can navigate between the different tp.file.cursor using the configured hotkey in obsidian settings.\n",
|
|
|
definition: "tp.file.cursor(order?: number)",
|
|
|
args: {
|
|
|
order: {
|
|
|
name: "order",
|
|
|
description: "The order of the different cursors jump, e.g. it will jump from 1 to 2 to 3, and so on.\nIf you specify multiple tp.file.cursor with the same order, the editor will switch to multi-cursor.\n"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
cursor_append: {
|
|
|
name: "cursor_append",
|
|
|
description: "Appends some content after the active cursor in the file.",
|
|
|
definition: "tp.file.cursor_append(content: string)",
|
|
|
args: {
|
|
|
content: {
|
|
|
name: "content",
|
|
|
description: "The content to append after the active cursor"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
exists: {
|
|
|
name: "exists",
|
|
|
description: "Checks if a file exists or not. Returns a true / false boolean.",
|
|
|
definition: "tp.file.exists(filename: string)",
|
|
|
args: {
|
|
|
filename: {
|
|
|
name: "filename",
|
|
|
description: "The filename of the file we want to check existence, e.g. MyFile."
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
find_tfile: {
|
|
|
name: "find_tfile",
|
|
|
description: "Retrieves the file's folder name.",
|
|
|
definition: "tp.file.folder(relative: boolean = false)",
|
|
|
args: {
|
|
|
relative: {
|
|
|
name: "relative",
|
|
|
description: "If set to true, appends the vault relative path to the folder name."
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
include: {
|
|
|
name: "include",
|
|
|
description: "Includes the file's link content. Templates in the included content will be resolved.",
|
|
|
definition: "tp.file.include(include_link: string ⎮ TFile)",
|
|
|
args: {
|
|
|
include_link: {
|
|
|
name: "include_link",
|
|
|
description: "The link to the file to include, e.g. [[MyFile]], or a TFile object. Also supports sections or blocks inclusions, e.g. [[MyFile#Section1]]"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
last_modified_date: {
|
|
|
name: "last_modified_date",
|
|
|
description: "Retrieves the file's last modification date.",
|
|
|
definition: "tp.file.last_modified_date(format: string = \"YYYY-MM-DD HH:mm\")",
|
|
|
args: {
|
|
|
format: {
|
|
|
name: "format",
|
|
|
description: "Format for the date, refer to format reference."
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
move: {
|
|
|
name: "functions.move",
|
|
|
description: "Moves the file to the desired vault location.",
|
|
|
definition: "tp.file.move(new_path: string)",
|
|
|
args: {
|
|
|
new_path: {
|
|
|
name: "new_path",
|
|
|
description: "The new vault relative path of the file, without the file extension. Note: the new path needs to include the folder and the filename, e.g. /Notes/MyNote"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
path: {
|
|
|
name: "path",
|
|
|
description: "Retrieves the file's absolute path on the system.",
|
|
|
definition: "tp.file.path(relative: boolean = false)",
|
|
|
args: {
|
|
|
relative: {
|
|
|
name: "relative",
|
|
|
description: "If set to true, only retrieves the vault's relative path."
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
rename: {
|
|
|
name: "rename",
|
|
|
description: "Renames the file (keeps the same file extension).",
|
|
|
definition: "tp.file.rename(new_title: string)",
|
|
|
args: {
|
|
|
new_title: {
|
|
|
name: "new_title",
|
|
|
description: "The new file title."
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
selection: {
|
|
|
name: "selection",
|
|
|
description: "Retrieves the active file's text selection.",
|
|
|
definition: "tp.file.selection()"
|
|
|
},
|
|
|
tags: {
|
|
|
name: "tags",
|
|
|
description: "Retrieves the file's tags (array of string)",
|
|
|
definition: "tp.file.tags"
|
|
|
},
|
|
|
title: {
|
|
|
name: "title",
|
|
|
definition: "tp.file.title",
|
|
|
description: "Retrieves the file's title."
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
frontmatter: {
|
|
|
name: "frontmatter",
|
|
|
description: "This modules exposes all the frontmatter variables of a file as variables."
|
|
|
},
|
|
|
obsidian: {
|
|
|
name: "obsidian",
|
|
|
description: "This module exposes all the functions and classes from the obsidian API."
|
|
|
},
|
|
|
system: {
|
|
|
name: "system",
|
|
|
description: "This module contains system related functions.",
|
|
|
functions: {
|
|
|
clipboard: {
|
|
|
name: "clipboard",
|
|
|
description: "Retrieves the clipboard's content",
|
|
|
definition: "tp.system.clipboard()"
|
|
|
},
|
|
|
prompt: {
|
|
|
name: "prompt",
|
|
|
description: "Spawns a prompt modal and returns the user's input.",
|
|
|
definition: "tp.system.prompt(prompt_text?: string, default_value?: string, throw_on_cancel: boolean = false)",
|
|
|
args: {
|
|
|
prompt_text: {
|
|
|
name: "prompt_text",
|
|
|
description: "Text placed above the input field"
|
|
|
},
|
|
|
default_value: {
|
|
|
name: "default_value",
|
|
|
description: "A default value for the input field"
|
|
|
},
|
|
|
throw_on_cancel: {
|
|
|
name: "throw_on_cancel",
|
|
|
description: "Throws an error if the prompt is canceled, instead of returning a `null` value"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
suggester: {
|
|
|
name: "suggester",
|
|
|
description: "Spawns a suggester prompt and returns the user's chosen item.",
|
|
|
definition: "tp.system.suggester(text_items: string[] ⎮ ((item: T) => string), items: T[], throw_on_cancel: boolean = false, placeholder: string = \"\")",
|
|
|
args: {
|
|
|
text_items: {
|
|
|
name: "text_items",
|
|
|
description: "Array of strings representing the text that will be displayed for each item in the suggester prompt. This can also be a function that maps an item to its text representation."
|
|
|
},
|
|
|
items: {
|
|
|
name: "items",
|
|
|
description: "Array containing the values of each item in the correct order."
|
|
|
},
|
|
|
throw_on_cancel: {
|
|
|
name: "throw_on_cancel",
|
|
|
description: "Throws an error if the prompt is canceled, instead of returning a `null` value"
|
|
|
},
|
|
|
placeholder: {
|
|
|
name: "placeholder",
|
|
|
description: "Placeholder string of the prompt"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
web: {
|
|
|
name: "web",
|
|
|
description: "This modules contains every internal function related to the web (making web requests).",
|
|
|
functions: {
|
|
|
daily_quote: {
|
|
|
name: "daily_quote",
|
|
|
description: "Retrieves and parses the daily quote from the API https://api.quotable.io",
|
|
|
definition: "tp.web.daily_quote()"
|
|
|
},
|
|
|
random_picture: {
|
|
|
name: "random_picture",
|
|
|
description: "Gets a random image from https://unsplash.com/",
|
|
|
definition: "tp.web.random_picture(size?: string, query?: string)",
|
|
|
args: {
|
|
|
size: {
|
|
|
name: "size",
|
|
|
description: "Image size in the format `<width>x<height>`"
|
|
|
},
|
|
|
query: {
|
|
|
name: "query",
|
|
|
description: "Limits selection to photos matching a search term. Multiple search terms can be passed separated by a comma `,`"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
var documentation = {
|
|
|
tp
|
|
|
};
|
|
|
|
|
|
const module_names = ["config", "date", "file", "frontmatter", "obsidian", "system", "user", "web"];
|
|
|
const module_names_checker = new Set(module_names);
|
|
|
function is_module_name(x) {
|
|
|
return typeof x === "string" && module_names_checker.has(x);
|
|
|
}
|
|
|
function is_function_documentation(x) {
|
|
|
if (x.definition) {
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
class Documentation {
|
|
|
constructor(app) {
|
|
|
this.app = app;
|
|
|
this.documentation = documentation;
|
|
|
}
|
|
|
get_all_modules_documentation() {
|
|
|
return Object.values(this.documentation.tp);
|
|
|
}
|
|
|
get_all_functions_documentation(module_name) {
|
|
|
if (!this.documentation.tp[module_name].functions) {
|
|
|
return null;
|
|
|
}
|
|
|
return Object.values(this.documentation.tp[module_name].functions);
|
|
|
}
|
|
|
get_module_documentation(module_name) {
|
|
|
return this.documentation.tp[module_name];
|
|
|
}
|
|
|
get_function_documentation(module_name, function_name) {
|
|
|
return this.documentation.tp[module_name].functions[function_name];
|
|
|
}
|
|
|
get_argument_documentation(module_name, function_name, argument_name) {
|
|
|
const function_doc = this.get_function_documentation(module_name, function_name);
|
|
|
if (!function_doc || !function_doc.args) {
|
|
|
return null;
|
|
|
}
|
|
|
return function_doc.args[argument_name];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class Autocomplete extends obsidian_module.EditorSuggest {
|
|
|
constructor(app, plugin) {
|
|
|
super(app);
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
//private in_command = false;
|
|
|
// https://regex101.com/r/ocmHzR/1
|
|
|
this.tp_keyword_regex = /tp\.(?<module>[a-z]*)?(?<fn_trigger>\.(?<fn>[a-z_]*)?)?$/;
|
|
|
}
|
|
|
onTrigger(cursor, editor, file) {
|
|
|
const range = editor.getRange({ line: cursor.line, ch: 0 }, { line: cursor.line, ch: cursor.ch });
|
|
|
const match = this.tp_keyword_regex.exec(range);
|
|
|
if (!match) {
|
|
|
return null;
|
|
|
}
|
|
|
let query;
|
|
|
const module_name = match.groups["module"] || "";
|
|
|
this.module_name = module_name;
|
|
|
if (match.groups["fn_trigger"]) {
|
|
|
if (module_name == "" || !is_module_name(module_name)) {
|
|
|
return;
|
|
|
}
|
|
|
this.function_trigger = true;
|
|
|
this.function_name = match.groups["fn"] || "";
|
|
|
query = this.function_name;
|
|
|
}
|
|
|
else {
|
|
|
this.function_trigger = false;
|
|
|
query = this.module_name;
|
|
|
}
|
|
|
const trigger_info = {
|
|
|
start: { line: cursor.line, ch: cursor.ch - query.length },
|
|
|
end: { line: cursor.line, ch: cursor.ch },
|
|
|
query: query,
|
|
|
};
|
|
|
this.latest_trigger_info = trigger_info;
|
|
|
return trigger_info;
|
|
|
}
|
|
|
getSuggestions(context) {
|
|
|
let suggestions;
|
|
|
if (this.module_name && this.function_trigger) {
|
|
|
suggestions =
|
|
|
this.plugin.templater.documentation.get_all_functions_documentation(this.module_name);
|
|
|
}
|
|
|
else {
|
|
|
suggestions =
|
|
|
this.plugin.templater.documentation.get_all_modules_documentation();
|
|
|
}
|
|
|
if (!suggestions) {
|
|
|
return [];
|
|
|
}
|
|
|
return suggestions.filter(s => s.name.startsWith(context.query));
|
|
|
}
|
|
|
renderSuggestion(value, el) {
|
|
|
el.createEl("b", { text: value.name });
|
|
|
el.createEl("br");
|
|
|
if (this.function_trigger && is_function_documentation(value)) {
|
|
|
el.createEl("code", { text: value.definition });
|
|
|
}
|
|
|
if (value.description) {
|
|
|
el.createEl("div", { text: value.description });
|
|
|
}
|
|
|
}
|
|
|
selectSuggestion(value, evt) {
|
|
|
const active_view = this.app.workspace.getActiveViewOfType(obsidian_module.MarkdownView);
|
|
|
if (!active_view) {
|
|
|
// TODO: Error msg
|
|
|
return;
|
|
|
}
|
|
|
active_view.editor.replaceRange(value.name, this.latest_trigger_info.start, this.latest_trigger_info.end);
|
|
|
if (this.latest_trigger_info.start.ch == this.latest_trigger_info.end.ch) {
|
|
|
// Dirty hack to prevent the cursor being at the
|
|
|
// beginning of the word after completion,
|
|
|
// Not sure what's the cause of this bug.
|
|
|
const cursor_pos = this.latest_trigger_info.end;
|
|
|
cursor_pos.ch += value.name.length;
|
|
|
active_view.editor.setCursor(cursor_pos);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
|
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
|
|
|
|
/* eslint-disable */
|
|
|
|
|
|
(function (mod) {
|
|
|
mod(window.CodeMirror);
|
|
|
})(function (CodeMirror) {
|
|
|
|
|
|
CodeMirror.defineMode("javascript", function (config, parserConfig) {
|
|
|
var indentUnit = config.indentUnit;
|
|
|
var statementIndent = parserConfig.statementIndent;
|
|
|
var jsonldMode = parserConfig.jsonld;
|
|
|
var jsonMode = parserConfig.json || jsonldMode;
|
|
|
var trackScope = parserConfig.trackScope !== false;
|
|
|
var isTS = parserConfig.typescript;
|
|
|
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
|
|
|
|
|
|
// Tokenizer
|
|
|
|
|
|
var keywords = (function () {
|
|
|
function kw(type) {
|
|
|
return { type: type, style: "keyword" };
|
|
|
}
|
|
|
var A = kw("keyword a"),
|
|
|
B = kw("keyword b"),
|
|
|
C = kw("keyword c"),
|
|
|
D = kw("keyword d");
|
|
|
var operator = kw("operator"),
|
|
|
atom = { type: "atom", style: "atom" };
|
|
|
|
|
|
return {
|
|
|
if: kw("if"),
|
|
|
while: A,
|
|
|
with: A,
|
|
|
else: B,
|
|
|
do: B,
|
|
|
try: B,
|
|
|
finally: B,
|
|
|
return: D,
|
|
|
break: D,
|
|
|
continue: D,
|
|
|
new: kw("new"),
|
|
|
delete: C,
|
|
|
void: C,
|
|
|
throw: C,
|
|
|
debugger: kw("debugger"),
|
|
|
var: kw("var"),
|
|
|
const: kw("var"),
|
|
|
let: kw("var"),
|
|
|
function: kw("function"),
|
|
|
catch: kw("catch"),
|
|
|
for: kw("for"),
|
|
|
switch: kw("switch"),
|
|
|
case: kw("case"),
|
|
|
default: kw("default"),
|
|
|
in: operator,
|
|
|
typeof: operator,
|
|
|
instanceof: operator,
|
|
|
true: atom,
|
|
|
false: atom,
|
|
|
null: atom,
|
|
|
undefined: atom,
|
|
|
NaN: atom,
|
|
|
Infinity: atom,
|
|
|
this: kw("this"),
|
|
|
class: kw("class"),
|
|
|
super: kw("atom"),
|
|
|
yield: C,
|
|
|
export: kw("export"),
|
|
|
import: kw("import"),
|
|
|
extends: C,
|
|
|
await: C,
|
|
|
};
|
|
|
})();
|
|
|
|
|
|
var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
|
|
|
var isJsonldKeyword =
|
|
|
/^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
|
|
|
|
|
|
function readRegexp(stream) {
|
|
|
var escaped = false,
|
|
|
next,
|
|
|
inSet = false;
|
|
|
while ((next = stream.next()) != null) {
|
|
|
if (!escaped) {
|
|
|
if (next == "/" && !inSet) return;
|
|
|
if (next == "[") inSet = true;
|
|
|
else if (inSet && next == "]") inSet = false;
|
|
|
}
|
|
|
escaped = !escaped && next == "\\";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Used as scratch variables to communicate multiple values without
|
|
|
// consing up tons of objects.
|
|
|
var type, content;
|
|
|
function ret(tp, style, cont) {
|
|
|
type = tp;
|
|
|
content = cont;
|
|
|
return style;
|
|
|
}
|
|
|
function tokenBase(stream, state) {
|
|
|
var ch = stream.next();
|
|
|
if (ch == '"' || ch == "'") {
|
|
|
state.tokenize = tokenString(ch);
|
|
|
return state.tokenize(stream, state);
|
|
|
} else if (
|
|
|
ch == "." &&
|
|
|
stream.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/)
|
|
|
) {
|
|
|
return ret("number", "number");
|
|
|
} else if (ch == "." && stream.match("..")) {
|
|
|
return ret("spread", "meta");
|
|
|
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
|
|
return ret(ch);
|
|
|
} else if (ch == "=" && stream.eat(">")) {
|
|
|
return ret("=>", "operator");
|
|
|
} else if (
|
|
|
ch == "0" &&
|
|
|
stream.match(/^(?:x[\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/)
|
|
|
) {
|
|
|
return ret("number", "number");
|
|
|
} else if (/\d/.test(ch)) {
|
|
|
stream.match(
|
|
|
/^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/
|
|
|
);
|
|
|
return ret("number", "number");
|
|
|
} else if (ch == "/") {
|
|
|
if (stream.eat("*")) {
|
|
|
state.tokenize = tokenComment;
|
|
|
return tokenComment(stream, state);
|
|
|
} else if (stream.eat("/")) {
|
|
|
stream.skipToEnd();
|
|
|
return ret("comment", "comment");
|
|
|
} else if (expressionAllowed(stream, state, 1)) {
|
|
|
readRegexp(stream);
|
|
|
stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
|
|
|
return ret("regexp", "string-2");
|
|
|
} else {
|
|
|
stream.eat("=");
|
|
|
return ret("operator", "operator", stream.current());
|
|
|
}
|
|
|
} else if (ch == "`") {
|
|
|
state.tokenize = tokenQuasi;
|
|
|
return tokenQuasi(stream, state);
|
|
|
} else if (ch == "#" && stream.peek() == "!") {
|
|
|
stream.skipToEnd();
|
|
|
return ret("meta", "meta");
|
|
|
} else if (ch == "#" && stream.eatWhile(wordRE)) {
|
|
|
return ret("variable", "property");
|
|
|
} else if (
|
|
|
(ch == "<" && stream.match("!--")) ||
|
|
|
(ch == "-" &&
|
|
|
stream.match("->") &&
|
|
|
!/\S/.test(stream.string.slice(0, stream.start)))
|
|
|
) {
|
|
|
stream.skipToEnd();
|
|
|
return ret("comment", "comment");
|
|
|
} else if (isOperatorChar.test(ch)) {
|
|
|
if (ch != ">" || !state.lexical || state.lexical.type != ">") {
|
|
|
if (stream.eat("=")) {
|
|
|
if (ch == "!" || ch == "=") stream.eat("=");
|
|
|
} else if (/[<>*+\-|&?]/.test(ch)) {
|
|
|
stream.eat(ch);
|
|
|
if (ch == ">") stream.eat(ch);
|
|
|
}
|
|
|
}
|
|
|
if (ch == "?" && stream.eat(".")) return ret(".");
|
|
|
return ret("operator", "operator", stream.current());
|
|
|
} else if (wordRE.test(ch)) {
|
|
|
stream.eatWhile(wordRE);
|
|
|
var word = stream.current();
|
|
|
if (state.lastType != ".") {
|
|
|
if (keywords.propertyIsEnumerable(word)) {
|
|
|
var kw = keywords[word];
|
|
|
return ret(kw.type, kw.style, word);
|
|
|
}
|
|
|
if (
|
|
|
word == "async" &&
|
|
|
stream.match(
|
|
|
/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/,
|
|
|
false
|
|
|
)
|
|
|
)
|
|
|
return ret("async", "keyword", word);
|
|
|
}
|
|
|
return ret("variable", "variable", word);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function tokenString(quote) {
|
|
|
return function (stream, state) {
|
|
|
var escaped = false,
|
|
|
next;
|
|
|
if (
|
|
|
jsonldMode &&
|
|
|
stream.peek() == "@" &&
|
|
|
stream.match(isJsonldKeyword)
|
|
|
) {
|
|
|
state.tokenize = tokenBase;
|
|
|
return ret("jsonld-keyword", "meta");
|
|
|
}
|
|
|
while ((next = stream.next()) != null) {
|
|
|
if (next == quote && !escaped) break;
|
|
|
escaped = !escaped && next == "\\";
|
|
|
}
|
|
|
if (!escaped) state.tokenize = tokenBase;
|
|
|
return ret("string", "string");
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function tokenComment(stream, state) {
|
|
|
var maybeEnd = false,
|
|
|
ch;
|
|
|
while ((ch = stream.next())) {
|
|
|
if (ch == "/" && maybeEnd) {
|
|
|
state.tokenize = tokenBase;
|
|
|
break;
|
|
|
}
|
|
|
maybeEnd = ch == "*";
|
|
|
}
|
|
|
return ret("comment", "comment");
|
|
|
}
|
|
|
|
|
|
function tokenQuasi(stream, state) {
|
|
|
var escaped = false,
|
|
|
next;
|
|
|
while ((next = stream.next()) != null) {
|
|
|
if (
|
|
|
!escaped &&
|
|
|
(next == "`" || (next == "$" && stream.eat("{")))
|
|
|
) {
|
|
|
state.tokenize = tokenBase;
|
|
|
break;
|
|
|
}
|
|
|
escaped = !escaped && next == "\\";
|
|
|
}
|
|
|
return ret("quasi", "string-2", stream.current());
|
|
|
}
|
|
|
|
|
|
var brackets = "([{}])";
|
|
|
// This is a crude lookahead trick to try and notice that we're
|
|
|
// parsing the argument patterns for a fat-arrow function before we
|
|
|
// actually hit the arrow token. It only works if the arrow is on
|
|
|
// the same line as the arguments and there's no strange noise
|
|
|
// (comments) in between. Fallback is to only notice when we hit the
|
|
|
// arrow, and not declare the arguments as locals for the arrow
|
|
|
// body.
|
|
|
function findFatArrow(stream, state) {
|
|
|
if (state.fatArrowAt) state.fatArrowAt = null;
|
|
|
var arrow = stream.string.indexOf("=>", stream.start);
|
|
|
if (arrow < 0) return;
|
|
|
|
|
|
if (isTS) {
|
|
|
// Try to skip TypeScript return type declarations after the arguments
|
|
|
var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(
|
|
|
stream.string.slice(stream.start, arrow)
|
|
|
);
|
|
|
if (m) arrow = m.index;
|
|
|
}
|
|
|
|
|
|
var depth = 0,
|
|
|
sawSomething = false;
|
|
|
for (var pos = arrow - 1; pos >= 0; --pos) {
|
|
|
var ch = stream.string.charAt(pos);
|
|
|
var bracket = brackets.indexOf(ch);
|
|
|
if (bracket >= 0 && bracket < 3) {
|
|
|
if (!depth) {
|
|
|
++pos;
|
|
|
break;
|
|
|
}
|
|
|
if (--depth == 0) {
|
|
|
if (ch == "(") sawSomething = true;
|
|
|
break;
|
|
|
}
|
|
|
} else if (bracket >= 3 && bracket < 6) {
|
|
|
++depth;
|
|
|
} else if (wordRE.test(ch)) {
|
|
|
sawSomething = true;
|
|
|
} else if (/["'\/`]/.test(ch)) {
|
|
|
for (; ; --pos) {
|
|
|
if (pos == 0) return;
|
|
|
var next = stream.string.charAt(pos - 1);
|
|
|
if (
|
|
|
next == ch &&
|
|
|
stream.string.charAt(pos - 2) != "\\"
|
|
|
) {
|
|
|
pos--;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
} else if (sawSomething && !depth) {
|
|
|
++pos;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (sawSomething && !depth) state.fatArrowAt = pos;
|
|
|
}
|
|
|
|
|
|
// Parser
|
|
|
|
|
|
var atomicTypes = {
|
|
|
atom: true,
|
|
|
number: true,
|
|
|
variable: true,
|
|
|
string: true,
|
|
|
regexp: true,
|
|
|
this: true,
|
|
|
import: true,
|
|
|
"jsonld-keyword": true,
|
|
|
};
|
|
|
|
|
|
function JSLexical(indented, column, type, align, prev, info) {
|
|
|
this.indented = indented;
|
|
|
this.column = column;
|
|
|
this.type = type;
|
|
|
this.prev = prev;
|
|
|
this.info = info;
|
|
|
if (align != null) this.align = align;
|
|
|
}
|
|
|
|
|
|
function inScope(state, varname) {
|
|
|
if (!trackScope) return false;
|
|
|
for (var v = state.localVars; v; v = v.next)
|
|
|
if (v.name == varname) return true;
|
|
|
for (var cx = state.context; cx; cx = cx.prev) {
|
|
|
for (var v = cx.vars; v; v = v.next)
|
|
|
if (v.name == varname) return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function parseJS(state, style, type, content, stream) {
|
|
|
var cc = state.cc;
|
|
|
// Communicate our context to the combinators.
|
|
|
// (Less wasteful than consing up a hundred closures on every call.)
|
|
|
cx.state = state;
|
|
|
cx.stream = stream;
|
|
|
(cx.marked = null), (cx.cc = cc);
|
|
|
cx.style = style;
|
|
|
|
|
|
if (!state.lexical.hasOwnProperty("align"))
|
|
|
state.lexical.align = true;
|
|
|
|
|
|
while (true) {
|
|
|
var combinator = cc.length
|
|
|
? cc.pop()
|
|
|
: jsonMode
|
|
|
? expression
|
|
|
: statement;
|
|
|
if (combinator(type, content)) {
|
|
|
while (cc.length && cc[cc.length - 1].lex) cc.pop()();
|
|
|
if (cx.marked) return cx.marked;
|
|
|
if (type == "variable" && inScope(state, content))
|
|
|
return "variable-2";
|
|
|
return style;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Combinator utils
|
|
|
|
|
|
var cx = { state: null, column: null, marked: null, cc: null };
|
|
|
function pass() {
|
|
|
for (var i = arguments.length - 1; i >= 0; i--)
|
|
|
cx.cc.push(arguments[i]);
|
|
|
}
|
|
|
function cont() {
|
|
|
pass.apply(null, arguments);
|
|
|
return true;
|
|
|
}
|
|
|
function inList(name, list) {
|
|
|
for (var v = list; v; v = v.next) if (v.name == name) return true;
|
|
|
return false;
|
|
|
}
|
|
|
function register(varname) {
|
|
|
var state = cx.state;
|
|
|
cx.marked = "def";
|
|
|
if (!trackScope) return;
|
|
|
if (state.context) {
|
|
|
if (
|
|
|
state.lexical.info == "var" &&
|
|
|
state.context &&
|
|
|
state.context.block
|
|
|
) {
|
|
|
// FIXME function decls are also not block scoped
|
|
|
var newContext = registerVarScoped(varname, state.context);
|
|
|
if (newContext != null) {
|
|
|
state.context = newContext;
|
|
|
return;
|
|
|
}
|
|
|
} else if (!inList(varname, state.localVars)) {
|
|
|
state.localVars = new Var(varname, state.localVars);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
// Fall through means this is global
|
|
|
if (parserConfig.globalVars && !inList(varname, state.globalVars))
|
|
|
state.globalVars = new Var(varname, state.globalVars);
|
|
|
}
|
|
|
function registerVarScoped(varname, context) {
|
|
|
if (!context) {
|
|
|
return null;
|
|
|
} else if (context.block) {
|
|
|
var inner = registerVarScoped(varname, context.prev);
|
|
|
if (!inner) return null;
|
|
|
if (inner == context.prev) return context;
|
|
|
return new Context(inner, context.vars, true);
|
|
|
} else if (inList(varname, context.vars)) {
|
|
|
return context;
|
|
|
} else {
|
|
|
return new Context(
|
|
|
context.prev,
|
|
|
new Var(varname, context.vars),
|
|
|
false
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function isModifier(name) {
|
|
|
return (
|
|
|
name == "public" ||
|
|
|
name == "private" ||
|
|
|
name == "protected" ||
|
|
|
name == "abstract" ||
|
|
|
name == "readonly"
|
|
|
);
|
|
|
}
|
|
|
|
|
|
// Combinators
|
|
|
|
|
|
function Context(prev, vars, block) {
|
|
|
this.prev = prev;
|
|
|
this.vars = vars;
|
|
|
this.block = block;
|
|
|
}
|
|
|
function Var(name, next) {
|
|
|
this.name = name;
|
|
|
this.next = next;
|
|
|
}
|
|
|
|
|
|
var defaultVars = new Var("this", new Var("arguments", null));
|
|
|
function pushcontext() {
|
|
|
cx.state.context = new Context(
|
|
|
cx.state.context,
|
|
|
cx.state.localVars,
|
|
|
false
|
|
|
);
|
|
|
cx.state.localVars = defaultVars;
|
|
|
}
|
|
|
function pushblockcontext() {
|
|
|
cx.state.context = new Context(
|
|
|
cx.state.context,
|
|
|
cx.state.localVars,
|
|
|
true
|
|
|
);
|
|
|
cx.state.localVars = null;
|
|
|
}
|
|
|
function popcontext() {
|
|
|
cx.state.localVars = cx.state.context.vars;
|
|
|
cx.state.context = cx.state.context.prev;
|
|
|
}
|
|
|
popcontext.lex = true;
|
|
|
function pushlex(type, info) {
|
|
|
var result = function () {
|
|
|
var state = cx.state,
|
|
|
indent = state.indented;
|
|
|
if (state.lexical.type == "stat")
|
|
|
indent = state.lexical.indented;
|
|
|
else
|
|
|
for (
|
|
|
var outer = state.lexical;
|
|
|
outer && outer.type == ")" && outer.align;
|
|
|
outer = outer.prev
|
|
|
)
|
|
|
indent = outer.indented;
|
|
|
state.lexical = new JSLexical(
|
|
|
indent,
|
|
|
cx.stream.column(),
|
|
|
type,
|
|
|
null,
|
|
|
state.lexical,
|
|
|
info
|
|
|
);
|
|
|
};
|
|
|
result.lex = true;
|
|
|
return result;
|
|
|
}
|
|
|
function poplex() {
|
|
|
var state = cx.state;
|
|
|
if (state.lexical.prev) {
|
|
|
if (state.lexical.type == ")")
|
|
|
state.indented = state.lexical.indented;
|
|
|
state.lexical = state.lexical.prev;
|
|
|
}
|
|
|
}
|
|
|
poplex.lex = true;
|
|
|
|
|
|
function expect(wanted) {
|
|
|
function exp(type) {
|
|
|
if (type == wanted) return cont();
|
|
|
else if (
|
|
|
wanted == ";" ||
|
|
|
type == "}" ||
|
|
|
type == ")" ||
|
|
|
type == "]"
|
|
|
)
|
|
|
return pass();
|
|
|
else return cont(exp);
|
|
|
}
|
|
|
return exp;
|
|
|
}
|
|
|
|
|
|
function statement(type, value) {
|
|
|
if (type == "var")
|
|
|
return cont(
|
|
|
pushlex("vardef", value),
|
|
|
vardef,
|
|
|
expect(";"),
|
|
|
poplex
|
|
|
);
|
|
|
if (type == "keyword a")
|
|
|
return cont(pushlex("form"), parenExpr, statement, poplex);
|
|
|
if (type == "keyword b")
|
|
|
return cont(pushlex("form"), statement, poplex);
|
|
|
if (type == "keyword d")
|
|
|
return cx.stream.match(/^\s*$/, false)
|
|
|
? cont()
|
|
|
: cont(
|
|
|
pushlex("stat"),
|
|
|
maybeexpression,
|
|
|
expect(";"),
|
|
|
poplex
|
|
|
);
|
|
|
if (type == "debugger") return cont(expect(";"));
|
|
|
if (type == "{")
|
|
|
return cont(
|
|
|
pushlex("}"),
|
|
|
pushblockcontext,
|
|
|
block,
|
|
|
poplex,
|
|
|
popcontext
|
|
|
);
|
|
|
if (type == ";") return cont();
|
|
|
if (type == "if") {
|
|
|
if (
|
|
|
cx.state.lexical.info == "else" &&
|
|
|
cx.state.cc[cx.state.cc.length - 1] == poplex
|
|
|
)
|
|
|
cx.state.cc.pop()();
|
|
|
return cont(
|
|
|
pushlex("form"),
|
|
|
parenExpr,
|
|
|
statement,
|
|
|
poplex,
|
|
|
maybeelse
|
|
|
);
|
|
|
}
|
|
|
if (type == "function") return cont(functiondef);
|
|
|
if (type == "for")
|
|
|
return cont(
|
|
|
pushlex("form"),
|
|
|
pushblockcontext,
|
|
|
forspec,
|
|
|
statement,
|
|
|
popcontext,
|
|
|
poplex
|
|
|
);
|
|
|
if (type == "class" || (isTS && value == "interface")) {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(
|
|
|
pushlex("form", type == "class" ? type : value),
|
|
|
className,
|
|
|
poplex
|
|
|
);
|
|
|
}
|
|
|
if (type == "variable") {
|
|
|
if (isTS && value == "declare") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(statement);
|
|
|
} else if (
|
|
|
isTS &&
|
|
|
(value == "module" || value == "enum" || value == "type") &&
|
|
|
cx.stream.match(/^\s*\w/, false)
|
|
|
) {
|
|
|
cx.marked = "keyword";
|
|
|
if (value == "enum") return cont(enumdef);
|
|
|
else if (value == "type")
|
|
|
return cont(
|
|
|
typename,
|
|
|
expect("operator"),
|
|
|
typeexpr,
|
|
|
expect(";")
|
|
|
);
|
|
|
else
|
|
|
return cont(
|
|
|
pushlex("form"),
|
|
|
pattern,
|
|
|
expect("{"),
|
|
|
pushlex("}"),
|
|
|
block,
|
|
|
poplex,
|
|
|
poplex
|
|
|
);
|
|
|
} else if (isTS && value == "namespace") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(pushlex("form"), expression, statement, poplex);
|
|
|
} else if (isTS && value == "abstract") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(statement);
|
|
|
} else {
|
|
|
return cont(pushlex("stat"), maybelabel);
|
|
|
}
|
|
|
}
|
|
|
if (type == "switch")
|
|
|
return cont(
|
|
|
pushlex("form"),
|
|
|
parenExpr,
|
|
|
expect("{"),
|
|
|
pushlex("}", "switch"),
|
|
|
pushblockcontext,
|
|
|
block,
|
|
|
poplex,
|
|
|
poplex,
|
|
|
popcontext
|
|
|
);
|
|
|
if (type == "case") return cont(expression, expect(":"));
|
|
|
if (type == "default") return cont(expect(":"));
|
|
|
if (type == "catch")
|
|
|
return cont(
|
|
|
pushlex("form"),
|
|
|
pushcontext,
|
|
|
maybeCatchBinding,
|
|
|
statement,
|
|
|
poplex,
|
|
|
popcontext
|
|
|
);
|
|
|
if (type == "export")
|
|
|
return cont(pushlex("stat"), afterExport, poplex);
|
|
|
if (type == "import")
|
|
|
return cont(pushlex("stat"), afterImport, poplex);
|
|
|
if (type == "async") return cont(statement);
|
|
|
if (value == "@") return cont(expression, statement);
|
|
|
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
|
|
}
|
|
|
function maybeCatchBinding(type) {
|
|
|
if (type == "(") return cont(funarg, expect(")"));
|
|
|
}
|
|
|
function expression(type, value) {
|
|
|
return expressionInner(type, value, false);
|
|
|
}
|
|
|
function expressionNoComma(type, value) {
|
|
|
return expressionInner(type, value, true);
|
|
|
}
|
|
|
function parenExpr(type) {
|
|
|
if (type != "(") return pass();
|
|
|
return cont(pushlex(")"), maybeexpression, expect(")"), poplex);
|
|
|
}
|
|
|
function expressionInner(type, value, noComma) {
|
|
|
if (cx.state.fatArrowAt == cx.stream.start) {
|
|
|
var body = noComma ? arrowBodyNoComma : arrowBody;
|
|
|
if (type == "(")
|
|
|
return cont(
|
|
|
pushcontext,
|
|
|
pushlex(")"),
|
|
|
commasep(funarg, ")"),
|
|
|
poplex,
|
|
|
expect("=>"),
|
|
|
body,
|
|
|
popcontext
|
|
|
);
|
|
|
else if (type == "variable")
|
|
|
return pass(
|
|
|
pushcontext,
|
|
|
pattern,
|
|
|
expect("=>"),
|
|
|
body,
|
|
|
popcontext
|
|
|
);
|
|
|
}
|
|
|
|
|
|
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
|
|
|
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
|
|
|
if (type == "function") return cont(functiondef, maybeop);
|
|
|
if (type == "class" || (isTS && value == "interface")) {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(pushlex("form"), classExpression, poplex);
|
|
|
}
|
|
|
if (type == "keyword c" || type == "async")
|
|
|
return cont(noComma ? expressionNoComma : expression);
|
|
|
if (type == "(")
|
|
|
return cont(
|
|
|
pushlex(")"),
|
|
|
maybeexpression,
|
|
|
expect(")"),
|
|
|
poplex,
|
|
|
maybeop
|
|
|
);
|
|
|
if (type == "operator" || type == "spread")
|
|
|
return cont(noComma ? expressionNoComma : expression);
|
|
|
if (type == "[")
|
|
|
return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
|
|
|
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
|
|
|
if (type == "quasi") return pass(quasi, maybeop);
|
|
|
if (type == "new") return cont(maybeTarget(noComma));
|
|
|
return cont();
|
|
|
}
|
|
|
function maybeexpression(type) {
|
|
|
if (type.match(/[;\}\)\],]/)) return pass();
|
|
|
return pass(expression);
|
|
|
}
|
|
|
|
|
|
function maybeoperatorComma(type, value) {
|
|
|
if (type == ",") return cont(maybeexpression);
|
|
|
return maybeoperatorNoComma(type, value, false);
|
|
|
}
|
|
|
function maybeoperatorNoComma(type, value, noComma) {
|
|
|
var me =
|
|
|
noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
|
|
|
var expr = noComma == false ? expression : expressionNoComma;
|
|
|
if (type == "=>")
|
|
|
return cont(
|
|
|
pushcontext,
|
|
|
noComma ? arrowBodyNoComma : arrowBody,
|
|
|
popcontext
|
|
|
);
|
|
|
if (type == "operator") {
|
|
|
if (/\+\+|--/.test(value) || (isTS && value == "!"))
|
|
|
return cont(me);
|
|
|
if (
|
|
|
isTS &&
|
|
|
value == "<" &&
|
|
|
cx.stream.match(/^([^<>]|<[^<>]*>)*>\s*\(/, false)
|
|
|
)
|
|
|
return cont(
|
|
|
pushlex(">"),
|
|
|
commasep(typeexpr, ">"),
|
|
|
poplex,
|
|
|
me
|
|
|
);
|
|
|
if (value == "?") return cont(expression, expect(":"), expr);
|
|
|
return cont(expr);
|
|
|
}
|
|
|
if (type == "quasi") {
|
|
|
return pass(quasi, me);
|
|
|
}
|
|
|
if (type == ";") return;
|
|
|
if (type == "(")
|
|
|
return contCommasep(expressionNoComma, ")", "call", me);
|
|
|
if (type == ".") return cont(property, me);
|
|
|
if (type == "[")
|
|
|
return cont(
|
|
|
pushlex("]"),
|
|
|
maybeexpression,
|
|
|
expect("]"),
|
|
|
poplex,
|
|
|
me
|
|
|
);
|
|
|
if (isTS && value == "as") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(typeexpr, me);
|
|
|
}
|
|
|
if (type == "regexp") {
|
|
|
cx.state.lastType = cx.marked = "operator";
|
|
|
cx.stream.backUp(cx.stream.pos - cx.stream.start - 1);
|
|
|
return cont(expr);
|
|
|
}
|
|
|
}
|
|
|
function quasi(type, value) {
|
|
|
if (type != "quasi") return pass();
|
|
|
if (value.slice(value.length - 2) != "${") return cont(quasi);
|
|
|
return cont(maybeexpression, continueQuasi);
|
|
|
}
|
|
|
function continueQuasi(type) {
|
|
|
if (type == "}") {
|
|
|
cx.marked = "string-2";
|
|
|
cx.state.tokenize = tokenQuasi;
|
|
|
return cont(quasi);
|
|
|
}
|
|
|
}
|
|
|
function arrowBody(type) {
|
|
|
findFatArrow(cx.stream, cx.state);
|
|
|
return pass(type == "{" ? statement : expression);
|
|
|
}
|
|
|
function arrowBodyNoComma(type) {
|
|
|
findFatArrow(cx.stream, cx.state);
|
|
|
return pass(type == "{" ? statement : expressionNoComma);
|
|
|
}
|
|
|
function maybeTarget(noComma) {
|
|
|
return function (type) {
|
|
|
if (type == ".") return cont(noComma ? targetNoComma : target);
|
|
|
else if (type == "variable" && isTS)
|
|
|
return cont(
|
|
|
maybeTypeArgs,
|
|
|
noComma ? maybeoperatorNoComma : maybeoperatorComma
|
|
|
);
|
|
|
else return pass(noComma ? expressionNoComma : expression);
|
|
|
};
|
|
|
}
|
|
|
function target(_, value) {
|
|
|
if (value == "target") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(maybeoperatorComma);
|
|
|
}
|
|
|
}
|
|
|
function targetNoComma(_, value) {
|
|
|
if (value == "target") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(maybeoperatorNoComma);
|
|
|
}
|
|
|
}
|
|
|
function maybelabel(type) {
|
|
|
if (type == ":") return cont(poplex, statement);
|
|
|
return pass(maybeoperatorComma, expect(";"), poplex);
|
|
|
}
|
|
|
function property(type) {
|
|
|
if (type == "variable") {
|
|
|
cx.marked = "property";
|
|
|
return cont();
|
|
|
}
|
|
|
}
|
|
|
function objprop(type, value) {
|
|
|
if (type == "async") {
|
|
|
cx.marked = "property";
|
|
|
return cont(objprop);
|
|
|
} else if (type == "variable" || cx.style == "keyword") {
|
|
|
cx.marked = "property";
|
|
|
if (value == "get" || value == "set") return cont(getterSetter);
|
|
|
var m; // Work around fat-arrow-detection complication for detecting typescript typed arrow params
|
|
|
if (
|
|
|
isTS &&
|
|
|
cx.state.fatArrowAt == cx.stream.start &&
|
|
|
(m = cx.stream.match(/^\s*:\s*/, false))
|
|
|
)
|
|
|
cx.state.fatArrowAt = cx.stream.pos + m[0].length;
|
|
|
return cont(afterprop);
|
|
|
} else if (type == "number" || type == "string") {
|
|
|
cx.marked = jsonldMode ? "property" : cx.style + " property";
|
|
|
return cont(afterprop);
|
|
|
} else if (type == "jsonld-keyword") {
|
|
|
return cont(afterprop);
|
|
|
} else if (isTS && isModifier(value)) {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(objprop);
|
|
|
} else if (type == "[") {
|
|
|
return cont(expression, maybetype, expect("]"), afterprop);
|
|
|
} else if (type == "spread") {
|
|
|
return cont(expressionNoComma, afterprop);
|
|
|
} else if (value == "*") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(objprop);
|
|
|
} else if (type == ":") {
|
|
|
return pass(afterprop);
|
|
|
}
|
|
|
}
|
|
|
function getterSetter(type) {
|
|
|
if (type != "variable") return pass(afterprop);
|
|
|
cx.marked = "property";
|
|
|
return cont(functiondef);
|
|
|
}
|
|
|
function afterprop(type) {
|
|
|
if (type == ":") return cont(expressionNoComma);
|
|
|
if (type == "(") return pass(functiondef);
|
|
|
}
|
|
|
function commasep(what, end, sep) {
|
|
|
function proceed(type, value) {
|
|
|
if (sep ? sep.indexOf(type) > -1 : type == ",") {
|
|
|
var lex = cx.state.lexical;
|
|
|
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
|
|
|
return cont(function (type, value) {
|
|
|
if (type == end || value == end) return pass();
|
|
|
return pass(what);
|
|
|
}, proceed);
|
|
|
}
|
|
|
if (type == end || value == end) return cont();
|
|
|
if (sep && sep.indexOf(";") > -1) return pass(what);
|
|
|
return cont(expect(end));
|
|
|
}
|
|
|
return function (type, value) {
|
|
|
if (type == end || value == end) return cont();
|
|
|
return pass(what, proceed);
|
|
|
};
|
|
|
}
|
|
|
function contCommasep(what, end, info) {
|
|
|
for (var i = 3; i < arguments.length; i++) cx.cc.push(arguments[i]);
|
|
|
return cont(pushlex(end, info), commasep(what, end), poplex);
|
|
|
}
|
|
|
function block(type) {
|
|
|
if (type == "}") return cont();
|
|
|
return pass(statement, block);
|
|
|
}
|
|
|
function maybetype(type, value) {
|
|
|
if (isTS) {
|
|
|
if (type == ":") return cont(typeexpr);
|
|
|
if (value == "?") return cont(maybetype);
|
|
|
}
|
|
|
}
|
|
|
function maybetypeOrIn(type, value) {
|
|
|
if (isTS && (type == ":" || value == "in")) return cont(typeexpr);
|
|
|
}
|
|
|
function mayberettype(type) {
|
|
|
if (isTS && type == ":") {
|
|
|
if (cx.stream.match(/^\s*\w+\s+is\b/, false))
|
|
|
return cont(expression, isKW, typeexpr);
|
|
|
else return cont(typeexpr);
|
|
|
}
|
|
|
}
|
|
|
function isKW(_, value) {
|
|
|
if (value == "is") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont();
|
|
|
}
|
|
|
}
|
|
|
function typeexpr(type, value) {
|
|
|
if (
|
|
|
value == "keyof" ||
|
|
|
value == "typeof" ||
|
|
|
value == "infer" ||
|
|
|
value == "readonly"
|
|
|
) {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(value == "typeof" ? expressionNoComma : typeexpr);
|
|
|
}
|
|
|
if (type == "variable" || value == "void") {
|
|
|
cx.marked = "type";
|
|
|
return cont(afterType);
|
|
|
}
|
|
|
if (value == "|" || value == "&") return cont(typeexpr);
|
|
|
if (type == "string" || type == "number" || type == "atom")
|
|
|
return cont(afterType);
|
|
|
if (type == "[")
|
|
|
return cont(
|
|
|
pushlex("]"),
|
|
|
commasep(typeexpr, "]", ","),
|
|
|
poplex,
|
|
|
afterType
|
|
|
);
|
|
|
if (type == "{")
|
|
|
return cont(pushlex("}"), typeprops, poplex, afterType);
|
|
|
if (type == "(")
|
|
|
return cont(commasep(typearg, ")"), maybeReturnType, afterType);
|
|
|
if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr);
|
|
|
if (type == "quasi") {
|
|
|
return pass(quasiType, afterType);
|
|
|
}
|
|
|
}
|
|
|
function maybeReturnType(type) {
|
|
|
if (type == "=>") return cont(typeexpr);
|
|
|
}
|
|
|
function typeprops(type) {
|
|
|
if (type.match(/[\}\)\]]/)) return cont();
|
|
|
if (type == "," || type == ";") return cont(typeprops);
|
|
|
return pass(typeprop, typeprops);
|
|
|
}
|
|
|
function typeprop(type, value) {
|
|
|
if (type == "variable" || cx.style == "keyword") {
|
|
|
cx.marked = "property";
|
|
|
return cont(typeprop);
|
|
|
} else if (value == "?" || type == "number" || type == "string") {
|
|
|
return cont(typeprop);
|
|
|
} else if (type == ":") {
|
|
|
return cont(typeexpr);
|
|
|
} else if (type == "[") {
|
|
|
return cont(
|
|
|
expect("variable"),
|
|
|
maybetypeOrIn,
|
|
|
expect("]"),
|
|
|
typeprop
|
|
|
);
|
|
|
} else if (type == "(") {
|
|
|
return pass(functiondecl, typeprop);
|
|
|
} else if (!type.match(/[;\}\)\],]/)) {
|
|
|
return cont();
|
|
|
}
|
|
|
}
|
|
|
function quasiType(type, value) {
|
|
|
if (type != "quasi") return pass();
|
|
|
if (value.slice(value.length - 2) != "${") return cont(quasiType);
|
|
|
return cont(typeexpr, continueQuasiType);
|
|
|
}
|
|
|
function continueQuasiType(type) {
|
|
|
if (type == "}") {
|
|
|
cx.marked = "string-2";
|
|
|
cx.state.tokenize = tokenQuasi;
|
|
|
return cont(quasiType);
|
|
|
}
|
|
|
}
|
|
|
function typearg(type, value) {
|
|
|
if (
|
|
|
(type == "variable" && cx.stream.match(/^\s*[?:]/, false)) ||
|
|
|
value == "?"
|
|
|
)
|
|
|
return cont(typearg);
|
|
|
if (type == ":") return cont(typeexpr);
|
|
|
if (type == "spread") return cont(typearg);
|
|
|
return pass(typeexpr);
|
|
|
}
|
|
|
function afterType(type, value) {
|
|
|
if (value == "<")
|
|
|
return cont(
|
|
|
pushlex(">"),
|
|
|
commasep(typeexpr, ">"),
|
|
|
poplex,
|
|
|
afterType
|
|
|
);
|
|
|
if (value == "|" || type == "." || value == "&")
|
|
|
return cont(typeexpr);
|
|
|
if (type == "[") return cont(typeexpr, expect("]"), afterType);
|
|
|
if (value == "extends" || value == "implements") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(typeexpr);
|
|
|
}
|
|
|
if (value == "?") return cont(typeexpr, expect(":"), typeexpr);
|
|
|
}
|
|
|
function maybeTypeArgs(_, value) {
|
|
|
if (value == "<")
|
|
|
return cont(
|
|
|
pushlex(">"),
|
|
|
commasep(typeexpr, ">"),
|
|
|
poplex,
|
|
|
afterType
|
|
|
);
|
|
|
}
|
|
|
function typeparam() {
|
|
|
return pass(typeexpr, maybeTypeDefault);
|
|
|
}
|
|
|
function maybeTypeDefault(_, value) {
|
|
|
if (value == "=") return cont(typeexpr);
|
|
|
}
|
|
|
function vardef(_, value) {
|
|
|
if (value == "enum") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(enumdef);
|
|
|
}
|
|
|
return pass(pattern, maybetype, maybeAssign, vardefCont);
|
|
|
}
|
|
|
function pattern(type, value) {
|
|
|
if (isTS && isModifier(value)) {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(pattern);
|
|
|
}
|
|
|
if (type == "variable") {
|
|
|
register(value);
|
|
|
return cont();
|
|
|
}
|
|
|
if (type == "spread") return cont(pattern);
|
|
|
if (type == "[") return contCommasep(eltpattern, "]");
|
|
|
if (type == "{") return contCommasep(proppattern, "}");
|
|
|
}
|
|
|
function proppattern(type, value) {
|
|
|
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
|
|
|
register(value);
|
|
|
return cont(maybeAssign);
|
|
|
}
|
|
|
if (type == "variable") cx.marked = "property";
|
|
|
if (type == "spread") return cont(pattern);
|
|
|
if (type == "}") return pass();
|
|
|
if (type == "[")
|
|
|
return cont(expression, expect("]"), expect(":"), proppattern);
|
|
|
return cont(expect(":"), pattern, maybeAssign);
|
|
|
}
|
|
|
function eltpattern() {
|
|
|
return pass(pattern, maybeAssign);
|
|
|
}
|
|
|
function maybeAssign(_type, value) {
|
|
|
if (value == "=") return cont(expressionNoComma);
|
|
|
}
|
|
|
function vardefCont(type) {
|
|
|
if (type == ",") return cont(vardef);
|
|
|
}
|
|
|
function maybeelse(type, value) {
|
|
|
if (type == "keyword b" && value == "else")
|
|
|
return cont(pushlex("form", "else"), statement, poplex);
|
|
|
}
|
|
|
function forspec(type, value) {
|
|
|
if (value == "await") return cont(forspec);
|
|
|
if (type == "(") return cont(pushlex(")"), forspec1, poplex);
|
|
|
}
|
|
|
function forspec1(type) {
|
|
|
if (type == "var") return cont(vardef, forspec2);
|
|
|
if (type == "variable") return cont(forspec2);
|
|
|
return pass(forspec2);
|
|
|
}
|
|
|
function forspec2(type, value) {
|
|
|
if (type == ")") return cont();
|
|
|
if (type == ";") return cont(forspec2);
|
|
|
if (value == "in" || value == "of") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(expression, forspec2);
|
|
|
}
|
|
|
return pass(expression, forspec2);
|
|
|
}
|
|
|
function functiondef(type, value) {
|
|
|
if (value == "*") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(functiondef);
|
|
|
}
|
|
|
if (type == "variable") {
|
|
|
register(value);
|
|
|
return cont(functiondef);
|
|
|
}
|
|
|
if (type == "(")
|
|
|
return cont(
|
|
|
pushcontext,
|
|
|
pushlex(")"),
|
|
|
commasep(funarg, ")"),
|
|
|
poplex,
|
|
|
mayberettype,
|
|
|
statement,
|
|
|
popcontext
|
|
|
);
|
|
|
if (isTS && value == "<")
|
|
|
return cont(
|
|
|
pushlex(">"),
|
|
|
commasep(typeparam, ">"),
|
|
|
poplex,
|
|
|
functiondef
|
|
|
);
|
|
|
}
|
|
|
function functiondecl(type, value) {
|
|
|
if (value == "*") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(functiondecl);
|
|
|
}
|
|
|
if (type == "variable") {
|
|
|
register(value);
|
|
|
return cont(functiondecl);
|
|
|
}
|
|
|
if (type == "(")
|
|
|
return cont(
|
|
|
pushcontext,
|
|
|
pushlex(")"),
|
|
|
commasep(funarg, ")"),
|
|
|
poplex,
|
|
|
mayberettype,
|
|
|
popcontext
|
|
|
);
|
|
|
if (isTS && value == "<")
|
|
|
return cont(
|
|
|
pushlex(">"),
|
|
|
commasep(typeparam, ">"),
|
|
|
poplex,
|
|
|
functiondecl
|
|
|
);
|
|
|
}
|
|
|
function typename(type, value) {
|
|
|
if (type == "keyword" || type == "variable") {
|
|
|
cx.marked = "type";
|
|
|
return cont(typename);
|
|
|
} else if (value == "<") {
|
|
|
return cont(pushlex(">"), commasep(typeparam, ">"), poplex);
|
|
|
}
|
|
|
}
|
|
|
function funarg(type, value) {
|
|
|
if (value == "@") cont(expression, funarg);
|
|
|
if (type == "spread") return cont(funarg);
|
|
|
if (isTS && isModifier(value)) {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(funarg);
|
|
|
}
|
|
|
if (isTS && type == "this") return cont(maybetype, maybeAssign);
|
|
|
return pass(pattern, maybetype, maybeAssign);
|
|
|
}
|
|
|
function classExpression(type, value) {
|
|
|
// Class expressions may have an optional name.
|
|
|
if (type == "variable") return className(type, value);
|
|
|
return classNameAfter(type, value);
|
|
|
}
|
|
|
function className(type, value) {
|
|
|
if (type == "variable") {
|
|
|
register(value);
|
|
|
return cont(classNameAfter);
|
|
|
}
|
|
|
}
|
|
|
function classNameAfter(type, value) {
|
|
|
if (value == "<")
|
|
|
return cont(
|
|
|
pushlex(">"),
|
|
|
commasep(typeparam, ">"),
|
|
|
poplex,
|
|
|
classNameAfter
|
|
|
);
|
|
|
if (
|
|
|
value == "extends" ||
|
|
|
value == "implements" ||
|
|
|
(isTS && type == ",")
|
|
|
) {
|
|
|
if (value == "implements") cx.marked = "keyword";
|
|
|
return cont(isTS ? typeexpr : expression, classNameAfter);
|
|
|
}
|
|
|
if (type == "{") return cont(pushlex("}"), classBody, poplex);
|
|
|
}
|
|
|
function classBody(type, value) {
|
|
|
if (
|
|
|
type == "async" ||
|
|
|
(type == "variable" &&
|
|
|
(value == "static" ||
|
|
|
value == "get" ||
|
|
|
value == "set" ||
|
|
|
(isTS && isModifier(value))) &&
|
|
|
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))
|
|
|
) {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(classBody);
|
|
|
}
|
|
|
if (type == "variable" || cx.style == "keyword") {
|
|
|
cx.marked = "property";
|
|
|
return cont(classfield, classBody);
|
|
|
}
|
|
|
if (type == "number" || type == "string")
|
|
|
return cont(classfield, classBody);
|
|
|
if (type == "[")
|
|
|
return cont(
|
|
|
expression,
|
|
|
maybetype,
|
|
|
expect("]"),
|
|
|
classfield,
|
|
|
classBody
|
|
|
);
|
|
|
if (value == "*") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(classBody);
|
|
|
}
|
|
|
if (isTS && type == "(") return pass(functiondecl, classBody);
|
|
|
if (type == ";" || type == ",") return cont(classBody);
|
|
|
if (type == "}") return cont();
|
|
|
if (value == "@") return cont(expression, classBody);
|
|
|
}
|
|
|
function classfield(type, value) {
|
|
|
if (value == "!") return cont(classfield);
|
|
|
if (value == "?") return cont(classfield);
|
|
|
if (type == ":") return cont(typeexpr, maybeAssign);
|
|
|
if (value == "=") return cont(expressionNoComma);
|
|
|
var context = cx.state.lexical.prev,
|
|
|
isInterface = context && context.info == "interface";
|
|
|
return pass(isInterface ? functiondecl : functiondef);
|
|
|
}
|
|
|
function afterExport(type, value) {
|
|
|
if (value == "*") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(maybeFrom, expect(";"));
|
|
|
}
|
|
|
if (value == "default") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(expression, expect(";"));
|
|
|
}
|
|
|
if (type == "{")
|
|
|
return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
|
|
|
return pass(statement);
|
|
|
}
|
|
|
function exportField(type, value) {
|
|
|
if (value == "as") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(expect("variable"));
|
|
|
}
|
|
|
if (type == "variable") return pass(expressionNoComma, exportField);
|
|
|
}
|
|
|
function afterImport(type) {
|
|
|
if (type == "string") return cont();
|
|
|
if (type == "(") return pass(expression);
|
|
|
if (type == ".") return pass(maybeoperatorComma);
|
|
|
return pass(importSpec, maybeMoreImports, maybeFrom);
|
|
|
}
|
|
|
function importSpec(type, value) {
|
|
|
if (type == "{") return contCommasep(importSpec, "}");
|
|
|
if (type == "variable") register(value);
|
|
|
if (value == "*") cx.marked = "keyword";
|
|
|
return cont(maybeAs);
|
|
|
}
|
|
|
function maybeMoreImports(type) {
|
|
|
if (type == ",") return cont(importSpec, maybeMoreImports);
|
|
|
}
|
|
|
function maybeAs(_type, value) {
|
|
|
if (value == "as") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(importSpec);
|
|
|
}
|
|
|
}
|
|
|
function maybeFrom(_type, value) {
|
|
|
if (value == "from") {
|
|
|
cx.marked = "keyword";
|
|
|
return cont(expression);
|
|
|
}
|
|
|
}
|
|
|
function arrayLiteral(type) {
|
|
|
if (type == "]") return cont();
|
|
|
return pass(commasep(expressionNoComma, "]"));
|
|
|
}
|
|
|
function enumdef() {
|
|
|
return pass(
|
|
|
pushlex("form"),
|
|
|
pattern,
|
|
|
expect("{"),
|
|
|
pushlex("}"),
|
|
|
commasep(enummember, "}"),
|
|
|
poplex,
|
|
|
poplex
|
|
|
);
|
|
|
}
|
|
|
function enummember() {
|
|
|
return pass(pattern, maybeAssign);
|
|
|
}
|
|
|
|
|
|
function isContinuedStatement(state, textAfter) {
|
|
|
return (
|
|
|
state.lastType == "operator" ||
|
|
|
state.lastType == "," ||
|
|
|
isOperatorChar.test(textAfter.charAt(0)) ||
|
|
|
/[,.]/.test(textAfter.charAt(0))
|
|
|
);
|
|
|
}
|
|
|
|
|
|
function expressionAllowed(stream, state, backUp) {
|
|
|
return (
|
|
|
(state.tokenize == tokenBase &&
|
|
|
/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(
|
|
|
state.lastType
|
|
|
)) ||
|
|
|
(state.lastType == "quasi" &&
|
|
|
/\{\s*$/.test(
|
|
|
stream.string.slice(0, stream.pos - (backUp || 0))
|
|
|
))
|
|
|
);
|
|
|
}
|
|
|
|
|
|
// Interface
|
|
|
|
|
|
return {
|
|
|
startState: function (basecolumn) {
|
|
|
var state = {
|
|
|
tokenize: tokenBase,
|
|
|
lastType: "sof",
|
|
|
cc: [],
|
|
|
lexical: new JSLexical(
|
|
|
(basecolumn || 0) - indentUnit,
|
|
|
0,
|
|
|
"block",
|
|
|
false
|
|
|
),
|
|
|
localVars: parserConfig.localVars,
|
|
|
context:
|
|
|
parserConfig.localVars &&
|
|
|
new Context(null, null, false),
|
|
|
indented: basecolumn || 0,
|
|
|
};
|
|
|
if (
|
|
|
parserConfig.globalVars &&
|
|
|
typeof parserConfig.globalVars == "object"
|
|
|
)
|
|
|
state.globalVars = parserConfig.globalVars;
|
|
|
return state;
|
|
|
},
|
|
|
|
|
|
token: function (stream, state) {
|
|
|
if (stream.sol()) {
|
|
|
if (!state.lexical.hasOwnProperty("align"))
|
|
|
state.lexical.align = false;
|
|
|
state.indented = stream.indentation();
|
|
|
findFatArrow(stream, state);
|
|
|
}
|
|
|
if (state.tokenize != tokenComment && stream.eatSpace())
|
|
|
return null;
|
|
|
var style = state.tokenize(stream, state);
|
|
|
if (type == "comment") return style;
|
|
|
state.lastType =
|
|
|
type == "operator" && (content == "++" || content == "--")
|
|
|
? "incdec"
|
|
|
: type;
|
|
|
return parseJS(state, style, type, content, stream);
|
|
|
},
|
|
|
|
|
|
indent: function (state, textAfter) {
|
|
|
if (
|
|
|
state.tokenize == tokenComment ||
|
|
|
state.tokenize == tokenQuasi
|
|
|
)
|
|
|
return CodeMirror.Pass;
|
|
|
if (state.tokenize != tokenBase) return 0;
|
|
|
var firstChar = textAfter && textAfter.charAt(0),
|
|
|
lexical = state.lexical,
|
|
|
top;
|
|
|
// Kludge to prevent 'maybelse' from blocking lexical scope pops
|
|
|
if (!/^\s*else\b/.test(textAfter))
|
|
|
for (var i = state.cc.length - 1; i >= 0; --i) {
|
|
|
var c = state.cc[i];
|
|
|
if (c == poplex) lexical = lexical.prev;
|
|
|
else if (c != maybeelse && c != popcontext) break;
|
|
|
}
|
|
|
while (
|
|
|
(lexical.type == "stat" || lexical.type == "form") &&
|
|
|
(firstChar == "}" ||
|
|
|
((top = state.cc[state.cc.length - 1]) &&
|
|
|
(top == maybeoperatorComma ||
|
|
|
top == maybeoperatorNoComma) &&
|
|
|
!/^[,\.=+\-*:?[\(]/.test(textAfter)))
|
|
|
)
|
|
|
lexical = lexical.prev;
|
|
|
if (
|
|
|
statementIndent &&
|
|
|
lexical.type == ")" &&
|
|
|
lexical.prev.type == "stat"
|
|
|
)
|
|
|
lexical = lexical.prev;
|
|
|
var type = lexical.type,
|
|
|
closing = firstChar == type;
|
|
|
|
|
|
if (type == "vardef")
|
|
|
return (
|
|
|
lexical.indented +
|
|
|
(state.lastType == "operator" || state.lastType == ","
|
|
|
? lexical.info.length + 1
|
|
|
: 0)
|
|
|
);
|
|
|
else if (type == "form" && firstChar == "{")
|
|
|
return lexical.indented;
|
|
|
else if (type == "form") return lexical.indented + indentUnit;
|
|
|
else if (type == "stat")
|
|
|
return (
|
|
|
lexical.indented +
|
|
|
(isContinuedStatement(state, textAfter)
|
|
|
? statementIndent || indentUnit
|
|
|
: 0)
|
|
|
);
|
|
|
else if (
|
|
|
lexical.info == "switch" &&
|
|
|
!closing &&
|
|
|
parserConfig.doubleIndentSwitch != false
|
|
|
)
|
|
|
return (
|
|
|
lexical.indented +
|
|
|
(/^(?:case|default)\b/.test(textAfter)
|
|
|
? indentUnit
|
|
|
: 2 * indentUnit)
|
|
|
);
|
|
|
else if (lexical.align)
|
|
|
return lexical.column + (closing ? 0 : 1);
|
|
|
else return lexical.indented + (closing ? 0 : indentUnit);
|
|
|
},
|
|
|
|
|
|
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
|
|
|
blockCommentStart: jsonMode ? null : "/*",
|
|
|
blockCommentEnd: jsonMode ? null : "*/",
|
|
|
blockCommentContinue: jsonMode ? null : " * ",
|
|
|
lineComment: jsonMode ? null : "//",
|
|
|
fold: "brace",
|
|
|
closeBrackets: "()[]{}''\"\"``",
|
|
|
|
|
|
helperType: jsonMode ? "json" : "javascript",
|
|
|
jsonldMode: jsonldMode,
|
|
|
jsonMode: jsonMode,
|
|
|
|
|
|
expressionAllowed: expressionAllowed,
|
|
|
|
|
|
skipExpression: function (state) {
|
|
|
parseJS(
|
|
|
state,
|
|
|
"atom",
|
|
|
"atom",
|
|
|
"true",
|
|
|
new CodeMirror.StringStream("", 2, null)
|
|
|
);
|
|
|
},
|
|
|
};
|
|
|
});
|
|
|
|
|
|
CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
|
|
|
|
|
|
CodeMirror.defineMIME("text/javascript", "javascript");
|
|
|
CodeMirror.defineMIME("text/ecmascript", "javascript");
|
|
|
CodeMirror.defineMIME("application/javascript", "javascript");
|
|
|
CodeMirror.defineMIME("application/x-javascript", "javascript");
|
|
|
CodeMirror.defineMIME("application/ecmascript", "javascript");
|
|
|
CodeMirror.defineMIME("application/json", {
|
|
|
name: "javascript",
|
|
|
json: true,
|
|
|
});
|
|
|
CodeMirror.defineMIME("application/x-json", {
|
|
|
name: "javascript",
|
|
|
json: true,
|
|
|
});
|
|
|
CodeMirror.defineMIME("application/manifest+json", {
|
|
|
name: "javascript",
|
|
|
json: true,
|
|
|
});
|
|
|
CodeMirror.defineMIME("application/ld+json", {
|
|
|
name: "javascript",
|
|
|
jsonld: true,
|
|
|
});
|
|
|
CodeMirror.defineMIME("text/typescript", {
|
|
|
name: "javascript",
|
|
|
typescript: true,
|
|
|
});
|
|
|
CodeMirror.defineMIME("application/typescript", {
|
|
|
name: "javascript",
|
|
|
typescript: true,
|
|
|
});
|
|
|
});
|
|
|
|
|
|
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
|
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
|
|
|
|
// Utility function that allows modes to be combined. The mode given
|
|
|
// as the base argument takes care of most of the normal mode
|
|
|
// functionality, but a second (typically simple) mode is used, which
|
|
|
// can override the style of text. Both modes get to parse all of the
|
|
|
// text, but when both assign a non-null style to a piece of code, the
|
|
|
// overlay wins, unless the combine argument was true and not overridden,
|
|
|
// or state.overlay.combineTokens was true, in which case the styles are
|
|
|
// combined.
|
|
|
|
|
|
(function (mod) {
|
|
|
mod(window.CodeMirror);
|
|
|
})(function (CodeMirror) {
|
|
|
|
|
|
CodeMirror.customOverlayMode = function (base, overlay, combine) {
|
|
|
return {
|
|
|
startState: function () {
|
|
|
return {
|
|
|
base: CodeMirror.startState(base),
|
|
|
overlay: CodeMirror.startState(overlay),
|
|
|
basePos: 0,
|
|
|
baseCur: null,
|
|
|
overlayPos: 0,
|
|
|
overlayCur: null,
|
|
|
streamSeen: null,
|
|
|
};
|
|
|
},
|
|
|
copyState: function (state) {
|
|
|
return {
|
|
|
base: CodeMirror.copyState(base, state.base),
|
|
|
overlay: CodeMirror.copyState(overlay, state.overlay),
|
|
|
basePos: state.basePos,
|
|
|
baseCur: null,
|
|
|
overlayPos: state.overlayPos,
|
|
|
overlayCur: null,
|
|
|
};
|
|
|
},
|
|
|
|
|
|
token: function (stream, state) {
|
|
|
if (
|
|
|
stream != state.streamSeen ||
|
|
|
Math.min(state.basePos, state.overlayPos) < stream.start
|
|
|
) {
|
|
|
state.streamSeen = stream;
|
|
|
state.basePos = state.overlayPos = stream.start;
|
|
|
}
|
|
|
|
|
|
if (stream.start == state.basePos) {
|
|
|
state.baseCur = base.token(stream, state.base);
|
|
|
state.basePos = stream.pos;
|
|
|
}
|
|
|
if (stream.start == state.overlayPos) {
|
|
|
stream.pos = stream.start;
|
|
|
state.overlayCur = overlay.token(stream, state.overlay);
|
|
|
state.overlayPos = stream.pos;
|
|
|
}
|
|
|
stream.pos = Math.min(state.basePos, state.overlayPos);
|
|
|
|
|
|
// Edge case for codeblocks in templater mode
|
|
|
if (
|
|
|
state.baseCur &&
|
|
|
state.overlayCur &&
|
|
|
state.baseCur.contains("line-HyperMD-codeblock")
|
|
|
) {
|
|
|
state.overlayCur = state.overlayCur.replace(
|
|
|
"line-templater-inline",
|
|
|
""
|
|
|
);
|
|
|
state.overlayCur += ` line-background-HyperMD-codeblock-bg`;
|
|
|
}
|
|
|
|
|
|
// state.overlay.combineTokens always takes precedence over combine,
|
|
|
// unless set to null
|
|
|
if (state.overlayCur == null) return state.baseCur;
|
|
|
else if (
|
|
|
(state.baseCur != null && state.overlay.combineTokens) ||
|
|
|
(combine && state.overlay.combineTokens == null)
|
|
|
)
|
|
|
return state.baseCur + " " + state.overlayCur;
|
|
|
else return state.overlayCur;
|
|
|
},
|
|
|
|
|
|
indent:
|
|
|
base.indent &&
|
|
|
function (state, textAfter, line) {
|
|
|
return base.indent(state.base, textAfter, line);
|
|
|
},
|
|
|
electricChars: base.electricChars,
|
|
|
|
|
|
innerMode: function (state) {
|
|
|
return { state: state.base, mode: base };
|
|
|
},
|
|
|
|
|
|
blankLine: function (state) {
|
|
|
var baseToken, overlayToken;
|
|
|
if (base.blankLine) baseToken = base.blankLine(state.base);
|
|
|
if (overlay.blankLine)
|
|
|
overlayToken = overlay.blankLine(state.overlay);
|
|
|
|
|
|
return overlayToken == null
|
|
|
? baseToken
|
|
|
: combine && baseToken != null
|
|
|
? baseToken + " " + overlayToken
|
|
|
: overlayToken;
|
|
|
},
|
|
|
};
|
|
|
};
|
|
|
});
|
|
|
|
|
|
//import "editor/mode/show-hint";
|
|
|
const TP_CMD_TOKEN_CLASS = "templater-command";
|
|
|
const TP_INLINE_CLASS = "templater-inline";
|
|
|
const TP_OPENING_TAG_TOKEN_CLASS = "templater-opening-tag";
|
|
|
const TP_CLOSING_TAG_TOKEN_CLASS = "templater-closing-tag";
|
|
|
const TP_INTERPOLATION_TAG_TOKEN_CLASS = "templater-interpolation-tag";
|
|
|
const TP_RAW_TAG_TOKEN_CLASS = "templater-raw-tag";
|
|
|
const TP_EXEC_TAG_TOKEN_CLASS = "templater-execution-tag";
|
|
|
class Editor {
|
|
|
constructor(app, plugin) {
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
this.cursor_jumper = new CursorJumper(this.app);
|
|
|
}
|
|
|
setup() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
yield this.registerCodeMirrorMode();
|
|
|
//await this.registerHinter();
|
|
|
this.plugin.registerEditorSuggest(new Autocomplete(this.app, this.plugin));
|
|
|
});
|
|
|
}
|
|
|
jump_to_next_cursor_location() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.cursor_jumper.jump_to_next_cursor_location();
|
|
|
});
|
|
|
}
|
|
|
registerCodeMirrorMode() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
// cm-editor-syntax-highlight-obsidian plugin
|
|
|
// https://codemirror.net/doc/manual.html#modeapi
|
|
|
// https://codemirror.net/mode/diff/diff.js
|
|
|
// https://codemirror.net/demo/mustache.html
|
|
|
// https://marijnhaverbeke.nl/blog/codemirror-mode-system.html
|
|
|
if (!this.plugin.settings.syntax_highlighting) {
|
|
|
return;
|
|
|
}
|
|
|
// TODO: Add mobile support
|
|
|
if (obsidian_module.Platform.isMobileApp) {
|
|
|
return;
|
|
|
}
|
|
|
const js_mode = window.CodeMirror.getMode({}, "javascript");
|
|
|
if (js_mode.name === "null") {
|
|
|
log_error(new TemplaterError("Javascript syntax mode couldn't be found, can't enable syntax highlighting."));
|
|
|
return;
|
|
|
}
|
|
|
// Custom overlay mode used to handle edge cases
|
|
|
// @ts-ignore
|
|
|
const overlay_mode = window.CodeMirror.customOverlayMode;
|
|
|
if (overlay_mode == null) {
|
|
|
log_error(new TemplaterError("Couldn't find customOverlayMode, can't enable syntax highlighting."));
|
|
|
return;
|
|
|
}
|
|
|
window.CodeMirror.defineMode("templater", function (config) {
|
|
|
const templaterOverlay = {
|
|
|
startState: function () {
|
|
|
const js_state = window.CodeMirror.startState(js_mode);
|
|
|
return Object.assign(Object.assign({}, js_state), { inCommand: false, tag_class: "", freeLine: false });
|
|
|
},
|
|
|
copyState: function (state) {
|
|
|
const js_state = window.CodeMirror.startState(js_mode);
|
|
|
const new_state = Object.assign(Object.assign({}, js_state), { inCommand: state.inCommand, tag_class: state.tag_class, freeLine: state.freeLine });
|
|
|
return new_state;
|
|
|
},
|
|
|
blankLine: function (state) {
|
|
|
if (state.inCommand) {
|
|
|
return `line-background-templater-command-bg`;
|
|
|
}
|
|
|
return null;
|
|
|
},
|
|
|
token: function (stream, state) {
|
|
|
if (stream.sol() && state.inCommand) {
|
|
|
state.freeLine = true;
|
|
|
}
|
|
|
if (state.inCommand) {
|
|
|
let keywords = "";
|
|
|
if (stream.match(/[-_]{0,1}%>/, true)) {
|
|
|
state.inCommand = false;
|
|
|
state.freeLine = false;
|
|
|
const tag_class = state.tag_class;
|
|
|
state.tag_class = "";
|
|
|
return `line-${TP_INLINE_CLASS} ${TP_CMD_TOKEN_CLASS} ${TP_CLOSING_TAG_TOKEN_CLASS} ${tag_class}`;
|
|
|
}
|
|
|
const js_result = js_mode.token(stream, state);
|
|
|
if (stream.peek() == null && state.freeLine) {
|
|
|
keywords += ` line-background-templater-command-bg`;
|
|
|
}
|
|
|
if (!state.freeLine) {
|
|
|
keywords += ` line-${TP_INLINE_CLASS}`;
|
|
|
}
|
|
|
return `${keywords} ${TP_CMD_TOKEN_CLASS} ${js_result}`;
|
|
|
}
|
|
|
const match = stream.match(/<%[-_]{0,1}\s*([*~+]{0,1})/, true);
|
|
|
if (match != null) {
|
|
|
switch (match[1]) {
|
|
|
case "*":
|
|
|
state.tag_class = TP_EXEC_TAG_TOKEN_CLASS;
|
|
|
break;
|
|
|
case "~":
|
|
|
state.tag_class = TP_RAW_TAG_TOKEN_CLASS;
|
|
|
break;
|
|
|
default:
|
|
|
state.tag_class =
|
|
|
TP_INTERPOLATION_TAG_TOKEN_CLASS;
|
|
|
break;
|
|
|
}
|
|
|
state.inCommand = true;
|
|
|
return `line-${TP_INLINE_CLASS} ${TP_CMD_TOKEN_CLASS} ${TP_OPENING_TAG_TOKEN_CLASS} ${state.tag_class}`;
|
|
|
}
|
|
|
while (stream.next() != null && !stream.match(/<%/, false))
|
|
|
;
|
|
|
return null;
|
|
|
},
|
|
|
};
|
|
|
return overlay_mode(window.CodeMirror.getMode(config, "hypermd"), templaterOverlay);
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
registerHinter() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
// TODO
|
|
|
/*
|
|
|
await delay(1000);
|
|
|
|
|
|
var comp = [
|
|
|
["here", "hither"],
|
|
|
["asynchronous", "nonsynchronous"],
|
|
|
["completion", "achievement", "conclusion", "culmination", "expirations"],
|
|
|
["hinting", "advise", "broach", "imply"],
|
|
|
["function","action"],
|
|
|
["provide", "add", "bring", "give"],
|
|
|
["synonyms", "equivalents"],
|
|
|
["words", "token"],
|
|
|
["each", "every"],
|
|
|
];
|
|
|
|
|
|
function synonyms(cm: any, option: any) {
|
|
|
return new Promise(function(accept) {
|
|
|
setTimeout(function() {
|
|
|
var cursor = cm.getCursor(), line = cm.getLine(cursor.line)
|
|
|
var start = cursor.ch, end = cursor.ch
|
|
|
while (start && /\w/.test(line.charAt(start - 1))) --start
|
|
|
while (end < line.length && /\w/.test(line.charAt(end))) ++end
|
|
|
var word = line.slice(start, end).toLowerCase()
|
|
|
for (var i = 0; i < comp.length; i++) {
|
|
|
if (comp[i].indexOf(word) != -1) {
|
|
|
return accept({
|
|
|
list: comp[i],
|
|
|
from: window.CodeMirror.Pos(cursor.line, start),
|
|
|
to: window.CodeMirror.Pos(cursor.line, end)
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
return accept(null);
|
|
|
}, 100)
|
|
|
});
|
|
|
}
|
|
|
|
|
|
this.app.workspace.on("codemirror", cm => {
|
|
|
cm.setOption("extraKeys", {"Ctrl-Space": "autocomplete"});
|
|
|
cm.setOption("hintOptions", {hint: synonyms});
|
|
|
});
|
|
|
|
|
|
this.app.workspace.iterateCodeMirrors(cm => {
|
|
|
console.log("CM:", cm);
|
|
|
cm.setOption("extraKeys", {"Space": "autocomplete"});
|
|
|
cm.setOption("hintOptions", {hint: synonyms});
|
|
|
});
|
|
|
*/
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function setPrototypeOf(obj, proto) {
|
|
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
|
if (Object.setPrototypeOf) {
|
|
|
Object.setPrototypeOf(obj, proto);
|
|
|
}
|
|
|
else {
|
|
|
obj.__proto__ = proto;
|
|
|
}
|
|
|
}
|
|
|
// This is pretty much the only way to get nice, extended Errors
|
|
|
// without using ES6
|
|
|
/**
|
|
|
* This returns a new Error with a custom prototype. Note that it's _not_ a constructor
|
|
|
*
|
|
|
* @param message Error message
|
|
|
*
|
|
|
* **Example**
|
|
|
*
|
|
|
* ```js
|
|
|
* throw EtaErr("template not found")
|
|
|
* ```
|
|
|
*/
|
|
|
function EtaErr(message) {
|
|
|
var err = new Error(message);
|
|
|
setPrototypeOf(err, EtaErr.prototype);
|
|
|
return err;
|
|
|
}
|
|
|
EtaErr.prototype = Object.create(Error.prototype, {
|
|
|
name: { value: 'Eta Error', enumerable: false }
|
|
|
});
|
|
|
/**
|
|
|
* Throws an EtaErr with a nicely formatted error and message showing where in the template the error occurred.
|
|
|
*/
|
|
|
function ParseErr(message, str, indx) {
|
|
|
var whitespace = str.slice(0, indx).split(/\n/);
|
|
|
var lineNo = whitespace.length;
|
|
|
var colNo = whitespace[lineNo - 1].length + 1;
|
|
|
message +=
|
|
|
' at line ' +
|
|
|
lineNo +
|
|
|
' col ' +
|
|
|
colNo +
|
|
|
':\n\n' +
|
|
|
' ' +
|
|
|
str.split(/\n/)[lineNo - 1] +
|
|
|
'\n' +
|
|
|
' ' +
|
|
|
Array(colNo).join(' ') +
|
|
|
'^';
|
|
|
throw EtaErr(message);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @returns The global Promise function
|
|
|
*/
|
|
|
var promiseImpl = new Function('return this')().Promise;
|
|
|
/**
|
|
|
* @returns A new AsyncFunction constuctor
|
|
|
*/
|
|
|
function getAsyncFunctionConstructor() {
|
|
|
try {
|
|
|
return new Function('return (async function(){}).constructor')();
|
|
|
}
|
|
|
catch (e) {
|
|
|
if (e instanceof SyntaxError) {
|
|
|
throw EtaErr("This environment doesn't support async/await");
|
|
|
}
|
|
|
else {
|
|
|
throw e;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* str.trimLeft polyfill
|
|
|
*
|
|
|
* @param str - Input string
|
|
|
* @returns The string with left whitespace removed
|
|
|
*
|
|
|
*/
|
|
|
function trimLeft(str) {
|
|
|
// eslint-disable-next-line no-extra-boolean-cast
|
|
|
if (!!String.prototype.trimLeft) {
|
|
|
return str.trimLeft();
|
|
|
}
|
|
|
else {
|
|
|
return str.replace(/^\s+/, '');
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* str.trimRight polyfill
|
|
|
*
|
|
|
* @param str - Input string
|
|
|
* @returns The string with right whitespace removed
|
|
|
*
|
|
|
*/
|
|
|
function trimRight(str) {
|
|
|
// eslint-disable-next-line no-extra-boolean-cast
|
|
|
if (!!String.prototype.trimRight) {
|
|
|
return str.trimRight();
|
|
|
}
|
|
|
else {
|
|
|
return str.replace(/\s+$/, ''); // TODO: do we really need to replace BOM's?
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// TODO: allow '-' to trim up until newline. Use [^\S\n\r] instead of \s
|
|
|
/* END TYPES */
|
|
|
function hasOwnProp(obj, prop) {
|
|
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
|
}
|
|
|
function copyProps(toObj, fromObj) {
|
|
|
for (var key in fromObj) {
|
|
|
if (hasOwnProp(fromObj, key)) {
|
|
|
toObj[key] = fromObj[key];
|
|
|
}
|
|
|
}
|
|
|
return toObj;
|
|
|
}
|
|
|
/**
|
|
|
* Takes a string within a template and trims it, based on the preceding tag's whitespace control and `config.autoTrim`
|
|
|
*/
|
|
|
function trimWS(str, config, wsLeft, wsRight) {
|
|
|
var leftTrim;
|
|
|
var rightTrim;
|
|
|
if (Array.isArray(config.autoTrim)) {
|
|
|
// kinda confusing
|
|
|
// but _}} will trim the left side of the following string
|
|
|
leftTrim = config.autoTrim[1];
|
|
|
rightTrim = config.autoTrim[0];
|
|
|
}
|
|
|
else {
|
|
|
leftTrim = rightTrim = config.autoTrim;
|
|
|
}
|
|
|
if (wsLeft || wsLeft === false) {
|
|
|
leftTrim = wsLeft;
|
|
|
}
|
|
|
if (wsRight || wsRight === false) {
|
|
|
rightTrim = wsRight;
|
|
|
}
|
|
|
if (!rightTrim && !leftTrim) {
|
|
|
return str;
|
|
|
}
|
|
|
if (leftTrim === 'slurp' && rightTrim === 'slurp') {
|
|
|
return str.trim();
|
|
|
}
|
|
|
if (leftTrim === '_' || leftTrim === 'slurp') {
|
|
|
// console.log('trimming left' + leftTrim)
|
|
|
// full slurp
|
|
|
str = trimLeft(str);
|
|
|
}
|
|
|
else if (leftTrim === '-' || leftTrim === 'nl') {
|
|
|
// nl trim
|
|
|
str = str.replace(/^(?:\r\n|\n|\r)/, '');
|
|
|
}
|
|
|
if (rightTrim === '_' || rightTrim === 'slurp') {
|
|
|
// full slurp
|
|
|
str = trimRight(str);
|
|
|
}
|
|
|
else if (rightTrim === '-' || rightTrim === 'nl') {
|
|
|
// nl trim
|
|
|
str = str.replace(/(?:\r\n|\n|\r)$/, ''); // TODO: make sure this gets \r\n
|
|
|
}
|
|
|
return str;
|
|
|
}
|
|
|
/**
|
|
|
* A map of special HTML characters to their XML-escaped equivalents
|
|
|
*/
|
|
|
var escMap = {
|
|
|
'&': '&',
|
|
|
'<': '<',
|
|
|
'>': '>',
|
|
|
'"': '"',
|
|
|
"'": '''
|
|
|
};
|
|
|
function replaceChar(s) {
|
|
|
return escMap[s];
|
|
|
}
|
|
|
/**
|
|
|
* XML-escapes an input value after converting it to a string
|
|
|
*
|
|
|
* @param str - Input value (usually a string)
|
|
|
* @returns XML-escaped string
|
|
|
*/
|
|
|
function XMLEscape(str) {
|
|
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
|
// To deal with XSS. Based on Escape implementations of Mustache.JS and Marko, then customized.
|
|
|
var newStr = String(str);
|
|
|
if (/[&<>"']/.test(newStr)) {
|
|
|
return newStr.replace(/[&<>"']/g, replaceChar);
|
|
|
}
|
|
|
else {
|
|
|
return newStr;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* END TYPES */
|
|
|
var templateLitReg = /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g;
|
|
|
var singleQuoteReg = /'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g;
|
|
|
var doubleQuoteReg = /"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g;
|
|
|
/** Escape special regular expression characters inside a string */
|
|
|
function escapeRegExp(string) {
|
|
|
// From MDN
|
|
|
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
|
}
|
|
|
function parse(str, config) {
|
|
|
var buffer = [];
|
|
|
var trimLeftOfNextStr = false;
|
|
|
var lastIndex = 0;
|
|
|
var parseOptions = config.parse;
|
|
|
if (config.plugins) {
|
|
|
for (var i = 0; i < config.plugins.length; i++) {
|
|
|
var plugin = config.plugins[i];
|
|
|
if (plugin.processTemplate) {
|
|
|
str = plugin.processTemplate(str, config);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
/* Adding for EJS compatibility */
|
|
|
if (config.rmWhitespace) {
|
|
|
// Code taken directly from EJS
|
|
|
// Have to use two separate replaces here as `^` and `$` operators don't
|
|
|
// work well with `\r` and empty lines don't work well with the `m` flag.
|
|
|
// Essentially, this replaces the whitespace at the beginning and end of
|
|
|
// each line and removes multiple newlines.
|
|
|
str = str.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, '');
|
|
|
}
|
|
|
/* End rmWhitespace option */
|
|
|
templateLitReg.lastIndex = 0;
|
|
|
singleQuoteReg.lastIndex = 0;
|
|
|
doubleQuoteReg.lastIndex = 0;
|
|
|
function pushString(strng, shouldTrimRightOfString) {
|
|
|
if (strng) {
|
|
|
// if string is truthy it must be of type 'string'
|
|
|
strng = trimWS(strng, config, trimLeftOfNextStr, // this will only be false on the first str, the next ones will be null or undefined
|
|
|
shouldTrimRightOfString);
|
|
|
if (strng) {
|
|
|
// replace \ with \\, ' with \'
|
|
|
// we're going to convert all CRLF to LF so it doesn't take more than one replace
|
|
|
strng = strng.replace(/\\|'/g, '\\$&').replace(/\r\n|\n|\r/g, '\\n');
|
|
|
buffer.push(strng);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
var prefixes = [parseOptions.exec, parseOptions.interpolate, parseOptions.raw].reduce(function (accumulator, prefix) {
|
|
|
if (accumulator && prefix) {
|
|
|
return accumulator + '|' + escapeRegExp(prefix);
|
|
|
}
|
|
|
else if (prefix) {
|
|
|
// accumulator is falsy
|
|
|
return escapeRegExp(prefix);
|
|
|
}
|
|
|
else {
|
|
|
// prefix and accumulator are both falsy
|
|
|
return accumulator;
|
|
|
}
|
|
|
}, '');
|
|
|
var parseOpenReg = new RegExp('([^]*?)' + escapeRegExp(config.tags[0]) + '(-|_)?\\s*(' + prefixes + ')?\\s*(?![\\s+\\-_' + prefixes + '])', 'g');
|
|
|
var parseCloseReg = new RegExp('\'|"|`|\\/\\*|(\\s*(-|_)?' + escapeRegExp(config.tags[1]) + ')', 'g');
|
|
|
// TODO: benchmark having the \s* on either side vs using str.trim()
|
|
|
var m;
|
|
|
while ((m = parseOpenReg.exec(str))) {
|
|
|
lastIndex = m[0].length + m.index;
|
|
|
var precedingString = m[1];
|
|
|
var wsLeft = m[2];
|
|
|
var prefix = m[3] || ''; // by default either ~, =, or empty
|
|
|
pushString(precedingString, wsLeft);
|
|
|
parseCloseReg.lastIndex = lastIndex;
|
|
|
var closeTag = void 0;
|
|
|
var currentObj = false;
|
|
|
while ((closeTag = parseCloseReg.exec(str))) {
|
|
|
if (closeTag[1]) {
|
|
|
var content = str.slice(lastIndex, closeTag.index);
|
|
|
parseOpenReg.lastIndex = lastIndex = parseCloseReg.lastIndex;
|
|
|
trimLeftOfNextStr = closeTag[2];
|
|
|
var currentType = prefix === parseOptions.exec
|
|
|
? 'e'
|
|
|
: prefix === parseOptions.raw
|
|
|
? 'r'
|
|
|
: prefix === parseOptions.interpolate
|
|
|
? 'i'
|
|
|
: '';
|
|
|
currentObj = { t: currentType, val: content };
|
|
|
break;
|
|
|
}
|
|
|
else {
|
|
|
var char = closeTag[0];
|
|
|
if (char === '/*') {
|
|
|
var commentCloseInd = str.indexOf('*/', parseCloseReg.lastIndex);
|
|
|
if (commentCloseInd === -1) {
|
|
|
ParseErr('unclosed comment', str, closeTag.index);
|
|
|
}
|
|
|
parseCloseReg.lastIndex = commentCloseInd;
|
|
|
}
|
|
|
else if (char === "'") {
|
|
|
singleQuoteReg.lastIndex = closeTag.index;
|
|
|
var singleQuoteMatch = singleQuoteReg.exec(str);
|
|
|
if (singleQuoteMatch) {
|
|
|
parseCloseReg.lastIndex = singleQuoteReg.lastIndex;
|
|
|
}
|
|
|
else {
|
|
|
ParseErr('unclosed string', str, closeTag.index);
|
|
|
}
|
|
|
}
|
|
|
else if (char === '"') {
|
|
|
doubleQuoteReg.lastIndex = closeTag.index;
|
|
|
var doubleQuoteMatch = doubleQuoteReg.exec(str);
|
|
|
if (doubleQuoteMatch) {
|
|
|
parseCloseReg.lastIndex = doubleQuoteReg.lastIndex;
|
|
|
}
|
|
|
else {
|
|
|
ParseErr('unclosed string', str, closeTag.index);
|
|
|
}
|
|
|
}
|
|
|
else if (char === '`') {
|
|
|
templateLitReg.lastIndex = closeTag.index;
|
|
|
var templateLitMatch = templateLitReg.exec(str);
|
|
|
if (templateLitMatch) {
|
|
|
parseCloseReg.lastIndex = templateLitReg.lastIndex;
|
|
|
}
|
|
|
else {
|
|
|
ParseErr('unclosed string', str, closeTag.index);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (currentObj) {
|
|
|
buffer.push(currentObj);
|
|
|
}
|
|
|
else {
|
|
|
ParseErr('unclosed tag', str, m.index + precedingString.length);
|
|
|
}
|
|
|
}
|
|
|
pushString(str.slice(lastIndex, str.length), false);
|
|
|
if (config.plugins) {
|
|
|
for (var i = 0; i < config.plugins.length; i++) {
|
|
|
var plugin = config.plugins[i];
|
|
|
if (plugin.processAST) {
|
|
|
buffer = plugin.processAST(buffer, config);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return buffer;
|
|
|
}
|
|
|
|
|
|
/* END TYPES */
|
|
|
/**
|
|
|
* Compiles a template string to a function string. Most often users just use `compile()`, which calls `compileToString` and creates a new function using the result
|
|
|
*
|
|
|
* **Example**
|
|
|
*
|
|
|
* ```js
|
|
|
* compileToString("Hi <%= it.user %>", eta.config)
|
|
|
* // "var tR='',include=E.include.bind(E),includeFile=E.includeFile.bind(E);tR+='Hi ';tR+=E.e(it.user);if(cb){cb(null,tR)} return tR"
|
|
|
* ```
|
|
|
*/
|
|
|
function compileToString(str, config) {
|
|
|
var buffer = parse(str, config);
|
|
|
var res = "var tR='',__l,__lP" +
|
|
|
(config.include ? ',include=E.include.bind(E)' : '') +
|
|
|
(config.includeFile ? ',includeFile=E.includeFile.bind(E)' : '') +
|
|
|
'\nfunction layout(p,d){__l=p;__lP=d}\n' +
|
|
|
(config.globalAwait ? 'const _prs = [];\n' : '') +
|
|
|
(config.useWith ? 'with(' + config.varName + '||{}){' : '') +
|
|
|
compileScope(buffer, config) +
|
|
|
(config.includeFile
|
|
|
? 'if(__l)tR=' +
|
|
|
(config.async ? 'await ' : '') +
|
|
|
("includeFile(__l,Object.assign(" + config.varName + ",{body:tR},__lP))\n")
|
|
|
: config.include
|
|
|
? 'if(__l)tR=' +
|
|
|
(config.async ? 'await ' : '') +
|
|
|
("include(__l,Object.assign(" + config.varName + ",{body:tR},__lP))\n")
|
|
|
: '') +
|
|
|
'if(cb){cb(null,tR)} return tR' +
|
|
|
(config.useWith ? '}' : '');
|
|
|
if (config.plugins) {
|
|
|
for (var i = 0; i < config.plugins.length; i++) {
|
|
|
var plugin = config.plugins[i];
|
|
|
if (plugin.processFnString) {
|
|
|
res = plugin.processFnString(res, config);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return res;
|
|
|
}
|
|
|
/**
|
|
|
* Loops through the AST generated by `parse` and transform each item into JS calls
|
|
|
*
|
|
|
* **Example**
|
|
|
*
|
|
|
* ```js
|
|
|
* // AST version of 'Hi <%= it.user %>'
|
|
|
* let templateAST = ['Hi ', { val: 'it.user', t: 'i' }]
|
|
|
* compileScope(templateAST, eta.config)
|
|
|
* // "tR+='Hi ';tR+=E.e(it.user);"
|
|
|
* ```
|
|
|
*/
|
|
|
function compileScope(buff, config) {
|
|
|
var i;
|
|
|
var buffLength = buff.length;
|
|
|
var returnStr = '';
|
|
|
var REPLACEMENT_STR = "rJ2KqXzxQg";
|
|
|
for (i = 0; i < buffLength; i++) {
|
|
|
var currentBlock = buff[i];
|
|
|
if (typeof currentBlock === 'string') {
|
|
|
var str = currentBlock;
|
|
|
// we know string exists
|
|
|
returnStr += "tR+='" + str + "'\n";
|
|
|
}
|
|
|
else {
|
|
|
var type = currentBlock.t; // ~, s, !, ?, r
|
|
|
var content = currentBlock.val || '';
|
|
|
if (type === 'r') {
|
|
|
// raw
|
|
|
if (config.globalAwait) {
|
|
|
returnStr += "_prs.push(" + content + ");\n";
|
|
|
returnStr += "tR+='" + REPLACEMENT_STR + "'\n";
|
|
|
}
|
|
|
else {
|
|
|
if (config.filter) {
|
|
|
content = 'E.filter(' + content + ')';
|
|
|
}
|
|
|
returnStr += 'tR+=' + content + '\n';
|
|
|
}
|
|
|
}
|
|
|
else if (type === 'i') {
|
|
|
// interpolate
|
|
|
if (config.globalAwait) {
|
|
|
returnStr += "_prs.push(" + content + ");\n";
|
|
|
returnStr += "tR+='" + REPLACEMENT_STR + "'\n";
|
|
|
}
|
|
|
else {
|
|
|
if (config.filter) {
|
|
|
content = 'E.filter(' + content + ')';
|
|
|
}
|
|
|
returnStr += 'tR+=' + content + '\n';
|
|
|
if (config.autoEscape) {
|
|
|
content = 'E.e(' + content + ')';
|
|
|
}
|
|
|
returnStr += 'tR+=' + content + '\n';
|
|
|
}
|
|
|
}
|
|
|
else if (type === 'e') {
|
|
|
// execute
|
|
|
returnStr += content + '\n'; // you need a \n in case you have <% } %>
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (config.globalAwait) {
|
|
|
returnStr += "const _rst = await Promise.all(_prs);\ntR = tR.replace(/" + REPLACEMENT_STR + "/g, () => _rst.shift());\n";
|
|
|
}
|
|
|
return returnStr;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Handles storage and accessing of values
|
|
|
*
|
|
|
* In this case, we use it to store compiled template functions
|
|
|
* Indexed by their `name` or `filename`
|
|
|
*/
|
|
|
var Cacher = /** @class */ (function () {
|
|
|
function Cacher(cache) {
|
|
|
this.cache = cache;
|
|
|
}
|
|
|
Cacher.prototype.define = function (key, val) {
|
|
|
this.cache[key] = val;
|
|
|
};
|
|
|
Cacher.prototype.get = function (key) {
|
|
|
// string | array.
|
|
|
// TODO: allow array of keys to look down
|
|
|
// TODO: create plugin to allow referencing helpers, filters with dot notation
|
|
|
return this.cache[key];
|
|
|
};
|
|
|
Cacher.prototype.remove = function (key) {
|
|
|
delete this.cache[key];
|
|
|
};
|
|
|
Cacher.prototype.reset = function () {
|
|
|
this.cache = {};
|
|
|
};
|
|
|
Cacher.prototype.load = function (cacheObj) {
|
|
|
copyProps(this.cache, cacheObj);
|
|
|
};
|
|
|
return Cacher;
|
|
|
}());
|
|
|
|
|
|
/* END TYPES */
|
|
|
/**
|
|
|
* Eta's template storage
|
|
|
*
|
|
|
* Stores partials and cached templates
|
|
|
*/
|
|
|
var templates = new Cacher({});
|
|
|
|
|
|
/* END TYPES */
|
|
|
/**
|
|
|
* Include a template based on its name (or filepath, if it's already been cached).
|
|
|
*
|
|
|
* Called like `include(templateNameOrPath, data)`
|
|
|
*/
|
|
|
function includeHelper(templateNameOrPath, data) {
|
|
|
var template = this.templates.get(templateNameOrPath);
|
|
|
if (!template) {
|
|
|
throw EtaErr('Could not fetch template "' + templateNameOrPath + '"');
|
|
|
}
|
|
|
return template(data, this);
|
|
|
}
|
|
|
/** Eta's base (global) configuration */
|
|
|
var config = {
|
|
|
async: false,
|
|
|
autoEscape: true,
|
|
|
autoTrim: [false, 'nl'],
|
|
|
cache: false,
|
|
|
e: XMLEscape,
|
|
|
include: includeHelper,
|
|
|
parse: {
|
|
|
exec: '',
|
|
|
interpolate: '=',
|
|
|
raw: '~'
|
|
|
},
|
|
|
plugins: [],
|
|
|
rmWhitespace: false,
|
|
|
tags: ['<%', '%>'],
|
|
|
templates: templates,
|
|
|
useWith: false,
|
|
|
varName: 'it'
|
|
|
};
|
|
|
/**
|
|
|
* Takes one or two partial (not necessarily complete) configuration objects, merges them 1 layer deep into eta.config, and returns the result
|
|
|
*
|
|
|
* @param override Partial configuration object
|
|
|
* @param baseConfig Partial configuration object to merge before `override`
|
|
|
*
|
|
|
* **Example**
|
|
|
*
|
|
|
* ```js
|
|
|
* let customConfig = getConfig({tags: ['!#', '#!']})
|
|
|
* ```
|
|
|
*/
|
|
|
function getConfig(override, baseConfig) {
|
|
|
// TODO: run more tests on this
|
|
|
var res = {}; // Linked
|
|
|
copyProps(res, config); // Creates deep clone of eta.config, 1 layer deep
|
|
|
if (baseConfig) {
|
|
|
copyProps(res, baseConfig);
|
|
|
}
|
|
|
if (override) {
|
|
|
copyProps(res, override);
|
|
|
}
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
/* END TYPES */
|
|
|
/**
|
|
|
* Takes a template string and returns a template function that can be called with (data, config, [cb])
|
|
|
*
|
|
|
* @param str - The template string
|
|
|
* @param config - A custom configuration object (optional)
|
|
|
*
|
|
|
* **Example**
|
|
|
*
|
|
|
* ```js
|
|
|
* let compiledFn = eta.compile("Hi <%= it.user %>")
|
|
|
* // function anonymous()
|
|
|
* let compiledFnStr = compiledFn.toString()
|
|
|
* // "function anonymous(it,E,cb\n) {\nvar tR='',include=E.include.bind(E),includeFile=E.includeFile.bind(E);tR+='Hi ';tR+=E.e(it.user);if(cb){cb(null,tR)} return tR\n}"
|
|
|
* ```
|
|
|
*/
|
|
|
function compile(str, config) {
|
|
|
var options = getConfig(config || {});
|
|
|
/* ASYNC HANDLING */
|
|
|
// The below code is modified from mde/ejs. All credit should go to them.
|
|
|
var ctor = options.async ? getAsyncFunctionConstructor() : Function;
|
|
|
/* END ASYNC HANDLING */
|
|
|
try {
|
|
|
return new ctor(options.varName, 'E', // EtaConfig
|
|
|
'cb', // optional callback
|
|
|
compileToString(str, options)); // eslint-disable-line no-new-func
|
|
|
}
|
|
|
catch (e) {
|
|
|
if (e instanceof SyntaxError) {
|
|
|
throw EtaErr('Bad template syntax\n\n' +
|
|
|
e.message +
|
|
|
'\n' +
|
|
|
Array(e.message.length + 1).join('=') +
|
|
|
'\n' +
|
|
|
compileToString(str, options) +
|
|
|
'\n' // This will put an extra newline before the callstack for extra readability
|
|
|
);
|
|
|
}
|
|
|
else {
|
|
|
throw e;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var _BOM = /^\uFEFF/;
|
|
|
/* END TYPES */
|
|
|
/**
|
|
|
* Get the path to the included file from the parent file path and the
|
|
|
* specified path.
|
|
|
*
|
|
|
* If `name` does not have an extension, it will default to `.eta`
|
|
|
*
|
|
|
* @param name specified path
|
|
|
* @param parentfile parent file path
|
|
|
* @param isDirectory whether parentfile is a directory
|
|
|
* @return absolute path to template
|
|
|
*/
|
|
|
function getWholeFilePath(name, parentfile, isDirectory) {
|
|
|
var includePath = path.resolve(isDirectory ? parentfile : path.dirname(parentfile), // returns directory the parent file is in
|
|
|
name // file
|
|
|
) + (path.extname(name) ? '' : '.eta');
|
|
|
return includePath;
|
|
|
}
|
|
|
/**
|
|
|
* Get the absolute path to an included template
|
|
|
*
|
|
|
* If this is called with an absolute path (for example, starting with '/' or 'C:\')
|
|
|
* then Eta will attempt to resolve the absolute path within options.views. If it cannot,
|
|
|
* Eta will fallback to options.root or '/'
|
|
|
*
|
|
|
* If this is called with a relative path, Eta will:
|
|
|
* - Look relative to the current template (if the current template has the `filename` property)
|
|
|
* - Look inside each directory in options.views
|
|
|
*
|
|
|
* Note: if Eta is unable to find a template using path and options, it will throw an error.
|
|
|
*
|
|
|
* @param path specified path
|
|
|
* @param options compilation options
|
|
|
* @return absolute path to template
|
|
|
*/
|
|
|
function getPath(path, options) {
|
|
|
var includePath = false;
|
|
|
var views = options.views;
|
|
|
var searchedPaths = [];
|
|
|
// If these four values are the same,
|
|
|
// getPath() will return the same result every time.
|
|
|
// We can cache the result to avoid expensive
|
|
|
// file operations.
|
|
|
var pathOptions = JSON.stringify({
|
|
|
filename: options.filename,
|
|
|
path: path,
|
|
|
root: options.root,
|
|
|
views: options.views
|
|
|
});
|
|
|
if (options.cache && options.filepathCache && options.filepathCache[pathOptions]) {
|
|
|
// Use the cached filepath
|
|
|
return options.filepathCache[pathOptions];
|
|
|
}
|
|
|
/** Add a filepath to the list of paths we've checked for a template */
|
|
|
function addPathToSearched(pathSearched) {
|
|
|
if (!searchedPaths.includes(pathSearched)) {
|
|
|
searchedPaths.push(pathSearched);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Take a filepath (like 'partials/mypartial.eta'). Attempt to find the template file inside `views`;
|
|
|
* return the resulting template file path, or `false` to indicate that the template was not found.
|
|
|
*
|
|
|
* @param views the filepath that holds templates, or an array of filepaths that hold templates
|
|
|
* @param path the path to the template
|
|
|
*/
|
|
|
function searchViews(views, path) {
|
|
|
var filePath;
|
|
|
// If views is an array, then loop through each directory
|
|
|
// And attempt to find the template
|
|
|
if (Array.isArray(views) &&
|
|
|
views.some(function (v) {
|
|
|
filePath = getWholeFilePath(path, v, true);
|
|
|
addPathToSearched(filePath);
|
|
|
return fs.existsSync(filePath);
|
|
|
})) {
|
|
|
// If the above returned true, we know that the filePath was just set to a path
|
|
|
// That exists (Array.some() returns as soon as it finds a valid element)
|
|
|
return filePath;
|
|
|
}
|
|
|
else if (typeof views === 'string') {
|
|
|
// Search for the file if views is a single directory
|
|
|
filePath = getWholeFilePath(path, views, true);
|
|
|
addPathToSearched(filePath);
|
|
|
if (fs.existsSync(filePath)) {
|
|
|
return filePath;
|
|
|
}
|
|
|
}
|
|
|
// Unable to find a file
|
|
|
return false;
|
|
|
}
|
|
|
// Path starts with '/', 'C:\', etc.
|
|
|
var match = /^[A-Za-z]+:\\|^\//.exec(path);
|
|
|
// Absolute path, like /partials/partial.eta
|
|
|
if (match && match.length) {
|
|
|
// We have to trim the beginning '/' off the path, or else
|
|
|
// path.resolve(dir, path) will always resolve to just path
|
|
|
var formattedPath = path.replace(/^\/*/, '');
|
|
|
// First, try to resolve the path within options.views
|
|
|
includePath = searchViews(views, formattedPath);
|
|
|
if (!includePath) {
|
|
|
// If that fails, searchViews will return false. Try to find the path
|
|
|
// inside options.root (by default '/', the base of the filesystem)
|
|
|
var pathFromRoot = getWholeFilePath(formattedPath, options.root || '/', true);
|
|
|
addPathToSearched(pathFromRoot);
|
|
|
includePath = pathFromRoot;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// Relative paths
|
|
|
// Look relative to a passed filename first
|
|
|
if (options.filename) {
|
|
|
var filePath = getWholeFilePath(path, options.filename);
|
|
|
addPathToSearched(filePath);
|
|
|
if (fs.existsSync(filePath)) {
|
|
|
includePath = filePath;
|
|
|
}
|
|
|
}
|
|
|
// Then look for the template in options.views
|
|
|
if (!includePath) {
|
|
|
includePath = searchViews(views, path);
|
|
|
}
|
|
|
if (!includePath) {
|
|
|
throw EtaErr('Could not find the template "' + path + '". Paths tried: ' + searchedPaths);
|
|
|
}
|
|
|
}
|
|
|
// If caching and filepathCache are enabled,
|
|
|
// cache the input & output of this function.
|
|
|
if (options.cache && options.filepathCache) {
|
|
|
options.filepathCache[pathOptions] = includePath;
|
|
|
}
|
|
|
return includePath;
|
|
|
}
|
|
|
/**
|
|
|
* Reads a file synchronously
|
|
|
*/
|
|
|
function readFile(filePath) {
|
|
|
try {
|
|
|
return fs.readFileSync(filePath).toString().replace(_BOM, ''); // TODO: is replacing BOM's necessary?
|
|
|
}
|
|
|
catch (_a) {
|
|
|
throw EtaErr("Failed to read template at '" + filePath + "'");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// express is set like: app.engine('html', require('eta').renderFile)
|
|
|
/* END TYPES */
|
|
|
/**
|
|
|
* Reads a template, compiles it into a function, caches it if caching isn't disabled, returns the function
|
|
|
*
|
|
|
* @param filePath Absolute path to template file
|
|
|
* @param options Eta configuration overrides
|
|
|
* @param noCache Optionally, make Eta not cache the template
|
|
|
*/
|
|
|
function loadFile(filePath, options, noCache) {
|
|
|
var config = getConfig(options);
|
|
|
var template = readFile(filePath);
|
|
|
try {
|
|
|
var compiledTemplate = compile(template, config);
|
|
|
if (!noCache) {
|
|
|
config.templates.define(config.filename, compiledTemplate);
|
|
|
}
|
|
|
return compiledTemplate;
|
|
|
}
|
|
|
catch (e) {
|
|
|
throw EtaErr('Loading file: ' + filePath + ' failed:\n\n' + e.message);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Get the template from a string or a file, either compiled on-the-fly or
|
|
|
* read from cache (if enabled), and cache the template if needed.
|
|
|
*
|
|
|
* If `options.cache` is true, this function reads the file from
|
|
|
* `options.filename` so it must be set prior to calling this function.
|
|
|
*
|
|
|
* @param options compilation options
|
|
|
* @return Eta template function
|
|
|
*/
|
|
|
function handleCache(options) {
|
|
|
var filename = options.filename;
|
|
|
if (options.cache) {
|
|
|
var func = options.templates.get(filename);
|
|
|
if (func) {
|
|
|
return func;
|
|
|
}
|
|
|
return loadFile(filename, options);
|
|
|
}
|
|
|
// Caching is disabled, so pass noCache = true
|
|
|
return loadFile(filename, options, true);
|
|
|
}
|
|
|
/**
|
|
|
* Get the template function.
|
|
|
*
|
|
|
* If `options.cache` is `true`, then the template is cached.
|
|
|
*
|
|
|
* This returns a template function and the config object with which that template function should be called.
|
|
|
*
|
|
|
* @remarks
|
|
|
*
|
|
|
* It's important that this returns a config object with `filename` set.
|
|
|
* Otherwise, the included file would not be able to use relative paths
|
|
|
*
|
|
|
* @param path path for the specified file (if relative, specify `views` on `options`)
|
|
|
* @param options compilation options
|
|
|
* @return [Eta template function, new config object]
|
|
|
*/
|
|
|
function includeFile(path, options) {
|
|
|
// the below creates a new options object, using the parent filepath of the old options object and the path
|
|
|
var newFileOptions = getConfig({ filename: getPath(path, options) }, options);
|
|
|
// TODO: make sure properties are currectly copied over
|
|
|
return [handleCache(newFileOptions), newFileOptions];
|
|
|
}
|
|
|
|
|
|
/* END TYPES */
|
|
|
/**
|
|
|
* Called with `includeFile(path, data)`
|
|
|
*/
|
|
|
function includeFileHelper(path, data) {
|
|
|
var templateAndConfig = includeFile(path, this);
|
|
|
return templateAndConfig[0](data, templateAndConfig[1]);
|
|
|
}
|
|
|
|
|
|
/* END TYPES */
|
|
|
function handleCache$1(template, options) {
|
|
|
if (options.cache && options.name && options.templates.get(options.name)) {
|
|
|
return options.templates.get(options.name);
|
|
|
}
|
|
|
var templateFunc = typeof template === 'function' ? template : compile(template, options);
|
|
|
// Note that we don't have to check if it already exists in the cache;
|
|
|
// it would have returned earlier if it had
|
|
|
if (options.cache && options.name) {
|
|
|
options.templates.define(options.name, templateFunc);
|
|
|
}
|
|
|
return templateFunc;
|
|
|
}
|
|
|
/**
|
|
|
* Render a template
|
|
|
*
|
|
|
* If `template` is a string, Eta will compile it to a function and then call it with the provided data.
|
|
|
* If `template` is a template function, Eta will call it with the provided data.
|
|
|
*
|
|
|
* If `config.async` is `false`, Eta will return the rendered template.
|
|
|
*
|
|
|
* If `config.async` is `true` and there's a callback function, Eta will call the callback with `(err, renderedTemplate)`.
|
|
|
* If `config.async` is `true` and there's not a callback function, Eta will return a Promise that resolves to the rendered template.
|
|
|
*
|
|
|
* If `config.cache` is `true` and `config` has a `name` or `filename` property, Eta will cache the template on the first render and use the cached template for all subsequent renders.
|
|
|
*
|
|
|
* @param template Template string or template function
|
|
|
* @param data Data to render the template with
|
|
|
* @param config Optional config options
|
|
|
* @param cb Callback function
|
|
|
*/
|
|
|
function render(template, data, config, cb) {
|
|
|
var options = getConfig(config || {});
|
|
|
if (options.async) {
|
|
|
if (cb) {
|
|
|
// If user passes callback
|
|
|
try {
|
|
|
// Note: if there is an error while rendering the template,
|
|
|
// It will bubble up and be caught here
|
|
|
var templateFn = handleCache$1(template, options);
|
|
|
templateFn(data, options, cb);
|
|
|
}
|
|
|
catch (err) {
|
|
|
return cb(err);
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// No callback, try returning a promise
|
|
|
if (typeof promiseImpl === 'function') {
|
|
|
return new promiseImpl(function (resolve, reject) {
|
|
|
try {
|
|
|
resolve(handleCache$1(template, options)(data, options));
|
|
|
}
|
|
|
catch (err) {
|
|
|
reject(err);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
else {
|
|
|
throw EtaErr("Please provide a callback function, this env doesn't support Promises");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
return handleCache$1(template, options)(data, options);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* Render a template asynchronously
|
|
|
*
|
|
|
* If `template` is a string, Eta will compile it to a function and call it with the provided data.
|
|
|
* If `template` is a function, Eta will call it with the provided data.
|
|
|
*
|
|
|
* If there is a callback function, Eta will call it with `(err, renderedTemplate)`.
|
|
|
* If there is not a callback function, Eta will return a Promise that resolves to the rendered template
|
|
|
*
|
|
|
* @param template Template string or template function
|
|
|
* @param data Data to render the template with
|
|
|
* @param config Optional config options
|
|
|
* @param cb Callback function
|
|
|
*/
|
|
|
function renderAsync(template, data, config, cb) {
|
|
|
// Using Object.assign to lower bundle size, using spread operator makes it larger because of typescript injected polyfills
|
|
|
return render(template, data, Object.assign({}, config, { async: true }), cb);
|
|
|
}
|
|
|
|
|
|
// @denoify-ignore
|
|
|
config.includeFile = includeFileHelper;
|
|
|
config.filepathCache = {};
|
|
|
|
|
|
class Parser {
|
|
|
parse_commands(content, object) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
content = (yield renderAsync(content, object, {
|
|
|
varName: "tp",
|
|
|
parse: {
|
|
|
exec: "*",
|
|
|
interpolate: "~",
|
|
|
raw: "",
|
|
|
},
|
|
|
autoTrim: false,
|
|
|
globalAwait: true,
|
|
|
}));
|
|
|
return content;
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var RunMode;
|
|
|
(function (RunMode) {
|
|
|
RunMode[RunMode["CreateNewFromTemplate"] = 0] = "CreateNewFromTemplate";
|
|
|
RunMode[RunMode["AppendActiveFile"] = 1] = "AppendActiveFile";
|
|
|
RunMode[RunMode["OverwriteFile"] = 2] = "OverwriteFile";
|
|
|
RunMode[RunMode["OverwriteActiveFile"] = 3] = "OverwriteActiveFile";
|
|
|
RunMode[RunMode["DynamicProcessor"] = 4] = "DynamicProcessor";
|
|
|
RunMode[RunMode["StartupTemplate"] = 5] = "StartupTemplate";
|
|
|
})(RunMode || (RunMode = {}));
|
|
|
class Templater {
|
|
|
constructor(app, plugin) {
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
this.functions_generator = new FunctionsGenerator(this.app, this.plugin);
|
|
|
this.editor = new Editor(this.app, this.plugin);
|
|
|
this.parser = new Parser();
|
|
|
this.documentation = new Documentation(this.app);
|
|
|
}
|
|
|
setup() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
yield this.editor.setup();
|
|
|
yield this.functions_generator.init();
|
|
|
this.plugin.registerMarkdownPostProcessor((el, ctx) => this.process_dynamic_templates(el, ctx));
|
|
|
});
|
|
|
}
|
|
|
create_running_config(template_file, target_file, run_mode) {
|
|
|
const active_file = this.app.workspace.getActiveFile();
|
|
|
return {
|
|
|
template_file: template_file,
|
|
|
target_file: target_file,
|
|
|
run_mode: run_mode,
|
|
|
active_file: active_file,
|
|
|
};
|
|
|
}
|
|
|
read_and_parse_template(config) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const template_content = yield this.app.vault.read(config.template_file);
|
|
|
return this.parse_template(config, template_content);
|
|
|
});
|
|
|
}
|
|
|
parse_template(config, template_content) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const functions_object = yield this.functions_generator.generate_object(config, FunctionsMode.USER_INTERNAL);
|
|
|
this.current_functions_object = functions_object;
|
|
|
const content = yield this.parser.parse_commands(template_content, functions_object);
|
|
|
return content;
|
|
|
});
|
|
|
}
|
|
|
jump_to_next_cursor_location(file) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
if (this.plugin.settings.auto_jump_to_cursor &&
|
|
|
this.app.workspace.getActiveFile() === file) {
|
|
|
yield this.editor.jump_to_next_cursor_location();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
create_new_note_from_template(template, folder, filename, open_new_note = true) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
// TODO: Maybe there is an obsidian API function for that
|
|
|
if (!folder) {
|
|
|
// TODO: Fix that
|
|
|
// @ts-ignore
|
|
|
const new_file_location = this.app.vault.getConfig("newFileLocation");
|
|
|
switch (new_file_location) {
|
|
|
case "current": {
|
|
|
const active_file = this.app.workspace.getActiveFile();
|
|
|
if (active_file) {
|
|
|
folder = active_file.parent;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
case "folder":
|
|
|
folder = this.app.fileManager.getNewFileParent("");
|
|
|
break;
|
|
|
case "root":
|
|
|
folder = this.app.vault.getRoot();
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
// TODO: Change that, not stable atm
|
|
|
// @ts-ignore
|
|
|
const created_note = yield this.app.fileManager.createNewMarkdownFile(folder, filename !== null && filename !== void 0 ? filename : "Untitled");
|
|
|
let running_config;
|
|
|
let output_content;
|
|
|
if (template instanceof obsidian_module.TFile) {
|
|
|
running_config = this.create_running_config(template, created_note, RunMode.CreateNewFromTemplate);
|
|
|
output_content = yield errorWrapper(() => __awaiter(this, void 0, void 0, function* () { return this.read_and_parse_template(running_config); }), "Template parsing error, aborting.");
|
|
|
}
|
|
|
else {
|
|
|
running_config = this.create_running_config(undefined, created_note, RunMode.CreateNewFromTemplate);
|
|
|
output_content = yield errorWrapper(() => __awaiter(this, void 0, void 0, function* () { return this.parse_template(running_config, template); }), "Template parsing error, aborting.");
|
|
|
}
|
|
|
if (output_content == null) {
|
|
|
yield this.app.vault.delete(created_note);
|
|
|
return;
|
|
|
}
|
|
|
yield this.app.vault.modify(created_note, output_content);
|
|
|
if (open_new_note) {
|
|
|
const active_leaf = this.app.workspace.activeLeaf;
|
|
|
if (!active_leaf) {
|
|
|
log_error(new TemplaterError("No active leaf"));
|
|
|
return;
|
|
|
}
|
|
|
yield active_leaf.openFile(created_note, {
|
|
|
state: { mode: "source" },
|
|
|
eState: { rename: "all" },
|
|
|
});
|
|
|
yield this.jump_to_next_cursor_location(created_note);
|
|
|
}
|
|
|
return created_note;
|
|
|
});
|
|
|
}
|
|
|
append_template_to_active_file(template_file) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const active_view = this.app.workspace.getActiveViewOfType(obsidian_module.MarkdownView);
|
|
|
if (active_view === null) {
|
|
|
log_error(new TemplaterError("No active view, can't append templates."));
|
|
|
return;
|
|
|
}
|
|
|
const running_config = this.create_running_config(template_file, active_view.file, RunMode.AppendActiveFile);
|
|
|
const output_content = yield errorWrapper(() => __awaiter(this, void 0, void 0, function* () { return this.read_and_parse_template(running_config); }), "Template parsing error, aborting.");
|
|
|
// errorWrapper failed
|
|
|
if (output_content == null) {
|
|
|
return;
|
|
|
}
|
|
|
const editor = active_view.editor;
|
|
|
const doc = editor.getDoc();
|
|
|
doc.replaceSelection(output_content);
|
|
|
yield this.jump_to_next_cursor_location(active_view.file);
|
|
|
});
|
|
|
}
|
|
|
write_template_to_file(template_file, file) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const running_config = this.create_running_config(template_file, file, RunMode.OverwriteFile);
|
|
|
const output_content = yield errorWrapper(() => __awaiter(this, void 0, void 0, function* () { return this.read_and_parse_template(running_config); }), "Template parsing error, aborting.");
|
|
|
// errorWrapper failed
|
|
|
if (output_content == null) {
|
|
|
return;
|
|
|
}
|
|
|
yield this.app.vault.modify(file, output_content);
|
|
|
yield this.jump_to_next_cursor_location(file);
|
|
|
});
|
|
|
}
|
|
|
overwrite_active_file_commands() {
|
|
|
const active_view = this.app.workspace.getActiveViewOfType(obsidian_module.MarkdownView);
|
|
|
if (active_view === null) {
|
|
|
log_error(new TemplaterError("Active view is null, can't overwrite content"));
|
|
|
return;
|
|
|
}
|
|
|
this.overwrite_file_commands(active_view.file, true);
|
|
|
}
|
|
|
overwrite_file_commands(file, active_file = false) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const running_config = this.create_running_config(file, file, active_file ? RunMode.OverwriteActiveFile : RunMode.OverwriteFile);
|
|
|
const output_content = yield errorWrapper(() => __awaiter(this, void 0, void 0, function* () { return this.read_and_parse_template(running_config); }), "Template parsing error, aborting.");
|
|
|
// errorWrapper failed
|
|
|
if (output_content == null) {
|
|
|
return;
|
|
|
}
|
|
|
yield this.app.vault.modify(file, output_content);
|
|
|
yield this.jump_to_next_cursor_location(file);
|
|
|
});
|
|
|
}
|
|
|
process_dynamic_templates(el, ctx) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
const dynamic_command_regex = generate_dynamic_command_regex();
|
|
|
const walker = document.createNodeIterator(el, NodeFilter.SHOW_TEXT);
|
|
|
let node;
|
|
|
let pass = false;
|
|
|
let functions_object;
|
|
|
while ((node = walker.nextNode())) {
|
|
|
let content = node.nodeValue;
|
|
|
let match;
|
|
|
if ((match = dynamic_command_regex.exec(content)) != null) {
|
|
|
const file = this.app.metadataCache.getFirstLinkpathDest("", ctx.sourcePath);
|
|
|
if (!file || !(file instanceof obsidian_module.TFile)) {
|
|
|
return;
|
|
|
}
|
|
|
if (!pass) {
|
|
|
pass = true;
|
|
|
const config = this.create_running_config(file, file, RunMode.DynamicProcessor);
|
|
|
functions_object =
|
|
|
yield this.functions_generator.generate_object(config, FunctionsMode.USER_INTERNAL);
|
|
|
this.current_functions_object = functions_object;
|
|
|
}
|
|
|
while (match != null) {
|
|
|
// Not the most efficient way to exclude the '+' from the command but I couldn't find something better
|
|
|
const complete_command = match[1] + match[2];
|
|
|
const command_output = yield errorWrapper(() => __awaiter(this, void 0, void 0, function* () {
|
|
|
return yield this.parser.parse_commands(complete_command, functions_object);
|
|
|
}), `Command Parsing error in dynamic command '${complete_command}'`);
|
|
|
if (command_output == null) {
|
|
|
return;
|
|
|
}
|
|
|
const start = dynamic_command_regex.lastIndex - match[0].length;
|
|
|
const end = dynamic_command_regex.lastIndex;
|
|
|
content =
|
|
|
content.substring(0, start) +
|
|
|
command_output +
|
|
|
content.substring(end);
|
|
|
dynamic_command_regex.lastIndex +=
|
|
|
command_output.length - match[0].length;
|
|
|
match = dynamic_command_regex.exec(content);
|
|
|
}
|
|
|
node.nodeValue = content;
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
get_new_file_template_for_folder(folder) {
|
|
|
do {
|
|
|
const match = this.plugin.settings.folder_templates.find((e) => e.folder == folder.path);
|
|
|
if (match && match.template) {
|
|
|
return match.template;
|
|
|
}
|
|
|
folder = folder.parent;
|
|
|
} while (folder);
|
|
|
}
|
|
|
static on_file_creation(templater, file) {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
if (!(file instanceof obsidian_module.TFile) || file.extension !== "md") {
|
|
|
return;
|
|
|
}
|
|
|
// Avoids template replacement when syncing template files
|
|
|
const template_folder = obsidian_module.normalizePath(templater.plugin.settings.templates_folder);
|
|
|
if (file.path.includes(template_folder) && template_folder !== "/") {
|
|
|
return;
|
|
|
}
|
|
|
// TODO: find a better way to do this
|
|
|
// Currently, I have to wait for the daily note plugin to add the file content before replacing
|
|
|
// Not a problem with Calendar however since it creates the file with the existing content
|
|
|
yield delay(300);
|
|
|
if (file.stat.size == 0 &&
|
|
|
templater.plugin.settings.enable_folder_templates) {
|
|
|
const folder_template_match = templater.get_new_file_template_for_folder(file.parent);
|
|
|
if (!folder_template_match) {
|
|
|
return;
|
|
|
}
|
|
|
const template_file = yield errorWrapper(() => __awaiter(this, void 0, void 0, function* () {
|
|
|
return resolve_tfile(templater.app, folder_template_match);
|
|
|
}), `Couldn't find template ${folder_template_match}`);
|
|
|
// errorWrapper failed
|
|
|
if (template_file == null) {
|
|
|
return;
|
|
|
}
|
|
|
yield templater.write_template_to_file(template_file, file);
|
|
|
}
|
|
|
else {
|
|
|
yield templater.overwrite_file_commands(file);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
execute_startup_scripts() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
for (const template of this.plugin.settings.startup_templates) {
|
|
|
if (!template) {
|
|
|
continue;
|
|
|
}
|
|
|
const file = errorWrapperSync(() => resolve_tfile(this.app, template), `Couldn't find startup template "${template}"`);
|
|
|
if (!file) {
|
|
|
continue;
|
|
|
}
|
|
|
const running_config = this.create_running_config(file, file, RunMode.StartupTemplate);
|
|
|
yield errorWrapper(() => __awaiter(this, void 0, void 0, function* () { return this.read_and_parse_template(running_config); }), `Startup Template parsing error, aborting.`);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class EventHandler {
|
|
|
constructor(app, plugin, templater, settings) {
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
this.templater = templater;
|
|
|
this.settings = settings;
|
|
|
}
|
|
|
setup() {
|
|
|
this.app.workspace.onLayoutReady(() => {
|
|
|
this.update_trigger_file_on_creation();
|
|
|
});
|
|
|
this.update_syntax_highlighting();
|
|
|
this.update_file_menu();
|
|
|
}
|
|
|
update_syntax_highlighting() {
|
|
|
if (this.plugin.settings.syntax_highlighting) {
|
|
|
this.syntax_highlighting_event = this.app.workspace.on("codemirror", (cm) => {
|
|
|
cm.setOption("mode", "templater");
|
|
|
});
|
|
|
this.app.workspace.iterateCodeMirrors((cm) => {
|
|
|
cm.setOption("mode", "templater");
|
|
|
});
|
|
|
this.plugin.registerEvent(this.syntax_highlighting_event);
|
|
|
}
|
|
|
else {
|
|
|
if (this.syntax_highlighting_event) {
|
|
|
this.app.vault.offref(this.syntax_highlighting_event);
|
|
|
}
|
|
|
this.app.workspace.iterateCodeMirrors((cm) => {
|
|
|
cm.setOption("mode", "hypermd");
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
update_trigger_file_on_creation() {
|
|
|
if (this.settings.trigger_on_file_creation) {
|
|
|
this.trigger_on_file_creation_event = this.app.vault.on("create", (file) => Templater.on_file_creation(this.templater, file));
|
|
|
this.plugin.registerEvent(this.trigger_on_file_creation_event);
|
|
|
}
|
|
|
else {
|
|
|
if (this.trigger_on_file_creation_event) {
|
|
|
this.app.vault.offref(this.trigger_on_file_creation_event);
|
|
|
this.trigger_on_file_creation_event = undefined;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
update_file_menu() {
|
|
|
this.plugin.registerEvent(this.app.workspace.on("file-menu", (menu, file) => {
|
|
|
if (file instanceof obsidian_module.TFolder) {
|
|
|
menu.addItem((item) => {
|
|
|
item.setTitle("Create new note from template")
|
|
|
.setIcon("templater-icon")
|
|
|
.onClick(() => {
|
|
|
this.plugin.fuzzy_suggester.create_new_note_from_template(file);
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
}));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class CommandHandler {
|
|
|
constructor(app, plugin) {
|
|
|
this.app = app;
|
|
|
this.plugin = plugin;
|
|
|
}
|
|
|
setup() {
|
|
|
this.plugin.addCommand({
|
|
|
id: "insert-templater",
|
|
|
name: "Open Insert Template modal",
|
|
|
hotkeys: [
|
|
|
{
|
|
|
modifiers: ["Alt"],
|
|
|
key: "e",
|
|
|
},
|
|
|
],
|
|
|
callback: () => {
|
|
|
this.plugin.fuzzy_suggester.insert_template();
|
|
|
},
|
|
|
});
|
|
|
this.plugin.addCommand({
|
|
|
id: "replace-in-file-templater",
|
|
|
name: "Replace templates in the active file",
|
|
|
hotkeys: [
|
|
|
{
|
|
|
modifiers: ["Alt"],
|
|
|
key: "r",
|
|
|
},
|
|
|
],
|
|
|
callback: () => {
|
|
|
this.plugin.templater.overwrite_active_file_commands();
|
|
|
},
|
|
|
});
|
|
|
this.plugin.addCommand({
|
|
|
id: "jump-to-next-cursor-location",
|
|
|
name: "Jump to next cursor location",
|
|
|
hotkeys: [
|
|
|
{
|
|
|
modifiers: ["Alt"],
|
|
|
key: "Tab",
|
|
|
},
|
|
|
],
|
|
|
callback: () => {
|
|
|
this.plugin.templater.editor.jump_to_next_cursor_location();
|
|
|
},
|
|
|
});
|
|
|
this.plugin.addCommand({
|
|
|
id: "create-new-note-from-template",
|
|
|
name: "Create new note from template",
|
|
|
hotkeys: [
|
|
|
{
|
|
|
modifiers: ["Alt"],
|
|
|
key: "n",
|
|
|
},
|
|
|
],
|
|
|
callback: () => {
|
|
|
this.plugin.fuzzy_suggester.create_new_note_from_template();
|
|
|
},
|
|
|
});
|
|
|
this.register_templates_hotkeys();
|
|
|
}
|
|
|
register_templates_hotkeys() {
|
|
|
this.plugin.settings.enabled_templates_hotkeys.forEach((template) => {
|
|
|
if (template) {
|
|
|
this.add_template_hotkey(null, template);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
add_template_hotkey(old_template, new_template) {
|
|
|
this.remove_template_hotkey(old_template);
|
|
|
if (new_template) {
|
|
|
this.plugin.addCommand({
|
|
|
id: new_template,
|
|
|
name: `Insert ${new_template}`,
|
|
|
callback: () => {
|
|
|
const template = errorWrapperSync(() => resolve_tfile(this.app, new_template), `Couldn't find the template file associated with this hotkey`);
|
|
|
if (!template) {
|
|
|
return;
|
|
|
}
|
|
|
this.plugin.templater.append_template_to_active_file(template);
|
|
|
},
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
remove_template_hotkey(template) {
|
|
|
if (template) {
|
|
|
// TODO: Find official way to do this
|
|
|
// @ts-ignore
|
|
|
this.app.commands.removeCommand(`${this.plugin.manifest.id}:${template}`);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class TemplaterPlugin extends obsidian_module.Plugin {
|
|
|
onload() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
yield this.load_settings();
|
|
|
this.templater = new Templater(this.app, this);
|
|
|
yield this.templater.setup();
|
|
|
this.fuzzy_suggester = new FuzzySuggester(this.app, this);
|
|
|
this.event_handler = new EventHandler(this.app, this, this.templater, this.settings);
|
|
|
this.event_handler.setup();
|
|
|
this.command_handler = new CommandHandler(this.app, this);
|
|
|
this.command_handler.setup();
|
|
|
obsidian_module.addIcon("templater-icon", ICON_DATA);
|
|
|
this.addRibbonIcon("templater-icon", "Templater", () => __awaiter(this, void 0, void 0, function* () {
|
|
|
this.fuzzy_suggester.insert_template();
|
|
|
}));
|
|
|
this.addSettingTab(new TemplaterSettingTab(this.app, this));
|
|
|
// Files might not be created yet
|
|
|
this.app.workspace.onLayoutReady(() => {
|
|
|
this.templater.execute_startup_scripts();
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
save_settings() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
yield this.saveData(this.settings);
|
|
|
});
|
|
|
}
|
|
|
load_settings() {
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
module.exports = TemplaterPlugin;
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNyYy9Mb2cudHMiLCJzcmMvRXJyb3IudHMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2VudW1zLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZU5hbWUuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRXaW5kb3cuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9pbnN0YW5jZU9mLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvYXBwbHlTdHlsZXMuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL21hdGguanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvY29udGFpbnMuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDb21wdXRlZFN0eWxlLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNUYWJsZUVsZW1lbnQuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXREb2N1bWVudEVsZW1lbnQuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRQYXJlbnROb2RlLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL3dpdGhpbi5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0RnJlc2hTaWRlT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9tZXJnZVBhZGRpbmdPYmplY3QuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2V4cGFuZFRvSGFzaE1hcC5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2Fycm93LmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRWYXJpYXRpb24uanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9jb21wdXRlU3R5bGVzLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldE9wcG9zaXRlUGxhY2VtZW50LmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudC5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFdpbmRvd1Njcm9sbC5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFdpbmRvd1Njcm9sbEJhclguanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRWaWV3cG9ydFJlY3QuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXREb2N1bWVudFJlY3QuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9pc1Njcm9sbFBhcmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFNjcm9sbFBhcmVudC5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2xpc3RTY3JvbGxQYXJlbnRzLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9yZWN0VG9DbGllbnRSZWN0LmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Q2xpcHBpbmdSZWN0LmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9jb21wdXRlT2Zmc2V0cy5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZGV0ZWN0T3ZlcmZsb3cuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2NvbXB1dGVBdXRvUGxhY2VtZW50LmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZmxpcC5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2hpZGUuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9vZmZzZXQuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRBbHRBeGlzLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvcHJldmVudE92ZXJmbG93LmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXROb2RlU2Nyb2xsLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Q29tcG9zaXRlUmVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvb3JkZXJNb2RpZmllcnMuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2RlYm91bmNlLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9mb3JtYXQuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL3ZhbGlkYXRlTW9kaWZpZXJzLmpzIiwibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy91bmlxdWVCeS5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWVyZ2VCeU5hbWUuanMiLCJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2NyZWF0ZVBvcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvcG9wcGVyLmpzIiwic3JjL3N1Z2dlc3RlcnMvc3VnZ2VzdC50cyIsInNyYy9zdWdnZXN0ZXJzL0ZvbGRlclN1Z2dlc3Rlci50cyIsInNyYy9VdGlscy50cyIsInNyYy9zdWdnZXN0ZXJzL0ZpbGVTdWdnZXN0ZXIudHMiLCJzcmMvU2V0dGluZ3MudHMiLCJzcmMvRnV6enlTdWdnZXN0ZXIudHMiLCJzcmMvQ29uc3RhbnRzLnRzIiwic3JjL2Z1bmN0aW9ucy9pbnRlcm5hbF9mdW5jdGlvbnMvSW50ZXJuYWxNb2R1bGUudHMiLCJzcmMvZnVuY3Rpb25zL2ludGVybmFsX2Z1bmN0aW9ucy9kYXRlL0ludGVybmFsTW9kdWxlRGF0ZS50cyIsInNyYy9mdW5jdGlvbnMvaW50ZXJuYWxfZnVuY3Rpb25zL2ZpbGUvSW50ZXJuYWxNb2R1bGVGaWxlLnRzIiwic3JjL2Z1bmN0aW9ucy9pbnRlcm5hbF9mdW5jdGlvbnMvd2ViL0ludGVybmFsTW9kdWxlV2ViLnRzIiwic3JjL2Z1bmN0aW9ucy9pbnRlcm5hbF9mdW5jdGlvbnMvZnJvbnRtYXR0ZXIvSW50ZXJuYWxNb2R1bGVGcm9udG1hdHRlci50cyIsInNyYy9mdW5jdGlvbnMvaW50ZXJuYWxfZnVuY3Rpb25zL3N5c3RlbS9Qcm9tcHRNb2RhbC50cyIsInNyYy9mdW5jdGlvbnMvaW50ZXJuYWxfZnVuY3Rpb25zL3N5c3RlbS9TdWdnZXN0ZXJNb2RhbC50cyIsInNyYy9mdW5jdGlvbnMvaW50ZXJuYWxfZnVuY3Rpb25zL3N5c3RlbS9JbnRlcm5hbE1vZHVsZVN5c3RlbS50cyIsInNyYy9mdW5jdGlvbnMvaW50ZXJuYWxfZnVuY3Rpb25zL2NvbmZpZy9JbnRlcm5hbE1vZHVsZUNvbmZpZy50cyIsInNyYy9mdW5jdGlvbnMvaW50ZXJuYWxfZnVuY3Rpb25zL0ludGVybmFsRnVuY3Rpb25zLnRzIiwic3JjL2Z1bmN0aW9ucy91c2VyX2Z1bmN0aW9ucy9Vc2VyU3lzdGVtRnVuY3Rpb25zLnRzIiwic3JjL2Z1bmN0aW9ucy91c2VyX2Z1bmN0aW9ucy9Vc2VyU2NyaXB0RnVuY3Rpb25zLnRzIiwic3JjL2Z1bmN0aW9ucy91c2VyX2Z1bmN0aW9ucy9Vc2VyRnVuY3Rpb25zLnRzIiwic3JjL2Z1bmN0aW9ucy9GdW5jdGlvbnNHZW5lcmF0b3IudHMiLCJzcmMvZWRpdG9yL0N1cnNvckp1bXBlci50cyIsInNyYy9mdW5jdGlvbnMvVHBEb2N1bWVudGF0aW9uLnRzIiwic3JjL2VkaXRvci9BdXRvY29tcGxldGUudHMiLCJzcmMvZWRpdG9yL21vZGUvamF2YXNjcmlwdC5qcyIsInNyYy9lZGl0b3IvbW9kZS9jdXN0b21fb3ZlcmxheS5qcyIsInNyYy9lZGl0b3IvRWRpdG9yLnRzIiwibm9kZV9tb2R1bGVzL2V0YS9kaXN0L2V0YS5lcy5qcyIsInNyYy9wYXJzZXIvUGFyc2VyLnRzIiwic3JjL1RlbXBsYXRlci50cyIsInNyYy9FdmVudEhhbmRsZXIudHMiLCJzcmMvQ29tbWFuZEhhbmRsZXIudHMiLCJzcmMvbWFpbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgaWYgKHR5cGVvZiBiICE9PSBcImZ1bmN0aW9uXCIgJiYgYiAhPT0gbnVsbClcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSBcIiArIFN0cmluZyhiKSArIFwiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGxcIik7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxyXG4gICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICAgICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH0pO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcbiIsImltcG9ydCB7IE5vdGljZSB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgVGVtcGxhdGVyRXJyb3IgfSBmcm9tIFwiRXJyb3JcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGxvZ191cGRhdGUobXNnOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBub3RpY2UgPSBuZXcgTm90aWNlKFwiXCIsIDE1MDAwKTtcbiAgICAvLyBUT0RPOiBGaW5kIGJldHRlciB3YXkgZm9yIHRoaXNcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgbm90aWNlLm5vdGljZUVsLmlubmVySFRNTCA9IGA8Yj5UZW1wbGF0ZXIgdXBkYXRlPC9iPjo8YnIvPiR7bXNnfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2dfZXJyb3IoZTogRXJyb3IgfCBUZW1wbGF0ZXJFcnJvcik6IHZvaWQge1xuICAgIGNvbnN0IG5vdGljZSA9IG5ldyBOb3RpY2UoXCJcIiwgODAwMCk7XG4gICAgaWYgKGUgaW5zdGFuY2VvZiBUZW1wbGF0ZXJFcnJvciAmJiBlLmNvbnNvbGVfbXNnKSB7XG4gICAgICAgIC8vIFRPRE86IEZpbmQgYSBiZXR0ZXIgd2F5IGZvciB0aGlzXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgbm90aWNlLm5vdGljZUVsLmlubmVySFRNTCA9IGA8Yj5UZW1wbGF0ZXIgRXJyb3I8L2I+Ojxici8+JHtlLm1lc3NhZ2V9PGJyLz5DaGVjayBjb25zb2xlIGZvciBtb3JlIGluZm9ybWF0aW9uc2A7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFRlbXBsYXRlciBFcnJvcjpgLCBlLm1lc3NhZ2UsIFwiXFxuXCIsIGUuY29uc29sZV9tc2cpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgbm90aWNlLm5vdGljZUVsLmlubmVySFRNTCA9IGA8Yj5UZW1wbGF0ZXIgRXJyb3I8L2I+Ojxici8+JHtlLm1lc3NhZ2V9YDtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBsb2dfZXJyb3IgfSBmcm9tIFwiTG9nXCI7XG5cbmV4cG9ydCBjbGFzcyBUZW1wbGF0ZXJFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZywgcHVibGljIGNvbnNvbGVfbXNnPzogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKG1zZyk7XG4gICAgICAgIHRoaXMubmFtZSA9IHRoaXMuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7XG4gICAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXJyb3JXcmFwcGVyPFQ+KFxuICAgIGZuOiAoKSA9PiBQcm9taXNlPFQ+LFxuICAgIG1zZzogc3RyaW5nXG4pOiBQcm9taXNlPFQ+IHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgZm4oKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBUZW1wbGF0ZXJFcnJvcikpIHtcbiAgICAgICAgICAgIGxvZ19lcnJvcihuZXcgVGVtcGxhdGVyRXJyb3IobXNnLCBlLm1lc3NhZ2UpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ19lcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlcnJvcldyYXBwZXJTeW5jPFQ+KGZuOiAoKSA9PiBULCBtc2c6IHN0cmluZyk6IFQge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBmbigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbG9nX2Vycm9yKG5ldyBUZW1wbGF0ZXJFcnJvcihtc2csIGUubWVzc2FnZSkpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59XG4iLCJleHBvcnQgdmFyIHRvcCA9ICd0b3AnO1xuZXhwb3J0IHZhciBib3R0b20gPSAnYm90dG9tJztcbmV4cG9ydCB2YXIgcmlnaHQgPSAncmlnaHQnO1xuZXhwb3J0IHZhciBsZWZ0ID0gJ2xlZnQnO1xuZXhwb3J0IHZhciBhdXRvID0gJ2F1dG8nO1xuZXhwb3J0IHZhciBiYXNlUGxhY2VtZW50cyA9IFt0b3AsIGJvdHRvbSwgcmlnaHQsIGxlZnRdO1xuZXhwb3J0IHZhciBzdGFydCA9ICdzdGFydCc7XG5leHBvcnQgdmFyIGVuZCA9ICdlbmQnO1xuZXhwb3J0IHZhciBjbGlwcGluZ1BhcmVudHMgPSAnY2xpcHBpbmdQYXJlbnRzJztcbmV4cG9ydCB2YXIgdmlld3BvcnQgPSAndmlld3BvcnQnO1xuZXhwb3J0IHZhciBwb3BwZXIgPSAncG9wcGVyJztcbmV4cG9ydCB2YXIgcmVmZXJlbmNlID0gJ3JlZmVyZW5jZSc7XG5leHBvcnQgdmFyIHZhcmlhdGlvblBsYWNlbWVudHMgPSAvKiNfX1BVUkVfXyovYmFzZVBsYWNlbWVudHMucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICByZXR1cm4gYWNjLmNvbmNhdChbcGxhY2VtZW50ICsgXCItXCIgKyBzdGFydCwgcGxhY2VtZW50ICsgXCItXCIgKyBlbmRdKTtcbn0sIFtdKTtcbmV4cG9ydCB2YXIgcGxhY2VtZW50cyA9IC8qI19fUFVSRV9fKi9bXS5jb25jYXQoYmFzZVBsYWNlbWVudHMsIFthdXRvXSkucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICByZXR1cm4gYWNjLmNvbmNhdChbcGxhY2VtZW50LCBwbGFjZW1lbnQgKyBcIi1cIiArIHN0YXJ0LCBwbGFjZW1lbnQgKyBcIi1cIiArIGVuZF0pO1xufSwgW10pOyAvLyBtb2RpZmllcnMgdGhhdCBuZWVkIHRvIHJlYWQgdGhlIERPTVxuXG5leHBvcnQgdmFyIGJlZm9yZVJlYWQgPSAnYmVmb3JlUmVhZCc7XG5leHBvcnQgdmFyIHJlYWQgPSAncmVhZCc7XG5leHBvcnQgdmFyIGFmdGVyUmVhZCA9ICdhZnRlclJlYWQnOyAvLyBwdXJlLWxvZ2ljIG1vZGlmaWVyc1xuXG5leHBvcnQgdmFyIGJlZm9yZU1haW4gPSAnYmVmb3JlTWFpbic7XG5leHBvcnQgdmFyIG1haW4gPSAnbWFpbic7XG5leHBvcnQgdmFyIGFmdGVyTWFpbiA9ICdhZnRlck1haW4nOyAvLyBtb2RpZmllciB3aXRoIHRoZSBwdXJwb3NlIHRvIHdyaXRlIHRvIHRoZSBET00gKG9yIHdyaXRlIGludG8gYSBmcmFtZXdvcmsgc3RhdGUpXG5cbmV4cG9ydCB2YXIgYmVmb3JlV3JpdGUgPSAnYmVmb3JlV3JpdGUnO1xuZXhwb3J0IHZhciB3cml0ZSA9ICd3cml0ZSc7XG5leHBvcnQgdmFyIGFmdGVyV3JpdGUgPSAnYWZ0ZXJXcml0ZSc7XG5leHBvcnQgdmFyIG1vZGlmaWVyUGhhc2VzID0gW2JlZm9yZVJlYWQsIHJlYWQsIGFmdGVyUmVhZCwgYmVmb3JlTWFpbiwgbWFpbiwgYWZ0ZXJNYWluLCBiZWZvcmVXcml0ZSwgd3JpdGUsIGFmdGVyV3JpdGVdOyIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE5vZGVOYW1lKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQgPyAoZWxlbWVudC5ub2RlTmFtZSB8fCAnJykudG9Mb3dlckNhc2UoKSA6IG51bGw7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHtcbiAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgIHJldHVybiB3aW5kb3c7XG4gIH1cblxuICBpZiAobm9kZS50b1N0cmluZygpICE9PSAnW29iamVjdCBXaW5kb3ddJykge1xuICAgIHZhciBvd25lckRvY3VtZW50ID0gbm9kZS5vd25lckRvY3VtZW50O1xuICAgIHJldHVybiBvd25lckRvY3VtZW50ID8gb3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3cgOiB3aW5kb3c7XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn0iLCJpbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuL2dldFdpbmRvdy5qc1wiO1xuXG5mdW5jdGlvbiBpc0VsZW1lbnQobm9kZSkge1xuICB2YXIgT3duRWxlbWVudCA9IGdldFdpbmRvdyhub2RlKS5FbGVtZW50O1xuICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIE93bkVsZW1lbnQgfHwgbm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGlzSFRNTEVsZW1lbnQobm9kZSkge1xuICB2YXIgT3duRWxlbWVudCA9IGdldFdpbmRvdyhub2RlKS5IVE1MRWxlbWVudDtcbiAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBPd25FbGVtZW50IHx8IG5vZGUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudDtcbn1cblxuZnVuY3Rpb24gaXNTaGFkb3dSb290KG5vZGUpIHtcbiAgLy8gSUUgMTEgaGFzIG5vIFNoYWRvd1Jvb3RcbiAgaWYgKHR5cGVvZiBTaGFkb3dSb290ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBPd25FbGVtZW50ID0gZ2V0V2luZG93KG5vZGUpLlNoYWRvd1Jvb3Q7XG4gIHJldHVybiBub2RlIGluc3RhbmNlb2YgT3duRWxlbWVudCB8fCBub2RlIGluc3RhbmNlb2YgU2hhZG93Um9vdDtcbn1cblxuZXhwb3J0IHsgaXNFbGVtZW50LCBpc0hUTUxFbGVtZW50LCBpc1NoYWRvd1Jvb3QgfTsiLCJpbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4uL2RvbS11dGlscy9nZXROb2RlTmFtZS5qc1wiO1xuaW1wb3J0IHsgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuLi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qc1wiOyAvLyBUaGlzIG1vZGlmaWVyIHRha2VzIHRoZSBzdHlsZXMgcHJlcGFyZWQgYnkgdGhlIGBjb21wdXRlU3R5bGVzYCBtb2RpZmllclxuLy8gYW5kIGFwcGxpZXMgdGhlbSB0byB0aGUgSFRNTEVsZW1lbnRzIHN1Y2ggYXMgcG9wcGVyIGFuZCBhcnJvd1xuXG5mdW5jdGlvbiBhcHBseVN0eWxlcyhfcmVmKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYuc3RhdGU7XG4gIE9iamVjdC5rZXlzKHN0YXRlLmVsZW1lbnRzKS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdmFyIHN0eWxlID0gc3RhdGUuc3R5bGVzW25hbWVdIHx8IHt9O1xuICAgIHZhciBhdHRyaWJ1dGVzID0gc3RhdGUuYXR0cmlidXRlc1tuYW1lXSB8fCB7fTtcbiAgICB2YXIgZWxlbWVudCA9IHN0YXRlLmVsZW1lbnRzW25hbWVdOyAvLyBhcnJvdyBpcyBvcHRpb25hbCArIHZpcnR1YWwgZWxlbWVudHNcblxuICAgIGlmICghaXNIVE1MRWxlbWVudChlbGVtZW50KSB8fCAhZ2V0Tm9kZU5hbWUoZWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIEZsb3cgZG9lc24ndCBzdXBwb3J0IHRvIGV4dGVuZCB0aGlzIHByb3BlcnR5LCBidXQgaXQncyB0aGUgbW9zdFxuICAgIC8vIGVmZmVjdGl2ZSB3YXkgdG8gYXBwbHkgc3R5bGVzIHRvIGFuIEhUTUxFbGVtZW50XG4gICAgLy8gJEZsb3dGaXhNZVtjYW5ub3Qtd3JpdGVdXG5cblxuICAgIE9iamVjdC5hc3NpZ24oZWxlbWVudC5zdHlsZSwgc3R5bGUpO1xuICAgIE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGF0dHJpYnV0ZXNbbmFtZV07XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSA9PT0gdHJ1ZSA/ICcnIDogdmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZWZmZWN0KF9yZWYyKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYyLnN0YXRlO1xuICB2YXIgaW5pdGlhbFN0eWxlcyA9IHtcbiAgICBwb3BwZXI6IHtcbiAgICAgIHBvc2l0aW9uOiBzdGF0ZS5vcHRpb25zLnN0cmF0ZWd5LFxuICAgICAgbGVmdDogJzAnLFxuICAgICAgdG9wOiAnMCcsXG4gICAgICBtYXJnaW46ICcwJ1xuICAgIH0sXG4gICAgYXJyb3c6IHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXG4gICAgfSxcbiAgICByZWZlcmVuY2U6IHt9XG4gIH07XG4gIE9iamVjdC5hc3NpZ24oc3RhdGUuZWxlbWVudHMucG9wcGVyLnN0eWxlLCBpbml0aWFsU3R5bGVzLnBvcHBlcik7XG4gIHN0YXRlLnN0eWxlcyA9IGluaXRpYWxTdHlsZXM7XG5cbiAgaWYgKHN0YXRlLmVsZW1lbnRzLmFycm93KSB7XG4gICAgT2JqZWN0LmFzc2lnbihzdGF0ZS5lbGVtZW50cy5hcnJvdy5zdHlsZSwgaW5pdGlhbFN0eWxlcy5hcnJvdyk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIE9iamVjdC5rZXlzKHN0YXRlLmVsZW1lbnRzKS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IHN0YXRlLmVsZW1lbnRzW25hbWVdO1xuICAgICAgdmFyIGF0dHJpYnV0ZXMgPSBzdGF0ZS5hdHRyaWJ1dGVzW25hbWVdIHx8IHt9O1xuICAgICAgdmFyIHN0eWxlUHJvcGVydGllcyA9IE9iamVjdC5rZXlzKHN0YXRlLnN0eWxlcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSA/IHN0YXRlLnN0eWxlc1tuYW1lXSA6IGluaXRpYWxTdHlsZXNbbmFtZV0pOyAvLyBTZXQgYWxsIHZhbHVlcyB0byBhbiBlbXB0eSBzdHJpbmcgdG8gdW5zZXQgdGhlbVxuXG4gICAgICB2YXIgc3R5bGUgPSBzdHlsZVByb3BlcnRpZXMucmVkdWNlKGZ1bmN0aW9uIChzdHlsZSwgcHJvcGVydHkpIHtcbiAgICAgICAgc3R5bGVbcHJvcGVydHldID0gJyc7XG4gICAgICAgIHJldHVybiBzdHlsZTtcbiAgICAgIH0sIHt9KTsgLy8gYXJyb3cgaXMgb3B0aW9uYWwgKyB2aXJ0dWFsIGVsZW1lbnRzXG5cbiAgICAgIGlmICghaXNIVE1MRWxlbWVudChlbGVtZW50KSB8fCAhZ2V0Tm9kZU5hbWUoZWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBPYmplY3QuYXNzaWduKGVsZW1lbnQuc3R5bGUsIHN0eWxlKTtcbiAgICAgIE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZSkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShhdHRyaWJ1dGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdhcHBseVN0eWxlcycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnd3JpdGUnLFxuICBmbjogYXBwbHlTdHlsZXMsXG4gIGVmZmVjdDogZWZmZWN0LFxuICByZXF1aXJlczogWydjb21wdXRlU3R5bGVzJ11cbn07IiwiaW1wb3J0IHsgYXV0byB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5zcGxpdCgnLScpWzBdO1xufSIsImV4cG9ydCB2YXIgbWF4ID0gTWF0aC5tYXg7XG5leHBvcnQgdmFyIG1pbiA9IE1hdGgubWluO1xuZXhwb3J0IHZhciByb3VuZCA9IE1hdGgucm91bmQ7IiwiaW1wb3J0IHsgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEJvdW5kaW5nQ2xpZW50UmVjdChlbGVtZW50LCBpbmNsdWRlU2NhbGUpIHtcbiAgaWYgKGluY2x1ZGVTY2FsZSA9PT0gdm9pZCAwKSB7XG4gICAgaW5jbHVkZVNjYWxlID0gZmFsc2U7XG4gIH1cblxuICB2YXIgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIHZhciBzY2FsZVggPSAxO1xuICB2YXIgc2NhbGVZID0gMTtcblxuICBpZiAoaXNIVE1MRWxlbWVudChlbGVtZW50KSAmJiBpbmNsdWRlU2NhbGUpIHtcbiAgICB2YXIgb2Zmc2V0SGVpZ2h0ID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gICAgdmFyIG9mZnNldFdpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aDsgLy8gRG8gbm90IGF0dGVtcHQgdG8gZGl2aWRlIGJ5IDAsIG90aGVyd2lzZSB3ZSBnZXQgYEluZmluaXR5YCBhcyBzY2FsZVxuICAgIC8vIEZhbGxiYWNrIHRvIDEgaW4gY2FzZSBib3RoIHZhbHVlcyBhcmUgYDBgXG5cbiAgICBpZiAob2Zmc2V0V2lkdGggPiAwKSB7XG4gICAgICBzY2FsZVggPSByb3VuZChyZWN0LndpZHRoKSAvIG9mZnNldFdpZHRoIHx8IDE7XG4gICAgfVxuXG4gICAgaWYgKG9mZnNldEhlaWdodCA+IDApIHtcbiAgICAgIHNjYWxlWSA9IHJvdW5kKHJlY3QuaGVpZ2h0KSAvIG9mZnNldEhlaWdodCB8fCAxO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHJlY3Qud2lkdGggLyBzY2FsZVgsXG4gICAgaGVpZ2h0OiByZWN0LmhlaWdodCAvIHNjYWxlWSxcbiAgICB0b3A6IHJlY3QudG9wIC8gc2NhbGVZLFxuICAgIHJpZ2h0OiByZWN0LnJpZ2h0IC8gc2NhbGVYLFxuICAgIGJvdHRvbTogcmVjdC5ib3R0b20gLyBzY2FsZVksXG4gICAgbGVmdDogcmVjdC5sZWZ0IC8gc2NhbGVYLFxuICAgIHg6IHJlY3QubGVmdCAvIHNjYWxlWCxcbiAgICB5OiByZWN0LnRvcCAvIHNjYWxlWVxuICB9O1xufSIsImltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4vZ2V0Qm91bmRpbmdDbGllbnRSZWN0LmpzXCI7IC8vIFJldHVybnMgdGhlIGxheW91dCByZWN0IG9mIGFuIGVsZW1lbnQgcmVsYXRpdmUgdG8gaXRzIG9mZnNldFBhcmVudC4gTGF5b3V0XG4vLyBtZWFucyBpdCBkb2Vzbid0IHRha2UgaW50byBhY2NvdW50IHRyYW5zZm9ybXMuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldExheW91dFJlY3QoZWxlbWVudCkge1xuICB2YXIgY2xpZW50UmVjdCA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChlbGVtZW50KTsgLy8gVXNlIHRoZSBjbGllbnRSZWN0IHNpemVzIGlmIGl0J3Mgbm90IGJlZW4gdHJhbnNmb3JtZWQuXG4gIC8vIEZpeGVzIGh0dHBzOi8vZ2l0aHViLmNvbS9wb3BwZXJqcy9wb3BwZXItY29yZS9pc3N1ZXMvMTIyM1xuXG4gIHZhciB3aWR0aCA9IGVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gIHZhciBoZWlnaHQgPSBlbGVtZW50Lm9mZnNldEhlaWdodDtcblxuICBpZiAoTWF0aC5hYnMoY2xpZW50UmVjdC53aWR0aCAtIHdpZHRoKSA8PSAxKSB7XG4gICAgd2lkdGggPSBjbGllbnRSZWN0LndpZHRoO1xuICB9XG5cbiAgaWYgKE1hdGguYWJzKGNsaWVudFJlY3QuaGVpZ2h0IC0gaGVpZ2h0KSA8PSAxKSB7XG4gICAgaGVpZ2h0ID0gY2xpZW50UmVjdC5oZWlnaHQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHg6IGVsZW1lbnQub2Zmc2V0TGVmdCxcbiAgICB5OiBlbGVtZW50Lm9mZnNldFRvcCxcbiAgICB3aWR0aDogd2lkdGgsXG4gICAgaGVpZ2h0OiBoZWlnaHRcbiAgfTtcbn0iLCJpbXBvcnQgeyBpc1NoYWRvd1Jvb3QgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb250YWlucyhwYXJlbnQsIGNoaWxkKSB7XG4gIHZhciByb290Tm9kZSA9IGNoaWxkLmdldFJvb3ROb2RlICYmIGNoaWxkLmdldFJvb3ROb2RlKCk7IC8vIEZpcnN0LCBhdHRlbXB0IHdpdGggZmFzdGVyIG5hdGl2ZSBtZXRob2RcblxuICBpZiAocGFyZW50LmNvbnRhaW5zKGNoaWxkKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIHRoZW4gZmFsbGJhY2sgdG8gY3VzdG9tIGltcGxlbWVudGF0aW9uIHdpdGggU2hhZG93IERPTSBzdXBwb3J0XG4gIGVsc2UgaWYgKHJvb3ROb2RlICYmIGlzU2hhZG93Um9vdChyb290Tm9kZSkpIHtcbiAgICAgIHZhciBuZXh0ID0gY2hpbGQ7XG5cbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKG5leHQgJiYgcGFyZW50LmlzU2FtZU5vZGUobmV4dCkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ106IG5lZWQgYSBiZXR0ZXIgd2F5IHRvIGhhbmRsZSB0aGlzLi4uXG5cblxuICAgICAgICBuZXh0ID0gbmV4dC5wYXJlbnROb2RlIHx8IG5leHQuaG9zdDtcbiAgICAgIH0gd2hpbGUgKG5leHQpO1xuICAgIH0gLy8gR2l2ZSB1cCwgdGhlIHJlc3VsdCBpcyBmYWxzZVxuXG5cbiAgcmV0dXJuIGZhbHNlO1xufSIsImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFdpbmRvdyhlbGVtZW50KS5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xufSIsImltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi9nZXROb2RlTmFtZS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaXNUYWJsZUVsZW1lbnQoZWxlbWVudCkge1xuICByZXR1cm4gWyd0YWJsZScsICd0ZCcsICd0aCddLmluZGV4T2YoZ2V0Tm9kZU5hbWUoZWxlbWVudCkpID49IDA7XG59IiwiaW1wb3J0IHsgaXNFbGVtZW50IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RG9jdW1lbnRFbGVtZW50KGVsZW1lbnQpIHtcbiAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtcmV0dXJuXTogYXNzdW1lIGJvZHkgaXMgYWx3YXlzIGF2YWlsYWJsZVxuICByZXR1cm4gKChpc0VsZW1lbnQoZWxlbWVudCkgPyBlbGVtZW50Lm93bmVyRG9jdW1lbnQgOiAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgZWxlbWVudC5kb2N1bWVudCkgfHwgd2luZG93LmRvY3VtZW50KS5kb2N1bWVudEVsZW1lbnQ7XG59IiwiaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IHsgaXNTaGFkb3dSb290IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0UGFyZW50Tm9kZShlbGVtZW50KSB7XG4gIGlmIChnZXROb2RlTmFtZShlbGVtZW50KSA9PT0gJ2h0bWwnKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICByZXR1cm4gKC8vIHRoaXMgaXMgYSBxdWlja2VyIChidXQgbGVzcyB0eXBlIHNhZmUpIHdheSB0byBzYXZlIHF1aXRlIHNvbWUgYnl0ZXMgZnJvbSB0aGUgYnVuZGxlXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtcmV0dXJuXVxuICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgIGVsZW1lbnQuYXNzaWduZWRTbG90IHx8IC8vIHN0ZXAgaW50byB0aGUgc2hhZG93IERPTSBvZiB0aGUgcGFyZW50IG9mIGEgc2xvdHRlZCBub2RlXG4gICAgZWxlbWVudC5wYXJlbnROb2RlIHx8ICggLy8gRE9NIEVsZW1lbnQgZGV0ZWN0ZWRcbiAgICBpc1NoYWRvd1Jvb3QoZWxlbWVudCkgPyBlbGVtZW50Lmhvc3QgOiBudWxsKSB8fCAvLyBTaGFkb3dSb290IGRldGVjdGVkXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF06IEhUTUxFbGVtZW50IGlzIGEgTm9kZVxuICAgIGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KSAvLyBmYWxsYmFja1xuXG4gICk7XG59IiwiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi9nZXROb2RlTmFtZS5qc1wiO1xuaW1wb3J0IGdldENvbXB1dGVkU3R5bGUgZnJvbSBcIi4vZ2V0Q29tcHV0ZWRTdHlsZS5qc1wiO1xuaW1wb3J0IHsgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBpc1RhYmxlRWxlbWVudCBmcm9tIFwiLi9pc1RhYmxlRWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuXG5mdW5jdGlvbiBnZXRUcnVlT2Zmc2V0UGFyZW50KGVsZW1lbnQpIHtcbiAgaWYgKCFpc0hUTUxFbGVtZW50KGVsZW1lbnQpIHx8IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wb3BwZXJqcy9wb3BwZXItY29yZS9pc3N1ZXMvODM3XG4gIGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkucG9zaXRpb24gPT09ICdmaXhlZCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50Lm9mZnNldFBhcmVudDtcbn0gLy8gYC5vZmZzZXRQYXJlbnRgIHJlcG9ydHMgYG51bGxgIGZvciBmaXhlZCBlbGVtZW50cywgd2hpbGUgYWJzb2x1dGUgZWxlbWVudHNcbi8vIHJldHVybiB0aGUgY29udGFpbmluZyBibG9ja1xuXG5cbmZ1bmN0aW9uIGdldENvbnRhaW5pbmdCbG9jayhlbGVtZW50KSB7XG4gIHZhciBpc0ZpcmVmb3ggPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkuaW5kZXhPZignZmlyZWZveCcpICE9PSAtMTtcbiAgdmFyIGlzSUUgPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ1RyaWRlbnQnKSAhPT0gLTE7XG5cbiAgaWYgKGlzSUUgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSkge1xuICAgIC8vIEluIElFIDksIDEwIGFuZCAxMSBmaXhlZCBlbGVtZW50cyBjb250YWluaW5nIGJsb2NrIGlzIGFsd2F5cyBlc3RhYmxpc2hlZCBieSB0aGUgdmlld3BvcnRcbiAgICB2YXIgZWxlbWVudENzcyA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG5cbiAgICBpZiAoZWxlbWVudENzcy5wb3NpdGlvbiA9PT0gJ2ZpeGVkJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgdmFyIGN1cnJlbnROb2RlID0gZ2V0UGFyZW50Tm9kZShlbGVtZW50KTtcblxuICB3aGlsZSAoaXNIVE1MRWxlbWVudChjdXJyZW50Tm9kZSkgJiYgWydodG1sJywgJ2JvZHknXS5pbmRleE9mKGdldE5vZGVOYW1lKGN1cnJlbnROb2RlKSkgPCAwKSB7XG4gICAgdmFyIGNzcyA9IGdldENvbXB1dGVkU3R5bGUoY3VycmVudE5vZGUpOyAvLyBUaGlzIGlzIG5vbi1leGhhdXN0aXZlIGJ1dCBjb3ZlcnMgdGhlIG1vc3QgY29tbW9uIENTUyBwcm9wZXJ0aWVzIHRoYXRcbiAgICAvLyBjcmVhdGUgYSBjb250YWluaW5nIGJsb2NrLlxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9Db250YWluaW5nX2Jsb2NrI2lkZW50aWZ5aW5nX3RoZV9jb250YWluaW5nX2Jsb2NrXG5cbiAgICBpZiAoY3NzLnRyYW5zZm9ybSAhPT0gJ25vbmUnIHx8IGNzcy5wZXJzcGVjdGl2ZSAhPT0gJ25vbmUnIHx8IGNzcy5jb250YWluID09PSAncGFpbnQnIHx8IFsndHJhbnNmb3JtJywgJ3BlcnNwZWN0aXZlJ10uaW5kZXhPZihjc3Mud2lsbENoYW5nZSkgIT09IC0xIHx8IGlzRmlyZWZveCAmJiBjc3Mud2lsbENoYW5nZSA9PT0gJ2ZpbHRlcicgfHwgaXNGaXJlZm94ICYmIGNzcy5maWx0ZXIgJiYgY3NzLmZpbHRlciAhPT0gJ25vbmUnKSB7XG4gICAgICByZXR1cm4gY3VycmVudE5vZGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUucGFyZW50Tm9kZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn0gLy8gR2V0cyB0aGUgY2xvc2VzdCBhbmNlc3RvciBwb3NpdGlvbmVkIGVsZW1lbnQuIEhhbmRsZXMgc29tZSBlZGdlIGNhc2VzLFxuLy8gc3VjaCBhcyB0YWJsZSBhbmNlc3RvcnMgYW5kIGNyb3NzIGJyb3dzZXIgYnVncy5cblxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRPZmZzZXRQYXJlbnQoZWxlbWVudCkge1xuICB2YXIgd2luZG93ID0gZ2V0V2luZG93KGVsZW1lbnQpO1xuICB2YXIgb2Zmc2V0UGFyZW50ID0gZ2V0VHJ1ZU9mZnNldFBhcmVudChlbGVtZW50KTtcblxuICB3aGlsZSAob2Zmc2V0UGFyZW50ICYmIGlzVGFibGVFbGVtZW50KG9mZnNldFBhcmVudCkgJiYgZ2V0Q29tcHV0ZWRTdHlsZShvZmZzZXRQYXJlbnQpLnBvc2l0aW9uID09PSAnc3RhdGljJykge1xuICAgIG9mZnNldFBhcmVudCA9IGdldFRydWVPZmZzZXRQYXJlbnQob2Zmc2V0UGFyZW50KTtcbiAgfVxuXG4gIGlmIChvZmZzZXRQYXJlbnQgJiYgKGdldE5vZGVOYW1lKG9mZnNldFBhcmVudCkgPT09ICdodG1sJyB8fCBnZXROb2RlTmFtZShvZmZzZXRQYXJlbnQpID09PSAnYm9keScgJiYgZ2V0Q29tcHV0ZWRTdHlsZShvZmZzZXRQYXJlbnQpLnBvc2l0aW9uID09PSAnc3RhdGljJykpIHtcbiAgICByZXR1cm4gd2luZG93O1xuICB9XG5cbiAgcmV0dXJuIG9mZnNldFBhcmVudCB8fCBnZXRDb250YWluaW5nQmxvY2soZWxlbWVudCkgfHwgd2luZG93O1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE1haW5BeGlzRnJvbVBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIFsndG9wJywgJ2JvdHRvbSddLmluZGV4T2YocGxhY2VtZW50KSA+PSAwID8gJ3gnIDogJ3knO1xufSIsImltcG9ydCB7IG1heCBhcyBtYXRoTWF4LCBtaW4gYXMgbWF0aE1pbiB9IGZyb20gXCIuL21hdGguanNcIjtcbmV4cG9ydCBmdW5jdGlvbiB3aXRoaW4obWluLCB2YWx1ZSwgbWF4KSB7XG4gIHJldHVybiBtYXRoTWF4KG1pbiwgbWF0aE1pbih2YWx1ZSwgbWF4KSk7XG59XG5leHBvcnQgZnVuY3Rpb24gd2l0aGluTWF4Q2xhbXAobWluLCB2YWx1ZSwgbWF4KSB7XG4gIHZhciB2ID0gd2l0aGluKG1pbiwgdmFsdWUsIG1heCk7XG4gIHJldHVybiB2ID4gbWF4ID8gbWF4IDogdjtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRGcmVzaFNpZGVPYmplY3QoKSB7XG4gIHJldHVybiB7XG4gICAgdG9wOiAwLFxuICAgIHJpZ2h0OiAwLFxuICAgIGJvdHRvbTogMCxcbiAgICBsZWZ0OiAwXG4gIH07XG59IiwiaW1wb3J0IGdldEZyZXNoU2lkZU9iamVjdCBmcm9tIFwiLi9nZXRGcmVzaFNpZGVPYmplY3QuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG1lcmdlUGFkZGluZ09iamVjdChwYWRkaW5nT2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBnZXRGcmVzaFNpZGVPYmplY3QoKSwgcGFkZGluZ09iamVjdCk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZXhwYW5kVG9IYXNoTWFwKHZhbHVlLCBrZXlzKSB7XG4gIHJldHVybiBrZXlzLnJlZHVjZShmdW5jdGlvbiAoaGFzaE1hcCwga2V5KSB7XG4gICAgaGFzaE1hcFtrZXldID0gdmFsdWU7XG4gICAgcmV0dXJuIGhhc2hNYXA7XG4gIH0sIHt9KTtcbn0iLCJpbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldExheW91dFJlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzXCI7XG5pbXBvcnQgY29udGFpbnMgZnJvbSBcIi4uL2RvbS11dGlscy9jb250YWlucy5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE9mZnNldFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgeyB3aXRoaW4gfSBmcm9tIFwiLi4vdXRpbHMvd2l0aGluLmpzXCI7XG5pbXBvcnQgbWVyZ2VQYWRkaW5nT2JqZWN0IGZyb20gXCIuLi91dGlscy9tZXJnZVBhZGRpbmdPYmplY3QuanNcIjtcbmltcG9ydCBleHBhbmRUb0hhc2hNYXAgZnJvbSBcIi4uL3V0aWxzL2V4cGFuZFRvSGFzaE1hcC5qc1wiO1xuaW1wb3J0IHsgbGVmdCwgcmlnaHQsIGJhc2VQbGFjZW1lbnRzLCB0b3AsIGJvdHRvbSB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuaW1wb3J0IHsgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuLi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbnZhciB0b1BhZGRpbmdPYmplY3QgPSBmdW5jdGlvbiB0b1BhZGRpbmdPYmplY3QocGFkZGluZywgc3RhdGUpIHtcbiAgcGFkZGluZyA9IHR5cGVvZiBwYWRkaW5nID09PSAnZnVuY3Rpb24nID8gcGFkZGluZyhPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5yZWN0cywge1xuICAgIHBsYWNlbWVudDogc3RhdGUucGxhY2VtZW50XG4gIH0pKSA6IHBhZGRpbmc7XG4gIHJldHVybiBtZXJnZVBhZGRpbmdPYmplY3QodHlwZW9mIHBhZGRpbmcgIT09ICdudW1iZXInID8gcGFkZGluZyA6IGV4cGFuZFRvSGFzaE1hcChwYWRkaW5nLCBiYXNlUGxhY2VtZW50cykpO1xufTtcblxuZnVuY3Rpb24gYXJyb3coX3JlZikge1xuICB2YXIgX3N0YXRlJG1vZGlmaWVyc0RhdGEkO1xuXG4gIHZhciBzdGF0ZSA9IF9yZWYuc3RhdGUsXG4gICAgICBuYW1lID0gX3JlZi5uYW1lLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucztcbiAgdmFyIGFycm93RWxlbWVudCA9IHN0YXRlLmVsZW1lbnRzLmFycm93O1xuICB2YXIgcG9wcGVyT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cztcbiAgdmFyIGJhc2VQbGFjZW1lbnQgPSBnZXRCYXNlUGxhY2VtZW50KHN0YXRlLnBsYWNlbWVudCk7XG4gIHZhciBheGlzID0gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KGJhc2VQbGFjZW1lbnQpO1xuICB2YXIgaXNWZXJ0aWNhbCA9IFtsZWZ0LCByaWdodF0uaW5kZXhPZihiYXNlUGxhY2VtZW50KSA+PSAwO1xuICB2YXIgbGVuID0gaXNWZXJ0aWNhbCA/ICdoZWlnaHQnIDogJ3dpZHRoJztcblxuICBpZiAoIWFycm93RWxlbWVudCB8fCAhcG9wcGVyT2Zmc2V0cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwYWRkaW5nT2JqZWN0ID0gdG9QYWRkaW5nT2JqZWN0KG9wdGlvbnMucGFkZGluZywgc3RhdGUpO1xuICB2YXIgYXJyb3dSZWN0ID0gZ2V0TGF5b3V0UmVjdChhcnJvd0VsZW1lbnQpO1xuICB2YXIgbWluUHJvcCA9IGF4aXMgPT09ICd5JyA/IHRvcCA6IGxlZnQ7XG4gIHZhciBtYXhQcm9wID0gYXhpcyA9PT0gJ3knID8gYm90dG9tIDogcmlnaHQ7XG4gIHZhciBlbmREaWZmID0gc3RhdGUucmVjdHMucmVmZXJlbmNlW2xlbl0gKyBzdGF0ZS5yZWN0cy5yZWZlcmVuY2VbYXhpc10gLSBwb3BwZXJPZmZzZXRzW2F4aXNdIC0gc3RhdGUucmVjdHMucG9wcGVyW2xlbl07XG4gIHZhciBzdGFydERpZmYgPSBwb3BwZXJPZmZzZXRzW2F4aXNdIC0gc3RhdGUucmVjdHMucmVmZXJlbmNlW2F4aXNdO1xuICB2YXIgYXJyb3dPZmZzZXRQYXJlbnQgPSBnZXRPZmZzZXRQYXJlbnQoYXJyb3dFbGVtZW50KTtcbiAgdmFyIGNsaWVudFNpemUgPSBhcnJvd09mZnNldFBhcmVudCA/IGF4aXMgPT09ICd5JyA/IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudEhlaWdodCB8fCAwIDogYXJyb3dPZmZzZXRQYXJlbnQuY2xpZW50V2lkdGggfHwgMCA6IDA7XG4gIHZhciBjZW50ZXJUb1JlZmVyZW5jZSA9IGVuZERpZmYgLyAyIC0gc3RhcnREaWZmIC8gMjsgLy8gTWFrZSBzdXJlIHRoZSBhcnJvdyBkb2Vzbid0IG92ZXJmbG93IHRoZSBwb3BwZXIgaWYgdGhlIGNlbnRlciBwb2ludCBpc1xuICAvLyBvdXRzaWRlIG9mIHRoZSBwb3BwZXIgYm91bmRzXG5cbiAgdmFyIG1pbiA9IHBhZGRpbmdPYmplY3RbbWluUHJvcF07XG4gIHZhciBtYXggPSBjbGllbnRTaXplIC0gYXJyb3dSZWN0W2xlbl0gLSBwYWRkaW5nT2JqZWN0W21heFByb3BdO1xuICB2YXIgY2VudGVyID0gY2xpZW50U2l6ZSAvIDIgLSBhcnJvd1JlY3RbbGVuXSAvIDIgKyBjZW50ZXJUb1JlZmVyZW5jZTtcbiAgdmFyIG9mZnNldCA9IHdpdGhpbihtaW4sIGNlbnRlciwgbWF4KTsgLy8gUHJldmVudHMgYnJlYWtpbmcgc3ludGF4IGhpZ2hsaWdodGluZy4uLlxuXG4gIHZhciBheGlzUHJvcCA9IGF4aXM7XG4gIHN0YXRlLm1vZGlmaWVyc0RhdGFbbmFtZV0gPSAoX3N0YXRlJG1vZGlmaWVyc0RhdGEkID0ge30sIF9zdGF0ZSRtb2RpZmllcnNEYXRhJFtheGlzUHJvcF0gPSBvZmZzZXQsIF9zdGF0ZSRtb2RpZmllcnNEYXRhJC5jZW50ZXJPZmZzZXQgPSBvZmZzZXQgLSBjZW50ZXIsIF9zdGF0ZSRtb2RpZmllcnNEYXRhJCk7XG59XG5cbmZ1bmN0aW9uIGVmZmVjdChfcmVmMikge1xuICB2YXIgc3RhdGUgPSBfcmVmMi5zdGF0ZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmMi5vcHRpb25zO1xuICB2YXIgX29wdGlvbnMkZWxlbWVudCA9IG9wdGlvbnMuZWxlbWVudCxcbiAgICAgIGFycm93RWxlbWVudCA9IF9vcHRpb25zJGVsZW1lbnQgPT09IHZvaWQgMCA/ICdbZGF0YS1wb3BwZXItYXJyb3ddJyA6IF9vcHRpb25zJGVsZW1lbnQ7XG5cbiAgaWYgKGFycm93RWxlbWVudCA9PSBudWxsKSB7XG4gICAgcmV0dXJuO1xuICB9IC8vIENTUyBzZWxlY3RvclxuXG5cbiAgaWYgKHR5cGVvZiBhcnJvd0VsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgYXJyb3dFbGVtZW50ID0gc3RhdGUuZWxlbWVudHMucG9wcGVyLnF1ZXJ5U2VsZWN0b3IoYXJyb3dFbGVtZW50KTtcblxuICAgIGlmICghYXJyb3dFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgIGlmICghaXNIVE1MRWxlbWVudChhcnJvd0VsZW1lbnQpKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFsnUG9wcGVyOiBcImFycm93XCIgZWxlbWVudCBtdXN0IGJlIGFuIEhUTUxFbGVtZW50IChub3QgYW4gU1ZHRWxlbWVudCkuJywgJ1RvIHVzZSBhbiBTVkcgYXJyb3csIHdyYXAgaXQgaW4gYW4gSFRNTEVsZW1lbnQgdGhhdCB3aWxsIGJlIHVzZWQgYXMnLCAndGhlIGFycm93LiddLmpvaW4oJyAnKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFjb250YWlucyhzdGF0ZS5lbGVtZW50cy5wb3BwZXIsIGFycm93RWxlbWVudCkpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFsnUG9wcGVyOiBcImFycm93XCIgbW9kaWZpZXJcXCdzIGBlbGVtZW50YCBtdXN0IGJlIGEgY2hpbGQgb2YgdGhlIHBvcHBlcicsICdlbGVtZW50LiddLmpvaW4oJyAnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgc3RhdGUuZWxlbWVudHMuYXJyb3cgPSBhcnJvd0VsZW1lbnQ7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdhcnJvdycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBhcnJvdyxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIHJlcXVpcmVzOiBbJ3BvcHBlck9mZnNldHMnXSxcbiAgcmVxdWlyZXNJZkV4aXN0czogWydwcmV2ZW50T3ZlcmZsb3cnXVxufTsiLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSB7XG4gIHJldHVybiBwbGFjZW1lbnQuc3BsaXQoJy0nKVsxXTtcbn0iLCJpbXBvcnQgeyB0b3AsIGxlZnQsIHJpZ2h0LCBib3R0b20sIGVuZCB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE9mZnNldFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldFdpbmRvdy5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50RWxlbWVudCBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldENvbXB1dGVkU3R5bGUgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi4vdXRpbHMvZ2V0VmFyaWF0aW9uLmpzXCI7XG5pbXBvcnQgeyByb3VuZCB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxudmFyIHVuc2V0U2lkZXMgPSB7XG4gIHRvcDogJ2F1dG8nLFxuICByaWdodDogJ2F1dG8nLFxuICBib3R0b206ICdhdXRvJyxcbiAgbGVmdDogJ2F1dG8nXG59OyAvLyBSb3VuZCB0aGUgb2Zmc2V0cyB0byB0aGUgbmVhcmVzdCBzdWl0YWJsZSBzdWJwaXhlbCBiYXNlZCBvbiB0aGUgRFBSLlxuLy8gWm9vbWluZyBjYW4gY2hhbmdlIHRoZSBEUFIsIGJ1dCBpdCBzZWVtcyB0byByZXBvcnQgYSB2YWx1ZSB0aGF0IHdpbGxcbi8vIGNsZWFubHkgZGl2aWRlIHRoZSB2YWx1ZXMgaW50byB0aGUgYXBwcm9wcmlhdGUgc3VicGl4ZWxzLlxuXG5mdW5jdGlvbiByb3VuZE9mZnNldHNCeURQUihfcmVmKSB7XG4gIHZhciB4ID0gX3JlZi54LFxuICAgICAgeSA9IF9yZWYueTtcbiAgdmFyIHdpbiA9IHdpbmRvdztcbiAgdmFyIGRwciA9IHdpbi5kZXZpY2VQaXhlbFJhdGlvIHx8IDE7XG4gIHJldHVybiB7XG4gICAgeDogcm91bmQoeCAqIGRwcikgLyBkcHIgfHwgMCxcbiAgICB5OiByb3VuZCh5ICogZHByKSAvIGRwciB8fCAwXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXBUb1N0eWxlcyhfcmVmMikge1xuICB2YXIgX09iamVjdCRhc3NpZ24yO1xuXG4gIHZhciBwb3BwZXIgPSBfcmVmMi5wb3BwZXIsXG4gICAgICBwb3BwZXJSZWN0ID0gX3JlZjIucG9wcGVyUmVjdCxcbiAgICAgIHBsYWNlbWVudCA9IF9yZWYyLnBsYWNlbWVudCxcbiAgICAgIHZhcmlhdGlvbiA9IF9yZWYyLnZhcmlhdGlvbixcbiAgICAgIG9mZnNldHMgPSBfcmVmMi5vZmZzZXRzLFxuICAgICAgcG9zaXRpb24gPSBfcmVmMi5wb3NpdGlvbixcbiAgICAgIGdwdUFjY2VsZXJhdGlvbiA9IF9yZWYyLmdwdUFjY2VsZXJhdGlvbixcbiAgICAgIGFkYXB0aXZlID0gX3JlZjIuYWRhcHRpdmUsXG4gICAgICByb3VuZE9mZnNldHMgPSBfcmVmMi5yb3VuZE9mZnNldHMsXG4gICAgICBpc0ZpeGVkID0gX3JlZjIuaXNGaXhlZDtcbiAgdmFyIF9vZmZzZXRzJHggPSBvZmZzZXRzLngsXG4gICAgICB4ID0gX29mZnNldHMkeCA9PT0gdm9pZCAwID8gMCA6IF9vZmZzZXRzJHgsXG4gICAgICBfb2Zmc2V0cyR5ID0gb2Zmc2V0cy55LFxuICAgICAgeSA9IF9vZmZzZXRzJHkgPT09IHZvaWQgMCA/IDAgOiBfb2Zmc2V0cyR5O1xuXG4gIHZhciBfcmVmMyA9IHR5cGVvZiByb3VuZE9mZnNldHMgPT09ICdmdW5jdGlvbicgPyByb3VuZE9mZnNldHMoe1xuICAgIHg6IHgsXG4gICAgeTogeVxuICB9KSA6IHtcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfTtcblxuICB4ID0gX3JlZjMueDtcbiAgeSA9IF9yZWYzLnk7XG4gIHZhciBoYXNYID0gb2Zmc2V0cy5oYXNPd25Qcm9wZXJ0eSgneCcpO1xuICB2YXIgaGFzWSA9IG9mZnNldHMuaGFzT3duUHJvcGVydHkoJ3knKTtcbiAgdmFyIHNpZGVYID0gbGVmdDtcbiAgdmFyIHNpZGVZID0gdG9wO1xuICB2YXIgd2luID0gd2luZG93O1xuXG4gIGlmIChhZGFwdGl2ZSkge1xuICAgIHZhciBvZmZzZXRQYXJlbnQgPSBnZXRPZmZzZXRQYXJlbnQocG9wcGVyKTtcbiAgICB2YXIgaGVpZ2h0UHJvcCA9ICdjbGllbnRIZWlnaHQnO1xuICAgIHZhciB3aWR0aFByb3AgPSAnY2xpZW50V2lkdGgnO1xuXG4gICAgaWYgKG9mZnNldFBhcmVudCA9PT0gZ2V0V2luZG93KHBvcHBlcikpIHtcbiAgICAgIG9mZnNldFBhcmVudCA9IGdldERvY3VtZW50RWxlbWVudChwb3BwZXIpO1xuXG4gICAgICBpZiAoZ2V0Q29tcHV0ZWRTdHlsZShvZmZzZXRQYXJlbnQpLnBvc2l0aW9uICE9PSAnc3RhdGljJyAmJiBwb3NpdGlvbiA9PT0gJ2Fic29sdXRlJykge1xuICAgICAgICBoZWlnaHRQcm9wID0gJ3Njcm9sbEhlaWdodCc7XG4gICAgICAgIHdpZHRoUHJvcCA9ICdzY3JvbGxXaWR0aCc7XG4gICAgICB9XG4gICAgfSAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1jYXN0XTogZm9yY2UgdHlwZSByZWZpbmVtZW50LCB3ZSBjb21wYXJlIG9mZnNldFBhcmVudCB3aXRoIHdpbmRvdyBhYm92ZSwgYnV0IEZsb3cgZG9lc24ndCBkZXRlY3QgaXRcblxuXG4gICAgb2Zmc2V0UGFyZW50ID0gb2Zmc2V0UGFyZW50O1xuXG4gICAgaWYgKHBsYWNlbWVudCA9PT0gdG9wIHx8IChwbGFjZW1lbnQgPT09IGxlZnQgfHwgcGxhY2VtZW50ID09PSByaWdodCkgJiYgdmFyaWF0aW9uID09PSBlbmQpIHtcbiAgICAgIHNpZGVZID0gYm90dG9tO1xuICAgICAgdmFyIG9mZnNldFkgPSBpc0ZpeGVkICYmIHdpbi52aXN1YWxWaWV3cG9ydCA/IHdpbi52aXN1YWxWaWV3cG9ydC5oZWlnaHQgOiAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgIG9mZnNldFBhcmVudFtoZWlnaHRQcm9wXTtcbiAgICAgIHkgLT0gb2Zmc2V0WSAtIHBvcHBlclJlY3QuaGVpZ2h0O1xuICAgICAgeSAqPSBncHVBY2NlbGVyYXRpb24gPyAxIDogLTE7XG4gICAgfVxuXG4gICAgaWYgKHBsYWNlbWVudCA9PT0gbGVmdCB8fCAocGxhY2VtZW50ID09PSB0b3AgfHwgcGxhY2VtZW50ID09PSBib3R0b20pICYmIHZhcmlhdGlvbiA9PT0gZW5kKSB7XG4gICAgICBzaWRlWCA9IHJpZ2h0O1xuICAgICAgdmFyIG9mZnNldFggPSBpc0ZpeGVkICYmIHdpbi52aXN1YWxWaWV3cG9ydCA/IHdpbi52aXN1YWxWaWV3cG9ydC53aWR0aCA6IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgICAgb2Zmc2V0UGFyZW50W3dpZHRoUHJvcF07XG4gICAgICB4IC09IG9mZnNldFggLSBwb3BwZXJSZWN0LndpZHRoO1xuICAgICAgeCAqPSBncHVBY2NlbGVyYXRpb24gPyAxIDogLTE7XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbW1vblN0eWxlcyA9IE9iamVjdC5hc3NpZ24oe1xuICAgIHBvc2l0aW9uOiBwb3NpdGlvblxuICB9LCBhZGFwdGl2ZSAmJiB1bnNldFNpZGVzKTtcblxuICB2YXIgX3JlZjQgPSByb3VuZE9mZnNldHMgPT09IHRydWUgPyByb3VuZE9mZnNldHNCeURQUih7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH0pIDoge1xuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xuXG4gIHggPSBfcmVmNC54O1xuICB5ID0gX3JlZjQueTtcblxuICBpZiAoZ3B1QWNjZWxlcmF0aW9uKSB7XG4gICAgdmFyIF9PYmplY3QkYXNzaWduO1xuXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGNvbW1vblN0eWxlcywgKF9PYmplY3QkYXNzaWduID0ge30sIF9PYmplY3QkYXNzaWduW3NpZGVZXSA9IGhhc1kgPyAnMCcgOiAnJywgX09iamVjdCRhc3NpZ25bc2lkZVhdID0gaGFzWCA/ICcwJyA6ICcnLCBfT2JqZWN0JGFzc2lnbi50cmFuc2Zvcm0gPSAod2luLmRldmljZVBpeGVsUmF0aW8gfHwgMSkgPD0gMSA/IFwidHJhbnNsYXRlKFwiICsgeCArIFwicHgsIFwiICsgeSArIFwicHgpXCIgOiBcInRyYW5zbGF0ZTNkKFwiICsgeCArIFwicHgsIFwiICsgeSArIFwicHgsIDApXCIsIF9PYmplY3QkYXNzaWduKSk7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCAoX09iamVjdCRhc3NpZ24yID0ge30sIF9PYmplY3QkYXNzaWduMltzaWRlWV0gPSBoYXNZID8geSArIFwicHhcIiA6ICcnLCBfT2JqZWN0JGFzc2lnbjJbc2lkZVhdID0gaGFzWCA/IHggKyBcInB4XCIgOiAnJywgX09iamVjdCRhc3NpZ24yLnRyYW5zZm9ybSA9ICcnLCBfT2JqZWN0JGFzc2lnbjIpKTtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZVN0eWxlcyhfcmVmNSkge1xuICB2YXIgc3RhdGUgPSBfcmVmNS5zdGF0ZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmNS5vcHRpb25zO1xuICB2YXIgX29wdGlvbnMkZ3B1QWNjZWxlcmF0ID0gb3B0aW9ucy5ncHVBY2NlbGVyYXRpb24sXG4gICAgICBncHVBY2NlbGVyYXRpb24gPSBfb3B0aW9ucyRncHVBY2NlbGVyYXQgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRncHVBY2NlbGVyYXQsXG4gICAgICBfb3B0aW9ucyRhZGFwdGl2ZSA9IG9wdGlvbnMuYWRhcHRpdmUsXG4gICAgICBhZGFwdGl2ZSA9IF9vcHRpb25zJGFkYXB0aXZlID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkYWRhcHRpdmUsXG4gICAgICBfb3B0aW9ucyRyb3VuZE9mZnNldHMgPSBvcHRpb25zLnJvdW5kT2Zmc2V0cyxcbiAgICAgIHJvdW5kT2Zmc2V0cyA9IF9vcHRpb25zJHJvdW5kT2Zmc2V0cyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJHJvdW5kT2Zmc2V0cztcblxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgdmFyIHRyYW5zaXRpb25Qcm9wZXJ0eSA9IGdldENvbXB1dGVkU3R5bGUoc3RhdGUuZWxlbWVudHMucG9wcGVyKS50cmFuc2l0aW9uUHJvcGVydHkgfHwgJyc7XG5cbiAgICBpZiAoYWRhcHRpdmUgJiYgWyd0cmFuc2Zvcm0nLCAndG9wJywgJ3JpZ2h0JywgJ2JvdHRvbScsICdsZWZ0J10uc29tZShmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgIHJldHVybiB0cmFuc2l0aW9uUHJvcGVydHkuaW5kZXhPZihwcm9wZXJ0eSkgPj0gMDtcbiAgICB9KSkge1xuICAgICAgY29uc29sZS53YXJuKFsnUG9wcGVyOiBEZXRlY3RlZCBDU1MgdHJhbnNpdGlvbnMgb24gYXQgbGVhc3Qgb25lIG9mIHRoZSBmb2xsb3dpbmcnLCAnQ1NTIHByb3BlcnRpZXM6IFwidHJhbnNmb3JtXCIsIFwidG9wXCIsIFwicmlnaHRcIiwgXCJib3R0b21cIiwgXCJsZWZ0XCIuJywgJ1xcblxcbicsICdEaXNhYmxlIHRoZSBcImNvbXB1dGVTdHlsZXNcIiBtb2RpZmllclxcJ3MgYGFkYXB0aXZlYCBvcHRpb24gdG8gYWxsb3cnLCAnZm9yIHNtb290aCB0cmFuc2l0aW9ucywgb3IgcmVtb3ZlIHRoZXNlIHByb3BlcnRpZXMgZnJvbSB0aGUgQ1NTJywgJ3RyYW5zaXRpb24gZGVjbGFyYXRpb24gb24gdGhlIHBvcHBlciBlbGVtZW50IGlmIG9ubHkgdHJhbnNpdGlvbmluZycsICdvcGFjaXR5IG9yIGJhY2tncm91bmQtY29sb3IgZm9yIGV4YW1wbGUuJywgJ1xcblxcbicsICdXZSByZWNvbW1lbmQgdXNpbmcgdGhlIHBvcHBlciBlbGVtZW50IGFzIGEgd3JhcHBlciBhcm91bmQgYW4gaW5uZXInLCAnZWxlbWVudCB0aGF0IGNhbiBoYXZlIGFueSBDU1MgcHJvcGVydHkgdHJhbnNpdGlvbmVkIGZvciBhbmltYXRpb25zLiddLmpvaW4oJyAnKSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbW1vblN0eWxlcyA9IHtcbiAgICBwbGFjZW1lbnQ6IGdldEJhc2VQbGFjZW1lbnQoc3RhdGUucGxhY2VtZW50KSxcbiAgICB2YXJpYXRpb246IGdldFZhcmlhdGlvbihzdGF0ZS5wbGFjZW1lbnQpLFxuICAgIHBvcHBlcjogc3RhdGUuZWxlbWVudHMucG9wcGVyLFxuICAgIHBvcHBlclJlY3Q6IHN0YXRlLnJlY3RzLnBvcHBlcixcbiAgICBncHVBY2NlbGVyYXRpb246IGdwdUFjY2VsZXJhdGlvbixcbiAgICBpc0ZpeGVkOiBzdGF0ZS5vcHRpb25zLnN0cmF0ZWd5ID09PSAnZml4ZWQnXG4gIH07XG5cbiAgaWYgKHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cyAhPSBudWxsKSB7XG4gICAgc3RhdGUuc3R5bGVzLnBvcHBlciA9IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnN0eWxlcy5wb3BwZXIsIG1hcFRvU3R5bGVzKE9iamVjdC5hc3NpZ24oe30sIGNvbW1vblN0eWxlcywge1xuICAgICAgb2Zmc2V0czogc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzLFxuICAgICAgcG9zaXRpb246IHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBhZGFwdGl2ZTogYWRhcHRpdmUsXG4gICAgICByb3VuZE9mZnNldHM6IHJvdW5kT2Zmc2V0c1xuICAgIH0pKSk7XG4gIH1cblxuICBpZiAoc3RhdGUubW9kaWZpZXJzRGF0YS5hcnJvdyAhPSBudWxsKSB7XG4gICAgc3RhdGUuc3R5bGVzLmFycm93ID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuc3R5bGVzLmFycm93LCBtYXBUb1N0eWxlcyhPYmplY3QuYXNzaWduKHt9LCBjb21tb25TdHlsZXMsIHtcbiAgICAgIG9mZnNldHM6IHN0YXRlLm1vZGlmaWVyc0RhdGEuYXJyb3csXG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIGFkYXB0aXZlOiBmYWxzZSxcbiAgICAgIHJvdW5kT2Zmc2V0czogcm91bmRPZmZzZXRzXG4gICAgfSkpKTtcbiAgfVxuXG4gIHN0YXRlLmF0dHJpYnV0ZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIsIHtcbiAgICAnZGF0YS1wb3BwZXItcGxhY2VtZW50Jzogc3RhdGUucGxhY2VtZW50XG4gIH0pO1xufSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAnY29tcHV0ZVN0eWxlcycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnYmVmb3JlV3JpdGUnLFxuICBmbjogY29tcHV0ZVN0eWxlcyxcbiAgZGF0YToge31cbn07IiwiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldFdpbmRvdy5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbnZhciBwYXNzaXZlID0ge1xuICBwYXNzaXZlOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgaW5zdGFuY2UgPSBfcmVmLmluc3RhbmNlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJHNjcm9sbCA9IG9wdGlvbnMuc2Nyb2xsLFxuICAgICAgc2Nyb2xsID0gX29wdGlvbnMkc2Nyb2xsID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkc2Nyb2xsLFxuICAgICAgX29wdGlvbnMkcmVzaXplID0gb3B0aW9ucy5yZXNpemUsXG4gICAgICByZXNpemUgPSBfb3B0aW9ucyRyZXNpemUgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRyZXNpemU7XG4gIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coc3RhdGUuZWxlbWVudHMucG9wcGVyKTtcbiAgdmFyIHNjcm9sbFBhcmVudHMgPSBbXS5jb25jYXQoc3RhdGUuc2Nyb2xsUGFyZW50cy5yZWZlcmVuY2UsIHN0YXRlLnNjcm9sbFBhcmVudHMucG9wcGVyKTtcblxuICBpZiAoc2Nyb2xsKSB7XG4gICAgc2Nyb2xsUGFyZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChzY3JvbGxQYXJlbnQpIHtcbiAgICAgIHNjcm9sbFBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHJlc2l6ZSkge1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc2Nyb2xsKSB7XG4gICAgICBzY3JvbGxQYXJlbnRzLmZvckVhY2goZnVuY3Rpb24gKHNjcm9sbFBhcmVudCkge1xuICAgICAgICBzY3JvbGxQYXJlbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgaW5zdGFuY2UudXBkYXRlLCBwYXNzaXZlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChyZXNpemUpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH1cbiAgfTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2V2ZW50TGlzdGVuZXJzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICd3cml0ZScsXG4gIGZuOiBmdW5jdGlvbiBmbigpIHt9LFxuICBlZmZlY3Q6IGVmZmVjdCxcbiAgZGF0YToge31cbn07IiwidmFyIGhhc2ggPSB7XG4gIGxlZnQ6ICdyaWdodCcsXG4gIHJpZ2h0OiAnbGVmdCcsXG4gIGJvdHRvbTogJ3RvcCcsXG4gIHRvcDogJ2JvdHRvbSdcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRPcHBvc2l0ZVBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5yZXBsYWNlKC9sZWZ0fHJpZ2h0fGJvdHRvbXx0b3AvZywgZnVuY3Rpb24gKG1hdGNoZWQpIHtcbiAgICByZXR1cm4gaGFzaFttYXRjaGVkXTtcbiAgfSk7XG59IiwidmFyIGhhc2ggPSB7XG4gIHN0YXJ0OiAnZW5kJyxcbiAgZW5kOiAnc3RhcnQnXG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQocGxhY2VtZW50KSB7XG4gIHJldHVybiBwbGFjZW1lbnQucmVwbGFjZSgvc3RhcnR8ZW5kL2csIGZ1bmN0aW9uIChtYXRjaGVkKSB7XG4gICAgcmV0dXJuIGhhc2hbbWF0Y2hlZF07XG4gIH0pO1xufSIsImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRXaW5kb3dTY3JvbGwobm9kZSkge1xuICB2YXIgd2luID0gZ2V0V2luZG93KG5vZGUpO1xuICB2YXIgc2Nyb2xsTGVmdCA9IHdpbi5wYWdlWE9mZnNldDtcbiAgdmFyIHNjcm9sbFRvcCA9IHdpbi5wYWdlWU9mZnNldDtcbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBzY3JvbGxMZWZ0LFxuICAgIHNjcm9sbFRvcDogc2Nyb2xsVG9wXG4gIH07XG59IiwiaW1wb3J0IGdldEJvdW5kaW5nQ2xpZW50UmVjdCBmcm9tIFwiLi9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93U2Nyb2xsIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0V2luZG93U2Nyb2xsQmFyWChlbGVtZW50KSB7XG4gIC8vIElmIDxodG1sPiBoYXMgYSBDU1Mgd2lkdGggZ3JlYXRlciB0aGFuIHRoZSB2aWV3cG9ydCwgdGhlbiB0aGlzIHdpbGwgYmVcbiAgLy8gaW5jb3JyZWN0IGZvciBSVEwuXG4gIC8vIFBvcHBlciAxIGlzIGJyb2tlbiBpbiB0aGlzIGNhc2UgYW5kIG5ldmVyIGhhZCBhIGJ1ZyByZXBvcnQgc28gbGV0J3MgYXNzdW1lXG4gIC8vIGl0J3Mgbm90IGFuIGlzc3VlLiBJIGRvbid0IHRoaW5rIGFueW9uZSBldmVyIHNwZWNpZmllcyB3aWR0aCBvbiA8aHRtbD5cbiAgLy8gYW55d2F5LlxuICAvLyBCcm93c2VycyB3aGVyZSB0aGUgbGVmdCBzY3JvbGxiYXIgZG9lc24ndCBjYXVzZSBhbiBpc3N1ZSByZXBvcnQgYDBgIGZvclxuICAvLyB0aGlzIChlLmcuIEVkZ2UgMjAxOSwgSUUxMSwgU2FmYXJpKVxuICByZXR1cm4gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KSkubGVmdCArIGdldFdpbmRvd1Njcm9sbChlbGVtZW50KS5zY3JvbGxMZWZ0O1xufSIsImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbEJhclggZnJvbSBcIi4vZ2V0V2luZG93U2Nyb2xsQmFyWC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Vmlld3BvcnRSZWN0KGVsZW1lbnQpIHtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhlbGVtZW50KTtcbiAgdmFyIGh0bWwgPSBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCk7XG4gIHZhciB2aXN1YWxWaWV3cG9ydCA9IHdpbi52aXN1YWxWaWV3cG9ydDtcbiAgdmFyIHdpZHRoID0gaHRtbC5jbGllbnRXaWR0aDtcbiAgdmFyIGhlaWdodCA9IGh0bWwuY2xpZW50SGVpZ2h0O1xuICB2YXIgeCA9IDA7XG4gIHZhciB5ID0gMDsgLy8gTkI6IFRoaXMgaXNuJ3Qgc3VwcG9ydGVkIG9uIGlPUyA8PSAxMi4gSWYgdGhlIGtleWJvYXJkIGlzIG9wZW4sIHRoZSBwb3BwZXJcbiAgLy8gY2FuIGJlIG9ic2N1cmVkIHVuZGVybmVhdGggaXQuXG4gIC8vIEFsc28sIGBodG1sLmNsaWVudEhlaWdodGAgYWRkcyB0aGUgYm90dG9tIGJhciBoZWlnaHQgaW4gU2FmYXJpIGlPUywgZXZlblxuICAvLyBpZiBpdCBpc24ndCBvcGVuLCBzbyBpZiB0aGlzIGlzbid0IGF2YWlsYWJsZSwgdGhlIHBvcHBlciB3aWxsIGJlIGRldGVjdGVkXG4gIC8vIHRvIG92ZXJmbG93IHRoZSBib3R0b20gb2YgdGhlIHNjcmVlbiB0b28gZWFybHkuXG5cbiAgaWYgKHZpc3VhbFZpZXdwb3J0KSB7XG4gICAgd2lkdGggPSB2aXN1YWxWaWV3cG9ydC53aWR0aDtcbiAgICBoZWlnaHQgPSB2aXN1YWxWaWV3cG9ydC5oZWlnaHQ7IC8vIFVzZXMgTGF5b3V0IFZpZXdwb3J0IChsaWtlIENocm9tZTsgU2FmYXJpIGRvZXMgbm90IGN1cnJlbnRseSlcbiAgICAvLyBJbiBDaHJvbWUsIGl0IHJldHVybnMgYSB2YWx1ZSB2ZXJ5IGNsb3NlIHRvIDAgKCsvLSkgYnV0IGNvbnRhaW5zIHJvdW5kaW5nXG4gICAgLy8gZXJyb3JzIGR1ZSB0byBmbG9hdGluZyBwb2ludCBudW1iZXJzLCBzbyB3ZSBuZWVkIHRvIGNoZWNrIHByZWNpc2lvbi5cbiAgICAvLyBTYWZhcmkgcmV0dXJucyBhIG51bWJlciA8PSAwLCB1c3VhbGx5IDwgLTEgd2hlbiBwaW5jaC16b29tZWRcbiAgICAvLyBGZWF0dXJlIGRldGVjdGlvbiBmYWlscyBpbiBtb2JpbGUgZW11bGF0aW9uIG1vZGUgaW4gQ2hyb21lLlxuICAgIC8vIE1hdGguYWJzKHdpbi5pbm5lcldpZHRoIC8gdmlzdWFsVmlld3BvcnQuc2NhbGUgLSB2aXN1YWxWaWV3cG9ydC53aWR0aCkgPFxuICAgIC8vIDAuMDAxXG4gICAgLy8gRmFsbGJhY2sgaGVyZTogXCJOb3QgU2FmYXJpXCIgdXNlckFnZW50XG5cbiAgICBpZiAoIS9eKCg/IWNocm9tZXxhbmRyb2lkKS4pKnNhZmFyaS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcbiAgICAgIHggPSB2aXN1YWxWaWV3cG9ydC5vZmZzZXRMZWZ0O1xuICAgICAgeSA9IHZpc3VhbFZpZXdwb3J0Lm9mZnNldFRvcDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICB4OiB4ICsgZ2V0V2luZG93U2Nyb2xsQmFyWChlbGVtZW50KSxcbiAgICB5OiB5XG4gIH07XG59IiwiaW1wb3J0IGdldERvY3VtZW50RWxlbWVudCBmcm9tIFwiLi9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRDb21wdXRlZFN0eWxlIGZyb20gXCIuL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCBnZXRXaW5kb3dTY3JvbGxCYXJYIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbEJhclguanNcIjtcbmltcG9ydCBnZXRXaW5kb3dTY3JvbGwgZnJvbSBcIi4vZ2V0V2luZG93U2Nyb2xsLmpzXCI7XG5pbXBvcnQgeyBtYXggfSBmcm9tIFwiLi4vdXRpbHMvbWF0aC5qc1wiOyAvLyBHZXRzIHRoZSBlbnRpcmUgc2l6ZSBvZiB0aGUgc2Nyb2xsYWJsZSBkb2N1bWVudCBhcmVhLCBldmVuIGV4dGVuZGluZyBvdXRzaWRlXG4vLyBvZiB0aGUgYDxodG1sPmAgYW5kIGA8Ym9keT5gIHJlY3QgYm91bmRzIGlmIGhvcml6b250YWxseSBzY3JvbGxhYmxlXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldERvY3VtZW50UmVjdChlbGVtZW50KSB7XG4gIHZhciBfZWxlbWVudCRvd25lckRvY3VtZW47XG5cbiAgdmFyIGh0bWwgPSBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCk7XG4gIHZhciB3aW5TY3JvbGwgPSBnZXRXaW5kb3dTY3JvbGwoZWxlbWVudCk7XG4gIHZhciBib2R5ID0gKF9lbGVtZW50JG93bmVyRG9jdW1lbiA9IGVsZW1lbnQub3duZXJEb2N1bWVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9lbGVtZW50JG93bmVyRG9jdW1lbi5ib2R5O1xuICB2YXIgd2lkdGggPSBtYXgoaHRtbC5zY3JvbGxXaWR0aCwgaHRtbC5jbGllbnRXaWR0aCwgYm9keSA/IGJvZHkuc2Nyb2xsV2lkdGggOiAwLCBib2R5ID8gYm9keS5jbGllbnRXaWR0aCA6IDApO1xuICB2YXIgaGVpZ2h0ID0gbWF4KGh0bWwuc2Nyb2xsSGVpZ2h0LCBodG1sLmNsaWVudEhlaWdodCwgYm9keSA/IGJvZHkuc2Nyb2xsSGVpZ2h0IDogMCwgYm9keSA/IGJvZHkuY2xpZW50SGVpZ2h0IDogMCk7XG4gIHZhciB4ID0gLXdpblNjcm9sbC5zY3JvbGxMZWZ0ICsgZ2V0V2luZG93U2Nyb2xsQmFyWChlbGVtZW50KTtcbiAgdmFyIHkgPSAtd2luU2Nyb2xsLnNjcm9sbFRvcDtcblxuICBpZiAoZ2V0Q29tcHV0ZWRTdHlsZShib2R5IHx8IGh0bWwpLmRpcmVjdGlvbiA9PT0gJ3J0bCcpIHtcbiAgICB4ICs9IG1heChodG1sLmNsaWVudFdpZHRoLCBib2R5ID8gYm9keS5jbGllbnRXaWR0aCA6IDApIC0gd2lkdGg7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfTtcbn0iLCJpbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc1Njcm9sbFBhcmVudChlbGVtZW50KSB7XG4gIC8vIEZpcmVmb3ggd2FudHMgdXMgdG8gY2hlY2sgYC14YCBhbmQgYC15YCB2YXJpYXRpb25zIGFzIHdlbGxcbiAgdmFyIF9nZXRDb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KSxcbiAgICAgIG92ZXJmbG93ID0gX2dldENvbXB1dGVkU3R5bGUub3ZlcmZsb3csXG4gICAgICBvdmVyZmxvd1ggPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1gsXG4gICAgICBvdmVyZmxvd1kgPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1k7XG5cbiAgcmV0dXJuIC9hdXRvfHNjcm9sbHxvdmVybGF5fGhpZGRlbi8udGVzdChvdmVyZmxvdyArIG92ZXJmbG93WSArIG92ZXJmbG93WCk7XG59IiwiaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGlzU2Nyb2xsUGFyZW50IGZyb20gXCIuL2lzU2Nyb2xsUGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRTY3JvbGxQYXJlbnQobm9kZSkge1xuICBpZiAoWydodG1sJywgJ2JvZHknLCAnI2RvY3VtZW50J10uaW5kZXhPZihnZXROb2RlTmFtZShub2RlKSkgPj0gMCkge1xuICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXJldHVybl06IGFzc3VtZSBib2R5IGlzIGFsd2F5cyBhdmFpbGFibGVcbiAgICByZXR1cm4gbm9kZS5vd25lckRvY3VtZW50LmJvZHk7XG4gIH1cblxuICBpZiAoaXNIVE1MRWxlbWVudChub2RlKSAmJiBpc1Njcm9sbFBhcmVudChub2RlKSkge1xuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgcmV0dXJuIGdldFNjcm9sbFBhcmVudChnZXRQYXJlbnROb2RlKG5vZGUpKTtcbn0iLCJpbXBvcnQgZ2V0U2Nyb2xsUGFyZW50IGZyb20gXCIuL2dldFNjcm9sbFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCBpc1Njcm9sbFBhcmVudCBmcm9tIFwiLi9pc1Njcm9sbFBhcmVudC5qc1wiO1xuLypcbmdpdmVuIGEgRE9NIGVsZW1lbnQsIHJldHVybiB0aGUgbGlzdCBvZiBhbGwgc2Nyb2xsIHBhcmVudHMsIHVwIHRoZSBsaXN0IG9mIGFuY2Vzb3JzXG51bnRpbCB3ZSBnZXQgdG8gdGhlIHRvcCB3aW5kb3cgb2JqZWN0LiBUaGlzIGxpc3QgaXMgd2hhdCB3ZSBhdHRhY2ggc2Nyb2xsIGxpc3RlbmVyc1xudG8sIGJlY2F1c2UgaWYgYW55IG9mIHRoZXNlIHBhcmVudCBlbGVtZW50cyBzY3JvbGwsIHdlJ2xsIG5lZWQgdG8gcmUtY2FsY3VsYXRlIHRoZVxucmVmZXJlbmNlIGVsZW1lbnQncyBwb3NpdGlvbi5cbiovXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxpc3RTY3JvbGxQYXJlbnRzKGVsZW1lbnQsIGxpc3QpIHtcbiAgdmFyIF9lbGVtZW50JG93bmVyRG9jdW1lbjtcblxuICBpZiAobGlzdCA9PT0gdm9pZCAwKSB7XG4gICAgbGlzdCA9IFtdO1xuICB9XG5cbiAgdmFyIHNjcm9sbFBhcmVudCA9IGdldFNjcm9sbFBhcmVudChlbGVtZW50KTtcbiAgdmFyIGlzQm9keSA9IHNjcm9sbFBhcmVudCA9PT0gKChfZWxlbWVudCRvd25lckRvY3VtZW4gPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQpID09IG51bGwgPyB2b2lkIDAgOiBfZWxlbWVudCRvd25lckRvY3VtZW4uYm9keSk7XG4gIHZhciB3aW4gPSBnZXRXaW5kb3coc2Nyb2xsUGFyZW50KTtcbiAgdmFyIHRhcmdldCA9IGlzQm9keSA/IFt3aW5dLmNvbmNhdCh3aW4udmlzdWFsVmlld3BvcnQgfHwgW10sIGlzU2Nyb2xsUGFyZW50KHNjcm9sbFBhcmVudCkgPyBzY3JvbGxQYXJlbnQgOiBbXSkgOiBzY3JvbGxQYXJlbnQ7XG4gIHZhciB1cGRhdGVkTGlzdCA9IGxpc3QuY29uY2F0KHRhcmdldCk7XG4gIHJldHVybiBpc0JvZHkgPyB1cGRhdGVkTGlzdCA6IC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLWNhbGxdOiBpc0JvZHkgdGVsbHMgdXMgdGFyZ2V0IHdpbGwgYmUgYW4gSFRNTEVsZW1lbnQgaGVyZVxuICB1cGRhdGVkTGlzdC5jb25jYXQobGlzdFNjcm9sbFBhcmVudHMoZ2V0UGFyZW50Tm9kZSh0YXJnZXQpKSk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVjdFRvQ2xpZW50UmVjdChyZWN0KSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCByZWN0LCB7XG4gICAgbGVmdDogcmVjdC54LFxuICAgIHRvcDogcmVjdC55LFxuICAgIHJpZ2h0OiByZWN0LnggKyByZWN0LndpZHRoLFxuICAgIGJvdHRvbTogcmVjdC55ICsgcmVjdC5oZWlnaHRcbiAgfSk7XG59IiwiaW1wb3J0IHsgdmlld3BvcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCBnZXRWaWV3cG9ydFJlY3QgZnJvbSBcIi4vZ2V0Vmlld3BvcnRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRSZWN0IGZyb20gXCIuL2dldERvY3VtZW50UmVjdC5qc1wiO1xuaW1wb3J0IGxpc3RTY3JvbGxQYXJlbnRzIGZyb20gXCIuL2xpc3RTY3JvbGxQYXJlbnRzLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuL2dldE9mZnNldFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50RWxlbWVudCBmcm9tIFwiLi9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRDb21wdXRlZFN0eWxlIGZyb20gXCIuL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4vZ2V0Qm91bmRpbmdDbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0UGFyZW50Tm9kZSBmcm9tIFwiLi9nZXRQYXJlbnROb2RlLmpzXCI7XG5pbXBvcnQgY29udGFpbnMgZnJvbSBcIi4vY29udGFpbnMuanNcIjtcbmltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi9nZXROb2RlTmFtZS5qc1wiO1xuaW1wb3J0IHJlY3RUb0NsaWVudFJlY3QgZnJvbSBcIi4uL3V0aWxzL3JlY3RUb0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCB7IG1heCwgbWluIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcblxuZnVuY3Rpb24gZ2V0SW5uZXJCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCkge1xuICB2YXIgcmVjdCA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChlbGVtZW50KTtcbiAgcmVjdC50b3AgPSByZWN0LnRvcCArIGVsZW1lbnQuY2xpZW50VG9wO1xuICByZWN0LmxlZnQgPSByZWN0LmxlZnQgKyBlbGVtZW50LmNsaWVudExlZnQ7XG4gIHJlY3QuYm90dG9tID0gcmVjdC50b3AgKyBlbGVtZW50LmNsaWVudEhlaWdodDtcbiAgcmVjdC5yaWdodCA9IHJlY3QubGVmdCArIGVsZW1lbnQuY2xpZW50V2lkdGg7XG4gIHJlY3Qud2lkdGggPSBlbGVtZW50LmNsaWVudFdpZHRoO1xuICByZWN0LmhlaWdodCA9IGVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICByZWN0LnggPSByZWN0LmxlZnQ7XG4gIHJlY3QueSA9IHJlY3QudG9wO1xuICByZXR1cm4gcmVjdDtcbn1cblxuZnVuY3Rpb24gZ2V0Q2xpZW50UmVjdEZyb21NaXhlZFR5cGUoZWxlbWVudCwgY2xpcHBpbmdQYXJlbnQpIHtcbiAgcmV0dXJuIGNsaXBwaW5nUGFyZW50ID09PSB2aWV3cG9ydCA/IHJlY3RUb0NsaWVudFJlY3QoZ2V0Vmlld3BvcnRSZWN0KGVsZW1lbnQpKSA6IGlzRWxlbWVudChjbGlwcGluZ1BhcmVudCkgPyBnZXRJbm5lckJvdW5kaW5nQ2xpZW50UmVjdChjbGlwcGluZ1BhcmVudCkgOiByZWN0VG9DbGllbnRSZWN0KGdldERvY3VtZW50UmVjdChnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkpKTtcbn0gLy8gQSBcImNsaXBwaW5nIHBhcmVudFwiIGlzIGFuIG92ZXJmbG93YWJsZSBjb250YWluZXIgd2l0aCB0aGUgY2hhcmFjdGVyaXN0aWMgb2Zcbi8vIGNsaXBwaW5nIChvciBoaWRpbmcpIG92ZXJmbG93aW5nIGVsZW1lbnRzIHdpdGggYSBwb3NpdGlvbiBkaWZmZXJlbnQgZnJvbVxuLy8gYGluaXRpYWxgXG5cblxuZnVuY3Rpb24gZ2V0Q2xpcHBpbmdQYXJlbnRzKGVsZW1lbnQpIHtcbiAgdmFyIGNsaXBwaW5nUGFyZW50cyA9IGxpc3RTY3JvbGxQYXJlbnRzKGdldFBhcmVudE5vZGUoZWxlbWVudCkpO1xuICB2YXIgY2FuRXNjYXBlQ2xpcHBpbmcgPSBbJ2Fic29sdXRlJywgJ2ZpeGVkJ10uaW5kZXhPZihnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLnBvc2l0aW9uKSA+PSAwO1xuICB2YXIgY2xpcHBlckVsZW1lbnQgPSBjYW5Fc2NhcGVDbGlwcGluZyAmJiBpc0hUTUxFbGVtZW50KGVsZW1lbnQpID8gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpIDogZWxlbWVudDtcblxuICBpZiAoIWlzRWxlbWVudChjbGlwcGVyRWxlbWVudCkpIHtcbiAgICByZXR1cm4gW107XG4gIH0gLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtcmV0dXJuXTogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2Zsb3cvaXNzdWVzLzE0MTRcblxuXG4gIHJldHVybiBjbGlwcGluZ1BhcmVudHMuZmlsdGVyKGZ1bmN0aW9uIChjbGlwcGluZ1BhcmVudCkge1xuICAgIHJldHVybiBpc0VsZW1lbnQoY2xpcHBpbmdQYXJlbnQpICYmIGNvbnRhaW5zKGNsaXBwaW5nUGFyZW50LCBjbGlwcGVyRWxlbWVudCkgJiYgZ2V0Tm9kZU5hbWUoY2xpcHBpbmdQYXJlbnQpICE9PSAnYm9keSc7XG4gIH0pO1xufSAvLyBHZXRzIHRoZSBtYXhpbXVtIGFyZWEgdGhhdCB0aGUgZWxlbWVudCBpcyB2aXNpYmxlIGluIGR1ZSB0byBhbnkgbnVtYmVyIG9mXG4vLyBjbGlwcGluZyBwYXJlbnRzXG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Q2xpcHBpbmdSZWN0KGVsZW1lbnQsIGJvdW5kYXJ5LCByb290Qm91bmRhcnkpIHtcbiAgdmFyIG1haW5DbGlwcGluZ1BhcmVudHMgPSBib3VuZGFyeSA9PT0gJ2NsaXBwaW5nUGFyZW50cycgPyBnZXRDbGlwcGluZ1BhcmVudHMoZWxlbWVudCkgOiBbXS5jb25jYXQoYm91bmRhcnkpO1xuICB2YXIgY2xpcHBpbmdQYXJlbnRzID0gW10uY29uY2F0KG1haW5DbGlwcGluZ1BhcmVudHMsIFtyb290Qm91bmRhcnldKTtcbiAgdmFyIGZpcnN0Q2xpcHBpbmdQYXJlbnQgPSBjbGlwcGluZ1BhcmVudHNbMF07XG4gIHZhciBjbGlwcGluZ1JlY3QgPSBjbGlwcGluZ1BhcmVudHMucmVkdWNlKGZ1bmN0aW9uIChhY2NSZWN0LCBjbGlwcGluZ1BhcmVudCkge1xuICAgIHZhciByZWN0ID0gZ2V0Q2xpZW50UmVjdEZyb21NaXhlZFR5cGUoZWxlbWVudCwgY2xpcHBpbmdQYXJlbnQpO1xuICAgIGFjY1JlY3QudG9wID0gbWF4KHJlY3QudG9wLCBhY2NSZWN0LnRvcCk7XG4gICAgYWNjUmVjdC5yaWdodCA9IG1pbihyZWN0LnJpZ2h0LCBhY2NSZWN0LnJpZ2h0KTtcbiAgICBhY2NSZWN0LmJvdHRvbSA9IG1pbihyZWN0LmJvdHRvbSwgYWNjUmVjdC5ib3R0b20pO1xuICAgIGFjY1JlY3QubGVmdCA9IG1heChyZWN0LmxlZnQsIGFjY1JlY3QubGVmdCk7XG4gICAgcmV0dXJuIGFjY1JlY3Q7XG4gIH0sIGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGZpcnN0Q2xpcHBpbmdQYXJlbnQpKTtcbiAgY2xpcHBpbmdSZWN0LndpZHRoID0gY2xpcHBpbmdSZWN0LnJpZ2h0IC0gY2xpcHBpbmdSZWN0LmxlZnQ7XG4gIGNsaXBwaW5nUmVjdC5oZWlnaHQgPSBjbGlwcGluZ1JlY3QuYm90dG9tIC0gY2xpcHBpbmdSZWN0LnRvcDtcbiAgY2xpcHBpbmdSZWN0LnggPSBjbGlwcGluZ1JlY3QubGVmdDtcbiAgY2xpcHBpbmdSZWN0LnkgPSBjbGlwcGluZ1JlY3QudG9wO1xuICByZXR1cm4gY2xpcHBpbmdSZWN0O1xufSIsImltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRWYXJpYXRpb24gZnJvbSBcIi4vZ2V0VmFyaWF0aW9uLmpzXCI7XG5pbXBvcnQgZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50IGZyb20gXCIuL2dldE1haW5BeGlzRnJvbVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0LCBzdGFydCwgZW5kIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb21wdXRlT2Zmc2V0cyhfcmVmKSB7XG4gIHZhciByZWZlcmVuY2UgPSBfcmVmLnJlZmVyZW5jZSxcbiAgICAgIGVsZW1lbnQgPSBfcmVmLmVsZW1lbnQsXG4gICAgICBwbGFjZW1lbnQgPSBfcmVmLnBsYWNlbWVudDtcbiAgdmFyIGJhc2VQbGFjZW1lbnQgPSBwbGFjZW1lbnQgPyBnZXRCYXNlUGxhY2VtZW50KHBsYWNlbWVudCkgOiBudWxsO1xuICB2YXIgdmFyaWF0aW9uID0gcGxhY2VtZW50ID8gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCkgOiBudWxsO1xuICB2YXIgY29tbW9uWCA9IHJlZmVyZW5jZS54ICsgcmVmZXJlbmNlLndpZHRoIC8gMiAtIGVsZW1lbnQud2lkdGggLyAyO1xuICB2YXIgY29tbW9uWSA9IHJlZmVyZW5jZS55ICsgcmVmZXJlbmNlLmhlaWdodCAvIDIgLSBlbGVtZW50LmhlaWdodCAvIDI7XG4gIHZhciBvZmZzZXRzO1xuXG4gIHN3aXRjaCAoYmFzZVBsYWNlbWVudCkge1xuICAgIGNhc2UgdG9wOlxuICAgICAgb2Zmc2V0cyA9IHtcbiAgICAgICAgeDogY29tbW9uWCxcbiAgICAgICAgeTogcmVmZXJlbmNlLnkgLSBlbGVtZW50LmhlaWdodFxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBib3R0b206XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiBjb21tb25YLFxuICAgICAgICB5OiByZWZlcmVuY2UueSArIHJlZmVyZW5jZS5oZWlnaHRcbiAgICAgIH07XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgcmlnaHQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCArIHJlZmVyZW5jZS53aWR0aCxcbiAgICAgICAgeTogY29tbW9uWVxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBsZWZ0OlxuICAgICAgb2Zmc2V0cyA9IHtcbiAgICAgICAgeDogcmVmZXJlbmNlLnggLSBlbGVtZW50LndpZHRoLFxuICAgICAgICB5OiBjb21tb25ZXG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgb2Zmc2V0cyA9IHtcbiAgICAgICAgeDogcmVmZXJlbmNlLngsXG4gICAgICAgIHk6IHJlZmVyZW5jZS55XG4gICAgICB9O1xuICB9XG5cbiAgdmFyIG1haW5BeGlzID0gYmFzZVBsYWNlbWVudCA/IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudChiYXNlUGxhY2VtZW50KSA6IG51bGw7XG5cbiAgaWYgKG1haW5BeGlzICE9IG51bGwpIHtcbiAgICB2YXIgbGVuID0gbWFpbkF4aXMgPT09ICd5JyA/ICdoZWlnaHQnIDogJ3dpZHRoJztcblxuICAgIHN3aXRjaCAodmFyaWF0aW9uKSB7XG4gICAgICBjYXNlIHN0YXJ0OlxuICAgICAgICBvZmZzZXRzW21haW5BeGlzXSA9IG9mZnNldHNbbWFpbkF4aXNdIC0gKHJlZmVyZW5jZVtsZW5dIC8gMiAtIGVsZW1lbnRbbGVuXSAvIDIpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBlbmQ6XG4gICAgICAgIG9mZnNldHNbbWFpbkF4aXNdID0gb2Zmc2V0c1ttYWluQXhpc10gKyAocmVmZXJlbmNlW2xlbl0gLyAyIC0gZWxlbWVudFtsZW5dIC8gMik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvZmZzZXRzO1xufSIsImltcG9ydCBnZXRDbGlwcGluZ1JlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBjb21wdXRlT2Zmc2V0cyBmcm9tIFwiLi9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuaW1wb3J0IHJlY3RUb0NsaWVudFJlY3QgZnJvbSBcIi4vcmVjdFRvQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IHsgY2xpcHBpbmdQYXJlbnRzLCByZWZlcmVuY2UsIHBvcHBlciwgYm90dG9tLCB0b3AsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdmlld3BvcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCB7IGlzRWxlbWVudCB9IGZyb20gXCIuLi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi9tZXJnZVBhZGRpbmdPYmplY3QuanNcIjtcbmltcG9ydCBleHBhbmRUb0hhc2hNYXAgZnJvbSBcIi4vZXhwYW5kVG9IYXNoTWFwLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBfb3B0aW9ucyRwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucyRwbGFjZW1lbnQgPT09IHZvaWQgMCA/IHN0YXRlLnBsYWNlbWVudCA6IF9vcHRpb25zJHBsYWNlbWVudCxcbiAgICAgIF9vcHRpb25zJGJvdW5kYXJ5ID0gX29wdGlvbnMuYm91bmRhcnksXG4gICAgICBib3VuZGFyeSA9IF9vcHRpb25zJGJvdW5kYXJ5ID09PSB2b2lkIDAgPyBjbGlwcGluZ1BhcmVudHMgOiBfb3B0aW9ucyRib3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJHJvb3RCb3VuZGFyeSA9IF9vcHRpb25zLnJvb3RCb3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeSA9IF9vcHRpb25zJHJvb3RCb3VuZGFyeSA9PT0gdm9pZCAwID8gdmlld3BvcnQgOiBfb3B0aW9ucyRyb290Qm91bmRhcnksXG4gICAgICBfb3B0aW9ucyRlbGVtZW50Q29udGUgPSBfb3B0aW9ucy5lbGVtZW50Q29udGV4dCxcbiAgICAgIGVsZW1lbnRDb250ZXh0ID0gX29wdGlvbnMkZWxlbWVudENvbnRlID09PSB2b2lkIDAgPyBwb3BwZXIgOiBfb3B0aW9ucyRlbGVtZW50Q29udGUsXG4gICAgICBfb3B0aW9ucyRhbHRCb3VuZGFyeSA9IF9vcHRpb25zLmFsdEJvdW5kYXJ5LFxuICAgICAgYWx0Qm91bmRhcnkgPSBfb3B0aW9ucyRhbHRCb3VuZGFyeSA9PT0gdm9pZCAwID8gZmFsc2UgOiBfb3B0aW9ucyRhbHRCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJHBhZGRpbmcgPSBfb3B0aW9ucy5wYWRkaW5nLFxuICAgICAgcGFkZGluZyA9IF9vcHRpb25zJHBhZGRpbmcgPT09IHZvaWQgMCA/IDAgOiBfb3B0aW9ucyRwYWRkaW5nO1xuICB2YXIgcGFkZGluZ09iamVjdCA9IG1lcmdlUGFkZGluZ09iamVjdCh0eXBlb2YgcGFkZGluZyAhPT0gJ251bWJlcicgPyBwYWRkaW5nIDogZXhwYW5kVG9IYXNoTWFwKHBhZGRpbmcsIGJhc2VQbGFjZW1lbnRzKSk7XG4gIHZhciBhbHRDb250ZXh0ID0gZWxlbWVudENvbnRleHQgPT09IHBvcHBlciA/IHJlZmVyZW5jZSA6IHBvcHBlcjtcbiAgdmFyIHBvcHBlclJlY3QgPSBzdGF0ZS5yZWN0cy5wb3BwZXI7XG4gIHZhciBlbGVtZW50ID0gc3RhdGUuZWxlbWVudHNbYWx0Qm91bmRhcnkgPyBhbHRDb250ZXh0IDogZWxlbWVudENvbnRleHRdO1xuICB2YXIgY2xpcHBpbmdDbGllbnRSZWN0ID0gZ2V0Q2xpcHBpbmdSZWN0KGlzRWxlbWVudChlbGVtZW50KSA/IGVsZW1lbnQgOiBlbGVtZW50LmNvbnRleHRFbGVtZW50IHx8IGdldERvY3VtZW50RWxlbWVudChzdGF0ZS5lbGVtZW50cy5wb3BwZXIpLCBib3VuZGFyeSwgcm9vdEJvdW5kYXJ5KTtcbiAgdmFyIHJlZmVyZW5jZUNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3Qoc3RhdGUuZWxlbWVudHMucmVmZXJlbmNlKTtcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBjb21wdXRlT2Zmc2V0cyh7XG4gICAgcmVmZXJlbmNlOiByZWZlcmVuY2VDbGllbnRSZWN0LFxuICAgIGVsZW1lbnQ6IHBvcHBlclJlY3QsXG4gICAgc3RyYXRlZ3k6ICdhYnNvbHV0ZScsXG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSk7XG4gIHZhciBwb3BwZXJDbGllbnRSZWN0ID0gcmVjdFRvQ2xpZW50UmVjdChPYmplY3QuYXNzaWduKHt9LCBwb3BwZXJSZWN0LCBwb3BwZXJPZmZzZXRzKSk7XG4gIHZhciBlbGVtZW50Q2xpZW50UmVjdCA9IGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgPyBwb3BwZXJDbGllbnRSZWN0IDogcmVmZXJlbmNlQ2xpZW50UmVjdDsgLy8gcG9zaXRpdmUgPSBvdmVyZmxvd2luZyB0aGUgY2xpcHBpbmcgcmVjdFxuICAvLyAwIG9yIG5lZ2F0aXZlID0gd2l0aGluIHRoZSBjbGlwcGluZyByZWN0XG5cbiAgdmFyIG92ZXJmbG93T2Zmc2V0cyA9IHtcbiAgICB0b3A6IGNsaXBwaW5nQ2xpZW50UmVjdC50b3AgLSBlbGVtZW50Q2xpZW50UmVjdC50b3AgKyBwYWRkaW5nT2JqZWN0LnRvcCxcbiAgICBib3R0b206IGVsZW1lbnRDbGllbnRSZWN0LmJvdHRvbSAtIGNsaXBwaW5nQ2xpZW50UmVjdC5ib3R0b20gKyBwYWRkaW5nT2JqZWN0LmJvdHRvbSxcbiAgICBsZWZ0OiBjbGlwcGluZ0NsaWVudFJlY3QubGVmdCAtIGVsZW1lbnRDbGllbnRSZWN0LmxlZnQgKyBwYWRkaW5nT2JqZWN0LmxlZnQsXG4gICAgcmlnaHQ6IGVsZW1lbnRDbGllbnRSZWN0LnJpZ2h0IC0gY2xpcHBpbmdDbGllbnRSZWN0LnJpZ2h0ICsgcGFkZGluZ09iamVjdC5yaWdodFxuICB9O1xuICB2YXIgb2Zmc2V0RGF0YSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0OyAvLyBPZmZzZXRzIGNhbiBiZSBhcHBsaWVkIG9ubHkgdG8gdGhlIHBvcHBlciBlbGVtZW50XG5cbiAgaWYgKGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgJiYgb2Zmc2V0RGF0YSkge1xuICAgIHZhciBvZmZzZXQgPSBvZmZzZXREYXRhW3BsYWNlbWVudF07XG4gICAgT2JqZWN0LmtleXMob3ZlcmZsb3dPZmZzZXRzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHZhciBtdWx0aXBseSA9IFtyaWdodCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/IDEgOiAtMTtcbiAgICAgIHZhciBheGlzID0gW3RvcCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/ICd5JyA6ICd4JztcbiAgICAgIG92ZXJmbG93T2Zmc2V0c1trZXldICs9IG9mZnNldFtheGlzXSAqIG11bHRpcGx5O1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG92ZXJmbG93T2Zmc2V0cztcbn0iLCJpbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuL2dldFZhcmlhdGlvbi5qc1wiO1xuaW1wb3J0IHsgdmFyaWF0aW9uUGxhY2VtZW50cywgYmFzZVBsYWNlbWVudHMsIHBsYWNlbWVudHMgYXMgYWxsUGxhY2VtZW50cyB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuaW1wb3J0IGRldGVjdE92ZXJmbG93IGZyb20gXCIuL2RldGVjdE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb21wdXRlQXV0b1BsYWNlbWVudChzdGF0ZSwgb3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG5cbiAgdmFyIF9vcHRpb25zID0gb3B0aW9ucyxcbiAgICAgIHBsYWNlbWVudCA9IF9vcHRpb25zLnBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5ID0gX29wdGlvbnMuYm91bmRhcnksXG4gICAgICByb290Qm91bmRhcnkgPSBfb3B0aW9ucy5yb290Qm91bmRhcnksXG4gICAgICBwYWRkaW5nID0gX29wdGlvbnMucGFkZGluZyxcbiAgICAgIGZsaXBWYXJpYXRpb25zID0gX29wdGlvbnMuZmxpcFZhcmlhdGlvbnMsXG4gICAgICBfb3B0aW9ucyRhbGxvd2VkQXV0b1AgPSBfb3B0aW9ucy5hbGxvd2VkQXV0b1BsYWNlbWVudHMsXG4gICAgICBhbGxvd2VkQXV0b1BsYWNlbWVudHMgPSBfb3B0aW9ucyRhbGxvd2VkQXV0b1AgPT09IHZvaWQgMCA/IGFsbFBsYWNlbWVudHMgOiBfb3B0aW9ucyRhbGxvd2VkQXV0b1A7XG4gIHZhciB2YXJpYXRpb24gPSBnZXRWYXJpYXRpb24ocGxhY2VtZW50KTtcbiAgdmFyIHBsYWNlbWVudHMgPSB2YXJpYXRpb24gPyBmbGlwVmFyaWF0aW9ucyA/IHZhcmlhdGlvblBsYWNlbWVudHMgOiB2YXJpYXRpb25QbGFjZW1lbnRzLmZpbHRlcihmdW5jdGlvbiAocGxhY2VtZW50KSB7XG4gICAgcmV0dXJuIGdldFZhcmlhdGlvbihwbGFjZW1lbnQpID09PSB2YXJpYXRpb247XG4gIH0pIDogYmFzZVBsYWNlbWVudHM7XG4gIHZhciBhbGxvd2VkUGxhY2VtZW50cyA9IHBsYWNlbWVudHMuZmlsdGVyKGZ1bmN0aW9uIChwbGFjZW1lbnQpIHtcbiAgICByZXR1cm4gYWxsb3dlZEF1dG9QbGFjZW1lbnRzLmluZGV4T2YocGxhY2VtZW50KSA+PSAwO1xuICB9KTtcblxuICBpZiAoYWxsb3dlZFBsYWNlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgYWxsb3dlZFBsYWNlbWVudHMgPSBwbGFjZW1lbnRzO1xuXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgY29uc29sZS5lcnJvcihbJ1BvcHBlcjogVGhlIGBhbGxvd2VkQXV0b1BsYWNlbWVudHNgIG9wdGlvbiBkaWQgbm90IGFsbG93IGFueScsICdwbGFjZW1lbnRzLiBFbnN1cmUgdGhlIGBwbGFjZW1lbnRgIG9wdGlvbiBtYXRjaGVzIHRoZSB2YXJpYXRpb24nLCAnb2YgdGhlIGFsbG93ZWQgcGxhY2VtZW50cy4nLCAnRm9yIGV4YW1wbGUsIFwiYXV0b1wiIGNhbm5vdCBiZSB1c2VkIHRvIGFsbG93IFwiYm90dG9tLXN0YXJ0XCIuJywgJ1VzZSBcImF1dG8tc3RhcnRcIiBpbnN0ZWFkLiddLmpvaW4oJyAnKSk7XG4gICAgfVxuICB9IC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXR5cGVdOiBGbG93IHNlZW1zIHRvIGhhdmUgcHJvYmxlbXMgd2l0aCB0d28gYXJyYXkgdW5pb25zLi4uXG5cblxuICB2YXIgb3ZlcmZsb3dzID0gYWxsb3dlZFBsYWNlbWVudHMucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICAgIGFjY1twbGFjZW1lbnRdID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICAgIHBsYWNlbWVudDogcGxhY2VtZW50LFxuICAgICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5OiByb290Qm91bmRhcnksXG4gICAgICBwYWRkaW5nOiBwYWRkaW5nXG4gICAgfSlbZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpXTtcbiAgICByZXR1cm4gYWNjO1xuICB9LCB7fSk7XG4gIHJldHVybiBPYmplY3Qua2V5cyhvdmVyZmxvd3MpLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dzW2FdIC0gb3ZlcmZsb3dzW2JdO1xuICB9KTtcbn0iLCJpbXBvcnQgZ2V0T3Bwb3NpdGVQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE9wcG9zaXRlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGRldGVjdE92ZXJmbG93IGZyb20gXCIuLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGNvbXB1dGVBdXRvUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9jb21wdXRlQXV0b1BsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgYm90dG9tLCB0b3AsIHN0YXJ0LCByaWdodCwgbGVmdCwgYXV0byB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi4vdXRpbHMvZ2V0VmFyaWF0aW9uLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZnVuY3Rpb24gZ2V0RXhwYW5kZWRGYWxsYmFja1BsYWNlbWVudHMocGxhY2VtZW50KSB7XG4gIGlmIChnZXRCYXNlUGxhY2VtZW50KHBsYWNlbWVudCkgPT09IGF1dG8pIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICB2YXIgb3Bwb3NpdGVQbGFjZW1lbnQgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuICByZXR1cm4gW2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50KHBsYWNlbWVudCksIG9wcG9zaXRlUGxhY2VtZW50LCBnZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudChvcHBvc2l0ZVBsYWNlbWVudCldO1xufVxuXG5mdW5jdGlvbiBmbGlwKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnMsXG4gICAgICBuYW1lID0gX3JlZi5uYW1lO1xuXG4gIGlmIChzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdLl9za2lwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIF9vcHRpb25zJG1haW5BeGlzID0gb3B0aW9ucy5tYWluQXhpcyxcbiAgICAgIGNoZWNrTWFpbkF4aXMgPSBfb3B0aW9ucyRtYWluQXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJG1haW5BeGlzLFxuICAgICAgX29wdGlvbnMkYWx0QXhpcyA9IG9wdGlvbnMuYWx0QXhpcyxcbiAgICAgIGNoZWNrQWx0QXhpcyA9IF9vcHRpb25zJGFsdEF4aXMgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRhbHRBeGlzLFxuICAgICAgc3BlY2lmaWVkRmFsbGJhY2tQbGFjZW1lbnRzID0gb3B0aW9ucy5mYWxsYmFja1BsYWNlbWVudHMsXG4gICAgICBwYWRkaW5nID0gb3B0aW9ucy5wYWRkaW5nLFxuICAgICAgYm91bmRhcnkgPSBvcHRpb25zLmJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gb3B0aW9ucy5yb290Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeSA9IG9wdGlvbnMuYWx0Qm91bmRhcnksXG4gICAgICBfb3B0aW9ucyRmbGlwVmFyaWF0aW8gPSBvcHRpb25zLmZsaXBWYXJpYXRpb25zLFxuICAgICAgZmxpcFZhcmlhdGlvbnMgPSBfb3B0aW9ucyRmbGlwVmFyaWF0aW8gPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRmbGlwVmFyaWF0aW8sXG4gICAgICBhbGxvd2VkQXV0b1BsYWNlbWVudHMgPSBvcHRpb25zLmFsbG93ZWRBdXRvUGxhY2VtZW50cztcbiAgdmFyIHByZWZlcnJlZFBsYWNlbWVudCA9IHN0YXRlLm9wdGlvbnMucGxhY2VtZW50O1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IGdldEJhc2VQbGFjZW1lbnQocHJlZmVycmVkUGxhY2VtZW50KTtcbiAgdmFyIGlzQmFzZVBsYWNlbWVudCA9IGJhc2VQbGFjZW1lbnQgPT09IHByZWZlcnJlZFBsYWNlbWVudDtcbiAgdmFyIGZhbGxiYWNrUGxhY2VtZW50cyA9IHNwZWNpZmllZEZhbGxiYWNrUGxhY2VtZW50cyB8fCAoaXNCYXNlUGxhY2VtZW50IHx8ICFmbGlwVmFyaWF0aW9ucyA/IFtnZXRPcHBvc2l0ZVBsYWNlbWVudChwcmVmZXJyZWRQbGFjZW1lbnQpXSA6IGdldEV4cGFuZGVkRmFsbGJhY2tQbGFjZW1lbnRzKHByZWZlcnJlZFBsYWNlbWVudCkpO1xuICB2YXIgcGxhY2VtZW50cyA9IFtwcmVmZXJyZWRQbGFjZW1lbnRdLmNvbmNhdChmYWxsYmFja1BsYWNlbWVudHMpLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgICByZXR1cm4gYWNjLmNvbmNhdChnZXRCYXNlUGxhY2VtZW50KHBsYWNlbWVudCkgPT09IGF1dG8gPyBjb21wdXRlQXV0b1BsYWNlbWVudChzdGF0ZSwge1xuICAgICAgcGxhY2VtZW50OiBwbGFjZW1lbnQsXG4gICAgICBib3VuZGFyeTogYm91bmRhcnksXG4gICAgICByb290Qm91bmRhcnk6IHJvb3RCb3VuZGFyeSxcbiAgICAgIHBhZGRpbmc6IHBhZGRpbmcsXG4gICAgICBmbGlwVmFyaWF0aW9uczogZmxpcFZhcmlhdGlvbnMsXG4gICAgICBhbGxvd2VkQXV0b1BsYWNlbWVudHM6IGFsbG93ZWRBdXRvUGxhY2VtZW50c1xuICAgIH0pIDogcGxhY2VtZW50KTtcbiAgfSwgW10pO1xuICB2YXIgcmVmZXJlbmNlUmVjdCA9IHN0YXRlLnJlY3RzLnJlZmVyZW5jZTtcbiAgdmFyIHBvcHBlclJlY3QgPSBzdGF0ZS5yZWN0cy5wb3BwZXI7XG4gIHZhciBjaGVja3NNYXAgPSBuZXcgTWFwKCk7XG4gIHZhciBtYWtlRmFsbGJhY2tDaGVja3MgPSB0cnVlO1xuICB2YXIgZmlyc3RGaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50c1swXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHBsYWNlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGxhY2VtZW50ID0gcGxhY2VtZW50c1tpXTtcblxuICAgIHZhciBfYmFzZVBsYWNlbWVudCA9IGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KTtcblxuICAgIHZhciBpc1N0YXJ0VmFyaWF0aW9uID0gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCkgPT09IHN0YXJ0O1xuICAgIHZhciBpc1ZlcnRpY2FsID0gW3RvcCwgYm90dG9tXS5pbmRleE9mKF9iYXNlUGxhY2VtZW50KSA+PSAwO1xuICAgIHZhciBsZW4gPSBpc1ZlcnRpY2FsID8gJ3dpZHRoJyA6ICdoZWlnaHQnO1xuICAgIHZhciBvdmVyZmxvdyA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgYWx0Qm91bmRhcnk6IGFsdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZ1xuICAgIH0pO1xuICAgIHZhciBtYWluVmFyaWF0aW9uU2lkZSA9IGlzVmVydGljYWwgPyBpc1N0YXJ0VmFyaWF0aW9uID8gcmlnaHQgOiBsZWZ0IDogaXNTdGFydFZhcmlhdGlvbiA/IGJvdHRvbSA6IHRvcDtcblxuICAgIGlmIChyZWZlcmVuY2VSZWN0W2xlbl0gPiBwb3BwZXJSZWN0W2xlbl0pIHtcbiAgICAgIG1haW5WYXJpYXRpb25TaWRlID0gZ2V0T3Bwb3NpdGVQbGFjZW1lbnQobWFpblZhcmlhdGlvblNpZGUpO1xuICAgIH1cblxuICAgIHZhciBhbHRWYXJpYXRpb25TaWRlID0gZ2V0T3Bwb3NpdGVQbGFjZW1lbnQobWFpblZhcmlhdGlvblNpZGUpO1xuICAgIHZhciBjaGVja3MgPSBbXTtcblxuICAgIGlmIChjaGVja01haW5BeGlzKSB7XG4gICAgICBjaGVja3MucHVzaChvdmVyZmxvd1tfYmFzZVBsYWNlbWVudF0gPD0gMCk7XG4gICAgfVxuXG4gICAgaWYgKGNoZWNrQWx0QXhpcykge1xuICAgICAgY2hlY2tzLnB1c2gob3ZlcmZsb3dbbWFpblZhcmlhdGlvblNpZGVdIDw9IDAsIG92ZXJmbG93W2FsdFZhcmlhdGlvblNpZGVdIDw9IDApO1xuICAgIH1cblxuICAgIGlmIChjaGVja3MuZXZlcnkoZnVuY3Rpb24gKGNoZWNrKSB7XG4gICAgICByZXR1cm4gY2hlY2s7XG4gICAgfSkpIHtcbiAgICAgIGZpcnN0Rml0dGluZ1BsYWNlbWVudCA9IHBsYWNlbWVudDtcbiAgICAgIG1ha2VGYWxsYmFja0NoZWNrcyA9IGZhbHNlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgY2hlY2tzTWFwLnNldChwbGFjZW1lbnQsIGNoZWNrcyk7XG4gIH1cblxuICBpZiAobWFrZUZhbGxiYWNrQ2hlY2tzKSB7XG4gICAgLy8gYDJgIG1heSBiZSBkZXNpcmVkIGluIHNvbWUgY2FzZXMg4oCTIHJlc2VhcmNoIGxhdGVyXG4gICAgdmFyIG51bWJlck9mQ2hlY2tzID0gZmxpcFZhcmlhdGlvbnMgPyAzIDogMTtcblxuICAgIHZhciBfbG9vcCA9IGZ1bmN0aW9uIF9sb29wKF9pKSB7XG4gICAgICB2YXIgZml0dGluZ1BsYWNlbWVudCA9IHBsYWNlbWVudHMuZmluZChmdW5jdGlvbiAocGxhY2VtZW50KSB7XG4gICAgICAgIHZhciBjaGVja3MgPSBjaGVja3NNYXAuZ2V0KHBsYWNlbWVudCk7XG5cbiAgICAgICAgaWYgKGNoZWNrcykge1xuICAgICAgICAgIHJldHVybiBjaGVja3Muc2xpY2UoMCwgX2kpLmV2ZXJ5KGZ1bmN0aW9uIChjaGVjaykge1xuICAgICAgICAgICAgcmV0dXJuIGNoZWNrO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKGZpdHRpbmdQbGFjZW1lbnQpIHtcbiAgICAgICAgZmlyc3RGaXR0aW5nUGxhY2VtZW50ID0gZml0dGluZ1BsYWNlbWVudDtcbiAgICAgICAgcmV0dXJuIFwiYnJlYWtcIjtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yICh2YXIgX2kgPSBudW1iZXJPZkNoZWNrczsgX2kgPiAwOyBfaS0tKSB7XG4gICAgICB2YXIgX3JldCA9IF9sb29wKF9pKTtcblxuICAgICAgaWYgKF9yZXQgPT09IFwiYnJlYWtcIikgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKHN0YXRlLnBsYWNlbWVudCAhPT0gZmlyc3RGaXR0aW5nUGxhY2VtZW50KSB7XG4gICAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXS5fc2tpcCA9IHRydWU7XG4gICAgc3RhdGUucGxhY2VtZW50ID0gZmlyc3RGaXR0aW5nUGxhY2VtZW50O1xuICAgIHN0YXRlLnJlc2V0ID0gdHJ1ZTtcbiAgfVxufSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAnZmxpcCcsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBmbGlwLFxuICByZXF1aXJlc0lmRXhpc3RzOiBbJ29mZnNldCddLFxuICBkYXRhOiB7XG4gICAgX3NraXA6IGZhbHNlXG4gIH1cbn07IiwiaW1wb3J0IHsgdG9wLCBib3R0b20sIGxlZnQsIHJpZ2h0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5cbmZ1bmN0aW9uIGdldFNpZGVPZmZzZXRzKG92ZXJmbG93LCByZWN0LCBwcmV2ZW50ZWRPZmZzZXRzKSB7XG4gIGlmIChwcmV2ZW50ZWRPZmZzZXRzID09PSB2b2lkIDApIHtcbiAgICBwcmV2ZW50ZWRPZmZzZXRzID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0b3A6IG92ZXJmbG93LnRvcCAtIHJlY3QuaGVpZ2h0IC0gcHJldmVudGVkT2Zmc2V0cy55LFxuICAgIHJpZ2h0OiBvdmVyZmxvdy5yaWdodCAtIHJlY3Qud2lkdGggKyBwcmV2ZW50ZWRPZmZzZXRzLngsXG4gICAgYm90dG9tOiBvdmVyZmxvdy5ib3R0b20gLSByZWN0LmhlaWdodCArIHByZXZlbnRlZE9mZnNldHMueSxcbiAgICBsZWZ0OiBvdmVyZmxvdy5sZWZ0IC0gcmVjdC53aWR0aCAtIHByZXZlbnRlZE9mZnNldHMueFxuICB9O1xufVxuXG5mdW5jdGlvbiBpc0FueVNpZGVGdWxseUNsaXBwZWQob3ZlcmZsb3cpIHtcbiAgcmV0dXJuIFt0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRdLnNvbWUoZnVuY3Rpb24gKHNpZGUpIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dbc2lkZV0gPj0gMDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGhpZGUoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgcHJldmVudGVkT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucHJldmVudE92ZXJmbG93O1xuICB2YXIgcmVmZXJlbmNlT3ZlcmZsb3cgPSBkZXRlY3RPdmVyZmxvdyhzdGF0ZSwge1xuICAgIGVsZW1lbnRDb250ZXh0OiAncmVmZXJlbmNlJ1xuICB9KTtcbiAgdmFyIHBvcHBlckFsdE92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICBhbHRCb3VuZGFyeTogdHJ1ZVxuICB9KTtcbiAgdmFyIHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyA9IGdldFNpZGVPZmZzZXRzKHJlZmVyZW5jZU92ZXJmbG93LCByZWZlcmVuY2VSZWN0KTtcbiAgdmFyIHBvcHBlckVzY2FwZU9mZnNldHMgPSBnZXRTaWRlT2Zmc2V0cyhwb3BwZXJBbHRPdmVyZmxvdywgcG9wcGVyUmVjdCwgcHJldmVudGVkT2Zmc2V0cyk7XG4gIHZhciBpc1JlZmVyZW5jZUhpZGRlbiA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChyZWZlcmVuY2VDbGlwcGluZ09mZnNldHMpO1xuICB2YXIgaGFzUG9wcGVyRXNjYXBlZCA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChwb3BwZXJFc2NhcGVPZmZzZXRzKTtcbiAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXSA9IHtcbiAgICByZWZlcmVuY2VDbGlwcGluZ09mZnNldHM6IHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyxcbiAgICBwb3BwZXJFc2NhcGVPZmZzZXRzOiBwb3BwZXJFc2NhcGVPZmZzZXRzLFxuICAgIGlzUmVmZXJlbmNlSGlkZGVuOiBpc1JlZmVyZW5jZUhpZGRlbixcbiAgICBoYXNQb3BwZXJFc2NhcGVkOiBoYXNQb3BwZXJFc2NhcGVkXG4gIH07XG4gIHN0YXRlLmF0dHJpYnV0ZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIsIHtcbiAgICAnZGF0YS1wb3BwZXItcmVmZXJlbmNlLWhpZGRlbic6IGlzUmVmZXJlbmNlSGlkZGVuLFxuICAgICdkYXRhLXBvcHBlci1lc2NhcGVkJzogaGFzUG9wcGVyRXNjYXBlZFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2hpZGUnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ21haW4nLFxuICByZXF1aXJlc0lmRXhpc3RzOiBbJ3ByZXZlbnRPdmVyZmxvdyddLFxuICBmbjogaGlkZVxufTsiLCJpbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgdG9wLCBsZWZ0LCByaWdodCwgcGxhY2VtZW50cyB9IGZyb20gXCIuLi9lbnVtcy5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbmV4cG9ydCBmdW5jdGlvbiBkaXN0YW5jZUFuZFNraWRkaW5nVG9YWShwbGFjZW1lbnQsIHJlY3RzLCBvZmZzZXQpIHtcbiAgdmFyIGJhc2VQbGFjZW1lbnQgPSBnZXRCYXNlUGxhY2VtZW50KHBsYWNlbWVudCk7XG4gIHZhciBpbnZlcnREaXN0YW5jZSA9IFtsZWZ0LCB0b3BdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgPj0gMCA/IC0xIDogMTtcblxuICB2YXIgX3JlZiA9IHR5cGVvZiBvZmZzZXQgPT09ICdmdW5jdGlvbicgPyBvZmZzZXQoT2JqZWN0LmFzc2lnbih7fSwgcmVjdHMsIHtcbiAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudFxuICB9KSkgOiBvZmZzZXQsXG4gICAgICBza2lkZGluZyA9IF9yZWZbMF0sXG4gICAgICBkaXN0YW5jZSA9IF9yZWZbMV07XG5cbiAgc2tpZGRpbmcgPSBza2lkZGluZyB8fCAwO1xuICBkaXN0YW5jZSA9IChkaXN0YW5jZSB8fCAwKSAqIGludmVydERpc3RhbmNlO1xuICByZXR1cm4gW2xlZnQsIHJpZ2h0XS5pbmRleE9mKGJhc2VQbGFjZW1lbnQpID49IDAgPyB7XG4gICAgeDogZGlzdGFuY2UsXG4gICAgeTogc2tpZGRpbmdcbiAgfSA6IHtcbiAgICB4OiBza2lkZGluZyxcbiAgICB5OiBkaXN0YW5jZVxuICB9O1xufVxuXG5mdW5jdGlvbiBvZmZzZXQoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZjIub3B0aW9ucyxcbiAgICAgIG5hbWUgPSBfcmVmMi5uYW1lO1xuICB2YXIgX29wdGlvbnMkb2Zmc2V0ID0gb3B0aW9ucy5vZmZzZXQsXG4gICAgICBvZmZzZXQgPSBfb3B0aW9ucyRvZmZzZXQgPT09IHZvaWQgMCA/IFswLCAwXSA6IF9vcHRpb25zJG9mZnNldDtcbiAgdmFyIGRhdGEgPSBwbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgICBhY2NbcGxhY2VtZW50XSA9IGRpc3RhbmNlQW5kU2tpZGRpbmdUb1hZKHBsYWNlbWVudCwgc3RhdGUucmVjdHMsIG9mZnNldCk7XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xuICB2YXIgX2RhdGEkc3RhdGUkcGxhY2VtZW50ID0gZGF0YVtzdGF0ZS5wbGFjZW1lbnRdLFxuICAgICAgeCA9IF9kYXRhJHN0YXRlJHBsYWNlbWVudC54LFxuICAgICAgeSA9IF9kYXRhJHN0YXRlJHBsYWNlbWVudC55O1xuXG4gIGlmIChzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMgIT0gbnVsbCkge1xuICAgIHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cy54ICs9IHg7XG4gICAgc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzLnkgKz0geTtcbiAgfVxuXG4gIHN0YXRlLm1vZGlmaWVyc0RhdGFbbmFtZV0gPSBkYXRhO1xufSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAnb2Zmc2V0JyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdtYWluJyxcbiAgcmVxdWlyZXM6IFsncG9wcGVyT2Zmc2V0cyddLFxuICBmbjogb2Zmc2V0XG59OyIsImltcG9ydCBjb21wdXRlT2Zmc2V0cyBmcm9tIFwiLi4vdXRpbHMvY29tcHV0ZU9mZnNldHMuanNcIjtcblxuZnVuY3Rpb24gcG9wcGVyT2Zmc2V0cyhfcmVmKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYuc3RhdGUsXG4gICAgICBuYW1lID0gX3JlZi5uYW1lO1xuICAvLyBPZmZzZXRzIGFyZSB0aGUgYWN0dWFsIHBvc2l0aW9uIHRoZSBwb3BwZXIgbmVlZHMgdG8gaGF2ZSB0byBiZVxuICAvLyBwcm9wZXJseSBwb3NpdGlvbmVkIG5lYXIgaXRzIHJlZmVyZW5jZSBlbGVtZW50XG4gIC8vIFRoaXMgaXMgdGhlIG1vc3QgYmFzaWMgcGxhY2VtZW50LCBhbmQgd2lsbCBiZSBhZGp1c3RlZCBieVxuICAvLyB0aGUgbW9kaWZpZXJzIGluIHRoZSBuZXh0IHN0ZXBcbiAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXSA9IGNvbXB1dGVPZmZzZXRzKHtcbiAgICByZWZlcmVuY2U6IHN0YXRlLnJlY3RzLnJlZmVyZW5jZSxcbiAgICBlbGVtZW50OiBzdGF0ZS5yZWN0cy5wb3BwZXIsXG4gICAgc3RyYXRlZ3k6ICdhYnNvbHV0ZScsXG4gICAgcGxhY2VtZW50OiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSk7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdwb3BwZXJPZmZzZXRzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdyZWFkJyxcbiAgZm46IHBvcHBlck9mZnNldHMsXG4gIGRhdGE6IHt9XG59OyIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEFsdEF4aXMoYXhpcykge1xuICByZXR1cm4gYXhpcyA9PT0gJ3gnID8gJ3knIDogJ3gnO1xufSIsImltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgc3RhcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRBbHRBeGlzIGZyb20gXCIuLi91dGlscy9nZXRBbHRBeGlzLmpzXCI7XG5pbXBvcnQgeyB3aXRoaW4sIHdpdGhpbk1heENsYW1wIH0gZnJvbSBcIi4uL3V0aWxzL3dpdGhpbi5qc1wiO1xuaW1wb3J0IGdldExheW91dFJlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCBnZXRGcmVzaFNpZGVPYmplY3QgZnJvbSBcIi4uL3V0aWxzL2dldEZyZXNoU2lkZU9iamVjdC5qc1wiO1xuaW1wb3J0IHsgbWluIGFzIG1hdGhNaW4sIG1heCBhcyBtYXRoTWF4IH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcblxuZnVuY3Rpb24gcHJldmVudE92ZXJmbG93KF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnMsXG4gICAgICBuYW1lID0gX3JlZi5uYW1lO1xuICB2YXIgX29wdGlvbnMkbWFpbkF4aXMgPSBvcHRpb25zLm1haW5BeGlzLFxuICAgICAgY2hlY2tNYWluQXhpcyA9IF9vcHRpb25zJG1haW5BeGlzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkbWFpbkF4aXMsXG4gICAgICBfb3B0aW9ucyRhbHRBeGlzID0gb3B0aW9ucy5hbHRBeGlzLFxuICAgICAgY2hlY2tBbHRBeGlzID0gX29wdGlvbnMkYWx0QXhpcyA9PT0gdm9pZCAwID8gZmFsc2UgOiBfb3B0aW9ucyRhbHRBeGlzLFxuICAgICAgYm91bmRhcnkgPSBvcHRpb25zLmJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gb3B0aW9ucy5yb290Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeSA9IG9wdGlvbnMuYWx0Qm91bmRhcnksXG4gICAgICBwYWRkaW5nID0gb3B0aW9ucy5wYWRkaW5nLFxuICAgICAgX29wdGlvbnMkdGV0aGVyID0gb3B0aW9ucy50ZXRoZXIsXG4gICAgICB0ZXRoZXIgPSBfb3B0aW9ucyR0ZXRoZXIgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyR0ZXRoZXIsXG4gICAgICBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQgPSBvcHRpb25zLnRldGhlck9mZnNldCxcbiAgICAgIHRldGhlck9mZnNldCA9IF9vcHRpb25zJHRldGhlck9mZnNldCA9PT0gdm9pZCAwID8gMCA6IF9vcHRpb25zJHRldGhlck9mZnNldDtcbiAgdmFyIG92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICBib3VuZGFyeTogYm91bmRhcnksXG4gICAgcm9vdEJvdW5kYXJ5OiByb290Qm91bmRhcnksXG4gICAgcGFkZGluZzogcGFkZGluZyxcbiAgICBhbHRCb3VuZGFyeTogYWx0Qm91bmRhcnlcbiAgfSk7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgdmFyaWF0aW9uID0gZ2V0VmFyaWF0aW9uKHN0YXRlLnBsYWNlbWVudCk7XG4gIHZhciBpc0Jhc2VQbGFjZW1lbnQgPSAhdmFyaWF0aW9uO1xuICB2YXIgbWFpbkF4aXMgPSBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQoYmFzZVBsYWNlbWVudCk7XG4gIHZhciBhbHRBeGlzID0gZ2V0QWx0QXhpcyhtYWluQXhpcyk7XG4gIHZhciBwb3BwZXJPZmZzZXRzID0gc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzO1xuICB2YXIgcmVmZXJlbmNlUmVjdCA9IHN0YXRlLnJlY3RzLnJlZmVyZW5jZTtcbiAgdmFyIHBvcHBlclJlY3QgPSBzdGF0ZS5yZWN0cy5wb3BwZXI7XG4gIHZhciB0ZXRoZXJPZmZzZXRWYWx1ZSA9IHR5cGVvZiB0ZXRoZXJPZmZzZXQgPT09ICdmdW5jdGlvbicgPyB0ZXRoZXJPZmZzZXQoT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVjdHMsIHtcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KSkgOiB0ZXRoZXJPZmZzZXQ7XG4gIHZhciBub3JtYWxpemVkVGV0aGVyT2Zmc2V0VmFsdWUgPSB0eXBlb2YgdGV0aGVyT2Zmc2V0VmFsdWUgPT09ICdudW1iZXInID8ge1xuICAgIG1haW5BeGlzOiB0ZXRoZXJPZmZzZXRWYWx1ZSxcbiAgICBhbHRBeGlzOiB0ZXRoZXJPZmZzZXRWYWx1ZVxuICB9IDogT2JqZWN0LmFzc2lnbih7XG4gICAgbWFpbkF4aXM6IDAsXG4gICAgYWx0QXhpczogMFxuICB9LCB0ZXRoZXJPZmZzZXRWYWx1ZSk7XG4gIHZhciBvZmZzZXRNb2RpZmllclN0YXRlID0gc3RhdGUubW9kaWZpZXJzRGF0YS5vZmZzZXQgPyBzdGF0ZS5tb2RpZmllcnNEYXRhLm9mZnNldFtzdGF0ZS5wbGFjZW1lbnRdIDogbnVsbDtcbiAgdmFyIGRhdGEgPSB7XG4gICAgeDogMCxcbiAgICB5OiAwXG4gIH07XG5cbiAgaWYgKCFwb3BwZXJPZmZzZXRzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGNoZWNrTWFpbkF4aXMpIHtcbiAgICB2YXIgX29mZnNldE1vZGlmaWVyU3RhdGUkO1xuXG4gICAgdmFyIG1haW5TaWRlID0gbWFpbkF4aXMgPT09ICd5JyA/IHRvcCA6IGxlZnQ7XG4gICAgdmFyIGFsdFNpZGUgPSBtYWluQXhpcyA9PT0gJ3knID8gYm90dG9tIDogcmlnaHQ7XG4gICAgdmFyIGxlbiA9IG1haW5BeGlzID09PSAneScgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG4gICAgdmFyIG9mZnNldCA9IHBvcHBlck9mZnNldHNbbWFpbkF4aXNdO1xuICAgIHZhciBtaW4gPSBvZmZzZXQgKyBvdmVyZmxvd1ttYWluU2lkZV07XG4gICAgdmFyIG1heCA9IG9mZnNldCAtIG92ZXJmbG93W2FsdFNpZGVdO1xuICAgIHZhciBhZGRpdGl2ZSA9IHRldGhlciA/IC1wb3BwZXJSZWN0W2xlbl0gLyAyIDogMDtcbiAgICB2YXIgbWluTGVuID0gdmFyaWF0aW9uID09PSBzdGFydCA/IHJlZmVyZW5jZVJlY3RbbGVuXSA6IHBvcHBlclJlY3RbbGVuXTtcbiAgICB2YXIgbWF4TGVuID0gdmFyaWF0aW9uID09PSBzdGFydCA/IC1wb3BwZXJSZWN0W2xlbl0gOiAtcmVmZXJlbmNlUmVjdFtsZW5dOyAvLyBXZSBuZWVkIHRvIGluY2x1ZGUgdGhlIGFycm93IGluIHRoZSBjYWxjdWxhdGlvbiBzbyB0aGUgYXJyb3cgZG9lc24ndCBnb1xuICAgIC8vIG91dHNpZGUgdGhlIHJlZmVyZW5jZSBib3VuZHNcblxuICAgIHZhciBhcnJvd0VsZW1lbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdztcbiAgICB2YXIgYXJyb3dSZWN0ID0gdGV0aGVyICYmIGFycm93RWxlbWVudCA/IGdldExheW91dFJlY3QoYXJyb3dFbGVtZW50KSA6IHtcbiAgICAgIHdpZHRoOiAwLFxuICAgICAgaGVpZ2h0OiAwXG4gICAgfTtcbiAgICB2YXIgYXJyb3dQYWRkaW5nT2JqZWN0ID0gc3RhdGUubW9kaWZpZXJzRGF0YVsnYXJyb3cjcGVyc2lzdGVudCddID8gc3RhdGUubW9kaWZpZXJzRGF0YVsnYXJyb3cjcGVyc2lzdGVudCddLnBhZGRpbmcgOiBnZXRGcmVzaFNpZGVPYmplY3QoKTtcbiAgICB2YXIgYXJyb3dQYWRkaW5nTWluID0gYXJyb3dQYWRkaW5nT2JqZWN0W21haW5TaWRlXTtcbiAgICB2YXIgYXJyb3dQYWRkaW5nTWF4ID0gYXJyb3dQYWRkaW5nT2JqZWN0W2FsdFNpZGVdOyAvLyBJZiB0aGUgcmVmZXJlbmNlIGxlbmd0aCBpcyBzbWFsbGVyIHRoYW4gdGhlIGFycm93IGxlbmd0aCwgd2UgZG9uJ3Qgd2FudFxuICAgIC8vIHRvIGluY2x1ZGUgaXRzIGZ1bGwgc2l6ZSBpbiB0aGUgY2FsY3VsYXRpb24uIElmIHRoZSByZWZlcmVuY2UgaXMgc21hbGxcbiAgICAvLyBhbmQgbmVhciB0aGUgZWRnZSBvZiBhIGJvdW5kYXJ5LCB0aGUgcG9wcGVyIGNhbiBvdmVyZmxvdyBldmVuIGlmIHRoZVxuICAgIC8vIHJlZmVyZW5jZSBpcyBub3Qgb3ZlcmZsb3dpbmcgYXMgd2VsbCAoZS5nLiB2aXJ0dWFsIGVsZW1lbnRzIHdpdGggbm9cbiAgICAvLyB3aWR0aCBvciBoZWlnaHQpXG5cbiAgICB2YXIgYXJyb3dMZW4gPSB3aXRoaW4oMCwgcmVmZXJlbmNlUmVjdFtsZW5dLCBhcnJvd1JlY3RbbGVuXSk7XG4gICAgdmFyIG1pbk9mZnNldCA9IGlzQmFzZVBsYWNlbWVudCA/IHJlZmVyZW5jZVJlY3RbbGVuXSAvIDIgLSBhZGRpdGl2ZSAtIGFycm93TGVuIC0gYXJyb3dQYWRkaW5nTWluIC0gbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLm1haW5BeGlzIDogbWluTGVuIC0gYXJyb3dMZW4gLSBhcnJvd1BhZGRpbmdNaW4gLSBub3JtYWxpemVkVGV0aGVyT2Zmc2V0VmFsdWUubWFpbkF4aXM7XG4gICAgdmFyIG1heE9mZnNldCA9IGlzQmFzZVBsYWNlbWVudCA/IC1yZWZlcmVuY2VSZWN0W2xlbl0gLyAyICsgYWRkaXRpdmUgKyBhcnJvd0xlbiArIGFycm93UGFkZGluZ01heCArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcyA6IG1heExlbiArIGFycm93TGVuICsgYXJyb3dQYWRkaW5nTWF4ICsgbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLm1haW5BeGlzO1xuICAgIHZhciBhcnJvd09mZnNldFBhcmVudCA9IHN0YXRlLmVsZW1lbnRzLmFycm93ICYmIGdldE9mZnNldFBhcmVudChzdGF0ZS5lbGVtZW50cy5hcnJvdyk7XG4gICAgdmFyIGNsaWVudE9mZnNldCA9IGFycm93T2Zmc2V0UGFyZW50ID8gbWFpbkF4aXMgPT09ICd5JyA/IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudFRvcCB8fCAwIDogYXJyb3dPZmZzZXRQYXJlbnQuY2xpZW50TGVmdCB8fCAwIDogMDtcbiAgICB2YXIgb2Zmc2V0TW9kaWZpZXJWYWx1ZSA9IChfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQgPSBvZmZzZXRNb2RpZmllclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBvZmZzZXRNb2RpZmllclN0YXRlW21haW5BeGlzXSkgIT0gbnVsbCA/IF9vZmZzZXRNb2RpZmllclN0YXRlJCA6IDA7XG4gICAgdmFyIHRldGhlck1pbiA9IG9mZnNldCArIG1pbk9mZnNldCAtIG9mZnNldE1vZGlmaWVyVmFsdWUgLSBjbGllbnRPZmZzZXQ7XG4gICAgdmFyIHRldGhlck1heCA9IG9mZnNldCArIG1heE9mZnNldCAtIG9mZnNldE1vZGlmaWVyVmFsdWU7XG4gICAgdmFyIHByZXZlbnRlZE9mZnNldCA9IHdpdGhpbih0ZXRoZXIgPyBtYXRoTWluKG1pbiwgdGV0aGVyTWluKSA6IG1pbiwgb2Zmc2V0LCB0ZXRoZXIgPyBtYXRoTWF4KG1heCwgdGV0aGVyTWF4KSA6IG1heCk7XG4gICAgcG9wcGVyT2Zmc2V0c1ttYWluQXhpc10gPSBwcmV2ZW50ZWRPZmZzZXQ7XG4gICAgZGF0YVttYWluQXhpc10gPSBwcmV2ZW50ZWRPZmZzZXQgLSBvZmZzZXQ7XG4gIH1cblxuICBpZiAoY2hlY2tBbHRBeGlzKSB7XG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclN0YXRlJDI7XG5cbiAgICB2YXIgX21haW5TaWRlID0gbWFpbkF4aXMgPT09ICd4JyA/IHRvcCA6IGxlZnQ7XG5cbiAgICB2YXIgX2FsdFNpZGUgPSBtYWluQXhpcyA9PT0gJ3gnID8gYm90dG9tIDogcmlnaHQ7XG5cbiAgICB2YXIgX29mZnNldCA9IHBvcHBlck9mZnNldHNbYWx0QXhpc107XG5cbiAgICB2YXIgX2xlbiA9IGFsdEF4aXMgPT09ICd5JyA/ICdoZWlnaHQnIDogJ3dpZHRoJztcblxuICAgIHZhciBfbWluID0gX29mZnNldCArIG92ZXJmbG93W19tYWluU2lkZV07XG5cbiAgICB2YXIgX21heCA9IF9vZmZzZXQgLSBvdmVyZmxvd1tfYWx0U2lkZV07XG5cbiAgICB2YXIgaXNPcmlnaW5TaWRlID0gW3RvcCwgbGVmdF0uaW5kZXhPZihiYXNlUGxhY2VtZW50KSAhPT0gLTE7XG5cbiAgICB2YXIgX29mZnNldE1vZGlmaWVyVmFsdWUgPSAoX29mZnNldE1vZGlmaWVyU3RhdGUkMiA9IG9mZnNldE1vZGlmaWVyU3RhdGUgPT0gbnVsbCA/IHZvaWQgMCA6IG9mZnNldE1vZGlmaWVyU3RhdGVbYWx0QXhpc10pICE9IG51bGwgPyBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQyIDogMDtcblxuICAgIHZhciBfdGV0aGVyTWluID0gaXNPcmlnaW5TaWRlID8gX21pbiA6IF9vZmZzZXQgLSByZWZlcmVuY2VSZWN0W19sZW5dIC0gcG9wcGVyUmVjdFtfbGVuXSAtIF9vZmZzZXRNb2RpZmllclZhbHVlICsgbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLmFsdEF4aXM7XG5cbiAgICB2YXIgX3RldGhlck1heCA9IGlzT3JpZ2luU2lkZSA/IF9vZmZzZXQgKyByZWZlcmVuY2VSZWN0W19sZW5dICsgcG9wcGVyUmVjdFtfbGVuXSAtIF9vZmZzZXRNb2RpZmllclZhbHVlIC0gbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLmFsdEF4aXMgOiBfbWF4O1xuXG4gICAgdmFyIF9wcmV2ZW50ZWRPZmZzZXQgPSB0ZXRoZXIgJiYgaXNPcmlnaW5TaWRlID8gd2l0aGluTWF4Q2xhbXAoX3RldGhlck1pbiwgX29mZnNldCwgX3RldGhlck1heCkgOiB3aXRoaW4odGV0aGVyID8gX3RldGhlck1pbiA6IF9taW4sIF9vZmZzZXQsIHRldGhlciA/IF90ZXRoZXJNYXggOiBfbWF4KTtcblxuICAgIHBvcHBlck9mZnNldHNbYWx0QXhpc10gPSBfcHJldmVudGVkT2Zmc2V0O1xuICAgIGRhdGFbYWx0QXhpc10gPSBfcHJldmVudGVkT2Zmc2V0IC0gX29mZnNldDtcbiAgfVxuXG4gIHN0YXRlLm1vZGlmaWVyc0RhdGFbbmFtZV0gPSBkYXRhO1xufSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAncHJldmVudE92ZXJmbG93JyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdtYWluJyxcbiAgZm46IHByZXZlbnRPdmVyZmxvdyxcbiAgcmVxdWlyZXNJZkV4aXN0czogWydvZmZzZXQnXVxufTsiLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRIVE1MRWxlbWVudFNjcm9sbChlbGVtZW50KSB7XG4gIHJldHVybiB7XG4gICAgc2Nyb2xsTGVmdDogZWxlbWVudC5zY3JvbGxMZWZ0LFxuICAgIHNjcm9sbFRvcDogZWxlbWVudC5zY3JvbGxUb3BcbiAgfTtcbn0iLCJpbXBvcnQgZ2V0V2luZG93U2Nyb2xsIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0SFRNTEVsZW1lbnRTY3JvbGwgZnJvbSBcIi4vZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE5vZGVTY3JvbGwobm9kZSkge1xuICBpZiAobm9kZSA9PT0gZ2V0V2luZG93KG5vZGUpIHx8ICFpc0hUTUxFbGVtZW50KG5vZGUpKSB7XG4gICAgcmV0dXJuIGdldFdpbmRvd1Njcm9sbChub2RlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZ2V0SFRNTEVsZW1lbnRTY3JvbGwobm9kZSk7XG4gIH1cbn0iLCJpbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IGdldE5vZGVTY3JvbGwgZnJvbSBcIi4vZ2V0Tm9kZVNjcm9sbC5qc1wiO1xuaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbEJhclggZnJvbSBcIi4vZ2V0V2luZG93U2Nyb2xsQmFyWC5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50RWxlbWVudCBmcm9tIFwiLi9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBpc1Njcm9sbFBhcmVudCBmcm9tIFwiLi9pc1Njcm9sbFBhcmVudC5qc1wiO1xuaW1wb3J0IHsgcm91bmQgfSBmcm9tIFwiLi4vdXRpbHMvbWF0aC5qc1wiO1xuXG5mdW5jdGlvbiBpc0VsZW1lbnRTY2FsZWQoZWxlbWVudCkge1xuICB2YXIgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIHZhciBzY2FsZVggPSByb3VuZChyZWN0LndpZHRoKSAvIGVsZW1lbnQub2Zmc2V0V2lkdGggfHwgMTtcbiAgdmFyIHNjYWxlWSA9IHJvdW5kKHJlY3QuaGVpZ2h0KSAvIGVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IDE7XG4gIHJldHVybiBzY2FsZVggIT09IDEgfHwgc2NhbGVZICE9PSAxO1xufSAvLyBSZXR1cm5zIHRoZSBjb21wb3NpdGUgcmVjdCBvZiBhbiBlbGVtZW50IHJlbGF0aXZlIHRvIGl0cyBvZmZzZXRQYXJlbnQuXG4vLyBDb21wb3NpdGUgbWVhbnMgaXQgdGFrZXMgaW50byBhY2NvdW50IHRyYW5zZm9ybXMgYXMgd2VsbCBhcyBsYXlvdXQuXG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Q29tcG9zaXRlUmVjdChlbGVtZW50T3JWaXJ0dWFsRWxlbWVudCwgb2Zmc2V0UGFyZW50LCBpc0ZpeGVkKSB7XG4gIGlmIChpc0ZpeGVkID09PSB2b2lkIDApIHtcbiAgICBpc0ZpeGVkID0gZmFsc2U7XG4gIH1cblxuICB2YXIgaXNPZmZzZXRQYXJlbnRBbkVsZW1lbnQgPSBpc0hUTUxFbGVtZW50KG9mZnNldFBhcmVudCk7XG4gIHZhciBvZmZzZXRQYXJlbnRJc1NjYWxlZCA9IGlzSFRNTEVsZW1lbnQob2Zmc2V0UGFyZW50KSAmJiBpc0VsZW1lbnRTY2FsZWQob2Zmc2V0UGFyZW50KTtcbiAgdmFyIGRvY3VtZW50RWxlbWVudCA9IGdldERvY3VtZW50RWxlbWVudChvZmZzZXRQYXJlbnQpO1xuICB2YXIgcmVjdCA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChlbGVtZW50T3JWaXJ0dWFsRWxlbWVudCwgb2Zmc2V0UGFyZW50SXNTY2FsZWQpO1xuICB2YXIgc2Nyb2xsID0ge1xuICAgIHNjcm9sbExlZnQ6IDAsXG4gICAgc2Nyb2xsVG9wOiAwXG4gIH07XG4gIHZhciBvZmZzZXRzID0ge1xuICAgIHg6IDAsXG4gICAgeTogMFxuICB9O1xuXG4gIGlmIChpc09mZnNldFBhcmVudEFuRWxlbWVudCB8fCAhaXNPZmZzZXRQYXJlbnRBbkVsZW1lbnQgJiYgIWlzRml4ZWQpIHtcbiAgICBpZiAoZ2V0Tm9kZU5hbWUob2Zmc2V0UGFyZW50KSAhPT0gJ2JvZHknIHx8IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wb3BwZXJqcy9wb3BwZXItY29yZS9pc3N1ZXMvMTA3OFxuICAgIGlzU2Nyb2xsUGFyZW50KGRvY3VtZW50RWxlbWVudCkpIHtcbiAgICAgIHNjcm9sbCA9IGdldE5vZGVTY3JvbGwob2Zmc2V0UGFyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoaXNIVE1MRWxlbWVudChvZmZzZXRQYXJlbnQpKSB7XG4gICAgICBvZmZzZXRzID0gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KG9mZnNldFBhcmVudCwgdHJ1ZSk7XG4gICAgICBvZmZzZXRzLnggKz0gb2Zmc2V0UGFyZW50LmNsaWVudExlZnQ7XG4gICAgICBvZmZzZXRzLnkgKz0gb2Zmc2V0UGFyZW50LmNsaWVudFRvcDtcbiAgICB9IGVsc2UgaWYgKGRvY3VtZW50RWxlbWVudCkge1xuICAgICAgb2Zmc2V0cy54ID0gZ2V0V2luZG93U2Nyb2xsQmFyWChkb2N1bWVudEVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgeDogcmVjdC5sZWZ0ICsgc2Nyb2xsLnNjcm9sbExlZnQgLSBvZmZzZXRzLngsXG4gICAgeTogcmVjdC50b3AgKyBzY3JvbGwuc2Nyb2xsVG9wIC0gb2Zmc2V0cy55LFxuICAgIHdpZHRoOiByZWN0LndpZHRoLFxuICAgIGhlaWdodDogcmVjdC5oZWlnaHRcbiAgfTtcbn0iLCJpbXBvcnQgeyBtb2RpZmllclBoYXNlcyB9IGZyb20gXCIuLi9lbnVtcy5qc1wiOyAvLyBzb3VyY2U6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQ5ODc1MjU1XG5cbmZ1bmN0aW9uIG9yZGVyKG1vZGlmaWVycykge1xuICB2YXIgbWFwID0gbmV3IE1hcCgpO1xuICB2YXIgdmlzaXRlZCA9IG5ldyBTZXQoKTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBtb2RpZmllcnMuZm9yRWFjaChmdW5jdGlvbiAobW9kaWZpZXIpIHtcbiAgICBtYXAuc2V0KG1vZGlmaWVyLm5hbWUsIG1vZGlmaWVyKTtcbiAgfSk7IC8vIE9uIHZpc2l0aW5nIG9iamVjdCwgY2hlY2sgZm9yIGl0cyBkZXBlbmRlbmNpZXMgYW5kIHZpc2l0IHRoZW0gcmVjdXJzaXZlbHlcblxuICBmdW5jdGlvbiBzb3J0KG1vZGlmaWVyKSB7XG4gICAgdmlzaXRlZC5hZGQobW9kaWZpZXIubmFtZSk7XG4gICAgdmFyIHJlcXVpcmVzID0gW10uY29uY2F0KG1vZGlmaWVyLnJlcXVpcmVzIHx8IFtdLCBtb2RpZmllci5yZXF1aXJlc0lmRXhpc3RzIHx8IFtdKTtcbiAgICByZXF1aXJlcy5mb3JFYWNoKGZ1bmN0aW9uIChkZXApIHtcbiAgICAgIGlmICghdmlzaXRlZC5oYXMoZGVwKSkge1xuICAgICAgICB2YXIgZGVwTW9kaWZpZXIgPSBtYXAuZ2V0KGRlcCk7XG5cbiAgICAgICAgaWYgKGRlcE1vZGlmaWVyKSB7XG4gICAgICAgICAgc29ydChkZXBNb2RpZmllcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXN1bHQucHVzaChtb2RpZmllcik7XG4gIH1cblxuICBtb2RpZmllcnMuZm9yRWFjaChmdW5jdGlvbiAobW9kaWZpZXIpIHtcbiAgICBpZiAoIXZpc2l0ZWQuaGFzKG1vZGlmaWVyLm5hbWUpKSB7XG4gICAgICAvLyBjaGVjayBmb3IgdmlzaXRlZCBvYmplY3RcbiAgICAgIHNvcnQobW9kaWZpZXIpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG9yZGVyTW9kaWZpZXJzKG1vZGlmaWVycykge1xuICAvLyBvcmRlciBiYXNlZCBvbiBkZXBlbmRlbmNpZXNcbiAgdmFyIG9yZGVyZWRNb2RpZmllcnMgPSBvcmRlcihtb2RpZmllcnMpOyAvLyBvcmRlciBiYXNlZCBvbiBwaGFzZVxuXG4gIHJldHVybiBtb2RpZmllclBoYXNlcy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcGhhc2UpIHtcbiAgICByZXR1cm4gYWNjLmNvbmNhdChvcmRlcmVkTW9kaWZpZXJzLmZpbHRlcihmdW5jdGlvbiAobW9kaWZpZXIpIHtcbiAgICAgIHJldHVybiBtb2RpZmllci5waGFzZSA9PT0gcGhhc2U7XG4gICAgfSkpO1xuICB9LCBbXSk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVib3VuY2UoZm4pIHtcbiAgdmFyIHBlbmRpbmc7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFwZW5kaW5nKSB7XG4gICAgICBwZW5kaW5nID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcGVuZGluZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXNvbHZlKGZuKCkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwZW5kaW5nO1xuICB9O1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGZvcm1hdChzdHIpIHtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgIGFyZ3NbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuIFtdLmNvbmNhdChhcmdzKS5yZWR1Y2UoZnVuY3Rpb24gKHAsIGMpIHtcbiAgICByZXR1cm4gcC5yZXBsYWNlKC8lcy8sIGMpO1xuICB9LCBzdHIpO1xufSIsImltcG9ydCBmb3JtYXQgZnJvbSBcIi4vZm9ybWF0LmpzXCI7XG5pbXBvcnQgeyBtb2RpZmllclBoYXNlcyB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xudmFyIElOVkFMSURfTU9ESUZJRVJfRVJST1IgPSAnUG9wcGVyOiBtb2RpZmllciBcIiVzXCIgcHJvdmlkZWQgYW4gaW52YWxpZCAlcyBwcm9wZXJ0eSwgZXhwZWN0ZWQgJXMgYnV0IGdvdCAlcyc7XG52YXIgTUlTU0lOR19ERVBFTkRFTkNZX0VSUk9SID0gJ1BvcHBlcjogbW9kaWZpZXIgXCIlc1wiIHJlcXVpcmVzIFwiJXNcIiwgYnV0IFwiJXNcIiBtb2RpZmllciBpcyBub3QgYXZhaWxhYmxlJztcbnZhciBWQUxJRF9QUk9QRVJUSUVTID0gWyduYW1lJywgJ2VuYWJsZWQnLCAncGhhc2UnLCAnZm4nLCAnZWZmZWN0JywgJ3JlcXVpcmVzJywgJ29wdGlvbnMnXTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHZhbGlkYXRlTW9kaWZpZXJzKG1vZGlmaWVycykge1xuICBtb2RpZmllcnMuZm9yRWFjaChmdW5jdGlvbiAobW9kaWZpZXIpIHtcbiAgICBbXS5jb25jYXQoT2JqZWN0LmtleXMobW9kaWZpZXIpLCBWQUxJRF9QUk9QRVJUSUVTKSAvLyBJRTExLWNvbXBhdGlibGUgcmVwbGFjZW1lbnQgZm9yIGBuZXcgU2V0KGl0ZXJhYmxlKWBcbiAgICAuZmlsdGVyKGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgsIHNlbGYpIHtcbiAgICAgIHJldHVybiBzZWxmLmluZGV4T2YodmFsdWUpID09PSBpbmRleDtcbiAgICB9KS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgIGNhc2UgJ25hbWUnOlxuICAgICAgICAgIGlmICh0eXBlb2YgbW9kaWZpZXIubmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZm9ybWF0KElOVkFMSURfTU9ESUZJRVJfRVJST1IsIFN0cmluZyhtb2RpZmllci5uYW1lKSwgJ1wibmFtZVwiJywgJ1wic3RyaW5nXCInLCBcIlxcXCJcIiArIFN0cmluZyhtb2RpZmllci5uYW1lKSArIFwiXFxcIlwiKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnZW5hYmxlZCc6XG4gICAgICAgICAgaWYgKHR5cGVvZiBtb2RpZmllci5lbmFibGVkICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZm9ybWF0KElOVkFMSURfTU9ESUZJRVJfRVJST1IsIG1vZGlmaWVyLm5hbWUsICdcImVuYWJsZWRcIicsICdcImJvb2xlYW5cIicsIFwiXFxcIlwiICsgU3RyaW5nKG1vZGlmaWVyLmVuYWJsZWQpICsgXCJcXFwiXCIpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdwaGFzZSc6XG4gICAgICAgICAgaWYgKG1vZGlmaWVyUGhhc2VzLmluZGV4T2YobW9kaWZpZXIucGhhc2UpIDwgMCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihmb3JtYXQoSU5WQUxJRF9NT0RJRklFUl9FUlJPUiwgbW9kaWZpZXIubmFtZSwgJ1wicGhhc2VcIicsIFwiZWl0aGVyIFwiICsgbW9kaWZpZXJQaGFzZXMuam9pbignLCAnKSwgXCJcXFwiXCIgKyBTdHJpbmcobW9kaWZpZXIucGhhc2UpICsgXCJcXFwiXCIpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdmbic6XG4gICAgICAgICAgaWYgKHR5cGVvZiBtb2RpZmllci5mbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihmb3JtYXQoSU5WQUxJRF9NT0RJRklFUl9FUlJPUiwgbW9kaWZpZXIubmFtZSwgJ1wiZm5cIicsICdcImZ1bmN0aW9uXCInLCBcIlxcXCJcIiArIFN0cmluZyhtb2RpZmllci5mbikgKyBcIlxcXCJcIikpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ2VmZmVjdCc6XG4gICAgICAgICAgaWYgKG1vZGlmaWVyLmVmZmVjdCAhPSBudWxsICYmIHR5cGVvZiBtb2RpZmllci5lZmZlY3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZm9ybWF0KElOVkFMSURfTU9ESUZJRVJfRVJST1IsIG1vZGlmaWVyLm5hbWUsICdcImVmZmVjdFwiJywgJ1wiZnVuY3Rpb25cIicsIFwiXFxcIlwiICsgU3RyaW5nKG1vZGlmaWVyLmZuKSArIFwiXFxcIlwiKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAncmVxdWlyZXMnOlxuICAgICAgICAgIGlmIChtb2RpZmllci5yZXF1aXJlcyAhPSBudWxsICYmICFBcnJheS5pc0FycmF5KG1vZGlmaWVyLnJlcXVpcmVzKSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihmb3JtYXQoSU5WQUxJRF9NT0RJRklFUl9FUlJPUiwgbW9kaWZpZXIubmFtZSwgJ1wicmVxdWlyZXNcIicsICdcImFycmF5XCInLCBcIlxcXCJcIiArIFN0cmluZyhtb2RpZmllci5yZXF1aXJlcykgKyBcIlxcXCJcIikpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ3JlcXVpcmVzSWZFeGlzdHMnOlxuICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtb2RpZmllci5yZXF1aXJlc0lmRXhpc3RzKSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihmb3JtYXQoSU5WQUxJRF9NT0RJRklFUl9FUlJPUiwgbW9kaWZpZXIubmFtZSwgJ1wicmVxdWlyZXNJZkV4aXN0c1wiJywgJ1wiYXJyYXlcIicsIFwiXFxcIlwiICsgU3RyaW5nKG1vZGlmaWVyLnJlcXVpcmVzSWZFeGlzdHMpICsgXCJcXFwiXCIpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdvcHRpb25zJzpcbiAgICAgICAgY2FzZSAnZGF0YSc6XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFwiUG9wcGVySlM6IGFuIGludmFsaWQgcHJvcGVydHkgaGFzIGJlZW4gcHJvdmlkZWQgdG8gdGhlIFxcXCJcIiArIG1vZGlmaWVyLm5hbWUgKyBcIlxcXCIgbW9kaWZpZXIsIHZhbGlkIHByb3BlcnRpZXMgYXJlIFwiICsgVkFMSURfUFJPUEVSVElFUy5tYXAoZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgICAgIHJldHVybiBcIlxcXCJcIiArIHMgKyBcIlxcXCJcIjtcbiAgICAgICAgICB9KS5qb2luKCcsICcpICsgXCI7IGJ1dCBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgd2FzIHByb3ZpZGVkLlwiKTtcbiAgICAgIH1cblxuICAgICAgbW9kaWZpZXIucmVxdWlyZXMgJiYgbW9kaWZpZXIucmVxdWlyZXMuZm9yRWFjaChmdW5jdGlvbiAocmVxdWlyZW1lbnQpIHtcbiAgICAgICAgaWYgKG1vZGlmaWVycy5maW5kKGZ1bmN0aW9uIChtb2QpIHtcbiAgICAgICAgICByZXR1cm4gbW9kLm5hbWUgPT09IHJlcXVpcmVtZW50O1xuICAgICAgICB9KSA9PSBudWxsKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihmb3JtYXQoTUlTU0lOR19ERVBFTkRFTkNZX0VSUk9SLCBTdHJpbmcobW9kaWZpZXIubmFtZSksIHJlcXVpcmVtZW50LCByZXF1aXJlbWVudCkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdW5pcXVlQnkoYXJyLCBmbikge1xuICB2YXIgaWRlbnRpZmllcnMgPSBuZXcgU2V0KCk7XG4gIHJldHVybiBhcnIuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgdmFyIGlkZW50aWZpZXIgPSBmbihpdGVtKTtcblxuICAgIGlmICghaWRlbnRpZmllcnMuaGFzKGlkZW50aWZpZXIpKSB7XG4gICAgICBpZGVudGlmaWVycy5hZGQoaWRlbnRpZmllcik7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG1lcmdlQnlOYW1lKG1vZGlmaWVycykge1xuICB2YXIgbWVyZ2VkID0gbW9kaWZpZXJzLnJlZHVjZShmdW5jdGlvbiAobWVyZ2VkLCBjdXJyZW50KSB7XG4gICAgdmFyIGV4aXN0aW5nID0gbWVyZ2VkW2N1cnJlbnQubmFtZV07XG4gICAgbWVyZ2VkW2N1cnJlbnQubmFtZV0gPSBleGlzdGluZyA/IE9iamVjdC5hc3NpZ24oe30sIGV4aXN0aW5nLCBjdXJyZW50LCB7XG4gICAgICBvcHRpb25zOiBPYmplY3QuYXNzaWduKHt9LCBleGlzdGluZy5vcHRpb25zLCBjdXJyZW50Lm9wdGlvbnMpLFxuICAgICAgZGF0YTogT2JqZWN0LmFzc2lnbih7fSwgZXhpc3RpbmcuZGF0YSwgY3VycmVudC5kYXRhKVxuICAgIH0pIDogY3VycmVudDtcbiAgICByZXR1cm4gbWVyZ2VkO1xuICB9LCB7fSk7IC8vIElFMTEgZG9lcyBub3Qgc3VwcG9ydCBPYmplY3QudmFsdWVzXG5cbiAgcmV0dXJuIE9iamVjdC5rZXlzKG1lcmdlZCkubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gbWVyZ2VkW2tleV07XG4gIH0pO1xufSIsImltcG9ydCBnZXRDb21wb3NpdGVSZWN0IGZyb20gXCIuL2RvbS11dGlscy9nZXRDb21wb3NpdGVSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0TGF5b3V0UmVjdCBmcm9tIFwiLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGxpc3RTY3JvbGxQYXJlbnRzIGZyb20gXCIuL2RvbS11dGlscy9saXN0U2Nyb2xsUGFyZW50cy5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9kb20tdXRpbHMvZ2V0Q29tcHV0ZWRTdHlsZS5qc1wiO1xuaW1wb3J0IG9yZGVyTW9kaWZpZXJzIGZyb20gXCIuL3V0aWxzL29yZGVyTW9kaWZpZXJzLmpzXCI7XG5pbXBvcnQgZGVib3VuY2UgZnJvbSBcIi4vdXRpbHMvZGVib3VuY2UuanNcIjtcbmltcG9ydCB2YWxpZGF0ZU1vZGlmaWVycyBmcm9tIFwiLi91dGlscy92YWxpZGF0ZU1vZGlmaWVycy5qc1wiO1xuaW1wb3J0IHVuaXF1ZUJ5IGZyb20gXCIuL3V0aWxzL3VuaXF1ZUJ5LmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgbWVyZ2VCeU5hbWUgZnJvbSBcIi4vdXRpbHMvbWVyZ2VCeU5hbWUuanNcIjtcbmltcG9ydCBkZXRlY3RPdmVyZmxvdyBmcm9tIFwiLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IHsgaXNFbGVtZW50IH0gZnJvbSBcIi4vZG9tLXV0aWxzL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCB7IGF1dG8gfSBmcm9tIFwiLi9lbnVtcy5qc1wiO1xudmFyIElOVkFMSURfRUxFTUVOVF9FUlJPUiA9ICdQb3BwZXI6IEludmFsaWQgcmVmZXJlbmNlIG9yIHBvcHBlciBhcmd1bWVudCBwcm92aWRlZC4gVGhleSBtdXN0IGJlIGVpdGhlciBhIERPTSBlbGVtZW50IG9yIHZpcnR1YWwgZWxlbWVudC4nO1xudmFyIElORklOSVRFX0xPT1BfRVJST1IgPSAnUG9wcGVyOiBBbiBpbmZpbml0ZSBsb29wIGluIHRoZSBtb2RpZmllcnMgY3ljbGUgaGFzIGJlZW4gZGV0ZWN0ZWQhIFRoZSBjeWNsZSBoYXMgYmVlbiBpbnRlcnJ1cHRlZCB0byBwcmV2ZW50IGEgYnJvd3NlciBjcmFzaC4nO1xudmFyIERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgcGxhY2VtZW50OiAnYm90dG9tJyxcbiAgbW9kaWZpZXJzOiBbXSxcbiAgc3RyYXRlZ3k6ICdhYnNvbHV0ZSdcbn07XG5cbmZ1bmN0aW9uIGFyZVZhbGlkRWxlbWVudHMoKSB7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gIH1cblxuICByZXR1cm4gIWFyZ3Muc29tZShmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHJldHVybiAhKGVsZW1lbnQgJiYgdHlwZW9mIGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0ID09PSAnZnVuY3Rpb24nKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwb3BwZXJHZW5lcmF0b3IoZ2VuZXJhdG9yT3B0aW9ucykge1xuICBpZiAoZ2VuZXJhdG9yT3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgZ2VuZXJhdG9yT3B0aW9ucyA9IHt9O1xuICB9XG5cbiAgdmFyIF9nZW5lcmF0b3JPcHRpb25zID0gZ2VuZXJhdG9yT3B0aW9ucyxcbiAgICAgIF9nZW5lcmF0b3JPcHRpb25zJGRlZiA9IF9nZW5lcmF0b3JPcHRpb25zLmRlZmF1bHRNb2RpZmllcnMsXG4gICAgICBkZWZhdWx0TW9kaWZpZXJzID0gX2dlbmVyYXRvck9wdGlvbnMkZGVmID09PSB2b2lkIDAgPyBbXSA6IF9nZW5lcmF0b3JPcHRpb25zJGRlZixcbiAgICAgIF9nZW5lcmF0b3JPcHRpb25zJGRlZjIgPSBfZ2VuZXJhdG9yT3B0aW9ucy5kZWZhdWx0T3B0aW9ucyxcbiAgICAgIGRlZmF1bHRPcHRpb25zID0gX2dlbmVyYXRvck9wdGlvbnMkZGVmMiA9PT0gdm9pZCAwID8gREVGQVVMVF9PUFRJT05TIDogX2dlbmVyYXRvck9wdGlvbnMkZGVmMjtcbiAgcmV0dXJuIGZ1bmN0aW9uIGNyZWF0ZVBvcHBlcihyZWZlcmVuY2UsIHBvcHBlciwgb3B0aW9ucykge1xuICAgIGlmIChvcHRpb25zID09PSB2b2lkIDApIHtcbiAgICAgIG9wdGlvbnMgPSBkZWZhdWx0T3B0aW9ucztcbiAgICB9XG5cbiAgICB2YXIgc3RhdGUgPSB7XG4gICAgICBwbGFjZW1lbnQ6ICdib3R0b20nLFxuICAgICAgb3JkZXJlZE1vZGlmaWVyczogW10sXG4gICAgICBvcHRpb25zOiBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX09QVElPTlMsIGRlZmF1bHRPcHRpb25zKSxcbiAgICAgIG1vZGlmaWVyc0RhdGE6IHt9LFxuICAgICAgZWxlbWVudHM6IHtcbiAgICAgICAgcmVmZXJlbmNlOiByZWZlcmVuY2UsXG4gICAgICAgIHBvcHBlcjogcG9wcGVyXG4gICAgICB9LFxuICAgICAgYXR0cmlidXRlczoge30sXG4gICAgICBzdHlsZXM6IHt9XG4gICAgfTtcbiAgICB2YXIgZWZmZWN0Q2xlYW51cEZucyA9IFtdO1xuICAgIHZhciBpc0Rlc3Ryb3llZCA9IGZhbHNlO1xuICAgIHZhciBpbnN0YW5jZSA9IHtcbiAgICAgIHN0YXRlOiBzdGF0ZSxcbiAgICAgIHNldE9wdGlvbnM6IGZ1bmN0aW9uIHNldE9wdGlvbnMoc2V0T3B0aW9uc0FjdGlvbikge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHR5cGVvZiBzZXRPcHRpb25zQWN0aW9uID09PSAnZnVuY3Rpb24nID8gc2V0T3B0aW9uc0FjdGlvbihzdGF0ZS5vcHRpb25zKSA6IHNldE9wdGlvbnNBY3Rpb247XG4gICAgICAgIGNsZWFudXBNb2RpZmllckVmZmVjdHMoKTtcbiAgICAgICAgc3RhdGUub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRPcHRpb25zLCBzdGF0ZS5vcHRpb25zLCBvcHRpb25zKTtcbiAgICAgICAgc3RhdGUuc2Nyb2xsUGFyZW50cyA9IHtcbiAgICAgICAgICByZWZlcmVuY2U6IGlzRWxlbWVudChyZWZlcmVuY2UpID8gbGlzdFNjcm9sbFBhcmVudHMocmVmZXJlbmNlKSA6IHJlZmVyZW5jZS5jb250ZXh0RWxlbWVudCA/IGxpc3RTY3JvbGxQYXJlbnRzKHJlZmVyZW5jZS5jb250ZXh0RWxlbWVudCkgOiBbXSxcbiAgICAgICAgICBwb3BwZXI6IGxpc3RTY3JvbGxQYXJlbnRzKHBvcHBlcilcbiAgICAgICAgfTsgLy8gT3JkZXJzIHRoZSBtb2RpZmllcnMgYmFzZWQgb24gdGhlaXIgZGVwZW5kZW5jaWVzIGFuZCBgcGhhc2VgXG4gICAgICAgIC8vIHByb3BlcnRpZXNcblxuICAgICAgICB2YXIgb3JkZXJlZE1vZGlmaWVycyA9IG9yZGVyTW9kaWZpZXJzKG1lcmdlQnlOYW1lKFtdLmNvbmNhdChkZWZhdWx0TW9kaWZpZXJzLCBzdGF0ZS5vcHRpb25zLm1vZGlmaWVycykpKTsgLy8gU3RyaXAgb3V0IGRpc2FibGVkIG1vZGlmaWVyc1xuXG4gICAgICAgIHN0YXRlLm9yZGVyZWRNb2RpZmllcnMgPSBvcmRlcmVkTW9kaWZpZXJzLmZpbHRlcihmdW5jdGlvbiAobSkge1xuICAgICAgICAgIHJldHVybiBtLmVuYWJsZWQ7XG4gICAgICAgIH0pOyAvLyBWYWxpZGF0ZSB0aGUgcHJvdmlkZWQgbW9kaWZpZXJzIHNvIHRoYXQgdGhlIGNvbnN1bWVyIHdpbGwgZ2V0IHdhcm5lZFxuICAgICAgICAvLyBpZiBvbmUgb2YgdGhlIG1vZGlmaWVycyBpcyBpbnZhbGlkIGZvciBhbnkgcmVhc29uXG5cbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgIHZhciBtb2RpZmllcnMgPSB1bmlxdWVCeShbXS5jb25jYXQob3JkZXJlZE1vZGlmaWVycywgc3RhdGUub3B0aW9ucy5tb2RpZmllcnMpLCBmdW5jdGlvbiAoX3JlZikge1xuICAgICAgICAgICAgdmFyIG5hbWUgPSBfcmVmLm5hbWU7XG4gICAgICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB2YWxpZGF0ZU1vZGlmaWVycyhtb2RpZmllcnMpO1xuXG4gICAgICAgICAgaWYgKGdldEJhc2VQbGFjZW1lbnQoc3RhdGUub3B0aW9ucy5wbGFjZW1lbnQpID09PSBhdXRvKSB7XG4gICAgICAgICAgICB2YXIgZmxpcE1vZGlmaWVyID0gc3RhdGUub3JkZXJlZE1vZGlmaWVycy5maW5kKGZ1bmN0aW9uIChfcmVmMikge1xuICAgICAgICAgICAgICB2YXIgbmFtZSA9IF9yZWYyLm5hbWU7XG4gICAgICAgICAgICAgIHJldHVybiBuYW1lID09PSAnZmxpcCc7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKCFmbGlwTW9kaWZpZXIpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihbJ1BvcHBlcjogXCJhdXRvXCIgcGxhY2VtZW50cyByZXF1aXJlIHRoZSBcImZsaXBcIiBtb2RpZmllciBiZScsICdwcmVzZW50IGFuZCBlbmFibGVkIHRvIHdvcmsuJ10uam9pbignICcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgX2dldENvbXB1dGVkU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKHBvcHBlciksXG4gICAgICAgICAgICAgIG1hcmdpblRvcCA9IF9nZXRDb21wdXRlZFN0eWxlLm1hcmdpblRvcCxcbiAgICAgICAgICAgICAgbWFyZ2luUmlnaHQgPSBfZ2V0Q29tcHV0ZWRTdHlsZS5tYXJnaW5SaWdodCxcbiAgICAgICAgICAgICAgbWFyZ2luQm90dG9tID0gX2dldENvbXB1dGVkU3R5bGUubWFyZ2luQm90dG9tLFxuICAgICAgICAgICAgICBtYXJnaW5MZWZ0ID0gX2dldENvbXB1dGVkU3R5bGUubWFyZ2luTGVmdDsgLy8gV2Ugbm8gbG9uZ2VyIHRha2UgaW50byBhY2NvdW50IGBtYXJnaW5zYCBvbiB0aGUgcG9wcGVyLCBhbmQgaXQgY2FuXG4gICAgICAgICAgLy8gY2F1c2UgYnVncyB3aXRoIHBvc2l0aW9uaW5nLCBzbyB3ZSdsbCB3YXJuIHRoZSBjb25zdW1lclxuXG5cbiAgICAgICAgICBpZiAoW21hcmdpblRvcCwgbWFyZ2luUmlnaHQsIG1hcmdpbkJvdHRvbSwgbWFyZ2luTGVmdF0uc29tZShmdW5jdGlvbiAobWFyZ2luKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VGbG9hdChtYXJnaW4pO1xuICAgICAgICAgIH0pKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oWydQb3BwZXI6IENTUyBcIm1hcmdpblwiIHN0eWxlcyBjYW5ub3QgYmUgdXNlZCB0byBhcHBseSBwYWRkaW5nJywgJ2JldHdlZW4gdGhlIHBvcHBlciBhbmQgaXRzIHJlZmVyZW5jZSBlbGVtZW50IG9yIGJvdW5kYXJ5LicsICdUbyByZXBsaWNhdGUgbWFyZ2luLCB1c2UgdGhlIGBvZmZzZXRgIG1vZGlmaWVyLCBhcyB3ZWxsIGFzJywgJ3RoZSBgcGFkZGluZ2Agb3B0aW9uIGluIHRoZSBgcHJldmVudE92ZXJmbG93YCBhbmQgYGZsaXBgJywgJ21vZGlmaWVycy4nXS5qb2luKCcgJykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJ1bk1vZGlmaWVyRWZmZWN0cygpO1xuICAgICAgICByZXR1cm4gaW5zdGFuY2UudXBkYXRlKCk7XG4gICAgICB9LFxuICAgICAgLy8gU3luYyB1cGRhdGUg4oCTIGl0IHdpbGwgYWx3YXlzIGJlIGV4ZWN1dGVkLCBldmVuIGlmIG5vdCBuZWNlc3NhcnkuIFRoaXNcbiAgICAgIC8vIGlzIHVzZWZ1bCBmb3IgbG93IGZyZXF1ZW5jeSB1cGRhdGVzIHdoZXJlIHN5bmMgYmVoYXZpb3Igc2ltcGxpZmllcyB0aGVcbiAgICAgIC8vIGxvZ2ljLlxuICAgICAgLy8gRm9yIGhpZ2ggZnJlcXVlbmN5IHVwZGF0ZXMgKGUuZy4gYHJlc2l6ZWAgYW5kIGBzY3JvbGxgIGV2ZW50cyksIGFsd2F5c1xuICAgICAgLy8gcHJlZmVyIHRoZSBhc3luYyBQb3BwZXIjdXBkYXRlIG1ldGhvZFxuICAgICAgZm9yY2VVcGRhdGU6IGZ1bmN0aW9uIGZvcmNlVXBkYXRlKCkge1xuICAgICAgICBpZiAoaXNEZXN0cm95ZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgX3N0YXRlJGVsZW1lbnRzID0gc3RhdGUuZWxlbWVudHMsXG4gICAgICAgICAgICByZWZlcmVuY2UgPSBfc3RhdGUkZWxlbWVudHMucmVmZXJlbmNlLFxuICAgICAgICAgICAgcG9wcGVyID0gX3N0YXRlJGVsZW1lbnRzLnBvcHBlcjsgLy8gRG9uJ3QgcHJvY2VlZCBpZiBgcmVmZXJlbmNlYCBvciBgcG9wcGVyYCBhcmUgbm90IHZhbGlkIGVsZW1lbnRzXG4gICAgICAgIC8vIGFueW1vcmVcblxuICAgICAgICBpZiAoIWFyZVZhbGlkRWxlbWVudHMocmVmZXJlbmNlLCBwb3BwZXIpKSB7XG4gICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihJTlZBTElEX0VMRU1FTlRfRVJST1IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSAvLyBTdG9yZSB0aGUgcmVmZXJlbmNlIGFuZCBwb3BwZXIgcmVjdHMgdG8gYmUgcmVhZCBieSBtb2RpZmllcnNcblxuXG4gICAgICAgIHN0YXRlLnJlY3RzID0ge1xuICAgICAgICAgIHJlZmVyZW5jZTogZ2V0Q29tcG9zaXRlUmVjdChyZWZlcmVuY2UsIGdldE9mZnNldFBhcmVudChwb3BwZXIpLCBzdGF0ZS5vcHRpb25zLnN0cmF0ZWd5ID09PSAnZml4ZWQnKSxcbiAgICAgICAgICBwb3BwZXI6IGdldExheW91dFJlY3QocG9wcGVyKVxuICAgICAgICB9OyAvLyBNb2RpZmllcnMgaGF2ZSB0aGUgYWJpbGl0eSB0byByZXNldCB0aGUgY3VycmVudCB1cGRhdGUgY3ljbGUuIFRoZVxuICAgICAgICAvLyBtb3N0IGNvbW1vbiB1c2UgY2FzZSBmb3IgdGhpcyBpcyB0aGUgYGZsaXBgIG1vZGlmaWVyIGNoYW5naW5nIHRoZVxuICAgICAgICAvLyBwbGFjZW1lbnQsIHdoaWNoIHRoZW4gbmVlZHMgdG8gcmUtcnVuIGFsbCB0aGUgbW9kaWZpZXJzLCBiZWNhdXNlIHRoZVxuICAgICAgICAvLyBsb2dpYyB3YXMgcHJldmlvdXNseSByYW4gZm9yIHRoZSBwcmV2aW91cyBwbGFjZW1lbnQgYW5kIGlzIHRoZXJlZm9yZVxuICAgICAgICAvLyBzdGFsZS9pbmNvcnJlY3RcblxuICAgICAgICBzdGF0ZS5yZXNldCA9IGZhbHNlO1xuICAgICAgICBzdGF0ZS5wbGFjZW1lbnQgPSBzdGF0ZS5vcHRpb25zLnBsYWNlbWVudDsgLy8gT24gZWFjaCB1cGRhdGUgY3ljbGUsIHRoZSBgbW9kaWZpZXJzRGF0YWAgcHJvcGVydHkgZm9yIGVhY2ggbW9kaWZpZXJcbiAgICAgICAgLy8gaXMgZmlsbGVkIHdpdGggdGhlIGluaXRpYWwgZGF0YSBzcGVjaWZpZWQgYnkgdGhlIG1vZGlmaWVyLiBUaGlzIG1lYW5zXG4gICAgICAgIC8vIGl0IGRvZXNuJ3QgcGVyc2lzdCBhbmQgaXMgZnJlc2ggb24gZWFjaCB1cGRhdGUuXG4gICAgICAgIC8vIFRvIGVuc3VyZSBwZXJzaXN0ZW50IGRhdGEsIHVzZSBgJHtuYW1lfSNwZXJzaXN0ZW50YFxuXG4gICAgICAgIHN0YXRlLm9yZGVyZWRNb2RpZmllcnMuZm9yRWFjaChmdW5jdGlvbiAobW9kaWZpZXIpIHtcbiAgICAgICAgICByZXR1cm4gc3RhdGUubW9kaWZpZXJzRGF0YVttb2RpZmllci5uYW1lXSA9IE9iamVjdC5hc3NpZ24oe30sIG1vZGlmaWVyLmRhdGEpO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIF9fZGVidWdfbG9vcHNfXyA9IDA7XG5cbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHN0YXRlLm9yZGVyZWRNb2RpZmllcnMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAgICAgICAgICAgX19kZWJ1Z19sb29wc19fICs9IDE7XG5cbiAgICAgICAgICAgIGlmIChfX2RlYnVnX2xvb3BzX18gPiAxMDApIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihJTkZJTklURV9MT09QX0VSUk9SKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHN0YXRlLnJlc2V0ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBzdGF0ZS5yZXNldCA9IGZhbHNlO1xuICAgICAgICAgICAgaW5kZXggPSAtMTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfc3RhdGUkb3JkZXJlZE1vZGlmaWUgPSBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzW2luZGV4XSxcbiAgICAgICAgICAgICAgZm4gPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUuZm4sXG4gICAgICAgICAgICAgIF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUub3B0aW9ucyxcbiAgICAgICAgICAgICAgX29wdGlvbnMgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUyID09PSB2b2lkIDAgPyB7fSA6IF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIsXG4gICAgICAgICAgICAgIG5hbWUgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUubmFtZTtcblxuICAgICAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHN0YXRlID0gZm4oe1xuICAgICAgICAgICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICAgICAgICAgIG9wdGlvbnM6IF9vcHRpb25zLFxuICAgICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgICBpbnN0YW5jZTogaW5zdGFuY2VcbiAgICAgICAgICAgIH0pIHx8IHN0YXRlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIEFzeW5jIGFuZCBvcHRpbWlzdGljYWxseSBvcHRpbWl6ZWQgdXBkYXRlIOKAkyBpdCB3aWxsIG5vdCBiZSBleGVjdXRlZCBpZlxuICAgICAgLy8gbm90IG5lY2Vzc2FyeSAoZGVib3VuY2VkIHRvIHJ1biBhdCBtb3N0IG9uY2UtcGVyLXRpY2spXG4gICAgICB1cGRhdGU6IGRlYm91bmNlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgaW5zdGFuY2UuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgICByZXNvbHZlKHN0YXRlKTtcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICAgIGNsZWFudXBNb2RpZmllckVmZmVjdHMoKTtcbiAgICAgICAgaXNEZXN0cm95ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoIWFyZVZhbGlkRWxlbWVudHMocmVmZXJlbmNlLCBwb3BwZXIpKSB7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoSU5WQUxJRF9FTEVNRU5UX0VSUk9SKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cblxuICAgIGluc3RhbmNlLnNldE9wdGlvbnMob3B0aW9ucykudGhlbihmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICAgIGlmICghaXNEZXN0cm95ZWQgJiYgb3B0aW9ucy5vbkZpcnN0VXBkYXRlKSB7XG4gICAgICAgIG9wdGlvbnMub25GaXJzdFVwZGF0ZShzdGF0ZSk7XG4gICAgICB9XG4gICAgfSk7IC8vIE1vZGlmaWVycyBoYXZlIHRoZSBhYmlsaXR5IHRvIGV4ZWN1dGUgYXJiaXRyYXJ5IGNvZGUgYmVmb3JlIHRoZSBmaXJzdFxuICAgIC8vIHVwZGF0ZSBjeWNsZSBydW5zLiBUaGV5IHdpbGwgYmUgZXhlY3V0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhlIHVwZGF0ZVxuICAgIC8vIGN5Y2xlLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIGEgbW9kaWZpZXIgYWRkcyBzb21lIHBlcnNpc3RlbnQgZGF0YSB0aGF0XG4gICAgLy8gb3RoZXIgbW9kaWZpZXJzIG5lZWQgdG8gdXNlLCBidXQgdGhlIG1vZGlmaWVyIGlzIHJ1biBhZnRlciB0aGUgZGVwZW5kZW50XG4gICAgLy8gb25lLlxuXG4gICAgZnVuY3Rpb24gcnVuTW9kaWZpZXJFZmZlY3RzKCkge1xuICAgICAgc3RhdGUub3JkZXJlZE1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChfcmVmMykge1xuICAgICAgICB2YXIgbmFtZSA9IF9yZWYzLm5hbWUsXG4gICAgICAgICAgICBfcmVmMyRvcHRpb25zID0gX3JlZjMub3B0aW9ucyxcbiAgICAgICAgICAgIG9wdGlvbnMgPSBfcmVmMyRvcHRpb25zID09PSB2b2lkIDAgPyB7fSA6IF9yZWYzJG9wdGlvbnMsXG4gICAgICAgICAgICBlZmZlY3QgPSBfcmVmMy5lZmZlY3Q7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBlZmZlY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB2YXIgY2xlYW51cEZuID0gZWZmZWN0KHtcbiAgICAgICAgICAgIHN0YXRlOiBzdGF0ZSxcbiAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICBpbnN0YW5jZTogaW5zdGFuY2UsXG4gICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB2YXIgbm9vcEZuID0gZnVuY3Rpb24gbm9vcEZuKCkge307XG5cbiAgICAgICAgICBlZmZlY3RDbGVhbnVwRm5zLnB1c2goY2xlYW51cEZuIHx8IG5vb3BGbik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFudXBNb2RpZmllckVmZmVjdHMoKSB7XG4gICAgICBlZmZlY3RDbGVhbnVwRm5zLmZvckVhY2goZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIHJldHVybiBmbigpO1xuICAgICAgfSk7XG4gICAgICBlZmZlY3RDbGVhbnVwRm5zID0gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIGluc3RhbmNlO1xuICB9O1xufVxuZXhwb3J0IHZhciBjcmVhdGVQb3BwZXIgPSAvKiNfX1BVUkVfXyovcG9wcGVyR2VuZXJhdG9yKCk7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IHsgZGV0ZWN0T3ZlcmZsb3cgfTsiLCJpbXBvcnQgeyBwb3BwZXJHZW5lcmF0b3IsIGRldGVjdE92ZXJmbG93IH0gZnJvbSBcIi4vY3JlYXRlUG9wcGVyLmpzXCI7XG5pbXBvcnQgZXZlbnRMaXN0ZW5lcnMgZnJvbSBcIi4vbW9kaWZpZXJzL2V2ZW50TGlzdGVuZXJzLmpzXCI7XG5pbXBvcnQgcG9wcGVyT2Zmc2V0cyBmcm9tIFwiLi9tb2RpZmllcnMvcG9wcGVyT2Zmc2V0cy5qc1wiO1xuaW1wb3J0IGNvbXB1dGVTdHlsZXMgZnJvbSBcIi4vbW9kaWZpZXJzL2NvbXB1dGVTdHlsZXMuanNcIjtcbmltcG9ydCBhcHBseVN0eWxlcyBmcm9tIFwiLi9tb2RpZmllcnMvYXBwbHlTdHlsZXMuanNcIjtcbmltcG9ydCBvZmZzZXQgZnJvbSBcIi4vbW9kaWZpZXJzL29mZnNldC5qc1wiO1xuaW1wb3J0IGZsaXAgZnJvbSBcIi4vbW9kaWZpZXJzL2ZsaXAuanNcIjtcbmltcG9ydCBwcmV2ZW50T3ZlcmZsb3cgZnJvbSBcIi4vbW9kaWZpZXJzL3ByZXZlbnRPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGFycm93IGZyb20gXCIuL21vZGlmaWVycy9hcnJvdy5qc1wiO1xuaW1wb3J0IGhpZGUgZnJvbSBcIi4vbW9kaWZpZXJzL2hpZGUuanNcIjtcbnZhciBkZWZhdWx0TW9kaWZpZXJzID0gW2V2ZW50TGlzdGVuZXJzLCBwb3BwZXJPZmZzZXRzLCBjb21wdXRlU3R5bGVzLCBhcHBseVN0eWxlcywgb2Zmc2V0LCBmbGlwLCBwcmV2ZW50T3ZlcmZsb3csIGFycm93LCBoaWRlXTtcbnZhciBjcmVhdGVQb3BwZXIgPSAvKiNfX1BVUkVfXyovcG9wcGVyR2VuZXJhdG9yKHtcbiAgZGVmYXVsdE1vZGlmaWVyczogZGVmYXVsdE1vZGlmaWVyc1xufSk7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IHsgY3JlYXRlUG9wcGVyLCBwb3BwZXJHZW5lcmF0b3IsIGRlZmF1bHRNb2RpZmllcnMsIGRldGVjdE92ZXJmbG93IH07IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IHsgY3JlYXRlUG9wcGVyIGFzIGNyZWF0ZVBvcHBlckxpdGUgfSBmcm9tIFwiLi9wb3BwZXItbGl0ZS5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbmV4cG9ydCAqIGZyb20gXCIuL21vZGlmaWVycy9pbmRleC5qc1wiOyIsIi8vIENyZWRpdHMgZ28gdG8gTGlhbSdzIFBlcmlvZGljIE5vdGVzIFBsdWdpbjogaHR0cHM6Ly9naXRodWIuY29tL2xpYW1jYWluL29ic2lkaWFuLXBlcmlvZGljLW5vdGVzXG5cbmltcG9ydCB7IEFwcCwgSVN1Z2dlc3RPd25lciwgU2NvcGUgfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB7IGNyZWF0ZVBvcHBlciwgSW5zdGFuY2UgYXMgUG9wcGVySW5zdGFuY2UgfSBmcm9tIFwiQHBvcHBlcmpzL2NvcmVcIjtcblxuY29uc3Qgd3JhcEFyb3VuZCA9ICh2YWx1ZTogbnVtYmVyLCBzaXplOiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICAgIHJldHVybiAoKHZhbHVlICUgc2l6ZSkgKyBzaXplKSAlIHNpemU7XG59O1xuXG5jbGFzcyBTdWdnZXN0PFQ+IHtcbiAgICBwcml2YXRlIG93bmVyOiBJU3VnZ2VzdE93bmVyPFQ+O1xuICAgIHByaXZhdGUgdmFsdWVzOiBUW107XG4gICAgcHJpdmF0ZSBzdWdnZXN0aW9uczogSFRNTERpdkVsZW1lbnRbXTtcbiAgICBwcml2YXRlIHNlbGVjdGVkSXRlbTogbnVtYmVyO1xuICAgIHByaXZhdGUgY29udGFpbmVyRWw6IEhUTUxFbGVtZW50O1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIG93bmVyOiBJU3VnZ2VzdE93bmVyPFQ+LFxuICAgICAgICBjb250YWluZXJFbDogSFRNTEVsZW1lbnQsXG4gICAgICAgIHNjb3BlOiBTY29wZVxuICAgICkge1xuICAgICAgICB0aGlzLm93bmVyID0gb3duZXI7XG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwgPSBjb250YWluZXJFbDtcblxuICAgICAgICBjb250YWluZXJFbC5vbihcbiAgICAgICAgICAgIFwiY2xpY2tcIixcbiAgICAgICAgICAgIFwiLnN1Z2dlc3Rpb24taXRlbVwiLFxuICAgICAgICAgICAgdGhpcy5vblN1Z2dlc3Rpb25DbGljay5iaW5kKHRoaXMpXG4gICAgICAgICk7XG4gICAgICAgIGNvbnRhaW5lckVsLm9uKFxuICAgICAgICAgICAgXCJtb3VzZW1vdmVcIixcbiAgICAgICAgICAgIFwiLnN1Z2dlc3Rpb24taXRlbVwiLFxuICAgICAgICAgICAgdGhpcy5vblN1Z2dlc3Rpb25Nb3VzZW92ZXIuYmluZCh0aGlzKVxuICAgICAgICApO1xuXG4gICAgICAgIHNjb3BlLnJlZ2lzdGVyKFtdLCBcIkFycm93VXBcIiwgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWV2ZW50LmlzQ29tcG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTZWxlY3RlZEl0ZW0odGhpcy5zZWxlY3RlZEl0ZW0gLSAxLCB0cnVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNjb3BlLnJlZ2lzdGVyKFtdLCBcIkFycm93RG93blwiLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICghZXZlbnQuaXNDb21wb3NpbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFNlbGVjdGVkSXRlbSh0aGlzLnNlbGVjdGVkSXRlbSArIDEsIHRydWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2NvcGUucmVnaXN0ZXIoW10sIFwiRW50ZXJcIiwgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWV2ZW50LmlzQ29tcG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51c2VTZWxlY3RlZEl0ZW0oZXZlbnQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25TdWdnZXN0aW9uQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIGVsOiBIVE1MRGl2RWxlbWVudCk6IHZvaWQge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLnN1Z2dlc3Rpb25zLmluZGV4T2YoZWwpO1xuICAgICAgICB0aGlzLnNldFNlbGVjdGVkSXRlbShpdGVtLCBmYWxzZSk7XG4gICAgICAgIHRoaXMudXNlU2VsZWN0ZWRJdGVtKGV2ZW50KTtcbiAgICB9XG5cbiAgICBvblN1Z2dlc3Rpb25Nb3VzZW92ZXIoX2V2ZW50OiBNb3VzZUV2ZW50LCBlbDogSFRNTERpdkVsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgaXRlbSA9IHRoaXMuc3VnZ2VzdGlvbnMuaW5kZXhPZihlbCk7XG4gICAgICAgIHRoaXMuc2V0U2VsZWN0ZWRJdGVtKGl0ZW0sIGZhbHNlKTtcbiAgICB9XG5cbiAgICBzZXRTdWdnZXN0aW9ucyh2YWx1ZXM6IFRbXSkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmVtcHR5KCk7XG4gICAgICAgIGNvbnN0IHN1Z2dlc3Rpb25FbHM6IEhUTUxEaXZFbGVtZW50W10gPSBbXTtcblxuICAgICAgICB2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN1Z2dlc3Rpb25FbCA9IHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRGl2KFwic3VnZ2VzdGlvbi1pdGVtXCIpO1xuICAgICAgICAgICAgdGhpcy5vd25lci5yZW5kZXJTdWdnZXN0aW9uKHZhbHVlLCBzdWdnZXN0aW9uRWwpO1xuICAgICAgICAgICAgc3VnZ2VzdGlvbkVscy5wdXNoKHN1Z2dlc3Rpb25FbCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMudmFsdWVzID0gdmFsdWVzO1xuICAgICAgICB0aGlzLnN1Z2dlc3Rpb25zID0gc3VnZ2VzdGlvbkVscztcbiAgICAgICAgdGhpcy5zZXRTZWxlY3RlZEl0ZW0oMCwgZmFsc2UpO1xuICAgIH1cblxuICAgIHVzZVNlbGVjdGVkSXRlbShldmVudDogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gdGhpcy52YWx1ZXNbdGhpcy5zZWxlY3RlZEl0ZW1dO1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLm93bmVyLnNlbGVjdFN1Z2dlc3Rpb24oY3VycmVudFZhbHVlLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRTZWxlY3RlZEl0ZW0oc2VsZWN0ZWRJbmRleDogbnVtYmVyLCBzY3JvbGxJbnRvVmlldzogYm9vbGVhbikge1xuICAgICAgICBjb25zdCBub3JtYWxpemVkSW5kZXggPSB3cmFwQXJvdW5kKFxuICAgICAgICAgICAgc2VsZWN0ZWRJbmRleCxcbiAgICAgICAgICAgIHRoaXMuc3VnZ2VzdGlvbnMubGVuZ3RoXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHByZXZTZWxlY3RlZFN1Z2dlc3Rpb24gPSB0aGlzLnN1Z2dlc3Rpb25zW3RoaXMuc2VsZWN0ZWRJdGVtXTtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRTdWdnZXN0aW9uID0gdGhpcy5zdWdnZXN0aW9uc1tub3JtYWxpemVkSW5kZXhdO1xuXG4gICAgICAgIHByZXZTZWxlY3RlZFN1Z2dlc3Rpb24/LnJlbW92ZUNsYXNzKFwiaXMtc2VsZWN0ZWRcIik7XG4gICAgICAgIHNlbGVjdGVkU3VnZ2VzdGlvbj8uYWRkQ2xhc3MoXCJpcy1zZWxlY3RlZFwiKTtcblxuICAgICAgICB0aGlzLnNlbGVjdGVkSXRlbSA9IG5vcm1hbGl6ZWRJbmRleDtcblxuICAgICAgICBpZiAoc2Nyb2xsSW50b1ZpZXcpIHtcbiAgICAgICAgICAgIHNlbGVjdGVkU3VnZ2VzdGlvbi5zY3JvbGxJbnRvVmlldyhmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBUZXh0SW5wdXRTdWdnZXN0PFQ+IGltcGxlbWVudHMgSVN1Z2dlc3RPd25lcjxUPiB7XG4gICAgcHJvdGVjdGVkIGFwcDogQXBwO1xuICAgIHByb3RlY3RlZCBpbnB1dEVsOiBIVE1MSW5wdXRFbGVtZW50IHwgSFRNTFRleHRBcmVhRWxlbWVudDtcblxuICAgIHByaXZhdGUgcG9wcGVyOiBQb3BwZXJJbnN0YW5jZTtcbiAgICBwcml2YXRlIHNjb3BlOiBTY29wZTtcbiAgICBwcml2YXRlIHN1Z2dlc3RFbDogSFRNTEVsZW1lbnQ7XG4gICAgcHJpdmF0ZSBzdWdnZXN0OiBTdWdnZXN0PFQ+O1xuXG4gICAgY29uc3RydWN0b3IoYXBwOiBBcHAsIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQgfCBIVE1MVGV4dEFyZWFFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuYXBwID0gYXBwO1xuICAgICAgICB0aGlzLmlucHV0RWwgPSBpbnB1dEVsO1xuICAgICAgICB0aGlzLnNjb3BlID0gbmV3IFNjb3BlKCk7XG5cbiAgICAgICAgdGhpcy5zdWdnZXN0RWwgPSBjcmVhdGVEaXYoXCJzdWdnZXN0aW9uLWNvbnRhaW5lclwiKTtcbiAgICAgICAgY29uc3Qgc3VnZ2VzdGlvbiA9IHRoaXMuc3VnZ2VzdEVsLmNyZWF0ZURpdihcInN1Z2dlc3Rpb25cIik7XG4gICAgICAgIHRoaXMuc3VnZ2VzdCA9IG5ldyBTdWdnZXN0KHRoaXMsIHN1Z2dlc3Rpb24sIHRoaXMuc2NvcGUpO1xuXG4gICAgICAgIHRoaXMuc2NvcGUucmVnaXN0ZXIoW10sIFwiRXNjYXBlXCIsIHRoaXMuY2xvc2UuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgdGhpcy5pbnB1dEVsLmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLCB0aGlzLm9uSW5wdXRDaGFuZ2VkLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmlucHV0RWwuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIHRoaXMub25JbnB1dENoYW5nZWQuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuaW5wdXRFbC5hZGRFdmVudExpc3RlbmVyKFwiYmx1clwiLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLnN1Z2dlc3RFbC5vbihcbiAgICAgICAgICAgIFwibW91c2Vkb3duXCIsXG4gICAgICAgICAgICBcIi5zdWdnZXN0aW9uLWNvbnRhaW5lclwiLFxuICAgICAgICAgICAgKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBvbklucHV0Q2hhbmdlZCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgaW5wdXRTdHIgPSB0aGlzLmlucHV0RWwudmFsdWU7XG4gICAgICAgIGNvbnN0IHN1Z2dlc3Rpb25zID0gdGhpcy5nZXRTdWdnZXN0aW9ucyhpbnB1dFN0cik7XG5cbiAgICAgICAgaWYgKCFzdWdnZXN0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN1Z2dlc3Rpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuc3VnZ2VzdC5zZXRTdWdnZXN0aW9ucyhzdWdnZXN0aW9ucyk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgdGhpcy5vcGVuKCg8YW55PnRoaXMuYXBwKS5kb20uYXBwQ29udGFpbmVyRWwsIHRoaXMuaW5wdXRFbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvcGVuKGNvbnRhaW5lcjogSFRNTEVsZW1lbnQsIGlucHV0RWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICg8YW55PnRoaXMuYXBwKS5rZXltYXAucHVzaFNjb3BlKHRoaXMuc2NvcGUpO1xuXG4gICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLnN1Z2dlc3RFbCk7XG4gICAgICAgIHRoaXMucG9wcGVyID0gY3JlYXRlUG9wcGVyKGlucHV0RWwsIHRoaXMuc3VnZ2VzdEVsLCB7XG4gICAgICAgICAgICBwbGFjZW1lbnQ6IFwiYm90dG9tLXN0YXJ0XCIsXG4gICAgICAgICAgICBtb2RpZmllcnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwic2FtZVdpZHRoXCIsXG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGZuOiAoeyBzdGF0ZSwgaW5zdGFuY2UgfSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZTogcG9zaXRpb25pbmcgbmVlZHMgdG8gYmUgY2FsY3VsYXRlZCB0d2ljZSAtXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBmaXJzdCBwYXNzIC0gcG9zaXRpb25pbmcgaXQgYWNjb3JkaW5nIHRvIHRoZSB3aWR0aCBvZiB0aGUgcG9wcGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzZWNvbmQgcGFzcyAtIHBvc2l0aW9uIGl0IHdpdGggdGhlIHdpZHRoIGJvdW5kIHRvIHRoZSByZWZlcmVuY2UgZWxlbWVudFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBlYXJseSBleGl0IHRvIGF2b2lkIGFuIGluZmluaXRlIGxvb3BcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldFdpZHRoID0gYCR7c3RhdGUucmVjdHMucmVmZXJlbmNlLndpZHRofXB4YDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5zdHlsZXMucG9wcGVyLndpZHRoID09PSB0YXJnZXRXaWR0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLnN0eWxlcy5wb3BwZXIud2lkdGggPSB0YXJnZXRXaWR0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnVwZGF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBwaGFzZTogXCJiZWZvcmVXcml0ZVwiLFxuICAgICAgICAgICAgICAgICAgICByZXF1aXJlczogW1wiY29tcHV0ZVN0eWxlc1wiXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY2xvc2UoKTogdm9pZCB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICg8YW55PnRoaXMuYXBwKS5rZXltYXAucG9wU2NvcGUodGhpcy5zY29wZSk7XG5cbiAgICAgICAgdGhpcy5zdWdnZXN0LnNldFN1Z2dlc3Rpb25zKFtdKTtcbiAgICAgICAgaWYgKHRoaXMucG9wcGVyKSB0aGlzLnBvcHBlci5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuc3VnZ2VzdEVsLmRldGFjaCgpO1xuICAgIH1cblxuICAgIGFic3RyYWN0IGdldFN1Z2dlc3Rpb25zKGlucHV0U3RyOiBzdHJpbmcpOiBUW107XG4gICAgYWJzdHJhY3QgcmVuZGVyU3VnZ2VzdGlvbihpdGVtOiBULCBlbDogSFRNTEVsZW1lbnQpOiB2b2lkO1xuICAgIGFic3RyYWN0IHNlbGVjdFN1Z2dlc3Rpb24oaXRlbTogVCk6IHZvaWQ7XG59XG4iLCIvLyBDcmVkaXRzIGdvIHRvIExpYW0ncyBQZXJpb2RpYyBOb3RlcyBQbHVnaW46IGh0dHBzOi8vZ2l0aHViLmNvbS9saWFtY2Fpbi9vYnNpZGlhbi1wZXJpb2RpYy1ub3Rlc1xuXG5pbXBvcnQgeyBUQWJzdHJhY3RGaWxlLCBURm9sZGVyIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5pbXBvcnQgeyBUZXh0SW5wdXRTdWdnZXN0IH0gZnJvbSBcInN1Z2dlc3RlcnMvc3VnZ2VzdFwiO1xuXG5leHBvcnQgY2xhc3MgRm9sZGVyU3VnZ2VzdCBleHRlbmRzIFRleHRJbnB1dFN1Z2dlc3Q8VEZvbGRlcj4ge1xuICAgIGdldFN1Z2dlc3Rpb25zKGlucHV0U3RyOiBzdHJpbmcpOiBURm9sZGVyW10ge1xuICAgICAgICBjb25zdCBhYnN0cmFjdEZpbGVzID0gdGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKTtcbiAgICAgICAgY29uc3QgZm9sZGVyczogVEZvbGRlcltdID0gW107XG4gICAgICAgIGNvbnN0IGxvd2VyQ2FzZUlucHV0U3RyID0gaW5wdXRTdHIudG9Mb3dlckNhc2UoKTtcblxuICAgICAgICBhYnN0cmFjdEZpbGVzLmZvckVhY2goKGZvbGRlcjogVEFic3RyYWN0RmlsZSkgPT4ge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGZvbGRlciBpbnN0YW5jZW9mIFRGb2xkZXIgJiZcbiAgICAgICAgICAgICAgICBmb2xkZXIucGF0aC50b0xvd2VyQ2FzZSgpLmNvbnRhaW5zKGxvd2VyQ2FzZUlucHV0U3RyKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgZm9sZGVycy5wdXNoKGZvbGRlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBmb2xkZXJzO1xuICAgIH1cblxuICAgIHJlbmRlclN1Z2dlc3Rpb24oZmlsZTogVEZvbGRlciwgZWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGVsLnNldFRleHQoZmlsZS5wYXRoKTtcbiAgICB9XG5cbiAgICBzZWxlY3RTdWdnZXN0aW9uKGZpbGU6IFRGb2xkZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pbnB1dEVsLnZhbHVlID0gZmlsZS5wYXRoO1xuICAgICAgICB0aGlzLmlucHV0RWwudHJpZ2dlcihcImlucHV0XCIpO1xuICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgVGVtcGxhdGVyRXJyb3IgfSBmcm9tIFwiRXJyb3JcIjtcbmltcG9ydCB7XG4gICAgQXBwLFxuICAgIG5vcm1hbGl6ZVBhdGgsXG4gICAgVEFic3RyYWN0RmlsZSxcbiAgICBURmlsZSxcbiAgICBURm9sZGVyLFxuICAgIFZhdWx0LFxufSBmcm9tIFwib2JzaWRpYW5cIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZV9SZWdFeHAoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csIFwiXFxcXCQmXCIpOyAvLyAkJiBtZWFucyB0aGUgd2hvbGUgbWF0Y2hlZCBzdHJpbmdcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlX2NvbW1hbmRfcmVnZXgoKTogUmVnRXhwIHtcbiAgICByZXR1cm4gLzwlKD86LXxfKT9cXHMqWyp+XXswLDF9KCg/Oi58XFxzKSo/KSg/Oi18Xyk/JT4vZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlX2R5bmFtaWNfY29tbWFuZF9yZWdleCgpOiBSZWdFeHAge1xuICAgIHJldHVybiAvKDwlKD86LXxfKT9cXHMqWyp+XXswLDF9KVxcKygoPzoufFxccykqPyU+KS9nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZV90Zm9sZGVyKGFwcDogQXBwLCBmb2xkZXJfc3RyOiBzdHJpbmcpOiBURm9sZGVyIHtcbiAgICBmb2xkZXJfc3RyID0gbm9ybWFsaXplUGF0aChmb2xkZXJfc3RyKTtcblxuICAgIGNvbnN0IGZvbGRlciA9IGFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyX3N0cik7XG4gICAgaWYgKCFmb2xkZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFRlbXBsYXRlckVycm9yKGBGb2xkZXIgXCIke2ZvbGRlcl9zdHJ9XCIgZG9lc24ndCBleGlzdGApO1xuICAgIH1cbiAgICBpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkge1xuICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVyRXJyb3IoYCR7Zm9sZGVyX3N0cn0gaXMgYSBmaWxlLCBub3QgYSBmb2xkZXJgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZm9sZGVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZV90ZmlsZShhcHA6IEFwcCwgZmlsZV9zdHI6IHN0cmluZyk6IFRGaWxlIHtcbiAgICBmaWxlX3N0ciA9IG5vcm1hbGl6ZVBhdGgoZmlsZV9zdHIpO1xuXG4gICAgY29uc3QgZmlsZSA9IGFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZmlsZV9zdHIpO1xuICAgIGlmICghZmlsZSkge1xuICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVyRXJyb3IoYEZpbGUgXCIke2ZpbGVfc3RyfVwiIGRvZXNuJ3QgZXhpc3RgKTtcbiAgICB9XG4gICAgaWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVyRXJyb3IoYCR7ZmlsZV9zdHJ9IGlzIGEgZm9sZGVyLCBub3QgYSBmaWxlYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRfdGZpbGVzX2Zyb21fZm9sZGVyKFxuICAgIGFwcDogQXBwLFxuICAgIGZvbGRlcl9zdHI6IHN0cmluZ1xuKTogQXJyYXk8VEZpbGU+IHtcbiAgICBjb25zdCBmb2xkZXIgPSByZXNvbHZlX3Rmb2xkZXIoYXBwLCBmb2xkZXJfc3RyKTtcblxuICAgIGNvbnN0IGZpbGVzOiBBcnJheTxURmlsZT4gPSBbXTtcbiAgICBWYXVsdC5yZWN1cnNlQ2hpbGRyZW4oZm9sZGVyLCAoZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xuICAgICAgICBpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XG4gICAgICAgICAgICBmaWxlcy5wdXNoKGZpbGUpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBmaWxlcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgIHJldHVybiBhLmJhc2VuYW1lLmxvY2FsZUNvbXBhcmUoYi5iYXNlbmFtZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZmlsZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcnJheW1vdmU8VD4oXG4gICAgYXJyOiBUW10sXG4gICAgZnJvbUluZGV4OiBudW1iZXIsXG4gICAgdG9JbmRleDogbnVtYmVyXG4pOiB2b2lkIHtcbiAgICBpZiAodG9JbmRleCA8IDAgfHwgdG9JbmRleCA9PT0gYXJyLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGVsZW1lbnQgPSBhcnJbZnJvbUluZGV4XTtcbiAgICBhcnJbZnJvbUluZGV4XSA9IGFyclt0b0luZGV4XTtcbiAgICBhcnJbdG9JbmRleF0gPSBlbGVtZW50O1xufVxuIiwiLy8gQ3JlZGl0cyBnbyB0byBMaWFtJ3MgUGVyaW9kaWMgTm90ZXMgUGx1Z2luOiBodHRwczovL2dpdGh1Yi5jb20vbGlhbWNhaW4vb2JzaWRpYW4tcGVyaW9kaWMtbm90ZXNcblxuaW1wb3J0IHsgQXBwLCBUQWJzdHJhY3RGaWxlLCBURmlsZSB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgVGV4dElucHV0U3VnZ2VzdCB9IGZyb20gXCJzdWdnZXN0ZXJzL3N1Z2dlc3RcIjtcbmltcG9ydCB7IGdldF90ZmlsZXNfZnJvbV9mb2xkZXIgfSBmcm9tIFwiVXRpbHNcIjtcbmltcG9ydCBUZW1wbGF0ZXJQbHVnaW4gZnJvbSBcIm1haW5cIjtcbmltcG9ydCB7IGVycm9yV3JhcHBlclN5bmMgfSBmcm9tIFwiRXJyb3JcIjtcblxuZXhwb3J0IGVudW0gRmlsZVN1Z2dlc3RNb2RlIHtcbiAgICBUZW1wbGF0ZUZpbGVzLFxuICAgIFNjcmlwdEZpbGVzLFxufVxuXG5leHBvcnQgY2xhc3MgRmlsZVN1Z2dlc3QgZXh0ZW5kcyBUZXh0SW5wdXRTdWdnZXN0PFRGaWxlPiB7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHB1YmxpYyBhcHA6IEFwcCxcbiAgICAgICAgcHVibGljIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQsXG4gICAgICAgIHByaXZhdGUgcGx1Z2luOiBUZW1wbGF0ZXJQbHVnaW4sXG4gICAgICAgIHByaXZhdGUgbW9kZTogRmlsZVN1Z2dlc3RNb2RlXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGFwcCwgaW5wdXRFbCk7XG4gICAgfVxuXG4gICAgZ2V0X2ZvbGRlcihtb2RlOiBGaWxlU3VnZ2VzdE1vZGUpOiBzdHJpbmcge1xuICAgICAgICBzd2l0Y2ggKG1vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgRmlsZVN1Z2dlc3RNb2RlLlRlbXBsYXRlRmlsZXM6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlc19mb2xkZXI7XG4gICAgICAgICAgICBjYXNlIEZpbGVTdWdnZXN0TW9kZS5TY3JpcHRGaWxlczpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlcl9zY3JpcHRzX2ZvbGRlcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF9lcnJvcl9tc2cobW9kZTogRmlsZVN1Z2dlc3RNb2RlKTogc3RyaW5nIHtcbiAgICAgICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICAgICAgICBjYXNlIEZpbGVTdWdnZXN0TW9kZS5UZW1wbGF0ZUZpbGVzOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVGVtcGxhdGVzIGZvbGRlciBkb2Vzbid0IGV4aXN0YDtcbiAgICAgICAgICAgIGNhc2UgRmlsZVN1Z2dlc3RNb2RlLlNjcmlwdEZpbGVzOlxuICAgICAgICAgICAgICAgIHJldHVybiBgVXNlciBTY3JpcHRzIGZvbGRlciBkb2Vzbid0IGV4aXN0YDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldFN1Z2dlc3Rpb25zKGlucHV0X3N0cjogc3RyaW5nKTogVEZpbGVbXSB7XG4gICAgICAgIGNvbnN0IGFsbF9maWxlcyA9IGVycm9yV3JhcHBlclN5bmMoXG4gICAgICAgICAgICAoKSA9PiBnZXRfdGZpbGVzX2Zyb21fZm9sZGVyKHRoaXMuYXBwLCB0aGlzLmdldF9mb2xkZXIodGhpcy5tb2RlKSksXG4gICAgICAgICAgICB0aGlzLmdldF9lcnJvcl9tc2codGhpcy5tb2RlKVxuICAgICAgICApO1xuICAgICAgICBpZiAoIWFsbF9maWxlcykge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlsZXM6IFRGaWxlW10gPSBbXTtcbiAgICAgICAgY29uc3QgbG93ZXJfaW5wdXRfc3RyID0gaW5wdXRfc3RyLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgYWxsX2ZpbGVzLmZvckVhY2goKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+IHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBmaWxlIGluc3RhbmNlb2YgVEZpbGUgJiZcbiAgICAgICAgICAgICAgICBmaWxlLmV4dGVuc2lvbiA9PT0gXCJtZFwiICYmXG4gICAgICAgICAgICAgICAgZmlsZS5wYXRoLnRvTG93ZXJDYXNlKCkuY29udGFpbnMobG93ZXJfaW5wdXRfc3RyKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgZmlsZXMucHVzaChmaWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGZpbGVzO1xuICAgIH1cblxuICAgIHJlbmRlclN1Z2dlc3Rpb24oZmlsZTogVEZpbGUsIGVsOiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgICAgICBlbC5zZXRUZXh0KGZpbGUucGF0aCk7XG4gICAgfVxuXG4gICAgc2VsZWN0U3VnZ2VzdGlvbihmaWxlOiBURmlsZSk6IHZvaWQge1xuICAgICAgICB0aGlzLmlucHV0RWwudmFsdWUgPSBmaWxlLnBhdGg7XG4gICAgICAgIHRoaXMuaW5wdXRFbC50cmlnZ2VyKFwiaW5wdXRcIik7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBBcHAsIEJ1dHRvbkNvbXBvbmVudCwgUGx1Z2luU2V0dGluZ1RhYiwgU2V0dGluZyB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgZXJyb3JXcmFwcGVyU3luYywgVGVtcGxhdGVyRXJyb3IgfSBmcm9tIFwiRXJyb3JcIjtcbmltcG9ydCB7IEZvbGRlclN1Z2dlc3QgfSBmcm9tIFwic3VnZ2VzdGVycy9Gb2xkZXJTdWdnZXN0ZXJcIjtcbmltcG9ydCB7IEZpbGVTdWdnZXN0LCBGaWxlU3VnZ2VzdE1vZGUgfSBmcm9tIFwic3VnZ2VzdGVycy9GaWxlU3VnZ2VzdGVyXCI7XG5pbXBvcnQgVGVtcGxhdGVyUGx1Z2luIGZyb20gXCIuL21haW5cIjtcbmltcG9ydCB7IGFycmF5bW92ZSwgZ2V0X3RmaWxlc19mcm9tX2ZvbGRlciB9IGZyb20gXCJVdGlsc1wiO1xuaW1wb3J0IHsgbG9nX2Vycm9yIH0gZnJvbSBcIkxvZ1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZvbGRlclRlbXBsYXRlIHtcbiAgICBmb2xkZXI6IHN0cmluZztcbiAgICB0ZW1wbGF0ZTogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogU2V0dGluZ3MgPSB7XG4gICAgY29tbWFuZF90aW1lb3V0OiA1LFxuICAgIHRlbXBsYXRlc19mb2xkZXI6IFwiXCIsXG4gICAgdGVtcGxhdGVzX3BhaXJzOiBbW1wiXCIsIFwiXCJdXSxcbiAgICB0cmlnZ2VyX29uX2ZpbGVfY3JlYXRpb246IGZhbHNlLFxuICAgIGF1dG9fanVtcF90b19jdXJzb3I6IGZhbHNlLFxuICAgIGVuYWJsZV9zeXN0ZW1fY29tbWFuZHM6IGZhbHNlLFxuICAgIHNoZWxsX3BhdGg6IFwiXCIsXG4gICAgdXNlcl9zY3JpcHRzX2ZvbGRlcjogXCJcIixcbiAgICBlbmFibGVfZm9sZGVyX3RlbXBsYXRlczogdHJ1ZSxcbiAgICBmb2xkZXJfdGVtcGxhdGVzOiBbeyBmb2xkZXI6IFwiXCIsIHRlbXBsYXRlOiBcIlwiIH1dLFxuICAgIHN5bnRheF9oaWdobGlnaHRpbmc6IHRydWUsXG4gICAgZW5hYmxlZF90ZW1wbGF0ZXNfaG90a2V5czogW1wiXCJdLFxuICAgIHN0YXJ0dXBfdGVtcGxhdGVzOiBbXCJcIl0sXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFNldHRpbmdzIHtcbiAgICBjb21tYW5kX3RpbWVvdXQ6IG51bWJlcjtcbiAgICB0ZW1wbGF0ZXNfZm9sZGVyOiBzdHJpbmc7XG4gICAgdGVtcGxhdGVzX3BhaXJzOiBBcnJheTxbc3RyaW5nLCBzdHJpbmddPjtcbiAgICB0cmlnZ2VyX29uX2ZpbGVfY3JlYXRpb246IGJvb2xlYW47XG4gICAgYXV0b19qdW1wX3RvX2N1cnNvcjogYm9vbGVhbjtcbiAgICBlbmFibGVfc3lzdGVtX2NvbW1hbmRzOiBib29sZWFuO1xuICAgIHNoZWxsX3BhdGg6IHN0cmluZztcbiAgICB1c2VyX3NjcmlwdHNfZm9sZGVyOiBzdHJpbmc7XG4gICAgZW5hYmxlX2ZvbGRlcl90ZW1wbGF0ZXM6IGJvb2xlYW47XG4gICAgZm9sZGVyX3RlbXBsYXRlczogQXJyYXk8Rm9sZGVyVGVtcGxhdGU+O1xuICAgIHN5bnRheF9oaWdobGlnaHRpbmc6IGJvb2xlYW47XG4gICAgZW5hYmxlZF90ZW1wbGF0ZXNfaG90a2V5czogQXJyYXk8c3RyaW5nPjtcbiAgICBzdGFydHVwX3RlbXBsYXRlczogQXJyYXk8c3RyaW5nPjtcbn1cblxuZXhwb3J0IGNsYXNzIFRlbXBsYXRlclNldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgYXBwOiBBcHAsIHByaXZhdGUgcGx1Z2luOiBUZW1wbGF0ZXJQbHVnaW4pIHtcbiAgICAgICAgc3VwZXIoYXBwLCBwbHVnaW4pO1xuICAgIH1cblxuICAgIGRpc3BsYXkoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuZW1wdHkoKTtcblxuICAgICAgICB0aGlzLmFkZF9nZW5lcmFsX3NldHRpbmdfaGVhZGVyKCk7XG4gICAgICAgIHRoaXMuYWRkX3RlbXBsYXRlX2ZvbGRlcl9zZXR0aW5nKCk7XG4gICAgICAgIHRoaXMuYWRkX2ludGVybmFsX2Z1bmN0aW9uc19zZXR0aW5nKCk7XG4gICAgICAgIHRoaXMuYWRkX3N5bnRheF9oaWdobGlnaHRpbmdfc2V0dGluZygpO1xuICAgICAgICB0aGlzLmFkZF9hdXRvX2p1bXBfdG9fY3Vyc29yKCk7XG4gICAgICAgIHRoaXMuYWRkX3RyaWdnZXJfb25fbmV3X2ZpbGVfY3JlYXRpb25fc2V0dGluZygpO1xuICAgICAgICB0aGlzLmFkZF90ZW1wbGF0ZXNfaG90a2V5c19zZXR0aW5nKCk7XG4gICAgICAgIGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy50cmlnZ2VyX29uX2ZpbGVfY3JlYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuYWRkX2ZvbGRlcl90ZW1wbGF0ZXNfc2V0dGluZygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWRkX3N0YXJ0dXBfdGVtcGxhdGVzX3NldHRpbmcoKTtcbiAgICAgICAgdGhpcy5hZGRfdXNlcl9zY3JpcHRfZnVuY3Rpb25zX3NldHRpbmcoKTtcbiAgICAgICAgdGhpcy5hZGRfdXNlcl9zeXN0ZW1fY29tbWFuZF9mdW5jdGlvbnNfc2V0dGluZygpO1xuICAgIH1cblxuICAgIGFkZF9nZW5lcmFsX3NldHRpbmdfaGVhZGVyKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiBcIkdlbmVyYWwgU2V0dGluZ3NcIiB9KTtcbiAgICB9XG5cbiAgICBhZGRfdGVtcGxhdGVfZm9sZGVyX3NldHRpbmcoKTogdm9pZCB7XG4gICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXG4gICAgICAgICAgICAuc2V0TmFtZShcIlRlbXBsYXRlIGZvbGRlciBsb2NhdGlvblwiKVxuICAgICAgICAgICAgLnNldERlc2MoXCJGaWxlcyBpbiB0aGlzIGZvbGRlciB3aWxsIGJlIGF2YWlsYWJsZSBhcyB0ZW1wbGF0ZXMuXCIpXG4gICAgICAgICAgICAuYWRkU2VhcmNoKChjYikgPT4ge1xuICAgICAgICAgICAgICAgIG5ldyBGb2xkZXJTdWdnZXN0KHRoaXMuYXBwLCBjYi5pbnB1dEVsKTtcbiAgICAgICAgICAgICAgICBjYi5zZXRQbGFjZWhvbGRlcihcIkV4YW1wbGU6IGZvbGRlcjEvZm9sZGVyMlwiKVxuICAgICAgICAgICAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVzX2ZvbGRlcilcbiAgICAgICAgICAgICAgICAgICAgLm9uQ2hhbmdlKChuZXdfZm9sZGVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50ZW1wbGF0ZXNfZm9sZGVyID0gbmV3X2ZvbGRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVfc2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKFwidGVtcGxhdGVyX3NlYXJjaFwiKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFkZF9pbnRlcm5hbF9mdW5jdGlvbnNfc2V0dGluZygpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGVzYyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZGVzYy5hcHBlbmQoXG4gICAgICAgICAgICBcIlRlbXBsYXRlciBwcm92aWRlcyBtdWx0aXBsZXMgcHJlZGVmaW5lZCB2YXJpYWJsZXMgLyBmdW5jdGlvbnMgdGhhdCB5b3UgY2FuIHVzZS5cIixcbiAgICAgICAgICAgIGRlc2MuY3JlYXRlRWwoXCJiclwiKSxcbiAgICAgICAgICAgIFwiQ2hlY2sgdGhlIFwiLFxuICAgICAgICAgICAgZGVzYy5jcmVhdGVFbChcImFcIiwge1xuICAgICAgICAgICAgICAgIGhyZWY6IFwiaHR0cHM6Ly9zaWxlbnR2b2lkMTMuZ2l0aHViLmlvL1RlbXBsYXRlci9cIixcbiAgICAgICAgICAgICAgICB0ZXh0OiBcImRvY3VtZW50YXRpb25cIixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgXCIgdG8gZ2V0IGEgbGlzdCBvZiBhbGwgdGhlIGF2YWlsYWJsZSBpbnRlcm5hbCB2YXJpYWJsZXMgLyBmdW5jdGlvbnMuXCJcbiAgICAgICAgKTtcblxuICAgICAgICBuZXcgU2V0dGluZyh0aGlzLmNvbnRhaW5lckVsKVxuICAgICAgICAgICAgLnNldE5hbWUoXCJJbnRlcm5hbCBWYXJpYWJsZXMgYW5kIEZ1bmN0aW9uc1wiKVxuICAgICAgICAgICAgLnNldERlc2MoZGVzYyk7XG4gICAgfVxuXG4gICAgYWRkX3N5bnRheF9oaWdobGlnaHRpbmdfc2V0dGluZygpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGVzYyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZGVzYy5hcHBlbmQoXG4gICAgICAgICAgICBcIkFkZHMgc3ludGF4IGhpZ2hsaWdodGluZyBmb3IgVGVtcGxhdGVyIGNvbW1hbmRzIGluIGVkaXQgbW9kZS5cIlxuICAgICAgICApO1xuXG4gICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXG4gICAgICAgICAgICAuc2V0TmFtZShcIlN5bnRheCBIaWdobGlnaHRpbmdcIilcbiAgICAgICAgICAgIC5zZXREZXNjKGRlc2MpXG4gICAgICAgICAgICAuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcbiAgICAgICAgICAgICAgICB0b2dnbGVcbiAgICAgICAgICAgICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bnRheF9oaWdobGlnaHRpbmcpXG4gICAgICAgICAgICAgICAgICAgIC5vbkNoYW5nZSgoc3ludGF4X2hpZ2hsaWdodGluZykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3Muc3ludGF4X2hpZ2hsaWdodGluZyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4X2hpZ2hsaWdodGluZztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVfc2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLmV2ZW50X2hhbmRsZXIudXBkYXRlX3N5bnRheF9oaWdobGlnaHRpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhZGRfYXV0b19qdW1wX3RvX2N1cnNvcigpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGVzYyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZGVzYy5hcHBlbmQoXG4gICAgICAgICAgICBcIkF1dG9tYXRpY2FsbHkgdHJpZ2dlcnMgXCIsXG4gICAgICAgICAgICBkZXNjLmNyZWF0ZUVsKFwiY29kZVwiLCB7IHRleHQ6IFwidHAuZmlsZS5jdXJzb3JcIiB9KSxcbiAgICAgICAgICAgIFwiIGFmdGVyIGluc2VydGluZyBhIHRlbXBsYXRlLlwiLFxuICAgICAgICAgICAgZGVzYy5jcmVhdGVFbChcImJyXCIpLFxuICAgICAgICAgICAgXCJZb3UgY2FuIGFsc28gc2V0IGEgaG90a2V5IHRvIG1hbnVhbGx5IHRyaWdnZXIgXCIsXG4gICAgICAgICAgICBkZXNjLmNyZWF0ZUVsKFwiY29kZVwiLCB7IHRleHQ6IFwidHAuZmlsZS5jdXJzb3JcIiB9KSxcbiAgICAgICAgICAgIFwiLlwiXG4gICAgICAgICk7XG5cbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbClcbiAgICAgICAgICAgIC5zZXROYW1lKFwiQXV0b21hdGljIGp1bXAgdG8gY3Vyc29yXCIpXG4gICAgICAgICAgICAuc2V0RGVzYyhkZXNjKVxuICAgICAgICAgICAgLmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XG4gICAgICAgICAgICAgICAgdG9nZ2xlXG4gICAgICAgICAgICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvX2p1bXBfdG9fY3Vyc29yKVxuICAgICAgICAgICAgICAgICAgICAub25DaGFuZ2UoKGF1dG9fanVtcF90b19jdXJzb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmF1dG9fanVtcF90b19jdXJzb3IgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9fanVtcF90b19jdXJzb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYWRkX3RyaWdnZXJfb25fbmV3X2ZpbGVfY3JlYXRpb25fc2V0dGluZygpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGVzYyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZGVzYy5hcHBlbmQoXG4gICAgICAgICAgICBcIlRlbXBsYXRlciB3aWxsIGxpc3RlbiBmb3IgdGhlIG5ldyBmaWxlIGNyZWF0aW9uIGV2ZW50LCBhbmQgcmVwbGFjZSBldmVyeSBjb21tYW5kIGl0IGZpbmRzIGluIHRoZSBuZXcgZmlsZSdzIGNvbnRlbnQuXCIsXG4gICAgICAgICAgICBkZXNjLmNyZWF0ZUVsKFwiYnJcIiksXG4gICAgICAgICAgICBcIlRoaXMgbWFrZXMgVGVtcGxhdGVyIGNvbXBhdGlibGUgd2l0aCBvdGhlciBwbHVnaW5zIGxpa2UgdGhlIERhaWx5IG5vdGUgY29yZSBwbHVnaW4sIENhbGVuZGFyIHBsdWdpbiwgUmV2aWV3IHBsdWdpbiwgTm90ZSByZWZhY3RvciBwbHVnaW4sIC4uLlwiLFxuICAgICAgICAgICAgZGVzYy5jcmVhdGVFbChcImJyXCIpLFxuICAgICAgICAgICAgZGVzYy5jcmVhdGVFbChcImJcIiwge1xuICAgICAgICAgICAgICAgIHRleHQ6IFwiV2FybmluZzogXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIFwiVGhpcyBjYW4gYmUgZGFuZ2Vyb3VzIGlmIHlvdSBjcmVhdGUgbmV3IGZpbGVzIHdpdGggdW5rbm93biAvIHVuc2FmZSBjb250ZW50IG9uIGNyZWF0aW9uLiBNYWtlIHN1cmUgdGhhdCBldmVyeSBuZXcgZmlsZSdzIGNvbnRlbnQgaXMgc2FmZSBvbiBjcmVhdGlvbi5cIlxuICAgICAgICApO1xuXG4gICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXG4gICAgICAgICAgICAuc2V0TmFtZShcIlRyaWdnZXIgVGVtcGxhdGVyIG9uIG5ldyBmaWxlIGNyZWF0aW9uXCIpXG4gICAgICAgICAgICAuc2V0RGVzYyhkZXNjKVxuICAgICAgICAgICAgLmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XG4gICAgICAgICAgICAgICAgdG9nZ2xlXG4gICAgICAgICAgICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy50cmlnZ2VyX29uX2ZpbGVfY3JlYXRpb24pXG4gICAgICAgICAgICAgICAgICAgIC5vbkNoYW5nZSgodHJpZ2dlcl9vbl9maWxlX2NyZWF0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50cmlnZ2VyX29uX2ZpbGVfY3JlYXRpb24gPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJfb25fZmlsZV9jcmVhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVfc2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLmV2ZW50X2hhbmRsZXIudXBkYXRlX3RyaWdnZXJfZmlsZV9vbl9jcmVhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yY2UgcmVmcmVzaFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYWRkX3RlbXBsYXRlc19ob3RrZXlzX3NldHRpbmcoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRWwoXCJoMlwiLCB7IHRleHQ6IFwiVGVtcGxhdGUgSG90a2V5c1wiIH0pO1xuXG4gICAgICAgIGNvbnN0IGRlc2MgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICAgIGRlc2MuYXBwZW5kKFxuICAgICAgICAgICAgXCJUZW1wbGF0ZSBIb3RrZXlzIGFsbG93cyB5b3UgdG8gYmluZCBhIHRlbXBsYXRlIHRvIGEgaG90a2V5LlwiXG4gICAgICAgICk7XG5cbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbCkuc2V0RGVzYyhkZXNjKTtcblxuICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5lbmFibGVkX3RlbXBsYXRlc19ob3RrZXlzLmZvckVhY2goXG4gICAgICAgICAgICAodGVtcGxhdGUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcyA9IG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXG4gICAgICAgICAgICAgICAgICAgIC5hZGRTZWFyY2goKGNiKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZVN1Z2dlc3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2IuaW5wdXRFbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlU3VnZ2VzdE1vZGUuVGVtcGxhdGVGaWxlc1xuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNiLnNldFBsYWNlaG9sZGVyKFwiRXhhbXBsZTogZm9sZGVyMS90ZW1wbGF0ZV9maWxlXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFZhbHVlKHRlbXBsYXRlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbkNoYW5nZSgobmV3X3RlbXBsYXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld190ZW1wbGF0ZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZW5hYmxlZF90ZW1wbGF0ZXNfaG90a2V5cy5jb250YWlucyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdfdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dfZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFRlbXBsYXRlckVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlRoaXMgdGVtcGxhdGUgaXMgYWxyZWFkeSBib3VuZCB0byBhIGhvdGtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5jb21tYW5kX2hhbmRsZXIuYWRkX3RlbXBsYXRlX2hvdGtleShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVuYWJsZWRfdGVtcGxhdGVzX2hvdGtleXNbaW5kZXhdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X3RlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmVuYWJsZWRfdGVtcGxhdGVzX2hvdGtleXNbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdID0gbmV3X3RlbXBsYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICBjYi5jb250YWluZXJFbC5hZGRDbGFzcyhcInRlbXBsYXRlcl9zZWFyY2hcIik7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5hZGRFeHRyYUJ1dHRvbigoY2IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNiLnNldEljb24oXCJhbnkta2V5XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFRvb2x0aXAoXCJDb25maWd1cmUgSG90a2V5XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBSZXBsYWNlIHdpdGggZnV0dXJlIFwib2ZmaWNpYWxcIiB3YXkgdG8gZG8gdGhpc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwLnNldHRpbmcub3BlblRhYkJ5SWQoXCJob3RrZXlzXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhYiA9IHRoaXMuYXBwLnNldHRpbmcuYWN0aXZlVGFiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWIuc2VhcmNoSW5wdXRFbC52YWx1ZSA9IFwiVGVtcGxhdGVyOiBJbnNlcnRcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFiLnVwZGF0ZUhvdGtleVZpc2liaWxpdHkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmFkZEV4dHJhQnV0dG9uKChjYikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2Iuc2V0SWNvbihcInVwLWNoZXZyb24tZ2x5cGhcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0VG9vbHRpcChcIk1vdmUgdXBcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub25DbGljaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5bW92ZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVuYWJsZWRfdGVtcGxhdGVzX2hvdGtleXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4IC0gMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuYWRkRXh0cmFCdXR0b24oKGNiKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYi5zZXRJY29uKFwiZG93bi1jaGV2cm9uLWdseXBoXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFRvb2x0aXAoXCJNb3ZlIGRvd25cIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub25DbGljaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5bW92ZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmVuYWJsZWRfdGVtcGxhdGVzX2hvdGtleXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ICsgMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuYWRkRXh0cmFCdXR0b24oKGNiKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYi5zZXRJY29uKFwiY3Jvc3NcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0VG9vbHRpcChcIkRlbGV0ZVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uY29tbWFuZF9oYW5kbGVyLnJlbW92ZV90ZW1wbGF0ZV9ob3RrZXkoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5nc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5lbmFibGVkX3RlbXBsYXRlc19ob3RrZXlzW2luZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5lbmFibGVkX3RlbXBsYXRlc19ob3RrZXlzLnNwbGljZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvcmNlIHJlZnJlc2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHMuaW5mb0VsLnJlbW92ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpLmFkZEJ1dHRvbigoY2IpID0+IHtcbiAgICAgICAgICAgIGNiLnNldEJ1dHRvblRleHQoXCJBZGQgbmV3IGhvdGtleSBmb3IgdGVtcGxhdGVcIilcbiAgICAgICAgICAgICAgICAuc2V0Q3RhKClcbiAgICAgICAgICAgICAgICAub25DbGljaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmVuYWJsZWRfdGVtcGxhdGVzX2hvdGtleXMucHVzaChcIlwiKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZV9zZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAvLyBGb3JjZSByZWZyZXNoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhZGRfZm9sZGVyX3RlbXBsYXRlc19zZXR0aW5nKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiBcIkZvbGRlciBUZW1wbGF0ZXNcIiB9KTtcblxuICAgICAgICBjb25zdCBkZXNjSGVhZGluZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZGVzY0hlYWRpbmcuYXBwZW5kKFxuICAgICAgICAgICAgXCJGb2xkZXIgVGVtcGxhdGVzIGFyZSB0cmlnZ2VyZWQgd2hlbiBhIG5ldyBcIixcbiAgICAgICAgICAgIGRlc2NIZWFkaW5nLmNyZWF0ZUVsKFwic3Ryb25nXCIsIHsgdGV4dDogXCJlbXB0eSBcIiB9KSxcbiAgICAgICAgICAgIFwiZmlsZSBpcyBjcmVhdGVkIGluIGEgZ2l2ZW4gZm9sZGVyLlwiLFxuICAgICAgICAgICAgZGVzY0hlYWRpbmcuY3JlYXRlRWwoXCJiclwiKSxcbiAgICAgICAgICAgIFwiVGVtcGxhdGVyIHdpbGwgZmlsbCB0aGUgZW1wdHkgZmlsZSB3aXRoIHRoZSBzcGVjaWZpZWQgdGVtcGxhdGUuXCIsXG4gICAgICAgICAgICBkZXNjSGVhZGluZy5jcmVhdGVFbChcImJyXCIpLFxuICAgICAgICAgICAgXCJUaGUgZGVlcGVzdCBtYXRjaCBpcyB1c2VkLiBBIGdsb2JhbCBkZWZhdWx0IHRlbXBsYXRlIHdvdWxkIGJlIGRlZmluZWQgb24gdGhlIHJvb3QgXCIsXG4gICAgICAgICAgICBkZXNjSGVhZGluZy5jcmVhdGVFbChcImNvZGVcIiwgeyB0ZXh0OiBcIi9cIiB9KSxcbiAgICAgICAgICAgIFwiLlwiXG4gICAgICAgICk7XG5cbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbCkuc2V0RGVzYyhkZXNjSGVhZGluZyk7XG5cbiAgICAgICAgY29uc3QgZGVzY1VzZU5ld0ZpbGVUZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZGVzY1VzZU5ld0ZpbGVUZW1wbGF0ZS5hcHBlbmQoXG4gICAgICAgICAgICBcIldoZW4gZW5hYmxlZCBUZW1wbGF0ZXIgd2lsbCBtYWtlIHVzZSBvZiB0aGUgZm9sZGVyIHRlbXBsYXRlcyBkZWZpbmVkIGJlbG93LlwiXG4gICAgICAgICk7XG5cbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbClcbiAgICAgICAgICAgIC5zZXROYW1lKFwiRW5hYmxlIEZvbGRlciBUZW1wbGF0ZXNcIilcbiAgICAgICAgICAgIC5zZXREZXNjKGRlc2NVc2VOZXdGaWxlVGVtcGxhdGUpXG4gICAgICAgICAgICAuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcbiAgICAgICAgICAgICAgICB0b2dnbGVcbiAgICAgICAgICAgICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmVuYWJsZV9mb2xkZXJfdGVtcGxhdGVzKVxuICAgICAgICAgICAgICAgICAgICAub25DaGFuZ2UoKHVzZV9uZXdfZmlsZV90ZW1wbGF0ZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmVuYWJsZV9mb2xkZXJfdGVtcGxhdGVzID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VfbmV3X2ZpbGVfdGVtcGxhdGVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZV9zZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yY2UgcmVmcmVzaFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCF0aGlzLnBsdWdpbi5zZXR0aW5ncy5lbmFibGVfZm9sZGVyX3RlbXBsYXRlcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbClcbiAgICAgICAgICAgIC5zZXROYW1lKFwiQWRkIE5ld1wiKVxuICAgICAgICAgICAgLnNldERlc2MoXCJBZGQgbmV3IGZvbGRlciB0ZW1wbGF0ZVwiKVxuICAgICAgICAgICAgLmFkZEJ1dHRvbigoYnV0dG9uOiBCdXR0b25Db21wb25lbnQpID0+IHtcbiAgICAgICAgICAgICAgICBidXR0b25cbiAgICAgICAgICAgICAgICAgICAgLnNldFRvb2x0aXAoXCJBZGQgYWRkaXRpb25hbCBmb2xkZXIgdGVtcGxhdGVcIilcbiAgICAgICAgICAgICAgICAgICAgLnNldEJ1dHRvblRleHQoXCIrXCIpXG4gICAgICAgICAgICAgICAgICAgIC5zZXRDdGEoKVxuICAgICAgICAgICAgICAgICAgICAub25DbGljaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJfdGVtcGxhdGVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbGRlcjogXCJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZTogXCJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZV9zZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZm9sZGVyX3RlbXBsYXRlcy5mb3JFYWNoKFxuICAgICAgICAgICAgKGZvbGRlcl90ZW1wbGF0ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzID0gbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbClcbiAgICAgICAgICAgICAgICAgICAgLmFkZFNlYXJjaCgoY2IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGb2xkZXJTdWdnZXN0KHRoaXMuYXBwLCBjYi5pbnB1dEVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNiLnNldFBsYWNlaG9sZGVyKFwiRm9sZGVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFZhbHVlKGZvbGRlcl90ZW1wbGF0ZS5mb2xkZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uQ2hhbmdlKChuZXdfZm9sZGVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld19mb2xkZXIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlcl90ZW1wbGF0ZXMuc29tZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZSkgPT4gZS5mb2xkZXIgPT0gbmV3X2ZvbGRlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ19lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVGVtcGxhdGVyRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiVGhpcyBmb2xkZXIgYWxyZWFkeSBoYXMgYSB0ZW1wbGF0ZSBhc3NvY2lhdGVkIHdpdGggaXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJfdGVtcGxhdGVzW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXS5mb2xkZXIgPSBuZXdfZm9sZGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICBjYi5jb250YWluZXJFbC5hZGRDbGFzcyhcInRlbXBsYXRlcl9zZWFyY2hcIik7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5hZGRTZWFyY2goKGNiKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZVN1Z2dlc3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2IuaW5wdXRFbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlU3VnZ2VzdE1vZGUuVGVtcGxhdGVGaWxlc1xuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNiLnNldFBsYWNlaG9sZGVyKFwiVGVtcGxhdGVcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0VmFsdWUoZm9sZGVyX3RlbXBsYXRlLnRlbXBsYXRlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbkNoYW5nZSgobmV3X3RlbXBsYXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlcl90ZW1wbGF0ZXNbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLnRlbXBsYXRlID0gbmV3X3RlbXBsYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICBjYi5jb250YWluZXJFbC5hZGRDbGFzcyhcInRlbXBsYXRlcl9zZWFyY2hcIik7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5hZGRFeHRyYUJ1dHRvbigoY2IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNiLnNldEljb24oXCJ1cC1jaGV2cm9uLWdseXBoXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFRvb2x0aXAoXCJNb3ZlIHVwXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheW1vdmUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJfdGVtcGxhdGVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCAtIDFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZV9zZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmFkZEV4dHJhQnV0dG9uKChjYikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2Iuc2V0SWNvbihcImRvd24tY2hldnJvbi1nbHlwaFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRUb29sdGlwKFwiTW92ZSBkb3duXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheW1vdmUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJfdGVtcGxhdGVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCArIDFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZV9zZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXkoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmFkZEV4dHJhQnV0dG9uKChjYikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2Iuc2V0SWNvbihcImNyb3NzXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFRvb2x0aXAoXCJEZWxldGVcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub25DbGljaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlcl90ZW1wbGF0ZXMuc3BsaWNlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVfc2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHMuaW5mb0VsLnJlbW92ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIGFkZF9zdGFydHVwX3RlbXBsYXRlc19zZXR0aW5nKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiBcIlN0YXJ0dXAgVGVtcGxhdGVzXCIgfSk7XG5cbiAgICAgICAgY29uc3QgZGVzYyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZGVzYy5hcHBlbmQoXG4gICAgICAgICAgICBcIlN0YXJ0dXAgVGVtcGxhdGVzIGFyZSB0ZW1wbGF0ZXMgdGhhdCB3aWxsIGdldCBleGVjdXRlZCBvbmNlIHdoZW4gVGVtcGxhdGVyIHN0YXJ0cy5cIixcbiAgICAgICAgICAgIGRlc2MuY3JlYXRlRWwoXCJiclwiKSxcbiAgICAgICAgICAgIFwiVGhlc2UgdGVtcGxhdGVzIHdvbid0IG91dHB1dCBhbnl0aGluZy5cIixcbiAgICAgICAgICAgIGRlc2MuY3JlYXRlRWwoXCJiclwiKSxcbiAgICAgICAgICAgIFwiVGhpcyBjYW4gYmUgdXNlZnVsIHRvIHNldCB1cCB0ZW1wbGF0ZXMgYWRkaW5nIGhvb2tzIHRvIG9ic2lkaWFuIGV2ZW50cyBmb3IgZXhhbXBsZS5cIlxuICAgICAgICApO1xuXG4gICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpLnNldERlc2MoZGVzYyk7XG5cbiAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3Muc3RhcnR1cF90ZW1wbGF0ZXMuZm9yRWFjaCgodGVtcGxhdGUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzID0gbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbClcbiAgICAgICAgICAgICAgICAuYWRkU2VhcmNoKChjYikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZVN1Z2dlc3QoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNiLmlucHV0RWwsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVTdWdnZXN0TW9kZS5UZW1wbGF0ZUZpbGVzXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGNiLnNldFBsYWNlaG9sZGVyKFwiRXhhbXBsZTogZm9sZGVyMS90ZW1wbGF0ZV9maWxlXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAuc2V0VmFsdWUodGVtcGxhdGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAub25DaGFuZ2UoKG5ld190ZW1wbGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X3RlbXBsYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLnN0YXJ0dXBfdGVtcGxhdGVzLmNvbnRhaW5zKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X3RlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nX2Vycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFRlbXBsYXRlckVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiVGhpcyBzdGFydHVwIHRlbXBsYXRlIGFscmVhZHkgZXhpc3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLnN0YXJ0dXBfdGVtcGxhdGVzW2luZGV4XSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld190ZW1wbGF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICBjYi5jb250YWluZXJFbC5hZGRDbGFzcyhcInRlbXBsYXRlcl9zZWFyY2hcIik7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuYWRkRXh0cmFCdXR0b24oKGNiKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNiLnNldEljb24oXCJjcm9zc1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnNldFRvb2x0aXAoXCJEZWxldGVcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIC5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdGFydHVwX3RlbXBsYXRlcy5zcGxpY2UoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yY2UgcmVmcmVzaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzLmluZm9FbC5yZW1vdmUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbCkuYWRkQnV0dG9uKChjYikgPT4ge1xuICAgICAgICAgICAgY2Iuc2V0QnV0dG9uVGV4dChcIkFkZCBuZXcgc3RhcnR1cCB0ZW1wbGF0ZVwiKVxuICAgICAgICAgICAgICAgIC5zZXRDdGEoKVxuICAgICAgICAgICAgICAgIC5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3Muc3RhcnR1cF90ZW1wbGF0ZXMucHVzaChcIlwiKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZV9zZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAvLyBGb3JjZSByZWZyZXNoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhZGRfdXNlcl9zY3JpcHRfZnVuY3Rpb25zX3NldHRpbmcoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRWwoXCJoMlwiLCB7IHRleHQ6IFwiVXNlciBTY3JpcHQgRnVuY3Rpb25zXCIgfSk7XG5cbiAgICAgICAgbGV0IGRlc2MgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICAgIGRlc2MuYXBwZW5kKFxuICAgICAgICAgICAgXCJBbGwgSmF2YVNjcmlwdCBmaWxlcyBpbiB0aGlzIGZvbGRlciB3aWxsIGJlIGxvYWRlZCBhcyBDb21tb25KUyBtb2R1bGVzLCB0byBpbXBvcnQgY3VzdG9tIHVzZXIgZnVuY3Rpb25zLlwiLFxuICAgICAgICAgICAgZGVzYy5jcmVhdGVFbChcImJyXCIpLFxuICAgICAgICAgICAgXCJUaGUgZm9sZGVyIG5lZWRzIHRvIGJlIGFjY2Vzc2libGUgZnJvbSB0aGUgdmF1bHQuXCIsXG4gICAgICAgICAgICBkZXNjLmNyZWF0ZUVsKFwiYnJcIiksXG4gICAgICAgICAgICBcIkNoZWNrIHRoZSBcIixcbiAgICAgICAgICAgIGRlc2MuY3JlYXRlRWwoXCJhXCIsIHtcbiAgICAgICAgICAgICAgICBocmVmOiBcImh0dHBzOi8vc2lsZW50dm9pZDEzLmdpdGh1Yi5pby9UZW1wbGF0ZXIvXCIsXG4gICAgICAgICAgICAgICAgdGV4dDogXCJkb2N1bWVudGF0aW9uXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIFwiIGZvciBtb3JlIGluZm9ybWF0aW9ucy5cIlxuICAgICAgICApO1xuXG4gICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXG4gICAgICAgICAgICAuc2V0TmFtZShcIlNjcmlwdCBmaWxlcyBmb2xkZXIgbG9jYXRpb25cIilcbiAgICAgICAgICAgIC5zZXREZXNjKGRlc2MpXG4gICAgICAgICAgICAuYWRkU2VhcmNoKChjYikgPT4ge1xuICAgICAgICAgICAgICAgIG5ldyBGb2xkZXJTdWdnZXN0KHRoaXMuYXBwLCBjYi5pbnB1dEVsKTtcbiAgICAgICAgICAgICAgICBjYi5zZXRQbGFjZWhvbGRlcihcIkV4YW1wbGU6IGZvbGRlcjEvZm9sZGVyMlwiKVxuICAgICAgICAgICAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlcl9zY3JpcHRzX2ZvbGRlcilcbiAgICAgICAgICAgICAgICAgICAgLm9uQ2hhbmdlKChuZXdfZm9sZGVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VyX3NjcmlwdHNfZm9sZGVyID0gbmV3X2ZvbGRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVfc2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKFwidGVtcGxhdGVyX3NlYXJjaFwiKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2MgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICAgIGxldCBuYW1lOiBzdHJpbmc7XG4gICAgICAgIGlmICghdGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlcl9zY3JpcHRzX2ZvbGRlcikge1xuICAgICAgICAgICAgbmFtZSA9IFwiTm8gVXNlciBTY3JpcHRzIGZvbGRlciBzZXRcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVzID0gZXJyb3JXcmFwcGVyU3luYyhcbiAgICAgICAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgICAgICAgICBnZXRfdGZpbGVzX2Zyb21fZm9sZGVyKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHAsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VyX3NjcmlwdHNfZm9sZGVyXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgYFVzZXIgU2NyaXB0cyBmb2xkZXIgZG9lc24ndCBleGlzdGBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoIWZpbGVzIHx8IGZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIG5hbWUgPSBcIk5vIFVzZXIgU2NyaXB0cyBkZXRlY3RlZFwiO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgY291bnQgPSAwO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZS5leHRlbnNpb24gPT09IFwianNcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY291bnQrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2MuYXBwZW5kKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2MuY3JlYXRlRWwoXCJsaVwiLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IGB0cC51c2VyLiR7ZmlsZS5iYXNlbmFtZX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5hbWUgPSBgRGV0ZWN0ZWQgJHtjb3VudH0gVXNlciBTY3JpcHQocylgO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbClcbiAgICAgICAgICAgIC5zZXROYW1lKG5hbWUpXG4gICAgICAgICAgICAuc2V0RGVzYyhkZXNjKVxuICAgICAgICAgICAgLmFkZEV4dHJhQnV0dG9uKChleHRyYSkgPT4ge1xuICAgICAgICAgICAgICAgIGV4dHJhXG4gICAgICAgICAgICAgICAgICAgIC5zZXRJY29uKFwic3luY1wiKVxuICAgICAgICAgICAgICAgICAgICAuc2V0VG9vbHRpcChcIlJlZnJlc2hcIilcbiAgICAgICAgICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yY2UgcmVmcmVzaFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYWRkX3VzZXJfc3lzdGVtX2NvbW1hbmRfZnVuY3Rpb25zX3NldHRpbmcoKTogdm9pZCB7XG4gICAgICAgIGxldCBkZXNjID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgICAgICBkZXNjLmFwcGVuZChcbiAgICAgICAgICAgIFwiQWxsb3dzIHlvdSB0byBjcmVhdGUgdXNlciBmdW5jdGlvbnMgbGlua2VkIHRvIHN5c3RlbSBjb21tYW5kcy5cIixcbiAgICAgICAgICAgIGRlc2MuY3JlYXRlRWwoXCJiclwiKSxcbiAgICAgICAgICAgIGRlc2MuY3JlYXRlRWwoXCJiXCIsIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBcIldhcm5pbmc6IFwiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBcIkl0IGNhbiBiZSBkYW5nZXJvdXMgdG8gZXhlY3V0ZSBhcmJpdHJhcnkgc3lzdGVtIGNvbW1hbmRzIGZyb20gdW50cnVzdGVkIHNvdXJjZXMuIE9ubHkgcnVuIHN5c3RlbSBjb21tYW5kcyB0aGF0IHlvdSB1bmRlcnN0YW5kLCBmcm9tIHRydXN0ZWQgc291cmNlcy5cIlxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRWwoXCJoMlwiLCB7XG4gICAgICAgICAgICB0ZXh0OiBcIlVzZXIgU3lzdGVtIENvbW1hbmQgRnVuY3Rpb25zXCIsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXG4gICAgICAgICAgICAuc2V0TmFtZShcIkVuYWJsZSBVc2VyIFN5c3RlbSBDb21tYW5kIEZ1bmN0aW9uc1wiKVxuICAgICAgICAgICAgLnNldERlc2MoZGVzYylcbiAgICAgICAgICAgIC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRvZ2dsZVxuICAgICAgICAgICAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZW5hYmxlX3N5c3RlbV9jb21tYW5kcylcbiAgICAgICAgICAgICAgICAgICAgLm9uQ2hhbmdlKChlbmFibGVfc3lzdGVtX2NvbW1hbmRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5lbmFibGVfc3lzdGVtX2NvbW1hbmRzID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVfc3lzdGVtX2NvbW1hbmRzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZV9zZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yY2UgcmVmcmVzaFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLmVuYWJsZV9zeXN0ZW1fY29tbWFuZHMpIHtcbiAgICAgICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXG4gICAgICAgICAgICAgICAgLnNldE5hbWUoXCJUaW1lb3V0XCIpXG4gICAgICAgICAgICAgICAgLnNldERlc2MoXCJNYXhpbXVtIHRpbWVvdXQgaW4gc2Vjb25kcyBmb3IgYSBzeXN0ZW0gY29tbWFuZC5cIilcbiAgICAgICAgICAgICAgICAuYWRkVGV4dCgodGV4dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0LnNldFBsYWNlaG9sZGVyKFwiVGltZW91dFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnNldFZhbHVlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmNvbW1hbmRfdGltZW91dC50b1N0cmluZygpXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAub25DaGFuZ2UoKG5ld192YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld190aW1lb3V0ID0gTnVtYmVyKG5ld192YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmFOKG5ld190aW1lb3V0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dfZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVGVtcGxhdGVyRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJUaW1lb3V0IG11c3QgYmUgYSBudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmNvbW1hbmRfdGltZW91dCA9IG5ld190aW1lb3V0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVfc2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBkZXNjID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgICAgICAgICAgZGVzYy5hcHBlbmQoXG4gICAgICAgICAgICAgICAgXCJGdWxsIHBhdGggdG8gdGhlIHNoZWxsIGJpbmFyeSB0byBleGVjdXRlIHRoZSBjb21tYW5kIHdpdGguXCIsXG4gICAgICAgICAgICAgICAgZGVzYy5jcmVhdGVFbChcImJyXCIpLFxuICAgICAgICAgICAgICAgIFwiVGhpcyBzZXR0aW5nIGlzIG9wdGlvbmFsIGFuZCB3aWxsIGRlZmF1bHQgdG8gdGhlIHN5c3RlbSdzIGRlZmF1bHQgc2hlbGwgaWYgbm90IHNwZWNpZmllZC5cIixcbiAgICAgICAgICAgICAgICBkZXNjLmNyZWF0ZUVsKFwiYnJcIiksXG4gICAgICAgICAgICAgICAgXCJZb3UgY2FuIHVzZSBmb3J3YXJkIHNsYXNoZXMgKCcvJykgYXMgcGF0aCBzZXBhcmF0b3JzIG9uIGFsbCBwbGF0Zm9ybXMgaWYgaW4gZG91YnQuXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBuZXcgU2V0dGluZyh0aGlzLmNvbnRhaW5lckVsKVxuICAgICAgICAgICAgICAgIC5zZXROYW1lKFwiU2hlbGwgYmluYXJ5IGxvY2F0aW9uXCIpXG4gICAgICAgICAgICAgICAgLnNldERlc2MoZGVzYylcbiAgICAgICAgICAgICAgICAuYWRkVGV4dCgodGV4dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0LnNldFBsYWNlaG9sZGVyKFwiRXhhbXBsZTogL2Jpbi9iYXNoLCAuLi5cIilcbiAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaGVsbF9wYXRoKVxuICAgICAgICAgICAgICAgICAgICAgICAgLm9uQ2hhbmdlKChzaGVsbF9wYXRoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hlbGxfcGF0aCA9IHNoZWxsX3BhdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZV9zZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGxldCBpID0gMTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlc19wYWlycy5mb3JFYWNoKCh0ZW1wbGF0ZV9wYWlyKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGl2ID0gdGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcImRpdlwiKTtcbiAgICAgICAgICAgICAgICBkaXYuYWRkQ2xhc3MoXCJ0ZW1wbGF0ZXJfZGl2XCIpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgdGl0bGUgPSB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDRcIiwge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBcIlVzZXIgRnVuY3Rpb24gbsKwXCIgKyBpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRpdGxlLmFkZENsYXNzKFwidGVtcGxhdGVyX3RpdGxlXCIpO1xuXG4gICAgICAgICAgICAgICAgY29uc3Qgc2V0dGluZyA9IG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXG4gICAgICAgICAgICAgICAgICAgIC5hZGRFeHRyYUJ1dHRvbigoZXh0cmEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldEljb24oXCJjcm9zc1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRUb29sdGlwKFwiRGVsZXRlXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50ZW1wbGF0ZXNfcGFpcnMuaW5kZXhPZihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZV9wYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVzX3BhaXJzLnNwbGljZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZV9zZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yY2UgcmVmcmVzaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmFkZFRleHQoKHRleHQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHQgPSB0ZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFBsYWNlaG9sZGVyKFwiRnVuY3Rpb24gbmFtZVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRWYWx1ZSh0ZW1wbGF0ZV9wYWlyWzBdKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbkNoYW5nZSgobmV3X3ZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlc19wYWlycy5pbmRleE9mKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlX3BhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50ZW1wbGF0ZXNfcGFpcnNbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1bMF0gPSBuZXdfdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zYXZlX3NldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHQuaW5wdXRFbC5hZGRDbGFzcyhcInRlbXBsYXRlcl90ZW1wbGF0ZVwiKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQ7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5hZGRUZXh0QXJlYSgodGV4dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdCA9IHRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0UGxhY2Vob2xkZXIoXCJTeXN0ZW0gQ29tbWFuZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRWYWx1ZSh0ZW1wbGF0ZV9wYWlyWzFdKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbkNoYW5nZSgobmV3X2NtZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50ZW1wbGF0ZXNfcGFpcnMuaW5kZXhPZihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZV9wYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVzX3BhaXJzW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdWzFdID0gbmV3X2NtZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVfc2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB0LmlucHV0RWwuc2V0QXR0cihcInJvd3NcIiwgMik7XG4gICAgICAgICAgICAgICAgICAgICAgICB0LmlucHV0RWwuYWRkQ2xhc3MoXCJ0ZW1wbGF0ZXJfY21kXCIpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBzZXR0aW5nLmluZm9FbC5yZW1vdmUoKTtcblxuICAgICAgICAgICAgICAgIGRpdi5hcHBlbmRDaGlsZCh0aXRsZSk7XG4gICAgICAgICAgICAgICAgZGl2LmFwcGVuZENoaWxkKHRoaXMuY29udGFpbmVyRWwubGFzdENoaWxkKTtcblxuICAgICAgICAgICAgICAgIGkgKz0gMTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBkaXYgPSB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xuICAgICAgICAgICAgZGl2LmFkZENsYXNzKFwidGVtcGxhdGVyX2RpdjJcIik7XG5cbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyh0aGlzLmNvbnRhaW5lckVsKS5hZGRCdXR0b24oXG4gICAgICAgICAgICAgICAgKGJ1dHRvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRCdXR0b25UZXh0KFwiQWRkIE5ldyBVc2VyIEZ1bmN0aW9uXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAuc2V0Q3RhKClcbiAgICAgICAgICAgICAgICAgICAgICAgIC5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50ZW1wbGF0ZXNfcGFpcnMucHVzaChbXCJcIiwgXCJcIl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVfc2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3JjZSByZWZyZXNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgc2V0dGluZy5pbmZvRWwucmVtb3ZlKCk7XG5cbiAgICAgICAgICAgIGRpdi5hcHBlbmRDaGlsZCh0aGlzLmNvbnRhaW5lckVsLmxhc3RDaGlsZCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgeyBBcHAsIEZ1enp5U3VnZ2VzdE1vZGFsLCBURmlsZSwgVEZvbGRlciB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgZ2V0X3RmaWxlc19mcm9tX2ZvbGRlciB9IGZyb20gXCJVdGlsc1wiO1xuaW1wb3J0IFRlbXBsYXRlclBsdWdpbiBmcm9tIFwiLi9tYWluXCI7XG5pbXBvcnQgeyBlcnJvcldyYXBwZXJTeW5jIH0gZnJvbSBcIkVycm9yXCI7XG5pbXBvcnQgeyBsb2dfZXJyb3IgfSBmcm9tIFwiTG9nXCI7XG5cbmV4cG9ydCBlbnVtIE9wZW5Nb2RlIHtcbiAgICBJbnNlcnRUZW1wbGF0ZSxcbiAgICBDcmVhdGVOb3RlVGVtcGxhdGUsXG59XG5cbmV4cG9ydCBjbGFzcyBGdXp6eVN1Z2dlc3RlciBleHRlbmRzIEZ1enp5U3VnZ2VzdE1vZGFsPFRGaWxlPiB7XG4gICAgcHVibGljIGFwcDogQXBwO1xuICAgIHByaXZhdGUgcGx1Z2luOiBUZW1wbGF0ZXJQbHVnaW47XG4gICAgcHJpdmF0ZSBvcGVuX21vZGU6IE9wZW5Nb2RlO1xuICAgIHByaXZhdGUgY3JlYXRpb25fZm9sZGVyOiBURm9sZGVyO1xuXG4gICAgY29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luKSB7XG4gICAgICAgIHN1cGVyKGFwcCk7XG4gICAgICAgIHRoaXMuYXBwID0gYXBwO1xuICAgICAgICB0aGlzLnBsdWdpbiA9IHBsdWdpbjtcbiAgICAgICAgdGhpcy5zZXRQbGFjZWhvbGRlcihcIlR5cGUgbmFtZSBvZiBhIHRlbXBsYXRlLi4uXCIpO1xuICAgIH1cblxuICAgIGdldEl0ZW1zKCk6IFRGaWxlW10ge1xuICAgICAgICBpZiAoIXRoaXMucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlc19mb2xkZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFwcC52YXVsdC5nZXRNYXJrZG93bkZpbGVzKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmlsZXMgPSBlcnJvcldyYXBwZXJTeW5jKFxuICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgICBnZXRfdGZpbGVzX2Zyb21fZm9sZGVyKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVzX2ZvbGRlclxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICBgQ291bGRuJ3QgcmV0cmlldmUgdGVtcGxhdGUgZmlsZXMgZnJvbSB0ZW1wbGF0ZXMgZm9sZGVyICR7dGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVzX2ZvbGRlcn1gXG4gICAgICAgICk7XG4gICAgICAgIGlmICghZmlsZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlsZXM7XG4gICAgfVxuXG4gICAgZ2V0SXRlbVRleHQoaXRlbTogVEZpbGUpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gaXRlbS5iYXNlbmFtZTtcbiAgICB9XG5cbiAgICBvbkNob29zZUl0ZW0oaXRlbTogVEZpbGUpOiB2b2lkIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLm9wZW5fbW9kZSkge1xuICAgICAgICAgICAgY2FzZSBPcGVuTW9kZS5JbnNlcnRUZW1wbGF0ZTpcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi50ZW1wbGF0ZXIuYXBwZW5kX3RlbXBsYXRlX3RvX2FjdGl2ZV9maWxlKGl0ZW0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBPcGVuTW9kZS5DcmVhdGVOb3RlVGVtcGxhdGU6XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4udGVtcGxhdGVyLmNyZWF0ZV9uZXdfbm90ZV9mcm9tX3RlbXBsYXRlKFxuICAgICAgICAgICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uX2ZvbGRlclxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGFydCgpOiB2b2lkIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMub3BlbigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBsb2dfZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpbnNlcnRfdGVtcGxhdGUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMub3Blbl9tb2RlID0gT3Blbk1vZGUuSW5zZXJ0VGVtcGxhdGU7XG4gICAgICAgIHRoaXMuc3RhcnQoKTtcbiAgICB9XG5cbiAgICBjcmVhdGVfbmV3X25vdGVfZnJvbV90ZW1wbGF0ZShmb2xkZXI/OiBURm9sZGVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY3JlYXRpb25fZm9sZGVyID0gZm9sZGVyO1xuICAgICAgICB0aGlzLm9wZW5fbW9kZSA9IE9wZW5Nb2RlLkNyZWF0ZU5vdGVUZW1wbGF0ZTtcbiAgICAgICAgdGhpcy5zdGFydCgpO1xuICAgIH1cbn1cbiIsImV4cG9ydCBjb25zdCBVTlNVUFBPUlRFRF9NT0JJTEVfVEVNUExBVEUgPSBcIkVycm9yX01vYmlsZVVuc3VwcG9ydGVkVGVtcGxhdGVcIjtcbmV4cG9ydCBjb25zdCBJQ09OX0RBVEEgPSBgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCA1MS4xMzI4IDI4LjdcIj48cGF0aCBkPVwiTTAgMTUuMTQgMCAxMC4xNSAxOC42NyAxLjUxIDE4LjY3IDYuMDMgNC43MiAxMi4zMyA0LjcyIDEyLjc2IDE4LjY3IDE5LjIyIDE4LjY3IDIzLjc0IDAgMTUuMTRaTTMzLjY5MjggMS44NEMzMy42OTI4IDEuODQgMzMuOTc2MSAyLjE0NjcgMzQuNTQyOCAyLjc2QzM1LjEwOTQgMy4zOCAzNS4zOTI4IDQuNTYgMzUuMzkyOCA2LjNDMzUuMzkyOCA4LjA0NjYgMzQuODE5NSA5LjU0IDMzLjY3MjggMTAuNzhDMzIuNTI2MSAxMi4wMiAzMS4wOTk1IDEyLjY0IDI5LjM5MjggMTIuNjRDMjcuNjg2MiAxMi42NCAyNi4yNjYxIDEyLjAyNjcgMjUuMTMyOCAxMC44QzIzLjk5MjggOS41NzMzIDIzLjQyMjggOC4wODY3IDIzLjQyMjggNi4zNEMyMy40MjI4IDQuNiAyMy45OTk1IDMuMTA2NiAyNS4xNTI4IDEuODZDMjYuMjk5NC42MiAyNy43MjYxIDAgMjkuNDMyOCAwQzMxLjEzOTUgMCAzMi41NTk0LjYxMzMgMzMuNjkyOCAxLjg0TTQ5LjgyMjguNjcgMjkuNTMyOCAyOC4zOCAyNC40MTI4IDI4LjM4IDQ0LjcxMjguNjcgNDkuODIyOC42N00zMS4wMzI4IDguMzhDMzEuMDMyOCA4LjM4IDMxLjEzOTUgOC4yNDY3IDMxLjM1MjggNy45OEMzMS41NjYyIDcuNzA2NyAzMS42NzI4IDcuMTczMyAzMS42NzI4IDYuMzhDMzEuNjcyOCA1LjU4NjcgMzEuNDQ2MSA0LjkyIDMwLjk5MjggNC4zOEMzMC41NDYxIDMuODQgMjkuOTk5NSAzLjU3IDI5LjM1MjggMy41N0MyOC43MDYxIDMuNTcgMjguMTY5NSAzLjg0IDI3Ljc0MjggNC4zOEMyNy4zMjI4IDQuOTIgMjcuMTEyOCA1LjU4NjcgMjcuMTEyOCA2LjM4QzI3LjExMjggNy4xNzMzIDI3LjMzNjEgNy44NCAyNy43ODI4IDguMzhDMjguMjM2MSA4LjkyNjcgMjguNzg2MSA5LjIgMjkuNDMyOCA5LjJDMzAuMDc5NSA5LjIgMzAuNjEyOCA4LjkyNjcgMzEuMDMyOCA4LjM4TTQ5LjQzMjggMTcuOUM0OS40MzI4IDE3LjkgNDkuNzE2MSAxOC4yMDY3IDUwLjI4MjggMTguODJDNTAuODQ5NSAxOS40MzMzIDUxLjEzMjggMjAuNjEzMyA1MS4xMzI4IDIyLjM2QzUxLjEzMjggMjQuMSA1MC41NTk0IDI1LjU5IDQ5LjQxMjggMjYuODNDNDguMjU5NSAyOC4wNzY2IDQ2LjgyOTUgMjguNyA0NS4xMjI4IDI4LjdDNDMuNDIyOCAyOC43IDQyLjAwMjggMjguMDgzMyA0MC44NjI4IDI2Ljg1QzM5LjcyOTUgMjUuNjIzMyAzOS4xNjI4IDI0LjEzNjYgMzkuMTYyOCAyMi4zOUMzOS4xNjI4IDIwLjY1IDM5LjczNjEgMTkuMTYgNDAuODgyOCAxNy45MkM0Mi4wMzYxIDE2LjY3MzMgNDMuNDYyOCAxNi4wNSA0NS4xNjI4IDE2LjA1QzQ2Ljg2OTQgMTYuMDUgNDguMjkyOCAxNi42NjY3IDQ5LjQzMjggMTcuOU00Ni44NTI4IDI0LjUyQzQ2Ljg1MjggMjQuNTIgNDYuOTU5NSAyNC4zODMzIDQ3LjE3MjggMjQuMTFDNDcuMzc5NSAyMy44MzY3IDQ3LjQ4MjggMjMuMzAzMyA0Ny40ODI4IDIyLjUxQzQ3LjQ4MjggMjEuNzE2NyA0Ny4yNTk1IDIxLjA1IDQ2LjgxMjggMjAuNTFDNDYuMzY2MSAxOS45NyA0NS44MTYyIDE5LjcgNDUuMTYyOCAxOS43QzQ0LjUxNjEgMTkuNyA0My45ODI4IDE5Ljk3IDQzLjU2MjggMjAuNTFDNDMuMTQyOCAyMS4wNSA0Mi45MzI4IDIxLjcxNjcgNDIuOTMyOCAyMi41MUM0Mi45MzI4IDIzLjMwMzMgNDMuMTU2MSAyMy45NzMzIDQzLjYwMjggMjQuNTJDNDQuMDQ5NCAyNS4wNiA0NC41OTYxIDI1LjMzIDQ1LjI0MjggMjUuMzNDNDUuODg5NSAyNS4zMyA0Ni40MjYxIDI1LjA2IDQ2Ljg1MjggMjQuNTJaXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiLz48L3N2Zz5gO1xuIiwiaW1wb3J0IFRlbXBsYXRlclBsdWdpbiBmcm9tIFwibWFpblwiO1xuaW1wb3J0IHsgQXBwIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5pbXBvcnQgeyBSdW5uaW5nQ29uZmlnIH0gZnJvbSBcIlRlbXBsYXRlclwiO1xuaW1wb3J0IHsgSUdlbmVyYXRlT2JqZWN0IH0gZnJvbSBcImZ1bmN0aW9ucy9JR2VuZXJhdGVPYmplY3RcIjtcbmltcG9ydCB7IE1vZHVsZU5hbWUgfSBmcm9tIFwiZnVuY3Rpb25zL1RwRG9jdW1lbnRhdGlvblwiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgSW50ZXJuYWxNb2R1bGUgaW1wbGVtZW50cyBJR2VuZXJhdGVPYmplY3Qge1xuICAgIHB1YmxpYyBhYnN0cmFjdCBuYW1lOiBNb2R1bGVOYW1lO1xuICAgIHByb3RlY3RlZCBzdGF0aWNfZnVuY3Rpb25zOiBNYXA8c3RyaW5nLCB1bmtub3duPiA9IG5ldyBNYXAoKTtcbiAgICBwcm90ZWN0ZWQgZHluYW1pY19mdW5jdGlvbnM6IE1hcDxzdHJpbmcsIHVua25vd24+ID0gbmV3IE1hcCgpO1xuICAgIHByb3RlY3RlZCBjb25maWc6IFJ1bm5pbmdDb25maWc7XG4gICAgcHJvdGVjdGVkIHN0YXRpY19vYmplY3Q6IHsgW3g6IHN0cmluZ106IHVua25vd24gfTtcblxuICAgIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBhcHA6IEFwcCwgcHJvdGVjdGVkIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luKSB7fVxuXG4gICAgZ2V0TmFtZSgpOiBNb2R1bGVOYW1lIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZTtcbiAgICB9XG5cbiAgICBhYnN0cmFjdCBjcmVhdGVfc3RhdGljX3RlbXBsYXRlcygpOiBQcm9taXNlPHZvaWQ+O1xuICAgIGFic3RyYWN0IGNyZWF0ZV9keW5hbWljX3RlbXBsYXRlcygpOiBQcm9taXNlPHZvaWQ+O1xuXG4gICAgYXN5bmMgaW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jcmVhdGVfc3RhdGljX3RlbXBsYXRlcygpO1xuICAgICAgICB0aGlzLnN0YXRpY19vYmplY3QgPSBPYmplY3QuZnJvbUVudHJpZXModGhpcy5zdGF0aWNfZnVuY3Rpb25zKTtcbiAgICB9XG5cbiAgICBhc3luYyBnZW5lcmF0ZV9vYmplY3QoXG4gICAgICAgIG5ld19jb25maWc6IFJ1bm5pbmdDb25maWdcbiAgICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gbmV3X2NvbmZpZztcbiAgICAgICAgYXdhaXQgdGhpcy5jcmVhdGVfZHluYW1pY190ZW1wbGF0ZXMoKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4udGhpcy5zdGF0aWNfb2JqZWN0LFxuICAgICAgICAgICAgLi4uT2JqZWN0LmZyb21FbnRyaWVzKHRoaXMuZHluYW1pY19mdW5jdGlvbnMpLFxuICAgICAgICB9O1xuICAgIH1cbn1cbiIsImltcG9ydCB7IFRlbXBsYXRlckVycm9yIH0gZnJvbSBcIkVycm9yXCI7XG5pbXBvcnQgeyBJbnRlcm5hbE1vZHVsZSB9IGZyb20gXCIuLi9JbnRlcm5hbE1vZHVsZVwiO1xuaW1wb3J0IHsgTW9kdWxlTmFtZSB9IGZyb20gXCJmdW5jdGlvbnMvVHBEb2N1bWVudGF0aW9uXCI7XG5cbmV4cG9ydCBjbGFzcyBJbnRlcm5hbE1vZHVsZURhdGUgZXh0ZW5kcyBJbnRlcm5hbE1vZHVsZSB7XG4gICAgcHVibGljIG5hbWU6IE1vZHVsZU5hbWUgPSBcImRhdGVcIjtcblxuICAgIGFzeW5jIGNyZWF0ZV9zdGF0aWNfdGVtcGxhdGVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnN0YXRpY19mdW5jdGlvbnMuc2V0KFwibm93XCIsIHRoaXMuZ2VuZXJhdGVfbm93KCkpO1xuICAgICAgICB0aGlzLnN0YXRpY19mdW5jdGlvbnMuc2V0KFwidG9tb3Jyb3dcIiwgdGhpcy5nZW5lcmF0ZV90b21vcnJvdygpKTtcbiAgICAgICAgdGhpcy5zdGF0aWNfZnVuY3Rpb25zLnNldChcIndlZWtkYXlcIiwgdGhpcy5nZW5lcmF0ZV93ZWVrZGF5KCkpO1xuICAgICAgICB0aGlzLnN0YXRpY19mdW5jdGlvbnMuc2V0KFwieWVzdGVyZGF5XCIsIHRoaXMuZ2VuZXJhdGVfeWVzdGVyZGF5KCkpO1xuICAgIH1cblxuICAgIGFzeW5jIGNyZWF0ZV9keW5hbWljX3RlbXBsYXRlcygpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgICBnZW5lcmF0ZV9ub3coKTogKFxuICAgICAgICBmb3JtYXQ/OiBzdHJpbmcsXG4gICAgICAgIG9mZnNldD86IG51bWJlciB8IHN0cmluZyxcbiAgICAgICAgcmVmZXJlbmNlPzogc3RyaW5nLFxuICAgICAgICByZWZlcmVuY2VfZm9ybWF0Pzogc3RyaW5nXG4gICAgKSA9PiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgZm9ybWF0ID0gXCJZWVlZLU1NLUREXCIsXG4gICAgICAgICAgICBvZmZzZXQ/OiBudW1iZXIgfCBzdHJpbmcsXG4gICAgICAgICAgICByZWZlcmVuY2U/OiBzdHJpbmcsXG4gICAgICAgICAgICByZWZlcmVuY2VfZm9ybWF0Pzogc3RyaW5nXG4gICAgICAgICkgPT4ge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHJlZmVyZW5jZSAmJlxuICAgICAgICAgICAgICAgICF3aW5kb3cubW9tZW50KHJlZmVyZW5jZSwgcmVmZXJlbmNlX2Zvcm1hdCkuaXNWYWxpZCgpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVyRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiSW52YWxpZCByZWZlcmVuY2UgZGF0ZSBmb3JtYXQsIHRyeSBzcGVjaWZ5aW5nIG9uZSB3aXRoIHRoZSBhcmd1bWVudCAncmVmZXJlbmNlX2Zvcm1hdCdcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgZHVyYXRpb247XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gd2luZG93Lm1vbWVudC5kdXJhdGlvbihvZmZzZXQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgZHVyYXRpb24gPSB3aW5kb3cubW9tZW50LmR1cmF0aW9uKG9mZnNldCwgXCJkYXlzXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gd2luZG93XG4gICAgICAgICAgICAgICAgLm1vbWVudChyZWZlcmVuY2UsIHJlZmVyZW5jZV9mb3JtYXQpXG4gICAgICAgICAgICAgICAgLmFkZChkdXJhdGlvbilcbiAgICAgICAgICAgICAgICAuZm9ybWF0KGZvcm1hdCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2VuZXJhdGVfdG9tb3Jyb3coKTogKGZvcm1hdD86IHN0cmluZykgPT4gc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIChmb3JtYXQgPSBcIllZWVktTU0tRERcIikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5tb21lbnQoKS5hZGQoMSwgXCJkYXlzXCIpLmZvcm1hdChmb3JtYXQpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdlbmVyYXRlX3dlZWtkYXkoKTogKFxuICAgICAgICBmb3JtYXQ6IHN0cmluZyxcbiAgICAgICAgd2Vla2RheTogbnVtYmVyLFxuICAgICAgICByZWZlcmVuY2U/OiBzdHJpbmcsXG4gICAgICAgIHJlZmVyZW5jZV9mb3JtYXQ/OiBzdHJpbmdcbiAgICApID0+IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBmb3JtYXQgPSBcIllZWVktTU0tRERcIixcbiAgICAgICAgICAgIHdlZWtkYXk6IG51bWJlcixcbiAgICAgICAgICAgIHJlZmVyZW5jZT86IHN0cmluZyxcbiAgICAgICAgICAgIHJlZmVyZW5jZV9mb3JtYXQ/OiBzdHJpbmdcbiAgICAgICAgKSA9PiB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgcmVmZXJlbmNlICYmXG4gICAgICAgICAgICAgICAgIXdpbmRvdy5tb21lbnQocmVmZXJlbmNlLCByZWZlcmVuY2VfZm9ybWF0KS5pc1ZhbGlkKClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUZW1wbGF0ZXJFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgXCJJbnZhbGlkIHJlZmVyZW5jZSBkYXRlIGZvcm1hdCwgdHJ5IHNwZWNpZnlpbmcgb25lIHdpdGggdGhlIGFyZ3VtZW50ICdyZWZlcmVuY2VfZm9ybWF0J1wiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB3aW5kb3dcbiAgICAgICAgICAgICAgICAubW9tZW50KHJlZmVyZW5jZSwgcmVmZXJlbmNlX2Zvcm1hdClcbiAgICAgICAgICAgICAgICAud2Vla2RheSh3ZWVrZGF5KVxuICAgICAgICAgICAgICAgIC5mb3JtYXQoZm9ybWF0KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZV95ZXN0ZXJkYXkoKTogKGZvcm1hdD86IHN0cmluZykgPT4gc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIChmb3JtYXQgPSBcIllZWVktTU0tRERcIikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5tb21lbnQoKS5hZGQoLTEsIFwiZGF5c1wiKS5mb3JtYXQoZm9ybWF0KTtcbiAgICAgICAgfTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBJbnRlcm5hbE1vZHVsZSB9IGZyb20gXCIuLi9JbnRlcm5hbE1vZHVsZVwiO1xuaW1wb3J0IHsgbG9nX2Vycm9yIH0gZnJvbSBcIkxvZ1wiO1xuXG5pbXBvcnQge1xuICAgIEZpbGVTeXN0ZW1BZGFwdGVyLFxuICAgIGdldEFsbFRhZ3MsXG4gICAgTWFya2Rvd25WaWV3LFxuICAgIG5vcm1hbGl6ZVBhdGgsXG4gICAgcGFyc2VMaW5rdGV4dCxcbiAgICBQbGF0Zm9ybSxcbiAgICByZXNvbHZlU3VicGF0aCxcbiAgICBURmlsZSxcbiAgICBURm9sZGVyLFxufSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB7IFVOU1VQUE9SVEVEX01PQklMRV9URU1QTEFURSB9IGZyb20gXCJDb25zdGFudHNcIjtcbmltcG9ydCB7IFRlbXBsYXRlckVycm9yIH0gZnJvbSBcIkVycm9yXCI7XG5pbXBvcnQgeyBNb2R1bGVOYW1lIH0gZnJvbSBcImZ1bmN0aW9ucy9UcERvY3VtZW50YXRpb25cIjtcblxuZXhwb3J0IGNvbnN0IERFUFRIX0xJTUlUID0gMTA7XG5cbmV4cG9ydCBjbGFzcyBJbnRlcm5hbE1vZHVsZUZpbGUgZXh0ZW5kcyBJbnRlcm5hbE1vZHVsZSB7XG4gICAgcHVibGljIG5hbWU6IE1vZHVsZU5hbWUgPSBcImZpbGVcIjtcbiAgICBwcml2YXRlIGluY2x1ZGVfZGVwdGggPSAwO1xuICAgIHByaXZhdGUgY3JlYXRlX25ld19kZXB0aCA9IDA7XG4gICAgcHJpdmF0ZSBsaW5rcGF0aF9yZWdleCA9IG5ldyBSZWdFeHAoXCJeXFxcXFtcXFxcWyguKilcXFxcXVxcXFxdJFwiKTtcblxuICAgIGFzeW5jIGNyZWF0ZV9zdGF0aWNfdGVtcGxhdGVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnN0YXRpY19mdW5jdGlvbnMuc2V0KFxuICAgICAgICAgICAgXCJjcmVhdGlvbl9kYXRlXCIsXG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlX2NyZWF0aW9uX2RhdGUoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0YXRpY19mdW5jdGlvbnMuc2V0KFwiY3JlYXRlX25ld1wiLCB0aGlzLmdlbmVyYXRlX2NyZWF0ZV9uZXcoKSk7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXCJjdXJzb3JcIiwgdGhpcy5nZW5lcmF0ZV9jdXJzb3IoKSk7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXG4gICAgICAgICAgICBcImN1cnNvcl9hcHBlbmRcIixcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVfY3Vyc29yX2FwcGVuZCgpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXCJleGlzdHNcIiwgdGhpcy5nZW5lcmF0ZV9leGlzdHMoKSk7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXCJmaW5kX3RmaWxlXCIsIHRoaXMuZ2VuZXJhdGVfZmluZF90ZmlsZSgpKTtcbiAgICAgICAgdGhpcy5zdGF0aWNfZnVuY3Rpb25zLnNldChcImZvbGRlclwiLCB0aGlzLmdlbmVyYXRlX2ZvbGRlcigpKTtcbiAgICAgICAgdGhpcy5zdGF0aWNfZnVuY3Rpb25zLnNldChcImluY2x1ZGVcIiwgdGhpcy5nZW5lcmF0ZV9pbmNsdWRlKCkpO1xuICAgICAgICB0aGlzLnN0YXRpY19mdW5jdGlvbnMuc2V0KFxuICAgICAgICAgICAgXCJsYXN0X21vZGlmaWVkX2RhdGVcIixcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVfbGFzdF9tb2RpZmllZF9kYXRlKClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdGF0aWNfZnVuY3Rpb25zLnNldChcIm1vdmVcIiwgdGhpcy5nZW5lcmF0ZV9tb3ZlKCkpO1xuICAgICAgICB0aGlzLnN0YXRpY19mdW5jdGlvbnMuc2V0KFwicGF0aFwiLCB0aGlzLmdlbmVyYXRlX3BhdGgoKSk7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXCJyZW5hbWVcIiwgdGhpcy5nZW5lcmF0ZV9yZW5hbWUoKSk7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXCJzZWxlY3Rpb25cIiwgdGhpcy5nZW5lcmF0ZV9zZWxlY3Rpb24oKSk7XG4gICAgfVxuXG4gICAgYXN5bmMgY3JlYXRlX2R5bmFtaWNfdGVtcGxhdGVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmR5bmFtaWNfZnVuY3Rpb25zLnNldChcImNvbnRlbnRcIiwgYXdhaXQgdGhpcy5nZW5lcmF0ZV9jb250ZW50KCkpO1xuICAgICAgICB0aGlzLmR5bmFtaWNfZnVuY3Rpb25zLnNldChcInRhZ3NcIiwgdGhpcy5nZW5lcmF0ZV90YWdzKCkpO1xuICAgICAgICB0aGlzLmR5bmFtaWNfZnVuY3Rpb25zLnNldChcInRpdGxlXCIsIHRoaXMuZ2VuZXJhdGVfdGl0bGUoKSk7XG4gICAgfVxuXG4gICAgYXN5bmMgZ2VuZXJhdGVfY29udGVudCgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5hcHAudmF1bHQucmVhZCh0aGlzLmNvbmZpZy50YXJnZXRfZmlsZSk7XG4gICAgfVxuXG4gICAgZ2VuZXJhdGVfY3JlYXRlX25ldygpOiAoXG4gICAgICAgIHRlbXBsYXRlOiBURmlsZSB8IHN0cmluZyxcbiAgICAgICAgZmlsZW5hbWU6IHN0cmluZyxcbiAgICAgICAgb3Blbl9uZXc6IGJvb2xlYW4sXG4gICAgICAgIGZvbGRlcj86IFRGb2xkZXJcbiAgICApID0+IFByb21pc2U8VEZpbGU+IHtcbiAgICAgICAgcmV0dXJuIGFzeW5jIChcbiAgICAgICAgICAgIHRlbXBsYXRlOiBURmlsZSB8IHN0cmluZyxcbiAgICAgICAgICAgIGZpbGVuYW1lOiBzdHJpbmcsXG4gICAgICAgICAgICBvcGVuX25ldyA9IGZhbHNlLFxuICAgICAgICAgICAgZm9sZGVyPzogVEZvbGRlclxuICAgICAgICApID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlX25ld19kZXB0aCArPSAxO1xuICAgICAgICAgICAgaWYgKHRoaXMuY3JlYXRlX25ld19kZXB0aCA+IERFUFRIX0xJTUlUKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVfbmV3X2RlcHRoID0gMDtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVyRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiUmVhY2hlZCBjcmVhdGVfbmV3IGRlcHRoIGxpbWl0IChtYXggPSAxMClcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IG5ld19maWxlID1cbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi50ZW1wbGF0ZXIuY3JlYXRlX25ld19ub3RlX2Zyb21fdGVtcGxhdGUoXG4gICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlLFxuICAgICAgICAgICAgICAgICAgICBmb2xkZXIsXG4gICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgICBvcGVuX25ld1xuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHRoaXMuY3JlYXRlX25ld19kZXB0aCAtPSAxO1xuXG4gICAgICAgICAgICByZXR1cm4gbmV3X2ZpbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2VuZXJhdGVfY3JlYXRpb25fZGF0ZSgpOiAoZm9ybWF0Pzogc3RyaW5nKSA9PiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gKGZvcm1hdCA9IFwiWVlZWS1NTS1ERCBISDptbVwiKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gd2luZG93XG4gICAgICAgICAgICAgICAgLm1vbWVudCh0aGlzLmNvbmZpZy50YXJnZXRfZmlsZS5zdGF0LmN0aW1lKVxuICAgICAgICAgICAgICAgIC5mb3JtYXQoZm9ybWF0KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZV9jdXJzb3IoKTogKG9yZGVyPzogbnVtYmVyKSA9PiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gKG9yZGVyPzogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAvLyBIYWNrIHRvIHByZXZlbnQgZW1wdHkgb3V0cHV0XG4gICAgICAgICAgICByZXR1cm4gYDwlIHRwLmZpbGUuY3Vyc29yKCR7b3JkZXIgPz8gXCJcIn0pICU+YDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZV9jdXJzb3JfYXBwZW5kKCk6IChjb250ZW50OiBzdHJpbmcpID0+IHZvaWQge1xuICAgICAgICByZXR1cm4gKGNvbnRlbnQ6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gICAgICAgICAgICBjb25zdCBhY3RpdmVfdmlldyA9XG4gICAgICAgICAgICAgICAgdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KTtcbiAgICAgICAgICAgIGlmIChhY3RpdmVfdmlldyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGxvZ19lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgbmV3IFRlbXBsYXRlckVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJObyBhY3RpdmUgdmlldywgY2FuJ3QgYXBwZW5kIHRvIGN1cnNvci5cIlxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGVkaXRvciA9IGFjdGl2ZV92aWV3LmVkaXRvcjtcbiAgICAgICAgICAgIGNvbnN0IGRvYyA9IGVkaXRvci5nZXREb2MoKTtcbiAgICAgICAgICAgIGRvYy5yZXBsYWNlU2VsZWN0aW9uKGNvbnRlbnQpO1xuICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2VuZXJhdGVfZXhpc3RzKCk6IChmaWxlbmFtZTogc3RyaW5nKSA9PiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChmaWxlbmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAvLyBUT0RPOiBSZW1vdmUgdGhpcywgb25seSBoZXJlIHRvIHN1cHBvcnQgdGhlIG9sZCB3YXlcbiAgICAgICAgICAgIGxldCBtYXRjaDtcbiAgICAgICAgICAgIGlmICgobWF0Y2ggPSB0aGlzLmxpbmtwYXRoX3JlZ2V4LmV4ZWMoZmlsZW5hbWUpKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGZpbGVuYW1lID0gbWF0Y2hbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLmFwcC5tZXRhZGF0YUNhY2hlLmdldEZpcnN0TGlua3BhdGhEZXN0KFxuICAgICAgICAgICAgICAgIGZpbGVuYW1lLFxuICAgICAgICAgICAgICAgIFwiXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gZmlsZSAhPSBudWxsO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdlbmVyYXRlX2ZpbmRfdGZpbGUoKTogKGZpbGVuYW1lOiBzdHJpbmcpID0+IFRGaWxlIHtcbiAgICAgICAgcmV0dXJuIChmaWxlbmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXRoID0gbm9ybWFsaXplUGF0aChmaWxlbmFtZSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaXJzdExpbmtwYXRoRGVzdChwYXRoLCBcIlwiKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZV9mb2xkZXIoKTogKHJlbGF0aXZlPzogYm9vbGVhbikgPT4gc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIChyZWxhdGl2ZSA9IGZhbHNlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSB0aGlzLmNvbmZpZy50YXJnZXRfZmlsZS5wYXJlbnQ7XG4gICAgICAgICAgICBsZXQgZm9sZGVyO1xuXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHtcbiAgICAgICAgICAgICAgICBmb2xkZXIgPSBwYXJlbnQucGF0aDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9sZGVyID0gcGFyZW50Lm5hbWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBmb2xkZXI7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2VuZXJhdGVfaW5jbHVkZSgpOiAoaW5jbHVkZV9saW5rOiBzdHJpbmcgfCBURmlsZSkgPT4gUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIGFzeW5jIChpbmNsdWRlX2xpbms6IHN0cmluZyB8IFRGaWxlKSA9PiB7XG4gICAgICAgICAgICAvLyBUT0RPOiBBZGQgbXV0ZXggZm9yIHRoaXMsIHRoaXMgbWF5IGN1cnJlbnRseSBsZWFkIHRvIGEgcmFjZSBjb25kaXRpb24uXG4gICAgICAgICAgICAvLyBXaGlsZSBub3QgdmVyeSBpbXBhY3RmdWwsIHRoYXQgY291bGQgc3RpbGwgYmUgYW5ub3lpbmcuXG4gICAgICAgICAgICB0aGlzLmluY2x1ZGVfZGVwdGggKz0gMTtcbiAgICAgICAgICAgIGlmICh0aGlzLmluY2x1ZGVfZGVwdGggPiBERVBUSF9MSU1JVCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5jbHVkZV9kZXB0aCAtPSAxO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUZW1wbGF0ZXJFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgXCJSZWFjaGVkIGluY2x1c2lvbiBkZXB0aCBsaW1pdCAobWF4ID0gMTApXCJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgaW5jX2ZpbGVfY29udGVudDogc3RyaW5nO1xuXG4gICAgICAgICAgICBpZiAoaW5jbHVkZV9saW5rIGluc3RhbmNlb2YgVEZpbGUpIHtcbiAgICAgICAgICAgICAgICBpbmNfZmlsZV9jb250ZW50ID0gYXdhaXQgdGhpcy5hcHAudmF1bHQucmVhZChpbmNsdWRlX2xpbmspO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgbWF0Y2g7XG4gICAgICAgICAgICAgICAgaWYgKChtYXRjaCA9IHRoaXMubGlua3BhdGhfcmVnZXguZXhlYyhpbmNsdWRlX2xpbmspKSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluY2x1ZGVfZGVwdGggLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRlbXBsYXRlckVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJJbnZhbGlkIGZpbGUgZm9ybWF0LCBwcm92aWRlIGFuIG9ic2lkaWFuIGxpbmsgYmV0d2VlbiBxdW90ZXMuXCJcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgeyBwYXRoLCBzdWJwYXRoIH0gPSBwYXJzZUxpbmt0ZXh0KG1hdGNoWzFdKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGluY19maWxlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaXJzdExpbmtwYXRoRGVzdChcbiAgICAgICAgICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgICAgICAgICAgXCJcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKCFpbmNfZmlsZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluY2x1ZGVfZGVwdGggLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRlbXBsYXRlckVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYEZpbGUgJHtpbmNsdWRlX2xpbmt9IGRvZXNuJ3QgZXhpc3RgXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGluY19maWxlX2NvbnRlbnQgPSBhd2FpdCB0aGlzLmFwcC52YXVsdC5yZWFkKGluY19maWxlKTtcblxuICAgICAgICAgICAgICAgIGlmIChzdWJwYXRoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhY2hlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaWxlQ2FjaGUoaW5jX2ZpbGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2FjaGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHJlc29sdmVTdWJwYXRoKGNhY2hlLCBzdWJwYXRoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNfZmlsZV9jb250ZW50ID0gaW5jX2ZpbGVfY29udGVudC5zbGljZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnN0YXJ0Lm9mZnNldCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmVuZD8ub2Zmc2V0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWRfY29udGVudCA9XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnRlbXBsYXRlci5wYXJzZXIucGFyc2VfY29tbWFuZHMoXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNfZmlsZV9jb250ZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4udGVtcGxhdGVyLmN1cnJlbnRfZnVuY3Rpb25zX29iamVjdFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5jbHVkZV9kZXB0aCAtPSAxO1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZWRfY29udGVudDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluY2x1ZGVfZGVwdGggLT0gMTtcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdlbmVyYXRlX2xhc3RfbW9kaWZpZWRfZGF0ZSgpOiAoZm9ybWF0Pzogc3RyaW5nKSA9PiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gKGZvcm1hdCA9IFwiWVlZWS1NTS1ERCBISDptbVwiKTogc3RyaW5nID0+IHtcbiAgICAgICAgICAgIHJldHVybiB3aW5kb3dcbiAgICAgICAgICAgICAgICAubW9tZW50KHRoaXMuY29uZmlnLnRhcmdldF9maWxlLnN0YXQubXRpbWUpXG4gICAgICAgICAgICAgICAgLmZvcm1hdChmb3JtYXQpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdlbmVyYXRlX21vdmUoKTogKHBhdGg6IHN0cmluZykgPT4gUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIGFzeW5jIChwYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5ld19wYXRoID0gbm9ybWFsaXplUGF0aChcbiAgICAgICAgICAgICAgICBgJHtwYXRofS4ke3RoaXMuY29uZmlnLnRhcmdldF9maWxlLmV4dGVuc2lvbn1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hcHAuZmlsZU1hbmFnZXIucmVuYW1lRmlsZShcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy50YXJnZXRfZmlsZSxcbiAgICAgICAgICAgICAgICBuZXdfcGF0aFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdlbmVyYXRlX3BhdGgoKTogKHJlbGF0aXZlOiBib29sZWFuKSA9PiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gKHJlbGF0aXZlID0gZmFsc2UpID0+IHtcbiAgICAgICAgICAgIC8vIFRPRE86IEFkZCBtb2JpbGUgc3VwcG9ydFxuICAgICAgICAgICAgaWYgKFBsYXRmb3JtLmlzTW9iaWxlQXBwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFVOU1VQUE9SVEVEX01PQklMRV9URU1QTEFURTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghKHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIgaW5zdGFuY2VvZiBGaWxlU3lzdGVtQWRhcHRlcikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVyRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiYXBwLnZhdWx0IGlzIG5vdCBhIEZpbGVTeXN0ZW1BZGFwdGVyIGluc3RhbmNlXCJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdmF1bHRfcGF0aCA9IHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIuZ2V0QmFzZVBhdGgoKTtcblxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnRhcmdldF9maWxlLnBhdGg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBgJHt2YXVsdF9wYXRofS8ke3RoaXMuY29uZmlnLnRhcmdldF9maWxlLnBhdGh9YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZV9yZW5hbWUoKTogKG5ld190aXRsZTogc3RyaW5nKSA9PiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gYXN5bmMgKG5ld190aXRsZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBpZiAobmV3X3RpdGxlLm1hdGNoKC9bXFxcXC86XSsvZykpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVyRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiRmlsZSBuYW1lIGNhbm5vdCBjb250YWluIGFueSBvZiB0aGVzZSBjaGFyYWN0ZXJzOiBcXFxcIC8gOlwiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5ld19wYXRoID0gbm9ybWFsaXplUGF0aChcbiAgICAgICAgICAgICAgICBgJHt0aGlzLmNvbmZpZy50YXJnZXRfZmlsZS5wYXJlbnQucGF0aH0vJHtuZXdfdGl0bGV9LiR7dGhpcy5jb25maWcudGFyZ2V0X2ZpbGUuZXh0ZW5zaW9ufWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmFwcC5maWxlTWFuYWdlci5yZW5hbWVGaWxlKFxuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLnRhcmdldF9maWxlLFxuICAgICAgICAgICAgICAgIG5ld19wYXRoXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2VuZXJhdGVfc2VsZWN0aW9uKCk6ICgpID0+IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhY3RpdmVfdmlldyA9XG4gICAgICAgICAgICAgICAgdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KTtcbiAgICAgICAgICAgIGlmIChhY3RpdmVfdmlldyA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFRlbXBsYXRlckVycm9yKFxuICAgICAgICAgICAgICAgICAgICBcIkFjdGl2ZSB2aWV3IGlzIG51bGwsIGNhbid0IHJlYWQgc2VsZWN0aW9uLlwiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZWRpdG9yID0gYWN0aXZlX3ZpZXcuZWRpdG9yO1xuICAgICAgICAgICAgcmV0dXJuIGVkaXRvci5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBUdXJuIHRoaXMgaW50byBhIGZ1bmN0aW9uXG4gICAgZ2VuZXJhdGVfdGFncygpOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IGNhY2hlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaWxlQ2FjaGUoXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy50YXJnZXRfZmlsZVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZ2V0QWxsVGFncyhjYWNoZSk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogVHVybiB0aGlzIGludG8gYSBmdW5jdGlvblxuICAgIGdlbmVyYXRlX3RpdGxlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy50YXJnZXRfZmlsZS5iYXNlbmFtZTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBUZW1wbGF0ZXJFcnJvciB9IGZyb20gXCJFcnJvclwiO1xuaW1wb3J0IHsgSW50ZXJuYWxNb2R1bGUgfSBmcm9tIFwiLi4vSW50ZXJuYWxNb2R1bGVcIjtcbmltcG9ydCB7IE1vZHVsZU5hbWUgfSBmcm9tIFwiZnVuY3Rpb25zL1RwRG9jdW1lbnRhdGlvblwiO1xuXG5leHBvcnQgY2xhc3MgSW50ZXJuYWxNb2R1bGVXZWIgZXh0ZW5kcyBJbnRlcm5hbE1vZHVsZSB7XG4gICAgbmFtZTogTW9kdWxlTmFtZSA9IFwid2ViXCI7XG5cbiAgICBhc3luYyBjcmVhdGVfc3RhdGljX3RlbXBsYXRlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5zdGF0aWNfZnVuY3Rpb25zLnNldChcImRhaWx5X3F1b3RlXCIsIHRoaXMuZ2VuZXJhdGVfZGFpbHlfcXVvdGUoKSk7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXG4gICAgICAgICAgICBcInJhbmRvbV9waWN0dXJlXCIsXG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlX3JhbmRvbV9waWN0dXJlKClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBhc3luYyBjcmVhdGVfZHluYW1pY190ZW1wbGF0ZXMoKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gICAgYXN5bmMgZ2V0UmVxdWVzdCh1cmw6IHN0cmluZyk6IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVyRXJyb3IoXCJFcnJvciBwZXJmb3JtaW5nIEdFVCByZXF1ZXN0XCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZV9kYWlseV9xdW90ZSgpOiAoKSA9PiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgXCJodHRwczovL2FwaS5xdW90YWJsZS5pby9yYW5kb21cIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGpzb24gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGF1dGhvciA9IGpzb24uYXV0aG9yO1xuICAgICAgICAgICAgY29uc3QgcXVvdGUgPSBqc29uLmNvbnRlbnQ7XG4gICAgICAgICAgICBjb25zdCBuZXdfY29udGVudCA9IGA+ICR7cXVvdGV9XFxuPiDigJQgPGNpdGU+JHthdXRob3J9PC9jaXRlPmA7XG5cbiAgICAgICAgICAgIHJldHVybiBuZXdfY29udGVudDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZV9yYW5kb21fcGljdHVyZSgpOiAoXG4gICAgICAgIHNpemU6IHN0cmluZyxcbiAgICAgICAgcXVlcnk/OiBzdHJpbmdcbiAgICApID0+IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBhc3luYyAoc2l6ZTogc3RyaW5nLCBxdWVyeT86IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgYGh0dHBzOi8vc291cmNlLnVuc3BsYXNoLmNvbS9yYW5kb20vJHtzaXplID8/IFwiXCJ9PyR7XG4gICAgICAgICAgICAgICAgICAgIHF1ZXJ5ID8/IFwiXCJcbiAgICAgICAgICAgICAgICB9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHJlc3BvbnNlLnVybDtcbiAgICAgICAgICAgIHJldHVybiBgIVt0cC53ZWIucmFuZG9tX3BpY3R1cmVdKCR7dXJsfSlgO1xuICAgICAgICB9O1xuICAgIH1cbn1cbiIsImltcG9ydCB7IEludGVybmFsTW9kdWxlIH0gZnJvbSBcIi4uL0ludGVybmFsTW9kdWxlXCI7XG5pbXBvcnQgeyBNb2R1bGVOYW1lIH0gZnJvbSBcImZ1bmN0aW9ucy9UcERvY3VtZW50YXRpb25cIjtcblxuZXhwb3J0IGNsYXNzIEludGVybmFsTW9kdWxlRnJvbnRtYXR0ZXIgZXh0ZW5kcyBJbnRlcm5hbE1vZHVsZSB7XG4gICAgcHVibGljIG5hbWU6IE1vZHVsZU5hbWUgPSBcImZyb250bWF0dGVyXCI7XG5cbiAgICBhc3luYyBjcmVhdGVfc3RhdGljX3RlbXBsYXRlcygpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgICBhc3luYyBjcmVhdGVfZHluYW1pY190ZW1wbGF0ZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IGNhY2hlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaWxlQ2FjaGUoXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy50YXJnZXRfZmlsZVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmR5bmFtaWNfZnVuY3Rpb25zID0gbmV3IE1hcChcbiAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGNhY2hlPy5mcm9udG1hdHRlciB8fCB7fSlcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBUZW1wbGF0ZXJFcnJvciB9IGZyb20gXCJFcnJvclwiO1xuaW1wb3J0IHsgQXBwLCBNb2RhbCB9IGZyb20gXCJvYnNpZGlhblwiO1xuXG5leHBvcnQgY2xhc3MgUHJvbXB0TW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG4gICAgcHJpdmF0ZSBwcm9tcHRFbDogSFRNTElucHV0RWxlbWVudDtcbiAgICBwcml2YXRlIHJlc29sdmU6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkO1xuICAgIHByaXZhdGUgcmVqZWN0OiAocmVhc29uPzogVGVtcGxhdGVyRXJyb3IpID0+IHZvaWQ7XG4gICAgcHJpdmF0ZSBzdWJtaXR0ZWQgPSBmYWxzZTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBhcHA6IEFwcCxcbiAgICAgICAgcHJpdmF0ZSBwcm9tcHRfdGV4dDogc3RyaW5nLFxuICAgICAgICBwcml2YXRlIGRlZmF1bHRfdmFsdWU6IHN0cmluZ1xuICAgICkge1xuICAgICAgICBzdXBlcihhcHApO1xuICAgIH1cblxuICAgIG9uT3BlbigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy50aXRsZUVsLnNldFRleHQodGhpcy5wcm9tcHRfdGV4dCk7XG4gICAgICAgIHRoaXMuY3JlYXRlRm9ybSgpO1xuICAgIH1cblxuICAgIG9uQ2xvc2UoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY29udGVudEVsLmVtcHR5KCk7XG4gICAgICAgIGlmICghdGhpcy5zdWJtaXR0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMucmVqZWN0KG5ldyBUZW1wbGF0ZXJFcnJvcihcIkNhbmNlbGxlZCBwcm9tcHRcIikpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY3JlYXRlRm9ybSgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGl2ID0gdGhpcy5jb250ZW50RWwuY3JlYXRlRGl2KCk7XG4gICAgICAgIGRpdi5hZGRDbGFzcyhcInRlbXBsYXRlci1wcm9tcHQtZGl2XCIpO1xuXG4gICAgICAgIGNvbnN0IGZvcm0gPSBkaXYuY3JlYXRlRWwoXCJmb3JtXCIpO1xuICAgICAgICBmb3JtLmFkZENsYXNzKFwidGVtcGxhdGVyLXByb21wdC1mb3JtXCIpO1xuICAgICAgICBmb3JtLnR5cGUgPSBcInN1Ym1pdFwiO1xuICAgICAgICBmb3JtLm9uc3VibWl0ID0gKGU6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN1Ym1pdHRlZCA9IHRydWU7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLnJlc29sdmUodGhpcy5wcm9tcHRFbC52YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5wcm9tcHRFbCA9IGZvcm0uY3JlYXRlRWwoXCJpbnB1dFwiKTtcbiAgICAgICAgdGhpcy5wcm9tcHRFbC50eXBlID0gXCJ0ZXh0XCI7XG4gICAgICAgIHRoaXMucHJvbXB0RWwucGxhY2Vob2xkZXIgPSBcIlR5cGUgdGV4dCBoZXJlLi4uXCI7XG4gICAgICAgIHRoaXMucHJvbXB0RWwudmFsdWUgPSB0aGlzLmRlZmF1bHRfdmFsdWUgPz8gXCJcIjtcbiAgICAgICAgdGhpcy5wcm9tcHRFbC5hZGRDbGFzcyhcInRlbXBsYXRlci1wcm9tcHQtaW5wdXRcIik7XG4gICAgICAgIHRoaXMucHJvbXB0RWwuc2VsZWN0KCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb3BlbkFuZEdldFZhbHVlKFxuICAgICAgICByZXNvbHZlOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZCxcbiAgICAgICAgcmVqZWN0OiAocmVhc29uPzogVGVtcGxhdGVyRXJyb3IpID0+IHZvaWRcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgdGhpcy5yZWplY3QgPSByZWplY3Q7XG4gICAgICAgIHRoaXMub3BlbigpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IFRlbXBsYXRlckVycm9yIH0gZnJvbSBcIkVycm9yXCI7XG5pbXBvcnQgeyBBcHAsIEZ1enp5TWF0Y2gsIEZ1enp5U3VnZ2VzdE1vZGFsIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmV4cG9ydCBjbGFzcyBTdWdnZXN0ZXJNb2RhbDxUPiBleHRlbmRzIEZ1enp5U3VnZ2VzdE1vZGFsPFQ+IHtcbiAgICBwcml2YXRlIHJlc29sdmU6ICh2YWx1ZTogVCkgPT4gdm9pZDtcbiAgICBwcml2YXRlIHJlamVjdDogKHJlYXNvbj86IFRlbXBsYXRlckVycm9yKSA9PiB2b2lkO1xuICAgIHByaXZhdGUgc3VibWl0dGVkID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgYXBwOiBBcHAsXG4gICAgICAgIHByaXZhdGUgdGV4dF9pdGVtczogc3RyaW5nW10gfCAoKGl0ZW06IFQpID0+IHN0cmluZyksXG4gICAgICAgIHByaXZhdGUgaXRlbXM6IFRbXSxcbiAgICAgICAgcGxhY2Vob2xkZXI6IHN0cmluZ1xuICAgICkge1xuICAgICAgICBzdXBlcihhcHApO1xuICAgICAgICB0aGlzLnNldFBsYWNlaG9sZGVyKHBsYWNlaG9sZGVyKTtcbiAgICB9XG5cbiAgICBnZXRJdGVtcygpOiBUW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5pdGVtcztcbiAgICB9XG5cbiAgICBvbkNsb3NlKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuc3VibWl0dGVkKSB7XG4gICAgICAgICAgICB0aGlzLnJlamVjdChuZXcgVGVtcGxhdGVyRXJyb3IoXCJDYW5jZWxsZWQgcHJvbXB0XCIpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNlbGVjdFN1Z2dlc3Rpb24oXG4gICAgICAgIHZhbHVlOiBGdXp6eU1hdGNoPFQ+LFxuICAgICAgICBldnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50XG4gICAgKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc3VibWl0dGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICB0aGlzLm9uQ2hvb3NlU3VnZ2VzdGlvbih2YWx1ZSwgZXZ0KTtcbiAgICB9XG5cbiAgICBnZXRJdGVtVGV4dChpdGVtOiBUKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHRoaXMudGV4dF9pdGVtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50ZXh0X2l0ZW1zKGl0ZW0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLnRleHRfaXRlbXNbdGhpcy5pdGVtcy5pbmRleE9mKGl0ZW0pXSB8fCBcIlVuZGVmaW5lZCBUZXh0IEl0ZW1cIlxuICAgICAgICApO1xuICAgIH1cblxuICAgIG9uQ2hvb3NlSXRlbShpdGVtOiBUKTogdm9pZCB7XG4gICAgICAgIHRoaXMucmVzb2x2ZShpdGVtKTtcbiAgICB9XG5cbiAgICBhc3luYyBvcGVuQW5kR2V0VmFsdWUoXG4gICAgICAgIHJlc29sdmU6ICh2YWx1ZTogVCkgPT4gdm9pZCxcbiAgICAgICAgcmVqZWN0OiAocmVhc29uPzogVGVtcGxhdGVyRXJyb3IpID0+IHZvaWRcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgdGhpcy5yZWplY3QgPSByZWplY3Q7XG4gICAgICAgIHRoaXMub3BlbigpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IFVOU1VQUE9SVEVEX01PQklMRV9URU1QTEFURSB9IGZyb20gXCJDb25zdGFudHNcIjtcbmltcG9ydCB7IEludGVybmFsTW9kdWxlIH0gZnJvbSBcIi4uL0ludGVybmFsTW9kdWxlXCI7XG5pbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgUHJvbXB0TW9kYWwgfSBmcm9tIFwiLi9Qcm9tcHRNb2RhbFwiO1xuaW1wb3J0IHsgU3VnZ2VzdGVyTW9kYWwgfSBmcm9tIFwiLi9TdWdnZXN0ZXJNb2RhbFwiO1xuaW1wb3J0IHsgVGVtcGxhdGVyRXJyb3IgfSBmcm9tIFwiRXJyb3JcIjtcbmltcG9ydCB7IE1vZHVsZU5hbWUgfSBmcm9tIFwiZnVuY3Rpb25zL1RwRG9jdW1lbnRhdGlvblwiO1xuXG5leHBvcnQgY2xhc3MgSW50ZXJuYWxNb2R1bGVTeXN0ZW0gZXh0ZW5kcyBJbnRlcm5hbE1vZHVsZSB7XG4gICAgcHVibGljIG5hbWU6IE1vZHVsZU5hbWUgPSBcInN5c3RlbVwiO1xuXG4gICAgYXN5bmMgY3JlYXRlX3N0YXRpY190ZW1wbGF0ZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXCJjbGlwYm9hcmRcIiwgdGhpcy5nZW5lcmF0ZV9jbGlwYm9hcmQoKSk7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXCJwcm9tcHRcIiwgdGhpcy5nZW5lcmF0ZV9wcm9tcHQoKSk7XG4gICAgICAgIHRoaXMuc3RhdGljX2Z1bmN0aW9ucy5zZXQoXCJzdWdnZXN0ZXJcIiwgdGhpcy5nZW5lcmF0ZV9zdWdnZXN0ZXIoKSk7XG4gICAgfVxuXG4gICAgYXN5bmMgY3JlYXRlX2R5bmFtaWNfdGVtcGxhdGVzKCk6IFByb21pc2U8dm9pZD4ge31cblxuICAgIGdlbmVyYXRlX2NsaXBib2FyZCgpOiAoKSA9PiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gVE9ETzogQWRkIG1vYmlsZSBzdXBwb3J0XG4gICAgICAgICAgICBpZiAoUGxhdGZvcm0uaXNNb2JpbGVBcHApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gVU5TVVBQT1JURURfTU9CSUxFX1RFTVBMQVRFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IG5hdmlnYXRvci5jbGlwYm9hcmQucmVhZFRleHQoKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZV9wcm9tcHQoKTogKFxuICAgICAgICBwcm9tcHRfdGV4dDogc3RyaW5nLFxuICAgICAgICBkZWZhdWx0X3ZhbHVlOiBzdHJpbmcsXG4gICAgICAgIHRocm93X29uX2NhbmNlbDogYm9vbGVhblxuICAgICkgPT4gUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIGFzeW5jIChcbiAgICAgICAgICAgIHByb21wdF90ZXh0OiBzdHJpbmcsXG4gICAgICAgICAgICBkZWZhdWx0X3ZhbHVlOiBzdHJpbmcsXG4gICAgICAgICAgICB0aHJvd19vbl9jYW5jZWwgPSBmYWxzZVxuICAgICAgICApOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJvbXB0ID0gbmV3IFByb21wdE1vZGFsKFxuICAgICAgICAgICAgICAgIHRoaXMuYXBwLFxuICAgICAgICAgICAgICAgIHByb21wdF90ZXh0LFxuICAgICAgICAgICAgICAgIGRlZmF1bHRfdmFsdWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UoXG4gICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZCxcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0OiAocmVhc29uPzogVGVtcGxhdGVyRXJyb3IpID0+IHZvaWRcbiAgICAgICAgICAgICAgICApID0+IHByb21wdC5vcGVuQW5kR2V0VmFsdWUocmVzb2x2ZSwgcmVqZWN0KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHByb21pc2U7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGlmICh0aHJvd19vbl9jYW5jZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdlbmVyYXRlX3N1Z2dlc3RlcigpOiA8VD4oXG4gICAgICAgIHRleHRfaXRlbXM6IHN0cmluZ1tdIHwgKChpdGVtOiBUKSA9PiBzdHJpbmcpLFxuICAgICAgICBpdGVtczogVFtdLFxuICAgICAgICB0aHJvd19vbl9jYW5jZWw6IGJvb2xlYW4sXG4gICAgICAgIHBsYWNlaG9sZGVyOiBzdHJpbmdcbiAgICApID0+IFByb21pc2U8VD4ge1xuICAgICAgICByZXR1cm4gYXN5bmMgPFQ+KFxuICAgICAgICAgICAgdGV4dF9pdGVtczogc3RyaW5nW10gfCAoKGl0ZW06IFQpID0+IHN0cmluZyksXG4gICAgICAgICAgICBpdGVtczogVFtdLFxuICAgICAgICAgICAgdGhyb3dfb25fY2FuY2VsID0gZmFsc2UsXG4gICAgICAgICAgICBwbGFjZWhvbGRlciA9IFwiXCJcbiAgICAgICAgKTogUHJvbWlzZTxUPiA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdWdnZXN0ZXIgPSBuZXcgU3VnZ2VzdGVyTW9kYWwoXG4gICAgICAgICAgICAgICAgdGhpcy5hcHAsXG4gICAgICAgICAgICAgICAgdGV4dF9pdGVtcyxcbiAgICAgICAgICAgICAgICBpdGVtcyxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlclxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZShcbiAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmU6ICh2YWx1ZTogVCkgPT4gdm9pZCxcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0OiAocmVhc29uPzogVGVtcGxhdGVyRXJyb3IpID0+IHZvaWRcbiAgICAgICAgICAgICAgICApID0+IHN1Z2dlc3Rlci5vcGVuQW5kR2V0VmFsdWUocmVzb2x2ZSwgcmVqZWN0KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHByb21pc2U7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGlmICh0aHJvd19vbl9jYW5jZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbn1cbiIsImltcG9ydCB7IEludGVybmFsTW9kdWxlIH0gZnJvbSBcImZ1bmN0aW9ucy9pbnRlcm5hbF9mdW5jdGlvbnMvSW50ZXJuYWxNb2R1bGVcIjtcbmltcG9ydCB7IFJ1bm5pbmdDb25maWcgfSBmcm9tIFwiVGVtcGxhdGVyXCI7XG5pbXBvcnQgeyBNb2R1bGVOYW1lIH0gZnJvbSBcImZ1bmN0aW9ucy9UcERvY3VtZW50YXRpb25cIjtcblxuZXhwb3J0IGNsYXNzIEludGVybmFsTW9kdWxlQ29uZmlnIGV4dGVuZHMgSW50ZXJuYWxNb2R1bGUge1xuICAgIHB1YmxpYyBuYW1lOiBNb2R1bGVOYW1lID0gXCJjb25maWdcIjtcblxuICAgIGFzeW5jIGNyZWF0ZV9zdGF0aWNfdGVtcGxhdGVzKCk6IFByb21pc2U8dm9pZD4ge31cblxuICAgIGFzeW5jIGNyZWF0ZV9keW5hbWljX3RlbXBsYXRlcygpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgICBhc3luYyBnZW5lcmF0ZV9vYmplY3QoXG4gICAgICAgIGNvbmZpZzogUnVubmluZ0NvbmZpZ1xuICAgICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBBcHAgfSBmcm9tIFwib2JzaWRpYW5cIjtcblxuaW1wb3J0IFRlbXBsYXRlclBsdWdpbiBmcm9tIFwibWFpblwiO1xuaW1wb3J0IHsgSUdlbmVyYXRlT2JqZWN0IH0gZnJvbSBcImZ1bmN0aW9ucy9JR2VuZXJhdGVPYmplY3RcIjtcbmltcG9ydCB7IEludGVybmFsTW9kdWxlIH0gZnJvbSBcIi4vSW50ZXJuYWxNb2R1bGVcIjtcbmltcG9ydCB7IEludGVybmFsTW9kdWxlRGF0ZSB9IGZyb20gXCIuL2RhdGUvSW50ZXJuYWxNb2R1bGVEYXRlXCI7XG5pbXBvcnQgeyBJbnRlcm5hbE1vZHVsZUZpbGUgfSBmcm9tIFwiLi9maWxlL0ludGVybmFsTW9kdWxlRmlsZVwiO1xuaW1wb3J0IHsgSW50ZXJuYWxNb2R1bGVXZWIgfSBmcm9tIFwiLi93ZWIvSW50ZXJuYWxNb2R1bGVXZWJcIjtcbmltcG9ydCB7IEludGVybmFsTW9kdWxlRnJvbnRtYXR0ZXIgfSBmcm9tIFwiLi9mcm9udG1hdHRlci9JbnRlcm5hbE1vZHVsZUZyb250bWF0dGVyXCI7XG5pbXBvcnQgeyBJbnRlcm5hbE1vZHVsZVN5c3RlbSB9IGZyb20gXCIuL3N5c3RlbS9JbnRlcm5hbE1vZHVsZVN5c3RlbVwiO1xuaW1wb3J0IHsgUnVubmluZ0NvbmZpZyB9IGZyb20gXCJUZW1wbGF0ZXJcIjtcbmltcG9ydCB7IEludGVybmFsTW9kdWxlQ29uZmlnIH0gZnJvbSBcIi4vY29uZmlnL0ludGVybmFsTW9kdWxlQ29uZmlnXCI7XG5cbmV4cG9ydCBjbGFzcyBJbnRlcm5hbEZ1bmN0aW9ucyBpbXBsZW1lbnRzIElHZW5lcmF0ZU9iamVjdCB7XG4gICAgcHJpdmF0ZSBtb2R1bGVzX2FycmF5OiBBcnJheTxJbnRlcm5hbE1vZHVsZT4gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBhcHA6IEFwcCwgcHJvdGVjdGVkIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luKSB7XG4gICAgICAgIHRoaXMubW9kdWxlc19hcnJheS5wdXNoKG5ldyBJbnRlcm5hbE1vZHVsZURhdGUodGhpcy5hcHAsIHRoaXMucGx1Z2luKSk7XG4gICAgICAgIHRoaXMubW9kdWxlc19hcnJheS5wdXNoKG5ldyBJbnRlcm5hbE1vZHVsZUZpbGUodGhpcy5hcHAsIHRoaXMucGx1Z2luKSk7XG4gICAgICAgIHRoaXMubW9kdWxlc19hcnJheS5wdXNoKG5ldyBJbnRlcm5hbE1vZHVsZVdlYih0aGlzLmFwcCwgdGhpcy5wbHVnaW4pKTtcbiAgICAgICAgdGhpcy5tb2R1bGVzX2FycmF5LnB1c2goXG4gICAgICAgICAgICBuZXcgSW50ZXJuYWxNb2R1bGVGcm9udG1hdHRlcih0aGlzLmFwcCwgdGhpcy5wbHVnaW4pXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMubW9kdWxlc19hcnJheS5wdXNoKFxuICAgICAgICAgICAgbmV3IEludGVybmFsTW9kdWxlU3lzdGVtKHRoaXMuYXBwLCB0aGlzLnBsdWdpbilcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5tb2R1bGVzX2FycmF5LnB1c2goXG4gICAgICAgICAgICBuZXcgSW50ZXJuYWxNb2R1bGVDb25maWcodGhpcy5hcHAsIHRoaXMucGx1Z2luKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIGFzeW5jIGluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGZvciAoY29uc3QgbW9kIG9mIHRoaXMubW9kdWxlc19hcnJheSkge1xuICAgICAgICAgICAgYXdhaXQgbW9kLmluaXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGdlbmVyYXRlX29iamVjdChcbiAgICAgICAgY29uZmlnOiBSdW5uaW5nQ29uZmlnXG4gICAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ge1xuICAgICAgICBjb25zdCBpbnRlcm5hbF9mdW5jdGlvbnNfb2JqZWN0OiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHt9O1xuXG4gICAgICAgIGZvciAoY29uc3QgbW9kIG9mIHRoaXMubW9kdWxlc19hcnJheSkge1xuICAgICAgICAgICAgaW50ZXJuYWxfZnVuY3Rpb25zX29iamVjdFttb2QuZ2V0TmFtZSgpXSA9XG4gICAgICAgICAgICAgICAgYXdhaXQgbW9kLmdlbmVyYXRlX29iamVjdChjb25maWcpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGludGVybmFsX2Z1bmN0aW9uc19vYmplY3Q7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgZXhlYyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tIFwidXRpbFwiO1xuaW1wb3J0IHsgQXBwLCBQbGF0Zm9ybSwgRmlsZVN5c3RlbUFkYXB0ZXIgfSBmcm9tIFwib2JzaWRpYW5cIjtcblxuaW1wb3J0IFRlbXBsYXRlclBsdWdpbiBmcm9tIFwibWFpblwiO1xuaW1wb3J0IHsgSUdlbmVyYXRlT2JqZWN0IH0gZnJvbSBcImZ1bmN0aW9ucy9JR2VuZXJhdGVPYmplY3RcIjtcbmltcG9ydCB7IFJ1bm5pbmdDb25maWcgfSBmcm9tIFwiVGVtcGxhdGVyXCI7XG5pbXBvcnQgeyBVTlNVUFBPUlRFRF9NT0JJTEVfVEVNUExBVEUgfSBmcm9tIFwiQ29uc3RhbnRzXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZXJFcnJvciB9IGZyb20gXCJFcnJvclwiO1xuaW1wb3J0IHsgRnVuY3Rpb25zTW9kZSB9IGZyb20gXCJmdW5jdGlvbnMvRnVuY3Rpb25zR2VuZXJhdG9yXCI7XG5cbmV4cG9ydCBjbGFzcyBVc2VyU3lzdGVtRnVuY3Rpb25zIGltcGxlbWVudHMgSUdlbmVyYXRlT2JqZWN0IHtcbiAgICBwcml2YXRlIGN3ZDogc3RyaW5nO1xuICAgIHByaXZhdGUgZXhlY19wcm9taXNlOiAoXG4gICAgICAgIGFyZzE6IHN0cmluZyxcbiAgICAgICAgYXJnMjogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgICApID0+IFByb21pc2U8eyBzdGRvdXQ6IHN0cmluZzsgc3RkZXJyOiBzdHJpbmcgfT47XG5cbiAgICBjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcHJpdmF0ZSBwbHVnaW46IFRlbXBsYXRlclBsdWdpbikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBQbGF0Zm9ybS5pc01vYmlsZUFwcCB8fFxuICAgICAgICAgICAgIShhcHAudmF1bHQuYWRhcHRlciBpbnN0YW5jZW9mIEZpbGVTeXN0ZW1BZGFwdGVyKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuY3dkID0gXCJcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY3dkID0gYXBwLnZhdWx0LmFkYXB0ZXIuZ2V0QmFzZVBhdGgoKTtcbiAgICAgICAgICAgIHRoaXMuZXhlY19wcm9taXNlID0gcHJvbWlzaWZ5KGV4ZWMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVE9ETzogQWRkIG1vYmlsZSBzdXBwb3J0XG4gICAgYXN5bmMgZ2VuZXJhdGVfc3lzdGVtX2Z1bmN0aW9ucyhcbiAgICAgICAgY29uZmlnOiBSdW5uaW5nQ29uZmlnXG4gICAgKTogUHJvbWlzZTxcbiAgICAgICAgTWFwPHN0cmluZywgKHVzZXJfYXJncz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBQcm9taXNlPHN0cmluZz4+XG4gICAgPiB7XG4gICAgICAgIGNvbnN0IHVzZXJfc3lzdGVtX2Z1bmN0aW9uczogTWFwPFxuICAgICAgICAgICAgc3RyaW5nLFxuICAgICAgICAgICAgKHVzZXJfYXJncz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBQcm9taXNlPHN0cmluZz5cbiAgICAgICAgPiA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3QgaW50ZXJuYWxfZnVuY3Rpb25zX29iamVjdCA9XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi50ZW1wbGF0ZXIuZnVuY3Rpb25zX2dlbmVyYXRvci5nZW5lcmF0ZV9vYmplY3QoXG4gICAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICAgIEZ1bmN0aW9uc01vZGUuSU5URVJOQUxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgZm9yIChjb25zdCB0ZW1wbGF0ZV9wYWlyIG9mIHRoaXMucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlc19wYWlycykge1xuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGUgPSB0ZW1wbGF0ZV9wYWlyWzBdO1xuICAgICAgICAgICAgbGV0IGNtZCA9IHRlbXBsYXRlX3BhaXJbMV07XG4gICAgICAgICAgICBpZiAoIXRlbXBsYXRlIHx8ICFjbWQpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKFBsYXRmb3JtLmlzTW9iaWxlQXBwKSB7XG4gICAgICAgICAgICAgICAgdXNlcl9zeXN0ZW1fZnVuY3Rpb25zLnNldCh0ZW1wbGF0ZSwgKCk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoVU5TVVBQT1JURURfTU9CSUxFX1RFTVBMQVRFKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjbWQgPSBhd2FpdCB0aGlzLnBsdWdpbi50ZW1wbGF0ZXIucGFyc2VyLnBhcnNlX2NvbW1hbmRzKFxuICAgICAgICAgICAgICAgICAgICBjbWQsXG4gICAgICAgICAgICAgICAgICAgIGludGVybmFsX2Z1bmN0aW9uc19vYmplY3RcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgdXNlcl9zeXN0ZW1fZnVuY3Rpb25zLnNldChcbiAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGUsXG4gICAgICAgICAgICAgICAgICAgIGFzeW5jIChcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJfYXJncz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICAgICAgICAgICAgICAgICAgICk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9jZXNzX2VudiA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wcm9jZXNzLmVudixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi51c2VyX2FyZ3MsXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbWRfb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lb3V0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5jb21tYW5kX3RpbWVvdXQgKiAxMDAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN3ZDogdGhpcy5jd2QsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52OiBwcm9jZXNzX2VudixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4odGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hlbGxfcGF0aCAmJiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoZWxsOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaGVsbF9wYXRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHN0ZG91dCB9ID0gYXdhaXQgdGhpcy5leGVjX3Byb21pc2UoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21kX29wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGRvdXQudHJpbVJpZ2h0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUZW1wbGF0ZXJFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYEVycm9yIHdpdGggVXNlciBUZW1wbGF0ZSAke3RlbXBsYXRlfWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVzZXJfc3lzdGVtX2Z1bmN0aW9ucztcbiAgICB9XG5cbiAgICBhc3luYyBnZW5lcmF0ZV9vYmplY3QoXG4gICAgICAgIGNvbmZpZzogUnVubmluZ0NvbmZpZ1xuICAgICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgICAgICAgY29uc3QgdXNlcl9zeXN0ZW1fZnVuY3Rpb25zID0gYXdhaXQgdGhpcy5nZW5lcmF0ZV9zeXN0ZW1fZnVuY3Rpb25zKFxuICAgICAgICAgICAgY29uZmlnXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXModXNlcl9zeXN0ZW1fZnVuY3Rpb25zKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBBcHAsIEZpbGVTeXN0ZW1BZGFwdGVyLCBURmlsZSB9IGZyb20gXCJvYnNpZGlhblwiO1xuXG5pbXBvcnQgVGVtcGxhdGVyUGx1Z2luIGZyb20gXCJtYWluXCI7XG5pbXBvcnQgeyBJR2VuZXJhdGVPYmplY3QgfSBmcm9tIFwiZnVuY3Rpb25zL0lHZW5lcmF0ZU9iamVjdFwiO1xuaW1wb3J0IHsgUnVubmluZ0NvbmZpZyB9IGZyb20gXCJUZW1wbGF0ZXJcIjtcbmltcG9ydCB7IGdldF90ZmlsZXNfZnJvbV9mb2xkZXIgfSBmcm9tIFwiVXRpbHNcIjtcbmltcG9ydCB7IGVycm9yV3JhcHBlclN5bmMsIFRlbXBsYXRlckVycm9yIH0gZnJvbSBcIkVycm9yXCI7XG5cbmV4cG9ydCBjbGFzcyBVc2VyU2NyaXB0RnVuY3Rpb25zIGltcGxlbWVudHMgSUdlbmVyYXRlT2JqZWN0IHtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFwcDogQXBwLCBwcml2YXRlIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luKSB7fVxuXG4gICAgYXN5bmMgZ2VuZXJhdGVfdXNlcl9zY3JpcHRfZnVuY3Rpb25zKFxuICAgICAgICBjb25maWc6IFJ1bm5pbmdDb25maWdcbiAgICApOiBQcm9taXNlPE1hcDxzdHJpbmcsIEZ1bmN0aW9uPj4ge1xuICAgICAgICBjb25zdCB1c2VyX3NjcmlwdF9mdW5jdGlvbnM6IE1hcDxzdHJpbmcsIEZ1bmN0aW9uPiA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3QgZmlsZXMgPSBlcnJvcldyYXBwZXJTeW5jKFxuICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgICBnZXRfdGZpbGVzX2Zyb21fZm9sZGVyKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlcl9zY3JpcHRzX2ZvbGRlclxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICBgQ291bGRuJ3QgZmluZCB1c2VyIHNjcmlwdCBmb2xkZXIgXCIke3RoaXMucGx1Z2luLnNldHRpbmdzLnVzZXJfc2NyaXB0c19mb2xkZXJ9XCJgXG4gICAgICAgICk7XG4gICAgICAgIGlmICghZmlsZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgTWFwKCk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICAgICAgICAgIGlmIChmaWxlLmV4dGVuc2lvbi50b0xvd2VyQ2FzZSgpID09PSBcImpzXCIpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmxvYWRfdXNlcl9zY3JpcHRfZnVuY3Rpb24oXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgICAgICAgZmlsZSxcbiAgICAgICAgICAgICAgICAgICAgdXNlcl9zY3JpcHRfZnVuY3Rpb25zXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXNlcl9zY3JpcHRfZnVuY3Rpb25zO1xuICAgIH1cblxuICAgIGFzeW5jIGxvYWRfdXNlcl9zY3JpcHRfZnVuY3Rpb24oXG4gICAgICAgIGNvbmZpZzogUnVubmluZ0NvbmZpZyxcbiAgICAgICAgZmlsZTogVEZpbGUsXG4gICAgICAgIHVzZXJfc2NyaXB0X2Z1bmN0aW9uczogTWFwPHN0cmluZywgRnVuY3Rpb24+XG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICghKHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIgaW5zdGFuY2VvZiBGaWxlU3lzdGVtQWRhcHRlcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUZW1wbGF0ZXJFcnJvcihcbiAgICAgICAgICAgICAgICBcImFwcC52YXVsdCBpcyBub3QgYSBGaWxlU3lzdGVtQWRhcHRlciBpbnN0YW5jZVwiXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhdWx0X3BhdGggPSB0aGlzLmFwcC52YXVsdC5hZGFwdGVyLmdldEJhc2VQYXRoKCk7XG4gICAgICAgIGNvbnN0IGZpbGVfcGF0aCA9IGAke3ZhdWx0X3BhdGh9LyR7ZmlsZS5wYXRofWA7XG5cbiAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjY2MzM5MDEvcmVsb2FkLW1vZHVsZS1hdC1ydW50aW1lXG4gICAgICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE5NzIyNDIvaG93LXRvLWF1dG8tcmVsb2FkLWZpbGVzLWluLW5vZGUtanNcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKHdpbmRvdy5yZXF1aXJlLmNhY2hlKS5jb250YWlucyhmaWxlX3BhdGgpKSB7XG4gICAgICAgICAgICBkZWxldGUgd2luZG93LnJlcXVpcmUuY2FjaGVbd2luZG93LnJlcXVpcmUucmVzb2x2ZShmaWxlX3BhdGgpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHVzZXJfZnVuY3Rpb24gPSBhd2FpdCBpbXBvcnQoZmlsZV9wYXRoKTtcbiAgICAgICAgaWYgKCF1c2VyX2Z1bmN0aW9uLmRlZmF1bHQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUZW1wbGF0ZXJFcnJvcihcbiAgICAgICAgICAgICAgICBgRmFpbGVkIHRvIGxvYWQgdXNlciBzY3JpcHQgJHtmaWxlX3BhdGh9LiBObyBleHBvcnRzIGRldGVjdGVkLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEodXNlcl9mdW5jdGlvbi5kZWZhdWx0IGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVGVtcGxhdGVyRXJyb3IoXG4gICAgICAgICAgICAgICAgYEZhaWxlZCB0byBsb2FkIHVzZXIgc2NyaXB0ICR7ZmlsZV9wYXRofS4gRGVmYXVsdCBleHBvcnQgaXMgbm90IGEgZnVuY3Rpb24uYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB1c2VyX3NjcmlwdF9mdW5jdGlvbnMuc2V0KGAke2ZpbGUuYmFzZW5hbWV9YCwgdXNlcl9mdW5jdGlvbi5kZWZhdWx0KTtcbiAgICB9XG5cbiAgICBhc3luYyBnZW5lcmF0ZV9vYmplY3QoXG4gICAgICAgIGNvbmZpZzogUnVubmluZ0NvbmZpZ1xuICAgICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgICAgICAgY29uc3QgdXNlcl9zY3JpcHRfZnVuY3Rpb25zID0gYXdhaXQgdGhpcy5nZW5lcmF0ZV91c2VyX3NjcmlwdF9mdW5jdGlvbnMoXG4gICAgICAgICAgICBjb25maWdcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyh1c2VyX3NjcmlwdF9mdW5jdGlvbnMpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IEFwcCwgUGxhdGZvcm0gfSBmcm9tIFwib2JzaWRpYW5cIjtcblxuaW1wb3J0IFRlbXBsYXRlclBsdWdpbiBmcm9tIFwibWFpblwiO1xuaW1wb3J0IHsgUnVubmluZ0NvbmZpZyB9IGZyb20gXCJUZW1wbGF0ZXJcIjtcbmltcG9ydCB7IElHZW5lcmF0ZU9iamVjdCB9IGZyb20gXCJmdW5jdGlvbnMvSUdlbmVyYXRlT2JqZWN0XCI7XG5pbXBvcnQgeyBVc2VyU3lzdGVtRnVuY3Rpb25zIH0gZnJvbSBcImZ1bmN0aW9ucy91c2VyX2Z1bmN0aW9ucy9Vc2VyU3lzdGVtRnVuY3Rpb25zXCI7XG5pbXBvcnQgeyBVc2VyU2NyaXB0RnVuY3Rpb25zIH0gZnJvbSBcImZ1bmN0aW9ucy91c2VyX2Z1bmN0aW9ucy9Vc2VyU2NyaXB0RnVuY3Rpb25zXCI7XG5cbmV4cG9ydCBjbGFzcyBVc2VyRnVuY3Rpb25zIGltcGxlbWVudHMgSUdlbmVyYXRlT2JqZWN0IHtcbiAgICBwcml2YXRlIHVzZXJfc3lzdGVtX2Z1bmN0aW9uczogVXNlclN5c3RlbUZ1bmN0aW9ucztcbiAgICBwcml2YXRlIHVzZXJfc2NyaXB0X2Z1bmN0aW9uczogVXNlclNjcmlwdEZ1bmN0aW9ucztcblxuICAgIGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwcml2YXRlIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luKSB7XG4gICAgICAgIHRoaXMudXNlcl9zeXN0ZW1fZnVuY3Rpb25zID0gbmV3IFVzZXJTeXN0ZW1GdW5jdGlvbnMoYXBwLCBwbHVnaW4pO1xuICAgICAgICB0aGlzLnVzZXJfc2NyaXB0X2Z1bmN0aW9ucyA9IG5ldyBVc2VyU2NyaXB0RnVuY3Rpb25zKGFwcCwgcGx1Z2luKTtcbiAgICB9XG5cbiAgICBhc3luYyBnZW5lcmF0ZV9vYmplY3QoXG4gICAgICAgIGNvbmZpZzogUnVubmluZ0NvbmZpZ1xuICAgICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgICAgICAgbGV0IHVzZXJfc3lzdGVtX2Z1bmN0aW9ucyA9IHt9O1xuICAgICAgICBsZXQgdXNlcl9zY3JpcHRfZnVuY3Rpb25zID0ge307XG5cbiAgICAgICAgaWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLmVuYWJsZV9zeXN0ZW1fY29tbWFuZHMpIHtcbiAgICAgICAgICAgIHVzZXJfc3lzdGVtX2Z1bmN0aW9ucyA9XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy51c2VyX3N5c3RlbV9mdW5jdGlvbnMuZ2VuZXJhdGVfb2JqZWN0KGNvbmZpZyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUT0RPOiBBZGQgbW9iaWxlIHN1cHBvcnRcbiAgICAgICAgLy8gdXNlcl9zY3JpcHRzX2ZvbGRlciBuZWVkcyB0byBiZSBleHBsaWNpdGx5IHNldCB0byAnLycgdG8gcXVlcnkgZnJvbSByb290XG4gICAgICAgIGlmIChQbGF0Zm9ybS5pc0Rlc2t0b3BBcHAgJiYgdGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlcl9zY3JpcHRzX2ZvbGRlcikge1xuICAgICAgICAgICAgdXNlcl9zY3JpcHRfZnVuY3Rpb25zID1cbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnVzZXJfc2NyaXB0X2Z1bmN0aW9ucy5nZW5lcmF0ZV9vYmplY3QoY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi51c2VyX3N5c3RlbV9mdW5jdGlvbnMsXG4gICAgICAgICAgICAuLi51c2VyX3NjcmlwdF9mdW5jdGlvbnMsXG4gICAgICAgIH07XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgQXBwIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmltcG9ydCB7IEludGVybmFsRnVuY3Rpb25zIH0gZnJvbSBcImZ1bmN0aW9ucy9pbnRlcm5hbF9mdW5jdGlvbnMvSW50ZXJuYWxGdW5jdGlvbnNcIjtcbmltcG9ydCB7IFVzZXJGdW5jdGlvbnMgfSBmcm9tIFwiZnVuY3Rpb25zL3VzZXJfZnVuY3Rpb25zL1VzZXJGdW5jdGlvbnNcIjtcbmltcG9ydCBUZW1wbGF0ZXJQbHVnaW4gZnJvbSBcIm1haW5cIjtcbmltcG9ydCB7IElHZW5lcmF0ZU9iamVjdCB9IGZyb20gXCJmdW5jdGlvbnMvSUdlbmVyYXRlT2JqZWN0XCI7XG5pbXBvcnQgeyBSdW5uaW5nQ29uZmlnIH0gZnJvbSBcIlRlbXBsYXRlclwiO1xuaW1wb3J0ICogYXMgb2JzaWRpYW5fbW9kdWxlIGZyb20gXCJvYnNpZGlhblwiO1xuXG5leHBvcnQgZW51bSBGdW5jdGlvbnNNb2RlIHtcbiAgICBJTlRFUk5BTCxcbiAgICBVU0VSX0lOVEVSTkFMLFxufVxuXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25zR2VuZXJhdG9yIGltcGxlbWVudHMgSUdlbmVyYXRlT2JqZWN0IHtcbiAgICBwdWJsaWMgaW50ZXJuYWxfZnVuY3Rpb25zOiBJbnRlcm5hbEZ1bmN0aW9ucztcbiAgICBwdWJsaWMgdXNlcl9mdW5jdGlvbnM6IFVzZXJGdW5jdGlvbnM7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFwcDogQXBwLCBwcml2YXRlIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luKSB7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxfZnVuY3Rpb25zID0gbmV3IEludGVybmFsRnVuY3Rpb25zKHRoaXMuYXBwLCB0aGlzLnBsdWdpbik7XG4gICAgICAgIHRoaXMudXNlcl9mdW5jdGlvbnMgPSBuZXcgVXNlckZ1bmN0aW9ucyh0aGlzLmFwcCwgdGhpcy5wbHVnaW4pO1xuICAgIH1cblxuICAgIGFzeW5jIGluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW50ZXJuYWxfZnVuY3Rpb25zLmluaXQoKTtcbiAgICB9XG5cbiAgICBhZGRpdGlvbmFsX2Z1bmN0aW9ucygpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvYnNpZGlhbjogb2JzaWRpYW5fbW9kdWxlLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGFzeW5jIGdlbmVyYXRlX29iamVjdChcbiAgICAgICAgY29uZmlnOiBSdW5uaW5nQ29uZmlnLFxuICAgICAgICBmdW5jdGlvbnNfbW9kZTogRnVuY3Rpb25zTW9kZSA9IEZ1bmN0aW9uc01vZGUuVVNFUl9JTlRFUk5BTFxuICAgICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgICAgICAgY29uc3QgZmluYWxfb2JqZWN0ID0ge307XG4gICAgICAgIGNvbnN0IGFkZGl0aW9uYWxfZnVuY3Rpb25zX29iamVjdCA9IHRoaXMuYWRkaXRpb25hbF9mdW5jdGlvbnMoKTtcbiAgICAgICAgY29uc3QgaW50ZXJuYWxfZnVuY3Rpb25zX29iamVjdCA9XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmludGVybmFsX2Z1bmN0aW9ucy5nZW5lcmF0ZV9vYmplY3QoY29uZmlnKTtcbiAgICAgICAgbGV0IHVzZXJfZnVuY3Rpb25zX29iamVjdCA9IHt9O1xuXG4gICAgICAgIE9iamVjdC5hc3NpZ24oZmluYWxfb2JqZWN0LCBhZGRpdGlvbmFsX2Z1bmN0aW9uc19vYmplY3QpO1xuICAgICAgICBzd2l0Y2ggKGZ1bmN0aW9uc19tb2RlKSB7XG4gICAgICAgICAgICBjYXNlIEZ1bmN0aW9uc01vZGUuSU5URVJOQUw6XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihmaW5hbF9vYmplY3QsIGludGVybmFsX2Z1bmN0aW9uc19vYmplY3QpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBGdW5jdGlvbnNNb2RlLlVTRVJfSU5URVJOQUw6XG4gICAgICAgICAgICAgICAgdXNlcl9mdW5jdGlvbnNfb2JqZWN0ID1cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy51c2VyX2Z1bmN0aW9ucy5nZW5lcmF0ZV9vYmplY3QoY29uZmlnKTtcbiAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKGZpbmFsX29iamVjdCwge1xuICAgICAgICAgICAgICAgICAgICAuLi5pbnRlcm5hbF9mdW5jdGlvbnNfb2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICB1c2VyOiB1c2VyX2Z1bmN0aW9uc19vYmplY3QsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmluYWxfb2JqZWN0O1xuICAgIH1cbn1cbiIsImltcG9ydCB7XG4gICAgQXBwLFxuICAgIEVkaXRvclBvc2l0aW9uLFxuICAgIEVkaXRvclJhbmdlT3JDYXJldCxcbiAgICBFZGl0b3JUcmFuc2FjdGlvbixcbiAgICBNYXJrZG93blZpZXcsXG59IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgZXNjYXBlX1JlZ0V4cCB9IGZyb20gXCJVdGlsc1wiO1xuXG5leHBvcnQgY2xhc3MgQ3Vyc29ySnVtcGVyIHtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFwcDogQXBwKSB7fVxuXG4gICAgYXN5bmMganVtcF90b19uZXh0X2N1cnNvcl9sb2NhdGlvbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgYWN0aXZlX3ZpZXcgPVxuICAgICAgICAgICAgdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KTtcbiAgICAgICAgaWYgKCFhY3RpdmVfdmlldykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFjdGl2ZV9maWxlID0gYWN0aXZlX3ZpZXcuZmlsZTtcbiAgICAgICAgYXdhaXQgYWN0aXZlX3ZpZXcuc2F2ZSgpO1xuXG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCB0aGlzLmFwcC52YXVsdC5yZWFkKGFjdGl2ZV9maWxlKTtcblxuICAgICAgICBjb25zdCB7IG5ld19jb250ZW50LCBwb3NpdGlvbnMgfSA9XG4gICAgICAgICAgICB0aGlzLnJlcGxhY2VfYW5kX2dldF9jdXJzb3JfcG9zaXRpb25zKGNvbnRlbnQpO1xuICAgICAgICBpZiAocG9zaXRpb25zKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmFwcC52YXVsdC5tb2RpZnkoYWN0aXZlX2ZpbGUsIG5ld19jb250ZW50KTtcbiAgICAgICAgICAgIHRoaXMuc2V0X2N1cnNvcl9sb2NhdGlvbihwb3NpdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0X2VkaXRvcl9wb3NpdGlvbl9mcm9tX2luZGV4KFxuICAgICAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgICAgIGluZGV4OiBudW1iZXJcbiAgICApOiBFZGl0b3JQb3NpdGlvbiB7XG4gICAgICAgIGNvbnN0IHN1YnN0ciA9IGNvbnRlbnQuc3Vic3RyKDAsIGluZGV4KTtcblxuICAgICAgICBsZXQgbCA9IDA7XG4gICAgICAgIGxldCBvZmZzZXQgPSAtMTtcbiAgICAgICAgbGV0IHIgPSAtMTtcbiAgICAgICAgZm9yICg7IChyID0gc3Vic3RyLmluZGV4T2YoXCJcXG5cIiwgciArIDEpKSAhPT0gLTE7IGwrKywgb2Zmc2V0ID0gcik7XG4gICAgICAgIG9mZnNldCArPSAxO1xuXG4gICAgICAgIGNvbnN0IGNoID0gY29udGVudC5zdWJzdHIob2Zmc2V0LCBpbmRleCAtIG9mZnNldCkubGVuZ3RoO1xuXG4gICAgICAgIHJldHVybiB7IGxpbmU6IGwsIGNoOiBjaCB9O1xuICAgIH1cblxuICAgIHJlcGxhY2VfYW5kX2dldF9jdXJzb3JfcG9zaXRpb25zKGNvbnRlbnQ6IHN0cmluZyk6IHtcbiAgICAgICAgbmV3X2NvbnRlbnQ/OiBzdHJpbmc7XG4gICAgICAgIHBvc2l0aW9ucz86IEVkaXRvclBvc2l0aW9uW107XG4gICAgfSB7XG4gICAgICAgIGxldCBjdXJzb3JfbWF0Y2hlcyA9IFtdO1xuICAgICAgICBsZXQgbWF0Y2g7XG4gICAgICAgIGNvbnN0IGN1cnNvcl9yZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAgICAgICBcIjwlXFxcXHMqdHAuZmlsZS5jdXJzb3JcXFxcKCg/PG9yZGVyPlswLTldezAsMn0pXFxcXClcXFxccyolPlwiLFxuICAgICAgICAgICAgXCJnXCJcbiAgICAgICAgKTtcblxuICAgICAgICB3aGlsZSAoKG1hdGNoID0gY3Vyc29yX3JlZ2V4LmV4ZWMoY29udGVudCkpICE9IG51bGwpIHtcbiAgICAgICAgICAgIGN1cnNvcl9tYXRjaGVzLnB1c2gobWF0Y2gpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjdXJzb3JfbWF0Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnNvcl9tYXRjaGVzLnNvcnQoKG0xLCBtMikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIE51bWJlcihtMS5ncm91cHNbXCJvcmRlclwiXSkgLSBOdW1iZXIobTIuZ3JvdXBzW1wib3JkZXJcIl0pO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbWF0Y2hfc3RyID0gY3Vyc29yX21hdGNoZXNbMF1bMF07XG5cbiAgICAgICAgY3Vyc29yX21hdGNoZXMgPSBjdXJzb3JfbWF0Y2hlcy5maWx0ZXIoKG0pID0+IHtcbiAgICAgICAgICAgIHJldHVybiBtWzBdID09PSBtYXRjaF9zdHI7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHBvc2l0aW9ucyA9IFtdO1xuICAgICAgICBsZXQgaW5kZXhfb2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBtYXRjaCBvZiBjdXJzb3JfbWF0Y2hlcykge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBtYXRjaC5pbmRleCAtIGluZGV4X29mZnNldDtcbiAgICAgICAgICAgIHBvc2l0aW9ucy5wdXNoKHRoaXMuZ2V0X2VkaXRvcl9wb3NpdGlvbl9mcm9tX2luZGV4KGNvbnRlbnQsIGluZGV4KSk7XG5cbiAgICAgICAgICAgIGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2UobmV3IFJlZ0V4cChlc2NhcGVfUmVnRXhwKG1hdGNoWzBdKSksIFwiXCIpO1xuICAgICAgICAgICAgaW5kZXhfb2Zmc2V0ICs9IG1hdGNoWzBdLmxlbmd0aDtcblxuICAgICAgICAgICAgLy8gRm9yIHRwLmZpbGUuY3Vyc29yKCksIHdlIGtlZXAgdGhlIGRlZmF1bHQgdG9wIHRvIGJvdHRvbVxuICAgICAgICAgICAgaWYgKG1hdGNoWzFdID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBuZXdfY29udGVudDogY29udGVudCwgcG9zaXRpb25zOiBwb3NpdGlvbnMgfTtcbiAgICB9XG5cbiAgICBzZXRfY3Vyc29yX2xvY2F0aW9uKHBvc2l0aW9uczogRWRpdG9yUG9zaXRpb25bXSk6IHZvaWQge1xuICAgICAgICBjb25zdCBhY3RpdmVfdmlldyA9XG4gICAgICAgICAgICB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpO1xuICAgICAgICBpZiAoIWFjdGl2ZV92aWV3KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBlZGl0b3IgPSBhY3RpdmVfdmlldy5lZGl0b3I7XG4gICAgICAgIGVkaXRvci5mb2N1cygpO1xuXG4gICAgICAgIGNvbnN0IHNlbGVjdGlvbnM6IEFycmF5PEVkaXRvclJhbmdlT3JDYXJldD4gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBwb3Mgb2YgcG9zaXRpb25zKSB7XG4gICAgICAgICAgICBzZWxlY3Rpb25zLnB1c2goeyBmcm9tOiBwb3MgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0cmFuc2FjdGlvbjogRWRpdG9yVHJhbnNhY3Rpb24gPSB7XG4gICAgICAgICAgICBzZWxlY3Rpb25zOiBzZWxlY3Rpb25zLFxuICAgICAgICB9O1xuICAgICAgICBlZGl0b3IudHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IEFwcCB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IGRvY3VtZW50YXRpb24gZnJvbSBcIi4uLy4uL2RvY3MvZG9jdW1lbnRhdGlvbi50b21sXCI7IFxuXG5jb25zdCBtb2R1bGVfbmFtZXMgPSBbXCJjb25maWdcIiwgXCJkYXRlXCIsIFwiZmlsZVwiLCBcImZyb250bWF0dGVyXCIsIFwib2JzaWRpYW5cIiwgXCJzeXN0ZW1cIiwgXCJ1c2VyXCIsIFwid2ViXCJdIGFzIGNvbnN0O1xuZXhwb3J0IHR5cGUgTW9kdWxlTmFtZSA9IHR5cGVvZiBtb2R1bGVfbmFtZXNbbnVtYmVyXTtcbmNvbnN0IG1vZHVsZV9uYW1lc19jaGVja2VyOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQobW9kdWxlX25hbWVzKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzX21vZHVsZV9uYW1lKHg6IHVua25vd24pOiB4IGlzIE1vZHVsZU5hbWUge1xuICAgIHJldHVybiB0eXBlb2YgeCA9PT0gXCJzdHJpbmdcIiAmJiBtb2R1bGVfbmFtZXNfY2hlY2tlci5oYXMoeCk7XG59XG5cbmV4cG9ydCB0eXBlIFRwRG9jdW1lbnRhdGlvbiA9IHsgXG4gICAgXCJ0cFwiOiB7XG4gICAgICAgIFtrZXkgaW4gTW9kdWxlTmFtZV06IFRwTW9kdWxlRG9jdW1lbnRhdGlvblxuICAgIH1cbn07XG5cbmV4cG9ydCB0eXBlIFRwTW9kdWxlRG9jdW1lbnRhdGlvbiA9IHtcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgZGVzY3JpcHRpb246IHN0cmluZyxcbiAgICBmdW5jdGlvbnM6IHtcbiAgICAgICAgW2tleTogc3RyaW5nXTogVHBGdW5jdGlvbkRvY3VtZW50YXRpb25cbiAgICB9XG59O1xuXG5leHBvcnQgdHlwZSBUcEZ1bmN0aW9uRG9jdW1lbnRhdGlvbiA9IHtcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgZGVmaW5pdGlvbjogc3RyaW5nLFxuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmcsXG4gICAgZXhhbXBsZTogc3RyaW5nLFxuICAgIGFyZ3M/OiB7XG4gICAgICAgIFtrZXk6IHN0cmluZ106IFRwQXJndW1lbnREb2N1bWVudGF0aW9uXG4gICAgfSxcbn07XG5cbmV4cG9ydCB0eXBlIFRwQXJndW1lbnREb2N1bWVudGF0aW9uID0ge1xuICAgIG5hbWU6IHN0cmluZyxcbiAgICBkZXNjcmlwdGlvbjogc3RyaW5nLFxufTtcblxuZXhwb3J0IHR5cGUgVHBTdWdnZXN0RG9jdW1lbnRhdGlvbiA9XG4gICAgfCBUcE1vZHVsZURvY3VtZW50YXRpb25cbiAgICB8IFRwRnVuY3Rpb25Eb2N1bWVudGF0aW9uO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNfZnVuY3Rpb25fZG9jdW1lbnRhdGlvbih4OiBUcFN1Z2dlc3REb2N1bWVudGF0aW9uKTogeCBpcyBUcEZ1bmN0aW9uRG9jdW1lbnRhdGlvbiB7XG4gICAgaWYgKCh4IGFzIFRwRnVuY3Rpb25Eb2N1bWVudGF0aW9uKS5kZWZpbml0aW9uKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBjbGFzcyBEb2N1bWVudGF0aW9uIHtcbiAgICBwdWJsaWMgZG9jdW1lbnRhdGlvbjogVHBEb2N1bWVudGF0aW9uID0gZG9jdW1lbnRhdGlvbjtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgYXBwOiBBcHApIHt9XG5cbiAgICBnZXRfYWxsX21vZHVsZXNfZG9jdW1lbnRhdGlvbigpOiBUcE1vZHVsZURvY3VtZW50YXRpb25bXSB7XG4gICAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMuZG9jdW1lbnRhdGlvbi50cCk7XG4gICAgfVxuXG4gICAgZ2V0X2FsbF9mdW5jdGlvbnNfZG9jdW1lbnRhdGlvbihtb2R1bGVfbmFtZTogTW9kdWxlTmFtZSk6IFRwRnVuY3Rpb25Eb2N1bWVudGF0aW9uW10ge1xuICAgICAgICBpZiAoIXRoaXMuZG9jdW1lbnRhdGlvbi50cFttb2R1bGVfbmFtZV0uZnVuY3Rpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0aGlzLmRvY3VtZW50YXRpb24udHBbbW9kdWxlX25hbWVdLmZ1bmN0aW9ucyk7XG4gICAgfVxuXG4gICAgZ2V0X21vZHVsZV9kb2N1bWVudGF0aW9uKG1vZHVsZV9uYW1lOiBNb2R1bGVOYW1lKTogVHBNb2R1bGVEb2N1bWVudGF0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnRhdGlvbi50cFttb2R1bGVfbmFtZV07XG4gICAgfVxuXG4gICAgZ2V0X2Z1bmN0aW9uX2RvY3VtZW50YXRpb24obW9kdWxlX25hbWU6IE1vZHVsZU5hbWUsIGZ1bmN0aW9uX25hbWU6IHN0cmluZyk6IFRwRnVuY3Rpb25Eb2N1bWVudGF0aW9uIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLmRvY3VtZW50YXRpb24udHBbbW9kdWxlX25hbWVdLmZ1bmN0aW9uc1tmdW5jdGlvbl9uYW1lXTtcbiAgICB9XG5cbiAgICBnZXRfYXJndW1lbnRfZG9jdW1lbnRhdGlvbihtb2R1bGVfbmFtZTogTW9kdWxlTmFtZSwgZnVuY3Rpb25fbmFtZTogc3RyaW5nLCBhcmd1bWVudF9uYW1lOiBzdHJpbmcpOiBUcEFyZ3VtZW50RG9jdW1lbnRhdGlvbiB8IG51bGwge1xuICAgICAgICBjb25zdCBmdW5jdGlvbl9kb2MgPSB0aGlzLmdldF9mdW5jdGlvbl9kb2N1bWVudGF0aW9uKG1vZHVsZV9uYW1lLCBmdW5jdGlvbl9uYW1lKTtcbiAgICAgICAgaWYgKCFmdW5jdGlvbl9kb2MgfHwgIWZ1bmN0aW9uX2RvYy5hcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVuY3Rpb25fZG9jLmFyZ3NbYXJndW1lbnRfbmFtZV07XG4gICAgfVxufVxuIiwiaW1wb3J0IHtcbiAgICBBcHAsXG4gICAgRWRpdG9yU3VnZ2VzdCxcbiAgICBFZGl0b3JTdWdnZXN0Q29udGV4dCxcbiAgICBFZGl0b3JTdWdnZXN0VHJpZ2dlckluZm8sXG4gICAgRWRpdG9yUG9zaXRpb24sXG4gICAgRWRpdG9yLFxuICAgIE1hcmtkb3duVmlldyxcbiAgICBURmlsZSxcbn0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmltcG9ydCBUZW1wbGF0ZXJQbHVnaW4gZnJvbSBcIm1haW5cIjtcbmltcG9ydCB7XG4gICAgaXNfZnVuY3Rpb25fZG9jdW1lbnRhdGlvbixcbiAgICBpc19tb2R1bGVfbmFtZSxcbiAgICBNb2R1bGVOYW1lLFxuICAgIFRwU3VnZ2VzdERvY3VtZW50YXRpb24sXG59IGZyb20gXCJmdW5jdGlvbnMvVHBEb2N1bWVudGF0aW9uXCI7XG5cbmV4cG9ydCBjbGFzcyBBdXRvY29tcGxldGUgZXh0ZW5kcyBFZGl0b3JTdWdnZXN0PFRwU3VnZ2VzdERvY3VtZW50YXRpb24+IHtcbiAgICAvL3ByaXZhdGUgaW5fY29tbWFuZCA9IGZhbHNlO1xuICAgIC8vIGh0dHBzOi8vcmVnZXgxMDEuY29tL3Ivb2NtSHpSLzFcbiAgICBwcml2YXRlIHRwX2tleXdvcmRfcmVnZXggPVxuICAgICAgICAvdHBcXC4oPzxtb2R1bGU+W2Etel0qKT8oPzxmbl90cmlnZ2VyPlxcLig/PGZuPlthLXpfXSopPyk/JC87XG4gICAgcHJpdmF0ZSBsYXRlc3RfdHJpZ2dlcl9pbmZvOiBFZGl0b3JTdWdnZXN0VHJpZ2dlckluZm87XG4gICAgcHJpdmF0ZSBtb2R1bGVfbmFtZTogTW9kdWxlTmFtZSB8IHN0cmluZztcbiAgICBwcml2YXRlIGZ1bmN0aW9uX3RyaWdnZXI6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBmdW5jdGlvbl9uYW1lOiBzdHJpbmc7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFwcDogQXBwLCBwcml2YXRlIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luKSB7XG4gICAgICAgIHN1cGVyKGFwcCk7XG4gICAgfVxuXG4gICAgb25UcmlnZ2VyKFxuICAgICAgICBjdXJzb3I6IEVkaXRvclBvc2l0aW9uLFxuICAgICAgICBlZGl0b3I6IEVkaXRvcixcbiAgICAgICAgZmlsZTogVEZpbGVcbiAgICApOiBFZGl0b3JTdWdnZXN0VHJpZ2dlckluZm8gfCBudWxsIHtcbiAgICAgICAgY29uc3QgcmFuZ2UgPSBlZGl0b3IuZ2V0UmFuZ2UoXG4gICAgICAgICAgICB7IGxpbmU6IGN1cnNvci5saW5lLCBjaDogMCB9LFxuICAgICAgICAgICAgeyBsaW5lOiBjdXJzb3IubGluZSwgY2g6IGN1cnNvci5jaCB9XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdGhpcy50cF9rZXl3b3JkX3JlZ2V4LmV4ZWMocmFuZ2UpO1xuICAgICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBxdWVyeTogc3RyaW5nO1xuICAgICAgICBjb25zdCBtb2R1bGVfbmFtZSA9IG1hdGNoLmdyb3Vwc1tcIm1vZHVsZVwiXSB8fCBcIlwiO1xuICAgICAgICB0aGlzLm1vZHVsZV9uYW1lID0gbW9kdWxlX25hbWU7XG5cbiAgICAgICAgaWYgKG1hdGNoLmdyb3Vwc1tcImZuX3RyaWdnZXJcIl0pIHtcbiAgICAgICAgICAgIGlmIChtb2R1bGVfbmFtZSA9PSBcIlwiIHx8ICFpc19tb2R1bGVfbmFtZShtb2R1bGVfbmFtZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmZ1bmN0aW9uX3RyaWdnZXIgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5mdW5jdGlvbl9uYW1lID0gbWF0Y2guZ3JvdXBzW1wiZm5cIl0gfHwgXCJcIjtcbiAgICAgICAgICAgIHF1ZXJ5ID0gdGhpcy5mdW5jdGlvbl9uYW1lO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mdW5jdGlvbl90cmlnZ2VyID0gZmFsc2U7XG4gICAgICAgICAgICBxdWVyeSA9IHRoaXMubW9kdWxlX25hbWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0cmlnZ2VyX2luZm86IEVkaXRvclN1Z2dlc3RUcmlnZ2VySW5mbyA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiB7IGxpbmU6IGN1cnNvci5saW5lLCBjaDogY3Vyc29yLmNoIC0gcXVlcnkubGVuZ3RoIH0sXG4gICAgICAgICAgICBlbmQ6IHsgbGluZTogY3Vyc29yLmxpbmUsIGNoOiBjdXJzb3IuY2ggfSxcbiAgICAgICAgICAgIHF1ZXJ5OiBxdWVyeSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5sYXRlc3RfdHJpZ2dlcl9pbmZvID0gdHJpZ2dlcl9pbmZvO1xuICAgICAgICByZXR1cm4gdHJpZ2dlcl9pbmZvO1xuICAgIH1cblxuICAgIGdldFN1Z2dlc3Rpb25zKFxuICAgICAgICBjb250ZXh0OiBFZGl0b3JTdWdnZXN0Q29udGV4dFxuICAgICk6IEFycmF5PFRwU3VnZ2VzdERvY3VtZW50YXRpb24+IHtcbiAgICAgICAgbGV0IHN1Z2dlc3Rpb25zOiBBcnJheTxUcFN1Z2dlc3REb2N1bWVudGF0aW9uPjtcbiAgICAgICAgaWYgKHRoaXMubW9kdWxlX25hbWUgJiYgdGhpcy5mdW5jdGlvbl90cmlnZ2VyKSB7XG4gICAgICAgICAgICBzdWdnZXN0aW9ucyA9XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4udGVtcGxhdGVyLmRvY3VtZW50YXRpb24uZ2V0X2FsbF9mdW5jdGlvbnNfZG9jdW1lbnRhdGlvbihcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2R1bGVfbmFtZSBhcyBNb2R1bGVOYW1lXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN1Z2dlc3Rpb25zID1cbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi50ZW1wbGF0ZXIuZG9jdW1lbnRhdGlvbi5nZXRfYWxsX21vZHVsZXNfZG9jdW1lbnRhdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghc3VnZ2VzdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VnZ2VzdGlvbnMuZmlsdGVyKHMgPT4gcy5uYW1lLnN0YXJ0c1dpdGgoY29udGV4dC5xdWVyeSkpO1xuICAgIH1cblxuICAgIHJlbmRlclN1Z2dlc3Rpb24odmFsdWU6IFRwU3VnZ2VzdERvY3VtZW50YXRpb24sIGVsOiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgICAgICBlbC5jcmVhdGVFbChcImJcIiwgeyB0ZXh0OiB2YWx1ZS5uYW1lIH0pO1xuICAgICAgICBlbC5jcmVhdGVFbChcImJyXCIpO1xuICAgICAgICBpZiAodGhpcy5mdW5jdGlvbl90cmlnZ2VyICYmIGlzX2Z1bmN0aW9uX2RvY3VtZW50YXRpb24odmFsdWUpKSB7XG4gICAgICAgICAgICBlbC5jcmVhdGVFbChcImNvZGVcIiwgeyB0ZXh0OiB2YWx1ZS5kZWZpbml0aW9uIH0pOyBcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgIGVsLmNyZWF0ZUVsKFwiZGl2XCIsIHsgdGV4dDogdmFsdWUuZGVzY3JpcHRpb24gfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxlY3RTdWdnZXN0aW9uKFxuICAgICAgICB2YWx1ZTogVHBTdWdnZXN0RG9jdW1lbnRhdGlvbixcbiAgICAgICAgZXZ0OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudFxuICAgICk6IHZvaWQge1xuICAgICAgICBjb25zdCBhY3RpdmVfdmlldyA9XG4gICAgICAgICAgICB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpO1xuICAgICAgICBpZiAoIWFjdGl2ZV92aWV3KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBFcnJvciBtc2dcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBhY3RpdmVfdmlldy5lZGl0b3IucmVwbGFjZVJhbmdlKFxuICAgICAgICAgICAgdmFsdWUubmFtZSxcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0X3RyaWdnZXJfaW5mby5zdGFydCxcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0X3RyaWdnZXJfaW5mby5lbmRcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHRoaXMubGF0ZXN0X3RyaWdnZXJfaW5mby5zdGFydC5jaCA9PSB0aGlzLmxhdGVzdF90cmlnZ2VyX2luZm8uZW5kLmNoKSB7XG4gICAgICAgICAgICAvLyBEaXJ0eSBoYWNrIHRvIHByZXZlbnQgdGhlIGN1cnNvciBiZWluZyBhdCB0aGVcbiAgICAgICAgICAgIC8vIGJlZ2lubmluZyBvZiB0aGUgd29yZCBhZnRlciBjb21wbGV0aW9uLCBcbiAgICAgICAgICAgIC8vIE5vdCBzdXJlIHdoYXQncyB0aGUgY2F1c2Ugb2YgdGhpcyBidWcuXG4gICAgICAgICAgICBjb25zdCBjdXJzb3JfcG9zID0gdGhpcy5sYXRlc3RfdHJpZ2dlcl9pbmZvLmVuZDtcbiAgICAgICAgICAgIGN1cnNvcl9wb3MuY2ggKz0gdmFsdWUubmFtZS5sZW5ndGg7XG4gICAgICAgICAgICBhY3RpdmVfdmlldy5lZGl0b3Iuc2V0Q3Vyc29yKGN1cnNvcl9wb3MpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwczovL2NvZGVtaXJyb3IubmV0L0xJQ0VOU0VcblxuLyogZXNsaW50LWRpc2FibGUgKi9cblxuKGZ1bmN0aW9uIChtb2QpIHtcbiAgICBtb2Qod2luZG93LkNvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24gKENvZGVNaXJyb3IpIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIENvZGVNaXJyb3IuZGVmaW5lTW9kZShcImphdmFzY3JpcHRcIiwgZnVuY3Rpb24gKGNvbmZpZywgcGFyc2VyQ29uZmlnKSB7XG4gICAgICAgIHZhciBpbmRlbnRVbml0ID0gY29uZmlnLmluZGVudFVuaXQ7XG4gICAgICAgIHZhciBzdGF0ZW1lbnRJbmRlbnQgPSBwYXJzZXJDb25maWcuc3RhdGVtZW50SW5kZW50O1xuICAgICAgICB2YXIganNvbmxkTW9kZSA9IHBhcnNlckNvbmZpZy5qc29ubGQ7XG4gICAgICAgIHZhciBqc29uTW9kZSA9IHBhcnNlckNvbmZpZy5qc29uIHx8IGpzb25sZE1vZGU7XG4gICAgICAgIHZhciB0cmFja1Njb3BlID0gcGFyc2VyQ29uZmlnLnRyYWNrU2NvcGUgIT09IGZhbHNlO1xuICAgICAgICB2YXIgaXNUUyA9IHBhcnNlckNvbmZpZy50eXBlc2NyaXB0O1xuICAgICAgICB2YXIgd29yZFJFID0gcGFyc2VyQ29uZmlnLndvcmRDaGFyYWN0ZXJzIHx8IC9bXFx3JFxceGExLVxcdWZmZmZdLztcblxuICAgICAgICAvLyBUb2tlbml6ZXJcblxuICAgICAgICB2YXIga2V5d29yZHMgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZnVuY3Rpb24ga3codHlwZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHR5cGU6IHR5cGUsIHN0eWxlOiBcImtleXdvcmRcIiB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIEEgPSBrdyhcImtleXdvcmQgYVwiKSxcbiAgICAgICAgICAgICAgICBCID0ga3coXCJrZXl3b3JkIGJcIiksXG4gICAgICAgICAgICAgICAgQyA9IGt3KFwia2V5d29yZCBjXCIpLFxuICAgICAgICAgICAgICAgIEQgPSBrdyhcImtleXdvcmQgZFwiKTtcbiAgICAgICAgICAgIHZhciBvcGVyYXRvciA9IGt3KFwib3BlcmF0b3JcIiksXG4gICAgICAgICAgICAgICAgYXRvbSA9IHsgdHlwZTogXCJhdG9tXCIsIHN0eWxlOiBcImF0b21cIiB9O1xuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGlmOiBrdyhcImlmXCIpLFxuICAgICAgICAgICAgICAgIHdoaWxlOiBBLFxuICAgICAgICAgICAgICAgIHdpdGg6IEEsXG4gICAgICAgICAgICAgICAgZWxzZTogQixcbiAgICAgICAgICAgICAgICBkbzogQixcbiAgICAgICAgICAgICAgICB0cnk6IEIsXG4gICAgICAgICAgICAgICAgZmluYWxseTogQixcbiAgICAgICAgICAgICAgICByZXR1cm46IEQsXG4gICAgICAgICAgICAgICAgYnJlYWs6IEQsXG4gICAgICAgICAgICAgICAgY29udGludWU6IEQsXG4gICAgICAgICAgICAgICAgbmV3OiBrdyhcIm5ld1wiKSxcbiAgICAgICAgICAgICAgICBkZWxldGU6IEMsXG4gICAgICAgICAgICAgICAgdm9pZDogQyxcbiAgICAgICAgICAgICAgICB0aHJvdzogQyxcbiAgICAgICAgICAgICAgICBkZWJ1Z2dlcjoga3coXCJkZWJ1Z2dlclwiKSxcbiAgICAgICAgICAgICAgICB2YXI6IGt3KFwidmFyXCIpLFxuICAgICAgICAgICAgICAgIGNvbnN0OiBrdyhcInZhclwiKSxcbiAgICAgICAgICAgICAgICBsZXQ6IGt3KFwidmFyXCIpLFxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uOiBrdyhcImZ1bmN0aW9uXCIpLFxuICAgICAgICAgICAgICAgIGNhdGNoOiBrdyhcImNhdGNoXCIpLFxuICAgICAgICAgICAgICAgIGZvcjoga3coXCJmb3JcIiksXG4gICAgICAgICAgICAgICAgc3dpdGNoOiBrdyhcInN3aXRjaFwiKSxcbiAgICAgICAgICAgICAgICBjYXNlOiBrdyhcImNhc2VcIiksXG4gICAgICAgICAgICAgICAgZGVmYXVsdDoga3coXCJkZWZhdWx0XCIpLFxuICAgICAgICAgICAgICAgIGluOiBvcGVyYXRvcixcbiAgICAgICAgICAgICAgICB0eXBlb2Y6IG9wZXJhdG9yLFxuICAgICAgICAgICAgICAgIGluc3RhbmNlb2Y6IG9wZXJhdG9yLFxuICAgICAgICAgICAgICAgIHRydWU6IGF0b20sXG4gICAgICAgICAgICAgICAgZmFsc2U6IGF0b20sXG4gICAgICAgICAgICAgICAgbnVsbDogYXRvbSxcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQ6IGF0b20sXG4gICAgICAgICAgICAgICAgTmFOOiBhdG9tLFxuICAgICAgICAgICAgICAgIEluZmluaXR5OiBhdG9tLFxuICAgICAgICAgICAgICAgIHRoaXM6IGt3KFwidGhpc1wiKSxcbiAgICAgICAgICAgICAgICBjbGFzczoga3coXCJjbGFzc1wiKSxcbiAgICAgICAgICAgICAgICBzdXBlcjoga3coXCJhdG9tXCIpLFxuICAgICAgICAgICAgICAgIHlpZWxkOiBDLFxuICAgICAgICAgICAgICAgIGV4cG9ydDoga3coXCJleHBvcnRcIiksXG4gICAgICAgICAgICAgICAgaW1wb3J0OiBrdyhcImltcG9ydFwiKSxcbiAgICAgICAgICAgICAgICBleHRlbmRzOiBDLFxuICAgICAgICAgICAgICAgIGF3YWl0OiBDLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkoKTtcblxuICAgICAgICB2YXIgaXNPcGVyYXRvckNoYXIgPSAvWytcXC0qJiU9PD4hP3x+XkBdLztcbiAgICAgICAgdmFyIGlzSnNvbmxkS2V5d29yZCA9XG4gICAgICAgICAgICAvXkAoY29udGV4dHxpZHx2YWx1ZXxsYW5ndWFnZXx0eXBlfGNvbnRhaW5lcnxsaXN0fHNldHxyZXZlcnNlfGluZGV4fGJhc2V8dm9jYWJ8Z3JhcGgpXCIvO1xuXG4gICAgICAgIGZ1bmN0aW9uIHJlYWRSZWdleHAoc3RyZWFtKSB7XG4gICAgICAgICAgICB2YXIgZXNjYXBlZCA9IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICAgICAgaW5TZXQgPSBmYWxzZTtcbiAgICAgICAgICAgIHdoaWxlICgobmV4dCA9IHN0cmVhbS5uZXh0KCkpICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWVzY2FwZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgPT0gXCIvXCIgJiYgIWluU2V0KSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0ID09IFwiW1wiKSBpblNldCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGluU2V0ICYmIG5leHQgPT0gXCJdXCIpIGluU2V0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVzY2FwZWQgPSAhZXNjYXBlZCAmJiBuZXh0ID09IFwiXFxcXFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXNlZCBhcyBzY3JhdGNoIHZhcmlhYmxlcyB0byBjb21tdW5pY2F0ZSBtdWx0aXBsZSB2YWx1ZXMgd2l0aG91dFxuICAgICAgICAvLyBjb25zaW5nIHVwIHRvbnMgb2Ygb2JqZWN0cy5cbiAgICAgICAgdmFyIHR5cGUsIGNvbnRlbnQ7XG4gICAgICAgIGZ1bmN0aW9uIHJldCh0cCwgc3R5bGUsIGNvbnQpIHtcbiAgICAgICAgICAgIHR5cGUgPSB0cDtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBjb250O1xuICAgICAgICAgICAgcmV0dXJuIHN0eWxlO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHRva2VuQmFzZShzdHJlYW0sIHN0YXRlKSB7XG4gICAgICAgICAgICB2YXIgY2ggPSBzdHJlYW0ubmV4dCgpO1xuICAgICAgICAgICAgaWYgKGNoID09ICdcIicgfHwgY2ggPT0gXCInXCIpIHtcbiAgICAgICAgICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IHRva2VuU3RyaW5nKGNoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGUudG9rZW5pemUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIGNoID09IFwiLlwiICYmXG4gICAgICAgICAgICAgICAgc3RyZWFtLm1hdGNoKC9eXFxkW1xcZF9dKig/OltlRV1bK1xcLV0/W1xcZF9dKyk/LylcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXQoXCJudW1iZXJcIiwgXCJudW1iZXJcIik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09IFwiLlwiICYmIHN0cmVhbS5tYXRjaChcIi4uXCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldChcInNwcmVhZFwiLCBcIm1ldGFcIik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKC9bXFxbXFxde31cXChcXCksO1xcOlxcLl0vLnRlc3QoY2gpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldChjaCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09IFwiPVwiICYmIHN0cmVhbS5lYXQoXCI+XCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldChcIj0+XCIsIFwib3BlcmF0b3JcIik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIGNoID09IFwiMFwiICYmXG4gICAgICAgICAgICAgICAgc3RyZWFtLm1hdGNoKC9eKD86eFtcXGRBLUZhLWZfXSt8b1swLTdfXSt8YlswMV9dKyluPy8pXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0KFwibnVtYmVyXCIsIFwibnVtYmVyXCIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgvXFxkLy50ZXN0KGNoKSkge1xuICAgICAgICAgICAgICAgIHN0cmVhbS5tYXRjaChcbiAgICAgICAgICAgICAgICAgICAgL15bXFxkX10qKD86bnwoPzpcXC5bXFxkX10qKT8oPzpbZUVdWytcXC1dP1tcXGRfXSspPyk/L1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldChcIm51bWJlclwiLCBcIm51bWJlclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gXCIvXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoc3RyZWFtLmVhdChcIipcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUudG9rZW5pemUgPSB0b2tlbkNvbW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0b2tlbkNvbW1lbnQoc3RyZWFtLCBzdGF0ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJlYW0uZWF0KFwiL1wiKSkge1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW0uc2tpcFRvRW5kKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQoXCJjb21tZW50XCIsIFwiY29tbWVudFwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4cHJlc3Npb25BbGxvd2VkKHN0cmVhbSwgc3RhdGUsIDEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlYWRSZWdleHAoc3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtLm1hdGNoKC9eXFxiKChbZ2lteXVzXSkoPyFbZ2lteXVzXSpcXDIpKStcXGIvKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldChcInJlZ2V4cFwiLCBcInN0cmluZy0yXCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5lYXQoXCI9XCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0KFwib3BlcmF0b3JcIiwgXCJvcGVyYXRvclwiLCBzdHJlYW0uY3VycmVudCgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09IFwiYFwiKSB7XG4gICAgICAgICAgICAgICAgc3RhdGUudG9rZW5pemUgPSB0b2tlblF1YXNpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0b2tlblF1YXNpKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSBcIiNcIiAmJiBzdHJlYW0ucGVlaygpID09IFwiIVwiKSB7XG4gICAgICAgICAgICAgICAgc3RyZWFtLnNraXBUb0VuZCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXQoXCJtZXRhXCIsIFwibWV0YVwiKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gXCIjXCIgJiYgc3RyZWFtLmVhdFdoaWxlKHdvcmRSRSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0KFwidmFyaWFibGVcIiwgXCJwcm9wZXJ0eVwiKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgKGNoID09IFwiPFwiICYmIHN0cmVhbS5tYXRjaChcIiEtLVwiKSkgfHxcbiAgICAgICAgICAgICAgICAoY2ggPT0gXCItXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtLm1hdGNoKFwiLT5cIikgJiZcbiAgICAgICAgICAgICAgICAgICAgIS9cXFMvLnRlc3Qoc3RyZWFtLnN0cmluZy5zbGljZSgwLCBzdHJlYW0uc3RhcnQpKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHN0cmVhbS5za2lwVG9FbmQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0KFwiY29tbWVudFwiLCBcImNvbW1lbnRcIik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzT3BlcmF0b3JDaGFyLnRlc3QoY2gpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNoICE9IFwiPlwiIHx8ICFzdGF0ZS5sZXhpY2FsIHx8IHN0YXRlLmxleGljYWwudHlwZSAhPSBcIj5cIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RyZWFtLmVhdChcIj1cIikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSBcIiFcIiB8fCBjaCA9PSBcIj1cIikgc3RyZWFtLmVhdChcIj1cIik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoL1s8PiorXFwtfCY/XS8udGVzdChjaCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5lYXQoY2gpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09IFwiPlwiKSBzdHJlYW0uZWF0KGNoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoY2ggPT0gXCI/XCIgJiYgc3RyZWFtLmVhdChcIi5cIikpIHJldHVybiByZXQoXCIuXCIpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXQoXCJvcGVyYXRvclwiLCBcIm9wZXJhdG9yXCIsIHN0cmVhbS5jdXJyZW50KCkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh3b3JkUkUudGVzdChjaCkpIHtcbiAgICAgICAgICAgICAgICBzdHJlYW0uZWF0V2hpbGUod29yZFJFKTtcbiAgICAgICAgICAgICAgICB2YXIgd29yZCA9IHN0cmVhbS5jdXJyZW50KCk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLmxhc3RUeXBlICE9IFwiLlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXl3b3Jkcy5wcm9wZXJ0eUlzRW51bWVyYWJsZSh3b3JkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGt3ID0ga2V5d29yZHNbd29yZF07XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0KGt3LnR5cGUsIGt3LnN0eWxlLCB3b3JkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICB3b3JkID09IFwiYXN5bmNcIiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLm1hdGNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC9eKFxcc3xcXC9cXCooW14qXXxcXCooPyFcXC8pKSo/XFwqXFwvKSpbXFxbXFwoXFx3XS8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldChcImFzeW5jXCIsIFwia2V5d29yZFwiLCB3b3JkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldChcInZhcmlhYmxlXCIsIFwidmFyaWFibGVcIiwgd29yZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiB0b2tlblN0cmluZyhxdW90ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzdHJlYW0sIHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVzY2FwZWQgPSBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbmV4dDtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIGpzb25sZE1vZGUgJiZcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnBlZWsoKSA9PSBcIkBcIiAmJlxuICAgICAgICAgICAgICAgICAgICBzdHJlYW0ubWF0Y2goaXNKc29ubGRLZXl3b3JkKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IHRva2VuQmFzZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldChcImpzb25sZC1rZXl3b3JkXCIsIFwibWV0YVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd2hpbGUgKChuZXh0ID0gc3RyZWFtLm5leHQoKSkgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCA9PSBxdW90ZSAmJiAhZXNjYXBlZCkgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGVzY2FwZWQgPSAhZXNjYXBlZCAmJiBuZXh0ID09IFwiXFxcXFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWVzY2FwZWQpIHN0YXRlLnRva2VuaXplID0gdG9rZW5CYXNlO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXQoXCJzdHJpbmdcIiwgXCJzdHJpbmdcIik7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gdG9rZW5Db21tZW50KHN0cmVhbSwgc3RhdGUpIHtcbiAgICAgICAgICAgIHZhciBtYXliZUVuZCA9IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNoO1xuICAgICAgICAgICAgd2hpbGUgKChjaCA9IHN0cmVhbS5uZXh0KCkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNoID09IFwiL1wiICYmIG1heWJlRW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLnRva2VuaXplID0gdG9rZW5CYXNlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbWF5YmVFbmQgPSBjaCA9PSBcIipcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXQoXCJjb21tZW50XCIsIFwiY29tbWVudFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHRva2VuUXVhc2koc3RyZWFtLCBzdGF0ZSkge1xuICAgICAgICAgICAgdmFyIGVzY2FwZWQgPSBmYWxzZSxcbiAgICAgICAgICAgICAgICBuZXh0O1xuICAgICAgICAgICAgd2hpbGUgKChuZXh0ID0gc3RyZWFtLm5leHQoKSkgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgIWVzY2FwZWQgJiZcbiAgICAgICAgICAgICAgICAgICAgKG5leHQgPT0gXCJgXCIgfHwgKG5leHQgPT0gXCIkXCIgJiYgc3RyZWFtLmVhdChcIntcIikpKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IHRva2VuQmFzZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVzY2FwZWQgPSAhZXNjYXBlZCAmJiBuZXh0ID09IFwiXFxcXFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldChcInF1YXNpXCIsIFwic3RyaW5nLTJcIiwgc3RyZWFtLmN1cnJlbnQoKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgYnJhY2tldHMgPSBcIihbe31dKVwiO1xuICAgICAgICAvLyBUaGlzIGlzIGEgY3J1ZGUgbG9va2FoZWFkIHRyaWNrIHRvIHRyeSBhbmQgbm90aWNlIHRoYXQgd2UncmVcbiAgICAgICAgLy8gcGFyc2luZyB0aGUgYXJndW1lbnQgcGF0dGVybnMgZm9yIGEgZmF0LWFycm93IGZ1bmN0aW9uIGJlZm9yZSB3ZVxuICAgICAgICAvLyBhY3R1YWxseSBoaXQgdGhlIGFycm93IHRva2VuLiBJdCBvbmx5IHdvcmtzIGlmIHRoZSBhcnJvdyBpcyBvblxuICAgICAgICAvLyB0aGUgc2FtZSBsaW5lIGFzIHRoZSBhcmd1bWVudHMgYW5kIHRoZXJlJ3Mgbm8gc3RyYW5nZSBub2lzZVxuICAgICAgICAvLyAoY29tbWVudHMpIGluIGJldHdlZW4uIEZhbGxiYWNrIGlzIHRvIG9ubHkgbm90aWNlIHdoZW4gd2UgaGl0IHRoZVxuICAgICAgICAvLyBhcnJvdywgYW5kIG5vdCBkZWNsYXJlIHRoZSBhcmd1bWVudHMgYXMgbG9jYWxzIGZvciB0aGUgYXJyb3dcbiAgICAgICAgLy8gYm9keS5cbiAgICAgICAgZnVuY3Rpb24gZmluZEZhdEFycm93KHN0cmVhbSwgc3RhdGUpIHtcbiAgICAgICAgICAgIGlmIChzdGF0ZS5mYXRBcnJvd0F0KSBzdGF0ZS5mYXRBcnJvd0F0ID0gbnVsbDtcbiAgICAgICAgICAgIHZhciBhcnJvdyA9IHN0cmVhbS5zdHJpbmcuaW5kZXhPZihcIj0+XCIsIHN0cmVhbS5zdGFydCk7XG4gICAgICAgICAgICBpZiAoYXJyb3cgPCAwKSByZXR1cm47XG5cbiAgICAgICAgICAgIGlmIChpc1RTKSB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IHRvIHNraXAgVHlwZVNjcmlwdCByZXR1cm4gdHlwZSBkZWNsYXJhdGlvbnMgYWZ0ZXIgdGhlIGFyZ3VtZW50c1xuICAgICAgICAgICAgICAgIHZhciBtID0gLzpcXHMqKD86XFx3Kyg/OjxbXj5dKj58XFxbXFxdKT98XFx7W159XSpcXH0pXFxzKiQvLmV4ZWMoXG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJpbmcuc2xpY2Uoc3RyZWFtLnN0YXJ0LCBhcnJvdylcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGlmIChtKSBhcnJvdyA9IG0uaW5kZXg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBkZXB0aCA9IDAsXG4gICAgICAgICAgICAgICAgc2F3U29tZXRoaW5nID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKHZhciBwb3MgPSBhcnJvdyAtIDE7IHBvcyA+PSAwOyAtLXBvcykge1xuICAgICAgICAgICAgICAgIHZhciBjaCA9IHN0cmVhbS5zdHJpbmcuY2hhckF0KHBvcyk7XG4gICAgICAgICAgICAgICAgdmFyIGJyYWNrZXQgPSBicmFja2V0cy5pbmRleE9mKGNoKTtcbiAgICAgICAgICAgICAgICBpZiAoYnJhY2tldCA+PSAwICYmIGJyYWNrZXQgPCAzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZGVwdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICsrcG9zO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKC0tZGVwdGggPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09IFwiKFwiKSBzYXdTb21ldGhpbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJyYWNrZXQgPj0gMyAmJiBicmFja2V0IDwgNikge1xuICAgICAgICAgICAgICAgICAgICArK2RlcHRoO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod29yZFJFLnRlc3QoY2gpKSB7XG4gICAgICAgICAgICAgICAgICAgIHNhd1NvbWV0aGluZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICgvW1wiJ1xcL2BdLy50ZXN0KGNoKSkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgOyAtLXBvcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAwKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dCA9IHN0cmVhbS5zdHJpbmcuY2hhckF0KHBvcyAtIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPT0gY2ggJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uc3RyaW5nLmNoYXJBdChwb3MgLSAyKSAhPSBcIlxcXFxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zLS07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNhd1NvbWV0aGluZyAmJiAhZGVwdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgKytwb3M7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzYXdTb21ldGhpbmcgJiYgIWRlcHRoKSBzdGF0ZS5mYXRBcnJvd0F0ID0gcG9zO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUGFyc2VyXG5cbiAgICAgICAgdmFyIGF0b21pY1R5cGVzID0ge1xuICAgICAgICAgICAgYXRvbTogdHJ1ZSxcbiAgICAgICAgICAgIG51bWJlcjogdHJ1ZSxcbiAgICAgICAgICAgIHZhcmlhYmxlOiB0cnVlLFxuICAgICAgICAgICAgc3RyaW5nOiB0cnVlLFxuICAgICAgICAgICAgcmVnZXhwOiB0cnVlLFxuICAgICAgICAgICAgdGhpczogdHJ1ZSxcbiAgICAgICAgICAgIGltcG9ydDogdHJ1ZSxcbiAgICAgICAgICAgIFwianNvbmxkLWtleXdvcmRcIjogdHJ1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICBmdW5jdGlvbiBKU0xleGljYWwoaW5kZW50ZWQsIGNvbHVtbiwgdHlwZSwgYWxpZ24sIHByZXYsIGluZm8pIHtcbiAgICAgICAgICAgIHRoaXMuaW5kZW50ZWQgPSBpbmRlbnRlZDtcbiAgICAgICAgICAgIHRoaXMuY29sdW1uID0gY29sdW1uO1xuICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgICAgIHRoaXMucHJldiA9IHByZXY7XG4gICAgICAgICAgICB0aGlzLmluZm8gPSBpbmZvO1xuICAgICAgICAgICAgaWYgKGFsaWduICE9IG51bGwpIHRoaXMuYWxpZ24gPSBhbGlnbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGluU2NvcGUoc3RhdGUsIHZhcm5hbWUpIHtcbiAgICAgICAgICAgIGlmICghdHJhY2tTY29wZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgZm9yICh2YXIgdiA9IHN0YXRlLmxvY2FsVmFyczsgdjsgdiA9IHYubmV4dClcbiAgICAgICAgICAgICAgICBpZiAodi5uYW1lID09IHZhcm5hbWUpIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgZm9yICh2YXIgY3ggPSBzdGF0ZS5jb250ZXh0OyBjeDsgY3ggPSBjeC5wcmV2KSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgdiA9IGN4LnZhcnM7IHY7IHYgPSB2Lm5leHQpXG4gICAgICAgICAgICAgICAgICAgIGlmICh2Lm5hbWUgPT0gdmFybmFtZSkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBwYXJzZUpTKHN0YXRlLCBzdHlsZSwgdHlwZSwgY29udGVudCwgc3RyZWFtKSB7XG4gICAgICAgICAgICB2YXIgY2MgPSBzdGF0ZS5jYztcbiAgICAgICAgICAgIC8vIENvbW11bmljYXRlIG91ciBjb250ZXh0IHRvIHRoZSBjb21iaW5hdG9ycy5cbiAgICAgICAgICAgIC8vIChMZXNzIHdhc3RlZnVsIHRoYW4gY29uc2luZyB1cCBhIGh1bmRyZWQgY2xvc3VyZXMgb24gZXZlcnkgY2FsbC4pXG4gICAgICAgICAgICBjeC5zdGF0ZSA9IHN0YXRlO1xuICAgICAgICAgICAgY3guc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICAgICAgKGN4Lm1hcmtlZCA9IG51bGwpLCAoY3guY2MgPSBjYyk7XG4gICAgICAgICAgICBjeC5zdHlsZSA9IHN0eWxlO1xuXG4gICAgICAgICAgICBpZiAoIXN0YXRlLmxleGljYWwuaGFzT3duUHJvcGVydHkoXCJhbGlnblwiKSlcbiAgICAgICAgICAgICAgICBzdGF0ZS5sZXhpY2FsLmFsaWduID0gdHJ1ZTtcblxuICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICB2YXIgY29tYmluYXRvciA9IGNjLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICA/IGNjLnBvcCgpXG4gICAgICAgICAgICAgICAgICAgIDoganNvbk1vZGVcbiAgICAgICAgICAgICAgICAgICAgPyBleHByZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgIDogc3RhdGVtZW50O1xuICAgICAgICAgICAgICAgIGlmIChjb21iaW5hdG9yKHR5cGUsIGNvbnRlbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChjYy5sZW5ndGggJiYgY2NbY2MubGVuZ3RoIC0gMV0ubGV4KSBjYy5wb3AoKSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3gubWFya2VkKSByZXR1cm4gY3gubWFya2VkO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBcInZhcmlhYmxlXCIgJiYgaW5TY29wZShzdGF0ZSwgY29udGVudCkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ2YXJpYWJsZS0yXCI7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHlsZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb21iaW5hdG9yIHV0aWxzXG5cbiAgICAgICAgdmFyIGN4ID0geyBzdGF0ZTogbnVsbCwgY29sdW1uOiBudWxsLCBtYXJrZWQ6IG51bGwsIGNjOiBudWxsIH07XG4gICAgICAgIGZ1bmN0aW9uIHBhc3MoKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gYXJndW1lbnRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgICAgICAgICAgIGN4LmNjLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBjb250KCkge1xuICAgICAgICAgICAgcGFzcy5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaW5MaXN0KG5hbWUsIGxpc3QpIHtcbiAgICAgICAgICAgIGZvciAodmFyIHYgPSBsaXN0OyB2OyB2ID0gdi5uZXh0KSBpZiAodi5uYW1lID09IG5hbWUpIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHJlZ2lzdGVyKHZhcm5hbWUpIHtcbiAgICAgICAgICAgIHZhciBzdGF0ZSA9IGN4LnN0YXRlO1xuICAgICAgICAgICAgY3gubWFya2VkID0gXCJkZWZcIjtcbiAgICAgICAgICAgIGlmICghdHJhY2tTY29wZSkgcmV0dXJuO1xuICAgICAgICAgICAgaWYgKHN0YXRlLmNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmxleGljYWwuaW5mbyA9PSBcInZhclwiICYmXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmNvbnRleHQgJiZcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUuY29udGV4dC5ibG9ja1xuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAvLyBGSVhNRSBmdW5jdGlvbiBkZWNscyBhcmUgYWxzbyBub3QgYmxvY2sgc2NvcGVkXG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXdDb250ZXh0ID0gcmVnaXN0ZXJWYXJTY29wZWQodmFybmFtZSwgc3RhdGUuY29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXdDb250ZXh0ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLmNvbnRleHQgPSBuZXdDb250ZXh0O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaW5MaXN0KHZhcm5hbWUsIHN0YXRlLmxvY2FsVmFycykpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUubG9jYWxWYXJzID0gbmV3IFZhcih2YXJuYW1lLCBzdGF0ZS5sb2NhbFZhcnMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRmFsbCB0aHJvdWdoIG1lYW5zIHRoaXMgaXMgZ2xvYmFsXG4gICAgICAgICAgICBpZiAocGFyc2VyQ29uZmlnLmdsb2JhbFZhcnMgJiYgIWluTGlzdCh2YXJuYW1lLCBzdGF0ZS5nbG9iYWxWYXJzKSlcbiAgICAgICAgICAgICAgICBzdGF0ZS5nbG9iYWxWYXJzID0gbmV3IFZhcih2YXJuYW1lLCBzdGF0ZS5nbG9iYWxWYXJzKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiByZWdpc3RlclZhclNjb3BlZCh2YXJuYW1lLCBjb250ZXh0KSB7XG4gICAgICAgICAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5ibG9jaykge1xuICAgICAgICAgICAgICAgIHZhciBpbm5lciA9IHJlZ2lzdGVyVmFyU2NvcGVkKHZhcm5hbWUsIGNvbnRleHQucHJldik7XG4gICAgICAgICAgICAgICAgaWYgKCFpbm5lcikgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKGlubmVyID09IGNvbnRleHQucHJldikgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb250ZXh0KGlubmVyLCBjb250ZXh0LnZhcnMsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpbkxpc3QodmFybmFtZSwgY29udGV4dC52YXJzKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbnRleHQoXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQucHJldixcbiAgICAgICAgICAgICAgICAgICAgbmV3IFZhcih2YXJuYW1lLCBjb250ZXh0LnZhcnMpLFxuICAgICAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpc01vZGlmaWVyKG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgbmFtZSA9PSBcInB1YmxpY1wiIHx8XG4gICAgICAgICAgICAgICAgbmFtZSA9PSBcInByaXZhdGVcIiB8fFxuICAgICAgICAgICAgICAgIG5hbWUgPT0gXCJwcm90ZWN0ZWRcIiB8fFxuICAgICAgICAgICAgICAgIG5hbWUgPT0gXCJhYnN0cmFjdFwiIHx8XG4gICAgICAgICAgICAgICAgbmFtZSA9PSBcInJlYWRvbmx5XCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb21iaW5hdG9yc1xuXG4gICAgICAgIGZ1bmN0aW9uIENvbnRleHQocHJldiwgdmFycywgYmxvY2spIHtcbiAgICAgICAgICAgIHRoaXMucHJldiA9IHByZXY7XG4gICAgICAgICAgICB0aGlzLnZhcnMgPSB2YXJzO1xuICAgICAgICAgICAgdGhpcy5ibG9jayA9IGJsb2NrO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIFZhcihuYW1lLCBuZXh0KSB7XG4gICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICAgICAgdGhpcy5uZXh0ID0gbmV4dDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkZWZhdWx0VmFycyA9IG5ldyBWYXIoXCJ0aGlzXCIsIG5ldyBWYXIoXCJhcmd1bWVudHNcIiwgbnVsbCkpO1xuICAgICAgICBmdW5jdGlvbiBwdXNoY29udGV4dCgpIHtcbiAgICAgICAgICAgIGN4LnN0YXRlLmNvbnRleHQgPSBuZXcgQ29udGV4dChcbiAgICAgICAgICAgICAgICBjeC5zdGF0ZS5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGN4LnN0YXRlLmxvY2FsVmFycyxcbiAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGN4LnN0YXRlLmxvY2FsVmFycyA9IGRlZmF1bHRWYXJzO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHB1c2hibG9ja2NvbnRleHQoKSB7XG4gICAgICAgICAgICBjeC5zdGF0ZS5jb250ZXh0ID0gbmV3IENvbnRleHQoXG4gICAgICAgICAgICAgICAgY3guc3RhdGUuY29udGV4dCxcbiAgICAgICAgICAgICAgICBjeC5zdGF0ZS5sb2NhbFZhcnMsXG4gICAgICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGN4LnN0YXRlLmxvY2FsVmFycyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gcG9wY29udGV4dCgpIHtcbiAgICAgICAgICAgIGN4LnN0YXRlLmxvY2FsVmFycyA9IGN4LnN0YXRlLmNvbnRleHQudmFycztcbiAgICAgICAgICAgIGN4LnN0YXRlLmNvbnRleHQgPSBjeC5zdGF0ZS5jb250ZXh0LnByZXY7XG4gICAgICAgIH1cbiAgICAgICAgcG9wY29udGV4dC5sZXggPSB0cnVlO1xuICAgICAgICBmdW5jdGlvbiBwdXNobGV4KHR5cGUsIGluZm8pIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0YXRlID0gY3guc3RhdGUsXG4gICAgICAgICAgICAgICAgICAgIGluZGVudCA9IHN0YXRlLmluZGVudGVkO1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5sZXhpY2FsLnR5cGUgPT0gXCJzdGF0XCIpXG4gICAgICAgICAgICAgICAgICAgIGluZGVudCA9IHN0YXRlLmxleGljYWwuaW5kZW50ZWQ7XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBmb3IgKFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG91dGVyID0gc3RhdGUubGV4aWNhbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dGVyICYmIG91dGVyLnR5cGUgPT0gXCIpXCIgJiYgb3V0ZXIuYWxpZ247XG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRlciA9IG91dGVyLnByZXZcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZW50ID0gb3V0ZXIuaW5kZW50ZWQ7XG4gICAgICAgICAgICAgICAgc3RhdGUubGV4aWNhbCA9IG5ldyBKU0xleGljYWwoXG4gICAgICAgICAgICAgICAgICAgIGluZGVudCxcbiAgICAgICAgICAgICAgICAgICAgY3guc3RyZWFtLmNvbHVtbigpLFxuICAgICAgICAgICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5sZXhpY2FsLFxuICAgICAgICAgICAgICAgICAgICBpbmZvXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXN1bHQubGV4ID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gcG9wbGV4KCkge1xuICAgICAgICAgICAgdmFyIHN0YXRlID0gY3guc3RhdGU7XG4gICAgICAgICAgICBpZiAoc3RhdGUubGV4aWNhbC5wcmV2KSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLmxleGljYWwudHlwZSA9PSBcIilcIilcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUuaW5kZW50ZWQgPSBzdGF0ZS5sZXhpY2FsLmluZGVudGVkO1xuICAgICAgICAgICAgICAgIHN0YXRlLmxleGljYWwgPSBzdGF0ZS5sZXhpY2FsLnByZXY7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcG9wbGV4LmxleCA9IHRydWU7XG5cbiAgICAgICAgZnVuY3Rpb24gZXhwZWN0KHdhbnRlZCkge1xuICAgICAgICAgICAgZnVuY3Rpb24gZXhwKHR5cGUpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSB3YW50ZWQpIHJldHVybiBjb250KCk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHdhbnRlZCA9PSBcIjtcIiB8fFxuICAgICAgICAgICAgICAgICAgICB0eXBlID09IFwifVwiIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgPT0gXCIpXCIgfHxcbiAgICAgICAgICAgICAgICAgICAgdHlwZSA9PSBcIl1cIlxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhc3MoKTtcbiAgICAgICAgICAgICAgICBlbHNlIHJldHVybiBjb250KGV4cCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZXhwO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gc3RhdGVtZW50KHR5cGUsIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInZhclwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBwdXNobGV4KFwidmFyZGVmXCIsIHZhbHVlKSxcbiAgICAgICAgICAgICAgICAgICAgdmFyZGVmLFxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoXCI7XCIpLFxuICAgICAgICAgICAgICAgICAgICBwb3BsZXhcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJrZXl3b3JkIGFcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChwdXNobGV4KFwiZm9ybVwiKSwgcGFyZW5FeHByLCBzdGF0ZW1lbnQsIHBvcGxleCk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcImtleXdvcmQgYlwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KHB1c2hsZXgoXCJmb3JtXCIpLCBzdGF0ZW1lbnQsIHBvcGxleCk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcImtleXdvcmQgZFwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjeC5zdHJlYW0ubWF0Y2goL15cXHMqJC8sIGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICA/IGNvbnQoKVxuICAgICAgICAgICAgICAgICAgICA6IGNvbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hsZXgoXCJzdGF0XCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBtYXliZWV4cHJlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdChcIjtcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBvcGxleFxuICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcImRlYnVnZ2VyXCIpIHJldHVybiBjb250KGV4cGVjdChcIjtcIikpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ7XCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoXG4gICAgICAgICAgICAgICAgICAgIHB1c2hsZXgoXCJ9XCIpLFxuICAgICAgICAgICAgICAgICAgICBwdXNoYmxvY2tjb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICBibG9jayxcbiAgICAgICAgICAgICAgICAgICAgcG9wbGV4LFxuICAgICAgICAgICAgICAgICAgICBwb3Bjb250ZXh0XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiO1wiKSByZXR1cm4gY29udCgpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJpZlwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBjeC5zdGF0ZS5sZXhpY2FsLmluZm8gPT0gXCJlbHNlXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgY3guc3RhdGUuY2NbY3guc3RhdGUuY2MubGVuZ3RoIC0gMV0gPT0gcG9wbGV4XG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICBjeC5zdGF0ZS5jYy5wb3AoKSgpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBwdXNobGV4KFwiZm9ybVwiKSxcbiAgICAgICAgICAgICAgICAgICAgcGFyZW5FeHByLFxuICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIHBvcGxleCxcbiAgICAgICAgICAgICAgICAgICAgbWF5YmVlbHNlXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiZnVuY3Rpb25cIikgcmV0dXJuIGNvbnQoZnVuY3Rpb25kZWYpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJmb3JcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChcbiAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcImZvcm1cIiksXG4gICAgICAgICAgICAgICAgICAgIHB1c2hibG9ja2NvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIGZvcnNwZWMsXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgcG9wY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgcG9wbGV4XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiY2xhc3NcIiB8fCAoaXNUUyAmJiB2YWx1ZSA9PSBcImludGVyZmFjZVwiKSkge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBwdXNobGV4KFwiZm9ybVwiLCB0eXBlID09IFwiY2xhc3NcIiA/IHR5cGUgOiB2YWx1ZSksXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgcG9wbGV4XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09IFwidmFyaWFibGVcIikge1xuICAgICAgICAgICAgICAgIGlmIChpc1RTICYmIHZhbHVlID09IFwiZGVjbGFyZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udChzdGF0ZW1lbnQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgICAgIGlzVFMgJiZcbiAgICAgICAgICAgICAgICAgICAgKHZhbHVlID09IFwibW9kdWxlXCIgfHwgdmFsdWUgPT0gXCJlbnVtXCIgfHwgdmFsdWUgPT0gXCJ0eXBlXCIpICYmXG4gICAgICAgICAgICAgICAgICAgIGN4LnN0cmVhbS5tYXRjaCgvXlxccypcXHcvLCBmYWxzZSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcImVudW1cIikgcmV0dXJuIGNvbnQoZW51bWRlZik7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09IFwidHlwZVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KFwib3BlcmF0b3JcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZWV4cHIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0KFwiO1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcImZvcm1cIiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoXCJ7XCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hsZXgoXCJ9XCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcGxleCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3BsZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc1RTICYmIHZhbHVlID09IFwibmFtZXNwYWNlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250KHB1c2hsZXgoXCJmb3JtXCIpLCBleHByZXNzaW9uLCBzdGF0ZW1lbnQsIHBvcGxleCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc1RTICYmIHZhbHVlID09IFwiYWJzdHJhY3RcIikge1xuICAgICAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcImtleXdvcmRcIjtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoc3RhdGVtZW50KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udChwdXNobGV4KFwic3RhdFwiKSwgbWF5YmVsYWJlbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJzd2l0Y2hcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChcbiAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcImZvcm1cIiksXG4gICAgICAgICAgICAgICAgICAgIHBhcmVuRXhwcixcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KFwie1wiKSxcbiAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcIn1cIiwgXCJzd2l0Y2hcIiksXG4gICAgICAgICAgICAgICAgICAgIHB1c2hibG9ja2NvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIGJsb2NrLFxuICAgICAgICAgICAgICAgICAgICBwb3BsZXgsXG4gICAgICAgICAgICAgICAgICAgIHBvcGxleCxcbiAgICAgICAgICAgICAgICAgICAgcG9wY29udGV4dFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcImNhc2VcIikgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbiwgZXhwZWN0KFwiOlwiKSk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcImRlZmF1bHRcIikgcmV0dXJuIGNvbnQoZXhwZWN0KFwiOlwiKSk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcImNhdGNoXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoXG4gICAgICAgICAgICAgICAgICAgIHB1c2hsZXgoXCJmb3JtXCIpLFxuICAgICAgICAgICAgICAgICAgICBwdXNoY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgbWF5YmVDYXRjaEJpbmRpbmcsXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgcG9wbGV4LFxuICAgICAgICAgICAgICAgICAgICBwb3Bjb250ZXh0XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiZXhwb3J0XCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQocHVzaGxleChcInN0YXRcIiksIGFmdGVyRXhwb3J0LCBwb3BsZXgpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJpbXBvcnRcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChwdXNobGV4KFwic3RhdFwiKSwgYWZ0ZXJJbXBvcnQsIHBvcGxleCk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcImFzeW5jXCIpIHJldHVybiBjb250KHN0YXRlbWVudCk7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJAXCIpIHJldHVybiBjb250KGV4cHJlc3Npb24sIHN0YXRlbWVudCk7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyhwdXNobGV4KFwic3RhdFwiKSwgZXhwcmVzc2lvbiwgZXhwZWN0KFwiO1wiKSwgcG9wbGV4KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBtYXliZUNhdGNoQmluZGluZyh0eXBlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIihcIikgcmV0dXJuIGNvbnQoZnVuYXJnLCBleHBlY3QoXCIpXCIpKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBleHByZXNzaW9uKHR5cGUsIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gZXhwcmVzc2lvbklubmVyKHR5cGUsIHZhbHVlLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZXhwcmVzc2lvbk5vQ29tbWEodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiBleHByZXNzaW9uSW5uZXIodHlwZSwgdmFsdWUsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHBhcmVuRXhwcih0eXBlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSAhPSBcIihcIikgcmV0dXJuIHBhc3MoKTtcbiAgICAgICAgICAgIHJldHVybiBjb250KHB1c2hsZXgoXCIpXCIpLCBtYXliZWV4cHJlc3Npb24sIGV4cGVjdChcIilcIiksIHBvcGxleCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZXhwcmVzc2lvbklubmVyKHR5cGUsIHZhbHVlLCBub0NvbW1hKSB7XG4gICAgICAgICAgICBpZiAoY3guc3RhdGUuZmF0QXJyb3dBdCA9PSBjeC5zdHJlYW0uc3RhcnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgYm9keSA9IG5vQ29tbWEgPyBhcnJvd0JvZHlOb0NvbW1hIDogYXJyb3dCb2R5O1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09IFwiKFwiKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udChcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hjb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcIilcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICBjb21tYXNlcChmdW5hcmcsIFwiKVwiKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcGxleCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdChcIj0+XCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcGNvbnRleHRcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFwidmFyaWFibGVcIilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhc3MoXG4gICAgICAgICAgICAgICAgICAgICAgICBwdXNoY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4sXG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3QoXCI9PlwiKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3Bjb250ZXh0XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBtYXliZW9wID0gbm9Db21tYSA/IG1heWJlb3BlcmF0b3JOb0NvbW1hIDogbWF5YmVvcGVyYXRvckNvbW1hO1xuICAgICAgICAgICAgaWYgKGF0b21pY1R5cGVzLmhhc093blByb3BlcnR5KHR5cGUpKSByZXR1cm4gY29udChtYXliZW9wKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiZnVuY3Rpb25cIikgcmV0dXJuIGNvbnQoZnVuY3Rpb25kZWYsIG1heWJlb3ApO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJjbGFzc1wiIHx8IChpc1RTICYmIHZhbHVlID09IFwiaW50ZXJmYWNlXCIpKSB7XG4gICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQocHVzaGxleChcImZvcm1cIiksIGNsYXNzRXhwcmVzc2lvbiwgcG9wbGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09IFwia2V5d29yZCBjXCIgfHwgdHlwZSA9PSBcImFzeW5jXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQobm9Db21tYSA/IGV4cHJlc3Npb25Ob0NvbW1hIDogZXhwcmVzc2lvbik7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIihcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChcbiAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcIilcIiksXG4gICAgICAgICAgICAgICAgICAgIG1heWJlZXhwcmVzc2lvbixcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KFwiKVwiKSxcbiAgICAgICAgICAgICAgICAgICAgcG9wbGV4LFxuICAgICAgICAgICAgICAgICAgICBtYXliZW9wXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwib3BlcmF0b3JcIiB8fCB0eXBlID09IFwic3ByZWFkXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQobm9Db21tYSA/IGV4cHJlc3Npb25Ob0NvbW1hIDogZXhwcmVzc2lvbik7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIltcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChwdXNobGV4KFwiXVwiKSwgYXJyYXlMaXRlcmFsLCBwb3BsZXgsIG1heWJlb3ApO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ7XCIpIHJldHVybiBjb250Q29tbWFzZXAob2JqcHJvcCwgXCJ9XCIsIG51bGwsIG1heWJlb3ApO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJxdWFzaVwiKSByZXR1cm4gcGFzcyhxdWFzaSwgbWF5YmVvcCk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIm5ld1wiKSByZXR1cm4gY29udChtYXliZVRhcmdldChub0NvbW1hKSk7XG4gICAgICAgICAgICByZXR1cm4gY29udCgpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG1heWJlZXhwcmVzc2lvbih0eXBlKSB7XG4gICAgICAgICAgICBpZiAodHlwZS5tYXRjaCgvWztcXH1cXClcXF0sXS8pKSByZXR1cm4gcGFzcygpO1xuICAgICAgICAgICAgcmV0dXJuIHBhc3MoZXhwcmVzc2lvbik7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBtYXliZW9wZXJhdG9yQ29tbWEodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiLFwiKSByZXR1cm4gY29udChtYXliZWV4cHJlc3Npb24pO1xuICAgICAgICAgICAgcmV0dXJuIG1heWJlb3BlcmF0b3JOb0NvbW1hKHR5cGUsIHZhbHVlLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbWF5YmVvcGVyYXRvck5vQ29tbWEodHlwZSwgdmFsdWUsIG5vQ29tbWEpIHtcbiAgICAgICAgICAgIHZhciBtZSA9XG4gICAgICAgICAgICAgICAgbm9Db21tYSA9PSBmYWxzZSA/IG1heWJlb3BlcmF0b3JDb21tYSA6IG1heWJlb3BlcmF0b3JOb0NvbW1hO1xuICAgICAgICAgICAgdmFyIGV4cHIgPSBub0NvbW1hID09IGZhbHNlID8gZXhwcmVzc2lvbiA6IGV4cHJlc3Npb25Ob0NvbW1hO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCI9PlwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBwdXNoY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgbm9Db21tYSA/IGFycm93Qm9keU5vQ29tbWEgOiBhcnJvd0JvZHksXG4gICAgICAgICAgICAgICAgICAgIHBvcGNvbnRleHRcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJvcGVyYXRvclwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKC9cXCtcXCt8LS0vLnRlc3QodmFsdWUpIHx8IChpc1RTICYmIHZhbHVlID09IFwiIVwiKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQobWUpO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgaXNUUyAmJlxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9PSBcIjxcIiAmJlxuICAgICAgICAgICAgICAgICAgICBjeC5zdHJlYW0ubWF0Y2goL14oW148Pl18PFtePD5dKj4pKj5cXHMqXFwoLywgZmFsc2UpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udChcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hsZXgoXCI+XCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFzZXAodHlwZWV4cHIsIFwiPlwiKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcGxleCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiP1wiKSByZXR1cm4gY29udChleHByZXNzaW9uLCBleHBlY3QoXCI6XCIpLCBleHByKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChleHByKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09IFwicXVhc2lcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXNzKHF1YXNpLCBtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIjtcIikgcmV0dXJuO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCIoXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRDb21tYXNlcChleHByZXNzaW9uTm9Db21tYSwgXCIpXCIsIFwiY2FsbFwiLCBtZSk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIi5cIikgcmV0dXJuIGNvbnQocHJvcGVydHksIG1lKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiW1wiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBwdXNobGV4KFwiXVwiKSxcbiAgICAgICAgICAgICAgICAgICAgbWF5YmVleHByZXNzaW9uLFxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoXCJdXCIpLFxuICAgICAgICAgICAgICAgICAgICBwb3BsZXgsXG4gICAgICAgICAgICAgICAgICAgIG1lXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChpc1RTICYmIHZhbHVlID09IFwiYXNcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KHR5cGVleHByLCBtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInJlZ2V4cFwiKSB7XG4gICAgICAgICAgICAgICAgY3guc3RhdGUubGFzdFR5cGUgPSBjeC5tYXJrZWQgPSBcIm9wZXJhdG9yXCI7XG4gICAgICAgICAgICAgICAgY3guc3RyZWFtLmJhY2tVcChjeC5zdHJlYW0ucG9zIC0gY3guc3RyZWFtLnN0YXJ0IC0gMSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoZXhwcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gcXVhc2kodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh0eXBlICE9IFwicXVhc2lcIikgcmV0dXJuIHBhc3MoKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZS5zbGljZSh2YWx1ZS5sZW5ndGggLSAyKSAhPSBcIiR7XCIpIHJldHVybiBjb250KHF1YXNpKTtcbiAgICAgICAgICAgIHJldHVybiBjb250KG1heWJlZXhwcmVzc2lvbiwgY29udGludWVRdWFzaSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY29udGludWVRdWFzaSh0eXBlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIn1cIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwic3RyaW5nLTJcIjtcbiAgICAgICAgICAgICAgICBjeC5zdGF0ZS50b2tlbml6ZSA9IHRva2VuUXVhc2k7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQocXVhc2kpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGFycm93Qm9keSh0eXBlKSB7XG4gICAgICAgICAgICBmaW5kRmF0QXJyb3coY3guc3RyZWFtLCBjeC5zdGF0ZSk7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyh0eXBlID09IFwie1wiID8gc3RhdGVtZW50IDogZXhwcmVzc2lvbik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gYXJyb3dCb2R5Tm9Db21tYSh0eXBlKSB7XG4gICAgICAgICAgICBmaW5kRmF0QXJyb3coY3guc3RyZWFtLCBjeC5zdGF0ZSk7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyh0eXBlID09IFwie1wiID8gc3RhdGVtZW50IDogZXhwcmVzc2lvbk5vQ29tbWEpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG1heWJlVGFyZ2V0KG5vQ29tbWEpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAodHlwZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09IFwiLlwiKSByZXR1cm4gY29udChub0NvbW1hID8gdGFyZ2V0Tm9Db21tYSA6IHRhcmdldCk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBcInZhcmlhYmxlXCIgJiYgaXNUUylcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXliZVR5cGVBcmdzLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm9Db21tYSA/IG1heWJlb3BlcmF0b3JOb0NvbW1hIDogbWF5YmVvcGVyYXRvckNvbW1hXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgZWxzZSByZXR1cm4gcGFzcyhub0NvbW1hID8gZXhwcmVzc2lvbk5vQ29tbWEgOiBleHByZXNzaW9uKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gdGFyZ2V0KF8sIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJ0YXJnZXRcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KG1heWJlb3BlcmF0b3JDb21tYSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gdGFyZ2V0Tm9Db21tYShfLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwidGFyZ2V0XCIpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcImtleXdvcmRcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChtYXliZW9wZXJhdG9yTm9Db21tYSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbWF5YmVsYWJlbCh0eXBlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIjpcIikgcmV0dXJuIGNvbnQocG9wbGV4LCBzdGF0ZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuIHBhc3MobWF5YmVvcGVyYXRvckNvbW1hLCBleHBlY3QoXCI7XCIpLCBwb3BsZXgpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHByb3BlcnR5KHR5cGUpIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwidmFyaWFibGVcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwicHJvcGVydHlcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9ianByb3AodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiYXN5bmNcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwicHJvcGVydHlcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChvYmpwcm9wKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBcInZhcmlhYmxlXCIgfHwgY3guc3R5bGUgPT0gXCJrZXl3b3JkXCIpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcInByb3BlcnR5XCI7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiZ2V0XCIgfHwgdmFsdWUgPT0gXCJzZXRcIikgcmV0dXJuIGNvbnQoZ2V0dGVyU2V0dGVyKTtcbiAgICAgICAgICAgICAgICB2YXIgbTsgLy8gV29yayBhcm91bmQgZmF0LWFycm93LWRldGVjdGlvbiBjb21wbGljYXRpb24gZm9yIGRldGVjdGluZyB0eXBlc2NyaXB0IHR5cGVkIGFycm93IHBhcmFtc1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgaXNUUyAmJlxuICAgICAgICAgICAgICAgICAgICBjeC5zdGF0ZS5mYXRBcnJvd0F0ID09IGN4LnN0cmVhbS5zdGFydCAmJlxuICAgICAgICAgICAgICAgICAgICAobSA9IGN4LnN0cmVhbS5tYXRjaCgvXlxccyo6XFxzKi8sIGZhbHNlKSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIGN4LnN0YXRlLmZhdEFycm93QXQgPSBjeC5zdHJlYW0ucG9zICsgbVswXS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoYWZ0ZXJwcm9wKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBcIm51bWJlclwiIHx8IHR5cGUgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IGpzb25sZE1vZGUgPyBcInByb3BlcnR5XCIgOiBjeC5zdHlsZSArIFwiIHByb3BlcnR5XCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoYWZ0ZXJwcm9wKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBcImpzb25sZC1rZXl3b3JkXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChhZnRlcnByb3ApO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc1RTICYmIGlzTW9kaWZpZXIodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQob2JqcHJvcCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gXCJbXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChleHByZXNzaW9uLCBtYXliZXR5cGUsIGV4cGVjdChcIl1cIiksIGFmdGVycHJvcCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gXCJzcHJlYWRcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KGV4cHJlc3Npb25Ob0NvbW1hLCBhZnRlcnByb3ApO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSBcIipcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KG9ianByb3ApO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IFwiOlwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhc3MoYWZ0ZXJwcm9wKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBnZXR0ZXJTZXR0ZXIodHlwZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgIT0gXCJ2YXJpYWJsZVwiKSByZXR1cm4gcGFzcyhhZnRlcnByb3ApO1xuICAgICAgICAgICAgY3gubWFya2VkID0gXCJwcm9wZXJ0eVwiO1xuICAgICAgICAgICAgcmV0dXJuIGNvbnQoZnVuY3Rpb25kZWYpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGFmdGVycHJvcCh0eXBlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIjpcIikgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbk5vQ29tbWEpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCIoXCIpIHJldHVybiBwYXNzKGZ1bmN0aW9uZGVmKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBjb21tYXNlcCh3aGF0LCBlbmQsIHNlcCkge1xuICAgICAgICAgICAgZnVuY3Rpb24gcHJvY2VlZCh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChzZXAgPyBzZXAuaW5kZXhPZih0eXBlKSA+IC0xIDogdHlwZSA9PSBcIixcIikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbGV4ID0gY3guc3RhdGUubGV4aWNhbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxleC5pbmZvID09IFwiY2FsbFwiKSBsZXgucG9zID0gKGxleC5wb3MgfHwgMCkgKyAxO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udChmdW5jdGlvbiAodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09IGVuZCB8fCB2YWx1ZSA9PSBlbmQpIHJldHVybiBwYXNzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFzcyh3aGF0KTtcbiAgICAgICAgICAgICAgICAgICAgfSwgcHJvY2VlZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0eXBlID09IGVuZCB8fCB2YWx1ZSA9PSBlbmQpIHJldHVybiBjb250KCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlcCAmJiBzZXAuaW5kZXhPZihcIjtcIikgPiAtMSkgcmV0dXJuIHBhc3Mod2hhdCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoZXhwZWN0KGVuZCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09IGVuZCB8fCB2YWx1ZSA9PSBlbmQpIHJldHVybiBjb250KCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhc3Mod2hhdCwgcHJvY2VlZCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGNvbnRDb21tYXNlcCh3aGF0LCBlbmQsIGluZm8pIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAzOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSBjeC5jYy5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gICAgICAgICAgICByZXR1cm4gY29udChwdXNobGV4KGVuZCwgaW5mbyksIGNvbW1hc2VwKHdoYXQsIGVuZCksIHBvcGxleCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gYmxvY2sodHlwZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ9XCIpIHJldHVybiBjb250KCk7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyhzdGF0ZW1lbnQsIGJsb2NrKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBtYXliZXR5cGUodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmIChpc1RTKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCI6XCIpIHJldHVybiBjb250KHR5cGVleHByKTtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCI/XCIpIHJldHVybiBjb250KG1heWJldHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbWF5YmV0eXBlT3JJbih0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGlzVFMgJiYgKHR5cGUgPT0gXCI6XCIgfHwgdmFsdWUgPT0gXCJpblwiKSkgcmV0dXJuIGNvbnQodHlwZWV4cHIpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG1heWJlcmV0dHlwZSh0eXBlKSB7XG4gICAgICAgICAgICBpZiAoaXNUUyAmJiB0eXBlID09IFwiOlwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGN4LnN0cmVhbS5tYXRjaCgvXlxccypcXHcrXFxzK2lzXFxiLywgZmFsc2UpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udChleHByZXNzaW9uLCBpc0tXLCB0eXBlZXhwcik7XG4gICAgICAgICAgICAgICAgZWxzZSByZXR1cm4gY29udCh0eXBlZXhwcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNLVyhfLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiaXNcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gdHlwZWV4cHIodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB2YWx1ZSA9PSBcImtleW9mXCIgfHxcbiAgICAgICAgICAgICAgICB2YWx1ZSA9PSBcInR5cGVvZlwiIHx8XG4gICAgICAgICAgICAgICAgdmFsdWUgPT0gXCJpbmZlclwiIHx8XG4gICAgICAgICAgICAgICAgdmFsdWUgPT0gXCJyZWFkb25seVwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcImtleXdvcmRcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udCh2YWx1ZSA9PSBcInR5cGVvZlwiID8gZXhwcmVzc2lvbk5vQ29tbWEgOiB0eXBlZXhwcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInZhcmlhYmxlXCIgfHwgdmFsdWUgPT0gXCJ2b2lkXCIpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcInR5cGVcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChhZnRlclR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwifFwiIHx8IHZhbHVlID09IFwiJlwiKSByZXR1cm4gY29udCh0eXBlZXhwcik7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInN0cmluZ1wiIHx8IHR5cGUgPT0gXCJudW1iZXJcIiB8fCB0eXBlID09IFwiYXRvbVwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KGFmdGVyVHlwZSk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIltcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChcbiAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcIl1cIiksXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hc2VwKHR5cGVleHByLCBcIl1cIiwgXCIsXCIpLFxuICAgICAgICAgICAgICAgICAgICBwb3BsZXgsXG4gICAgICAgICAgICAgICAgICAgIGFmdGVyVHlwZVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIntcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChwdXNobGV4KFwifVwiKSwgdHlwZXByb3BzLCBwb3BsZXgsIGFmdGVyVHlwZSk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIihcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChjb21tYXNlcCh0eXBlYXJnLCBcIilcIiksIG1heWJlUmV0dXJuVHlwZSwgYWZ0ZXJUeXBlKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiPFwiKSByZXR1cm4gY29udChjb21tYXNlcCh0eXBlZXhwciwgXCI+XCIpLCB0eXBlZXhwcik7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInF1YXNpXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFzcyhxdWFzaVR5cGUsIGFmdGVyVHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbWF5YmVSZXR1cm5UeXBlKHR5cGUpIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiPT5cIikgcmV0dXJuIGNvbnQodHlwZWV4cHIpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHR5cGVwcm9wcyh0eXBlKSB7XG4gICAgICAgICAgICBpZiAodHlwZS5tYXRjaCgvW1xcfVxcKVxcXV0vKSkgcmV0dXJuIGNvbnQoKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiLFwiIHx8IHR5cGUgPT0gXCI7XCIpIHJldHVybiBjb250KHR5cGVwcm9wcyk7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyh0eXBlcHJvcCwgdHlwZXByb3BzKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiB0eXBlcHJvcCh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ2YXJpYWJsZVwiIHx8IGN4LnN0eWxlID09IFwia2V5d29yZFwiKSB7XG4gICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJwcm9wZXJ0eVwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KHR5cGVwcm9wKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gXCI/XCIgfHwgdHlwZSA9PSBcIm51bWJlclwiIHx8IHR5cGUgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KHR5cGVwcm9wKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBcIjpcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KHR5cGVleHByKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBcIltcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBleHBlY3QoXCJ2YXJpYWJsZVwiKSxcbiAgICAgICAgICAgICAgICAgICAgbWF5YmV0eXBlT3JJbixcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KFwiXVwiKSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZXByb3BcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09IFwiKFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhc3MoZnVuY3Rpb25kZWNsLCB0eXBlcHJvcCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCF0eXBlLm1hdGNoKC9bO1xcfVxcKVxcXSxdLykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHF1YXNpVHlwZSh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgIT0gXCJxdWFzaVwiKSByZXR1cm4gcGFzcygpO1xuICAgICAgICAgICAgaWYgKHZhbHVlLnNsaWNlKHZhbHVlLmxlbmd0aCAtIDIpICE9IFwiJHtcIikgcmV0dXJuIGNvbnQocXVhc2lUeXBlKTtcbiAgICAgICAgICAgIHJldHVybiBjb250KHR5cGVleHByLCBjb250aW51ZVF1YXNpVHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY29udGludWVRdWFzaVR5cGUodHlwZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ9XCIpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcInN0cmluZy0yXCI7XG4gICAgICAgICAgICAgICAgY3guc3RhdGUudG9rZW5pemUgPSB0b2tlblF1YXNpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KHF1YXNpVHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gdHlwZWFyZyh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICh0eXBlID09IFwidmFyaWFibGVcIiAmJiBjeC5zdHJlYW0ubWF0Y2goL15cXHMqWz86XS8sIGZhbHNlKSkgfHxcbiAgICAgICAgICAgICAgICB2YWx1ZSA9PSBcIj9cIlxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KHR5cGVhcmcpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCI6XCIpIHJldHVybiBjb250KHR5cGVleHByKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwic3ByZWFkXCIpIHJldHVybiBjb250KHR5cGVhcmcpO1xuICAgICAgICAgICAgcmV0dXJuIHBhc3ModHlwZWV4cHIpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGFmdGVyVHlwZSh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiPFwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBwdXNobGV4KFwiPlwiKSxcbiAgICAgICAgICAgICAgICAgICAgY29tbWFzZXAodHlwZWV4cHIsIFwiPlwiKSxcbiAgICAgICAgICAgICAgICAgICAgcG9wbGV4LFxuICAgICAgICAgICAgICAgICAgICBhZnRlclR5cGVcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwifFwiIHx8IHR5cGUgPT0gXCIuXCIgfHwgdmFsdWUgPT0gXCImXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQodHlwZWV4cHIpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJbXCIpIHJldHVybiBjb250KHR5cGVleHByLCBleHBlY3QoXCJdXCIpLCBhZnRlclR5cGUpO1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiZXh0ZW5kc1wiIHx8IHZhbHVlID09IFwiaW1wbGVtZW50c1wiKSB7XG4gICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQodHlwZWV4cHIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiP1wiKSByZXR1cm4gY29udCh0eXBlZXhwciwgZXhwZWN0KFwiOlwiKSwgdHlwZWV4cHIpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG1heWJlVHlwZUFyZ3MoXywgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIjxcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChcbiAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcIj5cIiksXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hc2VwKHR5cGVleHByLCBcIj5cIiksXG4gICAgICAgICAgICAgICAgICAgIHBvcGxleCxcbiAgICAgICAgICAgICAgICAgICAgYWZ0ZXJUeXBlXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiB0eXBlcGFyYW0oKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyh0eXBlZXhwciwgbWF5YmVUeXBlRGVmYXVsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbWF5YmVUeXBlRGVmYXVsdChfLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiPVwiKSByZXR1cm4gY29udCh0eXBlZXhwcik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gdmFyZGVmKF8sIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJlbnVtXCIpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcImtleXdvcmRcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChlbnVtZGVmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwYXNzKHBhdHRlcm4sIG1heWJldHlwZSwgbWF5YmVBc3NpZ24sIHZhcmRlZkNvbnQpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHBhdHRlcm4odHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmIChpc1RTICYmIGlzTW9kaWZpZXIodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQocGF0dGVybik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInZhcmlhYmxlXCIpIHtcbiAgICAgICAgICAgICAgICByZWdpc3Rlcih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09IFwic3ByZWFkXCIpIHJldHVybiBjb250KHBhdHRlcm4pO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJbXCIpIHJldHVybiBjb250Q29tbWFzZXAoZWx0cGF0dGVybiwgXCJdXCIpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ7XCIpIHJldHVybiBjb250Q29tbWFzZXAocHJvcHBhdHRlcm4sIFwifVwiKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBwcm9wcGF0dGVybih0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ2YXJpYWJsZVwiICYmICFjeC5zdHJlYW0ubWF0Y2goL15cXHMqOi8sIGZhbHNlKSkge1xuICAgICAgICAgICAgICAgIHJlZ2lzdGVyKHZhbHVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChtYXliZUFzc2lnbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInZhcmlhYmxlXCIpIGN4Lm1hcmtlZCA9IFwicHJvcGVydHlcIjtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwic3ByZWFkXCIpIHJldHVybiBjb250KHBhdHRlcm4pO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ9XCIpIHJldHVybiBwYXNzKCk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIltcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChleHByZXNzaW9uLCBleHBlY3QoXCJdXCIpLCBleHBlY3QoXCI6XCIpLCBwcm9wcGF0dGVybik7XG4gICAgICAgICAgICByZXR1cm4gY29udChleHBlY3QoXCI6XCIpLCBwYXR0ZXJuLCBtYXliZUFzc2lnbik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZWx0cGF0dGVybigpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXNzKHBhdHRlcm4sIG1heWJlQXNzaWduKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBtYXliZUFzc2lnbihfdHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIj1cIikgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbk5vQ29tbWEpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHZhcmRlZkNvbnQodHlwZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCIsXCIpIHJldHVybiBjb250KHZhcmRlZik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbWF5YmVlbHNlKHR5cGUsIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcImtleXdvcmQgYlwiICYmIHZhbHVlID09IFwiZWxzZVwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KHB1c2hsZXgoXCJmb3JtXCIsIFwiZWxzZVwiKSwgc3RhdGVtZW50LCBwb3BsZXgpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGZvcnNwZWModHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcImF3YWl0XCIpIHJldHVybiBjb250KGZvcnNwZWMpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCIoXCIpIHJldHVybiBjb250KHB1c2hsZXgoXCIpXCIpLCBmb3JzcGVjMSwgcG9wbGV4KTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBmb3JzcGVjMSh0eXBlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInZhclwiKSByZXR1cm4gY29udCh2YXJkZWYsIGZvcnNwZWMyKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwidmFyaWFibGVcIikgcmV0dXJuIGNvbnQoZm9yc3BlYzIpO1xuICAgICAgICAgICAgcmV0dXJuIHBhc3MoZm9yc3BlYzIpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGZvcnNwZWMyKHR5cGUsIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIilcIikgcmV0dXJuIGNvbnQoKTtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiO1wiKSByZXR1cm4gY29udChmb3JzcGVjMik7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJpblwiIHx8IHZhbHVlID09IFwib2ZcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KGV4cHJlc3Npb24sIGZvcnNwZWMyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwYXNzKGV4cHJlc3Npb24sIGZvcnNwZWMyKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBmdW5jdGlvbmRlZih0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiKlwiKSB7XG4gICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoZnVuY3Rpb25kZWYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ2YXJpYWJsZVwiKSB7XG4gICAgICAgICAgICAgICAgcmVnaXN0ZXIodmFsdWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KGZ1bmN0aW9uZGVmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09IFwiKFwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBwdXNoY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcIilcIiksXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hc2VwKGZ1bmFyZywgXCIpXCIpLFxuICAgICAgICAgICAgICAgICAgICBwb3BsZXgsXG4gICAgICAgICAgICAgICAgICAgIG1heWJlcmV0dHlwZSxcbiAgICAgICAgICAgICAgICAgICAgc3RhdGVtZW50LFxuICAgICAgICAgICAgICAgICAgICBwb3Bjb250ZXh0XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChpc1RTICYmIHZhbHVlID09IFwiPFwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBwdXNobGV4KFwiPlwiKSxcbiAgICAgICAgICAgICAgICAgICAgY29tbWFzZXAodHlwZXBhcmFtLCBcIj5cIiksXG4gICAgICAgICAgICAgICAgICAgIHBvcGxleCxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25kZWZcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGZ1bmN0aW9uZGVjbCh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiKlwiKSB7XG4gICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoZnVuY3Rpb25kZWNsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09IFwidmFyaWFibGVcIikge1xuICAgICAgICAgICAgICAgIHJlZ2lzdGVyKHZhbHVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChmdW5jdGlvbmRlY2wpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCIoXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoXG4gICAgICAgICAgICAgICAgICAgIHB1c2hjb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICBwdXNobGV4KFwiKVwiKSxcbiAgICAgICAgICAgICAgICAgICAgY29tbWFzZXAoZnVuYXJnLCBcIilcIiksXG4gICAgICAgICAgICAgICAgICAgIHBvcGxleCxcbiAgICAgICAgICAgICAgICAgICAgbWF5YmVyZXR0eXBlLFxuICAgICAgICAgICAgICAgICAgICBwb3Bjb250ZXh0XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChpc1RTICYmIHZhbHVlID09IFwiPFwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KFxuICAgICAgICAgICAgICAgICAgICBwdXNobGV4KFwiPlwiKSxcbiAgICAgICAgICAgICAgICAgICAgY29tbWFzZXAodHlwZXBhcmFtLCBcIj5cIiksXG4gICAgICAgICAgICAgICAgICAgIHBvcGxleCxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25kZWNsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiB0eXBlbmFtZSh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJrZXl3b3JkXCIgfHwgdHlwZSA9PSBcInZhcmlhYmxlXCIpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcInR5cGVcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udCh0eXBlbmFtZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IFwiPFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQocHVzaGxleChcIj5cIiksIGNvbW1hc2VwKHR5cGVwYXJhbSwgXCI+XCIpLCBwb3BsZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGZ1bmFyZyh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiQFwiKSBjb250KGV4cHJlc3Npb24sIGZ1bmFyZyk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInNwcmVhZFwiKSByZXR1cm4gY29udChmdW5hcmcpO1xuICAgICAgICAgICAgaWYgKGlzVFMgJiYgaXNNb2RpZmllcih2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcImtleXdvcmRcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChmdW5hcmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzVFMgJiYgdHlwZSA9PSBcInRoaXNcIikgcmV0dXJuIGNvbnQobWF5YmV0eXBlLCBtYXliZUFzc2lnbik7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyhwYXR0ZXJuLCBtYXliZXR5cGUsIG1heWJlQXNzaWduKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBjbGFzc0V4cHJlc3Npb24odHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIC8vIENsYXNzIGV4cHJlc3Npb25zIG1heSBoYXZlIGFuIG9wdGlvbmFsIG5hbWUuXG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcInZhcmlhYmxlXCIpIHJldHVybiBjbGFzc05hbWUodHlwZSwgdmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIGNsYXNzTmFtZUFmdGVyKHR5cGUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBjbGFzc05hbWUodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwidmFyaWFibGVcIikge1xuICAgICAgICAgICAgICAgIHJlZ2lzdGVyKHZhbHVlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChjbGFzc05hbWVBZnRlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY2xhc3NOYW1lQWZ0ZXIodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIjxcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChcbiAgICAgICAgICAgICAgICAgICAgcHVzaGxleChcIj5cIiksXG4gICAgICAgICAgICAgICAgICAgIGNvbW1hc2VwKHR5cGVwYXJhbSwgXCI+XCIpLFxuICAgICAgICAgICAgICAgICAgICBwb3BsZXgsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZUFmdGVyXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB2YWx1ZSA9PSBcImV4dGVuZHNcIiB8fFxuICAgICAgICAgICAgICAgIHZhbHVlID09IFwiaW1wbGVtZW50c1wiIHx8XG4gICAgICAgICAgICAgICAgKGlzVFMgJiYgdHlwZSA9PSBcIixcIilcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcImltcGxlbWVudHNcIikgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoaXNUUyA/IHR5cGVleHByIDogZXhwcmVzc2lvbiwgY2xhc3NOYW1lQWZ0ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ7XCIpIHJldHVybiBjb250KHB1c2hsZXgoXCJ9XCIpLCBjbGFzc0JvZHksIHBvcGxleCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY2xhc3NCb2R5KHR5cGUsIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgdHlwZSA9PSBcImFzeW5jXCIgfHxcbiAgICAgICAgICAgICAgICAodHlwZSA9PSBcInZhcmlhYmxlXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgKHZhbHVlID09IFwic3RhdGljXCIgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID09IFwiZ2V0XCIgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID09IFwic2V0XCIgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChpc1RTICYmIGlzTW9kaWZpZXIodmFsdWUpKSkgJiZcbiAgICAgICAgICAgICAgICAgICAgY3guc3RyZWFtLm1hdGNoKC9eXFxzK1tcXHckXFx4YTEtXFx1ZmZmZl0vLCBmYWxzZSkpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcImtleXdvcmRcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChjbGFzc0JvZHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ2YXJpYWJsZVwiIHx8IGN4LnN0eWxlID09IFwia2V5d29yZFwiKSB7XG4gICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJwcm9wZXJ0eVwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KGNsYXNzZmllbGQsIGNsYXNzQm9keSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIm51bWJlclwiIHx8IHR5cGUgPT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChjbGFzc2ZpZWxkLCBjbGFzc0JvZHkpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJbXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoXG4gICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgIG1heWJldHlwZSxcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0KFwiXVwiKSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NmaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NCb2R5XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIipcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KGNsYXNzQm9keSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNUUyAmJiB0eXBlID09IFwiKFwiKSByZXR1cm4gcGFzcyhmdW5jdGlvbmRlY2wsIGNsYXNzQm9keSk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIjtcIiB8fCB0eXBlID09IFwiLFwiKSByZXR1cm4gY29udChjbGFzc0JvZHkpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ9XCIpIHJldHVybiBjb250KCk7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJAXCIpIHJldHVybiBjb250KGV4cHJlc3Npb24sIGNsYXNzQm9keSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gY2xhc3NmaWVsZCh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiIVwiKSByZXR1cm4gY29udChjbGFzc2ZpZWxkKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIj9cIikgcmV0dXJuIGNvbnQoY2xhc3NmaWVsZCk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIjpcIikgcmV0dXJuIGNvbnQodHlwZWV4cHIsIG1heWJlQXNzaWduKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIj1cIikgcmV0dXJuIGNvbnQoZXhwcmVzc2lvbk5vQ29tbWEpO1xuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSBjeC5zdGF0ZS5sZXhpY2FsLnByZXYsXG4gICAgICAgICAgICAgICAgaXNJbnRlcmZhY2UgPSBjb250ZXh0ICYmIGNvbnRleHQuaW5mbyA9PSBcImludGVyZmFjZVwiO1xuICAgICAgICAgICAgcmV0dXJuIHBhc3MoaXNJbnRlcmZhY2UgPyBmdW5jdGlvbmRlY2wgOiBmdW5jdGlvbmRlZik7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gYWZ0ZXJFeHBvcnQodHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIipcIikge1xuICAgICAgICAgICAgICAgIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250KG1heWJlRnJvbSwgZXhwZWN0KFwiO1wiKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJkZWZhdWx0XCIpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcImtleXdvcmRcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChleHByZXNzaW9uLCBleHBlY3QoXCI7XCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlID09IFwie1wiKVxuICAgICAgICAgICAgICAgIHJldHVybiBjb250KGNvbW1hc2VwKGV4cG9ydEZpZWxkLCBcIn1cIiksIG1heWJlRnJvbSwgZXhwZWN0KFwiO1wiKSk7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyhzdGF0ZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGV4cG9ydEZpZWxkKHR5cGUsIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJhc1wiKSB7XG4gICAgICAgICAgICAgICAgY3gubWFya2VkID0gXCJrZXl3b3JkXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnQoZXhwZWN0KFwidmFyaWFibGVcIikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ2YXJpYWJsZVwiKSByZXR1cm4gcGFzcyhleHByZXNzaW9uTm9Db21tYSwgZXhwb3J0RmllbGQpO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGFmdGVySW1wb3J0KHR5cGUpIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09IFwic3RyaW5nXCIpIHJldHVybiBjb250KCk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIihcIikgcmV0dXJuIHBhc3MoZXhwcmVzc2lvbik7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIi5cIikgcmV0dXJuIHBhc3MobWF5YmVvcGVyYXRvckNvbW1hKTtcbiAgICAgICAgICAgIHJldHVybiBwYXNzKGltcG9ydFNwZWMsIG1heWJlTW9yZUltcG9ydHMsIG1heWJlRnJvbSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaW1wb3J0U3BlYyh0eXBlLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ7XCIpIHJldHVybiBjb250Q29tbWFzZXAoaW1wb3J0U3BlYywgXCJ9XCIpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJ2YXJpYWJsZVwiKSByZWdpc3Rlcih2YWx1ZSk7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCIqXCIpIGN4Lm1hcmtlZCA9IFwia2V5d29yZFwiO1xuICAgICAgICAgICAgcmV0dXJuIGNvbnQobWF5YmVBcyk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbWF5YmVNb3JlSW1wb3J0cyh0eXBlKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBcIixcIikgcmV0dXJuIGNvbnQoaW1wb3J0U3BlYywgbWF5YmVNb3JlSW1wb3J0cyk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbWF5YmVBcyhfdHlwZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcImFzXCIpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcImtleXdvcmRcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChpbXBvcnRTcGVjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBtYXliZUZyb20oX3R5cGUsIHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJmcm9tXCIpIHtcbiAgICAgICAgICAgICAgICBjeC5tYXJrZWQgPSBcImtleXdvcmRcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udChleHByZXNzaW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBhcnJheUxpdGVyYWwodHlwZSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJdXCIpIHJldHVybiBjb250KCk7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyhjb21tYXNlcChleHByZXNzaW9uTm9Db21tYSwgXCJdXCIpKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBlbnVtZGVmKCkge1xuICAgICAgICAgICAgcmV0dXJuIHBhc3MoXG4gICAgICAgICAgICAgICAgcHVzaGxleChcImZvcm1cIiksXG4gICAgICAgICAgICAgICAgcGF0dGVybixcbiAgICAgICAgICAgICAgICBleHBlY3QoXCJ7XCIpLFxuICAgICAgICAgICAgICAgIHB1c2hsZXgoXCJ9XCIpLFxuICAgICAgICAgICAgICAgIGNvbW1hc2VwKGVudW1tZW1iZXIsIFwifVwiKSxcbiAgICAgICAgICAgICAgICBwb3BsZXgsXG4gICAgICAgICAgICAgICAgcG9wbGV4XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGVudW1tZW1iZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFzcyhwYXR0ZXJuLCBtYXliZUFzc2lnbik7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpc0NvbnRpbnVlZFN0YXRlbWVudChzdGF0ZSwgdGV4dEFmdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIHN0YXRlLmxhc3RUeXBlID09IFwib3BlcmF0b3JcIiB8fFxuICAgICAgICAgICAgICAgIHN0YXRlLmxhc3RUeXBlID09IFwiLFwiIHx8XG4gICAgICAgICAgICAgICAgaXNPcGVyYXRvckNoYXIudGVzdCh0ZXh0QWZ0ZXIuY2hhckF0KDApKSB8fFxuICAgICAgICAgICAgICAgIC9bLC5dLy50ZXN0KHRleHRBZnRlci5jaGFyQXQoMCkpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gZXhwcmVzc2lvbkFsbG93ZWQoc3RyZWFtLCBzdGF0ZSwgYmFja1VwKSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIChzdGF0ZS50b2tlbml6ZSA9PSB0b2tlbkJhc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgL14oPzpvcGVyYXRvcnxzb2Z8a2V5d29yZCBbYmNkXXxjYXNlfG5ld3xleHBvcnR8ZGVmYXVsdHxzcHJlYWR8W1xcW3t9XFwoLDs6XXw9PikkLy50ZXN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUubGFzdFR5cGVcbiAgICAgICAgICAgICAgICAgICAgKSkgfHxcbiAgICAgICAgICAgICAgICAoc3RhdGUubGFzdFR5cGUgPT0gXCJxdWFzaVwiICYmXG4gICAgICAgICAgICAgICAgICAgIC9cXHtcXHMqJC8udGVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5zdHJpbmcuc2xpY2UoMCwgc3RyZWFtLnBvcyAtIChiYWNrVXAgfHwgMCkpXG4gICAgICAgICAgICAgICAgICAgICkpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW50ZXJmYWNlXG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0U3RhdGU6IGZ1bmN0aW9uIChiYXNlY29sdW1uKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0YXRlID0ge1xuICAgICAgICAgICAgICAgICAgICB0b2tlbml6ZTogdG9rZW5CYXNlLFxuICAgICAgICAgICAgICAgICAgICBsYXN0VHlwZTogXCJzb2ZcIixcbiAgICAgICAgICAgICAgICAgICAgY2M6IFtdLFxuICAgICAgICAgICAgICAgICAgICBsZXhpY2FsOiBuZXcgSlNMZXhpY2FsKFxuICAgICAgICAgICAgICAgICAgICAgICAgKGJhc2Vjb2x1bW4gfHwgMCkgLSBpbmRlbnRVbml0LFxuICAgICAgICAgICAgICAgICAgICAgICAgMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiYmxvY2tcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIGxvY2FsVmFyczogcGFyc2VyQ29uZmlnLmxvY2FsVmFycyxcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlckNvbmZpZy5sb2NhbFZhcnMgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDb250ZXh0KG51bGwsIG51bGwsIGZhbHNlKSxcbiAgICAgICAgICAgICAgICAgICAgaW5kZW50ZWQ6IGJhc2Vjb2x1bW4gfHwgMCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VyQ29uZmlnLmdsb2JhbFZhcnMgJiZcbiAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHBhcnNlckNvbmZpZy5nbG9iYWxWYXJzID09IFwib2JqZWN0XCJcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmdsb2JhbFZhcnMgPSBwYXJzZXJDb25maWcuZ2xvYmFsVmFycztcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICB0b2tlbjogZnVuY3Rpb24gKHN0cmVhbSwgc3RhdGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoc3RyZWFtLnNvbCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc3RhdGUubGV4aWNhbC5oYXNPd25Qcm9wZXJ0eShcImFsaWduXCIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUubGV4aWNhbC5hbGlnbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5pbmRlbnRlZCA9IHN0cmVhbS5pbmRlbnRhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICBmaW5kRmF0QXJyb3coc3RyZWFtLCBzdGF0ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzdGF0ZS50b2tlbml6ZSAhPSB0b2tlbkNvbW1lbnQgJiYgc3RyZWFtLmVhdFNwYWNlKCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIHZhciBzdHlsZSA9IHN0YXRlLnRva2VuaXplKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09IFwiY29tbWVudFwiKSByZXR1cm4gc3R5bGU7XG4gICAgICAgICAgICAgICAgc3RhdGUubGFzdFR5cGUgPVxuICAgICAgICAgICAgICAgICAgICB0eXBlID09IFwib3BlcmF0b3JcIiAmJiAoY29udGVudCA9PSBcIisrXCIgfHwgY29udGVudCA9PSBcIi0tXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IFwiaW5jZGVjXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VKUyhzdGF0ZSwgc3R5bGUsIHR5cGUsIGNvbnRlbnQsIHN0cmVhbSk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBpbmRlbnQ6IGZ1bmN0aW9uIChzdGF0ZSwgdGV4dEFmdGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBzdGF0ZS50b2tlbml6ZSA9PSB0b2tlbkNvbW1lbnQgfHxcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUudG9rZW5pemUgPT0gdG9rZW5RdWFzaVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvZGVNaXJyb3IuUGFzcztcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUudG9rZW5pemUgIT0gdG9rZW5CYXNlKSByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICB2YXIgZmlyc3RDaGFyID0gdGV4dEFmdGVyICYmIHRleHRBZnRlci5jaGFyQXQoMCksXG4gICAgICAgICAgICAgICAgICAgIGxleGljYWwgPSBzdGF0ZS5sZXhpY2FsLFxuICAgICAgICAgICAgICAgICAgICB0b3A7XG4gICAgICAgICAgICAgICAgLy8gS2x1ZGdlIHRvIHByZXZlbnQgJ21heWJlbHNlJyBmcm9tIGJsb2NraW5nIGxleGljYWwgc2NvcGUgcG9wc1xuICAgICAgICAgICAgICAgIGlmICghL15cXHMqZWxzZVxcYi8udGVzdCh0ZXh0QWZ0ZXIpKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gc3RhdGUuY2MubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjID0gc3RhdGUuY2NbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSBwb3BsZXgpIGxleGljYWwgPSBsZXhpY2FsLnByZXY7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjICE9IG1heWJlZWxzZSAmJiBjICE9IHBvcGNvbnRleHQpIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd2hpbGUgKFxuICAgICAgICAgICAgICAgICAgICAobGV4aWNhbC50eXBlID09IFwic3RhdFwiIHx8IGxleGljYWwudHlwZSA9PSBcImZvcm1cIikgJiZcbiAgICAgICAgICAgICAgICAgICAgKGZpcnN0Q2hhciA9PSBcIn1cIiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgKCh0b3AgPSBzdGF0ZS5jY1tzdGF0ZS5jYy5sZW5ndGggLSAxXSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodG9wID09IG1heWJlb3BlcmF0b3JDb21tYSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3AgPT0gbWF5YmVvcGVyYXRvck5vQ29tbWEpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIS9eWyxcXC49K1xcLSo6P1tcXChdLy50ZXN0KHRleHRBZnRlcikpKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgbGV4aWNhbCA9IGxleGljYWwucHJldjtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlbWVudEluZGVudCAmJlxuICAgICAgICAgICAgICAgICAgICBsZXhpY2FsLnR5cGUgPT0gXCIpXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgbGV4aWNhbC5wcmV2LnR5cGUgPT0gXCJzdGF0XCJcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIGxleGljYWwgPSBsZXhpY2FsLnByZXY7XG4gICAgICAgICAgICAgICAgdmFyIHR5cGUgPSBsZXhpY2FsLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGNsb3NpbmcgPSBmaXJzdENoYXIgPT0gdHlwZTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlID09IFwidmFyZGVmXCIpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXhpY2FsLmluZGVudGVkICtcbiAgICAgICAgICAgICAgICAgICAgICAgIChzdGF0ZS5sYXN0VHlwZSA9PSBcIm9wZXJhdG9yXCIgfHwgc3RhdGUubGFzdFR5cGUgPT0gXCIsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGxleGljYWwuaW5mby5sZW5ndGggKyAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAwKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gXCJmb3JtXCIgJiYgZmlyc3RDaGFyID09IFwie1wiKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGV4aWNhbC5pbmRlbnRlZDtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFwiZm9ybVwiKSByZXR1cm4gbGV4aWNhbC5pbmRlbnRlZCArIGluZGVudFVuaXQ7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBcInN0YXRcIilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgICAgIGxleGljYWwuaW5kZW50ZWQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgKGlzQ29udGludWVkU3RhdGVtZW50KHN0YXRlLCB0ZXh0QWZ0ZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBzdGF0ZW1lbnRJbmRlbnQgfHwgaW5kZW50VW5pdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogMClcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAgICAgbGV4aWNhbC5pbmZvID09IFwic3dpdGNoXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgIWNsb3NpbmcgJiZcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VyQ29uZmlnLmRvdWJsZUluZGVudFN3aXRjaCAhPSBmYWxzZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgICAgIGxleGljYWwuaW5kZW50ZWQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgKC9eKD86Y2FzZXxkZWZhdWx0KVxcYi8udGVzdCh0ZXh0QWZ0ZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBpbmRlbnRVbml0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAyICogaW5kZW50VW5pdClcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChsZXhpY2FsLmFsaWduKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGV4aWNhbC5jb2x1bW4gKyAoY2xvc2luZyA/IDAgOiAxKTtcbiAgICAgICAgICAgICAgICBlbHNlIHJldHVybiBsZXhpY2FsLmluZGVudGVkICsgKGNsb3NpbmcgPyAwIDogaW5kZW50VW5pdCk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBlbGVjdHJpY0lucHV0OiAvXlxccyooPzpjYXNlIC4qPzp8ZGVmYXVsdDp8XFx7fFxcfSkkLyxcbiAgICAgICAgICAgIGJsb2NrQ29tbWVudFN0YXJ0OiBqc29uTW9kZSA/IG51bGwgOiBcIi8qXCIsXG4gICAgICAgICAgICBibG9ja0NvbW1lbnRFbmQ6IGpzb25Nb2RlID8gbnVsbCA6IFwiKi9cIixcbiAgICAgICAgICAgIGJsb2NrQ29tbWVudENvbnRpbnVlOiBqc29uTW9kZSA/IG51bGwgOiBcIiAqIFwiLFxuICAgICAgICAgICAgbGluZUNvbW1lbnQ6IGpzb25Nb2RlID8gbnVsbCA6IFwiLy9cIixcbiAgICAgICAgICAgIGZvbGQ6IFwiYnJhY2VcIixcbiAgICAgICAgICAgIGNsb3NlQnJhY2tldHM6IFwiKClbXXt9JydcXFwiXFxcImBgXCIsXG5cbiAgICAgICAgICAgIGhlbHBlclR5cGU6IGpzb25Nb2RlID8gXCJqc29uXCIgOiBcImphdmFzY3JpcHRcIixcbiAgICAgICAgICAgIGpzb25sZE1vZGU6IGpzb25sZE1vZGUsXG4gICAgICAgICAgICBqc29uTW9kZToganNvbk1vZGUsXG5cbiAgICAgICAgICAgIGV4cHJlc3Npb25BbGxvd2VkOiBleHByZXNzaW9uQWxsb3dlZCxcblxuICAgICAgICAgICAgc2tpcEV4cHJlc3Npb246IGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgICAgICAgICAgICAgIHBhcnNlSlMoXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBcImF0b21cIixcbiAgICAgICAgICAgICAgICAgICAgXCJhdG9tXCIsXG4gICAgICAgICAgICAgICAgICAgIFwidHJ1ZVwiLFxuICAgICAgICAgICAgICAgICAgICBuZXcgQ29kZU1pcnJvci5TdHJpbmdTdHJlYW0oXCJcIiwgMiwgbnVsbClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIENvZGVNaXJyb3IucmVnaXN0ZXJIZWxwZXIoXCJ3b3JkQ2hhcnNcIiwgXCJqYXZhc2NyaXB0XCIsIC9bXFx3JF0vKTtcblxuICAgIENvZGVNaXJyb3IuZGVmaW5lTUlNRShcInRleHQvamF2YXNjcmlwdFwiLCBcImphdmFzY3JpcHRcIik7XG4gICAgQ29kZU1pcnJvci5kZWZpbmVNSU1FKFwidGV4dC9lY21hc2NyaXB0XCIsIFwiamF2YXNjcmlwdFwiKTtcbiAgICBDb2RlTWlycm9yLmRlZmluZU1JTUUoXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XCIsIFwiamF2YXNjcmlwdFwiKTtcbiAgICBDb2RlTWlycm9yLmRlZmluZU1JTUUoXCJhcHBsaWNhdGlvbi94LWphdmFzY3JpcHRcIiwgXCJqYXZhc2NyaXB0XCIpO1xuICAgIENvZGVNaXJyb3IuZGVmaW5lTUlNRShcImFwcGxpY2F0aW9uL2VjbWFzY3JpcHRcIiwgXCJqYXZhc2NyaXB0XCIpO1xuICAgIENvZGVNaXJyb3IuZGVmaW5lTUlNRShcImFwcGxpY2F0aW9uL2pzb25cIiwge1xuICAgICAgICBuYW1lOiBcImphdmFzY3JpcHRcIixcbiAgICAgICAganNvbjogdHJ1ZSxcbiAgICB9KTtcbiAgICBDb2RlTWlycm9yLmRlZmluZU1JTUUoXCJhcHBsaWNhdGlvbi94LWpzb25cIiwge1xuICAgICAgICBuYW1lOiBcImphdmFzY3JpcHRcIixcbiAgICAgICAganNvbjogdHJ1ZSxcbiAgICB9KTtcbiAgICBDb2RlTWlycm9yLmRlZmluZU1JTUUoXCJhcHBsaWNhdGlvbi9tYW5pZmVzdCtqc29uXCIsIHtcbiAgICAgICAgbmFtZTogXCJqYXZhc2NyaXB0XCIsXG4gICAgICAgIGpzb246IHRydWUsXG4gICAgfSk7XG4gICAgQ29kZU1pcnJvci5kZWZpbmVNSU1FKFwiYXBwbGljYXRpb24vbGQranNvblwiLCB7XG4gICAgICAgIG5hbWU6IFwiamF2YXNjcmlwdFwiLFxuICAgICAgICBqc29ubGQ6IHRydWUsXG4gICAgfSk7XG4gICAgQ29kZU1pcnJvci5kZWZpbmVNSU1FKFwidGV4dC90eXBlc2NyaXB0XCIsIHtcbiAgICAgICAgbmFtZTogXCJqYXZhc2NyaXB0XCIsXG4gICAgICAgIHR5cGVzY3JpcHQ6IHRydWUsXG4gICAgfSk7XG4gICAgQ29kZU1pcnJvci5kZWZpbmVNSU1FKFwiYXBwbGljYXRpb24vdHlwZXNjcmlwdFwiLCB7XG4gICAgICAgIG5hbWU6IFwiamF2YXNjcmlwdFwiLFxuICAgICAgICB0eXBlc2NyaXB0OiB0cnVlLFxuICAgIH0pO1xufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHBzOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4vLyBVdGlsaXR5IGZ1bmN0aW9uIHRoYXQgYWxsb3dzIG1vZGVzIHRvIGJlIGNvbWJpbmVkLiBUaGUgbW9kZSBnaXZlblxuLy8gYXMgdGhlIGJhc2UgYXJndW1lbnQgdGFrZXMgY2FyZSBvZiBtb3N0IG9mIHRoZSBub3JtYWwgbW9kZVxuLy8gZnVuY3Rpb25hbGl0eSwgYnV0IGEgc2Vjb25kICh0eXBpY2FsbHkgc2ltcGxlKSBtb2RlIGlzIHVzZWQsIHdoaWNoXG4vLyBjYW4gb3ZlcnJpZGUgdGhlIHN0eWxlIG9mIHRleHQuIEJvdGggbW9kZXMgZ2V0IHRvIHBhcnNlIGFsbCBvZiB0aGVcbi8vIHRleHQsIGJ1dCB3aGVuIGJvdGggYXNzaWduIGEgbm9uLW51bGwgc3R5bGUgdG8gYSBwaWVjZSBvZiBjb2RlLCB0aGVcbi8vIG92ZXJsYXkgd2lucywgdW5sZXNzIHRoZSBjb21iaW5lIGFyZ3VtZW50IHdhcyB0cnVlIGFuZCBub3Qgb3ZlcnJpZGRlbixcbi8vIG9yIHN0YXRlLm92ZXJsYXkuY29tYmluZVRva2VucyB3YXMgdHJ1ZSwgaW4gd2hpY2ggY2FzZSB0aGUgc3R5bGVzIGFyZVxuLy8gY29tYmluZWQuXG5cbihmdW5jdGlvbiAobW9kKSB7XG4gICAgbW9kKHdpbmRvdy5Db2RlTWlycm9yKTtcbn0pKGZ1bmN0aW9uIChDb2RlTWlycm9yKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBDb2RlTWlycm9yLmN1c3RvbU92ZXJsYXlNb2RlID0gZnVuY3Rpb24gKGJhc2UsIG92ZXJsYXksIGNvbWJpbmUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0U3RhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBiYXNlOiBDb2RlTWlycm9yLnN0YXJ0U3RhdGUoYmFzZSksXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXk6IENvZGVNaXJyb3Iuc3RhcnRTdGF0ZShvdmVybGF5KSxcbiAgICAgICAgICAgICAgICAgICAgYmFzZVBvczogMCxcbiAgICAgICAgICAgICAgICAgICAgYmFzZUN1cjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgb3ZlcmxheVBvczogMCxcbiAgICAgICAgICAgICAgICAgICAgb3ZlcmxheUN1cjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtU2VlbjogbnVsbCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvcHlTdGF0ZTogZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgYmFzZTogQ29kZU1pcnJvci5jb3B5U3RhdGUoYmFzZSwgc3RhdGUuYmFzZSksXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXk6IENvZGVNaXJyb3IuY29weVN0YXRlKG92ZXJsYXksIHN0YXRlLm92ZXJsYXkpLFxuICAgICAgICAgICAgICAgICAgICBiYXNlUG9zOiBzdGF0ZS5iYXNlUG9zLFxuICAgICAgICAgICAgICAgICAgICBiYXNlQ3VyOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5UG9zOiBzdGF0ZS5vdmVybGF5UG9zLFxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5Q3VyOiBudWxsLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICB0b2tlbjogZnVuY3Rpb24gKHN0cmVhbSwgc3RhdGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbSAhPSBzdGF0ZS5zdHJlYW1TZWVuIHx8XG4gICAgICAgICAgICAgICAgICAgIE1hdGgubWluKHN0YXRlLmJhc2VQb3MsIHN0YXRlLm92ZXJsYXlQb3MpIDwgc3RyZWFtLnN0YXJ0XG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLnN0cmVhbVNlZW4gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmJhc2VQb3MgPSBzdGF0ZS5vdmVybGF5UG9zID0gc3RyZWFtLnN0YXJ0O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChzdHJlYW0uc3RhcnQgPT0gc3RhdGUuYmFzZVBvcykge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5iYXNlQ3VyID0gYmFzZS50b2tlbihzdHJlYW0sIHN0YXRlLmJhc2UpO1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5iYXNlUG9zID0gc3RyZWFtLnBvcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHN0cmVhbS5zdGFydCA9PSBzdGF0ZS5vdmVybGF5UG9zKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5wb3MgPSBzdHJlYW0uc3RhcnQ7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLm92ZXJsYXlDdXIgPSBvdmVybGF5LnRva2VuKHN0cmVhbSwgc3RhdGUub3ZlcmxheSk7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLm92ZXJsYXlQb3MgPSBzdHJlYW0ucG9zO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzdHJlYW0ucG9zID0gTWF0aC5taW4oc3RhdGUuYmFzZVBvcywgc3RhdGUub3ZlcmxheVBvcyk7XG5cbiAgICAgICAgICAgICAgICAvLyBFZGdlIGNhc2UgZm9yIGNvZGVibG9ja3MgaW4gdGVtcGxhdGVyIG1vZGVcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmJhc2VDdXIgJiZcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUub3ZlcmxheUN1ciAmJlxuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5iYXNlQ3VyLmNvbnRhaW5zKFwibGluZS1IeXBlck1ELWNvZGVibG9ja1wiKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5vdmVybGF5Q3VyID0gc3RhdGUub3ZlcmxheUN1ci5yZXBsYWNlKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJsaW5lLXRlbXBsYXRlci1pbmxpbmVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXCJcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUub3ZlcmxheUN1ciArPSBgIGxpbmUtYmFja2dyb3VuZC1IeXBlck1ELWNvZGVibG9jay1iZ2A7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gc3RhdGUub3ZlcmxheS5jb21iaW5lVG9rZW5zIGFsd2F5cyB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgY29tYmluZSxcbiAgICAgICAgICAgICAgICAvLyB1bmxlc3Mgc2V0IHRvIG51bGxcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUub3ZlcmxheUN1ciA9PSBudWxsKSByZXR1cm4gc3RhdGUuYmFzZUN1cjtcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAgICAgKHN0YXRlLmJhc2VDdXIgIT0gbnVsbCAmJiBzdGF0ZS5vdmVybGF5LmNvbWJpbmVUb2tlbnMpIHx8XG4gICAgICAgICAgICAgICAgICAgIChjb21iaW5lICYmIHN0YXRlLm92ZXJsYXkuY29tYmluZVRva2VucyA9PSBudWxsKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlLmJhc2VDdXIgKyBcIiBcIiArIHN0YXRlLm92ZXJsYXlDdXI7XG4gICAgICAgICAgICAgICAgZWxzZSByZXR1cm4gc3RhdGUub3ZlcmxheUN1cjtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIGluZGVudDpcbiAgICAgICAgICAgICAgICBiYXNlLmluZGVudCAmJlxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChzdGF0ZSwgdGV4dEFmdGVyLCBsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBiYXNlLmluZGVudChzdGF0ZS5iYXNlLCB0ZXh0QWZ0ZXIsIGxpbmUpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlbGVjdHJpY0NoYXJzOiBiYXNlLmVsZWN0cmljQ2hhcnMsXG5cbiAgICAgICAgICAgIGlubmVyTW9kZTogZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc3RhdGU6IHN0YXRlLmJhc2UsIG1vZGU6IGJhc2UgfTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIGJsYW5rTGluZTogZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJhc2VUb2tlbiwgb3ZlcmxheVRva2VuO1xuICAgICAgICAgICAgICAgIGlmIChiYXNlLmJsYW5rTGluZSkgYmFzZVRva2VuID0gYmFzZS5ibGFua0xpbmUoc3RhdGUuYmFzZSk7XG4gICAgICAgICAgICAgICAgaWYgKG92ZXJsYXkuYmxhbmtMaW5lKVxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5VG9rZW4gPSBvdmVybGF5LmJsYW5rTGluZShzdGF0ZS5vdmVybGF5KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBvdmVybGF5VG9rZW4gPT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/IGJhc2VUb2tlblxuICAgICAgICAgICAgICAgICAgICA6IGNvbWJpbmUgJiYgYmFzZVRva2VuICE9IG51bGxcbiAgICAgICAgICAgICAgICAgICAgPyBiYXNlVG9rZW4gKyBcIiBcIiArIG92ZXJsYXlUb2tlblxuICAgICAgICAgICAgICAgICAgICA6IG92ZXJsYXlUb2tlbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfTtcbn0pO1xuIiwiaW1wb3J0IHsgQXBwLCBQbGF0Zm9ybSB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IFRlbXBsYXRlclBsdWdpbiBmcm9tIFwibWFpblwiO1xuaW1wb3J0IHsgVGVtcGxhdGVyRXJyb3IgfSBmcm9tIFwiRXJyb3JcIjtcbmltcG9ydCB7IEN1cnNvckp1bXBlciB9IGZyb20gXCJlZGl0b3IvQ3Vyc29ySnVtcGVyXCI7XG5pbXBvcnQgeyBsb2dfZXJyb3IgfSBmcm9tIFwiTG9nXCI7XG5pbXBvcnQgeyBBdXRvY29tcGxldGUgfSBmcm9tIFwiZWRpdG9yL0F1dG9jb21wbGV0ZVwiO1xuXG5pbXBvcnQgXCJlZGl0b3IvbW9kZS9qYXZhc2NyaXB0XCI7XG5pbXBvcnQgXCJlZGl0b3IvbW9kZS9jdXN0b21fb3ZlcmxheVwiO1xuLy9pbXBvcnQgXCJlZGl0b3IvbW9kZS9zaG93LWhpbnRcIjtcblxuY29uc3QgVFBfQ01EX1RPS0VOX0NMQVNTID0gXCJ0ZW1wbGF0ZXItY29tbWFuZFwiO1xuY29uc3QgVFBfSU5MSU5FX0NMQVNTID0gXCJ0ZW1wbGF0ZXItaW5saW5lXCI7XG5cbmNvbnN0IFRQX09QRU5JTkdfVEFHX1RPS0VOX0NMQVNTID0gXCJ0ZW1wbGF0ZXItb3BlbmluZy10YWdcIjtcbmNvbnN0IFRQX0NMT1NJTkdfVEFHX1RPS0VOX0NMQVNTID0gXCJ0ZW1wbGF0ZXItY2xvc2luZy10YWdcIjtcblxuY29uc3QgVFBfSU5URVJQT0xBVElPTl9UQUdfVE9LRU5fQ0xBU1MgPSBcInRlbXBsYXRlci1pbnRlcnBvbGF0aW9uLXRhZ1wiO1xuY29uc3QgVFBfUkFXX1RBR19UT0tFTl9DTEFTUyA9IFwidGVtcGxhdGVyLXJhdy10YWdcIjtcbmNvbnN0IFRQX0VYRUNfVEFHX1RPS0VOX0NMQVNTID0gXCJ0ZW1wbGF0ZXItZXhlY3V0aW9uLXRhZ1wiO1xuXG5leHBvcnQgY2xhc3MgRWRpdG9yIHtcbiAgICBwcml2YXRlIGN1cnNvcl9qdW1wZXI6IEN1cnNvckp1bXBlcjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIGFwcDogQXBwLCBwcml2YXRlIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luKSB7XG4gICAgICAgIHRoaXMuY3Vyc29yX2p1bXBlciA9IG5ldyBDdXJzb3JKdW1wZXIodGhpcy5hcHApO1xuICAgIH1cblxuICAgIGFzeW5jIHNldHVwKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyQ29kZU1pcnJvck1vZGUoKTtcbiAgICAgICAgLy9hd2FpdCB0aGlzLnJlZ2lzdGVySGludGVyKCk7XG4gICAgICAgIHRoaXMucGx1Z2luLnJlZ2lzdGVyRWRpdG9yU3VnZ2VzdChuZXcgQXV0b2NvbXBsZXRlKHRoaXMuYXBwLCB0aGlzLnBsdWdpbikpO1xuICAgIH1cblxuICAgIGFzeW5jIGp1bXBfdG9fbmV4dF9jdXJzb3JfbG9jYXRpb24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuY3Vyc29yX2p1bXBlci5qdW1wX3RvX25leHRfY3Vyc29yX2xvY2F0aW9uKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVnaXN0ZXJDb2RlTWlycm9yTW9kZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gY20tZWRpdG9yLXN5bnRheC1oaWdobGlnaHQtb2JzaWRpYW4gcGx1Z2luXG4gICAgICAgIC8vIGh0dHBzOi8vY29kZW1pcnJvci5uZXQvZG9jL21hbnVhbC5odG1sI21vZGVhcGlcbiAgICAgICAgLy8gaHR0cHM6Ly9jb2RlbWlycm9yLm5ldC9tb2RlL2RpZmYvZGlmZi5qc1xuICAgICAgICAvLyBodHRwczovL2NvZGVtaXJyb3IubmV0L2RlbW8vbXVzdGFjaGUuaHRtbFxuICAgICAgICAvLyBodHRwczovL21hcmlqbmhhdmVyYmVrZS5ubC9ibG9nL2NvZGVtaXJyb3ItbW9kZS1zeXN0ZW0uaHRtbFxuXG4gICAgICAgIGlmICghdGhpcy5wbHVnaW4uc2V0dGluZ3Muc3ludGF4X2hpZ2hsaWdodGluZykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVE9ETzogQWRkIG1vYmlsZSBzdXBwb3J0XG4gICAgICAgIGlmIChQbGF0Zm9ybS5pc01vYmlsZUFwcCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QganNfbW9kZSA9IHdpbmRvdy5Db2RlTWlycm9yLmdldE1vZGUoe30sIFwiamF2YXNjcmlwdFwiKTtcbiAgICAgICAgaWYgKGpzX21vZGUubmFtZSA9PT0gXCJudWxsXCIpIHtcbiAgICAgICAgICAgIGxvZ19lcnJvcihcbiAgICAgICAgICAgICAgICBuZXcgVGVtcGxhdGVyRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiSmF2YXNjcmlwdCBzeW50YXggbW9kZSBjb3VsZG4ndCBiZSBmb3VuZCwgY2FuJ3QgZW5hYmxlIHN5bnRheCBoaWdobGlnaHRpbmcuXCJcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3VzdG9tIG92ZXJsYXkgbW9kZSB1c2VkIHRvIGhhbmRsZSBlZGdlIGNhc2VzXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgY29uc3Qgb3ZlcmxheV9tb2RlID0gd2luZG93LkNvZGVNaXJyb3IuY3VzdG9tT3ZlcmxheU1vZGU7XG4gICAgICAgIGlmIChvdmVybGF5X21vZGUgPT0gbnVsbCkge1xuICAgICAgICAgICAgbG9nX2Vycm9yKFxuICAgICAgICAgICAgICAgIG5ldyBUZW1wbGF0ZXJFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgXCJDb3VsZG4ndCBmaW5kIGN1c3RvbU92ZXJsYXlNb2RlLCBjYW4ndCBlbmFibGUgc3ludGF4IGhpZ2hsaWdodGluZy5cIlxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB3aW5kb3cuQ29kZU1pcnJvci5kZWZpbmVNb2RlKFwidGVtcGxhdGVyXCIsIGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlck92ZXJsYXkgPSB7XG4gICAgICAgICAgICAgICAgc3RhcnRTdGF0ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBqc19zdGF0ZSA9IHdpbmRvdy5Db2RlTWlycm9yLnN0YXJ0U3RhdGUoanNfbW9kZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5qc19zdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluQ29tbWFuZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWdfY2xhc3M6IFwiXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmVlTGluZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb3B5U3RhdGU6IGZ1bmN0aW9uIChzdGF0ZTogYW55KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzX3N0YXRlID0gd2luZG93LkNvZGVNaXJyb3Iuc3RhcnRTdGF0ZShqc19tb2RlKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3X3N0YXRlID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uanNfc3RhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbkNvbW1hbmQ6IHN0YXRlLmluQ29tbWFuZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ19jbGFzczogc3RhdGUudGFnX2NsYXNzLFxuICAgICAgICAgICAgICAgICAgICAgICAgZnJlZUxpbmU6IHN0YXRlLmZyZWVMaW5lLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3X3N0YXRlO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYmxhbmtMaW5lOiBmdW5jdGlvbiAoc3RhdGU6IGFueSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUuaW5Db21tYW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYGxpbmUtYmFja2dyb3VuZC10ZW1wbGF0ZXItY29tbWFuZC1iZ2A7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0b2tlbjogZnVuY3Rpb24gKHN0cmVhbTogYW55LCBzdGF0ZTogYW55KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW0uc29sKCkgJiYgc3RhdGUuaW5Db21tYW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZS5mcmVlTGluZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUuaW5Db21tYW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQga2V5d29yZHMgPSBcIlwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbS5tYXRjaCgvWy1fXXswLDF9JT4vLCB0cnVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLmluQ29tbWFuZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLmZyZWVMaW5lID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFnX2NsYXNzID0gc3RhdGUudGFnX2NsYXNzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLnRhZ19jbGFzcyA9IFwiXCI7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYGxpbmUtJHtUUF9JTkxJTkVfQ0xBU1N9ICR7VFBfQ01EX1RPS0VOX0NMQVNTfSAke1RQX0NMT1NJTkdfVEFHX1RPS0VOX0NMQVNTfSAke3RhZ19jbGFzc31gO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc19yZXN1bHQgPSBqc19tb2RlLnRva2VuKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbS5wZWVrKCkgPT0gbnVsbCAmJiBzdGF0ZS5mcmVlTGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXdvcmRzICs9IGAgbGluZS1iYWNrZ3JvdW5kLXRlbXBsYXRlci1jb21tYW5kLWJnYDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc3RhdGUuZnJlZUxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXl3b3JkcyArPSBgIGxpbmUtJHtUUF9JTkxJTkVfQ0xBU1N9YDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke2tleXdvcmRzfSAke1RQX0NNRF9UT0tFTl9DTEFTU30gJHtqc19yZXN1bHR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gc3RyZWFtLm1hdGNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgLzwlWy1fXXswLDF9XFxzKihbKn4rXXswLDF9KS8sXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnVlXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKG1hdGNoWzFdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcIipcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUudGFnX2NsYXNzID0gVFBfRVhFQ19UQUdfVE9LRU5fQ0xBU1M7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ+XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLnRhZ19jbGFzcyA9IFRQX1JBV19UQUdfVE9LRU5fQ0xBU1M7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLnRhZ19jbGFzcyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUF9JTlRFUlBPTEFUSU9OX1RBR19UT0tFTl9DTEFTUztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZS5pbkNvbW1hbmQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBsaW5lLSR7VFBfSU5MSU5FX0NMQVNTfSAke1RQX0NNRF9UT0tFTl9DTEFTU30gJHtUUF9PUEVOSU5HX1RBR19UT0tFTl9DTEFTU30gJHtzdGF0ZS50YWdfY2xhc3N9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdHJlYW0ubmV4dCgpICE9IG51bGwgJiYgIXN0cmVhbS5tYXRjaCgvPCUvLCBmYWxzZSkpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiBvdmVybGF5X21vZGUoXG4gICAgICAgICAgICAgICAgd2luZG93LkNvZGVNaXJyb3IuZ2V0TW9kZShjb25maWcsIFwiaHlwZXJtZFwiKSxcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZXJPdmVybGF5XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyByZWdpc3RlckhpbnRlcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gVE9ET1xuICAgICAgICAvKlxuICAgICAgICBhd2FpdCBkZWxheSgxMDAwKTtcblxuICAgICAgICB2YXIgY29tcCA9IFtcbiAgICAgICAgICAgIFtcImhlcmVcIiwgXCJoaXRoZXJcIl0sXG4gICAgICAgICAgICBbXCJhc3luY2hyb25vdXNcIiwgXCJub25zeW5jaHJvbm91c1wiXSxcbiAgICAgICAgICAgIFtcImNvbXBsZXRpb25cIiwgXCJhY2hpZXZlbWVudFwiLCBcImNvbmNsdXNpb25cIiwgXCJjdWxtaW5hdGlvblwiLCBcImV4cGlyYXRpb25zXCJdLFxuICAgICAgICAgICAgW1wiaGludGluZ1wiLCBcImFkdmlzZVwiLCBcImJyb2FjaFwiLCBcImltcGx5XCJdLFxuICAgICAgICAgICAgW1wiZnVuY3Rpb25cIixcImFjdGlvblwiXSxcbiAgICAgICAgICAgIFtcInByb3ZpZGVcIiwgXCJhZGRcIiwgXCJicmluZ1wiLCBcImdpdmVcIl0sXG4gICAgICAgICAgICBbXCJzeW5vbnltc1wiLCBcImVxdWl2YWxlbnRzXCJdLFxuICAgICAgICAgICAgW1wid29yZHNcIiwgXCJ0b2tlblwiXSxcbiAgICAgICAgICAgIFtcImVhY2hcIiwgXCJldmVyeVwiXSxcbiAgICAgICAgXTtcbiAgICBcbiAgICAgICAgZnVuY3Rpb24gc3lub255bXMoY206IGFueSwgb3B0aW9uOiBhbnkpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihhY2NlcHQpIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY3Vyc29yID0gY20uZ2V0Q3Vyc29yKCksIGxpbmUgPSBjbS5nZXRMaW5lKGN1cnNvci5saW5lKVxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RhcnQgPSBjdXJzb3IuY2gsIGVuZCA9IGN1cnNvci5jaFxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3RhcnQgJiYgL1xcdy8udGVzdChsaW5lLmNoYXJBdChzdGFydCAtIDEpKSkgLS1zdGFydFxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZW5kIDwgbGluZS5sZW5ndGggJiYgL1xcdy8udGVzdChsaW5lLmNoYXJBdChlbmQpKSkgKytlbmRcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdvcmQgPSBsaW5lLnNsaWNlKHN0YXJ0LCBlbmQpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb21wLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tcFtpXS5pbmRleE9mKHdvcmQpICE9IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjY2VwdCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3Q6IGNvbXBbaV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb206IHdpbmRvdy5Db2RlTWlycm9yLlBvcyhjdXJzb3IubGluZSwgc3RhcnQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bzogd2luZG93LkNvZGVNaXJyb3IuUG9zKGN1cnNvci5saW5lLCBlbmQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjY2VwdChudWxsKTtcbiAgICAgICAgICAgICAgICB9LCAxMDApXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYXBwLndvcmtzcGFjZS5vbihcImNvZGVtaXJyb3JcIiwgY20gPT4ge1xuICAgICAgICAgICAgY20uc2V0T3B0aW9uKFwiZXh0cmFLZXlzXCIsIHtcIkN0cmwtU3BhY2VcIjogXCJhdXRvY29tcGxldGVcIn0pO1xuICAgICAgICAgICAgY20uc2V0T3B0aW9uKFwiaGludE9wdGlvbnNcIiwge2hpbnQ6IHN5bm9ueW1zfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuYXBwLndvcmtzcGFjZS5pdGVyYXRlQ29kZU1pcnJvcnMoY20gPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJDTTpcIiwgY20pO1xuICAgICAgICAgICAgY20uc2V0T3B0aW9uKFwiZXh0cmFLZXlzXCIsIHtcIlNwYWNlXCI6IFwiYXV0b2NvbXBsZXRlXCJ9KTtcbiAgICAgICAgICAgIGNtLnNldE9wdGlvbihcImhpbnRPcHRpb25zXCIsIHtoaW50OiBzeW5vbnltc30pO1xuICAgICAgICB9KTtcbiAgICAgICAgKi9cbiAgICB9XG59XG4iLCJpbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyByZXNvbHZlLCBkaXJuYW1lLCBleHRuYW1lIH0gZnJvbSAncGF0aCc7XG5cbi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcblxyXG52YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfTtcclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59O1xuXG5mdW5jdGlvbiBzZXRQcm90b3R5cGVPZihvYmosIHByb3RvKSB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcclxuICAgIGlmIChPYmplY3Quc2V0UHJvdG90eXBlT2YpIHtcclxuICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2Yob2JqLCBwcm90byk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBvYmouX19wcm90b19fID0gcHJvdG87XHJcbiAgICB9XHJcbn1cclxuLy8gVGhpcyBpcyBwcmV0dHkgbXVjaCB0aGUgb25seSB3YXkgdG8gZ2V0IG5pY2UsIGV4dGVuZGVkIEVycm9yc1xyXG4vLyB3aXRob3V0IHVzaW5nIEVTNlxyXG4vKipcclxuICogVGhpcyByZXR1cm5zIGEgbmV3IEVycm9yIHdpdGggYSBjdXN0b20gcHJvdG90eXBlLiBOb3RlIHRoYXQgaXQncyBfbm90XyBhIGNvbnN0cnVjdG9yXHJcbiAqXHJcbiAqIEBwYXJhbSBtZXNzYWdlIEVycm9yIG1lc3NhZ2VcclxuICpcclxuICogKipFeGFtcGxlKipcclxuICpcclxuICogYGBganNcclxuICogdGhyb3cgRXRhRXJyKFwidGVtcGxhdGUgbm90IGZvdW5kXCIpXHJcbiAqIGBgYFxyXG4gKi9cclxuZnVuY3Rpb24gRXRhRXJyKG1lc3NhZ2UpIHtcclxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IobWVzc2FnZSk7XHJcbiAgICBzZXRQcm90b3R5cGVPZihlcnIsIEV0YUVyci5wcm90b3R5cGUpO1xyXG4gICAgcmV0dXJuIGVycjtcclxufVxyXG5FdGFFcnIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFcnJvci5wcm90b3R5cGUsIHtcclxuICAgIG5hbWU6IHsgdmFsdWU6ICdFdGEgRXJyb3InLCBlbnVtZXJhYmxlOiBmYWxzZSB9XHJcbn0pO1xyXG4vKipcclxuICogVGhyb3dzIGFuIEV0YUVyciB3aXRoIGEgbmljZWx5IGZvcm1hdHRlZCBlcnJvciBhbmQgbWVzc2FnZSBzaG93aW5nIHdoZXJlIGluIHRoZSB0ZW1wbGF0ZSB0aGUgZXJyb3Igb2NjdXJyZWQuXHJcbiAqL1xyXG5mdW5jdGlvbiBQYXJzZUVycihtZXNzYWdlLCBzdHIsIGluZHgpIHtcclxuICAgIHZhciB3aGl0ZXNwYWNlID0gc3RyLnNsaWNlKDAsIGluZHgpLnNwbGl0KC9cXG4vKTtcclxuICAgIHZhciBsaW5lTm8gPSB3aGl0ZXNwYWNlLmxlbmd0aDtcclxuICAgIHZhciBjb2xObyA9IHdoaXRlc3BhY2VbbGluZU5vIC0gMV0ubGVuZ3RoICsgMTtcclxuICAgIG1lc3NhZ2UgKz1cclxuICAgICAgICAnIGF0IGxpbmUgJyArXHJcbiAgICAgICAgICAgIGxpbmVObyArXHJcbiAgICAgICAgICAgICcgY29sICcgK1xyXG4gICAgICAgICAgICBjb2xObyArXHJcbiAgICAgICAgICAgICc6XFxuXFxuJyArXHJcbiAgICAgICAgICAgICcgICcgK1xyXG4gICAgICAgICAgICBzdHIuc3BsaXQoL1xcbi8pW2xpbmVObyAtIDFdICtcclxuICAgICAgICAgICAgJ1xcbicgK1xyXG4gICAgICAgICAgICAnICAnICtcclxuICAgICAgICAgICAgQXJyYXkoY29sTm8pLmpvaW4oJyAnKSArXHJcbiAgICAgICAgICAgICdeJztcclxuICAgIHRocm93IEV0YUVycihtZXNzYWdlKTtcclxufVxuXG4vKipcclxuICogQHJldHVybnMgVGhlIGdsb2JhbCBQcm9taXNlIGZ1bmN0aW9uXHJcbiAqL1xyXG52YXIgcHJvbWlzZUltcGwgPSBuZXcgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKS5Qcm9taXNlO1xyXG4vKipcclxuICogQHJldHVybnMgQSBuZXcgQXN5bmNGdW5jdGlvbiBjb25zdHVjdG9yXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRBc3luY0Z1bmN0aW9uQ29uc3RydWN0b3IoKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHJldHVybiBuZXcgRnVuY3Rpb24oJ3JldHVybiAoYXN5bmMgZnVuY3Rpb24oKXt9KS5jb25zdHJ1Y3RvcicpKCk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgIGlmIChlIGluc3RhbmNlb2YgU3ludGF4RXJyb3IpIHtcclxuICAgICAgICAgICAgdGhyb3cgRXRhRXJyKFwiVGhpcyBlbnZpcm9ubWVudCBkb2Vzbid0IHN1cHBvcnQgYXN5bmMvYXdhaXRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4vKipcclxuICogc3RyLnRyaW1MZWZ0IHBvbHlmaWxsXHJcbiAqXHJcbiAqIEBwYXJhbSBzdHIgLSBJbnB1dCBzdHJpbmdcclxuICogQHJldHVybnMgVGhlIHN0cmluZyB3aXRoIGxlZnQgd2hpdGVzcGFjZSByZW1vdmVkXHJcbiAqXHJcbiAqL1xyXG5mdW5jdGlvbiB0cmltTGVmdChzdHIpIHtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1leHRyYS1ib29sZWFuLWNhc3RcclxuICAgIGlmICghIVN0cmluZy5wcm90b3R5cGUudHJpbUxlZnQpIHtcclxuICAgICAgICByZXR1cm4gc3RyLnRyaW1MZWZ0KCk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrLywgJycpO1xyXG4gICAgfVxyXG59XHJcbi8qKlxyXG4gKiBzdHIudHJpbVJpZ2h0IHBvbHlmaWxsXHJcbiAqXHJcbiAqIEBwYXJhbSBzdHIgLSBJbnB1dCBzdHJpbmdcclxuICogQHJldHVybnMgVGhlIHN0cmluZyB3aXRoIHJpZ2h0IHdoaXRlc3BhY2UgcmVtb3ZlZFxyXG4gKlxyXG4gKi9cclxuZnVuY3Rpb24gdHJpbVJpZ2h0KHN0cikge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWV4dHJhLWJvb2xlYW4tY2FzdFxyXG4gICAgaWYgKCEhU3RyaW5nLnByb3RvdHlwZS50cmltUmlnaHQpIHtcclxuICAgICAgICByZXR1cm4gc3RyLnRyaW1SaWdodCgpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXHMrJC8sICcnKTsgLy8gVE9ETzogZG8gd2UgcmVhbGx5IG5lZWQgdG8gcmVwbGFjZSBCT00ncz9cclxuICAgIH1cclxufVxuXG4vLyBUT0RPOiBhbGxvdyAnLScgdG8gdHJpbSB1cCB1bnRpbCBuZXdsaW5lLiBVc2UgW15cXFNcXG5cXHJdIGluc3RlYWQgb2YgXFxzXHJcbi8qIEVORCBUWVBFUyAqL1xyXG5mdW5jdGlvbiBoYXNPd25Qcm9wKG9iaiwgcHJvcCkge1xyXG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xyXG59XHJcbmZ1bmN0aW9uIGNvcHlQcm9wcyh0b09iaiwgZnJvbU9iaikge1xyXG4gICAgZm9yICh2YXIga2V5IGluIGZyb21PYmopIHtcclxuICAgICAgICBpZiAoaGFzT3duUHJvcChmcm9tT2JqLCBrZXkpKSB7XHJcbiAgICAgICAgICAgIHRvT2JqW2tleV0gPSBmcm9tT2JqW2tleV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvT2JqO1xyXG59XHJcbi8qKlxyXG4gKiBUYWtlcyBhIHN0cmluZyB3aXRoaW4gYSB0ZW1wbGF0ZSBhbmQgdHJpbXMgaXQsIGJhc2VkIG9uIHRoZSBwcmVjZWRpbmcgdGFnJ3Mgd2hpdGVzcGFjZSBjb250cm9sIGFuZCBgY29uZmlnLmF1dG9UcmltYFxyXG4gKi9cclxuZnVuY3Rpb24gdHJpbVdTKHN0ciwgY29uZmlnLCB3c0xlZnQsIHdzUmlnaHQpIHtcclxuICAgIHZhciBsZWZ0VHJpbTtcclxuICAgIHZhciByaWdodFRyaW07XHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjb25maWcuYXV0b1RyaW0pKSB7XHJcbiAgICAgICAgLy8ga2luZGEgY29uZnVzaW5nXHJcbiAgICAgICAgLy8gYnV0IF99fSB3aWxsIHRyaW0gdGhlIGxlZnQgc2lkZSBvZiB0aGUgZm9sbG93aW5nIHN0cmluZ1xyXG4gICAgICAgIGxlZnRUcmltID0gY29uZmlnLmF1dG9UcmltWzFdO1xyXG4gICAgICAgIHJpZ2h0VHJpbSA9IGNvbmZpZy5hdXRvVHJpbVswXTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGxlZnRUcmltID0gcmlnaHRUcmltID0gY29uZmlnLmF1dG9UcmltO1xyXG4gICAgfVxyXG4gICAgaWYgKHdzTGVmdCB8fCB3c0xlZnQgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgbGVmdFRyaW0gPSB3c0xlZnQ7XHJcbiAgICB9XHJcbiAgICBpZiAod3NSaWdodCB8fCB3c1JpZ2h0ID09PSBmYWxzZSkge1xyXG4gICAgICAgIHJpZ2h0VHJpbSA9IHdzUmlnaHQ7XHJcbiAgICB9XHJcbiAgICBpZiAoIXJpZ2h0VHJpbSAmJiAhbGVmdFRyaW0pIHtcclxuICAgICAgICByZXR1cm4gc3RyO1xyXG4gICAgfVxyXG4gICAgaWYgKGxlZnRUcmltID09PSAnc2x1cnAnICYmIHJpZ2h0VHJpbSA9PT0gJ3NsdXJwJykge1xyXG4gICAgICAgIHJldHVybiBzdHIudHJpbSgpO1xyXG4gICAgfVxyXG4gICAgaWYgKGxlZnRUcmltID09PSAnXycgfHwgbGVmdFRyaW0gPT09ICdzbHVycCcpIHtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZygndHJpbW1pbmcgbGVmdCcgKyBsZWZ0VHJpbSlcclxuICAgICAgICAvLyBmdWxsIHNsdXJwXHJcbiAgICAgICAgc3RyID0gdHJpbUxlZnQoc3RyKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGxlZnRUcmltID09PSAnLScgfHwgbGVmdFRyaW0gPT09ICdubCcpIHtcclxuICAgICAgICAvLyBubCB0cmltXHJcbiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL14oPzpcXHJcXG58XFxufFxccikvLCAnJyk7XHJcbiAgICB9XHJcbiAgICBpZiAocmlnaHRUcmltID09PSAnXycgfHwgcmlnaHRUcmltID09PSAnc2x1cnAnKSB7XHJcbiAgICAgICAgLy8gZnVsbCBzbHVycFxyXG4gICAgICAgIHN0ciA9IHRyaW1SaWdodChzdHIpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAocmlnaHRUcmltID09PSAnLScgfHwgcmlnaHRUcmltID09PSAnbmwnKSB7XHJcbiAgICAgICAgLy8gbmwgdHJpbVxyXG4gICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC8oPzpcXHJcXG58XFxufFxccikkLywgJycpOyAvLyBUT0RPOiBtYWtlIHN1cmUgdGhpcyBnZXRzIFxcclxcblxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN0cjtcclxufVxyXG4vKipcclxuICogQSBtYXAgb2Ygc3BlY2lhbCBIVE1MIGNoYXJhY3RlcnMgdG8gdGhlaXIgWE1MLWVzY2FwZWQgZXF1aXZhbGVudHNcclxuICovXHJcbnZhciBlc2NNYXAgPSB7XHJcbiAgICAnJic6ICcmYW1wOycsXHJcbiAgICAnPCc6ICcmbHQ7JyxcclxuICAgICc+JzogJyZndDsnLFxyXG4gICAgJ1wiJzogJyZxdW90OycsXHJcbiAgICBcIidcIjogJyYjMzk7J1xyXG59O1xyXG5mdW5jdGlvbiByZXBsYWNlQ2hhcihzKSB7XHJcbiAgICByZXR1cm4gZXNjTWFwW3NdO1xyXG59XHJcbi8qKlxyXG4gKiBYTUwtZXNjYXBlcyBhbiBpbnB1dCB2YWx1ZSBhZnRlciBjb252ZXJ0aW5nIGl0IHRvIGEgc3RyaW5nXHJcbiAqXHJcbiAqIEBwYXJhbSBzdHIgLSBJbnB1dCB2YWx1ZSAodXN1YWxseSBhIHN0cmluZylcclxuICogQHJldHVybnMgWE1MLWVzY2FwZWQgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBYTUxFc2NhcGUoc3RyKSB7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcclxuICAgIC8vIFRvIGRlYWwgd2l0aCBYU1MuIEJhc2VkIG9uIEVzY2FwZSBpbXBsZW1lbnRhdGlvbnMgb2YgTXVzdGFjaGUuSlMgYW5kIE1hcmtvLCB0aGVuIGN1c3RvbWl6ZWQuXHJcbiAgICB2YXIgbmV3U3RyID0gU3RyaW5nKHN0cik7XHJcbiAgICBpZiAoL1smPD5cIiddLy50ZXN0KG5ld1N0cikpIHtcclxuICAgICAgICByZXR1cm4gbmV3U3RyLnJlcGxhY2UoL1smPD5cIiddL2csIHJlcGxhY2VDaGFyKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBuZXdTdHI7XHJcbiAgICB9XHJcbn1cblxuLyogRU5EIFRZUEVTICovXHJcbnZhciB0ZW1wbGF0ZUxpdFJlZyA9IC9gKD86XFxcXFtcXHNcXFNdfFxcJHsoPzpbXnt9XXx7KD86W157fV18e1tefV0qfSkqfSkqfXwoPyFcXCR7KVteXFxcXGBdKSpgL2c7XHJcbnZhciBzaW5nbGVRdW90ZVJlZyA9IC8nKD86XFxcXFtcXHNcXHdcIidcXFxcYF18W15cXG5cXHInXFxcXF0pKj8nL2c7XHJcbnZhciBkb3VibGVRdW90ZVJlZyA9IC9cIig/OlxcXFxbXFxzXFx3XCInXFxcXGBdfFteXFxuXFxyXCJcXFxcXSkqP1wiL2c7XHJcbi8qKiBFc2NhcGUgc3BlY2lhbCByZWd1bGFyIGV4cHJlc3Npb24gY2hhcmFjdGVycyBpbnNpZGUgYSBzdHJpbmcgKi9cclxuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHN0cmluZykge1xyXG4gICAgLy8gRnJvbSBNRE5cclxuICAgIHJldHVybiBzdHJpbmcucmVwbGFjZSgvWy4qK1xcLT9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKTsgLy8gJCYgbWVhbnMgdGhlIHdob2xlIG1hdGNoZWQgc3RyaW5nXHJcbn1cclxuZnVuY3Rpb24gcGFyc2Uoc3RyLCBjb25maWcpIHtcclxuICAgIHZhciBidWZmZXIgPSBbXTtcclxuICAgIHZhciB0cmltTGVmdE9mTmV4dFN0ciA9IGZhbHNlO1xyXG4gICAgdmFyIGxhc3RJbmRleCA9IDA7XHJcbiAgICB2YXIgcGFyc2VPcHRpb25zID0gY29uZmlnLnBhcnNlO1xyXG4gICAgaWYgKGNvbmZpZy5wbHVnaW5zKSB7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb25maWcucGx1Z2lucy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgcGx1Z2luID0gY29uZmlnLnBsdWdpbnNbaV07XHJcbiAgICAgICAgICAgIGlmIChwbHVnaW4ucHJvY2Vzc1RlbXBsYXRlKSB7XHJcbiAgICAgICAgICAgICAgICBzdHIgPSBwbHVnaW4ucHJvY2Vzc1RlbXBsYXRlKHN0ciwgY29uZmlnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8qIEFkZGluZyBmb3IgRUpTIGNvbXBhdGliaWxpdHkgKi9cclxuICAgIGlmIChjb25maWcucm1XaGl0ZXNwYWNlKSB7XHJcbiAgICAgICAgLy8gQ29kZSB0YWtlbiBkaXJlY3RseSBmcm9tIEVKU1xyXG4gICAgICAgIC8vIEhhdmUgdG8gdXNlIHR3byBzZXBhcmF0ZSByZXBsYWNlcyBoZXJlIGFzIGBeYCBhbmQgYCRgIG9wZXJhdG9ycyBkb24ndFxyXG4gICAgICAgIC8vIHdvcmsgd2VsbCB3aXRoIGBcXHJgIGFuZCBlbXB0eSBsaW5lcyBkb24ndCB3b3JrIHdlbGwgd2l0aCB0aGUgYG1gIGZsYWcuXHJcbiAgICAgICAgLy8gRXNzZW50aWFsbHksIHRoaXMgcmVwbGFjZXMgdGhlIHdoaXRlc3BhY2UgYXQgdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mXHJcbiAgICAgICAgLy8gZWFjaCBsaW5lIGFuZCByZW1vdmVzIG11bHRpcGxlIG5ld2xpbmVzLlxyXG4gICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9bXFxyXFxuXSsvZywgJ1xcbicpLnJlcGxhY2UoL15cXHMrfFxccyskL2dtLCAnJyk7XHJcbiAgICB9XHJcbiAgICAvKiBFbmQgcm1XaGl0ZXNwYWNlIG9wdGlvbiAqL1xyXG4gICAgdGVtcGxhdGVMaXRSZWcubGFzdEluZGV4ID0gMDtcclxuICAgIHNpbmdsZVF1b3RlUmVnLmxhc3RJbmRleCA9IDA7XHJcbiAgICBkb3VibGVRdW90ZVJlZy5sYXN0SW5kZXggPSAwO1xyXG4gICAgZnVuY3Rpb24gcHVzaFN0cmluZyhzdHJuZywgc2hvdWxkVHJpbVJpZ2h0T2ZTdHJpbmcpIHtcclxuICAgICAgICBpZiAoc3RybmcpIHtcclxuICAgICAgICAgICAgLy8gaWYgc3RyaW5nIGlzIHRydXRoeSBpdCBtdXN0IGJlIG9mIHR5cGUgJ3N0cmluZydcclxuICAgICAgICAgICAgc3RybmcgPSB0cmltV1Moc3RybmcsIGNvbmZpZywgdHJpbUxlZnRPZk5leHRTdHIsIC8vIHRoaXMgd2lsbCBvbmx5IGJlIGZhbHNlIG9uIHRoZSBmaXJzdCBzdHIsIHRoZSBuZXh0IG9uZXMgd2lsbCBiZSBudWxsIG9yIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICBzaG91bGRUcmltUmlnaHRPZlN0cmluZyk7XHJcbiAgICAgICAgICAgIGlmIChzdHJuZykge1xyXG4gICAgICAgICAgICAgICAgLy8gcmVwbGFjZSBcXCB3aXRoIFxcXFwsICcgd2l0aCBcXCdcclxuICAgICAgICAgICAgICAgIC8vIHdlJ3JlIGdvaW5nIHRvIGNvbnZlcnQgYWxsIENSTEYgdG8gTEYgc28gaXQgZG9lc24ndCB0YWtlIG1vcmUgdGhhbiBvbmUgcmVwbGFjZVxyXG4gICAgICAgICAgICAgICAgc3RybmcgPSBzdHJuZy5yZXBsYWNlKC9cXFxcfCcvZywgJ1xcXFwkJicpLnJlcGxhY2UoL1xcclxcbnxcXG58XFxyL2csICdcXFxcbicpO1xyXG4gICAgICAgICAgICAgICAgYnVmZmVyLnB1c2goc3RybmcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdmFyIHByZWZpeGVzID0gW3BhcnNlT3B0aW9ucy5leGVjLCBwYXJzZU9wdGlvbnMuaW50ZXJwb2xhdGUsIHBhcnNlT3B0aW9ucy5yYXddLnJlZHVjZShmdW5jdGlvbiAoYWNjdW11bGF0b3IsIHByZWZpeCkge1xyXG4gICAgICAgIGlmIChhY2N1bXVsYXRvciAmJiBwcmVmaXgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yICsgJ3wnICsgZXNjYXBlUmVnRXhwKHByZWZpeCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHByZWZpeCkge1xyXG4gICAgICAgICAgICAvLyBhY2N1bXVsYXRvciBpcyBmYWxzeVxyXG4gICAgICAgICAgICByZXR1cm4gZXNjYXBlUmVnRXhwKHByZWZpeCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBwcmVmaXggYW5kIGFjY3VtdWxhdG9yIGFyZSBib3RoIGZhbHN5XHJcbiAgICAgICAgICAgIHJldHVybiBhY2N1bXVsYXRvcjtcclxuICAgICAgICB9XHJcbiAgICB9LCAnJyk7XHJcbiAgICB2YXIgcGFyc2VPcGVuUmVnID0gbmV3IFJlZ0V4cCgnKFteXSo/KScgKyBlc2NhcGVSZWdFeHAoY29uZmlnLnRhZ3NbMF0pICsgJygtfF8pP1xcXFxzKignICsgcHJlZml4ZXMgKyAnKT9cXFxccyooPyFbXFxcXHMrXFxcXC1fJyArIHByZWZpeGVzICsgJ10pJywgJ2cnKTtcclxuICAgIHZhciBwYXJzZUNsb3NlUmVnID0gbmV3IFJlZ0V4cCgnXFwnfFwifGB8XFxcXC9cXFxcKnwoXFxcXHMqKC18Xyk/JyArIGVzY2FwZVJlZ0V4cChjb25maWcudGFnc1sxXSkgKyAnKScsICdnJyk7XHJcbiAgICAvLyBUT0RPOiBiZW5jaG1hcmsgaGF2aW5nIHRoZSBcXHMqIG9uIGVpdGhlciBzaWRlIHZzIHVzaW5nIHN0ci50cmltKClcclxuICAgIHZhciBtO1xyXG4gICAgd2hpbGUgKChtID0gcGFyc2VPcGVuUmVnLmV4ZWMoc3RyKSkpIHtcclxuICAgICAgICBsYXN0SW5kZXggPSBtWzBdLmxlbmd0aCArIG0uaW5kZXg7XHJcbiAgICAgICAgdmFyIHByZWNlZGluZ1N0cmluZyA9IG1bMV07XHJcbiAgICAgICAgdmFyIHdzTGVmdCA9IG1bMl07XHJcbiAgICAgICAgdmFyIHByZWZpeCA9IG1bM10gfHwgJyc7IC8vIGJ5IGRlZmF1bHQgZWl0aGVyIH4sID0sIG9yIGVtcHR5XHJcbiAgICAgICAgcHVzaFN0cmluZyhwcmVjZWRpbmdTdHJpbmcsIHdzTGVmdCk7XHJcbiAgICAgICAgcGFyc2VDbG9zZVJlZy5sYXN0SW5kZXggPSBsYXN0SW5kZXg7XHJcbiAgICAgICAgdmFyIGNsb3NlVGFnID0gdm9pZCAwO1xyXG4gICAgICAgIHZhciBjdXJyZW50T2JqID0gZmFsc2U7XHJcbiAgICAgICAgd2hpbGUgKChjbG9zZVRhZyA9IHBhcnNlQ2xvc2VSZWcuZXhlYyhzdHIpKSkge1xyXG4gICAgICAgICAgICBpZiAoY2xvc2VUYWdbMV0pIHtcclxuICAgICAgICAgICAgICAgIHZhciBjb250ZW50ID0gc3RyLnNsaWNlKGxhc3RJbmRleCwgY2xvc2VUYWcuaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgcGFyc2VPcGVuUmVnLmxhc3RJbmRleCA9IGxhc3RJbmRleCA9IHBhcnNlQ2xvc2VSZWcubGFzdEluZGV4O1xyXG4gICAgICAgICAgICAgICAgdHJpbUxlZnRPZk5leHRTdHIgPSBjbG9zZVRhZ1syXTtcclxuICAgICAgICAgICAgICAgIHZhciBjdXJyZW50VHlwZSA9IHByZWZpeCA9PT0gcGFyc2VPcHRpb25zLmV4ZWNcclxuICAgICAgICAgICAgICAgICAgICA/ICdlJ1xyXG4gICAgICAgICAgICAgICAgICAgIDogcHJlZml4ID09PSBwYXJzZU9wdGlvbnMucmF3XHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gJ3InXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogcHJlZml4ID09PSBwYXJzZU9wdGlvbnMuaW50ZXJwb2xhdGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gJ2knXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICcnO1xyXG4gICAgICAgICAgICAgICAgY3VycmVudE9iaiA9IHsgdDogY3VycmVudFR5cGUsIHZhbDogY29udGVudCB9O1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgY2hhciA9IGNsb3NlVGFnWzBdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGNoYXIgPT09ICcvKicpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29tbWVudENsb3NlSW5kID0gc3RyLmluZGV4T2YoJyovJywgcGFyc2VDbG9zZVJlZy5sYXN0SW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb21tZW50Q2xvc2VJbmQgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlRXJyKCd1bmNsb3NlZCBjb21tZW50Jywgc3RyLCBjbG9zZVRhZy5pbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlQ2xvc2VSZWcubGFzdEluZGV4ID0gY29tbWVudENsb3NlSW5kO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2hhciA9PT0gXCInXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICBzaW5nbGVRdW90ZVJlZy5sYXN0SW5kZXggPSBjbG9zZVRhZy5pbmRleDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2luZ2xlUXVvdGVNYXRjaCA9IHNpbmdsZVF1b3RlUmVnLmV4ZWMoc3RyKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2luZ2xlUXVvdGVNYXRjaCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZUNsb3NlUmVnLmxhc3RJbmRleCA9IHNpbmdsZVF1b3RlUmVnLmxhc3RJbmRleDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlRXJyKCd1bmNsb3NlZCBzdHJpbmcnLCBzdHIsIGNsb3NlVGFnLmluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChjaGFyID09PSAnXCInKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZG91YmxlUXVvdGVSZWcubGFzdEluZGV4ID0gY2xvc2VUYWcuaW5kZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRvdWJsZVF1b3RlTWF0Y2ggPSBkb3VibGVRdW90ZVJlZy5leGVjKHN0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvdWJsZVF1b3RlTWF0Y2gpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VDbG9zZVJlZy5sYXN0SW5kZXggPSBkb3VibGVRdW90ZVJlZy5sYXN0SW5kZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBQYXJzZUVycigndW5jbG9zZWQgc3RyaW5nJywgc3RyLCBjbG9zZVRhZy5pbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2hhciA9PT0gJ2AnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVMaXRSZWcubGFzdEluZGV4ID0gY2xvc2VUYWcuaW5kZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRlbXBsYXRlTGl0TWF0Y2ggPSB0ZW1wbGF0ZUxpdFJlZy5leGVjKHN0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXBsYXRlTGl0TWF0Y2gpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VDbG9zZVJlZy5sYXN0SW5kZXggPSB0ZW1wbGF0ZUxpdFJlZy5sYXN0SW5kZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBQYXJzZUVycigndW5jbG9zZWQgc3RyaW5nJywgc3RyLCBjbG9zZVRhZy5pbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjdXJyZW50T2JqKSB7XHJcbiAgICAgICAgICAgIGJ1ZmZlci5wdXNoKGN1cnJlbnRPYmopO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgUGFyc2VFcnIoJ3VuY2xvc2VkIHRhZycsIHN0ciwgbS5pbmRleCArIHByZWNlZGluZ1N0cmluZy5sZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHB1c2hTdHJpbmcoc3RyLnNsaWNlKGxhc3RJbmRleCwgc3RyLmxlbmd0aCksIGZhbHNlKTtcclxuICAgIGlmIChjb25maWcucGx1Z2lucykge1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29uZmlnLnBsdWdpbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdmFyIHBsdWdpbiA9IGNvbmZpZy5wbHVnaW5zW2ldO1xyXG4gICAgICAgICAgICBpZiAocGx1Z2luLnByb2Nlc3NBU1QpIHtcclxuICAgICAgICAgICAgICAgIGJ1ZmZlciA9IHBsdWdpbi5wcm9jZXNzQVNUKGJ1ZmZlciwgY29uZmlnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBidWZmZXI7XHJcbn1cblxuLyogRU5EIFRZUEVTICovXHJcbi8qKlxyXG4gKiBDb21waWxlcyBhIHRlbXBsYXRlIHN0cmluZyB0byBhIGZ1bmN0aW9uIHN0cmluZy4gTW9zdCBvZnRlbiB1c2VycyBqdXN0IHVzZSBgY29tcGlsZSgpYCwgd2hpY2ggY2FsbHMgYGNvbXBpbGVUb1N0cmluZ2AgYW5kIGNyZWF0ZXMgYSBuZXcgZnVuY3Rpb24gdXNpbmcgdGhlIHJlc3VsdFxyXG4gKlxyXG4gKiAqKkV4YW1wbGUqKlxyXG4gKlxyXG4gKiBgYGBqc1xyXG4gKiBjb21waWxlVG9TdHJpbmcoXCJIaSA8JT0gaXQudXNlciAlPlwiLCBldGEuY29uZmlnKVxyXG4gKiAvLyBcInZhciB0Uj0nJyxpbmNsdWRlPUUuaW5jbHVkZS5iaW5kKEUpLGluY2x1ZGVGaWxlPUUuaW5jbHVkZUZpbGUuYmluZChFKTt0Uis9J0hpICc7dFIrPUUuZShpdC51c2VyKTtpZihjYil7Y2IobnVsbCx0Uil9IHJldHVybiB0UlwiXHJcbiAqIGBgYFxyXG4gKi9cclxuZnVuY3Rpb24gY29tcGlsZVRvU3RyaW5nKHN0ciwgY29uZmlnKSB7XHJcbiAgICB2YXIgYnVmZmVyID0gcGFyc2Uoc3RyLCBjb25maWcpO1xyXG4gICAgdmFyIHJlcyA9IFwidmFyIHRSPScnLF9fbCxfX2xQXCIgK1xyXG4gICAgICAgIChjb25maWcuaW5jbHVkZSA/ICcsaW5jbHVkZT1FLmluY2x1ZGUuYmluZChFKScgOiAnJykgK1xyXG4gICAgICAgIChjb25maWcuaW5jbHVkZUZpbGUgPyAnLGluY2x1ZGVGaWxlPUUuaW5jbHVkZUZpbGUuYmluZChFKScgOiAnJykgK1xyXG4gICAgICAgICdcXG5mdW5jdGlvbiBsYXlvdXQocCxkKXtfX2w9cDtfX2xQPWR9XFxuJyArXHJcbiAgICAgICAgKGNvbmZpZy5nbG9iYWxBd2FpdCA/ICdjb25zdCBfcHJzID0gW107XFxuJyA6ICcnKSArXHJcbiAgICAgICAgKGNvbmZpZy51c2VXaXRoID8gJ3dpdGgoJyArIGNvbmZpZy52YXJOYW1lICsgJ3x8e30peycgOiAnJykgK1xyXG4gICAgICAgIGNvbXBpbGVTY29wZShidWZmZXIsIGNvbmZpZykgK1xyXG4gICAgICAgIChjb25maWcuaW5jbHVkZUZpbGVcclxuICAgICAgICAgICAgPyAnaWYoX19sKXRSPScgK1xyXG4gICAgICAgICAgICAgICAgKGNvbmZpZy5hc3luYyA/ICdhd2FpdCAnIDogJycpICtcclxuICAgICAgICAgICAgICAgIChcImluY2x1ZGVGaWxlKF9fbCxPYmplY3QuYXNzaWduKFwiICsgY29uZmlnLnZhck5hbWUgKyBcIix7Ym9keTp0Un0sX19sUCkpXFxuXCIpXHJcbiAgICAgICAgICAgIDogY29uZmlnLmluY2x1ZGVcclxuICAgICAgICAgICAgICAgID8gJ2lmKF9fbCl0Uj0nICtcclxuICAgICAgICAgICAgICAgICAgICAoY29uZmlnLmFzeW5jID8gJ2F3YWl0ICcgOiAnJykgK1xyXG4gICAgICAgICAgICAgICAgICAgIChcImluY2x1ZGUoX19sLE9iamVjdC5hc3NpZ24oXCIgKyBjb25maWcudmFyTmFtZSArIFwiLHtib2R5OnRSfSxfX2xQKSlcXG5cIilcclxuICAgICAgICAgICAgICAgIDogJycpICtcclxuICAgICAgICAnaWYoY2Ipe2NiKG51bGwsdFIpfSByZXR1cm4gdFInICtcclxuICAgICAgICAoY29uZmlnLnVzZVdpdGggPyAnfScgOiAnJyk7XHJcbiAgICBpZiAoY29uZmlnLnBsdWdpbnMpIHtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbmZpZy5wbHVnaW5zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBwbHVnaW4gPSBjb25maWcucGx1Z2luc1tpXTtcclxuICAgICAgICAgICAgaWYgKHBsdWdpbi5wcm9jZXNzRm5TdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgIHJlcyA9IHBsdWdpbi5wcm9jZXNzRm5TdHJpbmcocmVzLCBjb25maWcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlcztcclxufVxyXG4vKipcclxuICogTG9vcHMgdGhyb3VnaCB0aGUgQVNUIGdlbmVyYXRlZCBieSBgcGFyc2VgIGFuZCB0cmFuc2Zvcm0gZWFjaCBpdGVtIGludG8gSlMgY2FsbHNcclxuICpcclxuICogKipFeGFtcGxlKipcclxuICpcclxuICogYGBganNcclxuICogLy8gQVNUIHZlcnNpb24gb2YgJ0hpIDwlPSBpdC51c2VyICU+J1xyXG4gKiBsZXQgdGVtcGxhdGVBU1QgPSBbJ0hpICcsIHsgdmFsOiAnaXQudXNlcicsIHQ6ICdpJyB9XVxyXG4gKiBjb21waWxlU2NvcGUodGVtcGxhdGVBU1QsIGV0YS5jb25maWcpXHJcbiAqIC8vIFwidFIrPSdIaSAnO3RSKz1FLmUoaXQudXNlcik7XCJcclxuICogYGBgXHJcbiAqL1xyXG5mdW5jdGlvbiBjb21waWxlU2NvcGUoYnVmZiwgY29uZmlnKSB7XHJcbiAgICB2YXIgaTtcclxuICAgIHZhciBidWZmTGVuZ3RoID0gYnVmZi5sZW5ndGg7XHJcbiAgICB2YXIgcmV0dXJuU3RyID0gJyc7XHJcbiAgICB2YXIgUkVQTEFDRU1FTlRfU1RSID0gXCJySjJLcVh6eFFnXCI7XHJcbiAgICBmb3IgKGkgPSAwOyBpIDwgYnVmZkxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgdmFyIGN1cnJlbnRCbG9jayA9IGJ1ZmZbaV07XHJcbiAgICAgICAgaWYgKHR5cGVvZiBjdXJyZW50QmxvY2sgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIHZhciBzdHIgPSBjdXJyZW50QmxvY2s7XHJcbiAgICAgICAgICAgIC8vIHdlIGtub3cgc3RyaW5nIGV4aXN0c1xyXG4gICAgICAgICAgICByZXR1cm5TdHIgKz0gXCJ0Uis9J1wiICsgc3RyICsgXCInXFxuXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgdHlwZSA9IGN1cnJlbnRCbG9jay50OyAvLyB+LCBzLCAhLCA/LCByXHJcbiAgICAgICAgICAgIHZhciBjb250ZW50ID0gY3VycmVudEJsb2NrLnZhbCB8fCAnJztcclxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdyJykge1xyXG4gICAgICAgICAgICAgICAgLy8gcmF3XHJcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLmdsb2JhbEF3YWl0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuU3RyICs9IFwiX3Bycy5wdXNoKFwiICsgY29udGVudCArIFwiKTtcXG5cIjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm5TdHIgKz0gXCJ0Uis9J1wiICsgUkVQTEFDRU1FTlRfU1RSICsgXCInXFxuXCI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29uZmlnLmZpbHRlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gJ0UuZmlsdGVyKCcgKyBjb250ZW50ICsgJyknO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm5TdHIgKz0gJ3RSKz0nICsgY29udGVudCArICdcXG4nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICdpJykge1xyXG4gICAgICAgICAgICAgICAgLy8gaW50ZXJwb2xhdGVcclxuICAgICAgICAgICAgICAgIGlmIChjb25maWcuZ2xvYmFsQXdhaXQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm5TdHIgKz0gXCJfcHJzLnB1c2goXCIgKyBjb250ZW50ICsgXCIpO1xcblwiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblN0ciArPSBcInRSKz0nXCIgKyBSRVBMQUNFTUVOVF9TVFIgKyBcIidcXG5cIjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb25maWcuZmlsdGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSAnRS5maWx0ZXIoJyArIGNvbnRlbnQgKyAnKSc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblN0ciArPSAndFIrPScgKyBjb250ZW50ICsgJ1xcbic7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbmZpZy5hdXRvRXNjYXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSAnRS5lKCcgKyBjb250ZW50ICsgJyknO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm5TdHIgKz0gJ3RSKz0nICsgY29udGVudCArICdcXG4nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICdlJykge1xyXG4gICAgICAgICAgICAgICAgLy8gZXhlY3V0ZVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuU3RyICs9IGNvbnRlbnQgKyAnXFxuJzsgLy8geW91IG5lZWQgYSBcXG4gaW4gY2FzZSB5b3UgaGF2ZSA8JSB9ICU+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoY29uZmlnLmdsb2JhbEF3YWl0KSB7XHJcbiAgICAgICAgcmV0dXJuU3RyICs9IFwiY29uc3QgX3JzdCA9IGF3YWl0IFByb21pc2UuYWxsKF9wcnMpO1xcbnRSID0gdFIucmVwbGFjZSgvXCIgKyBSRVBMQUNFTUVOVF9TVFIgKyBcIi9nLCAoKSA9PiBfcnN0LnNoaWZ0KCkpO1xcblwiO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJldHVyblN0cjtcclxufVxuXG4vKipcclxuICogSGFuZGxlcyBzdG9yYWdlIGFuZCBhY2Nlc3Npbmcgb2YgdmFsdWVzXHJcbiAqXHJcbiAqIEluIHRoaXMgY2FzZSwgd2UgdXNlIGl0IHRvIHN0b3JlIGNvbXBpbGVkIHRlbXBsYXRlIGZ1bmN0aW9uc1xyXG4gKiBJbmRleGVkIGJ5IHRoZWlyIGBuYW1lYCBvciBgZmlsZW5hbWVgXHJcbiAqL1xyXG52YXIgQ2FjaGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gQ2FjaGVyKGNhY2hlKSB7XHJcbiAgICAgICAgdGhpcy5jYWNoZSA9IGNhY2hlO1xyXG4gICAgfVxyXG4gICAgQ2FjaGVyLnByb3RvdHlwZS5kZWZpbmUgPSBmdW5jdGlvbiAoa2V5LCB2YWwpIHtcclxuICAgICAgICB0aGlzLmNhY2hlW2tleV0gPSB2YWw7XHJcbiAgICB9O1xyXG4gICAgQ2FjaGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgLy8gc3RyaW5nIHwgYXJyYXkuXHJcbiAgICAgICAgLy8gVE9ETzogYWxsb3cgYXJyYXkgb2Yga2V5cyB0byBsb29rIGRvd25cclxuICAgICAgICAvLyBUT0RPOiBjcmVhdGUgcGx1Z2luIHRvIGFsbG93IHJlZmVyZW5jaW5nIGhlbHBlcnMsIGZpbHRlcnMgd2l0aCBkb3Qgbm90YXRpb25cclxuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVtrZXldO1xyXG4gICAgfTtcclxuICAgIENhY2hlci5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLmNhY2hlW2tleV07XHJcbiAgICB9O1xyXG4gICAgQ2FjaGVyLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmNhY2hlID0ge307XHJcbiAgICB9O1xyXG4gICAgQ2FjaGVyLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKGNhY2hlT2JqKSB7XHJcbiAgICAgICAgY29weVByb3BzKHRoaXMuY2FjaGUsIGNhY2hlT2JqKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gQ2FjaGVyO1xyXG59KCkpO1xuXG4vKiBFTkQgVFlQRVMgKi9cclxuLyoqXHJcbiAqIEV0YSdzIHRlbXBsYXRlIHN0b3JhZ2VcclxuICpcclxuICogU3RvcmVzIHBhcnRpYWxzIGFuZCBjYWNoZWQgdGVtcGxhdGVzXHJcbiAqL1xyXG52YXIgdGVtcGxhdGVzID0gbmV3IENhY2hlcih7fSk7XG5cbi8qIEVORCBUWVBFUyAqL1xyXG4vKipcclxuICogSW5jbHVkZSBhIHRlbXBsYXRlIGJhc2VkIG9uIGl0cyBuYW1lIChvciBmaWxlcGF0aCwgaWYgaXQncyBhbHJlYWR5IGJlZW4gY2FjaGVkKS5cclxuICpcclxuICogQ2FsbGVkIGxpa2UgYGluY2x1ZGUodGVtcGxhdGVOYW1lT3JQYXRoLCBkYXRhKWBcclxuICovXHJcbmZ1bmN0aW9uIGluY2x1ZGVIZWxwZXIodGVtcGxhdGVOYW1lT3JQYXRoLCBkYXRhKSB7XHJcbiAgICB2YXIgdGVtcGxhdGUgPSB0aGlzLnRlbXBsYXRlcy5nZXQodGVtcGxhdGVOYW1lT3JQYXRoKTtcclxuICAgIGlmICghdGVtcGxhdGUpIHtcclxuICAgICAgICB0aHJvdyBFdGFFcnIoJ0NvdWxkIG5vdCBmZXRjaCB0ZW1wbGF0ZSBcIicgKyB0ZW1wbGF0ZU5hbWVPclBhdGggKyAnXCInKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0ZW1wbGF0ZShkYXRhLCB0aGlzKTtcclxufVxyXG4vKiogRXRhJ3MgYmFzZSAoZ2xvYmFsKSBjb25maWd1cmF0aW9uICovXHJcbnZhciBjb25maWcgPSB7XHJcbiAgICBhc3luYzogZmFsc2UsXHJcbiAgICBhdXRvRXNjYXBlOiB0cnVlLFxyXG4gICAgYXV0b1RyaW06IFtmYWxzZSwgJ25sJ10sXHJcbiAgICBjYWNoZTogZmFsc2UsXHJcbiAgICBlOiBYTUxFc2NhcGUsXHJcbiAgICBpbmNsdWRlOiBpbmNsdWRlSGVscGVyLFxyXG4gICAgcGFyc2U6IHtcclxuICAgICAgICBleGVjOiAnJyxcclxuICAgICAgICBpbnRlcnBvbGF0ZTogJz0nLFxyXG4gICAgICAgIHJhdzogJ34nXHJcbiAgICB9LFxyXG4gICAgcGx1Z2luczogW10sXHJcbiAgICBybVdoaXRlc3BhY2U6IGZhbHNlLFxyXG4gICAgdGFnczogWyc8JScsICclPiddLFxyXG4gICAgdGVtcGxhdGVzOiB0ZW1wbGF0ZXMsXHJcbiAgICB1c2VXaXRoOiBmYWxzZSxcclxuICAgIHZhck5hbWU6ICdpdCdcclxufTtcclxuLyoqXHJcbiAqIFRha2VzIG9uZSBvciB0d28gcGFydGlhbCAobm90IG5lY2Vzc2FyaWx5IGNvbXBsZXRlKSBjb25maWd1cmF0aW9uIG9iamVjdHMsIG1lcmdlcyB0aGVtIDEgbGF5ZXIgZGVlcCBpbnRvIGV0YS5jb25maWcsIGFuZCByZXR1cm5zIHRoZSByZXN1bHRcclxuICpcclxuICogQHBhcmFtIG92ZXJyaWRlIFBhcnRpYWwgY29uZmlndXJhdGlvbiBvYmplY3RcclxuICogQHBhcmFtIGJhc2VDb25maWcgUGFydGlhbCBjb25maWd1cmF0aW9uIG9iamVjdCB0byBtZXJnZSBiZWZvcmUgYG92ZXJyaWRlYFxyXG4gKlxyXG4gKiAqKkV4YW1wbGUqKlxyXG4gKlxyXG4gKiBgYGBqc1xyXG4gKiBsZXQgY3VzdG9tQ29uZmlnID0gZ2V0Q29uZmlnKHt0YWdzOiBbJyEjJywgJyMhJ119KVxyXG4gKiBgYGBcclxuICovXHJcbmZ1bmN0aW9uIGdldENvbmZpZyhvdmVycmlkZSwgYmFzZUNvbmZpZykge1xyXG4gICAgLy8gVE9ETzogcnVuIG1vcmUgdGVzdHMgb24gdGhpc1xyXG4gICAgdmFyIHJlcyA9IHt9OyAvLyBMaW5rZWRcclxuICAgIGNvcHlQcm9wcyhyZXMsIGNvbmZpZyk7IC8vIENyZWF0ZXMgZGVlcCBjbG9uZSBvZiBldGEuY29uZmlnLCAxIGxheWVyIGRlZXBcclxuICAgIGlmIChiYXNlQ29uZmlnKSB7XHJcbiAgICAgICAgY29weVByb3BzKHJlcywgYmFzZUNvbmZpZyk7XHJcbiAgICB9XHJcbiAgICBpZiAob3ZlcnJpZGUpIHtcclxuICAgICAgICBjb3B5UHJvcHMocmVzLCBvdmVycmlkZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzO1xyXG59XHJcbi8qKiBVcGRhdGUgRXRhJ3MgYmFzZSBjb25maWcgKi9cclxuZnVuY3Rpb24gY29uZmlndXJlKG9wdGlvbnMpIHtcclxuICAgIHJldHVybiBjb3B5UHJvcHMoY29uZmlnLCBvcHRpb25zKTtcclxufVxuXG4vKiBFTkQgVFlQRVMgKi9cclxuLyoqXHJcbiAqIFRha2VzIGEgdGVtcGxhdGUgc3RyaW5nIGFuZCByZXR1cm5zIGEgdGVtcGxhdGUgZnVuY3Rpb24gdGhhdCBjYW4gYmUgY2FsbGVkIHdpdGggKGRhdGEsIGNvbmZpZywgW2NiXSlcclxuICpcclxuICogQHBhcmFtIHN0ciAtIFRoZSB0ZW1wbGF0ZSBzdHJpbmdcclxuICogQHBhcmFtIGNvbmZpZyAtIEEgY3VzdG9tIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChvcHRpb25hbClcclxuICpcclxuICogKipFeGFtcGxlKipcclxuICpcclxuICogYGBganNcclxuICogbGV0IGNvbXBpbGVkRm4gPSBldGEuY29tcGlsZShcIkhpIDwlPSBpdC51c2VyICU+XCIpXHJcbiAqIC8vIGZ1bmN0aW9uIGFub255bW91cygpXHJcbiAqIGxldCBjb21waWxlZEZuU3RyID0gY29tcGlsZWRGbi50b1N0cmluZygpXHJcbiAqIC8vIFwiZnVuY3Rpb24gYW5vbnltb3VzKGl0LEUsY2JcXG4pIHtcXG52YXIgdFI9JycsaW5jbHVkZT1FLmluY2x1ZGUuYmluZChFKSxpbmNsdWRlRmlsZT1FLmluY2x1ZGVGaWxlLmJpbmQoRSk7dFIrPSdIaSAnO3RSKz1FLmUoaXQudXNlcik7aWYoY2Ipe2NiKG51bGwsdFIpfSByZXR1cm4gdFJcXG59XCJcclxuICogYGBgXHJcbiAqL1xyXG5mdW5jdGlvbiBjb21waWxlKHN0ciwgY29uZmlnKSB7XHJcbiAgICB2YXIgb3B0aW9ucyA9IGdldENvbmZpZyhjb25maWcgfHwge30pO1xyXG4gICAgLyogQVNZTkMgSEFORExJTkcgKi9cclxuICAgIC8vIFRoZSBiZWxvdyBjb2RlIGlzIG1vZGlmaWVkIGZyb20gbWRlL2Vqcy4gQWxsIGNyZWRpdCBzaG91bGQgZ28gdG8gdGhlbS5cclxuICAgIHZhciBjdG9yID0gb3B0aW9ucy5hc3luYyA/IGdldEFzeW5jRnVuY3Rpb25Db25zdHJ1Y3RvcigpIDogRnVuY3Rpb247XHJcbiAgICAvKiBFTkQgQVNZTkMgSEFORExJTkcgKi9cclxuICAgIHRyeSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBjdG9yKG9wdGlvbnMudmFyTmFtZSwgJ0UnLCAvLyBFdGFDb25maWdcclxuICAgICAgICAnY2InLCAvLyBvcHRpb25hbCBjYWxsYmFja1xyXG4gICAgICAgIGNvbXBpbGVUb1N0cmluZyhzdHIsIG9wdGlvbnMpKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXctZnVuY1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFN5bnRheEVycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IEV0YUVycignQmFkIHRlbXBsYXRlIHN5bnRheFxcblxcbicgK1xyXG4gICAgICAgICAgICAgICAgZS5tZXNzYWdlICtcclxuICAgICAgICAgICAgICAgICdcXG4nICtcclxuICAgICAgICAgICAgICAgIEFycmF5KGUubWVzc2FnZS5sZW5ndGggKyAxKS5qb2luKCc9JykgK1xyXG4gICAgICAgICAgICAgICAgJ1xcbicgK1xyXG4gICAgICAgICAgICAgICAgY29tcGlsZVRvU3RyaW5nKHN0ciwgb3B0aW9ucykgK1xyXG4gICAgICAgICAgICAgICAgJ1xcbicgLy8gVGhpcyB3aWxsIHB1dCBhbiBleHRyYSBuZXdsaW5lIGJlZm9yZSB0aGUgY2FsbHN0YWNrIGZvciBleHRyYSByZWFkYWJpbGl0eVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cblxudmFyIF9CT00gPSAvXlxcdUZFRkYvO1xyXG4vKiBFTkQgVFlQRVMgKi9cclxuLyoqXHJcbiAqIEdldCB0aGUgcGF0aCB0byB0aGUgaW5jbHVkZWQgZmlsZSBmcm9tIHRoZSBwYXJlbnQgZmlsZSBwYXRoIGFuZCB0aGVcclxuICogc3BlY2lmaWVkIHBhdGguXHJcbiAqXHJcbiAqIElmIGBuYW1lYCBkb2VzIG5vdCBoYXZlIGFuIGV4dGVuc2lvbiwgaXQgd2lsbCBkZWZhdWx0IHRvIGAuZXRhYFxyXG4gKlxyXG4gKiBAcGFyYW0gbmFtZSBzcGVjaWZpZWQgcGF0aFxyXG4gKiBAcGFyYW0gcGFyZW50ZmlsZSBwYXJlbnQgZmlsZSBwYXRoXHJcbiAqIEBwYXJhbSBpc0RpcmVjdG9yeSB3aGV0aGVyIHBhcmVudGZpbGUgaXMgYSBkaXJlY3RvcnlcclxuICogQHJldHVybiBhYnNvbHV0ZSBwYXRoIHRvIHRlbXBsYXRlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRXaG9sZUZpbGVQYXRoKG5hbWUsIHBhcmVudGZpbGUsIGlzRGlyZWN0b3J5KSB7XHJcbiAgICB2YXIgaW5jbHVkZVBhdGggPSByZXNvbHZlKGlzRGlyZWN0b3J5ID8gcGFyZW50ZmlsZSA6IGRpcm5hbWUocGFyZW50ZmlsZSksIC8vIHJldHVybnMgZGlyZWN0b3J5IHRoZSBwYXJlbnQgZmlsZSBpcyBpblxyXG4gICAgbmFtZSAvLyBmaWxlXHJcbiAgICApICsgKGV4dG5hbWUobmFtZSkgPyAnJyA6ICcuZXRhJyk7XHJcbiAgICByZXR1cm4gaW5jbHVkZVBhdGg7XHJcbn1cclxuLyoqXHJcbiAqIEdldCB0aGUgYWJzb2x1dGUgcGF0aCB0byBhbiBpbmNsdWRlZCB0ZW1wbGF0ZVxyXG4gKlxyXG4gKiBJZiB0aGlzIGlzIGNhbGxlZCB3aXRoIGFuIGFic29sdXRlIHBhdGggKGZvciBleGFtcGxlLCBzdGFydGluZyB3aXRoICcvJyBvciAnQzpcXCcpXHJcbiAqIHRoZW4gRXRhIHdpbGwgYXR0ZW1wdCB0byByZXNvbHZlIHRoZSBhYnNvbHV0ZSBwYXRoIHdpdGhpbiBvcHRpb25zLnZpZXdzLiBJZiBpdCBjYW5ub3QsXHJcbiAqIEV0YSB3aWxsIGZhbGxiYWNrIHRvIG9wdGlvbnMucm9vdCBvciAnLydcclxuICpcclxuICogSWYgdGhpcyBpcyBjYWxsZWQgd2l0aCBhIHJlbGF0aXZlIHBhdGgsIEV0YSB3aWxsOlxyXG4gKiAtIExvb2sgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgdGVtcGxhdGUgKGlmIHRoZSBjdXJyZW50IHRlbXBsYXRlIGhhcyB0aGUgYGZpbGVuYW1lYCBwcm9wZXJ0eSlcclxuICogLSBMb29rIGluc2lkZSBlYWNoIGRpcmVjdG9yeSBpbiBvcHRpb25zLnZpZXdzXHJcbiAqXHJcbiAqIE5vdGU6IGlmIEV0YSBpcyB1bmFibGUgdG8gZmluZCBhIHRlbXBsYXRlIHVzaW5nIHBhdGggYW5kIG9wdGlvbnMsIGl0IHdpbGwgdGhyb3cgYW4gZXJyb3IuXHJcbiAqXHJcbiAqIEBwYXJhbSBwYXRoICAgIHNwZWNpZmllZCBwYXRoXHJcbiAqIEBwYXJhbSBvcHRpb25zIGNvbXBpbGF0aW9uIG9wdGlvbnNcclxuICogQHJldHVybiBhYnNvbHV0ZSBwYXRoIHRvIHRlbXBsYXRlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRQYXRoKHBhdGgsIG9wdGlvbnMpIHtcclxuICAgIHZhciBpbmNsdWRlUGF0aCA9IGZhbHNlO1xyXG4gICAgdmFyIHZpZXdzID0gb3B0aW9ucy52aWV3cztcclxuICAgIHZhciBzZWFyY2hlZFBhdGhzID0gW107XHJcbiAgICAvLyBJZiB0aGVzZSBmb3VyIHZhbHVlcyBhcmUgdGhlIHNhbWUsXHJcbiAgICAvLyBnZXRQYXRoKCkgd2lsbCByZXR1cm4gdGhlIHNhbWUgcmVzdWx0IGV2ZXJ5IHRpbWUuXHJcbiAgICAvLyBXZSBjYW4gY2FjaGUgdGhlIHJlc3VsdCB0byBhdm9pZCBleHBlbnNpdmVcclxuICAgIC8vIGZpbGUgb3BlcmF0aW9ucy5cclxuICAgIHZhciBwYXRoT3B0aW9ucyA9IEpTT04uc3RyaW5naWZ5KHtcclxuICAgICAgICBmaWxlbmFtZTogb3B0aW9ucy5maWxlbmFtZSxcclxuICAgICAgICBwYXRoOiBwYXRoLFxyXG4gICAgICAgIHJvb3Q6IG9wdGlvbnMucm9vdCxcclxuICAgICAgICB2aWV3czogb3B0aW9ucy52aWV3c1xyXG4gICAgfSk7XHJcbiAgICBpZiAob3B0aW9ucy5jYWNoZSAmJiBvcHRpb25zLmZpbGVwYXRoQ2FjaGUgJiYgb3B0aW9ucy5maWxlcGF0aENhY2hlW3BhdGhPcHRpb25zXSkge1xyXG4gICAgICAgIC8vIFVzZSB0aGUgY2FjaGVkIGZpbGVwYXRoXHJcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuZmlsZXBhdGhDYWNoZVtwYXRoT3B0aW9uc107XHJcbiAgICB9XHJcbiAgICAvKiogQWRkIGEgZmlsZXBhdGggdG8gdGhlIGxpc3Qgb2YgcGF0aHMgd2UndmUgY2hlY2tlZCBmb3IgYSB0ZW1wbGF0ZSAqL1xyXG4gICAgZnVuY3Rpb24gYWRkUGF0aFRvU2VhcmNoZWQocGF0aFNlYXJjaGVkKSB7XHJcbiAgICAgICAgaWYgKCFzZWFyY2hlZFBhdGhzLmluY2x1ZGVzKHBhdGhTZWFyY2hlZCkpIHtcclxuICAgICAgICAgICAgc2VhcmNoZWRQYXRocy5wdXNoKHBhdGhTZWFyY2hlZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBUYWtlIGEgZmlsZXBhdGggKGxpa2UgJ3BhcnRpYWxzL215cGFydGlhbC5ldGEnKS4gQXR0ZW1wdCB0byBmaW5kIHRoZSB0ZW1wbGF0ZSBmaWxlIGluc2lkZSBgdmlld3NgO1xyXG4gICAgICogcmV0dXJuIHRoZSByZXN1bHRpbmcgdGVtcGxhdGUgZmlsZSBwYXRoLCBvciBgZmFsc2VgIHRvIGluZGljYXRlIHRoYXQgdGhlIHRlbXBsYXRlIHdhcyBub3QgZm91bmQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHZpZXdzIHRoZSBmaWxlcGF0aCB0aGF0IGhvbGRzIHRlbXBsYXRlcywgb3IgYW4gYXJyYXkgb2YgZmlsZXBhdGhzIHRoYXQgaG9sZCB0ZW1wbGF0ZXNcclxuICAgICAqIEBwYXJhbSBwYXRoIHRoZSBwYXRoIHRvIHRoZSB0ZW1wbGF0ZVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBzZWFyY2hWaWV3cyh2aWV3cywgcGF0aCkge1xyXG4gICAgICAgIHZhciBmaWxlUGF0aDtcclxuICAgICAgICAvLyBJZiB2aWV3cyBpcyBhbiBhcnJheSwgdGhlbiBsb29wIHRocm91Z2ggZWFjaCBkaXJlY3RvcnlcclxuICAgICAgICAvLyBBbmQgYXR0ZW1wdCB0byBmaW5kIHRoZSB0ZW1wbGF0ZVxyXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZpZXdzKSAmJlxyXG4gICAgICAgICAgICB2aWV3cy5zb21lKGZ1bmN0aW9uICh2KSB7XHJcbiAgICAgICAgICAgICAgICBmaWxlUGF0aCA9IGdldFdob2xlRmlsZVBhdGgocGF0aCwgdiwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICBhZGRQYXRoVG9TZWFyY2hlZChmaWxlUGF0aCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZXhpc3RzU3luYyhmaWxlUGF0aCk7XHJcbiAgICAgICAgICAgIH0pKSB7XHJcbiAgICAgICAgICAgIC8vIElmIHRoZSBhYm92ZSByZXR1cm5lZCB0cnVlLCB3ZSBrbm93IHRoYXQgdGhlIGZpbGVQYXRoIHdhcyBqdXN0IHNldCB0byBhIHBhdGhcclxuICAgICAgICAgICAgLy8gVGhhdCBleGlzdHMgKEFycmF5LnNvbWUoKSByZXR1cm5zIGFzIHNvb24gYXMgaXQgZmluZHMgYSB2YWxpZCBlbGVtZW50KVxyXG4gICAgICAgICAgICByZXR1cm4gZmlsZVBhdGg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2aWV3cyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgLy8gU2VhcmNoIGZvciB0aGUgZmlsZSBpZiB2aWV3cyBpcyBhIHNpbmdsZSBkaXJlY3RvcnlcclxuICAgICAgICAgICAgZmlsZVBhdGggPSBnZXRXaG9sZUZpbGVQYXRoKHBhdGgsIHZpZXdzLCB0cnVlKTtcclxuICAgICAgICAgICAgYWRkUGF0aFRvU2VhcmNoZWQoZmlsZVBhdGgpO1xyXG4gICAgICAgICAgICBpZiAoZXhpc3RzU3luYyhmaWxlUGF0aCkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBVbmFibGUgdG8gZmluZCBhIGZpbGVcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICAvLyBQYXRoIHN0YXJ0cyB3aXRoICcvJywgJ0M6XFwnLCBldGMuXHJcbiAgICB2YXIgbWF0Y2ggPSAvXltBLVphLXpdKzpcXFxcfF5cXC8vLmV4ZWMocGF0aCk7XHJcbiAgICAvLyBBYnNvbHV0ZSBwYXRoLCBsaWtlIC9wYXJ0aWFscy9wYXJ0aWFsLmV0YVxyXG4gICAgaWYgKG1hdGNoICYmIG1hdGNoLmxlbmd0aCkge1xyXG4gICAgICAgIC8vIFdlIGhhdmUgdG8gdHJpbSB0aGUgYmVnaW5uaW5nICcvJyBvZmYgdGhlIHBhdGgsIG9yIGVsc2VcclxuICAgICAgICAvLyBwYXRoLnJlc29sdmUoZGlyLCBwYXRoKSB3aWxsIGFsd2F5cyByZXNvbHZlIHRvIGp1c3QgcGF0aFxyXG4gICAgICAgIHZhciBmb3JtYXR0ZWRQYXRoID0gcGF0aC5yZXBsYWNlKC9eXFwvKi8sICcnKTtcclxuICAgICAgICAvLyBGaXJzdCwgdHJ5IHRvIHJlc29sdmUgdGhlIHBhdGggd2l0aGluIG9wdGlvbnMudmlld3NcclxuICAgICAgICBpbmNsdWRlUGF0aCA9IHNlYXJjaFZpZXdzKHZpZXdzLCBmb3JtYXR0ZWRQYXRoKTtcclxuICAgICAgICBpZiAoIWluY2x1ZGVQYXRoKSB7XHJcbiAgICAgICAgICAgIC8vIElmIHRoYXQgZmFpbHMsIHNlYXJjaFZpZXdzIHdpbGwgcmV0dXJuIGZhbHNlLiBUcnkgdG8gZmluZCB0aGUgcGF0aFxyXG4gICAgICAgICAgICAvLyBpbnNpZGUgb3B0aW9ucy5yb290IChieSBkZWZhdWx0ICcvJywgdGhlIGJhc2Ugb2YgdGhlIGZpbGVzeXN0ZW0pXHJcbiAgICAgICAgICAgIHZhciBwYXRoRnJvbVJvb3QgPSBnZXRXaG9sZUZpbGVQYXRoKGZvcm1hdHRlZFBhdGgsIG9wdGlvbnMucm9vdCB8fCAnLycsIHRydWUpO1xyXG4gICAgICAgICAgICBhZGRQYXRoVG9TZWFyY2hlZChwYXRoRnJvbVJvb3QpO1xyXG4gICAgICAgICAgICBpbmNsdWRlUGF0aCA9IHBhdGhGcm9tUm9vdDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICAvLyBSZWxhdGl2ZSBwYXRoc1xyXG4gICAgICAgIC8vIExvb2sgcmVsYXRpdmUgdG8gYSBwYXNzZWQgZmlsZW5hbWUgZmlyc3RcclxuICAgICAgICBpZiAob3B0aW9ucy5maWxlbmFtZSkge1xyXG4gICAgICAgICAgICB2YXIgZmlsZVBhdGggPSBnZXRXaG9sZUZpbGVQYXRoKHBhdGgsIG9wdGlvbnMuZmlsZW5hbWUpO1xyXG4gICAgICAgICAgICBhZGRQYXRoVG9TZWFyY2hlZChmaWxlUGF0aCk7XHJcbiAgICAgICAgICAgIGlmIChleGlzdHNTeW5jKGZpbGVQYXRoKSkge1xyXG4gICAgICAgICAgICAgICAgaW5jbHVkZVBhdGggPSBmaWxlUGF0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBUaGVuIGxvb2sgZm9yIHRoZSB0ZW1wbGF0ZSBpbiBvcHRpb25zLnZpZXdzXHJcbiAgICAgICAgaWYgKCFpbmNsdWRlUGF0aCkge1xyXG4gICAgICAgICAgICBpbmNsdWRlUGF0aCA9IHNlYXJjaFZpZXdzKHZpZXdzLCBwYXRoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFpbmNsdWRlUGF0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBFdGFFcnIoJ0NvdWxkIG5vdCBmaW5kIHRoZSB0ZW1wbGF0ZSBcIicgKyBwYXRoICsgJ1wiLiBQYXRocyB0cmllZDogJyArIHNlYXJjaGVkUGF0aHMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIElmIGNhY2hpbmcgYW5kIGZpbGVwYXRoQ2FjaGUgYXJlIGVuYWJsZWQsXHJcbiAgICAvLyBjYWNoZSB0aGUgaW5wdXQgJiBvdXRwdXQgb2YgdGhpcyBmdW5jdGlvbi5cclxuICAgIGlmIChvcHRpb25zLmNhY2hlICYmIG9wdGlvbnMuZmlsZXBhdGhDYWNoZSkge1xyXG4gICAgICAgIG9wdGlvbnMuZmlsZXBhdGhDYWNoZVtwYXRoT3B0aW9uc10gPSBpbmNsdWRlUGF0aDtcclxuICAgIH1cclxuICAgIHJldHVybiBpbmNsdWRlUGF0aDtcclxufVxyXG4vKipcclxuICogUmVhZHMgYSBmaWxlIHN5bmNocm9ub3VzbHlcclxuICovXHJcbmZ1bmN0aW9uIHJlYWRGaWxlKGZpbGVQYXRoKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHJldHVybiByZWFkRmlsZVN5bmMoZmlsZVBhdGgpLnRvU3RyaW5nKCkucmVwbGFjZShfQk9NLCAnJyk7IC8vIFRPRE86IGlzIHJlcGxhY2luZyBCT00ncyBuZWNlc3Nhcnk/XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoX2EpIHtcclxuICAgICAgICB0aHJvdyBFdGFFcnIoXCJGYWlsZWQgdG8gcmVhZCB0ZW1wbGF0ZSBhdCAnXCIgKyBmaWxlUGF0aCArIFwiJ1wiKTtcclxuICAgIH1cclxufVxuXG4vLyBleHByZXNzIGlzIHNldCBsaWtlOiBhcHAuZW5naW5lKCdodG1sJywgcmVxdWlyZSgnZXRhJykucmVuZGVyRmlsZSlcclxuLyogRU5EIFRZUEVTICovXHJcbi8qKlxyXG4gKiBSZWFkcyBhIHRlbXBsYXRlLCBjb21waWxlcyBpdCBpbnRvIGEgZnVuY3Rpb24sIGNhY2hlcyBpdCBpZiBjYWNoaW5nIGlzbid0IGRpc2FibGVkLCByZXR1cm5zIHRoZSBmdW5jdGlvblxyXG4gKlxyXG4gKiBAcGFyYW0gZmlsZVBhdGggQWJzb2x1dGUgcGF0aCB0byB0ZW1wbGF0ZSBmaWxlXHJcbiAqIEBwYXJhbSBvcHRpb25zIEV0YSBjb25maWd1cmF0aW9uIG92ZXJyaWRlc1xyXG4gKiBAcGFyYW0gbm9DYWNoZSBPcHRpb25hbGx5LCBtYWtlIEV0YSBub3QgY2FjaGUgdGhlIHRlbXBsYXRlXHJcbiAqL1xyXG5mdW5jdGlvbiBsb2FkRmlsZShmaWxlUGF0aCwgb3B0aW9ucywgbm9DYWNoZSkge1xyXG4gICAgdmFyIGNvbmZpZyA9IGdldENvbmZpZyhvcHRpb25zKTtcclxuICAgIHZhciB0ZW1wbGF0ZSA9IHJlYWRGaWxlKGZpbGVQYXRoKTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgdmFyIGNvbXBpbGVkVGVtcGxhdGUgPSBjb21waWxlKHRlbXBsYXRlLCBjb25maWcpO1xyXG4gICAgICAgIGlmICghbm9DYWNoZSkge1xyXG4gICAgICAgICAgICBjb25maWcudGVtcGxhdGVzLmRlZmluZShjb25maWcuZmlsZW5hbWUsIGNvbXBpbGVkVGVtcGxhdGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY29tcGlsZWRUZW1wbGF0ZTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgdGhyb3cgRXRhRXJyKCdMb2FkaW5nIGZpbGU6ICcgKyBmaWxlUGF0aCArICcgZmFpbGVkOlxcblxcbicgKyBlLm1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcbi8qKlxyXG4gKiBHZXQgdGhlIHRlbXBsYXRlIGZyb20gYSBzdHJpbmcgb3IgYSBmaWxlLCBlaXRoZXIgY29tcGlsZWQgb24tdGhlLWZseSBvclxyXG4gKiByZWFkIGZyb20gY2FjaGUgKGlmIGVuYWJsZWQpLCBhbmQgY2FjaGUgdGhlIHRlbXBsYXRlIGlmIG5lZWRlZC5cclxuICpcclxuICogSWYgYG9wdGlvbnMuY2FjaGVgIGlzIHRydWUsIHRoaXMgZnVuY3Rpb24gcmVhZHMgdGhlIGZpbGUgZnJvbVxyXG4gKiBgb3B0aW9ucy5maWxlbmFtZWAgc28gaXQgbXVzdCBiZSBzZXQgcHJpb3IgdG8gY2FsbGluZyB0aGlzIGZ1bmN0aW9uLlxyXG4gKlxyXG4gKiBAcGFyYW0gb3B0aW9ucyAgIGNvbXBpbGF0aW9uIG9wdGlvbnNcclxuICogQHJldHVybiBFdGEgdGVtcGxhdGUgZnVuY3Rpb25cclxuICovXHJcbmZ1bmN0aW9uIGhhbmRsZUNhY2hlKG9wdGlvbnMpIHtcclxuICAgIHZhciBmaWxlbmFtZSA9IG9wdGlvbnMuZmlsZW5hbWU7XHJcbiAgICBpZiAob3B0aW9ucy5jYWNoZSkge1xyXG4gICAgICAgIHZhciBmdW5jID0gb3B0aW9ucy50ZW1wbGF0ZXMuZ2V0KGZpbGVuYW1lKTtcclxuICAgICAgICBpZiAoZnVuYykge1xyXG4gICAgICAgICAgICByZXR1cm4gZnVuYztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGxvYWRGaWxlKGZpbGVuYW1lLCBvcHRpb25zKTtcclxuICAgIH1cclxuICAgIC8vIENhY2hpbmcgaXMgZGlzYWJsZWQsIHNvIHBhc3Mgbm9DYWNoZSA9IHRydWVcclxuICAgIHJldHVybiBsb2FkRmlsZShmaWxlbmFtZSwgb3B0aW9ucywgdHJ1ZSk7XHJcbn1cclxuLyoqXHJcbiAqIFRyeSBjYWxsaW5nIGhhbmRsZUNhY2hlIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMgYW5kIGRhdGEgYW5kIGNhbGwgdGhlXHJcbiAqIGNhbGxiYWNrIHdpdGggdGhlIHJlc3VsdC4gSWYgYW4gZXJyb3Igb2NjdXJzLCBjYWxsIHRoZSBjYWxsYmFjayB3aXRoXHJcbiAqIHRoZSBlcnJvci4gVXNlZCBieSByZW5kZXJGaWxlKCkuXHJcbiAqXHJcbiAqIEBwYXJhbSBkYXRhIHRlbXBsYXRlIGRhdGFcclxuICogQHBhcmFtIG9wdGlvbnMgY29tcGlsYXRpb24gb3B0aW9uc1xyXG4gKiBAcGFyYW0gY2IgY2FsbGJhY2tcclxuICovXHJcbmZ1bmN0aW9uIHRyeUhhbmRsZUNhY2hlKGRhdGEsIG9wdGlvbnMsIGNiKSB7XHJcbiAgICBpZiAoY2IpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAvLyBOb3RlOiBpZiB0aGVyZSBpcyBhbiBlcnJvciB3aGlsZSByZW5kZXJpbmcgdGhlIHRlbXBsYXRlLFxyXG4gICAgICAgICAgICAvLyBJdCB3aWxsIGJ1YmJsZSB1cCBhbmQgYmUgY2F1Z2h0IGhlcmVcclxuICAgICAgICAgICAgdmFyIHRlbXBsYXRlRm4gPSBoYW5kbGVDYWNoZShvcHRpb25zKTtcclxuICAgICAgICAgICAgdGVtcGxhdGVGbihkYXRhLCBvcHRpb25zLCBjYik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNiKGVycik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8gTm8gY2FsbGJhY2ssIHRyeSByZXR1cm5pbmcgYSBwcm9taXNlXHJcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9taXNlSW1wbCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IHByb21pc2VJbXBsKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRlbXBsYXRlRm4gPSBoYW5kbGVDYWNoZShvcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gdGVtcGxhdGVGbihkYXRhLCBvcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgRXRhRXJyKFwiUGxlYXNlIHByb3ZpZGUgYSBjYWxsYmFjayBmdW5jdGlvbiwgdGhpcyBlbnYgZG9lc24ndCBzdXBwb3J0IFByb21pc2VzXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4vKipcclxuICogR2V0IHRoZSB0ZW1wbGF0ZSBmdW5jdGlvbi5cclxuICpcclxuICogSWYgYG9wdGlvbnMuY2FjaGVgIGlzIGB0cnVlYCwgdGhlbiB0aGUgdGVtcGxhdGUgaXMgY2FjaGVkLlxyXG4gKlxyXG4gKiBUaGlzIHJldHVybnMgYSB0ZW1wbGF0ZSBmdW5jdGlvbiBhbmQgdGhlIGNvbmZpZyBvYmplY3Qgd2l0aCB3aGljaCB0aGF0IHRlbXBsYXRlIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQuXHJcbiAqXHJcbiAqIEByZW1hcmtzXHJcbiAqXHJcbiAqIEl0J3MgaW1wb3J0YW50IHRoYXQgdGhpcyByZXR1cm5zIGEgY29uZmlnIG9iamVjdCB3aXRoIGBmaWxlbmFtZWAgc2V0LlxyXG4gKiBPdGhlcndpc2UsIHRoZSBpbmNsdWRlZCBmaWxlIHdvdWxkIG5vdCBiZSBhYmxlIHRvIHVzZSByZWxhdGl2ZSBwYXRoc1xyXG4gKlxyXG4gKiBAcGFyYW0gcGF0aCBwYXRoIGZvciB0aGUgc3BlY2lmaWVkIGZpbGUgKGlmIHJlbGF0aXZlLCBzcGVjaWZ5IGB2aWV3c2Agb24gYG9wdGlvbnNgKVxyXG4gKiBAcGFyYW0gb3B0aW9ucyBjb21waWxhdGlvbiBvcHRpb25zXHJcbiAqIEByZXR1cm4gW0V0YSB0ZW1wbGF0ZSBmdW5jdGlvbiwgbmV3IGNvbmZpZyBvYmplY3RdXHJcbiAqL1xyXG5mdW5jdGlvbiBpbmNsdWRlRmlsZShwYXRoLCBvcHRpb25zKSB7XHJcbiAgICAvLyB0aGUgYmVsb3cgY3JlYXRlcyBhIG5ldyBvcHRpb25zIG9iamVjdCwgdXNpbmcgdGhlIHBhcmVudCBmaWxlcGF0aCBvZiB0aGUgb2xkIG9wdGlvbnMgb2JqZWN0IGFuZCB0aGUgcGF0aFxyXG4gICAgdmFyIG5ld0ZpbGVPcHRpb25zID0gZ2V0Q29uZmlnKHsgZmlsZW5hbWU6IGdldFBhdGgocGF0aCwgb3B0aW9ucykgfSwgb3B0aW9ucyk7XHJcbiAgICAvLyBUT0RPOiBtYWtlIHN1cmUgcHJvcGVydGllcyBhcmUgY3VycmVjdGx5IGNvcGllZCBvdmVyXHJcbiAgICByZXR1cm4gW2hhbmRsZUNhY2hlKG5ld0ZpbGVPcHRpb25zKSwgbmV3RmlsZU9wdGlvbnNdO1xyXG59XHJcbmZ1bmN0aW9uIHJlbmRlckZpbGUoZmlsZW5hbWUsIGRhdGEsIGNvbmZpZywgY2IpIHtcclxuICAgIC8qXHJcbiAgICBIZXJlIHdlIGhhdmUgc29tZSBmdW5jdGlvbiBvdmVybG9hZGluZy5cclxuICAgIEVzc2VudGlhbGx5LCB0aGUgZmlyc3QgMiBhcmd1bWVudHMgdG8gcmVuZGVyRmlsZSBzaG91bGQgYWx3YXlzIGJlIHRoZSBmaWxlbmFtZSBhbmQgZGF0YVxyXG4gICAgSG93ZXZlciwgd2l0aCBFeHByZXNzLCBjb25maWd1cmF0aW9uIG9wdGlvbnMgd2lsbCBiZSBwYXNzZWQgYWxvbmcgd2l0aCB0aGUgZGF0YS5cclxuICAgIFRodXMsIEV4cHJlc3Mgd2lsbCBjYWxsIHJlbmRlckZpbGUgd2l0aCAoZmlsZW5hbWUsIGRhdGFBbmRPcHRpb25zLCBjYilcclxuICAgIEFuZCB3ZSB3YW50IHRvIGFsc28gbWFrZSAoZmlsZW5hbWUsIGRhdGEsIG9wdGlvbnMsIGNiKSBhdmFpbGFibGVcclxuICAgICovXHJcbiAgICB2YXIgcmVuZGVyQ29uZmlnO1xyXG4gICAgdmFyIGNhbGxiYWNrO1xyXG4gICAgZGF0YSA9IGRhdGEgfHwge307IC8vIElmIGRhdGEgaXMgdW5kZWZpbmVkLCB3ZSBkb24ndCB3YW50IGFjY2Vzc2luZyBkYXRhLnNldHRpbmdzIHRvIGVycm9yXHJcbiAgICAvLyBGaXJzdCwgYXNzaWduIG91ciBjYWxsYmFjayBmdW5jdGlvbiB0byBgY2FsbGJhY2tgXHJcbiAgICAvLyBXZSBjYW4gbGVhdmUgaXQgdW5kZWZpbmVkIGlmIG5laXRoZXIgcGFyYW1ldGVyIGlzIGEgZnVuY3Rpb247XHJcbiAgICAvLyBDYWxsYmFja3MgYXJlIG9wdGlvbmFsXHJcbiAgICBpZiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgLy8gVGhlIDR0aCBhcmd1bWVudCBpcyB0aGUgY2FsbGJhY2tcclxuICAgICAgICBjYWxsYmFjayA9IGNiO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAodHlwZW9mIGNvbmZpZyA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIC8vIFRoZSAzcmQgYXJnIGlzIHRoZSBjYWxsYmFja1xyXG4gICAgICAgIGNhbGxiYWNrID0gY29uZmlnO1xyXG4gICAgfVxyXG4gICAgLy8gSWYgdGhlcmUgaXMgYSBjb25maWcgb2JqZWN0IHBhc3NlZCBpbiBleHBsaWNpdGx5LCB1c2UgaXRcclxuICAgIGlmICh0eXBlb2YgY29uZmlnID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgIHJlbmRlckNvbmZpZyA9IGdldENvbmZpZyhjb25maWcgfHwge30pO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBnZXQgdGhlIGNvbmZpZyBmcm9tIHRoZSBkYXRhIG9iamVjdFxyXG4gICAgICAgIC8vIEFuZCB0aGVuIGdyYWIgc29tZSBjb25maWcgb3B0aW9ucyBmcm9tIGRhdGEuc2V0dGluZ3NcclxuICAgICAgICAvLyBXaGljaCBpcyB3aGVyZSBFeHByZXNzIHNvbWV0aW1lcyBzdG9yZXMgdGhlbVxyXG4gICAgICAgIHJlbmRlckNvbmZpZyA9IGdldENvbmZpZyhkYXRhKTtcclxuICAgICAgICBpZiAoZGF0YS5zZXR0aW5ncykge1xyXG4gICAgICAgICAgICAvLyBQdWxsIGEgZmV3IHRoaW5ncyBmcm9tIGtub3duIGxvY2F0aW9uc1xyXG4gICAgICAgICAgICBpZiAoZGF0YS5zZXR0aW5ncy52aWV3cykge1xyXG4gICAgICAgICAgICAgICAgcmVuZGVyQ29uZmlnLnZpZXdzID0gZGF0YS5zZXR0aW5ncy52aWV3cztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZGF0YS5zZXR0aW5nc1sndmlldyBjYWNoZSddKSB7XHJcbiAgICAgICAgICAgICAgICByZW5kZXJDb25maWcuY2FjaGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIFVuZG9jdW1lbnRlZCBhZnRlciBFeHByZXNzIDIsIGJ1dCBzdGlsbCB1c2FibGUsIGVzcC4gZm9yXHJcbiAgICAgICAgICAgIC8vIGl0ZW1zIHRoYXQgYXJlIHVuc2FmZSB0byBiZSBwYXNzZWQgYWxvbmcgd2l0aCBkYXRhLCBsaWtlIGByb290YFxyXG4gICAgICAgICAgICB2YXIgdmlld09wdHMgPSBkYXRhLnNldHRpbmdzWyd2aWV3IG9wdGlvbnMnXTtcclxuICAgICAgICAgICAgaWYgKHZpZXdPcHRzKSB7XHJcbiAgICAgICAgICAgICAgICBjb3B5UHJvcHMocmVuZGVyQ29uZmlnLCB2aWV3T3B0cyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBTZXQgdGhlIGZpbGVuYW1lIG9wdGlvbiBvbiB0aGUgdGVtcGxhdGVcclxuICAgIC8vIFRoaXMgd2lsbCBmaXJzdCB0cnkgdG8gcmVzb2x2ZSB0aGUgZmlsZSBwYXRoIChzZWUgZ2V0UGF0aCBmb3IgZGV0YWlscylcclxuICAgIHJlbmRlckNvbmZpZy5maWxlbmFtZSA9IGdldFBhdGgoZmlsZW5hbWUsIHJlbmRlckNvbmZpZyk7XHJcbiAgICByZXR1cm4gdHJ5SGFuZGxlQ2FjaGUoZGF0YSwgcmVuZGVyQ29uZmlnLCBjYWxsYmFjayk7XHJcbn1cclxuZnVuY3Rpb24gcmVuZGVyRmlsZUFzeW5jKGZpbGVuYW1lLCBkYXRhLCBjb25maWcsIGNiKSB7XHJcbiAgICByZXR1cm4gcmVuZGVyRmlsZShmaWxlbmFtZSwgdHlwZW9mIGNvbmZpZyA9PT0gJ2Z1bmN0aW9uJyA/IF9fYXNzaWduKF9fYXNzaWduKHt9LCBkYXRhKSwgeyBhc3luYzogdHJ1ZSB9KSA6IGRhdGEsIHR5cGVvZiBjb25maWcgPT09ICdvYmplY3QnID8gX19hc3NpZ24oX19hc3NpZ24oe30sIGNvbmZpZyksIHsgYXN5bmM6IHRydWUgfSkgOiBjb25maWcsIGNiKTtcclxufVxuXG4vKiBFTkQgVFlQRVMgKi9cclxuLyoqXHJcbiAqIENhbGxlZCB3aXRoIGBpbmNsdWRlRmlsZShwYXRoLCBkYXRhKWBcclxuICovXHJcbmZ1bmN0aW9uIGluY2x1ZGVGaWxlSGVscGVyKHBhdGgsIGRhdGEpIHtcclxuICAgIHZhciB0ZW1wbGF0ZUFuZENvbmZpZyA9IGluY2x1ZGVGaWxlKHBhdGgsIHRoaXMpO1xyXG4gICAgcmV0dXJuIHRlbXBsYXRlQW5kQ29uZmlnWzBdKGRhdGEsIHRlbXBsYXRlQW5kQ29uZmlnWzFdKTtcclxufVxuXG4vKiBFTkQgVFlQRVMgKi9cclxuZnVuY3Rpb24gaGFuZGxlQ2FjaGUkMSh0ZW1wbGF0ZSwgb3B0aW9ucykge1xyXG4gICAgaWYgKG9wdGlvbnMuY2FjaGUgJiYgb3B0aW9ucy5uYW1lICYmIG9wdGlvbnMudGVtcGxhdGVzLmdldChvcHRpb25zLm5hbWUpKSB7XHJcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMudGVtcGxhdGVzLmdldChvcHRpb25zLm5hbWUpO1xyXG4gICAgfVxyXG4gICAgdmFyIHRlbXBsYXRlRnVuYyA9IHR5cGVvZiB0ZW1wbGF0ZSA9PT0gJ2Z1bmN0aW9uJyA/IHRlbXBsYXRlIDogY29tcGlsZSh0ZW1wbGF0ZSwgb3B0aW9ucyk7XHJcbiAgICAvLyBOb3RlIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byBjaGVjayBpZiBpdCBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgY2FjaGU7XHJcbiAgICAvLyBpdCB3b3VsZCBoYXZlIHJldHVybmVkIGVhcmxpZXIgaWYgaXQgaGFkXHJcbiAgICBpZiAob3B0aW9ucy5jYWNoZSAmJiBvcHRpb25zLm5hbWUpIHtcclxuICAgICAgICBvcHRpb25zLnRlbXBsYXRlcy5kZWZpbmUob3B0aW9ucy5uYW1lLCB0ZW1wbGF0ZUZ1bmMpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRlbXBsYXRlRnVuYztcclxufVxyXG4vKipcclxuICogUmVuZGVyIGEgdGVtcGxhdGVcclxuICpcclxuICogSWYgYHRlbXBsYXRlYCBpcyBhIHN0cmluZywgRXRhIHdpbGwgY29tcGlsZSBpdCB0byBhIGZ1bmN0aW9uIGFuZCB0aGVuIGNhbGwgaXQgd2l0aCB0aGUgcHJvdmlkZWQgZGF0YS5cclxuICogSWYgYHRlbXBsYXRlYCBpcyBhIHRlbXBsYXRlIGZ1bmN0aW9uLCBFdGEgd2lsbCBjYWxsIGl0IHdpdGggdGhlIHByb3ZpZGVkIGRhdGEuXHJcbiAqXHJcbiAqIElmIGBjb25maWcuYXN5bmNgIGlzIGBmYWxzZWAsIEV0YSB3aWxsIHJldHVybiB0aGUgcmVuZGVyZWQgdGVtcGxhdGUuXHJcbiAqXHJcbiAqIElmIGBjb25maWcuYXN5bmNgIGlzIGB0cnVlYCBhbmQgdGhlcmUncyBhIGNhbGxiYWNrIGZ1bmN0aW9uLCBFdGEgd2lsbCBjYWxsIHRoZSBjYWxsYmFjayB3aXRoIGAoZXJyLCByZW5kZXJlZFRlbXBsYXRlKWAuXHJcbiAqIElmIGBjb25maWcuYXN5bmNgIGlzIGB0cnVlYCBhbmQgdGhlcmUncyBub3QgYSBjYWxsYmFjayBmdW5jdGlvbiwgRXRhIHdpbGwgcmV0dXJuIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSByZW5kZXJlZCB0ZW1wbGF0ZS5cclxuICpcclxuICogSWYgYGNvbmZpZy5jYWNoZWAgaXMgYHRydWVgIGFuZCBgY29uZmlnYCBoYXMgYSBgbmFtZWAgb3IgYGZpbGVuYW1lYCBwcm9wZXJ0eSwgRXRhIHdpbGwgY2FjaGUgdGhlIHRlbXBsYXRlIG9uIHRoZSBmaXJzdCByZW5kZXIgYW5kIHVzZSB0aGUgY2FjaGVkIHRlbXBsYXRlIGZvciBhbGwgc3Vic2VxdWVudCByZW5kZXJzLlxyXG4gKlxyXG4gKiBAcGFyYW0gdGVtcGxhdGUgVGVtcGxhdGUgc3RyaW5nIG9yIHRlbXBsYXRlIGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSBkYXRhIERhdGEgdG8gcmVuZGVyIHRoZSB0ZW1wbGF0ZSB3aXRoXHJcbiAqIEBwYXJhbSBjb25maWcgT3B0aW9uYWwgY29uZmlnIG9wdGlvbnNcclxuICogQHBhcmFtIGNiIENhbGxiYWNrIGZ1bmN0aW9uXHJcbiAqL1xyXG5mdW5jdGlvbiByZW5kZXIodGVtcGxhdGUsIGRhdGEsIGNvbmZpZywgY2IpIHtcclxuICAgIHZhciBvcHRpb25zID0gZ2V0Q29uZmlnKGNvbmZpZyB8fCB7fSk7XHJcbiAgICBpZiAob3B0aW9ucy5hc3luYykge1xyXG4gICAgICAgIGlmIChjYikge1xyXG4gICAgICAgICAgICAvLyBJZiB1c2VyIHBhc3NlcyBjYWxsYmFja1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgLy8gTm90ZTogaWYgdGhlcmUgaXMgYW4gZXJyb3Igd2hpbGUgcmVuZGVyaW5nIHRoZSB0ZW1wbGF0ZSxcclxuICAgICAgICAgICAgICAgIC8vIEl0IHdpbGwgYnViYmxlIHVwIGFuZCBiZSBjYXVnaHQgaGVyZVxyXG4gICAgICAgICAgICAgICAgdmFyIHRlbXBsYXRlRm4gPSBoYW5kbGVDYWNoZSQxKHRlbXBsYXRlLCBvcHRpb25zKTtcclxuICAgICAgICAgICAgICAgIHRlbXBsYXRlRm4oZGF0YSwgb3B0aW9ucywgY2IpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjYihlcnIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBObyBjYWxsYmFjaywgdHJ5IHJldHVybmluZyBhIHByb21pc2VcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBwcm9taXNlSW1wbCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBwcm9taXNlSW1wbChmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShoYW5kbGVDYWNoZSQxKHRlbXBsYXRlLCBvcHRpb25zKShkYXRhLCBvcHRpb25zKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBFdGFFcnIoXCJQbGVhc2UgcHJvdmlkZSBhIGNhbGxiYWNrIGZ1bmN0aW9uLCB0aGlzIGVudiBkb2Vzbid0IHN1cHBvcnQgUHJvbWlzZXNcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gaGFuZGxlQ2FjaGUkMSh0ZW1wbGF0ZSwgb3B0aW9ucykoZGF0YSwgb3B0aW9ucyk7XHJcbiAgICB9XHJcbn1cclxuLyoqXHJcbiAqIFJlbmRlciBhIHRlbXBsYXRlIGFzeW5jaHJvbm91c2x5XHJcbiAqXHJcbiAqIElmIGB0ZW1wbGF0ZWAgaXMgYSBzdHJpbmcsIEV0YSB3aWxsIGNvbXBpbGUgaXQgdG8gYSBmdW5jdGlvbiBhbmQgY2FsbCBpdCB3aXRoIHRoZSBwcm92aWRlZCBkYXRhLlxyXG4gKiBJZiBgdGVtcGxhdGVgIGlzIGEgZnVuY3Rpb24sIEV0YSB3aWxsIGNhbGwgaXQgd2l0aCB0aGUgcHJvdmlkZWQgZGF0YS5cclxuICpcclxuICogSWYgdGhlcmUgaXMgYSBjYWxsYmFjayBmdW5jdGlvbiwgRXRhIHdpbGwgY2FsbCBpdCB3aXRoIGAoZXJyLCByZW5kZXJlZFRlbXBsYXRlKWAuXHJcbiAqIElmIHRoZXJlIGlzIG5vdCBhIGNhbGxiYWNrIGZ1bmN0aW9uLCBFdGEgd2lsbCByZXR1cm4gYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJlbmRlcmVkIHRlbXBsYXRlXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZW1wbGF0ZSBUZW1wbGF0ZSBzdHJpbmcgb3IgdGVtcGxhdGUgZnVuY3Rpb25cclxuICogQHBhcmFtIGRhdGEgRGF0YSB0byByZW5kZXIgdGhlIHRlbXBsYXRlIHdpdGhcclxuICogQHBhcmFtIGNvbmZpZyBPcHRpb25hbCBjb25maWcgb3B0aW9uc1xyXG4gKiBAcGFyYW0gY2IgQ2FsbGJhY2sgZnVuY3Rpb25cclxuICovXHJcbmZ1bmN0aW9uIHJlbmRlckFzeW5jKHRlbXBsYXRlLCBkYXRhLCBjb25maWcsIGNiKSB7XHJcbiAgICAvLyBVc2luZyBPYmplY3QuYXNzaWduIHRvIGxvd2VyIGJ1bmRsZSBzaXplLCB1c2luZyBzcHJlYWQgb3BlcmF0b3IgbWFrZXMgaXQgbGFyZ2VyIGJlY2F1c2Ugb2YgdHlwZXNjcmlwdCBpbmplY3RlZCBwb2x5ZmlsbHNcclxuICAgIHJldHVybiByZW5kZXIodGVtcGxhdGUsIGRhdGEsIE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZywgeyBhc3luYzogdHJ1ZSB9KSwgY2IpO1xyXG59XG5cbi8vIEBkZW5vaWZ5LWlnbm9yZVxyXG5jb25maWcuaW5jbHVkZUZpbGUgPSBpbmNsdWRlRmlsZUhlbHBlcjtcclxuY29uZmlnLmZpbGVwYXRoQ2FjaGUgPSB7fTtcblxuZXhwb3J0IHsgcmVuZGVyRmlsZSBhcyBfX2V4cHJlc3MsIGNvbXBpbGUsIGNvbXBpbGVUb1N0cmluZywgY29uZmlnLCBjb25maWd1cmUsIGNvbmZpZyBhcyBkZWZhdWx0Q29uZmlnLCBnZXRDb25maWcsIGxvYWRGaWxlLCBwYXJzZSwgcmVuZGVyLCByZW5kZXJBc3luYywgcmVuZGVyRmlsZSwgcmVuZGVyRmlsZUFzeW5jLCB0ZW1wbGF0ZXMgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV0YS5lcy5qcy5tYXBcbiIsImltcG9ydCAqIGFzIEV0YSBmcm9tIFwiZXRhXCI7XG5cbmV4cG9ydCBjbGFzcyBQYXJzZXIge1xuICAgIGFzeW5jIHBhcnNlX2NvbW1hbmRzKFxuICAgICAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgICAgIG9iamVjdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICBjb250ZW50ID0gKGF3YWl0IEV0YS5yZW5kZXJBc3luYyhjb250ZW50LCBvYmplY3QsIHtcbiAgICAgICAgICAgIHZhck5hbWU6IFwidHBcIixcbiAgICAgICAgICAgIHBhcnNlOiB7XG4gICAgICAgICAgICAgICAgZXhlYzogXCIqXCIsXG4gICAgICAgICAgICAgICAgaW50ZXJwb2xhdGU6IFwiflwiLFxuICAgICAgICAgICAgICAgIHJhdzogXCJcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhdXRvVHJpbTogZmFsc2UsXG4gICAgICAgICAgICBnbG9iYWxBd2FpdDogdHJ1ZSxcbiAgICAgICAgfSkpIGFzIHN0cmluZztcblxuICAgICAgICByZXR1cm4gY29udGVudDtcbiAgICB9XG59XG4iLCJpbXBvcnQge1xuICAgIEFwcCxcbiAgICBub3JtYWxpemVQYXRoLFxuICAgIE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsXG4gICAgTWFya2Rvd25WaWV3LFxuICAgIFRBYnN0cmFjdEZpbGUsXG4gICAgVEZpbGUsXG4gICAgVEZvbGRlcixcbn0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmltcG9ydCB7IGdlbmVyYXRlX2R5bmFtaWNfY29tbWFuZF9yZWdleCwgcmVzb2x2ZV90ZmlsZSwgZGVsYXkgfSBmcm9tIFwiVXRpbHNcIjtcbmltcG9ydCBUZW1wbGF0ZXJQbHVnaW4gZnJvbSBcIm1haW5cIjtcbmltcG9ydCB7XG4gICAgRnVuY3Rpb25zTW9kZSxcbiAgICBGdW5jdGlvbnNHZW5lcmF0b3IsXG59IGZyb20gXCJmdW5jdGlvbnMvRnVuY3Rpb25zR2VuZXJhdG9yXCI7XG5pbXBvcnQgeyBlcnJvcldyYXBwZXIsIGVycm9yV3JhcHBlclN5bmMsIFRlbXBsYXRlckVycm9yIH0gZnJvbSBcIkVycm9yXCI7XG5pbXBvcnQgeyBFZGl0b3IgfSBmcm9tIFwiZWRpdG9yL0VkaXRvclwiO1xuaW1wb3J0IHsgUGFyc2VyIH0gZnJvbSBcInBhcnNlci9QYXJzZXJcIjtcbmltcG9ydCB7IGxvZ19lcnJvciB9IGZyb20gXCJMb2dcIjtcbmltcG9ydCB7IERvY3VtZW50YXRpb24gfSBmcm9tIFwiZnVuY3Rpb25zL1RwRG9jdW1lbnRhdGlvblwiO1xuXG5leHBvcnQgZW51bSBSdW5Nb2RlIHtcbiAgICBDcmVhdGVOZXdGcm9tVGVtcGxhdGUsXG4gICAgQXBwZW5kQWN0aXZlRmlsZSxcbiAgICBPdmVyd3JpdGVGaWxlLFxuICAgIE92ZXJ3cml0ZUFjdGl2ZUZpbGUsXG4gICAgRHluYW1pY1Byb2Nlc3NvcixcbiAgICBTdGFydHVwVGVtcGxhdGUsXG59XG5cbmV4cG9ydCB0eXBlIFJ1bm5pbmdDb25maWcgPSB7XG4gICAgdGVtcGxhdGVfZmlsZTogVEZpbGU7XG4gICAgdGFyZ2V0X2ZpbGU6IFRGaWxlO1xuICAgIHJ1bl9tb2RlOiBSdW5Nb2RlO1xuICAgIGFjdGl2ZV9maWxlPzogVEZpbGU7XG59O1xuXG5leHBvcnQgY2xhc3MgVGVtcGxhdGVyIHtcbiAgICBwdWJsaWMgcGFyc2VyOiBQYXJzZXI7XG4gICAgcHVibGljIGZ1bmN0aW9uc19nZW5lcmF0b3I6IEZ1bmN0aW9uc0dlbmVyYXRvcjtcbiAgICBwdWJsaWMgZWRpdG9yOiBFZGl0b3I7XG4gICAgcHVibGljIGN1cnJlbnRfZnVuY3Rpb25zX29iamVjdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgcHVibGljIGRvY3VtZW50YXRpb246IERvY3VtZW50YXRpb247XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFwcDogQXBwLCBwcml2YXRlIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luKSB7XG4gICAgICAgIHRoaXMuZnVuY3Rpb25zX2dlbmVyYXRvciA9IG5ldyBGdW5jdGlvbnNHZW5lcmF0b3IoXG4gICAgICAgICAgICB0aGlzLmFwcCxcbiAgICAgICAgICAgIHRoaXMucGx1Z2luXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuZWRpdG9yID0gbmV3IEVkaXRvcih0aGlzLmFwcCwgdGhpcy5wbHVnaW4pO1xuICAgICAgICB0aGlzLnBhcnNlciA9IG5ldyBQYXJzZXIoKTtcbiAgICAgICAgdGhpcy5kb2N1bWVudGF0aW9uID0gbmV3IERvY3VtZW50YXRpb24odGhpcy5hcHApO1xuICAgIH1cblxuICAgIGFzeW5jIHNldHVwKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmVkaXRvci5zZXR1cCgpO1xuICAgICAgICBhd2FpdCB0aGlzLmZ1bmN0aW9uc19nZW5lcmF0b3IuaW5pdCgpO1xuICAgICAgICB0aGlzLnBsdWdpbi5yZWdpc3Rlck1hcmtkb3duUG9zdFByb2Nlc3NvcigoZWwsIGN0eCkgPT5cbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc19keW5hbWljX3RlbXBsYXRlcyhlbCwgY3R4KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIGNyZWF0ZV9ydW5uaW5nX2NvbmZpZyhcbiAgICAgICAgdGVtcGxhdGVfZmlsZTogVEZpbGUsXG4gICAgICAgIHRhcmdldF9maWxlOiBURmlsZSxcbiAgICAgICAgcnVuX21vZGU6IFJ1bk1vZGVcbiAgICApOiBSdW5uaW5nQ29uZmlnIHtcbiAgICAgICAgY29uc3QgYWN0aXZlX2ZpbGUgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0ZW1wbGF0ZV9maWxlOiB0ZW1wbGF0ZV9maWxlLFxuICAgICAgICAgICAgdGFyZ2V0X2ZpbGU6IHRhcmdldF9maWxlLFxuICAgICAgICAgICAgcnVuX21vZGU6IHJ1bl9tb2RlLFxuICAgICAgICAgICAgYWN0aXZlX2ZpbGU6IGFjdGl2ZV9maWxlLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGFzeW5jIHJlYWRfYW5kX3BhcnNlX3RlbXBsYXRlKGNvbmZpZzogUnVubmluZ0NvbmZpZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlX2NvbnRlbnQgPSBhd2FpdCB0aGlzLmFwcC52YXVsdC5yZWFkKFxuICAgICAgICAgICAgY29uZmlnLnRlbXBsYXRlX2ZpbGVcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VfdGVtcGxhdGUoY29uZmlnLCB0ZW1wbGF0ZV9jb250ZW50KTtcbiAgICB9XG5cbiAgICBhc3luYyBwYXJzZV90ZW1wbGF0ZShcbiAgICAgICAgY29uZmlnOiBSdW5uaW5nQ29uZmlnLFxuICAgICAgICB0ZW1wbGF0ZV9jb250ZW50OiBzdHJpbmdcbiAgICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICBjb25zdCBmdW5jdGlvbnNfb2JqZWN0ID0gYXdhaXQgdGhpcy5mdW5jdGlvbnNfZ2VuZXJhdG9yLmdlbmVyYXRlX29iamVjdChcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIEZ1bmN0aW9uc01vZGUuVVNFUl9JTlRFUk5BTFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmN1cnJlbnRfZnVuY3Rpb25zX29iamVjdCA9IGZ1bmN0aW9uc19vYmplY3Q7XG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCB0aGlzLnBhcnNlci5wYXJzZV9jb21tYW5kcyhcbiAgICAgICAgICAgIHRlbXBsYXRlX2NvbnRlbnQsXG4gICAgICAgICAgICBmdW5jdGlvbnNfb2JqZWN0XG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBjb250ZW50O1xuICAgIH1cblxuICAgIGFzeW5jIGp1bXBfdG9fbmV4dF9jdXJzb3JfbG9jYXRpb24oZmlsZTogVEZpbGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuYXV0b19qdW1wX3RvX2N1cnNvciAmJlxuICAgICAgICAgICAgdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKSA9PT0gZmlsZVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZWRpdG9yLmp1bXBfdG9fbmV4dF9jdXJzb3JfbG9jYXRpb24oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGNyZWF0ZV9uZXdfbm90ZV9mcm9tX3RlbXBsYXRlKFxuICAgICAgICB0ZW1wbGF0ZTogVEZpbGUgfCBzdHJpbmcsXG4gICAgICAgIGZvbGRlcj86IFRGb2xkZXIsXG4gICAgICAgIGZpbGVuYW1lPzogc3RyaW5nLFxuICAgICAgICBvcGVuX25ld19ub3RlID0gdHJ1ZVxuICAgICk6IFByb21pc2U8VEZpbGU+IHtcbiAgICAgICAgLy8gVE9ETzogTWF5YmUgdGhlcmUgaXMgYW4gb2JzaWRpYW4gQVBJIGZ1bmN0aW9uIGZvciB0aGF0XG4gICAgICAgIGlmICghZm9sZGVyKSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBGaXggdGhhdFxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc3QgbmV3X2ZpbGVfbG9jYXRpb24gPVxuICAgICAgICAgICAgICAgIHRoaXMuYXBwLnZhdWx0LmdldENvbmZpZyhcIm5ld0ZpbGVMb2NhdGlvblwiKTtcbiAgICAgICAgICAgIHN3aXRjaCAobmV3X2ZpbGVfbG9jYXRpb24pIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwiY3VycmVudFwiOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZV9maWxlID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZV9maWxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb2xkZXIgPSBhY3RpdmVfZmlsZS5wYXJlbnQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgXCJmb2xkZXJcIjpcbiAgICAgICAgICAgICAgICAgICAgZm9sZGVyID0gdGhpcy5hcHAuZmlsZU1hbmFnZXIuZ2V0TmV3RmlsZVBhcmVudChcIlwiKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInJvb3RcIjpcbiAgICAgICAgICAgICAgICAgICAgZm9sZGVyID0gdGhpcy5hcHAudmF1bHQuZ2V0Um9vdCgpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRPRE86IENoYW5nZSB0aGF0LCBub3Qgc3RhYmxlIGF0bVxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IGNyZWF0ZWRfbm90ZSA9IGF3YWl0IHRoaXMuYXBwLmZpbGVNYW5hZ2VyLmNyZWF0ZU5ld01hcmtkb3duRmlsZShcbiAgICAgICAgICAgIGZvbGRlcixcbiAgICAgICAgICAgIGZpbGVuYW1lID8/IFwiVW50aXRsZWRcIlxuICAgICAgICApO1xuXG4gICAgICAgIGxldCBydW5uaW5nX2NvbmZpZzogUnVubmluZ0NvbmZpZztcbiAgICAgICAgbGV0IG91dHB1dF9jb250ZW50OiBzdHJpbmc7XG4gICAgICAgIGlmICh0ZW1wbGF0ZSBpbnN0YW5jZW9mIFRGaWxlKSB7XG4gICAgICAgICAgICBydW5uaW5nX2NvbmZpZyA9IHRoaXMuY3JlYXRlX3J1bm5pbmdfY29uZmlnKFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlLFxuICAgICAgICAgICAgICAgIGNyZWF0ZWRfbm90ZSxcbiAgICAgICAgICAgICAgICBSdW5Nb2RlLkNyZWF0ZU5ld0Zyb21UZW1wbGF0ZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG91dHB1dF9jb250ZW50ID0gYXdhaXQgZXJyb3JXcmFwcGVyKFxuICAgICAgICAgICAgICAgIGFzeW5jICgpID0+IHRoaXMucmVhZF9hbmRfcGFyc2VfdGVtcGxhdGUocnVubmluZ19jb25maWcpLFxuICAgICAgICAgICAgICAgIFwiVGVtcGxhdGUgcGFyc2luZyBlcnJvciwgYWJvcnRpbmcuXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBydW5uaW5nX2NvbmZpZyA9IHRoaXMuY3JlYXRlX3J1bm5pbmdfY29uZmlnKFxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBjcmVhdGVkX25vdGUsXG4gICAgICAgICAgICAgICAgUnVuTW9kZS5DcmVhdGVOZXdGcm9tVGVtcGxhdGVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBvdXRwdXRfY29udGVudCA9IGF3YWl0IGVycm9yV3JhcHBlcihcbiAgICAgICAgICAgICAgICBhc3luYyAoKSA9PiB0aGlzLnBhcnNlX3RlbXBsYXRlKHJ1bm5pbmdfY29uZmlnLCB0ZW1wbGF0ZSksXG4gICAgICAgICAgICAgICAgXCJUZW1wbGF0ZSBwYXJzaW5nIGVycm9yLCBhYm9ydGluZy5cIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvdXRwdXRfY29udGVudCA9PSBudWxsKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmFwcC52YXVsdC5kZWxldGUoY3JlYXRlZF9ub3RlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHRoaXMuYXBwLnZhdWx0Lm1vZGlmeShjcmVhdGVkX25vdGUsIG91dHB1dF9jb250ZW50KTtcblxuICAgICAgICBpZiAob3Blbl9uZXdfbm90ZSkge1xuICAgICAgICAgICAgY29uc3QgYWN0aXZlX2xlYWYgPSB0aGlzLmFwcC53b3Jrc3BhY2UuYWN0aXZlTGVhZjtcbiAgICAgICAgICAgIGlmICghYWN0aXZlX2xlYWYpIHtcbiAgICAgICAgICAgICAgICBsb2dfZXJyb3IobmV3IFRlbXBsYXRlckVycm9yKFwiTm8gYWN0aXZlIGxlYWZcIikpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IGFjdGl2ZV9sZWFmLm9wZW5GaWxlKGNyZWF0ZWRfbm90ZSwge1xuICAgICAgICAgICAgICAgIHN0YXRlOiB7IG1vZGU6IFwic291cmNlXCIgfSxcbiAgICAgICAgICAgICAgICBlU3RhdGU6IHsgcmVuYW1lOiBcImFsbFwiIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuanVtcF90b19uZXh0X2N1cnNvcl9sb2NhdGlvbihjcmVhdGVkX25vdGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZWRfbm90ZTtcbiAgICB9XG5cbiAgICBhc3luYyBhcHBlbmRfdGVtcGxhdGVfdG9fYWN0aXZlX2ZpbGUodGVtcGxhdGVfZmlsZTogVEZpbGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgYWN0aXZlX3ZpZXcgPVxuICAgICAgICAgICAgdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KTtcbiAgICAgICAgaWYgKGFjdGl2ZV92aWV3ID09PSBudWxsKSB7XG4gICAgICAgICAgICBsb2dfZXJyb3IoXG4gICAgICAgICAgICAgICAgbmV3IFRlbXBsYXRlckVycm9yKFwiTm8gYWN0aXZlIHZpZXcsIGNhbid0IGFwcGVuZCB0ZW1wbGF0ZXMuXCIpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJ1bm5pbmdfY29uZmlnID0gdGhpcy5jcmVhdGVfcnVubmluZ19jb25maWcoXG4gICAgICAgICAgICB0ZW1wbGF0ZV9maWxlLFxuICAgICAgICAgICAgYWN0aXZlX3ZpZXcuZmlsZSxcbiAgICAgICAgICAgIFJ1bk1vZGUuQXBwZW5kQWN0aXZlRmlsZVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBvdXRwdXRfY29udGVudCA9IGF3YWl0IGVycm9yV3JhcHBlcihcbiAgICAgICAgICAgIGFzeW5jICgpID0+IHRoaXMucmVhZF9hbmRfcGFyc2VfdGVtcGxhdGUocnVubmluZ19jb25maWcpLFxuICAgICAgICAgICAgXCJUZW1wbGF0ZSBwYXJzaW5nIGVycm9yLCBhYm9ydGluZy5cIlxuICAgICAgICApO1xuICAgICAgICAvLyBlcnJvcldyYXBwZXIgZmFpbGVkXG4gICAgICAgIGlmIChvdXRwdXRfY29udGVudCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBlZGl0b3IgPSBhY3RpdmVfdmlldy5lZGl0b3I7XG4gICAgICAgIGNvbnN0IGRvYyA9IGVkaXRvci5nZXREb2MoKTtcbiAgICAgICAgZG9jLnJlcGxhY2VTZWxlY3Rpb24ob3V0cHV0X2NvbnRlbnQpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuanVtcF90b19uZXh0X2N1cnNvcl9sb2NhdGlvbihhY3RpdmVfdmlldy5maWxlKTtcbiAgICB9XG5cbiAgICBhc3luYyB3cml0ZV90ZW1wbGF0ZV90b19maWxlKFxuICAgICAgICB0ZW1wbGF0ZV9maWxlOiBURmlsZSxcbiAgICAgICAgZmlsZTogVEZpbGVcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgcnVubmluZ19jb25maWcgPSB0aGlzLmNyZWF0ZV9ydW5uaW5nX2NvbmZpZyhcbiAgICAgICAgICAgIHRlbXBsYXRlX2ZpbGUsXG4gICAgICAgICAgICBmaWxlLFxuICAgICAgICAgICAgUnVuTW9kZS5PdmVyd3JpdGVGaWxlXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG91dHB1dF9jb250ZW50ID0gYXdhaXQgZXJyb3JXcmFwcGVyKFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4gdGhpcy5yZWFkX2FuZF9wYXJzZV90ZW1wbGF0ZShydW5uaW5nX2NvbmZpZyksXG4gICAgICAgICAgICBcIlRlbXBsYXRlIHBhcnNpbmcgZXJyb3IsIGFib3J0aW5nLlwiXG4gICAgICAgICk7XG4gICAgICAgIC8vIGVycm9yV3JhcHBlciBmYWlsZWRcbiAgICAgICAgaWYgKG91dHB1dF9jb250ZW50ID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLmFwcC52YXVsdC5tb2RpZnkoZmlsZSwgb3V0cHV0X2NvbnRlbnQpO1xuICAgICAgICBhd2FpdCB0aGlzLmp1bXBfdG9fbmV4dF9jdXJzb3JfbG9jYXRpb24oZmlsZSk7XG4gICAgfVxuXG4gICAgb3ZlcndyaXRlX2FjdGl2ZV9maWxlX2NvbW1hbmRzKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBhY3RpdmVfdmlldyA9XG4gICAgICAgICAgICB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpO1xuICAgICAgICBpZiAoYWN0aXZlX3ZpZXcgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGxvZ19lcnJvcihcbiAgICAgICAgICAgICAgICBuZXcgVGVtcGxhdGVyRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiQWN0aXZlIHZpZXcgaXMgbnVsbCwgY2FuJ3Qgb3ZlcndyaXRlIGNvbnRlbnRcIlxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vdmVyd3JpdGVfZmlsZV9jb21tYW5kcyhhY3RpdmVfdmlldy5maWxlLCB0cnVlKTtcbiAgICB9XG5cbiAgICBhc3luYyBvdmVyd3JpdGVfZmlsZV9jb21tYW5kcyhcbiAgICAgICAgZmlsZTogVEZpbGUsXG4gICAgICAgIGFjdGl2ZV9maWxlID0gZmFsc2VcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgcnVubmluZ19jb25maWcgPSB0aGlzLmNyZWF0ZV9ydW5uaW5nX2NvbmZpZyhcbiAgICAgICAgICAgIGZpbGUsXG4gICAgICAgICAgICBmaWxlLFxuICAgICAgICAgICAgYWN0aXZlX2ZpbGUgPyBSdW5Nb2RlLk92ZXJ3cml0ZUFjdGl2ZUZpbGUgOiBSdW5Nb2RlLk92ZXJ3cml0ZUZpbGVcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgb3V0cHV0X2NvbnRlbnQgPSBhd2FpdCBlcnJvcldyYXBwZXIoXG4gICAgICAgICAgICBhc3luYyAoKSA9PiB0aGlzLnJlYWRfYW5kX3BhcnNlX3RlbXBsYXRlKHJ1bm5pbmdfY29uZmlnKSxcbiAgICAgICAgICAgIFwiVGVtcGxhdGUgcGFyc2luZyBlcnJvciwgYWJvcnRpbmcuXCJcbiAgICAgICAgKTtcbiAgICAgICAgLy8gZXJyb3JXcmFwcGVyIGZhaWxlZFxuICAgICAgICBpZiAob3V0cHV0X2NvbnRlbnQgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuYXBwLnZhdWx0Lm1vZGlmeShmaWxlLCBvdXRwdXRfY29udGVudCk7XG4gICAgICAgIGF3YWl0IHRoaXMuanVtcF90b19uZXh0X2N1cnNvcl9sb2NhdGlvbihmaWxlKTtcbiAgICB9XG5cbiAgICBhc3luYyBwcm9jZXNzX2R5bmFtaWNfdGVtcGxhdGVzKFxuICAgICAgICBlbDogSFRNTEVsZW1lbnQsXG4gICAgICAgIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBkeW5hbWljX2NvbW1hbmRfcmVnZXggPSBnZW5lcmF0ZV9keW5hbWljX2NvbW1hbmRfcmVnZXgoKTtcblxuICAgICAgICBjb25zdCB3YWxrZXIgPSBkb2N1bWVudC5jcmVhdGVOb2RlSXRlcmF0b3IoZWwsIE5vZGVGaWx0ZXIuU0hPV19URVhUKTtcbiAgICAgICAgbGV0IG5vZGU7XG4gICAgICAgIGxldCBwYXNzID0gZmFsc2U7XG4gICAgICAgIGxldCBmdW5jdGlvbnNfb2JqZWN0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgd2hpbGUgKChub2RlID0gd2Fsa2VyLm5leHROb2RlKCkpKSB7XG4gICAgICAgICAgICBsZXQgY29udGVudCA9IG5vZGUubm9kZVZhbHVlO1xuICAgICAgICAgICAgbGV0IG1hdGNoO1xuICAgICAgICAgICAgaWYgKChtYXRjaCA9IGR5bmFtaWNfY29tbWFuZF9yZWdleC5leGVjKGNvbnRlbnQpKSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IHRoaXMuYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0Rmlyc3RMaW5rcGF0aERlc3QoXG4gICAgICAgICAgICAgICAgICAgIFwiXCIsXG4gICAgICAgICAgICAgICAgICAgIGN0eC5zb3VyY2VQYXRoXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBpZiAoIWZpbGUgfHwgIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFwYXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhc3MgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25maWcgPSB0aGlzLmNyZWF0ZV9ydW5uaW5nX2NvbmZpZyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgUnVuTW9kZS5EeW5hbWljUHJvY2Vzc29yXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uc19vYmplY3QgPVxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5mdW5jdGlvbnNfZ2VuZXJhdG9yLmdlbmVyYXRlX29iamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRnVuY3Rpb25zTW9kZS5VU0VSX0lOVEVSTkFMXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRfZnVuY3Rpb25zX29iamVjdCA9IGZ1bmN0aW9uc19vYmplY3Q7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgd2hpbGUgKG1hdGNoICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm90IHRoZSBtb3N0IGVmZmljaWVudCB3YXkgdG8gZXhjbHVkZSB0aGUgJysnIGZyb20gdGhlIGNvbW1hbmQgYnV0IEkgY291bGRuJ3QgZmluZCBzb21ldGhpbmcgYmV0dGVyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbXBsZXRlX2NvbW1hbmQgPSBtYXRjaFsxXSArIG1hdGNoWzJdO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21tYW5kX291dHB1dDogc3RyaW5nID0gYXdhaXQgZXJyb3JXcmFwcGVyKFxuICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnBhcnNlci5wYXJzZV9jb21tYW5kcyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGVfY29tbWFuZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25zX29iamVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgYENvbW1hbmQgUGFyc2luZyBlcnJvciBpbiBkeW5hbWljIGNvbW1hbmQgJyR7Y29tcGxldGVfY29tbWFuZH0nYFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWFuZF9vdXRwdXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID1cbiAgICAgICAgICAgICAgICAgICAgICAgIGR5bmFtaWNfY29tbWFuZF9yZWdleC5sYXN0SW5kZXggLSBtYXRjaFswXS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuZCA9IGR5bmFtaWNfY29tbWFuZF9yZWdleC5sYXN0SW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5zdWJzdHJpbmcoMCwgc3RhcnQpICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmRfb3V0cHV0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuc3Vic3RyaW5nKGVuZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgZHluYW1pY19jb21tYW5kX3JlZ2V4Lmxhc3RJbmRleCArPVxuICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZF9vdXRwdXQubGVuZ3RoIC0gbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGR5bmFtaWNfY29tbWFuZF9yZWdleC5leGVjKGNvbnRlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBub2RlLm5vZGVWYWx1ZSA9IGNvbnRlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfbmV3X2ZpbGVfdGVtcGxhdGVfZm9yX2ZvbGRlcihmb2xkZXI6IFRGb2xkZXIpOiBzdHJpbmcge1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBjb25zdCBtYXRjaCA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlcl90ZW1wbGF0ZXMuZmluZChcbiAgICAgICAgICAgICAgICAoZSkgPT4gZS5mb2xkZXIgPT0gZm9sZGVyLnBhdGhcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChtYXRjaCAmJiBtYXRjaC50ZW1wbGF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaC50ZW1wbGF0ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9sZGVyID0gZm9sZGVyLnBhcmVudDtcbiAgICAgICAgfSB3aGlsZSAoZm9sZGVyKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgYXN5bmMgb25fZmlsZV9jcmVhdGlvbihcbiAgICAgICAgdGVtcGxhdGVyOiBUZW1wbGF0ZXIsXG4gICAgICAgIGZpbGU6IFRBYnN0cmFjdEZpbGVcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB8fCBmaWxlLmV4dGVuc2lvbiAhPT0gXCJtZFwiKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBdm9pZHMgdGVtcGxhdGUgcmVwbGFjZW1lbnQgd2hlbiBzeW5jaW5nIHRlbXBsYXRlIGZpbGVzXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlX2ZvbGRlciA9IG5vcm1hbGl6ZVBhdGgoXG4gICAgICAgICAgICB0ZW1wbGF0ZXIucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlc19mb2xkZXJcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZpbGUucGF0aC5pbmNsdWRlcyh0ZW1wbGF0ZV9mb2xkZXIpICYmIHRlbXBsYXRlX2ZvbGRlciAhPT0gXCIvXCIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRPRE86IGZpbmQgYSBiZXR0ZXIgd2F5IHRvIGRvIHRoaXNcbiAgICAgICAgLy8gQ3VycmVudGx5LCBJIGhhdmUgdG8gd2FpdCBmb3IgdGhlIGRhaWx5IG5vdGUgcGx1Z2luIHRvIGFkZCB0aGUgZmlsZSBjb250ZW50IGJlZm9yZSByZXBsYWNpbmdcbiAgICAgICAgLy8gTm90IGEgcHJvYmxlbSB3aXRoIENhbGVuZGFyIGhvd2V2ZXIgc2luY2UgaXQgY3JlYXRlcyB0aGUgZmlsZSB3aXRoIHRoZSBleGlzdGluZyBjb250ZW50XG4gICAgICAgIGF3YWl0IGRlbGF5KDMwMCk7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgZmlsZS5zdGF0LnNpemUgPT0gMCAmJlxuICAgICAgICAgICAgdGVtcGxhdGVyLnBsdWdpbi5zZXR0aW5ncy5lbmFibGVfZm9sZGVyX3RlbXBsYXRlc1xuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IGZvbGRlcl90ZW1wbGF0ZV9tYXRjaCA9XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVyLmdldF9uZXdfZmlsZV90ZW1wbGF0ZV9mb3JfZm9sZGVyKGZpbGUucGFyZW50KTtcbiAgICAgICAgICAgIGlmICghZm9sZGVyX3RlbXBsYXRlX21hdGNoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0ZW1wbGF0ZV9maWxlOiBURmlsZSA9IGF3YWl0IGVycm9yV3JhcHBlcihcbiAgICAgICAgICAgICAgICBhc3luYyAoKTogUHJvbWlzZTxURmlsZT4gPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZV90ZmlsZSh0ZW1wbGF0ZXIuYXBwLCBmb2xkZXJfdGVtcGxhdGVfbWF0Y2gpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYENvdWxkbid0IGZpbmQgdGVtcGxhdGUgJHtmb2xkZXJfdGVtcGxhdGVfbWF0Y2h9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIC8vIGVycm9yV3JhcHBlciBmYWlsZWRcbiAgICAgICAgICAgIGlmICh0ZW1wbGF0ZV9maWxlID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCB0ZW1wbGF0ZXIud3JpdGVfdGVtcGxhdGVfdG9fZmlsZSh0ZW1wbGF0ZV9maWxlLCBmaWxlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGF3YWl0IHRlbXBsYXRlci5vdmVyd3JpdGVfZmlsZV9jb21tYW5kcyhmaWxlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGV4ZWN1dGVfc3RhcnR1cF9zY3JpcHRzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBmb3IgKGNvbnN0IHRlbXBsYXRlIG9mIHRoaXMucGx1Z2luLnNldHRpbmdzLnN0YXJ0dXBfdGVtcGxhdGVzKSB7XG4gICAgICAgICAgICBpZiAoIXRlbXBsYXRlKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBmaWxlID0gZXJyb3JXcmFwcGVyU3luYyhcbiAgICAgICAgICAgICAgICAoKSA9PiByZXNvbHZlX3RmaWxlKHRoaXMuYXBwLCB0ZW1wbGF0ZSksXG4gICAgICAgICAgICAgICAgYENvdWxkbid0IGZpbmQgc3RhcnR1cCB0ZW1wbGF0ZSBcIiR7dGVtcGxhdGV9XCJgXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKCFmaWxlKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBydW5uaW5nX2NvbmZpZyA9IHRoaXMuY3JlYXRlX3J1bm5pbmdfY29uZmlnKFxuICAgICAgICAgICAgICAgIGZpbGUsXG4gICAgICAgICAgICAgICAgZmlsZSxcbiAgICAgICAgICAgICAgICBSdW5Nb2RlLlN0YXJ0dXBUZW1wbGF0ZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGF3YWl0IGVycm9yV3JhcHBlcihcbiAgICAgICAgICAgICAgICBhc3luYyAoKSA9PiB0aGlzLnJlYWRfYW5kX3BhcnNlX3RlbXBsYXRlKHJ1bm5pbmdfY29uZmlnKSxcbiAgICAgICAgICAgICAgICBgU3RhcnR1cCBUZW1wbGF0ZSBwYXJzaW5nIGVycm9yLCBhYm9ydGluZy5gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiaW1wb3J0IFRlbXBsYXRlclBsdWdpbiBmcm9tIFwibWFpblwiO1xuaW1wb3J0IHsgVGVtcGxhdGVyIH0gZnJvbSBcIlRlbXBsYXRlclwiO1xuaW1wb3J0IHsgU2V0dGluZ3MgfSBmcm9tIFwiU2V0dGluZ3NcIjtcbmltcG9ydCB7XG4gICAgQXBwLFxuICAgIEV2ZW50UmVmLFxuICAgIE1lbnUsXG4gICAgTWVudUl0ZW0sXG4gICAgVEFic3RyYWN0RmlsZSxcbiAgICBURmlsZSxcbiAgICBURm9sZGVyLFxufSBmcm9tIFwib2JzaWRpYW5cIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXZlbnRIYW5kbGVyIHtcbiAgICBwcml2YXRlIHN5bnRheF9oaWdobGlnaHRpbmdfZXZlbnQ6IEV2ZW50UmVmO1xuICAgIHByaXZhdGUgdHJpZ2dlcl9vbl9maWxlX2NyZWF0aW9uX2V2ZW50OiBFdmVudFJlZjtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGFwcDogQXBwLFxuICAgICAgICBwcml2YXRlIHBsdWdpbjogVGVtcGxhdGVyUGx1Z2luLFxuICAgICAgICBwcml2YXRlIHRlbXBsYXRlcjogVGVtcGxhdGVyLFxuICAgICAgICBwcml2YXRlIHNldHRpbmdzOiBTZXR0aW5nc1xuICAgICkge31cblxuICAgIHNldHVwKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZV90cmlnZ2VyX2ZpbGVfb25fY3JlYXRpb24oKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBkYXRlX3N5bnRheF9oaWdobGlnaHRpbmcoKTtcbiAgICAgICAgdGhpcy51cGRhdGVfZmlsZV9tZW51KCk7XG4gICAgfVxuXG4gICAgdXBkYXRlX3N5bnRheF9oaWdobGlnaHRpbmcoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zeW50YXhfaGlnaGxpZ2h0aW5nKSB7XG4gICAgICAgICAgICB0aGlzLnN5bnRheF9oaWdobGlnaHRpbmdfZXZlbnQgPSB0aGlzLmFwcC53b3Jrc3BhY2Uub24oXG4gICAgICAgICAgICAgICAgXCJjb2RlbWlycm9yXCIsXG4gICAgICAgICAgICAgICAgKGNtKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNtLnNldE9wdGlvbihcIm1vZGVcIiwgXCJ0ZW1wbGF0ZXJcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuYXBwLndvcmtzcGFjZS5pdGVyYXRlQ29kZU1pcnJvcnMoKGNtKSA9PiB7XG4gICAgICAgICAgICAgICAgY20uc2V0T3B0aW9uKFwibW9kZVwiLCBcInRlbXBsYXRlclwiKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4ucmVnaXN0ZXJFdmVudCh0aGlzLnN5bnRheF9oaWdobGlnaHRpbmdfZXZlbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3ludGF4X2hpZ2hsaWdodGluZ19ldmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXBwLnZhdWx0Lm9mZnJlZih0aGlzLnN5bnRheF9oaWdobGlnaHRpbmdfZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hcHAud29ya3NwYWNlLml0ZXJhdGVDb2RlTWlycm9ycygoY20pID0+IHtcbiAgICAgICAgICAgICAgICBjbS5zZXRPcHRpb24oXCJtb2RlXCIsIFwiaHlwZXJtZFwiKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlX3RyaWdnZXJfZmlsZV9vbl9jcmVhdGlvbigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MudHJpZ2dlcl9vbl9maWxlX2NyZWF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJfb25fZmlsZV9jcmVhdGlvbl9ldmVudCA9IHRoaXMuYXBwLnZhdWx0Lm9uKFxuICAgICAgICAgICAgICAgIFwiY3JlYXRlXCIsXG4gICAgICAgICAgICAgICAgKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+XG4gICAgICAgICAgICAgICAgICAgIFRlbXBsYXRlci5vbl9maWxlX2NyZWF0aW9uKHRoaXMudGVtcGxhdGVyLCBmaWxlKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2luLnJlZ2lzdGVyRXZlbnQodGhpcy50cmlnZ2VyX29uX2ZpbGVfY3JlYXRpb25fZXZlbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMudHJpZ2dlcl9vbl9maWxlX2NyZWF0aW9uX2V2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcHAudmF1bHQub2ZmcmVmKHRoaXMudHJpZ2dlcl9vbl9maWxlX2NyZWF0aW9uX2V2ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJfb25fZmlsZV9jcmVhdGlvbl9ldmVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZV9maWxlX21lbnUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMucGx1Z2luLnJlZ2lzdGVyRXZlbnQoXG4gICAgICAgICAgICB0aGlzLmFwcC53b3Jrc3BhY2Uub24oXCJmaWxlLW1lbnVcIiwgKG1lbnU6IE1lbnUsIGZpbGU6IFRGaWxlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lbnUuYWRkSXRlbSgoaXRlbTogTWVudUl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uc2V0VGl0bGUoXCJDcmVhdGUgbmV3IG5vdGUgZnJvbSB0ZW1wbGF0ZVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRJY29uKFwidGVtcGxhdGVyLWljb25cIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub25DbGljaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLmZ1enp5X3N1Z2dlc3Rlci5jcmVhdGVfbmV3X25vdGVfZnJvbV90ZW1wbGF0ZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBBcHAgfSBmcm9tIFwib2JzaWRpYW5cIjtcblxuaW1wb3J0IFRlbXBsYXRlclBsdWdpbiBmcm9tIFwibWFpblwiO1xuaW1wb3J0IHsgcmVzb2x2ZV90ZmlsZSB9IGZyb20gXCJVdGlsc1wiO1xuaW1wb3J0IHsgZXJyb3JXcmFwcGVyU3luYyB9IGZyb20gXCJFcnJvclwiO1xuXG5leHBvcnQgY2xhc3MgQ29tbWFuZEhhbmRsZXIge1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgYXBwOiBBcHAsIHByaXZhdGUgcGx1Z2luOiBUZW1wbGF0ZXJQbHVnaW4pIHt9XG5cbiAgICBzZXR1cCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5wbHVnaW4uYWRkQ29tbWFuZCh7XG4gICAgICAgICAgICBpZDogXCJpbnNlcnQtdGVtcGxhdGVyXCIsXG4gICAgICAgICAgICBuYW1lOiBcIk9wZW4gSW5zZXJ0IFRlbXBsYXRlIG1vZGFsXCIsXG4gICAgICAgICAgICBob3RrZXlzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiXSxcbiAgICAgICAgICAgICAgICAgICAga2V5OiBcImVcIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNhbGxiYWNrOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uZnV6enlfc3VnZ2VzdGVyLmluc2VydF90ZW1wbGF0ZSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wbHVnaW4uYWRkQ29tbWFuZCh7XG4gICAgICAgICAgICBpZDogXCJyZXBsYWNlLWluLWZpbGUtdGVtcGxhdGVyXCIsXG4gICAgICAgICAgICBuYW1lOiBcIlJlcGxhY2UgdGVtcGxhdGVzIGluIHRoZSBhY3RpdmUgZmlsZVwiLFxuICAgICAgICAgICAgaG90a2V5czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbW9kaWZpZXJzOiBbXCJBbHRcIl0sXG4gICAgICAgICAgICAgICAgICAgIGtleTogXCJyXCIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjYWxsYmFjazogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnRlbXBsYXRlci5vdmVyd3JpdGVfYWN0aXZlX2ZpbGVfY29tbWFuZHMoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucGx1Z2luLmFkZENvbW1hbmQoe1xuICAgICAgICAgICAgaWQ6IFwianVtcC10by1uZXh0LWN1cnNvci1sb2NhdGlvblwiLFxuICAgICAgICAgICAgbmFtZTogXCJKdW1wIHRvIG5leHQgY3Vyc29yIGxvY2F0aW9uXCIsXG4gICAgICAgICAgICBob3RrZXlzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiXSxcbiAgICAgICAgICAgICAgICAgICAga2V5OiBcIlRhYlwiLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi50ZW1wbGF0ZXIuZWRpdG9yLmp1bXBfdG9fbmV4dF9jdXJzb3JfbG9jYXRpb24oKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucGx1Z2luLmFkZENvbW1hbmQoe1xuICAgICAgICAgICAgaWQ6IFwiY3JlYXRlLW5ldy1ub3RlLWZyb20tdGVtcGxhdGVcIixcbiAgICAgICAgICAgIG5hbWU6IFwiQ3JlYXRlIG5ldyBub3RlIGZyb20gdGVtcGxhdGVcIixcbiAgICAgICAgICAgIGhvdGtleXM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1vZGlmaWVyczogW1wiQWx0XCJdLFxuICAgICAgICAgICAgICAgICAgICBrZXk6IFwiblwiLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5mdXp6eV9zdWdnZXN0ZXIuY3JlYXRlX25ld19ub3RlX2Zyb21fdGVtcGxhdGUoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucmVnaXN0ZXJfdGVtcGxhdGVzX2hvdGtleXMoKTtcbiAgICB9XG5cbiAgICByZWdpc3Rlcl90ZW1wbGF0ZXNfaG90a2V5cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZW5hYmxlZF90ZW1wbGF0ZXNfaG90a2V5cy5mb3JFYWNoKCh0ZW1wbGF0ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRfdGVtcGxhdGVfaG90a2V5KG51bGwsIHRlbXBsYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYWRkX3RlbXBsYXRlX2hvdGtleShvbGRfdGVtcGxhdGU6IHN0cmluZywgbmV3X3RlbXBsYXRlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yZW1vdmVfdGVtcGxhdGVfaG90a2V5KG9sZF90ZW1wbGF0ZSk7XG5cbiAgICAgICAgaWYgKG5ld190ZW1wbGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uYWRkQ29tbWFuZCh7XG4gICAgICAgICAgICAgICAgaWQ6IG5ld190ZW1wbGF0ZSxcbiAgICAgICAgICAgICAgICBuYW1lOiBgSW5zZXJ0ICR7bmV3X3RlbXBsYXRlfWAsXG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBlcnJvcldyYXBwZXJTeW5jKFxuICAgICAgICAgICAgICAgICAgICAgICAgKCkgPT4gcmVzb2x2ZV90ZmlsZSh0aGlzLmFwcCwgbmV3X3RlbXBsYXRlKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGBDb3VsZG4ndCBmaW5kIHRoZSB0ZW1wbGF0ZSBmaWxlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGhvdGtleWBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZW1wbGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnRlbXBsYXRlci5hcHBlbmRfdGVtcGxhdGVfdG9fYWN0aXZlX2ZpbGUoXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbW92ZV90ZW1wbGF0ZV9ob3RrZXkodGVtcGxhdGU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBpZiAodGVtcGxhdGUpIHtcbiAgICAgICAgICAgIC8vIFRPRE86IEZpbmQgb2ZmaWNpYWwgd2F5IHRvIGRvIHRoaXNcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIHRoaXMuYXBwLmNvbW1hbmRzLnJlbW92ZUNvbW1hbmQoXG4gICAgICAgICAgICAgICAgYCR7dGhpcy5wbHVnaW4ubWFuaWZlc3QuaWR9OiR7dGVtcGxhdGV9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImltcG9ydCB7IGFkZEljb24sIFBsdWdpbiB9IGZyb20gXCJvYnNpZGlhblwiO1xuXG5pbXBvcnQgeyBERUZBVUxUX1NFVFRJTkdTLCBTZXR0aW5ncywgVGVtcGxhdGVyU2V0dGluZ1RhYiB9IGZyb20gXCJTZXR0aW5nc1wiO1xuaW1wb3J0IHsgRnV6enlTdWdnZXN0ZXIgfSBmcm9tIFwiRnV6enlTdWdnZXN0ZXJcIjtcbmltcG9ydCB7IElDT05fREFUQSB9IGZyb20gXCJDb25zdGFudHNcIjtcbmltcG9ydCB7IFRlbXBsYXRlciB9IGZyb20gXCJUZW1wbGF0ZXJcIjtcbmltcG9ydCBFdmVudEhhbmRsZXIgZnJvbSBcIkV2ZW50SGFuZGxlclwiO1xuaW1wb3J0IHsgQ29tbWFuZEhhbmRsZXIgfSBmcm9tIFwiQ29tbWFuZEhhbmRsZXJcIjtcbmltcG9ydCB7IFRwRG9jdW1lbnRhdGlvbiB9IGZyb20gXCJmdW5jdGlvbnMvVHBEb2N1bWVudGF0aW9uXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlbXBsYXRlclBsdWdpbiBleHRlbmRzIFBsdWdpbiB7XG4gICAgcHVibGljIHNldHRpbmdzOiBTZXR0aW5ncztcbiAgICBwdWJsaWMgdGVtcGxhdGVyOiBUZW1wbGF0ZXI7XG4gICAgcHVibGljIGV2ZW50X2hhbmRsZXI6IEV2ZW50SGFuZGxlcjtcbiAgICBwdWJsaWMgY29tbWFuZF9oYW5kbGVyOiBDb21tYW5kSGFuZGxlcjtcbiAgICBwdWJsaWMgZnV6enlfc3VnZ2VzdGVyOiBGdXp6eVN1Z2dlc3RlcjtcblxuICAgIGFzeW5jIG9ubG9hZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5sb2FkX3NldHRpbmdzKCk7XG5cbiAgICAgICAgdGhpcy50ZW1wbGF0ZXIgPSBuZXcgVGVtcGxhdGVyKHRoaXMuYXBwLCB0aGlzKTtcbiAgICAgICAgYXdhaXQgdGhpcy50ZW1wbGF0ZXIuc2V0dXAoKTtcblxuICAgICAgICB0aGlzLmZ1enp5X3N1Z2dlc3RlciA9IG5ldyBGdXp6eVN1Z2dlc3Rlcih0aGlzLmFwcCwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5ldmVudF9oYW5kbGVyID0gbmV3IEV2ZW50SGFuZGxlcihcbiAgICAgICAgICAgIHRoaXMuYXBwLFxuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIHRoaXMudGVtcGxhdGVyLFxuICAgICAgICAgICAgdGhpcy5zZXR0aW5nc1xuICAgICAgICApO1xuICAgICAgICB0aGlzLmV2ZW50X2hhbmRsZXIuc2V0dXAoKTtcblxuICAgICAgICB0aGlzLmNvbW1hbmRfaGFuZGxlciA9IG5ldyBDb21tYW5kSGFuZGxlcih0aGlzLmFwcCwgdGhpcyk7XG4gICAgICAgIHRoaXMuY29tbWFuZF9oYW5kbGVyLnNldHVwKCk7XG5cbiAgICAgICAgYWRkSWNvbihcInRlbXBsYXRlci1pY29uXCIsIElDT05fREFUQSk7XG4gICAgICAgIHRoaXMuYWRkUmliYm9uSWNvbihcInRlbXBsYXRlci1pY29uXCIsIFwiVGVtcGxhdGVyXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZnV6enlfc3VnZ2VzdGVyLmluc2VydF90ZW1wbGF0ZSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmFkZFNldHRpbmdUYWIobmV3IFRlbXBsYXRlclNldHRpbmdUYWIodGhpcy5hcHAsIHRoaXMpKTtcblxuICAgICAgICAvLyBGaWxlcyBtaWdodCBub3QgYmUgY3JlYXRlZCB5ZXRcbiAgICAgICAgdGhpcy5hcHAud29ya3NwYWNlLm9uTGF5b3V0UmVhZHkoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy50ZW1wbGF0ZXIuZXhlY3V0ZV9zdGFydHVwX3NjcmlwdHMoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgc2F2ZV9zZXR0aW5ncygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcbiAgICB9XG5cbiAgICBhc3luYyBsb2FkX3NldHRpbmdzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAgREVGQVVMVF9TRVRUSU5HUyxcbiAgICAgICAgICAgIGF3YWl0IHRoaXMubG9hZERhdGEoKVxuICAgICAgICApO1xuICAgIH1cbn1cbiJdLCJuYW1lcyI6WyJOb3RpY2UiLCJlZmZlY3QiLCJtaW4iLCJtYXgiLCJtYXRoTWF4IiwibWF0aE1pbiIsImhhc2giLCJhbGxQbGFjZW1lbnRzIiwicGxhY2VtZW50cyIsInBvcHBlck9mZnNldHMiLCJjb21wdXRlU3R5bGVzIiwiYXBwbHlTdHlsZXMiLCJvZmZzZXQiLCJmbGlwIiwicHJldmVudE92ZXJmbG93IiwiYXJyb3ciLCJoaWRlIiwiU2NvcGUiLCJURm9sZGVyIiwibm9ybWFsaXplUGF0aCIsIlRGaWxlIiwiVmF1bHQiLCJQbHVnaW5TZXR0aW5nVGFiIiwiU2V0dGluZyIsIkZ1enp5U3VnZ2VzdE1vZGFsIiwiTWFya2Rvd25WaWV3IiwicGFyc2VMaW5rdGV4dCIsInJlc29sdmVTdWJwYXRoIiwiUGxhdGZvcm0iLCJGaWxlU3lzdGVtQWRhcHRlciIsImdldEFsbFRhZ3MiLCJNb2RhbCIsInByb21pc2lmeSIsImV4ZWMiLCJvYnNpZGlhbl9tb2R1bGUiLCJFZGl0b3JTdWdnZXN0IiwicmVzb2x2ZSIsImRpcm5hbWUiLCJleHRuYW1lIiwiZXhpc3RzU3luYyIsInJlYWRGaWxlU3luYyIsIkV0YS5yZW5kZXJBc3luYyIsIlBsdWdpbiIsImFkZEljb24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF1REE7QUFDTyxTQUFTLFNBQVMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUU7QUFDN0QsSUFBSSxTQUFTLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEtBQUssWUFBWSxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLFVBQVUsT0FBTyxFQUFFLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDaEgsSUFBSSxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxVQUFVLE9BQU8sRUFBRSxNQUFNLEVBQUU7QUFDL0QsUUFBUSxTQUFTLFNBQVMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FB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
|