Files
speckle-server/scratch/edge-debug-selection/Default/Cache/Cache_Data/f_00003a
T

2732 lines
377 KiB
Plaintext

/*!
* vue-router v4.5.1
* (c) 2025 Eduardo San Martin Morote
* @license MIT
*/
import { getCurrentInstance, inject, onUnmounted, onDeactivated, onActivated, computed, unref, watchEffect, defineComponent, reactive, h, provide, ref, watch, shallowRef, shallowReactive, nextTick } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
import { setupDevtoolsPlugin } from "/_nuxt/node_modules/@vue/devtools-api/lib/esm/index.js?v=e4f18c29";
const isBrowser = typeof document !== "undefined";
function isRouteComponent(component) {
return typeof component === "object" || "displayName" in component || "props" in component || "__vccOpts" in component;
}
function isESModule(obj) {
return obj.__esModule || obj[Symbol.toStringTag] === "Module" || // support CF with dynamic imports that do not
// add the Module string tag
obj.default && isRouteComponent(obj.default);
}
const assign = Object.assign;
function applyToParams(fn, params) {
const newParams = {};
for (const key in params) {
const value = params[key];
newParams[key] = isArray(value) ? value.map(fn) : fn(value);
}
return newParams;
}
const noop = () => {
};
const isArray = Array.isArray;
function warn(msg) {
const args = Array.from(arguments).slice(1);
console.warn.apply(console, ["[Vue Router warn]: " + msg].concat(args));
}
const HASH_RE = /#/g;
const AMPERSAND_RE = /&/g;
const SLASH_RE = /\//g;
const EQUAL_RE = /=/g;
const IM_RE = /\?/g;
const PLUS_RE = /\+/g;
const ENC_BRACKET_OPEN_RE = /%5B/g;
const ENC_BRACKET_CLOSE_RE = /%5D/g;
const ENC_CARET_RE = /%5E/g;
const ENC_BACKTICK_RE = /%60/g;
const ENC_CURLY_OPEN_RE = /%7B/g;
const ENC_PIPE_RE = /%7C/g;
const ENC_CURLY_CLOSE_RE = /%7D/g;
const ENC_SPACE_RE = /%20/g;
function commonEncode(text) {
return encodeURI("" + text).replace(ENC_PIPE_RE, "|").replace(ENC_BRACKET_OPEN_RE, "[").replace(ENC_BRACKET_CLOSE_RE, "]");
}
function encodeHash(text) {
return commonEncode(text).replace(ENC_CURLY_OPEN_RE, "{").replace(ENC_CURLY_CLOSE_RE, "}").replace(ENC_CARET_RE, "^");
}
function encodeQueryValue(text) {
return commonEncode(text).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CURLY_OPEN_RE, "{").replace(ENC_CURLY_CLOSE_RE, "}").replace(ENC_CARET_RE, "^");
}
function encodeQueryKey(text) {
return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
}
function encodePath(text) {
return commonEncode(text).replace(HASH_RE, "%23").replace(IM_RE, "%3F");
}
function encodeParam(text) {
return text == null ? "" : encodePath(text).replace(SLASH_RE, "%2F");
}
function decode(text) {
try {
return decodeURIComponent("" + text);
} catch (err) {
warn(`Error decoding "${text}". Using original value`);
}
return "" + text;
}
const TRAILING_SLASH_RE = /\/$/;
const removeTrailingSlash = (path) => path.replace(TRAILING_SLASH_RE, "");
function parseURL(parseQuery2, location2, currentLocation = "/") {
let path, query = {}, searchString = "", hash = "";
const hashPos = location2.indexOf("#");
let searchPos = location2.indexOf("?");
if (hashPos < searchPos && hashPos >= 0) {
searchPos = -1;
}
if (searchPos > -1) {
path = location2.slice(0, searchPos);
searchString = location2.slice(searchPos + 1, hashPos > -1 ? hashPos : location2.length);
query = parseQuery2(searchString);
}
if (hashPos > -1) {
path = path || location2.slice(0, hashPos);
hash = location2.slice(hashPos, location2.length);
}
path = resolveRelativePath(path != null ? path : location2, currentLocation);
return {
fullPath: path + (searchString && "?") + searchString + hash,
path,
query,
hash: decode(hash)
};
}
function stringifyURL(stringifyQuery2, location2) {
const query = location2.query ? stringifyQuery2(location2.query) : "";
return location2.path + (query && "?") + query + (location2.hash || "");
}
function stripBase(pathname, base) {
if (!base || !pathname.toLowerCase().startsWith(base.toLowerCase()))
return pathname;
return pathname.slice(base.length) || "/";
}
function isSameRouteLocation(stringifyQuery2, a, b) {
const aLastIndex = a.matched.length - 1;
const bLastIndex = b.matched.length - 1;
return aLastIndex > -1 && aLastIndex === bLastIndex && isSameRouteRecord(a.matched[aLastIndex], b.matched[bLastIndex]) && isSameRouteLocationParams(a.params, b.params) && stringifyQuery2(a.query) === stringifyQuery2(b.query) && a.hash === b.hash;
}
function isSameRouteRecord(a, b) {
return (a.aliasOf || a) === (b.aliasOf || b);
}
function isSameRouteLocationParams(a, b) {
if (Object.keys(a).length !== Object.keys(b).length)
return false;
for (const key in a) {
if (!isSameRouteLocationParamsValue(a[key], b[key]))
return false;
}
return true;
}
function isSameRouteLocationParamsValue(a, b) {
return isArray(a) ? isEquivalentArray(a, b) : isArray(b) ? isEquivalentArray(b, a) : a === b;
}
function isEquivalentArray(a, b) {
return isArray(b) ? a.length === b.length && a.every((value, i) => value === b[i]) : a.length === 1 && a[0] === b;
}
function resolveRelativePath(to, from) {
if (to.startsWith("/"))
return to;
if (!from.startsWith("/")) {
warn(`Cannot resolve a relative location without an absolute path. Trying to resolve "${to}" from "${from}". It should look like "/${from}".`);
return to;
}
if (!to)
return from;
const fromSegments = from.split("/");
const toSegments = to.split("/");
const lastToSegment = toSegments[toSegments.length - 1];
if (lastToSegment === ".." || lastToSegment === ".") {
toSegments.push("");
}
let position = fromSegments.length - 1;
let toPosition;
let segment;
for (toPosition = 0; toPosition < toSegments.length; toPosition++) {
segment = toSegments[toPosition];
if (segment === ".")
continue;
if (segment === "..") {
if (position > 1)
position--;
} else
break;
}
return fromSegments.slice(0, position).join("/") + "/" + toSegments.slice(toPosition).join("/");
}
const START_LOCATION_NORMALIZED = {
path: "/",
// TODO: could we use a symbol in the future?
name: void 0,
params: {},
query: {},
hash: "",
fullPath: "/",
matched: [],
meta: {},
redirectedFrom: void 0
};
var NavigationType;
(function(NavigationType2) {
NavigationType2["pop"] = "pop";
NavigationType2["push"] = "push";
})(NavigationType || (NavigationType = {}));
var NavigationDirection;
(function(NavigationDirection2) {
NavigationDirection2["back"] = "back";
NavigationDirection2["forward"] = "forward";
NavigationDirection2["unknown"] = "";
})(NavigationDirection || (NavigationDirection = {}));
const START = "";
function normalizeBase(base) {
if (!base) {
if (isBrowser) {
const baseEl = document.querySelector("base");
base = baseEl && baseEl.getAttribute("href") || "/";
base = base.replace(/^\w+:\/\/[^\/]+/, "");
} else {
base = "/";
}
}
if (base[0] !== "/" && base[0] !== "#")
base = "/" + base;
return removeTrailingSlash(base);
}
const BEFORE_HASH_RE = /^[^#]+#/;
function createHref(base, location2) {
return base.replace(BEFORE_HASH_RE, "#") + location2;
}
function getElementPosition(el, offset) {
const docRect = document.documentElement.getBoundingClientRect();
const elRect = el.getBoundingClientRect();
return {
behavior: offset.behavior,
left: elRect.left - docRect.left - (offset.left || 0),
top: elRect.top - docRect.top - (offset.top || 0)
};
}
const computeScrollPosition = () => ({
left: window.scrollX,
top: window.scrollY
});
function scrollToPosition(position) {
let scrollToOptions;
if ("el" in position) {
const positionEl = position.el;
const isIdSelector = typeof positionEl === "string" && positionEl.startsWith("#");
if (typeof position.el === "string") {
if (!isIdSelector || !document.getElementById(position.el.slice(1))) {
try {
const foundEl = document.querySelector(position.el);
if (isIdSelector && foundEl) {
warn(`The selector "${position.el}" should be passed as "el: document.querySelector('${position.el}')" because it starts with "#".`);
return;
}
} catch (err) {
warn(`The selector "${position.el}" is invalid. If you are using an id selector, make sure to escape it. You can find more information about escaping characters in selectors at https://mathiasbynens.be/notes/css-escapes or use CSS.escape (https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape).`);
return;
}
}
}
const el = typeof positionEl === "string" ? isIdSelector ? document.getElementById(positionEl.slice(1)) : document.querySelector(positionEl) : positionEl;
if (!el) {
warn(`Couldn't find element using selector "${position.el}" returned by scrollBehavior.`);
return;
}
scrollToOptions = getElementPosition(el, position);
} else {
scrollToOptions = position;
}
if ("scrollBehavior" in document.documentElement.style)
window.scrollTo(scrollToOptions);
else {
window.scrollTo(scrollToOptions.left != null ? scrollToOptions.left : window.scrollX, scrollToOptions.top != null ? scrollToOptions.top : window.scrollY);
}
}
function getScrollKey(path, delta) {
const position = history.state ? history.state.position - delta : -1;
return position + path;
}
const scrollPositions = /* @__PURE__ */ new Map();
function saveScrollPosition(key, scrollPosition) {
scrollPositions.set(key, scrollPosition);
}
function getSavedScrollPosition(key) {
const scroll = scrollPositions.get(key);
scrollPositions.delete(key);
return scroll;
}
let createBaseLocation = () => location.protocol + "//" + location.host;
function createCurrentLocation(base, location2) {
const { pathname, search, hash } = location2;
const hashPos = base.indexOf("#");
if (hashPos > -1) {
let slicePos = hash.includes(base.slice(hashPos)) ? base.slice(hashPos).length : 1;
let pathFromHash = hash.slice(slicePos);
if (pathFromHash[0] !== "/")
pathFromHash = "/" + pathFromHash;
return stripBase(pathFromHash, "");
}
const path = stripBase(pathname, base);
return path + search + hash;
}
function useHistoryListeners(base, historyState, currentLocation, replace) {
let listeners = [];
let teardowns = [];
let pauseState = null;
const popStateHandler = ({ state }) => {
const to = createCurrentLocation(base, location);
const from = currentLocation.value;
const fromState = historyState.value;
let delta = 0;
if (state) {
currentLocation.value = to;
historyState.value = state;
if (pauseState && pauseState === from) {
pauseState = null;
return;
}
delta = fromState ? state.position - fromState.position : 0;
} else {
replace(to);
}
listeners.forEach((listener) => {
listener(currentLocation.value, from, {
delta,
type: NavigationType.pop,
direction: delta ? delta > 0 ? NavigationDirection.forward : NavigationDirection.back : NavigationDirection.unknown
});
});
};
function pauseListeners() {
pauseState = currentLocation.value;
}
function listen(callback) {
listeners.push(callback);
const teardown = () => {
const index = listeners.indexOf(callback);
if (index > -1)
listeners.splice(index, 1);
};
teardowns.push(teardown);
return teardown;
}
function beforeUnloadListener() {
const { history: history2 } = window;
if (!history2.state)
return;
history2.replaceState(assign({}, history2.state, { scroll: computeScrollPosition() }), "");
}
function destroy() {
for (const teardown of teardowns)
teardown();
teardowns = [];
window.removeEventListener("popstate", popStateHandler);
window.removeEventListener("beforeunload", beforeUnloadListener);
}
window.addEventListener("popstate", popStateHandler);
window.addEventListener("beforeunload", beforeUnloadListener, {
passive: true
});
return {
pauseListeners,
listen,
destroy
};
}
function buildState(back, current, forward, replaced = false, computeScroll = false) {
return {
back,
current,
forward,
replaced,
position: window.history.length,
scroll: computeScroll ? computeScrollPosition() : null
};
}
function useHistoryStateNavigation(base) {
const { history: history2, location: location2 } = window;
const currentLocation = {
value: createCurrentLocation(base, location2)
};
const historyState = { value: history2.state };
if (!historyState.value) {
changeLocation(currentLocation.value, {
back: null,
current: currentLocation.value,
forward: null,
// the length is off by one, we need to decrease it
position: history2.length - 1,
replaced: true,
// don't add a scroll as the user may have an anchor, and we want
// scrollBehavior to be triggered without a saved position
scroll: null
}, true);
}
function changeLocation(to, state, replace2) {
const hashIndex = base.indexOf("#");
const url = hashIndex > -1 ? (location2.host && document.querySelector("base") ? base : base.slice(hashIndex)) + to : createBaseLocation() + base + to;
try {
history2[replace2 ? "replaceState" : "pushState"](state, "", url);
historyState.value = state;
} catch (err) {
if (true) {
warn("Error with push/replace State", err);
} else {
console.error(err);
}
location2[replace2 ? "replace" : "assign"](url);
}
}
function replace(to, data) {
const state = assign({}, history2.state, buildState(
historyState.value.back,
// keep back and forward entries but override current position
to,
historyState.value.forward,
true
), data, { position: historyState.value.position });
changeLocation(to, state, true);
currentLocation.value = to;
}
function push(to, data) {
const currentState = assign(
{},
// use current history state to gracefully handle a wrong call to
// history.replaceState
// https://github.com/vuejs/router/issues/366
historyState.value,
history2.state,
{
forward: to,
scroll: computeScrollPosition()
}
);
if (!history2.state) {
warn(`history.state seems to have been manually replaced without preserving the necessary values. Make sure to preserve existing history state if you are manually calling history.replaceState:
history.replaceState(history.state, '', url)
You can find more information at https://router.vuejs.org/guide/migration/#Usage-of-history-state`);
}
changeLocation(currentState.current, currentState, true);
const state = assign({}, buildState(currentLocation.value, to, null), { position: currentState.position + 1 }, data);
changeLocation(to, state, false);
currentLocation.value = to;
}
return {
location: currentLocation,
state: historyState,
push,
replace
};
}
function createWebHistory(base) {
base = normalizeBase(base);
const historyNavigation = useHistoryStateNavigation(base);
const historyListeners = useHistoryListeners(base, historyNavigation.state, historyNavigation.location, historyNavigation.replace);
function go(delta, triggerListeners = true) {
if (!triggerListeners)
historyListeners.pauseListeners();
history.go(delta);
}
const routerHistory = assign({
// it's overridden right after
location: "",
base,
go,
createHref: createHref.bind(null, base)
}, historyNavigation, historyListeners);
Object.defineProperty(routerHistory, "location", {
enumerable: true,
get: () => historyNavigation.location.value
});
Object.defineProperty(routerHistory, "state", {
enumerable: true,
get: () => historyNavigation.state.value
});
return routerHistory;
}
function createMemoryHistory(base = "") {
let listeners = [];
let queue = [[START, {}]];
let position = 0;
base = normalizeBase(base);
function setLocation(location2, state = {}) {
position++;
if (position !== queue.length) {
queue.splice(position);
}
queue.push([location2, state]);
}
function triggerListeners(to, from, { direction, delta }) {
const info = {
direction,
delta,
type: NavigationType.pop
};
for (const callback of listeners) {
callback(to, from, info);
}
}
const routerHistory = {
// rewritten by Object.defineProperty
location: START,
// rewritten by Object.defineProperty
state: {},
base,
createHref: createHref.bind(null, base),
replace(to, state) {
queue.splice(position--, 1);
setLocation(to, state);
},
push(to, state) {
setLocation(to, state);
},
listen(callback) {
listeners.push(callback);
return () => {
const index = listeners.indexOf(callback);
if (index > -1)
listeners.splice(index, 1);
};
},
destroy() {
listeners = [];
queue = [[START, {}]];
position = 0;
},
go(delta, shouldTrigger = true) {
const from = this.location;
const direction = (
// we are considering delta === 0 going forward, but in abstract mode
// using 0 for the delta doesn't make sense like it does in html5 where
// it reloads the page
delta < 0 ? NavigationDirection.back : NavigationDirection.forward
);
position = Math.max(0, Math.min(position + delta, queue.length - 1));
if (shouldTrigger) {
triggerListeners(this.location, from, {
direction,
delta
});
}
}
};
Object.defineProperty(routerHistory, "location", {
enumerable: true,
get: () => queue[position][0]
});
Object.defineProperty(routerHistory, "state", {
enumerable: true,
get: () => queue[position][1]
});
return routerHistory;
}
function createWebHashHistory(base) {
base = location.host ? base || location.pathname + location.search : "";
if (!base.includes("#"))
base += "#";
if (!base.endsWith("#/") && !base.endsWith("#")) {
warn(`A hash base must end with a "#":
"${base}" should be "${base.replace(/#.*$/, "#")}".`);
}
return createWebHistory(base);
}
function isRouteLocation(route) {
return typeof route === "string" || route && typeof route === "object";
}
function isRouteName(name) {
return typeof name === "string" || typeof name === "symbol";
}
const NavigationFailureSymbol = Symbol(true ? "navigation failure" : "");
var NavigationFailureType;
(function(NavigationFailureType2) {
NavigationFailureType2[NavigationFailureType2["aborted"] = 4] = "aborted";
NavigationFailureType2[NavigationFailureType2["cancelled"] = 8] = "cancelled";
NavigationFailureType2[NavigationFailureType2["duplicated"] = 16] = "duplicated";
})(NavigationFailureType || (NavigationFailureType = {}));
const ErrorTypeMessages = {
[
1
/* ErrorTypes.MATCHER_NOT_FOUND */
]({ location: location2, currentLocation }) {
return `No match for
${JSON.stringify(location2)}${currentLocation ? "\nwhile being at\n" + JSON.stringify(currentLocation) : ""}`;
},
[
2
/* ErrorTypes.NAVIGATION_GUARD_REDIRECT */
]({ from, to }) {
return `Redirected from "${from.fullPath}" to "${stringifyRoute(to)}" via a navigation guard.`;
},
[
4
/* ErrorTypes.NAVIGATION_ABORTED */
]({ from, to }) {
return `Navigation aborted from "${from.fullPath}" to "${to.fullPath}" via a navigation guard.`;
},
[
8
/* ErrorTypes.NAVIGATION_CANCELLED */
]({ from, to }) {
return `Navigation cancelled from "${from.fullPath}" to "${to.fullPath}" with a new navigation.`;
},
[
16
/* ErrorTypes.NAVIGATION_DUPLICATED */
]({ from, to }) {
return `Avoided redundant navigation to current location: "${from.fullPath}".`;
}
};
function createRouterError(type, params) {
if (true) {
return assign(new Error(ErrorTypeMessages[type](params)), {
type,
[NavigationFailureSymbol]: true
}, params);
} else {
return assign(new Error(), {
type,
[NavigationFailureSymbol]: true
}, params);
}
}
function isNavigationFailure(error, type) {
return error instanceof Error && NavigationFailureSymbol in error && (type == null || !!(error.type & type));
}
const propertiesToLog = ["params", "query", "hash"];
function stringifyRoute(to) {
if (typeof to === "string")
return to;
if (to.path != null)
return to.path;
const location2 = {};
for (const key of propertiesToLog) {
if (key in to)
location2[key] = to[key];
}
return JSON.stringify(location2, null, 2);
}
const BASE_PARAM_PATTERN = "[^/]+?";
const BASE_PATH_PARSER_OPTIONS = {
sensitive: false,
strict: false,
start: true,
end: true
};
const REGEX_CHARS_RE = /[.+*?^${}()[\]/\\]/g;
function tokensToParser(segments, extraOptions) {
const options = assign({}, BASE_PATH_PARSER_OPTIONS, extraOptions);
const score = [];
let pattern = options.start ? "^" : "";
const keys = [];
for (const segment of segments) {
const segmentScores = segment.length ? [] : [
90
/* PathScore.Root */
];
if (options.strict && !segment.length)
pattern += "/";
for (let tokenIndex = 0; tokenIndex < segment.length; tokenIndex++) {
const token = segment[tokenIndex];
let subSegmentScore = 40 + (options.sensitive ? 0.25 : 0);
if (token.type === 0) {
if (!tokenIndex)
pattern += "/";
pattern += token.value.replace(REGEX_CHARS_RE, "\\$&");
subSegmentScore += 40;
} else if (token.type === 1) {
const { value, repeatable, optional, regexp } = token;
keys.push({
name: value,
repeatable,
optional
});
const re2 = regexp ? regexp : BASE_PARAM_PATTERN;
if (re2 !== BASE_PARAM_PATTERN) {
subSegmentScore += 10;
try {
new RegExp(`(${re2})`);
} catch (err) {
throw new Error(`Invalid custom RegExp for param "${value}" (${re2}): ` + err.message);
}
}
let subPattern = repeatable ? `((?:${re2})(?:/(?:${re2}))*)` : `(${re2})`;
if (!tokenIndex)
subPattern = // avoid an optional / if there are more segments e.g. /:p?-static
// or /:p?-:p2
optional && segment.length < 2 ? `(?:/${subPattern})` : "/" + subPattern;
if (optional)
subPattern += "?";
pattern += subPattern;
subSegmentScore += 20;
if (optional)
subSegmentScore += -8;
if (repeatable)
subSegmentScore += -20;
if (re2 === ".*")
subSegmentScore += -50;
}
segmentScores.push(subSegmentScore);
}
score.push(segmentScores);
}
if (options.strict && options.end) {
const i = score.length - 1;
score[i][score[i].length - 1] += 0.7000000000000001;
}
if (!options.strict)
pattern += "/?";
if (options.end)
pattern += "$";
else if (options.strict && !pattern.endsWith("/"))
pattern += "(?:/|$)";
const re = new RegExp(pattern, options.sensitive ? "" : "i");
function parse(path) {
const match = path.match(re);
const params = {};
if (!match)
return null;
for (let i = 1; i < match.length; i++) {
const value = match[i] || "";
const key = keys[i - 1];
params[key.name] = value && key.repeatable ? value.split("/") : value;
}
return params;
}
function stringify(params) {
let path = "";
let avoidDuplicatedSlash = false;
for (const segment of segments) {
if (!avoidDuplicatedSlash || !path.endsWith("/"))
path += "/";
avoidDuplicatedSlash = false;
for (const token of segment) {
if (token.type === 0) {
path += token.value;
} else if (token.type === 1) {
const { value, repeatable, optional } = token;
const param = value in params ? params[value] : "";
if (isArray(param) && !repeatable) {
throw new Error(`Provided param "${value}" is an array but it is not repeatable (* or + modifiers)`);
}
const text = isArray(param) ? param.join("/") : param;
if (!text) {
if (optional) {
if (segment.length < 2) {
if (path.endsWith("/"))
path = path.slice(0, -1);
else
avoidDuplicatedSlash = true;
}
} else
throw new Error(`Missing required param "${value}"`);
}
path += text;
}
}
}
return path || "/";
}
return {
re,
score,
keys,
parse,
stringify
};
}
function compareScoreArray(a, b) {
let i = 0;
while (i < a.length && i < b.length) {
const diff = b[i] - a[i];
if (diff)
return diff;
i++;
}
if (a.length < b.length) {
return a.length === 1 && a[0] === 40 + 40 ? -1 : 1;
} else if (a.length > b.length) {
return b.length === 1 && b[0] === 40 + 40 ? 1 : -1;
}
return 0;
}
function comparePathParserScore(a, b) {
let i = 0;
const aScore = a.score;
const bScore = b.score;
while (i < aScore.length && i < bScore.length) {
const comp = compareScoreArray(aScore[i], bScore[i]);
if (comp)
return comp;
i++;
}
if (Math.abs(bScore.length - aScore.length) === 1) {
if (isLastScoreNegative(aScore))
return 1;
if (isLastScoreNegative(bScore))
return -1;
}
return bScore.length - aScore.length;
}
function isLastScoreNegative(score) {
const last = score[score.length - 1];
return score.length > 0 && last[last.length - 1] < 0;
}
const ROOT_TOKEN = {
type: 0,
value: ""
};
const VALID_PARAM_RE = /[a-zA-Z0-9_]/;
function tokenizePath(path) {
if (!path)
return [[]];
if (path === "/")
return [[ROOT_TOKEN]];
if (!path.startsWith("/")) {
throw new Error(true ? `Route paths should start with a "/": "${path}" should be "/${path}".` : `Invalid path "${path}"`);
}
function crash(message) {
throw new Error(`ERR (${state})/"${buffer}": ${message}`);
}
let state = 0;
let previousState = state;
const tokens = [];
let segment;
function finalizeSegment() {
if (segment)
tokens.push(segment);
segment = [];
}
let i = 0;
let char;
let buffer = "";
let customRe = "";
function consumeBuffer() {
if (!buffer)
return;
if (state === 0) {
segment.push({
type: 0,
value: buffer
});
} else if (state === 1 || state === 2 || state === 3) {
if (segment.length > 1 && (char === "*" || char === "+"))
crash(`A repeatable param (${buffer}) must be alone in its segment. eg: '/:ids+.`);
segment.push({
type: 1,
value: buffer,
regexp: customRe,
repeatable: char === "*" || char === "+",
optional: char === "*" || char === "?"
});
} else {
crash("Invalid state to consume buffer");
}
buffer = "";
}
function addCharToBuffer() {
buffer += char;
}
while (i < path.length) {
char = path[i++];
if (char === "\\" && state !== 2) {
previousState = state;
state = 4;
continue;
}
switch (state) {
case 0:
if (char === "/") {
if (buffer) {
consumeBuffer();
}
finalizeSegment();
} else if (char === ":") {
consumeBuffer();
state = 1;
} else {
addCharToBuffer();
}
break;
case 4:
addCharToBuffer();
state = previousState;
break;
case 1:
if (char === "(") {
state = 2;
} else if (VALID_PARAM_RE.test(char)) {
addCharToBuffer();
} else {
consumeBuffer();
state = 0;
if (char !== "*" && char !== "?" && char !== "+")
i--;
}
break;
case 2:
if (char === ")") {
if (customRe[customRe.length - 1] == "\\")
customRe = customRe.slice(0, -1) + char;
else
state = 3;
} else {
customRe += char;
}
break;
case 3:
consumeBuffer();
state = 0;
if (char !== "*" && char !== "?" && char !== "+")
i--;
customRe = "";
break;
default:
crash("Unknown state");
break;
}
}
if (state === 2)
crash(`Unfinished custom RegExp for param "${buffer}"`);
consumeBuffer();
finalizeSegment();
return tokens;
}
function createRouteRecordMatcher(record, parent, options) {
const parser = tokensToParser(tokenizePath(record.path), options);
if (true) {
const existingKeys = /* @__PURE__ */ new Set();
for (const key of parser.keys) {
if (existingKeys.has(key.name))
warn(`Found duplicated params with name "${key.name}" for path "${record.path}". Only the last one will be available on "$route.params".`);
existingKeys.add(key.name);
}
}
const matcher = assign(parser, {
record,
parent,
// these needs to be populated by the parent
children: [],
alias: []
});
if (parent) {
if (!matcher.record.aliasOf === !parent.record.aliasOf)
parent.children.push(matcher);
}
return matcher;
}
function createRouterMatcher(routes, globalOptions) {
const matchers = [];
const matcherMap = /* @__PURE__ */ new Map();
globalOptions = mergeOptions({ strict: false, end: true, sensitive: false }, globalOptions);
function getRecordMatcher(name) {
return matcherMap.get(name);
}
function addRoute(record, parent, originalRecord) {
const isRootAdd = !originalRecord;
const mainNormalizedRecord = normalizeRouteRecord(record);
if (true) {
checkChildMissingNameWithEmptyPath(mainNormalizedRecord, parent);
}
mainNormalizedRecord.aliasOf = originalRecord && originalRecord.record;
const options = mergeOptions(globalOptions, record);
const normalizedRecords = [mainNormalizedRecord];
if ("alias" in record) {
const aliases = typeof record.alias === "string" ? [record.alias] : record.alias;
for (const alias of aliases) {
normalizedRecords.push(
// we need to normalize again to ensure the `mods` property
// being non enumerable
normalizeRouteRecord(assign({}, mainNormalizedRecord, {
// this allows us to hold a copy of the `components` option
// so that async components cache is hold on the original record
components: originalRecord ? originalRecord.record.components : mainNormalizedRecord.components,
path: alias,
// we might be the child of an alias
aliasOf: originalRecord ? originalRecord.record : mainNormalizedRecord
// the aliases are always of the same kind as the original since they
// are defined on the same record
}))
);
}
}
let matcher;
let originalMatcher;
for (const normalizedRecord of normalizedRecords) {
const { path } = normalizedRecord;
if (parent && path[0] !== "/") {
const parentPath = parent.record.path;
const connectingSlash = parentPath[parentPath.length - 1] === "/" ? "" : "/";
normalizedRecord.path = parent.record.path + (path && connectingSlash + path);
}
if (normalizedRecord.path === "*") {
throw new Error('Catch all routes ("*") must now be defined using a param with a custom regexp.\nSee more at https://router.vuejs.org/guide/migration/#Removed-star-or-catch-all-routes.');
}
matcher = createRouteRecordMatcher(normalizedRecord, parent, options);
if (parent && path[0] === "/")
checkMissingParamsInAbsolutePath(matcher, parent);
if (originalRecord) {
originalRecord.alias.push(matcher);
if (true) {
checkSameParams(originalRecord, matcher);
}
} else {
originalMatcher = originalMatcher || matcher;
if (originalMatcher !== matcher)
originalMatcher.alias.push(matcher);
if (isRootAdd && record.name && !isAliasRecord(matcher)) {
if (true) {
checkSameNameAsAncestor(record, parent);
}
removeRoute(record.name);
}
}
if (isMatchable(matcher)) {
insertMatcher(matcher);
}
if (mainNormalizedRecord.children) {
const children = mainNormalizedRecord.children;
for (let i = 0; i < children.length; i++) {
addRoute(children[i], matcher, originalRecord && originalRecord.children[i]);
}
}
originalRecord = originalRecord || matcher;
}
return originalMatcher ? () => {
removeRoute(originalMatcher);
} : noop;
}
function removeRoute(matcherRef) {
if (isRouteName(matcherRef)) {
const matcher = matcherMap.get(matcherRef);
if (matcher) {
matcherMap.delete(matcherRef);
matchers.splice(matchers.indexOf(matcher), 1);
matcher.children.forEach(removeRoute);
matcher.alias.forEach(removeRoute);
}
} else {
const index = matchers.indexOf(matcherRef);
if (index > -1) {
matchers.splice(index, 1);
if (matcherRef.record.name)
matcherMap.delete(matcherRef.record.name);
matcherRef.children.forEach(removeRoute);
matcherRef.alias.forEach(removeRoute);
}
}
}
function getRoutes() {
return matchers;
}
function insertMatcher(matcher) {
const index = findInsertionIndex(matcher, matchers);
matchers.splice(index, 0, matcher);
if (matcher.record.name && !isAliasRecord(matcher))
matcherMap.set(matcher.record.name, matcher);
}
function resolve(location2, currentLocation) {
let matcher;
let params = {};
let path;
let name;
if ("name" in location2 && location2.name) {
matcher = matcherMap.get(location2.name);
if (!matcher)
throw createRouterError(1, {
location: location2
});
if (true) {
const invalidParams = Object.keys(location2.params || {}).filter((paramName) => !matcher.keys.find((k) => k.name === paramName));
if (invalidParams.length) {
warn(`Discarded invalid param(s) "${invalidParams.join('", "')}" when navigating. See https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22 for more details.`);
}
}
name = matcher.record.name;
params = assign(
// paramsFromLocation is a new object
paramsFromLocation(
currentLocation.params,
// only keep params that exist in the resolved location
// only keep optional params coming from a parent record
matcher.keys.filter((k) => !k.optional).concat(matcher.parent ? matcher.parent.keys.filter((k) => k.optional) : []).map((k) => k.name)
),
// discard any existing params in the current location that do not exist here
// #1497 this ensures better active/exact matching
location2.params && paramsFromLocation(location2.params, matcher.keys.map((k) => k.name))
);
path = matcher.stringify(params);
} else if (location2.path != null) {
path = location2.path;
if (!path.startsWith("/")) {
warn(`The Matcher cannot resolve relative paths but received "${path}". Unless you directly called \`matcher.resolve("${path}")\`, this is probably a bug in vue-router. Please open an issue at https://github.com/vuejs/router/issues/new/choose.`);
}
matcher = matchers.find((m) => m.re.test(path));
if (matcher) {
params = matcher.parse(path);
name = matcher.record.name;
}
} else {
matcher = currentLocation.name ? matcherMap.get(currentLocation.name) : matchers.find((m) => m.re.test(currentLocation.path));
if (!matcher)
throw createRouterError(1, {
location: location2,
currentLocation
});
name = matcher.record.name;
params = assign({}, currentLocation.params, location2.params);
path = matcher.stringify(params);
}
const matched = [];
let parentMatcher = matcher;
while (parentMatcher) {
matched.unshift(parentMatcher.record);
parentMatcher = parentMatcher.parent;
}
return {
name,
path,
params,
matched,
meta: mergeMetaFields(matched)
};
}
routes.forEach((route) => addRoute(route));
function clearRoutes() {
matchers.length = 0;
matcherMap.clear();
}
return {
addRoute,
resolve,
removeRoute,
clearRoutes,
getRoutes,
getRecordMatcher
};
}
function paramsFromLocation(params, keys) {
const newParams = {};
for (const key of keys) {
if (key in params)
newParams[key] = params[key];
}
return newParams;
}
function normalizeRouteRecord(record) {
const normalized = {
path: record.path,
redirect: record.redirect,
name: record.name,
meta: record.meta || {},
aliasOf: record.aliasOf,
beforeEnter: record.beforeEnter,
props: normalizeRecordProps(record),
children: record.children || [],
instances: {},
leaveGuards: /* @__PURE__ */ new Set(),
updateGuards: /* @__PURE__ */ new Set(),
enterCallbacks: {},
// must be declared afterwards
// mods: {},
components: "components" in record ? record.components || null : record.component && { default: record.component }
};
Object.defineProperty(normalized, "mods", {
value: {}
});
return normalized;
}
function normalizeRecordProps(record) {
const propsObject = {};
const props = record.props || false;
if ("component" in record) {
propsObject.default = props;
} else {
for (const name in record.components)
propsObject[name] = typeof props === "object" ? props[name] : props;
}
return propsObject;
}
function isAliasRecord(record) {
while (record) {
if (record.record.aliasOf)
return true;
record = record.parent;
}
return false;
}
function mergeMetaFields(matched) {
return matched.reduce((meta, record) => assign(meta, record.meta), {});
}
function mergeOptions(defaults, partialOptions) {
const options = {};
for (const key in defaults) {
options[key] = key in partialOptions ? partialOptions[key] : defaults[key];
}
return options;
}
function isSameParam(a, b) {
return a.name === b.name && a.optional === b.optional && a.repeatable === b.repeatable;
}
function checkSameParams(a, b) {
for (const key of a.keys) {
if (!key.optional && !b.keys.find(isSameParam.bind(null, key)))
return warn(`Alias "${b.record.path}" and the original record: "${a.record.path}" must have the exact same param named "${key.name}"`);
}
for (const key of b.keys) {
if (!key.optional && !a.keys.find(isSameParam.bind(null, key)))
return warn(`Alias "${b.record.path}" and the original record: "${a.record.path}" must have the exact same param named "${key.name}"`);
}
}
function checkChildMissingNameWithEmptyPath(mainNormalizedRecord, parent) {
if (parent && parent.record.name && !mainNormalizedRecord.name && !mainNormalizedRecord.path) {
warn(`The route named "${String(parent.record.name)}" has a child without a name and an empty path. Using that name won't render the empty path child so you probably want to move the name to the child instead. If this is intentional, add a name to the child route to remove the warning.`);
}
}
function checkSameNameAsAncestor(record, parent) {
for (let ancestor = parent; ancestor; ancestor = ancestor.parent) {
if (ancestor.record.name === record.name) {
throw new Error(`A route named "${String(record.name)}" has been added as a ${parent === ancestor ? "child" : "descendant"} of a route with the same name. Route names must be unique and a nested route cannot use the same name as an ancestor.`);
}
}
}
function checkMissingParamsInAbsolutePath(record, parent) {
for (const key of parent.keys) {
if (!record.keys.find(isSameParam.bind(null, key)))
return warn(`Absolute path "${record.record.path}" must have the exact same param named "${key.name}" as its parent "${parent.record.path}".`);
}
}
function findInsertionIndex(matcher, matchers) {
let lower = 0;
let upper = matchers.length;
while (lower !== upper) {
const mid = lower + upper >> 1;
const sortOrder = comparePathParserScore(matcher, matchers[mid]);
if (sortOrder < 0) {
upper = mid;
} else {
lower = mid + 1;
}
}
const insertionAncestor = getInsertionAncestor(matcher);
if (insertionAncestor) {
upper = matchers.lastIndexOf(insertionAncestor, upper - 1);
if (upper < 0) {
warn(`Finding ancestor route "${insertionAncestor.record.path}" failed for "${matcher.record.path}"`);
}
}
return upper;
}
function getInsertionAncestor(matcher) {
let ancestor = matcher;
while (ancestor = ancestor.parent) {
if (isMatchable(ancestor) && comparePathParserScore(matcher, ancestor) === 0) {
return ancestor;
}
}
return;
}
function isMatchable({ record }) {
return !!(record.name || record.components && Object.keys(record.components).length || record.redirect);
}
function parseQuery(search) {
const query = {};
if (search === "" || search === "?")
return query;
const hasLeadingIM = search[0] === "?";
const searchParams = (hasLeadingIM ? search.slice(1) : search).split("&");
for (let i = 0; i < searchParams.length; ++i) {
const searchParam = searchParams[i].replace(PLUS_RE, " ");
const eqPos = searchParam.indexOf("=");
const key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos));
const value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1));
if (key in query) {
let currentValue = query[key];
if (!isArray(currentValue)) {
currentValue = query[key] = [currentValue];
}
currentValue.push(value);
} else {
query[key] = value;
}
}
return query;
}
function stringifyQuery(query) {
let search = "";
for (let key in query) {
const value = query[key];
key = encodeQueryKey(key);
if (value == null) {
if (value !== void 0) {
search += (search.length ? "&" : "") + key;
}
continue;
}
const values = isArray(value) ? value.map((v) => v && encodeQueryValue(v)) : [value && encodeQueryValue(value)];
values.forEach((value2) => {
if (value2 !== void 0) {
search += (search.length ? "&" : "") + key;
if (value2 != null)
search += "=" + value2;
}
});
}
return search;
}
function normalizeQuery(query) {
const normalizedQuery = {};
for (const key in query) {
const value = query[key];
if (value !== void 0) {
normalizedQuery[key] = isArray(value) ? value.map((v) => v == null ? null : "" + v) : value == null ? value : "" + value;
}
}
return normalizedQuery;
}
const matchedRouteKey = Symbol(true ? "router view location matched" : "");
const viewDepthKey = Symbol(true ? "router view depth" : "");
const routerKey = Symbol(true ? "router" : "");
const routeLocationKey = Symbol(true ? "route location" : "");
const routerViewLocationKey = Symbol(true ? "router view location" : "");
function useCallbacks() {
let handlers = [];
function add(handler) {
handlers.push(handler);
return () => {
const i = handlers.indexOf(handler);
if (i > -1)
handlers.splice(i, 1);
};
}
function reset() {
handlers = [];
}
return {
add,
list: () => handlers.slice(),
reset
};
}
function registerGuard(record, name, guard) {
const removeFromList = () => {
record[name].delete(guard);
};
onUnmounted(removeFromList);
onDeactivated(removeFromList);
onActivated(() => {
record[name].add(guard);
});
record[name].add(guard);
}
function onBeforeRouteLeave(leaveGuard) {
if (!getCurrentInstance()) {
warn("getCurrentInstance() returned null. onBeforeRouteLeave() must be called at the top of a setup function");
return;
}
const activeRecord = inject(
matchedRouteKey,
// to avoid warning
{}
).value;
if (!activeRecord) {
warn("No active route record was found when calling `onBeforeRouteLeave()`. Make sure you call this function inside a component child of <router-view>. Maybe you called it inside of App.vue?");
return;
}
registerGuard(activeRecord, "leaveGuards", leaveGuard);
}
function onBeforeRouteUpdate(updateGuard) {
if (!getCurrentInstance()) {
warn("getCurrentInstance() returned null. onBeforeRouteUpdate() must be called at the top of a setup function");
return;
}
const activeRecord = inject(
matchedRouteKey,
// to avoid warning
{}
).value;
if (!activeRecord) {
warn("No active route record was found when calling `onBeforeRouteUpdate()`. Make sure you call this function inside a component child of <router-view>. Maybe you called it inside of App.vue?");
return;
}
registerGuard(activeRecord, "updateGuards", updateGuard);
}
function guardToPromiseFn(guard, to, from, record, name, runWithContext = (fn) => fn()) {
const enterCallbackArray = record && // name is defined if record is because of the function overload
(record.enterCallbacks[name] = record.enterCallbacks[name] || []);
return () => new Promise((resolve, reject) => {
const next = (valid) => {
if (valid === false) {
reject(createRouterError(4, {
from,
to
}));
} else if (valid instanceof Error) {
reject(valid);
} else if (isRouteLocation(valid)) {
reject(createRouterError(2, {
from: to,
to: valid
}));
} else {
if (enterCallbackArray && // since enterCallbackArray is truthy, both record and name also are
record.enterCallbacks[name] === enterCallbackArray && typeof valid === "function") {
enterCallbackArray.push(valid);
}
resolve();
}
};
const guardReturn = runWithContext(() => guard.call(record && record.instances[name], to, from, true ? canOnlyBeCalledOnce(next, to, from) : next));
let guardCall = Promise.resolve(guardReturn);
if (guard.length < 3)
guardCall = guardCall.then(next);
if (guard.length > 2) {
const message = `The "next" callback was never called inside of ${guard.name ? '"' + guard.name + '"' : ""}:
${guard.toString()}
. If you are returning a value instead of calling "next", make sure to remove the "next" parameter from your function.`;
if (typeof guardReturn === "object" && "then" in guardReturn) {
guardCall = guardCall.then((resolvedValue) => {
if (!next._called) {
warn(message);
return Promise.reject(new Error("Invalid navigation guard"));
}
return resolvedValue;
});
} else if (guardReturn !== void 0) {
if (!next._called) {
warn(message);
reject(new Error("Invalid navigation guard"));
return;
}
}
}
guardCall.catch((err) => reject(err));
});
}
function canOnlyBeCalledOnce(next, to, from) {
let called = 0;
return function() {
if (called++ === 1)
warn(`The "next" callback was called more than once in one navigation guard when going from "${from.fullPath}" to "${to.fullPath}". It should be called exactly one time in each navigation guard. This will fail in production.`);
next._called = true;
if (called === 1)
next.apply(null, arguments);
};
}
function extractComponentsGuards(matched, guardType, to, from, runWithContext = (fn) => fn()) {
const guards = [];
for (const record of matched) {
if (!record.components && !record.children.length) {
warn(`Record with path "${record.path}" is either missing a "component(s)" or "children" property.`);
}
for (const name in record.components) {
let rawComponent = record.components[name];
if (true) {
if (!rawComponent || typeof rawComponent !== "object" && typeof rawComponent !== "function") {
warn(`Component "${name}" in record with path "${record.path}" is not a valid component. Received "${String(rawComponent)}".`);
throw new Error("Invalid route component");
} else if ("then" in rawComponent) {
warn(`Component "${name}" in record with path "${record.path}" is a Promise instead of a function that returns a Promise. Did you write "import('./MyPage.vue')" instead of "() => import('./MyPage.vue')" ? This will break in production if not fixed.`);
const promise = rawComponent;
rawComponent = () => promise;
} else if (rawComponent.__asyncLoader && // warn only once per component
!rawComponent.__warnedDefineAsync) {
rawComponent.__warnedDefineAsync = true;
warn(`Component "${name}" in record with path "${record.path}" is defined using "defineAsyncComponent()". Write "() => import('./MyPage.vue')" instead of "defineAsyncComponent(() => import('./MyPage.vue'))".`);
}
}
if (guardType !== "beforeRouteEnter" && !record.instances[name])
continue;
if (isRouteComponent(rawComponent)) {
const options = rawComponent.__vccOpts || rawComponent;
const guard = options[guardType];
guard && guards.push(guardToPromiseFn(guard, to, from, record, name, runWithContext));
} else {
let componentPromise = rawComponent();
if (!("catch" in componentPromise)) {
warn(`Component "${name}" in record with path "${record.path}" is a function that does not return a Promise. If you were passing a functional component, make sure to add a "displayName" to the component. This will break in production if not fixed.`);
componentPromise = Promise.resolve(componentPromise);
}
guards.push(() => componentPromise.then((resolved) => {
if (!resolved)
throw new Error(`Couldn't resolve component "${name}" at "${record.path}"`);
const resolvedComponent = isESModule(resolved) ? resolved.default : resolved;
record.mods[name] = resolved;
record.components[name] = resolvedComponent;
const options = resolvedComponent.__vccOpts || resolvedComponent;
const guard = options[guardType];
return guard && guardToPromiseFn(guard, to, from, record, name, runWithContext)();
}));
}
}
}
return guards;
}
function loadRouteLocation(route) {
return route.matched.every((record) => record.redirect) ? Promise.reject(new Error("Cannot load a route that redirects.")) : Promise.all(route.matched.map((record) => record.components && Promise.all(Object.keys(record.components).reduce((promises, name) => {
const rawComponent = record.components[name];
if (typeof rawComponent === "function" && !("displayName" in rawComponent)) {
promises.push(rawComponent().then((resolved) => {
if (!resolved)
return Promise.reject(new Error(`Couldn't resolve component "${name}" at "${record.path}". Ensure you passed a function that returns a promise.`));
const resolvedComponent = isESModule(resolved) ? resolved.default : resolved;
record.mods[name] = resolved;
record.components[name] = resolvedComponent;
return;
}));
}
return promises;
}, [])))).then(() => route);
}
function useLink(props) {
const router = inject(routerKey);
const currentRoute = inject(routeLocationKey);
let hasPrevious = false;
let previousTo = null;
const route = computed(() => {
const to = unref(props.to);
if (!hasPrevious || to !== previousTo) {
if (!isRouteLocation(to)) {
if (hasPrevious) {
warn(`Invalid value for prop "to" in useLink()
- to:`, to, `
- previous to:`, previousTo, `
- props:`, props);
} else {
warn(`Invalid value for prop "to" in useLink()
- to:`, to, `
- props:`, props);
}
}
previousTo = to;
hasPrevious = true;
}
return router.resolve(to);
});
const activeRecordIndex = computed(() => {
const { matched } = route.value;
const { length } = matched;
const routeMatched = matched[length - 1];
const currentMatched = currentRoute.matched;
if (!routeMatched || !currentMatched.length)
return -1;
const index = currentMatched.findIndex(isSameRouteRecord.bind(null, routeMatched));
if (index > -1)
return index;
const parentRecordPath = getOriginalPath(matched[length - 2]);
return (
// we are dealing with nested routes
length > 1 && // if the parent and matched route have the same path, this link is
// referring to the empty child. Or we currently are on a different
// child of the same parent
getOriginalPath(routeMatched) === parentRecordPath && // avoid comparing the child with its parent
currentMatched[currentMatched.length - 1].path !== parentRecordPath ? currentMatched.findIndex(isSameRouteRecord.bind(null, matched[length - 2])) : index
);
});
const isActive = computed(() => activeRecordIndex.value > -1 && includesParams(currentRoute.params, route.value.params));
const isExactActive = computed(() => activeRecordIndex.value > -1 && activeRecordIndex.value === currentRoute.matched.length - 1 && isSameRouteLocationParams(currentRoute.params, route.value.params));
function navigate(e = {}) {
if (guardEvent(e)) {
const p = router[unref(props.replace) ? "replace" : "push"](
unref(props.to)
// avoid uncaught errors are they are logged anyway
).catch(noop);
if (props.viewTransition && typeof document !== "undefined" && "startViewTransition" in document) {
document.startViewTransition(() => p);
}
return p;
}
return Promise.resolve();
}
if (isBrowser) {
const instance = getCurrentInstance();
if (instance) {
const linkContextDevtools = {
route: route.value,
isActive: isActive.value,
isExactActive: isExactActive.value,
error: null
};
instance.__vrl_devtools = instance.__vrl_devtools || [];
instance.__vrl_devtools.push(linkContextDevtools);
watchEffect(() => {
linkContextDevtools.route = route.value;
linkContextDevtools.isActive = isActive.value;
linkContextDevtools.isExactActive = isExactActive.value;
linkContextDevtools.error = isRouteLocation(unref(props.to)) ? null : 'Invalid "to" value';
}, { flush: "post" });
}
}
return {
route,
href: computed(() => route.value.href),
isActive,
isExactActive,
navigate
};
}
function preferSingleVNode(vnodes) {
return vnodes.length === 1 ? vnodes[0] : vnodes;
}
const RouterLinkImpl = /* @__PURE__ */ defineComponent({
name: "RouterLink",
compatConfig: { MODE: 3 },
props: {
to: {
type: [String, Object],
required: true
},
replace: Boolean,
activeClass: String,
// inactiveClass: String,
exactActiveClass: String,
custom: Boolean,
ariaCurrentValue: {
type: String,
default: "page"
},
viewTransition: Boolean
},
useLink,
setup(props, { slots }) {
const link = reactive(useLink(props));
const { options } = inject(routerKey);
const elClass = computed(() => ({
[getLinkClass(props.activeClass, options.linkActiveClass, "router-link-active")]: link.isActive,
// [getLinkClass(
// props.inactiveClass,
// options.linkInactiveClass,
// 'router-link-inactive'
// )]: !link.isExactActive,
[getLinkClass(props.exactActiveClass, options.linkExactActiveClass, "router-link-exact-active")]: link.isExactActive
}));
return () => {
const children = slots.default && preferSingleVNode(slots.default(link));
return props.custom ? children : h("a", {
"aria-current": link.isExactActive ? props.ariaCurrentValue : null,
href: link.href,
// this would override user added attrs but Vue will still add
// the listener, so we end up triggering both
onClick: link.navigate,
class: elClass.value
}, children);
};
}
});
const RouterLink = RouterLinkImpl;
function guardEvent(e) {
if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)
return;
if (e.defaultPrevented)
return;
if (e.button !== void 0 && e.button !== 0)
return;
if (e.currentTarget && e.currentTarget.getAttribute) {
const target = e.currentTarget.getAttribute("target");
if (/\b_blank\b/i.test(target))
return;
}
if (e.preventDefault)
e.preventDefault();
return true;
}
function includesParams(outer, inner) {
for (const key in inner) {
const innerValue = inner[key];
const outerValue = outer[key];
if (typeof innerValue === "string") {
if (innerValue !== outerValue)
return false;
} else {
if (!isArray(outerValue) || outerValue.length !== innerValue.length || innerValue.some((value, i) => value !== outerValue[i]))
return false;
}
}
return true;
}
function getOriginalPath(record) {
return record ? record.aliasOf ? record.aliasOf.path : record.path : "";
}
const getLinkClass = (propClass, globalClass, defaultClass) => propClass != null ? propClass : globalClass != null ? globalClass : defaultClass;
const RouterViewImpl = /* @__PURE__ */ defineComponent({
name: "RouterView",
// #674 we manually inherit them
inheritAttrs: false,
props: {
name: {
type: String,
default: "default"
},
route: Object
},
// Better compat for @vue/compat users
// https://github.com/vuejs/router/issues/1315
compatConfig: { MODE: 3 },
setup(props, { attrs, slots }) {
warnDeprecatedUsage();
const injectedRoute = inject(routerViewLocationKey);
const routeToDisplay = computed(() => props.route || injectedRoute.value);
const injectedDepth = inject(viewDepthKey, 0);
const depth = computed(() => {
let initialDepth = unref(injectedDepth);
const { matched } = routeToDisplay.value;
let matchedRoute;
while ((matchedRoute = matched[initialDepth]) && !matchedRoute.components) {
initialDepth++;
}
return initialDepth;
});
const matchedRouteRef = computed(() => routeToDisplay.value.matched[depth.value]);
provide(viewDepthKey, computed(() => depth.value + 1));
provide(matchedRouteKey, matchedRouteRef);
provide(routerViewLocationKey, routeToDisplay);
const viewRef = ref();
watch(() => [viewRef.value, matchedRouteRef.value, props.name], ([instance, to, name], [oldInstance, from, oldName]) => {
if (to) {
to.instances[name] = instance;
if (from && from !== to && instance && instance === oldInstance) {
if (!to.leaveGuards.size) {
to.leaveGuards = from.leaveGuards;
}
if (!to.updateGuards.size) {
to.updateGuards = from.updateGuards;
}
}
}
if (instance && to && // if there is no instance but to and from are the same this might be
// the first visit
(!from || !isSameRouteRecord(to, from) || !oldInstance)) {
(to.enterCallbacks[name] || []).forEach((callback) => callback(instance));
}
}, { flush: "post" });
return () => {
const route = routeToDisplay.value;
const currentName = props.name;
const matchedRoute = matchedRouteRef.value;
const ViewComponent = matchedRoute && matchedRoute.components[currentName];
if (!ViewComponent) {
return normalizeSlot(slots.default, { Component: ViewComponent, route });
}
const routePropsOption = matchedRoute.props[currentName];
const routeProps = routePropsOption ? routePropsOption === true ? route.params : typeof routePropsOption === "function" ? routePropsOption(route) : routePropsOption : null;
const onVnodeUnmounted = (vnode) => {
if (vnode.component.isUnmounted) {
matchedRoute.instances[currentName] = null;
}
};
const component = h(ViewComponent, assign({}, routeProps, attrs, {
onVnodeUnmounted,
ref: viewRef
}));
if (isBrowser && component.ref) {
const info = {
depth: depth.value,
name: matchedRoute.name,
path: matchedRoute.path,
meta: matchedRoute.meta
};
const internalInstances = isArray(component.ref) ? component.ref.map((r) => r.i) : [component.ref.i];
internalInstances.forEach((instance) => {
instance.__vrv_devtools = info;
});
}
return (
// pass the vnode to the slot as a prop.
// h and <component :is="..."> both accept vnodes
normalizeSlot(slots.default, { Component: component, route }) || component
);
};
}
});
function normalizeSlot(slot, data) {
if (!slot)
return null;
const slotContent = slot(data);
return slotContent.length === 1 ? slotContent[0] : slotContent;
}
const RouterView = RouterViewImpl;
function warnDeprecatedUsage() {
const instance = getCurrentInstance();
const parentName = instance.parent && instance.parent.type.name;
const parentSubTreeType = instance.parent && instance.parent.subTree && instance.parent.subTree.type;
if (parentName && (parentName === "KeepAlive" || parentName.includes("Transition")) && typeof parentSubTreeType === "object" && parentSubTreeType.name === "RouterView") {
const comp = parentName === "KeepAlive" ? "keep-alive" : "transition";
warn(`<router-view> can no longer be used directly inside <transition> or <keep-alive>.
Use slot props instead:
<router-view v-slot="{ Component }">
<${comp}>
<component :is="Component" />
</${comp}>
</router-view>`);
}
}
function formatRouteLocation(routeLocation, tooltip) {
const copy = assign({}, routeLocation, {
// remove variables that can contain vue instances
matched: routeLocation.matched.map((matched) => omit(matched, ["instances", "children", "aliasOf"]))
});
return {
_custom: {
type: null,
readOnly: true,
display: routeLocation.fullPath,
tooltip,
value: copy
}
};
}
function formatDisplay(display) {
return {
_custom: {
display
}
};
}
let routerId = 0;
function addDevtools(app, router, matcher) {
if (router.__hasDevtools)
return;
router.__hasDevtools = true;
const id = routerId++;
setupDevtoolsPlugin({
id: "org.vuejs.router" + (id ? "." + id : ""),
label: "Vue Router",
packageName: "vue-router",
homepage: "https://router.vuejs.org",
logo: "https://router.vuejs.org/logo.png",
componentStateTypes: ["Routing"],
app
}, (api) => {
if (typeof api.now !== "function") {
console.warn("[Vue Router]: You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.");
}
api.on.inspectComponent((payload, ctx) => {
if (payload.instanceData) {
payload.instanceData.state.push({
type: "Routing",
key: "$route",
editable: false,
value: formatRouteLocation(router.currentRoute.value, "Current Route")
});
}
});
api.on.visitComponentTree(({ treeNode: node, componentInstance }) => {
if (componentInstance.__vrv_devtools) {
const info = componentInstance.__vrv_devtools;
node.tags.push({
label: (info.name ? `${info.name.toString()}: ` : "") + info.path,
textColor: 0,
tooltip: "This component is rendered by &lt;router-view&gt;",
backgroundColor: PINK_500
});
}
if (isArray(componentInstance.__vrl_devtools)) {
componentInstance.__devtoolsApi = api;
componentInstance.__vrl_devtools.forEach((devtoolsData) => {
let label = devtoolsData.route.path;
let backgroundColor = ORANGE_400;
let tooltip = "";
let textColor = 0;
if (devtoolsData.error) {
label = devtoolsData.error;
backgroundColor = RED_100;
textColor = RED_700;
} else if (devtoolsData.isExactActive) {
backgroundColor = LIME_500;
tooltip = "This is exactly active";
} else if (devtoolsData.isActive) {
backgroundColor = BLUE_600;
tooltip = "This link is active";
}
node.tags.push({
label,
textColor,
tooltip,
backgroundColor
});
});
}
});
watch(router.currentRoute, () => {
refreshRoutesView();
api.notifyComponentUpdate();
api.sendInspectorTree(routerInspectorId);
api.sendInspectorState(routerInspectorId);
});
const navigationsLayerId = "router:navigations:" + id;
api.addTimelineLayer({
id: navigationsLayerId,
label: `Router${id ? " " + id : ""} Navigations`,
color: 4237508
});
router.onError((error, to) => {
api.addTimelineEvent({
layerId: navigationsLayerId,
event: {
title: "Error during Navigation",
subtitle: to.fullPath,
logType: "error",
time: api.now(),
data: { error },
groupId: to.meta.__navigationId
}
});
});
let navigationId = 0;
router.beforeEach((to, from) => {
const data = {
guard: formatDisplay("beforeEach"),
from: formatRouteLocation(from, "Current Location during this navigation"),
to: formatRouteLocation(to, "Target location")
};
Object.defineProperty(to.meta, "__navigationId", {
value: navigationId++
});
api.addTimelineEvent({
layerId: navigationsLayerId,
event: {
time: api.now(),
title: "Start of navigation",
subtitle: to.fullPath,
data,
groupId: to.meta.__navigationId
}
});
});
router.afterEach((to, from, failure) => {
const data = {
guard: formatDisplay("afterEach")
};
if (failure) {
data.failure = {
_custom: {
type: Error,
readOnly: true,
display: failure ? failure.message : "",
tooltip: "Navigation Failure",
value: failure
}
};
data.status = formatDisplay("❌");
} else {
data.status = formatDisplay("✅");
}
data.from = formatRouteLocation(from, "Current Location during this navigation");
data.to = formatRouteLocation(to, "Target location");
api.addTimelineEvent({
layerId: navigationsLayerId,
event: {
title: "End of navigation",
subtitle: to.fullPath,
time: api.now(),
data,
logType: failure ? "warning" : "default",
groupId: to.meta.__navigationId
}
});
});
const routerInspectorId = "router-inspector:" + id;
api.addInspector({
id: routerInspectorId,
label: "Routes" + (id ? " " + id : ""),
icon: "book",
treeFilterPlaceholder: "Search routes"
});
function refreshRoutesView() {
if (!activeRoutesPayload)
return;
const payload = activeRoutesPayload;
let routes = matcher.getRoutes().filter((route) => !route.parent || // these routes have a parent with no component which will not appear in the view
// therefore we still need to include them
!route.parent.record.components);
routes.forEach(resetMatchStateOnRouteRecord);
if (payload.filter) {
routes = routes.filter((route) => (
// save matches state based on the payload
isRouteMatching(route, payload.filter.toLowerCase())
));
}
routes.forEach((route) => markRouteRecordActive(route, router.currentRoute.value));
payload.rootNodes = routes.map(formatRouteRecordForInspector);
}
let activeRoutesPayload;
api.on.getInspectorTree((payload) => {
activeRoutesPayload = payload;
if (payload.app === app && payload.inspectorId === routerInspectorId) {
refreshRoutesView();
}
});
api.on.getInspectorState((payload) => {
if (payload.app === app && payload.inspectorId === routerInspectorId) {
const routes = matcher.getRoutes();
const route = routes.find((route2) => route2.record.__vd_id === payload.nodeId);
if (route) {
payload.state = {
options: formatRouteRecordMatcherForStateInspector(route)
};
}
}
});
api.sendInspectorTree(routerInspectorId);
api.sendInspectorState(routerInspectorId);
});
}
function modifierForKey(key) {
if (key.optional) {
return key.repeatable ? "*" : "?";
} else {
return key.repeatable ? "+" : "";
}
}
function formatRouteRecordMatcherForStateInspector(route) {
const { record } = route;
const fields = [
{ editable: false, key: "path", value: record.path }
];
if (record.name != null) {
fields.push({
editable: false,
key: "name",
value: record.name
});
}
fields.push({ editable: false, key: "regexp", value: route.re });
if (route.keys.length) {
fields.push({
editable: false,
key: "keys",
value: {
_custom: {
type: null,
readOnly: true,
display: route.keys.map((key) => `${key.name}${modifierForKey(key)}`).join(" "),
tooltip: "Param keys",
value: route.keys
}
}
});
}
if (record.redirect != null) {
fields.push({
editable: false,
key: "redirect",
value: record.redirect
});
}
if (route.alias.length) {
fields.push({
editable: false,
key: "aliases",
value: route.alias.map((alias) => alias.record.path)
});
}
if (Object.keys(route.record.meta).length) {
fields.push({
editable: false,
key: "meta",
value: route.record.meta
});
}
fields.push({
key: "score",
editable: false,
value: {
_custom: {
type: null,
readOnly: true,
display: route.score.map((score) => score.join(", ")).join(" | "),
tooltip: "Score used to sort routes",
value: route.score
}
}
});
return fields;
}
const PINK_500 = 15485081;
const BLUE_600 = 2450411;
const LIME_500 = 8702998;
const CYAN_400 = 2282478;
const ORANGE_400 = 16486972;
const DARK = 6710886;
const RED_100 = 16704226;
const RED_700 = 12131356;
function formatRouteRecordForInspector(route) {
const tags = [];
const { record } = route;
if (record.name != null) {
tags.push({
label: String(record.name),
textColor: 0,
backgroundColor: CYAN_400
});
}
if (record.aliasOf) {
tags.push({
label: "alias",
textColor: 0,
backgroundColor: ORANGE_400
});
}
if (route.__vd_match) {
tags.push({
label: "matches",
textColor: 0,
backgroundColor: PINK_500
});
}
if (route.__vd_exactActive) {
tags.push({
label: "exact",
textColor: 0,
backgroundColor: LIME_500
});
}
if (route.__vd_active) {
tags.push({
label: "active",
textColor: 0,
backgroundColor: BLUE_600
});
}
if (record.redirect) {
tags.push({
label: typeof record.redirect === "string" ? `redirect: ${record.redirect}` : "redirects",
textColor: 16777215,
backgroundColor: DARK
});
}
let id = record.__vd_id;
if (id == null) {
id = String(routeRecordId++);
record.__vd_id = id;
}
return {
id,
label: record.path,
tags,
children: route.children.map(formatRouteRecordForInspector)
};
}
let routeRecordId = 0;
const EXTRACT_REGEXP_RE = /^\/(.*)\/([a-z]*)$/;
function markRouteRecordActive(route, currentRoute) {
const isExactActive = currentRoute.matched.length && isSameRouteRecord(currentRoute.matched[currentRoute.matched.length - 1], route.record);
route.__vd_exactActive = route.__vd_active = isExactActive;
if (!isExactActive) {
route.__vd_active = currentRoute.matched.some((match) => isSameRouteRecord(match, route.record));
}
route.children.forEach((childRoute) => markRouteRecordActive(childRoute, currentRoute));
}
function resetMatchStateOnRouteRecord(route) {
route.__vd_match = false;
route.children.forEach(resetMatchStateOnRouteRecord);
}
function isRouteMatching(route, filter) {
const found = String(route.re).match(EXTRACT_REGEXP_RE);
route.__vd_match = false;
if (!found || found.length < 3) {
return false;
}
const nonEndingRE = new RegExp(found[1].replace(/\$$/, ""), found[2]);
if (nonEndingRE.test(filter)) {
route.children.forEach((child) => isRouteMatching(child, filter));
if (route.record.path !== "/" || filter === "/") {
route.__vd_match = route.re.test(filter);
return true;
}
return false;
}
const path = route.record.path.toLowerCase();
const decodedPath = decode(path);
if (!filter.startsWith("/") && (decodedPath.includes(filter) || path.includes(filter)))
return true;
if (decodedPath.startsWith(filter) || path.startsWith(filter))
return true;
if (route.record.name && String(route.record.name).includes(filter))
return true;
return route.children.some((child) => isRouteMatching(child, filter));
}
function omit(obj, keys) {
const ret = {};
for (const key in obj) {
if (!keys.includes(key)) {
ret[key] = obj[key];
}
}
return ret;
}
function createRouter(options) {
const matcher = createRouterMatcher(options.routes, options);
const parseQuery$1 = options.parseQuery || parseQuery;
const stringifyQuery$1 = options.stringifyQuery || stringifyQuery;
const routerHistory = options.history;
if (!routerHistory)
throw new Error('Provide the "history" option when calling "createRouter()": https://router.vuejs.org/api/interfaces/RouterOptions.html#history');
const beforeGuards = useCallbacks();
const beforeResolveGuards = useCallbacks();
const afterGuards = useCallbacks();
const currentRoute = shallowRef(START_LOCATION_NORMALIZED);
let pendingLocation = START_LOCATION_NORMALIZED;
if (isBrowser && options.scrollBehavior && "scrollRestoration" in history) {
history.scrollRestoration = "manual";
}
const normalizeParams = applyToParams.bind(null, (paramValue) => "" + paramValue);
const encodeParams = applyToParams.bind(null, encodeParam);
const decodeParams = (
// @ts-expect-error: intentionally avoid the type check
applyToParams.bind(null, decode)
);
function addRoute(parentOrRoute, route) {
let parent;
let record;
if (isRouteName(parentOrRoute)) {
parent = matcher.getRecordMatcher(parentOrRoute);
if (!parent) {
warn(`Parent route "${String(parentOrRoute)}" not found when adding child route`, route);
}
record = route;
} else {
record = parentOrRoute;
}
return matcher.addRoute(record, parent);
}
function removeRoute(name) {
const recordMatcher = matcher.getRecordMatcher(name);
if (recordMatcher) {
matcher.removeRoute(recordMatcher);
} else if (true) {
warn(`Cannot remove non-existent route "${String(name)}"`);
}
}
function getRoutes() {
return matcher.getRoutes().map((routeMatcher) => routeMatcher.record);
}
function hasRoute(name) {
return !!matcher.getRecordMatcher(name);
}
function resolve(rawLocation, currentLocation) {
currentLocation = assign({}, currentLocation || currentRoute.value);
if (typeof rawLocation === "string") {
const locationNormalized = parseURL(parseQuery$1, rawLocation, currentLocation.path);
const matchedRoute2 = matcher.resolve({ path: locationNormalized.path }, currentLocation);
const href2 = routerHistory.createHref(locationNormalized.fullPath);
if (true) {
if (href2.startsWith("//"))
warn(`Location "${rawLocation}" resolved to "${href2}". A resolved location cannot start with multiple slashes.`);
else if (!matchedRoute2.matched.length) {
warn(`No match found for location with path "${rawLocation}"`);
}
}
return assign(locationNormalized, matchedRoute2, {
params: decodeParams(matchedRoute2.params),
hash: decode(locationNormalized.hash),
redirectedFrom: void 0,
href: href2
});
}
if (!isRouteLocation(rawLocation)) {
warn(`router.resolve() was passed an invalid location. This will fail in production.
- Location:`, rawLocation);
return resolve({});
}
let matcherLocation;
if (rawLocation.path != null) {
if ("params" in rawLocation && !("name" in rawLocation) && // @ts-expect-error: the type is never
Object.keys(rawLocation.params).length) {
warn(`Path "${rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
}
matcherLocation = assign({}, rawLocation, {
path: parseURL(parseQuery$1, rawLocation.path, currentLocation.path).path
});
} else {
const targetParams = assign({}, rawLocation.params);
for (const key in targetParams) {
if (targetParams[key] == null) {
delete targetParams[key];
}
}
matcherLocation = assign({}, rawLocation, {
params: encodeParams(targetParams)
});
currentLocation.params = encodeParams(currentLocation.params);
}
const matchedRoute = matcher.resolve(matcherLocation, currentLocation);
const hash = rawLocation.hash || "";
if (hash && !hash.startsWith("#")) {
warn(`A \`hash\` should always start with the character "#". Replace "${hash}" with "#${hash}".`);
}
matchedRoute.params = normalizeParams(decodeParams(matchedRoute.params));
const fullPath = stringifyURL(stringifyQuery$1, assign({}, rawLocation, {
hash: encodeHash(hash),
path: matchedRoute.path
}));
const href = routerHistory.createHref(fullPath);
if (true) {
if (href.startsWith("//")) {
warn(`Location "${rawLocation}" resolved to "${href}". A resolved location cannot start with multiple slashes.`);
} else if (!matchedRoute.matched.length) {
warn(`No match found for location with path "${rawLocation.path != null ? rawLocation.path : rawLocation}"`);
}
}
return assign({
fullPath,
// keep the hash encoded so fullPath is effectively path + encodedQuery +
// hash
hash,
query: (
// if the user is using a custom query lib like qs, we might have
// nested objects, so we keep the query as is, meaning it can contain
// numbers at `$route.query`, but at the point, the user will have to
// use their own type anyway.
// https://github.com/vuejs/router/issues/328#issuecomment-649481567
stringifyQuery$1 === stringifyQuery ? normalizeQuery(rawLocation.query) : rawLocation.query || {}
)
}, matchedRoute, {
redirectedFrom: void 0,
href
});
}
function locationAsObject(to) {
return typeof to === "string" ? parseURL(parseQuery$1, to, currentRoute.value.path) : assign({}, to);
}
function checkCanceledNavigation(to, from) {
if (pendingLocation !== to) {
return createRouterError(8, {
from,
to
});
}
}
function push(to) {
return pushWithRedirect(to);
}
function replace(to) {
return push(assign(locationAsObject(to), { replace: true }));
}
function handleRedirectRecord(to) {
const lastMatched = to.matched[to.matched.length - 1];
if (lastMatched && lastMatched.redirect) {
const { redirect } = lastMatched;
let newTargetLocation = typeof redirect === "function" ? redirect(to) : redirect;
if (typeof newTargetLocation === "string") {
newTargetLocation = newTargetLocation.includes("?") || newTargetLocation.includes("#") ? newTargetLocation = locationAsObject(newTargetLocation) : (
// force empty params
{ path: newTargetLocation }
);
newTargetLocation.params = {};
}
if (newTargetLocation.path == null && !("name" in newTargetLocation)) {
warn(`Invalid redirect found:
${JSON.stringify(newTargetLocation, null, 2)}
when navigating to "${to.fullPath}". A redirect must contain a name or path. This will break in production.`);
throw new Error("Invalid redirect");
}
return assign({
query: to.query,
hash: to.hash,
// avoid transferring params if the redirect has a path
params: newTargetLocation.path != null ? {} : to.params
}, newTargetLocation);
}
}
function pushWithRedirect(to, redirectedFrom) {
const targetLocation = pendingLocation = resolve(to);
const from = currentRoute.value;
const data = to.state;
const force = to.force;
const replace2 = to.replace === true;
const shouldRedirect = handleRedirectRecord(targetLocation);
if (shouldRedirect)
return pushWithRedirect(
assign(locationAsObject(shouldRedirect), {
state: typeof shouldRedirect === "object" ? assign({}, data, shouldRedirect.state) : data,
force,
replace: replace2
}),
// keep original redirectedFrom if it exists
redirectedFrom || targetLocation
);
const toLocation = targetLocation;
toLocation.redirectedFrom = redirectedFrom;
let failure;
if (!force && isSameRouteLocation(stringifyQuery$1, from, targetLocation)) {
failure = createRouterError(16, { to: toLocation, from });
handleScroll(
from,
from,
// this is a push, the only way for it to be triggered from a
// history.listen is with a redirect, which makes it become a push
true,
// This cannot be the first navigation because the initial location
// cannot be manually navigated to
false
);
}
return (failure ? Promise.resolve(failure) : navigate(toLocation, from)).catch((error) => isNavigationFailure(error) ? (
// navigation redirects still mark the router as ready
isNavigationFailure(
error,
2
/* ErrorTypes.NAVIGATION_GUARD_REDIRECT */
) ? error : markAsReady(error)
) : (
// reject any unknown error
triggerError(error, toLocation, from)
)).then((failure2) => {
if (failure2) {
if (isNavigationFailure(
failure2,
2
/* ErrorTypes.NAVIGATION_GUARD_REDIRECT */
)) {
if (// we are redirecting to the same location we were already at
isSameRouteLocation(stringifyQuery$1, resolve(failure2.to), toLocation) && // and we have done it a couple of times
redirectedFrom && // @ts-expect-error: added only in dev
(redirectedFrom._count = redirectedFrom._count ? (
// @ts-expect-error
redirectedFrom._count + 1
) : 1) > 30) {
warn(`Detected a possibly infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow.
Are you always returning a new location within a navigation guard? That would lead to this error. Only return when redirecting or aborting, that should fix this. This might break in production if not fixed.`);
return Promise.reject(new Error("Infinite redirect in navigation guard"));
}
return pushWithRedirect(
// keep options
assign({
// preserve an existing replacement but allow the redirect to override it
replace: replace2
}, locationAsObject(failure2.to), {
state: typeof failure2.to === "object" ? assign({}, data, failure2.to.state) : data,
force
}),
// preserve the original redirectedFrom if any
redirectedFrom || toLocation
);
}
} else {
failure2 = finalizeNavigation(toLocation, from, true, replace2, data);
}
triggerAfterEach(toLocation, from, failure2);
return failure2;
});
}
function checkCanceledNavigationAndReject(to, from) {
const error = checkCanceledNavigation(to, from);
return error ? Promise.reject(error) : Promise.resolve();
}
function runWithContext(fn) {
const app = installedApps.values().next().value;
return app && typeof app.runWithContext === "function" ? app.runWithContext(fn) : fn();
}
function navigate(to, from) {
let guards;
const [leavingRecords, updatingRecords, enteringRecords] = extractChangingRecords(to, from);
guards = extractComponentsGuards(leavingRecords.reverse(), "beforeRouteLeave", to, from);
for (const record of leavingRecords) {
record.leaveGuards.forEach((guard) => {
guards.push(guardToPromiseFn(guard, to, from));
});
}
const canceledNavigationCheck = checkCanceledNavigationAndReject.bind(null, to, from);
guards.push(canceledNavigationCheck);
return runGuardQueue(guards).then(() => {
guards = [];
for (const guard of beforeGuards.list()) {
guards.push(guardToPromiseFn(guard, to, from));
}
guards.push(canceledNavigationCheck);
return runGuardQueue(guards);
}).then(() => {
guards = extractComponentsGuards(updatingRecords, "beforeRouteUpdate", to, from);
for (const record of updatingRecords) {
record.updateGuards.forEach((guard) => {
guards.push(guardToPromiseFn(guard, to, from));
});
}
guards.push(canceledNavigationCheck);
return runGuardQueue(guards);
}).then(() => {
guards = [];
for (const record of enteringRecords) {
if (record.beforeEnter) {
if (isArray(record.beforeEnter)) {
for (const beforeEnter of record.beforeEnter)
guards.push(guardToPromiseFn(beforeEnter, to, from));
} else {
guards.push(guardToPromiseFn(record.beforeEnter, to, from));
}
}
}
guards.push(canceledNavigationCheck);
return runGuardQueue(guards);
}).then(() => {
to.matched.forEach((record) => record.enterCallbacks = {});
guards = extractComponentsGuards(enteringRecords, "beforeRouteEnter", to, from, runWithContext);
guards.push(canceledNavigationCheck);
return runGuardQueue(guards);
}).then(() => {
guards = [];
for (const guard of beforeResolveGuards.list()) {
guards.push(guardToPromiseFn(guard, to, from));
}
guards.push(canceledNavigationCheck);
return runGuardQueue(guards);
}).catch((err) => isNavigationFailure(
err,
8
/* ErrorTypes.NAVIGATION_CANCELLED */
) ? err : Promise.reject(err));
}
function triggerAfterEach(to, from, failure) {
afterGuards.list().forEach((guard) => runWithContext(() => guard(to, from, failure)));
}
function finalizeNavigation(toLocation, from, isPush, replace2, data) {
const error = checkCanceledNavigation(toLocation, from);
if (error)
return error;
const isFirstNavigation = from === START_LOCATION_NORMALIZED;
const state = !isBrowser ? {} : history.state;
if (isPush) {
if (replace2 || isFirstNavigation)
routerHistory.replace(toLocation.fullPath, assign({
scroll: isFirstNavigation && state && state.scroll
}, data));
else
routerHistory.push(toLocation.fullPath, data);
}
currentRoute.value = toLocation;
handleScroll(toLocation, from, isPush, isFirstNavigation);
markAsReady();
}
let removeHistoryListener;
function setupListeners() {
if (removeHistoryListener)
return;
removeHistoryListener = routerHistory.listen((to, _from, info) => {
if (!router.listening)
return;
const toLocation = resolve(to);
const shouldRedirect = handleRedirectRecord(toLocation);
if (shouldRedirect) {
pushWithRedirect(assign(shouldRedirect, { replace: true, force: true }), toLocation).catch(noop);
return;
}
pendingLocation = toLocation;
const from = currentRoute.value;
if (isBrowser) {
saveScrollPosition(getScrollKey(from.fullPath, info.delta), computeScrollPosition());
}
navigate(toLocation, from).catch((error) => {
if (isNavigationFailure(
error,
4 | 8
/* ErrorTypes.NAVIGATION_CANCELLED */
)) {
return error;
}
if (isNavigationFailure(
error,
2
/* ErrorTypes.NAVIGATION_GUARD_REDIRECT */
)) {
pushWithRedirect(
assign(locationAsObject(error.to), {
force: true
}),
toLocation
// avoid an uncaught rejection, let push call triggerError
).then((failure) => {
if (isNavigationFailure(
failure,
4 | 16
/* ErrorTypes.NAVIGATION_DUPLICATED */
) && !info.delta && info.type === NavigationType.pop) {
routerHistory.go(-1, false);
}
}).catch(noop);
return Promise.reject();
}
if (info.delta) {
routerHistory.go(-info.delta, false);
}
return triggerError(error, toLocation, from);
}).then((failure) => {
failure = failure || finalizeNavigation(
// after navigation, all matched components are resolved
toLocation,
from,
false
);
if (failure) {
if (info.delta && // a new navigation has been triggered, so we do not want to revert, that will change the current history
// entry while a different route is displayed
!isNavigationFailure(
failure,
8
/* ErrorTypes.NAVIGATION_CANCELLED */
)) {
routerHistory.go(-info.delta, false);
} else if (info.type === NavigationType.pop && isNavigationFailure(
failure,
4 | 16
/* ErrorTypes.NAVIGATION_DUPLICATED */
)) {
routerHistory.go(-1, false);
}
}
triggerAfterEach(toLocation, from, failure);
}).catch(noop);
});
}
let readyHandlers = useCallbacks();
let errorListeners = useCallbacks();
let ready;
function triggerError(error, to, from) {
markAsReady(error);
const list = errorListeners.list();
if (list.length) {
list.forEach((handler) => handler(error, to, from));
} else {
if (true) {
warn("uncaught error during route navigation:");
}
console.error(error);
}
return Promise.reject(error);
}
function isReady() {
if (ready && currentRoute.value !== START_LOCATION_NORMALIZED)
return Promise.resolve();
return new Promise((resolve2, reject) => {
readyHandlers.add([resolve2, reject]);
});
}
function markAsReady(err) {
if (!ready) {
ready = !err;
setupListeners();
readyHandlers.list().forEach(([resolve2, reject]) => err ? reject(err) : resolve2());
readyHandlers.reset();
}
return err;
}
function handleScroll(to, from, isPush, isFirstNavigation) {
const { scrollBehavior } = options;
if (!isBrowser || !scrollBehavior)
return Promise.resolve();
const scrollPosition = !isPush && getSavedScrollPosition(getScrollKey(to.fullPath, 0)) || (isFirstNavigation || !isPush) && history.state && history.state.scroll || null;
return nextTick().then(() => scrollBehavior(to, from, scrollPosition)).then((position) => position && scrollToPosition(position)).catch((err) => triggerError(err, to, from));
}
const go = (delta) => routerHistory.go(delta);
let started;
const installedApps = /* @__PURE__ */ new Set();
const router = {
currentRoute,
listening: true,
addRoute,
removeRoute,
clearRoutes: matcher.clearRoutes,
hasRoute,
getRoutes,
resolve,
options,
push,
replace,
go,
back: () => go(-1),
forward: () => go(1),
beforeEach: beforeGuards.add,
beforeResolve: beforeResolveGuards.add,
afterEach: afterGuards.add,
onError: errorListeners.add,
isReady,
install(app) {
const router2 = this;
app.component("RouterLink", RouterLink);
app.component("RouterView", RouterView);
app.config.globalProperties.$router = router2;
Object.defineProperty(app.config.globalProperties, "$route", {
enumerable: true,
get: () => unref(currentRoute)
});
if (isBrowser && // used for the initial navigation client side to avoid pushing
// multiple times when the router is used in multiple apps
!started && currentRoute.value === START_LOCATION_NORMALIZED) {
started = true;
push(routerHistory.location).catch((err) => {
if (true)
warn("Unexpected error when starting the router:", err);
});
}
const reactiveRoute = {};
for (const key in START_LOCATION_NORMALIZED) {
Object.defineProperty(reactiveRoute, key, {
get: () => currentRoute.value[key],
enumerable: true
});
}
app.provide(routerKey, router2);
app.provide(routeLocationKey, shallowReactive(reactiveRoute));
app.provide(routerViewLocationKey, currentRoute);
const unmountApp = app.unmount;
installedApps.add(app);
app.unmount = function() {
installedApps.delete(app);
if (installedApps.size < 1) {
pendingLocation = START_LOCATION_NORMALIZED;
removeHistoryListener && removeHistoryListener();
removeHistoryListener = null;
currentRoute.value = START_LOCATION_NORMALIZED;
started = false;
ready = false;
}
unmountApp();
};
if (isBrowser) {
addDevtools(app, router2, matcher);
}
}
};
function runGuardQueue(guards) {
return guards.reduce((promise, guard) => promise.then(() => runWithContext(guard)), Promise.resolve());
}
return router;
}
function extractChangingRecords(to, from) {
const leavingRecords = [];
const updatingRecords = [];
const enteringRecords = [];
const len = Math.max(from.matched.length, to.matched.length);
for (let i = 0; i < len; i++) {
const recordFrom = from.matched[i];
if (recordFrom) {
if (to.matched.find((record) => isSameRouteRecord(record, recordFrom)))
updatingRecords.push(recordFrom);
else
leavingRecords.push(recordFrom);
}
const recordTo = to.matched[i];
if (recordTo) {
if (!from.matched.find((record) => isSameRouteRecord(record, recordTo))) {
enteringRecords.push(recordTo);
}
}
}
return [leavingRecords, updatingRecords, enteringRecords];
}
function useRouter() {
return inject(routerKey);
}
function useRoute(_name) {
return inject(routeLocationKey);
}
export { NavigationFailureType, RouterLink, RouterView, START_LOCATION_NORMALIZED as START_LOCATION, createMemoryHistory, createRouter, createRouterMatcher, createWebHashHistory, createWebHistory, isNavigationFailure, loadRouteLocation, matchedRouteKey, onBeforeRouteLeave, onBeforeRouteUpdate, parseQuery, routeLocationKey, routerKey, routerViewLocationKey, stringifyQuery, useLink, useRoute, useRouter, viewDepthKey };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInZ1ZS1yb3V0ZXIubWpzP3Y9ZTRmMThjMjkiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gICogdnVlLXJvdXRlciB2NC41LjFcbiAgKiAoYykgMjAyNSBFZHVhcmRvIFNhbiBNYXJ0aW4gTW9yb3RlXG4gICogQGxpY2Vuc2UgTUlUXG4gICovXG5pbXBvcnQgeyBnZXRDdXJyZW50SW5zdGFuY2UsIGluamVjdCwgb25Vbm1vdW50ZWQsIG9uRGVhY3RpdmF0ZWQsIG9uQWN0aXZhdGVkLCBjb21wdXRlZCwgdW5yZWYsIHdhdGNoRWZmZWN0LCBkZWZpbmVDb21wb25lbnQsIHJlYWN0aXZlLCBoLCBwcm92aWRlLCByZWYsIHdhdGNoLCBzaGFsbG93UmVmLCBzaGFsbG93UmVhY3RpdmUsIG5leHRUaWNrIH0gZnJvbSAndnVlJztcbmltcG9ydCB7IHNldHVwRGV2dG9vbHNQbHVnaW4gfSBmcm9tICdAdnVlL2RldnRvb2xzLWFwaSc7XG5cbmNvbnN0IGlzQnJvd3NlciA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCc7XG5cbi8qKlxuICogQWxsb3dzIGRpZmZlcmVudGlhdGluZyBsYXp5IGNvbXBvbmVudHMgZnJvbSBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYW5kIHZ1ZS1jbGFzcy1jb21wb25lbnRcbiAqIEBpbnRlcm5hbFxuICpcbiAqIEBwYXJhbSBjb21wb25lbnRcbiAqL1xuZnVuY3Rpb24gaXNSb3V0ZUNvbXBvbmVudChjb21wb25lbnQpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBjb21wb25lbnQgPT09ICdvYmplY3QnIHx8XG4gICAgICAgICdkaXNwbGF5TmFtZScgaW4gY29tcG9uZW50IHx8XG4gICAgICAgICdwcm9wcycgaW4gY29tcG9uZW50IHx8XG4gICAgICAgICdfX3ZjY09wdHMnIGluIGNvbXBvbmVudCk7XG59XG5mdW5jdGlvbiBpc0VTTW9kdWxlKG9iaikge1xuICAgIHJldHVybiAob2JqLl9fZXNNb2R1bGUgfHxcbiAgICAgICAgb2JqW1N5bWJvbC50b1N0cmluZ1RhZ10gPT09ICdNb2R1bGUnIHx8XG4gICAgICAgIC8vIHN1cHBvcnQgQ0Ygd2l0aCBkeW5hbWljIGltcG9ydHMgdGhhdCBkbyBub3RcbiAgICAgICAgLy8gYWRkIHRoZSBNb2R1bGUgc3RyaW5nIHRhZ1xuICAgICAgICAob2JqLmRlZmF1bHQgJiYgaXNSb3V0ZUNvbXBvbmVudChvYmouZGVmYXVsdCkpKTtcbn1cbmNvbnN0IGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG5mdW5jdGlvbiBhcHBseVRvUGFyYW1zKGZuLCBwYXJhbXMpIHtcbiAgICBjb25zdCBuZXdQYXJhbXMgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBwYXJhbXMpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBwYXJhbXNba2V5XTtcbiAgICAgICAgbmV3UGFyYW1zW2tleV0gPSBpc0FycmF5KHZhbHVlKVxuICAgICAgICAgICAgPyB2YWx1ZS5tYXAoZm4pXG4gICAgICAgICAgICA6IGZuKHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ld1BhcmFtcztcbn1cbmNvbnN0IG5vb3AgPSAoKSA9PiB7IH07XG4vKipcbiAqIFR5cGVzYWZlIGFsdGVybmF0aXZlIHRvIEFycmF5LmlzQXJyYXlcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvVHlwZVNjcmlwdC9wdWxsLzQ4MjI4XG4gKi9cbmNvbnN0IGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG5mdW5jdGlvbiB3YXJuKG1zZykge1xuICAgIC8vIGF2b2lkIHVzaW5nIC4uLmFyZ3MgYXMgaXQgYnJlYWtzIGluIG9sZGVyIEVkZ2UgYnVpbGRzXG4gICAgY29uc3QgYXJncyA9IEFycmF5LmZyb20oYXJndW1lbnRzKS5zbGljZSgxKTtcbiAgICBjb25zb2xlLndhcm4uYXBwbHkoY29uc29sZSwgWydbVnVlIFJvdXRlciB3YXJuXTogJyArIG1zZ10uY29uY2F0KGFyZ3MpKTtcbn1cblxuLyoqXG4gKiBFbmNvZGluZyBSdWxlcyAo4pCjID0gU3BhY2UpXG4gKiAtIFBhdGg6IOKQoyBcIiA8ID4gIyA/IHsgfVxuICogLSBRdWVyeTog4pCjIFwiIDwgPiAjICYgPVxuICogLSBIYXNoOiDikKMgXCIgPCA+IGBcbiAqXG4gKiBPbiB0b3Agb2YgdGhhdCwgdGhlIFJGQzM5ODYgKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzOTg2I3NlY3Rpb24tMi4yKVxuICogZGVmaW5lcyBzb21lIGV4dHJhIGNoYXJhY3RlcnMgdG8gYmUgZW5jb2RlZC4gTW9zdCBicm93c2VycyBkbyBub3QgZW5jb2RlIHRoZW1cbiAqIGluIGVuY29kZVVSSSBodHRwczovL2dpdGh1Yi5jb20vd2hhdHdnL3VybC9pc3N1ZXMvMzY5LCBzbyBpdCBtYXkgYmUgc2FmZXIgdG9cbiAqIGFsc28gZW5jb2RlIGAhJygpKmAuIExlYXZpbmcgdW4tZW5jb2RlZCBvbmx5IEFTQ0lJIGFscGhhbnVtZXJpYyhgYS16QS1aMC05YClcbiAqIHBsdXMgYC0uX35gLiBUaGlzIGV4dHJhIHNhZmV0eSBzaG91bGQgYmUgYXBwbGllZCB0byBxdWVyeSBieSBwYXRjaGluZyB0aGVcbiAqIHN0cmluZyByZXR1cm5lZCBieSBlbmNvZGVVUklDb21wb25lbnQgZW5jb2RlVVJJIGFsc28gZW5jb2RlcyBgW1xcXV5gLiBgXFxgXG4gKiBzaG91bGQgYmUgZW5jb2RlZCB0byBhdm9pZCBhbWJpZ3VpdHkuIEJyb3dzZXJzIChJRSwgRkYsIEMpIHRyYW5zZm9ybSBhIGBcXGBcbiAqIGludG8gYSBgL2AgaWYgZGlyZWN0bHkgdHlwZWQgaW4uIFRoZSBfYmFja3RpY2tfIChgYGBgYCkgc2hvdWxkIGFsc28gYmVcbiAqIGVuY29kZWQgZXZlcnl3aGVyZSBiZWNhdXNlIHNvbWUgYnJvd3NlcnMgbGlrZSBGRiBlbmNvZGUgaXQgd2hlbiBkaXJlY3RseVxuICogd3JpdHRlbiB3aGlsZSBvdGhlcnMgZG9uJ3QuIFNhZmFyaSBhbmQgSUUgZG9uJ3QgZW5jb2RlIGBgXCI8Pnt9YGBgIGluIGhhc2guXG4gKi9cbi8vIGNvbnN0IEVYVFJBX1JFU0VSVkVEX1JFID0gL1shJygpKl0vZ1xuLy8gY29uc3QgZW5jb2RlUmVzZXJ2ZWRSZXBsYWNlciA9IChjOiBzdHJpbmcpID0+ICclJyArIGMuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNilcbmNvbnN0IEhBU0hfUkUgPSAvIy9nOyAvLyAlMjNcbmNvbnN0IEFNUEVSU0FORF9SRSA9IC8mL2c7IC8vICUyNlxuY29uc3QgU0xBU0hfUkUgPSAvXFwvL2c7IC8vICUyRlxuY29uc3QgRVFVQUxfUkUgPSAvPS9nOyAvLyAlM0RcbmNvbnN0IElNX1JFID0gL1xcPy9nOyAvLyAlM0ZcbmNvbnN0IFBMVVNfUkUgPSAvXFwrL2c7IC8vICUyQlxuLyoqXG4gKiBOT1RFOiBJdCdzIG5vdCBjbGVhciB0byBtZSBpZiB3ZSBzaG91bGQgZW5jb2RlIHRoZSArIHN5bWJvbCBpbiBxdWVyaWVzLCBpdFxuICogc2VlbXMgdG8gYmUgbGVzcyBmbGV4aWJsZSB0aGFuIG5vdCBkb2luZyBzbyBhbmQgSSBjYW4ndCBmaW5kIG91dCB0aGUgbGVnYWN5XG4gKiBzeXN0ZW1zIHJlcXVpcmluZyB0aGlzIGZvciByZWd1bGFyIHJlcXVlc3RzIGxpa2UgdGV4dC9odG1sLiBJbiB0aGUgc3RhbmRhcmQsXG4gKiB0aGUgZW5jb2Rpbmcgb2YgdGhlIHBsdXMgY2hhcmFjdGVyIGlzIG9ubHkgbWVudGlvbmVkIGZvclxuICogYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAoaHR0cHM6Ly91cmwuc3BlYy53aGF0d2cub3JnLyN1cmxlbmNvZGVkLXBhcnNpbmcpIGFuZCBtb3N0IGJyb3dzZXJzIHNlZW1zIGxvXG4gKiBsZWF2ZSB0aGUgcGx1cyBjaGFyYWN0ZXIgYXMgaXMgaW4gcXVlcmllcy4gVG8gYmUgbW9yZSBmbGV4aWJsZSwgd2UgYWxsb3cgdGhlXG4gKiBwbHVzIGNoYXJhY3RlciBvbiB0aGUgcXVlcnksIGJ1dCBpdCBjYW4gYWxzbyBiZSBtYW51YWxseSBlbmNvZGVkIGJ5IHRoZSB1c2VyLlxuICpcbiAqIFJlc291cmNlczpcbiAqIC0gaHR0cHM6Ly91cmwuc3BlYy53aGF0d2cub3JnLyN1cmxlbmNvZGVkLXBhcnNpbmdcbiAqIC0gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTYzNDI3MS91cmwtZW5jb2RpbmctdGhlLXNwYWNlLWNoYXJhY3Rlci1vci0yMFxuICovXG5jb25zdCBFTkNfQlJBQ0tFVF9PUEVOX1JFID0gLyU1Qi9nOyAvLyBbXG5jb25zdCBFTkNfQlJBQ0tFVF9DTE9TRV9SRSA9IC8lNUQvZzsgLy8gXVxuY29uc3QgRU5DX0NBUkVUX1JFID0gLyU1RS9nOyAvLyBeXG5jb25zdCBFTkNfQkFDS1RJQ0tfUkUgPSAvJTYwL2c7IC8vIGBcbmNvbnN0IEVOQ19DVVJMWV9PUEVOX1JFID0gLyU3Qi9nOyAvLyB7XG5jb25zdCBFTkNfUElQRV9SRSA9IC8lN0MvZzsgLy8gfFxuY29uc3QgRU5DX0NVUkxZX0NMT1NFX1JFID0gLyU3RC9nOyAvLyB9XG5jb25zdCBFTkNfU1BBQ0VfUkUgPSAvJTIwL2c7IC8vIH1cbi8qKlxuICogRW5jb2RlIGNoYXJhY3RlcnMgdGhhdCBuZWVkIHRvIGJlIGVuY29kZWQgb24gdGhlIHBhdGgsIHNlYXJjaCBhbmQgaGFzaFxuICogc2VjdGlvbnMgb2YgdGhlIFVSTC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxuICogQHJldHVybnMgZW5jb2RlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gY29tbW9uRW5jb2RlKHRleHQpIHtcbiAgICByZXR1cm4gZW5jb2RlVVJJKCcnICsgdGV4dClcbiAgICAgICAgLnJlcGxhY2UoRU5DX1BJUEVfUkUsICd8JylcbiAgICAgICAgLnJlcGxhY2UoRU5DX0JSQUNLRVRfT1BFTl9SRSwgJ1snKVxuICAgICAgICAucmVwbGFjZShFTkNfQlJBQ0tFVF9DTE9TRV9SRSwgJ10nKTtcbn1cbi8qKlxuICogRW5jb2RlIGNoYXJhY3RlcnMgdGhhdCBuZWVkIHRvIGJlIGVuY29kZWQgb24gdGhlIGhhc2ggc2VjdGlvbiBvZiB0aGUgVVJMLlxuICpcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxuICogQHJldHVybnMgZW5jb2RlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gZW5jb2RlSGFzaCh0ZXh0KSB7XG4gICAgcmV0dXJuIGNvbW1vbkVuY29kZSh0ZXh0KVxuICAgICAgICAucmVwbGFjZShFTkNfQ1VSTFlfT1BFTl9SRSwgJ3snKVxuICAgICAgICAucmVwbGFjZShFTkNfQ1VSTFlfQ0xPU0VfUkUsICd9JylcbiAgICAgICAgLnJlcGxhY2UoRU5DX0NBUkVUX1JFLCAnXicpO1xufVxuLyoqXG4gKiBFbmNvZGUgY2hhcmFjdGVycyB0aGF0IG5lZWQgdG8gYmUgZW5jb2RlZCBxdWVyeSB2YWx1ZXMgb24gdGhlIHF1ZXJ5XG4gKiBzZWN0aW9uIG9mIHRoZSBVUkwuXG4gKlxuICogQHBhcmFtIHRleHQgLSBzdHJpbmcgdG8gZW5jb2RlXG4gKiBAcmV0dXJucyBlbmNvZGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiBlbmNvZGVRdWVyeVZhbHVlKHRleHQpIHtcbiAgICByZXR1cm4gKGNvbW1vbkVuY29kZSh0ZXh0KVxuICAgICAgICAvLyBFbmNvZGUgdGhlIHNwYWNlIGFzICssIGVuY29kZSB0aGUgKyB0byBkaWZmZXJlbnRpYXRlIGl0IGZyb20gdGhlIHNwYWNlXG4gICAgICAgIC5yZXBsYWNlKFBMVVNfUkUsICclMkInKVxuICAgICAgICAucmVwbGFjZShFTkNfU1BBQ0VfUkUsICcrJylcbiAgICAgICAgLnJlcGxhY2UoSEFTSF9SRSwgJyUyMycpXG4gICAgICAgIC5yZXBsYWNlKEFNUEVSU0FORF9SRSwgJyUyNicpXG4gICAgICAgIC5yZXBsYWNlKEVOQ19CQUNLVElDS19SRSwgJ2AnKVxuICAgICAgICAucmVwbGFjZShFTkNfQ1VSTFlfT1BFTl9SRSwgJ3snKVxuICAgICAgICAucmVwbGFjZShFTkNfQ1VSTFlfQ0xPU0VfUkUsICd9JylcbiAgICAgICAgLnJlcGxhY2UoRU5DX0NBUkVUX1JFLCAnXicpKTtcbn1cbi8qKlxuICogTGlrZSBgZW5jb2RlUXVlcnlWYWx1ZWAgYnV0IGFsc28gZW5jb2RlcyB0aGUgYD1gIGNoYXJhY3Rlci5cbiAqXG4gKiBAcGFyYW0gdGV4dCAtIHN0cmluZyB0byBlbmNvZGVcbiAqL1xuZnVuY3Rpb24gZW5jb2RlUXVlcnlLZXkodGV4dCkge1xuICAgIHJldHVybiBlbmNvZGVRdWVyeVZhbHVlKHRleHQpLnJlcGxhY2UoRVFVQUxfUkUsICclM0QnKTtcbn1cbi8qKlxuICogRW5jb2RlIGNoYXJhY3RlcnMgdGhhdCBuZWVkIHRvIGJlIGVuY29kZWQgb24gdGhlIHBhdGggc2VjdGlvbiBvZiB0aGUgVVJMLlxuICpcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxuICogQHJldHVybnMgZW5jb2RlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gZW5jb2RlUGF0aCh0ZXh0KSB7XG4gICAgcmV0dXJuIGNvbW1vbkVuY29kZSh0ZXh0KS5yZXBsYWNlKEhBU0hfUkUsICclMjMnKS5yZXBsYWNlKElNX1JFLCAnJTNGJyk7XG59XG4vKipcbiAqIEVuY29kZSBjaGFyYWN0ZXJzIHRoYXQgbmVlZCB0byBiZSBlbmNvZGVkIG9uIHRoZSBwYXRoIHNlY3Rpb24gb2YgdGhlIFVSTCBhcyBhXG4gKiBwYXJhbS4gVGhpcyBmdW5jdGlvbiBlbmNvZGVzIGV2ZXJ5dGhpbmcge0BsaW5rIGVuY29kZVBhdGh9IGRvZXMgcGx1cyB0aGVcbiAqIHNsYXNoIChgL2ApIGNoYXJhY3Rlci4gSWYgYHRleHRgIGlzIGBudWxsYCBvciBgdW5kZWZpbmVkYCwgcmV0dXJucyBhbiBlbXB0eVxuICogc3RyaW5nIGluc3RlYWQuXG4gKlxuICogQHBhcmFtIHRleHQgLSBzdHJpbmcgdG8gZW5jb2RlXG4gKiBAcmV0dXJucyBlbmNvZGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiBlbmNvZGVQYXJhbSh0ZXh0KSB7XG4gICAgcmV0dXJuIHRleHQgPT0gbnVsbCA/ICcnIDogZW5jb2RlUGF0aCh0ZXh0KS5yZXBsYWNlKFNMQVNIX1JFLCAnJTJGJyk7XG59XG4vKipcbiAqIERlY29kZSB0ZXh0IHVzaW5nIGBkZWNvZGVVUklDb21wb25lbnRgLiBSZXR1cm5zIHRoZSBvcmlnaW5hbCB0ZXh0IGlmIGl0XG4gKiBmYWlscy5cbiAqXG4gKiBAcGFyYW0gdGV4dCAtIHN0cmluZyB0byBkZWNvZGVcbiAqIEByZXR1cm5zIGRlY29kZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGRlY29kZSh0ZXh0KSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCgnJyArIHRleHQpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB3YXJuKGBFcnJvciBkZWNvZGluZyBcIiR7dGV4dH1cIi4gVXNpbmcgb3JpZ2luYWwgdmFsdWVgKTtcbiAgICB9XG4gICAgcmV0dXJuICcnICsgdGV4dDtcbn1cblxuY29uc3QgVFJBSUxJTkdfU0xBU0hfUkUgPSAvXFwvJC87XG5jb25zdCByZW1vdmVUcmFpbGluZ1NsYXNoID0gKHBhdGgpID0+IHBhdGgucmVwbGFjZShUUkFJTElOR19TTEFTSF9SRSwgJycpO1xuLyoqXG4gKiBUcmFuc2Zvcm1zIGEgVVJJIGludG8gYSBub3JtYWxpemVkIGhpc3RvcnkgbG9jYXRpb25cbiAqXG4gKiBAcGFyYW0gcGFyc2VRdWVyeVxuICogQHBhcmFtIGxvY2F0aW9uIC0gVVJJIHRvIG5vcm1hbGl6ZVxuICogQHBhcmFtIGN1cnJlbnRMb2NhdGlvbiAtIGN1cnJlbnQgYWJzb2x1dGUgbG9jYXRpb24uIEFsbG93cyByZXNvbHZpbmcgcmVsYXRpdmVcbiAqIHBhdGhzLiBNdXN0IHN0YXJ0IHdpdGggYC9gLiBEZWZhdWx0cyB0byBgL2BcbiAqIEByZXR1cm5zIGEgbm9ybWFsaXplZCBoaXN0b3J5IGxvY2F0aW9uXG4gKi9cbmZ1bmN0aW9uIHBhcnNlVVJMKHBhcnNlUXVlcnksIGxvY2F0aW9uLCBjdXJyZW50TG9jYXRpb24gPSAnLycpIHtcbiAgICBsZXQgcGF0aCwgcXVlcnkgPSB7fSwgc2VhcmNoU3RyaW5nID0gJycsIGhhc2ggPSAnJztcbiAgICAvLyBDb3VsZCB1c2UgVVJMIGFuZCBVUkxTZWFyY2hQYXJhbXMgYnV0IElFIDExIGRvZXNuJ3Qgc3VwcG9ydCBpdFxuICAgIC8vIFRPRE86IG1vdmUgdG8gbmV3IFVSTCgpXG4gICAgY29uc3QgaGFzaFBvcyA9IGxvY2F0aW9uLmluZGV4T2YoJyMnKTtcbiAgICBsZXQgc2VhcmNoUG9zID0gbG9jYXRpb24uaW5kZXhPZignPycpO1xuICAgIC8vIHRoZSBoYXNoIGFwcGVhcnMgYmVmb3JlIHRoZSBzZWFyY2gsIHNvIGl0J3Mgbm90IHBhcnQgb2YgdGhlIHNlYXJjaCBzdHJpbmdcbiAgICBpZiAoaGFzaFBvcyA8IHNlYXJjaFBvcyAmJiBoYXNoUG9zID49IDApIHtcbiAgICAgICAgc2VhcmNoUG9zID0gLTE7XG4gICAgfVxuICAgIGlmIChzZWFyY2hQb3MgPiAtMSkge1xuICAgICAgICBwYXRoID0gbG9jYXRpb24uc2xpY2UoMCwgc2VhcmNoUG9zKTtcbiAgICAgICAgc2VhcmNoU3RyaW5nID0gbG9jYXRpb24uc2xpY2Uoc2VhcmNoUG9zICsgMSwgaGFzaFBvcyA+IC0xID8gaGFzaFBvcyA6IGxvY2F0aW9uLmxlbmd0aCk7XG4gICAgICAgIHF1ZXJ5ID0gcGFyc2VRdWVyeShzZWFyY2hTdHJpbmcpO1xuICAgIH1cbiAgICBpZiAoaGFzaFBvcyA+IC0xKSB7XG4gICAgICAgIHBhdGggPSBwYXRoIHx8IGxvY2F0aW9uLnNsaWNlKDAsIGhhc2hQb3MpO1xuICAgICAgICAvLyBrZWVwIHRoZSAjIGNoYXJhY3RlclxuICAgICAgICBoYXNoID0gbG9jYXRpb24uc2xpY2UoaGFzaFBvcywgbG9jYXRpb24ubGVuZ3RoKTtcbiAgICB9XG4gICAgLy8gbm8gc2VhcmNoIGFuZCBubyBxdWVyeVxuICAgIHBhdGggPSByZXNvbHZlUmVsYXRpdmVQYXRoKHBhdGggIT0gbnVsbCA/IHBhdGggOiBsb2NhdGlvbiwgY3VycmVudExvY2F0aW9uKTtcbiAgICAvLyBlbXB0eSBwYXRoIG1lYW5zIGEgcmVsYXRpdmUgcXVlcnkgb3IgaGFzaCBgP2Zvbz1mYCwgYCN0aGluZ2BcbiAgICByZXR1cm4ge1xuICAgICAgICBmdWxsUGF0aDogcGF0aCArIChzZWFyY2hTdHJpbmcgJiYgJz8nKSArIHNlYXJjaFN0cmluZyArIGhhc2gsXG4gICAgICAgIHBhdGgsXG4gICAgICAgIHF1ZXJ5LFxuICAgICAgICBoYXNoOiBkZWNvZGUoaGFzaCksXG4gICAgfTtcbn1cbi8qKlxuICogU3RyaW5naWZpZXMgYSBVUkwgb2JqZWN0XG4gKlxuICogQHBhcmFtIHN0cmluZ2lmeVF1ZXJ5XG4gKiBAcGFyYW0gbG9jYXRpb25cbiAqL1xuZnVuY3Rpb24gc3RyaW5naWZ5VVJMKHN0cmluZ2lmeVF1ZXJ5LCBsb2NhdGlvbikge1xuICAgIGNvbnN0IHF1ZXJ5ID0gbG9jYXRpb24ucXVlcnkgPyBzdHJpbmdpZnlRdWVyeShsb2NhdGlvbi5xdWVyeSkgOiAnJztcbiAgICByZXR1cm4gbG9jYXRpb24ucGF0aCArIChxdWVyeSAmJiAnPycpICsgcXVlcnkgKyAobG9jYXRpb24uaGFzaCB8fCAnJyk7XG59XG4vKipcbiAqIFN0cmlwcyBvZmYgdGhlIGJhc2UgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIGEgbG9jYXRpb24ucGF0aG5hbWUgaW4gYSBub24tY2FzZS1zZW5zaXRpdmUgd2F5LlxuICpcbiAqIEBwYXJhbSBwYXRobmFtZSAtIGxvY2F0aW9uLnBhdGhuYW1lXG4gKiBAcGFyYW0gYmFzZSAtIGJhc2UgdG8gc3RyaXAgb2ZmXG4gKi9cbmZ1bmN0aW9uIHN0cmlwQmFzZShwYXRobmFtZSwgYmFzZSkge1xuICAgIC8vIG5vIGJhc2Ugb3IgYmFzZSBpcyBub3QgZm91bmQgYXQgdGhlIGJlZ2lubmluZ1xuICAgIGlmICghYmFzZSB8fCAhcGF0aG5hbWUudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKGJhc2UudG9Mb3dlckNhc2UoKSkpXG4gICAgICAgIHJldHVybiBwYXRobmFtZTtcbiAgICByZXR1cm4gcGF0aG5hbWUuc2xpY2UoYmFzZS5sZW5ndGgpIHx8ICcvJztcbn1cbi8qKlxuICogQ2hlY2tzIGlmIHR3byBSb3V0ZUxvY2F0aW9uIGFyZSBlcXVhbC4gVGhpcyBtZWFucyB0aGF0IGJvdGggbG9jYXRpb25zIGFyZVxuICogcG9pbnRpbmcgdG93YXJkcyB0aGUgc2FtZSB7QGxpbmsgUm91dGVSZWNvcmR9IGFuZCB0aGF0IGFsbCBgcGFyYW1zYCwgYHF1ZXJ5YFxuICogcGFyYW1ldGVycyBhbmQgYGhhc2hgIGFyZSB0aGUgc2FtZVxuICpcbiAqIEBwYXJhbSBzdHJpbmdpZnlRdWVyeSAtIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhIHF1ZXJ5IG9iamVjdCBvZiB0eXBlIExvY2F0aW9uUXVlcnlSYXcgYW5kIHJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgaXQuXG4gKiBAcGFyYW0gYSAtIGZpcnN0IHtAbGluayBSb3V0ZUxvY2F0aW9ufVxuICogQHBhcmFtIGIgLSBzZWNvbmQge0BsaW5rIFJvdXRlTG9jYXRpb259XG4gKi9cbmZ1bmN0aW9uIGlzU2FtZVJvdXRlTG9jYXRpb24oc3RyaW5naWZ5UXVlcnksIGEsIGIpIHtcbiAgICBjb25zdCBhTGFzdEluZGV4ID0gYS5tYXRjaGVkLmxlbmd0aCAtIDE7XG4gICAgY29uc3QgYkxhc3RJbmRleCA9IGIubWF0Y2hlZC5sZW5ndGggLSAxO1xuICAgIHJldHVybiAoYUxhc3RJbmRleCA+IC0xICYmXG4gICAgICAgIGFMYXN0SW5kZXggPT09IGJMYXN0SW5kZXggJiZcbiAgICAgICAgaXNTYW1lUm91dGVSZWNvcmQoYS5tYXRjaGVkW2FMYXN0SW5kZXhdLCBiLm1hdGNoZWRbYkxhc3RJbmRleF0pICYmXG4gICAgICAgIGlzU2FtZVJvdXRlTG9jYXRpb25QYXJhbXMoYS5wYXJhbXMsIGIucGFyYW1zKSAmJlxuICAgICAgICBzdHJpbmdpZnlRdWVyeShhLnF1ZXJ5KSA9PT0gc3RyaW5naWZ5UXVlcnkoYi5xdWVyeSkgJiZcbiAgICAgICAgYS5oYXNoID09PSBiLmhhc2gpO1xufVxuLyoqXG4gKiBDaGVjayBpZiB0d28gYFJvdXRlUmVjb3Jkc2AgYXJlIGVxdWFsLiBUYWtlcyBpbnRvIGFjY291bnQgYWxpYXNlczogdGhleSBhcmVcbiAqIGNvbnNpZGVyZWQgZXF1YWwgdG8gdGhlIGBSb3V0ZVJlY29yZGAgdGhleSBhcmUgYWxpYXNpbmcuXG4gKlxuICogQHBhcmFtIGEgLSBmaXJzdCB7QGxpbmsgUm91dGVSZWNvcmR9XG4gKiBAcGFyYW0gYiAtIHNlY29uZCB7QGxpbmsgUm91dGVSZWNvcmR9XG4gKi9cbmZ1bmN0aW9uIGlzU2FtZVJvdXRlUmVjb3JkKGEsIGIpIHtcbiAgICAvLyBzaW5jZSB0aGUgb3JpZ2luYWwgcmVjb3JkIGhhcyBhbiB1bmRlZmluZWQgdmFsdWUgZm9yIGFsaWFzT2ZcbiAgICAvLyBidXQgYWxsIGFsaWFzZXMgcG9pbnQgdG8gdGhlIG9yaWdpbmFsIHJlY29yZCwgdGhpcyB3aWxsIGFsd2F5cyBjb21wYXJlXG4gICAgLy8gdGhlIG9yaWdpbmFsIHJlY29yZFxuICAgIHJldHVybiAoYS5hbGlhc09mIHx8IGEpID09PSAoYi5hbGlhc09mIHx8IGIpO1xufVxuZnVuY3Rpb24gaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtcyhhLCBiKSB7XG4gICAgaWYgKE9iamVjdC5rZXlzKGEpLmxlbmd0aCAhPT0gT2JqZWN0LmtleXMoYikubGVuZ3RoKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gYSkge1xuICAgICAgICBpZiAoIWlzU2FtZVJvdXRlTG9jYXRpb25QYXJhbXNWYWx1ZShhW2tleV0sIGJba2V5XSkpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtc1ZhbHVlKGEsIGIpIHtcbiAgICByZXR1cm4gaXNBcnJheShhKVxuICAgICAgICA/IGlzRXF1aXZhbGVudEFycmF5KGEsIGIpXG4gICAgICAgIDogaXNBcnJheShiKVxuICAgICAgICAgICAgPyBpc0VxdWl2YWxlbnRBcnJheShiLCBhKVxuICAgICAgICAgICAgOiBhID09PSBiO1xufVxuLyoqXG4gKiBDaGVjayBpZiB0d28gYXJyYXlzIGFyZSB0aGUgc2FtZSBvciBpZiBhbiBhcnJheSB3aXRoIG9uZSBzaW5nbGUgZW50cnkgaXMgdGhlXG4gKiBzYW1lIGFzIGFub3RoZXIgcHJpbWl0aXZlIHZhbHVlLiBVc2VkIHRvIGNoZWNrIHF1ZXJ5IGFuZCBwYXJhbWV0ZXJzXG4gKlxuICogQHBhcmFtIGEgLSBhcnJheSBvZiB2YWx1ZXNcbiAqIEBwYXJhbSBiIC0gYXJyYXkgb2YgdmFsdWVzIG9yIGEgc2luZ2xlIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGlzRXF1aXZhbGVudEFycmF5KGEsIGIpIHtcbiAgICByZXR1cm4gaXNBcnJheShiKVxuICAgICAgICA/IGEubGVuZ3RoID09PSBiLmxlbmd0aCAmJiBhLmV2ZXJ5KCh2YWx1ZSwgaSkgPT4gdmFsdWUgPT09IGJbaV0pXG4gICAgICAgIDogYS5sZW5ndGggPT09IDEgJiYgYVswXSA9PT0gYjtcbn1cbi8qKlxuICogUmVzb2x2ZXMgYSByZWxhdGl2ZSBwYXRoIHRoYXQgc3RhcnRzIHdpdGggYC5gLlxuICpcbiAqIEBwYXJhbSB0byAtIHBhdGggbG9jYXRpb24gd2UgYXJlIHJlc29sdmluZ1xuICogQHBhcmFtIGZyb20gLSBjdXJyZW50TG9jYXRpb24ucGF0aCwgc2hvdWxkIHN0YXJ0IHdpdGggYC9gXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVSZWxhdGl2ZVBhdGgodG8sIGZyb20pIHtcbiAgICBpZiAodG8uc3RhcnRzV2l0aCgnLycpKVxuICAgICAgICByZXR1cm4gdG87XG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhZnJvbS5zdGFydHNXaXRoKCcvJykpIHtcbiAgICAgICAgd2FybihgQ2Fubm90IHJlc29sdmUgYSByZWxhdGl2ZSBsb2NhdGlvbiB3aXRob3V0IGFuIGFic29sdXRlIHBhdGguIFRyeWluZyB0byByZXNvbHZlIFwiJHt0b31cIiBmcm9tIFwiJHtmcm9tfVwiLiBJdCBzaG91bGQgbG9vayBsaWtlIFwiLyR7ZnJvbX1cIi5gKTtcbiAgICAgICAgcmV0dXJuIHRvO1xuICAgIH1cbiAgICBpZiAoIXRvKVxuICAgICAgICByZXR1cm4gZnJvbTtcbiAgICBjb25zdCBmcm9tU2VnbWVudHMgPSBmcm9tLnNwbGl0KCcvJyk7XG4gICAgY29uc3QgdG9TZWdtZW50cyA9IHRvLnNwbGl0KCcvJyk7XG4gICAgY29uc3QgbGFzdFRvU2VnbWVudCA9IHRvU2VnbWVudHNbdG9TZWdtZW50cy5sZW5ndGggLSAxXTtcbiAgICAvLyBtYWtlIC4gYW5kIC4vIHRoZSBzYW1lICguLi8gPT09IC4uLCAuLi8uLi8gPT09IC4uLy4uKVxuICAgIC8vIHRoaXMgaXMgdGhlIHNhbWUgYmVoYXZpb3IgYXMgbmV3IFVSTCgpXG4gICAgaWYgKGxhc3RUb1NlZ21lbnQgPT09ICcuLicgfHwgbGFzdFRvU2VnbWVudCA9PT0gJy4nKSB7XG4gICAgICAgIHRvU2VnbWVudHMucHVzaCgnJyk7XG4gICAgfVxuICAgIGxldCBwb3NpdGlvbiA9IGZyb21TZWdtZW50cy5sZW5ndGggLSAxO1xuICAgIGxldCB0b1Bvc2l0aW9uO1xuICAgIGxldCBzZWdtZW50O1xuICAgIGZvciAodG9Qb3NpdGlvbiA9IDA7IHRvUG9zaXRpb24gPCB0b1NlZ21lbnRzLmxlbmd0aDsgdG9Qb3NpdGlvbisrKSB7XG4gICAgICAgIHNlZ21lbnQgPSB0b1NlZ21lbnRzW3RvUG9zaXRpb25dO1xuICAgICAgICAvLyB3ZSBzdGF5IG9uIHRoZSBzYW1lIHBvc2l0aW9uXG4gICAgICAgIGlmIChzZWdtZW50ID09PSAnLicpXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgLy8gZ28gdXAgaW4gdGhlIGZyb20gYXJyYXlcbiAgICAgICAgaWYgKHNlZ21lbnQgPT09ICcuLicpIHtcbiAgICAgICAgICAgIC8vIHdlIGNhbid0IGdvIGJlbG93IHplcm8sIGJ1dCB3ZSBzdGlsbCBuZWVkIHRvIGluY3JlbWVudCB0b1Bvc2l0aW9uXG4gICAgICAgICAgICBpZiAocG9zaXRpb24gPiAxKVxuICAgICAgICAgICAgICAgIHBvc2l0aW9uLS07XG4gICAgICAgICAgICAvLyBjb250aW51ZVxuICAgICAgICB9XG4gICAgICAgIC8vIHdlIHJlYWNoZWQgYSBub24tcmVsYXRpdmUgcGF0aCwgd2Ugc3RvcCBoZXJlXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gKGZyb21TZWdtZW50cy5zbGljZSgwLCBwb3NpdGlvbikuam9pbignLycpICtcbiAgICAgICAgJy8nICtcbiAgICAgICAgdG9TZWdtZW50cy5zbGljZSh0b1Bvc2l0aW9uKS5qb2luKCcvJykpO1xufVxuLyoqXG4gKiBJbml0aWFsIHJvdXRlIGxvY2F0aW9uIHdoZXJlIHRoZSByb3V0ZXIgaXMuIENhbiBiZSB1c2VkIGluIG5hdmlnYXRpb24gZ3VhcmRzXG4gKiB0byBkaWZmZXJlbnRpYXRlIHRoZSBpbml0aWFsIG5hdmlnYXRpb24uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGpzXG4gKiBpbXBvcnQgeyBTVEFSVF9MT0NBVElPTiB9IGZyb20gJ3Z1ZS1yb3V0ZXInXG4gKlxuICogcm91dGVyLmJlZm9yZUVhY2goKHRvLCBmcm9tKSA9PiB7XG4gKiAgIGlmIChmcm9tID09PSBTVEFSVF9MT0NBVElPTikge1xuICogICAgIC8vIGluaXRpYWwgbmF2aWdhdGlvblxuICogICB9XG4gKiB9KVxuICogYGBgXG4gKi9cbmNvbnN0IFNUQVJUX0xPQ0FUSU9OX05PUk1BTElaRUQgPSB7XG4gICAgcGF0aDogJy8nLFxuICAgIC8vIFRPRE86IGNvdWxkIHdlIHVzZSBhIHN5bWJvbCBpbiB0aGUgZnV0dXJlP1xuICAgIG5hbWU6IHVuZGVmaW5lZCxcbiAgICBwYXJhbXM6IHt9LFxuICAgIHF1ZXJ5OiB7fSxcbiAgICBoYXNoOiAnJyxcbiAgICBmdWxsUGF0aDogJy8nLFxuICAgIG1hdGNoZWQ6IFtdLFxuICAgIG1ldGE6IHt9LFxuICAgIHJlZGlyZWN0ZWRGcm9tOiB1bmRlZmluZWQsXG59O1xuXG52YXIgTmF2aWdhdGlvblR5cGU7XG4oZnVuY3Rpb24gKE5hdmlnYXRpb25UeXBlKSB7XG4gICAgTmF2aWdhdGlvblR5cGVbXCJwb3BcIl0gPSBcInBvcFwiO1xuICAgIE5hdmlnYXRpb25UeXBlW1wicHVzaFwiXSA9IFwicHVzaFwiO1xufSkoTmF2aWdhdGlvblR5cGUgfHwgKE5hdmlnYXRpb25UeXBlID0ge30pKTtcbnZhciBOYXZpZ2F0aW9uRGlyZWN0aW9uO1xuKGZ1bmN0aW9uIChOYXZpZ2F0aW9uRGlyZWN0aW9uKSB7XG4gICAgTmF2aWdhdGlvbkRpcmVjdGlvbltcImJhY2tcIl0gPSBcImJhY2tcIjtcbiAgICBOYXZpZ2F0aW9uRGlyZWN0aW9uW1wiZm9yd2FyZFwiXSA9IFwiZm9yd2FyZFwiO1xuICAgIE5hdmlnYXRpb25EaXJlY3Rpb25bXCJ1bmtub3duXCJdID0gXCJcIjtcbn0pKE5hdmlnYXRpb25EaXJlY3Rpb24gfHwgKE5hdmlnYXRpb25EaXJlY3Rpb24gPSB7fSkpO1xuLyoqXG4gKiBTdGFydGluZyBsb2NhdGlvbiBmb3IgSGlzdG9yaWVzXG4gKi9cbmNvbnN0IFNUQVJUID0gJyc7XG4vLyBHZW5lcmljIHV0aWxzXG4vKipcbiAqIE5vcm1hbGl6ZXMgYSBiYXNlIGJ5IHJlbW92aW5nIGFueSB0cmFpbGluZyBzbGFzaCBhbmQgcmVhZGluZyB0aGUgYmFzZSB0YWcgaWZcbiAqIHByZXNlbnQuXG4gKlxuICogQHBhcmFtIGJhc2UgLSBiYXNlIHRvIG5vcm1hbGl6ZVxuICovXG5mdW5jdGlvbiBub3JtYWxpemVCYXNlKGJhc2UpIHtcbiAgICBpZiAoIWJhc2UpIHtcbiAgICAgICAgaWYgKGlzQnJvd3Nlcikge1xuICAgICAgICAgICAgLy8gcmVzcGVjdCA8YmFzZT4gdGFnXG4gICAgICAgICAgICBjb25zdCBiYXNlRWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdiYXNlJyk7XG4gICAgICAgICAgICBiYXNlID0gKGJhc2VFbCAmJiBiYXNlRWwuZ2V0QXR0cmlidXRlKCdocmVmJykpIHx8ICcvJztcbiAgICAgICAgICAgIC8vIHN0cmlwIGZ1bGwgVVJMIG9yaWdpblxuICAgICAgICAgICAgYmFzZSA9IGJhc2UucmVwbGFjZSgvXlxcdys6XFwvXFwvW15cXC9dKy8sICcnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGJhc2UgPSAnLyc7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gZW5zdXJlIGxlYWRpbmcgc2xhc2ggd2hlbiBpdCB3YXMgcmVtb3ZlZCBieSB0aGUgcmVnZXggYWJvdmUgYXZvaWQgbGVhZGluZ1xuICAgIC8vIHNsYXNoIHdpdGggaGFzaCBiZWNhdXNlIHRoZSBmaWxlIGNvdWxkIGJlIHJlYWQgZnJvbSB0aGUgZGlzayBsaWtlIGZpbGU6Ly9cbiAgICAvLyBhbmQgdGhlIGxlYWRpbmcgc2xhc2ggd291bGQgY2F1c2UgcHJvYmxlbXNcbiAgICBpZiAoYmFzZVswXSAhPT0gJy8nICYmIGJhc2VbMF0gIT09ICcjJylcbiAgICAgICAgYmFzZSA9ICcvJyArIGJhc2U7XG4gICAgLy8gcmVtb3ZlIHRoZSB0cmFpbGluZyBzbGFzaCBzbyBhbGwgb3RoZXIgbWV0aG9kIGNhbiBqdXN0IGRvIGBiYXNlICsgZnVsbFBhdGhgXG4gICAgLy8gdG8gYnVpbGQgYW4gaHJlZlxuICAgIHJldHVybiByZW1vdmVUcmFpbGluZ1NsYXNoKGJhc2UpO1xufVxuLy8gcmVtb3ZlIGFueSBjaGFyYWN0ZXIgYmVmb3JlIHRoZSBoYXNoXG5jb25zdCBCRUZPUkVfSEFTSF9SRSA9IC9eW14jXSsjLztcbmZ1bmN0aW9uIGNyZWF0ZUhyZWYoYmFzZSwgbG9jYXRpb24pIHtcbiAgICByZXR1cm4gYmFzZS5yZXBsYWNlKEJFRk9SRV9IQVNIX1JFLCAnIycpICsgbG9jYXRpb247XG59XG5cbmZ1bmN0aW9uIGdldEVsZW1lbnRQb3NpdGlvbihlbCwgb2Zmc2V0KSB7XG4gICAgY29uc3QgZG9jUmVjdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBlbFJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBiZWhhdmlvcjogb2Zmc2V0LmJlaGF2aW9yLFxuICAgICAgICBsZWZ0OiBlbFJlY3QubGVmdCAtIGRvY1JlY3QubGVmdCAtIChvZmZzZXQubGVmdCB8fCAwKSxcbiAgICAgICAgdG9wOiBlbFJlY3QudG9wIC0gZG9jUmVjdC50b3AgLSAob2Zmc2V0LnRvcCB8fCAwKSxcbiAgICB9O1xufVxuY29uc3QgY29tcHV0ZVNjcm9sbFBvc2l0aW9uID0gKCkgPT4gKHtcbiAgICBsZWZ0OiB3aW5kb3cuc2Nyb2xsWCxcbiAgICB0b3A6IHdpbmRvdy5zY3JvbGxZLFxufSk7XG5mdW5jdGlvbiBzY3JvbGxUb1Bvc2l0aW9uKHBvc2l0aW9uKSB7XG4gICAgbGV0IHNjcm9sbFRvT3B0aW9ucztcbiAgICBpZiAoJ2VsJyBpbiBwb3NpdGlvbikge1xuICAgICAgICBjb25zdCBwb3NpdGlvbkVsID0gcG9zaXRpb24uZWw7XG4gICAgICAgIGNvbnN0IGlzSWRTZWxlY3RvciA9IHR5cGVvZiBwb3NpdGlvbkVsID09PSAnc3RyaW5nJyAmJiBwb3NpdGlvbkVsLnN0YXJ0c1dpdGgoJyMnKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBpZGBzIGNhbiBhY2NlcHQgcHJldHR5IG11Y2ggYW55IGNoYXJhY3RlcnMsIGluY2x1ZGluZyBDU1MgY29tYmluYXRvcnNcbiAgICAgICAgICogbGlrZSBgPmAgb3IgYH5gLiBJdCdzIHN0aWxsIHBvc3NpYmxlIHRvIHJldHJpZXZlIGVsZW1lbnRzIHVzaW5nXG4gICAgICAgICAqIGBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnficpYCBidXQgaXQgbmVlZHMgdG8gYmUgZXNjYXBlZCB3aGVuIHVzaW5nXG4gICAgICAgICAqIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjXFxcXH4nKWAgZm9yIGl0IHRvIGJlIHZhbGlkLiBUaGUgb25seVxuICAgICAgICAgKiByZXF1aXJlbWVudHMgZm9yIGBpZGBzIGFyZSB0aGVtIHRvIGJlIHVuaXF1ZSBvbiB0aGUgcGFnZSBhbmQgdG8gbm90IGJlXG4gICAgICAgICAqIGVtcHR5IChgaWQ9XCJcImApLiBCZWNhdXNlIG9mIHRoYXQsIHdoZW4gcGFzc2luZyBhbiBpZCBzZWxlY3RvciwgaXQgc2hvdWxkXG4gICAgICAgICAqIGJlIHByb3Blcmx5IGVzY2FwZWQgZm9yIGl0IHRvIHdvcmsgd2l0aCBgcXVlcnlTZWxlY3RvcmAuIFdlIGNvdWxkIGNoZWNrXG4gICAgICAgICAqIGZvciB0aGUgaWQgc2VsZWN0b3IgdG8gYmUgc2ltcGxlIChubyBDU1MgY29tYmluYXRvcnMgYCsgPn5gKSBidXQgdGhhdFxuICAgICAgICAgKiB3b3VsZCBtYWtlIHRoaW5ncyBpbmNvbnNpc3RlbnQgc2luY2UgdGhleSBhcmUgdmFsaWQgY2hhcmFjdGVycyBmb3IgYW5cbiAgICAgICAgICogYGlkYCBidXQgd291bGQgbmVlZCB0byBiZSBlc2NhcGVkIHdoZW4gdXNpbmcgYHF1ZXJ5U2VsZWN0b3JgLCBicmVha2luZ1xuICAgICAgICAgKiB0aGVpciB1c2FnZSBhbmQgZW5kaW5nIHVwIGluIG5vIHNlbGVjdG9yIHJldHVybmVkLiBTZWxlY3RvcnMgbmVlZCB0byBiZVxuICAgICAgICAgKiBlc2NhcGVkOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIGAjMS10aGluZ2AgYmVjb21lcyBgI1xcMzEgLXRoaW5nYFxuICAgICAgICAgKiAtIGAjd2l0aH5zeW1ib2xzYCBiZWNvbWVzIGAjd2l0aFxcXFx+c3ltYm9sc2BcbiAgICAgICAgICpcbiAgICAgICAgICogLSBNb3JlIGluZm9ybWF0aW9uIGFib3V0ICB0aGUgdG9waWMgY2FuIGJlIGZvdW5kIGF0XG4gICAgICAgICAqICAgaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2h0bWw1LWlkLWNsYXNzLlxuICAgICAgICAgKiAtIFByYWN0aWNhbCBleGFtcGxlOiBodHRwczovL21hdGhpYXNieW5lbnMuYmUvZGVtby9odG1sNS1pZFxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB0eXBlb2YgcG9zaXRpb24uZWwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoIWlzSWRTZWxlY3RvciB8fCAhZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocG9zaXRpb24uZWwuc2xpY2UoMSkpKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZm91bmRFbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IocG9zaXRpb24uZWwpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNJZFNlbGVjdG9yICYmIGZvdW5kRWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm4oYFRoZSBzZWxlY3RvciBcIiR7cG9zaXRpb24uZWx9XCIgc2hvdWxkIGJlIHBhc3NlZCBhcyBcImVsOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcke3Bvc2l0aW9uLmVsfScpXCIgYmVjYXVzZSBpdCBzdGFydHMgd2l0aCBcIiNcIi5gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJldHVybiB0byBhdm9pZCBvdGhlciB3YXJuaW5nc1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgd2FybihgVGhlIHNlbGVjdG9yIFwiJHtwb3NpdGlvbi5lbH1cIiBpcyBpbnZhbGlkLiBJZiB5b3UgYXJlIHVzaW5nIGFuIGlkIHNlbGVjdG9yLCBtYWtlIHN1cmUgdG8gZXNjYXBlIGl0LiBZb3UgY2FuIGZpbmQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBlc2NhcGluZyBjaGFyYWN0ZXJzIGluIHNlbGVjdG9ycyBhdCBodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvY3NzLWVzY2FwZXMgb3IgdXNlIENTUy5lc2NhcGUgKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DU1MvZXNjYXBlKS5gKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJuIHRvIGF2b2lkIG90aGVyIHdhcm5pbmdzXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZWwgPSB0eXBlb2YgcG9zaXRpb25FbCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgID8gaXNJZFNlbGVjdG9yXG4gICAgICAgICAgICAgICAgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwb3NpdGlvbkVsLnNsaWNlKDEpKVxuICAgICAgICAgICAgICAgIDogZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihwb3NpdGlvbkVsKVxuICAgICAgICAgICAgOiBwb3NpdGlvbkVsO1xuICAgICAgICBpZiAoIWVsKSB7XG4gICAgICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiZcbiAgICAgICAgICAgICAgICB3YXJuKGBDb3VsZG4ndCBmaW5kIGVsZW1lbnQgdXNpbmcgc2VsZWN0b3IgXCIke3Bvc2l0aW9uLmVsfVwiIHJldHVybmVkIGJ5IHNjcm9sbEJlaGF2aW9yLmApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHNjcm9sbFRvT3B0aW9ucyA9IGdldEVsZW1lbnRQb3NpdGlvbihlbCwgcG9zaXRpb24pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2Nyb2xsVG9PcHRpb25zID0gcG9zaXRpb247XG4gICAgfVxuICAgIGlmICgnc2Nyb2xsQmVoYXZpb3InIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZSlcbiAgICAgICAgd2luZG93LnNjcm9sbFRvKHNjcm9sbFRvT3B0aW9ucyk7XG4gICAgZWxzZSB7XG4gICAgICAgIHdpbmRvdy5zY3JvbGxUbyhzY3JvbGxUb09wdGlvbnMubGVmdCAhPSBudWxsID8gc2Nyb2xsVG9PcHRpb25zLmxlZnQgOiB3aW5kb3cuc2Nyb2xsWCwgc2Nyb2xsVG9PcHRpb25zLnRvcCAhPSBudWxsID8gc2Nyb2xsVG9PcHRpb25zLnRvcCA6IHdpbmRvdy5zY3JvbGxZKTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRTY3JvbGxLZXkocGF0aCwgZGVsdGEpIHtcbiAgICBjb25zdCBwb3NpdGlvbiA9IGhpc3Rvcnkuc3RhdGUgPyBoaXN0b3J5LnN0YXRlLnBvc2l0aW9uIC0gZGVsdGEgOiAtMTtcbiAgICByZXR1cm4gcG9zaXRpb24gKyBwYXRoO1xufVxuY29uc3Qgc2Nyb2xsUG9zaXRpb25zID0gbmV3IE1hcCgpO1xuZnVuY3Rpb24gc2F2ZVNjcm9sbFBvc2l0aW9uKGtleSwgc2Nyb2xsUG9zaXRpb24pIHtcbiAgICBzY3JvbGxQb3NpdGlvbnMuc2V0KGtleSwgc2Nyb2xsUG9zaXRpb24pO1xufVxuZnVuY3Rpb24gZ2V0U2F2ZWRTY3JvbGxQb3NpdGlvbihrZXkpIHtcbiAgICBjb25zdCBzY3JvbGwgPSBzY3JvbGxQb3NpdGlvbnMuZ2V0KGtleSk7XG4gICAgLy8gY29uc3VtZSBpdCBzbyBpdCdzIG5vdCB1c2VkIGFnYWluXG4gICAgc2Nyb2xsUG9zaXRpb25zLmRlbGV0ZShrZXkpO1xuICAgIHJldHVybiBzY3JvbGw7XG59XG4vLyBUT0RPOiBSRkMgYWJvdXQgaG93IHRvIHNhdmUgc2Nyb2xsIHBvc2l0aW9uXG4vKipcbiAqIFNjcm9sbEJlaGF2aW9yIGluc3RhbmNlIHVzZWQgYnkgdGhlIHJvdXRlciB0byBjb21wdXRlIGFuZCByZXN0b3JlIHRoZSBzY3JvbGxcbiAqIHBvc2l0aW9uIHdoZW4gbmF2aWdhdGluZy5cbiAqL1xuLy8gZXhwb3J0IGludGVyZmFjZSBTY3JvbGxIYW5kbGVyPFNjcm9sbFBvc2l0aW9uRW50cnkgZXh0ZW5kcyBIaXN0b3J5U3RhdGVWYWx1ZSwgU2Nyb2xsUG9zaXRpb24gZXh0ZW5kcyBTY3JvbGxQb3NpdGlvbkVudHJ5PiB7XG4vLyAgIC8vIHJldHVybnMgYSBzY3JvbGwgcG9zaXRpb24gdGhhdCBjYW4gYmUgc2F2ZWQgaW4gaGlzdG9yeVxuLy8gICBjb21wdXRlKCk6IFNjcm9sbFBvc2l0aW9uRW50cnlcbi8vICAgLy8gY2FuIHRha2UgYW4gZXh0ZW5kZWQgU2Nyb2xsUG9zaXRpb25FbnRyeVxuLy8gICBzY3JvbGwocG9zaXRpb246IFNjcm9sbFBvc2l0aW9uKTogdm9pZFxuLy8gfVxuLy8gZXhwb3J0IGNvbnN0IHNjcm9sbEhhbmRsZXI6IFNjcm9sbEhhbmRsZXI8U2Nyb2xsUG9zaXRpb24+ID0ge1xuLy8gICBjb21wdXRlOiBjb21wdXRlU2Nyb2xsLFxuLy8gICBzY3JvbGw6IHNjcm9sbFRvUG9zaXRpb24sXG4vLyB9XG5cbmxldCBjcmVhdGVCYXNlTG9jYXRpb24gPSAoKSA9PiBsb2NhdGlvbi5wcm90b2NvbCArICcvLycgKyBsb2NhdGlvbi5ob3N0O1xuLyoqXG4gKiBDcmVhdGVzIGEgbm9ybWFsaXplZCBoaXN0b3J5IGxvY2F0aW9uIGZyb20gYSB3aW5kb3cubG9jYXRpb24gb2JqZWN0XG4gKiBAcGFyYW0gYmFzZSAtIFRoZSBiYXNlIHBhdGhcbiAqIEBwYXJhbSBsb2NhdGlvbiAtIFRoZSB3aW5kb3cubG9jYXRpb24gb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUN1cnJlbnRMb2NhdGlvbihiYXNlLCBsb2NhdGlvbikge1xuICAgIGNvbnN0IHsgcGF0aG5hbWUsIHNlYXJjaCwgaGFzaCB9ID0gbG9jYXRpb247XG4gICAgLy8gYWxsb3dzIGhhc2ggYmFzZXMgbGlrZSAjLCAvIywgIy8sICMhLCAjIS8sIC8jIS8sIG9yIGV2ZW4gL2ZvbGRlciNlbmRcbiAgICBjb25zdCBoYXNoUG9zID0gYmFzZS5pbmRleE9mKCcjJyk7XG4gICAgaWYgKGhhc2hQb3MgPiAtMSkge1xuICAgICAgICBsZXQgc2xpY2VQb3MgPSBoYXNoLmluY2x1ZGVzKGJhc2Uuc2xpY2UoaGFzaFBvcykpXG4gICAgICAgICAgICA/IGJhc2Uuc2xpY2UoaGFzaFBvcykubGVuZ3RoXG4gICAgICAgICAgICA6IDE7XG4gICAgICAgIGxldCBwYXRoRnJvbUhhc2ggPSBoYXNoLnNsaWNlKHNsaWNlUG9zKTtcbiAgICAgICAgLy8gcHJlcGVuZCB0aGUgc3RhcnRpbmcgc2xhc2ggdG8gaGFzaCBzbyB0aGUgdXJsIHN0YXJ0cyB3aXRoIC8jXG4gICAgICAgIGlmIChwYXRoRnJvbUhhc2hbMF0gIT09ICcvJylcbiAgICAgICAgICAgIHBhdGhGcm9tSGFzaCA9ICcvJyArIHBhdGhGcm9tSGFzaDtcbiAgICAgICAgcmV0dXJuIHN0cmlwQmFzZShwYXRoRnJvbUhhc2gsICcnKTtcbiAgICB9XG4gICAgY29uc3QgcGF0aCA9IHN0cmlwQmFzZShwYXRobmFtZSwgYmFzZSk7XG4gICAgcmV0dXJuIHBhdGggKyBzZWFyY2ggKyBoYXNoO1xufVxuZnVuY3Rpb24gdXNlSGlzdG9yeUxpc3RlbmVycyhiYXNlLCBoaXN0b3J5U3RhdGUsIGN1cnJlbnRMb2NhdGlvbiwgcmVwbGFjZSkge1xuICAgIGxldCBsaXN0ZW5lcnMgPSBbXTtcbiAgICBsZXQgdGVhcmRvd25zID0gW107XG4gICAgLy8gVE9ETzogc2hvdWxkIGl0IGJlIGEgc3RhY2s/IGEgRGljdC4gQ2hlY2sgaWYgdGhlIHBvcHN0YXRlIGxpc3RlbmVyXG4gICAgLy8gY2FuIHRyaWdnZXIgdHdpY2VcbiAgICBsZXQgcGF1c2VTdGF0ZSA9IG51bGw7XG4gICAgY29uc3QgcG9wU3RhdGVIYW5kbGVyID0gKHsgc3RhdGUsIH0pID0+IHtcbiAgICAgICAgY29uc3QgdG8gPSBjcmVhdGVDdXJyZW50TG9jYXRpb24oYmFzZSwgbG9jYXRpb24pO1xuICAgICAgICBjb25zdCBmcm9tID0gY3VycmVudExvY2F0aW9uLnZhbHVlO1xuICAgICAgICBjb25zdCBmcm9tU3RhdGUgPSBoaXN0b3J5U3RhdGUudmFsdWU7XG4gICAgICAgIGxldCBkZWx0YSA9IDA7XG4gICAgICAgIGlmIChzdGF0ZSkge1xuICAgICAgICAgICAgY3VycmVudExvY2F0aW9uLnZhbHVlID0gdG87XG4gICAgICAgICAgICBoaXN0b3J5U3RhdGUudmFsdWUgPSBzdGF0ZTtcbiAgICAgICAgICAgIC8vIGlnbm9yZSB0aGUgcG9wc3RhdGUgYW5kIHJlc2V0IHRoZSBwYXVzZVN0YXRlXG4gICAgICAgICAgICBpZiAocGF1c2VTdGF0ZSAmJiBwYXVzZVN0YXRlID09PSBmcm9tKSB7XG4gICAgICAgICAgICAgICAgcGF1c2VTdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsdGEgPSBmcm9tU3RhdGUgPyBzdGF0ZS5wb3NpdGlvbiAtIGZyb21TdGF0ZS5wb3NpdGlvbiA6IDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXBsYWNlKHRvKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBIZXJlIHdlIGNvdWxkIGFsc28gcmV2ZXJ0IHRoZSBuYXZpZ2F0aW9uIGJ5IGNhbGxpbmcgaGlzdG9yeS5nbygtZGVsdGEpXG4gICAgICAgIC8vIHRoaXMgbGlzdGVuZXIgd2lsbCBoYXZlIHRvIGJlIGFkYXB0ZWQgdG8gbm90IHRyaWdnZXIgYWdhaW4gYW5kIHRvIHdhaXQgZm9yIHRoZSB1cmxcbiAgICAgICAgLy8gdG8gYmUgdXBkYXRlZCBiZWZvcmUgdHJpZ2dlcmluZyB0aGUgbGlzdGVuZXJzLiBTb21lIGtpbmQgb2YgdmFsaWRhdGlvbiBmdW5jdGlvbiB3b3VsZCBhbHNvXG4gICAgICAgIC8vIG5lZWQgdG8gYmUgcGFzc2VkIHRvIHRoZSBsaXN0ZW5lcnMgc28gdGhlIG5hdmlnYXRpb24gY2FuIGJlIGFjY2VwdGVkXG4gICAgICAgIC8vIGNhbGwgYWxsIGxpc3RlbmVyc1xuICAgICAgICBsaXN0ZW5lcnMuZm9yRWFjaChsaXN0ZW5lciA9PiB7XG4gICAgICAgICAgICBsaXN0ZW5lcihjdXJyZW50TG9jYXRpb24udmFsdWUsIGZyb20sIHtcbiAgICAgICAgICAgICAgICBkZWx0YSxcbiAgICAgICAgICAgICAgICB0eXBlOiBOYXZpZ2F0aW9uVHlwZS5wb3AsXG4gICAgICAgICAgICAgICAgZGlyZWN0aW9uOiBkZWx0YVxuICAgICAgICAgICAgICAgICAgICA/IGRlbHRhID4gMFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBOYXZpZ2F0aW9uRGlyZWN0aW9uLmZvcndhcmRcbiAgICAgICAgICAgICAgICAgICAgICAgIDogTmF2aWdhdGlvbkRpcmVjdGlvbi5iYWNrXG4gICAgICAgICAgICAgICAgICAgIDogTmF2aWdhdGlvbkRpcmVjdGlvbi51bmtub3duLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgZnVuY3Rpb24gcGF1c2VMaXN0ZW5lcnMoKSB7XG4gICAgICAgIHBhdXNlU3RhdGUgPSBjdXJyZW50TG9jYXRpb24udmFsdWU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGxpc3RlbihjYWxsYmFjaykge1xuICAgICAgICAvLyBzZXQgdXAgdGhlIGxpc3RlbmVyIGFuZCBwcmVwYXJlIHRlYXJkb3duIGNhbGxiYWNrc1xuICAgICAgICBsaXN0ZW5lcnMucHVzaChjYWxsYmFjayk7XG4gICAgICAgIGNvbnN0IHRlYXJkb3duID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBsaXN0ZW5lcnMuaW5kZXhPZihjYWxsYmFjayk7XG4gICAgICAgICAgICBpZiAoaW5kZXggPiAtMSlcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGVhcmRvd25zLnB1c2godGVhcmRvd24pO1xuICAgICAgICByZXR1cm4gdGVhcmRvd247XG4gICAgfVxuICAgIGZ1bmN0aW9uIGJlZm9yZVVubG9hZExpc3RlbmVyKCkge1xuICAgICAgICBjb25zdCB7IGhpc3RvcnkgfSA9IHdpbmRvdztcbiAgICAgICAgaWYgKCFoaXN0b3J5LnN0YXRlKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBoaXN0b3J5LnJlcGxhY2VTdGF0ZShhc3NpZ24oe30sIGhpc3Rvcnkuc3RhdGUsIHsgc2Nyb2xsOiBjb21wdXRlU2Nyb2xsUG9zaXRpb24oKSB9KSwgJycpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgICAgICBmb3IgKGNvbnN0IHRlYXJkb3duIG9mIHRlYXJkb3ducylcbiAgICAgICAgICAgIHRlYXJkb3duKCk7XG4gICAgICAgIHRlYXJkb3ducyA9IFtdO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBwb3BTdGF0ZUhhbmRsZXIpO1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgYmVmb3JlVW5sb2FkTGlzdGVuZXIpO1xuICAgIH1cbiAgICAvLyBzZXQgdXAgdGhlIGxpc3RlbmVycyBhbmQgcHJlcGFyZSB0ZWFyZG93biBjYWxsYmFja3NcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBwb3BTdGF0ZUhhbmRsZXIpO1xuICAgIC8vIFRPRE86IGNvdWxkIHdlIHVzZSAncGFnZWhpZGUnIG9yICd2aXNpYmlsaXR5Y2hhbmdlJyBpbnN0ZWFkP1xuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLmNocm9tZS5jb20vYmxvZy9wYWdlLWxpZmVjeWNsZS1hcGkvXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2JlZm9yZXVubG9hZCcsIGJlZm9yZVVubG9hZExpc3RlbmVyLCB7XG4gICAgICAgIHBhc3NpdmU6IHRydWUsXG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcGF1c2VMaXN0ZW5lcnMsXG4gICAgICAgIGxpc3RlbixcbiAgICAgICAgZGVzdHJveSxcbiAgICB9O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgc3RhdGUgb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIGJ1aWxkU3RhdGUoYmFjaywgY3VycmVudCwgZm9yd2FyZCwgcmVwbGFjZWQgPSBmYWxzZSwgY29tcHV0ZVNjcm9sbCA9IGZhbHNlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYmFjayxcbiAgICAgICAgY3VycmVudCxcbiAgICAgICAgZm9yd2FyZCxcbiAgICAgICAgcmVwbGFjZWQsXG4gICAgICAgIHBvc2l0aW9uOiB3aW5kb3cuaGlzdG9yeS5sZW5ndGgsXG4gICAgICAgIHNjcm9sbDogY29tcHV0ZVNjcm9sbCA/IGNvbXB1dGVTY3JvbGxQb3NpdGlvbigpIDogbnVsbCxcbiAgICB9O1xufVxuZnVuY3Rpb24gdXNlSGlzdG9yeVN0YXRlTmF2aWdhdGlvbihiYXNlKSB7XG4gICAgY29uc3QgeyBoaXN0b3J5LCBsb2NhdGlvbiB9ID0gd2luZG93O1xuICAgIC8vIHByaXZhdGUgdmFyaWFibGVzXG4gICAgY29uc3QgY3VycmVudExvY2F0aW9uID0ge1xuICAgICAgICB2YWx1ZTogY3JlYXRlQ3VycmVudExvY2F0aW9uKGJhc2UsIGxvY2F0aW9uKSxcbiAgICB9O1xuICAgIGNvbnN0IGhpc3RvcnlTdGF0ZSA9IHsgdmFsdWU6IGhpc3Rvcnkuc3RhdGUgfTtcbiAgICAvLyBidWlsZCBjdXJyZW50IGhpc3RvcnkgZW50cnkgYXMgdGhpcyBpcyBhIGZyZXNoIG5hdmlnYXRpb25cbiAgICBpZiAoIWhpc3RvcnlTdGF0ZS52YWx1ZSkge1xuICAgICAgICBjaGFuZ2VMb2NhdGlvbihjdXJyZW50TG9jYXRpb24udmFsdWUsIHtcbiAgICAgICAgICAgIGJhY2s6IG51bGwsXG4gICAgICAgICAgICBjdXJyZW50OiBjdXJyZW50TG9jYXRpb24udmFsdWUsXG4gICAgICAgICAgICBmb3J3YXJkOiBudWxsLFxuICAgICAgICAgICAgLy8gdGhlIGxlbmd0aCBpcyBvZmYgYnkgb25lLCB3ZSBuZWVkIHRvIGRlY3JlYXNlIGl0XG4gICAgICAgICAgICBwb3NpdGlvbjogaGlzdG9yeS5sZW5ndGggLSAxLFxuICAgICAgICAgICAgcmVwbGFjZWQ6IHRydWUsXG4gICAgICAgICAgICAvLyBkb24ndCBhZGQgYSBzY3JvbGwgYXMgdGhlIHVzZXIgbWF5IGhhdmUgYW4gYW5jaG9yLCBhbmQgd2Ugd2FudFxuICAgICAgICAgICAgLy8gc2Nyb2xsQmVoYXZpb3IgdG8gYmUgdHJpZ2dlcmVkIHdpdGhvdXQgYSBzYXZlZCBwb3NpdGlvblxuICAgICAgICAgICAgc2Nyb2xsOiBudWxsLFxuICAgICAgICB9LCB0cnVlKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2hhbmdlTG9jYXRpb24odG8sIHN0YXRlLCByZXBsYWNlKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBpZiBhIGJhc2UgdGFnIGlzIHByb3ZpZGVkLCBhbmQgd2UgYXJlIG9uIGEgbm9ybWFsIGRvbWFpbiwgd2UgaGF2ZSB0b1xuICAgICAgICAgKiByZXNwZWN0IHRoZSBwcm92aWRlZCBgYmFzZWAgYXR0cmlidXRlIGJlY2F1c2UgcHVzaFN0YXRlKCkgd2lsbCB1c2UgaXQgYW5kXG4gICAgICAgICAqIHBvdGVudGlhbGx5IGVyYXNlIGFueXRoaW5nIGJlZm9yZSB0aGUgYCNgIGxpa2UgYXRcbiAgICAgICAgICogaHR0cHM6Ly9naXRodWIuY29tL3Z1ZWpzL3JvdXRlci9pc3N1ZXMvNjg1IHdoZXJlIGEgYmFzZSBvZlxuICAgICAgICAgKiBgL2ZvbGRlci8jYCBidXQgYSBiYXNlIG9mIGAvYCB3b3VsZCBlcmFzZSB0aGUgYC9mb2xkZXIvYCBzZWN0aW9uLiBJZlxuICAgICAgICAgKiB0aGVyZSBpcyBubyBob3N0LCB0aGUgYDxiYXNlPmAgdGFnIG1ha2VzIG5vIHNlbnNlIGFuZCBpZiB0aGVyZSBpc24ndCBhXG4gICAgICAgICAqIGJhc2UgdGFnIHdlIGNhbiBqdXN0IHVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBgI2AuXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBoYXNoSW5kZXggPSBiYXNlLmluZGV4T2YoJyMnKTtcbiAgICAgICAgY29uc3QgdXJsID0gaGFzaEluZGV4ID4gLTFcbiAgICAgICAgICAgID8gKGxvY2F0aW9uLmhvc3QgJiYgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYmFzZScpXG4gICAgICAgICAgICAgICAgPyBiYXNlXG4gICAgICAgICAgICAgICAgOiBiYXNlLnNsaWNlKGhhc2hJbmRleCkpICsgdG9cbiAgICAgICAgICAgIDogY3JlYXRlQmFzZUxvY2F0aW9uKCkgKyBiYXNlICsgdG87XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBCUk9XU0VSIFFVSVJLXG4gICAgICAgICAgICAvLyBOT1RFOiBTYWZhcmkgdGhyb3dzIGEgU2VjdXJpdHlFcnJvciB3aGVuIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiAxMDAgdGltZXMgaW4gMzAgc2Vjb25kc1xuICAgICAgICAgICAgaGlzdG9yeVtyZXBsYWNlID8gJ3JlcGxhY2VTdGF0ZScgOiAncHVzaFN0YXRlJ10oc3RhdGUsICcnLCB1cmwpO1xuICAgICAgICAgICAgaGlzdG9yeVN0YXRlLnZhbHVlID0gc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xuICAgICAgICAgICAgICAgIHdhcm4oJ0Vycm9yIHdpdGggcHVzaC9yZXBsYWNlIFN0YXRlJywgZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEZvcmNlIHRoZSBuYXZpZ2F0aW9uLCB0aGlzIGFsc28gcmVzZXRzIHRoZSBjYWxsIGNvdW50XG4gICAgICAgICAgICBsb2NhdGlvbltyZXBsYWNlID8gJ3JlcGxhY2UnIDogJ2Fzc2lnbiddKHVybCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZnVuY3Rpb24gcmVwbGFjZSh0bywgZGF0YSkge1xuICAgICAgICBjb25zdCBzdGF0ZSA9IGFzc2lnbih7fSwgaGlzdG9yeS5zdGF0ZSwgYnVpbGRTdGF0ZShoaXN0b3J5U3RhdGUudmFsdWUuYmFjaywgXG4gICAgICAgIC8vIGtlZXAgYmFjayBhbmQgZm9yd2FyZCBlbnRyaWVzIGJ1dCBvdmVycmlkZSBjdXJyZW50IHBvc2l0aW9uXG4gICAgICAgIHRvLCBoaXN0b3J5U3RhdGUudmFsdWUuZm9yd2FyZCwgdHJ1ZSksIGRhdGEsIHsgcG9zaXRpb246IGhpc3RvcnlTdGF0ZS52YWx1ZS5wb3NpdGlvbiB9KTtcbiAgICAgICAgY2hhbmdlTG9jYXRpb24odG8sIHN0YXRlLCB0cnVlKTtcbiAgICAgICAgY3VycmVudExvY2F0aW9uLnZhbHVlID0gdG87XG4gICAgfVxuICAgIGZ1bmN0aW9uIHB1c2godG8sIGRhdGEpIHtcbiAgICAgICAgLy8gQWRkIHRvIGN1cnJlbnQgZW50cnkgdGhlIGluZm9ybWF0aW9uIG9mIHdoZXJlIHdlIGFyZSBnb2luZ1xuICAgICAgICAvLyBhcyB3ZWxsIGFzIHNhdmluZyB0aGUgY3VycmVudCBwb3NpdGlvblxuICAgICAgICBjb25zdCBjdXJyZW50U3RhdGUgPSBhc3NpZ24oe30sIFxuICAgICAgICAvLyB1c2UgY3VycmVudCBoaXN0b3J5IHN0YXRlIHRvIGdyYWNlZnVsbHkgaGFuZGxlIGEgd3JvbmcgY2FsbCB0b1xuICAgICAgICAvLyBoaXN0b3J5LnJlcGxhY2VTdGF0ZVxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vdnVlanMvcm91dGVyL2lzc3Vlcy8zNjZcbiAgICAgICAgaGlzdG9yeVN0YXRlLnZhbHVlLCBoaXN0b3J5LnN0YXRlLCB7XG4gICAgICAgICAgICBmb3J3YXJkOiB0byxcbiAgICAgICAgICAgIHNjcm9sbDogY29tcHV0ZVNjcm9sbFBvc2l0aW9uKCksXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFoaXN0b3J5LnN0YXRlKSB7XG4gICAgICAgICAgICB3YXJuKGBoaXN0b3J5LnN0YXRlIHNlZW1zIHRvIGhhdmUgYmVlbiBtYW51YWxseSByZXBsYWNlZCB3aXRob3V0IHByZXNlcnZpbmcgdGhlIG5lY2Vzc2FyeSB2YWx1ZXMuIE1ha2Ugc3VyZSB0byBwcmVzZXJ2ZSBleGlzdGluZyBoaXN0b3J5IHN0YXRlIGlmIHlvdSBhcmUgbWFudWFsbHkgY2FsbGluZyBoaXN0b3J5LnJlcGxhY2VTdGF0ZTpcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgaGlzdG9yeS5yZXBsYWNlU3RhdGUoaGlzdG9yeS5zdGF0ZSwgJycsIHVybClcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgWW91IGNhbiBmaW5kIG1vcmUgaW5mb3JtYXRpb24gYXQgaHR0cHM6Ly9yb3V0ZXIudnVlanMub3JnL2d1aWRlL21pZ3JhdGlvbi8jVXNhZ2Utb2YtaGlzdG9yeS1zdGF0ZWApO1xuICAgICAgICB9XG4gICAgICAgIGNoYW5nZUxvY2F0aW9uKGN1cnJlbnRTdGF0ZS5jdXJyZW50LCBjdXJyZW50U3RhdGUsIHRydWUpO1xuICAgICAgICBjb25zdCBzdGF0ZSA9IGFzc2lnbih7fSwgYnVpbGRTdGF0ZShjdXJyZW50TG9jYXRpb24udmFsdWUsIHRvLCBudWxsKSwgeyBwb3NpdGlvbjogY3VycmVudFN0YXRlLnBvc2l0aW9uICsgMSB9LCBkYXRhKTtcbiAgICAgICAgY2hhbmdlTG9jYXRpb24odG8sIHN0YXRlLCBmYWxzZSk7XG4gICAgICAgIGN1cnJlbnRMb2NhdGlvbi52YWx1ZSA9IHRvO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBsb2NhdGlvbjogY3VycmVudExvY2F0aW9uLFxuICAgICAgICBzdGF0ZTogaGlzdG9yeVN0YXRlLFxuICAgICAgICBwdXNoLFxuICAgICAgICByZXBsYWNlLFxuICAgIH07XG59XG4vKipcbiAqIENyZWF0ZXMgYW4gSFRNTDUgaGlzdG9yeS4gTW9zdCBjb21tb24gaGlzdG9yeSBmb3Igc2luZ2xlIHBhZ2UgYXBwbGljYXRpb25zLlxuICpcbiAqIEBwYXJhbSBiYXNlIC1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlV2ViSGlzdG9yeShiYXNlKSB7XG4gICAgYmFzZSA9IG5vcm1hbGl6ZUJhc2UoYmFzZSk7XG4gICAgY29uc3QgaGlzdG9yeU5hdmlnYXRpb24gPSB1c2VIaXN0b3J5U3RhdGVOYXZpZ2F0aW9uKGJhc2UpO1xuICAgIGNvbnN0IGhpc3RvcnlMaXN0ZW5lcnMgPSB1c2VIaXN0b3J5TGlzdGVuZXJzKGJhc2UsIGhpc3RvcnlOYXZpZ2F0aW9uLnN0YXRlLCBoaXN0b3J5TmF2aWdhdGlvbi5sb2NhdGlvbiwgaGlzdG9yeU5hdmlnYXRpb24ucmVwbGFjZSk7XG4gICAgZnVuY3Rpb24gZ28oZGVsdGEsIHRyaWdnZXJMaXN0ZW5lcnMgPSB0cnVlKSB7XG4gICAgICAgIGlmICghdHJpZ2dlckxpc3RlbmVycylcbiAgICAgICAgICAgIGhpc3RvcnlMaXN0ZW5lcnMucGF1c2VMaXN0ZW5lcnMoKTtcbiAgICAgICAgaGlzdG9yeS5nbyhkZWx0YSk7XG4gICAgfVxuICAgIGNvbnN0IHJvdXRlckhpc3RvcnkgPSBhc3NpZ24oe1xuICAgICAgICAvLyBpdCdzIG92ZXJyaWRkZW4gcmlnaHQgYWZ0ZXJcbiAgICAgICAgbG9jYXRpb246ICcnLFxuICAgICAgICBiYXNlLFxuICAgICAgICBnbyxcbiAgICAgICAgY3JlYXRlSHJlZjogY3JlYXRlSHJlZi5iaW5kKG51bGwsIGJhc2UpLFxuICAgIH0sIGhpc3RvcnlOYXZpZ2F0aW9uLCBoaXN0b3J5TGlzdGVuZXJzKTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocm91dGVySGlzdG9yeSwgJ2xvY2F0aW9uJywge1xuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBnZXQ6ICgpID0+IGhpc3RvcnlOYXZpZ2F0aW9uLmxvY2F0aW9uLnZhbHVlLFxuICAgIH0pO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyb3V0ZXJIaXN0b3J5LCAnc3RhdGUnLCB7XG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGdldDogKCkgPT4gaGlzdG9yeU5hdmlnYXRpb24uc3RhdGUudmFsdWUsXG4gICAgfSk7XG4gICAgcmV0dXJuIHJvdXRlckhpc3Rvcnk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBpbi1tZW1vcnkgYmFzZWQgaGlzdG9yeS4gVGhlIG1haW4gcHVycG9zZSBvZiB0aGlzIGhpc3RvcnkgaXMgdG8gaGFuZGxlIFNTUi4gSXQgc3RhcnRzIGluIGEgc3BlY2lhbCBsb2NhdGlvbiB0aGF0IGlzIG5vd2hlcmUuXG4gKiBJdCdzIHVwIHRvIHRoZSB1c2VyIHRvIHJlcGxhY2UgdGhhdCBsb2NhdGlvbiB3aXRoIHRoZSBzdGFydGVyIGxvY2F0aW9uIGJ5IGVpdGhlciBjYWxsaW5nIGByb3V0ZXIucHVzaGAgb3IgYHJvdXRlci5yZXBsYWNlYC5cbiAqXG4gKiBAcGFyYW0gYmFzZSAtIEJhc2UgYXBwbGllZCB0byBhbGwgdXJscywgZGVmYXVsdHMgdG8gJy8nXG4gKiBAcmV0dXJucyBhIGhpc3Rvcnkgb2JqZWN0IHRoYXQgY2FuIGJlIHBhc3NlZCB0byB0aGUgcm91dGVyIGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZU1lbW9yeUhpc3RvcnkoYmFzZSA9ICcnKSB7XG4gICAgbGV0IGxpc3RlbmVycyA9IFtdO1xuICAgIGxldCBxdWV1ZSA9IFtbU1RBUlQsIHt9XV07XG4gICAgbGV0IHBvc2l0aW9uID0gMDtcbiAgICBiYXNlID0gbm9ybWFsaXplQmFzZShiYXNlKTtcbiAgICBmdW5jdGlvbiBzZXRMb2NhdGlvbihsb2NhdGlvbiwgc3RhdGUgPSB7fSkge1xuICAgICAgICBwb3NpdGlvbisrO1xuICAgICAgICBpZiAocG9zaXRpb24gIT09IHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gd2UgYXJlIGluIHRoZSBtaWRkbGUsIHdlIHJlbW92ZSBldmVyeXRoaW5nIGZyb20gaGVyZSBpbiB0aGUgcXVldWVcbiAgICAgICAgICAgIHF1ZXVlLnNwbGljZShwb3NpdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgcXVldWUucHVzaChbbG9jYXRpb24sIHN0YXRlXSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHRyaWdnZXJMaXN0ZW5lcnModG8sIGZyb20sIHsgZGlyZWN0aW9uLCBkZWx0YSB9KSB7XG4gICAgICAgIGNvbnN0IGluZm8gPSB7XG4gICAgICAgICAgICBkaXJlY3Rpb24sXG4gICAgICAgICAgICBkZWx0YSxcbiAgICAgICAgICAgIHR5cGU6IE5hdmlnYXRpb25UeXBlLnBvcCxcbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChjb25zdCBjYWxsYmFjayBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKHRvLCBmcm9tLCBpbmZvKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCByb3V0ZXJIaXN0b3J5ID0ge1xuICAgICAgICAvLyByZXdyaXR0ZW4gYnkgT2JqZWN0LmRlZmluZVByb3BlcnR5XG4gICAgICAgIGxvY2F0aW9uOiBTVEFSVCxcbiAgICAgICAgLy8gcmV3cml0dGVuIGJ5IE9iamVjdC5kZWZpbmVQcm9wZXJ0eVxuICAgICAgICBzdGF0ZToge30sXG4gICAgICAgIGJhc2UsXG4gICAgICAgIGNyZWF0ZUhyZWY6IGNyZWF0ZUhyZWYuYmluZChudWxsLCBiYXNlKSxcbiAgICAgICAgcmVwbGFjZSh0bywgc3RhdGUpIHtcbiAgICAgICAgICAgIC8vIHJlbW92ZSBjdXJyZW50IGVudHJ5IGFuZCBkZWNyZW1lbnQgcG9zaXRpb25cbiAgICAgICAgICAgIHF1ZXVlLnNwbGljZShwb3NpdGlvbi0tLCAxKTtcbiAgICAgICAgICAgIHNldExvY2F0aW9uKHRvLCBzdGF0ZSk7XG4gICAgICAgIH0sXG4gICAgICAgIHB1c2godG8sIHN0YXRlKSB7XG4gICAgICAgICAgICBzZXRMb2NhdGlvbih0bywgc3RhdGUpO1xuICAgICAgICB9LFxuICAgICAgICBsaXN0ZW4oY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGxpc3RlbmVycy5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBsaXN0ZW5lcnMuaW5kZXhPZihjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpXG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgZGVzdHJveSgpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IFtdO1xuICAgICAgICAgICAgcXVldWUgPSBbW1NUQVJULCB7fV1dO1xuICAgICAgICAgICAgcG9zaXRpb24gPSAwO1xuICAgICAgICB9LFxuICAgICAgICBnbyhkZWx0YSwgc2hvdWxkVHJpZ2dlciA9IHRydWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGZyb20gPSB0aGlzLmxvY2F0aW9uO1xuICAgICAgICAgICAgY29uc3QgZGlyZWN0aW9uID0gXG4gICAgICAgICAgICAvLyB3ZSBhcmUgY29uc2lkZXJpbmcgZGVsdGEgPT09IDAgZ29pbmcgZm9yd2FyZCwgYnV0IGluIGFic3RyYWN0IG1vZGVcbiAgICAgICAgICAgIC8vIHVzaW5nIDAgZm9yIHRoZSBkZWx0YSBkb2Vzbid0IG1ha2Ugc2Vuc2UgbGlrZSBpdCBkb2VzIGluIGh0bWw1IHdoZXJlXG4gICAgICAgICAgICAvLyBpdCByZWxvYWRzIHRoZSBwYWdlXG4gICAgICAgICAgICBkZWx0YSA8IDAgPyBOYXZpZ2F0aW9uRGlyZWN0aW9uLmJhY2sgOiBOYXZpZ2F0aW9uRGlyZWN0aW9uLmZvcndhcmQ7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IE1hdGgubWF4KDAsIE1hdGgubWluKHBvc2l0aW9uICsgZGVsdGEsIHF1ZXVlLmxlbmd0aCAtIDEpKTtcbiAgICAgICAgICAgIGlmIChzaG91bGRUcmlnZ2VyKSB7XG4gICAgICAgICAgICAgICAgdHJpZ2dlckxpc3RlbmVycyh0aGlzLmxvY2F0aW9uLCBmcm9tLCB7XG4gICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGVsdGEsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgfTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocm91dGVySGlzdG9yeSwgJ2xvY2F0aW9uJywge1xuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBnZXQ6ICgpID0+IHF1ZXVlW3Bvc2l0aW9uXVswXSxcbiAgICB9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocm91dGVySGlzdG9yeSwgJ3N0YXRlJywge1xuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBnZXQ6ICgpID0+IHF1ZXVlW3Bvc2l0aW9uXVsxXSxcbiAgICB9KTtcbiAgICByZXR1cm4gcm91dGVySGlzdG9yeTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgaGFzaCBoaXN0b3J5LiBVc2VmdWwgZm9yIHdlYiBhcHBsaWNhdGlvbnMgd2l0aCBubyBob3N0IChlLmcuIGBmaWxlOi8vYCkgb3Igd2hlbiBjb25maWd1cmluZyBhIHNlcnZlciB0b1xuICogaGFuZGxlIGFueSBVUkwgaXMgbm90IHBvc3NpYmxlLlxuICpcbiAqIEBwYXJhbSBiYXNlIC0gb3B0aW9uYWwgYmFzZSB0byBwcm92aWRlLiBEZWZhdWx0cyB0byBgbG9jYXRpb24ucGF0aG5hbWUgKyBsb2NhdGlvbi5zZWFyY2hgIElmIHRoZXJlIGlzIGEgYDxiYXNlPmAgdGFnXG4gKiBpbiB0aGUgYGhlYWRgLCBpdHMgdmFsdWUgd2lsbCBiZSBpZ25vcmVkIGluIGZhdm9yIG9mIHRoaXMgcGFyYW1ldGVyICoqYnV0IG5vdGUgaXQgYWZmZWN0cyBhbGwgdGhlIGhpc3RvcnkucHVzaFN0YXRlKClcbiAqIGNhbGxzKiosIG1lYW5pbmcgdGhhdCBpZiB5b3UgdXNlIGEgYDxiYXNlPmAgdGFnLCBpdCdzIGBocmVmYCB2YWx1ZSAqKmhhcyB0byBtYXRjaCB0aGlzIHBhcmFtZXRlcioqIChpZ25vcmluZyBhbnl0aGluZ1xuICogYWZ0ZXIgdGhlIGAjYCkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGpzXG4gKiAvLyBhdCBodHRwczovL2V4YW1wbGUuY29tL2ZvbGRlclxuICogY3JlYXRlV2ViSGFzaEhpc3RvcnkoKSAvLyBnaXZlcyBhIHVybCBvZiBgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXIjYFxuICogY3JlYXRlV2ViSGFzaEhpc3RvcnkoJy9mb2xkZXIvJykgLy8gZ2l2ZXMgYSB1cmwgb2YgYGh0dHBzOi8vZXhhbXBsZS5jb20vZm9sZGVyLyNgXG4gKiAvLyBpZiB0aGUgYCNgIGlzIHByb3ZpZGVkIGluIHRoZSBiYXNlLCBpdCB3b24ndCBiZSBhZGRlZCBieSBgY3JlYXRlV2ViSGFzaEhpc3RvcnlgXG4gKiBjcmVhdGVXZWJIYXNoSGlzdG9yeSgnL2ZvbGRlci8jL2FwcC8nKSAvLyBnaXZlcyBhIHVybCBvZiBgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXIvIy9hcHAvYFxuICogLy8geW91IHNob3VsZCBhdm9pZCBkb2luZyB0aGlzIGJlY2F1c2UgaXQgY2hhbmdlcyB0aGUgb3JpZ2luYWwgdXJsIGFuZCBicmVha3MgY29weWluZyB1cmxzXG4gKiBjcmVhdGVXZWJIYXNoSGlzdG9yeSgnL290aGVyLWZvbGRlci8nKSAvLyBnaXZlcyBhIHVybCBvZiBgaHR0cHM6Ly9leGFtcGxlLmNvbS9vdGhlci1mb2xkZXIvI2BcbiAqXG4gKiAvLyBhdCBmaWxlOi8vL3Vzci9ldGMvZm9sZGVyL2luZGV4Lmh0bWxcbiAqIC8vIGZvciBsb2NhdGlvbnMgd2l0aCBubyBgaG9zdGAsIHRoZSBiYXNlIGlzIGlnbm9yZWRcbiAqIGNyZWF0ZVdlYkhhc2hIaXN0b3J5KCcvaUFtSWdub3JlZCcpIC8vIGdpdmVzIGEgdXJsIG9mIGBmaWxlOi8vL3Vzci9ldGMvZm9sZGVyL2luZGV4Lmh0bWwjYFxuICogYGBgXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVdlYkhhc2hIaXN0b3J5KGJhc2UpIHtcbiAgICAvLyBNYWtlIHN1cmUgdGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBmaW5lIGluIHRlcm1zIG9mIGVuY29kaW5nLCBzcGVjaWFsbHkgZm9yIElFMTFcbiAgICAvLyBmb3IgYGZpbGU6Ly9gLCBkaXJlY3RseSB1c2UgdGhlIHBhdGhuYW1lIGFuZCBpZ25vcmUgdGhlIGJhc2VcbiAgICAvLyBsb2NhdGlvbi5wYXRobmFtZSBjb250YWlucyBhbiBpbml0aWFsIGAvYCBldmVuIGF0IHRoZSByb290OiBgaHR0cHM6Ly9leGFtcGxlLmNvbWBcbiAgICBiYXNlID0gbG9jYXRpb24uaG9zdCA/IGJhc2UgfHwgbG9jYXRpb24ucGF0aG5hbWUgKyBsb2NhdGlvbi5zZWFyY2ggOiAnJztcbiAgICAvLyBhbGxvdyB0aGUgdXNlciB0byBwcm92aWRlIGEgYCNgIGluIHRoZSBtaWRkbGU6IGAvYmFzZS8jL2FwcGBcbiAgICBpZiAoIWJhc2UuaW5jbHVkZXMoJyMnKSlcbiAgICAgICAgYmFzZSArPSAnIyc7XG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhYmFzZS5lbmRzV2l0aCgnIy8nKSAmJiAhYmFzZS5lbmRzV2l0aCgnIycpKSB7XG4gICAgICAgIHdhcm4oYEEgaGFzaCBiYXNlIG11c3QgZW5kIHdpdGggYSBcIiNcIjpcXG5cIiR7YmFzZX1cIiBzaG91bGQgYmUgXCIke2Jhc2UucmVwbGFjZSgvIy4qJC8sICcjJyl9XCIuYCk7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVXZWJIaXN0b3J5KGJhc2UpO1xufVxuXG5mdW5jdGlvbiBpc1JvdXRlTG9jYXRpb24ocm91dGUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHJvdXRlID09PSAnc3RyaW5nJyB8fCAocm91dGUgJiYgdHlwZW9mIHJvdXRlID09PSAnb2JqZWN0Jyk7XG59XG5mdW5jdGlvbiBpc1JvdXRlTmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBuYW1lID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgbmFtZSA9PT0gJ3N5bWJvbCc7XG59XG5cbmNvbnN0IE5hdmlnYXRpb25GYWlsdXJlU3ltYm9sID0gU3ltYm9sKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/ICduYXZpZ2F0aW9uIGZhaWx1cmUnIDogJycpO1xuLyoqXG4gKiBFbnVtZXJhdGlvbiB3aXRoIGFsbCBwb3NzaWJsZSB0eXBlcyBmb3IgbmF2aWdhdGlvbiBmYWlsdXJlcy4gQ2FuIGJlIHBhc3NlZCB0b1xuICoge0BsaW5rIGlzTmF2aWdhdGlvbkZhaWx1cmV9IHRvIGNoZWNrIGZvciBzcGVjaWZpYyBmYWlsdXJlcy5cbiAqL1xudmFyIE5hdmlnYXRpb25GYWlsdXJlVHlwZTtcbihmdW5jdGlvbiAoTmF2aWdhdGlvbkZhaWx1cmVUeXBlKSB7XG4gICAgLyoqXG4gICAgICogQW4gYWJvcnRlZCBuYXZpZ2F0aW9uIGlzIGEgbmF2aWdhdGlvbiB0aGF0IGZhaWxlZCBiZWNhdXNlIGEgbmF2aWdhdGlvblxuICAgICAqIGd1YXJkIHJldHVybmVkIGBmYWxzZWAgb3IgY2FsbGVkIGBuZXh0KGZhbHNlKWBcbiAgICAgKi9cbiAgICBOYXZpZ2F0aW9uRmFpbHVyZVR5cGVbTmF2aWdhdGlvbkZhaWx1cmVUeXBlW1wiYWJvcnRlZFwiXSA9IDRdID0gXCJhYm9ydGVkXCI7XG4gICAgLyoqXG4gICAgICogQSBjYW5jZWxsZWQgbmF2aWdhdGlvbiBpcyBhIG5hdmlnYXRpb24gdGhhdCBmYWlsZWQgYmVjYXVzZSBhIG1vcmUgcmVjZW50XG4gICAgICogbmF2aWdhdGlvbiBmaW5pc2hlZCBzdGFydGVkIChub3QgbmVjZXNzYXJpbHkgZmluaXNoZWQpLlxuICAgICAqL1xuICAgIE5hdmlnYXRpb25GYWlsdXJlVHlwZVtOYXZpZ2F0aW9uRmFpbHVyZVR5cGVbXCJjYW5jZWxsZWRcIl0gPSA4XSA9IFwiY2FuY2VsbGVkXCI7XG4gICAgLyoqXG4gICAgICogQSBkdXBsaWNhdGVkIG5hdmlnYXRpb24gaXMgYSBuYXZpZ2F0aW9uIHRoYXQgZmFpbGVkIGJlY2F1c2UgaXQgd2FzXG4gICAgICogaW5pdGlhdGVkIHdoaWxlIGFscmVhZHkgYmVpbmcgYXQgdGhlIGV4YWN0IHNhbWUgbG9jYXRpb24uXG4gICAgICovXG4gICAgTmF2aWdhdGlvbkZhaWx1cmVUeXBlW05hdmlnYXRpb25GYWlsdXJlVHlwZVtcImR1cGxpY2F0ZWRcIl0gPSAxNl0gPSBcImR1cGxpY2F0ZWRcIjtcbn0pKE5hdmlnYXRpb25GYWlsdXJlVHlwZSB8fCAoTmF2aWdhdGlvbkZhaWx1cmVUeXBlID0ge30pKTtcbi8vIERFViBvbmx5IGRlYnVnIG1lc3NhZ2VzXG5jb25zdCBFcnJvclR5cGVNZXNzYWdlcyA9IHtcbiAgICBbMSAvKiBFcnJvclR5cGVzLk1BVENIRVJfTk9UX0ZPVU5EICovXSh7IGxvY2F0aW9uLCBjdXJyZW50TG9jYXRpb24gfSkge1xuICAgICAgICByZXR1cm4gYE5vIG1hdGNoIGZvclxcbiAke0pTT04uc3RyaW5naWZ5KGxvY2F0aW9uKX0ke2N1cnJlbnRMb2NhdGlvblxuICAgICAgICAgICAgPyAnXFxud2hpbGUgYmVpbmcgYXRcXG4nICsgSlNPTi5zdHJpbmdpZnkoY3VycmVudExvY2F0aW9uKVxuICAgICAgICAgICAgOiAnJ31gO1xuICAgIH0sXG4gICAgWzIgLyogRXJyb3JUeXBlcy5OQVZJR0FUSU9OX0dVQVJEX1JFRElSRUNUICovXSh7IGZyb20sIHRvLCB9KSB7XG4gICAgICAgIHJldHVybiBgUmVkaXJlY3RlZCBmcm9tIFwiJHtmcm9tLmZ1bGxQYXRofVwiIHRvIFwiJHtzdHJpbmdpZnlSb3V0ZSh0byl9XCIgdmlhIGEgbmF2aWdhdGlvbiBndWFyZC5gO1xuICAgIH0sXG4gICAgWzQgLyogRXJyb3JUeXBlcy5OQVZJR0FUSU9OX0FCT1JURUQgKi9dKHsgZnJvbSwgdG8gfSkge1xuICAgICAgICByZXR1cm4gYE5hdmlnYXRpb24gYWJvcnRlZCBmcm9tIFwiJHtmcm9tLmZ1bGxQYXRofVwiIHRvIFwiJHt0by5mdWxsUGF0aH1cIiB2aWEgYSBuYXZpZ2F0aW9uIGd1YXJkLmA7XG4gICAgfSxcbiAgICBbOCAvKiBFcnJvclR5cGVzLk5BVklHQVRJT05fQ0FOQ0VMTEVEICovXSh7IGZyb20sIHRvIH0pIHtcbiAgICAgICAgcmV0dXJuIGBOYXZpZ2F0aW9uIGNhbmNlbGxlZCBmcm9tIFwiJHtmcm9tLmZ1bGxQYXRofVwiIHRvIFwiJHt0by5mdWxsUGF0aH1cIiB3aXRoIGEgbmV3IG5hdmlnYXRpb24uYDtcbiAgICB9LFxuICAgIFsxNiAvKiBFcnJvclR5cGVzLk5BVklHQVRJT05fRFVQTElDQVRFRCAqL10oeyBmcm9tLCB0byB9KSB7XG4gICAgICAgIHJldHVybiBgQXZvaWRlZCByZWR1bmRhbnQgbmF2aWdhdGlvbiB0byBjdXJyZW50IGxvY2F0aW9uOiBcIiR7ZnJvbS5mdWxsUGF0aH1cIi5gO1xuICAgIH0sXG59O1xuLyoqXG4gKiBDcmVhdGVzIGEgdHlwZWQgTmF2aWdhdGlvbkZhaWx1cmUgb2JqZWN0LlxuICogQGludGVybmFsXG4gKiBAcGFyYW0gdHlwZSAtIE5hdmlnYXRpb25GYWlsdXJlVHlwZVxuICogQHBhcmFtIHBhcmFtcyAtIHsgZnJvbSwgdG8gfVxuICovXG5mdW5jdGlvbiBjcmVhdGVSb3V0ZXJFcnJvcih0eXBlLCBwYXJhbXMpIHtcbiAgICAvLyBrZWVwIGZ1bGwgZXJyb3IgbWVzc2FnZXMgaW4gY2pzIHZlcnNpb25zXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB8fCAhdHJ1ZSkge1xuICAgICAgICByZXR1cm4gYXNzaWduKG5ldyBFcnJvcihFcnJvclR5cGVNZXNzYWdlc1t0eXBlXShwYXJhbXMpKSwge1xuICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgIFtOYXZpZ2F0aW9uRmFpbHVyZVN5bWJvbF06IHRydWUsXG4gICAgICAgIH0sIHBhcmFtcyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gYXNzaWduKG5ldyBFcnJvcigpLCB7XG4gICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgW05hdmlnYXRpb25GYWlsdXJlU3ltYm9sXTogdHJ1ZSxcbiAgICAgICAgfSwgcGFyYW1zKTtcbiAgICB9XG59XG5mdW5jdGlvbiBpc05hdmlnYXRpb25GYWlsdXJlKGVycm9yLCB0eXBlKSB7XG4gICAgcmV0dXJuIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmXG4gICAgICAgIE5hdmlnYXRpb25GYWlsdXJlU3ltYm9sIGluIGVycm9yICYmXG4gICAgICAgICh0eXBlID09IG51bGwgfHwgISEoZXJyb3IudHlwZSAmIHR5cGUpKSk7XG59XG5jb25zdCBwcm9wZXJ0aWVzVG9Mb2cgPSBbJ3BhcmFtcycsICdxdWVyeScsICdoYXNoJ107XG5mdW5jdGlvbiBzdHJpbmdpZnlSb3V0ZSh0bykge1xuICAgIGlmICh0eXBlb2YgdG8gPT09ICdzdHJpbmcnKVxuICAgICAgICByZXR1cm4gdG87XG4gICAgaWYgKHRvLnBhdGggIT0gbnVsbClcbiAgICAgICAgcmV0dXJuIHRvLnBhdGg7XG4gICAgY29uc3QgbG9jYXRpb24gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBwcm9wZXJ0aWVzVG9Mb2cpIHtcbiAgICAgICAgaWYgKGtleSBpbiB0bylcbiAgICAgICAgICAgIGxvY2F0aW9uW2tleV0gPSB0b1trZXldO1xuICAgIH1cbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobG9jYXRpb24sIG51bGwsIDIpO1xufVxuXG4vLyBkZWZhdWx0IHBhdHRlcm4gZm9yIGEgcGFyYW06IG5vbi1ncmVlZHkgZXZlcnl0aGluZyBidXQgL1xuY29uc3QgQkFTRV9QQVJBTV9QQVRURVJOID0gJ1teL10rPyc7XG5jb25zdCBCQVNFX1BBVEhfUEFSU0VSX09QVElPTlMgPSB7XG4gICAgc2Vuc2l0aXZlOiBmYWxzZSxcbiAgICBzdHJpY3Q6IGZhbHNlLFxuICAgIHN0YXJ0OiB0cnVlLFxuICAgIGVuZDogdHJ1ZSxcbn07XG4vLyBTcGVjaWFsIFJlZ2V4IGNoYXJhY3RlcnMgdGhhdCBtdXN0IGJlIGVzY2FwZWQgaW4gc3RhdGljIHRva2Vuc1xuY29uc3QgUkVHRVhfQ0hBUlNfUkUgPSAvWy4rKj9eJHt9KClbXFxdL1xcXFxdL2c7XG4vKipcbiAqIENyZWF0ZXMgYSBwYXRoIHBhcnNlciBmcm9tIGFuIGFycmF5IG9mIFNlZ21lbnRzIChhIHNlZ21lbnQgaXMgYW4gYXJyYXkgb2YgVG9rZW5zKVxuICpcbiAqIEBwYXJhbSBzZWdtZW50cyAtIGFycmF5IG9mIHNlZ21lbnRzIHJldHVybmVkIGJ5IHRva2VuaXplUGF0aFxuICogQHBhcmFtIGV4dHJhT3B0aW9ucyAtIG9wdGlvbmFsIG9wdGlvbnMgZm9yIHRoZSByZWdleHBcbiAqIEByZXR1cm5zIGEgUGF0aFBhcnNlclxuICovXG5mdW5jdGlvbiB0b2tlbnNUb1BhcnNlcihzZWdtZW50cywgZXh0cmFPcHRpb25zKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGFzc2lnbih7fSwgQkFTRV9QQVRIX1BBUlNFUl9PUFRJT05TLCBleHRyYU9wdGlvbnMpO1xuICAgIC8vIHRoZSBhbW91bnQgb2Ygc2NvcmVzIGlzIHRoZSBzYW1lIGFzIHRoZSBsZW5ndGggb2Ygc2VnbWVudHMgZXhjZXB0IGZvciB0aGUgcm9vdCBzZWdtZW50IFwiL1wiXG4gICAgY29uc3Qgc2NvcmUgPSBbXTtcbiAgICAvLyB0aGUgcmVnZXhwIGFzIGEgc3RyaW5nXG4gICAgbGV0IHBhdHRlcm4gPSBvcHRpb25zLnN0YXJ0ID8gJ14nIDogJyc7XG4gICAgLy8gZXh0cmFjdGVkIGtleXNcbiAgICBjb25zdCBrZXlzID0gW107XG4gICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgICAgIC8vIHRoZSByb290IHNlZ21lbnQgbmVlZHMgc3BlY2lhbCB0cmVhdG1lbnRcbiAgICAgICAgY29uc3Qgc2VnbWVudFNjb3JlcyA9IHNlZ21lbnQubGVuZ3RoID8gW10gOiBbOTAgLyogUGF0aFNjb3JlLlJvb3QgKi9dO1xuICAgICAgICAvLyBhbGxvdyB0cmFpbGluZyBzbGFzaFxuICAgICAgICBpZiAob3B0aW9ucy5zdHJpY3QgJiYgIXNlZ21lbnQubGVuZ3RoKVxuICAgICAgICAgICAgcGF0dGVybiArPSAnLyc7XG4gICAgICAgIGZvciAobGV0IHRva2VuSW5kZXggPSAwOyB0b2tlbkluZGV4IDwgc2VnbWVudC5sZW5ndGg7IHRva2VuSW5kZXgrKykge1xuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSBzZWdtZW50W3Rva2VuSW5kZXhdO1xuICAgICAgICAgICAgLy8gcmVzZXRzIHRoZSBzY29yZSBpZiB3ZSBhcmUgaW5zaWRlIGEgc3ViLXNlZ21lbnQgLzphLW90aGVyLTpiXG4gICAgICAgICAgICBsZXQgc3ViU2VnbWVudFNjb3JlID0gNDAgLyogUGF0aFNjb3JlLlNlZ21lbnQgKi8gK1xuICAgICAgICAgICAgICAgIChvcHRpb25zLnNlbnNpdGl2ZSA/IDAuMjUgLyogUGF0aFNjb3JlLkJvbnVzQ2FzZVNlbnNpdGl2ZSAqLyA6IDApO1xuICAgICAgICAgICAgaWYgKHRva2VuLnR5cGUgPT09IDAgLyogVG9rZW5UeXBlLlN0YXRpYyAqLykge1xuICAgICAgICAgICAgICAgIC8vIHByZXBlbmQgdGhlIHNsYXNoIGlmIHdlIGFyZSBzdGFydGluZyBhIG5ldyBzZWdtZW50XG4gICAgICAgICAgICAgICAgaWYgKCF0b2tlbkluZGV4KVxuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuICs9ICcvJztcbiAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IHRva2VuLnZhbHVlLnJlcGxhY2UoUkVHRVhfQ0hBUlNfUkUsICdcXFxcJCYnKTtcbiAgICAgICAgICAgICAgICBzdWJTZWdtZW50U2NvcmUgKz0gNDAgLyogUGF0aFNjb3JlLlN0YXRpYyAqLztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRva2VuLnR5cGUgPT09IDEgLyogVG9rZW5UeXBlLlBhcmFtICovKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyB2YWx1ZSwgcmVwZWF0YWJsZSwgb3B0aW9uYWwsIHJlZ2V4cCB9ID0gdG9rZW47XG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHJlcGVhdGFibGUsXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlID0gcmVnZXhwID8gcmVnZXhwIDogQkFTRV9QQVJBTV9QQVRURVJOO1xuICAgICAgICAgICAgICAgIC8vIHRoZSB1c2VyIHByb3ZpZGVkIGEgY3VzdG9tIHJlZ2V4cCAvOmlkKFxcXFxkKylcbiAgICAgICAgICAgICAgICBpZiAocmUgIT09IEJBU0VfUEFSQU1fUEFUVEVSTikge1xuICAgICAgICAgICAgICAgICAgICBzdWJTZWdtZW50U2NvcmUgKz0gMTAgLyogUGF0aFNjb3JlLkJvbnVzQ3VzdG9tUmVnRXhwICovO1xuICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIHJlZ2V4cCBpcyB2YWxpZCBiZWZvcmUgdXNpbmcgaXRcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZWdFeHAoYCgke3JlfSlgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgY3VzdG9tIFJlZ0V4cCBmb3IgcGFyYW0gXCIke3ZhbHVlfVwiICgke3JlfSk6IGAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyB3aGVuIHdlIHJlcGVhdCB3ZSBtdXN0IHRha2UgY2FyZSBvZiB0aGUgcmVwZWF0aW5nIGxlYWRpbmcgc2xhc2hcbiAgICAgICAgICAgICAgICBsZXQgc3ViUGF0dGVybiA9IHJlcGVhdGFibGUgPyBgKCg/OiR7cmV9KSg/Oi8oPzoke3JlfSkpKilgIDogYCgke3JlfSlgO1xuICAgICAgICAgICAgICAgIC8vIHByZXBlbmQgdGhlIHNsYXNoIGlmIHdlIGFyZSBzdGFydGluZyBhIG5ldyBzZWdtZW50XG4gICAgICAgICAgICAgICAgaWYgKCF0b2tlbkluZGV4KVxuICAgICAgICAgICAgICAgICAgICBzdWJQYXR0ZXJuID1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF2b2lkIGFuIG9wdGlvbmFsIC8gaWYgdGhlcmUgYXJlIG1vcmUgc2VnbWVudHMgZS5nLiAvOnA/LXN0YXRpY1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3IgLzpwPy06cDJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsICYmIHNlZ21lbnQubGVuZ3RoIDwgMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYCg/Oi8ke3N1YlBhdHRlcm59KWBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICcvJyArIHN1YlBhdHRlcm47XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbmFsKVxuICAgICAgICAgICAgICAgICAgICBzdWJQYXR0ZXJuICs9ICc/JztcbiAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IHN1YlBhdHRlcm47XG4gICAgICAgICAgICAgICAgc3ViU2VnbWVudFNjb3JlICs9IDIwIC8qIFBhdGhTY29yZS5EeW5hbWljICovO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25hbClcbiAgICAgICAgICAgICAgICAgICAgc3ViU2VnbWVudFNjb3JlICs9IC04IC8qIFBhdGhTY29yZS5Cb251c09wdGlvbmFsICovO1xuICAgICAgICAgICAgICAgIGlmIChyZXBlYXRhYmxlKVxuICAgICAgICAgICAgICAgICAgICBzdWJTZWdtZW50U2NvcmUgKz0gLTIwIC8qIFBhdGhTY29yZS5Cb251c1JlcGVhdGFibGUgKi87XG4gICAgICAgICAgICAgICAgaWYgKHJlID09PSAnLionKVxuICAgICAgICAgICAgICAgICAgICBzdWJTZWdtZW50U2NvcmUgKz0gLTUwIC8qIFBhdGhTY29yZS5Cb251c1dpbGRjYXJkICovO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VnbWVudFNjb3Jlcy5wdXNoKHN1YlNlZ21lbnRTY29yZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYW4gZW1wdHkgYXJyYXkgbGlrZSAvaG9tZS8gLT4gW1t7aG9tZX1dLCBbXV1cbiAgICAgICAgLy8gaWYgKCFzZWdtZW50Lmxlbmd0aCkgcGF0dGVybiArPSAnLydcbiAgICAgICAgc2NvcmUucHVzaChzZWdtZW50U2NvcmVzKTtcbiAgICB9XG4gICAgLy8gb25seSBhcHBseSB0aGUgc3RyaWN0IGJvbnVzIHRvIHRoZSBsYXN0IHNjb3JlXG4gICAgaWYgKG9wdGlvbnMuc3RyaWN0ICYmIG9wdGlvbnMuZW5kKSB7XG4gICAgICAgIGNvbnN0IGkgPSBzY29yZS5sZW5ndGggLSAxO1xuICAgICAgICBzY29yZVtpXVtzY29yZVtpXS5sZW5ndGggLSAxXSArPSAwLjcwMDAwMDAwMDAwMDAwMDEgLyogUGF0aFNjb3JlLkJvbnVzU3RyaWN0ICovO1xuICAgIH1cbiAgICAvLyBUT0RPOiBkZXYgb25seSB3YXJuIGRvdWJsZSB0cmFpbGluZyBzbGFzaFxuICAgIGlmICghb3B0aW9ucy5zdHJpY3QpXG4gICAgICAgIHBhdHRlcm4gKz0gJy8/JztcbiAgICBpZiAob3B0aW9ucy5lbmQpXG4gICAgICAgIHBhdHRlcm4gKz0gJyQnO1xuICAgIC8vIGFsbG93IHBhdGhzIGxpa2UgL2R5bmFtaWMgdG8gb25seSBtYXRjaCBkeW5hbWljIG9yIGR5bmFtaWMvLi4uIGJ1dCBub3QgZHluYW1pY19zb21ldGhpbmdfZWxzZVxuICAgIGVsc2UgaWYgKG9wdGlvbnMuc3RyaWN0ICYmICFwYXR0ZXJuLmVuZHNXaXRoKCcvJykpXG4gICAgICAgIHBhdHRlcm4gKz0gJyg/Oi98JCknO1xuICAgIGNvbnN0IHJlID0gbmV3IFJlZ0V4cChwYXR0ZXJuLCBvcHRpb25zLnNlbnNpdGl2ZSA/ICcnIDogJ2knKTtcbiAgICBmdW5jdGlvbiBwYXJzZShwYXRoKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gcGF0aC5tYXRjaChyZSk7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHt9O1xuICAgICAgICBpZiAoIW1hdGNoKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbWF0Y2gubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gbWF0Y2hbaV0gfHwgJyc7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBrZXlzW2kgLSAxXTtcbiAgICAgICAgICAgIHBhcmFtc1trZXkubmFtZV0gPSB2YWx1ZSAmJiBrZXkucmVwZWF0YWJsZSA/IHZhbHVlLnNwbGl0KCcvJykgOiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFyYW1zO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzdHJpbmdpZnkocGFyYW1zKSB7XG4gICAgICAgIGxldCBwYXRoID0gJyc7XG4gICAgICAgIC8vIGZvciBvcHRpb25hbCBwYXJhbWV0ZXJzIHRvIGFsbG93IHRvIGJlIGVtcHR5XG4gICAgICAgIGxldCBhdm9pZER1cGxpY2F0ZWRTbGFzaCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpIHtcbiAgICAgICAgICAgIGlmICghYXZvaWREdXBsaWNhdGVkU2xhc2ggfHwgIXBhdGguZW5kc1dpdGgoJy8nKSlcbiAgICAgICAgICAgICAgICBwYXRoICs9ICcvJztcbiAgICAgICAgICAgIGF2b2lkRHVwbGljYXRlZFNsYXNoID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRva2VuIG9mIHNlZ21lbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAodG9rZW4udHlwZSA9PT0gMCAvKiBUb2tlblR5cGUuU3RhdGljICovKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhdGggKz0gdG9rZW4udmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRva2VuLnR5cGUgPT09IDEgLyogVG9rZW5UeXBlLlBhcmFtICovKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgdmFsdWUsIHJlcGVhdGFibGUsIG9wdGlvbmFsIH0gPSB0b2tlbjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyYW0gPSB2YWx1ZSBpbiBwYXJhbXMgPyBwYXJhbXNbdmFsdWVdIDogJyc7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KHBhcmFtKSAmJiAhcmVwZWF0YWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcm92aWRlZCBwYXJhbSBcIiR7dmFsdWV9XCIgaXMgYW4gYXJyYXkgYnV0IGl0IGlzIG5vdCByZXBlYXRhYmxlICgqIG9yICsgbW9kaWZpZXJzKWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSBpc0FycmF5KHBhcmFtKVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBwYXJhbS5qb2luKCcvJylcbiAgICAgICAgICAgICAgICAgICAgICAgIDogcGFyYW07XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbmFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgd2UgaGF2ZSBtb3JlIHRoYW4gb25lIG9wdGlvbmFsIHBhcmFtIGxpa2UgLzphPy1zdGF0aWMgd2UgZG9uJ3QgbmVlZCB0byBjYXJlIGFib3V0IHRoZSBvcHRpb25hbCBwYXJhbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWdtZW50Lmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBsYXN0IHNsYXNoIGFzIHdlIGNvdWxkIGJlIGF0IHRoZSBlbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGguZW5kc1dpdGgoJy8nKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoLnNsaWNlKDAsIC0xKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90IGFwcGVuZCBhIHNsYXNoIG9uIHRoZSBuZXh0IGl0ZXJhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdm9pZER1cGxpY2F0ZWRTbGFzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyByZXF1aXJlZCBwYXJhbSBcIiR7dmFsdWV9XCJgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXRoICs9IHRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGF2b2lkIGVtcHR5IHBhdGggd2hlbiB3ZSBoYXZlIG11bHRpcGxlIG9wdGlvbmFsIHBhcmFtc1xuICAgICAgICByZXR1cm4gcGF0aCB8fCAnLyc7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHJlLFxuICAgICAgICBzY29yZSxcbiAgICAgICAga2V5cyxcbiAgICAgICAgcGFyc2UsXG4gICAgICAgIHN0cmluZ2lmeSxcbiAgICB9O1xufVxuLyoqXG4gKiBDb21wYXJlcyBhbiBhcnJheSBvZiBudW1iZXJzIGFzIHVzZWQgaW4gUGF0aFBhcnNlci5zY29yZSBhbmQgcmV0dXJucyBhXG4gKiBudW1iZXIuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gYHNvcnRgIGFuIGFycmF5XG4gKlxuICogQHBhcmFtIGEgLSBmaXJzdCBhcnJheSBvZiBudW1iZXJzXG4gKiBAcGFyYW0gYiAtIHNlY29uZCBhcnJheSBvZiBudW1iZXJzXG4gKiBAcmV0dXJucyAwIGlmIGJvdGggYXJlIGVxdWFsLCA8IDAgaWYgYSBzaG91bGQgYmUgc29ydGVkIGZpcnN0LCA+IDAgaWYgYlxuICogc2hvdWxkIGJlIHNvcnRlZCBmaXJzdFxuICovXG5mdW5jdGlvbiBjb21wYXJlU2NvcmVBcnJheShhLCBiKSB7XG4gICAgbGV0IGkgPSAwO1xuICAgIHdoaWxlIChpIDwgYS5sZW5ndGggJiYgaSA8IGIubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGRpZmYgPSBiW2ldIC0gYVtpXTtcbiAgICAgICAgLy8gb25seSBrZWVwIGdvaW5nIGlmIGRpZmYgPT09IDBcbiAgICAgICAgaWYgKGRpZmYpXG4gICAgICAgICAgICByZXR1cm4gZGlmZjtcbiAgICAgICAgaSsrO1xuICAgIH1cbiAgICAvLyBpZiB0aGUgbGFzdCBzdWJzZWdtZW50IHdhcyBTdGF0aWMsIHRoZSBzaG9ydGVyIHNlZ21lbnRzIHNob3VsZCBiZSBzb3J0ZWQgZmlyc3RcbiAgICAvLyBvdGhlcndpc2Ugc29ydCB0aGUgbG9uZ2VzdCBzZWdtZW50IGZpcnN0XG4gICAgaWYgKGEubGVuZ3RoIDwgYi5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGEubGVuZ3RoID09PSAxICYmIGFbMF0gPT09IDQwIC8qIFBhdGhTY29yZS5TdGF0aWMgKi8gKyA0MCAvKiBQYXRoU2NvcmUuU2VnbWVudCAqL1xuICAgICAgICAgICAgPyAtMVxuICAgICAgICAgICAgOiAxO1xuICAgIH1cbiAgICBlbHNlIGlmIChhLmxlbmd0aCA+IGIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBiLmxlbmd0aCA9PT0gMSAmJiBiWzBdID09PSA0MCAvKiBQYXRoU2NvcmUuU3RhdGljICovICsgNDAgLyogUGF0aFNjb3JlLlNlZ21lbnQgKi9cbiAgICAgICAgICAgID8gMVxuICAgICAgICAgICAgOiAtMTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59XG4vKipcbiAqIENvbXBhcmUgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB3aXRoIGBzb3J0YCB0byBzb3J0IGFuIGFycmF5IG9mIFBhdGhQYXJzZXJcbiAqXG4gKiBAcGFyYW0gYSAtIGZpcnN0IFBhdGhQYXJzZXJcbiAqIEBwYXJhbSBiIC0gc2Vjb25kIFBhdGhQYXJzZXJcbiAqIEByZXR1cm5zIDAgaWYgYm90aCBhcmUgZXF1YWwsIDwgMCBpZiBhIHNob3VsZCBiZSBzb3J0ZWQgZmlyc3QsID4gMCBpZiBiXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmVQYXRoUGFyc2VyU2NvcmUoYSwgYikge1xuICAgIGxldCBpID0gMDtcbiAgICBjb25zdCBhU2NvcmUgPSBhLnNjb3JlO1xuICAgIGNvbnN0IGJTY29yZSA9IGIuc2NvcmU7XG4gICAgd2hpbGUgKGkgPCBhU2NvcmUubGVuZ3RoICYmIGkgPCBiU2NvcmUubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGNvbXAgPSBjb21wYXJlU2NvcmVBcnJheShhU2NvcmVbaV0sIGJTY29yZVtpXSk7XG4gICAgICAgIC8vIGRvIG5vdCByZXR1cm4gaWYgYm90aCBhcmUgZXF1YWxcbiAgICAgICAgaWYgKGNvbXApXG4gICAgICAgICAgICByZXR1cm4gY29tcDtcbiAgICAgICAgaSsrO1xuICAgIH1cbiAgICBpZiAoTWF0aC5hYnMoYlNjb3JlLmxlbmd0aCAtIGFTY29yZS5sZW5ndGgpID09PSAxKSB7XG4gICAgICAgIGlmIChpc0xhc3RTY29yZU5lZ2F0aXZlKGFTY29yZSkpXG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgaWYgKGlzTGFzdFNjb3JlTmVnYXRpdmUoYlNjb3JlKSlcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgLy8gaWYgYSBhbmQgYiBzaGFyZSB0aGUgc2FtZSBzY29yZSBlbnRyaWVzIGJ1dCBiIGhhcyBtb3JlLCBzb3J0IGIgZmlyc3RcbiAgICByZXR1cm4gYlNjb3JlLmxlbmd0aCAtIGFTY29yZS5sZW5ndGg7XG4gICAgLy8gdGhpcyBpcyB0aGUgdGVybmFyeSB2ZXJzaW9uXG4gICAgLy8gcmV0dXJuIGFTY29yZS5sZW5ndGggPCBiU2NvcmUubGVuZ3RoXG4gICAgLy8gICA/IDFcbiAgICAvLyAgIDogYVNjb3JlLmxlbmd0aCA+IGJTY29yZS5sZW5ndGhcbiAgICAvLyAgID8gLTFcbiAgICAvLyAgIDogMFxufVxuLyoqXG4gKiBUaGlzIGFsbG93cyBkZXRlY3Rpbmcgc3BsYXRzIGF0IHRoZSBlbmQgb2YgYSBwYXRoOiAvaG9tZS86aWQoLiopKlxuICpcbiAqIEBwYXJhbSBzY29yZSAtIHNjb3JlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBsYXN0IGVudHJ5IGlzIG5lZ2F0aXZlXG4gKi9cbmZ1bmN0aW9uIGlzTGFzdFNjb3JlTmVnYXRpdmUoc2NvcmUpIHtcbiAgICBjb25zdCBsYXN0ID0gc2NvcmVbc2NvcmUubGVuZ3RoIC0gMV07XG4gICAgcmV0dXJuIHNjb3JlLmxlbmd0aCA+IDAgJiYgbGFzdFtsYXN0Lmxlbmd0aCAtIDFdIDwgMDtcbn1cblxuY29uc3QgUk9PVF9UT0tFTiA9IHtcbiAgICB0eXBlOiAwIC8qIFRva2VuVHlwZS5TdGF0aWMgKi8sXG4gICAgdmFsdWU6ICcnLFxufTtcbmNvbnN0IFZBTElEX1BBUkFNX1JFID0gL1thLXpBLVowLTlfXS87XG4vLyBBZnRlciBzb21lIHByb2ZpbGluZywgdGhlIGNhY2hlIHNlZW1zIHRvIGJlIHVubmVjZXNzYXJ5IGJlY2F1c2UgdG9rZW5pemVQYXRoXG4vLyAodGhlIHNsb3dlc3QgcGFydCBvZiBhZGRpbmcgYSByb3V0ZSkgaXMgdmVyeSBmYXN0XG4vLyBjb25zdCB0b2tlbkNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIFRva2VuW11bXT4oKVxuZnVuY3Rpb24gdG9rZW5pemVQYXRoKHBhdGgpIHtcbiAgICBpZiAoIXBhdGgpXG4gICAgICAgIHJldHVybiBbW11dO1xuICAgIGlmIChwYXRoID09PSAnLycpXG4gICAgICAgIHJldHVybiBbW1JPT1RfVE9LRU5dXTtcbiAgICBpZiAoIXBhdGguc3RhcnRzV2l0aCgnLycpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJylcbiAgICAgICAgICAgID8gYFJvdXRlIHBhdGhzIHNob3VsZCBzdGFydCB3aXRoIGEgXCIvXCI6IFwiJHtwYXRofVwiIHNob3VsZCBiZSBcIi8ke3BhdGh9XCIuYFxuICAgICAgICAgICAgOiBgSW52YWxpZCBwYXRoIFwiJHtwYXRofVwiYCk7XG4gICAgfVxuICAgIC8vIGlmICh0b2tlbkNhY2hlLmhhcyhwYXRoKSkgcmV0dXJuIHRva2VuQ2FjaGUuZ2V0KHBhdGgpIVxuICAgIGZ1bmN0aW9uIGNyYXNoKG1lc3NhZ2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFUlIgKCR7c3RhdGV9KS9cIiR7YnVmZmVyfVwiOiAke21lc3NhZ2V9YCk7XG4gICAgfVxuICAgIGxldCBzdGF0ZSA9IDAgLyogVG9rZW5pemVyU3RhdGUuU3RhdGljICovO1xuICAgIGxldCBwcmV2aW91c1N0YXRlID0gc3RhdGU7XG4gICAgY29uc3QgdG9rZW5zID0gW107XG4gICAgLy8gdGhlIHNlZ21lbnQgd2lsbCBhbHdheXMgYmUgdmFsaWQgYmVjYXVzZSB3ZSBnZXQgaW50byB0aGUgaW5pdGlhbCBzdGF0ZVxuICAgIC8vIHdpdGggdGhlIGxlYWRpbmcgL1xuICAgIGxldCBzZWdtZW50O1xuICAgIGZ1bmN0aW9uIGZpbmFsaXplU2VnbWVudCgpIHtcbiAgICAgICAgaWYgKHNlZ21lbnQpXG4gICAgICAgICAgICB0b2tlbnMucHVzaChzZWdtZW50KTtcbiAgICAgICAgc2VnbWVudCA9IFtdO1xuICAgIH1cbiAgICAvLyBpbmRleCBvbiB0aGUgcGF0aFxuICAgIGxldCBpID0gMDtcbiAgICAvLyBjaGFyIGF0IGluZGV4XG4gICAgbGV0IGNoYXI7XG4gICAgLy8gYnVmZmVyIG9mIHRoZSB2YWx1ZSByZWFkXG4gICAgbGV0IGJ1ZmZlciA9ICcnO1xuICAgIC8vIGN1c3RvbSByZWdleHAgZm9yIGEgcGFyYW1cbiAgICBsZXQgY3VzdG9tUmUgPSAnJztcbiAgICBmdW5jdGlvbiBjb25zdW1lQnVmZmVyKCkge1xuICAgICAgICBpZiAoIWJ1ZmZlcilcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKHN0YXRlID09PSAwIC8qIFRva2VuaXplclN0YXRlLlN0YXRpYyAqLykge1xuICAgICAgICAgICAgc2VnbWVudC5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAwIC8qIFRva2VuVHlwZS5TdGF0aWMgKi8sXG4gICAgICAgICAgICAgICAgdmFsdWU6IGJ1ZmZlcixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHN0YXRlID09PSAxIC8qIFRva2VuaXplclN0YXRlLlBhcmFtICovIHx8XG4gICAgICAgICAgICBzdGF0ZSA9PT0gMiAvKiBUb2tlbml6ZXJTdGF0ZS5QYXJhbVJlZ0V4cCAqLyB8fFxuICAgICAgICAgICAgc3RhdGUgPT09IDMgLyogVG9rZW5pemVyU3RhdGUuUGFyYW1SZWdFeHBFbmQgKi8pIHtcbiAgICAgICAgICAgIGlmIChzZWdtZW50Lmxlbmd0aCA+IDEgJiYgKGNoYXIgPT09ICcqJyB8fCBjaGFyID09PSAnKycpKVxuICAgICAgICAgICAgICAgIGNyYXNoKGBBIHJlcGVhdGFibGUgcGFyYW0gKCR7YnVmZmVyfSkgbXVzdCBiZSBhbG9uZSBpbiBpdHMgc2VnbWVudC4gZWc6ICcvOmlkcysuYCk7XG4gICAgICAgICAgICBzZWdtZW50LnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IDEgLyogVG9rZW5UeXBlLlBhcmFtICovLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBidWZmZXIsXG4gICAgICAgICAgICAgICAgcmVnZXhwOiBjdXN0b21SZSxcbiAgICAgICAgICAgICAgICByZXBlYXRhYmxlOiBjaGFyID09PSAnKicgfHwgY2hhciA9PT0gJysnLFxuICAgICAgICAgICAgICAgIG9wdGlvbmFsOiBjaGFyID09PSAnKicgfHwgY2hhciA9PT0gJz8nLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjcmFzaCgnSW52YWxpZCBzdGF0ZSB0byBjb25zdW1lIGJ1ZmZlcicpO1xuICAgICAgICB9XG4gICAgICAgIGJ1ZmZlciA9ICcnO1xuICAgIH1cbiAgICBmdW5jdGlvbiBhZGRDaGFyVG9CdWZmZXIoKSB7XG4gICAgICAgIGJ1ZmZlciArPSBjaGFyO1xuICAgIH1cbiAgICB3aGlsZSAoaSA8IHBhdGgubGVuZ3RoKSB7XG4gICAgICAgIGNoYXIgPSBwYXRoW2krK107XG4gICAgICAgIGlmIChjaGFyID09PSAnXFxcXCcgJiYgc3RhdGUgIT09IDIgLyogVG9rZW5pemVyU3RhdGUuUGFyYW1SZWdFeHAgKi8pIHtcbiAgICAgICAgICAgIHByZXZpb3VzU3RhdGUgPSBzdGF0ZTtcbiAgICAgICAgICAgIHN0YXRlID0gNCAvKiBUb2tlbml6ZXJTdGF0ZS5Fc2NhcGVOZXh0ICovO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoIChzdGF0ZSkge1xuICAgICAgICAgICAgY2FzZSAwIC8qIFRva2VuaXplclN0YXRlLlN0YXRpYyAqLzpcbiAgICAgICAgICAgICAgICBpZiAoY2hhciA9PT0gJy8nKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChidWZmZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN1bWVCdWZmZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZVNlZ21lbnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2hhciA9PT0gJzonKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN1bWVCdWZmZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSAxIC8qIFRva2VuaXplclN0YXRlLlBhcmFtICovO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkQ2hhclRvQnVmZmVyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSA0IC8qIFRva2VuaXplclN0YXRlLkVzY2FwZU5leHQgKi86XG4gICAgICAgICAgICAgICAgYWRkQ2hhclRvQnVmZmVyKCk7XG4gICAgICAgICAgICAgICAgc3RhdGUgPSBwcmV2aW91c1N0YXRlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAxIC8qIFRva2VuaXplclN0YXRlLlBhcmFtICovOlxuICAgICAgICAgICAgICAgIGlmIChjaGFyID09PSAnKCcpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSAyIC8qIFRva2VuaXplclN0YXRlLlBhcmFtUmVnRXhwICovO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChWQUxJRF9QQVJBTV9SRS50ZXN0KGNoYXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZENoYXJUb0J1ZmZlcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3VtZUJ1ZmZlcigpO1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IDAgLyogVG9rZW5pemVyU3RhdGUuU3RhdGljICovO1xuICAgICAgICAgICAgICAgICAgICAvLyBnbyBiYWNrIG9uZSBjaGFyYWN0ZXIgaWYgd2Ugd2VyZSBub3QgbW9kaWZ5aW5nXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGFyICE9PSAnKicgJiYgY2hhciAhPT0gJz8nICYmIGNoYXIgIT09ICcrJylcbiAgICAgICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDIgLyogVG9rZW5pemVyU3RhdGUuUGFyYW1SZWdFeHAgKi86XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogaXMgaXQgd29ydGggaGFuZGxpbmcgbmVzdGVkIHJlZ2V4cD8gbGlrZSA6cCg/OnByZWZpeF8oW14vXSspX3N1ZmZpeClcbiAgICAgICAgICAgICAgICAvLyBpdCBhbHJlYWR5IHdvcmtzIGJ5IGVzY2FwaW5nIHRoZSBjbG9zaW5nIClcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL3BhdGhzLmVzbS5kZXYvP3A9QUFNZUpiaUF3UUVjREtiQW9BQWtQNjBQRzJSNlFBdmdOYUE2QUZBQ00yQUJ1UUJCI1xuICAgICAgICAgICAgICAgIC8vIGlzIHRoaXMgcmVhbGx5IHNvbWV0aGluZyBwZW9wbGUgbmVlZCBzaW5jZSB5b3UgY2FuIGFsc28gd3JpdGVcbiAgICAgICAgICAgICAgICAvLyAvcHJlZml4XzpwKClfc3VmZml4XG4gICAgICAgICAgICAgICAgaWYgKGNoYXIgPT09ICcpJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgdGhlIGVzY2FwZWQgKVxuICAgICAgICAgICAgICAgICAgICBpZiAoY3VzdG9tUmVbY3VzdG9tUmUubGVuZ3RoIC0gMV0gPT0gJ1xcXFwnKVxuICAgICAgICAgICAgICAgICAgICAgICAgY3VzdG9tUmUgPSBjdXN0b21SZS5zbGljZSgwLCAtMSkgKyBjaGFyO1xuICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IDMgLyogVG9rZW5pemVyU3RhdGUuUGFyYW1SZWdFeHBFbmQgKi87XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21SZSArPSBjaGFyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgMyAvKiBUb2tlbml6ZXJTdGF0ZS5QYXJhbVJlZ0V4cEVuZCAqLzpcbiAgICAgICAgICAgICAgICAvLyBzYW1lIGFzIGZpbmFsaXppbmcgYSBwYXJhbVxuICAgICAgICAgICAgICAgIGNvbnN1bWVCdWZmZXIoKTtcbiAgICAgICAgICAgICAgICBzdGF0ZSA9IDAgLyogVG9rZW5pemVyU3RhdGUuU3RhdGljICovO1xuICAgICAgICAgICAgICAgIC8vIGdvIGJhY2sgb25lIGNoYXJhY3RlciBpZiB3ZSB3ZXJlIG5vdCBtb2RpZnlpbmdcbiAgICAgICAgICAgICAgICBpZiAoY2hhciAhPT0gJyonICYmIGNoYXIgIT09ICc/JyAmJiBjaGFyICE9PSAnKycpXG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICBjdXN0b21SZSA9ICcnO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBjcmFzaCgnVW5rbm93biBzdGF0ZScpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gMiAvKiBUb2tlbml6ZXJTdGF0ZS5QYXJhbVJlZ0V4cCAqLylcbiAgICAgICAgY3Jhc2goYFVuZmluaXNoZWQgY3VzdG9tIFJlZ0V4cCBmb3IgcGFyYW0gXCIke2J1ZmZlcn1cImApO1xuICAgIGNvbnN1bWVCdWZmZXIoKTtcbiAgICBmaW5hbGl6ZVNlZ21lbnQoKTtcbiAgICAvLyB0b2tlbkNhY2hlLnNldChwYXRoLCB0b2tlbnMpXG4gICAgcmV0dXJuIHRva2Vucztcbn1cblxuZnVuY3Rpb24gY3JlYXRlUm91dGVSZWNvcmRNYXRjaGVyKHJlY29yZCwgcGFyZW50LCBvcHRpb25zKSB7XG4gICAgY29uc3QgcGFyc2VyID0gdG9rZW5zVG9QYXJzZXIodG9rZW5pemVQYXRoKHJlY29yZC5wYXRoKSwgb3B0aW9ucyk7XG4gICAgLy8gd2FybiBhZ2FpbnN0IHBhcmFtcyB3aXRoIHRoZSBzYW1lIG5hbWVcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nS2V5cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgcGFyc2VyLmtleXMpIHtcbiAgICAgICAgICAgIGlmIChleGlzdGluZ0tleXMuaGFzKGtleS5uYW1lKSlcbiAgICAgICAgICAgICAgICB3YXJuKGBGb3VuZCBkdXBsaWNhdGVkIHBhcmFtcyB3aXRoIG5hbWUgXCIke2tleS5uYW1lfVwiIGZvciBwYXRoIFwiJHtyZWNvcmQucGF0aH1cIi4gT25seSB0aGUgbGFzdCBvbmUgd2lsbCBiZSBhdmFpbGFibGUgb24gXCIkcm91dGUucGFyYW1zXCIuYCk7XG4gICAgICAgICAgICBleGlzdGluZ0tleXMuYWRkKGtleS5uYW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBtYXRjaGVyID0gYXNzaWduKHBhcnNlciwge1xuICAgICAgICByZWNvcmQsXG4gICAgICAgIHBhcmVudCxcbiAgICAgICAgLy8gdGhlc2UgbmVlZHMgdG8gYmUgcG9wdWxhdGVkIGJ5IHRoZSBwYXJlbnRcbiAgICAgICAgY2hpbGRyZW46IFtdLFxuICAgICAgICBhbGlhczogW10sXG4gICAgfSk7XG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICAvLyBib3RoIGFyZSBhbGlhc2VzIG9yIGJvdGggYXJlIG5vdCBhbGlhc2VzXG4gICAgICAgIC8vIHdlIGRvbid0IHdhbnQgdG8gbWl4IHRoZW0gYmVjYXVzZSB0aGUgb3JkZXIgaXMgdXNlZCB3aGVuXG4gICAgICAgIC8vIHBhc3Npbmcgb3JpZ2luYWxSZWNvcmQgaW4gTWF0Y2hlci5hZGRSb3V0ZVxuICAgICAgICBpZiAoIW1hdGNoZXIucmVjb3JkLmFsaWFzT2YgPT09ICFwYXJlbnQucmVjb3JkLmFsaWFzT2YpXG4gICAgICAgICAgICBwYXJlbnQuY2hpbGRyZW4ucHVzaChtYXRjaGVyKTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXI7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIFJvdXRlciBNYXRjaGVyLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIHJvdXRlcyAtIGFycmF5IG9mIGluaXRpYWwgcm91dGVzXG4gKiBAcGFyYW0gZ2xvYmFsT3B0aW9ucyAtIGdsb2JhbCByb3V0ZSBvcHRpb25zXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVJvdXRlck1hdGNoZXIocm91dGVzLCBnbG9iYWxPcHRpb25zKSB7XG4gICAgLy8gbm9ybWFsaXplZCBvcmRlcmVkIGFycmF5IG9mIG1hdGNoZXJzXG4gICAgY29uc3QgbWF0Y2hlcnMgPSBbXTtcbiAgICBjb25zdCBtYXRjaGVyTWFwID0gbmV3IE1hcCgpO1xuICAgIGdsb2JhbE9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoeyBzdHJpY3Q6IGZhbHNlLCBlbmQ6IHRydWUsIHNlbnNpdGl2ZTogZmFsc2UgfSwgZ2xvYmFsT3B0aW9ucyk7XG4gICAgZnVuY3Rpb24gZ2V0UmVjb3JkTWF0Y2hlcihuYW1lKSB7XG4gICAgICAgIHJldHVybiBtYXRjaGVyTWFwLmdldChuYW1lKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYWRkUm91dGUocmVjb3JkLCBwYXJlbnQsIG9yaWdpbmFsUmVjb3JkKSB7XG4gICAgICAgIC8vIHVzZWQgbGF0ZXIgb24gdG8gcmVtb3ZlIGJ5IG5hbWVcbiAgICAgICAgY29uc3QgaXNSb290QWRkID0gIW9yaWdpbmFsUmVjb3JkO1xuICAgICAgICBjb25zdCBtYWluTm9ybWFsaXplZFJlY29yZCA9IG5vcm1hbGl6ZVJvdXRlUmVjb3JkKHJlY29yZCk7XG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcbiAgICAgICAgICAgIGNoZWNrQ2hpbGRNaXNzaW5nTmFtZVdpdGhFbXB0eVBhdGgobWFpbk5vcm1hbGl6ZWRSZWNvcmQsIHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gd2UgbWlnaHQgYmUgdGhlIGNoaWxkIG9mIGFuIGFsaWFzXG4gICAgICAgIG1haW5Ob3JtYWxpemVkUmVjb3JkLmFsaWFzT2YgPSBvcmlnaW5hbFJlY29yZCAmJiBvcmlnaW5hbFJlY29yZC5yZWNvcmQ7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoZ2xvYmFsT3B0aW9ucywgcmVjb3JkKTtcbiAgICAgICAgLy8gZ2VuZXJhdGUgYW4gYXJyYXkgb2YgcmVjb3JkcyB0byBjb3JyZWN0bHkgaGFuZGxlIGFsaWFzZXNcbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZFJlY29yZHMgPSBbbWFpbk5vcm1hbGl6ZWRSZWNvcmRdO1xuICAgICAgICBpZiAoJ2FsaWFzJyBpbiByZWNvcmQpIHtcbiAgICAgICAgICAgIGNvbnN0IGFsaWFzZXMgPSB0eXBlb2YgcmVjb3JkLmFsaWFzID09PSAnc3RyaW5nJyA/IFtyZWNvcmQuYWxpYXNdIDogcmVjb3JkLmFsaWFzO1xuICAgICAgICAgICAgZm9yIChjb25zdCBhbGlhcyBvZiBhbGlhc2VzKSB7XG4gICAgICAgICAgICAgICAgbm9ybWFsaXplZFJlY29yZHMucHVzaChcbiAgICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRvIG5vcm1hbGl6ZSBhZ2FpbiB0byBlbnN1cmUgdGhlIGBtb2RzYCBwcm9wZXJ0eVxuICAgICAgICAgICAgICAgIC8vIGJlaW5nIG5vbiBlbnVtZXJhYmxlXG4gICAgICAgICAgICAgICAgbm9ybWFsaXplUm91dGVSZWNvcmQoYXNzaWduKHt9LCBtYWluTm9ybWFsaXplZFJlY29yZCwge1xuICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGFsbG93cyB1cyB0byBob2xkIGEgY29weSBvZiB0aGUgYGNvbXBvbmVudHNgIG9wdGlvblxuICAgICAgICAgICAgICAgICAgICAvLyBzbyB0aGF0IGFzeW5jIGNvbXBvbmVudHMgY2FjaGUgaXMgaG9sZCBvbiB0aGUgb3JpZ2luYWwgcmVjb3JkXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHM6IG9yaWdpbmFsUmVjb3JkXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG9yaWdpbmFsUmVjb3JkLnJlY29yZC5jb21wb25lbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICA6IG1haW5Ob3JtYWxpemVkUmVjb3JkLmNvbXBvbmVudHMsXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGFsaWFzLFxuICAgICAgICAgICAgICAgICAgICAvLyB3ZSBtaWdodCBiZSB0aGUgY2hpbGQgb2YgYW4gYWxpYXNcbiAgICAgICAgICAgICAgICAgICAgYWxpYXNPZjogb3JpZ2luYWxSZWNvcmRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gb3JpZ2luYWxSZWNvcmQucmVjb3JkXG4gICAgICAgICAgICAgICAgICAgICAgICA6IG1haW5Ob3JtYWxpemVkUmVjb3JkLFxuICAgICAgICAgICAgICAgICAgICAvLyB0aGUgYWxpYXNlcyBhcmUgYWx3YXlzIG9mIHRoZSBzYW1lIGtpbmQgYXMgdGhlIG9yaWdpbmFsIHNpbmNlIHRoZXlcbiAgICAgICAgICAgICAgICAgICAgLy8gYXJlIGRlZmluZWQgb24gdGhlIHNhbWUgcmVjb3JkXG4gICAgICAgICAgICAgICAgfSkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgbWF0Y2hlcjtcbiAgICAgICAgbGV0IG9yaWdpbmFsTWF0Y2hlcjtcbiAgICAgICAgZm9yIChjb25zdCBub3JtYWxpemVkUmVjb3JkIG9mIG5vcm1hbGl6ZWRSZWNvcmRzKSB7XG4gICAgICAgICAgICBjb25zdCB7IHBhdGggfSA9IG5vcm1hbGl6ZWRSZWNvcmQ7XG4gICAgICAgICAgICAvLyBCdWlsZCB1cCB0aGUgcGF0aCBmb3IgbmVzdGVkIHJvdXRlcyBpZiB0aGUgY2hpbGQgaXNuJ3QgYW4gYWJzb2x1dGVcbiAgICAgICAgICAgIC8vIHJvdXRlLiBPbmx5IGFkZCB0aGUgLyBkZWxpbWl0ZXIgaWYgdGhlIGNoaWxkIHBhdGggaXNuJ3QgZW1wdHkgYW5kIGlmIHRoZVxuICAgICAgICAgICAgLy8gcGFyZW50IHBhdGggZG9lc24ndCBoYXZlIGEgdHJhaWxpbmcgc2xhc2hcbiAgICAgICAgICAgIGlmIChwYXJlbnQgJiYgcGF0aFswXSAhPT0gJy8nKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyZW50UGF0aCA9IHBhcmVudC5yZWNvcmQucGF0aDtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW5nU2xhc2ggPSBwYXJlbnRQYXRoW3BhcmVudFBhdGgubGVuZ3RoIC0gMV0gPT09ICcvJyA/ICcnIDogJy8nO1xuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRSZWNvcmQucGF0aCA9XG4gICAgICAgICAgICAgICAgICAgIHBhcmVudC5yZWNvcmQucGF0aCArIChwYXRoICYmIGNvbm5lY3RpbmdTbGFzaCArIHBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBub3JtYWxpemVkUmVjb3JkLnBhdGggPT09ICcqJykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2F0Y2ggYWxsIHJvdXRlcyAoXCIqXCIpIG11c3Qgbm93IGJlIGRlZmluZWQgdXNpbmcgYSBwYXJhbSB3aXRoIGEgY3VzdG9tIHJlZ2V4cC5cXG4nICtcbiAgICAgICAgICAgICAgICAgICAgJ1NlZSBtb3JlIGF0IGh0dHBzOi8vcm91dGVyLnZ1ZWpzLm9yZy9ndWlkZS9taWdyYXRpb24vI1JlbW92ZWQtc3Rhci1vci1jYXRjaC1hbGwtcm91dGVzLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gY3JlYXRlIHRoZSBvYmplY3QgYmVmb3JlaGFuZCwgc28gaXQgY2FuIGJlIHBhc3NlZCB0byBjaGlsZHJlblxuICAgICAgICAgICAgbWF0Y2hlciA9IGNyZWF0ZVJvdXRlUmVjb3JkTWF0Y2hlcihub3JtYWxpemVkUmVjb3JkLCBwYXJlbnQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBwYXJlbnQgJiYgcGF0aFswXSA9PT0gJy8nKVxuICAgICAgICAgICAgICAgIGNoZWNrTWlzc2luZ1BhcmFtc0luQWJzb2x1dGVQYXRoKG1hdGNoZXIsIHBhcmVudCk7XG4gICAgICAgICAgICAvLyBpZiB3ZSBhcmUgYW4gYWxpYXMgd2UgbXVzdCB0ZWxsIHRoZSBvcmlnaW5hbCByZWNvcmQgdGhhdCB3ZSBleGlzdCxcbiAgICAgICAgICAgIC8vIHNvIHdlIGNhbiBiZSByZW1vdmVkXG4gICAgICAgICAgICBpZiAob3JpZ2luYWxSZWNvcmQpIHtcbiAgICAgICAgICAgICAgICBvcmlnaW5hbFJlY29yZC5hbGlhcy5wdXNoKG1hdGNoZXIpO1xuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hlY2tTYW1lUGFyYW1zKG9yaWdpbmFsUmVjb3JkLCBtYXRjaGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UsIHRoZSBmaXJzdCByZWNvcmQgaXMgdGhlIG9yaWdpbmFsIGFuZCBvdGhlcnMgYXJlIGFsaWFzZXNcbiAgICAgICAgICAgICAgICBvcmlnaW5hbE1hdGNoZXIgPSBvcmlnaW5hbE1hdGNoZXIgfHwgbWF0Y2hlcjtcbiAgICAgICAgICAgICAgICBpZiAob3JpZ2luYWxNYXRjaGVyICE9PSBtYXRjaGVyKVxuICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbE1hdGNoZXIuYWxpYXMucHVzaChtYXRjaGVyKTtcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlIHJvdXRlIGlmIG5hbWVkIGFuZCBvbmx5IGZvciB0aGUgdG9wIHJlY29yZCAoYXZvaWQgaW4gbmVzdGVkIGNhbGxzKVxuICAgICAgICAgICAgICAgIC8vIHRoaXMgd29ya3MgYmVjYXVzZSB0aGUgb3JpZ2luYWwgcmVjb3JkIGlzIHRoZSBmaXJzdCBvbmVcbiAgICAgICAgICAgICAgICBpZiAoaXNSb290QWRkICYmIHJlY29yZC5uYW1lICYmICFpc0FsaWFzUmVjb3JkKG1hdGNoZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrU2FtZU5hbWVBc0FuY2VzdG9yKHJlY29yZCwgcGFyZW50KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZW1vdmVSb3V0ZShyZWNvcmQubmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQXZvaWQgYWRkaW5nIGEgcmVjb3JkIHRoYXQgZG9lc24ndCBkaXNwbGF5IGFueXRoaW5nLiBUaGlzIGFsbG93cyBwYXNzaW5nIHRocm91Z2ggcmVjb3JkcyB3aXRob3V0IGEgY29tcG9uZW50IHRvXG4gICAgICAgICAgICAvLyBub3QgYmUgcmVhY2hlZCBhbmQgcGFzcyB0aHJvdWdoIHRoZSBjYXRjaCBhbGwgcm91dGVcbiAgICAgICAgICAgIGlmIChpc01hdGNoYWJsZShtYXRjaGVyKSkge1xuICAgICAgICAgICAgICAgIGluc2VydE1hdGNoZXIobWF0Y2hlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWFpbk5vcm1hbGl6ZWRSZWNvcmQuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IG1haW5Ob3JtYWxpemVkUmVjb3JkLmNoaWxkcmVuO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkUm91dGUoY2hpbGRyZW5baV0sIG1hdGNoZXIsIG9yaWdpbmFsUmVjb3JkICYmIG9yaWdpbmFsUmVjb3JkLmNoaWxkcmVuW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBpZiB0aGVyZSB3YXMgbm8gb3JpZ2luYWwgcmVjb3JkLCB0aGVuIHRoZSBmaXJzdCBvbmUgd2FzIG5vdCBhbiBhbGlhcyBhbmQgYWxsXG4gICAgICAgICAgICAvLyBvdGhlciBhbGlhc2VzIChpZiBhbnkpIG5lZWQgdG8gcmVmZXJlbmNlIHRoaXMgcmVjb3JkIHdoZW4gYWRkaW5nIGNoaWxkcmVuXG4gICAgICAgICAgICBvcmlnaW5hbFJlY29yZCA9IG9yaWdpbmFsUmVjb3JkIHx8IG1hdGNoZXI7XG4gICAgICAgICAgICAvLyBUT0RPOiBhZGQgbm9ybWFsaXplZCByZWNvcmRzIGZvciBtb3JlIGZsZXhpYmlsaXR5XG4gICAgICAgICAgICAvLyBpZiAocGFyZW50ICYmIGlzQWxpYXNSZWNvcmQob3JpZ2luYWxSZWNvcmQpKSB7XG4gICAgICAgICAgICAvLyAgIHBhcmVudC5jaGlsZHJlbi5wdXNoKG9yaWdpbmFsUmVjb3JkKVxuICAgICAgICAgICAgLy8gfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvcmlnaW5hbE1hdGNoZXJcbiAgICAgICAgICAgID8gKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIHNpbmNlIG90aGVyIG1hdGNoZXJzIGFyZSBhbGlhc2VzLCB0aGV5IHNob3VsZCBiZSByZW1vdmVkIGJ5IHRoZSBvcmlnaW5hbCBtYXRjaGVyXG4gICAgICAgICAgICAgICAgcmVtb3ZlUm91dGUob3JpZ2luYWxNYXRjaGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDogbm9vcDtcbiAgICB9XG4gICAgZnVuY3Rpb24gcmVtb3ZlUm91dGUobWF0Y2hlclJlZikge1xuICAgICAgICBpZiAoaXNSb3V0ZU5hbWUobWF0Y2hlclJlZikpIHtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZXIgPSBtYXRjaGVyTWFwLmdldChtYXRjaGVyUmVmKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGVyKSB7XG4gICAgICAgICAgICAgICAgbWF0Y2hlck1hcC5kZWxldGUobWF0Y2hlclJlZik7XG4gICAgICAgICAgICAgICAgbWF0Y2hlcnMuc3BsaWNlKG1hdGNoZXJzLmluZGV4T2YobWF0Y2hlciksIDEpO1xuICAgICAgICAgICAgICAgIG1hdGNoZXIuY2hpbGRyZW4uZm9yRWFjaChyZW1vdmVSb3V0ZSk7XG4gICAgICAgICAgICAgICAgbWF0Y2hlci5hbGlhcy5mb3JFYWNoKHJlbW92ZVJvdXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gbWF0Y2hlcnMuaW5kZXhPZihtYXRjaGVyUmVmKTtcbiAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgbWF0Y2hlcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2hlclJlZi5yZWNvcmQubmFtZSlcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlck1hcC5kZWxldGUobWF0Y2hlclJlZi5yZWNvcmQubmFtZSk7XG4gICAgICAgICAgICAgICAgbWF0Y2hlclJlZi5jaGlsZHJlbi5mb3JFYWNoKHJlbW92ZVJvdXRlKTtcbiAgICAgICAgICAgICAgICBtYXRjaGVyUmVmLmFsaWFzLmZvckVhY2gocmVtb3ZlUm91dGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIGdldFJvdXRlcygpIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoZXJzO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpbnNlcnRNYXRjaGVyKG1hdGNoZXIpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBmaW5kSW5zZXJ0aW9uSW5kZXgobWF0Y2hlciwgbWF0Y2hlcnMpO1xuICAgICAgICBtYXRjaGVycy5zcGxpY2UoaW5kZXgsIDAsIG1hdGNoZXIpO1xuICAgICAgICAvLyBvbmx5IGFkZCB0aGUgb3JpZ2luYWwgcmVjb3JkIHRvIHRoZSBuYW1lIG1hcFxuICAgICAgICBpZiAobWF0Y2hlci5yZWNvcmQubmFtZSAmJiAhaXNBbGlhc1JlY29yZChtYXRjaGVyKSlcbiAgICAgICAgICAgIG1hdGNoZXJNYXAuc2V0KG1hdGNoZXIucmVjb3JkLm5hbWUsIG1hdGNoZXIpO1xuICAgIH1cbiAgICBmdW5jdGlvbiByZXNvbHZlKGxvY2F0aW9uLCBjdXJyZW50TG9jYXRpb24pIHtcbiAgICAgICAgbGV0IG1hdGNoZXI7XG4gICAgICAgIGxldCBwYXJhbXMgPSB7fTtcbiAgICAgICAgbGV0IHBhdGg7XG4gICAgICAgIGxldCBuYW1lO1xuICAgICAgICBpZiAoJ25hbWUnIGluIGxvY2F0aW9uICYmIGxvY2F0aW9uLm5hbWUpIHtcbiAgICAgICAgICAgIG1hdGNoZXIgPSBtYXRjaGVyTWFwLmdldChsb2NhdGlvbi5uYW1lKTtcbiAgICAgICAgICAgIGlmICghbWF0Y2hlcilcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVSb3V0ZXJFcnJvcigxIC8qIEVycm9yVHlwZXMuTUFUQ0hFUl9OT1RfRk9VTkQgKi8sIHtcbiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyB3YXJuIGlmIHRoZSB1c2VyIGlzIHBhc3NpbmcgaW52YWxpZCBwYXJhbXMgc28gdGhleSBjYW4gZGVidWcgaXQgYmV0dGVyIHdoZW4gdGhleSBnZXQgcmVtb3ZlZFxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGludmFsaWRQYXJhbXMgPSBPYmplY3Qua2V5cyhsb2NhdGlvbi5wYXJhbXMgfHwge30pLmZpbHRlcihwYXJhbU5hbWUgPT4gIW1hdGNoZXIua2V5cy5maW5kKGsgPT4gay5uYW1lID09PSBwYXJhbU5hbWUpKTtcbiAgICAgICAgICAgICAgICBpZiAoaW52YWxpZFBhcmFtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgd2FybihgRGlzY2FyZGVkIGludmFsaWQgcGFyYW0ocykgXCIke2ludmFsaWRQYXJhbXMuam9pbignXCIsIFwiJyl9XCIgd2hlbiBuYXZpZ2F0aW5nLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3Z1ZWpzL3JvdXRlci9ibG9iL21haW4vcGFja2FnZXMvcm91dGVyL0NIQU5HRUxPRy5tZCM0MTQtMjAyMi0wOC0yMiBmb3IgbW9yZSBkZXRhaWxzLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5hbWUgPSBtYXRjaGVyLnJlY29yZC5uYW1lO1xuICAgICAgICAgICAgcGFyYW1zID0gYXNzaWduKFxuICAgICAgICAgICAgLy8gcGFyYW1zRnJvbUxvY2F0aW9uIGlzIGEgbmV3IG9iamVjdFxuICAgICAgICAgICAgcGFyYW1zRnJvbUxvY2F0aW9uKGN1cnJlbnRMb2NhdGlvbi5wYXJhbXMsIFxuICAgICAgICAgICAgLy8gb25seSBrZWVwIHBhcmFtcyB0aGF0IGV4aXN0IGluIHRoZSByZXNvbHZlZCBsb2NhdGlvblxuICAgICAgICAgICAgLy8gb25seSBrZWVwIG9wdGlvbmFsIHBhcmFtcyBjb21pbmcgZnJvbSBhIHBhcmVudCByZWNvcmRcbiAgICAgICAgICAgIG1hdGNoZXIua2V5c1xuICAgICAgICAgICAgICAgIC5maWx0ZXIoayA9PiAhay5vcHRpb25hbClcbiAgICAgICAgICAgICAgICAuY29uY2F0KG1hdGNoZXIucGFyZW50ID8gbWF0Y2hlci5wYXJlbnQua2V5cy5maWx0ZXIoayA9PiBrLm9wdGlvbmFsKSA6IFtdKVxuICAgICAgICAgICAgICAgIC5tYXAoayA9PiBrLm5hbWUpKSwgXG4gICAgICAgICAgICAvLyBkaXNjYXJkIGFueSBleGlzdGluZyBwYXJhbXMgaW4gdGhlIGN1cnJlbnQgbG9jYXRpb24gdGhhdCBkbyBub3QgZXhpc3QgaGVyZVxuICAgICAgICAgICAgLy8gIzE0OTcgdGhpcyBlbnN1cmVzIGJldHRlciBhY3RpdmUvZXhhY3QgbWF0Y2hpbmdcbiAgICAgICAgICAgIGxvY2F0aW9uLnBhcmFtcyAmJlxuICAgICAgICAgICAgICAgIHBhcmFtc0Zyb21Mb2NhdGlvbihsb2NhdGlvbi5wYXJhbXMsIG1hdGNoZXIua2V5cy5tYXAoayA9PiBrLm5hbWUpKSk7XG4gICAgICAgICAgICAvLyB0aHJvd3MgaWYgY2Fubm90IGJlIHN0cmluZ2lmaWVkXG4gICAgICAgICAgICBwYXRoID0gbWF0Y2hlci5zdHJpbmdpZnkocGFyYW1zKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChsb2NhdGlvbi5wYXRoICE9IG51bGwpIHtcbiAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gcmVzb2x2ZSB0aGUgcGF0aCB3aXRoIHRoZSBtYXRjaGVyIGFzIGl0IHdhcyBwcm92aWRlZFxuICAgICAgICAgICAgLy8gdGhpcyBhbHNvIGFsbG93cyB0aGUgdXNlciB0byBjb250cm9sIHRoZSBlbmNvZGluZ1xuICAgICAgICAgICAgcGF0aCA9IGxvY2F0aW9uLnBhdGg7XG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFwYXRoLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgICAgICAgICAgICAgIHdhcm4oYFRoZSBNYXRjaGVyIGNhbm5vdCByZXNvbHZlIHJlbGF0aXZlIHBhdGhzIGJ1dCByZWNlaXZlZCBcIiR7cGF0aH1cIi4gVW5sZXNzIHlvdSBkaXJlY3RseSBjYWxsZWQgXFxgbWF0Y2hlci5yZXNvbHZlKFwiJHtwYXRofVwiKVxcYCwgdGhpcyBpcyBwcm9iYWJseSBhIGJ1ZyBpbiB2dWUtcm91dGVyLiBQbGVhc2Ugb3BlbiBhbiBpc3N1ZSBhdCBodHRwczovL2dpdGh1Yi5jb20vdnVlanMvcm91dGVyL2lzc3Vlcy9uZXcvY2hvb3NlLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWF0Y2hlciA9IG1hdGNoZXJzLmZpbmQobSA9PiBtLnJlLnRlc3QocGF0aCkpO1xuICAgICAgICAgICAgLy8gbWF0Y2hlciBzaG91bGQgaGF2ZSBhIHZhbHVlIGFmdGVyIHRoZSBsb29wXG4gICAgICAgICAgICBpZiAobWF0Y2hlcikge1xuICAgICAgICAgICAgICAgIC8vIHdlIGtub3cgdGhlIG1hdGNoZXIgd29ya3MgYmVjYXVzZSB3ZSB0ZXN0ZWQgdGhlIHJlZ2V4cFxuICAgICAgICAgICAgICAgIHBhcmFtcyA9IG1hdGNoZXIucGFyc2UocGF0aCk7XG4gICAgICAgICAgICAgICAgbmFtZSA9IG1hdGNoZXIucmVjb3JkLm5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBsb2NhdGlvbiBpcyBhIHJlbGF0aXZlIHBhdGhcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIG1hdGNoIGJ5IG5hbWUgb3IgcGF0aCBvZiBjdXJyZW50IHJvdXRlXG4gICAgICAgICAgICBtYXRjaGVyID0gY3VycmVudExvY2F0aW9uLm5hbWVcbiAgICAgICAgICAgICAgICA/IG1hdGNoZXJNYXAuZ2V0KGN1cnJlbnRMb2NhdGlvbi5uYW1lKVxuICAgICAgICAgICAgICAgIDogbWF0Y2hlcnMuZmluZChtID0+IG0ucmUudGVzdChjdXJyZW50TG9jYXRpb24ucGF0aCkpO1xuICAgICAgICAgICAgaWYgKCFtYXRjaGVyKVxuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZVJvdXRlckVycm9yKDEgLyogRXJyb3JUeXBlcy5NQVRDSEVSX05PVF9GT1VORCAqLywge1xuICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudExvY2F0aW9uLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbmFtZSA9IG1hdGNoZXIucmVjb3JkLm5hbWU7XG4gICAgICAgICAgICAvLyBzaW5jZSB3ZSBhcmUgbmF2aWdhdGluZyB0byB0aGUgc2FtZSBsb2NhdGlvbiwgd2UgZG9uJ3QgbmVlZCB0byBwaWNrIHRoZVxuICAgICAgICAgICAgLy8gcGFyYW1zIGxpa2Ugd2hlbiBgbmFtZWAgaXMgcHJvdmlkZWRcbiAgICAgICAgICAgIHBhcmFtcyA9IGFzc2lnbih7fSwgY3VycmVudExvY2F0aW9uLnBhcmFtcywgbG9jYXRpb24ucGFyYW1zKTtcbiAgICAgICAgICAgIHBhdGggPSBtYXRjaGVyLnN0cmluZ2lmeShwYXJhbXMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hdGNoZWQgPSBbXTtcbiAgICAgICAgbGV0IHBhcmVudE1hdGNoZXIgPSBtYXRjaGVyO1xuICAgICAgICB3aGlsZSAocGFyZW50TWF0Y2hlcikge1xuICAgICAgICAgICAgLy8gcmV2ZXJzZWQgb3JkZXIgc28gcGFyZW50cyBhcmUgYXQgdGhlIGJlZ2lubmluZ1xuICAgICAgICAgICAgbWF0Y2hlZC51bnNoaWZ0KHBhcmVudE1hdGNoZXIucmVjb3JkKTtcbiAgICAgICAgICAgIHBhcmVudE1hdGNoZXIgPSBwYXJlbnRNYXRjaGVyLnBhcmVudDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBwYXJhbXMsXG4gICAgICAgICAgICBtYXRjaGVkLFxuICAgICAgICAgICAgbWV0YTogbWVyZ2VNZXRhRmllbGRzKG1hdGNoZWQpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBhZGQgaW5pdGlhbCByb3V0ZXNcbiAgICByb3V0ZXMuZm9yRWFjaChyb3V0ZSA9PiBhZGRSb3V0ZShyb3V0ZSkpO1xuICAgIGZ1bmN0aW9uIGNsZWFyUm91dGVzKCkge1xuICAgICAgICBtYXRjaGVycy5sZW5ndGggPSAwO1xuICAgICAgICBtYXRjaGVyTWFwLmNsZWFyKCk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIGFkZFJvdXRlLFxuICAgICAgICByZXNvbHZlLFxuICAgICAgICByZW1vdmVSb3V0ZSxcbiAgICAgICAgY2xlYXJSb3V0ZXMsXG4gICAgICAgIGdldFJvdXRlcyxcbiAgICAgICAgZ2V0UmVjb3JkTWF0Y2hlcixcbiAgICB9O1xufVxuZnVuY3Rpb24gcGFyYW1zRnJvbUxvY2F0aW9uKHBhcmFtcywga2V5cykge1xuICAgIGNvbnN0IG5ld1BhcmFtcyA9IHt9O1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgICAgaWYgKGtleSBpbiBwYXJhbXMpXG4gICAgICAgICAgICBuZXdQYXJhbXNba2V5XSA9IHBhcmFtc1trZXldO1xuICAgIH1cbiAgICByZXR1cm4gbmV3UGFyYW1zO1xufVxuLyoqXG4gKiBOb3JtYWxpemVzIGEgUm91dGVSZWNvcmRSYXcuIENyZWF0ZXMgYSBjb3B5XG4gKlxuICogQHBhcmFtIHJlY29yZFxuICogQHJldHVybnMgdGhlIG5vcm1hbGl6ZWQgdmVyc2lvblxuICovXG5mdW5jdGlvbiBub3JtYWxpemVSb3V0ZVJlY29yZChyZWNvcmQpIHtcbiAgICBjb25zdCBub3JtYWxpemVkID0ge1xuICAgICAgICBwYXRoOiByZWNvcmQucGF0aCxcbiAgICAgICAgcmVkaXJlY3Q6IHJlY29yZC5yZWRpcmVjdCxcbiAgICAgICAgbmFtZTogcmVjb3JkLm5hbWUsXG4gICAgICAgIG1ldGE6IHJlY29yZC5tZXRhIHx8IHt9LFxuICAgICAgICBhbGlhc09mOiByZWNvcmQuYWxpYXNPZixcbiAgICAgICAgYmVmb3JlRW50ZXI6IHJlY29yZC5iZWZvcmVFbnRlcixcbiAgICAgICAgcHJvcHM6IG5vcm1hbGl6ZVJlY29yZFByb3BzKHJlY29yZCksXG4gICAgICAgIGNoaWxkcmVuOiByZWNvcmQuY2hpbGRyZW4gfHwgW10sXG4gICAgICAgIGluc3RhbmNlczoge30sXG4gICAgICAgIGxlYXZlR3VhcmRzOiBuZXcgU2V0KCksXG4gICAgICAgIHVwZGF0ZUd1YXJkczogbmV3IFNldCgpLFxuICAgICAgICBlbnRlckNhbGxiYWNrczoge30sXG4gICAgICAgIC8vIG11c3QgYmUgZGVjbGFyZWQgYWZ0ZXJ3YXJkc1xuICAgICAgICAvLyBtb2RzOiB7fSxcbiAgICAgICAgY29tcG9uZW50czogJ2NvbXBvbmVudHMnIGluIHJlY29yZFxuICAgICAgICAgICAgPyByZWNvcmQuY29tcG9uZW50cyB8fCBudWxsXG4gICAgICAgICAgICA6IHJlY29yZC5jb21wb25lbnQgJiYgeyBkZWZhdWx0OiByZWNvcmQuY29tcG9uZW50IH0sXG4gICAgfTtcbiAgICAvLyBtb2RzIGNvbnRhaW4gbW9kdWxlcyBhbmQgc2hvdWxkbid0IGJlIGNvcGllZCxcbiAgICAvLyBsb2dnZWQgb3IgYW55dGhpbmcuIEl0J3MganVzdCB1c2VkIGZvciBpbnRlcm5hbFxuICAgIC8vIGFkdmFuY2VkIHVzZSBjYXNlcyBsaWtlIGRhdGEgbG9hZGVyc1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShub3JtYWxpemVkLCAnbW9kcycsIHtcbiAgICAgICAgdmFsdWU6IHt9LFxuICAgIH0pO1xuICAgIHJldHVybiBub3JtYWxpemVkO1xufVxuLyoqXG4gKiBOb3JtYWxpemUgdGhlIG9wdGlvbmFsIGBwcm9wc2AgaW4gYSByZWNvcmQgdG8gYWx3YXlzIGJlIGFuIG9iamVjdCBzaW1pbGFyIHRvXG4gKiBjb21wb25lbnRzLiBBbHNvIGFjY2VwdCBhIGJvb2xlYW4gZm9yIGNvbXBvbmVudHMuXG4gKiBAcGFyYW0gcmVjb3JkXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJlY29yZFByb3BzKHJlY29yZCkge1xuICAgIGNvbnN0IHByb3BzT2JqZWN0ID0ge307XG4gICAgLy8gcHJvcHMgZG9lcyBub3QgZXhpc3Qgb24gcmVkaXJlY3QgcmVjb3JkcywgYnV0IHdlIGNhbiBzZXQgZmFsc2UgZGlyZWN0bHlcbiAgICBjb25zdCBwcm9wcyA9IHJlY29yZC5wcm9wcyB8fCBmYWxzZTtcbiAgICBpZiAoJ2NvbXBvbmVudCcgaW4gcmVjb3JkKSB7XG4gICAgICAgIHByb3BzT2JqZWN0LmRlZmF1bHQgPSBwcm9wcztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIE5PVEU6IHdlIGNvdWxkIGFsc28gYWxsb3cgYSBmdW5jdGlvbiB0byBiZSBhcHBsaWVkIHRvIGV2ZXJ5IGNvbXBvbmVudC5cbiAgICAgICAgLy8gV291bGQgbmVlZCB1c2VyIGZlZWRiYWNrIGZvciB1c2UgY2FzZXNcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIHJlY29yZC5jb21wb25lbnRzKVxuICAgICAgICAgICAgcHJvcHNPYmplY3RbbmFtZV0gPSB0eXBlb2YgcHJvcHMgPT09ICdvYmplY3QnID8gcHJvcHNbbmFtZV0gOiBwcm9wcztcbiAgICB9XG4gICAgcmV0dXJuIHByb3BzT2JqZWN0O1xufVxuLyoqXG4gKiBDaGVja3MgaWYgYSByZWNvcmQgb3IgYW55IG9mIGl0cyBwYXJlbnQgaXMgYW4gYWxpYXNcbiAqIEBwYXJhbSByZWNvcmRcbiAqL1xuZnVuY3Rpb24gaXNBbGlhc1JlY29yZChyZWNvcmQpIHtcbiAgICB3aGlsZSAocmVjb3JkKSB7XG4gICAgICAgIGlmIChyZWNvcmQucmVjb3JkLmFsaWFzT2YpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmVjb3JkID0gcmVjb3JkLnBhcmVudDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuLyoqXG4gKiBNZXJnZSBtZXRhIGZpZWxkcyBvZiBhbiBhcnJheSBvZiByZWNvcmRzXG4gKlxuICogQHBhcmFtIG1hdGNoZWQgLSBhcnJheSBvZiBtYXRjaGVkIHJlY29yZHNcbiAqL1xuZnVuY3Rpb24gbWVyZ2VNZXRhRmllbGRzKG1hdGNoZWQpIHtcbiAgICByZXR1cm4gbWF0Y2hlZC5yZWR1Y2UoKG1ldGEsIHJlY29yZCkgPT4gYXNzaWduKG1ldGEsIHJlY29yZC5tZXRhKSwge30pO1xufVxuZnVuY3Rpb24gbWVyZ2VPcHRpb25zKGRlZmF1bHRzLCBwYXJ0aWFsT3B0aW9ucykge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBkZWZhdWx0cykge1xuICAgICAgICBvcHRpb25zW2tleV0gPSBrZXkgaW4gcGFydGlhbE9wdGlvbnMgPyBwYXJ0aWFsT3B0aW9uc1trZXldIDogZGVmYXVsdHNba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIG9wdGlvbnM7XG59XG5mdW5jdGlvbiBpc1NhbWVQYXJhbShhLCBiKSB7XG4gICAgcmV0dXJuIChhLm5hbWUgPT09IGIubmFtZSAmJlxuICAgICAgICBhLm9wdGlvbmFsID09PSBiLm9wdGlvbmFsICYmXG4gICAgICAgIGEucmVwZWF0YWJsZSA9PT0gYi5yZXBlYXRhYmxlKTtcbn1cbi8qKlxuICogQ2hlY2sgaWYgYSBwYXRoIGFuZCBpdHMgYWxpYXMgaGF2ZSB0aGUgc2FtZSByZXF1aXJlZCBwYXJhbXNcbiAqXG4gKiBAcGFyYW0gYSAtIG9yaWdpbmFsIHJlY29yZFxuICogQHBhcmFtIGIgLSBhbGlhcyByZWNvcmRcbiAqL1xuZnVuY3Rpb24gY2hlY2tTYW1lUGFyYW1zKGEsIGIpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBhLmtleXMpIHtcbiAgICAgICAgaWYgKCFrZXkub3B0aW9uYWwgJiYgIWIua2V5cy5maW5kKGlzU2FtZVBhcmFtLmJpbmQobnVsbCwga2V5KSkpXG4gICAgICAgICAgICByZXR1cm4gd2FybihgQWxpYXMgXCIke2IucmVjb3JkLnBhdGh9XCIgYW5kIHRoZSBvcmlnaW5hbCByZWNvcmQ6IFwiJHthLnJlY29yZC5wYXRofVwiIG11c3QgaGF2ZSB0aGUgZXhhY3Qgc2FtZSBwYXJhbSBuYW1lZCBcIiR7a2V5Lm5hbWV9XCJgKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBrZXkgb2YgYi5rZXlzKSB7XG4gICAgICAgIGlmICgha2V5Lm9wdGlvbmFsICYmICFhLmtleXMuZmluZChpc1NhbWVQYXJhbS5iaW5kKG51bGwsIGtleSkpKVxuICAgICAgICAgICAgcmV0dXJuIHdhcm4oYEFsaWFzIFwiJHtiLnJlY29yZC5wYXRofVwiIGFuZCB0aGUgb3JpZ2luYWwgcmVjb3JkOiBcIiR7YS5yZWNvcmQucGF0aH1cIiBtdXN0IGhhdmUgdGhlIGV4YWN0IHNhbWUgcGFyYW0gbmFtZWQgXCIke2tleS5uYW1lfVwiYCk7XG4gICAgfVxufVxuLyoqXG4gKiBBIHJvdXRlIHdpdGggYSBuYW1lIGFuZCBhIGNoaWxkIHdpdGggYW4gZW1wdHkgcGF0aCB3aXRob3V0IGEgbmFtZSBzaG91bGQgd2FybiB3aGVuIGFkZGluZyB0aGUgcm91dGVcbiAqXG4gKiBAcGFyYW0gbWFpbk5vcm1hbGl6ZWRSZWNvcmQgLSBSb3V0ZVJlY29yZE5vcm1hbGl6ZWRcbiAqIEBwYXJhbSBwYXJlbnQgLSBSb3V0ZVJlY29yZE1hdGNoZXJcbiAqL1xuZnVuY3Rpb24gY2hlY2tDaGlsZE1pc3NpbmdOYW1lV2l0aEVtcHR5UGF0aChtYWluTm9ybWFsaXplZFJlY29yZCwgcGFyZW50KSB7XG4gICAgaWYgKHBhcmVudCAmJlxuICAgICAgICBwYXJlbnQucmVjb3JkLm5hbWUgJiZcbiAgICAgICAgIW1haW5Ob3JtYWxpemVkUmVjb3JkLm5hbWUgJiZcbiAgICAgICAgIW1haW5Ob3JtYWxpemVkUmVjb3JkLnBhdGgpIHtcbiAgICAgICAgd2FybihgVGhlIHJvdXRlIG5hbWVkIFwiJHtTdHJpbmcocGFyZW50LnJlY29yZC5uYW1lKX1cIiBoYXMgYSBjaGlsZCB3aXRob3V0IGEgbmFtZSBhbmQgYW4gZW1wdHkgcGF0aC4gVXNpbmcgdGhhdCBuYW1lIHdvbid0IHJlbmRlciB0aGUgZW1wdHkgcGF0aCBjaGlsZCBzbyB5b3UgcHJvYmFibHkgd2FudCB0byBtb3ZlIHRoZSBuYW1lIHRvIHRoZSBjaGlsZCBpbnN0ZWFkLiBJZiB0aGlzIGlzIGludGVudGlvbmFsLCBhZGQgYSBuYW1lIHRvIHRoZSBjaGlsZCByb3V0ZSB0byByZW1vdmUgdGhlIHdhcm5pbmcuYCk7XG4gICAgfVxufVxuZnVuY3Rpb24gY2hlY2tTYW1lTmFtZUFzQW5jZXN0b3IocmVjb3JkLCBwYXJlbnQpIHtcbiAgICBmb3IgKGxldCBhbmNlc3RvciA9IHBhcmVudDsgYW5jZXN0b3I7IGFuY2VzdG9yID0gYW5jZXN0b3IucGFyZW50KSB7XG4gICAgICAgIGlmIChhbmNlc3Rvci5yZWNvcmQubmFtZSA9PT0gcmVjb3JkLm5hbWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQSByb3V0ZSBuYW1lZCBcIiR7U3RyaW5nKHJlY29yZC5uYW1lKX1cIiBoYXMgYmVlbiBhZGRlZCBhcyBhICR7cGFyZW50ID09PSBhbmNlc3RvciA/ICdjaGlsZCcgOiAnZGVzY2VuZGFudCd9IG9mIGEgcm91dGUgd2l0aCB0aGUgc2FtZSBuYW1lLiBSb3V0ZSBuYW1lcyBtdXN0IGJlIHVuaXF1ZSBhbmQgYSBuZXN0ZWQgcm91dGUgY2Fubm90IHVzZSB0aGUgc2FtZSBuYW1lIGFzIGFuIGFuY2VzdG9yLmApO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gY2hlY2tNaXNzaW5nUGFyYW1zSW5BYnNvbHV0ZVBhdGgocmVjb3JkLCBwYXJlbnQpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBwYXJlbnQua2V5cykge1xuICAgICAgICBpZiAoIXJlY29yZC5rZXlzLmZpbmQoaXNTYW1lUGFyYW0uYmluZChudWxsLCBrZXkpKSlcbiAgICAgICAgICAgIHJldHVybiB3YXJuKGBBYnNvbHV0ZSBwYXRoIFwiJHtyZWNvcmQucmVjb3JkLnBhdGh9XCIgbXVzdCBoYXZlIHRoZSBleGFjdCBzYW1lIHBhcmFtIG5hbWVkIFwiJHtrZXkubmFtZX1cIiBhcyBpdHMgcGFyZW50IFwiJHtwYXJlbnQucmVjb3JkLnBhdGh9XCIuYCk7XG4gICAgfVxufVxuLyoqXG4gKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggdG8gZmluZCB0aGUgY29ycmVjdCBpbnNlcnRpb24gaW5kZXggZm9yIGEgbmV3IG1hdGNoZXIuXG4gKlxuICogTWF0Y2hlcnMgYXJlIHByaW1hcmlseSBzb3J0ZWQgYnkgdGhlaXIgc2NvcmUuIElmIHNjb3JlcyBhcmUgdGllZCB0aGVuIHdlIGFsc28gY29uc2lkZXIgcGFyZW50L2NoaWxkIHJlbGF0aW9uc2hpcHMsXG4gKiB3aXRoIGRlc2NlbmRhbnRzIGNvbWluZyBiZWZvcmUgYW5jZXN0b3JzLiBJZiB0aGVyZSdzIHN0aWxsIGEgdGllLCBuZXcgcm91dGVzIGFyZSBpbnNlcnRlZCBhZnRlciBleGlzdGluZyByb3V0ZXMuXG4gKlxuICogQHBhcmFtIG1hdGNoZXIgLSBuZXcgbWF0Y2hlciB0byBiZSBpbnNlcnRlZFxuICogQHBhcmFtIG1hdGNoZXJzIC0gZXhpc3RpbmcgbWF0Y2hlcnNcbiAqL1xuZnVuY3Rpb24gZmluZEluc2VydGlvbkluZGV4KG1hdGNoZXIsIG1hdGNoZXJzKSB7XG4gICAgLy8gRmlyc3QgcGhhc2U6IGJpbmFyeSBzZWFyY2ggYmFzZWQgb24gc2NvcmVcbiAgICBsZXQgbG93ZXIgPSAwO1xuICAgIGxldCB1cHBlciA9IG1hdGNoZXJzLmxlbmd0aDtcbiAgICB3aGlsZSAobG93ZXIgIT09IHVwcGVyKSB7XG4gICAgICAgIGNvbnN0IG1pZCA9IChsb3dlciArIHVwcGVyKSA+PiAxO1xuICAgICAgICBjb25zdCBzb3J0T3JkZXIgPSBjb21wYXJlUGF0aFBhcnNlclNjb3JlKG1hdGNoZXIsIG1hdGNoZXJzW21pZF0pO1xuICAgICAgICBpZiAoc29ydE9yZGVyIDwgMCkge1xuICAgICAgICAgICAgdXBwZXIgPSBtaWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsb3dlciA9IG1pZCArIDE7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gU2Vjb25kIHBoYXNlOiBjaGVjayBmb3IgYW4gYW5jZXN0b3Igd2l0aCB0aGUgc2FtZSBzY29yZVxuICAgIGNvbnN0IGluc2VydGlvbkFuY2VzdG9yID0gZ2V0SW5zZXJ0aW9uQW5jZXN0b3IobWF0Y2hlcik7XG4gICAgaWYgKGluc2VydGlvbkFuY2VzdG9yKSB7XG4gICAgICAgIHVwcGVyID0gbWF0Y2hlcnMubGFzdEluZGV4T2YoaW5zZXJ0aW9uQW5jZXN0b3IsIHVwcGVyIC0gMSk7XG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgdXBwZXIgPCAwKSB7XG4gICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW5cbiAgICAgICAgICAgIHdhcm4oYEZpbmRpbmcgYW5jZXN0b3Igcm91dGUgXCIke2luc2VydGlvbkFuY2VzdG9yLnJlY29yZC5wYXRofVwiIGZhaWxlZCBmb3IgXCIke21hdGNoZXIucmVjb3JkLnBhdGh9XCJgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdXBwZXI7XG59XG5mdW5jdGlvbiBnZXRJbnNlcnRpb25BbmNlc3RvcihtYXRjaGVyKSB7XG4gICAgbGV0IGFuY2VzdG9yID0gbWF0Y2hlcjtcbiAgICB3aGlsZSAoKGFuY2VzdG9yID0gYW5jZXN0b3IucGFyZW50KSkge1xuICAgICAgICBpZiAoaXNNYXRjaGFibGUoYW5jZXN0b3IpICYmXG4gICAgICAgICAgICBjb21wYXJlUGF0aFBhcnNlclNjb3JlKG1hdGNoZXIsIGFuY2VzdG9yKSA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGFuY2VzdG9yO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybjtcbn1cbi8qKlxuICogQ2hlY2tzIGlmIGEgbWF0Y2hlciBjYW4gYmUgcmVhY2hhYmxlLiBUaGlzIG1lYW5zIGlmIGl0J3MgcG9zc2libGUgdG8gcmVhY2ggaXQgYXMgYSByb3V0ZS4gRm9yIGV4YW1wbGUsIHJvdXRlcyB3aXRob3V0XG4gKiBhIGNvbXBvbmVudCwgb3IgbmFtZSwgb3IgcmVkaXJlY3QsIGFyZSBqdXN0IHVzZWQgdG8gZ3JvdXAgb3RoZXIgcm91dGVzLlxuICogQHBhcmFtIG1hdGNoZXJcbiAqIEBwYXJhbSBtYXRjaGVyLnJlY29yZCByZWNvcmQgb2YgdGhlIG1hdGNoZXJcbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGlzTWF0Y2hhYmxlKHsgcmVjb3JkIH0pIHtcbiAgICByZXR1cm4gISEocmVjb3JkLm5hbWUgfHxcbiAgICAgICAgKHJlY29yZC5jb21wb25lbnRzICYmIE9iamVjdC5rZXlzKHJlY29yZC5jb21wb25lbnRzKS5sZW5ndGgpIHx8XG4gICAgICAgIHJlY29yZC5yZWRpcmVjdCk7XG59XG5cbi8qKlxuICogVHJhbnNmb3JtcyBhIHF1ZXJ5U3RyaW5nIGludG8gYSB7QGxpbmsgTG9jYXRpb25RdWVyeX0gb2JqZWN0LiBBY2NlcHQgYm90aCwgYVxuICogdmVyc2lvbiB3aXRoIHRoZSBsZWFkaW5nIGA/YCBhbmQgd2l0aG91dCBTaG91bGQgd29yayBhcyBVUkxTZWFyY2hQYXJhbXNcblxuICogQGludGVybmFsXG4gKlxuICogQHBhcmFtIHNlYXJjaCAtIHNlYXJjaCBzdHJpbmcgdG8gcGFyc2VcbiAqIEByZXR1cm5zIGEgcXVlcnkgb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIHBhcnNlUXVlcnkoc2VhcmNoKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7fTtcbiAgICAvLyBhdm9pZCBjcmVhdGluZyBhbiBvYmplY3Qgd2l0aCBhbiBlbXB0eSBrZXkgYW5kIGVtcHR5IHZhbHVlXG4gICAgLy8gYmVjYXVzZSBvZiBzcGxpdCgnJicpXG4gICAgaWYgKHNlYXJjaCA9PT0gJycgfHwgc2VhcmNoID09PSAnPycpXG4gICAgICAgIHJldHVybiBxdWVyeTtcbiAgICBjb25zdCBoYXNMZWFkaW5nSU0gPSBzZWFyY2hbMF0gPT09ICc/JztcbiAgICBjb25zdCBzZWFyY2hQYXJhbXMgPSAoaGFzTGVhZGluZ0lNID8gc2VhcmNoLnNsaWNlKDEpIDogc2VhcmNoKS5zcGxpdCgnJicpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VhcmNoUGFyYW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIC8vIHByZSBkZWNvZGUgdGhlICsgaW50byBzcGFjZVxuICAgICAgICBjb25zdCBzZWFyY2hQYXJhbSA9IHNlYXJjaFBhcmFtc1tpXS5yZXBsYWNlKFBMVVNfUkUsICcgJyk7XG4gICAgICAgIC8vIGFsbG93IHRoZSA9IGNoYXJhY3RlclxuICAgICAgICBjb25zdCBlcVBvcyA9IHNlYXJjaFBhcmFtLmluZGV4T2YoJz0nKTtcbiAgICAgICAgY29uc3Qga2V5ID0gZGVjb2RlKGVxUG9zIDwgMCA/IHNlYXJjaFBhcmFtIDogc2VhcmNoUGFyYW0uc2xpY2UoMCwgZXFQb3MpKTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBlcVBvcyA8IDAgPyBudWxsIDogZGVjb2RlKHNlYXJjaFBhcmFtLnNsaWNlKGVxUG9zICsgMSkpO1xuICAgICAgICBpZiAoa2V5IGluIHF1ZXJ5KSB7XG4gICAgICAgICAgICAvLyBhbiBleHRyYSB2YXJpYWJsZSBmb3IgdHMgdHlwZXNcbiAgICAgICAgICAgIGxldCBjdXJyZW50VmFsdWUgPSBxdWVyeVtrZXldO1xuICAgICAgICAgICAgaWYgKCFpc0FycmF5KGN1cnJlbnRWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50VmFsdWUgPSBxdWVyeVtrZXldID0gW2N1cnJlbnRWYWx1ZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJyZW50VmFsdWUucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBxdWVyeVtrZXldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHF1ZXJ5O1xufVxuLyoqXG4gKiBTdHJpbmdpZmllcyBhIHtAbGluayBMb2NhdGlvblF1ZXJ5UmF3fSBvYmplY3QuIExpa2UgYFVSTFNlYXJjaFBhcmFtc2AsIGl0XG4gKiBkb2Vzbid0IHByZXBlbmQgYSBgP2BcbiAqXG4gKiBAaW50ZXJuYWxcbiAqXG4gKiBAcGFyYW0gcXVlcnkgLSBxdWVyeSBvYmplY3QgdG8gc3RyaW5naWZ5XG4gKiBAcmV0dXJucyBzdHJpbmcgdmVyc2lvbiBvZiB0aGUgcXVlcnkgd2l0aG91dCB0aGUgbGVhZGluZyBgP2BcbiAqL1xuZnVuY3Rpb24gc3RyaW5naWZ5UXVlcnkocXVlcnkpIHtcbiAgICBsZXQgc2VhcmNoID0gJyc7XG4gICAgZm9yIChsZXQga2V5IGluIHF1ZXJ5KSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcXVlcnlba2V5XTtcbiAgICAgICAga2V5ID0gZW5jb2RlUXVlcnlLZXkoa2V5KTtcbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIG9ubHkgbnVsbCBhZGRzIHRoZSB2YWx1ZVxuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBzZWFyY2ggKz0gKHNlYXJjaC5sZW5ndGggPyAnJicgOiAnJykgKyBrZXk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBrZWVwIG51bGwgdmFsdWVzXG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IGlzQXJyYXkodmFsdWUpXG4gICAgICAgICAgICA/IHZhbHVlLm1hcCh2ID0+IHYgJiYgZW5jb2RlUXVlcnlWYWx1ZSh2KSlcbiAgICAgICAgICAgIDogW3ZhbHVlICYmIGVuY29kZVF1ZXJ5VmFsdWUodmFsdWUpXTtcbiAgICAgICAgdmFsdWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgICAgICAgLy8gc2tpcCB1bmRlZmluZWQgdmFsdWVzIGluIGFycmF5cyBhcyBpZiB0aGV5IHdlcmUgbm90IHByZXNlbnRcbiAgICAgICAgICAgIC8vIHNtYWxsZXIgY29kZSB0aGFuIHVzaW5nIGZpbHRlclxuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBvbmx5IGFwcGVuZCAmIHdpdGggbm9uLWVtcHR5IHNlYXJjaFxuICAgICAgICAgICAgICAgIHNlYXJjaCArPSAoc2VhcmNoLmxlbmd0aCA/ICcmJyA6ICcnKSArIGtleTtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgc2VhcmNoICs9ICc9JyArIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHNlYXJjaDtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyBhIHtAbGluayBMb2NhdGlvblF1ZXJ5UmF3fSBpbnRvIGEge0BsaW5rIExvY2F0aW9uUXVlcnl9IGJ5IGNhc3RpbmdcbiAqIG51bWJlcnMgaW50byBzdHJpbmdzLCByZW1vdmluZyBrZXlzIHdpdGggYW4gdW5kZWZpbmVkIHZhbHVlIGFuZCByZXBsYWNpbmdcbiAqIHVuZGVmaW5lZCB3aXRoIG51bGwgaW4gYXJyYXlzXG4gKlxuICogQHBhcmFtIHF1ZXJ5IC0gcXVlcnkgb2JqZWN0IHRvIG5vcm1hbGl6ZVxuICogQHJldHVybnMgYSBub3JtYWxpemVkIHF1ZXJ5IG9iamVjdFxuICovXG5mdW5jdGlvbiBub3JtYWxpemVRdWVyeShxdWVyeSkge1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRRdWVyeSA9IHt9O1xuICAgIGZvciAoY29uc3Qga2V5IGluIHF1ZXJ5KSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcXVlcnlba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRRdWVyeVtrZXldID0gaXNBcnJheSh2YWx1ZSlcbiAgICAgICAgICAgICAgICA/IHZhbHVlLm1hcCh2ID0+ICh2ID09IG51bGwgPyBudWxsIDogJycgKyB2KSlcbiAgICAgICAgICAgICAgICA6IHZhbHVlID09IG51bGxcbiAgICAgICAgICAgICAgICAgICAgPyB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICA6ICcnICsgdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRRdWVyeTtcbn1cblxuLyoqXG4gKiBSb3V0ZVJlY29yZCBiZWluZyByZW5kZXJlZCBieSB0aGUgY2xvc2VzdCBhbmNlc3RvciBSb3V0ZXIgVmlldy4gVXNlZCBmb3JcbiAqIGBvbkJlZm9yZVJvdXRlVXBkYXRlYCBhbmQgYG9uQmVmb3JlUm91dGVMZWF2ZWAuIHJ2bG0gc3RhbmRzIGZvciBSb3V0ZXIgVmlld1xuICogTG9jYXRpb24gTWF0Y2hlZFxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5jb25zdCBtYXRjaGVkUm91dGVLZXkgPSBTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ3JvdXRlciB2aWV3IGxvY2F0aW9uIG1hdGNoZWQnIDogJycpO1xuLyoqXG4gKiBBbGxvd3Mgb3ZlcnJpZGluZyB0aGUgcm91dGVyIHZpZXcgZGVwdGggdG8gY29udHJvbCB3aGljaCBjb21wb25lbnQgaW5cbiAqIGBtYXRjaGVkYCBpcyByZW5kZXJlZC4gcnZkIHN0YW5kcyBmb3IgUm91dGVyIFZpZXcgRGVwdGhcbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY29uc3Qgdmlld0RlcHRoS2V5ID0gU3ltYm9sKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/ICdyb3V0ZXIgdmlldyBkZXB0aCcgOiAnJyk7XG4vKipcbiAqIEFsbG93cyBvdmVycmlkaW5nIHRoZSByb3V0ZXIgaW5zdGFuY2UgcmV0dXJuZWQgYnkgYHVzZVJvdXRlcmAgaW4gdGVzdHMuIHJcbiAqIHN0YW5kcyBmb3Igcm91dGVyXG4gKlxuICogQGludGVybmFsXG4gKi9cbmNvbnN0IHJvdXRlcktleSA9IFN5bWJvbCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyAncm91dGVyJyA6ICcnKTtcbi8qKlxuICogQWxsb3dzIG92ZXJyaWRpbmcgdGhlIGN1cnJlbnQgcm91dGUgcmV0dXJuZWQgYnkgYHVzZVJvdXRlYCBpbiB0ZXN0cy4gcmxcbiAqIHN0YW5kcyBmb3Igcm91dGUgbG9jYXRpb25cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY29uc3Qgcm91dGVMb2NhdGlvbktleSA9IFN5bWJvbCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyAncm91dGUgbG9jYXRpb24nIDogJycpO1xuLyoqXG4gKiBBbGxvd3Mgb3ZlcnJpZGluZyB0aGUgY3VycmVudCByb3V0ZSB1c2VkIGJ5IHJvdXRlci12aWV3LiBJbnRlcm5hbGx5IHRoaXMgaXNcbiAqIHVzZWQgd2hlbiB0aGUgYHJvdXRlYCBwcm9wIGlzIHBhc3NlZC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY29uc3Qgcm91dGVyVmlld0xvY2F0aW9uS2V5ID0gU3ltYm9sKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/ICdyb3V0ZXIgdmlldyBsb2NhdGlvbicgOiAnJyk7XG5cbi8qKlxuICogQ3JlYXRlIGEgbGlzdCBvZiBjYWxsYmFja3MgdGhhdCBjYW4gYmUgcmVzZXQuIFVzZWQgdG8gY3JlYXRlIGJlZm9yZSBhbmQgYWZ0ZXIgbmF2aWdhdGlvbiBndWFyZHMgbGlzdFxuICovXG5mdW5jdGlvbiB1c2VDYWxsYmFja3MoKSB7XG4gICAgbGV0IGhhbmRsZXJzID0gW107XG4gICAgZnVuY3Rpb24gYWRkKGhhbmRsZXIpIHtcbiAgICAgICAgaGFuZGxlcnMucHVzaChoYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGkgPSBoYW5kbGVycy5pbmRleE9mKGhhbmRsZXIpO1xuICAgICAgICAgICAgaWYgKGkgPiAtMSlcbiAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgICAgICBoYW5kbGVycyA9IFtdO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBhZGQsXG4gICAgICAgIGxpc3Q6ICgpID0+IGhhbmRsZXJzLnNsaWNlKCksXG4gICAgICAgIHJlc2V0LFxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHJlZ2lzdGVyR3VhcmQocmVjb3JkLCBuYW1lLCBndWFyZCkge1xuICAgIGNvbnN0IHJlbW92ZUZyb21MaXN0ID0gKCkgPT4ge1xuICAgICAgICByZWNvcmRbbmFtZV0uZGVsZXRlKGd1YXJkKTtcbiAgICB9O1xuICAgIG9uVW5tb3VudGVkKHJlbW92ZUZyb21MaXN0KTtcbiAgICBvbkRlYWN0aXZhdGVkKHJlbW92ZUZyb21MaXN0KTtcbiAgICBvbkFjdGl2YXRlZCgoKSA9PiB7XG4gICAgICAgIHJlY29yZFtuYW1lXS5hZGQoZ3VhcmQpO1xuICAgIH0pO1xuICAgIHJlY29yZFtuYW1lXS5hZGQoZ3VhcmQpO1xufVxuLyoqXG4gKiBBZGQgYSBuYXZpZ2F0aW9uIGd1YXJkIHRoYXQgdHJpZ2dlcnMgd2hlbmV2ZXIgdGhlIGNvbXBvbmVudCBmb3IgdGhlIGN1cnJlbnRcbiAqIGxvY2F0aW9uIGlzIGFib3V0IHRvIGJlIGxlZnQuIFNpbWlsYXIgdG8ge0BsaW5rIGJlZm9yZVJvdXRlTGVhdmV9IGJ1dCBjYW4gYmVcbiAqIHVzZWQgaW4gYW55IGNvbXBvbmVudC4gVGhlIGd1YXJkIGlzIHJlbW92ZWQgd2hlbiB0aGUgY29tcG9uZW50IGlzIHVubW91bnRlZC5cbiAqXG4gKiBAcGFyYW0gbGVhdmVHdWFyZCAtIHtAbGluayBOYXZpZ2F0aW9uR3VhcmR9XG4gKi9cbmZ1bmN0aW9uIG9uQmVmb3JlUm91dGVMZWF2ZShsZWF2ZUd1YXJkKSB7XG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhZ2V0Q3VycmVudEluc3RhbmNlKCkpIHtcbiAgICAgICAgd2FybignZ2V0Q3VycmVudEluc3RhbmNlKCkgcmV0dXJuZWQgbnVsbC4gb25CZWZvcmVSb3V0ZUxlYXZlKCkgbXVzdCBiZSBjYWxsZWQgYXQgdGhlIHRvcCBvZiBhIHNldHVwIGZ1bmN0aW9uJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYWN0aXZlUmVjb3JkID0gaW5qZWN0KG1hdGNoZWRSb3V0ZUtleSwgXG4gICAgLy8gdG8gYXZvaWQgd2FybmluZ1xuICAgIHt9KS52YWx1ZTtcbiAgICBpZiAoIWFjdGl2ZVJlY29yZCkge1xuICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiZcbiAgICAgICAgICAgIHdhcm4oJ05vIGFjdGl2ZSByb3V0ZSByZWNvcmQgd2FzIGZvdW5kIHdoZW4gY2FsbGluZyBgb25CZWZvcmVSb3V0ZUxlYXZlKClgLiBNYWtlIHN1cmUgeW91IGNhbGwgdGhpcyBmdW5jdGlvbiBpbnNpZGUgYSBjb21wb25lbnQgY2hpbGQgb2YgPHJvdXRlci12aWV3Pi4gTWF5YmUgeW91IGNhbGxlZCBpdCBpbnNpZGUgb2YgQXBwLnZ1ZT8nKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZWdpc3Rlckd1YXJkKGFjdGl2ZVJlY29yZCwgJ2xlYXZlR3VhcmRzJywgbGVhdmVHdWFyZCk7XG59XG4vKipcbiAqIEFkZCBhIG5hdmlnYXRpb24gZ3VhcmQgdGhhdCB0cmlnZ2VycyB3aGVuZXZlciB0aGUgY3VycmVudCBsb2NhdGlvbiBpcyBhYm91dFxuICogdG8gYmUgdXBkYXRlZC4gU2ltaWxhciB0byB7QGxpbmsgYmVmb3JlUm91dGVVcGRhdGV9IGJ1dCBjYW4gYmUgdXNlZCBpbiBhbnlcbiAqIGNvbXBvbmVudC4gVGhlIGd1YXJkIGlzIHJlbW92ZWQgd2hlbiB0aGUgY29tcG9uZW50IGlzIHVubW91bnRlZC5cbiAqXG4gKiBAcGFyYW0gdXBkYXRlR3VhcmQgLSB7QGxpbmsgTmF2aWdhdGlvbkd1YXJkfVxuICovXG5mdW5jdGlvbiBvbkJlZm9yZVJvdXRlVXBkYXRlKHVwZGF0ZUd1YXJkKSB7XG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhZ2V0Q3VycmVudEluc3RhbmNlKCkpIHtcbiAgICAgICAgd2FybignZ2V0Q3VycmVudEluc3RhbmNlKCkgcmV0dXJuZWQgbnVsbC4gb25CZWZvcmVSb3V0ZVVwZGF0ZSgpIG11c3QgYmUgY2FsbGVkIGF0IHRoZSB0b3Agb2YgYSBzZXR1cCBmdW5jdGlvbicpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGFjdGl2ZVJlY29yZCA9IGluamVjdChtYXRjaGVkUm91dGVLZXksIFxuICAgIC8vIHRvIGF2b2lkIHdhcm5pbmdcbiAgICB7fSkudmFsdWU7XG4gICAgaWYgKCFhY3RpdmVSZWNvcmQpIHtcbiAgICAgICAgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXG4gICAgICAgICAgICB3YXJuKCdObyBhY3RpdmUgcm91dGUgcmVjb3JkIHdhcyBmb3VuZCB3aGVuIGNhbGxpbmcgYG9uQmVmb3JlUm91dGVVcGRhdGUoKWAuIE1ha2Ugc3VyZSB5b3UgY2FsbCB0aGlzIGZ1bmN0aW9uIGluc2lkZSBhIGNvbXBvbmVudCBjaGlsZCBvZiA8cm91dGVyLXZpZXc+LiBNYXliZSB5b3UgY2FsbGVkIGl0IGluc2lkZSBvZiBBcHAudnVlPycpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlZ2lzdGVyR3VhcmQoYWN0aXZlUmVjb3JkLCAndXBkYXRlR3VhcmRzJywgdXBkYXRlR3VhcmQpO1xufVxuZnVuY3Rpb24gZ3VhcmRUb1Byb21pc2VGbihndWFyZCwgdG8sIGZyb20sIHJlY29yZCwgbmFtZSwgcnVuV2l0aENvbnRleHQgPSBmbiA9PiBmbigpKSB7XG4gICAgLy8ga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgZW50ZXJDYWxsYmFja0FycmF5IHRvIHByZXZlbnQgcHVzaGluZyBjYWxsYmFja3MgaWYgYSBuZXcgbmF2aWdhdGlvbiB0b29rIHBsYWNlXG4gICAgY29uc3QgZW50ZXJDYWxsYmFja0FycmF5ID0gcmVjb3JkICYmXG4gICAgICAgIC8vIG5hbWUgaXMgZGVmaW5lZCBpZiByZWNvcmQgaXMgYmVjYXVzZSBvZiB0aGUgZnVuY3Rpb24gb3ZlcmxvYWRcbiAgICAgICAgKHJlY29yZC5lbnRlckNhbGxiYWNrc1tuYW1lXSA9IHJlY29yZC5lbnRlckNhbGxiYWNrc1tuYW1lXSB8fCBbXSk7XG4gICAgcmV0dXJuICgpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgbmV4dCA9ICh2YWxpZCkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbGlkID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChjcmVhdGVSb3V0ZXJFcnJvcig0IC8qIEVycm9yVHlwZXMuTkFWSUdBVElPTl9BQk9SVEVEICovLCB7XG4gICAgICAgICAgICAgICAgICAgIGZyb20sXG4gICAgICAgICAgICAgICAgICAgIHRvLFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbGlkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QodmFsaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNSb3V0ZUxvY2F0aW9uKHZhbGlkKSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChjcmVhdGVSb3V0ZXJFcnJvcigyIC8qIEVycm9yVHlwZXMuTkFWSUdBVElPTl9HVUFSRF9SRURJUkVDVCAqLywge1xuICAgICAgICAgICAgICAgICAgICBmcm9tOiB0byxcbiAgICAgICAgICAgICAgICAgICAgdG86IHZhbGlkLFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChlbnRlckNhbGxiYWNrQXJyYXkgJiZcbiAgICAgICAgICAgICAgICAgICAgLy8gc2luY2UgZW50ZXJDYWxsYmFja0FycmF5IGlzIHRydXRoeSwgYm90aCByZWNvcmQgYW5kIG5hbWUgYWxzbyBhcmVcbiAgICAgICAgICAgICAgICAgICAgcmVjb3JkLmVudGVyQ2FsbGJhY2tzW25hbWVdID09PSBlbnRlckNhbGxiYWNrQXJyYXkgJiZcbiAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHZhbGlkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGVudGVyQ2FsbGJhY2tBcnJheS5wdXNoKHZhbGlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvLyB3cmFwcGluZyB3aXRoIFByb21pc2UucmVzb2x2ZSBhbGxvd3MgaXQgdG8gd29yayB3aXRoIGJvdGggYXN5bmMgYW5kIHN5bmMgZ3VhcmRzXG4gICAgICAgIGNvbnN0IGd1YXJkUmV0dXJuID0gcnVuV2l0aENvbnRleHQoKCkgPT4gZ3VhcmQuY2FsbChyZWNvcmQgJiYgcmVjb3JkLmluc3RhbmNlc1tuYW1lXSwgdG8sIGZyb20sIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/IGNhbk9ubHlCZUNhbGxlZE9uY2UobmV4dCwgdG8sIGZyb20pIDogbmV4dCkpO1xuICAgICAgICBsZXQgZ3VhcmRDYWxsID0gUHJvbWlzZS5yZXNvbHZlKGd1YXJkUmV0dXJuKTtcbiAgICAgICAgaWYgKGd1YXJkLmxlbmd0aCA8IDMpXG4gICAgICAgICAgICBndWFyZENhbGwgPSBndWFyZENhbGwudGhlbihuZXh0KTtcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBndWFyZC5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gYFRoZSBcIm5leHRcIiBjYWxsYmFjayB3YXMgbmV2ZXIgY2FsbGVkIGluc2lkZSBvZiAke2d1YXJkLm5hbWUgPyAnXCInICsgZ3VhcmQubmFtZSArICdcIicgOiAnJ306XFxuJHtndWFyZC50b1N0cmluZygpfVxcbi4gSWYgeW91IGFyZSByZXR1cm5pbmcgYSB2YWx1ZSBpbnN0ZWFkIG9mIGNhbGxpbmcgXCJuZXh0XCIsIG1ha2Ugc3VyZSB0byByZW1vdmUgdGhlIFwibmV4dFwiIHBhcmFtZXRlciBmcm9tIHlvdXIgZnVuY3Rpb24uYDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZ3VhcmRSZXR1cm4gPT09ICdvYmplY3QnICYmICd0aGVuJyBpbiBndWFyZFJldHVybikge1xuICAgICAgICAgICAgICAgIGd1YXJkQ2FsbCA9IGd1YXJkQ2FsbC50aGVuKHJlc29sdmVkVmFsdWUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiBfY2FsbGVkIGlzIGFkZGVkIGF0IGNhbk9ubHlCZUNhbGxlZE9uY2VcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuZXh0Ll9jYWxsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm4obWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdJbnZhbGlkIG5hdmlnYXRpb24gZ3VhcmQnKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmVkVmFsdWU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChndWFyZFJldHVybiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogX2NhbGxlZCBpcyBhZGRlZCBhdCBjYW5Pbmx5QmVDYWxsZWRPbmNlXG4gICAgICAgICAgICAgICAgaWYgKCFuZXh0Ll9jYWxsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgd2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignSW52YWxpZCBuYXZpZ2F0aW9uIGd1YXJkJykpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGd1YXJkQ2FsbC5jYXRjaChlcnIgPT4gcmVqZWN0KGVycikpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gY2FuT25seUJlQ2FsbGVkT25jZShuZXh0LCB0bywgZnJvbSkge1xuICAgIGxldCBjYWxsZWQgPSAwO1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjYWxsZWQrKyA9PT0gMSlcbiAgICAgICAgICAgIHdhcm4oYFRoZSBcIm5leHRcIiBjYWxsYmFjayB3YXMgY2FsbGVkIG1vcmUgdGhhbiBvbmNlIGluIG9uZSBuYXZpZ2F0aW9uIGd1YXJkIHdoZW4gZ29pbmcgZnJvbSBcIiR7ZnJvbS5mdWxsUGF0aH1cIiB0byBcIiR7dG8uZnVsbFBhdGh9XCIuIEl0IHNob3VsZCBiZSBjYWxsZWQgZXhhY3RseSBvbmUgdGltZSBpbiBlYWNoIG5hdmlnYXRpb24gZ3VhcmQuIFRoaXMgd2lsbCBmYWlsIGluIHByb2R1Y3Rpb24uYCk7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3I6IHdlIHB1dCBpdCBpbiB0aGUgb3JpZ2luYWwgb25lIGJlY2F1c2UgaXQncyBlYXNpZXIgdG8gY2hlY2tcbiAgICAgICAgbmV4dC5fY2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKGNhbGxlZCA9PT0gMSlcbiAgICAgICAgICAgIG5leHQuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuZnVuY3Rpb24gZXh0cmFjdENvbXBvbmVudHNHdWFyZHMobWF0Y2hlZCwgZ3VhcmRUeXBlLCB0bywgZnJvbSwgcnVuV2l0aENvbnRleHQgPSBmbiA9PiBmbigpKSB7XG4gICAgY29uc3QgZ3VhcmRzID0gW107XG4gICAgZm9yIChjb25zdCByZWNvcmQgb2YgbWF0Y2hlZCkge1xuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFyZWNvcmQuY29tcG9uZW50cyAmJiAhcmVjb3JkLmNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgd2FybihgUmVjb3JkIHdpdGggcGF0aCBcIiR7cmVjb3JkLnBhdGh9XCIgaXMgZWl0aGVyIG1pc3NpbmcgYSBcImNvbXBvbmVudChzKVwiYCArXG4gICAgICAgICAgICAgICAgYCBvciBcImNoaWxkcmVuXCIgcHJvcGVydHkuYCk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIHJlY29yZC5jb21wb25lbnRzKSB7XG4gICAgICAgICAgICBsZXQgcmF3Q29tcG9uZW50ID0gcmVjb3JkLmNvbXBvbmVudHNbbmFtZV07XG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFyYXdDb21wb25lbnQgfHxcbiAgICAgICAgICAgICAgICAgICAgKHR5cGVvZiByYXdDb21wb25lbnQgIT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgcmF3Q29tcG9uZW50ICE9PSAnZnVuY3Rpb24nKSkge1xuICAgICAgICAgICAgICAgICAgICB3YXJuKGBDb21wb25lbnQgXCIke25hbWV9XCIgaW4gcmVjb3JkIHdpdGggcGF0aCBcIiR7cmVjb3JkLnBhdGh9XCIgaXMgbm90YCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgIGEgdmFsaWQgY29tcG9uZW50LiBSZWNlaXZlZCBcIiR7U3RyaW5nKHJhd0NvbXBvbmVudCl9XCIuYCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRocm93IHRvIGVuc3VyZSB3ZSBzdG9wIGhlcmUgYnV0IHdhcm4gdG8gZW5zdXJlIHRoZSBtZXNzYWdlIGlzbid0XG4gICAgICAgICAgICAgICAgICAgIC8vIG1pc3NlZCBieSB0aGUgdXNlclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcm91dGUgY29tcG9uZW50Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCd0aGVuJyBpbiByYXdDb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gd2FybiBpZiB1c2VyIHdyb3RlIGltcG9ydCgnL2NvbXBvbmVudC52dWUnKSBpbnN0ZWFkIG9mICgpID0+XG4gICAgICAgICAgICAgICAgICAgIC8vIGltcG9ydCgnLi9jb21wb25lbnQudnVlJylcbiAgICAgICAgICAgICAgICAgICAgd2FybihgQ29tcG9uZW50IFwiJHtuYW1lfVwiIGluIHJlY29yZCB3aXRoIHBhdGggXCIke3JlY29yZC5wYXRofVwiIGlzIGEgYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgUHJvbWlzZSBpbnN0ZWFkIG9mIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgUHJvbWlzZS4gRGlkIHlvdSBgICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGB3cml0ZSBcImltcG9ydCgnLi9NeVBhZ2UudnVlJylcIiBpbnN0ZWFkIG9mIGAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYFwiKCkgPT4gaW1wb3J0KCcuL015UGFnZS52dWUnKVwiID8gVGhpcyB3aWxsIGJyZWFrIGluIGAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYHByb2R1Y3Rpb24gaWYgbm90IGZpeGVkLmApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlID0gcmF3Q29tcG9uZW50O1xuICAgICAgICAgICAgICAgICAgICByYXdDb21wb25lbnQgPSAoKSA9PiBwcm9taXNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChyYXdDb21wb25lbnQuX19hc3luY0xvYWRlciAmJlxuICAgICAgICAgICAgICAgICAgICAvLyB3YXJuIG9ubHkgb25jZSBwZXIgY29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICFyYXdDb21wb25lbnQuX193YXJuZWREZWZpbmVBc3luYykge1xuICAgICAgICAgICAgICAgICAgICByYXdDb21wb25lbnQuX193YXJuZWREZWZpbmVBc3luYyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYENvbXBvbmVudCBcIiR7bmFtZX1cIiBpbiByZWNvcmQgd2l0aCBwYXRoIFwiJHtyZWNvcmQucGF0aH1cIiBpcyBkZWZpbmVkIGAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYHVzaW5nIFwiZGVmaW5lQXN5bmNDb21wb25lbnQoKVwiLiBgICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGBXcml0ZSBcIigpID0+IGltcG9ydCgnLi9NeVBhZ2UudnVlJylcIiBpbnN0ZWFkIG9mIGAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYFwiZGVmaW5lQXN5bmNDb21wb25lbnQoKCkgPT4gaW1wb3J0KCcuL015UGFnZS52dWUnKSlcIi5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBza2lwIHVwZGF0ZSBhbmQgbGVhdmUgZ3VhcmRzIGlmIHRoZSByb3V0ZSBjb21wb25lbnQgaXMgbm90IG1vdW50ZWRcbiAgICAgICAgICAgIGlmIChndWFyZFR5cGUgIT09ICdiZWZvcmVSb3V0ZUVudGVyJyAmJiAhcmVjb3JkLmluc3RhbmNlc1tuYW1lXSlcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGlmIChpc1JvdXRlQ29tcG9uZW50KHJhd0NvbXBvbmVudCkpIHtcbiAgICAgICAgICAgICAgICAvLyBfX3ZjY09wdHMgaXMgYWRkZWQgYnkgdnVlLWNsYXNzLWNvbXBvbmVudCBhbmQgY29udGFpbiB0aGUgcmVndWxhciBvcHRpb25zXG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHJhd0NvbXBvbmVudC5fX3ZjY09wdHMgfHwgcmF3Q29tcG9uZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IGd1YXJkID0gb3B0aW9uc1tndWFyZFR5cGVdO1xuICAgICAgICAgICAgICAgIGd1YXJkICYmXG4gICAgICAgICAgICAgICAgICAgIGd1YXJkcy5wdXNoKGd1YXJkVG9Qcm9taXNlRm4oZ3VhcmQsIHRvLCBmcm9tLCByZWNvcmQsIG5hbWUsIHJ1bldpdGhDb250ZXh0KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBzdGFydCByZXF1ZXN0aW5nIHRoZSBjaHVuayBhbHJlYWR5XG4gICAgICAgICAgICAgICAgbGV0IGNvbXBvbmVudFByb21pc2UgPSByYXdDb21wb25lbnQoKTtcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICEoJ2NhdGNoJyBpbiBjb21wb25lbnRQcm9taXNlKSkge1xuICAgICAgICAgICAgICAgICAgICB3YXJuKGBDb21wb25lbnQgXCIke25hbWV9XCIgaW4gcmVjb3JkIHdpdGggcGF0aCBcIiR7cmVjb3JkLnBhdGh9XCIgaXMgYSBmdW5jdGlvbiB0aGF0IGRvZXMgbm90IHJldHVybiBhIFByb21pc2UuIElmIHlvdSB3ZXJlIHBhc3NpbmcgYSBmdW5jdGlvbmFsIGNvbXBvbmVudCwgbWFrZSBzdXJlIHRvIGFkZCBhIFwiZGlzcGxheU5hbWVcIiB0byB0aGUgY29tcG9uZW50LiBUaGlzIHdpbGwgYnJlYWsgaW4gcHJvZHVjdGlvbiBpZiBub3QgZml4ZWQuYCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoY29tcG9uZW50UHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGd1YXJkcy5wdXNoKCgpID0+IGNvbXBvbmVudFByb21pc2UudGhlbihyZXNvbHZlZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVzb2x2ZWQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkbid0IHJlc29sdmUgY29tcG9uZW50IFwiJHtuYW1lfVwiIGF0IFwiJHtyZWNvcmQucGF0aH1cImApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlZENvbXBvbmVudCA9IGlzRVNNb2R1bGUocmVzb2x2ZWQpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHJlc29sdmVkLmRlZmF1bHRcbiAgICAgICAgICAgICAgICAgICAgICAgIDogcmVzb2x2ZWQ7XG4gICAgICAgICAgICAgICAgICAgIC8vIGtlZXAgdGhlIHJlc29sdmVkIG1vZHVsZSBmb3IgcGx1Z2lucyBsaWtlIGRhdGEgbG9hZGVyc1xuICAgICAgICAgICAgICAgICAgICByZWNvcmQubW9kc1tuYW1lXSA9IHJlc29sdmVkO1xuICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSByZXNvbHZlZCBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgLy8gY2Fubm90IGJlIG51bGwgb3IgdW5kZWZpbmVkIGJlY2F1c2Ugd2Ugd2VudCBpbnRvIHRoZSBmb3IgbG9vcFxuICAgICAgICAgICAgICAgICAgICByZWNvcmQuY29tcG9uZW50c1tuYW1lXSA9IHJlc29sdmVkQ29tcG9uZW50O1xuICAgICAgICAgICAgICAgICAgICAvLyBfX3ZjY09wdHMgaXMgYWRkZWQgYnkgdnVlLWNsYXNzLWNvbXBvbmVudCBhbmQgY29udGFpbiB0aGUgcmVndWxhciBvcHRpb25zXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSByZXNvbHZlZENvbXBvbmVudC5fX3ZjY09wdHMgfHwgcmVzb2x2ZWRDb21wb25lbnQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGd1YXJkID0gb3B0aW9uc1tndWFyZFR5cGVdO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGd1YXJkICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBndWFyZFRvUHJvbWlzZUZuKGd1YXJkLCB0bywgZnJvbSwgcmVjb3JkLCBuYW1lLCBydW5XaXRoQ29udGV4dCkoKSk7XG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBndWFyZHM7XG59XG4vKipcbiAqIEVuc3VyZXMgYSByb3V0ZSBpcyBsb2FkZWQsIHNvIGl0IGNhbiBiZSBwYXNzZWQgYXMgbyBwcm9wIHRvIGA8Um91dGVyVmlldz5gLlxuICpcbiAqIEBwYXJhbSByb3V0ZSAtIHJlc29sdmVkIHJvdXRlIHRvIGxvYWRcbiAqL1xuZnVuY3Rpb24gbG9hZFJvdXRlTG9jYXRpb24ocm91dGUpIHtcbiAgICByZXR1cm4gcm91dGUubWF0Y2hlZC5ldmVyeShyZWNvcmQgPT4gcmVjb3JkLnJlZGlyZWN0KVxuICAgICAgICA/IFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignQ2Fubm90IGxvYWQgYSByb3V0ZSB0aGF0IHJlZGlyZWN0cy4nKSlcbiAgICAgICAgOiBQcm9taXNlLmFsbChyb3V0ZS5tYXRjaGVkLm1hcChyZWNvcmQgPT4gcmVjb3JkLmNvbXBvbmVudHMgJiZcbiAgICAgICAgICAgIFByb21pc2UuYWxsKE9iamVjdC5rZXlzKHJlY29yZC5jb21wb25lbnRzKS5yZWR1Y2UoKHByb21pc2VzLCBuYW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmF3Q29tcG9uZW50ID0gcmVjb3JkLmNvbXBvbmVudHNbbmFtZV07XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByYXdDb21wb25lbnQgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgICAgICAgICAgICAgISgnZGlzcGxheU5hbWUnIGluIHJhd0NvbXBvbmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChyYXdDb21wb25lbnQoKS50aGVuKHJlc29sdmVkID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcmVzb2x2ZWQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihgQ291bGRuJ3QgcmVzb2x2ZSBjb21wb25lbnQgXCIke25hbWV9XCIgYXQgXCIke3JlY29yZC5wYXRofVwiLiBFbnN1cmUgeW91IHBhc3NlZCBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuYCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZWRDb21wb25lbnQgPSBpc0VTTW9kdWxlKHJlc29sdmVkKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcmVzb2x2ZWQuZGVmYXVsdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogcmVzb2x2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBrZWVwIHRoZSByZXNvbHZlZCBtb2R1bGUgZm9yIHBsdWdpbnMgbGlrZSBkYXRhIGxvYWRlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY29yZC5tb2RzW25hbWVdID0gcmVzb2x2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSByZXNvbHZlZCBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbm5vdCBiZSBudWxsIG9yIHVuZGVmaW5lZCBiZWNhdXNlIHdlIHdlbnQgaW50byB0aGUgZm9yIGxvb3BcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY29yZC5jb21wb25lbnRzW25hbWVdID0gcmVzb2x2ZWRDb21wb25lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICAgICAgfSwgW10pKSkpLnRoZW4oKCkgPT4gcm91dGUpO1xufVxuXG4vLyBUT0RPOiB3ZSBjb3VsZCBhbGxvdyBjdXJyZW50Um91dGUgYXMgYSBwcm9wIHRvIGV4cG9zZSBgaXNBY3RpdmVgIGFuZFxuLy8gYGlzRXhhY3RBY3RpdmVgIGJlaGF2aW9yIHNob3VsZCBnbyB0aHJvdWdoIGFuIFJGQ1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCBiZWhhdmlvciBvZiBhIHtAbGluayBSb3V0ZXJMaW5rfSB3aXRob3V0IHRoZSByZW5kZXJpbmcgcGFydC5cbiAqXG4gKiBAcGFyYW0gcHJvcHMgLSBhIGB0b2AgbG9jYXRpb24gYW5kIGFuIG9wdGlvbmFsIGByZXBsYWNlYCBmbGFnXG4gKi9cbmZ1bmN0aW9uIHVzZUxpbmsocHJvcHMpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBpbmplY3Qocm91dGVyS2V5KTtcbiAgICBjb25zdCBjdXJyZW50Um91dGUgPSBpbmplY3Qocm91dGVMb2NhdGlvbktleSk7XG4gICAgbGV0IGhhc1ByZXZpb3VzID0gZmFsc2U7XG4gICAgbGV0IHByZXZpb3VzVG8gPSBudWxsO1xuICAgIGNvbnN0IHJvdXRlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCB0byA9IHVucmVmKHByb3BzLnRvKTtcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAoIWhhc1ByZXZpb3VzIHx8IHRvICE9PSBwcmV2aW91c1RvKSkge1xuICAgICAgICAgICAgaWYgKCFpc1JvdXRlTG9jYXRpb24odG8pKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhc1ByZXZpb3VzKSB7XG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYEludmFsaWQgdmFsdWUgZm9yIHByb3AgXCJ0b1wiIGluIHVzZUxpbmsoKVxcbi0gdG86YCwgdG8sIGBcXG4tIHByZXZpb3VzIHRvOmAsIHByZXZpb3VzVG8sIGBcXG4tIHByb3BzOmAsIHByb3BzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYEludmFsaWQgdmFsdWUgZm9yIHByb3AgXCJ0b1wiIGluIHVzZUxpbmsoKVxcbi0gdG86YCwgdG8sIGBcXG4tIHByb3BzOmAsIHByb3BzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwcmV2aW91c1RvID0gdG87XG4gICAgICAgICAgICBoYXNQcmV2aW91cyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJvdXRlci5yZXNvbHZlKHRvKTtcbiAgICB9KTtcbiAgICBjb25zdCBhY3RpdmVSZWNvcmRJbmRleCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgY29uc3QgeyBtYXRjaGVkIH0gPSByb3V0ZS52YWx1ZTtcbiAgICAgICAgY29uc3QgeyBsZW5ndGggfSA9IG1hdGNoZWQ7XG4gICAgICAgIGNvbnN0IHJvdXRlTWF0Y2hlZCA9IG1hdGNoZWRbbGVuZ3RoIC0gMV07XG4gICAgICAgIGNvbnN0IGN1cnJlbnRNYXRjaGVkID0gY3VycmVudFJvdXRlLm1hdGNoZWQ7XG4gICAgICAgIGlmICghcm91dGVNYXRjaGVkIHx8ICFjdXJyZW50TWF0Y2hlZC5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gY3VycmVudE1hdGNoZWQuZmluZEluZGV4KGlzU2FtZVJvdXRlUmVjb3JkLmJpbmQobnVsbCwgcm91dGVNYXRjaGVkKSk7XG4gICAgICAgIGlmIChpbmRleCA+IC0xKVxuICAgICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICAvLyBwb3NzaWJsZSBwYXJlbnQgcmVjb3JkXG4gICAgICAgIGNvbnN0IHBhcmVudFJlY29yZFBhdGggPSBnZXRPcmlnaW5hbFBhdGgobWF0Y2hlZFtsZW5ndGggLSAyXSk7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgIC8vIHdlIGFyZSBkZWFsaW5nIHdpdGggbmVzdGVkIHJvdXRlc1xuICAgICAgICBsZW5ndGggPiAxICYmXG4gICAgICAgICAgICAvLyBpZiB0aGUgcGFyZW50IGFuZCBtYXRjaGVkIHJvdXRlIGhhdmUgdGhlIHNhbWUgcGF0aCwgdGhpcyBsaW5rIGlzXG4gICAgICAgICAgICAvLyByZWZlcnJpbmcgdG8gdGhlIGVtcHR5IGNoaWxkLiBPciB3ZSBjdXJyZW50bHkgYXJlIG9uIGEgZGlmZmVyZW50XG4gICAgICAgICAgICAvLyBjaGlsZCBvZiB0aGUgc2FtZSBwYXJlbnRcbiAgICAgICAgICAgIGdldE9yaWdpbmFsUGF0aChyb3V0ZU1hdGNoZWQpID09PSBwYXJlbnRSZWNvcmRQYXRoICYmXG4gICAgICAgICAgICAvLyBhdm9pZCBjb21wYXJpbmcgdGhlIGNoaWxkIHdpdGggaXRzIHBhcmVudFxuICAgICAgICAgICAgY3VycmVudE1hdGNoZWRbY3VycmVudE1hdGNoZWQubGVuZ3RoIC0gMV0ucGF0aCAhPT0gcGFyZW50UmVjb3JkUGF0aFxuICAgICAgICAgICAgPyBjdXJyZW50TWF0Y2hlZC5maW5kSW5kZXgoaXNTYW1lUm91dGVSZWNvcmQuYmluZChudWxsLCBtYXRjaGVkW2xlbmd0aCAtIDJdKSlcbiAgICAgICAgICAgIDogaW5kZXgpO1xuICAgIH0pO1xuICAgIGNvbnN0IGlzQWN0aXZlID0gY29tcHV0ZWQoKCkgPT4gYWN0aXZlUmVjb3JkSW5kZXgudmFsdWUgPiAtMSAmJlxuICAgICAgICBpbmNsdWRlc1BhcmFtcyhjdXJyZW50Um91dGUucGFyYW1zLCByb3V0ZS52YWx1ZS5wYXJhbXMpKTtcbiAgICBjb25zdCBpc0V4YWN0QWN0aXZlID0gY29tcHV0ZWQoKCkgPT4gYWN0aXZlUmVjb3JkSW5kZXgudmFsdWUgPiAtMSAmJlxuICAgICAgICBhY3RpdmVSZWNvcmRJbmRleC52YWx1ZSA9PT0gY3VycmVudFJvdXRlLm1hdGNoZWQubGVuZ3RoIC0gMSAmJlxuICAgICAgICBpc1NhbWVSb3V0ZUxvY2F0aW9uUGFyYW1zKGN1cnJlbnRSb3V0ZS5wYXJhbXMsIHJvdXRlLnZhbHVlLnBhcmFtcykpO1xuICAgIGZ1bmN0aW9uIG5hdmlnYXRlKGUgPSB7fSkge1xuICAgICAgICBpZiAoZ3VhcmRFdmVudChlKSkge1xuICAgICAgICAgICAgY29uc3QgcCA9IHJvdXRlclt1bnJlZihwcm9wcy5yZXBsYWNlKSA/ICdyZXBsYWNlJyA6ICdwdXNoJ10odW5yZWYocHJvcHMudG8pXG4gICAgICAgICAgICAvLyBhdm9pZCB1bmNhdWdodCBlcnJvcnMgYXJlIHRoZXkgYXJlIGxvZ2dlZCBhbnl3YXlcbiAgICAgICAgICAgICkuY2F0Y2gobm9vcCk7XG4gICAgICAgICAgICBpZiAocHJvcHMudmlld1RyYW5zaXRpb24gJiZcbiAgICAgICAgICAgICAgICB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICAgICAgJ3N0YXJ0Vmlld1RyYW5zaXRpb24nIGluIGRvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuc3RhcnRWaWV3VHJhbnNpdGlvbigoKSA9PiBwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgLy8gZGV2dG9vbHMgb25seVxuICAgIGlmICgoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHx8IF9fVlVFX1BST0RfREVWVE9PTFNfXykgJiYgaXNCcm93c2VyKSB7XG4gICAgICAgIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7XG4gICAgICAgIGlmIChpbnN0YW5jZSkge1xuICAgICAgICAgICAgY29uc3QgbGlua0NvbnRleHREZXZ0b29scyA9IHtcbiAgICAgICAgICAgICAgICByb3V0ZTogcm91dGUudmFsdWUsXG4gICAgICAgICAgICAgICAgaXNBY3RpdmU6IGlzQWN0aXZlLnZhbHVlLFxuICAgICAgICAgICAgICAgIGlzRXhhY3RBY3RpdmU6IGlzRXhhY3RBY3RpdmUudmFsdWUsXG4gICAgICAgICAgICAgICAgZXJyb3I6IG51bGwsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogdGhpcyBpcyBpbnRlcm5hbFxuICAgICAgICAgICAgaW5zdGFuY2UuX192cmxfZGV2dG9vbHMgPSBpbnN0YW5jZS5fX3ZybF9kZXZ0b29scyB8fCBbXTtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3I6IHRoaXMgaXMgaW50ZXJuYWxcbiAgICAgICAgICAgIGluc3RhbmNlLl9fdnJsX2RldnRvb2xzLnB1c2gobGlua0NvbnRleHREZXZ0b29scyk7XG4gICAgICAgICAgICB3YXRjaEVmZmVjdCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgbGlua0NvbnRleHREZXZ0b29scy5yb3V0ZSA9IHJvdXRlLnZhbHVlO1xuICAgICAgICAgICAgICAgIGxpbmtDb250ZXh0RGV2dG9vbHMuaXNBY3RpdmUgPSBpc0FjdGl2ZS52YWx1ZTtcbiAgICAgICAgICAgICAgICBsaW5rQ29udGV4dERldnRvb2xzLmlzRXhhY3RBY3RpdmUgPSBpc0V4YWN0QWN0aXZlLnZhbHVlO1xuICAgICAgICAgICAgICAgIGxpbmtDb250ZXh0RGV2dG9vbHMuZXJyb3IgPSBpc1JvdXRlTG9jYXRpb24odW5yZWYocHJvcHMudG8pKVxuICAgICAgICAgICAgICAgICAgICA/IG51bGxcbiAgICAgICAgICAgICAgICAgICAgOiAnSW52YWxpZCBcInRvXCIgdmFsdWUnO1xuICAgICAgICAgICAgfSwgeyBmbHVzaDogJ3Bvc3QnIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE5PVEU6IHVwZGF0ZSB7QGxpbmsgX1JvdXRlckxpbmtJfSdzIGAkc2xvdHNgIHR5cGUgd2hlbiB1cGRhdGluZyB0aGlzXG4gICAgICovXG4gICAgcmV0dXJuIHtcbiAgICAgICAgcm91dGUsXG4gICAgICAgIGhyZWY6IGNvbXB1dGVkKCgpID0+IHJvdXRlLnZhbHVlLmhyZWYpLFxuICAgICAgICBpc0FjdGl2ZSxcbiAgICAgICAgaXNFeGFjdEFjdGl2ZSxcbiAgICAgICAgbmF2aWdhdGUsXG4gICAgfTtcbn1cbmZ1bmN0aW9uIHByZWZlclNpbmdsZVZOb2RlKHZub2Rlcykge1xuICAgIHJldHVybiB2bm9kZXMubGVuZ3RoID09PSAxID8gdm5vZGVzWzBdIDogdm5vZGVzO1xufVxuY29uc3QgUm91dGVyTGlua0ltcGwgPSAvKiNfX1BVUkVfXyovIGRlZmluZUNvbXBvbmVudCh7XG4gICAgbmFtZTogJ1JvdXRlckxpbmsnLFxuICAgIGNvbXBhdENvbmZpZzogeyBNT0RFOiAzIH0sXG4gICAgcHJvcHM6IHtcbiAgICAgICAgdG86IHtcbiAgICAgICAgICAgIHR5cGU6IFtTdHJpbmcsIE9iamVjdF0sXG4gICAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVwbGFjZTogQm9vbGVhbixcbiAgICAgICAgYWN0aXZlQ2xhc3M6IFN0cmluZyxcbiAgICAgICAgLy8gaW5hY3RpdmVDbGFzczogU3RyaW5nLFxuICAgICAgICBleGFjdEFjdGl2ZUNsYXNzOiBTdHJpbmcsXG4gICAgICAgIGN1c3RvbTogQm9vbGVhbixcbiAgICAgICAgYXJpYUN1cnJlbnRWYWx1ZToge1xuICAgICAgICAgICAgdHlwZTogU3RyaW5nLFxuICAgICAgICAgICAgZGVmYXVsdDogJ3BhZ2UnLFxuICAgICAgICB9LFxuICAgICAgICB2aWV3VHJhbnNpdGlvbjogQm9vbGVhbixcbiAgICB9LFxuICAgIHVzZUxpbmssXG4gICAgc2V0dXAocHJvcHMsIHsgc2xvdHMgfSkge1xuICAgICAgICBjb25zdCBsaW5rID0gcmVhY3RpdmUodXNlTGluayhwcm9wcykpO1xuICAgICAgICBjb25zdCB7IG9wdGlvbnMgfSA9IGluamVjdChyb3V0ZXJLZXkpO1xuICAgICAgICBjb25zdCBlbENsYXNzID0gY29tcHV0ZWQoKCkgPT4gKHtcbiAgICAgICAgICAgIFtnZXRMaW5rQ2xhc3MocHJvcHMuYWN0aXZlQ2xhc3MsIG9wdGlvbnMubGlua0FjdGl2ZUNsYXNzLCAncm91dGVyLWxpbmstYWN0aXZlJyldOiBsaW5rLmlzQWN0aXZlLFxuICAgICAgICAgICAgLy8gW2dldExpbmtDbGFzcyhcbiAgICAgICAgICAgIC8vICAgcHJvcHMuaW5hY3RpdmVDbGFzcyxcbiAgICAgICAgICAgIC8vICAgb3B0aW9ucy5saW5rSW5hY3RpdmVDbGFzcyxcbiAgICAgICAgICAgIC8vICAgJ3JvdXRlci1saW5rLWluYWN0aXZlJ1xuICAgICAgICAgICAgLy8gKV06ICFsaW5rLmlzRXhhY3RBY3RpdmUsXG4gICAgICAgICAgICBbZ2V0TGlua0NsYXNzKHByb3BzLmV4YWN0QWN0aXZlQ2xhc3MsIG9wdGlvbnMubGlua0V4YWN0QWN0aXZlQ2xhc3MsICdyb3V0ZXItbGluay1leGFjdC1hY3RpdmUnKV06IGxpbmsuaXNFeGFjdEFjdGl2ZSxcbiAgICAgICAgfSkpO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBzbG90cy5kZWZhdWx0ICYmIHByZWZlclNpbmdsZVZOb2RlKHNsb3RzLmRlZmF1bHQobGluaykpO1xuICAgICAgICAgICAgcmV0dXJuIHByb3BzLmN1c3RvbVxuICAgICAgICAgICAgICAgID8gY2hpbGRyZW5cbiAgICAgICAgICAgICAgICA6IGgoJ2EnLCB7XG4gICAgICAgICAgICAgICAgICAgICdhcmlhLWN1cnJlbnQnOiBsaW5rLmlzRXhhY3RBY3RpdmVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gcHJvcHMuYXJpYUN1cnJlbnRWYWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBocmVmOiBsaW5rLmhyZWYsXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgd291bGQgb3ZlcnJpZGUgdXNlciBhZGRlZCBhdHRycyBidXQgVnVlIHdpbGwgc3RpbGwgYWRkXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBsaXN0ZW5lciwgc28gd2UgZW5kIHVwIHRyaWdnZXJpbmcgYm90aFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiBsaW5rLm5hdmlnYXRlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzczogZWxDbGFzcy52YWx1ZSxcbiAgICAgICAgICAgICAgICB9LCBjaGlsZHJlbik7XG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuLy8gZXhwb3J0IHRoZSBwdWJsaWMgdHlwZSBmb3IgaC90c3ggaW5mZXJlbmNlXG4vLyBhbHNvIHRvIGF2b2lkIGlubGluZSBpbXBvcnQoKSBpbiBnZW5lcmF0ZWQgZC50cyBmaWxlc1xuLyoqXG4gKiBDb21wb25lbnQgdG8gcmVuZGVyIGEgbGluayB0aGF0IHRyaWdnZXJzIGEgbmF2aWdhdGlvbiBvbiBjbGljay5cbiAqL1xuY29uc3QgUm91dGVyTGluayA9IFJvdXRlckxpbmtJbXBsO1xuZnVuY3Rpb24gZ3VhcmRFdmVudChlKSB7XG4gICAgLy8gZG9uJ3QgcmVkaXJlY3Qgd2l0aCBjb250cm9sIGtleXNcbiAgICBpZiAoZS5tZXRhS2V5IHx8IGUuYWx0S2V5IHx8IGUuY3RybEtleSB8fCBlLnNoaWZ0S2V5KVxuICAgICAgICByZXR1cm47XG4gICAgLy8gZG9uJ3QgcmVkaXJlY3Qgd2hlbiBwcmV2ZW50RGVmYXVsdCBjYWxsZWRcbiAgICBpZiAoZS5kZWZhdWx0UHJldmVudGVkKVxuICAgICAgICByZXR1cm47XG4gICAgLy8gZG9uJ3QgcmVkaXJlY3Qgb24gcmlnaHQgY2xpY2tcbiAgICBpZiAoZS5idXR0b24gIT09IHVuZGVmaW5lZCAmJiBlLmJ1dHRvbiAhPT0gMClcbiAgICAgICAgcmV0dXJuO1xuICAgIC8vIGRvbid0IHJlZGlyZWN0IGlmIGB0YXJnZXQ9XCJfYmxhbmtcImBcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGdldEF0dHJpYnV0ZSBkb2VzIGV4aXN0XG4gICAgaWYgKGUuY3VycmVudFRhcmdldCAmJiBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKSB7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgZ2V0QXR0cmlidXRlIGV4aXN0c1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKCd0YXJnZXQnKTtcbiAgICAgICAgaWYgKC9cXGJfYmxhbmtcXGIvaS50ZXN0KHRhcmdldCkpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIHRoaXMgbWF5IGJlIGEgV2VleCBldmVudCB3aGljaCBkb2Vzbid0IGhhdmUgdGhpcyBtZXRob2RcbiAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdClcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gaW5jbHVkZXNQYXJhbXMob3V0ZXIsIGlubmVyKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gaW5uZXIpIHtcbiAgICAgICAgY29uc3QgaW5uZXJWYWx1ZSA9IGlubmVyW2tleV07XG4gICAgICAgIGNvbnN0IG91dGVyVmFsdWUgPSBvdXRlcltrZXldO1xuICAgICAgICBpZiAodHlwZW9mIGlubmVyVmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoaW5uZXJWYWx1ZSAhPT0gb3V0ZXJWYWx1ZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoIWlzQXJyYXkob3V0ZXJWYWx1ZSkgfHxcbiAgICAgICAgICAgICAgICBvdXRlclZhbHVlLmxlbmd0aCAhPT0gaW5uZXJWYWx1ZS5sZW5ndGggfHxcbiAgICAgICAgICAgICAgICBpbm5lclZhbHVlLnNvbWUoKHZhbHVlLCBpKSA9PiB2YWx1ZSAhPT0gb3V0ZXJWYWx1ZVtpXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBHZXQgdGhlIG9yaWdpbmFsIHBhdGggdmFsdWUgb2YgYSByZWNvcmQgYnkgZm9sbG93aW5nIGl0cyBhbGlhc09mXG4gKiBAcGFyYW0gcmVjb3JkXG4gKi9cbmZ1bmN0aW9uIGdldE9yaWdpbmFsUGF0aChyZWNvcmQpIHtcbiAgICByZXR1cm4gcmVjb3JkID8gKHJlY29yZC5hbGlhc09mID8gcmVjb3JkLmFsaWFzT2YucGF0aCA6IHJlY29yZC5wYXRoKSA6ICcnO1xufVxuLyoqXG4gKiBVdGlsaXR5IGNsYXNzIHRvIGdldCB0aGUgYWN0aXZlIGNsYXNzIGJhc2VkIG9uIGRlZmF1bHRzLlxuICogQHBhcmFtIHByb3BDbGFzc1xuICogQHBhcmFtIGdsb2JhbENsYXNzXG4gKiBAcGFyYW0gZGVmYXVsdENsYXNzXG4gKi9cbmNvbnN0IGdldExpbmtDbGFzcyA9IChwcm9wQ2xhc3MsIGdsb2JhbENsYXNzLCBkZWZhdWx0Q2xhc3MpID0+IHByb3BDbGFzcyAhPSBudWxsXG4gICAgPyBwcm9wQ2xhc3NcbiAgICA6IGdsb2JhbENsYXNzICE9IG51bGxcbiAgICAgICAgPyBnbG9iYWxDbGFzc1xuICAgICAgICA6IGRlZmF1bHRDbGFzcztcblxuY29uc3QgUm91dGVyVmlld0ltcGwgPSAvKiNfX1BVUkVfXyovIGRlZmluZUNvbXBvbmVudCh7XG4gICAgbmFtZTogJ1JvdXRlclZpZXcnLFxuICAgIC8vICM2NzQgd2UgbWFudWFsbHkgaW5oZXJpdCB0aGVtXG4gICAgaW5oZXJpdEF0dHJzOiBmYWxzZSxcbiAgICBwcm9wczoge1xuICAgICAgICBuYW1lOiB7XG4gICAgICAgICAgICB0eXBlOiBTdHJpbmcsXG4gICAgICAgICAgICBkZWZhdWx0OiAnZGVmYXVsdCcsXG4gICAgICAgIH0sXG4gICAgICAgIHJvdXRlOiBPYmplY3QsXG4gICAgfSxcbiAgICAvLyBCZXR0ZXIgY29tcGF0IGZvciBAdnVlL2NvbXBhdCB1c2Vyc1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy9yb3V0ZXIvaXNzdWVzLzEzMTVcbiAgICBjb21wYXRDb25maWc6IHsgTU9ERTogMyB9LFxuICAgIHNldHVwKHByb3BzLCB7IGF0dHJzLCBzbG90cyB9KSB7XG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB3YXJuRGVwcmVjYXRlZFVzYWdlKCk7XG4gICAgICAgIGNvbnN0IGluamVjdGVkUm91dGUgPSBpbmplY3Qocm91dGVyVmlld0xvY2F0aW9uS2V5KTtcbiAgICAgICAgY29uc3Qgcm91dGVUb0Rpc3BsYXkgPSBjb21wdXRlZCgoKSA9PiBwcm9wcy5yb3V0ZSB8fCBpbmplY3RlZFJvdXRlLnZhbHVlKTtcbiAgICAgICAgY29uc3QgaW5qZWN0ZWREZXB0aCA9IGluamVjdCh2aWV3RGVwdGhLZXksIDApO1xuICAgICAgICAvLyBUaGUgZGVwdGggY2hhbmdlcyBiYXNlZCBvbiBlbXB0eSBjb21wb25lbnRzIG9wdGlvbiwgd2hpY2ggYWxsb3dzIHBhc3N0aHJvdWdoIHJvdXRlcyBlLmcuIHJvdXRlcyB3aXRoIGNoaWxkcmVuXG4gICAgICAgIC8vIHRoYXQgYXJlIHVzZWQgdG8gcmV1c2UgdGhlIGBwYXRoYCBwcm9wZXJ0eVxuICAgICAgICBjb25zdCBkZXB0aCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBpbml0aWFsRGVwdGggPSB1bnJlZihpbmplY3RlZERlcHRoKTtcbiAgICAgICAgICAgIGNvbnN0IHsgbWF0Y2hlZCB9ID0gcm91dGVUb0Rpc3BsYXkudmFsdWU7XG4gICAgICAgICAgICBsZXQgbWF0Y2hlZFJvdXRlO1xuICAgICAgICAgICAgd2hpbGUgKChtYXRjaGVkUm91dGUgPSBtYXRjaGVkW2luaXRpYWxEZXB0aF0pICYmXG4gICAgICAgICAgICAgICAgIW1hdGNoZWRSb3V0ZS5jb21wb25lbnRzKSB7XG4gICAgICAgICAgICAgICAgaW5pdGlhbERlcHRoKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5pdGlhbERlcHRoO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbWF0Y2hlZFJvdXRlUmVmID0gY29tcHV0ZWQoKCkgPT4gcm91dGVUb0Rpc3BsYXkudmFsdWUubWF0Y2hlZFtkZXB0aC52YWx1ZV0pO1xuICAgICAgICBwcm92aWRlKHZpZXdEZXB0aEtleSwgY29tcHV0ZWQoKCkgPT4gZGVwdGgudmFsdWUgKyAxKSk7XG4gICAgICAgIHByb3ZpZGUobWF0Y2hlZFJvdXRlS2V5LCBtYXRjaGVkUm91dGVSZWYpO1xuICAgICAgICBwcm92aWRlKHJvdXRlclZpZXdMb2NhdGlvbktleSwgcm91dGVUb0Rpc3BsYXkpO1xuICAgICAgICBjb25zdCB2aWV3UmVmID0gcmVmKCk7XG4gICAgICAgIC8vIHdhdGNoIGF0IHRoZSBzYW1lIHRpbWUgdGhlIGNvbXBvbmVudCBpbnN0YW5jZSwgdGhlIHJvdXRlIHJlY29yZCB3ZSBhcmVcbiAgICAgICAgLy8gcmVuZGVyaW5nLCBhbmQgdGhlIG5hbWVcbiAgICAgICAgd2F0Y2goKCkgPT4gW3ZpZXdSZWYudmFsdWUsIG1hdGNoZWRSb3V0ZVJlZi52YWx1ZSwgcHJvcHMubmFtZV0sIChbaW5zdGFuY2UsIHRvLCBuYW1lXSwgW29sZEluc3RhbmNlLCBmcm9tLCBvbGROYW1lXSkgPT4ge1xuICAgICAgICAgICAgLy8gY29weSByZXVzZWQgaW5zdGFuY2VzXG4gICAgICAgICAgICBpZiAodG8pIHtcbiAgICAgICAgICAgICAgICAvLyB0aGlzIHdpbGwgdXBkYXRlIHRoZSBpbnN0YW5jZSBmb3IgbmV3IGluc3RhbmNlcyBhcyB3ZWxsIGFzIHJldXNlZFxuICAgICAgICAgICAgICAgIC8vIGluc3RhbmNlcyB3aGVuIG5hdmlnYXRpbmcgdG8gYSBuZXcgcm91dGVcbiAgICAgICAgICAgICAgICB0by5pbnN0YW5jZXNbbmFtZV0gPSBpbnN0YW5jZTtcbiAgICAgICAgICAgICAgICAvLyB0aGUgY29tcG9uZW50IGluc3RhbmNlIGlzIHJldXNlZCBmb3IgYSBkaWZmZXJlbnQgcm91dGUgb3IgbmFtZSwgc29cbiAgICAgICAgICAgICAgICAvLyB3ZSBjb3B5IGFueSBzYXZlZCB1cGRhdGUgb3IgbGVhdmUgZ3VhcmRzLiBXaXRoIGFzeW5jIHNldHVwLCB0aGVcbiAgICAgICAgICAgICAgICAvLyBtb3VudGluZyBjb21wb25lbnQgd2lsbCBtb3VudCBiZWZvcmUgdGhlIG1hdGNoZWRSb3V0ZSBjaGFuZ2VzLFxuICAgICAgICAgICAgICAgIC8vIG1ha2luZyBpbnN0YW5jZSA9PT0gb2xkSW5zdGFuY2UsIHNvIHdlIGNoZWNrIGlmIGd1YXJkcyBoYXZlIGJlZW5cbiAgICAgICAgICAgICAgICAvLyBhZGRlZCBiZWZvcmUuIFRoaXMgd29ya3MgYmVjYXVzZSB3ZSByZW1vdmUgZ3VhcmRzIHdoZW5cbiAgICAgICAgICAgICAgICAvLyB1bm1vdW50aW5nL2RlYWN0aXZhdGluZyBjb21wb25lbnRzXG4gICAgICAgICAgICAgICAgaWYgKGZyb20gJiYgZnJvbSAhPT0gdG8gJiYgaW5zdGFuY2UgJiYgaW5zdGFuY2UgPT09IG9sZEluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdG8ubGVhdmVHdWFyZHMuc2l6ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG8ubGVhdmVHdWFyZHMgPSBmcm9tLmxlYXZlR3VhcmRzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghdG8udXBkYXRlR3VhcmRzLnNpemUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvLnVwZGF0ZUd1YXJkcyA9IGZyb20udXBkYXRlR3VhcmRzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdHJpZ2dlciBiZWZvcmVSb3V0ZUVudGVyIG5leHQgY2FsbGJhY2tzXG4gICAgICAgICAgICBpZiAoaW5zdGFuY2UgJiZcbiAgICAgICAgICAgICAgICB0byAmJlxuICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIGluc3RhbmNlIGJ1dCB0byBhbmQgZnJvbSBhcmUgdGhlIHNhbWUgdGhpcyBtaWdodCBiZVxuICAgICAgICAgICAgICAgIC8vIHRoZSBmaXJzdCB2aXNpdFxuICAgICAgICAgICAgICAgICghZnJvbSB8fCAhaXNTYW1lUm91dGVSZWNvcmQodG8sIGZyb20pIHx8ICFvbGRJbnN0YW5jZSkpIHtcbiAgICAgICAgICAgICAgICAodG8uZW50ZXJDYWxsYmFja3NbbmFtZV0gfHwgW10pLmZvckVhY2goY2FsbGJhY2sgPT4gY2FsbGJhY2soaW5zdGFuY2UpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgeyBmbHVzaDogJ3Bvc3QnIH0pO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgcm91dGUgPSByb3V0ZVRvRGlzcGxheS52YWx1ZTtcbiAgICAgICAgICAgIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGF0IHRoZSB0aW1lIHdlIHJlbmRlciBiZWNhdXNlIHdoZW4gd2UgdW5tb3VudCwgd2VcbiAgICAgICAgICAgIC8vIG5hdmlnYXRlZCB0byBhIGRpZmZlcmVudCBsb2NhdGlvbiBzbyB0aGUgdmFsdWUgaXMgZGlmZmVyZW50XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50TmFtZSA9IHByb3BzLm5hbWU7XG4gICAgICAgICAgICBjb25zdCBtYXRjaGVkUm91dGUgPSBtYXRjaGVkUm91dGVSZWYudmFsdWU7XG4gICAgICAgICAgICBjb25zdCBWaWV3Q29tcG9uZW50ID0gbWF0Y2hlZFJvdXRlICYmIG1hdGNoZWRSb3V0ZS5jb21wb25lbnRzW2N1cnJlbnROYW1lXTtcbiAgICAgICAgICAgIGlmICghVmlld0NvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBub3JtYWxpemVTbG90KHNsb3RzLmRlZmF1bHQsIHsgQ29tcG9uZW50OiBWaWV3Q29tcG9uZW50LCByb3V0ZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHByb3BzIGZyb20gcm91dGUgY29uZmlndXJhdGlvblxuICAgICAgICAgICAgY29uc3Qgcm91dGVQcm9wc09wdGlvbiA9IG1hdGNoZWRSb3V0ZS5wcm9wc1tjdXJyZW50TmFtZV07XG4gICAgICAgICAgICBjb25zdCByb3V0ZVByb3BzID0gcm91dGVQcm9wc09wdGlvblxuICAgICAgICAgICAgICAgID8gcm91dGVQcm9wc09wdGlvbiA9PT0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICA/IHJvdXRlLnBhcmFtc1xuICAgICAgICAgICAgICAgICAgICA6IHR5cGVvZiByb3V0ZVByb3BzT3B0aW9uID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHJvdXRlUHJvcHNPcHRpb24ocm91dGUpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHJvdXRlUHJvcHNPcHRpb25cbiAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICBjb25zdCBvblZub2RlVW5tb3VudGVkID0gdm5vZGUgPT4ge1xuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgaW5zdGFuY2UgcmVmZXJlbmNlIHRvIHByZXZlbnQgbGVha1xuICAgICAgICAgICAgICAgIGlmICh2bm9kZS5jb21wb25lbnQuaXNVbm1vdW50ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZFJvdXRlLmluc3RhbmNlc1tjdXJyZW50TmFtZV0gPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjb21wb25lbnQgPSBoKFZpZXdDb21wb25lbnQsIGFzc2lnbih7fSwgcm91dGVQcm9wcywgYXR0cnMsIHtcbiAgICAgICAgICAgICAgICBvblZub2RlVW5tb3VudGVkLFxuICAgICAgICAgICAgICAgIHJlZjogdmlld1JlZixcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGlmICgoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHx8IF9fVlVFX1BST0RfREVWVE9PTFNfXykgJiZcbiAgICAgICAgICAgICAgICBpc0Jyb3dzZXIgJiZcbiAgICAgICAgICAgICAgICBjb21wb25lbnQucmVmKSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogY2FuIGRpc3BsYXkgaWYgaXQncyBhbiBhbGlhcywgaXRzIHByb3BzXG4gICAgICAgICAgICAgICAgY29uc3QgaW5mbyA9IHtcbiAgICAgICAgICAgICAgICAgICAgZGVwdGg6IGRlcHRoLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBtYXRjaGVkUm91dGUubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogbWF0Y2hlZFJvdXRlLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgIG1ldGE6IG1hdGNoZWRSb3V0ZS5tZXRhLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY29uc3QgaW50ZXJuYWxJbnN0YW5jZXMgPSBpc0FycmF5KGNvbXBvbmVudC5yZWYpXG4gICAgICAgICAgICAgICAgICAgID8gY29tcG9uZW50LnJlZi5tYXAociA9PiByLmkpXG4gICAgICAgICAgICAgICAgICAgIDogW2NvbXBvbmVudC5yZWYuaV07XG4gICAgICAgICAgICAgICAgaW50ZXJuYWxJbnN0YW5jZXMuZm9yRWFjaChpbnN0YW5jZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuX192cnZfZGV2dG9vbHMgPSBpbmZvO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIC8vIHBhc3MgdGhlIHZub2RlIHRvIHRoZSBzbG90IGFzIGEgcHJvcC5cbiAgICAgICAgICAgIC8vIGggYW5kIDxjb21wb25lbnQgOmlzPVwiLi4uXCI+IGJvdGggYWNjZXB0IHZub2Rlc1xuICAgICAgICAgICAgbm9ybWFsaXplU2xvdChzbG90cy5kZWZhdWx0LCB7IENvbXBvbmVudDogY29tcG9uZW50LCByb3V0ZSB9KSB8fFxuICAgICAgICAgICAgICAgIGNvbXBvbmVudCk7XG4gICAgICAgIH07XG4gICAgfSxcbn0pO1xuZnVuY3Rpb24gbm9ybWFsaXplU2xvdChzbG90LCBkYXRhKSB7XG4gICAgaWYgKCFzbG90KVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBzbG90Q29udGVudCA9IHNsb3QoZGF0YSk7XG4gICAgcmV0dXJuIHNsb3RDb250ZW50Lmxlbmd0aCA9PT0gMSA/IHNsb3RDb250ZW50WzBdIDogc2xvdENvbnRlbnQ7XG59XG4vLyBleHBvcnQgdGhlIHB1YmxpYyB0eXBlIGZvciBoL3RzeCBpbmZlcmVuY2Vcbi8vIGFsc28gdG8gYXZvaWQgaW5saW5lIGltcG9ydCgpIGluIGdlbmVyYXRlZCBkLnRzIGZpbGVzXG4vKipcbiAqIENvbXBvbmVudCB0byBkaXNwbGF5IHRoZSBjdXJyZW50IHJvdXRlIHRoZSB1c2VyIGlzIGF0LlxuICovXG5jb25zdCBSb3V0ZXJWaWV3ID0gUm91dGVyVmlld0ltcGw7XG4vLyB3YXJuIGFnYWluc3QgZGVwcmVjYXRlZCB1c2FnZSB3aXRoIDx0cmFuc2l0aW9uPiAmIDxrZWVwLWFsaXZlPlxuLy8gZHVlIHRvIGZ1bmN0aW9uYWwgY29tcG9uZW50IGJlaW5nIG5vIGxvbmdlciBlYWdlciBpbiBWdWUgM1xuZnVuY3Rpb24gd2FybkRlcHJlY2F0ZWRVc2FnZSgpIHtcbiAgICBjb25zdCBpbnN0YW5jZSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpO1xuICAgIGNvbnN0IHBhcmVudE5hbWUgPSBpbnN0YW5jZS5wYXJlbnQgJiYgaW5zdGFuY2UucGFyZW50LnR5cGUubmFtZTtcbiAgICBjb25zdCBwYXJlbnRTdWJUcmVlVHlwZSA9IGluc3RhbmNlLnBhcmVudCAmJiBpbnN0YW5jZS5wYXJlbnQuc3ViVHJlZSAmJiBpbnN0YW5jZS5wYXJlbnQuc3ViVHJlZS50eXBlO1xuICAgIGlmIChwYXJlbnROYW1lICYmXG4gICAgICAgIChwYXJlbnROYW1lID09PSAnS2VlcEFsaXZlJyB8fCBwYXJlbnROYW1lLmluY2x1ZGVzKCdUcmFuc2l0aW9uJykpICYmXG4gICAgICAgIHR5cGVvZiBwYXJlbnRTdWJUcmVlVHlwZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgcGFyZW50U3ViVHJlZVR5cGUubmFtZSA9PT0gJ1JvdXRlclZpZXcnKSB7XG4gICAgICAgIGNvbnN0IGNvbXAgPSBwYXJlbnROYW1lID09PSAnS2VlcEFsaXZlJyA/ICdrZWVwLWFsaXZlJyA6ICd0cmFuc2l0aW9uJztcbiAgICAgICAgd2FybihgPHJvdXRlci12aWV3PiBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgZGlyZWN0bHkgaW5zaWRlIDx0cmFuc2l0aW9uPiBvciA8a2VlcC1hbGl2ZT4uXFxuYCArXG4gICAgICAgICAgICBgVXNlIHNsb3QgcHJvcHMgaW5zdGVhZDpcXG5cXG5gICtcbiAgICAgICAgICAgIGA8cm91dGVyLXZpZXcgdi1zbG90PVwieyBDb21wb25lbnQgfVwiPlxcbmAgK1xuICAgICAgICAgICAgYCAgPCR7Y29tcH0+XFxuYCArXG4gICAgICAgICAgICBgICAgIDxjb21wb25lbnQgOmlzPVwiQ29tcG9uZW50XCIgLz5cXG5gICtcbiAgICAgICAgICAgIGAgIDwvJHtjb21wfT5cXG5gICtcbiAgICAgICAgICAgIGA8L3JvdXRlci12aWV3PmApO1xuICAgIH1cbn1cblxuLyoqXG4gKiBDb3BpZXMgYSByb3V0ZSBsb2NhdGlvbiBhbmQgcmVtb3ZlcyBhbnkgcHJvYmxlbWF0aWMgcHJvcGVydGllcyB0aGF0IGNhbm5vdCBiZSBzaG93biBpbiBkZXZ0b29scyAoZS5nLiBWdWUgaW5zdGFuY2VzKS5cbiAqXG4gKiBAcGFyYW0gcm91dGVMb2NhdGlvbiAtIHJvdXRlTG9jYXRpb24gdG8gZm9ybWF0XG4gKiBAcGFyYW0gdG9vbHRpcCAtIG9wdGlvbmFsIHRvb2x0aXBcbiAqIEByZXR1cm5zIGEgY29weSBvZiB0aGUgcm91dGVMb2NhdGlvblxuICovXG5mdW5jdGlvbiBmb3JtYXRSb3V0ZUxvY2F0aW9uKHJvdXRlTG9jYXRpb24sIHRvb2x0aXApIHtcbiAgICBjb25zdCBjb3B5ID0gYXNzaWduKHt9LCByb3V0ZUxvY2F0aW9uLCB7XG4gICAgICAgIC8vIHJlbW92ZSB2YXJpYWJsZXMgdGhhdCBjYW4gY29udGFpbiB2dWUgaW5zdGFuY2VzXG4gICAgICAgIG1hdGNoZWQ6IHJvdXRlTG9jYXRpb24ubWF0Y2hlZC5tYXAobWF0Y2hlZCA9PiBvbWl0KG1hdGNoZWQsIFsnaW5zdGFuY2VzJywgJ2NoaWxkcmVuJywgJ2FsaWFzT2YnXSkpLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICAgIF9jdXN0b206IHtcbiAgICAgICAgICAgIHR5cGU6IG51bGwsXG4gICAgICAgICAgICByZWFkT25seTogdHJ1ZSxcbiAgICAgICAgICAgIGRpc3BsYXk6IHJvdXRlTG9jYXRpb24uZnVsbFBhdGgsXG4gICAgICAgICAgICB0b29sdGlwLFxuICAgICAgICAgICAgdmFsdWU6IGNvcHksXG4gICAgICAgIH0sXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGZvcm1hdERpc3BsYXkoZGlzcGxheSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIF9jdXN0b206IHtcbiAgICAgICAgICAgIGRpc3BsYXksXG4gICAgICAgIH0sXG4gICAgfTtcbn1cbi8vIHRvIHN1cHBvcnQgbXVsdGlwbGUgcm91dGVyIGluc3RhbmNlc1xubGV0IHJvdXRlcklkID0gMDtcbmZ1bmN0aW9uIGFkZERldnRvb2xzKGFwcCwgcm91dGVyLCBtYXRjaGVyKSB7XG4gICAgLy8gVGFrZSBvdmVyIHJvdXRlci5iZWZvcmVFYWNoIGFuZCBhZnRlckVhY2hcbiAgICAvLyBtYWtlIHN1cmUgd2UgYXJlIG5vdCByZWdpc3RlcmluZyB0aGUgZGV2dG9vbCB0d2ljZVxuICAgIGlmIChyb3V0ZXIuX19oYXNEZXZ0b29scylcbiAgICAgICAgcmV0dXJuO1xuICAgIHJvdXRlci5fX2hhc0RldnRvb2xzID0gdHJ1ZTtcbiAgICAvLyBpbmNyZW1lbnQgdG8gc3VwcG9ydCBtdWx0aXBsZSByb3V0ZXIgaW5zdGFuY2VzXG4gICAgY29uc3QgaWQgPSByb3V0ZXJJZCsrO1xuICAgIHNldHVwRGV2dG9vbHNQbHVnaW4oe1xuICAgICAgICBpZDogJ29yZy52dWVqcy5yb3V0ZXInICsgKGlkID8gJy4nICsgaWQgOiAnJyksXG4gICAgICAgIGxhYmVsOiAnVnVlIFJvdXRlcicsXG4gICAgICAgIHBhY2thZ2VOYW1lOiAndnVlLXJvdXRlcicsXG4gICAgICAgIGhvbWVwYWdlOiAnaHR0cHM6Ly9yb3V0ZXIudnVlanMub3JnJyxcbiAgICAgICAgbG9nbzogJ2h0dHBzOi8vcm91dGVyLnZ1ZWpzLm9yZy9sb2dvLnBuZycsXG4gICAgICAgIGNvbXBvbmVudFN0YXRlVHlwZXM6IFsnUm91dGluZyddLFxuICAgICAgICBhcHAsXG4gICAgfSwgYXBpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBhcGkubm93ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tWdWUgUm91dGVyXTogWW91IHNlZW0gdG8gYmUgdXNpbmcgYW4gb3V0ZGF0ZWQgdmVyc2lvbiBvZiBWdWUgRGV2dG9vbHMuIEFyZSB5b3Ugc3RpbGwgdXNpbmcgdGhlIEJldGEgcmVsZWFzZSBpbnN0ZWFkIG9mIHRoZSBzdGFibGUgb25lPyBZb3UgY2FuIGZpbmQgdGhlIGxpbmtzIGF0IGh0dHBzOi8vZGV2dG9vbHMudnVlanMub3JnL2d1aWRlL2luc3RhbGxhdGlvbi5odG1sLicpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGRpc3BsYXkgc3RhdGUgYWRkZWQgYnkgdGhlIHJvdXRlclxuICAgICAgICBhcGkub24uaW5zcGVjdENvbXBvbmVudCgocGF5bG9hZCwgY3R4KSA9PiB7XG4gICAgICAgICAgICBpZiAocGF5bG9hZC5pbnN0YW5jZURhdGEpIHtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmluc3RhbmNlRGF0YS5zdGF0ZS5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1JvdXRpbmcnLFxuICAgICAgICAgICAgICAgICAgICBrZXk6ICckcm91dGUnLFxuICAgICAgICAgICAgICAgICAgICBlZGl0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmb3JtYXRSb3V0ZUxvY2F0aW9uKHJvdXRlci5jdXJyZW50Um91dGUudmFsdWUsICdDdXJyZW50IFJvdXRlJyksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYXJrIHJvdXRlci1saW5rIGFzIGFjdGl2ZSBhbmQgZGlzcGxheSB0YWdzIG9uIHJvdXRlciB2aWV3c1xuICAgICAgICBhcGkub24udmlzaXRDb21wb25lbnRUcmVlKCh7IHRyZWVOb2RlOiBub2RlLCBjb21wb25lbnRJbnN0YW5jZSB9KSA9PiB7XG4gICAgICAgICAgICBpZiAoY29tcG9uZW50SW5zdGFuY2UuX192cnZfZGV2dG9vbHMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbmZvID0gY29tcG9uZW50SW5zdGFuY2UuX192cnZfZGV2dG9vbHM7XG4gICAgICAgICAgICAgICAgbm9kZS50YWdzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogKGluZm8ubmFtZSA/IGAke2luZm8ubmFtZS50b1N0cmluZygpfTogYCA6ICcnKSArIGluZm8ucGF0aCxcbiAgICAgICAgICAgICAgICAgICAgdGV4dENvbG9yOiAwLFxuICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiAnVGhpcyBjb21wb25lbnQgaXMgcmVuZGVyZWQgYnkgJmx0O3JvdXRlci12aWV3Jmd0OycsXG4gICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogUElOS181MDAsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBpZiBtdWx0aXBsZSB1c2VMaW5rIGFyZSB1c2VkXG4gICAgICAgICAgICBpZiAoaXNBcnJheShjb21wb25lbnRJbnN0YW5jZS5fX3ZybF9kZXZ0b29scykpIHtcbiAgICAgICAgICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5fX2RldnRvb2xzQXBpID0gYXBpO1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudEluc3RhbmNlLl9fdnJsX2RldnRvb2xzLmZvckVhY2goZGV2dG9vbHNEYXRhID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gZGV2dG9vbHNEYXRhLnJvdXRlLnBhdGg7XG4gICAgICAgICAgICAgICAgICAgIGxldCBiYWNrZ3JvdW5kQ29sb3IgPSBPUkFOR0VfNDAwO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdG9vbHRpcCA9ICcnO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdGV4dENvbG9yID0gMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRldnRvb2xzRGF0YS5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSBkZXZ0b29sc0RhdGEuZXJyb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3IgPSBSRURfMTAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dENvbG9yID0gUkVEXzcwMDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChkZXZ0b29sc0RhdGEuaXNFeGFjdEFjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yID0gTElNRV81MDA7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwID0gJ1RoaXMgaXMgZXhhY3RseSBhY3RpdmUnO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRldnRvb2xzRGF0YS5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yID0gQkxVRV82MDA7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwID0gJ1RoaXMgbGluayBpcyBhY3RpdmUnO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG5vZGUudGFncy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dENvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB3YXRjaChyb3V0ZXIuY3VycmVudFJvdXRlLCAoKSA9PiB7XG4gICAgICAgICAgICAvLyByZWZyZXNoIGFjdGl2ZSBzdGF0ZVxuICAgICAgICAgICAgcmVmcmVzaFJvdXRlc1ZpZXcoKTtcbiAgICAgICAgICAgIGFwaS5ub3RpZnlDb21wb25lbnRVcGRhdGUoKTtcbiAgICAgICAgICAgIGFwaS5zZW5kSW5zcGVjdG9yVHJlZShyb3V0ZXJJbnNwZWN0b3JJZCk7XG4gICAgICAgICAgICBhcGkuc2VuZEluc3BlY3RvclN0YXRlKHJvdXRlckluc3BlY3RvcklkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5hdmlnYXRpb25zTGF5ZXJJZCA9ICdyb3V0ZXI6bmF2aWdhdGlvbnM6JyArIGlkO1xuICAgICAgICBhcGkuYWRkVGltZWxpbmVMYXllcih7XG4gICAgICAgICAgICBpZDogbmF2aWdhdGlvbnNMYXllcklkLFxuICAgICAgICAgICAgbGFiZWw6IGBSb3V0ZXIke2lkID8gJyAnICsgaWQgOiAnJ30gTmF2aWdhdGlvbnNgLFxuICAgICAgICAgICAgY29sb3I6IDB4NDBhOGM0LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29uc3QgZXJyb3JzTGF5ZXJJZCA9ICdyb3V0ZXI6ZXJyb3JzJ1xuICAgICAgICAvLyBhcGkuYWRkVGltZWxpbmVMYXllcih7XG4gICAgICAgIC8vICAgaWQ6IGVycm9yc0xheWVySWQsXG4gICAgICAgIC8vICAgbGFiZWw6ICdSb3V0ZXIgRXJyb3JzJyxcbiAgICAgICAgLy8gICBjb2xvcjogMHhlYTU0NTUsXG4gICAgICAgIC8vIH0pXG4gICAgICAgIHJvdXRlci5vbkVycm9yKChlcnJvciwgdG8pID0+IHtcbiAgICAgICAgICAgIGFwaS5hZGRUaW1lbGluZUV2ZW50KHtcbiAgICAgICAgICAgICAgICBsYXllcklkOiBuYXZpZ2F0aW9uc0xheWVySWQsXG4gICAgICAgICAgICAgICAgZXZlbnQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdFcnJvciBkdXJpbmcgTmF2aWdhdGlvbicsXG4gICAgICAgICAgICAgICAgICAgIHN1YnRpdGxlOiB0by5mdWxsUGF0aCxcbiAgICAgICAgICAgICAgICAgICAgbG9nVHlwZTogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgdGltZTogYXBpLm5vdygpLFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiB7IGVycm9yIH0sXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwSWQ6IHRvLm1ldGEuX19uYXZpZ2F0aW9uSWQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gYXR0YWNoZWQgdG8gYG1ldGFgIGFuZCB1c2VkIHRvIGdyb3VwIGV2ZW50c1xuICAgICAgICBsZXQgbmF2aWdhdGlvbklkID0gMDtcbiAgICAgICAgcm91dGVyLmJlZm9yZUVhY2goKHRvLCBmcm9tKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgICAgIGd1YXJkOiBmb3JtYXREaXNwbGF5KCdiZWZvcmVFYWNoJyksXG4gICAgICAgICAgICAgICAgZnJvbTogZm9ybWF0Um91dGVMb2NhdGlvbihmcm9tLCAnQ3VycmVudCBMb2NhdGlvbiBkdXJpbmcgdGhpcyBuYXZpZ2F0aW9uJyksXG4gICAgICAgICAgICAgICAgdG86IGZvcm1hdFJvdXRlTG9jYXRpb24odG8sICdUYXJnZXQgbG9jYXRpb24nKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBVc2VkIHRvIGdyb3VwIG5hdmlnYXRpb25zIHRvZ2V0aGVyLCBoaWRlIGZyb20gZGV2dG9vbHNcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0by5tZXRhLCAnX19uYXZpZ2F0aW9uSWQnLCB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IG5hdmlnYXRpb25JZCsrLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhcGkuYWRkVGltZWxpbmVFdmVudCh7XG4gICAgICAgICAgICAgICAgbGF5ZXJJZDogbmF2aWdhdGlvbnNMYXllcklkLFxuICAgICAgICAgICAgICAgIGV2ZW50OiB7XG4gICAgICAgICAgICAgICAgICAgIHRpbWU6IGFwaS5ub3coKSxcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdTdGFydCBvZiBuYXZpZ2F0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgc3VidGl0bGU6IHRvLmZ1bGxQYXRoLFxuICAgICAgICAgICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgICAgICAgICBncm91cElkOiB0by5tZXRhLl9fbmF2aWdhdGlvbklkLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJvdXRlci5hZnRlckVhY2goKHRvLCBmcm9tLCBmYWlsdXJlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge1xuICAgICAgICAgICAgICAgIGd1YXJkOiBmb3JtYXREaXNwbGF5KCdhZnRlckVhY2gnKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoZmFpbHVyZSkge1xuICAgICAgICAgICAgICAgIGRhdGEuZmFpbHVyZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgX2N1c3RvbToge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogRXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkT25seTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6IGZhaWx1cmUgPyBmYWlsdXJlLm1lc3NhZ2UgOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6ICdOYXZpZ2F0aW9uIEZhaWx1cmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZhaWx1cmUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBkYXRhLnN0YXR1cyA9IGZvcm1hdERpc3BsYXkoJ+KdjCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGF0YS5zdGF0dXMgPSBmb3JtYXREaXNwbGF5KCfinIUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHdlIHNldCBoZXJlIHRvIGhhdmUgdGhlIHJpZ2h0IG9yZGVyXG4gICAgICAgICAgICBkYXRhLmZyb20gPSBmb3JtYXRSb3V0ZUxvY2F0aW9uKGZyb20sICdDdXJyZW50IExvY2F0aW9uIGR1cmluZyB0aGlzIG5hdmlnYXRpb24nKTtcbiAgICAgICAgICAgIGRhdGEudG8gPSBmb3JtYXRSb3V0ZUxvY2F0aW9uKHRvLCAnVGFyZ2V0IGxvY2F0aW9uJyk7XG4gICAgICAgICAgICBhcGkuYWRkVGltZWxpbmVFdmVudCh7XG4gICAgICAgICAgICAgICAgbGF5ZXJJZDogbmF2aWdhdGlvbnNMYXllcklkLFxuICAgICAgICAgICAgICAgIGV2ZW50OiB7XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnRW5kIG9mIG5hdmlnYXRpb24nLFxuICAgICAgICAgICAgICAgICAgICBzdWJ0aXRsZTogdG8uZnVsbFBhdGgsXG4gICAgICAgICAgICAgICAgICAgIHRpbWU6IGFwaS5ub3coKSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgbG9nVHlwZTogZmFpbHVyZSA/ICd3YXJuaW5nJyA6ICdkZWZhdWx0JyxcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBJZDogdG8ubWV0YS5fX25hdmlnYXRpb25JZCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5zcGVjdG9yIG9mIEV4aXN0aW5nIHJvdXRlc1xuICAgICAgICAgKi9cbiAgICAgICAgY29uc3Qgcm91dGVySW5zcGVjdG9ySWQgPSAncm91dGVyLWluc3BlY3RvcjonICsgaWQ7XG4gICAgICAgIGFwaS5hZGRJbnNwZWN0b3Ioe1xuICAgICAgICAgICAgaWQ6IHJvdXRlckluc3BlY3RvcklkLFxuICAgICAgICAgICAgbGFiZWw6ICdSb3V0ZXMnICsgKGlkID8gJyAnICsgaWQgOiAnJyksXG4gICAgICAgICAgICBpY29uOiAnYm9vaycsXG4gICAgICAgICAgICB0cmVlRmlsdGVyUGxhY2Vob2xkZXI6ICdTZWFyY2ggcm91dGVzJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hSb3V0ZXNWaWV3KCkge1xuICAgICAgICAgICAgLy8gdGhlIHJvdXRlcyB2aWV3IGlzbid0IGFjdGl2ZVxuICAgICAgICAgICAgaWYgKCFhY3RpdmVSb3V0ZXNQYXlsb2FkKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBhY3RpdmVSb3V0ZXNQYXlsb2FkO1xuICAgICAgICAgICAgLy8gY2hpbGRyZW4gcm91dGVzIHdpbGwgYXBwZWFyIGFzIG5lc3RlZFxuICAgICAgICAgICAgbGV0IHJvdXRlcyA9IG1hdGNoZXIuZ2V0Um91dGVzKCkuZmlsdGVyKHJvdXRlID0+ICFyb3V0ZS5wYXJlbnQgfHxcbiAgICAgICAgICAgICAgICAvLyB0aGVzZSByb3V0ZXMgaGF2ZSBhIHBhcmVudCB3aXRoIG5vIGNvbXBvbmVudCB3aGljaCB3aWxsIG5vdCBhcHBlYXIgaW4gdGhlIHZpZXdcbiAgICAgICAgICAgICAgICAvLyB0aGVyZWZvcmUgd2Ugc3RpbGwgbmVlZCB0byBpbmNsdWRlIHRoZW1cbiAgICAgICAgICAgICAgICAhcm91dGUucGFyZW50LnJlY29yZC5jb21wb25lbnRzKTtcbiAgICAgICAgICAgIC8vIHJlc2V0IG1hdGNoIHN0YXRlIHRvIGZhbHNlXG4gICAgICAgICAgICByb3V0ZXMuZm9yRWFjaChyZXNldE1hdGNoU3RhdGVPblJvdXRlUmVjb3JkKTtcbiAgICAgICAgICAgIC8vIGFwcGx5IGEgbWF0Y2ggc3RhdGUgaWYgdGhlcmUgaXMgYSBwYXlsb2FkXG4gICAgICAgICAgICBpZiAocGF5bG9hZC5maWx0ZXIpIHtcbiAgICAgICAgICAgICAgICByb3V0ZXMgPSByb3V0ZXMuZmlsdGVyKHJvdXRlID0+IFxuICAgICAgICAgICAgICAgIC8vIHNhdmUgbWF0Y2hlcyBzdGF0ZSBiYXNlZCBvbiB0aGUgcGF5bG9hZFxuICAgICAgICAgICAgICAgIGlzUm91dGVNYXRjaGluZyhyb3V0ZSwgcGF5bG9hZC5maWx0ZXIudG9Mb3dlckNhc2UoKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gbWFyayBhY3RpdmUgcm91dGVzXG4gICAgICAgICAgICByb3V0ZXMuZm9yRWFjaChyb3V0ZSA9PiBtYXJrUm91dGVSZWNvcmRBY3RpdmUocm91dGUsIHJvdXRlci5jdXJyZW50Um91dGUudmFsdWUpKTtcbiAgICAgICAgICAgIHBheWxvYWQucm9vdE5vZGVzID0gcm91dGVzLm1hcChmb3JtYXRSb3V0ZVJlY29yZEZvckluc3BlY3Rvcik7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGFjdGl2ZVJvdXRlc1BheWxvYWQ7XG4gICAgICAgIGFwaS5vbi5nZXRJbnNwZWN0b3JUcmVlKHBheWxvYWQgPT4ge1xuICAgICAgICAgICAgYWN0aXZlUm91dGVzUGF5bG9hZCA9IHBheWxvYWQ7XG4gICAgICAgICAgICBpZiAocGF5bG9hZC5hcHAgPT09IGFwcCAmJiBwYXlsb2FkLmluc3BlY3RvcklkID09PSByb3V0ZXJJbnNwZWN0b3JJZCkge1xuICAgICAgICAgICAgICAgIHJlZnJlc2hSb3V0ZXNWaWV3KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHJvdXRlIHJlY29yZFxuICAgICAgICAgKi9cbiAgICAgICAgYXBpLm9uLmdldEluc3BlY3RvclN0YXRlKHBheWxvYWQgPT4ge1xuICAgICAgICAgICAgaWYgKHBheWxvYWQuYXBwID09PSBhcHAgJiYgcGF5bG9hZC5pbnNwZWN0b3JJZCA9PT0gcm91dGVySW5zcGVjdG9ySWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByb3V0ZXMgPSBtYXRjaGVyLmdldFJvdXRlcygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJvdXRlID0gcm91dGVzLmZpbmQocm91dGUgPT4gcm91dGUucmVjb3JkLl9fdmRfaWQgPT09IHBheWxvYWQubm9kZUlkKTtcbiAgICAgICAgICAgICAgICBpZiAocm91dGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZC5zdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IGZvcm1hdFJvdXRlUmVjb3JkTWF0Y2hlckZvclN0YXRlSW5zcGVjdG9yKHJvdXRlKSxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBhcGkuc2VuZEluc3BlY3RvclRyZWUocm91dGVySW5zcGVjdG9ySWQpO1xuICAgICAgICBhcGkuc2VuZEluc3BlY3RvclN0YXRlKHJvdXRlckluc3BlY3RvcklkKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIG1vZGlmaWVyRm9yS2V5KGtleSkge1xuICAgIGlmIChrZXkub3B0aW9uYWwpIHtcbiAgICAgICAgcmV0dXJuIGtleS5yZXBlYXRhYmxlID8gJyonIDogJz8nO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGtleS5yZXBlYXRhYmxlID8gJysnIDogJyc7XG4gICAgfVxufVxuZnVuY3Rpb24gZm9ybWF0Um91dGVSZWNvcmRNYXRjaGVyRm9yU3RhdGVJbnNwZWN0b3Iocm91dGUpIHtcbiAgICBjb25zdCB7IHJlY29yZCB9ID0gcm91dGU7XG4gICAgY29uc3QgZmllbGRzID0gW1xuICAgICAgICB7IGVkaXRhYmxlOiBmYWxzZSwga2V5OiAncGF0aCcsIHZhbHVlOiByZWNvcmQucGF0aCB9LFxuICAgIF07XG4gICAgaWYgKHJlY29yZC5uYW1lICE9IG51bGwpIHtcbiAgICAgICAgZmllbGRzLnB1c2goe1xuICAgICAgICAgICAgZWRpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAga2V5OiAnbmFtZScsXG4gICAgICAgICAgICB2YWx1ZTogcmVjb3JkLm5hbWUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBmaWVsZHMucHVzaCh7IGVkaXRhYmxlOiBmYWxzZSwga2V5OiAncmVnZXhwJywgdmFsdWU6IHJvdXRlLnJlIH0pO1xuICAgIGlmIChyb3V0ZS5rZXlzLmxlbmd0aCkge1xuICAgICAgICBmaWVsZHMucHVzaCh7XG4gICAgICAgICAgICBlZGl0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICBrZXk6ICdrZXlzJyxcbiAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgICAgX2N1c3RvbToge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICByZWFkT25seTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogcm91dGUua2V5c1xuICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChrZXkgPT4gYCR7a2V5Lm5hbWV9JHttb2RpZmllckZvcktleShrZXkpfWApXG4gICAgICAgICAgICAgICAgICAgICAgICAuam9pbignICcpLFxuICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiAnUGFyYW0ga2V5cycsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiByb3V0ZS5rZXlzLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHJlY29yZC5yZWRpcmVjdCAhPSBudWxsKSB7XG4gICAgICAgIGZpZWxkcy5wdXNoKHtcbiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGtleTogJ3JlZGlyZWN0JyxcbiAgICAgICAgICAgIHZhbHVlOiByZWNvcmQucmVkaXJlY3QsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAocm91dGUuYWxpYXMubGVuZ3RoKSB7XG4gICAgICAgIGZpZWxkcy5wdXNoKHtcbiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGtleTogJ2FsaWFzZXMnLFxuICAgICAgICAgICAgdmFsdWU6IHJvdXRlLmFsaWFzLm1hcChhbGlhcyA9PiBhbGlhcy5yZWNvcmQucGF0aCksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoT2JqZWN0LmtleXMocm91dGUucmVjb3JkLm1ldGEpLmxlbmd0aCkge1xuICAgICAgICBmaWVsZHMucHVzaCh7XG4gICAgICAgICAgICBlZGl0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICBrZXk6ICdtZXRhJyxcbiAgICAgICAgICAgIHZhbHVlOiByb3V0ZS5yZWNvcmQubWV0YSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGZpZWxkcy5wdXNoKHtcbiAgICAgICAga2V5OiAnc2NvcmUnLFxuICAgICAgICBlZGl0YWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICBfY3VzdG9tOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogbnVsbCxcbiAgICAgICAgICAgICAgICByZWFkT25seTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiByb3V0ZS5zY29yZS5tYXAoc2NvcmUgPT4gc2NvcmUuam9pbignLCAnKSkuam9pbignIHwgJyksXG4gICAgICAgICAgICAgICAgdG9vbHRpcDogJ1Njb3JlIHVzZWQgdG8gc29ydCByb3V0ZXMnLFxuICAgICAgICAgICAgICAgIHZhbHVlOiByb3V0ZS5zY29yZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIGZpZWxkcztcbn1cbi8qKlxuICogRXh0cmFjdGVkIGZyb20gdGFpbHdpbmQgcGFsZXR0ZVxuICovXG5jb25zdCBQSU5LXzUwMCA9IDB4ZWM0ODk5O1xuY29uc3QgQkxVRV82MDAgPSAweDI1NjNlYjtcbmNvbnN0IExJTUVfNTAwID0gMHg4NGNjMTY7XG5jb25zdCBDWUFOXzQwMCA9IDB4MjJkM2VlO1xuY29uc3QgT1JBTkdFXzQwMCA9IDB4ZmI5MjNjO1xuLy8gY29uc3QgR1JBWV8xMDAgPSAweGY0ZjRmNVxuY29uc3QgREFSSyA9IDB4NjY2NjY2O1xuY29uc3QgUkVEXzEwMCA9IDB4ZmVlMmUyO1xuY29uc3QgUkVEXzcwMCA9IDB4YjkxYzFjO1xuZnVuY3Rpb24gZm9ybWF0Um91dGVSZWNvcmRGb3JJbnNwZWN0b3Iocm91dGUpIHtcbiAgICBjb25zdCB0YWdzID0gW107XG4gICAgY29uc3QgeyByZWNvcmQgfSA9IHJvdXRlO1xuICAgIGlmIChyZWNvcmQubmFtZSAhPSBudWxsKSB7XG4gICAgICAgIHRhZ3MucHVzaCh7XG4gICAgICAgICAgICBsYWJlbDogU3RyaW5nKHJlY29yZC5uYW1lKSxcbiAgICAgICAgICAgIHRleHRDb2xvcjogMCxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogQ1lBTl80MDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAocmVjb3JkLmFsaWFzT2YpIHtcbiAgICAgICAgdGFncy5wdXNoKHtcbiAgICAgICAgICAgIGxhYmVsOiAnYWxpYXMnLFxuICAgICAgICAgICAgdGV4dENvbG9yOiAwLFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBPUkFOR0VfNDAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHJvdXRlLl9fdmRfbWF0Y2gpIHtcbiAgICAgICAgdGFncy5wdXNoKHtcbiAgICAgICAgICAgIGxhYmVsOiAnbWF0Y2hlcycsXG4gICAgICAgICAgICB0ZXh0Q29sb3I6IDAsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IFBJTktfNTAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHJvdXRlLl9fdmRfZXhhY3RBY3RpdmUpIHtcbiAgICAgICAgdGFncy5wdXNoKHtcbiAgICAgICAgICAgIGxhYmVsOiAnZXhhY3QnLFxuICAgICAgICAgICAgdGV4dENvbG9yOiAwLFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBMSU1FXzUwMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChyb3V0ZS5fX3ZkX2FjdGl2ZSkge1xuICAgICAgICB0YWdzLnB1c2goe1xuICAgICAgICAgICAgbGFiZWw6ICdhY3RpdmUnLFxuICAgICAgICAgICAgdGV4dENvbG9yOiAwLFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBCTFVFXzYwMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChyZWNvcmQucmVkaXJlY3QpIHtcbiAgICAgICAgdGFncy5wdXNoKHtcbiAgICAgICAgICAgIGxhYmVsOiB0eXBlb2YgcmVjb3JkLnJlZGlyZWN0ID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgID8gYHJlZGlyZWN0OiAke3JlY29yZC5yZWRpcmVjdH1gXG4gICAgICAgICAgICAgICAgOiAncmVkaXJlY3RzJyxcbiAgICAgICAgICAgIHRleHRDb2xvcjogMHhmZmZmZmYsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IERBUkssXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBhZGQgYW4gaWQgdG8gYmUgYWJsZSB0byBzZWxlY3QgaXQuIFVzaW5nIHRoZSBgcGF0aGAgaXMgbm90IHBvc3NpYmxlIGJlY2F1c2VcbiAgICAvLyBlbXB0eSBwYXRoIGNoaWxkcmVuIHdvdWxkIGNvbGxpZGUgd2l0aCB0aGVpciBwYXJlbnRzXG4gICAgbGV0IGlkID0gcmVjb3JkLl9fdmRfaWQ7XG4gICAgaWYgKGlkID09IG51bGwpIHtcbiAgICAgICAgaWQgPSBTdHJpbmcocm91dGVSZWNvcmRJZCsrKTtcbiAgICAgICAgcmVjb3JkLl9fdmRfaWQgPSBpZDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgaWQsXG4gICAgICAgIGxhYmVsOiByZWNvcmQucGF0aCxcbiAgICAgICAgdGFncyxcbiAgICAgICAgY2hpbGRyZW46IHJvdXRlLmNoaWxkcmVuLm1hcChmb3JtYXRSb3V0ZVJlY29yZEZvckluc3BlY3RvciksXG4gICAgfTtcbn1cbi8vICBpbmNyZW1lbnRhbCBpZCBmb3Igcm91dGUgcmVjb3JkcyBhbmQgaW5zcGVjdG9yIHN0YXRlXG5sZXQgcm91dGVSZWNvcmRJZCA9IDA7XG5jb25zdCBFWFRSQUNUX1JFR0VYUF9SRSA9IC9eXFwvKC4qKVxcLyhbYS16XSopJC87XG5mdW5jdGlvbiBtYXJrUm91dGVSZWNvcmRBY3RpdmUocm91dGUsIGN1cnJlbnRSb3V0ZSkge1xuICAgIC8vIG5vIHJvdXRlIHdpbGwgYmUgYWN0aXZlIGlmIG1hdGNoZWQgaXMgZW1wdHlcbiAgICAvLyByZXNldCB0aGUgbWF0Y2hpbmcgc3RhdGVcbiAgICBjb25zdCBpc0V4YWN0QWN0aXZlID0gY3VycmVudFJvdXRlLm1hdGNoZWQubGVuZ3RoICYmXG4gICAgICAgIGlzU2FtZVJvdXRlUmVjb3JkKGN1cnJlbnRSb3V0ZS5tYXRjaGVkW2N1cnJlbnRSb3V0ZS5tYXRjaGVkLmxlbmd0aCAtIDFdLCByb3V0ZS5yZWNvcmQpO1xuICAgIHJvdXRlLl9fdmRfZXhhY3RBY3RpdmUgPSByb3V0ZS5fX3ZkX2FjdGl2ZSA9IGlzRXhhY3RBY3RpdmU7XG4gICAgaWYgKCFpc0V4YWN0QWN0aXZlKSB7XG4gICAgICAgIHJvdXRlLl9fdmRfYWN0aXZlID0gY3VycmVudFJvdXRlLm1hdGNoZWQuc29tZShtYXRjaCA9PiBpc1NhbWVSb3V0ZVJlY29yZChtYXRjaCwgcm91dGUucmVjb3JkKSk7XG4gICAgfVxuICAgIHJvdXRlLmNoaWxkcmVuLmZvckVhY2goY2hpbGRSb3V0ZSA9PiBtYXJrUm91dGVSZWNvcmRBY3RpdmUoY2hpbGRSb3V0ZSwgY3VycmVudFJvdXRlKSk7XG59XG5mdW5jdGlvbiByZXNldE1hdGNoU3RhdGVPblJvdXRlUmVjb3JkKHJvdXRlKSB7XG4gICAgcm91dGUuX192ZF9tYXRjaCA9IGZhbHNlO1xuICAgIHJvdXRlLmNoaWxkcmVuLmZvckVhY2gocmVzZXRNYXRjaFN0YXRlT25Sb3V0ZVJlY29yZCk7XG59XG5mdW5jdGlvbiBpc1JvdXRlTWF0Y2hpbmcocm91dGUsIGZpbHRlcikge1xuICAgIGNvbnN0IGZvdW5kID0gU3RyaW5nKHJvdXRlLnJlKS5tYXRjaChFWFRSQUNUX1JFR0VYUF9SRSk7XG4gICAgcm91dGUuX192ZF9tYXRjaCA9IGZhbHNlO1xuICAgIGlmICghZm91bmQgfHwgZm91bmQubGVuZ3RoIDwgMykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIHVzZSBhIHJlZ2V4cCB3aXRob3V0ICQgYXQgdGhlIGVuZCB0byBtYXRjaCBuZXN0ZWQgcm91dGVzIGJldHRlclxuICAgIGNvbnN0IG5vbkVuZGluZ1JFID0gbmV3IFJlZ0V4cChmb3VuZFsxXS5yZXBsYWNlKC9cXCQkLywgJycpLCBmb3VuZFsyXSk7XG4gICAgaWYgKG5vbkVuZGluZ1JFLnRlc3QoZmlsdGVyKSkge1xuICAgICAgICAvLyBtYXJrIGNoaWxkcmVuIGFzIG1hdGNoZXNcbiAgICAgICAgcm91dGUuY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiBpc1JvdXRlTWF0Y2hpbmcoY2hpbGQsIGZpbHRlcikpO1xuICAgICAgICAvLyBleGNlcHRpb24gY2FzZTogYC9gXG4gICAgICAgIGlmIChyb3V0ZS5yZWNvcmQucGF0aCAhPT0gJy8nIHx8IGZpbHRlciA9PT0gJy8nKSB7XG4gICAgICAgICAgICByb3V0ZS5fX3ZkX21hdGNoID0gcm91dGUucmUudGVzdChmaWx0ZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaGlkZSB0aGUgLyByb3V0ZVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHBhdGggPSByb3V0ZS5yZWNvcmQucGF0aC50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IGRlY29kZWRQYXRoID0gZGVjb2RlKHBhdGgpO1xuICAgIC8vIGFsc28gYWxsb3cgcGFydGlhbCBtYXRjaGluZyBvbiB0aGUgcGF0aFxuICAgIGlmICghZmlsdGVyLnN0YXJ0c1dpdGgoJy8nKSAmJlxuICAgICAgICAoZGVjb2RlZFBhdGguaW5jbHVkZXMoZmlsdGVyKSB8fCBwYXRoLmluY2x1ZGVzKGZpbHRlcikpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoZGVjb2RlZFBhdGguc3RhcnRzV2l0aChmaWx0ZXIpIHx8IHBhdGguc3RhcnRzV2l0aChmaWx0ZXIpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICBpZiAocm91dGUucmVjb3JkLm5hbWUgJiYgU3RyaW5nKHJvdXRlLnJlY29yZC5uYW1lKS5pbmNsdWRlcyhmaWx0ZXIpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gcm91dGUuY2hpbGRyZW4uc29tZShjaGlsZCA9PiBpc1JvdXRlTWF0Y2hpbmcoY2hpbGQsIGZpbHRlcikpO1xufVxuZnVuY3Rpb24gb21pdChvYmosIGtleXMpIHtcbiAgICBjb25zdCByZXQgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKCFrZXlzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIHJldFtrZXldID0gb2JqW2tleV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgUm91dGVyIGluc3RhbmNlIHRoYXQgY2FuIGJlIHVzZWQgYnkgYSBWdWUgYXBwLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0ge0BsaW5rIFJvdXRlck9wdGlvbnN9XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVJvdXRlcihvcHRpb25zKSB7XG4gICAgY29uc3QgbWF0Y2hlciA9IGNyZWF0ZVJvdXRlck1hdGNoZXIob3B0aW9ucy5yb3V0ZXMsIG9wdGlvbnMpO1xuICAgIGNvbnN0IHBhcnNlUXVlcnkkMSA9IG9wdGlvbnMucGFyc2VRdWVyeSB8fCBwYXJzZVF1ZXJ5O1xuICAgIGNvbnN0IHN0cmluZ2lmeVF1ZXJ5JDEgPSBvcHRpb25zLnN0cmluZ2lmeVF1ZXJ5IHx8IHN0cmluZ2lmeVF1ZXJ5O1xuICAgIGNvbnN0IHJvdXRlckhpc3RvcnkgPSBvcHRpb25zLmhpc3Rvcnk7XG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhcm91dGVySGlzdG9yeSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm92aWRlIHRoZSBcImhpc3RvcnlcIiBvcHRpb24gd2hlbiBjYWxsaW5nIFwiY3JlYXRlUm91dGVyKClcIjonICtcbiAgICAgICAgICAgICcgaHR0cHM6Ly9yb3V0ZXIudnVlanMub3JnL2FwaS9pbnRlcmZhY2VzL1JvdXRlck9wdGlvbnMuaHRtbCNoaXN0b3J5Jyk7XG4gICAgY29uc3QgYmVmb3JlR3VhcmRzID0gdXNlQ2FsbGJhY2tzKCk7XG4gICAgY29uc3QgYmVmb3JlUmVzb2x2ZUd1YXJkcyA9IHVzZUNhbGxiYWNrcygpO1xuICAgIGNvbnN0IGFmdGVyR3VhcmRzID0gdXNlQ2FsbGJhY2tzKCk7XG4gICAgY29uc3QgY3VycmVudFJvdXRlID0gc2hhbGxvd1JlZihTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEKTtcbiAgICBsZXQgcGVuZGluZ0xvY2F0aW9uID0gU1RBUlRfTE9DQVRJT05fTk9STUFMSVpFRDtcbiAgICAvLyBsZWF2ZSB0aGUgc2Nyb2xsUmVzdG9yYXRpb24gaWYgbm8gc2Nyb2xsQmVoYXZpb3IgaXMgcHJvdmlkZWRcbiAgICBpZiAoaXNCcm93c2VyICYmIG9wdGlvbnMuc2Nyb2xsQmVoYXZpb3IgJiYgJ3Njcm9sbFJlc3RvcmF0aW9uJyBpbiBoaXN0b3J5KSB7XG4gICAgICAgIGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSAnbWFudWFsJztcbiAgICB9XG4gICAgY29uc3Qgbm9ybWFsaXplUGFyYW1zID0gYXBwbHlUb1BhcmFtcy5iaW5kKG51bGwsIHBhcmFtVmFsdWUgPT4gJycgKyBwYXJhbVZhbHVlKTtcbiAgICBjb25zdCBlbmNvZGVQYXJhbXMgPSBhcHBseVRvUGFyYW1zLmJpbmQobnVsbCwgZW5jb2RlUGFyYW0pO1xuICAgIGNvbnN0IGRlY29kZVBhcmFtcyA9IFxuICAgIC8vIEB0cy1leHBlY3QtZXJyb3I6IGludGVudGlvbmFsbHkgYXZvaWQgdGhlIHR5cGUgY2hlY2tcbiAgICBhcHBseVRvUGFyYW1zLmJpbmQobnVsbCwgZGVjb2RlKTtcbiAgICBmdW5jdGlvbiBhZGRSb3V0ZShwYXJlbnRPclJvdXRlLCByb3V0ZSkge1xuICAgICAgICBsZXQgcGFyZW50O1xuICAgICAgICBsZXQgcmVjb3JkO1xuICAgICAgICBpZiAoaXNSb3V0ZU5hbWUocGFyZW50T3JSb3V0ZSkpIHtcbiAgICAgICAgICAgIHBhcmVudCA9IG1hdGNoZXIuZ2V0UmVjb3JkTWF0Y2hlcihwYXJlbnRPclJvdXRlKTtcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIXBhcmVudCkge1xuICAgICAgICAgICAgICAgIHdhcm4oYFBhcmVudCByb3V0ZSBcIiR7U3RyaW5nKHBhcmVudE9yUm91dGUpfVwiIG5vdCBmb3VuZCB3aGVuIGFkZGluZyBjaGlsZCByb3V0ZWAsIHJvdXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlY29yZCA9IHJvdXRlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVjb3JkID0gcGFyZW50T3JSb3V0ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF0Y2hlci5hZGRSb3V0ZShyZWNvcmQsIHBhcmVudCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlbW92ZVJvdXRlKG5hbWUpIHtcbiAgICAgICAgY29uc3QgcmVjb3JkTWF0Y2hlciA9IG1hdGNoZXIuZ2V0UmVjb3JkTWF0Y2hlcihuYW1lKTtcbiAgICAgICAgaWYgKHJlY29yZE1hdGNoZXIpIHtcbiAgICAgICAgICAgIG1hdGNoZXIucmVtb3ZlUm91dGUocmVjb3JkTWF0Y2hlcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XG4gICAgICAgICAgICB3YXJuKGBDYW5ub3QgcmVtb3ZlIG5vbi1leGlzdGVudCByb3V0ZSBcIiR7U3RyaW5nKG5hbWUpfVwiYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZnVuY3Rpb24gZ2V0Um91dGVzKCkge1xuICAgICAgICByZXR1cm4gbWF0Y2hlci5nZXRSb3V0ZXMoKS5tYXAocm91dGVNYXRjaGVyID0+IHJvdXRlTWF0Y2hlci5yZWNvcmQpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBoYXNSb3V0ZShuYW1lKSB7XG4gICAgICAgIHJldHVybiAhIW1hdGNoZXIuZ2V0UmVjb3JkTWF0Y2hlcihuYW1lKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcmVzb2x2ZShyYXdMb2NhdGlvbiwgY3VycmVudExvY2F0aW9uKSB7XG4gICAgICAgIC8vIGNvbnN0IHJlc29sdmU6IFJvdXRlclsncmVzb2x2ZSddID0gKHJhd0xvY2F0aW9uOiBSb3V0ZUxvY2F0aW9uUmF3LCBjdXJyZW50TG9jYXRpb24pID0+IHtcbiAgICAgICAgLy8gY29uc3Qgb2JqZWN0TG9jYXRpb24gPSByb3V0ZXJMb2NhdGlvbkFzT2JqZWN0KHJhd0xvY2F0aW9uKVxuICAgICAgICAvLyB3ZSBjcmVhdGUgYSBjb3B5IHRvIG1vZGlmeSBpdCBsYXRlclxuICAgICAgICBjdXJyZW50TG9jYXRpb24gPSBhc3NpZ24oe30sIGN1cnJlbnRMb2NhdGlvbiB8fCBjdXJyZW50Um91dGUudmFsdWUpO1xuICAgICAgICBpZiAodHlwZW9mIHJhd0xvY2F0aW9uID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uc3QgbG9jYXRpb25Ob3JtYWxpemVkID0gcGFyc2VVUkwocGFyc2VRdWVyeSQxLCByYXdMb2NhdGlvbiwgY3VycmVudExvY2F0aW9uLnBhdGgpO1xuICAgICAgICAgICAgY29uc3QgbWF0Y2hlZFJvdXRlID0gbWF0Y2hlci5yZXNvbHZlKHsgcGF0aDogbG9jYXRpb25Ob3JtYWxpemVkLnBhdGggfSwgY3VycmVudExvY2F0aW9uKTtcbiAgICAgICAgICAgIGNvbnN0IGhyZWYgPSByb3V0ZXJIaXN0b3J5LmNyZWF0ZUhyZWYobG9jYXRpb25Ob3JtYWxpemVkLmZ1bGxQYXRoKTtcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcbiAgICAgICAgICAgICAgICBpZiAoaHJlZi5zdGFydHNXaXRoKCcvLycpKVxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBMb2NhdGlvbiBcIiR7cmF3TG9jYXRpb259XCIgcmVzb2x2ZWQgdG8gXCIke2hyZWZ9XCIuIEEgcmVzb2x2ZWQgbG9jYXRpb24gY2Fubm90IHN0YXJ0IHdpdGggbXVsdGlwbGUgc2xhc2hlcy5gKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghbWF0Y2hlZFJvdXRlLm1hdGNoZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYE5vIG1hdGNoIGZvdW5kIGZvciBsb2NhdGlvbiB3aXRoIHBhdGggXCIke3Jhd0xvY2F0aW9ufVwiYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gbG9jYXRpb25Ob3JtYWxpemVkIGlzIGFsd2F5cyBhIG5ldyBvYmplY3RcbiAgICAgICAgICAgIHJldHVybiBhc3NpZ24obG9jYXRpb25Ob3JtYWxpemVkLCBtYXRjaGVkUm91dGUsIHtcbiAgICAgICAgICAgICAgICBwYXJhbXM6IGRlY29kZVBhcmFtcyhtYXRjaGVkUm91dGUucGFyYW1zKSxcbiAgICAgICAgICAgICAgICBoYXNoOiBkZWNvZGUobG9jYXRpb25Ob3JtYWxpemVkLmhhc2gpLFxuICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgaHJlZixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIWlzUm91dGVMb2NhdGlvbihyYXdMb2NhdGlvbikpIHtcbiAgICAgICAgICAgIHdhcm4oYHJvdXRlci5yZXNvbHZlKCkgd2FzIHBhc3NlZCBhbiBpbnZhbGlkIGxvY2F0aW9uLiBUaGlzIHdpbGwgZmFpbCBpbiBwcm9kdWN0aW9uLlxcbi0gTG9jYXRpb246YCwgcmF3TG9jYXRpb24pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoe30pO1xuICAgICAgICB9XG4gICAgICAgIGxldCBtYXRjaGVyTG9jYXRpb247XG4gICAgICAgIC8vIHBhdGggY291bGQgYmUgcmVsYXRpdmUgaW4gb2JqZWN0IGFzIHdlbGxcbiAgICAgICAgaWYgKHJhd0xvY2F0aW9uLnBhdGggIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxuICAgICAgICAgICAgICAgICdwYXJhbXMnIGluIHJhd0xvY2F0aW9uICYmXG4gICAgICAgICAgICAgICAgISgnbmFtZScgaW4gcmF3TG9jYXRpb24pICYmXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogdGhlIHR5cGUgaXMgbmV2ZXJcbiAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhyYXdMb2NhdGlvbi5wYXJhbXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdhcm4oYFBhdGggXCIke3Jhd0xvY2F0aW9uLnBhdGh9XCIgd2FzIHBhc3NlZCB3aXRoIHBhcmFtcyBidXQgdGhleSB3aWxsIGJlIGlnbm9yZWQuIFVzZSBhIG5hbWVkIHJvdXRlIGFsb25nc2lkZSBwYXJhbXMgaW5zdGVhZC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1hdGNoZXJMb2NhdGlvbiA9IGFzc2lnbih7fSwgcmF3TG9jYXRpb24sIHtcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXJzZVVSTChwYXJzZVF1ZXJ5JDEsIHJhd0xvY2F0aW9uLnBhdGgsIGN1cnJlbnRMb2NhdGlvbi5wYXRoKS5wYXRoLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgYW55IG51bGxpc2ggcGFyYW1cbiAgICAgICAgICAgIGNvbnN0IHRhcmdldFBhcmFtcyA9IGFzc2lnbih7fSwgcmF3TG9jYXRpb24ucGFyYW1zKTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRhcmdldFBhcmFtcykge1xuICAgICAgICAgICAgICAgIGlmICh0YXJnZXRQYXJhbXNba2V5XSA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0YXJnZXRQYXJhbXNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBwYXNzIGVuY29kZWQgdmFsdWVzIHRvIHRoZSBtYXRjaGVyLCBzbyBpdCBjYW4gcHJvZHVjZSBlbmNvZGVkIHBhdGggYW5kIGZ1bGxQYXRoXG4gICAgICAgICAgICBtYXRjaGVyTG9jYXRpb24gPSBhc3NpZ24oe30sIHJhd0xvY2F0aW9uLCB7XG4gICAgICAgICAgICAgICAgcGFyYW1zOiBlbmNvZGVQYXJhbXModGFyZ2V0UGFyYW1zKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gY3VycmVudCBsb2NhdGlvbiBwYXJhbXMgYXJlIGRlY29kZWQsIHdlIG5lZWQgdG8gZW5jb2RlIHRoZW0gaW4gY2FzZSB0aGVcbiAgICAgICAgICAgIC8vIG1hdGNoZXIgbWVyZ2VzIHRoZSBwYXJhbXNcbiAgICAgICAgICAgIGN1cnJlbnRMb2NhdGlvbi5wYXJhbXMgPSBlbmNvZGVQYXJhbXMoY3VycmVudExvY2F0aW9uLnBhcmFtcyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWF0Y2hlZFJvdXRlID0gbWF0Y2hlci5yZXNvbHZlKG1hdGNoZXJMb2NhdGlvbiwgY3VycmVudExvY2F0aW9uKTtcbiAgICAgICAgY29uc3QgaGFzaCA9IHJhd0xvY2F0aW9uLmhhc2ggfHwgJyc7XG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgaGFzaCAmJiAhaGFzaC5zdGFydHNXaXRoKCcjJykpIHtcbiAgICAgICAgICAgIHdhcm4oYEEgXFxgaGFzaFxcYCBzaG91bGQgYWx3YXlzIHN0YXJ0IHdpdGggdGhlIGNoYXJhY3RlciBcIiNcIi4gUmVwbGFjZSBcIiR7aGFzaH1cIiB3aXRoIFwiIyR7aGFzaH1cIi5gKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGUgbWF0Y2hlciBtaWdodCBoYXZlIG1lcmdlZCBjdXJyZW50IGxvY2F0aW9uIHBhcmFtcywgc29cbiAgICAgICAgLy8gd2UgbmVlZCB0byBydW4gdGhlIGRlY29kaW5nIGFnYWluXG4gICAgICAgIG1hdGNoZWRSb3V0ZS5wYXJhbXMgPSBub3JtYWxpemVQYXJhbXMoZGVjb2RlUGFyYW1zKG1hdGNoZWRSb3V0ZS5wYXJhbXMpKTtcbiAgICAgICAgY29uc3QgZnVsbFBhdGggPSBzdHJpbmdpZnlVUkwoc3RyaW5naWZ5UXVlcnkkMSwgYXNzaWduKHt9LCByYXdMb2NhdGlvbiwge1xuICAgICAgICAgICAgaGFzaDogZW5jb2RlSGFzaChoYXNoKSxcbiAgICAgICAgICAgIHBhdGg6IG1hdGNoZWRSb3V0ZS5wYXRoLFxuICAgICAgICB9KSk7XG4gICAgICAgIGNvbnN0IGhyZWYgPSByb3V0ZXJIaXN0b3J5LmNyZWF0ZUhyZWYoZnVsbFBhdGgpO1xuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XG4gICAgICAgICAgICBpZiAoaHJlZi5zdGFydHNXaXRoKCcvLycpKSB7XG4gICAgICAgICAgICAgICAgd2FybihgTG9jYXRpb24gXCIke3Jhd0xvY2F0aW9ufVwiIHJlc29sdmVkIHRvIFwiJHtocmVmfVwiLiBBIHJlc29sdmVkIGxvY2F0aW9uIGNhbm5vdCBzdGFydCB3aXRoIG11bHRpcGxlIHNsYXNoZXMuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghbWF0Y2hlZFJvdXRlLm1hdGNoZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgd2FybihgTm8gbWF0Y2ggZm91bmQgZm9yIGxvY2F0aW9uIHdpdGggcGF0aCBcIiR7cmF3TG9jYXRpb24ucGF0aCAhPSBudWxsID8gcmF3TG9jYXRpb24ucGF0aCA6IHJhd0xvY2F0aW9ufVwiYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFzc2lnbih7XG4gICAgICAgICAgICBmdWxsUGF0aCxcbiAgICAgICAgICAgIC8vIGtlZXAgdGhlIGhhc2ggZW5jb2RlZCBzbyBmdWxsUGF0aCBpcyBlZmZlY3RpdmVseSBwYXRoICsgZW5jb2RlZFF1ZXJ5ICtcbiAgICAgICAgICAgIC8vIGhhc2hcbiAgICAgICAgICAgIGhhc2gsXG4gICAgICAgICAgICBxdWVyeTogXG4gICAgICAgICAgICAvLyBpZiB0aGUgdXNlciBpcyB1c2luZyBhIGN1c3RvbSBxdWVyeSBsaWIgbGlrZSBxcywgd2UgbWlnaHQgaGF2ZVxuICAgICAgICAgICAgLy8gbmVzdGVkIG9iamVjdHMsIHNvIHdlIGtlZXAgdGhlIHF1ZXJ5IGFzIGlzLCBtZWFuaW5nIGl0IGNhbiBjb250YWluXG4gICAgICAgICAgICAvLyBudW1iZXJzIGF0IGAkcm91dGUucXVlcnlgLCBidXQgYXQgdGhlIHBvaW50LCB0aGUgdXNlciB3aWxsIGhhdmUgdG9cbiAgICAgICAgICAgIC8vIHVzZSB0aGVpciBvd24gdHlwZSBhbnl3YXkuXG4gICAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vdnVlanMvcm91dGVyL2lzc3Vlcy8zMjgjaXNzdWVjb21tZW50LTY0OTQ4MTU2N1xuICAgICAgICAgICAgc3RyaW5naWZ5UXVlcnkkMSA9PT0gc3RyaW5naWZ5UXVlcnlcbiAgICAgICAgICAgICAgICA/IG5vcm1hbGl6ZVF1ZXJ5KHJhd0xvY2F0aW9uLnF1ZXJ5KVxuICAgICAgICAgICAgICAgIDogKHJhd0xvY2F0aW9uLnF1ZXJ5IHx8IHt9KSxcbiAgICAgICAgfSwgbWF0Y2hlZFJvdXRlLCB7XG4gICAgICAgICAgICByZWRpcmVjdGVkRnJvbTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgaHJlZixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGxvY2F0aW9uQXNPYmplY3QodG8pIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB0byA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgID8gcGFyc2VVUkwocGFyc2VRdWVyeSQxLCB0bywgY3VycmVudFJvdXRlLnZhbHVlLnBhdGgpXG4gICAgICAgICAgICA6IGFzc2lnbih7fSwgdG8pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjaGVja0NhbmNlbGVkTmF2aWdhdGlvbih0bywgZnJvbSkge1xuICAgICAgICBpZiAocGVuZGluZ0xvY2F0aW9uICE9PSB0bykge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVJvdXRlckVycm9yKDggLyogRXJyb3JUeXBlcy5OQVZJR0FUSU9OX0NBTkNFTExFRCAqLywge1xuICAgICAgICAgICAgICAgIGZyb20sXG4gICAgICAgICAgICAgICAgdG8sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBwdXNoKHRvKSB7XG4gICAgICAgIHJldHVybiBwdXNoV2l0aFJlZGlyZWN0KHRvKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcmVwbGFjZSh0bykge1xuICAgICAgICByZXR1cm4gcHVzaChhc3NpZ24obG9jYXRpb25Bc09iamVjdCh0byksIHsgcmVwbGFjZTogdHJ1ZSB9KSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGhhbmRsZVJlZGlyZWN0UmVjb3JkKHRvKSB7XG4gICAgICAgIGNvbnN0IGxhc3RNYXRjaGVkID0gdG8ubWF0Y2hlZFt0by5tYXRjaGVkLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAobGFzdE1hdGNoZWQgJiYgbGFzdE1hdGNoZWQucmVkaXJlY3QpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgcmVkaXJlY3QgfSA9IGxhc3RNYXRjaGVkO1xuICAgICAgICAgICAgbGV0IG5ld1RhcmdldExvY2F0aW9uID0gdHlwZW9mIHJlZGlyZWN0ID09PSAnZnVuY3Rpb24nID8gcmVkaXJlY3QodG8pIDogcmVkaXJlY3Q7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG5ld1RhcmdldExvY2F0aW9uID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIG5ld1RhcmdldExvY2F0aW9uID1cbiAgICAgICAgICAgICAgICAgICAgbmV3VGFyZ2V0TG9jYXRpb24uaW5jbHVkZXMoJz8nKSB8fCBuZXdUYXJnZXRMb2NhdGlvbi5pbmNsdWRlcygnIycpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IChuZXdUYXJnZXRMb2NhdGlvbiA9IGxvY2F0aW9uQXNPYmplY3QobmV3VGFyZ2V0TG9jYXRpb24pKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiAvLyBmb3JjZSBlbXB0eSBwYXJhbXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHBhdGg6IG5ld1RhcmdldExvY2F0aW9uIH07XG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogZm9yY2UgZW1wdHkgcGFyYW1zIHdoZW4gYSBzdHJpbmcgaXMgcGFzc2VkIHRvIGxldFxuICAgICAgICAgICAgICAgIC8vIHRoZSByb3V0ZXIgcGFyc2UgdGhlbSBhZ2FpblxuICAgICAgICAgICAgICAgIG5ld1RhcmdldExvY2F0aW9uLnBhcmFtcyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxuICAgICAgICAgICAgICAgIG5ld1RhcmdldExvY2F0aW9uLnBhdGggPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgICEoJ25hbWUnIGluIG5ld1RhcmdldExvY2F0aW9uKSkge1xuICAgICAgICAgICAgICAgIHdhcm4oYEludmFsaWQgcmVkaXJlY3QgZm91bmQ6XFxuJHtKU09OLnN0cmluZ2lmeShuZXdUYXJnZXRMb2NhdGlvbiwgbnVsbCwgMil9XFxuIHdoZW4gbmF2aWdhdGluZyB0byBcIiR7dG8uZnVsbFBhdGh9XCIuIEEgcmVkaXJlY3QgbXVzdCBjb250YWluIGEgbmFtZSBvciBwYXRoLiBUaGlzIHdpbGwgYnJlYWsgaW4gcHJvZHVjdGlvbi5gKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcmVkaXJlY3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhc3NpZ24oe1xuICAgICAgICAgICAgICAgIHF1ZXJ5OiB0by5xdWVyeSxcbiAgICAgICAgICAgICAgICBoYXNoOiB0by5oYXNoLFxuICAgICAgICAgICAgICAgIC8vIGF2b2lkIHRyYW5zZmVycmluZyBwYXJhbXMgaWYgdGhlIHJlZGlyZWN0IGhhcyBhIHBhdGhcbiAgICAgICAgICAgICAgICBwYXJhbXM6IG5ld1RhcmdldExvY2F0aW9uLnBhdGggIT0gbnVsbCA/IHt9IDogdG8ucGFyYW1zLFxuICAgICAgICAgICAgfSwgbmV3VGFyZ2V0TG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIHB1c2hXaXRoUmVkaXJlY3QodG8sIHJlZGlyZWN0ZWRGcm9tKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldExvY2F0aW9uID0gKHBlbmRpbmdMb2NhdGlvbiA9IHJlc29sdmUodG8pKTtcbiAgICAgICAgY29uc3QgZnJvbSA9IGN1cnJlbnRSb3V0ZS52YWx1ZTtcbiAgICAgICAgY29uc3QgZGF0YSA9IHRvLnN0YXRlO1xuICAgICAgICBjb25zdCBmb3JjZSA9IHRvLmZvcmNlO1xuICAgICAgICAvLyB0byBjb3VsZCBiZSBhIHN0cmluZyB3aGVyZSBgcmVwbGFjZWAgaXMgYSBmdW5jdGlvblxuICAgICAgICBjb25zdCByZXBsYWNlID0gdG8ucmVwbGFjZSA9PT0gdHJ1ZTtcbiAgICAgICAgY29uc3Qgc2hvdWxkUmVkaXJlY3QgPSBoYW5kbGVSZWRpcmVjdFJlY29yZCh0YXJnZXRMb2NhdGlvbik7XG4gICAgICAgIGlmIChzaG91bGRSZWRpcmVjdClcbiAgICAgICAgICAgIHJldHVybiBwdXNoV2l0aFJlZGlyZWN0KGFzc2lnbihsb2NhdGlvbkFzT2JqZWN0KHNob3VsZFJlZGlyZWN0KSwge1xuICAgICAgICAgICAgICAgIHN0YXRlOiB0eXBlb2Ygc2hvdWxkUmVkaXJlY3QgPT09ICdvYmplY3QnXG4gICAgICAgICAgICAgICAgICAgID8gYXNzaWduKHt9LCBkYXRhLCBzaG91bGRSZWRpcmVjdC5zdGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgOiBkYXRhLFxuICAgICAgICAgICAgICAgIGZvcmNlLFxuICAgICAgICAgICAgICAgIHJlcGxhY2UsXG4gICAgICAgICAgICB9KSwgXG4gICAgICAgICAgICAvLyBrZWVwIG9yaWdpbmFsIHJlZGlyZWN0ZWRGcm9tIGlmIGl0IGV4aXN0c1xuICAgICAgICAgICAgcmVkaXJlY3RlZEZyb20gfHwgdGFyZ2V0TG9jYXRpb24pO1xuICAgICAgICAvLyBpZiBpdCB3YXMgYSByZWRpcmVjdCB3ZSBhbHJlYWR5IGNhbGxlZCBgcHVzaFdpdGhSZWRpcmVjdGAgYWJvdmVcbiAgICAgICAgY29uc3QgdG9Mb2NhdGlvbiA9IHRhcmdldExvY2F0aW9uO1xuICAgICAgICB0b0xvY2F0aW9uLnJlZGlyZWN0ZWRGcm9tID0gcmVkaXJlY3RlZEZyb207XG4gICAgICAgIGxldCBmYWlsdXJlO1xuICAgICAgICBpZiAoIWZvcmNlICYmIGlzU2FtZVJvdXRlTG9jYXRpb24oc3RyaW5naWZ5UXVlcnkkMSwgZnJvbSwgdGFyZ2V0TG9jYXRpb24pKSB7XG4gICAgICAgICAgICBmYWlsdXJlID0gY3JlYXRlUm91dGVyRXJyb3IoMTYgLyogRXJyb3JUeXBlcy5OQVZJR0FUSU9OX0RVUExJQ0FURUQgKi8sIHsgdG86IHRvTG9jYXRpb24sIGZyb20gfSk7XG4gICAgICAgICAgICAvLyB0cmlnZ2VyIHNjcm9sbCB0byBhbGxvdyBzY3JvbGxpbmcgdG8gdGhlIHNhbWUgYW5jaG9yXG4gICAgICAgICAgICBoYW5kbGVTY3JvbGwoZnJvbSwgZnJvbSwgXG4gICAgICAgICAgICAvLyB0aGlzIGlzIGEgcHVzaCwgdGhlIG9ubHkgd2F5IGZvciBpdCB0byBiZSB0cmlnZ2VyZWQgZnJvbSBhXG4gICAgICAgICAgICAvLyBoaXN0b3J5Lmxpc3RlbiBpcyB3aXRoIGEgcmVkaXJlY3QsIHdoaWNoIG1ha2VzIGl0IGJlY29tZSBhIHB1c2hcbiAgICAgICAgICAgIHRydWUsIFxuICAgICAgICAgICAgLy8gVGhpcyBjYW5ub3QgYmUgdGhlIGZpcnN0IG5hdmlnYXRpb24gYmVjYXVzZSB0aGUgaW5pdGlhbCBsb2NhdGlvblxuICAgICAgICAgICAgLy8gY2Fubm90IGJlIG1hbnVhbGx5IG5hdmlnYXRlZCB0b1xuICAgICAgICAgICAgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoZmFpbHVyZSA/IFByb21pc2UucmVzb2x2ZShmYWlsdXJlKSA6IG5hdmlnYXRlKHRvTG9jYXRpb24sIGZyb20pKVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gaXNOYXZpZ2F0aW9uRmFpbHVyZShlcnJvcilcbiAgICAgICAgICAgID8gLy8gbmF2aWdhdGlvbiByZWRpcmVjdHMgc3RpbGwgbWFyayB0aGUgcm91dGVyIGFzIHJlYWR5XG4gICAgICAgICAgICAgICAgaXNOYXZpZ2F0aW9uRmFpbHVyZShlcnJvciwgMiAvKiBFcnJvclR5cGVzLk5BVklHQVRJT05fR1VBUkRfUkVESVJFQ1QgKi8pXG4gICAgICAgICAgICAgICAgICAgID8gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgOiBtYXJrQXNSZWFkeShlcnJvcikgLy8gYWxzbyByZXR1cm5zIHRoZSBlcnJvclxuICAgICAgICAgICAgOiAvLyByZWplY3QgYW55IHVua25vd24gZXJyb3JcbiAgICAgICAgICAgICAgICB0cmlnZ2VyRXJyb3IoZXJyb3IsIHRvTG9jYXRpb24sIGZyb20pKVxuICAgICAgICAgICAgLnRoZW4oKGZhaWx1cmUpID0+IHtcbiAgICAgICAgICAgIGlmIChmYWlsdXJlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzTmF2aWdhdGlvbkZhaWx1cmUoZmFpbHVyZSwgMiAvKiBFcnJvclR5cGVzLk5BVklHQVRJT05fR1VBUkRfUkVESVJFQ1QgKi8pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGFyZSByZWRpcmVjdGluZyB0byB0aGUgc2FtZSBsb2NhdGlvbiB3ZSB3ZXJlIGFscmVhZHkgYXRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzU2FtZVJvdXRlTG9jYXRpb24oc3RyaW5naWZ5UXVlcnkkMSwgcmVzb2x2ZShmYWlsdXJlLnRvKSwgdG9Mb2NhdGlvbikgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB3ZSBoYXZlIGRvbmUgaXQgYSBjb3VwbGUgb2YgdGltZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiBhZGRlZCBvbmx5IGluIGRldlxuICAgICAgICAgICAgICAgICAgICAgICAgKHJlZGlyZWN0ZWRGcm9tLl9jb3VudCA9IHJlZGlyZWN0ZWRGcm9tLl9jb3VudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWRpcmVjdGVkRnJvbS5fY291bnQgKyAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAxKSA+IDMwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3YXJuKGBEZXRlY3RlZCBhIHBvc3NpYmx5IGluZmluaXRlIHJlZGlyZWN0aW9uIGluIGEgbmF2aWdhdGlvbiBndWFyZCB3aGVuIGdvaW5nIGZyb20gXCIke2Zyb20uZnVsbFBhdGh9XCIgdG8gXCIke3RvTG9jYXRpb24uZnVsbFBhdGh9XCIuIEFib3J0aW5nIHRvIGF2b2lkIGEgU3RhY2sgT3ZlcmZsb3cuXFxuIEFyZSB5b3UgYWx3YXlzIHJldHVybmluZyBhIG5ldyBsb2NhdGlvbiB3aXRoaW4gYSBuYXZpZ2F0aW9uIGd1YXJkPyBUaGF0IHdvdWxkIGxlYWQgdG8gdGhpcyBlcnJvci4gT25seSByZXR1cm4gd2hlbiByZWRpcmVjdGluZyBvciBhYm9ydGluZywgdGhhdCBzaG91bGQgZml4IHRoaXMuIFRoaXMgbWlnaHQgYnJlYWsgaW4gcHJvZHVjdGlvbiBpZiBub3QgZml4ZWQuYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdJbmZpbml0ZSByZWRpcmVjdCBpbiBuYXZpZ2F0aW9uIGd1YXJkJykpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwdXNoV2l0aFJlZGlyZWN0KFxuICAgICAgICAgICAgICAgICAgICAvLyBrZWVwIG9wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgYXNzaWduKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByZXNlcnZlIGFuIGV4aXN0aW5nIHJlcGxhY2VtZW50IGJ1dCBhbGxvdyB0aGUgcmVkaXJlY3QgdG8gb3ZlcnJpZGUgaXRcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2UsXG4gICAgICAgICAgICAgICAgICAgIH0sIGxvY2F0aW9uQXNPYmplY3QoZmFpbHVyZS50byksIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlOiB0eXBlb2YgZmFpbHVyZS50byA9PT0gJ29iamVjdCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFzc2lnbih7fSwgZGF0YSwgZmFpbHVyZS50by5zdGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JjZSxcbiAgICAgICAgICAgICAgICAgICAgfSksIFxuICAgICAgICAgICAgICAgICAgICAvLyBwcmVzZXJ2ZSB0aGUgb3JpZ2luYWwgcmVkaXJlY3RlZEZyb20gaWYgYW55XG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tIHx8IHRvTG9jYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGlmIHdlIGZhaWwgd2UgZG9uJ3QgZmluYWxpemUgdGhlIG5hdmlnYXRpb25cbiAgICAgICAgICAgICAgICBmYWlsdXJlID0gZmluYWxpemVOYXZpZ2F0aW9uKHRvTG9jYXRpb24sIGZyb20sIHRydWUsIHJlcGxhY2UsIGRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJpZ2dlckFmdGVyRWFjaCh0b0xvY2F0aW9uLCBmcm9tLCBmYWlsdXJlKTtcbiAgICAgICAgICAgIHJldHVybiBmYWlsdXJlO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGVscGVyIHRvIHJlamVjdCBhbmQgc2tpcCBhbGwgbmF2aWdhdGlvbiBndWFyZHMgaWYgYSBuZXcgbmF2aWdhdGlvbiBoYXBwZW5lZFxuICAgICAqIEBwYXJhbSB0b1xuICAgICAqIEBwYXJhbSBmcm9tXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2hlY2tDYW5jZWxlZE5hdmlnYXRpb25BbmRSZWplY3QodG8sIGZyb20pIHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBjaGVja0NhbmNlbGVkTmF2aWdhdGlvbih0bywgZnJvbSk7XG4gICAgICAgIHJldHVybiBlcnJvciA/IFByb21pc2UucmVqZWN0KGVycm9yKSA6IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBydW5XaXRoQ29udGV4dChmbikge1xuICAgICAgICBjb25zdCBhcHAgPSBpbnN0YWxsZWRBcHBzLnZhbHVlcygpLm5leHQoKS52YWx1ZTtcbiAgICAgICAgLy8gc3VwcG9ydCBWdWUgPCAzLjNcbiAgICAgICAgcmV0dXJuIGFwcCAmJiB0eXBlb2YgYXBwLnJ1bldpdGhDb250ZXh0ID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICA/IGFwcC5ydW5XaXRoQ29udGV4dChmbilcbiAgICAgICAgICAgIDogZm4oKTtcbiAgICB9XG4gICAgLy8gVE9ETzogcmVmYWN0b3IgdGhlIHdob2xlIGJlZm9yZSBndWFyZHMgYnkgaW50ZXJuYWxseSB1c2luZyByb3V0ZXIuYmVmb3JlRWFjaFxuICAgIGZ1bmN0aW9uIG5hdmlnYXRlKHRvLCBmcm9tKSB7XG4gICAgICAgIGxldCBndWFyZHM7XG4gICAgICAgIGNvbnN0IFtsZWF2aW5nUmVjb3JkcywgdXBkYXRpbmdSZWNvcmRzLCBlbnRlcmluZ1JlY29yZHNdID0gZXh0cmFjdENoYW5naW5nUmVjb3Jkcyh0bywgZnJvbSk7XG4gICAgICAgIC8vIGFsbCBjb21wb25lbnRzIGhlcmUgaGF2ZSBiZWVuIHJlc29sdmVkIG9uY2UgYmVjYXVzZSB3ZSBhcmUgbGVhdmluZ1xuICAgICAgICBndWFyZHMgPSBleHRyYWN0Q29tcG9uZW50c0d1YXJkcyhsZWF2aW5nUmVjb3Jkcy5yZXZlcnNlKCksICdiZWZvcmVSb3V0ZUxlYXZlJywgdG8sIGZyb20pO1xuICAgICAgICAvLyBsZWF2aW5nUmVjb3JkcyBpcyBhbHJlYWR5IHJldmVyc2VkXG4gICAgICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIGxlYXZpbmdSZWNvcmRzKSB7XG4gICAgICAgICAgICByZWNvcmQubGVhdmVHdWFyZHMuZm9yRWFjaChndWFyZCA9PiB7XG4gICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihndWFyZCwgdG8sIGZyb20pKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrID0gY2hlY2tDYW5jZWxlZE5hdmlnYXRpb25BbmRSZWplY3QuYmluZChudWxsLCB0bywgZnJvbSk7XG4gICAgICAgIGd1YXJkcy5wdXNoKGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrKTtcbiAgICAgICAgLy8gcnVuIHRoZSBxdWV1ZSBvZiBwZXIgcm91dGUgYmVmb3JlUm91dGVMZWF2ZSBndWFyZHNcbiAgICAgICAgcmV0dXJuIChydW5HdWFyZFF1ZXVlKGd1YXJkcylcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGNoZWNrIGdsb2JhbCBndWFyZHMgYmVmb3JlRWFjaFxuICAgICAgICAgICAgZ3VhcmRzID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGd1YXJkIG9mIGJlZm9yZUd1YXJkcy5saXN0KCkpIHtcbiAgICAgICAgICAgICAgICBndWFyZHMucHVzaChndWFyZFRvUHJvbWlzZUZuKGd1YXJkLCB0bywgZnJvbSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ3VhcmRzLnB1c2goY2FuY2VsZWROYXZpZ2F0aW9uQ2hlY2spO1xuICAgICAgICAgICAgcmV0dXJuIHJ1bkd1YXJkUXVldWUoZ3VhcmRzKTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGNoZWNrIGluIGNvbXBvbmVudHMgYmVmb3JlUm91dGVVcGRhdGVcbiAgICAgICAgICAgIGd1YXJkcyA9IGV4dHJhY3RDb21wb25lbnRzR3VhcmRzKHVwZGF0aW5nUmVjb3JkcywgJ2JlZm9yZVJvdXRlVXBkYXRlJywgdG8sIGZyb20pO1xuICAgICAgICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgdXBkYXRpbmdSZWNvcmRzKSB7XG4gICAgICAgICAgICAgICAgcmVjb3JkLnVwZGF0ZUd1YXJkcy5mb3JFYWNoKGd1YXJkID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihndWFyZCwgdG8sIGZyb20pKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGd1YXJkcy5wdXNoKGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrKTtcbiAgICAgICAgICAgIC8vIHJ1biB0aGUgcXVldWUgb2YgcGVyIHJvdXRlIGJlZm9yZUVudGVyIGd1YXJkc1xuICAgICAgICAgICAgcmV0dXJuIHJ1bkd1YXJkUXVldWUoZ3VhcmRzKTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGNoZWNrIHRoZSByb3V0ZSBiZWZvcmVFbnRlclxuICAgICAgICAgICAgZ3VhcmRzID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiBlbnRlcmluZ1JlY29yZHMpIHtcbiAgICAgICAgICAgICAgICAvLyBkbyBub3QgdHJpZ2dlciBiZWZvcmVFbnRlciBvbiByZXVzZWQgdmlld3NcbiAgICAgICAgICAgICAgICBpZiAocmVjb3JkLmJlZm9yZUVudGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KHJlY29yZC5iZWZvcmVFbnRlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmVmb3JlRW50ZXIgb2YgcmVjb3JkLmJlZm9yZUVudGVyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGd1YXJkcy5wdXNoKGd1YXJkVG9Qcm9taXNlRm4oYmVmb3JlRW50ZXIsIHRvLCBmcm9tKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBndWFyZHMucHVzaChndWFyZFRvUHJvbWlzZUZuKHJlY29yZC5iZWZvcmVFbnRlciwgdG8sIGZyb20pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGd1YXJkcy5wdXNoKGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrKTtcbiAgICAgICAgICAgIC8vIHJ1biB0aGUgcXVldWUgb2YgcGVyIHJvdXRlIGJlZm9yZUVudGVyIGd1YXJkc1xuICAgICAgICAgICAgcmV0dXJuIHJ1bkd1YXJkUXVldWUoZ3VhcmRzKTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIE5PVEU6IGF0IHRoaXMgcG9pbnQgdG8ubWF0Y2hlZCBpcyBub3JtYWxpemVkIGFuZCBkb2VzIG5vdCBjb250YWluIGFueSAoKSA9PiBQcm9taXNlPENvbXBvbmVudD5cbiAgICAgICAgICAgIC8vIGNsZWFyIGV4aXN0aW5nIGVudGVyQ2FsbGJhY2tzLCB0aGVzZSBhcmUgYWRkZWQgYnkgZXh0cmFjdENvbXBvbmVudHNHdWFyZHNcbiAgICAgICAgICAgIHRvLm1hdGNoZWQuZm9yRWFjaChyZWNvcmQgPT4gKHJlY29yZC5lbnRlckNhbGxiYWNrcyA9IHt9KSk7XG4gICAgICAgICAgICAvLyBjaGVjayBpbi1jb21wb25lbnQgYmVmb3JlUm91dGVFbnRlclxuICAgICAgICAgICAgZ3VhcmRzID0gZXh0cmFjdENvbXBvbmVudHNHdWFyZHMoZW50ZXJpbmdSZWNvcmRzLCAnYmVmb3JlUm91dGVFbnRlcicsIHRvLCBmcm9tLCBydW5XaXRoQ29udGV4dCk7XG4gICAgICAgICAgICBndWFyZHMucHVzaChjYW5jZWxlZE5hdmlnYXRpb25DaGVjayk7XG4gICAgICAgICAgICAvLyBydW4gdGhlIHF1ZXVlIG9mIHBlciByb3V0ZSBiZWZvcmVFbnRlciBndWFyZHNcbiAgICAgICAgICAgIHJldHVybiBydW5HdWFyZFF1ZXVlKGd1YXJkcyk7XG4gICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAvLyBjaGVjayBnbG9iYWwgZ3VhcmRzIGJlZm9yZVJlc29sdmVcbiAgICAgICAgICAgIGd1YXJkcyA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBndWFyZCBvZiBiZWZvcmVSZXNvbHZlR3VhcmRzLmxpc3QoKSkge1xuICAgICAgICAgICAgICAgIGd1YXJkcy5wdXNoKGd1YXJkVG9Qcm9taXNlRm4oZ3VhcmQsIHRvLCBmcm9tKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBndWFyZHMucHVzaChjYW5jZWxlZE5hdmlnYXRpb25DaGVjayk7XG4gICAgICAgICAgICByZXR1cm4gcnVuR3VhcmRRdWV1ZShndWFyZHMpO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLy8gY2F0Y2ggYW55IG5hdmlnYXRpb24gY2FuY2VsZWRcbiAgICAgICAgICAgIC5jYXRjaChlcnIgPT4gaXNOYXZpZ2F0aW9uRmFpbHVyZShlcnIsIDggLyogRXJyb3JUeXBlcy5OQVZJR0FUSU9OX0NBTkNFTExFRCAqLylcbiAgICAgICAgICAgID8gZXJyXG4gICAgICAgICAgICA6IFByb21pc2UucmVqZWN0KGVycikpKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gdHJpZ2dlckFmdGVyRWFjaCh0bywgZnJvbSwgZmFpbHVyZSkge1xuICAgICAgICAvLyBuYXZpZ2F0aW9uIGlzIGNvbmZpcm1lZCwgY2FsbCBhZnRlckd1YXJkc1xuICAgICAgICAvLyBUT0RPOiB3cmFwIHdpdGggZXJyb3IgaGFuZGxlcnNcbiAgICAgICAgYWZ0ZXJHdWFyZHNcbiAgICAgICAgICAgIC5saXN0KClcbiAgICAgICAgICAgIC5mb3JFYWNoKGd1YXJkID0+IHJ1bldpdGhDb250ZXh0KCgpID0+IGd1YXJkKHRvLCBmcm9tLCBmYWlsdXJlKSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAtIENsZWFucyB1cCBhbnkgbmF2aWdhdGlvbiBndWFyZHNcbiAgICAgKiAtIENoYW5nZXMgdGhlIHVybCBpZiBuZWNlc3NhcnlcbiAgICAgKiAtIENhbGxzIHRoZSBzY3JvbGxCZWhhdmlvclxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbmFsaXplTmF2aWdhdGlvbih0b0xvY2F0aW9uLCBmcm9tLCBpc1B1c2gsIHJlcGxhY2UsIGRhdGEpIHtcbiAgICAgICAgLy8gYSBtb3JlIHJlY2VudCBuYXZpZ2F0aW9uIHRvb2sgcGxhY2VcbiAgICAgICAgY29uc3QgZXJyb3IgPSBjaGVja0NhbmNlbGVkTmF2aWdhdGlvbih0b0xvY2F0aW9uLCBmcm9tKTtcbiAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICAvLyBvbmx5IGNvbnNpZGVyIGFzIHB1c2ggaWYgaXQncyBub3QgdGhlIGZpcnN0IG5hdmlnYXRpb25cbiAgICAgICAgY29uc3QgaXNGaXJzdE5hdmlnYXRpb24gPSBmcm9tID09PSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEO1xuICAgICAgICBjb25zdCBzdGF0ZSA9ICFpc0Jyb3dzZXIgPyB7fSA6IGhpc3Rvcnkuc3RhdGU7XG4gICAgICAgIC8vIGNoYW5nZSBVUkwgb25seSBpZiB0aGUgdXNlciBkaWQgYSBwdXNoL3JlcGxhY2UgYW5kIGlmIGl0J3Mgbm90IHRoZSBpbml0aWFsIG5hdmlnYXRpb24gYmVjYXVzZVxuICAgICAgICAvLyBpdCdzIGp1c3QgcmVmbGVjdGluZyB0aGUgdXJsXG4gICAgICAgIGlmIChpc1B1c2gpIHtcbiAgICAgICAgICAgIC8vIG9uIHRoZSBpbml0aWFsIG5hdmlnYXRpb24sIHdlIHdhbnQgdG8gcmV1c2UgdGhlIHNjcm9sbCBwb3NpdGlvbiBmcm9tXG4gICAgICAgICAgICAvLyBoaXN0b3J5IHN0YXRlIGlmIGl0IGV4aXN0c1xuICAgICAgICAgICAgaWYgKHJlcGxhY2UgfHwgaXNGaXJzdE5hdmlnYXRpb24pXG4gICAgICAgICAgICAgICAgcm91dGVySGlzdG9yeS5yZXBsYWNlKHRvTG9jYXRpb24uZnVsbFBhdGgsIGFzc2lnbih7XG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbDogaXNGaXJzdE5hdmlnYXRpb24gJiYgc3RhdGUgJiYgc3RhdGUuc2Nyb2xsLFxuICAgICAgICAgICAgICAgIH0sIGRhdGEpKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICByb3V0ZXJIaXN0b3J5LnB1c2godG9Mb2NhdGlvbi5mdWxsUGF0aCwgZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYWNjZXB0IGN1cnJlbnQgbmF2aWdhdGlvblxuICAgICAgICBjdXJyZW50Um91dGUudmFsdWUgPSB0b0xvY2F0aW9uO1xuICAgICAgICBoYW5kbGVTY3JvbGwodG9Mb2NhdGlvbiwgZnJvbSwgaXNQdXNoLCBpc0ZpcnN0TmF2aWdhdGlvbik7XG4gICAgICAgIG1hcmtBc1JlYWR5KCk7XG4gICAgfVxuICAgIGxldCByZW1vdmVIaXN0b3J5TGlzdGVuZXI7XG4gICAgLy8gYXR0YWNoIGxpc3RlbmVyIHRvIGhpc3RvcnkgdG8gdHJpZ2dlciBuYXZpZ2F0aW9uc1xuICAgIGZ1bmN0aW9uIHNldHVwTGlzdGVuZXJzKCkge1xuICAgICAgICAvLyBhdm9pZCBzZXR0aW5nIHVwIGxpc3RlbmVycyB0d2ljZSBkdWUgdG8gYW4gaW52YWxpZCBmaXJzdCBuYXZpZ2F0aW9uXG4gICAgICAgIGlmIChyZW1vdmVIaXN0b3J5TGlzdGVuZXIpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHJlbW92ZUhpc3RvcnlMaXN0ZW5lciA9IHJvdXRlckhpc3RvcnkubGlzdGVuKCh0bywgX2Zyb20sIGluZm8pID0+IHtcbiAgICAgICAgICAgIGlmICghcm91dGVyLmxpc3RlbmluZylcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAvLyBjYW5ub3QgYmUgYSByZWRpcmVjdCByb3V0ZSBiZWNhdXNlIGl0IHdhcyBpbiBoaXN0b3J5XG4gICAgICAgICAgICBjb25zdCB0b0xvY2F0aW9uID0gcmVzb2x2ZSh0byk7XG4gICAgICAgICAgICAvLyBkdWUgdG8gZHluYW1pYyByb3V0aW5nLCBhbmQgdG8gaGFzaCBoaXN0b3J5IHdpdGggbWFudWFsIG5hdmlnYXRpb25cbiAgICAgICAgICAgIC8vIChtYW51YWxseSBjaGFuZ2luZyB0aGUgdXJsIG9yIGNhbGxpbmcgaGlzdG9yeS5oYXNoID0gJyMvc29tZXdoZXJlJyksXG4gICAgICAgICAgICAvLyB0aGVyZSBjb3VsZCBiZSBhIHJlZGlyZWN0IHJlY29yZCBpbiBoaXN0b3J5XG4gICAgICAgICAgICBjb25zdCBzaG91bGRSZWRpcmVjdCA9IGhhbmRsZVJlZGlyZWN0UmVjb3JkKHRvTG9jYXRpb24pO1xuICAgICAgICAgICAgaWYgKHNob3VsZFJlZGlyZWN0KSB7XG4gICAgICAgICAgICAgICAgcHVzaFdpdGhSZWRpcmVjdChhc3NpZ24oc2hvdWxkUmVkaXJlY3QsIHsgcmVwbGFjZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSksIHRvTG9jYXRpb24pLmNhdGNoKG5vb3ApO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBlbmRpbmdMb2NhdGlvbiA9IHRvTG9jYXRpb247XG4gICAgICAgICAgICBjb25zdCBmcm9tID0gY3VycmVudFJvdXRlLnZhbHVlO1xuICAgICAgICAgICAgLy8gVE9ETzogc2hvdWxkIGJlIG1vdmVkIHRvIHdlYiBoaXN0b3J5P1xuICAgICAgICAgICAgaWYgKGlzQnJvd3Nlcikge1xuICAgICAgICAgICAgICAgIHNhdmVTY3JvbGxQb3NpdGlvbihnZXRTY3JvbGxLZXkoZnJvbS5mdWxsUGF0aCwgaW5mby5kZWx0YSksIGNvbXB1dGVTY3JvbGxQb3NpdGlvbigpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5hdmlnYXRlKHRvTG9jYXRpb24sIGZyb20pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpc05hdmlnYXRpb25GYWlsdXJlKGVycm9yLCA0IC8qIEVycm9yVHlwZXMuTkFWSUdBVElPTl9BQk9SVEVEICovIHwgOCAvKiBFcnJvclR5cGVzLk5BVklHQVRJT05fQ0FOQ0VMTEVEICovKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChpc05hdmlnYXRpb25GYWlsdXJlKGVycm9yLCAyIC8qIEVycm9yVHlwZXMuTkFWSUdBVElPTl9HVUFSRF9SRURJUkVDVCAqLykpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSGVyZSB3ZSBjb3VsZCBjYWxsIGlmIChpbmZvLmRlbHRhKSByb3V0ZXJIaXN0b3J5LmdvKC1pbmZvLmRlbHRhLFxuICAgICAgICAgICAgICAgICAgICAvLyBmYWxzZSkgYnV0IHRoaXMgaXMgYnVnIHByb25lIGFzIHdlIGhhdmUgbm8gd2F5IHRvIHdhaXQgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRpb24gdG8gYmUgZmluaXNoZWQgYmVmb3JlIGNhbGxpbmcgcHVzaFdpdGhSZWRpcmVjdC4gVXNpbmdcbiAgICAgICAgICAgICAgICAgICAgLy8gYSBzZXRUaW1lb3V0IG9mIDE2bXMgc2VlbXMgdG8gd29yayBidXQgdGhlcmUgaXMgbm8gZ3VhcmFudGVlIGZvclxuICAgICAgICAgICAgICAgICAgICAvLyBpdCB0byB3b3JrIG9uIGV2ZXJ5IGJyb3dzZXIuIFNvIGluc3RlYWQgd2UgZG8gbm90IHJlc3RvcmUgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vIGhpc3RvcnkgZW50cnkgYW5kIHRyaWdnZXIgYSBuZXcgbmF2aWdhdGlvbiBhcyByZXF1ZXN0ZWQgYnkgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRpb24gZ3VhcmQuXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBlcnJvciBpcyBhbHJlYWR5IGhhbmRsZWQgYnkgcm91dGVyLnB1c2ggd2UganVzdCB3YW50IHRvIGF2b2lkXG4gICAgICAgICAgICAgICAgICAgIC8vIGxvZ2dpbmcgdGhlIGVycm9yXG4gICAgICAgICAgICAgICAgICAgIHB1c2hXaXRoUmVkaXJlY3QoYXNzaWduKGxvY2F0aW9uQXNPYmplY3QoZXJyb3IudG8pLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JjZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgfSksIHRvTG9jYXRpb25cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgYW4gdW5jYXVnaHQgcmVqZWN0aW9uLCBsZXQgcHVzaCBjYWxsIHRyaWdnZXJFcnJvclxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihmYWlsdXJlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1hbnVhbCBjaGFuZ2UgaW4gaGFzaCBoaXN0b3J5ICM5MTYgZW5kaW5nIHVwIGluIHRoZSBVUkwgbm90XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2luZywgYnV0IGl0IHdhcyBjaGFuZ2VkIGJ5IHRoZSBtYW51YWwgdXJsIGNoYW5nZSwgc28gd2VcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gbWFudWFsbHkgY2hhbmdlIGl0IG91cnNlbHZlc1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmF2aWdhdGlvbkZhaWx1cmUoZmFpbHVyZSwgNCAvKiBFcnJvclR5cGVzLk5BVklHQVRJT05fQUJPUlRFRCAqLyB8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMTYgLyogRXJyb3JUeXBlcy5OQVZJR0FUSU9OX0RVUExJQ0FURUQgKi8pICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIWluZm8uZGVsdGEgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLnR5cGUgPT09IE5hdmlnYXRpb25UeXBlLnBvcCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlckhpc3RvcnkuZ28oLTEsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChub29wKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgdGhlIHRoZW4gYnJhbmNoXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBkbyBub3QgcmVzdG9yZSBoaXN0b3J5IG9uIHVua25vd24gZGlyZWN0aW9uXG4gICAgICAgICAgICAgICAgaWYgKGluZm8uZGVsdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgcm91dGVySGlzdG9yeS5nbygtaW5mby5kZWx0YSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyB1bnJlY29nbml6ZWQgZXJyb3IsIHRyYW5zZmVyIHRvIHRoZSBnbG9iYWwgaGFuZGxlclxuICAgICAgICAgICAgICAgIHJldHVybiB0cmlnZ2VyRXJyb3IoZXJyb3IsIHRvTG9jYXRpb24sIGZyb20pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAudGhlbigoZmFpbHVyZSkgPT4ge1xuICAgICAgICAgICAgICAgIGZhaWx1cmUgPVxuICAgICAgICAgICAgICAgICAgICBmYWlsdXJlIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZU5hdmlnYXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhZnRlciBuYXZpZ2F0aW9uLCBhbGwgbWF0Y2hlZCBjb21wb25lbnRzIGFyZSByZXNvbHZlZFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9Mb2NhdGlvbiwgZnJvbSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIC8vIHJldmVydCB0aGUgbmF2aWdhdGlvblxuICAgICAgICAgICAgICAgIGlmIChmYWlsdXJlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmZvLmRlbHRhICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhIG5ldyBuYXZpZ2F0aW9uIGhhcyBiZWVuIHRyaWdnZXJlZCwgc28gd2UgZG8gbm90IHdhbnQgdG8gcmV2ZXJ0LCB0aGF0IHdpbGwgY2hhbmdlIHRoZSBjdXJyZW50IGhpc3RvcnlcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVudHJ5IHdoaWxlIGEgZGlmZmVyZW50IHJvdXRlIGlzIGRpc3BsYXllZFxuICAgICAgICAgICAgICAgICAgICAgICAgIWlzTmF2aWdhdGlvbkZhaWx1cmUoZmFpbHVyZSwgOCAvKiBFcnJvclR5cGVzLk5BVklHQVRJT05fQ0FOQ0VMTEVEICovKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVySGlzdG9yeS5nbygtaW5mby5kZWx0YSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGluZm8udHlwZSA9PT0gTmF2aWdhdGlvblR5cGUucG9wICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBpc05hdmlnYXRpb25GYWlsdXJlKGZhaWx1cmUsIDQgLyogRXJyb3JUeXBlcy5OQVZJR0FUSU9OX0FCT1JURUQgKi8gfCAxNiAvKiBFcnJvclR5cGVzLk5BVklHQVRJT05fRFVQTElDQVRFRCAqLykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1hbnVhbCBjaGFuZ2UgaW4gaGFzaCBoaXN0b3J5ICM5MTZcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0J3MgbGlrZSBhIHB1c2ggYnV0IGxhY2tzIHRoZSBpbmZvcm1hdGlvbiBvZiB0aGUgZGlyZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICByb3V0ZXJIaXN0b3J5LmdvKC0xLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdHJpZ2dlckFmdGVyRWFjaCh0b0xvY2F0aW9uLCBmcm9tLCBmYWlsdXJlKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLy8gYXZvaWQgd2FybmluZ3MgaW4gdGhlIGNvbnNvbGUgYWJvdXQgdW5jYXVnaHQgcmVqZWN0aW9ucywgdGhleSBhcmUgbG9nZ2VkIGJ5IHRyaWdnZXJFcnJvcnNcbiAgICAgICAgICAgICAgICAuY2F0Y2gobm9vcCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBJbml0aWFsaXphdGlvbiBhbmQgRXJyb3JzXG4gICAgbGV0IHJlYWR5SGFuZGxlcnMgPSB1c2VDYWxsYmFja3MoKTtcbiAgICBsZXQgZXJyb3JMaXN0ZW5lcnMgPSB1c2VDYWxsYmFja3MoKTtcbiAgICBsZXQgcmVhZHk7XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciBlcnJvckxpc3RlbmVycyBhZGRlZCB2aWEgb25FcnJvciBhbmQgdGhyb3dzIHRoZSBlcnJvciBhcyB3ZWxsXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXJyb3IgLSBlcnJvciB0byB0aHJvd1xuICAgICAqIEBwYXJhbSB0byAtIGxvY2F0aW9uIHdlIHdlcmUgbmF2aWdhdGluZyB0byB3aGVuIHRoZSBlcnJvciBoYXBwZW5lZFxuICAgICAqIEBwYXJhbSBmcm9tIC0gbG9jYXRpb24gd2Ugd2VyZSBuYXZpZ2F0aW5nIGZyb20gd2hlbiB0aGUgZXJyb3IgaGFwcGVuZWRcbiAgICAgKiBAcmV0dXJucyB0aGUgZXJyb3IgYXMgYSByZWplY3RlZCBwcm9taXNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJpZ2dlckVycm9yKGVycm9yLCB0bywgZnJvbSkge1xuICAgICAgICBtYXJrQXNSZWFkeShlcnJvcik7XG4gICAgICAgIGNvbnN0IGxpc3QgPSBlcnJvckxpc3RlbmVycy5saXN0KCk7XG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCkge1xuICAgICAgICAgICAgbGlzdC5mb3JFYWNoKGhhbmRsZXIgPT4gaGFuZGxlcihlcnJvciwgdG8sIGZyb20pKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcbiAgICAgICAgICAgICAgICB3YXJuKCd1bmNhdWdodCBlcnJvciBkdXJpbmcgcm91dGUgbmF2aWdhdGlvbjonKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJlamVjdCB0aGUgZXJyb3Igbm8gbWF0dGVyIHRoZXJlIHdlcmUgZXJyb3IgbGlzdGVuZXJzIG9yIG5vdFxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpc1JlYWR5KCkge1xuICAgICAgICBpZiAocmVhZHkgJiYgY3VycmVudFJvdXRlLnZhbHVlICE9PSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEKVxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcmVhZHlIYW5kbGVycy5hZGQoW3Jlc29sdmUsIHJlamVjdF0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gbWFya0FzUmVhZHkoZXJyKSB7XG4gICAgICAgIGlmICghcmVhZHkpIHtcbiAgICAgICAgICAgIC8vIHN0aWxsIG5vdCByZWFkeSBpZiBhbiBlcnJvciBoYXBwZW5lZFxuICAgICAgICAgICAgcmVhZHkgPSAhZXJyO1xuICAgICAgICAgICAgc2V0dXBMaXN0ZW5lcnMoKTtcbiAgICAgICAgICAgIHJlYWR5SGFuZGxlcnNcbiAgICAgICAgICAgICAgICAubGlzdCgpXG4gICAgICAgICAgICAgICAgLmZvckVhY2goKFtyZXNvbHZlLCByZWplY3RdKSA9PiAoZXJyID8gcmVqZWN0KGVycikgOiByZXNvbHZlKCkpKTtcbiAgICAgICAgICAgIHJlYWR5SGFuZGxlcnMucmVzZXQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZXJyO1xuICAgIH1cbiAgICAvLyBTY3JvbGwgYmVoYXZpb3JcbiAgICBmdW5jdGlvbiBoYW5kbGVTY3JvbGwodG8sIGZyb20sIGlzUHVzaCwgaXNGaXJzdE5hdmlnYXRpb24pIHtcbiAgICAgICAgY29uc3QgeyBzY3JvbGxCZWhhdmlvciB9ID0gb3B0aW9ucztcbiAgICAgICAgaWYgKCFpc0Jyb3dzZXIgfHwgIXNjcm9sbEJlaGF2aW9yKVxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICBjb25zdCBzY3JvbGxQb3NpdGlvbiA9ICghaXNQdXNoICYmIGdldFNhdmVkU2Nyb2xsUG9zaXRpb24oZ2V0U2Nyb2xsS2V5KHRvLmZ1bGxQYXRoLCAwKSkpIHx8XG4gICAgICAgICAgICAoKGlzRmlyc3ROYXZpZ2F0aW9uIHx8ICFpc1B1c2gpICYmXG4gICAgICAgICAgICAgICAgaGlzdG9yeS5zdGF0ZSAmJlxuICAgICAgICAgICAgICAgIGhpc3Rvcnkuc3RhdGUuc2Nyb2xsKSB8fFxuICAgICAgICAgICAgbnVsbDtcbiAgICAgICAgcmV0dXJuIG5leHRUaWNrKClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHNjcm9sbEJlaGF2aW9yKHRvLCBmcm9tLCBzY3JvbGxQb3NpdGlvbikpXG4gICAgICAgICAgICAudGhlbihwb3NpdGlvbiA9PiBwb3NpdGlvbiAmJiBzY3JvbGxUb1Bvc2l0aW9uKHBvc2l0aW9uKSlcbiAgICAgICAgICAgIC5jYXRjaChlcnIgPT4gdHJpZ2dlckVycm9yKGVyciwgdG8sIGZyb20pKTtcbiAgICB9XG4gICAgY29uc3QgZ28gPSAoZGVsdGEpID0+IHJvdXRlckhpc3RvcnkuZ28oZGVsdGEpO1xuICAgIGxldCBzdGFydGVkO1xuICAgIGNvbnN0IGluc3RhbGxlZEFwcHMgPSBuZXcgU2V0KCk7XG4gICAgY29uc3Qgcm91dGVyID0ge1xuICAgICAgICBjdXJyZW50Um91dGUsXG4gICAgICAgIGxpc3RlbmluZzogdHJ1ZSxcbiAgICAgICAgYWRkUm91dGUsXG4gICAgICAgIHJlbW92ZVJvdXRlLFxuICAgICAgICBjbGVhclJvdXRlczogbWF0Y2hlci5jbGVhclJvdXRlcyxcbiAgICAgICAgaGFzUm91dGUsXG4gICAgICAgIGdldFJvdXRlcyxcbiAgICAgICAgcmVzb2x2ZSxcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgcHVzaCxcbiAgICAgICAgcmVwbGFjZSxcbiAgICAgICAgZ28sXG4gICAgICAgIGJhY2s6ICgpID0+IGdvKC0xKSxcbiAgICAgICAgZm9yd2FyZDogKCkgPT4gZ28oMSksXG4gICAgICAgIGJlZm9yZUVhY2g6IGJlZm9yZUd1YXJkcy5hZGQsXG4gICAgICAgIGJlZm9yZVJlc29sdmU6IGJlZm9yZVJlc29sdmVHdWFyZHMuYWRkLFxuICAgICAgICBhZnRlckVhY2g6IGFmdGVyR3VhcmRzLmFkZCxcbiAgICAgICAgb25FcnJvcjogZXJyb3JMaXN0ZW5lcnMuYWRkLFxuICAgICAgICBpc1JlYWR5LFxuICAgICAgICBpbnN0YWxsKGFwcCkge1xuICAgICAgICAgICAgY29uc3Qgcm91dGVyID0gdGhpcztcbiAgICAgICAgICAgIGFwcC5jb21wb25lbnQoJ1JvdXRlckxpbmsnLCBSb3V0ZXJMaW5rKTtcbiAgICAgICAgICAgIGFwcC5jb21wb25lbnQoJ1JvdXRlclZpZXcnLCBSb3V0ZXJWaWV3KTtcbiAgICAgICAgICAgIGFwcC5jb25maWcuZ2xvYmFsUHJvcGVydGllcy4kcm91dGVyID0gcm91dGVyO1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcC5jb25maWcuZ2xvYmFsUHJvcGVydGllcywgJyRyb3V0ZScsIHtcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdldDogKCkgPT4gdW5yZWYoY3VycmVudFJvdXRlKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gdGhpcyBpbml0aWFsIG5hdmlnYXRpb24gaXMgb25seSBuZWNlc3Nhcnkgb24gY2xpZW50LCBvbiBzZXJ2ZXIgaXQgZG9lc24ndFxuICAgICAgICAgICAgLy8gbWFrZSBzZW5zZSBiZWNhdXNlIGl0IHdpbGwgY3JlYXRlIGFuIGV4dHJhIHVubmVjZXNzYXJ5IG5hdmlnYXRpb24gYW5kIGNvdWxkXG4gICAgICAgICAgICAvLyBsZWFkIHRvIHByb2JsZW1zXG4gICAgICAgICAgICBpZiAoaXNCcm93c2VyICYmXG4gICAgICAgICAgICAgICAgLy8gdXNlZCBmb3IgdGhlIGluaXRpYWwgbmF2aWdhdGlvbiBjbGllbnQgc2lkZSB0byBhdm9pZCBwdXNoaW5nXG4gICAgICAgICAgICAgICAgLy8gbXVsdGlwbGUgdGltZXMgd2hlbiB0aGUgcm91dGVyIGlzIHVzZWQgaW4gbXVsdGlwbGUgYXBwc1xuICAgICAgICAgICAgICAgICFzdGFydGVkICYmXG4gICAgICAgICAgICAgICAgY3VycmVudFJvdXRlLnZhbHVlID09PSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEKSB7XG4gICAgICAgICAgICAgICAgLy8gc2VlIGFib3ZlXG4gICAgICAgICAgICAgICAgc3RhcnRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcHVzaChyb3V0ZXJIaXN0b3J5LmxvY2F0aW9uKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKVxuICAgICAgICAgICAgICAgICAgICAgICAgd2FybignVW5leHBlY3RlZCBlcnJvciB3aGVuIHN0YXJ0aW5nIHRoZSByb3V0ZXI6JywgZXJyKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlYWN0aXZlUm91dGUgPSB7fTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIFNUQVJUX0xPQ0FUSU9OX05PUk1BTElaRUQpIHtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVhY3RpdmVSb3V0ZSwga2V5LCB7XG4gICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gY3VycmVudFJvdXRlLnZhbHVlW2tleV0sXG4gICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhcHAucHJvdmlkZShyb3V0ZXJLZXksIHJvdXRlcik7XG4gICAgICAgICAgICBhcHAucHJvdmlkZShyb3V0ZUxvY2F0aW9uS2V5LCBzaGFsbG93UmVhY3RpdmUocmVhY3RpdmVSb3V0ZSkpO1xuICAgICAgICAgICAgYXBwLnByb3ZpZGUocm91dGVyVmlld0xvY2F0aW9uS2V5LCBjdXJyZW50Um91dGUpO1xuICAgICAgICAgICAgY29uc3QgdW5tb3VudEFwcCA9IGFwcC51bm1vdW50O1xuICAgICAgICAgICAgaW5zdGFsbGVkQXBwcy5hZGQoYXBwKTtcbiAgICAgICAgICAgIGFwcC51bm1vdW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGluc3RhbGxlZEFwcHMuZGVsZXRlKGFwcCk7XG4gICAgICAgICAgICAgICAgLy8gdGhlIHJvdXRlciBpcyBub3QgYXR0YWNoZWQgdG8gYW4gYXBwIGFueW1vcmVcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFsbGVkQXBwcy5zaXplIDwgMSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpbnZhbGlkYXRlIHRoZSBjdXJyZW50IG5hdmlnYXRpb25cbiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0xvY2F0aW9uID0gU1RBUlRfTE9DQVRJT05fTk9STUFMSVpFRDtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlSGlzdG9yeUxpc3RlbmVyICYmIHJlbW92ZUhpc3RvcnlMaXN0ZW5lcigpO1xuICAgICAgICAgICAgICAgICAgICByZW1vdmVIaXN0b3J5TGlzdGVuZXIgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50Um91dGUudmFsdWUgPSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEO1xuICAgICAgICAgICAgICAgICAgICBzdGFydGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJlYWR5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHVubW91bnRBcHAoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBUT0RPOiB0aGlzIHByb2JhYmx5IG5lZWRzIHRvIGJlIHVwZGF0ZWQgc28gaXQgY2FuIGJlIHVzZWQgYnkgdnVlLXRlcm11aVxuICAgICAgICAgICAgaWYgKCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSAmJiBpc0Jyb3dzZXIpIHtcbiAgICAgICAgICAgICAgICBhZGREZXZ0b29scyhhcHAsIHJvdXRlciwgbWF0Y2hlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgfTtcbiAgICAvLyBUT0RPOiB0eXBlIHRoaXMgYXMgTmF2aWdhdGlvbkd1YXJkUmV0dXJuIG9yIHNpbWlsYXIgaW5zdGVhZCBvZiBhbnlcbiAgICBmdW5jdGlvbiBydW5HdWFyZFF1ZXVlKGd1YXJkcykge1xuICAgICAgICByZXR1cm4gZ3VhcmRzLnJlZHVjZSgocHJvbWlzZSwgZ3VhcmQpID0+IHByb21pc2UudGhlbigoKSA9PiBydW5XaXRoQ29udGV4dChndWFyZCkpLCBQcm9taXNlLnJlc29sdmUoKSk7XG4gICAgfVxuICAgIHJldHVybiByb3V0ZXI7XG59XG5mdW5jdGlvbiBleHRyYWN0Q2hhbmdpbmdSZWNvcmRzKHRvLCBmcm9tKSB7XG4gICAgY29uc3QgbGVhdmluZ1JlY29yZHMgPSBbXTtcbiAgICBjb25zdCB1cGRhdGluZ1JlY29yZHMgPSBbXTtcbiAgICBjb25zdCBlbnRlcmluZ1JlY29yZHMgPSBbXTtcbiAgICBjb25zdCBsZW4gPSBNYXRoLm1heChmcm9tLm1hdGNoZWQubGVuZ3RoLCB0by5tYXRjaGVkLmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBjb25zdCByZWNvcmRGcm9tID0gZnJvbS5tYXRjaGVkW2ldO1xuICAgICAgICBpZiAocmVjb3JkRnJvbSkge1xuICAgICAgICAgICAgaWYgKHRvLm1hdGNoZWQuZmluZChyZWNvcmQgPT4gaXNTYW1lUm91dGVSZWNvcmQocmVjb3JkLCByZWNvcmRGcm9tKSkpXG4gICAgICAgICAgICAgICAgdXBkYXRpbmdSZWNvcmRzLnB1c2gocmVjb3JkRnJvbSk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgbGVhdmluZ1JlY29yZHMucHVzaChyZWNvcmRGcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZWNvcmRUbyA9IHRvLm1hdGNoZWRbaV07XG4gICAgICAgIGlmIChyZWNvcmRUbykge1xuICAgICAgICAgICAgLy8gdGhlIHR5cGUgZG9lc24ndCBtYXR0ZXIgYmVjYXVzZSB3ZSBhcmUgY29tcGFyaW5nIHBlciByZWZlcmVuY2VcbiAgICAgICAgICAgIGlmICghZnJvbS5tYXRjaGVkLmZpbmQocmVjb3JkID0+IGlzU2FtZVJvdXRlUmVjb3JkKHJlY29yZCwgcmVjb3JkVG8pKSkge1xuICAgICAgICAgICAgICAgIGVudGVyaW5nUmVjb3Jkcy5wdXNoKHJlY29yZFRvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW2xlYXZpbmdSZWNvcmRzLCB1cGRhdGluZ1JlY29yZHMsIGVudGVyaW5nUmVjb3Jkc107XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcm91dGVyIGluc3RhbmNlLiBFcXVpdmFsZW50IHRvIHVzaW5nIGAkcm91dGVyYCBpbnNpZGVcbiAqIHRlbXBsYXRlcy5cbiAqL1xuZnVuY3Rpb24gdXNlUm91dGVyKCkge1xuICAgIHJldHVybiBpbmplY3Qocm91dGVyS2V5KTtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgY3VycmVudCByb3V0ZSBsb2NhdGlvbi4gRXF1aXZhbGVudCB0byB1c2luZyBgJHJvdXRlYCBpbnNpZGVcbiAqIHRlbXBsYXRlcy5cbiAqL1xuZnVuY3Rpb24gdXNlUm91dGUoX25hbWUpIHtcbiAgICByZXR1cm4gaW5qZWN0KHJvdXRlTG9jYXRpb25LZXkpO1xufVxuXG5leHBvcnQgeyBOYXZpZ2F0aW9uRmFpbHVyZVR5cGUsIFJvdXRlckxpbmssIFJvdXRlclZpZXcsIFNUQVJUX0xPQ0FUSU9OX05PUk1BTElaRUQgYXMgU1RBUlRfTE9DQVRJT04sIGNyZWF0ZU1lbW9yeUhpc3RvcnksIGNyZWF0ZVJvdXRlciwgY3JlYXRlUm91dGVyTWF0Y2hlciwgY3JlYXRlV2ViSGFzaEhpc3RvcnksIGNyZWF0ZVdlYkhpc3RvcnksIGlzTmF2aWdhdGlvbkZhaWx1cmUsIGxvYWRSb3V0ZUxvY2F0aW9uLCBtYXRjaGVkUm91dGVLZXksIG9uQmVmb3JlUm91dGVMZWF2ZSwgb25CZWZvcmVSb3V0ZVVwZGF0ZSwgcGFyc2VRdWVyeSwgcm91dGVMb2NhdGlvbktleSwgcm91dGVyS2V5LCByb3V0ZXJWaWV3TG9jYXRpb25LZXksIHN0cmluZ2lmeVF1ZXJ5LCB1c2VMaW5rLCB1c2VSb3V0ZSwgdXNlUm91dGVyLCB2aWV3RGVwdGhLZXkgfTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUtBLFNBQVMsb0JBQW9CLFFBQVEsYUFBYSxlQUFlLGFBQWEsVUFBVSxPQUFPLGFBQWEsaUJBQWlCLFVBQVUsR0FBRyxTQUFTLEtBQUssT0FBTyxZQUFZLGlCQUFpQixnQkFBZ0I7QUFDNU0sU0FBUywyQkFBMkI7QUFFcEMsTUFBTSxZQUFZLE9BQU8sYUFBYTtBQVF0QyxTQUFTLGlCQUFpQixXQUFXO0FBQ2pDLFNBQVEsT0FBTyxjQUFjLFlBQ3pCLGlCQUFpQixhQUNqQixXQUFXLGFBQ1gsZUFBZTtBQUN2QjtBQUNBLFNBQVMsV0FBVyxLQUFLO0FBQ3JCLFNBQVEsSUFBSSxjQUNSLElBQUksT0FBTyxXQUFXLE1BQU07QUFBQTtBQUFBLEVBRzNCLElBQUksV0FBVyxpQkFBaUIsSUFBSSxPQUFPO0FBQ3BEO0FBQ0EsTUFBTSxTQUFTLE9BQU87QUFDdEIsU0FBUyxjQUFjLElBQUksUUFBUTtBQUMvQixRQUFNLFlBQVksQ0FBQztBQUNuQixhQUFXLE9BQU8sUUFBUTtBQUN0QixVQUFNLFFBQVEsT0FBTyxHQUFHO0FBQ3hCLGNBQVUsR0FBRyxJQUFJLFFBQVEsS0FBSyxJQUN4QixNQUFNLElBQUksRUFBRSxJQUNaLEdBQUcsS0FBSztBQUFBLEVBQ2xCO0FBQ0EsU0FBTztBQUNYO0FBQ0EsTUFBTSxPQUFPLE1BQU07QUFBRTtBQUtyQixNQUFNLFVBQVUsTUFBTTtBQUV0QixTQUFTLEtBQUssS0FBSztBQUVmLFFBQU0sT0FBTyxNQUFNLEtBQUssU0FBUyxFQUFFLE1BQU0sQ0FBQztBQUMxQyxVQUFRLEtBQUssTUFBTSxTQUFTLENBQUMsd0JBQXdCLEdBQUcsRUFBRSxPQUFPLElBQUksQ0FBQztBQUMxRTtBQXFCQSxNQUFNLFVBQVU7QUFDaEIsTUFBTSxlQUFlO0FBQ3JCLE1BQU0sV0FBVztBQUNqQixNQUFNLFdBQVc7QUFDakIsTUFBTSxRQUFRO0FBQ2QsTUFBTSxVQUFVO0FBZWhCLE1BQU0sc0JBQXNCO0FBQzVCLE1BQU0sdUJBQXVCO0FBQzdCLE1BQU0sZUFBZTtBQUNyQixNQUFNLGtCQUFrQjtBQUN4QixNQUFNLG9CQUFvQjtBQUMxQixNQUFNLGNBQWM7QUFDcEIsTUFBTSxxQkFBcUI7QUFDM0IsTUFBTSxlQUFlO0FBU3JCLFNBQVMsYUFBYSxNQUFNO0FBQ3hCLFNBQU8sVUFBVSxLQUFLLElBQUksRUFDckIsUUFBUSxhQUFhLEdBQUcsRUFDeEIsUUFBUSxxQkFBcUIsR0FBRyxFQUNoQyxRQUFRLHNCQUFzQixHQUFHO0FBQzFDO0FBT0EsU0FBUyxXQUFXLE1BQU07QUFDdEIsU0FBTyxhQUFhLElBQUksRUFDbkIsUUFBUSxtQkFBbUIsR0FBRyxFQUM5QixRQUFRLG9CQUFvQixHQUFHLEVBQy9CLFFBQVEsY0FBYyxHQUFHO0FBQ2xDO0FBUUEsU0FBUyxpQkFBaUIsTUFBTTtBQUM1QixTQUFRLGFBQWEsSUFBSSxFQUVwQixRQUFRLFNBQVMsS0FBSyxFQUN0QixRQUFRLGNBQWMsR0FBRyxFQUN6QixRQUFRLFNBQVMsS0FBSyxFQUN0QixRQUFRLGNBQWMsS0FBSyxFQUMzQixRQUFRLGlCQUFpQixHQUFHLEVBQzVCLFFBQVEsbUJBQW1CLEdBQUcsRUFDOUIsUUFBUSxvQkFBb0IsR0FBRyxFQUMvQixRQUFRLGNBQWMsR0FBRztBQUNsQztBQU1BLFNBQVMsZUFBZSxNQUFNO0FBQzFCLFNBQU8saUJBQWlCLElBQUksRUFBRSxRQUFRLFVBQVUsS0FBSztBQUN6RDtBQU9BLFNBQVMsV0FBVyxNQUFNO0FBQ3RCLFNBQU8sYUFBYSxJQUFJLEVBQUUsUUFBUSxTQUFTLEtBQUssRUFBRSxRQUFRLE9BQU8sS0FBSztBQUMxRTtBQVVBLFNBQVMsWUFBWSxNQUFNO0FBQ3ZCLFNBQU8sUUFBUSxPQUFPLEtBQUssV0FBVyxJQUFJLEVBQUUsUUFBUSxVQUFVLEtBQUs7QUFDdkU7QUFRQSxTQUFTLE9BQU8sTUFBTTtBQUNsQixNQUFJO0FBQ0EsV0FBTyxtQkFBbUIsS0FBSyxJQUFJO0FBQUEsRUFDdkMsU0FDTyxLQUFLO0FBQ1IsSUFBMkMsS0FBSyxtQkFBbUIsSUFBSSx5QkFBeUI7QUFBQSxFQUNwRztBQUNBLFNBQU8sS0FBSztBQUNoQjtBQUVBLE1BQU0sb0JBQW9CO0FBQzFCLE1BQU0sc0JBQXNCLENBQUMsU0FBUyxLQUFLLFFBQVEsbUJBQW1CLEVBQUU7QUFVeEUsU0FBUyxTQUFTQSxhQUFZQyxXQUFVLGtCQUFrQixLQUFLO0FBQzNELE1BQUksTUFBTSxRQUFRLENBQUMsR0FBRyxlQUFlLElBQUksT0FBTztBQUdoRCxRQUFNLFVBQVVBLFVBQVMsUUFBUSxHQUFHO0FBQ3BDLE1BQUksWUFBWUEsVUFBUyxRQUFRLEdBQUc7QUFFcEMsTUFBSSxVQUFVLGFBQWEsV0FBVyxHQUFHO0FBQ3JDLGdCQUFZO0FBQUEsRUFDaEI7QUFDQSxNQUFJLFlBQVksSUFBSTtBQUNoQixXQUFPQSxVQUFTLE1BQU0sR0FBRyxTQUFTO0FBQ2xDLG1CQUFlQSxVQUFTLE1BQU0sWUFBWSxHQUFHLFVBQVUsS0FBSyxVQUFVQSxVQUFTLE1BQU07QUFDckYsWUFBUUQsWUFBVyxZQUFZO0FBQUEsRUFDbkM7QUFDQSxNQUFJLFVBQVUsSUFBSTtBQUNkLFdBQU8sUUFBUUMsVUFBUyxNQUFNLEdBQUcsT0FBTztBQUV4QyxXQUFPQSxVQUFTLE1BQU0sU0FBU0EsVUFBUyxNQUFNO0FBQUEsRUFDbEQ7QUFFQSxTQUFPLG9CQUFvQixRQUFRLE9BQU8sT0FBT0EsV0FBVSxlQUFlO0FBRTFFLFNBQU87QUFBQSxJQUNILFVBQVUsUUFBUSxnQkFBZ0IsT0FBTyxlQUFlO0FBQUEsSUFDeEQ7QUFBQSxJQUNBO0FBQUEsSUFDQSxNQUFNLE9BQU8sSUFBSTtBQUFBLEVBQ3JCO0FBQ0o7QUFPQSxTQUFTLGFBQWFDLGlCQUFnQkQsV0FBVTtBQUM1QyxRQUFNLFFBQVFBLFVBQVMsUUFBUUMsZ0JBQWVELFVBQVMsS0FBSyxJQUFJO0FBQ2hFLFNBQU9BLFVBQVMsUUFBUSxTQUFTLE9BQU8sU0FBU0EsVUFBUyxRQUFRO0FBQ3RFO0FBT0EsU0FBUyxVQUFVLFVBQVUsTUFBTTtBQUUvQixNQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsWUFBWSxFQUFFLFdBQVcsS0FBSyxZQUFZLENBQUM7QUFDOUQsV0FBTztBQUNYLFNBQU8sU0FBUyxNQUFNLEtBQUssTUFBTSxLQUFLO0FBQzFDO0FBVUEsU0FBUyxvQkFBb0JDLGlCQUFnQixHQUFHLEdBQUc7QUFDL0MsUUFBTSxhQUFhLEVBQUUsUUFBUSxTQUFTO0FBQ3RDLFFBQU0sYUFBYSxFQUFFLFFBQVEsU0FBUztBQUN0QyxTQUFRLGFBQWEsTUFDakIsZUFBZSxjQUNmLGtCQUFrQixFQUFFLFFBQVEsVUFBVSxHQUFHLEVBQUUsUUFBUSxVQUFVLENBQUMsS0FDOUQsMEJBQTBCLEVBQUUsUUFBUSxFQUFFLE1BQU0sS0FDNUNBLGdCQUFlLEVBQUUsS0FBSyxNQUFNQSxnQkFBZSxFQUFFLEtBQUssS0FDbEQsRUFBRSxTQUFTLEVBQUU7QUFDckI7QUFRQSxTQUFTLGtCQUFrQixHQUFHLEdBQUc7QUFJN0IsVUFBUSxFQUFFLFdBQVcsUUFBUSxFQUFFLFdBQVc7QUFDOUM7QUFDQSxTQUFTLDBCQUEwQixHQUFHLEdBQUc7QUFDckMsTUFBSSxPQUFPLEtBQUssQ0FBQyxFQUFFLFdBQVcsT0FBTyxLQUFLLENBQUMsRUFBRTtBQUN6QyxXQUFPO0FBQ1gsYUFBVyxPQUFPLEdBQUc7QUFDakIsUUFBSSxDQUFDLCtCQUErQixFQUFFLEdBQUcsR0FBRyxFQUFFLEdBQUcsQ0FBQztBQUM5QyxhQUFPO0FBQUEsRUFDZjtBQUNBLFNBQU87QUFDWDtBQUNBLFNBQVMsK0JBQStCLEdBQUcsR0FBRztBQUMxQyxTQUFPLFFBQVEsQ0FBQyxJQUNWLGtCQUFrQixHQUFHLENBQUMsSUFDdEIsUUFBUSxDQUFDLElBQ0wsa0JBQWtCLEdBQUcsQ0FBQyxJQUN0QixNQUFNO0FBQ3BCO0FBUUEsU0FBUyxrQkFBa0IsR0FBRyxHQUFHO0FBQzdCLFNBQU8sUUFBUSxDQUFDLElBQ1YsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxPQUFPLE1BQU0sVUFBVSxFQUFFLENBQUMsQ0FBQyxJQUM3RCxFQUFFLFdBQVcsS0FBSyxFQUFFLENBQUMsTUFBTTtBQUNyQztBQU9BLFNBQVMsb0JBQW9CLElBQUksTUFBTTtBQUNuQyxNQUFJLEdBQUcsV0FBVyxHQUFHO0FBQ2pCLFdBQU87QUFDWCxNQUErQyxDQUFDLEtBQUssV0FBVyxHQUFHLEdBQUc7QUFDbEUsU0FBSyxtRkFBbUYsRUFBRSxXQUFXLElBQUksNEJBQTRCLElBQUksSUFBSTtBQUM3SSxXQUFPO0FBQUEsRUFDWDtBQUNBLE1BQUksQ0FBQztBQUNELFdBQU87QUFDWCxRQUFNLGVBQWUsS0FBSyxNQUFNLEdBQUc7QUFDbkMsUUFBTSxhQUFhLEdBQUcsTUFBTSxHQUFHO0FBQy9CLFFBQU0sZ0JBQWdCLFdBQVcsV0FBVyxTQUFTLENBQUM7QUFHdEQsTUFBSSxrQkFBa0IsUUFBUSxrQkFBa0IsS0FBSztBQUNqRCxlQUFXLEtBQUssRUFBRTtBQUFBLEVBQ3RCO0FBQ0EsTUFBSSxXQUFXLGFBQWEsU0FBUztBQUNyQyxNQUFJO0FBQ0osTUFBSTtBQUNKLE9BQUssYUFBYSxHQUFHLGFBQWEsV0FBVyxRQUFRLGNBQWM7QUFDL0QsY0FBVSxXQUFXLFVBQVU7QUFFL0IsUUFBSSxZQUFZO0FBQ1o7QUFFSixRQUFJLFlBQVksTUFBTTtBQUVsQixVQUFJLFdBQVc7QUFDWDtBQUFBLElBRVI7QUFHSTtBQUFBLEVBQ1I7QUFDQSxTQUFRLGFBQWEsTUFBTSxHQUFHLFFBQVEsRUFBRSxLQUFLLEdBQUcsSUFDNUMsTUFDQSxXQUFXLE1BQU0sVUFBVSxFQUFFLEtBQUssR0FBRztBQUM3QztBQWdCQSxNQUFNLDRCQUE0QjtBQUFBLEVBQzlCLE1BQU07QUFBQTtBQUFBLEVBRU4sTUFBTTtBQUFBLEVBQ04sUUFBUSxDQUFDO0FBQUEsRUFDVCxPQUFPLENBQUM7QUFBQSxFQUNSLE1BQU07QUFBQSxFQUNOLFVBQVU7QUFBQSxFQUNWLFNBQVMsQ0FBQztBQUFBLEVBQ1YsTUFBTSxDQUFDO0FBQUEsRUFDUCxnQkFBZ0I7QUFDcEI7QUFFQSxJQUFJO0FBQUEsQ0FDSCxTQUFVQyxpQkFBZ0I7QUFDdkIsRUFBQUEsZ0JBQWUsS0FBSyxJQUFJO0FBQ3hCLEVBQUFBLGdCQUFlLE1BQU0sSUFBSTtBQUM3QixHQUFHLG1CQUFtQixpQkFBaUIsQ0FBQyxFQUFFO0FBQzFDLElBQUk7QUFBQSxDQUNILFNBQVVDLHNCQUFxQjtBQUM1QixFQUFBQSxxQkFBb0IsTUFBTSxJQUFJO0FBQzlCLEVBQUFBLHFCQUFvQixTQUFTLElBQUk7QUFDakMsRUFBQUEscUJBQW9CLFNBQVMsSUFBSTtBQUNyQyxHQUFHLHdCQUF3QixzQkFBc0IsQ0FBQyxFQUFFO0FBSXBELE1BQU0sUUFBUTtBQVFkLFNBQVMsY0FBYyxNQUFNO0FBQ3pCLE1BQUksQ0FBQyxNQUFNO0FBQ1AsUUFBSSxXQUFXO0FBRVgsWUFBTSxTQUFTLFNBQVMsY0FBYyxNQUFNO0FBQzVDLGFBQVEsVUFBVSxPQUFPLGFBQWEsTUFBTSxLQUFNO0FBRWxELGFBQU8sS0FBSyxRQUFRLG1CQUFtQixFQUFFO0FBQUEsSUFDN0MsT0FDSztBQUNELGFBQU87QUFBQSxJQUNYO0FBQUEsRUFDSjtBQUlBLE1BQUksS0FBSyxDQUFDLE1BQU0sT0FBTyxLQUFLLENBQUMsTUFBTTtBQUMvQixXQUFPLE1BQU07QUFHakIsU0FBTyxvQkFBb0IsSUFBSTtBQUNuQztBQUVBLE1BQU0saUJBQWlCO0FBQ3ZCLFNBQVMsV0FBVyxNQUFNSCxXQUFVO0FBQ2hDLFNBQU8sS0FBSyxRQUFRLGdCQUFnQixHQUFHLElBQUlBO0FBQy9DO0FBRUEsU0FBUyxtQkFBbUIsSUFBSSxRQUFRO0FBQ3BDLFFBQU0sVUFBVSxTQUFTLGdCQUFnQixzQkFBc0I7QUFDL0QsUUFBTSxTQUFTLEdBQUcsc0JBQXNCO0FBQ3hDLFNBQU87QUFBQSxJQUNILFVBQVUsT0FBTztBQUFBLElBQ2pCLE1BQU0sT0FBTyxPQUFPLFFBQVEsUUFBUSxPQUFPLFFBQVE7QUFBQSxJQUNuRCxLQUFLLE9BQU8sTUFBTSxRQUFRLE9BQU8sT0FBTyxPQUFPO0FBQUEsRUFDbkQ7QUFDSjtBQUNBLE1BQU0sd0JBQXdCLE9BQU87QUFBQSxFQUNqQyxNQUFNLE9BQU87QUFBQSxFQUNiLEtBQUssT0FBTztBQUNoQjtBQUNBLFNBQVMsaUJBQWlCLFVBQVU7QUFDaEMsTUFBSTtBQUNKLE1BQUksUUFBUSxVQUFVO0FBQ2xCLFVBQU0sYUFBYSxTQUFTO0FBQzVCLFVBQU0sZUFBZSxPQUFPLGVBQWUsWUFBWSxXQUFXLFdBQVcsR0FBRztBQXNCaEYsUUFBK0MsT0FBTyxTQUFTLE9BQU8sVUFBVTtBQUM1RSxVQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxlQUFlLFNBQVMsR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHO0FBQ2pFLFlBQUk7QUFDQSxnQkFBTSxVQUFVLFNBQVMsY0FBYyxTQUFTLEVBQUU7QUFDbEQsY0FBSSxnQkFBZ0IsU0FBUztBQUN6QixpQkFBSyxpQkFBaUIsU0FBUyxFQUFFLHNEQUFzRCxTQUFTLEVBQUUsaUNBQWlDO0FBRW5JO0FBQUEsVUFDSjtBQUFBLFFBQ0osU0FDTyxLQUFLO0FBQ1IsZUFBSyxpQkFBaUIsU0FBUyxFQUFFLDRRQUE0UTtBQUU3UztBQUFBLFFBQ0o7QUFBQSxNQUNKO0FBQUEsSUFDSjtBQUNBLFVBQU0sS0FBSyxPQUFPLGVBQWUsV0FDM0IsZUFDSSxTQUFTLGVBQWUsV0FBVyxNQUFNLENBQUMsQ0FBQyxJQUMzQyxTQUFTLGNBQWMsVUFBVSxJQUNyQztBQUNOLFFBQUksQ0FBQyxJQUFJO0FBQ0wsTUFDSSxLQUFLLHlDQUF5QyxTQUFTLEVBQUUsK0JBQStCO0FBQzVGO0FBQUEsSUFDSjtBQUNBLHNCQUFrQixtQkFBbUIsSUFBSSxRQUFRO0FBQUEsRUFDckQsT0FDSztBQUNELHNCQUFrQjtBQUFBLEVBQ3RCO0FBQ0EsTUFBSSxvQkFBb0IsU0FBUyxnQkFBZ0I7QUFDN0MsV0FBTyxTQUFTLGVBQWU7QUFBQSxPQUM5QjtBQUNELFdBQU8sU0FBUyxnQkFBZ0IsUUFBUSxPQUFPLGdCQUFnQixPQUFPLE9BQU8sU0FBUyxnQkFBZ0IsT0FBTyxPQUFPLGdCQUFnQixNQUFNLE9BQU8sT0FBTztBQUFBLEVBQzVKO0FBQ0o7QUFDQSxTQUFTLGFBQWEsTUFBTSxPQUFPO0FBQy9CLFFBQU0sV0FBVyxRQUFRLFFBQVEsUUFBUSxNQUFNLFdBQVcsUUFBUTtBQUNsRSxTQUFPLFdBQVc7QUFDdEI7QUFDQSxNQUFNLGtCQUFrQixvQkFBSSxJQUFJO0FBQ2hDLFNBQVMsbUJBQW1CLEtBQUssZ0JBQWdCO0FBQzdDLGtCQUFnQixJQUFJLEtBQUssY0FBYztBQUMzQztBQUNBLFNBQVMsdUJBQXVCLEtBQUs7QUFDakMsUUFBTSxTQUFTLGdCQUFnQixJQUFJLEdBQUc7QUFFdEMsa0JBQWdCLE9BQU8sR0FBRztBQUMxQixTQUFPO0FBQ1g7QUFpQkEsSUFBSSxxQkFBcUIsTUFBTSxTQUFTLFdBQVcsT0FBTyxTQUFTO0FBTW5FLFNBQVMsc0JBQXNCLE1BQU1BLFdBQVU7QUFDM0MsUUFBTSxFQUFFLFVBQVUsUUFBUSxLQUFLLElBQUlBO0FBRW5DLFFBQU0sVUFBVSxLQUFLLFFBQVEsR0FBRztBQUNoQyxNQUFJLFVBQVUsSUFBSTtBQUNkLFFBQUksV0FBVyxLQUFLLFNBQVMsS0FBSyxNQUFNLE9BQU8sQ0FBQyxJQUMxQyxLQUFLLE1BQU0sT0FBTyxFQUFFLFNBQ3BCO0FBQ04sUUFBSSxlQUFlLEtBQUssTUFBTSxRQUFRO0FBRXRDLFFBQUksYUFBYSxDQUFDLE1BQU07QUFDcEIscUJBQWUsTUFBTTtBQUN6QixXQUFPLFVBQVUsY0FBYyxFQUFFO0FBQUEsRUFDckM7QUFDQSxRQUFNLE9BQU8sVUFBVSxVQUFVLElBQUk7QUFDckMsU0FBTyxPQUFPLFNBQVM7QUFDM0I7QUFDQSxTQUFTLG9CQUFvQixNQUFNLGNBQWMsaUJBQWlCLFNBQVM7QUFDdkUsTUFBSSxZQUFZLENBQUM7QUFDakIsTUFBSSxZQUFZLENBQUM7QUFHakIsTUFBSSxhQUFhO0FBQ2pCLFFBQU0sa0JBQWtCLENBQUMsRUFBRSxNQUFPLE1BQU07QUFDcEMsVUFBTSxLQUFLLHNCQUFzQixNQUFNLFFBQVE7QUFDL0MsVUFBTSxPQUFPLGdCQUFnQjtBQUM3QixVQUFNLFlBQVksYUFBYTtBQUMvQixRQUFJLFFBQVE7QUFDWixRQUFJLE9BQU87QUFDUCxzQkFBZ0IsUUFBUTtBQUN4QixtQkFBYSxRQUFRO0FBRXJCLFVBQUksY0FBYyxlQUFlLE1BQU07QUFDbkMscUJBQWE7QUFDYjtBQUFBLE1BQ0o7QUFDQSxjQUFRLFlBQVksTUFBTSxXQUFXLFVBQVUsV0FBVztBQUFBLElBQzlELE9BQ0s7QUFDRCxjQUFRLEVBQUU7QUFBQSxJQUNkO0FBTUEsY0FBVSxRQUFRLGNBQVk7QUFDMUIsZUFBUyxnQkFBZ0IsT0FBTyxNQUFNO0FBQUEsUUFDbEM7QUFBQSxRQUNBLE1BQU0sZUFBZTtBQUFBLFFBQ3JCLFdBQVcsUUFDTCxRQUFRLElBQ0osb0JBQW9CLFVBQ3BCLG9CQUFvQixPQUN4QixvQkFBb0I7QUFBQSxNQUM5QixDQUFDO0FBQUEsSUFDTCxDQUFDO0FBQUEsRUFDTDtBQUNBLFdBQVMsaUJBQWlCO0FBQ3RCLGlCQUFhLGdCQUFnQjtBQUFBLEVBQ2pDO0FBQ0EsV0FBUyxPQUFPLFVBQVU7QUFFdEIsY0FBVSxLQUFLLFFBQVE7QUFDdkIsVUFBTSxXQUFXLE1BQU07QUFDbkIsWUFBTSxRQUFRLFVBQVUsUUFBUSxRQUFRO0FBQ3hDLFVBQUksUUFBUTtBQUNSLGtCQUFVLE9BQU8sT0FBTyxDQUFDO0FBQUEsSUFDakM7QUFDQSxjQUFVLEtBQUssUUFBUTtBQUN2QixXQUFPO0FBQUEsRUFDWDtBQUNBLFdBQVMsdUJBQXVCO0FBQzVCLFVBQU0sRUFBRSxTQUFBSSxTQUFRLElBQUk7QUFDcEIsUUFBSSxDQUFDQSxTQUFRO0FBQ1Q7QUFDSixJQUFBQSxTQUFRLGFBQWEsT0FBTyxDQUFDLEdBQUdBLFNBQVEsT0FBTyxFQUFFLFFBQVEsc0JBQXNCLEVBQUUsQ0FBQyxHQUFHLEVBQUU7QUFBQSxFQUMzRjtBQUNBLFdBQVMsVUFBVTtBQUNmLGVBQVcsWUFBWTtBQUNuQixlQUFTO0FBQ2IsZ0JBQVksQ0FBQztBQUNiLFdBQU8sb0JBQW9CLFlBQVksZUFBZTtBQUN0RCxXQUFPLG9CQUFvQixnQkFBZ0Isb0JBQW9CO0FBQUEsRUFDbkU7QUFFQSxTQUFPLGlCQUFpQixZQUFZLGVBQWU7QUFHbkQsU0FBTyxpQkFBaUIsZ0JBQWdCLHNCQUFzQjtBQUFBLElBQzFELFNBQVM7QUFBQSxFQUNiLENBQUM7QUFDRCxTQUFPO0FBQUEsSUFDSDtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDSjtBQUNKO0FBSUEsU0FBUyxXQUFXLE1BQU0sU0FBUyxTQUFTLFdBQVcsT0FBTyxnQkFBZ0IsT0FBTztBQUNqRixTQUFPO0FBQUEsSUFDSDtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0EsVUFBVSxPQUFPLFFBQVE7QUFBQSxJQUN6QixRQUFRLGdCQUFnQixzQkFBc0IsSUFBSTtBQUFBLEVBQ3REO0FBQ0o7QUFDQSxTQUFTLDBCQUEwQixNQUFNO0FBQ3JDLFFBQU0sRUFBRSxTQUFBQSxVQUFTLFVBQUFKLFVBQVMsSUFBSTtBQUU5QixRQUFNLGtCQUFrQjtBQUFBLElBQ3BCLE9BQU8sc0JBQXNCLE1BQU1BLFNBQVE7QUFBQSxFQUMvQztBQUNBLFFBQU0sZUFBZSxFQUFFLE9BQU9JLFNBQVEsTUFBTTtBQUU1QyxNQUFJLENBQUMsYUFBYSxPQUFPO0FBQ3JCLG1CQUFlLGdCQUFnQixPQUFPO0FBQUEsTUFDbEMsTUFBTTtBQUFBLE1BQ04sU0FBUyxnQkFBZ0I7QUFBQSxNQUN6QixTQUFTO0FBQUE7QUFBQSxNQUVULFVBQVVBLFNBQVEsU0FBUztBQUFBLE1BQzNCLFVBQVU7QUFBQTtBQUFBO0FBQUEsTUFHVixRQUFRO0FBQUEsSUFDWixHQUFHLElBQUk7QUFBQSxFQUNYO0FBQ0EsV0FBUyxlQUFlLElBQUksT0FBT0MsVUFBUztBQVV4QyxVQUFNLFlBQVksS0FBSyxRQUFRLEdBQUc7QUFDbEMsVUFBTSxNQUFNLFlBQVksTUFDakJMLFVBQVMsUUFBUSxTQUFTLGNBQWMsTUFBTSxJQUMzQyxPQUNBLEtBQUssTUFBTSxTQUFTLEtBQUssS0FDN0IsbUJBQW1CLElBQUksT0FBTztBQUNwQyxRQUFJO0FBR0EsTUFBQUksU0FBUUMsV0FBVSxpQkFBaUIsV0FBVyxFQUFFLE9BQU8sSUFBSSxHQUFHO0FBQzlELG1CQUFhLFFBQVE7QUFBQSxJQUN6QixTQUNPLEtBQUs7QUFDUixVQUFLLE1BQXdDO0FBQ3pDLGFBQUssaUNBQWlDLEdBQUc7QUFBQSxNQUM3QyxPQUNLO0FBQ0QsZ0JBQVEsTUFBTSxHQUFHO0FBQUEsTUFDckI7QUFFQSxNQUFBTCxVQUFTSyxXQUFVLFlBQVksUUFBUSxFQUFFLEdBQUc7QUFBQSxJQUNoRDtBQUFBLEVBQ0o7QUFDQSxXQUFTLFFBQVEsSUFBSSxNQUFNO0FBQ3ZCLFVBQU0sUUFBUSxPQUFPLENBQUMsR0FBR0QsU0FBUSxPQUFPO0FBQUEsTUFBVyxhQUFhLE1BQU07QUFBQTtBQUFBLE1BRXRFO0FBQUEsTUFBSSxhQUFhLE1BQU07QUFBQSxNQUFTO0FBQUEsSUFBSSxHQUFHLE1BQU0sRUFBRSxVQUFVLGFBQWEsTUFBTSxTQUFTLENBQUM7QUFDdEYsbUJBQWUsSUFBSSxPQUFPLElBQUk7QUFDOUIsb0JBQWdCLFFBQVE7QUFBQSxFQUM1QjtBQUNBLFdBQVMsS0FBSyxJQUFJLE1BQU07QUFHcEIsVUFBTSxlQUFlO0FBQUEsTUFBTyxDQUFDO0FBQUE7QUFBQTtBQUFBO0FBQUEsTUFJN0IsYUFBYTtBQUFBLE1BQU9BLFNBQVE7QUFBQSxNQUFPO0FBQUEsUUFDL0IsU0FBUztBQUFBLFFBQ1QsUUFBUSxzQkFBc0I7QUFBQSxNQUNsQztBQUFBLElBQUM7QUFDRCxRQUErQyxDQUFDQSxTQUFRLE9BQU87QUFDM0QsV0FBSztBQUFBO0FBQUE7QUFBQTtBQUFBLGtHQUVrRztBQUFBLElBQzNHO0FBQ0EsbUJBQWUsYUFBYSxTQUFTLGNBQWMsSUFBSTtBQUN2RCxVQUFNLFFBQVEsT0FBTyxDQUFDLEdBQUcsV0FBVyxnQkFBZ0IsT0FBTyxJQUFJLElBQUksR0FBRyxFQUFFLFVBQVUsYUFBYSxXQUFXLEVBQUUsR0FBRyxJQUFJO0FBQ25ILG1CQUFlLElBQUksT0FBTyxLQUFLO0FBQy9CLG9CQUFnQixRQUFRO0FBQUEsRUFDNUI7QUFDQSxTQUFPO0FBQUEsSUFDSCxVQUFVO0FBQUEsSUFDVixPQUFPO0FBQUEsSUFDUDtBQUFBLElBQ0E7QUFBQSxFQUNKO0FBQ0o7QUFNQSxTQUFTLGlCQUFpQixNQUFNO0FBQzVCLFNBQU8sY0FBYyxJQUFJO0FBQ3pCLFFBQU0sb0JBQW9CLDBCQUEwQixJQUFJO0FBQ3hELFFBQU0sbUJBQW1CLG9CQUFvQixNQUFNLGtCQUFrQixPQUFPLGtCQUFrQixVQUFVLGtCQUFrQixPQUFPO0FBQ2pJLFdBQVMsR0FBRyxPQUFPLG1CQUFtQixNQUFNO0FBQ3hDLFFBQUksQ0FBQztBQUNELHVCQUFpQixlQUFlO0FBQ3BDLFlBQVEsR0FBRyxLQUFLO0FBQUEsRUFDcEI7QUFDQSxRQUFNLGdCQUFnQixPQUFPO0FBQUE7QUFBQSxJQUV6QixVQUFVO0FBQUEsSUFDVjtBQUFBLElBQ0E7QUFBQSxJQUNBLFlBQVksV0FBVyxLQUFLLE1BQU0sSUFBSTtBQUFBLEVBQzFDLEdBQUcsbUJBQW1CLGdCQUFnQjtBQUN0QyxTQUFPLGVBQWUsZUFBZSxZQUFZO0FBQUEsSUFDN0MsWUFBWTtBQUFBLElBQ1osS0FBSyxNQUFNLGtCQUFrQixTQUFTO0FBQUEsRUFDMUMsQ0FBQztBQUNELFNBQU8sZUFBZSxlQUFlLFNBQVM7QUFBQSxJQUMxQyxZQUFZO0FBQUEsSUFDWixLQUFLLE1BQU0sa0JBQWtCLE1BQU07QUFBQSxFQUN2QyxDQUFDO0FBQ0QsU0FBTztBQUNYO0FBU0EsU0FBUyxvQkFBb0IsT0FBTyxJQUFJO0FBQ3BDLE1BQUksWUFBWSxDQUFDO0FBQ2pCLE1BQUksUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUN4QixNQUFJLFdBQVc7QUFDZixTQUFPLGNBQWMsSUFBSTtBQUN6QixXQUFTLFlBQVlKLFdBQVUsUUFBUSxDQUFDLEdBQUc7QUFDdkM7QUFDQSxRQUFJLGFBQWEsTUFBTSxRQUFRO0FBRTNCLFlBQU0sT0FBTyxRQUFRO0FBQUEsSUFDekI7QUFDQSxVQUFNLEtBQUssQ0FBQ0EsV0FBVSxLQUFLLENBQUM7QUFBQSxFQUNoQztBQUNBLFdBQVMsaUJBQWlCLElBQUksTUFBTSxFQUFFLFdBQVcsTUFBTSxHQUFHO0FBQ3RELFVBQU0sT0FBTztBQUFBLE1BQ1Q7QUFBQSxNQUNBO0FBQUEsTUFDQSxNQUFNLGVBQWU7QUFBQSxJQUN6QjtBQUNBLGVBQVcsWUFBWSxXQUFXO0FBQzlCLGVBQVMsSUFBSSxNQUFNLElBQUk7QUFBQSxJQUMzQjtBQUFBLEVBQ0o7QUFDQSxRQUFNLGdCQUFnQjtBQUFBO0FBQUEsSUFFbEIsVUFBVTtBQUFBO0FBQUEsSUFFVixPQUFPLENBQUM7QUFBQSxJQUNSO0FBQUEsSUFDQSxZQUFZLFdBQVcsS0FBSyxNQUFNLElBQUk7QUFBQSxJQUN0QyxRQUFRLElBQUksT0FBTztBQUVmLFlBQU0sT0FBTyxZQUFZLENBQUM7QUFDMUIsa0JBQVksSUFBSSxLQUFLO0FBQUEsSUFDekI7QUFBQSxJQUNBLEtBQUssSUFBSSxPQUFPO0FBQ1osa0JBQVksSUFBSSxLQUFLO0FBQUEsSUFDekI7QUFBQSxJQUNBLE9BQU8sVUFBVTtBQUNiLGdCQUFVLEtBQUssUUFBUTtBQUN2QixhQUFPLE1BQU07QUFDVCxjQUFNLFFBQVEsVUFBVSxRQUFRLFFBQVE7QUFDeEMsWUFBSSxRQUFRO0FBQ1Isb0JBQVUsT0FBTyxPQUFPLENBQUM7QUFBQSxNQUNqQztBQUFBLElBQ0o7QUFBQSxJQUNBLFVBQVU7QUFDTixrQkFBWSxDQUFDO0FBQ2IsY0FBUSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUNwQixpQkFBVztBQUFBLElBQ2Y7QUFBQSxJQUNBLEdBQUcsT0FBTyxnQkFBZ0IsTUFBTTtBQUM1QixZQUFNLE9BQU8sS0FBSztBQUNsQixZQUFNO0FBQUE7QUFBQTtBQUFBO0FBQUEsUUFJTixRQUFRLElBQUksb0JBQW9CLE9BQU8sb0JBQW9CO0FBQUE7QUFDM0QsaUJBQVcsS0FBSyxJQUFJLEdBQUcsS0FBSyxJQUFJLFdBQVcsT0FBTyxNQUFNLFNBQVMsQ0FBQyxDQUFDO0FBQ25FLFVBQUksZUFBZTtBQUNmLHlCQUFpQixLQUFLLFVBQVUsTUFBTTtBQUFBLFVBQ2xDO0FBQUEsVUFDQTtBQUFBLFFBQ0osQ0FBQztBQUFBLE1BQ0w7QUFBQSxJQUNKO0FBQUEsRUFDSjtBQUNBLFNBQU8sZUFBZSxlQUFlLFlBQVk7QUFBQSxJQUM3QyxZQUFZO0FBQUEsSUFDWixLQUFLLE1BQU0sTUFBTSxRQUFRLEVBQUUsQ0FBQztBQUFBLEVBQ2hDLENBQUM7QUFDRCxTQUFPLGVBQWUsZUFBZSxTQUFTO0FBQUEsSUFDMUMsWUFBWTtBQUFBLElBQ1osS0FBSyxNQUFNLE1BQU0sUUFBUSxFQUFFLENBQUM7QUFBQSxFQUNoQyxDQUFDO0FBQ0QsU0FBTztBQUNYO0FBMEJBLFNBQVMscUJBQXFCLE1BQU07QUFJaEMsU0FBTyxTQUFTLE9BQU8sUUFBUSxTQUFTLFdBQVcsU0FBUyxTQUFTO0FBRXJFLE1BQUksQ0FBQyxLQUFLLFNBQVMsR0FBRztBQUNsQixZQUFRO0FBQ1osTUFBK0MsQ0FBQyxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsS0FBSyxTQUFTLEdBQUcsR0FBRztBQUN4RixTQUFLO0FBQUEsR0FBc0MsSUFBSSxnQkFBZ0IsS0FBSyxRQUFRLFFBQVEsR0FBRyxDQUFDLElBQUk7QUFBQSxFQUNoRztBQUNBLFNBQU8saUJBQWlCLElBQUk7QUFDaEM7QUFFQSxTQUFTLGdCQUFnQixPQUFPO0FBQzVCLFNBQU8sT0FBTyxVQUFVLFlBQWEsU0FBUyxPQUFPLFVBQVU7QUFDbkU7QUFDQSxTQUFTLFlBQVksTUFBTTtBQUN2QixTQUFPLE9BQU8sU0FBUyxZQUFZLE9BQU8sU0FBUztBQUN2RDtBQUVBLE1BQU0sMEJBQTBCLE9BQVEsT0FBeUMsdUJBQXVCLEVBQUU7QUFLMUcsSUFBSTtBQUFBLENBQ0gsU0FBVU0sd0JBQXVCO0FBSzlCLEVBQUFBLHVCQUFzQkEsdUJBQXNCLFNBQVMsSUFBSSxDQUFDLElBQUk7QUFLOUQsRUFBQUEsdUJBQXNCQSx1QkFBc0IsV0FBVyxJQUFJLENBQUMsSUFBSTtBQUtoRSxFQUFBQSx1QkFBc0JBLHVCQUFzQixZQUFZLElBQUksRUFBRSxJQUFJO0FBQ3RFLEdBQUcsMEJBQTBCLHdCQUF3QixDQUFDLEVBQUU7QUFFeEQsTUFBTSxvQkFBb0I7QUFBQSxFQUN0QjtBQUFBLElBQUM7QUFBQTtBQUFBLEVBQW9DLEVBQUUsRUFBRSxVQUFBTixXQUFVLGdCQUFnQixHQUFHO0FBQ2xFLFdBQU87QUFBQSxHQUFrQixLQUFLLFVBQVVBLFNBQVEsQ0FBQyxHQUFHLGtCQUM5Qyx1QkFBdUIsS0FBSyxVQUFVLGVBQWUsSUFDckQsRUFBRTtBQUFBLEVBQ1o7QUFBQSxFQUNBO0FBQUEsSUFBQztBQUFBO0FBQUEsRUFBNEMsRUFBRSxFQUFFLE1BQU0sR0FBSSxHQUFHO0FBQzFELFdBQU8sb0JBQW9CLEtBQUssUUFBUSxTQUFTLGVBQWUsRUFBRSxDQUFDO0FBQUEsRUFDdkU7QUFBQSxFQUNBO0FBQUEsSUFBQztBQUFBO0FBQUEsRUFBcUMsRUFBRSxFQUFFLE1BQU0sR0FBRyxHQUFHO0FBQ2xELFdBQU8sNEJBQTRCLEtBQUssUUFBUSxTQUFTLEdBQUcsUUFBUTtBQUFBLEVBQ3hFO0FBQUEsRUFDQTtBQUFBLElBQUM7QUFBQTtBQUFBLEVBQXVDLEVBQUUsRUFBRSxNQUFNLEdBQUcsR0FBRztBQUNwRCxXQUFPLDhCQUE4QixLQUFLLFFBQVEsU0FBUyxHQUFHLFFBQVE7QUFBQSxFQUMxRTtBQUFBLEVBQ0E7QUFBQSxJQUFDO0FBQUE7QUFBQSxFQUF5QyxFQUFFLEVBQUUsTUFBTSxHQUFHLEdBQUc7QUFDdEQsV0FBTyxzREFBc0QsS0FBSyxRQUFRO0FBQUEsRUFDOUU7QUFDSjtBQU9BLFNBQVMsa0JBQWtCLE1BQU0sUUFBUTtBQUVyQyxNQUFLLE1BQWlEO0FBQ2xELFdBQU8sT0FBTyxJQUFJLE1BQU0sa0JBQWtCLElBQUksRUFBRSxNQUFNLENBQUMsR0FBRztBQUFBLE1BQ3REO0FBQUEsTUFDQSxDQUFDLHVCQUF1QixHQUFHO0FBQUEsSUFDL0IsR0FBRyxNQUFNO0FBQUEsRUFDYixPQUNLO0FBQ0QsV0FBTyxPQUFPLElBQUksTUFBTSxHQUFHO0FBQUEsTUFDdkI7QUFBQSxNQUNBLENBQUMsdUJBQXVCLEdBQUc7QUFBQSxJQUMvQixHQUFHLE1BQU07QUFBQSxFQUNiO0FBQ0o7QUFDQSxTQUFTLG9CQUFvQixPQUFPLE1BQU07QUFDdEMsU0FBUSxpQkFBaUIsU0FDckIsMkJBQTJCLFVBQzFCLFFBQVEsUUFBUSxDQUFDLEVBQUUsTUFBTSxPQUFPO0FBQ3pDO0FBQ0EsTUFBTSxrQkFBa0IsQ0FBQyxVQUFVLFNBQVMsTUFBTTtBQUNsRCxTQUFTLGVBQWUsSUFBSTtBQUN4QixNQUFJLE9BQU8sT0FBTztBQUNkLFdBQU87QUFDWCxNQUFJLEdBQUcsUUFBUTtBQUNYLFdBQU8sR0FBRztBQUNkLFFBQU1BLFlBQVcsQ0FBQztBQUNsQixhQUFXLE9BQU8saUJBQWlCO0FBQy9CLFFBQUksT0FBTztBQUNQLE1BQUFBLFVBQVMsR0FBRyxJQUFJLEdBQUcsR0FBRztBQUFBLEVBQzlCO0FBQ0EsU0FBTyxLQUFLLFVBQVVBLFdBQVUsTUFBTSxDQUFDO0FBQzNDO0FBR0EsTUFBTSxxQkFBcUI7QUFDM0IsTUFBTSwyQkFBMkI7QUFBQSxFQUM3QixXQUFXO0FBQUEsRUFDWCxRQUFRO0FBQUEsRUFDUixPQUFPO0FBQUEsRUFDUCxLQUFLO0FBQ1Q7QUFFQSxNQUFNLGlCQUFpQjtBQVF2QixTQUFTLGVBQWUsVUFBVSxjQUFjO0FBQzVDLFFBQU0sVUFBVSxPQUFPLENBQUMsR0FBRywwQkFBMEIsWUFBWTtBQUVqRSxRQUFNLFFBQVEsQ0FBQztBQUVmLE1BQUksVUFBVSxRQUFRLFFBQVEsTUFBTTtBQUVwQyxRQUFNLE9BQU8sQ0FBQztBQUNkLGFBQVcsV0FBVyxVQUFVO0FBRTVCLFVBQU0sZ0JBQWdCLFFBQVEsU0FBUyxDQUFDLElBQUk7QUFBQSxNQUFDO0FBQUE7QUFBQSxJQUF1QjtBQUVwRSxRQUFJLFFBQVEsVUFBVSxDQUFDLFFBQVE7QUFDM0IsaUJBQVc7QUFDZixhQUFTLGFBQWEsR0FBRyxhQUFhLFFBQVEsUUFBUSxjQUFjO0FBQ2hFLFlBQU0sUUFBUSxRQUFRLFVBQVU7QUFFaEMsVUFBSSxrQkFBa0IsTUFDakIsUUFBUSxZQUFZLE9BQTBDO0FBQ25FLFVBQUksTUFBTSxTQUFTLEdBQTBCO0FBRXpDLFlBQUksQ0FBQztBQUNELHFCQUFXO0FBQ2YsbUJBQVcsTUFBTSxNQUFNLFFBQVEsZ0JBQWdCLE1BQU07QUFDckQsMkJBQW1CO0FBQUEsTUFDdkIsV0FDUyxNQUFNLFNBQVMsR0FBeUI7QUFDN0MsY0FBTSxFQUFFLE9BQU8sWUFBWSxVQUFVLE9BQU8sSUFBSTtBQUNoRCxhQUFLLEtBQUs7QUFBQSxVQUNOLE1BQU07QUFBQSxVQUNOO0FBQUEsVUFDQTtBQUFBLFFBQ0osQ0FBQztBQUNELGNBQU1PLE1BQUssU0FBUyxTQUFTO0FBRTdCLFlBQUlBLFFBQU8sb0JBQW9CO0FBQzNCLDZCQUFtQjtBQUVuQixjQUFJO0FBQ0EsZ0JBQUksT0FBTyxJQUFJQSxHQUFFLEdBQUc7QUFBQSxVQUN4QixTQUNPLEtBQUs7QUFDUixrQkFBTSxJQUFJLE1BQU0sb0NBQW9DLEtBQUssTUFBTUEsR0FBRSxRQUM3RCxJQUFJLE9BQU87QUFBQSxVQUNuQjtBQUFBLFFBQ0o7QUFFQSxZQUFJLGFBQWEsYUFBYSxPQUFPQSxHQUFFLFdBQVdBLEdBQUUsU0FBUyxJQUFJQSxHQUFFO0FBRW5FLFlBQUksQ0FBQztBQUNEO0FBQUE7QUFBQSxVQUdJLFlBQVksUUFBUSxTQUFTLElBQ3ZCLE9BQU8sVUFBVSxNQUNqQixNQUFNO0FBQ3BCLFlBQUk7QUFDQSx3QkFBYztBQUNsQixtQkFBVztBQUNYLDJCQUFtQjtBQUNuQixZQUFJO0FBQ0EsNkJBQW1CO0FBQ3ZCLFlBQUk7QUFDQSw2QkFBbUI7QUFDdkIsWUFBSUEsUUFBTztBQUNQLDZCQUFtQjtBQUFBLE1BQzNCO0FBQ0Esb0JBQWMsS0FBSyxlQUFlO0FBQUEsSUFDdEM7QUFHQSxVQUFNLEtBQUssYUFBYTtBQUFBLEVBQzVCO0FBRUEsTUFBSSxRQUFRLFVBQVUsUUFBUSxLQUFLO0FBQy9CLFVBQU0sSUFBSSxNQUFNLFNBQVM7QUFDekIsVUFBTSxDQUFDLEVBQUUsTUFBTSxDQUFDLEVBQUUsU0FBUyxDQUFDLEtBQUs7QUFBQSxFQUNyQztBQUVBLE1BQUksQ0FBQyxRQUFRO0FBQ1QsZUFBVztBQUNmLE1BQUksUUFBUTtBQUNSLGVBQVc7QUFBQSxXQUVOLFFBQVEsVUFBVSxDQUFDLFFBQVEsU0FBUyxHQUFHO0FBQzVDLGVBQVc7QUFDZixRQUFNLEtBQUssSUFBSSxPQUFPLFNBQVMsUUFBUSxZQUFZLEtBQUssR0FBRztBQUMzRCxXQUFTLE1BQU0sTUFBTTtBQUNqQixVQUFNLFFBQVEsS0FBSyxNQUFNLEVBQUU7QUFDM0IsVUFBTSxTQUFTLENBQUM7QUFDaEIsUUFBSSxDQUFDO0FBQ0QsYUFBTztBQUNYLGFBQVMsSUFBSSxHQUFHLElBQUksTUFBTSxRQUFRLEtBQUs7QUFDbkMsWUFBTSxRQUFRLE1BQU0sQ0FBQyxLQUFLO0FBQzFCLFlBQU0sTUFBTSxLQUFLLElBQUksQ0FBQztBQUN0QixhQUFPLElBQUksSUFBSSxJQUFJLFNBQVMsSUFBSSxhQUFhLE1BQU0sTUFBTSxHQUFHLElBQUk7QUFBQSxJQUNwRTtBQUNBLFdBQU87QUFBQSxFQUNYO0FBQ0EsV0FBUyxVQUFVLFFBQVE7QUFDdkIsUUFBSSxPQUFPO0FBRVgsUUFBSSx1QkFBdUI7QUFDM0IsZUFBVyxXQUFXLFVBQVU7QUFDNUIsVUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssU0FBUyxHQUFHO0FBQzNDLGdCQUFRO0FBQ1osNkJBQXVCO0FBQ3ZCLGlCQUFXLFNBQVMsU0FBUztBQUN6QixZQUFJLE1BQU0sU0FBUyxHQUEwQjtBQUN6QyxrQkFBUSxNQUFNO0FBQUEsUUFDbEIsV0FDUyxNQUFNLFNBQVMsR0FBeUI7QUFDN0MsZ0JBQU0sRUFBRSxPQUFPLFlBQVksU0FBUyxJQUFJO0FBQ3hDLGdCQUFNLFFBQVEsU0FBUyxTQUFTLE9BQU8sS0FBSyxJQUFJO0FBQ2hELGNBQUksUUFBUSxLQUFLLEtBQUssQ0FBQyxZQUFZO0FBQy9CLGtCQUFNLElBQUksTUFBTSxtQkFBbUIsS0FBSywyREFBMkQ7QUFBQSxVQUN2RztBQUNBLGdCQUFNLE9BQU8sUUFBUSxLQUFLLElBQ3BCLE1BQU0sS0FBSyxHQUFHLElBQ2Q7QUFDTixjQUFJLENBQUMsTUFBTTtBQUNQLGdCQUFJLFVBQVU7QUFFVixrQkFBSSxRQUFRLFNBQVMsR0FBRztBQUVwQixvQkFBSSxLQUFLLFNBQVMsR0FBRztBQUNqQix5QkFBTyxLQUFLLE1BQU0sR0FBRyxFQUFFO0FBQUE7QUFHdkIseUNBQXVCO0FBQUEsY0FDL0I7QUFBQSxZQUNKO0FBRUksb0JBQU0sSUFBSSxNQUFNLDJCQUEyQixLQUFLLEdBQUc7QUFBQSxVQUMzRDtBQUNBLGtCQUFRO0FBQUEsUUFDWjtBQUFBLE1BQ0o7QUFBQSxJQUNKO0FBRUEsV0FBTyxRQUFRO0FBQUEsRUFDbkI7QUFDQSxTQUFPO0FBQUEsSUFDSDtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNKO0FBQ0o7QUFVQSxTQUFTLGtCQUFrQixHQUFHLEdBQUc7QUFDN0IsTUFBSSxJQUFJO0FBQ1IsU0FBTyxJQUFJLEVBQUUsVUFBVSxJQUFJLEVBQUUsUUFBUTtBQUNqQyxVQUFNLE9BQU8sRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO0FBRXZCLFFBQUk7QUFDQSxhQUFPO0FBQ1g7QUFBQSxFQUNKO0FBR0EsTUFBSSxFQUFFLFNBQVMsRUFBRSxRQUFRO0FBQ3JCLFdBQU8sRUFBRSxXQUFXLEtBQUssRUFBRSxDQUFDLE1BQU0sS0FBNEIsS0FDeEQsS0FDQTtBQUFBLEVBQ1YsV0FDUyxFQUFFLFNBQVMsRUFBRSxRQUFRO0FBQzFCLFdBQU8sRUFBRSxXQUFXLEtBQUssRUFBRSxDQUFDLE1BQU0sS0FBNEIsS0FDeEQsSUFDQTtBQUFBLEVBQ1Y7QUFDQSxTQUFPO0FBQ1g7QUFRQSxTQUFTLHVCQUF1QixHQUFHLEdBQUc7QUFDbEMsTUFBSSxJQUFJO0FBQ1IsUUFBTSxTQUFTLEVBQUU7QUFDakIsUUFBTSxTQUFTLEVBQUU7QUFDakIsU0FBTyxJQUFJLE9BQU8sVUFBVSxJQUFJLE9BQU8sUUFBUTtBQUMzQyxVQUFNLE9BQU8sa0JBQWtCLE9BQU8sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDO0FBRW5ELFFBQUk7QUFDQSxhQUFPO0FBQ1g7QUFBQSxFQUNKO0FBQ0EsTUFBSSxLQUFLLElBQUksT0FBTyxTQUFTLE9BQU8sTUFBTSxNQUFNLEdBQUc7QUFDL0MsUUFBSSxvQkFBb0IsTUFBTTtBQUMxQixhQUFPO0FBQ1gsUUFBSSxvQkFBb0IsTUFBTTtBQUMxQixhQUFPO0FBQUEsRUFDZjtBQUVBLFNBQU8sT0FBTyxTQUFTLE9BQU87QUFPbEM7QUFPQSxTQUFTLG9CQUFvQixPQUFPO0FBQ2hDLFFBQU0sT0FBTyxNQUFNLE1BQU0sU0FBUyxDQUFDO0FBQ25DLFNBQU8sTUFBTSxTQUFTLEtBQUssS0FBSyxLQUFLLFNBQVMsQ0FBQyxJQUFJO0FBQ3ZEO0FBRUEsTUFBTSxhQUFhO0FBQUEsRUFDZixNQUFNO0FBQUEsRUFDTixPQUFPO0FBQ1g7QUFDQSxNQUFNLGlCQUFpQjtBQUl2QixTQUFTLGFBQWEsTUFBTTtBQUN4QixNQUFJLENBQUM7QUFDRCxXQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ2QsTUFBSSxTQUFTO0FBQ1QsV0FBTyxDQUFDLENBQUMsVUFBVSxDQUFDO0FBQ3hCLE1BQUksQ0FBQyxLQUFLLFdBQVcsR0FBRyxHQUFHO0FBQ3ZCLFVBQU0sSUFBSSxNQUFPLE9BQ1gseUNBQXlDLElBQUksaUJBQWlCLElBQUksT0FDbEUsaUJBQWlCLElBQUksR0FBRztBQUFBLEVBQ2xDO0FBRUEsV0FBUyxNQUFNLFNBQVM7QUFDcEIsVUFBTSxJQUFJLE1BQU0sUUFBUSxLQUFLLE1BQU0sTUFBTSxNQUFNLE9BQU8sRUFBRTtBQUFBLEVBQzVEO0FBQ0EsTUFBSSxRQUFRO0FBQ1osTUFBSSxnQkFBZ0I7QUFDcEIsUUFBTSxTQUFTLENBQUM7QUFHaEIsTUFBSTtBQUNKLFdBQVMsa0JBQWtCO0FBQ3ZCLFFBQUk7QUFDQSxhQUFPLEtBQUssT0FBTztBQUN2QixjQUFVLENBQUM7QUFBQSxFQUNmO0FBRUEsTUFBSSxJQUFJO0FBRVIsTUFBSTtBQUVKLE1BQUksU0FBUztBQUViLE1BQUksV0FBVztBQUNmLFdBQVMsZ0JBQWdCO0FBQ3JCLFFBQUksQ0FBQztBQUNEO0FBQ0osUUFBSSxVQUFVLEdBQStCO0FBQ3pDLGNBQVEsS0FBSztBQUFBLFFBQ1QsTUFBTTtBQUFBLFFBQ04sT0FBTztBQUFBLE1BQ1gsQ0FBQztBQUFBLElBQ0wsV0FDUyxVQUFVLEtBQ2YsVUFBVSxLQUNWLFVBQVUsR0FBdUM7QUFDakQsVUFBSSxRQUFRLFNBQVMsTUFBTSxTQUFTLE9BQU8sU0FBUztBQUNoRCxjQUFNLHVCQUF1QixNQUFNLDhDQUE4QztBQUNyRixjQUFRLEtBQUs7QUFBQSxRQUNULE1BQU07QUFBQSxRQUNOLE9BQU87QUFBQSxRQUNQLFFBQVE7QUFBQSxRQUNSLFlBQVksU0FBUyxPQUFPLFNBQVM7QUFBQSxRQUNyQyxVQUFVLFNBQVMsT0FBTyxTQUFTO0FBQUEsTUFDdkMsQ0FBQztBQUFBLElBQ0wsT0FDSztBQUNELFlBQU0saUNBQWlDO0FBQUEsSUFDM0M7QUFDQSxhQUFTO0FBQUEsRUFDYjtBQUNBLFdBQVMsa0JBQWtCO0FBQ3ZCLGNBQVU7QUFBQSxFQUNkO0FBQ0EsU0FBTyxJQUFJLEtBQUssUUFBUTtBQUNwQixXQUFPLEtBQUssR0FBRztBQUNmLFFBQUksU0FBUyxRQUFRLFVBQVUsR0FBb0M7QUFDL0Qsc0JBQWdCO0FBQ2hCLGNBQVE7QUFDUjtBQUFBLElBQ0o7QUFDQSxZQUFRLE9BQU87QUFBQSxNQUNYLEtBQUs7QUFDRCxZQUFJLFNBQVMsS0FBSztBQUNkLGNBQUksUUFBUTtBQUNSLDBCQUFjO0FBQUEsVUFDbEI7QUFDQSwwQkFBZ0I7QUFBQSxRQUNwQixXQUNTLFNBQVMsS0FBSztBQUNuQix3QkFBYztBQUNkLGtCQUFRO0FBQUEsUUFDWixPQUNLO0FBQ0QsMEJBQWdCO0FBQUEsUUFDcEI7QUFDQTtBQUFBLE1BQ0osS0FBSztBQUNELHdCQUFnQjtBQUNoQixnQkFBUTtBQUNSO0FBQUEsTUFDSixLQUFLO0FBQ0QsWUFBSSxTQUFTLEtBQUs7QUFDZCxrQkFBUTtBQUFBLFFBQ1osV0FDUyxlQUFlLEtBQUssSUFBSSxHQUFHO0FBQ2hDLDBCQUFnQjtBQUFBLFFBQ3BCLE9BQ0s7QUFDRCx3QkFBYztBQUNkLGtCQUFRO0FBRVIsY0FBSSxTQUFTLE9BQU8sU0FBUyxPQUFPLFNBQVM7QUFDekM7QUFBQSxRQUNSO0FBQ0E7QUFBQSxNQUNKLEtBQUs7QUFNRCxZQUFJLFNBQVMsS0FBSztBQUVkLGNBQUksU0FBUyxTQUFTLFNBQVMsQ0FBQyxLQUFLO0FBQ2pDLHVCQUFXLFNBQVMsTUFBTSxHQUFHLEVBQUUsSUFBSTtBQUFBO0FBRW5DLG9CQUFRO0FBQUEsUUFDaEIsT0FDSztBQUNELHNCQUFZO0FBQUEsUUFDaEI7QUFDQTtBQUFBLE1BQ0osS0FBSztBQUVELHNCQUFjO0FBQ2QsZ0JBQVE7QUFFUixZQUFJLFNBQVMsT0FBTyxTQUFTLE9BQU8sU0FBUztBQUN6QztBQUNKLG1CQUFXO0FBQ1g7QUFBQSxNQUNKO0FBQ0ksY0FBTSxlQUFlO0FBQ3JCO0FBQUEsSUFDUjtBQUFBLEVBQ0o7QUFDQSxNQUFJLFVBQVU7QUFDVixVQUFNLHVDQUF1QyxNQUFNLEdBQUc7QUFDMUQsZ0JBQWM7QUFDZCxrQkFBZ0I7QUFFaEIsU0FBTztBQUNYO0FBRUEsU0FBUyx5QkFBeUIsUUFBUSxRQUFRLFNBQVM7QUFDdkQsUUFBTSxTQUFTLGVBQWUsYUFBYSxPQUFPLElBQUksR0FBRyxPQUFPO0FBRWhFLE1BQUssTUFBd0M7QUFDekMsVUFBTSxlQUFlLG9CQUFJLElBQUk7QUFDN0IsZUFBVyxPQUFPLE9BQU8sTUFBTTtBQUMzQixVQUFJLGFBQWEsSUFBSSxJQUFJLElBQUk7QUFDekIsYUFBSyxzQ0FBc0MsSUFBSSxJQUFJLGVBQWUsT0FBTyxJQUFJLDREQUE0RDtBQUM3SSxtQkFBYSxJQUFJLElBQUksSUFBSTtBQUFBLElBQzdCO0FBQUEsRUFDSjtBQUNBLFFBQU0sVUFBVSxPQUFPLFFBQVE7QUFBQSxJQUMzQjtBQUFBLElBQ0E7QUFBQTtBQUFBLElBRUEsVUFBVSxDQUFDO0FBQUEsSUFDWCxPQUFPLENBQUM7QUFBQSxFQUNaLENBQUM7QUFDRCxNQUFJLFFBQVE7QUFJUixRQUFJLENBQUMsUUFBUSxPQUFPLFlBQVksQ0FBQyxPQUFPLE9BQU87QUFDM0MsYUFBTyxTQUFTLEtBQUssT0FBTztBQUFBLEVBQ3BDO0FBQ0EsU0FBTztBQUNYO0FBU0EsU0FBUyxvQkFBb0IsUUFBUSxlQUFlO0FBRWhELFFBQU0sV0FBVyxDQUFDO0FBQ2xCLFFBQU0sYUFBYSxvQkFBSSxJQUFJO0FBQzNCLGtCQUFnQixhQUFhLEVBQUUsUUFBUSxPQUFPLEtBQUssTUFBTSxXQUFXLE1BQU0sR0FBRyxhQUFhO0FBQzFGLFdBQVMsaUJBQWlCLE1BQU07QUFDNUIsV0FBTyxXQUFXLElBQUksSUFBSTtBQUFBLEVBQzlCO0FBQ0EsV0FBUyxTQUFTLFFBQVEsUUFBUSxnQkFBZ0I7QUFFOUMsVUFBTSxZQUFZLENBQUM7QUFDbkIsVUFBTSx1QkFBdUIscUJBQXFCLE1BQU07QUFDeEQsUUFBSyxNQUF3QztBQUN6Qyx5Q0FBbUMsc0JBQXNCLE1BQU07QUFBQSxJQUNuRTtBQUVBLHlCQUFxQixVQUFVLGtCQUFrQixlQUFlO0FBQ2hFLFVBQU0sVUFBVSxhQUFhLGVBQWUsTUFBTTtBQUVsRCxVQUFNLG9CQUFvQixDQUFDLG9CQUFvQjtBQUMvQyxRQUFJLFdBQVcsUUFBUTtBQUNuQixZQUFNLFVBQVUsT0FBTyxPQUFPLFVBQVUsV0FBVyxDQUFDLE9BQU8sS0FBSyxJQUFJLE9BQU87QUFDM0UsaUJBQVcsU0FBUyxTQUFTO0FBQ3pCLDBCQUFrQjtBQUFBO0FBQUE7QUFBQSxVQUdsQixxQkFBcUIsT0FBTyxDQUFDLEdBQUcsc0JBQXNCO0FBQUE7QUFBQTtBQUFBLFlBR2xELFlBQVksaUJBQ04sZUFBZSxPQUFPLGFBQ3RCLHFCQUFxQjtBQUFBLFlBQzNCLE1BQU07QUFBQTtBQUFBLFlBRU4sU0FBUyxpQkFDSCxlQUFlLFNBQ2Y7QUFBQTtBQUFBO0FBQUEsVUFHVixDQUFDLENBQUM7QUFBQSxRQUFDO0FBQUEsTUFDUDtBQUFBLElBQ0o7QUFDQSxRQUFJO0FBQ0osUUFBSTtBQUNKLGVBQVcsb0JBQW9CLG1CQUFtQjtBQUM5QyxZQUFNLEVBQUUsS0FBSyxJQUFJO0FBSWpCLFVBQUksVUFBVSxLQUFLLENBQUMsTUFBTSxLQUFLO0FBQzNCLGNBQU0sYUFBYSxPQUFPLE9BQU87QUFDakMsY0FBTSxrQkFBa0IsV0FBVyxXQUFXLFNBQVMsQ0FBQyxNQUFNLE1BQU0sS0FBSztBQUN6RSx5QkFBaUIsT0FDYixPQUFPLE9BQU8sUUFBUSxRQUFRLGtCQUFrQjtBQUFBLE1BQ3hEO0FBQ0EsVUFBK0MsaUJBQWlCLFNBQVMsS0FBSztBQUMxRSxjQUFNLElBQUksTUFBTSx5S0FDNkU7QUFBQSxNQUNqRztBQUVBLGdCQUFVLHlCQUF5QixrQkFBa0IsUUFBUSxPQUFPO0FBQ3BFLFVBQStDLFVBQVUsS0FBSyxDQUFDLE1BQU07QUFDakUseUNBQWlDLFNBQVMsTUFBTTtBQUdwRCxVQUFJLGdCQUFnQjtBQUNoQix1QkFBZSxNQUFNLEtBQUssT0FBTztBQUNqQyxZQUFLLE1BQXdDO0FBQ3pDLDBCQUFnQixnQkFBZ0IsT0FBTztBQUFBLFFBQzNDO0FBQUEsTUFDSixPQUNLO0FBRUQsMEJBQWtCLG1CQUFtQjtBQUNyQyxZQUFJLG9CQUFvQjtBQUNwQiwwQkFBZ0IsTUFBTSxLQUFLLE9BQU87QUFHdEMsWUFBSSxhQUFhLE9BQU8sUUFBUSxDQUFDLGNBQWMsT0FBTyxHQUFHO0FBQ3JELGNBQUssTUFBd0M7QUFDekMsb0NBQXdCLFFBQVEsTUFBTTtBQUFBLFVBQzFDO0FBQ0Esc0JBQVksT0FBTyxJQUFJO0FBQUEsUUFDM0I7QUFBQSxNQUNKO0FBR0EsVUFBSSxZQUFZLE9BQU8sR0FBRztBQUN0QixzQkFBYyxPQUFPO0FBQUEsTUFDekI7QUFDQSxVQUFJLHFCQUFxQixVQUFVO0FBQy9CLGNBQU0sV0FBVyxxQkFBcUI7QUFDdEMsaUJBQVMsSUFBSSxHQUFHLElBQUksU0FBUyxRQUFRLEtBQUs7QUFDdEMsbUJBQVMsU0FBUyxDQUFDLEdBQUcsU0FBUyxrQkFBa0IsZUFBZSxTQUFTLENBQUMsQ0FBQztBQUFBLFFBQy9FO0FBQUEsTUFDSjtBQUdBLHVCQUFpQixrQkFBa0I7QUFBQSxJQUt2QztBQUNBLFdBQU8sa0JBQ0QsTUFBTTtBQUVKLGtCQUFZLGVBQWU7QUFBQSxJQUMvQixJQUNFO0FBQUEsRUFDVjtBQUNBLFdBQVMsWUFBWSxZQUFZO0FBQzdCLFFBQUksWUFBWSxVQUFVLEdBQUc7QUFDekIsWUFBTSxVQUFVLFdBQVcsSUFBSSxVQUFVO0FBQ3pDLFVBQUksU0FBUztBQUNULG1CQUFXLE9BQU8sVUFBVTtBQUM1QixpQkFBUyxPQUFPLFNBQVMsUUFBUSxPQUFPLEdBQUcsQ0FBQztBQUM1QyxnQkFBUSxTQUFTLFFBQVEsV0FBVztBQUNwQyxnQkFBUSxNQUFNLFFBQVEsV0FBVztBQUFBLE1BQ3JDO0FBQUEsSUFDSixPQUNLO0FBQ0QsWUFBTSxRQUFRLFNBQVMsUUFBUSxVQUFVO0FBQ3pDLFVBQUksUUFBUSxJQUFJO0FBQ1osaUJBQVMsT0FBTyxPQUFPLENBQUM7QUFDeEIsWUFBSSxXQUFXLE9BQU87QUFDbEIscUJBQVcsT0FBTyxXQUFXLE9BQU8sSUFBSTtBQUM1QyxtQkFBVyxTQUFTLFFBQVEsV0FBVztBQUN2QyxtQkFBVyxNQUFNLFFBQVEsV0FBVztBQUFBLE1BQ3hDO0FBQUEsSUFDSjtBQUFBLEVBQ0o7QUFDQSxXQUFTLFlBQVk7QUFDakIsV0FBTztBQUFBLEVBQ1g7QUFDQSxXQUFTLGNBQWMsU0FBUztBQUM1QixVQUFNLFFBQVEsbUJBQW1CLFNBQVMsUUFBUTtBQUNsRCxhQUFTLE9BQU8sT0FBTyxHQUFHLE9BQU87QUFFakMsUUFBSSxRQUFRLE9BQU8sUUFBUSxDQUFDLGNBQWMsT0FBTztBQUM3QyxpQkFBVyxJQUFJLFFBQVEsT0FBTyxNQUFNLE9BQU87QUFBQSxFQUNuRDtBQUNBLFdBQVMsUUFBUVAsV0FBVSxpQkFBaUI7QUFDeEMsUUFBSTtBQUNKLFFBQUksU0FBUyxDQUFDO0FBQ2QsUUFBSTtBQUNKLFFBQUk7QUFDSixRQUFJLFVBQVVBLGFBQVlBLFVBQVMsTUFBTTtBQUNyQyxnQkFBVSxXQUFXLElBQUlBLFVBQVMsSUFBSTtBQUN0QyxVQUFJLENBQUM7QUFDRCxjQUFNLGtCQUFrQixHQUFzQztBQUFBLFVBQzFELFVBQUFBO0FBQUEsUUFDSixDQUFDO0FBRUwsVUFBSyxNQUF3QztBQUN6QyxjQUFNLGdCQUFnQixPQUFPLEtBQUtBLFVBQVMsVUFBVSxDQUFDLENBQUMsRUFBRSxPQUFPLGVBQWEsQ0FBQyxRQUFRLEtBQUssS0FBSyxPQUFLLEVBQUUsU0FBUyxTQUFTLENBQUM7QUFDMUgsWUFBSSxjQUFjLFFBQVE7QUFDdEIsZUFBSywrQkFBK0IsY0FBYyxLQUFLLE1BQU0sQ0FBQyxnSUFBZ0k7QUFBQSxRQUNsTTtBQUFBLE1BQ0o7QUFDQSxhQUFPLFFBQVEsT0FBTztBQUN0QixlQUFTO0FBQUE7QUFBQSxRQUVUO0FBQUEsVUFBbUIsZ0JBQWdCO0FBQUE7QUFBQTtBQUFBLFVBR25DLFFBQVEsS0FDSCxPQUFPLE9BQUssQ0FBQyxFQUFFLFFBQVEsRUFDdkIsT0FBTyxRQUFRLFNBQVMsUUFBUSxPQUFPLEtBQUssT0FBTyxPQUFLLEVBQUUsUUFBUSxJQUFJLENBQUMsQ0FBQyxFQUN4RSxJQUFJLE9BQUssRUFBRSxJQUFJO0FBQUEsUUFBQztBQUFBO0FBQUE7QUFBQSxRQUdyQkEsVUFBUyxVQUNMLG1CQUFtQkEsVUFBUyxRQUFRLFFBQVEsS0FBSyxJQUFJLE9BQUssRUFBRSxJQUFJLENBQUM7QUFBQSxNQUFDO0FBRXRFLGFBQU8sUUFBUSxVQUFVLE1BQU07QUFBQSxJQUNuQyxXQUNTQSxVQUFTLFFBQVEsTUFBTTtBQUc1QixhQUFPQSxVQUFTO0FBQ2hCLFVBQStDLENBQUMsS0FBSyxXQUFXLEdBQUcsR0FBRztBQUNsRSxhQUFLLDJEQUEyRCxJQUFJLG9EQUFvRCxJQUFJLHdIQUF3SDtBQUFBLE1BQ3hQO0FBQ0EsZ0JBQVUsU0FBUyxLQUFLLE9BQUssRUFBRSxHQUFHLEtBQUssSUFBSSxDQUFDO0FBRTVDLFVBQUksU0FBUztBQUVULGlCQUFTLFFBQVEsTUFBTSxJQUFJO0FBQzNCLGVBQU8sUUFBUSxPQUFPO0FBQUEsTUFDMUI7QUFBQSxJQUVKLE9BQ0s7QUFFRCxnQkFBVSxnQkFBZ0IsT0FDcEIsV0FBVyxJQUFJLGdCQUFnQixJQUFJLElBQ25DLFNBQVMsS0FBSyxPQUFLLEVBQUUsR0FBRyxLQUFLLGdCQUFnQixJQUFJLENBQUM7QUFDeEQsVUFBSSxDQUFDO0FBQ0QsY0FBTSxrQkFBa0IsR0FBc0M7QUFBQSxVQUMxRCxVQUFBQTtBQUFBLFVBQ0E7QUFBQSxRQUNKLENBQUM7QUFDTCxhQUFPLFFBQVEsT0FBTztBQUd0QixlQUFTLE9BQU8sQ0FBQyxHQUFHLGdCQUFnQixRQUFRQSxVQUFTLE1BQU07QUFDM0QsYUFBTyxRQUFRLFVBQVUsTUFBTTtBQUFBLElBQ25DO0FBQ0EsVUFBTSxVQUFVLENBQUM7QUFDakIsUUFBSSxnQkFBZ0I7QUFDcEIsV0FBTyxlQUFlO0FBRWxCLGNBQVEsUUFBUSxjQUFjLE1BQU07QUFDcEMsc0JBQWdCLGNBQWM7QUFBQSxJQUNsQztBQUNBLFdBQU87QUFBQSxNQUNIO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQSxNQUFNLGdCQUFnQixPQUFPO0FBQUEsSUFDakM7QUFBQSxFQUNKO0FBRUEsU0FBTyxRQUFRLFdBQVMsU0FBUyxLQUFLLENBQUM7QUFDdkMsV0FBUyxjQUFjO0FBQ25CLGFBQVMsU0FBUztBQUNsQixlQUFXLE1BQU07QUFBQSxFQUNyQjtBQUNBLFNBQU87QUFBQSxJQUNIO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNKO0FBQ0o7QUFDQSxTQUFTLG1CQUFtQixRQUFRLE1BQU07QUFDdEMsUUFBTSxZQUFZLENBQUM7QUFDbkIsYUFBVyxPQUFPLE1BQU07QUFDcEIsUUFBSSxPQUFPO0FBQ1AsZ0JBQVUsR0FBRyxJQUFJLE9BQU8sR0FBRztBQUFBLEVBQ25DO0FBQ0EsU0FBTztBQUNYO0FBT0EsU0FBUyxxQkFBcUIsUUFBUTtBQUNsQyxRQUFNLGFBQWE7QUFBQSxJQUNmLE1BQU0sT0FBTztBQUFBLElBQ2IsVUFBVSxPQUFPO0FBQUEsSUFDakIsTUFBTSxPQUFPO0FBQUEsSUFDYixNQUFNLE9BQU8sUUFBUSxDQUFDO0FBQUEsSUFDdEIsU0FBUyxPQUFPO0FBQUEsSUFDaEIsYUFBYSxPQUFPO0FBQUEsSUFDcEIsT0FBTyxxQkFBcUIsTUFBTTtBQUFBLElBQ2xDLFVBQVUsT0FBTyxZQUFZLENBQUM7QUFBQSxJQUM5QixXQUFXLENBQUM7QUFBQSxJQUNaLGFBQWEsb0JBQUksSUFBSTtBQUFBLElBQ3JCLGNBQWMsb0JBQUksSUFBSTtBQUFBLElBQ3RCLGdCQUFnQixDQUFDO0FBQUE7QUFBQTtBQUFBLElBR2pCLFlBQVksZ0JBQWdCLFNBQ3RCLE9BQU8sY0FBYyxPQUNyQixPQUFPLGFBQWEsRUFBRSxTQUFTLE9BQU8sVUFBVTtBQUFBLEVBQzFEO0FBSUEsU0FBTyxlQUFlLFlBQVksUUFBUTtBQUFBLElBQ3RDLE9BQU8sQ0FBQztBQUFBLEVBQ1osQ0FBQztBQUNELFNBQU87QUFDWDtBQU1BLFNBQVMscUJBQXFCLFFBQVE7QUFDbEMsUUFBTSxjQUFjLENBQUM7QUFFckIsUUFBTSxRQUFRLE9BQU8sU0FBUztBQUM5QixNQUFJLGVBQWUsUUFBUTtBQUN2QixnQkFBWSxVQUFVO0FBQUEsRUFDMUIsT0FDSztBQUdELGVBQVcsUUFBUSxPQUFPO0FBQ3RCLGtCQUFZLElBQUksSUFBSSxPQUFPLFVBQVUsV0FBVyxNQUFNLElBQUksSUFBSTtBQUFBLEVBQ3RFO0FBQ0EsU0FBTztBQUNYO0FBS0EsU0FBUyxjQUFjLFFBQVE7QUFDM0IsU0FBTyxRQUFRO0FBQ1gsUUFBSSxPQUFPLE9BQU87QUFDZCxhQUFPO0FBQ1gsYUFBUyxPQUFPO0FBQUEsRUFDcEI7QUFDQSxTQUFPO0FBQ1g7QUFNQSxTQUFTLGdCQUFnQixTQUFTO0FBQzlCLFNBQU8sUUFBUSxPQUFPLENBQUMsTUFBTSxXQUFXLE9BQU8sTUFBTSxPQUFPLElBQUksR0FBRyxDQUFDLENBQUM7QUFDekU7QUFDQSxTQUFTLGFBQWEsVUFBVSxnQkFBZ0I7QUFDNUMsUUFBTSxVQUFVLENBQUM7QUFDakIsYUFBVyxPQUFPLFVBQVU7QUFDeEIsWUFBUSxHQUFHLElBQUksT0FBTyxpQkFBaUIsZUFBZSxHQUFHLElBQUksU0FBUyxHQUFHO0FBQUEsRUFDN0U7QUFDQSxTQUFPO0FBQ1g7QUFDQSxTQUFTLFlBQVksR0FBRyxHQUFHO0FBQ3ZCLFNBQVEsRUFBRSxTQUFTLEVBQUUsUUFDakIsRUFBRSxhQUFhLEVBQUUsWUFDakIsRUFBRSxlQUFlLEVBQUU7QUFDM0I7QUFPQSxTQUFTLGdCQUFnQixHQUFHLEdBQUc7QUFDM0IsYUFBVyxPQUFPLEVBQUUsTUFBTTtBQUN0QixRQUFJLENBQUMsSUFBSSxZQUFZLENBQUMsRUFBRSxLQUFLLEtBQUssWUFBWSxLQUFLLE1BQU0sR0FBRyxDQUFDO0FBQ3pELGFBQU8sS0FBSyxVQUFVLEVBQUUsT0FBTyxJQUFJLCtCQUErQixFQUFFLE9BQU8sSUFBSSwyQ0FBMkMsSUFBSSxJQUFJLEdBQUc7QUFBQSxFQUM3STtBQUNBLGFBQVcsT0FBTyxFQUFFLE1BQU07QUFDdEIsUUFBSSxDQUFDLElBQUksWUFBWSxDQUFDLEVBQUUsS0FBSyxLQUFLLFlBQVksS0FBSyxNQUFNLEdBQUcsQ0FBQztBQUN6RCxhQUFPLEtBQUssVUFBVSxFQUFFLE9BQU8sSUFBSSwrQkFBK0IsRUFBRSxPQUFPLElBQUksMkNBQTJDLElBQUksSUFBSSxHQUFHO0FBQUEsRUFDN0k7QUFDSjtBQU9BLFNBQVMsbUNBQW1DLHNCQUFzQixRQUFRO0FBQ3RFLE1BQUksVUFDQSxPQUFPLE9BQU8sUUFDZCxDQUFDLHFCQUFxQixRQUN0QixDQUFDLHFCQUFxQixNQUFNO0FBQzVCLFNBQUssb0JBQW9CLE9BQU8sT0FBTyxPQUFPLElBQUksQ0FBQyw0T0FBNE87QUFBQSxFQUNuUztBQUNKO0FBQ0EsU0FBUyx3QkFBd0IsUUFBUSxRQUFRO0FBQzdDLFdBQVMsV0FBVyxRQUFRLFVBQVUsV0FBVyxTQUFTLFFBQVE7QUFDOUQsUUFBSSxTQUFTLE9BQU8sU0FBUyxPQUFPLE1BQU07QUFDdEMsWUFBTSxJQUFJLE1BQU0sa0JBQWtCLE9BQU8sT0FBTyxJQUFJLENBQUMseUJBQXlCLFdBQVcsV0FBVyxVQUFVLFlBQVksd0hBQXdIO0FBQUEsSUFDdFA7QUFBQSxFQUNKO0FBQ0o7QUFDQSxTQUFTLGlDQUFpQyxRQUFRLFFBQVE7QUFDdEQsYUFBVyxPQUFPLE9BQU8sTUFBTTtBQUMzQixRQUFJLENBQUMsT0FBTyxLQUFLLEtBQUssWUFBWSxLQUFLLE1BQU0sR0FBRyxDQUFDO0FBQzdDLGFBQU8sS0FBSyxrQkFBa0IsT0FBTyxPQUFPLElBQUksMkNBQTJDLElBQUksSUFBSSxvQkFBb0IsT0FBTyxPQUFPLElBQUksSUFBSTtBQUFBLEVBQ3JKO0FBQ0o7QUFVQSxTQUFTLG1CQUFtQixTQUFTLFVBQVU7QUFFM0MsTUFBSSxRQUFRO0FBQ1osTUFBSSxRQUFRLFNBQVM7QUFDckIsU0FBTyxVQUFVLE9BQU87QUFDcEIsVUFBTSxNQUFPLFFBQVEsU0FBVTtBQUMvQixVQUFNLFlBQVksdUJBQXVCLFNBQVMsU0FBUyxHQUFHLENBQUM7QUFDL0QsUUFBSSxZQUFZLEdBQUc7QUFDZixjQUFRO0FBQUEsSUFDWixPQUNLO0FBQ0QsY0FBUSxNQUFNO0FBQUEsSUFDbEI7QUFBQSxFQUNKO0FBRUEsUUFBTSxvQkFBb0IscUJBQXFCLE9BQU87QUFDdEQsTUFBSSxtQkFBbUI7QUFDbkIsWUFBUSxTQUFTLFlBQVksbUJBQW1CLFFBQVEsQ0FBQztBQUN6RCxRQUErQyxRQUFRLEdBQUc7QUFFdEQsV0FBSywyQkFBMkIsa0JBQWtCLE9BQU8sSUFBSSxpQkFBaUIsUUFBUSxPQUFPLElBQUksR0FBRztBQUFBLElBQ3hHO0FBQUEsRUFDSjtBQUNBLFNBQU87QUFDWDtBQUNBLFNBQVMscUJBQXFCLFNBQVM7QUFDbkMsTUFBSSxXQUFXO0FBQ2YsU0FBUSxXQUFXLFNBQVMsUUFBUztBQUNqQyxRQUFJLFlBQVksUUFBUSxLQUNwQix1QkFBdUIsU0FBUyxRQUFRLE1BQU0sR0FBRztBQUNqRCxhQUFPO0FBQUEsSUFDWDtBQUFBLEVBQ0o7QUFDQTtBQUNKO0FBUUEsU0FBUyxZQUFZLEVBQUUsT0FBTyxHQUFHO0FBQzdCLFNBQU8sQ0FBQyxFQUFFLE9BQU8sUUFDWixPQUFPLGNBQWMsT0FBTyxLQUFLLE9BQU8sVUFBVSxFQUFFLFVBQ3JELE9BQU87QUFDZjtBQVdBLFNBQVMsV0FBVyxRQUFRO0FBQ3hCLFFBQU0sUUFBUSxDQUFDO0FBR2YsTUFBSSxXQUFXLE1BQU0sV0FBVztBQUM1QixXQUFPO0FBQ1gsUUFBTSxlQUFlLE9BQU8sQ0FBQyxNQUFNO0FBQ25DLFFBQU0sZ0JBQWdCLGVBQWUsT0FBTyxNQUFNLENBQUMsSUFBSSxRQUFRLE1BQU0sR0FBRztBQUN4RSxXQUFTLElBQUksR0FBRyxJQUFJLGFBQWEsUUFBUSxFQUFFLEdBQUc7QUFFMUMsVUFBTSxjQUFjLGFBQWEsQ0FBQyxFQUFFLFFBQVEsU0FBUyxHQUFHO0FBRXhELFVBQU0sUUFBUSxZQUFZLFFBQVEsR0FBRztBQUNyQyxVQUFNLE1BQU0sT0FBTyxRQUFRLElBQUksY0FBYyxZQUFZLE1BQU0sR0FBRyxLQUFLLENBQUM7QUFDeEUsVUFBTSxRQUFRLFFBQVEsSUFBSSxPQUFPLE9BQU8sWUFBWSxNQUFNLFFBQVEsQ0FBQyxDQUFDO0FBQ3BFLFFBQUksT0FBTyxPQUFPO0FBRWQsVUFBSSxlQUFlLE1BQU0sR0FBRztBQUM1QixVQUFJLENBQUMsUUFBUSxZQUFZLEdBQUc7QUFDeEIsdUJBQWUsTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZO0FBQUEsTUFDN0M7QUFDQSxtQkFBYSxLQUFLLEtBQUs7QUFBQSxJQUMzQixPQUNLO0FBQ0QsWUFBTSxHQUFHLElBQUk7QUFBQSxJQUNqQjtBQUFBLEVBQ0o7QUFDQSxTQUFPO0FBQ1g7QUFVQSxTQUFTLGVBQWUsT0FBTztBQUMzQixNQUFJLFNBQVM7QUFDYixXQUFTLE9BQU8sT0FBTztBQUNuQixVQUFNLFFBQVEsTUFBTSxHQUFHO0FBQ3ZCLFVBQU0sZUFBZSxHQUFHO0FBQ3hCLFFBQUksU0FBUyxNQUFNO0FBRWYsVUFBSSxVQUFVLFFBQVc7QUFDckIsbUJBQVcsT0FBTyxTQUFTLE1BQU0sTUFBTTtBQUFBLE1BQzNDO0FBQ0E7QUFBQSxJQUNKO0FBRUEsVUFBTSxTQUFTLFFBQVEsS0FBSyxJQUN0QixNQUFNLElBQUksT0FBSyxLQUFLLGlCQUFpQixDQUFDLENBQUMsSUFDdkMsQ0FBQyxTQUFTLGlCQUFpQixLQUFLLENBQUM7QUFDdkMsV0FBTyxRQUFRLENBQUFRLFdBQVM7QUFHcEIsVUFBSUEsV0FBVSxRQUFXO0FBRXJCLG1CQUFXLE9BQU8sU0FBUyxNQUFNLE1BQU07QUFDdkMsWUFBSUEsVUFBUztBQUNULG9CQUFVLE1BQU1BO0FBQUEsTUFDeEI7QUFBQSxJQUNKLENBQUM7QUFBQSxFQUNMO0FBQ0EsU0FBTztBQUNYO0FBU0EsU0FBUyxlQUFlLE9BQU87QUFDM0IsUUFBTSxrQkFBa0IsQ0FBQztBQUN6QixhQUFXLE9BQU8sT0FBTztBQUNyQixVQUFNLFFBQVEsTUFBTSxHQUFHO0FBQ3ZCLFFBQUksVUFBVSxRQUFXO0FBQ3JCLHNCQUFnQixHQUFHLElBQUksUUFBUSxLQUFLLElBQzlCLE1BQU0sSUFBSSxPQUFNLEtBQUssT0FBTyxPQUFPLEtBQUssQ0FBRSxJQUMxQyxTQUFTLE9BQ0wsUUFDQSxLQUFLO0FBQUEsSUFDbkI7QUFBQSxFQUNKO0FBQ0EsU0FBTztBQUNYO0FBU0EsTUFBTSxrQkFBa0IsT0FBUSxPQUF5QyxpQ0FBaUMsRUFBRTtBQU81RyxNQUFNLGVBQWUsT0FBUSxPQUF5QyxzQkFBc0IsRUFBRTtBQU85RixNQUFNLFlBQVksT0FBUSxPQUF5QyxXQUFXLEVBQUU7QUFPaEYsTUFBTSxtQkFBbUIsT0FBUSxPQUF5QyxtQkFBbUIsRUFBRTtBQU8vRixNQUFNLHdCQUF3QixPQUFRLE9BQXlDLHlCQUF5QixFQUFFO0FBSzFHLFNBQVMsZUFBZTtBQUNwQixNQUFJLFdBQVcsQ0FBQztBQUNoQixXQUFTLElBQUksU0FBUztBQUNsQixhQUFTLEtBQUssT0FBTztBQUNyQixXQUFPLE1BQU07QUFDVCxZQUFNLElBQUksU0FBUyxRQUFRLE9BQU87QUFDbEMsVUFBSSxJQUFJO0FBQ0osaUJBQVMsT0FBTyxHQUFHLENBQUM7QUFBQSxJQUM1QjtBQUFBLEVBQ0o7QUFDQSxXQUFTLFFBQVE7QUFDYixlQUFXLENBQUM7QUFBQSxFQUNoQjtBQUNBLFNBQU87QUFBQSxJQUNIO0FBQUEsSUFDQSxNQUFNLE1BQU0sU0FBUyxNQUFNO0FBQUEsSUFDM0I7QUFBQSxFQUNKO0FBQ0o7QUFFQSxTQUFTLGNBQWMsUUFBUSxNQUFNLE9BQU87QUFDeEMsUUFBTSxpQkFBaUIsTUFBTTtBQUN6QixXQUFPLElBQUksRUFBRSxPQUFPLEtBQUs7QUFBQSxFQUM3QjtBQUNBLGNBQVksY0FBYztBQUMxQixnQkFBYyxjQUFjO0FBQzVCLGNBQVksTUFBTTtBQUNkLFdBQU8sSUFBSSxFQUFFLElBQUksS0FBSztBQUFBLEVBQzFCLENBQUM7QUFDRCxTQUFPLElBQUksRUFBRSxJQUFJLEtBQUs7QUFDMUI7QUFRQSxTQUFTLG1CQUFtQixZQUFZO0FBQ3BDLE1BQStDLENBQUMsbUJBQW1CLEdBQUc7QUFDbEUsU0FBSyx3R0FBd0c7QUFDN0c7QUFBQSxFQUNKO0FBQ0EsUUFBTSxlQUFlO0FBQUEsSUFBTztBQUFBO0FBQUEsSUFFNUIsQ0FBQztBQUFBLEVBQUMsRUFBRTtBQUNKLE1BQUksQ0FBQyxjQUFjO0FBQ2YsSUFDSSxLQUFLLDBMQUEwTDtBQUNuTTtBQUFBLEVBQ0o7QUFDQSxnQkFBYyxjQUFjLGVBQWUsVUFBVTtBQUN6RDtBQVFBLFNBQVMsb0JBQW9CLGFBQWE7QUFDdEMsTUFBK0MsQ0FBQyxtQkFBbUIsR0FBRztBQUNsRSxTQUFLLHlHQUF5RztBQUM5RztBQUFBLEVBQ0o7QUFDQSxRQUFNLGVBQWU7QUFBQSxJQUFPO0FBQUE7QUFBQSxJQUU1QixDQUFDO0FBQUEsRUFBQyxFQUFFO0FBQ0osTUFBSSxDQUFDLGNBQWM7QUFDZixJQUNJLEtBQUssMkxBQTJMO0FBQ3BNO0FBQUEsRUFDSjtBQUNBLGdCQUFjLGNBQWMsZ0JBQWdCLFdBQVc7QUFDM0Q7QUFDQSxTQUFTLGlCQUFpQixPQUFPLElBQUksTUFBTSxRQUFRLE1BQU0saUJBQWlCLFFBQU0sR0FBRyxHQUFHO0FBRWxGLFFBQU0scUJBQXFCO0FBQUEsR0FFdEIsT0FBTyxlQUFlLElBQUksSUFBSSxPQUFPLGVBQWUsSUFBSSxLQUFLLENBQUM7QUFDbkUsU0FBTyxNQUFNLElBQUksUUFBUSxDQUFDLFNBQVMsV0FBVztBQUMxQyxVQUFNLE9BQU8sQ0FBQyxVQUFVO0FBQ3BCLFVBQUksVUFBVSxPQUFPO0FBQ2pCLGVBQU8sa0JBQWtCLEdBQXVDO0FBQUEsVUFDNUQ7QUFBQSxVQUNBO0FBQUEsUUFDSixDQUFDLENBQUM7QUFBQSxNQUNOLFdBQ1MsaUJBQWlCLE9BQU87QUFDN0IsZUFBTyxLQUFLO0FBQUEsTUFDaEIsV0FDUyxnQkFBZ0IsS0FBSyxHQUFHO0FBQzdCLGVBQU8sa0JBQWtCLEdBQThDO0FBQUEsVUFDbkUsTUFBTTtBQUFBLFVBQ04sSUFBSTtBQUFBLFFBQ1IsQ0FBQyxDQUFDO0FBQUEsTUFDTixPQUNLO0FBQ0QsWUFBSTtBQUFBLFFBRUEsT0FBTyxlQUFlLElBQUksTUFBTSxzQkFDaEMsT0FBTyxVQUFVLFlBQVk7QUFDN0IsNkJBQW1CLEtBQUssS0FBSztBQUFBLFFBQ2pDO0FBQ0EsZ0JBQVE7QUFBQSxNQUNaO0FBQUEsSUFDSjtBQUVBLFVBQU0sY0FBYyxlQUFlLE1BQU0sTUFBTSxLQUFLLFVBQVUsT0FBTyxVQUFVLElBQUksR0FBRyxJQUFJLE1BQU8sT0FBeUMsb0JBQW9CLE1BQU0sSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDO0FBQ3JMLFFBQUksWUFBWSxRQUFRLFFBQVEsV0FBVztBQUMzQyxRQUFJLE1BQU0sU0FBUztBQUNmLGtCQUFZLFVBQVUsS0FBSyxJQUFJO0FBQ25DLFFBQStDLE1BQU0sU0FBUyxHQUFHO0FBQzdELFlBQU0sVUFBVSxrREFBa0QsTUFBTSxPQUFPLE1BQU0sTUFBTSxPQUFPLE1BQU0sRUFBRTtBQUFBLEVBQU0sTUFBTSxTQUFTLENBQUM7QUFBQTtBQUNoSSxVQUFJLE9BQU8sZ0JBQWdCLFlBQVksVUFBVSxhQUFhO0FBQzFELG9CQUFZLFVBQVUsS0FBSyxtQkFBaUI7QUFFeEMsY0FBSSxDQUFDLEtBQUssU0FBUztBQUNmLGlCQUFLLE9BQU87QUFDWixtQkFBTyxRQUFRLE9BQU8sSUFBSSxNQUFNLDBCQUEwQixDQUFDO0FBQUEsVUFDL0Q7QUFDQSxpQkFBTztBQUFBLFFBQ1gsQ0FBQztBQUFBLE1BQ0wsV0FDUyxnQkFBZ0IsUUFBVztBQUVoQyxZQUFJLENBQUMsS0FBSyxTQUFTO0FBQ2YsZUFBSyxPQUFPO0FBQ1osaUJBQU8sSUFBSSxNQUFNLDBCQUEwQixDQUFDO0FBQzVDO0FBQUEsUUFDSjtBQUFBLE1BQ0o7QUFBQSxJQUNKO0FBQ0EsY0FBVSxNQUFNLFNBQU8sT0FBTyxHQUFHLENBQUM7QUFBQSxFQUN0QyxDQUFDO0FBQ0w7QUFDQSxTQUFTLG9CQUFvQixNQUFNLElBQUksTUFBTTtBQUN6QyxNQUFJLFNBQVM7QUFDYixTQUFPLFdBQVk7QUFDZixRQUFJLGFBQWE7QUFDYixXQUFLLDBGQUEwRixLQUFLLFFBQVEsU0FBUyxHQUFHLFFBQVEsaUdBQWlHO0FBRXJPLFNBQUssVUFBVTtBQUNmLFFBQUksV0FBVztBQUNYLFdBQUssTUFBTSxNQUFNLFNBQVM7QUFBQSxFQUNsQztBQUNKO0FBQ0EsU0FBUyx3QkFBd0IsU0FBUyxXQUFXLElBQUksTUFBTSxpQkFBaUIsUUFBTSxHQUFHLEdBQUc7QUFDeEYsUUFBTSxTQUFTLENBQUM7QUFDaEIsYUFBVyxVQUFVLFNBQVM7QUFDMUIsUUFBK0MsQ0FBQyxPQUFPLGNBQWMsQ0FBQyxPQUFPLFNBQVMsUUFBUTtBQUMxRixXQUFLLHFCQUFxQixPQUFPLElBQUksOERBQ1A7QUFBQSxJQUNsQztBQUNBLGVBQVcsUUFBUSxPQUFPLFlBQVk7QUFDbEMsVUFBSSxlQUFlLE9BQU8sV0FBVyxJQUFJO0FBQ3pDLFVBQUssTUFBd0M7QUFDekMsWUFBSSxDQUFDLGdCQUNBLE9BQU8saUJBQWlCLFlBQ3JCLE9BQU8saUJBQWlCLFlBQWE7QUFDekMsZUFBSyxjQUFjLElBQUksMEJBQTBCLE9BQU8sSUFBSSx5Q0FDdkIsT0FBTyxZQUFZLENBQUMsSUFBSTtBQUc3RCxnQkFBTSxJQUFJLE1BQU0seUJBQXlCO0FBQUEsUUFDN0MsV0FDUyxVQUFVLGNBQWM7QUFHN0IsZUFBSyxjQUFjLElBQUksMEJBQTBCLE9BQU8sSUFBSSw2TEFJOUI7QUFDOUIsZ0JBQU0sVUFBVTtBQUNoQix5QkFBZSxNQUFNO0FBQUEsUUFDekIsV0FDUyxhQUFhO0FBQUEsUUFFbEIsQ0FBQyxhQUFhLHFCQUFxQjtBQUNuQyx1QkFBYSxzQkFBc0I7QUFDbkMsZUFBSyxjQUFjLElBQUksMEJBQTBCLE9BQU8sSUFBSSxvSkFHRDtBQUFBLFFBQy9EO0FBQUEsTUFDSjtBQUVBLFVBQUksY0FBYyxzQkFBc0IsQ0FBQyxPQUFPLFVBQVUsSUFBSTtBQUMxRDtBQUNKLFVBQUksaUJBQWlCLFlBQVksR0FBRztBQUVoQyxjQUFNLFVBQVUsYUFBYSxhQUFhO0FBQzFDLGNBQU0sUUFBUSxRQUFRLFNBQVM7QUFDL0IsaUJBQ0ksT0FBTyxLQUFLLGlCQUFpQixPQUFPLElBQUksTUFBTSxRQUFRLE1BQU0sY0FBYyxDQUFDO0FBQUEsTUFDbkYsT0FDSztBQUVELFlBQUksbUJBQW1CLGFBQWE7QUFDcEMsWUFBK0MsRUFBRSxXQUFXLG1CQUFtQjtBQUMzRSxlQUFLLGNBQWMsSUFBSSwwQkFBMEIsT0FBTyxJQUFJLDRMQUE0TDtBQUN4UCw2QkFBbUIsUUFBUSxRQUFRLGdCQUFnQjtBQUFBLFFBQ3ZEO0FBQ0EsZUFBTyxLQUFLLE1BQU0saUJBQWlCLEtBQUssY0FBWTtBQUNoRCxjQUFJLENBQUM7QUFDRCxrQkFBTSxJQUFJLE1BQU0sK0JBQStCLElBQUksU0FBUyxPQUFPLElBQUksR0FBRztBQUM5RSxnQkFBTSxvQkFBb0IsV0FBVyxRQUFRLElBQ3ZDLFNBQVMsVUFDVDtBQUVOLGlCQUFPLEtBQUssSUFBSSxJQUFJO0FBR3BCLGlCQUFPLFdBQVcsSUFBSSxJQUFJO0FBRTFCLGdCQUFNLFVBQVUsa0JBQWtCLGFBQWE7QUFDL0MsZ0JBQU0sUUFBUSxRQUFRLFNBQVM7QUFDL0IsaUJBQVEsU0FDSixpQkFBaUIsT0FBTyxJQUFJLE1BQU0sUUFBUSxNQUFNLGNBQWMsRUFBRTtBQUFBLFFBQ3hFLENBQUMsQ0FBQztBQUFBLE1BQ047QUFBQSxJQUNKO0FBQUEsRUFDSjtBQUNBLFNBQU87QUFDWDtBQU1BLFNBQVMsa0JBQWtCLE9BQU87QUFDOUIsU0FBTyxNQUFNLFFBQVEsTUFBTSxZQUFVLE9BQU8sUUFBUSxJQUM5QyxRQUFRLE9BQU8sSUFBSSxNQUFNLHFDQUFxQyxDQUFDLElBQy9ELFFBQVEsSUFBSSxNQUFNLFFBQVEsSUFBSSxZQUFVLE9BQU8sY0FDN0MsUUFBUSxJQUFJLE9BQU8sS0FBSyxPQUFPLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVSxTQUFTO0FBQ2xFLFVBQU0sZUFBZSxPQUFPLFdBQVcsSUFBSTtBQUMzQyxRQUFJLE9BQU8saUJBQWlCLGNBQ3hCLEVBQUUsaUJBQWlCLGVBQWU7QUFDbEMsZUFBUyxLQUFLLGFBQWEsRUFBRSxLQUFLLGNBQVk7QUFDMUMsWUFBSSxDQUFDO0FBQ0QsaUJBQU8sUUFBUSxPQUFPLElBQUksTUFBTSwrQkFBK0IsSUFBSSxTQUFTLE9BQU8sSUFBSSx5REFBeUQsQ0FBQztBQUNySixjQUFNLG9CQUFvQixXQUFXLFFBQVEsSUFDdkMsU0FBUyxVQUNUO0FBRU4sZUFBTyxLQUFLLElBQUksSUFBSTtBQUdwQixlQUFPLFdBQVcsSUFBSSxJQUFJO0FBQzFCO0FBQUEsTUFDSixDQUFDLENBQUM7QUFBQSxJQUNOO0FBQ0EsV0FBTztBQUFBLEVBQ1gsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLE1BQU0sS0FBSztBQUN0QztBQVNBLFNBQVMsUUFBUSxPQUFPO0FBQ3BCLFFBQU0sU0FBUyxPQUFPLFNBQVM7QUFDL0IsUUFBTSxlQUFlLE9BQU8sZ0JBQWdCO0FBQzVDLE1BQUksY0FBYztBQUNsQixNQUFJLGFBQWE7QUFDakIsUUFBTSxRQUFRLFNBQVMsTUFBTTtBQUN6QixVQUFNLEtBQUssTUFBTSxNQUFNLEVBQUU7QUFDekIsUUFBZ0QsQ0FBQyxlQUFlLE9BQU8sWUFBYTtBQUNoRixVQUFJLENBQUMsZ0JBQWdCLEVBQUUsR0FBRztBQUN0QixZQUFJLGFBQWE7QUFDYixlQUFLO0FBQUEsUUFBbUQsSUFBSTtBQUFBLGlCQUFvQixZQUFZO0FBQUEsV0FBYyxLQUFLO0FBQUEsUUFDbkgsT0FDSztBQUNELGVBQUs7QUFBQSxRQUFtRCxJQUFJO0FBQUEsV0FBYyxLQUFLO0FBQUEsUUFDbkY7QUFBQSxNQUNKO0FBQ0EsbUJBQWE7QUFDYixvQkFBYztBQUFBLElBQ2xCO0FBQ0EsV0FBTyxPQUFPLFFBQVEsRUFBRTtBQUFBLEVBQzVCLENBQUM7QUFDRCxRQUFNLG9CQUFvQixTQUFTLE1BQU07QUFDckMsVUFBTSxFQUFFLFFBQVEsSUFBSSxNQUFNO0FBQzFCLFVBQU0sRUFBRSxPQUFPLElBQUk7QUFDbkIsVUFBTSxlQUFlLFFBQVEsU0FBUyxDQUFDO0FBQ3ZDLFVBQU0saUJBQWlCLGFBQWE7QUFDcEMsUUFBSSxDQUFDLGdCQUFnQixDQUFDLGVBQWU7QUFDakMsYUFBTztBQUNYLFVBQU0sUUFBUSxlQUFlLFVBQVUsa0JBQWtCLEtBQUssTUFBTSxZQUFZLENBQUM7QUFDakYsUUFBSSxRQUFRO0FBQ1IsYUFBTztBQUVYLFVBQU0sbUJBQW1CLGdCQUFnQixRQUFRLFNBQVMsQ0FBQyxDQUFDO0FBQzVEO0FBQUE7QUFBQSxNQUVBLFNBQVM7QUFBQTtBQUFBO0FBQUEsTUFJTCxnQkFBZ0IsWUFBWSxNQUFNO0FBQUEsTUFFbEMsZUFBZSxlQUFlLFNBQVMsQ0FBQyxFQUFFLFNBQVMsbUJBQ2pELGVBQWUsVUFBVSxrQkFBa0IsS0FBSyxNQUFNLFFBQVEsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUMxRTtBQUFBO0FBQUEsRUFDVixDQUFDO0FBQ0QsUUFBTSxXQUFXLFNBQVMsTUFBTSxrQkFBa0IsUUFBUSxNQUN0RCxlQUFlLGFBQWEsUUFBUSxNQUFNLE1BQU0sTUFBTSxDQUFDO0FBQzNELFFBQU0sZ0JBQWdCLFNBQVMsTUFBTSxrQkFBa0IsUUFBUSxNQUMzRCxrQkFBa0IsVUFBVSxhQUFhLFFBQVEsU0FBUyxLQUMxRCwwQkFBMEIsYUFBYSxRQUFRLE1BQU0sTUFBTSxNQUFNLENBQUM7QUFDdEUsV0FBUyxTQUFTLElBQUksQ0FBQyxHQUFHO0FBQ3RCLFFBQUksV0FBVyxDQUFDLEdBQUc7QUFDZixZQUFNLElBQUksT0FBTyxNQUFNLE1BQU0sT0FBTyxJQUFJLFlBQVksTUFBTTtBQUFBLFFBQUUsTUFBTSxNQUFNLEVBQUU7QUFBQTtBQUFBLE1BRTFFLEVBQUUsTUFBTSxJQUFJO0FBQ1osVUFBSSxNQUFNLGtCQUNOLE9BQU8sYUFBYSxlQUNwQix5QkFBeUIsVUFBVTtBQUNuQyxpQkFBUyxvQkFBb0IsTUFBTSxDQUFDO0FBQUEsTUFDeEM7QUFDQSxhQUFPO0FBQUEsSUFDWDtBQUNBLFdBQU8sUUFBUSxRQUFRO0FBQUEsRUFDM0I7QUFFQSxNQUEwRSxXQUFXO0FBQ2pGLFVBQU0sV0FBVyxtQkFBbUI7QUFDcEMsUUFBSSxVQUFVO0FBQ1YsWUFBTSxzQkFBc0I7QUFBQSxRQUN4QixPQUFPLE1BQU07QUFBQSxRQUNiLFVBQVUsU0FBUztBQUFBLFFBQ25CLGVBQWUsY0FBYztBQUFBLFFBQzdCLE9BQU87QUFBQSxNQUNYO0FBRUEsZUFBUyxpQkFBaUIsU0FBUyxrQkFBa0IsQ0FBQztBQUV0RCxlQUFTLGVBQWUsS0FBSyxtQkFBbUI7QUFDaEQsa0JBQVksTUFBTTtBQUNkLDRCQUFvQixRQUFRLE1BQU07QUFDbEMsNEJBQW9CLFdBQVcsU0FBUztBQUN4Qyw0QkFBb0IsZ0JBQWdCLGNBQWM7QUFDbEQsNEJBQW9CLFFBQVEsZ0JBQWdCLE1BQU0sTUFBTSxFQUFFLENBQUMsSUFDckQsT0FDQTtBQUFBLE1BQ1YsR0FBRyxFQUFFLE9BQU8sT0FBTyxDQUFDO0FBQUEsSUFDeEI7QUFBQSxFQUNKO0FBSUEsU0FBTztBQUFBLElBQ0g7QUFBQSxJQUNBLE1BQU0sU0FBUyxNQUFNLE1BQU0sTUFBTSxJQUFJO0FBQUEsSUFDckM7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0o7QUFDSjtBQUNBLFNBQVMsa0JBQWtCLFFBQVE7QUFDL0IsU0FBTyxPQUFPLFdBQVcsSUFBSSxPQUFPLENBQUMsSUFBSTtBQUM3QztBQUNBLE1BQU0saUJBQStCLGdDQUFnQjtBQUFBLEVBQ2pELE1BQU07QUFBQSxFQUNOLGNBQWMsRUFBRSxNQUFNLEVBQUU7QUFBQSxFQUN4QixPQUFPO0FBQUEsSUFDSCxJQUFJO0FBQUEsTUFDQSxNQUFNLENBQUMsUUFBUSxNQUFNO0FBQUEsTUFDckIsVUFBVTtBQUFBLElBQ2Q7QUFBQSxJQUNBLFNBQVM7QUFBQSxJQUNULGFBQWE7QUFBQTtBQUFBLElBRWIsa0JBQWtCO0FBQUEsSUFDbEIsUUFBUTtBQUFBLElBQ1Isa0JBQWtCO0FBQUEsTUFDZCxNQUFNO0FBQUEsTUFDTixTQUFTO0FBQUEsSUFDYjtBQUFBLElBQ0EsZ0JBQWdCO0FBQUEsRUFDcEI7QUFBQSxFQUNBO0FBQUEsRUFDQSxNQUFNLE9BQU8sRUFBRSxNQUFNLEdBQUc7QUFDcEIsVUFBTSxPQUFPLFNBQVMsUUFBUSxLQUFLLENBQUM7QUFDcEMsVUFBTSxFQUFFLFFBQVEsSUFBSSxPQUFPLFNBQVM7QUFDcEMsVUFBTSxVQUFVLFNBQVMsT0FBTztBQUFBLE1BQzVCLENBQUMsYUFBYSxNQUFNLGFBQWEsUUFBUSxpQkFBaUIsb0JBQW9CLENBQUMsR0FBRyxLQUFLO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLE1BTXZGLENBQUMsYUFBYSxNQUFNLGtCQUFrQixRQUFRLHNCQUFzQiwwQkFBMEIsQ0FBQyxHQUFHLEtBQUs7QUFBQSxJQUMzRyxFQUFFO0FBQ0YsV0FBTyxNQUFNO0FBQ1QsWUFBTSxXQUFXLE1BQU0sV0FBVyxrQkFBa0IsTUFBTSxRQUFRLElBQUksQ0FBQztBQUN2RSxhQUFPLE1BQU0sU0FDUCxXQUNBLEVBQUUsS0FBSztBQUFBLFFBQ0wsZ0JBQWdCLEtBQUssZ0JBQ2YsTUFBTSxtQkFDTjtBQUFBLFFBQ04sTUFBTSxLQUFLO0FBQUE7QUFBQTtBQUFBLFFBR1gsU0FBUyxLQUFLO0FBQUEsUUFDZCxPQUFPLFFBQVE7QUFBQSxNQUNuQixHQUFHLFFBQVE7QUFBQSxJQUNuQjtBQUFBLEVBQ0o7QUFDSixDQUFDO0FBTUQsTUFBTSxhQUFhO0FBQ25CLFNBQVMsV0FBVyxHQUFHO0FBRW5CLE1BQUksRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRTtBQUN4QztBQUVKLE1BQUksRUFBRTtBQUNGO0FBRUosTUFBSSxFQUFFLFdBQVcsVUFBYSxFQUFFLFdBQVc7QUFDdkM7QUFHSixNQUFJLEVBQUUsaUJBQWlCLEVBQUUsY0FBYyxjQUFjO0FBRWpELFVBQU0sU0FBUyxFQUFFLGNBQWMsYUFBYSxRQUFRO0FBQ3BELFFBQUksY0FBYyxLQUFLLE1BQU07QUFDekI7QUFBQSxFQUNSO0FBRUEsTUFBSSxFQUFFO0FBQ0YsTUFBRSxlQUFlO0FBQ3JCLFNBQU87QUFDWDtBQUNBLFNBQVMsZUFBZSxPQUFPLE9BQU87QUFDbEMsYUFBVyxPQUFPLE9BQU87QUFDckIsVUFBTSxhQUFhLE1BQU0sR0FBRztBQUM1QixVQUFNLGFBQWEsTUFBTSxHQUFHO0FBQzVCLFFBQUksT0FBTyxlQUFlLFVBQVU7QUFDaEMsVUFBSSxlQUFlO0FBQ2YsZUFBTztBQUFBLElBQ2YsT0FDSztBQUNELFVBQUksQ0FBQyxRQUFRLFVBQVUsS0FDbkIsV0FBVyxXQUFXLFdBQVcsVUFDakMsV0FBVyxLQUFLLENBQUMsT0FBTyxNQUFNLFVBQVUsV0FBVyxDQUFDLENBQUM7QUFDckQsZUFBTztBQUFBLElBQ2Y7QUFBQSxFQUNKO0FBQ0EsU0FBTztBQUNYO0FBS0EsU0FBUyxnQkFBZ0IsUUFBUTtBQUM3QixTQUFPLFNBQVUsT0FBTyxVQUFVLE9BQU8sUUFBUSxPQUFPLE9BQU8sT0FBUTtBQUMzRTtBQU9BLE1BQU0sZUFBZSxDQUFDLFdBQVcsYUFBYSxpQkFBaUIsYUFBYSxPQUN0RSxZQUNBLGVBQWUsT0FDWCxjQUNBO0FBRVYsTUFBTSxpQkFBK0IsZ0NBQWdCO0FBQUEsRUFDakQsTUFBTTtBQUFBO0FBQUEsRUFFTixjQUFjO0FBQUEsRUFDZCxPQUFPO0FBQUEsSUFDSCxNQUFNO0FBQUEsTUFDRixNQUFNO0FBQUEsTUFDTixTQUFTO0FBQUEsSUFDYjtBQUFBLElBQ0EsT0FBTztBQUFBLEVBQ1g7QUFBQTtBQUFBO0FBQUEsRUFHQSxjQUFjLEVBQUUsTUFBTSxFQUFFO0FBQUEsRUFDeEIsTUFBTSxPQUFPLEVBQUUsT0FBTyxNQUFNLEdBQUc7QUFDM0IsSUFBMkMsb0JBQW9CO0FBQy9ELFVBQU0sZ0JBQWdCLE9BQU8scUJBQXFCO0FBQ2xELFVBQU0saUJBQWlCLFNBQVMsTUFBTSxNQUFNLFNBQVMsY0FBYyxLQUFLO0FBQ3hFLFVBQU0sZ0JBQWdCLE9BQU8sY0FBYyxDQUFDO0FBRzVDLFVBQU0sUUFBUSxTQUFTLE1BQU07QUFDekIsVUFBSSxlQUFlLE1BQU0sYUFBYTtBQUN0QyxZQUFNLEVBQUUsUUFBUSxJQUFJLGVBQWU7QUFDbkMsVUFBSTtBQUNKLGNBQVEsZUFBZSxRQUFRLFlBQVksTUFDdkMsQ0FBQyxhQUFhLFlBQVk7QUFDMUI7QUFBQSxNQUNKO0FBQ0EsYUFBTztBQUFBLElBQ1gsQ0FBQztBQUNELFVBQU0sa0JBQWtCLFNBQVMsTUFBTSxlQUFlLE1BQU0sUUFBUSxNQUFNLEtBQUssQ0FBQztBQUNoRixZQUFRLGNBQWMsU0FBUyxNQUFNLE1BQU0sUUFBUSxDQUFDLENBQUM7QUFDckQsWUFBUSxpQkFBaUIsZUFBZTtBQUN4QyxZQUFRLHVCQUF1QixjQUFjO0FBQzdDLFVBQU0sVUFBVSxJQUFJO0FBR3BCLFVBQU0sTUFBTSxDQUFDLFFBQVEsT0FBTyxnQkFBZ0IsT0FBTyxNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsVUFBVSxJQUFJLElBQUksR0FBRyxDQUFDLGFBQWEsTUFBTSxPQUFPLE1BQU07QUFFcEgsVUFBSSxJQUFJO0FBR0osV0FBRyxVQUFVLElBQUksSUFBSTtBQU9yQixZQUFJLFFBQVEsU0FBUyxNQUFNLFlBQVksYUFBYSxhQUFhO0FBQzdELGNBQUksQ0FBQyxHQUFHLFlBQVksTUFBTTtBQUN0QixlQUFHLGNBQWMsS0FBSztBQUFBLFVBQzFCO0FBQ0EsY0FBSSxDQUFDLEdBQUcsYUFBYSxNQUFNO0FBQ3ZCLGVBQUcsZUFBZSxLQUFLO0FBQUEsVUFDM0I7QUFBQSxRQUNKO0FBQUEsTUFDSjtBQUVBLFVBQUksWUFDQTtBQUFBO0FBQUEsT0FHQyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLEtBQUssQ0FBQyxjQUFjO0FBQ3pELFNBQUMsR0FBRyxlQUFlLElBQUksS0FBSyxDQUFDLEdBQUcsUUFBUSxjQUFZLFNBQVMsUUFBUSxDQUFDO0FBQUEsTUFDMUU7QUFBQSxJQUNKLEdBQUcsRUFBRSxPQUFPLE9BQU8sQ0FBQztBQUNwQixXQUFPLE1BQU07QUFDVCxZQUFNLFFBQVEsZUFBZTtBQUc3QixZQUFNLGNBQWMsTUFBTTtBQUMxQixZQUFNLGVBQWUsZ0JBQWdCO0FBQ3JDLFlBQU0sZ0JBQWdCLGdCQUFnQixhQUFhLFdBQVcsV0FBVztBQUN6RSxVQUFJLENBQUMsZUFBZTtBQUNoQixlQUFPLGNBQWMsTUFBTSxTQUFTLEVBQUUsV0FBVyxlQUFlLE1BQU0sQ0FBQztBQUFBLE1BQzNFO0FBRUEsWUFBTSxtQkFBbUIsYUFBYSxNQUFNLFdBQVc7QUFDdkQsWUFBTSxhQUFhLG1CQUNiLHFCQUFxQixPQUNqQixNQUFNLFNBQ04sT0FBTyxxQkFBcUIsYUFDeEIsaUJBQWlCLEtBQUssSUFDdEIsbUJBQ1I7QUFDTixZQUFNLG1CQUFtQixXQUFTO0FBRTlCLFlBQUksTUFBTSxVQUFVLGFBQWE7QUFDN0IsdUJBQWEsVUFBVSxXQUFXLElBQUk7QUFBQSxRQUMxQztBQUFBLE1BQ0o7QUFDQSxZQUFNLFlBQVksRUFBRSxlQUFlLE9BQU8sQ0FBQyxHQUFHLFlBQVksT0FBTztBQUFBLFFBQzdEO0FBQUEsUUFDQSxLQUFLO0FBQUEsTUFDVCxDQUFDLENBQUM7QUFDRixVQUNJLGFBQ0EsVUFBVSxLQUFLO0FBRWYsY0FBTSxPQUFPO0FBQUEsVUFDVCxPQUFPLE1BQU07QUFBQSxVQUNiLE1BQU0sYUFBYTtBQUFBLFVBQ25CLE1BQU0sYUFBYTtBQUFBLFVBQ25CLE1BQU0sYUFBYTtBQUFBLFFBQ3ZCO0FBQ0EsY0FBTSxvQkFBb0IsUUFBUSxVQUFVLEdBQUcsSUFDekMsVUFBVSxJQUFJLElBQUksT0FBSyxFQUFFLENBQUMsSUFDMUIsQ0FBQyxVQUFVLElBQUksQ0FBQztBQUN0QiwwQkFBa0IsUUFBUSxjQUFZO0FBRWxDLG1CQUFTLGlCQUFpQjtBQUFBLFFBQzlCLENBQUM7QUFBQSxNQUNMO0FBQ0E7QUFBQTtBQUFBO0FBQUEsUUFHQSxjQUFjLE1BQU0sU0FBUyxFQUFFLFdBQVcsV0FBVyxNQUFNLENBQUMsS0FDeEQ7QUFBQTtBQUFBLElBQ1I7QUFBQSxFQUNKO0FBQ0osQ0FBQztBQUNELFNBQVMsY0FBYyxNQUFNLE1BQU07QUFDL0IsTUFBSSxDQUFDO0FBQ0QsV0FBTztBQUNYLFFBQU0sY0FBYyxLQUFLLElBQUk7QUFDN0IsU0FBTyxZQUFZLFdBQVcsSUFBSSxZQUFZLENBQUMsSUFBSTtBQUN2RDtBQU1BLE1BQU0sYUFBYTtBQUduQixTQUFTLHNCQUFzQjtBQUMzQixRQUFNLFdBQVcsbUJBQW1CO0FBQ3BDLFFBQU0sYUFBYSxTQUFTLFVBQVUsU0FBUyxPQUFPLEtBQUs7QUFDM0QsUUFBTSxvQkFBb0IsU0FBUyxVQUFVLFNBQVMsT0FBTyxXQUFXLFNBQVMsT0FBTyxRQUFRO0FBQ2hHLE1BQUksZUFDQyxlQUFlLGVBQWUsV0FBVyxTQUFTLFlBQVksTUFDL0QsT0FBTyxzQkFBc0IsWUFDN0Isa0JBQWtCLFNBQVMsY0FBYztBQUN6QyxVQUFNLE9BQU8sZUFBZSxjQUFjLGVBQWU7QUFDekQsU0FBSztBQUFBO0FBQUE7QUFBQTtBQUFBLEtBR0ssSUFBSTtBQUFBO0FBQUEsTUFFSCxJQUFJO0FBQUEsZUFDSztBQUFBLEVBQ3hCO0FBQ0o7QUFTQSxTQUFTLG9CQUFvQixlQUFlLFNBQVM7QUFDakQsUUFBTSxPQUFPLE9BQU8sQ0FBQyxHQUFHLGVBQWU7QUFBQTtBQUFBLElBRW5DLFNBQVMsY0FBYyxRQUFRLElBQUksYUFBVyxLQUFLLFNBQVMsQ0FBQyxhQUFhLFlBQVksU0FBUyxDQUFDLENBQUM7QUFBQSxFQUNyRyxDQUFDO0FBQ0QsU0FBTztBQUFBLElBQ0gsU0FBUztBQUFBLE1BQ0wsTUFBTTtBQUFBLE1BQ04sVUFBVTtBQUFBLE1BQ1YsU0FBUyxjQUFjO0FBQUEsTUFDdkI7QUFBQSxNQUNBLE9BQU87QUFBQSxJQUNYO0FBQUEsRUFDSjtBQUNKO0FBQ0EsU0FBUyxjQUFjLFNBQVM7QUFDNUIsU0FBTztBQUFBLElBQ0gsU0FBUztBQUFBLE1BQ0w7QUFBQSxJQUNKO0FBQUEsRUFDSjtBQUNKO0FBRUEsSUFBSSxXQUFXO0FBQ2YsU0FBUyxZQUFZLEtBQUssUUFBUSxTQUFTO0FBR3ZDLE1BQUksT0FBTztBQUNQO0FBQ0osU0FBTyxnQkFBZ0I7QUFFdkIsUUFBTSxLQUFLO0FBQ1gsc0JBQW9CO0FBQUEsSUFDaEIsSUFBSSxzQkFBc0IsS0FBSyxNQUFNLEtBQUs7QUFBQSxJQUMxQyxPQUFPO0FBQUEsSUFDUCxhQUFhO0FBQUEsSUFDYixVQUFVO0FBQUEsSUFDVixNQUFNO0FBQUEsSUFDTixxQkFBcUIsQ0FBQyxTQUFTO0FBQUEsSUFDL0I7QUFBQSxFQUNKLEdBQUcsU0FBTztBQUNOLFFBQUksT0FBTyxJQUFJLFFBQVEsWUFBWTtBQUMvQixjQUFRLEtBQUssdU5BQXVOO0FBQUEsSUFDeE87QUFFQSxRQUFJLEdBQUcsaUJBQWlCLENBQUMsU0FBUyxRQUFRO0FBQ3RDLFVBQUksUUFBUSxjQUFjO0FBQ3RCLGdCQUFRLGFBQWEsTUFBTSxLQUFLO0FBQUEsVUFDNUIsTUFBTTtBQUFBLFVBQ04sS0FBSztBQUFBLFVBQ0wsVUFBVTtBQUFBLFVBQ1YsT0FBTyxvQkFBb0IsT0FBTyxhQUFhLE9BQU8sZUFBZTtBQUFBLFFBQ3pFLENBQUM7QUFBQSxNQUNMO0FBQUEsSUFDSixDQUFDO0FBRUQsUUFBSSxHQUFHLG1CQUFtQixDQUFDLEVBQUUsVUFBVSxNQUFNLGtCQUFrQixNQUFNO0FBQ2pFLFVBQUksa0JBQWtCLGdCQUFnQjtBQUNsQyxjQUFNLE9BQU8sa0JBQWtCO0FBQy9CLGFBQUssS0FBSyxLQUFLO0FBQUEsVUFDWCxRQUFRLEtBQUssT0FBTyxHQUFHLEtBQUssS0FBSyxTQUFTLENBQUMsT0FBTyxNQUFNLEtBQUs7QUFBQSxVQUM3RCxXQUFXO0FBQUEsVUFDWCxTQUFTO0FBQUEsVUFDVCxpQkFBaUI7QUFBQSxRQUNyQixDQUFDO0FBQUEsTUFDTDtBQUVBLFVBQUksUUFBUSxrQkFBa0IsY0FBYyxHQUFHO0FBQzNDLDBCQUFrQixnQkFBZ0I7QUFDbEMsMEJBQWtCLGVBQWUsUUFBUSxrQkFBZ0I7QUFDckQsY0FBSSxRQUFRLGFBQWEsTUFBTTtBQUMvQixjQUFJLGtCQUFrQjtBQUN0QixjQUFJLFVBQVU7QUFDZCxjQUFJLFlBQVk7QUFDaEIsY0FBSSxhQUFhLE9BQU87QUFDcEIsb0JBQVEsYUFBYTtBQUNyQiw4QkFBa0I7QUFDbEIsd0JBQVk7QUFBQSxVQUNoQixXQUNTLGFBQWEsZUFBZTtBQUNqQyw4QkFBa0I7QUFDbEIsc0JBQVU7QUFBQSxVQUNkLFdBQ1MsYUFBYSxVQUFVO0FBQzVCLDhCQUFrQjtBQUNsQixzQkFBVTtBQUFBLFVBQ2Q7QUFDQSxlQUFLLEtBQUssS0FBSztBQUFBLFlBQ1g7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxVQUNKLENBQUM7QUFBQSxRQUNMLENBQUM7QUFBQSxNQUNMO0FBQUEsSUFDSixDQUFDO0FBQ0QsVUFBTSxPQUFPLGNBQWMsTUFBTTtBQUU3Qix3QkFBa0I7QUFDbEIsVUFBSSxzQkFBc0I7QUFDMUIsVUFBSSxrQkFBa0IsaUJBQWlCO0FBQ3ZDLFVBQUksbUJBQW1CLGlCQUFpQjtBQUFBLElBQzVDLENBQUM7QUFDRCxVQUFNLHFCQUFxQix3QkFBd0I7QUFDbkQsUUFBSSxpQkFBaUI7QUFBQSxNQUNqQixJQUFJO0FBQUEsTUFDSixPQUFPLFNBQVMsS0FBSyxNQUFNLEtBQUssRUFBRTtBQUFBLE1BQ2xDLE9BQU87QUFBQSxJQUNYLENBQUM7QUFPRCxXQUFPLFFBQVEsQ0FBQyxPQUFPLE9BQU87QUFDMUIsVUFBSSxpQkFBaUI7QUFBQSxRQUNqQixTQUFTO0FBQUEsUUFDVCxPQUFPO0FBQUEsVUFDSCxPQUFPO0FBQUEsVUFDUCxVQUFVLEdBQUc7QUFBQSxVQUNiLFNBQVM7QUFBQSxVQUNULE1BQU0sSUFBSSxJQUFJO0FBQUEsVUFDZCxNQUFNLEVBQUUsTUFBTTtBQUFBLFVBQ2QsU0FBUyxHQUFHLEtBQUs7QUFBQSxRQUNyQjtBQUFBLE1BQ0osQ0FBQztBQUFBLElBQ0wsQ0FBQztBQUVELFFBQUksZUFBZTtBQUNuQixXQUFPLFdBQVcsQ0FBQyxJQUFJLFNBQVM7QUFDNUIsWUFBTSxPQUFPO0FBQUEsUUFDVCxPQUFPLGNBQWMsWUFBWTtBQUFBLFFBQ2pDLE1BQU0sb0JBQW9CLE1BQU0seUNBQXlDO0FBQUEsUUFDekUsSUFBSSxvQkFBb0IsSUFBSSxpQkFBaUI7QUFBQSxNQUNqRDtBQUVBLGFBQU8sZUFBZSxHQUFHLE1BQU0sa0JBQWtCO0FBQUEsUUFDN0MsT0FBTztBQUFBLE1BQ1gsQ0FBQztBQUNELFVBQUksaUJBQWlCO0FBQUEsUUFDakIsU0FBUztBQUFBLFFBQ1QsT0FBTztBQUFBLFVBQ0gsTUFBTSxJQUFJLElBQUk7QUFBQSxVQUNkLE9BQU87QUFBQSxVQUNQLFVBQVUsR0FBRztBQUFBLFVBQ2I7QUFBQSxVQUNBLFNBQVMsR0FBRyxLQUFLO0FBQUEsUUFDckI7QUFBQSxNQUNKLENBQUM7QUFBQSxJQUNMLENBQUM7QUFDRCxXQUFPLFVBQVUsQ0FBQyxJQUFJLE1BQU0sWUFBWTtBQUNwQyxZQUFNLE9BQU87QUFBQSxRQUNULE9BQU8sY0FBYyxXQUFXO0FBQUEsTUFDcEM7QUFDQSxVQUFJLFNBQVM7QUFDVCxhQUFLLFVBQVU7QUFBQSxVQUNYLFNBQVM7QUFBQSxZQUNMLE1BQU07QUFBQSxZQUNOLFVBQVU7QUFBQSxZQUNWLFNBQVMsVUFBVSxRQUFRLFVBQVU7QUFBQSxZQUNyQyxTQUFTO0FBQUEsWUFDVCxPQUFPO0FBQUEsVUFDWDtBQUFBLFFBQ0o7QUFDQSxhQUFLLFNBQVMsY0FBYyxHQUFHO0FBQUEsTUFDbkMsT0FDSztBQUNELGFBQUssU0FBUyxjQUFjLEdBQUc7QUFBQSxNQUNuQztBQUVBLFdBQUssT0FBTyxvQkFBb0IsTUFBTSx5Q0FBeUM7QUFDL0UsV0FBSyxLQUFLLG9CQUFvQixJQUFJLGlCQUFpQjtBQUNuRCxVQUFJLGlCQUFpQjtBQUFBLFFBQ2pCLFNBQVM7QUFBQSxRQUNULE9BQU87QUFBQSxVQUNILE9BQU87QUFBQSxVQUNQLFVBQVUsR0FBRztBQUFBLFVBQ2IsTUFBTSxJQUFJLElBQUk7QUFBQSxVQUNkO0FBQUEsVUFDQSxTQUFTLFVBQVUsWUFBWTtBQUFBLFVBQy9CLFNBQVMsR0FBRyxLQUFLO0FBQUEsUUFDckI7QUFBQSxNQUNKLENBQUM7QUFBQSxJQUNMLENBQUM7QUFJRCxVQUFNLG9CQUFvQixzQkFBc0I7QUFDaEQsUUFBSSxhQUFhO0FBQUEsTUFDYixJQUFJO0FBQUEsTUFDSixPQUFPLFlBQVksS0FBSyxNQUFNLEtBQUs7QUFBQSxNQUNuQyxNQUFNO0FBQUEsTUFDTix1QkFBdUI7QUFBQSxJQUMzQixDQUFDO0FBQ0QsYUFBUyxvQkFBb0I7QUFFekIsVUFBSSxDQUFDO0FBQ0Q7QUFDSixZQUFNLFVBQVU7QUFFaEIsVUFBSSxTQUFTLFFBQVEsVUFBVSxFQUFFLE9BQU8sV0FBUyxDQUFDLE1BQU07QUFBQTtBQUFBLE1BR3BELENBQUMsTUFBTSxPQUFPLE9BQU8sVUFBVTtBQUVuQyxhQUFPLFFBQVEsNEJBQTRCO0FBRTNDLFVBQUksUUFBUSxRQUFRO0FBQ2hCLGlCQUFTLE9BQU8sT0FBTztBQUFBO0FBQUEsVUFFdkIsZ0JBQWdCLE9BQU8sUUFBUSxPQUFPLFlBQVksQ0FBQztBQUFBLFNBQUM7QUFBQSxNQUN4RDtBQUVBLGFBQU8sUUFBUSxXQUFTLHNCQUFzQixPQUFPLE9BQU8sYUFBYSxLQUFLLENBQUM7QUFDL0UsY0FBUSxZQUFZLE9BQU8sSUFBSSw2QkFBNkI7QUFBQSxJQUNoRTtBQUNBLFFBQUk7QUFDSixRQUFJLEdBQUcsaUJBQWlCLGFBQVc7QUFDL0IsNEJBQXNCO0FBQ3RCLFVBQUksUUFBUSxRQUFRLE9BQU8sUUFBUSxnQkFBZ0IsbUJBQW1CO0FBQ2xFLDBCQUFrQjtBQUFBLE1BQ3RCO0FBQUEsSUFDSixDQUFDO0FBSUQsUUFBSSxHQUFHLGtCQUFrQixhQUFXO0FBQ2hDLFVBQUksUUFBUSxRQUFRLE9BQU8sUUFBUSxnQkFBZ0IsbUJBQW1CO0FBQ2xFLGNBQU0sU0FBUyxRQUFRLFVBQVU7QUFDakMsY0FBTSxRQUFRLE9BQU8sS0FBSyxDQUFBQyxXQUFTQSxPQUFNLE9BQU8sWUFBWSxRQUFRLE1BQU07QUFDMUUsWUFBSSxPQUFPO0FBQ1Asa0JBQVEsUUFBUTtBQUFBLFlBQ1osU0FBUywwQ0FBMEMsS0FBSztBQUFBLFVBQzVEO0FBQUEsUUFDSjtBQUFBLE1BQ0o7QUFBQSxJQUNKLENBQUM7QUFDRCxRQUFJLGtCQUFrQixpQkFBaUI7QUFDdkMsUUFBSSxtQkFBbUIsaUJBQWlCO0FBQUEsRUFDNUMsQ0FBQztBQUNMO0FBQ0EsU0FBUyxlQUFlLEtBQUs7QUFDekIsTUFBSSxJQUFJLFVBQVU7QUFDZCxXQUFPLElBQUksYUFBYSxNQUFNO0FBQUEsRUFDbEMsT0FDSztBQUNELFdBQU8sSUFBSSxhQUFhLE1BQU07QUFBQSxFQUNsQztBQUNKO0FBQ0EsU0FBUywwQ0FBMEMsT0FBTztBQUN0RCxRQUFNLEVBQUUsT0FBTyxJQUFJO0FBQ25CLFFBQU0sU0FBUztBQUFBLElBQ1gsRUFBRSxVQUFVLE9BQU8sS0FBSyxRQUFRLE9BQU8sT0FBTyxLQUFLO0FBQUEsRUFDdkQ7QUFDQSxNQUFJLE9BQU8sUUFBUSxNQUFNO0FBQ3JCLFdBQU8sS0FBSztBQUFBLE1BQ1IsVUFBVTtBQUFBLE1BQ1YsS0FBSztBQUFBLE1BQ0wsT0FBTyxPQUFPO0FBQUEsSUFDbEIsQ0FBQztBQUFBLEVBQ0w7QUFDQSxTQUFPLEtBQUssRUFBRSxVQUFVLE9BQU8sS0FBSyxVQUFVLE9BQU8sTUFBTSxHQUFHLENBQUM7QUFDL0QsTUFBSSxNQUFNLEtBQUssUUFBUTtBQUNuQixXQUFPLEtBQUs7QUFBQSxNQUNSLFVBQVU7QUFBQSxNQUNWLEtBQUs7QUFBQSxNQUNMLE9BQU87QUFBQSxRQUNILFNBQVM7QUFBQSxVQUNMLE1BQU07QUFBQSxVQUNOLFVBQVU7QUFBQSxVQUNWLFNBQVMsTUFBTSxLQUNWLElBQUksU0FBTyxHQUFHLElBQUksSUFBSSxHQUFHLGVBQWUsR0FBRyxDQUFDLEVBQUUsRUFDOUMsS0FBSyxHQUFHO0FBQUEsVUFDYixTQUFTO0FBQUEsVUFDVCxPQUFPLE1BQU07QUFBQSxRQUNqQjtBQUFBLE1BQ0o7QUFBQSxJQUNKLENBQUM7QUFBQSxFQUNMO0FBQ0EsTUFBSSxPQUFPLFlBQVksTUFBTTtBQUN6QixXQUFPLEtBQUs7QUFBQSxNQUNSLFVBQVU7QUFBQSxNQUNWLEtBQUs7QUFBQSxNQUNMLE9BQU8sT0FBTztBQUFBLElBQ2xCLENBQUM7QUFBQSxFQUNMO0FBQ0EsTUFBSSxNQUFNLE1BQU0sUUFBUTtBQUNwQixXQUFPLEtBQUs7QUFBQSxNQUNSLFVBQVU7QUFBQSxNQUNWLEtBQUs7QUFBQSxNQUNMLE9BQU8sTUFBTSxNQUFNLElBQUksV0FBUyxNQUFNLE9BQU8sSUFBSTtBQUFBLElBQ3JELENBQUM7QUFBQSxFQUNMO0FBQ0EsTUFBSSxPQUFPLEtBQUssTUFBTSxPQUFPLElBQUksRUFBRSxRQUFRO0FBQ3ZDLFdBQU8sS0FBSztBQUFBLE1BQ1IsVUFBVTtBQUFBLE1BQ1YsS0FBSztBQUFBLE1BQ0wsT0FBTyxNQUFNLE9BQU87QUFBQSxJQUN4QixDQUFDO0FBQUEsRUFDTDtBQUNBLFNBQU8sS0FBSztBQUFBLElBQ1IsS0FBSztBQUFBLElBQ0wsVUFBVTtBQUFBLElBQ1YsT0FBTztBQUFBLE1BQ0gsU0FBUztBQUFBLFFBQ0wsTUFBTTtBQUFBLFFBQ04sVUFBVTtBQUFBLFFBQ1YsU0FBUyxNQUFNLE1BQU0sSUFBSSxXQUFTLE1BQU0sS0FBSyxJQUFJLENBQUMsRUFBRSxLQUFLLEtBQUs7QUFBQSxRQUM5RCxTQUFTO0FBQUEsUUFDVCxPQUFPLE1BQU07QUFBQSxNQUNqQjtBQUFBLElBQ0o7QUFBQSxFQUNKLENBQUM7QUFDRCxTQUFPO0FBQ1g7QUFJQSxNQUFNLFdBQVc7QUFDakIsTUFBTSxXQUFXO0FBQ2pCLE1BQU0sV0FBVztBQUNqQixNQUFNLFdBQVc7QUFDakIsTUFBTSxhQUFhO0FBRW5CLE1BQU0sT0FBTztBQUNiLE1BQU0sVUFBVTtBQUNoQixNQUFNLFVBQVU7QUFDaEIsU0FBUyw4QkFBOEIsT0FBTztBQUMxQyxRQUFNLE9BQU8sQ0FBQztBQUNkLFFBQU0sRUFBRSxPQUFPLElBQUk7QUFDbkIsTUFBSSxPQUFPLFFBQVEsTUFBTTtBQUNyQixTQUFLLEtBQUs7QUFBQSxNQUNOLE9BQU8sT0FBTyxPQUFPLElBQUk7QUFBQSxNQUN6QixXQUFXO0FBQUEsTUFDWCxpQkFBaUI7QUFBQSxJQUNyQixDQUFDO0FBQUEsRUFDTDtBQUNBLE1BQUksT0FBTyxTQUFTO0FBQ2hCLFNBQUssS0FBSztBQUFBLE1BQ04sT0FBTztBQUFBLE1BQ1AsV0FBVztBQUFBLE1BQ1gsaUJBQWlCO0FBQUEsSUFDckIsQ0FBQztBQUFBLEVBQ0w7QUFDQSxNQUFJLE1BQU0sWUFBWTtBQUNsQixTQUFLLEtBQUs7QUFBQSxNQUNOLE9BQU87QUFBQSxNQUNQLFdBQVc7QUFBQSxNQUNYLGlCQUFpQjtBQUFBLElBQ3JCLENBQUM7QUFBQSxFQUNMO0FBQ0EsTUFBSSxNQUFNLGtCQUFrQjtBQUN4QixTQUFLLEtBQUs7QUFBQSxNQUNOLE9BQU87QUFBQSxNQUNQLFdBQVc7QUFBQSxNQUNYLGlCQUFpQjtBQUFBLElBQ3JCLENBQUM7QUFBQSxFQUNMO0FBQ0EsTUFBSSxNQUFNLGFBQWE7QUFDbkIsU0FBSyxLQUFLO0FBQUEsTUFDTixPQUFPO0FBQUEsTUFDUCxXQUFXO0FBQUEsTUFDWCxpQkFBaUI7QUFBQSxJQUNyQixDQUFDO0FBQUEsRUFDTDtBQUNBLE1BQUksT0FBTyxVQUFVO0FBQ2pCLFNBQUssS0FBSztBQUFBLE1BQ04sT0FBTyxPQUFPLE9BQU8sYUFBYSxXQUM1QixhQUFhLE9BQU8sUUFBUSxLQUM1QjtBQUFBLE1BQ04sV0FBVztBQUFBLE1BQ1gsaUJBQWlCO0FBQUEsSUFDckIsQ0FBQztBQUFBLEVBQ0w7QUFHQSxNQUFJLEtBQUssT0FBTztBQUNoQixNQUFJLE1BQU0sTUFBTTtBQUNaLFNBQUssT0FBTyxlQUFlO0FBQzNCLFdBQU8sVUFBVTtBQUFBLEVBQ3JCO0FBQ0EsU0FBTztBQUFBLElBQ0g7QUFBQSxJQUNBLE9BQU8sT0FBTztBQUFBLElBQ2Q7QUFBQSxJQUNBLFVBQVUsTUFBTSxTQUFTLElBQUksNkJBQTZCO0FBQUEsRUFDOUQ7QUFDSjtBQUVBLElBQUksZ0JBQWdCO0FBQ3BCLE1BQU0sb0JBQW9CO0FBQzFCLFNBQVMsc0JBQXNCLE9BQU8sY0FBYztBQUdoRCxRQUFNLGdCQUFnQixhQUFhLFFBQVEsVUFDdkMsa0JBQWtCLGFBQWEsUUFBUSxhQUFhLFFBQVEsU0FBUyxDQUFDLEdBQUcsTUFBTSxNQUFNO0FBQ3pGLFFBQU0sbUJBQW1CLE1BQU0sY0FBYztBQUM3QyxNQUFJLENBQUMsZUFBZTtBQUNoQixVQUFNLGNBQWMsYUFBYSxRQUFRLEtBQUssV0FBUyxrQkFBa0IsT0FBTyxNQUFNLE1BQU0sQ0FBQztBQUFBLEVBQ2pHO0FBQ0EsUUFBTSxTQUFTLFFBQVEsZ0JBQWMsc0JBQXNCLFlBQVksWUFBWSxDQUFDO0FBQ3hGO0FBQ0EsU0FBUyw2QkFBNkIsT0FBTztBQUN6QyxRQUFNLGFBQWE7QUFDbkIsUUFBTSxTQUFTLFFBQVEsNEJBQTRCO0FBQ3ZEO0FBQ0EsU0FBUyxnQkFBZ0IsT0FBTyxRQUFRO0FBQ3BDLFFBQU0sUUFBUSxPQUFPLE1BQU0sRUFBRSxFQUFFLE1BQU0saUJBQWlCO0FBQ3RELFFBQU0sYUFBYTtBQUNuQixNQUFJLENBQUMsU0FBUyxNQUFNLFNBQVMsR0FBRztBQUM1QixXQUFPO0FBQUEsRUFDWDtBQUVBLFFBQU0sY0FBYyxJQUFJLE9BQU8sTUFBTSxDQUFDLEVBQUUsUUFBUSxPQUFPLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQztBQUNwRSxNQUFJLFlBQVksS0FBSyxNQUFNLEdBQUc7QUFFMUIsVUFBTSxTQUFTLFFBQVEsV0FBUyxnQkFBZ0IsT0FBTyxNQUFNLENBQUM7QUFFOUQsUUFBSSxNQUFNLE9BQU8sU0FBUyxPQUFPLFdBQVcsS0FBSztBQUM3QyxZQUFNLGFBQWEsTUFBTSxHQUFHLEtBQUssTUFBTTtBQUN2QyxhQUFPO0FBQUEsSUFDWDtBQUVBLFdBQU87QUFBQSxFQUNYO0FBQ0EsUUFBTSxPQUFPLE1BQU0sT0FBTyxLQUFLLFlBQVk7QUFDM0MsUUFBTSxjQUFjLE9BQU8sSUFBSTtBQUUvQixNQUFJLENBQUMsT0FBTyxXQUFXLEdBQUcsTUFDckIsWUFBWSxTQUFTLE1BQU0sS0FBSyxLQUFLLFNBQVMsTUFBTTtBQUNyRCxXQUFPO0FBQ1gsTUFBSSxZQUFZLFdBQVcsTUFBTSxLQUFLLEtBQUssV0FBVyxNQUFNO0FBQ3hELFdBQU87QUFDWCxNQUFJLE1BQU0sT0FBTyxRQUFRLE9BQU8sTUFBTSxPQUFPLElBQUksRUFBRSxTQUFTLE1BQU07QUFDOUQsV0FBTztBQUNYLFNBQU8sTUFBTSxTQUFTLEtBQUssV0FBUyxnQkFBZ0IsT0FBTyxNQUFNLENBQUM7QUFDdEU7QUFDQSxTQUFTLEtBQUssS0FBSyxNQUFNO0FBQ3JCLFFBQU0sTUFBTSxDQUFDO0FBQ2IsYUFBVyxPQUFPLEtBQUs7QUFDbkIsUUFBSSxDQUFDLEtBQUssU0FBUyxHQUFHLEdBQUc7QUFFckIsVUFBSSxHQUFHLElBQUksSUFBSSxHQUFHO0FBQUEsSUFDdEI7QUFBQSxFQUNKO0FBQ0EsU0FBTztBQUNYO0FBT0EsU0FBUyxhQUFhLFNBQVM7QUFDM0IsUUFBTSxVQUFVLG9CQUFvQixRQUFRLFFBQVEsT0FBTztBQUMzRCxRQUFNLGVBQWUsUUFBUSxjQUFjO0FBQzNDLFFBQU0sbUJBQW1CLFFBQVEsa0JBQWtCO0FBQ25ELFFBQU0sZ0JBQWdCLFFBQVE7QUFDOUIsTUFBK0MsQ0FBQztBQUM1QyxVQUFNLElBQUksTUFBTSxnSUFDeUQ7QUFDN0UsUUFBTSxlQUFlLGFBQWE7QUFDbEMsUUFBTSxzQkFBc0IsYUFBYTtBQUN6QyxRQUFNLGNBQWMsYUFBYTtBQUNqQyxRQUFNLGVBQWUsV0FBVyx5QkFBeUI7QUFDekQsTUFBSSxrQkFBa0I7QUFFdEIsTUFBSSxhQUFhLFFBQVEsa0JBQWtCLHVCQUF1QixTQUFTO0FBQ3ZFLFlBQVEsb0JBQW9CO0FBQUEsRUFDaEM7QUFDQSxRQUFNLGtCQUFrQixjQUFjLEtBQUssTUFBTSxnQkFBYyxLQUFLLFVBQVU7QUFDOUUsUUFBTSxlQUFlLGNBQWMsS0FBSyxNQUFNLFdBQVc7QUFDekQsUUFBTTtBQUFBO0FBQUEsSUFFTixjQUFjLEtBQUssTUFBTSxNQUFNO0FBQUE7QUFDL0IsV0FBUyxTQUFTLGVBQWUsT0FBTztBQUNwQyxRQUFJO0FBQ0osUUFBSTtBQUNKLFFBQUksWUFBWSxhQUFhLEdBQUc7QUFDNUIsZUFBUyxRQUFRLGlCQUFpQixhQUFhO0FBQy9DLFVBQStDLENBQUMsUUFBUTtBQUNwRCxhQUFLLGlCQUFpQixPQUFPLGFBQWEsQ0FBQyx1Q0FBdUMsS0FBSztBQUFBLE1BQzNGO0FBQ0EsZUFBUztBQUFBLElBQ2IsT0FDSztBQUNELGVBQVM7QUFBQSxJQUNiO0FBQ0EsV0FBTyxRQUFRLFNBQVMsUUFBUSxNQUFNO0FBQUEsRUFDMUM7QUFDQSxXQUFTLFlBQVksTUFBTTtBQUN2QixVQUFNLGdCQUFnQixRQUFRLGlCQUFpQixJQUFJO0FBQ25ELFFBQUksZUFBZTtBQUNmLGNBQVEsWUFBWSxhQUFhO0FBQUEsSUFDckMsV0FDVSxNQUF3QztBQUM5QyxXQUFLLHFDQUFxQyxPQUFPLElBQUksQ0FBQyxHQUFHO0FBQUEsSUFDN0Q7QUFBQSxFQUNKO0FBQ0EsV0FBUyxZQUFZO0FBQ2pCLFdBQU8sUUFBUSxVQUFVLEVBQUUsSUFBSSxrQkFBZ0IsYUFBYSxNQUFNO0FBQUEsRUFDdEU7QUFDQSxXQUFTLFNBQVMsTUFBTTtBQUNwQixXQUFPLENBQUMsQ0FBQyxRQUFRLGlCQUFpQixJQUFJO0FBQUEsRUFDMUM7QUFDQSxXQUFTLFFBQVEsYUFBYSxpQkFBaUI7QUFJM0Msc0JBQWtCLE9BQU8sQ0FBQyxHQUFHLG1CQUFtQixhQUFhLEtBQUs7QUFDbEUsUUFBSSxPQUFPLGdCQUFnQixVQUFVO0FBQ2pDLFlBQU0scUJBQXFCLFNBQVMsY0FBYyxhQUFhLGdCQUFnQixJQUFJO0FBQ25GLFlBQU1DLGdCQUFlLFFBQVEsUUFBUSxFQUFFLE1BQU0sbUJBQW1CLEtBQUssR0FBRyxlQUFlO0FBQ3ZGLFlBQU1DLFFBQU8sY0FBYyxXQUFXLG1CQUFtQixRQUFRO0FBQ2pFLFVBQUssTUFBd0M7QUFDekMsWUFBSUEsTUFBSyxXQUFXLElBQUk7QUFDcEIsZUFBSyxhQUFhLFdBQVcsa0JBQWtCQSxLQUFJLDREQUE0RDtBQUFBLGlCQUMxRyxDQUFDRCxjQUFhLFFBQVEsUUFBUTtBQUNuQyxlQUFLLDBDQUEwQyxXQUFXLEdBQUc7QUFBQSxRQUNqRTtBQUFBLE1BQ0o7QUFFQSxhQUFPLE9BQU8sb0JBQW9CQSxlQUFjO0FBQUEsUUFDNUMsUUFBUSxhQUFhQSxjQUFhLE1BQU07QUFBQSxRQUN4QyxNQUFNLE9BQU8sbUJBQW1CLElBQUk7QUFBQSxRQUNwQyxnQkFBZ0I7QUFBQSxRQUNoQixNQUFBQztBQUFBLE1BQ0osQ0FBQztBQUFBLElBQ0w7QUFDQSxRQUErQyxDQUFDLGdCQUFnQixXQUFXLEdBQUc7QUFDMUUsV0FBSztBQUFBLGNBQStGLFdBQVc7QUFDL0csYUFBTyxRQUFRLENBQUMsQ0FBQztBQUFBLElBQ3JCO0FBQ0EsUUFBSTtBQUVKLFFBQUksWUFBWSxRQUFRLE1BQU07QUFDMUIsVUFDSSxZQUFZLGVBQ1osRUFBRSxVQUFVO0FBQUEsTUFFWixPQUFPLEtBQUssWUFBWSxNQUFNLEVBQUUsUUFBUTtBQUN4QyxhQUFLLFNBQVMsWUFBWSxJQUFJLGdHQUFnRztBQUFBLE1BQ2xJO0FBQ0Esd0JBQWtCLE9BQU8sQ0FBQyxHQUFHLGFBQWE7QUFBQSxRQUN0QyxNQUFNLFNBQVMsY0FBYyxZQUFZLE1BQU0sZ0JBQWdCLElBQUksRUFBRTtBQUFBLE1BQ3pFLENBQUM7QUFBQSxJQUNMLE9BQ0s7QUFFRCxZQUFNLGVBQWUsT0FBTyxDQUFDLEdBQUcsWUFBWSxNQUFNO0FBQ2xELGlCQUFXLE9BQU8sY0FBYztBQUM1QixZQUFJLGFBQWEsR0FBRyxLQUFLLE1BQU07QUFDM0IsaUJBQU8sYUFBYSxHQUFHO0FBQUEsUUFDM0I7QUFBQSxNQUNKO0FBRUEsd0JBQWtCLE9BQU8sQ0FBQyxHQUFHLGFBQWE7QUFBQSxRQUN0QyxRQUFRLGFBQWEsWUFBWTtBQUFBLE1BQ3JDLENBQUM7QUFHRCxzQkFBZ0IsU0FBUyxhQUFhLGdCQUFnQixNQUFNO0FBQUEsSUFDaEU7QUFDQSxVQUFNLGVBQWUsUUFBUSxRQUFRLGlCQUFpQixlQUFlO0FBQ3JFLFVBQU0sT0FBTyxZQUFZLFFBQVE7QUFDakMsUUFBK0MsUUFBUSxDQUFDLEtBQUssV0FBVyxHQUFHLEdBQUc7QUFDMUUsV0FBSyxtRUFBbUUsSUFBSSxZQUFZLElBQUksSUFBSTtBQUFBLElBQ3BHO0FBR0EsaUJBQWEsU0FBUyxnQkFBZ0IsYUFBYSxhQUFhLE1BQU0sQ0FBQztBQUN2RSxVQUFNLFdBQVcsYUFBYSxrQkFBa0IsT0FBTyxDQUFDLEdBQUcsYUFBYTtBQUFBLE1BQ3BFLE1BQU0sV0FBVyxJQUFJO0FBQUEsTUFDckIsTUFBTSxhQUFhO0FBQUEsSUFDdkIsQ0FBQyxDQUFDO0FBQ0YsVUFBTSxPQUFPLGNBQWMsV0FBVyxRQUFRO0FBQzlDLFFBQUssTUFBd0M7QUFDekMsVUFBSSxLQUFLLFdBQVcsSUFBSSxHQUFHO0FBQ3ZCLGFBQUssYUFBYSxXQUFXLGtCQUFrQixJQUFJLDREQUE0RDtBQUFBLE1BQ25ILFdBQ1MsQ0FBQyxhQUFhLFFBQVEsUUFBUTtBQUNuQyxhQUFLLDBDQUEwQyxZQUFZLFFBQVEsT0FBTyxZQUFZLE9BQU8sV0FBVyxHQUFHO0FBQUEsTUFDL0c7QUFBQSxJQUNKO0FBQ0EsV0FBTyxPQUFPO0FBQUEsTUFDVjtBQUFBO0FBQUE7QUFBQSxNQUdBO0FBQUEsTUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxRQU1BLHFCQUFxQixpQkFDZixlQUFlLFlBQVksS0FBSyxJQUMvQixZQUFZLFNBQVMsQ0FBQztBQUFBO0FBQUEsSUFDakMsR0FBRyxjQUFjO0FBQUEsTUFDYixnQkFBZ0I7QUFBQSxNQUNoQjtBQUFBLElBQ0osQ0FBQztBQUFBLEVBQ0w7QUFDQSxXQUFTLGlCQUFpQixJQUFJO0FBQzFCLFdBQU8sT0FBTyxPQUFPLFdBQ2YsU0FBUyxjQUFjLElBQUksYUFBYSxNQUFNLElBQUksSUFDbEQsT0FBTyxDQUFDLEdBQUcsRUFBRTtBQUFBLEVBQ3ZCO0FBQ0EsV0FBUyx3QkFBd0IsSUFBSSxNQUFNO0FBQ3ZDLFFBQUksb0JBQW9CLElBQUk7QUFDeEIsYUFBTyxrQkFBa0IsR0FBeUM7QUFBQSxRQUM5RDtBQUFBLFFBQ0E7QUFBQSxNQUNKLENBQUM7QUFBQSxJQUNMO0FBQUEsRUFDSjtBQUNBLFdBQVMsS0FBSyxJQUFJO0FBQ2QsV0FBTyxpQkFBaUIsRUFBRTtBQUFBLEVBQzlCO0FBQ0EsV0FBUyxRQUFRLElBQUk7QUFDakIsV0FBTyxLQUFLLE9BQU8saUJBQWlCLEVBQUUsR0FBRyxFQUFFLFNBQVMsS0FBSyxDQUFDLENBQUM7QUFBQSxFQUMvRDtBQUNBLFdBQVMscUJBQXFCLElBQUk7QUFDOUIsVUFBTSxjQUFjLEdBQUcsUUFBUSxHQUFHLFFBQVEsU0FBUyxDQUFDO0FBQ3BELFFBQUksZUFBZSxZQUFZLFVBQVU7QUFDckMsWUFBTSxFQUFFLFNBQVMsSUFBSTtBQUNyQixVQUFJLG9CQUFvQixPQUFPLGFBQWEsYUFBYSxTQUFTLEVBQUUsSUFBSTtBQUN4RSxVQUFJLE9BQU8sc0JBQXNCLFVBQVU7QUFDdkMsNEJBQ0ksa0JBQWtCLFNBQVMsR0FBRyxLQUFLLGtCQUFrQixTQUFTLEdBQUcsSUFDMUQsb0JBQW9CLGlCQUFpQixpQkFBaUI7QUFBQTtBQUFBLFVBRXJELEVBQUUsTUFBTSxrQkFBa0I7QUFBQTtBQUd0QywwQkFBa0IsU0FBUyxDQUFDO0FBQUEsTUFDaEM7QUFDQSxVQUNJLGtCQUFrQixRQUFRLFFBQzFCLEVBQUUsVUFBVSxvQkFBb0I7QUFDaEMsYUFBSztBQUFBLEVBQTRCLEtBQUssVUFBVSxtQkFBbUIsTUFBTSxDQUFDLENBQUM7QUFBQSx1QkFBMEIsR0FBRyxRQUFRLDJFQUEyRTtBQUMzTCxjQUFNLElBQUksTUFBTSxrQkFBa0I7QUFBQSxNQUN0QztBQUNBLGFBQU8sT0FBTztBQUFBLFFBQ1YsT0FBTyxHQUFHO0FBQUEsUUFDVixNQUFNLEdBQUc7QUFBQTtBQUFBLFFBRVQsUUFBUSxrQkFBa0IsUUFBUSxPQUFPLENBQUMsSUFBSSxHQUFHO0FBQUEsTUFDckQsR0FBRyxpQkFBaUI7QUFBQSxJQUN4QjtBQUFBLEVBQ0o7QUFDQSxXQUFTLGlCQUFpQixJQUFJLGdCQUFnQjtBQUMxQyxVQUFNLGlCQUFrQixrQkFBa0IsUUFBUSxFQUFFO0FBQ3BELFVBQU0sT0FBTyxhQUFhO0FBQzFCLFVBQU0sT0FBTyxHQUFHO0FBQ2hCLFVBQU0sUUFBUSxHQUFHO0FBRWpCLFVBQU1OLFdBQVUsR0FBRyxZQUFZO0FBQy9CLFVBQU0saUJBQWlCLHFCQUFxQixjQUFjO0FBQzFELFFBQUk7QUFDQSxhQUFPO0FBQUEsUUFBaUIsT0FBTyxpQkFBaUIsY0FBYyxHQUFHO0FBQUEsVUFDN0QsT0FBTyxPQUFPLG1CQUFtQixXQUMzQixPQUFPLENBQUMsR0FBRyxNQUFNLGVBQWUsS0FBSyxJQUNyQztBQUFBLFVBQ047QUFBQSxVQUNBLFNBQUFBO0FBQUEsUUFDSixDQUFDO0FBQUE7QUFBQSxRQUVELGtCQUFrQjtBQUFBLE1BQWM7QUFFcEMsVUFBTSxhQUFhO0FBQ25CLGVBQVcsaUJBQWlCO0FBQzVCLFFBQUk7QUFDSixRQUFJLENBQUMsU0FBUyxvQkFBb0Isa0JBQWtCLE1BQU0sY0FBYyxHQUFHO0FBQ3ZFLGdCQUFVLGtCQUFrQixJQUEyQyxFQUFFLElBQUksWUFBWSxLQUFLLENBQUM7QUFFL0Y7QUFBQSxRQUFhO0FBQUEsUUFBTTtBQUFBO0FBQUE7QUFBQSxRQUduQjtBQUFBO0FBQUE7QUFBQSxRQUdBO0FBQUEsTUFBSztBQUFBLElBQ1Q7QUFDQSxZQUFRLFVBQVUsUUFBUSxRQUFRLE9BQU8sSUFBSSxTQUFTLFlBQVksSUFBSSxHQUNqRSxNQUFNLENBQUMsVUFBVSxvQkFBb0IsS0FBSztBQUFBO0FBQUEsTUFFdkM7QUFBQSxRQUFvQjtBQUFBLFFBQU87QUFBQTtBQUFBLE1BQTRDLElBQ2pFLFFBQ0EsWUFBWSxLQUFLO0FBQUE7QUFBQTtBQUFBLE1BRXZCLGFBQWEsT0FBTyxZQUFZLElBQUk7QUFBQSxLQUFDLEVBQ3hDLEtBQUssQ0FBQ08sYUFBWTtBQUNuQixVQUFJQSxVQUFTO0FBQ1QsWUFBSTtBQUFBLFVBQW9CQTtBQUFBLFVBQVM7QUFBQTtBQUFBLFFBQTRDLEdBQUc7QUFDNUU7QUFBQSxVQUVJLG9CQUFvQixrQkFBa0IsUUFBUUEsU0FBUSxFQUFFLEdBQUcsVUFBVTtBQUFBLFVBRXJFO0FBQUEsV0FFQyxlQUFlLFNBQVMsZUFBZTtBQUFBO0FBQUEsWUFFaEMsZUFBZSxTQUFTO0FBQUEsY0FDMUIsS0FBSyxJQUFJO0FBQ2YsaUJBQUssbUZBQW1GLEtBQUssUUFBUSxTQUFTLFdBQVcsUUFBUTtBQUFBLGdOQUF5UDtBQUMxWCxtQkFBTyxRQUFRLE9BQU8sSUFBSSxNQUFNLHVDQUF1QyxDQUFDO0FBQUEsVUFDNUU7QUFDQSxpQkFBTztBQUFBO0FBQUEsWUFFUCxPQUFPO0FBQUE7QUFBQSxjQUVILFNBQUFQO0FBQUEsWUFDSixHQUFHLGlCQUFpQk8sU0FBUSxFQUFFLEdBQUc7QUFBQSxjQUM3QixPQUFPLE9BQU9BLFNBQVEsT0FBTyxXQUN2QixPQUFPLENBQUMsR0FBRyxNQUFNQSxTQUFRLEdBQUcsS0FBSyxJQUNqQztBQUFBLGNBQ047QUFBQSxZQUNKLENBQUM7QUFBQTtBQUFBLFlBRUQsa0JBQWtCO0FBQUEsVUFBVTtBQUFBLFFBQ2hDO0FBQUEsTUFDSixPQUNLO0FBRUQsUUFBQUEsV0FBVSxtQkFBbUIsWUFBWSxNQUFNLE1BQU1QLFVBQVMsSUFBSTtBQUFBLE1BQ3RFO0FBQ0EsdUJBQWlCLFlBQVksTUFBTU8sUUFBTztBQUMxQyxhQUFPQTtBQUFBLElBQ1gsQ0FBQztBQUFBLEVBQ0w7QUFNQSxXQUFTLGlDQUFpQyxJQUFJLE1BQU07QUFDaEQsVUFBTSxRQUFRLHdCQUF3QixJQUFJLElBQUk7QUFDOUMsV0FBTyxRQUFRLFFBQVEsT0FBTyxLQUFLLElBQUksUUFBUSxRQUFRO0FBQUEsRUFDM0Q7QUFDQSxXQUFTLGVBQWUsSUFBSTtBQUN4QixVQUFNLE1BQU0sY0FBYyxPQUFPLEVBQUUsS0FBSyxFQUFFO0FBRTFDLFdBQU8sT0FBTyxPQUFPLElBQUksbUJBQW1CLGFBQ3RDLElBQUksZUFBZSxFQUFFLElBQ3JCLEdBQUc7QUFBQSxFQUNiO0FBRUEsV0FBUyxTQUFTLElBQUksTUFBTTtBQUN4QixRQUFJO0FBQ0osVUFBTSxDQUFDLGdCQUFnQixpQkFBaUIsZUFBZSxJQUFJLHVCQUF1QixJQUFJLElBQUk7QUFFMUYsYUFBUyx3QkFBd0IsZUFBZSxRQUFRLEdBQUcsb0JBQW9CLElBQUksSUFBSTtBQUV2RixlQUFXLFVBQVUsZ0JBQWdCO0FBQ2pDLGFBQU8sWUFBWSxRQUFRLFdBQVM7QUFDaEMsZUFBTyxLQUFLLGlCQUFpQixPQUFPLElBQUksSUFBSSxDQUFDO0FBQUEsTUFDakQsQ0FBQztBQUFBLElBQ0w7QUFDQSxVQUFNLDBCQUEwQixpQ0FBaUMsS0FBSyxNQUFNLElBQUksSUFBSTtBQUNwRixXQUFPLEtBQUssdUJBQXVCO0FBRW5DLFdBQVEsY0FBYyxNQUFNLEVBQ3ZCLEtBQUssTUFBTTtBQUVaLGVBQVMsQ0FBQztBQUNWLGlCQUFXLFNBQVMsYUFBYSxLQUFLLEdBQUc7QUFDckMsZUFBTyxLQUFLLGlCQUFpQixPQUFPLElBQUksSUFBSSxDQUFDO0FBQUEsTUFDakQ7QUFDQSxhQUFPLEtBQUssdUJBQXVCO0FBQ25DLGFBQU8sY0FBYyxNQUFNO0FBQUEsSUFDL0IsQ0FBQyxFQUNJLEtBQUssTUFBTTtBQUVaLGVBQVMsd0JBQXdCLGlCQUFpQixxQkFBcUIsSUFBSSxJQUFJO0FBQy9FLGlCQUFXLFVBQVUsaUJBQWlCO0FBQ2xDLGVBQU8sYUFBYSxRQUFRLFdBQVM7QUFDakMsaUJBQU8sS0FBSyxpQkFBaUIsT0FBTyxJQUFJLElBQUksQ0FBQztBQUFBLFFBQ2pELENBQUM7QUFBQSxNQUNMO0FBQ0EsYUFBTyxLQUFLLHVCQUF1QjtBQUVuQyxhQUFPLGNBQWMsTUFBTTtBQUFBLElBQy9CLENBQUMsRUFDSSxLQUFLLE1BQU07QUFFWixlQUFTLENBQUM7QUFDVixpQkFBVyxVQUFVLGlCQUFpQjtBQUVsQyxZQUFJLE9BQU8sYUFBYTtBQUNwQixjQUFJLFFBQVEsT0FBTyxXQUFXLEdBQUc7QUFDN0IsdUJBQVcsZUFBZSxPQUFPO0FBQzdCLHFCQUFPLEtBQUssaUJBQWlCLGFBQWEsSUFBSSxJQUFJLENBQUM7QUFBQSxVQUMzRCxPQUNLO0FBQ0QsbUJBQU8sS0FBSyxpQkFBaUIsT0FBTyxhQUFhLElBQUksSUFBSSxDQUFDO0FBQUEsVUFDOUQ7QUFBQSxRQUNKO0FBQUEsTUFDSjtBQUNBLGFBQU8sS0FBSyx1QkFBdUI7QUFFbkMsYUFBTyxjQUFjLE1BQU07QUFBQSxJQUMvQixDQUFDLEVBQ0ksS0FBSyxNQUFNO0FBR1osU0FBRyxRQUFRLFFBQVEsWUFBVyxPQUFPLGlCQUFpQixDQUFDLENBQUU7QUFFekQsZUFBUyx3QkFBd0IsaUJBQWlCLG9CQUFvQixJQUFJLE1BQU0sY0FBYztBQUM5RixhQUFPLEtBQUssdUJBQXVCO0FBRW5DLGFBQU8sY0FBYyxNQUFNO0FBQUEsSUFDL0IsQ0FBQyxFQUNJLEtBQUssTUFBTTtBQUVaLGVBQVMsQ0FBQztBQUNWLGlCQUFXLFNBQVMsb0JBQW9CLEtBQUssR0FBRztBQUM1QyxlQUFPLEtBQUssaUJBQWlCLE9BQU8sSUFBSSxJQUFJLENBQUM7QUFBQSxNQUNqRDtBQUNBLGFBQU8sS0FBSyx1QkFBdUI7QUFDbkMsYUFBTyxjQUFjLE1BQU07QUFBQSxJQUMvQixDQUFDLEVBRUksTUFBTSxTQUFPO0FBQUEsTUFBb0I7QUFBQSxNQUFLO0FBQUE7QUFBQSxJQUF1QyxJQUM1RSxNQUNBLFFBQVEsT0FBTyxHQUFHLENBQUM7QUFBQSxFQUM3QjtBQUNBLFdBQVMsaUJBQWlCLElBQUksTUFBTSxTQUFTO0FBR3pDLGdCQUNLLEtBQUssRUFDTCxRQUFRLFdBQVMsZUFBZSxNQUFNLE1BQU0sSUFBSSxNQUFNLE9BQU8sQ0FBQyxDQUFDO0FBQUEsRUFDeEU7QUFNQSxXQUFTLG1CQUFtQixZQUFZLE1BQU0sUUFBUVAsVUFBUyxNQUFNO0FBRWpFLFVBQU0sUUFBUSx3QkFBd0IsWUFBWSxJQUFJO0FBQ3RELFFBQUk7QUFDQSxhQUFPO0FBRVgsVUFBTSxvQkFBb0IsU0FBUztBQUNuQyxVQUFNLFFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxRQUFRO0FBR3hDLFFBQUksUUFBUTtBQUdSLFVBQUlBLFlBQVc7QUFDWCxzQkFBYyxRQUFRLFdBQVcsVUFBVSxPQUFPO0FBQUEsVUFDOUMsUUFBUSxxQkFBcUIsU0FBUyxNQUFNO0FBQUEsUUFDaEQsR0FBRyxJQUFJLENBQUM7QUFBQTtBQUVSLHNCQUFjLEtBQUssV0FBVyxVQUFVLElBQUk7QUFBQSxJQUNwRDtBQUVBLGlCQUFhLFFBQVE7QUFDckIsaUJBQWEsWUFBWSxNQUFNLFFBQVEsaUJBQWlCO0FBQ3hELGdCQUFZO0FBQUEsRUFDaEI7QUFDQSxNQUFJO0FBRUosV0FBUyxpQkFBaUI7QUFFdEIsUUFBSTtBQUNBO0FBQ0osNEJBQXdCLGNBQWMsT0FBTyxDQUFDLElBQUksT0FBTyxTQUFTO0FBQzlELFVBQUksQ0FBQyxPQUFPO0FBQ1I7QUFFSixZQUFNLGFBQWEsUUFBUSxFQUFFO0FBSTdCLFlBQU0saUJBQWlCLHFCQUFxQixVQUFVO0FBQ3RELFVBQUksZ0JBQWdCO0FBQ2hCLHlCQUFpQixPQUFPLGdCQUFnQixFQUFFLFNBQVMsTUFBTSxPQUFPLEtBQUssQ0FBQyxHQUFHLFVBQVUsRUFBRSxNQUFNLElBQUk7QUFDL0Y7QUFBQSxNQUNKO0FBQ0Esd0JBQWtCO0FBQ2xCLFlBQU0sT0FBTyxhQUFhO0FBRTFCLFVBQUksV0FBVztBQUNYLDJCQUFtQixhQUFhLEtBQUssVUFBVSxLQUFLLEtBQUssR0FBRyxzQkFBc0IsQ0FBQztBQUFBLE1BQ3ZGO0FBQ0EsZUFBUyxZQUFZLElBQUksRUFDcEIsTUFBTSxDQUFDLFVBQVU7QUFDbEIsWUFBSTtBQUFBLFVBQW9CO0FBQUEsVUFBTyxJQUF3QztBQUFBO0FBQUEsUUFBdUMsR0FBRztBQUM3RyxpQkFBTztBQUFBLFFBQ1g7QUFDQSxZQUFJO0FBQUEsVUFBb0I7QUFBQSxVQUFPO0FBQUE7QUFBQSxRQUE0QyxHQUFHO0FBVTFFO0FBQUEsWUFBaUIsT0FBTyxpQkFBaUIsTUFBTSxFQUFFLEdBQUc7QUFBQSxjQUNoRCxPQUFPO0FBQUEsWUFDWCxDQUFDO0FBQUEsWUFBRztBQUFBO0FBQUEsVUFFSixFQUNLLEtBQUssYUFBVztBQUlqQixnQkFBSTtBQUFBLGNBQW9CO0FBQUEsY0FBUyxJQUM3QjtBQUFBO0FBQUEsWUFBeUMsS0FDekMsQ0FBQyxLQUFLLFNBQ04sS0FBSyxTQUFTLGVBQWUsS0FBSztBQUNsQyw0QkFBYyxHQUFHLElBQUksS0FBSztBQUFBLFlBQzlCO0FBQUEsVUFDSixDQUFDLEVBQ0ksTUFBTSxJQUFJO0FBRWYsaUJBQU8sUUFBUSxPQUFPO0FBQUEsUUFDMUI7QUFFQSxZQUFJLEtBQUssT0FBTztBQUNaLHdCQUFjLEdBQUcsQ0FBQyxLQUFLLE9BQU8sS0FBSztBQUFBLFFBQ3ZDO0FBRUEsZUFBTyxhQUFhLE9BQU8sWUFBWSxJQUFJO0FBQUEsTUFDL0MsQ0FBQyxFQUNJLEtBQUssQ0FBQyxZQUFZO0FBQ25CLGtCQUNJLFdBQ0k7QUFBQTtBQUFBLFVBRUE7QUFBQSxVQUFZO0FBQUEsVUFBTTtBQUFBLFFBQUs7QUFFL0IsWUFBSSxTQUFTO0FBQ1QsY0FBSSxLQUFLO0FBQUE7QUFBQSxVQUdMLENBQUM7QUFBQSxZQUFvQjtBQUFBLFlBQVM7QUFBQTtBQUFBLFVBQXVDLEdBQUc7QUFDeEUsMEJBQWMsR0FBRyxDQUFDLEtBQUssT0FBTyxLQUFLO0FBQUEsVUFDdkMsV0FDUyxLQUFLLFNBQVMsZUFBZSxPQUNsQztBQUFBLFlBQW9CO0FBQUEsWUFBUyxJQUF3QztBQUFBO0FBQUEsVUFBeUMsR0FBRztBQUdqSCwwQkFBYyxHQUFHLElBQUksS0FBSztBQUFBLFVBQzlCO0FBQUEsUUFDSjtBQUNBLHlCQUFpQixZQUFZLE1BQU0sT0FBTztBQUFBLE1BQzlDLENBQUMsRUFFSSxNQUFNLElBQUk7QUFBQSxJQUNuQixDQUFDO0FBQUEsRUFDTDtBQUVBLE1BQUksZ0JBQWdCLGFBQWE7QUFDakMsTUFBSSxpQkFBaUIsYUFBYTtBQUNsQyxNQUFJO0FBU0osV0FBUyxhQUFhLE9BQU8sSUFBSSxNQUFNO0FBQ25DLGdCQUFZLEtBQUs7QUFDakIsVUFBTSxPQUFPLGVBQWUsS0FBSztBQUNqQyxRQUFJLEtBQUssUUFBUTtBQUNiLFdBQUssUUFBUSxhQUFXLFFBQVEsT0FBTyxJQUFJLElBQUksQ0FBQztBQUFBLElBQ3BELE9BQ0s7QUFDRCxVQUFLLE1BQXdDO0FBQ3pDLGFBQUsseUNBQXlDO0FBQUEsTUFDbEQ7QUFDQSxjQUFRLE1BQU0sS0FBSztBQUFBLElBQ3ZCO0FBRUEsV0FBTyxRQUFRLE9BQU8sS0FBSztBQUFBLEVBQy9CO0FBQ0EsV0FBUyxVQUFVO0FBQ2YsUUFBSSxTQUFTLGFBQWEsVUFBVTtBQUNoQyxhQUFPLFFBQVEsUUFBUTtBQUMzQixXQUFPLElBQUksUUFBUSxDQUFDUSxVQUFTLFdBQVc7QUFDcEMsb0JBQWMsSUFBSSxDQUFDQSxVQUFTLE1BQU0sQ0FBQztBQUFBLElBQ3ZDLENBQUM7QUFBQSxFQUNMO0FBQ0EsV0FBUyxZQUFZLEtBQUs7QUFDdEIsUUFBSSxDQUFDLE9BQU87QUFFUixjQUFRLENBQUM7QUFDVCxxQkFBZTtBQUNmLG9CQUNLLEtBQUssRUFDTCxRQUFRLENBQUMsQ0FBQ0EsVUFBUyxNQUFNLE1BQU8sTUFBTSxPQUFPLEdBQUcsSUFBSUEsU0FBUSxDQUFFO0FBQ25FLG9CQUFjLE1BQU07QUFBQSxJQUN4QjtBQUNBLFdBQU87QUFBQSxFQUNYO0FBRUEsV0FBUyxhQUFhLElBQUksTUFBTSxRQUFRLG1CQUFtQjtBQUN2RCxVQUFNLEVBQUUsZUFBZSxJQUFJO0FBQzNCLFFBQUksQ0FBQyxhQUFhLENBQUM7QUFDZixhQUFPLFFBQVEsUUFBUTtBQUMzQixVQUFNLGlCQUFrQixDQUFDLFVBQVUsdUJBQXVCLGFBQWEsR0FBRyxVQUFVLENBQUMsQ0FBQyxNQUNoRixxQkFBcUIsQ0FBQyxXQUNwQixRQUFRLFNBQ1IsUUFBUSxNQUFNLFVBQ2xCO0FBQ0osV0FBTyxTQUFTLEVBQ1gsS0FBSyxNQUFNLGVBQWUsSUFBSSxNQUFNLGNBQWMsQ0FBQyxFQUNuRCxLQUFLLGNBQVksWUFBWSxpQkFBaUIsUUFBUSxDQUFDLEVBQ3ZELE1BQU0sU0FBTyxhQUFhLEtBQUssSUFBSSxJQUFJLENBQUM7QUFBQSxFQUNqRDtBQUNBLFFBQU0sS0FBSyxDQUFDLFVBQVUsY0FBYyxHQUFHLEtBQUs7QUFDNUMsTUFBSTtBQUNKLFFBQU0sZ0JBQWdCLG9CQUFJLElBQUk7QUFDOUIsUUFBTSxTQUFTO0FBQUEsSUFDWDtBQUFBLElBQ0EsV0FBVztBQUFBLElBQ1g7QUFBQSxJQUNBO0FBQUEsSUFDQSxhQUFhLFFBQVE7QUFBQSxJQUNyQjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0EsTUFBTSxNQUFNLEdBQUcsRUFBRTtBQUFBLElBQ2pCLFNBQVMsTUFBTSxHQUFHLENBQUM7QUFBQSxJQUNuQixZQUFZLGFBQWE7QUFBQSxJQUN6QixlQUFlLG9CQUFvQjtBQUFBLElBQ25DLFdBQVcsWUFBWTtBQUFBLElBQ3ZCLFNBQVMsZUFBZTtBQUFBLElBQ3hCO0FBQUEsSUFDQSxRQUFRLEtBQUs7QUFDVCxZQUFNQyxVQUFTO0FBQ2YsVUFBSSxVQUFVLGNBQWMsVUFBVTtBQUN0QyxVQUFJLFVBQVUsY0FBYyxVQUFVO0FBQ3RDLFVBQUksT0FBTyxpQkFBaUIsVUFBVUE7QUFDdEMsYUFBTyxlQUFlLElBQUksT0FBTyxrQkFBa0IsVUFBVTtBQUFBLFFBQ3pELFlBQVk7QUFBQSxRQUNaLEtBQUssTUFBTSxNQUFNLFlBQVk7QUFBQSxNQUNqQyxDQUFDO0FBSUQsVUFBSTtBQUFBO0FBQUEsTUFHQSxDQUFDLFdBQ0QsYUFBYSxVQUFVLDJCQUEyQjtBQUVsRCxrQkFBVTtBQUNWLGFBQUssY0FBYyxRQUFRLEVBQUUsTUFBTSxTQUFPO0FBQ3RDLGNBQUs7QUFDRCxpQkFBSyw4Q0FBOEMsR0FBRztBQUFBLFFBQzlELENBQUM7QUFBQSxNQUNMO0FBQ0EsWUFBTSxnQkFBZ0IsQ0FBQztBQUN2QixpQkFBVyxPQUFPLDJCQUEyQjtBQUN6QyxlQUFPLGVBQWUsZUFBZSxLQUFLO0FBQUEsVUFDdEMsS0FBSyxNQUFNLGFBQWEsTUFBTSxHQUFHO0FBQUEsVUFDakMsWUFBWTtBQUFBLFFBQ2hCLENBQUM7QUFBQSxNQUNMO0FBQ0EsVUFBSSxRQUFRLFdBQVdBLE9BQU07QUFDN0IsVUFBSSxRQUFRLGtCQUFrQixnQkFBZ0IsYUFBYSxDQUFDO0FBQzVELFVBQUksUUFBUSx1QkFBdUIsWUFBWTtBQUMvQyxZQUFNLGFBQWEsSUFBSTtBQUN2QixvQkFBYyxJQUFJLEdBQUc7QUFDckIsVUFBSSxVQUFVLFdBQVk7QUFDdEIsc0JBQWMsT0FBTyxHQUFHO0FBRXhCLFlBQUksY0FBYyxPQUFPLEdBQUc7QUFFeEIsNEJBQWtCO0FBQ2xCLG1DQUF5QixzQkFBc0I7QUFDL0Msa0NBQXdCO0FBQ3hCLHVCQUFhLFFBQVE7QUFDckIsb0JBQVU7QUFDVixrQkFBUTtBQUFBLFFBQ1o7QUFDQSxtQkFBVztBQUFBLE1BQ2Y7QUFFQSxVQUEwRSxXQUFXO0FBQ2pGLG9CQUFZLEtBQUtBLFNBQVEsT0FBTztBQUFBLE1BQ3BDO0FBQUEsSUFDSjtBQUFBLEVBQ0o7QUFFQSxXQUFTLGNBQWMsUUFBUTtBQUMzQixXQUFPLE9BQU8sT0FBTyxDQUFDLFNBQVMsVUFBVSxRQUFRLEtBQUssTUFBTSxlQUFlLEtBQUssQ0FBQyxHQUFHLFFBQVEsUUFBUSxDQUFDO0FBQUEsRUFDekc7QUFDQSxTQUFPO0FBQ1g7QUFDQSxTQUFTLHVCQUF1QixJQUFJLE1BQU07QUFDdEMsUUFBTSxpQkFBaUIsQ0FBQztBQUN4QixRQUFNLGtCQUFrQixDQUFDO0FBQ3pCLFFBQU0sa0JBQWtCLENBQUM7QUFDekIsUUFBTSxNQUFNLEtBQUssSUFBSSxLQUFLLFFBQVEsUUFBUSxHQUFHLFFBQVEsTUFBTTtBQUMzRCxXQUFTLElBQUksR0FBRyxJQUFJLEtBQUssS0FBSztBQUMxQixVQUFNLGFBQWEsS0FBSyxRQUFRLENBQUM7QUFDakMsUUFBSSxZQUFZO0FBQ1osVUFBSSxHQUFHLFFBQVEsS0FBSyxZQUFVLGtCQUFrQixRQUFRLFVBQVUsQ0FBQztBQUMvRCx3QkFBZ0IsS0FBSyxVQUFVO0FBQUE7QUFFL0IsdUJBQWUsS0FBSyxVQUFVO0FBQUEsSUFDdEM7QUFDQSxVQUFNLFdBQVcsR0FBRyxRQUFRLENBQUM7QUFDN0IsUUFBSSxVQUFVO0FBRVYsVUFBSSxDQUFDLEtBQUssUUFBUSxLQUFLLFlBQVUsa0JBQWtCLFFBQVEsUUFBUSxDQUFDLEdBQUc7QUFDbkUsd0JBQWdCLEtBQUssUUFBUTtBQUFBLE1BQ2pDO0FBQUEsSUFDSjtBQUFBLEVBQ0o7QUFDQSxTQUFPLENBQUMsZ0JBQWdCLGlCQUFpQixlQUFlO0FBQzVEO0FBTUEsU0FBUyxZQUFZO0FBQ2pCLFNBQU8sT0FBTyxTQUFTO0FBQzNCO0FBS0EsU0FBUyxTQUFTLE9BQU87QUFDckIsU0FBTyxPQUFPLGdCQUFnQjtBQUNsQztBQUVBLFNBQVMsdUJBQXVCLFlBQVksWUFBWSw2QkFBNkIsZ0JBQWdCLHFCQUFxQixjQUFjLHFCQUFxQixzQkFBc0Isa0JBQWtCLHFCQUFxQixtQkFBbUIsaUJBQWlCLG9CQUFvQixxQkFBcUIsWUFBWSxrQkFBa0IsV0FBVyx1QkFBdUIsZ0JBQWdCLFNBQVMsVUFBVSxXQUFXOyIsIm5hbWVzIjpbInBhcnNlUXVlcnkiLCJsb2NhdGlvbiIsInN0cmluZ2lmeVF1ZXJ5IiwiTmF2aWdhdGlvblR5cGUiLCJOYXZpZ2F0aW9uRGlyZWN0aW9uIiwiaGlzdG9yeSIsInJlcGxhY2UiLCJOYXZpZ2F0aW9uRmFpbHVyZVR5cGUiLCJyZSIsInZhbHVlIiwicm91dGUiLCJtYXRjaGVkUm91dGUiLCJocmVmIiwiZmFpbHVyZSIsInJlc29sdmUiLCJyb3V0ZXIiXSwieF9nb29nbGVfaWdub3JlTGlzdCI6WzBdfQ==