1
0
Fork 0
digital-art-composition-book/.obsidian/plugins/multi-column-markdown/main.js
2024-09-14 11:25:13 -04:00

6556 lines
1 MiB

/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/
'use strict';
var obsidian = require('obsidian');
var state = require('@codemirror/state');
var view = require('@codemirror/view');
var language = require('@codemirror/language');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function getStyle(element, property) {
var _a;
const view = ((_a = element.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) || window;
const style = view.getComputedStyle(element);
return (style.getPropertyValue(property) || style[property]);
}
const PIXELS_PER_INCH = 96;
const MILLIMETRES_PER_INCH = 25.4;
const POINTS_PER_INCH = 72;
const PICAS_PER_INCH = 6;
function fontSize(element) {
return element
? getStyle(element, 'fontSize') || fontSize(element.parentElement)
: getStyle(window.document.documentElement, 'fontSize');
}
function parse(providedLength) {
var _a;
const length = providedLength || '0';
const value = parseFloat(length);
const match = length.match(/[\d-.]+(\w+)$/);
const unit = (_a = match === null || match === void 0 ? void 0 : match[1]) !== null && _a !== void 0 ? _a : '';
return [value, unit.toLowerCase()];
}
function pixels(length, element) {
var _a, _b;
const view = (_b = (_a = element === null || element === void 0 ? void 0 : element.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) !== null && _b !== void 0 ? _b : window;
const root = view.document.documentElement || view.document.body;
const [value, unit] = parse(length);
switch (unit) {
case 'rem':
return value * pixels(fontSize(window.document.documentElement));
case 'em':
return value * pixels(fontSize(element), element === null || element === void 0 ? void 0 : element.parentElement);
case 'in':
return value * PIXELS_PER_INCH;
case 'q':
return (value * PIXELS_PER_INCH) / MILLIMETRES_PER_INCH / 4;
case 'mm':
return (value * PIXELS_PER_INCH) / MILLIMETRES_PER_INCH;
case 'cm':
return (value * PIXELS_PER_INCH * 10) / MILLIMETRES_PER_INCH;
case 'pt':
return (value * PIXELS_PER_INCH) / POINTS_PER_INCH;
case 'pc':
return (value * PIXELS_PER_INCH) / PICAS_PER_INCH;
case 'vh':
return (value * view.innerHeight || root.clientWidth) / 100;
case 'vw':
return (value * view.innerWidth || root.clientHeight) / 100;
case 'vmin':
return ((value *
Math.min(view.innerWidth || root.clientWidth, view.innerHeight || root.clientHeight)) /
100);
case 'vmax':
return ((value *
Math.max(view.innerWidth || root.clientWidth, view.innerHeight || root.clientHeight)) /
100);
default:
return value;
}
}
/**
* File: /src/utilities/interfaces.ts *
* Author: Cameron Robinson *
* *
* Copyright (c) 2023 Cameron Robinson *
*/
class HTMLSizing {
get sizeValue() {
return this._sizeValue;
}
set sizeValue(value) {
this._sizeValue = value;
}
constructor(value, units) {
this._sizeValue = 0;
this.widthSet = false;
this.sizeUnits = "px";
this.sizeValue = value;
this.sizeUnits = units;
}
setWidth(value) {
this.widthSet = true;
return new HTMLSizing(value, this.sizeUnits);
}
setUnits(units) {
return new HTMLSizing(this.sizeValue, units);
}
toString() {
return `${this.sizeValue}${this.sizeUnits}`;
}
convertToPX(parentElement) {
if (this.sizeUnits === "px") {
return this;
}
switch (this.sizeUnits) {
case "cm":
case "mm":
case "in":
case "pt":
case "pc":
let absUnitsResult = pixels(`${this.toString()}`);
return new HTMLSizing(absUnitsResult, "px");
case "vw":
case "vh":
return handleViewportSizing();
case "em":
return getFontSizeFromEl();
case "ch":
let ch = createEl("p", {
"attr": { "style": "width: 1ch;" }
});
return getSizeFromStyleWidth(ch);
case "ex":
let ex = createEl("p", {
"attr": { "style": "width: 1ex;" }
});
return getSizeFromStyleWidth(ex);
}
function getSizeFromStyleWidth(el) {
const DEFAULT_SIZE = 16;
if (parentElement === null ||
parentElement === undefined) {
return new HTMLSizing(this.sizeValue * DEFAULT_SIZE, "px");
}
parentElement.appendChild(el);
let exToPxResult = this.sizeValue * el.clientWidth;
if (el.clientWidth === 0) {
exToPxResult = this.sizeValue * DEFAULT_SIZE;
}
parentElement.removeChild(el);
return new HTMLSizing(exToPxResult, "px");
}
function getFontSizeFromEl() {
const DEFAULT_SIZE = 16;
let fontSize = DEFAULT_SIZE;
let emToPxResult = fontSize * this.sizeValue;
if (parentElement === null ||
parentElement === undefined) {
return new HTMLSizing(emToPxResult, "px");
}
let sizing = HTMLSizing.parseToSizing(parentElement.getCssPropertyValue("font-size"));
if (sizing !== null) {
fontSize = sizing.sizeValue;
emToPxResult = fontSize * this.sizeValue;
}
return new HTMLSizing(emToPxResult, "px");
}
function handleViewportSizing() {
let scale = this.sizeValue / 100;
if (parentElement === null || parentElement === undefined) {
console.warn("Found undefined root element. Using default client size. Result may not appear as intended.");
let defaultSizing = scale * 1200;
return new HTMLSizing(defaultSizing, "px");
}
let viewWidth = parentElement.clientWidth;
let viewHeight = parentElement.clientHeight;
switch (this.sizeUnits) {
case "vw":
let wToPxResult = scale * viewWidth;
return new HTMLSizing(wToPxResult, "px");
case "vh":
case "%":
let hToPxResult = scale * viewHeight;
return new HTMLSizing(hToPxResult, "px");
}
}
}
static create() {
return new HTMLSizing(0, "px");
}
static parseToSizing(sizingText) {
if (sizingText === "") {
return null;
}
let unitData = HTMLSizing.getLengthUnit(sizingText);
if (unitData.isValid === true) {
let units = unitData.unitStr;
let sizeText = sizingText.replace(units, "").trim();
let size = parseInt(sizeText);
if (isNaN(size)) {
return null;
}
return HTMLSizing.create().setWidth(size).setUnits(units);
}
return null;
}
static getLengthUnit(lengthStr) {
let lastChar = lengthStr.slice(lengthStr.length - 1);
let lastTwoChars = lengthStr.slice(lengthStr.length - 2);
let unitStr = "";
let isValid = false;
if (lastChar === "%") {
unitStr = lastChar;
isValid = true;
}
else if (lastTwoChars === "cm" ||
lastTwoChars === "mm" ||
lastTwoChars === "in" ||
lastTwoChars === "px" ||
lastTwoChars === "pt" ||
lastTwoChars === "pc" ||
lastTwoChars === "em" ||
lastTwoChars === "ex" ||
lastTwoChars === "ch" ||
lastTwoChars === "vw" ||
lastTwoChars === "vh") {
unitStr = lastTwoChars;
isValid = true;
}
return { isValid: isValid, unitStr: unitStr };
}
}
addEventListener("mousedown", () => {
});
addEventListener("mouseup", () => {
});
function defaultStartRegionData() {
return {
found: false,
startPosition: -1,
endPosition: -1,
matchLength: 0,
regionType: "CODEBLOCK"
};
}
/*
* Filename: multi-column-markdown/src/regionSettings.ts
* Created Date: Tuesday, February 1st 2022, 12:23:53 pm
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
var BorderOption;
(function (BorderOption) {
BorderOption[BorderOption["enabled"] = 0] = "enabled";
BorderOption[BorderOption["on"] = 1] = "on";
BorderOption[BorderOption["true"] = 2] = "true";
BorderOption[BorderOption["disabled"] = 3] = "disabled";
BorderOption[BorderOption["off"] = 4] = "off";
BorderOption[BorderOption["false"] = 5] = "false";
})(BorderOption || (BorderOption = {}));
var ShadowOption;
(function (ShadowOption) {
ShadowOption[ShadowOption["enabled"] = 0] = "enabled";
ShadowOption[ShadowOption["on"] = 1] = "on";
ShadowOption[ShadowOption["true"] = 2] = "true";
ShadowOption[ShadowOption["disabled"] = 3] = "disabled";
ShadowOption[ShadowOption["off"] = 4] = "off";
ShadowOption[ShadowOption["false"] = 5] = "false";
})(ShadowOption || (ShadowOption = {}));
var TableAlignOption;
(function (TableAlignOption) {
TableAlignOption[TableAlignOption["enabled"] = 0] = "enabled";
TableAlignOption[TableAlignOption["on"] = 1] = "on";
TableAlignOption[TableAlignOption["true"] = 2] = "true";
TableAlignOption[TableAlignOption["disabled"] = 3] = "disabled";
TableAlignOption[TableAlignOption["off"] = 4] = "off";
TableAlignOption[TableAlignOption["false"] = 5] = "false";
})(TableAlignOption || (TableAlignOption = {}));
const ALL_LAYOUTS = [
"standard",
"left",
"first",
"center",
"middle",
"second",
"right",
"third",
"last"
];
function isColumnLayout(value) {
return ALL_LAYOUTS.includes(value.toLowerCase());
}
function validateColumnLayout(value) {
return value.toLowerCase();
}
var ContentOverflowType;
(function (ContentOverflowType) {
ContentOverflowType[ContentOverflowType["scroll"] = 0] = "scroll";
ContentOverflowType[ContentOverflowType["hidden"] = 1] = "hidden";
})(ContentOverflowType || (ContentOverflowType = {}));
var AlignmentType;
(function (AlignmentType) {
AlignmentType[AlignmentType["left"] = 0] = "left";
AlignmentType[AlignmentType["center"] = 1] = "center";
AlignmentType[AlignmentType["right"] = 2] = "right";
})(AlignmentType || (AlignmentType = {}));
var TableAlignment;
(function (TableAlignment) {
TableAlignment[TableAlignment["useSettingsDefault"] = 0] = "useSettingsDefault";
TableAlignment[TableAlignment["align"] = 1] = "align";
TableAlignment[TableAlignment["noAlign"] = 2] = "noAlign";
})(TableAlignment || (TableAlignment = {}));
function MCSettings_isEqual(settingsA, settingsB) {
if ((settingsA === null || settingsA === void 0 ? void 0 : settingsA.columnID) !== (settingsB === null || settingsB === void 0 ? void 0 : settingsB.columnID)) {
return false;
}
if ((settingsA === null || settingsA === void 0 ? void 0 : settingsA.numberOfColumns) !== (settingsB === null || settingsB === void 0 ? void 0 : settingsB.numberOfColumns)) {
return false;
}
if (JSON.stringify(settingsA === null || settingsA === void 0 ? void 0 : settingsA.drawBorder) !== JSON.stringify(settingsB === null || settingsB === void 0 ? void 0 : settingsB.drawBorder)) {
return false;
}
if ((settingsA === null || settingsA === void 0 ? void 0 : settingsA.drawShadow) !== (settingsB === null || settingsB === void 0 ? void 0 : settingsB.drawShadow)) {
return false;
}
if ((settingsA === null || settingsA === void 0 ? void 0 : settingsA.autoLayout) !== (settingsB === null || settingsB === void 0 ? void 0 : settingsB.autoLayout)) {
return false;
}
if (JSON.stringify(settingsA === null || settingsA === void 0 ? void 0 : settingsA.columnSize) !== JSON.stringify(settingsB === null || settingsB === void 0 ? void 0 : settingsB.columnSize)) {
return false;
}
if ((settingsA === null || settingsA === void 0 ? void 0 : settingsA.columnPosition) !== (settingsB === null || settingsB === void 0 ? void 0 : settingsB.columnPosition)) {
return false;
}
if (JSON.stringify(settingsA === null || settingsA === void 0 ? void 0 : settingsA.columnSpacing) !== JSON.stringify(settingsB === null || settingsB === void 0 ? void 0 : settingsB.columnSpacing)) {
return false;
}
if (JSON.stringify(settingsA === null || settingsA === void 0 ? void 0 : settingsA.contentOverflow) !== JSON.stringify(settingsB === null || settingsB === void 0 ? void 0 : settingsB.contentOverflow)) {
return false;
}
if (JSON.stringify(settingsA === null || settingsA === void 0 ? void 0 : settingsA.alignment) !== JSON.stringify(settingsB === null || settingsB === void 0 ? void 0 : settingsB.alignment)) {
return false;
}
if ((settingsA === null || settingsA === void 0 ? void 0 : settingsA.columnHeight) !== (settingsB === null || settingsB === void 0 ? void 0 : settingsB.columnHeight)) {
return false;
}
if ((settingsA === null || settingsA === void 0 ? void 0 : settingsA.fullDocReflow) !== (settingsB === null || settingsB === void 0 ? void 0 : settingsB.fullDocReflow)) {
return false;
}
if ((settingsA === null || settingsA === void 0 ? void 0 : settingsA.alignTablesToAlignment) !== (settingsB === null || settingsB === void 0 ? void 0 : settingsB.alignTablesToAlignment)) {
return false;
}
return true;
}
function getDefaultMultiColumnSettings() {
return {
columnID: "",
numberOfColumns: 2,
drawBorder: [true],
drawShadow: true,
autoLayout: false,
columnSize: "standard",
columnPosition: "standard",
columnSpacing: [""],
contentOverflow: [ContentOverflowType.scroll],
alignment: [AlignmentType.left],
columnHeight: null,
fullDocReflow: false,
alignTablesToAlignment: TableAlignment.useSettingsDefault
};
}
function shouldDrawColumnBorder(index, settings) {
if (settings.drawBorder.length === 0) {
return true;
}
return getIndexedClampedArrayValue(index, settings.drawBorder);
}
function columnOverflowState(index, settings) {
if (settings.contentOverflow.length === 0) {
return ContentOverflowType.scroll;
}
return getIndexedClampedArrayValue(index, settings.contentOverflow);
}
function columnAlignmentState(index, settings) {
if (settings.alignment.length === 0) {
return AlignmentType.left;
}
return getIndexedClampedArrayValue(index, settings.alignment);
}
function columnSpacingState(index, settings) {
if (settings.columnSpacing.length === 0) {
return "";
}
return `margin-inline: ${getIndexedClampedArrayValue(index, settings.columnSpacing)};`;
}
function getIndexedClampedArrayValue(index, arr) {
if (arr.length === 0) {
throw ("Error getting value from empty array.");
}
if (index < 0) {
return arr[0];
}
if (index < arr.length) {
return arr[index];
}
return arr.last();
}
/**
* File: /src/utilities/settingsParser.ts
* Created Date: Friday, June 3rd 2022, 8:16 pm
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
/**
* Here we define all of the valid settings strings that the user can enter for each setting type.
* The strings are then mapped twice, first to a valid regex string that searches for the setting
* name, ignoring all extra spaces and letter case, and then maped to a RegEx object to be used
* when parsing.
*/
const COL_POSITION_OPTION_STRS = [
"column position",
"col position",
"column location",
"col location",
"single column location",
"single column position",
];
const COL_POSITION_REGEX_ARR = COL_POSITION_OPTION_STRS.map(convertStringToSettingsRegex).map((value) => {
return new RegExp(value, "i");
});
const COL_SIZE_OPTION_STRS = [
"column size",
"column width",
"col size",
"col width",
"single column size",
"single col size",
"single column width",
"single col width",
"largest column"
];
const COL_SIZE_OPTION_REGEX_ARR = COL_SIZE_OPTION_STRS.map(convertStringToSettingsRegex).map((value) => {
return new RegExp(value, "i");
});
const NUMBER_OF_COLUMNS_STRS = [
"number of columns",
"num of cols",
"col count",
"column count"
];
const NUMBER_OF_COLUMNS_REGEX_ARR = NUMBER_OF_COLUMNS_STRS.map(convertStringToSettingsRegex).map((value) => {
return new RegExp(value, "i");
});
const DRAW_BORDER_STRS = [
"border"
];
const DRAW_BORDER_REGEX_ARR = DRAW_BORDER_STRS.map(convertStringToSettingsRegex).map((value) => {
return new RegExp(value, "i");
});
const DRAW_SHADOW_STRS = [
"shadow"
];
const DRAW_SHADOW_REGEX_ARR = DRAW_SHADOW_STRS.map(convertStringToSettingsRegex).map((value) => {
return new RegExp(value, "i");
});
const AUTO_LAYOUT_SETTING_STRS = [
"auto layout",
"fluid div",
"fluid divs",
"fluid columns",
"fluid cols",
"fluid col"
];
const AUTO_LAYOUT_REGEX_ARR = AUTO_LAYOUT_SETTING_STRS.map(convertStringToSettingsRegex).map((value) => {
return new RegExp(value, "i");
});
const COLUMN_SPACING_REGEX_ARR = [
"column spacing",
"column gap",
"column sep"
].map((value) => {
return new RegExp(convertStringToSettingsRegex(value), "i");
});
const COLUMN_HEIGHT_REGEX_ARR = [
"column height",
"col height",
"column max height",
"col max height",
"max column height",
"max col height"
].map((value) => {
return new RegExp(convertStringToSettingsRegex(value), "i");
});
const CONTENT_OVERFLOW_REGEX_ARR = [
"overflow",
"content overflow"
].map((value) => {
return new RegExp(convertStringToSettingsRegex(value), "i");
});
const ALIGNMENT_REGEX_ARR = [
"alignment",
"content alignment",
"align",
"content align",
"align content",
"text align",
"align text",
"Text Alignment"
].map((value) => {
return new RegExp(convertStringToSettingsRegex(value), "i");
});
const TABLE_ALIGNMENT_REGEX_ARR = [
"align tables to text alignment"
].map((value) => {
return new RegExp(convertStringToSettingsRegex(value), "i");
});
/**
* This function searches the settings string through each regex option. If one of the regex
* values match, it returns the first group found by the regex. This is depended on proper
* regex formatting which is done by the convertStringToSettingsRegex function defined below.
*
* @param settingsString The value that may match one of the setting options.
* @param validSettingFormatRegEx The settings options through which to check all options. If one of these regex
* values match on the string we break from the loop returning the found value.
*
* @returns the user entered data if the setting is a match, or null if non of the options matched.
*/
function getSettingsDataFromKeys(settingsString, validSettingFormatRegEx) {
for (let i = 0; i < validSettingFormatRegEx.length; i++) {
let regexSearchData = validSettingFormatRegEx[i].exec(settingsString);
if (regexSearchData !== null) {
return regexSearchData[1].trim();
}
}
return null;
}
function parseSingleColumnSettings(settingsStr, originalSettings) {
originalSettings.columnSize = "medium";
let settingsLines = settingsStr.split("\n");
for (let i = 0; i < settingsLines.length; i++) {
let settingsLine = settingsLines[i];
let settingsData = getSettingsDataFromKeys(settingsLine, COL_POSITION_REGEX_ARR);
if (settingsData !== null) {
originalSettings.columnPosition = parseForSingleColumnLocation(settingsData);
}
settingsData = getSettingsDataFromKeys(settingsLine, COL_SIZE_OPTION_REGEX_ARR);
if (settingsData !== null) {
originalSettings.columnSize = parseForSingleColumnSize(settingsData);
}
}
return originalSettings;
}
function parseColumnSettings(settingsStr) {
let parsedSettings = getDefaultMultiColumnSettings();
let settingsLines = settingsStr.split("\n");
for (let i = 0; i < settingsLines.length; i++) {
let settingsLine = settingsLines[i];
checkSettingIsRegionID(settingsLine, parsedSettings);
checkSettingIsNumberOfColumns(settingsLine, parsedSettings);
checkSettingDefinesColumnSize(settingsLine, parsedSettings);
checkSettingIsDrawBorder(settingsLine, parsedSettings);
checkSettingIsDrawShadow(settingsLine, parsedSettings);
checkSettingIsAutoLayout(settingsLine, parsedSettings);
checkSettingIsColumnSpacing(settingsLine, parsedSettings);
checkSettingIsContentOverflow(settingsLine, parsedSettings);
checkSettingIsColumnAlignment(settingsLine, parsedSettings);
checkSettingIsColumnHeight(settingsLine, parsedSettings);
checkSettingIsTableAlignment(settingsLine, parsedSettings);
}
return parsedSettings;
}
function checkSettingIsNumberOfColumns(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, NUMBER_OF_COLUMNS_REGEX_ARR);
if (settingsData === null) {
return;
}
let settingValues = parseForMultiSettings(settingsData);
settingsData = settingValues[0];
let numOfCols = parseInt(settingsData);
if (Number.isNaN(numOfCols) === false) {
if (numOfCols >= 1) {
parsedSettings.numberOfColumns = numOfCols;
}
}
}
function checkSettingIsRegionID(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, CODEBLOCK_REGION_ID_REGEX_ARR);
if (settingsData === null) {
return;
}
parsedSettings.columnID = settingsData;
}
function checkSettingDefinesColumnSize(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, COL_SIZE_OPTION_REGEX_ARR);
if (settingsData === null) {
return;
}
let settingValues = parseForMultiSettings(settingsData);
if (settingValues.length === 1) {
// If there is only 1 item we attempt to parse out a layout type. If we get a valid item we
// return here.
if (isColumnLayout(settingValues[0])) {
parsedSettings.columnSize = validateColumnLayout(settingValues[0]);
return;
}
}
let widths = [];
for (let setting of settingValues) {
let parsed = HTMLSizing.parseToSizing(setting.trim());
if (parsed !== null) {
widths.push(parsed);
}
}
// If none are parsed properly to a width then we return a default.
if (widths.length === 0) {
console.warn("Error parsing column layout or width, defaulting to standard layout.");
parsedSettings.columnSize = "standard";
return;
}
// If we parsed some lengths and some did not parse properly, the user has either
// poorly defined their settings or is attempting to break us. Take the first valid option
// between the two arrays.
if (widths.length !== settingValues.length) {
for (let setting of settingValues) {
let unitData = HTMLSizing.getLengthUnit(setting);
if (unitData.isValid === true) {
parsedSettings.columnSize = widths;
return;
}
if (isColumnLayout(settingValues[0])) {
parsedSettings.columnSize = validateColumnLayout(settingValues[0]);
return;
}
}
}
parsedSettings.columnSize = widths;
}
function checkSettingIsDrawBorder(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, DRAW_BORDER_REGEX_ARR);
if (settingsData === null) {
return;
}
let borders = [];
let settingValues = parseForMultiSettings(settingsData);
for (let settingsData of settingValues) {
let borderState = true;
let isBorderDrawn = BorderOption[settingsData];
if (isBorderDrawn !== undefined) {
switch (isBorderDrawn) {
case (BorderOption.disabled):
case (BorderOption.off):
case (BorderOption.false):
borderState = false;
break;
}
}
borders.push(borderState);
}
parsedSettings.drawBorder = borders;
}
function checkSettingIsDrawShadow(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, DRAW_SHADOW_REGEX_ARR);
if (settingsData === null) {
return;
}
let settingValues = parseForMultiSettings(settingsData);
settingsData = settingValues[0];
let isShadowDrawn = ShadowOption[settingsData];
if (isShadowDrawn !== undefined) {
switch (isShadowDrawn) {
case (ShadowOption.disabled):
case (ShadowOption.off):
case (ShadowOption.false):
parsedSettings.drawShadow = false;
break;
}
}
}
function checkSettingIsAutoLayout(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, AUTO_LAYOUT_REGEX_ARR);
if (settingsData === null) {
return;
}
let settingValues = parseForMultiSettings(settingsData);
settingsData = settingValues[0];
if (settingsData === "false" ||
settingsData === "off") {
parsedSettings.autoLayout = false;
}
parsedSettings.autoLayout = true;
}
function checkSettingIsColumnSpacing(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, COLUMN_SPACING_REGEX_ARR);
if (settingsData === null) {
return;
}
let spacings = [];
let settingValues = parseForMultiSettings(settingsData);
for (let settingsData of settingValues) {
let parsed = HTMLSizing.parseToSizing(settingsData.trim());
let spacingStr = "";
if (parsed !== null) {
spacingStr = parsed.toString();
}
else {
let noUnitsNum = parseInt(settingsData.trim());
if (isNaN(noUnitsNum) === false) {
spacingStr = `${noUnitsNum}pt`;
}
}
spacings.push(spacingStr);
}
parsedSettings.columnSpacing = spacings;
}
function checkSettingIsContentOverflow(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, CONTENT_OVERFLOW_REGEX_ARR);
if (settingsData === null) {
return;
}
let overflowStates = [];
let settingValues = parseForMultiSettings(settingsData);
for (let settingsData of settingValues) {
let overflowType = ContentOverflowType.scroll;
settingsData = settingsData.toLowerCase().trim();
if (settingsData === "hidden") {
overflowType = ContentOverflowType.hidden;
}
overflowStates.push(overflowType);
}
parsedSettings.contentOverflow = overflowStates;
}
function checkSettingIsColumnAlignment(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, ALIGNMENT_REGEX_ARR);
if (settingsData === null) {
return;
}
let alignments = [];
let settingValues = parseForMultiSettings(settingsData);
for (let settingsData of settingValues) {
let alignmentType = AlignmentType.left;
settingsData = settingsData.toLowerCase().trim();
if (settingsData === "center") {
alignmentType = AlignmentType.center;
}
if (settingsData === "right") {
alignmentType = AlignmentType.right;
}
alignments.push(alignmentType);
}
parsedSettings.alignment = alignments;
}
function checkSettingIsTableAlignment(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, TABLE_ALIGNMENT_REGEX_ARR);
if (settingsData === null) {
return;
}
let settingValues = parseForMultiSettings(settingsData);
settingsData = settingValues[0];
let tableAlignment = TableAlignOption[settingsData];
if (tableAlignment !== undefined) {
switch (tableAlignment) {
case (TableAlignOption.disabled):
case (TableAlignOption.off):
case (TableAlignOption.false):
parsedSettings.alignTablesToAlignment = TableAlignment.noAlign;
break;
default:
parsedSettings.alignTablesToAlignment = TableAlignment.align;
}
}
}
function checkSettingIsColumnHeight(settingsLine, parsedSettings) {
let settingsData = getSettingsDataFromKeys(settingsLine, COLUMN_HEIGHT_REGEX_ARR);
if (settingsData === null) {
return;
}
let settingValues = parseForMultiSettings(settingsData);
settingsData = settingValues[0];
let parsed = HTMLSizing.parseToSizing(settingsData.trim());
if (parsed !== null) {
parsedSettings.columnHeight = parsed;
}
else {
let noUnitsNum = parseInt(settingsData.trim());
if (isNaN(noUnitsNum) === false) {
parsedSettings.columnHeight = HTMLSizing.create().setWidth(noUnitsNum).setUnits("pt");
}
}
}
function parseForMultiSettings(originalValue) {
// Parse off brackets. If no brackets we return original value to be parsed as sole value.
let result = /\[(.*)\]/.exec(originalValue);
if (result === null) {
return [originalValue];
}
let settingsList = result[1];
let settings = settingsList.split(",").map((val) => {
return val.trim();
});
return settings;
}
const CODEBLOCK_REGION_ID_REGEX_STRS = [
"id",
"region id"
];
const CODEBLOCK_REGION_ID_REGEX_ARR = CODEBLOCK_REGION_ID_REGEX_STRS.map(convertStringToSettingsRegex).map((value) => {
return new RegExp(value, "i");
});
function parseStartRegionCodeBlockID(settingsStr) {
let codeBlockRegionID = "";
let settingsLines = settingsStr.split("\n");
for (let i = 0; i < settingsLines.length; i++) {
let settingsLine = settingsLines[i];
let settingsData = getSettingsDataFromKeys(settingsLine, CODEBLOCK_REGION_ID_REGEX_ARR);
if (settingsData !== null) {
codeBlockRegionID = settingsData;
}
}
return codeBlockRegionID;
}
function parseForSingleColumnLocation(locationString) {
switch (locationString.toLowerCase().trim().replace(" ", "")) {
case "left":
case "leftside":
case "leftmargin":
case "leftalign":
case "leftaligned":
case "leftalignement":
case "first":
case "start":
case "beginning":
return "left";
case "middle":
case "middlealigned":
case "middlealignment":
case "center":
case "centeraligned":
case "centeralignment":
case "centered":
case "standard":
return "center";
case "right":
case "rightside":
case "rightmargin":
case "rightalign":
case "rightaligned":
case "rightalignment":
case "last":
case "end":
return "right";
}
return "center";
}
function parseForSingleColumnSize(sizeString) {
switch (sizeString = sizeString.toLowerCase().trim().replace(" ", "")) {
case "small":
case "sm":
return "small";
case "medium":
case "med":
return "medium";
case "large":
case "lg":
return "large";
case "full":
case "full size":
return "full";
}
return "medium";
}
function convertStringToSettingsRegex(originalString) {
originalString = originalString.replace(" ", "(?:[-_]| *|)");
let regexString = `(?:${originalString} *[:=] *)(.*)`;
return regexString;
}
const PANDOC_ENGLISH_NUMBER_OF_COLUMNS = [
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten"
];
function isPandocNumberOfColumns(value) {
return PANDOC_ENGLISH_NUMBER_OF_COLUMNS.includes(value);
}
function validatePandocNumberOfColumns(value) {
return value.toLowerCase();
}
function pandocNumberOfColumnsToValue(value) {
switch (value) {
case "two":
return 2;
case "three":
return 3;
case "four":
return 4;
case "five":
return 5;
case "six":
return 6;
case "seven":
return 7;
case "eight":
return 8;
case "nine":
return 9;
case "ten":
return 10;
}
}
const PANDOC_COL_DOT_COUNT_NAME = "colDotCount";
const PANDOC_COL_NODOT_COUNT_NAME = "colCount";
const PANDOC_COl_SETTINGS = "colSettings";
const PANDOC_REGEX_STR = (() => {
let nums = PANDOC_ENGLISH_NUMBER_OF_COLUMNS.join("|");
let regex_strings = `:{3,} *(?:\\{ *\\.(?<${PANDOC_COL_DOT_COUNT_NAME}>(?:${nums}|))(?:[-_]|)columns(?<${PANDOC_COl_SETTINGS}>.*)\\}|(?<${PANDOC_COL_NODOT_COUNT_NAME}>(?:${nums}|))(?:[-_]|)columns)(?:[ :]*)$\\n?`;
return regex_strings;
})();
const PANDOC_REGEX = new RegExp(PANDOC_REGEX_STR, "m");
const PANDOC_OPEN_FENCE_REGEX = /^:{3,} *(?:[a-zA-Z]+|\{.*\})(?:[ :]*)$/m;
const PANDOC_CLOSE_FENCE_REGEX = /^:{3,} *$/m;
function findPandoc(text) {
let regexData = PANDOC_REGEX.exec(text);
if (regexData !== null) {
let data = defaultPandocRegexData();
data.found = true;
data.startPosition = regexData.index;
data.endPosition = regexData.index + regexData[0].length;
let regionData = reducePandocRegionToEndDiv(text.slice(data.endPosition));
data.endPosition += regionData.content.length + regionData.matchLength;
data.content = regionData.content;
data.matchLength = data.endPosition - data.startPosition;
data.userSettings = regexData.groups[PANDOC_COl_SETTINGS] ? regexData.groups[PANDOC_COl_SETTINGS] : "";
data.columnCount = regexData.groups[PANDOC_COL_DOT_COUNT_NAME] ? regexData.groups[PANDOC_COL_DOT_COUNT_NAME] : regexData.groups[PANDOC_COL_NODOT_COUNT_NAME];
return data;
}
return defaultPandocRegexData();
}
function getPandocStartData(text) {
let data = findPandoc(text);
if (data.found === false) {
return {
found: false,
userSettings: getDefaultMultiColumnSettings()
};
}
return {
found: true,
userSettings: parsePandocSettings(data.userSettings, data.columnCount)
};
}
function containsPandoc(text) {
return findPandoc(text).found;
}
function containsPandocStartTag(text) {
let regexData = PANDOC_REGEX.exec(text);
if (regexData !== null) {
return true;
}
return false;
}
function containsPandocEndTag(text) {
let regexData = PANDOC_CLOSE_FENCE_REGEX.exec(text);
if (regexData !== null) {
return true;
}
return false;
}
function isValidPandocEndTag(linesAbove, currentLine) {
if (containsPandocEndTag(currentLine) === false) {
return false;
}
let contentText = linesAbove.concat(currentLine).join("\n");
return reducePandocRegionToEndDiv(contentText).found;
}
function reducePandocRegionToEndDiv(contentText) {
let workingText = contentText;
let result = {
found: false,
content: workingText,
matchLength: 0
};
let state = 0;
let offset = 0;
for (let i = 0; true; i++) {
if (i > 100) {
break;
}
let fence = getNextPandocFence(workingText);
if (fence === null) {
break;
}
let result = fence.result;
if (fence.type === "close") {
// console.log(workingText.slice(result.index, result.index + result[0].length));
offset += (result.index + result[0].length);
state--;
}
else {
// console.log(workingText.slice(result.index, result.index + result[0].length));
offset += (result.index + result[0].length);
state++;
}
if (state === -1) {
// We have found our last close tag.
return buildReturnData(result);
}
workingText = contentText.slice(offset);
}
function buildReturnData(matchResult) {
result.content = contentText.slice(0, offset - matchResult[0].length);
result.matchLength = matchResult[0].length;
result.found = true;
return result;
}
return result;
}
function getNextPandocFence(workingText) {
let openResult = PANDOC_OPEN_FENCE_REGEX.exec(workingText);
let closeResult = PANDOC_CLOSE_FENCE_REGEX.exec(workingText);
if (openResult === null && closeResult === null) {
return null;
}
if (openResult === null && closeResult !== null) {
return {
result: closeResult,
type: "close"
};
}
if (closeResult === null && openResult !== null) {
return {
result: openResult,
type: "open"
};
}
if (closeResult.index < openResult.index) {
return {
result: closeResult,
type: "close"
};
}
else {
return {
result: openResult,
type: "open"
};
}
}
function findPandocStart(text) {
let startRegion = defaultStartRegionData();
startRegion.regionType = "PADOC";
let regexData = PANDOC_REGEX.exec(text);
if (regexData !== null && regexData.length > 0) {
startRegion.found = true;
startRegion.startPosition = regexData.index;
startRegion.matchLength = regexData[0].length;
startRegion.endPosition = startRegion.startPosition + startRegion.matchLength;
}
return startRegion;
}
function defaultPandocRegexData() {
return {
found: false,
startPosition: -1,
endPosition: -1,
matchLength: 0,
content: "",
userSettings: "",
columnCount: "",
regionType: "PADOC"
};
}
const PANDOC_SETTING_REGEX = /(?<settingName>[^ ]*)=(?<settingValue>".*"|[^ =]*)/;
function parsePandocSettings(pandocUserSettings, colCount = "") {
//TODO: Add option for column rule.
let defaultSettings = getDefaultMultiColumnSettings();
let colCountDefined = false;
if (colCount !== "" && isPandocNumberOfColumns(colCount)) {
colCountDefined = true;
defaultSettings.numberOfColumns = pandocNumberOfColumnsToValue(validatePandocNumberOfColumns(colCount));
}
if (pandocUserSettings.replace(" ", "") === "") {
return defaultSettings;
}
let workingString = pandocUserSettings;
let regexValue = PANDOC_SETTING_REGEX.exec(workingString);
let settingList = "";
for (let i = 0; regexValue !== null; i < 100) {
let settingName = regexValue.groups['settingName'];
let settingValue = regexValue.groups['settingValue'];
settingList += `${settingName}: ${settingValue}\n`;
workingString = workingString.slice(regexValue.index + regexValue[0].length);
regexValue = PANDOC_SETTING_REGEX.exec(workingString);
}
let parsedSettings = parseColumnSettings(settingList);
if (colCountDefined) {
parsedSettings.numberOfColumns = defaultSettings.numberOfColumns;
}
return parsedSettings;
}
/*
* File: multi-column-markdown/src/MultiColumnParser.ts
* Created Date: Saturday, January 22nd 2022, 6:02:46 pm
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
const START_REGEX_STRS = ["(===|---) *start-multi-column(:?[a-zA-Z0-9-_\\s]*)?",
"(===|---) *multi-column-start(:?[a-zA-Z0-9-_\\s]*)?"];
const START_REGEX_ARR = [];
for (let i = 0; i < START_REGEX_STRS.length; i++) {
START_REGEX_ARR.push(new RegExp(START_REGEX_STRS[i]));
}
const START_REGEX_STRS_WHOLE_LINE = ["^(===|---) *start-multi-column(:?[a-zA-Z0-9-_\\s]*)?$",
"^(===|---) *multi-column-start(:?[a-zA-Z0-9-_\\s]*)?$"];
const START_REGEX_ARR_WHOLE_LINE = [];
for (let i = 0; i < START_REGEX_STRS_WHOLE_LINE.length; i++) {
START_REGEX_ARR_WHOLE_LINE.push(new RegExp(START_REGEX_STRS_WHOLE_LINE[i]));
}
function findStartTag(text) {
let startRegion = defaultStartRegionData();
startRegion.regionType = "ORIGINAL";
for (let i = 0; i < START_REGEX_ARR.length; i++) {
let regexData = START_REGEX_ARR[i].exec(text);
if (regexData !== null && regexData.length > 0) {
startRegion.startPosition = regexData.index;
startRegion.matchLength = regexData[0].length;
startRegion.endPosition = startRegion.startPosition + startRegion.matchLength;
let line = text.slice(startRegion.startPosition, startRegion.endPosition);
if (START_REGEX_ARR_WHOLE_LINE[i].test(line)) {
startRegion.found = true;
break;
}
}
}
return startRegion;
}
function containsStartTag(text) {
return findStartTag(text).found;
}
function isStartTagWithID(text) {
let startTagData = findStartTag(text);
if (startTagData.found === true) {
let key = getStartTagKey(text);
if (key === null || key === "") {
return { isStartTag: true, hasKey: false };
}
return { isStartTag: true, hasKey: true };
}
return { isStartTag: false, hasKey: false };
}
const END_REGEX_STRS = ["--- *end-multi-column",
"--- *multi-column-end",
"=== *end-multi-column",
"=== *multi-column-end"];
const END_REGEX_ARR = [];
for (let i = 0; i < END_REGEX_STRS.length; i++) {
END_REGEX_ARR.push(new RegExp(END_REGEX_STRS[i]));
}
function findEndTag(text) {
// We want to find the first end tag in the text.
// So here we loop backwards, slicing off the tail until
// there are no more end tags available
let lastValidData = getEndTagData(text);
let workingRegexData = lastValidData;
while (workingRegexData.found === true) {
lastValidData = workingRegexData;
text = text.slice(0, workingRegexData.startPosition);
workingRegexData = getEndTagData(text);
}
return lastValidData;
}
function findEndTagClosestToEnd(text) {
let workingText = text;
let offset = 0;
let lastValidData = getEndTagData(workingText);
while (lastValidData.found) {
workingText = workingText.slice(lastValidData.endPosition);
let newData = getEndTagData(workingText);
if (newData.found === false) {
break;
}
offset += lastValidData.endPosition;
lastValidData = newData;
}
return {
found: lastValidData.found,
startPosition: lastValidData.startPosition + offset,
endPosition: lastValidData.endPosition + offset,
matchLength: lastValidData.matchLength
};
}
function containsEndTag(text) {
return findEndTag(text).found;
}
function getEndTagData(text) {
let found = false;
let startPosition = -1;
let endPosition = -1;
let matchLength = 0;
for (let i = 0; i < END_REGEX_ARR.length; i++) {
let regexData = END_REGEX_ARR[i].exec(text);
if (regexData !== null && regexData.length > 0) {
found = true;
startPosition = regexData.index;
matchLength = regexData[0].length;
break;
}
}
endPosition = startPosition + matchLength;
return { found, startPosition, endPosition, matchLength };
}
const COL_REGEX_STRS = [["^===\\s*?column-end\\s*?===\\s*?$", ""],
["^===\\s*?end-column\\s*?===\\s*?$", ""],
["^===\\s*?column-break\\s*?===\\s*?$", ""],
["^===\\s*?break-column\\s*?===\\s*?$", ""],
["^---\\s*?column-end\\s*?---\\s*?$", ""],
["^---\\s*?end-column\\s*?---\\s*?$", ""],
["^---\\s*?column-break\\s*?---\\s*?$", ""],
["^---\\s*?break-column\\s*?---\\s*?$", ""],
["^ *?(?:\\?)\\columnbreak *?$", ""],
["^:{3,} *column-?break *(?:(?:$\\n^)?| *):{3,} *$", "m"]];
const COL_REGEX_ARR = [];
for (let i = 0; i < COL_REGEX_STRS.length; i++) {
COL_REGEX_ARR.push(new RegExp(COL_REGEX_STRS[i][0], COL_REGEX_STRS[i][1]));
}
function containsColEndTag(text) {
let found = false;
for (let i = 0; i < COL_REGEX_ARR.length; i++) {
if (COL_REGEX_ARR[i].test(text)) {
found = true;
break;
}
}
return found;
}
const INNER_COL_END_REGEX_ARR = [
/^-{3}\s*?column-end\s*?-{3}\s*?$\n?/m,
/^-{3}\s*?end-column\s*?-{3}\s*?$\n?/m,
/^-{3}\s*?column-break\s*?-{3}\s*?$\n?/m,
/^-{3}\s*?break-column\s*?-{3}\s*?$\n?/m,
/^={3}\s*?column-end\s*?={3}\s*?$\n?/m,
/^={3}\s*?end-column\s*?={3}\s*?$\n?/m,
/^={3}\s*?column-break\s*?={3}\s*?$\n?/m,
/^={3}\s*?break-column\s*?={3}\s*?$\n?/m,
/^ *?(?:\\?)\\columnbreak *?$\n?/m,
/^:{3,} *column-?break *(?:(?:$\n^)?| *):{3,} *$/m
];
function checkForParagraphInnerColEndTag(text) {
for (let i = 0; i < INNER_COL_END_REGEX_ARR.length; i++) {
let regexResult = INNER_COL_END_REGEX_ARR[i].exec(text);
if (regexResult) {
return regexResult;
}
}
return null;
}
const COL_ELEMENT_INNER_TEXT_REGEX_STRS = ["= *column-end *=",
"= *end-column *=",
"= *column-break *=",
"= *break-column *="];
const COL_ELEMENT_INNER_TEXT_REGEX_ARR = [];
for (let i = 0; i < COL_ELEMENT_INNER_TEXT_REGEX_STRS.length; i++) {
COL_ELEMENT_INNER_TEXT_REGEX_ARR.push(new RegExp(COL_ELEMENT_INNER_TEXT_REGEX_STRS[i]));
}
function elInnerTextContainsColEndTag(text) {
let found = false;
for (let i = 0; i < COL_ELEMENT_INNER_TEXT_REGEX_ARR.length; i++) {
if (COL_ELEMENT_INNER_TEXT_REGEX_ARR[i].test(text)) {
found = true;
break;
}
}
return found;
}
const COL_SETTINGS_REGEX_STRS = ["```settings",
"```column-settings",
"```multi-column-settings"];
const COL_SETTINGS_REGEX_ARR = [];
for (let i = 0; i < COL_SETTINGS_REGEX_STRS.length; i++) {
COL_SETTINGS_REGEX_ARR.push(new RegExp(COL_SETTINGS_REGEX_STRS[i]));
}
function containsColSettingsTag(text) {
let found = false;
for (let i = 0; i < COL_SETTINGS_REGEX_ARR.length; i++) {
if (COL_SETTINGS_REGEX_ARR[i].test(text)) {
found = true;
break;
}
}
return found;
}
function findSettingsCodeblock(text) {
let found = false;
let startPosition = -1;
let endPosition = -1;
let matchLength = 0;
for (let i = 0; i < COL_SETTINGS_REGEX_ARR.length; i++) {
let regexData = COL_SETTINGS_REGEX_ARR[i].exec(text);
if (regexData !== null && regexData.length > 0) {
found = true;
startPosition = regexData.index;
matchLength = regexData[0].length;
endPosition = startPosition + matchLength;
let remainingText = text.slice(endPosition);
regexData = CODEBLOCK_END_REGEX.exec(remainingText);
if (regexData !== null && regexData.length > 0) {
found = true;
endPosition += regexData.index + regexData[0].length;
}
break;
}
}
return {
found,
startPosition,
endPosition,
matchLength,
regionType: "CODEBLOCK"
};
}
const CODEBLOCK_START_REGEX_STR = [
"multi-column-start",
"start-multi-column"
].reduce((prev, cur) => {
if (prev === "") {
return cur;
}
return `${prev}|${cur}`;
}, "");
const START_CODEBLOCK_REGEX = new RegExp(`\`\`\`(:?${CODEBLOCK_START_REGEX_STR})(.*?)\`\`\``, "ms");
function findStartCodeblock(text) {
let startRegion = defaultStartRegionData();
startRegion.regionType = "CODEBLOCK";
let regexData = START_CODEBLOCK_REGEX.exec(text);
if (regexData !== null && regexData.length > 0) {
startRegion.found = true;
startRegion.startPosition = regexData.index;
startRegion.matchLength = regexData[0].length;
startRegion.endPosition = startRegion.startPosition + startRegion.matchLength;
}
return startRegion;
}
function containsStartCodeBlock(text) {
return findStartCodeblock(text).found;
}
function containsRegionStart(text) {
return containsStartCodeBlock(text) || containsStartTag(text) || containsPandoc(text);
}
function countStartTags(initialText) {
let keys = [];
let text = initialText;
let startTagData = findStartTag(text);
while (startTagData.found) {
// Slice off everything before the tag
text = text.slice(startTagData.startPosition);
/**
* Get just the start tag line and then set text to everything just
* after the start tag.
*/
let tag = text.split("\n")[0];
text = text.slice(1); // This moves the text 1 character so we dont match the same tag.
// Parse out the key and append to the list.
let key = getStartTagKey(tag);
if (key === null) {
key = "";
}
keys.push(key);
// Search again for another tag before looping.
startTagData = findStartTag(text);
}
text = initialText;
startTagData = findStartCodeblock(text);
while (startTagData.found) {
let settingsText = text.slice(startTagData.startPosition, startTagData.endPosition);
text = text.slice(startTagData.endPosition);
let key = parseStartRegionCodeBlockID(settingsText);
if (key === null) {
key = "";
}
keys.push(key);
// Search again for another tag before looping.
startTagData = findStartCodeblock(text);
}
return { numberOfTags: keys.length, keys };
}
function getStartDataAboveLine(linesAboveArray) {
return getStartBlockOrCodeblockAboveLine(linesAboveArray, [
findStartTag,
findStartCodeblock,
findPandocStart
]);
}
function getStartBlockOrCodeblockAboveLine(linesAboveArray, searchFunctions) {
let originalText = linesAboveArray.join("\n");
let { tagMatchData, lastFoundTag, textAbove } = findLastValidTag(originalText);
if (tagMatchData === null) {
return null;
}
if (tagMatchData.found === false) {
return null;
}
if (tagMatchData.regionType === "CODEBLOCK") {
let endTagSerachData = findEndTag(textAbove);
if (endTagSerachData.found === true) {
return null;
}
let startBlockKey = parseStartRegionCodeBlockID(lastFoundTag);
let linesAboveArray = textAbove.split("\n");
return { startBlockKey, linesAboveArray, startBlockType: "CODEBLOCK" };
}
if (tagMatchData.regionType === "ORIGINAL") {
let endTagSerachData = findEndTag(textAbove);
if (endTagSerachData.found === true) {
return null;
}
let linesAboveArray = textAbove.split("\n");
let startBlockKey = getStartTagKey(lastFoundTag);
let codeBlockData = parseCodeBlockStart(linesAboveArray);
if (codeBlockData !== null) {
startBlockKey = codeBlockData.id;
if (codeBlockData.index > 0) {
linesAboveArray = linesAboveArray.slice(codeBlockData.index + 1);
}
}
if (startBlockKey === null) {
startBlockKey = "";
}
return { startBlockKey, linesAboveArray, startBlockType: "ORIGINAL" };
}
if (tagMatchData.regionType === "PADOC") {
let endTagSerachData = reducePandocRegionToEndDiv(textAbove);
if (endTagSerachData.found === true) {
return null;
}
let linesAboveArray = textAbove.split("\n");
let pandocData = getPandocStartData(`${lastFoundTag}`);
let startBlockKey = pandocData.userSettings.columnID;
return {
startBlockKey,
linesAboveArray,
startBlockType: "PADOC"
};
}
return null;
function findLastValidTag(originalText) {
let textAbove = originalText;
let offset = 0;
let tagMatchData = null;
let lastFoundTag = "";
for (let i = 0; true; i++) {
if (i > 100) {
break;
}
let tagsFound = [];
searchFunctions.forEach((func) => {
tagsFound.push(func(textAbove));
});
tagsFound = tagsFound.filter((val) => {
return val.found === true;
}).sort((a, b) => {
return a.startPosition - b.startPosition;
});
if (tagsFound.length === 0) {
break;
}
tagMatchData = tagsFound[0];
let startIndex = offset + tagMatchData.startPosition;
lastFoundTag = originalText.slice(startIndex, startIndex + tagMatchData.matchLength).trimEnd();
offset += (tagMatchData.startPosition + tagMatchData.matchLength);
textAbove = originalText.slice(offset);
}
return {
tagMatchData,
lastFoundTag,
textAbove
};
}
}
/**
* This function will filter a set of strings, returning all items starting
* from the closest open start tag through the last item in the set.
*
* The function filters out all end tags to make sure that the start tag we
* find is the proper start tag for the list sent.
* @param linesAboveArray
* @returns
*/
function getStartBlockAboveLine(linesAboveArray) {
return getStartBlockOrCodeblockAboveLine(linesAboveArray, [findStartTag]);
}
function getEndBlockBelow(linesBelow) {
// Reduce the array down into a single string so that we can
// easily RegEx over the string and find the indicies we're looking for.
let linesBelowStr = linesBelow.reduce((prev, current) => {
return prev + "\n" + current;
}, "");
let endTagSerachData = findEndTag(linesBelowStr);
let startTagSearchData = findStartTag(linesBelowStr);
let sliceEndIndex = -1; // If neither start or end found we return the entire array.
if (endTagSerachData.found === true && startTagSearchData.found === false) {
sliceEndIndex = endTagSerachData.startPosition;
}
else if (endTagSerachData.found === false && startTagSearchData.found === true) {
sliceEndIndex = startTagSearchData.startPosition;
}
else if (endTagSerachData.found === true && startTagSearchData.found === true) {
sliceEndIndex = endTagSerachData.startPosition;
if (startTagSearchData.startPosition < endTagSerachData.startPosition) {
/**
* If we found a start tag before an end tag we want to use the start tag
* our current block is not properly ended and we use the next start tag
* as our limit
*/
sliceEndIndex = startTagSearchData.startPosition;
}
}
return linesBelow.slice(0, sliceEndIndex);
}
function getStartTagKey(startTag) {
let keySplit = startTag.split(":");
if (keySplit.length > 1) {
return keySplit[1].replace(" ", "");
}
return null;
}
const TAB_HEADER_END_REGEX_STR = "^```$";
const TAB_HEADER_END_REGEX = new RegExp(TAB_HEADER_END_REGEX_STR);
function parseCodeBlockStart(codeBlockLines) {
let id = null;
for (let i = 0; i < codeBlockLines.length; i++) {
let line = codeBlockLines[i];
if (id === null) {
let key = line.split(":")[0];
if (key.toLowerCase() === "region id") {
id = line.split(":")[1].trim();
}
}
else {
if (TAB_HEADER_END_REGEX.test(line)) {
return { id: id, index: i };
}
}
}
if (id === null) {
return null;
}
else {
return { id: id, index: -1 };
}
}
const CODEBLOCK_END_REGEX_STR = "```";
const CODEBLOCK_END_REGEX = new RegExp(CODEBLOCK_END_REGEX_STR);
/*
* Filename: multi-column-markdown/src/utilities/utils.ts
* Created Date: Tuesday, January 30th 2022, 4:02:19 pm
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
function getUID(length = 10) {
if (length > 10) {
length = 10;
}
let UID = Math.random().toString(36).substring(2);
UID = UID.slice(0, length);
return UID;
}
/**
* BFS on the child nodes of the passed element searching for the first instance of the
* node type passed. Returning the element found or null if none found.
*
* @param root
* @param nodeTypeName
* @returns
*/
function searchChildrenForNodeType(root, nodeTypeName) {
nodeTypeName = nodeTypeName.toLowerCase();
let queue = [root];
while (queue.length > 0) {
for (let i = 0; i < queue.length; i++) {
let node = queue.shift();
let nodeName = node.nodeName.toLowerCase();
if (nodeName === nodeTypeName) {
return node;
}
for (let i = 0; i < node.children.length; i++) {
queue.push(node.children[i]);
}
}
}
return null;
}
function fileStillInView(sourcePath) {
let fileLeaf = getFileLeaf(sourcePath);
if (fileLeaf === null) {
return false;
}
return true;
}
function getFileLeaf(sourcePath) {
let markdownLeaves = app.workspace.getLeavesOfType("markdown");
if (markdownLeaves.length === 0) {
return null;
}
for (let i = 0; i < markdownLeaves.length; i++) {
if (markdownLeaves[i].getViewState().state.file === sourcePath) {
return markdownLeaves[i];
}
}
return null;
}
/*
* Filename: multi-column-markdown/src/domObject.ts
* Created Date: Tuesday, February 1st 2022, 12:04:00 pm
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
const UPDATE_TIMES = [125, 125, 250, 20000];
const MID_BREAK_ERROR_MESSAGE = "Detected invalid column break syntax.\nPlease make sure column break tags are not in the middle of a paragraph block";
var DOMObjectTag;
(function (DOMObjectTag) {
DOMObjectTag[DOMObjectTag["none"] = 0] = "none";
DOMObjectTag[DOMObjectTag["startRegion"] = 1] = "startRegion";
DOMObjectTag[DOMObjectTag["regionSettings"] = 2] = "regionSettings";
DOMObjectTag[DOMObjectTag["columnBreak"] = 3] = "columnBreak";
DOMObjectTag[DOMObjectTag["endRegion"] = 4] = "endRegion";
})(DOMObjectTag || (DOMObjectTag = {}));
var ElementColumnBreakType;
(function (ElementColumnBreakType) {
ElementColumnBreakType[ElementColumnBreakType["none"] = 0] = "none";
ElementColumnBreakType[ElementColumnBreakType["preBreak"] = 1] = "preBreak";
ElementColumnBreakType[ElementColumnBreakType["postBreak"] = 2] = "postBreak";
ElementColumnBreakType[ElementColumnBreakType["midBreak"] = 3] = "midBreak";
})(ElementColumnBreakType || (ElementColumnBreakType = {}));
class DOMObject {
constructor(element, linesOfElement, randomID = getUID(), tag = DOMObjectTag.none) {
this.clonedElement = null;
this.elementIsColumnBreak = ElementColumnBreakType.none;
this.elementType = "undefined";
this.elementContainer = null;
this.elementRenderedHeight = 0;
this.canvasElementUpdateTime = Date.now();
this.canvasTimerIndex = 0;
this.lastClonedElementUpdateTime = Date.now();
this.updateTimerIndex = 0;
this.nodeKey = element.innerText.trim();
this.originalElement = element;
this.UID = randomID;
this.tag = tag;
this.usingOriginalElement = false;
this.linesOfElement = linesOfElement;
if (this.tag === DOMObjectTag.none) {
this.setDomObjectTag();
}
// If our tag is still none here, we now want to check for
// an in paragraph column break flag.
if (this.tag === DOMObjectTag.none) {
this.checkForPrePostColumnBreak();
}
}
setMainDOMElement(domElement) {
this.originalElement = domElement;
this.usingOriginalElement = true;
}
clonedElementReadyForUpdate() {
let deltaTime = Date.now() - this.lastClonedElementUpdateTime;
if (deltaTime > UPDATE_TIMES[this.updateTimerIndex]) {
return true;
}
return false;
}
canvasReadyForUpdate() {
var timingArray = UPDATE_TIMES;
let { requiresUpdate, timerIndex, updateTime } = checkIfTimingIsReadyForUpdate(timingArray, this.canvasElementUpdateTime, this.canvasTimerIndex);
if (requiresUpdate === false) {
return false;
}
this.canvasElementUpdateTime = updateTime;
this.canvasTimerIndex = timerIndex;
return true;
}
updateClonedElement(newClonedElement) {
this.clonedElement = newClonedElement;
this.updateClonedElementTimer();
}
updateClonedElementTimer() {
this.lastClonedElementUpdateTime = Date.now();
this.updateTimerIndex = Math.clamp(this.updateTimerIndex + 1, 0, UPDATE_TIMES.length - 1);
}
setDomObjectTag() {
let elementTextSpaced = this.linesOfElement.reduce((prev, curr) => {
return prev + "\n" + curr;
});
if (containsEndTag(this.originalElement.textContent) === true) {
this.elementType = "unRendered";
this.tag = DOMObjectTag.endRegion;
// el.addClass(MultiColumnStyleCSS.RegionEndTag)
// regionalManager.updateElementTag(currentObject.UID, DOMObjectTag.endRegion);
}
else if (containsColEndTag(this.originalElement.textContent) === true ||
(this.originalElement.innerHTML.startsWith("<mark>")) && elInnerTextContainsColEndTag(this.originalElement.textContent)) {
this.elementType = "unRendered";
this.tag = DOMObjectTag.columnBreak;
// el.addClass(MultiColumnStyleCSS.ColumnEndTag)
// regionalManager.updateElementTag(currentObject.UID, DOMObjectTag.columnBreak);
}
else if (containsStartTag(this.originalElement.textContent) === true) {
this.elementType = "unRendered";
this.tag = DOMObjectTag.startRegion;
// el.addClass(MultiColumnStyleCSS.ColumnEndTag)
// regionalManager.updateElementTag(currentObject.UID, DOMObjectTag.columnBreak);
}
else if (containsColSettingsTag(elementTextSpaced) === true) {
this.elementType = "unRendered";
// el.addClass(MultiColumnStyleCSS.RegionSettings)
// regionalManager = regionalContainer.setRegionSettings(elementTextSpaced)
// regionalManager.updateElementTag(currentObject.UID, DOMObjectTag.regionSettings);
}
}
checkForPrePostColumnBreak() {
function replaceColBreak(text) {
let colBreakData = checkForParagraphInnerColEndTag(text);
if (containsColumnBreak === null) {
return text;
}
let startIndex = colBreakData.index;
let endIndex = startIndex + colBreakData[0].length;
let pre = text.slice(0, startIndex);
let post = text.slice(endIndex);
return `${pre}${post}`;
}
let textOfElement = this.originalElement.innerText;
let containsColumnBreak = checkForParagraphInnerColEndTag(textOfElement);
if (containsColumnBreak !== null) {
let text = this.originalElement.innerText;
let startIndex = containsColumnBreak.index;
let endIndex = startIndex + containsColumnBreak[0].length;
let pre = text.slice(0, startIndex);
let post = text.slice(endIndex);
// Sometimes the element passed in is a DIV containing a child element, other
// times it is the root child element alone, here we just make sure we are accessing
// the right element we want.
let checkNode = this.originalElement;
if (this.originalElement.nodeName === "DIV") {
checkNode = this.originalElement.children[0];
}
let paragraph = null;
if (checkNode.nodeName === "P") {
// Paragraphs simply remove the col-break tag
// we set our element here incase we need to display an error.
paragraph = checkNode;
checkNode.innerText = `${pre}${post}`;
}
else if (checkNode.nodeName === "UL" || checkNode.nodeName === "OL") {
// Attempt to get the list item that contains the column break,
// From testing this code should only run when the column break is at the end
// of a list not at the start of the list.
let listItem = null;
for (let i = checkNode.children.length - 1; i >= 0; i--) {
if (checkNode.children[i].nodeName === "LI") {
listItem = checkNode.children[i];
break;
}
}
if (listItem !== null) {
// Replace, the list element HTML without the col-break text.
listItem.innerHTML = replaceColBreak(listItem.innerHTML);
}
}
else {
console.debug(`Element Type: ${checkNode.nodeName}, does not currently support appened column-breaks.`, checkNode.cloneNode(true));
// if(paragraph) {
// paragraph.innerText = `${pre}${post}`;
// }
}
// console.debug("Checking where column break is", startIndex, endIndex, text.length);
if (startIndex === 0) {
// console.debug("Column break at begining of element.")
this.elementIsColumnBreak = ElementColumnBreakType.preBreak;
}
else if (endIndex === text.length) {
// console.debug("Column break at end of element.")
this.elementIsColumnBreak = ElementColumnBreakType.postBreak;
}
else {
// console.debug("Column break in the middle of element?")
this.elementIsColumnBreak = ElementColumnBreakType.midBreak;
const ERROR_COLOR_CSS = "mcm-error-message-color";
const CENTER_ALIGN_SPAN_CSS = "mcm-span-content-alignment-center";
if (paragraph) {
paragraph.innerHTML = `${pre}\n<span class="${ERROR_COLOR_CSS} ${CENTER_ALIGN_SPAN_CSS}">${MID_BREAK_ERROR_MESSAGE}</span>\n\n${post}`.split("\n").join("<br>");
}
}
}
}
}
class TaskListDOMObject extends DOMObject {
constructor(baseDOMObject) {
super(baseDOMObject.originalElement, baseDOMObject.linesOfElement, baseDOMObject.UID, DOMObjectTag.none);
this.originalCheckboxes = [];
this.checkboxElements = new Map();
}
checkboxClicked(index) {
if (this.checkboxElements.has(index)) {
this.checkboxElements.get(index).click();
}
if (index < this.originalCheckboxes.length) {
let originalInput = this.originalCheckboxes[index].getElementsByClassName('task-list-item-checkbox');
if (originalInput.length === 1) {
originalInput[0].click();
}
// else {
// console.error("Could not find checkbox to click.")
// }
}
}
getCheckboxElement(index) {
var _a;
if (this.checkboxElements.has(index) === false) {
if (index < this.originalCheckboxes.length) {
let originalInput = (_a = this.originalCheckboxes[index]) === null || _a === void 0 ? void 0 : _a.getElementsByClassName('task-list-item-checkbox');
if ((originalInput === null || originalInput === void 0 ? void 0 : originalInput.length) >= 1) {
this.checkboxElements.set(index, originalInput[0]);
}
// else {
// console.error("Could not find checkbox element to return.", this.originalCheckboxes, index);
// }
}
}
return this.checkboxElements.get(index);
}
static checkForTaskListElement(domElement) {
if (domElement.originalElement.getElementsByClassName("task-list-item").length > 0) {
return new TaskListDOMObject(domElement);
}
return domElement;
}
static getChildCheckbox(el) {
let checkboxElements = el.getElementsByClassName('task-list-item-checkbox');
if (checkboxElements.length === 1) {
return checkboxElements[0];
}
return el.children[0];
}
}
function checkIfTimingIsReadyForUpdate(timingArray, canvasElementUpdateTime, canvasTimerIndex) {
let deltaTime = Date.now() - canvasElementUpdateTime;
if (deltaTime > timingArray[canvasTimerIndex]) {
canvasElementUpdateTime = Date.now();
canvasTimerIndex = Math.clamp(canvasTimerIndex + 1, 0, UPDATE_TIMES.length - 1);
return {
requiresUpdate: true,
updateTime: canvasElementUpdateTime,
timerIndex: canvasTimerIndex,
};
}
return {
requiresUpdate: false,
updateTime: canvasElementUpdateTime,
timerIndex: canvasTimerIndex
};
}
/*
* File: multi-column-markdown/src/utilities/cssDefinitions.ts
* Created Date: Wednesday, February 16th 2022, 11:09:06 am
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
var MultiColumnLayoutCSS;
(function (MultiColumnLayoutCSS) {
MultiColumnLayoutCSS["RegionRootContainerDiv"] = "mcm-column-root-container";
MultiColumnLayoutCSS["RegionErrorContainerDiv"] = "mcm-column-error-region-wrapper";
MultiColumnLayoutCSS["RegionContentContainerDiv"] = "mcm-column-region-wrapper";
MultiColumnLayoutCSS["RegionColumnContainerDiv"] = "mcm-column-parent-container";
MultiColumnLayoutCSS["ColumnDualElementContainer"] = "mcm-column-element-wrapper";
MultiColumnLayoutCSS["OriginalElementType"] = "mcm-original-column-element";
MultiColumnLayoutCSS["ClonedElementType"] = "mcm-cloned-column-element";
MultiColumnLayoutCSS["ContentOverflowAutoScroll_X"] = "mcm-content-overflow-auto-scroll-x";
MultiColumnLayoutCSS["ContentOverflowAutoScroll_Y"] = "mcm-content-overflow-auto-scroll-y";
MultiColumnLayoutCSS["ContentOverflowHidden_X"] = "mcm-content-overflow-hidden-x";
MultiColumnLayoutCSS["ContentOverflowHidden_Y"] = "mcm-content-overflow-hidden-y";
MultiColumnLayoutCSS["AlignmentLeft"] = "mcm-content-alignment-left";
MultiColumnLayoutCSS["AlignmentCenter"] = "mcm-content-alignment-center";
MultiColumnLayoutCSS["AlignmentRight"] = "mcm-content-alignment-right";
MultiColumnLayoutCSS["TableAlignment"] = "mcm-table-alignment";
MultiColumnLayoutCSS["NoFlexShrink"] = "mcm-no-flex-shrink";
MultiColumnLayoutCSS["ReflowContainerDiv"] = "mcm-doc-reflow-container";
MultiColumnLayoutCSS["ErrorRegionPadding"] = "mcm-column-error-padding";
// ------------------------------------------------------ //
MultiColumnLayoutCSS["SingleColumnSmall"] = "mcm-single-column-small";
MultiColumnLayoutCSS["SingleColumnMed"] = "mcm-single-column-medium";
MultiColumnLayoutCSS["SingleColumnLarge"] = "mcm-single-column-large";
MultiColumnLayoutCSS["SingleColumnFull"] = "mcm-single-column-full";
MultiColumnLayoutCSS["SingleColumnLeftLayout"] = "mcm-singlecol-layout-left";
MultiColumnLayoutCSS["SingleColumnCenterLayout"] = "mcm-singlecol-layout-center";
MultiColumnLayoutCSS["SingleColumnRightLayout"] = "mcm-singlecol-layout-right";
// ------------------------------------------------------ //
MultiColumnLayoutCSS["TwoEqualColumns"] = "mcm-two-equal-columns";
MultiColumnLayoutCSS["TwoColumnSmall"] = "mcm-two-column-small";
MultiColumnLayoutCSS["TwoColumnLarge"] = "mcm-two-column-large";
// ------------------------------------------------------ //
MultiColumnLayoutCSS["ThreeEqualColumns"] = "mcm-three-equal-columns";
MultiColumnLayoutCSS["ThreeColumn_Large"] = "mcm-three-column-large";
MultiColumnLayoutCSS["ThreeColumn_Small"] = "mcm-three-column-small";
})(MultiColumnLayoutCSS || (MultiColumnLayoutCSS = {}));
var MultiColumnStyleCSS;
(function (MultiColumnStyleCSS) {
MultiColumnStyleCSS["RegionErrorMessage"] = "mcm-column-error-message";
MultiColumnStyleCSS["RegionSettings"] = "mcm-column-settings-wrapper";
MultiColumnStyleCSS["RegionContent"] = "mcm-column-content-wrapper";
MultiColumnStyleCSS["RegionEndTag"] = "mcm-column-end-tag-wrapper";
MultiColumnStyleCSS["ColumnEndTag"] = "mcm-column-break-tag-wrapper";
MultiColumnStyleCSS["RegionShadow"] = "mcm-region-shadow";
MultiColumnStyleCSS["ColumnShadow"] = "mcm-column-shadow";
MultiColumnStyleCSS["ColumnBorder"] = "mcm-column-border";
MultiColumnStyleCSS["ColumnContent"] = "mcm-column-div";
MultiColumnStyleCSS["SmallFont"] = "mcm-small-font-message";
})(MultiColumnStyleCSS || (MultiColumnStyleCSS = {}));
var ObsidianStyleCSS;
(function (ObsidianStyleCSS) {
ObsidianStyleCSS["RenderedMarkdown"] = "markdown-rendered";
})(ObsidianStyleCSS || (ObsidianStyleCSS = {}));
/**
* File: /src/utilities/elementRenderTypeParser.ts *
* Author: Cameron Robinson *
* *
* Copyright (c) 2023 Cameron Robinson *
*/
function getElementRenderType(element) {
if (isEmbededImage(element) === true) {
return "imageEmbed";
}
if (isButtonPlugin_CrossCompatibilty(element) === true) {
return "buttonPlugin";
}
if (isTasksPlugin(element) === true) {
return "tasksPlugin";
}
/**
* The Dataview plugin needs to be constantly checked if the clone should be
* updated but should not always update the "dual render" aspect, so we add
* a special case for that plugin and maybe others in the future.
*/
if (hasDataview(element) === true) {
return "dataviewPlugin";
}
else if (isPDFEmbed(element)) {
return "pdfEmbed";
}
else if (isInternalEmbed(element)) {
return "internalEmbed";
}
/**
* Some types of content are rendered in canvases which are not rendered properly
* when we clone the original node. Here we are flagging the element as a canvas
* element so we can clone the canvas to a copy element within the region.
*
*/
if (hasDataviewJSCanvas(element) === true) {
return "dataviewJSCanvasEmbed";
}
if (hasDataviewJS(element) === true) {
return "dataviewJSEmbed";
}
if (hasDataviewInline(element) === true) {
return "dataviewInlineQuery";
}
/**
* Look for specific kinds of elements by their CSS class names here. These
* are going to be brittle links as they rely on other plugin definitions but
* as this is only adding in extra compatability to the plugins defined here
* it should be ok.
*
* These may be classes on one of the simple elements (such as a paragraph)
* that we search for below so need to look for these first.
*/
if (hasDiceRoller(element) === true) {
return "diceRoller";
}
else if (hasCopyButton(element) === true) {
return "calloutCopyButton";
}
else if (hasAdmonitionFold(element) === true) {
return "admonitionFold";
}
/**
* This checks for special types of elements that should be rendered normally. Is
* slightly redundant with next check but differentiates between types of ements
* being checked.
*/
if (hasAdmonition(element) === true) {
return "admonition";
}
else if (isIFrame(element) === true) {
return "iFrameEmbed";
}
else if (isCustomIFrame(element) === true) {
return "customFramePlugin";
}
/**
* If we didnt find a special element we want to check for simple elements
* such as paragraphs or lists. In the current implementation we only set up
* the special case for "specialRender" elements so this *should* be saving
* some rendering time by setting these tags properly.
*/
if (hasParagraph(element) ||
hasHeader(element) ||
hasList(element) ||
isHorizontalRule(element) ||
isTable(element)) {
return "basicElement";
}
// If still nothing found we return other as the default response if nothing else found.
return "specialRender";
}
function hasParagraph(element) {
return element.innerHTML.startsWith("<p");
}
function hasHeader(element) {
if (element.innerHTML.startsWith("<h1") ||
element.innerHTML.startsWith("<h2") ||
element.innerHTML.startsWith("<h3") ||
element.innerHTML.startsWith("<h4") ||
element.innerHTML.startsWith("<h5") ||
element.innerHTML.startsWith("<h6")) {
return true;
}
return false;
}
function hasList(element) {
if (element.innerHTML.startsWith("<ul") ||
element.innerHTML.startsWith("<ol")) {
return true;
}
return false;
}
function hasCopyButton(element) {
return element.getElementsByClassName("copy-code-button").length !== 0 ||
element.getElementsByClassName("admonition-content-copy").length !== 0;
}
function hasDiceRoller(element) {
return element.getElementsByClassName("dice-roller").length !== 0;
}
function hasAdmonition(element) {
return element.getElementsByClassName("admonition").length !== 0;
}
function isIFrame(element) {
if (element.children.length > 0) {
return element.firstChild.nodeName.toLowerCase() === "iframe";
}
return false;
}
function isTasksPlugin(element) {
return element.hasClass("block-language-tasks") ||
element.getElementsByClassName("block-language-tasks").length !== 0;
}
function isHorizontalRule(element) {
return element.innerHTML.startsWith("<hr");
}
function isTable(element) {
return element.innerHTML.startsWith("<table");
}
function hasAdmonitionFold(element) {
return element.getElementsByClassName("callout-fold").length !== 0;
}
function hasDataview(element) {
let isDataview = element.getElementsByClassName("block-language-dataview").length !== 0;
return isDataview;
}
function hasDataviewInline(element) {
let isDataview = element.getElementsByClassName("dataview-inline-query").length !== 0;
return isDataview;
}
function hasDataviewJSCanvas(element) {
let isDataviewJS = element.getElementsByClassName("block-language-dataviewjs").length !== 0;
let canvas = searchChildrenForNodeType(element, "canvas");
/**
* This means only dataviewJS chart canvas elements should be rendered properly. Other canvases will
* need thier own case put in or the restriction removed after testing.
*/
return canvas !== null && isDataviewJS;
}
function hasDataviewJS(element) {
let isDataviewJS = element.getElementsByClassName("block-language-dataviewjs").length !== 0;
return isDataviewJS;
}
function isInternalEmbed(element) {
let isEmbed = element.getElementsByClassName("internal-embed").length !== 0;
return isEmbed;
}
function isPDFEmbed(element) {
let isPDFEmbed = element.getElementsByClassName("pdf-embed").length !== 0;
return isPDFEmbed;
}
function getHeadingCollapseElement(element) {
if (element === null) {
return null;
}
let childElements = element.getElementsByClassName("heading-collapse-indicator");
if (childElements.length === 1) {
return childElements[0];
}
if (childElements.length > 1) ;
return null;
}
function isCustomIFrame(element) {
let isFrame = element.getElementsByClassName("custom-frames-frame").length !== 0;
return isFrame;
}
function isButtonPlugin_CrossCompatibilty(element) {
if (element.hasClass("block-language-button")) {
return true;
}
let buttonPluginBlock = element.getElementsByClassName("block-language-button")[0];
if (buttonPluginBlock) {
return true;
}
return false;
}
function isEmbededImage(element) {
let img = element.getElementsByTagName("img")[0];
if (img === null ||
img === undefined) {
return false;
}
return true;
}
/**
* File: /src/dom_manager/regional_managers/RegionManager.ts *
* Created Date: Sunday, May 22nd 2022, 7:49 pm *
* Author: Cameron Robinson *
* *
* Copyright (c) 2022 Cameron Robinson *
*/
class RegionManager {
get numberOfChildren() {
return this.domList.length;
}
get regionParent() {
return this._regionParent;
}
set regionParent(value) {
this._regionParent = value;
}
get errorManager() {
return this._errorManager;
}
set errorManager(value) {
this._errorManager = value;
}
updateErrorManager(newManager, rootElement) {
while (rootElement.children.length > 0) {
rootElement.childNodes.forEach(child => {
rootElement.removeChild(child);
});
}
this._errorManager = newManager;
this._errorManager.setRegionRootElement(rootElement);
}
constructor(data) {
this.domList = [];
this.domObjectMap = new Map();
this.regionalSettings = getDefaultMultiColumnSettings();
this.domList = data.domList;
this.domObjectMap = data.domObjectMap;
this.regionParent = data.regionParent;
this.fileManager = data.fileManager;
this.regionalSettings = data.regionalSettings;
this.regionKey = data.regionKey;
this.errorManager = data.errorManager;
}
getRegionData() {
return {
domList: this.domList,
domObjectMap: this.domObjectMap,
regionParent: this.regionParent,
fileManager: this.fileManager,
regionalSettings: this.regionalSettings,
regionKey: this.regionKey,
rootElement: null,
errorManager: this.errorManager
};
}
/**
* Adds a new object to the region by finding where it should be relative to its siblings.
* @param siblingsAbove The Markdown text rendered elements for sibilings above this element in the dom
* @param siblingsBelow The Markdown text rendered elements for sibilings below this element in the dom
* @param obj The object to add.
* @returns Returns the index at which the object has been added.
*/
addObject(siblingsAbove, siblingsBelow, obj) {
let nextObj = siblingsBelow.children[0];
let addAtIndex = siblingsAbove.children.length;
if (siblingsAbove.children.length > 0) {
/**
* We want to find the first sibling withouth "" for an inner text so we can use that to anchor our
* element into the domList. For most items the first element before our new element will have the proper
* innerText. Sometimes other elements are empty and were causing issues.
*
* Now we loop back through the previous siblings looking for the first one with a valid inner text and using that
* as the anchor and offsetting our addAtIndex by the number of empty string elements we found.
*/
let prevSiblingInnerText = "";
let prevSiblingOffset = 0;
for (let i = siblingsAbove.children.length - 1; i >= 0; i--) {
let obj = siblingsAbove.children[i];
if (obj.innerText !== "") {
prevSiblingInnerText = obj.innerText;
break;
}
prevSiblingOffset++;
}
for (let i = this.domList.length - 1; i >= 0; i--) {
if (this.domList[i].nodeKey === prevSiblingInnerText) {
addAtIndex = i + 1 + prevSiblingOffset;
break;
}
}
}
let nextElIndex = addAtIndex;
if (nextObj !== undefined) {
nextObj.innerText;
for (let i = addAtIndex; i < this.domList.length; i++) {
if (this.domList[i].nodeKey === nextObj.innerText.trim()) {
nextElIndex = i;
break;
}
}
}
// console.log(" Prev: ", Array.from(siblingsAbove.children).slice(-3), "Adding: ", obj.originalElement, " Next: ", siblingsBelow.children[0], "Overwriting:", this.domList.slice(addAtIndex, nextElIndex));
this.domList.splice(addAtIndex, nextElIndex - addAtIndex, obj);
this.domObjectMap.set(obj.UID, obj);
// /**
// * Make a copy of the list to log, only because
// * console log updates its references with updates in memory.
// */
// let x = this.domList.slice(0);
// console.log(x);
return addAtIndex;
}
addObjectAtIndex(obj, index) {
this.domList.splice(index, 0, obj);
this.domObjectMap.set(obj.UID, obj);
}
removeObject(objectUID) {
// /**
// * Make a copy of the list to log
// */
// let x = domList.slice(0);
// console.log(x);
// Get the object by key, remove it from the map and then
// from the list.
let obj = this.domObjectMap.get(objectUID);
this.domObjectMap.delete(objectUID);
if (obj === undefined) {
return;
}
if (this.domList.contains(obj)) {
this.domList.remove(obj);
}
if (this.domList.length === 0 && this.fileManager !== null) {
this.fileManager.removeRegion(this.regionKey);
}
// x = domList.slice(0);
// console.log(x);
}
updateElementTag(objectUID, newTag) {
let obj = this.domObjectMap.get(objectUID);
obj.tag = newTag;
}
setRegionalSettings(regionSettings) {
this.regionalSettings = regionSettings;
}
/**
* Creates an object containing all necessary information for the region
* to be rendered to the preview pane.
*
* @returns a MultiColumnRenderData object with the root DOM element, settings object, and
* all child objects in the order they should be rendered.
*/
getRegionRenderData() {
return {
parentRenderElement: this.regionParent,
parentRenderSettings: this.regionalSettings,
domObjects: this.domList
};
}
/**
* This fuction is called when a start tag is removed from view meaning
* our parent element storing the multi-column region is removed. It
* removes the CSS class from all of the elements so they will be
* re-rendered in the preview window.
*/
displayOriginalElements() {
for (let i = 0; i < this.domList.length; i++) {
if (this.domList[i].originalElement) {
this.domList[i].originalElement.removeClasses([MultiColumnStyleCSS.RegionEndTag,
MultiColumnStyleCSS.ColumnEndTag,
MultiColumnStyleCSS.RegionSettings,
MultiColumnStyleCSS.RegionContent]);
if (this.domList[i].originalElement.parentElement) {
this.domList[i].originalElement.parentElement.removeChild(this.domList[i].originalElement);
}
}
}
}
getID() {
return this.regionKey;
}
updateRenderedMarkdown() {
/**
* This function acts as the update loop for the multi-column regions.
* Here we loop through all of the elements within the rendered region and
* potentially update how things are rendered. We need to do this for
* compatability with other plugins.
*
* If the multi-column region is rendered before other plugins that effect
* content within the region our rendered data may not properly display
* the content from the other plugin. Here we loop through the elements
* after all plugins have had a chance to run and can make changes to the
* DOM at this point.
*/
for (let i = 0; i < this.domList.length; i++) {
let elementType = this.domList[i].elementType;
if (elementType === "unRendered") {
continue;
}
/**
* If the element is not currently a special render element we check again
* as the original element may have been updated.
*/
if (elementType === "undefined" ||
elementType === "basicElement" ||
elementType === "specialRender") {
// If the new result returns as a special renderer we update so
// this wont run again for this item.
elementType = getElementRenderType(this.domList[i].originalElement);
}
let taskListObj = this.domList[i];
/**
* Here we check for special cases
*/
if (taskListObj &&
elementType === "dataviewJSEmbed") {
if (this.domList[i].clonedElementReadyForUpdate()) {
cloneElement(this.domList[i]);
this.fixClonedCheckListButtons(this.domList[i], true);
}
else {
this.fixClonedCheckListButtons(this.domList[i]);
}
continue;
}
if (taskListObj &&
elementType === "basicElement") {
this.fixClonedCheckListButtons(this.domList[i]);
continue;
}
if (elementType === "basicElement") {
this.domList[i].elementType = "basicElement";
continue;
}
if (elementType === "imageEmbed") { //ElementRenderType.fixedElementRender) {
this.domList[i].elementType = elementType;
continue;
}
if (elementType === "buttonPlugin") {
processButtonPluginUpdate(this.domList[i]);
continue;
}
if (elementType === "pdfEmbed") {
this.domList[i].elementType = elementType;
this.setUpDualRender(this.domList[i]);
continue;
}
if (elementType === "diceRoller" ||
elementType === "admonitionFold" ||
elementType === "calloutCopyButton" ||
elementType === "dataviewPlugin" ||
elementType === "internalEmbed" ||
elementType === "dataviewJSCanvasEmbed" ||
elementType === "dataviewJSEmbed" ||
elementType === "dataviewInlineQuery" ||
elementType === "tasksPlugin") {
this.domList[i].elementType = elementType;
this.setUpDualRender(this.domList[i]);
continue;
}
}
}
/**
* This function takes in the original element and its clone and checks if
* the element contains a task-list-item class. If so it loops through all
* items in the list and fixes their checkboxes to properly fire an event.
* The new checkbox calls the click function on the original checkbox so
* compatability with other plugins *should* remain.
* @param domElement
* @param initalizeCheckboxes
*/
fixClonedCheckListButtons(domElement, initalizeCheckboxes = false) {
if (domElement.originalElement === null || domElement.clonedElement === null) {
return;
}
let element = domElement.originalElement;
let clonedElement = domElement.clonedElement;
let clonedListCheckboxes = Array.from(clonedElement.getElementsByClassName("task-list-item"));
let originalListCheckboxes = Array.from(element.getElementsByClassName("task-list-item"));
if (initalizeCheckboxes === true) {
domElement.originalCheckboxes = originalListCheckboxes;
// When we initalize we remove the old input checkbox that contains
// the weird callback situation causing the bug. Then we create a new
// checkbox to replace it and set it up to fire the click event on
// the original checkbox so functionality is restored.
for (let i = 0; i < originalListCheckboxes.length; i++) {
const checkbox = createEl('input');
let originalInput = originalListCheckboxes[i].getElementsByTagName("input")[0];
let isChecked = false;
if (originalInput) {
isChecked = originalInput.checked;
}
else {
console.debug("Could not find original checkbox. Is it null?");
}
let oldCheckbox = TaskListDOMObject.getChildCheckbox(clonedListCheckboxes[i]);
clonedListCheckboxes[i].replaceChild(checkbox, oldCheckbox);
checkbox.checked = isChecked;
checkbox.addClass('task-list-item-checkbox');
checkbox.type = 'checkbox';
checkbox.onClickEvent(() => {
domElement.checkboxClicked(i);
if (checkbox.checked) {
clonedListCheckboxes[i].addClass("is-checked");
clonedListCheckboxes[i].setAttr("data-task", "x");
}
else {
clonedListCheckboxes[i].removeClass("is-checked");
clonedListCheckboxes[i].setAttr("data-task", " ");
}
});
}
}
else {
// Whenever we reach this point we update our list of original checkboxes
// that may be different from our cache. This is due to how obsidian
// changes the DOM underneath us so we need to constantly update our cache.
domElement.originalCheckboxes = originalListCheckboxes;
}
// When the Tasks plugin is installed the cloned copy of the original element contains
// an extra element for some reason. If this occurs for other reasons here we adjust
// that to keep the clone the same as the original.
if (clonedListCheckboxes.length > originalListCheckboxes.length) {
for (let i = originalListCheckboxes.length; i < clonedListCheckboxes.length; i++) {
try {
clonedListCheckboxes[i].detach();
}
catch (error) {
console.debug("No child found when removing from list.");
}
}
}
}
setUpDualRender(domElement) {
/**
* If our element is of "specialRender" type it *may* need to be rendered
* using the original element rather than a copy. For example, an element
* may have an onClick event that would not get coppied to the clone.
*
* If we just moved these elements into the region it would get
* moved back out into the original location in the DOM by obsidian
* when scrolling or when the file is updated. On the next refresh it
* would be moved back but that can lead to a region jumping
* around as the item is moved in and out.
*
* Here we set up the div to contain the element and create
* a visual only clone of it. The clone will only be visible
* when the original is not in the multi-column region so it
* saves us from the visual noise of the region jumping around.
*/
let originalElement = domElement.originalElement;
let clonedElement = domElement.clonedElement;
let containerElement = domElement.elementContainer;
// Get height of the original and cloned element. If the element is not currently rendered
// it will have 0 height so we need to temporarily render it to get the height.
let originalElementHeight = getElementClientHeight(originalElement, containerElement);
let clonedElementHeight = getElementClientHeight(clonedElement, containerElement);
if (domElement.elementType === "pdfEmbed") {
updatePDFEmbed(domElement);
return;
}
if (domElement.elementType === "dataviewJSCanvasEmbed") {
reRenderDataviewJS(domElement);
return;
}
/**
* We only want to clone the element once to reduce GC. But if the cloned
* element's height is not equal to the original element, this means the
* item element has been updated somewhere else without the dom being
* refreshed. This can occur when elements are updated by other plugins,
* such as Dataview.
*/
if ((clonedElement === null ||
Math.abs(clonedElementHeight - originalElementHeight) > 10 ||
domElement.clonedElementReadyForUpdate() === true)) {
// console.log("Updating Cloned Element.", ElementRenderType[domElement.elementType], clonedElementHeight, originalElementHeight)
// Update clone and reference.
cloneElement(domElement);
}
/**
* If the container element has less than 2 children we need to move the
* original element back into it. However some elements constantly get moved
* in and out causing some unwanted behavior. Those element will be tagged
* as specialSingleElementRender so we ignore those elements here.
*/
if (domElement.elementContainer.children.length < 2 &&
domElement.elementType !== "dataviewPlugin" &&
domElement.elementType !== "internalEmbed" &&
domElement.elementType !== "dataviewJSEmbed") {
// console.log("Updating dual rendering.", domElement, domElement.originalElement.parentElement, domElement.originalElement.parentElement?.childElementCount);
// Make sure our CSS is up to date.
originalElement.addClass(MultiColumnLayoutCSS.OriginalElementType);
clonedElement.addClass(MultiColumnLayoutCSS.ClonedElementType);
clonedElement.removeClasses([MultiColumnStyleCSS.RegionContent, MultiColumnLayoutCSS.OriginalElementType]);
for (let i = containerElement.children.length - 1; i >= 0; i--) {
containerElement.children[i].detach();
}
containerElement.appendChild(originalElement);
containerElement.appendChild(clonedElement);
}
}
/**
* Sets up the CSS classes and the number of columns based on the passed settings.
* @param settings The user defined settings that determine what CSS is set here.
* @param multiColumnParent The parent object that the column divs will be created under.
* @returns The list of column divs created under the passed parent element.
*/
getColumnContentDivs(settings, multiColumnParent) {
let columnContentDivs = [];
if (typeof settings.columnSize === "string" &&
isColumnLayout(settings.columnSize) &&
(settings.numberOfColumns === 2 || settings.numberOfColumns === 3)) {
settings.columnSize = validateColumnLayout(settings.columnSize);
multiColumnParent.removeClass(MultiColumnLayoutCSS.ContentOverflowAutoScroll_X);
multiColumnParent.addClass(MultiColumnLayoutCSS.ContentOverflowHidden_X);
buildStandardLayouts(settings, multiColumnParent, columnContentDivs);
setMaxColumnHeight();
return columnContentDivs;
}
if (typeof settings.columnSize === "string" &&
isColumnLayout(settings.columnSize) &&
settings.columnSize === "standard" &&
settings.numberOfColumns > 3) {
settings.columnSize = validateColumnLayout(settings.columnSize);
multiColumnParent.removeClass(MultiColumnLayoutCSS.ContentOverflowAutoScroll_X);
multiColumnParent.addClass(MultiColumnLayoutCSS.ContentOverflowHidden_X);
buildEqualLayout(settings, multiColumnParent, columnContentDivs);
setMaxColumnHeight();
return columnContentDivs;
}
let columnSizes = [];
// If the user has defined the widths individually then we just need to create
// each column individually with each width size.
if (Array.isArray(settings.columnSize)) {
columnSizes = settings.columnSize.slice();
}
else {
calcColumnSizes(settings, columnSizes);
}
if (columnSizes.length === 0) {
columnSizes.push(HTMLSizing.create().setWidth(50).setUnits("%"));
}
for (let i = 0; i < settings.numberOfColumns; i++) {
let sizing = getIndexedClampedArrayValue(i, columnSizes);
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent}`,
attr: { "style": `width: ${sizing.toString()}` }
}));
if (i !== settings.numberOfColumns - 1) {
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(0, settings) }
});
}
}
for (let i = 0; i < columnContentDivs.length; i++) {
columnContentDivs[i].addClass(MultiColumnLayoutCSS.NoFlexShrink);
}
setMaxColumnHeight();
return columnContentDivs;
function setMaxColumnHeight() {
if (settings.columnHeight !== null) {
multiColumnParent.removeClass(MultiColumnLayoutCSS.ContentOverflowHidden_Y);
multiColumnParent.addClass(MultiColumnLayoutCSS.ContentOverflowAutoScroll_Y);
columnContentDivs.forEach((column) => {
column.style.height = settings.columnHeight.toString();
column.style.maxHeight = settings.columnHeight.toString();
column.style.minHeight = settings.columnHeight.toString();
});
}
}
}
}
function createErrorElement(errorText, alt = "", src = "") {
let errorEl = createDiv({
cls: "internal-embed markdown-embed inline-embed is-loaded",
attr: {
"tabindex": "-1",
"contenteditable": "false"
}
});
errorEl.setAttr("alt", alt);
errorEl.setAttr("src", `app://obsidian.md/${src}`);
errorEl.appendChild(createDiv({
"cls": "embed-title markdown-embed-title",
}));
let contentEl = errorEl.createDiv({
"cls": `markdown-embed-content`,
});
let paragraph = contentEl.createEl("p", {
"cls": `${MultiColumnStyleCSS.RegionErrorMessage}, ${MultiColumnStyleCSS.SmallFont}`
});
paragraph.innerText = errorText;
return errorEl;
}
function updatePDFEmbed(domElement) {
// if(domElement.canvasReadyForUpdate() === false) {
// return
// }
domElement.originalElement;
let clonedElement = domElement.clonedElement;
domElement.elementContainer;
for (let i = clonedElement.children.length - 1; i >= 0; i--) {
clonedElement.children[i].detach();
}
clonedElement.appendChild(createErrorElement("Due to an update to Obsidian's PDF viewer, PDF embeds are currently not supported.\nSorry for the inconvienence."));
return;
}
function reRenderDataviewJS(domElement) {
if (domElement.canvasReadyForUpdate() === false) {
return;
}
let originalElement = domElement.originalElement;
let clonedElement = domElement.clonedElement;
let containerElement = domElement.elementContainer;
containerElement.appendChild(originalElement);
if (clonedElement !== null && clonedElement.parentElement === containerElement) {
containerElement.removeChild(clonedElement);
}
function cloneCanvas(originalCanvas) {
//create a new canvas
let clonedCanvas = originalCanvas.cloneNode(true);
let context = clonedCanvas.getContext('2d');
//set dimensions
clonedCanvas.width = originalCanvas.width;
clonedCanvas.height = originalCanvas.height;
if (clonedCanvas.width === 0 || clonedCanvas.height === 0) {
// Dont want to render if the width is 0 as it throws an error
// would happen if the old canvas hasnt been rendered yet.
return clonedCanvas;
}
//apply the old canvas to the new one
context.drawImage(originalCanvas, 0, 0);
//return the new canvas
return clonedCanvas;
}
let canvas = searchChildrenForNodeType(originalElement, "canvas");
if (canvas !== null) {
domElement.updateClonedElement(originalElement.cloneNode(true));
clonedElement = domElement.clonedElement;
clonedElement.addClass(MultiColumnLayoutCSS.ClonedElementType);
clonedElement.removeClasses([MultiColumnStyleCSS.RegionContent, MultiColumnLayoutCSS.OriginalElementType]);
containerElement.appendChild(clonedElement);
for (let i = clonedElement.children.length - 1; i >= 0; i--) {
clonedElement.children[i].detach();
}
clonedElement.appendChild(cloneCanvas(canvas));
}
containerElement.removeChild(originalElement);
containerElement.appendChild(clonedElement);
}
function calcColumnSizes(settings, columnSizes) {
let layout = settings.columnSize;
if (settings.numberOfColumns === 2) {
switch (layout) {
case ("standard"):
case ("middle"):
case ("center"):
case ("third"):
columnSizes.push(HTMLSizing.create().setWidth(50).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(50).setUnits("%"));
break;
case ("left"):
case ("first"):
columnSizes.push(HTMLSizing.create().setWidth(75).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(25).setUnits("%"));
break;
case ("right"):
case ("second"):
case ("last"):
columnSizes.push(HTMLSizing.create().setWidth(25).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(75).setUnits("%"));
break;
}
return;
}
if (settings.numberOfColumns === 3) {
switch (layout) {
case ("standard"):
columnSizes.push(HTMLSizing.create().setWidth(33).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(33).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(33).setUnits("%"));
break;
case ("left"):
case ("first"):
columnSizes.push(HTMLSizing.create().setWidth(50).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(25).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(25).setUnits("%"));
break;
case ("middle"):
case ("center"):
case ("second"):
columnSizes.push(HTMLSizing.create().setWidth(25).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(50).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(25).setUnits("%"));
break;
case ("right"):
case ("third"):
case ("last"):
columnSizes.push(HTMLSizing.create().setWidth(25).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(25).setUnits("%"));
columnSizes.push(HTMLSizing.create().setWidth(50).setUnits("%"));
break;
}
}
}
function getElementClientHeight(element, parentRenderElement) {
let height = element.clientHeight;
if (height === 0) {
parentRenderElement.appendChild(element);
height = element.clientHeight;
parentRenderElement.removeChild(element);
}
return height;
}
function buildEqualLayout(settings, multiColumnParent, columnContentDivs) {
let percent = Math.ceil(100 / settings.numberOfColumns);
for (let i = 0; i < settings.numberOfColumns; i++) {
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent}`,
attr: { "style": `width: ${percent}%` }
}));
if (i !== settings.numberOfColumns - 1) {
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(0, settings) }
});
}
}
}
function buildStandardLayouts(settings, multiColumnParent, columnContentDivs) {
let layout = settings.columnSize;
if (settings.numberOfColumns === 2) {
switch (layout) {
case ("standard"):
case ("middle"):
case ("center"):
case ("third"):
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.TwoEqualColumns}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(0, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.TwoEqualColumns}`
}));
break;
case ("left"):
case ("first"):
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.TwoColumnLarge}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(0, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.TwoColumnSmall}`
}));
break;
case ("right"):
case ("second"):
case ("last"):
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.TwoColumnSmall}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(0, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.TwoColumnLarge}`
}));
break;
}
return;
}
if (settings.numberOfColumns === 3) {
switch (layout) {
case ("standard"):
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeEqualColumns}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(0, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeEqualColumns}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(1, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeEqualColumns}`
}));
break;
case ("left"):
case ("first"):
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeColumn_Large}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(0, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeColumn_Small}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(1, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeColumn_Small}`
}));
break;
case ("middle"):
case ("center"):
case ("second"):
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeColumn_Small}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(0, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeColumn_Large}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(1, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeColumn_Small}`
}));
break;
case ("right"):
case ("third"):
case ("last"):
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeColumn_Small}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(0, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeColumn_Small}`
}));
multiColumnParent.createDiv({
cls: `mcm-column-spacer`,
attr: { "style": columnSpacingState(1, settings) }
});
columnContentDivs.push(multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent} ${MultiColumnLayoutCSS.ThreeColumn_Large}`
}));
break;
}
}
}
function fixOnClick(domElement) {
let originalElement = domElement.originalElement;
let clonedElement = domElement.clonedElement;
let originalButton = originalElement.getElementsByTagName("button")[0];
let clonedButton = clonedElement.getElementsByTagName("button")[0];
if (originalButton === undefined || clonedButton === undefined) {
return;
}
clonedButton.onClickEvent((ev) => {
originalButton.click();
});
}
function cloneElement(domElement) {
let originalElement = domElement.originalElement;
let clonedElement = domElement.clonedElement;
let containerElement = domElement.elementContainer;
domElement.updateClonedElement(originalElement.cloneNode(true));
clonedElement = domElement.clonedElement;
/**
* If we updated the cloned element, we want to also update the
* element rendered in the parent container.
*/
for (let i = containerElement.children.length - 1; i >= 0; i--) {
containerElement.children[i].detach();
}
// Update CSS, we add cloned class and remove classes from originalElement that do not apply.
clonedElement.addClass(MultiColumnLayoutCSS.ClonedElementType);
clonedElement.removeClasses([MultiColumnStyleCSS.RegionContent, MultiColumnLayoutCSS.OriginalElementType]);
containerElement.appendChild(clonedElement);
}
function processButtonPluginUpdate(domObject) {
domObject.elementType = "buttonPlugin";
if (domObject.clonedElementReadyForUpdate() === true) {
cloneElement(domObject);
fixOnClick(domObject);
}
}
const DEFAULT_SETTINGS = {
renderOnMobile: true,
autoLayoutBalanceIterations: 5,
useLivePreviewCache: false,
alignTablesToContentAlignment: true,
renderInlineElErrors: true
};
class MCM_SettingsManager {
constructor() {
this._settings = DEFAULT_SETTINGS;
}
static get shared() {
if (MCM_SettingsManager.local === null) {
MCM_SettingsManager.local = new MCM_SettingsManager();
}
return MCM_SettingsManager.local;
}
get settings() { return this._settings; }
set settings(newVal) {
this.updateTimestamp();
this._settings = newVal;
}
get lastUpdateTimestamp() { return this._lastUpdateTimestamp; }
updateTimestamp() {
this._lastUpdateTimestamp = Date.now();
}
get renderOnMobile() { return this._settings.renderOnMobile; }
get autoLayoutBalanceIterations() { return this._settings.autoLayoutBalanceIterations; }
get useLivePreviewCache() { return this._settings.useLivePreviewCache; }
get alignTablesToContentAlignment() { return this._settings.alignTablesToContentAlignment; }
get renderInlineElErrors() { return this._settings.renderInlineElErrors; }
set renderOnMobile(newVal) {
this.updateTimestamp();
this._settings.renderOnMobile = newVal;
}
set autoLayoutBalanceIterations(newVal) {
this.updateTimestamp();
this._settings.autoLayoutBalanceIterations = newVal;
}
set useLivePreviewCache(newVal) {
this.updateTimestamp();
this._settings.useLivePreviewCache = newVal;
}
set alignTablesToContentAlignment(newVal) {
this.updateTimestamp();
this._settings.alignTablesToContentAlignment = newVal;
}
set renderInlineElErrors(newVal) {
this.updateTimestamp();
this._settings.renderInlineElErrors = newVal;
}
}
MCM_SettingsManager.local = null;
/**
* File: /src/dom_manager/regional_managers/regionDOMManager.ts *
* Created Date: Sunday, May 22nd 2022, 7:46 pm *
* Author: Cameron Robinson *
* *
* Copyright (c) 2022 Cameron Robinson *
*/
class StandardMultiColumnRegionManager extends RegionManager {
renderRegionElementsToScreen() {
this.renderColumnMarkdown(this.regionParent, this.domList, this.regionalSettings);
}
exportRegionElementsToPDF(pdfParentElement) {
// Default set shadow to off for exporting PDFs
let renderSettings = this.regionalSettings;
renderSettings.drawShadow = false;
this.renderColumnMarkdown(pdfParentElement, this.domList.slice(), renderSettings);
}
renderRegionElementsToLivePreview(parentElement) {
this.renderColumnMarkdown(parentElement, this.domList, this.regionalSettings, true);
}
/**
* This function takes in the data for the multi-column region and sets up the
* user defined number of children with the proper css classes to be rendered properly.
*
* @param parentElement The element that the multi-column region will be rendered under.
* @param regionElements The list of DOM objects that will be coppied under the parent object
* @param settings The settings the user has defined for the region.
*/
renderColumnMarkdown(parentElement, regionElements, settings, isLivePreview = false) {
let multiColumnParent = createDiv({
cls: `${MultiColumnLayoutCSS.RegionColumnContainerDiv} \
${MultiColumnLayoutCSS.ContentOverflowAutoScroll_X} \
${MultiColumnLayoutCSS.ContentOverflowHidden_Y};
`
});
/**
* Pass our parent div and settings to parser to create the required
* column divs as children of the parent.
*/
let columnContentDivs = this.getColumnContentDivs(settings, multiColumnParent);
if (settings.drawShadow === true) {
multiColumnParent.addClass(MultiColumnStyleCSS.RegionShadow);
}
for (let i = 0; i < columnContentDivs.length; i++) {
if (shouldDrawColumnBorder(i, settings) === true) {
columnContentDivs[i].addClass(MultiColumnStyleCSS.ColumnBorder);
}
if (settings.drawShadow === true) {
columnContentDivs[i].addClass(MultiColumnStyleCSS.ColumnShadow);
}
}
// Create markdown renderer to parse the passed markdown
// between the tags.
let markdownRenderChild = new obsidian.MarkdownRenderChild(multiColumnParent);
// Remove every other child from the parent so
// we dont end up with multiple sets of data. This should
// really only need to loop once for i = 0 but loop just
// in case.
for (let i = parentElement.children.length - 1; i >= 0; i--) {
parentElement.children[i].detach();
}
parentElement.appendChild(markdownRenderChild.containerEl);
this.appendElementsToColumns(regionElements, columnContentDivs, settings, isLivePreview);
}
appendElementsToColumns(regionElements, columnContentDivs, settings, isLivePreview = false) {
let columnIndex = 0;
for (let i = 0; i < regionElements.length; i++) {
if (regionElements[i].tag === DOMObjectTag.none ||
regionElements[i].tag === DOMObjectTag.columnBreak) {
// If a standard element contains a column break tag and it is set as a pre content break tag we flip our index here.
if (regionElements[i].tag === DOMObjectTag.none &&
regionElements[i].elementIsColumnBreak === ElementColumnBreakType.preBreak &&
(columnIndex + 1) < settings.numberOfColumns) {
columnIndex++;
}
// We store the elements in a wrapper container until we determine
let element = createDiv({
cls: MultiColumnLayoutCSS.ColumnDualElementContainer,
});
if (columnOverflowState(columnIndex, settings) === ContentOverflowType.hidden) {
element.addClass(MultiColumnLayoutCSS.ContentOverflowHidden_X);
}
else {
element.addClass(MultiColumnLayoutCSS.ContentOverflowAutoScroll_X);
}
let alignment = columnAlignmentState(columnIndex, settings);
if (alignment === AlignmentType.center) {
element.addClass(MultiColumnLayoutCSS.AlignmentCenter);
}
else if (alignment === AlignmentType.right) {
element.addClass(MultiColumnLayoutCSS.AlignmentRight);
}
else {
element.addClass(MultiColumnLayoutCSS.AlignmentLeft);
}
let tableAlignment = MCM_SettingsManager.shared.alignTablesToContentAlignment;
if (settings.alignTablesToAlignment !== TableAlignment.useSettingsDefault) {
tableAlignment = settings.alignTablesToAlignment === TableAlignment.align;
}
if (tableAlignment) {
element.addClass(MultiColumnLayoutCSS.TableAlignment);
}
regionElements[i].elementContainer = element;
let elementToAppend = regionElements[i].originalElement;
if (isLivePreview === false) {
let clonedElement = regionElements[i].originalElement.cloneNode(true);
let headingCollapseElement = getHeadingCollapseElement(clonedElement);
if (headingCollapseElement !== null) {
// This removes the collapse arrow from the view if it exists.
headingCollapseElement.detach();
}
regionElements[i].clonedElement = clonedElement;
elementToAppend = clonedElement;
}
element.appendChild(elementToAppend);
if (regionElements[i] instanceof TaskListDOMObject) {
this.fixClonedCheckListButtons(regionElements[i], true);
}
if (element !== null && regionElements[i].tag !== DOMObjectTag.columnBreak) {
columnContentDivs[columnIndex].appendChild(element);
}
/**
* If the tag is a column break we update the column index after
* appending the item to the column div. This keeps the main DOM
* cleaner by removing other items and placing them all within
* a region container.
*/
if (regionElements[i].tag === DOMObjectTag.columnBreak &&
(columnIndex + 1) < settings.numberOfColumns) {
columnIndex++;
}
else if (regionElements[i].tag === DOMObjectTag.none &&
regionElements[i].elementIsColumnBreak === ElementColumnBreakType.postBreak &&
(columnIndex + 1) < settings.numberOfColumns) {
// If a standard element contains a column break tag and it is set as a post content break tag we flip our index here.
columnIndex++;
}
}
}
}
}
/**
* File: /src/dom_manager/regional_managers/singleColumnRegionManager.ts *
* Author: Cameron Robinson *
* *
* Copyright (c) 2023 Cameron Robinson *
*/
class SingleColumnRegionManager extends RegionManager {
renderRegionElementsToScreen() {
this.renderColumnMarkdown(this.regionParent, this.domList, this.regionalSettings);
}
exportRegionElementsToPDF(pdfParentElement) {
// Default set shadow to off for exporting PDFs
let renderSettings = this.regionalSettings;
renderSettings.drawShadow = false;
this.renderColumnMarkdown(pdfParentElement, this.domList.slice(), renderSettings);
}
renderRegionElementsToLivePreview(parentElement) {
this.renderColumnMarkdown(parentElement, this.domList, this.regionalSettings, true);
}
/**
* This function takes in the data for the multi-column region and sets up the
* user defined number of children with the proper css classes to be rendered properly.
*
* @param parentElement The element that the multi-column region will be rendered under.
* @param regionElements The list of DOM objects that will be coppied under the parent object
* @param settings The settings the user has defined for the region.
*/
renderColumnMarkdown(parentElement, regionElements, settings, isLivePreview = false) {
let multiColumnParent = createDiv({
cls: `${MultiColumnLayoutCSS.RegionColumnContainerDiv} \
${MultiColumnLayoutCSS.ContentOverflowAutoScroll_X} \
${MultiColumnLayoutCSS.ContentOverflowHidden_Y};
`
});
if (isLeftLayout(this.regionalSettings.columnPosition)) {
multiColumnParent.addClass(MultiColumnLayoutCSS.SingleColumnLeftLayout);
}
else if (isRightLayout(this.regionalSettings.columnPosition)) {
multiColumnParent.addClass(MultiColumnLayoutCSS.SingleColumnRightLayout);
}
else {
multiColumnParent.addClass(MultiColumnLayoutCSS.SingleColumnCenterLayout);
}
/**
* Pass our parent div and settings to parser to create the required
* column divs as children of the parent.
*/
let columnContentDiv = this.createColumnContentDivs(multiColumnParent);
if (shouldDrawColumnBorder(0, settings) === true) {
columnContentDiv.addClass(MultiColumnStyleCSS.ColumnBorder);
}
if (settings.drawShadow === true) {
columnContentDiv.addClass(MultiColumnStyleCSS.ColumnShadow);
}
// Create markdown renderer to parse the passed markdown
// between the tags.
let markdownRenderChild = new obsidian.MarkdownRenderChild(multiColumnParent);
// Remove every other child from the parent so
// we dont end up with multiple sets of data. This should
// really only need to loop once for i = 0 but loop just
// in case.
for (let i = parentElement.children.length - 1; i >= 0; i--) {
parentElement.children[i].detach();
}
parentElement.appendChild(markdownRenderChild.containerEl);
this.appendElementsToColumns(regionElements, columnContentDiv, settings, isLivePreview);
}
appendElementsToColumns(regionElements, columnContentDiv, settings, isLivePreview = false) {
for (let i = 0; i < regionElements.length; i++) {
if (regionElements[i].tag === DOMObjectTag.none ||
regionElements[i].tag === DOMObjectTag.columnBreak) {
// We store the elements in a wrapper container until we determine
let element = createDiv({
cls: MultiColumnLayoutCSS.ColumnDualElementContainer,
});
regionElements[i].elementContainer = element;
if (columnOverflowState(0, settings) === ContentOverflowType.hidden) {
element.addClass(MultiColumnLayoutCSS.ContentOverflowHidden_X);
}
else {
element.addClass(MultiColumnLayoutCSS.ContentOverflowAutoScroll_X);
}
let alignment = columnAlignmentState(0, settings);
if (alignment === AlignmentType.center) {
element.addClass(MultiColumnLayoutCSS.AlignmentCenter);
}
else if (alignment === AlignmentType.right) {
element.addClass(MultiColumnLayoutCSS.AlignmentRight);
}
else {
element.addClass(MultiColumnLayoutCSS.AlignmentLeft);
}
let tableAlignment = MCM_SettingsManager.shared.alignTablesToContentAlignment;
if (settings.alignTablesToAlignment !== TableAlignment.useSettingsDefault) {
tableAlignment = settings.alignTablesToAlignment === TableAlignment.align;
}
if (tableAlignment) {
element.addClass(MultiColumnLayoutCSS.TableAlignment);
}
let elementToAppend = regionElements[i].originalElement;
if (isLivePreview === false) {
let clonedElement = regionElements[i].originalElement.cloneNode(true);
let headingCollapseElement = getHeadingCollapseElement(clonedElement);
if (headingCollapseElement !== null) {
// This removes the collapse arrow from the view if it exists.
headingCollapseElement.detach();
}
regionElements[i].clonedElement = clonedElement;
elementToAppend = clonedElement;
}
element.appendChild(elementToAppend);
if (regionElements[i] instanceof TaskListDOMObject) {
this.fixClonedCheckListButtons(regionElements[i], true);
}
if (element !== null) {
columnContentDiv.appendChild(element);
}
}
}
}
createColumnContentDivs(multiColumnParent) {
let contentDiv = multiColumnParent.createDiv({
cls: `${MultiColumnStyleCSS.ColumnContent}`
});
if (this.regionalSettings.columnSize === "small") {
contentDiv.addClass(`${MultiColumnLayoutCSS.SingleColumnSmall}`);
}
else if (this.regionalSettings.columnSize === "large") {
contentDiv.addClass(`${MultiColumnLayoutCSS.SingleColumnLarge}`);
}
else if (this.regionalSettings.columnSize === "full") {
contentDiv.addClass(`${MultiColumnLayoutCSS.SingleColumnFull}`);
}
else {
contentDiv.addClass(`${MultiColumnLayoutCSS.SingleColumnMed}`);
}
return contentDiv;
}
}
function isLeftLayout(layout) {
if (layout === "left" ||
layout === "first") {
return true;
}
return false;
}
function isRightLayout(layout) {
if (layout === "right" ||
layout === "third" ||
layout === "last") {
return true;
}
return false;
}
/**
* File: /src/dom_manager/regional_managers/autoLayoutRegionManager.ts *
* Created Date: Sunday, May 22nd 2022, 10:23 pm *
* Author: Cameron Robinson *
* *
* Copyright (c) 2022 Cameron Robinson *
*/
class AutoLayoutRegionManager extends RegionManager {
constructor(data, isLivePreview = false) {
super(data);
this.isLivePreview = false;
this.previousColumnHeights = [];
this.isLivePreview = isLivePreview;
this.docReflow = data.regionalSettings.fullDocReflow;
}
renderRegionElementsToScreen() {
this.renderColumnMarkdown(this.regionParent, this.domList, this.regionalSettings);
}
exportRegionElementsToPDF(pdfParentElement) {
// Default set shadow to off for exporting PDFs
let renderSettings = this.regionalSettings;
renderSettings.drawShadow = false;
this.renderColumnMarkdown(pdfParentElement, this.domList.slice(), renderSettings);
}
renderRegionElementsToLivePreview(parentElement) {
this.renderColumnMarkdown(parentElement, this.domList, this.regionalSettings, true);
}
/**
* This function takes in the data for the multi-column region and sets up the
* user defined number of children with the proper css classes to be rendered properly.
*
* @param parentElement The element that the multi-column region will be rendered under.
* @param regionElements The list of DOM objects that will be coppied under the parent object
* @param settings The settings the user has defined for the region.
*/
renderColumnMarkdown(parentElement, regionElements, settings, isLivePreview = false) {
let multiColumnParent = createDiv({
cls: `${MultiColumnLayoutCSS.RegionColumnContainerDiv} \
${MultiColumnLayoutCSS.ContentOverflowAutoScroll_X} \
${MultiColumnLayoutCSS.ContentOverflowHidden_Y};
`
});
this.columnParent = multiColumnParent;
/**
* Pass our parent div and settings to parser to create the required
* column divs as children of the parent.
*/
this.columnDivs = this.getColumnContentDivs(settings, multiColumnParent);
if (settings.drawShadow === true) {
multiColumnParent.addClass(MultiColumnStyleCSS.RegionShadow);
}
for (let i = 0; i < this.columnDivs.length; i++) {
if (shouldDrawColumnBorder(i, settings) === true) {
this.columnDivs[i].addClass(MultiColumnStyleCSS.ColumnBorder);
}
if (settings.drawShadow === true) {
this.columnDivs[i].addClass(MultiColumnStyleCSS.ColumnShadow);
}
}
// Remove every other child from the parent so
// we dont end up with multiple sets of data. This should
// really only need to loop once for i = 0 but loop just
// in case.
for (let i = parentElement.children.length - 1; i >= 0; i--) {
parentElement.children[i].detach();
}
parentElement.appendChild(multiColumnParent);
this.appendElementsToColumns(regionElements, this.columnDivs, settings, isLivePreview);
}
appendElementsToColumns(regionElements, columnContentDivs, settings, isLivePreview = false) {
function balanceElements() {
let totalHeight = regionElements.map((el, index) => {
// We only want to attempt to update the elementRenderedHeight if it is 0 and if it is not an unrendered element such as a endregion tag.
if (el.elementRenderedHeight === 0 &&
el.tag !== DOMObjectTag.columnBreak &&
el.tag !== DOMObjectTag.endRegion &&
el.tag !== DOMObjectTag.regionSettings &&
el.tag !== DOMObjectTag.startRegion) {
// Add element to rendered div so we can extract the rendered height.
columnContentDivs[0].appendChild(el.originalElement);
el.elementRenderedHeight = el.originalElement.clientHeight;
columnContentDivs[0].removeChild(el.originalElement);
}
return el.elementRenderedHeight;
}).reduce((prev, curr) => { return prev + curr; }, 0);
let maxColumnContentHeight = Math.trunc(totalHeight / settings.numberOfColumns);
for (let i = 0; i < columnContentDivs.length; i++) {
for (let j = columnContentDivs[i].children.length - 1; j >= 0; j--) {
columnContentDivs[i].children[j].detach();
}
}
let columnIndex = 0;
let currentColumnHeight = 0;
function checkShouldSwitchColumns(nextElementHeight) {
if (currentColumnHeight + nextElementHeight > maxColumnContentHeight &&
(columnIndex + 1) < settings.numberOfColumns) {
columnIndex++;
currentColumnHeight = 0;
}
}
for (let i = 0; i < regionElements.length; i++) {
if (regionElements[i].tag === DOMObjectTag.none ||
regionElements[i].tag === DOMObjectTag.columnBreak) {
/**
* Here we check if we need to swap to the next column for the current element.
* If the user wants to keep headings with the content below it we also make sure
* that the last item in a column is not a header element by using the header and
* the next element's height as the height value.
*/
if (hasHeader(regionElements[i].originalElement) === true) { // TODO: Add this as selectable option.
let headerAndNextElementHeight = regionElements[i].elementRenderedHeight;
if (i < regionElements.length - 1) {
headerAndNextElementHeight += regionElements[i + 1].elementRenderedHeight;
}
checkShouldSwitchColumns(headerAndNextElementHeight);
}
else {
checkShouldSwitchColumns(regionElements[i].elementRenderedHeight);
}
currentColumnHeight += regionElements[i].elementRenderedHeight;
/**
* We store the elements in a wrapper container until we determine if we want to
* use the original element or a clone of the element. This helps us by allowing
* us to create a visual only clone while the update loop moves the original element
* into the columns.
*/
let element = createDiv({
cls: MultiColumnLayoutCSS.ColumnDualElementContainer,
});
regionElements[i].elementContainer = element;
if (columnOverflowState(columnIndex, settings) === ContentOverflowType.hidden) {
element.addClass(MultiColumnLayoutCSS.ContentOverflowHidden_X);
}
else {
element.addClass(MultiColumnLayoutCSS.ContentOverflowAutoScroll_X);
}
let alignment = columnAlignmentState(columnIndex, settings);
if (alignment === AlignmentType.center) {
element.addClass(MultiColumnLayoutCSS.AlignmentCenter);
}
else if (alignment === AlignmentType.right) {
element.addClass(MultiColumnLayoutCSS.AlignmentRight);
}
else {
element.addClass(MultiColumnLayoutCSS.AlignmentLeft);
}
let tableAlignment = MCM_SettingsManager.shared.alignTablesToContentAlignment;
if (settings.alignTablesToAlignment !== TableAlignment.useSettingsDefault) {
tableAlignment = settings.alignTablesToAlignment === TableAlignment.align;
}
if (tableAlignment) {
element.addClass(MultiColumnLayoutCSS.TableAlignment);
}
let elementToAppend = regionElements[i].originalElement;
if (isLivePreview === false) {
let clonedElement = regionElements[i].clonedElement;
if (regionElements[i].clonedElement === null) {
clonedElement = regionElements[i].originalElement.cloneNode(true);
let headingCollapseElement = getHeadingCollapseElement(clonedElement);
if (headingCollapseElement !== null) {
// This removes the collapse arrow from the view if it exists.
headingCollapseElement.detach();
}
regionElements[i].clonedElement = clonedElement;
elementToAppend = clonedElement;
}
}
element.appendChild(elementToAppend);
if (regionElements[i] instanceof TaskListDOMObject) {
this.fixClonedCheckListButtons(regionElements[i], true);
}
if (element !== null &&
columnContentDivs[columnIndex] &&
regionElements[i].tag !== DOMObjectTag.columnBreak) {
columnContentDivs[columnIndex].appendChild(element);
regionElements[i].elementRenderedHeight = element.clientHeight;
}
/**
* If the tag is a column break we update the column index after
* appending the item to the column div. This keeps the main DOM
* cleaner by removing other items and placing them all within
* a region container.
*
* Removing the end column tag as an option for now.
*/
// if (regionElements[i].tag === DOMObjectTag.columnBreak &&
// (columnIndex + 1) < settings.numberOfColumns) {
// columnIndex++;
// currentColumnHeight = 0;
// }
}
}
}
/**
* Attempt to balanced the elements. We need to iterate over the elements multiple times because
* our initial balance estimate may not be perfectly balanced due to different column widths causing
* elements within them to be of different heights. This can cause the elements to jump around on
* subsiquent update loops which is not ideal. Here we render the elements to the screen and update
* their height after being rendered into the estimated position.
*
* Once everything is rendered we check all of the column heights against our last iteration and
* if nothing has changed we know we are balanced.
*
* There is probably a better way of accomplishing this task but this works for the time being.
*/
let autoLayoutBalanceIterations = 1;
if (this.isLivePreview === false) {
autoLayoutBalanceIterations = MCM_SettingsManager.shared.autoLayoutBalanceIterations;
}
for (let i = 0; i < autoLayoutBalanceIterations; i++) {
balanceElements();
let balanced = true;
for (let j = 0; j < columnContentDivs.length; j++) {
// If the column heights are undefined we set default to zero so not to encounter an error.
if (!this.previousColumnHeights[j]) {
this.previousColumnHeights.push(0);
}
// if this render height is not the same as the previous height we are still balancing.
if (this.previousColumnHeights[j] !== columnContentDivs[j].clientHeight) {
this.previousColumnHeights[j] = columnContentDivs[j].clientHeight;
balanced = false;
}
}
// if we made it out of the loop and all of the columns are the same height as last update
// we're balanced so we can break out of the loop.
if (balanced === true) {
break;
}
}
}
updateRenderedMarkdown() {
if (this.docReflow === true) {
super.updateRenderedMarkdown();
return;
}
for (let i = 0; i < this.domList.length; i++) {
let el = this.domList[i];
let originalClientHeight = 0;
if (el.originalElement) {
originalClientHeight = el.originalElement.clientHeight;
}
let clonedClientHeight = 0;
if (el.clonedElement) {
clonedClientHeight = el.clonedElement.clientHeight;
}
if (originalClientHeight < clonedClientHeight) {
this.domList[i].elementRenderedHeight = clonedClientHeight;
}
else {
this.domList[i].elementRenderedHeight = originalClientHeight;
}
}
let validColumns = true;
if (this.columnParent !== null && this.columnDivs !== null && this.columnDivs !== undefined &&
this.columnDivs.length === this.regionalSettings.numberOfColumns) {
let totalHeight = this.domList.map((el, index) => {
// We only want to attempt to update the elementRenderedHeight if it is 0 and if it is not an unrendered element such as a endregion tag.
if (el.elementRenderedHeight === 0 &&
el.tag !== DOMObjectTag.columnBreak &&
el.tag !== DOMObjectTag.endRegion &&
el.tag !== DOMObjectTag.regionSettings &&
el.tag !== DOMObjectTag.startRegion) {
// Add element to rendered div so we can extract the rendered height.
this.columnParent.appendChild(el.originalElement);
el.elementRenderedHeight = el.originalElement.clientHeight;
this.columnParent.removeChild(el.originalElement);
}
return el.elementRenderedHeight;
}).reduce((prev, curr) => { return prev + curr; }, 0);
let maxColumnContentHeight = Math.trunc(totalHeight / this.regionalSettings.numberOfColumns);
for (let i = 0; i < this.columnDivs.length - 1; i++) {
let columnHeight = 0;
for (let j = 0; j < this.columnDivs[i].children.length; j++) {
columnHeight += this.columnDivs[i].children[j].clientHeight;
}
if (columnHeight > maxColumnContentHeight) {
validColumns = false;
break;
}
}
}
if (validColumns === false) {
this.renderColumnMarkdown(this.regionParent, this.domList, this.regionalSettings);
}
super.updateRenderedMarkdown();
}
}
/**
* File: /src/dom_manager/regional_managers/reflowRegionManager.ts *
* Created Date: Thursday, May 11th 2023, 9:59 pm *
* Author: Cameron Robinson *
* *
* Copyright (c) 2023 Cameron Robinson *
*/
class ReflowRegionManager extends RegionManager {
renderRegionElementsToScreen() {
this.renderColumnMarkdown(this.regionParent, this.domList, this.regionalSettings);
}
exportRegionElementsToPDF(pdfParentElement) {
// Default set shadow to off for exporting PDFs
let renderSettings = this.regionalSettings;
renderSettings.drawShadow = false;
this.renderColumnMarkdown(pdfParentElement, this.domList.slice(), renderSettings);
}
renderRegionElementsToLivePreview(parentElement) {
this.renderColumnMarkdown(parentElement, this.domList, this.regionalSettings);
}
/**
* This function takes in the data for the multi-column region and sets up the
* user defined number of children with the proper css classes to be rendered properly.
*
* @param parentElement The element that the multi-column region will be rendered under.
* @param regionElements The list of DOM objects that will be coppied under the parent object
* @param settings The settings the user has defined for the region.
*/
renderColumnMarkdown(parentElement, regionElements, settings) {
let verticalColumnParent = createDiv({
cls: ``
});
/**
* Pass our parent div and settings to parser to create the required
* column divs as children of the parent.
*/
// Remove every other child from the parent so
// we dont end up with multiple sets of data. This should
// really only need to loop once for i = 0 but loop just
// in case.
for (let i = parentElement.children.length - 1; i >= 0; i--) {
parentElement.children[i].detach();
}
parentElement.appendChild(verticalColumnParent);
this.appendElementsToColumns(verticalColumnParent, regionElements, settings);
}
appendElementsToColumns(verticalColumnParent, regionElements, settings) {
this.domList.forEach((el, index) => {
// We only want to attempt to update the elementRenderedHeight if it is 0 and if it is not an unrendered element such as a endregion tag.
if (el.elementRenderedHeight === 0 &&
el.tag !== DOMObjectTag.columnBreak &&
el.tag !== DOMObjectTag.endRegion &&
el.tag !== DOMObjectTag.regionSettings &&
el.tag !== DOMObjectTag.startRegion) {
// Add element to rendered div so we can extract the rendered height.
verticalColumnParent.appendChild(el.originalElement);
el.elementRenderedHeight = el.originalElement.clientHeight;
verticalColumnParent.removeChild(el.originalElement);
}
});
let maxColumnContentHeight = settings.columnHeight.sizeValue;
let columnIndex = 0;
let currentColumnHeight = 0;
let divCount = 1;
let colDivsCallback = (settings, multiColumnParent) => {
return this.getColumnContentDivs(settings, multiColumnParent);
};
let columns = getFormattedColumnDivs(settings, verticalColumnParent, colDivsCallback, divCount);
for (let i = 0; i < regionElements.length; i++) {
if (regionElements[i].tag === DOMObjectTag.none ||
regionElements[i].tag === DOMObjectTag.columnBreak) {
/**
* Here we check if we need to swap to the next column for the current element.
* If the user wants to keep headings with the content below it we also make sure
* that the last item in a column is not a header element by using the header and
* the next element's height as the height value.
*/
if (hasHeader(regionElements[i].originalElement) === true) { // TODO: Add this as selectable option.
let headerAndNextElementHeight = regionElements[i].elementRenderedHeight;
if (i < regionElements.length - 1) {
headerAndNextElementHeight += regionElements[i + 1].elementRenderedHeight;
}
checkShouldSwitchColumns(headerAndNextElementHeight);
}
else {
checkShouldSwitchColumns(regionElements[i].elementRenderedHeight);
}
currentColumnHeight += regionElements[i].elementRenderedHeight;
/**
* We store the elements in a wrapper container until we determine if we want to
* use the original element or a clone of the element. This helps us by allowing
* us to create a visual only clone while the update loop moves the original element
* into the columns.
*/
let element = createDiv({
cls: MultiColumnLayoutCSS.ColumnDualElementContainer,
});
regionElements[i].elementContainer = element;
if (columnOverflowState(columnIndex, settings) === ContentOverflowType.hidden) {
element.addClass(MultiColumnLayoutCSS.ContentOverflowHidden_X);
}
else {
element.addClass(MultiColumnLayoutCSS.ContentOverflowAutoScroll_X);
}
let alignment = columnAlignmentState(columnIndex, settings);
if (alignment === AlignmentType.center) {
element.addClass(MultiColumnLayoutCSS.AlignmentCenter);
}
else if (alignment === AlignmentType.right) {
element.addClass(MultiColumnLayoutCSS.AlignmentRight);
}
else {
element.addClass(MultiColumnLayoutCSS.AlignmentLeft);
}
let tableAlignment = MCM_SettingsManager.shared.alignTablesToContentAlignment;
if (settings.alignTablesToAlignment !== TableAlignment.useSettingsDefault) {
tableAlignment = settings.alignTablesToAlignment === TableAlignment.align;
}
if (tableAlignment) {
element.addClass(MultiColumnLayoutCSS.TableAlignment);
}
let clonedElement = regionElements[i].clonedElement;
if (regionElements[i].clonedElement === null) {
clonedElement = regionElements[i].originalElement.cloneNode(true);
let headingCollapseElement = getHeadingCollapseElement(clonedElement);
if (headingCollapseElement !== null) {
// This removes the collapse arrow from the view if it exists.
headingCollapseElement.detach();
}
regionElements[i].clonedElement = clonedElement;
}
element.appendChild(clonedElement);
if (regionElements[i] instanceof TaskListDOMObject) {
this.fixClonedCheckListButtons(regionElements[i], true);
}
if (element !== null &&
columns[columnIndex] &&
regionElements[i].tag !== DOMObjectTag.columnBreak) {
columns[columnIndex].appendChild(element);
regionElements[i].elementRenderedHeight = element.clientHeight;
}
/**
* If the tag is a column break we update the column index after
* appending the item to the column div. This keeps the main DOM
* cleaner by removing other items and placing them all within
* a region container.
*/
if (regionElements[i].tag === DOMObjectTag.columnBreak) {
checkCreateNewColumns();
columnIndex++;
currentColumnHeight = 0;
}
}
}
function checkShouldSwitchColumns(nextElementHeight) {
if (currentColumnHeight + nextElementHeight < maxColumnContentHeight) {
return;
}
checkCreateNewColumns();
columnIndex++;
currentColumnHeight = 0;
}
function checkCreateNewColumns() {
if ((columnIndex + 1) >= columns.length) {
divCount++;
columns = columns.concat(getFormattedColumnDivs(settings, verticalColumnParent, colDivsCallback, divCount));
}
}
}
}
function getFormattedColumnDivs(settings, verticalColumnParent, getColumnContentDivs, divCount) {
let multiColumnParent = verticalColumnParent.createDiv({
cls: `${MultiColumnLayoutCSS.RegionColumnContainerDiv} \
${MultiColumnLayoutCSS.ContentOverflowAutoScroll_X} \
${MultiColumnLayoutCSS.ContentOverflowHidden_Y};
`
});
if (divCount > 1) {
multiColumnParent.addClass(`${MultiColumnLayoutCSS.ReflowContainerDiv}`);
}
let columnDivs = getColumnContentDivs(settings, multiColumnParent);
if (settings.drawShadow === true) {
multiColumnParent.addClass(MultiColumnStyleCSS.RegionShadow);
}
for (let i = 0; i < columnDivs.length; i++) {
if (shouldDrawColumnBorder(i, settings) === true) {
columnDivs[i].addClass(MultiColumnStyleCSS.ColumnBorder);
}
if (settings.drawShadow === true) {
columnDivs[i].addClass(MultiColumnStyleCSS.ColumnShadow);
}
}
return columnDivs;
}
/**
* File: /src/dom_manager/regional_managers/regionManagerContainer.ts *
* Created Date: Sunday, May 22nd 2022, 7:50 pm *
* Author: Cameron Robinson *
* *
* Copyright (c) 2022 Cameron Robinson *
*/
/**
* This class acts as an abstraction for the actual regional manager. It is used to update the
* subclass of RegionalManager depending on user preferences to make rendering more simplified.
*/
class RegionManagerContainer {
constructor(parentFileManager, regionKey, rootElement, regionParent, errorManager) {
this.region = new StandardMultiColumnRegionManager(createDefaultRegionManagerData(regionParent, parentFileManager, regionKey, rootElement, errorManager));
}
getRegion() {
return this.region;
}
setRegionSettings(settingsText) {
let regionalSettings = parseColumnSettings(settingsText);
if (regionalSettings.numberOfColumns === 1) {
regionalSettings = parseSingleColumnSettings(settingsText, regionalSettings);
}
return this.setRegionParsedSettings(regionalSettings);
}
setRegionParsedSettings(regionalSettings) {
this.region.setRegionalSettings(regionalSettings);
if (regionalSettings.numberOfColumns === 1) {
if (this.region instanceof SingleColumnRegionManager === false) {
// console.debug("Converting region to single column.")
this.convertToSingleColumn();
}
}
else if (regionalSettings.autoLayout === true) {
if (this.region instanceof AutoLayoutRegionManager === false) {
// console.debug("Converting region to auto layout.")
this.convertToAutoLayout();
}
}
else if (regionalSettings.fullDocReflow === true) {
if (this.region instanceof ReflowRegionManager === false) {
// console.debug("Converting region to auto layout.")
this.convertToDocReflow();
}
}
else if (regionalSettings.numberOfColumns >= 2) {
if (this.region instanceof StandardMultiColumnRegionManager === false) {
// console.debug("Converting region to standard multi-column")
this.convertToStandardMultiColumn();
}
}
return this.region;
}
convertToSingleColumn() {
let data = this.region.getRegionData();
this.region = new SingleColumnRegionManager(data);
return this.region;
}
convertToStandardMultiColumn() {
let data = this.region.getRegionData();
this.region = new StandardMultiColumnRegionManager(data);
return this.region;
}
convertToAutoLayout() {
let data = this.region.getRegionData();
this.region = new AutoLayoutRegionManager(data);
return this.region;
}
convertToDocReflow() {
let data = this.region.getRegionData();
this.region = new ReflowRegionManager(data);
return this.region;
}
}
function createDefaultRegionManagerData(regionParent, fileManager, regionKey, rootElement, errorManager) {
return {
domList: [],
domObjectMap: new Map(),
regionParent: regionParent,
fileManager: fileManager,
regionalSettings: getDefaultMultiColumnSettings(),
regionKey: regionKey,
rootElement: rootElement,
errorManager: errorManager
};
}
/*
* File: multi-column-markdown/src/domManager.ts
* Created Date: Saturday, January 30th 2022, 3:16:32 pm
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
/**
* This class handles the global managers keeping track of all open files that
* contain MCM-Regions.
*/
class GlobalDOMManager {
constructor() {
this.managers = new Map();
}
removeFileManagerCallback(key) {
if (this.managers.has(key) === true) {
this.managers.delete(key);
}
}
getFileManager(key) {
let fileManager = null;
if (this.managers.has(key) === true) {
fileManager = this.managers.get(key);
}
else {
fileManager = new FileDOMManager(this, key);
this.managers.set(key, fileManager);
}
return fileManager;
}
getAllFileManagers() {
return Array.from(this.managers.values());
}
}
class FileDOMManager {
constructor(parentManager, fileKey) {
this.regionMap = new Map();
this.hasStartTag = false;
this.parentManager = parentManager;
this.fileKey = fileKey;
}
removeRegion(regionKey) {
let regionContainer = this.regionMap.get(regionKey);
if (regionContainer === undefined) {
return;
}
let regionalManager = regionContainer.getRegion();
regionalManager.displayOriginalElements();
this.regionMap.delete(regionKey);
if (this.regionMap.size === 0) {
this.parentManager.removeFileManagerCallback(this.fileKey);
}
}
createRegionalManager(regionKey, rootElement, errorManager, renderRegionElement) {
let regonalContainer = new RegionManagerContainer(this, regionKey, rootElement, renderRegionElement, errorManager);
this.regionMap.set(regionKey, regonalContainer);
return regonalContainer.getRegion();
}
getRegionalContainer(regionKey) {
let regonalManager = null;
if (this.regionMap.has(regionKey) === true) {
regonalManager = this.regionMap.get(regionKey);
}
return regonalManager;
}
getAllRegionalManagers() {
let containers = Array.from(this.regionMap.values());
let regions = containers.map((curr) => { return curr.getRegion(); });
return regions;
}
setHasStartTag() {
this.hasStartTag = true;
}
getHasStartTag() {
return this.hasStartTag;
}
getNumberOfRegions() {
return this.regionMap.size;
}
checkKeyExists(checkKey) {
return this.regionMap.has(checkKey);
}
}
class RegionErrorManager {
get totalNumMessages() {
return this.errorMessages.length + this.warningMessages.length;
}
constructor(rootElement, initialErrorMessages = []) {
this.errorMessages = [];
this.warningMessages = [];
this.errorMessages = initialErrorMessages;
this.setRegionRootElement(rootElement);
}
addErrorMessage(errorString) {
this.errorMessages.push(errorString);
this.updateErrorView();
}
addWarningMessage(warningString) {
this.warningMessages.push(warningString);
this.updateErrorView();
}
setRegionRootElement(rootElement) {
this.errorParentElement = rootElement.createDiv({
cls: `${MultiColumnLayoutCSS.RegionErrorContainerDiv}`,
});
this.titleRegion = this.errorParentElement.createDiv({
cls: `${MultiColumnLayoutCSS.ErrorRegionPadding}`
});
this.contentEl = this.errorParentElement.createDiv({
cls: `${MultiColumnLayoutCSS.ErrorRegionPadding} mcm-message-region`
});
this.updateErrorView();
}
setupErrorHeader() {
if (this.errorMessages.length > 0) {
let text = "Error";
if (this.errorMessages.length > 1) {
text = text + "s";
}
this.titleRegion.createSpan({
attr: { "style": "color: var(--text-error); padding: 5px;" },
text: "\u2A02"
});
this.titleRegion.createSpan({
text: `${this.errorMessages.length} ${text}`
});
}
if (this.errorMessages.length > 0 && this.warningMessages.length > 0) {
this.titleRegion.createSpan({
text: ` and `
});
}
if (this.warningMessages.length > 0) {
let text = "Warning";
if (this.warningMessages.length > 1) {
text = text + "s";
}
this.titleRegion.createSpan({
attr: { "style": "color: var(--color-yellow); padding: 5px;" },
text: "\u26A0"
});
this.titleRegion.createSpan({
text: `${this.warningMessages.length} ${text}`
});
}
this.titleRegion.createSpan({
text: ` in region`
});
let regionOpened = false;
this.titleRegion.addEventListener("click", (ev) => {
this.titleRegion.classList.toggle("mcm-error-heading-open");
regionOpened = !regionOpened;
if (regionOpened) {
this.contentEl.style.maxHeight = this.contentEl.scrollHeight + "px";
}
else {
this.contentEl.style.maxHeight = null;
}
});
}
updateErrorView() {
this.resetErrorView();
if (this.totalNumMessages === 0) {
return;
}
this.titleRegion.addClass(`mcm-error-heading`); //TODO: move to const.
this.errorParentElement.classList.add(MultiColumnStyleCSS.ColumnBorder);
this.setupErrorHeader();
this.appendContentToEl();
}
appendContentToEl() {
for (let i = 0; i < this.errorMessages.length; i++) {
let p = this.contentEl.createEl("p");
p.innerHTML = `<span class="mcm-error-icon">\u2A02</span>${this.errorMessages[0]}`;
}
for (let i = 0; i < this.warningMessages.length; i++) {
let p = this.contentEl.createEl("p");
p.innerHTML = `<span class="mcm-warning-icon">\u26A0</span>${this.warningMessages[0]}`;
}
}
resetErrorView() {
var _a;
this.errorParentElement.classList.remove(MultiColumnStyleCSS.ColumnBorder);
this.titleRegion.removeClass(`mcm-error-heading`); //TODO: move to const.
while (this.titleRegion.children.length > 0) {
this.titleRegion.childNodes.forEach(child => {
this.titleRegion.removeChild(child);
});
}
if (this.contentEl === null) {
return;
}
let children = (_a = this.contentEl) === null || _a === void 0 ? void 0 : _a.childNodes;
children.forEach(child => {
if (child !== null && child.parentElement === this.contentEl) {
this.contentEl.removeChild(child);
}
});
}
}
function createColBreakWarning(type, errorManager) {
let typeErrorStr = "";
if (type === ElementColumnBreakType.preBreak) {
typeErrorStr = "at the begining of another element";
}
if (type === ElementColumnBreakType.postBreak) {
typeErrorStr = "at the end of another element";
}
if (type === ElementColumnBreakType.midBreak) {
typeErrorStr = "in the middle of two elements";
}
errorManager.addWarningMessage(`Detected a column break tag ${typeErrorStr}. Please make sure to surround column breaks with empty lines on both sides, or render issues may occur.`);
}
function parseColBreakErrorType(elementInfo, errorManager) {
if (elementInfo.objectTag !== DOMObjectTag.columnBreak &&
elementInfo.colBreakType === ElementColumnBreakType.none) {
return;
}
let errorType = elementInfo.colBreakType;
if (elementInfo.objectTag === DOMObjectTag.columnBreak) {
if (elementInfo.lineAbove === "" &&
elementInfo.lineBelow === "") {
return;
}
let lineAbove = elementInfo.lineAbove;
let lineBelow = elementInfo.lineBelow;
if (lineAbove !== "" && lineBelow === "") {
errorType = ElementColumnBreakType.postBreak;
}
if (lineAbove === "" && lineBelow !== "") {
errorType = ElementColumnBreakType.preBreak;
}
if (lineAbove !== "" && lineBelow !== "") {
errorType = ElementColumnBreakType.midBreak;
}
}
createColBreakWarning(errorType, errorManager);
}
function getLeafFromFilePath(workspace, filePath) {
function checkState(state) {
if (state["type"] === undefined ||
state["type"] !== "markdown") {
return false;
}
if (state["state"] === undefined) {
return false;
}
if (state["state"]["file"] === undefined) {
return false;
}
let stateFilePath = state["state"]["file"];
return stateFilePath === filePath;
}
if (workspace === null) {
return null;
}
let entries = Object.entries(workspace.getLayout());
let items = Array.from(entries).map((val) => {
return val[1];
});
while (items.length > 0) {
let entryObj = items.shift();
if (entryObj["id"] !== undefined && entryObj["type"] !== undefined) {
if (entryObj["type"] === "split" ||
entryObj["type"] === "tabs") {
items = items.concat(entryObj['children']);
continue;
}
if (entryObj["type"] === "leaf" &&
entryObj["id"] !== undefined &&
entryObj["state"] !== undefined) {
let id = entryObj["id"];
let state = entryObj["state"];
console.log(state);
let valid = checkState(state);
if (valid) {
return workspace.getLeafById(id);
}
}
}
}
return null;
}
function getPreviewLeafFromFilePath(workspace, filePath) {
function checkState(state) {
if (state["type"] === undefined ||
state["type"] !== "markdown") {
return false;
}
if (state["state"] === undefined) {
return false;
}
if (state["state"]["file"] === undefined) {
return false;
}
let stateFilePath = state["state"]["file"];
return stateFilePath === filePath;
}
let entries = Object.entries(workspace.getLayout());
let items = Array.from(entries).map((val) => {
return val[1];
});
while (items.length > 0) {
let entryObj = items.shift();
if (entryObj["id"] !== undefined && entryObj["type"] !== undefined) {
if (entryObj["type"] === "split" ||
entryObj["type"] === "tabs") {
items = items.concat(entryObj['children']);
continue;
}
if (entryObj["type"] === "leaf" &&
entryObj["id"] !== undefined &&
entryObj["state"] !== undefined) {
let id = entryObj["id"];
let state = entryObj["state"];
let isPreview = false;
if (state["state"] !== undefined &&
state["state"]["mode"] !== undefined) {
let mode = state["state"]["mode"];
isPreview = mode === "preview";
}
let validFilePath = checkState(state);
if (validFilePath && isPreview) {
return workspace.getLeafById(id);
}
}
}
}
return null;
}
/*
* Filename: multi-column-markdown/src/live_preview/MultiColumnMarkdown_Widget.ts
* Created Date: Tuesday, August 16th 2022, 4:38:43 pm
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
const CACHE_MAX_DELTA_TIME_MS = 2 * 60 * 1000; // 2m
let livePreviewElementCache = new Map();
function clearCache(skipKey = "") {
return __awaiter(this, void 0, void 0, function* () {
let keys = Array.from(livePreviewElementCache.keys());
for (let key of keys) {
if (key === skipKey) {
// console.debug(`Element: ${index} | Skipping key: ${key.split(" : ")[0]}`)
continue;
}
if (livePreviewElementCache.has(key) === false) {
continue;
}
let val = livePreviewElementCache.get(key);
let deltaTimeMS = Date.now() - val.timestamp;
if ((val.element.parentNode === null || val.element.parentNode.parentNode === null) && deltaTimeMS > CACHE_MAX_DELTA_TIME_MS) {
// console.debug(`cache delta: ${deltaTimeMS} > ${CACHE_MAX_DELTA_TIME_MS} or 2 minutes.`)
livePreviewElementCache.delete(key);
}
else if (val.element.parentNode == null || val.element.parentNode.parentNode === null) ;
}
});
}
function clearLivePreviewCache() {
clearCache();
}
class MultiColumnMarkdown_LivePreview_Widget extends view.WidgetType {
constructor(originalText, contentData, userSettings, sourceFile, settingsText = "", regionType) {
super();
this.domList = [];
this.regionSettings = getDefaultMultiColumnSettings();
this.sourcePath = "";
this.contentData = contentData;
this.settingsText = settingsText;
this.sourceFile = sourceFile;
if (this.sourceFile === null) {
return;
}
this.elementCacheID = `${this.sourceFile.path} : ${this.contentData}`;
if (this.sourceFile) {
this.sourcePath = sourceFile.path;
}
if (userSettings !== null) {
this.regionSettings = userSettings;
}
let errorManager = new RegionErrorManager(createDiv());
if (regionType === "CODEBLOCK") {
errorManager.addErrorMessage("The codeblock region start syntax has been depricated. Please manually update to the current syntax defined in the ReadMe, run the \"Fix Multi-Column Syntax in Current File\" from the Command Palette, or use the \"Update Depricated Syntax\" command found in the plugin settings window. You must reload the file for changes to take effect.");
}
(() => __awaiter(this, void 0, void 0, function* () {
function hasBadContentBetween(contentBetween) {
let regexResult = new RegExp("((?: *\n){6,})").exec(contentBetween);
if (regexResult !== null) {
// console.log("Found at least 6 empty lines.")
return false;
}
regexResult = /^(?:(?! *$)(?! *--- *$)).+$/mg.exec(contentBetween);
if (regexResult !== null) {
return false;
}
return true;
}
let fileText = yield sourceFile.vault.cachedRead(sourceFile);
fileText = fileText.replace(originalText, "###--START_HERE--###");
let regexResult = new RegExp("###--START_HERE--###").exec(fileText);
if (regexResult === null) {
return;
}
fileText = fileText.slice(0, regexResult.index);
let nextStartTag = findEndTagClosestToEnd(fileText);
if (nextStartTag.found === false) {
return;
}
let errorString = hasBadContentBetween(fileText.slice(nextStartTag.endPosition));
if (errorString === false) {
return;
}
errorManager.addWarningMessage("Detected possible issue with the content between this region and the region above. \
If you experience page jumping when clicking within this document, please make sure there are at least 6 blank \
lines or some form of text content between the two regions. This is a known issue that is under investigation. Sorry for the inconvenience.");
}))();
if (livePreviewElementCache.has(this.elementCacheID)) {
let cache = livePreviewElementCache.get(this.elementCacheID);
let regionManager = cache.regionManager;
let regionSettingsEqual = MCSettings_isEqual(userSettings, cache.cacheSettings);
let pluginSettingsUpdated = MCM_SettingsManager.shared.lastUpdateTimestamp > cache.pluginSettingsUpdateTimestamp;
if (regionManager && regionSettingsEqual === true && pluginSettingsUpdated === false) {
regionManager.updateErrorManager(errorManager, cache.errorRootEl);
let useLivePreviewCache = MCM_SettingsManager.shared.useLivePreviewCache;
let fileLeaf = getPreviewLeafFromFilePath(app.workspace, this.sourceFile.path);
if (useLivePreviewCache && fileLeaf === null) {
return;
}
}
else {
livePreviewElementCache.delete(this.elementCacheID);
}
}
// Render the markdown content to our temp parent element.
this.tempParent = createDiv();
let elementMarkdownRenderer = new obsidian.MarkdownRenderChild(this.tempParent);
obsidian.MarkdownRenderer.renderMarkdown(this.contentData, this.tempParent, this.sourcePath, elementMarkdownRenderer);
let previousText = "";
let workingText = originalText;
// take all elements, in order, and create our DOM list.
let arr = Array.from(this.tempParent.children);
for (let i = 0; i < arr.length; i++) {
let el = this.fixElementRender(arr[i]);
let domObject = new DOMObject(el, [""]);
this.domList.push(domObject);
let newData = sliceWorkingTextToEl(domObject, previousText, workingText);
previousText = newData.previousText;
workingText = newData.workingText;
newData = attemptToFixCheckboxes(domObject, previousText, workingText, sourceFile, this.elementCacheID);
previousText = newData.previousText;
workingText = newData.workingText;
workingText = checkForColumnBreakErrors(domObject, previousText, workingText, errorManager);
}
// Set up the region manager data before then creating our region manager.
let regionData = {
domList: this.domList,
domObjectMap: new Map(),
regionParent: createDiv(),
fileManager: null,
regionalSettings: this.regionSettings,
regionKey: getUID(),
rootElement: createDiv(),
errorManager: errorManager
};
// Finally setup the type of region manager required.
if (this.regionSettings.numberOfColumns === 1) {
this.regionSettings = parseSingleColumnSettings(this.settingsText, this.regionSettings);
this.regionManager = new SingleColumnRegionManager(regionData);
}
else if (this.regionSettings.autoLayout === true) {
this.regionManager = new AutoLayoutRegionManager(regionData, true);
}
else {
this.regionManager = new StandardMultiColumnRegionManager(regionData);
}
clearCache(this.elementCacheID);
}
fixElementRender(el) {
let fixedEl = fixImageRender(el, this.sourcePath);
fixedEl = fixPDFRender(fixedEl, this.sourcePath);
fixedEl = fixFileEmbed(fixedEl, this.sourcePath);
fixedEl = fixTableRender(fixedEl);
fixedEl = fixUnSupportedRender(fixedEl);
return fixedEl;
}
toDOM() {
let useLivePreviewCache = MCM_SettingsManager.shared.useLivePreviewCache;
let fileLeaf = getPreviewLeafFromFilePath(app.workspace, this.sourceFile.path);
if (useLivePreviewCache &&
livePreviewElementCache.has(this.elementCacheID) &&
fileLeaf === null) {
return livePreviewElementCache.get(this.elementCacheID).element;
}
// Create our element to hold all of the live preview elements.
let el = document.createElement("div");
el.className = "mcm-cm-preview";
/**
* For situations where we need to know the rendered height, AutoLayout,
* the element must be rendered onto the screen to get the info, even if
* only for a moment. Here we attempt to get a leaf from the app so we
* can briefly append our element, check any data if required, and then
* remove it.
*/
let autolayoutLeaf = null;
if (app) {
let leaves = app.workspace.getLeavesOfType("markdown");
if (leaves.length > 0) {
autolayoutLeaf = leaves[0];
}
}
if (this.regionManager) {
this.errorRootEl = el.createDiv();
let contentElement = el.createDiv();
this.regionManager.getRegionData().errorManager.setRegionRootElement(this.errorRootEl);
let requireUnload = false;
if (autolayoutLeaf && this.regionManager instanceof AutoLayoutRegionManager) {
autolayoutLeaf.view.containerEl.appendChild(el);
requireUnload = true;
}
this.regionManager.renderRegionElementsToLivePreview(contentElement);
for (let domObj of this.regionManager.getRegionData().domList) {
fixListCSS(domObj.originalElement);
}
if (requireUnload) {
autolayoutLeaf.view.containerEl.removeChild(el);
}
}
fixExternalLinks(el);
livePreviewElementCache.set(this.elementCacheID, {
timestamp: Date.now(),
element: el,
regionManager: this.regionManager,
errorRootEl: this.errorRootEl,
cacheSettings: this.regionSettings,
pluginSettingsUpdateTimestamp: MCM_SettingsManager.shared.lastUpdateTimestamp
});
return el;
}
fixElementCSS(domObject) {
fixListCSS(domObject.originalElement);
}
}
const OBSIDIAN_LIVEPREVIEW_TABLE_CLASSES = "cm-embed-block markdown-rendered cm-table-widget show-indentation-guide";
function fixTableRender(el) {
if (el.tagName !== "TABLE") {
return el;
}
let parentDiv = createDiv({
"cls": OBSIDIAN_LIVEPREVIEW_TABLE_CLASSES
});
parentDiv.appendChild(el);
return parentDiv;
}
function fixFileEmbed(el, source) {
let embed = getEmbed(el);
if (embed === null) {
return el;
}
let alt = embed.getAttr("alt");
let src = embed.getAttr("src");
if (src === null) {
return el;
}
let file = app.metadataCache.getFirstLinkpathDest(src, source);
if (file === null) {
return el;
}
if (isMDExtension(file.extension) === false) {
return el;
}
return createLPErrorElement("File embeds are not supported in Live Preview.\nPlease use reading mode to view.", alt, src);
}
function createLPErrorElement(errorText, alt = "", src = "") {
let errorEl = createDiv({
cls: "internal-embed markdown-embed inline-embed is-loaded",
attr: {
"tabindex": "-1",
"contenteditable": "false"
}
});
errorEl.setAttr("alt", alt);
errorEl.setAttr("src", `app://obsidian.md/${src}`);
errorEl.appendChild(createDiv({
"cls": "embed-title markdown-embed-title",
}));
let contentEl = errorEl.createDiv({
"cls": `markdown-embed-content`,
});
let paragraph = contentEl.createEl("p", {
"cls": `${MultiColumnStyleCSS.RegionErrorMessage}, ${MultiColumnStyleCSS.SmallFont}`
});
paragraph.innerText = errorText;
return errorEl;
}
function fixPDFRender(el, source) {
let embed = getEmbed(el);
if (embed === null) {
return el;
}
let alt = embed.getAttr("alt");
let src = embed.getAttr("src");
if (src === null) {
return el;
}
let file = app.metadataCache.getFirstLinkpathDest(src, source);
if (file === null) {
return el;
}
if (isPDFExtension(file.extension) === false) {
return el;
}
return createLPErrorElement("Due to an update to Obsidian's PDF viewer, PDF embeds are currently not supported.\nSorry for the inconvienence.", alt, src);
}
function fixImageRender(el, source) {
let embed = getEmbed(el);
if (embed === null) {
return el;
}
let customWidth = embed.attributes.getNamedItem("width");
let alt = embed.getAttr("alt");
let src = embed.getAttr("src");
if (src === null) {
return el;
}
let file = app.metadataCache.getFirstLinkpathDest(src, source);
if (file === null) {
return el;
}
// If the link source is not an image we dont want to make any adjustments.
if (isImageExtension(file.extension) === false) {
return el;
}
let fixedEl = createDiv({
cls: "internal-embed image-embed is-loaded",
});
fixedEl.setAttr("alt", alt);
let resourcePath = app.vault.getResourcePath(file);
let image = fixedEl.createEl("img");
image.setAttr("src", resourcePath);
if (customWidth !== null) {
image.setAttr("width", customWidth.value);
}
return fixedEl;
}
function fixExternalLinks(el) {
let items = el.getElementsByClassName("external-link");
for (let linkEl of Array.from(items)) {
let link = linkEl;
if (link === undefined ||
link === null) {
continue;
}
// Remove the href from the link and setup an event listener to open the link in the default browser.
let href = link.getAttr("href");
link.removeAttribute("href");
link.addEventListener("click", (ev) => {
window.open(href);
});
}
items = el.getElementsByClassName("internal-link");
for (let linkEl of Array.from(items)) {
let link = linkEl;
if (link === undefined ||
link === null) {
continue;
}
// Removing the href from internal links is all that seems to be required to fix the onclick.
link.removeAttribute("href");
}
return el;
}
function getEmbed(el) {
// embeds can either be a <div class="internal-embed" or <p><div class="internal-embed"
// depending on the syntax this additional check is to fix false negatives when embed is
// the first case.
if (el.hasClass("internal-embed")) {
return el;
}
else {
let items = el.getElementsByClassName("internal-embed");
if (items.length === 1) {
return items[0];
}
}
return null;
}
function isImageExtension(extension) {
extension = extension.toLowerCase();
switch (extension) {
case "png":
case "jpg":
case "jpeg":
case "gif":
case "bmp":
case "svg":
case "webp":
return true;
}
return false;
}
function isPDFExtension(extension) {
return extension.toLowerCase() === "pdf";
}
function isMDExtension(extension) {
return extension.toLowerCase() === "md";
}
function fixListCSS(el) {
var _a;
if (el.tagName !== "UL" && el.tagName !== "OL") {
return el;
}
(_a = el.parentElement) === null || _a === void 0 ? void 0 : _a.addClass(ObsidianStyleCSS.RenderedMarkdown);
return el;
}
function fixUnSupportedRender(el) {
if (isTasksPlugin(el)) {
if (MCM_SettingsManager.shared.renderInlineElErrors === true) {
let fixedEl = createDiv();
let paragraph = fixedEl.createEl("p", {
"cls": `${MultiColumnStyleCSS.RegionErrorMessage} ${MultiColumnStyleCSS.SmallFont}`
});
paragraph.innerText = "The Tasks plugin is not supported in Live Preview.\nPlease use reading mode.";
return fixedEl;
}
return el;
}
return el;
}
function checkForColumnBreakErrors(domObject, previousText, workingText, errorManager) {
if (domObject.tag !== DOMObjectTag.columnBreak &&
domObject.elementIsColumnBreak === ElementColumnBreakType.none) {
return workingText;
}
let prevLine = previousText.split("\n").slice(-2).join("\n");
let checkText = workingText;
if (checkForParagraphInnerColEndTag(prevLine)) {
checkText = prevLine + workingText;
}
let nextColBreak = checkForParagraphInnerColEndTag(checkText);
if (nextColBreak === null) {
console.error("Error. Something went wrong parsing column break out of text.");
return workingText;
}
let startIndex = nextColBreak.index;
let matchLength = nextColBreak[0].length;
let endIndex = startIndex + matchLength;
let matchText = nextColBreak[0].trim();
let newWorkingText = checkText.slice(endIndex);
// Already parsed column break warning.
if (domObject.elementIsColumnBreak !== ElementColumnBreakType.none) {
parseColBreakErrorType({
lineAbove: "",
lineBelow: "",
objectTag: DOMObjectTag.none,
colBreakType: domObject.elementIsColumnBreak
}, errorManager);
return newWorkingText;
}
// Now we have a standard column break but due to changes in obsidian parsing may still
// require displaying an error message.
let endTagText = domObject.originalElement.innerText;
// make sure the element text is a column break just to be sure. This really should never fail.
if (containsColEndTag(endTagText) === false) {
// If something went wrong here we can not proceed with the next regex unless this passes.
console.error("Error parsing column-break tag back out of element text.", endTagText);
return workingText;
}
// make sure the text of the element matche the syntax of what we parsed from the text.
if (matchText !== endTagText) {
console.error("Error matching next col-break to current element. Can not continue.");
return workingText;
}
// Slice out the 20 characters before and after the column break and then get just
// the one line before and after to check if error message required.
let startIndexOffset = Math.clamp(startIndex - 20, 0, startIndex);
let endIndexOffset = Math.clamp(endIndex + 20, endIndex, checkText.length - 1);
let additionalText = checkText.slice(startIndexOffset, endIndexOffset);
let textBefore = additionalText.slice(0, 20);
let textAfter = additionalText.slice(20 + matchLength);
textBefore = textBefore.replace(endTagText, "");
let linesAbove = textBefore.split("\n").filter((val) => {
return val !== "";
});
let linesBelow = textAfter.split("\n").filter((val) => {
return val !== "";
});
if (linesAbove.length === 0 && linesBelow.length === 0) {
return workingText;
}
let lineAbove = linesAbove.last();
let lineBelow = linesBelow.first();
parseColBreakErrorType({
lineAbove: lineAbove,
lineBelow: lineBelow,
objectTag: DOMObjectTag.columnBreak,
colBreakType: ElementColumnBreakType.none
}, errorManager);
return newWorkingText;
}
function sliceWorkingTextToEl(domObject, previousText, workingText) {
function processParagraph() {
let regex = new RegExp(`^ *${escapeRegExp(domObject.originalElement.textContent)} *$`, "m");
let result = regex.exec(workingText);
if (result) {
let updatedPrevious = previousText + workingText.slice(0, result.index);
workingText.slice(result.index, result.index + result[0].length);
let updatedWorkingText = workingText.slice(result.index);
return {
previousText: updatedPrevious,
workingText: updatedWorkingText
};
}
return {
previousText: previousText,
workingText: workingText
};
}
function processHeader() {
let count = parseInt(domObject.originalElement.tagName.slice(1));
let text = '#'.repeat(count);
let regex = new RegExp(`^${text} +${escapeRegExp(domObject.originalElement.textContent)} *$`, "m");
let result = regex.exec(workingText);
if (result) {
let updatedPrevious = previousText + workingText.slice(0, result.index);
workingText.slice(result.index, result.index + result[0].length);
let updatedWorkingText = workingText.slice(result.index);
return {
previousText: updatedPrevious,
workingText: updatedWorkingText
};
}
return {
previousText: previousText,
workingText: workingText
};
}
if (domObject.originalElement.tagName === "P") {
return processParagraph();
}
if (domObject.originalElement.tagName === "H1" ||
domObject.originalElement.tagName === "H2" ||
domObject.originalElement.tagName === "H3" ||
domObject.originalElement.tagName === "H4" ||
domObject.originalElement.tagName === "H5") {
return processHeader();
}
return {
previousText: previousText,
workingText: workingText
};
}
function attemptToFixCheckboxes(domObject, textBeforeElement, textOfElementAndAfter, sourceFile, cacheID) {
if (domObject.originalElement.tagName !== "UL") {
return {
previousText: textBeforeElement,
workingText: textOfElementAndAfter
};
}
if (domObject.originalElement.hasClass("contains-task-list") === false) {
return {
previousText: textBeforeElement,
workingText: textOfElementAndAfter
};
}
let listItems = Array.from(domObject.originalElement.getElementsByTagName("li")).filter((item) => {
return item.hasClass("task-list-item");
});
let workingTextBefore = textBeforeElement;
let workingText = textOfElementAndAfter;
for (let listElement of listItems) {
let possibleCheckbox = listElement.getElementsByTagName("input");
if (possibleCheckbox.length !== 1) {
console.error("Error: Could not get input for task item.");
continue;
}
let checkbox = possibleCheckbox[0];
if (checkbox.getAttr("type") !== "checkbox") {
console.error("Error: Checkbox not of proper type");
continue;
}
if (checkbox.hasClass("task-list-item-checkbox") === false) {
console.error("Error: Checkbox is missing proper class.");
continue;
}
if (checkbox.onclick !== null) {
console.error("Error: OnClick aready defined, not overwriting method.");
continue;
}
let checkboxIsChecked = listElement.getAttr("data-task") === "x" || listElement.getAttr("data-task") === "X";
let checkboxTextRegexSearch = RegExp(`^( *)-( +)\\[${checkboxIsChecked ? "[xX]" : " *"}\\]( +)${escapeRegExp(listElement.innerText)}( *)$`, "m");
let checkboxTextRegexResult = checkboxTextRegexSearch.exec(workingText);
if (checkboxTextRegexResult === null) {
console.error("Could not find text in provided document.");
continue;
}
let startOfElementIndex = checkboxTextRegexResult.index;
let endOfElementIndex = startOfElementIndex + checkboxTextRegexResult[0].length;
let newTextAfter = workingText.slice(endOfElementIndex);
let onClickNewTextAfter = newTextAfter;
workingTextBefore = workingTextBefore + workingText.slice(0, startOfElementIndex);
let onClickNewTextBefore = workingTextBefore;
workingText = workingText.slice(startOfElementIndex);
let onClickNewWorkingText = workingText;
let spaceBeforeDash = checkboxTextRegexResult[1];
let spaceAfterDash = checkboxTextRegexResult[2];
let spaceAfterCheck = checkboxTextRegexResult[3];
let spaceAfterContent = checkboxTextRegexResult[4];
let currentCacheID = cacheID;
let sourceFilePath = sourceFile.path;
checkbox.onclick = () => {
let replacementLine = `${spaceBeforeDash}-${spaceAfterDash}[${checkboxIsChecked ? " " : "X"}]${spaceAfterCheck}${listElement.innerText}${spaceAfterContent}`;
let originalTextToReplace = onClickNewTextBefore + onClickNewWorkingText;
let newReplacementText = onClickNewTextBefore + replacementLine + onClickNewTextAfter;
if (livePreviewElementCache.has(currentCacheID)) {
let newCacheID = `${sourceFilePath} : ${newReplacementText}`;
let currentData = livePreviewElementCache.get(currentCacheID);
livePreviewElementCache.set(newCacheID, currentData);
currentCacheID = newCacheID;
}
(() => __awaiter(this, void 0, void 0, function* () {
let fileText = yield sourceFile.vault.read(sourceFile);
if (fileText.contains(originalTextToReplace) === false) {
console.error("Could not update file. File does not contain region text.");
return;
}
let newFileText = fileText.replace(originalTextToReplace, newReplacementText);
sourceFile.vault.modify(sourceFile, newFileText);
}))();
listElement.classList.toggle("is-checked");
if (checkboxIsChecked) {
listElement.removeAttribute("data-task");
}
else {
listElement.setAttribute("data-task", "x");
}
checkboxIsChecked = !checkboxIsChecked;
};
}
return {
previousText: workingTextBefore,
workingText: workingText
};
}
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
/*
* Filename: multi-column-markdown/src/live_preview/cm6_livePreview.ts
* Created Date: Monday, August 1st 2022, 1:51:16 pm
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
const multiColumnMarkdown_StateField = state.StateField.define({
create(state) {
return view.Decoration.none;
},
update(oldState, transaction) {
const builder = new state.RangeSetBuilder();
let ignoreFurtherIterations = false;
// Check if view is in live preview state.
if (transaction.state.field(obsidian.editorLivePreviewField) === false) {
return builder.finish();
}
/**
* When we have the while file we then get the entire doc text and check if it
* contains a MCM region so we know to break or not.
*/
let docLength = transaction.state.doc.length;
let docText = transaction.state.doc.sliceString(0, docLength);
if (containsRegionStart(docText) === false) {
return builder.finish();
}
language.syntaxTree(transaction.state).iterate({
enter(node) {
// If we find that the file does not contain any MCM regions we can flip this
// flag and skip all other node iterations, potentially saving a lot of compute time.
//
// We only want to run the generation once per state change. If
// a previous node has sucessfully generated regions we ignore all
// other nodes in the state.
if (ignoreFurtherIterations === true) {
return;
}
// We want to run on the whole file so we dont just look for a single token.
const tokenProps = node.type.prop(language.tokenClassNodeProp);
if (tokenProps !== undefined) {
return;
}
// We want to know where the user's cursor is, it can be
// selecting multiple regions of text as well so we need to know
// all locations. Used to know if we should render region as text or as preview.
let ranges = getCursorLineLocations();
// Setup our loop to render the regions as MCM.
let workingFileText = docText;
let loopIndex = 0;
let startIndexOffset = 0;
while (true) {
let regionData = getNextRegion(workingFileText, startIndexOffset, docText);
if (regionData === null) {
break;
}
let elementText = regionData.regionText;
workingFileText = regionData.remainingText;
let startIndex = regionData.startIndex;
let endIndex = regionData.endIndex;
startIndexOffset = endIndex;
// Here we check if the cursor is in this specific region.
let cursorInRegion = checkCursorInRegion(startIndex, endIndex, ranges);
if (cursorInRegion === true) ;
else {
let foundSettings = getSettingsData(regionData);
let userSettings = null;
let settingsText = "";
let originalText = elementText;
if (foundSettings !== null) {
elementText = foundSettings.contentData;
userSettings = foundSettings.settings;
settingsText = foundSettings.settingsText;
}
const editorInfo = transaction.state.field(obsidian.editorInfoField);
// At this point if the cursor isnt in the region we pass the data to the
// element to be rendered.
builder.add(startIndex, endIndex, view.Decoration.replace({
widget: new MultiColumnMarkdown_LivePreview_Widget(originalText, elementText, userSettings, editorInfo.file, settingsText, regionData.regionType),
}));
}
ignoreFurtherIterations = true;
// Infinite loop protection.
loopIndex++;
if (loopIndex > 100) {
console.warn("Potential issue with rendering Multi-Column Markdown live preview regions. If problem persists please file a bug report with developer.");
break;
}
}
},
});
return builder.finish();
function getCursorLineLocations() {
let ranges = [];
if (transaction.state.selection.ranges) {
ranges = transaction.state.selection.ranges.filter((range) => {
return range.empty;
}).map((range) => {
let line = transaction.state.doc.lineAt(range.head);
`${line.number}:${range.head - line.from}`;
return {
line: line,
position: range.head
};
});
}
return ranges;
}
function valueIsInRange(value, minVal, maxVal, inclusive = true) {
if (inclusive === true && (value === minVal || value === maxVal)) {
return true;
}
if (minVal < value && value < maxVal) {
return true;
}
return false;
}
function checkCursorInRegion(startIndex, endIndex, ranges) {
for (let i = 0; i < ranges.length; i++) {
// TODO: Maybe look into limiting this to the second and second to last line
// of the region as clicking right at the top or bottom of the region
// swaps it to unrendered.
let range = ranges[i];
if (valueIsInRange(range.position, startIndex, endIndex) === true) {
return true;
}
}
if (transaction.state.selection) {
for (let i = 0; i < transaction.state.selection.ranges.length; i++) {
let range = transaction.state.selection.ranges[i];
// If either the start or end of the selection is within the
// region range we do not render live preview.
if (valueIsInRange(range.from, startIndex, endIndex) ||
valueIsInRange(range.to, startIndex, endIndex)) {
return true;
}
// // Or if the entire region is within the selection range
// we do not render the live preview.
if (valueIsInRange(startIndex, range.from, range.to) &&
valueIsInRange(endIndex, range.from, range.to)) {
return true;
}
}
}
return false;
}
},
provide(field) {
return view.EditorView.decorations.from(field);
},
});
function getNextRegion(workingFileText, startIndexOffset, wholeDoc) {
let region = findNextRegion(workingFileText);
if (region === null) {
return null;
}
if (region.dataType === "CODEBLOCK" || region.dataType === "ORIGINAL") {
// Search for the first end tag after a start block. (No recursive columns.)
let endTagData = findEndTag(workingFileText.slice(region.data.startPosition));
if (endTagData.found === false) {
return null;
}
/**
* For the region we found get the start and end position of the tags so we
* can slice it out of the document.
*/
let startIndex = startIndexOffset + region.data.startPosition;
let endIndex = startIndex + endTagData.startPosition + endTagData.matchLength; // Without the matchLength will leave the end tag on the screen.
// This text is the entire region data including the start and end tags.
let elementText = wholeDoc.slice(startIndex, endIndex);
workingFileText = wholeDoc.slice(endIndex);
/**
* Update our start offset and the working text of the file so our next
* iteration knows where we left off
*/
let data = {
regionType: region.dataType,
regionText: elementText,
remainingText: workingFileText,
startIndex: startIndex,
endIndex: endIndex
};
return data;
}
if (region.dataType === "PADOC") {
let pandocData = region.data;
let startIndex = startIndexOffset + pandocData.startPosition;
let endIndex = startIndexOffset + pandocData.endPosition;
workingFileText = wholeDoc.slice(endIndex);
let data = {
regionType: region.dataType,
regionText: pandocData.content,
remainingText: workingFileText,
startIndex: startIndex,
endIndex: endIndex,
columnCount: pandocData.columnCount,
userSettings: pandocData.userSettings
};
return data;
}
}
function findNextRegion(workingFileText) {
// If there are multiple kinds of start blocks, the old way of parsing would cause issues.
// Now search for both kinds and determine what to do after search.
let startTagData_codeblockStart = { dataType: "CODEBLOCK", data: findStartCodeblock(workingFileText) };
let startTagData_originalStart = { dataType: "ORIGINAL", data: findStartTag(workingFileText) };
let pandocData = { dataType: "PADOC", data: findPandoc(workingFileText) };
if (startTagData_codeblockStart.data.found === false &&
startTagData_originalStart.data.found === false &&
pandocData.data.found === false) {
return null;
}
let regionsFound = [startTagData_codeblockStart, startTagData_originalStart, pandocData].filter((val) => { return val.data.found === true; });
if (regionsFound.length > 1) {
let sorted = regionsFound.sort((a, b) => {
return a.data.startPosition - b.data.endPosition;
});
return sorted.first();
}
if (startTagData_codeblockStart.data.found === true) {
return startTagData_codeblockStart;
}
if (startTagData_originalStart.data.found === true) {
return startTagData_originalStart;
}
if (pandocData.data.found === true) {
return pandocData;
}
throw ("Unknown type found when parsing region.");
}
function getSettingsData(regionData) {
let contentData = regionData.regionText;
function parseCodeBlockSettings(settingsStartData) {
let settingsText = contentData.slice(settingsStartData.startPosition, settingsStartData.endPosition);
contentData = contentData.replace(settingsText, "");
let settings = parseColumnSettings(settingsText);
return {
settings: settings,
settingsText: settingsText,
contentData: contentData
};
}
if (regionData.regionType === "CODEBLOCK") {
let settingsStartData = findStartCodeblock(contentData);
if (settingsStartData.found === false) {
return null;
}
return parseCodeBlockSettings(settingsStartData);
}
if (regionData.regionType === "ORIGINAL") {
let settingsStartData = findSettingsCodeblock(contentData);
if (settingsStartData.found === false) {
return null;
}
return parseCodeBlockSettings(settingsStartData);
}
if (regionData.regionType === "PADOC") {
let pandocData = regionData;
return {
settings: parsePandocSettings(pandocData.userSettings, pandocData.columnCount),
settingsText: "",
contentData: regionData.regionText
};
}
}
/**
* File: /src/live_preview/cm6_livePreivew_onClickFix.ts *
* Created Date: Friday, March 24th 2023, 6:10 pm *
* Author: Cameron Robinson *
* *
* Copyright (c) 2023 Cameron Robinson *
*/
const MultiColumnMarkdown_OnClickFix = state.StateField.define({
create(state) {
return view.Decoration.none;
},
update(oldState, transaction) {
const builder = new state.RangeSetBuilder();
return builder.finish();
},
provide(field) {
return view.EditorView.decorations.from(field);
},
});
function updateAllSyntax(originalFileContent) {
let fileCount = 0;
let regionStartCount = 0;
let columnBreakCount = 0;
let columnEndCount = 0;
let fileUpdated = false;
let { updatedFileContent, numRegionsUpdated } = updateColumnCodeblockStartSyntax(originalFileContent);
if (numRegionsUpdated > 0) {
fileCount++;
fileUpdated = true;
regionStartCount += numRegionsUpdated;
}
let colStart = updateColumnStartSyntax(updatedFileContent);
if (colStart.numRegionsUpdated) {
if (fileUpdated === false) {
fileUpdated = true;
fileCount++;
}
updatedFileContent = colStart.updatedFileContent;
regionStartCount += colStart.numRegionsUpdated;
}
let colBreak = updateColumnBreakSyntax(updatedFileContent);
if (colBreak.numRegionsUpdated) {
if (fileUpdated === false) {
fileUpdated = true;
fileCount++;
}
updatedFileContent = colBreak.updatedFileContent;
columnBreakCount += colBreak.numRegionsUpdated;
}
let colEnd = updateColumnEndSyntax(updatedFileContent);
if (colEnd.numRegionsUpdated) {
if (fileUpdated === false) {
fileUpdated = true;
fileCount++;
}
updatedFileContent = colEnd.updatedFileContent;
columnEndCount += colEnd.numRegionsUpdated;
}
return {
fileCount: fileCount,
regionStartCount: regionStartCount,
columnBreakCount: columnBreakCount,
columnEndCount: columnEndCount,
updatedFileContent: updatedFileContent,
fileWasUpdated: updatedFileContent !== originalFileContent
};
}
const OLD_COL_END_SYNTAX_REGEX = /=== *(end-multi-column|multi-column-end)/g;
function updateColumnEndSyntax(originalFileContent) {
let matches = Array.from(originalFileContent.matchAll(OLD_COL_END_SYNTAX_REGEX));
let updatedFileContent = originalFileContent;
let offset = 0;
for (let match of matches) {
let startIndex = match.index + offset;
let matchLength = match[0].length;
let endIndex = startIndex + matchLength;
let columnEndSyntax = match[1];
let replacementText = `--- ${columnEndSyntax}`;
offset += replacementText.length - matchLength;
updatedFileContent = updatedFileContent.slice(0, startIndex) + replacementText + updatedFileContent.slice(endIndex);
console.groupCollapsed();
console.log("Original File:\n\n", originalFileContent);
console.log("Updated File:\n\n", updatedFileContent);
console.groupEnd();
}
return {
updatedFileContent: updatedFileContent,
numRegionsUpdated: matches.length
};
}
const OLD_COL_BREAK_SYNTAX_REGEX = /===\s*?(column-end|end-column|column-break|break-column)\s*?===\s*?/g;
function updateColumnBreakSyntax(originalFileContent) {
let matches = Array.from(originalFileContent.matchAll(OLD_COL_BREAK_SYNTAX_REGEX));
let updatedFileContent = originalFileContent;
let offset = 0;
for (let match of matches) {
let startIndex = match.index + offset;
let matchLength = match[0].length;
let endIndex = startIndex + matchLength;
let columnBreakSyntax = match[1];
let replacementText = `--- ${columnBreakSyntax} ---`;
offset += replacementText.length - matchLength;
updatedFileContent = updatedFileContent.slice(0, startIndex) + replacementText + updatedFileContent.slice(endIndex);
console.groupCollapsed();
console.log("Original File:\n\n", originalFileContent);
console.log("Updated File:\n\n", updatedFileContent);
console.groupEnd();
}
return {
updatedFileContent: updatedFileContent,
numRegionsUpdated: matches.length
};
}
const OLD_COL_START_SYNTAX_REGEX = /=== *(start-multi-column|multi-column-start)/g;
function updateColumnStartSyntax(originalFileContent) {
let matches = Array.from(originalFileContent.matchAll(OLD_COL_START_SYNTAX_REGEX));
let updatedFileContent = originalFileContent;
let offset = 0;
for (let match of matches) {
let startIndex = match.index + offset;
let matchLength = match[0].length;
let endIndex = startIndex + matchLength;
let columnStartSyntax = match[1];
let replacementText = `--- ${columnStartSyntax}`;
offset += replacementText.length - matchLength;
updatedFileContent = updatedFileContent.slice(0, startIndex) + replacementText + updatedFileContent.slice(endIndex);
console.groupCollapsed();
console.log("Original File:\n\n", originalFileContent);
console.log("Updated File:\n\n", updatedFileContent);
console.groupEnd();
}
return {
updatedFileContent: updatedFileContent,
numRegionsUpdated: matches.length
};
}
const OLD_CODEBLOCK_COL_START_SYNTAX_REGEX = /```(start-multi-column|multi-column-start).*?```/sg;
function updateColumnCodeblockStartSyntax(originalFileContent) {
let matches = Array.from(originalFileContent.matchAll(OLD_CODEBLOCK_COL_START_SYNTAX_REGEX));
let updatedFileContent = originalFileContent;
let offset = 0;
for (let match of matches) {
let startIndex = match.index + offset;
let matchLength = match[0].length;
let endIndex = startIndex + matchLength;
let originalSettingsText = match[0];
let settingsText = originalSettingsText;
let columnStartSyntax = match[1];
let columnStartLine = `--- ${columnStartSyntax}`;
let idResult = /ID:(.*)/i.exec(originalSettingsText);
if (idResult !== null) {
let id = idResult[1].trim();
columnStartLine = `${columnStartLine}: ${id}`;
let startIndex = idResult.index;
let endIndex = startIndex + idResult[0].length;
settingsText = originalSettingsText.slice(0, startIndex);
settingsText += originalSettingsText.slice(endIndex + 1);
}
settingsText = settingsText.replace(columnStartSyntax, "column-settings");
let replacementText = `${columnStartLine}\n${settingsText}`;
offset += replacementText.length - matchLength;
updatedFileContent = updatedFileContent.slice(0, startIndex) + replacementText + updatedFileContent.slice(endIndex);
console.groupCollapsed();
console.log("Original File:\n\n", originalFileContent);
console.log("Updated File:\n\n", updatedFileContent);
console.groupEnd();
}
return {
updatedFileContent: updatedFileContent,
numRegionsUpdated: matches.length
};
}
class MultiColumnSettingsView extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
this.containerEl.empty();
this.containerEl.createEl("h2", { text: "Multi-Column Markdown - Settings" });
const settingsContainerEl = this.containerEl.createDiv();
new obsidian.Setting(settingsContainerEl)
.setName("Number of auto-layout balance iterations")
.setDesc("The maximum number of times auto-layout will try to balance elements between all of the columns. Setting this too high may cause Obsidian to slow down during loading and refreshing of Auto-Layout columns.")
.addSlider((slider) => {
slider.setLimits(1, 15, 2);
slider.setValue(MCM_SettingsManager.shared.autoLayoutBalanceIterations);
slider.setDynamicTooltip();
slider.onChange((val) => {
MCM_SettingsManager.shared.autoLayoutBalanceIterations = val;
this.plugin.saveSettings();
});
});
new obsidian.Setting(settingsContainerEl)
.setName("Align tables with text alignment by default")
.setDesc(this.buildTableAlignDocFrag())
.addToggle((t) => t.setValue(MCM_SettingsManager.shared.alignTablesToContentAlignment)
.onChange((v) => {
MCM_SettingsManager.shared.alignTablesToContentAlignment = v;
this.plugin.saveSettings();
}));
new obsidian.Setting(settingsContainerEl)
.setName("Use Live Preview render cache")
.setDesc(this.buildRenderCacheDocFrag())
.addToggle((t) => t.setValue(MCM_SettingsManager.shared.useLivePreviewCache)
.onChange((v) => {
MCM_SettingsManager.shared.useLivePreviewCache = v;
this.plugin.saveSettings();
}));
if (obsidian.Platform.isMobile === true) {
new obsidian.Setting(settingsContainerEl)
.setName("Render column regions on mobile devices")
.addToggle((t) => t.setValue(MCM_SettingsManager.shared.renderOnMobile).onChange((v) => {
MCM_SettingsManager.shared.renderOnMobile = v;
this.plugin.saveSettings();
}));
}
this.containerEl.createEl("h5", { attr: { "style": "color: var(--text-error); margin-bottom: 0px;" }, text: "DANGER ZONE" });
this.containerEl.createEl("hr", { attr: { "style": "margin-top: 1px; margin-bottom: 0.75em;" } });
const dangerZoneContainerEl = this.containerEl.createDiv();
this.buildUpdateDepricated(dangerZoneContainerEl);
this.buildFixMissingIDs(dangerZoneContainerEl);
this.containerEl.createEl("br");
let { bgColor, fontColor, coffeeColor } = getDonateButtonColors(this.containerEl);
new obsidian.Setting(this.containerEl)
.setName("Donate")
.setDesc(`If you like this Plugin, please consider providing a one time donation to support it's development.`)
.addButton((b) => {
b.buttonEl.setAttr("style", "background-color: transparent; height: 30pt; padding: 0px;");
const div = b.buttonEl.createDiv({ attr: { "style": "width: 100%; height: 100%" } });
div.createEl("a", {
href: "https://www.buymeacoffee.com/ckrobinson"
}).createEl("img", {
attr: {
style: "width: 100%; height: 100%",
src: `https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=ckrobinson&button_colour=${bgColor}&font_colour=${fontColor}&font_family=Cookie&outline_colour=000000&coffee_colour=${coffeeColor}`
}
});
});
}
buildRenderCacheDocFrag() {
let docFrag = new DocumentFragment();
docFrag.createDiv({}, div => {
div.createSpan({}, span => {
span.innerText = "Caches rendered content in Live Preview to reduce render cycles and element flashing on note interaction.";
});
div.createEl("br");
div.createEl("br");
div.createSpan({}, span => {
span.innerText = "Only uses cache when a file Live Preview tab is open. If both reading view and Live Preview are opened this feature is disabled.";
});
div.createEl("br");
div.createEl("br");
div.createEl("h5", {}, span => {
span.setAttr("style", "color: var(--text-error); margin-bottom: 0px; margin-top: 3px;");
span.innerText = "EXPERIMENTAL:";
});
div.createSpan({}, span => {
span.setAttr("style", "color: var(--text-error);");
span.innerText = "This feature is experimental only and has intermittently caused notes to erase column content during development. A fix has been implemented \
but due to the potential data loss you must opt-in to using this feature. If content is erased you can use Undo to restore the file data. \
Please make backups and disable if you experience any data loss.";
});
});
return docFrag;
}
buildTableAlignDocFrag() {
let docFrag = new DocumentFragment();
docFrag.createDiv({}, div => {
div.createSpan({}, span => {
span.innerText = "Sets the defalut behavior when determining whether to align table to text alignment.";
});
div.createEl("br");
div.createEl("ul").createEl("li", { text: "This value is overwritten when defining the column setting: 'Align Tables to Text Alignment: true/false'" });
});
return docFrag;
}
buildUpdateDepricated(dangerZoneContainerEl) {
let docFrag = new DocumentFragment();
docFrag.createDiv({}, div => {
div.createSpan({}, span => {
span.innerText = "This may take a while for large vaults, you can continue to use Obsidian but application may slow down during process.";
});
div.createEl("br");
div.createEl("br");
div.createEl("h5", {}, span => {
span.setAttr("style", "color: var(--text-error); margin-bottom: 0px; margin-top: 3px;");
span.innerText = "WARNING:";
});
div.createSpan({}, span => {
span.setAttr("style", "color: var(--text-error);");
span.innerText = "This action modifies any note file with depricated syntax and could lead to corrupted file text.";
});
div.createEl("br");
div.createSpan({}, span => {
span.setAttr("style", "color: var(--text-error);");
span.innerText = "No guarentee is given. Please make sure to back your vault up first.";
});
});
let modalDescriptionEl = createDiv({}, div => {
div.createSpan({ text: "This action may corrupt vault data." });
div.createEl("br");
div.createSpan({ text: "Please confirm you have backed up your vault." });
});
new obsidian.Setting(dangerZoneContainerEl)
.setName("Update ALL depricated Multi-Column syntax.")
.setDesc(docFrag)
.addButton((b) => b.setButtonText("Update Syntax").onClick(() => {
const modal = ConfirmModal.confirmModalWithElement(this.app, modalDescriptionEl, { primary: "Confirm", secondary: "Cancel" });
modal.onClose = () => {
if (modal.confirmed === false) {
return;
}
updateFileSyntax();
};
modal.open();
}));
}
buildFixMissingIDs(dangerZoneContainerEl) {
let docFrag = new DocumentFragment();
docFrag.createDiv({}, div => {
div.createSpan({}, span => {
span.innerText = "This will only modify column regions without a pre-defined ID, and which use the up to date core syntax. Will not modify depricated syntax or fenced-divs.";
});
div.createEl("br");
div.createEl("br");
div.createSpan({}, span => {
span.innerText = "This may take a while for large vaults, you can continue to use Obsidian but application may slow down during process.";
});
div.createEl("br");
div.createEl("br");
div.createEl("h5", {}, span => {
span.setAttr("style", "color: var(--text-error); margin-bottom: 0px; margin-top: 3px;");
span.innerText = "WARNING:";
});
div.createSpan({}, span => {
span.setAttr("style", "color: var(--text-error);");
span.innerText = "This action modifies any note file missing column IDs and could lead to corrupted file text.";
});
div.createEl("br");
div.createSpan({}, span => {
span.setAttr("style", "color: var(--text-error);");
span.innerText = "No guarentee is given. Please make sure to back your vault up first.";
});
});
let modalDescriptionEl = createDiv({}, div => {
div.createSpan({ text: "This action may corrupt vault data." });
div.createEl("br");
div.createSpan({ text: "Please confirm you have backed up your vault." });
});
new obsidian.Setting(dangerZoneContainerEl)
.setName("Append IDs to all Multi-Column regions in vault.")
.setDesc(docFrag)
.addButton((b) => b.setButtonText("Add IDs").onClick(() => {
const modal = ConfirmModal.confirmModalWithElement(this.app, modalDescriptionEl, { primary: "Confirm", secondary: "Cancel" });
modal.onClose = () => {
if (modal.confirmed === false) {
return;
}
findAndReplaceMissingIDs();
};
modal.open();
}));
}
}
class ConfirmModal extends obsidian.Modal {
static confirmModalWithText(app, text, buttons) {
return new ConfirmModal(app, createSpan({ text: text }), buttons);
}
static confirmModalWithElement(app, descriptionEl, buttons) {
return new ConfirmModal(app, descriptionEl, buttons);
}
constructor(app, descriptionEl, buttons) {
super(app);
this.confirmed = false;
this.descriptionEl = descriptionEl;
this.buttons = buttons;
}
display() {
return __awaiter(this, void 0, void 0, function* () {
this.contentEl.empty();
this.contentEl.appendChild(this.descriptionEl);
const buttonEl = this.contentEl.createDiv();
new obsidian.ButtonComponent(buttonEl)
.setButtonText(this.buttons.primary)
.setCta()
.onClick(() => {
this.confirmed = true;
this.close();
});
new obsidian.ButtonComponent(buttonEl)
.setButtonText(this.buttons.secondary)
.onClick(() => {
this.close();
});
});
}
onOpen() {
this.display();
}
}
function findAndReplaceMissingIDs() {
return __awaiter(this, void 0, void 0, function* () {
function searchFileForMissingID(docText) {
let lines = docText.split("\n");
/**
* Loop through all of the lines checking if the line is a
* start tag and if so is it missing an ID.
*/
let linesWithoutIDs = 0;
for (let i = 0; i < lines.length; i++) {
let data = isStartTagWithID(lines[i]);
if (data.isStartTag === true && data.hasKey === false) {
let originalText = lines[i];
let text = originalText;
text = text.trimEnd();
if (text.charAt(text.length - 1) === ":") {
text = text.slice(0, text.length - 1);
}
text = `${text}: ID_${getUID(4)}`;
lines[i] = text;
linesWithoutIDs++;
}
}
if (linesWithoutIDs === 0) {
return {
updatedFileContent: docText,
numRegionsUpdated: 0
};
}
let newFileContent = lines.join("\n");
return {
updatedFileContent: newFileContent,
numRegionsUpdated: linesWithoutIDs
};
}
let count = 0;
let fileCount = 0;
for (let mdFile of app.vault.getMarkdownFiles()) {
let originalFileContent = yield app.vault.read(mdFile);
let result = searchFileForMissingID(originalFileContent);
if (result.numRegionsUpdated > 0) {
count += result.numRegionsUpdated;
fileCount++;
let updatedFileContent = result.updatedFileContent;
if (updatedFileContent !== originalFileContent) {
app.vault.modify(mdFile, updatedFileContent);
}
else {
console.log("No changes, not updating file.");
}
}
}
new obsidian.Notice(`Finished updating:\n${count} region IDs, across ${fileCount} files.`);
});
}
function updateFileSyntax() {
return __awaiter(this, void 0, void 0, function* () {
let fileCount = 0;
let regionStartCount = 0;
let columnBreakCount = 0;
let columnEndCount = 0;
for (let mdFile of app.vault.getMarkdownFiles()) {
let originalFileContent = yield app.vault.read(mdFile);
let result = updateAllSyntax(originalFileContent);
fileCount += result.fileCount;
regionStartCount += result.regionStartCount;
columnBreakCount += result.columnBreakCount;
columnEndCount += result.columnEndCount;
let updatedFileContent = result.updatedFileContent;
// TODO: Add in final file modification when done testing.
if (result.fileWasUpdated) {
app.vault.modify(mdFile, updatedFileContent);
}
}
new obsidian.Notice(`Finished updating:\n${regionStartCount} start syntaxes,\n${columnBreakCount} column breaks, and\n${columnEndCount} column end tags,\nacross ${fileCount} files.`);
});
}
function getDonateButtonColors(containerEl) {
let computedStyle = getComputedStyle(containerEl);
let fontColor = computedStyle.getPropertyValue('--text-normal');
let bgColor = computedStyle.getPropertyValue('--accent');
let coffeeColor = "ffffff";
if (isValidHexColor(fontColor) &&
isValidHexColor(bgColor)) {
fontColor = fontColor.slice(1);
bgColor = bgColor.slice(1);
coffeeColor = fontColor;
}
else {
fontColor = "000000";
bgColor = "FFDD00";
coffeeColor = "ffffff";
}
return { bgColor, fontColor, coffeeColor };
}
function isValidHexColor(possibleColor) {
let firstChar = possibleColor[0];
if (firstChar !== "#") {
return false;
}
if (possibleColor.length !== 7) {
return false;
}
return /^#[0-9A-F]{6}$/i.test(possibleColor);
}
/*
* File: multi-column-markdown/src/main.ts
* Created Date: Tuesday, October 5th 2021, 1:09 pm
* Author: Cameron Robinson
*
* Copyright (c) 2022 Cameron Robinson
*/
const CODEBLOCK_START_STRS = [
"start-multi-column",
"multi-column-start"
];
class MultiColumnMarkdown extends obsidian.Plugin {
constructor() {
super(...arguments);
this.settingsManager = MCM_SettingsManager.shared;
this.globalManager = new GlobalDOMManager();
//#endregion PDF Exporting.
}
onload() {
return __awaiter(this, void 0, void 0, function* () {
console.log("Loading multi-column markdown");
yield this.loadSettings();
this.globalManager = new GlobalDOMManager();
this.registerEditorExtension(multiColumnMarkdown_StateField);
this.registerEditorExtension(MultiColumnMarkdown_OnClickFix);
for (let i = 0; i < CODEBLOCK_START_STRS.length; i++) {
let startStr = CODEBLOCK_START_STRS[i];
this.setupMarkdownCodeblockPostProcessor(startStr);
}
this.setupMarkdownPostProcessor();
this.addSettingTab(new MultiColumnSettingsView(this.app, this));
this.addCommand({
id: `toggle-mobile-rendering-mcm`,
name: `Toggle Mobile Rendering - Multi-Column Markdown`,
callback: () => __awaiter(this, void 0, void 0, function* () {
this.settingsManager.renderOnMobile = !this.settingsManager.renderOnMobile;
yield this.saveSettings();
let noticeString = `Toggled mobile rendering ${this.settingsManager.renderOnMobile ? "on" : "off"}.`;
if (obsidian.Platform.isMobile === true) {
noticeString += ` Please reload any open files for change to take effect.`;
}
new obsidian.Notice(noticeString);
})
});
//TODO: Set up this as a modal to set settings automatically
this.addCommand({
id: `insert-multi-column-region`,
name: `Insert Multi-Column Region`,
editorCallback: (editor, view) => {
try {
let cursorStartPosition = editor.getCursor("from");
editor.getDoc().replaceSelection(`
--- start-multi-column: ID_${getUID(4)}
\`\`\`column-settings
Number of Columns: 2
Largest Column: standard
\`\`\`
--- column-break ---
--- end-multi-column
${editor.getDoc().getSelection()}`);
cursorStartPosition.line = cursorStartPosition.line + 7;
cursorStartPosition.ch = 0;
editor.setCursor(cursorStartPosition);
}
catch (e) {
new obsidian.Notice("Encountered an error inserting a multi-column region. Please try again later.");
}
}
});
this.addCommand({
id: `clear-lp-cache-mcm`,
name: `Clear Live Preview Cache - Multi-Column Markdown`,
callback: () => __awaiter(this, void 0, void 0, function* () {
clearLivePreviewCache();
})
});
this.addCommand({
id: `add-IDs-To-multi-column-region`,
name: `Fix Missing IDs for Multi-Column Regions`,
editorCallback: (editor, view) => {
try {
/**
* Not sure if there is an easier way to do this.
*
* Get all of the lines of the document split by newlines.
*/
let docText = editor.getRange({ line: 0, ch: 0 }, { line: editor.getDoc().lineCount(), ch: 0 });
let lines = docText.split("\n");
let startCodeblock = findStartCodeblock(docText);
let lineOffset = 0;
let numCodeblocksUpdated = 0;
while (startCodeblock.found === true) {
// Get the text of the settings block so we can check if it contains an ID,
// also so we can get the length of the first line, used to calculate where to append a new ID if needed
let settingsText = docText.slice(startCodeblock.startPosition, startCodeblock.endPosition);
let firstLineOfCodeblockLength = settingsText.split("\n")[0].length;
// We need the lines before the block to know where to start replacing text
// and the lines including the block to know where to set our offset to after this iteration.
let linesBefore = docText.slice(0, startCodeblock.startPosition);
let startReplacementLineIndex = (linesBefore.split("\n").length - 1) + lineOffset;
let linesOf = docText.slice(0, startCodeblock.endPosition);
let endReplacementLineIndex = (linesOf.split("\n").length - 1) + lineOffset;
let settingsID = parseStartRegionCodeBlockID(settingsText);
if (settingsID === "") {
// copy the first line of the codeblock and append a new ID, then replace the first line of the block
let replacementText = editor.getRange({ line: startReplacementLineIndex, ch: 0 }, { line: startReplacementLineIndex, ch: firstLineOfCodeblockLength }) + `\nID: ID_${getUID(4)}`;
editor.replaceRange(replacementText, { line: startReplacementLineIndex, ch: 0 }, { line: startReplacementLineIndex, ch: firstLineOfCodeblockLength });
endReplacementLineIndex += 1;
numCodeblocksUpdated += 1;
}
lineOffset = endReplacementLineIndex;
docText = docText.slice(startCodeblock.endPosition);
startCodeblock = findStartCodeblock(docText);
}
/**
* Loop through all of the lines checking if the line is a
* start tag and if so is it missing an ID.
*/
let linesWithoutIDs = [];
let textWithoutIDs = [];
for (let i = 0; i < lines.length; i++) {
let data = isStartTagWithID(lines[i]);
if (data.isStartTag === true && data.hasKey === false) {
linesWithoutIDs.push(i);
textWithoutIDs.push(lines[i]);
}
}
if (linesWithoutIDs.length === 0 && numCodeblocksUpdated === 0) {
new obsidian.Notice("Found 0 missing IDs in the current document.");
return;
}
/**
* Now loop through each line that is missing an ID and
* generate a random ID and replace the original text.
*/
for (let i = 0; i < linesWithoutIDs.length; i++) {
let originalText = textWithoutIDs[i];
let text = originalText;
text = text.trimEnd();
if (text.charAt(text.length - 1) === ":") {
text = text.slice(0, text.length - 1);
}
text = `${text}: ID_${getUID(4)}`;
editor.replaceRange(text, { line: linesWithoutIDs[i], ch: 0 }, { line: linesWithoutIDs[i], ch: originalText.length });
}
new obsidian.Notice(`Replaced ${linesWithoutIDs.length + numCodeblocksUpdated} missing ID(s) in the current document.`);
}
catch (e) {
new obsidian.Notice("Encountered an error addign IDs to multi-column regions. Please try again later.");
}
}
});
this.addCommand({
id: `mcm-Toggle-Document-Reflow`,
name: `Setup Multi-Column Reflow - Multi-Column Markdown`,
editorCallback: (editor, view) => {
app.fileManager.processFrontMatter(view.file, (frontmatter) => {
let isReflow = isMultiColumnReflow(frontmatter);
if (isReflow) {
return;
}
frontmatter["Multi-Column Markdown"] = [
{ "Number of Columns": 2 },
{ "Column Size": "Standard" }
];
view.editor.refresh();
});
}
});
this.addCommand({
id: `mcm-fix-file-multi-column-syntax`,
name: `Fix Multi-Column Syntax in Current File.`,
editorCallback: (editor, view) => {
try {
let fromPosition = { line: 0, ch: 0 };
let toPosition = { line: editor.getDoc().lineCount(), ch: 0 };
let docText = editor.getRange(fromPosition, toPosition);
let result = updateAllSyntax(docText);
let regionStartCount = result.regionStartCount;
let columnBreakCount = result.columnBreakCount;
let columnEndCount = result.columnEndCount;
let updatedFileContent = result.updatedFileContent;
if (result.fileWasUpdated) {
editor.replaceRange(updatedFileContent, fromPosition, toPosition);
new obsidian.Notice(`Finished updating:\n${regionStartCount} start syntaxes,\n${columnBreakCount} column breaks, and\n${columnEndCount} column end tags.`);
}
else {
new obsidian.Notice(`Found no region syntax to update.`);
}
}
catch (e) {
new obsidian.Notice("Encountered an error fixing multi-column region syntax. Please try again later.");
}
}
});
this.registerInterval(window.setInterval(() => {
this.UpdateOpenFilePreviews();
}, 500));
});
}
UpdateOpenFilePreviews() {
let fileManagers = this.globalManager.getAllFileManagers();
fileManagers.forEach(element => {
let regionalManagers = element.getAllRegionalManagers();
regionalManagers.forEach(regionManager => {
regionManager.updateRenderedMarkdown();
});
});
}
setupMarkdownPostProcessor() {
this.registerMarkdownPostProcessor((el, ctx) => __awaiter(this, void 0, void 0, function* () {
if (this.settingsManager.renderOnMobile === false &&
obsidian.Platform.isMobile === true) {
return;
}
const sourcePath = ctx.sourcePath;
let fileDOMManager = this.globalManager.getFileManager(sourcePath);
if (fileDOMManager === null) {
console.warn("Found null DOM manager. Could not process multi-column markdown.");
return;
}
/**
* Here we check if the export "print" flag is in the DOM so we can determine if we
* are exporting and handle that case.
*/
if (this.checkExporting(el)) {
this.exportDocumentToPDF(el, fileDOMManager, sourcePath);
}
// Get the info for our current context and then check
// if the entire text contains a start tag. If there is
// no start tag in the document we can just return and
// ignore the rest of the parsing.
let info = ctx.getSectionInfo(el);
/**
* We need the context info to properly parse so returning here
* info is null. TODO: Set error in view if this occurs.
*/
if (!info) {
return;
}
let docString = info.text;
let docLines = docString.split("\n");
let reflowFrontmatter = isMultiColumnReflow(ctx.frontmatter);
if (reflowFrontmatter === true) {
this.renderDocReflow(el, ctx, sourcePath, fileDOMManager, docString, info);
return;
}
else {
fileDOMManager.removeRegion("Multi-Column Reflow Region");
}
/**
* If we encounter a start tag on the document we set the flag to start
* parsing the rest of the document.
*/
if (containsRegionStart(docString)) {
fileDOMManager.setHasStartTag();
}
/**
* If the document does not contain any start tags we ignore the
* rest of the parsing. This is only set to true once the first
* start tag element is parsed above.
*/
if (fileDOMManager.getHasStartTag() === false) {
return;
}
/**
* Take the info provided and generate the required variables from
* the line start and end values.
*/
let relativeTexts = extractElementRelativeLocationData(docLines, info);
/**
* If the current line is a start tag we want to set up the
* region manager. The regional manager takes care
* of all items between it's start and end tags while the
* file manager we got above above takes care of all regional
* managers in each file.
*/
if (containsStartTag(relativeTexts.textOfElement)) {
createStartElement(el, relativeTexts.linesOfElement, ctx, fileDOMManager, docString);
return;
}
// Pandoc Start Region Tag.
if (containsPandocStartTag(relativeTexts.textOfElement)) {
createPandocStartElement(el, relativeTexts.textOfElement, ctx, fileDOMManager, docString);
return;
}
/**
* Check if any of the lines above us contain a start block, and if
* so get the lines from our current element to the start block.
*/
let startBockAbove = getStartDataAboveLine(relativeTexts.linesAboveArray);
if (startBockAbove === null) {
return;
}
/**
* We now know we're within a multi-column region, so we update our
* list of lines above to just be the items within this region.
*/
relativeTexts.linesAboveArray = startBockAbove.linesAboveArray;
/**
* We use the start block's key to get our regional manager. If this
* lookup fails we can not continue processing this element.
*/
let regionalContainer = fileDOMManager.getRegionalContainer(startBockAbove.startBlockKey);
if (regionalContainer === null) {
return;
}
regionalContainer.getRegion();
/**
* To make sure we're placing the item in the right location (and
* overwrite elements that are now gone) we now want all of the
* lines after this element up to the end tag.
*/
relativeTexts.linesBelowArray = getEndBlockBelow(relativeTexts.linesBelowArray);
/**
* Now we take the lines above our current element up until the
* start region tag and render that into an HTML element. We will
* use these elements to determine where to place our current element.
*/
this.appendToRegionalManager(el, regionalContainer, ctx, relativeTexts, sourcePath, startBockAbove, (domObj) => {
onUnloadElement(domObj, regionalContainer);
});
return;
}));
}
appendToRegionalManager(el, regionalContainer, ctx, relativeLines, sourcePath, parentStartBlock, onUnloadCallback) {
let { linesAboveArray, linesOfElement, linesBelowArray, textOfElement } = relativeLines;
let siblingsAbove = renderMarkdownFromLines(linesAboveArray, sourcePath);
let siblingsBelow = renderMarkdownFromLines(linesBelowArray, sourcePath);
let regionalManager = regionalContainer.getRegion();
/**
* Set up our dom object to be added to the manager.
*/
let currentObject = new DOMObject(el, linesOfElement);
el.id = currentObject.UID;
currentObject = TaskListDOMObject.checkForTaskListElement(currentObject);
/**
* Now we add the object to the manager and then setup the
* callback for when the object is removed from view that will remove
* the item from the manager.
*/
regionalManager.addObject(siblingsAbove, siblingsBelow, currentObject);
let elementMarkdownRenderer = new obsidian.MarkdownRenderChild(el);
elementMarkdownRenderer.onunload = () => {
onUnloadCallback(currentObject);
};
ctx.addChild(elementMarkdownRenderer);
/**
* Now we check if our current element is a special flag so we can
* properly set the element tag within the regional manager.
*/
if (containsEndTag(el.textContent) === true &&
parentStartBlock.startBlockType !== "PADOC") {
currentObject.elementType = "unRendered";
regionalManager.updateElementTag(currentObject.UID, DOMObjectTag.endRegion);
}
if (isValidPandocEndTag(linesAboveArray, el.textContent) === true &&
parentStartBlock.startBlockType === "PADOC") {
currentObject.elementType = "unRendered";
regionalManager.updateElementTag(currentObject.UID, DOMObjectTag.endRegion);
}
else if (containsColEndTag(textOfElement) === true) {
currentObject.elementType = "unRendered";
regionalManager.updateElementTag(currentObject.UID, DOMObjectTag.columnBreak);
}
else if (containsColSettingsTag(textOfElement) === true) {
currentObject.elementType = "unRendered";
regionalManager = regionalContainer.setRegionSettings(textOfElement);
regionalManager.updateElementTag(currentObject.UID, DOMObjectTag.regionSettings);
}
setElementCSS(currentObject, el);
parseColBreakErrorType({
lineAbove: linesAboveArray.last(),
lineBelow: linesBelowArray.first(),
objectTag: currentObject.tag,
colBreakType: currentObject.elementIsColumnBreak
}, regionalManager.errorManager);
regionalManager.renderRegionElementsToScreen();
return regionalManager;
}
setupMarkdownCodeblockPostProcessor(startStr) {
this.registerMarkdownCodeBlockProcessor(startStr, (source, el, ctx) => {
var _a;
if (this.settingsManager.renderOnMobile === false &&
obsidian.Platform.isMobile === true) {
return;
}
const sourcePath = ctx.sourcePath;
// Set up our CSS so that the codeblock only renders this data in reading mode
// source/live preview mode is handled by the CM6 implementation.
(_a = el.parentElement) === null || _a === void 0 ? void 0 : _a.addClass("preivew-mcm-start-block");
// To determine what kind of view we are rendering in we need a markdown leaf.
// Really this should never return here since rendering is only done in markdown leaves.
let markdownLeaves = app.workspace.getLeavesOfType("markdown");
if (markdownLeaves.length === 0) {
return;
}
if (this.globalManager === null || this.globalManager === undefined) {
// console.log("Global manager is undefined?");
return;
}
let fileDOMManager = this.globalManager.getFileManager(sourcePath);
if (fileDOMManager === null) {
return;
}
if (ctx.frontmatter &&
ctx.frontmatter["Multi-Column Reflow"] !== undefined) {
return;
}
else {
fileDOMManager.removeRegion("Multi-Column Reflow Region");
}
// Set file to have start tag.
fileDOMManager.setHasStartTag();
// Get the info for our current context and then check
// if the entire text contains a start tag. If there is
// no start tag in the document we can just return and
// ignore the rest of the parsing.
let info = ctx.getSectionInfo(el);
/**
* We need the context info to properly parse so returning here
* info is null. TODO: Set error in view if this occurs.
*/
if (!info) {
return;
}
/**
* Set up the current element to act as the parent for the
* multi-column region.
*/
el.classList.add(MultiColumnLayoutCSS.RegionRootContainerDiv);
let errorManager = new RegionErrorManager(el, ["The codeblock region start syntax has been depricated. Please manually update to the current syntax defined in the ReadMe, run the \"Fix Multi-Column Syntax in Current File\" from the Command Palette, or use the \"Update Depricated Syntax\" command found in the plugin settings window. You must reload the file for changes to take effect."]);
let renderColumnRegion = el.createDiv({
cls: MultiColumnLayoutCSS.RegionContentContainerDiv
});
let regionKey = parseStartRegionCodeBlockID(source);
let createNewRegionManager = true;
if (fileDOMManager.checkKeyExists(regionKey) === true) {
createNewRegionManager = false;
let { numberOfTags, keys } = countStartTags(info.text);
let numMatches = 0;
for (let i = 0; i < numberOfTags; i++) {
// Because we checked if key exists one of these has to match.
if (keys[i] === regionKey) {
numMatches++;
}
}
// We only want to display an error if there are more than 2 of the same id across
// the whole document. This prevents erros when obsidian reloads the whole document
// and there are two of the same key in the map.
if (numMatches >= 2) {
if (regionKey === "") {
errorManager.addErrorMessage("Found multiple regions with empty IDs. Please set a unique ID in the codeblock.\nEG: 'ID: randomID'");
}
else {
errorManager.addErrorMessage("Region ID already exists in document, please set a unique ID.");
}
return;
}
}
el.id = `MultiColumnID:${regionKey}`;
// If something changes in the codeblock we dont necessarily want to update our
// old reference to the region manager. This could be a potential bug area.
if (createNewRegionManager === true) {
// Create a new regional manager.
let elementMarkdownRenderer = new obsidian.MarkdownRenderChild(el);
fileDOMManager.createRegionalManager(regionKey, el, errorManager, renderColumnRegion);
// Set up the on unload callback. This can be called if the user changes
// the start/settings codeblock in any way. We only want to unload
// if the file is being removed from view.
elementMarkdownRenderer.onunload = () => {
if (fileDOMManager && fileStillInView(sourcePath) === false) {
// console.debug("File not in any markdown leaf. Removing region from dom manager.")
fileDOMManager.removeRegion(regionKey);
}
};
ctx.addChild(elementMarkdownRenderer);
}
let regionalManagerContainer = fileDOMManager.getRegionalContainer(regionKey);
if (regionalManagerContainer !== null) {
let regionalManager = regionalManagerContainer.setRegionSettings(source);
regionalManager.regionParent = renderColumnRegion;
}
});
}
loadSettings() {
return __awaiter(this, void 0, void 0, function* () {
this.settingsManager.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
});
}
saveSettings() {
return __awaiter(this, void 0, void 0, function* () {
yield this.saveData(this.settingsManager.settings);
});
}
renderDocReflow(el, ctx, sourcePath, fileDOMManager, docString, info) {
let regionalContainer = null;
if (fileDOMManager.checkKeyExists("Multi-Column Reflow Region") === true &&
el.getElementsByClassName("frontmatter").length === 0) {
regionalContainer = fileDOMManager.getRegionalContainer("Multi-Column Reflow Region");
}
else if (fileDOMManager.checkKeyExists("Multi-Column Reflow Region") === true &&
el.getElementsByClassName("frontmatter").length === 1) {
let parentEl = createDiv();
el.appendChild(parentEl);
// Get current data, remove old region.
regionalContainer = fileDOMManager.getRegionalContainer("Multi-Column Reflow Region");
let domList = regionalContainer.getRegion().getRegionData().domList.slice();
fileDOMManager.removeRegion("Multi-Column Reflow Region");
// Create new region.
setupStartTag(parentEl, ctx, fileDOMManager, docString, "Multi-Column Reflow Region");
regionalContainer = fileDOMManager.getRegionalContainer("Multi-Column Reflow Region");
let settings = getMultiColumnSettingsFromFrontmatter(ctx);
let leaf = getLeafFromFilePath(this.app.workspace, ctx.sourcePath);
let clientHeight = calcVisibleClietHeight(leaf, this.app.workspace);
if (settings.columnHeight === null) {
settings.columnHeight = HTMLSizing.create().setWidth(clientHeight).setUnits("px");
}
else {
settings.columnHeight = settings.columnHeight.convertToPX(this.app.workspace.containerEl);
}
regionalContainer.setRegionParsedSettings(settings);
// Re-Render after small delay.
// Delay is so the auto layout check can properly read the client height.
function delayRender() {
return __awaiter(this, void 0, void 0, function* () {
setTimeout(() => {
// Append all items to region.
let regionalManager = regionalContainer.getRegion();
let listLength = domList.length;
for (let i = 0; i < listLength; i++) {
let domObj = domList.shift();
regionalManager.addObjectAtIndex(domObj, i);
setElementCSS(domObj, domObj.originalElement);
}
regionalContainer.getRegion().renderRegionElementsToScreen();
}, 50);
});
}
delayRender();
return;
}
else {
// The first element to hit this point appears to be the yaml information which we can use
// as our root div since the whole doc is going to be re-formatted.
let parentEl = createDiv();
el.appendChild(parentEl);
setupStartTag(parentEl, ctx, fileDOMManager, docString, "Multi-Column Reflow Region");
regionalContainer = fileDOMManager.getRegionalContainer("Multi-Column Reflow Region");
let settings = getMultiColumnSettingsFromFrontmatter(ctx);
let leaf = getLeafFromFilePath(this.app.workspace, ctx.sourcePath);
let clientHeight = calcVisibleClietHeight(leaf, this.app.workspace);
if (settings.columnHeight === null) {
settings.columnHeight = HTMLSizing.create().setWidth(clientHeight).setUnits("px");
}
else {
settings.columnHeight = settings.columnHeight.convertToPX(this.app.workspace.containerEl);
}
regionalContainer.setRegionParsedSettings(settings);
return;
}
if (regionalContainer === null) {
return;
}
let docLines = docString.split("\n");
let relativeTexts = extractElementRelativeLocationData(docLines, info);
relativeTexts.linesBelowArray = getEndBlockBelow(relativeTexts.linesBelowArray);
if (containsStartTag(relativeTexts.textOfElement) ||
containsColSettingsTag(relativeTexts.textOfElement)) {
if (containsStartTag(relativeTexts.textOfElement)) {
setElementCSSByTag(DOMObjectTag.startRegion, el);
}
else if (containsColSettingsTag(relativeTexts.textOfElement)) {
setElementCSSByTag(DOMObjectTag.regionSettings, el);
}
return;
}
let startBockAbove = {
linesAboveArray: relativeTexts.linesAboveArray,
startBlockKey: "Multi-Column Reflow Region",
startBlockType: "ORIGINAL"
};
this.appendToRegionalManager(el, regionalContainer, ctx, relativeTexts, sourcePath, startBockAbove, (domObj) => {
onUnloadElement(domObj, regionalContainer);
});
}
//#region PDF Exporting.
isStartCodeblockInExport(node) {
for (let i = 0; i < CODEBLOCK_START_STRS.length; i++) {
if (node.hasClass(`block-language-${CODEBLOCK_START_STRS[i]}`)) {
return true;
}
}
return false;
}
exportDocumentToPDF(el, fileDOMManager, sourcePath) {
return __awaiter(this, void 0, void 0, function* () {
// A true export will be passed an element with all other items in the doc as children.
// So if there are no children we can just return
let docChildren = Array.from(el.childNodes);
if (docChildren.length === 0) {
return;
}
let childrenToRemove = [];
// To export codeblocks we need to get the IDs so we can get the data from our managers.
// however since the ID isnt being stored in the element yet this means we need to read
// all of the IDs out of the full document.
let codeblockStartBlocks = [];
let aFile = this.app.vault.getAbstractFileByPath(sourcePath);
if (aFile instanceof obsidian.TFile) {
let file = aFile;
let fileText = yield this.app.vault.cachedRead(file); // Is cached read Ok here? It should be.
// Once we have our data we search the text for all codeblock start values.
// storing them into our queue.
let codeBlockData = findStartCodeblock(fileText);
while (codeBlockData.found === true) {
let codeblockText = fileText.slice(codeBlockData.startPosition, codeBlockData.endPosition);
fileText = fileText.slice(codeBlockData.endPosition);
codeblockStartBlocks.push(codeblockText);
codeBlockData = findStartCodeblock(fileText);
}
}
else {
console.error(`Error getting file from source path: ${sourcePath}`);
}
let inBlock = false;
for (let i = 0; i < docChildren.length; i++) {
let child = docChildren[i];
if (child instanceof HTMLElement) {
if (inBlock === false) {
let foundBlockData = false;
let regionKey = "";
let blockData = isStartTagWithID(child.textContent);
let pandocData = getPandocStartData(child.textContent);
if (blockData.isStartTag === true) {
// If an old-style start tag.
foundBlockData = true;
if (blockData.hasKey === true) {
let foundKey = getStartTagKey(child.textContent);
if (foundKey !== null) {
regionKey = foundKey;
}
}
}
else if (blockData.isStartTag === false && this.isStartCodeblockInExport(child)) {
// If the start tag from the old version is null we then check to see if the element is
// a codeblock start. If it is we use the next available codeblock data to retrieve our ID.
let codeblockText = codeblockStartBlocks.shift();
if (codeblockText === undefined) {
console.error("Found undefined codeblock data when exporting.");
return;
}
let id = parseStartRegionCodeBlockID(codeblockText);
if (id !== "") {
foundBlockData = true;
regionKey = id;
}
}
else if (pandocData.found) {
foundBlockData = true;
regionKey = pandocData.userSettings.columnID;
}
if (foundBlockData === true && regionKey !== "") {
inBlock = true;
for (let i = child.children.length - 1; i >= 0; i--) {
child.children[i].detach();
}
child.innerText = "";
child.classList.add(MultiColumnLayoutCSS.RegionRootContainerDiv);
let errorManager = new RegionErrorManager(el);
let renderColumnRegion = child.createDiv({
cls: MultiColumnLayoutCSS.RegionContentContainerDiv
});
let regionalContainer = fileDOMManager.getRegionalContainer(regionKey);
if (regionalContainer === null || regionalContainer.getRegion().numberOfChildren === 0) {
// If the number of children is 0, we are probably in LivePreview, where the codeblock start regions have been processed by native obsidian live preview but do not have any children linked to them.
errorManager.addErrorMessage("Error rendering multi-column region.\nPlease close and reopen the file, then make sure you are in reading mode before exporting.");
}
else {
let regionalManager = regionalContainer.getRegion();
regionalManager.exportRegionElementsToPDF(renderColumnRegion);
}
}
}
else {
if (containsEndTag(child.textContent) === true ||
containsPandocEndTag(child.textContent) === true) {
inBlock = false;
}
childrenToRemove.push(child);
}
}
}
childrenToRemove.forEach(child => {
if (child.parentElement === el) {
el.removeChild(child);
}
});
});
}
checkExporting(element) {
if (element === null) {
return false;
}
if (element.classList.contains("print")) {
return true;
}
if (element.parentNode !== null) {
return this.checkExporting(element.parentElement);
}
return false;
}
}
function setElementCSS(currentObject, el) {
setElementCSSByTag(currentObject.tag, el);
}
function setElementCSSByTag(tag, el) {
if (tag === DOMObjectTag.endRegion) {
el.addClass(MultiColumnStyleCSS.RegionEndTag);
}
else if (tag === DOMObjectTag.columnBreak) {
el.addClass(MultiColumnStyleCSS.ColumnEndTag);
}
else if (tag === DOMObjectTag.regionSettings) {
el.addClass(MultiColumnStyleCSS.RegionSettings);
}
else {
el.addClass(MultiColumnStyleCSS.RegionContent);
}
}
function onUnloadElement(currentObject, regionalContainer) {
if (regionalContainer === null) {
return;
}
let regionalManager = regionalContainer.getRegion();
if (regionalManager) {
// We can attempt to update the view here after the item is removed
// but need to get the item's parent element before removing object from manager.
let regionRenderData = regionalManager.getRegionRenderData();
regionalManager.removeObject(currentObject.UID);
/**
* Need to check here if element is null as this closure will be called
* repeatedly on file change.
*/
if (regionRenderData.parentRenderElement === null) {
return;
}
regionalManager.renderRegionElementsToScreen();
}
}
function extractElementRelativeLocationData(docLines, info) {
let linesAboveArray = docLines.slice(0, info.lineStart);
let linesOfElement = docLines.slice(info.lineStart, info.lineEnd + 1);
let textOfElement = linesOfElement.join("\n");
let linesBelowArray = docLines.slice(info.lineEnd + 1);
return {
linesAboveArray,
linesOfElement,
linesBelowArray,
textOfElement
};
}
function createStartElement(el, linesOfElement, ctx, fileDOMManager, docString) {
el.children[0].detach();
let startBlockData = getStartBlockAboveLine(linesOfElement);
if (startBlockData === null) {
return;
}
let regionID = startBlockData.startBlockKey;
setupStartTag(el, ctx, fileDOMManager, docString, regionID);
return;
}
function createPandocStartElement(el, textOfElement, ctx, fileDOMManager, docString) {
el.children[0].detach();
let pandocData = getPandocStartData(textOfElement);
let settings = pandocData.userSettings;
let regionManager = setupStartTag(el, ctx, fileDOMManager, docString, settings.columnID);
regionManager.setRegionalSettings(settings);
return;
}
function renderMarkdownFromLines(mdLines, sourcePath) {
/**
* We re-render all of the items above our element, until the start tag,
* so we can determine where to place the new item in the manager.
*
* TODO: Can reduce the amount needing to be rendered by only rendering to
* the start tag or a column-break whichever is closer.
*/
let siblings = createDiv();
let markdownRenderChild = new obsidian.MarkdownRenderChild(siblings);
obsidian.MarkdownRenderer.renderMarkdown(mdLines.reduce((prev, current) => {
return prev + "\n" + current;
}, ""), siblings, sourcePath, markdownRenderChild);
return siblings;
}
function setupStartTag(el, ctx, fileDOMManager, docString, regionID) {
/**
* Set up the current element to act as the parent for the
* multi-column region.
*/
el.classList.add(MultiColumnLayoutCSS.RegionRootContainerDiv);
let errorManager = new RegionErrorManager(el);
let renderColumnRegion = el.createDiv({
cls: MultiColumnLayoutCSS.RegionContentContainerDiv
});
if (fileDOMManager.checkKeyExists(regionID) === true) {
let { numberOfTags, keys } = countStartTags(docString);
let numMatches = 0;
for (let i = 0; i < numberOfTags; i++) {
// Because we checked if key exists one of these has to match.
if (keys[i] === regionID) {
numMatches++;
}
}
// We only want to display an error if there are more than 2 of the same id across
// the whole document. This prevents erros when obsidian reloads the whole document
// and there are two of the same key in the map.
if (numMatches >= 2) {
if (regionID === "") {
errorManager.addErrorMessage("Found multiple regions with empty IDs. Please set a unique ID after each start tag.\nEG: '--- multi-column-start: randomID'\nOr use 'Fix Missing IDs' in the command palette and reload the document.");
}
else {
errorManager.addErrorMessage("Region ID already exists in document, please set a unique ID.\nEG: '--- multi-column-start: randomID'");
}
return;
}
}
el.id = `MultiColumnID:${regionID}`;
let elementMarkdownRenderer = new obsidian.MarkdownRenderChild(el);
let regionManager = fileDOMManager.createRegionalManager(regionID, el, errorManager, renderColumnRegion);
elementMarkdownRenderer.onunload = () => {
if (fileDOMManager) {
fileDOMManager.removeRegion(regionID);
}
};
ctx.addChild(elementMarkdownRenderer);
return regionManager;
}
const FRONTMATTER_REGEX = [
/Multi[- ]*Column *Markdown/i,
/Multi[- ]*Column *Reflow/i
];
function isMultiColumnReflow(frontmatter) {
if (frontmatter === null ||
frontmatter === undefined) {
return false;
}
for (let regex of FRONTMATTER_REGEX) {
let frontmatterReflowData = obsidian.parseFrontMatterEntry(frontmatter, regex);
if (frontmatterReflowData !== null) {
return true;
}
}
let [keys, values] = Object.entries(frontmatter);
if (keys === undefined) {
return false;
}
for (let key of keys) {
if (typeof key !== "string") {
continue;
}
for (let regex of FRONTMATTER_REGEX) {
let regexResult = regex.exec(key);
if (regexResult !== null) {
return true;
}
}
}
return false;
}
function getMultiColumnSettingsFromFrontmatter(ctx) {
let settings = getDefaultMultiColumnSettings();
settings.fullDocReflow = true;
if (ctx.frontmatter === null ||
ctx.frontmatter === undefined) {
return settings;
}
for (let regex of FRONTMATTER_REGEX) {
let frontmatterReflowData = obsidian.parseFrontMatterEntry(ctx.frontmatter, regex);
if (frontmatterReflowData !== null &&
Array.isArray(frontmatterReflowData)) {
settings = parseFrontmatterSettings(frontmatterReflowData);
settings.fullDocReflow = true;
break;
}
}
return settings;
}
function parseFrontmatterSettings(frontmatterReflowData) {
let str = "";
for (let obj of frontmatterReflowData) {
let [key, value] = Object.entries(obj)[0];
str += `${key}: [${value}]\n`;
}
let settings = parseColumnSettings(str);
return settings;
}
function getContentHeightFromLeaf(leaf) {
let contentEl = leaf.view["contentEl"];
if (contentEl !== undefined &&
contentEl.clientHeight > 0) {
return contentEl.clientHeight;
}
let clientHeight = leaf.view.containerEl.clientHeight;
let titleContainer = leaf.view["titleContainerEl"];
if (titleContainer !== undefined &&
titleContainer.clientHeight > 0) {
return clientHeight - titleContainer.clientHeight;
}
return clientHeight - 50;
}
function calcVisibleClietHeight(leaf, workspace) {
let clientHeight = 0;
if (leaf) {
clientHeight = getContentHeightFromLeaf(leaf);
}
else if ((workspace !== null && workspace !== undefined) &&
(workspace.containerEl !== null && workspace.containerEl !== undefined) &&
workspace.containerEl.clientHeight > 0) {
clientHeight = workspace.containerEl.clientHeight - 100;
}
else {
clientHeight = 1000;
}
return clientHeight;
}
module.exports = MultiColumnMarkdown;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm5vZGVfbW9kdWxlcy9AcGFjb3RlL2dldC1zdHlsZS9saWIvZXNtL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BwYWNvdGUvcGl4ZWxzL2xpYi9lc20vaW5kZXguanMiLCJzcmMvdXRpbGl0aWVzL2ludGVyZmFjZXMudHMiLCJzcmMvcmVnaW9uU2V0dGluZ3MudHMiLCJzcmMvdXRpbGl0aWVzL3NldHRpbmdzUGFyc2VyLnRzIiwic3JjL3V0aWxpdGllcy9wYW5kb2NQYXJzZXIudHMiLCJzcmMvdXRpbGl0aWVzL3RleHRQYXJzZXIudHMiLCJzcmMvdXRpbGl0aWVzL3V0aWxzLnRzIiwic3JjL2RvbV9tYW5hZ2VyL2RvbU9iamVjdC50cyIsInNyYy91dGlsaXRpZXMvY3NzRGVmaW5pdGlvbnMudHMiLCJzcmMvdXRpbGl0aWVzL2VsZW1lbnRSZW5kZXJUeXBlUGFyc2VyLnRzIiwic3JjL2RvbV9tYW5hZ2VyL3JlZ2lvbmFsX21hbmFnZXJzL3JlZ2lvbk1hbmFnZXIudHMiLCJzcmMvcGx1Z2luU2V0dGluZ3MudHMiLCJzcmMvZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvc3RhbmRhcmRNdWx0aUNvbHVtblJlZ2lvbk1hbmFnZXIudHMiLCJzcmMvZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvc2luZ2xlQ29sdW1uUmVnaW9uTWFuYWdlci50cyIsInNyYy9kb21fbWFuYWdlci9yZWdpb25hbF9tYW5hZ2Vycy9hdXRvTGF5b3V0UmVnaW9uTWFuYWdlci50cyIsInNyYy9kb21fbWFuYWdlci9yZWdpb25hbF9tYW5hZ2Vycy9yZWZsb3dSZWdpb25NYW5hZ2VyLnRzIiwic3JjL2RvbV9tYW5hZ2VyL3JlZ2lvbmFsX21hbmFnZXJzL3JlZ2lvbk1hbmFnZXJDb250YWluZXIudHMiLCJzcmMvZG9tX21hbmFnZXIvZG9tTWFuYWdlci50cyIsInNyYy9kb21fbWFuYWdlci9yZWdpb25FcnJvck1hbmFnZXIudHMiLCJzcmMvdXRpbGl0aWVzL2Vycm9yTWVzc2FnZS50cyIsInNyYy91dGlsaXRpZXMvb2JzaVV0aWxzLnRzIiwic3JjL2xpdmVfcHJldmlldy9tY21fbGl2ZVByZXZpZXdfd2lkZ2V0LnRzIiwic3JjL2xpdmVfcHJldmlldy9jbTZfbGl2ZVByZXZpZXcudHMiLCJzcmMvbGl2ZV9wcmV2aWV3L2NtNl9saXZlUHJlaXZld19vbkNsaWNrRml4LnRzIiwic3JjL3V0aWxpdGllcy9zeW50YXhVcGRhdGUudHMiLCJzcmMvc2V0dGluZ3MvTXVsdGlDb2x1bW5TZXR0aW5nc1ZpZXcudHMiLCJzcmMvbWFpbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xyXG4gICAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XHJcbiAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcclxuICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciBjb250ZXh0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XHJcbiAgICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMucHVzaChfKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XHJcbiAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy5wdXNoKF8pO1xyXG4gICAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xyXG4gICAgZG9uZSA9IHRydWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoZyAmJiAoZyA9IDAsIG9wWzBdICYmIChfID0gMCkpLCBfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcclxuICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XHJcbiAgICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcclxuICAgIH1cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXHJcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgcmV0dXJuIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5KHRvLCBmcm9tLCBwYWNrKSB7XHJcbiAgICBpZiAocGFjayB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSBmb3IgKHZhciBpID0gMCwgbCA9IGZyb20ubGVuZ3RoLCBhcjsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcclxuICAgICAgICAgICAgaWYgKCFhcikgYXIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tLCAwLCBpKTtcclxuICAgICAgICAgICAgYXJbaV0gPSBmcm9tW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0by5jb25jYXQoYXIgfHwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSkpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xyXG4gICAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XHJcbiAgICByZXR1cm4gdHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciA9PT0gc3RhdGUgOiBzdGF0ZS5oYXMocmVjZWl2ZXIpO1xyXG59XHJcbiIsImV4cG9ydCBmdW5jdGlvbiBnZXRTdHlsZShlbGVtZW50LCBwcm9wZXJ0eSkge1xuICAgIHZhciBfYTtcbiAgICBjb25zdCB2aWV3ID0gKChfYSA9IGVsZW1lbnQub3duZXJEb2N1bWVudCkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmRlZmF1bHRWaWV3KSB8fCB3aW5kb3c7XG4gICAgY29uc3Qgc3R5bGUgPSB2aWV3LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG4gICAgcmV0dXJuIChzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKHByb3BlcnR5KSB8fCBzdHlsZVtwcm9wZXJ0eV0pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgZ2V0U3R5bGUgfSBmcm9tICdAcGFjb3RlL2dldC1zdHlsZSc7XG5jb25zdCBQSVhFTFNfUEVSX0lOQ0ggPSA5NjtcbmNvbnN0IE1JTExJTUVUUkVTX1BFUl9JTkNIID0gMjUuNDtcbmNvbnN0IFBPSU5UU19QRVJfSU5DSCA9IDcyO1xuY29uc3QgUElDQVNfUEVSX0lOQ0ggPSA2O1xuZnVuY3Rpb24gZm9udFNpemUoZWxlbWVudCkge1xuICAgIHJldHVybiBlbGVtZW50XG4gICAgICAgID8gZ2V0U3R5bGUoZWxlbWVudCwgJ2ZvbnRTaXplJykgfHwgZm9udFNpemUoZWxlbWVudC5wYXJlbnRFbGVtZW50KVxuICAgICAgICA6IGdldFN0eWxlKHdpbmRvdy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdmb250U2l6ZScpO1xufVxuZnVuY3Rpb24gcGFyc2UocHJvdmlkZWRMZW5ndGgpIHtcbiAgICB2YXIgX2E7XG4gICAgY29uc3QgbGVuZ3RoID0gcHJvdmlkZWRMZW5ndGggfHwgJzAnO1xuICAgIGNvbnN0IHZhbHVlID0gcGFyc2VGbG9hdChsZW5ndGgpO1xuICAgIGNvbnN0IG1hdGNoID0gbGVuZ3RoLm1hdGNoKC9bXFxkLS5dKyhcXHcrKSQvKTtcbiAgICBjb25zdCB1bml0ID0gKF9hID0gbWF0Y2ggPT09IG51bGwgfHwgbWF0Y2ggPT09IHZvaWQgMCA/IHZvaWQgMCA6IG1hdGNoWzFdKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiAnJztcbiAgICByZXR1cm4gW3ZhbHVlLCB1bml0LnRvTG93ZXJDYXNlKCldO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHBpeGVscyhsZW5ndGgsIGVsZW1lbnQpIHtcbiAgICB2YXIgX2EsIF9iO1xuICAgIGNvbnN0IHZpZXcgPSAoX2IgPSAoX2EgPSBlbGVtZW50ID09PSBudWxsIHx8IGVsZW1lbnQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGVsZW1lbnQub3duZXJEb2N1bWVudCkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmRlZmF1bHRWaWV3KSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiB3aW5kb3c7XG4gICAgY29uc3Qgcm9vdCA9IHZpZXcuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IHx8IHZpZXcuZG9jdW1lbnQuYm9keTtcbiAgICBjb25zdCBbdmFsdWUsIHVuaXRdID0gcGFyc2UobGVuZ3RoKTtcbiAgICBzd2l0Y2ggKHVuaXQpIHtcbiAgICAgICAgY2FzZSAncmVtJzpcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSAqIHBpeGVscyhmb250U2l6ZSh3aW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSk7XG4gICAgICAgIGNhc2UgJ2VtJzpcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSAqIHBpeGVscyhmb250U2l6ZShlbGVtZW50KSwgZWxlbWVudCA9PT0gbnVsbCB8fCBlbGVtZW50ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBlbGVtZW50LnBhcmVudEVsZW1lbnQpO1xuICAgICAgICBjYXNlICdpbic6XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgKiBQSVhFTFNfUEVSX0lOQ0g7XG4gICAgICAgIGNhc2UgJ3EnOlxuICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSAqIFBJWEVMU19QRVJfSU5DSCkgLyBNSUxMSU1FVFJFU19QRVJfSU5DSCAvIDQ7XG4gICAgICAgIGNhc2UgJ21tJzpcbiAgICAgICAgICAgIHJldHVybiAodmFsdWUgKiBQSVhFTFNfUEVSX0lOQ0gpIC8gTUlMTElNRVRSRVNfUEVSX0lOQ0g7XG4gICAgICAgIGNhc2UgJ2NtJzpcbiAgICAgICAgICAgIHJldHVybiAodmFsdWUgKiBQSVhFTFNfUEVSX0lOQ0ggKiAxMCkgLyBNSUxMSU1FVFJFU19QRVJfSU5DSDtcbiAgICAgICAgY2FzZSAncHQnOlxuICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSAqIFBJWEVMU19QRVJfSU5DSCkgLyBQT0lOVFNfUEVSX0lOQ0g7XG4gICAgICAgIGNhc2UgJ3BjJzpcbiAgICAgICAgICAgIHJldHVybiAodmFsdWUgKiBQSVhFTFNfUEVSX0lOQ0gpIC8gUElDQVNfUEVSX0lOQ0g7XG4gICAgICAgIGNhc2UgJ3ZoJzpcbiAgICAgICAgICAgIHJldHVybiAodmFsdWUgKiB2aWV3LmlubmVySGVpZ2h0IHx8IHJvb3QuY2xpZW50V2lkdGgpIC8gMTAwO1xuICAgICAgICBjYXNlICd2dyc6XG4gICAgICAgICAgICByZXR1cm4gKHZhbHVlICogdmlldy5pbm5lcldpZHRoIHx8IHJvb3QuY2xpZW50SGVpZ2h0KSAvIDEwMDtcbiAgICAgICAgY2FzZSAndm1pbic6XG4gICAgICAgICAgICByZXR1cm4gKCh2YWx1ZSAqXG4gICAgICAgICAgICAgICAgTWF0aC5taW4odmlldy5pbm5lcldpZHRoIHx8IHJvb3QuY2xpZW50V2lkdGgsIHZpZXcuaW5uZXJIZWlnaHQgfHwgcm9vdC5jbGllbnRIZWlnaHQpKSAvXG4gICAgICAgICAgICAgICAgMTAwKTtcbiAgICAgICAgY2FzZSAndm1heCc6XG4gICAgICAgICAgICByZXR1cm4gKCh2YWx1ZSAqXG4gICAgICAgICAgICAgICAgTWF0aC5tYXgodmlldy5pbm5lcldpZHRoIHx8IHJvb3QuY2xpZW50V2lkdGgsIHZpZXcuaW5uZXJIZWlnaHQgfHwgcm9vdC5jbGllbnRIZWlnaHQpKSAvXG4gICAgICAgICAgICAgICAgMTAwKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCIvKipcbiAqIEZpbGU6IC9zcmMvdXRpbGl0aWVzL2ludGVyZmFjZXMudHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiBBdXRob3I6IENhbWVyb24gUm9iaW5zb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqIENvcHlyaWdodCAoYykgMjAyMyBDYW1lcm9uIFJvYmluc29uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKi9cbmltcG9ydCB7IHBpeGVscyB9IGZyb20gJ0BwYWNvdGUvcGl4ZWxzJ1xuXG5leHBvcnQgY2xhc3MgSFRNTFNpemluZyB7XG5cbiAgICBwcml2YXRlIF9zaXplVmFsdWU6IG51bWJlciA9IDA7XG4gICAgcHVibGljIGdldCBzaXplVmFsdWUoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpemVWYWx1ZTtcbiAgICB9XG4gICAgcHVibGljIHNldCBzaXplVmFsdWUodmFsdWU6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9zaXplVmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gICAgcHJpdmF0ZSB3aWR0aFNldDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHByaXZhdGUgc2l6ZVVuaXRzOiBzdHJpbmcgPSBcInB4XCI7XG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3Rvcih2YWx1ZTogbnVtYmVyLCB1bml0czogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2l6ZVZhbHVlID0gdmFsdWU7XG4gICAgICAgIHRoaXMuc2l6ZVVuaXRzID0gdW5pdHM7XG4gICAgfVxuICAgIHB1YmxpYyBzZXRXaWR0aCh2YWx1ZTogbnVtYmVyKTogSFRNTFNpemluZyB7XG4gICAgICAgIHRoaXMud2lkdGhTZXQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gbmV3IEhUTUxTaXppbmcodmFsdWUsIHRoaXMuc2l6ZVVuaXRzKTtcbiAgICB9XG4gICAgcHVibGljIHNldFVuaXRzKHVuaXRzOiBzdHJpbmcpOiBIVE1MU2l6aW5nIHtcbiAgICAgICAgcmV0dXJuIG5ldyBIVE1MU2l6aW5nKHRoaXMuc2l6ZVZhbHVlLCB1bml0cyk7XG4gICAgfVxuICAgIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5zaXplVmFsdWV9JHt0aGlzLnNpemVVbml0c31gO1xuICAgIH1cblxuICAgIGNvbnZlcnRUb1BYKHBhcmVudEVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIGlmKHRoaXMuc2l6ZVVuaXRzID09PSBcInB4XCIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoKHRoaXMuc2l6ZVVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlIFwiY21cIjpcbiAgICAgICAgICAgIGNhc2UgXCJtbVwiOlxuICAgICAgICAgICAgY2FzZSBcImluXCI6XG4gICAgICAgICAgICBjYXNlIFwicHRcIjpcbiAgICAgICAgICAgIGNhc2UgXCJwY1wiOlxuICAgICAgICAgICAgICAgIGxldCBhYnNVbml0c1Jlc3VsdCA9IHBpeGVscyhgJHt0aGlzLnRvU3RyaW5nKCl9YCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBIVE1MU2l6aW5nKGFic1VuaXRzUmVzdWx0LCBcInB4XCIpO1xuICAgICAgICAgICAgY2FzZSBcInZ3XCI6XG4gICAgICAgICAgICBjYXNlIFwidmhcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlVmlld3BvcnRTaXppbmcoKTtcbiAgICAgICAgICAgIGNhc2UgXCJlbVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBnZXRGb250U2l6ZUZyb21FbCgpO1xuICAgICAgICAgICAgY2FzZSBcImNoXCI6XG4gICAgICAgICAgICAgICAgbGV0IGNoID0gY3JlYXRlRWwoXCJwXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgXCJhdHRyXCI6IHsgXCJzdHlsZVwiOiBcIndpZHRoOiAxY2g7XCIgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldFNpemVGcm9tU3R5bGVXaWR0aChjaCk7XG5cbiAgICAgICAgICAgIGNhc2UgXCJleFwiOlxuICAgICAgICAgICAgICAgIGxldCBleCA9IGNyZWF0ZUVsKFwicFwiLCB7XG4gICAgICAgICAgICAgICAgICAgIFwiYXR0clwiOiB7IFwic3R5bGVcIjogXCJ3aWR0aDogMWV4O1wiIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBnZXRTaXplRnJvbVN0eWxlV2lkdGgoZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gZ2V0U2l6ZUZyb21TdHlsZVdpZHRoKGVsOiBIVE1MUGFyYWdyYXBoRWxlbWVudCkge1xuXG4gICAgICAgICAgICBjb25zdCBERUZBVUxUX1NJWkUgPSAxNjtcbiAgICAgICAgICAgIGlmKHBhcmVudEVsZW1lbnQgPT09IG51bGwgfHxcbiAgICAgICAgICAgICAgICBwYXJlbnRFbGVtZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSFRNTFNpemluZyh0aGlzLnNpemVWYWx1ZSAqIERFRkFVTFRfU0laRSwgXCJweFwiKTtcbiAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICAgICAgbGV0IGV4VG9QeFJlc3VsdCA9IHRoaXMuc2l6ZVZhbHVlICogZWwuY2xpZW50V2lkdGg7XG4gICAgICAgICAgICBpZihlbC5jbGllbnRXaWR0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGV4VG9QeFJlc3VsdCA9IHRoaXMuc2l6ZVZhbHVlICogREVGQVVMVF9TSVpFO1xuICAgICAgICAgICAgfSBcblxuICAgICAgICAgICAgcGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZChlbCk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEhUTUxTaXppbmcoZXhUb1B4UmVzdWx0LCBcInB4XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gZ2V0Rm9udFNpemVGcm9tRWwoKSB7XG5cbiAgICAgICAgICAgIGNvbnN0IERFRkFVTFRfU0laRSA9IDE2O1xuICAgICAgICAgICAgbGV0IGZvbnRTaXplID0gREVGQVVMVF9TSVpFO1xuICAgICAgICAgICAgbGV0IGVtVG9QeFJlc3VsdCA9IGZvbnRTaXplICogdGhpcy5zaXplVmFsdWU7XG5cbiAgICAgICAgICAgIGlmKHBhcmVudEVsZW1lbnQgPT09IG51bGwgfHxcbiAgICAgICAgICAgICAgIHBhcmVudEVsZW1lbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSFRNTFNpemluZyhlbVRvUHhSZXN1bHQsIFwicHhcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBzaXppbmcgPSBIVE1MU2l6aW5nLnBhcnNlVG9TaXppbmcocGFyZW50RWxlbWVudC5nZXRDc3NQcm9wZXJ0eVZhbHVlKFwiZm9udC1zaXplXCIpKTtcbiAgICAgICAgICAgIGlmIChzaXppbmcgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBmb250U2l6ZSA9IHNpemluZy5zaXplVmFsdWU7XG4gICAgICAgICAgICAgICAgZW1Ub1B4UmVzdWx0ID0gZm9udFNpemUgKiB0aGlzLnNpemVWYWx1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG5ldyBIVE1MU2l6aW5nKGVtVG9QeFJlc3VsdCwgXCJweFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGhhbmRsZVZpZXdwb3J0U2l6aW5nKCkge1xuXG4gICAgICAgICAgICBsZXQgc2NhbGUgPSB0aGlzLnNpemVWYWx1ZSAvIDEwMDtcbiAgICAgICAgICAgIGlmKHBhcmVudEVsZW1lbnQgPT09IG51bGwgfHwgcGFyZW50RWxlbWVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiRm91bmQgdW5kZWZpbmVkIHJvb3QgZWxlbWVudC4gVXNpbmcgZGVmYXVsdCBjbGllbnQgc2l6ZS4gUmVzdWx0IG1heSBub3QgYXBwZWFyIGFzIGludGVuZGVkLlwiKTtcbiAgICAgICAgICAgICAgICBsZXQgZGVmYXVsdFNpemluZyA9IHNjYWxlICogMTIwMDtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEhUTUxTaXppbmcoZGVmYXVsdFNpemluZywgXCJweFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHZpZXdXaWR0aCA9IHBhcmVudEVsZW1lbnQuY2xpZW50V2lkdGg7XG4gICAgICAgICAgICBsZXQgdmlld0hlaWdodCA9IHBhcmVudEVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICAgICAgICAgICAgc3dpdGNoKHRoaXMuc2l6ZVVuaXRzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcInZ3XCI6XG4gICAgICAgICAgICAgICAgICAgIGxldCB3VG9QeFJlc3VsdCA9IHNjYWxlICogdmlld1dpZHRoO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEhUTUxTaXppbmcod1RvUHhSZXN1bHQsIFwicHhcIik7XG4gICAgICAgICAgICAgICAgY2FzZSBcInZoXCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcIiVcIjpcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhUb1B4UmVzdWx0ID0gc2NhbGUgKiB2aWV3SGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEhUTUxTaXppbmcoaFRvUHhSZXN1bHQsIFwicHhcIik7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlKCk6IEhUTUxTaXppbmcge1xuICAgICAgICByZXR1cm4gbmV3IEhUTUxTaXppbmcoMCwgXCJweFwiKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIHBhcnNlVG9TaXppbmcoc2l6aW5nVGV4dDogc3RyaW5nKTogSFRNTFNpemluZyB8IG51bGwge1xuXG4gICAgICAgIGlmKHNpemluZ1RleHQgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHVuaXREYXRhID0gSFRNTFNpemluZy5nZXRMZW5ndGhVbml0KHNpemluZ1RleHQpO1xuICAgICAgICBpZih1bml0RGF0YS5pc1ZhbGlkID09PSB0cnVlKSB7XG5cbiAgICAgICAgICAgIGxldCB1bml0czogc3RyaW5nID0gdW5pdERhdGEudW5pdFN0clxuICAgICAgICAgICAgbGV0IHNpemVUZXh0OiBzdHJpbmcgPSBzaXppbmdUZXh0LnJlcGxhY2UodW5pdHMsIFwiXCIpLnRyaW0oKTtcbiAgICAgICAgICAgIGxldCBzaXplOiBudW1iZXIgPSBwYXJzZUludChzaXplVGV4dCk7XG4gICAgICAgICAgICBpZihpc05hTihzaXplKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aChzaXplKS5zZXRVbml0cyh1bml0cyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyAgZ2V0TGVuZ3RoVW5pdChsZW5ndGhTdHI6IHN0cmluZyk6IHsgaXNWYWxpZDogYm9vbGVhbiwgdW5pdFN0cjogc3RyaW5nIH0ge1xuXG4gICAgICAgIGxldCBsYXN0Q2hhciA9IGxlbmd0aFN0ci5zbGljZShsZW5ndGhTdHIubGVuZ3RoIC0gMSk7XG4gICAgICAgIGxldCBsYXN0VHdvQ2hhcnMgPSBsZW5ndGhTdHIuc2xpY2UobGVuZ3RoU3RyLmxlbmd0aCAtIDIpO1xuICAgIFxuICAgICAgICBsZXQgdW5pdFN0ciA9IFwiXCJcbiAgICAgICAgbGV0IGlzVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgaWYobGFzdENoYXIgPT09IFwiJVwiKSB7XG4gICAgICAgICAgICB1bml0U3RyID0gbGFzdENoYXI7XG4gICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKGxhc3RUd29DaGFycyA9PT0gXCJjbVwiIHx8XG4gICAgICAgICAgICAgICAgbGFzdFR3b0NoYXJzID09PSBcIm1tXCIgfHxcbiAgICAgICAgICAgICAgICBsYXN0VHdvQ2hhcnMgPT09IFwiaW5cIiB8fFxuICAgICAgICAgICAgICAgIGxhc3RUd29DaGFycyA9PT0gXCJweFwiIHx8XG4gICAgICAgICAgICAgICAgbGFzdFR3b0NoYXJzID09PSBcInB0XCIgfHxcbiAgICAgICAgICAgICAgICBsYXN0VHdvQ2hhcnMgPT09IFwicGNcIiB8fFxuICAgICAgICAgICAgICAgIGxhc3RUd29DaGFycyA9PT0gXCJlbVwiIHx8XG4gICAgICAgICAgICAgICAgbGFzdFR3b0NoYXJzID09PSBcImV4XCIgfHxcbiAgICAgICAgICAgICAgICBsYXN0VHdvQ2hhcnMgPT09IFwiY2hcIiB8fFxuICAgICAgICAgICAgICAgIGxhc3RUd29DaGFycyA9PT0gXCJ2d1wiIHx8XG4gICAgICAgICAgICAgICAgbGFzdFR3b0NoYXJzID09PSBcInZoXCIgKSB7XG4gICAgICAgICAgICB1bml0U3RyID0gbGFzdFR3b0NoYXJzO1xuICAgICAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogaXNWYWxpZCwgdW5pdFN0cjogdW5pdFN0ciB9XG4gICAgfVxufVxuXG5jb25zdCBBTExfTU9VU0VfU1RBVEVTID0gW1xuICAgIFwidXBcIixcbiAgICBcImRvd25cIiwgXG5dIGFzIGNvbnN0O1xudHlwZSBNb3VzZVN0YXRlVHVwbGUgPSB0eXBlb2YgQUxMX01PVVNFX1NUQVRFUztcbmV4cG9ydCB0eXBlIE1vdXNlU3RhdGUgPSBNb3VzZVN0YXRlVHVwbGVbbnVtYmVyXTtcbmV4cG9ydCBsZXQgbW91c2VTdGF0ZTogTW91c2VTdGF0ZSA9IFwidXBcIjsgXG5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsICgpID0+IHtcblx0bW91c2VTdGF0ZSA9IFwiZG93blwiXG59KVxuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgKCkgPT4ge1xuXHRtb3VzZVN0YXRlID0gXCJ1cFwiXG59KVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXJ0VGFnUmVnZXhNYXRjaCB7XG4gICAgZm91bmQ6IGJvb2xlYW47XG4gICAgc3RhcnRQb3NpdGlvbjogbnVtYmVyO1xuICAgIGVuZFBvc2l0aW9uOiBudW1iZXI7XG4gICAgbWF0Y2hMZW5ndGg6IG51bWJlcjtcbiAgICByZWdpb25UeXBlOiBSZWdpb25UeXBlO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRTdGFydFJlZ2lvbkRhdGEoKTogU3RhcnRUYWdSZWdleE1hdGNoIHtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGZvdW5kOiBmYWxzZSxcbiAgICAgICAgc3RhcnRQb3NpdGlvbjogLTEsXG4gICAgICAgIGVuZFBvc2l0aW9uOiAtMSxcbiAgICAgICAgbWF0Y2hMZW5ndGg6IDAsXG4gICAgICAgIHJlZ2lvblR5cGU6IFwiQ09ERUJMT0NLXCJcbiAgICB9XG59XG5cbmNvbnN0IEFMTF9SRUdJT05fVFlQRVM9IFtcbiAgICBcIkNPREVCTE9DS1wiLFxuICAgIFwiT1JJR0lOQUxcIiwgXG4gICAgXCJQQURPQ1wiXG5dIGFzIGNvbnN0O1xudHlwZSBSZWdpb25UeXBlVHVwbGUgPSB0eXBlb2YgQUxMX1JFR0lPTl9UWVBFUztcbmV4cG9ydCB0eXBlIFJlZ2lvblR5cGUgPSBSZWdpb25UeXBlVHVwbGVbbnVtYmVyXTsiLCIvKlxuICogRmlsZW5hbWU6IG11bHRpLWNvbHVtbi1tYXJrZG93bi9zcmMvcmVnaW9uU2V0dGluZ3MudHNcbiAqIENyZWF0ZWQgRGF0ZTogVHVlc2RheSwgRmVicnVhcnkgMXN0IDIwMjIsIDEyOjIzOjUzIHBtXG4gKiBBdXRob3I6IENhbWVyb24gUm9iaW5zb25cbiAqIFxuICogQ29weXJpZ2h0IChjKSAyMDIyIENhbWVyb24gUm9iaW5zb25cbiAqL1xuXG5pbXBvcnQgeyBIVE1MU2l6aW5nIH0gZnJvbSBcIi4vdXRpbGl0aWVzL2ludGVyZmFjZXNcIlxuXG5leHBvcnQgZW51bSBCb3JkZXJPcHRpb24ge1xuICAgIGVuYWJsZWQsXG4gICAgb24sXG4gICAgdHJ1ZSxcbiAgICBkaXNhYmxlZCxcbiAgICBvZmYsXG4gICAgZmFsc2Vcbn1cblxuZXhwb3J0IGVudW0gU2hhZG93T3B0aW9uIHtcbiAgICBlbmFibGVkLFxuICAgIG9uLFxuICAgIHRydWUsXG4gICAgZGlzYWJsZWQsXG4gICAgb2ZmLFxuICAgIGZhbHNlXG59XG5cbmV4cG9ydCBlbnVtIFRhYmxlQWxpZ25PcHRpb24ge1xuICAgIGVuYWJsZWQsXG4gICAgb24sXG4gICAgdHJ1ZSxcbiAgICBkaXNhYmxlZCxcbiAgICBvZmYsXG4gICAgZmFsc2Vcbn1cblxuY29uc3QgQUxMX0xBWU9VVFMgPSBbXG4gICAgXCJzdGFuZGFyZFwiLFxuICAgIFwibGVmdFwiLCBcbiAgICBcImZpcnN0XCIsIFxuICAgIFwiY2VudGVyXCIsXG4gICAgXCJtaWRkbGVcIixcbiAgICBcInNlY29uZFwiLFxuICAgIFwicmlnaHRcIixcbiAgICBcInRoaXJkXCIsXG4gICAgXCJsYXN0XCJcbl0gYXMgY29uc3Q7XG50eXBlIENvbHVtbkxheW91dFR1cGxlID0gdHlwZW9mIEFMTF9MQVlPVVRTO1xuZXhwb3J0IHR5cGUgQ29sdW1uTGF5b3V0ID0gQ29sdW1uTGF5b3V0VHVwbGVbbnVtYmVyXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ29sdW1uTGF5b3V0KHZhbHVlOiBzdHJpbmcpOiB2YWx1ZSBpcyBDb2x1bW5MYXlvdXQge1xuICByZXR1cm4gQUxMX0xBWU9VVFMuaW5jbHVkZXModmFsdWUudG9Mb3dlckNhc2UoKSBhcyBDb2x1bW5MYXlvdXQpXG59XG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVDb2x1bW5MYXlvdXQodmFsdWU6IHN0cmluZyB8IENvbHVtbkxheW91dCk6IENvbHVtbkxheW91dCB7XG4gICAgcmV0dXJuICh2YWx1ZS50b0xvd2VyQ2FzZSgpIGFzIENvbHVtbkxheW91dClcbn1cblxuY29uc3QgQUxMX1NJTkdMRV9DT0xVTU5fU0laRVMgPSBbXG4gICAgXCJzbWFsbFwiLFxuICAgIFwibWVkaXVtXCIsXG4gICAgXCJsYXJnZVwiLFxuICAgIFwiZnVsbFwiXG5dXG50eXBlIFNpbmdsZUNvbHVtblNpemVUdXBsZSA9IHR5cGVvZiBBTExfU0lOR0xFX0NPTFVNTl9TSVpFUztcbmV4cG9ydCB0eXBlIFNpbmdsZUNvbHVtblNpemUgPSBTaW5nbGVDb2x1bW5TaXplVHVwbGVbbnVtYmVyXTtcbmV4cG9ydCBmdW5jdGlvbiBpc1NpbmdsZUNvbHVtblNpemUodmFsdWU6IHN0cmluZyk6IHZhbHVlIGlzIFNpbmdsZUNvbHVtblNpemUge1xuICAgIHJldHVybiBBTExfU0lOR0xFX0NPTFVNTl9TSVpFUy5pbmNsdWRlcyh2YWx1ZS50b0xvd2VyQ2FzZSgpIGFzIFNpbmdsZUNvbHVtblNpemUpXG59XG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVTaW5nbGVDb2x1bW5TaXplKHZhbHVlOiBzdHJpbmcgfCBTaW5nbGVDb2x1bW5TaXplKTogU2luZ2xlQ29sdW1uU2l6ZSB7XG4gICAgcmV0dXJuICh2YWx1ZS50b0xvd2VyQ2FzZSgpIGFzIFNpbmdsZUNvbHVtblNpemUpXG59XG5cbmV4cG9ydCBlbnVtIENvbnRlbnRPdmVyZmxvd1R5cGUge1xuICAgIHNjcm9sbCxcbiAgICBoaWRkZW5cbn1cblxuZXhwb3J0IGVudW0gQWxpZ25tZW50VHlwZSB7XG4gICAgbGVmdCxcbiAgICBjZW50ZXIsXG4gICAgcmlnaHRcbn1cblxuZXhwb3J0IGVudW0gVGFibGVBbGlnbm1lbnQge1xuICAgIHVzZVNldHRpbmdzRGVmYXVsdCxcbiAgICBhbGlnbixcbiAgICBub0FsaWduXG59XG5cbmV4cG9ydCB0eXBlIE11bHRpQ29sdW1uU2V0dGluZ3MgPSB7XG4gICAgY29sdW1uSUQ6IHN0cmluZyxcbiAgICBudW1iZXJPZkNvbHVtbnM6IG51bWJlcixcbiAgICBkcmF3Qm9yZGVyOiBib29sZWFuW10sXG4gICAgZHJhd1NoYWRvdzogYm9vbGVhbixcbiAgICBhdXRvTGF5b3V0OiBib29sZWFuXG4gICAgY29sdW1uU2l6ZTogU2luZ2xlQ29sdW1uU2l6ZSB8IENvbHVtbkxheW91dCB8IEhUTUxTaXppbmdbXSxcbiAgICBjb2x1bW5Qb3NpdGlvbjogQ29sdW1uTGF5b3V0LFxuICAgIGNvbHVtblNwYWNpbmc6IHN0cmluZ1tdLFxuICAgIGNvbnRlbnRPdmVyZmxvdzogQ29udGVudE92ZXJmbG93VHlwZVtdLFxuICAgIGFsaWdubWVudDogQWxpZ25tZW50VHlwZVtdLFxuICAgIGNvbHVtbkhlaWdodDogSFRNTFNpemluZyB8IG51bGwsXG4gICAgZnVsbERvY1JlZmxvdzogYm9vbGVhbixcbiAgICBhbGlnblRhYmxlc1RvQWxpZ25tZW50OiBUYWJsZUFsaWdubWVudFxufVxuZXhwb3J0IGZ1bmN0aW9uIE1DU2V0dGluZ3NfaXNFcXVhbChzZXR0aW5nc0E6IE11bHRpQ29sdW1uU2V0dGluZ3MsIHNldHRpbmdzQjogTXVsdGlDb2x1bW5TZXR0aW5ncyk6IGJvb2xlYW4ge1xuXG4gICAgaWYoc2V0dGluZ3NBPy5jb2x1bW5JRCAhPT0gc2V0dGluZ3NCPy5jb2x1bW5JRCkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgaWYoc2V0dGluZ3NBPy5udW1iZXJPZkNvbHVtbnMgIT09IHNldHRpbmdzQj8ubnVtYmVyT2ZDb2x1bW5zKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBpZihKU09OLnN0cmluZ2lmeShzZXR0aW5nc0E/LmRyYXdCb3JkZXIpICE9PSBKU09OLnN0cmluZ2lmeShzZXR0aW5nc0I/LmRyYXdCb3JkZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBpZihzZXR0aW5nc0E/LmRyYXdTaGFkb3cgIT09IHNldHRpbmdzQj8uZHJhd1NoYWRvdykge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgaWYoc2V0dGluZ3NBPy5hdXRvTGF5b3V0ICE9PSBzZXR0aW5nc0I/LmF1dG9MYXlvdXQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGlmKEpTT04uc3RyaW5naWZ5KHNldHRpbmdzQT8uY29sdW1uU2l6ZSkgIT09IEpTT04uc3RyaW5naWZ5KHNldHRpbmdzQj8uY29sdW1uU2l6ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGlmKHNldHRpbmdzQT8uY29sdW1uUG9zaXRpb24gIT09IHNldHRpbmdzQj8uY29sdW1uUG9zaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGlmKEpTT04uc3RyaW5naWZ5KHNldHRpbmdzQT8uY29sdW1uU3BhY2luZykgIT09IEpTT04uc3RyaW5naWZ5KHNldHRpbmdzQj8uY29sdW1uU3BhY2luZykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGlmKEpTT04uc3RyaW5naWZ5KHNldHRpbmdzQT8uY29udGVudE92ZXJmbG93KSAhPT0gSlNPTi5zdHJpbmdpZnkoc2V0dGluZ3NCPy5jb250ZW50T3ZlcmZsb3cpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBpZihKU09OLnN0cmluZ2lmeShzZXR0aW5nc0E/LmFsaWdubWVudCkgIT09IEpTT04uc3RyaW5naWZ5KHNldHRpbmdzQj8uYWxpZ25tZW50KSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgaWYoc2V0dGluZ3NBPy5jb2x1bW5IZWlnaHQgIT09IHNldHRpbmdzQj8uY29sdW1uSGVpZ2h0KSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBpZihzZXR0aW5nc0E/LmZ1bGxEb2NSZWZsb3cgIT09IHNldHRpbmdzQj8uZnVsbERvY1JlZmxvdykge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgaWYoc2V0dGluZ3NBPy5hbGlnblRhYmxlc1RvQWxpZ25tZW50ICE9PSBzZXR0aW5nc0I/LmFsaWduVGFibGVzVG9BbGlnbm1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWZhdWx0TXVsdGlDb2x1bW5TZXR0aW5ncygpOiBNdWx0aUNvbHVtblNldHRpbmdzIHtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGNvbHVtbklEOiBcIlwiLFxuICAgICAgICBudW1iZXJPZkNvbHVtbnM6IDIsXG4gICAgICAgIGRyYXdCb3JkZXI6IFt0cnVlXSxcbiAgICAgICAgZHJhd1NoYWRvdzogdHJ1ZSxcbiAgICAgICAgYXV0b0xheW91dDogZmFsc2UsXG4gICAgICAgIGNvbHVtblNpemU6IFwic3RhbmRhcmRcIixcbiAgICAgICAgY29sdW1uUG9zaXRpb246IFwic3RhbmRhcmRcIixcbiAgICAgICAgY29sdW1uU3BhY2luZzogW1wiXCJdLFxuICAgICAgICBjb250ZW50T3ZlcmZsb3c6IFtDb250ZW50T3ZlcmZsb3dUeXBlLnNjcm9sbF0sXG4gICAgICAgIGFsaWdubWVudDogW0FsaWdubWVudFR5cGUubGVmdF0sXG4gICAgICAgIGNvbHVtbkhlaWdodDogbnVsbCxcbiAgICAgICAgZnVsbERvY1JlZmxvdzogZmFsc2UsXG4gICAgICAgIGFsaWduVGFibGVzVG9BbGlnbm1lbnQ6IFRhYmxlQWxpZ25tZW50LnVzZVNldHRpbmdzRGVmYXVsdFxuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNob3VsZERyYXdDb2x1bW5Cb3JkZXIoaW5kZXg6IG51bWJlciwgc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MpOiBib29sZWFuIHtcblxuICAgIGlmKHNldHRpbmdzLmRyYXdCb3JkZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBnZXRJbmRleGVkQ2xhbXBlZEFycmF5VmFsdWUoaW5kZXgsIHNldHRpbmdzLmRyYXdCb3JkZXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29sdW1uT3ZlcmZsb3dTdGF0ZShpbmRleDogbnVtYmVyLCBzZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncyk6IENvbnRlbnRPdmVyZmxvd1R5cGUge1xuXG4gICAgaWYoc2V0dGluZ3MuY29udGVudE92ZXJmbG93Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gQ29udGVudE92ZXJmbG93VHlwZS5zY3JvbGxcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0SW5kZXhlZENsYW1wZWRBcnJheVZhbHVlKGluZGV4LCBzZXR0aW5ncy5jb250ZW50T3ZlcmZsb3cpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29sdW1uQWxpZ25tZW50U3RhdGUoaW5kZXg6IG51bWJlciwgc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MpOiBBbGlnbm1lbnRUeXBlIHtcblxuICAgIGlmKHNldHRpbmdzLmFsaWdubWVudC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEFsaWdubWVudFR5cGUubGVmdFxuICAgIH1cblxuICAgIHJldHVybiBnZXRJbmRleGVkQ2xhbXBlZEFycmF5VmFsdWUoaW5kZXgsIHNldHRpbmdzLmFsaWdubWVudClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbHVtblNwYWNpbmdTdGF0ZShpbmRleDogbnVtYmVyLCBzZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncyk6IHN0cmluZyB7XG5cbiAgICBpZihzZXR0aW5ncy5jb2x1bW5TcGFjaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG5cbiAgICByZXR1cm4gYG1hcmdpbi1pbmxpbmU6ICR7Z2V0SW5kZXhlZENsYW1wZWRBcnJheVZhbHVlKGluZGV4LCBzZXR0aW5ncy5jb2x1bW5TcGFjaW5nKX07YDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEluZGV4ZWRDbGFtcGVkQXJyYXlWYWx1ZTxUPihpbmRleDogbnVtYmVyLCBhcnI6IFRbXSkge1xuXG4gICAgaWYoYXJyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyhcIkVycm9yIGdldHRpbmcgdmFsdWUgZnJvbSBlbXB0eSBhcnJheS5cIilcbiAgICB9XG5cbiAgICBpZihpbmRleCA8IDApIHtcbiAgICAgICAgcmV0dXJuIGFyclswXTtcbiAgICB9XG5cbiAgICBpZihpbmRleCA8IGFyci5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGFycltpbmRleF07XG4gICAgfVxuXG4gICAgcmV0dXJuIGFyci5sYXN0KCk7XG59IiwiLyoqXG4gKiBGaWxlOiAvc3JjL3V0aWxpdGllcy9zZXR0aW5nc1BhcnNlci50cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gKiBDcmVhdGVkIERhdGU6IEZyaWRheSwgSnVuZSAzcmQgMjAyMiwgODoxNiBwbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gKiBBdXRob3I6IENhbWVyb24gUm9iaW5zb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjIgQ2FtZXJvbiBSb2JpbnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gKi9cblxuaW1wb3J0IHsgSFRNTFNpemluZyB9IGZyb20gXCJzcmMvdXRpbGl0aWVzL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IE11bHRpQ29sdW1uU2V0dGluZ3MsIENvbHVtbkxheW91dCwgQm9yZGVyT3B0aW9uLCBTaGFkb3dPcHRpb24sIGdldERlZmF1bHRNdWx0aUNvbHVtblNldHRpbmdzLCBTaW5nbGVDb2x1bW5TaXplLCBDb250ZW50T3ZlcmZsb3dUeXBlLCBBbGlnbm1lbnRUeXBlLCBpc0NvbHVtbkxheW91dCwgdmFsaWRhdGVDb2x1bW5MYXlvdXQsIFRhYmxlQWxpZ25PcHRpb24sIFRhYmxlQWxpZ25tZW50IH0gZnJvbSBcIi4uL3JlZ2lvblNldHRpbmdzXCI7XG5cbi8qKlxuICogSGVyZSB3ZSBkZWZpbmUgYWxsIG9mIHRoZSB2YWxpZCBzZXR0aW5ncyBzdHJpbmdzIHRoYXQgdGhlIHVzZXIgY2FuIGVudGVyIGZvciBlYWNoIHNldHRpbmcgdHlwZS5cbiAqIFRoZSBzdHJpbmdzIGFyZSB0aGVuIG1hcHBlZCB0d2ljZSwgZmlyc3QgdG8gYSB2YWxpZCByZWdleCBzdHJpbmcgdGhhdCBzZWFyY2hlcyBmb3IgdGhlIHNldHRpbmdcbiAqIG5hbWUsIGlnbm9yaW5nIGFsbCBleHRyYSBzcGFjZXMgYW5kIGxldHRlciBjYXNlLCBhbmQgdGhlbiBtYXBlZCB0byBhIFJlZ0V4IG9iamVjdCB0byBiZSB1c2VkIFxuICogd2hlbiBwYXJzaW5nLlxuICovXG5jb25zdCBDT0xfUE9TSVRJT05fT1BUSU9OX1NUUlM6IHN0cmluZ1tdID0gW1xuICAgIFwiY29sdW1uIHBvc2l0aW9uXCIsXG4gICAgXCJjb2wgcG9zaXRpb25cIixcbiAgICBcImNvbHVtbiBsb2NhdGlvblwiLFxuICAgIFwiY29sIGxvY2F0aW9uXCIsXG4gICAgXCJzaW5nbGUgY29sdW1uIGxvY2F0aW9uXCIsXG4gICAgXCJzaW5nbGUgY29sdW1uIHBvc2l0aW9uXCIsXG5dO1xuY29uc3QgQ09MX1BPU0lUSU9OX1JFR0VYX0FSUjogUmVnRXhwW10gPSBDT0xfUE9TSVRJT05fT1BUSU9OX1NUUlMubWFwKGNvbnZlcnRTdHJpbmdUb1NldHRpbmdzUmVnZXgpLm1hcCgodmFsdWUpID0+IHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cCh2YWx1ZSwgXCJpXCIpO1xufSk7XG5cbmNvbnN0IENPTF9TSVpFX09QVElPTl9TVFJTOiBzdHJpbmdbXSA9IFtcbiAgICBcImNvbHVtbiBzaXplXCIsXG4gICAgXCJjb2x1bW4gd2lkdGhcIixcbiAgICBcImNvbCBzaXplXCIsXG4gICAgXCJjb2wgd2lkdGhcIixcbiAgICBcInNpbmdsZSBjb2x1bW4gc2l6ZVwiLFxuICAgIFwic2luZ2xlIGNvbCBzaXplXCIsXG4gICAgXCJzaW5nbGUgY29sdW1uIHdpZHRoXCIsXG4gICAgXCJzaW5nbGUgY29sIHdpZHRoXCIsXG4gICAgXCJsYXJnZXN0IGNvbHVtblwiXG5dO1xuY29uc3QgQ09MX1NJWkVfT1BUSU9OX1JFR0VYX0FSUjogUmVnRXhwW10gPSBDT0xfU0laRV9PUFRJT05fU1RSUy5tYXAoY29udmVydFN0cmluZ1RvU2V0dGluZ3NSZWdleCkubWFwKCh2YWx1ZSkgPT4ge1xuICAgIHJldHVybiBuZXcgUmVnRXhwKHZhbHVlLCBcImlcIik7XG59KTtcblxuY29uc3QgTlVNQkVSX09GX0NPTFVNTlNfU1RSUyA9IFtcbiAgICBcIm51bWJlciBvZiBjb2x1bW5zXCIsXG4gICAgXCJudW0gb2YgY29sc1wiLFxuICAgIFwiY29sIGNvdW50XCIsXG4gICAgXCJjb2x1bW4gY291bnRcIlxuXVxuY29uc3QgTlVNQkVSX09GX0NPTFVNTlNfUkVHRVhfQVJSOiBSZWdFeHBbXSA9IE5VTUJFUl9PRl9DT0xVTU5TX1NUUlMubWFwKGNvbnZlcnRTdHJpbmdUb1NldHRpbmdzUmVnZXgpLm1hcCgodmFsdWUpID0+IHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cCh2YWx1ZSwgXCJpXCIpO1xufSk7XG5cbmNvbnN0IERSQVdfQk9SREVSX1NUUlMgPSBbXG4gICAgXCJib3JkZXJcIlxuXVxuY29uc3QgRFJBV19CT1JERVJfUkVHRVhfQVJSOiBSZWdFeHBbXSA9IERSQVdfQk9SREVSX1NUUlMubWFwKGNvbnZlcnRTdHJpbmdUb1NldHRpbmdzUmVnZXgpLm1hcCgodmFsdWUpID0+IHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cCh2YWx1ZSwgXCJpXCIpO1xufSk7XG5cbmNvbnN0IERSQVdfU0hBRE9XX1NUUlMgPSBbXG4gICAgXCJzaGFkb3dcIlxuXVxuY29uc3QgRFJBV19TSEFET1dfUkVHRVhfQVJSOiBSZWdFeHBbXSA9IERSQVdfU0hBRE9XX1NUUlMubWFwKGNvbnZlcnRTdHJpbmdUb1NldHRpbmdzUmVnZXgpLm1hcCgodmFsdWUpID0+IHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cCh2YWx1ZSwgXCJpXCIpO1xufSk7XG5cbmNvbnN0IEFVVE9fTEFZT1VUX1NFVFRJTkdfU1RSUyA9IFtcbiAgICBcImF1dG8gbGF5b3V0XCIsXG4gICAgXCJmbHVpZCBkaXZcIixcbiAgICBcImZsdWlkIGRpdnNcIixcbiAgICBcImZsdWlkIGNvbHVtbnNcIixcbiAgICBcImZsdWlkIGNvbHNcIixcbiAgICBcImZsdWlkIGNvbFwiXG5dXG5jb25zdCBBVVRPX0xBWU9VVF9SRUdFWF9BUlI6IFJlZ0V4cFtdID0gQVVUT19MQVlPVVRfU0VUVElOR19TVFJTLm1hcChjb252ZXJ0U3RyaW5nVG9TZXR0aW5nc1JlZ2V4KS5tYXAoKHZhbHVlKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAodmFsdWUsIFwiaVwiKTtcbn0pO1xuXG5jb25zdCBDT0xVTU5fU1BBQ0lOR19SRUdFWF9BUlI6IFJlZ0V4cFtdID0gW1xuICAgIFwiY29sdW1uIHNwYWNpbmdcIixcbiAgICBcImNvbHVtbiBnYXBcIixcbiAgICBcImNvbHVtbiBzZXBcIlxuXS5tYXAoKHZhbHVlKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoY29udmVydFN0cmluZ1RvU2V0dGluZ3NSZWdleCh2YWx1ZSksIFwiaVwiKTtcbn0pO1xuXG5jb25zdCBDT0xVTU5fSEVJR0hUX1JFR0VYX0FSUjogUmVnRXhwW10gPSBbXG4gICAgXCJjb2x1bW4gaGVpZ2h0XCIsXG4gICAgXCJjb2wgaGVpZ2h0XCIsXG4gICAgXCJjb2x1bW4gbWF4IGhlaWdodFwiLFxuICAgIFwiY29sIG1heCBoZWlnaHRcIixcbiAgICBcIm1heCBjb2x1bW4gaGVpZ2h0XCIsXG4gICAgXCJtYXggY29sIGhlaWdodFwiXG5dLm1hcCgodmFsdWUpID0+IHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChjb252ZXJ0U3RyaW5nVG9TZXR0aW5nc1JlZ2V4KHZhbHVlKSwgXCJpXCIpO1xufSk7XG5cbmNvbnN0IENPTlRFTlRfT1ZFUkZMT1dfUkVHRVhfQVJSOiBSZWdFeHBbXSA9IFtcbiAgICBcIm92ZXJmbG93XCIsXG4gICAgXCJjb250ZW50IG92ZXJmbG93XCJcbl0ubWFwKCh2YWx1ZSkgPT4ge1xuICAgIHJldHVybiBuZXcgUmVnRXhwKGNvbnZlcnRTdHJpbmdUb1NldHRpbmdzUmVnZXgodmFsdWUpLCBcImlcIilcbn0pO1xuXG5jb25zdCBBTElHTk1FTlRfUkVHRVhfQVJSOiBSZWdFeHBbXSA9IFtcbiAgICBcImFsaWdubWVudFwiLFxuICAgIFwiY29udGVudCBhbGlnbm1lbnRcIixcbiAgICBcImFsaWduXCIsXG4gICAgXCJjb250ZW50IGFsaWduXCIsXG4gICAgXCJhbGlnbiBjb250ZW50XCIsXG4gICAgXCJ0ZXh0IGFsaWduXCIsXG4gICAgXCJhbGlnbiB0ZXh0XCIsXG4gICAgXCJUZXh0IEFsaWdubWVudFwiXG5dLm1hcCgodmFsdWUpID0+IHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChjb252ZXJ0U3RyaW5nVG9TZXR0aW5nc1JlZ2V4KHZhbHVlKSwgXCJpXCIpO1xufSk7XG5cbmNvbnN0IFRBQkxFX0FMSUdOTUVOVF9SRUdFWF9BUlI6IFJlZ0V4cFtdID0gW1xuICAgIFwiYWxpZ24gdGFibGVzIHRvIHRleHQgYWxpZ25tZW50XCJcbl0ubWFwKCh2YWx1ZSkgPT4ge1xuICAgIHJldHVybiBuZXcgUmVnRXhwKGNvbnZlcnRTdHJpbmdUb1NldHRpbmdzUmVnZXgodmFsdWUpLCBcImlcIik7XG59KTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHNlYXJjaGVzIHRoZSBzZXR0aW5ncyBzdHJpbmcgdGhyb3VnaCBlYWNoIHJlZ2V4IG9wdGlvbi4gSWYgb25lIG9mIHRoZSByZWdleFxuICogdmFsdWVzIG1hdGNoLCBpdCByZXR1cm5zIHRoZSBmaXJzdCBncm91cCBmb3VuZCBieSB0aGUgcmVnZXguIFRoaXMgaXMgZGVwZW5kZWQgb24gcHJvcGVyXG4gKiByZWdleCBmb3JtYXR0aW5nIHdoaWNoIGlzIGRvbmUgYnkgdGhlIGNvbnZlcnRTdHJpbmdUb1NldHRpbmdzUmVnZXggZnVuY3Rpb24gZGVmaW5lZCBiZWxvdy5cbiAqIFxuICogQHBhcmFtIHNldHRpbmdzU3RyaW5nIFRoZSB2YWx1ZSB0aGF0IG1heSBtYXRjaCBvbmUgb2YgdGhlIHNldHRpbmcgb3B0aW9ucy5cbiAqIEBwYXJhbSB2YWxpZFNldHRpbmdGb3JtYXRSZWdFeCBUaGUgc2V0dGluZ3Mgb3B0aW9ucyB0aHJvdWdoIHdoaWNoIHRvIGNoZWNrIGFsbCBvcHRpb25zLiBJZiBvbmUgb2YgdGhlc2UgcmVnZXggXG4gKiB2YWx1ZXMgbWF0Y2ggb24gdGhlIHN0cmluZyB3ZSBicmVhayBmcm9tIHRoZSBsb29wIHJldHVybmluZyB0aGUgZm91bmQgdmFsdWUuXG4gKiBcbiAqIEByZXR1cm5zIHRoZSB1c2VyIGVudGVyZWQgZGF0YSBpZiB0aGUgc2V0dGluZyBpcyBhIG1hdGNoLCBvciBudWxsIGlmIG5vbiBvZiB0aGUgb3B0aW9ucyBtYXRjaGVkLlxuICovXG5mdW5jdGlvbiBnZXRTZXR0aW5nc0RhdGFGcm9tS2V5cyhzZXR0aW5nc1N0cmluZzogc3RyaW5nLCB2YWxpZFNldHRpbmdGb3JtYXRSZWdFeDogUmVnRXhwW10pOiBzdHJpbmcgfCBudWxsIHtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsaWRTZXR0aW5nRm9ybWF0UmVnRXgubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICBsZXQgcmVnZXhTZWFyY2hEYXRhID0gdmFsaWRTZXR0aW5nRm9ybWF0UmVnRXhbaV0uZXhlYyhzZXR0aW5nc1N0cmluZylcbiAgICAgICAgaWYocmVnZXhTZWFyY2hEYXRhICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVnZXhTZWFyY2hEYXRhWzFdLnRyaW0oKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVNpbmdsZUNvbHVtblNldHRpbmdzKHNldHRpbmdzU3RyOiBzdHJpbmcsIG9yaWdpbmFsU2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MpOiBNdWx0aUNvbHVtblNldHRpbmdzIHtcblxuICAgIG9yaWdpbmFsU2V0dGluZ3MuY29sdW1uU2l6ZSA9IFwibWVkaXVtXCI7XG4gICAgbGV0IHNldHRpbmdzTGluZXMgPSBzZXR0aW5nc1N0ci5zcGxpdChcIlxcblwiKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldHRpbmdzTGluZXMubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICBsZXQgc2V0dGluZ3NMaW5lID0gc2V0dGluZ3NMaW5lc1tpXTtcbiAgICAgICAgbGV0IHNldHRpbmdzRGF0YSA9IGdldFNldHRpbmdzRGF0YUZyb21LZXlzKHNldHRpbmdzTGluZSwgQ09MX1BPU0lUSU9OX1JFR0VYX0FSUik7XG4gICAgICAgIGlmIChzZXR0aW5nc0RhdGEgIT09IG51bGwpIHtcblxuICAgICAgICAgICAgb3JpZ2luYWxTZXR0aW5ncy5jb2x1bW5Qb3NpdGlvbiA9IHBhcnNlRm9yU2luZ2xlQ29sdW1uTG9jYXRpb24oc2V0dGluZ3NEYXRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldHRpbmdzRGF0YSA9IGdldFNldHRpbmdzRGF0YUZyb21LZXlzKHNldHRpbmdzTGluZSwgQ09MX1NJWkVfT1BUSU9OX1JFR0VYX0FSUik7XG4gICAgICAgIGlmIChzZXR0aW5nc0RhdGEgIT09IG51bGwpIHtcblxuICAgICAgICAgICAgb3JpZ2luYWxTZXR0aW5ncy5jb2x1bW5TaXplID0gcGFyc2VGb3JTaW5nbGVDb2x1bW5TaXplKHNldHRpbmdzRGF0YSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvcmlnaW5hbFNldHRpbmdzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDb2x1bW5TZXR0aW5ncyhzZXR0aW5nc1N0cjogc3RyaW5nKTogTXVsdGlDb2x1bW5TZXR0aW5ncyB7XG5cbiAgICBsZXQgcGFyc2VkU2V0dGluZ3MgPSBnZXREZWZhdWx0TXVsdGlDb2x1bW5TZXR0aW5ncygpO1xuXG4gICAgbGV0IHNldHRpbmdzTGluZXMgPSBzZXR0aW5nc1N0ci5zcGxpdChcIlxcblwiKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2V0dGluZ3NMaW5lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgc2V0dGluZ3NMaW5lID0gc2V0dGluZ3NMaW5lc1tpXTtcblxuICAgICAgICBjaGVja1NldHRpbmdJc1JlZ2lvbklEKHNldHRpbmdzTGluZSwgcGFyc2VkU2V0dGluZ3MpO1xuICAgICAgICBjaGVja1NldHRpbmdJc051bWJlck9mQ29sdW1ucyhzZXR0aW5nc0xpbmUsIHBhcnNlZFNldHRpbmdzKTtcbiAgICAgICAgY2hlY2tTZXR0aW5nRGVmaW5lc0NvbHVtblNpemUoc2V0dGluZ3NMaW5lLCBwYXJzZWRTZXR0aW5ncyk7XG4gICAgICAgIGNoZWNrU2V0dGluZ0lzRHJhd0JvcmRlcihzZXR0aW5nc0xpbmUsIHBhcnNlZFNldHRpbmdzKTtcbiAgICAgICAgY2hlY2tTZXR0aW5nSXNEcmF3U2hhZG93KHNldHRpbmdzTGluZSwgcGFyc2VkU2V0dGluZ3MpO1xuICAgICAgICBjaGVja1NldHRpbmdJc0F1dG9MYXlvdXQoc2V0dGluZ3NMaW5lLCBwYXJzZWRTZXR0aW5ncyk7XG4gICAgICAgIGNoZWNrU2V0dGluZ0lzQ29sdW1uU3BhY2luZyhzZXR0aW5nc0xpbmUsIHBhcnNlZFNldHRpbmdzKTtcbiAgICAgICAgY2hlY2tTZXR0aW5nSXNDb250ZW50T3ZlcmZsb3coc2V0dGluZ3NMaW5lLCBwYXJzZWRTZXR0aW5ncyk7XG4gICAgICAgIGNoZWNrU2V0dGluZ0lzQ29sdW1uQWxpZ25tZW50KHNldHRpbmdzTGluZSwgcGFyc2VkU2V0dGluZ3MpO1xuICAgICAgICBjaGVja1NldHRpbmdJc0NvbHVtbkhlaWdodChzZXR0aW5nc0xpbmUsIHBhcnNlZFNldHRpbmdzKTtcbiAgICAgICAgY2hlY2tTZXR0aW5nSXNUYWJsZUFsaWdubWVudChzZXR0aW5nc0xpbmUsIHBhcnNlZFNldHRpbmdzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VkU2V0dGluZ3M7XG59XG5cbmZ1bmN0aW9uIGNoZWNrU2V0dGluZ0lzTnVtYmVyT2ZDb2x1bW5zKHNldHRpbmdzTGluZTogc3RyaW5nLCBwYXJzZWRTZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncykge1xuXG4gICAgbGV0IHNldHRpbmdzRGF0YSA9IGdldFNldHRpbmdzRGF0YUZyb21LZXlzKHNldHRpbmdzTGluZSwgTlVNQkVSX09GX0NPTFVNTlNfUkVHRVhfQVJSKTtcbiAgICBpZiAoc2V0dGluZ3NEYXRhID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgc2V0dGluZ1ZhbHVlcyA9IHBhcnNlRm9yTXVsdGlTZXR0aW5ncyhzZXR0aW5nc0RhdGEpO1xuICAgIHNldHRpbmdzRGF0YSA9IHNldHRpbmdWYWx1ZXNbMF07XG5cbiAgICBsZXQgbnVtT2ZDb2xzID0gcGFyc2VJbnQoc2V0dGluZ3NEYXRhKTtcbiAgICBpZiAoTnVtYmVyLmlzTmFOKG51bU9mQ29scykgPT09IGZhbHNlKSB7XG4gICAgICAgIGlmIChudW1PZkNvbHMgPj0gMSkge1xuICAgICAgICAgICAgcGFyc2VkU2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zID0gbnVtT2ZDb2xzO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjaGVja1NldHRpbmdJc1JlZ2lvbklEKHNldHRpbmdzTGluZTogc3RyaW5nLCBwYXJzZWRTZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncykge1xuICAgIGxldCBzZXR0aW5nc0RhdGEgPSBnZXRTZXR0aW5nc0RhdGFGcm9tS2V5cyhzZXR0aW5nc0xpbmUsIENPREVCTE9DS19SRUdJT05fSURfUkVHRVhfQVJSKTtcbiAgICBpZiAoc2V0dGluZ3NEYXRhID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwYXJzZWRTZXR0aW5ncy5jb2x1bW5JRCA9IHNldHRpbmdzRGF0YTtcbn1cblxuZnVuY3Rpb24gY2hlY2tTZXR0aW5nRGVmaW5lc0NvbHVtblNpemUoc2V0dGluZ3NMaW5lOiBzdHJpbmcsIHBhcnNlZFNldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzKSB7XG5cbiAgICBsZXQgc2V0dGluZ3NEYXRhID0gZ2V0U2V0dGluZ3NEYXRhRnJvbUtleXMoc2V0dGluZ3NMaW5lLCBDT0xfU0laRV9PUFRJT05fUkVHRVhfQVJSKTtcbiAgICBpZiAoc2V0dGluZ3NEYXRhID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgc2V0dGluZ1ZhbHVlcyA9IHBhcnNlRm9yTXVsdGlTZXR0aW5ncyhzZXR0aW5nc0RhdGEpO1xuICAgIGlmKHNldHRpbmdWYWx1ZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIC8vIElmIHRoZXJlIGlzIG9ubHkgMSBpdGVtIHdlIGF0dGVtcHQgdG8gcGFyc2Ugb3V0IGEgbGF5b3V0IHR5cGUuIElmIHdlIGdldCBhIHZhbGlkIGl0ZW0gd2UgXG4gICAgICAgIC8vIHJldHVybiBoZXJlLlxuICAgICAgICBpZiAoaXNDb2x1bW5MYXlvdXQoc2V0dGluZ1ZhbHVlc1swXSkpIHtcbiAgICAgICAgICAgIHBhcnNlZFNldHRpbmdzLmNvbHVtblNpemUgPSB2YWxpZGF0ZUNvbHVtbkxheW91dChzZXR0aW5nVmFsdWVzWzBdKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCB3aWR0aHM6IEhUTUxTaXppbmdbXSA9IFtdXG4gICAgZm9yKGxldCBzZXR0aW5nIG9mIHNldHRpbmdWYWx1ZXMpIHtcblxuICAgICAgICBsZXQgcGFyc2VkID0gSFRNTFNpemluZy5wYXJzZVRvU2l6aW5nKHNldHRpbmcudHJpbSgpKTtcbiAgICAgICAgaWYocGFyc2VkICE9PSBudWxsKSB7XG4gICAgICAgICAgICB3aWR0aHMucHVzaChwYXJzZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgbm9uZSBhcmUgcGFyc2VkIHByb3Blcmx5IHRvIGEgd2lkdGggdGhlbiB3ZSByZXR1cm4gYSBkZWZhdWx0LlxuICAgIGlmKHdpZHRocy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29uc29sZS53YXJuKFwiRXJyb3IgcGFyc2luZyBjb2x1bW4gbGF5b3V0IG9yIHdpZHRoLCBkZWZhdWx0aW5nIHRvIHN0YW5kYXJkIGxheW91dC5cIilcbiAgICAgICAgcGFyc2VkU2V0dGluZ3MuY29sdW1uU2l6ZSA9IFwic3RhbmRhcmRcIjtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIElmIHdlIHBhcnNlZCBzb21lIGxlbmd0aHMgYW5kIHNvbWUgZGlkIG5vdCBwYXJzZSBwcm9wZXJseSwgdGhlIHVzZXIgaGFzIGVpdGhlclxuICAgIC8vIHBvb3JseSBkZWZpbmVkIHRoZWlyIHNldHRpbmdzIG9yIGlzIGF0dGVtcHRpbmcgdG8gYnJlYWsgdXMuIFRha2UgdGhlIGZpcnN0IHZhbGlkIG9wdGlvblxuICAgIC8vIGJldHdlZW4gdGhlIHR3byBhcnJheXMuXG4gICAgaWYod2lkdGhzLmxlbmd0aCAhPT0gc2V0dGluZ1ZhbHVlcy5sZW5ndGgpIHtcblxuICAgICAgICBmb3IobGV0IHNldHRpbmcgb2Ygc2V0dGluZ1ZhbHVlcykge1xuXG4gICAgICAgICAgICBsZXQgdW5pdERhdGEgPSBIVE1MU2l6aW5nLmdldExlbmd0aFVuaXQoc2V0dGluZyk7XG4gICAgICAgICAgICBpZih1bml0RGF0YS5pc1ZhbGlkID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgcGFyc2VkU2V0dGluZ3MuY29sdW1uU2l6ZSA9IHdpZHRocztcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0NvbHVtbkxheW91dChzZXR0aW5nVmFsdWVzWzBdKSkge1xuICAgICAgICAgICAgICAgIHBhcnNlZFNldHRpbmdzLmNvbHVtblNpemUgPSB2YWxpZGF0ZUNvbHVtbkxheW91dChzZXR0aW5nVmFsdWVzWzBdKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwYXJzZWRTZXR0aW5ncy5jb2x1bW5TaXplID0gd2lkdGhzO1xufVxuXG5mdW5jdGlvbiBjaGVja1NldHRpbmdJc0RyYXdCb3JkZXIoc2V0dGluZ3NMaW5lOiBzdHJpbmcsIHBhcnNlZFNldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzKSB7XG5cbiAgICBsZXQgc2V0dGluZ3NEYXRhID0gZ2V0U2V0dGluZ3NEYXRhRnJvbUtleXMoc2V0dGluZ3NMaW5lLCBEUkFXX0JPUkRFUl9SRUdFWF9BUlIpO1xuICAgIGlmIChzZXR0aW5nc0RhdGEgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBib3JkZXJzOiBib29sZWFuW10gPSBbXVxuICAgIGxldCBzZXR0aW5nVmFsdWVzID0gcGFyc2VGb3JNdWx0aVNldHRpbmdzKHNldHRpbmdzRGF0YSk7XG4gICAgZm9yKGxldCBzZXR0aW5nc0RhdGEgb2Ygc2V0dGluZ1ZhbHVlcykge1xuXG4gICAgICAgIGxldCBib3JkZXJTdGF0ZSA9IHRydWU7XG4gICAgICAgIGxldCBpc0JvcmRlckRyYXduOiBCb3JkZXJPcHRpb24gPSAoPGFueT5Cb3JkZXJPcHRpb24pW3NldHRpbmdzRGF0YV07XG4gICAgICAgIGlmIChpc0JvcmRlckRyYXduICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoaXNCb3JkZXJEcmF3bikge1xuICAgICAgICAgICAgICAgIGNhc2UgKEJvcmRlck9wdGlvbi5kaXNhYmxlZCk6XG4gICAgICAgICAgICAgICAgY2FzZSAoQm9yZGVyT3B0aW9uLm9mZik6XG4gICAgICAgICAgICAgICAgY2FzZSAoQm9yZGVyT3B0aW9uLmZhbHNlKTpcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyU3RhdGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGJvcmRlcnMucHVzaChib3JkZXJTdGF0ZSk7XG4gICAgfVxuXG4gICAgcGFyc2VkU2V0dGluZ3MuZHJhd0JvcmRlciA9IGJvcmRlcnM7XG59XG5cbmZ1bmN0aW9uIGNoZWNrU2V0dGluZ0lzRHJhd1NoYWRvdyhzZXR0aW5nc0xpbmU6IHN0cmluZywgcGFyc2VkU2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MpIHtcblxuICAgIGxldCBzZXR0aW5nc0RhdGEgPSBnZXRTZXR0aW5nc0RhdGFGcm9tS2V5cyhzZXR0aW5nc0xpbmUsIERSQVdfU0hBRE9XX1JFR0VYX0FSUik7XG4gICAgaWYgKHNldHRpbmdzRGF0YSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHNldHRpbmdWYWx1ZXMgPSBwYXJzZUZvck11bHRpU2V0dGluZ3Moc2V0dGluZ3NEYXRhKTtcbiAgICBzZXR0aW5nc0RhdGEgPSBzZXR0aW5nVmFsdWVzWzBdO1xuXG4gICAgbGV0IGlzU2hhZG93RHJhd246IFNoYWRvd09wdGlvbiA9ICg8YW55PlNoYWRvd09wdGlvbilbc2V0dGluZ3NEYXRhXTtcbiAgICBpZiAoaXNTaGFkb3dEcmF3biAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHN3aXRjaCAoaXNTaGFkb3dEcmF3bikge1xuICAgICAgICAgICAgY2FzZSAoU2hhZG93T3B0aW9uLmRpc2FibGVkKTpcbiAgICAgICAgICAgIGNhc2UgKFNoYWRvd09wdGlvbi5vZmYpOlxuICAgICAgICAgICAgY2FzZSAoU2hhZG93T3B0aW9uLmZhbHNlKTpcbiAgICAgICAgICAgICAgICBwYXJzZWRTZXR0aW5ncy5kcmF3U2hhZG93ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrU2V0dGluZ0lzQXV0b0xheW91dChzZXR0aW5nc0xpbmU6IHN0cmluZywgcGFyc2VkU2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MpIHtcbiAgICBcbiAgICBsZXQgc2V0dGluZ3NEYXRhID0gZ2V0U2V0dGluZ3NEYXRhRnJvbUtleXMoc2V0dGluZ3NMaW5lLCBBVVRPX0xBWU9VVF9SRUdFWF9BUlIpO1xuICAgIGlmIChzZXR0aW5nc0RhdGEgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBzZXR0aW5nVmFsdWVzID0gcGFyc2VGb3JNdWx0aVNldHRpbmdzKHNldHRpbmdzRGF0YSk7XG4gICAgc2V0dGluZ3NEYXRhID0gc2V0dGluZ1ZhbHVlc1swXTtcblxuXG4gICAgaWYgKHNldHRpbmdzRGF0YSA9PT0gXCJmYWxzZVwiIHx8IFxuICAgICAgICBzZXR0aW5nc0RhdGEgPT09IFwib2ZmXCIgICAgICkge1xuXG4gICAgICAgIHBhcnNlZFNldHRpbmdzLmF1dG9MYXlvdXQgPSBmYWxzZTtcbiAgICB9XG4gICAgcGFyc2VkU2V0dGluZ3MuYXV0b0xheW91dCA9IHRydWU7XG59XG5cbmZ1bmN0aW9uIGNoZWNrU2V0dGluZ0lzQ29sdW1uU3BhY2luZyhzZXR0aW5nc0xpbmU6IHN0cmluZywgcGFyc2VkU2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MpIHtcbiAgICBcbiAgICBsZXQgc2V0dGluZ3NEYXRhID0gZ2V0U2V0dGluZ3NEYXRhRnJvbUtleXMoc2V0dGluZ3NMaW5lLCBDT0xVTU5fU1BBQ0lOR19SRUdFWF9BUlIpO1xuICAgIGlmIChzZXR0aW5nc0RhdGEgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuXG4gICAgbGV0IHNwYWNpbmdzOiBzdHJpbmdbXSA9IFtdXG5cbiAgICBsZXQgc2V0dGluZ1ZhbHVlcyA9IHBhcnNlRm9yTXVsdGlTZXR0aW5ncyhzZXR0aW5nc0RhdGEpO1xuICAgIGZvcihsZXQgc2V0dGluZ3NEYXRhIG9mIHNldHRpbmdWYWx1ZXMpIHtcbiAgICAgICAgXG4gICAgICAgIGxldCBwYXJzZWQgPSBIVE1MU2l6aW5nLnBhcnNlVG9TaXppbmcoc2V0dGluZ3NEYXRhLnRyaW0oKSk7XG4gICAgICAgIGxldCBzcGFjaW5nU3RyID0gXCJcIjtcbiAgICAgICAgaWYgKHBhcnNlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgc3BhY2luZ1N0ciA9IHBhcnNlZC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgIFxuICAgICAgICAgICAgbGV0IG5vVW5pdHNOdW0gPSBwYXJzZUludChzZXR0aW5nc0RhdGEudHJpbSgpKTtcbiAgICAgICAgICAgIGlmIChpc05hTihub1VuaXRzTnVtKSA9PT0gZmFsc2UpIHtcbiAgICBcbiAgICAgICAgICAgICAgICBzcGFjaW5nU3RyID0gYCR7bm9Vbml0c051bX1wdGA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3BhY2luZ3MucHVzaChzcGFjaW5nU3RyKTtcbiAgICB9XG5cbiAgICBwYXJzZWRTZXR0aW5ncy5jb2x1bW5TcGFjaW5nID0gc3BhY2luZ3M7XG59XG5cbmZ1bmN0aW9uIGNoZWNrU2V0dGluZ0lzQ29udGVudE92ZXJmbG93KHNldHRpbmdzTGluZTogc3RyaW5nLCBwYXJzZWRTZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncykge1xuICAgIFxuICAgIGxldCBzZXR0aW5nc0RhdGEgPSBnZXRTZXR0aW5nc0RhdGFGcm9tS2V5cyhzZXR0aW5nc0xpbmUsIENPTlRFTlRfT1ZFUkZMT1dfUkVHRVhfQVJSKTtcbiAgICBpZiAoc2V0dGluZ3NEYXRhID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgb3ZlcmZsb3dTdGF0ZXM6IENvbnRlbnRPdmVyZmxvd1R5cGVbXSA9IFtdXG4gICAgbGV0IHNldHRpbmdWYWx1ZXMgPSBwYXJzZUZvck11bHRpU2V0dGluZ3Moc2V0dGluZ3NEYXRhKTtcblxuICAgIGZvcihsZXQgc2V0dGluZ3NEYXRhIG9mIHNldHRpbmdWYWx1ZXMpIHtcbiAgICAgICAgXG4gICAgICAgIGxldCBvdmVyZmxvd1R5cGUgPSBDb250ZW50T3ZlcmZsb3dUeXBlLnNjcm9sbDtcbiAgICAgICAgc2V0dGluZ3NEYXRhID0gc2V0dGluZ3NEYXRhLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuICAgICAgICBpZiAoc2V0dGluZ3NEYXRhID09PSBcImhpZGRlblwiKSB7XG4gICAgICAgICAgICBvdmVyZmxvd1R5cGUgPSBDb250ZW50T3ZlcmZsb3dUeXBlLmhpZGRlbjtcbiAgICAgICAgfVxuICAgICAgICBvdmVyZmxvd1N0YXRlcy5wdXNoKG92ZXJmbG93VHlwZSk7XG4gICAgfVxuICAgIHBhcnNlZFNldHRpbmdzLmNvbnRlbnRPdmVyZmxvdyA9IG92ZXJmbG93U3RhdGVzO1xufVxuXG5mdW5jdGlvbiBjaGVja1NldHRpbmdJc0NvbHVtbkFsaWdubWVudChzZXR0aW5nc0xpbmU6IHN0cmluZywgcGFyc2VkU2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MpIHtcbiAgICBcbiAgICBsZXQgc2V0dGluZ3NEYXRhID0gZ2V0U2V0dGluZ3NEYXRhRnJvbUtleXMoc2V0dGluZ3NMaW5lLCBBTElHTk1FTlRfUkVHRVhfQVJSKTtcbiAgICBpZiAoc2V0dGluZ3NEYXRhID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cblxuICAgIGxldCBhbGlnbm1lbnRzOiBBbGlnbm1lbnRUeXBlW10gPSBbXVxuXG4gICAgbGV0IHNldHRpbmdWYWx1ZXMgPSBwYXJzZUZvck11bHRpU2V0dGluZ3Moc2V0dGluZ3NEYXRhKTtcbiAgICBmb3IobGV0IHNldHRpbmdzRGF0YSBvZiBzZXR0aW5nVmFsdWVzKSB7XG4gICAgICAgIFxuICAgICAgICBsZXQgYWxpZ25tZW50VHlwZSA9IEFsaWdubWVudFR5cGUubGVmdDtcbiAgICAgICAgc2V0dGluZ3NEYXRhID0gc2V0dGluZ3NEYXRhLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuICAgICAgICBpZiAoc2V0dGluZ3NEYXRhID09PSBcImNlbnRlclwiKSB7XG4gICAgICAgICAgICBhbGlnbm1lbnRUeXBlID0gQWxpZ25tZW50VHlwZS5jZW50ZXI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNldHRpbmdzRGF0YSA9PT0gXCJyaWdodFwiKSB7XG4gICAgICAgICAgICBhbGlnbm1lbnRUeXBlID0gQWxpZ25tZW50VHlwZS5yaWdodDtcbiAgICAgICAgfVxuICAgICAgICBhbGlnbm1lbnRzLnB1c2goYWxpZ25tZW50VHlwZSk7XG4gICAgfVxuICAgIHBhcnNlZFNldHRpbmdzLmFsaWdubWVudCA9IGFsaWdubWVudHM7XG59XG5cbmZ1bmN0aW9uIGNoZWNrU2V0dGluZ0lzVGFibGVBbGlnbm1lbnQoc2V0dGluZ3NMaW5lOiBzdHJpbmcsIHBhcnNlZFNldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzKSB7XG4gICAgXG4gICAgbGV0IHNldHRpbmdzRGF0YSA9IGdldFNldHRpbmdzRGF0YUZyb21LZXlzKHNldHRpbmdzTGluZSwgVEFCTEVfQUxJR05NRU5UX1JFR0VYX0FSUik7XG4gICAgaWYgKHNldHRpbmdzRGF0YSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHNldHRpbmdWYWx1ZXMgPSBwYXJzZUZvck11bHRpU2V0dGluZ3Moc2V0dGluZ3NEYXRhKTtcbiAgICBzZXR0aW5nc0RhdGEgPSBzZXR0aW5nVmFsdWVzWzBdO1xuXG4gICAgbGV0IHRhYmxlQWxpZ25tZW50OiBUYWJsZUFsaWduT3B0aW9uID0gKDxhbnk+VGFibGVBbGlnbk9wdGlvbilbc2V0dGluZ3NEYXRhXTtcbiAgICBpZiAodGFibGVBbGlnbm1lbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzd2l0Y2ggKHRhYmxlQWxpZ25tZW50KSB7XG4gICAgICAgICAgICBjYXNlIChUYWJsZUFsaWduT3B0aW9uLmRpc2FibGVkKTpcbiAgICAgICAgICAgIGNhc2UgKFRhYmxlQWxpZ25PcHRpb24ub2ZmKTpcbiAgICAgICAgICAgIGNhc2UgKFRhYmxlQWxpZ25PcHRpb24uZmFsc2UpOlxuICAgICAgICAgICAgICAgIHBhcnNlZFNldHRpbmdzLmFsaWduVGFibGVzVG9BbGlnbm1lbnQgPSBUYWJsZUFsaWdubWVudC5ub0FsaWduO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBwYXJzZWRTZXR0aW5ncy5hbGlnblRhYmxlc1RvQWxpZ25tZW50ID0gVGFibGVBbGlnbm1lbnQuYWxpZ247XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrU2V0dGluZ0lzQ29sdW1uSGVpZ2h0KHNldHRpbmdzTGluZTogc3RyaW5nLCBwYXJzZWRTZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncykge1xuXG4gICAgbGV0IHNldHRpbmdzRGF0YSA9IGdldFNldHRpbmdzRGF0YUZyb21LZXlzKHNldHRpbmdzTGluZSwgQ09MVU1OX0hFSUdIVF9SRUdFWF9BUlIpO1xuICAgIGlmKHNldHRpbmdzRGF0YSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHNldHRpbmdWYWx1ZXMgPSBwYXJzZUZvck11bHRpU2V0dGluZ3Moc2V0dGluZ3NEYXRhKTtcbiAgICBzZXR0aW5nc0RhdGEgPSBzZXR0aW5nVmFsdWVzWzBdO1xuXG4gICAgbGV0IHBhcnNlZCA9IEhUTUxTaXppbmcucGFyc2VUb1NpemluZyhzZXR0aW5nc0RhdGEudHJpbSgpKTtcbiAgICBpZiAocGFyc2VkICE9PSBudWxsKSB7XG5cbiAgICAgICAgcGFyc2VkU2V0dGluZ3MuY29sdW1uSGVpZ2h0ID0gcGFyc2VkO1xuICAgIH1cbiAgICBlbHNlIHtcblxuICAgICAgICBsZXQgbm9Vbml0c051bSA9IHBhcnNlSW50KHNldHRpbmdzRGF0YS50cmltKCkpO1xuICAgICAgICBpZiAoaXNOYU4obm9Vbml0c051bSkgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgIHBhcnNlZFNldHRpbmdzLmNvbHVtbkhlaWdodCA9IEhUTUxTaXppbmcuY3JlYXRlKCkuc2V0V2lkdGgobm9Vbml0c051bSkuc2V0VW5pdHMoXCJwdFwiKVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZUZvck11bHRpU2V0dGluZ3Mob3JpZ2luYWxWYWx1ZTogc3RyaW5nKTogc3RyaW5nW10ge1xuXG4gICAgLy8gUGFyc2Ugb2ZmIGJyYWNrZXRzLiBJZiBubyBicmFja2V0cyB3ZSByZXR1cm4gb3JpZ2luYWwgdmFsdWUgdG8gYmUgcGFyc2VkIGFzIHNvbGUgdmFsdWUuXG4gICAgbGV0IHJlc3VsdCA9IC9cXFsoLiopXFxdLy5leGVjKG9yaWdpbmFsVmFsdWUpO1xuICAgIGlmKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gW29yaWdpbmFsVmFsdWVdO1xuICAgIH1cblxuICAgIGxldCBzZXR0aW5nc0xpc3Q6IHN0cmluZyA9IHJlc3VsdFsxXTtcbiAgICBsZXQgc2V0dGluZ3M6IHN0cmluZ1tdID0gc2V0dGluZ3NMaXN0LnNwbGl0KFwiLFwiKS5tYXAoKHZhbCkgPT4ge1xuICAgICAgICByZXR1cm4gdmFsLnRyaW0oKTtcbiAgICB9KVxuXG4gICAgcmV0dXJuIHNldHRpbmdzO1xufVxuXG5jb25zdCBDT0RFQkxPQ0tfUkVHSU9OX0lEX1JFR0VYX1NUUlMgPSBbXG4gICAgXCJpZFwiLFxuICAgIFwicmVnaW9uIGlkXCJcbl1cbmNvbnN0IENPREVCTE9DS19SRUdJT05fSURfUkVHRVhfQVJSOiBSZWdFeHBbXSA9IENPREVCTE9DS19SRUdJT05fSURfUkVHRVhfU1RSUy5tYXAoY29udmVydFN0cmluZ1RvU2V0dGluZ3NSZWdleCkubWFwKCh2YWx1ZSkgPT4ge1xuICAgIHJldHVybiBuZXcgUmVnRXhwKHZhbHVlLCBcImlcIik7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVN0YXJ0UmVnaW9uQ29kZUJsb2NrSUQoc2V0dGluZ3NTdHI6IHN0cmluZyk6IHN0cmluZyB7XG5cbiAgICBsZXQgY29kZUJsb2NrUmVnaW9uSUQgPSBcIlwiXG4gICAgbGV0IHNldHRpbmdzTGluZXMgPSBzZXR0aW5nc1N0ci5zcGxpdChcIlxcblwiKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2V0dGluZ3NMaW5lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgc2V0dGluZ3NMaW5lID0gc2V0dGluZ3NMaW5lc1tpXTtcblxuICAgICAgICBsZXQgc2V0dGluZ3NEYXRhID0gZ2V0U2V0dGluZ3NEYXRhRnJvbUtleXMoc2V0dGluZ3NMaW5lLCBDT0RFQkxPQ0tfUkVHSU9OX0lEX1JFR0VYX0FSUik7XG4gICAgICAgIGlmIChzZXR0aW5nc0RhdGEgIT09IG51bGwpIHtcblxuICAgICAgICAgICAgY29kZUJsb2NrUmVnaW9uSUQgPSBzZXR0aW5nc0RhdGFcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb2RlQmxvY2tSZWdpb25JRDtcbn1cblxuZnVuY3Rpb24gcGFyc2VGb3JTaW5nbGVDb2x1bW5Mb2NhdGlvbihsb2NhdGlvblN0cmluZzogc3RyaW5nKTogQ29sdW1uTGF5b3V0e1xuXG4gICAgc3dpdGNoIChsb2NhdGlvblN0cmluZy50b0xvd2VyQ2FzZSgpLnRyaW0oKS5yZXBsYWNlKFwiIFwiLCBcIlwiKSkge1xuICAgICAgICBjYXNlIFwibGVmdFwiOlxuICAgICAgICBjYXNlIFwibGVmdHNpZGVcIjpcbiAgICAgICAgY2FzZSBcImxlZnRtYXJnaW5cIjpcbiAgICAgICAgY2FzZSBcImxlZnRhbGlnblwiOlxuICAgICAgICBjYXNlIFwibGVmdGFsaWduZWRcIjpcbiAgICAgICAgY2FzZSBcImxlZnRhbGlnbmVtZW50XCI6XG4gICAgICAgIGNhc2UgXCJmaXJzdFwiOlxuICAgICAgICBjYXNlIFwic3RhcnRcIjpcbiAgICAgICAgY2FzZSBcImJlZ2lubmluZ1wiOlxuICAgICAgICAgICAgcmV0dXJuIFwibGVmdFwiXG4gICAgICAgIGNhc2UgXCJtaWRkbGVcIjpcbiAgICAgICAgY2FzZSBcIm1pZGRsZWFsaWduZWRcIjpcbiAgICAgICAgY2FzZSBcIm1pZGRsZWFsaWdubWVudFwiOlxuICAgICAgICBjYXNlIFwiY2VudGVyXCI6XG4gICAgICAgIGNhc2UgXCJjZW50ZXJhbGlnbmVkXCI6XG4gICAgICAgIGNhc2UgXCJjZW50ZXJhbGlnbm1lbnRcIjpcbiAgICAgICAgY2FzZSBcImNlbnRlcmVkXCI6XG4gICAgICAgIGNhc2UgXCJzdGFuZGFyZFwiOlxuICAgICAgICAgICAgcmV0dXJuIFwiY2VudGVyXCJcbiAgICAgICAgY2FzZSBcInJpZ2h0XCI6XG4gICAgICAgIGNhc2UgXCJyaWdodHNpZGVcIjpcbiAgICAgICAgY2FzZSBcInJpZ2h0bWFyZ2luXCI6XG4gICAgICAgIGNhc2UgXCJyaWdodGFsaWduXCI6XG4gICAgICAgIGNhc2UgXCJyaWdodGFsaWduZWRcIjpcbiAgICAgICAgY2FzZSBcInJpZ2h0YWxpZ25tZW50XCI6XG4gICAgICAgIGNhc2UgXCJsYXN0XCI6XG4gICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgIHJldHVybiBcInJpZ2h0XCJcbiAgICB9XG5cbiAgICByZXR1cm4gXCJjZW50ZXJcIlxufVxuXG5mdW5jdGlvbiBwYXJzZUZvclNpbmdsZUNvbHVtblNpemUoc2l6ZVN0cmluZzogc3RyaW5nKTogU2luZ2xlQ29sdW1uU2l6ZSB7XG5cbiAgICBzd2l0Y2ggKHNpemVTdHJpbmcgPSBzaXplU3RyaW5nLnRvTG93ZXJDYXNlKCkudHJpbSgpLnJlcGxhY2UoXCIgXCIsIFwiXCIpKSB7XG4gICAgICAgIGNhc2UgXCJzbWFsbFwiOlxuICAgICAgICBjYXNlIFwic21cIjpcbiAgICAgICAgICAgIHJldHVybiBcInNtYWxsXCI7XG4gICAgICAgIGNhc2UgXCJtZWRpdW1cIjpcbiAgICAgICAgY2FzZSBcIm1lZFwiOlxuICAgICAgICAgICAgcmV0dXJuIFwibWVkaXVtXCI7XG4gICAgICAgIGNhc2UgXCJsYXJnZVwiOlxuICAgICAgICBjYXNlIFwibGdcIjpcbiAgICAgICAgICAgIHJldHVybiBcImxhcmdlXCI7XG4gICAgICAgIGNhc2UgXCJmdWxsXCI6XG4gICAgICAgIGNhc2UgXCJmdWxsIHNpemVcIjpcbiAgICAgICAgICAgIHJldHVybiBcImZ1bGxcIjtcbiAgICB9XG5cbiAgICByZXR1cm4gXCJtZWRpdW1cIlxufVxuXG5mdW5jdGlvbiBjb252ZXJ0U3RyaW5nVG9TZXR0aW5nc1JlZ2V4KG9yaWdpbmFsU3RyaW5nOiBTdHJpbmcpOiBzdHJpbmcge1xuXG4gICAgb3JpZ2luYWxTdHJpbmcgPSBvcmlnaW5hbFN0cmluZy5yZXBsYWNlKFwiIFwiLCBcIig/OlstX118ICp8KVwiKTtcblxuICAgIGxldCByZWdleFN0cmluZyA9IGAoPzoke29yaWdpbmFsU3RyaW5nfSAqWzo9XSAqKSguKilgO1xuICAgIHJldHVybiByZWdleFN0cmluZztcbn1cblxuIiwiaW1wb3J0IHsgTXVsdGlDb2x1bW5TZXR0aW5ncywgZ2V0RGVmYXVsdE11bHRpQ29sdW1uU2V0dGluZ3MgfSBmcm9tIFwic3JjL3JlZ2lvblNldHRpbmdzXCI7XG5pbXBvcnQgeyBwYXJzZUNvbHVtblNldHRpbmdzIH0gZnJvbSBcIi4vc2V0dGluZ3NQYXJzZXJcIjtcbmltcG9ydCB7IFN0YXJ0VGFnUmVnZXhNYXRjaCwgZGVmYXVsdFN0YXJ0UmVnaW9uRGF0YSB9IGZyb20gXCIuL2ludGVyZmFjZXNcIjtcblxuXG5leHBvcnQgY29uc3QgUEFORE9DX0VOR0xJU0hfTlVNQkVSX09GX0NPTFVNTlMgPSBbXG4gICAgXCJ0d29cIixcbiAgICBcInRocmVlXCIsXG4gICAgXCJmb3VyXCIsXG4gICAgXCJmaXZlXCIsXG4gICAgXCJzaXhcIixcbiAgICBcInNldmVuXCIsXG4gICAgXCJlaWdodFwiLFxuICAgIFwibmluZVwiLFxuICAgIFwidGVuXCJcbl0gYXMgY29uc3Q7XG50eXBlIFBhbmRvY051bWJlck9mQ29sdW1uc1R1cGxlID0gdHlwZW9mIFBBTkRPQ19FTkdMSVNIX05VTUJFUl9PRl9DT0xVTU5TO1xuZXhwb3J0IHR5cGUgUGFuZG9jTnVtYmVyT2ZDb2x1bW5zID0gUGFuZG9jTnVtYmVyT2ZDb2x1bW5zVHVwbGVbbnVtYmVyXTtcbmV4cG9ydCBmdW5jdGlvbiBpc1BhbmRvY051bWJlck9mQ29sdW1ucyh2YWx1ZTogc3RyaW5nKTogdmFsdWUgaXMgUGFuZG9jTnVtYmVyT2ZDb2x1bW5zIHtcbiAgICByZXR1cm4gUEFORE9DX0VOR0xJU0hfTlVNQkVSX09GX0NPTFVNTlMuaW5jbHVkZXModmFsdWUgYXMgUGFuZG9jTnVtYmVyT2ZDb2x1bW5zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVBhbmRvY051bWJlck9mQ29sdW1ucyh2YWx1ZTogc3RyaW5nIHwgUGFuZG9jTnVtYmVyT2ZDb2x1bW5zKTogUGFuZG9jTnVtYmVyT2ZDb2x1bW5zIHtcbiAgICByZXR1cm4gKHZhbHVlLnRvTG93ZXJDYXNlKCkgYXMgUGFuZG9jTnVtYmVyT2ZDb2x1bW5zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBwYW5kb2NOdW1iZXJPZkNvbHVtbnNUb1ZhbHVlKHZhbHVlOiBQYW5kb2NOdW1iZXJPZkNvbHVtbnMpOiBudW1iZXIge1xuICAgIHN3aXRjaCAodmFsdWUpIHtcbiAgICAgICAgY2FzZSBcInR3b1wiOlxuICAgICAgICAgICAgcmV0dXJuIDI7XG4gICAgICAgIGNhc2UgXCJ0aHJlZVwiOlxuICAgICAgICAgICAgcmV0dXJuIDM7XG4gICAgICAgIGNhc2UgXCJmb3VyXCI6XG4gICAgICAgICAgICByZXR1cm4gNDtcbiAgICAgICAgY2FzZSBcImZpdmVcIjpcbiAgICAgICAgICAgIHJldHVybiA1O1xuICAgICAgICBjYXNlIFwic2l4XCI6XG4gICAgICAgICAgICByZXR1cm4gNjtcbiAgICAgICAgY2FzZSBcInNldmVuXCI6XG4gICAgICAgICAgICByZXR1cm4gNztcbiAgICAgICAgY2FzZSBcImVpZ2h0XCI6XG4gICAgICAgICAgICByZXR1cm4gODtcbiAgICAgICAgY2FzZSBcIm5pbmVcIjpcbiAgICAgICAgICAgIHJldHVybiA5O1xuICAgICAgICBjYXNlIFwidGVuXCI6XG4gICAgICAgICAgICByZXR1cm4gMTA7XG4gICAgfVxufVxuY29uc3QgUEFORE9DX0NPTF9ET1RfQ09VTlRfTkFNRSA9IFwiY29sRG90Q291bnRcIjtcbmNvbnN0IFBBTkRPQ19DT0xfTk9ET1RfQ09VTlRfTkFNRSA9IFwiY29sQ291bnRcIjtcbmNvbnN0IFBBTkRPQ19DT0xfQ09OVEVOVCA9IFwiY29sQ29udGVudFwiO1xuY29uc3QgUEFORE9DX0NPbF9TRVRUSU5HUyA9IFwiY29sU2V0dGluZ3NcIjtcbmNvbnN0IFBBTkRPQ19SRUdFWF9TVFI6IHN0cmluZyA9ICgoKSA9PiB7XG5cbiAgICBsZXQgbnVtcyA9IFBBTkRPQ19FTkdMSVNIX05VTUJFUl9PRl9DT0xVTU5TLmpvaW4oXCJ8XCIpO1xuICAgIGxldCByZWdleF9zdHJpbmdzID0gYDp7Myx9ICooPzpcXFxceyAqXFxcXC4oPzwke1BBTkRPQ19DT0xfRE9UX0NPVU5UX05BTUV9Pig/OiR7bnVtc318KSkoPzpbLV9dfCljb2x1bW5zKD88JHtQQU5ET0NfQ09sX1NFVFRJTkdTfT4uKilcXFxcfXwoPzwke1BBTkRPQ19DT0xfTk9ET1RfQ09VTlRfTkFNRX0+KD86JHtudW1zfXwpKSg/OlstX118KWNvbHVtbnMpKD86WyA6XSopJFxcXFxuP2A7XG4gICAgcmV0dXJuIHJlZ2V4X3N0cmluZ3M7XG59KSgpO1xuY29uc3QgUEFORE9DX1JFR0VYID0gbmV3IFJlZ0V4cChQQU5ET0NfUkVHRVhfU1RSLCBcIm1cIik7XG5jb25zdCBQQU5ET0NfT1BFTl9GRU5DRV9SRUdFWCA9IC9eOnszLH0gKig/OlthLXpBLVpdK3xcXHsuKlxcfSkoPzpbIDpdKikkL207XG5jb25zdCBQQU5ET0NfQ0xPU0VfRkVOQ0VfUkVHRVggPSAvXjp7Myx9ICokL207XG5leHBvcnQgZnVuY3Rpb24gZmluZFBhbmRvYyh0ZXh0OiBzdHJpbmcpOiBQYW5kb2NSZWdleERhdGEge1xuXG4gICAgbGV0IHJlZ2V4RGF0YSA9IFBBTkRPQ19SRUdFWC5leGVjKHRleHQpO1xuICAgIGlmIChyZWdleERhdGEgIT09IG51bGwpIHtcblxuICAgICAgICBsZXQgZGF0YSA9IGRlZmF1bHRQYW5kb2NSZWdleERhdGEoKTtcbiAgICAgICAgZGF0YS5mb3VuZCA9IHRydWU7XG4gICAgICAgIGRhdGEuc3RhcnRQb3NpdGlvbiA9IHJlZ2V4RGF0YS5pbmRleDtcbiAgICAgICAgZGF0YS5lbmRQb3NpdGlvbiA9IHJlZ2V4RGF0YS5pbmRleCArIHJlZ2V4RGF0YVswXS5sZW5ndGg7XG5cbiAgICAgICAgbGV0IHJlZ2lvbkRhdGEgPSByZWR1Y2VQYW5kb2NSZWdpb25Ub0VuZERpdih0ZXh0LnNsaWNlKGRhdGEuZW5kUG9zaXRpb24pKTtcbiAgICAgICAgZGF0YS5lbmRQb3NpdGlvbiArPSByZWdpb25EYXRhLmNvbnRlbnQubGVuZ3RoICsgcmVnaW9uRGF0YS5tYXRjaExlbmd0aDtcbiAgICAgICAgZGF0YS5jb250ZW50ID0gcmVnaW9uRGF0YS5jb250ZW50O1xuICAgICAgICBkYXRhLm1hdGNoTGVuZ3RoID0gZGF0YS5lbmRQb3NpdGlvbiAtIGRhdGEuc3RhcnRQb3NpdGlvbjtcblxuICAgICAgICBkYXRhLnVzZXJTZXR0aW5ncyA9IHJlZ2V4RGF0YS5ncm91cHNbUEFORE9DX0NPbF9TRVRUSU5HU10gPyByZWdleERhdGEuZ3JvdXBzW1BBTkRPQ19DT2xfU0VUVElOR1NdIDogXCJcIjtcbiAgICAgICAgZGF0YS5jb2x1bW5Db3VudCA9IHJlZ2V4RGF0YS5ncm91cHNbUEFORE9DX0NPTF9ET1RfQ09VTlRfTkFNRV0gPyByZWdleERhdGEuZ3JvdXBzW1BBTkRPQ19DT0xfRE9UX0NPVU5UX05BTUVdIDogcmVnZXhEYXRhLmdyb3Vwc1tQQU5ET0NfQ09MX05PRE9UX0NPVU5UX05BTUVdO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVmYXVsdFBhbmRvY1JlZ2V4RGF0YSgpO1xufVxuZXhwb3J0IGludGVyZmFjZSBQYW5kb2NTdGFydERhdGEge1xuICAgIGZvdW5kOiBib29sZWFuO1xuICAgIHVzZXJTZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncztcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYW5kb2NTdGFydERhdGEodGV4dDogc3RyaW5nKTogUGFuZG9jU3RhcnREYXRhIHtcblxuICAgIGxldCBkYXRhID0gZmluZFBhbmRvYyh0ZXh0KTtcbiAgICBpZiAoZGF0YS5mb3VuZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZvdW5kOiBmYWxzZSxcbiAgICAgICAgICAgIHVzZXJTZXR0aW5nczogZ2V0RGVmYXVsdE11bHRpQ29sdW1uU2V0dGluZ3MoKVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGZvdW5kOiB0cnVlLFxuICAgICAgICB1c2VyU2V0dGluZ3M6IHBhcnNlUGFuZG9jU2V0dGluZ3MoZGF0YS51c2VyU2V0dGluZ3MsIGRhdGEuY29sdW1uQ291bnQpXG4gICAgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjb250YWluc1BhbmRvYyh0ZXh0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmluZFBhbmRvYyh0ZXh0KS5mb3VuZDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjb250YWluc1BhbmRvY1N0YXJ0VGFnKHRleHQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuXG4gICAgbGV0IHJlZ2V4RGF0YSA9IFBBTkRPQ19SRUdFWC5leGVjKHRleHQpO1xuICAgIGlmIChyZWdleERhdGEgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjb250YWluc1BhbmRvY0VuZFRhZyh0ZXh0OiBzdHJpbmcpOiBib29sZWFuIHtcblxuICAgIGxldCByZWdleERhdGEgPSBQQU5ET0NfQ0xPU0VfRkVOQ0VfUkVHRVguZXhlYyh0ZXh0KTtcbiAgICBpZiAocmVnZXhEYXRhICE9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFBhbmRvY0VuZFRhZyhsaW5lc0Fib3ZlOiBzdHJpbmdbXSwgY3VycmVudExpbmU6IHN0cmluZyk6IGJvb2xlYW4ge1xuXG4gICAgaWYgKGNvbnRhaW5zUGFuZG9jRW5kVGFnKGN1cnJlbnRMaW5lKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGxldCBjb250ZW50VGV4dCA9IGxpbmVzQWJvdmUuY29uY2F0KGN1cnJlbnRMaW5lKS5qb2luKFwiXFxuXCIpO1xuICAgIHJldHVybiByZWR1Y2VQYW5kb2NSZWdpb25Ub0VuZERpdihjb250ZW50VGV4dCkuZm91bmQ7XG59XG5leHBvcnQgZnVuY3Rpb24gcmVkdWNlUGFuZG9jUmVnaW9uVG9FbmREaXYoY29udGVudFRleHQ6IHN0cmluZykge1xuXG4gICAgbGV0IHdvcmtpbmdUZXh0ID0gY29udGVudFRleHQ7XG5cbiAgICBsZXQgcmVzdWx0ID0ge1xuICAgICAgICBmb3VuZDogZmFsc2UsXG4gICAgICAgIGNvbnRlbnQ6IHdvcmtpbmdUZXh0LFxuICAgICAgICBtYXRjaExlbmd0aDogMFxuICAgIH07XG5cbiAgICBsZXQgc3RhdGUgPSAwO1xuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyB0cnVlOyBpKyspIHtcbiAgICAgICAgaWYgKGkgPiAxMDApIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGZlbmNlID0gZ2V0TmV4dFBhbmRvY0ZlbmNlKHdvcmtpbmdUZXh0KTtcbiAgICAgICAgaWYgKGZlbmNlID09PSBudWxsKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCByZXN1bHQgPSBmZW5jZS5yZXN1bHQ7XG4gICAgICAgIGlmIChmZW5jZS50eXBlID09PSBcImNsb3NlXCIpIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHdvcmtpbmdUZXh0LnNsaWNlKHJlc3VsdC5pbmRleCwgcmVzdWx0LmluZGV4ICsgcmVzdWx0WzBdLmxlbmd0aCkpO1xuICAgICAgICAgICAgb2Zmc2V0ICs9IChyZXN1bHQuaW5kZXggKyByZXN1bHRbMF0ubGVuZ3RoKTtcbiAgICAgICAgICAgIHN0YXRlLS07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyh3b3JraW5nVGV4dC5zbGljZShyZXN1bHQuaW5kZXgsIHJlc3VsdC5pbmRleCArIHJlc3VsdFswXS5sZW5ndGgpKTtcbiAgICAgICAgICAgIG9mZnNldCArPSAocmVzdWx0LmluZGV4ICsgcmVzdWx0WzBdLmxlbmd0aCk7XG4gICAgICAgICAgICBzdGF0ZSsrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0YXRlID09PSAtMSkge1xuICAgICAgICAgICAgLy8gV2UgaGF2ZSBmb3VuZCBvdXIgbGFzdCBjbG9zZSB0YWcuXG4gICAgICAgICAgICByZXR1cm4gYnVpbGRSZXR1cm5EYXRhKHJlc3VsdCk7XG4gICAgICAgIH1cblxuICAgICAgICB3b3JraW5nVGV4dCA9IGNvbnRlbnRUZXh0LnNsaWNlKG9mZnNldCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYnVpbGRSZXR1cm5EYXRhKG1hdGNoUmVzdWx0OiBSZWdFeHBFeGVjQXJyYXkpIHtcbiAgICAgICAgcmVzdWx0LmNvbnRlbnQgPSBjb250ZW50VGV4dC5zbGljZSgwLCBvZmZzZXQgLSBtYXRjaFJlc3VsdFswXS5sZW5ndGgpO1xuICAgICAgICByZXN1bHQubWF0Y2hMZW5ndGggPSBtYXRjaFJlc3VsdFswXS5sZW5ndGg7XG4gICAgICAgIHJlc3VsdC5mb3VuZCA9IHRydWU7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGdldE5leHRQYW5kb2NGZW5jZSh3b3JraW5nVGV4dDogc3RyaW5nKTogeyByZXN1bHQ6IFJlZ0V4cEV4ZWNBcnJheTsgdHlwZTogXCJvcGVuXCIgfCBcImNsb3NlXCI7IH0ge1xuXG4gICAgbGV0IG9wZW5SZXN1bHQgPSBQQU5ET0NfT1BFTl9GRU5DRV9SRUdFWC5leGVjKHdvcmtpbmdUZXh0KTtcbiAgICBsZXQgY2xvc2VSZXN1bHQgPSBQQU5ET0NfQ0xPU0VfRkVOQ0VfUkVHRVguZXhlYyh3b3JraW5nVGV4dCk7XG5cbiAgICBpZiAob3BlblJlc3VsdCA9PT0gbnVsbCAmJiBjbG9zZVJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAob3BlblJlc3VsdCA9PT0gbnVsbCAmJiBjbG9zZVJlc3VsdCAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVzdWx0OiBjbG9zZVJlc3VsdCxcbiAgICAgICAgICAgIHR5cGU6IFwiY2xvc2VcIlxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmIChjbG9zZVJlc3VsdCA9PT0gbnVsbCAmJiBvcGVuUmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXN1bHQ6IG9wZW5SZXN1bHQsXG4gICAgICAgICAgICB0eXBlOiBcIm9wZW5cIlxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmIChjbG9zZVJlc3VsdC5pbmRleCA8IG9wZW5SZXN1bHQuaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlc3VsdDogY2xvc2VSZXN1bHQsXG4gICAgICAgICAgICB0eXBlOiBcImNsb3NlXCJcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZXN1bHQ6IG9wZW5SZXN1bHQsXG4gICAgICAgICAgICB0eXBlOiBcIm9wZW5cIlxuICAgICAgICB9O1xuICAgIH1cbn1cbmV4cG9ydCBmdW5jdGlvbiBmaW5kUGFuZG9jU3RhcnQodGV4dDogc3RyaW5nKTogU3RhcnRUYWdSZWdleE1hdGNoIHtcblxuICAgIGxldCBzdGFydFJlZ2lvbiA9IGRlZmF1bHRTdGFydFJlZ2lvbkRhdGEoKTtcbiAgICBzdGFydFJlZ2lvbi5yZWdpb25UeXBlID0gXCJQQURPQ1wiO1xuXG4gICAgbGV0IHJlZ2V4RGF0YSA9IFBBTkRPQ19SRUdFWC5leGVjKHRleHQpO1xuICAgIGlmIChyZWdleERhdGEgIT09IG51bGwgJiYgcmVnZXhEYXRhLmxlbmd0aCA+IDApIHtcblxuICAgICAgICBzdGFydFJlZ2lvbi5mb3VuZCA9IHRydWU7XG4gICAgICAgIHN0YXJ0UmVnaW9uLnN0YXJ0UG9zaXRpb24gPSByZWdleERhdGEuaW5kZXg7XG4gICAgICAgIHN0YXJ0UmVnaW9uLm1hdGNoTGVuZ3RoID0gcmVnZXhEYXRhWzBdLmxlbmd0aDtcbiAgICAgICAgc3RhcnRSZWdpb24uZW5kUG9zaXRpb24gPSBzdGFydFJlZ2lvbi5zdGFydFBvc2l0aW9uICsgc3RhcnRSZWdpb24ubWF0Y2hMZW5ndGg7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXJ0UmVnaW9uO1xufVxuZXhwb3J0IGludGVyZmFjZSBQYW5kb2NSZWdleERhdGEgZXh0ZW5kcyBTdGFydFRhZ1JlZ2V4TWF0Y2gge1xuICAgIGZvdW5kOiBib29sZWFuO1xuICAgIHN0YXJ0UG9zaXRpb246IG51bWJlcjtcbiAgICBlbmRQb3NpdGlvbjogbnVtYmVyO1xuICAgIGNvbnRlbnQ6IHN0cmluZztcbiAgICB1c2VyU2V0dGluZ3M6IHN0cmluZztcbiAgICBjb2x1bW5Db3VudDogc3RyaW5nO1xufVxuZnVuY3Rpb24gZGVmYXVsdFBhbmRvY1JlZ2V4RGF0YSgpOiBQYW5kb2NSZWdleERhdGEge1xuICAgIHJldHVybiB7XG4gICAgICAgIGZvdW5kOiBmYWxzZSxcbiAgICAgICAgc3RhcnRQb3NpdGlvbjogLTEsXG4gICAgICAgIGVuZFBvc2l0aW9uOiAtMSxcbiAgICAgICAgbWF0Y2hMZW5ndGg6IDAsXG4gICAgICAgIGNvbnRlbnQ6IFwiXCIsXG4gICAgICAgIHVzZXJTZXR0aW5nczogXCJcIixcbiAgICAgICAgY29sdW1uQ291bnQ6IFwiXCIsXG4gICAgICAgIHJlZ2lvblR5cGU6IFwiUEFET0NcIlxuICAgIH07XG59XG5cbmNvbnN0IFBBTkRPQ19TRVRUSU5HX1JFR0VYID0gLyg/PHNldHRpbmdOYW1lPlteIF0qKT0oPzxzZXR0aW5nVmFsdWU+XCIuKlwifFteID1dKikvO1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGFuZG9jU2V0dGluZ3MocGFuZG9jVXNlclNldHRpbmdzOiBzdHJpbmcsIGNvbENvdW50OiBzdHJpbmcgPSBcIlwiKTogTXVsdGlDb2x1bW5TZXR0aW5ncyB7XG5cbiAgICAvL1RPRE86IEFkZCBvcHRpb24gZm9yIGNvbHVtbiBydWxlLiBcblxuICAgIGxldCBkZWZhdWx0U2V0dGluZ3MgPSBnZXREZWZhdWx0TXVsdGlDb2x1bW5TZXR0aW5ncygpO1xuICAgIGxldCBjb2xDb3VudERlZmluZWQgPSBmYWxzZTtcbiAgICBpZiAoY29sQ291bnQgIT09IFwiXCIgJiYgaXNQYW5kb2NOdW1iZXJPZkNvbHVtbnMoY29sQ291bnQpKSB7XG4gICAgICAgIGNvbENvdW50RGVmaW5lZCA9IHRydWU7XG4gICAgICAgIGRlZmF1bHRTZXR0aW5ncy5udW1iZXJPZkNvbHVtbnMgPSBwYW5kb2NOdW1iZXJPZkNvbHVtbnNUb1ZhbHVlKHZhbGlkYXRlUGFuZG9jTnVtYmVyT2ZDb2x1bW5zKGNvbENvdW50KSk7XG4gICAgfVxuXG4gICAgaWYgKHBhbmRvY1VzZXJTZXR0aW5ncy5yZXBsYWNlKFwiIFwiLCBcIlwiKSA9PT0gXCJcIikge1xuICAgICAgICByZXR1cm4gZGVmYXVsdFNldHRpbmdzO1xuICAgIH1cblxuICAgIGxldCB3b3JraW5nU3RyaW5nID0gcGFuZG9jVXNlclNldHRpbmdzO1xuICAgIGxldCByZWdleFZhbHVlID0gUEFORE9DX1NFVFRJTkdfUkVHRVguZXhlYyh3b3JraW5nU3RyaW5nKTtcbiAgICBsZXQgc2V0dGluZ0xpc3QgPSBcIlwiXG4gICAgZm9yIChsZXQgaSA9IDA7IHJlZ2V4VmFsdWUgIT09IG51bGw7IGkgPCAxMDApIHtcblxuICAgICAgICBsZXQgc2V0dGluZ05hbWUgPSByZWdleFZhbHVlLmdyb3Vwc1snc2V0dGluZ05hbWUnXTtcbiAgICAgICAgbGV0IHNldHRpbmdWYWx1ZSA9IHJlZ2V4VmFsdWUuZ3JvdXBzWydzZXR0aW5nVmFsdWUnXTtcbiAgICAgICAgc2V0dGluZ0xpc3QgKz0gYCR7c2V0dGluZ05hbWV9OiAke3NldHRpbmdWYWx1ZX1cXG5gXG5cbiAgICAgICAgd29ya2luZ1N0cmluZyA9IHdvcmtpbmdTdHJpbmcuc2xpY2UocmVnZXhWYWx1ZS5pbmRleCArIHJlZ2V4VmFsdWVbMF0ubGVuZ3RoKTtcbiAgICAgICAgcmVnZXhWYWx1ZSA9IFBBTkRPQ19TRVRUSU5HX1JFR0VYLmV4ZWMod29ya2luZ1N0cmluZyk7XG4gICAgfVxuXG4gICAgbGV0IHBhcnNlZFNldHRpbmdzID0gcGFyc2VDb2x1bW5TZXR0aW5ncyhzZXR0aW5nTGlzdClcbiAgICBpZihjb2xDb3VudERlZmluZWQpIHtcbiAgICAgICAgcGFyc2VkU2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zID0gZGVmYXVsdFNldHRpbmdzLm51bWJlck9mQ29sdW1uc1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZWRTZXR0aW5ncztcbn0iLCIvKlxuICogRmlsZTogbXVsdGktY29sdW1uLW1hcmtkb3duL3NyYy9NdWx0aUNvbHVtblBhcnNlci50c1xuICogQ3JlYXRlZCBEYXRlOiBTYXR1cmRheSwgSmFudWFyeSAyMm5kIDIwMjIsIDY6MDI6NDYgcG1cbiAqIEF1dGhvcjogQ2FtZXJvbiBSb2JpbnNvblxuICogXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjIgQ2FtZXJvbiBSb2JpbnNvblxuICovXG5cbmltcG9ydCB7IHBhcnNlU3RhcnRSZWdpb25Db2RlQmxvY2tJRCB9IGZyb20gXCIuL3NldHRpbmdzUGFyc2VyXCI7XG5pbXBvcnQgeyBjb250YWluc1BhbmRvYywgZmluZFBhbmRvY1N0YXJ0LCByZWR1Y2VQYW5kb2NSZWdpb25Ub0VuZERpdiwgZ2V0UGFuZG9jU3RhcnREYXRhIH0gZnJvbSBcIi4vcGFuZG9jUGFyc2VyXCI7XG5pbXBvcnQgeyBSZWdpb25UeXBlLCBTdGFydFRhZ1JlZ2V4TWF0Y2gsIGRlZmF1bHRTdGFydFJlZ2lvbkRhdGEgfSBmcm9tIFwiLi9pbnRlcmZhY2VzXCI7XG5cbmNvbnN0IFNUQVJUX1JFR0VYX1NUUlMgPSBbXCIoPT09fC0tLSkgKnN0YXJ0LW11bHRpLWNvbHVtbig6P1thLXpBLVowLTktX1xcXFxzXSopP1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBcIig9PT18LS0tKSAqbXVsdGktY29sdW1uLXN0YXJ0KDo/W2EtekEtWjAtOS1fXFxcXHNdKik/XCJdXG5jb25zdCBTVEFSVF9SRUdFWF9BUlI6IFJlZ0V4cFtdID0gW107XG5mb3IobGV0IGkgPSAwOyBpIDwgU1RBUlRfUkVHRVhfU1RSUy5sZW5ndGg7IGkrKykge1xuICAgIFNUQVJUX1JFR0VYX0FSUi5wdXNoKG5ldyBSZWdFeHAoU1RBUlRfUkVHRVhfU1RSU1tpXSkpO1xufVxuXG5jb25zdCBTVEFSVF9SRUdFWF9TVFJTX1dIT0xFX0xJTkUgPSBbXCJeKD09PXwtLS0pICpzdGFydC1tdWx0aS1jb2x1bW4oOj9bYS16QS1aMC05LV9cXFxcc10qKT8kXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJeKD09PXwtLS0pICptdWx0aS1jb2x1bW4tc3RhcnQoOj9bYS16QS1aMC05LV9cXFxcc10qKT8kXCJdXG5jb25zdCBTVEFSVF9SRUdFWF9BUlJfV0hPTEVfTElORTogUmVnRXhwW10gPSBbXTtcbmZvcihsZXQgaSA9IDA7IGkgPCBTVEFSVF9SRUdFWF9TVFJTX1dIT0xFX0xJTkUubGVuZ3RoOyBpKyspIHtcbiAgICBTVEFSVF9SRUdFWF9BUlJfV0hPTEVfTElORS5wdXNoKG5ldyBSZWdFeHAoU1RBUlRfUkVHRVhfU1RSU19XSE9MRV9MSU5FW2ldKSk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRTdGFydFRhZyh0ZXh0OiBzdHJpbmcpOiBTdGFydFRhZ1JlZ2V4TWF0Y2gge1xuXG4gICAgbGV0IHN0YXJ0UmVnaW9uID0gZGVmYXVsdFN0YXJ0UmVnaW9uRGF0YSgpO1xuICAgIHN0YXJ0UmVnaW9uLnJlZ2lvblR5cGUgPSBcIk9SSUdJTkFMXCI7XG5cbiAgICBmb3IobGV0IGkgPSAwOyBpPCBTVEFSVF9SRUdFWF9BUlIubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICBsZXQgcmVnZXhEYXRhID0gU1RBUlRfUkVHRVhfQVJSW2ldLmV4ZWModGV4dClcbiAgICAgICAgaWYocmVnZXhEYXRhICE9PSBudWxsICYmIHJlZ2V4RGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzdGFydFJlZ2lvbi5zdGFydFBvc2l0aW9uID0gcmVnZXhEYXRhLmluZGV4XG4gICAgICAgICAgICBzdGFydFJlZ2lvbi5tYXRjaExlbmd0aCA9IHJlZ2V4RGF0YVswXS5sZW5ndGg7XG4gICAgICAgICAgICBzdGFydFJlZ2lvbi5lbmRQb3NpdGlvbiA9IHN0YXJ0UmVnaW9uLnN0YXJ0UG9zaXRpb24gKyBzdGFydFJlZ2lvbi5tYXRjaExlbmd0aDtcblxuICAgICAgICAgICAgbGV0IGxpbmUgPSB0ZXh0LnNsaWNlKHN0YXJ0UmVnaW9uLnN0YXJ0UG9zaXRpb24sIHN0YXJ0UmVnaW9uLmVuZFBvc2l0aW9uKTtcbiAgICAgICAgICAgIGlmKFNUQVJUX1JFR0VYX0FSUl9XSE9MRV9MSU5FW2ldLnRlc3QobGluZSkpIHtcbiAgICAgICAgICAgICAgICBzdGFydFJlZ2lvbi5mb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0YXJ0UmVnaW9uO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5zU3RhcnRUYWcodGV4dDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZpbmRTdGFydFRhZyh0ZXh0KS5mb3VuZFxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTdGFydFRhZ1dpdGhJRCh0ZXh0OiBzdHJpbmcpOiB7aXNTdGFydFRhZzogYm9vbGVhbiwgaGFzS2V5OiBib29sZWFufSB7XG5cbiAgICBsZXQgc3RhcnRUYWdEYXRhID0gZmluZFN0YXJ0VGFnKHRleHQpO1xuICAgIGlmKHN0YXJ0VGFnRGF0YS5mb3VuZCA9PT0gdHJ1ZSkge1xuXG4gICAgICAgIGxldCBrZXkgPSBnZXRTdGFydFRhZ0tleSh0ZXh0KVxuICAgICAgICBpZihrZXkgPT09IG51bGwgfHwga2V5ID09PSBcIlwiKSB7XG4gICAgICAgICAgICByZXR1cm4ge2lzU3RhcnRUYWc6IHRydWUsIGhhc0tleTogZmFsc2V9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7aXNTdGFydFRhZzogdHJ1ZSwgaGFzS2V5OiB0cnVlfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge2lzU3RhcnRUYWc6IGZhbHNlLCBoYXNLZXk6IGZhbHNlfTtcbn1cblxuY29uc3QgRU5EX1JFR0VYX1NUUlMgPSBbXCItLS0gKmVuZC1tdWx0aS1jb2x1bW5cIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiLS0tICptdWx0aS1jb2x1bW4tZW5kXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIj09PSAqZW5kLW11bHRpLWNvbHVtblwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCI9PT0gKm11bHRpLWNvbHVtbi1lbmRcIl1cbmNvbnN0IEVORF9SRUdFWF9BUlI6IFJlZ0V4cFtdID0gW107XG5mb3IobGV0IGkgPSAwOyBpIDwgRU5EX1JFR0VYX1NUUlMubGVuZ3RoOyBpKyspIHtcbiAgICBFTkRfUkVHRVhfQVJSLnB1c2gobmV3IFJlZ0V4cChFTkRfUkVHRVhfU1RSU1tpXSkpO1xufVxuXG50eXBlIFRhZ1Bvc2l0aW9uaW5nRGF0YSA9IHtcbiAgICBmb3VuZDogYm9vbGVhbjtcbiAgICBzdGFydFBvc2l0aW9uOiBudW1iZXI7XG4gICAgZW5kUG9zaXRpb246IG51bWJlcjtcbiAgICBtYXRjaExlbmd0aDogbnVtYmVyO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRFbmRUYWcodGV4dDogc3RyaW5nKTogVGFnUG9zaXRpb25pbmdEYXRhIHtcblxuICAgIC8vIFdlIHdhbnQgdG8gZmluZCB0aGUgZmlyc3QgZW5kIHRhZyBpbiB0aGUgdGV4dC5cbiAgICAvLyBTbyBoZXJlIHdlIGxvb3AgYmFja3dhcmRzLCBzbGljaW5nIG9mZiB0aGUgdGFpbCB1bnRpbFxuICAgIC8vIHRoZXJlIGFyZSBubyBtb3JlIGVuZCB0YWdzIGF2YWlsYWJsZVxuICAgIGxldCBsYXN0VmFsaWREYXRhID0gZ2V0RW5kVGFnRGF0YSh0ZXh0KTtcbiAgICBsZXQgd29ya2luZ1JlZ2V4RGF0YSA9IGxhc3RWYWxpZERhdGE7XG4gICAgd2hpbGUod29ya2luZ1JlZ2V4RGF0YS5mb3VuZCA9PT0gdHJ1ZSkge1xuXG4gICAgICAgIGxhc3RWYWxpZERhdGEgPSB3b3JraW5nUmVnZXhEYXRhO1xuICAgICAgICB0ZXh0ID0gdGV4dC5zbGljZSgwLCB3b3JraW5nUmVnZXhEYXRhLnN0YXJ0UG9zaXRpb24pO1xuICAgICAgICB3b3JraW5nUmVnZXhEYXRhID0gZ2V0RW5kVGFnRGF0YSh0ZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGFzdFZhbGlkRGF0YTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRFbmRUYWdDbG9zZXN0VG9FbmQodGV4dDogc3RyaW5nKTogVGFnUG9zaXRpb25pbmdEYXRhIHtcblxuICAgIGxldCB3b3JraW5nVGV4dCA9IHRleHQ7XG4gICAgbGV0IG9mZnNldCA9IDA7XG5cbiAgICBsZXQgbGFzdFZhbGlkRGF0YSA9IGdldEVuZFRhZ0RhdGEod29ya2luZ1RleHQpO1xuICAgIHdoaWxlKGxhc3RWYWxpZERhdGEuZm91bmQpIHtcblxuICAgICAgICB3b3JraW5nVGV4dCA9IHdvcmtpbmdUZXh0LnNsaWNlKGxhc3RWYWxpZERhdGEuZW5kUG9zaXRpb24pO1xuICAgICAgICBsZXQgbmV3RGF0YSA9IGdldEVuZFRhZ0RhdGEod29ya2luZ1RleHQpO1xuICAgICAgICBpZihuZXdEYXRhLmZvdW5kID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgb2Zmc2V0ICs9IGxhc3RWYWxpZERhdGEuZW5kUG9zaXRpb247XG4gICAgICAgIGxhc3RWYWxpZERhdGEgPSBuZXdEYXRhO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGZvdW5kOiBsYXN0VmFsaWREYXRhLmZvdW5kLFxuICAgICAgICBzdGFydFBvc2l0aW9uOiBsYXN0VmFsaWREYXRhLnN0YXJ0UG9zaXRpb24gKyBvZmZzZXQsXG4gICAgICAgIGVuZFBvc2l0aW9uOiBsYXN0VmFsaWREYXRhLmVuZFBvc2l0aW9uICsgb2Zmc2V0LFxuICAgICAgICBtYXRjaExlbmd0aDogbGFzdFZhbGlkRGF0YS5tYXRjaExlbmd0aFxuICAgIH07XG59XG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNFbmRUYWcodGV4dDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZpbmRFbmRUYWcodGV4dCkuZm91bmRcbn1cblxuZnVuY3Rpb24gZ2V0RW5kVGFnRGF0YSh0ZXh0OiBzdHJpbmcpIHtcblxuICAgIGxldCBmb3VuZCA9IGZhbHNlO1xuICAgIGxldCBzdGFydFBvc2l0aW9uID0gLTE7XG4gICAgbGV0IGVuZFBvc2l0aW9uID0gLTFcbiAgICBsZXQgbWF0Y2hMZW5ndGggPSAwO1xuICAgIGZvcihsZXQgaSA9IDA7IGk8IEVORF9SRUdFWF9BUlIubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICBsZXQgcmVnZXhEYXRhID0gRU5EX1JFR0VYX0FSUltpXS5leGVjKHRleHQpXG4gICAgICAgIGlmKHJlZ2V4RGF0YSAhPT0gbnVsbCAmJiByZWdleERhdGEubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgc3RhcnRQb3NpdGlvbiA9IHJlZ2V4RGF0YS5pbmRleFxuICAgICAgICAgICAgbWF0Y2hMZW5ndGggPSByZWdleERhdGFbMF0ubGVuZ3RoO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZW5kUG9zaXRpb24gPSBzdGFydFBvc2l0aW9uICsgbWF0Y2hMZW5ndGg7XG5cbiAgICByZXR1cm4geyBmb3VuZCwgc3RhcnRQb3NpdGlvbiwgZW5kUG9zaXRpb24sIG1hdGNoTGVuZ3RoIH07XG59XG5cbmNvbnN0IENPTF9SRUdFWF9TVFJTOiBbc3RyaW5nLHN0cmluZ11bXSA9IFtbXCJePT09XFxcXHMqP2NvbHVtbi1lbmRcXFxccyo/PT09XFxcXHMqPyRcIiAgICxcIlwiXSwgLy8gW1JlZ2V4LCBSZWdleCBGbGFnc11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJePT09XFxcXHMqP2VuZC1jb2x1bW5cXFxccyo/PT09XFxcXHMqPyRcIiAgICxcIlwiXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJePT09XFxcXHMqP2NvbHVtbi1icmVha1xcXFxzKj89PT1cXFxccyo/JFwiICxcIlwiXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJePT09XFxcXHMqP2JyZWFrLWNvbHVtblxcXFxzKj89PT1cXFxccyo/JFwiICxcIlwiXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJeLS0tXFxcXHMqP2NvbHVtbi1lbmRcXFxccyo/LS0tXFxcXHMqPyRcIiAgICxcIlwiXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJeLS0tXFxcXHMqP2VuZC1jb2x1bW5cXFxccyo/LS0tXFxcXHMqPyRcIiAgICxcIlwiXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJeLS0tXFxcXHMqP2NvbHVtbi1icmVha1xcXFxzKj8tLS1cXFxccyo/JFwiICxcIlwiXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJeLS0tXFxcXHMqP2JyZWFrLWNvbHVtblxcXFxzKj8tLS1cXFxccyo/JFwiICxcIlwiXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXCJeICo/KD86XFxcXD8pXFxcXGNvbHVtbmJyZWFrICo/JFwiICAgICAgICAsXCJcIl0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1wiXjp7Myx9ICpjb2x1bW4tP2JyZWFrICooPzooPzokXFxcXG5eKT98ICopOnszLH0gKiRcIiAsXCJtXCJdXTtcbmNvbnN0IENPTF9SRUdFWF9BUlI6IFJlZ0V4cFtdID0gW107XG5mb3IobGV0IGkgPSAwOyBpIDwgQ09MX1JFR0VYX1NUUlMubGVuZ3RoOyBpKyspIHtcbiAgICBDT0xfUkVHRVhfQVJSLnB1c2gobmV3IFJlZ0V4cChDT0xfUkVHRVhfU1RSU1tpXVswXSwgQ09MX1JFR0VYX1NUUlNbaV1bMV0pKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjb250YWluc0NvbEVuZFRhZyh0ZXh0OiBzdHJpbmcpOiBib29sZWFuIHtcblxuICAgIGxldCBmb3VuZCA9IGZhbHNlO1xuICAgIGZvcihsZXQgaSA9IDA7IGk8IENPTF9SRUdFWF9BUlIubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICBpZihDT0xfUkVHRVhfQVJSW2ldLnRlc3QodGV4dCkpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZvdW5kO1xufVxuXG5jb25zdCBJTk5FUl9DT0xfRU5EX1JFR0VYX0FSUjogUmVnRXhwW10gPSBbXG4gICAgL14tezN9XFxzKj9jb2x1bW4tZW5kXFxzKj8tezN9XFxzKj8kXFxuPy9tLFxuICAgIC9eLXszfVxccyo/ZW5kLWNvbHVtblxccyo/LXszfVxccyo/JFxcbj8vbSxcbiAgICAvXi17M31cXHMqP2NvbHVtbi1icmVha1xccyo/LXszfVxccyo/JFxcbj8vbSxcbiAgICAvXi17M31cXHMqP2JyZWFrLWNvbHVtblxccyo/LXszfVxccyo/JFxcbj8vbSxcbiAgICAvXj17M31cXHMqP2NvbHVtbi1lbmRcXHMqPz17M31cXHMqPyRcXG4/L20sXG4gICAgL149ezN9XFxzKj9lbmQtY29sdW1uXFxzKj89ezN9XFxzKj8kXFxuPy9tLFxuICAgIC9ePXszfVxccyo/Y29sdW1uLWJyZWFrXFxzKj89ezN9XFxzKj8kXFxuPy9tLFxuICAgIC9ePXszfVxccyo/YnJlYWstY29sdW1uXFxzKj89ezN9XFxzKj8kXFxuPy9tLFxuICAgIC9eICo/KD86XFxcXD8pXFxcXGNvbHVtbmJyZWFrICo/JFxcbj8vbSxcbiAgICAvXjp7Myx9ICpjb2x1bW4tP2JyZWFrICooPzooPzokXFxuXik/fCAqKTp7Myx9ICokL21cbl1cbmV4cG9ydCBmdW5jdGlvbiBjaGVja0ZvclBhcmFncmFwaElubmVyQ29sRW5kVGFnKHRleHQ6IHN0cmluZyk6IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGwge1xuXG4gICAgZm9yKGxldCBpID0gMDsgaTwgSU5ORVJfQ09MX0VORF9SRUdFWF9BUlIubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICBsZXQgcmVnZXhSZXN1bHQgPSBJTk5FUl9DT0xfRU5EX1JFR0VYX0FSUltpXS5leGVjKHRleHQpO1xuICAgICAgICBpZihyZWdleFJlc3VsdCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlZ2V4UmVzdWx0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBDT0xfRUxFTUVOVF9JTk5FUl9URVhUX1JFR0VYX1NUUlM6IHN0cmluZ1tdID0gW1wiPSAqY29sdW1uLWVuZCAqPVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiPSAqZW5kLWNvbHVtbiAqPVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiPSAqY29sdW1uLWJyZWFrICo9XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCI9ICpicmVhay1jb2x1bW4gKj1cIl1cbmNvbnN0IENPTF9FTEVNRU5UX0lOTkVSX1RFWFRfUkVHRVhfQVJSOiBSZWdFeHBbXSA9IFtdO1xuZm9yKGxldCBpID0gMDsgaSA8IENPTF9FTEVNRU5UX0lOTkVSX1RFWFRfUkVHRVhfU1RSUy5sZW5ndGg7IGkrKykge1xuICAgIENPTF9FTEVNRU5UX0lOTkVSX1RFWFRfUkVHRVhfQVJSLnB1c2gobmV3IFJlZ0V4cChDT0xfRUxFTUVOVF9JTk5FUl9URVhUX1JFR0VYX1NUUlNbaV0pKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBlbElubmVyVGV4dENvbnRhaW5zQ29sRW5kVGFnKHRleHQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuXG4gICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgZm9yKGxldCBpID0gMDsgaTwgQ09MX0VMRU1FTlRfSU5ORVJfVEVYVF9SRUdFWF9BUlIubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICBpZihDT0xfRUxFTUVOVF9JTk5FUl9URVhUX1JFR0VYX0FSUltpXS50ZXN0KHRleHQpKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmb3VuZDtcbn1cblxuY29uc3QgQ09MX1NFVFRJTkdTX1JFR0VYX1NUUlMgPSBbXCJgYGBzZXR0aW5nc1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJgYGBjb2x1bW4tc2V0dGluZ3NcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYGBgbXVsdGktY29sdW1uLXNldHRpbmdzXCJdO1xuY29uc3QgQ09MX1NFVFRJTkdTX1JFR0VYX0FSUjogUmVnRXhwW10gPSBbXTtcbmZvcihsZXQgaSA9IDA7IGkgPCBDT0xfU0VUVElOR1NfUkVHRVhfU1RSUy5sZW5ndGg7IGkrKykge1xuICAgIENPTF9TRVRUSU5HU19SRUdFWF9BUlIucHVzaChuZXcgUmVnRXhwKENPTF9TRVRUSU5HU19SRUdFWF9TVFJTW2ldKSk7XG59XG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNDb2xTZXR0aW5nc1RhZyh0ZXh0OiBzdHJpbmcpOiBib29sZWFuIHtcblxuICAgIGxldCBmb3VuZCA9IGZhbHNlO1xuICAgIGZvcihsZXQgaSA9IDA7IGk8IENPTF9TRVRUSU5HU19SRUdFWF9BUlIubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICBpZihDT0xfU0VUVElOR1NfUkVHRVhfQVJSW2ldLnRlc3QodGV4dCkpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZvdW5kO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZFNldHRpbmdzQ29kZWJsb2NrKHRleHQ6IHN0cmluZyk6IFN0YXJ0VGFnUmVnZXhNYXRjaCB7XG5cbiAgICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgICBsZXQgc3RhcnRQb3NpdGlvbiA9IC0xO1xuICAgIGxldCBlbmRQb3NpdGlvbiA9IC0xXG4gICAgbGV0IG1hdGNoTGVuZ3RoID0gMDtcbiAgICBmb3IobGV0IGkgPSAwOyBpPCBDT0xfU0VUVElOR1NfUkVHRVhfQVJSLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgbGV0IHJlZ2V4RGF0YSA9IENPTF9TRVRUSU5HU19SRUdFWF9BUlJbaV0uZXhlYyh0ZXh0KVxuICAgICAgICBpZihyZWdleERhdGEgIT09IG51bGwgJiYgcmVnZXhEYXRhLmxlbmd0aCA+IDApIHtcblxuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgc3RhcnRQb3NpdGlvbiA9IHJlZ2V4RGF0YS5pbmRleFxuICAgICAgICAgICAgbWF0Y2hMZW5ndGggPSByZWdleERhdGFbMF0ubGVuZ3RoO1xuICAgICAgICAgICAgZW5kUG9zaXRpb24gPSBzdGFydFBvc2l0aW9uICsgbWF0Y2hMZW5ndGg7XG5cbiAgICAgICAgICAgIGxldCByZW1haW5pbmdUZXh0ID0gdGV4dC5zbGljZShlbmRQb3NpdGlvbilcbiAgICAgICAgICAgIHJlZ2V4RGF0YSA9IENPREVCTE9DS19FTkRfUkVHRVguZXhlYyhyZW1haW5pbmdUZXh0KVxuICAgICAgICAgICAgaWYocmVnZXhEYXRhICE9PSBudWxsICYmIHJlZ2V4RGF0YS5sZW5ndGggPiAwKSB7XG5cbiAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgZW5kUG9zaXRpb24gKz0gcmVnZXhEYXRhLmluZGV4ICsgcmVnZXhEYXRhWzBdLmxlbmd0aCBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgXG4gICAgICAgIGZvdW5kLCBcbiAgICAgICAgc3RhcnRQb3NpdGlvbiwgXG4gICAgICAgIGVuZFBvc2l0aW9uLCBcbiAgICAgICAgbWF0Y2hMZW5ndGgsXG4gICAgICAgIHJlZ2lvblR5cGU6IFwiQ09ERUJMT0NLXCJcbiAgICB9O1xufVxuXG5jb25zdCBDT0RFQkxPQ0tfU1RBUlRfUkVHRVhfU1RSOiBzdHJpbmcgPSBbXG5cIm11bHRpLWNvbHVtbi1zdGFydFwiLFxuXCJzdGFydC1tdWx0aS1jb2x1bW5cIlxuXS5yZWR1Y2UoKHByZXYsIGN1cikgPT4ge1xuICAgIGlmKHByZXYgPT09IFwiXCIpIHtcbiAgICAgICAgcmV0dXJuIGN1cjtcbiAgICB9XG4gICAgcmV0dXJuIGAke3ByZXZ9fCR7Y3VyfWA7XG59LCBcIlwiKVxuY29uc3QgU1RBUlRfQ09ERUJMT0NLX1JFR0VYOiBSZWdFeHAgPSBuZXcgUmVnRXhwKGBcXGBcXGBcXGAoOj8ke0NPREVCTE9DS19TVEFSVF9SRUdFWF9TVFJ9KSguKj8pXFxgXFxgXFxgYCwgXCJtc1wiKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRTdGFydENvZGVibG9jayh0ZXh0OiBzdHJpbmcpOiBTdGFydFRhZ1JlZ2V4TWF0Y2gge1xuXG4gICAgbGV0IHN0YXJ0UmVnaW9uID0gZGVmYXVsdFN0YXJ0UmVnaW9uRGF0YSgpO1xuICAgIHN0YXJ0UmVnaW9uLnJlZ2lvblR5cGUgPSBcIkNPREVCTE9DS1wiO1xuXG4gICAgbGV0IHJlZ2V4RGF0YSA9IFNUQVJUX0NPREVCTE9DS19SRUdFWC5leGVjKHRleHQpXG4gICAgaWYocmVnZXhEYXRhICE9PSBudWxsICYmIHJlZ2V4RGF0YS5sZW5ndGggPiAwKSB7XG5cbiAgICAgICAgc3RhcnRSZWdpb24uZm91bmQgPSB0cnVlO1xuICAgICAgICBzdGFydFJlZ2lvbi5zdGFydFBvc2l0aW9uID0gcmVnZXhEYXRhLmluZGV4XG4gICAgICAgIHN0YXJ0UmVnaW9uLm1hdGNoTGVuZ3RoID0gcmVnZXhEYXRhWzBdLmxlbmd0aDtcbiAgICAgICAgc3RhcnRSZWdpb24uZW5kUG9zaXRpb24gPSBzdGFydFJlZ2lvbi5zdGFydFBvc2l0aW9uICsgc3RhcnRSZWdpb24ubWF0Y2hMZW5ndGg7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXJ0UmVnaW9uO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5zU3RhcnRDb2RlQmxvY2sodGV4dDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZpbmRTdGFydENvZGVibG9jayh0ZXh0KS5mb3VuZFxufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNSZWdpb25TdGFydCh0ZXh0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gY29udGFpbnNTdGFydENvZGVCbG9jayh0ZXh0KSB8fCBjb250YWluc1N0YXJ0VGFnKHRleHQpIHx8IGNvbnRhaW5zUGFuZG9jKHRleHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY291bnRTdGFydFRhZ3MoaW5pdGlhbFRleHQ6IHN0cmluZyk6IHsgbnVtYmVyT2ZUYWdzOiBudW1iZXIsIGtleXM6IHN0cmluZ1tdIH0ge1xuXG4gICAgbGV0IGtleXM6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IHRleHQgPSBpbml0aWFsVGV4dFxuICAgIGxldCBzdGFydFRhZ0RhdGEgPSBmaW5kU3RhcnRUYWcodGV4dCk7XG4gICAgd2hpbGUoc3RhcnRUYWdEYXRhLmZvdW5kKSB7XG4gICAgICAgIFxuICAgICAgICAvLyBTbGljZSBvZmYgZXZlcnl0aGluZyBiZWZvcmUgdGhlIHRhZ1xuICAgICAgICB0ZXh0ID0gdGV4dC5zbGljZShzdGFydFRhZ0RhdGEuc3RhcnRQb3NpdGlvbik7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldCBqdXN0IHRoZSBzdGFydCB0YWcgbGluZSBhbmQgdGhlbiBzZXQgdGV4dCB0byBldmVyeXRoaW5nIGp1c3RcbiAgICAgICAgICogYWZ0ZXIgdGhlIHN0YXJ0IHRhZy5cbiAgICAgICAgICovXG4gICAgICAgIGxldCB0YWcgPSB0ZXh0LnNwbGl0KFwiXFxuXCIpWzBdO1xuICAgICAgICB0ZXh0ID0gdGV4dC5zbGljZSgxKTsgLy8gVGhpcyBtb3ZlcyB0aGUgdGV4dCAxIGNoYXJhY3RlciBzbyB3ZSBkb250IG1hdGNoIHRoZSBzYW1lIHRhZy5cblxuICAgICAgICAvLyBQYXJzZSBvdXQgdGhlIGtleSBhbmQgYXBwZW5kIHRvIHRoZSBsaXN0LlxuICAgICAgICBsZXQga2V5ID0gZ2V0U3RhcnRUYWdLZXkodGFnKTtcbiAgICAgICAgaWYoa2V5ID09PSBudWxsKSB7XG4gICAgICAgICAgICBrZXkgPSBcIlwiXG4gICAgICAgIH1cbiAgICAgICAga2V5cy5wdXNoKGtleSk7XG5cbiAgICAgICAgLy8gU2VhcmNoIGFnYWluIGZvciBhbm90aGVyIHRhZyBiZWZvcmUgbG9vcGluZy5cbiAgICAgICAgc3RhcnRUYWdEYXRhID0gZmluZFN0YXJ0VGFnKHRleHQpO1xuICAgIH1cblxuICAgIHRleHQgPSBpbml0aWFsVGV4dDtcbiAgICBzdGFydFRhZ0RhdGEgPSBmaW5kU3RhcnRDb2RlYmxvY2sodGV4dCk7XG4gICAgd2hpbGUoc3RhcnRUYWdEYXRhLmZvdW5kKSB7XG4gICAgICAgIFxuICAgICAgICBsZXQgc2V0dGluZ3NUZXh0ID0gdGV4dC5zbGljZShzdGFydFRhZ0RhdGEuc3RhcnRQb3NpdGlvbiwgc3RhcnRUYWdEYXRhLmVuZFBvc2l0aW9uKTtcbiAgICAgICAgdGV4dCA9IHRleHQuc2xpY2Uoc3RhcnRUYWdEYXRhLmVuZFBvc2l0aW9uKTtcblxuICAgICAgICBsZXQga2V5ID0gcGFyc2VTdGFydFJlZ2lvbkNvZGVCbG9ja0lEKHNldHRpbmdzVGV4dCk7XG4gICAgICAgIGlmKGtleSA9PT0gbnVsbCkge1xuICAgICAgICAgICAga2V5ID0gXCJcIlxuICAgICAgICB9XG4gICAgICAgIGtleXMucHVzaChrZXkpO1xuXG4gICAgICAgIC8vIFNlYXJjaCBhZ2FpbiBmb3IgYW5vdGhlciB0YWcgYmVmb3JlIGxvb3BpbmcuXG4gICAgICAgIHN0YXJ0VGFnRGF0YSA9IGZpbmRTdGFydENvZGVibG9jayh0ZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBudW1iZXJPZlRhZ3M6IGtleXMubGVuZ3RoLCBrZXlzIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhcnRUYWdEYXRhIHtcbiAgICBzdGFydEJsb2NrS2V5OiBzdHJpbmc7XG4gICAgbGluZXNBYm92ZUFycmF5OiBzdHJpbmdbXTtcbiAgICBzdGFydEJsb2NrVHlwZTogUmVnaW9uVHlwZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdGFydERhdGFBYm92ZUxpbmUobGluZXNBYm92ZUFycmF5OiBzdHJpbmdbXSk6IFN0YXJ0VGFnRGF0YSB7XG4gICAgcmV0dXJuIGdldFN0YXJ0QmxvY2tPckNvZGVibG9ja0Fib3ZlTGluZShsaW5lc0Fib3ZlQXJyYXksIFtcbiAgICAgICAgZmluZFN0YXJ0VGFnLFxuICAgICAgICBmaW5kU3RhcnRDb2RlYmxvY2ssXG4gICAgICAgIGZpbmRQYW5kb2NTdGFydFxuICAgIF0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdGFydEJsb2NrT3JDb2RlYmxvY2tBYm92ZUxpbmUobGluZXNBYm92ZUFycmF5OiBzdHJpbmdbXSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlYXJjaEZ1bmN0aW9uczogKCh0ZXh0OiBzdHJpbmcpID0+IFN0YXJ0VGFnUmVnZXhNYXRjaClbXSk6IHsgc3RhcnRCbG9ja0tleTogc3RyaW5nLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lc0Fib3ZlQXJyYXk6IHN0cmluZ1tdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0QmxvY2tUeXBlOiBSZWdpb25UeXBlICB9IHwgbnVsbCB7XG5cbiAgICBsZXQgb3JpZ2luYWxUZXh0ID0gbGluZXNBYm92ZUFycmF5LmpvaW4oXCJcXG5cIik7XG4gICAgbGV0IHt0YWdNYXRjaERhdGEsIGxhc3RGb3VuZFRhZywgdGV4dEFib3ZlfSA9ICBmaW5kTGFzdFZhbGlkVGFnKG9yaWdpbmFsVGV4dCk7XG5cbiAgICBpZih0YWdNYXRjaERhdGEgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYodGFnTWF0Y2hEYXRhLmZvdW5kID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZih0YWdNYXRjaERhdGEucmVnaW9uVHlwZSA9PT0gXCJDT0RFQkxPQ0tcIikge1xuICAgIFxuICAgICAgICBsZXQgZW5kVGFnU2VyYWNoRGF0YSA9IGZpbmRFbmRUYWcodGV4dEFib3ZlKTtcbiAgICAgICAgaWYoZW5kVGFnU2VyYWNoRGF0YS5mb3VuZCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3RhcnRCbG9ja0tleSA9IHBhcnNlU3RhcnRSZWdpb25Db2RlQmxvY2tJRChsYXN0Rm91bmRUYWcpO1xuICAgICAgICBsZXQgbGluZXNBYm92ZUFycmF5ID0gdGV4dEFib3ZlLnNwbGl0KFwiXFxuXCIpO1xuXG4gICAgICAgIHJldHVybiB7IHN0YXJ0QmxvY2tLZXksIGxpbmVzQWJvdmVBcnJheSwgc3RhcnRCbG9ja1R5cGU6IFwiQ09ERUJMT0NLXCIgfTtcbiAgICB9XG5cbiAgICBpZih0YWdNYXRjaERhdGEucmVnaW9uVHlwZSA9PT0gXCJPUklHSU5BTFwiKSB7XG4gICAgXG4gICAgICAgIGxldCBlbmRUYWdTZXJhY2hEYXRhID0gZmluZEVuZFRhZyh0ZXh0QWJvdmUpO1xuICAgICAgICBpZihlbmRUYWdTZXJhY2hEYXRhLmZvdW5kID09PSB0cnVlKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBsaW5lc0Fib3ZlQXJyYXkgPSB0ZXh0QWJvdmUuc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIGxldCBzdGFydEJsb2NrS2V5ID0gZ2V0U3RhcnRUYWdLZXkobGFzdEZvdW5kVGFnKTtcblxuICAgICAgICBsZXQgY29kZUJsb2NrRGF0YSA9IHBhcnNlQ29kZUJsb2NrU3RhcnQobGluZXNBYm92ZUFycmF5KVxuICAgICAgICBpZihjb2RlQmxvY2tEYXRhICE9PSBudWxsKSB7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHN0YXJ0QmxvY2tLZXkgPSBjb2RlQmxvY2tEYXRhLmlkO1xuICAgICAgICAgICAgaWYoY29kZUJsb2NrRGF0YS5pbmRleCA+IDApIHtcbiAgICAgICAgICAgICAgICBsaW5lc0Fib3ZlQXJyYXkgPSBsaW5lc0Fib3ZlQXJyYXkuc2xpY2UoY29kZUJsb2NrRGF0YS5pbmRleCArIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYoc3RhcnRCbG9ja0tleSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgc3RhcnRCbG9ja0tleSA9IFwiXCI7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBzdGFydEJsb2NrS2V5LCBsaW5lc0Fib3ZlQXJyYXksIHN0YXJ0QmxvY2tUeXBlOiBcIk9SSUdJTkFMXCIgfTtcbiAgICB9XG5cbiAgICBpZih0YWdNYXRjaERhdGEucmVnaW9uVHlwZSA9PT0gXCJQQURPQ1wiKSB7XG5cbiAgICAgICAgbGV0IGVuZFRhZ1NlcmFjaERhdGEgPSByZWR1Y2VQYW5kb2NSZWdpb25Ub0VuZERpdih0ZXh0QWJvdmUpXG4gICAgICAgIGlmKGVuZFRhZ1NlcmFjaERhdGEuZm91bmQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGxpbmVzQWJvdmVBcnJheSA9IHRleHRBYm92ZS5zcGxpdChcIlxcblwiKTtcblxuICAgICAgICBsZXQgcGFuZG9jRGF0YSA9IGdldFBhbmRvY1N0YXJ0RGF0YShgJHtsYXN0Rm91bmRUYWd9YCk7XG4gICAgICAgIGxldCBzdGFydEJsb2NrS2V5ID0gcGFuZG9jRGF0YS51c2VyU2V0dGluZ3MuY29sdW1uSUQ7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0QmxvY2tLZXksXG4gICAgICAgICAgICBsaW5lc0Fib3ZlQXJyYXksXG4gICAgICAgICAgICBzdGFydEJsb2NrVHlwZTogXCJQQURPQ1wiXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcblxuICAgIGZ1bmN0aW9uIGZpbmRMYXN0VmFsaWRUYWcob3JpZ2luYWxUZXh0OiBzdHJpbmcpIHtcblxuICAgICAgICBsZXQgdGV4dEFib3ZlID0gb3JpZ2luYWxUZXh0O1xuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAgICAgbGV0IHRhZ01hdGNoRGF0YTogU3RhcnRUYWdSZWdleE1hdGNoID0gbnVsbDtcbiAgICAgICAgbGV0IGxhc3RGb3VuZFRhZyA9IFwiXCJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IHRydWU7IGkrKykge1xuICAgICAgICAgICAgaWYgKGkgPiAxMDApIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHRhZ3NGb3VuZDogU3RhcnRUYWdSZWdleE1hdGNoW10gPSBbXTtcbiAgICAgICAgICAgIHNlYXJjaEZ1bmN0aW9ucy5mb3JFYWNoKChmdW5jKSA9PiB7XG4gICAgICAgICAgICAgICAgdGFnc0ZvdW5kLnB1c2goZnVuYyh0ZXh0QWJvdmUpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGFnc0ZvdW5kID0gdGFnc0ZvdW5kLmZpbHRlcigodmFsKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbC5mb3VuZCA9PT0gdHJ1ZTtcbiAgICAgICAgICAgIH0pLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYS5zdGFydFBvc2l0aW9uIC0gYi5zdGFydFBvc2l0aW9uO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICh0YWdzRm91bmQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRhZ01hdGNoRGF0YSA9IHRhZ3NGb3VuZFswXTtcbiAgICAgICAgICAgIGxldCBzdGFydEluZGV4ID0gb2Zmc2V0ICsgdGFnTWF0Y2hEYXRhLnN0YXJ0UG9zaXRpb247XG4gICAgICAgICAgICBsYXN0Rm91bmRUYWcgPSBvcmlnaW5hbFRleHQuc2xpY2Uoc3RhcnRJbmRleCwgc3RhcnRJbmRleCArIHRhZ01hdGNoRGF0YS5tYXRjaExlbmd0aCkudHJpbUVuZCgpO1xuXG4gICAgICAgICAgICBvZmZzZXQgKz0gKHRhZ01hdGNoRGF0YS5zdGFydFBvc2l0aW9uICsgdGFnTWF0Y2hEYXRhLm1hdGNoTGVuZ3RoKTtcbiAgICAgICAgICAgIHRleHRBYm92ZSA9IG9yaWdpbmFsVGV4dC5zbGljZShvZmZzZXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRhZ01hdGNoRGF0YSxcbiAgICAgICAgICAgIGxhc3RGb3VuZFRhZyxcbiAgICAgICAgICAgIHRleHRBYm92ZVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBmaWx0ZXIgYSBzZXQgb2Ygc3RyaW5ncywgcmV0dXJuaW5nIGFsbCBpdGVtcyBzdGFydGluZ1xuICogZnJvbSB0aGUgY2xvc2VzdCBvcGVuIHN0YXJ0IHRhZyB0aHJvdWdoIHRoZSBsYXN0IGl0ZW0gaW4gdGhlIHNldC4gXG4gKiBcbiAqIFRoZSBmdW5jdGlvbiBmaWx0ZXJzIG91dCBhbGwgZW5kIHRhZ3MgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHN0YXJ0IHRhZyB3ZSBcbiAqIGZpbmQgaXMgdGhlIHByb3BlciBzdGFydCB0YWcgZm9yIHRoZSBsaXN0IHNlbnQuIFxuICogQHBhcmFtIGxpbmVzQWJvdmVBcnJheSBcbiAqIEByZXR1cm5zIFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RhcnRCbG9ja0Fib3ZlTGluZShsaW5lc0Fib3ZlQXJyYXk6IHN0cmluZ1tdKTogeyBzdGFydEJsb2NrS2V5OiBzdHJpbmcsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lc0Fib3ZlQXJyYXk6IHN0cmluZ1tdIH0gfCBudWxsIHtcblxuICAgIHJldHVybiBnZXRTdGFydEJsb2NrT3JDb2RlYmxvY2tBYm92ZUxpbmUobGluZXNBYm92ZUFycmF5LCBbZmluZFN0YXJ0VGFnXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbmRCbG9ja0JlbG93KGxpbmVzQmVsb3c6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuXG4gICAgLy8gUmVkdWNlIHRoZSBhcnJheSBkb3duIGludG8gYSBzaW5nbGUgc3RyaW5nIHNvIHRoYXQgd2UgY2FuXG4gICAgLy8gZWFzaWx5IFJlZ0V4IG92ZXIgdGhlIHN0cmluZyBhbmQgZmluZCB0aGUgaW5kaWNpZXMgd2UncmUgbG9va2luZyBmb3IuXG4gICAgbGV0IGxpbmVzQmVsb3dTdHIgPSBsaW5lc0JlbG93LnJlZHVjZSgocHJldiwgY3VycmVudCkgPT4ge1xuICAgICAgICByZXR1cm4gcHJldiArIFwiXFxuXCIgICsgY3VycmVudDtcbiAgICB9LCBcIlwiKTtcbiAgICBsZXQgZW5kVGFnU2VyYWNoRGF0YSA9IGZpbmRFbmRUYWcobGluZXNCZWxvd1N0cik7XG4gICAgbGV0IHN0YXJ0VGFnU2VhcmNoRGF0YSA9IGZpbmRTdGFydFRhZyhsaW5lc0JlbG93U3RyKTtcblxuICAgIGxldCBzbGljZUVuZEluZGV4ID0gLTE7IC8vIElmIG5laXRoZXIgc3RhcnQgb3IgZW5kIGZvdW5kIHdlIHJldHVybiB0aGUgZW50aXJlIGFycmF5LlxuICAgIGlmKGVuZFRhZ1NlcmFjaERhdGEuZm91bmQgPT09IHRydWUgJiYgc3RhcnRUYWdTZWFyY2hEYXRhLmZvdW5kID09PSBmYWxzZSkge1xuXG4gICAgICAgIHNsaWNlRW5kSW5kZXggPSBlbmRUYWdTZXJhY2hEYXRhLnN0YXJ0UG9zaXRpb247XG4gICAgfVxuICAgIGVsc2UgaWYoZW5kVGFnU2VyYWNoRGF0YS5mb3VuZCA9PT0gZmFsc2UgJiYgc3RhcnRUYWdTZWFyY2hEYXRhLmZvdW5kID09PSB0cnVlKSB7XG5cbiAgICAgICAgc2xpY2VFbmRJbmRleCA9IHN0YXJ0VGFnU2VhcmNoRGF0YS5zdGFydFBvc2l0aW9uO1xuICAgIH1cbiAgICBlbHNlIGlmKGVuZFRhZ1NlcmFjaERhdGEuZm91bmQgPT09IHRydWUgJiYgc3RhcnRUYWdTZWFyY2hEYXRhLmZvdW5kID09PSB0cnVlKSB7XG5cbiAgICAgICAgc2xpY2VFbmRJbmRleCA9IGVuZFRhZ1NlcmFjaERhdGEuc3RhcnRQb3NpdGlvbjtcbiAgICAgICAgaWYoc3RhcnRUYWdTZWFyY2hEYXRhLnN0YXJ0UG9zaXRpb24gPCBlbmRUYWdTZXJhY2hEYXRhLnN0YXJ0UG9zaXRpb24pIHtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBJZiB3ZSBmb3VuZCBhIHN0YXJ0IHRhZyBiZWZvcmUgYW4gZW5kIHRhZyB3ZSB3YW50IHRvIHVzZSB0aGUgc3RhcnQgdGFnXG4gICAgICAgICAgICAgKiBvdXIgY3VycmVudCBibG9jayBpcyBub3QgcHJvcGVybHkgZW5kZWQgYW5kIHdlIHVzZSB0aGUgbmV4dCBzdGFydCB0YWcgXG4gICAgICAgICAgICAgKiBhcyBvdXIgbGltaXRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgc2xpY2VFbmRJbmRleCA9IHN0YXJ0VGFnU2VhcmNoRGF0YS5zdGFydFBvc2l0aW9uO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbmVzQmVsb3cuc2xpY2UoMCwgc2xpY2VFbmRJbmRleCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdGFydFRhZ0tleShzdGFydFRhZzogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG5cbiAgICBsZXQga2V5U3BsaXQgPSBzdGFydFRhZy5zcGxpdChcIjpcIik7XG4gICAgaWYoa2V5U3BsaXQubGVuZ3RoID4gMSl7XG4gICAgICAgIHJldHVybiBrZXlTcGxpdFsxXS5yZXBsYWNlKFwiIFwiLCBcIlwiKVxuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xufVxuXG5cbmNvbnN0IFRBQl9IRUFERVJfRU5EX1JFR0VYX1NUUiA9IFwiXmBgYCRcIjtcbmNvbnN0IFRBQl9IRUFERVJfRU5EX1JFR0VYOiBSZWdFeHAgPSBuZXcgUmVnRXhwKFRBQl9IRUFERVJfRU5EX1JFR0VYX1NUUik7XG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDb2RlQmxvY2tTdGFydChjb2RlQmxvY2tMaW5lczogc3RyaW5nW10pOiB7IGlkOiBzdHJpbmcsIGluZGV4OiBudW1iZXJ9IHwgbnVsbCB7XG5cbiAgICBsZXQgaWQgPSBudWxsO1xuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBjb2RlQmxvY2tMaW5lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgbGluZSA9IGNvZGVCbG9ja0xpbmVzW2ldO1xuXG4gICAgICAgIGlmKGlkID09PSBudWxsKSB7XG4gICAgICAgICAgICBsZXQga2V5ID0gbGluZS5zcGxpdChcIjpcIilbMF07XG4gICAgICAgICAgICBpZihrZXkudG9Mb3dlckNhc2UoKSA9PT0gXCJyZWdpb24gaWRcIikge1xuICAgICAgICAgICAgICAgIGlkID0gbGluZS5zcGxpdChcIjpcIilbMV0udHJpbSgpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZihUQUJfSEVBREVSX0VORF9SRUdFWC50ZXN0KGxpbmUpKSB7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4geyBpZDogaWQsIGluZGV4OiBpIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZihpZCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiB7IGlkOiBpZCwgaW5kZXg6IC0xIH1cbiAgICB9XG59XG5jb25zdCBDT0RFQkxPQ0tfRU5EX1JFR0VYX1NUUiA9IFwiYGBgXCI7XG5jb25zdCBDT0RFQkxPQ0tfRU5EX1JFR0VYOiBSZWdFeHAgPSBuZXcgUmVnRXhwKENPREVCTE9DS19FTkRfUkVHRVhfU1RSKTtcbmV4cG9ydCBmdW5jdGlvbiBmaW5kRW5kT2ZDb2RlQmxvY2sodGV4dDogc3RyaW5nKTogeyBmb3VuZDogYm9vbGVhbiwgc3RhcnRQb3NpdGlvbjogbnVtYmVyLCBlbmRQb3NpdGlvbjogbnVtYmVyLCBtYXRjaExlbmd0aDogbnVtYmVyIH0ge1xuXG4gICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgbGV0IHN0YXJ0UG9zaXRpb24gPSAtMTtcbiAgICBsZXQgbWF0Y2hMZW5ndGggPSAwO1xuICAgIGxldCBlbmRQb3NpdGlvbiA9IC0xO1xuXG4gICAgbGV0IHJlZ2V4RGF0YSA9IENPREVCTE9DS19FTkRfUkVHRVguZXhlYyh0ZXh0KVxuICAgIGlmKHJlZ2V4RGF0YSAhPT0gbnVsbCAmJiByZWdleERhdGEubGVuZ3RoID4gMCkge1xuICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgIHN0YXJ0UG9zaXRpb24gPSByZWdleERhdGEuaW5kZXhcbiAgICAgICAgbWF0Y2hMZW5ndGggPSByZWdleERhdGFbMF0ubGVuZ3RoXG4gICAgfVxuICAgIGVuZFBvc2l0aW9uID0gc3RhcnRQb3NpdGlvbiArIG1hdGNoTGVuZ3RoO1xuXG4gICAgcmV0dXJuIHsgZm91bmQsIHN0YXJ0UG9zaXRpb24sIGVuZFBvc2l0aW9uLCBtYXRjaExlbmd0aCB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDb2RlQmxvY2tTZXR0aW5ncyhjb2RlQmxvY2tMaW5lczogc3RyaW5nW10pOiBzdHJpbmcge1xuXG4gICAgbGV0IHNldHRpbmdzTGluZXMgPSBbXTtcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgY29kZUJsb2NrTGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IGxpbmUgPSBjb2RlQmxvY2tMaW5lc1tpXTtcblxuICAgICAgICBsZXQga2V5ID0gbGluZS5zcGxpdChcIjpcIilbMF07XG4gICAgICAgIGlmKGtleS50b0xvd2VyQ2FzZSgpICE9PSBcInJlZ2lvbiBpZFwiKSB7XG4gICAgICAgICAgICBzZXR0aW5nc0xpbmVzLnB1c2gobGluZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2V0dGluZ3NMaW5lcy5qb2luKFwiXFxuXCIpO1xufSIsIi8qXG4gKiBGaWxlbmFtZTogbXVsdGktY29sdW1uLW1hcmtkb3duL3NyYy91dGlsaXRpZXMvdXRpbHMudHNcbiAqIENyZWF0ZWQgRGF0ZTogVHVlc2RheSwgSmFudWFyeSAzMHRoIDIwMjIsIDQ6MDI6MTkgcG1cbiAqIEF1dGhvcjogQ2FtZXJvbiBSb2JpbnNvblxuICogXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjIgQ2FtZXJvbiBSb2JpbnNvblxuICovXG5cbmltcG9ydCB7IFdvcmtzcGFjZUxlYWYgfSBmcm9tIFwib2JzaWRpYW5cIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVJRChsZW5ndGg6IG51bWJlciA9IDEwKTogc3RyaW5nIHtcblxuICAgIGlmKGxlbmd0aCA+IDEwKSB7XG4gICAgICAgIGxlbmd0aCA9IDEwO1xuICAgIH1cbiAgICBsZXQgVUlEID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDIpO1xuICAgIFVJRCA9IFVJRC5zbGljZSgwLCBsZW5ndGgpO1xuICAgIFxuICAgIHJldHVybiBVSUQ7XG59XG5cbi8qKlxuICogQkZTIG9uIHRoZSBjaGlsZCBub2RlcyBvZiB0aGUgcGFzc2VkIGVsZW1lbnQgc2VhcmNoaW5nIGZvciB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgdGhlXG4gKiBub2RlIHR5cGUgcGFzc2VkLiBSZXR1cm5pbmcgdGhlIGVsZW1lbnQgZm91bmQgb3IgbnVsbCBpZiBub25lIGZvdW5kLlxuICogXG4gKiBAcGFyYW0gcm9vdCBcbiAqIEBwYXJhbSBub2RlVHlwZU5hbWVcbiAqIEByZXR1cm5zIFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VhcmNoQ2hpbGRyZW5Gb3JOb2RlVHlwZShyb290OiBIVE1MRWxlbWVudCwgbm9kZVR5cGVOYW1lOiBzdHJpbmcpOiBIVE1MRWxlbWVudCB8IG51bGwge1xuXG4gICAgbm9kZVR5cGVOYW1lID0gbm9kZVR5cGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgbGV0IHF1ZXVlOiBIVE1MRWxlbWVudFtdID0gW3Jvb3RdXG4gICAgd2hpbGUocXVldWUubGVuZ3RoID4gMCl7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBsZXQgbm9kZSA9IHF1ZXVlLnNoaWZ0KClcblxuICAgICAgICAgICAgbGV0IG5vZGVOYW1lID0gbm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICBpZihub2RlTmFtZSA9PT0gbm9kZVR5cGVOYW1lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcXVldWUucHVzaChub2RlLmNoaWxkcmVuW2ldIGFzIEhUTUxFbGVtZW50KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZWFyY2hDaGlsZHJlbkZvck5vZGVzT2ZUeXBlKHJvb3Q6IEhUTUxFbGVtZW50LCBub2RlVHlwZU5hbWU6IHN0cmluZywgcGFyZW50Q2xhc3M6IHN0cmluZyk6IEhUTUxFbGVtZW50W10gfCBudWxsIHtcbiAgICBsZXQgZWxGb3VuZCA9IHNlYXJjaENoaWxkcmVuRm9yTm9kZVR5cGUocm9vdCwgbm9kZVR5cGVOYW1lKVxuICAgIGlmKGVsRm91bmQgIT09IG51bGwpIHtcblxuICAgICAgICBsZXQgY3VycmVudFBhcmVudCA9IGVsRm91bmQucGFyZW50RWxlbWVudDtcbiAgICAgICAgd2hpbGUoY3VycmVudFBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYoY3VycmVudFBhcmVudC5oYXNDbGFzcyhwYXJlbnRDbGFzcykpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBjdXJyZW50UGFyZW50LnBhcmVudEVsZW1lbnRcbiAgICAgICAgfVxuICAgICAgICBpZihjdXJyZW50UGFyZW50ID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNhbnZhc2VzOiBIVE1MRWxlbWVudFtdID0gW107XG4gICAgICAgIGZvcihsZXQgY2hpbGQgb2YgQXJyYXkuZnJvbShjdXJyZW50UGFyZW50LmNoaWxkcmVuKSkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBsZXQgY2FudmFzID0gc2VhcmNoQ2hpbGRyZW5Gb3JOb2RlVHlwZShjaGlsZCBhcyBIVE1MRWxlbWVudCwgbm9kZVR5cGVOYW1lKVxuICAgICAgICAgICAgaWYoY2FudmFzICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY2FudmFzZXMucHVzaChjYW52YXMpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYoY2FudmFzZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbnZhc2VzXG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGaWxlU291cmNlTW9kZShzb3VyY2VQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuXG4gICAgbGV0IGZpbGVMZWFmID0gZ2V0RmlsZUxlYWYoc291cmNlUGF0aCk7XG4gICAgaWYoZmlsZUxlYWYgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuICAgIHJldHVybiBmaWxlTGVhZi5nZXRWaWV3U3RhdGUoKS5zdGF0ZS5tb2RlO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldExlYWZTb3VyY2VNb2RlKGZpbGVMZWFmOiBXb3Jrc3BhY2VMZWFmKTogc3RyaW5nIHtcblxuICAgIHJldHVybiBmaWxlTGVhZi5nZXRWaWV3U3RhdGUoKS5zdGF0ZS5tb2RlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlsZVN0aWxsSW5WaWV3KHNvdXJjZVBhdGg6IHN0cmluZyk6Ym9vbGVhbiB7XG5cbiAgICBsZXQgZmlsZUxlYWYgPSBnZXRGaWxlTGVhZihzb3VyY2VQYXRoKTtcbiAgICBpZihmaWxlTGVhZiA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZUxlYWYoc291cmNlUGF0aDogc3RyaW5nKTogV29ya3NwYWNlTGVhZiB8IG51bGwge1xuXG4gICAgbGV0IG1hcmtkb3duTGVhdmVzID0gYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoXCJtYXJrZG93blwiKTtcbiAgICBpZihtYXJrZG93bkxlYXZlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgZm9yKGxldCBpID0gMDsgaSA8IG1hcmtkb3duTGVhdmVzLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgaWYobWFya2Rvd25MZWF2ZXNbaV0uZ2V0Vmlld1N0YXRlKCkuc3RhdGUuZmlsZSA9PT0gc291cmNlUGF0aCkge1xuICAgICAgICAgICAgcmV0dXJuIG1hcmtkb3duTGVhdmVzW2ldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG59IiwiLypcbiAqIEZpbGVuYW1lOiBtdWx0aS1jb2x1bW4tbWFya2Rvd24vc3JjL2RvbU9iamVjdC50c1xuICogQ3JlYXRlZCBEYXRlOiBUdWVzZGF5LCBGZWJydWFyeSAxc3QgMjAyMiwgMTI6MDQ6MDAgcG1cbiAqIEF1dGhvcjogQ2FtZXJvbiBSb2JpbnNvblxuICogXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjIgQ2FtZXJvbiBSb2JpbnNvblxuICovXG5cbmltcG9ydCB7IGdldFVJRCB9IGZyb20gXCIuLi91dGlsaXRpZXMvdXRpbHNcIjtcbmltcG9ydCB7IEVsZW1lbnRSZW5kZXJUeXBlIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9lbGVtZW50UmVuZGVyVHlwZVBhcnNlclwiO1xuaW1wb3J0IHsgY2hlY2tGb3JQYXJhZ3JhcGhJbm5lckNvbEVuZFRhZywgY29udGFpbnNDb2xFbmRUYWcsIGNvbnRhaW5zQ29sU2V0dGluZ3NUYWcsIGNvbnRhaW5zRW5kVGFnLCBjb250YWluc1N0YXJ0VGFnLCBlbElubmVyVGV4dENvbnRhaW5zQ29sRW5kVGFnIH0gZnJvbSBcInNyYy91dGlsaXRpZXMvdGV4dFBhcnNlclwiO1xuXG5jb25zdCBVUERBVEVfVElNRVM6IG51bWJlcltdID0gWzEyNSwgMTI1LCAyNTAsIDIwMDAwXTtcbmNvbnN0IE1JRF9CUkVBS19FUlJPUl9NRVNTQUdFOiBzdHJpbmcgPSBcIkRldGVjdGVkIGludmFsaWQgY29sdW1uIGJyZWFrIHN5bnRheC5cXG5QbGVhc2UgbWFrZSBzdXJlIGNvbHVtbiBicmVhayB0YWdzIGFyZSBub3QgaW4gdGhlIG1pZGRsZSBvZiBhIHBhcmFncmFwaCBibG9ja1wiXG5cbmV4cG9ydCBlbnVtIERPTU9iamVjdFRhZyB7XG4gICAgbm9uZSxcbiAgICBzdGFydFJlZ2lvbixcbiAgICByZWdpb25TZXR0aW5ncyxcbiAgICBjb2x1bW5CcmVhayxcbiAgICBlbmRSZWdpb25cbn1cblxuZXhwb3J0IGVudW0gRWxlbWVudENvbHVtbkJyZWFrVHlwZSB7XG4gICAgbm9uZSA9IDAsXG4gICAgcHJlQnJlYWssXG4gICAgcG9zdEJyZWFrLFxuICAgIG1pZEJyZWFrXG59XG5cbmV4cG9ydCBjbGFzcyBET01PYmplY3Qge1xuICAgIG5vZGVLZXk6IHN0cmluZztcbiAgICBvcmlnaW5hbEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIGNsb25lZEVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gbnVsbDtcbiAgICBVSUQ6IHN0cmluZztcbiAgICB0YWc6IERPTU9iamVjdFRhZztcbiAgICBlbGVtZW50SXNDb2x1bW5CcmVhazogRWxlbWVudENvbHVtbkJyZWFrVHlwZSA9IEVsZW1lbnRDb2x1bW5CcmVha1R5cGUubm9uZTtcbiAgICB1c2luZ09yaWdpbmFsRWxlbWVudDogYm9vbGVhblxuICAgIGVsZW1lbnRUeXBlOiBFbGVtZW50UmVuZGVyVHlwZSA9IFwidW5kZWZpbmVkXCI7XG4gICAgZWxlbWVudENvbnRhaW5lcjogSFRNTERpdkVsZW1lbnQgPSBudWxsO1xuICAgIGVsZW1lbnRSZW5kZXJlZEhlaWdodCA9IDA7XG4gICAgbGluZXNPZkVsZW1lbnQ6IHN0cmluZ1tdXG5cbiAgICBjYW52YXNFbGVtZW50VXBkYXRlVGltZTogbnVtYmVyID0gRGF0ZS5ub3coKTtcbiAgICBjYW52YXNUaW1lckluZGV4ID0gMDtcblxuICAgIGxhc3RDbG9uZWRFbGVtZW50VXBkYXRlVGltZTogbnVtYmVyID0gRGF0ZS5ub3coKTtcbiAgICB1cGRhdGVUaW1lckluZGV4ID0gMDtcblxuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IEhUTUxFbGVtZW50LFxuICAgICAgICAgICAgICAgIGxpbmVzT2ZFbGVtZW50OiBzdHJpbmdbXSxcbiAgICAgICAgICAgICAgICByYW5kb21JRDpzdHJpbmcgPSBnZXRVSUQoKSwgXG4gICAgICAgICAgICAgICAgdGFnOiBET01PYmplY3RUYWcgPSBET01PYmplY3RUYWcubm9uZSApIHtcbiAgICAgICAgdGhpcy5ub2RlS2V5ID0gZWxlbWVudC5pbm5lclRleHQudHJpbSgpO1xuICAgICAgICB0aGlzLm9yaWdpbmFsRWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgIHRoaXMuVUlEID0gcmFuZG9tSUQ7XG4gICAgICAgIHRoaXMudGFnID0gdGFnO1xuICAgICAgICB0aGlzLnVzaW5nT3JpZ2luYWxFbGVtZW50ID0gZmFsc2VcbiAgICAgICAgdGhpcy5saW5lc09mRWxlbWVudCA9IGxpbmVzT2ZFbGVtZW50O1xuXG4gICAgICAgIGlmKHRoaXMudGFnID09PSBET01PYmplY3RUYWcubm9uZSkge1xuICAgICAgICAgICAgdGhpcy5zZXREb21PYmplY3RUYWcoKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgb3VyIHRhZyBpcyBzdGlsbCBub25lIGhlcmUsIHdlIG5vdyB3YW50IHRvIGNoZWNrIGZvclxuICAgICAgICAvLyBhbiBpbiBwYXJhZ3JhcGggY29sdW1uIGJyZWFrIGZsYWcuXG4gICAgICAgIGlmKHRoaXMudGFnID09PSBET01PYmplY3RUYWcubm9uZSkge1xuICAgICAgICAgICAgdGhpcy5jaGVja0ZvclByZVBvc3RDb2x1bW5CcmVhaygpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRNYWluRE9NRWxlbWVudChkb21FbGVtZW50OiBIVE1MRWxlbWVudCkge1xuICAgICAgICB0aGlzLm9yaWdpbmFsRWxlbWVudCA9IGRvbUVsZW1lbnQ7XG4gICAgICAgIHRoaXMudXNpbmdPcmlnaW5hbEVsZW1lbnQgPSB0cnVlXG4gICAgfVxuXG4gICAgY2xvbmVkRWxlbWVudFJlYWR5Rm9yVXBkYXRlKCk6IGJvb2xlYW4ge1xuXG4gICAgICAgIGxldCBkZWx0YVRpbWUgPSBEYXRlLm5vdygpIC0gdGhpcy5sYXN0Q2xvbmVkRWxlbWVudFVwZGF0ZVRpbWU7XG4gICAgICAgIGlmKGRlbHRhVGltZSA+IFVQREFURV9USU1FU1t0aGlzLnVwZGF0ZVRpbWVySW5kZXhdKSB7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNhbnZhc1JlYWR5Rm9yVXBkYXRlKCk6IGJvb2xlYW4ge1xuICAgICAgICB2YXIgdGltaW5nQXJyYXkgPSBVUERBVEVfVElNRVNcbiAgICAgICAgbGV0IHtyZXF1aXJlc1VwZGF0ZSwgdGltZXJJbmRleCwgdXBkYXRlVGltZX0gPSBjaGVja0lmVGltaW5nSXNSZWFkeUZvclVwZGF0ZSh0aW1pbmdBcnJheSwgdGhpcy5jYW52YXNFbGVtZW50VXBkYXRlVGltZSwgdGhpcy5jYW52YXNUaW1lckluZGV4KVxuICAgICAgICBpZihyZXF1aXJlc1VwZGF0ZSA9PT0gZmFsc2Upe1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jYW52YXNFbGVtZW50VXBkYXRlVGltZSA9IHVwZGF0ZVRpbWU7XG4gICAgICAgIHRoaXMuY2FudmFzVGltZXJJbmRleCA9IHRpbWVySW5kZXhcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICB1cGRhdGVDbG9uZWRFbGVtZW50KG5ld0Nsb25lZEVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG5cbiAgICAgICAgdGhpcy5jbG9uZWRFbGVtZW50ID0gbmV3Q2xvbmVkRWxlbWVudDtcbiAgICAgICAgdGhpcy51cGRhdGVDbG9uZWRFbGVtZW50VGltZXIoKVxuICAgIH1cblxuICAgIHVwZGF0ZUNsb25lZEVsZW1lbnRUaW1lcigpIHtcbiAgICAgICAgdGhpcy5sYXN0Q2xvbmVkRWxlbWVudFVwZGF0ZVRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICB0aGlzLnVwZGF0ZVRpbWVySW5kZXggPSBNYXRoLmNsYW1wKHRoaXMudXBkYXRlVGltZXJJbmRleCArIDEsIDAsIFVQREFURV9USU1FUy5sZW5ndGggLSAxKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldERvbU9iamVjdFRhZygpIHtcblxuICAgICAgICBsZXQgZWxlbWVudFRleHRTcGFjZWQgPSB0aGlzLmxpbmVzT2ZFbGVtZW50LnJlZHVjZSgocHJldiwgY3VycikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHByZXYgKyBcIlxcblwiICsgY3VycjtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYoY29udGFpbnNFbmRUYWcodGhpcy5vcmlnaW5hbEVsZW1lbnQudGV4dENvbnRlbnQpID09PSB0cnVlKSB7XG5cbiAgICAgICAgICAgIHRoaXMuZWxlbWVudFR5cGUgPSBcInVuUmVuZGVyZWRcIjtcbiAgICAgICAgICAgIHRoaXMudGFnID0gRE9NT2JqZWN0VGFnLmVuZFJlZ2lvbjtcbiAgICAgICAgICAgIC8vIGVsLmFkZENsYXNzKE11bHRpQ29sdW1uU3R5bGVDU1MuUmVnaW9uRW5kVGFnKVxuICAgICAgICAgICAgLy8gcmVnaW9uYWxNYW5hZ2VyLnVwZGF0ZUVsZW1lbnRUYWcoY3VycmVudE9iamVjdC5VSUQsIERPTU9iamVjdFRhZy5lbmRSZWdpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoY29udGFpbnNDb2xFbmRUYWcodGhpcy5vcmlnaW5hbEVsZW1lbnQudGV4dENvbnRlbnQpID09PSB0cnVlIHx8IFxuICAgICAgICAodGhpcy5vcmlnaW5hbEVsZW1lbnQuaW5uZXJIVE1MLnN0YXJ0c1dpdGgoXCI8bWFyaz5cIikpICYmIGVsSW5uZXJUZXh0Q29udGFpbnNDb2xFbmRUYWcodGhpcy5vcmlnaW5hbEVsZW1lbnQudGV4dENvbnRlbnQpKSB7XG5cbiAgICAgICAgICAgIHRoaXMuZWxlbWVudFR5cGUgPSBcInVuUmVuZGVyZWRcIlxuICAgICAgICAgICAgdGhpcy50YWcgPSBET01PYmplY3RUYWcuY29sdW1uQnJlYWs7XG4gICAgICAgICAgICAvLyBlbC5hZGRDbGFzcyhNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtbkVuZFRhZylcbiAgICAgICAgICAgIC8vIHJlZ2lvbmFsTWFuYWdlci51cGRhdGVFbGVtZW50VGFnKGN1cnJlbnRPYmplY3QuVUlELCBET01PYmplY3RUYWcuY29sdW1uQnJlYWspO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoY29udGFpbnNTdGFydFRhZyh0aGlzLm9yaWdpbmFsRWxlbWVudC50ZXh0Q29udGVudCkgPT09IHRydWUpIHtcblxuICAgICAgICAgICAgdGhpcy5lbGVtZW50VHlwZSA9IFwidW5SZW5kZXJlZFwiXG4gICAgICAgICAgICB0aGlzLnRhZyA9IERPTU9iamVjdFRhZy5zdGFydFJlZ2lvbjtcbiAgICAgICAgICAgIC8vIGVsLmFkZENsYXNzKE11bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uRW5kVGFnKVxuICAgICAgICAgICAgLy8gcmVnaW9uYWxNYW5hZ2VyLnVwZGF0ZUVsZW1lbnRUYWcoY3VycmVudE9iamVjdC5VSUQsIERPTU9iamVjdFRhZy5jb2x1bW5CcmVhayk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZihjb250YWluc0NvbFNldHRpbmdzVGFnKGVsZW1lbnRUZXh0U3BhY2VkKSA9PT0gdHJ1ZSkge1xuXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnRUeXBlID0gXCJ1blJlbmRlcmVkXCJcbiAgICAgICAgICAgIC8vIGVsLmFkZENsYXNzKE11bHRpQ29sdW1uU3R5bGVDU1MuUmVnaW9uU2V0dGluZ3MpXG4gICAgICAgICAgICAvLyByZWdpb25hbE1hbmFnZXIgPSByZWdpb25hbENvbnRhaW5lci5zZXRSZWdpb25TZXR0aW5ncyhlbGVtZW50VGV4dFNwYWNlZClcbiAgICAgICAgICAgIC8vIHJlZ2lvbmFsTWFuYWdlci51cGRhdGVFbGVtZW50VGFnKGN1cnJlbnRPYmplY3QuVUlELCBET01PYmplY3RUYWcucmVnaW9uU2V0dGluZ3MpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2hlY2tGb3JQcmVQb3N0Q29sdW1uQnJlYWsoKSB7XG4gICAgICAgIGZ1bmN0aW9uIHJlcGxhY2VDb2xCcmVhayh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuXG4gICAgICAgICAgICBsZXQgY29sQnJlYWtEYXRhID0gY2hlY2tGb3JQYXJhZ3JhcGhJbm5lckNvbEVuZFRhZyh0ZXh0KTtcbiAgICAgICAgICAgIGlmKGNvbnRhaW5zQ29sdW1uQnJlYWsgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGV4dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSBjb2xCcmVha0RhdGEuaW5kZXg7XG4gICAgICAgICAgICBsZXQgZW5kSW5kZXggPSBzdGFydEluZGV4ICsgY29sQnJlYWtEYXRhWzBdLmxlbmd0aDtcbiAgICAgICAgICAgIGxldCBwcmUgPSB0ZXh0LnNsaWNlKDAsIHN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgbGV0IHBvc3QgPSB0ZXh0LnNsaWNlKGVuZEluZGV4KTtcblxuICAgICAgICAgICAgcmV0dXJuIGAke3ByZX0ke3Bvc3R9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCB0ZXh0T2ZFbGVtZW50ID0gdGhpcy5vcmlnaW5hbEVsZW1lbnQuaW5uZXJUZXh0O1xuICAgICAgICBsZXQgY29udGFpbnNDb2x1bW5CcmVhayA9IGNoZWNrRm9yUGFyYWdyYXBoSW5uZXJDb2xFbmRUYWcodGV4dE9mRWxlbWVudCk7XG4gICAgICAgIGlmKGNvbnRhaW5zQ29sdW1uQnJlYWsgIT09IG51bGwpIHtcblxuICAgICAgICAgICAgbGV0IHRleHQgPSB0aGlzLm9yaWdpbmFsRWxlbWVudC5pbm5lclRleHQ7XG4gICAgICAgICAgICBsZXQgc3RhcnRJbmRleCA9IGNvbnRhaW5zQ29sdW1uQnJlYWsuaW5kZXg7XG4gICAgICAgICAgICBsZXQgZW5kSW5kZXggPSBzdGFydEluZGV4ICsgY29udGFpbnNDb2x1bW5CcmVha1swXS5sZW5ndGg7XG4gICAgICAgICAgICBsZXQgcHJlID0gdGV4dC5zbGljZSgwLCBzdGFydEluZGV4KTtcbiAgICAgICAgICAgIGxldCBwb3N0ID0gdGV4dC5zbGljZShlbmRJbmRleClcblxuICAgICAgICAgICAgLy8gU29tZXRpbWVzIHRoZSBlbGVtZW50IHBhc3NlZCBpbiBpcyBhIERJViBjb250YWluaW5nIGEgY2hpbGQgZWxlbWVudCwgb3RoZXJcbiAgICAgICAgICAgIC8vIHRpbWVzIGl0IGlzIHRoZSByb290IGNoaWxkIGVsZW1lbnQgYWxvbmUsIGhlcmUgd2UganVzdCBtYWtlIHN1cmUgd2UgYXJlIGFjY2Vzc2luZ1xuICAgICAgICAgICAgLy8gdGhlIHJpZ2h0IGVsZW1lbnQgd2Ugd2FudC5cbiAgICAgICAgICAgIGxldCBjaGVja05vZGUgPSB0aGlzLm9yaWdpbmFsRWxlbWVudDtcbiAgICAgICAgICAgIGlmKHRoaXMub3JpZ2luYWxFbGVtZW50Lm5vZGVOYW1lID09PSBcIkRJVlwiKSB7XG4gICAgICAgICAgICAgICAgY2hlY2tOb2RlID0gdGhpcy5vcmlnaW5hbEVsZW1lbnQuY2hpbGRyZW5bMF0gYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBwYXJhZ3JhcGggPSBudWxsO1xuICAgICAgICAgICAgaWYoY2hlY2tOb2RlLm5vZGVOYW1lID09PSBcIlBcIikge1xuXG4gICAgICAgICAgICAgICAgLy8gUGFyYWdyYXBocyBzaW1wbHkgcmVtb3ZlIHRoZSBjb2wtYnJlYWsgdGFnXG4gICAgICAgICAgICAgICAgLy8gd2Ugc2V0IG91ciBlbGVtZW50IGhlcmUgaW5jYXNlIHdlIG5lZWQgdG8gZGlzcGxheSBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBwYXJhZ3JhcGggPSBjaGVja05vZGU7XG4gICAgICAgICAgICAgICAgY2hlY2tOb2RlLmlubmVyVGV4dCA9IGAke3ByZX0ke3Bvc3R9YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYoY2hlY2tOb2RlLm5vZGVOYW1lID09PSBcIlVMXCIgfHwgY2hlY2tOb2RlLm5vZGVOYW1lID09PSBcIk9MXCIpIHtcblxuICAgICAgICAgICAgICAgIC8vIEF0dGVtcHQgdG8gZ2V0IHRoZSBsaXN0IGl0ZW0gdGhhdCBjb250YWlucyB0aGUgY29sdW1uIGJyZWFrLFxuICAgICAgICAgICAgICAgIC8vIEZyb20gdGVzdGluZyB0aGlzIGNvZGUgc2hvdWxkIG9ubHkgcnVuIHdoZW4gdGhlIGNvbHVtbiBicmVhayBpcyBhdCB0aGUgZW5kXG4gICAgICAgICAgICAgICAgLy8gb2YgYSBsaXN0IG5vdCBhdCB0aGUgc3RhcnQgb2YgdGhlIGxpc3QuXG4gICAgICAgICAgICAgICAgbGV0IGxpc3RJdGVtID0gbnVsbDtcbiAgICAgICAgICAgICAgICBmb3IobGV0IGkgPSBjaGVja05vZGUuY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYoY2hlY2tOb2RlLmNoaWxkcmVuW2ldLm5vZGVOYW1lID09PSBcIkxJXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RJdGVtID0gY2hlY2tOb2RlLmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZihsaXN0SXRlbSAhPT0gbnVsbCkge1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UsIHRoZSBsaXN0IGVsZW1lbnQgSFRNTCB3aXRob3V0IHRoZSBjb2wtYnJlYWsgdGV4dC5cbiAgICAgICAgICAgICAgICAgICAgKGxpc3RJdGVtIGFzIEhUTUxFbGVtZW50KS5pbm5lckhUTUwgPSByZXBsYWNlQ29sQnJlYWsoKGxpc3RJdGVtIGFzIEhUTUxFbGVtZW50KS5pbm5lckhUTUwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoYEVsZW1lbnQgVHlwZTogJHtjaGVja05vZGUubm9kZU5hbWV9LCBkb2VzIG5vdCBjdXJyZW50bHkgc3VwcG9ydCBhcHBlbmVkIGNvbHVtbi1icmVha3MuYCwgY2hlY2tOb2RlLmNsb25lTm9kZSh0cnVlKSk7XG4gICAgICAgICAgICAgICAgLy8gaWYocGFyYWdyYXBoKSB7XG4gICAgICAgICAgICAgICAgLy8gICAgIHBhcmFncmFwaC5pbm5lclRleHQgPSBgJHtwcmV9JHtwb3N0fWA7XG4gICAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBjb25zb2xlLmRlYnVnKFwiQ2hlY2tpbmcgd2hlcmUgY29sdW1uIGJyZWFrIGlzXCIsIHN0YXJ0SW5kZXgsIGVuZEluZGV4LCB0ZXh0Lmxlbmd0aCk7XG4gICAgICAgICAgICBpZihzdGFydEluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5kZWJ1ZyhcIkNvbHVtbiBicmVhayBhdCBiZWdpbmluZyBvZiBlbGVtZW50LlwiKVxuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudElzQ29sdW1uQnJlYWsgPSBFbGVtZW50Q29sdW1uQnJlYWtUeXBlLnByZUJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZihlbmRJbmRleCA9PT0gdGV4dC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmRlYnVnKFwiQ29sdW1uIGJyZWFrIGF0IGVuZCBvZiBlbGVtZW50LlwiKVxuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudElzQ29sdW1uQnJlYWsgPSBFbGVtZW50Q29sdW1uQnJlYWtUeXBlLnBvc3RCcmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUuZGVidWcoXCJDb2x1bW4gYnJlYWsgaW4gdGhlIG1pZGRsZSBvZiBlbGVtZW50P1wiKVxuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudElzQ29sdW1uQnJlYWsgPSBFbGVtZW50Q29sdW1uQnJlYWtUeXBlLm1pZEJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgRVJST1JfQ09MT1JfQ1NTID0gXCJtY20tZXJyb3ItbWVzc2FnZS1jb2xvclwiO1xuICAgICAgICAgICAgICAgIGNvbnN0IENFTlRFUl9BTElHTl9TUEFOX0NTUyA9IFwibWNtLXNwYW4tY29udGVudC1hbGlnbm1lbnQtY2VudGVyXCI7XG4gICAgICAgICAgICAgICAgaWYocGFyYWdyYXBoKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFncmFwaC5pbm5lckhUTUwgPSBgJHtwcmV9XFxuPHNwYW4gY2xhc3M9XCIke0VSUk9SX0NPTE9SX0NTU30gJHtDRU5URVJfQUxJR05fU1BBTl9DU1N9XCI+JHtNSURfQlJFQUtfRVJST1JfTUVTU0FHRX08L3NwYW4+XFxuXFxuJHtwb3N0fWAuc3BsaXQoXCJcXG5cIikuam9pbihcIjxicj5cIik7XG5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBET01TdGFydFJlZ2lvbk9iamVjdCBleHRlbmRzIERPTU9iamVjdCB7XG5cbiAgICByZWdpb25FbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIGNvbnN0cnVjdG9yKGJhc2VET01PYmplY3Q6IERPTU9iamVjdCwgcmVnaW9uRWxlbWVudDogSFRNTEVsZW1lbnQpIHtcblxuICAgICAgICBzdXBlcihiYXNlRE9NT2JqZWN0Lm9yaWdpbmFsRWxlbWVudCwgYmFzZURPTU9iamVjdC5saW5lc09mRWxlbWVudCwgYmFzZURPTU9iamVjdC5VSUQsIERPTU9iamVjdFRhZy5zdGFydFJlZ2lvbik7XG4gICAgICAgIHRoaXMucmVnaW9uRWxlbWVudCA9IHJlZ2lvbkVsZW1lbnQ7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgVGFza0xpc3RET01PYmplY3QgZXh0ZW5kcyBET01PYmplY3Qge1xuXG4gICAgb3JpZ2luYWxDaGVja2JveGVzOiBIVE1MRWxlbWVudFtdID0gW107XG4gICAgY2hlY2tib3hFbGVtZW50czogTWFwPG51bWJlciwgSFRNTElucHV0RWxlbWVudD4gPSBuZXcgTWFwKCk7XG5cbiAgICBjb25zdHJ1Y3RvcihiYXNlRE9NT2JqZWN0OiBET01PYmplY3QpIHtcblxuICAgICAgICBzdXBlcihiYXNlRE9NT2JqZWN0Lm9yaWdpbmFsRWxlbWVudCwgYmFzZURPTU9iamVjdC5saW5lc09mRWxlbWVudCwgYmFzZURPTU9iamVjdC5VSUQsIERPTU9iamVjdFRhZy5ub25lKTtcbiAgICB9XG5cbiAgICBjaGVja2JveENsaWNrZWQoaW5kZXg6IG51bWJlcikge1xuICAgICAgICBcbiAgICAgICAgaWYodGhpcy5jaGVja2JveEVsZW1lbnRzLmhhcyhpbmRleCkpIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tib3hFbGVtZW50cy5nZXQoaW5kZXgpLmNsaWNrKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZihpbmRleCA8IHRoaXMub3JpZ2luYWxDaGVja2JveGVzLmxlbmd0aCkge1xuXG4gICAgICAgICAgICBsZXQgb3JpZ2luYWxJbnB1dCA9IHRoaXMub3JpZ2luYWxDaGVja2JveGVzW2luZGV4XS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCd0YXNrLWxpc3QtaXRlbS1jaGVja2JveCcpXG4gICAgICAgICAgICBpZihvcmlnaW5hbElucHV0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgIChvcmlnaW5hbElucHV0WzBdIGFzIEhUTUxJbnB1dEVsZW1lbnQpLmNsaWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBlbHNlIHtcbiAgICAgICAgICAgIC8vICAgICBjb25zb2xlLmVycm9yKFwiQ291bGQgbm90IGZpbmQgY2hlY2tib3ggdG8gY2xpY2suXCIpXG4gICAgICAgICAgICAvLyB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRDaGVja2JveEVsZW1lbnQoaW5kZXg6IG51bWJlcik6IEhUTUxJbnB1dEVsZW1lbnQgfCB1bmRlZmluZWQge1xuXG5cbiAgICAgICAgaWYodGhpcy5jaGVja2JveEVsZW1lbnRzLmhhcyhpbmRleCkgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgICAgIGlmKGluZGV4IDwgdGhpcy5vcmlnaW5hbENoZWNrYm94ZXMubGVuZ3RoKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgb3JpZ2luYWxJbnB1dCA9IHRoaXMub3JpZ2luYWxDaGVja2JveGVzW2luZGV4XT8uZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndGFzay1saXN0LWl0ZW0tY2hlY2tib3gnKVxuICAgICAgICAgICAgICAgIGlmKG9yaWdpbmFsSW5wdXQ/Lmxlbmd0aCA+PSAxKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVja2JveEVsZW1lbnRzLnNldChpbmRleCwgKG9yaWdpbmFsSW5wdXRbMF0gYXMgSFRNTElucHV0RWxlbWVudCkpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vICAgICBjb25zb2xlLmVycm9yKFwiQ291bGQgbm90IGZpbmQgY2hlY2tib3ggZWxlbWVudCB0byByZXR1cm4uXCIsIHRoaXMub3JpZ2luYWxDaGVja2JveGVzLCBpbmRleCk7XG4gICAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmNoZWNrYm94RWxlbWVudHMuZ2V0KGluZGV4KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgY2hlY2tGb3JUYXNrTGlzdEVsZW1lbnQoZG9tRWxlbWVudDogRE9NT2JqZWN0KSB7XG5cbiAgICAgICAgaWYoZG9tRWxlbWVudC5vcmlnaW5hbEVsZW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInRhc2stbGlzdC1pdGVtXCIpLmxlbmd0aCA+IDAgKSB7XG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgVGFza0xpc3RET01PYmplY3QoZG9tRWxlbWVudCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZG9tRWxlbWVudDtcbiAgICB9XG5cbiAgICBzdGF0aWMgZ2V0Q2hpbGRDaGVja2JveChlbDogSFRNTEVsZW1lbnQpOiBIVE1MRWxlbWVudCB7XG5cbiAgICAgICAgbGV0IGNoZWNrYm94RWxlbWVudHMgPSBlbC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCd0YXNrLWxpc3QtaXRlbS1jaGVja2JveCcpXG4gICAgICAgIGlmKGNoZWNrYm94RWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG5cbiAgICAgICAgICAgIHJldHVybiBjaGVja2JveEVsZW1lbnRzWzBdIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICByZXR1cm4gZWwuY2hpbGRyZW5bMF0gYXMgSFRNTEVsZW1lbnRcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrSWZUaW1pbmdJc1JlYWR5Rm9yVXBkYXRlKHRpbWluZ0FycmF5OiBudW1iZXJbXSwgY2FudmFzRWxlbWVudFVwZGF0ZVRpbWU6IG51bWJlciwgY2FudmFzVGltZXJJbmRleDogbnVtYmVyKSB7XG4gICAgbGV0IGRlbHRhVGltZSA9IERhdGUubm93KCkgLSBjYW52YXNFbGVtZW50VXBkYXRlVGltZVxuICAgIGlmKGRlbHRhVGltZSA+IHRpbWluZ0FycmF5W2NhbnZhc1RpbWVySW5kZXhdKSB7XG4gICAgICAgIGNhbnZhc0VsZW1lbnRVcGRhdGVUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgY2FudmFzVGltZXJJbmRleCA9IE1hdGguY2xhbXAoY2FudmFzVGltZXJJbmRleCArIDEsIDAsIFVQREFURV9USU1FUy5sZW5ndGggLSAxKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlcXVpcmVzVXBkYXRlOiB0cnVlLFxuICAgICAgICAgICAgdXBkYXRlVGltZTogY2FudmFzRWxlbWVudFVwZGF0ZVRpbWUsXG4gICAgICAgICAgICB0aW1lckluZGV4OiBjYW52YXNUaW1lckluZGV4LFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmVxdWlyZXNVcGRhdGU6IGZhbHNlLFxuICAgICAgICB1cGRhdGVUaW1lOiBjYW52YXNFbGVtZW50VXBkYXRlVGltZSxcbiAgICAgICAgdGltZXJJbmRleDogY2FudmFzVGltZXJJbmRleFxuICAgIH1cbn0iLCIvKlxuICogRmlsZTogbXVsdGktY29sdW1uLW1hcmtkb3duL3NyYy91dGlsaXRpZXMvY3NzRGVmaW5pdGlvbnMudHNcbiAqIENyZWF0ZWQgRGF0ZTogV2VkbmVzZGF5LCBGZWJydWFyeSAxNnRoIDIwMjIsIDExOjA5OjA2IGFtXG4gKiBBdXRob3I6IENhbWVyb24gUm9iaW5zb25cbiAqIFxuICogQ29weXJpZ2h0IChjKSAyMDIyIENhbWVyb24gUm9iaW5zb25cbiAqL1xuXG5leHBvcnQgZW51bSBNdWx0aUNvbHVtbkxheW91dENTUyB7XG5cbiAgICBSZWdpb25Sb290Q29udGFpbmVyRGl2ID0gXCJtY20tY29sdW1uLXJvb3QtY29udGFpbmVyXCIsXG4gICAgUmVnaW9uRXJyb3JDb250YWluZXJEaXYgPSBcIm1jbS1jb2x1bW4tZXJyb3ItcmVnaW9uLXdyYXBwZXJcIixcbiAgICBSZWdpb25Db250ZW50Q29udGFpbmVyRGl2ID0gXCJtY20tY29sdW1uLXJlZ2lvbi13cmFwcGVyXCIsXG4gICAgUmVnaW9uQ29sdW1uQ29udGFpbmVyRGl2ID0gXCJtY20tY29sdW1uLXBhcmVudC1jb250YWluZXJcIixcbiAgICBDb2x1bW5EdWFsRWxlbWVudENvbnRhaW5lciA9IFwibWNtLWNvbHVtbi1lbGVtZW50LXdyYXBwZXJcIixcbiAgICBPcmlnaW5hbEVsZW1lbnRUeXBlID0gXCJtY20tb3JpZ2luYWwtY29sdW1uLWVsZW1lbnRcIixcbiAgICBDbG9uZWRFbGVtZW50VHlwZSA9IFwibWNtLWNsb25lZC1jb2x1bW4tZWxlbWVudFwiLFxuXG4gICAgQ29udGVudE92ZXJmbG93QXV0b1Njcm9sbF9YID0gXCJtY20tY29udGVudC1vdmVyZmxvdy1hdXRvLXNjcm9sbC14XCIsXG4gICAgQ29udGVudE92ZXJmbG93QXV0b1Njcm9sbF9ZID0gXCJtY20tY29udGVudC1vdmVyZmxvdy1hdXRvLXNjcm9sbC15XCIsXG4gICAgQ29udGVudE92ZXJmbG93SGlkZGVuX1ggPSBcIm1jbS1jb250ZW50LW92ZXJmbG93LWhpZGRlbi14XCIsXG4gICAgQ29udGVudE92ZXJmbG93SGlkZGVuX1kgPSBcIm1jbS1jb250ZW50LW92ZXJmbG93LWhpZGRlbi15XCIsXG5cbiAgICBBbGlnbm1lbnRMZWZ0ID0gXCJtY20tY29udGVudC1hbGlnbm1lbnQtbGVmdFwiLFxuICAgIEFsaWdubWVudENlbnRlciA9IFwibWNtLWNvbnRlbnQtYWxpZ25tZW50LWNlbnRlclwiLFxuICAgIEFsaWdubWVudFJpZ2h0ID0gXCJtY20tY29udGVudC1hbGlnbm1lbnQtcmlnaHRcIixcblxuICAgIFRhYmxlQWxpZ25tZW50ID0gXCJtY20tdGFibGUtYWxpZ25tZW50XCIsXG5cbiAgICBOb0ZsZXhTaHJpbmsgPSBcIm1jbS1uby1mbGV4LXNocmlua1wiLFxuXG4gICAgUmVmbG93Q29udGFpbmVyRGl2ID0gXCJtY20tZG9jLXJlZmxvdy1jb250YWluZXJcIixcblxuICAgIEVycm9yUmVnaW9uUGFkZGluZyA9IFwibWNtLWNvbHVtbi1lcnJvci1wYWRkaW5nXCIsXG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy9cblxuICAgIFNpbmdsZUNvbHVtblNtYWxsID0gXCJtY20tc2luZ2xlLWNvbHVtbi1zbWFsbFwiLFxuICAgIFNpbmdsZUNvbHVtbk1lZCA9IFwibWNtLXNpbmdsZS1jb2x1bW4tbWVkaXVtXCIsXG4gICAgU2luZ2xlQ29sdW1uTGFyZ2UgPSBcIm1jbS1zaW5nbGUtY29sdW1uLWxhcmdlXCIsXG4gICAgU2luZ2xlQ29sdW1uRnVsbCA9IFwibWNtLXNpbmdsZS1jb2x1bW4tZnVsbFwiLFxuXG4gICAgU2luZ2xlQ29sdW1uTGVmdExheW91dCA9IFwibWNtLXNpbmdsZWNvbC1sYXlvdXQtbGVmdFwiLFxuICAgIFNpbmdsZUNvbHVtbkNlbnRlckxheW91dCA9IFwibWNtLXNpbmdsZWNvbC1sYXlvdXQtY2VudGVyXCIsXG4gICAgU2luZ2xlQ29sdW1uUmlnaHRMYXlvdXQgPSBcIm1jbS1zaW5nbGVjb2wtbGF5b3V0LXJpZ2h0XCIsXG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy9cblxuICAgIFR3b0VxdWFsQ29sdW1ucyA9IFwibWNtLXR3by1lcXVhbC1jb2x1bW5zXCIsXG5cbiAgICBUd29Db2x1bW5TbWFsbCA9IFwibWNtLXR3by1jb2x1bW4tc21hbGxcIixcbiAgICBUd29Db2x1bW5MYXJnZSA9IFwibWNtLXR3by1jb2x1bW4tbGFyZ2VcIixcblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAvL1xuXG4gICAgVGhyZWVFcXVhbENvbHVtbnMgPSBcIm1jbS10aHJlZS1lcXVhbC1jb2x1bW5zXCIsXG5cbiAgICBUaHJlZUNvbHVtbl9MYXJnZSA9IFwibWNtLXRocmVlLWNvbHVtbi1sYXJnZVwiLFxuICAgIFRocmVlQ29sdW1uX1NtYWxsID0gXCJtY20tdGhyZWUtY29sdW1uLXNtYWxsXCIsXG59XG5cbmV4cG9ydCBlbnVtIE11bHRpQ29sdW1uU3R5bGVDU1Mge1xuXG4gICAgUmVnaW9uRXJyb3JNZXNzYWdlID0gXCJtY20tY29sdW1uLWVycm9yLW1lc3NhZ2VcIixcbiAgICBSZWdpb25TZXR0aW5ncyA9IFwibWNtLWNvbHVtbi1zZXR0aW5ncy13cmFwcGVyXCIsXG4gICAgUmVnaW9uQ29udGVudCA9IFwibWNtLWNvbHVtbi1jb250ZW50LXdyYXBwZXJcIixcbiAgICBSZWdpb25FbmRUYWcgPSBcIm1jbS1jb2x1bW4tZW5kLXRhZy13cmFwcGVyXCIsXG4gICAgQ29sdW1uRW5kVGFnID0gXCJtY20tY29sdW1uLWJyZWFrLXRhZy13cmFwcGVyXCIsXG4gICAgUmVnaW9uU2hhZG93ID0gXCJtY20tcmVnaW9uLXNoYWRvd1wiLFxuICAgIENvbHVtblNoYWRvdyA9IFwibWNtLWNvbHVtbi1zaGFkb3dcIixcbiAgICBDb2x1bW5Cb3JkZXIgPSBcIm1jbS1jb2x1bW4tYm9yZGVyXCIsXG4gICAgQ29sdW1uQ29udGVudCA9IFwibWNtLWNvbHVtbi1kaXZcIixcbiAgICBTbWFsbEZvbnQgPSBcIm1jbS1zbWFsbC1mb250LW1lc3NhZ2VcIlxufVxuXG5leHBvcnQgZW51bSBPYnNpZGlhblN0eWxlQ1NTIHtcbiAgICBSZW5kZXJlZE1hcmtkb3duID0gXCJtYXJrZG93bi1yZW5kZXJlZFwiXG59IiwiLyoqXG4gKiBGaWxlOiAvc3JjL3V0aWxpdGllcy9lbGVtZW50UmVuZGVyVHlwZVBhcnNlci50cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogQXV0aG9yOiBDYW1lcm9uIFJvYmluc29uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjMgQ2FtZXJvbiBSb2JpbnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICovXG5cbmltcG9ydCB7IHNlYXJjaENoaWxkcmVuRm9yTm9kZVR5cGUgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5jb25zdCBBTExfRUxFTUVOVF9SRU5ERVJfVFlQRVMgPSBbXG4gICAgXCJ1bmRlZmluZWRcIixcbiAgICBcImJhc2ljRWxlbWVudFwiLFxuICAgIFwic3BlY2lhbFJlbmRlclwiLFxuICAgIFwiYnV0dG9uUGx1Z2luXCIsXG4gICAgXCJkYXRhdmlld1BsdWdpblwiLFxuICAgIFwiaW1hZ2VFbWJlZFwiLFxuICAgIFwiYWRtb25pdGlvbkZvbGRcIixcbiAgICBcImNhbGxvdXRDb3B5QnV0dG9uXCIsXG4gICAgXCJpbnRlcm5hbEVtYmVkXCIsXG4gICAgXCJkYXRhdmlld0pTQ2FudmFzRW1iZWRcIixcbiAgICBcImRhdGF2aWV3SlNFbWJlZFwiLFxuICAgIFwiZGF0YXZpZXdJbmxpbmVRdWVyeVwiLFxuICAgIFwiZGljZVJvbGxlclwiLFxuICAgIFwiYWRtb25pdGlvblwiLFxuICAgIFwiY3VzdG9tRnJhbWVQbHVnaW5cIixcbiAgICBcImlGcmFtZUVtYmVkXCIsXG4gICAgXCJ0YXNrc1BsdWdpblwiLFxuICAgIFwidW5SZW5kZXJlZFwiLFxuICAgIFwicGRmRW1iZWRcIlxuXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIEVsZW1lbnRSZW5kZXJUeXBlID0gdHlwZW9mIEFMTF9FTEVNRU5UX1JFTkRFUl9UWVBFU1tudW1iZXJdO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RWxlbWVudFJlbmRlclR5cGUoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBFbGVtZW50UmVuZGVyVHlwZSB7XG5cbiAgICBpZihpc0VtYmVkZWRJbWFnZShlbGVtZW50KSA9PT0gdHJ1ZSkge1xuICAgICAgICByZXR1cm4gXCJpbWFnZUVtYmVkXCJcbiAgICB9XG5cbiAgICBpZihpc0J1dHRvblBsdWdpbl9Dcm9zc0NvbXBhdGliaWx0eShlbGVtZW50KSA9PT0gdHJ1ZSkge1xuICAgICAgICByZXR1cm4gXCJidXR0b25QbHVnaW5cIlxuICAgIH1cblxuICAgIGlmKGlzVGFza3NQbHVnaW4oZWxlbWVudCkgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIFwidGFza3NQbHVnaW5cIlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBEYXRhdmlldyBwbHVnaW4gbmVlZHMgdG8gYmUgY29uc3RhbnRseSBjaGVja2VkIGlmIHRoZSBjbG9uZSBzaG91bGQgYmVcbiAgICAgKiB1cGRhdGVkIGJ1dCBzaG91bGQgbm90IGFsd2F5cyB1cGRhdGUgdGhlIFwiZHVhbCByZW5kZXJcIiBhc3BlY3QsIHNvIHdlIGFkZFxuICAgICAqIGEgc3BlY2lhbCBjYXNlIGZvciB0aGF0IHBsdWdpbiBhbmQgbWF5YmUgb3RoZXJzIGluIHRoZSBmdXR1cmUuXG4gICAgICovXG4gICAgaWYoaGFzRGF0YXZpZXcoZWxlbWVudCkgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIFwiZGF0YXZpZXdQbHVnaW5cIlxuICAgIH1cbiAgICBlbHNlIGlmKGlzUERGRW1iZWQoZWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuIFwicGRmRW1iZWRcIlxuICAgIH1cbiAgICBlbHNlIGlmKGlzSW50ZXJuYWxFbWJlZChlbGVtZW50KSkge1xuICAgICAgICByZXR1cm4gXCJpbnRlcm5hbEVtYmVkXCJcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTb21lIHR5cGVzIG9mIGNvbnRlbnQgYXJlIHJlbmRlcmVkIGluIGNhbnZhc2VzIHdoaWNoIGFyZSBub3QgcmVuZGVyZWQgcHJvcGVybHlcbiAgICAgKiB3aGVuIHdlIGNsb25lIHRoZSBvcmlnaW5hbCBub2RlLiBIZXJlIHdlIGFyZSBmbGFnZ2luZyB0aGUgZWxlbWVudCBhcyBhIGNhbnZhc1xuICAgICAqIGVsZW1lbnQgc28gd2UgY2FuIGNsb25lIHRoZSBjYW52YXMgdG8gYSBjb3B5IGVsZW1lbnQgd2l0aGluIHRoZSByZWdpb24uXG4gICAgICogXG4gICAgICovXG4gICAgaWYoIGhhc0RhdGF2aWV3SlNDYW52YXMoZWxlbWVudCkgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIFwiZGF0YXZpZXdKU0NhbnZhc0VtYmVkXCJcbiAgICB9XG4gICAgaWYoIGhhc0RhdGF2aWV3SlMoZWxlbWVudCkgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIFwiZGF0YXZpZXdKU0VtYmVkXCJcbiAgICB9XG4gICAgaWYoaGFzRGF0YXZpZXdJbmxpbmUoZWxlbWVudCkgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIFwiZGF0YXZpZXdJbmxpbmVRdWVyeVwiXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9vayBmb3Igc3BlY2lmaWMga2luZHMgb2YgZWxlbWVudHMgYnkgdGhlaXIgQ1NTIGNsYXNzIG5hbWVzIGhlcmUuIFRoZXNlIFxuICAgICAqIGFyZSBnb2luZyB0byBiZSBicml0dGxlIGxpbmtzIGFzIHRoZXkgcmVseSBvbiBvdGhlciBwbHVnaW4gZGVmaW5pdGlvbnMgYnV0XG4gICAgICogYXMgdGhpcyBpcyBvbmx5IGFkZGluZyBpbiBleHRyYSBjb21wYXRhYmlsaXR5IHRvIHRoZSBwbHVnaW5zIGRlZmluZWQgaGVyZSBcbiAgICAgKiBpdCBzaG91bGQgYmUgb2suXG4gICAgICogXG4gICAgICogVGhlc2UgbWF5IGJlIGNsYXNzZXMgb24gb25lIG9mIHRoZSBzaW1wbGUgZWxlbWVudHMgKHN1Y2ggYXMgYSBwYXJhZ3JhcGgpXG4gICAgICogdGhhdCB3ZSBzZWFyY2ggZm9yIGJlbG93IHNvIG5lZWQgdG8gbG9vayBmb3IgdGhlc2UgZmlyc3QuXG4gICAgICovXG4gICAgaWYoaGFzRGljZVJvbGxlcihlbGVtZW50KSA9PT0gdHJ1ZSkge1xuICAgICAgICByZXR1cm4gXCJkaWNlUm9sbGVyXCJcbiAgICB9XG4gICAgZWxzZSBpZihoYXNDb3B5QnV0dG9uKGVsZW1lbnQpID09PSB0cnVlKSB7XG4gICAgICAgIHJldHVybiBcImNhbGxvdXRDb3B5QnV0dG9uXCJcbiAgICB9XG4gICAgZWxzZSBpZihoYXNBZG1vbml0aW9uRm9sZChlbGVtZW50KSA9PT0gdHJ1ZSkge1xuICAgICAgICByZXR1cm4gXCJhZG1vbml0aW9uRm9sZFwiXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBjaGVja3MgZm9yIHNwZWNpYWwgdHlwZXMgb2YgZWxlbWVudHMgdGhhdCBzaG91bGQgYmUgcmVuZGVyZWQgbm9ybWFsbHkuIElzXG4gICAgICogc2xpZ2h0bHkgcmVkdW5kYW50IHdpdGggbmV4dCBjaGVjayBidXQgZGlmZmVyZW50aWF0ZXMgYmV0d2VlbiB0eXBlcyBvZiBlbWVudHMgXG4gICAgICogYmVpbmcgY2hlY2tlZC5cbiAgICAgKi9cbiAgICBpZihoYXNBZG1vbml0aW9uKGVsZW1lbnQpID09PSB0cnVlKSB7XG4gICAgICAgIHJldHVybiBcImFkbW9uaXRpb25cIlxuICAgIH1cbiAgICBlbHNlIGlmIChpc0lGcmFtZShlbGVtZW50KSA9PT0gdHJ1ZSkge1xuXG4gICAgICAgIHJldHVybiBcImlGcmFtZUVtYmVkXCJcbiAgICB9XG4gICAgZWxzZSBpZihpc0N1c3RvbUlGcmFtZShlbGVtZW50KSA9PT0gdHJ1ZSkge1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIFwiY3VzdG9tRnJhbWVQbHVnaW5cIlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIElmIHdlIGRpZG50IGZpbmQgYSBzcGVjaWFsIGVsZW1lbnQgd2Ugd2FudCB0byBjaGVjayBmb3Igc2ltcGxlIGVsZW1lbnRzXG4gICAgICogc3VjaCBhcyBwYXJhZ3JhcGhzIG9yIGxpc3RzLiBJbiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiB3ZSBvbmx5IHNldCB1cFxuICAgICAqIHRoZSBzcGVjaWFsIGNhc2UgZm9yIFwic3BlY2lhbFJlbmRlclwiIGVsZW1lbnRzIHNvIHRoaXMgKnNob3VsZCogYmUgc2F2aW5nXG4gICAgICogc29tZSByZW5kZXJpbmcgdGltZSBieSBzZXR0aW5nIHRoZXNlIHRhZ3MgcHJvcGVybHkuXG4gICAgICovXG4gICAgaWYoaGFzUGFyYWdyYXBoKGVsZW1lbnQpIHx8IFxuICAgICAgIGhhc0hlYWRlcihlbGVtZW50KSAgICB8fFxuICAgICAgIGhhc0xpc3QoZWxlbWVudCkgfHxcbiAgICAgICBpc0hvcml6b250YWxSdWxlKGVsZW1lbnQpIHx8XG4gICAgICAgaXNUYWJsZShlbGVtZW50KSkge1xuXG4gICAgICAgIHJldHVybiBcImJhc2ljRWxlbWVudFwiXG4gICAgfVxuXG4gICAgLy8gSWYgc3RpbGwgbm90aGluZyBmb3VuZCB3ZSByZXR1cm4gb3RoZXIgYXMgdGhlIGRlZmF1bHQgcmVzcG9uc2UgaWYgbm90aGluZyBlbHNlIGZvdW5kLlxuICAgIHJldHVybiBcInNwZWNpYWxSZW5kZXJcIlxufVxuXG5mdW5jdGlvbiBoYXNQYXJhZ3JhcGgoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZWxlbWVudC5pbm5lckhUTUwuc3RhcnRzV2l0aChcIjxwXCIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzSGVhZGVyKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG5cbiAgICBpZihlbGVtZW50LmlubmVySFRNTC5zdGFydHNXaXRoKFwiPGgxXCIpIHx8IFxuICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MLnN0YXJ0c1dpdGgoXCI8aDJcIikgfHwgXG4gICAgICAgZWxlbWVudC5pbm5lckhUTUwuc3RhcnRzV2l0aChcIjxoM1wiKSB8fCBcbiAgICAgICBlbGVtZW50LmlubmVySFRNTC5zdGFydHNXaXRoKFwiPGg0XCIpIHx8XG4gICAgICAgZWxlbWVudC5pbm5lckhUTUwuc3RhcnRzV2l0aChcIjxoNVwiKSB8fFxuICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MLnN0YXJ0c1dpdGgoXCI8aDZcIikpIHtcblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGhhc0xpc3QoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICBcbiAgICBpZihlbGVtZW50LmlubmVySFRNTC5zdGFydHNXaXRoKFwiPHVsXCIpIHx8IFxuICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MLnN0YXJ0c1dpdGgoXCI8b2xcIikpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBoYXNDb3B5QnV0dG9uKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGVsZW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImNvcHktY29kZS1idXR0b25cIikubGVuZ3RoICE9PSAwIHx8IFxuICAgICAgICAgICAgZWxlbWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiYWRtb25pdGlvbi1jb250ZW50LWNvcHlcIikubGVuZ3RoICE9PSAwO1xufVxuXG5mdW5jdGlvbiBoYXNEaWNlUm9sbGVyKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGVsZW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImRpY2Utcm9sbGVyXCIpLmxlbmd0aCAhPT0gMDtcbn1cblxuZnVuY3Rpb24gaGFzQWRtb25pdGlvbihlbGVtZW50OiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBlbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJhZG1vbml0aW9uXCIpLmxlbmd0aCAhPT0gMDtcbn1cblxuZnVuY3Rpb24gaXNJRnJhbWUoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcblxuICAgIGlmKGVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuXG4gICAgICAgIHJldHVybiBlbGVtZW50LmZpcnN0Q2hpbGQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJpZnJhbWVcIjtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2Vcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVGFza3NQbHVnaW4oZWxlbWVudDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHsgICAgXG4gICAgcmV0dXJuIGVsZW1lbnQuaGFzQ2xhc3MoXCJibG9jay1sYW5ndWFnZS10YXNrc1wiKSB8fCBcbiAgICBlbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJibG9jay1sYW5ndWFnZS10YXNrc1wiKS5sZW5ndGggIT09IDBcbn1cblxuZnVuY3Rpb24gaXNIb3Jpem9udGFsUnVsZShlbGVtZW50OiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBlbGVtZW50LmlubmVySFRNTC5zdGFydHNXaXRoKFwiPGhyXCIpXG59XG5cbmZ1bmN0aW9uIGlzVGFibGUoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZWxlbWVudC5pbm5lckhUTUwuc3RhcnRzV2l0aChcIjx0YWJsZVwiKVxufVxuXG5mdW5jdGlvbiBoYXNBZG1vbml0aW9uRm9sZChlbGVtZW50OiBIVE1MRWxlbWVudCkge1xuICAgIHJldHVybiBlbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJjYWxsb3V0LWZvbGRcIikubGVuZ3RoICE9PSAwO1xufVxuXG5mdW5jdGlvbiBoYXNEYXRhdmlldyhlbGVtZW50OiBIVE1MRWxlbWVudCkge1xuXG4gICAgbGV0IGlzRGF0YXZpZXcgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJibG9jay1sYW5ndWFnZS1kYXRhdmlld1wiKS5sZW5ndGggIT09IDA7XG4gICAgcmV0dXJuIGlzRGF0YXZpZXc7XG59XG5cbmZ1bmN0aW9uIGhhc0RhdGF2aWV3SW5saW5lKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgbGV0IGlzRGF0YXZpZXcgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJkYXRhdmlldy1pbmxpbmUtcXVlcnlcIikubGVuZ3RoICE9PSAwO1xuICAgIHJldHVybiBpc0RhdGF2aWV3O1xufVxuXG5mdW5jdGlvbiBoYXNEYXRhdmlld0pTQ2FudmFzKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG5cbiAgICBsZXQgaXNEYXRhdmlld0pTID0gZWxlbWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiYmxvY2stbGFuZ3VhZ2UtZGF0YXZpZXdqc1wiKS5sZW5ndGggIT09IDA7XG4gICAgbGV0IGNhbnZhcyA9IHNlYXJjaENoaWxkcmVuRm9yTm9kZVR5cGUoZWxlbWVudCwgXCJjYW52YXNcIik7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1lYW5zIG9ubHkgZGF0YXZpZXdKUyBjaGFydCBjYW52YXMgZWxlbWVudHMgc2hvdWxkIGJlIHJlbmRlcmVkIHByb3Blcmx5LiBPdGhlciBjYW52YXNlcyB3aWxsIFxuICAgICAqIG5lZWQgdGhpZXIgb3duIGNhc2UgcHV0IGluIG9yIHRoZSByZXN0cmljdGlvbiByZW1vdmVkIGFmdGVyIHRlc3RpbmcuXG4gICAgICovXG4gICAgcmV0dXJuIGNhbnZhcyAhPT0gbnVsbCAmJiBpc0RhdGF2aWV3SlMgXG59XG5cbmZ1bmN0aW9uIGhhc0RhdGF2aWV3SlMoZWxlbWVudDogSFRNTEVsZW1lbnQpIHtcblxuICAgIGxldCBpc0RhdGF2aWV3SlMgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJibG9jay1sYW5ndWFnZS1kYXRhdmlld2pzXCIpLmxlbmd0aCAhPT0gMDtcbiAgICByZXR1cm4gaXNEYXRhdmlld0pTIFxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRW1iZWQoZWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgICBsZXQgaXNFbWJlZCA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImludGVybmFsLWVtYmVkXCIpLmxlbmd0aCAhPT0gMDtcbiAgICByZXR1cm4gaXNFbWJlZDtcbn1cblxuZnVuY3Rpb24gaXNQREZFbWJlZChlbGVtZW50OiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIGxldCBpc1BERkVtYmVkID0gZWxlbWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwicGRmLWVtYmVkXCIpLmxlbmd0aCAhPT0gMDtcbiAgICByZXR1cm4gaXNQREZFbWJlZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhlYWRpbmdDb2xsYXBzZUVsZW1lbnQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBFbGVtZW50IHwgbnVsbCB7XG5cbiAgICBpZihlbGVtZW50ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGxldCBjaGlsZEVsZW1lbnRzID0gZWxlbWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiaGVhZGluZy1jb2xsYXBzZS1pbmRpY2F0b3JcIilcbiAgICBpZihjaGlsZEVsZW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gY2hpbGRFbGVtZW50c1swXTtcbiAgICB9XG4gICAgaWYoY2hpbGRFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIC8vIGNvbnNvbGUuZGVidWcoXCJGb3VuZCBtdWx0aXBsZSBoZWFkaW5nIGNvbGxhcHNlIGluZGljYXRvcnMgaW4gZWxlbWVudC5cIilcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzQ3VzdG9tSUZyYW1lKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgbGV0IGlzRnJhbWUgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJjdXN0b20tZnJhbWVzLWZyYW1lXCIpLmxlbmd0aCAhPT0gMDtcbiAgICByZXR1cm4gaXNGcmFtZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQnV0dG9uUGx1Z2luX0Nyb3NzQ29tcGF0aWJpbHR5KGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG5cbiAgICBpZihlbGVtZW50Lmhhc0NsYXNzKFwiYmxvY2stbGFuZ3VhZ2UtYnV0dG9uXCIpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGxldCBidXR0b25QbHVnaW5CbG9jayA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImJsb2NrLWxhbmd1YWdlLWJ1dHRvblwiKVswXTtcbiAgICBpZihidXR0b25QbHVnaW5CbG9jaykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzRW1iZWRlZEltYWdlKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgXG4gICAgbGV0IGltZyA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJpbWdcIilbMF07XG4gICAgaWYoaW1nID09PSBudWxsIHx8IFxuICAgICAgIGltZyA9PT0gdW5kZWZpbmVkKSB7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn0iLCIvKipcbiAqIEZpbGU6IC9zcmMvZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvUmVnaW9uTWFuYWdlci50cyAgICAgICAgICAgICAgICAgICAqXG4gKiBDcmVhdGVkIERhdGU6IFN1bmRheSwgTWF5IDIybmQgMjAyMiwgNzo0OSBwbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogQXV0aG9yOiBDYW1lcm9uIFJvYmluc29uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjIgQ2FtZXJvbiBSb2JpbnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICovXG5cbmltcG9ydCB7IERPTU9iamVjdCwgRE9NT2JqZWN0VGFnLCBUYXNrTGlzdERPTU9iamVjdCB9IGZyb20gJy4uL2RvbU9iamVjdCc7XG5pbXBvcnQgeyBNdWx0aUNvbHVtblNldHRpbmdzLCBDb2x1bW5MYXlvdXQsIGdldERlZmF1bHRNdWx0aUNvbHVtblNldHRpbmdzLCBjb2x1bW5TcGFjaW5nU3RhdGUsIGdldEluZGV4ZWRDbGFtcGVkQXJyYXlWYWx1ZSwgaXNDb2x1bW5MYXlvdXQsIHZhbGlkYXRlQ29sdW1uTGF5b3V0IH0gZnJvbSBcIi4uLy4uL3JlZ2lvblNldHRpbmdzXCI7XG5pbXBvcnQgeyBNdWx0aUNvbHVtbkxheW91dENTUywgTXVsdGlDb2x1bW5TdHlsZUNTUyB9IGZyb20gJy4uLy4uL3V0aWxpdGllcy9jc3NEZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBGaWxlRE9NTWFuYWdlciB9IGZyb20gJy4uL2RvbU1hbmFnZXInO1xuaW1wb3J0IHsgZ2V0RWxlbWVudFJlbmRlclR5cGUgfSBmcm9tICdzcmMvdXRpbGl0aWVzL2VsZW1lbnRSZW5kZXJUeXBlUGFyc2VyJztcbmltcG9ydCB7IFJlZ2lvbk1hbmFnZXJEYXRhIH0gZnJvbSAnLi9yZWdpb25NYW5hZ2VyQ29udGFpbmVyJztcbmltcG9ydCB7IHNlYXJjaENoaWxkcmVuRm9yTm9kZVR5cGUsIHNlYXJjaENoaWxkcmVuRm9yTm9kZXNPZlR5cGUgfSBmcm9tICdzcmMvdXRpbGl0aWVzL3V0aWxzJztcbmltcG9ydCB7IEhUTUxTaXppbmcgfSBmcm9tICdzcmMvdXRpbGl0aWVzL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgUmVnaW9uRXJyb3JNYW5hZ2VyIH0gZnJvbSAnLi4vcmVnaW9uRXJyb3JNYW5hZ2VyJztcblxuZXhwb3J0IHR5cGUgTXVsdGlDb2x1bW5SZW5kZXJEYXRhID0geyBcbiAgICBwYXJlbnRSZW5kZXJFbGVtZW50OiBIVE1MRWxlbWVudCwgXG4gICAgcGFyZW50UmVuZGVyU2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MsXG4gICAgZG9tT2JqZWN0czogRE9NT2JqZWN0W11cbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFJlZ2lvbk1hbmFnZXIge1xuXG4gICAgcHJvdGVjdGVkIGRvbUxpc3Q6IERPTU9iamVjdFtdID0gW107XG4gICAgcHVibGljIGdldCBudW1iZXJPZkNoaWxkcmVuKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmRvbUxpc3QubGVuZ3RoO1xuICAgIH1cbiAgICBwcm90ZWN0ZWQgZG9tT2JqZWN0TWFwOiBNYXA8c3RyaW5nLCBET01PYmplY3Q+ID0gbmV3IE1hcCgpO1xuICAgIHByaXZhdGUgX3JlZ2lvblBhcmVudDogSFRNTEVsZW1lbnQ7XG4gICAgcHVibGljIGdldCByZWdpb25QYXJlbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVnaW9uUGFyZW50O1xuICAgIH1cbiAgICBwdWJsaWMgc2V0IHJlZ2lvblBhcmVudCh2YWx1ZTogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5fcmVnaW9uUGFyZW50ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGZpbGVNYW5hZ2VyOiBGaWxlRE9NTWFuYWdlcjtcbiAgICBwcm90ZWN0ZWQgcmVnaW9uYWxTZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncyA9IGdldERlZmF1bHRNdWx0aUNvbHVtblNldHRpbmdzKCk7XG5cbiAgICBwcm90ZWN0ZWQgcmVnaW9uS2V5OiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBfZXJyb3JNYW5hZ2VyOiBSZWdpb25FcnJvck1hbmFnZXI7XG4gICAgcHVibGljIGdldCBlcnJvck1hbmFnZXIoKTogUmVnaW9uRXJyb3JNYW5hZ2VyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yTWFuYWdlcjtcbiAgICB9XG4gICAgcHJvdGVjdGVkIHNldCBlcnJvck1hbmFnZXIodmFsdWU6IFJlZ2lvbkVycm9yTWFuYWdlcikge1xuICAgICAgICB0aGlzLl9lcnJvck1hbmFnZXIgPSB2YWx1ZTtcbiAgICB9XG4gICAgcHVibGljIHVwZGF0ZUVycm9yTWFuYWdlcihuZXdNYW5hZ2VyOiBSZWdpb25FcnJvck1hbmFnZXIsIHJvb3RFbGVtZW50OiBIVE1MRGl2RWxlbWVudCkge1xuICAgICAgICB3aGlsZShyb290RWxlbWVudC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICByb290RWxlbWVudC5jaGlsZE5vZGVzLmZvckVhY2goY2hpbGQgPT4ge1xuICAgICAgICAgICAgICAgIHJvb3RFbGVtZW50LnJlbW92ZUNoaWxkKGNoaWxkKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9lcnJvck1hbmFnZXIgPSBuZXdNYW5hZ2VyO1xuICAgICAgICB0aGlzLl9lcnJvck1hbmFnZXIuc2V0UmVnaW9uUm9vdEVsZW1lbnQocm9vdEVsZW1lbnQpXG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IoZGF0YTogUmVnaW9uTWFuYWdlckRhdGEpIHtcbiAgICAgICAgdGhpcy5kb21MaXN0ID0gZGF0YS5kb21MaXN0O1xuICAgICAgICB0aGlzLmRvbU9iamVjdE1hcCA9IGRhdGEuZG9tT2JqZWN0TWFwO1xuICAgICAgICB0aGlzLnJlZ2lvblBhcmVudCA9IGRhdGEucmVnaW9uUGFyZW50O1xuXG4gICAgICAgIHRoaXMuZmlsZU1hbmFnZXIgPSBkYXRhLmZpbGVNYW5hZ2VyO1xuICAgICAgICB0aGlzLnJlZ2lvbmFsU2V0dGluZ3MgPSBkYXRhLnJlZ2lvbmFsU2V0dGluZ3M7XG5cbiAgICAgICAgdGhpcy5yZWdpb25LZXkgPSBkYXRhLnJlZ2lvbktleTtcbiAgICAgICAgdGhpcy5lcnJvck1hbmFnZXIgPSBkYXRhLmVycm9yTWFuYWdlclxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRSZWdpb25EYXRhKCk6IFJlZ2lvbk1hbmFnZXJEYXRhIHtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZG9tTGlzdDogdGhpcy5kb21MaXN0LFxuICAgICAgICAgICAgZG9tT2JqZWN0TWFwOiB0aGlzLmRvbU9iamVjdE1hcCxcbiAgICAgICAgICAgIHJlZ2lvblBhcmVudDogdGhpcy5yZWdpb25QYXJlbnQsXG5cbiAgICAgICAgICAgIGZpbGVNYW5hZ2VyOiB0aGlzLmZpbGVNYW5hZ2VyLFxuICAgICAgICAgICAgcmVnaW9uYWxTZXR0aW5nczogdGhpcy5yZWdpb25hbFNldHRpbmdzLFxuXG4gICAgICAgICAgICByZWdpb25LZXk6IHRoaXMucmVnaW9uS2V5LFxuICAgICAgICAgICAgcm9vdEVsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICBlcnJvck1hbmFnZXI6IHRoaXMuZXJyb3JNYW5hZ2VyXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIG5ldyBvYmplY3QgdG8gdGhlIHJlZ2lvbiBieSBmaW5kaW5nIHdoZXJlIGl0IHNob3VsZCBiZSByZWxhdGl2ZSB0byBpdHMgc2libGluZ3MuXG4gICAgICogQHBhcmFtIHNpYmxpbmdzQWJvdmUgVGhlIE1hcmtkb3duIHRleHQgcmVuZGVyZWQgZWxlbWVudHMgZm9yIHNpYmlsaW5ncyBhYm92ZSB0aGlzIGVsZW1lbnQgaW4gdGhlIGRvbVxuICAgICAqIEBwYXJhbSBzaWJsaW5nc0JlbG93IFRoZSBNYXJrZG93biB0ZXh0IHJlbmRlcmVkIGVsZW1lbnRzIGZvciBzaWJpbGluZ3MgYmVsb3cgdGhpcyBlbGVtZW50IGluIHRoZSBkb21cbiAgICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3QgdG8gYWRkLlxuICAgICAqIEByZXR1cm5zIFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBvYmplY3QgaGFzIGJlZW4gYWRkZWQuXG4gICAgICovXG4gICAgcHVibGljIGFkZE9iamVjdChzaWJsaW5nc0Fib3ZlOiBIVE1MRGl2RWxlbWVudCwgc2libGluZ3NCZWxvdzogSFRNTERpdkVsZW1lbnQsIG9iajogRE9NT2JqZWN0KTogbnVtYmVyIHtcblxuICAgICAgICBsZXQgbmV4dE9iaiA9IHNpYmxpbmdzQmVsb3cuY2hpbGRyZW5bMF0gYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAgICAgbGV0IGFkZEF0SW5kZXggPSBzaWJsaW5nc0Fib3ZlLmNoaWxkcmVuLmxlbmd0aDtcblxuICAgICAgICBpZiAoc2libGluZ3NBYm92ZS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogV2Ugd2FudCB0byBmaW5kIHRoZSBmaXJzdCBzaWJsaW5nIHdpdGhvdXRoIFwiXCIgZm9yIGFuIGlubmVyIHRleHQgc28gd2UgY2FuIHVzZSB0aGF0IHRvIGFuY2hvciBvdXJcbiAgICAgICAgICAgICAqIGVsZW1lbnQgaW50byB0aGUgZG9tTGlzdC4gRm9yIG1vc3QgaXRlbXMgdGhlIGZpcnN0IGVsZW1lbnQgYmVmb3JlIG91ciBuZXcgZWxlbWVudCB3aWxsIGhhdmUgdGhlIHByb3BlclxuICAgICAgICAgICAgICogaW5uZXJUZXh0LiBTb21ldGltZXMgb3RoZXIgZWxlbWVudHMgYXJlIGVtcHR5IGFuZCB3ZXJlIGNhdXNpbmcgaXNzdWVzLlxuICAgICAgICAgICAgICogXG4gICAgICAgICAgICAgKiBOb3cgd2UgbG9vcCBiYWNrIHRocm91Z2ggdGhlIHByZXZpb3VzIHNpYmxpbmdzIGxvb2tpbmcgZm9yIHRoZSBmaXJzdCBvbmUgd2l0aCBhIHZhbGlkIGlubmVyIHRleHQgYW5kIHVzaW5nIHRoYXQgXG4gICAgICAgICAgICAgKiBhcyB0aGUgYW5jaG9yIGFuZCBvZmZzZXR0aW5nIG91ciBhZGRBdEluZGV4IGJ5IHRoZSBudW1iZXIgb2YgZW1wdHkgc3RyaW5nIGVsZW1lbnRzIHdlIGZvdW5kLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBsZXQgcHJldlNpYmxpbmdJbm5lclRleHQgPSBcIlwiXG4gICAgICAgICAgICBsZXQgcHJldlNpYmxpbmdPZmZzZXQgPSAwO1xuICAgICAgICAgICAgZm9yKGxldCBpID0gc2libGluZ3NBYm92ZS5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IG9iaiA9IHNpYmxpbmdzQWJvdmUuY2hpbGRyZW5baV0gYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgaWYob2JqLmlubmVyVGV4dCAhPT0gXCJcIikge1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBwcmV2U2libGluZ0lubmVyVGV4dCA9IG9iai5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHByZXZTaWJsaW5nT2Zmc2V0Kys7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSB0aGlzLmRvbUxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kb21MaXN0W2ldLm5vZGVLZXkgPT09IHByZXZTaWJsaW5nSW5uZXJUZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZEF0SW5kZXggPSBpICsgMSArIHByZXZTaWJsaW5nT2Zmc2V0O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbmV4dEVsSW5kZXggPSBhZGRBdEluZGV4O1xuICAgICAgICBsZXQgbmV4dE9ialRleHQgPSBcIlwiO1xuICAgICAgICBpZiAobmV4dE9iaiAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICAgICAgICAgIGxldCBmb3VuZE5leHQgPSBmYWxzZTtcbiAgICAgICAgICAgIG5leHRPYmpUZXh0ID0gbmV4dE9iai5pbm5lclRleHQ7XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBhZGRBdEluZGV4OyBpIDwgdGhpcy5kb21MaXN0Lmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kb21MaXN0W2ldLm5vZGVLZXkgPT09IG5leHRPYmouaW5uZXJUZXh0LnRyaW0oKSkge1xuXG4gICAgICAgICAgICAgICAgICAgIG5leHRFbEluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgZm91bmROZXh0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gY29uc29sZS5sb2coXCIgUHJldjogXCIsIEFycmF5LmZyb20oc2libGluZ3NBYm92ZS5jaGlsZHJlbikuc2xpY2UoLTMpLCBcIkFkZGluZzogXCIsIG9iai5vcmlnaW5hbEVsZW1lbnQsIFwiIE5leHQ6IFwiLCBzaWJsaW5nc0JlbG93LmNoaWxkcmVuWzBdLCBcIk92ZXJ3cml0aW5nOlwiLCB0aGlzLmRvbUxpc3Quc2xpY2UoYWRkQXRJbmRleCwgbmV4dEVsSW5kZXgpKTtcbiAgICAgICAgdGhpcy5kb21MaXN0LnNwbGljZShhZGRBdEluZGV4LCBuZXh0RWxJbmRleCAtIGFkZEF0SW5kZXgsIG9iaik7XG4gICAgICAgIHRoaXMuZG9tT2JqZWN0TWFwLnNldChvYmouVUlELCBvYmopO1xuXG4gICAgICAgIC8vIC8qKlxuICAgICAgICAvLyAgKiBNYWtlIGEgY29weSBvZiB0aGUgbGlzdCB0byBsb2csIG9ubHkgYmVjYXVzZVxuICAgICAgICAvLyAgKiBjb25zb2xlIGxvZyB1cGRhdGVzIGl0cyByZWZlcmVuY2VzIHdpdGggdXBkYXRlcyBpbiBtZW1vcnkuXG4gICAgICAgIC8vICAqL1xuICAgICAgICAvLyBsZXQgeCA9IHRoaXMuZG9tTGlzdC5zbGljZSgwKTtcbiAgICAgICAgLy8gY29uc29sZS5sb2coeCk7XG4gICAgICAgIHJldHVybiBhZGRBdEluZGV4O1xuICAgIH1cblxuICAgIHB1YmxpYyBhZGRPYmplY3RBdEluZGV4KG9iajogRE9NT2JqZWN0LCBpbmRleDogbnVtYmVyKSB7XG5cbiAgICAgICAgdGhpcy5kb21MaXN0LnNwbGljZShpbmRleCwgMCwgb2JqKTtcbiAgICAgICAgdGhpcy5kb21PYmplY3RNYXAuc2V0KG9iai5VSUQsIG9iaik7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbW92ZU9iamVjdChvYmplY3RVSUQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICAvLyAvKipcbiAgICAgICAgLy8gICogTWFrZSBhIGNvcHkgb2YgdGhlIGxpc3QgdG8gbG9nXG4gICAgICAgIC8vICAqL1xuICAgICAgICAvLyBsZXQgeCA9IGRvbUxpc3Quc2xpY2UoMCk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHgpO1xuICAgICAgICAvLyBHZXQgdGhlIG9iamVjdCBieSBrZXksIHJlbW92ZSBpdCBmcm9tIHRoZSBtYXAgYW5kIHRoZW5cbiAgICAgICAgLy8gZnJvbSB0aGUgbGlzdC5cbiAgICAgICAgbGV0IG9iaiA9IHRoaXMuZG9tT2JqZWN0TWFwLmdldChvYmplY3RVSUQpO1xuICAgICAgICB0aGlzLmRvbU9iamVjdE1hcC5kZWxldGUob2JqZWN0VUlEKTtcblxuICAgICAgICBpZiAob2JqID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRvbUxpc3QuY29udGFpbnMob2JqKSkge1xuICAgICAgICAgICAgdGhpcy5kb21MaXN0LnJlbW92ZShvYmopO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZG9tTGlzdC5sZW5ndGggPT09IDAgJiYgdGhpcy5maWxlTWFuYWdlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5maWxlTWFuYWdlci5yZW1vdmVSZWdpb24odGhpcy5yZWdpb25LZXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8geCA9IGRvbUxpc3Quc2xpY2UoMCk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHgpO1xuICAgIH1cblxuICAgIHB1YmxpYyB1cGRhdGVFbGVtZW50VGFnKG9iamVjdFVJRDogc3RyaW5nLCBuZXdUYWc6IERPTU9iamVjdFRhZyk6IHZvaWQge1xuXG4gICAgICAgIGxldCBvYmogPSB0aGlzLmRvbU9iamVjdE1hcC5nZXQob2JqZWN0VUlEKTtcbiAgICAgICAgb2JqLnRhZyA9IG5ld1RhZztcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0UmVnaW9uYWxTZXR0aW5ncyhyZWdpb25TZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncyk6IHZvaWQge1xuICAgICAgICB0aGlzLnJlZ2lvbmFsU2V0dGluZ3MgPSByZWdpb25TZXR0aW5ncztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb250YWluaW5nIGFsbCBuZWNlc3NhcnkgaW5mb3JtYXRpb24gZm9yIHRoZSByZWdpb25cbiAgICAgKiB0byBiZSByZW5kZXJlZCB0byB0aGUgcHJldmlldyBwYW5lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgYSBNdWx0aUNvbHVtblJlbmRlckRhdGEgb2JqZWN0IHdpdGggdGhlIHJvb3QgRE9NIGVsZW1lbnQsIHNldHRpbmdzIG9iamVjdCwgYW5kXG4gICAgICogYWxsIGNoaWxkIG9iamVjdHMgaW4gdGhlIG9yZGVyIHRoZXkgc2hvdWxkIGJlIHJlbmRlcmVkLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRSZWdpb25SZW5kZXJEYXRhKCk6IE11bHRpQ29sdW1uUmVuZGVyRGF0YSB7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHBhcmVudFJlbmRlckVsZW1lbnQ6IHRoaXMucmVnaW9uUGFyZW50LFxuICAgICAgICAgICAgcGFyZW50UmVuZGVyU2V0dGluZ3M6IHRoaXMucmVnaW9uYWxTZXR0aW5ncyxcbiAgICAgICAgICAgIGRvbU9iamVjdHM6IHRoaXMuZG9tTGlzdFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVjdGlvbiBpcyBjYWxsZWQgd2hlbiBhIHN0YXJ0IHRhZyBpcyByZW1vdmVkIGZyb20gdmlldyBtZWFuaW5nXG4gICAgICogb3VyIHBhcmVudCBlbGVtZW50IHN0b3JpbmcgdGhlIG11bHRpLWNvbHVtbiByZWdpb24gaXMgcmVtb3ZlZC4gSXRcbiAgICAgKiByZW1vdmVzIHRoZSBDU1MgY2xhc3MgZnJvbSBhbGwgb2YgdGhlIGVsZW1lbnRzIHNvIHRoZXkgd2lsbCBiZVxuICAgICAqIHJlLXJlbmRlcmVkIGluIHRoZSBwcmV2aWV3IHdpbmRvdy5cbiAgICAgKi9cbiAgICBwdWJsaWMgZGlzcGxheU9yaWdpbmFsRWxlbWVudHMoKSB7XG5cblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZG9tTGlzdC5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kb21MaXN0W2ldLm9yaWdpbmFsRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZG9tTGlzdFtpXS5vcmlnaW5hbEVsZW1lbnQucmVtb3ZlQ2xhc3NlcyhbTXVsdGlDb2x1bW5TdHlsZUNTUy5SZWdpb25FbmRUYWcsXG4gICAgICAgICAgICAgICAgTXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5FbmRUYWcsXG4gICAgICAgICAgICAgICAgTXVsdGlDb2x1bW5TdHlsZUNTUy5SZWdpb25TZXR0aW5ncyxcbiAgICAgICAgICAgICAgICBNdWx0aUNvbHVtblN0eWxlQ1NTLlJlZ2lvbkNvbnRlbnRdKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kb21MaXN0W2ldLm9yaWdpbmFsRWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZG9tTGlzdFtpXS5vcmlnaW5hbEVsZW1lbnQucGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzLmRvbUxpc3RbaV0ub3JpZ2luYWxFbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgcHVibGljIGdldElEKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZ2lvbktleTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlUmVuZGVyZWRNYXJrZG93bigpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoaXMgZnVuY3Rpb24gYWN0cyBhcyB0aGUgdXBkYXRlIGxvb3AgZm9yIHRoZSBtdWx0aS1jb2x1bW4gcmVnaW9ucy5cbiAgICAgICAgICogSGVyZSB3ZSBsb29wIHRocm91Z2ggYWxsIG9mIHRoZSBlbGVtZW50cyB3aXRoaW4gdGhlIHJlbmRlcmVkIHJlZ2lvbiBhbmRcbiAgICAgICAgICogcG90ZW50aWFsbHkgdXBkYXRlIGhvdyB0aGluZ3MgYXJlIHJlbmRlcmVkLiBXZSBuZWVkIHRvIGRvIHRoaXMgZm9yXG4gICAgICAgICAqIGNvbXBhdGFiaWxpdHkgd2l0aCBvdGhlciBwbHVnaW5zLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgbXVsdGktY29sdW1uIHJlZ2lvbiBpcyByZW5kZXJlZCBiZWZvcmUgb3RoZXIgcGx1Z2lucyB0aGF0IGVmZmVjdFxuICAgICAgICAgKiBjb250ZW50IHdpdGhpbiB0aGUgcmVnaW9uIG91ciByZW5kZXJlZCBkYXRhIG1heSBub3QgcHJvcGVybHkgZGlzcGxheVxuICAgICAgICAgKiB0aGUgY29udGVudCBmcm9tIHRoZSBvdGhlciBwbHVnaW4uIEhlcmUgd2UgbG9vcCB0aHJvdWdoIHRoZSBlbGVtZW50c1xuICAgICAgICAgKiBhZnRlciBhbGwgcGx1Z2lucyBoYXZlIGhhZCBhIGNoYW5jZSB0byBydW4gYW5kIGNhbiBtYWtlIGNoYW5nZXMgdG8gdGhlXG4gICAgICAgICAqIERPTSBhdCB0aGlzIHBvaW50LlxuICAgICAgICAgKi9cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmRvbUxpc3QubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgbGV0IGVsZW1lbnRUeXBlID0gdGhpcy5kb21MaXN0W2ldLmVsZW1lbnRUeXBlO1xuICAgICAgICAgICAgaWYoZWxlbWVudFR5cGUgPT09IFwidW5SZW5kZXJlZFwiKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogSWYgdGhlIGVsZW1lbnQgaXMgbm90IGN1cnJlbnRseSBhIHNwZWNpYWwgcmVuZGVyIGVsZW1lbnQgd2UgY2hlY2sgYWdhaW5cbiAgICAgICAgICAgICAqIGFzIHRoZSBvcmlnaW5hbCBlbGVtZW50IG1heSBoYXZlIGJlZW4gdXBkYXRlZC5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYoZWxlbWVudFR5cGUgPT09IFwidW5kZWZpbmVkXCIgfHxcbiAgICAgICAgICAgICAgIGVsZW1lbnRUeXBlID09PSBcImJhc2ljRWxlbWVudFwiIHx8XG4gICAgICAgICAgICAgICBlbGVtZW50VHlwZSA9PT0gXCJzcGVjaWFsUmVuZGVyXCIpIHtcblxuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBuZXcgcmVzdWx0IHJldHVybnMgYXMgYSBzcGVjaWFsIHJlbmRlcmVyIHdlIHVwZGF0ZSBzb1xuICAgICAgICAgICAgICAgIC8vIHRoaXMgd29udCBydW4gYWdhaW4gZm9yIHRoaXMgaXRlbS5cbiAgICAgICAgICAgICAgICBlbGVtZW50VHlwZSA9IGdldEVsZW1lbnRSZW5kZXJUeXBlKHRoaXMuZG9tTGlzdFtpXS5vcmlnaW5hbEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgdGFza0xpc3RPYmogPSAodGhpcy5kb21MaXN0W2ldIGFzIFRhc2tMaXN0RE9NT2JqZWN0KVxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBIZXJlIHdlIGNoZWNrIGZvciBzcGVjaWFsIGNhc2VzXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICh0YXNrTGlzdE9iaiAmJiBcbiAgICAgICAgICAgICAgICBlbGVtZW50VHlwZSA9PT0gXCJkYXRhdmlld0pTRW1iZWRcIikge1xuXG4gICAgICAgICAgICAgICAgaWYodGhpcy5kb21MaXN0W2ldLmNsb25lZEVsZW1lbnRSZWFkeUZvclVwZGF0ZSgpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY2xvbmVFbGVtZW50KHRoaXMuZG9tTGlzdFtpXSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZml4Q2xvbmVkQ2hlY2tMaXN0QnV0dG9ucyh0aGlzLmRvbUxpc3RbaV0gYXMgVGFza0xpc3RET01PYmplY3QsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXhDbG9uZWRDaGVja0xpc3RCdXR0b25zKHRoaXMuZG9tTGlzdFtpXSBhcyBUYXNrTGlzdERPTU9iamVjdClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRhc2tMaXN0T2JqICYmIFxuICAgICAgICAgICAgICAgIGVsZW1lbnRUeXBlID09PSBcImJhc2ljRWxlbWVudFwiKSB7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmZpeENsb25lZENoZWNrTGlzdEJ1dHRvbnModGhpcy5kb21MaXN0W2ldIGFzIFRhc2tMaXN0RE9NT2JqZWN0KTtcbiAgICAgICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZihlbGVtZW50VHlwZSA9PT0gXCJiYXNpY0VsZW1lbnRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuZG9tTGlzdFtpXS5lbGVtZW50VHlwZSA9IFwiYmFzaWNFbGVtZW50XCJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYoZWxlbWVudFR5cGUgPT09IFwiaW1hZ2VFbWJlZFwiKSB7Ly9FbGVtZW50UmVuZGVyVHlwZS5maXhlZEVsZW1lbnRSZW5kZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRvbUxpc3RbaV0uZWxlbWVudFR5cGUgPSBlbGVtZW50VHlwZTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYoZWxlbWVudFR5cGUgPT09IFwiYnV0dG9uUGx1Z2luXCIpIHtcbiAgICAgICAgICAgICAgICBwcm9jZXNzQnV0dG9uUGx1Z2luVXBkYXRlKHRoaXMuZG9tTGlzdFtpXSlcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYoZWxlbWVudFR5cGUgPT09IFwicGRmRW1iZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuZG9tTGlzdFtpXS5lbGVtZW50VHlwZSA9IGVsZW1lbnRUeXBlO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0VXBEdWFsUmVuZGVyKHRoaXMuZG9tTGlzdFtpXSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmKGVsZW1lbnRUeXBlID09PSBcImRpY2VSb2xsZXJcIiB8fFxuICAgICAgICAgICAgICAgZWxlbWVudFR5cGUgPT09IFwiYWRtb25pdGlvbkZvbGRcIiB8fFxuICAgICAgICAgICAgICAgZWxlbWVudFR5cGUgPT09IFwiY2FsbG91dENvcHlCdXR0b25cIiB8fFxuICAgICAgICAgICAgICAgZWxlbWVudFR5cGUgPT09IFwiZGF0YXZpZXdQbHVnaW5cIiB8fFxuICAgICAgICAgICAgICAgZWxlbWVudFR5cGUgPT09IFwiaW50ZXJuYWxFbWJlZFwiIHx8XG4gICAgICAgICAgICAgICBlbGVtZW50VHlwZSA9PT0gXCJkYXRhdmlld0pTQ2FudmFzRW1iZWRcIiB8fFxuICAgICAgICAgICAgICAgZWxlbWVudFR5cGUgPT09IFwiZGF0YXZpZXdKU0VtYmVkXCIgfHwgXG4gICAgICAgICAgICAgICBlbGVtZW50VHlwZSA9PT0gXCJkYXRhdmlld0lubGluZVF1ZXJ5XCIgfHxcbiAgICAgICAgICAgICAgIGVsZW1lbnRUeXBlID09PSBcInRhc2tzUGx1Z2luXCJcbiAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHRoaXMuZG9tTGlzdFtpXS5lbGVtZW50VHlwZSA9IGVsZW1lbnRUeXBlO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0VXBEdWFsUmVuZGVyKHRoaXMuZG9tTGlzdFtpXSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIHRha2VzIGluIHRoZSBvcmlnaW5hbCBlbGVtZW50IGFuZCBpdHMgY2xvbmUgYW5kIGNoZWNrcyBpZlxuICAgICAqIHRoZSBlbGVtZW50IGNvbnRhaW5zIGEgdGFzay1saXN0LWl0ZW0gY2xhc3MuIElmIHNvIGl0IGxvb3BzIHRocm91Z2ggYWxsXG4gICAgICogaXRlbXMgaW4gdGhlIGxpc3QgYW5kIGZpeGVzIHRoZWlyIGNoZWNrYm94ZXMgdG8gcHJvcGVybHkgZmlyZSBhbiBldmVudC5cbiAgICAgKiBUaGUgbmV3IGNoZWNrYm94IGNhbGxzIHRoZSBjbGljayBmdW5jdGlvbiBvbiB0aGUgb3JpZ2luYWwgY2hlY2tib3ggc29cbiAgICAgKiBjb21wYXRhYmlsaXR5IHdpdGggb3RoZXIgcGx1Z2lucyAqc2hvdWxkKiByZW1haW4uXG4gICAgICogQHBhcmFtIGRvbUVsZW1lbnRcbiAgICAgKiBAcGFyYW0gaW5pdGFsaXplQ2hlY2tib3hlc1xuICAgICAqL1xuICAgIHByb3RlY3RlZCBmaXhDbG9uZWRDaGVja0xpc3RCdXR0b25zKGRvbUVsZW1lbnQ6IFRhc2tMaXN0RE9NT2JqZWN0LCBpbml0YWxpemVDaGVja2JveGVzOiBib29sZWFuID0gZmFsc2UpIHtcblxuICAgICAgICBpZihkb21FbGVtZW50Lm9yaWdpbmFsRWxlbWVudCA9PT0gbnVsbCB8fCBkb21FbGVtZW50LmNsb25lZEVsZW1lbnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBlbGVtZW50OiBIVE1MRWxlbWVudCA9IGRvbUVsZW1lbnQub3JpZ2luYWxFbGVtZW50O1xuICAgICAgICBsZXQgY2xvbmVkRWxlbWVudDogSFRNTEVsZW1lbnQgPSBkb21FbGVtZW50LmNsb25lZEVsZW1lbnQ7XG5cbiAgICAgICAgbGV0IGNsb25lZExpc3RDaGVja2JveGVzID0gQXJyYXkuZnJvbShjbG9uZWRFbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJ0YXNrLWxpc3QtaXRlbVwiKSkgYXMgSFRNTEVsZW1lbnRbXTtcbiAgICAgICAgbGV0IG9yaWdpbmFsTGlzdENoZWNrYm94ZXMgPSBBcnJheS5mcm9tKGVsZW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInRhc2stbGlzdC1pdGVtXCIpKSBhcyBIVE1MRWxlbWVudFtdO1xuXG4gICAgICAgIGlmIChpbml0YWxpemVDaGVja2JveGVzID09PSB0cnVlKSB7XG5cbiAgICAgICAgICAgIGRvbUVsZW1lbnQub3JpZ2luYWxDaGVja2JveGVzID0gb3JpZ2luYWxMaXN0Q2hlY2tib3hlcztcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgaW5pdGFsaXplIHdlIHJlbW92ZSB0aGUgb2xkIGlucHV0IGNoZWNrYm94IHRoYXQgY29udGFpbnNcbiAgICAgICAgICAgIC8vIHRoZSB3ZWlyZCBjYWxsYmFjayBzaXR1YXRpb24gY2F1c2luZyB0aGUgYnVnLiBUaGVuIHdlIGNyZWF0ZSBhIG5ld1xuICAgICAgICAgICAgLy8gY2hlY2tib3ggdG8gcmVwbGFjZSBpdCBhbmQgc2V0IGl0IHVwIHRvIGZpcmUgdGhlIGNsaWNrIGV2ZW50IG9uXG4gICAgICAgICAgICAvLyB0aGUgb3JpZ2luYWwgY2hlY2tib3ggc28gZnVuY3Rpb25hbGl0eSBpcyByZXN0b3JlZC5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JpZ2luYWxMaXN0Q2hlY2tib3hlcy5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgICAgICAgICAgY29uc3QgY2hlY2tib3ggPSBjcmVhdGVFbCgnaW5wdXQnKTtcblxuICAgICAgICAgICAgICAgIGxldCBvcmlnaW5hbElucHV0ID0gb3JpZ2luYWxMaXN0Q2hlY2tib3hlc1tpXS5nZXRFbGVtZW50c0J5VGFnTmFtZShcImlucHV0XCIpWzBdXG5cbiAgICAgICAgICAgICAgICBsZXQgaXNDaGVja2VkID0gZmFsc2VcbiAgICAgICAgICAgICAgICBpZihvcmlnaW5hbElucHV0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlzQ2hlY2tlZCA9IG9yaWdpbmFsSW5wdXQuY2hlY2tlZFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcIkNvdWxkIG5vdCBmaW5kIG9yaWdpbmFsIGNoZWNrYm94LiBJcyBpdCBudWxsP1wiKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBvbGRDaGVja2JveCA9IFRhc2tMaXN0RE9NT2JqZWN0LmdldENoaWxkQ2hlY2tib3goY2xvbmVkTGlzdENoZWNrYm94ZXNbaV0pXG4gICAgICAgICAgICAgICAgY2xvbmVkTGlzdENoZWNrYm94ZXNbaV0ucmVwbGFjZUNoaWxkKGNoZWNrYm94LCBvbGRDaGVja2JveCk7XG5cbiAgICAgICAgICAgICAgICBjaGVja2JveC5jaGVja2VkID0gaXNDaGVja2VkXG4gICAgICAgICAgICAgICAgY2hlY2tib3guYWRkQ2xhc3MoJ3Rhc2stbGlzdC1pdGVtLWNoZWNrYm94Jyk7XG4gICAgICAgICAgICAgICAgY2hlY2tib3gudHlwZSA9ICdjaGVja2JveCc7XG4gICAgICAgICAgICAgICAgY2hlY2tib3gub25DbGlja0V2ZW50KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZG9tRWxlbWVudC5jaGVja2JveENsaWNrZWQoaSk7XG4gICAgICAgICAgICAgICAgICAgIGlmKGNoZWNrYm94LmNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lZExpc3RDaGVja2JveGVzW2ldLmFkZENsYXNzKFwiaXMtY2hlY2tlZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgY2xvbmVkTGlzdENoZWNrYm94ZXNbaV0uc2V0QXR0cihcImRhdGEtdGFza1wiLCBcInhcIilcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lZExpc3RDaGVja2JveGVzW2ldLnJlbW92ZUNsYXNzKFwiaXMtY2hlY2tlZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgY2xvbmVkTGlzdENoZWNrYm94ZXNbaV0uc2V0QXR0cihcImRhdGEtdGFza1wiLCBcIiBcIilcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuXG4gICAgICAgICAgICAvLyBXaGVuZXZlciB3ZSByZWFjaCB0aGlzIHBvaW50IHdlIHVwZGF0ZSBvdXIgbGlzdCBvZiBvcmlnaW5hbCBjaGVja2JveGVzXG4gICAgICAgICAgICAvLyB0aGF0IG1heSBiZSBkaWZmZXJlbnQgZnJvbSBvdXIgY2FjaGUuIFRoaXMgaXMgZHVlIHRvIGhvdyBvYnNpZGlhblxuICAgICAgICAgICAgLy8gY2hhbmdlcyB0aGUgRE9NIHVuZGVybmVhdGggdXMgc28gd2UgbmVlZCB0byBjb25zdGFudGx5IHVwZGF0ZSBvdXIgY2FjaGUuXG4gICAgICAgICAgICBkb21FbGVtZW50Lm9yaWdpbmFsQ2hlY2tib3hlcyA9IG9yaWdpbmFsTGlzdENoZWNrYm94ZXM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBXaGVuIHRoZSBUYXNrcyBwbHVnaW4gaXMgaW5zdGFsbGVkIHRoZSBjbG9uZWQgY29weSBvZiB0aGUgb3JpZ2luYWwgZWxlbWVudCBjb250YWluc1xuICAgICAgICAvLyBhbiBleHRyYSBlbGVtZW50IGZvciBzb21lIHJlYXNvbi4gSWYgdGhpcyBvY2N1cnMgZm9yIG90aGVyIHJlYXNvbnMgaGVyZSB3ZSBhZGp1c3RcbiAgICAgICAgLy8gdGhhdCB0byBrZWVwIHRoZSBjbG9uZSB0aGUgc2FtZSBhcyB0aGUgb3JpZ2luYWwuXG4gICAgICAgIGlmIChjbG9uZWRMaXN0Q2hlY2tib3hlcy5sZW5ndGggPiBvcmlnaW5hbExpc3RDaGVja2JveGVzLmxlbmd0aCkge1xuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gb3JpZ2luYWxMaXN0Q2hlY2tib3hlcy5sZW5ndGg7IGkgPCBjbG9uZWRMaXN0Q2hlY2tib3hlcy5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY2xvbmVkTGlzdENoZWNrYm94ZXNbaV0uZGV0YWNoKClcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwiTm8gY2hpbGQgZm91bmQgd2hlbiByZW1vdmluZyBmcm9tIGxpc3QuXCIpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHNldFVwRHVhbFJlbmRlcihkb21FbGVtZW50OiBET01PYmplY3QpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgb3VyIGVsZW1lbnQgaXMgb2YgXCJzcGVjaWFsUmVuZGVyXCIgdHlwZSBpdCAqbWF5KiBuZWVkIHRvIGJlIHJlbmRlcmVkXG4gICAgICAgICAqIHVzaW5nIHRoZSBvcmlnaW5hbCBlbGVtZW50IHJhdGhlciB0aGFuIGEgY29weS4gRm9yIGV4YW1wbGUsIGFuIGVsZW1lbnRcbiAgICAgICAgICogbWF5IGhhdmUgYW4gb25DbGljayBldmVudCB0aGF0IHdvdWxkIG5vdCBnZXQgY29wcGllZCB0byB0aGUgY2xvbmUuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHdlIGp1c3QgbW92ZWQgdGhlc2UgZWxlbWVudHMgaW50byB0aGUgcmVnaW9uIGl0IHdvdWxkIGdldFxuICAgICAgICAgKiBtb3ZlZCBiYWNrIG91dCBpbnRvIHRoZSBvcmlnaW5hbCBsb2NhdGlvbiBpbiB0aGUgRE9NIGJ5IG9ic2lkaWFuXG4gICAgICAgICAqIHdoZW4gc2Nyb2xsaW5nIG9yIHdoZW4gdGhlIGZpbGUgaXMgdXBkYXRlZC4gT24gdGhlIG5leHQgcmVmcmVzaCBpdFxuICAgICAgICAgKiB3b3VsZCBiZSBtb3ZlZCBiYWNrIGJ1dCB0aGF0IGNhbiBsZWFkIHRvIGEgcmVnaW9uIGp1bXBpbmdcbiAgICAgICAgICogYXJvdW5kIGFzIHRoZSBpdGVtIGlzIG1vdmVkIGluIGFuZCBvdXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEhlcmUgd2Ugc2V0IHVwIHRoZSBkaXYgdG8gY29udGFpbiB0aGUgZWxlbWVudCBhbmQgY3JlYXRlXG4gICAgICAgICAqIGEgdmlzdWFsIG9ubHkgY2xvbmUgb2YgaXQuIFRoZSBjbG9uZSB3aWxsIG9ubHkgYmUgdmlzaWJsZVxuICAgICAgICAgKiB3aGVuIHRoZSBvcmlnaW5hbCBpcyBub3QgaW4gdGhlIG11bHRpLWNvbHVtbiByZWdpb24gc28gaXRcbiAgICAgICAgICogc2F2ZXMgdXMgZnJvbSB0aGUgdmlzdWFsIG5vaXNlIG9mIHRoZSByZWdpb24ganVtcGluZyBhcm91bmQuXG4gICAgICAgICAqL1xuXG4gICAgICAgICBsZXQgb3JpZ2luYWxFbGVtZW50ID0gZG9tRWxlbWVudC5vcmlnaW5hbEVsZW1lbnQ7XG4gICAgICAgICBsZXQgY2xvbmVkRWxlbWVudCA9IGRvbUVsZW1lbnQuY2xvbmVkRWxlbWVudDtcbiAgICAgICAgIGxldCBjb250YWluZXJFbGVtZW50OiBIVE1MRGl2RWxlbWVudCA9IGRvbUVsZW1lbnQuZWxlbWVudENvbnRhaW5lcjtcblxuICAgICAgICAvLyBHZXQgaGVpZ2h0IG9mIHRoZSBvcmlnaW5hbCBhbmQgY2xvbmVkIGVsZW1lbnQuIElmIHRoZSBlbGVtZW50IGlzIG5vdCBjdXJyZW50bHkgcmVuZGVyZWRcbiAgICAgICAgLy8gaXQgd2lsbCBoYXZlIDAgaGVpZ2h0IHNvIHdlIG5lZWQgdG8gdGVtcG9yYXJpbHkgcmVuZGVyIGl0IHRvIGdldCB0aGUgaGVpZ2h0LlxuICAgICAgICBsZXQgb3JpZ2luYWxFbGVtZW50SGVpZ2h0ID0gZ2V0RWxlbWVudENsaWVudEhlaWdodChvcmlnaW5hbEVsZW1lbnQsIGNvbnRhaW5lckVsZW1lbnQpO1xuICAgICAgICBsZXQgY2xvbmVkRWxlbWVudEhlaWdodCA9IGdldEVsZW1lbnRDbGllbnRIZWlnaHQoY2xvbmVkRWxlbWVudCwgY29udGFpbmVyRWxlbWVudCk7XG5cbiAgICAgICAgaWYoZG9tRWxlbWVudC5lbGVtZW50VHlwZSA9PT0gXCJwZGZFbWJlZFwiKSB7XG4gICAgICAgICAgICB1cGRhdGVQREZFbWJlZChkb21FbGVtZW50KVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9tRWxlbWVudC5lbGVtZW50VHlwZSA9PT0gXCJkYXRhdmlld0pTQ2FudmFzRW1iZWRcIikge1xuICAgICAgICAgICAgcmVSZW5kZXJEYXRhdmlld0pTKGRvbUVsZW1lbnQpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXZSBvbmx5IHdhbnQgdG8gY2xvbmUgdGhlIGVsZW1lbnQgb25jZSB0byByZWR1Y2UgR0MuIEJ1dCBpZiB0aGUgY2xvbmVkIFxuICAgICAgICAgKiBlbGVtZW50J3MgaGVpZ2h0IGlzIG5vdCBlcXVhbCB0byB0aGUgb3JpZ2luYWwgZWxlbWVudCwgdGhpcyBtZWFucyB0aGVcbiAgICAgICAgICogaXRlbSBlbGVtZW50IGhhcyBiZWVuIHVwZGF0ZWQgc29tZXdoZXJlIGVsc2Ugd2l0aG91dCB0aGUgZG9tIGJlaW5nIFxuICAgICAgICAgKiByZWZyZXNoZWQuIFRoaXMgY2FuIG9jY3VyIHdoZW4gZWxlbWVudHMgYXJlIHVwZGF0ZWQgYnkgb3RoZXIgcGx1Z2lucywgXG4gICAgICAgICAqIHN1Y2ggYXMgRGF0YXZpZXcuXG4gICAgICAgICAqL1xuICAgICAgICBpZigoY2xvbmVkRWxlbWVudCA9PT0gbnVsbCAgfHwgXG4gICAgICAgICAgIE1hdGguYWJzKGNsb25lZEVsZW1lbnRIZWlnaHQgLSBvcmlnaW5hbEVsZW1lbnRIZWlnaHQpID4gMTAgfHxcbiAgICAgICAgICAgZG9tRWxlbWVudC5jbG9uZWRFbGVtZW50UmVhZHlGb3JVcGRhdGUoKSA9PT0gdHJ1ZSkpIHtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJVcGRhdGluZyBDbG9uZWQgRWxlbWVudC5cIiwgRWxlbWVudFJlbmRlclR5cGVbZG9tRWxlbWVudC5lbGVtZW50VHlwZV0sIGNsb25lZEVsZW1lbnRIZWlnaHQsIG9yaWdpbmFsRWxlbWVudEhlaWdodClcbiAgICAgICAgICAgIC8vIFVwZGF0ZSBjbG9uZSBhbmQgcmVmZXJlbmNlLlxuICAgICAgICAgICAgY2xvbmVFbGVtZW50KGRvbUVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvKiogXG4gICAgICAgICAqIElmIHRoZSBjb250YWluZXIgZWxlbWVudCBoYXMgbGVzcyB0aGFuIDIgY2hpbGRyZW4gd2UgbmVlZCB0byBtb3ZlIHRoZVxuICAgICAgICAgKiBvcmlnaW5hbCBlbGVtZW50IGJhY2sgaW50byBpdC4gSG93ZXZlciBzb21lIGVsZW1lbnRzIGNvbnN0YW50bHkgZ2V0IG1vdmVkXG4gICAgICAgICAqIGluIGFuZCBvdXQgY2F1c2luZyBzb21lIHVud2FudGVkIGJlaGF2aW9yLiBUaG9zZSBlbGVtZW50IHdpbGwgYmUgdGFnZ2VkXG4gICAgICAgICAqIGFzIHNwZWNpYWxTaW5nbGVFbGVtZW50UmVuZGVyIHNvIHdlIGlnbm9yZSB0aG9zZSBlbGVtZW50cyBoZXJlLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYoZG9tRWxlbWVudC5lbGVtZW50Q29udGFpbmVyLmNoaWxkcmVuLmxlbmd0aCA8IDIgJiYgXG4gICAgICAgICAgIGRvbUVsZW1lbnQuZWxlbWVudFR5cGUgIT09IFwiZGF0YXZpZXdQbHVnaW5cIiAmJlxuICAgICAgICAgICBkb21FbGVtZW50LmVsZW1lbnRUeXBlICE9PSBcImludGVybmFsRW1iZWRcIiAmJlxuICAgICAgICAgICBkb21FbGVtZW50LmVsZW1lbnRUeXBlICE9PSBcImRhdGF2aWV3SlNFbWJlZFwiKSB7XG5cbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiVXBkYXRpbmcgZHVhbCByZW5kZXJpbmcuXCIsIGRvbUVsZW1lbnQsIGRvbUVsZW1lbnQub3JpZ2luYWxFbGVtZW50LnBhcmVudEVsZW1lbnQsIGRvbUVsZW1lbnQub3JpZ2luYWxFbGVtZW50LnBhcmVudEVsZW1lbnQ/LmNoaWxkRWxlbWVudENvdW50KTtcblxuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIG91ciBDU1MgaXMgdXAgdG8gZGF0ZS5cbiAgICAgICAgICAgIG9yaWdpbmFsRWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5PcmlnaW5hbEVsZW1lbnRUeXBlKTtcbiAgICAgICAgICAgIGNsb25lZEVsZW1lbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ2xvbmVkRWxlbWVudFR5cGUpO1xuICAgICAgICAgICAgY2xvbmVkRWxlbWVudC5yZW1vdmVDbGFzc2VzKFtNdWx0aUNvbHVtblN0eWxlQ1NTLlJlZ2lvbkNvbnRlbnQsIE11bHRpQ29sdW1uTGF5b3V0Q1NTLk9yaWdpbmFsRWxlbWVudFR5cGVdKTtcbiAgICBcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBjb250YWluZXJFbGVtZW50LmNoaWxkcmVuLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyRWxlbWVudC5jaGlsZHJlbltpXS5kZXRhY2goKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRhaW5lckVsZW1lbnQuYXBwZW5kQ2hpbGQob3JpZ2luYWxFbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnRhaW5lckVsZW1lbnQuYXBwZW5kQ2hpbGQoY2xvbmVkRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHVwIHRoZSBDU1MgY2xhc3NlcyBhbmQgdGhlIG51bWJlciBvZiBjb2x1bW5zIGJhc2VkIG9uIHRoZSBwYXNzZWQgc2V0dGluZ3MuXG4gICAgICogQHBhcmFtIHNldHRpbmdzIFRoZSB1c2VyIGRlZmluZWQgc2V0dGluZ3MgdGhhdCBkZXRlcm1pbmUgd2hhdCBDU1MgaXMgc2V0IGhlcmUuXG4gICAgICogQHBhcmFtIG11bHRpQ29sdW1uUGFyZW50IFRoZSBwYXJlbnQgb2JqZWN0IHRoYXQgdGhlIGNvbHVtbiBkaXZzIHdpbGwgYmUgY3JlYXRlZCB1bmRlci5cbiAgICAgKiBAcmV0dXJucyBUaGUgbGlzdCBvZiBjb2x1bW4gZGl2cyBjcmVhdGVkIHVuZGVyIHRoZSBwYXNzZWQgcGFyZW50IGVsZW1lbnQuXG4gICAgICovXG4gICAgZ2V0Q29sdW1uQ29udGVudERpdnMoc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MsIG11bHRpQ29sdW1uUGFyZW50OiBIVE1MRGl2RWxlbWVudCk6IEhUTUxEaXZFbGVtZW50W10ge1xuXG4gICAgICAgIGxldCBjb2x1bW5Db250ZW50RGl2czogSFRNTERpdkVsZW1lbnRbXSA9IFtdXG4gICAgICAgIFxuICAgICAgICBpZih0eXBlb2Ygc2V0dGluZ3MuY29sdW1uU2l6ZSA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAgICBpc0NvbHVtbkxheW91dChzZXR0aW5ncy5jb2x1bW5TaXplKSAgICAgJiYgXG4gICAgICAgICAgIChzZXR0aW5ncy5udW1iZXJPZkNvbHVtbnMgPT09IDIgfHwgc2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zID09PSAzKSkgeyAgICAgIFxuXG4gICAgICAgICAgICBzZXR0aW5ncy5jb2x1bW5TaXplID0gdmFsaWRhdGVDb2x1bW5MYXlvdXQoc2V0dGluZ3MuY29sdW1uU2l6ZSlcbiAgICAgICAgICAgIG11bHRpQ29sdW1uUGFyZW50LnJlbW92ZUNsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLkNvbnRlbnRPdmVyZmxvd0F1dG9TY3JvbGxfWCk7XG4gICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5Db250ZW50T3ZlcmZsb3dIaWRkZW5fWCk7XG5cbiAgICAgICAgICAgIGJ1aWxkU3RhbmRhcmRMYXlvdXRzKHNldHRpbmdzLCBtdWx0aUNvbHVtblBhcmVudCwgY29sdW1uQ29udGVudERpdnMpXG4gICAgICAgICAgICBzZXRNYXhDb2x1bW5IZWlnaHQoKTtcbiAgICAgICAgICAgIHJldHVybiBjb2x1bW5Db250ZW50RGl2cztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKHR5cGVvZiBzZXR0aW5ncy5jb2x1bW5TaXplID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgIGlzQ29sdW1uTGF5b3V0KHNldHRpbmdzLmNvbHVtblNpemUpICAgICAmJiBcbiAgICAgICAgICAgc2V0dGluZ3MuY29sdW1uU2l6ZSA9PT0gXCJzdGFuZGFyZFwiICYmIFxuICAgICAgICAgICBzZXR0aW5ncy5udW1iZXJPZkNvbHVtbnMgPiAzICl7XG5cbiAgICAgICAgICAgIHNldHRpbmdzLmNvbHVtblNpemUgPSB2YWxpZGF0ZUNvbHVtbkxheW91dChzZXR0aW5ncy5jb2x1bW5TaXplKTtcbiAgICAgICAgICAgIG11bHRpQ29sdW1uUGFyZW50LnJlbW92ZUNsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLkNvbnRlbnRPdmVyZmxvd0F1dG9TY3JvbGxfWCk7XG4gICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5Db250ZW50T3ZlcmZsb3dIaWRkZW5fWCk7XG5cbiAgICAgICAgICAgIGJ1aWxkRXF1YWxMYXlvdXQoc2V0dGluZ3MsIG11bHRpQ29sdW1uUGFyZW50LCBjb2x1bW5Db250ZW50RGl2cyk7XG5cbiAgICAgICAgICAgIHNldE1heENvbHVtbkhlaWdodCgpO1xuICAgICAgICAgICAgcmV0dXJuIGNvbHVtbkNvbnRlbnREaXZzO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBsZXQgY29sdW1uU2l6ZXM6IEhUTUxTaXppbmdbXSA9IFtdO1xuICAgICAgICAvLyBJZiB0aGUgdXNlciBoYXMgZGVmaW5lZCB0aGUgd2lkdGhzIGluZGl2aWR1YWxseSB0aGVuIHdlIGp1c3QgbmVlZCB0byBjcmVhdGVcbiAgICAgICAgLy8gZWFjaCBjb2x1bW4gaW5kaXZpZHVhbGx5IHdpdGggZWFjaCB3aWR0aCBzaXplLlxuICAgICAgICBpZihBcnJheS5pc0FycmF5KHNldHRpbmdzLmNvbHVtblNpemUpKSB7XG4gICAgICAgICAgICBjb2x1bW5TaXplcyA9IHNldHRpbmdzLmNvbHVtblNpemUuc2xpY2UoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNhbGNDb2x1bW5TaXplcyhzZXR0aW5ncywgY29sdW1uU2l6ZXMpXG4gICAgICAgIH1cblxuICAgICAgICBpZihjb2x1bW5TaXplcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCg1MCkuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHNldHRpbmdzLm51bWJlck9mQ29sdW1uczsgaSsrKSB7XG5cbiAgICAgICAgICAgIGxldCBzaXppbmcgPSBnZXRJbmRleGVkQ2xhbXBlZEFycmF5VmFsdWUoaSwgY29sdW1uU2l6ZXMpO1xuXG4gICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2cy5wdXNoKG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtbkNvbnRlbnR9YCxcbiAgICAgICAgICAgICAgICBhdHRyOiB7XCJzdHlsZVwiOiBgd2lkdGg6ICR7c2l6aW5nLnRvU3RyaW5nKCl9YH1cbiAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgaWYoaSAhPT0gc2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zIC0gMSkge1xuICAgICAgICAgICAgICAgIG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYG1jbS1jb2x1bW4tc3BhY2VyYCxcbiAgICAgICAgICAgICAgICAgICAgYXR0cjoge1wic3R5bGVcIjogY29sdW1uU3BhY2luZ1N0YXRlKDAsIHNldHRpbmdzKX1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBjb2x1bW5Db250ZW50RGl2cy5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2c1tpXS5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5Ob0ZsZXhTaHJpbmspO1xuICAgICAgICB9XG5cbiAgICAgICAgc2V0TWF4Q29sdW1uSGVpZ2h0KCk7XG5cbiAgICAgICAgcmV0dXJuIGNvbHVtbkNvbnRlbnREaXZzO1xuXG4gICAgICAgIGZ1bmN0aW9uIHNldE1heENvbHVtbkhlaWdodCgpIHtcbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5jb2x1bW5IZWlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5yZW1vdmVDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5Db250ZW50T3ZlcmZsb3dIaWRkZW5fWSk7XG4gICAgICAgICAgICAgICAgbXVsdGlDb2x1bW5QYXJlbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29udGVudE92ZXJmbG93QXV0b1Njcm9sbF9ZKTtcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2cy5mb3JFYWNoKChjb2x1bW4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uLnN0eWxlLmhlaWdodCA9IHNldHRpbmdzLmNvbHVtbkhlaWdodC50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW4uc3R5bGUubWF4SGVpZ2h0ID0gc2V0dGluZ3MuY29sdW1uSGVpZ2h0LnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbi5zdHlsZS5taW5IZWlnaHQgPSBzZXR0aW5ncy5jb2x1bW5IZWlnaHQudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhYnN0cmFjdCByZW5kZXJSZWdpb25FbGVtZW50c1RvU2NyZWVuKCk6IHZvaWQ7XG4gICAgcHVibGljIGFic3RyYWN0IGV4cG9ydFJlZ2lvbkVsZW1lbnRzVG9QREYocGRmUGFyZW50RWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkO1xuICAgIHB1YmxpYyBhYnN0cmFjdCByZW5kZXJSZWdpb25FbGVtZW50c1RvTGl2ZVByZXZpZXcocGFyZW50RWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUVycm9yRWxlbWVudChlcnJvclRleHQ6IHN0cmluZywgYWx0OiBzdHJpbmcgPSBcIlwiLCBzcmM6IHN0cmluZyA9IFwiXCIpOiBIVE1MRGl2RWxlbWVudCB7XG4gICAgbGV0IGVycm9yRWwgPSBjcmVhdGVEaXYoe1xuICAgICAgICBjbHM6IFwiaW50ZXJuYWwtZW1iZWQgbWFya2Rvd24tZW1iZWQgaW5saW5lLWVtYmVkIGlzLWxvYWRlZFwiLFxuICAgICAgICBhdHRyOiB7XG4gICAgICAgICAgICBcInRhYmluZGV4XCI6IFwiLTFcIixcbiAgICAgICAgICAgIFwiY29udGVudGVkaXRhYmxlXCI6IFwiZmFsc2VcIlxuICAgICAgICB9XG4gICAgfSlcbiAgICBlcnJvckVsLnNldEF0dHIoXCJhbHRcIiwgYWx0KTtcbiAgICBlcnJvckVsLnNldEF0dHIoXCJzcmNcIiwgYGFwcDovL29ic2lkaWFuLm1kLyR7c3JjfWApXG4gICAgZXJyb3JFbC5hcHBlbmRDaGlsZChjcmVhdGVEaXYoXG4gICAgICAgIHtcbiAgICAgICAgICAgIFwiY2xzXCI6IFwiZW1iZWQtdGl0bGUgbWFya2Rvd24tZW1iZWQtdGl0bGVcIixcbiAgICAgICAgfVxuICAgICkpO1xuICAgIGxldCBjb250ZW50RWwgPSBlcnJvckVsLmNyZWF0ZURpdih7XG4gICAgICAgIFwiY2xzXCI6IGBtYXJrZG93bi1lbWJlZC1jb250ZW50YCxcbiAgICB9KTtcbiAgICBsZXQgcGFyYWdyYXBoID0gY29udGVudEVsLmNyZWF0ZUVsKFwicFwiLCB7XG4gICAgICAgIFwiY2xzXCI6IGAke011bHRpQ29sdW1uU3R5bGVDU1MuUmVnaW9uRXJyb3JNZXNzYWdlfSwgJHtNdWx0aUNvbHVtblN0eWxlQ1NTLlNtYWxsRm9udH1gXG4gICAgfSk7XG4gICAgcGFyYWdyYXBoLmlubmVyVGV4dCA9IGVycm9yVGV4dDtcblxuICAgIHJldHVybiBlcnJvckVsXG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVBERkVtYmVkKGRvbUVsZW1lbnQ6IERPTU9iamVjdCkge1xuICAgIFxuICAgIC8vIGlmKGRvbUVsZW1lbnQuY2FudmFzUmVhZHlGb3JVcGRhdGUoKSA9PT0gZmFsc2UpIHtcbiAgICAvLyAgICAgcmV0dXJuXG4gICAgLy8gfVxuXG4gICAgbGV0IG9yaWdpbmFsRWxlbWVudCA9IGRvbUVsZW1lbnQub3JpZ2luYWxFbGVtZW50O1xuICAgIGxldCBjbG9uZWRFbGVtZW50ID0gZG9tRWxlbWVudC5jbG9uZWRFbGVtZW50O1xuICAgIGxldCBjb250YWluZXJFbGVtZW50OiBIVE1MRGl2RWxlbWVudCA9IGRvbUVsZW1lbnQuZWxlbWVudENvbnRhaW5lcjtcbiAgICBmb3IgKGxldCBpID0gY2xvbmVkRWxlbWVudC5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBjbG9uZWRFbGVtZW50LmNoaWxkcmVuW2ldLmRldGFjaCgpO1xuICAgIH1cbiAgICBjbG9uZWRFbGVtZW50LmFwcGVuZENoaWxkKGNyZWF0ZUVycm9yRWxlbWVudChcIkR1ZSB0byBhbiB1cGRhdGUgdG8gT2JzaWRpYW4ncyBQREYgdmlld2VyLCBQREYgZW1iZWRzIGFyZSBjdXJyZW50bHkgbm90IHN1cHBvcnRlZC5cXG5Tb3JyeSBmb3IgdGhlIGluY29udmllbmVuY2UuXCIpKVxuICAgIHJldHVyblxufVxuXG5mdW5jdGlvbiByZVJlbmRlckRhdGF2aWV3SlMoZG9tRWxlbWVudDogRE9NT2JqZWN0KSB7XG4gICAgaWYoZG9tRWxlbWVudC5jYW52YXNSZWFkeUZvclVwZGF0ZSgpID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBsZXQgb3JpZ2luYWxFbGVtZW50ID0gZG9tRWxlbWVudC5vcmlnaW5hbEVsZW1lbnQ7XG4gICAgbGV0IGNsb25lZEVsZW1lbnQgPSBkb21FbGVtZW50LmNsb25lZEVsZW1lbnQ7XG4gICAgbGV0IGNvbnRhaW5lckVsZW1lbnQ6IEhUTUxEaXZFbGVtZW50ID0gZG9tRWxlbWVudC5lbGVtZW50Q29udGFpbmVyO1xuXG4gICAgY29udGFpbmVyRWxlbWVudC5hcHBlbmRDaGlsZChvcmlnaW5hbEVsZW1lbnQpO1xuICAgIGlmKGNsb25lZEVsZW1lbnQgIT09IG51bGwgJiYgY2xvbmVkRWxlbWVudC5wYXJlbnRFbGVtZW50ID09PSBjb250YWluZXJFbGVtZW50KSB7XG4gICAgICAgIGNvbnRhaW5lckVsZW1lbnQucmVtb3ZlQ2hpbGQoY2xvbmVkRWxlbWVudCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2xvbmVDYW52YXMob3JpZ2luYWxDYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KTogSFRNTENhbnZhc0VsZW1lbnQge1xuXG4gICAgICAgIC8vY3JlYXRlIGEgbmV3IGNhbnZhc1xuICAgICAgICBsZXQgY2xvbmVkQ2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IG9yaWdpbmFsQ2FudmFzLmNsb25lTm9kZSh0cnVlKSBhcyBIVE1MQ2FudmFzRWxlbWVudDtcbiAgICAgICAgbGV0IGNvbnRleHQ6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCA9IGNsb25lZENhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgIFxuICAgICAgICAvL3NldCBkaW1lbnNpb25zXG4gICAgICAgIGNsb25lZENhbnZhcy53aWR0aCA9IG9yaWdpbmFsQ2FudmFzLndpZHRoO1xuICAgICAgICBjbG9uZWRDYW52YXMuaGVpZ2h0ID0gb3JpZ2luYWxDYW52YXMuaGVpZ2h0O1xuXG4gICAgICAgIGlmKGNsb25lZENhbnZhcy53aWR0aCA9PT0gMCB8fCBjbG9uZWRDYW52YXMuaGVpZ2h0ID09PSAwKXtcbiAgICAgICAgICAgIC8vIERvbnQgd2FudCB0byByZW5kZXIgaWYgdGhlIHdpZHRoIGlzIDAgYXMgaXQgdGhyb3dzIGFuIGVycm9yXG4gICAgICAgICAgICAvLyB3b3VsZCBoYXBwZW4gaWYgdGhlIG9sZCBjYW52YXMgaGFzbnQgYmVlbiByZW5kZXJlZCB5ZXQuXG4gICAgICAgICAgICByZXR1cm4gY2xvbmVkQ2FudmFzO1xuICAgICAgICB9IFxuXG4gICAgICAgIC8vYXBwbHkgdGhlIG9sZCBjYW52YXMgdG8gdGhlIG5ldyBvbmVcbiAgICAgICAgY29udGV4dC5kcmF3SW1hZ2Uob3JpZ2luYWxDYW52YXMsIDAsIDApO1xuICAgIFxuICAgICAgICAvL3JldHVybiB0aGUgbmV3IGNhbnZhc1xuICAgICAgICByZXR1cm4gY2xvbmVkQ2FudmFzO1xuICAgIH1cblxuICAgIGxldCBjYW52YXMgPSBzZWFyY2hDaGlsZHJlbkZvck5vZGVUeXBlKG9yaWdpbmFsRWxlbWVudCwgXCJjYW52YXNcIik7XG4gICAgaWYoY2FudmFzICE9PSBudWxsKSB7XG4gICAgICAgIFxuICAgICAgICBkb21FbGVtZW50LnVwZGF0ZUNsb25lZEVsZW1lbnQob3JpZ2luYWxFbGVtZW50LmNsb25lTm9kZSh0cnVlKSBhcyBIVE1MRGl2RWxlbWVudCk7XG4gICAgICAgIGNsb25lZEVsZW1lbnQgPSBkb21FbGVtZW50LmNsb25lZEVsZW1lbnQ7XG4gICAgICAgIGNsb25lZEVsZW1lbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ2xvbmVkRWxlbWVudFR5cGUpO1xuICAgICAgICBjbG9uZWRFbGVtZW50LnJlbW92ZUNsYXNzZXMoW011bHRpQ29sdW1uU3R5bGVDU1MuUmVnaW9uQ29udGVudCwgTXVsdGlDb2x1bW5MYXlvdXRDU1MuT3JpZ2luYWxFbGVtZW50VHlwZV0pO1xuICAgICAgICBjb250YWluZXJFbGVtZW50LmFwcGVuZENoaWxkKGNsb25lZEVsZW1lbnQpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSBjbG9uZWRFbGVtZW50LmNoaWxkcmVuLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBjbG9uZWRFbGVtZW50LmNoaWxkcmVuW2ldLmRldGFjaCgpO1xuICAgICAgICB9XG4gICAgICAgIGNsb25lZEVsZW1lbnQuYXBwZW5kQ2hpbGQoY2xvbmVDYW52YXMoY2FudmFzIGFzIEhUTUxDYW52YXNFbGVtZW50KSlcbiAgICB9XG5cbiAgICBjb250YWluZXJFbGVtZW50LnJlbW92ZUNoaWxkKG9yaWdpbmFsRWxlbWVudCk7XG4gICAgY29udGFpbmVyRWxlbWVudC5hcHBlbmRDaGlsZChjbG9uZWRFbGVtZW50KTtcbn1cblxuZnVuY3Rpb24gY2FsY0NvbHVtblNpemVzKHNldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzLCBjb2x1bW5TaXplczogSFRNTFNpemluZ1tdKSB7XG4gICAgbGV0IGxheW91dCA9IHNldHRpbmdzLmNvbHVtblNpemUgYXMgQ29sdW1uTGF5b3V0O1xuXG4gICAgaWYoc2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zID09PSAyKSB7XG4gICAgICAgIHN3aXRjaChsYXlvdXQpIHtcbiAgICAgICAgICAgIGNhc2UoXCJzdGFuZGFyZFwiKTpcbiAgICAgICAgICAgIGNhc2UoXCJtaWRkbGVcIik6XG4gICAgICAgICAgICBjYXNlKFwiY2VudGVyXCIpOlxuICAgICAgICAgICAgY2FzZShcInRoaXJkXCIpOlxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCg1MCkuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCg1MCkuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlKFwibGVmdFwiKTpcbiAgICAgICAgICAgIGNhc2UoXCJmaXJzdFwiKTpcbiAgICAgICAgICAgICAgICBjb2x1bW5TaXplcy5wdXNoKEhUTUxTaXppbmcuY3JlYXRlKCkuc2V0V2lkdGgoNzUpLnNldFVuaXRzKFwiJVwiKSlcbiAgICAgICAgICAgICAgICBjb2x1bW5TaXplcy5wdXNoKEhUTUxTaXppbmcuY3JlYXRlKCkuc2V0V2lkdGgoMjUpLnNldFVuaXRzKFwiJVwiKSlcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZShcInJpZ2h0XCIpOlxuICAgICAgICAgICAgY2FzZShcInNlY29uZFwiKTpcbiAgICAgICAgICAgIGNhc2UoXCJsYXN0XCIpOlxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCgyNSkuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCg3NSkuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZihzZXR0aW5ncy5udW1iZXJPZkNvbHVtbnMgPT09IDMpIHtcbiAgICAgICAgc3dpdGNoKGxheW91dCkge1xuICAgICAgICAgICAgY2FzZShcInN0YW5kYXJkXCIpOlxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCgzMykuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCgzMykuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCgzMykuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlKFwibGVmdFwiKTpcbiAgICAgICAgICAgIGNhc2UoXCJmaXJzdFwiKTpcbiAgICAgICAgICAgICAgICBjb2x1bW5TaXplcy5wdXNoKEhUTUxTaXppbmcuY3JlYXRlKCkuc2V0V2lkdGgoNTApLnNldFVuaXRzKFwiJVwiKSlcbiAgICAgICAgICAgICAgICBjb2x1bW5TaXplcy5wdXNoKEhUTUxTaXppbmcuY3JlYXRlKCkuc2V0V2lkdGgoMjUpLnNldFVuaXRzKFwiJVwiKSlcbiAgICAgICAgICAgICAgICBjb2x1bW5TaXplcy5wdXNoKEhUTUxTaXppbmcuY3JlYXRlKCkuc2V0V2lkdGgoMjUpLnNldFVuaXRzKFwiJVwiKSlcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZShcIm1pZGRsZVwiKTpcbiAgICAgICAgICAgIGNhc2UoXCJjZW50ZXJcIik6XG4gICAgICAgICAgICBjYXNlKFwic2Vjb25kXCIpOlxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCgyNSkuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCg1MCkuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGNvbHVtblNpemVzLnB1c2goSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aCgyNSkuc2V0VW5pdHMoXCIlXCIpKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlKFwicmlnaHRcIik6XG4gICAgICAgICAgICBjYXNlKFwidGhpcmRcIik6XG4gICAgICAgICAgICBjYXNlKFwibGFzdFwiKTpcbiAgICAgICAgICAgICAgICBjb2x1bW5TaXplcy5wdXNoKEhUTUxTaXppbmcuY3JlYXRlKCkuc2V0V2lkdGgoMjUpLnNldFVuaXRzKFwiJVwiKSlcbiAgICAgICAgICAgICAgICBjb2x1bW5TaXplcy5wdXNoKEhUTUxTaXppbmcuY3JlYXRlKCkuc2V0V2lkdGgoMjUpLnNldFVuaXRzKFwiJVwiKSlcbiAgICAgICAgICAgICAgICBjb2x1bW5TaXplcy5wdXNoKEhUTUxTaXppbmcuY3JlYXRlKCkuc2V0V2lkdGgoNTApLnNldFVuaXRzKFwiJVwiKSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZ2V0RWxlbWVudENsaWVudEhlaWdodChlbGVtZW50OiBIVE1MRWxlbWVudCwgcGFyZW50UmVuZGVyRWxlbWVudDogSFRNTERpdkVsZW1lbnQpOiBudW1iZXIge1xuXG4gICAgbGV0IGhlaWdodCA9IGVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICAgIGlmKGhlaWdodCA9PT0gMCkge1xuICAgICAgICBwYXJlbnRSZW5kZXJFbGVtZW50LmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICBoZWlnaHQgPSBlbGVtZW50LmNsaWVudEhlaWdodFxuICAgICAgICBwYXJlbnRSZW5kZXJFbGVtZW50LnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuICAgIH1cbiAgICByZXR1cm4gaGVpZ2h0XG59XG5cbmZ1bmN0aW9uIGJ1aWxkRXF1YWxMYXlvdXQoc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MsIG11bHRpQ29sdW1uUGFyZW50OiBIVE1MRGl2RWxlbWVudCwgY29sdW1uQ29udGVudERpdnM6IEhUTUxEaXZFbGVtZW50W10pIHtcblxuICAgIGxldCBwZXJjZW50ID0gTWF0aC5jZWlsKDEwMCAvIHNldHRpbmdzLm51bWJlck9mQ29sdW1ucyk7XG5cbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgc2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zOyBpKyspIHtcbiAgICAgICAgXG4gICAgICAgIGNvbHVtbkNvbnRlbnREaXZzLnB1c2gobXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Db250ZW50fWAsXG4gICAgICAgICAgICBhdHRyOiB7XCJzdHlsZVwiOiBgd2lkdGg6ICR7cGVyY2VudH0lYH1cbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGlmKGkgIT09IHNldHRpbmdzLm51bWJlck9mQ29sdW1ucyAtIDEpIHtcbiAgICAgICAgICAgIG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgY2xzOiBgbWNtLWNvbHVtbi1zcGFjZXJgLFxuICAgICAgICAgICAgICAgIGF0dHI6IHtcInN0eWxlXCI6IGNvbHVtblNwYWNpbmdTdGF0ZSgwLCBzZXR0aW5ncyl9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gYnVpbGRTdGFuZGFyZExheW91dHMoc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MsIG11bHRpQ29sdW1uUGFyZW50OiBIVE1MRGl2RWxlbWVudCwgY29sdW1uQ29udGVudERpdnM6IEhUTUxEaXZFbGVtZW50W10pIHtcblxuICAgIGxldCBsYXlvdXQgPSBzZXR0aW5ncy5jb2x1bW5TaXplIGFzIENvbHVtbkxheW91dDtcblxuICAgIGlmKHNldHRpbmdzLm51bWJlck9mQ29sdW1ucyA9PT0gMikge1xuICAgICAgICBzd2l0Y2gobGF5b3V0KSB7XG4gICAgICAgICAgICBjYXNlKFwic3RhbmRhcmRcIik6XG4gICAgICAgICAgICBjYXNlKFwibWlkZGxlXCIpOlxuICAgICAgICAgICAgY2FzZShcImNlbnRlclwiKTpcbiAgICAgICAgICAgIGNhc2UoXCJ0aGlyZFwiKTpcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2cy5wdXNoKG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Db250ZW50fSAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlR3b0VxdWFsQ29sdW1uc31gXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYG1jbS1jb2x1bW4tc3BhY2VyYCxcbiAgICAgICAgICAgICAgICAgICAgYXR0cjoge1wic3R5bGVcIjogY29sdW1uU3BhY2luZ1N0YXRlKDAsIHNldHRpbmdzKX1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2cy5wdXNoKG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Db250ZW50fSAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlR3b0VxdWFsQ29sdW1uc31gXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlKFwibGVmdFwiKTpcbiAgICAgICAgICAgIGNhc2UoXCJmaXJzdFwiKTpcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2cy5wdXNoKG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Db250ZW50fSAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlR3b0NvbHVtbkxhcmdlfWBcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgbXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBgbWNtLWNvbHVtbi1zcGFjZXJgLFxuICAgICAgICAgICAgICAgICAgICBhdHRyOiB7XCJzdHlsZVwiOiBjb2x1bW5TcGFjaW5nU3RhdGUoMCwgc2V0dGluZ3MpfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbHVtbkNvbnRlbnREaXZzLnB1c2gobXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtbkNvbnRlbnR9ICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuVHdvQ29sdW1uU21hbGx9YFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZShcInJpZ2h0XCIpOlxuICAgICAgICAgICAgY2FzZShcInNlY29uZFwiKTpcbiAgICAgICAgICAgIGNhc2UoXCJsYXN0XCIpOlxuICAgICAgICAgICAgICAgIGNvbHVtbkNvbnRlbnREaXZzLnB1c2gobXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtbkNvbnRlbnR9ICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuVHdvQ29sdW1uU21hbGx9YFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGBtY20tY29sdW1uLXNwYWNlcmAsXG4gICAgICAgICAgICAgICAgICAgIGF0dHI6IHtcInN0eWxlXCI6IGNvbHVtblNwYWNpbmdTdGF0ZSgwLCBzZXR0aW5ncyl9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29sdW1uQ29udGVudERpdnMucHVzaChtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGAke011bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uQ29udGVudH0gJHtNdWx0aUNvbHVtbkxheW91dENTUy5Ud29Db2x1bW5MYXJnZX1gXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZihzZXR0aW5ncy5udW1iZXJPZkNvbHVtbnMgPT09IDMpIHtcbiAgICAgICAgc3dpdGNoKGxheW91dCkge1xuICAgICAgICAgICAgY2FzZShcInN0YW5kYXJkXCIpOlxuICAgICAgICAgICAgICAgIGNvbHVtbkNvbnRlbnREaXZzLnB1c2gobXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtbkNvbnRlbnR9ICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuVGhyZWVFcXVhbENvbHVtbnN9YFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGBtY20tY29sdW1uLXNwYWNlcmAsXG4gICAgICAgICAgICAgICAgICAgIGF0dHI6IHtcInN0eWxlXCI6IGNvbHVtblNwYWNpbmdTdGF0ZSgwLCBzZXR0aW5ncyl9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29sdW1uQ29udGVudERpdnMucHVzaChtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGAke011bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uQ29udGVudH0gJHtNdWx0aUNvbHVtbkxheW91dENTUy5UaHJlZUVxdWFsQ29sdW1uc31gXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYG1jbS1jb2x1bW4tc3BhY2VyYCxcbiAgICAgICAgICAgICAgICAgICAgYXR0cjoge1wic3R5bGVcIjogY29sdW1uU3BhY2luZ1N0YXRlKDEsIHNldHRpbmdzKX1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2cy5wdXNoKG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Db250ZW50fSAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlRocmVlRXF1YWxDb2x1bW5zfWBcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UoXCJsZWZ0XCIpOlxuICAgICAgICAgICAgY2FzZShcImZpcnN0XCIpOlxuICAgICAgICAgICAgICAgIGNvbHVtbkNvbnRlbnREaXZzLnB1c2gobXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtbkNvbnRlbnR9ICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuVGhyZWVDb2x1bW5fTGFyZ2V9YFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGBtY20tY29sdW1uLXNwYWNlcmAsXG4gICAgICAgICAgICAgICAgICAgIGF0dHI6IHtcInN0eWxlXCI6IGNvbHVtblNwYWNpbmdTdGF0ZSgwLCBzZXR0aW5ncyl9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29sdW1uQ29udGVudERpdnMucHVzaChtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGAke011bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uQ29udGVudH0gJHtNdWx0aUNvbHVtbkxheW91dENTUy5UaHJlZUNvbHVtbl9TbWFsbH1gXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYG1jbS1jb2x1bW4tc3BhY2VyYCxcbiAgICAgICAgICAgICAgICAgICAgYXR0cjoge1wic3R5bGVcIjogY29sdW1uU3BhY2luZ1N0YXRlKDEsIHNldHRpbmdzKX1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2cy5wdXNoKG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Db250ZW50fSAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlRocmVlQ29sdW1uX1NtYWxsfWBcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UoXCJtaWRkbGVcIik6XG4gICAgICAgICAgICBjYXNlKFwiY2VudGVyXCIpOlxuICAgICAgICAgICAgY2FzZShcInNlY29uZFwiKTpcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2cy5wdXNoKG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Db250ZW50fSAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlRocmVlQ29sdW1uX1NtYWxsfWBcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgbXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBgbWNtLWNvbHVtbi1zcGFjZXJgLFxuICAgICAgICAgICAgICAgICAgICBhdHRyOiB7XCJzdHlsZVwiOiBjb2x1bW5TcGFjaW5nU3RhdGUoMCwgc2V0dGluZ3MpfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbHVtbkNvbnRlbnREaXZzLnB1c2gobXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtbkNvbnRlbnR9ICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuVGhyZWVDb2x1bW5fTGFyZ2V9YFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGBtY20tY29sdW1uLXNwYWNlcmAsXG4gICAgICAgICAgICAgICAgICAgIGF0dHI6IHtcInN0eWxlXCI6IGNvbHVtblNwYWNpbmdTdGF0ZSgxLCBzZXR0aW5ncyl9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29sdW1uQ29udGVudERpdnMucHVzaChtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGAke011bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uQ29udGVudH0gJHtNdWx0aUNvbHVtbkxheW91dENTUy5UaHJlZUNvbHVtbl9TbWFsbH1gXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlKFwicmlnaHRcIik6XG4gICAgICAgICAgICBjYXNlKFwidGhpcmRcIik6XG4gICAgICAgICAgICBjYXNlKFwibGFzdFwiKTpcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2cy5wdXNoKG11bHRpQ29sdW1uUGFyZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Db250ZW50fSAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlRocmVlQ29sdW1uX1NtYWxsfWBcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgbXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBgbWNtLWNvbHVtbi1zcGFjZXJgLFxuICAgICAgICAgICAgICAgICAgICBhdHRyOiB7XCJzdHlsZVwiOiBjb2x1bW5TcGFjaW5nU3RhdGUoMCwgc2V0dGluZ3MpfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbHVtbkNvbnRlbnREaXZzLnB1c2gobXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtbkNvbnRlbnR9ICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuVGhyZWVDb2x1bW5fU21hbGx9YFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGBtY20tY29sdW1uLXNwYWNlcmAsXG4gICAgICAgICAgICAgICAgICAgIGF0dHI6IHtcInN0eWxlXCI6IGNvbHVtblNwYWNpbmdTdGF0ZSgxLCBzZXR0aW5ncyl9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29sdW1uQ29udGVudERpdnMucHVzaChtdWx0aUNvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgICAgICAgICBjbHM6IGAke011bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uQ29udGVudH0gJHtNdWx0aUNvbHVtbkxheW91dENTUy5UaHJlZUNvbHVtbl9MYXJnZX1gXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmaXhPbkNsaWNrKGRvbUVsZW1lbnQ6IERPTU9iamVjdCkge1xuXG4gICAgbGV0IG9yaWdpbmFsRWxlbWVudCA9IGRvbUVsZW1lbnQub3JpZ2luYWxFbGVtZW50O1xuICAgIGxldCBjbG9uZWRFbGVtZW50ID0gZG9tRWxlbWVudC5jbG9uZWRFbGVtZW50O1xuXG4gICAgbGV0IG9yaWdpbmFsQnV0dG9uID0gb3JpZ2luYWxFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiYnV0dG9uXCIpWzBdO1xuICAgIGxldCBjbG9uZWRCdXR0b24gPSBjbG9uZWRFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiYnV0dG9uXCIpWzBdO1xuXG4gICAgaWYob3JpZ2luYWxCdXR0b24gPT09IHVuZGVmaW5lZCB8fCBjbG9uZWRCdXR0b24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY2xvbmVkQnV0dG9uLm9uQ2xpY2tFdmVudCgoZXYpID0+IHtcblxuICAgICAgICBvcmlnaW5hbEJ1dHRvbi5jbGljaygpO1xuICAgIH0pXG59XG5cbmZ1bmN0aW9uIGNsb25lRWxlbWVudChkb21FbGVtZW50OiBET01PYmplY3QpIHtcblxuICAgIGxldCBvcmlnaW5hbEVsZW1lbnQgPSBkb21FbGVtZW50Lm9yaWdpbmFsRWxlbWVudDtcbiAgICBsZXQgY2xvbmVkRWxlbWVudCA9IGRvbUVsZW1lbnQuY2xvbmVkRWxlbWVudDtcbiAgICBsZXQgY29udGFpbmVyRWxlbWVudDogSFRNTERpdkVsZW1lbnQgPSBkb21FbGVtZW50LmVsZW1lbnRDb250YWluZXI7XG5cbiAgICBkb21FbGVtZW50LnVwZGF0ZUNsb25lZEVsZW1lbnQob3JpZ2luYWxFbGVtZW50LmNsb25lTm9kZSh0cnVlKSBhcyBIVE1MRGl2RWxlbWVudCk7XG4gICAgY2xvbmVkRWxlbWVudCA9IGRvbUVsZW1lbnQuY2xvbmVkRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIElmIHdlIHVwZGF0ZWQgdGhlIGNsb25lZCBlbGVtZW50LCB3ZSB3YW50IHRvIGFsc28gdXBkYXRlIHRoZVxuICAgICAqIGVsZW1lbnQgcmVuZGVyZWQgaW4gdGhlIHBhcmVudCBjb250YWluZXIuXG4gICAgICovXG4gICAgZm9yIChsZXQgaSA9IGNvbnRhaW5lckVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgY29udGFpbmVyRWxlbWVudC5jaGlsZHJlbltpXS5kZXRhY2goKTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgQ1NTLCB3ZSBhZGQgY2xvbmVkIGNsYXNzIGFuZCByZW1vdmUgY2xhc3NlcyBmcm9tIG9yaWdpbmFsRWxlbWVudCB0aGF0IGRvIG5vdCBhcHBseS5cbiAgICBjbG9uZWRFbGVtZW50LmFkZENsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLkNsb25lZEVsZW1lbnRUeXBlKTtcbiAgICBjbG9uZWRFbGVtZW50LnJlbW92ZUNsYXNzZXMoW011bHRpQ29sdW1uU3R5bGVDU1MuUmVnaW9uQ29udGVudCwgTXVsdGlDb2x1bW5MYXlvdXRDU1MuT3JpZ2luYWxFbGVtZW50VHlwZV0pO1xuICAgIGNvbnRhaW5lckVsZW1lbnQuYXBwZW5kQ2hpbGQoY2xvbmVkRWxlbWVudCk7XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NCdXR0b25QbHVnaW5VcGRhdGUoZG9tT2JqZWN0OiBET01PYmplY3QpIHtcblxuICAgIGRvbU9iamVjdC5lbGVtZW50VHlwZSA9IFwiYnV0dG9uUGx1Z2luXCJcbiAgICBpZihkb21PYmplY3QuY2xvbmVkRWxlbWVudFJlYWR5Rm9yVXBkYXRlKCkgPT09IHRydWUpIHtcbiAgICAgICAgY2xvbmVFbGVtZW50KGRvbU9iamVjdCk7XG4gICAgICAgIGZpeE9uQ2xpY2soZG9tT2JqZWN0KTtcbiAgICB9XG59IiwiZXhwb3J0IGludGVyZmFjZSBNQ01fU2V0dGluZ3Mge1xuICAgIHJlbmRlck9uTW9iaWxlOiBib29sZWFuO1xuICAgIGF1dG9MYXlvdXRCYWxhbmNlSXRlcmF0aW9uczogbnVtYmVyO1xuICAgIHVzZUxpdmVQcmV2aWV3Q2FjaGU6IGJvb2xlYW47XG4gICAgYWxpZ25UYWJsZXNUb0NvbnRlbnRBbGlnbm1lbnQ6IGJvb2xlYW47XG4gICAgcmVuZGVySW5saW5lRWxFcnJvcnM6IGJvb2xlYW47XG59XG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogTUNNX1NldHRpbmdzID0ge1xuICAgIHJlbmRlck9uTW9iaWxlOiB0cnVlLFxuICAgIGF1dG9MYXlvdXRCYWxhbmNlSXRlcmF0aW9uczogNSxcbiAgICB1c2VMaXZlUHJldmlld0NhY2hlOiBmYWxzZSxcbiAgICBhbGlnblRhYmxlc1RvQ29udGVudEFsaWdubWVudDogdHJ1ZSxcbiAgICByZW5kZXJJbmxpbmVFbEVycm9yczogdHJ1ZVxufTtcblxuZXhwb3J0IGNsYXNzIE1DTV9TZXR0aW5nc01hbmFnZXIge1xuXG4gICAgcHJpdmF0ZSBzdGF0aWMgbG9jYWw6IE1DTV9TZXR0aW5nc01hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgICBwdWJsaWMgc3RhdGljIGdldCBzaGFyZWQoKTogTUNNX1NldHRpbmdzTWFuYWdlciB7XG4gICAgICAgIGlmKE1DTV9TZXR0aW5nc01hbmFnZXIubG9jYWwgPT09IG51bGwpIHtcbiAgICAgICAgICAgIE1DTV9TZXR0aW5nc01hbmFnZXIubG9jYWwgPSBuZXcgTUNNX1NldHRpbmdzTWFuYWdlcigpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE1DTV9TZXR0aW5nc01hbmFnZXIubG9jYWw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc2V0dGluZ3M6IE1DTV9TZXR0aW5ncyA9IERFRkFVTFRfU0VUVElOR1M7XG4gICAgcHVibGljIGdldCBzZXR0aW5ncygpOiBNQ01fU2V0dGluZ3MgeyByZXR1cm4gdGhpcy5fc2V0dGluZ3MgfVxuICAgIHB1YmxpYyBzZXQgc2V0dGluZ3MobmV3VmFsOiBNQ01fU2V0dGluZ3MpIHtcbiAgICAgICAgdGhpcy51cGRhdGVUaW1lc3RhbXAoKVxuICAgICAgICB0aGlzLl9zZXR0aW5ncyA9IG5ld1ZhbFxuICAgIH1cblxuICAgIHByaXZhdGUgX2xhc3RVcGRhdGVUaW1lc3RhbXA6IG51bWJlclxuICAgIHB1YmxpYyBnZXQgbGFzdFVwZGF0ZVRpbWVzdGFtcCgpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fbGFzdFVwZGF0ZVRpbWVzdGFtcCB9XG4gICAgcHJpdmF0ZSB1cGRhdGVUaW1lc3RhbXAoKSB7XG4gICAgICAgIHRoaXMuX2xhc3RVcGRhdGVUaW1lc3RhbXAgPSBEYXRlLm5vdygpXG4gICAgfVxuXG4gICAgcHVibGljIGdldCByZW5kZXJPbk1vYmlsZSgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuX3NldHRpbmdzLnJlbmRlck9uTW9iaWxlIH1cbiAgICBwdWJsaWMgZ2V0IGF1dG9MYXlvdXRCYWxhbmNlSXRlcmF0aW9ucygpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fc2V0dGluZ3MuYXV0b0xheW91dEJhbGFuY2VJdGVyYXRpb25zIH1cbiAgICBwdWJsaWMgZ2V0IHVzZUxpdmVQcmV2aWV3Q2FjaGUoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLl9zZXR0aW5ncy51c2VMaXZlUHJldmlld0NhY2hlIH1cbiAgICBwdWJsaWMgZ2V0IGFsaWduVGFibGVzVG9Db250ZW50QWxpZ25tZW50KCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fc2V0dGluZ3MuYWxpZ25UYWJsZXNUb0NvbnRlbnRBbGlnbm1lbnQgfVxuICAgIHB1YmxpYyBnZXQgcmVuZGVySW5saW5lRWxFcnJvcnMoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLl9zZXR0aW5ncy5yZW5kZXJJbmxpbmVFbEVycm9ycyB9XG5cbiAgICBwdWJsaWMgc2V0IHJlbmRlck9uTW9iaWxlKG5ld1ZhbDogYm9vbGVhbikge1xuICAgICAgICB0aGlzLnVwZGF0ZVRpbWVzdGFtcCgpXG4gICAgICAgIHRoaXMuX3NldHRpbmdzLnJlbmRlck9uTW9iaWxlID0gbmV3VmFsXG4gICAgfVxuICAgIHB1YmxpYyBzZXQgYXV0b0xheW91dEJhbGFuY2VJdGVyYXRpb25zKG5ld1ZhbDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMudXBkYXRlVGltZXN0YW1wKClcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MuYXV0b0xheW91dEJhbGFuY2VJdGVyYXRpb25zID0gbmV3VmFsXG4gICAgfVxuICAgIHB1YmxpYyBzZXQgdXNlTGl2ZVByZXZpZXdDYWNoZShuZXdWYWw6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy51cGRhdGVUaW1lc3RhbXAoKVxuICAgICAgICB0aGlzLl9zZXR0aW5ncy51c2VMaXZlUHJldmlld0NhY2hlID0gbmV3VmFsXG4gICAgfVxuICAgIHB1YmxpYyBzZXQgYWxpZ25UYWJsZXNUb0NvbnRlbnRBbGlnbm1lbnQobmV3VmFsOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMudXBkYXRlVGltZXN0YW1wKClcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MuYWxpZ25UYWJsZXNUb0NvbnRlbnRBbGlnbm1lbnQgPSBuZXdWYWxcbiAgICB9XG4gICAgcHVibGljIHNldCByZW5kZXJJbmxpbmVFbEVycm9ycyhuZXdWYWw6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy51cGRhdGVUaW1lc3RhbXAoKVxuICAgICAgICB0aGlzLl9zZXR0aW5ncy5yZW5kZXJJbmxpbmVFbEVycm9ycyA9IG5ld1ZhbFxuICAgIH1cbn0iLCIvKipcbiAqIEZpbGU6IC9zcmMvZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvcmVnaW9uRE9NTWFuYWdlci50cyAgICAgICAgICAgICAgICAqXG4gKiBDcmVhdGVkIERhdGU6IFN1bmRheSwgTWF5IDIybmQgMjAyMiwgNzo0NiBwbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogQXV0aG9yOiBDYW1lcm9uIFJvYmluc29uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjIgQ2FtZXJvbiBSb2JpbnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICovXG5cbmltcG9ydCB7IERPTU9iamVjdCwgRE9NT2JqZWN0VGFnLCBFbGVtZW50Q29sdW1uQnJlYWtUeXBlLCBUYXNrTGlzdERPTU9iamVjdCB9IGZyb20gJy4uL2RvbU9iamVjdCc7XG5pbXBvcnQgeyBNdWx0aUNvbHVtblNldHRpbmdzLCBDb250ZW50T3ZlcmZsb3dUeXBlLCBBbGlnbm1lbnRUeXBlLCBzaG91bGREcmF3Q29sdW1uQm9yZGVyLCBjb2x1bW5PdmVyZmxvd1N0YXRlLCBjb2x1bW5BbGlnbm1lbnRTdGF0ZSwgVGFibGVBbGlnbm1lbnQgfSBmcm9tIFwiLi4vLi4vcmVnaW9uU2V0dGluZ3NcIjtcbmltcG9ydCB7IE11bHRpQ29sdW1uTGF5b3V0Q1NTLCBNdWx0aUNvbHVtblN0eWxlQ1NTIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2Nzc0RlZmluaXRpb25zJztcbmltcG9ydCB7IE1hcmtkb3duUmVuZGVyQ2hpbGQgfSBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgeyBSZWdpb25NYW5hZ2VyIH0gZnJvbSAnLi9yZWdpb25NYW5hZ2VyJztcbmltcG9ydCB7IGdldEhlYWRpbmdDb2xsYXBzZUVsZW1lbnQgfSBmcm9tICdzcmMvdXRpbGl0aWVzL2VsZW1lbnRSZW5kZXJUeXBlUGFyc2VyJztcbmltcG9ydCB7IE1DTV9TZXR0aW5nc01hbmFnZXIgfSBmcm9tICdzcmMvcGx1Z2luU2V0dGluZ3MnO1xuXG5leHBvcnQgY2xhc3MgU3RhbmRhcmRNdWx0aUNvbHVtblJlZ2lvbk1hbmFnZXIgZXh0ZW5kcyBSZWdpb25NYW5hZ2VyIHtcblxuXG4gICAgcHVibGljIHJlbmRlclJlZ2lvbkVsZW1lbnRzVG9TY3JlZW4oKTogdm9pZCB7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJDb2x1bW5NYXJrZG93bih0aGlzLnJlZ2lvblBhcmVudCwgdGhpcy5kb21MaXN0LCB0aGlzLnJlZ2lvbmFsU2V0dGluZ3MpO1xuICAgIH1cbiAgICBwdWJsaWMgZXhwb3J0UmVnaW9uRWxlbWVudHNUb1BERihwZGZQYXJlbnRFbGVtZW50OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuXG4gICAgICAgIC8vIERlZmF1bHQgc2V0IHNoYWRvdyB0byBvZmYgZm9yIGV4cG9ydGluZyBQREZzXG4gICAgICAgIGxldCByZW5kZXJTZXR0aW5ncyA9IHRoaXMucmVnaW9uYWxTZXR0aW5ncztcbiAgICAgICAgcmVuZGVyU2V0dGluZ3MuZHJhd1NoYWRvdyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlbmRlckNvbHVtbk1hcmtkb3duKHBkZlBhcmVudEVsZW1lbnQsIHRoaXMuZG9tTGlzdC5zbGljZSgpLCByZW5kZXJTZXR0aW5ncyk7XG4gICAgfVxuICAgIHB1YmxpYyByZW5kZXJSZWdpb25FbGVtZW50c1RvTGl2ZVByZXZpZXcocGFyZW50RWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcblxuICAgICAgICB0aGlzLnJlbmRlckNvbHVtbk1hcmtkb3duKHBhcmVudEVsZW1lbnQsIHRoaXMuZG9tTGlzdCwgdGhpcy5yZWdpb25hbFNldHRpbmdzLCB0cnVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiB0YWtlcyBpbiB0aGUgZGF0YSBmb3IgdGhlIG11bHRpLWNvbHVtbiByZWdpb24gYW5kIHNldHMgdXAgdGhlIFxuICAgICAqIHVzZXIgZGVmaW5lZCBudW1iZXIgb2YgY2hpbGRyZW4gd2l0aCB0aGUgcHJvcGVyIGNzcyBjbGFzc2VzIHRvIGJlIHJlbmRlcmVkIHByb3Blcmx5LlxuICAgICAqIFxuICAgICAqIEBwYXJhbSBwYXJlbnRFbGVtZW50IFRoZSBlbGVtZW50IHRoYXQgdGhlIG11bHRpLWNvbHVtbiByZWdpb24gd2lsbCBiZSByZW5kZXJlZCB1bmRlci5cbiAgICAgKiBAcGFyYW0gcmVnaW9uRWxlbWVudHMgVGhlIGxpc3Qgb2YgRE9NIG9iamVjdHMgdGhhdCB3aWxsIGJlIGNvcHBpZWQgdW5kZXIgdGhlIHBhcmVudCBvYmplY3RcbiAgICAgKiBAcGFyYW0gc2V0dGluZ3MgVGhlIHNldHRpbmdzIHRoZSB1c2VyIGhhcyBkZWZpbmVkIGZvciB0aGUgcmVnaW9uLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVuZGVyQ29sdW1uTWFya2Rvd24ocGFyZW50RWxlbWVudDogSFRNTEVsZW1lbnQsIHJlZ2lvbkVsZW1lbnRzOiBET01PYmplY3RbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzLCBpc0xpdmVQcmV2aWV3OiBib29sZWFuID0gZmFsc2UpIHtcblxuICAgICAgICBsZXQgbXVsdGlDb2x1bW5QYXJlbnQgPSBjcmVhdGVEaXYoe1xuICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtbkxheW91dENTUy5SZWdpb25Db2x1bW5Db250YWluZXJEaXZ9IFxcXG4gICAgICAgICAgICAgICAgICAke011bHRpQ29sdW1uTGF5b3V0Q1NTLkNvbnRlbnRPdmVyZmxvd0F1dG9TY3JvbGxfWH0gXFxcbiAgICAgICAgICAgICAgICAgICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29udGVudE92ZXJmbG93SGlkZGVuX1l9O1xuICAgICAgICAgICAgICAgICAgYFxuICAgICAgICB9KTtcblxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQYXNzIG91ciBwYXJlbnQgZGl2IGFuZCBzZXR0aW5ncyB0byBwYXJzZXIgdG8gY3JlYXRlIHRoZSByZXF1aXJlZFxuICAgICAgICAgKiBjb2x1bW4gZGl2cyBhcyBjaGlsZHJlbiBvZiB0aGUgcGFyZW50LlxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IGNvbHVtbkNvbnRlbnREaXZzID0gdGhpcy5nZXRDb2x1bW5Db250ZW50RGl2cyhzZXR0aW5ncywgbXVsdGlDb2x1bW5QYXJlbnQpO1xuICAgICAgICBpZihzZXR0aW5ncy5kcmF3U2hhZG93ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5hZGRDbGFzcyhNdWx0aUNvbHVtblN0eWxlQ1NTLlJlZ2lvblNoYWRvdyk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgY29sdW1uQ29udGVudERpdnMubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgaWYoc2hvdWxkRHJhd0NvbHVtbkJvcmRlcihpLCBzZXR0aW5ncykgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2c1tpXS5hZGRDbGFzcyhNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtbkJvcmRlcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmKHNldHRpbmdzLmRyYXdTaGFkb3cgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2c1tpXS5hZGRDbGFzcyhNdWx0aUNvbHVtblN0eWxlQ1NTLkNvbHVtblNoYWRvdyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgbWFya2Rvd24gcmVuZGVyZXIgdG8gcGFyc2UgdGhlIHBhc3NlZCBtYXJrZG93blxuICAgICAgICAvLyBiZXR3ZWVuIHRoZSB0YWdzLlxuICAgICAgICBsZXQgbWFya2Rvd25SZW5kZXJDaGlsZCA9IG5ldyBNYXJrZG93blJlbmRlckNoaWxkKFxuICAgICAgICAgICAgbXVsdGlDb2x1bW5QYXJlbnRcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBSZW1vdmUgZXZlcnkgb3RoZXIgY2hpbGQgZnJvbSB0aGUgcGFyZW50IHNvIFxuICAgICAgICAvLyB3ZSBkb250IGVuZCB1cCB3aXRoIG11bHRpcGxlIHNldHMgb2YgZGF0YS4gVGhpcyBzaG91bGRcbiAgICAgICAgLy8gcmVhbGx5IG9ubHkgbmVlZCB0byBsb29wIG9uY2UgZm9yIGkgPSAwIGJ1dCBsb29wIGp1c3RcbiAgICAgICAgLy8gaW4gY2FzZS5cbiAgICAgICAgZm9yKGxldCBpID0gcGFyZW50RWxlbWVudC5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgcGFyZW50RWxlbWVudC5jaGlsZHJlbltpXS5kZXRhY2goKTtcbiAgICAgICAgfVxuICAgICAgICBwYXJlbnRFbGVtZW50LmFwcGVuZENoaWxkKG1hcmtkb3duUmVuZGVyQ2hpbGQuY29udGFpbmVyRWwpO1xuXG4gICAgICAgIHRoaXMuYXBwZW5kRWxlbWVudHNUb0NvbHVtbnMocmVnaW9uRWxlbWVudHMsIGNvbHVtbkNvbnRlbnREaXZzLCBzZXR0aW5ncywgaXNMaXZlUHJldmlldyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhcHBlbmRFbGVtZW50c1RvQ29sdW1ucyhyZWdpb25FbGVtZW50czogRE9NT2JqZWN0W10sIGNvbHVtbkNvbnRlbnREaXZzOiBIVE1MRGl2RWxlbWVudFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MsIGlzTGl2ZVByZXZpZXc6IGJvb2xlYW4gPSBmYWxzZSkge1xuXG4gICAgICAgIGxldCBjb2x1bW5JbmRleCA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVnaW9uRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgaWYgKHJlZ2lvbkVsZW1lbnRzW2ldLnRhZyA9PT0gRE9NT2JqZWN0VGFnLm5vbmUgfHxcbiAgICAgICAgICAgICAgICByZWdpb25FbGVtZW50c1tpXS50YWcgPT09IERPTU9iamVjdFRhZy5jb2x1bW5CcmVhaykge1xuXG4gICAgICAgICAgICAgICAgLy8gSWYgYSBzdGFuZGFyZCBlbGVtZW50IGNvbnRhaW5zIGEgY29sdW1uIGJyZWFrIHRhZyBhbmQgaXQgaXMgc2V0IGFzIGEgcHJlIGNvbnRlbnQgYnJlYWsgdGFnIHdlIGZsaXAgb3VyIGluZGV4IGhlcmUuXG4gICAgICAgICAgICAgICAgaWYocmVnaW9uRWxlbWVudHNbaV0udGFnID09PSBET01PYmplY3RUYWcubm9uZSAmJiBcbiAgICAgICAgICAgICAgICAgICByZWdpb25FbGVtZW50c1tpXS5lbGVtZW50SXNDb2x1bW5CcmVhayA9PT0gRWxlbWVudENvbHVtbkJyZWFrVHlwZS5wcmVCcmVhayAmJiBcbiAgICAgICAgICAgICAgICAgICAoY29sdW1uSW5kZXggKyAxKSA8IHNldHRpbmdzLm51bWJlck9mQ29sdW1ucykge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW5JbmRleCsrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIFdlIHN0b3JlIHRoZSBlbGVtZW50cyBpbiBhIHdyYXBwZXIgY29udGFpbmVyIHVudGlsIHdlIGRldGVybWluZVxuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgY2xzOiBNdWx0aUNvbHVtbkxheW91dENTUy5Db2x1bW5EdWFsRWxlbWVudENvbnRhaW5lcixcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGlmKGNvbHVtbk92ZXJmbG93U3RhdGUoY29sdW1uSW5kZXgsIHNldHRpbmdzKSA9PT0gQ29udGVudE92ZXJmbG93VHlwZS5oaWRkZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5Db250ZW50T3ZlcmZsb3dIaWRkZW5fWClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29udGVudE92ZXJmbG93QXV0b1Njcm9sbF9YKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBhbGlnbm1lbnQgPSBjb2x1bW5BbGlnbm1lbnRTdGF0ZShjb2x1bW5JbmRleCwgc2V0dGluZ3MpO1xuICAgICAgICAgICAgICAgIGlmKGFsaWdubWVudCA9PT0gQWxpZ25tZW50VHlwZS5jZW50ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5BbGlnbm1lbnRDZW50ZXIpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGFsaWdubWVudCA9PT0gQWxpZ25tZW50VHlwZS5yaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFkZENsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLkFsaWdubWVudFJpZ2h0KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5BbGlnbm1lbnRMZWZ0KVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCB0YWJsZUFsaWdubWVudCA9IE1DTV9TZXR0aW5nc01hbmFnZXIuc2hhcmVkLmFsaWduVGFibGVzVG9Db250ZW50QWxpZ25tZW50O1xuICAgICAgICAgICAgICAgIGlmKHNldHRpbmdzLmFsaWduVGFibGVzVG9BbGlnbm1lbnQgIT09IFRhYmxlQWxpZ25tZW50LnVzZVNldHRpbmdzRGVmYXVsdCkge1xuICAgICAgICAgICAgICAgICAgICB0YWJsZUFsaWdubWVudCA9IHNldHRpbmdzLmFsaWduVGFibGVzVG9BbGlnbm1lbnQgPT09IFRhYmxlQWxpZ25tZW50LmFsaWduXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmKHRhYmxlQWxpZ25tZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuVGFibGVBbGlnbm1lbnQpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVnaW9uRWxlbWVudHNbaV0uZWxlbWVudENvbnRhaW5lciA9IGVsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudFRvQXBwZW5kOiBIVE1MRWxlbWVudCA9IHJlZ2lvbkVsZW1lbnRzW2ldLm9yaWdpbmFsRWxlbWVudDtcbiAgICAgICAgICAgICAgICBpZihpc0xpdmVQcmV2aWV3ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgY2xvbmVkRWxlbWVudCA9IHJlZ2lvbkVsZW1lbnRzW2ldLm9yaWdpbmFsRWxlbWVudC5jbG9uZU5vZGUodHJ1ZSkgYXMgSFRNTERpdkVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIGxldCBoZWFkaW5nQ29sbGFwc2VFbGVtZW50ID0gZ2V0SGVhZGluZ0NvbGxhcHNlRWxlbWVudChjbG9uZWRFbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgaWYoaGVhZGluZ0NvbGxhcHNlRWxlbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyByZW1vdmVzIHRoZSBjb2xsYXBzZSBhcnJvdyBmcm9tIHRoZSB2aWV3IGlmIGl0IGV4aXN0cy5cbiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRpbmdDb2xsYXBzZUVsZW1lbnQuZGV0YWNoKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmVnaW9uRWxlbWVudHNbaV0uY2xvbmVkRWxlbWVudCA9IGNsb25lZEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRUb0FwcGVuZCA9IGNsb25lZEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChlbGVtZW50VG9BcHBlbmQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlZ2lvbkVsZW1lbnRzW2ldIGluc3RhbmNlb2YgVGFza0xpc3RET01PYmplY3QpIHtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpeENsb25lZENoZWNrTGlzdEJ1dHRvbnMocmVnaW9uRWxlbWVudHNbaV0gYXMgVGFza0xpc3RET01PYmplY3QsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ICE9PSBudWxsICYmIHJlZ2lvbkVsZW1lbnRzW2ldLnRhZyAhPT0gRE9NT2JqZWN0VGFnLmNvbHVtbkJyZWFrKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29sdW1uQ29udGVudERpdnNbY29sdW1uSW5kZXhdLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAqIElmIHRoZSB0YWcgaXMgYSBjb2x1bW4gYnJlYWsgd2UgdXBkYXRlIHRoZSBjb2x1bW4gaW5kZXggYWZ0ZXJcbiAgICAgICAgICAgICAgICAgKiBhcHBlbmRpbmcgdGhlIGl0ZW0gdG8gdGhlIGNvbHVtbiBkaXYuIFRoaXMga2VlcHMgdGhlIG1haW4gRE9NXG4gICAgICAgICAgICAgICAgICogY2xlYW5lciBieSByZW1vdmluZyBvdGhlciBpdGVtcyBhbmQgcGxhY2luZyB0aGVtIGFsbCB3aXRoaW5cbiAgICAgICAgICAgICAgICAgKiBhIHJlZ2lvbiBjb250YWluZXIuXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgaWYgKHJlZ2lvbkVsZW1lbnRzW2ldLnRhZyA9PT0gRE9NT2JqZWN0VGFnLmNvbHVtbkJyZWFrICYmXG4gICAgICAgICAgICAgICAgICAgIChjb2x1bW5JbmRleCArIDEpIDwgc2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29sdW1uSW5kZXgrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZihyZWdpb25FbGVtZW50c1tpXS50YWcgPT09IERPTU9iamVjdFRhZy5ub25lICYmIFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW9uRWxlbWVudHNbaV0uZWxlbWVudElzQ29sdW1uQnJlYWsgPT09IEVsZW1lbnRDb2x1bW5CcmVha1R5cGUucG9zdEJyZWFrICYmIFxuICAgICAgICAgICAgICAgICAgICAgICAgKGNvbHVtbkluZGV4ICsgMSkgPCBzZXR0aW5ncy5udW1iZXJPZkNvbHVtbnMpIHtcblxuICAgICAgICAgICAgICAgICAgICAvLyBJZiBhIHN0YW5kYXJkIGVsZW1lbnQgY29udGFpbnMgYSBjb2x1bW4gYnJlYWsgdGFnIGFuZCBpdCBpcyBzZXQgYXMgYSBwb3N0IGNvbnRlbnQgYnJlYWsgdGFnIHdlIGZsaXAgb3VyIGluZGV4IGhlcmUuXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbkluZGV4Kys7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIiwiLyoqXG4gKiBGaWxlOiAvc3JjL2RvbV9tYW5hZ2VyL3JlZ2lvbmFsX21hbmFnZXJzL3NpbmdsZUNvbHVtblJlZ2lvbk1hbmFnZXIudHMgICAgICAgKlxuICogQXV0aG9yOiBDYW1lcm9uIFJvYmluc29uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjMgQ2FtZXJvbiBSb2JpbnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICovXG5cbmltcG9ydCB7IERPTU9iamVjdCwgRE9NT2JqZWN0VGFnLCBUYXNrTGlzdERPTU9iamVjdCB9IGZyb20gJy4uL2RvbU9iamVjdCc7XG5pbXBvcnQgeyBNdWx0aUNvbHVtblNldHRpbmdzLCBDb2x1bW5MYXlvdXQsIENvbnRlbnRPdmVyZmxvd1R5cGUsIEFsaWdubWVudFR5cGUsIGNvbHVtbk92ZXJmbG93U3RhdGUsIGNvbHVtbkFsaWdubWVudFN0YXRlLCBzaG91bGREcmF3Q29sdW1uQm9yZGVyLCBUYWJsZUFsaWdubWVudCB9IGZyb20gXCIuLi8uLi9yZWdpb25TZXR0aW5nc1wiO1xuaW1wb3J0IHsgTXVsdGlDb2x1bW5MYXlvdXRDU1MsIE11bHRpQ29sdW1uU3R5bGVDU1MgfSBmcm9tICcuLi8uLi91dGlsaXRpZXMvY3NzRGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgTWFya2Rvd25SZW5kZXJDaGlsZCB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB7IFJlZ2lvbk1hbmFnZXIgfSBmcm9tICcuL3JlZ2lvbk1hbmFnZXInO1xuaW1wb3J0IHsgZ2V0SGVhZGluZ0NvbGxhcHNlRWxlbWVudCB9IGZyb20gJ3NyYy91dGlsaXRpZXMvZWxlbWVudFJlbmRlclR5cGVQYXJzZXInO1xuaW1wb3J0IHsgTUNNX1NldHRpbmdzTWFuYWdlciB9IGZyb20gJ3NyYy9wbHVnaW5TZXR0aW5ncyc7XG5cbmV4cG9ydCBjbGFzcyBTaW5nbGVDb2x1bW5SZWdpb25NYW5hZ2VyIGV4dGVuZHMgUmVnaW9uTWFuYWdlciB7XG5cblxuICAgIHB1YmxpYyByZW5kZXJSZWdpb25FbGVtZW50c1RvU2NyZWVuKCk6IHZvaWQge1xuXG4gICAgICAgIHRoaXMucmVuZGVyQ29sdW1uTWFya2Rvd24odGhpcy5yZWdpb25QYXJlbnQsIHRoaXMuZG9tTGlzdCwgdGhpcy5yZWdpb25hbFNldHRpbmdzKTtcbiAgICB9XG4gICAgcHVibGljIGV4cG9ydFJlZ2lvbkVsZW1lbnRzVG9QREYocGRmUGFyZW50RWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcblxuICAgICAgICAvLyBEZWZhdWx0IHNldCBzaGFkb3cgdG8gb2ZmIGZvciBleHBvcnRpbmcgUERGc1xuICAgICAgICBsZXQgcmVuZGVyU2V0dGluZ3MgPSB0aGlzLnJlZ2lvbmFsU2V0dGluZ3M7XG4gICAgICAgIHJlbmRlclNldHRpbmdzLmRyYXdTaGFkb3cgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZW5kZXJDb2x1bW5NYXJrZG93bihwZGZQYXJlbnRFbGVtZW50LCB0aGlzLmRvbUxpc3Quc2xpY2UoKSwgcmVuZGVyU2V0dGluZ3MpO1xuICAgIH1cbiAgICBwdWJsaWMgcmVuZGVyUmVnaW9uRWxlbWVudHNUb0xpdmVQcmV2aWV3KHBhcmVudEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJDb2x1bW5NYXJrZG93bihwYXJlbnRFbGVtZW50LCB0aGlzLmRvbUxpc3QsIHRoaXMucmVnaW9uYWxTZXR0aW5ncywgdHJ1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gdGFrZXMgaW4gdGhlIGRhdGEgZm9yIHRoZSBtdWx0aS1jb2x1bW4gcmVnaW9uIGFuZCBzZXRzIHVwIHRoZVxuICAgICAqIHVzZXIgZGVmaW5lZCBudW1iZXIgb2YgY2hpbGRyZW4gd2l0aCB0aGUgcHJvcGVyIGNzcyBjbGFzc2VzIHRvIGJlIHJlbmRlcmVkIHByb3Blcmx5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHBhcmVudEVsZW1lbnQgVGhlIGVsZW1lbnQgdGhhdCB0aGUgbXVsdGktY29sdW1uIHJlZ2lvbiB3aWxsIGJlIHJlbmRlcmVkIHVuZGVyLlxuICAgICAqIEBwYXJhbSByZWdpb25FbGVtZW50cyBUaGUgbGlzdCBvZiBET00gb2JqZWN0cyB0aGF0IHdpbGwgYmUgY29wcGllZCB1bmRlciB0aGUgcGFyZW50IG9iamVjdFxuICAgICAqIEBwYXJhbSBzZXR0aW5ncyBUaGUgc2V0dGluZ3MgdGhlIHVzZXIgaGFzIGRlZmluZWQgZm9yIHRoZSByZWdpb24uXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlbmRlckNvbHVtbk1hcmtkb3duKHBhcmVudEVsZW1lbnQ6IEhUTUxFbGVtZW50LCByZWdpb25FbGVtZW50czogRE9NT2JqZWN0W10sIHNldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzLCBpc0xpdmVQcmV2aWV3OiBib29sZWFuID0gZmFsc2UpIHtcblxuICAgICAgICBsZXQgbXVsdGlDb2x1bW5QYXJlbnQgPSBjcmVhdGVEaXYoe1xuICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtbkxheW91dENTUy5SZWdpb25Db2x1bW5Db250YWluZXJEaXZ9IFxcXG4gICAgICAgICAgICAgICAgICAke011bHRpQ29sdW1uTGF5b3V0Q1NTLkNvbnRlbnRPdmVyZmxvd0F1dG9TY3JvbGxfWH0gXFxcbiAgICAgICAgICAgICAgICAgICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29udGVudE92ZXJmbG93SGlkZGVuX1l9O1xuICAgICAgICAgICAgICAgICAgYFxuICAgICAgICB9KTtcblxuICAgICAgICBpZihpc0xlZnRMYXlvdXQodGhpcy5yZWdpb25hbFNldHRpbmdzLmNvbHVtblBvc2l0aW9uKSl7XG4gICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5TaW5nbGVDb2x1bW5MZWZ0TGF5b3V0KVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYoaXNSaWdodExheW91dCh0aGlzLnJlZ2lvbmFsU2V0dGluZ3MuY29sdW1uUG9zaXRpb24pKSB7XG4gICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5TaW5nbGVDb2x1bW5SaWdodExheW91dClcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG11bHRpQ29sdW1uUGFyZW50LmFkZENsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLlNpbmdsZUNvbHVtbkNlbnRlckxheW91dClcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQYXNzIG91ciBwYXJlbnQgZGl2IGFuZCBzZXR0aW5ncyB0byBwYXJzZXIgdG8gY3JlYXRlIHRoZSByZXF1aXJlZFxuICAgICAgICAgKiBjb2x1bW4gZGl2cyBhcyBjaGlsZHJlbiBvZiB0aGUgcGFyZW50LlxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IGNvbHVtbkNvbnRlbnREaXYgPSB0aGlzLmNyZWF0ZUNvbHVtbkNvbnRlbnREaXZzKG11bHRpQ29sdW1uUGFyZW50KTtcbiAgICAgICAgaWYoc2hvdWxkRHJhd0NvbHVtbkJvcmRlcigwLCBzZXR0aW5ncykgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbHVtbkNvbnRlbnREaXYuYWRkQ2xhc3MoTXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Cb3JkZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5kcmF3U2hhZG93ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2LmFkZENsYXNzKE11bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uU2hhZG93KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBtYXJrZG93biByZW5kZXJlciB0byBwYXJzZSB0aGUgcGFzc2VkIG1hcmtkb3duXG4gICAgICAgIC8vIGJldHdlZW4gdGhlIHRhZ3MuXG4gICAgICAgIGxldCBtYXJrZG93blJlbmRlckNoaWxkID0gbmV3IE1hcmtkb3duUmVuZGVyQ2hpbGQoXG4gICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFJlbW92ZSBldmVyeSBvdGhlciBjaGlsZCBmcm9tIHRoZSBwYXJlbnQgc28gXG4gICAgICAgIC8vIHdlIGRvbnQgZW5kIHVwIHdpdGggbXVsdGlwbGUgc2V0cyBvZiBkYXRhLiBUaGlzIHNob3VsZFxuICAgICAgICAvLyByZWFsbHkgb25seSBuZWVkIHRvIGxvb3Agb25jZSBmb3IgaSA9IDAgYnV0IGxvb3AganVzdFxuICAgICAgICAvLyBpbiBjYXNlLlxuICAgICAgICBmb3IgKGxldCBpID0gcGFyZW50RWxlbWVudC5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgcGFyZW50RWxlbWVudC5jaGlsZHJlbltpXS5kZXRhY2goKTtcbiAgICAgICAgfVxuICAgICAgICBwYXJlbnRFbGVtZW50LmFwcGVuZENoaWxkKG1hcmtkb3duUmVuZGVyQ2hpbGQuY29udGFpbmVyRWwpO1xuXG4gICAgICAgIHRoaXMuYXBwZW5kRWxlbWVudHNUb0NvbHVtbnMocmVnaW9uRWxlbWVudHMsIGNvbHVtbkNvbnRlbnREaXYsIHNldHRpbmdzLCBpc0xpdmVQcmV2aWV3KTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgYXBwZW5kRWxlbWVudHNUb0NvbHVtbnMocmVnaW9uRWxlbWVudHM6IERPTU9iamVjdFtdLCBjb2x1bW5Db250ZW50RGl2OiBIVE1MRGl2RWxlbWVudCwgc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MsIGlzTGl2ZVByZXZpZXc6IGJvb2xlYW4gPSBmYWxzZSkge1xuXG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWdpb25FbGVtZW50cy5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgICAgICBpZiAocmVnaW9uRWxlbWVudHNbaV0udGFnID09PSBET01PYmplY3RUYWcubm9uZSB8fFxuICAgICAgICAgICAgICAgIHJlZ2lvbkVsZW1lbnRzW2ldLnRhZyA9PT0gRE9NT2JqZWN0VGFnLmNvbHVtbkJyZWFrKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBXZSBzdG9yZSB0aGUgZWxlbWVudHMgaW4gYSB3cmFwcGVyIGNvbnRhaW5lciB1bnRpbCB3ZSBkZXRlcm1pbmVcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudCA9IGNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29sdW1uRHVhbEVsZW1lbnRDb250YWluZXIsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmVnaW9uRWxlbWVudHNbaV0uZWxlbWVudENvbnRhaW5lciA9IGVsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZihjb2x1bW5PdmVyZmxvd1N0YXRlKDAsIHNldHRpbmdzKSA9PT0gQ29udGVudE92ZXJmbG93VHlwZS5oaWRkZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5Db250ZW50T3ZlcmZsb3dIaWRkZW5fWClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29udGVudE92ZXJmbG93QXV0b1Njcm9sbF9YKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBsZXQgYWxpZ25tZW50ID0gY29sdW1uQWxpZ25tZW50U3RhdGUoMCwgc2V0dGluZ3MpO1xuICAgICAgICAgICAgICAgIGlmKGFsaWdubWVudCA9PT0gQWxpZ25tZW50VHlwZS5jZW50ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5BbGlnbm1lbnRDZW50ZXIpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGFsaWdubWVudCA9PT0gQWxpZ25tZW50VHlwZS5yaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFkZENsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLkFsaWdubWVudFJpZ2h0KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5BbGlnbm1lbnRMZWZ0KVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCB0YWJsZUFsaWdubWVudCA9IE1DTV9TZXR0aW5nc01hbmFnZXIuc2hhcmVkLmFsaWduVGFibGVzVG9Db250ZW50QWxpZ25tZW50O1xuICAgICAgICAgICAgICAgIGlmKHNldHRpbmdzLmFsaWduVGFibGVzVG9BbGlnbm1lbnQgIT09IFRhYmxlQWxpZ25tZW50LnVzZVNldHRpbmdzRGVmYXVsdCkge1xuICAgICAgICAgICAgICAgICAgICB0YWJsZUFsaWdubWVudCA9IHNldHRpbmdzLmFsaWduVGFibGVzVG9BbGlnbm1lbnQgPT09IFRhYmxlQWxpZ25tZW50LmFsaWduXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmKHRhYmxlQWxpZ25tZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuVGFibGVBbGlnbm1lbnQpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnRUb0FwcGVuZDogSFRNTEVsZW1lbnQgPSByZWdpb25FbGVtZW50c1tpXS5vcmlnaW5hbEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgaWYoaXNMaXZlUHJldmlldyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNsb25lZEVsZW1lbnQgPSByZWdpb25FbGVtZW50c1tpXS5vcmlnaW5hbEVsZW1lbnQuY2xvbmVOb2RlKHRydWUpIGFzIEhUTUxEaXZFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICBsZXQgaGVhZGluZ0NvbGxhcHNlRWxlbWVudCA9IGdldEhlYWRpbmdDb2xsYXBzZUVsZW1lbnQoY2xvbmVkRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgIGlmKGhlYWRpbmdDb2xsYXBzZUVsZW1lbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgcmVtb3ZlcyB0aGUgY29sbGFwc2UgYXJyb3cgZnJvbSB0aGUgdmlldyBpZiBpdCBleGlzdHMuXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkaW5nQ29sbGFwc2VFbGVtZW50LmRldGFjaCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJlZ2lvbkVsZW1lbnRzW2ldLmNsb25lZEVsZW1lbnQgPSBjbG9uZWRFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50VG9BcHBlbmQgPSBjbG9uZWRFbGVtZW50XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoZWxlbWVudFRvQXBwZW5kKTtcblxuICAgICAgICAgICAgICAgIGlmIChyZWdpb25FbGVtZW50c1tpXSBpbnN0YW5jZW9mIFRhc2tMaXN0RE9NT2JqZWN0KSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXhDbG9uZWRDaGVja0xpc3RCdXR0b25zKHJlZ2lvbkVsZW1lbnRzW2ldIGFzIFRhc2tMaXN0RE9NT2JqZWN0LCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCAhPT0gbnVsbCkge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbkNvbnRlbnREaXYuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY3JlYXRlQ29sdW1uQ29udGVudERpdnMobXVsdGlDb2x1bW5QYXJlbnQ6IEhUTUxEaXZFbGVtZW50KTogSFRNTERpdkVsZW1lbnQge1xuXG4gICAgICAgIGxldCBjb250ZW50RGl2ID0gbXVsdGlDb2x1bW5QYXJlbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Db250ZW50fWBcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYodGhpcy5yZWdpb25hbFNldHRpbmdzLmNvbHVtblNpemUgPT09IFwic21hbGxcIikge1xuICAgICAgICAgICAgY29udGVudERpdi5hZGRDbGFzcyhgJHtNdWx0aUNvbHVtbkxheW91dENTUy5TaW5nbGVDb2x1bW5TbWFsbH1gKVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYodGhpcy5yZWdpb25hbFNldHRpbmdzLmNvbHVtblNpemUgPT09IFwibGFyZ2VcIikge1xuICAgICAgICAgICAgY29udGVudERpdi5hZGRDbGFzcyhgJHtNdWx0aUNvbHVtbkxheW91dENTUy5TaW5nbGVDb2x1bW5MYXJnZX1gKVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYodGhpcy5yZWdpb25hbFNldHRpbmdzLmNvbHVtblNpemUgPT09IFwiZnVsbFwiKSB7XG4gICAgICAgICAgICBjb250ZW50RGl2LmFkZENsYXNzKGAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlNpbmdsZUNvbHVtbkZ1bGx9YClcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRlbnREaXYuYWRkQ2xhc3MoYCR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuU2luZ2xlQ29sdW1uTWVkfWApXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29udGVudERpdjtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzQ2VudGVyZWQobGF5b3V0OiBDb2x1bW5MYXlvdXQpOiBib29sZWFuIHtcblxuICAgIGlmKGxheW91dCA9PT0gXCJzdGFuZGFyZFwiIHx8XG4gICAgICAgbGF5b3V0ID09PSBcIm1pZGRsZVwiICAgfHxcbiAgICAgICBsYXlvdXQgPT09IFwiY2VudGVyXCIgICB8fFxuICAgICAgIGxheW91dCA9PT0gXCJzZWNvbmRcIiAgICApIHtcblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gaXNMZWZ0TGF5b3V0KGxheW91dDogQ29sdW1uTGF5b3V0KTogYm9vbGVhbiB7XG5cbiAgICBpZihsYXlvdXQgPT09IFwibGVmdFwiIHx8XG4gICAgICAgbGF5b3V0ID09PSBcImZpcnN0XCIgKSB7XG4gXG4gICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgfVxuIFxuICAgICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gaXNSaWdodExheW91dChsYXlvdXQ6IENvbHVtbkxheW91dCk6IGJvb2xlYW4ge1xuXG4gICAgaWYobGF5b3V0ID09PSBcInJpZ2h0XCIgfHxcbiAgICAgICBsYXlvdXQgPT09IFwidGhpcmRcIiB8fFxuICAgICAgIGxheW91dCA9PT0gXCJsYXN0XCIgKSB7XG4gXG4gICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgfVxuIFxuICAgICByZXR1cm4gZmFsc2Vcbn0iLCIvKipcbiAqIEZpbGU6IC9zcmMvZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvYXV0b0xheW91dFJlZ2lvbk1hbmFnZXIudHMgICAgICAgICAqXG4gKiBDcmVhdGVkIERhdGU6IFN1bmRheSwgTWF5IDIybmQgMjAyMiwgMTA6MjMgcG0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogQXV0aG9yOiBDYW1lcm9uIFJvYmluc29uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjIgQ2FtZXJvbiBSb2JpbnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICovXG5cbmltcG9ydCB7IERPTU9iamVjdCwgRE9NT2JqZWN0VGFnLCBUYXNrTGlzdERPTU9iamVjdCB9IGZyb20gJy4uL2RvbU9iamVjdCc7XG5pbXBvcnQgeyBBbGlnbm1lbnRUeXBlLCBDb250ZW50T3ZlcmZsb3dUeXBlLCBNdWx0aUNvbHVtblNldHRpbmdzLCBUYWJsZUFsaWdubWVudCwgY29sdW1uQWxpZ25tZW50U3RhdGUsIGNvbHVtbk92ZXJmbG93U3RhdGUsIHNob3VsZERyYXdDb2x1bW5Cb3JkZXIgfSBmcm9tIFwiLi4vLi4vcmVnaW9uU2V0dGluZ3NcIjtcbmltcG9ydCB7IE11bHRpQ29sdW1uTGF5b3V0Q1NTLCBNdWx0aUNvbHVtblN0eWxlQ1NTIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2Nzc0RlZmluaXRpb25zJztcbmltcG9ydCB7IFJlZ2lvbk1hbmFnZXIgfSBmcm9tICcuL3JlZ2lvbk1hbmFnZXInO1xuaW1wb3J0IHsgZ2V0SGVhZGluZ0NvbGxhcHNlRWxlbWVudCwgaGFzSGVhZGVyIH0gZnJvbSAnc3JjL3V0aWxpdGllcy9lbGVtZW50UmVuZGVyVHlwZVBhcnNlcic7XG5pbXBvcnQgeyBSZWdpb25NYW5hZ2VyRGF0YSB9IGZyb20gJy4vcmVnaW9uTWFuYWdlckNvbnRhaW5lcic7XG5pbXBvcnQgeyBNQ01fU2V0dGluZ3NNYW5hZ2VyIH0gZnJvbSAnc3JjL3BsdWdpblNldHRpbmdzJztcblxuZXhwb3J0IGNsYXNzIEF1dG9MYXlvdXRSZWdpb25NYW5hZ2VyIGV4dGVuZHMgUmVnaW9uTWFuYWdlciB7XG5cbiAgICBwcml2YXRlIGlzTGl2ZVByZXZpZXc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBwcml2YXRlIHByZXZpb3VzQ29sdW1uSGVpZ2h0czogbnVtYmVyW10gPSBbXVxuXG4gICAgcHJpdmF0ZSBjb2x1bW5QYXJlbnQ6IEhUTUxEaXZFbGVtZW50O1xuICAgIHByaXZhdGUgY29sdW1uRGl2czogSFRNTERpdkVsZW1lbnRbXTtcbiAgICBwcml2YXRlIGRvY1JlZmxvdzogYm9vbGVhbjtcblxuICAgIGNvbnN0cnVjdG9yKGRhdGE6IFJlZ2lvbk1hbmFnZXJEYXRhLCBpc0xpdmVQcmV2aWV3OiBib29sZWFuID0gZmFsc2UpIHtcbiAgICAgICAgc3VwZXIoZGF0YSk7XG5cbiAgICAgICAgdGhpcy5pc0xpdmVQcmV2aWV3ID0gaXNMaXZlUHJldmlldztcbiAgICAgICAgdGhpcy5kb2NSZWZsb3cgPSBkYXRhLnJlZ2lvbmFsU2V0dGluZ3MuZnVsbERvY1JlZmxvdztcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVuZGVyUmVnaW9uRWxlbWVudHNUb1NjcmVlbigpOiB2b2lkIHtcblxuICAgICAgICAgdGhpcy5yZW5kZXJDb2x1bW5NYXJrZG93bih0aGlzLnJlZ2lvblBhcmVudCwgdGhpcy5kb21MaXN0LCB0aGlzLnJlZ2lvbmFsU2V0dGluZ3MpO1xuICAgIH1cbiAgICBwdWJsaWMgZXhwb3J0UmVnaW9uRWxlbWVudHNUb1BERihwZGZQYXJlbnRFbGVtZW50OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuXG4gICAgICAgIC8vIERlZmF1bHQgc2V0IHNoYWRvdyB0byBvZmYgZm9yIGV4cG9ydGluZyBQREZzXG4gICAgICAgIGxldCByZW5kZXJTZXR0aW5ncyA9IHRoaXMucmVnaW9uYWxTZXR0aW5ncztcbiAgICAgICAgcmVuZGVyU2V0dGluZ3MuZHJhd1NoYWRvdyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlbmRlckNvbHVtbk1hcmtkb3duKHBkZlBhcmVudEVsZW1lbnQsIHRoaXMuZG9tTGlzdC5zbGljZSgpLCByZW5kZXJTZXR0aW5ncyk7XG4gICAgfVxuICAgIHB1YmxpYyByZW5kZXJSZWdpb25FbGVtZW50c1RvTGl2ZVByZXZpZXcocGFyZW50RWxlbWVudDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcblxuICAgICAgICB0aGlzLnJlbmRlckNvbHVtbk1hcmtkb3duKHBhcmVudEVsZW1lbnQsIHRoaXMuZG9tTGlzdCwgdGhpcy5yZWdpb25hbFNldHRpbmdzLCB0cnVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiB0YWtlcyBpbiB0aGUgZGF0YSBmb3IgdGhlIG11bHRpLWNvbHVtbiByZWdpb24gYW5kIHNldHMgdXAgdGhlIFxuICAgICAqIHVzZXIgZGVmaW5lZCBudW1iZXIgb2YgY2hpbGRyZW4gd2l0aCB0aGUgcHJvcGVyIGNzcyBjbGFzc2VzIHRvIGJlIHJlbmRlcmVkIHByb3Blcmx5LlxuICAgICAqIFxuICAgICAqIEBwYXJhbSBwYXJlbnRFbGVtZW50IFRoZSBlbGVtZW50IHRoYXQgdGhlIG11bHRpLWNvbHVtbiByZWdpb24gd2lsbCBiZSByZW5kZXJlZCB1bmRlci5cbiAgICAgKiBAcGFyYW0gcmVnaW9uRWxlbWVudHMgVGhlIGxpc3Qgb2YgRE9NIG9iamVjdHMgdGhhdCB3aWxsIGJlIGNvcHBpZWQgdW5kZXIgdGhlIHBhcmVudCBvYmplY3RcbiAgICAgKiBAcGFyYW0gc2V0dGluZ3MgVGhlIHNldHRpbmdzIHRoZSB1c2VyIGhhcyBkZWZpbmVkIGZvciB0aGUgcmVnaW9uLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVuZGVyQ29sdW1uTWFya2Rvd24ocGFyZW50RWxlbWVudDogSFRNTEVsZW1lbnQsIHJlZ2lvbkVsZW1lbnRzOiBET01PYmplY3RbXSwgc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MsIGlzTGl2ZVByZXZpZXc6IGJvb2xlYW4gPSBmYWxzZSkge1xuXG4gICAgICAgIGxldCBtdWx0aUNvbHVtblBhcmVudCA9IGNyZWF0ZURpdih7XG4gICAgICAgICAgICBjbHM6IGAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlJlZ2lvbkNvbHVtbkNvbnRhaW5lckRpdn0gXFxcbiAgICAgICAgICAgICAgICAgICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29udGVudE92ZXJmbG93QXV0b1Njcm9sbF9YfSBcXFxuICAgICAgICAgICAgICAgICAgJHtNdWx0aUNvbHVtbkxheW91dENTUy5Db250ZW50T3ZlcmZsb3dIaWRkZW5fWX07XG4gICAgICAgICAgICAgICAgICBgXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNvbHVtblBhcmVudCA9IG11bHRpQ29sdW1uUGFyZW50O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQYXNzIG91ciBwYXJlbnQgZGl2IGFuZCBzZXR0aW5ncyB0byBwYXJzZXIgdG8gY3JlYXRlIHRoZSByZXF1aXJlZFxuICAgICAgICAgKiBjb2x1bW4gZGl2cyBhcyBjaGlsZHJlbiBvZiB0aGUgcGFyZW50LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb2x1bW5EaXZzID0gdGhpcy5nZXRDb2x1bW5Db250ZW50RGl2cyhzZXR0aW5ncywgbXVsdGlDb2x1bW5QYXJlbnQpO1xuXG4gICAgICAgIGlmIChzZXR0aW5ncy5kcmF3U2hhZG93ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBtdWx0aUNvbHVtblBhcmVudC5hZGRDbGFzcyhNdWx0aUNvbHVtblN0eWxlQ1NTLlJlZ2lvblNoYWRvdyk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNvbHVtbkRpdnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmKHNob3VsZERyYXdDb2x1bW5Cb3JkZXIoaSwgc2V0dGluZ3MpID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb2x1bW5EaXZzW2ldLmFkZENsYXNzKE11bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uQm9yZGVyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLmRyYXdTaGFkb3cgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbHVtbkRpdnNbaV0uYWRkQ2xhc3MoTXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5TaGFkb3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIGV2ZXJ5IG90aGVyIGNoaWxkIGZyb20gdGhlIHBhcmVudCBzbyBcbiAgICAgICAgLy8gd2UgZG9udCBlbmQgdXAgd2l0aCBtdWx0aXBsZSBzZXRzIG9mIGRhdGEuIFRoaXMgc2hvdWxkXG4gICAgICAgIC8vIHJlYWxseSBvbmx5IG5lZWQgdG8gbG9vcCBvbmNlIGZvciBpID0gMCBidXQgbG9vcCBqdXN0XG4gICAgICAgIC8vIGluIGNhc2UuXG4gICAgICAgIGZvciAobGV0IGkgPSBwYXJlbnRFbGVtZW50LmNoaWxkcmVuLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBwYXJlbnRFbGVtZW50LmNoaWxkcmVuW2ldLmRldGFjaCgpO1xuICAgICAgICB9XG4gICAgICAgIHBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQobXVsdGlDb2x1bW5QYXJlbnQpO1xuXG4gICAgICAgIHRoaXMuYXBwZW5kRWxlbWVudHNUb0NvbHVtbnMocmVnaW9uRWxlbWVudHMsIHRoaXMuY29sdW1uRGl2cywgc2V0dGluZ3MsIGlzTGl2ZVByZXZpZXcpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXBwZW5kRWxlbWVudHNUb0NvbHVtbnMocmVnaW9uRWxlbWVudHM6IERPTU9iamVjdFtdLCBjb2x1bW5Db250ZW50RGl2czogSFRNTERpdkVsZW1lbnRbXSwgc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MsIGlzTGl2ZVByZXZpZXc6IGJvb2xlYW4gPSBmYWxzZSkge1xuXG4gICAgICAgIGZ1bmN0aW9uIGJhbGFuY2VFbGVtZW50cygpIHtcblxuICAgICAgICAgICAgbGV0IHRvdGFsSGVpZ2h0ID0gcmVnaW9uRWxlbWVudHMubWFwKChlbDogRE9NT2JqZWN0LCBpbmRleDogbnVtYmVyKSA9PiB7IFxuXG4gICAgICAgICAgICAgICAgLy8gV2Ugb25seSB3YW50IHRvIGF0dGVtcHQgdG8gdXBkYXRlIHRoZSBlbGVtZW50UmVuZGVyZWRIZWlnaHQgaWYgaXQgaXMgMCBhbmQgaWYgaXQgaXMgbm90IGFuIHVucmVuZGVyZWQgZWxlbWVudCBzdWNoIGFzIGEgZW5kcmVnaW9uIHRhZy5cbiAgICAgICAgICAgICAgICBpZihlbC5lbGVtZW50UmVuZGVyZWRIZWlnaHQgPT09IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgZWwudGFnICE9PSBET01PYmplY3RUYWcuY29sdW1uQnJlYWsgJiZcbiAgICAgICAgICAgICAgICAgICAgZWwudGFnICE9PSBET01PYmplY3RUYWcuZW5kUmVnaW9uICYmXG4gICAgICAgICAgICAgICAgICAgIGVsLnRhZyAhPT0gRE9NT2JqZWN0VGFnLnJlZ2lvblNldHRpbmdzICYmXG4gICAgICAgICAgICAgICAgICAgIGVsLnRhZyAhPT0gRE9NT2JqZWN0VGFnLnN0YXJ0UmVnaW9uKSB7XG4gICAgXG4gICAgICAgICAgICAgICAgICAgIC8vIEFkZCBlbGVtZW50IHRvIHJlbmRlcmVkIGRpdiBzbyB3ZSBjYW4gZXh0cmFjdCB0aGUgcmVuZGVyZWQgaGVpZ2h0LlxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2c1swXS5hcHBlbmRDaGlsZChlbC5vcmlnaW5hbEVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgIGVsLmVsZW1lbnRSZW5kZXJlZEhlaWdodCA9IGVsLm9yaWdpbmFsRWxlbWVudC5jbGllbnRIZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uQ29udGVudERpdnNbMF0ucmVtb3ZlQ2hpbGQoZWwub3JpZ2luYWxFbGVtZW50KVxuICAgICAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgICAgICByZXR1cm4gZWwuZWxlbWVudFJlbmRlcmVkSGVpZ2h0IFxuICAgICAgICAgICAgfSkucmVkdWNlKChwcmV2OiBudW1iZXIsIGN1cnI6IG51bWJlcikgPT4geyByZXR1cm4gcHJldiArIGN1cnIgfSwgMCk7XG4gICAgICAgICAgICBsZXQgbWF4Q29sdW1uQ29udGVudEhlaWdodCA9IE1hdGgudHJ1bmModG90YWxIZWlnaHQgLyBzZXR0aW5ncy5udW1iZXJPZkNvbHVtbnMpO1xuXG4gICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgY29sdW1uQ29udGVudERpdnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gY29sdW1uQ29udGVudERpdnNbaV0uY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uQ29udGVudERpdnNbaV0uY2hpbGRyZW5bal0uZGV0YWNoKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgY29sdW1uSW5kZXggPSAwO1xuICAgICAgICAgICAgbGV0IGN1cnJlbnRDb2x1bW5IZWlnaHQgPSAwO1xuICAgICAgICAgICAgZnVuY3Rpb24gY2hlY2tTaG91bGRTd2l0Y2hDb2x1bW5zKG5leHRFbGVtZW50SGVpZ2h0OiBudW1iZXIpIHtcbiAgICBcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudENvbHVtbkhlaWdodCArIG5leHRFbGVtZW50SGVpZ2h0ID4gbWF4Q29sdW1uQ29udGVudEhlaWdodCAmJlxuICAgICAgICAgICAgICAgICAgICAoY29sdW1uSW5kZXggKyAxKSA8IHNldHRpbmdzLm51bWJlck9mQ29sdW1ucykge1xuICAgIFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5JbmRleCsrO1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q29sdW1uSGVpZ2h0ID0gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVnaW9uRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgICAgIGlmIChyZWdpb25FbGVtZW50c1tpXS50YWcgPT09IERPTU9iamVjdFRhZy5ub25lIHx8XG4gICAgICAgICAgICAgICAgICAgIHJlZ2lvbkVsZW1lbnRzW2ldLnRhZyA9PT0gRE9NT2JqZWN0VGFnLmNvbHVtbkJyZWFrKSB7XG4gICAgXG4gICAgICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAgICAgKiBIZXJlIHdlIGNoZWNrIGlmIHdlIG5lZWQgdG8gc3dhcCB0byB0aGUgbmV4dCBjb2x1bW4gZm9yIHRoZSBjdXJyZW50IGVsZW1lbnQuXG4gICAgICAgICAgICAgICAgICAgICAqIElmIHRoZSB1c2VyIHdhbnRzIHRvIGtlZXAgaGVhZGluZ3Mgd2l0aCB0aGUgY29udGVudCBiZWxvdyBpdCB3ZSBhbHNvIG1ha2Ugc3VyZVxuICAgICAgICAgICAgICAgICAgICAgKiB0aGF0IHRoZSBsYXN0IGl0ZW0gaW4gYSBjb2x1bW4gaXMgbm90IGEgaGVhZGVyIGVsZW1lbnQgYnkgdXNpbmcgdGhlIGhlYWRlciBhbmRcbiAgICAgICAgICAgICAgICAgICAgICogdGhlIG5leHQgZWxlbWVudCdzIGhlaWdodCBhcyB0aGUgaGVpZ2h0IHZhbHVlLiBcbiAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgIGlmKGhhc0hlYWRlcihyZWdpb25FbGVtZW50c1tpXS5vcmlnaW5hbEVsZW1lbnQpID09PSB0cnVlKSB7IC8vIFRPRE86IEFkZCB0aGlzIGFzIHNlbGVjdGFibGUgb3B0aW9uLlxuICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGhlYWRlckFuZE5leHRFbGVtZW50SGVpZ2h0ID0gcmVnaW9uRWxlbWVudHNbaV0uZWxlbWVudFJlbmRlcmVkSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYoaSA8IHJlZ2lvbkVsZW1lbnRzLmxlbmd0aCAtIDEpIHtcbiAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJBbmROZXh0RWxlbWVudEhlaWdodCArPSByZWdpb25FbGVtZW50c1tpICsgMV0uZWxlbWVudFJlbmRlcmVkSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tTaG91bGRTd2l0Y2hDb2x1bW5zKGhlYWRlckFuZE5leHRFbGVtZW50SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrU2hvdWxkU3dpdGNoQ29sdW1ucyhyZWdpb25FbGVtZW50c1tpXS5lbGVtZW50UmVuZGVyZWRIZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDb2x1bW5IZWlnaHQgKz0gcmVnaW9uRWxlbWVudHNbaV0uZWxlbWVudFJlbmRlcmVkSGVpZ2h0XG4gICAgXG4gICAgXG4gICAgICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAgICAgKiBXZSBzdG9yZSB0aGUgZWxlbWVudHMgaW4gYSB3cmFwcGVyIGNvbnRhaW5lciB1bnRpbCB3ZSBkZXRlcm1pbmUgaWYgd2Ugd2FudCB0byBcbiAgICAgICAgICAgICAgICAgICAgICogdXNlIHRoZSBvcmlnaW5hbCBlbGVtZW50IG9yIGEgY2xvbmUgb2YgdGhlIGVsZW1lbnQuIFRoaXMgaGVscHMgdXMgYnkgYWxsb3dpbmcgXG4gICAgICAgICAgICAgICAgICAgICAqIHVzIHRvIGNyZWF0ZSBhIHZpc3VhbCBvbmx5IGNsb25lIHdoaWxlIHRoZSB1cGRhdGUgbG9vcCBtb3ZlcyB0aGUgb3JpZ2luYWwgZWxlbWVudCBcbiAgICAgICAgICAgICAgICAgICAgICogaW50byB0aGUgY29sdW1ucy5cbiAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgIGxldCBlbGVtZW50ID0gY3JlYXRlRGl2KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsczogTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29sdW1uRHVhbEVsZW1lbnRDb250YWluZXIsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICByZWdpb25FbGVtZW50c1tpXS5lbGVtZW50Q29udGFpbmVyID0gZWxlbWVudDtcbiAgICBcbiAgICAgICAgICAgICAgICAgICAgaWYoY29sdW1uT3ZlcmZsb3dTdGF0ZShjb2x1bW5JbmRleCwgc2V0dGluZ3MpID09PSBDb250ZW50T3ZlcmZsb3dUeXBlLmhpZGRlbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5Db250ZW50T3ZlcmZsb3dIaWRkZW5fWClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29udGVudE92ZXJmbG93QXV0b1Njcm9sbF9YKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBsZXQgYWxpZ25tZW50ID0gY29sdW1uQWxpZ25tZW50U3RhdGUoY29sdW1uSW5kZXgsIHNldHRpbmdzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYoYWxpZ25tZW50ID09PSBBbGlnbm1lbnRUeXBlLmNlbnRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5BbGlnbm1lbnRDZW50ZXIpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYWxpZ25tZW50ID09PSBBbGlnbm1lbnRUeXBlLnJpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFkZENsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLkFsaWdubWVudFJpZ2h0KVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5BbGlnbm1lbnRMZWZ0KVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IHRhYmxlQWxpZ25tZW50ID0gTUNNX1NldHRpbmdzTWFuYWdlci5zaGFyZWQuYWxpZ25UYWJsZXNUb0NvbnRlbnRBbGlnbm1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIGlmKHNldHRpbmdzLmFsaWduVGFibGVzVG9BbGlnbm1lbnQgIT09IFRhYmxlQWxpZ25tZW50LnVzZVNldHRpbmdzRGVmYXVsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVBbGlnbm1lbnQgPSBzZXR0aW5ncy5hbGlnblRhYmxlc1RvQWxpZ25tZW50ID09PSBUYWJsZUFsaWdubWVudC5hbGlnblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmKHRhYmxlQWxpZ25tZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFkZENsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLlRhYmxlQWxpZ25tZW50KVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGVsZW1lbnRUb0FwcGVuZDogSFRNTEVsZW1lbnQgPSByZWdpb25FbGVtZW50c1tpXS5vcmlnaW5hbEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIGlmKGlzTGl2ZVByZXZpZXcgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2xvbmVkRWxlbWVudCA9IHJlZ2lvbkVsZW1lbnRzW2ldLmNsb25lZEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZihyZWdpb25FbGVtZW50c1tpXS5jbG9uZWRFbGVtZW50ID09PSBudWxsKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZWRFbGVtZW50ID0gcmVnaW9uRWxlbWVudHNbaV0ub3JpZ2luYWxFbGVtZW50LmNsb25lTm9kZSh0cnVlKSBhcyBIVE1MRGl2RWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaGVhZGluZ0NvbGxhcHNlRWxlbWVudCA9IGdldEhlYWRpbmdDb2xsYXBzZUVsZW1lbnQoY2xvbmVkRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoaGVhZGluZ0NvbGxhcHNlRWxlbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHJlbW92ZXMgdGhlIGNvbGxhcHNlIGFycm93IGZyb20gdGhlIHZpZXcgaWYgaXQgZXhpc3RzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkaW5nQ29sbGFwc2VFbGVtZW50LmRldGFjaCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbkVsZW1lbnRzW2ldLmNsb25lZEVsZW1lbnQgPSBjbG9uZWRFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRUb0FwcGVuZCA9IGNsb25lZEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChlbGVtZW50VG9BcHBlbmQpO1xuICAgIFxuICAgICAgICAgICAgICAgICAgICBpZiAocmVnaW9uRWxlbWVudHNbaV0gaW5zdGFuY2VvZiBUYXNrTGlzdERPTU9iamVjdCkge1xuICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maXhDbG9uZWRDaGVja0xpc3RCdXR0b25zKHJlZ2lvbkVsZW1lbnRzW2ldIGFzIFRhc2tMaXN0RE9NT2JqZWN0LCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCAhPT0gbnVsbCAmJiBcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbkNvbnRlbnREaXZzW2NvbHVtbkluZGV4XSAmJiBcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbkVsZW1lbnRzW2ldLnRhZyAhPT0gRE9NT2JqZWN0VGFnLmNvbHVtbkJyZWFrKSB7XG4gICAgXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5Db250ZW50RGl2c1tjb2x1bW5JbmRleF0uYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWdpb25FbGVtZW50c1tpXS5lbGVtZW50UmVuZGVyZWRIZWlnaHQgPSBlbGVtZW50LmNsaWVudEhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgICAgICogSWYgdGhlIHRhZyBpcyBhIGNvbHVtbiBicmVhayB3ZSB1cGRhdGUgdGhlIGNvbHVtbiBpbmRleCBhZnRlclxuICAgICAgICAgICAgICAgICAgICAgKiBhcHBlbmRpbmcgdGhlIGl0ZW0gdG8gdGhlIGNvbHVtbiBkaXYuIFRoaXMga2VlcHMgdGhlIG1haW4gRE9NXG4gICAgICAgICAgICAgICAgICAgICAqIGNsZWFuZXIgYnkgcmVtb3Zpbmcgb3RoZXIgaXRlbXMgYW5kIHBsYWNpbmcgdGhlbSBhbGwgd2l0aGluXG4gICAgICAgICAgICAgICAgICAgICAqIGEgcmVnaW9uIGNvbnRhaW5lci5cbiAgICAgICAgICAgICAgICAgICAgICogXG4gICAgICAgICAgICAgICAgICAgICAqIFJlbW92aW5nIHRoZSBlbmQgY29sdW1uIHRhZyBhcyBhbiBvcHRpb24gZm9yIG5vdy5cbiAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIChyZWdpb25FbGVtZW50c1tpXS50YWcgPT09IERPTU9iamVjdFRhZy5jb2x1bW5CcmVhayAmJlxuICAgICAgICAgICAgICAgICAgICAvLyAgICAoY29sdW1uSW5kZXggKyAxKSA8IHNldHRpbmdzLm51bWJlck9mQ29sdW1ucykge1xuICAgIFxuICAgICAgICAgICAgICAgICAgICAvLyAgICAgY29sdW1uSW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIGN1cnJlbnRDb2x1bW5IZWlnaHQgPSAwO1xuICAgICAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dGVtcHQgdG8gYmFsYW5jZWQgdGhlIGVsZW1lbnRzLiBXZSBuZWVkIHRvIGl0ZXJhdGUgb3ZlciB0aGUgZWxlbWVudHMgbXVsdGlwbGUgdGltZXMgYmVjYXVzZVxuICAgICAgICAgKiBvdXIgaW5pdGlhbCBiYWxhbmNlIGVzdGltYXRlIG1heSBub3QgYmUgcGVyZmVjdGx5IGJhbGFuY2VkIGR1ZSB0byBkaWZmZXJlbnQgY29sdW1uIHdpZHRocyBjYXVzaW5nIFxuICAgICAgICAgKiBlbGVtZW50cyB3aXRoaW4gdGhlbSB0byBiZSBvZiBkaWZmZXJlbnQgaGVpZ2h0cy4gVGhpcyBjYW4gY2F1c2UgdGhlIGVsZW1lbnRzIHRvIGp1bXAgYXJvdW5kIG9uIFxuICAgICAgICAgKiBzdWJzaXF1ZW50IHVwZGF0ZSBsb29wcyB3aGljaCBpcyBub3QgaWRlYWwuIEhlcmUgd2UgcmVuZGVyIHRoZSBlbGVtZW50cyB0byB0aGUgc2NyZWVuIGFuZCB1cGRhdGUgXG4gICAgICAgICAqIHRoZWlyIGhlaWdodCBhZnRlciBiZWluZyByZW5kZXJlZCBpbnRvIHRoZSBlc3RpbWF0ZWQgcG9zaXRpb24uIFxuICAgICAgICAgKiBcbiAgICAgICAgICogT25jZSBldmVyeXRoaW5nIGlzIHJlbmRlcmVkIHdlIGNoZWNrIGFsbCBvZiB0aGUgY29sdW1uIGhlaWdodHMgYWdhaW5zdCBvdXIgbGFzdCBpdGVyYXRpb24gYW5kIFxuICAgICAgICAgKiBpZiBub3RoaW5nIGhhcyBjaGFuZ2VkIHdlIGtub3cgd2UgYXJlIGJhbGFuY2VkLlxuICAgICAgICAgKiBcbiAgICAgICAgICogVGhlcmUgaXMgcHJvYmFibHkgYSBiZXR0ZXIgd2F5IG9mIGFjY29tcGxpc2hpbmcgdGhpcyB0YXNrIGJ1dCB0aGlzIHdvcmtzIGZvciB0aGUgdGltZSBiZWluZy5cbiAgICAgICAgICovXG5cbiAgICAgICAgbGV0IGF1dG9MYXlvdXRCYWxhbmNlSXRlcmF0aW9ucyA9IDE7XG4gICAgICAgIGlmKHRoaXMuaXNMaXZlUHJldmlldyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGF1dG9MYXlvdXRCYWxhbmNlSXRlcmF0aW9ucyA9IE1DTV9TZXR0aW5nc01hbmFnZXIuc2hhcmVkLmF1dG9MYXlvdXRCYWxhbmNlSXRlcmF0aW9uc1xuICAgICAgICB9XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBhdXRvTGF5b3V0QmFsYW5jZUl0ZXJhdGlvbnM7IGkrKykge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBiYWxhbmNlRWxlbWVudHMoKVxuXG4gICAgICAgICAgICBsZXQgYmFsYW5jZWQgPSB0cnVlO1xuICAgICAgICAgICAgZm9yKGxldCBqID0gMDsgaiA8IGNvbHVtbkNvbnRlbnREaXZzLmxlbmd0aDsgaisrKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgY29sdW1uIGhlaWdodHMgYXJlIHVuZGVmaW5lZCB3ZSBzZXQgZGVmYXVsdCB0byB6ZXJvIHNvIG5vdCB0byBlbmNvdW50ZXIgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgaWYoIXRoaXMucHJldmlvdXNDb2x1bW5IZWlnaHRzW2pdKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNDb2x1bW5IZWlnaHRzLnB1c2goMClcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIHJlbmRlciBoZWlnaHQgaXMgbm90IHRoZSBzYW1lIGFzIHRoZSBwcmV2aW91cyBoZWlnaHQgd2UgYXJlIHN0aWxsIGJhbGFuY2luZy5cbiAgICAgICAgICAgICAgICBpZih0aGlzLnByZXZpb3VzQ29sdW1uSGVpZ2h0c1tqXSAhPT0gY29sdW1uQ29udGVudERpdnNbal0uY2xpZW50SGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNDb2x1bW5IZWlnaHRzW2pdID0gY29sdW1uQ29udGVudERpdnNbal0uY2xpZW50SGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgIGJhbGFuY2VkID0gZmFsc2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHdlIG1hZGUgaXQgb3V0IG9mIHRoZSBsb29wIGFuZCBhbGwgb2YgdGhlIGNvbHVtbnMgYXJlIHRoZSBzYW1lIGhlaWdodCBhcyBsYXN0IHVwZGF0ZVxuICAgICAgICAgICAgLy8gd2UncmUgYmFsYW5jZWQgc28gd2UgY2FuIGJyZWFrIG91dCBvZiB0aGUgbG9vcC5cbiAgICAgICAgICAgIGlmKGJhbGFuY2VkID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlUmVuZGVyZWRNYXJrZG93bigpIHtcblxuICAgICAgICBpZih0aGlzLmRvY1JlZmxvdyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgc3VwZXIudXBkYXRlUmVuZGVyZWRNYXJrZG93bigpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmRvbUxpc3QubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgbGV0IGVsID0gdGhpcy5kb21MaXN0W2ldXG4gICAgICAgICAgICBsZXQgb3JpZ2luYWxDbGllbnRIZWlnaHQgPSAwO1xuICAgICAgICAgICAgaWYgKGVsLm9yaWdpbmFsRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIG9yaWdpbmFsQ2xpZW50SGVpZ2h0ID0gZWwub3JpZ2luYWxFbGVtZW50LmNsaWVudEhlaWdodFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGNsb25lZENsaWVudEhlaWdodCA9IDA7XG4gICAgICAgICAgICBpZiAoZWwuY2xvbmVkRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGNsb25lZENsaWVudEhlaWdodCA9IGVsLmNsb25lZEVsZW1lbnQuY2xpZW50SGVpZ2h0XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChvcmlnaW5hbENsaWVudEhlaWdodCA8IGNsb25lZENsaWVudEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZG9tTGlzdFtpXS5lbGVtZW50UmVuZGVyZWRIZWlnaHQgPSBjbG9uZWRDbGllbnRIZWlnaHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRvbUxpc3RbaV0uZWxlbWVudFJlbmRlcmVkSGVpZ2h0ID0gb3JpZ2luYWxDbGllbnRIZWlnaHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmFsaWRDb2x1bW5zID0gdHJ1ZTtcbiAgICAgICAgaWYodGhpcy5jb2x1bW5QYXJlbnQgIT09IG51bGwgJiYgdGhpcy5jb2x1bW5EaXZzICE9PSBudWxsICYmIHRoaXMuY29sdW1uRGl2cyAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICB0aGlzLmNvbHVtbkRpdnMubGVuZ3RoID09PSB0aGlzLnJlZ2lvbmFsU2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zKSB7XG5cbiAgICAgICAgICAgIGxldCB0b3RhbEhlaWdodCA9IHRoaXMuZG9tTGlzdC5tYXAoKGVsOiBET01PYmplY3QsIGluZGV4OiBudW1iZXIpID0+IHsgXG5cbiAgICAgICAgICAgICAgICAvLyBXZSBvbmx5IHdhbnQgdG8gYXR0ZW1wdCB0byB1cGRhdGUgdGhlIGVsZW1lbnRSZW5kZXJlZEhlaWdodCBpZiBpdCBpcyAwIGFuZCBpZiBpdCBpcyBub3QgYW4gdW5yZW5kZXJlZCBlbGVtZW50IHN1Y2ggYXMgYSBlbmRyZWdpb24gdGFnLlxuICAgICAgICAgICAgICAgIGlmKGVsLmVsZW1lbnRSZW5kZXJlZEhlaWdodCA9PT0gMCAmJlxuICAgICAgICAgICAgICAgICAgICBlbC50YWcgIT09IERPTU9iamVjdFRhZy5jb2x1bW5CcmVhayAmJlxuICAgICAgICAgICAgICAgICAgICBlbC50YWcgIT09IERPTU9iamVjdFRhZy5lbmRSZWdpb24gJiZcbiAgICAgICAgICAgICAgICAgICAgZWwudGFnICE9PSBET01PYmplY3RUYWcucmVnaW9uU2V0dGluZ3MgJiZcbiAgICAgICAgICAgICAgICAgICAgZWwudGFnICE9PSBET01PYmplY3RUYWcuc3RhcnRSZWdpb24pIHtcbiAgICBcbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGVsZW1lbnQgdG8gcmVuZGVyZWQgZGl2IHNvIHdlIGNhbiBleHRyYWN0IHRoZSByZW5kZXJlZCBoZWlnaHQuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uUGFyZW50LmFwcGVuZENoaWxkKGVsLm9yaWdpbmFsRWxlbWVudClcbiAgICAgICAgICAgICAgICAgICAgZWwuZWxlbWVudFJlbmRlcmVkSGVpZ2h0ID0gZWwub3JpZ2luYWxFbGVtZW50LmNsaWVudEhlaWdodFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbHVtblBhcmVudC5yZW1vdmVDaGlsZChlbC5vcmlnaW5hbEVsZW1lbnQpXG4gICAgICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgICAgIHJldHVybiBlbC5lbGVtZW50UmVuZGVyZWRIZWlnaHQgXG4gICAgICAgICAgICB9KS5yZWR1Y2UoKHByZXY6IG51bWJlciwgY3VycjogbnVtYmVyKSA9PiB7IHJldHVybiBwcmV2ICsgY3VyciB9LCAwKTtcbiAgICAgICAgICAgIGxldCBtYXhDb2x1bW5Db250ZW50SGVpZ2h0ID0gTWF0aC50cnVuYyh0b3RhbEhlaWdodCAvIHRoaXMucmVnaW9uYWxTZXR0aW5ncy5udW1iZXJPZkNvbHVtbnMpO1xuXG4gICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy5jb2x1bW5EaXZzLmxlbmd0aCAtIDE7IGkrKykge1xuXG4gICAgICAgICAgICAgICAgbGV0IGNvbHVtbkhlaWdodCA9IDBcbiAgICAgICAgICAgICAgICBmb3IobGV0IGogPSAwOyBqIDwgdGhpcy5jb2x1bW5EaXZzW2ldLmNoaWxkcmVuLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbkhlaWdodCArPSB0aGlzLmNvbHVtbkRpdnNbaV0uY2hpbGRyZW5bal0uY2xpZW50SGVpZ2h0XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYoY29sdW1uSGVpZ2h0ID4gbWF4Q29sdW1uQ29udGVudEhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICB2YWxpZENvbHVtbnMgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYodmFsaWRDb2x1bW5zID09PSBmYWxzZSkge1xuXG4gICAgICAgICAgICB0aGlzLnJlbmRlckNvbHVtbk1hcmtkb3duKHRoaXMucmVnaW9uUGFyZW50LCB0aGlzLmRvbUxpc3QsIHRoaXMucmVnaW9uYWxTZXR0aW5ncyk7XG4gICAgICAgIH1cblxuICAgICAgICBzdXBlci51cGRhdGVSZW5kZXJlZE1hcmtkb3duKCk7XG4gICAgfVxufVxuXG4iLCIvKipcbiAqIEZpbGU6IC9zcmMvZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvcmVmbG93UmVnaW9uTWFuYWdlci50cyAgICAgICAgICAgICAqXG4gKiBDcmVhdGVkIERhdGU6IFRodXJzZGF5LCBNYXkgMTF0aCAyMDIzLCA5OjU5IHBtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogQXV0aG9yOiBDYW1lcm9uIFJvYmluc29uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjMgQ2FtZXJvbiBSb2JpbnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICovXG5cbmltcG9ydCB7IERPTU9iamVjdCwgRE9NT2JqZWN0VGFnLCBUYXNrTGlzdERPTU9iamVjdCB9IGZyb20gJy4uL2RvbU9iamVjdCc7XG5pbXBvcnQgeyBBbGlnbm1lbnRUeXBlLCBDb250ZW50T3ZlcmZsb3dUeXBlLCBNdWx0aUNvbHVtblNldHRpbmdzLCBUYWJsZUFsaWdubWVudCwgY29sdW1uQWxpZ25tZW50U3RhdGUsIGNvbHVtbk92ZXJmbG93U3RhdGUsIHNob3VsZERyYXdDb2x1bW5Cb3JkZXIgfSBmcm9tIFwiLi4vLi4vcmVnaW9uU2V0dGluZ3NcIjtcbmltcG9ydCB7IE11bHRpQ29sdW1uTGF5b3V0Q1NTLCBNdWx0aUNvbHVtblN0eWxlQ1NTIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2Nzc0RlZmluaXRpb25zJztcbmltcG9ydCB7IFJlZ2lvbk1hbmFnZXIgfSBmcm9tICcuL3JlZ2lvbk1hbmFnZXInO1xuaW1wb3J0IHsgZ2V0SGVhZGluZ0NvbGxhcHNlRWxlbWVudCwgaGFzSGVhZGVyIH0gZnJvbSAnc3JjL3V0aWxpdGllcy9lbGVtZW50UmVuZGVyVHlwZVBhcnNlcic7XG5pbXBvcnQgeyBNQ01fU2V0dGluZ3NNYW5hZ2VyIH0gZnJvbSAnc3JjL3BsdWdpblNldHRpbmdzJztcblxuZXhwb3J0IGNsYXNzIFJlZmxvd1JlZ2lvbk1hbmFnZXIgZXh0ZW5kcyBSZWdpb25NYW5hZ2VyIHtcblxuICAgIHB1YmxpYyByZW5kZXJSZWdpb25FbGVtZW50c1RvU2NyZWVuKCk6IHZvaWQge1xuXG4gICAgICAgICB0aGlzLnJlbmRlckNvbHVtbk1hcmtkb3duKHRoaXMucmVnaW9uUGFyZW50LCB0aGlzLmRvbUxpc3QsIHRoaXMucmVnaW9uYWxTZXR0aW5ncyk7XG4gICAgfVxuICAgIHB1YmxpYyBleHBvcnRSZWdpb25FbGVtZW50c1RvUERGKHBkZlBhcmVudEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XG5cbiAgICAgICAgLy8gRGVmYXVsdCBzZXQgc2hhZG93IHRvIG9mZiBmb3IgZXhwb3J0aW5nIFBERnNcbiAgICAgICAgbGV0IHJlbmRlclNldHRpbmdzID0gdGhpcy5yZWdpb25hbFNldHRpbmdzO1xuICAgICAgICByZW5kZXJTZXR0aW5ncy5kcmF3U2hhZG93ID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVuZGVyQ29sdW1uTWFya2Rvd24ocGRmUGFyZW50RWxlbWVudCwgdGhpcy5kb21MaXN0LnNsaWNlKCksIHJlbmRlclNldHRpbmdzKTtcbiAgICB9XG4gICAgcHVibGljIHJlbmRlclJlZ2lvbkVsZW1lbnRzVG9MaXZlUHJldmlldyhwYXJlbnRFbGVtZW50OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuXG4gICAgICAgIHRoaXMucmVuZGVyQ29sdW1uTWFya2Rvd24ocGFyZW50RWxlbWVudCwgdGhpcy5kb21MaXN0LCB0aGlzLnJlZ2lvbmFsU2V0dGluZ3MpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIHRha2VzIGluIHRoZSBkYXRhIGZvciB0aGUgbXVsdGktY29sdW1uIHJlZ2lvbiBhbmQgc2V0cyB1cCB0aGUgXG4gICAgICogdXNlciBkZWZpbmVkIG51bWJlciBvZiBjaGlsZHJlbiB3aXRoIHRoZSBwcm9wZXIgY3NzIGNsYXNzZXMgdG8gYmUgcmVuZGVyZWQgcHJvcGVybHkuXG4gICAgICogXG4gICAgICogQHBhcmFtIHBhcmVudEVsZW1lbnQgVGhlIGVsZW1lbnQgdGhhdCB0aGUgbXVsdGktY29sdW1uIHJlZ2lvbiB3aWxsIGJlIHJlbmRlcmVkIHVuZGVyLlxuICAgICAqIEBwYXJhbSByZWdpb25FbGVtZW50cyBUaGUgbGlzdCBvZiBET00gb2JqZWN0cyB0aGF0IHdpbGwgYmUgY29wcGllZCB1bmRlciB0aGUgcGFyZW50IG9iamVjdFxuICAgICAqIEBwYXJhbSBzZXR0aW5ncyBUaGUgc2V0dGluZ3MgdGhlIHVzZXIgaGFzIGRlZmluZWQgZm9yIHRoZSByZWdpb24uXG4gICAgICovXG4gICAgcHJpdmF0ZSByZW5kZXJDb2x1bW5NYXJrZG93bihwYXJlbnRFbGVtZW50OiBIVE1MRWxlbWVudCwgcmVnaW9uRWxlbWVudHM6IERPTU9iamVjdFtdLCBzZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncykge1xuXG4gICAgICAgIGxldCB2ZXJ0aWNhbENvbHVtblBhcmVudCA9IGNyZWF0ZURpdih7XG4gICAgICAgICAgICBjbHM6IGBgXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQYXNzIG91ciBwYXJlbnQgZGl2IGFuZCBzZXR0aW5ncyB0byBwYXJzZXIgdG8gY3JlYXRlIHRoZSByZXF1aXJlZFxuICAgICAgICAgKiBjb2x1bW4gZGl2cyBhcyBjaGlsZHJlbiBvZiB0aGUgcGFyZW50LlxuICAgICAgICAgKi9cblxuICAgICAgICAvLyBSZW1vdmUgZXZlcnkgb3RoZXIgY2hpbGQgZnJvbSB0aGUgcGFyZW50IHNvIFxuICAgICAgICAvLyB3ZSBkb250IGVuZCB1cCB3aXRoIG11bHRpcGxlIHNldHMgb2YgZGF0YS4gVGhpcyBzaG91bGRcbiAgICAgICAgLy8gcmVhbGx5IG9ubHkgbmVlZCB0byBsb29wIG9uY2UgZm9yIGkgPSAwIGJ1dCBsb29wIGp1c3RcbiAgICAgICAgLy8gaW4gY2FzZS5cbiAgICAgICAgZm9yIChsZXQgaSA9IHBhcmVudEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIHBhcmVudEVsZW1lbnQuY2hpbGRyZW5baV0uZGV0YWNoKCk7XG4gICAgICAgIH1cbiAgICAgICAgcGFyZW50RWxlbWVudC5hcHBlbmRDaGlsZCh2ZXJ0aWNhbENvbHVtblBhcmVudCk7XG5cbiAgICAgICAgdGhpcy5hcHBlbmRFbGVtZW50c1RvQ29sdW1ucyh2ZXJ0aWNhbENvbHVtblBhcmVudCwgcmVnaW9uRWxlbWVudHMsIHNldHRpbmdzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFwcGVuZEVsZW1lbnRzVG9Db2x1bW5zKHZlcnRpY2FsQ29sdW1uUGFyZW50OiBIVE1MRGl2RWxlbWVudCwgcmVnaW9uRWxlbWVudHM6IERPTU9iamVjdFtdLCBzZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncykge1xuXG4gICAgICAgIHRoaXMuZG9tTGlzdC5mb3JFYWNoKChlbDogRE9NT2JqZWN0LCBpbmRleDogbnVtYmVyKSA9PiB7IFxuXG4gICAgICAgICAgICAvLyBXZSBvbmx5IHdhbnQgdG8gYXR0ZW1wdCB0byB1cGRhdGUgdGhlIGVsZW1lbnRSZW5kZXJlZEhlaWdodCBpZiBpdCBpcyAwIGFuZCBpZiBpdCBpcyBub3QgYW4gdW5yZW5kZXJlZCBlbGVtZW50IHN1Y2ggYXMgYSBlbmRyZWdpb24gdGFnLlxuICAgICAgICAgICAgaWYoZWwuZWxlbWVudFJlbmRlcmVkSGVpZ2h0ID09PSAwICYmXG4gICAgICAgICAgICAgICAgZWwudGFnICE9PSBET01PYmplY3RUYWcuY29sdW1uQnJlYWsgJiZcbiAgICAgICAgICAgICAgICBlbC50YWcgIT09IERPTU9iamVjdFRhZy5lbmRSZWdpb24gJiZcbiAgICAgICAgICAgICAgICBlbC50YWcgIT09IERPTU9iamVjdFRhZy5yZWdpb25TZXR0aW5ncyAmJlxuICAgICAgICAgICAgICAgIGVsLnRhZyAhPT0gRE9NT2JqZWN0VGFnLnN0YXJ0UmVnaW9uKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBBZGQgZWxlbWVudCB0byByZW5kZXJlZCBkaXYgc28gd2UgY2FuIGV4dHJhY3QgdGhlIHJlbmRlcmVkIGhlaWdodC5cbiAgICAgICAgICAgICAgICB2ZXJ0aWNhbENvbHVtblBhcmVudC5hcHBlbmRDaGlsZChlbC5vcmlnaW5hbEVsZW1lbnQpXG4gICAgICAgICAgICAgICAgZWwuZWxlbWVudFJlbmRlcmVkSGVpZ2h0ID0gZWwub3JpZ2luYWxFbGVtZW50LmNsaWVudEhlaWdodFxuICAgICAgICAgICAgICAgIHZlcnRpY2FsQ29sdW1uUGFyZW50LnJlbW92ZUNoaWxkKGVsLm9yaWdpbmFsRWxlbWVudClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICBsZXQgbWF4Q29sdW1uQ29udGVudEhlaWdodCA9IHNldHRpbmdzLmNvbHVtbkhlaWdodC5zaXplVmFsdWVcblxuICAgICAgICBsZXQgY29sdW1uSW5kZXggPSAwO1xuICAgICAgICBsZXQgY3VycmVudENvbHVtbkhlaWdodCA9IDA7XG4gICAgICAgIGxldCBkaXZDb3VudCA9IDE7XG4gICAgICAgIGxldCBjb2xEaXZzQ2FsbGJhY2sgPSAoc2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MsIG11bHRpQ29sdW1uUGFyZW50OiBIVE1MRGl2RWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q29sdW1uQ29udGVudERpdnMoc2V0dGluZ3MsIG11bHRpQ29sdW1uUGFyZW50KTtcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGNvbHVtbnMgPSBnZXRGb3JtYXR0ZWRDb2x1bW5EaXZzKHNldHRpbmdzLCB2ZXJ0aWNhbENvbHVtblBhcmVudCwgY29sRGl2c0NhbGxiYWNrLCBkaXZDb3VudCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVnaW9uRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgaWYgKHJlZ2lvbkVsZW1lbnRzW2ldLnRhZyA9PT0gRE9NT2JqZWN0VGFnLm5vbmUgfHxcbiAgICAgICAgICAgICAgICByZWdpb25FbGVtZW50c1tpXS50YWcgPT09IERPTU9iamVjdFRhZy5jb2x1bW5CcmVhaykge1xuXG4gICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICogSGVyZSB3ZSBjaGVjayBpZiB3ZSBuZWVkIHRvIHN3YXAgdG8gdGhlIG5leHQgY29sdW1uIGZvciB0aGUgY3VycmVudCBlbGVtZW50LlxuICAgICAgICAgICAgICAgICAqIElmIHRoZSB1c2VyIHdhbnRzIHRvIGtlZXAgaGVhZGluZ3Mgd2l0aCB0aGUgY29udGVudCBiZWxvdyBpdCB3ZSBhbHNvIG1ha2Ugc3VyZVxuICAgICAgICAgICAgICAgICAqIHRoYXQgdGhlIGxhc3QgaXRlbSBpbiBhIGNvbHVtbiBpcyBub3QgYSBoZWFkZXIgZWxlbWVudCBieSB1c2luZyB0aGUgaGVhZGVyIGFuZFxuICAgICAgICAgICAgICAgICAqIHRoZSBuZXh0IGVsZW1lbnQncyBoZWlnaHQgYXMgdGhlIGhlaWdodCB2YWx1ZS4gXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgaWYoaGFzSGVhZGVyKHJlZ2lvbkVsZW1lbnRzW2ldLm9yaWdpbmFsRWxlbWVudCkgPT09IHRydWUpIHsgLy8gVE9ETzogQWRkIHRoaXMgYXMgc2VsZWN0YWJsZSBvcHRpb24uXG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGhlYWRlckFuZE5leHRFbGVtZW50SGVpZ2h0ID0gcmVnaW9uRWxlbWVudHNbaV0uZWxlbWVudFJlbmRlcmVkSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICBpZihpIDwgcmVnaW9uRWxlbWVudHMubGVuZ3RoIC0gMSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJBbmROZXh0RWxlbWVudEhlaWdodCArPSByZWdpb25FbGVtZW50c1tpICsgMV0uZWxlbWVudFJlbmRlcmVkSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2hlY2tTaG91bGRTd2l0Y2hDb2x1bW5zKGhlYWRlckFuZE5leHRFbGVtZW50SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY2hlY2tTaG91bGRTd2l0Y2hDb2x1bW5zKHJlZ2lvbkVsZW1lbnRzW2ldLmVsZW1lbnRSZW5kZXJlZEhlaWdodCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGN1cnJlbnRDb2x1bW5IZWlnaHQgKz0gcmVnaW9uRWxlbWVudHNbaV0uZWxlbWVudFJlbmRlcmVkSGVpZ2h0XG5cbiAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgKiBXZSBzdG9yZSB0aGUgZWxlbWVudHMgaW4gYSB3cmFwcGVyIGNvbnRhaW5lciB1bnRpbCB3ZSBkZXRlcm1pbmUgaWYgd2Ugd2FudCB0byBcbiAgICAgICAgICAgICAgICAgKiB1c2UgdGhlIG9yaWdpbmFsIGVsZW1lbnQgb3IgYSBjbG9uZSBvZiB0aGUgZWxlbWVudC4gVGhpcyBoZWxwcyB1cyBieSBhbGxvd2luZyBcbiAgICAgICAgICAgICAgICAgKiB1cyB0byBjcmVhdGUgYSB2aXN1YWwgb25seSBjbG9uZSB3aGlsZSB0aGUgdXBkYXRlIGxvb3AgbW92ZXMgdGhlIG9yaWdpbmFsIGVsZW1lbnQgXG4gICAgICAgICAgICAgICAgICogaW50byB0aGUgY29sdW1ucy5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudCA9IGNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgICAgIGNsczogTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29sdW1uRHVhbEVsZW1lbnRDb250YWluZXIsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmVnaW9uRWxlbWVudHNbaV0uZWxlbWVudENvbnRhaW5lciA9IGVsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZihjb2x1bW5PdmVyZmxvd1N0YXRlKGNvbHVtbkluZGV4LCBzZXR0aW5ncykgPT09IENvbnRlbnRPdmVyZmxvd1R5cGUuaGlkZGVuKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29udGVudE92ZXJmbG93SGlkZGVuX1gpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFkZENsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLkNvbnRlbnRPdmVyZmxvd0F1dG9TY3JvbGxfWClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgbGV0IGFsaWdubWVudCA9IGNvbHVtbkFsaWdubWVudFN0YXRlKGNvbHVtbkluZGV4LCBzZXR0aW5ncyk7XG4gICAgICAgICAgICAgICAgaWYoYWxpZ25tZW50ID09PSBBbGlnbm1lbnRUeXBlLmNlbnRlcikge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFkZENsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLkFsaWdubWVudENlbnRlcilcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYWxpZ25tZW50ID09PSBBbGlnbm1lbnRUeXBlLnJpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5MYXlvdXRDU1MuQWxpZ25tZW50UmlnaHQpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFkZENsYXNzKE11bHRpQ29sdW1uTGF5b3V0Q1NTLkFsaWdubWVudExlZnQpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IHRhYmxlQWxpZ25tZW50ID0gTUNNX1NldHRpbmdzTWFuYWdlci5zaGFyZWQuYWxpZ25UYWJsZXNUb0NvbnRlbnRBbGlnbm1lbnQ7XG4gICAgICAgICAgICAgICAgaWYoc2V0dGluZ3MuYWxpZ25UYWJsZXNUb0FsaWdubWVudCAhPT0gVGFibGVBbGlnbm1lbnQudXNlU2V0dGluZ3NEZWZhdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRhYmxlQWxpZ25tZW50ID0gc2V0dGluZ3MuYWxpZ25UYWJsZXNUb0FsaWdubWVudCA9PT0gVGFibGVBbGlnbm1lbnQuYWxpZ25cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYodGFibGVBbGlnbm1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRDbGFzcyhNdWx0aUNvbHVtbkxheW91dENTUy5UYWJsZUFsaWdubWVudClcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgY2xvbmVkRWxlbWVudCA9IHJlZ2lvbkVsZW1lbnRzW2ldLmNsb25lZEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgaWYocmVnaW9uRWxlbWVudHNbaV0uY2xvbmVkRWxlbWVudCA9PT0gbnVsbCkge1xuXG4gICAgICAgICAgICAgICAgICAgIGNsb25lZEVsZW1lbnQgPSByZWdpb25FbGVtZW50c1tpXS5vcmlnaW5hbEVsZW1lbnQuY2xvbmVOb2RlKHRydWUpIGFzIEhUTUxEaXZFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICBsZXQgaGVhZGluZ0NvbGxhcHNlRWxlbWVudCA9IGdldEhlYWRpbmdDb2xsYXBzZUVsZW1lbnQoY2xvbmVkRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgIGlmKGhlYWRpbmdDb2xsYXBzZUVsZW1lbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgcmVtb3ZlcyB0aGUgY29sbGFwc2UgYXJyb3cgZnJvbSB0aGUgdmlldyBpZiBpdCBleGlzdHMuXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkaW5nQ29sbGFwc2VFbGVtZW50LmRldGFjaCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICAgICAgICAgIHJlZ2lvbkVsZW1lbnRzW2ldLmNsb25lZEVsZW1lbnQgPSBjbG9uZWRFbGVtZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKGNsb25lZEVsZW1lbnQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlZ2lvbkVsZW1lbnRzW2ldIGluc3RhbmNlb2YgVGFza0xpc3RET01PYmplY3QpIHtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpeENsb25lZENoZWNrTGlzdEJ1dHRvbnMocmVnaW9uRWxlbWVudHNbaV0gYXMgVGFza0xpc3RET01PYmplY3QsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ICE9PSBudWxsICYmIFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5zW2NvbHVtbkluZGV4XSAmJiBcbiAgICAgICAgICAgICAgICAgICAgcmVnaW9uRWxlbWVudHNbaV0udGFnICE9PSBET01PYmplY3RUYWcuY29sdW1uQnJlYWspIHtcblxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5zW2NvbHVtbkluZGV4XS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgcmVnaW9uRWxlbWVudHNbaV0uZWxlbWVudFJlbmRlcmVkSGVpZ2h0ID0gZWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICogSWYgdGhlIHRhZyBpcyBhIGNvbHVtbiBicmVhayB3ZSB1cGRhdGUgdGhlIGNvbHVtbiBpbmRleCBhZnRlclxuICAgICAgICAgICAgICAgICAqIGFwcGVuZGluZyB0aGUgaXRlbSB0byB0aGUgY29sdW1uIGRpdi4gVGhpcyBrZWVwcyB0aGUgbWFpbiBET01cbiAgICAgICAgICAgICAgICAgKiBjbGVhbmVyIGJ5IHJlbW92aW5nIG90aGVyIGl0ZW1zIGFuZCBwbGFjaW5nIHRoZW0gYWxsIHdpdGhpblxuICAgICAgICAgICAgICAgICAqIGEgcmVnaW9uIGNvbnRhaW5lci5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBpZiAocmVnaW9uRWxlbWVudHNbaV0udGFnID09PSBET01PYmplY3RUYWcuY29sdW1uQnJlYWspIHtcblxuICAgICAgICAgICAgICAgICAgICBjaGVja0NyZWF0ZU5ld0NvbHVtbnMoKTtcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uSW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudENvbHVtbkhlaWdodCA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gY2hlY2tTaG91bGRTd2l0Y2hDb2x1bW5zKG5leHRFbGVtZW50SGVpZ2h0OiBudW1iZXIpIHtcblxuICAgICAgICAgICAgaWYgKGN1cnJlbnRDb2x1bW5IZWlnaHQgKyBuZXh0RWxlbWVudEhlaWdodCA8IG1heENvbHVtbkNvbnRlbnRIZWlnaHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNoZWNrQ3JlYXRlTmV3Q29sdW1ucygpO1xuICAgICAgICAgICAgY29sdW1uSW5kZXgrKztcbiAgICAgICAgICAgIGN1cnJlbnRDb2x1bW5IZWlnaHQgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gY2hlY2tDcmVhdGVOZXdDb2x1bW5zKCkge1xuICAgICAgICAgICAgaWYgKChjb2x1bW5JbmRleCArIDEpID49IGNvbHVtbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgZGl2Q291bnQrKztcbiAgICAgICAgICAgICAgICBjb2x1bW5zID0gY29sdW1ucy5jb25jYXQoZ2V0Rm9ybWF0dGVkQ29sdW1uRGl2cyhzZXR0aW5ncywgdmVydGljYWxDb2x1bW5QYXJlbnQsIGNvbERpdnNDYWxsYmFjaywgZGl2Q291bnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkQ29sdW1uRGl2cyhcbiAgICBzZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncywgXG4gICAgdmVydGljYWxDb2x1bW5QYXJlbnQ6IEhUTUxEaXZFbGVtZW50LCBcbiAgICBnZXRDb2x1bW5Db250ZW50RGl2czogKHNldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzLCBtdWx0aUNvbHVtblBhcmVudDogSFRNTERpdkVsZW1lbnQpID0+IEhUTUxEaXZFbGVtZW50W10sXG4gICAgZGl2Q291bnQ6IG51bWJlcikge1xuICAgICAgICBcbiAgICBsZXQgbXVsdGlDb2x1bW5QYXJlbnQgPSB2ZXJ0aWNhbENvbHVtblBhcmVudC5jcmVhdGVEaXYoe1xuICAgICAgICBjbHM6IGAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlJlZ2lvbkNvbHVtbkNvbnRhaW5lckRpdn0gXFxcbiAgICAgICAgICAgICAgJHtNdWx0aUNvbHVtbkxheW91dENTUy5Db250ZW50T3ZlcmZsb3dBdXRvU2Nyb2xsX1h9IFxcXG4gICAgICAgICAgICAgICR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuQ29udGVudE92ZXJmbG93SGlkZGVuX1l9O1xuICAgICAgICAgICAgICBgXG4gICAgfSk7XG4gICAgaWYoZGl2Q291bnQgPiAxKSB7XG4gICAgICAgIG11bHRpQ29sdW1uUGFyZW50LmFkZENsYXNzKGAke011bHRpQ29sdW1uTGF5b3V0Q1NTLlJlZmxvd0NvbnRhaW5lckRpdn1gKTtcbiAgICB9XG5cbiAgICBsZXQgY29sdW1uRGl2cyA9IGdldENvbHVtbkNvbnRlbnREaXZzKHNldHRpbmdzLCBtdWx0aUNvbHVtblBhcmVudCk7XG4gICAgaWYgKHNldHRpbmdzLmRyYXdTaGFkb3cgPT09IHRydWUpIHtcbiAgICAgICAgbXVsdGlDb2x1bW5QYXJlbnQuYWRkQ2xhc3MoTXVsdGlDb2x1bW5TdHlsZUNTUy5SZWdpb25TaGFkb3cpO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbHVtbkRpdnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHNob3VsZERyYXdDb2x1bW5Cb3JkZXIoaSwgc2V0dGluZ3MpID09PSB0cnVlKSB7XG4gICAgICAgICAgICBjb2x1bW5EaXZzW2ldLmFkZENsYXNzKE11bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uQm9yZGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZXR0aW5ncy5kcmF3U2hhZG93ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBjb2x1bW5EaXZzW2ldLmFkZENsYXNzKE11bHRpQ29sdW1uU3R5bGVDU1MuQ29sdW1uU2hhZG93KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb2x1bW5EaXZzXG59IiwiLyoqXG4gKiBGaWxlOiAvc3JjL2RvbV9tYW5hZ2VyL3JlZ2lvbmFsX21hbmFnZXJzL3JlZ2lvbk1hbmFnZXJDb250YWluZXIudHMgICAgICAgICAgKlxuICogQ3JlYXRlZCBEYXRlOiBTdW5kYXksIE1heSAyMm5kIDIwMjIsIDc6NTAgcG0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqIEF1dGhvcjogQ2FtZXJvbiBSb2JpbnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogQ29weXJpZ2h0IChjKSAyMDIyIENhbWVyb24gUm9iaW5zb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqL1xuXG5pbXBvcnQgeyBwYXJzZUNvbHVtblNldHRpbmdzLCBwYXJzZVNpbmdsZUNvbHVtblNldHRpbmdzIH0gZnJvbSBcIi4uLy4uL3V0aWxpdGllcy9zZXR0aW5nc1BhcnNlclwiO1xuaW1wb3J0IHsgRE9NT2JqZWN0IH0gZnJvbSAnLi4vZG9tT2JqZWN0JztcbmltcG9ydCB7IE11bHRpQ29sdW1uU2V0dGluZ3MsIGdldERlZmF1bHRNdWx0aUNvbHVtblNldHRpbmdzIH0gZnJvbSBcIi4uLy4uL3JlZ2lvblNldHRpbmdzXCI7XG5pbXBvcnQgeyBGaWxlRE9NTWFuYWdlciB9IGZyb20gJy4uL2RvbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RhbmRhcmRNdWx0aUNvbHVtblJlZ2lvbk1hbmFnZXIgYXMgU3RhbmRhcmRNdWx0aUNvbHVtblJlZ2lvbk1hbmFnZXIgfSBmcm9tICcuL3N0YW5kYXJkTXVsdGlDb2x1bW5SZWdpb25NYW5hZ2VyJztcbmltcG9ydCB7IFNpbmdsZUNvbHVtblJlZ2lvbk1hbmFnZXIgfSBmcm9tIFwiLi9zaW5nbGVDb2x1bW5SZWdpb25NYW5hZ2VyXCI7XG5pbXBvcnQgeyBSZWdpb25NYW5hZ2VyIH0gZnJvbSBcIi4vcmVnaW9uTWFuYWdlclwiO1xuaW1wb3J0IHsgQXV0b0xheW91dFJlZ2lvbk1hbmFnZXIgfSBmcm9tICcuL2F1dG9MYXlvdXRSZWdpb25NYW5hZ2VyJztcbmltcG9ydCB7IFJlZmxvd1JlZ2lvbk1hbmFnZXIgfSBmcm9tIFwiLi9yZWZsb3dSZWdpb25NYW5hZ2VyXCI7XG5pbXBvcnQgeyBNQ01fU2V0dGluZ3MsIERFRkFVTFRfU0VUVElOR1MgfSBmcm9tICcuLi8uLi9wbHVnaW5TZXR0aW5ncyc7XG5pbXBvcnQgeyBSZWdpb25FcnJvck1hbmFnZXIgfSBmcm9tIFwiLi4vcmVnaW9uRXJyb3JNYW5hZ2VyXCI7XG5cbi8qKlxuICogVGhpcyBjbGFzcyBhY3RzIGFzIGFuIGFic3RyYWN0aW9uIGZvciB0aGUgYWN0dWFsIHJlZ2lvbmFsIG1hbmFnZXIuIEl0IGlzIHVzZWQgdG8gdXBkYXRlIHRoZVxuICogc3ViY2xhc3Mgb2YgUmVnaW9uYWxNYW5hZ2VyIGRlcGVuZGluZyBvbiB1c2VyIHByZWZlcmVuY2VzIHRvIG1ha2UgcmVuZGVyaW5nIG1vcmUgc2ltcGxpZmllZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFJlZ2lvbk1hbmFnZXJDb250YWluZXIge1xuXG4gICAgcHJvdGVjdGVkIHJlZ2lvbjogUmVnaW9uTWFuYWdlcjtcblxuICAgIGNvbnN0cnVjdG9yKHBhcmVudEZpbGVNYW5hZ2VyOiBGaWxlRE9NTWFuYWdlciwgcmVnaW9uS2V5OiBzdHJpbmcsIHJvb3RFbGVtZW50OiBIVE1MRWxlbWVudCwgcmVnaW9uUGFyZW50OiBIVE1MRWxlbWVudCwgZXJyb3JNYW5hZ2VyOiBSZWdpb25FcnJvck1hbmFnZXIpIHtcbiAgICAgICAgdGhpcy5yZWdpb24gPSBuZXcgU3RhbmRhcmRNdWx0aUNvbHVtblJlZ2lvbk1hbmFnZXIoY3JlYXRlRGVmYXVsdFJlZ2lvbk1hbmFnZXJEYXRhKHJlZ2lvblBhcmVudCwgcGFyZW50RmlsZU1hbmFnZXIsIHJlZ2lvbktleSwgcm9vdEVsZW1lbnQsIGVycm9yTWFuYWdlcikpO1xuICAgIH1cbiAgICBcbiAgICBwdWJsaWMgZ2V0UmVnaW9uKCk6IFJlZ2lvbk1hbmFnZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWdpb247XG4gICAgfVxuXG4gICAgcHVibGljIHNldFJlZ2lvblNldHRpbmdzKHNldHRpbmdzVGV4dDogc3RyaW5nKTogUmVnaW9uTWFuYWdlciB7XG5cbiAgICAgICAgbGV0IHJlZ2lvbmFsU2V0dGluZ3MgPSBwYXJzZUNvbHVtblNldHRpbmdzKHNldHRpbmdzVGV4dCk7XG4gICAgICAgIGlmIChyZWdpb25hbFNldHRpbmdzLm51bWJlck9mQ29sdW1ucyA9PT0gMSkge1xuXG4gICAgICAgICAgICByZWdpb25hbFNldHRpbmdzID0gcGFyc2VTaW5nbGVDb2x1bW5TZXR0aW5ncyhzZXR0aW5nc1RleHQsIHJlZ2lvbmFsU2V0dGluZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnNldFJlZ2lvblBhcnNlZFNldHRpbmdzKHJlZ2lvbmFsU2V0dGluZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRSZWdpb25QYXJzZWRTZXR0aW5ncyhyZWdpb25hbFNldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzKTogUmVnaW9uTWFuYWdlciB7XG5cbiAgICAgICAgdGhpcy5yZWdpb24uc2V0UmVnaW9uYWxTZXR0aW5ncyhyZWdpb25hbFNldHRpbmdzKTtcblxuICAgICAgICBpZiAocmVnaW9uYWxTZXR0aW5ncy5udW1iZXJPZkNvbHVtbnMgPT09IDEpIHtcblxuICAgICAgICAgICAgaWYodGhpcy5yZWdpb24gaW5zdGFuY2VvZiBTaW5nbGVDb2x1bW5SZWdpb25NYW5hZ2VyID09PSBmYWxzZSkge1xuXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5kZWJ1ZyhcIkNvbnZlcnRpbmcgcmVnaW9uIHRvIHNpbmdsZSBjb2x1bW4uXCIpXG4gICAgICAgICAgICAgICAgdGhpcy5jb252ZXJ0VG9TaW5nbGVDb2x1bW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKHJlZ2lvbmFsU2V0dGluZ3MuYXV0b0xheW91dCA9PT0gdHJ1ZSkge1xuXG4gICAgICAgICAgICBpZih0aGlzLnJlZ2lvbiBpbnN0YW5jZW9mIEF1dG9MYXlvdXRSZWdpb25NYW5hZ2VyID09PSBmYWxzZSkge1xuXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5kZWJ1ZyhcIkNvbnZlcnRpbmcgcmVnaW9uIHRvIGF1dG8gbGF5b3V0LlwiKVxuICAgICAgICAgICAgICAgIHRoaXMuY29udmVydFRvQXV0b0xheW91dCgpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZihyZWdpb25hbFNldHRpbmdzLmZ1bGxEb2NSZWZsb3cgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGlmKHRoaXMucmVnaW9uIGluc3RhbmNlb2YgUmVmbG93UmVnaW9uTWFuYWdlciA9PT0gZmFsc2UpIHtcblxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUuZGVidWcoXCJDb252ZXJ0aW5nIHJlZ2lvbiB0byBhdXRvIGxheW91dC5cIilcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnZlcnRUb0RvY1JlZmxvdygpXG4gICAgICAgICAgICB9IFxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJlZ2lvbmFsU2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zID49IDIpIHtcblxuICAgICAgICAgICAgaWYodGhpcy5yZWdpb24gaW5zdGFuY2VvZiBTdGFuZGFyZE11bHRpQ29sdW1uUmVnaW9uTWFuYWdlciA9PT0gZmFsc2UpIHtcblxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUuZGVidWcoXCJDb252ZXJ0aW5nIHJlZ2lvbiB0byBzdGFuZGFyZCBtdWx0aS1jb2x1bW5cIilcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnZlcnRUb1N0YW5kYXJkTXVsdGlDb2x1bW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnJlZ2lvbjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNvbnZlcnRUb1NpbmdsZUNvbHVtbigpOiBTaW5nbGVDb2x1bW5SZWdpb25NYW5hZ2VyIHtcblxuICAgICAgICBsZXQgZGF0YSA9IHRoaXMucmVnaW9uLmdldFJlZ2lvbkRhdGEoKTtcbiAgICAgICAgdGhpcy5yZWdpb24gPSBuZXcgU2luZ2xlQ29sdW1uUmVnaW9uTWFuYWdlcihkYXRhKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5yZWdpb24gYXMgU2luZ2xlQ29sdW1uUmVnaW9uTWFuYWdlcjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNvbnZlcnRUb1N0YW5kYXJkTXVsdGlDb2x1bW4oKTogU3RhbmRhcmRNdWx0aUNvbHVtblJlZ2lvbk1hbmFnZXIge1xuXG4gICAgICAgIGxldCBkYXRhID0gdGhpcy5yZWdpb24uZ2V0UmVnaW9uRGF0YSgpO1xuICAgICAgICB0aGlzLnJlZ2lvbiA9IG5ldyBTdGFuZGFyZE11bHRpQ29sdW1uUmVnaW9uTWFuYWdlcihkYXRhKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5yZWdpb24gYXMgU3RhbmRhcmRNdWx0aUNvbHVtblJlZ2lvbk1hbmFnZXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb252ZXJ0VG9BdXRvTGF5b3V0KCk6IEF1dG9MYXlvdXRSZWdpb25NYW5hZ2VyIHtcblxuICAgICAgICBsZXQgZGF0YSA9IHRoaXMucmVnaW9uLmdldFJlZ2lvbkRhdGEoKTtcbiAgICAgICAgdGhpcy5yZWdpb24gPSBuZXcgQXV0b0xheW91dFJlZ2lvbk1hbmFnZXIoZGF0YSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMucmVnaW9uIGFzIEF1dG9MYXlvdXRSZWdpb25NYW5hZ2VyO1xuICAgIH1cblxuICAgIHByaXZhdGUgY29udmVydFRvRG9jUmVmbG93KCk6IFJlZmxvd1JlZ2lvbk1hbmFnZXIge1xuXG4gICAgICAgIGxldCBkYXRhID0gdGhpcy5yZWdpb24uZ2V0UmVnaW9uRGF0YSgpO1xuICAgICAgICB0aGlzLnJlZ2lvbiA9IG5ldyBSZWZsb3dSZWdpb25NYW5hZ2VyKGRhdGEpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnJlZ2lvbiBhcyBSZWZsb3dSZWdpb25NYW5hZ2VyO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVmYXVsdFJlZ2lvbk1hbmFnZXJEYXRhKHJlZ2lvblBhcmVudDogSFRNTEVsZW1lbnQsIGZpbGVNYW5hZ2VyOiBGaWxlRE9NTWFuYWdlciwgcmVnaW9uS2V5OiBzdHJpbmcsIHJvb3RFbGVtZW50OiBIVE1MRWxlbWVudCwgZXJyb3JNYW5hZ2VyOiBSZWdpb25FcnJvck1hbmFnZXIpOiBSZWdpb25NYW5hZ2VyRGF0YSB7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBkb21MaXN0OiBbXSxcbiAgICAgICAgZG9tT2JqZWN0TWFwOiBuZXcgTWFwKCksXG4gICAgICAgIHJlZ2lvblBhcmVudDogcmVnaW9uUGFyZW50LFxuICAgICAgICBmaWxlTWFuYWdlcjogZmlsZU1hbmFnZXIsXG4gICAgICAgIHJlZ2lvbmFsU2V0dGluZ3M6IGdldERlZmF1bHRNdWx0aUNvbHVtblNldHRpbmdzKCksXG4gICAgICAgIHJlZ2lvbktleTogcmVnaW9uS2V5LFxuICAgICAgICByb290RWxlbWVudDogcm9vdEVsZW1lbnQsXG4gICAgICAgIGVycm9yTWFuYWdlcjogZXJyb3JNYW5hZ2VyXG4gICAgfTtcbn1cblxuZXhwb3J0IHR5cGUgUmVnaW9uTWFuYWdlckRhdGEgPSB7XG4gICAgZG9tTGlzdDogRE9NT2JqZWN0W107XG4gICAgZG9tT2JqZWN0TWFwOiBNYXA8c3RyaW5nLCBET01PYmplY3Q+O1xuICAgIHJlZ2lvblBhcmVudDogSFRNTEVsZW1lbnQ7XG5cbiAgICBmaWxlTWFuYWdlcjogRmlsZURPTU1hbmFnZXI7XG4gICAgcmVnaW9uYWxTZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncztcblxuICAgIHJlZ2lvbktleTogc3RyaW5nO1xuICAgIHJvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBlcnJvck1hbmFnZXI6IFJlZ2lvbkVycm9yTWFuYWdlcjtcbn07XG4iLCIvKlxuICogRmlsZTogbXVsdGktY29sdW1uLW1hcmtkb3duL3NyYy9kb21NYW5hZ2VyLnRzXG4gKiBDcmVhdGVkIERhdGU6IFNhdHVyZGF5LCBKYW51YXJ5IDMwdGggMjAyMiwgMzoxNjozMiBwbVxuICogQXV0aG9yOiBDYW1lcm9uIFJvYmluc29uXG4gKiBcbiAqIENvcHlyaWdodCAoYykgMjAyMiBDYW1lcm9uIFJvYmluc29uXG4gKi9cblxuaW1wb3J0IHsgUmVnaW9uTWFuYWdlciB9IGZyb20gXCIuL3JlZ2lvbmFsX21hbmFnZXJzL3JlZ2lvbk1hbmFnZXJcIjtcbmltcG9ydCB7IFJlZ2lvbk1hbmFnZXJDb250YWluZXIgfSBmcm9tIFwiLi9yZWdpb25hbF9tYW5hZ2Vycy9yZWdpb25NYW5hZ2VyQ29udGFpbmVyXCI7XG5pbXBvcnQgeyBSZWdpb25FcnJvck1hbmFnZXIgfSBmcm9tIFwiLi9yZWdpb25FcnJvck1hbmFnZXJcIjtcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGhhbmRsZXMgdGhlIGdsb2JhbCBtYW5hZ2VycyBrZWVwaW5nIHRyYWNrIG9mIGFsbCBvcGVuIGZpbGVzIHRoYXRcbiAqIGNvbnRhaW4gTUNNLVJlZ2lvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBHbG9iYWxET01NYW5hZ2VyIHtcbiAgICBtYW5hZ2VyczogTWFwPHN0cmluZywgRmlsZURPTU1hbmFnZXI+O1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMubWFuYWdlcnMgPSBuZXcgTWFwKCk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbW92ZUZpbGVNYW5hZ2VyQ2FsbGJhY2soa2V5OiBzdHJpbmcpIHtcbiAgICAgICAgaWYodGhpcy5tYW5hZ2Vycy5oYXMoa2V5KSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgdGhpcy5tYW5hZ2Vycy5kZWxldGUoa2V5KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRGaWxlTWFuYWdlcihrZXk6IHN0cmluZykge1xuXG4gICAgICAgIGxldCBmaWxlTWFuYWdlciA9IG51bGw7XG4gICAgICAgIGlmKHRoaXMubWFuYWdlcnMuaGFzKGtleSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGZpbGVNYW5hZ2VyID0gdGhpcy5tYW5hZ2Vycy5nZXQoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZpbGVNYW5hZ2VyID0gbmV3IEZpbGVET01NYW5hZ2VyKHRoaXMsIGtleSk7XG4gICAgICAgICAgICB0aGlzLm1hbmFnZXJzLnNldChrZXksIGZpbGVNYW5hZ2VyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmaWxlTWFuYWdlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0QWxsRmlsZU1hbmFnZXJzKCkge1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLm1hbmFnZXJzLnZhbHVlcygpKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGaWxlRE9NTWFuYWdlciB7XG4gICAgcmVnaW9uTWFwOiBNYXA8c3RyaW5nLCBSZWdpb25NYW5hZ2VyQ29udGFpbmVyPjtcbiAgICBoYXNTdGFydFRhZzogYm9vbGVhbjtcbiAgICBmaWxlS2V5OiBzdHJpbmc7XG4gICAgcGFyZW50TWFuYWdlcjogR2xvYmFsRE9NTWFuYWdlcjtcblxuICAgIGNvbnN0cnVjdG9yKHBhcmVudE1hbmFnZXI6IEdsb2JhbERPTU1hbmFnZXIsIGZpbGVLZXk6IHN0cmluZykge1xuICAgICAgICB0aGlzLnJlZ2lvbk1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgdGhpcy5oYXNTdGFydFRhZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnBhcmVudE1hbmFnZXIgPSBwYXJlbnRNYW5hZ2VyO1xuICAgICAgICB0aGlzLmZpbGVLZXkgPSBmaWxlS2V5O1xuICAgIH1cblxuICAgIHJlbW92ZVJlZ2lvbihyZWdpb25LZXk6IHN0cmluZyk6IHZvaWQge1xuXG4gICAgICAgIGxldCByZWdpb25Db250YWluZXIgPSB0aGlzLnJlZ2lvbk1hcC5nZXQocmVnaW9uS2V5KTtcbiAgICAgICAgaWYocmVnaW9uQ29udGFpbmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCByZWdpb25hbE1hbmFnZXIgPSByZWdpb25Db250YWluZXIuZ2V0UmVnaW9uKCk7XG4gICAgICAgIHJlZ2lvbmFsTWFuYWdlci5kaXNwbGF5T3JpZ2luYWxFbGVtZW50cygpO1xuXG4gICAgICAgIHRoaXMucmVnaW9uTWFwLmRlbGV0ZShyZWdpb25LZXkpO1xuICAgICAgICBcbiAgICAgICAgaWYodGhpcy5yZWdpb25NYXAuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5wYXJlbnRNYW5hZ2VyLnJlbW92ZUZpbGVNYW5hZ2VyQ2FsbGJhY2sodGhpcy5maWxlS2V5KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZVJlZ2lvbmFsTWFuYWdlcihyZWdpb25LZXk6IHN0cmluZywgcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50LCBlcnJvck1hbmFnZXI6IFJlZ2lvbkVycm9yTWFuYWdlciwgcmVuZGVyUmVnaW9uRWxlbWVudDogSFRNTEVsZW1lbnQpOiBSZWdpb25NYW5hZ2VyIHtcblxuICAgICAgICBsZXQgcmVnb25hbENvbnRhaW5lciA9IG5ldyBSZWdpb25NYW5hZ2VyQ29udGFpbmVyKHRoaXMsIHJlZ2lvbktleSwgcm9vdEVsZW1lbnQsIHJlbmRlclJlZ2lvbkVsZW1lbnQsIGVycm9yTWFuYWdlcik7XG4gICAgICAgIHRoaXMucmVnaW9uTWFwLnNldChyZWdpb25LZXksIHJlZ29uYWxDb250YWluZXIpO1xuICAgICAgICByZXR1cm4gcmVnb25hbENvbnRhaW5lci5nZXRSZWdpb24oKTtcbiAgICB9XG5cbiAgICBnZXRSZWdpb25hbENvbnRhaW5lcihyZWdpb25LZXk6IHN0cmluZyk6IFJlZ2lvbk1hbmFnZXJDb250YWluZXIgfCBudWxsIHtcblxuICAgICAgICBsZXQgcmVnb25hbE1hbmFnZXIgPSBudWxsO1xuICAgICAgICBpZih0aGlzLnJlZ2lvbk1hcC5oYXMocmVnaW9uS2V5KSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmVnb25hbE1hbmFnZXIgPSB0aGlzLnJlZ2lvbk1hcC5nZXQocmVnaW9uS2V5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZWdvbmFsTWFuYWdlcjtcbiAgICB9XG5cbiAgICBnZXRBbGxSZWdpb25hbE1hbmFnZXJzKCk6IFJlZ2lvbk1hbmFnZXJbXSB7XG5cbiAgICAgICAgbGV0IGNvbnRhaW5lcnMgPSBBcnJheS5mcm9tKHRoaXMucmVnaW9uTWFwLnZhbHVlcygpKVxuICAgICAgICBsZXQgcmVnaW9uczogUmVnaW9uTWFuYWdlcltdID0gY29udGFpbmVycy5tYXAoKGN1cnIpID0+IHsgcmV0dXJuIGN1cnIuZ2V0UmVnaW9uKCkgfSk7XG4gICAgICAgIHJldHVybiByZWdpb25zO1xuICAgIH1cblxuICAgIHNldEhhc1N0YXJ0VGFnKCkge1xuICAgICAgICB0aGlzLmhhc1N0YXJ0VGFnID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBnZXRIYXNTdGFydFRhZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzU3RhcnRUYWc7XG4gICAgfVxuXG4gICAgZ2V0TnVtYmVyT2ZSZWdpb25zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWdpb25NYXAuc2l6ZVxuICAgIH1cblxuICAgIGNoZWNrS2V5RXhpc3RzKGNoZWNrS2V5OiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVnaW9uTWFwLmhhcyhjaGVja0tleSk7XG4gICAgfVxufSIsImltcG9ydCB7IE11bHRpQ29sdW1uTGF5b3V0Q1NTLCBNdWx0aUNvbHVtblN0eWxlQ1NTIH0gZnJvbSBcInNyYy91dGlsaXRpZXMvY3NzRGVmaW5pdGlvbnNcIjtcblxuZXhwb3J0IGNsYXNzIFJlZ2lvbkVycm9yTWFuYWdlciB7XG5cbiAgICAvL1RPRE86IEFkZCB3YXJuaW5nc1xuXG4gICAgZXJyb3JQYXJlbnRFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBjb250ZW50RWw6IEhUTUxFbGVtZW50O1xuICAgIHRpdGxlUmVnaW9uOiBIVE1MRWxlbWVudDtcblxuICAgIGVycm9yTWVzc2FnZXM6IHN0cmluZ1tdID0gW107XG4gICAgd2FybmluZ01lc3NhZ2VzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBnZXQgdG90YWxOdW1NZXNzYWdlcygpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5lcnJvck1lc3NhZ2VzLmxlbmd0aCArIHRoaXMud2FybmluZ01lc3NhZ2VzLmxlbmd0aFxuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHJvb3RFbGVtZW50OiBIVE1MRWxlbWVudCwgaW5pdGlhbEVycm9yTWVzc2FnZXM6IHN0cmluZ1tdID0gW10pIHtcbiAgICAgICAgXG4gICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlcyA9IGluaXRpYWxFcnJvck1lc3NhZ2VzO1xuICAgICAgICB0aGlzLnNldFJlZ2lvblJvb3RFbGVtZW50KHJvb3RFbGVtZW50KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkRXJyb3JNZXNzYWdlKGVycm9yU3RyaW5nOiBzdHJpbmcpIHtcblxuICAgICAgICB0aGlzLmVycm9yTWVzc2FnZXMucHVzaChlcnJvclN0cmluZyk7XG4gICAgICAgIHRoaXMudXBkYXRlRXJyb3JWaWV3KClcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkV2FybmluZ01lc3NhZ2Uod2FybmluZ1N0cmluZzogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMud2FybmluZ01lc3NhZ2VzLnB1c2god2FybmluZ1N0cmluZyk7XG4gICAgICAgIHRoaXMudXBkYXRlRXJyb3JWaWV3KClcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0UmVnaW9uUm9vdEVsZW1lbnQocm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG5cbiAgICAgICAgdGhpcy5lcnJvclBhcmVudEVsZW1lbnQgPSByb290RWxlbWVudC5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgY2xzOiBgJHtNdWx0aUNvbHVtbkxheW91dENTUy5SZWdpb25FcnJvckNvbnRhaW5lckRpdn1gLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy50aXRsZVJlZ2lvbiA9IHRoaXMuZXJyb3JQYXJlbnRFbGVtZW50LmNyZWF0ZURpdih7XG4gICAgICAgICAgICBjbHM6IGAke011bHRpQ29sdW1uTGF5b3V0Q1NTLkVycm9yUmVnaW9uUGFkZGluZ31gXG4gICAgICAgIH0pXG4gICAgICAgIHRoaXMuY29udGVudEVsID0gdGhpcy5lcnJvclBhcmVudEVsZW1lbnQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgIGNsczogYCR7TXVsdGlDb2x1bW5MYXlvdXRDU1MuRXJyb3JSZWdpb25QYWRkaW5nfSBtY20tbWVzc2FnZS1yZWdpb25gXG4gICAgICAgIH0pXG4gICAgICAgIHRoaXMudXBkYXRlRXJyb3JWaWV3KClcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldHVwRXJyb3JIZWFkZXIoKSB7XG4gICAgICAgIGlmKHRoaXMuZXJyb3JNZXNzYWdlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBsZXQgdGV4dCA9IFwiRXJyb3JcIlxuICAgICAgICAgICAgaWYodGhpcy5lcnJvck1lc3NhZ2VzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICB0ZXh0ID0gdGV4dCArIFwic1wiXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudGl0bGVSZWdpb24uY3JlYXRlU3Bhbih7XG4gICAgICAgICAgICAgICAgYXR0cjoge1wic3R5bGVcIjogXCJjb2xvcjogdmFyKC0tdGV4dC1lcnJvcik7IHBhZGRpbmc6IDVweDtcIn0sXG4gICAgICAgICAgICAgICAgdGV4dDogXCJcXHUyQTAyXCJcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLnRpdGxlUmVnaW9uLmNyZWF0ZVNwYW4oe1xuICAgICAgICAgICAgICAgIHRleHQ6IGAke3RoaXMuZXJyb3JNZXNzYWdlcy5sZW5ndGh9ICR7dGV4dH1gXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgaWYodGhpcy5lcnJvck1lc3NhZ2VzLmxlbmd0aCA+IDAgJiYgdGhpcy53YXJuaW5nTWVzc2FnZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy50aXRsZVJlZ2lvbi5jcmVhdGVTcGFuKHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBgIGFuZCBgXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgaWYodGhpcy53YXJuaW5nTWVzc2FnZXMubGVuZ3RoID4gMCkge1xuXG4gICAgICAgICAgICBsZXQgdGV4dCA9IFwiV2FybmluZ1wiXG4gICAgICAgICAgICBpZih0aGlzLndhcm5pbmdNZXNzYWdlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgdGV4dCA9IHRleHQgKyBcInNcIlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnRpdGxlUmVnaW9uLmNyZWF0ZVNwYW4oe1xuICAgICAgICAgICAgICAgIGF0dHI6IHtcInN0eWxlXCI6IFwiY29sb3I6IHZhcigtLWNvbG9yLXllbGxvdyk7IHBhZGRpbmc6IDVweDtcIn0sXG4gICAgICAgICAgICAgICAgdGV4dDogXCJcXHUyNkEwXCJcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLnRpdGxlUmVnaW9uLmNyZWF0ZVNwYW4oe1xuICAgICAgICAgICAgICAgIHRleHQ6IGAke3RoaXMud2FybmluZ01lc3NhZ2VzLmxlbmd0aH0gJHt0ZXh0fWBcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50aXRsZVJlZ2lvbi5jcmVhdGVTcGFuKHtcbiAgICAgICAgICAgIHRleHQ6IGAgaW4gcmVnaW9uYFxuICAgICAgICB9KVxuXG4gICAgICAgIGxldCByZWdpb25PcGVuZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50aXRsZVJlZ2lvbi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGV2KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRpdGxlUmVnaW9uLmNsYXNzTGlzdC50b2dnbGUoXCJtY20tZXJyb3ItaGVhZGluZy1vcGVuXCIpO1xuICAgICAgICAgICAgcmVnaW9uT3BlbmVkID0gIXJlZ2lvbk9wZW5lZFxuICAgICAgICAgICAgaWYocmVnaW9uT3BlbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50RWwuc3R5bGUubWF4SGVpZ2h0ID0gdGhpcy5jb250ZW50RWwuc2Nyb2xsSGVpZ2h0ICsgXCJweFwiO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRFbC5zdHlsZS5tYXhIZWlnaHQgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIHB1YmxpYyB1cGRhdGVFcnJvclZpZXcoKSB7XG5cbiAgICAgICAgdGhpcy5yZXNldEVycm9yVmlldygpXG5cbiAgICAgICAgaWYodGhpcy50b3RhbE51bU1lc3NhZ2VzID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50aXRsZVJlZ2lvbi5hZGRDbGFzcyhgbWNtLWVycm9yLWhlYWRpbmdgKSAvL1RPRE86IG1vdmUgdG8gY29uc3QuXG4gICAgICAgIHRoaXMuZXJyb3JQYXJlbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoTXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Cb3JkZXIpXG4gICAgICAgIHRoaXMuc2V0dXBFcnJvckhlYWRlcigpXG4gICAgICAgIHRoaXMuYXBwZW5kQ29udGVudFRvRWwoKVxuICAgIH1cblxuXG4gICAgcHJpdmF0ZSBhcHBlbmRDb250ZW50VG9FbCgpIHtcblxuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy5lcnJvck1lc3NhZ2VzLmxlbmd0aDsgaSsrKSB7XG5cbiAgICAgICAgICAgIGxldCBwID0gdGhpcy5jb250ZW50RWwuY3JlYXRlRWwoXCJwXCIpXG4gICAgICAgICAgICBwLmlubmVySFRNTCA9IGA8c3BhbiBjbGFzcz1cIm1jbS1lcnJvci1pY29uXCI+XFx1MkEwMjwvc3Bhbj4ke3RoaXMuZXJyb3JNZXNzYWdlc1swXX1gXG4gICAgICAgIH1cblxuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy53YXJuaW5nTWVzc2FnZXMubGVuZ3RoOyBpKyspIHtcblxuICAgICAgICAgICAgbGV0IHAgPSB0aGlzLmNvbnRlbnRFbC5jcmVhdGVFbChcInBcIilcbiAgICAgICAgICAgIHAuaW5uZXJIVE1MID0gYDxzcGFuIGNsYXNzPVwibWNtLXdhcm5pbmctaWNvblwiPlxcdTI2QTA8L3NwYW4+JHt0aGlzLndhcm5pbmdNZXNzYWdlc1swXX1gXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlc2V0RXJyb3JWaWV3KCkge1xuXG4gICAgICAgIHRoaXMuZXJyb3JQYXJlbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoTXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5Cb3JkZXIpXG4gICAgICAgIHRoaXMudGl0bGVSZWdpb24ucmVtb3ZlQ2xhc3MoYG1jbS1lcnJvci1oZWFkaW5nYCkgLy9UT0RPOiBtb3ZlIHRvIGNvbnN0LlxuXG4gICAgICAgIHdoaWxlKHRoaXMudGl0bGVSZWdpb24uY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy50aXRsZVJlZ2lvbi5jaGlsZE5vZGVzLmZvckVhY2goY2hpbGQgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudGl0bGVSZWdpb24ucmVtb3ZlQ2hpbGQoY2hpbGQpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgaWYodGhpcy5jb250ZW50RWwgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjaGlsZHJlbiA9IHRoaXMuY29udGVudEVsPy5jaGlsZE5vZGVzO1xuICAgICAgICBjaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IHtcbiAgICAgICAgICAgIGlmKGNoaWxkICE9PSBudWxsICYmIGNoaWxkLnBhcmVudEVsZW1lbnQgPT09IHRoaXMuY29udGVudEVsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50RWwucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59IiwiaW1wb3J0IHsgRE9NT2JqZWN0VGFnLCBFbGVtZW50Q29sdW1uQnJlYWtUeXBlIH0gZnJvbSBcInNyYy9kb21fbWFuYWdlci9kb21PYmplY3RcIlxuaW1wb3J0IHsgUmVnaW9uRXJyb3JNYW5hZ2VyIH0gZnJvbSBcInNyYy9kb21fbWFuYWdlci9yZWdpb25FcnJvck1hbmFnZXJcIlxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29sQnJlYWtXYXJuaW5nKHR5cGU6IEVsZW1lbnRDb2x1bW5CcmVha1R5cGUsIGVycm9yTWFuYWdlcjogUmVnaW9uRXJyb3JNYW5hZ2VyKSB7XG5cbiAgICBsZXQgdHlwZUVycm9yU3RyID0gXCJcIlxuICAgIGlmKHR5cGUgPT09IEVsZW1lbnRDb2x1bW5CcmVha1R5cGUucHJlQnJlYWspIHtcbiAgICAgICAgdHlwZUVycm9yU3RyID0gXCJhdCB0aGUgYmVnaW5pbmcgb2YgYW5vdGhlciBlbGVtZW50XCJcbiAgICB9XG4gICAgaWYodHlwZSA9PT0gRWxlbWVudENvbHVtbkJyZWFrVHlwZS5wb3N0QnJlYWspIHtcbiAgICAgICAgdHlwZUVycm9yU3RyID0gXCJhdCB0aGUgZW5kIG9mIGFub3RoZXIgZWxlbWVudFwiXG4gICAgfVxuICAgIGlmKHR5cGUgPT09IEVsZW1lbnRDb2x1bW5CcmVha1R5cGUubWlkQnJlYWspIHtcbiAgICAgICAgdHlwZUVycm9yU3RyID0gXCJpbiB0aGUgbWlkZGxlIG9mIHR3byBlbGVtZW50c1wiXG4gICAgfVxuXG4gICAgZXJyb3JNYW5hZ2VyLmFkZFdhcm5pbmdNZXNzYWdlKGBEZXRlY3RlZCBhIGNvbHVtbiBicmVhayB0YWcgJHt0eXBlRXJyb3JTdHJ9LiBQbGVhc2UgbWFrZSBzdXJlIHRvIHN1cnJvdW5kIGNvbHVtbiBicmVha3Mgd2l0aCBlbXB0eSBsaW5lcyBvbiBib3RoIHNpZGVzLCBvciByZW5kZXIgaXNzdWVzIG1heSBvY2N1ci5gKVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbEJyZWFrVHlwZUluZm8ge1xuICAgIGxpbmVBYm92ZTogc3RyaW5nO1xuICAgIGxpbmVCZWxvdzogc3RyaW5nO1xuICAgIG9iamVjdFRhZzogRE9NT2JqZWN0VGFnO1xuICAgIGNvbEJyZWFrVHlwZTogRWxlbWVudENvbHVtbkJyZWFrVHlwZVxufVxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQ29sQnJlYWtFcnJvclR5cGUoZWxlbWVudEluZm86IENvbEJyZWFrVHlwZUluZm8sIGVycm9yTWFuYWdlcjogUmVnaW9uRXJyb3JNYW5hZ2VyKSB7XG5cbiAgICBpZihlbGVtZW50SW5mby5vYmplY3RUYWcgIT09IERPTU9iamVjdFRhZy5jb2x1bW5CcmVhayAmJlxuICAgICAgIGVsZW1lbnRJbmZvLmNvbEJyZWFrVHlwZSA9PT0gRWxlbWVudENvbHVtbkJyZWFrVHlwZS5ub25lKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgZXJyb3JUeXBlOiBFbGVtZW50Q29sdW1uQnJlYWtUeXBlID0gZWxlbWVudEluZm8uY29sQnJlYWtUeXBlO1xuICAgIGlmKGVsZW1lbnRJbmZvLm9iamVjdFRhZyA9PT0gRE9NT2JqZWN0VGFnLmNvbHVtbkJyZWFrKSB7XG5cbiAgICAgICAgaWYoZWxlbWVudEluZm8ubGluZUFib3ZlID09PSBcIlwiICYmXG4gICAgICAgICAgIGVsZW1lbnRJbmZvLmxpbmVCZWxvdyA9PT0gXCJcIikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGxpbmVBYm92ZSA9IGVsZW1lbnRJbmZvLmxpbmVBYm92ZVxuICAgICAgICBsZXQgbGluZUJlbG93ID0gZWxlbWVudEluZm8ubGluZUJlbG93XG4gICAgICAgIGlmKGxpbmVBYm92ZSAhPT0gXCJcIiAmJiBsaW5lQmVsb3cgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIGVycm9yVHlwZSA9IEVsZW1lbnRDb2x1bW5CcmVha1R5cGUucG9zdEJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgaWYobGluZUFib3ZlID09PSBcIlwiICYmIGxpbmVCZWxvdyAhPT0gXCJcIikge1xuICAgICAgICAgICAgZXJyb3JUeXBlID0gRWxlbWVudENvbHVtbkJyZWFrVHlwZS5wcmVCcmVha1xuICAgICAgICB9XG4gICAgICAgIGlmKGxpbmVBYm92ZSAhPT0gXCJcIiAmJiBsaW5lQmVsb3cgIT09IFwiXCIpIHtcbiAgICAgICAgICAgIGVycm9yVHlwZSA9IEVsZW1lbnRDb2x1bW5CcmVha1R5cGUubWlkQnJlYWtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjcmVhdGVDb2xCcmVha1dhcm5pbmcoZXJyb3JUeXBlLCBlcnJvck1hbmFnZXIpXG59IiwiaW1wb3J0IHsgV29ya3NwYWNlLCBXb3Jrc3BhY2VMZWFmIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMZWFmRnJvbUZpbGVQYXRoKHdvcmtzcGFjZTogV29ya3NwYWNlLCBmaWxlUGF0aDogc3RyaW5nKTogV29ya3NwYWNlTGVhZiB8IG51bGwge1xuXG4gICAgZnVuY3Rpb24gY2hlY2tTdGF0ZShzdGF0ZTogYW55KSB7XG5cbiAgICAgICAgaWYoc3RhdGVbXCJ0eXBlXCJdID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgc3RhdGVbXCJ0eXBlXCJdICE9PSBcIm1hcmtkb3duXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKHN0YXRlW1wic3RhdGVcIl0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICBpZihzdGF0ZVtcInN0YXRlXCJdW1wiZmlsZVwiXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3RhdGVGaWxlUGF0aCA9IHN0YXRlW1wic3RhdGVcIl1bXCJmaWxlXCJdO1xuICAgICAgICByZXR1cm4gc3RhdGVGaWxlUGF0aCA9PT0gZmlsZVBhdGg7XG4gICAgfVxuXG4gICAgaWYod29ya3NwYWNlID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGxldCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXMod29ya3NwYWNlLmdldExheW91dCgpKTtcbiAgICBsZXQgaXRlbXMgPSBBcnJheS5mcm9tKGVudHJpZXMpLm1hcCgodmFsKSA9PiB7XG4gICAgICAgIHJldHVybiB2YWxbMV1cbiAgICB9KVxuICAgIHdoaWxlKGl0ZW1zLmxlbmd0aCA+IDApIHtcblxuICAgICAgICBsZXQgZW50cnlPYmogPSBpdGVtcy5zaGlmdCgpIGFzIGFueTtcbiAgICAgICAgaWYoZW50cnlPYmpbXCJpZFwiXSAhPT0gdW5kZWZpbmVkICYmIGVudHJ5T2JqW1widHlwZVwiXSAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICAgICAgICAgIGlmKGVudHJ5T2JqW1widHlwZVwiXSA9PT0gXCJzcGxpdFwiIHx8XG4gICAgICAgICAgICAgICBlbnRyeU9ialtcInR5cGVcIl0gPT09IFwidGFic1wiICkge1xuICAgICAgICAgICAgICAgIGl0ZW1zID0gaXRlbXMuY29uY2F0KGVudHJ5T2JqWydjaGlsZHJlbiddKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYoZW50cnlPYmpbXCJ0eXBlXCJdID09PSBcImxlYWZcIiAmJiBcbiAgICAgICAgICAgICAgIGVudHJ5T2JqW1wiaWRcIl0gIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgZW50cnlPYmpbXCJzdGF0ZVwiXSAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgaWQgPSBlbnRyeU9ialtcImlkXCJdO1xuICAgICAgICAgICAgICAgIGxldCBzdGF0ZSA9IGVudHJ5T2JqW1wic3RhdGVcIl07XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coc3RhdGUpXG5cbiAgICAgICAgICAgICAgICBsZXQgdmFsaWQgPSBjaGVja1N0YXRlKHN0YXRlKTtcbiAgICAgICAgICAgICAgICBpZih2YWxpZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd29ya3NwYWNlLmdldExlYWZCeUlkKGlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmV2aWV3TGVhZkZyb21GaWxlUGF0aCh3b3Jrc3BhY2U6IFdvcmtzcGFjZSwgZmlsZVBhdGg6IHN0cmluZyk6IFdvcmtzcGFjZUxlYWYgfCBudWxsIHtcblxuICAgIGZ1bmN0aW9uIGNoZWNrU3RhdGUoc3RhdGU6IGFueSkge1xuXG4gICAgICAgIGlmKHN0YXRlW1widHlwZVwiXSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgIHN0YXRlW1widHlwZVwiXSAhPT0gXCJtYXJrZG93blwiKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZihzdGF0ZVtcInN0YXRlXCJdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgaWYoc3RhdGVbXCJzdGF0ZVwiXVtcImZpbGVcIl0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN0YXRlRmlsZVBhdGggPSBzdGF0ZVtcInN0YXRlXCJdW1wiZmlsZVwiXTtcbiAgICAgICAgcmV0dXJuIHN0YXRlRmlsZVBhdGggPT09IGZpbGVQYXRoO1xuICAgIH1cblxuICAgIGxldCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXMod29ya3NwYWNlLmdldExheW91dCgpKTtcbiAgICBsZXQgaXRlbXMgPSBBcnJheS5mcm9tKGVudHJpZXMpLm1hcCgodmFsKSA9PiB7XG4gICAgICAgIHJldHVybiB2YWxbMV1cbiAgICB9KVxuICAgIHdoaWxlKGl0ZW1zLmxlbmd0aCA+IDApIHtcblxuICAgICAgICBsZXQgZW50cnlPYmogPSBpdGVtcy5zaGlmdCgpIGFzIGFueTtcbiAgICAgICAgaWYoZW50cnlPYmpbXCJpZFwiXSAhPT0gdW5kZWZpbmVkICYmIGVudHJ5T2JqW1widHlwZVwiXSAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICAgICAgICAgIGlmKGVudHJ5T2JqW1widHlwZVwiXSA9PT0gXCJzcGxpdFwiIHx8XG4gICAgICAgICAgICAgICBlbnRyeU9ialtcInR5cGVcIl0gPT09IFwidGFic1wiICkge1xuICAgICAgICAgICAgICAgIGl0ZW1zID0gaXRlbXMuY29uY2F0KGVudHJ5T2JqWydjaGlsZHJlbiddKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYoZW50cnlPYmpbXCJ0eXBlXCJdID09PSBcImxlYWZcIiAmJiBcbiAgICAgICAgICAgICAgIGVudHJ5T2JqW1wiaWRcIl0gIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgICAgZW50cnlPYmpbXCJzdGF0ZVwiXSAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgaWQgPSBlbnRyeU9ialtcImlkXCJdO1xuICAgICAgICAgICAgICAgIGxldCBzdGF0ZSA9IGVudHJ5T2JqW1wic3RhdGVcIl07XG5cbiAgICAgICAgICAgICAgICBsZXQgaXNQcmV2aWV3ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgaWYoc3RhdGVbXCJzdGF0ZVwiXSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlW1wic3RhdGVcIl1bXCJtb2RlXCJdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1vZGUgPSBzdGF0ZVtcInN0YXRlXCJdW1wibW9kZVwiXVxuICAgICAgICAgICAgICAgICAgICBpc1ByZXZpZXcgPSBtb2RlID09PSBcInByZXZpZXdcIlxuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgdmFsaWRGaWxlUGF0aCA9IGNoZWNrU3RhdGUoc3RhdGUpO1xuICAgICAgICAgICAgICAgIGlmKHZhbGlkRmlsZVBhdGggJiYgaXNQcmV2aWV3KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB3b3Jrc3BhY2UuZ2V0TGVhZkJ5SWQoaWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn0iLCIvKlxuICogRmlsZW5hbWU6IG11bHRpLWNvbHVtbi1tYXJrZG93bi9zcmMvbGl2ZV9wcmV2aWV3L011bHRpQ29sdW1uTWFya2Rvd25fV2lkZ2V0LnRzXG4gKiBDcmVhdGVkIERhdGU6IFR1ZXNkYXksIEF1Z3VzdCAxNnRoIDIwMjIsIDQ6Mzg6NDMgcG1cbiAqIEF1dGhvcjogQ2FtZXJvbiBSb2JpbnNvblxuICogXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjIgQ2FtZXJvbiBSb2JpbnNvblxuICovXG5cbmltcG9ydCB7IE1hcmtkb3duUmVuZGVyQ2hpbGQsIE1hcmtkb3duUmVuZGVyZXIsIFRGaWxlLCBXb3Jrc3BhY2VMZWFmIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5pbXBvcnQgeyBXaWRnZXRUeXBlIH0gZnJvbSBcIkBjb2RlbWlycm9yL3ZpZXdcIjtcbmltcG9ydCB7IGdldERlZmF1bHRNdWx0aUNvbHVtblNldHRpbmdzLCBNQ1NldHRpbmdzX2lzRXF1YWwsIE11bHRpQ29sdW1uU2V0dGluZ3MgfSBmcm9tIFwiLi4vcmVnaW9uU2V0dGluZ3NcIjtcbmltcG9ydCB7IHBhcnNlU2luZ2xlQ29sdW1uU2V0dGluZ3MgfSBmcm9tIFwiLi4vdXRpbGl0aWVzL3NldHRpbmdzUGFyc2VyXCI7XG5pbXBvcnQgeyBTdGFuZGFyZE11bHRpQ29sdW1uUmVnaW9uTWFuYWdlciB9IGZyb20gXCIuLi9kb21fbWFuYWdlci9yZWdpb25hbF9tYW5hZ2Vycy9zdGFuZGFyZE11bHRpQ29sdW1uUmVnaW9uTWFuYWdlclwiO1xuaW1wb3J0IHsgUmVnaW9uTWFuYWdlckRhdGEgfSBmcm9tIFwiLi4vZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvcmVnaW9uTWFuYWdlckNvbnRhaW5lclwiO1xuaW1wb3J0IHsgZ2V0VUlEIH0gZnJvbSBcIi4uL3V0aWxpdGllcy91dGlsc1wiO1xuaW1wb3J0IHsgRE9NT2JqZWN0LCBET01PYmplY3RUYWcsIEVsZW1lbnRDb2x1bW5CcmVha1R5cGUgfSBmcm9tIFwiLi4vZG9tX21hbmFnZXIvZG9tT2JqZWN0XCI7XG5pbXBvcnQgeyBSZWdpb25NYW5hZ2VyIH0gZnJvbSBcIi4uL2RvbV9tYW5hZ2VyL3JlZ2lvbmFsX21hbmFnZXJzL3JlZ2lvbk1hbmFnZXJcIjtcbmltcG9ydCB7IFNpbmdsZUNvbHVtblJlZ2lvbk1hbmFnZXIgfSBmcm9tIFwiLi4vZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvc2luZ2xlQ29sdW1uUmVnaW9uTWFuYWdlclwiO1xuaW1wb3J0IHsgQXV0b0xheW91dFJlZ2lvbk1hbmFnZXIgfSBmcm9tIFwiLi4vZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvYXV0b0xheW91dFJlZ2lvbk1hbmFnZXJcIjtcbmltcG9ydCB7IE11bHRpQ29sdW1uU3R5bGVDU1MsIE9ic2lkaWFuU3R5bGVDU1MgfSBmcm9tIFwic3JjL3V0aWxpdGllcy9jc3NEZWZpbml0aW9uc1wiO1xuaW1wb3J0IHsgaXNUYXNrc1BsdWdpbiB9IGZyb20gXCJzcmMvdXRpbGl0aWVzL2VsZW1lbnRSZW5kZXJUeXBlUGFyc2VyXCI7XG5pbXBvcnQgeyBSZWdpb25FcnJvck1hbmFnZXIgfSBmcm9tIFwic3JjL2RvbV9tYW5hZ2VyL3JlZ2lvbkVycm9yTWFuYWdlclwiO1xuaW1wb3J0IHsgUmVnaW9uVHlwZSB9IGZyb20gXCJzcmMvdXRpbGl0aWVzL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IHBhcnNlQ29sQnJlYWtFcnJvclR5cGUgfSBmcm9tIFwic3JjL3V0aWxpdGllcy9lcnJvck1lc3NhZ2VcIjtcbmltcG9ydCB7IGNoZWNrRm9yUGFyYWdyYXBoSW5uZXJDb2xFbmRUYWcsIGNvbnRhaW5zQ29sRW5kVGFnLCBmaW5kRW5kVGFnQ2xvc2VzdFRvRW5kIH0gZnJvbSBcInNyYy91dGlsaXRpZXMvdGV4dFBhcnNlclwiO1xuaW1wb3J0IHsgZ2V0UHJldmlld0xlYWZGcm9tRmlsZVBhdGggfSBmcm9tIFwic3JjL3V0aWxpdGllcy9vYnNpVXRpbHNcIjtcbmltcG9ydCB7IE1DTV9TZXR0aW5nc01hbmFnZXIgfSBmcm9tIFwic3JjL3BsdWdpblNldHRpbmdzXCI7XG5cbmNvbnN0IENBQ0hFX01BWF9ERUxUQV9USU1FX01TID0gMiAqIDYwICogMTAwMDsgLy8gMm1cblxuaW50ZXJmYWNlIGNhY2hlRGF0YSB7XG4gICAgdGltZXN0YW1wOiBudW1iZXIsXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnQsXG4gICAgcmVnaW9uTWFuYWdlcjogUmVnaW9uTWFuYWdlcixcbiAgICBlcnJvclJvb3RFbDogSFRNTERpdkVsZW1lbnQsXG4gICAgY2FjaGVTZXR0aW5nczogTXVsdGlDb2x1bW5TZXR0aW5ncyxcbiAgICBwbHVnaW5TZXR0aW5nc1VwZGF0ZVRpbWVzdGFtcDogbnVtYmVyXG59XG5cbmxldCBsaXZlUHJldmlld0VsZW1lbnRDYWNoZTogTWFwPHN0cmluZywgY2FjaGVEYXRhPiA9IG5ldyBNYXAoKVxuYXN5bmMgZnVuY3Rpb24gY2xlYXJDYWNoZShza2lwS2V5OiBzdHJpbmcgPSBcIlwiKSB7XG5cbiAgICBsZXQgaW5kZXggPSAtMTtcbiAgICBsZXQga2V5cyA9IEFycmF5LmZyb20obGl2ZVByZXZpZXdFbGVtZW50Q2FjaGUua2V5cygpKVxuICAgIGZvcihsZXQga2V5IG9mIGtleXMpIHtcbiAgICAgICAgaW5kZXgrK1xuXG4gICAgICAgIGlmKGtleSA9PT0gc2tpcEtleSkge1xuICAgICAgICAgICAgLy8gY29uc29sZS5kZWJ1ZyhgRWxlbWVudDogJHtpbmRleH0gfCBTa2lwcGluZyBrZXk6ICR7a2V5LnNwbGl0KFwiIDogXCIpWzBdfWApXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKGxpdmVQcmV2aWV3RWxlbWVudENhY2hlLmhhcyhrZXkpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gXG5cbiAgICAgICAgbGV0IHZhbCA9IGxpdmVQcmV2aWV3RWxlbWVudENhY2hlLmdldChrZXkpXG5cbiAgICAgICAgbGV0IGRlbHRhVGltZU1TID0gRGF0ZS5ub3coKSAtIHZhbC50aW1lc3RhbXBcbiAgICAgICAgaWYoKHZhbC5lbGVtZW50LnBhcmVudE5vZGUgPT09IG51bGwgfHwgdmFsLmVsZW1lbnQucGFyZW50Tm9kZS5wYXJlbnROb2RlID09PSBudWxsKSAmJiBkZWx0YVRpbWVNUyA+IENBQ0hFX01BWF9ERUxUQV9USU1FX01TKSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmRlYnVnKGBjYWNoZSBkZWx0YTogJHtkZWx0YVRpbWVNU30gPiAke0NBQ0hFX01BWF9ERUxUQV9USU1FX01TfSBvciAyIG1pbnV0ZXMuYClcbiAgICAgICAgICAgIGxpdmVQcmV2aWV3RWxlbWVudENhY2hlLmRlbGV0ZShrZXkpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZih2YWwuZWxlbWVudC5wYXJlbnROb2RlID09IG51bGwgfHwgdmFsLmVsZW1lbnQucGFyZW50Tm9kZS5wYXJlbnROb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIGNvbnNvbGUuZGVidWcoYEVsZW1lbnQgJHtpbmRleH0gbnVsbCBidXQgbm90IHJlbW92aW5nIGZyb20gY2FjaGUgeWV0LiBcXG5FbGVtZW50IGZpbGUgcGF0aDogJHtrZXkuc3BsaXQoXCIgOiBcIilbMF19IFxcblBhdGggRWxhcHNlZCB0aW1lOiAke01hdGguZmxvb3IoZGVsdGFUaW1lTVMgLyAxMDAwKX1gKVxuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyTGl2ZVByZXZpZXdDYWNoZSgpIHtcbiAgICBjbGVhckNhY2hlKClcbn1cblxuZXhwb3J0IGNsYXNzIE11bHRpQ29sdW1uTWFya2Rvd25fTGl2ZVByZXZpZXdfV2lkZ2V0IGV4dGVuZHMgV2lkZ2V0VHlwZSB7XG5cbiAgICBjb250ZW50RGF0YTogc3RyaW5nO1xuICAgIHRlbXBQYXJlbnQ6IEhUTUxEaXZFbGVtZW50O1xuICAgIGRvbUxpc3Q6IERPTU9iamVjdFtdID0gW107XG4gICAgc2V0dGluZ3NUZXh0OiBzdHJpbmc7XG4gICAgcmVnaW9uU2V0dGluZ3M6IE11bHRpQ29sdW1uU2V0dGluZ3MgPSBnZXREZWZhdWx0TXVsdGlDb2x1bW5TZXR0aW5ncygpO1xuICAgIHJlZ2lvbk1hbmFnZXI6IFJlZ2lvbk1hbmFnZXI7XG4gICAgc291cmNlRmlsZTogVEZpbGU7XG4gICAgc291cmNlUGF0aDogc3RyaW5nID0gXCJcIjtcbiAgICBlbGVtZW50Q2FjaGVJRDogc3RyaW5nO1xuICAgIGVycm9yUm9vdEVsOiBIVE1MRGl2RWxlbWVudDtcbiAgICBcbiAgICBjb25zdHJ1Y3RvcihvcmlnaW5hbFRleHQ6IHN0cmluZywgY29udGVudERhdGE6IHN0cmluZywgdXNlclNldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzLCBzb3VyY2VGaWxlOiBURmlsZSwgc2V0dGluZ3NUZXh0OiBzdHJpbmcgPSBcIlwiLCByZWdpb25UeXBlOiBSZWdpb25UeXBlKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuY29udGVudERhdGEgPSBjb250ZW50RGF0YTtcbiAgICAgICAgdGhpcy5zZXR0aW5nc1RleHQgPSBzZXR0aW5nc1RleHQ7XG4gICAgICAgIHRoaXMuc291cmNlRmlsZSA9IHNvdXJjZUZpbGU7XG5cbiAgICAgICAgaWYodGhpcy5zb3VyY2VGaWxlID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVsZW1lbnRDYWNoZUlEID0gYCR7dGhpcy5zb3VyY2VGaWxlLnBhdGh9IDogJHt0aGlzLmNvbnRlbnREYXRhfWA7XG5cbiAgICAgICAgaWYodGhpcy5zb3VyY2VGaWxlKSB7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZVBhdGggPSBzb3VyY2VGaWxlLnBhdGg7XG4gICAgICAgIH1cblxuICAgICAgICBpZih1c2VyU2V0dGluZ3MgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucmVnaW9uU2V0dGluZ3MgPSB1c2VyU2V0dGluZ3M7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZXJyb3JNYW5hZ2VyID0gbmV3IFJlZ2lvbkVycm9yTWFuYWdlcihjcmVhdGVEaXYoKSk7XG4gICAgICAgIGlmKHJlZ2lvblR5cGUgPT09IFwiQ09ERUJMT0NLXCIpIHtcbiAgICAgICAgICAgIGVycm9yTWFuYWdlci5hZGRFcnJvck1lc3NhZ2UoXCJUaGUgY29kZWJsb2NrIHJlZ2lvbiBzdGFydCBzeW50YXggaGFzIGJlZW4gZGVwcmljYXRlZC4gUGxlYXNlIG1hbnVhbGx5IHVwZGF0ZSB0byB0aGUgY3VycmVudCBzeW50YXggZGVmaW5lZCBpbiB0aGUgUmVhZE1lLCBydW4gdGhlIFxcXCJGaXggTXVsdGktQ29sdW1uIFN5bnRheCBpbiBDdXJyZW50IEZpbGVcXFwiIGZyb20gdGhlIENvbW1hbmQgUGFsZXR0ZSwgb3IgdXNlIHRoZSBcXFwiVXBkYXRlIERlcHJpY2F0ZWQgU3ludGF4XFxcIiBjb21tYW5kIGZvdW5kIGluIHRoZSBwbHVnaW4gc2V0dGluZ3Mgd2luZG93LiBZb3UgbXVzdCByZWxvYWQgdGhlIGZpbGUgZm9yIGNoYW5nZXMgdG8gdGFrZSBlZmZlY3QuXCIpXG4gICAgICAgIH1cblxuICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgZnVuY3Rpb24gaGFzQmFkQ29udGVudEJldHdlZW4oY29udGVudEJldHdlZW46IHN0cmluZyk6IGJvb2xlYW4ge1xuXG4gICAgICAgICAgICAgICAgbGV0IHJlZ2V4UmVzdWx0ID0gbmV3IFJlZ0V4cChcIigoPzogKlxcbil7Nix9KVwiKS5leGVjKGNvbnRlbnRCZXR3ZWVuKVxuICAgICAgICAgICAgICAgIGlmKHJlZ2V4UmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiRm91bmQgYXQgbGVhc3QgNiBlbXB0eSBsaW5lcy5cIilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlZ2V4UmVzdWx0ID0gL14oPzooPyEgKiQpKD8hICotLS0gKiQpKS4rJC9tZy5leGVjKGNvbnRlbnRCZXR3ZWVuKTtcbiAgICAgICAgICAgICAgICBpZihyZWdleFJlc3VsdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBmaWxlVGV4dCA9IGF3YWl0IHNvdXJjZUZpbGUudmF1bHQuY2FjaGVkUmVhZChzb3VyY2VGaWxlKTtcbiAgICAgICAgICAgIGZpbGVUZXh0ID0gZmlsZVRleHQucmVwbGFjZShvcmlnaW5hbFRleHQsIFwiIyMjLS1TVEFSVF9IRVJFLS0jIyNcIilcblxuICAgICAgICAgICAgbGV0IHJlZ2V4UmVzdWx0ID0gbmV3IFJlZ0V4cChcIiMjIy0tU1RBUlRfSEVSRS0tIyMjXCIpLmV4ZWMoZmlsZVRleHQpXG4gICAgICAgICAgICBpZihyZWdleFJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZmlsZVRleHQgPSBmaWxlVGV4dC5zbGljZSgwLCByZWdleFJlc3VsdC5pbmRleCk7XG5cbiAgICAgICAgICAgIGxldCBuZXh0U3RhcnRUYWcgPSBmaW5kRW5kVGFnQ2xvc2VzdFRvRW5kKGZpbGVUZXh0KTtcbiAgICAgICAgICAgIGlmKG5leHRTdGFydFRhZy5mb3VuZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBlcnJvclN0cmluZyA9IGhhc0JhZENvbnRlbnRCZXR3ZWVuKGZpbGVUZXh0LnNsaWNlKG5leHRTdGFydFRhZy5lbmRQb3NpdGlvbikpXG4gICAgICAgICAgICBpZihlcnJvclN0cmluZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGVycm9yTWFuYWdlci5hZGRXYXJuaW5nTWVzc2FnZShcIkRldGVjdGVkIHBvc3NpYmxlIGlzc3VlIHdpdGggdGhlIGNvbnRlbnQgYmV0d2VlbiB0aGlzIHJlZ2lvbiBhbmQgdGhlIHJlZ2lvbiBhYm92ZS4gXFxcbiAgICAgICAgICAgIElmIHlvdSBleHBlcmllbmNlIHBhZ2UganVtcGluZyB3aGVuIGNsaWNraW5nIHdpdGhpbiB0aGlzIGRvY3VtZW50LCBwbGVhc2UgbWFrZSBzdXJlIHRoZXJlIGFyZSBhdCBsZWFzdCA2IGJsYW5rIFxcXG4gICAgICAgICAgICBsaW5lcyBvciBzb21lIGZvcm0gb2YgdGV4dCBjb250ZW50IGJldHdlZW4gdGhlIHR3byByZWdpb25zLiBUaGlzIGlzIGEga25vd24gaXNzdWUgdGhhdCBpcyB1bmRlciBpbnZlc3RpZ2F0aW9uLiBTb3JyeSBmb3IgdGhlIGluY29udmVuaWVuY2UuXCIpXG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgaWYobGl2ZVByZXZpZXdFbGVtZW50Q2FjaGUuaGFzKHRoaXMuZWxlbWVudENhY2hlSUQpKSB7XG4gICAgICAgICAgICBsZXQgY2FjaGUgPSBsaXZlUHJldmlld0VsZW1lbnRDYWNoZS5nZXQodGhpcy5lbGVtZW50Q2FjaGVJRClcbiAgICAgICAgICAgIGxldCByZWdpb25NYW5hZ2VyID0gY2FjaGUucmVnaW9uTWFuYWdlclxuICAgICAgICAgICAgbGV0IHJlZ2lvblNldHRpbmdzRXF1YWwgPSBNQ1NldHRpbmdzX2lzRXF1YWwodXNlclNldHRpbmdzLCBjYWNoZS5jYWNoZVNldHRpbmdzKVxuICAgICAgICAgICAgbGV0IHBsdWdpblNldHRpbmdzVXBkYXRlZCA9IE1DTV9TZXR0aW5nc01hbmFnZXIuc2hhcmVkLmxhc3RVcGRhdGVUaW1lc3RhbXAgPiBjYWNoZS5wbHVnaW5TZXR0aW5nc1VwZGF0ZVRpbWVzdGFtcFxuICAgICAgICAgICAgaWYocmVnaW9uTWFuYWdlciAmJiByZWdpb25TZXR0aW5nc0VxdWFsID09PSB0cnVlICYmIHBsdWdpblNldHRpbmdzVXBkYXRlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZWdpb25NYW5hZ2VyLnVwZGF0ZUVycm9yTWFuYWdlcihlcnJvck1hbmFnZXIsIGNhY2hlLmVycm9yUm9vdEVsKTtcblxuICAgICAgICAgICAgICAgIGxldCB1c2VMaXZlUHJldmlld0NhY2hlID0gTUNNX1NldHRpbmdzTWFuYWdlci5zaGFyZWQudXNlTGl2ZVByZXZpZXdDYWNoZTtcbiAgICAgICAgICAgICAgICBsZXQgZmlsZUxlYWYgPSBnZXRQcmV2aWV3TGVhZkZyb21GaWxlUGF0aChhcHAud29ya3NwYWNlLCB0aGlzLnNvdXJjZUZpbGUucGF0aClcbiAgICAgICAgICAgICAgICBpZih1c2VMaXZlUHJldmlld0NhY2hlICYmIGZpbGVMZWFmID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxpdmVQcmV2aWV3RWxlbWVudENhY2hlLmRlbGV0ZSh0aGlzLmVsZW1lbnRDYWNoZUlEKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbmRlciB0aGUgbWFya2Rvd24gY29udGVudCB0byBvdXIgdGVtcCBwYXJlbnQgZWxlbWVudC5cbiAgICAgICAgdGhpcy50ZW1wUGFyZW50ID0gY3JlYXRlRGl2KCk7XG4gICAgICAgIGxldCBlbGVtZW50TWFya2Rvd25SZW5kZXJlciA9IG5ldyBNYXJrZG93blJlbmRlckNoaWxkKHRoaXMudGVtcFBhcmVudCk7XG4gICAgICAgIE1hcmtkb3duUmVuZGVyZXIucmVuZGVyTWFya2Rvd24odGhpcy5jb250ZW50RGF0YSwgdGhpcy50ZW1wUGFyZW50LCB0aGlzLnNvdXJjZVBhdGgsIGVsZW1lbnRNYXJrZG93blJlbmRlcmVyKTtcblxuICAgICAgICBsZXQgcHJldmlvdXNUZXh0ID0gXCJcIjtcbiAgICAgICAgbGV0IHdvcmtpbmdUZXh0ID0gb3JpZ2luYWxUZXh0O1xuICAgICAgICAvLyB0YWtlIGFsbCBlbGVtZW50cywgaW4gb3JkZXIsIGFuZCBjcmVhdGUgb3VyIERPTSBsaXN0LlxuICAgICAgICBsZXQgYXJyID0gQXJyYXkuZnJvbSh0aGlzLnRlbXBQYXJlbnQuY2hpbGRyZW4pO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgICAgICBsZXQgZWwgPSB0aGlzLmZpeEVsZW1lbnRSZW5kZXIoYXJyW2ldKTtcblxuICAgICAgICAgICAgbGV0IGRvbU9iamVjdCA9IG5ldyBET01PYmplY3QoZWwgYXMgSFRNTEVsZW1lbnQsIFtcIlwiXSlcbiAgICAgICAgICAgIHRoaXMuZG9tTGlzdC5wdXNoKGRvbU9iamVjdCk7XG5cbiAgICAgICAgICAgIGxldCBuZXdEYXRhID0gc2xpY2VXb3JraW5nVGV4dFRvRWwoZG9tT2JqZWN0LCBwcmV2aW91c1RleHQsIHdvcmtpbmdUZXh0KVxuICAgICAgICAgICAgcHJldmlvdXNUZXh0ID0gbmV3RGF0YS5wcmV2aW91c1RleHQ7XG4gICAgICAgICAgICB3b3JraW5nVGV4dCA9IG5ld0RhdGEud29ya2luZ1RleHQ7XG5cbiAgICAgICAgICAgIG5ld0RhdGEgPSBhdHRlbXB0VG9GaXhDaGVja2JveGVzKGRvbU9iamVjdCwgcHJldmlvdXNUZXh0LCB3b3JraW5nVGV4dCwgc291cmNlRmlsZSwgdGhpcy5lbGVtZW50Q2FjaGVJRClcbiAgICAgICAgICAgIHByZXZpb3VzVGV4dCA9IG5ld0RhdGEucHJldmlvdXNUZXh0O1xuICAgICAgICAgICAgd29ya2luZ1RleHQgPSBuZXdEYXRhLndvcmtpbmdUZXh0O1xuXG4gICAgICAgICAgICB3b3JraW5nVGV4dCA9IGNoZWNrRm9yQ29sdW1uQnJlYWtFcnJvcnMoZG9tT2JqZWN0LCBwcmV2aW91c1RleHQsIHdvcmtpbmdUZXh0LCBlcnJvck1hbmFnZXIpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdXAgdGhlIHJlZ2lvbiBtYW5hZ2VyIGRhdGEgYmVmb3JlIHRoZW4gY3JlYXRpbmcgb3VyIHJlZ2lvbiBtYW5hZ2VyLlxuICAgICAgICBsZXQgcmVnaW9uRGF0YTogUmVnaW9uTWFuYWdlckRhdGEgPSB7XG4gICAgICAgICAgICBkb21MaXN0OiB0aGlzLmRvbUxpc3QsXG4gICAgICAgICAgICBkb21PYmplY3RNYXA6IG5ldyBNYXA8c3RyaW5nLCBET01PYmplY3Q+KCksXG4gICAgICAgICAgICByZWdpb25QYXJlbnQ6IGNyZWF0ZURpdigpLFxuICAgICAgICAgICAgZmlsZU1hbmFnZXI6IG51bGwsXG4gICAgICAgICAgICByZWdpb25hbFNldHRpbmdzOiB0aGlzLnJlZ2lvblNldHRpbmdzLFxuICAgICAgICAgICAgcmVnaW9uS2V5OiBnZXRVSUQoKSxcbiAgICAgICAgICAgIHJvb3RFbGVtZW50OiBjcmVhdGVEaXYoKSxcbiAgICAgICAgICAgIGVycm9yTWFuYWdlcjogZXJyb3JNYW5hZ2VyXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gRmluYWxseSBzZXR1cCB0aGUgdHlwZSBvZiByZWdpb24gbWFuYWdlciByZXF1aXJlZC5cbiAgICAgICAgaWYgKHRoaXMucmVnaW9uU2V0dGluZ3MubnVtYmVyT2ZDb2x1bW5zID09PSAxKSB7XG4gICAgICAgICAgICB0aGlzLnJlZ2lvblNldHRpbmdzID0gcGFyc2VTaW5nbGVDb2x1bW5TZXR0aW5ncyh0aGlzLnNldHRpbmdzVGV4dCwgdGhpcy5yZWdpb25TZXR0aW5ncyk7XG4gICAgICAgICAgICB0aGlzLnJlZ2lvbk1hbmFnZXIgPSBuZXcgU2luZ2xlQ29sdW1uUmVnaW9uTWFuYWdlcihyZWdpb25EYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnJlZ2lvblNldHRpbmdzLmF1dG9MYXlvdXQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHRoaXMucmVnaW9uTWFuYWdlciA9IG5ldyBBdXRvTGF5b3V0UmVnaW9uTWFuYWdlcihyZWdpb25EYXRhLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmVnaW9uTWFuYWdlciA9IG5ldyBTdGFuZGFyZE11bHRpQ29sdW1uUmVnaW9uTWFuYWdlcihyZWdpb25EYXRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNsZWFyQ2FjaGUodGhpcy5lbGVtZW50Q2FjaGVJRClcbiAgICB9XG5cbiAgICBmaXhFbGVtZW50UmVuZGVyKGVsOiBFbGVtZW50KTogRWxlbWVudCB7XG5cbiAgICAgICAgbGV0IGZpeGVkRWwgPSBmaXhJbWFnZVJlbmRlcihlbCwgdGhpcy5zb3VyY2VQYXRoKTtcbiAgICAgICAgZml4ZWRFbCA9IGZpeFBERlJlbmRlcihmaXhlZEVsLCB0aGlzLnNvdXJjZVBhdGgpO1xuICAgICAgICBmaXhlZEVsID0gZml4RmlsZUVtYmVkKGZpeGVkRWwsIHRoaXMuc291cmNlUGF0aCk7XG4gICAgICAgIGZpeGVkRWwgPSBmaXhUYWJsZVJlbmRlcihmaXhlZEVsKTtcbiAgICAgICAgZml4ZWRFbCA9IGZpeFVuU3VwcG9ydGVkUmVuZGVyKGZpeGVkRWwpO1xuICAgICAgICByZXR1cm4gZml4ZWRFbDtcbiAgICB9XG5cbiAgICB0b0RPTSgpIHtcblxuICAgICAgICBsZXQgdXNlTGl2ZVByZXZpZXdDYWNoZSA9IE1DTV9TZXR0aW5nc01hbmFnZXIuc2hhcmVkLnVzZUxpdmVQcmV2aWV3Q2FjaGU7XG4gICAgICAgIGxldCBmaWxlTGVhZiA9IGdldFByZXZpZXdMZWFmRnJvbUZpbGVQYXRoKGFwcC53b3Jrc3BhY2UsIHRoaXMuc291cmNlRmlsZS5wYXRoKVxuICAgICAgICBpZih1c2VMaXZlUHJldmlld0NhY2hlICYmIFxuICAgICAgICAgICAgbGl2ZVByZXZpZXdFbGVtZW50Q2FjaGUuaGFzKHRoaXMuZWxlbWVudENhY2hlSUQpICYmXG4gICAgICAgICAgICBmaWxlTGVhZiA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGxpdmVQcmV2aWV3RWxlbWVudENhY2hlLmdldCh0aGlzLmVsZW1lbnRDYWNoZUlEKS5lbGVtZW50XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgb3VyIGVsZW1lbnQgdG8gaG9sZCBhbGwgb2YgdGhlIGxpdmUgcHJldmlldyBlbGVtZW50cy5cbiAgICAgICAgbGV0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgZWwuY2xhc3NOYW1lID0gXCJtY20tY20tcHJldmlld1wiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGb3Igc2l0dWF0aW9ucyB3aGVyZSB3ZSBuZWVkIHRvIGtub3cgdGhlIHJlbmRlcmVkIGhlaWdodCwgQXV0b0xheW91dCwgXG4gICAgICAgICAqIHRoZSBlbGVtZW50IG11c3QgYmUgcmVuZGVyZWQgb250byB0aGUgc2NyZWVuIHRvIGdldCB0aGUgaW5mbywgZXZlbiBpZiBcbiAgICAgICAgICogb25seSBmb3IgYSBtb21lbnQuIEhlcmUgd2UgYXR0ZW1wdCB0byBnZXQgYSBsZWFmIGZyb20gdGhlIGFwcCBzbyB3ZSBcbiAgICAgICAgICogY2FuIGJyaWVmbHkgYXBwZW5kIG91ciBlbGVtZW50LCBjaGVjayBhbnkgZGF0YSBpZiByZXF1aXJlZCwgYW5kIHRoZW5cbiAgICAgICAgICogcmVtb3ZlIGl0LlxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IGF1dG9sYXlvdXRMZWFmOiBXb3Jrc3BhY2VMZWFmID0gbnVsbDtcbiAgICAgICAgaWYgKGFwcCkge1xuICAgICAgICAgICAgbGV0IGxlYXZlcyA9IGFwcC53b3Jrc3BhY2UuZ2V0TGVhdmVzT2ZUeXBlKFwibWFya2Rvd25cIik7XG4gICAgICAgICAgICBpZiAobGVhdmVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBhdXRvbGF5b3V0TGVhZiA9IGxlYXZlc1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnJlZ2lvbk1hbmFnZXIpIHtcblxuICAgICAgICAgICAgdGhpcy5lcnJvclJvb3RFbCA9IGVsLmNyZWF0ZURpdigpXG4gICAgICAgICAgICBsZXQgY29udGVudEVsZW1lbnQgPSBlbC5jcmVhdGVEaXYoKVxuICAgICAgICAgICAgdGhpcy5yZWdpb25NYW5hZ2VyLmdldFJlZ2lvbkRhdGEoKS5lcnJvck1hbmFnZXIuc2V0UmVnaW9uUm9vdEVsZW1lbnQodGhpcy5lcnJvclJvb3RFbClcblxuICAgICAgICAgICAgbGV0IHJlcXVpcmVVbmxvYWQgPSBmYWxzZVxuICAgICAgICAgICAgaWYgKGF1dG9sYXlvdXRMZWFmICYmIHRoaXMucmVnaW9uTWFuYWdlciBpbnN0YW5jZW9mIEF1dG9MYXlvdXRSZWdpb25NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgYXV0b2xheW91dExlYWYudmlldy5jb250YWluZXJFbC5hcHBlbmRDaGlsZChlbCk7XG4gICAgICAgICAgICAgICAgcmVxdWlyZVVubG9hZCA9IHRydWVcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZWdpb25NYW5hZ2VyLnJlbmRlclJlZ2lvbkVsZW1lbnRzVG9MaXZlUHJldmlldyhjb250ZW50RWxlbWVudCk7XG4gICAgICAgICAgICBmb3IobGV0IGRvbU9iaiBvZiB0aGlzLnJlZ2lvbk1hbmFnZXIuZ2V0UmVnaW9uRGF0YSgpLmRvbUxpc3QpIHtcbiAgICAgICAgICAgICAgICBmaXhMaXN0Q1NTKGRvbU9iai5vcmlnaW5hbEVsZW1lbnQpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXF1aXJlVW5sb2FkKSB7XG4gICAgICAgICAgICAgICAgYXV0b2xheW91dExlYWYudmlldy5jb250YWluZXJFbC5yZW1vdmVDaGlsZChlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmaXhFeHRlcm5hbExpbmtzKGVsKVxuXG4gICAgICAgIGxpdmVQcmV2aWV3RWxlbWVudENhY2hlLnNldCh0aGlzLmVsZW1lbnRDYWNoZUlELCB7XG4gICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICBlbGVtZW50OiBlbCxcbiAgICAgICAgICAgIHJlZ2lvbk1hbmFnZXI6IHRoaXMucmVnaW9uTWFuYWdlcixcbiAgICAgICAgICAgIGVycm9yUm9vdEVsOiB0aGlzLmVycm9yUm9vdEVsLFxuICAgICAgICAgICAgY2FjaGVTZXR0aW5nczogdGhpcy5yZWdpb25TZXR0aW5ncyxcbiAgICAgICAgICAgIHBsdWdpblNldHRpbmdzVXBkYXRlVGltZXN0YW1wOiBNQ01fU2V0dGluZ3NNYW5hZ2VyLnNoYXJlZC5sYXN0VXBkYXRlVGltZXN0YW1wXG4gICAgICAgIH0pXG5cbiAgICAgICAgcmV0dXJuIGVsO1xuICAgIH1cblxuICAgIGZpeEVsZW1lbnRDU1MoZG9tT2JqZWN0OiBET01PYmplY3QpIHtcbiAgICAgICAgZml4TGlzdENTUyhkb21PYmplY3Qub3JpZ2luYWxFbGVtZW50KTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNdWx0aUNvbHVtbk1hcmtkb3duX0RlZmluZWRTZXR0aW5nc19MaXZlUHJldmlld19XaWRnZXQgZXh0ZW5kcyBXaWRnZXRUeXBlIHtcblxuICAgIGNvbnRlbnREYXRhOiBzdHJpbmc7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb250ZW50RGF0YTogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpcy5jb250ZW50RGF0YSA9IGNvbnRlbnREYXRhO1xuICAgIH1cblxuICAgIHRvRE9NKCkge1xuICAgICAgICAvLyBDcmVhdGUgb3VyIGVsZW1lbnQgdG8gaG9sZCBhbGwgb2YgdGhlIGxpdmUgcHJldmlldyBlbGVtZW50cy5cbiAgICAgICAgbGV0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgZWwuY2xhc3NOYW1lID0gXCJtY20tY20tc2V0dGluZ3MtcHJldmlld1wiO1xuXG4gICAgICAgIGxldCBsYWJlbERpdiA9IGVsLmNyZWF0ZURpdigpXG4gICAgICAgIGxldCBsYWJlbCA9IGxhYmVsRGl2LmNyZWF0ZVNwYW4oe1xuICAgICAgICAgICAgY2xzOiBcIm1jbS1jb2wtc2V0dGluZ3MtcHJldmlld1wiXG4gICAgICAgIH0pXG4gICAgICAgIGxhYmVsLnRleHRDb250ZW50ID0gXCJDb2x1bW4gU2V0dGluZ3M6XCI7XG5cbiAgICAgICAgbGV0IGxpc3QgPSBlbC5jcmVhdGVFbChcInVsXCIpXG4gICAgICAgIGxldCBsaW5lcyA9IHRoaXMuY29udGVudERhdGEuc3BsaXQoXCJcXG5cIilcbiAgICAgICAgZm9yKGxldCBpID0gMTsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgICAgbGV0IGl0ZW0gPSBsaXN0LmNyZWF0ZUVsKFwibGlcIilcbiAgICAgICAgICAgIGl0ZW0udGV4dENvbnRlbnQgPSBsaW5lc1tpXVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVsO1xuICAgIH1cbn1cblxuY29uc3QgT0JTSURJQU5fTElWRVBSRVZJRVdfVEFCTEVfQ0xBU1NFUyA9IFwiY20tZW1iZWQtYmxvY2sgbWFya2Rvd24tcmVuZGVyZWQgY20tdGFibGUtd2lkZ2V0IHNob3ctaW5kZW50YXRpb24tZ3VpZGVcIlxuZnVuY3Rpb24gZml4VGFibGVSZW5kZXIoZWw6IEVsZW1lbnQpOiBFbGVtZW50IHtcblxuICAgIGlmKGVsLnRhZ05hbWUgIT09IFwiVEFCTEVcIikge1xuICAgICAgICByZXR1cm4gZWw7XG4gICAgfVxuXG4gICAgbGV0IHBhcmVudERpdiA9IGNyZWF0ZURpdih7XG4gICAgICAgIFwiY2xzXCI6IE9CU0lESUFOX0xJVkVQUkVWSUVXX1RBQkxFX0NMQVNTRVNcbiAgICB9KVxuICAgIHBhcmVudERpdi5hcHBlbmRDaGlsZChlbCk7XG4gICAgcmV0dXJuIHBhcmVudERpdjtcbn1cblxuZnVuY3Rpb24gZml4RmlsZUVtYmVkKGVsOiBFbGVtZW50LCBzb3VyY2U6IHN0cmluZyk6IEVsZW1lbnQge1xuXG4gICAgbGV0IGVtYmVkID0gZ2V0RW1iZWQoZWwpO1xuICAgIGlmKGVtYmVkID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBlbDtcbiAgICB9XG5cbiAgICBsZXQgYWx0ID0gZW1iZWQuZ2V0QXR0cihcImFsdFwiKVxuICAgIGxldCBzcmMgPSBlbWJlZC5nZXRBdHRyKFwic3JjXCIpXG4gICAgaWYoc3JjID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBlbDtcbiAgICB9XG5cbiAgICBsZXQgZmlsZTogVEZpbGUgPSBhcHAubWV0YWRhdGFDYWNoZS5nZXRGaXJzdExpbmtwYXRoRGVzdChzcmMsIHNvdXJjZSk7XG4gICAgaWYoZmlsZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZWw7XG4gICAgfVxuICAgIFxuICAgIGlmKGlzTURFeHRlbnNpb24oZmlsZS5leHRlbnNpb24pID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gZWw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNyZWF0ZUxQRXJyb3JFbGVtZW50KFwiRmlsZSBlbWJlZHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gTGl2ZSBQcmV2aWV3LlxcblBsZWFzZSB1c2UgcmVhZGluZyBtb2RlIHRvIHZpZXcuXCIsIGFsdCwgc3JjKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlTFBFcnJvckVsZW1lbnQoZXJyb3JUZXh0OiBzdHJpbmcsIGFsdDogc3RyaW5nID0gXCJcIiwgc3JjOiBzdHJpbmcgPSBcIlwiKTogSFRNTERpdkVsZW1lbnQge1xuICAgIGxldCBlcnJvckVsID0gY3JlYXRlRGl2KHtcbiAgICAgICAgY2xzOiBcImludGVybmFsLWVtYmVkIG1hcmtkb3duLWVtYmVkIGlubGluZS1lbWJlZCBpcy1sb2FkZWRcIixcbiAgICAgICAgYXR0cjoge1xuICAgICAgICAgICAgXCJ0YWJpbmRleFwiOiBcIi0xXCIsXG4gICAgICAgICAgICBcImNvbnRlbnRlZGl0YWJsZVwiOiBcImZhbHNlXCJcbiAgICAgICAgfVxuICAgIH0pXG4gICAgZXJyb3JFbC5zZXRBdHRyKFwiYWx0XCIsIGFsdCk7XG4gICAgZXJyb3JFbC5zZXRBdHRyKFwic3JjXCIsIGBhcHA6Ly9vYnNpZGlhbi5tZC8ke3NyY31gKVxuICAgIGVycm9yRWwuYXBwZW5kQ2hpbGQoY3JlYXRlRGl2KFxuICAgICAgICB7XG4gICAgICAgICAgICBcImNsc1wiOiBcImVtYmVkLXRpdGxlIG1hcmtkb3duLWVtYmVkLXRpdGxlXCIsXG4gICAgICAgIH1cbiAgICApKTtcbiAgICBsZXQgY29udGVudEVsID0gZXJyb3JFbC5jcmVhdGVEaXYoe1xuICAgICAgICBcImNsc1wiOiBgbWFya2Rvd24tZW1iZWQtY29udGVudGAsXG4gICAgfSk7XG4gICAgbGV0IHBhcmFncmFwaCA9IGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuICAgICAgICBcImNsc1wiOiBgJHtNdWx0aUNvbHVtblN0eWxlQ1NTLlJlZ2lvbkVycm9yTWVzc2FnZX0sICR7TXVsdGlDb2x1bW5TdHlsZUNTUy5TbWFsbEZvbnR9YFxuICAgIH0pO1xuICAgIHBhcmFncmFwaC5pbm5lclRleHQgPSBlcnJvclRleHQ7XG5cbiAgICByZXR1cm4gZXJyb3JFbFxufVxuXG5mdW5jdGlvbiBmaXhQREZSZW5kZXIoZWw6IEVsZW1lbnQsIHNvdXJjZTogc3RyaW5nKTogRWxlbWVudCB7XG5cbiAgICBsZXQgZW1iZWQgPSBnZXRFbWJlZChlbCk7XG4gICAgaWYoZW1iZWQgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGVsO1xuICAgIH1cblxuICAgIGxldCBhbHQgPSBlbWJlZC5nZXRBdHRyKFwiYWx0XCIpXG4gICAgbGV0IHNyYyA9IGVtYmVkLmdldEF0dHIoXCJzcmNcIilcbiAgICBpZihzcmMgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGVsO1xuICAgIH1cblxuICAgIGxldCBmaWxlOiBURmlsZSA9IGFwcC5tZXRhZGF0YUNhY2hlLmdldEZpcnN0TGlua3BhdGhEZXN0KHNyYywgc291cmNlKTtcbiAgICBpZihmaWxlID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBlbDtcbiAgICB9XG4gICAgXG4gICAgaWYoaXNQREZFeHRlbnNpb24oZmlsZS5leHRlbnNpb24pID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gZWw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNyZWF0ZUxQRXJyb3JFbGVtZW50KFwiRHVlIHRvIGFuIHVwZGF0ZSB0byBPYnNpZGlhbidzIFBERiB2aWV3ZXIsIFBERiBlbWJlZHMgYXJlIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkLlxcblNvcnJ5IGZvciB0aGUgaW5jb252aWVuZW5jZS5cIiwgYWx0LCBzcmMpO1xufVxuXG5mdW5jdGlvbiBmaXhJbWFnZVJlbmRlcihlbDogRWxlbWVudCwgc291cmNlOiBzdHJpbmcpOiBFbGVtZW50IHtcblxuICAgIGxldCBlbWJlZCA9IGdldEVtYmVkKGVsKTtcbiAgICBpZihlbWJlZCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZWw7XG4gICAgfVxuXG4gICAgbGV0IGN1c3RvbVdpZHRoID0gZW1iZWQuYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oXCJ3aWR0aFwiKVxuICAgIGxldCBhbHQgPSBlbWJlZC5nZXRBdHRyKFwiYWx0XCIpXG4gICAgbGV0IHNyYyA9IGVtYmVkLmdldEF0dHIoXCJzcmNcIilcbiAgICBpZihzcmMgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGVsO1xuICAgIH1cblxuICAgIGxldCBmaWxlOiBURmlsZSA9IGFwcC5tZXRhZGF0YUNhY2hlLmdldEZpcnN0TGlua3BhdGhEZXN0KHNyYywgc291cmNlKTtcbiAgICBpZihmaWxlID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBlbDtcbiAgICB9XG4gICAgXG4gICAgLy8gSWYgdGhlIGxpbmsgc291cmNlIGlzIG5vdCBhbiBpbWFnZSB3ZSBkb250IHdhbnQgdG8gbWFrZSBhbnkgYWRqdXN0bWVudHMuXG4gICAgaWYoaXNJbWFnZUV4dGVuc2lvbihmaWxlLmV4dGVuc2lvbikgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBlbDtcbiAgICB9XG5cbiAgICBsZXQgZml4ZWRFbCA9IGNyZWF0ZURpdih7XG4gICAgICAgIGNsczogXCJpbnRlcm5hbC1lbWJlZCBpbWFnZS1lbWJlZCBpcy1sb2FkZWRcIixcbiAgICB9KVxuICAgIGZpeGVkRWwuc2V0QXR0cihcImFsdFwiLCBhbHQpO1xuXG4gICAgbGV0IHJlc291cmNlUGF0aCA9IGFwcC52YXVsdC5nZXRSZXNvdXJjZVBhdGgoZmlsZSk7XG4gICAgbGV0IGltYWdlID0gZml4ZWRFbC5jcmVhdGVFbChcImltZ1wiKTtcbiAgICBpbWFnZS5zZXRBdHRyKFwic3JjXCIsIHJlc291cmNlUGF0aCk7XG5cbiAgICBpZihjdXN0b21XaWR0aCAhPT0gbnVsbCkge1xuICAgICAgICBpbWFnZS5zZXRBdHRyKFwid2lkdGhcIiwgY3VzdG9tV2lkdGgudmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiBmaXhlZEVsO1xufVxuXG5mdW5jdGlvbiBmaXhFeHRlcm5hbExpbmtzKGVsOiBFbGVtZW50KTogRWxlbWVudCB7XG5cbiAgICBsZXQgaXRlbXMgPSBlbC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiZXh0ZXJuYWwtbGlua1wiKTtcbiAgICBmb3IobGV0IGxpbmtFbCBvZiBBcnJheS5mcm9tKGl0ZW1zKSkge1xuXG4gICAgICAgIGxldCBsaW5rID0gbGlua0VsIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBpZihsaW5rID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgbGluayA9PT0gbnVsbCApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBocmVmIGZyb20gdGhlIGxpbmsgYW5kIHNldHVwIGFuIGV2ZW50IGxpc3RlbmVyIHRvIG9wZW4gdGhlIGxpbmsgaW4gdGhlIGRlZmF1bHQgYnJvd3Nlci5cbiAgICAgICAgbGV0IGhyZWYgPSBsaW5rLmdldEF0dHIoXCJocmVmXCIpXG4gICAgICAgIGxpbmsucmVtb3ZlQXR0cmlidXRlKFwiaHJlZlwiKTtcblxuICAgICAgICBsaW5rLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZXYpID0+IHtcblxuICAgICAgICAgICAgd2luZG93Lm9wZW4oaHJlZik7IFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBpdGVtcyA9IGVsLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJpbnRlcm5hbC1saW5rXCIpO1xuICAgIGZvcihsZXQgbGlua0VsIG9mIEFycmF5LmZyb20oaXRlbXMpKSB7XG5cbiAgICAgICAgbGV0IGxpbmsgPSBsaW5rRWwgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIGlmKGxpbmsgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICBsaW5rID09PSBudWxsICkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW1vdmluZyB0aGUgaHJlZiBmcm9tIGludGVybmFsIGxpbmtzIGlzIGFsbCB0aGF0IHNlZW1zIHRvIGJlIHJlcXVpcmVkIHRvIGZpeCB0aGUgb25jbGljay5cbiAgICAgICAgbGluay5yZW1vdmVBdHRyaWJ1dGUoXCJocmVmXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBlbDtcbn1cblxuZnVuY3Rpb24gZ2V0RW1iZWQoZWw6IEVsZW1lbnQpOiBFbGVtZW50IHwgbnVsbCB7XG5cbiAgICAvLyBlbWJlZHMgY2FuIGVpdGhlciBiZSBhIDxkaXYgY2xhc3M9XCJpbnRlcm5hbC1lbWJlZFwiIG9yIDxwPjxkaXYgY2xhc3M9XCJpbnRlcm5hbC1lbWJlZFwiXG4gICAgLy8gZGVwZW5kaW5nIG9uIHRoZSBzeW50YXggdGhpcyBhZGRpdGlvbmFsIGNoZWNrIGlzIHRvIGZpeCBmYWxzZSBuZWdhdGl2ZXMgd2hlbiBlbWJlZCBpc1xuICAgIC8vIHRoZSBmaXJzdCBjYXNlLlxuICAgIGlmKGVsLmhhc0NsYXNzKFwiaW50ZXJuYWwtZW1iZWRcIikpIHtcbiAgICAgICAgcmV0dXJuIGVsO1xuICAgIH1cbiAgICBlbHNlIHtcblxuICAgICAgICBsZXQgaXRlbXMgPSBlbC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiaW50ZXJuYWwtZW1iZWRcIik7XG4gICAgICAgIGlmKGl0ZW1zLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zWzBdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzSW1hZ2VFeHRlbnNpb24oZXh0ZW5zaW9uOiBzdHJpbmcpOiBib29sZWFuIHtcblxuICAgIGV4dGVuc2lvbiA9IGV4dGVuc2lvbi50b0xvd2VyQ2FzZSgpO1xuICAgIHN3aXRjaChleHRlbnNpb24pIHtcbiAgICAgICAgY2FzZSBcInBuZ1wiOlxuICAgICAgICBjYXNlIFwianBnXCI6XG4gICAgICAgIGNhc2UgXCJqcGVnXCI6XG4gICAgICAgIGNhc2UgXCJnaWZcIjpcbiAgICAgICAgY2FzZSBcImJtcFwiOlxuICAgICAgICBjYXNlIFwic3ZnXCI6XG4gICAgICAgIGNhc2UgXCJ3ZWJwXCI6XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBpc1BERkV4dGVuc2lvbihleHRlbnNpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBleHRlbnNpb24udG9Mb3dlckNhc2UoKSA9PT0gXCJwZGZcIjtcbn1cblxuZnVuY3Rpb24gaXNNREV4dGVuc2lvbihleHRlbnNpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBleHRlbnNpb24udG9Mb3dlckNhc2UoKSA9PT0gXCJtZFwiO1xufVxuXG5mdW5jdGlvbiBmaXhMaXN0Q1NTKGVsOiBFbGVtZW50KTogRWxlbWVudCB7XG4gICAgaWYoZWwudGFnTmFtZSAhPT0gXCJVTFwiICYmIGVsLnRhZ05hbWUgIT09IFwiT0xcIikge1xuICAgICAgICByZXR1cm4gZWxcbiAgICB9XG4gICAgZWwucGFyZW50RWxlbWVudD8uYWRkQ2xhc3MoT2JzaWRpYW5TdHlsZUNTUy5SZW5kZXJlZE1hcmtkb3duKVxuICAgIHJldHVybiBlbDtcbn1cblxuZnVuY3Rpb24gZml4VW5TdXBwb3J0ZWRSZW5kZXIoZWw6IEVsZW1lbnQpOiBFbGVtZW50IHtcblxuICAgIGlmKGlzVGFza3NQbHVnaW4oZWwgYXMgSFRNTEVsZW1lbnQpKSB7XG5cbiAgICAgICAgaWYoTUNNX1NldHRpbmdzTWFuYWdlci5zaGFyZWQucmVuZGVySW5saW5lRWxFcnJvcnMgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGxldCBmaXhlZEVsID0gY3JlYXRlRGl2KClcbiAgICAgICAgICAgIGxldCBwYXJhZ3JhcGggPSBmaXhlZEVsLmNyZWF0ZUVsKFwicFwiLCB7XG4gICAgICAgICAgICAgICAgXCJjbHNcIjogYCR7TXVsdGlDb2x1bW5TdHlsZUNTUy5SZWdpb25FcnJvck1lc3NhZ2V9ICR7TXVsdGlDb2x1bW5TdHlsZUNTUy5TbWFsbEZvbnR9YFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwYXJhZ3JhcGguaW5uZXJUZXh0ID0gXCJUaGUgVGFza3MgcGx1Z2luIGlzIG5vdCBzdXBwb3J0ZWQgaW4gTGl2ZSBQcmV2aWV3LlxcblBsZWFzZSB1c2UgcmVhZGluZyBtb2RlLlwiXG4gICAgICAgICAgICByZXR1cm4gZml4ZWRFbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZWw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsO1xufVxuXG5mdW5jdGlvbiBjaGVja0ZvckNvbHVtbkJyZWFrRXJyb3JzKGRvbU9iamVjdDogRE9NT2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c1RleHQ6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ya2luZ1RleHQ6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNYW5hZ2VyOiBSZWdpb25FcnJvck1hbmFnZXIpOiBzdHJpbmcge1xuXG4gICAgaWYoZG9tT2JqZWN0LnRhZyAhPT0gRE9NT2JqZWN0VGFnLmNvbHVtbkJyZWFrICYmXG4gICAgICAgIGRvbU9iamVjdC5lbGVtZW50SXNDb2x1bW5CcmVhayA9PT0gRWxlbWVudENvbHVtbkJyZWFrVHlwZS5ub25lKSB7XG4gICAgICAgIHJldHVybiB3b3JraW5nVGV4dDtcbiAgICB9XG5cbiAgICBsZXQgcHJldkxpbmUgPSBwcmV2aW91c1RleHQuc3BsaXQoXCJcXG5cIikuc2xpY2UoLTIpLmpvaW4oXCJcXG5cIilcbiAgICBsZXQgY2hlY2tUZXh0ID0gd29ya2luZ1RleHQ7XG4gICAgaWYoY2hlY2tGb3JQYXJhZ3JhcGhJbm5lckNvbEVuZFRhZyhwcmV2TGluZSkpIHtcbiAgICAgICAgY2hlY2tUZXh0ID0gcHJldkxpbmUgKyB3b3JraW5nVGV4dFxuICAgIH1cblxuICAgIGxldCBuZXh0Q29sQnJlYWsgPSBjaGVja0ZvclBhcmFncmFwaElubmVyQ29sRW5kVGFnKGNoZWNrVGV4dClcbiAgICBpZihuZXh0Q29sQnJlYWsgPT09IG51bGwpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yLiBTb21ldGhpbmcgd2VudCB3cm9uZyBwYXJzaW5nIGNvbHVtbiBicmVhayBvdXQgb2YgdGV4dC5cIilcbiAgICAgICAgcmV0dXJuIHdvcmtpbmdUZXh0O1xuICAgIH1cblxuICAgIGxldCBzdGFydEluZGV4ID0gbmV4dENvbEJyZWFrLmluZGV4XG4gICAgbGV0IG1hdGNoTGVuZ3RoID0gbmV4dENvbEJyZWFrWzBdLmxlbmd0aFxuICAgIGxldCBlbmRJbmRleCA9IHN0YXJ0SW5kZXggKyBtYXRjaExlbmd0aFxuICAgIGxldCBtYXRjaFRleHQgPSBuZXh0Q29sQnJlYWtbMF0udHJpbSgpO1xuXG4gICAgbGV0IG5ld1dvcmtpbmdUZXh0ID0gY2hlY2tUZXh0LnNsaWNlKGVuZEluZGV4KVxuXG4gICAgLy8gQWxyZWFkeSBwYXJzZWQgY29sdW1uIGJyZWFrIHdhcm5pbmcuXG4gICAgaWYoZG9tT2JqZWN0LmVsZW1lbnRJc0NvbHVtbkJyZWFrICE9PSBFbGVtZW50Q29sdW1uQnJlYWtUeXBlLm5vbmUpIHtcblxuICAgICAgICBwYXJzZUNvbEJyZWFrRXJyb3JUeXBlKHtcbiAgICAgICAgICAgIGxpbmVBYm92ZTogXCJcIixcbiAgICAgICAgICAgIGxpbmVCZWxvdzogXCJcIixcbiAgICAgICAgICAgIG9iamVjdFRhZzogRE9NT2JqZWN0VGFnLm5vbmUsXG4gICAgICAgICAgICBjb2xCcmVha1R5cGU6IGRvbU9iamVjdC5lbGVtZW50SXNDb2x1bW5CcmVha1xuICAgICAgICB9LCBlcnJvck1hbmFnZXIpXG5cbiAgICAgICAgcmV0dXJuIG5ld1dvcmtpbmdUZXh0O1xuICAgIH1cblxuICAgIC8vIE5vdyB3ZSBoYXZlIGEgc3RhbmRhcmQgY29sdW1uIGJyZWFrIGJ1dCBkdWUgdG8gY2hhbmdlcyBpbiBvYnNpZGlhbiBwYXJzaW5nIG1heSBzdGlsbCBcbiAgICAvLyByZXF1aXJlIGRpc3BsYXlpbmcgYW4gZXJyb3IgbWVzc2FnZS5cbiAgICBsZXQgZW5kVGFnVGV4dCA9IGRvbU9iamVjdC5vcmlnaW5hbEVsZW1lbnQuaW5uZXJUZXh0XG5cbiAgICAvLyBtYWtlIHN1cmUgdGhlIGVsZW1lbnQgdGV4dCBpcyBhIGNvbHVtbiBicmVhayBqdXN0IHRvIGJlIHN1cmUuIFRoaXMgcmVhbGx5IHNob3VsZCBuZXZlciBmYWlsLlxuICAgIGlmKGNvbnRhaW5zQ29sRW5kVGFnKGVuZFRhZ1RleHQpID09PSBmYWxzZSkge1xuICAgICAgICAvLyBJZiBzb21ldGhpbmcgd2VudCB3cm9uZyBoZXJlIHdlIGNhbiBub3QgcHJvY2VlZCB3aXRoIHRoZSBuZXh0IHJlZ2V4IHVubGVzcyB0aGlzIHBhc3Nlcy5cbiAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHBhcnNpbmcgY29sdW1uLWJyZWFrIHRhZyBiYWNrIG91dCBvZiBlbGVtZW50IHRleHQuXCIsIGVuZFRhZ1RleHQpXG4gICAgICAgIHJldHVybiB3b3JraW5nVGV4dDtcbiAgICB9XG5cbiAgICAvLyBtYWtlIHN1cmUgdGhlIHRleHQgb2YgdGhlIGVsZW1lbnQgbWF0Y2hlIHRoZSBzeW50YXggb2Ygd2hhdCB3ZSBwYXJzZWQgZnJvbSB0aGUgdGV4dC5cbiAgICBpZihtYXRjaFRleHQgIT09IGVuZFRhZ1RleHQpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIG1hdGNoaW5nIG5leHQgY29sLWJyZWFrIHRvIGN1cnJlbnQgZWxlbWVudC4gQ2FuIG5vdCBjb250aW51ZS5cIilcbiAgICAgICAgcmV0dXJuIHdvcmtpbmdUZXh0O1xuICAgIH1cblxuICAgIC8vIFNsaWNlIG91dCB0aGUgMjAgY2hhcmFjdGVycyBiZWZvcmUgYW5kIGFmdGVyIHRoZSBjb2x1bW4gYnJlYWsgYW5kIHRoZW4gZ2V0IGp1c3RcbiAgICAvLyB0aGUgb25lIGxpbmUgYmVmb3JlIGFuZCBhZnRlciB0byBjaGVjayBpZiBlcnJvciBtZXNzYWdlIHJlcXVpcmVkLlxuICAgIGxldCBzdGFydEluZGV4T2Zmc2V0ID0gTWF0aC5jbGFtcChzdGFydEluZGV4IC0gMjAsIDAsIHN0YXJ0SW5kZXgpO1xuICAgIGxldCBlbmRJbmRleE9mZnNldCA9IE1hdGguY2xhbXAoZW5kSW5kZXggKyAyMCwgZW5kSW5kZXgsIGNoZWNrVGV4dC5sZW5ndGggLSAxKTtcbiAgICBcbiAgICBsZXQgYWRkaXRpb25hbFRleHQgPSBjaGVja1RleHQuc2xpY2Uoc3RhcnRJbmRleE9mZnNldCwgZW5kSW5kZXhPZmZzZXQpO1xuICAgIGxldCB0ZXh0QmVmb3JlID0gYWRkaXRpb25hbFRleHQuc2xpY2UoMCwgMjApO1xuICAgIGxldCB0ZXh0QWZ0ZXIgPSBhZGRpdGlvbmFsVGV4dC5zbGljZSgyMCArIG1hdGNoTGVuZ3RoKVxuICAgIHRleHRCZWZvcmUgPSB0ZXh0QmVmb3JlLnJlcGxhY2UoZW5kVGFnVGV4dCwgXCJcIilcblxuICAgIGxldCBsaW5lc0Fib3ZlID0gdGV4dEJlZm9yZS5zcGxpdChcIlxcblwiKS5maWx0ZXIoKHZhbCkgPT4ge1xuICAgICAgICByZXR1cm4gdmFsICE9PSBcIlwiXG4gICAgfSlcbiAgICBsZXQgbGluZXNCZWxvdyA9IHRleHRBZnRlci5zcGxpdChcIlxcblwiKS5maWx0ZXIoKHZhbCkgPT4ge1xuICAgICAgICByZXR1cm4gdmFsICE9PSBcIlwiXG4gICAgfSlcbiAgICBpZihsaW5lc0Fib3ZlLmxlbmd0aCA9PT0gMCAmJiBsaW5lc0JlbG93Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gd29ya2luZ1RleHRcbiAgICB9XG5cbiAgICBsZXQgbGluZUFib3ZlID0gbGluZXNBYm92ZS5sYXN0KClcbiAgICBsZXQgbGluZUJlbG93ID0gbGluZXNCZWxvdy5maXJzdCgpXG4gICAgcGFyc2VDb2xCcmVha0Vycm9yVHlwZSh7XG4gICAgICAgIGxpbmVBYm92ZTogbGluZUFib3ZlLFxuICAgICAgICBsaW5lQmVsb3c6IGxpbmVCZWxvdyxcbiAgICAgICAgb2JqZWN0VGFnOiBET01PYmplY3RUYWcuY29sdW1uQnJlYWssXG4gICAgICAgIGNvbEJyZWFrVHlwZTogRWxlbWVudENvbHVtbkJyZWFrVHlwZS5ub25lXG4gICAgfSwgZXJyb3JNYW5hZ2VyKVxuXG4gICAgcmV0dXJuIG5ld1dvcmtpbmdUZXh0XG59XG5cbmZ1bmN0aW9uIHNsaWNlV29ya2luZ1RleHRUb0VsKGRvbU9iamVjdDogRE9NT2JqZWN0LCBwcmV2aW91c1RleHQ6IHN0cmluZywgd29ya2luZ1RleHQ6IHN0cmluZyk6IHtwcmV2aW91c1RleHQ6IHN0cmluZywgd29ya2luZ1RleHQ6IHN0cmluZ30ge1xuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc1BhcmFncmFwaCgpIHtcbiAgICAgICAgbGV0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXiAqJHtlc2NhcGVSZWdFeHAoZG9tT2JqZWN0Lm9yaWdpbmFsRWxlbWVudC50ZXh0Q29udGVudCl9ICokYCwgXCJtXCIpXG4gICAgICAgIGxldCByZXN1bHQgPSByZWdleC5leGVjKHdvcmtpbmdUZXh0KVxuICAgICAgICBpZihyZXN1bHQpIHtcbiAgICAgICAgICAgIGxldCB1cGRhdGVkUHJldmlvdXMgPSBwcmV2aW91c1RleHQgKyB3b3JraW5nVGV4dC5zbGljZSgwLCByZXN1bHQuaW5kZXgpO1xuICAgICAgICAgICAgbGV0IHVwZGF0ZWRJdGVtVGV4dCA9IHdvcmtpbmdUZXh0LnNsaWNlKHJlc3VsdC5pbmRleCwgcmVzdWx0LmluZGV4ICsgcmVzdWx0WzBdLmxlbmd0aClcbiAgICAgICAgICAgIGxldCB1cGRhdGVkV29ya2luZ1RleHQgPSB3b3JraW5nVGV4dC5zbGljZShyZXN1bHQuaW5kZXgpXG4gICAgICAgICAgICByZXR1cm4geyBcbiAgICAgICAgICAgICAgICBwcmV2aW91c1RleHQ6IHVwZGF0ZWRQcmV2aW91cyxcbiAgICAgICAgICAgICAgICB3b3JraW5nVGV4dDogdXBkYXRlZFdvcmtpbmdUZXh0XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IFxuICAgICAgICAgICAgcHJldmlvdXNUZXh0OiBwcmV2aW91c1RleHQsXG4gICAgICAgICAgICB3b3JraW5nVGV4dDogd29ya2luZ1RleHRcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzSGVhZGVyKCkge1xuICAgICAgICBsZXQgY291bnQgPSBwYXJzZUludChkb21PYmplY3Qub3JpZ2luYWxFbGVtZW50LnRhZ05hbWUuc2xpY2UoMSkpXG4gICAgICAgIGxldCB0ZXh0ID0gJyMnLnJlcGVhdChjb3VudCk7XG5cbiAgICAgICAgbGV0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXiR7dGV4dH0gKyR7ZXNjYXBlUmVnRXhwKGRvbU9iamVjdC5vcmlnaW5hbEVsZW1lbnQudGV4dENvbnRlbnQpfSAqJGAsIFwibVwiKVxuXG4gICAgICAgIGxldCByZXN1bHQgPSByZWdleC5leGVjKHdvcmtpbmdUZXh0KVxuICAgICAgICBpZihyZXN1bHQpIHtcbiAgICAgICAgICAgIGxldCB1cGRhdGVkUHJldmlvdXMgPSBwcmV2aW91c1RleHQgKyB3b3JraW5nVGV4dC5zbGljZSgwLCByZXN1bHQuaW5kZXgpO1xuICAgICAgICAgICAgbGV0IHVwZGF0ZWRJdGVtVGV4dCA9IHdvcmtpbmdUZXh0LnNsaWNlKHJlc3VsdC5pbmRleCwgcmVzdWx0LmluZGV4ICsgcmVzdWx0WzBdLmxlbmd0aClcbiAgICAgICAgICAgIGxldCB1cGRhdGVkV29ya2luZ1RleHQgPSB3b3JraW5nVGV4dC5zbGljZShyZXN1bHQuaW5kZXgpXG4gICAgICAgICAgICByZXR1cm4geyBcbiAgICAgICAgICAgICAgICBwcmV2aW91c1RleHQ6IHVwZGF0ZWRQcmV2aW91cyxcbiAgICAgICAgICAgICAgICB3b3JraW5nVGV4dDogdXBkYXRlZFdvcmtpbmdUZXh0XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IFxuICAgICAgICAgICAgcHJldmlvdXNUZXh0OiBwcmV2aW91c1RleHQsXG4gICAgICAgICAgICB3b3JraW5nVGV4dDogd29ya2luZ1RleHRcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZihkb21PYmplY3Qub3JpZ2luYWxFbGVtZW50LnRhZ05hbWUgPT09IFwiUFwiKSB7XG4gICAgICAgIHJldHVybiBwcm9jZXNzUGFyYWdyYXBoKCk7XG4gICAgfVxuXG4gICAgaWYoZG9tT2JqZWN0Lm9yaWdpbmFsRWxlbWVudC50YWdOYW1lID09PSBcIkgxXCIgfHxcbiAgICAgICBkb21PYmplY3Qub3JpZ2luYWxFbGVtZW50LnRhZ05hbWUgPT09IFwiSDJcIiB8fFxuICAgICAgIGRvbU9iamVjdC5vcmlnaW5hbEVsZW1lbnQudGFnTmFtZSA9PT0gXCJIM1wiIHx8XG4gICAgICAgZG9tT2JqZWN0Lm9yaWdpbmFsRWxlbWVudC50YWdOYW1lID09PSBcIkg0XCIgfHxcbiAgICAgICBkb21PYmplY3Qub3JpZ2luYWxFbGVtZW50LnRhZ05hbWUgPT09IFwiSDVcIikge1xuICAgICAgICByZXR1cm4gcHJvY2Vzc0hlYWRlcigpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHByZXZpb3VzVGV4dDogcHJldmlvdXNUZXh0LFxuICAgICAgICB3b3JraW5nVGV4dDogd29ya2luZ1RleHRcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGF0dGVtcHRUb0ZpeENoZWNrYm94ZXMoZG9tT2JqZWN0OiBET01PYmplY3QsIHRleHRCZWZvcmVFbGVtZW50OiBzdHJpbmcsIHRleHRPZkVsZW1lbnRBbmRBZnRlcjogc3RyaW5nLCBzb3VyY2VGaWxlOiBURmlsZSwgY2FjaGVJRDogc3RyaW5nKSB7XG5cbiAgICBpZihkb21PYmplY3Qub3JpZ2luYWxFbGVtZW50LnRhZ05hbWUgIT09IFwiVUxcIikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJldmlvdXNUZXh0OiB0ZXh0QmVmb3JlRWxlbWVudCxcbiAgICAgICAgICAgIHdvcmtpbmdUZXh0OiB0ZXh0T2ZFbGVtZW50QW5kQWZ0ZXJcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZihkb21PYmplY3Qub3JpZ2luYWxFbGVtZW50Lmhhc0NsYXNzKFwiY29udGFpbnMtdGFzay1saXN0XCIpID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHJldmlvdXNUZXh0OiB0ZXh0QmVmb3JlRWxlbWVudCxcbiAgICAgICAgICAgIHdvcmtpbmdUZXh0OiB0ZXh0T2ZFbGVtZW50QW5kQWZ0ZXJcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCBsaXN0SXRlbXMgPSBBcnJheS5mcm9tKGRvbU9iamVjdC5vcmlnaW5hbEVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJsaVwiKSkuZmlsdGVyKChpdGVtKSA9PiB7XG4gICAgICAgIHJldHVybiBpdGVtLmhhc0NsYXNzKFwidGFzay1saXN0LWl0ZW1cIilcbiAgICB9KVxuXG4gICAgbGV0IHdvcmtpbmdUZXh0QmVmb3JlID0gdGV4dEJlZm9yZUVsZW1lbnQ7XG4gICAgbGV0IHdvcmtpbmdUZXh0ID0gdGV4dE9mRWxlbWVudEFuZEFmdGVyO1xuICAgIGZvcihsZXQgbGlzdEVsZW1lbnQgb2YgbGlzdEl0ZW1zKSB7XG5cbiAgICAgICAgbGV0IHBvc3NpYmxlQ2hlY2tib3ggPSBsaXN0RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImlucHV0XCIpO1xuICAgICAgICBpZihwb3NzaWJsZUNoZWNrYm94Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yOiBDb3VsZCBub3QgZ2V0IGlucHV0IGZvciB0YXNrIGl0ZW0uXCIpXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjaGVja2JveCA9IHBvc3NpYmxlQ2hlY2tib3hbMF07XG4gICAgICAgIGlmKGNoZWNrYm94LmdldEF0dHIoXCJ0eXBlXCIpICE9PSBcImNoZWNrYm94XCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvcjogQ2hlY2tib3ggbm90IG9mIHByb3BlciB0eXBlXCIpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZihjaGVja2JveC5oYXNDbGFzcyhcInRhc2stbGlzdC1pdGVtLWNoZWNrYm94XCIpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yOiBDaGVja2JveCBpcyBtaXNzaW5nIHByb3BlciBjbGFzcy5cIilcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoY2hlY2tib3gub25jbGljayAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yOiBPbkNsaWNrIGFyZWFkeSBkZWZpbmVkLCBub3Qgb3ZlcndyaXRpbmcgbWV0aG9kLlwiKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNoZWNrYm94SXNDaGVja2VkID0gbGlzdEVsZW1lbnQuZ2V0QXR0cihcImRhdGEtdGFza1wiKSA9PT0gXCJ4XCIgfHwgbGlzdEVsZW1lbnQuZ2V0QXR0cihcImRhdGEtdGFza1wiKSA9PT0gXCJYXCJcblxuICAgICAgICBsZXQgY2hlY2tib3hUZXh0UmVnZXhTZWFyY2ggPSBSZWdFeHAoYF4oICopLSggKylcXFxcWyR7Y2hlY2tib3hJc0NoZWNrZWQgPyBcIlt4WF1cIiA6IFwiICpcIn1cXFxcXSggKykke2VzY2FwZVJlZ0V4cChsaXN0RWxlbWVudC5pbm5lclRleHQpfSggKikkYCwgXCJtXCIpO1xuICAgICAgICBsZXQgY2hlY2tib3hUZXh0UmVnZXhSZXN1bHQgPSBjaGVja2JveFRleHRSZWdleFNlYXJjaC5leGVjKHdvcmtpbmdUZXh0KTtcbiAgICAgICAgaWYoY2hlY2tib3hUZXh0UmVnZXhSZXN1bHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJDb3VsZCBub3QgZmluZCB0ZXh0IGluIHByb3ZpZGVkIGRvY3VtZW50LlwiKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN0YXJ0T2ZFbGVtZW50SW5kZXggPSBjaGVja2JveFRleHRSZWdleFJlc3VsdC5pbmRleFxuICAgICAgICBsZXQgZW5kT2ZFbGVtZW50SW5kZXggPSBzdGFydE9mRWxlbWVudEluZGV4ICsgY2hlY2tib3hUZXh0UmVnZXhSZXN1bHRbMF0ubGVuZ3RoXG4gICAgICAgIGxldCBuZXdUZXh0QWZ0ZXIgPSB3b3JraW5nVGV4dC5zbGljZShlbmRPZkVsZW1lbnRJbmRleCk7XG4gICAgICAgIGxldCBvbkNsaWNrTmV3VGV4dEFmdGVyID0gbmV3VGV4dEFmdGVyO1xuXG4gICAgICAgIHdvcmtpbmdUZXh0QmVmb3JlID0gd29ya2luZ1RleHRCZWZvcmUgKyB3b3JraW5nVGV4dC5zbGljZSgwLCBzdGFydE9mRWxlbWVudEluZGV4KTtcbiAgICAgICAgbGV0IG9uQ2xpY2tOZXdUZXh0QmVmb3JlID0gd29ya2luZ1RleHRCZWZvcmU7XG5cbiAgICAgICAgd29ya2luZ1RleHQgPSB3b3JraW5nVGV4dC5zbGljZShzdGFydE9mRWxlbWVudEluZGV4KVxuICAgICAgICBsZXQgb25DbGlja05ld1dvcmtpbmdUZXh0ID0gd29ya2luZ1RleHQ7XG5cbiAgICAgICAgbGV0IHNwYWNlQmVmb3JlRGFzaCA9IGNoZWNrYm94VGV4dFJlZ2V4UmVzdWx0WzFdXG4gICAgICAgIGxldCBzcGFjZUFmdGVyRGFzaCA9IGNoZWNrYm94VGV4dFJlZ2V4UmVzdWx0WzJdXG4gICAgICAgIGxldCBzcGFjZUFmdGVyQ2hlY2sgPSBjaGVja2JveFRleHRSZWdleFJlc3VsdFszXVxuICAgICAgICBsZXQgc3BhY2VBZnRlckNvbnRlbnQgPSBjaGVja2JveFRleHRSZWdleFJlc3VsdFs0XVxuXG4gICAgICAgIGxldCBjdXJyZW50Q2FjaGVJRCA9IGNhY2hlSURcbiAgICAgICAgbGV0IHNvdXJjZUZpbGVQYXRoID0gc291cmNlRmlsZS5wYXRoXG4gICAgICAgIGNoZWNrYm94Lm9uY2xpY2sgPSAoKSA9PiB7XG5cbiAgICAgICAgICAgIGxldCByZXBsYWNlbWVudExpbmUgPSBgJHtzcGFjZUJlZm9yZURhc2h9LSR7c3BhY2VBZnRlckRhc2h9WyR7Y2hlY2tib3hJc0NoZWNrZWQgPyBcIiBcIiA6IFwiWFwifV0ke3NwYWNlQWZ0ZXJDaGVja30ke2xpc3RFbGVtZW50LmlubmVyVGV4dH0ke3NwYWNlQWZ0ZXJDb250ZW50fWBcblxuICAgICAgICAgICAgbGV0IG9yaWdpbmFsVGV4dFRvUmVwbGFjZSA9IG9uQ2xpY2tOZXdUZXh0QmVmb3JlICsgb25DbGlja05ld1dvcmtpbmdUZXh0XG4gICAgICAgICAgICBsZXQgbmV3UmVwbGFjZW1lbnRUZXh0ID0gb25DbGlja05ld1RleHRCZWZvcmUgKyByZXBsYWNlbWVudExpbmUgKyBvbkNsaWNrTmV3VGV4dEFmdGVyXG5cbiAgICAgICAgICAgIGlmKGxpdmVQcmV2aWV3RWxlbWVudENhY2hlLmhhcyhjdXJyZW50Q2FjaGVJRCkpIHtcbiAgICAgICAgICAgICAgICBsZXQgbmV3Q2FjaGVJRCA9IGAke3NvdXJjZUZpbGVQYXRofSA6ICR7bmV3UmVwbGFjZW1lbnRUZXh0fWA7XG4gICAgICAgICAgICAgICAgbGV0IGN1cnJlbnREYXRhID0gbGl2ZVByZXZpZXdFbGVtZW50Q2FjaGUuZ2V0KGN1cnJlbnRDYWNoZUlEKTtcbiAgICAgICAgICAgICAgICBsaXZlUHJldmlld0VsZW1lbnRDYWNoZS5zZXQobmV3Q2FjaGVJRCwgY3VycmVudERhdGEpXG4gICAgICAgICAgICAgICAgY3VycmVudENhY2hlSUQgPSBuZXdDYWNoZUlEXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IGZpbGVUZXh0ID0gYXdhaXQgc291cmNlRmlsZS52YXVsdC5yZWFkKHNvdXJjZUZpbGUpO1xuICAgICAgICAgICAgICAgIGlmKGZpbGVUZXh0LmNvbnRhaW5zKG9yaWdpbmFsVGV4dFRvUmVwbGFjZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJDb3VsZCBub3QgdXBkYXRlIGZpbGUuIEZpbGUgZG9lcyBub3QgY29udGFpbiByZWdpb24gdGV4dC5cIilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBuZXdGaWxlVGV4dCA9IGZpbGVUZXh0LnJlcGxhY2Uob3JpZ2luYWxUZXh0VG9SZXBsYWNlLCBuZXdSZXBsYWNlbWVudFRleHQpXG4gICAgICAgICAgICAgICAgc291cmNlRmlsZS52YXVsdC5tb2RpZnkoc291cmNlRmlsZSwgbmV3RmlsZVRleHQpXG4gICAgICAgICAgICB9KSgpO1xuXG4gICAgICAgICAgICBsaXN0RWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKFwiaXMtY2hlY2tlZFwiKVxuICAgICAgICAgICAgaWYoY2hlY2tib3hJc0NoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICBsaXN0RWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoXCJkYXRhLXRhc2tcIilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxpc3RFbGVtZW50LnNldEF0dHJpYnV0ZShcImRhdGEtdGFza1wiLCBcInhcIilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNoZWNrYm94SXNDaGVja2VkID0gIWNoZWNrYm94SXNDaGVja2VkXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBwcmV2aW91c1RleHQ6IHdvcmtpbmdUZXh0QmVmb3JlLFxuICAgICAgICB3b3JraW5nVGV4dDogd29ya2luZ1RleHRcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGVzY2FwZVJlZ0V4cChzdHI6IHN0cmluZykge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKTsgLy8gJCYgbWVhbnMgdGhlIHdob2xlIG1hdGNoZWQgc3RyaW5nXG59XG4iLCIvKlxuICogRmlsZW5hbWU6IG11bHRpLWNvbHVtbi1tYXJrZG93bi9zcmMvbGl2ZV9wcmV2aWV3L2NtNl9saXZlUHJldmlldy50c1xuICogQ3JlYXRlZCBEYXRlOiBNb25kYXksIEF1Z3VzdCAxc3QgMjAyMiwgMTo1MToxNiBwbVxuICogQXV0aG9yOiBDYW1lcm9uIFJvYmluc29uXG4gKiBcbiAqIENvcHlyaWdodCAoYykgMjAyMiBDYW1lcm9uIFJvYmluc29uXG4gKi9cblxuaW1wb3J0IHsgRXh0ZW5zaW9uLCBMaW5lLCBSYW5nZVNldEJ1aWxkZXIsIFN0YXRlRmllbGQsIFRyYW5zYWN0aW9uIH0gZnJvbSBcIkBjb2RlbWlycm9yL3N0YXRlXCI7XG5pbXBvcnQgeyBEZWNvcmF0aW9uLCBEZWNvcmF0aW9uU2V0LCBFZGl0b3JWaWV3IH0gZnJvbSBcIkBjb2RlbWlycm9yL3ZpZXdcIjtcbmltcG9ydCB7IHN5bnRheFRyZWUsIHRva2VuQ2xhc3NOb2RlUHJvcCB9IGZyb20gXCJAY29kZW1pcnJvci9sYW5ndWFnZVwiO1xuaW1wb3J0IHsgY29udGFpbnNSZWdpb25TdGFydCwgZmluZEVuZFRhZywgZmluZFNldHRpbmdzQ29kZWJsb2NrLCBmaW5kU3RhcnRDb2RlYmxvY2ssIGZpbmRTdGFydFRhZyB9IGZyb20gXCIuLi91dGlsaXRpZXMvdGV4dFBhcnNlclwiO1xuaW1wb3J0IHsgUGFuZG9jUmVnZXhEYXRhLCBmaW5kUGFuZG9jLCBwYXJzZVBhbmRvY1NldHRpbmdzIH0gZnJvbSBcInNyYy91dGlsaXRpZXMvcGFuZG9jUGFyc2VyXCI7XG5pbXBvcnQgeyBNdWx0aUNvbHVtbk1hcmtkb3duX0RlZmluZWRTZXR0aW5nc19MaXZlUHJldmlld19XaWRnZXQsIE11bHRpQ29sdW1uTWFya2Rvd25fTGl2ZVByZXZpZXdfV2lkZ2V0IH0gZnJvbSBcIi4vbWNtX2xpdmVQcmV2aWV3X3dpZGdldFwiO1xuaW1wb3J0IHsgZWRpdG9ySW5mb0ZpZWxkLCBlZGl0b3JMaXZlUHJldmlld0ZpZWxkIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5pbXBvcnQgeyBSZWdpb25UeXBlLCBTdGFydFRhZ1JlZ2V4TWF0Y2gsIG1vdXNlU3RhdGUgfSBmcm9tIFwic3JjL3V0aWxpdGllcy9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBNdWx0aUNvbHVtblNldHRpbmdzIH0gZnJvbSBcInNyYy9yZWdpb25TZXR0aW5nc1wiO1xuaW1wb3J0IHsgcGFyc2VDb2x1bW5TZXR0aW5ncyB9IGZyb20gXCJzcmMvdXRpbGl0aWVzL3NldHRpbmdzUGFyc2VyXCI7XG5cbmxldCBzZWxlY3RpbmcgPSBmYWxzZTtcbmV4cG9ydCBjb25zdCBtdWx0aUNvbHVtbk1hcmtkb3duX1N0YXRlRmllbGQgPSBTdGF0ZUZpZWxkLmRlZmluZTxEZWNvcmF0aW9uU2V0Pih7XG5cdGNyZWF0ZShzdGF0ZSk6IERlY29yYXRpb25TZXQge1xuXHRcdHJldHVybiBEZWNvcmF0aW9uLm5vbmU7XG5cdH0sXG5cdHVwZGF0ZShvbGRTdGF0ZTogRGVjb3JhdGlvblNldCwgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uKTogRGVjb3JhdGlvblNldCB7XG5cdFx0Y29uc3QgYnVpbGRlciA9IG5ldyBSYW5nZVNldEJ1aWxkZXI8RGVjb3JhdGlvbj4oKTtcbiAgICAgICAgbGV0IGlnbm9yZUZ1cnRoZXJJdGVyYXRpb25zID0gZmFsc2U7XG5cblx0XHQvLyBDaGVjayBpZiB2aWV3IGlzIGluIGxpdmUgcHJldmlldyBzdGF0ZS5cblx0XHRpZih0cmFuc2FjdGlvbi5zdGF0ZS5maWVsZChlZGl0b3JMaXZlUHJldmlld0ZpZWxkKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmZpbmlzaCgpO1xuXHRcdH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogV2hlbiB3ZSBoYXZlIHRoZSB3aGlsZSBmaWxlIHdlIHRoZW4gZ2V0IHRoZSBlbnRpcmUgZG9jIHRleHQgYW5kIGNoZWNrIGlmIGl0IFxuICAgICAgICAgKiBjb250YWlucyBhIE1DTSByZWdpb24gc28gd2Uga25vdyB0byBicmVhayBvciBub3QuXG4gICAgICAgICAqL1xuICAgICAgICBsZXQgZG9jTGVuZ3RoID0gdHJhbnNhY3Rpb24uc3RhdGUuZG9jLmxlbmd0aFxuICAgICAgICBsZXQgZG9jVGV4dCA9IHRyYW5zYWN0aW9uLnN0YXRlLmRvYy5zbGljZVN0cmluZygwLCBkb2NMZW5ndGgpO1xuICAgICAgICBpZiAoY29udGFpbnNSZWdpb25TdGFydChkb2NUZXh0KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmZpbmlzaCgpO1xuICAgICAgICB9XG5cblx0XHRzeW50YXhUcmVlKHRyYW5zYWN0aW9uLnN0YXRlKS5pdGVyYXRlKHtcblx0XHRcdGVudGVyKG5vZGUpIHtcblxuXHRcdFx0XHQvLyBJZiB3ZSBmaW5kIHRoYXQgdGhlIGZpbGUgZG9lcyBub3QgY29udGFpbiBhbnkgTUNNIHJlZ2lvbnMgd2UgY2FuIGZsaXAgdGhpc1xuXHRcdFx0XHQvLyBmbGFnIGFuZCBza2lwIGFsbCBvdGhlciBub2RlIGl0ZXJhdGlvbnMsIHBvdGVudGlhbGx5IHNhdmluZyBhIGxvdCBvZiBjb21wdXRlIHRpbWUuXG5cdFx0XHRcdC8vIFxuICAgICAgICAgICAgICAgIC8vIFdlIG9ubHkgd2FudCB0byBydW4gdGhlIGdlbmVyYXRpb24gb25jZSBwZXIgc3RhdGUgY2hhbmdlLiBJZlxuICAgICAgICAgICAgICAgIC8vIGEgcHJldmlvdXMgbm9kZSBoYXMgc3VjZXNzZnVsbHkgZ2VuZXJhdGVkIHJlZ2lvbnMgd2UgaWdub3JlIGFsbFxuICAgICAgICAgICAgICAgIC8vIG90aGVyIG5vZGVzIGluIHRoZSBzdGF0ZS5cbiAgICAgICAgICAgICAgICBpZihpZ25vcmVGdXJ0aGVySXRlcmF0aW9ucyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG5cdFx0XHRcdC8vIFdlIHdhbnQgdG8gcnVuIG9uIHRoZSB3aG9sZSBmaWxlIHNvIHdlIGRvbnQganVzdCBsb29rIGZvciBhIHNpbmdsZSB0b2tlbi5cblx0XHRcdFx0Y29uc3QgdG9rZW5Qcm9wcyA9IG5vZGUudHlwZS5wcm9wPHN0cmluZz4odG9rZW5DbGFzc05vZGVQcm9wKTtcblx0XHRcdFx0aWYgKHRva2VuUHJvcHMgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFdlIHdhbnQgdG8ga25vdyB3aGVyZSB0aGUgdXNlcidzIGN1cnNvciBpcywgaXQgY2FuIGJlXG5cdFx0XHRcdC8vIHNlbGVjdGluZyBtdWx0aXBsZSByZWdpb25zIG9mIHRleHQgYXMgd2VsbCBzbyB3ZSBuZWVkIHRvIGtub3dcblx0XHRcdFx0Ly8gYWxsIGxvY2F0aW9ucy4gVXNlZCB0byBrbm93IGlmIHdlIHNob3VsZCByZW5kZXIgcmVnaW9uIGFzIHRleHQgb3IgYXMgcHJldmlldy5cblx0XHRcdFx0bGV0IHJhbmdlcyA9IGdldEN1cnNvckxpbmVMb2NhdGlvbnMoKTtcblxuXHRcdFx0XHQvLyBTZXR1cCBvdXIgbG9vcCB0byByZW5kZXIgdGhlIHJlZ2lvbnMgYXMgTUNNLiBcblx0XHRcdFx0bGV0IHdvcmtpbmdGaWxlVGV4dCA9IGRvY1RleHQ7XG5cblx0XHRcdFx0bGV0IGxvb3BJbmRleCA9IDA7XG5cdFx0XHRcdGxldCBzdGFydEluZGV4T2Zmc2V0ID0gMDtcblx0XHRcdFx0d2hpbGUgKHRydWUpIHtcblxuXHRcdFx0XHRcdGxldCByZWdpb25EYXRhOiBSZWdpb25EYXRhID0gZ2V0TmV4dFJlZ2lvbih3b3JraW5nRmlsZVRleHQsIHN0YXJ0SW5kZXhPZmZzZXQsIGRvY1RleHQpO1xuXHRcdFx0XHRcdGlmKHJlZ2lvbkRhdGEgPT09IG51bGwpIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGxldCBlbGVtZW50VGV4dCAgPSByZWdpb25EYXRhLnJlZ2lvblRleHQ7XG5cdFx0XHRcdFx0d29ya2luZ0ZpbGVUZXh0ICA9IHJlZ2lvbkRhdGEucmVtYWluaW5nVGV4dDtcblx0XHRcdFx0XHRsZXQgc3RhcnRJbmRleCAgID0gcmVnaW9uRGF0YS5zdGFydEluZGV4O1xuXHRcdFx0XHRcdGxldCBlbmRJbmRleCAgICAgPSByZWdpb25EYXRhLmVuZEluZGV4O1xuXHRcdFx0XHRcdHN0YXJ0SW5kZXhPZmZzZXQgPSBlbmRJbmRleDtcblxuXHRcdFx0XHRcdC8vIEhlcmUgd2UgY2hlY2sgaWYgdGhlIGN1cnNvciBpcyBpbiB0aGlzIHNwZWNpZmljIHJlZ2lvbi5cblx0XHRcdFx0XHRsZXQgY3Vyc29ySW5SZWdpb24gPSBjaGVja0N1cnNvckluUmVnaW9uKHN0YXJ0SW5kZXgsIGVuZEluZGV4LCByYW5nZXMpO1xuXHRcdFx0XHRcdGlmKGN1cnNvckluUmVnaW9uID09PSB0cnVlKSB7XG5cdFx0XHRcdFx0XHRcblx0XHRcdFx0XHRcdC8vIC8vIElmIHRoZSBjdXJzb3IgaXMgd2l0aGluIHRoZSByZWdpb24gd2UgdGhlbiBuZWVkIHRvIGtub3cgaWZcblx0XHRcdFx0XHRcdC8vIC8vIGl0IGlzIHdpdGhpbiBvdXIgc2V0dGluZ3MgYmxvY2sgKGlmIGl0IGV4aXN0cy4pXG5cdFx0XHRcdFx0XHQvLyBsZXQgc2V0dGluZ3NTdGFydERhdGEgPSBmaW5kU3RhcnRDb2RlYmxvY2soZWxlbWVudFRleHQpO1xuXHRcdFx0XHRcdFx0Ly8gaWYoc2V0dGluZ3NTdGFydERhdGEuZm91bmQgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHQvLyBcdHNldHRpbmdzU3RhcnREYXRhID0gZmluZFNldHRpbmdzQ29kZWJsb2NrKGVsZW1lbnRUZXh0KTtcblx0XHRcdFx0XHRcdC8vIH1cblxuXHRcdFx0XHRcdFx0Ly8gaWYoc2V0dGluZ3NTdGFydERhdGEuZm91bmQgPT09IHRydWUpIHtcblxuXHRcdFx0XHRcdFx0Ly8gXHQvLyBTaW5jZSB0aGUgc2V0dGluZ3MgYmxvY2sgZXhpc3RzIGNoZWNrIGlmIHRoZSBjdXJzb3IgaXMgd2l0aGluIHRoYXQgcmVnaW9uLlxuXHRcdFx0XHRcdFx0Ly8gXHRsZXQgY29kZWJsb2NrU3RhcnRJbmRleCA9IHN0YXJ0SW5kZXggKyBzZXR0aW5nc1N0YXJ0RGF0YS5zdGFydFBvc2l0aW9uO1xuXHRcdFx0XHRcdFx0Ly8gXHRsZXQgY29kZWJsb2NrRW5kSW5kZXggPSBzdGFydEluZGV4ICsgc2V0dGluZ3NTdGFydERhdGEuZW5kUG9zaXRpb247XG5cdFx0XHRcdFx0XHQvLyBcdGxldCBzZXR0aW5nc1RleHQgPSBkb2NUZXh0LnNsaWNlKGNvZGVibG9ja1N0YXJ0SW5kZXgsIGNvZGVibG9ja0VuZEluZGV4IClcblxuXHRcdFx0XHRcdFx0Ly8gXHRsZXQgY3Vyc29ySW5Db2RlYmxvY2sgPSBjaGVja0N1cnNvckluUmVnaW9uKGNvZGVibG9ja1N0YXJ0SW5kZXgsIGNvZGVibG9ja0VuZEluZGV4LCByYW5nZXMpO1xuXHRcdFx0XHRcdFx0Ly8gXHRpZihjdXJzb3JJbkNvZGVibG9jayA9PT0gZmFsc2UpIHtcblx0XG5cdFx0XHRcdFx0XHQvLyBcdFx0Ly8gSWYgdGhlIGN1cnNvciBpcyBub3Qgd2l0aGluIHRoZSByZWdpb24gd2UgcGFzcyB0aGUgZGF0YSB0byB0aGVcblx0XHRcdFx0XHRcdC8vIFx0XHQvLyBzZXR0aW5ncyB2aWV3IHNvIGl0IGNhbiBiZSBkaXNwbGF5ZWQgaW4gdGhlIHJlZ2lvbi5cblx0XHRcdFx0XHRcdC8vIFx0XHRidWlsZGVyLmFkZChcblx0XHRcdFx0XHRcdC8vIFx0XHRcdGNvZGVibG9ja1N0YXJ0SW5kZXgsXG5cdFx0XHRcdFx0XHQvLyBcdFx0XHRjb2RlYmxvY2tFbmRJbmRleCxcblx0XHRcdFx0XHRcdC8vIFx0XHRcdERlY29yYXRpb24ucmVwbGFjZSh7XG5cdFx0XHRcdFx0XHQvLyBcdFx0XHRcdHdpZGdldDogbmV3IE11bHRpQ29sdW1uTWFya2Rvd25fRGVmaW5lZFNldHRpbmdzX0xpdmVQcmV2aWV3X1dpZGdldChzZXR0aW5nc1RleHQpLFxuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0fSlcblx0XHRcdFx0XHRcdC8vIFx0XHQpO1xuXHRcdFx0XHRcdFx0Ly8gXHR9XG5cdFx0XHRcdFx0XHQvLyB9XHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRsZXQgZm91bmRTZXR0aW5ncyA9IGdldFNldHRpbmdzRGF0YShyZWdpb25EYXRhKTtcblx0XHRcdFx0XHRcdGxldCB1c2VyU2V0dGluZ3MgPSBudWxsO1xuXHRcdFx0XHRcdFx0bGV0IHNldHRpbmdzVGV4dCA9IFwiXCJcblx0XHRcdFx0XHRcdGxldCBvcmlnaW5hbFRleHQgPSBlbGVtZW50VGV4dFxuXHRcdFx0XHRcdFx0aWYoZm91bmRTZXR0aW5ncyAhPT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0XHRcblx0XHRcdFx0XHRcdFx0ZWxlbWVudFRleHQgPSBmb3VuZFNldHRpbmdzLmNvbnRlbnREYXRhO1xuXHRcdFx0XHRcdFx0XHR1c2VyU2V0dGluZ3MgPSBmb3VuZFNldHRpbmdzLnNldHRpbmdzO1xuXHRcdFx0XHRcdFx0XHRzZXR0aW5nc1RleHQgPSBmb3VuZFNldHRpbmdzLnNldHRpbmdzVGV4dDtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Y29uc3QgZWRpdG9ySW5mbyA9IHRyYW5zYWN0aW9uLnN0YXRlLmZpZWxkKGVkaXRvckluZm9GaWVsZCk7XG5cblx0XHRcdFx0XHRcdC8vIEF0IHRoaXMgcG9pbnQgaWYgdGhlIGN1cnNvciBpc250IGluIHRoZSByZWdpb24gd2UgcGFzcyB0aGUgZGF0YSB0byB0aGVcblx0XHRcdFx0XHRcdC8vIGVsZW1lbnQgdG8gYmUgcmVuZGVyZWQuXG5cdFx0XHRcdFx0XHRidWlsZGVyLmFkZChcblx0XHRcdFx0XHRcdFx0c3RhcnRJbmRleCxcblx0XHRcdFx0XHRcdFx0ZW5kSW5kZXgsXG5cdFx0XHRcdFx0XHRcdERlY29yYXRpb24ucmVwbGFjZSh7XG5cdFx0XHRcdFx0XHRcdFx0d2lkZ2V0OiBuZXcgTXVsdGlDb2x1bW5NYXJrZG93bl9MaXZlUHJldmlld19XaWRnZXQob3JpZ2luYWxUZXh0LCBlbGVtZW50VGV4dCwgdXNlclNldHRpbmdzLCBlZGl0b3JJbmZvLmZpbGUsIHNldHRpbmdzVGV4dCwgcmVnaW9uRGF0YS5yZWdpb25UeXBlKSxcblx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlnbm9yZUZ1cnRoZXJJdGVyYXRpb25zID0gdHJ1ZTtcblxuXHRcdFx0XHRcdC8vIEluZmluaXRlIGxvb3AgcHJvdGVjdGlvbi5cblx0XHRcdFx0XHRsb29wSW5kZXgrKztcblx0XHRcdFx0XHRpZihsb29wSW5kZXggPiAxMDApIHtcblx0XHRcdFx0XHRcdGNvbnNvbGUud2FybihcIlBvdGVudGlhbCBpc3N1ZSB3aXRoIHJlbmRlcmluZyBNdWx0aS1Db2x1bW4gTWFya2Rvd24gbGl2ZSBwcmV2aWV3IHJlZ2lvbnMuIElmIHByb2JsZW0gcGVyc2lzdHMgcGxlYXNlIGZpbGUgYSBidWcgcmVwb3J0IHdpdGggZGV2ZWxvcGVyLlwiKVxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdH0pO1xuIFxuXHRcdHJldHVybiBidWlsZGVyLmZpbmlzaCgpO1xuXG5cdFx0ZnVuY3Rpb24gZ2V0Q3Vyc29yTGluZUxvY2F0aW9ucygpOiB7IGxpbmU6IExpbmUsIHBvc2l0aW9uOiBudW1iZXIgfVtdIHtcblxuXHRcdFx0bGV0IHJhbmdlczogeyBsaW5lOiBMaW5lLCBwb3NpdGlvbjogbnVtYmVyIH1bXSA9IFtdO1xuXG5cdFx0XHRpZiAodHJhbnNhY3Rpb24uc3RhdGUuc2VsZWN0aW9uLnJhbmdlcykge1xuXG5cdFx0XHRcdHJhbmdlcyA9IHRyYW5zYWN0aW9uLnN0YXRlLnNlbGVjdGlvbi5yYW5nZXMuZmlsdGVyKChyYW5nZSkgPT4ge1xuXG5cdFx0XHRcdFx0cmV0dXJuIHJhbmdlLmVtcHR5O1xuXHRcdFx0XHR9KS5tYXAoKHJhbmdlKSA9PiB7XG5cblx0XHRcdFx0XHRsZXQgbGluZSA9IHRyYW5zYWN0aW9uLnN0YXRlLmRvYy5saW5lQXQocmFuZ2UuaGVhZCk7XG5cdFx0XHRcdFx0bGV0IHRleHQgPSBgJHtsaW5lLm51bWJlcn06JHtyYW5nZS5oZWFkIC0gbGluZS5mcm9tfWA7XG5cblx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0bGluZTogbGluZSxcblx0XHRcdFx0XHRcdHBvc2l0aW9uOiByYW5nZS5oZWFkXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHJhbmdlcztcblx0XHR9XG5cbiAgICAgICAgZnVuY3Rpb24gdmFsdWVJc0luUmFuZ2UodmFsdWU6IG51bWJlciwgbWluVmFsOiBudW1iZXIsIG1heFZhbDogbnVtYmVyLCBpbmNsdXNpdmU6IGJvb2xlYW4gPSB0cnVlKSB7XG5cbiAgICAgICAgICAgIGlmKGluY2x1c2l2ZSA9PT0gdHJ1ZSAmJiAodmFsdWUgPT09IG1pblZhbCB8fCB2YWx1ZSA9PT0gbWF4VmFsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobWluVmFsIDwgdmFsdWUgJiYgdmFsdWUgPCBtYXhWYWwpIHtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuXHRcdGZ1bmN0aW9uIGNoZWNrQ3Vyc29ySW5SZWdpb24oc3RhcnRJbmRleDogbnVtYmVyLFxuXHRcdFx0XHRcdFx0XHRcdGVuZEluZGV4OiBudW1iZXIsIFxuXHRcdFx0XHRcdFx0XHRcdHJhbmdlczogeyBsaW5lOiBMaW5lLCBwb3NpdGlvbjogbnVtYmVyIH1bXSApOiBib29sZWFuIHtcblxuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCByYW5nZXMubGVuZ3RoOyBpKyspIHtcblxuXHRcdFx0XHQvLyBUT0RPOiBNYXliZSBsb29rIGludG8gbGltaXRpbmcgdGhpcyB0byB0aGUgc2Vjb25kIGFuZCBzZWNvbmQgdG8gbGFzdCBsaW5lXG5cdFx0XHRcdC8vIG9mIHRoZSByZWdpb24gYXMgY2xpY2tpbmcgcmlnaHQgYXQgdGhlIHRvcCBvciBib3R0b20gb2YgdGhlIHJlZ2lvblxuXHRcdFx0XHQvLyBzd2FwcyBpdCB0byB1bnJlbmRlcmVkLlxuXHRcdFx0XHRsZXQgcmFuZ2UgPSByYW5nZXNbaV07XG5cdFx0XHRcdGlmKHZhbHVlSXNJblJhbmdlKHJhbmdlLnBvc2l0aW9uLCBzdGFydEluZGV4LCBlbmRJbmRleCkgPT09IHRydWUpIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZih0cmFuc2FjdGlvbi5zdGF0ZS5zZWxlY3Rpb24pe1xuXHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRyYW5zYWN0aW9uLnN0YXRlLnNlbGVjdGlvbi5yYW5nZXMubGVuZ3RoOyBpKyspIHtcblxuXHRcdFx0XHRcdGxldCByYW5nZSA9IHRyYW5zYWN0aW9uLnN0YXRlLnNlbGVjdGlvbi5yYW5nZXNbaV07XG5cblx0XHRcdFx0XHQvLyBJZiBlaXRoZXIgdGhlIHN0YXJ0IG9yIGVuZCBvZiB0aGUgc2VsZWN0aW9uIGlzIHdpdGhpbiB0aGVcblx0XHRcdFx0XHQvLyByZWdpb24gcmFuZ2Ugd2UgZG8gbm90IHJlbmRlciBsaXZlIHByZXZpZXcuXG5cdFx0XHRcdFx0aWYodmFsdWVJc0luUmFuZ2UocmFuZ2UuZnJvbSwgc3RhcnRJbmRleCwgZW5kSW5kZXgpIHx8IFxuXHRcdFx0XHRcdCAgIHZhbHVlSXNJblJhbmdlKHJhbmdlLnRvLCBzdGFydEluZGV4LCBlbmRJbmRleCkpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIC8vIE9yIGlmIHRoZSBlbnRpcmUgcmVnaW9uIGlzIHdpdGhpbiB0aGUgc2VsZWN0aW9uIHJhbmdlXG5cdFx0XHRcdFx0Ly8gd2UgZG8gbm90IHJlbmRlciB0aGUgbGl2ZSBwcmV2aWV3LlxuXHRcdFx0XHRcdGlmKHZhbHVlSXNJblJhbmdlKHN0YXJ0SW5kZXgsIHJhbmdlLmZyb20sIHJhbmdlLnRvKSAmJiBcblx0XHRcdFx0XHQgICB2YWx1ZUlzSW5SYW5nZShlbmRJbmRleCwgcmFuZ2UuZnJvbSwgcmFuZ2UudG8pKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fSxcblx0cHJvdmlkZShmaWVsZDogU3RhdGVGaWVsZDxEZWNvcmF0aW9uU2V0Pik6IEV4dGVuc2lvbiB7XG5cdFx0cmV0dXJuIEVkaXRvclZpZXcuZGVjb3JhdGlvbnMuZnJvbShmaWVsZCk7XG5cdH0sXG59KTtcblxuaW50ZXJmYWNlIFJlZ2lvbkRhdGEge1xuXHRyZWdpb25UeXBlOiBSZWdpb25UeXBlO1xuXHRyZWdpb25UZXh0OiBzdHJpbmc7XG5cdHJlbWFpbmluZ1RleHQ6IHN0cmluZztcblx0c3RhcnRJbmRleDogbnVtYmVyO1xuXHRlbmRJbmRleDogbnVtYmVyO1xufVxuaW50ZXJmYWNlIFBhbmRvY1JlZ2lvbkRhdGEgZXh0ZW5kcyBSZWdpb25EYXRhIHtcblx0Y29sdW1uQ291bnQ6IHN0cmluZztcblx0dXNlclNldHRpbmdzOiBzdHJpbmc7XG59XG5cbmZ1bmN0aW9uIGdldE5leHRSZWdpb24od29ya2luZ0ZpbGVUZXh0OiBzdHJpbmcsIHN0YXJ0SW5kZXhPZmZzZXQ6IG51bWJlciwgd2hvbGVEb2M6IHN0cmluZyk6IFJlZ2lvbkRhdGEgfCBudWxsIHtcblxuXHRsZXQgcmVnaW9uID0gZmluZE5leHRSZWdpb24od29ya2luZ0ZpbGVUZXh0KTtcblx0aWYocmVnaW9uID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHRpZihyZWdpb24uZGF0YVR5cGUgPT09IFwiQ09ERUJMT0NLXCIgfHwgcmVnaW9uLmRhdGFUeXBlID09PSBcIk9SSUdJTkFMXCIpIHtcblxuXHRcdC8vIFNlYXJjaCBmb3IgdGhlIGZpcnN0IGVuZCB0YWcgYWZ0ZXIgYSBzdGFydCBibG9jay4gKE5vIHJlY3Vyc2l2ZSBjb2x1bW5zLilcblx0XHRsZXQgZW5kVGFnRGF0YSA9IGZpbmRFbmRUYWcod29ya2luZ0ZpbGVUZXh0LnNsaWNlKHJlZ2lvbi5kYXRhLnN0YXJ0UG9zaXRpb24pKTtcblx0XHRpZihlbmRUYWdEYXRhLmZvdW5kID09PSBmYWxzZSkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogRm9yIHRoZSByZWdpb24gd2UgZm91bmQgZ2V0IHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9uIG9mIHRoZSB0YWdzIHNvIHdlIFxuXHRcdCAqIGNhbiBzbGljZSBpdCBvdXQgb2YgdGhlIGRvY3VtZW50LlxuXHRcdCAqL1xuXHRcdGxldCBzdGFydEluZGV4ID0gc3RhcnRJbmRleE9mZnNldCArIHJlZ2lvbi5kYXRhLnN0YXJ0UG9zaXRpb247XG5cdFx0bGV0IGVuZEluZGV4ID0gc3RhcnRJbmRleCArIGVuZFRhZ0RhdGEuc3RhcnRQb3NpdGlvbiArIGVuZFRhZ0RhdGEubWF0Y2hMZW5ndGggLy8gV2l0aG91dCB0aGUgbWF0Y2hMZW5ndGggd2lsbCBsZWF2ZSB0aGUgZW5kIHRhZyBvbiB0aGUgc2NyZWVuLlxuXG5cdFx0Ly8gVGhpcyB0ZXh0IGlzIHRoZSBlbnRpcmUgcmVnaW9uIGRhdGEgaW5jbHVkaW5nIHRoZSBzdGFydCBhbmQgZW5kIHRhZ3MuXG5cdFx0bGV0IGVsZW1lbnRUZXh0ID0gd2hvbGVEb2Muc2xpY2Uoc3RhcnRJbmRleCwgZW5kSW5kZXgpXG5cdFx0d29ya2luZ0ZpbGVUZXh0ID0gd2hvbGVEb2Muc2xpY2UoZW5kSW5kZXgpO1xuXG5cdFx0LyoqXG5cdFx0ICogVXBkYXRlIG91ciBzdGFydCBvZmZzZXQgYW5kIHRoZSB3b3JraW5nIHRleHQgb2YgdGhlIGZpbGUgc28gb3VyIG5leHQgXG5cdFx0ICogaXRlcmF0aW9uIGtub3dzIHdoZXJlIHdlIGxlZnQgb2ZmXG5cdFx0ICovXG5cdFx0bGV0IGRhdGE6IFJlZ2lvbkRhdGEgPSB7XG5cdFx0XHRyZWdpb25UeXBlOiByZWdpb24uZGF0YVR5cGUsXG5cdFx0XHRyZWdpb25UZXh0OiBlbGVtZW50VGV4dCxcblx0XHRcdHJlbWFpbmluZ1RleHQ6IHdvcmtpbmdGaWxlVGV4dCxcblx0XHRcdHN0YXJ0SW5kZXg6IHN0YXJ0SW5kZXgsXG5cdFx0XHRlbmRJbmRleDogZW5kSW5kZXhcblx0XHR9XG5cdFx0cmV0dXJuIGRhdGE7XG5cdH1cblxuXHRpZihyZWdpb24uZGF0YVR5cGUgPT09IFwiUEFET0NcIikge1xuXG5cdFx0bGV0IHBhbmRvY0RhdGE6IFBhbmRvY1JlZ2V4RGF0YSA9IHJlZ2lvbi5kYXRhIGFzIFBhbmRvY1JlZ2V4RGF0YTtcblx0XHRsZXQgc3RhcnRJbmRleCA9IHN0YXJ0SW5kZXhPZmZzZXQgKyBwYW5kb2NEYXRhLnN0YXJ0UG9zaXRpb247XG5cdFx0bGV0IGVuZEluZGV4ID0gc3RhcnRJbmRleE9mZnNldCArIHBhbmRvY0RhdGEuZW5kUG9zaXRpb247XG5cdFx0d29ya2luZ0ZpbGVUZXh0ID0gd2hvbGVEb2Muc2xpY2UoZW5kSW5kZXgpO1xuXHRcdGxldCBkYXRhOiBQYW5kb2NSZWdpb25EYXRhID0ge1xuXHRcdFx0cmVnaW9uVHlwZTogcmVnaW9uLmRhdGFUeXBlLFxuXHRcdFx0cmVnaW9uVGV4dDogcGFuZG9jRGF0YS5jb250ZW50LFxuXHRcdFx0cmVtYWluaW5nVGV4dDogd29ya2luZ0ZpbGVUZXh0LFxuXHRcdFx0c3RhcnRJbmRleDogc3RhcnRJbmRleCxcblx0XHRcdGVuZEluZGV4OiBlbmRJbmRleCxcblx0XHRcdGNvbHVtbkNvdW50OiBwYW5kb2NEYXRhLmNvbHVtbkNvdW50LFxuXHRcdFx0dXNlclNldHRpbmdzOiBwYW5kb2NEYXRhLnVzZXJTZXR0aW5nc1xuXHRcdH1cblx0XHRyZXR1cm4gZGF0YTtcblx0fVxufVxuXG5mdW5jdGlvbiBmaW5kTmV4dFJlZ2lvbih3b3JraW5nRmlsZVRleHQ6IHN0cmluZyk6IHsgZGF0YVR5cGU6IFJlZ2lvblR5cGUsIGRhdGE6IFN0YXJ0VGFnUmVnZXhNYXRjaCB8IFBhbmRvY1JlZ2V4RGF0YSB9IHtcblxuXHQvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUga2luZHMgb2Ygc3RhcnQgYmxvY2tzLCB0aGUgb2xkIHdheSBvZiBwYXJzaW5nIHdvdWxkIGNhdXNlIGlzc3Vlcy5cblx0Ly8gTm93IHNlYXJjaCBmb3IgYm90aCBraW5kcyBhbmQgZGV0ZXJtaW5lIHdoYXQgdG8gZG8gYWZ0ZXIgc2VhcmNoLlxuXHRsZXQgc3RhcnRUYWdEYXRhX2NvZGVibG9ja1N0YXJ0OiB7IGRhdGFUeXBlOiBSZWdpb25UeXBlLCBkYXRhOiBTdGFydFRhZ1JlZ2V4TWF0Y2ggfSA9IHtkYXRhVHlwZTogXCJDT0RFQkxPQ0tcIiwgZGF0YTogZmluZFN0YXJ0Q29kZWJsb2NrKHdvcmtpbmdGaWxlVGV4dCkgfTtcblx0bGV0IHN0YXJ0VGFnRGF0YV9vcmlnaW5hbFN0YXJ0OiB7IGRhdGFUeXBlOiBSZWdpb25UeXBlLCBkYXRhOiBTdGFydFRhZ1JlZ2V4TWF0Y2ggfSA9IHtkYXRhVHlwZTogXCJPUklHSU5BTFwiLCBkYXRhOiBmaW5kU3RhcnRUYWcod29ya2luZ0ZpbGVUZXh0KSB9O1xuXHRsZXQgcGFuZG9jRGF0YTogeyBkYXRhVHlwZTogUmVnaW9uVHlwZSwgZGF0YTogUGFuZG9jUmVnZXhEYXRhIH0gPSB7ZGF0YVR5cGU6IFwiUEFET0NcIiwgZGF0YTogZmluZFBhbmRvYyh3b3JraW5nRmlsZVRleHQpIH1cblxuXHRpZihzdGFydFRhZ0RhdGFfY29kZWJsb2NrU3RhcnQuZGF0YS5mb3VuZCA9PT0gZmFsc2UgJiYgXG5cdCAgIHN0YXJ0VGFnRGF0YV9vcmlnaW5hbFN0YXJ0LmRhdGEuZm91bmQgPT09IGZhbHNlICYmXG5cdCAgIHBhbmRvY0RhdGEuZGF0YS5mb3VuZCA9PT0gZmFsc2UpIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdGxldCByZWdpb25zRm91bmQgPSBbc3RhcnRUYWdEYXRhX2NvZGVibG9ja1N0YXJ0LCBzdGFydFRhZ0RhdGFfb3JpZ2luYWxTdGFydCwgcGFuZG9jRGF0YV0uZmlsdGVyKCh2YWwpID0+IHsgcmV0dXJuIHZhbC5kYXRhLmZvdW5kID09PSB0cnVlIH0pO1xuXHRpZihyZWdpb25zRm91bmQubGVuZ3RoID4gMSkge1xuXG5cdFx0bGV0IHNvcnRlZCA9IHJlZ2lvbnNGb3VuZC5zb3J0KChhLCBiKSA9PiB7XG5cdFx0XHRyZXR1cm4gYS5kYXRhLnN0YXJ0UG9zaXRpb24gLSBiLmRhdGEuZW5kUG9zaXRpb247XG5cdFx0fSlcblx0XHRyZXR1cm4gc29ydGVkLmZpcnN0KCk7XG5cdH1cblx0XG5cdGlmKHN0YXJ0VGFnRGF0YV9jb2RlYmxvY2tTdGFydC5kYXRhLmZvdW5kID09PSB0cnVlKSB7XG5cdFx0cmV0dXJuIHN0YXJ0VGFnRGF0YV9jb2RlYmxvY2tTdGFydDtcblx0fVxuXHRcblx0aWYoc3RhcnRUYWdEYXRhX29yaWdpbmFsU3RhcnQuZGF0YS5mb3VuZCA9PT0gdHJ1ZSl7XG5cdFx0cmV0dXJuIHN0YXJ0VGFnRGF0YV9vcmlnaW5hbFN0YXJ0O1xuXHR9XG5cdFxuXHRpZihwYW5kb2NEYXRhLmRhdGEuZm91bmQgPT09IHRydWUpIHtcblx0XHRyZXR1cm4gcGFuZG9jRGF0YTtcblx0fVxuXG5cdHRocm93KFwiVW5rbm93biB0eXBlIGZvdW5kIHdoZW4gcGFyc2luZyByZWdpb24uXCIpXG59XG5cbmZ1bmN0aW9uIGdldFNldHRpbmdzRGF0YShyZWdpb25EYXRhOiBSZWdpb25EYXRhKToge3NldHRpbmdzOiBNdWx0aUNvbHVtblNldHRpbmdzLCBzZXR0aW5nc1RleHQ6IHN0cmluZywgY29udGVudERhdGE6IHN0cmluZ30ge1xuXG5cdGxldCBjb250ZW50RGF0YSA9IHJlZ2lvbkRhdGEucmVnaW9uVGV4dFxuXHRmdW5jdGlvbiBwYXJzZUNvZGVCbG9ja1NldHRpbmdzKHNldHRpbmdzU3RhcnREYXRhOiBTdGFydFRhZ1JlZ2V4TWF0Y2gpIHtcblxuXHRcdGxldCBzZXR0aW5nc1RleHQgPSBjb250ZW50RGF0YS5zbGljZShzZXR0aW5nc1N0YXJ0RGF0YS5zdGFydFBvc2l0aW9uLCBzZXR0aW5nc1N0YXJ0RGF0YS5lbmRQb3NpdGlvbik7XG5cdFx0Y29udGVudERhdGEgPSBjb250ZW50RGF0YS5yZXBsYWNlKHNldHRpbmdzVGV4dCwgXCJcIik7XG5cblx0XHRsZXQgc2V0dGluZ3MgPSBwYXJzZUNvbHVtblNldHRpbmdzKHNldHRpbmdzVGV4dCk7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0c2V0dGluZ3M6IHNldHRpbmdzLFxuXHRcdFx0c2V0dGluZ3NUZXh0OiBzZXR0aW5nc1RleHQsXG5cdFx0XHRjb250ZW50RGF0YTogY29udGVudERhdGFcblx0XHR9XG5cdH1cblxuXHRpZihyZWdpb25EYXRhLnJlZ2lvblR5cGUgPT09IFwiQ09ERUJMT0NLXCIpIHtcblx0XHRsZXQgc2V0dGluZ3NTdGFydERhdGEgPSBmaW5kU3RhcnRDb2RlYmxvY2soY29udGVudERhdGEpO1xuXHRcdGlmIChzZXR0aW5nc1N0YXJ0RGF0YS5mb3VuZCA9PT0gZmFsc2UpIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblxuXHRcdHJldHVybiBwYXJzZUNvZGVCbG9ja1NldHRpbmdzKHNldHRpbmdzU3RhcnREYXRhKVxuXHR9XG5cblx0aWYocmVnaW9uRGF0YS5yZWdpb25UeXBlID09PSBcIk9SSUdJTkFMXCIpIHtcblx0XHRsZXQgc2V0dGluZ3NTdGFydERhdGEgPSBmaW5kU2V0dGluZ3NDb2RlYmxvY2soY29udGVudERhdGEpO1xuXHRcdGlmIChzZXR0aW5nc1N0YXJ0RGF0YS5mb3VuZCA9PT0gZmFsc2UpIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0XHRyZXR1cm4gcGFyc2VDb2RlQmxvY2tTZXR0aW5ncyhzZXR0aW5nc1N0YXJ0RGF0YSlcblx0fVxuXG5cdGlmKHJlZ2lvbkRhdGEucmVnaW9uVHlwZSA9PT0gXCJQQURPQ1wiKSB7XG5cblx0XHRsZXQgcGFuZG9jRGF0YSA9IHJlZ2lvbkRhdGEgYXMgUGFuZG9jUmVnaW9uRGF0YVxuXHRcdHJldHVybiB7XG5cdFx0XHRzZXR0aW5nczogcGFyc2VQYW5kb2NTZXR0aW5ncyhwYW5kb2NEYXRhLnVzZXJTZXR0aW5ncywgcGFuZG9jRGF0YS5jb2x1bW5Db3VudCksXG5cdFx0XHRzZXR0aW5nc1RleHQ6IFwiXCIsXG5cdFx0XHRjb250ZW50RGF0YTogcmVnaW9uRGF0YS5yZWdpb25UZXh0XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIGNoZWNrVXNlclNlbGVjdGluZyh0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24pOiBib29sZWFuIHtcblx0XG5cdGxldCBpc1NlbGVjdGluZyA9IGZhbHNlO1xuXHRpZih0cmFuc2FjdGlvbi5pc1VzZXJFdmVudChcInNlbGVjdC5wb2ludGVyXCIpICYmIFxuXHRcdHRyYW5zYWN0aW9uLnN0YXRlLnNlbGVjdGlvbi5yYW5nZXMgJiYgXG5cdFx0dHJhbnNhY3Rpb24uc3RhdGUuc2VsZWN0aW9uLnJhbmdlcy5sZW5ndGggPiAwKSB7XG5cblx0XHRmb3IobGV0IHJhbmdlIG9mIHRyYW5zYWN0aW9uLnN0YXRlLnNlbGVjdGlvbi5yYW5nZXMpIHtcblxuXHRcdFx0aWYocmFuZ2UudG8gLSByYW5nZS5mcm9tID4gMSkge1xuXG5cdFx0XHRcdGlzU2VsZWN0aW5nID0gdHJ1ZTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGlzU2VsZWN0aW5nXG59IiwiLyoqXG4gKiBGaWxlOiAvc3JjL2xpdmVfcHJldmlldy9jbTZfbGl2ZVByZWl2ZXdfb25DbGlja0ZpeC50cyAgICAgICAgICAgICAgICAgICAgICAgKlxuICogQ3JlYXRlZCBEYXRlOiBGcmlkYXksIE1hcmNoIDI0dGggMjAyMywgNjoxMCBwbSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqIEF1dGhvcjogQ2FtZXJvbiBSb2JpbnNvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogQ29weXJpZ2h0IChjKSAyMDIzIENhbWVyb24gUm9iaW5zb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqL1xuXG4vKipcbiAqIFRoaXMgbW9kdWxlIGlzIG1vc3RseSBhIGJvZGdlZCBmaXggZm9yIHRoZSBMaXZlIFByZXZpZXcgc2Nyb2xsaW5nIGlzc3VlIGNyZWF0ZWQgd2hlblxuICogbGFyZ2UgLyBsb25nIGNvbnRlbnQgKHN1Y2ggYXMgTUNNKSBpcyBiZWluZyByZW5kZXJlZCB0aHJvdWdoIGEgQ002IFN0YXRlRmllbGQuXG4gKiBUaGUgY29yZSBwcm9ibGVtIHRoaXMgbW9kdWxlIGFpbXMgdG8gXCJmaXhcIiBpcyBPYnNpZGlhbidzIHJlZHJhdyBhbmQgbWVtb3J5XG4gKiBtYW5hZ2VtZW50IHdoaWNoIGNhdXNlcyB0aGUgdmlld3BvcnQgdG8gc25hcCB0byB0aGUgYm90dG9tIG9mIHRoZSBkb2N1bWVudFxuICogb24gdXNlciBjbGljayBpbnRlcmFjdGlvbi4gXG4gKiBcbiAqIFRoaXMgQ002IHBsdWdpbiBtYWtlIHRoZSBlZGl0aW5nIGV4cGVyaWVuY2Ugd2l0aCBNQ00gbW9yZSB1c2VyIGZpZW5kbHkgYnkgc25hcHBpbmcgXG4gKiB0aGUgdmlldyBiYWNrIHRvIHRoZSBjdXJzb3IgYWZ0ZXIgT2JzaWRpYW4gaGFzIHBlcmZvcm1lZCBpdCdzIGZ1bGwgTFAgcmVkcmF3LCBhbmQgXG4gKiBjdWxsZWQgb3V0IHVubmVlZGVkIGVsZW1lbnRzIGZyb20gdGhlIExQIHZpZXcuXG4gKiBcbiAqIElmIHRoZSBjb3JlIHByb2JsZW0gaXMgZXZlciBmaXhlZCBieSBPYnNpZGlhbiwgdGhpcyBtb2R1bGUgd2lsbCBiZWNvbWUgb2Jzb2xldGVcbiAqIGFuZCBiZSByZW1vdmVkLlxuICovXG5cbmltcG9ydCB7IEVkaXRvclNlbGVjdGlvbiwgRXh0ZW5zaW9uLCBSYW5nZVNldEJ1aWxkZXIsIFNlbGVjdGlvblJhbmdlLCBTdGF0ZUZpZWxkLCBUcmFuc2FjdGlvbiwgVHJhbnNhY3Rpb25TcGVjLCBUZXh0IH0gZnJvbSBcIkBjb2RlbWlycm9yL3N0YXRlXCI7XG5pbXBvcnQgeyBEZWNvcmF0aW9uLCBEZWNvcmF0aW9uU2V0LCBFZGl0b3JWaWV3IH0gZnJvbSBcIkBjb2RlbWlycm9yL3ZpZXdcIjtcbmltcG9ydCB7IGNvbnRhaW5zRW5kVGFnLCBjb250YWluc1JlZ2lvblN0YXJ0IH0gZnJvbSBcIi4uL3V0aWxpdGllcy90ZXh0UGFyc2VyXCI7XG5pbXBvcnQgeyBlZGl0b3JFZGl0b3JGaWVsZCwgZWRpdG9yTGl2ZVByZXZpZXdGaWVsZCB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgTW91c2VTdGF0ZSwgbW91c2VTdGF0ZSB9IGZyb20gXCJzcmMvdXRpbGl0aWVzL2ludGVyZmFjZXNcIjtcblxuY29uc3QgRURJVE9SX1ZJRVdfR0NfVElNRU9VVF9NUyA9IDE1MDAwMCAvLyAyLjVtIGluIG1zXG5cbmFic3RyYWN0IGNsYXNzIEVkaXRvckNhbGxiYWNrTWFuYWdlciB7XG5cdHByb3RlY3RlZCBfcmVnYWluZWRGb2N1czogYm9vbGVhbiA9IHRydWU7XG5cdHB1YmxpYyBnZXQgcmVnYWluZWRGb2N1cygpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5fcmVnYWluZWRGb2N1cztcblx0fVxuXG5cdHByb3RlY3RlZCBfbG9zdEZvY3VzOiBib29sZWFuID0gdHJ1ZTtcblx0cHVibGljIGdldCBsb3N0Rm9jdXMoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuX2xvc3RGb2N1cztcblx0fVxuXG5cdHByb3RlY3RlZCBfaGFzRm9jdXM6IGJvb2xlYW47XG5cdHB1YmxpYyBnZXQgaGFzRm9jdXMoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuX2hhc0ZvY3VzO1xuXHR9XG5cdHB1YmxpYyBzZXQgaGFzRm9jdXModmFsdWU6IGJvb2xlYW4pIHtcblxuXHRcdGlmKHZhbHVlID09PSB0cnVlKSB7XG5cdFx0XHRpZih0aGlzLl9oYXNGb2N1cyA9PT0gZmFsc2UpIHtcblx0XHRcdFx0dGhpcy5fcmVnYWluZWRGb2N1cyA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0dGhpcy5fcmVnYWluZWRGb2N1cyA9IGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGlmKHRoaXMuX2hhc0ZvY3VzID09PSB0cnVlKSB7XG5cdFx0XHRcdHRoaXMuX2xvc3RGb2N1cyA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0dGhpcy5fbG9zdEZvY3VzID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhpcy5faGFzRm9jdXMgPSB2YWx1ZTtcblx0fVxufVxuXG5jbGFzcyBFZGl0b3JWaWV3U2Nyb2xsU3RhdGVNYW5hZ2VyIGV4dGVuZHMgRWRpdG9yQ2FsbGJhY2tNYW5hZ2Vye1xuXG5cdHByaXZhdGUgbGFzdFVzZVRpbWVzdGFtcDogbnVtYmVyID0gRGF0ZS5ub3coKTtcblxuXHQvLyBUT0RPOiBGaW5kIGEgd2F5IHRvIG5vdCByZXF1aXJlIHRoZSBlZGl0b3Igdmlldz8/XG5cdHByaXZhdGUgX2VkaXRvclZpZXc6IEVkaXRvclZpZXc7XG5cdHB1YmxpYyBnZXQgZWRpdG9yVmlldygpOiBFZGl0b3JWaWV3IHtcblx0XHRyZXR1cm4gdGhpcy5fZWRpdG9yVmlldztcblx0fVxuXG5cdHByaXZhdGUgX2xhc3REb2NTdGF0ZTogVGV4dDtcblx0cHVibGljIGdldCBsYXN0RG9jU3RhdGUoKTogVGV4dCB7XG5cdFx0cmV0dXJuIHRoaXMuX2xhc3REb2NTdGF0ZTtcblx0fVxuXHRwdWJsaWMgc2V0IGxhc3REb2NTdGF0ZSh2YWx1ZTogVGV4dCkge1xuXHRcdHRoaXMuX2xhc3REb2NTdGF0ZSA9IHZhbHVlO1xuXHR9XG5cblx0Ly8gQ3VycmVudGx5IHVudXNlZC4gS2VlcGluZyBzdG9yZWQgZm9yIGVhc3kgYWNjZXNzIGluIGZ1dHVyZS5cblx0cHJpdmF0ZSBfZG9jVGl0bGU6IHN0cmluZ1xuXHRwdWJsaWMgZ2V0IGRvY1RpdGxlKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMuX2RvY1RpdGxlXG5cdH1cblx0cHVibGljIHNldCBkb2NUaXRsZSh2YWx1ZTogc3RyaW5nKSB7XG5cblx0XHRsZXQgcGFyc2VkRG9jVGl0bGUgPSBhdHRlbXB0UGFyc2VEb2NUaXRsZSh2YWx1ZSlcblx0XHRpZihwYXJzZWREb2NUaXRsZSAhPT0gXCJcIikge1xuXG5cdFx0XHR0aGlzLl9kb2NUaXRsZSA9IHBhcnNlZERvY1RpdGxlO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLl9kb2NUaXRsZSA9IHZhbHVlO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoZWRpdG9yVmlldzogRWRpdG9yVmlldykge1xuXHRcdHN1cGVyKCk7XG5cblx0XHR0aGlzLl9lZGl0b3JWaWV3ID0gZWRpdG9yVmlldztcblx0XHR0aGlzLmhhc0ZvY3VzID0gdHJ1ZTtcblx0fVxuXG5cdHB1YmxpYyBoYXNCZWVuQWNjZXNzZWQoKSB7XG5cdFx0dGhpcy5sYXN0VXNlVGltZXN0YW1wID0gRGF0ZS5ub3coKTtcblx0fVxuXG5cdGdldCBpc1JlYWR5Rm9yR0MoKTogYm9vbGVhbiB7XG5cblx0XHRpZih0aGlzLl9lZGl0b3JWaWV3ID09PSBudWxsKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRsZXQgZGVsdGEgPSBEYXRlLm5vdygpIC0gdGhpcy5sYXN0VXNlVGltZXN0YW1wO1xuXHRcdGlmKCB0aGlzLl9lZGl0b3JWaWV3LmluVmlldyA9PT0gZmFsc2UgJiZcblx0XHQgICAgdGhpcy5fZWRpdG9yVmlldy5oYXNGb2N1cyA9PT0gZmFsc2UgJiYgXG5cdFx0XHRkZWx0YSA+IEVESVRPUl9WSUVXX0dDX1RJTUVPVVRfTVMpIHtcblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG5cbmNsYXNzIEVkaXRvckRlbGF5Q2FsbGJhY2sgZXh0ZW5kcyBFZGl0b3JDYWxsYmFja01hbmFnZXIge1xuXG5cdHB1YmxpYyBjYWxsYmFjazogKCkgPT4gdm9pZFxuXHRwcml2YXRlIGNyZWF0aW9uVGltZXN0YW1wOiBudW1iZXIgPSBEYXRlLm5vdygpO1xuXG5cdGdldCBjYWxsYmFja1Nob3VsZFRpbWVvdXQoKTogYm9vbGVhbiB7XG5cdFxuXHRcdGxldCBjdXJyZW50VGltZU1TID0gRGF0ZS5ub3coKTtcblx0XG5cdFx0bGV0IGRlbHRhID0gY3VycmVudFRpbWVNUyAtIHRoaXMuY3JlYXRpb25UaW1lc3RhbXBcblx0XG5cdFx0bGV0IG1heERlbHRhVGltZU1TID0gMjAwXG5cdFx0aWYoZGVsdGEgPiBtYXhEZWx0YVRpbWVNUykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG5jb25zdCBjbGlja0RlbGF5Q2FsbGJhY2tzOiBNYXA8c3RyaW5nLCBFZGl0b3JEZWxheUNhbGxiYWNrPiA9IG5ldyBNYXAoKTtcbmNvbnN0IG9wZW5FZGl0b3JWaWV3czogTWFwPEVkaXRvclZpZXcsIEVkaXRvclZpZXdTY3JvbGxTdGF0ZU1hbmFnZXI+ID0gbmV3IE1hcCgpO1xubGV0IGxhc3RHQ1Bhc3MgPSBEYXRlLm5vdygpO1xubGV0IGVkaXRvck1vdXNlU3RhdGU6IE1vdXNlU3RhdGUgPSBcInVwXCI7XG5cbmV4cG9ydCBjb25zdCBNdWx0aUNvbHVtbk1hcmtkb3duX09uQ2xpY2tGaXggPSBTdGF0ZUZpZWxkLmRlZmluZTxEZWNvcmF0aW9uU2V0Pih7XG5cdGNyZWF0ZShzdGF0ZSk6IERlY29yYXRpb25TZXQge1xuXHRcdHJldHVybiBEZWNvcmF0aW9uLm5vbmU7XG5cdH0sXG5cdHVwZGF0ZShvbGRTdGF0ZTogRGVjb3JhdGlvblNldCwgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uKTogRGVjb3JhdGlvblNldCB7XG5cdFx0Y29uc3QgYnVpbGRlciA9IG5ldyBSYW5nZVNldEJ1aWxkZXI8RGVjb3JhdGlvbj4oKTtcblx0XHRyZXR1cm4gYnVpbGRlci5maW5pc2goKTtcblxuXHRcdGlmKCBzaG91bGRSdW5HQ09uRWRpdG9yTWFwKCkgKSB7XG5cblx0XHRcdGZvcihsZXQgW2VkaXRvclZpZXcsIHNjcm9sbFN0YXRlTWFuYWdlcl0gb2Ygb3BlbkVkaXRvclZpZXdzKSB7XG5cblx0XHRcdFx0aWYoc2Nyb2xsU3RhdGVNYW5hZ2VyLmlzUmVhZHlGb3JHQykge1xuXHRcdFx0XHRcdG9wZW5FZGl0b3JWaWV3cy5kZWxldGUoZWRpdG9yVmlldyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cbiAgICAgICAgaWYodHJhbnNhY3Rpb24uc3RhdGUuZmllbGQoZWRpdG9yTGl2ZVByZXZpZXdGaWVsZCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gYnVpbGRlci5maW5pc2goKTtcbiAgICAgICAgfVxuXG5cdFx0aWYoIGlzVHJhbnNhY3Rpb25SYW5nZVNlbGVjdGlvbih0cmFuc2FjdGlvbikgPT09IHRydWUgKSB7XG5cdFx0XHRyZXR1cm4gYnVpbGRlci5maW5pc2goKTtcblx0XHR9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZW4gd2UgaGF2ZSB0aGUgd2hpbGUgZmlsZSB3ZSB0aGVuIGdldCB0aGUgZW50aXJlIGRvYyB0ZXh0IGFuZCBjaGVjayBpZiBpdCBcbiAgICAgICAgICogY29udGFpbnMgYSBNQ00gcmVnaW9uIHNvIHdlIGtub3cgdG8gYnJlYWsgb3Igbm90LlxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IGRvY0xlbmd0aCA9IHRyYW5zYWN0aW9uLnN0YXRlLmRvYy5sZW5ndGhcbiAgICAgICAgbGV0IGRvY1RleHQgPSB0cmFuc2FjdGlvbi5zdGF0ZS5kb2Muc2xpY2VTdHJpbmcoMCwgZG9jTGVuZ3RoKTtcbiAgICAgICAgaWYgKGNvbnRhaW5zUmVnaW9uU3RhcnQoZG9jVGV4dCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gYnVpbGRlci5maW5pc2goKTtcbiAgICAgICAgfVxuXG5cdFx0aWYobW91c2VTdGF0ZSA9PT0gXCJkb3duXCIpIHtcblx0XHRcdGVkaXRvck1vdXNlU3RhdGUgPSBtb3VzZVN0YXRlO1xuXHRcdH1cblxuXHRcdGNvbnN0IGVkaXRvclZpZXcgPSB0cmFuc2FjdGlvbi5zdGF0ZS5maWVsZChlZGl0b3JFZGl0b3JGaWVsZCk7XG5cdFx0XG5cdFx0bGV0IHNjcm9sbFN0YXRlTWFuYWdlcjogRWRpdG9yVmlld1Njcm9sbFN0YXRlTWFuYWdlciA9IGdldFNjcm9sbFN0YXRlTWFuYWdlcihlZGl0b3JWaWV3LCB0cmFuc2FjdGlvbik7XG5cdFx0c2Nyb2xsU3RhdGVNYW5hZ2VyLmxhc3REb2NTdGF0ZSA9IHRyYW5zYWN0aW9uLm5ld0RvY1xuXHRcdHNjcm9sbFN0YXRlTWFuYWdlci5kb2NUaXRsZSA9IGVkaXRvclZpZXcuZG9tLm93bmVyRG9jdW1lbnQudGl0bGU7XG5cblx0XHRpZihlZGl0b3JWaWV3Lmhhc0ZvY3VzID09PSB0cnVlKSB7XG5cdFx0XHRzY3JvbGxTdGF0ZU1hbmFnZXIuaGFzRm9jdXMgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGxldCBjdXJzb3JMb2NhdGlvbjogU2VsZWN0aW9uUmFuZ2UgPSBnZXRNYWluQ3Vyc29yTG9jYXRpb24odHJhbnNhY3Rpb24pO1xuXHRcdGlmKGN1cnNvckxvY2F0aW9uICE9PSBudWxsKSB7XG5cdFx0XHRsZXQgdGV4dEFib3ZlQ3Vyc29yID0gZG9jVGV4dC5zbGljZSgwLCBjdXJzb3JMb2NhdGlvbi5mcm9tKTtcblxuXHRcdFx0bGV0IGVuZFRhZ0Fib3ZlQ3Vyc29yID0gY29udGFpbnNFbmRUYWcodGV4dEFib3ZlQ3Vyc29yKTtcblx0XHRcdGlmKGVuZFRhZ0Fib3ZlQ3Vyc29yID09PSBmYWxzZSkge1xuXHRcdFx0XHRyZXR1cm4gYnVpbGRlci5maW5pc2goKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiggdHJhbnNhY3Rpb25Jc1ZhbGlkTW91c2VEb3duRXZlbnQodHJhbnNhY3Rpb24sIGN1cnNvckxvY2F0aW9uKSApIHtcblx0XHRcdFxuXHRcdFx0aGFuZGxlTW91c2VEb3duRXZlbnQodHJhbnNhY3Rpb24sIGVkaXRvclZpZXcsIGN1cnNvckxvY2F0aW9uKTtcblx0XHR9XG5cdFx0ZWxzZSBpZiggdHJhbnNhY3Rpb25Jc01vdXNlVXBFdmVudCh0cmFuc2FjdGlvbikgKSB7XG5cblx0XHRcdGhhbmRsZU1vdXNlVXBFdmVudCh0cmFuc2FjdGlvbik7XG5cdFx0fVxuXHRcdGVsc2UgaWYoZWRpdG9ySGFzQmVlbkNsaWNrZWRBd2F5RnJvbSh0cmFuc2FjdGlvbiwgZWRpdG9yVmlldywgc2Nyb2xsU3RhdGVNYW5hZ2VyKSkge1xuXG5cdFx0XHRsZXQgcmVmb2N1c0xvY2F0aW9uID0gc2hvdWxkUmVmb2N1c09uQ3Vyc29yT3JWaWV3cG9ydChlZGl0b3JWaWV3LCBjdXJzb3JMb2NhdGlvbiwgZG9jTGVuZ3RoKTtcblx0XHRcdHJlZm9jdXNPbkN1cnNvckFyZWEocmVmb2N1c0xvY2F0aW9uLCBlZGl0b3JWaWV3KTtcblx0XHRcdHNjcm9sbFN0YXRlTWFuYWdlci5oYXNGb2N1cyA9IGZhbHNlO1xuXHRcdH1cblx0XHQvLyBlbHNlIGlmKCBlZGl0b3JIYXNCZWVuQ2xpY2tlZEJhY2tJbnRvKHRyYW5zYWN0aW9uLCBzY3JvbGxTdGF0ZU1hbmFnZXIsIGVkaXRvclZpZXcpICl7XG5cdFx0Ly8gIC8vIFRPRE86IEJ1ZyB3aGVyZSBjbGlja2luZyBiYWNrIGludG8gZWRpdG9yIHdpdGhvdXQgc2VsZWN0aW5nIGEgbmV3IGN1cnNvciBsb2NhdGlvbiBcblx0XHQvLyAgLy8gd2lsbCBjYXVzZSBlZGl0b3IgdG8ganVtcCB0byB0b3Agb2YgZG9jLiBEbyBub3QgaGF2ZSB3YXkgdG8gcHJldmVudCB0aGlzIGFzIG9mIG5vdy5cblx0XHQvLyBcdGNvbnNvbGUubG9nKFwiRWRpdG9yIGhhcyBiZWVuIHJlZm9jdXNlZCB3aXRoIG51bGwgY3Vyc29yIGxvY2F0aW9uLlwiKVxuXHRcdC8vIH1cblx0XHRlbHNlIGlmKCBlZGl0b3JNb3VzZVN0YXRlID09PSBcImRvd25cIiAmJiBtb3VzZVN0YXRlID09PSBcInVwXCIgJiZcblx0XHRcdFx0IHRyYW5zYWN0aW9uLnN0YXRlLnNlbGVjdGlvbi5yYW5nZXMgJiYgXG5cdFx0XHRcdCB0cmFuc2FjdGlvbi5zdGF0ZS5zZWxlY3Rpb24ucmFuZ2VzLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdGVkaXRvck1vdXNlU3RhdGUgPSBtb3VzZVN0YXRlO1xuXHRcdFx0bGV0IHJlZm9jdXNMb2NhdGlvbiA9IHNob3VsZFJlZm9jdXNPbkN1cnNvck9yVmlld3BvcnQoZWRpdG9yVmlldywgY3Vyc29yTG9jYXRpb24sIGRvY0xlbmd0aCk7XG5cdFx0XHRyZWZvY3VzT25DdXJzb3JBcmVhKHJlZm9jdXNMb2NhdGlvbiwgZWRpdG9yVmlldyk7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXG5cdFx0XHRjbGVhclVuVXNlZEVudHJpZXModHJhbnNhY3Rpb24pO1xuXHRcdH1cblxuICAgICAgICByZXR1cm4gYnVpbGRlci5maW5pc2goKTtcblx0fSxcblx0cHJvdmlkZShmaWVsZDogU3RhdGVGaWVsZDxEZWNvcmF0aW9uU2V0Pik6IEV4dGVuc2lvbiB7XG5cdFx0cmV0dXJuIEVkaXRvclZpZXcuZGVjb3JhdGlvbnMuZnJvbShmaWVsZCk7XG5cdH0sXG59KTtcblxuZnVuY3Rpb24gZWRpdG9ySGFzQmVlbkNsaWNrZWRCYWNrSW50byh0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24sIHNjcm9sbFN0YXRlTWFuYWdlcjogRWRpdG9yVmlld1Njcm9sbFN0YXRlTWFuYWdlciwgZWRpdG9yVmlldzogRWRpdG9yVmlldyk6IGJvb2xlYW4ge1xuXG5cdGlmKHRyYW5zYWN0aW9uLmlzVXNlckV2ZW50KFwic2VsZWN0LnBvaW50ZXJcIikgPT09IGZhbHNlICYmXG5cdCAgIHNjcm9sbFN0YXRlTWFuYWdlci5oYXNGb2N1cyA9PT0gZmFsc2UgJiZcblx0ICAgc2Nyb2xsU3RhdGVNYW5hZ2VyLnJlZ2FpbmVkRm9jdXMgPT09IGZhbHNlICYmIFxuXHQgICBzY3JvbGxTdGF0ZU1hbmFnZXIubG9zdEZvY3VzID09PSBmYWxzZSAmJiBcblx0ICAgZWRpdG9yVmlldy5pblZpZXcpIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0TWFpbkN1cnNvckxvY2F0aW9uKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbik6IFNlbGVjdGlvblJhbmdlIHtcblxuXHRsZXQgY3Vyc29yTG9jYXRpb246IFNlbGVjdGlvblJhbmdlID0gbnVsbDtcblx0aWYgKHRyYW5zYWN0aW9uLnN0YXRlLnNlbGVjdGlvbi5yYW5nZXMgJiZcblx0XHR0cmFuc2FjdGlvbi5zdGF0ZS5zZWxlY3Rpb24ucmFuZ2VzLmxlbmd0aCA+IDApIHtcblxuXHRcdGN1cnNvckxvY2F0aW9uID0gdHJhbnNhY3Rpb24uc3RhdGUuc2VsZWN0aW9uLnJhbmdlc1swXTtcblx0fVxuXG5cdHJldHVybiBjdXJzb3JMb2NhdGlvbjtcbn1cblxuZnVuY3Rpb24gaGFuZGxlTW91c2VEb3duRXZlbnQodHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uLCBlZGl0b3JWaWV3OiBFZGl0b3JWaWV3LCBjdXJzb3JMb2NhdGlvbjogU2VsZWN0aW9uUmFuZ2UpIHtcblxuXHRsZXQgeDogVHJhbnNhY3Rpb25TcGVjID0ge1xuXHRcdGVmZmVjdHM6IEVkaXRvclZpZXcuc2Nyb2xsSW50b1ZpZXcoY3Vyc29yTG9jYXRpb24sIHtcblx0XHRcdHk6IFwiY2VudGVyXCJcblx0XHR9KVxuXHR9O1xuXG5cdGFzeW5jIGZ1bmN0aW9uIGRlbGF5KCkge1xuXHRcdGF3YWl0IHNsZWVwKDE1KTtcblx0XHRlZGl0b3JWaWV3LmRpc3BhdGNoKHgpO1xuXHR9XG5cdGxldCBkZWxheUNhbGxiYWNrRGF0YSA9IG5ldyBFZGl0b3JEZWxheUNhbGxiYWNrKCk7XG5cdGRlbGF5Q2FsbGJhY2tEYXRhLmNhbGxiYWNrID0gZGVsYXk7XG5cdGNsaWNrRGVsYXlDYWxsYmFja3Muc2V0KHRyYW5zYWN0aW9uLnN0YXRlLnNsaWNlRG9jKCksIGRlbGF5Q2FsbGJhY2tEYXRhKTtcblxuXHRpZiAoaXNSYW5nZWRTZWxlY3Rpb24oW2N1cnNvckxvY2F0aW9uXSkgPT09IGZhbHNlIHx8XG5cdFx0ZGVsYXlDYWxsYmFja0RhdGEucmVnYWluZWRGb2N1cyA9PT0gdHJ1ZSkge1xuXHRcdGRlbGF5KCk7XG5cdH1cbn1cblxuZnVuY3Rpb24gdHJhbnNhY3Rpb25Jc1ZhbGlkTW91c2VEb3duRXZlbnQodHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uLCBjdXJzb3JMb2NhdGlvbjogU2VsZWN0aW9uUmFuZ2UpIHtcblx0cmV0dXJuIHRyYW5zYWN0aW9uLmlzVXNlckV2ZW50KFwic2VsZWN0LnBvaW50ZXJcIikgJiZcblx0XHRjdXJzb3JMb2NhdGlvbiAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gdHJhbnNhY3Rpb25Jc01vdXNlVXBFdmVudCh0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24pOiBib29sZWFuIHtcblxuXHRpZiggdHJhbnNhY3Rpb24uZG9jQ2hhbmdlZCA9PT0gZmFsc2UgJiYgXG5cdCAgICBjbGlja0RlbGF5Q2FsbGJhY2tzLmhhcyh0cmFuc2FjdGlvbi5zdGF0ZS5zbGljZURvYygpKSApIHtcblxuXHRcdFx0ZWRpdG9yTW91c2VTdGF0ZSA9IG1vdXNlU3RhdGU7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGdldFNjcm9sbFN0YXRlTWFuYWdlcihlZGl0b3JWaWV3OiBFZGl0b3JWaWV3LCB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24pIHtcblx0XG5cdGlmIChvcGVuRWRpdG9yVmlld3MuaGFzKGVkaXRvclZpZXcpID09PSBmYWxzZSkge1xuXG5cdFx0bGV0IHNjcm9sbFN0YXRlTWFuYWdlcjogRWRpdG9yVmlld1Njcm9sbFN0YXRlTWFuYWdlciA9IG5ldyBFZGl0b3JWaWV3U2Nyb2xsU3RhdGVNYW5hZ2VyKGVkaXRvclZpZXcpO1xuXHRcdG9wZW5FZGl0b3JWaWV3cy5zZXQoZWRpdG9yVmlldywgc2Nyb2xsU3RhdGVNYW5hZ2VyKTtcblxuXHRcdHJldHVybiBzY3JvbGxTdGF0ZU1hbmFnZXI7XG5cdH1cblxuXHRsZXQgc2Nyb2xsU3RhdGVNYW5hZ2VyOiBFZGl0b3JWaWV3U2Nyb2xsU3RhdGVNYW5hZ2VyID0gb3BlbkVkaXRvclZpZXdzLmdldChlZGl0b3JWaWV3KTtcblx0aWYgKHRyYW5zYWN0aW9uU3dhcHBlZEVkaXRvckZpbGUodHJhbnNhY3Rpb24sIHNjcm9sbFN0YXRlTWFuYWdlcikpIHtcblxuXHRcdHNjcm9sbFN0YXRlTWFuYWdlciA9IG5ldyBFZGl0b3JWaWV3U2Nyb2xsU3RhdGVNYW5hZ2VyKGVkaXRvclZpZXcpO1xuXHRcdG9wZW5FZGl0b3JWaWV3cy5zZXQoZWRpdG9yVmlldywgc2Nyb2xsU3RhdGVNYW5hZ2VyKTtcblx0XHRyZXR1cm4gc2Nyb2xsU3RhdGVNYW5hZ2VyO1xuXHR9XG5cblx0c2Nyb2xsU3RhdGVNYW5hZ2VyLmhhc0JlZW5BY2Nlc3NlZCgpO1x0XG5cdHJldHVybiBzY3JvbGxTdGF0ZU1hbmFnZXI7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZU1vdXNlVXBFdmVudCh0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24pIHtcblxuXHRsZXQgZGVsYXlDYWxsYmFja0RhdGEgPSBjbGlja0RlbGF5Q2FsbGJhY2tzLmdldCh0cmFuc2FjdGlvbi5zdGF0ZS5zbGljZURvYygpKTtcblx0ZGVsYXlDYWxsYmFja0RhdGEuY2FsbGJhY2soKTtcblx0aWYgKGRlbGF5Q2FsbGJhY2tEYXRhLmNhbGxiYWNrU2hvdWxkVGltZW91dCA9PT0gdHJ1ZSkge1xuXHRcdGNsaWNrRGVsYXlDYWxsYmFja3MuZGVsZXRlKHRyYW5zYWN0aW9uLnN0YXRlLnNsaWNlRG9jKCkpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNsZWFyVW5Vc2VkRW50cmllcyh0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24pIHtcblxuXHRmb3IgKGxldCBba2V5LCB2YWx1ZV0gb2YgY2xpY2tEZWxheUNhbGxiYWNrcykge1xuXHRcdGlmICh2YWx1ZS5jYWxsYmFja1Nob3VsZFRpbWVvdXQgPT09IHRydWUpIHtcblx0XHRcdGNsaWNrRGVsYXlDYWxsYmFja3MuZGVsZXRlKHRyYW5zYWN0aW9uLnN0YXRlLnNsaWNlRG9jKCkpO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBzaG91bGRSZWZvY3VzT25DdXJzb3JPclZpZXdwb3J0KGVkaXRvclZpZXc6IEVkaXRvclZpZXcsIGN1cnNvckxvY2F0aW9uOiBTZWxlY3Rpb25SYW5nZSwgZG9jTGVuZ3RoOiBudW1iZXIpOiBTZWxlY3Rpb25SYW5nZSB7XG5cblx0Y29uc3QgVklFV1BPUlRfQ1VSU09SX1JFRk9DVVNfUkFOR0UgPSAzMDA7XG5cblx0bGV0IHZpZXdwb3J0UmFuZ2UgPSBlZGl0b3JWaWV3LnZpZXdwb3J0O1xuXHRpZih2aWV3cG9ydFJhbmdlLmZyb20gKyBWSUVXUE9SVF9DVVJTT1JfUkVGT0NVU19SQU5HRSA8PSBjdXJzb3JMb2NhdGlvbi5mcm9tICYmIGN1cnNvckxvY2F0aW9uLmZyb20gPD0gdmlld3BvcnRSYW5nZS50byAtIFZJRVdQT1JUX0NVUlNPUl9SRUZPQ1VTX1JBTkdFKSB7XG5cdFx0cmV0dXJuIGN1cnNvckxvY2F0aW9uO1xuXHR9XG5cblx0aWYodmlld3BvcnRSYW5nZS5mcm9tID09PSAwKSB7XG5cdFx0cmV0dXJuIEVkaXRvclNlbGVjdGlvbi5jdXJzb3IoMCk7XG5cdH1cblxuXHRpZih2aWV3cG9ydFJhbmdlLnRvID49IGRvY0xlbmd0aCkge1xuXHRcdHJldHVybiBFZGl0b3JTZWxlY3Rpb24uY3Vyc29yKGRvY0xlbmd0aCk7XG5cdH1cblxuXHRsZXQgbG9jYXRpb24gPSB2aWV3cG9ydFJhbmdlLmZyb20gKyBNYXRoLmZsb29yKCh2aWV3cG9ydFJhbmdlLnRvIC0gdmlld3BvcnRSYW5nZS5mcm9tKSAvIDIpO1xuXHRyZXR1cm4gRWRpdG9yU2VsZWN0aW9uLmN1cnNvcihsb2NhdGlvbilcbn1cblxuZnVuY3Rpb24gcmVmb2N1c09uQ3Vyc29yQXJlYShjdXJzb3JMb2NhdGlvbjogU2VsZWN0aW9uUmFuZ2UsIGVkaXRvclZpZXc6IEVkaXRvclZpZXcpIHtcblxuXHRsZXQgeDogVHJhbnNhY3Rpb25TcGVjID0ge1xuXHRcdGVmZmVjdHM6IEVkaXRvclZpZXcuc2Nyb2xsSW50b1ZpZXcoY3Vyc29yTG9jYXRpb24sIHtcblx0XHRcdHk6IFwiY2VudGVyXCJcblx0XHR9KVxuXHR9XG5cblx0YXN5bmMgZnVuY3Rpb24gZGVsYXkoKSB7XG5cdFx0YXdhaXQgc2xlZXAoMTAwKTtcblx0XHRlZGl0b3JWaWV3LmRpc3BhdGNoKHgpXG5cdH1cblx0ZGVsYXkoKVxufVxuXG5mdW5jdGlvbiBlZGl0b3JIYXNCZWVuQ2xpY2tlZEF3YXlGcm9tKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbiwgZWRpdG9yVmlldzogRWRpdG9yVmlldywgc2Nyb2xsU3RhdGVNYW5hZ2VyOiBFZGl0b3JWaWV3U2Nyb2xsU3RhdGVNYW5hZ2VyKTogYm9vbGVhbiB7XG5cblx0aWYoIHRyYW5zYWN0aW9uLmRvY0NoYW5nZWQgPT09IGZhbHNlICYmIFxuXHRcdGVkaXRvclZpZXcuaGFzRm9jdXMgICAgPT09IGZhbHNlICYmIFxuXHRcdGVkaXRvclZpZXcuaW5WaWV3ICAgICAgPT09IHRydWUgICYmXG5cdFx0c2Nyb2xsU3RhdGVNYW5hZ2VyLmhhc0ZvY3VzICA9PT0gdHJ1ZSAgJiZcblx0XHRzY3JvbGxTdGF0ZU1hbmFnZXIubG9zdEZvY3VzID09PSB0cnVlICAgICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNSYW5nZWRTZWxlY3Rpb24oY3Vyc29yTG9jYXRpb25zOiBTZWxlY3Rpb25SYW5nZVtdKSB7XG5cblx0Zm9yKGxldCByYW5nZSBvZiBjdXJzb3JMb2NhdGlvbnMpIHtcblx0XHRpZihyYW5nZS50byAtIHJhbmdlLmZyb20gPiAxKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBpc1RyYW5zYWN0aW9uUmFuZ2VTZWxlY3Rpb24odHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uKTogYm9vbGVhbiB7XG5cblx0aWYodHJhbnNhY3Rpb24uaXNVc2VyRXZlbnQoXCJzZWxlY3QucG9pbnRlclwiKSAmJiBcblx0ICAgdHJhbnNhY3Rpb24uc3RhdGUuc2VsZWN0aW9uLnJhbmdlcyAmJiBcblx0ICAgdHJhbnNhY3Rpb24uc3RhdGUuc2VsZWN0aW9uLnJhbmdlcy5sZW5ndGggPiAwICYmXG5cdCAgIGlzUmFuZ2VkU2VsZWN0aW9uKHRyYW5zYWN0aW9uLnN0YXRlLnNlbGVjdGlvbi5yYW5nZXMuc2xpY2UoKSkpIHtcblxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gdHJhbnNhY3Rpb25Td2FwcGVkRWRpdG9yRmlsZSh0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24sIHNjcm9sbFN0YXRlTWFuYWdlcjogRWRpdG9yVmlld1Njcm9sbFN0YXRlTWFuYWdlcik6IGJvb2xlYW4ge1xuXG5cdC8vIElmIG9uIHRoaXMgdHJhbnNhY3Rpb24gdGhlcmUgYXJlIG11bHRpcGxlIHNlbGVjdGlvbiByYW5nZXMgd2Uga25vd1xuXHQvLyB0aGUgdXNlciBjYW4gbm90IGhhdmUgc3dhcHBlZCB0byBhIG5ldyBmaWxlIHRoaXMgdHJhbnNhY3Rpb24uXG5cdGlmKHRyYW5zYWN0aW9uLnN0YXRlLnNlbGVjdGlvbi5yYW5nZXMubGVuZ3RoICE9PSAxKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0Ly8gT24gbmV3IGRvY3VtZW50IGxvYWQgdGhlIGN1cnNvciBpcyBwbGFjZWQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlsZS5cblx0Ly8gSWYgY3Vyc29yIGlzIG5vdCBhdCB0aGlzIGxvY2F0aW9uIHdlIGtub3cgaXQgaXNudCBkb2N1bWVudCBsb2FkLlxuXHRpZih0cmFuc2FjdGlvbi5zdGF0ZS5zZWxlY3Rpb24ucmFuZ2VzWzBdLmZyb20gIT09IDAgJiZcblx0ICAgdHJhbnNhY3Rpb24uc3RhdGUuc2VsZWN0aW9uLnJhbmdlc1swXS50byAgICE9PSAwKSB7XG5cdCAgIHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8vIE1ha2Ugc3VyZSB0cmFuc2FjdGlvbiBpcyBub3QgYWxzbyBhIHVzZXIgZXZlbnQuIEF0IHRoaXMgcG9pbnQgc2hvdWxkIHdlIGJlIGZhaXJseVxuXHQvLyBjZXJ0YWluIHRoYXQgdGhpcyBpcyBhIGRvY3VtZW50IGxvYWQ/XG5cdGlmKHRyYW5zYWN0aW9uLmlzVXNlckV2ZW50KFwiaW5wdXRcIikgIHx8IFxuXHQgICB0cmFuc2FjdGlvbi5pc1VzZXJFdmVudChcImRlbGV0ZVwiKSB8fFxuXHQgICB0cmFuc2FjdGlvbi5pc1VzZXJFdmVudChcIm1vdmVcIikgICB8fCBcblx0ICAgdHJhbnNhY3Rpb24uaXNVc2VyRXZlbnQoXCJzZWxlY3RcIikgfHxcblx0ICAgdHJhbnNhY3Rpb24uaXNVc2VyRXZlbnQoXCJ1bmRvXCIpICAgfHxcblx0ICAgdHJhbnNhY3Rpb24uaXNVc2VyRXZlbnQoXCJyZWRvXCIpKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0aWYoc2Nyb2xsU3RhdGVNYW5hZ2VyLmxhc3REb2NTdGF0ZSA9PT0gdHJhbnNhY3Rpb24ubmV3RG9jKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0cmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHNob3VsZFJ1bkdDT25FZGl0b3JNYXAoKTogYm9vbGVhbiB7XG5cdFxuXHRjb25zdCBHQ19ERUxUQV9USU1FUiA9IDMwMDAwIC8vIDMwc1xuXG5cdGxldCBkZWx0YSA9IERhdGUubm93KCkgLSBsYXN0R0NQYXNzO1xuXHRpZihkZWx0YSA+IEdDX0RFTFRBX1RJTUVSKSB7XG5cblx0XHRsYXN0R0NQYXNzID0gRGF0ZS5ub3coKTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGF0dGVtcHRQYXJzZURvY1RpdGxlKHZhbHVlOiBzdHJpbmcpIHtcblxuXHRmb3IobGV0IGkgPSAwOyBpIDwgMjsgaSsrKSB7XG5cblx0XHRsZXQgcmVzdWx0ID0gLyguKikgLSAuKi8uZXhlYyh2YWx1ZSlcblx0XHRpZihyZXN1bHQgIT09IG51bGwgJiYgcmVzdWx0Lmxlbmd0aCA+IDEpIHtcblx0XHRcdHZhbHVlID0gcmVzdWx0WzFdO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdHJldHVybiBcIlwiXG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHZhbHVlO1xufSIsImV4cG9ydCB0eXBlIFN5bnRheFJlc3VsdCA9IHtcbiAgICBmaWxlQ291bnQ6IG51bWJlcjtcbiAgICByZWdpb25TdGFydENvdW50OiBudW1iZXI7XG4gICAgY29sdW1uQnJlYWtDb3VudDogbnVtYmVyXG4gICAgY29sdW1uRW5kQ291bnQ6IG51bWJlcjtcbiAgICB1cGRhdGVkRmlsZUNvbnRlbnQ6IHN0cmluZztcbiAgICBmaWxlV2FzVXBkYXRlZDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUFsbFN5bnRheChvcmlnaW5hbEZpbGVDb250ZW50OiBzdHJpbmcpOiBTeW50YXhSZXN1bHQge1xuXG4gICAgbGV0IGZpbGVDb3VudCA9IDBcbiAgICBsZXQgcmVnaW9uU3RhcnRDb3VudCA9IDA7XG4gICAgbGV0IGNvbHVtbkJyZWFrQ291bnQgPSAwO1xuICAgIGxldCBjb2x1bW5FbmRDb3VudCA9IDA7XG5cbiAgICBsZXQgZmlsZVVwZGF0ZWQgPSBmYWxzZTtcbiAgICBsZXQgeyB1cGRhdGVkRmlsZUNvbnRlbnQsIG51bVJlZ2lvbnNVcGRhdGVkIH0gPSB1cGRhdGVDb2x1bW5Db2RlYmxvY2tTdGFydFN5bnRheChvcmlnaW5hbEZpbGVDb250ZW50KTtcbiAgICBpZihudW1SZWdpb25zVXBkYXRlZCA+IDApIHtcbiAgICAgICAgZmlsZUNvdW50Kys7XG4gICAgICAgIGZpbGVVcGRhdGVkID0gdHJ1ZTtcbiAgICAgICAgcmVnaW9uU3RhcnRDb3VudCArPSBudW1SZWdpb25zVXBkYXRlZFxuICAgIH1cblxuICAgIGxldCBjb2xTdGFydCA9IHVwZGF0ZUNvbHVtblN0YXJ0U3ludGF4KHVwZGF0ZWRGaWxlQ29udGVudClcbiAgICBpZihjb2xTdGFydC5udW1SZWdpb25zVXBkYXRlZCkge1xuICAgICAgICBpZihmaWxlVXBkYXRlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGZpbGVVcGRhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGZpbGVDb3VudCsrO1xuICAgICAgICB9XG4gICAgICAgIHVwZGF0ZWRGaWxlQ29udGVudCA9IGNvbFN0YXJ0LnVwZGF0ZWRGaWxlQ29udGVudFxuICAgICAgICByZWdpb25TdGFydENvdW50ICs9IGNvbFN0YXJ0Lm51bVJlZ2lvbnNVcGRhdGVkXG4gICAgfVxuXG4gICAgbGV0IGNvbEJyZWFrID0gdXBkYXRlQ29sdW1uQnJlYWtTeW50YXgodXBkYXRlZEZpbGVDb250ZW50KVxuICAgIGlmKGNvbEJyZWFrLm51bVJlZ2lvbnNVcGRhdGVkKSB7XG4gICAgICAgIGlmKGZpbGVVcGRhdGVkID09PSBmYWxzZSkge1xuICAgICAgICAgICAgZmlsZVVwZGF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgZmlsZUNvdW50Kys7XG4gICAgICAgIH1cbiAgICAgICAgdXBkYXRlZEZpbGVDb250ZW50ID0gY29sQnJlYWsudXBkYXRlZEZpbGVDb250ZW50XG4gICAgICAgIGNvbHVtbkJyZWFrQ291bnQgKz0gY29sQnJlYWsubnVtUmVnaW9uc1VwZGF0ZWRcbiAgICB9XG5cbiAgICBsZXQgY29sRW5kID0gdXBkYXRlQ29sdW1uRW5kU3ludGF4KHVwZGF0ZWRGaWxlQ29udGVudClcbiAgICBpZihjb2xFbmQubnVtUmVnaW9uc1VwZGF0ZWQpIHtcbiAgICAgICAgaWYoZmlsZVVwZGF0ZWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBmaWxlVXBkYXRlZCA9IHRydWU7XG4gICAgICAgICAgICBmaWxlQ291bnQrKztcbiAgICAgICAgfVxuICAgICAgICB1cGRhdGVkRmlsZUNvbnRlbnQgPSBjb2xFbmQudXBkYXRlZEZpbGVDb250ZW50XG4gICAgICAgIGNvbHVtbkVuZENvdW50ICs9IGNvbEVuZC5udW1SZWdpb25zVXBkYXRlZDsgICBcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBmaWxlQ291bnQ6IGZpbGVDb3VudCxcbiAgICAgICAgcmVnaW9uU3RhcnRDb3VudDogcmVnaW9uU3RhcnRDb3VudCxcbiAgICAgICAgY29sdW1uQnJlYWtDb3VudDogY29sdW1uQnJlYWtDb3VudCxcbiAgICAgICAgY29sdW1uRW5kQ291bnQ6IGNvbHVtbkVuZENvdW50LFxuICAgICAgICB1cGRhdGVkRmlsZUNvbnRlbnQ6IHVwZGF0ZWRGaWxlQ29udGVudCxcbiAgICAgICAgZmlsZVdhc1VwZGF0ZWQ6IHVwZGF0ZWRGaWxlQ29udGVudCAhPT0gb3JpZ2luYWxGaWxlQ29udGVudFxuICAgIH1cbn1cblxuY29uc3QgT0xEX0NPTF9FTkRfU1lOVEFYX1JFR0VYID0gLz09PSAqKGVuZC1tdWx0aS1jb2x1bW58bXVsdGktY29sdW1uLWVuZCkvZ1xuZnVuY3Rpb24gdXBkYXRlQ29sdW1uRW5kU3ludGF4KG9yaWdpbmFsRmlsZUNvbnRlbnQ6IHN0cmluZyk6IHsgdXBkYXRlZEZpbGVDb250ZW50OiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bVJlZ2lvbnNVcGRhdGVkOiBudW1iZXIgfSB7XG4gICAgbGV0IG1hdGNoZXMgPSBBcnJheS5mcm9tKG9yaWdpbmFsRmlsZUNvbnRlbnQubWF0Y2hBbGwoT0xEX0NPTF9FTkRfU1lOVEFYX1JFR0VYKSlcblxuICAgIGxldCB1cGRhdGVkRmlsZUNvbnRlbnQgPSBvcmlnaW5hbEZpbGVDb250ZW50O1xuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIFxuICAgIGZvcihsZXQgbWF0Y2ggb2YgbWF0Y2hlcykgeyAgICBcbiAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSBtYXRjaC5pbmRleCArIG9mZnNldFxuICAgICAgICBsZXQgbWF0Y2hMZW5ndGggPSBtYXRjaFswXS5sZW5ndGhcbiAgICAgICAgbGV0IGVuZEluZGV4ID0gc3RhcnRJbmRleCArIG1hdGNoTGVuZ3RoO1xuXG4gICAgICAgIGxldCBjb2x1bW5FbmRTeW50YXggPSBtYXRjaFsxXSAgICAgICAgXG4gICAgICAgIGxldCByZXBsYWNlbWVudFRleHQgPSBgLS0tICR7Y29sdW1uRW5kU3ludGF4fWBcbiAgICAgICAgb2Zmc2V0ICs9IHJlcGxhY2VtZW50VGV4dC5sZW5ndGggLSBtYXRjaExlbmd0aFxuXG4gICAgICAgIHVwZGF0ZWRGaWxlQ29udGVudCA9IHVwZGF0ZWRGaWxlQ29udGVudC5zbGljZSgwLCBzdGFydEluZGV4KSArIHJlcGxhY2VtZW50VGV4dCArIHVwZGF0ZWRGaWxlQ29udGVudC5zbGljZShlbmRJbmRleClcbiAgICAgICAgY29uc29sZS5ncm91cENvbGxhcHNlZCgpXG4gICAgICAgIGNvbnNvbGUubG9nKFwiT3JpZ2luYWwgRmlsZTpcXG5cXG5cIiwgb3JpZ2luYWxGaWxlQ29udGVudClcbiAgICAgICAgY29uc29sZS5sb2coXCJVcGRhdGVkIEZpbGU6XFxuXFxuXCIsIHVwZGF0ZWRGaWxlQ29udGVudClcbiAgICAgICAgY29uc29sZS5ncm91cEVuZCgpICAgICAgXG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHVwZGF0ZWRGaWxlQ29udGVudDogdXBkYXRlZEZpbGVDb250ZW50LFxuICAgICAgICBudW1SZWdpb25zVXBkYXRlZDogbWF0Y2hlcy5sZW5ndGhcbiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxufVxuXG5jb25zdCBPTERfQ09MX0JSRUFLX1NZTlRBWF9SRUdFWCA9IC89PT1cXHMqPyhjb2x1bW4tZW5kfGVuZC1jb2x1bW58Y29sdW1uLWJyZWFrfGJyZWFrLWNvbHVtbilcXHMqPz09PVxccyo/L2dcbmZ1bmN0aW9uIHVwZGF0ZUNvbHVtbkJyZWFrU3ludGF4KG9yaWdpbmFsRmlsZUNvbnRlbnQ6IHN0cmluZyk6IHsgdXBkYXRlZEZpbGVDb250ZW50OiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bVJlZ2lvbnNVcGRhdGVkOiBudW1iZXIgfSB7XG4gICAgbGV0IG1hdGNoZXMgPSBBcnJheS5mcm9tKG9yaWdpbmFsRmlsZUNvbnRlbnQubWF0Y2hBbGwoT0xEX0NPTF9CUkVBS19TWU5UQVhfUkVHRVgpKVxuXG4gICAgbGV0IHVwZGF0ZWRGaWxlQ29udGVudCA9IG9yaWdpbmFsRmlsZUNvbnRlbnQ7XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgXG4gICAgZm9yKGxldCBtYXRjaCBvZiBtYXRjaGVzKSB7ICAgIFxuICAgICAgICBsZXQgc3RhcnRJbmRleCA9IG1hdGNoLmluZGV4ICsgb2Zmc2V0XG4gICAgICAgIGxldCBtYXRjaExlbmd0aCA9IG1hdGNoWzBdLmxlbmd0aFxuICAgICAgICBsZXQgZW5kSW5kZXggPSBzdGFydEluZGV4ICsgbWF0Y2hMZW5ndGg7XG5cbiAgICAgICAgbGV0IGNvbHVtbkJyZWFrU3ludGF4ID0gbWF0Y2hbMV0gICAgICAgIFxuICAgICAgICBsZXQgcmVwbGFjZW1lbnRUZXh0ID0gYC0tLSAke2NvbHVtbkJyZWFrU3ludGF4fSAtLS1gXG4gICAgICAgIG9mZnNldCArPSByZXBsYWNlbWVudFRleHQubGVuZ3RoIC0gbWF0Y2hMZW5ndGhcblxuICAgICAgICB1cGRhdGVkRmlsZUNvbnRlbnQgPSB1cGRhdGVkRmlsZUNvbnRlbnQuc2xpY2UoMCwgc3RhcnRJbmRleCkgKyByZXBsYWNlbWVudFRleHQgKyB1cGRhdGVkRmlsZUNvbnRlbnQuc2xpY2UoZW5kSW5kZXgpXG4gICAgICAgIGNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQoKVxuICAgICAgICBjb25zb2xlLmxvZyhcIk9yaWdpbmFsIEZpbGU6XFxuXFxuXCIsIG9yaWdpbmFsRmlsZUNvbnRlbnQpXG4gICAgICAgIGNvbnNvbGUubG9nKFwiVXBkYXRlZCBGaWxlOlxcblxcblwiLCB1cGRhdGVkRmlsZUNvbnRlbnQpXG4gICAgICAgIGNvbnNvbGUuZ3JvdXBFbmQoKSAgICAgIFxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB1cGRhdGVkRmlsZUNvbnRlbnQ6IHVwZGF0ZWRGaWxlQ29udGVudCxcbiAgICAgICAgbnVtUmVnaW9uc1VwZGF0ZWQ6IG1hdGNoZXMubGVuZ3RoXG4gICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbn1cblxuY29uc3QgT0xEX0NPTF9TVEFSVF9TWU5UQVhfUkVHRVggPSAvPT09ICooc3RhcnQtbXVsdGktY29sdW1ufG11bHRpLWNvbHVtbi1zdGFydCkvZ1xuZnVuY3Rpb24gdXBkYXRlQ29sdW1uU3RhcnRTeW50YXgob3JpZ2luYWxGaWxlQ29udGVudDogc3RyaW5nKTogeyB1cGRhdGVkRmlsZUNvbnRlbnQ6IHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtUmVnaW9uc1VwZGF0ZWQ6IG51bWJlciB9IHtcbiAgICBsZXQgbWF0Y2hlcyA9IEFycmF5LmZyb20ob3JpZ2luYWxGaWxlQ29udGVudC5tYXRjaEFsbChPTERfQ09MX1NUQVJUX1NZTlRBWF9SRUdFWCkpXG5cbiAgICBsZXQgdXBkYXRlZEZpbGVDb250ZW50ID0gb3JpZ2luYWxGaWxlQ29udGVudDtcbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICBcbiAgICBmb3IobGV0IG1hdGNoIG9mIG1hdGNoZXMpIHsgICAgXG4gICAgICAgIGxldCBzdGFydEluZGV4ID0gbWF0Y2guaW5kZXggKyBvZmZzZXRcbiAgICAgICAgbGV0IG1hdGNoTGVuZ3RoID0gbWF0Y2hbMF0ubGVuZ3RoXG4gICAgICAgIGxldCBlbmRJbmRleCA9IHN0YXJ0SW5kZXggKyBtYXRjaExlbmd0aDtcblxuICAgICAgICBsZXQgY29sdW1uU3RhcnRTeW50YXggPSBtYXRjaFsxXSAgICAgICAgXG4gICAgICAgIGxldCByZXBsYWNlbWVudFRleHQgPSBgLS0tICR7Y29sdW1uU3RhcnRTeW50YXh9YFxuICAgICAgICBvZmZzZXQgKz0gcmVwbGFjZW1lbnRUZXh0Lmxlbmd0aCAtIG1hdGNoTGVuZ3RoXG5cbiAgICAgICAgdXBkYXRlZEZpbGVDb250ZW50ID0gdXBkYXRlZEZpbGVDb250ZW50LnNsaWNlKDAsIHN0YXJ0SW5kZXgpICsgcmVwbGFjZW1lbnRUZXh0ICsgdXBkYXRlZEZpbGVDb250ZW50LnNsaWNlKGVuZEluZGV4KVxuICAgICAgICBjb25zb2xlLmdyb3VwQ29sbGFwc2VkKClcbiAgICAgICAgY29uc29sZS5sb2coXCJPcmlnaW5hbCBGaWxlOlxcblxcblwiLCBvcmlnaW5hbEZpbGVDb250ZW50KVxuICAgICAgICBjb25zb2xlLmxvZyhcIlVwZGF0ZWQgRmlsZTpcXG5cXG5cIiwgdXBkYXRlZEZpbGVDb250ZW50KVxuICAgICAgICBjb25zb2xlLmdyb3VwRW5kKCkgICAgICBcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdXBkYXRlZEZpbGVDb250ZW50OiB1cGRhdGVkRmlsZUNvbnRlbnQsXG4gICAgICAgIG51bVJlZ2lvbnNVcGRhdGVkOiBtYXRjaGVzLmxlbmd0aFxuICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG59XG5cbmNvbnN0IE9MRF9DT0RFQkxPQ0tfQ09MX1NUQVJUX1NZTlRBWF9SRUdFWCA9IC9gYGAoc3RhcnQtbXVsdGktY29sdW1ufG11bHRpLWNvbHVtbi1zdGFydCkuKj9gYGAvc2c7XG5mdW5jdGlvbiB1cGRhdGVDb2x1bW5Db2RlYmxvY2tTdGFydFN5bnRheChvcmlnaW5hbEZpbGVDb250ZW50OiBzdHJpbmcpOiB7IHVwZGF0ZWRGaWxlQ29udGVudDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1SZWdpb25zVXBkYXRlZDogbnVtYmVyIH0ge1xuICAgIGxldCBtYXRjaGVzID0gQXJyYXkuZnJvbShvcmlnaW5hbEZpbGVDb250ZW50Lm1hdGNoQWxsKE9MRF9DT0RFQkxPQ0tfQ09MX1NUQVJUX1NZTlRBWF9SRUdFWCkpXG5cbiAgICBsZXQgdXBkYXRlZEZpbGVDb250ZW50ID0gb3JpZ2luYWxGaWxlQ29udGVudDtcbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICBcbiAgICBmb3IobGV0IG1hdGNoIG9mIG1hdGNoZXMpIHtcblxuICAgICAgICBsZXQgc3RhcnRJbmRleCA9IG1hdGNoLmluZGV4ICsgb2Zmc2V0XG4gICAgICAgIGxldCBtYXRjaExlbmd0aCA9IG1hdGNoWzBdLmxlbmd0aFxuICAgICAgICBsZXQgZW5kSW5kZXggPSBzdGFydEluZGV4ICsgbWF0Y2hMZW5ndGg7XG5cbiAgICAgICAgbGV0IG9yaWdpbmFsU2V0dGluZ3NUZXh0ID0gbWF0Y2hbMF1cbiAgICAgICAgbGV0IHNldHRpbmdzVGV4dCA9IG9yaWdpbmFsU2V0dGluZ3NUZXh0XG4gICAgICAgIGxldCBjb2x1bW5TdGFydFN5bnRheCA9IG1hdGNoWzFdXG4gICAgICAgIGxldCBjb2x1bW5TdGFydExpbmUgPSBgLS0tICR7Y29sdW1uU3RhcnRTeW50YXh9YFxuXG4gICAgICAgIFxuICAgICAgICBsZXQgaWRSZXN1bHQgPSAvSUQ6KC4qKS9pLmV4ZWMob3JpZ2luYWxTZXR0aW5nc1RleHQpXG4gICAgICAgIGlmKGlkUmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgaWQgPSBpZFJlc3VsdFsxXS50cmltKClcbiAgICAgICAgICAgIGNvbHVtblN0YXJ0TGluZSA9IGAke2NvbHVtblN0YXJ0TGluZX06ICR7aWR9YFxuXG4gICAgICAgICAgICBsZXQgc3RhcnRJbmRleCA9IGlkUmVzdWx0LmluZGV4XG4gICAgICAgICAgICBsZXQgZW5kSW5kZXggPSBzdGFydEluZGV4ICsgaWRSZXN1bHRbMF0ubGVuZ3RoXG5cbiAgICAgICAgICAgIHNldHRpbmdzVGV4dCA9IG9yaWdpbmFsU2V0dGluZ3NUZXh0LnNsaWNlKDAsIHN0YXJ0SW5kZXgpXG4gICAgICAgICAgICBzZXR0aW5nc1RleHQgKz0gb3JpZ2luYWxTZXR0aW5nc1RleHQuc2xpY2UoZW5kSW5kZXggKyAxKVxuICAgICAgICB9XG4gICAgICAgIHNldHRpbmdzVGV4dCA9IHNldHRpbmdzVGV4dC5yZXBsYWNlKGNvbHVtblN0YXJ0U3ludGF4LCBcImNvbHVtbi1zZXR0aW5nc1wiKVxuICAgICAgICBcbiAgICAgICAgbGV0IHJlcGxhY2VtZW50VGV4dCA9IGAke2NvbHVtblN0YXJ0TGluZX1cXG4ke3NldHRpbmdzVGV4dH1gXG5cbiAgICAgICAgb2Zmc2V0ICs9IHJlcGxhY2VtZW50VGV4dC5sZW5ndGggLSBtYXRjaExlbmd0aFxuXG4gICAgICAgIHVwZGF0ZWRGaWxlQ29udGVudCA9IHVwZGF0ZWRGaWxlQ29udGVudC5zbGljZSgwLCBzdGFydEluZGV4KSArIHJlcGxhY2VtZW50VGV4dCArIHVwZGF0ZWRGaWxlQ29udGVudC5zbGljZShlbmRJbmRleClcbiAgICAgICAgY29uc29sZS5ncm91cENvbGxhcHNlZCgpXG4gICAgICAgIGNvbnNvbGUubG9nKFwiT3JpZ2luYWwgRmlsZTpcXG5cXG5cIiwgb3JpZ2luYWxGaWxlQ29udGVudClcbiAgICAgICAgY29uc29sZS5sb2coXCJVcGRhdGVkIEZpbGU6XFxuXFxuXCIsIHVwZGF0ZWRGaWxlQ29udGVudClcbiAgICAgICAgY29uc29sZS5ncm91cEVuZCgpXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgdXBkYXRlZEZpbGVDb250ZW50OiB1cGRhdGVkRmlsZUNvbnRlbnQsXG4gICAgICAgIG51bVJlZ2lvbnNVcGRhdGVkOiBtYXRjaGVzLmxlbmd0aFxuICAgIH1cbn0iLCJpbXBvcnQgeyBBcHAsIEJ1dHRvbkNvbXBvbmVudCwgTW9kYWwsIE5vdGljZSwgUGxhdGZvcm0sIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcgfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCBNdWx0aUNvbHVtbk1hcmtkb3duIGZyb20gXCJzcmMvbWFpblwiO1xuaW1wb3J0ICogYXMgbXVsdGlDb2x1bW5QYXJzZXIgZnJvbSAnLi4vdXRpbGl0aWVzL3RleHRQYXJzZXInO1xuaW1wb3J0IHsgZ2V0VUlEIH0gZnJvbSBcInNyYy91dGlsaXRpZXMvdXRpbHNcIjtcbmltcG9ydCB7IHVwZGF0ZUFsbFN5bnRheCB9IGZyb20gXCJzcmMvdXRpbGl0aWVzL3N5bnRheFVwZGF0ZVwiO1xuaW1wb3J0IHsgTUNNX1NldHRpbmdzTWFuYWdlciB9IGZyb20gXCJzcmMvcGx1Z2luU2V0dGluZ3NcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTXVsdGlDb2x1bW5TZXR0aW5nc1ZpZXcgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblxuICAgIGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwdWJsaWMgcGx1Z2luOiBNdWx0aUNvbHVtbk1hcmtkb3duKSB7XG4gICAgICAgIHN1cGVyKGFwcCwgcGx1Z2luKTtcbiAgICB9XG4gICAgXG4gICAgZGlzcGxheSgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXJFbC5lbXB0eSgpO1xuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiBcIk11bHRpLUNvbHVtbiBNYXJrZG93biAtIFNldHRpbmdzXCIgfSk7XG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3NDb250YWluZXJFbCA9IHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRGl2KCk7XG5cbiAgICAgICAgbmV3IFNldHRpbmcoc2V0dGluZ3NDb250YWluZXJFbClcbiAgICAgICAgICAgIC5zZXROYW1lKFwiTnVtYmVyIG9mIGF1dG8tbGF5b3V0IGJhbGFuY2UgaXRlcmF0aW9uc1wiKVxuICAgICAgICAgICAgLnNldERlc2MoXCJUaGUgbWF4aW11bSBudW1iZXIgb2YgdGltZXMgYXV0by1sYXlvdXQgd2lsbCB0cnkgdG8gYmFsYW5jZSBlbGVtZW50cyBiZXR3ZWVuIGFsbCBvZiB0aGUgY29sdW1ucy4gU2V0dGluZyB0aGlzIHRvbyBoaWdoIG1heSBjYXVzZSBPYnNpZGlhbiB0byBzbG93IGRvd24gZHVyaW5nIGxvYWRpbmcgYW5kIHJlZnJlc2hpbmcgb2YgQXV0by1MYXlvdXQgY29sdW1ucy5cIilcbiAgICAgICAgICAgIC5hZGRTbGlkZXIoKHNsaWRlcikgPT4ge1xuICAgICAgICAgICAgICAgIHNsaWRlci5zZXRMaW1pdHMoMSwgMTUsIDIpXG4gICAgICAgICAgICAgICAgc2xpZGVyLnNldFZhbHVlKE1DTV9TZXR0aW5nc01hbmFnZXIuc2hhcmVkLmF1dG9MYXlvdXRCYWxhbmNlSXRlcmF0aW9ucylcbiAgICAgICAgICAgICAgICBzbGlkZXIuc2V0RHluYW1pY1Rvb2x0aXAoKVxuICAgICAgICAgICAgICAgIHNsaWRlci5vbkNoYW5nZSgodmFsKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIE1DTV9TZXR0aW5nc01hbmFnZXIuc2hhcmVkLmF1dG9MYXlvdXRCYWxhbmNlSXRlcmF0aW9ucyA9IHZhbDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKClcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcblxuICAgICAgICBuZXcgU2V0dGluZyhzZXR0aW5nc0NvbnRhaW5lckVsKVxuICAgICAgICAuc2V0TmFtZShcIkFsaWduIHRhYmxlcyB3aXRoIHRleHQgYWxpZ25tZW50IGJ5IGRlZmF1bHRcIilcbiAgICAgICAgLnNldERlc2ModGhpcy5idWlsZFRhYmxlQWxpZ25Eb2NGcmFnKCkpXG4gICAgICAgIC5hZGRUb2dnbGUoKHQpID0+XG4gICAgICAgICAgICB0LnNldFZhbHVlKE1DTV9TZXR0aW5nc01hbmFnZXIuc2hhcmVkLmFsaWduVGFibGVzVG9Db250ZW50QWxpZ25tZW50KVxuICAgICAgICAgICAgLm9uQ2hhbmdlKCh2KSA9PiB7XG4gICAgICAgICAgICAgICAgTUNNX1NldHRpbmdzTWFuYWdlci5zaGFyZWQuYWxpZ25UYWJsZXNUb0NvbnRlbnRBbGlnbm1lbnQgPSB2XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIClcblxuICAgICAgICBuZXcgU2V0dGluZyhzZXR0aW5nc0NvbnRhaW5lckVsKVxuICAgICAgICAuc2V0TmFtZShcIlVzZSBMaXZlIFByZXZpZXcgcmVuZGVyIGNhY2hlXCIpXG4gICAgICAgIC5zZXREZXNjKHRoaXMuYnVpbGRSZW5kZXJDYWNoZURvY0ZyYWcoKSlcbiAgICAgICAgLmFkZFRvZ2dsZSgodCkgPT5cbiAgICAgICAgICAgIHQuc2V0VmFsdWUoTUNNX1NldHRpbmdzTWFuYWdlci5zaGFyZWQudXNlTGl2ZVByZXZpZXdDYWNoZSlcbiAgICAgICAgICAgIC5vbkNoYW5nZSgodikgPT4ge1xuICAgICAgICAgICAgICAgIE1DTV9TZXR0aW5nc01hbmFnZXIuc2hhcmVkLnVzZUxpdmVQcmV2aWV3Q2FjaGUgPSB2XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIClcblxuICAgICAgICBpZihQbGF0Zm9ybS5pc01vYmlsZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgbmV3IFNldHRpbmcoc2V0dGluZ3NDb250YWluZXJFbClcbiAgICAgICAgICAgICAgICAuc2V0TmFtZShcIlJlbmRlciBjb2x1bW4gcmVnaW9ucyBvbiBtb2JpbGUgZGV2aWNlc1wiKVxuICAgICAgICAgICAgICAgIC5hZGRUb2dnbGUoKHQpID0+XG4gICAgICAgICAgICAgICAgICAgIHQuc2V0VmFsdWUoTUNNX1NldHRpbmdzTWFuYWdlci5zaGFyZWQucmVuZGVyT25Nb2JpbGUpLm9uQ2hhbmdlKCh2KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBNQ01fU2V0dGluZ3NNYW5hZ2VyLnNoYXJlZC5yZW5kZXJPbk1vYmlsZSA9IHZcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRWwoXCJoNVwiLCB7IGF0dHI6IHtcInN0eWxlXCI6IFwiY29sb3I6IHZhcigtLXRleHQtZXJyb3IpOyBtYXJnaW4tYm90dG9tOiAwcHg7XCJ9LCB0ZXh0OiBcIkRBTkdFUiBaT05FXCIgfSk7XG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRWwoXCJoclwiLCB7IGF0dHI6IHtcInN0eWxlXCI6IFwibWFyZ2luLXRvcDogMXB4OyBtYXJnaW4tYm90dG9tOiAwLjc1ZW07XCJ9IH0pXG4gICAgICAgIGNvbnN0IGRhbmdlclpvbmVDb250YWluZXJFbCA9IHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRGl2KCk7XG5cbiAgICAgICAgdGhpcy5idWlsZFVwZGF0ZURlcHJpY2F0ZWQoZGFuZ2VyWm9uZUNvbnRhaW5lckVsKTtcbiAgICAgICAgdGhpcy5idWlsZEZpeE1pc3NpbmdJRHMoZGFuZ2VyWm9uZUNvbnRhaW5lckVsKTtcblxuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiYnJcIilcblxuICAgICAgICBsZXQgeyBiZ0NvbG9yLCBmb250Q29sb3IsIGNvZmZlZUNvbG9yIH0gPSBnZXREb25hdGVCdXR0b25Db2xvcnModGhpcy5jb250YWluZXJFbCk7XG4gICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXG4gICAgICAgIC5zZXROYW1lKFwiRG9uYXRlXCIpXG4gICAgICAgIC5zZXREZXNjKGBJZiB5b3UgbGlrZSB0aGlzIFBsdWdpbiwgcGxlYXNlIGNvbnNpZGVyIHByb3ZpZGluZyBhIG9uZSB0aW1lIGRvbmF0aW9uIHRvIHN1cHBvcnQgaXQncyBkZXZlbG9wbWVudC5gKVxuICAgICAgICAuYWRkQnV0dG9uKChiKSA9PiB7XG4gICAgICAgICAgICBiLmJ1dHRvbkVsLnNldEF0dHIoXCJzdHlsZVwiLCBcImJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50OyBoZWlnaHQ6IDMwcHQ7IHBhZGRpbmc6IDBweDtcIilcbiAgICAgICAgICAgIGNvbnN0IGRpdiA9IGIuYnV0dG9uRWwuY3JlYXRlRGl2KHthdHRyOiB7XCJzdHlsZVwiOiBcIndpZHRoOiAxMDAlOyBoZWlnaHQ6IDEwMCVcIn19KTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVFbChcImFcIiwge1xuICAgICAgICAgICAgICAgIGhyZWY6IFwiaHR0cHM6Ly93d3cuYnV5bWVhY29mZmVlLmNvbS9ja3JvYmluc29uXCJcbiAgICAgICAgICAgIH0pLmNyZWF0ZUVsKFwiaW1nXCIsIHtcbiAgICAgICAgICAgICAgICBhdHRyOiB7XG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiBcIndpZHRoOiAxMDAlOyBoZWlnaHQ6IDEwMCVcIixcbiAgICAgICAgICAgICAgICAgICAgc3JjOiBgaHR0cHM6Ly9pbWcuYnV5bWVhY29mZmVlLmNvbS9idXR0b24tYXBpLz90ZXh0PUJ1eSBtZSBhIGNvZmZlZSZlbW9qaT0mc2x1Zz1ja3JvYmluc29uJmJ1dHRvbl9jb2xvdXI9JHtiZ0NvbG9yfSZmb250X2NvbG91cj0ke2ZvbnRDb2xvcn0mZm9udF9mYW1pbHk9Q29va2llJm91dGxpbmVfY29sb3VyPTAwMDAwMCZjb2ZmZWVfY29sb3VyPSR7Y29mZmVlQ29sb3J9YFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBidWlsZFJlbmRlckNhY2hlRG9jRnJhZygpOiBEb2N1bWVudEZyYWdtZW50IHtcbiAgICAgICAgbGV0IGRvY0ZyYWcgPSBuZXcgRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgICAgICBkb2NGcmFnLmNyZWF0ZURpdih7fSwgZGl2ID0+IHtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVTcGFuKHt9LCBzcGFuID0+IHtcbiAgICAgICAgICAgICAgICBzcGFuLmlubmVyVGV4dCA9IFwiQ2FjaGVzIHJlbmRlcmVkIGNvbnRlbnQgaW4gTGl2ZSBQcmV2aWV3IHRvIHJlZHVjZSByZW5kZXIgY3ljbGVzIGFuZCBlbGVtZW50IGZsYXNoaW5nIG9uIG5vdGUgaW50ZXJhY3Rpb24uXCI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVFbChcImJyXCIpO1xuICAgICAgICAgICAgZGl2LmNyZWF0ZUVsKFwiYnJcIik7XG4gICAgICAgICAgICBkaXYuY3JlYXRlU3Bhbih7fSwgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgc3Bhbi5pbm5lclRleHQgPSBcIk9ubHkgdXNlcyBjYWNoZSB3aGVuIGEgZmlsZSBMaXZlIFByZXZpZXcgdGFiIGlzIG9wZW4uIElmIGJvdGggcmVhZGluZyB2aWV3IGFuZCBMaXZlIFByZXZpZXcgYXJlIG9wZW5lZCB0aGlzIGZlYXR1cmUgaXMgZGlzYWJsZWQuXCI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVFbChcImJyXCIpO1xuICAgICAgICAgICAgZGl2LmNyZWF0ZUVsKFwiYnJcIik7XG4gICAgICAgICAgICBkaXYuY3JlYXRlRWwoXCJoNVwiLCB7fSwgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgc3Bhbi5zZXRBdHRyKFwic3R5bGVcIiwgXCJjb2xvcjogdmFyKC0tdGV4dC1lcnJvcik7IG1hcmdpbi1ib3R0b206IDBweDsgbWFyZ2luLXRvcDogM3B4O1wiKTtcbiAgICAgICAgICAgICAgICBzcGFuLmlubmVyVGV4dCA9IFwiRVhQRVJJTUVOVEFMOlwiO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkaXYuY3JlYXRlU3Bhbih7fSwgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgc3Bhbi5zZXRBdHRyKFwic3R5bGVcIiwgXCJjb2xvcjogdmFyKC0tdGV4dC1lcnJvcik7XCIpO1xuICAgICAgICAgICAgICAgIHNwYW4uaW5uZXJUZXh0ID0gXCJUaGlzIGZlYXR1cmUgaXMgZXhwZXJpbWVudGFsIG9ubHkgYW5kIGhhcyBpbnRlcm1pdHRlbnRseSBjYXVzZWQgbm90ZXMgdG8gZXJhc2UgY29sdW1uIGNvbnRlbnQgZHVyaW5nIGRldmVsb3BtZW50LiBBIGZpeCBoYXMgYmVlbiBpbXBsZW1lbnRlZCBcXFxuICAgICAgICAgICAgICAgIGJ1dCBkdWUgdG8gdGhlIHBvdGVudGlhbCBkYXRhIGxvc3MgeW91IG11c3Qgb3B0LWluIHRvIHVzaW5nIHRoaXMgZmVhdHVyZS4gSWYgY29udGVudCBpcyBlcmFzZWQgeW91IGNhbiB1c2UgVW5kbyB0byByZXN0b3JlIHRoZSBmaWxlIGRhdGEuIFxcXG4gICAgICAgICAgICAgICAgUGxlYXNlIG1ha2UgYmFja3VwcyBhbmQgZGlzYWJsZSBpZiB5b3UgZXhwZXJpZW5jZSBhbnkgZGF0YSBsb3NzLlwiO1xuICAgICAgICAgICAgfSk7XG5cblxuICAgICAgICB9KVxuICAgICAgICByZXR1cm4gZG9jRnJhZztcbiAgICB9XG5cbiAgICBwcml2YXRlIGJ1aWxkVGFibGVBbGlnbkRvY0ZyYWcoKTogRG9jdW1lbnRGcmFnbWVudCB7XG4gICAgICAgIGxldCBkb2NGcmFnID0gbmV3IERvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZG9jRnJhZy5jcmVhdGVEaXYoe30sIGRpdiA9PiB7XG4gICAgICAgICAgICBkaXYuY3JlYXRlU3Bhbih7fSwgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgc3Bhbi5pbm5lclRleHQgPSBcIlNldHMgdGhlIGRlZmFsdXQgYmVoYXZpb3Igd2hlbiBkZXRlcm1pbmluZyB3aGV0aGVyIHRvIGFsaWduIHRhYmxlIHRvIHRleHQgYWxpZ25tZW50LlwiO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkaXYuY3JlYXRlRWwoXCJiclwiKTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVFbChcInVsXCIpLmNyZWF0ZUVsKFwibGlcIiwgeyB0ZXh0OiBcIlRoaXMgdmFsdWUgaXMgb3ZlcndyaXR0ZW4gd2hlbiBkZWZpbmluZyB0aGUgY29sdW1uIHNldHRpbmc6ICdBbGlnbiBUYWJsZXMgdG8gVGV4dCBBbGlnbm1lbnQ6IHRydWUvZmFsc2UnXCIgfSlcbiAgICAgICAgfSlcbiAgICAgICAgcmV0dXJuIGRvY0ZyYWc7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBidWlsZFVwZGF0ZURlcHJpY2F0ZWQoZGFuZ2VyWm9uZUNvbnRhaW5lckVsOiBIVE1MRGl2RWxlbWVudCkge1xuXG4gICAgICAgIGxldCBkb2NGcmFnID0gbmV3IERvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZG9jRnJhZy5jcmVhdGVEaXYoe30sIGRpdiA9PiB7XG4gICAgICAgICAgICBkaXYuY3JlYXRlU3Bhbih7fSwgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgc3Bhbi5pbm5lclRleHQgPSBcIlRoaXMgbWF5IHRha2UgYSB3aGlsZSBmb3IgbGFyZ2UgdmF1bHRzLCB5b3UgY2FuIGNvbnRpbnVlIHRvIHVzZSBPYnNpZGlhbiBidXQgYXBwbGljYXRpb24gbWF5IHNsb3cgZG93biBkdXJpbmcgcHJvY2Vzcy5cIjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGl2LmNyZWF0ZUVsKFwiYnJcIik7XG4gICAgICAgICAgICBkaXYuY3JlYXRlRWwoXCJiclwiKTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVFbChcImg1XCIsIHt9LCBzcGFuID0+IHtcbiAgICAgICAgICAgICAgICBzcGFuLnNldEF0dHIoXCJzdHlsZVwiLCBcImNvbG9yOiB2YXIoLS10ZXh0LWVycm9yKTsgbWFyZ2luLWJvdHRvbTogMHB4OyBtYXJnaW4tdG9wOiAzcHg7XCIpO1xuICAgICAgICAgICAgICAgIHNwYW4uaW5uZXJUZXh0ID0gXCJXQVJOSU5HOlwiO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkaXYuY3JlYXRlU3Bhbih7fSwgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgc3Bhbi5zZXRBdHRyKFwic3R5bGVcIiwgXCJjb2xvcjogdmFyKC0tdGV4dC1lcnJvcik7XCIpO1xuICAgICAgICAgICAgICAgIHNwYW4uaW5uZXJUZXh0ID0gXCJUaGlzIGFjdGlvbiBtb2RpZmllcyBhbnkgbm90ZSBmaWxlIHdpdGggZGVwcmljYXRlZCBzeW50YXggYW5kIGNvdWxkIGxlYWQgdG8gY29ycnVwdGVkIGZpbGUgdGV4dC5cIjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGl2LmNyZWF0ZUVsKFwiYnJcIik7XG4gICAgICAgICAgICBkaXYuY3JlYXRlU3Bhbih7fSwgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgc3Bhbi5zZXRBdHRyKFwic3R5bGVcIiwgXCJjb2xvcjogdmFyKC0tdGV4dC1lcnJvcik7XCIpO1xuICAgICAgICAgICAgICAgIHNwYW4uaW5uZXJUZXh0ID0gXCJObyBndWFyZW50ZWUgaXMgZ2l2ZW4uIFBsZWFzZSBtYWtlIHN1cmUgdG8gYmFjayB5b3VyIHZhdWx0IHVwIGZpcnN0LlwiO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgbW9kYWxEZXNjcmlwdGlvbkVsID0gY3JlYXRlRGl2KHt9LCBkaXYgPT4ge1xuICAgICAgICAgICAgZGl2LmNyZWF0ZVNwYW4oeyB0ZXh0OiBcIlRoaXMgYWN0aW9uIG1heSBjb3JydXB0IHZhdWx0IGRhdGEuXCIgfSk7XG4gICAgICAgICAgICBkaXYuY3JlYXRlRWwoXCJiclwiKTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVTcGFuKHsgdGV4dDogXCJQbGVhc2UgY29uZmlybSB5b3UgaGF2ZSBiYWNrZWQgdXAgeW91ciB2YXVsdC5cIiB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIG5ldyBTZXR0aW5nKGRhbmdlclpvbmVDb250YWluZXJFbClcbiAgICAgICAgICAgIC5zZXROYW1lKFwiVXBkYXRlIEFMTCBkZXByaWNhdGVkIE11bHRpLUNvbHVtbiBzeW50YXguXCIpXG4gICAgICAgICAgICAuc2V0RGVzYyhkb2NGcmFnKVxuICAgICAgICAgICAgLmFkZEJ1dHRvbigoYikgPT4gYi5zZXRCdXR0b25UZXh0KFwiVXBkYXRlIFN5bnRheFwiKS5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBtb2RhbCA9IENvbmZpcm1Nb2RhbC5jb25maXJtTW9kYWxXaXRoRWxlbWVudCh0aGlzLmFwcCwgbW9kYWxEZXNjcmlwdGlvbkVsLCB7IHByaW1hcnk6IFwiQ29uZmlybVwiLCBzZWNvbmRhcnk6IFwiQ2FuY2VsXCIgfSk7XG4gICAgICAgICAgICAgICAgbW9kYWwub25DbG9zZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1vZGFsLmNvbmZpcm1lZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUZpbGVTeW50YXgoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG1vZGFsLm9wZW4oKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgYnVpbGRGaXhNaXNzaW5nSURzKGRhbmdlclpvbmVDb250YWluZXJFbDogSFRNTERpdkVsZW1lbnQpIHtcbiAgICAgICAgXG4gICAgICAgIGxldCBkb2NGcmFnID0gbmV3IERvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgZG9jRnJhZy5jcmVhdGVEaXYoe30sIGRpdiA9PiB7XG4gICAgICAgICAgICBkaXYuY3JlYXRlU3Bhbih7fSwgc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgc3Bhbi5pbm5lclRleHQgPSBcIlRoaXMgd2lsbCBvbmx5IG1vZGlmeSBjb2x1bW4gcmVnaW9ucyB3aXRob3V0IGEgcHJlLWRlZmluZWQgSUQsIGFuZCB3aGljaCB1c2UgdGhlIHVwIHRvIGRhdGUgY29yZSBzeW50YXguIFdpbGwgbm90IG1vZGlmeSBkZXByaWNhdGVkIHN5bnRheCBvciBmZW5jZWQtZGl2cy5cIjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGl2LmNyZWF0ZUVsKFwiYnJcIik7XG4gICAgICAgICAgICBkaXYuY3JlYXRlRWwoXCJiclwiKTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVTcGFuKHt9LCBzcGFuID0+IHtcbiAgICAgICAgICAgICAgICBzcGFuLmlubmVyVGV4dCA9IFwiVGhpcyBtYXkgdGFrZSBhIHdoaWxlIGZvciBsYXJnZSB2YXVsdHMsIHlvdSBjYW4gY29udGludWUgdG8gdXNlIE9ic2lkaWFuIGJ1dCBhcHBsaWNhdGlvbiBtYXkgc2xvdyBkb3duIGR1cmluZyBwcm9jZXNzLlwiO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkaXYuY3JlYXRlRWwoXCJiclwiKTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVFbChcImJyXCIpO1xuICAgICAgICAgICAgZGl2LmNyZWF0ZUVsKFwiaDVcIiwge30sIHNwYW4gPT4ge1xuICAgICAgICAgICAgICAgIHNwYW4uc2V0QXR0cihcInN0eWxlXCIsIFwiY29sb3I6IHZhcigtLXRleHQtZXJyb3IpOyBtYXJnaW4tYm90dG9tOiAwcHg7IG1hcmdpbi10b3A6IDNweDtcIik7XG4gICAgICAgICAgICAgICAgc3Bhbi5pbm5lclRleHQgPSBcIldBUk5JTkc6XCI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVTcGFuKHt9LCBzcGFuID0+IHtcbiAgICAgICAgICAgICAgICBzcGFuLnNldEF0dHIoXCJzdHlsZVwiLCBcImNvbG9yOiB2YXIoLS10ZXh0LWVycm9yKTtcIik7XG4gICAgICAgICAgICAgICAgc3Bhbi5pbm5lclRleHQgPSBcIlRoaXMgYWN0aW9uIG1vZGlmaWVzIGFueSBub3RlIGZpbGUgbWlzc2luZyBjb2x1bW4gSURzIGFuZCBjb3VsZCBsZWFkIHRvIGNvcnJ1cHRlZCBmaWxlIHRleHQuXCI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVFbChcImJyXCIpO1xuICAgICAgICAgICAgZGl2LmNyZWF0ZVNwYW4oe30sIHNwYW4gPT4ge1xuICAgICAgICAgICAgICAgIHNwYW4uc2V0QXR0cihcInN0eWxlXCIsIFwiY29sb3I6IHZhcigtLXRleHQtZXJyb3IpO1wiKTtcbiAgICAgICAgICAgICAgICBzcGFuLmlubmVyVGV4dCA9IFwiTm8gZ3VhcmVudGVlIGlzIGdpdmVuLiBQbGVhc2UgbWFrZSBzdXJlIHRvIGJhY2sgeW91ciB2YXVsdCB1cCBmaXJzdC5cIjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgbGV0IG1vZGFsRGVzY3JpcHRpb25FbCA9IGNyZWF0ZURpdih7fSwgZGl2ID0+IHtcbiAgICAgICAgICAgIGRpdi5jcmVhdGVTcGFuKHsgdGV4dDogXCJUaGlzIGFjdGlvbiBtYXkgY29ycnVwdCB2YXVsdCBkYXRhLlwiIH0pO1xuICAgICAgICAgICAgZGl2LmNyZWF0ZUVsKFwiYnJcIik7XG4gICAgICAgICAgICBkaXYuY3JlYXRlU3Bhbih7IHRleHQ6IFwiUGxlYXNlIGNvbmZpcm0geW91IGhhdmUgYmFja2VkIHVwIHlvdXIgdmF1bHQuXCIgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBuZXcgU2V0dGluZyhkYW5nZXJab25lQ29udGFpbmVyRWwpXG4gICAgICAgICAgICAuc2V0TmFtZShcIkFwcGVuZCBJRHMgdG8gYWxsIE11bHRpLUNvbHVtbiByZWdpb25zIGluIHZhdWx0LlwiKVxuICAgICAgICAgICAgLnNldERlc2MoZG9jRnJhZylcbiAgICAgICAgICAgIC5hZGRCdXR0b24oKGIpID0+IGIuc2V0QnV0dG9uVGV4dChcIkFkZCBJRHNcIikub25DbGljaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbW9kYWwgPSBDb25maXJtTW9kYWwuY29uZmlybU1vZGFsV2l0aEVsZW1lbnQodGhpcy5hcHAsIG1vZGFsRGVzY3JpcHRpb25FbCwgeyBwcmltYXJ5OiBcIkNvbmZpcm1cIiwgc2Vjb25kYXJ5OiBcIkNhbmNlbFwiIH0pO1xuICAgICAgICAgICAgICAgIG1vZGFsLm9uQ2xvc2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtb2RhbC5jb25maXJtZWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBmaW5kQW5kUmVwbGFjZU1pc3NpbmdJRHMoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG1vZGFsLm9wZW4oKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29uZmlybU1vZGFsIGV4dGVuZHMgTW9kYWwge1xuXG4gICAgc3RhdGljIGNvbmZpcm1Nb2RhbFdpdGhUZXh0KGFwcDogQXBwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbnM6IHsgcHJpbWFyeTogc3RyaW5nOyBzZWNvbmRhcnk6IHN0cmluZyB9KTogQ29uZmlybU1vZGFsIHtcblxuICAgICAgICByZXR1cm4gbmV3IENvbmZpcm1Nb2RhbChhcHAsIGNyZWF0ZVNwYW4oe3RleHQ6IHRleHR9KSwgYnV0dG9ucylcbiAgICB9XG5cbiAgICBzdGF0aWMgY29uZmlybU1vZGFsV2l0aEVsZW1lbnQoYXBwOiBBcHAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uRWw6IEhUTUxFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25zOiB7IHByaW1hcnk6IHN0cmluZzsgc2Vjb25kYXJ5OiBzdHJpbmcgfSk6IENvbmZpcm1Nb2RhbCB7XG4gICAgICAgIHJldHVybiBuZXcgQ29uZmlybU1vZGFsKGFwcCwgZGVzY3JpcHRpb25FbCwgYnV0dG9ucylcbiAgICB9XG5cbiAgICBwdWJsaWMgZGVzY3JpcHRpb25FbDogSFRNTEVsZW1lbnRcbiAgICBwdWJsaWMgYnV0dG9uczogeyBwcmltYXJ5OiBzdHJpbmc7IHNlY29uZGFyeTogc3RyaW5nIH1cbiAgICBwcml2YXRlIGNvbnN0cnVjdG9yKGFwcDogQXBwLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uRWw6IEhUTUxFbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uczogeyBwcmltYXJ5OiBzdHJpbmc7IHNlY29uZGFyeTogc3RyaW5nIH0pIHtcbiAgICAgICAgc3VwZXIoYXBwKTtcbiAgICAgICAgdGhpcy5kZXNjcmlwdGlvbkVsID0gZGVzY3JpcHRpb25FbDtcbiAgICAgICAgdGhpcy5idXR0b25zID0gYnV0dG9ucztcbiAgICB9XG4gICAgY29uZmlybWVkOiBib29sZWFuID0gZmFsc2U7XG4gICAgYXN5bmMgZGlzcGxheSgpIHtcbiAgICAgICAgdGhpcy5jb250ZW50RWwuZW1wdHkoKTtcbiAgICAgICAgdGhpcy5jb250ZW50RWwuYXBwZW5kQ2hpbGQodGhpcy5kZXNjcmlwdGlvbkVsKVxuXG4gICAgICAgIGNvbnN0IGJ1dHRvbkVsID0gdGhpcy5jb250ZW50RWwuY3JlYXRlRGl2KCk7XG4gICAgICAgIG5ldyBCdXR0b25Db21wb25lbnQoYnV0dG9uRWwpXG4gICAgICAgICAgICAuc2V0QnV0dG9uVGV4dCh0aGlzLmJ1dHRvbnMucHJpbWFyeSlcbiAgICAgICAgICAgIC5zZXRDdGEoKVxuICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlybWVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgbmV3IEJ1dHRvbkNvbXBvbmVudChidXR0b25FbClcbiAgICAgICAgICAgIC5zZXRCdXR0b25UZXh0KHRoaXMuYnV0dG9ucy5zZWNvbmRhcnkpXG4gICAgICAgICAgICAub25DbGljaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuICAgIG9uT3BlbigpIHtcbiAgICAgICAgdGhpcy5kaXNwbGF5KCk7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBmaW5kQW5kUmVwbGFjZU1pc3NpbmdJRHMoKSB7XG5cbiAgICBmdW5jdGlvbiBzZWFyY2hGaWxlRm9yTWlzc2luZ0lEKGRvY1RleHQ6IHN0cmluZyk6IHsgdXBkYXRlZEZpbGVDb250ZW50OiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bVJlZ2lvbnNVcGRhdGVkOiBudW1iZXIgfSB7XG4gICAgICAgIGxldCBsaW5lcyA9IGRvY1RleHQuc3BsaXQoXCJcXG5cIik7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIExvb3AgdGhyb3VnaCBhbGwgb2YgdGhlIGxpbmVzIGNoZWNraW5nIGlmIHRoZSBsaW5lIGlzIGEgXG4gICAgICAgICAqIHN0YXJ0IHRhZyBhbmQgaWYgc28gaXMgaXQgbWlzc2luZyBhbiBJRC5cbiAgICAgICAgICovXG4gICAgICAgIGxldCBsaW5lc1dpdGhvdXRJRHMgPSAwXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgICAgICBsZXQgZGF0YSA9IG11bHRpQ29sdW1uUGFyc2VyLmlzU3RhcnRUYWdXaXRoSUQobGluZXNbaV0pO1xuICAgICAgICAgICAgaWYoZGF0YS5pc1N0YXJ0VGFnID09PSB0cnVlICYmIGRhdGEuaGFzS2V5ID09PSBmYWxzZSkge1xuXG4gICAgICAgICAgICAgICAgbGV0IG9yaWdpbmFsVGV4dCA9IGxpbmVzW2ldXG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSBvcmlnaW5hbFRleHQ7XG4gICAgICAgICAgICAgICAgdGV4dCA9IHRleHQudHJpbUVuZCgpO1xuICAgICAgICAgICAgICAgIGlmKHRleHQuY2hhckF0KHRleHQubGVuZ3RoIC0gMSkgPT09IFwiOlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0LnNsaWNlKDAsIHRleHQubGVuZ3RoLTEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0ZXh0ID0gYCR7dGV4dH06IElEXyR7Z2V0VUlEKDQpfWA7XG5cbiAgICAgICAgICAgICAgICBsaW5lc1tpXSA9IHRleHQ7XG4gICAgICAgICAgICAgICAgbGluZXNXaXRob3V0SURzKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gICAgICAgICAgICAgICAgICAgIFxuXG4gICAgICAgIGlmKGxpbmVzV2l0aG91dElEcyA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVkRmlsZUNvbnRlbnQ6IGRvY1RleHQsXG4gICAgICAgICAgICAgICAgbnVtUmVnaW9uc1VwZGF0ZWQ6IDBcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbmV3RmlsZUNvbnRlbnQgPSBsaW5lcy5qb2luKFwiXFxuXCIpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdXBkYXRlZEZpbGVDb250ZW50OiBuZXdGaWxlQ29udGVudCxcbiAgICAgICAgICAgIG51bVJlZ2lvbnNVcGRhdGVkOiBsaW5lc1dpdGhvdXRJRHNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBsZXQgY291bnQgPSAwO1xuICAgIGxldCBmaWxlQ291bnQgPSAwO1xuICAgIGZvcihsZXQgbWRGaWxlIG9mIGFwcC52YXVsdC5nZXRNYXJrZG93bkZpbGVzKCkpIHtcbiAgICAgICAgbGV0IG9yaWdpbmFsRmlsZUNvbnRlbnQgPSBhd2FpdCBhcHAudmF1bHQucmVhZChtZEZpbGUpO1xuXG4gICAgICAgIGxldCByZXN1bHQgPSBzZWFyY2hGaWxlRm9yTWlzc2luZ0lEKG9yaWdpbmFsRmlsZUNvbnRlbnQpO1xuICAgICAgICBpZihyZXN1bHQubnVtUmVnaW9uc1VwZGF0ZWQgPiAwKSB7XG4gICAgICAgICAgICBjb3VudCArPSByZXN1bHQubnVtUmVnaW9uc1VwZGF0ZWQ7XG4gICAgICAgICAgICBmaWxlQ291bnQrKztcblxuICAgICAgICAgICAgbGV0IHVwZGF0ZWRGaWxlQ29udGVudCA9IHJlc3VsdC51cGRhdGVkRmlsZUNvbnRlbnQ7XG4gICAgICAgICAgICBpZih1cGRhdGVkRmlsZUNvbnRlbnQgIT09IG9yaWdpbmFsRmlsZUNvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICBhcHAudmF1bHQubW9kaWZ5KG1kRmlsZSwgdXBkYXRlZEZpbGVDb250ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiTm8gY2hhbmdlcywgbm90IHVwZGF0aW5nIGZpbGUuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIG5ldyBOb3RpY2UoYEZpbmlzaGVkIHVwZGF0aW5nOlxcbiR7Y291bnR9IHJlZ2lvbiBJRHMsIGFjcm9zcyAke2ZpbGVDb3VudH0gZmlsZXMuYClcbn1cblxuYXN5bmMgZnVuY3Rpb24gdXBkYXRlRmlsZVN5bnRheCgpIHtcbiAgICBcbiAgICBsZXQgZmlsZUNvdW50ID0gMFxuICAgIGxldCByZWdpb25TdGFydENvdW50ID0gMDtcbiAgICBsZXQgY29sdW1uQnJlYWtDb3VudCA9IDA7XG4gICAgbGV0IGNvbHVtbkVuZENvdW50ID0gMDtcbiAgICBmb3IobGV0IG1kRmlsZSBvZiBhcHAudmF1bHQuZ2V0TWFya2Rvd25GaWxlcygpKSB7XG4gICAgICAgIGxldCBvcmlnaW5hbEZpbGVDb250ZW50ID0gYXdhaXQgYXBwLnZhdWx0LnJlYWQobWRGaWxlKTtcbiAgICAgICAgbGV0IHJlc3VsdCA9IHVwZGF0ZUFsbFN5bnRheChvcmlnaW5hbEZpbGVDb250ZW50KTtcblxuICAgICAgICBmaWxlQ291bnQgKz0gcmVzdWx0LmZpbGVDb3VudDtcbiAgICAgICAgcmVnaW9uU3RhcnRDb3VudCArPSByZXN1bHQucmVnaW9uU3RhcnRDb3VudDtcbiAgICAgICAgY29sdW1uQnJlYWtDb3VudCArPSByZXN1bHQuY29sdW1uQnJlYWtDb3VudDtcbiAgICAgICAgY29sdW1uRW5kQ291bnQgKz0gcmVzdWx0LmNvbHVtbkVuZENvdW50O1xuICAgICAgICBsZXQgdXBkYXRlZEZpbGVDb250ZW50ID0gcmVzdWx0LnVwZGF0ZWRGaWxlQ29udGVudDtcblxuICAgICAgICAvLyBUT0RPOiBBZGQgaW4gZmluYWwgZmlsZSBtb2RpZmljYXRpb24gd2hlbiBkb25lIHRlc3RpbmcuXG4gICAgICAgIGlmKHJlc3VsdC5maWxlV2FzVXBkYXRlZCkge1xuICAgICAgICAgICAgYXBwLnZhdWx0Lm1vZGlmeShtZEZpbGUsIHVwZGF0ZWRGaWxlQ29udGVudClcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUuZGVidWcoXCJObyBjaGFuZ2VzLCBub3QgdXBkYXRpbmcgZmlsZS5cIilcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5ldyBOb3RpY2UoYEZpbmlzaGVkIHVwZGF0aW5nOlxcbiR7cmVnaW9uU3RhcnRDb3VudH0gc3RhcnQgc3ludGF4ZXMsXFxuJHtjb2x1bW5CcmVha0NvdW50fSBjb2x1bW4gYnJlYWtzLCBhbmRcXG4ke2NvbHVtbkVuZENvdW50fSBjb2x1bW4gZW5kIHRhZ3MsXFxuYWNyb3NzICR7ZmlsZUNvdW50fSBmaWxlcy5gKVxufVxuXG5mdW5jdGlvbiBnZXREb25hdGVCdXR0b25Db2xvcnMoY29udGFpbmVyRWw6IEhUTUxFbGVtZW50KSB7XG4gICAgbGV0IGNvbXB1dGVkU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGNvbnRhaW5lckVsKTtcbiAgICBsZXQgZm9udENvbG9yID0gY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCctLXRleHQtbm9ybWFsJyk7XG4gICAgbGV0IGJnQ29sb3IgPSBjb21wdXRlZFN0eWxlLmdldFByb3BlcnR5VmFsdWUoJy0tYWNjZW50Jyk7XG4gICAgbGV0IGNvZmZlZUNvbG9yID0gXCJmZmZmZmZcIjtcbiAgICBpZiAoaXNWYWxpZEhleENvbG9yKGZvbnRDb2xvcikgJiZcbiAgICAgICAgaXNWYWxpZEhleENvbG9yKGJnQ29sb3IpKSB7XG4gICAgICAgIGZvbnRDb2xvciA9IGZvbnRDb2xvci5zbGljZSgxKTtcbiAgICAgICAgYmdDb2xvciA9IGJnQ29sb3Iuc2xpY2UoMSk7XG4gICAgICAgIGNvZmZlZUNvbG9yID0gZm9udENvbG9yO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9udENvbG9yID0gXCIwMDAwMDBcIjtcbiAgICAgICAgYmdDb2xvciA9IFwiRkZERDAwXCI7XG4gICAgICAgIGNvZmZlZUNvbG9yID0gXCJmZmZmZmZcIjtcbiAgICB9XG4gICAgcmV0dXJuIHsgYmdDb2xvciwgZm9udENvbG9yLCBjb2ZmZWVDb2xvciB9O1xufVxuXG5mdW5jdGlvbiBpc1ZhbGlkSGV4Q29sb3IocG9zc2libGVDb2xvcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgXG4gICAgbGV0IGZpcnN0Q2hhciA9IHBvc3NpYmxlQ29sb3JbMF1cbiAgICBpZihmaXJzdENoYXIgIT09IFwiI1wiKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlmKHBvc3NpYmxlQ29sb3IubGVuZ3RoICE9PSA3KSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHJldHVybiAvXiNbMC05QS1GXXs2fSQvaS50ZXN0KHBvc3NpYmxlQ29sb3IpXG59IiwiLypcclxuICogRmlsZTogbXVsdGktY29sdW1uLW1hcmtkb3duL3NyYy9tYWluLnRzXHJcbiAqIENyZWF0ZWQgRGF0ZTogVHVlc2RheSwgT2N0b2JlciA1dGggMjAyMSwgMTowOSBwbVxyXG4gKiBBdXRob3I6IENhbWVyb24gUm9iaW5zb25cclxuICogXHJcbiAqIENvcHlyaWdodCAoYykgMjAyMiBDYW1lcm9uIFJvYmluc29uXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgTm90aWNlLCBQbHVnaW4sICBNYXJrZG93blJlbmRlckNoaWxkLCBNYXJrZG93blJlbmRlcmVyLCBURmlsZSwgUGxhdGZvcm0sIE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIE1hcmtkb3duU2VjdGlvbkluZm9ybWF0aW9uLCBwYXJzZUZyb250TWF0dGVyRW50cnksIFdvcmtzcGFjZSwgV29ya3NwYWNlTGVhZiwgRWRpdG9yUG9zaXRpb24gfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCAqIGFzIG11bHRpQ29sdW1uUGFyc2VyIGZyb20gJy4vdXRpbGl0aWVzL3RleHRQYXJzZXInO1xyXG5pbXBvcnQgKiBhcyBjb250YWluc1BhbmRvYyBmcm9tIFwiLi91dGlsaXRpZXMvcGFuZG9jUGFyc2VyXCI7XHJcbmltcG9ydCB7IEZpbGVET01NYW5hZ2VyLCBHbG9iYWxET01NYW5hZ2VyIH0gZnJvbSAnLi9kb21fbWFuYWdlci9kb21NYW5hZ2VyJztcclxuaW1wb3J0IHsgTXVsdGlDb2x1bW5SZW5kZXJEYXRhIH0gZnJvbSBcIi4vZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvcmVnaW9uTWFuYWdlclwiO1xyXG5pbXBvcnQgeyBSZWdpb25NYW5hZ2VyIH0gZnJvbSBcIi4vZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvcmVnaW9uTWFuYWdlclwiO1xyXG5pbXBvcnQgeyBSZWdpb25NYW5hZ2VyQ29udGFpbmVyIH0gZnJvbSBcIi4vZG9tX21hbmFnZXIvcmVnaW9uYWxfbWFuYWdlcnMvcmVnaW9uTWFuYWdlckNvbnRhaW5lclwiO1xyXG5pbXBvcnQgeyBET01PYmplY3QsIERPTU9iamVjdFRhZywgVGFza0xpc3RET01PYmplY3QgfSBmcm9tICcuL2RvbV9tYW5hZ2VyL2RvbU9iamVjdCc7XHJcbmltcG9ydCB7IGZpbGVTdGlsbEluVmlldywgZ2V0VUlEIH0gZnJvbSAnLi91dGlsaXRpZXMvdXRpbHMnO1xyXG5pbXBvcnQgeyBNdWx0aUNvbHVtbkxheW91dENTUywgTXVsdGlDb2x1bW5TdHlsZUNTUyB9IGZyb20gJy4vdXRpbGl0aWVzL2Nzc0RlZmluaXRpb25zJztcclxuaW1wb3J0IHsgbXVsdGlDb2x1bW5NYXJrZG93bl9TdGF0ZUZpZWxkIH0gZnJvbSAnLi9saXZlX3ByZXZpZXcvY202X2xpdmVQcmV2aWV3JztcclxuaW1wb3J0IHsgcGFyc2VDb2x1bW5TZXR0aW5ncywgcGFyc2VTdGFydFJlZ2lvbkNvZGVCbG9ja0lEIH0gZnJvbSAnLi91dGlsaXRpZXMvc2V0dGluZ3NQYXJzZXInO1xyXG5pbXBvcnQgeyBNdWx0aUNvbHVtbk1hcmtkb3duX09uQ2xpY2tGaXggfSBmcm9tICcuL2xpdmVfcHJldmlldy9jbTZfbGl2ZVByZWl2ZXdfb25DbGlja0ZpeCc7XHJcbmltcG9ydCB7IE11bHRpQ29sdW1uU2V0dGluZ3MsIGdldERlZmF1bHRNdWx0aUNvbHVtblNldHRpbmdzIH0gZnJvbSAnLi9yZWdpb25TZXR0aW5ncyc7XHJcbmltcG9ydCB7IEhUTUxTaXppbmcgfSBmcm9tICcuL3V0aWxpdGllcy9pbnRlcmZhY2VzJztcclxuaW1wb3J0IE11bHRpQ29sdW1uU2V0dGluZ3NWaWV3IGZyb20gJy4vc2V0dGluZ3MvTXVsdGlDb2x1bW5TZXR0aW5nc1ZpZXcnO1xyXG5pbXBvcnQgeyBERUZBVUxUX1NFVFRJTkdTLCBNQ01fU2V0dGluZ3NNYW5hZ2VyIH0gZnJvbSAnLi9wbHVnaW5TZXR0aW5ncyc7XHJcbmltcG9ydCB7IFJlZ2lvbkVycm9yTWFuYWdlciB9IGZyb20gJy4vZG9tX21hbmFnZXIvcmVnaW9uRXJyb3JNYW5hZ2VyJztcclxuaW1wb3J0IHsgcGFyc2VDb2xCcmVha0Vycm9yVHlwZSB9IGZyb20gJy4vdXRpbGl0aWVzL2Vycm9yTWVzc2FnZSc7XHJcbmltcG9ydCB7IHVwZGF0ZUFsbFN5bnRheCB9IGZyb20gJy4vdXRpbGl0aWVzL3N5bnRheFVwZGF0ZSc7XHJcbmltcG9ydCB7IGdldExlYWZGcm9tRmlsZVBhdGggfSBmcm9tICcuL3V0aWxpdGllcy9vYnNpVXRpbHMnO1xyXG5pbXBvcnQgeyBjbGVhckxpdmVQcmV2aWV3Q2FjaGUgfSBmcm9tICcuL2xpdmVfcHJldmlldy9tY21fbGl2ZVByZXZpZXdfd2lkZ2V0JztcclxuXHJcbmNvbnN0IENPREVCTE9DS19TVEFSVF9TVFJTID0gW1xyXG4gICAgXCJzdGFydC1tdWx0aS1jb2x1bW5cIixcclxuICAgIFwibXVsdGktY29sdW1uLXN0YXJ0XCJcclxuXVxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNdWx0aUNvbHVtbk1hcmtkb3duIGV4dGVuZHMgUGx1Z2luIHtcclxuXHJcbiAgICBzZXR0aW5nc01hbmFnZXI6IE1DTV9TZXR0aW5nc01hbmFnZXIgPSBNQ01fU2V0dGluZ3NNYW5hZ2VyLnNoYXJlZDtcclxuICAgIGdsb2JhbE1hbmFnZXI6IEdsb2JhbERPTU1hbmFnZXIgPSBuZXcgR2xvYmFsRE9NTWFuYWdlcigpO1xyXG5cclxuXHRhc3luYyBvbmxvYWQoKSB7XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKFwiTG9hZGluZyBtdWx0aS1jb2x1bW4gbWFya2Rvd25cIik7XHJcblxyXG4gICAgICAgIGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XHJcblxyXG4gICAgICAgIHRoaXMuZ2xvYmFsTWFuYWdlciA9IG5ldyBHbG9iYWxET01NYW5hZ2VyKCk7XHJcblxyXG4gICAgICAgIHRoaXMucmVnaXN0ZXJFZGl0b3JFeHRlbnNpb24obXVsdGlDb2x1bW5NYXJrZG93bl9TdGF0ZUZpZWxkKVxyXG4gICAgICAgIHRoaXMucmVnaXN0ZXJFZGl0b3JFeHRlbnNpb24oTXVsdGlDb2x1bW5NYXJrZG93bl9PbkNsaWNrRml4KTtcclxuXHJcbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IENPREVCTE9DS19TVEFSVF9TVFJTLmxlbmd0aDsgaSsrKSB7XHJcblxyXG4gICAgICAgICAgICBsZXQgc3RhcnRTdHIgPSBDT0RFQkxPQ0tfU1RBUlRfU1RSU1tpXVxyXG4gICAgICAgICAgICB0aGlzLnNldHVwTWFya2Rvd25Db2RlYmxvY2tQb3N0UHJvY2Vzc29yKHN0YXJ0U3RyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5zZXR1cE1hcmtkb3duUG9zdFByb2Nlc3NvcigpO1xyXG5cclxuICAgICAgICB0aGlzLmFkZFNldHRpbmdUYWIobmV3IE11bHRpQ29sdW1uU2V0dGluZ3NWaWV3KHRoaXMuYXBwLCB0aGlzKSlcclxuXHJcbiAgICAgICAgdGhpcy5hZGRDb21tYW5kKHsgICAgICAgICAgICBcclxuICAgICAgICAgICAgaWQ6IGB0b2dnbGUtbW9iaWxlLXJlbmRlcmluZy1tY21gLFxyXG4gICAgICAgICAgICBuYW1lOiBgVG9nZ2xlIE1vYmlsZSBSZW5kZXJpbmcgLSBNdWx0aS1Db2x1bW4gTWFya2Rvd25gLFxyXG4gICAgICAgICAgICBjYWxsYmFjazogYXN5bmMgKCkgPT4ge1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZ3NNYW5hZ2VyLnJlbmRlck9uTW9iaWxlID0gIXRoaXMuc2V0dGluZ3NNYW5hZ2VyLnJlbmRlck9uTW9iaWxlO1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgbm90aWNlU3RyaW5nID0gYFRvZ2dsZWQgbW9iaWxlIHJlbmRlcmluZyAke3RoaXMuc2V0dGluZ3NNYW5hZ2VyLnJlbmRlck9uTW9iaWxlID8gXCJvblwiIDogXCJvZmZcIn0uYFxyXG4gICAgICAgICAgICAgICAgaWYoUGxhdGZvcm0uaXNNb2JpbGUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBub3RpY2VTdHJpbmcgKz0gYCBQbGVhc2UgcmVsb2FkIGFueSBvcGVuIGZpbGVzIGZvciBjaGFuZ2UgdG8gdGFrZSBlZmZlY3QuYFxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbmV3IE5vdGljZSAobm90aWNlU3RyaW5nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvL1RPRE86IFNldCB1cCB0aGlzIGFzIGEgbW9kYWwgdG8gc2V0IHNldHRpbmdzIGF1dG9tYXRpY2FsbHlcclxuICAgICAgICB0aGlzLmFkZENvbW1hbmQoeyAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZDogYGluc2VydC1tdWx0aS1jb2x1bW4tcmVnaW9uYCxcclxuICAgICAgICAgICAgbmFtZTogYEluc2VydCBNdWx0aS1Db2x1bW4gUmVnaW9uYCxcclxuICAgICAgICAgICAgZWRpdG9yQ2FsbGJhY2s6IChlZGl0b3IsIHZpZXcpID0+IHtcclxuXHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBjdXJzb3JTdGFydFBvc2l0aW9uID0gZWRpdG9yLmdldEN1cnNvcihcImZyb21cIik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGVkaXRvci5nZXREb2MoKS5yZXBsYWNlU2VsZWN0aW9uKFxyXG5gXHJcbi0tLSBzdGFydC1tdWx0aS1jb2x1bW46IElEXyR7Z2V0VUlEKDQpfVxyXG5cXGBcXGBcXGBjb2x1bW4tc2V0dGluZ3NcclxuTnVtYmVyIG9mIENvbHVtbnM6IDJcclxuTGFyZ2VzdCBDb2x1bW46IHN0YW5kYXJkXHJcblxcYFxcYFxcYFxyXG5cclxuXHJcblxyXG4tLS0gY29sdW1uLWJyZWFrIC0tLVxyXG5cclxuXHJcblxyXG4tLS0gZW5kLW11bHRpLWNvbHVtblxyXG5cclxuJHtlZGl0b3IuZ2V0RG9jKCkuZ2V0U2VsZWN0aW9uKCl9YFxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgY3Vyc29yU3RhcnRQb3NpdGlvbi5saW5lID0gY3Vyc29yU3RhcnRQb3NpdGlvbi5saW5lICsgN1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnNvclN0YXJ0UG9zaXRpb24uY2ggPSAwO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBlZGl0b3Iuc2V0Q3Vyc29yKGN1cnNvclN0YXJ0UG9zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiRW5jb3VudGVyZWQgYW4gZXJyb3IgaW5zZXJ0aW5nIGEgbXVsdGktY29sdW1uIHJlZ2lvbi4gUGxlYXNlIHRyeSBhZ2FpbiBsYXRlci5cIlxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5hZGRDb21tYW5kKHsgICAgICAgICAgICBcclxuICAgICAgICAgICAgaWQ6IGBjbGVhci1scC1jYWNoZS1tY21gLFxyXG4gICAgICAgICAgICBuYW1lOiBgQ2xlYXIgTGl2ZSBQcmV2aWV3IENhY2hlIC0gTXVsdGktQ29sdW1uIE1hcmtkb3duYCxcclxuICAgICAgICAgICAgY2FsbGJhY2s6IGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNsZWFyTGl2ZVByZXZpZXdDYWNoZSgpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5hZGRDb21tYW5kKHsgICAgICAgICAgICBcclxuICAgICAgICAgICAgaWQ6IGBhZGQtSURzLVRvLW11bHRpLWNvbHVtbi1yZWdpb25gLFxyXG4gICAgICAgICAgICBuYW1lOiBgRml4IE1pc3NpbmcgSURzIGZvciBNdWx0aS1Db2x1bW4gUmVnaW9uc2AsXHJcbiAgICAgICAgICAgIGVkaXRvckNhbGxiYWNrOiAoZWRpdG9yLCB2aWV3KSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAgICAgKiBOb3Qgc3VyZSBpZiB0aGVyZSBpcyBhbiBlYXNpZXIgd2F5IHRvIGRvIHRoaXMuXHJcbiAgICAgICAgICAgICAgICAgICAgICogXHJcbiAgICAgICAgICAgICAgICAgICAgICogR2V0IGFsbCBvZiB0aGUgbGluZXMgb2YgdGhlIGRvY3VtZW50IHNwbGl0IGJ5IG5ld2xpbmVzLlxyXG4gICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBkb2NUZXh0ID0gZWRpdG9yLmdldFJhbmdlKHsgbGluZTogMCwgY2g6IDAgfSwgeyBsaW5lOiBlZGl0b3IuZ2V0RG9jKCkubGluZUNvdW50KCksIGNoOiAwfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGxpbmVzID0gZG9jVGV4dC5zcGxpdChcIlxcblwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHN0YXJ0Q29kZWJsb2NrID0gbXVsdGlDb2x1bW5QYXJzZXIuZmluZFN0YXJ0Q29kZWJsb2NrKGRvY1RleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBsaW5lT2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgbnVtQ29kZWJsb2Nrc1VwZGF0ZWQgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlKHN0YXJ0Q29kZWJsb2NrLmZvdW5kID09PSB0cnVlKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIHRleHQgb2YgdGhlIHNldHRpbmdzIGJsb2NrIHNvIHdlIGNhbiBjaGVjayBpZiBpdCBjb250YWlucyBhbiBJRCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWxzbyBzbyB3ZSBjYW4gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIGZpcnN0IGxpbmUsIHVzZWQgdG8gY2FsY3VsYXRlIHdoZXJlIHRvIGFwcGVuZCBhIG5ldyBJRCBpZiBuZWVkZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHNldHRpbmdzVGV4dCA9IGRvY1RleHQuc2xpY2Uoc3RhcnRDb2RlYmxvY2suc3RhcnRQb3NpdGlvbiwgc3RhcnRDb2RlYmxvY2suZW5kUG9zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmlyc3RMaW5lT2ZDb2RlYmxvY2tMZW5ndGggPSBzZXR0aW5nc1RleHQuc3BsaXQoXCJcXG5cIilbMF0ubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0aGUgbGluZXMgYmVmb3JlIHRoZSBibG9jayB0byBrbm93IHdoZXJlIHRvIHN0YXJ0IHJlcGxhY2luZyB0ZXh0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB0aGUgbGluZXMgaW5jbHVkaW5nIHRoZSBibG9jayB0byBrbm93IHdoZXJlIHRvIHNldCBvdXIgb2Zmc2V0IHRvIGFmdGVyIHRoaXMgaXRlcmF0aW9uLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbGluZXNCZWZvcmUgPSBkb2NUZXh0LnNsaWNlKDAsIHN0YXJ0Q29kZWJsb2NrLnN0YXJ0UG9zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgc3RhcnRSZXBsYWNlbWVudExpbmVJbmRleCA9IChsaW5lc0JlZm9yZS5zcGxpdChcIlxcblwiKS5sZW5ndGggLSAxKSArIGxpbmVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsaW5lc09mID0gZG9jVGV4dC5zbGljZSgwLCBzdGFydENvZGVibG9jay5lbmRQb3NpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlbmRSZXBsYWNlbWVudExpbmVJbmRleCA9ICAobGluZXNPZi5zcGxpdChcIlxcblwiKS5sZW5ndGggLSAxKSArIGxpbmVPZmZzZXQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgc2V0dGluZ3NJRCA9IHBhcnNlU3RhcnRSZWdpb25Db2RlQmxvY2tJRChzZXR0aW5nc1RleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihzZXR0aW5nc0lEID09PSBcIlwiKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29weSB0aGUgZmlyc3QgbGluZSBvZiB0aGUgY29kZWJsb2NrIGFuZCBhcHBlbmQgYSBuZXcgSUQsIHRoZW4gcmVwbGFjZSB0aGUgZmlyc3QgbGluZSBvZiB0aGUgYmxvY2tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZXBsYWNlbWVudFRleHQgPSBlZGl0b3IuZ2V0UmFuZ2UoeyBsaW5lOiBzdGFydFJlcGxhY2VtZW50TGluZUluZGV4LCBjaDogMCB9LCB7IGxpbmU6IHN0YXJ0UmVwbGFjZW1lbnRMaW5lSW5kZXgsIGNoOiBmaXJzdExpbmVPZkNvZGVibG9ja0xlbmd0aH0pICsgYFxcbklEOiBJRF8ke2dldFVJRCg0KX1gXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZGl0b3IucmVwbGFjZVJhbmdlKHJlcGxhY2VtZW50VGV4dCwgeyBsaW5lOiBzdGFydFJlcGxhY2VtZW50TGluZUluZGV4LCBjaDogMCB9LCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGxpbmU6IHN0YXJ0UmVwbGFjZW1lbnRMaW5lSW5kZXgsIGNoOiBmaXJzdExpbmVPZkNvZGVibG9ja0xlbmd0aH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kUmVwbGFjZW1lbnRMaW5lSW5kZXggKz0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bUNvZGVibG9ja3NVcGRhdGVkICs9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVPZmZzZXQgPSBlbmRSZXBsYWNlbWVudExpbmVJbmRleFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkb2NUZXh0ID0gZG9jVGV4dC5zbGljZShzdGFydENvZGVibG9jay5lbmRQb3NpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29kZWJsb2NrID0gbXVsdGlDb2x1bW5QYXJzZXIuZmluZFN0YXJ0Q29kZWJsb2NrKGRvY1RleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgICAgICogTG9vcCB0aHJvdWdoIGFsbCBvZiB0aGUgbGluZXMgY2hlY2tpbmcgaWYgdGhlIGxpbmUgaXMgYSBcclxuICAgICAgICAgICAgICAgICAgICAgKiBzdGFydCB0YWcgYW5kIGlmIHNvIGlzIGl0IG1pc3NpbmcgYW4gSUQuXHJcbiAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGxpbmVzV2l0aG91dElEcyA9IFtdXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRleHRXaXRob3V0SURzID0gW11cclxuICAgICAgICAgICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkYXRhID0gbXVsdGlDb2x1bW5QYXJzZXIuaXNTdGFydFRhZ1dpdGhJRChsaW5lc1tpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGRhdGEuaXNTdGFydFRhZyA9PT0gdHJ1ZSAmJiBkYXRhLmhhc0tleSA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVzV2l0aG91dElEcy5wdXNoKGkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dFdpdGhvdXRJRHMucHVzaChsaW5lc1tpXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgIFxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZihsaW5lc1dpdGhvdXRJRHMubGVuZ3RoID09PSAwICYmIG51bUNvZGVibG9ja3NVcGRhdGVkID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UgKFwiRm91bmQgMCBtaXNzaW5nIElEcyBpbiB0aGUgY3VycmVudCBkb2N1bWVudC5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAqIE5vdyBsb29wIHRocm91Z2ggZWFjaCBsaW5lIHRoYXQgaXMgbWlzc2luZyBhbiBJRCBhbmRcclxuICAgICAgICAgICAgICAgICAgICAgKiBnZW5lcmF0ZSBhIHJhbmRvbSBJRCBhbmQgcmVwbGFjZSB0aGUgb3JpZ2luYWwgdGV4dC5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgbGluZXNXaXRob3V0SURzLmxlbmd0aDsgaSsrKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgb3JpZ2luYWxUZXh0ID0gdGV4dFdpdGhvdXRJRHNbaV1cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRleHQgPSBvcmlnaW5hbFRleHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0LnRyaW1FbmQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYodGV4dC5jaGFyQXQodGV4dC5sZW5ndGggLSAxKSA9PT0gXCI6XCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0LnNsaWNlKDAsIHRleHQubGVuZ3RoLTEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBgJHt0ZXh0fTogSURfJHtnZXRVSUQoNCl9YDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRvci5yZXBsYWNlUmFuZ2UodGV4dCwgeyBsaW5lOiBsaW5lc1dpdGhvdXRJRHNbaV0sIGNoOiAwIH0sIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgbGluZTogbGluZXNXaXRob3V0SURzW2ldLCBjaDogb3JpZ2luYWxUZXh0Lmxlbmd0aH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IE5vdGljZSAoYFJlcGxhY2VkICR7bGluZXNXaXRob3V0SURzLmxlbmd0aCArIG51bUNvZGVibG9ja3NVcGRhdGVkfSBtaXNzaW5nIElEKHMpIGluIHRoZSBjdXJyZW50IGRvY3VtZW50LmApO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiRW5jb3VudGVyZWQgYW4gZXJyb3IgYWRkaWduIElEcyB0byBtdWx0aS1jb2x1bW4gcmVnaW9ucy4gUGxlYXNlIHRyeSBhZ2FpbiBsYXRlci5cIlxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmFkZENvbW1hbmQoeyAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZDogYG1jbS1Ub2dnbGUtRG9jdW1lbnQtUmVmbG93YCxcclxuICAgICAgICAgICAgbmFtZTogYFNldHVwIE11bHRpLUNvbHVtbiBSZWZsb3cgLSBNdWx0aS1Db2x1bW4gTWFya2Rvd25gLFxyXG4gICAgICAgICAgICBlZGl0b3JDYWxsYmFjazogKGVkaXRvciwgdmlldykgPT4ge1xyXG5cclxuICAgICAgICAgICAgICAgIGFwcC5maWxlTWFuYWdlci5wcm9jZXNzRnJvbnRNYXR0ZXIodmlldy5maWxlLCAoZnJvbnRtYXR0ZXIpID0+IHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGlzUmVmbG93ID0gaXNNdWx0aUNvbHVtblJlZmxvdyhmcm9udG1hdHRlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYoaXNSZWZsb3cpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZnJvbnRtYXR0ZXJbXCJNdWx0aS1Db2x1bW4gTWFya2Rvd25cIl0gPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcIk51bWJlciBvZiBDb2x1bW5zXCI6IDJ9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7XCJDb2x1bW4gU2l6ZVwiOiBcIlN0YW5kYXJkXCJ9XHJcbiAgICAgICAgICAgICAgICAgICAgXVxyXG4gICAgICAgICAgICAgICAgICAgIHZpZXcuZWRpdG9yLnJlZnJlc2goKVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmFkZENvbW1hbmQoeyAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZDogYG1jbS1maXgtZmlsZS1tdWx0aS1jb2x1bW4tc3ludGF4YCxcclxuICAgICAgICAgICAgbmFtZTogYEZpeCBNdWx0aS1Db2x1bW4gU3ludGF4IGluIEN1cnJlbnQgRmlsZS5gLFxyXG4gICAgICAgICAgICBlZGl0b3JDYWxsYmFjazogKGVkaXRvciwgdmlldykgPT4ge1xyXG5cclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGZyb21Qb3NpdGlvbjogRWRpdG9yUG9zaXRpb24gPSB7IGxpbmU6IDAsIGNoOiAwIH1cclxuICAgICAgICAgICAgICAgICAgICBsZXQgdG9Qb3NpdGlvbjogRWRpdG9yUG9zaXRpb24gPSB7IGxpbmU6IGVkaXRvci5nZXREb2MoKS5saW5lQ291bnQoKSwgY2g6IDB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBkb2NUZXh0ID0gZWRpdG9yLmdldFJhbmdlKGZyb21Qb3NpdGlvbiwgdG9Qb3NpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IHVwZGF0ZUFsbFN5bnRheChkb2NUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVnaW9uU3RhcnRDb3VudCA9IHJlc3VsdC5yZWdpb25TdGFydENvdW50O1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBjb2x1bW5CcmVha0NvdW50ID0gcmVzdWx0LmNvbHVtbkJyZWFrQ291bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbHVtbkVuZENvdW50ID0gcmVzdWx0LmNvbHVtbkVuZENvdW50O1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB1cGRhdGVkRmlsZUNvbnRlbnQgPSByZXN1bHQudXBkYXRlZEZpbGVDb250ZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZihyZXN1bHQuZmlsZVdhc1VwZGF0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWRpdG9yLnJlcGxhY2VSYW5nZSh1cGRhdGVkRmlsZUNvbnRlbnQsIGZyb21Qb3NpdGlvbiwgdG9Qb3NpdGlvbilcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5vdGljZShgRmluaXNoZWQgdXBkYXRpbmc6XFxuJHtyZWdpb25TdGFydENvdW50fSBzdGFydCBzeW50YXhlcyxcXG4ke2NvbHVtbkJyZWFrQ291bnR9IGNvbHVtbiBicmVha3MsIGFuZFxcbiR7Y29sdW1uRW5kQ291bnR9IGNvbHVtbiBlbmQgdGFncy5gKVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5vdGljZShgRm91bmQgbm8gcmVnaW9uIHN5bnRheCB0byB1cGRhdGUuYClcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IE5vdGljZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgXCJFbmNvdW50ZXJlZCBhbiBlcnJvciBmaXhpbmcgbXVsdGktY29sdW1uIHJlZ2lvbiBzeW50YXguIFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuXCJcclxuICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5yZWdpc3RlckludGVydmFsKHdpbmRvdy5zZXRJbnRlcnZhbCgoKSA9PiB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB0aGlzLlVwZGF0ZU9wZW5GaWxlUHJldmlld3MoKTtcclxuICAgICAgICB9LCA1MDApKTtcclxuICAgIH1cclxuXHJcbiAgICBVcGRhdGVPcGVuRmlsZVByZXZpZXdzKCkge1xyXG5cclxuICAgICAgICBsZXQgZmlsZU1hbmFnZXJzID0gdGhpcy5nbG9iYWxNYW5hZ2VyLmdldEFsbEZpbGVNYW5hZ2VycygpO1xyXG4gICAgICAgIGZpbGVNYW5hZ2Vycy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgbGV0IHJlZ2lvbmFsTWFuYWdlcnMgPSBlbGVtZW50LmdldEFsbFJlZ2lvbmFsTWFuYWdlcnMoKTtcclxuICAgICAgICAgICAgcmVnaW9uYWxNYW5hZ2Vycy5mb3JFYWNoKHJlZ2lvbk1hbmFnZXIgPT4ge1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICByZWdpb25NYW5hZ2VyLnVwZGF0ZVJlbmRlcmVkTWFya2Rvd24oKVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzZXR1cE1hcmtkb3duUG9zdFByb2Nlc3NvcigpIHtcclxuICAgICAgICB0aGlzLnJlZ2lzdGVyTWFya2Rvd25Qb3N0UHJvY2Vzc29yKGFzeW5jIChlbCwgY3R4KSA9PiB7XHJcblxyXG4gICAgICAgICAgICBpZih0aGlzLnNldHRpbmdzTWFuYWdlci5yZW5kZXJPbk1vYmlsZSA9PT0gZmFsc2UgJiZcclxuICAgICAgICAgICAgICAgUGxhdGZvcm0uaXNNb2JpbGUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3Qgc291cmNlUGF0aCA9IGN0eC5zb3VyY2VQYXRoO1xyXG5cclxuICAgICAgICAgICAgbGV0IGZpbGVET01NYW5hZ2VyID0gdGhpcy5nbG9iYWxNYW5hZ2VyLmdldEZpbGVNYW5hZ2VyKHNvdXJjZVBhdGgpO1xyXG4gICAgICAgICAgICBpZihmaWxlRE9NTWFuYWdlciA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiRm91bmQgbnVsbCBET00gbWFuYWdlci4gQ291bGQgbm90IHByb2Nlc3MgbXVsdGktY29sdW1uIG1hcmtkb3duLlwiKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSGVyZSB3ZSBjaGVjayBpZiB0aGUgZXhwb3J0IFwicHJpbnRcIiBmbGFnIGlzIGluIHRoZSBET00gc28gd2UgY2FuIGRldGVybWluZSBpZiB3ZVxyXG4gICAgICAgICAgICAgKiBhcmUgZXhwb3J0aW5nIGFuZCBoYW5kbGUgdGhhdCBjYXNlLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgaWYodGhpcy5jaGVja0V4cG9ydGluZyhlbCkpIHtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmV4cG9ydERvY3VtZW50VG9QREYoZWwsIGZpbGVET01NYW5hZ2VyLCBzb3VyY2VQYXRoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gR2V0IHRoZSBpbmZvIGZvciBvdXIgY3VycmVudCBjb250ZXh0IGFuZCB0aGVuIGNoZWNrXHJcbiAgICAgICAgICAgIC8vIGlmIHRoZSBlbnRpcmUgdGV4dCBjb250YWlucyBhIHN0YXJ0IHRhZy4gSWYgdGhlcmUgaXNcclxuICAgICAgICAgICAgLy8gbm8gc3RhcnQgdGFnIGluIHRoZSBkb2N1bWVudCB3ZSBjYW4ganVzdCByZXR1cm4gYW5kXHJcbiAgICAgICAgICAgIC8vIGlnbm9yZSB0aGUgcmVzdCBvZiB0aGUgcGFyc2luZy5cclxuICAgICAgICAgICAgbGV0IGluZm8gPSBjdHguZ2V0U2VjdGlvbkluZm8oZWwpO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFdlIG5lZWQgdGhlIGNvbnRleHQgaW5mbyB0byBwcm9wZXJseSBwYXJzZSBzbyByZXR1cm5pbmcgaGVyZSBcclxuICAgICAgICAgICAgICogaW5mbyBpcyBudWxsLiBUT0RPOiBTZXQgZXJyb3IgaW4gdmlldyBpZiB0aGlzIG9jY3Vycy5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGlmKCFpbmZvKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgZG9jU3RyaW5nID0gaW5mby50ZXh0O1xyXG4gICAgICAgICAgICBsZXQgZG9jTGluZXMgPSBkb2NTdHJpbmcuc3BsaXQoXCJcXG5cIik7XHJcblxyXG4gICAgICAgICAgICBsZXQgcmVmbG93RnJvbnRtYXR0ZXIgPSBpc011bHRpQ29sdW1uUmVmbG93KGN0eC5mcm9udG1hdHRlcik7XHJcbiAgICAgICAgICAgIGlmKHJlZmxvd0Zyb250bWF0dGVyID09PSB0cnVlKSB7XHJcbiBcclxuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyRG9jUmVmbG93KGVsLCBjdHgsIHNvdXJjZVBhdGgsIGZpbGVET01NYW5hZ2VyLCBkb2NTdHJpbmcsIGluZm8pO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZmlsZURPTU1hbmFnZXIucmVtb3ZlUmVnaW9uKFwiTXVsdGktQ29sdW1uIFJlZmxvdyBSZWdpb25cIik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBJZiB3ZSBlbmNvdW50ZXIgYSBzdGFydCB0YWcgb24gdGhlIGRvY3VtZW50IHdlIHNldCB0aGUgZmxhZyB0byBzdGFydFxyXG4gICAgICAgICAgICAgKiBwYXJzaW5nIHRoZSByZXN0IG9mIHRoZSBkb2N1bWVudC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGlmKG11bHRpQ29sdW1uUGFyc2VyLmNvbnRhaW5zUmVnaW9uU3RhcnQoZG9jU3RyaW5nKSkge1xyXG5cclxuICAgICAgICAgICAgICAgIGZpbGVET01NYW5hZ2VyLnNldEhhc1N0YXJ0VGFnKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKiBcclxuICAgICAgICAgICAgICogSWYgdGhlIGRvY3VtZW50IGRvZXMgbm90IGNvbnRhaW4gYW55IHN0YXJ0IHRhZ3Mgd2UgaWdub3JlIHRoZVxyXG4gICAgICAgICAgICAgKiByZXN0IG9mIHRoZSBwYXJzaW5nLiBUaGlzIGlzIG9ubHkgc2V0IHRvIHRydWUgb25jZSB0aGUgZmlyc3RcclxuICAgICAgICAgICAgICogc3RhcnQgdGFnIGVsZW1lbnQgaXMgcGFyc2VkIGFib3ZlLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgaWYoZmlsZURPTU1hbmFnZXIuZ2V0SGFzU3RhcnRUYWcoKSA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFRha2UgdGhlIGluZm8gcHJvdmlkZWQgYW5kIGdlbmVyYXRlIHRoZSByZXF1aXJlZCB2YXJpYWJsZXMgZnJvbSBcclxuICAgICAgICAgICAgICogdGhlIGxpbmUgc3RhcnQgYW5kIGVuZCB2YWx1ZXMuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBsZXQgcmVsYXRpdmVUZXh0czogRWxlbWVudFJlbGF0aXZlTG9jYXRpb25EYXRhID0gZXh0cmFjdEVsZW1lbnRSZWxhdGl2ZUxvY2F0aW9uRGF0YShkb2NMaW5lcywgaW5mbyk7XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSWYgdGhlIGN1cnJlbnQgbGluZSBpcyBhIHN0YXJ0IHRhZyB3ZSB3YW50IHRvIHNldCB1cCB0aGVcclxuICAgICAgICAgICAgICogcmVnaW9uIG1hbmFnZXIuIFRoZSByZWdpb25hbCBtYW5hZ2VyIHRha2VzIGNhcmVcclxuICAgICAgICAgICAgICogb2YgYWxsIGl0ZW1zIGJldHdlZW4gaXQncyBzdGFydCBhbmQgZW5kIHRhZ3Mgd2hpbGUgdGhlXHJcbiAgICAgICAgICAgICAqIGZpbGUgbWFuYWdlciB3ZSBnb3QgYWJvdmUgYWJvdmUgdGFrZXMgY2FyZSBvZiBhbGwgcmVnaW9uYWwgXHJcbiAgICAgICAgICAgICAqIG1hbmFnZXJzIGluIGVhY2ggZmlsZS5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGlmKG11bHRpQ29sdW1uUGFyc2VyLmNvbnRhaW5zU3RhcnRUYWcocmVsYXRpdmVUZXh0cy50ZXh0T2ZFbGVtZW50KSkge1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBjcmVhdGVTdGFydEVsZW1lbnQoZWwsIHJlbGF0aXZlVGV4dHMubGluZXNPZkVsZW1lbnQsIGN0eCwgZmlsZURPTU1hbmFnZXIsIGRvY1N0cmluZyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFBhbmRvYyBTdGFydCBSZWdpb24gVGFnLlxyXG4gICAgICAgICAgICBpZihjb250YWluc1BhbmRvYy5jb250YWluc1BhbmRvY1N0YXJ0VGFnKHJlbGF0aXZlVGV4dHMudGV4dE9mRWxlbWVudCkpIHtcclxuXHJcbiAgICAgICAgICAgICAgICBjcmVhdGVQYW5kb2NTdGFydEVsZW1lbnQoZWwsIHJlbGF0aXZlVGV4dHMudGV4dE9mRWxlbWVudCwgY3R4LCBmaWxlRE9NTWFuYWdlciwgZG9jU3RyaW5nKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIENoZWNrIGlmIGFueSBvZiB0aGUgbGluZXMgYWJvdmUgdXMgY29udGFpbiBhIHN0YXJ0IGJsb2NrLCBhbmQgaWZcclxuICAgICAgICAgICAgICogc28gZ2V0IHRoZSBsaW5lcyBmcm9tIG91ciBjdXJyZW50IGVsZW1lbnQgdG8gdGhlIHN0YXJ0IGJsb2NrLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgbGV0IHN0YXJ0Qm9ja0Fib3ZlID0gbXVsdGlDb2x1bW5QYXJzZXIuZ2V0U3RhcnREYXRhQWJvdmVMaW5lKHJlbGF0aXZlVGV4dHMubGluZXNBYm92ZUFycmF5KTtcclxuICAgICAgICAgICAgaWYoc3RhcnRCb2NrQWJvdmUgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogV2Ugbm93IGtub3cgd2UncmUgd2l0aGluIGEgbXVsdGktY29sdW1uIHJlZ2lvbiwgc28gd2UgdXBkYXRlIG91clxyXG4gICAgICAgICAgICAgKiBsaXN0IG9mIGxpbmVzIGFib3ZlIHRvIGp1c3QgYmUgdGhlIGl0ZW1zIHdpdGhpbiB0aGlzIHJlZ2lvbi5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHJlbGF0aXZlVGV4dHMubGluZXNBYm92ZUFycmF5ID0gc3RhcnRCb2NrQWJvdmUubGluZXNBYm92ZUFycmF5O1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFdlIHVzZSB0aGUgc3RhcnQgYmxvY2sncyBrZXkgdG8gZ2V0IG91ciByZWdpb25hbCBtYW5hZ2VyLiBJZiB0aGlzXHJcbiAgICAgICAgICAgICAqIGxvb2t1cCBmYWlscyB3ZSBjYW4gbm90IGNvbnRpbnVlIHByb2Nlc3NpbmcgdGhpcyBlbGVtZW50LlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgbGV0IHJlZ2lvbmFsQ29udGFpbmVyOiBSZWdpb25NYW5hZ2VyQ29udGFpbmVyID0gZmlsZURPTU1hbmFnZXIuZ2V0UmVnaW9uYWxDb250YWluZXIoc3RhcnRCb2NrQWJvdmUuc3RhcnRCbG9ja0tleSk7XHJcbiAgICAgICAgICAgIGlmKHJlZ2lvbmFsQ29udGFpbmVyID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbGV0IHJlZ2lvbmFsTWFuYWdlcjogUmVnaW9uTWFuYWdlciA9IHJlZ2lvbmFsQ29udGFpbmVyLmdldFJlZ2lvbigpO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFRvIG1ha2Ugc3VyZSB3ZSdyZSBwbGFjaW5nIHRoZSBpdGVtIGluIHRoZSByaWdodCBsb2NhdGlvbiAoYW5kIFxyXG4gICAgICAgICAgICAgKiBvdmVyd3JpdGUgZWxlbWVudHMgdGhhdCBhcmUgbm93IGdvbmUpIHdlIG5vdyB3YW50IGFsbCBvZiB0aGVcclxuICAgICAgICAgICAgICogbGluZXMgYWZ0ZXIgdGhpcyBlbGVtZW50IHVwIHRvIHRoZSBlbmQgdGFnLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgcmVsYXRpdmVUZXh0cy5saW5lc0JlbG93QXJyYXkgPSAgbXVsdGlDb2x1bW5QYXJzZXIuZ2V0RW5kQmxvY2tCZWxvdyhyZWxhdGl2ZVRleHRzLmxpbmVzQmVsb3dBcnJheSk7XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTm93IHdlIHRha2UgdGhlIGxpbmVzIGFib3ZlIG91ciBjdXJyZW50IGVsZW1lbnQgdXAgdW50aWwgdGhlXHJcbiAgICAgICAgICAgICAqIHN0YXJ0IHJlZ2lvbiB0YWcgYW5kIHJlbmRlciB0aGF0IGludG8gYW4gSFRNTCBlbGVtZW50LiBXZSB3aWxsIFxyXG4gICAgICAgICAgICAgKiB1c2UgdGhlc2UgZWxlbWVudHMgdG8gZGV0ZXJtaW5lIHdoZXJlIHRvIHBsYWNlIG91ciBjdXJyZW50IGVsZW1lbnQuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICByZWdpb25hbE1hbmFnZXIgPSB0aGlzLmFwcGVuZFRvUmVnaW9uYWxNYW5hZ2VyKGVsLCByZWdpb25hbENvbnRhaW5lciwgY3R4LCByZWxhdGl2ZVRleHRzLCBzb3VyY2VQYXRoLCBzdGFydEJvY2tBYm92ZSwgKGRvbU9iajogRE9NT2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBvblVubG9hZEVsZW1lbnQoZG9tT2JqLCByZWdpb25hbENvbnRhaW5lcik7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhcHBlbmRUb1JlZ2lvbmFsTWFuYWdlcihlbDogSFRNTEVsZW1lbnQsIHJlZ2lvbmFsQ29udGFpbmVyOiBSZWdpb25NYW5hZ2VyQ29udGFpbmVyLCBjdHg6IE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIHJlbGF0aXZlTGluZXM6IEVsZW1lbnRSZWxhdGl2ZUxvY2F0aW9uRGF0YSwgc291cmNlUGF0aDogc3RyaW5nLCBwYXJlbnRTdGFydEJsb2NrOiBtdWx0aUNvbHVtblBhcnNlci5TdGFydFRhZ0RhdGEsIG9uVW5sb2FkQ2FsbGJhY2s6IChkb21PYmo6IERPTU9iamVjdCkgPT4gdm9pZCkge1xyXG5cclxuICAgICAgICBsZXQgeyBsaW5lc0Fib3ZlQXJyYXksIGxpbmVzT2ZFbGVtZW50LCBsaW5lc0JlbG93QXJyYXksIHRleHRPZkVsZW1lbnQgfSA9IHJlbGF0aXZlTGluZXM7XHJcblxyXG4gICAgICAgIGxldCBzaWJsaW5nc0Fib3ZlOiBIVE1MRGl2RWxlbWVudCA9IHJlbmRlck1hcmtkb3duRnJvbUxpbmVzKGxpbmVzQWJvdmVBcnJheSwgc291cmNlUGF0aCk7XHJcblxyXG4gICAgICAgIGxldCBzaWJsaW5nc0JlbG93OiBIVE1MRGl2RWxlbWVudCA9IHJlbmRlck1hcmtkb3duRnJvbUxpbmVzKGxpbmVzQmVsb3dBcnJheSwgc291cmNlUGF0aCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgbGV0IHJlZ2lvbmFsTWFuYWdlcjogUmVnaW9uTWFuYWdlciA9IHJlZ2lvbmFsQ29udGFpbmVyLmdldFJlZ2lvbigpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdXAgb3VyIGRvbSBvYmplY3QgdG8gYmUgYWRkZWQgdG8gdGhlIG1hbmFnZXIuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbGV0IGN1cnJlbnRPYmplY3Q6IERPTU9iamVjdCA9IG5ldyBET01PYmplY3QoZWwsIGxpbmVzT2ZFbGVtZW50KTtcclxuICAgICAgICBlbC5pZCA9IGN1cnJlbnRPYmplY3QuVUlEO1xyXG5cclxuICAgICAgICBjdXJyZW50T2JqZWN0ID0gVGFza0xpc3RET01PYmplY3QuY2hlY2tGb3JUYXNrTGlzdEVsZW1lbnQoY3VycmVudE9iamVjdCk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE5vdyB3ZSBhZGQgdGhlIG9iamVjdCB0byB0aGUgbWFuYWdlciBhbmQgdGhlbiBzZXR1cCB0aGVcclxuICAgICAgICAgKiBjYWxsYmFjayBmb3Igd2hlbiB0aGUgb2JqZWN0IGlzIHJlbW92ZWQgZnJvbSB2aWV3IHRoYXQgd2lsbCByZW1vdmVcclxuICAgICAgICAgKiB0aGUgaXRlbSBmcm9tIHRoZSBtYW5hZ2VyLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGxldCBhZGRJbmRleCA9IHJlZ2lvbmFsTWFuYWdlci5hZGRPYmplY3Qoc2libGluZ3NBYm92ZSwgc2libGluZ3NCZWxvdywgY3VycmVudE9iamVjdCk7XHJcblxyXG4gICAgICAgIGxldCBlbGVtZW50TWFya2Rvd25SZW5kZXJlciA9IG5ldyBNYXJrZG93blJlbmRlckNoaWxkKGVsKTtcclxuICAgICAgICBlbGVtZW50TWFya2Rvd25SZW5kZXJlci5vbnVubG9hZCA9ICgpID0+IHtcclxuICAgICAgICAgICAgb25VbmxvYWRDYWxsYmFjayhjdXJyZW50T2JqZWN0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY3R4LmFkZENoaWxkKGVsZW1lbnRNYXJrZG93blJlbmRlcmVyKTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTm93IHdlIGNoZWNrIGlmIG91ciBjdXJyZW50IGVsZW1lbnQgaXMgYSBzcGVjaWFsIGZsYWcgc28gd2UgY2FuXHJcbiAgICAgICAgICogcHJvcGVybHkgc2V0IHRoZSBlbGVtZW50IHRhZyB3aXRoaW4gdGhlIHJlZ2lvbmFsIG1hbmFnZXIuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaWYgKG11bHRpQ29sdW1uUGFyc2VyLmNvbnRhaW5zRW5kVGFnKGVsLnRleHRDb250ZW50KSA9PT0gdHJ1ZSAmJlxyXG4gICAgICAgICAgICBwYXJlbnRTdGFydEJsb2NrLnN0YXJ0QmxvY2tUeXBlICE9PSBcIlBBRE9DXCIpIHtcclxuXHJcbiAgICAgICAgICAgIGN1cnJlbnRPYmplY3QuZWxlbWVudFR5cGUgPSBcInVuUmVuZGVyZWRcIjtcclxuICAgICAgICAgICAgcmVnaW9uYWxNYW5hZ2VyLnVwZGF0ZUVsZW1lbnRUYWcoY3VycmVudE9iamVjdC5VSUQsIERPTU9iamVjdFRhZy5lbmRSZWdpb24pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29udGFpbnNQYW5kb2MuaXNWYWxpZFBhbmRvY0VuZFRhZyhsaW5lc0Fib3ZlQXJyYXksIGVsLnRleHRDb250ZW50KSA9PT0gdHJ1ZSAmJlxyXG4gICAgICAgICAgICBwYXJlbnRTdGFydEJsb2NrLnN0YXJ0QmxvY2tUeXBlID09PSBcIlBBRE9DXCIpIHtcclxuXHJcbiAgICAgICAgICAgIGN1cnJlbnRPYmplY3QuZWxlbWVudFR5cGUgPSBcInVuUmVuZGVyZWRcIjtcclxuICAgICAgICAgICAgcmVnaW9uYWxNYW5hZ2VyLnVwZGF0ZUVsZW1lbnRUYWcoY3VycmVudE9iamVjdC5VSUQsIERPTU9iamVjdFRhZy5lbmRSZWdpb24pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChtdWx0aUNvbHVtblBhcnNlci5jb250YWluc0NvbEVuZFRhZyh0ZXh0T2ZFbGVtZW50KSA9PT0gdHJ1ZSkge1xyXG5cclxuICAgICAgICAgICAgY3VycmVudE9iamVjdC5lbGVtZW50VHlwZSA9IFwidW5SZW5kZXJlZFwiO1xyXG4gICAgICAgICAgICByZWdpb25hbE1hbmFnZXIudXBkYXRlRWxlbWVudFRhZyhjdXJyZW50T2JqZWN0LlVJRCwgRE9NT2JqZWN0VGFnLmNvbHVtbkJyZWFrKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAobXVsdGlDb2x1bW5QYXJzZXIuY29udGFpbnNDb2xTZXR0aW5nc1RhZyh0ZXh0T2ZFbGVtZW50KSA9PT0gdHJ1ZSkge1xyXG5cclxuICAgICAgICAgICAgY3VycmVudE9iamVjdC5lbGVtZW50VHlwZSA9IFwidW5SZW5kZXJlZFwiO1xyXG4gICAgICAgICAgICByZWdpb25hbE1hbmFnZXIgPSByZWdpb25hbENvbnRhaW5lci5zZXRSZWdpb25TZXR0aW5ncyh0ZXh0T2ZFbGVtZW50KTtcclxuICAgICAgICAgICAgcmVnaW9uYWxNYW5hZ2VyLnVwZGF0ZUVsZW1lbnRUYWcoY3VycmVudE9iamVjdC5VSUQsIERPTU9iamVjdFRhZy5yZWdpb25TZXR0aW5ncyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNldEVsZW1lbnRDU1MoY3VycmVudE9iamVjdCwgZWwpO1xyXG5cclxuICAgICAgICBwYXJzZUNvbEJyZWFrRXJyb3JUeXBlKHtcclxuICAgICAgICAgICAgbGluZUFib3ZlOiBsaW5lc0Fib3ZlQXJyYXkubGFzdCgpLFxyXG4gICAgICAgICAgICBsaW5lQmVsb3c6IGxpbmVzQmVsb3dBcnJheS5maXJzdCgpLFxyXG4gICAgICAgICAgICBvYmplY3RUYWc6IGN1cnJlbnRPYmplY3QudGFnLFxyXG4gICAgICAgICAgICBjb2xCcmVha1R5cGU6IGN1cnJlbnRPYmplY3QuZWxlbWVudElzQ29sdW1uQnJlYWtcclxuICAgICAgICB9LCByZWdpb25hbE1hbmFnZXIuZXJyb3JNYW5hZ2VyKVxyXG5cclxuICAgICAgICByZWdpb25hbE1hbmFnZXIucmVuZGVyUmVnaW9uRWxlbWVudHNUb1NjcmVlbigpO1xyXG4gICAgICAgIHJldHVybiByZWdpb25hbE1hbmFnZXI7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0dXBNYXJrZG93bkNvZGVibG9ja1Bvc3RQcm9jZXNzb3Ioc3RhcnRTdHI6IHN0cmluZykge1xyXG5cclxuICAgICAgICB0aGlzLnJlZ2lzdGVyTWFya2Rvd25Db2RlQmxvY2tQcm9jZXNzb3Ioc3RhcnRTdHIsIChzb3VyY2UsIGVsLCBjdHgpID0+IHtcclxuXHJcbiAgICAgICAgICAgIGlmKHRoaXMuc2V0dGluZ3NNYW5hZ2VyLnJlbmRlck9uTW9iaWxlID09PSBmYWxzZSAmJlxyXG4gICAgICAgICAgICAgICAgUGxhdGZvcm0uaXNNb2JpbGUgPT09IHRydWUpIHtcclxuIFxyXG4gICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3Qgc291cmNlUGF0aCA9IGN0eC5zb3VyY2VQYXRoO1xyXG4gICAgICAgIFxyXG4gICAgICAgICAgICAvLyBTZXQgdXAgb3VyIENTUyBzbyB0aGF0IHRoZSBjb2RlYmxvY2sgb25seSByZW5kZXJzIHRoaXMgZGF0YSBpbiByZWFkaW5nIG1vZGVcclxuICAgICAgICAgICAgLy8gc291cmNlL2xpdmUgcHJldmlldyBtb2RlIGlzIGhhbmRsZWQgYnkgdGhlIENNNiBpbXBsZW1lbnRhdGlvbi5cclxuICAgICAgICAgICAgZWwucGFyZW50RWxlbWVudD8uYWRkQ2xhc3MoXCJwcmVpdmV3LW1jbS1zdGFydC1ibG9ja1wiKTtcclxuICAgICAgICBcclxuICAgICAgICAgICAgLy8gVG8gZGV0ZXJtaW5lIHdoYXQga2luZCBvZiB2aWV3IHdlIGFyZSByZW5kZXJpbmcgaW4gd2UgbmVlZCBhIG1hcmtkb3duIGxlYWYuXHJcbiAgICAgICAgICAgIC8vIFJlYWxseSB0aGlzIHNob3VsZCBuZXZlciByZXR1cm4gaGVyZSBzaW5jZSByZW5kZXJpbmcgaXMgb25seSBkb25lIGluIG1hcmtkb3duIGxlYXZlcy5cclxuICAgICAgICAgICAgbGV0IG1hcmtkb3duTGVhdmVzID0gYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoXCJtYXJrZG93blwiKTtcclxuICAgICAgICAgICAgaWYobWFya2Rvd25MZWF2ZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICAgICAgaWYodGhpcy5nbG9iYWxNYW5hZ2VyID09PSBudWxsIHx8IHRoaXMuZ2xvYmFsTWFuYWdlciA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIkdsb2JhbCBtYW5hZ2VyIGlzIHVuZGVmaW5lZD9cIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGxldCBmaWxlRE9NTWFuYWdlciA9IHRoaXMuZ2xvYmFsTWFuYWdlci5nZXRGaWxlTWFuYWdlcihzb3VyY2VQYXRoKTtcclxuICAgICAgICAgICAgaWYoZmlsZURPTU1hbmFnZXIgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgaWYoY3R4LmZyb250bWF0dGVyICYmIFxyXG4gICAgICAgICAgICAgICBjdHguZnJvbnRtYXR0ZXJbXCJNdWx0aS1Db2x1bW4gUmVmbG93XCJdICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZpbGVET01NYW5hZ2VyLnJlbW92ZVJlZ2lvbihcIk11bHRpLUNvbHVtbiBSZWZsb3cgUmVnaW9uXCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBTZXQgZmlsZSB0byBoYXZlIHN0YXJ0IHRhZy5cclxuICAgICAgICAgICAgZmlsZURPTU1hbmFnZXIuc2V0SGFzU3RhcnRUYWcoKTtcclxuICAgICAgICBcclxuICAgICAgICAgICAgLy8gR2V0IHRoZSBpbmZvIGZvciBvdXIgY3VycmVudCBjb250ZXh0IGFuZCB0aGVuIGNoZWNrXHJcbiAgICAgICAgICAgIC8vIGlmIHRoZSBlbnRpcmUgdGV4dCBjb250YWlucyBhIHN0YXJ0IHRhZy4gSWYgdGhlcmUgaXNcclxuICAgICAgICAgICAgLy8gbm8gc3RhcnQgdGFnIGluIHRoZSBkb2N1bWVudCB3ZSBjYW4ganVzdCByZXR1cm4gYW5kXHJcbiAgICAgICAgICAgIC8vIGlnbm9yZSB0aGUgcmVzdCBvZiB0aGUgcGFyc2luZy5cclxuICAgICAgICAgICAgbGV0IGluZm8gPSBjdHguZ2V0U2VjdGlvbkluZm8oZWwpO1xyXG4gICAgICAgIFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogV2UgbmVlZCB0aGUgY29udGV4dCBpbmZvIHRvIHByb3Blcmx5IHBhcnNlIHNvIHJldHVybmluZyBoZXJlIFxyXG4gICAgICAgICAgICAgKiBpbmZvIGlzIG51bGwuIFRPRE86IFNldCBlcnJvciBpbiB2aWV3IGlmIHRoaXMgb2NjdXJzLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgaWYoIWluZm8pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgICAgICAvKiogXHJcbiAgICAgICAgICAgICAqIFNldCB1cCB0aGUgY3VycmVudCBlbGVtZW50IHRvIGFjdCBhcyB0aGUgcGFyZW50IGZvciB0aGUgXHJcbiAgICAgICAgICAgICAqIG11bHRpLWNvbHVtbiByZWdpb24uXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBlbC5jbGFzc0xpc3QuYWRkKE11bHRpQ29sdW1uTGF5b3V0Q1NTLlJlZ2lvblJvb3RDb250YWluZXJEaXYpXHJcblxyXG4gICAgICAgICAgICBsZXQgZXJyb3JNYW5hZ2VyID0gbmV3IFJlZ2lvbkVycm9yTWFuYWdlcihlbCwgW1wiVGhlIGNvZGVibG9jayByZWdpb24gc3RhcnQgc3ludGF4IGhhcyBiZWVuIGRlcHJpY2F0ZWQuIFBsZWFzZSBtYW51YWxseSB1cGRhdGUgdG8gdGhlIGN1cnJlbnQgc3ludGF4IGRlZmluZWQgaW4gdGhlIFJlYWRNZSwgcnVuIHRoZSBcXFwiRml4IE11bHRpLUNvbHVtbiBTeW50YXggaW4gQ3VycmVudCBGaWxlXFxcIiBmcm9tIHRoZSBDb21tYW5kIFBhbGV0dGUsIG9yIHVzZSB0aGUgXFxcIlVwZGF0ZSBEZXByaWNhdGVkIFN5bnRheFxcXCIgY29tbWFuZCBmb3VuZCBpbiB0aGUgcGx1Z2luIHNldHRpbmdzIHdpbmRvdy4gWW91IG11c3QgcmVsb2FkIHRoZSBmaWxlIGZvciBjaGFuZ2VzIHRvIHRha2UgZWZmZWN0LlwiXSk7XHJcbiAgICAgICAgICAgIGxldCByZW5kZXJDb2x1bW5SZWdpb24gPSBlbC5jcmVhdGVEaXYoe1xyXG4gICAgICAgICAgICAgICAgY2xzOiBNdWx0aUNvbHVtbkxheW91dENTUy5SZWdpb25Db250ZW50Q29udGFpbmVyRGl2XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgIGxldCByZWdpb25LZXkgPSBwYXJzZVN0YXJ0UmVnaW9uQ29kZUJsb2NrSUQoc291cmNlKTtcclxuICAgICAgICBcclxuICAgICAgICAgICAgbGV0IGNyZWF0ZU5ld1JlZ2lvbk1hbmFnZXIgPSB0cnVlO1xyXG4gICAgICAgICAgICBpZihmaWxlRE9NTWFuYWdlci5jaGVja0tleUV4aXN0cyhyZWdpb25LZXkpID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGNyZWF0ZU5ld1JlZ2lvbk1hbmFnZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGxldCB7IG51bWJlck9mVGFncywga2V5cyB9ID0gbXVsdGlDb2x1bW5QYXJzZXIuY291bnRTdGFydFRhZ3MoaW5mby50ZXh0KTtcclxuICAgICAgICBcclxuICAgICAgICAgICAgICAgIGxldCBudW1NYXRjaGVzID0gMDtcclxuICAgICAgICAgICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBudW1iZXJPZlRhZ3M7IGkrKykge1xyXG4gICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIEJlY2F1c2Ugd2UgY2hlY2tlZCBpZiBrZXkgZXhpc3RzIG9uZSBvZiB0aGVzZSBoYXMgdG8gbWF0Y2guXHJcbiAgICAgICAgICAgICAgICAgICAgaWYoa2V5c1tpXSA9PT0gcmVnaW9uS2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bU1hdGNoZXMrKztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAvLyBXZSBvbmx5IHdhbnQgdG8gZGlzcGxheSBhbiBlcnJvciBpZiB0aGVyZSBhcmUgbW9yZSB0aGFuIDIgb2YgdGhlIHNhbWUgaWQgYWNyb3NzXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgd2hvbGUgZG9jdW1lbnQuIFRoaXMgcHJldmVudHMgZXJyb3Mgd2hlbiBvYnNpZGlhbiByZWxvYWRzIHRoZSB3aG9sZSBkb2N1bWVudFxyXG4gICAgICAgICAgICAgICAgLy8gYW5kIHRoZXJlIGFyZSB0d28gb2YgdGhlIHNhbWUga2V5IGluIHRoZSBtYXAuXHJcbiAgICAgICAgICAgICAgICBpZihudW1NYXRjaGVzID49IDIpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZihyZWdpb25LZXkgPT09IFwiXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNYW5hZ2VyLmFkZEVycm9yTWVzc2FnZShcIkZvdW5kIG11bHRpcGxlIHJlZ2lvbnMgd2l0aCBlbXB0eSBJRHMuIFBsZWFzZSBzZXQgYSB1bmlxdWUgSUQgaW4gdGhlIGNvZGVibG9jay5cXG5FRzogJ0lEOiByYW5kb21JRCdcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1hbmFnZXIuYWRkRXJyb3JNZXNzYWdlKFwiUmVnaW9uIElEIGFscmVhZHkgZXhpc3RzIGluIGRvY3VtZW50LCBwbGVhc2Ugc2V0IGEgdW5pcXVlIElELlwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsLmlkID0gYE11bHRpQ29sdW1uSUQ6JHtyZWdpb25LZXl9YFxyXG4gICAgICAgIFxyXG4gICAgICAgICAgICAvLyBJZiBzb21ldGhpbmcgY2hhbmdlcyBpbiB0aGUgY29kZWJsb2NrIHdlIGRvbnQgbmVjZXNzYXJpbHkgd2FudCB0byB1cGRhdGUgb3VyXHJcbiAgICAgICAgICAgIC8vIG9sZCByZWZlcmVuY2UgdG8gdGhlIHJlZ2lvbiBtYW5hZ2VyLiBUaGlzIGNvdWxkIGJlIGEgcG90ZW50aWFsIGJ1ZyBhcmVhLlxyXG4gICAgICAgICAgICBpZihjcmVhdGVOZXdSZWdpb25NYW5hZ2VyID09PSB0cnVlKSB7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgcmVnaW9uYWwgbWFuYWdlci5cclxuICAgICAgICAgICAgICAgIGxldCBlbGVtZW50TWFya2Rvd25SZW5kZXJlciA9IG5ldyBNYXJrZG93blJlbmRlckNoaWxkKGVsKTtcclxuICAgICAgICAgICAgICAgIGZpbGVET01NYW5hZ2VyLmNyZWF0ZVJlZ2lvbmFsTWFuYWdlcihyZWdpb25LZXksIGVsLCBlcnJvck1hbmFnZXIsIHJlbmRlckNvbHVtblJlZ2lvbik7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgdXAgdGhlIG9uIHVubG9hZCBjYWxsYmFjay4gVGhpcyBjYW4gYmUgY2FsbGVkIGlmIHRoZSB1c2VyIGNoYW5nZXNcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBzdGFydC9zZXR0aW5ncyBjb2RlYmxvY2sgaW4gYW55IHdheS4gV2Ugb25seSB3YW50IHRvIHVubG9hZFxyXG4gICAgICAgICAgICAgICAgLy8gaWYgdGhlIGZpbGUgaXMgYmVpbmcgcmVtb3ZlZCBmcm9tIHZpZXcuXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50TWFya2Rvd25SZW5kZXJlci5vbnVubG9hZCA9ICgpID0+IHtcclxuICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBpZihmaWxlRE9NTWFuYWdlciAmJiBmaWxlU3RpbGxJblZpZXcoc291cmNlUGF0aCkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUuZGVidWcoXCJGaWxlIG5vdCBpbiBhbnkgbWFya2Rvd24gbGVhZi4gUmVtb3ZpbmcgcmVnaW9uIGZyb20gZG9tIG1hbmFnZXIuXCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVET01NYW5hZ2VyLnJlbW92ZVJlZ2lvbihyZWdpb25LZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICBjdHguYWRkQ2hpbGQoZWxlbWVudE1hcmtkb3duUmVuZGVyZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgIGxldCByZWdpb25hbE1hbmFnZXJDb250YWluZXIgPSBmaWxlRE9NTWFuYWdlci5nZXRSZWdpb25hbENvbnRhaW5lcihyZWdpb25LZXkpO1xyXG4gICAgICAgICAgICBpZihyZWdpb25hbE1hbmFnZXJDb250YWluZXIgIT09IG51bGwpIHtcclxuICAgICAgICBcclxuICAgICAgICAgICAgICAgIGxldCByZWdpb25hbE1hbmFnZXIgPSByZWdpb25hbE1hbmFnZXJDb250YWluZXIuc2V0UmVnaW9uU2V0dGluZ3Moc291cmNlKTtcclxuICAgICAgICAgICAgICAgIHJlZ2lvbmFsTWFuYWdlci5yZWdpb25QYXJlbnQgPSByZW5kZXJDb2x1bW5SZWdpb247XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGxvYWRTZXR0aW5ncygpIHtcclxuXHJcblx0XHR0aGlzLnNldHRpbmdzTWFuYWdlci5zZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oe30sIERFRkFVTFRfU0VUVElOR1MsIGF3YWl0IHRoaXMubG9hZERhdGEoKSk7XHJcblx0fVxyXG5cclxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKSB7XHJcblx0XHRhd2FpdCB0aGlzLnNhdmVEYXRhKHRoaXMuc2V0dGluZ3NNYW5hZ2VyLnNldHRpbmdzKTtcclxuXHR9XHJcblxyXG4gICAgcmVuZGVyRG9jUmVmbG93KGVsOiBIVE1MRWxlbWVudCwgY3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LCBzb3VyY2VQYXRoOiBzdHJpbmcsIGZpbGVET01NYW5hZ2VyOiBGaWxlRE9NTWFuYWdlciwgZG9jU3RyaW5nOiBzdHJpbmcsIGluZm86IE1hcmtkb3duU2VjdGlvbkluZm9ybWF0aW9uKSB7XHJcblxyXG4gICAgICAgIGxldCByZWdpb25hbENvbnRhaW5lcjogUmVnaW9uTWFuYWdlckNvbnRhaW5lciA9IG51bGw7XHJcbiAgICAgICAgaWYoZmlsZURPTU1hbmFnZXIuY2hlY2tLZXlFeGlzdHMoXCJNdWx0aS1Db2x1bW4gUmVmbG93IFJlZ2lvblwiKSA9PT0gdHJ1ZSAmJlxyXG4gICAgICAgICAgIGVsLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJmcm9udG1hdHRlclwiKS5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgcmVnaW9uYWxDb250YWluZXIgPSBmaWxlRE9NTWFuYWdlci5nZXRSZWdpb25hbENvbnRhaW5lcihcIk11bHRpLUNvbHVtbiBSZWZsb3cgUmVnaW9uXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmKGZpbGVET01NYW5hZ2VyLmNoZWNrS2V5RXhpc3RzKFwiTXVsdGktQ29sdW1uIFJlZmxvdyBSZWdpb25cIikgPT09IHRydWUgJiZcclxuICAgICAgICAgICAgICAgIGVsLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJmcm9udG1hdHRlclwiKS5sZW5ndGggPT09IDEpIHtcclxuXHJcbiAgICAgICAgICAgIGxldCBwYXJlbnRFbCA9IGNyZWF0ZURpdigpXHJcbiAgICAgICAgICAgIGVsLmFwcGVuZENoaWxkKHBhcmVudEVsKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEdldCBjdXJyZW50IGRhdGEsIHJlbW92ZSBvbGQgcmVnaW9uLlxyXG4gICAgICAgICAgICByZWdpb25hbENvbnRhaW5lciA9IGZpbGVET01NYW5hZ2VyLmdldFJlZ2lvbmFsQ29udGFpbmVyKFwiTXVsdGktQ29sdW1uIFJlZmxvdyBSZWdpb25cIik7XHJcbiAgICAgICAgICAgIGxldCBkb21MaXN0ID0gcmVnaW9uYWxDb250YWluZXIuZ2V0UmVnaW9uKCkuZ2V0UmVnaW9uRGF0YSgpLmRvbUxpc3Quc2xpY2UoKTtcclxuICAgICAgICAgICAgZmlsZURPTU1hbmFnZXIucmVtb3ZlUmVnaW9uKFwiTXVsdGktQ29sdW1uIFJlZmxvdyBSZWdpb25cIik7XHJcblxyXG4gICAgICAgICAgICAvLyBDcmVhdGUgbmV3IHJlZ2lvbi5cclxuICAgICAgICAgICAgc2V0dXBTdGFydFRhZyhwYXJlbnRFbCwgY3R4LCBmaWxlRE9NTWFuYWdlciwgZG9jU3RyaW5nLCBcIk11bHRpLUNvbHVtbiBSZWZsb3cgUmVnaW9uXCIpO1xyXG4gICAgICAgICAgICByZWdpb25hbENvbnRhaW5lciA9IGZpbGVET01NYW5hZ2VyLmdldFJlZ2lvbmFsQ29udGFpbmVyKFwiTXVsdGktQ29sdW1uIFJlZmxvdyBSZWdpb25cIik7XHJcbiAgICAgICAgICAgIGxldCBzZXR0aW5ncyA9IGdldE11bHRpQ29sdW1uU2V0dGluZ3NGcm9tRnJvbnRtYXR0ZXIoY3R4KTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGxldCBsZWFmID0gZ2V0TGVhZkZyb21GaWxlUGF0aCh0aGlzLmFwcC53b3Jrc3BhY2UsIGN0eC5zb3VyY2VQYXRoKTtcclxuICAgICAgICAgICAgbGV0IGNsaWVudEhlaWdodCA9IGNhbGNWaXNpYmxlQ2xpZXRIZWlnaHQobGVhZiwgdGhpcy5hcHAud29ya3NwYWNlKTtcclxuICAgICAgICAgICAgaWYoc2V0dGluZ3MuY29sdW1uSGVpZ2h0ID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBzZXR0aW5ncy5jb2x1bW5IZWlnaHQgPSBIVE1MU2l6aW5nLmNyZWF0ZSgpLnNldFdpZHRoKGNsaWVudEhlaWdodCkuc2V0VW5pdHMoXCJweFwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHNldHRpbmdzLmNvbHVtbkhlaWdodCA9IHNldHRpbmdzLmNvbHVtbkhlaWdodC5jb252ZXJ0VG9QWCh0aGlzLmFwcC53b3Jrc3BhY2UuY29udGFpbmVyRWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJlZ2lvbmFsQ29udGFpbmVyLnNldFJlZ2lvblBhcnNlZFNldHRpbmdzKHNldHRpbmdzKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIC8vIFJlLVJlbmRlciBhZnRlciBzbWFsbCBkZWxheS5cclxuICAgICAgICAgICAgLy8gRGVsYXkgaXMgc28gdGhlIGF1dG8gbGF5b3V0IGNoZWNrIGNhbiBwcm9wZXJseSByZWFkIHRoZSBjbGllbnQgaGVpZ2h0LlxyXG4gICAgICAgICAgICBhc3luYyBmdW5jdGlvbiBkZWxheVJlbmRlcigpIHtcclxuXHJcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpPT4geyAgICAgICAgICAgICAgICAgICAgXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIEFwcGVuZCBhbGwgaXRlbXMgdG8gcmVnaW9uLlxyXG4gICAgICAgICAgICAgICAgICAgIGxldCByZWdpb25hbE1hbmFnZXIgPSByZWdpb25hbENvbnRhaW5lci5nZXRSZWdpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgbGlzdExlbmd0aCA9IGRvbUxpc3QubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBsaXN0TGVuZ3RoOyBpKyspIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkb21PYmogPSBkb21MaXN0LnNoaWZ0KClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW9uYWxNYW5hZ2VyLmFkZE9iamVjdEF0SW5kZXgoZG9tT2JqLCBpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEVsZW1lbnRDU1MoZG9tT2JqLCBkb21PYmoub3JpZ2luYWxFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJlZ2lvbmFsQ29udGFpbmVyLmdldFJlZ2lvbigpLnJlbmRlclJlZ2lvbkVsZW1lbnRzVG9TY3JlZW4oKTtcclxuICAgICAgICAgICAgICAgIH0sIDUwKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlbGF5UmVuZGVyKCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG5cclxuICAgICAgICAgICAgLy8gVGhlIGZpcnN0IGVsZW1lbnQgdG8gaGl0IHRoaXMgcG9pbnQgYXBwZWFycyB0byBiZSB0aGUgeWFtbCBpbmZvcm1hdGlvbiB3aGljaCB3ZSBjYW4gdXNlXHJcbiAgICAgICAgICAgIC8vIGFzIG91ciByb290IGRpdiBzaW5jZSB0aGUgd2hvbGUgZG9jIGlzIGdvaW5nIHRvIGJlIHJlLWZvcm1hdHRlZC5cclxuICAgICAgICAgICAgbGV0IHBhcmVudEVsID0gY3JlYXRlRGl2KClcclxuICAgICAgICAgICAgZWwuYXBwZW5kQ2hpbGQocGFyZW50RWwpO1xyXG5cclxuICAgICAgICAgICAgc2V0dXBTdGFydFRhZyhwYXJlbnRFbCwgY3R4LCBmaWxlRE9NTWFuYWdlciwgZG9jU3RyaW5nLCBcIk11bHRpLUNvbHVtbiBSZWZsb3cgUmVnaW9uXCIpO1xyXG4gICAgICAgICAgICByZWdpb25hbENvbnRhaW5lciA9IGZpbGVET01NYW5hZ2VyLmdldFJlZ2lvbmFsQ29udGFpbmVyKFwiTXVsdGktQ29sdW1uIFJlZmxvdyBSZWdpb25cIik7XHJcblxyXG4gICAgICAgICAgICBsZXQgc2V0dGluZ3MgPSBnZXRNdWx0aUNvbHVtblNldHRpbmdzRnJvbUZyb250bWF0dGVyKGN0eCk7XHJcbiAgICAgICAgICAgIGxldCBsZWFmID0gZ2V0TGVhZkZyb21GaWxlUGF0aCh0aGlzLmFwcC53b3Jrc3BhY2UsIGN0eC5zb3VyY2VQYXRoKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBjbGllbnRIZWlnaHQgPSBjYWxjVmlzaWJsZUNsaWV0SGVpZ2h0KGxlYWYsIHRoaXMuYXBwLndvcmtzcGFjZSk7XHJcbiAgICAgICAgICAgIGlmKHNldHRpbmdzLmNvbHVtbkhlaWdodCA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgc2V0dGluZ3MuY29sdW1uSGVpZ2h0ID0gSFRNTFNpemluZy5jcmVhdGUoKS5zZXRXaWR0aChjbGllbnRIZWlnaHQpLnNldFVuaXRzKFwicHhcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBzZXR0aW5ncy5jb2x1bW5IZWlnaHQgPSBzZXR0aW5ncy5jb2x1bW5IZWlnaHQuY29udmVydFRvUFgodGhpcy5hcHAud29ya3NwYWNlLmNvbnRhaW5lckVsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZWdpb25hbENvbnRhaW5lci5zZXRSZWdpb25QYXJzZWRTZXR0aW5ncyhzZXR0aW5ncyk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZihyZWdpb25hbENvbnRhaW5lciA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgZG9jTGluZXMgPSBkb2NTdHJpbmcuc3BsaXQoXCJcXG5cIik7XHJcbiAgICAgICAgbGV0IHJlbGF0aXZlVGV4dHM6IEVsZW1lbnRSZWxhdGl2ZUxvY2F0aW9uRGF0YSA9IGV4dHJhY3RFbGVtZW50UmVsYXRpdmVMb2NhdGlvbkRhdGEoZG9jTGluZXMsIGluZm8pO1xyXG4gICAgICAgIHJlbGF0aXZlVGV4dHMubGluZXNCZWxvd0FycmF5ID0gIG11bHRpQ29sdW1uUGFyc2VyLmdldEVuZEJsb2NrQmVsb3cocmVsYXRpdmVUZXh0cy5saW5lc0JlbG93QXJyYXkpO1xyXG5cclxuICAgICAgICBpZihtdWx0aUNvbHVtblBhcnNlci5jb250YWluc1N0YXJ0VGFnKHJlbGF0aXZlVGV4dHMudGV4dE9mRWxlbWVudCkgfHxcclxuICAgICAgICAgICBtdWx0aUNvbHVtblBhcnNlci5jb250YWluc0NvbFNldHRpbmdzVGFnKHJlbGF0aXZlVGV4dHMudGV4dE9mRWxlbWVudCkpIHtcclxuXHJcbiAgICAgICAgICAgIGlmKG11bHRpQ29sdW1uUGFyc2VyLmNvbnRhaW5zU3RhcnRUYWcocmVsYXRpdmVUZXh0cy50ZXh0T2ZFbGVtZW50KSkge1xyXG4gICAgICAgICAgICAgICAgc2V0RWxlbWVudENTU0J5VGFnKERPTU9iamVjdFRhZy5zdGFydFJlZ2lvbiwgZWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYobXVsdGlDb2x1bW5QYXJzZXIuY29udGFpbnNDb2xTZXR0aW5nc1RhZyhyZWxhdGl2ZVRleHRzLnRleHRPZkVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICBzZXRFbGVtZW50Q1NTQnlUYWcoRE9NT2JqZWN0VGFnLnJlZ2lvblNldHRpbmdzLCBlbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHN0YXJ0Qm9ja0Fib3ZlOiBtdWx0aUNvbHVtblBhcnNlci5TdGFydFRhZ0RhdGEgPSB7XHJcbiAgICAgICAgICAgIGxpbmVzQWJvdmVBcnJheTogcmVsYXRpdmVUZXh0cy5saW5lc0Fib3ZlQXJyYXksXHJcbiAgICAgICAgICAgIHN0YXJ0QmxvY2tLZXk6IFwiTXVsdGktQ29sdW1uIFJlZmxvdyBSZWdpb25cIixcclxuICAgICAgICAgICAgc3RhcnRCbG9ja1R5cGU6IFwiT1JJR0lOQUxcIlxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5hcHBlbmRUb1JlZ2lvbmFsTWFuYWdlcihlbCwgcmVnaW9uYWxDb250YWluZXIsIGN0eCwgcmVsYXRpdmVUZXh0cywgc291cmNlUGF0aCwgc3RhcnRCb2NrQWJvdmUsIChkb21PYmo6IERPTU9iamVjdCkgPT4ge1xyXG4gICAgICAgICAgICBvblVubG9hZEVsZW1lbnQoZG9tT2JqLCByZWdpb25hbENvbnRhaW5lcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8jcmVnaW9uIFBERiBFeHBvcnRpbmcuXHJcbiAgICBwcml2YXRlIGlzU3RhcnRDb2RlYmxvY2tJbkV4cG9ydChub2RlOiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xyXG5cclxuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgQ09ERUJMT0NLX1NUQVJUX1NUUlMubGVuZ3RoOyBpKyspIHtcclxuXHJcbiAgICAgICAgICAgIGlmKG5vZGUuaGFzQ2xhc3MoYGJsb2NrLWxhbmd1YWdlLSR7Q09ERUJMT0NLX1NUQVJUX1NUUlNbaV19YCkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIGV4cG9ydERvY3VtZW50VG9QREYoZWw6IEhUTUxFbGVtZW50LCBmaWxlRE9NTWFuYWdlcjogRmlsZURPTU1hbmFnZXIsIHNvdXJjZVBhdGg6IHN0cmluZykge1xyXG5cclxuICAgICAgICAvLyBBIHRydWUgZXhwb3J0IHdpbGwgYmUgcGFzc2VkIGFuIGVsZW1lbnQgd2l0aCBhbGwgb3RoZXIgaXRlbXMgaW4gdGhlIGRvYyBhcyBjaGlsZHJlbi4gXHJcbiAgICAgICAgLy8gU28gaWYgdGhlcmUgYXJlIG5vIGNoaWxkcmVuIHdlIGNhbiBqdXN0IHJldHVyblxyXG4gICAgICAgIGxldCBkb2NDaGlsZHJlbiA9IEFycmF5LmZyb20oZWwuY2hpbGROb2Rlcyk7XHJcbiAgICAgICAgaWYoZG9jQ2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBjaGlsZHJlblRvUmVtb3ZlID0gW107XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gVG8gZXhwb3J0IGNvZGVibG9ja3Mgd2UgbmVlZCB0byBnZXQgdGhlIElEcyBzbyB3ZSBjYW4gZ2V0IHRoZSBkYXRhIGZyb20gb3VyIG1hbmFnZXJzLlxyXG4gICAgICAgIC8vIGhvd2V2ZXIgc2luY2UgdGhlIElEIGlzbnQgYmVpbmcgc3RvcmVkIGluIHRoZSBlbGVtZW50IHlldCB0aGlzIG1lYW5zIHdlIG5lZWQgdG8gcmVhZFxyXG4gICAgICAgIC8vIGFsbCBvZiB0aGUgSURzIG91dCBvZiB0aGUgZnVsbCBkb2N1bWVudC5cclxuICAgICAgICBsZXQgY29kZWJsb2NrU3RhcnRCbG9ja3MgPSBbXVxyXG4gICAgICAgIGxldCBhRmlsZSA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChzb3VyY2VQYXRoKTtcclxuICAgICAgICBpZihhRmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblxyXG4gICAgICAgICAgICBsZXQgZmlsZSA9IGFGaWxlIGFzIFRGaWxlXHJcbiAgICAgICAgICAgIGxldCBmaWxlVGV4dCA9IGF3YWl0IHRoaXMuYXBwLnZhdWx0LmNhY2hlZFJlYWQoZmlsZSkgLy8gSXMgY2FjaGVkIHJlYWQgT2sgaGVyZT8gSXQgc2hvdWxkIGJlLlxyXG5cclxuICAgICAgICAgICAgLy8gT25jZSB3ZSBoYXZlIG91ciBkYXRhIHdlIHNlYXJjaCB0aGUgdGV4dCBmb3IgYWxsIGNvZGVibG9jayBzdGFydCB2YWx1ZXMuXHJcbiAgICAgICAgICAgIC8vIHN0b3JpbmcgdGhlbSBpbnRvIG91ciBxdWV1ZS5cclxuICAgICAgICAgICAgbGV0IGNvZGVCbG9ja0RhdGEgPSBtdWx0aUNvbHVtblBhcnNlci5maW5kU3RhcnRDb2RlYmxvY2soZmlsZVRleHQpO1xyXG4gICAgICAgICAgICB3aGlsZShjb2RlQmxvY2tEYXRhLmZvdW5kID09PSB0cnVlKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGNvZGVibG9ja1RleHQgPSBmaWxlVGV4dC5zbGljZShjb2RlQmxvY2tEYXRhLnN0YXJ0UG9zaXRpb24sIGNvZGVCbG9ja0RhdGEuZW5kUG9zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgZmlsZVRleHQgPSBmaWxlVGV4dC5zbGljZShjb2RlQmxvY2tEYXRhLmVuZFBvc2l0aW9uKTtcclxuICAgICAgICAgICAgICAgIGNvZGVibG9ja1N0YXJ0QmxvY2tzLnB1c2goY29kZWJsb2NrVGV4dCk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29kZUJsb2NrRGF0YSA9IG11bHRpQ29sdW1uUGFyc2VyLmZpbmRTdGFydENvZGVibG9jayhmaWxlVGV4dCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGdldHRpbmcgZmlsZSBmcm9tIHNvdXJjZSBwYXRoOiAke3NvdXJjZVBhdGh9YClcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBpbkJsb2NrID0gZmFsc2U7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkb2NDaGlsZHJlbi5sZW5ndGg7IGkrKykge1xyXG5cclxuICAgICAgICAgICAgbGV0IGNoaWxkID0gZG9jQ2hpbGRyZW5baV07XHJcbiAgICAgICAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgY2hpbGRFbCA9IGNoaWxkIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgaWYgKGluQmxvY2sgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGZvdW5kQmxvY2tEYXRhID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlZ2lvbktleSA9IFwiXCI7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBibG9ja0RhdGEgPSBtdWx0aUNvbHVtblBhcnNlci5pc1N0YXJ0VGFnV2l0aElEKGNoaWxkLnRleHRDb250ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcGFuZG9jRGF0YSA9IGNvbnRhaW5zUGFuZG9jLmdldFBhbmRvY1N0YXJ0RGF0YShjaGlsZC50ZXh0Q29udGVudClcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tEYXRhLmlzU3RhcnRUYWcgPT09IHRydWUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIGFuIG9sZC1zdHlsZSBzdGFydCB0YWcuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kQmxvY2tEYXRhID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrRGF0YS5oYXNLZXkgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmb3VuZEtleSA9IG11bHRpQ29sdW1uUGFyc2VyLmdldFN0YXJ0VGFnS2V5KGNoaWxkLnRleHRDb250ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZEtleSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbktleSA9IGZvdW5kS2V5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoYmxvY2tEYXRhLmlzU3RhcnRUYWcgPT09IGZhbHNlICYmIHRoaXMuaXNTdGFydENvZGVibG9ja0luRXhwb3J0KGNoaWxkKSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHN0YXJ0IHRhZyBmcm9tIHRoZSBvbGQgdmVyc2lvbiBpcyBudWxsIHdlIHRoZW4gY2hlY2sgdG8gc2VlIGlmIHRoZSBlbGVtZW50IGlzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgY29kZWJsb2NrIHN0YXJ0LiBJZiBpdCBpcyB3ZSB1c2UgdGhlIG5leHQgYXZhaWxhYmxlIGNvZGVibG9jayBkYXRhIHRvIHJldHJpZXZlIG91ciBJRC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvZGVibG9ja1RleHQgPSBjb2RlYmxvY2tTdGFydEJsb2Nrcy5zaGlmdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihjb2RlYmxvY2tUZXh0ID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJGb3VuZCB1bmRlZmluZWQgY29kZWJsb2NrIGRhdGEgd2hlbiBleHBvcnRpbmcuXCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpZCA9IHBhcnNlU3RhcnRSZWdpb25Db2RlQmxvY2tJRChjb2RlYmxvY2tUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoaWQgIT09IFwiXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kQmxvY2tEYXRhID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbktleSA9IGlkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYocGFuZG9jRGF0YS5mb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3VuZEJsb2NrRGF0YSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbktleSA9IHBhbmRvY0RhdGEudXNlclNldHRpbmdzLmNvbHVtbklEO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYoZm91bmRCbG9ja0RhdGEgPT09IHRydWUgJiYgcmVnaW9uS2V5ICE9PSBcIlwiKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbkJsb2NrID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBjaGlsZC5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuY2hpbGRyZW5baV0uZGV0YWNoKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuaW5uZXJUZXh0ID0gXCJcIjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLmNsYXNzTGlzdC5hZGQoTXVsdGlDb2x1bW5MYXlvdXRDU1MuUmVnaW9uUm9vdENvbnRhaW5lckRpdik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXJyb3JNYW5hZ2VyID0gbmV3IFJlZ2lvbkVycm9yTWFuYWdlcihlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZW5kZXJDb2x1bW5SZWdpb24gPSBjaGlsZC5jcmVhdGVEaXYoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xzOiBNdWx0aUNvbHVtbkxheW91dENTUy5SZWdpb25Db250ZW50Q29udGFpbmVyRGl2XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZWdpb25hbENvbnRhaW5lcjogUmVnaW9uTWFuYWdlckNvbnRhaW5lciA9IGZpbGVET01NYW5hZ2VyLmdldFJlZ2lvbmFsQ29udGFpbmVyKHJlZ2lvbktleSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWdpb25hbENvbnRhaW5lciA9PT0gbnVsbCB8fCByZWdpb25hbENvbnRhaW5lci5nZXRSZWdpb24oKS5udW1iZXJPZkNoaWxkcmVuID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbnVtYmVyIG9mIGNoaWxkcmVuIGlzIDAsIHdlIGFyZSBwcm9iYWJseSBpbiBMaXZlUHJldmlldywgd2hlcmUgdGhlIGNvZGVibG9jayBzdGFydCByZWdpb25zIGhhdmUgYmVlbiBwcm9jZXNzZWQgYnkgbmF0aXZlIG9ic2lkaWFuIGxpdmUgcHJldmlldyBidXQgZG8gbm90IGhhdmUgYW55IGNoaWxkcmVuIGxpbmtlZCB0byB0aGVtLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNYW5hZ2VyLmFkZEVycm9yTWVzc2FnZShcIkVycm9yIHJlbmRlcmluZyBtdWx0aS1jb2x1bW4gcmVnaW9uLlxcblBsZWFzZSBjbG9zZSBhbmQgcmVvcGVuIHRoZSBmaWxlLCB0aGVuIG1ha2Ugc3VyZSB5b3UgYXJlIGluIHJlYWRpbmcgbW9kZSBiZWZvcmUgZXhwb3J0aW5nLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZWdpb25hbE1hbmFnZXI6IFJlZ2lvbk1hbmFnZXIgPSByZWdpb25hbENvbnRhaW5lci5nZXRSZWdpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbmFsTWFuYWdlci5leHBvcnRSZWdpb25FbGVtZW50c1RvUERGKHJlbmRlckNvbHVtblJlZ2lvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG11bHRpQ29sdW1uUGFyc2VyLmNvbnRhaW5zRW5kVGFnKGNoaWxkLnRleHRDb250ZW50KSA9PT0gdHJ1ZSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250YWluc1BhbmRvYy5jb250YWluc1BhbmRvY0VuZFRhZyhjaGlsZC50ZXh0Q29udGVudCkgPT09IHRydWUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluQmxvY2sgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuVG9SZW1vdmUucHVzaChjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNoaWxkcmVuVG9SZW1vdmUuZm9yRWFjaChjaGlsZCA9PiB7XHJcbiAgICAgICAgICAgIGlmKGNoaWxkLnBhcmVudEVsZW1lbnQgPT09IGVsKSB7XHJcbiAgICAgICAgICAgICAgICBlbC5yZW1vdmVDaGlsZChjaGlsZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjaGVja0V4cG9ydGluZyhlbGVtZW50OiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xyXG5cclxuICAgICAgICBpZihlbGVtZW50ID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKFwicHJpbnRcIikpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZihlbGVtZW50LnBhcmVudE5vZGUgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2hlY2tFeHBvcnRpbmcoZWxlbWVudC5wYXJlbnRFbGVtZW50KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIC8vI2VuZHJlZ2lvbiBQREYgRXhwb3J0aW5nLlxyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRFbGVtZW50Q1NTKGN1cnJlbnRPYmplY3Q6IERPTU9iamVjdCwgZWw6IEhUTUxFbGVtZW50KSB7XHJcbiAgICBzZXRFbGVtZW50Q1NTQnlUYWcoY3VycmVudE9iamVjdC50YWcsIGVsKTtcclxufVxyXG5mdW5jdGlvbiBzZXRFbGVtZW50Q1NTQnlUYWcodGFnOiBET01PYmplY3RUYWcsIGVsOiBIVE1MRWxlbWVudCkge1xyXG4gICAgaWYgKHRhZyA9PT0gRE9NT2JqZWN0VGFnLmVuZFJlZ2lvbikge1xyXG4gICAgICAgIGVsLmFkZENsYXNzKE11bHRpQ29sdW1uU3R5bGVDU1MuUmVnaW9uRW5kVGFnKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHRhZyA9PT0gRE9NT2JqZWN0VGFnLmNvbHVtbkJyZWFrKSB7XHJcbiAgICAgICAgZWwuYWRkQ2xhc3MoTXVsdGlDb2x1bW5TdHlsZUNTUy5Db2x1bW5FbmRUYWcpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAodGFnID09PSBET01PYmplY3RUYWcucmVnaW9uU2V0dGluZ3MpIHtcclxuICAgICAgICBlbC5hZGRDbGFzcyhNdWx0aUNvbHVtblN0eWxlQ1NTLlJlZ2lvblNldHRpbmdzKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGVsLmFkZENsYXNzKE11bHRpQ29sdW1uU3R5bGVDU1MuUmVnaW9uQ29udGVudCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uVW5sb2FkRWxlbWVudChjdXJyZW50T2JqZWN0OiBET01PYmplY3QsIHJlZ2lvbmFsQ29udGFpbmVyOiBSZWdpb25NYW5hZ2VyQ29udGFpbmVyKTogdm9pZCB7XHJcblxyXG4gICAgaWYgKHJlZ2lvbmFsQ29udGFpbmVyID09PSBudWxsKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCByZWdpb25hbE1hbmFnZXI6IFJlZ2lvbk1hbmFnZXIgPSByZWdpb25hbENvbnRhaW5lci5nZXRSZWdpb24oKTtcclxuICAgIGlmIChyZWdpb25hbE1hbmFnZXIpIHtcclxuXHJcbiAgICAgICAgLy8gV2UgY2FuIGF0dGVtcHQgdG8gdXBkYXRlIHRoZSB2aWV3IGhlcmUgYWZ0ZXIgdGhlIGl0ZW0gaXMgcmVtb3ZlZFxyXG4gICAgICAgIC8vIGJ1dCBuZWVkIHRvIGdldCB0aGUgaXRlbSdzIHBhcmVudCBlbGVtZW50IGJlZm9yZSByZW1vdmluZyBvYmplY3QgZnJvbSBtYW5hZ2VyLlxyXG4gICAgICAgIGxldCByZWdpb25SZW5kZXJEYXRhOiBNdWx0aUNvbHVtblJlbmRlckRhdGEgPSByZWdpb25hbE1hbmFnZXIuZ2V0UmVnaW9uUmVuZGVyRGF0YSgpO1xyXG5cclxuICAgICAgICByZWdpb25hbE1hbmFnZXIucmVtb3ZlT2JqZWN0KGN1cnJlbnRPYmplY3QuVUlEKTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTmVlZCB0byBjaGVjayBoZXJlIGlmIGVsZW1lbnQgaXMgbnVsbCBhcyB0aGlzIGNsb3N1cmUgd2lsbCBiZSBjYWxsZWRcclxuICAgICAgICAgKiByZXBlYXRlZGx5IG9uIGZpbGUgY2hhbmdlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGlmIChyZWdpb25SZW5kZXJEYXRhLnBhcmVudFJlbmRlckVsZW1lbnQgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZWdpb25hbE1hbmFnZXIucmVuZGVyUmVnaW9uRWxlbWVudHNUb1NjcmVlbigpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuaW50ZXJmYWNlIEVsZW1lbnRSZWxhdGl2ZUxvY2F0aW9uRGF0YSB7XHJcbiAgICBsaW5lc0Fib3ZlQXJyYXk6IHN0cmluZ1tdO1xyXG4gICAgbGluZXNPZkVsZW1lbnQ6IHN0cmluZ1tdO1xyXG4gICAgbGluZXNCZWxvd0FycmF5OiBzdHJpbmdbXTtcclxuICAgIHRleHRPZkVsZW1lbnQ6IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IHR5cGUgbmVhcmJ5U2libGluZ3MgPSB7IFxyXG4gICAgc2libGluZ3NBYm92ZTogSFRNTERpdkVsZW1lbnQsXHJcbiAgICBjdXJyZW50T2JqZWN0OiBET01PYmplY3QsIFxyXG59XHJcblxyXG5mdW5jdGlvbiBleHRyYWN0RWxlbWVudFJlbGF0aXZlTG9jYXRpb25EYXRhKGRvY0xpbmVzOiBzdHJpbmdbXSwgaW5mbzogTWFya2Rvd25TZWN0aW9uSW5mb3JtYXRpb24pOiBFbGVtZW50UmVsYXRpdmVMb2NhdGlvbkRhdGEge1xyXG5cclxuICAgIGxldCBsaW5lc0Fib3ZlQXJyYXkgPSBkb2NMaW5lcy5zbGljZSgwLCBpbmZvLmxpbmVTdGFydCk7XHJcbiAgICBsZXQgbGluZXNPZkVsZW1lbnQgPSBkb2NMaW5lcy5zbGljZShpbmZvLmxpbmVTdGFydCwgaW5mby5saW5lRW5kICsgMSk7XHJcbiAgICBsZXQgdGV4dE9mRWxlbWVudCA9IGxpbmVzT2ZFbGVtZW50LmpvaW4oXCJcXG5cIik7XHJcbiAgICBsZXQgbGluZXNCZWxvd0FycmF5ID0gZG9jTGluZXMuc2xpY2UoaW5mby5saW5lRW5kICsgMSk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBsaW5lc0Fib3ZlQXJyYXksXHJcbiAgICAgICAgbGluZXNPZkVsZW1lbnQsXHJcbiAgICAgICAgbGluZXNCZWxvd0FycmF5LFxyXG4gICAgICAgIHRleHRPZkVsZW1lbnRcclxuICAgIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVN0YXJ0RWxlbWVudChlbDogSFRNTEVsZW1lbnQsIGxpbmVzT2ZFbGVtZW50OiBzdHJpbmdbXSwgY3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LCBmaWxlRE9NTWFuYWdlcjogRmlsZURPTU1hbmFnZXIsIGRvY1N0cmluZzogc3RyaW5nKSB7XHJcblxyXG4gICAgZWwuY2hpbGRyZW5bMF0uZGV0YWNoKCk7XHJcblxyXG4gICAgbGV0IHN0YXJ0QmxvY2tEYXRhID0gbXVsdGlDb2x1bW5QYXJzZXIuZ2V0U3RhcnRCbG9ja0Fib3ZlTGluZShsaW5lc09mRWxlbWVudClcclxuICAgIGlmKHN0YXJ0QmxvY2tEYXRhID09PSBudWxsKSB7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCByZWdpb25JRCA9IHN0YXJ0QmxvY2tEYXRhLnN0YXJ0QmxvY2tLZXk7XHJcblxyXG4gICAgc2V0dXBTdGFydFRhZyhlbCwgY3R4LCBmaWxlRE9NTWFuYWdlciwgZG9jU3RyaW5nLCByZWdpb25JRCk7XHJcbiAgICByZXR1cm47XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVBhbmRvY1N0YXJ0RWxlbWVudChlbDogSFRNTEVsZW1lbnQsIHRleHRPZkVsZW1lbnQ6IHN0cmluZywgY3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0LCBmaWxlRE9NTWFuYWdlcjogRmlsZURPTU1hbmFnZXIsIGRvY1N0cmluZzogc3RyaW5nKSB7XHJcbiAgICBlbC5jaGlsZHJlblswXS5kZXRhY2goKTtcclxuXHJcbiAgICBsZXQgcGFuZG9jRGF0YSA9IGNvbnRhaW5zUGFuZG9jLmdldFBhbmRvY1N0YXJ0RGF0YSh0ZXh0T2ZFbGVtZW50KTtcclxuICAgIGxldCBzZXR0aW5ncyA9IHBhbmRvY0RhdGEudXNlclNldHRpbmdzO1xyXG5cclxuICAgIGxldCByZWdpb25NYW5hZ2VyID0gc2V0dXBTdGFydFRhZyhlbCwgY3R4LCBmaWxlRE9NTWFuYWdlciwgZG9jU3RyaW5nLCBzZXR0aW5ncy5jb2x1bW5JRCk7XHJcbiAgICByZWdpb25NYW5hZ2VyLnNldFJlZ2lvbmFsU2V0dGluZ3Moc2V0dGluZ3MpO1xyXG4gICAgcmV0dXJuO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZW5kZXJNYXJrZG93bkZyb21MaW5lcyhtZExpbmVzOiBzdHJpbmdbXSwgc291cmNlUGF0aDogc3RyaW5nKTogSFRNTERpdkVsZW1lbnQge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2UgcmUtcmVuZGVyIGFsbCBvZiB0aGUgaXRlbXMgYWJvdmUgb3VyIGVsZW1lbnQsIHVudGlsIHRoZSBzdGFydCB0YWcsIFxyXG4gICAgICogc28gd2UgY2FuIGRldGVybWluZSB3aGVyZSB0byBwbGFjZSB0aGUgbmV3IGl0ZW0gaW4gdGhlIG1hbmFnZXIuXHJcbiAgICAgKiBcclxuICAgICAqIFRPRE86IENhbiByZWR1Y2UgdGhlIGFtb3VudCBuZWVkaW5nIHRvIGJlIHJlbmRlcmVkIGJ5IG9ubHkgcmVuZGVyaW5nIHRvXHJcbiAgICAgKiB0aGUgc3RhcnQgdGFnIG9yIGEgY29sdW1uLWJyZWFrIHdoaWNoZXZlciBpcyBjbG9zZXIuXHJcbiAgICAgKi9cclxuICAgIGxldCBzaWJsaW5ncyA9IGNyZWF0ZURpdigpO1xyXG4gICAgbGV0IG1hcmtkb3duUmVuZGVyQ2hpbGQgPSBuZXcgTWFya2Rvd25SZW5kZXJDaGlsZChcclxuICAgICAgICBzaWJsaW5nc1xyXG4gICAgKTtcclxuICAgIE1hcmtkb3duUmVuZGVyZXIucmVuZGVyTWFya2Rvd24oXHJcbiAgICAgICAgbWRMaW5lcy5yZWR1Y2UoKHByZXYsIGN1cnJlbnQpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHByZXYgKyBcIlxcblwiICArIGN1cnJlbnQ7XHJcbiAgICAgICAgfSwgXCJcIiksXHJcbiAgICAgICAgc2libGluZ3MsXHJcbiAgICAgICAgc291cmNlUGF0aCxcclxuICAgICAgICBtYXJrZG93blJlbmRlckNoaWxkXHJcbiAgICApO1xyXG5cclxuICAgIHJldHVybiBzaWJsaW5ncztcclxufVxyXG5cclxuZnVuY3Rpb24gc2V0dXBTdGFydFRhZyhlbDogSFRNTEVsZW1lbnQsIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgZmlsZURPTU1hbmFnZXI6IEZpbGVET01NYW5hZ2VyLCBkb2NTdHJpbmc6IHN0cmluZywgcmVnaW9uSUQ6IHN0cmluZykge1xyXG4gICAgLyoqIFxyXG4gICAgICogU2V0IHVwIHRoZSBjdXJyZW50IGVsZW1lbnQgdG8gYWN0IGFzIHRoZSBwYXJlbnQgZm9yIHRoZSBcclxuICAgICAqIG11bHRpLWNvbHVtbiByZWdpb24uXHJcbiAgICAgKi9cclxuICAgIGVsLmNsYXNzTGlzdC5hZGQoTXVsdGlDb2x1bW5MYXlvdXRDU1MuUmVnaW9uUm9vdENvbnRhaW5lckRpdilcclxuXHJcbiAgICBsZXQgZXJyb3JNYW5hZ2VyID0gbmV3IFJlZ2lvbkVycm9yTWFuYWdlcihlbCk7XHJcbiAgICBsZXQgcmVuZGVyQ29sdW1uUmVnaW9uID0gZWwuY3JlYXRlRGl2KHtcclxuICAgICAgICBjbHM6IE11bHRpQ29sdW1uTGF5b3V0Q1NTLlJlZ2lvbkNvbnRlbnRDb250YWluZXJEaXZcclxuICAgIH0pXHJcblxyXG4gICAgaWYoZmlsZURPTU1hbmFnZXIuY2hlY2tLZXlFeGlzdHMocmVnaW9uSUQpID09PSB0cnVlKSB7XHJcblxyXG4gICAgICAgIGxldCB7IG51bWJlck9mVGFncywga2V5cyB9ID0gbXVsdGlDb2x1bW5QYXJzZXIuY291bnRTdGFydFRhZ3MoZG9jU3RyaW5nKTtcclxuXHJcbiAgICAgICAgbGV0IG51bU1hdGNoZXMgPSAwO1xyXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBudW1iZXJPZlRhZ3M7IGkrKykge1xyXG5cclxuICAgICAgICAgICAgLy8gQmVjYXVzZSB3ZSBjaGVja2VkIGlmIGtleSBleGlzdHMgb25lIG9mIHRoZXNlIGhhcyB0byBtYXRjaC5cclxuICAgICAgICAgICAgaWYoa2V5c1tpXSA9PT0gcmVnaW9uSUQpIHtcclxuICAgICAgICAgICAgICAgIG51bU1hdGNoZXMrKztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gV2Ugb25seSB3YW50IHRvIGRpc3BsYXkgYW4gZXJyb3IgaWYgdGhlcmUgYXJlIG1vcmUgdGhhbiAyIG9mIHRoZSBzYW1lIGlkIGFjcm9zc1xyXG4gICAgICAgIC8vIHRoZSB3aG9sZSBkb2N1bWVudC4gVGhpcyBwcmV2ZW50cyBlcnJvcyB3aGVuIG9ic2lkaWFuIHJlbG9hZHMgdGhlIHdob2xlIGRvY3VtZW50XHJcbiAgICAgICAgLy8gYW5kIHRoZXJlIGFyZSB0d28gb2YgdGhlIHNhbWUga2V5IGluIHRoZSBtYXAuXHJcbiAgICAgICAgaWYobnVtTWF0Y2hlcyA+PSAyKSB7XHJcbiAgICAgICAgICAgIGlmKHJlZ2lvbklEID09PSBcIlwiKSB7XHJcbiAgICAgICAgICAgICAgICBlcnJvck1hbmFnZXIuYWRkRXJyb3JNZXNzYWdlKFwiRm91bmQgbXVsdGlwbGUgcmVnaW9ucyB3aXRoIGVtcHR5IElEcy4gUGxlYXNlIHNldCBhIHVuaXF1ZSBJRCBhZnRlciBlYWNoIHN0YXJ0IHRhZy5cXG5FRzogJy0tLSBtdWx0aS1jb2x1bW4tc3RhcnQ6IHJhbmRvbUlEJ1xcbk9yIHVzZSAnRml4IE1pc3NpbmcgSURzJyBpbiB0aGUgY29tbWFuZCBwYWxldHRlIGFuZCByZWxvYWQgdGhlIGRvY3VtZW50LlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGVycm9yTWFuYWdlci5hZGRFcnJvck1lc3NhZ2UoXCJSZWdpb24gSUQgYWxyZWFkeSBleGlzdHMgaW4gZG9jdW1lbnQsIHBsZWFzZSBzZXQgYSB1bmlxdWUgSUQuXFxuRUc6ICctLS0gbXVsdGktY29sdW1uLXN0YXJ0OiByYW5kb21JRCdcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsLmlkID0gYE11bHRpQ29sdW1uSUQ6JHtyZWdpb25JRH1gXHJcblxyXG4gICAgbGV0IGVsZW1lbnRNYXJrZG93blJlbmRlcmVyID0gbmV3IE1hcmtkb3duUmVuZGVyQ2hpbGQoZWwpO1xyXG4gICAgbGV0IHJlZ2lvbk1hbmFnZXIgPSBmaWxlRE9NTWFuYWdlci5jcmVhdGVSZWdpb25hbE1hbmFnZXIocmVnaW9uSUQsIGVsLCBlcnJvck1hbmFnZXIsIHJlbmRlckNvbHVtblJlZ2lvbik7XHJcbiAgICBlbGVtZW50TWFya2Rvd25SZW5kZXJlci5vbnVubG9hZCA9ICgpID0+IHtcclxuICAgICAgICBpZihmaWxlRE9NTWFuYWdlcikge1xyXG5cclxuICAgICAgICAgICAgZmlsZURPTU1hbmFnZXIucmVtb3ZlUmVnaW9uKHJlZ2lvbklEKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgY3R4LmFkZENoaWxkKGVsZW1lbnRNYXJrZG93blJlbmRlcmVyKTtcclxuXHJcbiAgICByZXR1cm4gcmVnaW9uTWFuYWdlclxyXG59XHJcblxyXG5jb25zdCBGUk9OVE1BVFRFUl9SRUdFWDogUmVnRXhwW10gPVxyXG5bXHJcbi9NdWx0aVstIF0qQ29sdW1uICpNYXJrZG93bi9pLFxyXG4vTXVsdGlbLSBdKkNvbHVtbiAqUmVmbG93L2lcclxuXVxyXG5mdW5jdGlvbiBpc011bHRpQ29sdW1uUmVmbG93KGZyb250bWF0dGVyOiBhbnkpOiBib29sZWFuIHtcclxuXHJcbiAgICBpZihmcm9udG1hdHRlciA9PT0gbnVsbCB8fFxyXG4gICAgICAgZnJvbnRtYXR0ZXIgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBmb3IobGV0IHJlZ2V4IG9mIEZST05UTUFUVEVSX1JFR0VYKSB7XHJcblxyXG4gICAgICAgIGxldCBmcm9udG1hdHRlclJlZmxvd0RhdGEgPSBwYXJzZUZyb250TWF0dGVyRW50cnkoZnJvbnRtYXR0ZXIsIHJlZ2V4KTtcclxuICAgICAgICBpZihmcm9udG1hdHRlclJlZmxvd0RhdGEgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGxldCBba2V5cywgdmFsdWVzXSA9IE9iamVjdC5lbnRyaWVzKGZyb250bWF0dGVyKTtcclxuICAgIGlmKGtleXMgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBmb3IobGV0IGtleSBvZiBrZXlzKSB7XHJcblxyXG4gICAgICAgIGlmKHR5cGVvZiBrZXkgIT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IobGV0IHJlZ2V4IG9mIEZST05UTUFUVEVSX1JFR0VYKSB7XHJcblxyXG4gICAgICAgICAgICBsZXQgcmVnZXhSZXN1bHQgPSByZWdleC5leGVjKGtleSk7XHJcbiAgICAgICAgICAgIGlmKHJlZ2V4UmVzdWx0ICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldE11bHRpQ29sdW1uU2V0dGluZ3NGcm9tRnJvbnRtYXR0ZXIoY3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0KTogTXVsdGlDb2x1bW5TZXR0aW5ncyB7XHJcblxyXG4gICAgbGV0IHNldHRpbmdzID0gZ2V0RGVmYXVsdE11bHRpQ29sdW1uU2V0dGluZ3MoKTtcclxuICAgIHNldHRpbmdzLmZ1bGxEb2NSZWZsb3cgPSB0cnVlO1xyXG4gICAgaWYoY3R4LmZyb250bWF0dGVyID09PSBudWxsIHx8XHJcbiAgICAgICBjdHguZnJvbnRtYXR0ZXIgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiBzZXR0aW5ncztcclxuICAgIH1cclxuXHJcbiAgICBmb3IobGV0IHJlZ2V4IG9mIEZST05UTUFUVEVSX1JFR0VYKSB7XHJcblxyXG4gICAgICAgIGxldCBmcm9udG1hdHRlclJlZmxvd0RhdGEgPSBwYXJzZUZyb250TWF0dGVyRW50cnkoY3R4LmZyb250bWF0dGVyLCByZWdleCk7XHJcbiAgICAgICAgaWYoZnJvbnRtYXR0ZXJSZWZsb3dEYXRhICE9PSBudWxsICYmXHJcbiAgICAgICAgICAgQXJyYXkuaXNBcnJheShmcm9udG1hdHRlclJlZmxvd0RhdGEpKSB7XHJcbiAgICAgICAgICAgIHNldHRpbmdzID0gcGFyc2VGcm9udG1hdHRlclNldHRpbmdzKGZyb250bWF0dGVyUmVmbG93RGF0YSk7XHJcbiAgICAgICAgICAgIHNldHRpbmdzLmZ1bGxEb2NSZWZsb3cgPSB0cnVlO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHNldHRpbmdzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBwYXJzZUZyb250bWF0dGVyU2V0dGluZ3MoZnJvbnRtYXR0ZXJSZWZsb3dEYXRhOiBhbnlbXSk6IE11bHRpQ29sdW1uU2V0dGluZ3Mge1xyXG5cclxuICAgIGxldCBzdHIgPSBcIlwiO1xyXG4gICAgZm9yKGxldCBvYmogb2YgZnJvbnRtYXR0ZXJSZWZsb3dEYXRhKSB7XHJcblxyXG4gICAgICAgIGxldCBba2V5LCB2YWx1ZV0gPSBPYmplY3QuZW50cmllcyhvYmopWzBdO1xyXG4gICAgICAgIHN0ciArPSBgJHtrZXl9OiBbJHt2YWx1ZX1dXFxuYDtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgc2V0dGluZ3MgPSBwYXJzZUNvbHVtblNldHRpbmdzKHN0cik7XHJcblxyXG4gICAgcmV0dXJuIHNldHRpbmdzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRDb250ZW50SGVpZ2h0RnJvbUxlYWYobGVhZjogV29ya3NwYWNlTGVhZik6IG51bWJlciB7XHJcblxyXG4gICAgbGV0IGNvbnRlbnRFbCA9IChsZWFmLnZpZXcgYXMgYW55KVtcImNvbnRlbnRFbFwiXSBhcyBIVE1MRWxlbWVudFxyXG4gICAgaWYoY29udGVudEVsICE9PSB1bmRlZmluZWQgJiZcclxuICAgICAgIGNvbnRlbnRFbC5jbGllbnRIZWlnaHQgPiAwKSB7XHJcbiAgICAgICAgcmV0dXJuIGNvbnRlbnRFbC5jbGllbnRIZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGNsaWVudEhlaWdodCA9IGxlYWYudmlldy5jb250YWluZXJFbC5jbGllbnRIZWlnaHQ7XHJcbiAgICBsZXQgdGl0bGVDb250YWluZXIgPSAobGVhZi52aWV3IGFzIGFueSlbXCJ0aXRsZUNvbnRhaW5lckVsXCJdIGFzIEhUTUxFbGVtZW50IFxyXG4gICAgaWYodGl0bGVDb250YWluZXIgIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICAgdGl0bGVDb250YWluZXIuY2xpZW50SGVpZ2h0ID4gMCkge1xyXG4gICAgICAgIHJldHVybiBjbGllbnRIZWlnaHQgLSB0aXRsZUNvbnRhaW5lci5jbGllbnRIZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGNsaWVudEhlaWdodCAtIDUwO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjYWxjVmlzaWJsZUNsaWV0SGVpZ2h0KGxlYWY6IFdvcmtzcGFjZUxlYWYsIHdvcmtzcGFjZTogV29ya3NwYWNlKTogbnVtYmVyIHtcclxuXHJcbiAgICBsZXQgY2xpZW50SGVpZ2h0ID0gMDtcclxuICAgIGlmIChsZWFmKSB7XHJcbiAgICAgICAgY2xpZW50SGVpZ2h0ID0gZ2V0Q29udGVudEhlaWdodEZyb21MZWFmKGxlYWYpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoKHdvcmtzcGFjZSAhPT0gbnVsbCAmJiB3b3Jrc3BhY2UgIT09IHVuZGVmaW5lZCkgJiZcclxuICAgICAgICAgICAgICh3b3Jrc3BhY2UuY29udGFpbmVyRWwgIT09IG51bGwgJiYgd29ya3NwYWNlLmNvbnRhaW5lckVsICE9PSB1bmRlZmluZWQpICYmXHJcbiAgICAgICAgICAgICAgd29ya3NwYWNlLmNvbnRhaW5lckVsLmNsaWVudEhlaWdodCA+IDApIHtcclxuICAgICAgICBjbGllbnRIZWlnaHQgPSB3b3Jrc3BhY2UuY29udGFpbmVyRWwuY2xpZW50SGVpZ2h0IC0gMTAwO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgY2xpZW50SGVpZ2h0ID0gMTAwMDtcclxuICAgIH1cclxuICAgIHJldHVybiBjbGllbnRIZWlnaHQ7XHJcbn0iXSwibmFtZXMiOlsiTWFya2Rvd25SZW5kZXJDaGlsZCIsIldpZGdldFR5cGUiLCJNYXJrZG93blJlbmRlcmVyIiwiU3RhdGVGaWVsZCIsIkRlY29yYXRpb24iLCJSYW5nZVNldEJ1aWxkZXIiLCJlZGl0b3JMaXZlUHJldmlld0ZpZWxkIiwic3ludGF4VHJlZSIsInRva2VuQ2xhc3NOb2RlUHJvcCIsImVkaXRvckluZm9GaWVsZCIsIkVkaXRvclZpZXciLCJQbHVnaW5TZXR0aW5nVGFiIiwiU2V0dGluZyIsIlBsYXRmb3JtIiwiTW9kYWwiLCJCdXR0b25Db21wb25lbnQiLCJtdWx0aUNvbHVtblBhcnNlci5pc1N0YXJ0VGFnV2l0aElEIiwiTm90aWNlIiwiUGx1Z2luIiwibXVsdGlDb2x1bW5QYXJzZXIuZmluZFN0YXJ0Q29kZWJsb2NrIiwibXVsdGlDb2x1bW5QYXJzZXIuY29udGFpbnNSZWdpb25TdGFydCIsIm11bHRpQ29sdW1uUGFyc2VyLmNvbnRhaW5zU3RhcnRUYWciLCJjb250YWluc1BhbmRvYy5jb250YWluc1BhbmRvY1N0YXJ0VGFnIiwibXVsdGlDb2x1bW5QYXJzZXIuZ2V0U3RhcnREYXRhQWJvdmVMaW5lIiwibXVsdGlDb2x1bW5QYXJzZXIuZ2V0RW5kQmxvY2tCZWxvdyIsIm11bHRpQ29sdW1uUGFyc2VyLmNvbnRhaW5zRW5kVGFnIiwiY29udGFpbnNQYW5kb2MuaXNWYWxpZFBhbmRvY0VuZFRhZyIsIm11bHRpQ29sdW1uUGFyc2VyLmNvbnRhaW5zQ29sRW5kVGFnIiwibXVsdGlDb2x1bW5QYXJzZXIuY29udGFpbnNDb2xTZXR0aW5nc1RhZyIsIm11bHRpQ29sdW1uUGFyc2VyLmNvdW50U3RhcnRUYWdzIiwiVEZpbGUiLCJjb250YWluc1BhbmRvYy5nZXRQYW5kb2NTdGFydERhdGEiLCJtdWx0aUNvbHVtblBhcnNlci5nZXRTdGFydFRhZ0tleSIsImNvbnRhaW5zUGFuZG9jLmNvbnRhaW5zUGFuZG9jRW5kVGFnIiwibXVsdGlDb2x1bW5QYXJzZXIuZ2V0U3RhcnRCbG9ja0Fib3ZlTGluZSIsInBhcnNlRnJvbnRNYXR0ZXJFbnRyeSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQW9HQTtBQUNPLFNBQVMsU0FBUyxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRTtBQUM3RCxJQUFJLFNBQVMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLE9BQU8sS0FBSyxZQUFZLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsVUFBVSxPQUFPLEVBQUUsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNoSCxJQUFJLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLE9BQU8sQ0FBQyxFQUFFLFVBQVUsT0FBTyxFQUFFLE1BQU0sRUFBRTtBQUMvRCxRQUFRLFNBQVMsU0FBUyxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDbkcsUUFBUSxTQUFTLFFBQVEsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDdEcsUUFBUSxTQUFTLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLEVBQUU7QUFDdEgsUUFBUSxJQUFJLENBQUMsQ0FBQyxT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VCxTQUFTLENBQUUsVUFBVSxDQUFDLEVBQUU7QUFDaEYsUUFBQSxPQUFPLEtBQUssQ0FBQTtBQUNmLEtBQUE7QUFDRCxJQUFBLElBQUcsQ0FBQSxTQUFTLEtBQUEsSUFBQSxJQUFULFNBQVMsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBVCxTQUFTLENBQUUsVUFBVSxPQUFLLFNBQVMsYUFBVCxTQUFTLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQVQsU0FBUyxDQUFFLFVBQVUsQ0FBQSxFQUFFO0FBQ2hELFFBQUEsT0FBTyxLQUFLLENBQUE7QUFDZixLQUFBO0FBQ0QsSUFBQSxJQUFHLENBQUEsU0FBUyxLQUFBLElBQUEsSUFBVCxTQUFTLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQVQsU0FBUyxDQUFFLFVBQVUsT0FBSyxTQUFTLGFBQVQsU0FBUyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFULFNBQVMsQ0FBRSxVQUFVLENBQUEsRUFBRTtBQUNoRCxRQUFBLE9BQU8sS0FBSyxDQUFBO0FBQ2YsS0FBQTtJQUNELElBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLGFBQVQsU0FBUyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFULFNBQVMsQ0FBRSxVQUFVLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsS0FBQSxJQUFBLElBQVQsU0FBUyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFULFNBQVMsQ0FBRSxVQUFVLENBQUMsRUFBRTtBQUNoRixRQUFBLE9BQU8sS0FBSyxDQUFBO0FBQ2YsS0FBQTtBQUNELElBQUEsSUFBRyxDQUFBLFNBQVMsS0FBQSxJQUFBLElBQVQsU0FBUyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFULFNBQVMsQ0FBRSxjQUFjLE9BQUssU0FBUyxhQUFULFNBQVMsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBVCxTQUFTLENBQUUsY0FBYyxDQUFBLEVBQUU7QUFDeEQsUUFBQSxPQUFPLEtBQUssQ0FBQTtBQUNmLEtBQUE7SUFDRCxJQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxhQUFULFNBQVMsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBVCxTQUFTLENBQUUsYUFBYSxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEtBQUEsSUFBQSxJQUFULFNBQVMsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBVCxTQUFTLENBQUUsYUFBYSxDQUFDLEVBQUU7QUFDdEYsUUFBQSxPQUFPLEtBQUssQ0FBQTtBQUNmLEtBQUE7SUFDRCxJQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxhQUFULFNBQVMsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBVCxTQUFTLENBQUUsZUFBZSxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEtBQUEsSUFBQSxJQUFULFNBQVMsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBVCxTQUFTLENBQUUsZUFBZSxDQUFDLEVBQUU7QUFDMUYsUUFBQSxPQUFPLEtBQUssQ0FBQTtBQUNmLEtBQUE7SUFDRCxJQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxhQUFULFNBQVMsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBVCxTQUFTLENBQUUsU0FBUyxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEtBQUEsSUFBQSxJQUFULFNBQVMsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBVCxTQUFTLENBQUUsU0FBUyxDQUFDLEVBQUU7QUFDOUUsUUFBQSxPQUFPLEtBQUssQ0FBQTtBQUNmLEtBQUE7QUFDRCxJQUFBLElBQUcsQ0FBQSxTQUFTLEtBQUEsSUFBQSxJQUFULFNBQVMsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBVCxTQUFTLENBQUUsWUFBWSxPQUFLLFNBQVMsYUFBVCxTQUFTLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQVQsU0FBUyxDQUFFLFlBQVksQ0FBQSxFQUFFO0FBQ3BELFFBQUEsT0FBTyxLQUFLLENBQUE7QUFDZixLQUFBO0FBQ0QsSUFBQSxJQUFHLENBQUEsU0FBUyxLQUFBLElBQUEsSUFBVCxTQUFTLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQVQsU0FBUyxDQUFFLGFBQWEsT0FBSyxTQUFTLGFBQVQsU0FBUyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFULFNBQVMsQ0FBRSxhQUFhLENBQUEsRUFBRTtBQUN0RCxRQUFBLE9BQU8sS0FBSyxDQUFBO0FBQ2YsS0FBQTtBQUNELElBQUEsSUFBRyxDQUFBLFNBQVMsS0FBQSxJQUFBLElBQVQsU0FBUyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFULFNBQVMsQ0FBRSxzQkFBc0IsT0FBSyxTQUFTLGFBQVQsU0FBUyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFULFNBQVMsQ0FBRSxzQkFBc0IsQ0FBQSxFQUFFO0FBQ3hFLFFBQUEsT0FBTyxLQUFLLENBQUE7QUFDZixLQUFBO0FBQ0QsSUFBQSxPQUFPLElBQUksQ0FBQTtBQUNmLENBQUM7U0FFZSw2QkFBNkIsR0FBQTtJQUV6QyxPQUFPO0FBQ0gsUUFBQSxRQUFRLEVBQUUsRUFBRTtBQUNaLFFBQUEsZUFBZSxFQUFFLENBQUM7UUFDbEIsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDO0FBQ2xCLFFBQUEsVUFBVSxFQUFFLElBQUk7QUFDaEIsUUFBQSxVQUFVLEVBQUUsS0FBSztBQUNqQixRQUFBLFVBQVUsRUFBRSxVQUFVO0FBQ3RCLFFBQUEsY0FBYyxFQUFFLFVBQVU7UUFDMUIsYUFBYSxFQUFFLENBQUMsRUFBRSxDQUFDO0FBQ25CLFFBQUEsZUFBZSxFQUFFLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDO0FBQzdDLFFBQUEsU0FBUyxFQUFFLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQztBQUMvQixRQUFBLFlBQVksRUFBRSxJQUFJO0FBQ2xCLFFBQUEsYUFBYSxFQUFFLEtBQUs7UUFDcEIsc0JBQXNCLEVBQUUsY0FBYyxDQUFDLGtCQUFrQjtLQUM1RCxDQUFBO0FBQ0wsQ0FBQztBQUVlLFNBQUEsc0JBQXNCLENBQUMsS0FBYSxFQUFFLFFBQTZCLEVBQUE7QUFFL0UsSUFBQSxJQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtBQUNqQyxRQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsS0FBQTtJQUVELE9BQU8sMkJBQTJCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNuRSxDQUFDO0FBRWUsU0FBQSxtQkFBbUIsQ0FBQyxLQUFhLEVBQUUsUUFBNkIsRUFBQTtBQUU1RSxJQUFBLElBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1FBQ3RDLE9BQU8sbUJBQW1CLENBQUMsTUFBTSxDQUFBO0FBQ3BDLEtBQUE7SUFFRCxPQUFPLDJCQUEyQixDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDeEUsQ0FBQztBQUVlLFNBQUEsb0JBQW9CLENBQUMsS0FBYSxFQUFFLFFBQTZCLEVBQUE7QUFFN0UsSUFBQSxJQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUNoQyxPQUFPLGFBQWEsQ0FBQyxJQUFJLENBQUE7QUFDNUIsS0FBQTtJQUVELE9BQU8sMkJBQTJCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUNqRSxDQUFDO0FBRWUsU0FBQSxrQkFBa0IsQ0FBQyxLQUFhLEVBQUUsUUFBNkIsRUFBQTtBQUUzRSxJQUFBLElBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO0FBQ3BDLFFBQUEsT0FBTyxFQUFFLENBQUM7QUFDYixLQUFBO0lBRUQsT0FBTyxDQUFBLGVBQUEsRUFBa0IsMkJBQTJCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQSxDQUFBLENBQUcsQ0FBQztBQUMzRixDQUFDO0FBRWUsU0FBQSwyQkFBMkIsQ0FBSSxLQUFhLEVBQUUsR0FBUSxFQUFBO0FBRWxFLElBQUEsSUFBRyxHQUFHLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUNqQixPQUFNLHVDQUF1QyxFQUFDO0FBQ2pELEtBQUE7SUFFRCxJQUFHLEtBQUssR0FBRyxDQUFDLEVBQUU7QUFDVixRQUFBLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pCLEtBQUE7QUFFRCxJQUFBLElBQUcsS0FBSyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUU7QUFDbkIsUUFBQSxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNyQixLQUFBO0FBRUQsSUFBQSxPQUFPLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUN0Qjs7QUMzTkE7Ozs7OztBQU1HO0FBS0g7Ozs7O0FBS0c7QUFDSCxNQUFNLHdCQUF3QixHQUFhO0lBQ3ZDLGlCQUFpQjtJQUNqQixjQUFjO0lBQ2QsaUJBQWlCO0lBQ2pCLGNBQWM7SUFDZCx3QkFBd0I7SUFDeEIsd0JBQXdCO0NBQzNCLENBQUM7QUFDRixNQUFNLHNCQUFzQixHQUFhLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSTtBQUM5RyxJQUFBLE9BQU8sSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2xDLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxvQkFBb0IsR0FBYTtJQUNuQyxhQUFhO0lBQ2IsY0FBYztJQUNkLFVBQVU7SUFDVixXQUFXO0lBQ1gsb0JBQW9CO0lBQ3BCLGlCQUFpQjtJQUNqQixxQkFBcUI7SUFDckIsa0JBQWtCO0lBQ2xCLGdCQUFnQjtDQUNuQixDQUFDO0FBQ0YsTUFBTSx5QkFBeUIsR0FBYSxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEtBQUk7QUFDN0csSUFBQSxPQUFPLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNsQyxDQUFDLENBQUMsQ0FBQztBQUVILE1BQU0sc0JBQXNCLEdBQUc7SUFDM0IsbUJBQW1CO0lBQ25CLGFBQWE7SUFDYixXQUFXO0lBQ1gsY0FBYztDQUNqQixDQUFBO0FBQ0QsTUFBTSwyQkFBMkIsR0FBYSxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEtBQUk7QUFDakgsSUFBQSxPQUFPLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNsQyxDQUFDLENBQUMsQ0FBQztBQUVILE1BQU0sZ0JBQWdCLEdBQUc7SUFDckIsUUFBUTtDQUNYLENBQUE7QUFDRCxNQUFNLHFCQUFxQixHQUFhLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSTtBQUNyRyxJQUFBLE9BQU8sSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2xDLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxnQkFBZ0IsR0FBRztJQUNyQixRQUFRO0NBQ1gsQ0FBQTtBQUNELE1BQU0scUJBQXFCLEdBQWEsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxLQUFJO0FBQ3JHLElBQUEsT0FBTyxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDbEMsQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLHdCQUF3QixHQUFHO0lBQzdCLGFBQWE7SUFDYixXQUFXO0lBQ1gsWUFBWTtJQUNaLGVBQWU7SUFDZixZQUFZO0lBQ1osV0FBVztDQUNkLENBQUE7QUFDRCxNQUFNLHFCQUFxQixHQUFhLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSTtBQUM3RyxJQUFBLE9BQU8sSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2xDLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSx3QkFBd0IsR0FBYTtJQUN2QyxnQkFBZ0I7SUFDaEIsWUFBWTtJQUNaLFlBQVk7QUFDZixDQUFBLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxLQUFJO0lBQ1osT0FBTyxJQUFJLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNoRSxDQUFDLENBQUMsQ0FBQztBQUVILE1BQU0sdUJBQXVCLEdBQWE7SUFDdEMsZUFBZTtJQUNmLFlBQVk7SUFDWixtQkFBbUI7SUFDbkIsZ0JBQWdCO0lBQ2hCLG1CQUFtQjtJQUNuQixnQkFBZ0I7QUFDbkIsQ0FBQSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSTtJQUNaLE9BQU8sSUFBSSxNQUFNLENBQUMsNEJBQTRCLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDaEUsQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLDBCQUEwQixHQUFhO0lBQ3pDLFVBQVU7SUFDVixrQkFBa0I7QUFDckIsQ0FBQSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSTtJQUNaLE9BQU8sSUFBSSxNQUFNLENBQUMsNEJBQTRCLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUE7QUFDL0QsQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLG1CQUFtQixHQUFhO0lBQ2xDLFdBQVc7SUFDWCxtQkFBbUI7SUFDbkIsT0FBTztJQUNQLGVBQWU7SUFDZixlQUFlO0lBQ2YsWUFBWTtJQUNaLFlBQVk7SUFDWixnQkFBZ0I7QUFDbkIsQ0FBQSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSTtJQUNaLE9BQU8sSUFBSSxNQUFNLENBQUMsNEJBQTRCLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDaEUsQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLHlCQUF5QixHQUFhO0lBQ3hDLGdDQUFnQztBQUNuQyxDQUFBLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxLQUFJO0lBQ1osT0FBTyxJQUFJLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNoRSxDQUFDLENBQUMsQ0FBQztBQUVIOzs7Ozs7Ozs7O0FBVUc7QUFDSCxTQUFTLHVCQUF1QixDQUFDLGNBQXNCLEVBQUUsdUJBQWlDLEVBQUE7QUFFdEYsSUFBQSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsdUJBQXVCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBRXJELElBQUksZUFBZSxHQUFHLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQTtRQUNyRSxJQUFHLGVBQWUsS0FBSyxJQUFJLEVBQUU7QUFDekIsWUFBQSxPQUFPLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtBQUNuQyxTQUFBO0FBQ0osS0FBQTtBQUVELElBQUEsT0FBTyxJQUFJLENBQUM7QUFDaEIsQ0FBQztBQUVlLFNBQUEseUJBQXlCLENBQUMsV0FBbUIsRUFBRSxnQkFBcUMsRUFBQTtBQUVoRyxJQUFBLGdCQUFnQixDQUFDLFVBQVUsR0FBRyxRQUFRLENBQUM7SUFDdkMsSUFBSSxhQUFhLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM1QyxJQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBRTNDLFFBQUEsSUFBSSxZQUFZLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLElBQUksWUFBWSxHQUFHLHVCQUF1QixDQUFDLFlBQVksRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBQ2pGLElBQUksWUFBWSxLQUFLLElBQUksRUFBRTtBQUV2QixZQUFBLGdCQUFnQixDQUFDLGNBQWMsR0FBRyw0QkFBNEIsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUNoRixTQUFBO0FBRUQsUUFBQSxZQUFZLEdBQUcsdUJBQXVCLENBQUMsWUFBWSxFQUFFLHlCQUF5QixDQUFDLENBQUM7UUFDaEYsSUFBSSxZQUFZLEtBQUssSUFBSSxFQUFFO0FBRXZCLFlBQUEsZ0JBQWdCLENBQUMsVUFBVSxHQUFHLHdCQUF3QixDQUFDLFlBQVksQ0FBQyxDQUFBO0FBQ3ZFLFNBQUE7QUFDSixLQUFBO0FBRUQsSUFBQSxPQUFPLGdCQUFnQixDQUFDO0FBQzVCLENBQUM7QUFFSyxTQUFVLG1CQUFtQixDQUFDLFdBQW1CLEVBQUE7QUFFbkQsSUFBQSxJQUFJLGNBQWMsR0FBRyw2QkFBNkIsRUFBRSxDQUFDO0lBRXJELElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7QUFFNUMsSUFBQSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUMzQyxRQUFBLElBQUksWUFBWSxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVwQyxRQUFBLHNCQUFzQixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUNyRCxRQUFBLDZCQUE2QixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUM1RCxRQUFBLDZCQUE2QixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUM1RCxRQUFBLHdCQUF3QixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUN2RCxRQUFBLHdCQUF3QixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUN2RCxRQUFBLHdCQUF3QixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUN2RCxRQUFBLDJCQUEyQixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUMxRCxRQUFBLDZCQUE2QixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUM1RCxRQUFBLDZCQUE2QixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUM1RCxRQUFBLDBCQUEwQixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUN6RCxRQUFBLDRCQUE0QixDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztBQUM5RCxLQUFBO0FBRUQsSUFBQSxPQUFPLGNBQWMsQ0FBQztBQUMxQixDQUFDO0FBRUQsU0FBUyw2QkFBNkIsQ0FBQyxZQUFvQixFQUFFLGNBQW1DLEVBQUE7SUFFNUYsSUFBSSxZQUFZLEdBQUcsdUJBQXVCLENBQUMsWUFBWSxFQUFFLDJCQUEyQixDQUFDLENBQUM7SUFDdEYsSUFBSSxZQUFZLEtBQUssSUFBSSxFQUFFO1FBQ3ZCLE9BQU87QUFDVixLQUFBO0FBRUQsSUFBQSxJQUFJLGFBQWEsR0FBRyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUN4RCxJQUFBLFlBQVksR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFaEMsSUFBQSxJQUFJLFNBQVMsR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDdkMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEtBQUssRUFBRTtRQUNuQyxJQUFJLFNBQVMsSUFBSSxDQUFDLEVBQUU7QUFDaEIsWUFBQSxjQUFjLENBQUMsZUFBZSxHQUFHLFNBQVMsQ0FBQztBQUM5QyxTQUFBO0FBQ0osS0FBQTtBQUNMLENBQUM7QUFFRCxTQUFTLHNCQUFzQixDQUFDLFlBQW9CLEVBQUUsY0FBbUMsRUFBQTtJQUNyRixJQUFJLFlBQVksR0FBRyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUUsNkJBQTZCLENBQUMsQ0FBQztJQUN4RixJQUFJLFlBQVksS0FBSyxJQUFJLEVBQUU7UUFDdkIsT0FBTztBQUNWLEtBQUE7QUFFRCxJQUFBLGNBQWMsQ0FBQyxRQUFRLEdBQUcsWUFBWSxDQUFDO0FBQzNDLENBQUM7QUFFRCxTQUFTLDZCQUE2QixDQUFDLFlBQW9CLEVBQUUsY0FBbUMsRUFBQTtJQUU1RixJQUFJLFlBQVksR0FBRyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUUseUJBQXlCLENBQUMsQ0FBQztJQUNwRixJQUFJLFlBQVksS0FBSyxJQUFJLEVBQUU7UUFDdkIsT0FBTztBQUNWLEtBQUE7QUFFRCxJQUFBLElBQUksYUFBYSxHQUFHLHFCQUFxQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ3hELElBQUEsSUFBRyxhQUFhLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTs7O0FBRzNCLFFBQUEsSUFBSSxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDbEMsY0FBYyxDQUFDLFVBQVUsR0FBRyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRSxPQUFPO0FBQ1YsU0FBQTtBQUNKLEtBQUE7SUFFRCxJQUFJLE1BQU0sR0FBaUIsRUFBRSxDQUFBO0FBQzdCLElBQUEsS0FBSSxJQUFJLE9BQU8sSUFBSSxhQUFhLEVBQUU7UUFFOUIsSUFBSSxNQUFNLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN0RCxJQUFHLE1BQU0sS0FBSyxJQUFJLEVBQUU7QUFDaEIsWUFBQSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3ZCLFNBQUE7QUFDSixLQUFBOztBQUdELElBQUEsSUFBRyxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtBQUNwQixRQUFBLE9BQU8sQ0FBQyxJQUFJLENBQUMsc0VBQXNFLENBQUMsQ0FBQTtBQUNwRixRQUFBLGNBQWMsQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQ3ZDLE9BQU87QUFDVixLQUFBOzs7O0FBS0QsSUFBQSxJQUFHLE1BQU0sQ0FBQyxNQUFNLEtBQUssYUFBYSxDQUFDLE1BQU0sRUFBRTtBQUV2QyxRQUFBLEtBQUksSUFBSSxPQUFPLElBQUksYUFBYSxFQUFFO1lBRTlCLElBQUksUUFBUSxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDakQsWUFBQSxJQUFHLFFBQVEsQ0FBQyxPQUFPLEtBQUssSUFBSSxFQUFFO0FBQzFCLGdCQUFBLGNBQWMsQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO2dCQUNuQyxPQUFPO0FBQ1YsYUFBQTtBQUVELFlBQUEsSUFBSSxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2xDLGNBQWMsQ0FBQyxVQUFVLEdBQUcsb0JBQW9CLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ25FLE9BQU87QUFDVixhQUFBO0FBQ0osU0FBQTtBQUNKLEtBQUE7QUFFRCxJQUFBLGNBQWMsQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO0FBQ3ZDLENBQUM7QUFFRCxTQUFTLHdCQUF3QixDQUFDLFlBQW9CLEVBQUUsY0FBbUMsRUFBQTtJQUV2RixJQUFJLFlBQVksR0FBRyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUUscUJBQXFCLENBQUMsQ0FBQztJQUNoRixJQUFJLFlBQVksS0FBSyxJQUFJLEVBQUU7UUFDdkIsT0FBTztBQUNWLEtBQUE7SUFFRCxJQUFJLE9BQU8sR0FBYyxFQUFFLENBQUE7QUFDM0IsSUFBQSxJQUFJLGFBQWEsR0FBRyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUN4RCxJQUFBLEtBQUksSUFBSSxZQUFZLElBQUksYUFBYSxFQUFFO1FBRW5DLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQztBQUN2QixRQUFBLElBQUksYUFBYSxHQUF1QixZQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEUsSUFBSSxhQUFhLEtBQUssU0FBUyxFQUFFO0FBQzdCLFlBQUEsUUFBUSxhQUFhO0FBQ2pCLGdCQUFBLE1BQU0sWUFBWSxDQUFDLFFBQVEsRUFBRTtBQUM3QixnQkFBQSxNQUFNLFlBQVksQ0FBQyxHQUFHLEVBQUU7QUFDeEIsZ0JBQUEsTUFBTSxZQUFZLENBQUMsS0FBSztvQkFDcEIsV0FBVyxHQUFHLEtBQUssQ0FBQztvQkFDcEIsTUFBTTtBQUNiLGFBQUE7QUFDSixTQUFBO0FBRUQsUUFBQSxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzdCLEtBQUE7QUFFRCxJQUFBLGNBQWMsQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDO0FBQ3hDLENBQUM7QUFFRCxTQUFTLHdCQUF3QixDQUFDLFlBQW9CLEVBQUUsY0FBbUMsRUFBQTtJQUV2RixJQUFJLFlBQVksR0FBRyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUUscUJBQXFCLENBQUMsQ0FBQztJQUNoRixJQUFJLFlBQVksS0FBSyxJQUFJLEVBQUU7UUFDdkIsT0FBTztBQUNWLEtBQUE7QUFFRCxJQUFBLElBQUksYUFBYSxHQUFHLHFCQUFxQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ3hELElBQUEsWUFBWSxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVoQyxJQUFBLElBQUksYUFBYSxHQUF1QixZQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDcEUsSUFBSSxhQUFhLEtBQUssU0FBUyxFQUFFO0FBQzdCLFFBQUEsUUFBUSxhQUFhO0FBQ2pCLFlBQUEsTUFBTSxZQUFZLENBQUMsUUFBUSxFQUFFO0FBQzdCLFlBQUEsTUFBTSxZQUFZLENBQUMsR0FBRyxFQUFFO0FBQ3hCLFlBQUEsTUFBTSxZQUFZLENBQUMsS0FBSztBQUNwQixnQkFBQSxjQUFjLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztnQkFDbEMsTUFBTTtBQUNiLFNBQUE7QUFDSixLQUFBO0FBQ0wsQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQUMsWUFBb0IsRUFBRSxjQUFtQyxFQUFBO0lBRXZGLElBQUksWUFBWSxHQUFHLHVCQUF1QixDQUFDLFlBQVksRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0lBQ2hGLElBQUksWUFBWSxLQUFLLElBQUksRUFBRTtRQUN2QixPQUFPO0FBQ1YsS0FBQTtBQUVELElBQUEsSUFBSSxhQUFhLEdBQUcscUJBQXFCLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDeEQsSUFBQSxZQUFZLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBR2hDLElBQUksWUFBWSxLQUFLLE9BQU87UUFDeEIsWUFBWSxLQUFLLEtBQUssRUFBTztBQUU3QixRQUFBLGNBQWMsQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO0FBQ3JDLEtBQUE7QUFDRCxJQUFBLGNBQWMsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBQ3JDLENBQUM7QUFFRCxTQUFTLDJCQUEyQixDQUFDLFlBQW9CLEVBQUUsY0FBbUMsRUFBQTtJQUUxRixJQUFJLFlBQVksR0FBRyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUUsd0JBQXdCLENBQUMsQ0FBQztJQUNuRixJQUFJLFlBQVksS0FBSyxJQUFJLEVBQUU7UUFDdkIsT0FBTztBQUNWLEtBQUE7SUFHRCxJQUFJLFFBQVEsR0FBYSxFQUFFLENBQUE7QUFFM0IsSUFBQSxJQUFJLGFBQWEsR0FBRyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUN4RCxJQUFBLEtBQUksSUFBSSxZQUFZLElBQUksYUFBYSxFQUFFO1FBRW5DLElBQUksTUFBTSxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDM0QsSUFBSSxVQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLElBQUksTUFBTSxLQUFLLElBQUksRUFBRTtBQUNqQixZQUFBLFVBQVUsR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDbEMsU0FBQTtBQUNJLGFBQUE7WUFFRCxJQUFJLFVBQVUsR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7QUFDL0MsWUFBQSxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxLQUFLLEVBQUU7QUFFN0IsZ0JBQUEsVUFBVSxHQUFHLENBQUEsRUFBRyxVQUFVLENBQUEsRUFBQSxDQUFJLENBQUM7QUFDbEMsYUFBQTtBQUNKLFNBQUE7QUFDRCxRQUFBLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDN0IsS0FBQTtBQUVELElBQUEsY0FBYyxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUM7QUFDNUMsQ0FBQztBQUVELFNBQVMsNkJBQTZCLENBQUMsWUFBb0IsRUFBRSxjQUFtQyxFQUFBO0lBRTVGLElBQUksWUFBWSxHQUFHLHVCQUF1QixDQUFDLFlBQVksRUFBRSwwQkFBMEIsQ0FBQyxDQUFDO0lBQ3JGLElBQUksWUFBWSxLQUFLLElBQUksRUFBRTtRQUN2QixPQUFPO0FBQ1YsS0FBQTtJQUVELElBQUksY0FBYyxHQUEwQixFQUFFLENBQUE7QUFDOUMsSUFBQSxJQUFJLGFBQWEsR0FBRyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUV4RCxJQUFBLEtBQUksSUFBSSxZQUFZLElBQUksYUFBYSxFQUFFO0FBRW5DLFFBQUEsSUFBSSxZQUFZLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxDQUFDO1FBQzlDLFlBQVksR0FBRyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDakQsSUFBSSxZQUFZLEtBQUssUUFBUSxFQUFFO0FBQzNCLFlBQUEsWUFBWSxHQUFHLG1CQUFtQixDQUFDLE1BQU0sQ0FBQztBQUM3QyxTQUFBO0FBQ0QsUUFBQSxjQUFjLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ3JDLEtBQUE7QUFDRCxJQUFBLGNBQWMsQ0FBQyxlQUFlLEdBQUcsY0FBYyxDQUFDO0FBQ3BELENBQUM7QUFFRCxTQUFTLDZCQUE2QixDQUFDLFlBQW9CLEVBQUUsY0FBbUMsRUFBQTtJQUU1RixJQUFJLFlBQVksR0FBRyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztJQUM5RSxJQUFJLFlBQVksS0FBSyxJQUFJLEVBQUU7UUFDdkIsT0FBTztBQUNWLEtBQUE7SUFHRCxJQUFJLFVBQVUsR0FBb0IsRUFBRSxDQUFBO0FBRXBDLElBQUEsSUFBSSxhQUFhLEdBQUcscUJBQXFCLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDeEQsSUFBQSxLQUFJLElBQUksWUFBWSxJQUFJLGFBQWEsRUFBRTtBQUVuQyxRQUFBLElBQUksYUFBYSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUM7UUFDdkMsWUFBWSxHQUFHLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNqRCxJQUFJLFlBQVksS0FBSyxRQUFRLEVBQUU7QUFDM0IsWUFBQSxhQUFhLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQztBQUN4QyxTQUFBO1FBQ0QsSUFBSSxZQUFZLEtBQUssT0FBTyxFQUFFO0FBQzFCLFlBQUEsYUFBYSxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUM7QUFDdkMsU0FBQTtBQUNELFFBQUEsVUFBVSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUNsQyxLQUFBO0FBQ0QsSUFBQSxjQUFjLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQztBQUMxQyxDQUFDO0FBRUQsU0FBUyw0QkFBNEIsQ0FBQyxZQUFvQixFQUFFLGNBQW1DLEVBQUE7SUFFM0YsSUFBSSxZQUFZLEdBQUcsdUJBQXVCLENBQUMsWUFBWSxFQUFFLHlCQUF5QixDQUFDLENBQUM7SUFDcEYsSUFBSSxZQUFZLEtBQUssSUFBSSxFQUFFO1FBQ3ZCLE9BQU87QUFDVixLQUFBO0FBRUQsSUFBQSxJQUFJLGFBQWEsR0FBRyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUN4RCxJQUFBLFlBQVksR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFaEMsSUFBQSxJQUFJLGNBQWMsR0FBMkIsZ0JBQWlCLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDN0UsSUFBSSxjQUFjLEtBQUssU0FBUyxFQUFFO0FBQzlCLFFBQUEsUUFBUSxjQUFjO0FBQ2xCLFlBQUEsTUFBTSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUU7QUFDakMsWUFBQSxNQUFNLGdCQUFnQixDQUFDLEdBQUcsRUFBRTtBQUM1QixZQUFBLE1BQU0sZ0JBQWdCLENBQUMsS0FBSztBQUN4QixnQkFBQSxjQUFjLENBQUMsc0JBQXNCLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQztnQkFDL0QsTUFBTTtBQUNWLFlBQUE7QUFDSSxnQkFBQSxjQUFjLENBQUMsc0JBQXNCLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQztBQUNwRSxTQUFBO0FBQ0osS0FBQTtBQUNMLENBQUM7QUFFRCxTQUFTLDBCQUEwQixDQUFDLFlBQW9CLEVBQUUsY0FBbUMsRUFBQTtJQUV6RixJQUFJLFlBQVksR0FBRyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUUsdUJBQXVCLENBQUMsQ0FBQztJQUNsRixJQUFHLFlBQVksS0FBSyxJQUFJLEVBQUU7UUFDdEIsT0FBTztBQUNWLEtBQUE7QUFFRCxJQUFBLElBQUksYUFBYSxHQUFHLHFCQUFxQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ3hELElBQUEsWUFBWSxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVoQyxJQUFJLE1BQU0sR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzNELElBQUksTUFBTSxLQUFLLElBQUksRUFBRTtBQUVqQixRQUFBLGNBQWMsQ0FBQyxZQUFZLEdBQUcsTUFBTSxDQUFDO0FBQ3hDLEtBQUE7QUFDSSxTQUFBO1FBRUQsSUFBSSxVQUFVLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQy9DLFFBQUEsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssS0FBSyxFQUFFO0FBRTdCLFlBQUEsY0FBYyxDQUFDLFlBQVksR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtBQUN4RixTQUFBO0FBQ0osS0FBQTtBQUNMLENBQUM7QUFFRCxTQUFTLHFCQUFxQixDQUFDLGFBQXFCLEVBQUE7O0lBR2hELElBQUksTUFBTSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDNUMsSUFBRyxNQUFNLEtBQUssSUFBSSxFQUFFO1FBQ2hCLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUMxQixLQUFBO0FBRUQsSUFBQSxJQUFJLFlBQVksR0FBVyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckMsSUFBQSxJQUFJLFFBQVEsR0FBYSxZQUFZLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSTtBQUN6RCxRQUFBLE9BQU8sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ3RCLEtBQUMsQ0FBQyxDQUFBO0FBRUYsSUFBQSxPQUFPLFFBQVEsQ0FBQztBQUNwQixDQUFDO0FBRUQsTUFBTSw4QkFBOEIsR0FBRztJQUNuQyxJQUFJO0lBQ0osV0FBVztDQUNkLENBQUE7QUFDRCxNQUFNLDZCQUE2QixHQUFhLDhCQUE4QixDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSTtBQUMzSCxJQUFBLE9BQU8sSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2xDLENBQUMsQ0FBQyxDQUFDO0FBQ0csU0FBVSwyQkFBMkIsQ0FBQyxXQUFtQixFQUFBO0lBRTNELElBQUksaUJBQWlCLEdBQUcsRUFBRSxDQUFBO0lBQzFCLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7QUFFNUMsSUFBQSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUMzQyxRQUFBLElBQUksWUFBWSxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVwQyxJQUFJLFlBQVksR0FBRyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUUsNkJBQTZCLENBQUMsQ0FBQztRQUN4RixJQUFJLFlBQVksS0FBSyxJQUFJLEVBQUU7WUFFdkIsaUJBQWlCLEdBQUcsWUFBWSxDQUFBO0FBQ25DLFNBQUE7QUFDSixLQUFBO0FBRUQsSUFBQSxPQUFPLGlCQUFpQixDQUFDO0FBQzdCLENBQUM7QUFFRCxTQUFTLDRCQUE0QixDQUFDLGNBQXNCLEVBQUE7QUFFeEQsSUFBQSxRQUFRLGNBQWMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztBQUN4RCxRQUFBLEtBQUssTUFBTSxDQUFDO0FBQ1osUUFBQSxLQUFLLFVBQVUsQ0FBQztBQUNoQixRQUFBLEtBQUssWUFBWSxDQUFDO0FBQ2xCLFFBQUEsS0FBSyxXQUFXLENBQUM7QUFDakIsUUFBQSxLQUFLLGFBQWEsQ0FBQztBQUNuQixRQUFBLEtBQUssZ0JBQWdCLENBQUM7QUFDdEIsUUFBQSxLQUFLLE9BQU8sQ0FBQztBQUNiLFFBQUEsS0FBSyxPQUFPLENBQUM7QUFDYixRQUFBLEtBQUssV0FBVztBQUNaLFlBQUEsT0FBTyxNQUFNLENBQUE7QUFDakIsUUFBQSxLQUFLLFFBQVEsQ0FBQztBQUNkLFFBQUEsS0FBSyxlQUFlLENBQUM7QUFDckIsUUFBQSxLQUFLLGlCQUFpQixDQUFDO0FBQ3ZCLFFBQUEsS0FBSyxRQUFRLENBQUM7QUFDZCxRQUFBLEtBQUssZUFBZSxDQUFDO0FBQ3JCLFFBQUEsS0FBSyxpQkFBaUIsQ0FBQztBQUN2QixRQUFBLEtBQUssVUFBVSxDQUFDO0FBQ2hCLFFBQUEsS0FBSyxVQUFVO0FBQ1gsWUFBQSxPQUFPLFFBQVEsQ0FBQTtBQUNuQixRQUFBLEtBQUssT0FBTyxDQUFDO0FBQ2IsUUFBQSxLQUFLLFdBQVcsQ0FBQztBQUNqQixRQUFBLEtBQUssYUFBYSxDQUFDO0FBQ25CLFFBQUEsS0FBSyxZQUFZLENBQUM7QUFDbEIsUUFBQSxLQUFLLGNBQWMsQ0FBQztBQUNwQixRQUFBLEtBQUssZ0JBQWdCLENBQUM7QUFDdEIsUUFBQSxLQUFLLE1BQU0sQ0FBQztBQUNaLFFBQUEsS0FBSyxLQUFLO0FBQ04sWUFBQSxPQUFPLE9BQU8sQ0FBQTtBQUNyQixLQUFBO0FBRUQsSUFBQSxPQUFPLFFBQVEsQ0FBQTtBQUNuQixDQUFDO0FBRUQsU0FBUyx3QkFBd0IsQ0FBQyxVQUFrQixFQUFBO0FBRWhELElBQUEsUUFBUSxVQUFVLEdBQUcsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO0FBQ2pFLFFBQUEsS0FBSyxPQUFPLENBQUM7QUFDYixRQUFBLEtBQUssSUFBSTtBQUNMLFlBQUEsT0FBTyxPQUFPLENBQUM7QUFDbkIsUUFBQSxLQUFLLFFBQVEsQ0FBQztBQUNkLFFBQUEsS0FBSyxLQUFLO0FBQ04sWUFBQSxPQUFPLFFBQVEsQ0FBQztBQUNwQixRQUFBLEtBQUssT0FBTyxDQUFDO0FBQ2IsUUFBQSxLQUFLLElBQUk7QUFDTCxZQUFBLE9BQU8sT0FBTyxDQUFDO0FBQ25CLFFBQUEsS0FBSyxNQUFNLENBQUM7QUFDWixRQUFBLEtBQUssV0FBVztBQUNaLFlBQUEsT0FBTyxNQUFNLENBQUM7QUFDckIsS0FBQTtBQUVELElBQUEsT0FBTyxRQUFRLENBQUE7QUFDbkIsQ0FBQztBQUVELFNBQVMsNEJBQTRCLENBQUMsY0FBc0IsRUFBQTtJQUV4RCxjQUFjLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsY0FBYyxDQUFDLENBQUM7QUFFN0QsSUFBQSxJQUFJLFdBQVcsR0FBRyxDQUFNLEdBQUEsRUFBQSxjQUFjLGVBQWUsQ0FBQztBQUN0RCxJQUFBLE9BQU8sV0FBVyxDQUFDO0FBQ3ZCOztBQ2prQk8sTUFBTSxnQ0FBZ0MsR0FBRztJQUM1QyxLQUFLO0lBQ0wsT0FBTztJQUNQLE1BQU07SUFDTixNQUFNO0lBQ04sS0FBSztJQUNMLE9BQU87SUFDUCxPQUFPO0lBQ1AsTUFBTTtJQUNOLEtBQUs7Q0FDQyxDQUFDO0FBR0wsU0FBVSx1QkFBdUIsQ0FBQyxLQUFhLEVBQUE7QUFDakQsSUFBQSxPQUFPLGdDQUFnQyxDQUFDLFFBQVEsQ0FBQyxLQUE4QixDQUFDLENBQUM7QUFDckYsQ0FBQztBQUNLLFNBQVUsNkJBQTZCLENBQUMsS0FBcUMsRUFBQTtBQUMvRSxJQUFBLE9BQVEsS0FBSyxDQUFDLFdBQVcsRUFBNEIsQ0FBQztBQUMxRCxDQUFDO0FBQ0ssU0FBVSw0QkFBNEIsQ0FBQyxLQUE0QixFQUFBO0FBQ3JFLElBQUEsUUFBUSxLQUFLO0FBQ1QsUUFBQSxLQUFLLEtBQUs7QUFDTixZQUFBLE9BQU8sQ0FBQyxDQUFDO0FBQ2IsUUFBQSxLQUFLLE9BQU87QUFDUixZQUFBLE9BQU8sQ0FBQyxDQUFDO0FBQ2IsUUFBQSxLQUFLLE1BQU07QUFDUCxZQUFBLE9BQU8sQ0FBQyxDQUFDO0FBQ2IsUUFBQSxLQUFLLE1BQU07QUFDUCxZQUFBLE9BQU8sQ0FBQyxDQUFDO0FBQ2IsUUFBQSxLQUFLLEtBQUs7QUFDTixZQUFBLE9BQU8sQ0FBQyxDQUFDO0FBQ2IsUUFBQSxLQUFLLE9BQU87QUFDUixZQUFBLE9BQU8sQ0FBQyxDQUFDO0FBQ2IsUUFBQSxLQUFLLE9BQU87QUFDUixZQUFBLE9BQU8sQ0FBQyxDQUFDO0FBQ2IsUUFBQSxLQUFLLE1BQU07QUFDUCxZQUFBLE9BQU8sQ0FBQyxDQUFDO0FBQ2IsUUFBQSxLQUFLLEtBQUs7QUFDTixZQUFBLE9BQU8sRUFBRSxDQUFDO0FBQ2pCLEtBQUE7QUFDTCxDQUFDO0FBQ0QsTUFBTSx5QkFBeUIsR0FBRyxhQUFhLENBQUM7QUFDaEQsTUFBTSwyQkFBMkIsR0FBRyxVQUFVLENBQUM7QUFFL0MsTUFBTSxtQkFBbUIsR0FBRyxhQUFhLENBQUM7QUFDMUMsTUFBTSxnQkFBZ0IsR0FBVyxDQUFDLE1BQUs7SUFFbkMsSUFBSSxJQUFJLEdBQUcsZ0NBQWdDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RELElBQUEsSUFBSSxhQUFhLEdBQUcsQ0FBd0IscUJBQUEsRUFBQSx5QkFBeUIsQ0FBTyxJQUFBLEVBQUEsSUFBSSxDQUF5QixzQkFBQSxFQUFBLG1CQUFtQixDQUFjLFdBQUEsRUFBQSwyQkFBMkIsQ0FBTyxJQUFBLEVBQUEsSUFBSSxvQ0FBb0MsQ0FBQztBQUNyTixJQUFBLE9BQU8sYUFBYSxDQUFDO0FBQ3pCLENBQUMsR0FBRyxDQUFDO0FBQ0wsTUFBTSxZQUFZLEdBQUcsSUFBSSxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDdkQsTUFBTSx1QkFBdUIsR0FBRyx5Q0FBeUMsQ0FBQztBQUMxRSxNQUFNLHdCQUF3QixHQUFHLFlBQVksQ0FBQztBQUN4QyxTQUFVLFVBQVUsQ0FBQyxJQUFZLEVBQUE7SUFFbkMsSUFBSSxTQUFTLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QyxJQUFJLFNBQVMsS0FBSyxJQUFJLEVBQUU7QUFFcEIsUUFBQSxJQUFJLElBQUksR0FBRyxzQkFBc0IsRUFBRSxDQUFDO0FBQ3BDLFFBQUEsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDbEIsUUFBQSxJQUFJLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUM7QUFDckMsUUFBQSxJQUFJLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQyxLQUFLLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUV6RCxRQUFBLElBQUksVUFBVSxHQUFHLDBCQUEwQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDMUUsUUFBQSxJQUFJLENBQUMsV0FBVyxJQUFJLFVBQVUsQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUM7QUFDdkUsUUFBQSxJQUFJLENBQUMsT0FBTyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUM7UUFDbEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFFekQsSUFBSSxDQUFDLFlBQVksR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2RyxJQUFJLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMseUJBQXlCLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLHlCQUF5QixDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0FBQzdKLFFBQUEsT0FBTyxJQUFJLENBQUM7QUFDZixLQUFBO0lBRUQsT0FBTyxzQkFBc0IsRUFBRSxDQUFDO0FBQ3BDLENBQUM7QUFLSyxTQUFVLGtCQUFrQixDQUFDLElBQVksRUFBQTtBQUUzQyxJQUFBLElBQUksSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM1QixJQUFBLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxLQUFLLEVBQUU7UUFDdEIsT0FBTztBQUNILFlBQUEsS0FBSyxFQUFFLEtBQUs7WUFDWixZQUFZLEVBQUUsNkJBQTZCLEVBQUU7U0FDaEQsQ0FBQztBQUNMLEtBQUE7SUFFRCxPQUFPO0FBQ0gsUUFBQSxLQUFLLEVBQUUsSUFBSTtRQUNYLFlBQVksRUFBRSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUM7S0FDekUsQ0FBQztBQUNOLENBQUM7QUFDSyxTQUFVLGNBQWMsQ0FBQyxJQUFZLEVBQUE7QUFDdkMsSUFBQSxPQUFPLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUM7QUFDbEMsQ0FBQztBQUNLLFNBQVUsc0JBQXNCLENBQUMsSUFBWSxFQUFBO0lBRS9DLElBQUksU0FBUyxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEMsSUFBSSxTQUFTLEtBQUssSUFBSSxFQUFFO0FBQ3BCLFFBQUEsT0FBTyxJQUFJLENBQUM7QUFDZixLQUFBO0FBQ0QsSUFBQSxPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDO0FBQ0ssU0FBVSxvQkFBb0IsQ0FBQyxJQUFZLEVBQUE7SUFFN0MsSUFBSSxTQUFTLEdBQUcsd0JBQXdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BELElBQUksU0FBUyxLQUFLLElBQUksRUFBRTtBQUNwQixRQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsS0FBQTtBQUNELElBQUEsT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQztBQUNlLFNBQUEsbUJBQW1CLENBQUMsVUFBb0IsRUFBRSxXQUFtQixFQUFBO0FBRXpFLElBQUEsSUFBSSxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsS0FBSyxLQUFLLEVBQUU7QUFDN0MsUUFBQSxPQUFPLEtBQUssQ0FBQztBQUNoQixLQUFBO0FBRUQsSUFBQSxJQUFJLFdBQVcsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM1RCxJQUFBLE9BQU8sMEJBQTBCLENBQUMsV0FBVyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ3pELENBQUM7QUFDSyxTQUFVLDBCQUEwQixDQUFDLFdBQW1CLEVBQUE7SUFFMUQsSUFBSSxXQUFXLEdBQUcsV0FBVyxDQUFDO0FBRTlCLElBQUEsSUFBSSxNQUFNLEdBQUc7QUFDVCxRQUFBLEtBQUssRUFBRSxLQUFLO0FBQ1osUUFBQSxPQUFPLEVBQUUsV0FBVztBQUNwQixRQUFBLFdBQVcsRUFBRSxDQUFDO0tBQ2pCLENBQUM7SUFFRixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDZCxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDZixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDdkIsSUFBSSxDQUFDLEdBQUcsR0FBRyxFQUFFO1lBQ1QsTUFBTTtBQUNULFNBQUE7QUFFRCxRQUFBLElBQUksS0FBSyxHQUFHLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzVDLElBQUksS0FBSyxLQUFLLElBQUksRUFBRTtZQUNoQixNQUFNO0FBQ1QsU0FBQTtBQUVELFFBQUEsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztBQUMxQixRQUFBLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7O0FBRXhCLFlBQUEsTUFBTSxLQUFLLE1BQU0sQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzVDLFlBQUEsS0FBSyxFQUFFLENBQUM7QUFDWCxTQUFBO0FBQ0ksYUFBQTs7QUFFRCxZQUFBLE1BQU0sS0FBSyxNQUFNLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM1QyxZQUFBLEtBQUssRUFBRSxDQUFDO0FBQ1gsU0FBQTtBQUVELFFBQUEsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDLEVBQUU7O0FBRWQsWUFBQSxPQUFPLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNsQyxTQUFBO0FBRUQsUUFBQSxXQUFXLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMzQyxLQUFBO0lBRUQsU0FBUyxlQUFlLENBQUMsV0FBNEIsRUFBQTtBQUNqRCxRQUFBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsTUFBTSxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0RSxNQUFNLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDM0MsUUFBQSxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztBQUNwQixRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2pCO0FBRUQsSUFBQSxPQUFPLE1BQU0sQ0FBQztBQUNsQixDQUFDO0FBQ0QsU0FBUyxrQkFBa0IsQ0FBQyxXQUFtQixFQUFBO0lBRTNDLElBQUksVUFBVSxHQUFHLHVCQUF1QixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUMzRCxJQUFJLFdBQVcsR0FBRyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7QUFFN0QsSUFBQSxJQUFJLFVBQVUsS0FBSyxJQUFJLElBQUksV0FBVyxLQUFLLElBQUksRUFBRTtBQUM3QyxRQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsS0FBQTtBQUVELElBQUEsSUFBSSxVQUFVLEtBQUssSUFBSSxJQUFJLFdBQVcsS0FBSyxJQUFJLEVBQUU7UUFDN0MsT0FBTztBQUNILFlBQUEsTUFBTSxFQUFFLFdBQVc7QUFDbkIsWUFBQSxJQUFJLEVBQUUsT0FBTztTQUNoQixDQUFDO0FBQ0wsS0FBQTtBQUVELElBQUEsSUFBSSxXQUFXLEtBQUssSUFBSSxJQUFJLFVBQVUsS0FBSyxJQUFJLEVBQUU7UUFDN0MsT0FBTztBQUNILFlBQUEsTUFBTSxFQUFFLFVBQVU7QUFDbEIsWUFBQSxJQUFJLEVBQUUsTUFBTTtTQUNmLENBQUM7QUFDTCxLQUFBO0FBRUQsSUFBQSxJQUFJLFdBQVcsQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssRUFBRTtRQUN0QyxPQUFPO0FBQ0gsWUFBQSxNQUFNLEVBQUUsV0FBVztBQUNuQixZQUFBLElBQUksRUFBRSxPQUFPO1NBQ2hCLENBQUM7QUFDTCxLQUFBO0FBQ0ksU0FBQTtRQUNELE9BQU87QUFDSCxZQUFBLE1BQU0sRUFBRSxVQUFVO0FBQ2xCLFlBQUEsSUFBSSxFQUFFLE1BQU07U0FDZixDQUFDO0FBQ0wsS0FBQTtBQUNMLENBQUM7QUFDSyxTQUFVLGVBQWUsQ0FBQyxJQUFZLEVBQUE7QUFFeEMsSUFBQSxJQUFJLFdBQVcsR0FBRyxzQkFBc0IsRUFBRSxDQUFDO0FBQzNDLElBQUEsV0FBVyxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUM7SUFFakMsSUFBSSxTQUFTLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QyxJQUFJLFNBQVMsS0FBSyxJQUFJLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7QUFFNUMsUUFBQSxXQUFXLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztBQUN6QixRQUFBLFdBQVcsQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUM1QyxXQUFXLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDOUMsV0FBVyxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUMsYUFBYSxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUM7QUFDakYsS0FBQTtBQUVELElBQUEsT0FBTyxXQUFXLENBQUM7QUFDdkIsQ0FBQztBQVNELFNBQVMsc0JBQXNCLEdBQUE7SUFDM0IsT0FBTztBQUNILFFBQUEsS0FBSyxFQUFFLEtBQUs7UUFDWixhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQ2pCLFdBQVcsRUFBRSxDQUFDLENBQUM7QUFDZixRQUFBLFdBQVcsRUFBRSxDQUFDO0FBQ2QsUUFBQSxPQUFPLEVBQUUsRUFBRTtBQUNYLFFBQUEsWUFBWSxFQUFFLEVBQUU7QUFDaEIsUUFBQSxXQUFXLEVBQUUsRUFBRTtBQUNmLFFBQUEsVUFBVSxFQUFFLE9BQU87S0FDdEIsQ0FBQztBQUNOLENBQUM7QUFFRCxNQUFNLG9CQUFvQixHQUFHLG9EQUFvRCxDQUFDO1NBQ2xFLG1CQUFtQixDQUFDLGtCQUEwQixFQUFFLFdBQW1CLEVBQUUsRUFBQTs7QUFJakYsSUFBQSxJQUFJLGVBQWUsR0FBRyw2QkFBNkIsRUFBRSxDQUFDO0lBQ3RELElBQUksZUFBZSxHQUFHLEtBQUssQ0FBQztJQUM1QixJQUFJLFFBQVEsS0FBSyxFQUFFLElBQUksdUJBQXVCLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDdEQsZUFBZSxHQUFHLElBQUksQ0FBQztRQUN2QixlQUFlLENBQUMsZUFBZSxHQUFHLDRCQUE0QixDQUFDLDZCQUE2QixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDM0csS0FBQTtJQUVELElBQUksa0JBQWtCLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7QUFDNUMsUUFBQSxPQUFPLGVBQWUsQ0FBQztBQUMxQixLQUFBO0lBRUQsSUFBSSxhQUFhLEdBQUcsa0JBQWtCLENBQUM7SUFDdkMsSUFBSSxVQUFVLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzFELElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQTtBQUNwQixJQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFVBQVUsS0FBSyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRTtRQUUxQyxJQUFJLFdBQVcsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ25ELElBQUksWUFBWSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDckQsUUFBQSxXQUFXLElBQUksQ0FBRyxFQUFBLFdBQVcsQ0FBSyxFQUFBLEVBQUEsWUFBWSxJQUFJLENBQUE7QUFFbEQsUUFBQSxhQUFhLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM3RSxRQUFBLFVBQVUsR0FBRyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDekQsS0FBQTtBQUVELElBQUEsSUFBSSxjQUFjLEdBQUcsbUJBQW1CLENBQUMsV0FBVyxDQUFDLENBQUE7QUFDckQsSUFBQSxJQUFHLGVBQWUsRUFBRTtBQUNoQixRQUFBLGNBQWMsQ0FBQyxlQUFlLEdBQUcsZUFBZSxDQUFDLGVBQWUsQ0FBQTtBQUNuRSxLQUFBO0FBRUQsSUFBQSxPQUFPLGNBQWMsQ0FBQztBQUMxQjs7QUMvUkE7Ozs7OztBQU1HO0FBTUgsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLHFEQUFxRDtBQUNyRCxJQUFBLHFEQUFxRCxDQUFDLENBQUE7QUFDaEYsTUFBTSxlQUFlLEdBQWEsRUFBRSxDQUFDO0FBQ3JDLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDN0MsSUFBQSxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6RCxDQUFBO0FBRUQsTUFBTSwyQkFBMkIsR0FBRyxDQUFDLHVEQUF1RDtBQUN2RCxJQUFBLHVEQUF1RCxDQUFDLENBQUE7QUFDN0YsTUFBTSwwQkFBMEIsR0FBYSxFQUFFLENBQUM7QUFDaEQsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLDJCQUEyQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUN4RCxJQUFBLDBCQUEwQixDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0UsQ0FBQTtBQUdLLFNBQVUsWUFBWSxDQUFDLElBQVksRUFBQTtBQUVyQyxJQUFBLElBQUksV0FBVyxHQUFHLHNCQUFzQixFQUFFLENBQUM7QUFDM0MsSUFBQSxXQUFXLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztBQUVwQyxJQUFBLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRSxlQUFlLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBRTNDLElBQUksU0FBUyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDN0MsSUFBRyxTQUFTLEtBQUssSUFBSSxJQUFJLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0FBQzNDLFlBQUEsV0FBVyxDQUFDLGFBQWEsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFBO1lBQzNDLFdBQVcsQ0FBQyxXQUFXLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUM5QyxXQUFXLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQyxhQUFhLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQztBQUU5RSxZQUFBLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDMUUsSUFBRywwQkFBMEIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7QUFDekMsZ0JBQUEsV0FBVyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7Z0JBQ3pCLE1BQU07QUFDVCxhQUFBO0FBQ0osU0FBQTtBQUNKLEtBQUE7QUFDRCxJQUFBLE9BQU8sV0FBVyxDQUFDO0FBQ3ZCLENBQUM7QUFDSyxTQUFVLGdCQUFnQixDQUFDLElBQVksRUFBQTtBQUN6QyxJQUFBLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQTtBQUNuQyxDQUFDO0FBRUssU0FBVSxnQkFBZ0IsQ0FBQyxJQUFZLEVBQUE7QUFFekMsSUFBQSxJQUFJLFlBQVksR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDdEMsSUFBQSxJQUFHLFlBQVksQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFO0FBRTVCLFFBQUEsSUFBSSxHQUFHLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFBO0FBQzlCLFFBQUEsSUFBRyxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxFQUFFLEVBQUU7WUFDM0IsT0FBTyxFQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDO0FBQzVDLFNBQUE7UUFDRCxPQUFPLEVBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFDLENBQUM7QUFDM0MsS0FBQTtJQUVELE9BQU8sRUFBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUQsTUFBTSxjQUFjLEdBQUcsQ0FBQyx1QkFBdUI7SUFDdkIsdUJBQXVCO0lBQ3ZCLHVCQUF1QjtBQUN2QixJQUFBLHVCQUF1QixDQUFDLENBQUE7QUFDaEQsTUFBTSxhQUFhLEdBQWEsRUFBRSxDQUFDO0FBQ25DLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQzNDLElBQUEsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JELENBQUE7QUFTSyxTQUFVLFVBQVUsQ0FBQyxJQUFZLEVBQUE7Ozs7QUFLbkMsSUFBQSxJQUFJLGFBQWEsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEMsSUFBSSxnQkFBZ0IsR0FBRyxhQUFhLENBQUM7QUFDckMsSUFBQSxPQUFNLGdCQUFnQixDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUU7UUFFbkMsYUFBYSxHQUFHLGdCQUFnQixDQUFDO1FBQ2pDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUNyRCxRQUFBLGdCQUFnQixHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxQyxLQUFBO0FBRUQsSUFBQSxPQUFPLGFBQWEsQ0FBQztBQUN6QixDQUFDO0FBRUssU0FBVSxzQkFBc0IsQ0FBQyxJQUFZLEVBQUE7SUFFL0MsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQ3ZCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztBQUVmLElBQUEsSUFBSSxhQUFhLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQy9DLE9BQU0sYUFBYSxDQUFDLEtBQUssRUFBRTtRQUV2QixXQUFXLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDM0QsUUFBQSxJQUFJLE9BQU8sR0FBRyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDekMsUUFBQSxJQUFHLE9BQU8sQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFO1lBQ3hCLE1BQU07QUFDVCxTQUFBO0FBQ0QsUUFBQSxNQUFNLElBQUksYUFBYSxDQUFDLFdBQVcsQ0FBQztRQUNwQyxhQUFhLEdBQUcsT0FBTyxDQUFDO0FBQzNCLEtBQUE7SUFFRCxPQUFPO1FBQ0gsS0FBSyxFQUFFLGFBQWEsQ0FBQyxLQUFLO0FBQzFCLFFBQUEsYUFBYSxFQUFFLGFBQWEsQ0FBQyxhQUFhLEdBQUcsTUFBTTtBQUNuRCxRQUFBLFdBQVcsRUFBRSxhQUFhLENBQUMsV0FBVyxHQUFHLE1BQU07UUFDL0MsV0FBVyxFQUFFLGFBQWEsQ0FBQyxXQUFXO0tBQ3pDLENBQUM7QUFDTixDQUFDO0FBQ0ssU0FBVSxjQUFjLENBQUMsSUFBWSxFQUFBO0FBQ3ZDLElBQUEsT0FBTyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFBO0FBQ2pDLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxJQUFZLEVBQUE7SUFFL0IsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ2xCLElBQUEsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdkIsSUFBQSxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQTtJQUNwQixJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7QUFDcEIsSUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUUsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUV6QyxJQUFJLFNBQVMsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzNDLElBQUcsU0FBUyxLQUFLLElBQUksSUFBSSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUMzQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2IsWUFBQSxhQUFhLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQTtBQUMvQixZQUFBLFdBQVcsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1lBQ2xDLE1BQU07QUFDVCxTQUFBO0FBQ0osS0FBQTtBQUNELElBQUEsV0FBVyxHQUFHLGFBQWEsR0FBRyxXQUFXLENBQUM7SUFFMUMsT0FBTyxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxDQUFDO0FBQzlELENBQUM7QUFFRCxNQUFNLGNBQWMsR0FBc0IsQ0FBQyxDQUFDLG1DQUFtQyxFQUFJLEVBQUUsQ0FBQztJQUMzQyxDQUFDLG1DQUFtQyxFQUFJLEVBQUUsQ0FBQztJQUMzQyxDQUFDLHFDQUFxQyxFQUFFLEVBQUUsQ0FBQztJQUMzQyxDQUFDLHFDQUFxQyxFQUFFLEVBQUUsQ0FBQztJQUMzQyxDQUFDLG1DQUFtQyxFQUFJLEVBQUUsQ0FBQztJQUMzQyxDQUFDLG1DQUFtQyxFQUFJLEVBQUUsQ0FBQztJQUMzQyxDQUFDLHFDQUFxQyxFQUFFLEVBQUUsQ0FBQztJQUMzQyxDQUFDLHFDQUFxQyxFQUFFLEVBQUUsQ0FBQztJQUMzQyxDQUFDLDhCQUE4QixFQUFTLEVBQUUsQ0FBQztBQUMzQyxJQUFBLENBQUMsa0RBQWtELEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN0RyxNQUFNLGFBQWEsR0FBYSxFQUFFLENBQUM7QUFDbkMsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDM0MsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5RSxDQUFBO0FBQ0ssU0FBVSxpQkFBaUIsQ0FBQyxJQUFZLEVBQUE7SUFFMUMsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ2xCLElBQUEsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFFLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFFekMsSUFBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzVCLEtBQUssR0FBRyxJQUFJLENBQUM7WUFDYixNQUFNO0FBQ1QsU0FBQTtBQUNKLEtBQUE7QUFFRCxJQUFBLE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxNQUFNLHVCQUF1QixHQUFhO0lBQ3RDLHNDQUFzQztJQUN0QyxzQ0FBc0M7SUFDdEMsd0NBQXdDO0lBQ3hDLHdDQUF3QztJQUN4QyxzQ0FBc0M7SUFDdEMsc0NBQXNDO0lBQ3RDLHdDQUF3QztJQUN4Qyx3Q0FBd0M7SUFDeEMsa0NBQWtDO0lBQ2xDLGtEQUFrRDtDQUNyRCxDQUFBO0FBQ0ssU0FBVSwrQkFBK0IsQ0FBQyxJQUFZLEVBQUE7QUFFeEQsSUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUUsdUJBQXVCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBRW5ELElBQUksV0FBVyxHQUFHLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN4RCxRQUFBLElBQUcsV0FBVyxFQUFFO0FBQ1osWUFBQSxPQUFPLFdBQVcsQ0FBQztBQUN0QixTQUFBO0FBQ0osS0FBQTtBQUNELElBQUEsT0FBTyxJQUFJLENBQUM7QUFDaEIsQ0FBQztBQUVELE1BQU0saUNBQWlDLEdBQWEsQ0FBQyxrQkFBa0I7SUFDbkIsa0JBQWtCO0lBQ2xCLG9CQUFvQjtBQUNwQixJQUFBLG9CQUFvQixDQUFDLENBQUE7QUFDekUsTUFBTSxnQ0FBZ0MsR0FBYSxFQUFFLENBQUM7QUFDdEQsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGlDQUFpQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUM5RCxJQUFBLGdDQUFnQyxDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0YsQ0FBQTtBQUNLLFNBQVUsNEJBQTRCLENBQUMsSUFBWSxFQUFBO0lBRXJELElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQztBQUNsQixJQUFBLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRSxnQ0FBZ0MsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFFNUQsSUFBRyxnQ0FBZ0MsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDL0MsS0FBSyxHQUFHLElBQUksQ0FBQztZQUNiLE1BQU07QUFDVCxTQUFBO0FBQ0osS0FBQTtBQUVELElBQUEsT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQztBQUVELE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxhQUFhO0lBQ2Isb0JBQW9CO0FBQ3BCLElBQUEsMEJBQTBCLENBQUMsQ0FBQztBQUM3RCxNQUFNLHNCQUFzQixHQUFhLEVBQUUsQ0FBQztBQUM1QyxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsdUJBQXVCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ3BELElBQUEsc0JBQXNCLENBQUMsSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2RSxDQUFBO0FBQ0ssU0FBVSxzQkFBc0IsQ0FBQyxJQUFZLEVBQUE7SUFFL0MsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ2xCLElBQUEsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFFLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUVsRCxJQUFHLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNyQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBQ2IsTUFBTTtBQUNULFNBQUE7QUFDSixLQUFBO0FBRUQsSUFBQSxPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDO0FBRUssU0FBVSxxQkFBcUIsQ0FBQyxJQUFZLEVBQUE7SUFFOUMsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ2xCLElBQUEsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdkIsSUFBQSxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQTtJQUNwQixJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7QUFDcEIsSUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUUsc0JBQXNCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBRWxELElBQUksU0FBUyxHQUFHLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNwRCxJQUFHLFNBQVMsS0FBSyxJQUFJLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFFM0MsS0FBSyxHQUFHLElBQUksQ0FBQztBQUNiLFlBQUEsYUFBYSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUE7QUFDL0IsWUFBQSxXQUFXLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUNsQyxZQUFBLFdBQVcsR0FBRyxhQUFhLEdBQUcsV0FBVyxDQUFDO1lBRTFDLElBQUksYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUE7QUFDM0MsWUFBQSxTQUFTLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO1lBQ25ELElBQUcsU0FBUyxLQUFLLElBQUksSUFBSSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFFM0MsS0FBSyxHQUFHLElBQUksQ0FBQztnQkFDYixXQUFXLElBQUksU0FBUyxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFBO0FBQ3ZELGFBQUE7WUFDRCxNQUFNO0FBQ1QsU0FBQTtBQUNKLEtBQUE7SUFFRCxPQUFPO1FBQ0gsS0FBSztRQUNMLGFBQWE7UUFDYixXQUFXO1FBQ1gsV0FBVztBQUNYLFFBQUEsVUFBVSxFQUFFLFdBQVc7S0FDMUIsQ0FBQztBQUNOLENBQUM7QUFFRCxNQUFNLHlCQUF5QixHQUFXO0lBQzFDLG9CQUFvQjtJQUNwQixvQkFBb0I7QUFDbkIsQ0FBQSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxHQUFHLEtBQUk7SUFDbkIsSUFBRyxJQUFJLEtBQUssRUFBRSxFQUFFO0FBQ1osUUFBQSxPQUFPLEdBQUcsQ0FBQztBQUNkLEtBQUE7QUFDRCxJQUFBLE9BQU8sQ0FBRyxFQUFBLElBQUksQ0FBSSxDQUFBLEVBQUEsR0FBRyxFQUFFLENBQUM7QUFDNUIsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFBO0FBQ04sTUFBTSxxQkFBcUIsR0FBVyxJQUFJLE1BQU0sQ0FBQyxDQUFZLFNBQUEsRUFBQSx5QkFBeUIsQ0FBYyxZQUFBLENBQUEsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUV0RyxTQUFVLGtCQUFrQixDQUFDLElBQVksRUFBQTtBQUUzQyxJQUFBLElBQUksV0FBVyxHQUFHLHNCQUFzQixFQUFFLENBQUM7QUFDM0MsSUFBQSxXQUFXLENBQUMsVUFBVSxHQUFHLFdBQVcsQ0FBQztJQUVyQyxJQUFJLFNBQVMsR0FBRyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDaEQsSUFBRyxTQUFTLEtBQUssSUFBSSxJQUFJLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0FBRTNDLFFBQUEsV0FBVyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDekIsUUFBQSxXQUFXLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUE7UUFDM0MsV0FBVyxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQzlDLFdBQVcsQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDLGFBQWEsR0FBRyxXQUFXLENBQUMsV0FBVyxDQUFDO0FBQ2pGLEtBQUE7QUFFRCxJQUFBLE9BQU8sV0FBVyxDQUFDO0FBQ3ZCLENBQUM7QUFDSyxTQUFVLHNCQUFzQixDQUFDLElBQVksRUFBQTtBQUMvQyxJQUFBLE9BQU8sa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFBO0FBQ3pDLENBQUM7QUFFSyxTQUFVLG1CQUFtQixDQUFDLElBQVksRUFBQTtBQUM1QyxJQUFBLE9BQU8sc0JBQXNCLENBQUMsSUFBSSxDQUFDLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzFGLENBQUM7QUFFSyxTQUFVLGNBQWMsQ0FBQyxXQUFtQixFQUFBO0lBRTlDLElBQUksSUFBSSxHQUFhLEVBQUUsQ0FBQztJQUN4QixJQUFJLElBQUksR0FBRyxXQUFXLENBQUE7QUFDdEIsSUFBQSxJQUFJLFlBQVksR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEMsT0FBTSxZQUFZLENBQUMsS0FBSyxFQUFFOztRQUd0QixJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7QUFFOUM7OztBQUdHO1FBQ0gsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QixJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQzs7QUFHckIsUUFBQSxJQUFJLEdBQUcsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUIsSUFBRyxHQUFHLEtBQUssSUFBSSxFQUFFO1lBQ2IsR0FBRyxHQUFHLEVBQUUsQ0FBQTtBQUNYLFNBQUE7QUFDRCxRQUFBLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7O0FBR2YsUUFBQSxZQUFZLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3JDLEtBQUE7SUFFRCxJQUFJLEdBQUcsV0FBVyxDQUFDO0FBQ25CLElBQUEsWUFBWSxHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLE9BQU0sWUFBWSxDQUFDLEtBQUssRUFBRTtBQUV0QixRQUFBLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDcEYsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBRTVDLFFBQUEsSUFBSSxHQUFHLEdBQUcsMkJBQTJCLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEQsSUFBRyxHQUFHLEtBQUssSUFBSSxFQUFFO1lBQ2IsR0FBRyxHQUFHLEVBQUUsQ0FBQTtBQUNYLFNBQUE7QUFDRCxRQUFBLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7O0FBR2YsUUFBQSxZQUFZLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDM0MsS0FBQTtJQUVELE9BQU8sRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUMvQyxDQUFDO0FBT0ssU0FBVSxxQkFBcUIsQ0FBQyxlQUF5QixFQUFBO0lBQzNELE9BQU8saUNBQWlDLENBQUMsZUFBZSxFQUFFO1FBQ3RELFlBQVk7UUFDWixrQkFBa0I7UUFDbEIsZUFBZTtBQUNsQixLQUFBLENBQUMsQ0FBQTtBQUNOLENBQUM7QUFFZSxTQUFBLGlDQUFpQyxDQUFDLGVBQXlCLEVBQ3pCLGVBQXlELEVBQUE7SUFJdkcsSUFBSSxZQUFZLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM5QyxJQUFBLElBQUksRUFBQyxZQUFZLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBQyxHQUFJLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRTlFLElBQUcsWUFBWSxLQUFLLElBQUksRUFBRTtBQUN0QixRQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsS0FBQTtBQUVELElBQUEsSUFBRyxZQUFZLENBQUMsS0FBSyxLQUFLLEtBQUssRUFBRTtBQUM3QixRQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsS0FBQTtBQUVELElBQUEsSUFBRyxZQUFZLENBQUMsVUFBVSxLQUFLLFdBQVcsRUFBRTtBQUV4QyxRQUFBLElBQUksZ0JBQWdCLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzdDLFFBQUEsSUFBRyxnQkFBZ0IsQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFO0FBQ2hDLFlBQUEsT0FBTyxJQUFJLENBQUM7QUFDZixTQUFBO0FBRUQsUUFBQSxJQUFJLGFBQWEsR0FBRywyQkFBMkIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM5RCxJQUFJLGVBQWUsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTVDLE9BQU8sRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsQ0FBQztBQUMxRSxLQUFBO0FBRUQsSUFBQSxJQUFHLFlBQVksQ0FBQyxVQUFVLEtBQUssVUFBVSxFQUFFO0FBRXZDLFFBQUEsSUFBSSxnQkFBZ0IsR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDN0MsUUFBQSxJQUFHLGdCQUFnQixDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUU7QUFDaEMsWUFBQSxPQUFPLElBQUksQ0FBQztBQUNmLFNBQUE7UUFFRCxJQUFJLGVBQWUsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzVDLFFBQUEsSUFBSSxhQUFhLEdBQUcsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBRWpELFFBQUEsSUFBSSxhQUFhLEdBQUcsbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUE7UUFDeEQsSUFBRyxhQUFhLEtBQUssSUFBSSxFQUFFO0FBRXZCLFlBQUEsYUFBYSxHQUFHLGFBQWEsQ0FBQyxFQUFFLENBQUM7QUFDakMsWUFBQSxJQUFHLGFBQWEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFO2dCQUN4QixlQUFlLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3BFLGFBQUE7QUFDSixTQUFBO1FBRUQsSUFBRyxhQUFhLEtBQUssSUFBSSxFQUFFO1lBQ3ZCLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFDdEIsU0FBQTtRQUVELE9BQU8sRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsQ0FBQztBQUN6RSxLQUFBO0FBRUQsSUFBQSxJQUFHLFlBQVksQ0FBQyxVQUFVLEtBQUssT0FBTyxFQUFFO0FBRXBDLFFBQUEsSUFBSSxnQkFBZ0IsR0FBRywwQkFBMEIsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUM1RCxRQUFBLElBQUcsZ0JBQWdCLENBQUMsS0FBSyxLQUFLLElBQUksRUFBRTtBQUNoQyxZQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsU0FBQTtRQUVELElBQUksZUFBZSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFNUMsSUFBSSxVQUFVLEdBQUcsa0JBQWtCLENBQUMsR0FBRyxZQUFZLENBQUEsQ0FBRSxDQUFDLENBQUM7QUFDdkQsUUFBQSxJQUFJLGFBQWEsR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztRQUVyRCxPQUFPO1lBQ0gsYUFBYTtZQUNiLGVBQWU7QUFDZixZQUFBLGNBQWMsRUFBRSxPQUFPO1NBQzFCLENBQUE7QUFDSixLQUFBO0FBRUQsSUFBQSxPQUFPLElBQUksQ0FBQztJQUVaLFNBQVMsZ0JBQWdCLENBQUMsWUFBb0IsRUFBQTtRQUUxQyxJQUFJLFNBQVMsR0FBRyxZQUFZLENBQUM7UUFDN0IsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsSUFBSSxZQUFZLEdBQXVCLElBQUksQ0FBQztRQUM1QyxJQUFJLFlBQVksR0FBRyxFQUFFLENBQUE7UUFDckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxHQUFHLEdBQUcsRUFBRTtnQkFDVCxNQUFNO0FBQ1QsYUFBQTtZQUVELElBQUksU0FBUyxHQUF5QixFQUFFLENBQUM7QUFDekMsWUFBQSxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxLQUFJO2dCQUM3QixTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ3BDLGFBQUMsQ0FBQyxDQUFDO1lBQ0gsU0FBUyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEtBQUk7QUFDakMsZ0JBQUEsT0FBTyxHQUFHLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQzthQUM3QixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSTtBQUNiLGdCQUFBLE9BQU8sQ0FBQyxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDO0FBQzdDLGFBQUMsQ0FBQyxDQUFDO0FBRUgsWUFBQSxJQUFJLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUN4QixNQUFNO0FBQ1QsYUFBQTtBQUVELFlBQUEsWUFBWSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixZQUFBLElBQUksVUFBVSxHQUFHLE1BQU0sR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDO0FBQ3JELFlBQUEsWUFBWSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLFVBQVUsR0FBRyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7WUFFL0YsTUFBTSxLQUFLLFlBQVksQ0FBQyxhQUFhLEdBQUcsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ2xFLFlBQUEsU0FBUyxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDMUMsU0FBQTtRQUVELE9BQU87WUFDSCxZQUFZO1lBQ1osWUFBWTtZQUNaLFNBQVM7U0FDWixDQUFBO0tBQ0o7QUFDTCxDQUFDO0FBRUQ7Ozs7Ozs7O0FBUUc7QUFDRyxTQUFVLHNCQUFzQixDQUFDLGVBQXlCLEVBQUE7SUFHNUQsT0FBTyxpQ0FBaUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO0FBQzlFLENBQUM7QUFFSyxTQUFVLGdCQUFnQixDQUFDLFVBQW9CLEVBQUE7OztJQUlqRCxJQUFJLGFBQWEsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLE9BQU8sS0FBSTtBQUNwRCxRQUFBLE9BQU8sSUFBSSxHQUFHLElBQUksR0FBSSxPQUFPLENBQUM7S0FDakMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNQLElBQUEsSUFBSSxnQkFBZ0IsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDakQsSUFBQSxJQUFJLGtCQUFrQixHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUVyRCxJQUFBLElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3ZCLElBQUcsZ0JBQWdCLENBQUMsS0FBSyxLQUFLLElBQUksSUFBSSxrQkFBa0IsQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFO0FBRXRFLFFBQUEsYUFBYSxHQUFHLGdCQUFnQixDQUFDLGFBQWEsQ0FBQztBQUNsRCxLQUFBO1NBQ0ksSUFBRyxnQkFBZ0IsQ0FBQyxLQUFLLEtBQUssS0FBSyxJQUFJLGtCQUFrQixDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUU7QUFFM0UsUUFBQSxhQUFhLEdBQUcsa0JBQWtCLENBQUMsYUFBYSxDQUFDO0FBQ3BELEtBQUE7U0FDSSxJQUFHLGdCQUFnQixDQUFDLEtBQUssS0FBSyxJQUFJLElBQUksa0JBQWtCLENBQUMsS0FBSyxLQUFLLElBQUksRUFBRTtBQUUxRSxRQUFBLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUM7QUFDL0MsUUFBQSxJQUFHLGtCQUFrQixDQUFDLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUU7QUFFbEU7Ozs7QUFJRztBQUNILFlBQUEsYUFBYSxHQUFHLGtCQUFrQixDQUFDLGFBQWEsQ0FBQztBQUNwRCxTQUFBO0FBQ0osS0FBQTtJQUVELE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFDOUMsQ0FBQztBQUVLLFNBQVUsY0FBYyxDQUFDLFFBQWdCLEVBQUE7SUFFM0MsSUFBSSxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNuQyxJQUFBLElBQUcsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUM7UUFDbkIsT0FBTyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQTtBQUN0QyxLQUFBO0FBRUQsSUFBQSxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBR0QsTUFBTSx3QkFBd0IsR0FBRyxPQUFPLENBQUM7QUFDekMsTUFBTSxvQkFBb0IsR0FBVyxJQUFJLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBQ3BFLFNBQVUsbUJBQW1CLENBQUMsY0FBd0IsRUFBQTtJQUV4RCxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDZCxJQUFBLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQzNDLFFBQUEsSUFBSSxJQUFJLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTdCLElBQUcsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNaLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0IsWUFBQSxJQUFHLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxXQUFXLEVBQUU7QUFDbEMsZ0JBQUEsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7QUFDakMsYUFBQTtBQUNKLFNBQUE7QUFDSSxhQUFBO0FBQ0QsWUFBQSxJQUFHLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFFaEMsT0FBTyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO0FBQy9CLGFBQUE7QUFDSixTQUFBO0FBQ0osS0FBQTtJQUVELElBQUcsRUFBRSxLQUFLLElBQUksRUFBRTtBQUNaLFFBQUEsT0FBTyxJQUFJLENBQUM7QUFDZixLQUFBO0FBQ0ksU0FBQTtRQUNELE9BQU8sRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFBO0FBQy9CLEtBQUE7QUFDTCxDQUFDO0FBQ0QsTUFBTSx1QkFBdUIsR0FBRyxLQUFLLENBQUM7QUFDdEMsTUFBTSxtQkFBbUIsR0FBVyxJQUFJLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQzs7QUMxa0J2RTs7Ozs7O0FBTUc7QUFJYSxTQUFBLE1BQU0sQ0FBQyxNQUFBLEdBQWlCLEVBQUUsRUFBQTtJQUV0QyxJQUFHLE1BQU0sR0FBRyxFQUFFLEVBQUU7UUFDWixNQUFNLEdBQUcsRUFBRSxDQUFDO0FBQ2YsS0FBQTtBQUNELElBQUEsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEQsR0FBRyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBRTNCLElBQUEsT0FBTyxHQUFHLENBQUM7QUFDZixDQUFDO0FBRUQ7Ozs7Ozs7QUFPRztBQUNhLFNBQUEseUJBQXlCLENBQUMsSUFBaUIsRUFBRSxZQUFvQixFQUFBO0FBRTdFLElBQUEsWUFBWSxHQUFHLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQUMxQyxJQUFBLElBQUksS0FBSyxHQUFrQixDQUFDLElBQUksQ0FBQyxDQUFBO0FBQ2pDLElBQUEsT0FBTSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBQztBQUNuQixRQUFBLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBRWxDLFlBQUEsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFBO1lBRXhCLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUE7WUFDMUMsSUFBRyxRQUFRLEtBQUssWUFBWSxFQUFFO0FBQzFCLGdCQUFBLE9BQU8sSUFBbUIsQ0FBQztBQUM5QixhQUFBO0FBRUQsWUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQWdCLENBQUMsQ0FBQTtBQUM5QyxhQUFBO0FBQ0osU0FBQTtBQUNKLEtBQUE7QUFFRCxJQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUM7QUE2Q0ssU0FBVSxlQUFlLENBQUMsVUFBa0IsRUFBQTtBQUU5QyxJQUFBLElBQUksUUFBUSxHQUFHLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN2QyxJQUFHLFFBQVEsS0FBSyxJQUFJLEVBQUU7QUFDbEIsUUFBQSxPQUFPLEtBQUssQ0FBQztBQUNoQixLQUFBO0FBQ0QsSUFBQSxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBRUssU0FBVSxXQUFXLENBQUMsVUFBa0IsRUFBQTtJQUUxQyxJQUFJLGNBQWMsR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUMvRCxJQUFBLElBQUcsY0FBYyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7QUFDNUIsUUFBQSxPQUFPLElBQUksQ0FBQztBQUNmLEtBQUE7QUFFRCxJQUFBLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBRTNDLFFBQUEsSUFBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUU7QUFDM0QsWUFBQSxPQUFPLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1QixTQUFBO0FBQ0osS0FBQTtBQUVELElBQUEsT0FBTyxJQUFJLENBQUM7QUFDaEI7O0FDdkhBOzs7Ozs7QUFNRztBQU1ILE1BQU0sWUFBWSxHQUFhLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDdEQsTUFBTSx1QkFBdUIsR0FBVyxzSEFBc0gsQ0FBQTtBQUU5SixJQUFZLFlBTVgsQ0FBQTtBQU5ELENBQUEsVUFBWSxZQUFZLEVBQUE7QUFDcEIsSUFBQSxZQUFBLENBQUEsWUFBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLE1BQUksQ0FBQTtBQUNKLElBQUEsWUFBQSxDQUFBLFlBQUEsQ0FBQSxhQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsR0FBQSxhQUFXLENBQUE7QUFDWCxJQUFBLFlBQUEsQ0FBQSxZQUFBLENBQUEsZ0JBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLGdCQUFjLENBQUE7QUFDZCxJQUFBLFlBQUEsQ0FBQSxZQUFBLENBQUEsYUFBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLEdBQUEsYUFBVyxDQUFBO0FBQ1gsSUFBQSxZQUFBLENBQUEsWUFBQSxDQUFBLFdBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLFdBQVMsQ0FBQTtBQUNiLENBQUMsRUFOVyxZQUFZLEtBQVosWUFBWSxHQU12QixFQUFBLENBQUEsQ0FBQSxDQUFBO0FBRUQsSUFBWSxzQkFLWCxDQUFBO0FBTEQsQ0FBQSxVQUFZLHNCQUFzQixFQUFBO0FBQzlCLElBQUEsc0JBQUEsQ0FBQSxzQkFBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLE1BQVEsQ0FBQTtBQUNSLElBQUEsc0JBQUEsQ0FBQSxzQkFBQSxDQUFBLFVBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLFVBQVEsQ0FBQTtBQUNSLElBQUEsc0JBQUEsQ0FBQSxzQkFBQSxDQUFBLFdBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLFdBQVMsQ0FBQTtBQUNULElBQUEsc0JBQUEsQ0FBQSxzQkFBQSxDQUFBLFVBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLFVBQVEsQ0FBQTtBQUNaLENBQUMsRUFMVyxzQkFBc0IsS0FBdEIsc0JBQXNCLEdBS2pDLEVBQUEsQ0FBQSxDQUFBLENBQUE7TUFFWSxTQUFTLENBQUE7SUFtQmxCLFdBQVksQ0FBQSxPQUFvQixFQUNwQixjQUF3QixFQUN4QixRQUFBLEdBQWtCLE1BQU0sRUFBRSxFQUMxQixHQUFBLEdBQW9CLFlBQVksQ0FBQyxJQUFJLEVBQUE7UUFuQmpELElBQWEsQ0FBQSxhQUFBLEdBQWdCLElBQUksQ0FBQztBQUdsQyxRQUFBLElBQUEsQ0FBQSxvQkFBb0IsR0FBMkIsc0JBQXNCLENBQUMsSUFBSSxDQUFDO1FBRTNFLElBQVcsQ0FBQSxXQUFBLEdBQXNCLFdBQVcsQ0FBQztRQUM3QyxJQUFnQixDQUFBLGdCQUFBLEdBQW1CLElBQUksQ0FBQztRQUN4QyxJQUFxQixDQUFBLHFCQUFBLEdBQUcsQ0FBQyxDQUFDO0FBRzFCLFFBQUEsSUFBQSxDQUFBLHVCQUF1QixHQUFXLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUM3QyxJQUFnQixDQUFBLGdCQUFBLEdBQUcsQ0FBQyxDQUFDO0FBRXJCLFFBQUEsSUFBQSxDQUFBLDJCQUEyQixHQUFXLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNqRCxJQUFnQixDQUFBLGdCQUFBLEdBQUcsQ0FBQyxDQUFDO1FBTWpCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUN4QyxRQUFBLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQy9CLFFBQUEsSUFBSSxDQUFDLEdBQUcsR0FBRyxRQUFRLENBQUM7QUFDcEIsUUFBQSxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUNmLFFBQUEsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEtBQUssQ0FBQTtBQUNqQyxRQUFBLElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO0FBRXJDLFFBQUEsSUFBRyxJQUFJLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxJQUFJLEVBQUU7WUFDL0IsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFBO0FBQ3pCLFNBQUE7OztBQUlELFFBQUEsSUFBRyxJQUFJLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxJQUFJLEVBQUU7WUFDL0IsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUE7QUFDcEMsU0FBQTtLQUNKO0FBRUQsSUFBQSxpQkFBaUIsQ0FBQyxVQUF1QixFQUFBO0FBQ3JDLFFBQUEsSUFBSSxDQUFDLGVBQWUsR0FBRyxVQUFVLENBQUM7QUFDbEMsUUFBQSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFBO0tBQ25DO0lBRUQsMkJBQTJCLEdBQUE7UUFFdkIsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQywyQkFBMkIsQ0FBQztRQUM5RCxJQUFHLFNBQVMsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUU7QUFFaEQsWUFBQSxPQUFPLElBQUksQ0FBQztBQUNmLFNBQUE7QUFFRCxRQUFBLE9BQU8sS0FBSyxDQUFDO0tBQ2hCO0lBRUQsb0JBQW9CLEdBQUE7UUFDaEIsSUFBSSxXQUFXLEdBQUcsWUFBWSxDQUFBO1FBQzlCLElBQUksRUFBQyxjQUFjLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBQyxHQUFHLDZCQUE2QixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsdUJBQXVCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUE7UUFDOUksSUFBRyxjQUFjLEtBQUssS0FBSyxFQUFDO0FBQ3hCLFlBQUEsT0FBTyxLQUFLLENBQUE7QUFDZixTQUFBO0FBQ0QsUUFBQSxJQUFJLENBQUMsdUJBQXVCLEdBQUcsVUFBVSxDQUFDO0FBQzFDLFFBQUEsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFVBQVUsQ0FBQTtBQUNsQyxRQUFBLE9BQU8sSUFBSSxDQUFBO0tBQ2Q7QUFFRCxJQUFBLG1CQUFtQixDQUFDLGdCQUE2QixFQUFBO0FBRTdDLFFBQUEsSUFBSSxDQUFDLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQztRQUN0QyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQTtLQUNsQztJQUVELHdCQUF3QixHQUFBO0FBQ3BCLFFBQUEsSUFBSSxDQUFDLDJCQUEyQixHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUM5QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0tBQzdGO0lBRU8sZUFBZSxHQUFBO0FBRW5CLFFBQUEsSUFBSSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLEtBQUk7QUFDOUQsWUFBQSxPQUFPLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQzlCLFNBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBRyxjQUFjLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFFMUQsWUFBQSxJQUFJLENBQUMsV0FBVyxHQUFHLFlBQVksQ0FBQztBQUNoQyxZQUFBLElBQUksQ0FBQyxHQUFHLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQzs7O0FBR3JDLFNBQUE7YUFDSSxJQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLEtBQUssSUFBSTtZQUNwRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxFQUFFO0FBRXJILFlBQUEsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUE7QUFDL0IsWUFBQSxJQUFJLENBQUMsR0FBRyxHQUFHLFlBQVksQ0FBQyxXQUFXLENBQUM7OztBQUd2QyxTQUFBO2FBQ0ksSUFBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxLQUFLLElBQUksRUFBRTtBQUVqRSxZQUFBLElBQUksQ0FBQyxXQUFXLEdBQUcsWUFBWSxDQUFBO0FBQy9CLFlBQUEsSUFBSSxDQUFDLEdBQUcsR0FBRyxZQUFZLENBQUMsV0FBVyxDQUFDOzs7QUFHdkMsU0FBQTtBQUNJLGFBQUEsSUFBRyxzQkFBc0IsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLElBQUksRUFBRTtBQUV4RCxZQUFBLElBQUksQ0FBQyxXQUFXLEdBQUcsWUFBWSxDQUFBOzs7O0FBSWxDLFNBQUE7S0FDSjtJQUVELDBCQUEwQixHQUFBO1FBQ3RCLFNBQVMsZUFBZSxDQUFDLElBQVksRUFBQTtBQUVqQyxZQUFBLElBQUksWUFBWSxHQUFHLCtCQUErQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pELElBQUcsbUJBQW1CLEtBQUssSUFBSSxFQUFFO0FBQzdCLGdCQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsYUFBQTtBQUVELFlBQUEsSUFBSSxVQUFVLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQztZQUNwQyxJQUFJLFFBQVEsR0FBRyxVQUFVLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUNuRCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNwQyxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBRWhDLFlBQUEsT0FBTyxDQUFHLEVBQUEsR0FBRyxDQUFHLEVBQUEsSUFBSSxFQUFFLENBQUM7U0FDMUI7QUFFRCxRQUFBLElBQUksYUFBYSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDO0FBQ25ELFFBQUEsSUFBSSxtQkFBbUIsR0FBRywrQkFBK0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN6RSxJQUFHLG1CQUFtQixLQUFLLElBQUksRUFBRTtBQUU3QixZQUFBLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDO0FBQzFDLFlBQUEsSUFBSSxVQUFVLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDO1lBQzNDLElBQUksUUFBUSxHQUFHLFVBQVUsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7WUFDMUQsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDcEMsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTs7OztBQUsvQixZQUFBLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7QUFDckMsWUFBQSxJQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxLQUFLLEtBQUssRUFBRTtnQkFDeEMsU0FBUyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBZ0IsQ0FBQztBQUMvRCxhQUFBO1lBRUQsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDO0FBQ3JCLFlBQUEsSUFBRyxTQUFTLENBQUMsUUFBUSxLQUFLLEdBQUcsRUFBRTs7O2dCQUkzQixTQUFTLEdBQUcsU0FBUyxDQUFDO2dCQUN0QixTQUFTLENBQUMsU0FBUyxHQUFHLENBQUEsRUFBRyxHQUFHLENBQUcsRUFBQSxJQUFJLEVBQUUsQ0FBQztBQUN6QyxhQUFBO2lCQUNJLElBQUcsU0FBUyxDQUFDLFFBQVEsS0FBSyxJQUFJLElBQUksU0FBUyxDQUFDLFFBQVEsS0FBSyxJQUFJLEVBQUU7Ozs7Z0JBS2hFLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQztBQUNwQixnQkFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUNwRCxJQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxLQUFLLElBQUksRUFBRTtBQUN4Qyx3QkFBQSxRQUFRLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDakMsTUFBTTtBQUNULHFCQUFBO0FBQ0osaUJBQUE7Z0JBRUQsSUFBRyxRQUFRLEtBQUssSUFBSSxFQUFFOztvQkFHakIsUUFBd0IsQ0FBQyxTQUFTLEdBQUcsZUFBZSxDQUFFLFFBQXdCLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDOUYsaUJBQUE7QUFDSixhQUFBO0FBQ0ksaUJBQUE7QUFDRCxnQkFBQSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQWlCLGNBQUEsRUFBQSxTQUFTLENBQUMsUUFBUSxDQUFBLG1EQUFBLENBQXFELEVBQUUsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDOzs7O0FBSXRJLGFBQUE7O1lBR0QsSUFBRyxVQUFVLEtBQUssQ0FBQyxFQUFFOztBQUVqQixnQkFBQSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsc0JBQXNCLENBQUMsUUFBUSxDQUFDO0FBQy9ELGFBQUE7QUFDSSxpQkFBQSxJQUFHLFFBQVEsS0FBSyxJQUFJLENBQUMsTUFBTSxFQUFFOztBQUU5QixnQkFBQSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsc0JBQXNCLENBQUMsU0FBUyxDQUFDO0FBQ2hFLGFBQUE7QUFDSSxpQkFBQTs7QUFFRCxnQkFBQSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsc0JBQXNCLENBQUMsUUFBUSxDQUFDO2dCQUU1RCxNQUFNLGVBQWUsR0FBRyx5QkFBeUIsQ0FBQztnQkFDbEQsTUFBTSxxQkFBcUIsR0FBRyxtQ0FBbUMsQ0FBQztBQUNsRSxnQkFBQSxJQUFHLFNBQVMsRUFBRTtvQkFDVixTQUFTLENBQUMsU0FBUyxHQUFHLENBQUcsRUFBQSxHQUFHLGtCQUFrQixlQUFlLENBQUEsQ0FBQSxFQUFJLHFCQUFxQixDQUFBLEVBQUEsRUFBSyx1QkFBdUIsQ0FBQSxXQUFBLEVBQWMsSUFBSSxDQUFFLENBQUEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBRW5LLGlCQUFBO0FBQ0osYUFBQTtBQUNKLFNBQUE7S0FDSjtBQUNKLENBQUE7QUFhSyxNQUFPLGlCQUFrQixTQUFRLFNBQVMsQ0FBQTtBQUs1QyxJQUFBLFdBQUEsQ0FBWSxhQUF3QixFQUFBO0FBRWhDLFFBQUEsS0FBSyxDQUFDLGFBQWEsQ0FBQyxlQUFlLEVBQUUsYUFBYSxDQUFDLGNBQWMsRUFBRSxhQUFhLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUw3RyxJQUFrQixDQUFBLGtCQUFBLEdBQWtCLEVBQUUsQ0FBQztBQUN2QyxRQUFBLElBQUEsQ0FBQSxnQkFBZ0IsR0FBa0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztLQUszRDtBQUVELElBQUEsZUFBZSxDQUFDLEtBQWEsRUFBQTtRQUV6QixJQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDakMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUM1QyxTQUFBO0FBRUQsUUFBQSxJQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFO0FBRXZDLFlBQUEsSUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDLHNCQUFzQixDQUFDLHlCQUF5QixDQUFDLENBQUE7QUFDcEcsWUFBQSxJQUFHLGFBQWEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO0FBQzFCLGdCQUFBLGFBQWEsQ0FBQyxDQUFDLENBQXNCLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDbEQsYUFBQTs7OztBQUlKLFNBQUE7S0FDSjtBQUVELElBQUEsa0JBQWtCLENBQUMsS0FBYSxFQUFBOztRQUc1QixJQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxFQUFFO0FBRTNDLFlBQUEsSUFBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRTtBQUV2QyxnQkFBQSxJQUFJLGFBQWEsR0FBRyxDQUFBLEVBQUEsR0FBQSxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLE1BQUUsSUFBQSxJQUFBLEVBQUEsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBQSxFQUFBLENBQUEsc0JBQXNCLENBQUMseUJBQXlCLENBQUMsQ0FBQTtnQkFDckcsSUFBRyxDQUFBLGFBQWEsS0FBQSxJQUFBLElBQWIsYUFBYSxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFiLGFBQWEsQ0FBRSxNQUFNLEtBQUksQ0FBQyxFQUFFO0FBRTNCLG9CQUFBLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFHLGFBQWEsQ0FBQyxDQUFDLENBQXNCLENBQUMsQ0FBQTtBQUMzRSxpQkFBQTs7OztBQUlKLGFBQUE7QUFDSixTQUFBO1FBQ0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQzNDO0lBRUQsT0FBTyx1QkFBdUIsQ0FBQyxVQUFxQixFQUFBO0FBRWhELFFBQUEsSUFBRyxVQUFVLENBQUMsZUFBZSxDQUFDLHNCQUFzQixDQUFDLGdCQUFnQixDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRztBQUVoRixZQUFBLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUM1QyxTQUFBO0FBRUQsUUFBQSxPQUFPLFVBQVUsQ0FBQztLQUNyQjtJQUVELE9BQU8sZ0JBQWdCLENBQUMsRUFBZSxFQUFBO1FBRW5DLElBQUksZ0JBQWdCLEdBQUcsRUFBRSxDQUFDLHNCQUFzQixDQUFDLHlCQUF5QixDQUFDLENBQUE7QUFDM0UsUUFBQSxJQUFHLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7QUFFOUIsWUFBQSxPQUFPLGdCQUFnQixDQUFDLENBQUMsQ0FBZ0IsQ0FBQztBQUM3QyxTQUFBO0FBRUQsUUFBQSxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFnQixDQUFBO0tBQ3ZDO0FBQ0osQ0FBQTtBQUVELFNBQVMsNkJBQTZCLENBQUMsV0FBcUIsRUFBRSx1QkFBK0IsRUFBRSxnQkFBd0IsRUFBQTtJQUNuSCxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsdUJBQXVCLENBQUE7QUFDcEQsSUFBQSxJQUFHLFNBQVMsR0FBRyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtBQUMxQyxRQUFBLHVCQUF1QixHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNyQyxRQUFBLGdCQUFnQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2hGLE9BQU87QUFDSCxZQUFBLGNBQWMsRUFBRSxJQUFJO0FBQ3BCLFlBQUEsVUFBVSxFQUFFLHVCQUF1QjtBQUNuQyxZQUFBLFVBQVUsRUFBRSxnQkFBZ0I7U0FDL0IsQ0FBQTtBQUNKLEtBQUE7SUFFRCxPQUFPO0FBQ0gsUUFBQSxjQUFjLEVBQUUsS0FBSztBQUNyQixRQUFBLFVBQVUsRUFBRSx1QkFBdUI7QUFDbkMsUUFBQSxVQUFVLEVBQUUsZ0JBQWdCO0tBQy9CLENBQUE7QUFDTDs7QUNoVkE7Ozs7OztBQU1HO0FBRUgsSUFBWSxvQkFtRFgsQ0FBQTtBQW5ERCxDQUFBLFVBQVksb0JBQW9CLEVBQUE7QUFFNUIsSUFBQSxvQkFBQSxDQUFBLHdCQUFBLENBQUEsR0FBQSwyQkFBb0QsQ0FBQTtBQUNwRCxJQUFBLG9CQUFBLENBQUEseUJBQUEsQ0FBQSxHQUFBLGlDQUEyRCxDQUFBO0FBQzNELElBQUEsb0JBQUEsQ0FBQSwyQkFBQSxDQUFBLEdBQUEsMkJBQXVELENBQUE7QUFDdkQsSUFBQSxvQkFBQSxDQUFBLDBCQUFBLENBQUEsR0FBQSw2QkFBd0QsQ0FBQTtBQUN4RCxJQUFBLG9CQUFBLENBQUEsNEJBQUEsQ0FBQSxHQUFBLDRCQUF5RCxDQUFBO0FBQ3pELElBQUEsb0JBQUEsQ0FBQSxxQkFBQSxDQUFBLEdBQUEsNkJBQW1ELENBQUE7QUFDbkQsSUFBQSxvQkFBQSxDQUFBLG1CQUFBLENBQUEsR0FBQSwyQkFBK0MsQ0FBQTtBQUUvQyxJQUFBLG9CQUFBLENBQUEsNkJBQUEsQ0FBQSxHQUFBLG9DQUFrRSxDQUFBO0FBQ2xFLElBQUEsb0JBQUEsQ0FBQSw2QkFBQSxDQUFBLEdBQUEsb0NBQWtFLENBQUE7QUFDbEUsSUFBQSxvQkFBQSxDQUFBLHlCQUFBLENBQUEsR0FBQSwrQkFBeUQsQ0FBQTtBQUN6RCxJQUFBLG9CQUFBLENBQUEseUJBQUEsQ0FBQSxHQUFBLCtCQUF5RCxDQUFBO0FBRXpELElBQUEsb0JBQUEsQ0FBQSxlQUFBLENBQUEsR0FBQSw0QkFBNEMsQ0FBQTtBQUM1QyxJQUFBLG9CQUFBLENBQUEsaUJBQUEsQ0FBQSxHQUFBLDhCQUFnRCxDQUFBO0FBQ2hELElBQUEsb0JBQUEsQ0FBQSxnQkFBQSxDQUFBLEdBQUEsNkJBQThDLENBQUE7QUFFOUMsSUFBQSxvQkFBQSxDQUFBLGdCQUFBLENBQUEsR0FBQSxxQkFBc0MsQ0FBQTtBQUV0QyxJQUFBLG9CQUFBLENBQUEsY0FBQSxDQUFBLEdBQUEsb0JBQW1DLENBQUE7QUFFbkMsSUFBQSxvQkFBQSxDQUFBLG9CQUFBLENBQUEsR0FBQSwwQkFBK0MsQ0FBQTtBQUUvQyxJQUFBLG9CQUFBLENBQUEsb0JBQUEsQ0FBQSxHQUFBLDBCQUErQyxDQUFBOztBQUkvQyxJQUFBLG9CQUFBLENBQUEsbUJBQUEsQ0FBQSxHQUFBLHlCQUE2QyxDQUFBO0FBQzdDLElBQUEsb0JBQUEsQ0FBQSxpQkFBQSxDQUFBLEdBQUEsMEJBQTRDLENBQUE7QUFDNUMsSUFBQSxvQkFBQSxDQUFBLG1CQUFBLENBQUEsR0FBQSx5QkFBNkMsQ0FBQTtBQUM3QyxJQUFBLG9CQUFBLENBQUEsa0JBQUEsQ0FBQSxHQUFBLHdCQUEyQyxDQUFBO0FBRTNDLElBQUEsb0JBQUEsQ0FBQSx3QkFBQSxDQUFBLEdBQUEsMkJBQW9ELENBQUE7QUFDcEQsSUFBQSxvQkFBQSxDQUFBLDBCQUFBLENBQUEsR0FBQSw2QkFBd0QsQ0FBQTtBQUN4RCxJQUFBLG9CQUFBLENBQUEseUJBQUEsQ0FBQSxHQUFBLDRCQUFzRCxDQUFBOztBQUl0RCxJQUFBLG9CQUFBLENBQUEsaUJBQUEsQ0FBQSxHQUFBLHVCQUF5QyxDQUFBO0FBRXpDLElBQUEsb0JBQUEsQ0FBQSxnQkFBQSxDQUFBLEdBQUEsc0JBQXVDLENBQUE7QUFDdkMsSUFBQSxvQkFBQSxDQUFBLGdCQUFBLENBQUEsR0FBQSxzQkFBdUMsQ0FBQTs7QUFJdkMsSUFBQSxvQkFBQSxDQUFBLG1CQUFBLENBQUEsR0FBQSx5QkFBNkMsQ0FBQTtBQUU3QyxJQUFBLG9CQUFBLENBQUEsbUJBQUEsQ0FBQSxHQUFBLHdCQUE0QyxDQUFBO0FBQzVDLElBQUEsb0JBQUEsQ0FBQSxtQkFBQSxDQUFBLEdBQUEsd0JBQTRDLENBQUE7QUFDaEQsQ0FBQyxFQW5EVyxvQkFBb0IsS0FBcEIsb0JBQW9CLEdBbUQvQixFQUFBLENBQUEsQ0FBQSxDQUFBO0FBRUQsSUFBWSxtQkFZWCxDQUFBO0FBWkQsQ0FBQSxVQUFZLG1CQUFtQixFQUFBO0FBRTNCLElBQUEsbUJBQUEsQ0FBQSxvQkFBQSxDQUFBLEdBQUEsMEJBQStDLENBQUE7QUFDL0MsSUFBQSxtQkFBQSxDQUFBLGdCQUFBLENBQUEsR0FBQSw2QkFBOEMsQ0FBQTtBQUM5QyxJQUFBLG1CQUFBLENBQUEsZUFBQSxDQUFBLEdBQUEsNEJBQTRDLENBQUE7QUFDNUMsSUFBQSxtQkFBQSxDQUFBLGNBQUEsQ0FBQSxHQUFBLDRCQUEyQyxDQUFBO0FBQzNDLElBQUEsbUJBQUEsQ0FBQSxjQUFBLENBQUEsR0FBQSw4QkFBNkMsQ0FBQTtBQUM3QyxJQUFBLG1CQUFBLENBQUEsY0FBQSxDQUFBLEdBQUEsbUJBQWtDLENBQUE7QUFDbEMsSUFBQSxtQkFBQSxDQUFBLGNBQUEsQ0FBQSxHQUFBLG1CQUFrQyxDQUFBO0FBQ2xDLElBQUEsbUJBQUEsQ0FBQSxjQUFBLENBQUEsR0FBQSxtQkFBa0MsQ0FBQTtBQUNsQyxJQUFBLG1CQUFBLENBQUEsZUFBQSxDQUFBLEdBQUEsZ0JBQWdDLENBQUE7QUFDaEMsSUFBQSxtQkFBQSxDQUFBLFdBQUEsQ0FBQSxHQUFBLHdCQUFvQyxDQUFBO0FBQ3hDLENBQUMsRUFaVyxtQkFBbUIsS0FBbkIsbUJBQW1CLEdBWTlCLEVBQUEsQ0FBQSxDQUFBLENBQUE7QUFFRCxJQUFZLGdCQUVYLENBQUE7QUFGRCxDQUFBLFVBQVksZ0JBQWdCLEVBQUE7QUFDeEIsSUFBQSxnQkFBQSxDQUFBLGtCQUFBLENBQUEsR0FBQSxtQkFBc0MsQ0FBQTtBQUMxQyxDQUFDLEVBRlcsZ0JBQWdCLEtBQWhCLGdCQUFnQixHQUUzQixFQUFBLENBQUEsQ0FBQTs7QUM3RUQ7Ozs7O0FBS0c7QUEyQkcsU0FBVSxvQkFBb0IsQ0FBQyxPQUFvQixFQUFBO0FBRXJELElBQUEsSUFBRyxjQUFjLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFO0FBQ2pDLFFBQUEsT0FBTyxZQUFZLENBQUE7QUFDdEIsS0FBQTtBQUVELElBQUEsSUFBRyxnQ0FBZ0MsQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFDbkQsUUFBQSxPQUFPLGNBQWMsQ0FBQTtBQUN4QixLQUFBO0FBRUQsSUFBQSxJQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFDaEMsUUFBQSxPQUFPLGFBQWEsQ0FBQTtBQUN2QixLQUFBO0FBRUQ7Ozs7QUFJRztBQUNILElBQUEsSUFBRyxXQUFXLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFO0FBQzlCLFFBQUEsT0FBTyxnQkFBZ0IsQ0FBQTtBQUMxQixLQUFBO0FBQ0ksU0FBQSxJQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRTtBQUN6QixRQUFBLE9BQU8sVUFBVSxDQUFBO0FBQ3BCLEtBQUE7QUFDSSxTQUFBLElBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQyxFQUFFO0FBQzlCLFFBQUEsT0FBTyxlQUFlLENBQUE7QUFDekIsS0FBQTtBQUVEOzs7OztBQUtHO0FBQ0gsSUFBQSxJQUFJLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksRUFBRTtBQUN2QyxRQUFBLE9BQU8sdUJBQXVCLENBQUE7QUFDakMsS0FBQTtBQUNELElBQUEsSUFBSSxhQUFhLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFO0FBQ2pDLFFBQUEsT0FBTyxpQkFBaUIsQ0FBQTtBQUMzQixLQUFBO0FBQ0QsSUFBQSxJQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksRUFBRTtBQUNwQyxRQUFBLE9BQU8scUJBQXFCLENBQUE7QUFDL0IsS0FBQTtBQUVEOzs7Ozs7OztBQVFHO0FBQ0gsSUFBQSxJQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFDaEMsUUFBQSxPQUFPLFlBQVksQ0FBQTtBQUN0QixLQUFBO0FBQ0ksU0FBQSxJQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFDckMsUUFBQSxPQUFPLG1CQUFtQixDQUFBO0FBQzdCLEtBQUE7QUFDSSxTQUFBLElBQUcsaUJBQWlCLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFO0FBQ3pDLFFBQUEsT0FBTyxnQkFBZ0IsQ0FBQTtBQUMxQixLQUFBO0FBRUQ7Ozs7QUFJRztBQUNILElBQUEsSUFBRyxhQUFhLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFO0FBQ2hDLFFBQUEsT0FBTyxZQUFZLENBQUE7QUFDdEIsS0FBQTtBQUNJLFNBQUEsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFO0FBRWpDLFFBQUEsT0FBTyxhQUFhLENBQUE7QUFDdkIsS0FBQTtBQUNJLFNBQUEsSUFBRyxjQUFjLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFO0FBRXRDLFFBQUEsT0FBTyxtQkFBbUIsQ0FBQTtBQUM3QixLQUFBO0FBRUQ7Ozs7O0FBS0c7SUFDSCxJQUFHLFlBQVksQ0FBQyxPQUFPLENBQUM7UUFDckIsU0FBUyxDQUFDLE9BQU8sQ0FBQztRQUNsQixPQUFPLENBQUMsT0FBTyxDQUFDO1FBQ2hCLGdCQUFnQixDQUFDLE9BQU8sQ0FBQztRQUN6QixPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUU7QUFFakIsUUFBQSxPQUFPLGNBQWMsQ0FBQTtBQUN4QixLQUFBOztBQUdELElBQUEsT0FBTyxlQUFlLENBQUE7QUFDMUIsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLE9BQW9CLEVBQUE7SUFDdEMsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUssU0FBVSxTQUFTLENBQUMsT0FBb0IsRUFBQTtBQUUxQyxJQUFBLElBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO0FBQ25DLFFBQUEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO0FBQ25DLFFBQUEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO0FBQ25DLFFBQUEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO0FBQ25DLFFBQUEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO0FBQ25DLFFBQUEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUU7QUFFcEMsUUFBQSxPQUFPLElBQUksQ0FBQztBQUNmLEtBQUE7QUFFRCxJQUFBLE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxTQUFTLE9BQU8sQ0FBQyxPQUFvQixFQUFBO0FBRWpDLElBQUEsSUFBRyxPQUFPLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7QUFDbkMsUUFBQSxPQUFPLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRTtBQUNwQyxRQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsS0FBQTtBQUVELElBQUEsT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLE9BQW9CLEVBQUE7SUFDdkMsT0FBTyxPQUFPLENBQUMsc0JBQXNCLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUM5RCxPQUFPLENBQUMsc0JBQXNCLENBQUMseUJBQXlCLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO0FBQ25GLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxPQUFvQixFQUFBO0lBQ3ZDLE9BQU8sT0FBTyxDQUFDLHNCQUFzQixDQUFDLGFBQWEsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7QUFDdEUsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLE9BQW9CLEVBQUE7SUFDdkMsT0FBTyxPQUFPLENBQUMsc0JBQXNCLENBQUMsWUFBWSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQztBQUNyRSxDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUMsT0FBb0IsRUFBQTtBQUVsQyxJQUFBLElBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBRTVCLE9BQU8sT0FBTyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLEtBQUssUUFBUSxDQUFDO0FBQ2pFLEtBQUE7QUFFRCxJQUFBLE9BQU8sS0FBSyxDQUFBO0FBQ2hCLENBQUM7QUFFSyxTQUFVLGFBQWEsQ0FBQyxPQUFvQixFQUFBO0FBQzlDLElBQUEsT0FBTyxPQUFPLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDO1FBQy9DLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUE7QUFDdkUsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsT0FBb0IsRUFBQTtJQUMxQyxPQUFPLE9BQU8sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFBO0FBQzlDLENBQUM7QUFFRCxTQUFTLE9BQU8sQ0FBQyxPQUFvQixFQUFBO0lBQ2pDLE9BQU8sT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUE7QUFDakQsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsT0FBb0IsRUFBQTtJQUMzQyxPQUFPLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxjQUFjLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO0FBQ3ZFLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxPQUFvQixFQUFBO0FBRXJDLElBQUEsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLHNCQUFzQixDQUFDLHlCQUF5QixDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQztBQUN4RixJQUFBLE9BQU8sVUFBVSxDQUFDO0FBQ3RCLENBQUM7QUFFRCxTQUFTLGlCQUFpQixDQUFDLE9BQW9CLEVBQUE7QUFDM0MsSUFBQSxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsc0JBQXNCLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO0FBQ3RGLElBQUEsT0FBTyxVQUFVLENBQUM7QUFDdEIsQ0FBQztBQUVELFNBQVMsbUJBQW1CLENBQUMsT0FBb0IsRUFBQTtBQUU3QyxJQUFBLElBQUksWUFBWSxHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7SUFDNUYsSUFBSSxNQUFNLEdBQUcseUJBQXlCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBRTFEOzs7QUFHRztBQUNILElBQUEsT0FBTyxNQUFNLEtBQUssSUFBSSxJQUFJLFlBQVksQ0FBQTtBQUMxQyxDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsT0FBb0IsRUFBQTtBQUV2QyxJQUFBLElBQUksWUFBWSxHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7QUFDNUYsSUFBQSxPQUFPLFlBQVksQ0FBQTtBQUN2QixDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsT0FBb0IsRUFBQTtBQUN6QyxJQUFBLElBQUksT0FBTyxHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7QUFDNUUsSUFBQSxPQUFPLE9BQU8sQ0FBQztBQUNuQixDQUFDO0FBRUQsU0FBUyxVQUFVLENBQUMsT0FBb0IsRUFBQTtBQUNwQyxJQUFBLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO0FBQzFFLElBQUEsT0FBTyxVQUFVLENBQUM7QUFDdEIsQ0FBQztBQUVLLFNBQVUseUJBQXlCLENBQUMsT0FBb0IsRUFBQTtJQUUxRCxJQUFHLE9BQU8sS0FBSyxJQUFJLEVBQUU7QUFDakIsUUFBQSxPQUFPLElBQUksQ0FBQztBQUNmLEtBQUE7SUFFRCxJQUFJLGFBQWEsR0FBRyxPQUFPLENBQUMsc0JBQXNCLENBQUMsNEJBQTRCLENBQUMsQ0FBQTtBQUNoRixJQUFBLElBQUcsYUFBYSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7QUFDM0IsUUFBQSxPQUFPLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMzQixLQUFBO0FBQ0QsSUFBQSxJQUFHLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBRTVCO0FBQ0QsSUFBQSxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsT0FBb0IsRUFBQTtBQUN4QyxJQUFBLElBQUksT0FBTyxHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7QUFDakYsSUFBQSxPQUFPLE9BQU8sQ0FBQztBQUNuQixDQUFDO0FBRUssU0FBVSxnQ0FBZ0MsQ0FBQyxPQUFvQixFQUFBO0FBRWpFLElBQUEsSUFBRyxPQUFPLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDLEVBQUU7QUFDMUMsUUFBQSxPQUFPLElBQUksQ0FBQztBQUNmLEtBQUE7SUFFRCxJQUFJLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25GLElBQUEsSUFBRyxpQkFBaUIsRUFBRTtBQUNsQixRQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsS0FBQTtBQUVELElBQUEsT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQztBQUVELFNBQVMsY0FBYyxDQUFDLE9BQW9CLEVBQUE7SUFFeEMsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pELElBQUcsR0FBRyxLQUFLLElBQUk7UUFDWixHQUFHLEtBQUssU0FBUyxFQUFFO0FBRWxCLFFBQUEsT0FBTyxLQUFLLENBQUM7QUFDaEIsS0FBQTtBQUNELElBQUEsT0FBTyxJQUFJLENBQUM7QUFDaEI7O0FDNVJBOzs7Ozs7QUFNRztNQWtCbUIsYUFBYSxDQUFBO0FBRy9CLElBQUEsSUFBVyxnQkFBZ0IsR0FBQTtBQUN2QixRQUFBLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7S0FDOUI7QUFHRCxJQUFBLElBQVcsWUFBWSxHQUFBO1FBQ25CLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztLQUM3QjtJQUNELElBQVcsWUFBWSxDQUFDLEtBQWtCLEVBQUE7QUFDdEMsUUFBQSxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztLQUM5QjtBQU9ELElBQUEsSUFBVyxZQUFZLEdBQUE7UUFDbkIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO0tBQzdCO0lBQ0QsSUFBYyxZQUFZLENBQUMsS0FBeUIsRUFBQTtBQUNoRCxRQUFBLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO0tBQzlCO0lBQ00sa0JBQWtCLENBQUMsVUFBOEIsRUFBRSxXQUEyQixFQUFBO0FBQ2pGLFFBQUEsT0FBTSxXQUFXLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7QUFDbkMsWUFBQSxXQUFXLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUc7QUFDbkMsZ0JBQUEsV0FBVyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQTtBQUNsQyxhQUFDLENBQUMsQ0FBQTtBQUNMLFNBQUE7QUFDRCxRQUFBLElBQUksQ0FBQyxhQUFhLEdBQUcsVUFBVSxDQUFDO0FBQ2hDLFFBQUEsSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsQ0FBQTtLQUN2RDtBQUVELElBQUEsV0FBQSxDQUFZLElBQXVCLEVBQUE7UUFsQ3pCLElBQU8sQ0FBQSxPQUFBLEdBQWdCLEVBQUUsQ0FBQztBQUkxQixRQUFBLElBQUEsQ0FBQSxZQUFZLEdBQTJCLElBQUksR0FBRyxFQUFFLENBQUM7UUFVakQsSUFBZ0IsQ0FBQSxnQkFBQSxHQUF3Qiw2QkFBNkIsRUFBRSxDQUFDO0FBcUI5RSxRQUFBLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUM1QixRQUFBLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztBQUN0QyxRQUFBLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztBQUV0QyxRQUFBLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztBQUNwQyxRQUFBLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7QUFFOUMsUUFBQSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDaEMsUUFBQSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUE7S0FDeEM7SUFFTSxhQUFhLEdBQUE7UUFFaEIsT0FBTztZQUNILE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVk7WUFDL0IsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1lBRS9CLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztZQUM3QixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO1lBRXZDLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztBQUN6QixZQUFBLFdBQVcsRUFBRSxJQUFJO1lBQ2pCLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtTQUNsQyxDQUFDO0tBQ0w7QUFFRDs7Ozs7O0FBTUc7QUFDSSxJQUFBLFNBQVMsQ0FBQyxhQUE2QixFQUFFLGFBQTZCLEVBQUUsR0FBYyxFQUFBO1FBRXpGLElBQUksT0FBTyxHQUFHLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFnQixDQUFDO0FBRXZELFFBQUEsSUFBSSxVQUFVLEdBQUcsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7QUFFL0MsUUFBQSxJQUFJLGFBQWEsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUVuQzs7Ozs7OztBQU9HO1lBQ0gsSUFBSSxvQkFBb0IsR0FBRyxFQUFFLENBQUE7WUFDN0IsSUFBSSxpQkFBaUIsR0FBRyxDQUFDLENBQUM7QUFDMUIsWUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLGFBQWEsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUV4RCxJQUFJLEdBQUcsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBZ0IsQ0FBQztBQUNuRCxnQkFBQSxJQUFHLEdBQUcsQ0FBQyxTQUFTLEtBQUssRUFBRSxFQUFFO0FBRXJCLG9CQUFBLG9CQUFvQixHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUM7b0JBQ3JDLE1BQU07QUFDVCxpQkFBQTtBQUVELGdCQUFBLGlCQUFpQixFQUFFLENBQUM7QUFDdkIsYUFBQTtBQUVELFlBQUEsS0FBSyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDL0MsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxvQkFBb0IsRUFBRTtBQUNsRCxvQkFBQSxVQUFVLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxpQkFBaUIsQ0FBQztvQkFDdkMsTUFBTTtBQUNULGlCQUFBO0FBQ0osYUFBQTtBQUNKLFNBQUE7UUFFRCxJQUFJLFdBQVcsR0FBRyxVQUFVLENBQUM7UUFFN0IsSUFBSSxPQUFPLEtBQUssU0FBUyxFQUFFO0FBR3ZCLFlBQWMsT0FBTyxDQUFDLFNBQVMsQ0FBQztBQUVoQyxZQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsVUFBVSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUVuRCxnQkFBQSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEVBQUU7b0JBRXRELFdBQVcsR0FBRyxDQUFDLENBQUM7b0JBRWhCLE1BQU07QUFDVCxpQkFBQTtBQUNKLGFBQUE7QUFDSixTQUFBOztBQUdELFFBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLFdBQVcsR0FBRyxVQUFVLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQzs7Ozs7OztBQVFwQyxRQUFBLE9BQU8sVUFBVSxDQUFDO0tBQ3JCO0lBRU0sZ0JBQWdCLENBQUMsR0FBYyxFQUFFLEtBQWEsRUFBQTtRQUVqRCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7S0FDdkM7QUFFTSxJQUFBLFlBQVksQ0FBQyxTQUFpQixFQUFBOzs7Ozs7OztRQVFqQyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMzQyxRQUFBLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXBDLElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRTtZQUNuQixPQUFPO0FBQ1YsU0FBQTtRQUVELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUU7QUFDNUIsWUFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM1QixTQUFBO0FBRUQsUUFBQSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLElBQUksRUFBRTtZQUN4RCxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDakQsU0FBQTs7O0tBSUo7SUFFTSxnQkFBZ0IsQ0FBQyxTQUFpQixFQUFFLE1BQW9CLEVBQUE7UUFFM0QsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDM0MsUUFBQSxHQUFHLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztLQUNwQjtBQUVNLElBQUEsbUJBQW1CLENBQUMsY0FBbUMsRUFBQTtBQUMxRCxRQUFBLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxjQUFjLENBQUM7S0FDMUM7QUFFRDs7Ozs7O0FBTUc7SUFDSSxtQkFBbUIsR0FBQTtRQUV0QixPQUFPO1lBQ0gsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLFlBQVk7WUFDdEMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtZQUMzQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU87U0FDM0IsQ0FBQztLQUNMO0FBRUQ7Ozs7O0FBS0c7SUFDSSx1QkFBdUIsR0FBQTtBQUcxQixRQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUUxQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxFQUFFO0FBQ2pDLGdCQUFBLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLFlBQVk7QUFDL0Usb0JBQUEsbUJBQW1CLENBQUMsWUFBWTtBQUNoQyxvQkFBQSxtQkFBbUIsQ0FBQyxjQUFjO0FBQ2xDLG9CQUFBLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsYUFBYSxFQUFFO29CQUMvQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDOUYsaUJBQUE7QUFDSixhQUFBO0FBQ0osU0FBQTtLQUNKO0lBRU0sS0FBSyxHQUFBO1FBQ1IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0tBQ3pCO0lBRU0sc0JBQXNCLEdBQUE7QUFDekI7Ozs7Ozs7Ozs7O0FBV0c7QUFDSCxRQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUUxQyxJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztZQUM5QyxJQUFHLFdBQVcsS0FBSyxZQUFZLEVBQUU7Z0JBQzdCLFNBQVM7QUFDWixhQUFBO0FBRUQ7OztBQUdHO1lBQ0gsSUFBRyxXQUFXLEtBQUssV0FBVztBQUMzQixnQkFBQSxXQUFXLEtBQUssY0FBYztnQkFDOUIsV0FBVyxLQUFLLGVBQWUsRUFBRTs7O0FBSWhDLGdCQUFBLFdBQVcsR0FBRyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBQ3ZFLGFBQUE7WUFFRCxJQUFJLFdBQVcsR0FBSSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBdUIsQ0FBQTtBQUN4RDs7QUFFRztBQUNILFlBQUEsSUFBSSxXQUFXO2dCQUNYLFdBQVcsS0FBSyxpQkFBaUIsRUFBRTtnQkFFbkMsSUFBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLDJCQUEyQixFQUFFLEVBQUU7b0JBRTlDLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUIsb0JBQUEsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFzQixFQUFFLElBQUksQ0FBQyxDQUFDO0FBQzlFLGlCQUFBO0FBQ0kscUJBQUE7b0JBQ0QsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFzQixDQUFDLENBQUE7QUFDdkUsaUJBQUE7Z0JBQ0QsU0FBUTtBQUNYLGFBQUE7QUFFRCxZQUFBLElBQUksV0FBVztnQkFDWCxXQUFXLEtBQUssY0FBYyxFQUFFO2dCQUVoQyxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQXNCLENBQUMsQ0FBQztnQkFDckUsU0FBUTtBQUNYLGFBQUE7WUFFRCxJQUFHLFdBQVcsS0FBSyxjQUFjLEVBQUU7Z0JBQy9CLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxHQUFHLGNBQWMsQ0FBQTtnQkFDNUMsU0FBUztBQUNaLGFBQUE7QUFFRCxZQUFBLElBQUcsV0FBVyxLQUFLLFlBQVksRUFBRTtnQkFDN0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO2dCQUMxQyxTQUFTO0FBQ1osYUFBQTtZQUVELElBQUcsV0FBVyxLQUFLLGNBQWMsRUFBRTtnQkFDL0IseUJBQXlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUMxQyxTQUFTO0FBQ1osYUFBQTtZQUVELElBQUcsV0FBVyxLQUFLLFVBQVUsRUFBRTtnQkFDM0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO2dCQUMxQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEMsU0FBUztBQUNaLGFBQUE7WUFFRCxJQUFHLFdBQVcsS0FBSyxZQUFZO0FBQzVCLGdCQUFBLFdBQVcsS0FBSyxnQkFBZ0I7QUFDaEMsZ0JBQUEsV0FBVyxLQUFLLG1CQUFtQjtBQUNuQyxnQkFBQSxXQUFXLEtBQUssZ0JBQWdCO0FBQ2hDLGdCQUFBLFdBQVcsS0FBSyxlQUFlO0FBQy9CLGdCQUFBLFdBQVcsS0FBSyx1QkFBdUI7QUFDdkMsZ0JBQUEsV0FBVyxLQUFLLGlCQUFpQjtBQUNqQyxnQkFBQSxXQUFXLEtBQUsscUJBQXFCO2dCQUNyQyxXQUFXLEtBQUssYUFBYSxFQUMzQjtnQkFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7Z0JBQzFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0QyxTQUFTO0FBQ1osYUFBQTtBQUNKLFNBQUE7S0FDSjtBQUVEOzs7Ozs7OztBQVFHO0FBQ08sSUFBQSx5QkFBeUIsQ0FBQyxVQUE2QixFQUFFLG1CQUFBLEdBQStCLEtBQUssRUFBQTtRQUVuRyxJQUFHLFVBQVUsQ0FBQyxlQUFlLEtBQUssSUFBSSxJQUFJLFVBQVUsQ0FBQyxhQUFhLEtBQUssSUFBSSxFQUFFO1lBQ3pFLE9BQU87QUFDVixTQUFBO0FBRUQsUUFBQSxJQUFJLE9BQU8sR0FBZ0IsVUFBVSxDQUFDLGVBQWUsQ0FBQztBQUN0RCxRQUFBLElBQUksYUFBYSxHQUFnQixVQUFVLENBQUMsYUFBYSxDQUFDO0FBRTFELFFBQUEsSUFBSSxvQkFBb0IsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFrQixDQUFDO0FBQy9HLFFBQUEsSUFBSSxzQkFBc0IsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFrQixDQUFDO1FBRTNHLElBQUksbUJBQW1CLEtBQUssSUFBSSxFQUFFO0FBRTlCLFlBQUEsVUFBVSxDQUFDLGtCQUFrQixHQUFHLHNCQUFzQixDQUFDOzs7OztBQUt2RCxZQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFFcEQsZ0JBQUEsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBRW5DLGdCQUFBLElBQUksYUFBYSxHQUFHLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUU5RSxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUE7QUFDckIsZ0JBQUEsSUFBRyxhQUFhLEVBQUU7QUFDZCxvQkFBQSxTQUFTLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQTtBQUNwQyxpQkFBQTtBQUNJLHFCQUFBO0FBQ0Qsb0JBQUEsT0FBTyxDQUFDLEtBQUssQ0FBQywrQ0FBK0MsQ0FBQyxDQUFBO0FBQ2pFLGlCQUFBO2dCQUVELElBQUksV0FBVyxHQUFHLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7Z0JBQzdFLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFFNUQsZ0JBQUEsUUFBUSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUE7QUFDNUIsZ0JBQUEsUUFBUSxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0FBQzdDLGdCQUFBLFFBQVEsQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDO0FBQzNCLGdCQUFBLFFBQVEsQ0FBQyxZQUFZLENBQUMsTUFBSztBQUN2QixvQkFBQSxVQUFVLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUM5QixJQUFHLFFBQVEsQ0FBQyxPQUFPLEVBQUU7d0JBQ2pCLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQTt3QkFDOUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQTtBQUNwRCxxQkFBQTtBQUNJLHlCQUFBO3dCQUNELG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQTt3QkFDakQsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQTtBQUNwRCxxQkFBQTtBQUNMLGlCQUFDLENBQUMsQ0FBQztBQUNOLGFBQUE7QUFDSixTQUFBO0FBQ0ksYUFBQTs7OztBQUtELFlBQUEsVUFBVSxDQUFDLGtCQUFrQixHQUFHLHNCQUFzQixDQUFDO0FBQzFELFNBQUE7Ozs7QUFLRCxRQUFBLElBQUksb0JBQW9CLENBQUMsTUFBTSxHQUFHLHNCQUFzQixDQUFDLE1BQU0sRUFBRTtBQUU3RCxZQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsc0JBQXNCLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBRTlFLElBQUk7QUFDQSxvQkFBQSxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQTtBQUNuQyxpQkFBQTtBQUFDLGdCQUFBLE9BQU8sS0FBSyxFQUFFO0FBQ1osb0JBQUEsT0FBTyxDQUFDLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFBO0FBQzNELGlCQUFBO0FBQ0osYUFBQTtBQUNKLFNBQUE7S0FDSjtBQUVTLElBQUEsZUFBZSxDQUFDLFVBQXFCLEVBQUE7QUFFM0M7Ozs7Ozs7Ozs7Ozs7OztBQWVHO0FBRUYsUUFBQSxJQUFJLGVBQWUsR0FBRyxVQUFVLENBQUMsZUFBZSxDQUFDO0FBQ2pELFFBQUEsSUFBSSxhQUFhLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQztBQUM3QyxRQUFBLElBQUksZ0JBQWdCLEdBQW1CLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQzs7O1FBSXBFLElBQUkscUJBQXFCLEdBQUcsc0JBQXNCLENBQUMsZUFBZSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFDdEYsSUFBSSxtQkFBbUIsR0FBRyxzQkFBc0IsQ0FBQyxhQUFhLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztBQUVsRixRQUFBLElBQUcsVUFBVSxDQUFDLFdBQVcsS0FBSyxVQUFVLEVBQUU7WUFDdEMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQzFCLE9BQU07QUFDVCxTQUFBO0FBQ0QsUUFBQSxJQUFHLFVBQVUsQ0FBQyxXQUFXLEtBQUssdUJBQXVCLEVBQUU7WUFDbkQsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUE7WUFDOUIsT0FBTTtBQUNULFNBQUE7QUFFRDs7Ozs7O0FBTUc7UUFDSCxLQUFJLGFBQWEsS0FBSyxJQUFJO1lBQ3ZCLElBQUksQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEdBQUcscUJBQXFCLENBQUMsR0FBRyxFQUFFO0FBQzFELFlBQUEsVUFBVSxDQUFDLDJCQUEyQixFQUFFLEtBQUssSUFBSSxHQUFHOzs7WUFJbkQsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzVCLFNBQUE7QUFFRDs7Ozs7QUFLRztRQUNILElBQUcsVUFBVSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUMvQyxVQUFVLENBQUMsV0FBVyxLQUFLLGdCQUFnQjtZQUMzQyxVQUFVLENBQUMsV0FBVyxLQUFLLGVBQWU7QUFDMUMsWUFBQSxVQUFVLENBQUMsV0FBVyxLQUFLLGlCQUFpQixFQUFFOzs7QUFLN0MsWUFBQSxlQUFlLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDbkUsWUFBQSxhQUFhLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDL0QsWUFBQSxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLG9CQUFvQixDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztBQUUzRyxZQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDNUQsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ3pDLGFBQUE7QUFDRCxZQUFBLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUM5QyxZQUFBLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUMvQyxTQUFBO0tBQ0o7QUFFRDs7Ozs7QUFLRztJQUNILG9CQUFvQixDQUFDLFFBQTZCLEVBQUUsaUJBQWlDLEVBQUE7UUFFakYsSUFBSSxpQkFBaUIsR0FBcUIsRUFBRSxDQUFBO0FBRTVDLFFBQUEsSUFBRyxPQUFPLFFBQVEsQ0FBQyxVQUFVLEtBQUssUUFBUTtBQUN2QyxZQUFBLGNBQWMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO0FBQ25DLGFBQUMsUUFBUSxDQUFDLGVBQWUsS0FBSyxDQUFDLElBQUksUUFBUSxDQUFDLGVBQWUsS0FBSyxDQUFDLENBQUMsRUFBRTtZQUVuRSxRQUFRLENBQUMsVUFBVSxHQUFHLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQTtBQUMvRCxZQUFBLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0FBQ2hGLFlBQUEsaUJBQWlCLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLHVCQUF1QixDQUFDLENBQUM7QUFFekUsWUFBQSxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQTtBQUNwRSxZQUFBLGtCQUFrQixFQUFFLENBQUM7QUFDckIsWUFBQSxPQUFPLGlCQUFpQixDQUFDO0FBQzVCLFNBQUE7QUFFRCxRQUFBLElBQUcsT0FBTyxRQUFRLENBQUMsVUFBVSxLQUFLLFFBQVE7QUFDdkMsWUFBQSxjQUFjLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztZQUNuQyxRQUFRLENBQUMsVUFBVSxLQUFLLFVBQVU7QUFDbEMsWUFBQSxRQUFRLENBQUMsZUFBZSxHQUFHLENBQUMsRUFBRTtZQUU3QixRQUFRLENBQUMsVUFBVSxHQUFHLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNoRSxZQUFBLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0FBQ2hGLFlBQUEsaUJBQWlCLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLHVCQUF1QixDQUFDLENBQUM7QUFFekUsWUFBQSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztBQUVqRSxZQUFBLGtCQUFrQixFQUFFLENBQUM7QUFDckIsWUFBQSxPQUFPLGlCQUFpQixDQUFDO0FBQzVCLFNBQUE7UUFFRCxJQUFJLFdBQVcsR0FBaUIsRUFBRSxDQUFDOzs7UUFHbkMsSUFBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRTtBQUNuQyxZQUFBLFdBQVcsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQzdDLFNBQUE7QUFDSSxhQUFBO0FBQ0QsWUFBQSxlQUFlLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFBO0FBQ3pDLFNBQUE7QUFFRCxRQUFBLElBQUcsV0FBVyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7QUFDekIsWUFBQSxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFDbkUsU0FBQTtBQUVELFFBQUEsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFFOUMsSUFBSSxNQUFNLEdBQUcsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBRXpELFlBQUEsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztBQUMvQyxnQkFBQSxHQUFHLEVBQUUsQ0FBQSxFQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBRSxDQUFBO2dCQUMzQyxJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQSxPQUFBLEVBQVUsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFBLENBQUUsRUFBQztBQUNqRCxhQUFBLENBQUMsQ0FBQyxDQUFDO0FBRUosWUFBQSxJQUFHLENBQUMsS0FBSyxRQUFRLENBQUMsZUFBZSxHQUFHLENBQUMsRUFBRTtnQkFDbkMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO0FBQ3hCLG9CQUFBLEdBQUcsRUFBRSxDQUFtQixpQkFBQSxDQUFBO29CQUN4QixJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUFDO0FBQ25ELGlCQUFBLENBQUMsQ0FBQztBQUNOLGFBQUE7QUFDSixTQUFBO0FBRUQsUUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBRTlDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUNwRSxTQUFBO0FBRUQsUUFBQSxrQkFBa0IsRUFBRSxDQUFDO0FBRXJCLFFBQUEsT0FBTyxpQkFBaUIsQ0FBQztBQUV6QixRQUFBLFNBQVMsa0JBQWtCLEdBQUE7QUFDdkIsWUFBQSxJQUFJLFFBQVEsQ0FBQyxZQUFZLEtBQUssSUFBSSxFQUFFO0FBRWhDLGdCQUFBLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0FBQzVFLGdCQUFBLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0FBQzdFLGdCQUFBLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sS0FBSTtvQkFDakMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDdkQsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDMUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUM5RCxpQkFBQyxDQUFDLENBQUM7QUFDTixhQUFBO1NBQ0o7S0FDSjtBQUtKLENBQUE7QUFFRCxTQUFTLGtCQUFrQixDQUFDLFNBQWlCLEVBQUUsTUFBYyxFQUFFLEVBQUUsTUFBYyxFQUFFLEVBQUE7SUFDN0UsSUFBSSxPQUFPLEdBQUcsU0FBUyxDQUFDO0FBQ3BCLFFBQUEsR0FBRyxFQUFFLHNEQUFzRDtBQUMzRCxRQUFBLElBQUksRUFBRTtBQUNGLFlBQUEsVUFBVSxFQUFFLElBQUk7QUFDaEIsWUFBQSxpQkFBaUIsRUFBRSxPQUFPO0FBQzdCLFNBQUE7QUFDSixLQUFBLENBQUMsQ0FBQTtBQUNGLElBQUEsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDNUIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBcUIsa0JBQUEsRUFBQSxHQUFHLENBQUUsQ0FBQSxDQUFDLENBQUE7QUFDbEQsSUFBQSxPQUFPLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FDekI7QUFDSSxRQUFBLEtBQUssRUFBRSxrQ0FBa0M7QUFDNUMsS0FBQSxDQUNKLENBQUMsQ0FBQztBQUNILElBQUEsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQztBQUM5QixRQUFBLEtBQUssRUFBRSxDQUF3QixzQkFBQSxDQUFBO0FBQ2xDLEtBQUEsQ0FBQyxDQUFDO0FBQ0gsSUFBQSxJQUFJLFNBQVMsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRTtRQUNwQyxLQUFLLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxrQkFBa0IsQ0FBSyxFQUFBLEVBQUEsbUJBQW1CLENBQUMsU0FBUyxDQUFFLENBQUE7QUFDdkYsS0FBQSxDQUFDLENBQUM7QUFDSCxJQUFBLFNBQVMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0FBRWhDLElBQUEsT0FBTyxPQUFPLENBQUE7QUFDbEIsQ0FBQztBQUVELFNBQVMsY0FBYyxDQUFDLFVBQXFCLEVBQUE7Ozs7QUFNekMsSUFBc0IsVUFBVSxDQUFDLGdCQUFnQjtBQUNqRCxJQUFBLElBQUksYUFBYSxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUM7QUFDN0MsSUFBdUMsVUFBVSxDQUFDLGlCQUFpQjtBQUNuRSxJQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDekQsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN0QyxLQUFBO0lBQ0QsYUFBYSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxrSEFBa0gsQ0FBQyxDQUFDLENBQUE7SUFDakssT0FBTTtBQUNWLENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLFVBQXFCLEVBQUE7QUFDN0MsSUFBQSxJQUFHLFVBQVUsQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLEtBQUssRUFBRTtRQUM1QyxPQUFNO0FBQ1QsS0FBQTtBQUVELElBQUEsSUFBSSxlQUFlLEdBQUcsVUFBVSxDQUFDLGVBQWUsQ0FBQztBQUNqRCxJQUFBLElBQUksYUFBYSxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUM7QUFDN0MsSUFBQSxJQUFJLGdCQUFnQixHQUFtQixVQUFVLENBQUMsZ0JBQWdCLENBQUM7QUFFbkUsSUFBQSxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDOUMsSUFBRyxhQUFhLEtBQUssSUFBSSxJQUFJLGFBQWEsQ0FBQyxhQUFhLEtBQUssZ0JBQWdCLEVBQUU7QUFDM0UsUUFBQSxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDL0MsS0FBQTtJQUVELFNBQVMsV0FBVyxDQUFDLGNBQWlDLEVBQUE7O1FBR2xELElBQUksWUFBWSxHQUFzQixjQUFjLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBc0IsQ0FBQztRQUMxRixJQUFJLE9BQU8sR0FBNkIsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQzs7QUFHdEUsUUFBQSxZQUFZLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUM7QUFDMUMsUUFBQSxZQUFZLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUM7UUFFNUMsSUFBRyxZQUFZLENBQUMsS0FBSyxLQUFLLENBQUMsSUFBSSxZQUFZLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBQzs7O0FBR3JELFlBQUEsT0FBTyxZQUFZLENBQUM7QUFDdkIsU0FBQTs7UUFHRCxPQUFPLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7O0FBR3hDLFFBQUEsT0FBTyxZQUFZLENBQUM7S0FDdkI7SUFFRCxJQUFJLE1BQU0sR0FBRyx5QkFBeUIsQ0FBQyxlQUFlLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDbEUsSUFBRyxNQUFNLEtBQUssSUFBSSxFQUFFO1FBRWhCLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBbUIsQ0FBQyxDQUFDO0FBQ2xGLFFBQUEsYUFBYSxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUM7QUFDekMsUUFBQSxhQUFhLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDL0QsUUFBQSxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLG9CQUFvQixDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztBQUMzRyxRQUFBLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUU1QyxRQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDekQsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN0QyxTQUFBO1FBQ0QsYUFBYSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsTUFBMkIsQ0FBQyxDQUFDLENBQUE7QUFDdEUsS0FBQTtBQUVELElBQUEsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBQzlDLElBQUEsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ2hELENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxRQUE2QixFQUFFLFdBQXlCLEVBQUE7QUFDN0UsSUFBQSxJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUMsVUFBMEIsQ0FBQztBQUVqRCxJQUFBLElBQUcsUUFBUSxDQUFDLGVBQWUsS0FBSyxDQUFDLEVBQUU7QUFDL0IsUUFBQSxRQUFPLE1BQU07WUFDVCxNQUFLLFVBQVUsRUFBRTtZQUNqQixNQUFLLFFBQVEsRUFBRTtZQUNmLE1BQUssUUFBUSxFQUFFO1lBQ2YsTUFBSyxPQUFPO0FBQ1IsZ0JBQUEsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0FBQ2hFLGdCQUFBLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtnQkFDaEUsTUFBTTtZQUVWLE1BQUssTUFBTSxFQUFFO1lBQ2IsTUFBSyxPQUFPO0FBQ1IsZ0JBQUEsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0FBQ2hFLGdCQUFBLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtnQkFDaEUsTUFBTTtZQUVWLE1BQUssT0FBTyxFQUFFO1lBQ2QsTUFBSyxRQUFRLEVBQUU7WUFDZixNQUFLLE1BQU07QUFDUCxnQkFBQSxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFDaEUsZ0JBQUEsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO2dCQUNoRSxNQUFNO0FBQ2IsU0FBQTtRQUNELE9BQU87QUFDVixLQUFBO0FBRUQsSUFBQSxJQUFHLFFBQVEsQ0FBQyxlQUFlLEtBQUssQ0FBQyxFQUFFO0FBQy9CLFFBQUEsUUFBTyxNQUFNO1lBQ1QsTUFBSyxVQUFVO0FBQ1gsZ0JBQUEsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0FBQ2hFLGdCQUFBLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtBQUNoRSxnQkFBQSxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7Z0JBQ2hFLE1BQU07WUFFVixNQUFLLE1BQU0sRUFBRTtZQUNiLE1BQUssT0FBTztBQUNSLGdCQUFBLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtBQUNoRSxnQkFBQSxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFDaEUsZ0JBQUEsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO2dCQUNoRSxNQUFNO1lBRVYsTUFBSyxRQUFRLEVBQUU7WUFDZixNQUFLLFFBQVEsRUFBRTtZQUNmLE1BQUssUUFBUTtBQUNULGdCQUFBLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtBQUNoRSxnQkFBQSxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFDaEUsZ0JBQUEsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO2dCQUNoRSxNQUFNO1lBRVYsTUFBSyxPQUFPLEVBQUU7WUFDZCxNQUFLLE9BQU8sRUFBRTtZQUNkLE1BQUssTUFBTTtBQUNQLGdCQUFBLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtBQUNoRSxnQkFBQSxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFDaEUsZ0JBQUEsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO2dCQUNoRSxNQUFNO0FBQ2IsU0FBQTtBQUNKLEtBQUE7QUFDTCxDQUFDO0FBRUQsU0FBUyxzQkFBc0IsQ0FBQyxPQUFvQixFQUFFLG1CQUFtQyxFQUFBO0FBRXJGLElBQUEsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztJQUNsQyxJQUFHLE1BQU0sS0FBSyxDQUFDLEVBQUU7QUFDYixRQUFBLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN6QyxRQUFBLE1BQU0sR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFBO0FBQzdCLFFBQUEsbUJBQW1CLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzVDLEtBQUE7QUFDRCxJQUFBLE9BQU8sTUFBTSxDQUFBO0FBQ2pCLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLFFBQTZCLEVBQUUsaUJBQWlDLEVBQUUsaUJBQW1DLEVBQUE7QUFFM0gsSUFBQSxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7QUFFeEQsSUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUU5QyxRQUFBLGlCQUFpQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUM7QUFDL0MsWUFBQSxHQUFHLEVBQUUsQ0FBQSxFQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBRSxDQUFBO0FBQzNDLFlBQUEsSUFBSSxFQUFFLEVBQUMsT0FBTyxFQUFFLENBQVUsT0FBQSxFQUFBLE9BQU8sR0FBRyxFQUFDO0FBQ3hDLFNBQUEsQ0FBQyxDQUFDLENBQUM7QUFFSixRQUFBLElBQUcsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxFQUFFO1lBQ25DLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztBQUN4QixnQkFBQSxHQUFHLEVBQUUsQ0FBbUIsaUJBQUEsQ0FBQTtnQkFDeEIsSUFBSSxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsRUFBQztBQUNuRCxhQUFBLENBQUMsQ0FBQztBQUNOLFNBQUE7QUFDSixLQUFBO0FBQ0wsQ0FBQztBQUVELFNBQVMsb0JBQW9CLENBQUMsUUFBNkIsRUFBRSxpQkFBaUMsRUFBRSxpQkFBbUMsRUFBQTtBQUUvSCxJQUFBLElBQUksTUFBTSxHQUFHLFFBQVEsQ0FBQyxVQUEwQixDQUFDO0FBRWpELElBQUEsSUFBRyxRQUFRLENBQUMsZUFBZSxLQUFLLENBQUMsRUFBRTtBQUMvQixRQUFBLFFBQU8sTUFBTTtZQUNULE1BQUssVUFBVSxFQUFFO1lBQ2pCLE1BQUssUUFBUSxFQUFFO1lBQ2YsTUFBSyxRQUFRLEVBQUU7WUFDZixNQUFLLE9BQU87QUFDUixnQkFBQSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO29CQUMvQyxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxhQUFhLENBQUksQ0FBQSxFQUFBLG9CQUFvQixDQUFDLGVBQWUsQ0FBRSxDQUFBO0FBQ3RGLGlCQUFBLENBQUMsQ0FBQyxDQUFDO2dCQUNKLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztBQUN4QixvQkFBQSxHQUFHLEVBQUUsQ0FBbUIsaUJBQUEsQ0FBQTtvQkFDeEIsSUFBSSxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsRUFBQztBQUNuRCxpQkFBQSxDQUFDLENBQUM7QUFDSCxnQkFBQSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO29CQUMvQyxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxhQUFhLENBQUksQ0FBQSxFQUFBLG9CQUFvQixDQUFDLGVBQWUsQ0FBRSxDQUFBO0FBQ3RGLGlCQUFBLENBQUMsQ0FBQyxDQUFDO2dCQUNKLE1BQU07WUFFVixNQUFLLE1BQU0sRUFBRTtZQUNiLE1BQUssT0FBTztBQUNSLGdCQUFBLGlCQUFpQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUM7b0JBQy9DLEdBQUcsRUFBRSxHQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBSSxDQUFBLEVBQUEsb0JBQW9CLENBQUMsY0FBYyxDQUFFLENBQUE7QUFDckYsaUJBQUEsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osaUJBQWlCLENBQUMsU0FBUyxDQUFDO0FBQ3hCLG9CQUFBLEdBQUcsRUFBRSxDQUFtQixpQkFBQSxDQUFBO29CQUN4QixJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUFDO0FBQ25ELGlCQUFBLENBQUMsQ0FBQztBQUNILGdCQUFBLGlCQUFpQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUM7b0JBQy9DLEdBQUcsRUFBRSxHQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBSSxDQUFBLEVBQUEsb0JBQW9CLENBQUMsY0FBYyxDQUFFLENBQUE7QUFDckYsaUJBQUEsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osTUFBTTtZQUVWLE1BQUssT0FBTyxFQUFFO1lBQ2QsTUFBSyxRQUFRLEVBQUU7WUFDZixNQUFLLE1BQU07QUFDUCxnQkFBQSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO29CQUMvQyxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxhQUFhLENBQUksQ0FBQSxFQUFBLG9CQUFvQixDQUFDLGNBQWMsQ0FBRSxDQUFBO0FBQ3JGLGlCQUFBLENBQUMsQ0FBQyxDQUFDO2dCQUNKLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztBQUN4QixvQkFBQSxHQUFHLEVBQUUsQ0FBbUIsaUJBQUEsQ0FBQTtvQkFDeEIsSUFBSSxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsRUFBQztBQUNuRCxpQkFBQSxDQUFDLENBQUM7QUFDSCxnQkFBQSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO29CQUMvQyxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxhQUFhLENBQUksQ0FBQSxFQUFBLG9CQUFvQixDQUFDLGNBQWMsQ0FBRSxDQUFBO0FBQ3JGLGlCQUFBLENBQUMsQ0FBQyxDQUFDO2dCQUNKLE1BQU07QUFDYixTQUFBO1FBQ0QsT0FBTztBQUNWLEtBQUE7QUFFRCxJQUFBLElBQUcsUUFBUSxDQUFDLGVBQWUsS0FBSyxDQUFDLEVBQUU7QUFDL0IsUUFBQSxRQUFPLE1BQU07WUFDVCxNQUFLLFVBQVU7QUFDWCxnQkFBQSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO29CQUMvQyxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxhQUFhLENBQUksQ0FBQSxFQUFBLG9CQUFvQixDQUFDLGlCQUFpQixDQUFFLENBQUE7QUFDeEYsaUJBQUEsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osaUJBQWlCLENBQUMsU0FBUyxDQUFDO0FBQ3hCLG9CQUFBLEdBQUcsRUFBRSxDQUFtQixpQkFBQSxDQUFBO29CQUN4QixJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUFDO0FBQ25ELGlCQUFBLENBQUMsQ0FBQztBQUNILGdCQUFBLGlCQUFpQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUM7b0JBQy9DLEdBQUcsRUFBRSxHQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBSSxDQUFBLEVBQUEsb0JBQW9CLENBQUMsaUJBQWlCLENBQUUsQ0FBQTtBQUN4RixpQkFBQSxDQUFDLENBQUMsQ0FBQztnQkFDSixpQkFBaUIsQ0FBQyxTQUFTLENBQUM7QUFDeEIsb0JBQUEsR0FBRyxFQUFFLENBQW1CLGlCQUFBLENBQUE7b0JBQ3hCLElBQUksRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUM7QUFDbkQsaUJBQUEsQ0FBQyxDQUFDO0FBQ0gsZ0JBQUEsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztvQkFDL0MsR0FBRyxFQUFFLEdBQUcsbUJBQW1CLENBQUMsYUFBYSxDQUFJLENBQUEsRUFBQSxvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBRSxDQUFBO0FBQ3hGLGlCQUFBLENBQUMsQ0FBQyxDQUFDO2dCQUNKLE1BQU07WUFFVixNQUFLLE1BQU0sRUFBRTtZQUNiLE1BQUssT0FBTztBQUNSLGdCQUFBLGlCQUFpQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUM7b0JBQy9DLEdBQUcsRUFBRSxHQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBSSxDQUFBLEVBQUEsb0JBQW9CLENBQUMsaUJBQWlCLENBQUUsQ0FBQTtBQUN4RixpQkFBQSxDQUFDLENBQUMsQ0FBQztnQkFDSixpQkFBaUIsQ0FBQyxTQUFTLENBQUM7QUFDeEIsb0JBQUEsR0FBRyxFQUFFLENBQW1CLGlCQUFBLENBQUE7b0JBQ3hCLElBQUksRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUM7QUFDbkQsaUJBQUEsQ0FBQyxDQUFDO0FBQ0gsZ0JBQUEsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztvQkFDL0MsR0FBRyxFQUFFLEdBQUcsbUJBQW1CLENBQUMsYUFBYSxDQUFJLENBQUEsRUFBQSxvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBRSxDQUFBO0FBQ3hGLGlCQUFBLENBQUMsQ0FBQyxDQUFDO2dCQUNKLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztBQUN4QixvQkFBQSxHQUFHLEVBQUUsQ0FBbUIsaUJBQUEsQ0FBQTtvQkFDeEIsSUFBSSxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsRUFBQztBQUNuRCxpQkFBQSxDQUFDLENBQUM7QUFDSCxnQkFBQSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO29CQUMvQyxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxhQUFhLENBQUksQ0FBQSxFQUFBLG9CQUFvQixDQUFDLGlCQUFpQixDQUFFLENBQUE7QUFDeEYsaUJBQUEsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osTUFBTTtZQUVWLE1BQUssUUFBUSxFQUFFO1lBQ2YsTUFBSyxRQUFRLEVBQUU7WUFDZixNQUFLLFFBQVE7QUFDVCxnQkFBQSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO29CQUMvQyxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxhQUFhLENBQUksQ0FBQSxFQUFBLG9CQUFvQixDQUFDLGlCQUFpQixDQUFFLENBQUE7QUFDeEYsaUJBQUEsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osaUJBQWlCLENBQUMsU0FBUyxDQUFDO0FBQ3hCLG9CQUFBLEdBQUcsRUFBRSxDQUFtQixpQkFBQSxDQUFBO29CQUN4QixJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUFDO0FBQ25ELGlCQUFBLENBQUMsQ0FBQztBQUNILGdCQUFBLGlCQUFpQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUM7b0JBQy9DLEdBQUcsRUFBRSxHQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBSSxDQUFBLEVBQUEsb0JBQW9CLENBQUMsaUJBQWlCLENBQUUsQ0FBQTtBQUN4RixpQkFBQSxDQUFDLENBQUMsQ0FBQztnQkFDSixpQkFBaUIsQ0FBQyxTQUFTLENBQUM7QUFDeEIsb0JBQUEsR0FBRyxFQUFFLENBQW1CLGlCQUFBLENBQUE7b0JBQ3hCLElBQUksRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUM7QUFDbkQsaUJBQUEsQ0FBQyxDQUFDO0FBQ0gsZ0JBQUEsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztvQkFDL0MsR0FBRyxFQUFFLEdBQUcsbUJBQW1CLENBQUMsYUFBYSxDQUFJLENBQUEsRUFBQSxvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBRSxDQUFBO0FBQ3hGLGlCQUFBLENBQUMsQ0FBQyxDQUFDO2dCQUNKLE1BQU07WUFFVixNQUFLLE9BQU8sRUFBRTtZQUNkLE1BQUssT0FBTyxFQUFFO1lBQ2QsTUFBSyxNQUFNO0FBQ1AsZ0JBQUEsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztvQkFDL0MsR0FBRyxFQUFFLEdBQUcsbUJBQW1CLENBQUMsYUFBYSxDQUFJLENBQUEsRUFBQSxvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBRSxDQUFBO0FBQ3hGLGlCQUFBLENBQUMsQ0FBQyxDQUFDO2dCQUNKLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztBQUN4QixvQkFBQSxHQUFHLEVBQUUsQ0FBbUIsaUJBQUEsQ0FBQTtvQkFDeEIsSUFBSSxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsRUFBQztBQUNuRCxpQkFBQSxDQUFDLENBQUM7QUFDSCxnQkFBQSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO29CQUMvQyxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxhQUFhLENBQUksQ0FBQSxFQUFBLG9CQUFvQixDQUFDLGlCQUFpQixDQUFFLENBQUE7QUFDeEYsaUJBQUEsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osaUJBQWlCLENBQUMsU0FBUyxDQUFDO0FBQ3hCLG9CQUFBLEdBQUcsRUFBRSxDQUFtQixpQkFBQSxDQUFBO29CQUN4QixJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUFDO0FBQ25ELGlCQUFBLENBQUMsQ0FBQztBQUNILGdCQUFBLGlCQUFpQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUM7b0JBQy9DLEdBQUcsRUFBRSxHQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBSSxDQUFBLEVBQUEsb0JBQW9CLENBQUMsaUJBQWlCLENBQUUsQ0FBQTtBQUN4RixpQkFBQSxDQUFDLENBQUMsQ0FBQztnQkFDSixNQUFNO0FBQ2IsU0FBQTtBQUNKLEtBQUE7QUFDTCxDQUFDO0FBRUQsU0FBUyxVQUFVLENBQUMsVUFBcUIsRUFBQTtBQUVyQyxJQUFBLElBQUksZUFBZSxHQUFHLFVBQVUsQ0FBQyxlQUFlLENBQUM7QUFDakQsSUFBQSxJQUFJLGFBQWEsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDO0lBRTdDLElBQUksY0FBYyxHQUFHLGVBQWUsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2RSxJQUFJLFlBQVksR0FBRyxhQUFhLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFbkUsSUFBQSxJQUFHLGNBQWMsS0FBSyxTQUFTLElBQUksWUFBWSxLQUFLLFNBQVMsRUFBRTtRQUMzRCxPQUFPO0FBQ1YsS0FBQTtBQUVELElBQUEsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDLEVBQUUsS0FBSTtRQUU3QixjQUFjLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDM0IsS0FBQyxDQUFDLENBQUE7QUFDTixDQUFDO0FBRUQsU0FBUyxZQUFZLENBQUMsVUFBcUIsRUFBQTtBQUV2QyxJQUFBLElBQUksZUFBZSxHQUFHLFVBQVUsQ0FBQyxlQUFlLENBQUM7QUFDakQsSUFBQSxJQUFJLGFBQWEsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDO0FBQzdDLElBQUEsSUFBSSxnQkFBZ0IsR0FBbUIsVUFBVSxDQUFDLGdCQUFnQixDQUFDO0lBRW5FLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBbUIsQ0FBQyxDQUFDO0FBQ2xGLElBQUEsYUFBYSxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUM7QUFFekM7OztBQUdHO0FBQ0gsSUFBQSxLQUFLLElBQUksQ0FBQyxHQUFHLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDNUQsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ3pDLEtBQUE7O0FBR0QsSUFBQSxhQUFhLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDL0QsSUFBQSxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLG9CQUFvQixDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztBQUMzRyxJQUFBLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQsU0FBUyx5QkFBeUIsQ0FBQyxTQUFvQixFQUFBO0FBRW5ELElBQUEsU0FBUyxDQUFDLFdBQVcsR0FBRyxjQUFjLENBQUE7QUFDdEMsSUFBQSxJQUFHLFNBQVMsQ0FBQywyQkFBMkIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNqRCxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEIsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ3pCLEtBQUE7QUFDTDs7QUN4OUJPLE1BQU0sZ0JBQWdCLEdBQWlCO0FBQzFDLElBQUEsY0FBYyxFQUFFLElBQUk7QUFDcEIsSUFBQSwyQkFBMkIsRUFBRSxDQUFDO0FBQzlCLElBQUEsbUJBQW1CLEVBQUUsS0FBSztBQUMxQixJQUFBLDZCQUE2QixFQUFFLElBQUk7QUFDbkMsSUFBQSxvQkFBb0IsRUFBRSxJQUFJO0NBQzdCLENBQUM7TUFFVyxtQkFBbUIsQ0FBQTtBQUFoQyxJQUFBLFdBQUEsR0FBQTtRQVVZLElBQVMsQ0FBQSxTQUFBLEdBQWlCLGdCQUFnQixDQUFDO0tBdUN0RDtBQTlDVSxJQUFBLFdBQVcsTUFBTSxHQUFBO0FBQ3BCLFFBQUEsSUFBRyxtQkFBbUIsQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFO0FBQ25DLFlBQUEsbUJBQW1CLENBQUMsS0FBSyxHQUFHLElBQUksbUJBQW1CLEVBQUUsQ0FBQTtBQUN4RCxTQUFBO1FBQ0QsT0FBTyxtQkFBbUIsQ0FBQyxLQUFLLENBQUM7S0FDcEM7SUFHRCxJQUFXLFFBQVEsS0FBbUIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFBLEVBQUU7SUFDN0QsSUFBVyxRQUFRLENBQUMsTUFBb0IsRUFBQTtRQUNwQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7QUFDdEIsUUFBQSxJQUFJLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQTtLQUMxQjtJQUdELElBQVcsbUJBQW1CLEtBQWEsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUEsRUFBRTtJQUNyRSxlQUFlLEdBQUE7QUFDbkIsUUFBQSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFBO0tBQ3pDO0lBRUQsSUFBVyxjQUFjLEdBQWMsRUFBQSxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFBLEVBQUU7SUFDN0UsSUFBVywyQkFBMkIsR0FBYSxFQUFBLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQywyQkFBMkIsQ0FBQSxFQUFFO0lBQ3RHLElBQVcsbUJBQW1CLEdBQWMsRUFBQSxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsbUJBQW1CLENBQUEsRUFBRTtJQUN2RixJQUFXLDZCQUE2QixHQUFjLEVBQUEsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLDZCQUE2QixDQUFBLEVBQUU7SUFDM0csSUFBVyxvQkFBb0IsR0FBYyxFQUFBLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQSxFQUFFO0lBRXpGLElBQVcsY0FBYyxDQUFDLE1BQWUsRUFBQTtRQUNyQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7QUFDdEIsUUFBQSxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUE7S0FDekM7SUFDRCxJQUFXLDJCQUEyQixDQUFDLE1BQWMsRUFBQTtRQUNqRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7QUFDdEIsUUFBQSxJQUFJLENBQUMsU0FBUyxDQUFDLDJCQUEyQixHQUFHLE1BQU0sQ0FBQTtLQUN0RDtJQUNELElBQVcsbUJBQW1CLENBQUMsTUFBZSxFQUFBO1FBQzFDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQTtBQUN0QixRQUFBLElBQUksQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEdBQUcsTUFBTSxDQUFBO0tBQzlDO0lBQ0QsSUFBVyw2QkFBNkIsQ0FBQyxNQUFlLEVBQUE7UUFDcEQsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFBO0FBQ3RCLFFBQUEsSUFBSSxDQUFDLFNBQVMsQ0FBQyw2QkFBNkIsR0FBRyxNQUFNLENBQUE7S0FDeEQ7SUFDRCxJQUFXLG9CQUFvQixDQUFDLE1BQWUsRUFBQTtRQUMzQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7QUFDdEIsUUFBQSxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixHQUFHLE1BQU0sQ0FBQTtLQUMvQzs7QUE5Q2MsbUJBQUssQ0FBQSxLQUFBLEdBQStCLElBQUk7O0FDakIzRDs7Ozs7O0FBTUc7QUFVRyxNQUFPLGdDQUFpQyxTQUFRLGFBQWEsQ0FBQTtJQUd4RCw0QkFBNEIsR0FBQTtBQUUvQixRQUFBLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7S0FDckY7QUFDTSxJQUFBLHlCQUF5QixDQUFDLGdCQUE2QixFQUFBOztBQUcxRCxRQUFBLElBQUksY0FBYyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztBQUMzQyxRQUFBLGNBQWMsQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO0FBQ2xDLFFBQUEsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsY0FBYyxDQUFDLENBQUM7S0FDckY7QUFDTSxJQUFBLGlDQUFpQyxDQUFDLGFBQTBCLEVBQUE7QUFFL0QsUUFBQSxJQUFJLENBQUMsb0JBQW9CLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxDQUFDO0tBQ3ZGO0FBQ0Q7Ozs7Ozs7QUFPRztJQUNLLG9CQUFvQixDQUFDLGFBQTBCLEVBQUUsY0FBMkIsRUFDdkQsUUFBNkIsRUFBRSxnQkFBeUIsS0FBSyxFQUFBO1FBRXRGLElBQUksaUJBQWlCLEdBQUcsU0FBUyxDQUFDO0FBQzlCLFlBQUEsR0FBRyxFQUFFLENBQUEsRUFBRyxvQkFBb0IsQ0FBQyx3QkFBd0IsQ0FBQTtBQUM3QyxrQkFBQSxFQUFBLG9CQUFvQixDQUFDLDJCQUEyQixDQUFBO0FBQ2hELGtCQUFBLEVBQUEsb0JBQW9CLENBQUMsdUJBQXVCLENBQUE7QUFDN0Msa0JBQUEsQ0FBQTtBQUNWLFNBQUEsQ0FBQyxDQUFDO0FBR0g7OztBQUdHO1FBQ0gsSUFBSSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFDL0UsUUFBQSxJQUFHLFFBQVEsQ0FBQyxVQUFVLEtBQUssSUFBSSxFQUFFO0FBQzdCLFlBQUEsaUJBQWlCLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ2hFLFNBQUE7QUFFRCxRQUFBLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFFOUMsSUFBRyxzQkFBc0IsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEtBQUssSUFBSSxFQUFFO2dCQUM3QyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDbkUsYUFBQTtBQUVELFlBQUEsSUFBRyxRQUFRLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRTtnQkFDN0IsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ25FLGFBQUE7QUFDSixTQUFBOzs7QUFJRCxRQUFBLElBQUksbUJBQW1CLEdBQUcsSUFBSUEsNEJBQW1CLENBQzdDLGlCQUFpQixDQUNwQixDQUFDOzs7OztBQU1GLFFBQUEsS0FBSSxJQUFJLENBQUMsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN4RCxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ3RDLFNBQUE7QUFDRCxRQUFBLGFBQWEsQ0FBQyxXQUFXLENBQUMsbUJBQW1CLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFM0QsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUM7S0FDNUY7SUFFTyx1QkFBdUIsQ0FBQyxjQUEyQixFQUFFLGlCQUFtQyxFQUNoRSxRQUE2QixFQUFFLGdCQUF5QixLQUFLLEVBQUE7UUFFekYsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLFFBQUEsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFFNUMsSUFBSSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxJQUFJO2dCQUMzQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxXQUFXLEVBQUU7O2dCQUdwRCxJQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssWUFBWSxDQUFDLElBQUk7b0JBQzNDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsS0FBSyxzQkFBc0IsQ0FBQyxRQUFRO29CQUMxRSxDQUFDLFdBQVcsR0FBRyxDQUFDLElBQUksUUFBUSxDQUFDLGVBQWUsRUFBRTtBQUM3QyxvQkFBQSxXQUFXLEVBQUUsQ0FBQztBQUNqQixpQkFBQTs7Z0JBR0QsSUFBSSxPQUFPLEdBQUcsU0FBUyxDQUFDO29CQUNwQixHQUFHLEVBQUUsb0JBQW9CLENBQUMsMEJBQTBCO0FBQ3ZELGlCQUFBLENBQUMsQ0FBQztnQkFFSCxJQUFHLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsS0FBSyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUU7QUFDMUUsb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFBO0FBQ2pFLGlCQUFBO0FBQ0kscUJBQUE7QUFDRCxvQkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLDJCQUEyQixDQUFDLENBQUE7QUFDckUsaUJBQUE7Z0JBRUQsSUFBSSxTQUFTLEdBQUcsb0JBQW9CLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzVELGdCQUFBLElBQUcsU0FBUyxLQUFLLGFBQWEsQ0FBQyxNQUFNLEVBQUU7QUFDbkMsb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlLENBQUMsQ0FBQTtBQUN6RCxpQkFBQTtBQUNJLHFCQUFBLElBQUksU0FBUyxLQUFLLGFBQWEsQ0FBQyxLQUFLLEVBQUU7QUFDeEMsb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxjQUFjLENBQUMsQ0FBQTtBQUN4RCxpQkFBQTtBQUNJLHFCQUFBO0FBQ0Qsb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsQ0FBQTtBQUN2RCxpQkFBQTtBQUVELGdCQUFBLElBQUksY0FBYyxHQUFHLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQztBQUM5RSxnQkFBQSxJQUFHLFFBQVEsQ0FBQyxzQkFBc0IsS0FBSyxjQUFjLENBQUMsa0JBQWtCLEVBQUU7b0JBQ3RFLGNBQWMsR0FBRyxRQUFRLENBQUMsc0JBQXNCLEtBQUssY0FBYyxDQUFDLEtBQUssQ0FBQTtBQUM1RSxpQkFBQTtBQUNELGdCQUFBLElBQUcsY0FBYyxFQUFFO0FBQ2Ysb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxjQUFjLENBQUMsQ0FBQTtBQUN4RCxpQkFBQTtBQUVELGdCQUFBLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7Z0JBRTdDLElBQUksZUFBZSxHQUFnQixjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDO2dCQUNyRSxJQUFHLGFBQWEsS0FBSyxLQUFLLEVBQUU7QUFDeEIsb0JBQUEsSUFBSSxhQUFhLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFtQixDQUFDO0FBQ3hGLG9CQUFBLElBQUksc0JBQXNCLEdBQUcseUJBQXlCLENBQUMsYUFBYSxDQUFDLENBQUM7b0JBQ3RFLElBQUcsc0JBQXNCLEtBQUssSUFBSSxFQUFFOzt3QkFFaEMsc0JBQXNCLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDbkMscUJBQUE7QUFDRCxvQkFBQSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztvQkFDaEQsZUFBZSxHQUFHLGFBQWEsQ0FBQztBQUNuQyxpQkFBQTtBQUVELGdCQUFBLE9BQU8sQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUM7QUFFckMsZ0JBQUEsSUFBSSxjQUFjLENBQUMsQ0FBQyxDQUFDLFlBQVksaUJBQWlCLEVBQUU7b0JBRWhELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFzQixFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2hGLGlCQUFBO0FBRUQsZ0JBQUEsSUFBSSxPQUFPLEtBQUssSUFBSSxJQUFJLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssWUFBWSxDQUFDLFdBQVcsRUFBRTtvQkFFeEUsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3ZELGlCQUFBO0FBRUQ7Ozs7O0FBS0c7Z0JBQ0gsSUFBSSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxXQUFXO29CQUNsRCxDQUFDLFdBQVcsR0FBRyxDQUFDLElBQUksUUFBUSxDQUFDLGVBQWUsRUFBRTtBQUU5QyxvQkFBQSxXQUFXLEVBQUUsQ0FBQztBQUNqQixpQkFBQTtxQkFDSSxJQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssWUFBWSxDQUFDLElBQUk7b0JBQzNDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsS0FBSyxzQkFBc0IsQ0FBQyxTQUFTO29CQUMzRSxDQUFDLFdBQVcsR0FBRyxDQUFDLElBQUksUUFBUSxDQUFDLGVBQWUsRUFBRTs7QUFHbEQsb0JBQUEsV0FBVyxFQUFFLENBQUM7QUFDakIsaUJBQUE7QUFDSixhQUFBO0FBQ0osU0FBQTtLQUNKO0FBQ0o7O0FDekxEOzs7OztBQUtHO0FBVUcsTUFBTyx5QkFBMEIsU0FBUSxhQUFhLENBQUE7SUFHakQsNEJBQTRCLEdBQUE7QUFFL0IsUUFBQSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0tBQ3JGO0FBQ00sSUFBQSx5QkFBeUIsQ0FBQyxnQkFBNkIsRUFBQTs7QUFHMUQsUUFBQSxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7QUFDM0MsUUFBQSxjQUFjLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztBQUNsQyxRQUFBLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0tBQ3JGO0FBQ00sSUFBQSxpQ0FBaUMsQ0FBQyxhQUEwQixFQUFBO0FBRS9ELFFBQUEsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsQ0FBQztLQUN2RjtBQUNEOzs7Ozs7O0FBT0c7SUFDTyxvQkFBb0IsQ0FBQyxhQUEwQixFQUFFLGNBQTJCLEVBQUUsUUFBNkIsRUFBRSxnQkFBeUIsS0FBSyxFQUFBO1FBRWpKLElBQUksaUJBQWlCLEdBQUcsU0FBUyxDQUFDO0FBQzlCLFlBQUEsR0FBRyxFQUFFLENBQUEsRUFBRyxvQkFBb0IsQ0FBQyx3QkFBd0IsQ0FBQTtBQUM3QyxrQkFBQSxFQUFBLG9CQUFvQixDQUFDLDJCQUEyQixDQUFBO0FBQ2hELGtCQUFBLEVBQUEsb0JBQW9CLENBQUMsdUJBQXVCLENBQUE7QUFDN0Msa0JBQUEsQ0FBQTtBQUNWLFNBQUEsQ0FBQyxDQUFDO1FBRUgsSUFBRyxZQUFZLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxFQUFDO0FBQ2xELFlBQUEsaUJBQWlCLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLHNCQUFzQixDQUFDLENBQUE7QUFDMUUsU0FBQTthQUNJLElBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsRUFBRTtBQUN6RCxZQUFBLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFBO0FBQzNFLFNBQUE7QUFDSSxhQUFBO0FBQ0QsWUFBQSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsd0JBQXdCLENBQUMsQ0FBQTtBQUM1RSxTQUFBO0FBRUQ7OztBQUdHO1FBQ0gsSUFBSSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUN2RSxJQUFHLHNCQUFzQixDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFDN0MsWUFBQSxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDL0QsU0FBQTtBQUNELFFBQUEsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRTtBQUM5QixZQUFBLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUMvRCxTQUFBOzs7QUFJRCxRQUFBLElBQUksbUJBQW1CLEdBQUcsSUFBSUEsNEJBQW1CLENBQzdDLGlCQUFpQixDQUNwQixDQUFDOzs7OztBQU1GLFFBQUEsS0FBSyxJQUFJLENBQUMsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN6RCxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ3RDLFNBQUE7QUFDRCxRQUFBLGFBQWEsQ0FBQyxXQUFXLENBQUMsbUJBQW1CLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFM0QsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUM7S0FDM0Y7SUFFUyx1QkFBdUIsQ0FBQyxjQUEyQixFQUFFLGdCQUFnQyxFQUFFLFFBQTZCLEVBQUUsZ0JBQXlCLEtBQUssRUFBQTtBQUcxSixRQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBRTVDLElBQUksY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsSUFBSTtnQkFDM0MsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsV0FBVyxFQUFFOztnQkFHcEQsSUFBSSxPQUFPLEdBQUcsU0FBUyxDQUFDO29CQUNwQixHQUFHLEVBQUUsb0JBQW9CLENBQUMsMEJBQTBCO0FBQ3ZELGlCQUFBLENBQUMsQ0FBQztBQUNILGdCQUFBLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7Z0JBRTdDLElBQUcsbUJBQW1CLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLG1CQUFtQixDQUFDLE1BQU0sRUFBRTtBQUNoRSxvQkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLHVCQUF1QixDQUFDLENBQUE7QUFDakUsaUJBQUE7QUFDSSxxQkFBQTtBQUNELG9CQUFBLE9BQU8sQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtBQUNyRSxpQkFBQTtnQkFFRCxJQUFJLFNBQVMsR0FBRyxvQkFBb0IsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDbEQsZ0JBQUEsSUFBRyxTQUFTLEtBQUssYUFBYSxDQUFDLE1BQU0sRUFBRTtBQUNuQyxvQkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFBO0FBQ3pELGlCQUFBO0FBQ0kscUJBQUEsSUFBSSxTQUFTLEtBQUssYUFBYSxDQUFDLEtBQUssRUFBRTtBQUN4QyxvQkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFBO0FBQ3hELGlCQUFBO0FBQ0kscUJBQUE7QUFDRCxvQkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxDQUFBO0FBQ3ZELGlCQUFBO0FBRUQsZ0JBQUEsSUFBSSxjQUFjLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxDQUFDLDZCQUE2QixDQUFDO0FBQzlFLGdCQUFBLElBQUcsUUFBUSxDQUFDLHNCQUFzQixLQUFLLGNBQWMsQ0FBQyxrQkFBa0IsRUFBRTtvQkFDdEUsY0FBYyxHQUFHLFFBQVEsQ0FBQyxzQkFBc0IsS0FBSyxjQUFjLENBQUMsS0FBSyxDQUFBO0FBQzVFLGlCQUFBO0FBQ0QsZ0JBQUEsSUFBRyxjQUFjLEVBQUU7QUFDZixvQkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFBO0FBQ3hELGlCQUFBO2dCQUVELElBQUksZUFBZSxHQUFnQixjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDO2dCQUNyRSxJQUFHLGFBQWEsS0FBSyxLQUFLLEVBQUU7QUFDeEIsb0JBQUEsSUFBSSxhQUFhLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFtQixDQUFDO0FBQ3hGLG9CQUFBLElBQUksc0JBQXNCLEdBQUcseUJBQXlCLENBQUMsYUFBYSxDQUFDLENBQUM7b0JBQ3RFLElBQUcsc0JBQXNCLEtBQUssSUFBSSxFQUFFOzt3QkFFaEMsc0JBQXNCLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDbkMscUJBQUE7QUFDRCxvQkFBQSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztvQkFDaEQsZUFBZSxHQUFHLGFBQWEsQ0FBQTtBQUNsQyxpQkFBQTtBQUNELGdCQUFBLE9BQU8sQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUM7QUFFckMsZ0JBQUEsSUFBSSxjQUFjLENBQUMsQ0FBQyxDQUFDLFlBQVksaUJBQWlCLEVBQUU7b0JBRWhELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFzQixFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2hGLGlCQUFBO2dCQUVELElBQUksT0FBTyxLQUFLLElBQUksRUFBRTtBQUVsQixvQkFBQSxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDekMsaUJBQUE7QUFDSixhQUFBO0FBQ0osU0FBQTtLQUNKO0FBRUQsSUFBQSx1QkFBdUIsQ0FBQyxpQkFBaUMsRUFBQTtBQUVyRCxRQUFBLElBQUksVUFBVSxHQUFHLGlCQUFpQixDQUFDLFNBQVMsQ0FBQztBQUN6QyxZQUFBLEdBQUcsRUFBRSxDQUFBLEVBQUcsbUJBQW1CLENBQUMsYUFBYSxDQUFFLENBQUE7QUFDOUMsU0FBQSxDQUFDLENBQUM7QUFFSCxRQUFBLElBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsS0FBSyxPQUFPLEVBQUU7WUFDN0MsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFBLEVBQUcsb0JBQW9CLENBQUMsaUJBQWlCLENBQUUsQ0FBQSxDQUFDLENBQUE7QUFDbkUsU0FBQTtBQUNJLGFBQUEsSUFBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxLQUFLLE9BQU8sRUFBRTtZQUNsRCxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUEsRUFBRyxvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBRSxDQUFBLENBQUMsQ0FBQTtBQUNuRSxTQUFBO0FBQ0ksYUFBQSxJQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLEtBQUssTUFBTSxFQUFFO1lBQ2pELFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQSxFQUFHLG9CQUFvQixDQUFDLGdCQUFnQixDQUFFLENBQUEsQ0FBQyxDQUFBO0FBQ2xFLFNBQUE7QUFDSSxhQUFBO1lBQ0QsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFBLEVBQUcsb0JBQW9CLENBQUMsZUFBZSxDQUFFLENBQUEsQ0FBQyxDQUFBO0FBQ2pFLFNBQUE7QUFFRCxRQUFBLE9BQU8sVUFBVSxDQUFDO0tBQ3JCO0FBQ0osQ0FBQTtBQWVELFNBQVMsWUFBWSxDQUFDLE1BQW9CLEVBQUE7SUFFdEMsSUFBRyxNQUFNLEtBQUssTUFBTTtRQUNqQixNQUFNLEtBQUssT0FBTyxFQUFHO0FBRW5CLFFBQUEsT0FBTyxJQUFJLENBQUM7QUFDZixLQUFBO0FBRUQsSUFBQSxPQUFPLEtBQUssQ0FBQTtBQUNqQixDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsTUFBb0IsRUFBQTtJQUV2QyxJQUFHLE1BQU0sS0FBSyxPQUFPO0FBQ2xCLFFBQUEsTUFBTSxLQUFLLE9BQU87UUFDbEIsTUFBTSxLQUFLLE1BQU0sRUFBRztBQUVsQixRQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsS0FBQTtBQUVELElBQUEsT0FBTyxLQUFLLENBQUE7QUFDakI7O0FDck5BOzs7Ozs7QUFNRztBQVVHLE1BQU8sdUJBQXdCLFNBQVEsYUFBYSxDQUFBO0lBU3RELFdBQVksQ0FBQSxJQUF1QixFQUFFLGFBQUEsR0FBeUIsS0FBSyxFQUFBO1FBQy9ELEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQVJSLElBQWEsQ0FBQSxhQUFBLEdBQVksS0FBSyxDQUFDO1FBQy9CLElBQXFCLENBQUEscUJBQUEsR0FBYSxFQUFFLENBQUE7QUFTeEMsUUFBQSxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztRQUNuQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUM7S0FDeEQ7SUFFTSw0QkFBNEIsR0FBQTtBQUU5QixRQUFBLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7S0FDdEY7QUFDTSxJQUFBLHlCQUF5QixDQUFDLGdCQUE2QixFQUFBOztBQUcxRCxRQUFBLElBQUksY0FBYyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztBQUMzQyxRQUFBLGNBQWMsQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO0FBQ2xDLFFBQUEsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsY0FBYyxDQUFDLENBQUM7S0FDckY7QUFDTSxJQUFBLGlDQUFpQyxDQUFDLGFBQTBCLEVBQUE7QUFFL0QsUUFBQSxJQUFJLENBQUMsb0JBQW9CLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxDQUFDO0tBQ3ZGO0FBQ0Q7Ozs7Ozs7QUFPRztJQUNLLG9CQUFvQixDQUFDLGFBQTBCLEVBQUUsY0FBMkIsRUFBRSxRQUE2QixFQUFFLGdCQUF5QixLQUFLLEVBQUE7UUFFL0ksSUFBSSxpQkFBaUIsR0FBRyxTQUFTLENBQUM7QUFDOUIsWUFBQSxHQUFHLEVBQUUsQ0FBQSxFQUFHLG9CQUFvQixDQUFDLHdCQUF3QixDQUFBO0FBQzdDLGtCQUFBLEVBQUEsb0JBQW9CLENBQUMsMkJBQTJCLENBQUE7QUFDaEQsa0JBQUEsRUFBQSxvQkFBb0IsQ0FBQyx1QkFBdUIsQ0FBQTtBQUM3QyxrQkFBQSxDQUFBO0FBQ1YsU0FBQSxDQUFDLENBQUM7QUFDSCxRQUFBLElBQUksQ0FBQyxZQUFZLEdBQUcsaUJBQWlCLENBQUM7QUFFdEM7OztBQUdHO1FBQ0gsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFFekUsUUFBQSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEtBQUssSUFBSSxFQUFFO0FBQzlCLFlBQUEsaUJBQWlCLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ2hFLFNBQUE7QUFDRCxRQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUM3QyxJQUFHLHNCQUFzQixDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFDN0MsZ0JBQUEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDakUsYUFBQTtBQUVELFlBQUEsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRTtBQUM5QixnQkFBQSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUNqRSxhQUFBO0FBQ0osU0FBQTs7Ozs7QUFNRCxRQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDekQsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN0QyxTQUFBO0FBQ0QsUUFBQSxhQUFhLENBQUMsV0FBVyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFFN0MsUUFBQSxJQUFJLENBQUMsdUJBQXVCLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0tBQzFGO0lBRU8sdUJBQXVCLENBQUMsY0FBMkIsRUFBRSxpQkFBbUMsRUFBRSxRQUE2QixFQUFFLGdCQUF5QixLQUFLLEVBQUE7QUFFM0osUUFBQSxTQUFTLGVBQWUsR0FBQTtZQUVwQixJQUFJLFdBQVcsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBYSxFQUFFLEtBQWEsS0FBSTs7QUFHbEUsZ0JBQUEsSUFBRyxFQUFFLENBQUMscUJBQXFCLEtBQUssQ0FBQztBQUM3QixvQkFBQSxFQUFFLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxXQUFXO0FBQ25DLG9CQUFBLEVBQUUsQ0FBQyxHQUFHLEtBQUssWUFBWSxDQUFDLFNBQVM7QUFDakMsb0JBQUEsRUFBRSxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsY0FBYztBQUN0QyxvQkFBQSxFQUFFLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxXQUFXLEVBQUU7O29CQUdyQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFBO29CQUNwRCxFQUFFLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUE7b0JBQzFELGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUE7QUFDdkQsaUJBQUE7Z0JBRUQsT0FBTyxFQUFFLENBQUMscUJBQXFCLENBQUE7YUFDbEMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQVksRUFBRSxJQUFZLE9BQU8sT0FBTyxJQUFJLEdBQUcsSUFBSSxDQUFBLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNyRSxZQUFBLElBQUksc0JBQXNCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBRWhGLFlBQUEsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDOUMsS0FBSyxJQUFJLENBQUMsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUNoRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDN0MsaUJBQUE7QUFDSixhQUFBO1lBRUQsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO1lBQ3BCLElBQUksbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO1lBQzVCLFNBQVMsd0JBQXdCLENBQUMsaUJBQXlCLEVBQUE7QUFFdkQsZ0JBQUEsSUFBSSxtQkFBbUIsR0FBRyxpQkFBaUIsR0FBRyxzQkFBc0I7b0JBQ2hFLENBQUMsV0FBVyxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsZUFBZSxFQUFFO0FBRTlDLG9CQUFBLFdBQVcsRUFBRSxDQUFDO29CQUNkLG1CQUFtQixHQUFHLENBQUMsQ0FBQztBQUMzQixpQkFBQTthQUNKO0FBRUQsWUFBQSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFFNUMsSUFBSSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxJQUFJO29CQUMzQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxXQUFXLEVBQUU7QUFFcEQ7Ozs7O0FBS0c7QUFDSCxvQkFBQSxJQUFHLFNBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssSUFBSSxFQUFFO3dCQUV0RCxJQUFJLDBCQUEwQixHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQztBQUN6RSx3QkFBQSxJQUFHLENBQUMsR0FBRyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTs0QkFFOUIsMEJBQTBCLElBQUksY0FBYyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQztBQUM3RSx5QkFBQTt3QkFFRCx3QkFBd0IsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0FBQ3hELHFCQUFBO0FBQ0kseUJBQUE7d0JBRUQsd0JBQXdCLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDckUscUJBQUE7QUFDRCxvQkFBQSxtQkFBbUIsSUFBSSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUE7QUFHOUQ7Ozs7O0FBS0c7b0JBQ0gsSUFBSSxPQUFPLEdBQUcsU0FBUyxDQUFDO3dCQUNwQixHQUFHLEVBQUUsb0JBQW9CLENBQUMsMEJBQTBCO0FBQ3ZELHFCQUFBLENBQUMsQ0FBQztBQUNILG9CQUFBLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7b0JBRTdDLElBQUcsbUJBQW1CLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxLQUFLLG1CQUFtQixDQUFDLE1BQU0sRUFBRTtBQUMxRSx3QkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLHVCQUF1QixDQUFDLENBQUE7QUFDakUscUJBQUE7QUFDSSx5QkFBQTtBQUNELHdCQUFBLE9BQU8sQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtBQUNyRSxxQkFBQTtvQkFFRCxJQUFJLFNBQVMsR0FBRyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDNUQsb0JBQUEsSUFBRyxTQUFTLEtBQUssYUFBYSxDQUFDLE1BQU0sRUFBRTtBQUNuQyx3QkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxDQUFBO0FBQ3pELHFCQUFBO0FBQ0kseUJBQUEsSUFBSSxTQUFTLEtBQUssYUFBYSxDQUFDLEtBQUssRUFBRTtBQUN4Qyx3QkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFBO0FBQ3hELHFCQUFBO0FBQ0kseUJBQUE7QUFDRCx3QkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxDQUFBO0FBQ3ZELHFCQUFBO0FBRUQsb0JBQUEsSUFBSSxjQUFjLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxDQUFDLDZCQUE2QixDQUFDO0FBQzlFLG9CQUFBLElBQUcsUUFBUSxDQUFDLHNCQUFzQixLQUFLLGNBQWMsQ0FBQyxrQkFBa0IsRUFBRTt3QkFDdEUsY0FBYyxHQUFHLFFBQVEsQ0FBQyxzQkFBc0IsS0FBSyxjQUFjLENBQUMsS0FBSyxDQUFBO0FBQzVFLHFCQUFBO0FBQ0Qsb0JBQUEsSUFBRyxjQUFjLEVBQUU7QUFDZix3QkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxDQUFBO0FBQ3hELHFCQUFBO29CQUVELElBQUksZUFBZSxHQUFnQixjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDO29CQUNyRSxJQUFHLGFBQWEsS0FBSyxLQUFLLEVBQUU7d0JBQ3hCLElBQUksYUFBYSxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUM7d0JBQ3BELElBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsS0FBSyxJQUFJLEVBQUU7QUFFekMsNEJBQUEsYUFBYSxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBbUIsQ0FBQztBQUNwRiw0QkFBQSxJQUFJLHNCQUFzQixHQUFHLHlCQUF5QixDQUFDLGFBQWEsQ0FBQyxDQUFDOzRCQUN0RSxJQUFHLHNCQUFzQixLQUFLLElBQUksRUFBRTs7Z0NBRWhDLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ25DLDZCQUFBO0FBRUQsNEJBQUEsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7NEJBQ2hELGVBQWUsR0FBRyxhQUFhLENBQUM7QUFDbkMseUJBQUE7QUFDSixxQkFBQTtBQUNELG9CQUFBLE9BQU8sQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUM7QUFFckMsb0JBQUEsSUFBSSxjQUFjLENBQUMsQ0FBQyxDQUFDLFlBQVksaUJBQWlCLEVBQUU7d0JBRWhELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFzQixFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2hGLHFCQUFBO29CQUVELElBQUksT0FBTyxLQUFLLElBQUk7d0JBQ2hCLGlCQUFpQixDQUFDLFdBQVcsQ0FBQzt3QkFDOUIsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsV0FBVyxFQUFFO3dCQUVwRCxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7d0JBQ3BELGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDO0FBQ2xFLHFCQUFBO0FBRUQ7Ozs7Ozs7QUFPRzs7Ozs7O0FBT04saUJBQUE7QUFDSixhQUFBO1NBQ0o7QUFFRDs7Ozs7Ozs7Ozs7QUFXRztRQUVILElBQUksMkJBQTJCLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLFFBQUEsSUFBRyxJQUFJLENBQUMsYUFBYSxLQUFLLEtBQUssRUFBRTtBQUM3QixZQUFBLDJCQUEyQixHQUFHLG1CQUFtQixDQUFDLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQTtBQUN2RixTQUFBO1FBQ0QsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLDJCQUEyQixFQUFFLENBQUMsRUFBRSxFQUFFO0FBRWpELFlBQUEsZUFBZSxFQUFFLENBQUE7WUFFakIsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3BCLFlBQUEsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTs7QUFHOUMsZ0JBQUEsSUFBRyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUMvQixvQkFBQSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ3JDLGlCQUFBOztBQUdELGdCQUFBLElBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxLQUFLLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksRUFBRTtBQUNwRSxvQkFBQSxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLEdBQUcsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFBO29CQUNqRSxRQUFRLEdBQUcsS0FBSyxDQUFBO0FBQ25CLGlCQUFBO0FBQ0osYUFBQTs7O1lBSUQsSUFBRyxRQUFRLEtBQUssSUFBSSxFQUFFO2dCQUNsQixNQUFNO0FBQ1QsYUFBQTtBQUNKLFNBQUE7S0FDSjtJQUVNLHNCQUFzQixHQUFBO0FBRXpCLFFBQUEsSUFBRyxJQUFJLENBQUMsU0FBUyxLQUFLLElBQUksRUFBRTtZQUN4QixLQUFLLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUMvQixPQUFPO0FBQ1YsU0FBQTtBQUVELFFBQUEsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBRTFDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDeEIsSUFBSSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7WUFDN0IsSUFBSSxFQUFFLENBQUMsZUFBZSxFQUFFO0FBQ3BCLGdCQUFBLG9CQUFvQixHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFBO0FBQ3pELGFBQUE7WUFDRCxJQUFJLGtCQUFrQixHQUFHLENBQUMsQ0FBQztZQUMzQixJQUFJLEVBQUUsQ0FBQyxhQUFhLEVBQUU7QUFDbEIsZ0JBQUEsa0JBQWtCLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUE7QUFDckQsYUFBQTtZQUVELElBQUksb0JBQW9CLEdBQUcsa0JBQWtCLEVBQUU7Z0JBQzNDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMscUJBQXFCLEdBQUcsa0JBQWtCLENBQUM7QUFDOUQsYUFBQTtBQUNJLGlCQUFBO2dCQUNELElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMscUJBQXFCLEdBQUcsb0JBQW9CLENBQUM7QUFDaEUsYUFBQTtBQUNKLFNBQUE7UUFFRCxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUM7QUFDeEIsUUFBQSxJQUFHLElBQUksQ0FBQyxZQUFZLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssU0FBUztZQUN0RixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZUFBZSxFQUFFO0FBRWxFLFlBQUEsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFhLEVBQUUsS0FBYSxLQUFJOztBQUdoRSxnQkFBQSxJQUFHLEVBQUUsQ0FBQyxxQkFBcUIsS0FBSyxDQUFDO0FBQzdCLG9CQUFBLEVBQUUsQ0FBQyxHQUFHLEtBQUssWUFBWSxDQUFDLFdBQVc7QUFDbkMsb0JBQUEsRUFBRSxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsU0FBUztBQUNqQyxvQkFBQSxFQUFFLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxjQUFjO0FBQ3RDLG9CQUFBLEVBQUUsQ0FBQyxHQUFHLEtBQUssWUFBWSxDQUFDLFdBQVcsRUFBRTs7b0JBR3JDLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxlQUFlLENBQUMsQ0FBQTtvQkFDakQsRUFBRSxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFBO29CQUMxRCxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUE7QUFDcEQsaUJBQUE7Z0JBRUQsT0FBTyxFQUFFLENBQUMscUJBQXFCLENBQUE7YUFDbEMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQVksRUFBRSxJQUFZLE9BQU8sT0FBTyxJQUFJLEdBQUcsSUFBSSxDQUFBLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNyRSxZQUFBLElBQUksc0JBQXNCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBRTdGLFlBQUEsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFFaEQsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFBO2dCQUNwQixLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBQ3hELG9CQUFBLFlBQVksSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUE7QUFDOUQsaUJBQUE7Z0JBRUQsSUFBRyxZQUFZLEdBQUcsc0JBQXNCLEVBQUU7b0JBQ3RDLFlBQVksR0FBRyxLQUFLLENBQUM7b0JBQ3JCLE1BQU07QUFDVCxpQkFBQTtBQUNKLGFBQUE7QUFDSixTQUFBO1FBRUQsSUFBRyxZQUFZLEtBQUssS0FBSyxFQUFFO0FBRXZCLFlBQUEsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztBQUNyRixTQUFBO1FBRUQsS0FBSyxDQUFDLHNCQUFzQixFQUFFLENBQUM7S0FDbEM7QUFDSjs7QUM5V0Q7Ozs7OztBQU1HO0FBU0csTUFBTyxtQkFBb0IsU0FBUSxhQUFhLENBQUE7SUFFM0MsNEJBQTRCLEdBQUE7QUFFOUIsUUFBQSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0tBQ3RGO0FBQ00sSUFBQSx5QkFBeUIsQ0FBQyxnQkFBNkIsRUFBQTs7QUFHMUQsUUFBQSxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7QUFDM0MsUUFBQSxjQUFjLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztBQUNsQyxRQUFBLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0tBQ3JGO0FBQ00sSUFBQSxpQ0FBaUMsQ0FBQyxhQUEwQixFQUFBO0FBRS9ELFFBQUEsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0tBQ2pGO0FBQ0Q7Ozs7Ozs7QUFPRztBQUNLLElBQUEsb0JBQW9CLENBQUMsYUFBMEIsRUFBRSxjQUEyQixFQUFFLFFBQTZCLEVBQUE7UUFFL0csSUFBSSxvQkFBb0IsR0FBRyxTQUFTLENBQUM7QUFDakMsWUFBQSxHQUFHLEVBQUUsQ0FBRSxDQUFBO0FBQ1YsU0FBQSxDQUFDLENBQUM7QUFFSDs7O0FBR0c7Ozs7O0FBTUgsUUFBQSxLQUFLLElBQUksQ0FBQyxHQUFHLGFBQWEsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3pELGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDdEMsU0FBQTtBQUNELFFBQUEsYUFBYSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBRWhELElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxvQkFBb0IsRUFBRSxjQUFjLEVBQUUsUUFBUSxDQUFDLENBQUM7S0FDaEY7QUFFTyxJQUFBLHVCQUF1QixDQUFDLG9CQUFvQyxFQUFFLGNBQTJCLEVBQUUsUUFBNkIsRUFBQTtRQUU1SCxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQWEsRUFBRSxLQUFhLEtBQUk7O0FBR2xELFlBQUEsSUFBRyxFQUFFLENBQUMscUJBQXFCLEtBQUssQ0FBQztBQUM3QixnQkFBQSxFQUFFLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxXQUFXO0FBQ25DLGdCQUFBLEVBQUUsQ0FBQyxHQUFHLEtBQUssWUFBWSxDQUFDLFNBQVM7QUFDakMsZ0JBQUEsRUFBRSxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsY0FBYztBQUN0QyxnQkFBQSxFQUFFLENBQUMsR0FBRyxLQUFLLFlBQVksQ0FBQyxXQUFXLEVBQUU7O0FBR3JDLGdCQUFBLG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUE7Z0JBQ3BELEVBQUUsQ0FBQyxxQkFBcUIsR0FBRyxFQUFFLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQTtBQUMxRCxnQkFBQSxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFBO0FBQ3ZELGFBQUE7QUFDTCxTQUFDLENBQUMsQ0FBQTtBQUVGLFFBQUEsSUFBSSxzQkFBc0IsR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQTtRQUU1RCxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7UUFDcEIsSUFBSSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7UUFDNUIsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLFFBQUEsSUFBSSxlQUFlLEdBQUcsQ0FBQyxRQUE2QixFQUFFLGlCQUFpQyxLQUFJO1lBQ3ZGLE9BQU8sSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0FBQ2xFLFNBQUMsQ0FBQztBQUNGLFFBQUEsSUFBSSxPQUFPLEdBQUcsc0JBQXNCLENBQUMsUUFBUSxFQUFFLG9CQUFvQixFQUFFLGVBQWUsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNoRyxRQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBRTVDLElBQUksY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsSUFBSTtnQkFDM0MsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsV0FBVyxFQUFFO0FBRXBEOzs7OztBQUtHO0FBQ0gsZ0JBQUEsSUFBRyxTQUFTLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLElBQUksRUFBRTtvQkFFdEQsSUFBSSwwQkFBMEIsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUM7QUFDekUsb0JBQUEsSUFBRyxDQUFDLEdBQUcsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7d0JBRTlCLDBCQUEwQixJQUFJLGNBQWMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUM7QUFDN0UscUJBQUE7b0JBRUQsd0JBQXdCLENBQUMsMEJBQTBCLENBQUMsQ0FBQztBQUN4RCxpQkFBQTtBQUNJLHFCQUFBO29CQUVELHdCQUF3QixDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0FBQ3JFLGlCQUFBO0FBQ0QsZ0JBQUEsbUJBQW1CLElBQUksY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixDQUFBO0FBRTlEOzs7OztBQUtHO2dCQUNILElBQUksT0FBTyxHQUFHLFNBQVMsQ0FBQztvQkFDcEIsR0FBRyxFQUFFLG9CQUFvQixDQUFDLDBCQUEwQjtBQUN2RCxpQkFBQSxDQUFDLENBQUM7QUFDSCxnQkFBQSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDO2dCQUU3QyxJQUFHLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsS0FBSyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUU7QUFDMUUsb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFBO0FBQ2pFLGlCQUFBO0FBQ0kscUJBQUE7QUFDRCxvQkFBQSxPQUFPLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLDJCQUEyQixDQUFDLENBQUE7QUFDckUsaUJBQUE7Z0JBRUQsSUFBSSxTQUFTLEdBQUcsb0JBQW9CLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzVELGdCQUFBLElBQUcsU0FBUyxLQUFLLGFBQWEsQ0FBQyxNQUFNLEVBQUU7QUFDbkMsb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxlQUFlLENBQUMsQ0FBQTtBQUN6RCxpQkFBQTtBQUNJLHFCQUFBLElBQUksU0FBUyxLQUFLLGFBQWEsQ0FBQyxLQUFLLEVBQUU7QUFDeEMsb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxjQUFjLENBQUMsQ0FBQTtBQUN4RCxpQkFBQTtBQUNJLHFCQUFBO0FBQ0Qsb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsQ0FBQTtBQUN2RCxpQkFBQTtBQUVELGdCQUFBLElBQUksY0FBYyxHQUFHLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQztBQUM5RSxnQkFBQSxJQUFHLFFBQVEsQ0FBQyxzQkFBc0IsS0FBSyxjQUFjLENBQUMsa0JBQWtCLEVBQUU7b0JBQ3RFLGNBQWMsR0FBRyxRQUFRLENBQUMsc0JBQXNCLEtBQUssY0FBYyxDQUFDLEtBQUssQ0FBQTtBQUM1RSxpQkFBQTtBQUNELGdCQUFBLElBQUcsY0FBYyxFQUFFO0FBQ2Ysb0JBQUEsT0FBTyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxjQUFjLENBQUMsQ0FBQTtBQUN4RCxpQkFBQTtnQkFFRCxJQUFJLGFBQWEsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDO2dCQUNwRCxJQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLEtBQUssSUFBSSxFQUFFO0FBRXpDLG9CQUFBLGFBQWEsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQW1CLENBQUM7QUFDcEYsb0JBQUEsSUFBSSxzQkFBc0IsR0FBRyx5QkFBeUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztvQkFDdEUsSUFBRyxzQkFBc0IsS0FBSyxJQUFJLEVBQUU7O3dCQUVoQyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUNuQyxxQkFBQTtBQUVELG9CQUFBLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO0FBQ25ELGlCQUFBO0FBQ0QsZ0JBQUEsT0FBTyxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUVuQyxnQkFBQSxJQUFJLGNBQWMsQ0FBQyxDQUFDLENBQUMsWUFBWSxpQkFBaUIsRUFBRTtvQkFFaEQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQXNCLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDaEYsaUJBQUE7Z0JBRUQsSUFBSSxPQUFPLEtBQUssSUFBSTtvQkFDaEIsT0FBTyxDQUFDLFdBQVcsQ0FBQztvQkFDcEIsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsV0FBVyxFQUFFO29CQUVwRCxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUMxQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMscUJBQXFCLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztBQUNsRSxpQkFBQTtBQUVEOzs7OztBQUtHO2dCQUNILElBQUksY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsV0FBVyxFQUFFO0FBRXBELG9CQUFBLHFCQUFxQixFQUFFLENBQUM7QUFDeEIsb0JBQUEsV0FBVyxFQUFFLENBQUM7b0JBQ2QsbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0FBQzNCLGlCQUFBO0FBQ0osYUFBQTtBQUNKLFNBQUE7UUFFRCxTQUFTLHdCQUF3QixDQUFDLGlCQUF5QixFQUFBO0FBRXZELFlBQUEsSUFBSSxtQkFBbUIsR0FBRyxpQkFBaUIsR0FBRyxzQkFBc0IsRUFBRTtnQkFDbEUsT0FBTztBQUNWLGFBQUE7QUFFRCxZQUFBLHFCQUFxQixFQUFFLENBQUM7QUFDeEIsWUFBQSxXQUFXLEVBQUUsQ0FBQztZQUNkLG1CQUFtQixHQUFHLENBQUMsQ0FBQztTQUMzQjtBQUVELFFBQUEsU0FBUyxxQkFBcUIsR0FBQTtZQUMxQixJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsS0FBSyxPQUFPLENBQUMsTUFBTSxFQUFFO0FBQ3JDLGdCQUFBLFFBQVEsRUFBRSxDQUFDO0FBQ1gsZ0JBQUEsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsc0JBQXNCLENBQUMsUUFBUSxFQUFFLG9CQUFvQixFQUFFLGVBQWUsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQy9HLGFBQUE7U0FDSjtLQUNKO0FBQ0osQ0FBQTtBQUVELFNBQVMsc0JBQXNCLENBQzNCLFFBQTZCLEVBQzdCLG9CQUFvQyxFQUNwQyxvQkFBNEcsRUFDNUcsUUFBZ0IsRUFBQTtBQUVoQixJQUFBLElBQUksaUJBQWlCLEdBQUcsb0JBQW9CLENBQUMsU0FBUyxDQUFDO0FBQ25ELFFBQUEsR0FBRyxFQUFFLENBQUEsRUFBRyxvQkFBb0IsQ0FBQyx3QkFBd0IsQ0FBQTtBQUM3QyxjQUFBLEVBQUEsb0JBQW9CLENBQUMsMkJBQTJCLENBQUE7QUFDaEQsY0FBQSxFQUFBLG9CQUFvQixDQUFDLHVCQUF1QixDQUFBO0FBQzdDLGNBQUEsQ0FBQTtBQUNWLEtBQUEsQ0FBQyxDQUFDO0lBQ0gsSUFBRyxRQUFRLEdBQUcsQ0FBQyxFQUFFO1FBQ2IsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUEsRUFBRyxvQkFBb0IsQ0FBQyxrQkFBa0IsQ0FBRSxDQUFBLENBQUMsQ0FBQztBQUM1RSxLQUFBO0lBRUQsSUFBSSxVQUFVLEdBQUcsb0JBQW9CLENBQUMsUUFBUSxFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFDbkUsSUFBQSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEtBQUssSUFBSSxFQUFFO0FBQzlCLFFBQUEsaUJBQWlCLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ2hFLEtBQUE7QUFDRCxJQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3hDLElBQUksc0JBQXNCLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLElBQUksRUFBRTtZQUM5QyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQzVELFNBQUE7QUFFRCxRQUFBLElBQUksUUFBUSxDQUFDLFVBQVUsS0FBSyxJQUFJLEVBQUU7WUFDOUIsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUM1RCxTQUFBO0FBQ0osS0FBQTtBQUVELElBQUEsT0FBTyxVQUFVLENBQUE7QUFDckI7O0FDdlBBOzs7Ozs7QUFNRztBQWNIOzs7QUFHRztNQUNVLHNCQUFzQixDQUFBO0lBSS9CLFdBQVksQ0FBQSxpQkFBaUMsRUFBRSxTQUFpQixFQUFFLFdBQXdCLEVBQUUsWUFBeUIsRUFBRSxZQUFnQyxFQUFBO0FBQ25KLFFBQUEsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLGdDQUFnQyxDQUFDLDhCQUE4QixDQUFDLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7S0FDN0o7SUFFTSxTQUFTLEdBQUE7UUFDWixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7S0FDdEI7QUFFTSxJQUFBLGlCQUFpQixDQUFDLFlBQW9CLEVBQUE7QUFFekMsUUFBQSxJQUFJLGdCQUFnQixHQUFHLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ3pELFFBQUEsSUFBSSxnQkFBZ0IsQ0FBQyxlQUFlLEtBQUssQ0FBQyxFQUFFO0FBRXhDLFlBQUEsZ0JBQWdCLEdBQUcseUJBQXlCLENBQUMsWUFBWSxFQUFFLGdCQUFnQixDQUFDLENBQUM7QUFDaEYsU0FBQTtBQUNELFFBQUEsT0FBTyxJQUFJLENBQUMsdUJBQXVCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztLQUN6RDtBQUVNLElBQUEsdUJBQXVCLENBQUMsZ0JBQXFDLEVBQUE7QUFFaEUsUUFBQSxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFFbEQsUUFBQSxJQUFJLGdCQUFnQixDQUFDLGVBQWUsS0FBSyxDQUFDLEVBQUU7QUFFeEMsWUFBQSxJQUFHLElBQUksQ0FBQyxNQUFNLFlBQVkseUJBQXlCLEtBQUssS0FBSyxFQUFFOztnQkFHM0QsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7QUFDaEMsYUFBQTtBQUNKLFNBQUE7QUFDSSxhQUFBLElBQUcsZ0JBQWdCLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRTtBQUUxQyxZQUFBLElBQUcsSUFBSSxDQUFDLE1BQU0sWUFBWSx1QkFBdUIsS0FBSyxLQUFLLEVBQUU7O2dCQUd6RCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQTtBQUM3QixhQUFBO0FBQ0osU0FBQTtBQUNJLGFBQUEsSUFBRyxnQkFBZ0IsQ0FBQyxhQUFhLEtBQUssSUFBSSxFQUFFO0FBQzdDLFlBQUEsSUFBRyxJQUFJLENBQUMsTUFBTSxZQUFZLG1CQUFtQixLQUFLLEtBQUssRUFBRTs7Z0JBR3JELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO0FBQzVCLGFBQUE7QUFDSixTQUFBO0FBQ0ksYUFBQSxJQUFJLGdCQUFnQixDQUFDLGVBQWUsSUFBSSxDQUFDLEVBQUU7QUFFNUMsWUFBQSxJQUFHLElBQUksQ0FBQyxNQUFNLFlBQVksZ0NBQWdDLEtBQUssS0FBSyxFQUFFOztnQkFHbEUsSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUM7QUFDdkMsYUFBQTtBQUNKLFNBQUE7UUFFRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7S0FDdEI7SUFFTyxxQkFBcUIsR0FBQTtRQUV6QixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVsRCxPQUFPLElBQUksQ0FBQyxNQUFtQyxDQUFDO0tBQ25EO0lBRU8sNEJBQTRCLEdBQUE7UUFFaEMsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksZ0NBQWdDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekQsT0FBTyxJQUFJLENBQUMsTUFBMEMsQ0FBQztLQUMxRDtJQUVPLG1CQUFtQixHQUFBO1FBRXZCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLHVCQUF1QixDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWhELE9BQU8sSUFBSSxDQUFDLE1BQWlDLENBQUM7S0FDakQ7SUFFTyxrQkFBa0IsR0FBQTtRQUV0QixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU1QyxPQUFPLElBQUksQ0FBQyxNQUE2QixDQUFDO0tBQzdDO0FBQ0osQ0FBQTtBQUVELFNBQVMsOEJBQThCLENBQUMsWUFBeUIsRUFBRSxXQUEyQixFQUFFLFNBQWlCLEVBQUUsV0FBd0IsRUFBRSxZQUFnQyxFQUFBO0lBRXpLLE9BQU87QUFDSCxRQUFBLE9BQU8sRUFBRSxFQUFFO1FBQ1gsWUFBWSxFQUFFLElBQUksR0FBRyxFQUFFO0FBQ3ZCLFFBQUEsWUFBWSxFQUFFLFlBQVk7QUFDMUIsUUFBQSxXQUFXLEVBQUUsV0FBVztRQUN4QixnQkFBZ0IsRUFBRSw2QkFBNkIsRUFBRTtBQUNqRCxRQUFBLFNBQVMsRUFBRSxTQUFTO0FBQ3BCLFFBQUEsV0FBVyxFQUFFLFdBQVc7QUFDeEIsUUFBQSxZQUFZLEVBQUUsWUFBWTtLQUM3QixDQUFDO0FBQ047O0FDbElBOzs7Ozs7QUFNRztBQU1IOzs7QUFHRztNQUNVLGdCQUFnQixDQUFBO0FBR3pCLElBQUEsV0FBQSxHQUFBO0FBQ0ksUUFBQSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7S0FDN0I7QUFFTSxJQUFBLHlCQUF5QixDQUFDLEdBQVcsRUFBQTtRQUN4QyxJQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksRUFBRTtBQUNoQyxZQUFBLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLFNBQUE7S0FDSjtBQUVNLElBQUEsY0FBYyxDQUFDLEdBQVcsRUFBQTtRQUU3QixJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDdkIsSUFBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDaEMsV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hDLFNBQUE7QUFDSSxhQUFBO1lBQ0QsV0FBVyxHQUFHLElBQUksY0FBYyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDdkMsU0FBQTtBQUVELFFBQUEsT0FBTyxXQUFXLENBQUM7S0FDdEI7SUFFTSxrQkFBa0IsR0FBQTtRQUNyQixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0tBQzdDO0FBQ0osQ0FBQTtNQUVZLGNBQWMsQ0FBQTtJQU12QixXQUFZLENBQUEsYUFBK0IsRUFBRSxPQUFlLEVBQUE7QUFDeEQsUUFBQSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7QUFDM0IsUUFBQSxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztBQUN6QixRQUFBLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO0FBQ25DLFFBQUEsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7S0FDMUI7QUFFRCxJQUFBLFlBQVksQ0FBQyxTQUFpQixFQUFBO1FBRTFCLElBQUksZUFBZSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3BELElBQUcsZUFBZSxLQUFLLFNBQVMsRUFBRTtZQUM5QixPQUFPO0FBQ1YsU0FBQTtBQUVELFFBQUEsSUFBSSxlQUFlLEdBQUcsZUFBZSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2xELGVBQWUsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO0FBRTFDLFFBQUEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7QUFFakMsUUFBQSxJQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRTtZQUMxQixJQUFJLENBQUMsYUFBYSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM5RCxTQUFBO0tBQ0o7QUFFRCxJQUFBLHFCQUFxQixDQUFDLFNBQWlCLEVBQUUsV0FBd0IsRUFBRSxZQUFnQyxFQUFFLG1CQUFnQyxFQUFBO0FBRWpJLFFBQUEsSUFBSSxnQkFBZ0IsR0FBRyxJQUFJLHNCQUFzQixDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ25ILElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ2hELFFBQUEsT0FBTyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQztLQUN2QztBQUVELElBQUEsb0JBQW9CLENBQUMsU0FBaUIsRUFBQTtRQUVsQyxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDMUIsSUFBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDdkMsY0FBYyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ2xELFNBQUE7QUFFRCxRQUFBLE9BQU8sY0FBYyxDQUFDO0tBQ3pCO0lBRUQsc0JBQXNCLEdBQUE7QUFFbEIsUUFBQSxJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQTtRQUNwRCxJQUFJLE9BQU8sR0FBb0IsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksT0FBTyxPQUFPLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQSxFQUFFLENBQUMsQ0FBQztBQUNyRixRQUFBLE9BQU8sT0FBTyxDQUFDO0tBQ2xCO0lBRUQsY0FBYyxHQUFBO0FBQ1YsUUFBQSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztLQUMzQjtJQUVELGNBQWMsR0FBQTtRQUNWLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztLQUMzQjtJQUVELGtCQUFrQixHQUFBO0FBQ2QsUUFBQSxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFBO0tBQzdCO0FBRUQsSUFBQSxjQUFjLENBQUMsUUFBZ0IsRUFBQTtRQUMzQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQ3ZDO0FBQ0o7O01DbkhZLGtCQUFrQixDQUFBO0FBVzNCLElBQUEsSUFBWSxnQkFBZ0IsR0FBQTtRQUN4QixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFBO0tBQ2pFO0lBRUQsV0FBWSxDQUFBLFdBQXdCLEVBQUUsb0JBQUEsR0FBaUMsRUFBRSxFQUFBO1FBUHpFLElBQWEsQ0FBQSxhQUFBLEdBQWEsRUFBRSxDQUFDO1FBQzdCLElBQWUsQ0FBQSxlQUFBLEdBQWEsRUFBRSxDQUFDO0FBUTNCLFFBQUEsSUFBSSxDQUFDLGFBQWEsR0FBRyxvQkFBb0IsQ0FBQztBQUMxQyxRQUFBLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztLQUMxQztBQUVNLElBQUEsZUFBZSxDQUFDLFdBQW1CLEVBQUE7QUFFdEMsUUFBQSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7S0FDekI7QUFFTSxJQUFBLGlCQUFpQixDQUFDLGFBQXFCLEVBQUE7QUFDMUMsUUFBQSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7S0FDekI7QUFFTSxJQUFBLG9CQUFvQixDQUFDLFdBQXdCLEVBQUE7QUFFaEQsUUFBQSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQztBQUM1QyxZQUFBLEdBQUcsRUFBRSxDQUFBLEVBQUcsb0JBQW9CLENBQUMsdUJBQXVCLENBQUUsQ0FBQTtBQUN6RCxTQUFBLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQztBQUNqRCxZQUFBLEdBQUcsRUFBRSxDQUFBLEVBQUcsb0JBQW9CLENBQUMsa0JBQWtCLENBQUUsQ0FBQTtBQUNwRCxTQUFBLENBQUMsQ0FBQTtRQUNGLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQztBQUMvQyxZQUFBLEdBQUcsRUFBRSxDQUFBLEVBQUcsb0JBQW9CLENBQUMsa0JBQWtCLENBQXFCLG1CQUFBLENBQUE7QUFDdkUsU0FBQSxDQUFDLENBQUE7UUFDRixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7S0FDekI7SUFFTyxnQkFBZ0IsR0FBQTtBQUNwQixRQUFBLElBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzlCLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQTtBQUNsQixZQUFBLElBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0FBQzlCLGdCQUFBLElBQUksR0FBRyxJQUFJLEdBQUcsR0FBRyxDQUFBO0FBQ3BCLGFBQUE7QUFFRCxZQUFBLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDO0FBQ3hCLGdCQUFBLElBQUksRUFBRSxFQUFDLE9BQU8sRUFBRSx5Q0FBeUMsRUFBQztBQUMxRCxnQkFBQSxJQUFJLEVBQUUsUUFBUTtBQUNqQixhQUFBLENBQUMsQ0FBQTtBQUNGLFlBQUEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUM7Z0JBQ3hCLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFJLENBQUEsRUFBQSxJQUFJLENBQUUsQ0FBQTtBQUMvQyxhQUFBLENBQUMsQ0FBQTtBQUNMLFNBQUE7QUFFRCxRQUFBLElBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUNqRSxZQUFBLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDO0FBQ3hCLGdCQUFBLElBQUksRUFBRSxDQUFPLEtBQUEsQ0FBQTtBQUNoQixhQUFBLENBQUMsQ0FBQTtBQUNMLFNBQUE7QUFFRCxRQUFBLElBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBRWhDLElBQUksSUFBSSxHQUFHLFNBQVMsQ0FBQTtBQUNwQixZQUFBLElBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0FBQ2hDLGdCQUFBLElBQUksR0FBRyxJQUFJLEdBQUcsR0FBRyxDQUFBO0FBQ3BCLGFBQUE7QUFFRCxZQUFBLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDO0FBQ3hCLGdCQUFBLElBQUksRUFBRSxFQUFDLE9BQU8sRUFBRSwyQ0FBMkMsRUFBQztBQUM1RCxnQkFBQSxJQUFJLEVBQUUsUUFBUTtBQUNqQixhQUFBLENBQUMsQ0FBQTtBQUNGLFlBQUEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUM7Z0JBQ3hCLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFJLENBQUEsRUFBQSxJQUFJLENBQUUsQ0FBQTtBQUNqRCxhQUFBLENBQUMsQ0FBQTtBQUNMLFNBQUE7QUFDRCxRQUFBLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDO0FBQ3hCLFlBQUEsSUFBSSxFQUFFLENBQVksVUFBQSxDQUFBO0FBQ3JCLFNBQUEsQ0FBQyxDQUFBO1FBRUYsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxLQUFJO1lBQzlDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQzVELFlBQVksR0FBRyxDQUFDLFlBQVksQ0FBQTtBQUM1QixZQUFBLElBQUcsWUFBWSxFQUFFO0FBQ2IsZ0JBQUEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztBQUN2RSxhQUFBO0FBQU0saUJBQUE7Z0JBQ0gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztBQUN6QyxhQUFBO0FBQ0wsU0FBQyxDQUFDLENBQUE7S0FDTDtJQUVNLGVBQWUsR0FBQTtRQUVsQixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUE7QUFFckIsUUFBQSxJQUFHLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxDQUFDLEVBQUU7WUFDNUIsT0FBTztBQUNWLFNBQUE7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFtQixpQkFBQSxDQUFBLENBQUMsQ0FBQTtRQUM5QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQTtRQUN2RSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtRQUN2QixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtLQUMzQjtJQUdPLGlCQUFpQixHQUFBO0FBRXJCLFFBQUEsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBRS9DLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ3BDLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBNkMsMENBQUEsRUFBQSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFBLENBQUUsQ0FBQTtBQUNyRixTQUFBO0FBRUQsUUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFFakQsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDcEMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUErQyw0Q0FBQSxFQUFBLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUEsQ0FBRSxDQUFBO0FBQ3pGLFNBQUE7S0FDSjtJQUVPLGNBQWMsR0FBQTs7UUFFbEIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUE7UUFDMUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBbUIsaUJBQUEsQ0FBQSxDQUFDLENBQUE7UUFFakQsT0FBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3hDLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUc7QUFDeEMsZ0JBQUEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUE7QUFDdkMsYUFBQyxDQUFDLENBQUE7QUFDTCxTQUFBO0FBRUQsUUFBQSxJQUFHLElBQUksQ0FBQyxTQUFTLEtBQUssSUFBSSxFQUFFO1lBQ3hCLE9BQU87QUFDVixTQUFBO1FBRUQsSUFBSSxRQUFRLEdBQUcsQ0FBQSxFQUFBLEdBQUEsSUFBSSxDQUFDLFNBQVMsTUFBQSxJQUFBLElBQUEsRUFBQSxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFBLEVBQUEsQ0FBRSxVQUFVLENBQUM7QUFDMUMsUUFBQSxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBRztZQUNyQixJQUFHLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxDQUFDLGFBQWEsS0FBSyxJQUFJLENBQUMsU0FBUyxFQUFFO0FBQ3pELGdCQUFBLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3JDLGFBQUE7QUFDTCxTQUFDLENBQUMsQ0FBQztLQUNOO0FBQ0o7O0FDckplLFNBQUEscUJBQXFCLENBQUMsSUFBNEIsRUFBRSxZQUFnQyxFQUFBO0lBRWhHLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQTtBQUNyQixJQUFBLElBQUcsSUFBSSxLQUFLLHNCQUFzQixDQUFDLFFBQVEsRUFBRTtRQUN6QyxZQUFZLEdBQUcsb0NBQW9DLENBQUE7QUFDdEQsS0FBQTtBQUNELElBQUEsSUFBRyxJQUFJLEtBQUssc0JBQXNCLENBQUMsU0FBUyxFQUFFO1FBQzFDLFlBQVksR0FBRywrQkFBK0IsQ0FBQTtBQUNqRCxLQUFBO0FBQ0QsSUFBQSxJQUFHLElBQUksS0FBSyxzQkFBc0IsQ0FBQyxRQUFRLEVBQUU7UUFDekMsWUFBWSxHQUFHLCtCQUErQixDQUFBO0FBQ2pELEtBQUE7QUFFRCxJQUFBLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQywrQkFBK0IsWUFBWSxDQUFBLHdHQUFBLENBQTBHLENBQUMsQ0FBQTtBQUN6TCxDQUFDO0FBUWUsU0FBQSxzQkFBc0IsQ0FBQyxXQUE2QixFQUFFLFlBQWdDLEVBQUE7QUFFbEcsSUFBQSxJQUFHLFdBQVcsQ0FBQyxTQUFTLEtBQUssWUFBWSxDQUFDLFdBQVc7QUFDbEQsUUFBQSxXQUFXLENBQUMsWUFBWSxLQUFLLHNCQUFzQixDQUFDLElBQUksRUFBRTtRQUN6RCxPQUFPO0FBQ1YsS0FBQTtBQUVELElBQUEsSUFBSSxTQUFTLEdBQTJCLFdBQVcsQ0FBQyxZQUFZLENBQUM7QUFDakUsSUFBQSxJQUFHLFdBQVcsQ0FBQyxTQUFTLEtBQUssWUFBWSxDQUFDLFdBQVcsRUFBRTtBQUVuRCxRQUFBLElBQUcsV0FBVyxDQUFDLFNBQVMsS0FBSyxFQUFFO0FBQzVCLFlBQUEsV0FBVyxDQUFDLFNBQVMsS0FBSyxFQUFFLEVBQUU7WUFDN0IsT0FBTztBQUNWLFNBQUE7QUFFRCxRQUFBLElBQUksU0FBUyxHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUE7QUFDckMsUUFBQSxJQUFJLFNBQVMsR0FBRyxXQUFXLENBQUMsU0FBUyxDQUFBO0FBQ3JDLFFBQUEsSUFBRyxTQUFTLEtBQUssRUFBRSxJQUFJLFNBQVMsS0FBSyxFQUFFLEVBQUU7QUFDckMsWUFBQSxTQUFTLEdBQUcsc0JBQXNCLENBQUMsU0FBUyxDQUFBO0FBQy9DLFNBQUE7QUFDRCxRQUFBLElBQUcsU0FBUyxLQUFLLEVBQUUsSUFBSSxTQUFTLEtBQUssRUFBRSxFQUFFO0FBQ3JDLFlBQUEsU0FBUyxHQUFHLHNCQUFzQixDQUFDLFFBQVEsQ0FBQTtBQUM5QyxTQUFBO0FBQ0QsUUFBQSxJQUFHLFNBQVMsS0FBSyxFQUFFLElBQUksU0FBUyxLQUFLLEVBQUUsRUFBRTtBQUNyQyxZQUFBLFNBQVMsR0FBRyxzQkFBc0IsQ0FBQyxRQUFRLENBQUE7QUFDOUMsU0FBQTtBQUNKLEtBQUE7QUFDRCxJQUFBLHFCQUFxQixDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQTtBQUNsRDs7QUNuRGdCLFNBQUEsbUJBQW1CLENBQUMsU0FBb0IsRUFBRSxRQUFnQixFQUFBO0lBRXRFLFNBQVMsVUFBVSxDQUFDLEtBQVUsRUFBQTtBQUUxQixRQUFBLElBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLFNBQVM7QUFDM0IsWUFBQSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssVUFBVSxFQUFFO0FBQzdCLFlBQUEsT0FBTyxLQUFLLENBQUM7QUFDaEIsU0FBQTtBQUVELFFBQUEsSUFBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssU0FBUyxFQUFFO0FBQzdCLFlBQUEsT0FBTyxLQUFLLENBQUE7QUFDZixTQUFBO1FBRUQsSUFBRyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssU0FBUyxFQUFFO0FBQ3JDLFlBQUEsT0FBTyxLQUFLLENBQUM7QUFDaEIsU0FBQTtRQUVELElBQUksYUFBYSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQyxPQUFPLGFBQWEsS0FBSyxRQUFRLENBQUM7S0FDckM7SUFFRCxJQUFHLFNBQVMsS0FBSyxJQUFJLEVBQUU7QUFDbkIsUUFBQSxPQUFPLElBQUksQ0FBQztBQUNmLEtBQUE7SUFFRCxJQUFJLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO0FBQ3BELElBQUEsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUk7QUFDeEMsUUFBQSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQTtBQUNqQixLQUFDLENBQUMsQ0FBQTtBQUNGLElBQUEsT0FBTSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUVwQixRQUFBLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQVMsQ0FBQztBQUNwQyxRQUFBLElBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLFNBQVMsSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssU0FBUyxFQUFFO0FBRS9ELFlBQUEsSUFBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssT0FBTztBQUM1QixnQkFBQSxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssTUFBTSxFQUFHO2dCQUM3QixLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztnQkFDM0MsU0FBUztBQUNaLGFBQUE7QUFFRCxZQUFBLElBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLE1BQU07QUFDM0IsZ0JBQUEsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLFNBQVM7QUFDNUIsZ0JBQUEsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFNBQVMsRUFBRTtBQUVoQyxnQkFBQSxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDeEIsZ0JBQUEsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzlCLGdCQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7QUFFbEIsZ0JBQUEsSUFBSSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzlCLGdCQUFBLElBQUcsS0FBSyxFQUFFO0FBQ04sb0JBQUEsT0FBTyxTQUFTLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3BDLGlCQUFBO0FBQ0osYUFBQTtBQUNKLFNBQUE7QUFDSixLQUFBO0FBQ0QsSUFBQSxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBRWUsU0FBQSwwQkFBMEIsQ0FBQyxTQUFvQixFQUFFLFFBQWdCLEVBQUE7SUFFN0UsU0FBUyxVQUFVLENBQUMsS0FBVSxFQUFBO0FBRTFCLFFBQUEsSUFBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssU0FBUztBQUMzQixZQUFBLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxVQUFVLEVBQUU7QUFDN0IsWUFBQSxPQUFPLEtBQUssQ0FBQztBQUNoQixTQUFBO0FBRUQsUUFBQSxJQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxTQUFTLEVBQUU7QUFDN0IsWUFBQSxPQUFPLEtBQUssQ0FBQTtBQUNmLFNBQUE7UUFFRCxJQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxTQUFTLEVBQUU7QUFDckMsWUFBQSxPQUFPLEtBQUssQ0FBQztBQUNoQixTQUFBO1FBRUQsSUFBSSxhQUFhLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNDLE9BQU8sYUFBYSxLQUFLLFFBQVEsQ0FBQztLQUNyQztJQUVELElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7QUFDcEQsSUFBQSxJQUFJLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSTtBQUN4QyxRQUFBLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ2pCLEtBQUMsQ0FBQyxDQUFBO0FBQ0YsSUFBQSxPQUFNLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0FBRXBCLFFBQUEsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBUyxDQUFDO0FBQ3BDLFFBQUEsSUFBRyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssU0FBUyxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxTQUFTLEVBQUU7QUFFL0QsWUFBQSxJQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxPQUFPO0FBQzVCLGdCQUFBLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxNQUFNLEVBQUc7Z0JBQzdCLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUMzQyxTQUFTO0FBQ1osYUFBQTtBQUVELFlBQUEsSUFBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssTUFBTTtBQUMzQixnQkFBQSxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssU0FBUztBQUM1QixnQkFBQSxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssU0FBUyxFQUFFO0FBRWhDLGdCQUFBLElBQUksRUFBRSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN4QixnQkFBQSxJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRTlCLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztBQUN0QixnQkFBQSxJQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxTQUFTO29CQUMzQixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssU0FBUyxFQUFFO29CQUN0QyxJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUE7QUFDakMsb0JBQUEsU0FBUyxHQUFHLElBQUksS0FBSyxTQUFTLENBQUE7QUFFakMsaUJBQUE7QUFFRCxnQkFBQSxJQUFJLGFBQWEsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3RDLElBQUcsYUFBYSxJQUFJLFNBQVMsRUFBRTtBQUMzQixvQkFBQSxPQUFPLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEMsaUJBQUE7QUFDSixhQUFBO0FBQ0osU0FBQTtBQUNKLEtBQUE7QUFDRCxJQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2hCOztBQ3ZIQTs7Ozs7O0FBTUc7QUFzQkgsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQVc5QyxJQUFJLHVCQUF1QixHQUEyQixJQUFJLEdBQUcsRUFBRSxDQUFBO0FBQy9ELFNBQWUsVUFBVSxDQUFDLE9BQUEsR0FBa0IsRUFBRSxFQUFBOztRQUcxQyxJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksRUFBRSxDQUFDLENBQUE7QUFDckQsUUFBQSxLQUFJLElBQUksR0FBRyxJQUFJLElBQUksRUFBRTtZQUdqQixJQUFHLEdBQUcsS0FBSyxPQUFPLEVBQUU7O2dCQUVoQixTQUFTO0FBQ1osYUFBQTtZQUVELElBQUcsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEtBQUssRUFBRTtnQkFDM0MsU0FBUztBQUNaLGFBQUE7WUFFRCxJQUFJLEdBQUcsR0FBRyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7WUFFMUMsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUE7WUFDNUMsSUFBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsVUFBVSxLQUFLLElBQUksSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxVQUFVLEtBQUssSUFBSSxLQUFLLFdBQVcsR0FBRyx1QkFBdUIsRUFBRTs7QUFFekgsZ0JBQUEsdUJBQXVCLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQ3RDLGFBQUE7QUFDSSxpQkFBQSxJQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsVUFBVSxJQUFJLElBQUksSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxVQUFVLEtBQUssSUFBSSxFQUFFLENBR3JGO0FBQ0osU0FBQTtLQUNKLENBQUEsQ0FBQTtBQUFBLENBQUE7U0FDZSxxQkFBcUIsR0FBQTtBQUNqQyxJQUFBLFVBQVUsRUFBRSxDQUFBO0FBQ2hCLENBQUM7QUFFSyxNQUFPLHNDQUF1QyxTQUFRQyxlQUFVLENBQUE7SUFhbEUsV0FBWSxDQUFBLFlBQW9CLEVBQUUsV0FBbUIsRUFBRSxZQUFpQyxFQUFFLFVBQWlCLEVBQUUsWUFBQSxHQUF1QixFQUFFLEVBQUUsVUFBc0IsRUFBQTtBQUMxSixRQUFBLEtBQUssRUFBRSxDQUFDO1FBVlosSUFBTyxDQUFBLE9BQUEsR0FBZ0IsRUFBRSxDQUFDO1FBRTFCLElBQWMsQ0FBQSxjQUFBLEdBQXdCLDZCQUE2QixFQUFFLENBQUM7UUFHdEUsSUFBVSxDQUFBLFVBQUEsR0FBVyxFQUFFLENBQUM7QUFNcEIsUUFBQSxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztBQUMvQixRQUFBLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO0FBQ2pDLFFBQUEsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7QUFFN0IsUUFBQSxJQUFHLElBQUksQ0FBQyxVQUFVLEtBQUssSUFBSSxFQUFFO1lBQ3pCLE9BQU07QUFDVCxTQUFBO0FBQ0QsUUFBQSxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUEsRUFBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBTSxHQUFBLEVBQUEsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRXRFLElBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRTtBQUNoQixZQUFBLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQztBQUNyQyxTQUFBO1FBRUQsSUFBRyxZQUFZLEtBQUssSUFBSSxFQUFFO0FBQ3RCLFlBQUEsSUFBSSxDQUFDLGNBQWMsR0FBRyxZQUFZLENBQUM7QUFDdEMsU0FBQTtRQUVELElBQUksWUFBWSxHQUFHLElBQUksa0JBQWtCLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUN2RCxJQUFHLFVBQVUsS0FBSyxXQUFXLEVBQUU7QUFDM0IsWUFBQSxZQUFZLENBQUMsZUFBZSxDQUFDLG9WQUFvVixDQUFDLENBQUE7QUFDclgsU0FBQTtBQUVELFFBQUEsQ0FBQyxNQUFXLFNBQUEsQ0FBQSxJQUFBLEVBQUEsS0FBQSxDQUFBLEVBQUEsS0FBQSxDQUFBLEVBQUEsYUFBQTtZQUNSLFNBQVMsb0JBQW9CLENBQUMsY0FBc0IsRUFBQTtBQUVoRCxnQkFBQSxJQUFJLFdBQVcsR0FBRyxJQUFJLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQTtnQkFDbkUsSUFBRyxXQUFXLEtBQUssSUFBSSxFQUFFOztBQUVyQixvQkFBQSxPQUFPLEtBQUssQ0FBQztBQUNoQixpQkFBQTtBQUVELGdCQUFBLFdBQVcsR0FBRywrQkFBK0IsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQ25FLElBQUcsV0FBVyxLQUFLLElBQUksRUFBRTtBQUNyQixvQkFBQSxPQUFPLEtBQUssQ0FBQztBQUNoQixpQkFBQTtBQUVELGdCQUFBLE9BQU8sSUFBSSxDQUFDO2FBQ2Y7WUFFRCxJQUFJLFFBQVEsR0FBRyxNQUFNLFVBQVUsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzdELFFBQVEsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxzQkFBc0IsQ0FBQyxDQUFBO0FBRWpFLFlBQUEsSUFBSSxXQUFXLEdBQUcsSUFBSSxNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7WUFDbkUsSUFBRyxXQUFXLEtBQUssSUFBSSxFQUFFO2dCQUNyQixPQUFPO0FBQ1YsYUFBQTtZQUVELFFBQVEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7QUFFaEQsWUFBQSxJQUFJLFlBQVksR0FBRyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNwRCxZQUFBLElBQUcsWUFBWSxDQUFDLEtBQUssS0FBSyxLQUFLLEVBQUU7Z0JBQzdCLE9BQU87QUFDVixhQUFBO0FBRUQsWUFBQSxJQUFJLFdBQVcsR0FBRyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFBO1lBQ2hGLElBQUcsV0FBVyxLQUFLLEtBQUssRUFBRTtnQkFDdEIsT0FBTztBQUNWLGFBQUE7WUFFRCxZQUFZLENBQUMsaUJBQWlCLENBQUM7O0FBRTZHLHdKQUFBLENBQUMsQ0FBQTtTQUNoSixDQUFBLEdBQUcsQ0FBQztRQUVMLElBQUcsdUJBQXVCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBRTtZQUNqRCxJQUFJLEtBQUssR0FBRyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFBO0FBQzVELFlBQUEsSUFBSSxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQTtZQUN2QyxJQUFJLG1CQUFtQixHQUFHLGtCQUFrQixDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUE7WUFDL0UsSUFBSSxxQkFBcUIsR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDLDZCQUE2QixDQUFBO1lBQ2hILElBQUcsYUFBYSxJQUFJLG1CQUFtQixLQUFLLElBQUksSUFBSSxxQkFBcUIsS0FBSyxLQUFLLEVBQUU7Z0JBQ2pGLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBRWxFLGdCQUFBLElBQUksbUJBQW1CLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDO0FBQ3pFLGdCQUFBLElBQUksUUFBUSxHQUFHLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQTtBQUM5RSxnQkFBQSxJQUFHLG1CQUFtQixJQUFJLFFBQVEsS0FBSyxJQUFJLEVBQUU7b0JBQ3pDLE9BQU07QUFDVCxpQkFBQTtBQUNKLGFBQUE7QUFDSSxpQkFBQTtBQUNELGdCQUFBLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDdkQsYUFBQTtBQUNKLFNBQUE7O0FBR0QsUUFBQSxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsRUFBRSxDQUFDO1FBQzlCLElBQUksdUJBQXVCLEdBQUcsSUFBSUQsNEJBQW1CLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3ZFLFFBQUFFLHlCQUFnQixDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1FBRTdHLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN0QixJQUFJLFdBQVcsR0FBRyxZQUFZLENBQUM7O0FBRS9CLFFBQUEsSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQy9DLFFBQUEsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFFakMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXZDLElBQUksU0FBUyxHQUFHLElBQUksU0FBUyxDQUFDLEVBQWlCLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO0FBQ3RELFlBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFN0IsSUFBSSxPQUFPLEdBQUcsb0JBQW9CLENBQUMsU0FBUyxFQUFFLFlBQVksRUFBRSxXQUFXLENBQUMsQ0FBQTtBQUN4RSxZQUFBLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDO0FBQ3BDLFlBQUEsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7QUFFbEMsWUFBQSxPQUFPLEdBQUcsc0JBQXNCLENBQUMsU0FBUyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQTtBQUN2RyxZQUFBLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDO0FBQ3BDLFlBQUEsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7WUFFbEMsV0FBVyxHQUFHLHlCQUF5QixDQUFDLFNBQVMsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFlBQVksQ0FBQyxDQUFBO0FBQzlGLFNBQUE7O0FBR0QsUUFBQSxJQUFJLFVBQVUsR0FBc0I7WUFDaEMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLFlBQVksRUFBRSxJQUFJLEdBQUcsRUFBcUI7WUFDMUMsWUFBWSxFQUFFLFNBQVMsRUFBRTtBQUN6QixZQUFBLFdBQVcsRUFBRSxJQUFJO1lBQ2pCLGdCQUFnQixFQUFFLElBQUksQ0FBQyxjQUFjO1lBQ3JDLFNBQVMsRUFBRSxNQUFNLEVBQUU7WUFDbkIsV0FBVyxFQUFFLFNBQVMsRUFBRTtBQUN4QixZQUFBLFlBQVksRUFBRSxZQUFZO1NBQzdCLENBQUM7O0FBR0YsUUFBQSxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsZUFBZSxLQUFLLENBQUMsRUFBRTtBQUMzQyxZQUFBLElBQUksQ0FBQyxjQUFjLEdBQUcseUJBQXlCLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDeEYsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLHlCQUF5QixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ2xFLFNBQUE7QUFDSSxhQUFBLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEtBQUssSUFBSSxFQUFFO1lBQzlDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSx1QkFBdUIsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDdEUsU0FBQTtBQUNJLGFBQUE7WUFDRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksZ0NBQWdDLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDekUsU0FBQTtBQUVELFFBQUEsVUFBVSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQTtLQUNsQztBQUVELElBQUEsZ0JBQWdCLENBQUMsRUFBVyxFQUFBO1FBRXhCLElBQUksT0FBTyxHQUFHLGNBQWMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2xELE9BQU8sR0FBRyxZQUFZLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNqRCxPQUFPLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDakQsUUFBQSxPQUFPLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ2xDLFFBQUEsT0FBTyxHQUFHLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3hDLFFBQUEsT0FBTyxPQUFPLENBQUM7S0FDbEI7SUFFRCxLQUFLLEdBQUE7QUFFRCxRQUFBLElBQUksbUJBQW1CLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDO0FBQ3pFLFFBQUEsSUFBSSxRQUFRLEdBQUcsMEJBQTBCLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFBO0FBQzlFLFFBQUEsSUFBRyxtQkFBbUI7QUFDbEIsWUFBQSx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQztZQUNoRCxRQUFRLEtBQUssSUFBSSxFQUFFO1lBQ25CLE9BQU8sdUJBQXVCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxPQUFPLENBQUE7QUFDbEUsU0FBQTs7UUFHRCxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3ZDLFFBQUEsRUFBRSxDQUFDLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQztBQUVoQzs7Ozs7O0FBTUc7UUFDSCxJQUFJLGNBQWMsR0FBa0IsSUFBSSxDQUFDO0FBQ3pDLFFBQUEsSUFBSSxHQUFHLEVBQUU7WUFDTCxJQUFJLE1BQU0sR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUN2RCxZQUFBLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7QUFDbkIsZ0JBQUEsY0FBYyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixhQUFBO0FBQ0osU0FBQTtRQUVELElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtBQUVwQixZQUFBLElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFBO0FBQ2pDLFlBQUEsSUFBSSxjQUFjLEdBQUcsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFBO0FBQ25DLFlBQUEsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxZQUFZLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFBO1lBRXRGLElBQUksYUFBYSxHQUFHLEtBQUssQ0FBQTtBQUN6QixZQUFBLElBQUksY0FBYyxJQUFJLElBQUksQ0FBQyxhQUFhLFlBQVksdUJBQXVCLEVBQUU7Z0JBQ3pFLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDaEQsYUFBYSxHQUFHLElBQUksQ0FBQTtBQUN2QixhQUFBO0FBRUQsWUFBQSxJQUFJLENBQUMsYUFBYSxDQUFDLGlDQUFpQyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3JFLEtBQUksSUFBSSxNQUFNLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxPQUFPLEVBQUU7QUFDMUQsZ0JBQUEsVUFBVSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQTtBQUNyQyxhQUFBO0FBRUQsWUFBQSxJQUFJLGFBQWEsRUFBRTtnQkFDZixjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbkQsYUFBQTtBQUNKLFNBQUE7UUFFRCxnQkFBZ0IsQ0FBQyxFQUFFLENBQUMsQ0FBQTtBQUVwQixRQUFBLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFO0FBQzdDLFlBQUEsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7QUFDckIsWUFBQSxPQUFPLEVBQUUsRUFBRTtZQUNYLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTtZQUNqQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDN0IsYUFBYSxFQUFFLElBQUksQ0FBQyxjQUFjO0FBQ2xDLFlBQUEsNkJBQTZCLEVBQUUsbUJBQW1CLENBQUMsTUFBTSxDQUFDLG1CQUFtQjtBQUNoRixTQUFBLENBQUMsQ0FBQTtBQUVGLFFBQUEsT0FBTyxFQUFFLENBQUM7S0FDYjtBQUVELElBQUEsYUFBYSxDQUFDLFNBQW9CLEVBQUE7QUFDOUIsUUFBQSxVQUFVLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0tBQ3pDO0FBQ0osQ0FBQTtBQWtDRCxNQUFNLGtDQUFrQyxHQUFHLHlFQUF5RSxDQUFBO0FBQ3BILFNBQVMsY0FBYyxDQUFDLEVBQVcsRUFBQTtBQUUvQixJQUFBLElBQUcsRUFBRSxDQUFDLE9BQU8sS0FBSyxPQUFPLEVBQUU7QUFDdkIsUUFBQSxPQUFPLEVBQUUsQ0FBQztBQUNiLEtBQUE7SUFFRCxJQUFJLFNBQVMsR0FBRyxTQUFTLENBQUM7QUFDdEIsUUFBQSxLQUFLLEVBQUUsa0NBQWtDO0FBQzVDLEtBQUEsQ0FBQyxDQUFBO0FBQ0YsSUFBQSxTQUFTLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFCLElBQUEsT0FBTyxTQUFTLENBQUM7QUFDckIsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLEVBQVcsRUFBRSxNQUFjLEVBQUE7QUFFN0MsSUFBQSxJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDekIsSUFBRyxLQUFLLEtBQUssSUFBSSxFQUFFO0FBQ2YsUUFBQSxPQUFPLEVBQUUsQ0FBQztBQUNiLEtBQUE7SUFFRCxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzlCLElBQUksR0FBRyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDOUIsSUFBRyxHQUFHLEtBQUssSUFBSSxFQUFFO0FBQ2IsUUFBQSxPQUFPLEVBQUUsQ0FBQztBQUNiLEtBQUE7QUFFRCxJQUFBLElBQUksSUFBSSxHQUFVLEdBQUcsQ0FBQyxhQUFhLENBQUMsb0JBQW9CLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3RFLElBQUcsSUFBSSxLQUFLLElBQUksRUFBRTtBQUNkLFFBQUEsT0FBTyxFQUFFLENBQUM7QUFDYixLQUFBO0lBRUQsSUFBRyxhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEtBQUssRUFBRTtBQUN4QyxRQUFBLE9BQU8sRUFBRSxDQUFDO0FBQ2IsS0FBQTtJQUVELE9BQU8sb0JBQW9CLENBQUMsa0ZBQWtGLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzlILENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUFDLFNBQWlCLEVBQUUsTUFBYyxFQUFFLEVBQUUsTUFBYyxFQUFFLEVBQUE7SUFDL0UsSUFBSSxPQUFPLEdBQUcsU0FBUyxDQUFDO0FBQ3BCLFFBQUEsR0FBRyxFQUFFLHNEQUFzRDtBQUMzRCxRQUFBLElBQUksRUFBRTtBQUNGLFlBQUEsVUFBVSxFQUFFLElBQUk7QUFDaEIsWUFBQSxpQkFBaUIsRUFBRSxPQUFPO0FBQzdCLFNBQUE7QUFDSixLQUFBLENBQUMsQ0FBQTtBQUNGLElBQUEsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDNUIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBcUIsa0JBQUEsRUFBQSxHQUFHLENBQUUsQ0FBQSxDQUFDLENBQUE7QUFDbEQsSUFBQSxPQUFPLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FDekI7QUFDSSxRQUFBLEtBQUssRUFBRSxrQ0FBa0M7QUFDNUMsS0FBQSxDQUNKLENBQUMsQ0FBQztBQUNILElBQUEsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQztBQUM5QixRQUFBLEtBQUssRUFBRSxDQUF3QixzQkFBQSxDQUFBO0FBQ2xDLEtBQUEsQ0FBQyxDQUFDO0FBQ0gsSUFBQSxJQUFJLFNBQVMsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRTtRQUNwQyxLQUFLLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxrQkFBa0IsQ0FBSyxFQUFBLEVBQUEsbUJBQW1CLENBQUMsU0FBUyxDQUFFLENBQUE7QUFDdkYsS0FBQSxDQUFDLENBQUM7QUFDSCxJQUFBLFNBQVMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0FBRWhDLElBQUEsT0FBTyxPQUFPLENBQUE7QUFDbEIsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLEVBQVcsRUFBRSxNQUFjLEVBQUE7QUFFN0MsSUFBQSxJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDekIsSUFBRyxLQUFLLEtBQUssSUFBSSxFQUFFO0FBQ2YsUUFBQSxPQUFPLEVBQUUsQ0FBQztBQUNiLEtBQUE7SUFFRCxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzlCLElBQUksR0FBRyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDOUIsSUFBRyxHQUFHLEtBQUssSUFBSSxFQUFFO0FBQ2IsUUFBQSxPQUFPLEVBQUUsQ0FBQztBQUNiLEtBQUE7QUFFRCxJQUFBLElBQUksSUFBSSxHQUFVLEdBQUcsQ0FBQyxhQUFhLENBQUMsb0JBQW9CLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3RFLElBQUcsSUFBSSxLQUFLLElBQUksRUFBRTtBQUNkLFFBQUEsT0FBTyxFQUFFLENBQUM7QUFDYixLQUFBO0lBRUQsSUFBRyxjQUFjLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEtBQUssRUFBRTtBQUN6QyxRQUFBLE9BQU8sRUFBRSxDQUFDO0FBQ2IsS0FBQTtJQUVELE9BQU8sb0JBQW9CLENBQUMsa0hBQWtILEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzlKLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxFQUFXLEVBQUUsTUFBYyxFQUFBO0FBRS9DLElBQUEsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3pCLElBQUcsS0FBSyxLQUFLLElBQUksRUFBRTtBQUNmLFFBQUEsT0FBTyxFQUFFLENBQUM7QUFDYixLQUFBO0lBRUQsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDeEQsSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUM5QixJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzlCLElBQUcsR0FBRyxLQUFLLElBQUksRUFBRTtBQUNiLFFBQUEsT0FBTyxFQUFFLENBQUM7QUFDYixLQUFBO0FBRUQsSUFBQSxJQUFJLElBQUksR0FBVSxHQUFHLENBQUMsYUFBYSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN0RSxJQUFHLElBQUksS0FBSyxJQUFJLEVBQUU7QUFDZCxRQUFBLE9BQU8sRUFBRSxDQUFDO0FBQ2IsS0FBQTs7SUFHRCxJQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxLQUFLLEVBQUU7QUFDM0MsUUFBQSxPQUFPLEVBQUUsQ0FBQztBQUNiLEtBQUE7SUFFRCxJQUFJLE9BQU8sR0FBRyxTQUFTLENBQUM7QUFDcEIsUUFBQSxHQUFHLEVBQUUsc0NBQXNDO0FBQzlDLEtBQUEsQ0FBQyxDQUFBO0FBQ0YsSUFBQSxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztJQUU1QixJQUFJLFlBQVksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuRCxJQUFJLEtBQUssR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BDLElBQUEsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFFbkMsSUFBRyxXQUFXLEtBQUssSUFBSSxFQUFFO1FBQ3JCLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM3QyxLQUFBO0FBRUQsSUFBQSxPQUFPLE9BQU8sQ0FBQztBQUNuQixDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxFQUFXLEVBQUE7SUFFakMsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDLHNCQUFzQixDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3ZELEtBQUksSUFBSSxNQUFNLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUVqQyxJQUFJLElBQUksR0FBRyxNQUFxQixDQUFDO1FBQ2pDLElBQUcsSUFBSSxLQUFLLFNBQVM7WUFDbEIsSUFBSSxLQUFLLElBQUksRUFBRztZQUNmLFNBQVM7QUFDWixTQUFBOztRQUdELElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUE7QUFDL0IsUUFBQSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEtBQUk7QUFFbEMsWUFBQSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3RCLFNBQUMsQ0FBQyxDQUFDO0FBQ04sS0FBQTtBQUVELElBQUEsS0FBSyxHQUFHLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNuRCxLQUFJLElBQUksTUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFFakMsSUFBSSxJQUFJLEdBQUcsTUFBcUIsQ0FBQztRQUNqQyxJQUFHLElBQUksS0FBSyxTQUFTO1lBQ2xCLElBQUksS0FBSyxJQUFJLEVBQUc7WUFDZixTQUFTO0FBQ1osU0FBQTs7QUFHRCxRQUFBLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDaEMsS0FBQTtBQUVELElBQUEsT0FBTyxFQUFFLENBQUM7QUFDZCxDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUMsRUFBVyxFQUFBOzs7O0FBS3pCLElBQUEsSUFBRyxFQUFFLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLEVBQUU7QUFDOUIsUUFBQSxPQUFPLEVBQUUsQ0FBQztBQUNiLEtBQUE7QUFDSSxTQUFBO1FBRUQsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDLHNCQUFzQixDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDeEQsUUFBQSxJQUFHLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO0FBQ25CLFlBQUEsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkIsU0FBQTtBQUNKLEtBQUE7QUFFRCxJQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLFNBQWlCLEVBQUE7QUFFdkMsSUFBQSxTQUFTLEdBQUcsU0FBUyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBQ3BDLElBQUEsUUFBTyxTQUFTO0FBQ1osUUFBQSxLQUFLLEtBQUssQ0FBQztBQUNYLFFBQUEsS0FBSyxLQUFLLENBQUM7QUFDWCxRQUFBLEtBQUssTUFBTSxDQUFDO0FBQ1osUUFBQSxLQUFLLEtBQUssQ0FBQztBQUNYLFFBQUEsS0FBSyxLQUFLLENBQUM7QUFDWCxRQUFBLEtBQUssS0FBSyxDQUFDO0FBQ1gsUUFBQSxLQUFLLE1BQU07QUFDUCxZQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ25CLEtBQUE7QUFDRCxJQUFBLE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxTQUFpQixFQUFBO0FBQ3JDLElBQUEsT0FBTyxTQUFTLENBQUMsV0FBVyxFQUFFLEtBQUssS0FBSyxDQUFDO0FBQzdDLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxTQUFpQixFQUFBO0FBQ3BDLElBQUEsT0FBTyxTQUFTLENBQUMsV0FBVyxFQUFFLEtBQUssSUFBSSxDQUFDO0FBQzVDLENBQUM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxFQUFXLEVBQUE7O0lBQzNCLElBQUcsRUFBRSxDQUFDLE9BQU8sS0FBSyxJQUFJLElBQUksRUFBRSxDQUFDLE9BQU8sS0FBSyxJQUFJLEVBQUU7QUFDM0MsUUFBQSxPQUFPLEVBQUUsQ0FBQTtBQUNaLEtBQUE7SUFDRCxDQUFBLEVBQUEsR0FBQSxFQUFFLENBQUMsYUFBYSxNQUFFLElBQUEsSUFBQSxFQUFBLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQUEsRUFBQSxDQUFBLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0FBQzdELElBQUEsT0FBTyxFQUFFLENBQUM7QUFDZCxDQUFDO0FBRUQsU0FBUyxvQkFBb0IsQ0FBQyxFQUFXLEVBQUE7QUFFckMsSUFBQSxJQUFHLGFBQWEsQ0FBQyxFQUFpQixDQUFDLEVBQUU7QUFFakMsUUFBQSxJQUFHLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsS0FBSyxJQUFJLEVBQUU7QUFDekQsWUFBQSxJQUFJLE9BQU8sR0FBRyxTQUFTLEVBQUUsQ0FBQTtBQUN6QixZQUFBLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFO2dCQUNsQyxLQUFLLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxrQkFBa0IsQ0FBSSxDQUFBLEVBQUEsbUJBQW1CLENBQUMsU0FBUyxDQUFFLENBQUE7QUFDdEYsYUFBQSxDQUFDLENBQUM7QUFDSCxZQUFBLFNBQVMsQ0FBQyxTQUFTLEdBQUcsOEVBQThFLENBQUE7QUFDcEcsWUFBQSxPQUFPLE9BQU8sQ0FBQztBQUNsQixTQUFBO0FBQ0QsUUFBQSxPQUFPLEVBQUUsQ0FBQztBQUNiLEtBQUE7QUFFRCxJQUFBLE9BQU8sRUFBRSxDQUFDO0FBQ2QsQ0FBQztBQUVELFNBQVMseUJBQXlCLENBQUMsU0FBb0IsRUFDcEIsWUFBb0IsRUFDcEIsV0FBbUIsRUFDbkIsWUFBZ0MsRUFBQTtBQUUvRCxJQUFBLElBQUcsU0FBUyxDQUFDLEdBQUcsS0FBSyxZQUFZLENBQUMsV0FBVztBQUN6QyxRQUFBLFNBQVMsQ0FBQyxvQkFBb0IsS0FBSyxzQkFBc0IsQ0FBQyxJQUFJLEVBQUU7QUFDaEUsUUFBQSxPQUFPLFdBQVcsQ0FBQztBQUN0QixLQUFBO0FBRUQsSUFBQSxJQUFJLFFBQVEsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM1RCxJQUFJLFNBQVMsR0FBRyxXQUFXLENBQUM7QUFDNUIsSUFBQSxJQUFHLCtCQUErQixDQUFDLFFBQVEsQ0FBQyxFQUFFO0FBQzFDLFFBQUEsU0FBUyxHQUFHLFFBQVEsR0FBRyxXQUFXLENBQUE7QUFDckMsS0FBQTtBQUVELElBQUEsSUFBSSxZQUFZLEdBQUcsK0JBQStCLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDN0QsSUFBRyxZQUFZLEtBQUssSUFBSSxFQUFFO0FBQ3RCLFFBQUEsT0FBTyxDQUFDLEtBQUssQ0FBQywrREFBK0QsQ0FBQyxDQUFBO0FBQzlFLFFBQUEsT0FBTyxXQUFXLENBQUM7QUFDdEIsS0FBQTtBQUVELElBQUEsSUFBSSxVQUFVLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQTtJQUNuQyxJQUFJLFdBQVcsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFBO0FBQ3hDLElBQUEsSUFBSSxRQUFRLEdBQUcsVUFBVSxHQUFHLFdBQVcsQ0FBQTtJQUN2QyxJQUFJLFNBQVMsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFdkMsSUFBSSxjQUFjLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTs7QUFHOUMsSUFBQSxJQUFHLFNBQVMsQ0FBQyxvQkFBb0IsS0FBSyxzQkFBc0IsQ0FBQyxJQUFJLEVBQUU7QUFFL0QsUUFBQSxzQkFBc0IsQ0FBQztBQUNuQixZQUFBLFNBQVMsRUFBRSxFQUFFO0FBQ2IsWUFBQSxTQUFTLEVBQUUsRUFBRTtZQUNiLFNBQVMsRUFBRSxZQUFZLENBQUMsSUFBSTtZQUM1QixZQUFZLEVBQUUsU0FBUyxDQUFDLG9CQUFvQjtTQUMvQyxFQUFFLFlBQVksQ0FBQyxDQUFBO0FBRWhCLFFBQUEsT0FBTyxjQUFjLENBQUM7QUFDekIsS0FBQTs7O0FBSUQsSUFBQSxJQUFJLFVBQVUsR0FBRyxTQUFTLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQTs7QUFHcEQsSUFBQSxJQUFHLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUssRUFBRTs7QUFFeEMsUUFBQSxPQUFPLENBQUMsS0FBSyxDQUFDLDBEQUEwRCxFQUFFLFVBQVUsQ0FBQyxDQUFBO0FBQ3JGLFFBQUEsT0FBTyxXQUFXLENBQUM7QUFDdEIsS0FBQTs7SUFHRCxJQUFHLFNBQVMsS0FBSyxVQUFVLEVBQUU7QUFDekIsUUFBQSxPQUFPLENBQUMsS0FBSyxDQUFDLHFFQUFxRSxDQUFDLENBQUE7QUFDcEYsUUFBQSxPQUFPLFdBQVcsQ0FBQztBQUN0QixLQUFBOzs7QUFJRCxJQUFBLElBQUksZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUNsRSxJQUFBLElBQUksY0FBYyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLEVBQUUsRUFBRSxRQUFRLEVBQUUsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUUvRSxJQUFJLGNBQWMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ3ZFLElBQUksVUFBVSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzdDLElBQUksU0FBUyxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLFdBQVcsQ0FBQyxDQUFBO0lBQ3RELFVBQVUsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQTtBQUUvQyxJQUFBLElBQUksVUFBVSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxLQUFJO1FBQ25ELE9BQU8sR0FBRyxLQUFLLEVBQUUsQ0FBQTtBQUNyQixLQUFDLENBQUMsQ0FBQTtBQUNGLElBQUEsSUFBSSxVQUFVLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEtBQUk7UUFDbEQsT0FBTyxHQUFHLEtBQUssRUFBRSxDQUFBO0FBQ3JCLEtBQUMsQ0FBQyxDQUFBO0lBQ0YsSUFBRyxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtBQUNuRCxRQUFBLE9BQU8sV0FBVyxDQUFBO0FBQ3JCLEtBQUE7QUFFRCxJQUFBLElBQUksU0FBUyxHQUFHLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtBQUNqQyxJQUFBLElBQUksU0FBUyxHQUFHLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtBQUNsQyxJQUFBLHNCQUFzQixDQUFDO0FBQ25CLFFBQUEsU0FBUyxFQUFFLFNBQVM7QUFDcEIsUUFBQSxTQUFTLEVBQUUsU0FBUztRQUNwQixTQUFTLEVBQUUsWUFBWSxDQUFDLFdBQVc7UUFDbkMsWUFBWSxFQUFFLHNCQUFzQixDQUFDLElBQUk7S0FDNUMsRUFBRSxZQUFZLENBQUMsQ0FBQTtBQUVoQixJQUFBLE9BQU8sY0FBYyxDQUFBO0FBQ3pCLENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUFDLFNBQW9CLEVBQUUsWUFBb0IsRUFBRSxXQUFtQixFQUFBO0FBRXpGLElBQUEsU0FBUyxnQkFBZ0IsR0FBQTtBQUNyQixRQUFBLElBQUksS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLENBQUEsR0FBQSxFQUFNLFlBQVksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUE7UUFDM0YsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQTtBQUNwQyxRQUFBLElBQUcsTUFBTSxFQUFFO0FBQ1AsWUFBQSxJQUFJLGVBQWUsR0FBRyxZQUFZLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xELFdBQVcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUM7WUFDdEYsSUFBSSxrQkFBa0IsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUN4RCxPQUFPO0FBQ0gsZ0JBQUEsWUFBWSxFQUFFLGVBQWU7QUFDN0IsZ0JBQUEsV0FBVyxFQUFFLGtCQUFrQjthQUNsQyxDQUFDO0FBQ0wsU0FBQTtRQUNELE9BQU87QUFDSCxZQUFBLFlBQVksRUFBRSxZQUFZO0FBQzFCLFlBQUEsV0FBVyxFQUFFLFdBQVc7U0FDM0IsQ0FBQztLQUNMO0FBRUQsSUFBQSxTQUFTLGFBQWEsR0FBQTtBQUNsQixRQUFBLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNoRSxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRTdCLElBQUksS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLENBQUksQ0FBQSxFQUFBLElBQUksS0FBSyxZQUFZLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFBO1FBRWxHLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7QUFDcEMsUUFBQSxJQUFHLE1BQU0sRUFBRTtBQUNQLFlBQUEsSUFBSSxlQUFlLEdBQUcsWUFBWSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNsRCxXQUFXLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFDO1lBQ3RGLElBQUksa0JBQWtCLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDeEQsT0FBTztBQUNILGdCQUFBLFlBQVksRUFBRSxlQUFlO0FBQzdCLGdCQUFBLFdBQVcsRUFBRSxrQkFBa0I7YUFDbEMsQ0FBQztBQUNMLFNBQUE7UUFDRCxPQUFPO0FBQ0gsWUFBQSxZQUFZLEVBQUUsWUFBWTtBQUMxQixZQUFBLFdBQVcsRUFBRSxXQUFXO1NBQzNCLENBQUM7S0FDTDtBQUVELElBQUEsSUFBRyxTQUFTLENBQUMsZUFBZSxDQUFDLE9BQU8sS0FBSyxHQUFHLEVBQUU7UUFDMUMsT0FBTyxnQkFBZ0IsRUFBRSxDQUFDO0FBQzdCLEtBQUE7QUFFRCxJQUFBLElBQUcsU0FBUyxDQUFDLGVBQWUsQ0FBQyxPQUFPLEtBQUssSUFBSTtBQUMxQyxRQUFBLFNBQVMsQ0FBQyxlQUFlLENBQUMsT0FBTyxLQUFLLElBQUk7QUFDMUMsUUFBQSxTQUFTLENBQUMsZUFBZSxDQUFDLE9BQU8sS0FBSyxJQUFJO0FBQzFDLFFBQUEsU0FBUyxDQUFDLGVBQWUsQ0FBQyxPQUFPLEtBQUssSUFBSTtBQUMxQyxRQUFBLFNBQVMsQ0FBQyxlQUFlLENBQUMsT0FBTyxLQUFLLElBQUksRUFBRTtRQUMzQyxPQUFPLGFBQWEsRUFBRSxDQUFDO0FBQzFCLEtBQUE7SUFFRCxPQUFPO0FBQ0gsUUFBQSxZQUFZLEVBQUUsWUFBWTtBQUMxQixRQUFBLFdBQVcsRUFBRSxXQUFXO0tBQzNCLENBQUE7QUFDTCxDQUFDO0FBRUQsU0FBUyxzQkFBc0IsQ0FBQyxTQUFvQixFQUFFLGlCQUF5QixFQUFFLHFCQUE2QixFQUFFLFVBQWlCLEVBQUUsT0FBZSxFQUFBO0FBRTlJLElBQUEsSUFBRyxTQUFTLENBQUMsZUFBZSxDQUFDLE9BQU8sS0FBSyxJQUFJLEVBQUU7UUFDM0MsT0FBTztBQUNILFlBQUEsWUFBWSxFQUFFLGlCQUFpQjtBQUMvQixZQUFBLFdBQVcsRUFBRSxxQkFBcUI7U0FDckMsQ0FBQTtBQUNKLEtBQUE7SUFDRCxJQUFHLFNBQVMsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLEtBQUssS0FBSyxFQUFFO1FBQ25FLE9BQU87QUFDSCxZQUFBLFlBQVksRUFBRSxpQkFBaUI7QUFDL0IsWUFBQSxXQUFXLEVBQUUscUJBQXFCO1NBQ3JDLENBQUE7QUFDSixLQUFBO0lBRUQsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxLQUFJO0FBQzdGLFFBQUEsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUE7QUFDMUMsS0FBQyxDQUFDLENBQUE7SUFFRixJQUFJLGlCQUFpQixHQUFHLGlCQUFpQixDQUFDO0lBQzFDLElBQUksV0FBVyxHQUFHLHFCQUFxQixDQUFDO0FBQ3hDLElBQUEsS0FBSSxJQUFJLFdBQVcsSUFBSSxTQUFTLEVBQUU7UUFFOUIsSUFBSSxnQkFBZ0IsR0FBRyxXQUFXLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDakUsUUFBQSxJQUFHLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7QUFDOUIsWUFBQSxPQUFPLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxDQUFDLENBQUE7WUFDMUQsU0FBUztBQUNaLFNBQUE7QUFFRCxRQUFBLElBQUksUUFBUSxHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25DLElBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxVQUFVLEVBQUU7QUFDeEMsWUFBQSxPQUFPLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7WUFDcEQsU0FBUztBQUNaLFNBQUE7UUFFRCxJQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMseUJBQXlCLENBQUMsS0FBSyxLQUFLLEVBQUU7QUFDdkQsWUFBQSxPQUFPLENBQUMsS0FBSyxDQUFDLDBDQUEwQyxDQUFDLENBQUE7WUFDekQsU0FBUztBQUNaLFNBQUE7QUFFRCxRQUFBLElBQUcsUUFBUSxDQUFDLE9BQU8sS0FBSyxJQUFJLEVBQUU7QUFDMUIsWUFBQSxPQUFPLENBQUMsS0FBSyxDQUFDLHdEQUF3RCxDQUFDLENBQUM7WUFDeEUsU0FBUztBQUNaLFNBQUE7QUFFRCxRQUFBLElBQUksaUJBQWlCLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsS0FBSyxHQUFHLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsS0FBSyxHQUFHLENBQUE7UUFFNUcsSUFBSSx1QkFBdUIsR0FBRyxNQUFNLENBQUMsQ0FBQSxhQUFBLEVBQWdCLGlCQUFpQixHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUEsT0FBQSxFQUFVLFlBQVksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQU8sS0FBQSxDQUFBLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDakosSUFBSSx1QkFBdUIsR0FBRyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDeEUsSUFBRyx1QkFBdUIsS0FBSyxJQUFJLEVBQUU7QUFDakMsWUFBQSxPQUFPLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxDQUFDLENBQUM7WUFDM0QsU0FBUztBQUNaLFNBQUE7QUFFRCxRQUFBLElBQUksbUJBQW1CLEdBQUcsdUJBQXVCLENBQUMsS0FBSyxDQUFBO1FBQ3ZELElBQUksaUJBQWlCLEdBQUcsbUJBQW1CLEdBQUcsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFBO1FBQy9FLElBQUksWUFBWSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUN4RCxJQUFJLG1CQUFtQixHQUFHLFlBQVksQ0FBQztRQUV2QyxpQkFBaUIsR0FBRyxpQkFBaUIsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1FBQ2xGLElBQUksb0JBQW9CLEdBQUcsaUJBQWlCLENBQUM7QUFFN0MsUUFBQSxXQUFXLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO1FBQ3BELElBQUkscUJBQXFCLEdBQUcsV0FBVyxDQUFDO0FBRXhDLFFBQUEsSUFBSSxlQUFlLEdBQUcsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDaEQsUUFBQSxJQUFJLGNBQWMsR0FBRyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQTtBQUMvQyxRQUFBLElBQUksZUFBZSxHQUFHLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ2hELFFBQUEsSUFBSSxpQkFBaUIsR0FBRyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUVsRCxJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUE7QUFDNUIsUUFBQSxJQUFJLGNBQWMsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFBO0FBQ3BDLFFBQUEsUUFBUSxDQUFDLE9BQU8sR0FBRyxNQUFLO1lBRXBCLElBQUksZUFBZSxHQUFHLENBQUEsRUFBRyxlQUFlLENBQUEsQ0FBQSxFQUFJLGNBQWMsQ0FBSSxDQUFBLEVBQUEsaUJBQWlCLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQSxDQUFBLEVBQUksZUFBZSxDQUFBLEVBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQSxFQUFHLGlCQUFpQixDQUFBLENBQUUsQ0FBQTtBQUU1SixZQUFBLElBQUkscUJBQXFCLEdBQUcsb0JBQW9CLEdBQUcscUJBQXFCLENBQUE7QUFDeEUsWUFBQSxJQUFJLGtCQUFrQixHQUFHLG9CQUFvQixHQUFHLGVBQWUsR0FBRyxtQkFBbUIsQ0FBQTtBQUVyRixZQUFBLElBQUcsdUJBQXVCLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxFQUFFO0FBQzVDLGdCQUFBLElBQUksVUFBVSxHQUFHLENBQUEsRUFBRyxjQUFjLENBQU0sR0FBQSxFQUFBLGtCQUFrQixFQUFFLENBQUM7Z0JBQzdELElBQUksV0FBVyxHQUFHLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUM5RCxnQkFBQSx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFBO2dCQUNwRCxjQUFjLEdBQUcsVUFBVSxDQUFBO0FBQzlCLGFBQUE7QUFFRCxZQUFBLENBQUMsTUFBVyxTQUFBLENBQUEsSUFBQSxFQUFBLEtBQUEsQ0FBQSxFQUFBLEtBQUEsQ0FBQSxFQUFBLGFBQUE7Z0JBQ1IsSUFBSSxRQUFRLEdBQUcsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDdkQsSUFBRyxRQUFRLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLEtBQUssS0FBSyxFQUFFO0FBQ25ELG9CQUFBLE9BQU8sQ0FBQyxLQUFLLENBQUMsMkRBQTJELENBQUMsQ0FBQTtvQkFDMUUsT0FBTztBQUNWLGlCQUFBO2dCQUVELElBQUksV0FBVyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtnQkFDN0UsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFBO2FBQ25ELENBQUEsR0FBRyxDQUFDO0FBRUwsWUFBQSxXQUFXLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUMxQyxZQUFBLElBQUcsaUJBQWlCLEVBQUU7QUFDbEIsZ0JBQUEsV0FBVyxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQTtBQUMzQyxhQUFBO0FBQ0ksaUJBQUE7QUFDRCxnQkFBQSxXQUFXLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQTtBQUM3QyxhQUFBO1lBQ0QsaUJBQWlCLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQTtBQUMxQyxTQUFDLENBQUE7QUFDSixLQUFBO0lBRUQsT0FBTztBQUNILFFBQUEsWUFBWSxFQUFFLGlCQUFpQjtBQUMvQixRQUFBLFdBQVcsRUFBRSxXQUFXO0tBQzNCLENBQUE7QUFDTCxDQUFDO0FBRUQsU0FBUyxZQUFZLENBQUMsR0FBVyxFQUFBO0lBQzdCLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN0RDs7QUN4MEJBOzs7Ozs7QUFNRztBQWNJLE1BQU0sOEJBQThCLEdBQUdDLGdCQUFVLENBQUMsTUFBTSxDQUFnQjtBQUM5RSxJQUFBLE1BQU0sQ0FBQyxLQUFLLEVBQUE7UUFDWCxPQUFPQyxlQUFVLENBQUMsSUFBSSxDQUFDO0tBQ3ZCO0lBQ0QsTUFBTSxDQUFDLFFBQXVCLEVBQUUsV0FBd0IsRUFBQTtBQUN2RCxRQUFBLE1BQU0sT0FBTyxHQUFHLElBQUlDLHFCQUFlLEVBQWMsQ0FBQztRQUM1QyxJQUFJLHVCQUF1QixHQUFHLEtBQUssQ0FBQzs7UUFHMUMsSUFBRyxXQUFXLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQ0MsK0JBQXNCLENBQUMsS0FBSyxLQUFLLEVBQUU7QUFDcEQsWUFBQSxPQUFPLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUNqQyxTQUFBO0FBRUs7OztBQUdHO1FBQ0gsSUFBSSxTQUFTLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFBO0FBQzVDLFFBQUEsSUFBSSxPQUFPLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUM5RCxRQUFBLElBQUksbUJBQW1CLENBQUMsT0FBTyxDQUFDLEtBQUssS0FBSyxFQUFFO0FBQ3hDLFlBQUEsT0FBTyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDM0IsU0FBQTtBQUVQLFFBQUFDLG1CQUFVLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUNyQyxZQUFBLEtBQUssQ0FBQyxJQUFJLEVBQUE7Ozs7Ozs7Z0JBUUcsSUFBRyx1QkFBdUIsS0FBSyxJQUFJLEVBQUU7b0JBQ2pDLE9BQU87QUFDVixpQkFBQTs7Z0JBR2IsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQVNDLDJCQUFrQixDQUFDLENBQUM7Z0JBQzlELElBQUksVUFBVSxLQUFLLFNBQVMsRUFBRTtvQkFDN0IsT0FBTztBQUNQLGlCQUFBOzs7O0FBS0QsZ0JBQUEsSUFBSSxNQUFNLEdBQUcsc0JBQXNCLEVBQUUsQ0FBQzs7Z0JBR3RDLElBQUksZUFBZSxHQUFHLE9BQU8sQ0FBQztnQkFFOUIsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO2dCQUNsQixJQUFJLGdCQUFnQixHQUFHLENBQUMsQ0FBQztBQUN6QixnQkFBQSxPQUFPLElBQUksRUFBRTtvQkFFWixJQUFJLFVBQVUsR0FBZSxhQUFhLENBQUMsZUFBZSxFQUFFLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxDQUFDO29CQUN2RixJQUFHLFVBQVUsS0FBSyxJQUFJLEVBQUU7d0JBQ3ZCLE1BQU07QUFDTixxQkFBQTtBQUVELG9CQUFBLElBQUksV0FBVyxHQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUM7QUFDekMsb0JBQUEsZUFBZSxHQUFJLFVBQVUsQ0FBQyxhQUFhLENBQUM7QUFDNUMsb0JBQUEsSUFBSSxVQUFVLEdBQUssVUFBVSxDQUFDLFVBQVUsQ0FBQztBQUN6QyxvQkFBQSxJQUFJLFFBQVEsR0FBTyxVQUFVLENBQUMsUUFBUSxDQUFDO29CQUN2QyxnQkFBZ0IsR0FBRyxRQUFRLENBQUM7O29CQUc1QixJQUFJLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO29CQUN2RSxJQUFHLGNBQWMsS0FBSyxJQUFJLEVBQUUsQ0E4QjNCO0FBQ0kseUJBQUE7QUFFSix3QkFBQSxJQUFJLGFBQWEsR0FBRyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7d0JBQ2hELElBQUksWUFBWSxHQUFHLElBQUksQ0FBQzt3QkFDeEIsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFBO3dCQUNyQixJQUFJLFlBQVksR0FBRyxXQUFXLENBQUE7d0JBQzlCLElBQUcsYUFBYSxLQUFLLElBQUksRUFBRTtBQUUxQiw0QkFBQSxXQUFXLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FBQztBQUN4Qyw0QkFBQSxZQUFZLEdBQUcsYUFBYSxDQUFDLFFBQVEsQ0FBQztBQUN0Qyw0QkFBQSxZQUFZLEdBQUcsYUFBYSxDQUFDLFlBQVksQ0FBQztBQUMxQyx5QkFBQTt3QkFFRCxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQ0Msd0JBQWUsQ0FBQyxDQUFDOzs7d0JBSTVELE9BQU8sQ0FBQyxHQUFHLENBQ1YsVUFBVSxFQUNWLFFBQVEsRUFDUkwsZUFBVSxDQUFDLE9BQU8sQ0FBQztBQUNsQiw0QkFBQSxNQUFNLEVBQUUsSUFBSSxzQ0FBc0MsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxVQUFVLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxVQUFVLENBQUMsVUFBVSxDQUFDO0FBQ2pKLHlCQUFBLENBQUMsQ0FDRixDQUFDO0FBQ0YscUJBQUE7b0JBQ0QsdUJBQXVCLEdBQUcsSUFBSSxDQUFDOztBQUcvQixvQkFBQSxTQUFTLEVBQUUsQ0FBQztvQkFDWixJQUFHLFNBQVMsR0FBRyxHQUFHLEVBQUU7QUFDbkIsd0JBQUEsT0FBTyxDQUFDLElBQUksQ0FBQyx5SUFBeUksQ0FBQyxDQUFBO3dCQUN2SixNQUFNO0FBQ04scUJBQUE7QUFDRCxpQkFBQTthQUNEO0FBQ0QsU0FBQSxDQUFDLENBQUM7QUFFSCxRQUFBLE9BQU8sT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBRXhCLFFBQUEsU0FBUyxzQkFBc0IsR0FBQTtZQUU5QixJQUFJLE1BQU0sR0FBdUMsRUFBRSxDQUFDO0FBRXBELFlBQUEsSUFBSSxXQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUU7QUFFdkMsZ0JBQUEsTUFBTSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEtBQUk7b0JBRTVELE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQztBQUNwQixpQkFBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxLQUFJO0FBRWhCLG9CQUFBLElBQUksSUFBSSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDcEQsb0JBQVcsQ0FBRyxFQUFBLElBQUksQ0FBQyxNQUFNLENBQUEsQ0FBQSxFQUFJLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRztvQkFFdEQsT0FBTztBQUNOLHdCQUFBLElBQUksRUFBRSxJQUFJO3dCQUNWLFFBQVEsRUFBRSxLQUFLLENBQUMsSUFBSTtxQkFDcEIsQ0FBQTtBQUNGLGlCQUFDLENBQUMsQ0FBQztBQUNILGFBQUE7QUFFRCxZQUFBLE9BQU8sTUFBTSxDQUFDO1NBQ2Q7UUFFSyxTQUFTLGNBQWMsQ0FBQyxLQUFhLEVBQUUsTUFBYyxFQUFFLE1BQWMsRUFBRSxTQUFBLEdBQXFCLElBQUksRUFBQTtBQUU1RixZQUFBLElBQUcsU0FBUyxLQUFLLElBQUksS0FBSyxLQUFLLEtBQUssTUFBTSxJQUFJLEtBQUssS0FBSyxNQUFNLENBQUMsRUFBRTtBQUM3RCxnQkFBQSxPQUFPLElBQUksQ0FBQztBQUNmLGFBQUE7QUFFRCxZQUFBLElBQUksTUFBTSxHQUFHLEtBQUssSUFBSSxLQUFLLEdBQUcsTUFBTSxFQUFFO0FBRWxDLGdCQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ2YsYUFBQTtBQUVELFlBQUEsT0FBTyxLQUFLLENBQUM7U0FDaEI7QUFFUCxRQUFBLFNBQVMsbUJBQW1CLENBQUMsVUFBa0IsRUFDekMsUUFBZ0IsRUFDaEIsTUFBMEMsRUFBQTtBQUUvQyxZQUFBLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFOzs7O0FBS3ZDLGdCQUFBLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixnQkFBQSxJQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFDakUsb0JBQUEsT0FBTyxJQUFJLENBQUM7QUFDWixpQkFBQTtBQUNELGFBQUE7QUFFRCxZQUFBLElBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUM7QUFDOUIsZ0JBQUEsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFFbkUsb0JBQUEsSUFBSSxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDOzs7b0JBSWxELElBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQzt3QkFDaEQsY0FBYyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxFQUFFO0FBQ2xELHdCQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ1oscUJBQUE7OztvQkFJRCxJQUFHLGNBQWMsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO3dCQUNoRCxjQUFjLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2xELHdCQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ1oscUJBQUE7QUFDRCxpQkFBQTtBQUNELGFBQUE7QUFFRCxZQUFBLE9BQU8sS0FBSyxDQUFDO1NBQ2I7S0FDRDtBQUNELElBQUEsT0FBTyxDQUFDLEtBQWdDLEVBQUE7UUFDdkMsT0FBT00sZUFBVSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDMUM7QUFDRCxDQUFBLENBQUMsQ0FBQztBQWNILFNBQVMsYUFBYSxDQUFDLGVBQXVCLEVBQUUsZ0JBQXdCLEVBQUUsUUFBZ0IsRUFBQTtBQUV6RixJQUFBLElBQUksTUFBTSxHQUFHLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUM3QyxJQUFHLE1BQU0sS0FBSyxJQUFJLEVBQUU7QUFDbkIsUUFBQSxPQUFPLElBQUksQ0FBQztBQUNaLEtBQUE7SUFFRCxJQUFHLE1BQU0sQ0FBQyxRQUFRLEtBQUssV0FBVyxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssVUFBVSxFQUFFOztBQUdyRSxRQUFBLElBQUksVUFBVSxHQUFHLFVBQVUsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztBQUM5RSxRQUFBLElBQUcsVUFBVSxDQUFDLEtBQUssS0FBSyxLQUFLLEVBQUU7QUFDOUIsWUFBQSxPQUFPLElBQUksQ0FBQztBQUNaLFNBQUE7QUFFRDs7O0FBR0c7UUFDSCxJQUFJLFVBQVUsR0FBRyxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztBQUM5RCxRQUFBLElBQUksUUFBUSxHQUFHLFVBQVUsR0FBRyxVQUFVLENBQUMsYUFBYSxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUE7O1FBRzdFLElBQUksV0FBVyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFBO0FBQ3RELFFBQUEsZUFBZSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7QUFFM0M7OztBQUdHO0FBQ0gsUUFBQSxJQUFJLElBQUksR0FBZTtZQUN0QixVQUFVLEVBQUUsTUFBTSxDQUFDLFFBQVE7QUFDM0IsWUFBQSxVQUFVLEVBQUUsV0FBVztBQUN2QixZQUFBLGFBQWEsRUFBRSxlQUFlO0FBQzlCLFlBQUEsVUFBVSxFQUFFLFVBQVU7QUFDdEIsWUFBQSxRQUFRLEVBQUUsUUFBUTtTQUNsQixDQUFBO0FBQ0QsUUFBQSxPQUFPLElBQUksQ0FBQztBQUNaLEtBQUE7QUFFRCxJQUFBLElBQUcsTUFBTSxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUU7QUFFL0IsUUFBQSxJQUFJLFVBQVUsR0FBb0IsTUFBTSxDQUFDLElBQXVCLENBQUM7QUFDakUsUUFBQSxJQUFJLFVBQVUsR0FBRyxnQkFBZ0IsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDO0FBQzdELFFBQUEsSUFBSSxRQUFRLEdBQUcsZ0JBQWdCLEdBQUcsVUFBVSxDQUFDLFdBQVcsQ0FBQztBQUN6RCxRQUFBLGVBQWUsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzNDLFFBQUEsSUFBSSxJQUFJLEdBQXFCO1lBQzVCLFVBQVUsRUFBRSxNQUFNLENBQUMsUUFBUTtZQUMzQixVQUFVLEVBQUUsVUFBVSxDQUFDLE9BQU87QUFDOUIsWUFBQSxhQUFhLEVBQUUsZUFBZTtBQUM5QixZQUFBLFVBQVUsRUFBRSxVQUFVO0FBQ3RCLFlBQUEsUUFBUSxFQUFFLFFBQVE7WUFDbEIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxXQUFXO1lBQ25DLFlBQVksRUFBRSxVQUFVLENBQUMsWUFBWTtTQUNyQyxDQUFBO0FBQ0QsUUFBQSxPQUFPLElBQUksQ0FBQztBQUNaLEtBQUE7QUFDRixDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsZUFBdUIsRUFBQTs7O0FBSTlDLElBQUEsSUFBSSwyQkFBMkIsR0FBdUQsRUFBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxrQkFBa0IsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO0FBQzFKLElBQUEsSUFBSSwwQkFBMEIsR0FBdUQsRUFBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxZQUFZLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztBQUNsSixJQUFBLElBQUksVUFBVSxHQUFvRCxFQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFBO0FBRXpILElBQUEsSUFBRywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsS0FBSyxLQUFLLEtBQUs7QUFDaEQsUUFBQSwwQkFBMEIsQ0FBQyxJQUFJLENBQUMsS0FBSyxLQUFLLEtBQUs7QUFDL0MsUUFBQSxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxLQUFLLEVBQUU7QUFDbkMsUUFBQSxPQUFPLElBQUksQ0FBQztBQUNaLEtBQUE7QUFFRCxJQUFBLElBQUksWUFBWSxHQUFHLENBQUMsMkJBQTJCLEVBQUUsMEJBQTBCLEVBQUUsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxLQUFPLEVBQUEsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUEsRUFBRSxDQUFDLENBQUM7QUFDN0ksSUFBQSxJQUFHLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBRTNCLElBQUksTUFBTSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFJO1lBQ3ZDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7QUFDbEQsU0FBQyxDQUFDLENBQUE7QUFDRixRQUFBLE9BQU8sTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ3RCLEtBQUE7QUFFRCxJQUFBLElBQUcsMkJBQTJCLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUU7QUFDbkQsUUFBQSxPQUFPLDJCQUEyQixDQUFDO0FBQ25DLEtBQUE7QUFFRCxJQUFBLElBQUcsMEJBQTBCLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUM7QUFDakQsUUFBQSxPQUFPLDBCQUEwQixDQUFDO0FBQ2xDLEtBQUE7QUFFRCxJQUFBLElBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFO0FBQ2xDLFFBQUEsT0FBTyxVQUFVLENBQUM7QUFDbEIsS0FBQTtJQUVELE9BQU0seUNBQXlDLEVBQUM7QUFDakQsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLFVBQXNCLEVBQUE7QUFFOUMsSUFBQSxJQUFJLFdBQVcsR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFBO0lBQ3ZDLFNBQVMsc0JBQXNCLENBQUMsaUJBQXFDLEVBQUE7QUFFcEUsUUFBQSxJQUFJLFlBQVksR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNyRyxXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFFcEQsUUFBQSxJQUFJLFFBQVEsR0FBRyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVqRCxPQUFPO0FBQ04sWUFBQSxRQUFRLEVBQUUsUUFBUTtBQUNsQixZQUFBLFlBQVksRUFBRSxZQUFZO0FBQzFCLFlBQUEsV0FBVyxFQUFFLFdBQVc7U0FDeEIsQ0FBQTtLQUNEO0FBRUQsSUFBQSxJQUFHLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVyxFQUFFO0FBQ3pDLFFBQUEsSUFBSSxpQkFBaUIsR0FBRyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN4RCxRQUFBLElBQUksaUJBQWlCLENBQUMsS0FBSyxLQUFLLEtBQUssRUFBRTtBQUN0QyxZQUFBLE9BQU8sSUFBSSxDQUFDO0FBQ1osU0FBQTtBQUVELFFBQUEsT0FBTyxzQkFBc0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO0FBQ2hELEtBQUE7QUFFRCxJQUFBLElBQUcsVUFBVSxDQUFDLFVBQVUsS0FBSyxVQUFVLEVBQUU7QUFDeEMsUUFBQSxJQUFJLGlCQUFpQixHQUFHLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzNELFFBQUEsSUFBSSxpQkFBaUIsQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFO0FBQ3RDLFlBQUEsT0FBTyxJQUFJLENBQUM7QUFDWixTQUFBO0FBQ0QsUUFBQSxPQUFPLHNCQUFzQixDQUFDLGlCQUFpQixDQUFDLENBQUE7QUFDaEQsS0FBQTtBQUVELElBQUEsSUFBRyxVQUFVLENBQUMsVUFBVSxLQUFLLE9BQU8sRUFBRTtRQUVyQyxJQUFJLFVBQVUsR0FBRyxVQUE4QixDQUFBO1FBQy9DLE9BQU87WUFDTixRQUFRLEVBQUUsbUJBQW1CLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRSxVQUFVLENBQUMsV0FBVyxDQUFDO0FBQzlFLFlBQUEsWUFBWSxFQUFFLEVBQUU7WUFDaEIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxVQUFVO1NBQ2xDLENBQUE7QUFDRCxLQUFBO0FBQ0Y7O0FDdllBOzs7Ozs7QUFNRztBQXNKSSxNQUFNLDhCQUE4QixHQUFHUCxnQkFBVSxDQUFDLE1BQU0sQ0FBZ0I7QUFDOUUsSUFBQSxNQUFNLENBQUMsS0FBSyxFQUFBO1FBQ1gsT0FBT0MsZUFBVSxDQUFDLElBQUksQ0FBQztLQUN2QjtJQUNELE1BQU0sQ0FBQyxRQUF1QixFQUFFLFdBQXdCLEVBQUE7QUFDdkQsUUFBQSxNQUFNLE9BQU8sR0FBRyxJQUFJQyxxQkFBZSxFQUFjLENBQUM7QUFDbEQsUUFBQSxPQUFPLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztLQXVGeEI7QUFDRCxJQUFBLE9BQU8sQ0FBQyxLQUFnQyxFQUFBO1FBQ3ZDLE9BQU9LLGVBQVUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQzFDO0FBQ0QsQ0FBQSxDQUFDOztBQ3BQSSxTQUFVLGVBQWUsQ0FBQyxtQkFBMkIsRUFBQTtJQUV2RCxJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUE7SUFDakIsSUFBSSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7SUFDekIsSUFBSSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7SUFDekIsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDO0lBRXZCLElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQztJQUN4QixJQUFJLEVBQUUsa0JBQWtCLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxnQ0FBZ0MsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3RHLElBQUcsaUJBQWlCLEdBQUcsQ0FBQyxFQUFFO0FBQ3RCLFFBQUEsU0FBUyxFQUFFLENBQUM7UUFDWixXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ25CLGdCQUFnQixJQUFJLGlCQUFpQixDQUFBO0FBQ3hDLEtBQUE7QUFFRCxJQUFBLElBQUksUUFBUSxHQUFHLHVCQUF1QixDQUFDLGtCQUFrQixDQUFDLENBQUE7SUFDMUQsSUFBRyxRQUFRLENBQUMsaUJBQWlCLEVBQUU7UUFDM0IsSUFBRyxXQUFXLEtBQUssS0FBSyxFQUFFO1lBQ3RCLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFDbkIsWUFBQSxTQUFTLEVBQUUsQ0FBQztBQUNmLFNBQUE7QUFDRCxRQUFBLGtCQUFrQixHQUFHLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQTtBQUNoRCxRQUFBLGdCQUFnQixJQUFJLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQTtBQUNqRCxLQUFBO0FBRUQsSUFBQSxJQUFJLFFBQVEsR0FBRyx1QkFBdUIsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO0lBQzFELElBQUcsUUFBUSxDQUFDLGlCQUFpQixFQUFFO1FBQzNCLElBQUcsV0FBVyxLQUFLLEtBQUssRUFBRTtZQUN0QixXQUFXLEdBQUcsSUFBSSxDQUFDO0FBQ25CLFlBQUEsU0FBUyxFQUFFLENBQUM7QUFDZixTQUFBO0FBQ0QsUUFBQSxrQkFBa0IsR0FBRyxRQUFRLENBQUMsa0JBQWtCLENBQUE7QUFDaEQsUUFBQSxnQkFBZ0IsSUFBSSxRQUFRLENBQUMsaUJBQWlCLENBQUE7QUFDakQsS0FBQTtBQUVELElBQUEsSUFBSSxNQUFNLEdBQUcscUJBQXFCLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtJQUN0RCxJQUFHLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRTtRQUN6QixJQUFHLFdBQVcsS0FBSyxLQUFLLEVBQUU7WUFDdEIsV0FBVyxHQUFHLElBQUksQ0FBQztBQUNuQixZQUFBLFNBQVMsRUFBRSxDQUFDO0FBQ2YsU0FBQTtBQUNELFFBQUEsa0JBQWtCLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixDQUFBO0FBQzlDLFFBQUEsY0FBYyxJQUFJLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztBQUM5QyxLQUFBO0lBRUQsT0FBTztBQUNILFFBQUEsU0FBUyxFQUFFLFNBQVM7QUFDcEIsUUFBQSxnQkFBZ0IsRUFBRSxnQkFBZ0I7QUFDbEMsUUFBQSxnQkFBZ0IsRUFBRSxnQkFBZ0I7QUFDbEMsUUFBQSxjQUFjLEVBQUUsY0FBYztBQUM5QixRQUFBLGtCQUFrQixFQUFFLGtCQUFrQjtRQUN0QyxjQUFjLEVBQUUsa0JBQWtCLEtBQUssbUJBQW1CO0tBQzdELENBQUE7QUFDTCxDQUFDO0FBRUQsTUFBTSx3QkFBd0IsR0FBRywyQ0FBMkMsQ0FBQTtBQUM1RSxTQUFTLHFCQUFxQixDQUFDLG1CQUEyQixFQUFBO0FBRXRELElBQUEsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFBO0lBRWhGLElBQUksa0JBQWtCLEdBQUcsbUJBQW1CLENBQUM7SUFDN0MsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBRWYsSUFBQSxLQUFJLElBQUksS0FBSyxJQUFJLE9BQU8sRUFBRTtBQUN0QixRQUFBLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFBO1FBQ3JDLElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUE7QUFDakMsUUFBQSxJQUFJLFFBQVEsR0FBRyxVQUFVLEdBQUcsV0FBVyxDQUFDO0FBRXhDLFFBQUEsSUFBSSxlQUFlLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQzlCLFFBQUEsSUFBSSxlQUFlLEdBQUcsQ0FBTyxJQUFBLEVBQUEsZUFBZSxFQUFFLENBQUE7QUFDOUMsUUFBQSxNQUFNLElBQUksZUFBZSxDQUFDLE1BQU0sR0FBRyxXQUFXLENBQUE7QUFFOUMsUUFBQSxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxHQUFHLGVBQWUsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDbkgsT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFBO0FBQ3hCLFFBQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxtQkFBbUIsQ0FBQyxDQUFBO0FBQ3RELFFBQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxrQkFBa0IsQ0FBQyxDQUFBO1FBQ3BELE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQTtBQUNyQixLQUFBO0lBQ0QsT0FBTztBQUNILFFBQUEsa0JBQWtCLEVBQUUsa0JBQWtCO1FBQ3RDLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxNQUFNO0tBQ3BDLENBQUE7QUFDTCxDQUFDO0FBRUQsTUFBTSwwQkFBMEIsR0FBRyxzRUFBc0UsQ0FBQTtBQUN6RyxTQUFTLHVCQUF1QixDQUFDLG1CQUEyQixFQUFBO0FBRXhELElBQUEsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFBO0lBRWxGLElBQUksa0JBQWtCLEdBQUcsbUJBQW1CLENBQUM7SUFDN0MsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBRWYsSUFBQSxLQUFJLElBQUksS0FBSyxJQUFJLE9BQU8sRUFBRTtBQUN0QixRQUFBLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFBO1FBQ3JDLElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUE7QUFDakMsUUFBQSxJQUFJLFFBQVEsR0FBRyxVQUFVLEdBQUcsV0FBVyxDQUFDO0FBRXhDLFFBQUEsSUFBSSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDaEMsUUFBQSxJQUFJLGVBQWUsR0FBRyxDQUFPLElBQUEsRUFBQSxpQkFBaUIsTUFBTSxDQUFBO0FBQ3BELFFBQUEsTUFBTSxJQUFJLGVBQWUsQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFBO0FBRTlDLFFBQUEsa0JBQWtCLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsR0FBRyxlQUFlLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQ25ILE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQTtBQUN4QixRQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUUsbUJBQW1CLENBQUMsQ0FBQTtBQUN0RCxRQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtRQUNwRCxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUE7QUFDckIsS0FBQTtJQUNELE9BQU87QUFDSCxRQUFBLGtCQUFrQixFQUFFLGtCQUFrQjtRQUN0QyxpQkFBaUIsRUFBRSxPQUFPLENBQUMsTUFBTTtLQUNwQyxDQUFBO0FBQ0wsQ0FBQztBQUVELE1BQU0sMEJBQTBCLEdBQUcsK0NBQStDLENBQUE7QUFDbEYsU0FBUyx1QkFBdUIsQ0FBQyxtQkFBMkIsRUFBQTtBQUV4RCxJQUFBLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLDBCQUEwQixDQUFDLENBQUMsQ0FBQTtJQUVsRixJQUFJLGtCQUFrQixHQUFHLG1CQUFtQixDQUFDO0lBQzdDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztBQUVmLElBQUEsS0FBSSxJQUFJLEtBQUssSUFBSSxPQUFPLEVBQUU7QUFDdEIsUUFBQSxJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQTtRQUNyQyxJQUFJLFdBQVcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFBO0FBQ2pDLFFBQUEsSUFBSSxRQUFRLEdBQUcsVUFBVSxHQUFHLFdBQVcsQ0FBQztBQUV4QyxRQUFBLElBQUksaUJBQWlCLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ2hDLFFBQUEsSUFBSSxlQUFlLEdBQUcsQ0FBTyxJQUFBLEVBQUEsaUJBQWlCLEVBQUUsQ0FBQTtBQUNoRCxRQUFBLE1BQU0sSUFBSSxlQUFlLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQTtBQUU5QyxRQUFBLGtCQUFrQixHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLEdBQUcsZUFBZSxHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUNuSCxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUE7QUFDeEIsUUFBQSxPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixFQUFFLG1CQUFtQixDQUFDLENBQUE7QUFDdEQsUUFBQSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLGtCQUFrQixDQUFDLENBQUE7UUFDcEQsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFBO0FBQ3JCLEtBQUE7SUFDRCxPQUFPO0FBQ0gsUUFBQSxrQkFBa0IsRUFBRSxrQkFBa0I7UUFDdEMsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLE1BQU07S0FDcEMsQ0FBQTtBQUNMLENBQUM7QUFFRCxNQUFNLG9DQUFvQyxHQUFHLG9EQUFvRCxDQUFDO0FBQ2xHLFNBQVMsZ0NBQWdDLENBQUMsbUJBQTJCLEVBQUE7QUFFakUsSUFBQSxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDLENBQUE7SUFFNUYsSUFBSSxrQkFBa0IsR0FBRyxtQkFBbUIsQ0FBQztJQUM3QyxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFFZixJQUFBLEtBQUksSUFBSSxLQUFLLElBQUksT0FBTyxFQUFFO0FBRXRCLFFBQUEsSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUE7UUFDckMsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQTtBQUNqQyxRQUFBLElBQUksUUFBUSxHQUFHLFVBQVUsR0FBRyxXQUFXLENBQUM7QUFFeEMsUUFBQSxJQUFJLG9CQUFvQixHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNuQyxJQUFJLFlBQVksR0FBRyxvQkFBb0IsQ0FBQTtBQUN2QyxRQUFBLElBQUksaUJBQWlCLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ2hDLFFBQUEsSUFBSSxlQUFlLEdBQUcsQ0FBTyxJQUFBLEVBQUEsaUJBQWlCLEVBQUUsQ0FBQTtRQUdoRCxJQUFJLFFBQVEsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUE7UUFDcEQsSUFBRyxRQUFRLEtBQUssSUFBSSxFQUFFO1lBQ2xCLElBQUksRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtBQUMzQixZQUFBLGVBQWUsR0FBRyxDQUFHLEVBQUEsZUFBZSxDQUFLLEVBQUEsRUFBQSxFQUFFLEVBQUUsQ0FBQTtBQUU3QyxZQUFBLElBQUksVUFBVSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUE7WUFDL0IsSUFBSSxRQUFRLEdBQUcsVUFBVSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUE7WUFFOUMsWUFBWSxHQUFHLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUE7WUFDeEQsWUFBWSxJQUFJLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFDM0QsU0FBQTtRQUNELFlBQVksR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLGlCQUFpQixFQUFFLGlCQUFpQixDQUFDLENBQUE7QUFFekUsUUFBQSxJQUFJLGVBQWUsR0FBRyxDQUFBLEVBQUcsZUFBZSxDQUFLLEVBQUEsRUFBQSxZQUFZLEVBQUUsQ0FBQTtBQUUzRCxRQUFBLE1BQU0sSUFBSSxlQUFlLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQTtBQUU5QyxRQUFBLGtCQUFrQixHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLEdBQUcsZUFBZSxHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUNuSCxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUE7QUFDeEIsUUFBQSxPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixFQUFFLG1CQUFtQixDQUFDLENBQUE7QUFDdEQsUUFBQSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLGtCQUFrQixDQUFDLENBQUE7UUFDcEQsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFBO0FBQ3JCLEtBQUE7SUFFRCxPQUFPO0FBQ0gsUUFBQSxrQkFBa0IsRUFBRSxrQkFBa0I7UUFDdEMsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLE1BQU07S0FDcEMsQ0FBQTtBQUNMOztBQ2hNcUIsTUFBQSx1QkFBd0IsU0FBUUMseUJBQWdCLENBQUE7SUFFakUsV0FBWSxDQUFBLEdBQVEsRUFBUyxNQUEyQixFQUFBO0FBQ3BELFFBQUEsS0FBSyxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztRQURNLElBQU0sQ0FBQSxNQUFBLEdBQU4sTUFBTSxDQUFxQjtLQUV2RDtJQUVELE9BQU8sR0FBQTtBQUNILFFBQUEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUN6QixRQUFBLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxrQ0FBa0MsRUFBRSxDQUFDLENBQUM7UUFFOUUsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRXpELElBQUlDLGdCQUFPLENBQUMsbUJBQW1CLENBQUM7YUFDM0IsT0FBTyxDQUFDLDBDQUEwQyxDQUFDO2FBQ25ELE9BQU8sQ0FBQyw4TUFBOE0sQ0FBQztBQUN2TixhQUFBLFNBQVMsQ0FBQyxDQUFDLE1BQU0sS0FBSTtZQUNsQixNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUE7WUFDMUIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtZQUN2RSxNQUFNLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtBQUMxQixZQUFBLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLEtBQUk7QUFDcEIsZ0JBQUEsbUJBQW1CLENBQUMsTUFBTSxDQUFDLDJCQUEyQixHQUFHLEdBQUcsQ0FBQztBQUM3RCxnQkFBQSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFBO0FBQzlCLGFBQUMsQ0FBQyxDQUFBO0FBQ04sU0FBQyxDQUFDLENBQUE7UUFFTixJQUFJQSxnQkFBTyxDQUFDLG1CQUFtQixDQUFDO2FBQy9CLE9BQU8sQ0FBQyw2Q0FBNkMsQ0FBQztBQUN0RCxhQUFBLE9BQU8sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztBQUN0QyxhQUFBLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FDVCxDQUFDLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQztBQUNuRSxhQUFBLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSTtBQUNaLFlBQUEsbUJBQW1CLENBQUMsTUFBTSxDQUFDLDZCQUE2QixHQUFHLENBQUMsQ0FBQTtBQUM1RCxZQUFBLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUE7U0FDN0IsQ0FBQyxDQUNMLENBQUE7UUFFRCxJQUFJQSxnQkFBTyxDQUFDLG1CQUFtQixDQUFDO2FBQy9CLE9BQU8sQ0FBQywrQkFBK0IsQ0FBQztBQUN4QyxhQUFBLE9BQU8sQ0FBQyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztBQUN2QyxhQUFBLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FDVCxDQUFDLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQztBQUN6RCxhQUFBLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSTtBQUNaLFlBQUEsbUJBQW1CLENBQUMsTUFBTSxDQUFDLG1CQUFtQixHQUFHLENBQUMsQ0FBQTtBQUNsRCxZQUFBLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUE7U0FDN0IsQ0FBQyxDQUNMLENBQUE7QUFFRCxRQUFBLElBQUdDLGlCQUFRLENBQUMsUUFBUSxLQUFLLElBQUksRUFBRTtZQUMzQixJQUFJRCxnQkFBTyxDQUFDLG1CQUFtQixDQUFDO2lCQUMzQixPQUFPLENBQUMseUNBQXlDLENBQUM7aUJBQ2xELFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FDVCxDQUFDLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUk7QUFDakUsZ0JBQUEsbUJBQW1CLENBQUMsTUFBTSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUE7QUFDN0MsZ0JBQUEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQTthQUM3QixDQUFDLENBQ0wsQ0FBQztBQUNULFNBQUE7UUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsK0NBQStDLEVBQUMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQztBQUMzSCxRQUFBLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxFQUFDLE9BQU8sRUFBRSx5Q0FBeUMsRUFBQyxFQUFFLENBQUMsQ0FBQTtRQUMvRixNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7QUFFM0QsUUFBQSxJQUFJLENBQUMscUJBQXFCLENBQUMscUJBQXFCLENBQUMsQ0FBQztBQUNsRCxRQUFBLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0FBRS9DLFFBQUEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7QUFFL0IsUUFBQSxJQUFJLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsR0FBRyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDbEYsUUFBQSxJQUFJQSxnQkFBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7YUFDNUIsT0FBTyxDQUFDLFFBQVEsQ0FBQzthQUNqQixPQUFPLENBQUMscUdBQXFHLENBQUM7QUFDOUcsYUFBQSxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUk7WUFDYixDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsNERBQTRELENBQUMsQ0FBQTtBQUN6RixZQUFBLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUMsSUFBSSxFQUFFLEVBQUMsT0FBTyxFQUFFLDJCQUEyQixFQUFDLEVBQUMsQ0FBQyxDQUFDO0FBQ2pGLFlBQUEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7QUFDZCxnQkFBQSxJQUFJLEVBQUUseUNBQXlDO0FBQ2xELGFBQUEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUU7QUFDZixnQkFBQSxJQUFJLEVBQUU7QUFDRixvQkFBQSxLQUFLLEVBQUUsMkJBQTJCO0FBQ2xDLG9CQUFBLEdBQUcsRUFBRSxDQUFzRyxtR0FBQSxFQUFBLE9BQU8sZ0JBQWdCLFNBQVMsQ0FBQSx3REFBQSxFQUEyRCxXQUFXLENBQUUsQ0FBQTtBQUN0TixpQkFBQTtBQUNKLGFBQUEsQ0FBQyxDQUFBO0FBQ04sU0FBQyxDQUFDLENBQUE7S0FDTDtJQUVPLHVCQUF1QixHQUFBO0FBQzNCLFFBQUEsSUFBSSxPQUFPLEdBQUcsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO0FBQ3JDLFFBQUEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxJQUFHO0FBQ3hCLFlBQUEsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxJQUFHO0FBQ3RCLGdCQUFBLElBQUksQ0FBQyxTQUFTLEdBQUcsMkdBQTJHLENBQUM7QUFDakksYUFBQyxDQUFDLENBQUM7QUFDSCxZQUFBLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbkIsWUFBQSxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25CLFlBQUEsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxJQUFHO0FBQ3RCLGdCQUFBLElBQUksQ0FBQyxTQUFTLEdBQUcsa0lBQWtJLENBQUM7QUFDeEosYUFBQyxDQUFDLENBQUM7QUFDSCxZQUFBLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbkIsWUFBQSxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25CLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLElBQUc7QUFDMUIsZ0JBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsZ0VBQWdFLENBQUMsQ0FBQztBQUN4RixnQkFBQSxJQUFJLENBQUMsU0FBUyxHQUFHLGVBQWUsQ0FBQztBQUNyQyxhQUFDLENBQUMsQ0FBQztBQUNILFlBQUEsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxJQUFHO0FBQ3RCLGdCQUFBLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLDJCQUEyQixDQUFDLENBQUM7Z0JBQ25ELElBQUksQ0FBQyxTQUFTLEdBQUc7O2lGQUVnRCxDQUFDO0FBQ3RFLGFBQUMsQ0FBQyxDQUFDO0FBR1AsU0FBQyxDQUFDLENBQUE7QUFDRixRQUFBLE9BQU8sT0FBTyxDQUFDO0tBQ2xCO0lBRU8sc0JBQXNCLEdBQUE7QUFDMUIsUUFBQSxJQUFJLE9BQU8sR0FBRyxJQUFJLGdCQUFnQixFQUFFLENBQUM7QUFDckMsUUFBQSxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUc7QUFDeEIsWUFBQSxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxJQUFJLElBQUc7QUFDdEIsZ0JBQUEsSUFBSSxDQUFDLFNBQVMsR0FBRyxzRkFBc0YsQ0FBQztBQUM1RyxhQUFDLENBQUMsQ0FBQztBQUNILFlBQUEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNuQixZQUFBLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSwwR0FBMEcsRUFBRSxDQUFDLENBQUE7QUFDM0osU0FBQyxDQUFDLENBQUE7QUFDRixRQUFBLE9BQU8sT0FBTyxDQUFDO0tBQ2xCO0FBRU8sSUFBQSxxQkFBcUIsQ0FBQyxxQkFBcUMsRUFBQTtBQUUvRCxRQUFBLElBQUksT0FBTyxHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztBQUNyQyxRQUFBLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLEdBQUcsSUFBRztBQUN4QixZQUFBLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLElBQUksSUFBRztBQUN0QixnQkFBQSxJQUFJLENBQUMsU0FBUyxHQUFHLHdIQUF3SCxDQUFDO0FBQzlJLGFBQUMsQ0FBQyxDQUFDO0FBQ0gsWUFBQSxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25CLFlBQUEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQixHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsSUFBSSxJQUFHO0FBQzFCLGdCQUFBLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLGdFQUFnRSxDQUFDLENBQUM7QUFDeEYsZ0JBQUEsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFVLENBQUM7QUFDaEMsYUFBQyxDQUFDLENBQUM7QUFDSCxZQUFBLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLElBQUksSUFBRztBQUN0QixnQkFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSwyQkFBMkIsQ0FBQyxDQUFDO0FBQ25ELGdCQUFBLElBQUksQ0FBQyxTQUFTLEdBQUcsa0dBQWtHLENBQUM7QUFDeEgsYUFBQyxDQUFDLENBQUM7QUFDSCxZQUFBLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbkIsWUFBQSxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxJQUFJLElBQUc7QUFDdEIsZ0JBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsMkJBQTJCLENBQUMsQ0FBQztBQUNuRCxnQkFBQSxJQUFJLENBQUMsU0FBUyxHQUFHLHNFQUFzRSxDQUFDO0FBQzVGLGFBQUMsQ0FBQyxDQUFDO0FBQ1AsU0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLGtCQUFrQixHQUFHLFNBQVMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxJQUFHO1lBQ3pDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLEVBQUUscUNBQXFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2hFLFlBQUEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQixHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxFQUFFLCtDQUErQyxFQUFFLENBQUMsQ0FBQztBQUM5RSxTQUFDLENBQUMsQ0FBQztRQUNILElBQUlBLGdCQUFPLENBQUMscUJBQXFCLENBQUM7YUFDN0IsT0FBTyxDQUFDLDRDQUE0QyxDQUFDO2FBQ3JELE9BQU8sQ0FBQyxPQUFPLENBQUM7QUFDaEIsYUFBQSxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBSztZQUM1RCxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxrQkFBa0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7QUFDOUgsWUFBQSxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQUs7QUFDakIsZ0JBQUEsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLEtBQUssRUFBRTtvQkFDM0IsT0FBTztBQUNWLGlCQUFBO0FBRUQsZ0JBQUEsZ0JBQWdCLEVBQUUsQ0FBQztBQUN2QixhQUFDLENBQUM7WUFDRixLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDaEIsQ0FBQyxDQUNELENBQUM7S0FDVDtBQUVPLElBQUEsa0JBQWtCLENBQUMscUJBQXFDLEVBQUE7QUFFNUQsUUFBQSxJQUFJLE9BQU8sR0FBRyxJQUFJLGdCQUFnQixFQUFFLENBQUM7QUFDckMsUUFBQSxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUc7QUFDeEIsWUFBQSxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxJQUFJLElBQUc7QUFDdEIsZ0JBQUEsSUFBSSxDQUFDLFNBQVMsR0FBRyw0SkFBNEosQ0FBQztBQUNsTCxhQUFDLENBQUMsQ0FBQztBQUNILFlBQUEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNuQixZQUFBLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbkIsWUFBQSxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxJQUFJLElBQUc7QUFDdEIsZ0JBQUEsSUFBSSxDQUFDLFNBQVMsR0FBRyx3SEFBd0gsQ0FBQztBQUM5SSxhQUFDLENBQUMsQ0FBQztBQUNILFlBQUEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNuQixZQUFBLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbkIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksSUFBRztBQUMxQixnQkFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxnRUFBZ0UsQ0FBQyxDQUFDO0FBQ3hGLGdCQUFBLElBQUksQ0FBQyxTQUFTLEdBQUcsVUFBVSxDQUFDO0FBQ2hDLGFBQUMsQ0FBQyxDQUFDO0FBQ0gsWUFBQSxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxJQUFJLElBQUc7QUFDdEIsZ0JBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsMkJBQTJCLENBQUMsQ0FBQztBQUNuRCxnQkFBQSxJQUFJLENBQUMsU0FBUyxHQUFHLDhGQUE4RixDQUFDO0FBQ3BILGFBQUMsQ0FBQyxDQUFDO0FBQ0gsWUFBQSxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25CLFlBQUEsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxJQUFHO0FBQ3RCLGdCQUFBLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLDJCQUEyQixDQUFDLENBQUM7QUFDbkQsZ0JBQUEsSUFBSSxDQUFDLFNBQVMsR0FBRyxzRUFBc0UsQ0FBQztBQUM1RixhQUFDLENBQUMsQ0FBQztBQUNQLFNBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxrQkFBa0IsR0FBRyxTQUFTLENBQUMsRUFBRSxFQUFFLEdBQUcsSUFBRztZQUN6QyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxFQUFFLHFDQUFxQyxFQUFFLENBQUMsQ0FBQztBQUNoRSxZQUFBLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbkIsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksRUFBRSwrQ0FBK0MsRUFBRSxDQUFDLENBQUM7QUFDOUUsU0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJQSxnQkFBTyxDQUFDLHFCQUFxQixDQUFDO2FBQzdCLE9BQU8sQ0FBQyxrREFBa0QsQ0FBQzthQUMzRCxPQUFPLENBQUMsT0FBTyxDQUFDO0FBQ2hCLGFBQUEsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQUs7WUFDdEQsTUFBTSxLQUFLLEdBQUcsWUFBWSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsa0JBQWtCLEVBQUUsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0FBQzlILFlBQUEsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFLO0FBQ2pCLGdCQUFBLElBQUksS0FBSyxDQUFDLFNBQVMsS0FBSyxLQUFLLEVBQUU7b0JBQzNCLE9BQU87QUFDVixpQkFBQTtBQUVELGdCQUFBLHdCQUF3QixFQUFFLENBQUM7QUFDL0IsYUFBQyxDQUFDO1lBQ0YsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ2hCLENBQUMsQ0FDTCxDQUFDO0tBQ0w7QUFDSixDQUFBO0FBRUssTUFBTyxZQUFhLFNBQVFFLGNBQUssQ0FBQTtBQUVuQyxJQUFBLE9BQU8sb0JBQW9CLENBQUMsR0FBUSxFQUNSLElBQVksRUFDWixPQUErQyxFQUFBO0FBRXZFLFFBQUEsT0FBTyxJQUFJLFlBQVksQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUE7S0FDbEU7QUFFRCxJQUFBLE9BQU8sdUJBQXVCLENBQUMsR0FBUSxFQUNSLGFBQTBCLEVBQzFCLE9BQStDLEVBQUE7UUFDMUUsT0FBTyxJQUFJLFlBQVksQ0FBQyxHQUFHLEVBQUUsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0tBQ3ZEO0FBSUQsSUFBQSxXQUFBLENBQW9CLEdBQVEsRUFDUixhQUEwQixFQUMxQixPQUErQyxFQUFBO1FBQy9ELEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUlmLElBQVMsQ0FBQSxTQUFBLEdBQVksS0FBSyxDQUFDO0FBSHZCLFFBQUEsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7QUFDbkMsUUFBQSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztLQUMxQjtJQUVLLE9BQU8sR0FBQTs7QUFDVCxZQUFBLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO1lBRTlDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDNUMsSUFBSUMsd0JBQWUsQ0FBQyxRQUFRLENBQUM7QUFDeEIsaUJBQUEsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO0FBQ25DLGlCQUFBLE1BQU0sRUFBRTtpQkFDUixPQUFPLENBQUMsTUFBSztBQUNWLGdCQUFBLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2dCQUN0QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDakIsYUFBQyxDQUFDLENBQUM7WUFDUCxJQUFJQSx3QkFBZSxDQUFDLFFBQVEsQ0FBQztBQUN4QixpQkFBQSxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7aUJBQ3JDLE9BQU8sQ0FBQyxNQUFLO2dCQUNWLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNqQixhQUFDLENBQUMsQ0FBQztTQUNWLENBQUEsQ0FBQTtBQUFBLEtBQUE7SUFDRCxNQUFNLEdBQUE7UUFDRixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7S0FDbEI7QUFDSixDQUFBO0FBRUQsU0FBZSx3QkFBd0IsR0FBQTs7UUFFbkMsU0FBUyxzQkFBc0IsQ0FBQyxPQUFlLEVBQUE7WUFFM0MsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUVoQzs7O0FBR0c7WUFDSCxJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUE7QUFDdkIsWUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFFbEMsSUFBSSxJQUFJLEdBQUdDLGdCQUFrQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4RCxJQUFHLElBQUksQ0FBQyxVQUFVLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssS0FBSyxFQUFFO0FBRWxELG9CQUFBLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtvQkFDM0IsSUFBSSxJQUFJLEdBQUcsWUFBWSxDQUFDO0FBQ3hCLG9CQUFBLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDdEIsb0JBQUEsSUFBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFO0FBQ3JDLHdCQUFBLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLHFCQUFBO29CQUNELElBQUksR0FBRyxHQUFHLElBQUksQ0FBQSxLQUFBLEVBQVEsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFBLENBQUUsQ0FBQztBQUVsQyxvQkFBQSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ2hCLG9CQUFBLGVBQWUsRUFBRSxDQUFDO0FBQ3JCLGlCQUFBO0FBQ0osYUFBQTtZQUVELElBQUcsZUFBZSxLQUFLLENBQUMsRUFBRTtnQkFDdEIsT0FBTztBQUNILG9CQUFBLGtCQUFrQixFQUFFLE9BQU87QUFDM0Isb0JBQUEsaUJBQWlCLEVBQUUsQ0FBQztpQkFDdkIsQ0FBQztBQUNMLGFBQUE7WUFFRCxJQUFJLGNBQWMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3RDLE9BQU87QUFDSCxnQkFBQSxrQkFBa0IsRUFBRSxjQUFjO0FBQ2xDLGdCQUFBLGlCQUFpQixFQUFFLGVBQWU7YUFDckMsQ0FBQztTQUNMO1FBRUQsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLEtBQUksSUFBSSxNQUFNLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFO1lBQzVDLElBQUksbUJBQW1CLEdBQUcsTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUV2RCxZQUFBLElBQUksTUFBTSxHQUFHLHNCQUFzQixDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDekQsWUFBQSxJQUFHLE1BQU0sQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLEVBQUU7QUFDN0IsZ0JBQUEsS0FBSyxJQUFJLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztBQUNsQyxnQkFBQSxTQUFTLEVBQUUsQ0FBQztBQUVaLGdCQUFBLElBQUksa0JBQWtCLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixDQUFDO2dCQUNuRCxJQUFHLGtCQUFrQixLQUFLLG1CQUFtQixFQUFFO29CQUMzQyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztBQUNoRCxpQkFBQTtBQUNJLHFCQUFBO0FBQ0Qsb0JBQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ2pELGlCQUFBO0FBQ0osYUFBQTtBQUNKLFNBQUE7UUFDRCxJQUFJQyxlQUFNLENBQUMsQ0FBdUIsb0JBQUEsRUFBQSxLQUFLLHVCQUF1QixTQUFTLENBQUEsT0FBQSxDQUFTLENBQUMsQ0FBQTtLQUNwRixDQUFBLENBQUE7QUFBQSxDQUFBO0FBRUQsU0FBZSxnQkFBZ0IsR0FBQTs7UUFFM0IsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFBO1FBQ2pCLElBQUksZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLElBQUksZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQztRQUN2QixLQUFJLElBQUksTUFBTSxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsRUFBRTtZQUM1QyxJQUFJLG1CQUFtQixHQUFHLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDdkQsWUFBQSxJQUFJLE1BQU0sR0FBRyxlQUFlLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUVsRCxZQUFBLFNBQVMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDO0FBQzlCLFlBQUEsZ0JBQWdCLElBQUksTUFBTSxDQUFDLGdCQUFnQixDQUFDO0FBQzVDLFlBQUEsZ0JBQWdCLElBQUksTUFBTSxDQUFDLGdCQUFnQixDQUFDO0FBQzVDLFlBQUEsY0FBYyxJQUFJLE1BQU0sQ0FBQyxjQUFjLENBQUM7QUFDeEMsWUFBQSxJQUFJLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQzs7WUFHbkQsSUFBRyxNQUFNLENBQUMsY0FBYyxFQUFFO2dCQUN0QixHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtBQUMvQyxhQUdBO0FBQ0osU0FBQTtBQUVELFFBQUEsSUFBSUEsZUFBTSxDQUFDLENBQXVCLG9CQUFBLEVBQUEsZ0JBQWdCLENBQXFCLGtCQUFBLEVBQUEsZ0JBQWdCLENBQXdCLHFCQUFBLEVBQUEsY0FBYyxDQUE2QiwwQkFBQSxFQUFBLFNBQVMsQ0FBUyxPQUFBLENBQUEsQ0FBQyxDQUFBO0tBQ2hMLENBQUEsQ0FBQTtBQUFBLENBQUE7QUFFRCxTQUFTLHFCQUFxQixDQUFDLFdBQXdCLEVBQUE7QUFDbkQsSUFBQSxJQUFJLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNsRCxJQUFJLFNBQVMsR0FBRyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDaEUsSUFBSSxPQUFPLEdBQUcsYUFBYSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pELElBQUksV0FBVyxHQUFHLFFBQVEsQ0FBQztJQUMzQixJQUFJLGVBQWUsQ0FBQyxTQUFTLENBQUM7UUFDMUIsZUFBZSxDQUFDLE9BQU8sQ0FBQyxFQUFFO0FBQzFCLFFBQUEsU0FBUyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQixXQUFXLEdBQUcsU0FBUyxDQUFDO0FBQzNCLEtBQUE7QUFDSSxTQUFBO1FBQ0QsU0FBUyxHQUFHLFFBQVEsQ0FBQztRQUNyQixPQUFPLEdBQUcsUUFBUSxDQUFDO1FBQ25CLFdBQVcsR0FBRyxRQUFRLENBQUM7QUFDMUIsS0FBQTtBQUNELElBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLENBQUM7QUFDL0MsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLGFBQXFCLEVBQUE7QUFFMUMsSUFBQSxJQUFJLFNBQVMsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDaEMsSUFBRyxTQUFTLEtBQUssR0FBRyxFQUFFO0FBQ2xCLFFBQUEsT0FBTyxLQUFLLENBQUE7QUFDZixLQUFBO0FBRUQsSUFBQSxJQUFHLGFBQWEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO0FBQzNCLFFBQUEsT0FBTyxLQUFLLENBQUE7QUFDZixLQUFBO0FBRUQsSUFBQSxPQUFPLGlCQUFpQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQTtBQUNoRDs7QUNqWkE7Ozs7OztBQU1HO0FBeUJILE1BQU0sb0JBQW9CLEdBQUc7SUFDekIsb0JBQW9CO0lBQ3BCLG9CQUFvQjtDQUN2QixDQUFBO0FBQ29CLE1BQUEsbUJBQW9CLFNBQVFDLGVBQU0sQ0FBQTtBQUF2RCxJQUFBLFdBQUEsR0FBQTs7QUFFSSxRQUFBLElBQUEsQ0FBQSxlQUFlLEdBQXdCLG1CQUFtQixDQUFDLE1BQU0sQ0FBQztBQUNsRSxRQUFBLElBQUEsQ0FBQSxhQUFhLEdBQXFCLElBQUksZ0JBQWdCLEVBQUUsQ0FBQzs7S0F3MkI1RDtJQXQyQk0sTUFBTSxHQUFBOztBQUVMLFlBQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0FBRTdDLFlBQUEsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7QUFFMUIsWUFBQSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztBQUU1QyxZQUFBLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO0FBQzVELFlBQUEsSUFBSSxDQUFDLHVCQUF1QixDQUFDLDhCQUE4QixDQUFDLENBQUM7QUFFN0QsWUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsb0JBQW9CLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO0FBRWpELGdCQUFBLElBQUksUUFBUSxHQUFHLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ3RDLGdCQUFBLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUN0RCxhQUFBO1lBQ0QsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7QUFFbEMsWUFBQSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksdUJBQXVCLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFBO1lBRS9ELElBQUksQ0FBQyxVQUFVLENBQUM7QUFDWixnQkFBQSxFQUFFLEVBQUUsQ0FBNkIsMkJBQUEsQ0FBQTtBQUNqQyxnQkFBQSxJQUFJLEVBQUUsQ0FBaUQsK0NBQUEsQ0FBQTtnQkFDdkQsUUFBUSxFQUFFLE1BQVcsU0FBQSxDQUFBLElBQUEsRUFBQSxLQUFBLENBQUEsRUFBQSxLQUFBLENBQUEsRUFBQSxhQUFBO29CQUVqQixJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsY0FBYyxDQUFDO0FBQzNFLG9CQUFBLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0FBRTFCLG9CQUFBLElBQUksWUFBWSxHQUFHLENBQUEseUJBQUEsRUFBNEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxjQUFjLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxDQUFBO0FBQ3BHLG9CQUFBLElBQUdMLGlCQUFRLENBQUMsUUFBUSxLQUFLLElBQUksRUFBRTt3QkFDM0IsWUFBWSxJQUFJLDBEQUEwRCxDQUFBO0FBQzdFLHFCQUFBO0FBQ0Qsb0JBQUEsSUFBSUksZUFBTSxDQUFFLFlBQVksQ0FBQyxDQUFDO0FBQzlCLGlCQUFDLENBQUE7QUFDSixhQUFBLENBQUMsQ0FBQzs7WUFHSCxJQUFJLENBQUMsVUFBVSxDQUFDO0FBQ1osZ0JBQUEsRUFBRSxFQUFFLENBQTRCLDBCQUFBLENBQUE7QUFDaEMsZ0JBQUEsSUFBSSxFQUFFLENBQTRCLDBCQUFBLENBQUE7QUFDbEMsZ0JBQUEsY0FBYyxFQUFFLENBQUMsTUFBTSxFQUFFLElBQUksS0FBSTtvQkFFN0IsSUFBSTt3QkFDQSxJQUFJLG1CQUFtQixHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7QUFFbkQsd0JBQUEsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLGdCQUFnQixDQUNwRCxDQUFBOzZCQUM2QixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUE7Ozs7Ozs7Ozs7Ozs7O0VBY3BDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQSxDQUFFLENBQ2IsQ0FBQzt3QkFFRixtQkFBbUIsQ0FBQyxJQUFJLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQTtBQUN2RCx3QkFBQSxtQkFBbUIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBRTNCLHdCQUFBLE1BQU0sQ0FBQyxTQUFTLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQUN6QyxxQkFBQTtBQUFDLG9CQUFBLE9BQU8sQ0FBQyxFQUFFO0FBQ1Isd0JBQUEsSUFBSUEsZUFBTSxDQUNOLCtFQUErRSxDQUNsRixDQUFDO0FBQ0wscUJBQUE7aUJBQ0o7QUFDSixhQUFBLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxVQUFVLENBQUM7QUFDWixnQkFBQSxFQUFFLEVBQUUsQ0FBb0Isa0JBQUEsQ0FBQTtBQUN4QixnQkFBQSxJQUFJLEVBQUUsQ0FBa0QsZ0RBQUEsQ0FBQTtnQkFDeEQsUUFBUSxFQUFFLE1BQVcsU0FBQSxDQUFBLElBQUEsRUFBQSxLQUFBLENBQUEsRUFBQSxLQUFBLENBQUEsRUFBQSxhQUFBO0FBQ2pCLG9CQUFBLHFCQUFxQixFQUFFLENBQUE7QUFDM0IsaUJBQUMsQ0FBQTtBQUNKLGFBQUEsQ0FBQyxDQUFDO1lBRUgsSUFBSSxDQUFDLFVBQVUsQ0FBQztBQUNaLGdCQUFBLEVBQUUsRUFBRSxDQUFnQyw4QkFBQSxDQUFBO0FBQ3BDLGdCQUFBLElBQUksRUFBRSxDQUEwQyx3Q0FBQSxDQUFBO0FBQ2hELGdCQUFBLGNBQWMsRUFBRSxDQUFDLE1BQU0sRUFBRSxJQUFJLEtBQUk7b0JBRTdCLElBQUk7QUFDQTs7OztBQUlHO0FBQ0gsd0JBQUEsSUFBSSxPQUFPLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFDLENBQUMsQ0FBQzt3QkFDL0YsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQzt3QkFFaEMsSUFBSSxjQUFjLEdBQUdFLGtCQUFvQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO3dCQUNuRSxJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7d0JBQ25CLElBQUksb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLHdCQUFBLE9BQU0sY0FBYyxDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUU7OztBQUlqQyw0QkFBQSxJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUUsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzNGLDRCQUFBLElBQUksMEJBQTBCLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7OztBQUlwRSw0QkFBQSxJQUFJLFdBQVcsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDakUsNEJBQUEsSUFBSSx5QkFBeUIsR0FBRyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxVQUFVLENBQUM7QUFDbEYsNEJBQUEsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzNELDRCQUFBLElBQUksdUJBQXVCLEdBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksVUFBVSxDQUFDO0FBRTdFLDRCQUFBLElBQUksVUFBVSxHQUFHLDJCQUEyQixDQUFDLFlBQVksQ0FBQyxDQUFDOzRCQUMzRCxJQUFHLFVBQVUsS0FBSyxFQUFFLEVBQUU7O0FBR2xCLGdDQUFBLElBQUksZUFBZSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLHlCQUF5QixFQUFFLEVBQUUsRUFBRSwwQkFBMEIsRUFBQyxDQUFDLEdBQUcsWUFBWSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtnQ0FDL0ssTUFBTSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUMxQyxFQUFFLElBQUksRUFBRSx5QkFBeUIsRUFBRSxFQUFFLEVBQUUsMEJBQTBCLEVBQUMsQ0FBQyxDQUFDO2dDQUN6Ryx1QkFBdUIsSUFBSSxDQUFDLENBQUM7Z0NBQzdCLG9CQUFvQixJQUFJLENBQUMsQ0FBQztBQUM3Qiw2QkFBQTs0QkFFRCxVQUFVLEdBQUcsdUJBQXVCLENBQUE7NEJBQ3BDLE9BQU8sR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUNwRCw0QkFBQSxjQUFjLEdBQUdBLGtCQUFvQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ2xFLHlCQUFBO0FBRUQ7OztBQUdHO3dCQUNILElBQUksZUFBZSxHQUFHLEVBQUUsQ0FBQTt3QkFDeEIsSUFBSSxjQUFjLEdBQUcsRUFBRSxDQUFBO0FBQ3ZCLHdCQUFBLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFOzRCQUVsQyxJQUFJLElBQUksR0FBR0gsZ0JBQWtDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ3hELElBQUcsSUFBSSxDQUFDLFVBQVUsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxLQUFLLEVBQUU7QUFDbEQsZ0NBQUEsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FDeEIsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtBQUNoQyw2QkFBQTtBQUNKLHlCQUFBO3dCQUVELElBQUcsZUFBZSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksb0JBQW9CLEtBQUssQ0FBQyxFQUFFO0FBQzNELDRCQUFBLElBQUlDLGVBQU0sQ0FBRSw4Q0FBOEMsQ0FBQyxDQUFDOzRCQUM1RCxPQUFPO0FBQ1YseUJBQUE7QUFFRDs7O0FBR0c7QUFDSCx3QkFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUU1Qyw0QkFBQSxJQUFJLFlBQVksR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUE7NEJBQ3BDLElBQUksSUFBSSxHQUFHLFlBQVksQ0FBQztBQUN4Qiw0QkFBQSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3RCLDRCQUFBLElBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRTtBQUNyQyxnQ0FBQSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2Qyw2QkFBQTs0QkFDRCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUEsS0FBQSxFQUFRLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQSxDQUFFLENBQUM7QUFFbEMsNEJBQUEsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFDbkMsRUFBRSxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFDLENBQUMsQ0FBQztBQUNuRix5QkFBQTt3QkFFRCxJQUFJQSxlQUFNLENBQUUsQ0FBQSxTQUFBLEVBQVksZUFBZSxDQUFDLE1BQU0sR0FBRyxvQkFBb0IsQ0FBeUMsdUNBQUEsQ0FBQSxDQUFDLENBQUM7QUFDbkgscUJBQUE7QUFBQyxvQkFBQSxPQUFPLENBQUMsRUFBRTtBQUNSLHdCQUFBLElBQUlBLGVBQU0sQ0FDTixrRkFBa0YsQ0FDckYsQ0FBQztBQUNMLHFCQUFBO2lCQUNKO0FBQ0osYUFBQSxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsVUFBVSxDQUFDO0FBQ1osZ0JBQUEsRUFBRSxFQUFFLENBQTRCLDBCQUFBLENBQUE7QUFDaEMsZ0JBQUEsSUFBSSxFQUFFLENBQW1ELGlEQUFBLENBQUE7QUFDekQsZ0JBQUEsY0FBYyxFQUFFLENBQUMsTUFBTSxFQUFFLElBQUksS0FBSTtBQUU3QixvQkFBQSxHQUFHLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEtBQUk7QUFFMUQsd0JBQUEsSUFBSSxRQUFRLEdBQUcsbUJBQW1CLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDaEQsd0JBQUEsSUFBRyxRQUFRLEVBQUU7NEJBQ1QsT0FBTztBQUNWLHlCQUFBO3dCQUVELFdBQVcsQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHOzRCQUNuQyxFQUFDLG1CQUFtQixFQUFFLENBQUMsRUFBQzs0QkFDeEIsRUFBQyxhQUFhLEVBQUUsVUFBVSxFQUFDO3lCQUM5QixDQUFBO0FBQ0Qsd0JBQUEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQTtBQUN6QixxQkFBQyxDQUFDLENBQUM7aUJBQ047QUFDSixhQUFBLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxVQUFVLENBQUM7QUFDWixnQkFBQSxFQUFFLEVBQUUsQ0FBa0MsZ0NBQUEsQ0FBQTtBQUN0QyxnQkFBQSxJQUFJLEVBQUUsQ0FBMEMsd0NBQUEsQ0FBQTtBQUNoRCxnQkFBQSxjQUFjLEVBQUUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxLQUFJO29CQUU3QixJQUFJO3dCQUNBLElBQUksWUFBWSxHQUFtQixFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFBO0FBQ3JELHdCQUFBLElBQUksVUFBVSxHQUFtQixFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBQyxDQUFBO3dCQUU1RSxJQUFJLE9BQU8sR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxVQUFVLENBQUMsQ0FBQztBQUN4RCx3QkFBQSxJQUFJLE1BQU0sR0FBRyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDdEMsd0JBQUEsSUFBSSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUM7QUFDL0Msd0JBQUEsSUFBSSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUM7QUFDL0Msd0JBQUEsSUFBSSxjQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQztBQUMzQyx3QkFBQSxJQUFJLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQzt3QkFFbkQsSUFBRyxNQUFNLENBQUMsY0FBYyxFQUFFOzRCQUN0QixNQUFNLENBQUMsWUFBWSxDQUFDLGtCQUFrQixFQUFFLFlBQVksRUFBRSxVQUFVLENBQUMsQ0FBQTs0QkFDakUsSUFBSUEsZUFBTSxDQUFDLENBQUEsb0JBQUEsRUFBdUIsZ0JBQWdCLENBQUEsa0JBQUEsRUFBcUIsZ0JBQWdCLENBQXdCLHFCQUFBLEVBQUEsY0FBYyxDQUFtQixpQkFBQSxDQUFBLENBQUMsQ0FBQTtBQUNwSix5QkFBQTtBQUNJLDZCQUFBO0FBQ0QsNEJBQUEsSUFBSUEsZUFBTSxDQUFDLENBQW1DLGlDQUFBLENBQUEsQ0FBQyxDQUFBO0FBQ2xELHlCQUFBO0FBQ0oscUJBQUE7QUFBQyxvQkFBQSxPQUFPLENBQUMsRUFBRTtBQUNSLHdCQUFBLElBQUlBLGVBQU0sQ0FDTixpRkFBaUYsQ0FDcEYsQ0FBQztBQUNMLHFCQUFBO2lCQUNKO0FBQ0osYUFBQSxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFLO2dCQUUxQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztBQUNsQyxhQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztTQUNaLENBQUEsQ0FBQTtBQUFBLEtBQUE7SUFFRCxzQkFBc0IsR0FBQTtRQUVsQixJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQUM7QUFDM0QsUUFBQSxZQUFZLENBQUMsT0FBTyxDQUFDLE9BQU8sSUFBRztBQUUzQixZQUFBLElBQUksZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLHNCQUFzQixFQUFFLENBQUM7QUFDeEQsWUFBQSxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsYUFBYSxJQUFHO2dCQUVyQyxhQUFhLENBQUMsc0JBQXNCLEVBQUUsQ0FBQTtBQUMxQyxhQUFDLENBQUMsQ0FBQztBQUNQLFNBQUMsQ0FBQyxDQUFDO0tBQ047SUFFRCwwQkFBMEIsR0FBQTtRQUN0QixJQUFJLENBQUMsNkJBQTZCLENBQUMsQ0FBTyxFQUFFLEVBQUUsR0FBRyxLQUFJLFNBQUEsQ0FBQSxJQUFBLEVBQUEsS0FBQSxDQUFBLEVBQUEsS0FBQSxDQUFBLEVBQUEsYUFBQTtBQUVqRCxZQUFBLElBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxjQUFjLEtBQUssS0FBSztBQUM3QyxnQkFBQUosaUJBQVEsQ0FBQyxRQUFRLEtBQUssSUFBSSxFQUFFO2dCQUMzQixPQUFPO0FBQ1YsYUFBQTtBQUVELFlBQUEsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQztZQUVsQyxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNuRSxJQUFHLGNBQWMsS0FBSyxJQUFJLEVBQUU7QUFDeEIsZ0JBQUEsT0FBTyxDQUFDLElBQUksQ0FBQyxrRUFBa0UsQ0FBQyxDQUFBO2dCQUNoRixPQUFPO0FBQ1YsYUFBQTtBQUVEOzs7QUFHRztBQUNILFlBQUEsSUFBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUV4QixJQUFJLENBQUMsbUJBQW1CLENBQUMsRUFBRSxFQUFFLGNBQWMsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM1RCxhQUFBOzs7OztZQU1ELElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUM7QUFFbEM7OztBQUdHO1lBQ0gsSUFBRyxDQUFDLElBQUksRUFBRTtnQkFFTixPQUFPO0FBQ1YsYUFBQTtBQUVELFlBQUEsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztZQUMxQixJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXJDLElBQUksaUJBQWlCLEdBQUcsbUJBQW1CLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzdELElBQUcsaUJBQWlCLEtBQUssSUFBSSxFQUFFO0FBRTNCLGdCQUFBLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDM0UsT0FBTztBQUNWLGFBQUE7QUFDSSxpQkFBQTtBQUNELGdCQUFBLGNBQWMsQ0FBQyxZQUFZLENBQUMsNEJBQTRCLENBQUMsQ0FBQztBQUM3RCxhQUFBO0FBRUQ7OztBQUdHO0FBQ0gsWUFBQSxJQUFHTyxtQkFBcUMsQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFFakQsY0FBYyxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQ25DLGFBQUE7QUFFRDs7OztBQUlHO0FBQ0gsWUFBQSxJQUFHLGNBQWMsQ0FBQyxjQUFjLEVBQUUsS0FBSyxLQUFLLEVBQUU7Z0JBQzFDLE9BQU87QUFDVixhQUFBO0FBRUQ7OztBQUdHO1lBQ0gsSUFBSSxhQUFhLEdBQWdDLGtDQUFrQyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUVwRzs7Ozs7O0FBTUc7WUFDSCxJQUFHQyxnQkFBa0MsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLEVBQUU7QUFFaEUsZ0JBQUEsa0JBQWtCLENBQUMsRUFBRSxFQUFFLGFBQWEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxFQUFFLGNBQWMsRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDckYsT0FBTztBQUNWLGFBQUE7O1lBR0QsSUFBR0Msc0JBQXFDLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxFQUFFO0FBRW5FLGdCQUFBLHdCQUF3QixDQUFDLEVBQUUsRUFBRSxhQUFhLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQzFGLE9BQU87QUFDVixhQUFBO0FBRUQ7OztBQUdHO1lBQ0gsSUFBSSxjQUFjLEdBQUdDLHFCQUF1QyxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM1RixJQUFHLGNBQWMsS0FBSyxJQUFJLEVBQUU7Z0JBQ3hCLE9BQU87QUFDVixhQUFBO0FBQ0Q7OztBQUdHO0FBQ0gsWUFBQSxhQUFhLENBQUMsZUFBZSxHQUFHLGNBQWMsQ0FBQyxlQUFlLENBQUM7QUFFL0Q7OztBQUdHO1lBQ0gsSUFBSSxpQkFBaUIsR0FBMkIsY0FBYyxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNsSCxJQUFHLGlCQUFpQixLQUFLLElBQUksRUFBRTtnQkFDM0IsT0FBTztBQUNWLGFBQUE7QUFDRCxZQUFxQyxpQkFBaUIsQ0FBQyxTQUFTLEdBQUc7QUFFbkU7Ozs7QUFJRztZQUNILGFBQWEsQ0FBQyxlQUFlLEdBQUlDLGdCQUFrQyxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUVuRzs7OztBQUlHO1lBQ2UsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxHQUFHLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsQ0FBQyxNQUFpQixLQUFJO0FBQ3hJLGdCQUFBLGVBQWUsQ0FBQyxNQUFNLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztBQUMvQyxhQUFDLENBQUMsQ0FBQztZQUNILE9BQU87U0FDVixDQUFBLENBQUMsQ0FBQztLQUNOO0FBRU8sSUFBQSx1QkFBdUIsQ0FBQyxFQUFlLEVBQUUsaUJBQXlDLEVBQUUsR0FBaUMsRUFBRSxhQUEwQyxFQUFFLFVBQWtCLEVBQUUsZ0JBQWdELEVBQUUsZ0JBQTZDLEVBQUE7UUFFMVIsSUFBSSxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxHQUFHLGFBQWEsQ0FBQztRQUV4RixJQUFJLGFBQWEsR0FBbUIsdUJBQXVCLENBQUMsZUFBZSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRXpGLElBQUksYUFBYSxHQUFtQix1QkFBdUIsQ0FBQyxlQUFlLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFFekYsUUFBQSxJQUFJLGVBQWUsR0FBa0IsaUJBQWlCLENBQUMsU0FBUyxFQUFFLENBQUM7QUFFbkU7O0FBRUc7UUFDSCxJQUFJLGFBQWEsR0FBYyxJQUFJLFNBQVMsQ0FBQyxFQUFFLEVBQUUsY0FBYyxDQUFDLENBQUM7QUFDakUsUUFBQSxFQUFFLENBQUMsRUFBRSxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUM7QUFFMUIsUUFBQSxhQUFhLEdBQUcsaUJBQWlCLENBQUMsdUJBQXVCLENBQUMsYUFBYSxDQUFDLENBQUM7QUFFekU7Ozs7QUFJRztBQUNILFFBQWUsZUFBZSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRTtBQUV0RixRQUFBLElBQUksdUJBQXVCLEdBQUcsSUFBSXhCLDRCQUFtQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFELFFBQUEsdUJBQXVCLENBQUMsUUFBUSxHQUFHLE1BQUs7WUFDcEMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDcEMsU0FBQyxDQUFBO0FBQ0QsUUFBQSxHQUFHLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDLENBQUM7QUFFdEM7OztBQUdHO1FBQ0gsSUFBSXlCLGNBQWdDLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxLQUFLLElBQUk7QUFDekQsWUFBQSxnQkFBZ0IsQ0FBQyxjQUFjLEtBQUssT0FBTyxFQUFFO0FBRTdDLFlBQUEsYUFBYSxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUM7WUFDekMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQy9FLFNBQUE7UUFDRCxJQUFJQyxtQkFBa0MsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxLQUFLLElBQUk7QUFDNUUsWUFBQSxnQkFBZ0IsQ0FBQyxjQUFjLEtBQUssT0FBTyxFQUFFO0FBRTdDLFlBQUEsYUFBYSxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUM7WUFDekMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQy9FLFNBQUE7YUFDSSxJQUFJQyxpQkFBbUMsQ0FBQyxhQUFhLENBQUMsS0FBSyxJQUFJLEVBQUU7QUFFbEUsWUFBQSxhQUFhLENBQUMsV0FBVyxHQUFHLFlBQVksQ0FBQztZQUN6QyxlQUFlLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDakYsU0FBQTthQUNJLElBQUlDLHNCQUF3QyxDQUFDLGFBQWEsQ0FBQyxLQUFLLElBQUksRUFBRTtBQUV2RSxZQUFBLGFBQWEsQ0FBQyxXQUFXLEdBQUcsWUFBWSxDQUFDO0FBQ3pDLFlBQUEsZUFBZSxHQUFHLGlCQUFpQixDQUFDLGlCQUFpQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3JFLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUNwRixTQUFBO0FBQ0QsUUFBQSxhQUFhLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBRWpDLFFBQUEsc0JBQXNCLENBQUM7QUFDbkIsWUFBQSxTQUFTLEVBQUUsZUFBZSxDQUFDLElBQUksRUFBRTtBQUNqQyxZQUFBLFNBQVMsRUFBRSxlQUFlLENBQUMsS0FBSyxFQUFFO1lBQ2xDLFNBQVMsRUFBRSxhQUFhLENBQUMsR0FBRztZQUM1QixZQUFZLEVBQUUsYUFBYSxDQUFDLG9CQUFvQjtBQUNuRCxTQUFBLEVBQUUsZUFBZSxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBRWhDLGVBQWUsQ0FBQyw0QkFBNEIsRUFBRSxDQUFDO0FBQy9DLFFBQUEsT0FBTyxlQUFlLENBQUM7S0FDMUI7QUFFRCxJQUFBLG1DQUFtQyxDQUFDLFFBQWdCLEVBQUE7QUFFaEQsUUFBQSxJQUFJLENBQUMsa0NBQWtDLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEtBQUk7O0FBRWxFLFlBQUEsSUFBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsS0FBSyxLQUFLO0FBQzVDLGdCQUFBZixpQkFBUSxDQUFDLFFBQVEsS0FBSyxJQUFJLEVBQUU7Z0JBRTNCLE9BQU87QUFDWCxhQUFBO0FBRUQsWUFBQSxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDOzs7WUFJbEMsQ0FBQSxFQUFBLEdBQUEsRUFBRSxDQUFDLGFBQWEsTUFBQSxJQUFBLElBQUEsRUFBQSxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFBLEVBQUEsQ0FBRSxRQUFRLENBQUMseUJBQXlCLENBQUMsQ0FBQzs7O1lBSXRELElBQUksY0FBYyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQy9ELFlBQUEsSUFBRyxjQUFjLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDNUIsT0FBTztBQUNWLGFBQUE7WUFFRCxJQUFHLElBQUksQ0FBQyxhQUFhLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssU0FBUyxFQUFFOztnQkFFaEUsT0FBTztBQUNWLGFBQUE7WUFFRCxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNuRSxJQUFHLGNBQWMsS0FBSyxJQUFJLEVBQUU7Z0JBQ3hCLE9BQU87QUFDVixhQUFBO1lBRUQsSUFBRyxHQUFHLENBQUMsV0FBVztBQUNmLGdCQUFBLEdBQUcsQ0FBQyxXQUFXLENBQUMscUJBQXFCLENBQUMsS0FBSyxTQUFTLEVBQUU7Z0JBQ3JELE9BQU87QUFDVixhQUFBO0FBQ0ksaUJBQUE7QUFDRCxnQkFBQSxjQUFjLENBQUMsWUFBWSxDQUFDLDRCQUE0QixDQUFDLENBQUM7QUFDN0QsYUFBQTs7WUFHRCxjQUFjLENBQUMsY0FBYyxFQUFFLENBQUM7Ozs7O1lBTWhDLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUM7QUFFbEM7OztBQUdHO1lBQ0gsSUFBRyxDQUFDLElBQUksRUFBRTtnQkFDTixPQUFPO0FBQ1YsYUFBQTtBQUVEOzs7QUFHRztZQUNILEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLHNCQUFzQixDQUFDLENBQUE7WUFFN0QsSUFBSSxZQUFZLEdBQUcsSUFBSSxrQkFBa0IsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxvVkFBb1YsQ0FBQyxDQUFDLENBQUM7QUFDdFksWUFBQSxJQUFJLGtCQUFrQixHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUM7Z0JBQ2xDLEdBQUcsRUFBRSxvQkFBb0IsQ0FBQyx5QkFBeUI7QUFDdEQsYUFBQSxDQUFDLENBQUE7QUFFRixZQUFBLElBQUksU0FBUyxHQUFHLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRXBELElBQUksc0JBQXNCLEdBQUcsSUFBSSxDQUFDO1lBQ2xDLElBQUcsY0FBYyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsS0FBSyxJQUFJLEVBQUU7Z0JBRWxELHNCQUFzQixHQUFHLEtBQUssQ0FBQztBQUMvQixnQkFBQSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxHQUFHZ0IsY0FBZ0MsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRXpFLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztnQkFDbkIsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFlBQVksRUFBRSxDQUFDLEVBQUUsRUFBRTs7QUFHbEMsb0JBQUEsSUFBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxFQUFFO0FBQ3RCLHdCQUFBLFVBQVUsRUFBRSxDQUFDO0FBQ2hCLHFCQUFBO0FBQ0osaUJBQUE7Ozs7Z0JBS0QsSUFBRyxVQUFVLElBQUksQ0FBQyxFQUFFO29CQUNoQixJQUFHLFNBQVMsS0FBSyxFQUFFLEVBQUU7QUFDakIsd0JBQUEsWUFBWSxDQUFDLGVBQWUsQ0FBQyxxR0FBcUcsQ0FBQyxDQUFDO0FBQ3ZJLHFCQUFBO0FBQ0kseUJBQUE7QUFDRCx3QkFBQSxZQUFZLENBQUMsZUFBZSxDQUFDLCtEQUErRCxDQUFDLENBQUM7QUFDakcscUJBQUE7b0JBQ0QsT0FBTztBQUNWLGlCQUFBO0FBQ0osYUFBQTtBQUNELFlBQUEsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFpQixjQUFBLEVBQUEsU0FBUyxFQUFFLENBQUE7OztZQUlwQyxJQUFHLHNCQUFzQixLQUFLLElBQUksRUFBRTs7QUFHaEMsZ0JBQUEsSUFBSSx1QkFBdUIsR0FBRyxJQUFJN0IsNEJBQW1CLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQzFELGNBQWMsQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLEVBQUUsRUFBRSxFQUFFLFlBQVksRUFBRSxrQkFBa0IsQ0FBQyxDQUFDOzs7O0FBS3RGLGdCQUFBLHVCQUF1QixDQUFDLFFBQVEsR0FBRyxNQUFLO29CQUVwQyxJQUFHLGNBQWMsSUFBSSxlQUFlLENBQUMsVUFBVSxDQUFDLEtBQUssS0FBSyxFQUFFOztBQUd4RCx3QkFBQSxjQUFjLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzFDLHFCQUFBO0FBQ0wsaUJBQUMsQ0FBQztBQUNGLGdCQUFBLEdBQUcsQ0FBQyxRQUFRLENBQUMsdUJBQXVCLENBQUMsQ0FBQztBQUN6QyxhQUFBO1lBRUQsSUFBSSx3QkFBd0IsR0FBRyxjQUFjLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDOUUsSUFBRyx3QkFBd0IsS0FBSyxJQUFJLEVBQUU7Z0JBRWxDLElBQUksZUFBZSxHQUFHLHdCQUF3QixDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3pFLGdCQUFBLGVBQWUsQ0FBQyxZQUFZLEdBQUcsa0JBQWtCLENBQUM7QUFDckQsYUFBQTtBQUNMLFNBQUMsQ0FBQyxDQUFBO0tBQ0w7SUFFSyxZQUFZLEdBQUE7O0FBRXBCLFlBQUEsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztTQUMzRixDQUFBLENBQUE7QUFBQSxLQUFBO0lBRUssWUFBWSxHQUFBOztZQUNqQixNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUNuRCxDQUFBLENBQUE7QUFBQSxLQUFBO0lBRUUsZUFBZSxDQUFDLEVBQWUsRUFBRSxHQUFpQyxFQUFFLFVBQWtCLEVBQUUsY0FBOEIsRUFBRSxTQUFpQixFQUFFLElBQWdDLEVBQUE7UUFFdkssSUFBSSxpQkFBaUIsR0FBMkIsSUFBSSxDQUFDO0FBQ3JELFFBQUEsSUFBRyxjQUFjLENBQUMsY0FBYyxDQUFDLDRCQUE0QixDQUFDLEtBQUssSUFBSTtZQUNwRSxFQUFFLENBQUMsc0JBQXNCLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtBQUN0RCxZQUFBLGlCQUFpQixHQUFHLGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0FBQ3pGLFNBQUE7QUFDSSxhQUFBLElBQUcsY0FBYyxDQUFDLGNBQWMsQ0FBQyw0QkFBNEIsQ0FBQyxLQUFLLElBQUk7WUFDcEUsRUFBRSxDQUFDLHNCQUFzQixDQUFDLGFBQWEsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7QUFFM0QsWUFBQSxJQUFJLFFBQVEsR0FBRyxTQUFTLEVBQUUsQ0FBQTtBQUMxQixZQUFBLEVBQUUsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7O0FBR3pCLFlBQUEsaUJBQWlCLEdBQUcsY0FBYyxDQUFDLG9CQUFvQixDQUFDLDRCQUE0QixDQUFDLENBQUM7QUFDdEYsWUFBQSxJQUFJLE9BQU8sR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDNUUsWUFBQSxjQUFjLENBQUMsWUFBWSxDQUFDLDRCQUE0QixDQUFDLENBQUM7O1lBRzFELGFBQWEsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsNEJBQTRCLENBQUMsQ0FBQztBQUN0RixZQUFBLGlCQUFpQixHQUFHLGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0FBQ3RGLFlBQUEsSUFBSSxRQUFRLEdBQUcscUNBQXFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFFMUQsWUFBQSxJQUFJLElBQUksR0FBRyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDbkUsWUFBQSxJQUFJLFlBQVksR0FBRyxzQkFBc0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUNwRSxZQUFBLElBQUcsUUFBUSxDQUFDLFlBQVksS0FBSyxJQUFJLEVBQUU7QUFDL0IsZ0JBQUEsUUFBUSxDQUFDLFlBQVksR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNyRixhQUFBO0FBQ0ksaUJBQUE7QUFDRCxnQkFBQSxRQUFRLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzdGLGFBQUE7QUFDRCxZQUFBLGlCQUFpQixDQUFDLHVCQUF1QixDQUFDLFFBQVEsQ0FBQyxDQUFDOzs7QUFJcEQsWUFBQSxTQUFlLFdBQVcsR0FBQTs7b0JBRXRCLFVBQVUsQ0FBQyxNQUFJOztBQUdYLHdCQUFBLElBQUksZUFBZSxHQUFHLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQ3BELHdCQUFBLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7d0JBQ2hDLEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFFaEMsNEJBQUEsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFBO0FBQzVCLDRCQUFBLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFFNUMsNEJBQUEsYUFBYSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDakQseUJBQUE7QUFFRCx3QkFBQSxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsQ0FBQyw0QkFBNEIsRUFBRSxDQUFDO3FCQUNoRSxFQUFFLEVBQUUsQ0FBQyxDQUFBO2lCQUNULENBQUEsQ0FBQTtBQUFBLGFBQUE7QUFDRCxZQUFBLFdBQVcsRUFBRSxDQUFDO1lBRWQsT0FBTztBQUNWLFNBQUE7QUFDSSxhQUFBOzs7QUFJRCxZQUFBLElBQUksUUFBUSxHQUFHLFNBQVMsRUFBRSxDQUFBO0FBQzFCLFlBQUEsRUFBRSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUV6QixhQUFhLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLDRCQUE0QixDQUFDLENBQUM7QUFDdEYsWUFBQSxpQkFBaUIsR0FBRyxjQUFjLENBQUMsb0JBQW9CLENBQUMsNEJBQTRCLENBQUMsQ0FBQztBQUV0RixZQUFBLElBQUksUUFBUSxHQUFHLHFDQUFxQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFELFlBQUEsSUFBSSxJQUFJLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBRW5FLFlBQUEsSUFBSSxZQUFZLEdBQUcsc0JBQXNCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDcEUsWUFBQSxJQUFHLFFBQVEsQ0FBQyxZQUFZLEtBQUssSUFBSSxFQUFFO0FBQy9CLGdCQUFBLFFBQVEsQ0FBQyxZQUFZLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDckYsYUFBQTtBQUNJLGlCQUFBO0FBQ0QsZ0JBQUEsUUFBUSxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUM3RixhQUFBO0FBQ0QsWUFBQSxpQkFBaUIsQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUVwRCxPQUFPO0FBQ1YsU0FBQTtRQUVELElBQUcsaUJBQWlCLEtBQUssSUFBSSxFQUFFO1lBQzNCLE9BQU87QUFDVixTQUFBO1FBRUQsSUFBSSxRQUFRLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyQyxJQUFJLGFBQWEsR0FBZ0Msa0NBQWtDLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3BHLGFBQWEsQ0FBQyxlQUFlLEdBQUl3QixnQkFBa0MsQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUM7QUFFbkcsUUFBQSxJQUFHSCxnQkFBa0MsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDO0FBQy9ELFlBQUFPLHNCQUF3QyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsRUFBRTtZQUV0RSxJQUFHUCxnQkFBa0MsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLEVBQUU7QUFDaEUsZ0JBQUEsa0JBQWtCLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNwRCxhQUFBO2lCQUNJLElBQUdPLHNCQUF3QyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsRUFBRTtBQUMzRSxnQkFBQSxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZELGFBQUE7WUFDRCxPQUFPO0FBQ1YsU0FBQTtBQUVELFFBQUEsSUFBSSxjQUFjLEdBQW1DO1lBQ2pELGVBQWUsRUFBRSxhQUFhLENBQUMsZUFBZTtBQUM5QyxZQUFBLGFBQWEsRUFBRSw0QkFBNEI7QUFDM0MsWUFBQSxjQUFjLEVBQUUsVUFBVTtTQUM3QixDQUFBO0FBRUQsUUFBQSxJQUFJLENBQUMsdUJBQXVCLENBQUMsRUFBRSxFQUFFLGlCQUFpQixFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxDQUFDLE1BQWlCLEtBQUk7QUFDdEgsWUFBQSxlQUFlLENBQUMsTUFBTSxFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFDL0MsU0FBQyxDQUFDLENBQUM7S0FDTjs7QUFHTyxJQUFBLHdCQUF3QixDQUFDLElBQWlCLEVBQUE7QUFFOUMsUUFBQSxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsb0JBQW9CLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBRWpELElBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBLGVBQUEsRUFBa0Isb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUUsQ0FBQSxDQUFDLEVBQUU7QUFDM0QsZ0JBQUEsT0FBTyxJQUFJLENBQUM7QUFDZixhQUFBO0FBQ0osU0FBQTtBQUNELFFBQUEsT0FBTyxLQUFLLENBQUM7S0FDaEI7QUFFYSxJQUFBLG1CQUFtQixDQUFDLEVBQWUsRUFBRSxjQUE4QixFQUFFLFVBQWtCLEVBQUE7Ozs7WUFJakcsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDNUMsWUFBQSxJQUFHLFdBQVcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUN6QixPQUFPO0FBQ1YsYUFBQTtZQUVELElBQUksZ0JBQWdCLEdBQUcsRUFBRSxDQUFDOzs7O1lBSzFCLElBQUksb0JBQW9CLEdBQUcsRUFBRSxDQUFBO0FBQzdCLFlBQUEsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDN0QsSUFBRyxLQUFLLFlBQVlFLGNBQUssRUFBRTtnQkFFdkIsSUFBSSxJQUFJLEdBQUcsS0FBYyxDQUFBO0FBQ3pCLGdCQUFBLElBQUksUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFBOzs7Z0JBSXBELElBQUksYUFBYSxHQUFHWCxrQkFBb0MsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNuRSxnQkFBQSxPQUFNLGFBQWEsQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFO0FBRWhDLG9CQUFBLElBQUksYUFBYSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUM7b0JBQzNGLFFBQVEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUNyRCxvQkFBQSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7QUFFekMsb0JBQUEsYUFBYSxHQUFHQSxrQkFBb0MsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNsRSxpQkFBQTtBQUNKLGFBQUE7QUFDSSxpQkFBQTtBQUNELGdCQUFBLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0NBQXdDLFVBQVUsQ0FBQSxDQUFFLENBQUMsQ0FBQTtBQUN0RSxhQUFBO1lBRUQsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO0FBQ3BCLFlBQUEsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFFekMsZ0JBQUEsSUFBSSxLQUFLLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMzQixJQUFJLEtBQUssWUFBWSxXQUFXLEVBQUU7b0JBRTlCLElBQUksT0FBTyxLQUFLLEtBQUssRUFBRTt3QkFFbkIsSUFBSSxjQUFjLEdBQUcsS0FBSyxDQUFDO3dCQUMzQixJQUFJLFNBQVMsR0FBRyxFQUFFLENBQUM7d0JBRW5CLElBQUksU0FBUyxHQUFHSCxnQkFBa0MsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7d0JBQ3RFLElBQUksVUFBVSxHQUFHZSxrQkFBaUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUE7QUFDckUsd0JBQUEsSUFBSSxTQUFTLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRTs7NEJBRy9CLGNBQWMsR0FBRyxJQUFJLENBQUM7QUFDdEIsNEJBQUEsSUFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLElBQUksRUFBRTtnQ0FDM0IsSUFBSSxRQUFRLEdBQUdDLGNBQWdDLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dDQUNuRSxJQUFJLFFBQVEsS0FBSyxJQUFJLEVBQUU7b0NBQ25CLFNBQVMsR0FBRyxRQUFRLENBQUM7QUFDeEIsaUNBQUE7QUFDSiw2QkFBQTtBQUNKLHlCQUFBO0FBQ0ksNkJBQUEsSUFBRyxTQUFTLENBQUMsVUFBVSxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLEVBQUU7OztBQUk1RSw0QkFBQSxJQUFJLGFBQWEsR0FBRyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQzs0QkFDakQsSUFBRyxhQUFhLEtBQUssU0FBUyxFQUFFO0FBQzVCLGdDQUFBLE9BQU8sQ0FBQyxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQTtnQ0FDL0QsT0FBTztBQUNWLDZCQUFBO0FBRUQsNEJBQUEsSUFBSSxFQUFFLEdBQUcsMkJBQTJCLENBQUMsYUFBYSxDQUFDLENBQUM7NEJBQ3BELElBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRTtnQ0FDVixjQUFjLEdBQUcsSUFBSSxDQUFDO2dDQUN0QixTQUFTLEdBQUcsRUFBRSxDQUFDO0FBQ2xCLDZCQUFBO0FBQ0oseUJBQUE7NkJBQ0ksSUFBRyxVQUFVLENBQUMsS0FBSyxFQUFFOzRCQUN0QixjQUFjLEdBQUcsSUFBSSxDQUFDO0FBQ3RCLDRCQUFBLFNBQVMsR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztBQUNoRCx5QkFBQTtBQUVELHdCQUFBLElBQUcsY0FBYyxLQUFLLElBQUksSUFBSSxTQUFTLEtBQUssRUFBRSxFQUFFOzRCQUU1QyxPQUFPLEdBQUcsSUFBSSxDQUFDO0FBRWYsNEJBQUEsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQ0FDakQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUM5Qiw2QkFBQTtBQUNELDRCQUFBLEtBQUssQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDOzRCQUVyQixLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBRWpFLDRCQUFBLElBQUksWUFBWSxHQUFHLElBQUksa0JBQWtCLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDOUMsNEJBQUEsSUFBSSxrQkFBa0IsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO2dDQUNyQyxHQUFHLEVBQUUsb0JBQW9CLENBQUMseUJBQXlCO0FBQ3RELDZCQUFBLENBQUMsQ0FBQzs0QkFHSCxJQUFJLGlCQUFpQixHQUEyQixjQUFjLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDL0YsNEJBQUEsSUFBSSxpQkFBaUIsS0FBSyxJQUFJLElBQUksaUJBQWlCLENBQUMsU0FBUyxFQUFFLENBQUMsZ0JBQWdCLEtBQUssQ0FBQyxFQUFFOztBQUVwRixnQ0FBQSxZQUFZLENBQUMsZUFBZSxDQUFDLGtJQUFrSSxDQUFDLENBQUM7QUFDcEssNkJBQUE7QUFDSSxpQ0FBQTtBQUNELGdDQUFBLElBQUksZUFBZSxHQUFrQixpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUNuRSxnQ0FBQSxlQUFlLENBQUMseUJBQXlCLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUNqRSw2QkFBQTtBQUNKLHlCQUFBO0FBQ0oscUJBQUE7QUFDSSx5QkFBQTt3QkFFRCxJQUFJUCxjQUFnQyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxJQUFJOzRCQUM1RFEsb0JBQW1DLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLElBQUksRUFBRTs0QkFFakUsT0FBTyxHQUFHLEtBQUssQ0FBQztBQUNuQix5QkFBQTtBQUVELHdCQUFBLGdCQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNoQyxxQkFBQTtBQUNKLGlCQUFBO0FBQ0osYUFBQTtBQUVELFlBQUEsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBRztBQUM3QixnQkFBQSxJQUFHLEtBQUssQ0FBQyxhQUFhLEtBQUssRUFBRSxFQUFFO0FBQzNCLG9CQUFBLEVBQUUsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDekIsaUJBQUE7QUFDTCxhQUFDLENBQUMsQ0FBQztTQUNOLENBQUEsQ0FBQTtBQUFBLEtBQUE7QUFFRCxJQUFBLGNBQWMsQ0FBQyxPQUFvQixFQUFBO1FBRS9CLElBQUcsT0FBTyxLQUFLLElBQUksRUFBRTtBQUNqQixZQUFBLE9BQU8sS0FBSyxDQUFDO0FBQ2hCLFNBQUE7UUFFRCxJQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFO0FBQ3BDLFlBQUEsT0FBTyxJQUFJLENBQUM7QUFDZixTQUFBO0FBRUQsUUFBQSxJQUFHLE9BQU8sQ0FBQyxVQUFVLEtBQUssSUFBSSxFQUFFO1lBQzVCLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDckQsU0FBQTtBQUVELFFBQUEsT0FBTyxLQUFLLENBQUM7S0FDaEI7QUFFSixDQUFBO0FBRUQsU0FBUyxhQUFhLENBQUMsYUFBd0IsRUFBRSxFQUFlLEVBQUE7QUFDNUQsSUFBQSxrQkFBa0IsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQzlDLENBQUM7QUFDRCxTQUFTLGtCQUFrQixDQUFDLEdBQWlCLEVBQUUsRUFBZSxFQUFBO0FBQzFELElBQUEsSUFBSSxHQUFHLEtBQUssWUFBWSxDQUFDLFNBQVMsRUFBRTtBQUNoQyxRQUFBLEVBQUUsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDakQsS0FBQTtBQUNJLFNBQUEsSUFBSSxHQUFHLEtBQUssWUFBWSxDQUFDLFdBQVcsRUFBRTtBQUN2QyxRQUFBLEVBQUUsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDakQsS0FBQTtBQUNJLFNBQUEsSUFBSSxHQUFHLEtBQUssWUFBWSxDQUFDLGNBQWMsRUFBRTtBQUMxQyxRQUFBLEVBQUUsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDbkQsS0FBQTtBQUNJLFNBQUE7QUFDRCxRQUFBLEVBQUUsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDbEQsS0FBQTtBQUNMLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxhQUF3QixFQUFFLGlCQUF5QyxFQUFBO0lBRXhGLElBQUksaUJBQWlCLEtBQUssSUFBSSxFQUFFO1FBQzVCLE9BQU87QUFDVixLQUFBO0FBRUQsSUFBQSxJQUFJLGVBQWUsR0FBa0IsaUJBQWlCLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDbkUsSUFBQSxJQUFJLGVBQWUsRUFBRTs7O0FBSWpCLFFBQUEsSUFBSSxnQkFBZ0IsR0FBMEIsZUFBZSxDQUFDLG1CQUFtQixFQUFFLENBQUM7QUFFcEYsUUFBQSxlQUFlLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUVoRDs7O0FBR0c7QUFDSCxRQUFBLElBQUksZ0JBQWdCLENBQUMsbUJBQW1CLEtBQUssSUFBSSxFQUFFO1lBQy9DLE9BQU87QUFDVixTQUFBO1FBQ0QsZUFBZSxDQUFDLDRCQUE0QixFQUFFLENBQUM7QUFDbEQsS0FBQTtBQUNMLENBQUM7QUFjRCxTQUFTLGtDQUFrQyxDQUFDLFFBQWtCLEVBQUUsSUFBZ0MsRUFBQTtBQUU1RixJQUFBLElBQUksZUFBZSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUN4RCxJQUFBLElBQUksY0FBYyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3RFLElBQUksYUFBYSxHQUFHLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDOUMsSUFBQSxJQUFJLGVBQWUsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFdkQsT0FBTztRQUNILGVBQWU7UUFDZixjQUFjO1FBQ2QsZUFBZTtRQUNmLGFBQWE7S0FDaEIsQ0FBQztBQUNOLENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLEVBQWUsRUFBRSxjQUF3QixFQUFFLEdBQWlDLEVBQUUsY0FBOEIsRUFBRSxTQUFpQixFQUFBO0lBRXZKLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7SUFFeEIsSUFBSSxjQUFjLEdBQUdDLHNCQUF3QyxDQUFDLGNBQWMsQ0FBQyxDQUFBO0lBQzdFLElBQUcsY0FBYyxLQUFLLElBQUksRUFBRTtRQUN4QixPQUFPO0FBQ1YsS0FBQTtBQUVELElBQUEsSUFBSSxRQUFRLEdBQUcsY0FBYyxDQUFDLGFBQWEsQ0FBQztJQUU1QyxhQUFhLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzVELE9BQU87QUFDWCxDQUFDO0FBRUQsU0FBUyx3QkFBd0IsQ0FBQyxFQUFlLEVBQUUsYUFBcUIsRUFBRSxHQUFpQyxFQUFFLGNBQThCLEVBQUUsU0FBaUIsRUFBQTtJQUMxSixFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBRXhCLElBQUksVUFBVSxHQUFHSCxrQkFBaUMsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUNsRSxJQUFBLElBQUksUUFBUSxHQUFHLFVBQVUsQ0FBQyxZQUFZLENBQUM7QUFFdkMsSUFBQSxJQUFJLGFBQWEsR0FBRyxhQUFhLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUN6RixJQUFBLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1QyxPQUFPO0FBQ1gsQ0FBQztBQUVELFNBQVMsdUJBQXVCLENBQUMsT0FBaUIsRUFBRSxVQUFrQixFQUFBO0FBRWxFOzs7Ozs7QUFNRztBQUNILElBQUEsSUFBSSxRQUFRLEdBQUcsU0FBUyxFQUFFLENBQUM7QUFDM0IsSUFBQSxJQUFJLG1CQUFtQixHQUFHLElBQUkvQiw0QkFBbUIsQ0FDN0MsUUFBUSxDQUNYLENBQUM7QUFDRixJQUFBRSx5QkFBZ0IsQ0FBQyxjQUFjLENBQzNCLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxLQUFJO0FBQzdCLFFBQUEsT0FBTyxJQUFJLEdBQUcsSUFBSSxHQUFJLE9BQU8sQ0FBQztLQUNqQyxFQUFFLEVBQUUsQ0FBQyxFQUNOLFFBQVEsRUFDUixVQUFVLEVBQ1YsbUJBQW1CLENBQ3RCLENBQUM7QUFFRixJQUFBLE9BQU8sUUFBUSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxFQUFlLEVBQUUsR0FBaUMsRUFBRSxjQUE4QixFQUFFLFNBQWlCLEVBQUUsUUFBZ0IsRUFBQTtBQUMxSTs7O0FBR0c7SUFDSCxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFBO0FBRTdELElBQUEsSUFBSSxZQUFZLEdBQUcsSUFBSSxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUM5QyxJQUFBLElBQUksa0JBQWtCLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQztRQUNsQyxHQUFHLEVBQUUsb0JBQW9CLENBQUMseUJBQXlCO0FBQ3RELEtBQUEsQ0FBQyxDQUFBO0lBRUYsSUFBRyxjQUFjLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxLQUFLLElBQUksRUFBRTtBQUVqRCxRQUFBLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLEdBQUcyQixjQUFnQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXpFLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztRQUNuQixLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsWUFBWSxFQUFFLENBQUMsRUFBRSxFQUFFOztBQUdsQyxZQUFBLElBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsRUFBRTtBQUNyQixnQkFBQSxVQUFVLEVBQUUsQ0FBQztBQUNoQixhQUFBO0FBQ0osU0FBQTs7OztRQUtELElBQUcsVUFBVSxJQUFJLENBQUMsRUFBRTtZQUNoQixJQUFHLFFBQVEsS0FBSyxFQUFFLEVBQUU7QUFDaEIsZ0JBQUEsWUFBWSxDQUFDLGVBQWUsQ0FBQyx1TUFBdU0sQ0FBQyxDQUFDO0FBQ3pPLGFBQUE7QUFDSSxpQkFBQTtBQUNELGdCQUFBLFlBQVksQ0FBQyxlQUFlLENBQUMsdUdBQXVHLENBQUMsQ0FBQztBQUN6SSxhQUFBO1lBQ0QsT0FBTztBQUNWLFNBQUE7QUFDSixLQUFBO0FBQ0QsSUFBQSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQWlCLGNBQUEsRUFBQSxRQUFRLEVBQUUsQ0FBQTtBQUVuQyxJQUFBLElBQUksdUJBQXVCLEdBQUcsSUFBSTdCLDRCQUFtQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFELElBQUEsSUFBSSxhQUFhLEdBQUcsY0FBYyxDQUFDLHFCQUFxQixDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsWUFBWSxFQUFFLGtCQUFrQixDQUFDLENBQUM7QUFDekcsSUFBQSx1QkFBdUIsQ0FBQyxRQUFRLEdBQUcsTUFBSztBQUNwQyxRQUFBLElBQUcsY0FBYyxFQUFFO0FBRWYsWUFBQSxjQUFjLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3pDLFNBQUE7QUFDTCxLQUFDLENBQUM7QUFDRixJQUFBLEdBQUcsQ0FBQyxRQUFRLENBQUMsdUJBQXVCLENBQUMsQ0FBQztBQUV0QyxJQUFBLE9BQU8sYUFBYSxDQUFBO0FBQ3hCLENBQUM7QUFFRCxNQUFNLGlCQUFpQixHQUN2QjtJQUNBLDZCQUE2QjtJQUM3QiwyQkFBMkI7Q0FDMUIsQ0FBQTtBQUNELFNBQVMsbUJBQW1CLENBQUMsV0FBZ0IsRUFBQTtJQUV6QyxJQUFHLFdBQVcsS0FBSyxJQUFJO1FBQ3BCLFdBQVcsS0FBSyxTQUFTLEVBQUU7QUFDMUIsUUFBQSxPQUFPLEtBQUssQ0FBQztBQUNoQixLQUFBO0FBRUQsSUFBQSxLQUFJLElBQUksS0FBSyxJQUFJLGlCQUFpQixFQUFFO1FBRWhDLElBQUkscUJBQXFCLEdBQUdtQyw4QkFBcUIsQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdEUsSUFBRyxxQkFBcUIsS0FBSyxJQUFJLEVBQUU7QUFDL0IsWUFBQSxPQUFPLElBQUksQ0FBQztBQUNmLFNBQUE7QUFDSixLQUFBO0FBRUQsSUFBQSxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDakQsSUFBRyxJQUFJLEtBQUssU0FBUyxFQUFFO0FBQ25CLFFBQUEsT0FBTyxLQUFLLENBQUM7QUFDaEIsS0FBQTtBQUVELElBQUEsS0FBSSxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFFakIsUUFBQSxJQUFHLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtZQUN4QixTQUFTO0FBQ1osU0FBQTtBQUVELFFBQUEsS0FBSSxJQUFJLEtBQUssSUFBSSxpQkFBaUIsRUFBRTtZQUVoQyxJQUFJLFdBQVcsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2xDLElBQUcsV0FBVyxLQUFLLElBQUksRUFBRTtBQUNyQixnQkFBQSxPQUFPLElBQUksQ0FBQztBQUNmLGFBQUE7QUFDSixTQUFBO0FBQ0osS0FBQTtBQUVELElBQUEsT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQztBQUVELFNBQVMscUNBQXFDLENBQUMsR0FBaUMsRUFBQTtBQUU1RSxJQUFBLElBQUksUUFBUSxHQUFHLDZCQUE2QixFQUFFLENBQUM7QUFDL0MsSUFBQSxRQUFRLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztBQUM5QixJQUFBLElBQUcsR0FBRyxDQUFDLFdBQVcsS0FBSyxJQUFJO0FBQ3hCLFFBQUEsR0FBRyxDQUFDLFdBQVcsS0FBSyxTQUFTLEVBQUU7QUFDOUIsUUFBQSxPQUFPLFFBQVEsQ0FBQztBQUNuQixLQUFBO0FBRUQsSUFBQSxLQUFJLElBQUksS0FBSyxJQUFJLGlCQUFpQixFQUFFO1FBRWhDLElBQUkscUJBQXFCLEdBQUdBLDhCQUFxQixDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDMUUsSUFBRyxxQkFBcUIsS0FBSyxJQUFJO0FBQzlCLFlBQUEsS0FBSyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFO0FBQ3JDLFlBQUEsUUFBUSxHQUFHLHdCQUF3QixDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDM0QsWUFBQSxRQUFRLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztZQUM5QixNQUFNO0FBQ1QsU0FBQTtBQUNKLEtBQUE7QUFFRCxJQUFBLE9BQU8sUUFBUSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxTQUFTLHdCQUF3QixDQUFDLHFCQUE0QixFQUFBO0lBRTFELElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUNiLElBQUEsS0FBSSxJQUFJLEdBQUcsSUFBSSxxQkFBcUIsRUFBRTtBQUVsQyxRQUFBLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxQyxRQUFBLEdBQUcsSUFBSSxDQUFHLEVBQUEsR0FBRyxDQUFNLEdBQUEsRUFBQSxLQUFLLEtBQUssQ0FBQztBQUNqQyxLQUFBO0FBRUQsSUFBQSxJQUFJLFFBQVEsR0FBRyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUV4QyxJQUFBLE9BQU8sUUFBUSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxTQUFTLHdCQUF3QixDQUFDLElBQW1CLEVBQUE7SUFFakQsSUFBSSxTQUFTLEdBQUksSUFBSSxDQUFDLElBQVksQ0FBQyxXQUFXLENBQWdCLENBQUE7SUFDOUQsSUFBRyxTQUFTLEtBQUssU0FBUztBQUN2QixRQUFBLFNBQVMsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxFQUFFO1FBQzNCLE9BQU8sU0FBUyxDQUFDLFlBQVksQ0FBQztBQUNqQyxLQUFBO0lBRUQsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDO0lBQ3RELElBQUksY0FBYyxHQUFJLElBQUksQ0FBQyxJQUFZLENBQUMsa0JBQWtCLENBQWdCLENBQUE7SUFDMUUsSUFBRyxjQUFjLEtBQUssU0FBUztBQUM1QixRQUFBLGNBQWMsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxFQUFFO0FBQ2hDLFFBQUEsT0FBTyxZQUFZLEdBQUcsY0FBYyxDQUFDLFlBQVksQ0FBQztBQUNyRCxLQUFBO0lBRUQsT0FBTyxZQUFZLEdBQUcsRUFBRSxDQUFDO0FBQzdCLENBQUM7QUFFRCxTQUFTLHNCQUFzQixDQUFDLElBQW1CLEVBQUUsU0FBb0IsRUFBQTtJQUVyRSxJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7QUFDckIsSUFBQSxJQUFJLElBQUksRUFBRTtBQUNOLFFBQUEsWUFBWSxHQUFHLHdCQUF3QixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2pELEtBQUE7U0FDSSxJQUFJLENBQUMsU0FBUyxLQUFLLElBQUksSUFBSSxTQUFTLEtBQUssU0FBUztTQUM3QyxTQUFTLENBQUMsV0FBVyxLQUFLLElBQUksSUFBSSxTQUFTLENBQUMsV0FBVyxLQUFLLFNBQVMsQ0FBQztBQUN0RSxRQUFBLFNBQVMsQ0FBQyxXQUFXLENBQUMsWUFBWSxHQUFHLENBQUMsRUFBRTtRQUM5QyxZQUFZLEdBQUcsU0FBUyxDQUFDLFdBQVcsQ0FBQyxZQUFZLEdBQUcsR0FBRyxDQUFDO0FBQzNELEtBQUE7QUFDSSxTQUFBO1FBQ0QsWUFBWSxHQUFHLElBQUksQ0FBQztBQUN2QixLQUFBO0FBQ0QsSUFBQSxPQUFPLFlBQVksQ0FBQztBQUN4Qjs7OzsifQ==